mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
fix(pi): align the doctor with the pi resolver, correct the strip rationale, update the skill
Second review pass on #282, the three items left open after f4dcfbe.
1. `codeman doctor` and the run mode disagreed about pi. The registry entry
accepted a bare `which pi` hit while pi-cli-resolver demanded semver-shaped
`--version` output, so the Dependencies panel could report an installed Pi CLI
on a box where Run Pi stays hidden, which reads as a broken mode rather than a
missing install. Both sides now share one exported PI_VERSION_REGEX, and
PathResolver gains an opt-in `requireVersionMatch` so a binary that fails the
shape check is reported MISSING instead of installed-with-unknown-version.
Only pi sets it; every other tool keeps its current behaviour.
2. The isAltScreenStripMode comment justified excluding pi with "the alt screen
is load-bearing for its fullscreen TUI". That is not what exclusion does: pi
is tmux-backed, so it falls through to isMuxAltScreenOnlyStripMode, which
strips the alt-screen toggles anyway. What exclusion actually preserves is
`\x1b[3J` and the mouse DECSETs, which is the real reason (pi renders into the
main screen and is mouse-aware). Comment and changeset now say that, and state
the consequence: fullscreen pi paints into the main buffer, like vim in a tmux
shell session.
3. skills/codeman still enumerated the five pre-pi modes in nine places, telling
agents a backend does not exist and understating class-wide caveats by one
mode. All updated, plus stale session.ts line references refreshed.
Tests: a new static guard derives the mode set from the Zod schema (not a copy)
and fails when a skill enumeration lists a partial set of external CLIs, verified
by mutation. It also documents the one legitimate exception it found: the "writes
no transcript" lists drop codex, which does write a rollout Codeman reads back.
Plus doctor cases for an unrelated `pi` on PATH and registry/resolver regex parity.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -568,7 +568,7 @@ recovered by submitting it with `{"input":"\r"}`.
|
||||
|
||||
⚠️ `stop` and `blocked` fire for `claude` sessions only (they are Claude Code hooks,
|
||||
and only when the workspace actually has them, see [§5.1](#51-where-to-spawn)). On
|
||||
`shell`/`opencode`/`codex`/`gemini`/`antigravity`, requesting them explicitly is a
|
||||
`shell`/`opencode`/`codex`/`gemini`/`antigravity`/`pi`, requesting them explicitly is a
|
||||
400, and lifecycle transitions there are coarse (a short shell command may emit **no**
|
||||
`idle` transition at all, verified live), so synchronize those with markers.
|
||||
|
||||
@@ -594,7 +594,8 @@ from the transcript file, which is flushed slightly *after* the `stop` hook fire
|
||||
single read taken the instant send-and-wait returns comes back `""` even though the
|
||||
turn finished (verified live: empty on the first call, full text seconds later). `text`
|
||||
is also `""` before the worker's first completed turn, and always `""` for modes with
|
||||
no transcript (`shell`, `opencode`, `gemini`, `antigravity`, verified live), which is
|
||||
no transcript (`shell`, `opencode`, `gemini`, `antigravity`, `pi`; the first four
|
||||
verified live, pi from the same source path), which is
|
||||
why the loop above is bounded rather than open-ended. Fall back to the terminal buffer
|
||||
there, tail in **bytes** (`textOutput` in `GET .../output` stays empty for interactive
|
||||
sessions; don't use it):
|
||||
@@ -678,7 +679,7 @@ turn), and both better than diffing terminal samples:
|
||||
```
|
||||
|
||||
⚠️ `active-tools` is parsed out of Claude's own output format, so it is **empty for
|
||||
`opencode`/`codex`/`gemini`/`antigravity`** (those parsers are skipped wholesale) and
|
||||
`opencode`/`codex`/`gemini`/`antigravity`/`pi`** (those parsers are skipped wholesale) and
|
||||
in practice empty for `shell`. Source-verified, not measured live.
|
||||
|
||||
Only if neither helps: sample `terminal?tail=` twice a few seconds apart. A changing
|
||||
|
||||
@@ -237,7 +237,7 @@ minutes, never retry the credential.
|
||||
flushed slightly *after* the `stop` hook fires, so a read taken the instant the wait
|
||||
returns is too early (verified live: empty on the first call, full prose seconds later).
|
||||
It is also `""` before the worker's first completed turn, and permanently `""` for
|
||||
`shell`, `opencode`, `gemini` and `antigravity`, which write no transcript.
|
||||
`shell`, `opencode`, `gemini`, `antigravity` and `pi`, which write no Claude transcript.
|
||||
|
||||
**Fix** Poll it, bounded (10 tries, 1 s apart). If it is still empty on a hook-less mode,
|
||||
that is expected, not a failure: read `terminal?tail=` and strip ANSI instead.
|
||||
@@ -334,7 +334,7 @@ ESC=$(printf '\033')
|
||||
|
||||
`POST /api/v1/quick-start` body (all optional):
|
||||
`{"caseName":"worker-1","mode":"claude","sessionName":"w9-worker","effort":"high"}`
|
||||
, `mode` ∈ `claude|shell|opencode|codex|gemini|antigravity`; response is
|
||||
, `mode` ∈ `claude|shell|opencode|codex|gemini|antigravity|pi`; response is
|
||||
`.data.{sessionId, caseName, casePath}`. Creates the case directory (a real directory
|
||||
on the user's disk) if missing, do not retry it in a loop, and remember the name.
|
||||
|
||||
@@ -450,9 +450,9 @@ Quirks that will bite you:
|
||||
session answers with an empty timeline rather than a 404.
|
||||
- ⚠️ **`active-tools` proves presence, never absence.** It is fed by the BashToolParser,
|
||||
which reads Claude's rendered `● Bash(…)` lines, and `_processExpensiveParsers`
|
||||
returns early for every external CLI mode (`session.ts:2086`), so it is permanently
|
||||
`[]` on `opencode`/`codex`/`gemini`/`antigravity`. ⚠️ **`shell` is NOT one of those**
|
||||
(`isExternalCliMode`, `session.ts:164-166`, lists only those four), so the parser does
|
||||
returns early for every external CLI mode (`session.ts:2136`), so it is permanently
|
||||
`[]` on `opencode`/`codex`/`gemini`/`antigravity`/`pi`. ⚠️ **`shell` is NOT one of those**
|
||||
(`isExternalCliMode`, `session.ts:165-167`, lists only those five), so the parser does
|
||||
run on a shell worker, and `TEXT_COMMAND_PATTERN` (`bash-tool-parser.ts:88`) matches
|
||||
bare `tail|cat|head|less|grep|watch|multitail <path>` lines with no `● Bash(` wrapper:
|
||||
a shell worker running `cat build.log` really does populate this. In practice it stays
|
||||
|
||||
@@ -56,7 +56,7 @@ own head: the worker enforcing the cap is the one who has to be told about it.
|
||||
| synchronize on end of turn | HTTP `wait until=stop` (fires for message-initiated turns too, verified live) |
|
||||
| liveness / death check | HTTP `wait?until=exit` |
|
||||
| interrupt a running turn (break-glass) | HTTP input, a bare `\x1b` with no `\r` |
|
||||
| non-claude modes (`shell`/`opencode`/`codex`/`gemini`/`antigravity`) | HTTP only (no other CLI has messaging) |
|
||||
| non-claude modes (`shell`/`opencode`/`codex`/`gemini`/`antigravity`/`pi`) | HTTP only (no other CLI has messaging) |
|
||||
| delete | HTTP, via SKILL.md's `delete_session` guard |
|
||||
|
||||
## Availability: probe, never assume
|
||||
@@ -345,7 +345,7 @@ Without a break-glass, a pair with a bad brief is a token bonfire with no off sw
|
||||
|
||||
### Mixed fleets: the pairing matrix
|
||||
|
||||
Non-claude workers (`shell`, `opencode`, `codex`, `gemini`, `antigravity`) cannot be peers
|
||||
Non-claude workers (`shell`, `opencode`, `codex`, `gemini`, `antigravity`, `pi`) cannot be peers
|
||||
at all; no other CLI has this feature. Their tasks route over HTTP, and you never mention
|
||||
messaging in their briefs. The claude half of the fleet can use messaging among itself,
|
||||
subject to the namespace rule: **messaging works between two sessions that share one
|
||||
|
||||
@@ -177,7 +177,7 @@ for _ in $(seq 1 10); do
|
||||
done
|
||||
printf '%s\n' "$TXT"
|
||||
# (.data is {text,timestamp}; text is also "" before the first completed turn and
|
||||
# always "" for shell/opencode/gemini/antigravity, which have no transcript, use
|
||||
# always "" for shell/opencode/gemini/antigravity/pi, which have no transcript, use
|
||||
# the terminal tail there, and here only to diagnose an unsubmitted prompt.)
|
||||
|
||||
# 6. clean up: exact id, own list only, through the fail-closed preamble helper
|
||||
|
||||
Reference in New Issue
Block a user