Shared Cursor provider schema and headless proto-lab for OpenClaw, GoClaw, and 9router.
Fake tool catalog leaks come from Cursor cloud API responses (api2.cursor.sh), not the local IDE. Proto-lab (raw) talks to Cursor directly with credentials from IDE state.vscdb / .env — that is the ground truth for regression. Each consumer layer (9router, OpenClaw plugin, GoClaw adapter) is compared against the same scenario ids.
cursor-bridge/
schema/cursor-bridge.schema.json # single source of truth
packages/
cursor-proto-lab/ # forked protobuf + direct API probe
schema/ # @cursor-bridge/schema (npm coerce)
credential-loader/ # .env + state.vscdb autodetect
openclaw-plugin/ # before_tool_call belt
goclaw-adapter/ # Go coerce + pre-tool-use binary
scripts/
layered-regression.mjs # L0 raw → L1 9router → L2/L3 coerce
cursor-audit.mjs # raw-only audit (subset of L0)
build-schema.mjs # canonical JSON + Go embed sync
git clone https://github.com/jahrulnr/cursor-bridge.git
cd cursor-bridge
cp .env.example .env # CURSOR_ACCESS_TOKEN + CURSOR_MACHINE_ID (or rely on state.vscdb)
npm install
npm testSibling clones (optional, for L1 regression / 9router file dep):
git clone https://github.com/jahrulnr/9router.git ../9router| Layer | What | Credential | Proves |
|---|---|---|---|
| L0 raw | cursor-proto-lab → api2.cursor.sh |
IDE state.vscdb / .env |
Upstream behavior (leak in thinking, tool_calls) |
| L1 ninerouter | :20128 OpenAI API |
NINEROUTER_API_KEY + 9router Cursor DB |
Guard/coercion vs raw baseline |
| L2 openclaw | @cursor-bridge/schema coerce |
— | Plugin belt shapes (edit, apply_patch) |
| L3 goclaw | Go embed coerce | — | Adapter belt shapes |
Same testMatrix scenario id runs on L0 then L1 — if 9router breaks, you see raw still leaks but client output is wrong (or vice versa).
npm test
npm run regression # L0 + L2 + L3; L1 if 9router up
npm run regression:raw # L0 only (IDE/CLI autoload)
NINEROUTER_API_KEY=... npm run regression:9router # L1 only
npm run validate # test + build:schema + full regressionCredential split: L0 raw uses credential-loader (IDE/CLI). L1 uses 9router's own Cursor connection (dashboard auto-import into 9router DB) — different stores, same upstream API.
npm run probe -- cu/defaultLeak detection scans content + thinking (thinkingLen often non-zero). Without credentials the CLI exits clearly; unit tests still pass.
npm run audit
# writes audit-report.json; exit 1 on failed scenarios# from repo root
openclaw plugins install "$(pwd)/packages/openclaw-plugin" --link
# plugins.entries.cursor-bridge.enabled = true — only after validate + regression:9routernpm run test:goclaw
npm run build:goclaw # → dist/cursor-bridge-pre-tool-use
node scripts/install-goclaw-hook.mjs --bin dist/cursor-bridge-pre-tool-useRegister the printed JSON as a GoClaw script hook on pre_tool_use (command handler does not apply updatedInput).
9router imports @cursor-bridge/schema for cursorToolGuard.js and kimiToolParser.js. Guard defaults on (NINEROUTER_CURSOR_TOOL_GUARD unset or true).
Outbound fixes in kimiToolParser.js:
normalizeClientToolArgs— stringifiededitsJSON → array (LOQeditbug)- OpenClaw
coerce—search_replace/ flat args →edit.edits[]
| Variable | Purpose |
|---|---|
CURSOR_ACCESS_TOKEN |
Bearer token |
CURSOR_MACHINE_ID |
Checksum machine id |
CURSOR_GHOST_MODE |
Default true |
NINEROUTER_CURSOR_TOOL_GUARD |
9router guard toggle (default on) |