Hooks silently not loaded from a local directory marketplace; ZCode 0.16.5 Stop transcript is assistant-only so stock sync always fails

Open
#2 2 comments 0 reactions 1 assignee View on GitHub

@ThaddeusJiang is already working on this.

Since Nov 12, 2026.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
45/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Quiet
Tech stack
javascript
Domain
devtools

Research direction

The report describes two independent failures: hooks not loading from a local directory marketplace and assistant-only Stop transcripts failing sync. Start by tracing hook registration and the Stop hook's transcript handling, then inspect the ZCode session-store workaround described in the issue. Done means the failures are handled or surfaced clearly and sync works for the reported ZCode 0.16.5 case; no relevant source files or tests are named.

Written by the indexing model from the issue text.

Description

bug

Environment: plugin 0.2.0, nmem 0.10.73, ZCode CLI 0.16.5 / App 3.10.0, macOS — two Macs with identical versions of both nmem and the plugin.

We spent a full day diagnosing why one Mac auto-synced ZCode sessions and the other silently synced nothing. Two independent failure modes found; documenting both so others (and the plugin) can short-circuit this.

1. Same plugin, different marketplace source → hooks loaded vs never loaded

  • Mac A installed via the GitHub marketplace source → plugin hooks load, sessions auto-sync. ✅
  • Mac B installed the same plugin 0.2.0 from a local directory marketplace (local clone registered as a directory-type source) → ZCode never loads the plugin's hooks. ❌

The only observable signal is in ZCode's startup log (~/.zcode/cli/log/zcode-<date>.jsonl, event bootstrap.app.startup.plugins.completed): hookCount: 0 on Mac B vs a positive count on Mac A. Nothing surfaces in the UI; nmem doctor shows everything green on both. Sessions just silently never sync.

The marketplace registration itself looks healthy on Mac B: plugin listed as enabled, cache populated, commands/skills resolvable.

Suggestions:

  • Make hooks from directory-source marketplaces load identically to GitHub-sourced ones — or fail loudly / document the limitation.
  • Add a doctor check "ZCode actually registered the plugin's hooks" (reading the same hookCount signal), so this failure mode is diagnosable without cross-machine diffing.

2. ZCode 0.16.5's Stop transcript contains only the last assistant message

ZCode 0.16.5's hook runner writes the Stop transcript as a single JSONL line with only the final assistant message:

{"message":{"content":[{"text":"…","type":"text"}],"role":"assistant"}}

(see Hei() in zcode.cjs — JDr("assistant", e.responseText ?? e.responsePreview)).

nmem t sync --from zcode then rejects it with:

ZCode session needs at least one user and one assistant message

So on this ZCode build the stock Stop hook fires but the sync can never succeed — the error only appears in hook stderr.

Workaround we deployed (working reliably on 0.16.5): instead of copying transcript_path, the Stop hook exports the full user/assistant conversation for session_id straight from ~/.zcode/cli/db/db.sqlite (session/message/part schema is OpenCode-compatible), emits it in the same one-line-per-message format, and feeds that to t sync --from zcode --apply. Full conversation per turn, idempotent, and it also survives the assistant-only transcript limitation.

Longer-term options:

  • Have the hook script fall back to reading the ZCode sqlite store (like the workaround above), or
  • Have t sync --from zcode tolerate assistant-only transcripts by pulling the missing user turns via --session-id.

Footnote

Two more things that extended our debugging session, in case they help others:

  • The MCP server type must be http (not streamableHttp) in ~/.zcode/cli/config.json — wrong values are silently skipped (only a config.mcp_server.skipped warn in the same log file).
  • Hooks are registered when the ZCode process starts; editing config.json requires a full app restart for hooks (MCP reconnects per session and picks changes up immediately).
Dominant language
JavaScript
Stars
3
Forks
1
PR merge metrics
No merged PRs in 30d

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nowledge-co/zcode-plugin

All issues in nowledge-co/zcode-plugin

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.