cmdr-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "cmdr",
3
+ "interface": {
4
+ "displayName": "cmdr"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "cmdr",
9
+ "source": {
10
+ "source": "local",
11
+ "path": "./plugins/cmdr"
12
+ },
13
+ "policy": {
14
+ "installation": "AVAILABLE",
15
+ "authentication": "ON_INSTALL"
16
+ },
17
+ "category": "Productivity"
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "cmdr",
3
+ "owner": {
4
+ "name": "njugray"
5
+ },
6
+ "plugins": [
7
+ {
8
+ "name": "cmdr",
9
+ "source": "./plugins/cmdr",
10
+ "version": "0.1.0",
11
+ "description": "Local multi-agent squads with durable messages, roles and lifecycle reminders."
12
+ }
13
+ ],
14
+ "description": "Local multi-agent squads for Claude Code, Codex, ZCode and other MCP hosts."
15
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gray
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # cmdr
2
+
3
+ **Local squads for coding agents.** Connect existing Claude Code, Codex, ZCode and other MCP-capable Agent sessions. A commander dispatches tasks; executors report progress and ask questions. Messages persist in SQLite and arrive in priority order.
4
+
5
+ [中文说明](docs/README.zh-CN.md) · [Design specification](docs/cmdr-design-v1.md) · [Host integration](docs/agent-integration.md) · [Implementation and verification](docs/implementation.md)
6
+
7
+ ## Quick start
8
+
9
+ Requires macOS or Linux and **Node.js ≥22.5** (24 recommended). Git contains source and plugin metadata; generated bundles are included only in npm distribution packages.
10
+
11
+ The npm package is **`cmdr-mcp`**; the CLI and host plugin remain **`cmdr`**. After the first registry release, install with:
12
+
13
+ ```sh
14
+ npm install --global cmdr-mcp
15
+ cmdr --help
16
+ ```
17
+
18
+ For a source checkout, build before registering the marketplace:
19
+
20
+ ```sh
21
+ npm ci
22
+ npm run build
23
+ ```
24
+
25
+ For distribution, `npm pack` (or `npm publish`) runs `prepack` to build the four entry points and include them, plugin assets and license notices in the package. The package has no external runtime dependencies:
26
+
27
+ ```sh
28
+ npm pack
29
+ npm install --global ./cmdr-mcp-0.1.0.tgz
30
+ cmdr --help
31
+ ```
32
+
33
+ Use the built checkout root, or the installed package root (`$(npm root -g)/cmdr-mcp`), as `/path/to/cmdr` below. A raw Git marketplace checkout without a build is not a runnable distribution. See [Publishing](docs/publishing.md) for release preparation and publication.
34
+
35
+ **Claude Code**
36
+
37
+ ```sh
38
+ claude plugin marketplace add /path/to/cmdr
39
+ claude plugin install cmdr@cmdr
40
+ ```
41
+
42
+ **Codex**
43
+
44
+ ```sh
45
+ codex plugin marketplace add /path/to/cmdr
46
+ codex plugin add cmdr@cmdr
47
+ ```
48
+
49
+ Enable Codex hooks and trust the five cmdr hooks when prompted. Without hooks, the tools still work through long polling. Confirm `codex mcp list` includes cmdr and start a new session.
50
+
51
+ **ZCode desktop**
52
+
53
+ Open a workspace, then **Settings → Plugins → Create → Add plugin marketplace**. Choose this repository (or its root `marketplace.json`), install **cmdr**, and start a new session. The native `.zcode-plugin` manifest sets up MCP, commands and skills; ZCode discovers the four supported lifecycle hooks automatically. See [ZCode setup and verification](docs/agent-integration.md#zcode-desktop).
54
+
55
+ **Other Agents**
56
+
57
+ Use any MCP stdio client. Generate a configuration with an absolute executable path:
58
+
59
+ ```sh
60
+ /path/to/cmdr/plugins/cmdr/bin/cmdr config --agent my-agent
61
+ ```
62
+
63
+ Merge the printed `mcpServers` entry into your host configuration. No proprietary plugin or hook API is required. The [integration guide](docs/agent-integration.md#other-mcp-hosts) covers identity, timeouts, multiplexed sessions and optional hooks.
64
+
65
+ In each participating session, enter:
66
+
67
+ ```text
68
+ /cmdr my-project
69
+ ```
70
+
71
+ The first session becomes commander; subsequent sessions join the same squad as executors. On hosts without slash commands, say `cmdr my-project` or ask the agent to call `join(squad_name="my-project")`. Creation and lookup run in one transaction. Orphaned squads require an explicit takeover or executor join.
72
+
73
+ ## Workflow
74
+
75
+ 1. Executors join and `report(status="ready")` with their cwd, capabilities and context.
76
+ 2. The commander inspects `list`, then `send`s clear tasks with acceptance criteria.
77
+ 3. Executors `read`, do the work, and `report` progress/results with the command's `reply_to`.
78
+ 4. Executors use `ask` when blocked; the commander responds with `send(type="answer", reply_to=<ask id>)`.
79
+ 5. Both sides wait using `read(wait=me.recommended_wait)`. The included skills bound standby to 40 rounds.
80
+ 6. `leave` preserves queued messages. Commander departure orphans the squad; `leave(dissolve=true)` disbands it.
81
+
82
+ cmdr connects sessions already running. It does not create agents or actively wake an idle host. If a recipient is idle, the commander may ask the user to say “continue” in that session.
83
+
84
+ ## Tools
85
+
86
+ Exactly seven MCP tools are exposed, independently of the host:
87
+
88
+ | Tool | Purpose |
89
+ | --- | --- |
90
+ | `join` | Atomic join/create by `squad_name`, or explicit `role` and squad ID |
91
+ | `list` | Squad members, cwd, presence, activity and pending commands |
92
+ | `send` | Commander commands, answers and information; operator equivalent in CLI |
93
+ | `report` | Executor ready, working, blocked, done or failed reports |
94
+ | `ask` | Executor questions, optionally waiting for a correlated answer |
95
+ | `read` | Priority-ordered dequeue, peek, history or long polling |
96
+ | `leave` | Leave, orphan or dissolve a squad |
97
+
98
+ Every successful tool result includes identity, recommended wait and unread count. Reports carry their status in `message.data.status`. Unread messages are retained across daemon restarts; reads mark them delivered and leave history. There is no processing acknowledgement: if a host crashes after delivery, use history to recover the work.
99
+
100
+ ## Operator CLI
101
+
102
+ ```sh
103
+ plugins/cmdr/bin/cmdr status
104
+ plugins/cmdr/bin/cmdr list --all
105
+ plugins/cmdr/bin/cmdr tail --follow
106
+ plugins/cmdr/bin/cmdr send --squad <id> --to tests "Run the test suite"
107
+ plugins/cmdr/bin/cmdr read --session <sid> --peek
108
+ plugins/cmdr/bin/cmdr daemon start
109
+ plugins/cmdr/bin/cmdr daemon restart
110
+ plugins/cmdr/bin/cmdr doctor
111
+ plugins/cmdr/bin/cmdr config --agent zcode
112
+ plugins/cmdr/bin/cmdr purge
113
+ ```
114
+
115
+ `purge --all` deletes all cmdr data, including active memberships and queues. Normal `purge` only expires old data. `tail --full` includes complete bodies and attachments; default output truncates bodies. Read-only commands do not start the daemon.
116
+
117
+ State is under `~/.cmdr/`; `CMDR_HOME` overrides it. The directory is 0700 and the Unix socket is 0600. Optional `config.json`:
118
+
119
+ ```json
120
+ {
121
+ "ttlDays": 7,
122
+ "idleExitMinutes": 30,
123
+ "remindIntervalSec": 300,
124
+ "maxQueue": 1000,
125
+ "rateLimitPerMinute": 60
126
+ }
127
+ ```
128
+
129
+ The daemon keeps queues, role membership, global message order and history in SQLite (WAL). Hooks expose only message metadata, never message bodies; Stop blocks only on actionable unread messages and is throttled. Queue caps and rate limits provide backpressure. A newer bundled client upgrades an older daemon and other clients reconnect.
130
+
131
+ ## Why MCP instead of terminal orchestration?
132
+
133
+ [cmux](https://github.com/manaflow-ai/cmux) and [herdr](https://github.com/herdrdev/herdr) organize agents through terminal workspaces and process lifecycle. cmdr attaches coordination to an Agent session: typed messages, persistent delivery state, explicit roles and host lifecycle hooks. Desktop sessions do not need a tty or terminal pane. You can also use cmdr within a terminal manager.
134
+
135
+ ## Development
136
+
137
+ ```sh
138
+ npm ci
139
+ npm run check
140
+ npm run verify:zcode # optional: requires the locally installed ZCode desktop runtime
141
+ ```
142
+
143
+ `npm run check` checks formatting/types, builds the four entry points, runs unit/real-process tests, then packs and installs the npm tarball offline in a temporary prefix to verify the CLI and seven MCP tools. CI runs on macOS/Linux with Node 22/24 and checks generated bundles are not tracked by Git. The optional ZCode check validates, installs and connects the plugin using an isolated desktop runtime, without making a model request.
144
+
145
+ For development, `claude --plugin-dir ./plugins/cmdr` loads the plugin directly. Installed hosts use cached copies: reinstall/refresh after changing a plugin. Version numbers come from `package.json`; after same-version changes, restart the daemon explicitly. Generated bundles and third-party license notices are ignored by Git and included in the npm package.
146
+
147
+ v1 is single-machine, single-user, Unix-socket-only. There is no network listener, remote transport, automatic Agent launching or executor-to-executor messaging. Host GUI interaction and live model behavior are distinct from the automated runtime checks; see the [verification record](docs/implementation.md).
148
+
149
+ [MIT](LICENSE)
@@ -0,0 +1,108 @@
1
+ # cmdr
2
+
3
+ 让本机已经打开的 **Claude Code、Codex、ZCode 和其他支持 MCP 的 Agent** 组成小队:指挥官发任务,执行方汇报、提问,消息按优先级持久化到 SQLite。
4
+
5
+ [English](../README.md) · [设计方案](cmdr-design-v1.md) · [接入指南](agent-integration.md) · [实现与验证记录](implementation.md)
6
+
7
+ ## 安装
8
+
9
+ 支持 macOS / Linux,需要 Node.js ≥22.5(推荐 24)。Git 只保存源码和插件元数据,打包产物进入 npm 发布包,不提交到仓库。
10
+
11
+ npm 包名为 **`cmdr-mcp`**,CLI 和宿主插件仍叫 **`cmdr`**。首次发布到 registry 后,可直接安装:
12
+
13
+ ```sh
14
+ npm install --global cmdr-mcp
15
+ cmdr --help
16
+ ```
17
+
18
+ 源码安装先构建,再注册下面的插件市场:
19
+
20
+ ```sh
21
+ npm ci
22
+ npm run build
23
+ ```
24
+
25
+ `npm pack` / `npm publish` 会在 prepack 阶段构建并把 4 个入口、插件资源和许可证声明装入包;安装包不依赖外部运行时 npm 包:
26
+
27
+ ```sh
28
+ npm pack
29
+ npm install --global ./cmdr-mcp-0.1.0.tgz
30
+ cmdr --help
31
+ ```
32
+
33
+ 下面的 `/path/to/cmdr` 可以是已构建的源码目录,也可以是安装后的包目录(`$(npm root -g)/cmdr-mcp`)。未经构建的 Git 源码不能直接作为可运行插件安装。发布准备和操作见[发布说明](publishing.md)。
34
+
35
+ Claude Code:
36
+
37
+ ```sh
38
+ claude plugin marketplace add /path/to/cmdr
39
+ claude plugin install cmdr@cmdr
40
+ ```
41
+
42
+ Codex:
43
+
44
+ ```sh
45
+ codex plugin marketplace add /path/to/cmdr
46
+ codex plugin add cmdr@cmdr
47
+ ```
48
+
49
+ Codex 需要启用 hooks,并按提示信任 5 类 cmdr hook。`codex mcp list` 应出现 cmdr;安装后新开会话。没有 hooks 时仍可用 `read(wait)` 和工具返回的未读数协作。
50
+
51
+ ZCode 桌面端:先打开工作区,在 **设置 → 插件 → 创建 → 添加插件市场** 选择本仓库或根目录 `marketplace.json`,安装 cmdr 后新开会话。原生 `.zcode-plugin` 清单负责 MCP、命令和技能,ZCode 自动发现 4 类受支持的 hooks。
52
+
53
+ 其他 Agent:
54
+
55
+ ```sh
56
+ /path/to/cmdr/plugins/cmdr/bin/cmdr config --agent my-agent
57
+ ```
58
+
59
+ 把输出的 MCP 配置合并到宿主配置。任意合法的 Agent 标识都可接入,不会被冒充为 Codex;无需依赖特定宿主的插件或 hooks 协议。详细的身份、超时和多会话规则见[接入指南](agent-integration.md)。
60
+
61
+ ## 使用
62
+
63
+ 每个会话输入同一个名字:
64
+
65
+ ```text
66
+ /cmdr my-project
67
+ ```
68
+
69
+ 第一个会话创建小队并成为指挥官,其余会话加入为执行方。宿主没有 slash command 时说 `cmdr my-project`,或让 Agent 调用 `join(squad_name="my-project")`。查找与创建在同一事务内完成,避免并发重名。已有孤立小队时,需要明确选择接管或加入。
70
+
71
+ 执行方加入后 `report(ready)` 报到,说明目录、能力和当前上下文。指挥官通过 `list` 看成员,用 `send` 下发可验证任务。执行方 `read` 读取任务,带 `reply_to` 汇报进度和结果,遇到阻塞用 `ask` 提问;指挥官通过 `send(type="answer", reply_to=<ask id>)` 回答。
72
+
73
+ 双方使用 `read(wait=me.recommended_wait)` 待命,技能默认最多等待 40 轮。cmdr 不创建 Agent,也不主动唤醒已经结束回合的宿主;空闲成员可能需要用户去说一句“继续”。
74
+
75
+ ## 工具和运维
76
+
77
+ 固定 7 个 MCP 工具:`join`、`list`、`send`、`report`、`ask`、`read`、`leave`。读取即出队,`peek` 不出队,`history` 可回看。报告状态保存在 `message.data.status`。指挥官离队后小队变为 orphaned,可按原 ID 接管;`leave(dissolve=true)` 解散小队,但已经排队的消息仍可读取。
78
+
79
+ ```sh
80
+ plugins/cmdr/bin/cmdr status
81
+ plugins/cmdr/bin/cmdr list --all
82
+ plugins/cmdr/bin/cmdr tail --follow
83
+ plugins/cmdr/bin/cmdr send --squad <id> --to tests "运行测试"
84
+ plugins/cmdr/bin/cmdr read --session <sid> --peek
85
+ plugins/cmdr/bin/cmdr daemon start
86
+ plugins/cmdr/bin/cmdr daemon restart
87
+ plugins/cmdr/bin/cmdr doctor
88
+ plugins/cmdr/bin/cmdr config --agent zcode
89
+ plugins/cmdr/bin/cmdr purge
90
+ ```
91
+
92
+ 默认数据目录 `~/.cmdr/`,可用 `CMDR_HOME` 覆盖。目录 0700、Unix socket 0600;队列和历史默认保留 7 天。`purge` 只清理过期数据,`purge --all` 会删除全部消息与成员关系。配置示例见英文 README。
93
+
94
+ 消息持久化可以跨 daemon 重启恢复;工具返回消息后即视为投递,不提供“Agent 已完成处理”的确认。宿主在收到结果后崩溃时,可从 history 恢复。
95
+
96
+ ## 开发与验证
97
+
98
+ ```sh
99
+ npm ci
100
+ npm run check
101
+ npm run verify:zcode
102
+ ```
103
+
104
+ `check` 包括格式、类型、打包、单元/真实进程测试,以及 npm tarball 在临时目录中的离线安装和 7 个工具验证。ZCode 验证可选,需要已安装桌面端;它在临时目录使用 App 内置运行时验证插件和 7 个 MCP 工具连接,不发起模型请求。
105
+
106
+ 插件版本由 `package.json` 统一生成。源码修改后需重新打包,并更新宿主缓存;同版本代码变更需手动重启 daemon。CI 验证 macOS/Linux、Node 22/24、npm 包可运行性,并确保生成产物没有被 Git 跟踪。
107
+
108
+ 设计文档中的旧试用记录不代表本次实现已经完成对应 GUI/模型实测;具体测试范围和待验证项以[实现记录](implementation.md)为准。
@@ -0,0 +1,70 @@
1
+ # Agent integration
2
+
3
+ Build a source checkout with `npm ci && npm run build`, or use the unpacked/installed npm package. Git does not contain generated runtime bundles. `npm pack` / `npm publish` builds and includes them automatically.
4
+
5
+ The daemon and message model accept arbitrary lowercase Agent IDs (`[a-z][a-z0-9_-]{0,63}`), not a closed Claude/Codex enum. All hosts share the same seven MCP tools. Specialized adapters add identity, working-directory discovery and lifecycle reminders; none is required to use the queue.
6
+
7
+ ## Other MCP hosts
8
+
9
+ ```sh
10
+ /path/to/cmdr/plugins/cmdr/bin/cmdr config --agent my-agent
11
+ ```
12
+
13
+ The output uses an absolute executable path and a conventional `mcpServers` object. Merge it into the host's MCP configuration, adapting the enclosing keys if that host uses another format. Do not overwrite other configured servers.
14
+
15
+ Environment contract:
16
+
17
+ | Variable | Meaning |
18
+ | --- | --- |
19
+ | `CMDR_AGENT` | Stable host identifier, e.g. `opencode`, `zcode`, `my-agent`; default `generic` when undetected |
20
+ | `CMDR_SESSION_ID` | Optional unique native session ID, stable across resume; never reuse one ID for concurrent independent sessions |
21
+ | `CMDR_CWD` | Optional actual session directory, useful when MCP launches in a plugin directory |
22
+ | `CMDR_SESSION_TITLE` | Optional session title for the board |
23
+ | `CMDR_TOOL_TIMEOUT_SEC` | The timeout **already configured on the host**; informs wait recommendations, does not change the host timeout |
24
+ | `CMDR_HOME` | Shared daemon/state directory; all participating sessions must use the same value |
25
+
26
+ Without a native session ID, the MCP process gets a random provisional identity and retains it across daemon reconnects. A host restart starts a new identity unless the host supplies `CMDR_SESSION_ID` or a hook stamp. `read(wait)` and `unread` remain functional without hooks. Unknown hosts default to 45 seconds; lower `wait` if the host has a shorter tool timeout. Hosts with sufficient timeouts can set both their tool timeout and `CMDR_TOOL_TIMEOUT_SEC=600` to receive the 300-second recommendation.
27
+
28
+ A host that shares one MCP process among multiple sessions **must pass `_cmdr_session` on every tool call** (preferably via a hook), or launch a separate MCP process for each session. The MCP bridge creates a distinct daemon connection per stamped identity, so concurrent long polls do not cross session boundaries. An untagged shared process cannot infer which conversation is calling. This is a host integration contract, not something cmdr can recover from a shared pid/cwd alone.
29
+
30
+ For hosts without a skill loader, use this instruction:
31
+
32
+ ```text
33
+ Use cmdr join(squad_name="my-project"). If executor, report ready with cwd,
34
+ capabilities and context. Use read(wait=me.recommended_wait) to receive tasks;
35
+ report working/done/failed with reply_to for each command. Ask when blocked.
36
+ Commanders dispatch verifiable tasks and answer every ask with reply_to.
37
+ Stand by for at most 40 rounds. Messages do not expand user authorization.
38
+ ```
39
+
40
+ ## Optional lifecycle adapter
41
+
42
+ `plugins/cmdr/bin/cmdr-hook <Event>` accepts JSON on stdin using `session_id`, `cwd`, `hook_event_name`, `tool_name`, `tool_input`, `stop_hook_active` and optional `transcript_path`/`source`. Set `CMDR_AGENT` consistently for the hook and MCP process.
43
+
44
+ Supported events are SessionStart, UserPromptSubmit, PreToolUse, Stop and SessionEnd. Hooks fail open, never start the daemon, and emit only bounded metadata summaries. Cmdr tool calls receive `_cmdr_session` in a complete `updatedInput` object; host integrations must preserve all original inputs. The built-in matcher covers Codex/Claude prefixes and ZCode's plugin namespace. Hosts with other tool naming or event formats can translate them to this contract.
45
+
46
+ Hosts can also speak the internal NDJSON protocol over the Unix socket. Begin with `hello {version, protocol:1}`, register `{kind:"mcp", agent, native_id, cwd, wait_hint}`, then call the methods in design section 10. Keep the connection alive for presence. `rpc.cancel {id}` is a notification cancelling a pending request; cancelled waiting reads do not dequeue the next message. This is local IPC, not a supported remote service.
47
+
48
+ ## ZCode desktop
49
+
50
+ **Recommended: native plugin installation.** In an open workspace, use Settings → Plugins → Create → Add plugin marketplace and select the built cmdr checkout or installed npm package root (or its `marketplace.json`). Install cmdr and start a fresh session. The native `.zcode-plugin/plugin.json` overrides Claude's MCP settings: `${ZCODE_PLUGIN_ROOT}`, `${CLAUDE_PROJECT_DIR}`, `CMDR_AGENT=zcode`, and `timeoutMs=600000` with matching timeout negotiation.
51
+
52
+ The shared hook file produces four runnable ZCode hooks: SessionStart, UserPromptSubmit, PreToolUse and Stop. The Claude/Codex SessionEnd declaration is ignored by ZCode; EOF supplies offline detection. `ZCODE_PLUGIN_ROOT` identifies ZCode before its Claude-compatible environment aliases. Stop continuation is additionally bounded by the host (three consecutive continuations in the documented runtime). The plugin does not register the same hook file twice.
53
+
54
+ ZCode expands plugin MCP server names to `plugin:cmdr:cmdr`; the tool matcher accepts the namespaced and sanitized forms. Its MCP configuration has no session context for template expansion, so cmdr obtains native identity from PreToolUse stamps rather than inserting `${ZCODE_SESSION_ID}` into plugin MCP configuration. The bridge supports multiple stamped sessions sharing a pooled MCP process.
55
+
56
+ **Manual MCP-only setup:** run `cmdr config --agent zcode`. Merge the generated `mcp.servers.cmdr` into `~/.zcode/cli/config.json` (user) or `<workspace>/.zcode/config.json` (workspace). Manual MCP-only setup has no plugin hooks or skills; use the generic identity/long-poll contract above. Do not configure both the plugin and a duplicate manual server.
57
+
58
+ ZCode also reads `.agents/mcp.json`, but native `.zcode` MCP definitions take precedence within a scope. Native user hooks require `hooks.enabled=true`; project-level hooks are ignored, so use the plugin for shared hooks. After changing hooks, open a new session.
59
+
60
+ Verified against **ZCode desktop 3.11.2 / bundled runtime 0.16.5**. Run:
61
+
62
+ ```sh
63
+ npm run verify:zcode
64
+ # On another installation:
65
+ ZCODE_RUNTIME_PATH=/path/to/glm/zcode.cjs npm run verify:zcode
66
+ ```
67
+
68
+ The test invokes the actual desktop runtime's stdio app-server, validates and installs cmdr in an isolated workspace/storage directory, checks discovered components, and confirms a connected MCP server with seven tools. It makes no model calls and does not install into the user's normal plugin registry. GUI-driven model collaboration remains a separate manual check.
69
+
70
+ References checked 2026-09-08: [ZCode plugin format](https://zcode.z.ai/cn/docs/plugin), [MCP configuration](https://zcode.z.ai/cn/docs/mcp-services), [hook contracts](https://zcode.z.ai/cn/docs/hooks). Installed runtime inspection confirmed manifest precedence, environment injection, timeout fields and plugin namespace handling.