@ken-jo/agent-connector 0.6.4 → 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.
Files changed (90) hide show
  1. package/README.md +18 -12
  2. package/dist/{action-IKJ2J3X4.js → action-DFUJOXVJ.js} +9 -8
  3. package/dist/{action-IKJ2J3X4.js.map → action-DFUJOXVJ.js.map} +1 -1
  4. package/dist/{audit-5K2H7PAT.js → audit-IMNQJZ4W.js} +6 -5
  5. package/dist/{audit-5K2H7PAT.js.map → audit-IMNQJZ4W.js.map} +1 -1
  6. package/dist/{chunk-K67UJSJI.js → chunk-66TGBYSL.js} +5 -5
  7. package/dist/{chunk-QG26JEJF.js → chunk-7C3COFOD.js} +9 -9
  8. package/dist/{chunk-QG26JEJF.js.map → chunk-7C3COFOD.js.map} +1 -1
  9. package/dist/{chunk-HUL5CRF2.js → chunk-BAJL27XI.js} +4 -4
  10. package/dist/{codex-C7ERS3TW.js → chunk-BB4DFAHC.js} +21 -8
  11. package/dist/chunk-BB4DFAHC.js.map +1 -0
  12. package/dist/{chunk-STR3CRH3.js → chunk-C4NDV6GW.js} +2 -2
  13. package/dist/{chunk-LO6NIZSL.js → chunk-CG44RWYJ.js} +5 -5
  14. package/dist/chunk-D35FMUFZ.js +48 -0
  15. package/dist/chunk-D35FMUFZ.js.map +1 -0
  16. package/dist/{chunk-OXANBA4I.js → chunk-ITVST3SZ.js} +2 -2
  17. package/dist/{chunk-W4GVN3TJ.js → chunk-KQBRUI3Y.js} +3 -3
  18. package/dist/{chunk-TCJN5S4T.js → chunk-PTITNBSS.js} +22 -33
  19. package/dist/chunk-PTITNBSS.js.map +1 -0
  20. package/dist/{chunk-O7CFTOM5.js → chunk-S2TAC22E.js} +2 -2
  21. package/dist/{chunk-BD72ZF6D.js → chunk-V7GZ3AMV.js} +2 -2
  22. package/dist/{chunk-BGPVMJOG.js → chunk-ZYB2UFEN.js} +6 -2
  23. package/dist/chunk-ZYB2UFEN.js.map +1 -0
  24. package/dist/{claude-code-EIC4Q7OT.js → claude-code-JRKJARPH.js} +5 -4
  25. package/dist/{claude-code-EIC4Q7OT.js.map → claude-code-JRKJARPH.js.map} +1 -1
  26. package/dist/cli/sdk.js +5 -4
  27. package/dist/cli/sdk.js.map +1 -1
  28. package/dist/cli.js +2 -1
  29. package/dist/cli.js.map +1 -1
  30. package/dist/{cline-AJZ67XEE.js → cline-XAFNCZFQ.js} +26 -5
  31. package/dist/cline-XAFNCZFQ.js.map +1 -0
  32. package/dist/codex-X3WZZOJ4.js +22 -0
  33. package/dist/codex-X3WZZOJ4.js.map +1 -0
  34. package/dist/{define-connector-iosc34CA.d.ts → define-connector-D4UOI__e.d.ts} +1 -1
  35. package/dist/{detect-KYRQJUDY.js → detect-RT75DWQ5.js} +5 -4
  36. package/dist/{detect-KYRQJUDY.js.map → detect-RT75DWQ5.js.map} +1 -1
  37. package/dist/{doctor-BGWPZ676.js → doctor-F3RRQBQN.js} +135 -11
  38. package/dist/doctor-F3RRQBQN.js.map +1 -0
  39. package/dist/{hook-YMCFZRJE.js → hook-VYA4Q3YR.js} +9 -8
  40. package/dist/{hook-YMCFZRJE.js.map → hook-VYA4Q3YR.js.map} +1 -1
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +2 -2
  43. package/dist/{install-RCHVHCHO.js → install-XNTRLUZI.js} +9 -8
  44. package/dist/{install-RCHVHCHO.js.map → install-XNTRLUZI.js.map} +1 -1
  45. package/dist/{introspect-z3eKVWHN.d.ts → introspect-gaKVzg2q.d.ts} +1 -1
  46. package/dist/{leaderboard-V3DXXZNL.js → leaderboard-VF4W6PZ2.js} +3 -2
  47. package/dist/{leaderboard-V3DXXZNL.js.map → leaderboard-VF4W6PZ2.js.map} +1 -1
  48. package/dist/open-interpreter-ZHBMASXY.js +154 -0
  49. package/dist/open-interpreter-ZHBMASXY.js.map +1 -0
  50. package/dist/{package-75T46SXP.js → package-VRV5YHUJ.js} +7 -6
  51. package/dist/{package-75T46SXP.js.map → package-VRV5YHUJ.js.map} +1 -1
  52. package/dist/runtime/index.d.ts +1 -1
  53. package/dist/runtime/index.js +7 -6
  54. package/dist/sdk/index.d.ts +4 -4
  55. package/dist/sdk/index.js +3 -3
  56. package/dist/sdk/test.d.ts +2 -2
  57. package/dist/sdk/test.js +7 -6
  58. package/dist/{serve-IRMYJWFT.js → serve-EPEAGVOE.js} +9 -8
  59. package/dist/{serve-IRMYJWFT.js.map → serve-EPEAGVOE.js.map} +1 -1
  60. package/dist/{status-VJVNMWT7.js → status-3EHFFIQ7.js} +7 -6
  61. package/dist/{status-VJVNMWT7.js.map → status-3EHFFIQ7.js.map} +1 -1
  62. package/dist/{statusline-OKW44KFR.js → statusline-64IDYANK.js} +8 -7
  63. package/dist/{statusline-OKW44KFR.js.map → statusline-64IDYANK.js.map} +1 -1
  64. package/dist/{telemetry-YVMUXTDG.js → telemetry-AEE4TOFA.js} +6 -5
  65. package/dist/{telemetry-YVMUXTDG.js.map → telemetry-AEE4TOFA.js.map} +1 -1
  66. package/dist/{types-CAKApZpX.d.ts → types-htm_wrWo.d.ts} +6 -5
  67. package/dist/{uninstall-WZHO4CVL.js → uninstall-EJLQGZRN.js} +9 -8
  68. package/dist/{uninstall-WZHO4CVL.js.map → uninstall-EJLQGZRN.js.map} +1 -1
  69. package/dist/{upgrade-DZMEUPF2.js → upgrade-ZPHQELKG.js} +9 -8
  70. package/dist/{upgrade-DZMEUPF2.js.map → upgrade-ZPHQELKG.js.map} +1 -1
  71. package/dist/{usage-QSM4PP3E.js → usage-IWPGACHN.js} +3 -2
  72. package/dist/{usage-QSM4PP3E.js.map → usage-IWPGACHN.js.map} +1 -1
  73. package/dist/{usage-event-FH3X232T.js → usage-event-W5VLRA3X.js} +8 -7
  74. package/dist/{usage-event-FH3X232T.js.map → usage-event-W5VLRA3X.js.map} +1 -1
  75. package/package.json +1 -1
  76. package/dist/chunk-BGPVMJOG.js.map +0 -1
  77. package/dist/chunk-TCJN5S4T.js.map +0 -1
  78. package/dist/cline-AJZ67XEE.js.map +0 -1
  79. package/dist/codex-C7ERS3TW.js.map +0 -1
  80. package/dist/doctor-BGWPZ676.js.map +0 -1
  81. package/dist/open-interpreter-CXUCCZI3.js +0 -264
  82. package/dist/open-interpreter-CXUCCZI3.js.map +0 -1
  83. /package/dist/{chunk-K67UJSJI.js.map → chunk-66TGBYSL.js.map} +0 -0
  84. /package/dist/{chunk-HUL5CRF2.js.map → chunk-BAJL27XI.js.map} +0 -0
  85. /package/dist/{chunk-STR3CRH3.js.map → chunk-C4NDV6GW.js.map} +0 -0
  86. /package/dist/{chunk-LO6NIZSL.js.map → chunk-CG44RWYJ.js.map} +0 -0
  87. /package/dist/{chunk-OXANBA4I.js.map → chunk-ITVST3SZ.js.map} +0 -0
  88. /package/dist/{chunk-W4GVN3TJ.js.map → chunk-KQBRUI3Y.js.map} +0 -0
  89. /package/dist/{chunk-O7CFTOM5.js.map → chunk-S2TAC22E.js.map} +0 -0
  90. /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
  [![npm](https://img.shields.io/npm/v/@ken-jo/agent-connector?color=cb3837&logo=npm)](https://www.npmjs.com/package/@ken-jo/agent-connector)
17
22
  [![license](https://img.shields.io/npm/l/@ken-jo/agent-connector?color=22c55e)](LICENSE)
18
23
  [![agent hosts](https://img.shields.io/badge/agent%20hosts-42-2563eb)](https://agent-connector.ai/coverage)
@@ -22,7 +27,7 @@ Cursor, Copilot, Gemini, OpenCode, Warp, Zed…).
22
27
  [![headless runtime](https://img.shields.io/badge/headless%20runtime-verified%20matrix-22c55e)](https://agent-connector.ai/coverage)
23
28
  ![package formats](https://img.shields.io/badge/package-9%20plugin%20formats%20%2B%202%20MCP%20artifacts-2563eb)
24
29
  [![agent plugins](https://img.shields.io/badge/Agent%20Plugins-1.0.0-2563eb)](https://agent-plugins.org)
25
- ![tests](https://img.shields.io/badge/tests-150%20files-22c55e)
30
+ ![tests](https://img.shields.io/badge/tests-152%20files-22c55e)
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,12 @@ 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 (40), skills (34), hooks (31), commands (19), subagents (16), actions (9), status line (3) |
34
- | Hook events normalized | **13**, dispatched through **3** paradigms (`json-stdio` 23 hosts · `mcp-only` 11 · `ts-plugin` 8) |
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 | **25 of 42** (5 of them end-to-end through a model tool call); the other **17** by the registry install harness in an isolated HOME |
37
- | Measured footprint | one 135-line `defineConnector()` → **64 host-native files** in 6 file extensions across 41 of 42 hosts at user scope (61 at project scope) — `npm run measure:footprint` |
38
- | Test suite | **150** test files |
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 |
39
44
 
40
45
  **Who it is for.** agent-connector is the **publisher** side of MCP distribution:
41
46
  you wrote (or are writing) an MCP server and want it to install itself into your
@@ -99,7 +104,7 @@ npm install @ken-jo/agent-connector
99
104
  "name": "@acme/acme-db-mcp",
100
105
  "mcpName": "io.github.acme/acme-db",
101
106
  "bin": { "acme-db": "./bin.mjs" },
102
- "dependencies": { "@ken-jo/agent-connector": "^0.6.4" }
107
+ "dependencies": { "@ken-jo/agent-connector": "^0.6.5" }
103
108
  }
104
109
  ```
105
110
 
@@ -521,8 +526,8 @@ set (see [`/coverage`](https://agent-connector.ai/coverage) and
521
526
 
522
527
  | Paradigm | Platforms |
523
528
  |---|---|
524
- | `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 |
525
- | `mcp-only` (MCP registration only) | Warp · Cline · Trae · Zed · Freebuff · Xum · Pi · Windsurf · Open Interpreter · Junie · Mistral Vibe |
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 |
526
531
  | `ts-plugin` (generated bridge module) | OpenCode · MiMoCode · Kilo CLI · Kilo · OMP · NemoClaw · OpenClaw · Amp |
527
532
 
528
533
  Adding a platform = **one registry entry + one adapter**.
@@ -534,8 +539,8 @@ Adding a platform = **one registry entry + one adapter**.
534
539
  | `detect` | List installed platforms, scopes, capabilities, hook paradigm. |
535
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:`. |
536
541
  | `uninstall [--targets …] [--purge] [--method …]` | Full inverse — removes everything we wrote; `--purge` also clears framework state. |
537
- | `upgrade [--channel …]` | Re-render host config + heal stale pointers + refresh the home binary (alias: `update`, `sync`); never a silent self-update. |
538
- | `doctor [--probe] [--explain]` | Per-platform health checks with fixes; `--probe` runs a live MCP handshake, `--explain` prints the per-`(host, event)` hook honor matrix. |
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. |
539
544
  | `status` | Light install-state: which connectors are present on which hosts (always exits 0). |
540
545
  | `package [--format <fmt>\|all]` | Emit a host plugin bundle, or an OFFICIAL standard artifact: `mcp-server-json` (registry) · `mcpb` (one-click bundle). |
541
546
  | `audit [--strict]` | Pre-install package identity lint: package name/version/bin, runtime dependency, connector id/version drift, and publish `files` coverage. |
@@ -633,7 +638,8 @@ every adapter, drives the real install → uninstall into an isolated HOME and
633
638
  asserts on-disk placement + zero residue. A separate committed
634
639
  `scripts/verify-host.mjs` driver installs real host CLIs from the verification
635
640
  matrix and checks install → placement → clean-uninstall; live hook dispatch +
636
- telemetry are proven end-to-end where the host can run headlessly. IDE
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
637
643
  extensions / GUI editors with no headless CLI stay covered by the
638
644
  install-roundtrip harness.
639
645
 
@@ -1,20 +1,21 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  fail
4
- } from "./chunk-TCJN5S4T.js";
4
+ } from "./chunk-PTITNBSS.js";
5
5
  import {
6
6
  runAction
7
- } from "./chunk-K67UJSJI.js";
7
+ } from "./chunk-66TGBYSL.js";
8
8
  import "./chunk-OP4KBXUO.js";
9
9
  import "./chunk-GDIAHWNY.js";
10
- import "./chunk-OXANBA4I.js";
11
- import "./chunk-W4GVN3TJ.js";
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-BGPVMJOG.js";
16
- import "./chunk-O7CFTOM5.js";
17
- import "./chunk-QG26JEJF.js";
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-IKJ2J3X4.js.map
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":";;;;;;;;;;;;;;;;;;;;;;;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":[]}
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-TCJN5S4T.js";
5
+ } from "./chunk-PTITNBSS.js";
6
6
  import {
7
7
  findConnectorConfig,
8
8
  loadConnectorFromPath
9
- } from "./chunk-BGPVMJOG.js";
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-O7CFTOM5.js";
16
- import "./chunk-QG26JEJF.js";
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-5K2H7PAT.js.map
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-OXANBA4I.js";
12
+ } from "./chunk-ITVST3SZ.js";
13
13
  import {
14
14
  attachLazyTelemetryUsage,
15
15
  buildTelemetryAccessor,
16
16
  measureToolCall,
17
17
  measureToolDefs
18
- } from "./chunk-W4GVN3TJ.js";
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-BGPVMJOG.js";
35
+ } from "./chunk-ZYB2UFEN.js";
36
36
  import {
37
37
  REGISTERED_PLATFORM_IDS,
38
38
  loadAdapter
39
- } from "./chunk-QG26JEJF.js";
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-K67UJSJI.js.map
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-EIC4Q7OT.js").then((m) => m.default)
15
+ load: () => import("./claude-code-JRKJARPH.js").then((m) => m.default)
16
16
  },
17
17
  {
18
18
  id: "codex",
19
- load: () => import("./codex-C7ERS3TW.js").then((m) => m.default)
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-AJZ67XEE.js").then((m) => m.default)
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) — mcp-only. It is a
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. Kept mcp-only (the codex hook
273
- // subsystem is present in the fork, but the `interpreter` product's live hook
274
- // wire contract is not first-party-verified, so hooks are not claimed).
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-CXUCCZI3.js").then((m) => m.default)
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-QG26JEJF.js.map
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-W4GVN3TJ.js";
5
+ } from "./chunk-KQBRUI3Y.js";
6
6
  import {
7
7
  SURFACE_PREDICATES,
8
8
  hostCanFireEvent
9
- } from "./chunk-BD72ZF6D.js";
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-QG26JEJF.js";
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-HUL5CRF2.js.map
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) => CODEX_HOOK_EVENTS.includes(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) => CODEX_HOOK_EVENTS.includes(e) ? e : void 0,
284
- unmappedWarnDetail: (e) => `${e} has no Codex hook equivalent \u2014 skipped`,
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: CODEX_HOOK_EVENTS
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, "codex", event, ctx.connector.id);
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 as default
776
+ codex_default
764
777
  };
765
- //# sourceMappingURL=codex-C7ERS3TW.js.map
778
+ //# sourceMappingURL=chunk-BB4DFAHC.js.map