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 +97 -14
- package/README_zh.md +93 -14
- package/bin/ferrycat.js +20 -1
- package/dist/cli.js +196 -14
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +137 -1
- package/dist/daemon.js +673 -10
- package/dist/daemon.js.map +1 -1
- package/dist/delivery.d.ts +48 -0
- package/dist/delivery.js +158 -0
- package/dist/delivery.js.map +1 -0
- package/dist/demo.d.ts +36 -0
- package/dist/demo.js +343 -0
- package/dist/demo.js.map +1 -0
- package/dist/engine.d.ts +15 -1
- package/dist/engine.js +287 -29
- package/dist/engine.js.map +1 -1
- package/dist/fingerprint.d.ts +60 -4
- package/dist/fingerprint.js +438 -9
- package/dist/fingerprint.js.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +62 -0
- package/dist/init.js +356 -0
- package/dist/init.js.map +1 -0
- package/dist/schemas.d.ts +64 -0
- package/dist/schemas.js +30 -0
- package/dist/schemas.js.map +1 -1
- package/dist/supervisor.d.ts +10 -0
- package/dist/supervisor.js +34 -26
- package/dist/supervisor.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/package.json +16 -4
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
[](https://glama.ai/mcp/servers/GuoBug/FerryCat)
|
|
14
14
|
[](LICENSE)
|
|
15
15
|
|
|
16
|
-
> **FerryCat** (`ferrycat`) is a lightweight, deterministic cross-host AI agent handoff
|
|
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.
|
|
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`
|
|
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
|
|
302
|
+
npx ferrycat inspect
|
|
240
303
|
|
|
241
304
|
# Filter by target agent (e.g., only tasks for antigravity)
|
|
242
|
-
npx ferrycat
|
|
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
|
|
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
|
|
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
|
[](https://glama.ai/mcp/servers/GuoBug/FerryCat)
|
|
14
14
|
[](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
|
|
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
|
-
|
|
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
|
|
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
|
|
298
|
+
npx ferrycat inspect
|
|
240
299
|
|
|
241
300
|
# 按接收方过滤(例如仅查看 target 为 antigravity 的工单)
|
|
242
|
-
npx ferrycat
|
|
301
|
+
npx ferrycat inspect --target antigravity
|
|
243
302
|
```
|
|
244
303
|
|
|
245
304
|
### 2. 交付前只读预检(Pre-Flight Verify)
|
|
246
305
|
在正式交付前,无需变更契约状态即可安全核验磁盘文件指针一致性,杜绝因未落盘修改导致的假阳性交付:
|
|
247
306
|
```bash
|
|
248
|
-
npx ferrycat
|
|
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
|
|
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
|
|
265
|
-
| **`poll_next_task`** | 接收方 (Worker) | 先读后写清理超时工单 $\to$ `changes === 1` 原子抢占为 `CLAIMED` $\to$
|
|
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) |
|
|
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
|
|
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) {
|