Repository navigation
codex: SessionStart hook at parity with Claude Code - #60
Merged
Merged
Conversation
`parsec up --session-start` (Codex's SessionStart hook) now emits hook JSON in the shape Codex 0.15x accepts (session-start.command.output): the curation note and any staged trim as additionalContext, the key banner, lifetime note and proxy upgrade/revival notices as systemMessage. Previously it printed raw text, which Codex surfaces to the model as a developer message: proxy status lines leaked into context, and the model never got the fold-marker contract despite Codex traffic being curated. - hook::codex_session_start mirrors the Claude Code SessionStart branch; stdout carries only the JSON object, and failures become messages (exit 0) instead of errors. - Banner and lifetime note are worded per harness (trim::Source::label, savings_cmd → `$parsec-savings` on Codex). - Codex hook block matches startup|resume|clear|compact and passes --port, so it revives the port the Codex provider routes to. - Trim is no longer consumed on resume (same one-shot rule as Claude).
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.
Summary
Codex's SessionStart hook (
parsec up --session-start) did much less than Claude Code'sparsec hook SessionStart, and what it did print leaked into the model's context. This brings it to parity.Before: the hook printed raw text to stdout. Codex surfaces that to the model as a
developermessage, so lines likeproxy already listening on 127.0.0.1:… — nothing to dolanded in context. The model also never got the curation note (fold-marker contract), even though Codex traffic is curated (responses.rsfold-back). That's the read-spiral the note exists to prevent.After: Codex 0.157.1's embedded
session-start.command.outputschema takes the same fields as Claude Code (systemMessage,suppressOutput,hookSpecificOutput.additionalContext). The newhook::codex_session_startprints exactly that JSON object and nothing else:$parsec-savingssystemMessageclear/compactstartup|resume)Other changes
--port, so the hook revives the port the Codex provider actually routes to (it can differ from Claude Code's).apikey::gate_bannerandstatusline::lifetime_notetake atrim::Source, so their text matches the harness.setup::updrops itssession_startparameter;main.rssends--session-startto the new handler.Deliberately not ported
parsec disableswitch:parsec disable codexremoves the hook entirely.Upgrade note
The JSON output takes effect as soon as the binary updates. The wider matcher and
--portarrive only after re-runningparsec setup codex. This is noted in the CHANGELOG.Test plan
cargo fmt --check,cargo clippy -p parsec-proxy --all-targets -- -D warningstrim_clitests: the curation note on startup/clear/compact but not on resume or when unentitled; the trim skipped on resume and delivered on clear (alongside the note); the banner as a Codex-wordedsystemMessage; stdout is always valid hook JSONadditionalContextsystemMessagepanel renders (it's laid out for Claude Code's display)Pre-existing failures, unrelated:
noreread::tests::grant_is_per_file_cross_surface_and_refundsandcompound_command_passes_whole_on_reissuefail on cleanmaintoo. Everything else inparsec-proxypasses.