feat(cli): add read-only fleet view and Codex deep-link helpers#244
Open
e-jung wants to merge 5 commits into
Open
feat(cli): add read-only fleet view and Codex deep-link helpers#244e-jung wants to merge 5 commits into
e-jung wants to merge 5 commits into
Conversation
4 tasks
cfd5058 to
614e54c
Compare
…ISSING via lavish-axi
614e54c to
899f295
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Implement the Phase 1/2 Codex GUI friendliness MVP for firstmate: make the firstmate thread usable as the captain's compact Codex GUI control/dashboard while Herdr/tmux/zellij/Orca remain the worker backends. Add a read-only fleet visibility command that summarizes in-flight tasks from primary state/backlog with task id, repo, kind, backend, current status, PR/report pointer, path, and watch/steer guidance. Add a dependency-light Codex deep-link helper for task worktrees, reports, and project directories using canonical codex://new links. Document the one-control-thread UX and update script docs/README. Add focused fake-state tests. Do not implement a new runtime backend, do not touch report-handoff, and do not change merge, teardown, or no-mistakes safety.
What Changed
bin/fm-fleet-view.sh, a dependency-light read-only command that renders in-flight tasks from primary state/backlog with id, repo, kind, backend, current status, PR/report pointer, worktree path, and watch/steer guidance.bin/fm-codex-link.sh, which emits canonicalcodex://newdeep links for task worktrees, reports (by id or absolute path), and project directories, with query-encoded prompts.docs/codex-gui.md, indexes the new scripts inREADME.md/CONTRIBUTING.md/docs/scripts.md, and adds focused fake-state tests intests/fm-fleet-view.test.shplus a session-start test determinism fix.Risk Assessment
✅ Low: Additive, read-only dashboard + deep-link helpers plus docs and focused fake-state tests; touches no merge/teardown/no-mistakes safety paths, mirrors the existing backlog-item parsing convention used by fm-backlog-handoff.sh, and the prior usage-range leak was correctly fixed.
Testing
Baseline full test suite passes cleanly (the earlier exit-code-1 failure is fixed by the branch's two follow-up commits). I then demonstrated the captain-facing user intent directly with a realistic fake fleet and captured real CLI transcripts: the fleet dashboard renders all required columns across tmux/herdr/orca backends, reconciles a stale needs-decision status into the live "parked" state, shows a scout report pointer, surfaces an in-flight backlog orphan while hiding queued items, and prints a clean (none) row when empty; the Codex deep-link helper emits canonical codex://new links (URL-encoded, with raw-path fallbacks) for tasks, reports, and projects and exits non-zero with clear messages for missing task/report/no-args. No actionable issues found.
Evidence: Fleet dashboard + codex-link CLI transcript (multi-backend fake fleet)
############### fm-fleet-view.sh (multi-backend fleet) ############### ID | REPO | KIND | BACKEND | STATUS | PR/REPORT | PATH | WATCH / STEER ---|---|---|---|---|---|---|--- api-fix | repos-api | ship | tmux | state: parked · source: status-log · approve the rate-limit shape | PR https://github.com/acme/api-server/pull/142 | .../repos-api | watch: bin/fm-peek.sh fm-api-fix; steer: bin/fm-send.sh fm-api-fix '<message>'; links: bin/fm-codex-link.sh task api-fix billing-migrate | repos-api | ship | herdr | state: unknown · backend target gone: herdr-sess:h-pane-billing | - | .../repos-api | watch ... steer ... links: bin/fm-codex-link.sh task billing-migrate billing-secondmate | home | secondmate | tmux | state: unknown ... | - | .../home | watch ... links ... docs-audit | repos-docs | scout | tmux | state: unknown ... | report .../data/docs-audit/report.md | .../repos-docs | watch ... links: bin/fm-codex-link.sh task docs-audit orca-exp | repos-docs | ship | orca | state: unknown ... | - | .../repos-docs | watch ... links ... orphan-cleanup | - | backlog | - | state: unknown (backlog in-flight, no metadata); stale secondmate entries need pruning | - | - | create/recover task metadata before watch/steer ############### fm-codex-link.sh task docs-audit (scout + report) ############### task: docs-audit worktree path: .../repos-docs worktree codex: codex://new?path=%2Ftmp%2F...%2Frepos-docs&prompt=Review%20firstmate%20task%20docs-audit%20... report path: .../home/data/docs-audit report codex: codex://new?path=...%2Fhome%2Fdata%2Fdocs-audit&prompt=Review%20report%20...%2Freport.md%20... ############### fm-codex-link.sh project <dir> 'Summarize the architecture' ############### project path: .../repos-api project codex: codex://new?path=...%2Frepos-api&prompt=Summarize%20the%20architecture ############### fm-codex-link.sh task does-not-exist (error path) ############### error: no metadata for task does-not-exist in .../home/stateEvidence: Empty-fleet dashboard output
ID | REPO | KIND | BACKEND | STATUS | PR/REPORT | PATH | WATCH / STEER ---|---|---|---|---|---|---|--- (none) | - | - | - | no in-flight tasks in .../state | - | - | -Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/fm-codex-link.sh:26- usage() runssed -n '2,16p' "$0", but the comment header ends at line 12; lines 13-16 are live code (set -u, a blank line,SCRIPT_DIR=...,FM_ROOT=...), so every usage/error message prints four stray code lines after the intended help text (verified by runningfm-codex-link.shwith no args). The range should be2,12p.bin/fm-codex-link.sh:35- urlencode() percent-encodes every byte outside [A-Za-z0-9.~_-], including/, so an absolute path like/tmpbecomespath=%2Ftmpin the emittedcodex://new?path=...link (verified). This is RFC-3986-valid and the docs state 'query values encoded', but the whole value is a local directory path: if the Codex app's URL handler does not decode%2Fback to/within the path query param, every task/project/report deep link resolves the wrong directory. RFC 3986 permits/unencoded in the query component, so leaving slashes literal (encoding only spaces and other unsafe bytes) is the safer interop choice. Worth confirming against the real Codex app since the feature is unverified without it.bin/fm-fleet-view.sh:57- status_summary spawns a fullfm-crew-state.shsubprocess per in-flight task; each one can issue up to two boundedno-mistakescalls (FM_FLEET_VIEW_STATE_TIMEOUT defaults to 2s each) plus git/tmux probes. On a healthy fleet this is fast, but worst case is several seconds per row, so a large dashboard can take tens of seconds to render. Acceptable for a manual command and the timeout bounds it; noted only as a known characteristic.🔧 Fix: fix usage() header range leak in fm-codex-link.sh
1 info still open:
bin/fm-codex-link.sh:35- urlencode() percent-encodes '/' as %2F (so /home/user/alpha becomes path=%2Fhome%2Fuser%2Falpha). Round 1 flagged this as a possible interop risk if the Codex app does not decode %2F back to '/'. This is RFC-3986-compliant and the conservative/safe choice: any standard URL query-value parser decodes %2F->/, and encoding slashes avoids ambiguity with path separators. The one residual limitation is that the test suite only validates encoding mechanics (e.g. with%20space) and never exercises the emitted codex://new link against a real Codex app consumer, so live interop remains the author's to confirm but needs no code change here.🔧 **Test** - 1 issue found → auto-fixed ✅
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"🔧 Fix: fix session-start tests to force a deterministic MISSING via lavish-axi
✅ Re-checked - no issues remain.
command -v tmux >/dev/null || { echo "tmux is required for e2e tests" >&2; exit 1; }; tmux -V; rc=0; for t in tests/*.test.sh; do echo "== $t =="; bash "$t" || rc=1; done; exit "$rc"Baseline suite:command -v tmux >/dev/null || ...; for t in tests/*.test.sh; do bash "$t"; done(full run, all pass)bash tests/fm-fleet-view.test.sh(5/5 ok)bash tests/fm-session-start.test.sh(11/11 ok, includes the lavish-axi MISSING determinism fix)Manual E2E:FM_HOME=<fake> bin/fm-fleet-view.shagainst a fleet spanning tmux/herdr/orca + scout-with-report + secondmate + backlog-orphanManual E2E:bin/fm-codex-link.sh task <id>for ship and scout shapes (worktree + report deep links)Manual E2E:bin/fm-codex-link.sh report <id>andreport <abs-file-path>(id + absolute-path resolution)Manual E2E:bin/fm-codex-link.sh project <dir> <prompt>(encoded prompt deep link)Manual E2E: positional shorthandbin/fm-codex-link.sh <id>Error paths: missing task (exit 1), missing report (exit 1), no-args usage (exit 2)Empty-fleet path:bin/fm-fleet-view.shon a home with no meta/backlog prints the(none)row (exit 0)Repo-hygiene:git status --porcelainclean; docs/scripts.md + README.md + docs/codex-gui.md diffs present✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.