feat: automatically reap terminal crews and orphaned lifecycle state #480
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| name: Lint shell scripts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Install pinned ShellCheck | |
| run: | | |
| set -eu | |
| bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin" | |
| echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" | |
| # Single owner of the lint definition (file set + config + version). Do not | |
| # re-spell the shellcheck command here; keep CI and the pre-push gate on it. | |
| - run: bin/fm-lint.sh | |
| tests: | |
| name: Behavior tests | |
| runs-on: ubuntu-latest | |
| # The pre-cutover suite reached 25m35s, and the exhaustive Bridge crash | |
| # matrix adds bounded work. Keep enough margin without masking a real hang. | |
| timeout-minutes: 90 | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pinned ShellCheck | |
| run: | | |
| set -eu | |
| bin/fm-install-shellcheck.sh "$RUNNER_TEMP/bin" | |
| echo "$RUNNER_TEMP/bin" >> "$GITHUB_PATH" | |
| - name: Require tmux for e2e tests | |
| run: | | |
| set -eu | |
| command -v tmux >/dev/null || { | |
| echo "::error::tmux is required for real afk injection e2e coverage" | |
| exit 1 | |
| } | |
| tmux -V | |
| - name: Install tasks-axi for backlog-handoff delegation | |
| run: | | |
| set -eu | |
| npm install -g tasks-axi | |
| tasks-axi --version | |
| - run: | | |
| set -eu | |
| for test_script in tests/*.test.sh; do | |
| "$test_script" | |
| done | |
| agent-fleet: | |
| name: Agent Fleet package | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install pinned uv | |
| run: python -m pip install uv==0.9.10 | |
| - name: Verify locked package | |
| working-directory: tools/agent-fleet | |
| run: | | |
| set -eu | |
| uv sync --locked | |
| uv run --locked ruff check . | |
| uv run --locked pytest | |
| uv run --locked python -m compileall -q src | |
| uv build --out-dir "$RUNNER_TEMP/agent-fleet-dist" | |
| invariants: | |
| name: Repo invariants | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Symlinks must stay intact | |
| run: | | |
| set -eu | |
| [ "$(readlink CLAUDE.md)" = "AGENTS.md" ] || { echo "::error::CLAUDE.md must be a symlink to AGENTS.md"; exit 1; } | |
| [ "$(readlink .claude/skills)" = "../.agents/skills" ] || { echo "::error::.claude/skills must be a symlink to ../.agents/skills"; exit 1; } | |
| - name: Personal fleet paths must not be tracked | |
| run: | | |
| set -eu | |
| tracked=$(git ls-files -- data state config projects .no-mistakes) | |
| if [ -n "$tracked" ]; then | |
| echo "::error::Personal fleet paths are tracked in git:" | |
| printf '%s\n' "$tracked" | |
| exit 1 | |
| fi |