Cursor Skill

zcode-delegate

Delegate a coding task to the Z.AI ZCode CLI as a background implementer, then review its diff and land it yourself. Use this whenever the user wants to hand implementation work to ZCode — phrasings like "have ZCode do X", "delegate this to ZCode", "run it through ZCode", or "use

LLM Mart · 0 points · 16 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download amElnagdy-delegate-skills-skills_zcode-delegate-a4f24b4.zip · 29 KB
Part of amelnagdy/delegate-skills — 18 skills

Install

skills CLI npx skills add https://github.com/amElnagdy/delegate-skills/tree/master/skills/zcode-delegate
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install amelnagdy-delegate-skills@llmmart
Git git clone https://github.com/amElnagdy/delegate-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole amelnagdy/delegate-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

ZCode Delegate

You are the orchestrator. This skill lets you hand a bounded coding task to a separate implementer — the Z.AI ZCode CLI — then review what it produced and land it yourself. You write the brief and own the judgment; ZCode does the typing; you verify and commit.

Nothing here is specific to one orchestrating agent. The loop needs only the ability to run a shell command and read a file. (It is designed for and run on Claude Code; treat other orchestrators as designed-for, not yet proven.)

When NOT to use this

  • The task is small enough to just do inline — delegation overhead is not worth it.
  • ZCode is not installed, or its CLI has no model provider configured.
  • You want to write the code yourself, or you only need a review.

Prerequisites (check once)

  1. ZCode is installed. The CLI ships inside the desktop app — it is not on PATH and not on npm. The relay resolves it in this order: --zcode-path <file> or ZCODE_CLI first, then PATH, then the installed app bundle. On Linux the app is an AppImage with no fixed install path, so the flag or the environment variable is required there — the relay guesses nothing.
  2. A model provider is configured for the CLI, with a key it can actually reach. Being signed into the desktop app is not enough — see below.
  3. You are in (or will point --cd at) the target git repository.

The relay records the CLI version and how it was resolved into result.json, so a surprising install is visible after the fact.

Authenticating the headless CLI

Signing into the ZCode desktop app does not authenticate the CLI this relay drives. The CLI keeps its own config at ~/.zcode/cli/config.json, separate from the desktop app's, and nothing bridges the two. zcode login is the intended path, but where it fails with OAuth response is not valid JSON the way in is a Z.AI API key.

Two pieces are needed, and they are separate:

  1. The provider block must exist in ~/.zcode/cli/config.json. It defines the provider, its endpoint and its models — the environment cannot supply this:

    {
      "provider": {
        "zai": {
          "kind": "anthropic",
          "options": { "apiKeyRequired": true, "baseURL": "https://api.z.ai/api/anthropic" },
          "models": { "glm-5.1": { "name": "GLM-5.1" } }
        }
      },
      "model": { "main": "zai/glm-5.1" }
    }
    
  2. The key can live either in provider.zai.options.apiKey in that file, or in the environment as any one of ZAI_API_KEY, ZCODE_API_KEY, or ANTHROPIC_API_KEY. Prefer the environment — it keeps the secret off disk.

If a run fails with Model provider is missing an API key: <provider>, the provider block resolved but no key was found: set one of those variables and re-run.

Autonomy — read this before dispatching

ZCode's own term is mode. It has four values; only two are usable headlessly.

mode Behaviour
yolo Writes. ZCode's own default for --prompt, and this relay's write-capable default.
plan Refuses edits. What --read-only selects.
build Rejected by this relay. No permission client exists headlessly, so tools are blocked and the run exits 0 having done nothing.
edit Rejected for the same reason.

Two limits stated plainly, because ZCode cannot enforce them:

  • plan mode refused edits in testing, but the relay does not treat that as a guarantee. It takes a Git fingerprint before the run and reports a tri-state readOnlyViolation afterwards. Confirm touchedFiles came back empty rather than assuming no edits.
  • ZCode has no --allowed-tools. Only the --disallowed-tools denylist exists, and it is genuinely enforced. An explicit allowlisted tool surface is therefore impossible here — do not assume one.

The loop

Run these five steps per task. Steps 1, 4, and 5 are your judgment; 2 and 3 are mechanical.

1. Write the brief

ZCode sees only what you send — no repo memory, no chat history. Everything the task needs goes in the brief: the goal, the current state, what to change, what to leave untouched, the project's actual gate commands (discover them from the repo's CLAUDE.md/AGENTS.md/Makefile — do not assume), and a report contract. Tell ZCode it will not commit. One task per brief. The relay delivers the brief as an attached file, so the command line no longer bounds its length — the model's context window still does. Full guidance and a template: references/writing-the-brief.md.

