Skip to content

fix: emit structured JSON from Codex context hooks - #85

Closed
MoonCaves wants to merge 1 commit into
mnemon-dev:masterfrom
MoonCaves:fix/codex-hooks-structured-json
Closed

fix: emit structured JSON from Codex context hooks#85
MoonCaves wants to merge 1 commit into
mnemon-dev:masterfrom
MoonCaves:fix/codex-hooks-structured-json

Conversation

@MoonCaves

Copy link
Copy Markdown
Contributor

Problem

Codex's hook parser classifies any hook stdout beginning with [ or { as attempted JSON (looks_like_json() in codex-rs/hooks/src/engine/output_parser.rs) and parses it. Mnemon's SessionStart (prime) and UserPromptSubmit hooks emit context that begins with [mnemon], so Codex tries to parse it, fails, and reports hook returned invalid ... JSON output on every session start and every prompt.

Fix

Move the existing context into Codex's documented hookSpecificOutput.additionalContext envelope, with no change to the context text itself:

  • user_prompt.sh — emit the reminder as a single static UserPromptSubmit object.
  • prime.sh — pipe the existing status / missing-binary-warning / guide output through python3 json.dumps into one SessionStart object. python3 is already required by the sibling stop.sh, so this adds no new dependency. The existing MNEMON_DATA_DIR (with legacy ~/.mnemon) path resolution is unchanged.

stop.sh already emitted valid JSON and is untouched.

Tests

internal/setup/assets/codex_hooks_test.go executes the actual embedded hook byte slices (CodexUserPromptHook, CodexPrimeHook) as subprocesses and asserts only their external JSON contract: exactly one object, correct hookEventName, and additionalContext carrying the prior text verbatim. Coverage includes missing mnemon, populated mnemon status, empty status, MNEMON_DATA_DIR override, legacy-path fallback, and a guide fixture with quotes / backslash / tab / newline / non-ASCII (byte-exact round-trip). The tests fail against the pre-patch hooks and pass with this change.

go test ./... and make test pass.

This is a correctness repair, not a feature.

Codex classifies hook stdout beginning with `[` or `{` as attempted JSON and
parses it. Mnemon's SessionStart (prime) and UserPromptSubmit hooks emit context
beginning with `[mnemon]`, so Codex tries to parse it, fails, and reports
`hook returned invalid ... JSON output` on every session start and prompt.

Move the existing context into Codex's documented
`hookSpecificOutput.additionalContext` envelope:

- user_prompt.sh: emit the reminder as a static UserPromptSubmit object.
- prime.sh: pipe the existing status/warning/guide output through
  `python3 json.dumps` into a SessionStart object (python3 is already required by
  the sibling stop.sh). Existing context and MNEMON_DATA_DIR path resolution are
  unchanged.

stop.sh already emitted valid JSON and is untouched.

Add internal/setup/assets/codex_hooks_test.go, which executes the embedded hook
byte slices and asserts their external JSON contract across the missing-binary,
stats, empty-status, MNEMON_DATA_DIR override, legacy-fallback, and
special-character-guide cases. The tests fail on the pre-patch hooks and pass
with this change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@MoonCaves MoonCaves closed this Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant