Skip to content

feat: zcode (z.ai GLM-5.3) worker with first-run key provisioning (2.9.0) - #19

Draft
mariuszkreft wants to merge 1 commit into
mainfrom
feat/zcode-worker
Draft

feat: zcode (z.ai GLM-5.3) worker with first-run key provisioning (2.9.0)#19
mariuszkreft wants to merge 1 commit into
mainfrom
feat/zcode-worker

Conversation

@mariuszkreft

Copy link
Copy Markdown
Contributor

Adds z.ai's GLM Coding Plan as a first-class m2herd worker, following the prime precedent (#18).

Design decision: claude binary, z.ai endpoint

z.ai ships no CLI. ZCode is a desktop app (DMG installer, GUI-only); the npm zcode-* packages are unofficial. The path z.ai documents for a GLM Coding Plan in a terminal is Claude Code pointed at their Anthropic-compatible endpoint (https://api.z.ai/api/anthropic), with the sonnet/opus tier names mapped to GLM models.

So zcode runs the claude binary with the same auto-approve flag, plus a sourced env file. This is not a shortcut — it's what makes everything else free: session resume, the --output-format json envelope, report salvage, token parsing, and herdr's claude integration (authoritative pane lifecycle, not heuristic like prime) all work unchanged. --model sonnet (headless default, now shared with zcode) resolves to glm-5.3[1m] (1M context) server-side.

First-run key

First --agent zcode dispatch prompts once, silent input, before any worktree or pane is created; stores ~/.config/m2herd/zai.env mode 600; reused forever after. Resolution order: existing file → $ZAI_API_KEY → TTY prompt. Non-interactive runs never hang — they exit with the one-liner that fixes it. Overrides $M2HERD_ZAI_ENV, $M2HERD_ZAI_MODEL, $M2HERD_ZAI_HAIKU_MODEL.

Secret hygiene

The key is sourced by the spawned worker (set -a; . <file>; set +a), never herdr agent start --env (which would put it in this process's argv) and never interpolated into a command line. It cannot appear in ps, pane scrollback, overview.json, or --dry-run output — asserted in testing (0 occurrences).

The agent start last-resort fallback wraps the worker in /bin/bash -lc for the same reason: execing the binary directly would silently run a zcode worker against Anthropic instead of z.ai — wrong endpoint, wrong quota, confusing auth failure.

Verification

  • bash -n both scripts; m2herd selftest PASS; hooks/smoke.sh 36 passed, 0 failed
  • config set workers.agent zcode accepted; bogus rejected (also fixes the error message, which never listed prime)
  • --dry-run dispatch for all three spawn paths (headless / pane split / agent-start fallback) carries the env; --agent claude dispatch byte-identical to before
  • Caught in review-by-testing: --model '' (the sonnet default was claude-gated) — fixed

Not covered

No live call against a real GLM Coding Plan — that needs a key. First real dispatch is the remaining verification step.

🤖 Generated with Claude Code

…9.0)

Adds z.ai's GLM Coding Plan to the worker selection. z.ai ships no CLI of
its own — ZCode is a desktop app — so zcode runs the claude BINARY against
z.ai's Anthropic-compatible endpoint, the path z.ai documents for a GLM
Coding Plan. Consequence: session resume, the --output-format json envelope,
report salvage, token parsing, and herdr's claude integration (authoritative
pane lifecycle) all work unchanged. --model sonnet (the headless default,
now shared with zcode) resolves to glm-5.3[1m] server-side.

First run prompts once (silent input) for the key and stores it at
~/.config/m2herd/zai.env mode 600; later dispatches reuse it. Non-interactive
runs never hang — they fail with the ZAI_API_KEY=<key> one-liner that fixes
it. Overrides: M2HERD_ZAI_ENV / M2HERD_ZAI_MODEL / M2HERD_ZAI_HAIKU_MODEL.

The key is SOURCED by the spawned worker, never passed via agent start --env
and never interpolated into a command line, so it cannot reach ps, pane
scrollback, overview.json, or --dry-run output. The agent-start last-resort
fallback wraps the worker in /bin/bash -lc for the same reason: execing the
binary directly would silently run a zcode worker against Anthropic.

Also fixes the settings_validate_agent error message, which never listed
prime.

Verified: bash -n both scripts, m2herd selftest PASS, hooks smoke 36/0,
config set accept/reject, dry-run dispatch for all three spawn paths
(headless / pane split / agent-start fallback) carries the env, claude
dispatch unchanged, and the key appears 0 times in any output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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