2. Dispatch

node "<skill-dir>/scripts/relay.mjs" --brief brief.txt --cd /path/to/repo
# read-only (review/diagnosis, no edits):   add --read-only
# continue a specific session:              add --session <sess_...>  (from result.json; send only the delta brief)
# continue the latest session for --cd:     add --resume-last
# withhold tools (denylist):                add --disallowed-tools "Write,Edit,Bash"
# point at the CLI explicitly:              add --zcode-path /path/to/zcode.cjs
# hard time limit (watchdog):               add --timeout 2h  (default: off)
# see all options:                          node .../relay.mjs --help

(<skill-dir> is this skill's installed directory — the folder containing this SKILL.md.)

The relay writes its artifacts to a temp dir, so the repo under review stays clean. It never commits — see step 5. Mechanics, flags, and the result.json shape: references/dispatch-and-poll.md.

3. Wait for completion

The relay blocks until ZCode finishes, so back it with whatever your orchestrator offers:

  • Claude Code: run the Bash call with run_in_background: true; you are notified on completion.
  • Plain shell / other agents: foreground for short tasks, or background it and poll the result file. The run is done when result.json exists with a status. A pre-run usage error exits 2 and writes no result file, so check the exit code too; a CLI that cannot be found exits 127 but does write a result.json with status zcode_unavailable.

Do not trust progress trackers over reality: read the working tree, not a status line.

4. Review — do not trust the self-report

  • Re-run the project's gates yourself. Never take "gates passed" on faith.
  • Read the diff against the brief: did ZCode do what was asked, nothing more and nothing less? touchedFiles is your starting point.
  • On a --read-only run, check readOnlyViolation and confirm touchedFiles is empty.
  • Run the relevant guard skills on the diff if you have them installed.

Full checklist: references/review-and-land.md.

5. Land it

The orchestrator commits. Only after the gates pass and the diff holds:

  • Commit the verified work yourself, with a clear message.
  • If it needs changes, send a delta brief with --session <sessionId> from the prior result.json, and review again.

Read-only second opinions

The relay doubles as a way to get an adversarial second opinion with no write risk: dispatch --read-only with a brief listing the agreed points, then each contested point with both positions, and ask ZCode to defend or concede each. Because plan mode's guarantee is measured rather than enforced here, verify touchedFiles came back empty instead of assuming no edits.

Authorization model

Delegation is something the human opts into. Once they have, committing verified, gate-passing work is the agreed contract. Two limits: surface, don't absorb (report ZCode's design decisions and defensible-but-unasked turns rather than silently keeping them) and stop for scope changes (if correct completion needs going beyond the brief, ask). The full treatment is in references/review-and-land.md.

References

