Skip to content

track ZCode sessions through its hooks - #122

Closed
iPeluwa wants to merge 2 commits into
iamnotstatic:mainfrom
iPeluwa:zcode-hooks
Closed

iPeluwa wants to merge 2 commits into
iamnotstatic:mainfrom
iPeluwa:zcode-hooks

Conversation

@iPeluwa

@iPeluwa iPeluwa commented Oct 16, 2026 •

Copy link
Copy Markdown

ZCode (Z.ai's desktop coding agent) never runs the wrapped terminal commands, so its sessions were invisible to vibetime. It does have lifecycle hooks, so this tracks it the same way as the Claude Code, Codex and Cursor desktop apps.

Where the hooks go. ZCode reads user hooks from ~/.zcode/cli/config.json under hooks.events, as matcher groups. src/zcode-hooks.ts merges ours in next to whatever else is in that file (it already holds the plugin settings) and removes them again on uninstall, matching on __hook like the other installers. vibe init, vibe hooks install, vibe hooks uninstall, vibe uninstall and the session-start repair in reconcile.ts all cover it.

ZCode keeps new hooks off. ZCode loads hooks only at startup and lists new ones under Settings → Hooks switched off; the user switches them on there, and ZCode records that by writing enabled: true onto each hook (and hooks.enabled), rewriting timeoutMs to timeout in seconds as it saves. So the installer writes timeout: 10 in that form, and a vibe hook whose command already matches is left exactly as ZCode saved it. Without that, the session-start repair would rewrite the group on every session and switch tracking back off. A changed command (a moved Node or CLI) is written fresh without enabled, so ZCode asks the user to switch it on again rather than vibetime approving new code to run. The README walks through the switch-on.

Events. SessionStart opens the session, and UserPromptSubmit, PostToolUse and Stop are activity. ZCode has no session-end event, so a ZCode session closes through the reaper after 30 idle minutes, the same path that closes a desktop session the editor never ended.

Session ids. ZCode names sessions sess_<uuid>, which UUID_RE rejected, so every event was dropped. resolveSessionId now takes the uuid inside that prefix. Sub-agents are sess_subagent_agent_<uuid>; they still fail the check, so a sub-agent never opens a session of its own beside the one that spawned it.

Tool tag. Sessions are tagged zcode, which passes the server's VALID_TOOLS_RE.

Checks: npm test passes, 157 of 157. New tests cover the installer (non-destructive merge that keeps other config keys, idempotent reinstall, a hook the user switched on left byte-identical, stale command refresh that does not carry the switch-on over, removal, invalid JSON left untouched, fresh config) and the hook path (a sess_ id opens one session under the bare uuid, tagged zcode; a sub-agent id opens none).

Verified live with ZCode 3.15.3 (agent 0.16.9) on macOS: after switching the hooks on, a new ZCode task sess_ab348fec-… was recorded in ~/.vibe/sessions.json as session ab348fec-…, tool zcode, measuring the workspace's repos, with activity updating after the reply. ZCode logged the SessionStart hooks at 1.5 s and the prompt hooks at 0.1 s. The payload carries cwd (the task's working directory) and session_id, which is all the hook reads.

@iPeluwa
iPeluwa marked this pull request as ready for review October 16, 2026 07:44
@iPeluwa

iPeluwa commented Oct 21, 2026

Copy link
Copy Markdown
Author

Closing — keeping these fixes local rather than upstreaming. Thanks!

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