Repository navigation
feat(composer): live, attribute-aware composer state (agent-code#800, #1313) - #54
Merged
Merged
Conversation
…, #1313) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… #1313) Codex 0.157 paints its empty-composer placeholder dim and a typed draft plain, under a two-row footer the 0.149.1 classifier rejects. getComposerState reads the live buffer's dim flags inside an anchored bottom pane: empty, drafted, or unknown when the pane is not provably the composer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ue footer, images, Vim on either row Dim cells alone called the quit frame (`› Shutting down...`, dim) and an image attached above the textarea empty. Codex shows `? for shortcuts` only in ComposerEmpty, and its is_empty counts attachments, so `empty` now needs that hint. Drafts under the running-turn queue footer read as drafted. Tests pin the quit frame, continuation rows, a markerless pane, the row bound and Vim on the second footer row. The fixture's session id is redacted too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, never from the cwd The status row carries the cwd, which is user-controlled: a folder named `for shortcuts` forged `empty` over an attached image or the quit frame, and one named `to queue message` forged `drafted`. The shortcuts and queue hints are now matched only at the start of a hint row (or the queue row itself). The quit test cuts at the `› Shutting down...` frame itself, and the comment says `unknown` is neither ready nor occupied. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Final disposition (pre-merge), head 03c64f3. Three reviewers: A (correctness, Codex), B (tests, Codex), C (evidence, Grok). Two rounds each; no round 3.
Round 1 → fixed in
Round 2 → fixed in
Residuals, stated in the PR body for the app side:
The full suite passes (231 tests), and 🤖 Generated with Claude Code |
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.
Refs Juliusolsson05/agent-code#800 and Juliusolsson05/agent-code#1313. The app side follows in agent-code once this merges.
Plan:
docs/plans/2026-09-25-composer-state-0157.md(first commit).Evidence
testing/fixtures/composer-0157/idle-draft-ctrlc.jsonis a raw PTY recording of codex-cli 0.157.0 at 100×30: idle start, a typed draft with no Enter and no model request, then Ctrl+C twice. The home directory name is redacted with a same-length string.› Ask Codex to do anythingwith the placeholder dim (\x1b[2m), then a blank row, the status row and a second footer row (hints or warnings).› please review the draftin plain cells.HeadlessTerminal,classifyCodex01491ComposerSurfacereturnsunknownfor both frames, because it requires exactly one footer row. The app's text-only empty check refuses the empty composer (agent-code#1313), and nothing reports a draft (agent-code#800).Change
HeadlessTerminal.snapshotComposerCells(): viewport rows with each non-blank cell's dim flag, from the live buffer. It returns null while bytes are still parsing.classifyCodexComposerState(rows)returnsempty,draftedorunknown(revised after review round 1):›row, then a blank row, then the footer: the status row (or, during a turn, the queue row), plus at most one more footer row. Anything else isunknown.drafted: plain cells after the marker, an[Image #n]label on the composer rows, or Codex's "tab to queue message" hint.empty: no plain cells and Codex's own? for shortcutshint.for shortcutsorto queue messageused to forgeemptyordrafted. Codex shows that hint only inFooterMode::ComposerEmpty, and itsis_empty()counts attachments and bash mode (vendor/codex-src/…/footer.rs:224-231). Dim cells alone are not enough: the quit frame's› Shutting down...is dim, and an image above the textarea keeps the dim placeholder.unknown.CodexHeadless.getComposerState()wires the two together. Both are exported from the index.PromptInputEvidenceare untouched; they stay version-gated.For the app side (agent-code)
Only
emptyis consent, and onlydraftedis occupancy.unknownmust not map to ready: Codex readiness latches after startup (markComposerReady), so an occupancy reason needs its own publication path (#54 review C).Tests
ComposerState.recorded.test.ts(10 tests):empty;drafted;emptyagain;› Shutting down...quit frame (cut at that exact paint) is neverempty.empty; with no hint it readsunknown.empty; a dim image label on the composer row isdrafted.active-footer-tab-queueframe readsdrafted, and so does a dim row under the queue hint.drafted. The composer bound is 12 continuation rows (drafted); 13 readsunknown.›row, a markerless pane, and Vim on either footer row all readunknown.~/for shortcutsand~/to queue messagein the status row. These tests were red on round 2's head.The full suite passes (231 tests), and
tsc --noEmitis clean. The fixture's home directory and session id are redacted with same-length values.🤖 Generated with Claude Code