Files (delegate-skills)
  • references
    • dispatch-and-poll.md 6.4 KB
      # Dispatch and poll
      
      The relay wraps the ZCode CLI so your job is "run a command, read a file."
      
      ```bash
      node "<skill-dir>/scripts/relay.mjs" --brief brief.txt --cd /path/to/repo
      cat brief.txt | node "<skill-dir>/scripts/relay.mjs" --cd /path/to/repo
      ```
      
      ## How the relay finds ZCode
      
      ZCode does not install a `zcode` binary on PATH and does not publish one to npm — the CLI ships
      inside the desktop app. The relay resolves it in this order, first hit wins:
      
      1. `zcode` on **PATH** — if you made a shim or alias, this is used.
      2. **`--zcode-path <file>`**, else the **`ZCODE_CLI`** environment variable.
      3. The installed **app bundle**: `%LOCALAPPDATA%\Programs\ZCode\resources\glm\zcode.cjs` on Windows,
         `/Applications/ZCode.app/…` (and `~/Applications/…`) on macOS. Linux ships an AppImage with no
         fixed install path, so there is nothing to auto-discover there — use option 1 or 2.
      
      A resolved `.cjs` bundle is launched under `node`. `result.json` records which route was used in
      `zcodeSource` (`path` / `flag` / `env` / `bundle`), so a surprising install is visible after the run.
      
      If no CLI is found — including when you name one explicitly that does not exist — the relay exits
      **127** and still writes a `result.json` with `status: "zcode_unavailable"`.
      
      ## Options
      
      | Flag | Effect |
      | --- | --- |
      | `--brief <file>` | Path to the brief. Omitted → read from stdin. |
      | `--cd <dir>` | Working root for ZCode (default: current directory). |
      | `--lane <name>` | Fleet lane from `delegate-setup` config. Explicit flags win over lane dials. |
      | `--mode <mode>` | ZCode's `--mode`. **Only `plan` and `yolo` are accepted** (see below). Default `yolo`. |
      | `--read-only` | Shortcut for `--mode plan` (review/diagnosis, no edits). |
      | `--disallowed-tools <list>` | Comma/space-separated denylist, e.g. `"Write,Edit,Bash"`. Enforced by ZCode. |
      | `--session <id>` | Continue a specific session by `sess_…` id from a prior `result.json`. |
      | `--resume-last` | Continue the latest session **for `--cd`**. Mutually exclusive with `--session`. |
      | `--zcode-path <file>` | Point at the CLI explicitly. |
      | `--timeout <dur>` | Relay-side watchdog (default: off). `30m`, `2h`. ZCode has no timeout flag of its own. |
      | `--out-dir <dir>` | Where to write run artifacts (default: a fresh dir under the system temp dir). |
      | `-h, --help` | Show help. |
      
      ### Why `build` and `edit` are rejected
      
      ZCode documents four modes. Headless runs have no permission client, so under `build` or `edit` the
      Write and Bash tools are blocked and the run **exits 0 having changed nothing**, with a report
      explaining that tool permissions were denied. That is a success status for a run that did no work,
      so the relay refuses those modes up front with a usage error (exit 2) rather than letting them look
      like a completed task. Use `--mode yolo` to write, or `--read-only` for plan mode.
      
      ## The `result.json` contract
      
      Speaks `delegate-relay.result.v1`.
      
      | Field | Meaning |
      | --- | --- |
      | `status` | `completed` \| `failed` \| `timeout` \| `aborted` \| `zcode_unavailable` |
      | `exitCode` | ZCode's own exit code, or the relay's mapping for a killed run |
      | `signal` | The signal that killed the child, or `null` |
      | `finalMessage` | ZCode's final report (its `response` field) |
      | `sessionId` | The `sess_…` id — pass to `--session` to continue this exact session |
      | `touchedFiles` | Git porcelain paths. `[]` when the tree is clean, `null` when git cannot report. |
      | `mode` | The ZCode mode the run actually used |
      | `readOnlyViolation` | Tri-state. `false` = the tripwire saw no change on a plan run, `true` = it did, `null` = unknown or not applicable |
      | `usage` | ZCode's token accounting (input, output, total, cache reads) |
      | `contextWindow` | From ZCode's `projection` |
      | `zcodeVersion`, `zcodeSource` | Which CLI ran, and how it was found |
      | `briefPath`, `outputPath`, `finalPath` | Run artifacts on disk |
      
      Exit codes: a pre-run usage error (bad args, empty brief, a rejected `--mode`) exits **2** and writes
      **no** result file. A CLI that cannot be found exits **127** and *does* write one. Otherwise the exit
      code mirrors ZCode's, and a run killed by the watchdog reports `timeout`.
      
      An orchestrator that polls for the file must therefore also check the exit code — a non-zero exit
      with no file is a usage error, not a crashed run.
      
      ## Backgrounding
      
      - **Claude Code:** run the Bash call with `run_in_background: true`.
      - **bash/zsh (incl. Git Bash/WSL):** `… &`, then poll for `result.json`.
      - **PowerShell:** `Start-Job`. **cmd:** `start /b`.
      
      The run is finished when `result.json` exists with a `status` *and* the process has exited.
      
      ## Reading the output
      
      ZCode's `--json` prints a single JSON document at the end rather than a stream of events, and the
      relay parses it tolerantly: the bundled AI SDK sometimes prints a warning banner on stdout ahead of
      the JSON, so leading non-JSON lines are skipped. The raw stdout is preserved at `outputPath` and the
      final report at `finalPath`, so nothing is lost if parsing degrades.
      
      If the document cannot be parsed at all:
      
      - with exit 0, the run is still `completed`, `finalMessage` falls back to the raw stdout, and a
        `parseWarning` field is set — read `outputPath` yourself.
      - with a non-zero exit, the run is `failed` and `stderrTail` carries the last lines of stderr.
      
      ## When a run misbehaves
      
      - **`status: "timeout"`** — the watchdog fired. The whole ZCode process tree was killed. Inspect the
        working tree before re-dispatching; a killed run can leave partial edits.
      - **`status: "aborted"`** — the relay itself was killed and forwarded the kill. Same advice.
      - **`status: "zcode_unavailable"`** — no CLI found. Check the three resolution routes above.
      - **Exit 1 with `Session not found`** — the `--session` id does not exist. Session ids are
        `sess_`-prefixed; copy them from a prior `result.json`, not from memory.
      - **`completed` but `touchedFiles` is empty on a write run** — read `finalMessage`. ZCode may have
        reported that it could not proceed. That is a real outcome, not a relay bug.
      - **`(no final message captured)` on a resumed plan-mode run** — ZCode has been observed returning
        `"response": ""` while doing substantial work (658 output tokens across 602 events in one measured
        run). The relay reports what ZCode sent, so an empty report here is the CLI's, not a parse failure:
        `parseWarning` will be absent and `usage` non-zero. Read `outputPath` and the working tree rather
        than concluding nothing happened.
      
    • multi-task-queues.md 3.5 KB
      # Multi-task queues
      
      A queue is a sequence of bounded tasks dispatched one at a time, each reviewed and landed before the
      next begins. It is the shape that makes delegation worth the overhead: a migration, a mechanical
      refactor across many files, a removal sweep.
      
      **Run them sequentially.** Parallel dispatches against one working tree produce interleaved edits
      that no reviewer can untangle, and `touchedFiles` stops meaning anything.
      
      ## The loop
      
      For each task in the queue:
      
      1. Write the brief for **this task only**.
      2. Dispatch.
      3. Wait for `result.json`.
      4. Review: re-run the gates, read the diff, check scope.
      5. Land it — a commit per task, not one commit at the end.
      6. Note anything learned that the next brief needs.
      
      A commit per task is what makes a queue recoverable. When task 6 of 9 goes wrong, you revert one
      commit instead of unpicking a nine-task blob.
      
      ## Carrying constraints forward
      
      Each brief is written cold, so constraints do not survive on their own. Keep a short block and paste
      it into every brief in the queue:
      
      ```markdown
      # Standing constraints (apply to every task in this queue)
      - Do not add dependencies.
      - Do not reformat files you are not otherwise changing.
      - Public API in src/api/ is frozen; changing it fails review.
      - Gates: node test/relay-smoke.mjs
      ```
      
      Add to this block as you learn. If task 3's review caught a drive-by refactor, task 4's brief should
      forbid it explicitly. The block is how a queue gets *more* reliable as it runs rather than less.
      
      ## Fresh session per task, usually
      
      Start each task cold — a new dispatch with no `--session`. Independent tasks should not inherit an
      earlier task's context, which can carry over assumptions you rejected in review.
      
      Use `--session` **within** a task, for rework, not **between** tasks. The exception is a genuinely
      continuous piece of work split across dispatches for length; there, continuing the session preserves
      context that a cold brief would have to restate.
      
      ## Tracking progress
      
      Keep a visible checklist — the queue, one line each, marked as landed. Update it after the commit,
      not after the dispatch. A task is done when it is committed and the gates passed, not when ZCode
      said it finished.
      
      Record the `sessionId` of each task next to its line. If a landed task later turns out to be wrong,
      that id is the cheapest way back into its context.
      
      ## The end-of-run coherence check
      
      Individually correct changes can be collectively wrong. When the queue is done, review the whole
      range as one diff:
      
      ```bash
      git diff <commit-before-the-queue>..HEAD
      ```
      
      Look for what per-task review structurally cannot catch:
      
      - **Drift** — the same problem solved three different ways across tasks.
      - **Duplication** — a helper invented in task 2 and reinvented in task 7.
      - **Dead ends** — code added for a task that a later task made unnecessary.
      - **Half-migrations** — the old and new patterns now both present, with no task left to finish it.
      
      Then run the gates once more over the final state. A queue where every task passed its own gates can
      still end with a broken tree, because task N's gates ran before task N+1 existed.
      
      ## When to stop the queue
      
      Stop and go back to the human when:
      
      - Two consecutive tasks need rework for the same reason — the standing constraints are wrong, not
        the implementer.
      - A task reveals the plan was based on a wrong assumption about the codebase.
      - Correct completion needs a scope change. Ask; do not expand the mandate yourself.
      
      Stopping a queue at task 4 with a clear explanation is a better outcome than finishing all nine and
      handing over a diff you cannot defend.
      
    • review-and-land.md 4 KB
      # Review and land
      
      ZCode's `result.json` contains its own summary and its own claims about gates. Treat all of it as a
      hypothesis. You are the reviewer; the commit is yours.
      
      ## The checklist
      
      1. **Re-run the project's gates yourself.** Every time. "Gates passed" in `finalMessage` is a claim,
         not evidence. Run the actual commands from the brief and read their output.
      2. **Read the diff against the brief.** Did ZCode do what was asked — nothing more, nothing less?
         `touchedFiles` tells you where to look; `git diff` tells you what happened.
      3. **Check the "Out of scope" list.** Was anything on it touched?
      4. **Read the DECISIONS section** of the report. Anything ZCode chose that the brief did not specify
         is something you now own. Surface it; do not absorb it silently.
      5. **On a `--read-only` run**, confirm `touchedFiles` is `[]` and `readOnlyViolation` is `false`.
         Plan mode refuses edits, but the relay measures rather than assumes — see below.
      6. **Run your guard skills** on the diff if you have them installed. This skill produces the work;
         those skills judge it.
      7. For schema or migration changes, round-trip them. For removals, grep for dangling references.
      
      ## What `readOnlyViolation` means
      
      `plan` mode refused to write in testing, but whether that refusal is enforced by ZCode's tool layer
      or is model compliance is not established. So the relay fingerprints the repository before the run
      and compares afterwards:
      
      - `false` — no Git-visible change was detected. This is the expected result.
      - `true` — something changed during a read-only run. **Stop and inspect the tree.** The relay
        detects and reports; it does not attribute or revert.
      - `null` — git could not report, so the tripwire has no opinion. Inspect the tree directly.
      
      `readOnlyViolation` is `null` on `yolo` runs, where writes are the point.
      
      ## The commit boundary
      
      **The relay never commits.** Not on success, not on a clean gate run, not ever. Committing belongs
      to whoever reviewed the diff, and that is you.
      
      This is not a limitation to work around. If you find yourself wanting the implementer to commit, the
      review step is being skipped.
      
      ## Rework: the exact-session cycle
      
      When the diff needs changes, continue the same session rather than starting cold:
      
      ```bash
      node "<skill-dir>/scripts/relay.mjs" --brief delta-brief.txt --cd /path/to/repo --session sess_3d8fa06c-…
      ```
      
      - Take `sessionId` from the prior `result.json`.
      - **Send only the delta** — what was wrong and what to do instead. ZCode still has the earlier turn;
        re-sending the original brief wastes context and invites it to redo accepted work.
      - `--resume-last` continues the latest session for `--cd`. It is scoped to that directory rather
        than being a global "last", which makes it safer than it sounds — but `--session` is still the
        precise choice when you have the id.
      - Review the result again. A rework cycle gets the same scrutiny as the first pass.
      
      ## Authorization model
      
      Delegation is something the human opts into. Once they have — "run this queue", "proceed" —
      committing verified, gate-passing work is the agreed contract. Two limits on that mandate:
      
      **Surface, don't absorb.** Report ZCode's design decisions, its defensible-but-unasked turns, and
      non-blocking nitpicks. Your reviewer's summary should let the human disagree with a choice they
      would not have made. Silently keeping such a change makes it yours.
      
      **Stop for scope changes.** If correct completion requires going beyond the brief — a schema change
      the task implies, a dependency the fix needs, a refactor without which the change is unsafe — ask.
      Do not expand the mandate yourself, and do not let the implementer expand it for you.
      
      ## What to tell the human
      
      After landing, say what actually happened:
      
      - what changed, and why
      - which gates you ran, and their real output
      - what ZCode decided that the brief did not specify
      - anything you left undone, and why
      
      If a gate failed, say so with the output. If a step was skipped, say that. A clean report of a messy
      run is more useful than a confident summary that does not survive contact with the diff.
      
    • writing-the-brief.md 4.9 KB
      # Writing the brief
      
      ZCode starts every dispatch cold. It has no orchestrator chat history, no memory of the last task,
      and no idea what you already ruled out. The brief is the entire context, and a vague brief is the
      single most common cause of a diff you have to throw away.
      
      ## How the brief reaches ZCode
      
      The relay writes your brief to `brief.md` in its run directory and passes it with ZCode's
      `--attach` flag, alongside a fixed one-line prompt telling ZCode to follow the attached brief.
      
      That matters in two ways:
      
      - **The command line stops bounding the brief.** ZCode has no stdin delivery, so a brief passed as
        prompt text would be limited by the command line (about 32 767 characters on Windows). Attaching
        sidesteps that entirely — write the brief the task deserves. The configured model's context window
        still applies, so this buys room, not an unlimited budget.
      - **The brief is a document, not a chat message.** Structure it with headings. ZCode reads it as a
        file.
      
      ## Structure
      
      ```markdown
      # Goal
      One or two sentences. What must be true when this is done.
      
      # Current state
      Where the relevant code lives, what it does today, and anything already tried and rejected.
      Name files with paths. Do not make ZCode hunt.
      
      # Change
      Exactly what to do. Be specific about behaviour, not implementation, unless the implementation
      is the point.
      
      # Out of scope
      What to leave alone. This is the field that prevents scope creep — spend real effort on it.
      
      # Gates
      The project's ACTUAL commands, copied from its CLAUDE.md / AGENTS.md / Makefile / package.json.
      Do not invent these.
      
          node test/relay-smoke.mjs
          npx skills add . --list
      
      # Constraints
      Anything non-negotiable: dependency limits, style rules, files that must not be touched,
      platforms that must keep working.
      
      # Report contract
      End your final message with:
      - WHAT CHANGED: one line per file, with the reason
      - GATES: the command you ran and its actual result
      - DECISIONS: anything you chose that the brief did not specify
      - UNFINISHED: anything you could not complete, and why
      
      # You will not commit
      Do not run `git commit`, `git push`, or any command that writes to `.git`.
      The orchestrator reviews the diff and commits.
      ```
      
      ## The rules that actually matter
      
      **Embed the real gate commands.** The most common failure is a brief that says "run the tests" to an
      implementer with no idea what the test command is. Discover them from the repo first, then paste
      them. If you did not verify the command yourself, do not put it in the brief.
      
      **Spend effort on "Out of scope".** An implementer that is uncertain tends to do more, not less. A
      brief that says only what to change invites reformatting, drive-by refactors, and dependency
      additions. Name the things you do not want touched.
      
      **One task per brief.** If the brief has an "and then also", split it. Queues are for sequences —
      see [multi-task-queues.md](multi-task-queues.md).
      
      **Ask for a report contract.** You are going to re-verify everything anyway, but a structured report
      tells you where to look first, and the DECISIONS section is how you catch defensible-but-unasked
      turns before they reach your commit.
      
      **Say it will not commit.** The relay never commits, and ZCode running under `--mode yolo` has a
      Bash tool. Being explicit costs one line.
      
      ## Tool restrictions belong on the command line, not in the brief
      
      If the task genuinely must not touch certain tools, do not ask politely in the brief — pass
      `--disallowed-tools "Write,Edit,Bash"`. That denylist is enforced by ZCode: the named tools are
      absent from the session entirely. Prose in a brief is not.
      
      There is no allowlist counterpart — ZCode has no `--allowed-tools`. You can subtract capability, not
      enumerate it.
      
      ## For a read-only run
      
      A `--read-only` dispatch runs in ZCode's `plan` mode, which refuses edits. Briefs for these runs
      should ask for a deliverable **in the final message**, since no files will change:
      
      ```markdown
      # Goal
      Give a second opinion on the approach below. Do not change any files.
      
      # Agreed
      ...points both sides accept...
      
      # Contested
      1. <point> — Position A: ... Position B: ...
      2. ...
      
      # Report contract
      For each contested point, defend or concede, and say which evidence moved you.
      ```
      
      Then verify the result: `touchedFiles` is `[]` and `readOnlyViolation` is `false`. Plan mode's
      refusal is measured by the relay's Git tripwire, not guaranteed by a sandbox, and
      `readOnlyViolation` is tri-state — `true` means Git-visible changes were detected, `false` means
      none were, and `null` means the tripwire could not tell, which calls for inspecting the tree
      yourself rather than assuming either.
      
      ## Delta briefs for rework
      
      When you send work back with `--session <sessionId>`, ZCode still has the earlier turn. Send only
      what changed — the correction, not the whole original brief. Repeating the full brief wastes context
      and invites it to redo work you already accepted. See [review-and-land.md](review-and-land.md).
      
  • scripts
    • relay.mjs 46.9 KB · in bundle
  • SKILL.md 9.4 KB
    ---
    name: zcode-delegate
    description: >-
      Delegate a coding task to the Z.AI ZCode CLI as a background implementer, then review its diff and
      land it yourself. Use this whenever the user wants to hand implementation work to ZCode — phrasings
      like "have ZCode do X", "delegate this to ZCode", "run it through ZCode", or "use ZCode to
      implement/fix/refactor" — or to run a queue of coding tasks through ZCode while staying the
      reviewer. DO NOT USE for tasks small enough to do inline, or when the user wants the code written
      directly without delegating.
    license: MIT
    compatibility: Requires the `zcode` CLI (Z.AI ZCode) with a configured model provider, Node 18+, and git. ZCode ships its CLI inside the desktop app rather than on PATH or npm — see Prerequisites. The orchestrating agent must be able to run shell commands and read files. Shell examples assume bash/zsh (macOS/Linux, or Git Bash/WSL on Windows).
    metadata:
      version: 0.5.0
    ---
    
    # ZCode Delegate
    
    You are the **orchestrator**. This skill lets you hand a bounded coding task to a separate
    **implementer** — the Z.AI ZCode CLI — then review what it produced and land it yourself. You write
    the brief and own the judgment; ZCode does the typing; you verify and commit.
    
    Nothing here is specific to one orchestrating agent. The loop needs only the ability to run a shell
    command and read a file. (It is designed for and run on Claude Code; treat other orchestrators as
    designed-for, not yet proven.)
    
    ## When NOT to use this
    
    - The task is small enough to just do inline — delegation overhead is not worth it.
    - ZCode is not installed, or its CLI has no model provider configured.
    - You want to write the code yourself, or you only need a review.
    
    ## Prerequisites (check once)
    
    1. **ZCode is installed.** The CLI ships **inside the desktop app** — it is not on PATH and not on
       npm. The relay resolves it in this order: `--zcode-path <file>` or `ZCODE_CLI` first, then PATH,
       then the installed app bundle. On Linux the app is an AppImage with no fixed install path, so
       the flag or the environment variable is required there — the relay guesses nothing.
    2. **A model provider is configured for the CLI**, with a key it can actually reach. Being signed
       into the desktop app is *not* enough — see below.
    3. You are in (or will point `--cd` at) the target git repository.
    
    The relay records the CLI version and how it was resolved into `result.json`, so a surprising
    install is visible after the fact.
    
    ## Authenticating the headless CLI
    
    **Signing into the ZCode desktop app does not authenticate the CLI this relay drives.** The CLI
    keeps its own config at `~/.zcode/cli/config.json`, separate from the desktop app's, and nothing
    bridges the two. `zcode login` is the intended path, but where it fails with `OAuth response is
    not valid JSON` the way in is a Z.AI API key.
    
    Two pieces are needed, and they are separate:
    
    1. **The provider block** must exist in `~/.zcode/cli/config.json`. It defines the provider, its
       endpoint and its models — the environment cannot supply this:
    
       ```jsonc
       {
         "provider": {
           "zai": {
             "kind": "anthropic",
             "options": { "apiKeyRequired": true, "baseURL": "https://api.z.ai/api/anthropic" },
             "models": { "glm-5.1": { "name": "GLM-5.1" } }
           }
         },
         "model": { "main": "zai/glm-5.1" }
       }
       ```
    
    2. **The key** can live either in `provider.zai.options.apiKey` in that file, or in the
       environment as any one of `ZAI_API_KEY`, `ZCODE_API_KEY`, or `ANTHROPIC_API_KEY`. Prefer the
       environment — it keeps the secret off disk.
    
    If a run fails with `Model provider is missing an API key: <provider>`, the provider block resolved
    but no key was found: set one of those variables and re-run.
    
    ## Autonomy — read this before dispatching
    
    ZCode's own term is **mode**. It has four values; only two are usable headlessly.
    
    | mode | Behaviour |
    | --- | --- |
    | `yolo` | **Writes.** ZCode's own default for `--prompt`, and this relay's write-capable default. |
    | `plan` | **Refuses edits.** What `--read-only` selects. |
    | `build` | **Rejected by this relay.** No permission client exists headlessly, so tools are blocked and the run exits 0 having done nothing. |
    | `edit` | Rejected for the same reason. |
    
    Two limits stated plainly, because ZCode cannot enforce them:
    
    - **`plan` mode refused edits in testing, but the relay does not treat that as a guarantee.** It
      takes a Git fingerprint before the run and reports a tri-state `readOnlyViolation` afterwards.
      Confirm `touchedFiles` came back empty rather than assuming no edits.
    - **ZCode has no `--allowed-tools`.** Only the `--disallowed-tools` denylist exists, and it *is*
      genuinely enforced. An explicit allowlisted tool surface is therefore impossible here — do not
      assume one.
    
    ## The loop
    
    Run these five steps per task. Steps 1, 4, and 5 are your judgment; 2 and 3 are mechanical.
    
    ### 1. Write the brief
    
    ZCode sees **only** what you send — no repo memory, no chat history. Everything the task needs goes
    in the brief: the goal, the current state, what to change, what to leave untouched, the project's
    **actual** gate commands (discover them from the repo's CLAUDE.md/AGENTS.md/Makefile — do not
    assume), and a report contract. Tell ZCode it will **not** commit. One task per brief. The relay
    delivers the brief as an attached file, so the command line no longer bounds its length — the
    model's context window still does. Full guidance and a template:
    [references/writing-the-brief.md](references/writing-the-brief.md).
    
    ### 2. Dispatch
    
    ```bash
    node "<skill-dir>/scripts/relay.mjs" --brief brief.txt --cd /path/to/repo
    # read-only (review/diagnosis, no edits):   add --read-only
    # continue a specific session:              add --session <sess_...>  (from result.json; send only the delta brief)
    # continue the latest session for --cd:     add --resume-last
    # withhold tools (denylist):                add --disallowed-tools "Write,Edit,Bash"
    # point at the CLI explicitly:              add --zcode-path /path/to/zcode.cjs
    # hard time limit (watchdog):               add --timeout 2h  (default: off)
    # see all options:                          node .../relay.mjs --help
    ```
    
    (`<skill-dir>` is this skill's installed directory — the folder containing this `SKILL.md`.)
    
    The relay writes its artifacts to a temp dir, so the repo under review stays clean. It **never
    commits** — see step 5. Mechanics, flags, and the `result.json` shape:
    [references/dispatch-and-poll.md](references/dispatch-and-poll.md).
    
    ### 3. Wait for completion
    
    The relay blocks until ZCode finishes, so back it with whatever your orchestrator offers:
    
    - **Claude Code:** run the Bash call with `run_in_background: true`; you are notified on completion.
    - **Plain shell / other agents:** foreground for short tasks, or background it and poll the result
      file. The run is done when `result.json` exists with a `status`. A pre-run usage error exits 2 and
      writes **no** result file, so check the exit code too; a CLI that cannot be found exits 127 but
      *does* write a `result.json` with status `zcode_unavailable`.
    
    Do not trust progress trackers over reality: read the working tree, not a status line.
    
    ### 4. Review — do not trust the self-report
    
    - **Re-run the project's gates yourself.** Never take "gates passed" on faith.
    - **Read the diff** against the brief: did ZCode do what was asked, nothing more and nothing less?
      `touchedFiles` is your starting point.
    - **On a `--read-only` run, check `readOnlyViolation` and confirm `touchedFiles` is empty.**
    - Run the relevant guard skills on the diff if you have them installed.
    
    Full checklist: [references/review-and-land.md](references/review-and-land.md).
    
    ### 5. Land it
    
    **The orchestrator commits.** Only after the gates pass and the diff holds:
    
    - Commit the verified work yourself, with a clear message.
    - If it needs changes, send a delta brief with `--session <sessionId>` from the prior `result.json`,
      and review again.
    
    ## Read-only second opinions
    
    The relay doubles as a way to get an adversarial second opinion with no write risk: dispatch
    `--read-only` with a brief listing the agreed points, then each contested point with both positions,
    and ask ZCode to defend or concede each. Because plan mode's guarantee is measured rather than
    enforced here, verify `touchedFiles` came back empty instead of assuming no edits.
    
    ## Authorization model
    
    Delegation is something the human opts into. Once they have, committing verified, gate-passing work
    is the agreed contract. Two limits: **surface, don't absorb** (report ZCode's design decisions and
    defensible-but-unasked turns rather than silently keeping them) and **stop for scope changes** (if
    correct completion needs going beyond the brief, ask). The full treatment is in
    [references/review-and-land.md](references/review-and-land.md).
    
    ## References
    
    - [references/writing-the-brief.md](references/writing-the-brief.md) — how to write a brief ZCode can
      execute blind: structure, the report contract, embedding the real gate commands.
    - [references/dispatch-and-poll.md](references/dispatch-and-poll.md) — `relay.mjs` flags, the
      `result.json` contract, how the CLI is resolved, backgrounding, and recovery.
    - [references/review-and-land.md](references/review-and-land.md) — the review checklist, the commit
      boundary, and the exact-session rework cycle.
    - [references/multi-task-queues.md](references/multi-task-queues.md) — running a sequential queue:
      carrying constraints forward, progress tracking, and the end-of-run coherence check.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related