@ken-jo/agent-connector 0.6.3 → 0.6.5
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 +25 -12
- package/dist/{action-IKJ2J3X4.js → action-DFUJOXVJ.js} +9 -8
- package/dist/{action-IKJ2J3X4.js.map → action-DFUJOXVJ.js.map} +1 -1
- package/dist/{audit-5K2H7PAT.js → audit-IMNQJZ4W.js} +6 -5
- package/dist/{audit-5K2H7PAT.js.map → audit-IMNQJZ4W.js.map} +1 -1
- package/dist/{chunk-K67UJSJI.js → chunk-66TGBYSL.js} +5 -5
- package/dist/{chunk-QG26JEJF.js → chunk-7C3COFOD.js} +9 -9
- package/dist/{chunk-QG26JEJF.js.map → chunk-7C3COFOD.js.map} +1 -1
- package/dist/{chunk-HUL5CRF2.js → chunk-BAJL27XI.js} +4 -4
- package/dist/{codex-C7ERS3TW.js → chunk-BB4DFAHC.js} +21 -8
- package/dist/chunk-BB4DFAHC.js.map +1 -0
- package/dist/{chunk-STR3CRH3.js → chunk-C4NDV6GW.js} +2 -2
- package/dist/{chunk-LO6NIZSL.js → chunk-CG44RWYJ.js} +5 -5
- package/dist/chunk-D35FMUFZ.js +48 -0
- package/dist/chunk-D35FMUFZ.js.map +1 -0
- package/dist/{chunk-OXANBA4I.js → chunk-ITVST3SZ.js} +2 -2
- package/dist/{chunk-W4GVN3TJ.js → chunk-KQBRUI3Y.js} +3 -3
- package/dist/{chunk-TCJN5S4T.js → chunk-PTITNBSS.js} +22 -33
- package/dist/chunk-PTITNBSS.js.map +1 -0
- package/dist/{chunk-O7CFTOM5.js → chunk-S2TAC22E.js} +2 -2
- package/dist/{chunk-BD72ZF6D.js → chunk-V7GZ3AMV.js} +2 -2
- package/dist/{chunk-BGPVMJOG.js → chunk-ZYB2UFEN.js} +6 -2
- package/dist/chunk-ZYB2UFEN.js.map +1 -0
- package/dist/{claude-code-EIC4Q7OT.js → claude-code-JRKJARPH.js} +5 -4
- package/dist/{claude-code-EIC4Q7OT.js.map → claude-code-JRKJARPH.js.map} +1 -1
- package/dist/cli/sdk.js +5 -4
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/dist/{cline-AJZ67XEE.js → cline-XAFNCZFQ.js} +26 -5
- package/dist/cline-XAFNCZFQ.js.map +1 -0
- package/dist/codex-X3WZZOJ4.js +22 -0
- package/dist/codex-X3WZZOJ4.js.map +1 -0
- package/dist/{define-connector-iosc34CA.d.ts → define-connector-D4UOI__e.d.ts} +1 -1
- package/dist/{detect-KYRQJUDY.js → detect-RT75DWQ5.js} +5 -4
- package/dist/{detect-KYRQJUDY.js.map → detect-RT75DWQ5.js.map} +1 -1
- package/dist/{doctor-BGWPZ676.js → doctor-F3RRQBQN.js} +135 -11
- package/dist/doctor-F3RRQBQN.js.map +1 -0
- package/dist/{hook-YMCFZRJE.js → hook-VYA4Q3YR.js} +9 -8
- package/dist/{hook-YMCFZRJE.js.map → hook-VYA4Q3YR.js.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/{install-RCHVHCHO.js → install-XNTRLUZI.js} +9 -8
- package/dist/{install-RCHVHCHO.js.map → install-XNTRLUZI.js.map} +1 -1
- package/dist/{introspect-z3eKVWHN.d.ts → introspect-gaKVzg2q.d.ts} +1 -1
- package/dist/{leaderboard-V3DXXZNL.js → leaderboard-VF4W6PZ2.js} +3 -2
- package/dist/{leaderboard-V3DXXZNL.js.map → leaderboard-VF4W6PZ2.js.map} +1 -1
- package/dist/open-interpreter-ZHBMASXY.js +154 -0
- package/dist/open-interpreter-ZHBMASXY.js.map +1 -0
- package/dist/{package-75T46SXP.js → package-VRV5YHUJ.js} +7 -6
- package/dist/{package-75T46SXP.js.map → package-VRV5YHUJ.js.map} +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +7 -6
- package/dist/sdk/index.d.ts +4 -4
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +7 -6
- package/dist/{serve-IRMYJWFT.js → serve-EPEAGVOE.js} +9 -8
- package/dist/{serve-IRMYJWFT.js.map → serve-EPEAGVOE.js.map} +1 -1
- package/dist/{status-VJVNMWT7.js → status-3EHFFIQ7.js} +7 -6
- package/dist/{status-VJVNMWT7.js.map → status-3EHFFIQ7.js.map} +1 -1
- package/dist/{statusline-OKW44KFR.js → statusline-64IDYANK.js} +8 -7
- package/dist/{statusline-OKW44KFR.js.map → statusline-64IDYANK.js.map} +1 -1
- package/dist/{telemetry-YVMUXTDG.js → telemetry-AEE4TOFA.js} +6 -5
- package/dist/{telemetry-YVMUXTDG.js.map → telemetry-AEE4TOFA.js.map} +1 -1
- package/dist/{types-CAKApZpX.d.ts → types-htm_wrWo.d.ts} +6 -5
- package/dist/{uninstall-WZHO4CVL.js → uninstall-EJLQGZRN.js} +9 -8
- package/dist/{uninstall-WZHO4CVL.js.map → uninstall-EJLQGZRN.js.map} +1 -1
- package/dist/{upgrade-DZMEUPF2.js → upgrade-ZPHQELKG.js} +9 -8
- package/dist/{upgrade-DZMEUPF2.js.map → upgrade-ZPHQELKG.js.map} +1 -1
- package/dist/{usage-QSM4PP3E.js → usage-IWPGACHN.js} +3 -2
- package/dist/{usage-QSM4PP3E.js.map → usage-IWPGACHN.js.map} +1 -1
- package/dist/{usage-event-FH3X232T.js → usage-event-W5VLRA3X.js} +8 -7
- package/dist/{usage-event-FH3X232T.js.map → usage-event-W5VLRA3X.js.map} +1 -1
- package/package.json +20 -7
- package/dist/chunk-BGPVMJOG.js.map +0 -1
- package/dist/chunk-TCJN5S4T.js.map +0 -1
- package/dist/cline-AJZ67XEE.js.map +0 -1
- package/dist/codex-C7ERS3TW.js.map +0 -1
- package/dist/doctor-BGWPZ676.js.map +0 -1
- package/dist/open-interpreter-CXUCCZI3.js +0 -264
- package/dist/open-interpreter-CXUCCZI3.js.map +0 -1
- /package/dist/{chunk-K67UJSJI.js.map → chunk-66TGBYSL.js.map} +0 -0
- /package/dist/{chunk-HUL5CRF2.js.map → chunk-BAJL27XI.js.map} +0 -0
- /package/dist/{chunk-STR3CRH3.js.map → chunk-C4NDV6GW.js.map} +0 -0
- /package/dist/{chunk-LO6NIZSL.js.map → chunk-CG44RWYJ.js.map} +0 -0
- /package/dist/{chunk-OXANBA4I.js.map → chunk-ITVST3SZ.js.map} +0 -0
- /package/dist/{chunk-W4GVN3TJ.js.map → chunk-KQBRUI3Y.js.map} +0 -0
- /package/dist/{chunk-O7CFTOM5.js.map → chunk-S2TAC22E.js.map} +0 -0
- /package/dist/{chunk-BD72ZF6D.js.map → chunk-V7GZ3AMV.js.map} +0 -0
package/README.md
CHANGED
|
@@ -13,6 +13,11 @@ the native config — or `package` it as a real plugin — across every detected
|
|
|
13
13
|
host: terminal CLIs, IDE extensions and desktop apps alike (Claude Code, Codex,
|
|
14
14
|
Cursor, Copilot, Gemini, OpenCode, Warp, Zed…).
|
|
15
15
|
|
|
16
|
+
Agent-readable docs: [`llms.txt`](https://agent-connector.ai/llms.txt) (route map) ·
|
|
17
|
+
[`llms-full.txt`](https://agent-connector.ai/llms-full.txt) (per-host reference) ·
|
|
18
|
+
[`SKILL.md`](https://agent-connector.ai/skills/agent-connector/SKILL.md) (agent skill) ·
|
|
19
|
+
guide: [Publish an MCP server so users install it in every agent host](https://agent-connector.ai/docs/guides/publish-mcp-server).
|
|
20
|
+
|
|
16
21
|
[](https://www.npmjs.com/package/@ken-jo/agent-connector)
|
|
17
22
|
[](LICENSE)
|
|
18
23
|
[](https://agent-connector.ai/coverage)
|
|
@@ -22,7 +27,7 @@ Cursor, Copilot, Gemini, OpenCode, Warp, Zed…).
|
|
|
22
27
|
[](https://agent-connector.ai/coverage)
|
|
23
28
|

|
|
24
29
|
[](https://agent-plugins.org)
|
|
25
|
-

|
|
26
31
|
|
|
27
32
|
**By the numbers.** Every figure is derived from the adapter registry or measured
|
|
28
33
|
by a test on each run, and a drift test fails if the README and the source disagree.
|
|
@@ -30,12 +35,19 @@ by a test on each run, and a drift test fails if the README and the source disag
|
|
|
30
35
|
| | |
|
|
31
36
|
|---|---|
|
|
32
37
|
| Agent hosts with an adapter | **42** — terminal CLIs, IDE extensions and desktop apps ([coverage wall](https://agent-connector.ai/coverage)) |
|
|
33
|
-
| Surfaces rendered per host | **8** — MCP server (41 hosts), memory (
|
|
34
|
-
| Hook events normalized | **13**, dispatched through **3** paradigms (`json-stdio`
|
|
38
|
+
| Surfaces rendered per host | **8** — MCP server (41 hosts), memory (41), skills (35), hooks (32), commands (19), subagents (16), actions (9), status line (3) |
|
|
39
|
+
| Hook events normalized | **13**, dispatched through **3** paradigms (`json-stdio` 24 hosts · `mcp-only` 10 · `ts-plugin` 8) |
|
|
35
40
|
| Package formats emitted | **9** host plugin formats + **2** MCP standard artifacts (`mcp-server-json`, `mcpb`) |
|
|
36
|
-
| Hosts verified against the real host binary | **
|
|
37
|
-
| Measured footprint | one 135-line `defineConnector()` → **
|
|
38
|
-
| Test suite | **
|
|
41
|
+
| Hosts verified against the real host binary | **29 of 42** (22 of them end-to-end through a model tool call); the other **13** by the registry install harness in an isolated HOME |
|
|
42
|
+
| Measured footprint | one 135-line `defineConnector()` → **65 host-native files** in 6 file extensions across 41 of 42 hosts at user scope (62 at project scope) — `npm run measure:footprint` |
|
|
43
|
+
| Test suite | **152** test files |
|
|
44
|
+
|
|
45
|
+
**Who it is for.** agent-connector is the **publisher** side of MCP distribution:
|
|
46
|
+
you wrote (or are writing) an MCP server and want it to install itself into your
|
|
47
|
+
users' agent hosts — with hooks, skills and a plugin bundle — from your own package,
|
|
48
|
+
`npx <your-package> install`. Tools such as `add-mcp` and `agent-install` are the
|
|
49
|
+
**end-user** side: they add an existing server to the agents on one machine. The two
|
|
50
|
+
compose; agent-connector is what the server's author ships.
|
|
39
51
|
|
|
40
52
|
**Two audiences:** connector developers start at [Quick start](#quick-start);
|
|
41
53
|
if you already run an agent host and just want token totals, jump straight to
|
|
@@ -92,7 +104,7 @@ npm install @ken-jo/agent-connector
|
|
|
92
104
|
"name": "@acme/acme-db-mcp",
|
|
93
105
|
"mcpName": "io.github.acme/acme-db",
|
|
94
106
|
"bin": { "acme-db": "./bin.mjs" },
|
|
95
|
-
"dependencies": { "@ken-jo/agent-connector": "^0.6.
|
|
107
|
+
"dependencies": { "@ken-jo/agent-connector": "^0.6.5" }
|
|
96
108
|
}
|
|
97
109
|
```
|
|
98
110
|
|
|
@@ -514,8 +526,8 @@ set (see [`/coverage`](https://agent-connector.ai/coverage) and
|
|
|
514
526
|
|
|
515
527
|
| Paradigm | Platforms |
|
|
516
528
|
|---|---|
|
|
517
|
-
| `json-stdio` (full hook dispatch) | CodeBuddy · Claude Code · Codex CLI · Cursor · VS Code Copilot · JetBrains Copilot · GitHub Copilot CLI · Gemini CLI · Qwen CLI · Kiro · Kimi CLI · Crush · Goose · Hermes · Droid (Factory) · OpenHands · Antigravity · Antigravity CLI · Continue · Amazon Q · Grok Build · Grok CLI · Devin CLI |
|
|
518
|
-
| `mcp-only` (MCP registration only) | Warp · Cline · Trae · Zed · Freebuff · Xum · Pi · Windsurf ·
|
|
529
|
+
| `json-stdio` (full hook dispatch) | CodeBuddy · Claude Code · Codex CLI · Cursor · VS Code Copilot · JetBrains Copilot · GitHub Copilot CLI · Gemini CLI · Qwen CLI · Kiro · Kimi CLI · Crush · Goose · Hermes · Droid (Factory) · OpenHands · Antigravity · Antigravity CLI · Continue · Amazon Q · Grok Build · Grok CLI · Devin CLI · Open Interpreter |
|
|
530
|
+
| `mcp-only` (MCP registration only) | Warp · Cline · Trae · Zed · Freebuff · Xum · Pi · Windsurf · Junie · Mistral Vibe |
|
|
519
531
|
| `ts-plugin` (generated bridge module) | OpenCode · MiMoCode · Kilo CLI · Kilo · OMP · NemoClaw · OpenClaw · Amp |
|
|
520
532
|
|
|
521
533
|
Adding a platform = **one registry entry + one adapter**.
|
|
@@ -527,8 +539,8 @@ Adding a platform = **one registry entry + one adapter**.
|
|
|
527
539
|
| `detect` | List installed platforms, scopes, capabilities, hook paradigm. |
|
|
528
540
|
| `install [<source>] [--scope …] [--targets …] [--method …] [--dry-run] [--force]` | Render + write MCP + hooks + content surfaces. `<source>` may be local, GitHub/git, `npm:<package>[@version]`, or `.tgz`/`archive:`. |
|
|
529
541
|
| `uninstall [--targets …] [--purge] [--method …]` | Full inverse — removes everything we wrote; `--purge` also clears framework state. |
|
|
530
|
-
| `upgrade [--channel …]` | Re-render host config + heal stale pointers + refresh the home binary (alias: `update`, `sync`); never a silent self-update. |
|
|
531
|
-
| `doctor [--probe] [--explain]` | Per-platform health checks with fixes
|
|
542
|
+
| `upgrade [--channel …]` | Re-render host config + heal stale pointers + refresh the home binary (alias: `update`, `sync`); clears every `doctor` version warning; never a silent self-update. |
|
|
543
|
+
| `doctor [--probe] [--heal] [--explain] [--json] [--dry-run]` | Per-platform health checks with fixes, plus version checks: the home binary's target install and every connector's rendering framework version are compared with the running CLI (drift → warn + `upgrade`). `--probe` runs a live MCP handshake, `--heal` re-syncs every fixable finding, `--explain` prints the per-`(host, event)` hook honor matrix. |
|
|
532
544
|
| `status` | Light install-state: which connectors are present on which hosts (always exits 0). |
|
|
533
545
|
| `package [--format <fmt>\|all]` | Emit a host plugin bundle, or an OFFICIAL standard artifact: `mcp-server-json` (registry) · `mcpb` (one-click bundle). |
|
|
534
546
|
| `audit [--strict]` | Pre-install package identity lint: package name/version/bin, runtime dependency, connector id/version drift, and publish `files` coverage. |
|
|
@@ -626,7 +638,8 @@ every adapter, drives the real install → uninstall into an isolated HOME and
|
|
|
626
638
|
asserts on-disk placement + zero residue. A separate committed
|
|
627
639
|
`scripts/verify-host.mjs` driver installs real host CLIs from the verification
|
|
628
640
|
matrix and checks install → placement → clean-uninstall; live hook dispatch +
|
|
629
|
-
telemetry are proven end-to-end where the host can run headlessly
|
|
641
|
+
telemetry are proven end-to-end where the host can run headlessly, against a real
|
|
642
|
+
model or the committed local mock model provider (`scripts/README.md`). IDE
|
|
630
643
|
extensions / GUI editors with no headless CLI stay covered by the
|
|
631
644
|
install-roundtrip harness.
|
|
632
645
|
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
fail
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PTITNBSS.js";
|
|
5
5
|
import {
|
|
6
6
|
runAction
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-66TGBYSL.js";
|
|
8
8
|
import "./chunk-OP4KBXUO.js";
|
|
9
9
|
import "./chunk-GDIAHWNY.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-ITVST3SZ.js";
|
|
11
|
+
import "./chunk-KQBRUI3Y.js";
|
|
12
12
|
import "./chunk-IVAWP6HH.js";
|
|
13
13
|
import "./chunk-KHO5WNTP.js";
|
|
14
14
|
import "./chunk-4NFDNY3C.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-ZYB2UFEN.js";
|
|
16
|
+
import "./chunk-D35FMUFZ.js";
|
|
17
|
+
import "./chunk-S2TAC22E.js";
|
|
18
|
+
import "./chunk-7C3COFOD.js";
|
|
18
19
|
import "./chunk-NBYKLUF6.js";
|
|
19
20
|
import "./chunk-QSY74NAP.js";
|
|
20
21
|
import "./chunk-UMQ6NBQR.js";
|
|
@@ -53,4 +54,4 @@ async function run(argv) {
|
|
|
53
54
|
export {
|
|
54
55
|
run
|
|
55
56
|
};
|
|
56
|
-
//# sourceMappingURL=action-
|
|
57
|
+
//# sourceMappingURL=action-DFUJOXVJ.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/action.ts"],"sourcesContent":["/**\n * cli/commands/action — the universal user-invokable action entrypoint.\n *\n * agent-connector action <platform> <actionId> --connector <id>\n *\n * A host-native affordance or a manual command points at the single stable home\n * binary (via core/spawn.buildHomeBinActionCommand). This command parses the\n * positionals + --connector, dispatches through runAction, writes any\n * stdout/stderr the action produced, and exits with its code. It reads NO stdin\n * (an action takes no host payload, unlike a hook or status line).\n *\n * USER-TRIGGERED is the runtime's contract: unlike the fail-open hook command,\n * an unknown action id or a throwing run surfaces as exit 1 + a stderr message —\n * the user invoked it deliberately, so the failure is shown, never swallowed.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport { runAction } from \"../../runtime/index.js\";\nimport { fail } from \"../app.js\";\n\nexport async function run(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const platformId = positionals[0];\n const actionId = positionals[1];\n if (!platformId || !actionId) {\n return fail(\"usage: agent-connector action <platform> <actionId> --connector <id>\");\n }\n const connectorId = values.connector;\n if (!connectorId || connectorId.trim() === \"\") {\n return fail(\"action requires --connector <id>\");\n }\n\n const reply = await runAction({ platformId, actionId, connectorId });\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\n process.stdout.write(reply.stdout.endsWith(\"\\n\") ? reply.stdout : `${reply.stdout}\\n`);\n }\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\n }\n process.exit(reply.exitCode);\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/action.ts"],"sourcesContent":["/**\n * cli/commands/action — the universal user-invokable action entrypoint.\n *\n * agent-connector action <platform> <actionId> --connector <id>\n *\n * A host-native affordance or a manual command points at the single stable home\n * binary (via core/spawn.buildHomeBinActionCommand). This command parses the\n * positionals + --connector, dispatches through runAction, writes any\n * stdout/stderr the action produced, and exits with its code. It reads NO stdin\n * (an action takes no host payload, unlike a hook or status line).\n *\n * USER-TRIGGERED is the runtime's contract: unlike the fail-open hook command,\n * an unknown action id or a throwing run surfaces as exit 1 + a stderr message —\n * the user invoked it deliberately, so the failure is shown, never swallowed.\n */\n\nimport { parseArgs } from \"node:util\";\n\nimport { runAction } from \"../../runtime/index.js\";\nimport { fail } from \"../app.js\";\n\nexport async function run(argv: string[]): Promise<number> {\n const { values, positionals } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n },\n allowPositionals: true,\n });\n\n const platformId = positionals[0];\n const actionId = positionals[1];\n if (!platformId || !actionId) {\n return fail(\"usage: agent-connector action <platform> <actionId> --connector <id>\");\n }\n const connectorId = values.connector;\n if (!connectorId || connectorId.trim() === \"\") {\n return fail(\"action requires --connector <id>\");\n }\n\n const reply = await runAction({ platformId, actionId, connectorId });\n if (reply.stdout !== undefined && reply.stdout !== \"\") {\n process.stdout.write(reply.stdout.endsWith(\"\\n\") ? reply.stdout : `${reply.stdout}\\n`);\n }\n if (reply.stderr !== undefined && reply.stderr !== \"\") {\n process.stderr.write(reply.stderr.endsWith(\"\\n\") ? reply.stderr : `${reply.stderr}\\n`);\n }\n process.exit(reply.exitCode);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAgBA,SAAS,iBAAiB;AAK1B,eAAsB,IAAI,MAAiC;AACzD,QAAM,EAAE,QAAQ,YAAY,IAAI,UAAU;AAAA,IACxC,MAAM;AAAA,IACN,SAAS;AAAA,MACP,WAAW,EAAE,MAAM,SAAS;AAAA,IAC9B;AAAA,IACA,kBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,aAAa,YAAY,CAAC;AAChC,QAAM,WAAW,YAAY,CAAC;AAC9B,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,WAAO,KAAK,sEAAsE;AAAA,EACpF;AACA,QAAM,cAAc,OAAO;AAC3B,MAAI,CAAC,eAAe,YAAY,KAAK,MAAM,IAAI;AAC7C,WAAO,KAAK,kCAAkC;AAAA,EAChD;AAEA,QAAM,QAAQ,MAAM,UAAU,EAAE,YAAY,UAAU,YAAY,CAAC;AACnE,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,MAAI,MAAM,WAAW,UAAa,MAAM,WAAW,IAAI;AACrD,YAAQ,OAAO,MAAM,MAAM,OAAO,SAAS,IAAI,IAAI,MAAM,SAAS,GAAG,MAAM,MAAM;AAAA,CAAI;AAAA,EACvF;AACA,UAAQ,KAAK,MAAM,QAAQ;AAC7B;","names":[]}
|
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
import {
|
|
3
3
|
fail,
|
|
4
4
|
print
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-PTITNBSS.js";
|
|
6
6
|
import {
|
|
7
7
|
findConnectorConfig,
|
|
8
8
|
loadConnectorFromPath
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ZYB2UFEN.js";
|
|
10
|
+
import "./chunk-D35FMUFZ.js";
|
|
10
11
|
import {
|
|
11
12
|
deriveHostAliasFromMcpName,
|
|
12
13
|
deriveHostAliasFromPackageName,
|
|
13
14
|
findNearestPackageJson,
|
|
14
15
|
readConnectorPackageMetadataFromPackageJson
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-S2TAC22E.js";
|
|
17
|
+
import "./chunk-7C3COFOD.js";
|
|
17
18
|
import "./chunk-NBYKLUF6.js";
|
|
18
19
|
import "./chunk-UMQ6NBQR.js";
|
|
19
20
|
import "./chunk-GZGLCCEE.js";
|
|
@@ -308,4 +309,4 @@ async function run(argv) {
|
|
|
308
309
|
export {
|
|
309
310
|
run
|
|
310
311
|
};
|
|
311
|
-
//# sourceMappingURL=audit-
|
|
312
|
+
//# sourceMappingURL=audit-IMNQJZ4W.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/audit.ts","../src/core/package-audit.ts"],"sourcesContent":["/**\n * cli/commands/audit — pre-install package identity lint for branded MCP packages.\n *\n * This command catches the mistakes that make a connector feel unbranded after\n * publish: missing bin, missing runtime dependency, package/connector version\n * drift, and mismatched package-derived aliases.\n */\n\nimport { dirname } from \"node:path\";\nimport { parseArgs } from \"node:util\";\n\nimport { findConnectorConfig } from \"../../core/load-connector.js\";\nimport {\n auditConnectorPackage,\n type PackageAuditFinding,\n type PackageAuditResult,\n} from \"../../core/package-audit.js\";\nimport { findNearestPackageJson } from \"../../core/package-metadata.js\";\nimport { fail, print } from \"../app.js\";\n\nfunction glyph(severity: PackageAuditFinding[\"severity\"]): string {\n return severity === \"error\" ? \"x\" : severity === \"warn\" ? \"!\" : \"✓\";\n}\n\nfunction renderAudit(result: PackageAuditResult): string {\n const lines = [\n `audit ${result.connectorId ? `\"${result.connectorId}\"` : \"package\"}`,\n ` package: ${result.packageJsonPath}`,\n ` connector: ${result.connectorPath}`,\n ];\n if (result.binName) lines.push(` bin: ${result.binName}`);\n lines.push(\"\");\n\n for (const finding of result.findings) {\n lines.push(` ${glyph(finding.severity)} ${finding.message}`);\n }\n\n const errors = result.findings.filter((finding) => finding.severity === \"error\").length;\n const warnings = result.findings.filter((finding) => finding.severity === \"warn\").length;\n lines.push(\"\");\n lines.push(\n errors === 0\n ? `✓ package audit passed${warnings > 0 ? ` with ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"}.`\n : `x package audit failed with ${errors} error${errors === 1 ? \"\" : \"s\"}${warnings > 0 ? ` and ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"}.`,\n );\n return lines.join(\"\\n\");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n \"package-json\": { type: \"string\" },\n project: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n strict: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n const connectorPath = values.connector ?? findConnectorConfig(projectDir);\n if (!connectorPath) {\n return fail(\n \"no connector config found. Pass --connector <path> or add an \" +\n \"agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n\n const packageJsonPath =\n values[\"package-json\"] ?? findNearestPackageJson(dirname(connectorPath));\n if (!packageJsonPath) {\n return fail(\"no package.json found. Pass --package-json <path>.\");\n }\n\n const result = await auditConnectorPackage({ connectorPath, packageJsonPath });\n if (values.json) {\n print(JSON.stringify(result, null, 2));\n } else {\n print(renderAudit(result));\n }\n\n const hasError = result.findings.some((finding) => finding.severity === \"error\");\n const hasWarning = result.findings.some((finding) => finding.severity === \"warn\");\n return hasError || (values.strict && hasWarning) ? 1 : 0;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\n\nimport { loadConnectorFromPath } from \"./load-connector.js\";\nimport {\n deriveHostAliasFromMcpName,\n deriveHostAliasFromPackageName,\n readConnectorPackageMetadataFromPackageJson,\n} from \"./package-metadata.js\";\nimport type { ResolvedConnector } from \"./types.js\";\n\nexport type PackageAuditSeverity = \"error\" | \"warn\" | \"info\";\n\nexport interface PackageAuditFinding {\n severity: PackageAuditSeverity;\n code: string;\n message: string;\n}\n\nexport interface PackageAuditResult {\n ok: boolean;\n packageJsonPath: string;\n connectorPath: string;\n packageName?: string;\n packageVersion?: string;\n connectorId?: string;\n connectorVersion?: string;\n binName?: string;\n findings: PackageAuditFinding[];\n}\n\ninterface RawPackageJson {\n name?: unknown;\n version?: unknown;\n mcpName?: unknown;\n mcp?: unknown;\n bin?: unknown;\n files?: unknown;\n dependencies?: unknown;\n devDependencies?: unknown;\n peerDependencies?: unknown;\n}\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readRawPackageJson(path: string): RawPackageJson {\n return JSON.parse(readFileSync(path, \"utf8\")) as RawPackageJson;\n}\n\nfunction dependencyVersion(pkg: RawPackageJson, name: string): string | undefined {\n for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const deps = pkg[field];\n if (!deps || typeof deps !== \"object\" || Array.isArray(deps)) continue;\n const value = (deps as Record<string, unknown>)[name];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n }\n return undefined;\n}\n\nfunction dependencyField(pkg: RawPackageJson, name: string): string | undefined {\n for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const deps = pkg[field];\n if (!deps || typeof deps !== \"object\" || Array.isArray(deps)) continue;\n if (typeof (deps as Record<string, unknown>)[name] === \"string\") return field;\n }\n return undefined;\n}\n\nfunction normalizePackagePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction binEntries(bin: unknown, packageName: string | undefined): [string, string][] {\n if (typeof bin === \"string\") {\n const derived = packageName?.startsWith(\"@\")\n ? packageName.split(\"/\")[1]\n : packageName;\n const name = cleanString(derived);\n return name ? [[name, bin]] : [];\n }\n if (!bin || typeof bin !== \"object\" || Array.isArray(bin)) return [];\n return Object.entries(bin)\n .filter((entry): entry is [string, string] => cleanString(entry[0]) != null && typeof entry[1] === \"string\")\n .map(([name, target]) => [name, target]);\n}\n\nfunction filesList(files: unknown): string[] | undefined {\n if (files == null) return undefined;\n if (!Array.isArray(files)) return [];\n return files.filter((entry): entry is string => typeof entry === \"string\" && entry.trim() !== \"\");\n}\n\nfunction filesIncludes(files: string[], relPath: string): boolean {\n const normalized = normalizePackagePath(relPath);\n return files.some((entry) => {\n const item = normalizePackagePath(entry);\n return item === normalized || normalized.startsWith(`${item.replace(/\\/$/, \"\")}/`);\n });\n}\n\nfunction add(\n findings: PackageAuditFinding[],\n severity: PackageAuditSeverity,\n code: string,\n message: string,\n): void {\n findings.push({ severity, code, message });\n}\n\nfunction expectedAliases(pkg: RawPackageJson, packageName: string | undefined): string[] {\n const out = new Set<string>();\n const mcpName =\n cleanString(pkg.mcpName) ??\n (pkg.mcp && typeof pkg.mcp === \"object\" && !Array.isArray(pkg.mcp)\n ? cleanString((pkg.mcp as { name?: unknown; mcpName?: unknown }).mcpName) ??\n cleanString((pkg.mcp as { name?: unknown; mcpName?: unknown }).name)\n : undefined);\n if (mcpName) {\n const alias = deriveHostAliasFromMcpName(mcpName);\n if (alias) out.add(alias);\n }\n if (packageName) {\n const alias = deriveHostAliasFromPackageName(packageName);\n if (alias) out.add(alias);\n }\n return [...out];\n}\n\nfunction auditLoadedConnector(input: {\n pkg: RawPackageJson;\n packageJsonPath: string;\n connectorPath: string;\n connector: ResolvedConnector;\n}): PackageAuditResult {\n const { pkg, packageJsonPath, connectorPath, connector } = input;\n const packageDir = dirname(packageJsonPath);\n const findings: PackageAuditFinding[] = [];\n const packageName = cleanString(pkg.name);\n const packageVersion = cleanString(pkg.version);\n const entries = binEntries(pkg.bin, packageName);\n const metadata = readConnectorPackageMetadataFromPackageJson(packageJsonPath);\n const metadataMcp = metadata.mcp;\n const aliasCandidates = expectedAliases(pkg, packageName);\n const selectedBin = metadataMcp?.bin;\n\n if (!packageName) {\n add(findings, \"error\", \"missing-package-name\", \"package.json must declare a non-empty `name`.\");\n } else {\n add(findings, \"info\", \"package-name\", `package name: ${packageName}`);\n }\n\n if (!packageVersion) {\n add(findings, \"error\", \"missing-version\", \"package.json must declare a non-empty `version`.\");\n } else {\n add(findings, \"info\", \"package-version\", `package version: ${packageVersion}`);\n }\n\n if (entries.length === 0) {\n add(findings, \"error\", \"missing-bin\", \"branded MCP packages must expose a `bin` command.\");\n } else if (!selectedBin) {\n add(\n findings,\n \"error\",\n \"ambiguous-bin\",\n \"package.json `bin` could not be mapped to one branded command; use one bin or a bin matching the package basename.\",\n );\n } else {\n add(findings, \"info\", \"bin\", `branded bin: ${selectedBin}`);\n }\n\n for (const [binName, target] of entries) {\n const targetPath = resolve(packageDir, target);\n if (!existsSync(targetPath)) {\n add(findings, \"error\", \"missing-bin-target\", `bin \"${binName}\" points at a missing file: ${target}`);\n }\n }\n\n const dep = dependencyVersion(pkg, \"@ken-jo/agent-connector\");\n const depField = dependencyField(pkg, \"@ken-jo/agent-connector\");\n if (!dep) {\n add(\n findings,\n \"error\",\n \"missing-agent-connector-dependency\",\n \"package.json must depend on `@ken-jo/agent-connector` so the branded bin works after install.\",\n );\n } else if (depField !== \"dependencies\") {\n add(\n findings,\n \"warn\",\n \"agent-connector-not-runtime-dependency\",\n `@ken-jo/agent-connector is in ${depField}; published MCP packages usually need it in dependencies.`,\n );\n } else {\n add(findings, \"info\", \"agent-connector-dependency\", `@ken-jo/agent-connector dependency: ${dep}`);\n }\n\n if (metadataMcp?.packageName && connector.mcp?.packageName && connector.mcp.packageName !== metadataMcp.packageName) {\n add(\n findings,\n \"error\",\n \"package-name-drift\",\n `connector mcp.packageName (${connector.mcp.packageName}) differs from package.json name (${metadataMcp.packageName}).`,\n );\n }\n\n if (packageVersion && connector.version !== packageVersion) {\n add(\n findings,\n \"warn\",\n \"version-drift\",\n `connector version (${connector.version}) differs from package.json version (${packageVersion}); keep package.json as the source of truth unless this is intentional.`,\n );\n }\n\n if (aliasCandidates.length > 0 && !aliasCandidates.includes(connector.id)) {\n add(\n findings,\n \"warn\",\n \"connector-id-drift\",\n `connector id (${connector.id}) does not match package-derived alias candidates (${aliasCandidates.join(\", \")}).`,\n );\n }\n\n if (selectedBin && selectedBin !== connector.id) {\n add(\n findings,\n \"warn\",\n \"bin-id-drift\",\n `branded bin (${selectedBin}) differs from connector id (${connector.id}); users may see two names for one MCP package.`,\n );\n }\n\n const files = filesList(pkg.files);\n if (files && files.length === 0) {\n add(findings, \"error\", \"invalid-files\", \"`files` must be an array of package paths when present.\");\n } else if (files) {\n const connectorRel = normalizePackagePath(relative(packageDir, connectorPath));\n if (!connectorRel.startsWith(\"../\") && !isAbsolute(connectorRel) && !filesIncludes(files, connectorRel)) {\n add(\n findings,\n \"warn\",\n \"files-missing-connector\",\n `package.json files does not include the connector config (${connectorRel}).`,\n );\n }\n for (const [binName, target] of entries) {\n const rel = normalizePackagePath(target);\n if (!filesIncludes(files, rel)) {\n add(findings, \"warn\", \"files-missing-bin\", `package.json files does not include bin \"${binName}\" target (${rel}).`);\n }\n }\n }\n\n const hasError = findings.some((finding) => finding.severity === \"error\");\n return {\n ok: !hasError,\n packageJsonPath,\n connectorPath,\n ...(packageName ? { packageName } : {}),\n ...(packageVersion ? { packageVersion } : {}),\n connectorId: connector.id,\n connectorVersion: connector.version,\n ...(selectedBin ? { binName: selectedBin } : {}),\n findings,\n };\n}\n\nexport async function auditConnectorPackage(input: {\n connectorPath: string;\n packageJsonPath: string;\n}): Promise<PackageAuditResult> {\n const packageJsonPath = resolve(input.packageJsonPath);\n const connectorPath = resolve(input.connectorPath);\n const findings: PackageAuditFinding[] = [];\n\n if (!existsSync(packageJsonPath)) {\n add(findings, \"error\", \"package-json-not-found\", `package.json not found: ${packageJsonPath}`);\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n if (!existsSync(connectorPath)) {\n add(findings, \"error\", \"connector-not-found\", `connector config not found: ${connectorPath}`);\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n let pkg: RawPackageJson;\n try {\n pkg = readRawPackageJson(packageJsonPath);\n } catch (err) {\n add(\n findings,\n \"error\",\n \"package-json-invalid\",\n `package.json could not be parsed: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n try {\n const { connector } = await loadConnectorFromPath(connectorPath);\n return auditLoadedConnector({ pkg, packageJsonPath, connectorPath, connector });\n } catch (err) {\n add(\n findings,\n \"error\",\n \"connector-load-failed\",\n `connector config could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n}\n"],"mappings":"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","names":["dirname","dirname"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/audit.ts","../src/core/package-audit.ts"],"sourcesContent":["/**\n * cli/commands/audit — pre-install package identity lint for branded MCP packages.\n *\n * This command catches the mistakes that make a connector feel unbranded after\n * publish: missing bin, missing runtime dependency, package/connector version\n * drift, and mismatched package-derived aliases.\n */\n\nimport { dirname } from \"node:path\";\nimport { parseArgs } from \"node:util\";\n\nimport { findConnectorConfig } from \"../../core/load-connector.js\";\nimport {\n auditConnectorPackage,\n type PackageAuditFinding,\n type PackageAuditResult,\n} from \"../../core/package-audit.js\";\nimport { findNearestPackageJson } from \"../../core/package-metadata.js\";\nimport { fail, print } from \"../app.js\";\n\nfunction glyph(severity: PackageAuditFinding[\"severity\"]): string {\n return severity === \"error\" ? \"x\" : severity === \"warn\" ? \"!\" : \"✓\";\n}\n\nfunction renderAudit(result: PackageAuditResult): string {\n const lines = [\n `audit ${result.connectorId ? `\"${result.connectorId}\"` : \"package\"}`,\n ` package: ${result.packageJsonPath}`,\n ` connector: ${result.connectorPath}`,\n ];\n if (result.binName) lines.push(` bin: ${result.binName}`);\n lines.push(\"\");\n\n for (const finding of result.findings) {\n lines.push(` ${glyph(finding.severity)} ${finding.message}`);\n }\n\n const errors = result.findings.filter((finding) => finding.severity === \"error\").length;\n const warnings = result.findings.filter((finding) => finding.severity === \"warn\").length;\n lines.push(\"\");\n lines.push(\n errors === 0\n ? `✓ package audit passed${warnings > 0 ? ` with ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"}.`\n : `x package audit failed with ${errors} error${errors === 1 ? \"\" : \"s\"}${warnings > 0 ? ` and ${warnings} warning${warnings === 1 ? \"\" : \"s\"}` : \"\"}.`,\n );\n return lines.join(\"\\n\");\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n connector: { type: \"string\" },\n \"package-json\": { type: \"string\" },\n project: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n strict: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const projectDir = values.project ?? process.cwd();\n const connectorPath = values.connector ?? findConnectorConfig(projectDir);\n if (!connectorPath) {\n return fail(\n \"no connector config found. Pass --connector <path> or add an \" +\n \"agent-connector.config.{mjs,js,json} to your project.\",\n );\n }\n\n const packageJsonPath =\n values[\"package-json\"] ?? findNearestPackageJson(dirname(connectorPath));\n if (!packageJsonPath) {\n return fail(\"no package.json found. Pass --package-json <path>.\");\n }\n\n const result = await auditConnectorPackage({ connectorPath, packageJsonPath });\n if (values.json) {\n print(JSON.stringify(result, null, 2));\n } else {\n print(renderAudit(result));\n }\n\n const hasError = result.findings.some((finding) => finding.severity === \"error\");\n const hasWarning = result.findings.some((finding) => finding.severity === \"warn\");\n return hasError || (values.strict && hasWarning) ? 1 : 0;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, relative, resolve } from \"node:path\";\n\nimport { loadConnectorFromPath } from \"./load-connector.js\";\nimport {\n deriveHostAliasFromMcpName,\n deriveHostAliasFromPackageName,\n readConnectorPackageMetadataFromPackageJson,\n} from \"./package-metadata.js\";\nimport type { ResolvedConnector } from \"./types.js\";\n\nexport type PackageAuditSeverity = \"error\" | \"warn\" | \"info\";\n\nexport interface PackageAuditFinding {\n severity: PackageAuditSeverity;\n code: string;\n message: string;\n}\n\nexport interface PackageAuditResult {\n ok: boolean;\n packageJsonPath: string;\n connectorPath: string;\n packageName?: string;\n packageVersion?: string;\n connectorId?: string;\n connectorVersion?: string;\n binName?: string;\n findings: PackageAuditFinding[];\n}\n\ninterface RawPackageJson {\n name?: unknown;\n version?: unknown;\n mcpName?: unknown;\n mcp?: unknown;\n bin?: unknown;\n files?: unknown;\n dependencies?: unknown;\n devDependencies?: unknown;\n peerDependencies?: unknown;\n}\n\nfunction cleanString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n\nfunction readRawPackageJson(path: string): RawPackageJson {\n return JSON.parse(readFileSync(path, \"utf8\")) as RawPackageJson;\n}\n\nfunction dependencyVersion(pkg: RawPackageJson, name: string): string | undefined {\n for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const deps = pkg[field];\n if (!deps || typeof deps !== \"object\" || Array.isArray(deps)) continue;\n const value = (deps as Record<string, unknown>)[name];\n if (typeof value === \"string\" && value.trim()) return value.trim();\n }\n return undefined;\n}\n\nfunction dependencyField(pkg: RawPackageJson, name: string): string | undefined {\n for (const field of [\"dependencies\", \"devDependencies\", \"peerDependencies\"] as const) {\n const deps = pkg[field];\n if (!deps || typeof deps !== \"object\" || Array.isArray(deps)) continue;\n if (typeof (deps as Record<string, unknown>)[name] === \"string\") return field;\n }\n return undefined;\n}\n\nfunction normalizePackagePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nfunction binEntries(bin: unknown, packageName: string | undefined): [string, string][] {\n if (typeof bin === \"string\") {\n const derived = packageName?.startsWith(\"@\")\n ? packageName.split(\"/\")[1]\n : packageName;\n const name = cleanString(derived);\n return name ? [[name, bin]] : [];\n }\n if (!bin || typeof bin !== \"object\" || Array.isArray(bin)) return [];\n return Object.entries(bin)\n .filter((entry): entry is [string, string] => cleanString(entry[0]) != null && typeof entry[1] === \"string\")\n .map(([name, target]) => [name, target]);\n}\n\nfunction filesList(files: unknown): string[] | undefined {\n if (files == null) return undefined;\n if (!Array.isArray(files)) return [];\n return files.filter((entry): entry is string => typeof entry === \"string\" && entry.trim() !== \"\");\n}\n\nfunction filesIncludes(files: string[], relPath: string): boolean {\n const normalized = normalizePackagePath(relPath);\n return files.some((entry) => {\n const item = normalizePackagePath(entry);\n return item === normalized || normalized.startsWith(`${item.replace(/\\/$/, \"\")}/`);\n });\n}\n\nfunction add(\n findings: PackageAuditFinding[],\n severity: PackageAuditSeverity,\n code: string,\n message: string,\n): void {\n findings.push({ severity, code, message });\n}\n\nfunction expectedAliases(pkg: RawPackageJson, packageName: string | undefined): string[] {\n const out = new Set<string>();\n const mcpName =\n cleanString(pkg.mcpName) ??\n (pkg.mcp && typeof pkg.mcp === \"object\" && !Array.isArray(pkg.mcp)\n ? cleanString((pkg.mcp as { name?: unknown; mcpName?: unknown }).mcpName) ??\n cleanString((pkg.mcp as { name?: unknown; mcpName?: unknown }).name)\n : undefined);\n if (mcpName) {\n const alias = deriveHostAliasFromMcpName(mcpName);\n if (alias) out.add(alias);\n }\n if (packageName) {\n const alias = deriveHostAliasFromPackageName(packageName);\n if (alias) out.add(alias);\n }\n return [...out];\n}\n\nfunction auditLoadedConnector(input: {\n pkg: RawPackageJson;\n packageJsonPath: string;\n connectorPath: string;\n connector: ResolvedConnector;\n}): PackageAuditResult {\n const { pkg, packageJsonPath, connectorPath, connector } = input;\n const packageDir = dirname(packageJsonPath);\n const findings: PackageAuditFinding[] = [];\n const packageName = cleanString(pkg.name);\n const packageVersion = cleanString(pkg.version);\n const entries = binEntries(pkg.bin, packageName);\n const metadata = readConnectorPackageMetadataFromPackageJson(packageJsonPath);\n const metadataMcp = metadata.mcp;\n const aliasCandidates = expectedAliases(pkg, packageName);\n const selectedBin = metadataMcp?.bin;\n\n if (!packageName) {\n add(findings, \"error\", \"missing-package-name\", \"package.json must declare a non-empty `name`.\");\n } else {\n add(findings, \"info\", \"package-name\", `package name: ${packageName}`);\n }\n\n if (!packageVersion) {\n add(findings, \"error\", \"missing-version\", \"package.json must declare a non-empty `version`.\");\n } else {\n add(findings, \"info\", \"package-version\", `package version: ${packageVersion}`);\n }\n\n if (entries.length === 0) {\n add(findings, \"error\", \"missing-bin\", \"branded MCP packages must expose a `bin` command.\");\n } else if (!selectedBin) {\n add(\n findings,\n \"error\",\n \"ambiguous-bin\",\n \"package.json `bin` could not be mapped to one branded command; use one bin or a bin matching the package basename.\",\n );\n } else {\n add(findings, \"info\", \"bin\", `branded bin: ${selectedBin}`);\n }\n\n for (const [binName, target] of entries) {\n const targetPath = resolve(packageDir, target);\n if (!existsSync(targetPath)) {\n add(findings, \"error\", \"missing-bin-target\", `bin \"${binName}\" points at a missing file: ${target}`);\n }\n }\n\n const dep = dependencyVersion(pkg, \"@ken-jo/agent-connector\");\n const depField = dependencyField(pkg, \"@ken-jo/agent-connector\");\n if (!dep) {\n add(\n findings,\n \"error\",\n \"missing-agent-connector-dependency\",\n \"package.json must depend on `@ken-jo/agent-connector` so the branded bin works after install.\",\n );\n } else if (depField !== \"dependencies\") {\n add(\n findings,\n \"warn\",\n \"agent-connector-not-runtime-dependency\",\n `@ken-jo/agent-connector is in ${depField}; published MCP packages usually need it in dependencies.`,\n );\n } else {\n add(findings, \"info\", \"agent-connector-dependency\", `@ken-jo/agent-connector dependency: ${dep}`);\n }\n\n if (metadataMcp?.packageName && connector.mcp?.packageName && connector.mcp.packageName !== metadataMcp.packageName) {\n add(\n findings,\n \"error\",\n \"package-name-drift\",\n `connector mcp.packageName (${connector.mcp.packageName}) differs from package.json name (${metadataMcp.packageName}).`,\n );\n }\n\n if (packageVersion && connector.version !== packageVersion) {\n add(\n findings,\n \"warn\",\n \"version-drift\",\n `connector version (${connector.version}) differs from package.json version (${packageVersion}); keep package.json as the source of truth unless this is intentional.`,\n );\n }\n\n if (aliasCandidates.length > 0 && !aliasCandidates.includes(connector.id)) {\n add(\n findings,\n \"warn\",\n \"connector-id-drift\",\n `connector id (${connector.id}) does not match package-derived alias candidates (${aliasCandidates.join(\", \")}).`,\n );\n }\n\n if (selectedBin && selectedBin !== connector.id) {\n add(\n findings,\n \"warn\",\n \"bin-id-drift\",\n `branded bin (${selectedBin}) differs from connector id (${connector.id}); users may see two names for one MCP package.`,\n );\n }\n\n const files = filesList(pkg.files);\n if (files && files.length === 0) {\n add(findings, \"error\", \"invalid-files\", \"`files` must be an array of package paths when present.\");\n } else if (files) {\n const connectorRel = normalizePackagePath(relative(packageDir, connectorPath));\n if (!connectorRel.startsWith(\"../\") && !isAbsolute(connectorRel) && !filesIncludes(files, connectorRel)) {\n add(\n findings,\n \"warn\",\n \"files-missing-connector\",\n `package.json files does not include the connector config (${connectorRel}).`,\n );\n }\n for (const [binName, target] of entries) {\n const rel = normalizePackagePath(target);\n if (!filesIncludes(files, rel)) {\n add(findings, \"warn\", \"files-missing-bin\", `package.json files does not include bin \"${binName}\" target (${rel}).`);\n }\n }\n }\n\n const hasError = findings.some((finding) => finding.severity === \"error\");\n return {\n ok: !hasError,\n packageJsonPath,\n connectorPath,\n ...(packageName ? { packageName } : {}),\n ...(packageVersion ? { packageVersion } : {}),\n connectorId: connector.id,\n connectorVersion: connector.version,\n ...(selectedBin ? { binName: selectedBin } : {}),\n findings,\n };\n}\n\nexport async function auditConnectorPackage(input: {\n connectorPath: string;\n packageJsonPath: string;\n}): Promise<PackageAuditResult> {\n const packageJsonPath = resolve(input.packageJsonPath);\n const connectorPath = resolve(input.connectorPath);\n const findings: PackageAuditFinding[] = [];\n\n if (!existsSync(packageJsonPath)) {\n add(findings, \"error\", \"package-json-not-found\", `package.json not found: ${packageJsonPath}`);\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n if (!existsSync(connectorPath)) {\n add(findings, \"error\", \"connector-not-found\", `connector config not found: ${connectorPath}`);\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n let pkg: RawPackageJson;\n try {\n pkg = readRawPackageJson(packageJsonPath);\n } catch (err) {\n add(\n findings,\n \"error\",\n \"package-json-invalid\",\n `package.json could not be parsed: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n\n try {\n const { connector } = await loadConnectorFromPath(connectorPath);\n return auditLoadedConnector({ pkg, packageJsonPath, connectorPath, connector });\n } catch (err) {\n add(\n findings,\n \"error\",\n \"connector-load-failed\",\n `connector config could not be loaded: ${err instanceof Error ? err.message : String(err)}`,\n );\n return { ok: false, packageJsonPath, connectorPath, findings };\n }\n}\n"],"mappings":"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","names":["dirname","dirname"]}
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
} from "./chunk-GDIAHWNY.js";
|
|
10
10
|
import {
|
|
11
11
|
detectRuntimeHost
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ITVST3SZ.js";
|
|
13
13
|
import {
|
|
14
14
|
attachLazyTelemetryUsage,
|
|
15
15
|
buildTelemetryAccessor,
|
|
16
16
|
measureToolCall,
|
|
17
17
|
measureToolDefs
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-KQBRUI3Y.js";
|
|
19
19
|
import {
|
|
20
20
|
getTokenizer,
|
|
21
21
|
inferModelFamily,
|
|
@@ -32,11 +32,11 @@ import {
|
|
|
32
32
|
import {
|
|
33
33
|
loadRegisteredConnector,
|
|
34
34
|
readRegisteredMeta
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-ZYB2UFEN.js";
|
|
36
36
|
import {
|
|
37
37
|
REGISTERED_PLATFORM_IDS,
|
|
38
38
|
loadAdapter
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-7C3COFOD.js";
|
|
40
40
|
import {
|
|
41
41
|
detectLaunchMethod
|
|
42
42
|
} from "./chunk-QSY74NAP.js";
|
|
@@ -712,4 +712,4 @@ export {
|
|
|
712
712
|
runStatusline,
|
|
713
713
|
runAction
|
|
714
714
|
};
|
|
715
|
-
//# sourceMappingURL=chunk-
|
|
715
|
+
//# sourceMappingURL=chunk-66TGBYSL.js.map
|
|
@@ -12,11 +12,11 @@ var ADAPTER_REGISTRY = [
|
|
|
12
12
|
},
|
|
13
13
|
{
|
|
14
14
|
id: "claude-code",
|
|
15
|
-
load: () => import("./claude-code-
|
|
15
|
+
load: () => import("./claude-code-JRKJARPH.js").then((m) => m.default)
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
id: "codex",
|
|
19
|
-
load: () => import("./codex-
|
|
19
|
+
load: () => import("./codex-X3WZZOJ4.js").then((m) => m.default)
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
id: "cursor",
|
|
@@ -94,7 +94,7 @@ var ADAPTER_REGISTRY = [
|
|
|
94
94
|
// constraint here; it simply sits beside it.
|
|
95
95
|
{
|
|
96
96
|
id: "cline",
|
|
97
|
-
load: () => import("./cline-
|
|
97
|
+
load: () => import("./cline-XAFNCZFQ.js").then((m) => m.default)
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
id: "trae",
|
|
@@ -260,7 +260,7 @@ var ADAPTER_REGISTRY = [
|
|
|
260
260
|
id: "devin",
|
|
261
261
|
load: () => import("./devin-VD6VCB4Y.js").then((m) => m.default)
|
|
262
262
|
},
|
|
263
|
-
// Open Interpreter (the new Rust `interpreter` / `i` CLI) —
|
|
263
|
+
// Open Interpreter (the new Rust `interpreter` / `i` CLI) — json-stdio. It is a
|
|
264
264
|
// FORK of OpenAI's Codex (README: "Open Interpreter is a fork of OpenAI's
|
|
265
265
|
// Codex"), so its native config is Codex's: a TOML `config.toml` carrying
|
|
266
266
|
// `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/
|
|
@@ -269,12 +269,12 @@ var ADAPTER_REGISTRY = [
|
|
|
269
269
|
// `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter
|
|
270
270
|
// (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO
|
|
271
271
|
// fork-ordering constraint vs codex — the two never target the same file — so
|
|
272
|
-
// it simply sits at the end of the registry.
|
|
273
|
-
//
|
|
274
|
-
//
|
|
272
|
+
// it simply sits at the end of the registry. The adapter EXTENDS the codex
|
|
273
|
+
// adapter: hooks (Claude-shaped hooks.json under the OI home, SessionEnd too),
|
|
274
|
+
// skills and AGENTS.md memory were verified 2026-09-07 by source + a live run.
|
|
275
275
|
{
|
|
276
276
|
id: "open-interpreter",
|
|
277
|
-
load: () => import("./open-interpreter-
|
|
277
|
+
load: () => import("./open-interpreter-ZHBMASXY.js").then((m) => m.default)
|
|
278
278
|
},
|
|
279
279
|
// Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from
|
|
280
280
|
// jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.
|
|
@@ -322,4 +322,4 @@ export {
|
|
|
322
322
|
loadAdapter,
|
|
323
323
|
allAdapters
|
|
324
324
|
};
|
|
325
|
-
//# sourceMappingURL=chunk-
|
|
325
|
+
//# sourceMappingURL=chunk-7C3COFOD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/registry.ts"],"sourcesContent":["/**\n * adapters/registry — single source of truth for the platforms agent-connector\n * targets. Generalized from context-mode's `ADAPTER_REGISTRY` pattern, adapted\n * to our `Adapter` / `AdapterFactory` contract (adapters/spi.ts).\n *\n * In context-mode the same platform set was redeclared in four places (env-var\n * detection, session-dir lookup, the lazy adapter loader, and per-adapter base\n * constructors); adding a platform meant editing all of them and missing one\n * was silent. Here the list lives ONCE below: each platform is one entry with a\n * lazy `load()` thunk that resolves the adapter singleton. Adding a platform is\n * a single new entry — `getFactory` / `loadAdapter` / `allAdapters` and the\n * detection cascade in detect.ts all derive from this list.\n *\n * `load()` returns the module's default export, which every adapter file is\n * required to provide as its singleton (`export default adapter;`). It is a\n * function (not an eager import) so module loading stays lazy: an adapter is\n * only imported when it is actually needed, keeping startup cheap.\n *\n * Order is load-bearing for runtime host detection (detect.ts iterates env\n * markers in registry order): forks MUST precede their parent so a session\n * running inside a derived shell is not misclassified as the parent. For the\n * three Phase-1 adapters this is moot, but the ordering convention is fixed now\n * so later additions (cursor is a VS Code fork, etc.) slot in correctly.\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { Adapter, AdapterFactory } from \"./spi.js\";\n\n/**\n * Authoritative list of installable platforms. One entry per platform; the\n * `load` thunk lazily imports the adapter module and returns its default-export\n * singleton. To add a platform: drop its `src/adapters/<id>/index.ts` in place\n * (default-exporting an `Adapter`) and add one entry here.\n */\nexport const ADAPTER_REGISTRY: readonly AdapterFactory[] = [\n // codebuddy (Tencent CodeBuddy) is a Claude Code fork that ALSO exports\n // CLAUDE_SESSION_ID at runtime (its bundle sets both CODEBUDDY_SESSION_ID and\n // CLAUDE_SESSION_ID), so it must precede claude-code: the fork's exclusive\n // runtime markers are checked first during host detection (fork-before-parent).\n {\n id: \"codebuddy\",\n load: () => import(\"./codebuddy/index.js\").then((m) => m.default),\n },\n {\n id: \"claude-code\",\n load: () => import(\"./claude-code/index.js\").then((m) => m.default),\n },\n {\n id: \"codex\",\n load: () => import(\"./codex/index.js\").then((m) => m.default),\n },\n {\n id: \"cursor\",\n load: () => import(\"./cursor/index.js\").then((m) => m.default),\n },\n // vscode-copilot after cursor: cursor is a VS Code fork, so the fork's runtime\n // markers must be checked first during host detection.\n {\n id: \"vscode-copilot\",\n load: () => import(\"./vscode-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"copilot-cli\",\n load: () => import(\"./copilot-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"gemini-cli\",\n load: () => import(\"./gemini-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"warp\",\n load: () => import(\"./warp/index.js\").then((m) => m.default),\n },\n // ts-plugin paradigm: OpenCode loads a generated plugin module that bridges\n // its in-process events to the universal hook entrypoint.\n {\n id: \"opencode\",\n load: () => import(\"./opencode/index.js\").then((m) => m.default),\n },\n // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK\n // (ts-plugin, MCP root key \"mcp\", ~/.config/mimocode/mimocode.json). Grouped\n // beside the OpenCode family whose config dialect + plugin contract it shares;\n // detected via the DISTINCT ~/.config/mimocode dir, so there is no fork-ordering\n // constraint vs opencode (no shared config file to disambiguate).\n {\n id: \"mimo-code\",\n load: () => import(\"./mimo-code/index.js\").then((m) => m.default),\n },\n // kilo-cli is the SQLite-backed OpenCode FORK command-line product (ts-plugin,\n // loads @kilocode/plugin modules registered in kilo.jsonc's \"plugin\" array;\n // MCP root key \"mcp\", ~/.config/kilo/kilo.jsonc). Grouped beside the OpenCode\n // family whose plugin contract + config dialect it shares; distinct host from\n // the \"kilo\" extension so there is no fork-ordering constraint between them.\n {\n id: \"kilo-cli\",\n load: () => import(\"./kilo-cli/index.js\").then((m) => m.default),\n },\n // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).\n {\n id: \"droid\",\n load: () => import(\"./droid/index.js\").then((m) => m.default),\n },\n // openhands is the All-Hands-AI OpenHands CLI (`openhands`, ex-OpenDevin) —\n // a standalone json-stdio host: MCP at ~/.openhands/mcp.json (\"mcpServers\",\n // FastMCP entry shape) + a SEPARATE .openhands/hooks.json carrying the\n // Claude-Code-plugin-compatible nested-rule hooks (6 events). Its persistence\n // dir (~/.openhands) is distinct, so there is no fork-ordering constraint.\n {\n id: \"openhands\",\n load: () => import(\"./openhands/index.js\").then((m) => m.default),\n },\n // kilo is the Kilo Code VS Code extension (kilocode.kilo-code) — a Cline\n // fork, so it sits beside cline (mcp-only, root key \"mcpServers\", VS Code\n // globalStorage / .kilocode project scope). Distinct host from \"kilo-cli\".\n {\n id: \"kilo\",\n load: () => import(\"./kilo/index.js\").then((m) => m.default),\n },\n // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-\n // installed AI coding extension and the PARENT that kilo forked.\n // mcp-only (no hook layer); MCP at the globalStorage cline_mcp_settings.json\n // (\"mcpServers\"); content lives in the .clinerules tree + ~/Documents/Cline.\n // NO runtime-marker collision with kilo (kilocode.kilo-code / .kilo) —\n // distinct ext ids + dotdirs — so there is NO fork-before-parent ordering\n // constraint here; it simply sits beside it.\n {\n id: \"cline\",\n load: () => import(\"./cline/index.js\").then((m) => m.default),\n },\n {\n id: \"trae\",\n load: () => import(\"./trae/index.js\").then((m) => m.default),\n },\n // antigravity-cli BEFORE antigravity: the `agy` CLI is a fork of the IDE\n // adapter with its own runtime markers (the universal hook command tags the\n // host as \"antigravity-cli\"), so the more-specific CLI marker must be checked\n // before the IDE/parent during host detection.\n {\n id: \"antigravity-cli\",\n load: () => import(\"./antigravity-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"antigravity\",\n load: () => import(\"./antigravity/index.js\").then((m) => m.default),\n },\n {\n id: \"zed\",\n load: () => import(\"./zed/index.js\").then((m) => m.default),\n },\n {\n id: \"amp\",\n load: () => import(\"./amp/index.js\").then((m) => m.default),\n },\n {\n id: \"codebuff\",\n load: () => import(\"./codebuff/index.js\").then((m) => m.default),\n },\n {\n id: \"mux\",\n load: () => import(\"./mux/index.js\").then((m) => m.default),\n },\n // Pi — mcp-only host with no writable MCP config; drives the Agent Skills\n // surface only (writes <piDir>/skills/<name>/SKILL.md).\n {\n id: \"pi\",\n load: () => import(\"./pi/index.js\").then((m) => m.default),\n },\n // Wave 2 — json-stdio adapters (full hook dispatch via the universal entrypoint).\n // jetbrains-copilot before vscode-copilot is unnecessary (distinct hosts); grouped here.\n {\n id: \"jetbrains-copilot\",\n load: () => import(\"./jetbrains-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"qwen-code\",\n load: () => import(\"./qwen-code/index.js\").then((m) => m.default),\n },\n {\n id: \"kiro\",\n load: () => import(\"./kiro/index.js\").then((m) => m.default),\n },\n {\n id: \"kimi\",\n load: () => import(\"./kimi/index.js\").then((m) => m.default),\n },\n {\n id: \"crush\",\n load: () => import(\"./crush/index.js\").then((m) => m.default),\n },\n // Wave 3 — json-stdio adapters with YAML config (MCP in YAML; hooks per host).\n {\n id: \"goose\",\n load: () => import(\"./goose/index.js\").then((m) => m.default),\n },\n {\n id: \"hermes\",\n load: () => import(\"./hermes/index.js\").then((m) => m.default),\n },\n // Wave 4 — ts-plugin adapters (generate a bridge module to the universal entrypoint).\n {\n id: \"omp\",\n load: () => import(\"./omp/index.js\").then((m) => m.default),\n },\n // nemoclaw BEFORE openclaw (fork-before-parent convention). NVIDIA NemoClaw\n // wraps OpenClaw and DRIVES the SAME ~/.openclaw/openclaw.json, so a NemoClaw\n // box carries BOTH the ~/.nemoclaw/ and ~/.openclaw/ markers. Exclusivity is\n // enforced at the SOURCE: OpenClawAdapter.detectInstalled BOWS OUT when\n // ~/.nemoclaw/ is present, so the shared config is never double-targeted as two\n // platforms. This ordering is the deterministic tie-break (matching the\n // antigravity-cli/antigravity precedent). nemoclaw extends OpenClawAdapter\n // (id/name/detection overridden), so inherited server/hook registration still\n // lands in the wrapped openclaw.json.\n {\n id: \"nemoclaw\",\n load: () => import(\"./nemoclaw/index.js\").then((m) => m.default),\n },\n {\n id: \"openclaw\",\n load: () => import(\"./openclaw/index.js\").then((m) => m.default),\n },\n // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/\n // (user) and .amazonq/ (project); root key \"mcpServers\"; bare stdio entry\n // { command, args, env, timeout? } or remote entry { type: \"http\", url } (no\n // headers) for http. The agent-format hooks layer (cli-agents/*.json) +\n // agents/prompts content surfaces are separate, not-yet-wired surfaces; this\n // adapter installs MCP entries + the .amazonq/rules memory surface.\n {\n id: \"amazon-q\",\n load: () => import(\"./amazon-q/index.js\").then((m) => m.default),\n },\n // Continue (the `cn` terminal agent / Continue.dev, npm @continuedev/cli) —\n // json-stdio (Claude-compatible hooks). MCP config is YAML at ~/.continue/config.yaml (user) and\n // <projectDir>/.continue/config.yaml (project); root key \"mcpServers\" is a\n // YAML ARRAY of { name, command, type?, args?, env?, cwd?, url } entries (NOT a\n // keyed map). Hooks: a Claude-compatible json-stdio layer in settings.json\n // (~/.continue/settings.json — separate from the MCP config.yaml; PR #11029) +\n // nativeHooks for the host-specific events. Distinct ~/.continue marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"continue\",\n load: () => import(\"./continue/index.js\").then((m) => m.default),\n },\n // Windsurf (Codeium / Cognition's Cascade agent) — mcp-only. USER/GLOBAL scope\n // ONLY: MCP config is JSON at ~/.codeium/windsurf/mcp_config.json (the docs\n // document no project/workspace path), root key \"mcpServers\" is a Claude-\n // Desktop-style OBJECT map keyed by server name (like cursor). stdio entry\n // { command, args?, env? }; remote entry { serverUrl, headers? } (NOT `url`;\n // no type/disabled). No user-installable hook/plugin layer (GUI editor), so it\n // stays mcp-only paradigm — but content surfaces ARE wired: workflows\n // (.windsurf/workflows + ~/.codeium/windsurf/global_workflows), skills\n // (.windsurf/skills + ~/.codeium/windsurf/skills), and the .windsurf/rules\n // memory surface. Distinct ~/.codeium marker — no fork-ordering constraint.\n {\n id: \"windsurf\",\n load: () => import(\"./windsurf/index.js\").then((m) => m.default),\n },\n // Grok Build (xAI's OFFICIAL coding agent, xai-org/grok-build, Apache-2.0,\n // bin `grok`) — json-stdio. MCP lives in $GROK_HOME/config.toml (default\n // ~/.grok) under [mcp_servers.<id>]; hooks in $GROK_HOME/hooks/*.json\n // (Claude-compatible JSON). Placed immediately BEFORE grok-cli because the two\n // are UNRELATED products that share the default ~/.grok directory: keeping\n // them adjacent keeps the disambiguation readable. There is no fork-ordering\n // constraint (neither exports runtime env markers we detect on); the shared\n // dir is handled by per-adapter marker-file detection with a sibling bow-out,\n // not by registry order.\n {\n id: \"grok-build\",\n load: () => import(\"./grok-build/index.js\").then((m) => m.default),\n },\n // Grok CLI (the community superagent-ai/grok-cli, npm `grok-dev`, bin `grok`,\n // MIT) — json-stdio. Id is `grok-cli` (NOT `grok`) to stay distinct from xAI's\n // separate \"Grok Build\" product above. USER-SCOPE ONLY: both MCP servers\n // (nested `mcp.servers` JSON ARRAY, keyed by `id`) and hooks (top-level\n // `hooks`, Claude nested-rule shape) live in ~/.grok/user-settings.json\n // (project .grok/settings.json holds neither — Grok excludes project hooks for\n // security). Shares the ~/.grok DIRECTORY with grok-build but never a FILE.\n {\n id: \"grok-cli\",\n load: () => import(\"./grok-cli/index.js\").then((m) => m.default),\n },\n // Devin CLI (Cognition) — json-stdio. A Rust binary (`devin`, installed via\n // `curl cli.devin.ai/install.sh` → ~/.local/bin/devin). MCP + hooks live in\n // ONE config.json per scope: user ~/.config/devin/config.json\n // (%APPDATA%\\devin\\config.json on Windows) / project <projectDir>/.devin/\n // config.json. MCP root key \"mcpServers\" (object map; stdio { command, args?,\n // env? }, remote { url, transport?, headers? }; native ${env:VAR}). Hooks\n // under the same file's \"hooks\" key (Claude-compatible NESTED-rule shape; reply\n // is the SIMPLE top-level {decision:\"approve\"|\"block\"|\"deny\", reason}). Distinct\n // ~/.config/devin / .devin marker — no fork-ordering constraint.\n {\n id: \"devin\",\n load: () => import(\"./devin/index.js\").then((m) => m.default),\n },\n // Open Interpreter (the new Rust `interpreter` / `i` CLI) — mcp-only. It is a\n // FORK of OpenAI's Codex (README: \"Open Interpreter is a fork of OpenAI's\n // Codex\"), so its native config is Codex's: a TOML `config.toml` carrying\n // `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/\n // http_headers streamable-HTTP). The config home is DELIBERATELY isolated from\n // Codex — the `interpreter` binary honors ONLY `$INTERPRETER_HOME` (NOT\n // `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter\n // (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO\n // fork-ordering constraint vs codex — the two never target the same file — so\n // it simply sits at the end of the registry. Kept mcp-only (the codex hook\n // subsystem is present in the fork, but the `interpreter` product's live hook\n // wire contract is not first-party-verified, so hooks are not claimed).\n {\n id: \"open-interpreter\",\n load: () => import(\"./open-interpreter/index.js\").then((m) => m.default),\n },\n // Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from\n // jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.\n // The `junie` CLI (npm @jetbrains/junie, github.com/JetBrains/junie) shares its\n // MCP JSON config with Junie in JetBrains IDEs: object map \"mcpServers\" at\n // <projectDir>/.junie/mcp/mcp.json (project) and ~/.junie/mcp/mcp.json (user);\n // stdio { command, args?, env? }, remote { url, headers? }. No documented\n // user-installable hook surface → mcp-only. Distinct ~/.junie marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"junie\",\n load: () => import(\"./junie/index.js\").then((m) => m.default),\n },\n // mistral-vibe is Mistral's coding-agent CLI — an mcp-only host. MCP config is\n // TOML at <projectDir>/.vibe/config.toml (project, precedence) → ~/.vibe/\n // config.toml (user); root key `mcp_servers` is a TOML ARRAY-OF-TABLES\n // ([[mcp_servers]], each entry carries a `name` short alias — distinct from\n // codex's table-keyed [mcp_servers.<name>]). Distinct ~/.vibe / .vibe marker —\n // no fork-ordering constraint.\n {\n id: \"mistral-vibe\",\n load: () => import(\"./mistral-vibe/index.js\").then((m) => m.default),\n },\n];\n\n/** O(1) lookup index, built once at module-load time. */\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, AdapterFactory> = new Map(\n ADAPTER_REGISTRY.map((factory) => [factory.id, factory] as const),\n);\n\n/** Every platform id present in the registry (useful for matrix tests). */\nexport const REGISTERED_PLATFORM_IDS: ReadonlySet<PlatformId> = new Set(\n ADAPTER_REGISTRY.map((factory) => factory.id),\n);\n\n/**\n * Look up the lazy factory for a platform id. Returns `undefined` for ids that\n * are not registered (including `\"unknown\"` and typos) so callers can fall back\n * deliberately rather than crash.\n */\nexport function getFactory(id: PlatformId | string): AdapterFactory | undefined {\n return REGISTRY_BY_ID.get(id as PlatformId);\n}\n\n/**\n * Resolve a platform id to its adapter singleton. Returns `undefined` when the\n * id is not registered — callers decide whether to skip or fall back.\n */\nexport async function loadAdapter(id: PlatformId | string): Promise<Adapter | undefined> {\n const factory = getFactory(id);\n return factory ? factory.load() : undefined;\n}\n\n/**\n * Load every registered adapter. Imports run in parallel; the result preserves\n * registry order so downstream detection/install logic sees forks before\n * parents.\n */\nexport async function allAdapters(): Promise<Adapter[]> {\n return Promise.all(ADAPTER_REGISTRY.map((factory) => factory.load()));\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/registry.ts"],"sourcesContent":["/**\n * adapters/registry — single source of truth for the platforms agent-connector\n * targets. Generalized from context-mode's `ADAPTER_REGISTRY` pattern, adapted\n * to our `Adapter` / `AdapterFactory` contract (adapters/spi.ts).\n *\n * In context-mode the same platform set was redeclared in four places (env-var\n * detection, session-dir lookup, the lazy adapter loader, and per-adapter base\n * constructors); adding a platform meant editing all of them and missing one\n * was silent. Here the list lives ONCE below: each platform is one entry with a\n * lazy `load()` thunk that resolves the adapter singleton. Adding a platform is\n * a single new entry — `getFactory` / `loadAdapter` / `allAdapters` and the\n * detection cascade in detect.ts all derive from this list.\n *\n * `load()` returns the module's default export, which every adapter file is\n * required to provide as its singleton (`export default adapter;`). It is a\n * function (not an eager import) so module loading stays lazy: an adapter is\n * only imported when it is actually needed, keeping startup cheap.\n *\n * Order is load-bearing for runtime host detection (detect.ts iterates env\n * markers in registry order): forks MUST precede their parent so a session\n * running inside a derived shell is not misclassified as the parent. For the\n * three Phase-1 adapters this is moot, but the ordering convention is fixed now\n * so later additions (cursor is a VS Code fork, etc.) slot in correctly.\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { Adapter, AdapterFactory } from \"./spi.js\";\n\n/**\n * Authoritative list of installable platforms. One entry per platform; the\n * `load` thunk lazily imports the adapter module and returns its default-export\n * singleton. To add a platform: drop its `src/adapters/<id>/index.ts` in place\n * (default-exporting an `Adapter`) and add one entry here.\n */\nexport const ADAPTER_REGISTRY: readonly AdapterFactory[] = [\n // codebuddy (Tencent CodeBuddy) is a Claude Code fork that ALSO exports\n // CLAUDE_SESSION_ID at runtime (its bundle sets both CODEBUDDY_SESSION_ID and\n // CLAUDE_SESSION_ID), so it must precede claude-code: the fork's exclusive\n // runtime markers are checked first during host detection (fork-before-parent).\n {\n id: \"codebuddy\",\n load: () => import(\"./codebuddy/index.js\").then((m) => m.default),\n },\n {\n id: \"claude-code\",\n load: () => import(\"./claude-code/index.js\").then((m) => m.default),\n },\n {\n id: \"codex\",\n load: () => import(\"./codex/index.js\").then((m) => m.default),\n },\n {\n id: \"cursor\",\n load: () => import(\"./cursor/index.js\").then((m) => m.default),\n },\n // vscode-copilot after cursor: cursor is a VS Code fork, so the fork's runtime\n // markers must be checked first during host detection.\n {\n id: \"vscode-copilot\",\n load: () => import(\"./vscode-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"copilot-cli\",\n load: () => import(\"./copilot-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"gemini-cli\",\n load: () => import(\"./gemini-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"warp\",\n load: () => import(\"./warp/index.js\").then((m) => m.default),\n },\n // ts-plugin paradigm: OpenCode loads a generated plugin module that bridges\n // its in-process events to the universal hook entrypoint.\n {\n id: \"opencode\",\n load: () => import(\"./opencode/index.js\").then((m) => m.default),\n },\n // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK\n // (ts-plugin, MCP root key \"mcp\", ~/.config/mimocode/mimocode.json). Grouped\n // beside the OpenCode family whose config dialect + plugin contract it shares;\n // detected via the DISTINCT ~/.config/mimocode dir, so there is no fork-ordering\n // constraint vs opencode (no shared config file to disambiguate).\n {\n id: \"mimo-code\",\n load: () => import(\"./mimo-code/index.js\").then((m) => m.default),\n },\n // kilo-cli is the SQLite-backed OpenCode FORK command-line product (ts-plugin,\n // loads @kilocode/plugin modules registered in kilo.jsonc's \"plugin\" array;\n // MCP root key \"mcp\", ~/.config/kilo/kilo.jsonc). Grouped beside the OpenCode\n // family whose plugin contract + config dialect it shares; distinct host from\n // the \"kilo\" extension so there is no fork-ordering constraint between them.\n {\n id: \"kilo-cli\",\n load: () => import(\"./kilo-cli/index.js\").then((m) => m.default),\n },\n // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).\n {\n id: \"droid\",\n load: () => import(\"./droid/index.js\").then((m) => m.default),\n },\n // openhands is the All-Hands-AI OpenHands CLI (`openhands`, ex-OpenDevin) —\n // a standalone json-stdio host: MCP at ~/.openhands/mcp.json (\"mcpServers\",\n // FastMCP entry shape) + a SEPARATE .openhands/hooks.json carrying the\n // Claude-Code-plugin-compatible nested-rule hooks (6 events). Its persistence\n // dir (~/.openhands) is distinct, so there is no fork-ordering constraint.\n {\n id: \"openhands\",\n load: () => import(\"./openhands/index.js\").then((m) => m.default),\n },\n // kilo is the Kilo Code VS Code extension (kilocode.kilo-code) — a Cline\n // fork, so it sits beside cline (mcp-only, root key \"mcpServers\", VS Code\n // globalStorage / .kilocode project scope). Distinct host from \"kilo-cli\".\n {\n id: \"kilo\",\n load: () => import(\"./kilo/index.js\").then((m) => m.default),\n },\n // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-\n // installed AI coding extension and the PARENT that kilo forked.\n // mcp-only (no hook layer); MCP at the globalStorage cline_mcp_settings.json\n // (\"mcpServers\"); content lives in the .clinerules tree + ~/Documents/Cline.\n // NO runtime-marker collision with kilo (kilocode.kilo-code / .kilo) —\n // distinct ext ids + dotdirs — so there is NO fork-before-parent ordering\n // constraint here; it simply sits beside it.\n {\n id: \"cline\",\n load: () => import(\"./cline/index.js\").then((m) => m.default),\n },\n {\n id: \"trae\",\n load: () => import(\"./trae/index.js\").then((m) => m.default),\n },\n // antigravity-cli BEFORE antigravity: the `agy` CLI is a fork of the IDE\n // adapter with its own runtime markers (the universal hook command tags the\n // host as \"antigravity-cli\"), so the more-specific CLI marker must be checked\n // before the IDE/parent during host detection.\n {\n id: \"antigravity-cli\",\n load: () => import(\"./antigravity-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"antigravity\",\n load: () => import(\"./antigravity/index.js\").then((m) => m.default),\n },\n {\n id: \"zed\",\n load: () => import(\"./zed/index.js\").then((m) => m.default),\n },\n {\n id: \"amp\",\n load: () => import(\"./amp/index.js\").then((m) => m.default),\n },\n {\n id: \"codebuff\",\n load: () => import(\"./codebuff/index.js\").then((m) => m.default),\n },\n {\n id: \"mux\",\n load: () => import(\"./mux/index.js\").then((m) => m.default),\n },\n // Pi — mcp-only host with no writable MCP config; drives the Agent Skills\n // surface only (writes <piDir>/skills/<name>/SKILL.md).\n {\n id: \"pi\",\n load: () => import(\"./pi/index.js\").then((m) => m.default),\n },\n // Wave 2 — json-stdio adapters (full hook dispatch via the universal entrypoint).\n // jetbrains-copilot before vscode-copilot is unnecessary (distinct hosts); grouped here.\n {\n id: \"jetbrains-copilot\",\n load: () => import(\"./jetbrains-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"qwen-code\",\n load: () => import(\"./qwen-code/index.js\").then((m) => m.default),\n },\n {\n id: \"kiro\",\n load: () => import(\"./kiro/index.js\").then((m) => m.default),\n },\n {\n id: \"kimi\",\n load: () => import(\"./kimi/index.js\").then((m) => m.default),\n },\n {\n id: \"crush\",\n load: () => import(\"./crush/index.js\").then((m) => m.default),\n },\n // Wave 3 — json-stdio adapters with YAML config (MCP in YAML; hooks per host).\n {\n id: \"goose\",\n load: () => import(\"./goose/index.js\").then((m) => m.default),\n },\n {\n id: \"hermes\",\n load: () => import(\"./hermes/index.js\").then((m) => m.default),\n },\n // Wave 4 — ts-plugin adapters (generate a bridge module to the universal entrypoint).\n {\n id: \"omp\",\n load: () => import(\"./omp/index.js\").then((m) => m.default),\n },\n // nemoclaw BEFORE openclaw (fork-before-parent convention). NVIDIA NemoClaw\n // wraps OpenClaw and DRIVES the SAME ~/.openclaw/openclaw.json, so a NemoClaw\n // box carries BOTH the ~/.nemoclaw/ and ~/.openclaw/ markers. Exclusivity is\n // enforced at the SOURCE: OpenClawAdapter.detectInstalled BOWS OUT when\n // ~/.nemoclaw/ is present, so the shared config is never double-targeted as two\n // platforms. This ordering is the deterministic tie-break (matching the\n // antigravity-cli/antigravity precedent). nemoclaw extends OpenClawAdapter\n // (id/name/detection overridden), so inherited server/hook registration still\n // lands in the wrapped openclaw.json.\n {\n id: \"nemoclaw\",\n load: () => import(\"./nemoclaw/index.js\").then((m) => m.default),\n },\n {\n id: \"openclaw\",\n load: () => import(\"./openclaw/index.js\").then((m) => m.default),\n },\n // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/\n // (user) and .amazonq/ (project); root key \"mcpServers\"; bare stdio entry\n // { command, args, env, timeout? } or remote entry { type: \"http\", url } (no\n // headers) for http. The agent-format hooks layer (cli-agents/*.json) +\n // agents/prompts content surfaces are separate, not-yet-wired surfaces; this\n // adapter installs MCP entries + the .amazonq/rules memory surface.\n {\n id: \"amazon-q\",\n load: () => import(\"./amazon-q/index.js\").then((m) => m.default),\n },\n // Continue (the `cn` terminal agent / Continue.dev, npm @continuedev/cli) —\n // json-stdio (Claude-compatible hooks). MCP config is YAML at ~/.continue/config.yaml (user) and\n // <projectDir>/.continue/config.yaml (project); root key \"mcpServers\" is a\n // YAML ARRAY of { name, command, type?, args?, env?, cwd?, url } entries (NOT a\n // keyed map). Hooks: a Claude-compatible json-stdio layer in settings.json\n // (~/.continue/settings.json — separate from the MCP config.yaml; PR #11029) +\n // nativeHooks for the host-specific events. Distinct ~/.continue marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"continue\",\n load: () => import(\"./continue/index.js\").then((m) => m.default),\n },\n // Windsurf (Codeium / Cognition's Cascade agent) — mcp-only. USER/GLOBAL scope\n // ONLY: MCP config is JSON at ~/.codeium/windsurf/mcp_config.json (the docs\n // document no project/workspace path), root key \"mcpServers\" is a Claude-\n // Desktop-style OBJECT map keyed by server name (like cursor). stdio entry\n // { command, args?, env? }; remote entry { serverUrl, headers? } (NOT `url`;\n // no type/disabled). No user-installable hook/plugin layer (GUI editor), so it\n // stays mcp-only paradigm — but content surfaces ARE wired: workflows\n // (.windsurf/workflows + ~/.codeium/windsurf/global_workflows), skills\n // (.windsurf/skills + ~/.codeium/windsurf/skills), and the .windsurf/rules\n // memory surface. Distinct ~/.codeium marker — no fork-ordering constraint.\n {\n id: \"windsurf\",\n load: () => import(\"./windsurf/index.js\").then((m) => m.default),\n },\n // Grok Build (xAI's OFFICIAL coding agent, xai-org/grok-build, Apache-2.0,\n // bin `grok`) — json-stdio. MCP lives in $GROK_HOME/config.toml (default\n // ~/.grok) under [mcp_servers.<id>]; hooks in $GROK_HOME/hooks/*.json\n // (Claude-compatible JSON). Placed immediately BEFORE grok-cli because the two\n // are UNRELATED products that share the default ~/.grok directory: keeping\n // them adjacent keeps the disambiguation readable. There is no fork-ordering\n // constraint (neither exports runtime env markers we detect on); the shared\n // dir is handled by per-adapter marker-file detection with a sibling bow-out,\n // not by registry order.\n {\n id: \"grok-build\",\n load: () => import(\"./grok-build/index.js\").then((m) => m.default),\n },\n // Grok CLI (the community superagent-ai/grok-cli, npm `grok-dev`, bin `grok`,\n // MIT) — json-stdio. Id is `grok-cli` (NOT `grok`) to stay distinct from xAI's\n // separate \"Grok Build\" product above. USER-SCOPE ONLY: both MCP servers\n // (nested `mcp.servers` JSON ARRAY, keyed by `id`) and hooks (top-level\n // `hooks`, Claude nested-rule shape) live in ~/.grok/user-settings.json\n // (project .grok/settings.json holds neither — Grok excludes project hooks for\n // security). Shares the ~/.grok DIRECTORY with grok-build but never a FILE.\n {\n id: \"grok-cli\",\n load: () => import(\"./grok-cli/index.js\").then((m) => m.default),\n },\n // Devin CLI (Cognition) — json-stdio. A Rust binary (`devin`, installed via\n // `curl cli.devin.ai/install.sh` → ~/.local/bin/devin). MCP + hooks live in\n // ONE config.json per scope: user ~/.config/devin/config.json\n // (%APPDATA%\\devin\\config.json on Windows) / project <projectDir>/.devin/\n // config.json. MCP root key \"mcpServers\" (object map; stdio { command, args?,\n // env? }, remote { url, transport?, headers? }; native ${env:VAR}). Hooks\n // under the same file's \"hooks\" key (Claude-compatible NESTED-rule shape; reply\n // is the SIMPLE top-level {decision:\"approve\"|\"block\"|\"deny\", reason}). Distinct\n // ~/.config/devin / .devin marker — no fork-ordering constraint.\n {\n id: \"devin\",\n load: () => import(\"./devin/index.js\").then((m) => m.default),\n },\n // Open Interpreter (the new Rust `interpreter` / `i` CLI) — json-stdio. It is a\n // FORK of OpenAI's Codex (README: \"Open Interpreter is a fork of OpenAI's\n // Codex\"), so its native config is Codex's: a TOML `config.toml` carrying\n // `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/\n // http_headers streamable-HTTP). The config home is DELIBERATELY isolated from\n // Codex — the `interpreter` binary honors ONLY `$INTERPRETER_HOME` (NOT\n // `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter\n // (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO\n // fork-ordering constraint vs codex — the two never target the same file — so\n // it simply sits at the end of the registry. The adapter EXTENDS the codex\n // adapter: hooks (Claude-shaped hooks.json under the OI home, SessionEnd too),\n // skills and AGENTS.md memory were verified 2026-09-07 by source + a live run.\n {\n id: \"open-interpreter\",\n load: () => import(\"./open-interpreter/index.js\").then((m) => m.default),\n },\n // Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from\n // jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.\n // The `junie` CLI (npm @jetbrains/junie, github.com/JetBrains/junie) shares its\n // MCP JSON config with Junie in JetBrains IDEs: object map \"mcpServers\" at\n // <projectDir>/.junie/mcp/mcp.json (project) and ~/.junie/mcp/mcp.json (user);\n // stdio { command, args?, env? }, remote { url, headers? }. No documented\n // user-installable hook surface → mcp-only. Distinct ~/.junie marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"junie\",\n load: () => import(\"./junie/index.js\").then((m) => m.default),\n },\n // mistral-vibe is Mistral's coding-agent CLI — an mcp-only host. MCP config is\n // TOML at <projectDir>/.vibe/config.toml (project, precedence) → ~/.vibe/\n // config.toml (user); root key `mcp_servers` is a TOML ARRAY-OF-TABLES\n // ([[mcp_servers]], each entry carries a `name` short alias — distinct from\n // codex's table-keyed [mcp_servers.<name>]). Distinct ~/.vibe / .vibe marker —\n // no fork-ordering constraint.\n {\n id: \"mistral-vibe\",\n load: () => import(\"./mistral-vibe/index.js\").then((m) => m.default),\n },\n];\n\n/** O(1) lookup index, built once at module-load time. */\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, AdapterFactory> = new Map(\n ADAPTER_REGISTRY.map((factory) => [factory.id, factory] as const),\n);\n\n/** Every platform id present in the registry (useful for matrix tests). */\nexport const REGISTERED_PLATFORM_IDS: ReadonlySet<PlatformId> = new Set(\n ADAPTER_REGISTRY.map((factory) => factory.id),\n);\n\n/**\n * Look up the lazy factory for a platform id. Returns `undefined` for ids that\n * are not registered (including `\"unknown\"` and typos) so callers can fall back\n * deliberately rather than crash.\n */\nexport function getFactory(id: PlatformId | string): AdapterFactory | undefined {\n return REGISTRY_BY_ID.get(id as PlatformId);\n}\n\n/**\n * Resolve a platform id to its adapter singleton. Returns `undefined` when the\n * id is not registered — callers decide whether to skip or fall back.\n */\nexport async function loadAdapter(id: PlatformId | string): Promise<Adapter | undefined> {\n const factory = getFactory(id);\n return factory ? factory.load() : undefined;\n}\n\n/**\n * Load every registered adapter. Imports run in parallel; the result preserves\n * registry order so downstream detection/install logic sees forks before\n * parents.\n */\nexport async function allAdapters(): Promise<Adapter[]> {\n return Promise.all(ADAPTER_REGISTRY.map((factory) => factory.load()));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import {
|
|
3
3
|
compileMatcher,
|
|
4
4
|
eventMatcherSubject
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KQBRUI3Y.js";
|
|
6
6
|
import {
|
|
7
7
|
SURFACE_PREDICATES,
|
|
8
8
|
hostCanFireEvent
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-V7GZ3AMV.js";
|
|
10
10
|
import {
|
|
11
11
|
applyStatuslineOutputLimits,
|
|
12
12
|
statuslineOptionsForHost
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import {
|
|
15
15
|
allAdapters,
|
|
16
16
|
loadAdapter
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-7C3COFOD.js";
|
|
18
18
|
|
|
19
19
|
// src/sdk/test-harness.ts
|
|
20
20
|
function declaredGlobalSurfaces(connector) {
|
|
@@ -399,4 +399,4 @@ export {
|
|
|
399
399
|
simulate,
|
|
400
400
|
explainHooks
|
|
401
401
|
};
|
|
402
|
-
//# sourceMappingURL=chunk-
|
|
402
|
+
//# sourceMappingURL=chunk-BAJL27XI.js.map
|
|
@@ -22,7 +22,6 @@ import {
|
|
|
22
22
|
buildHomeBinHookCommand,
|
|
23
23
|
buildWrappedStdio
|
|
24
24
|
} from "./chunk-QSY74NAP.js";
|
|
25
|
-
import "./chunk-UMQ6NBQR.js";
|
|
26
25
|
import {
|
|
27
26
|
ensureDir
|
|
28
27
|
} from "./chunk-GZGLCCEE.js";
|
|
@@ -249,6 +248,18 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
249
248
|
];
|
|
250
249
|
}
|
|
251
250
|
// ── Install hooks (hooks.json) ──────────────────────────────────────────
|
|
251
|
+
/**
|
|
252
|
+
* Host-native hook events this adapter registers. A Codex FORK that fires a
|
|
253
|
+
* superset (open-interpreter also fires SessionEnd) overrides this once; the
|
|
254
|
+
* install, descriptor and remove paths all read it.
|
|
255
|
+
*/
|
|
256
|
+
get hookEventNames() {
|
|
257
|
+
return CODEX_HOOK_EVENTS;
|
|
258
|
+
}
|
|
259
|
+
/** Host label used in unsupported-event warn details ("<event> has no Codex hook equivalent"). */
|
|
260
|
+
get hookHostLabel() {
|
|
261
|
+
return "Codex";
|
|
262
|
+
}
|
|
252
263
|
installHooks(ctx) {
|
|
253
264
|
const path = this.getHookConfigPath(ctx);
|
|
254
265
|
const hooksOff = ctx.connector.platforms[this.id]?.hooks === false;
|
|
@@ -256,7 +267,7 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
256
267
|
if (declared.length === 0) {
|
|
257
268
|
return [{ platform: this.id, action: "skip", path, detail: "no hooks declared" }];
|
|
258
269
|
}
|
|
259
|
-
const supported = (e) =>
|
|
270
|
+
const supported = (e) => this.hookEventNames.includes(e);
|
|
260
271
|
const pending = [
|
|
261
272
|
...declared.filter((e) => !supported(e)).map((event) => ({ event, matcher: "" })),
|
|
262
273
|
...declared.filter(supported).map((event) => ({ event, matcher: "" }))
|
|
@@ -280,8 +291,8 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
280
291
|
malformedPolicy: "coerce",
|
|
281
292
|
// Supported event → identity; any other canonical event → undefined → the
|
|
282
293
|
// engine reports it (never silent), at the severity unmappedAction picks.
|
|
283
|
-
mapEvent: (e) =>
|
|
284
|
-
unmappedWarnDetail: (e) => `${e} has no
|
|
294
|
+
mapEvent: (e) => this.hookEventNames.includes(e) ? e : void 0,
|
|
295
|
+
unmappedWarnDetail: (e) => `${e} has no ${this.hookHostLabel} hook equivalent \u2014 skipped`,
|
|
285
296
|
// E1 newer events (PostToolUseFailure) keep the established `warn` (exit-1);
|
|
286
297
|
// the legacy SessionEnd / Notification — silently dropped before this fix —
|
|
287
298
|
// become a VISIBLE `skip` so the install exit code is unchanged for them.
|
|
@@ -307,7 +318,7 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
307
318
|
// Uninstall scans EXACTLY codex's fixed event set (not Object.keys), so a
|
|
308
319
|
// home-bin command hand-placed under a foreign event key is left untouched —
|
|
309
320
|
// byte-identical to the prior `for (const event of CODEX_HOOK_EVENTS)` loop.
|
|
310
|
-
removeEventKeys:
|
|
321
|
+
removeEventKeys: this.hookEventNames
|
|
311
322
|
};
|
|
312
323
|
}
|
|
313
324
|
// ── Health checks (default doctor renders these) ────────────────────────
|
|
@@ -750,16 +761,18 @@ var CodexAdapter = class extends BaseAdapter {
|
|
|
750
761
|
*/
|
|
751
762
|
isOurEntry(ctx, event, entry) {
|
|
752
763
|
if (!entry || typeof entry !== "object" || !Array.isArray(entry.hooks)) return false;
|
|
753
|
-
const ours = buildHomeBinHookCommand(ctx.homeBinPath,
|
|
764
|
+
const ours = buildHomeBinHookCommand(ctx.homeBinPath, this.id, event, ctx.connector.id);
|
|
754
765
|
const needle = ours.replace(/\\/g, "/");
|
|
755
766
|
return entry.hooks.some((h) => (h.command ?? "").replace(/\\/g, "/") === needle);
|
|
756
767
|
}
|
|
757
768
|
};
|
|
758
769
|
var adapter = new CodexAdapter();
|
|
759
770
|
var codex_default = adapter;
|
|
771
|
+
|
|
760
772
|
export {
|
|
773
|
+
CODEX_HOOK_EVENTS,
|
|
761
774
|
CodexAdapter,
|
|
762
775
|
adapter,
|
|
763
|
-
codex_default
|
|
776
|
+
codex_default
|
|
764
777
|
};
|
|
765
|
-
//# sourceMappingURL=
|
|
778
|
+
//# sourceMappingURL=chunk-BB4DFAHC.js.map
|