ferrycat 0.3.3 → 0.5.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
@@ -13,8 +13,8 @@
13
13
  [![Glama](https://img.shields.io/badge/Glama-MCP_Server-18181b?style=flat)](https://glama.ai/mcp/servers/GuoBug/FerryCat)
14
14
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
15
15
 
16
- > **FerryCat** (`ferrycat`) is a lightweight, deterministic cross-host AI agent handoff and code review bus built on the Model Context Protocol (MCP) and Node.js built-in `node:sqlite` (WAL mode).
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
+ > **FerryCat** (`ferrycat`) is a lightweight, deterministic cross-host AI agent handoff, code review, and verification harness built on the Model Context Protocol (MCP) and Node.js built-in `node:sqlite` (WAL mode).
17
+ > Purpose-built to safely bridge isolated desktop IDE agent hosts (such as Google Antigravity, WorkBuddy, Claude Code, and Cursor) across separate OS processes—enabling Actor-Critic evaluation loops, static analysis gates, and SWE-bench-style patch verification without context drift or blind reviews on stale files.
18
18
 
19
19
  <p align="center">
20
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" />
@@ -24,6 +24,26 @@
24
24
 
25
25
  ---
26
26
 
27
+ ## Quick Glance (See It in 60s)
28
+
29
+ No IDE setup or config file edits required. Watch the entire deterministic loop execute inside an isolated sandbox in ~2 seconds:
30
+
31
+ ```bash
32
+ npx ferrycat demo
33
+ ```
34
+
35
+ ```text
36
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
37
+ ✔ [1/4] Contract Dispatched Locked: src/calc.ts (sha256: ce3ba9a5...bc5d)
38
+ ✔ [2/4] Contract Claimed Lease: 7424261d-9a3f-4a86-a7ff-de278c273e96
39
+ ✔ [3/4] Execution & Check Heartbeat 1 renewal | CHANGES_REQUESTED (loose equality caught)
40
+ ✔ [4/4] Contract Completed TOCTOU: 0 dirty files | Status: COMPLETED (elapsed: 2.1s)
41
+ 🎉 End-to-end multi-agent handoff verified successfully!
42
+ ```
43
+ > 💡 Real benchmark: spins up an isolated child-process sandbox, triggers 1 real lease renewal, and runs a static analysis & verification gate that catches loose equality at `src/calc.ts:6`. Options (`--keep` / `--json` / `--no-color`) detailed in [Quickstart §0](#0-see-what-it-actually-does-first-ferrycat-demo).
44
+
45
+ ---
46
+
27
47
  ## Core Pain Points & Engineering Solutions
28
48
 
29
49
  While the official MCP `Tasks` specification (2025-11 / 2026-07) addresses long-running operations within a **single `Client ↔ Server` connection**, it does not solve cross-host collaboration on a developer workstation:
@@ -87,6 +107,8 @@ Every state transition is bound to an explicit SQL transaction with optimistic c
87
107
  └───────────┘ └───────────────────┘ └───────────────┘
88
108
  ```
89
109
 
110
+ > *Note on `POINTER_STALE` vs. `SELF_CONTAINED` Patch Mode (FC-202)*: `POINTER_STALE` is terminal whenever on-disk pointer files mismatch the dispatched SHA-256 baseline, **except** when a read-only contract (`code_review` / `architecture_audit`) attaches a verified unified `git_patch` (`--patch-file`) that satisfies all three gates: every declared file block carries at least one `@@` hunk with real `+`/`-` content (`EMPTY_PATCH_HUNKS` / `EMPTY_PATCH_CONTENT` otherwise), and the touched paths cover every pointer file (`PATCH_DOES_NOT_COVER_POINTERS` otherwise). In that `SELF_CONTAINED` mode, `poll_next_task` returns `patch_mode: "SELF_CONTAINED"` with an explicit `workspace_warning` instructing the reviewer to inspect `git_patch` rather than stale on-disk files.
111
+
90
112
  Holder-side lifecycle controls on a `CLAIMED` contract (all require `agent_id === target_agent`):
91
113
 
92
114
  | Call | Transition | Guard rails |
@@ -97,7 +119,7 @@ Holder-side lifecycle controls on a `CLAIMED` contract (all require `agent_id ==
97
119
 
98
120
  ### 2. Full-File SHA-256 Fingerprinting, Pre-Flight Verify & TOCTOU Soft-Failure Buffering (ADR-0004)
99
121
  - **Dispatch Snapshot**: `dispatch_contract` reads target files on disk, recording byte `size`, full-file `sha256` (64 hex chars), `first_line`, and `last_line`. If a file was modified within the last 3 seconds, a `warning` is emitted to alert the requester of potential unsaved IDE buffers.
100
- - **Claim Verification**: `poll_next_task` verifies `Existence -> Byte Size -> Full-File SHA-256` (never rejecting on `mtime_ms` alone to tolerate no-op IDE saves). On mismatch, it waits `150ms` and retries once to rule out transient IDE flushes before marking the contract `POINTER_STALE`.
122
+ - **Claim Verification**: `poll_next_task` verifies `Existence -> Byte Size -> Full-File SHA-256` (never rejecting on `mtime_ms` alone to tolerate no-op IDE saves). On mismatch, it waits `150ms` asynchronously (non-blocking, FC-203) and retries once to rule out transient IDE flushes before marking the contract `POINTER_STALE` — unless the contract is a read-only review/audit carrying a verified unified `git_patch` covering all pointer files (`SELF_CONTAINED` patch mode, FC-202), in which case it claims with an explicit `workspace_warning` and records `__verified_on_disk__: "NO"` and `__unverified_pointers__` in `verified_sha256`.
101
123
  - **Pre-Flight Verify (`verify_contract`)**: A strictly read-only check allowing workers or scripts to audit pointer health (`valid: true` vs `valid: false` with dirty files list) before submitting.
102
124
  - **TOCTOU Soft-Failure Buffering**: `fulfill_contract` checks on-disk pointer fingerprints. If dirty pointers are detected:
103
125
  - **Strike 1** returns `RETRY_NEEDED`, leaves the contract `CLAIMED`, renews the execution window, and lists dirty files with recovery instructions (`git stash` / `git checkout -- <file>`).
@@ -135,7 +157,7 @@ Holder-side lifecycle controls on a `CLAIMED` contract (all require `agent_id ==
135
157
 
136
158
  ## Controlled Daemon & Declarative Handlers (ADR-0005)
137
159
 
138
- FerryCat provides a controlled daemon mode governed by SQLite microsecond CAS leases on `daemon_locks` and declarative scripts defined in `ferrycat.config.json`:
160
+ FerryCat provides a controlled daemon mode governed by SQLite microsecond CAS leases on `daemon_locks` and declarative scripts defined in `ferrycat.config.json` (ideal for binding static analysis gates like `tsc` / `eslint` / AST checks or automated test suites like `Jest` / `Vitest` / `Pytest` as deterministic verification workers):
139
161
 
140
162
  ```bash
141
163
  # Run a single dispatch cycle with declared handlers
@@ -143,8 +165,13 @@ ferrycat-cli daemon --config ./ferrycat.config.json --once
143
165
 
144
166
  # Start continuous daemon loop
145
167
  ferrycat-cli daemon --config ./ferrycat.config.json
168
+
169
+ # Inspect lease ownership + write-ahead journal health (read-only)
170
+ ferrycat-cli daemon --status
146
171
  ```
147
172
 
173
+ `daemon --status` reports `journal_degraded` / `last_journal_error` / `journal_path` / `journal_entries` alongside lease ownership, so a silently unwritable write-ahead journal (which would disarm crash recovery) is visible instead of failing mute.
174
+
148
175
  Example `ferrycat.config.json`:
149
176
  ```json
150
177
  {
@@ -172,9 +199,45 @@ Example `ferrycat.config.json`:
172
199
 
173
200
  ## Quickstart
174
201
 
202
+ ### 0. See what it actually does first (`ferrycat demo`)
203
+
204
+ Before configuring any MCP server, watch the whole loop in ~3 seconds:
205
+
206
+ ```bash
207
+ npx ferrycat demo
208
+ ```
209
+ *(or `npx -p ferrycat ferrycat-cli demo`)*
210
+
211
+ It spins up a fully isolated sandbox under the OS temp dir (dedicated SQLite database,
212
+ sample source file, sample handler), runs `dispatch → claim → supervised execution →
213
+ TOCTOU re-verification → COMPLETED`, then deletes the sandbox.
214
+ **Your real workspace and `~/.ferrycat/mesh.db` are never read or written.**
215
+
216
+ ```text
217
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
218
+ Sandbox: /tmp/ferrycat-demo-c5iK6V
219
+
220
+ ✔ [1/4] Contract Dispatched
221
+ Locked src/calc.ts (sha256: ce3ba9a5...bc5d)
222
+ ✔ [2/4] Contract Claimed
223
+ Lease 7424261d-9a3f-4a86-a7ff-de278c273e96
224
+ ✔ [3/4] Execution & Schema Check
225
+ Heartbeat 1 lease renewal(s)
226
+ ✔ [4/4] Contract Completed
227
+ TOCTOU fingerprints matched (0 dirty files)
228
+
229
+ 🎉 End-to-end multi-agent handoff verified successfully!
230
+ ```
231
+
232
+ | Option | Effect |
233
+ | :--- | :--- |
234
+ | `--json` | Emit a structured result for CI / upstream assertions |
235
+ | `--keep` | Keep the sandbox and print its path for manual `sqlite3` inspection |
236
+ | `--no-color` | Disable ANSI colors (auto-off when not a TTY or `NO_COLOR` is set) |
237
+
175
238
  ### 1. Recommended: Zero-Install MCP Mounting (via npx)
176
239
 
177
- No local clone or manual compilation required. Mount directly into your IDE's MCP configuration using `npx -y ferrycat`:
240
+ No local clone or manual compilation required. Run `npx ferrycat init --yes` to auto-detect installed hosts (Antigravity, WorkBuddy, Cursor, VS Code, Windsurf, Claude Desktop, Claude Code) and safely merge the `ferrycat` server entry (with backup and JSONC protection), or mount manually into your IDE's MCP configuration using `npx -y ferrycat`:
178
241
 
179
242
  #### Antigravity Configuration
180
243
  Edit `%USERPROFILE%\.gemini\antigravity\mcp_config.json` (or `~/.gemini/antigravity/mcp_config.json` on macOS/Linux):
@@ -230,29 +293,47 @@ Configure the target host's MCP settings with its respective `AGENT_NAME`:
230
293
 
231
294
  ## First-Class CLI Experience (`ferrycat-cli`)
232
295
 
233
- Beyond serving as an in-IDE MCP Server, FerryCat provides a first-class CLI utility (`ferrycat-cli` or `npx ferrycat-cli`). 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:
296
+ 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:
234
297
 
235
298
  ### 1. Terminal Visual Inspection (ASCII Status Table)
236
299
  Inspect all cross-host handoffs and error reasons formatted as an ASCII table:
237
300
  ```bash
238
301
  # View all contracts in an ASCII table
239
- npx ferrycat-cli inspect
302
+ npx ferrycat inspect
240
303
 
241
304
  # Filter by target agent (e.g., only tasks for antigravity)
242
- npx ferrycat-cli inspect --target antigravity
305
+ npx ferrycat inspect --target antigravity
243
306
  ```
244
307
 
245
308
  ### 2. Pre-Flight Verification (Auditing Before Mutation)
246
309
  Audit on-disk pointer file integrity against the contract's baseline SHA-256 before committing review work (ADR-0004), eliminating false-positive deliveries:
247
310
  ```bash
248
- npx ferrycat-cli verify <CONTRACT_ID>
311
+ npx ferrycat verify <CONTRACT_ID>
249
312
  ```
250
313
 
251
314
  ### 3. Local CI & Headless Worker Execution
252
315
  Poll the queue, claim tasks, and execute local review/test scripts with automatic failure closure:
253
316
  ```bash
254
317
  # Safely run a script upon task arrival (no shell quotation hazards)
255
- npx ferrycat-cli worker --agent codex --mode=exec --exec-file ./scripts/review.sh
318
+ npx ferrycat worker --agent codex --mode=exec --exec-file ./scripts/review.sh --delivery envelope
319
+ # See docs/examples/ for dispatch.example.json, fulfill.example.json, and handler.example.cjs templates.
320
+ ```
321
+
322
+ ### 4. Zero-Config Sandbox Walkthrough (demo)
323
+ Run the self-contained multi-agent lifecycle simulation without configuring an MCP server:
324
+ ```bash
325
+ npx ferrycat demo
326
+ ```
327
+ Options (`--keep` to retain SQLite for manual inspection, `--json` for CI assertions) detailed in [Quickstart §0](#0-see-what-it-actually-does-first-ferrycat-demo).
328
+
329
+ ### 5. Production Controlled Daemon (daemon, ADR-0005)
330
+ Run the headless orchestration daemon coordinating background workers via atomic CAS leases and declarative script bindings:
331
+ ```bash
332
+ # Launch daemon using project-local declarative configuration
333
+ npx ferrycat daemon --config ./ferrycat.config.json
334
+
335
+ # Run single poll/dispatch iteration for a targeted agent and exit
336
+ npx ferrycat daemon --agent workbuddy --once
256
337
  ```
257
338
 
258
339
  ---
@@ -261,20 +342,22 @@ npx ferrycat-cli worker --agent codex --mode=exec --exec-file ./scripts/review.s
261
342
 
262
343
  | Tool Name | Role | Transactional Behavior |
263
344
  | :--- | :--- | :--- |
264
- | **`dispatch_contract`** | Requester | Enforces path blacklist $\to$ computes full-file SHA-256 & line bounds $\to$ inserts `SUBMITTED`. |
265
- | **`poll_next_task`** | Worker | Sweeps expired TTLs (read-before-write) $\to$ claims via `changes === 1` (`CLAIMED`) $\to$ verifies disk SHA-256 (or marks `POINTER_STALE`). |
345
+ | **`dispatch_contract`** | Requester | Enforces path blacklist $\to$ computes full-file SHA-256 & line bounds (plus optional unified `git_patch` / `--patch-file` validation covering pointers, FC-202) $\to$ inserts `SUBMITTED`. |
346
+ | **`poll_next_task`** | Worker | Sweeps expired TTLs (read-before-write) $\to$ claims via `changes === 1` (`CLAIMED`) $\to$ verifies disk SHA-256 with async 150ms retry (FC-203) or falls back to `SELF_CONTAINED` patch mode with `workspace_warning` (otherwise marks `POINTER_STALE`). |
266
347
  | **`fulfill_contract`** | Worker | Re-verifies SHA-256 (TOCTOU guard) $\to$ validates Ajv JSON Schema ($\le 2$ retries via `RETRY_NEEDED`, 3rd marks `VALIDATION_FAILED`) $\to$ marks `COMPLETED`. |
267
348
  | **`release_contract`** | Worker (holder) | Hands a `CLAIMED` contract back to the queue tail as `SUBMITTED`. `retry_count` is preserved (contract-level circuit breaker); `extend_count` is reset. Max 3 releases; refused once past the absolute lifetime deadline. |
268
349
  | **`extend_ttl`** | Worker (holder) | Heartbeat: restarts the execution window (`claimed_at = now`), max 5 renewals and bounded total lifetime. |
269
350
  | **`fail_contract`** | Worker (holder) | Marks a `CLAIMED` contract terminal `FAILED` with a mandatory `reason`. |
270
351
  | **`verify_contract`** | Worker / Any (Read-Only) | Pre-flight check: validates on-disk pointer files against the baseline SHA-256 without mutating contract state (ADR-0004). |
271
- | **`inspect_mesh_state`** | Any (Read-Only) | Pure read-only query of contract states, outputs, and dynamic `is_logically_expired` flags. |
352
+ | **`inspect_mesh_state`** | Any (Read-Only) | Pure read-only query of contract states, outputs, `patch_sha256` / `patch_bytes` (opt-in `include_patch: true`), and dynamic `is_logically_expired` flags. |
272
353
 
273
354
  > 💡 **Architecture Decision Records & Engineering Verification**:
274
355
  > - [ADR-0001: Cross-Host SQLite WAL Bus & Human-Scheduled Poll Model](docs/adr/0001-cross-host-sqlite-wal-and-poll-model.md) (Why `node:sqlite` WAL + `poll_next_task` instead of 60s Blocking Hold or single-connection MCP Tasks)
275
356
  > - [ADR-0002: Full-File SHA-256 Fingerprinting, TOCTOU Guard & Cross-Model Audit](docs/adr/0002-fingerprint-toctou-and-cross-model-audit.md) (Stale-context prevention and real-world cross-host verification records)
276
357
  > - [ADR-0003: GUI Sandbox vs CLI Process Hybrid Layering Architecture & Wake-Up Boundaries](docs/adr/0003-gui-cli-hybrid-architecture.md) (Desktop HITL approval vs in-house CLI dual-channel autonomy)
277
- > - [ADR-0004: Separation of Review and Mutation (SRM), TOCTOU Soft-Failure Buffering & Immutable Baseline Protocol](docs/adr/0004-review-mutation-separation-and-toctou-buffer.md) (How to prevent review abortion from concurrent or well-intended reviewer edits)
358
+ > - [ADR-0004: Separation of Review and Mutation (SRM), TOCTOU Soft-Failure Buffering & Immutable Baseline Protocol](docs/adr/0004-review-mutation-separation-and-toctou-buffer.md) (How to prevent review abortion from concurrent or well-intended reviewer edits; live mesh case: contract `fc_1793098036393_aea8bb9b`)
359
+ > - [ADR-0005: Controlled Daemon, Atomic CAS Micro-Leases & Safe Execution Boundaries](docs/adr/0005-controlled-daemon-and-process-supervision.md) (Microsecond atomic CAS leases on `daemon_locks` and declarative whitelist handler enforcement)
360
+ > - [ADR-0006: Dual-Track TOCTOU Semantics & Post-Mutation SHA-256 Fulfillment](docs/adr/0006-dual-track-mutation-fulfillment.md) (Why `implementation` / `test_generation` tasks commit post-mutation SHA-256 into `verified_sha256` while preserving pre-mutation baselines in `pointers`; live mesh case: `fc_1793100801409_4eedf544`)
278
361
  > - [FerryCat Requirements Backlog & Roadmap](docs/roadmap.md)
279
362
 
280
363
  ---
package/README_zh.md CHANGED
@@ -13,8 +13,8 @@
13
13
  [![Glama](https://img.shields.io/badge/Glama-MCP_Server-18181b?style=flat)](https://glama.ai/mcp/servers/GuoBug/FerryCat)
14
14
  [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
15
15
 
16
- > **FerryCat** (`ferrycat`) 是一个基于 Model Context Protocol (MCP) 与 Node.js 内置 `node:sqlite`(WAL 并发模式)构建的轻量级、确定性跨宿主 AI Agent 工单交接与交叉评审总线。
17
- > 专为解决单机桌面环境下不同 IDE 宿主(如 Google Antigravity、WorkBuddy、Claude Code、Cursor)因进程物理隔离导致的上下文割裂、未落盘代码静默盲审与非结构化交付痛点而设计。
16
+ > **FerryCat** (`ferrycat`) 是一个基于 Model Context Protocol (MCP) 与 Node.js 内置 `node:sqlite`(WAL 并发模式)构建的轻量级、确定性跨宿主 AI Agent 工单交接、交叉评审与评测验证底座(Verification Harness)。
17
+ > 专为解决单机桌面环境下不同 IDE 宿主(如 Google Antigravity、WorkBuddy、Claude Code、Cursor)因进程物理隔离导致的上下文割裂、未落盘代码静默盲审与非结构化交付痛点而设计,支持构建 Actor-Critic 双智能体评测、静态分析守卫(Static Analysis Gate)与 SWE-bench 风格的补丁验证流水线。
18
18
 
19
19
  <p align="center">
20
20
  <img src="https://guobug.github.io/assets/images/flowchart-ferrycat-cross-host-demand-and-workflow.svg" alt="FerryCat 跨宿主契约摆渡全景" width="960" />
@@ -24,6 +24,26 @@
24
24
 
25
25
  ---
26
26
 
27
+ ## 60 秒看懂它 (Quick Glance)
28
+
29
+ 无需安装配置任何 IDE,无需修改配置文件,一条命令在系统临时目录跑通完整沙箱闭环:
30
+
31
+ ```bash
32
+ npx ferrycat demo
33
+ ```
34
+
35
+ ```text
36
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
37
+ ✔ [1/4] Contract Dispatched Locked: src/calc.ts (sha256: ce3ba9a5...bc5d)
38
+ ✔ [2/4] Contract Claimed Lease: 7424261d-9a3f-4a86-a7ff-de278c273e96
39
+ ✔ [3/4] Execution & Check Heartbeat 1 renewal | CHANGES_REQUESTED (loose equality caught)
40
+ ✔ [4/4] Contract Completed TOCTOU: 0 dirty files | Status: COMPLETED (elapsed: 2.1s)
41
+ 🎉 End-to-end multi-agent handoff verified successfully!
42
+ ```
43
+ > 💡 实测数据:2 秒真实拉起独立子进程沙箱、真实心跳续约 1 次、通过静态分析与验证守卫真实检出 `src/calc.ts:6` 的松散相等缺陷。详细参数(`--keep` / `--json` / `--no-color`)与底层机制见 [快速上手 §0](#0-先用一条命令看它到底是什么ferrycat-demo)。
44
+
45
+ ---
46
+
27
47
  ## 核心痛点与工程解法
28
48
 
29
49
  MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client ↔ Server` 连接内部**的长耗时任务状态跟踪,但无法解决桌面端跨宿主协同的四个物理难题:
@@ -87,6 +107,8 @@ MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client
87
107
  └───────────┘ └───────────────────┘ └───────────────┘
88
108
  ```
89
109
 
110
+ > *关于 `POINTER_STALE` 与 `SELF_CONTAINED` 补丁模式的边界说明 (FC-202)*:当磁盘文件与派单基线 SHA-256 不一致时,工单默认流转至终态 `POINTER_STALE`;**唯一例外**是只读审查类任务(`code_review` / `architecture_audit`)附带了同时通过三重闸门的统一差异补丁(`git_patch` / `--patch-file`):每个声明文件块必须含至少一个带真实 `+`/`-` 内容的 `@@` hunk(否则 `EMPTY_PATCH_HUNKS` / `EMPTY_PATCH_CONTENT`),且补丁触及路径必须覆盖全部指针文件(否则 `PATCH_DOES_NOT_COVER_POINTERS`)。在此 `SELF_CONTAINED` 模式下,`poll_next_task` 返回 `patch_mode: "SELF_CONTAINED"` 及显式告警 `workspace_warning`,指示审查方以 `git_patch` 为准,且交单后 `verified_sha256` 显式标记 `__verified_on_disk__: "NO"` 与 `__unverified_pointers__`。
111
+
90
112
  持单方对 `CLAIMED` 工单的生命周期控制(均要求 `agent_id === target_agent`):
91
113
 
92
114
  | 调用 | 状态流转 | 护栏 |
@@ -97,7 +119,7 @@ MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client
97
119
 
98
120
  ### 2. 全文件 SHA-256 指纹校验、预检与 TOCTOU 软失败缓冲 (ADR-0004)
99
121
  - **派单快照**:`dispatch_contract` 读取磁盘文件,记录字节数 `size`、全文件 `sha256`(64 位 hex)以及非空首末行 `first_line` / `last_line`。若文件在最近 3 秒内刚被修改,返回 `warning` 提醒确认 IDE 缓冲区已落盘。
100
- - **领单核验**:`poll_next_task` 严格按 `存在性 -> 字节数 size -> 全文件 sha256` 顺序核验(绝不以 `mtime` 单独判死刑,避免 IDE 无变更保存导致误杀)。若不一致,等待 `150ms` 重试一次排除瞬态写入,仍不一致则直接置为终态 `POINTER_STALE`。
122
+ - **领单核验**:`poll_next_task` 严格按 `存在性 -> 字节数 size -> 全文件 sha256` 顺序核验(绝不以 `mtime` 单独判死刑,避免 IDE 无变更保存导致误杀)。若不一致,异步等待 `150ms` 重试一次(非阻塞,FC-203)排除瞬态写入;若仍不一致,除附带完整覆盖指针的 `git_patch` 只读任务降级为 `SELF_CONTAINED` 模式(附带 `workspace_warning`)外,其余直接置为终态 `POINTER_STALE`。
101
123
  - **只读预检 (`verify_contract`)**:纯只读命令,允许 Worker 或外部脚本在交单前核验指针健康度(返回 `valid: true/false` 与脏文件清单),不消耗工单状态。
102
124
  - **TOCTOU 软失败缓冲**:`fulfill_contract` 在交单时二次核验全文件指纹。若检测到脏指针:
103
125
  - **第 1 次超标(Strike 1)**:返回 `RETRY_NEEDED`,工单保持 `CLAIMED` 并自动续期执行窗口,返回脏文件清单与抢救指引(`git stash` / `git checkout -- <file>`)。
@@ -135,7 +157,7 @@ MCP 官方的 `Tasks` 规范(2025-11 / 2026-07)解决的是**单条 `Client
135
157
 
136
158
  ## 守护进程与声明式处理 (Controlled Daemon, ADR-0005)
137
159
 
138
- FerryCat 支持受控后台守护进程,通过 SQLite 微事务 CAS 租约锁实现多进程安全抢占与故障转移,并强制通过 `ferrycat.config.json` 静态绑定脚本处理器:
160
+ FerryCat 支持受控后台守护进程,通过 SQLite 微事务 CAS 租约锁实现多进程安全抢占与故障转移,并强制通过 `ferrycat.config.json` 静态绑定脚本处理器(非常适合挂载 `tsc` / `eslint` / AST 静态分析守卫,或接入 `Jest` / `Vitest` / `Pytest` 自动化测试套件作为确定性验证 Worker):
139
161
 
140
162
  ```bash
141
163
  # 单次轮询分发并执行已声明的处理脚本
@@ -143,6 +165,8 @@ ferrycat-cli daemon --config ./ferrycat.config.json --once
143
165
 
144
166
  # 启动后台守护主循环
145
167
  ferrycat-cli daemon --config ./ferrycat.config.json
168
+ # 只读查询租约归属与预写日志健康度
169
+ ferrycat-cli daemon --status
146
170
  ```
147
171
 
148
172
  配置文件形态示例(`ferrycat.config.json`):
@@ -172,9 +196,44 @@ ferrycat-cli daemon --config ./ferrycat.config.json
172
196
 
173
197
  ## 快速上手 (Quickstart)
174
198
 
199
+ ### 0. 先用一条命令看它到底是什么(`ferrycat demo`)
200
+
201
+ 在配置任何 MCP 之前,先花 3 秒看一遍完整闭环:
202
+
203
+ ```bash
204
+ npx ferrycat demo
205
+ ```
206
+ *(亦可使用完整形式 `npx -p ferrycat ferrycat-cli demo`)*
207
+
208
+ 它会在系统临时目录里建一个完全隔离的沙箱(独立 SQLite + 示例源码 + 示例 handler),
209
+ 跑完 `派单 → 认领 → 受控执行 → TOCTOU 复核 → COMPLETED` 全流程,然后自动删除沙箱。
210
+ **不会读写你的真实工作区,也不会碰 `~/.ferrycat/mesh.db`。**
211
+
212
+ ```text
213
+ ⚡ FerryCat Zero-Config Sandbox Demo ⚡
214
+ Sandbox: C:\Users\...\Temp\ferrycat-demo-c5iK6V
215
+
216
+ ✔ [1/4] Contract Dispatched
217
+ Locked src/calc.ts (sha256: ce3ba9a5...bc5d)
218
+ ✔ [2/4] Contract Claimed
219
+ Lease 7424261d-9a3f-4a86-a7ff-de278c273e96
220
+ ✔ [3/4] Execution & Schema Check
221
+ Heartbeat 1 lease renewal(s)
222
+ ✔ [4/4] Contract Completed
223
+ TOCTOU fingerprints matched (0 dirty files)
224
+
225
+ 🎉 End-to-end multi-agent handoff verified successfully!
226
+ ```
227
+
228
+ | 选项 | 作用 |
229
+ | :--- | :--- |
230
+ | `--json` | 输出结构化结果,便于 CI 或上游脚本断言 |
231
+ | `--keep` | 保留沙箱目录并打印路径,方便用 `sqlite3` 手动 inspect 生成的表 |
232
+ | `--no-color` | 关闭 ANSI 颜色(非 TTY 或设置 `NO_COLOR` 时自动关闭) |
233
+
175
234
  ### 1. 推荐:零配置免安装挂载 (npx)
176
235
 
177
- 无需手动克隆仓库或本地编译,直接在各 IDE 宿主的 MCP 配置文件中声明(基于全局或 `npx -y ferrycat`):
236
+ 无需手动克隆仓库或本地编译。推荐直接运行 `npx ferrycat init --yes` 自动探测本机已安装的 IDE 宿主(Antigravity、WorkBuddy、Cursor、VS Code、Windsurf、Claude Desktop、Claude Code)并安全合并注入配置(自带原文件备份与 JSONC 注释保护),或在各 IDE 宿主的 MCP 配置文件中手动声明(基于全局或 `npx -y ferrycat`):
178
237
 
179
238
  #### Antigravity 宿主配置
180
239
  编辑 `%USERPROFILE%\.gemini\antigravity\mcp_config.json`(macOS/Linux 为 `~/.gemini/antigravity/mcp_config.json`):
@@ -230,29 +289,47 @@ ferrycat-cli daemon --config ./ferrycat.config.json
230
289
 
231
290
  ## 一级入口:CLI 极速总线与自动化调度 (`ferrycat-cli`)
232
291
 
233
- 除了作为 MCP Server 嵌入在 IDE 内部供大模型自主调用外,FerryCat 原生提供一级命令行工具 **`ferrycat-cli`**(可通过全局安装或直接运行 `npx ferrycat-cli`)。它与 MCP 共享同一份 `~/.ferrycat/mesh.db` 数据库与 Zod 校验契约,无需切换 IDE 窗口即可在终端直观排查链路、接入 Git Hook 或自动化 CI:
292
+ 除了作为 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:
234
293
 
235
294
  ### 1. 终端可视化监控(ASCII 状态总线)
236
295
  实时打印工单流转状态、执行租约与报错信息,无需打开数据库查看:
237
296
  ```bash
238
297
  # 查看全局工单 ASCII 终端表格
239
- npx ferrycat-cli inspect
298
+ npx ferrycat inspect
240
299
 
241
300
  # 按接收方过滤(例如仅查看 target 为 antigravity 的工单)
242
- npx ferrycat-cli inspect --target antigravity
301
+ npx ferrycat inspect --target antigravity
243
302
  ```
244
303
 
245
304
  ### 2. 交付前只读预检(Pre-Flight Verify)
246
305
  在正式交付前,无需变更契约状态即可安全核验磁盘文件指针一致性,杜绝因未落盘修改导致的假阳性交付:
247
306
  ```bash
248
- npx ferrycat-cli verify <CONTRACT_ID>
307
+ npx ferrycat verify <CONTRACT_ID>
249
308
  ```
250
309
 
251
310
  ### 3. 本地 CI 与自动化 Worker 执行
252
311
  监听契约队列并直接拉起本地脚本执行(支持安全脚本执行与非零退出自动熔断为 `FAILED`):
253
312
  ```bash
254
313
  # 启动常驻 Worker 监听并自动执行指定脚本(无 Shell 注入风险)
255
- npx ferrycat-cli worker --agent codex --mode=exec --exec-file ./scripts/review.sh
314
+ npx ferrycat worker --agent codex --mode=exec --exec-file ./scripts/review.sh --delivery envelope
315
+ # 标准载荷与 Handler 范例模板见 docs/examples/(dispatch.example.json / fulfill.example.json / handler.example.cjs)
316
+ ```
317
+
318
+ ### 4. 零配置一键沙箱演练 (demo)
319
+ 在系统临时目录中构建沙箱,验证两端 Agent 派单、认领、心跳保活与交单的完整流转:
320
+ ```bash
321
+ npx ferrycat demo
322
+ ```
323
+ 完整参数(`--keep` 保留 SQLite 供手动 inspect、`--json` 供 CI 断言等)见 [快速上手 §0](#0-先用一条命令看它到底是什么ferrycat-demo)。
324
+
325
+ ### 5. 受控常驻守护进程(daemon,ADR-0005)
326
+ 脱离前台控制台,基于 SQLite WAL 短事务原子 CAS 租约与声明式配置自动拉起白名单脚本,无人值守但严格受控:
327
+ ```bash
328
+ # 依据当前目录 ferrycat.config.json 启动常驻守护中枢
329
+ npx ferrycat daemon --config ./ferrycat.config.json
330
+
331
+ # 指定监听单一 Agent 且仅处理一次工单后退出(适合轻量调度)
332
+ npx ferrycat daemon --agent workbuddy --once
256
333
  ```
257
334
 
258
335
  ---
@@ -261,20 +338,22 @@ npx ferrycat-cli worker --agent codex --mode=exec --exec-file ./scripts/review.s
261
338
 
262
339
  | 工具名 | 调用角色 | 职责与事务行为 |
263
340
  | :--- | :--- | :--- |
264
- | **`dispatch_contract`** | 发起方 (Requester) | 校验路径黑名单 $\to$ 计算全文件 SHA-256 与首末行快照 $\to$ 写入 `SUBMITTED`。 |
265
- | **`poll_next_task`** | 接收方 (Worker) | 先读后写清理超时工单 $\to$ `changes === 1` 原子抢占为 `CLAIMED` $\to$ 校验文件指纹(不匹配则置为 `POINTER_STALE`)。 |
341
+ | **`dispatch_contract`** | 发起方 (Requester) | 校验路径黑名单 $\to$ 计算全文件 SHA-256 与首末行快照(以及可选的 `git_patch` / `--patch-file` 统一补丁及指针覆盖校验,FC-202)$\to$ 写入 `SUBMITTED`。 |
342
+ | **`poll_next_task`** | 接收方 (Worker) | 先读后写清理超时工单 $\to$ `changes === 1` 原子抢占为 `CLAIMED` $\to$ 校验文件指纹(含 150ms 异步重试 FC-203;只读任务附带完整覆盖指针的 `git_patch` 时进入 `SELF_CONTAINED` 模式并返回 `workspace_warning`,否则置为 `POINTER_STALE`)。 |
266
343
  | **`verify_contract`** | 接收方 / 任意方 (Read-Only) | 只读预检:校验磁盘文件指纹与基线是否一致,不变更任何状态(ADR-0004)。 |
267
344
  | **`fulfill_contract`** | 接收方 (Worker) | 二次复核文件指纹(TOCTOU 软失败缓冲:Strike 1 返回 `RETRY_NEEDED`,Strike 2 置为 `POINTER_STALE` 并在 `salvaged_result` 抢救产出)$\to$ 校验 Ajv JSON Schema $\to$ 通过则置为 `COMPLETED`。 |
268
345
  | **`release_contract`** | 持单方 (Worker) | 将 `CLAIMED` 工单退回队尾重新置为 `SUBMITTED`。保留 `retry_count`(工单级熔断配额),清零 `extend_count`。最多退回 3 次;超出绝对生命期上限时拒绝。 |
269
346
  | **`extend_ttl`** | 持单方 (Worker) | 心跳续期:重置执行窗口(`claimed_at = now`),最多 5 次,总生命周期有上限。 |
270
347
  | **`fail_contract`** | 持单方 (Worker) | 携带必填 `reason` 将 `CLAIMED` 工单置为终态 `FAILED`。 |
271
- | **`inspect_mesh_state`** | 任意方 (Read-Only) | 纯只读查询工单状态、结构化产出与错误原因,动态计算 `is_logically_expired`。 |
348
+ | **`inspect_mesh_state`** | 任意方 (Read-Only) | 纯只读查询工单状态、结构化产出、`patch_sha256` / `patch_bytes`(可通过 `include_patch: true` 显式读取补丁正文)与错误原因,动态计算 `is_logically_expired`。 |
272
349
 
273
350
  > 💡 **架构决策记录 (ADR) 与工程验证沉淀**:
274
351
  > - [ADR-0001: 采用跨宿主 SQLite WAL 总线与人工调度即时轮询模型](docs/adr/0001-cross-host-sqlite-wal-and-poll-model_zh.md)(为什么采用 `node:sqlite` WAL + `poll_next_task`,而非 60s 长轮询挂起或单连接 MCP Tasks)
275
352
  > - [ADR-0002: 全文件 SHA-256 指纹防盲审、TOCTOU 闭合与跨宿主多模型实测记录](docs/adr/0002-fingerprint-toctou-and-cross-model-audit_zh.md)(指针陈旧防护设计与 3 模型真实互审复盘记录)
276
353
  > - [ADR-0003: GUI 沙箱与 CLI 进程混合分层架构、唤醒边界与双通道 Worker 选型](docs/adr/0003-gui-cli-hybrid-architecture_zh.md)(桌面人在回路审批闸 vs 自研 CLI 双通道自治)
277
- > - [ADR-0004: 审议分离协议、TOCTOU 软失败缓冲与审查期不可变基线规范](docs/adr/0004-review-mutation-separation-and-toctou-buffer_zh.md)(如何彻底规避审查者“边审边修”或并发写入引发的工单报废)
354
+ > - [ADR-0004: 审议分离协议、TOCTOU 软失败缓冲与审查期不可变基线规范](docs/adr/0004-review-mutation-separation-and-toctou-buffer_zh.md)(如何彻底规避审查者“边审边修”或并发写入引发的工单报废;真实案例见 2026-10-27 真实总线工单 `fc_1793098036393_aea8bb9b` 漂移拦截)
355
+ > - [ADR-0005: 受控守护进程、短事务 CAS 租约与安全执行边界](docs/adr/0005-controlled-daemon-and-process-supervision_zh.md)(微秒级原子 CAS 租约如何防死锁、声明式 handler 如何将任意 Shell 注入面彻底收敛)
356
+ > - [ADR-0006: 读写双轨 TOCTOU 语义与变更型任务双哈希交单存证协议](docs/adr/0006-dual-track-mutation-fulfillment_zh.md)(为什么 `implementation` / `test_generation` 任务在 `pointers` 保留修改前基线并在 `verified_sha256` 落库修改后产物哈希;实战案例:`fc_1793100801409_4eedf544`)
278
357
  > - [FerryCat 演进路线图 (Roadmap)](docs/roadmap_zh.md)
279
358
 
280
359
  ---
package/bin/ferrycat.js CHANGED
@@ -10,7 +10,26 @@ 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
+ 'init',
16
+ 'dispatch',
17
+ 'poll',
18
+ 'verify',
19
+ 'fulfill',
20
+ 'release',
21
+ 'extend',
22
+ 'fail',
23
+ 'inspect',
24
+ 'worker',
25
+ 'daemon',
26
+ ]);
27
+
28
+ const firstArg = process.argv[2];
29
+ const isCli = Boolean(firstArg && CLI_SUBCOMMANDS.has(firstArg));
30
+ const targetPath = fileURLToPath(
31
+ new URL(isCli ? '../dist/cli.js' : '../dist/index.js', import.meta.url)
32
+ );
14
33
  const needsFlag = major === 22 && !process.execArgv.includes('--experimental-sqlite');
15
34
 
16
35
  if (needsFlag) {