ferrycat 0.3.2 → 0.4.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.
package/README.md CHANGED
@@ -5,6 +5,8 @@
5
5
  <a href="README_zh.md">中文</a>
6
6
  </p>
7
7
 
8
+ [![npm version](https://img.shields.io/npm/v/ferrycat.svg?style=flat&color=cb3837&logo=npm)](https://www.npmjs.com/package/ferrycat)
9
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-Active-10b981?style=flat)](https://registry.modelcontextprotocol.io/v0/servers?search=ferrycat)
8
10
  [![Node.js Version](https://img.shields.io/badge/Node.js-22.5%2B-339933?style=flat&logo=nodedotjs)](https://nodejs.org/)
9
11
  [![Native Addons](https://img.shields.io/badge/Native_Addons-0_(node%3Asqlite)-success?style=flat)]()
10
12
  [![Protocol](https://img.shields.io/badge/Protocol-MCP_Stdio-orange?style=flat)](https://modelcontextprotocol.io/)
@@ -15,7 +17,7 @@
15
17
  > Purpose-built to safely bridge isolated desktop IDE agent hosts (such as Google Antigravity, WorkBuddy, Claude Code, and Cursor) across separate OS processes without context drift or blind reviews on stale files.
16
18
 
17
19
  <p align="center">
18
- <img src="https://guobug.github.io/assets/images/flowchart-ferrycat-cross-host-demand-and-workflow.svg" alt="FerryCat Architecture and Workflow" width="960" />
20
+ <img src="https://guobug.github.io/assets/images/flowchart-ferrycat-cross-host-demand-and-workflow-en.svg" alt="FerryCat Architecture and Workflow" width="960" />
19
21
  </p>
20
22
 
21
23
  > 📖 **Deep Dive**: [Why I Started Building FerryCat: When Two AI Coding Hosts Live on the Same Desktop](https://guobug.github.io/posts/2026/10/22/why-we-built-ferrycat-cross-host-agent-review-bus/)
@@ -118,6 +120,7 @@ Holder-side lifecycle controls on a `CLAIMED` contract (all require `agent_id ==
118
120
  ### 6. Threat Model & Security Assumptions (Local Workstation IPC)
119
121
  - **Assumed Trust Environment**: FerryCat is intentionally designed as a **Trusted Local Workstation Bus** bridging isolated IDE hosts operating under the **same OS user account**. Callers and workers share the local file system (`workspace_root`) and SQLite database (`~/.ferrycat/mesh.db`).
120
122
  - **Defense Scope**: Path containment (`assertSafePointerPath`) and sensitive file pattern filters prevent unintentional workspace escapes, symlink traversals, or accidental leakage of credentials/secret files during handoffs.
123
+ - **Daemon Execution Surface**: In daemon mode (`ferrycat-cli daemon`), handler scripts are invoked directly via `execFile`. Write permissions to `ferrycat.config.json` or handler script paths are equivalent to host execution privileges (ADR-0005 §2.2). Keep configurations local and version-controlled.
121
124
  - **Out of Scope (Non-Goals)**: FerryCat does **not** provide adversarial sandboxing, multi-tenant isolation, or network authorization against malicious local processes or adversarial agents spoofing `AGENT_NAME`.
122
125
 
123
126
  ---
@@ -126,32 +129,97 @@ Holder-side lifecycle controls on a `CLAIMED` contract (all require `agent_id ==
126
129
 
127
130
  1. **Disjoint File Systems**: FerryCat offloads context by file reference; both hosts must share access to the same local `workspace_root`.
128
131
  2. **Trivial Single-Turn Queries**: Each cross-host handoff involves 3 explicit human window switches (~15–25s overhead).
129
- 3. **Unattended Background Pipelines**: Desktop IDE hosts follow a request-response model and cannot be woken up asynchronously by an idle MCP server. For unattended multi-step pipelines, use a standalone DAG workflow engine such as [PatchCat](https://github.com/GuoBug/ai-prompt-orchestrator).
132
+ 3. **Multi-Step Dynamic DAG Pipelines**: FerryCat's background daemon (`ferrycat-cli daemon`, ADR-0005) manages single-step contract dispatch and supervised worker lifecycles; for complex multi-step branching DAG orchestrations, use dedicated DAG workflow engines such as [PatchCat](https://github.com/GuoBug/ai-prompt-orchestrator).
133
+
134
+ ---
135
+
136
+ ## Controlled Daemon & Declarative Handlers (ADR-0005)
137
+
138
+ FerryCat provides a controlled daemon mode governed by SQLite microsecond CAS leases on `daemon_locks` and declarative scripts defined in `ferrycat.config.json`:
139
+
140
+ ```bash
141
+ # Run a single dispatch cycle with declared handlers
142
+ ferrycat-cli daemon --config ./ferrycat.config.json --once
143
+
144
+ # Start continuous daemon loop
145
+ ferrycat-cli daemon --config ./ferrycat.config.json
146
+ ```
147
+
148
+ Example `ferrycat.config.json`:
149
+ ```json
150
+ {
151
+ "version": 1,
152
+ "daemon": {
153
+ "poll_interval_ms": 1000,
154
+ "lease_ttl_sec": 30,
155
+ "heartbeat_interval_ms": 10000,
156
+ "notify": true
157
+ },
158
+ "agents": {
159
+ "workbuddy": {
160
+ "handlers": {
161
+ "code_review": {
162
+ "exec_file": "./scripts/review-handler.js",
163
+ "pass_env": ["CUSTOM_ANALYZER_PATH"]
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ ```
130
170
 
131
171
  ---
132
172
 
133
173
  ## Quickstart
134
174
 
135
- ### 1. Build & Verify
175
+ ### 0. See what it actually does first (`ferrycat demo`)
176
+
177
+ Before configuring any MCP server, watch the whole loop in ~3 seconds:
178
+
136
179
  ```bash
137
- git clone https://github.com/GuoBug/FerryCat.git
138
- cd FerryCat
139
- npm install
140
- npm run build
141
- npm test
180
+ npx ferrycat demo
181
+ ```
182
+ *(or `npx -p ferrycat ferrycat-cli demo`)*
183
+
184
+ It spins up a fully isolated sandbox under the OS temp dir (dedicated SQLite database,
185
+ sample source file, sample handler), runs `dispatch → claim → supervised execution →
186
+ TOCTOU re-verification → COMPLETED`, then deletes the sandbox.
187
+ **Your real workspace and `~/.ferrycat/mesh.db` are never read or written.**
188
+
189
+ ```text
190
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
191
+ Sandbox: /tmp/ferrycat-demo-c5iK6V
192
+
193
+ ✔ [1/4] Contract Dispatched
194
+ Locked src/calc.ts (sha256: ce3ba9a5...bc5d)
195
+ ✔ [2/4] Contract Claimed
196
+ Lease 7424261d-9a3f-4a86-a7ff-de278c273e96
197
+ ✔ [3/4] Execution & Schema Check
198
+ Heartbeat 1 lease renewal(s)
199
+ ✔ [4/4] Contract Completed
200
+ TOCTOU fingerprints matched (0 dirty files)
201
+
202
+ 🎉 End-to-end multi-agent handoff verified successfully!
142
203
  ```
143
204
 
144
- ### 2. Mount in Antigravity
205
+ | Option | Effect |
206
+ | :--- | :--- |
207
+ | `--json` | Emit a structured result for CI / upstream assertions |
208
+ | `--keep` | Keep the sandbox and print its path for manual `sqlite3` inspection |
209
+ | `--no-color` | Disable ANSI colors (auto-off when not a TTY or `NO_COLOR` is set) |
210
+
211
+ ### 1. Recommended: Zero-Install MCP Mounting (via npx)
212
+
213
+ No local clone or manual compilation required. Mount directly into your IDE's MCP configuration using `npx -y ferrycat`:
214
+
215
+ #### Antigravity Configuration
145
216
  Edit `%USERPROFILE%\.gemini\antigravity\mcp_config.json` (or `~/.gemini/antigravity/mcp_config.json` on macOS/Linux):
146
217
  ```json
147
218
  {
148
219
  "mcpServers": {
149
220
  "ferrycat": {
150
- "command": "node",
151
- "args": [
152
- "--experimental-sqlite",
153
- "F:/git/FerryCat/dist/index.js"
154
- ],
221
+ "command": "npx",
222
+ "args": ["-y", "ferrycat"],
155
223
  "env": {
156
224
  "AGENT_NAME": "antigravity"
157
225
  }
@@ -160,17 +228,14 @@ Edit `%USERPROFILE%\.gemini\antigravity\mcp_config.json` (or `~/.gemini/antigrav
160
228
  }
161
229
  ```
162
230
 
163
- ### 3. Mount in WorkBuddy / Claude Code / Cursor
231
+ #### WorkBuddy / Claude Code / Cursor / Codex Configuration
164
232
  Configure the target host's MCP settings with its respective `AGENT_NAME`:
165
233
  ```json
166
234
  {
167
235
  "mcpServers": {
168
236
  "ferrycat": {
169
- "command": "node",
170
- "args": [
171
- "--experimental-sqlite",
172
- "F:/git/FerryCat/dist/index.js"
173
- ],
237
+ "command": "npx",
238
+ "args": ["-y", "ferrycat"],
174
239
  "env": {
175
240
  "AGENT_NAME": "workbuddy"
176
241
  }
@@ -178,7 +243,53 @@ Configure the target host's MCP settings with its respective `AGENT_NAME`:
178
243
  }
179
244
  }
180
245
  ```
181
- > **Note**: Both MCP Stdio and direct CLI invocation (`ferrycat-cli <dispatch|poll|verify|fulfill|release|extend|fail|inspect|worker>`) share the same SQLite WAL database at `~/.ferrycat/mesh.db` and the same Zod validation schemas. CLI supports `--help` tree, stdin payloads (`--file -` or `-`), `verify` pre-flight check, `inspect` ASCII table formatting (`--target <agent>`), `worker --mode=watch|claim|exec` and direct script execution via `--exec-file <script>`. In `worker --exec` mode, a non-zero exit of the child command closes the contract as `FAILED` instead of leaving it `CLAIMED` until the TTL sweep.
246
+
247
+ ### 2. Global Installation & Source Build
248
+
249
+ - **Global CLI Installation**:
250
+ ```bash
251
+ npm install -g ferrycat
252
+ ```
253
+ Then simply set `"command": "ferrycat"` in your MCP config.
254
+ - **Local Source Build (For Contributors)**:
255
+ ```bash
256
+ git clone https://github.com/GuoBug/FerryCat.git
257
+ cd FerryCat
258
+ npm install
259
+ npm run build
260
+ npm test
261
+ ```
262
+ Mount using your local path:
263
+ `"command": "node"`, `"args": ["--experimental-sqlite", "/path/to/FerryCat/dist/index.js"]`.
264
+
265
+ ---
266
+
267
+ ## First-Class CLI Experience (`ferrycat-cli`)
268
+
269
+ Beyond serving as an in-IDE MCP Server, FerryCat provides a first-class CLI utility (`ferrycat-cli`). The single `ferrycat` executable dispatches on its first argument: no argv starts the MCP stdio server, a known subcommand routes to the CLI. So you can run `npx ferrycat <command>` with zero install (or `ferrycat-cli <command>` once installed globally). Sharing the same `~/.ferrycat/mesh.db` SQLite WAL database and Zod validation contracts, the CLI allows developers to inspect mesh health, verify working tree safety, and hook into automated CI/Git scripts without leaving their terminal:
270
+
271
+ ### 1. Terminal Visual Inspection (ASCII Status Table)
272
+ Inspect all cross-host handoffs and error reasons formatted as an ASCII table:
273
+ ```bash
274
+ # View all contracts in an ASCII table
275
+ npx ferrycat inspect
276
+
277
+ # Filter by target agent (e.g., only tasks for antigravity)
278
+ npx ferrycat inspect --target antigravity
279
+ ```
280
+
281
+ ### 2. Pre-Flight Verification (Auditing Before Mutation)
282
+ Audit on-disk pointer file integrity against the contract's baseline SHA-256 before committing review work (ADR-0004), eliminating false-positive deliveries:
283
+ ```bash
284
+ npx ferrycat verify <CONTRACT_ID>
285
+ ```
286
+
287
+ ### 3. Local CI & Headless Worker Execution
288
+ Poll the queue, claim tasks, and execute local review/test scripts with automatic failure closure:
289
+ ```bash
290
+ # Safely run a script upon task arrival (no shell quotation hazards)
291
+ npx ferrycat worker --agent codex --mode=exec --exec-file ./scripts/review.sh
292
+ ```
182
293
 
183
294
  ---
184
295
 
package/README_zh.md CHANGED
@@ -5,6 +5,8 @@
5
5
  <b>中文</b>
6
6
  </p>
7
7
 
8
+ [![npm version](https://img.shields.io/npm/v/ferrycat.svg?style=flat&color=cb3837&logo=npm)](https://www.npmjs.com/package/ferrycat)
9
+ [![MCP Registry](https://img.shields.io/badge/MCP_Registry-Active-10b981?style=flat)](https://registry.modelcontextprotocol.io/v0/servers?search=ferrycat)
8
10
  [![Node.js Version](https://img.shields.io/badge/Node.js-22.5%2B-339933?style=flat&logo=nodedotjs)](https://nodejs.org/)
9
11
  [![Native Addons](https://img.shields.io/badge/Native_Addons-0_(node%3Asqlite)-success?style=flat)]()
10
12
  [![Protocol](https://img.shields.io/badge/Protocol-MCP_Stdio-orange?style=flat)](https://modelcontextprotocol.io/)
@@ -118,6 +120,7 @@ MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client
118
120
  ### 6. 威胁模型与安全边界声明 (同机同用户受信 IPC)
119
121
  - **环境信任假设**:FerryCat 定位为**面向同机同操作系统用户的跨宿主 AI 开发者协作总线**。所有 IDE 宿主与 Worker 均运行在同一本地用户权限下,共享本地工作区(`workspace_root`)与本地 SQLite 文件(`~/.ferrycat/mesh.db`)。
120
122
  - **防护范畴**:双端路径防逃逸(`assertSafePointerPath`)与敏感文件模式黑名单旨在防范跨宿主误触敏感配置(如 `.env`、SSH 密钥)、软链接越界与无意识的目录逃逸。
123
+ - **守护进程执行面**:在守护进程模式(`ferrycat-cli daemon`)下,处理脚本通过 `execFile` 直接执行。`ferrycat.config.json` 或处理脚本所在目录的写权限等价于宿主代码执行权限(详见 ADR-0005 §2.2),请确保配置文件置于本地受信任路径。
121
124
  - **非防护目标**:FerryCat **不作为**面向不受信外部网络、多租户强隔离或恶意本地进程伪造 `AGENT_NAME` 的零信任安全网关。
122
125
 
123
126
  ---
@@ -126,34 +129,96 @@ MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client
126
129
 
127
130
  1. **两端不共享同一本地文件系统**:FerryCat 依赖按引用传递文件指针(Context Offloading by Reference),要求双方能访问同一份 `workspace_root`。
128
131
  2. **单轮简单问答即可解决的任务**:每次跨宿主交接需要 3 次人工窗口切换(约 15~25 秒操作开销),简单问题直接在单个 IDE 内完成即可。
129
- 3. **需要无人值守全自动流水线的场景**:桌面 IDE 宿主受限于请求-响应模型,无法在空闲时被 MCP 服务端主动推流唤醒;若需无人值守编排,请使用独立的 DAG 状态机工作流引擎(如 [PatchCat](https://github.com/GuoBug/ai-prompt-orchestrator))。
132
+ 3. **跨步骤复杂有向图编排**:FerryCat 的守护进程(`ferrycat-cli daemon`)负责同机多 Agent 之间的单步契约分发与进程生命周期托管;若需跨多步骤的复杂动态 DAG 有向无环图分支编排,请使用专门的工作流引擎(如 [PatchCat](https://github.com/GuoBug/ai-prompt-orchestrator))。
130
133
 
131
134
  ---
132
135
 
133
- ## 快速上手
136
+ ## 守护进程与声明式处理 (Controlled Daemon, ADR-0005)
137
+
138
+ FerryCat 支持受控后台守护进程,通过 SQLite 微事务 CAS 租约锁实现多进程安全抢占与故障转移,并强制通过 `ferrycat.config.json` 静态绑定脚本处理器:
139
+
140
+ ```bash
141
+ # 单次轮询分发并执行已声明的处理脚本
142
+ ferrycat-cli daemon --config ./ferrycat.config.json --once
143
+
144
+ # 启动后台守护主循环
145
+ ferrycat-cli daemon --config ./ferrycat.config.json
146
+ ```
147
+
148
+ 配置文件形态示例(`ferrycat.config.json`):
149
+ ```json
150
+ {
151
+ "version": 1,
152
+ "daemon": {
153
+ "poll_interval_ms": 1000,
154
+ "lease_ttl_sec": 30,
155
+ "heartbeat_interval_ms": 10000,
156
+ "notify": true
157
+ },
158
+ "agents": {
159
+ "workbuddy": {
160
+ "handlers": {
161
+ "code_review": {
162
+ "exec_file": "./scripts/review-handler.js",
163
+ "pass_env": ["CUSTOM_ANALYZER_PATH"]
164
+ }
165
+ }
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ ---
172
+
173
+ ## 快速上手 (Quickstart)
174
+
175
+ ### 0. 先用一条命令看它到底是什么(`ferrycat demo`)
176
+
177
+ 在配置任何 MCP 之前,先花 3 秒看一遍完整闭环:
134
178
 
135
- ### 1. 安装与编译测试
136
179
  ```bash
137
- git clone https://github.com/GuoBug/FerryCat.git
138
- cd FerryCat
139
- npm install
140
- npm run build
141
- npm test
180
+ npx ferrycat demo
142
181
  ```
182
+ *(亦可使用完整形式 `npx -p ferrycat ferrycat-cli demo`)*
183
+
184
+ 它会在系统临时目录里建一个完全隔离的沙箱(独立 SQLite + 示例源码 + 示例 handler),
185
+ 跑完 `派单 → 认领 → 受控执行 → TOCTOU 复核 → COMPLETED` 全流程,然后自动删除沙箱。
186
+ **不会读写你的真实工作区,也不会碰 `~/.ferrycat/mesh.db`。**
187
+
188
+ ```text
189
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
190
+ Sandbox: C:\Users\...\Temp\ferrycat-demo-c5iK6V
191
+
192
+ ✔ [1/4] Contract Dispatched
193
+ Locked src/calc.ts (sha256: ce3ba9a5...bc5d)
194
+ ✔ [2/4] Contract Claimed
195
+ Lease 7424261d-9a3f-4a86-a7ff-de278c273e96
196
+ ✔ [3/4] Execution & Schema Check
197
+ Heartbeat 1 lease renewal(s)
198
+ ✔ [4/4] Contract Completed
199
+ TOCTOU fingerprints matched (0 dirty files)
200
+
201
+ 🎉 End-to-end multi-agent handoff verified successfully!
202
+ ```
203
+
204
+ | 选项 | 作用 |
205
+ | :--- | :--- |
206
+ | `--json` | 输出结构化结果,便于 CI 或上游脚本断言 |
207
+ | `--keep` | 保留沙箱目录并打印路径,方便用 `sqlite3` 手动 inspect 生成的表 |
208
+ | `--no-color` | 关闭 ANSI 颜色(非 TTY 或设置 `NO_COLOR` 时自动关闭) |
209
+
210
+ ### 1. 推荐:零配置免安装挂载 (npx)
143
211
 
144
- > **关于 `--experimental-sqlite`**:启动参数中恒定携带 `--experimental-sqlite`,以同时兼容 Node 22.12 LTS(需 flag)与 Node 22.22+ / Node 24+(原生免 flag,携带亦不报错),实现零原生 C++ 编译依赖。
212
+ 无需手动克隆仓库或本地编译,直接在各 IDE 宿主的 MCP 配置文件中声明(基于全局或 `npx -y ferrycat`):
145
213
 
146
- ### 2. Antigravity 侧挂载
214
+ #### Antigravity 宿主配置
147
215
  编辑 `%USERPROFILE%\.gemini\antigravity\mcp_config.json`(macOS/Linux 为 `~/.gemini/antigravity/mcp_config.json`):
148
216
  ```json
149
217
  {
150
218
  "mcpServers": {
151
219
  "ferrycat": {
152
- "command": "node",
153
- "args": [
154
- "--experimental-sqlite",
155
- "F:/git/FerryCat/dist/index.js"
156
- ],
220
+ "command": "npx",
221
+ "args": ["-y", "ferrycat"],
157
222
  "env": {
158
223
  "AGENT_NAME": "antigravity"
159
224
  }
@@ -162,17 +227,14 @@ npm test
162
227
  }
163
228
  ```
164
229
 
165
- ### 3. WorkBuddy / Claude Code / Cursor 侧挂载
166
- 在目标宿主的 MCP 配置文件中添加对应 `AGENT_NAME`:
230
+ #### WorkBuddy / Claude Code / Cursor / Codex 宿主配置
231
+ 在目标宿主的 MCP 配置文件中指定对应 `AGENT_NAME` 即可:
167
232
  ```json
168
233
  {
169
234
  "mcpServers": {
170
235
  "ferrycat": {
171
- "command": "node",
172
- "args": [
173
- "--experimental-sqlite",
174
- "F:/git/FerryCat/dist/index.js"
175
- ],
236
+ "command": "npx",
237
+ "args": ["-y", "ferrycat"],
176
238
  "env": {
177
239
  "AGENT_NAME": "workbuddy"
178
240
  }
@@ -180,7 +242,53 @@ npm test
180
242
  }
181
243
  }
182
244
  ```
183
- > **注**:MCP `stdio` 模式与 CLI 直接调用模式(`ferrycat-cli <dispatch|poll|verify|fulfill|release|extend|fail|inspect|worker>`)共享同一份 `~/.ferrycat/mesh.db` 数据库与同一套 Zod 参数校验契约。CLI 提供全量 `--help` 树、stdin 管道输入(`--file -` 或 `-`)、`verify` 只读预检、`inspect` ASCII 表格输出(支持 `--target <agent>` 过滤)、`worker --mode=watch|claim|exec` 以及 `--exec-file <script>` 无转义直接执行脚本。在 `worker --exec` 模式下子进程非零退出时,工单会被直接置为 `FAILED`,不再挂在 `CLAIMED` 等超时。
245
+
246
+ ### 2. 全局安装或本地源码模式
247
+
248
+ - **全局 CLI 安装**:
249
+ ```bash
250
+ npm install -g ferrycat
251
+ ```
252
+ 在 MCP 配置文件中直接指定 `"command": "ferrycat"` 即可。
253
+ - **本地源码编译(适合贡献者二次开发)**:
254
+ ```bash
255
+ git clone https://github.com/GuoBug/FerryCat.git
256
+ cd FerryCat
257
+ npm install
258
+ npm run build
259
+ npm test
260
+ ```
261
+ 本地调试时可将配置中的 `command` 与 `args` 设为:
262
+ `"command": "node"`, `"args": ["--experimental-sqlite", "/path/to/FerryCat/dist/index.js"]`。
263
+
264
+ ---
265
+
266
+ ## 一级入口:CLI 极速总线与自动化调度 (`ferrycat-cli`)
267
+
268
+ 除了作为 MCP Server 嵌入在 IDE 内部供大模型自主调用外,FerryCat 原生提供一级命令行工具 **`ferrycat-cli`**。同一个 `ferrycat` 可执行文件会根据首个参数自动分流:无参数时启动 MCP Server,带子命令时走 CLI。因此免安装即可直接运行 `npx ferrycat <command>`(全局安装后也可用 `ferrycat-cli <command>`)。它与 MCP 共享同一份 `~/.ferrycat/mesh.db` 数据库与 Zod 校验契约,无需切换 IDE 窗口即可在终端直观排查链路、接入 Git Hook 或自动化 CI:
269
+
270
+ ### 1. 终端可视化监控(ASCII 状态总线)
271
+ 实时打印工单流转状态、执行租约与报错信息,无需打开数据库查看:
272
+ ```bash
273
+ # 查看全局工单 ASCII 终端表格
274
+ npx ferrycat inspect
275
+
276
+ # 按接收方过滤(例如仅查看 target 为 antigravity 的工单)
277
+ npx ferrycat inspect --target antigravity
278
+ ```
279
+
280
+ ### 2. 交付前只读预检(Pre-Flight Verify)
281
+ 在正式交付前,无需变更契约状态即可安全核验磁盘文件指针一致性,杜绝因未落盘修改导致的假阳性交付:
282
+ ```bash
283
+ npx ferrycat verify <CONTRACT_ID>
284
+ ```
285
+
286
+ ### 3. 本地 CI 与自动化 Worker 执行
287
+ 监听契约队列并直接拉起本地脚本执行(支持安全脚本执行与非零退出自动熔断为 `FAILED`):
288
+ ```bash
289
+ # 启动常驻 Worker 监听并自动执行指定脚本(无 Shell 注入风险)
290
+ npx ferrycat worker --agent codex --mode=exec --exec-file ./scripts/review.sh
291
+ ```
184
292
 
185
293
  ---
186
294
 
package/bin/ferrycat.js CHANGED
@@ -10,7 +10,25 @@ if (major < 22 || (major === 22 && minor < 5)) {
10
10
  process.exit(1);
11
11
  }
12
12
 
13
- const targetPath = fileURLToPath(new URL('../dist/index.js', import.meta.url));
13
+ const CLI_SUBCOMMANDS = new Set([
14
+ 'demo',
15
+ 'dispatch',
16
+ 'poll',
17
+ 'verify',
18
+ 'fulfill',
19
+ 'release',
20
+ 'extend',
21
+ 'fail',
22
+ 'inspect',
23
+ 'worker',
24
+ 'daemon',
25
+ ]);
26
+
27
+ const firstArg = process.argv[2];
28
+ const isCli = Boolean(firstArg && CLI_SUBCOMMANDS.has(firstArg));
29
+ const targetPath = fileURLToPath(
30
+ new URL(isCli ? '../dist/cli.js' : '../dist/index.js', import.meta.url)
31
+ );
14
32
  const needsFlag = major === 22 && !process.execArgv.includes('--experimental-sqlite');
15
33
 
16
34
  if (needsFlag) {