Skip to content

fix: emit hookSpecificOutput JSON on ZCode so rules reach the model - #799

Open
Arteiimis wants to merge 1 commit into
DietrichGebert:mainfrom
Arteiimis:fix/zcode-hook-output
Open

fix: emit hookSpecificOutput JSON on ZCode so rules reach the model#799
Arteiimis wants to merge 1 commit into
DietrichGebert:mainfrom
Arteiimis:fix/zcode-hook-output

Conversation

@Arteiimis

@Arteiimis Arteiimis commented Sep 3, 2026

Copy link
Copy Markdown

Fixes #798

ZCode parses hook stdout as strict JSON and injects only additionalContext; the native-Claude raw-text output fails validation and is silently discarded, so the ponytail ruleset never reaches the model there. The hook itself runs fine — the state flag is written at session start — which is what makes the failure so quiet.

Changes

  • Detect ZCode via ZCODE_APP_VERSION, which ZCode injects into every child process, hooks included. A Claude-compat variable alone (CLAUDE_PLUGIN_ROOT) can't distinguish the two.
  • Reuse the Qoder hookSpecificOutput shape for ZCode in writeHookOutput. Unlike Qoder, ZCode has SessionStart, so ponytail-activate.js keeps handling startup injection — only the output shape differs from Claude Code.
  • Same treatment for the off-mode early exit in ponytail-activate.js, where the bare OK text would also fail ZCode's strict JSON parse.
  • Skip the statusline nudge on ZCode: its statusline configuration story is unverified, and the nudge points the agent at Claude's settings.json.
  • No SubagentStart change: ZCode drops that event at registration time, which is already the desired behavior there.
  • Tests mirror the Qoder block in tests/hooks.test.js: SessionStart injection, mode switch, deactivation.

Verification

  • node --test tests/hooks.test.js and tests/hooks-windows.test.js pass; scripts/check-rule-copies.js and scripts/check-versions.js pass.
  • Output shape follows ZCode's documented hook contract (strict-JSON stdout, hookSpecificOutput.hookEventName + additionalContext, cf. ZCode: SessionStart rules never injected — raw-text stdout fails ZCode's JSON validation #798 diagnostics: an event-specific output naming the wrong event fails validation).
  • End-to-end injection on a live ZCode 3.10.2 session: reported in a follow-up comment once confirmed (the patch is running on the reporter's install).

ZCode parses hook stdout as strict JSON; the native-Claude raw-text
SessionStart output fails validation and is silently discarded, so the
ponytail ruleset never reaches the model there (DietrichGebert#798). Detect ZCode via
the ZCODE_APP_VERSION env var it injects into child processes and reuse
the Qoder hookSpecificOutput shape. Skip the bare-OK off-mode output and
the statusline nudge on ZCode for the same reason.
@Arteiimis

Copy link
Copy Markdown
Author

Verified end-to-end on the reporter's install (ZCode 3.10.2, Windows 11, ponytail 4.9.0 with this patch applied to the installed plugin): on a fresh session the SessionStart hook fires and the full ruleset reaches the model as injected additionalContext — no manual /ponytail needed. The UserPromptSubmit path (/ponytail mode switch) delivers its confirmation through the same envelope correctly.

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.

ZCode: SessionStart rules never injected — raw-text stdout fails ZCode's JSON validation

2 participants