@ken-jo/agent-connector 0.4.26 → 0.4.43

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 (152) hide show
  1. package/dist/{action-AZRZ3V7E.js → action-ZUHMOGLV.js} +8 -8
  2. package/dist/{amazon-q-BWSOHTW5.js → amazon-q-UFLBUSHG.js} +15 -16
  3. package/dist/amazon-q-UFLBUSHG.js.map +1 -0
  4. package/dist/{amp-TF5X6OGH.js → amp-5DJK7VAL.js} +3 -5
  5. package/dist/{amp-TF5X6OGH.js.map → amp-5DJK7VAL.js.map} +1 -1
  6. package/dist/{antigravity-3XHBPXZK.js → antigravity-NWP2TUG6.js} +3 -4
  7. package/dist/{antigravity-cli-TJGOBUPK.js → antigravity-cli-KPNLE7X4.js} +3 -4
  8. package/dist/{antigravity-cli-TJGOBUPK.js.map → antigravity-cli-KPNLE7X4.js.map} +1 -1
  9. package/dist/{chunk-YRBFSZ2G.js → chunk-3Q6YEDCG.js} +3 -5
  10. package/dist/{chunk-YRBFSZ2G.js.map → chunk-3Q6YEDCG.js.map} +1 -1
  11. package/dist/{chunk-25BNMXPP.js → chunk-3ZZK4KXG.js} +18 -18
  12. package/dist/{chunk-ZVTPSV5Z.js → chunk-4CBHYWUG.js} +5 -5
  13. package/dist/{chunk-YEJCNOET.js → chunk-54B5HAVT.js} +2 -2
  14. package/dist/{chunk-HU6DZZBG.js → chunk-5HSLICR3.js} +36 -36
  15. package/dist/{chunk-HZDU3J4U.js → chunk-5TMIJ7AY.js} +20 -4
  16. package/dist/chunk-5TMIJ7AY.js.map +1 -0
  17. package/dist/{chunk-3I7UG52L.js → chunk-A767JFHW.js} +65 -4
  18. package/dist/chunk-A767JFHW.js.map +1 -0
  19. package/dist/{chunk-OLI5SD6I.js → chunk-AQ53TOH4.js} +2 -2
  20. package/dist/{chunk-KD4BE5MW.js → chunk-ERV4TKRV.js} +3 -5
  21. package/dist/{chunk-KD4BE5MW.js.map → chunk-ERV4TKRV.js.map} +1 -1
  22. package/dist/{chunk-JLMD3IGK.js → chunk-H3BATOBP.js} +2 -2
  23. package/dist/{chunk-IW46JIQM.js → chunk-RAJBLK2V.js} +5 -5
  24. package/dist/{chunk-YKVNI44Y.js → chunk-VDSXVNEH.js} +3 -3
  25. package/dist/{cursor-R5QB4YR4.js → chunk-XW46WVR2.js} +11 -12
  26. package/dist/chunk-XW46WVR2.js.map +1 -0
  27. package/dist/{chunk-Q5HR4ADS.js → chunk-YG3KFOOQ.js} +2 -2
  28. package/dist/{claude-code-JLPFUZ4V.js → claude-code-YNNKQCCR.js} +6 -8
  29. package/dist/{claude-code-JLPFUZ4V.js.map → claude-code-YNNKQCCR.js.map} +1 -1
  30. package/dist/cli/sdk.js +4 -4
  31. package/dist/cli.js +1 -1
  32. package/dist/{cline-GBP3EVSX.js → cline-AGFJF4AC.js} +3 -5
  33. package/dist/{cline-GBP3EVSX.js.map → cline-AGFJF4AC.js.map} +1 -1
  34. package/dist/{codebuff-WMKFUVER.js → codebuff-YUQ4PN7G.js} +3 -5
  35. package/dist/{codebuff-WMKFUVER.js.map → codebuff-YUQ4PN7G.js.map} +1 -1
  36. package/dist/{codex-5CZR5XKX.js → codex-FLU37DV3.js} +26 -11
  37. package/dist/codex-FLU37DV3.js.map +1 -0
  38. package/dist/{continue-3AGXWM5W.js → continue-ZMI4YN75.js} +2 -3
  39. package/dist/{continue-3AGXWM5W.js.map → continue-ZMI4YN75.js.map} +1 -1
  40. package/dist/{copilot-cli-IH4P3GRZ.js → copilot-cli-XPRJ5MQB.js} +29 -5
  41. package/dist/copilot-cli-XPRJ5MQB.js.map +1 -0
  42. package/dist/{crush-FDBL3JEK.js → crush-3OB5ZTCC.js} +11 -10
  43. package/dist/crush-3OB5ZTCC.js.map +1 -0
  44. package/dist/cursor-F4HYO2FP.js +22 -0
  45. package/dist/{detect-L5OZPVFO.js → detect-FXGBSNQU.js} +4 -4
  46. package/dist/{doctor-WDIQ2YFE.js → doctor-2O65SAPG.js} +13 -10
  47. package/dist/{doctor-WDIQ2YFE.js.map → doctor-2O65SAPG.js.map} +1 -1
  48. package/dist/{droid-X2QHQL7D.js → droid-NZCKYKOV.js} +3 -5
  49. package/dist/{droid-X2QHQL7D.js.map → droid-NZCKYKOV.js.map} +1 -1
  50. package/dist/{gemini-cli-HCN7XKSX.js → gemini-cli-3ZGCXUDD.js} +3 -5
  51. package/dist/{gemini-cli-HCN7XKSX.js.map → gemini-cli-3ZGCXUDD.js.map} +1 -1
  52. package/dist/{goose-ILMM76JP.js → goose-MGGNVXJP.js} +56 -9
  53. package/dist/goose-MGGNVXJP.js.map +1 -0
  54. package/dist/{hermes-YX2ODUZL.js → hermes-L3CBJ37L.js} +8 -6
  55. package/dist/hermes-L3CBJ37L.js.map +1 -0
  56. package/dist/{hook-JRDQ56BN.js → hook-D3PY6TDK.js} +8 -8
  57. package/dist/index.js +2 -2
  58. package/dist/{install-HRCVPRAQ.js → install-SVBIK4VJ.js} +13 -10
  59. package/dist/{install-HRCVPRAQ.js.map → install-SVBIK4VJ.js.map} +1 -1
  60. package/dist/{jetbrains-copilot-QESFUN6W.js → jetbrains-copilot-M2LHJBAW.js} +3 -5
  61. package/dist/{jetbrains-copilot-QESFUN6W.js.map → jetbrains-copilot-M2LHJBAW.js.map} +1 -1
  62. package/dist/{kilo-POTCYIRG.js → kilo-RMRP2EL7.js} +3 -5
  63. package/dist/{kilo-POTCYIRG.js.map → kilo-RMRP2EL7.js.map} +1 -1
  64. package/dist/{kilo-cli-MO6FSMH2.js → kilo-cli-6ITBNHTH.js} +14 -10
  65. package/dist/kilo-cli-6ITBNHTH.js.map +1 -0
  66. package/dist/{kimi-RXS36OJP.js → kimi-I35VOOY4.js} +45 -15
  67. package/dist/kimi-I35VOOY4.js.map +1 -0
  68. package/dist/{kiro-VTLX7CMF.js → kiro-2K5UJVGC.js} +11 -16
  69. package/dist/kiro-2K5UJVGC.js.map +1 -0
  70. package/dist/{leaderboard-ASGR3E2U.js → leaderboard-ZMZST52G.js} +2 -2
  71. package/dist/{mimo-code-F4BWMESO.js → mimo-code-K7AMX2QW.js} +3 -5
  72. package/dist/{mimo-code-F4BWMESO.js.map → mimo-code-K7AMX2QW.js.map} +1 -1
  73. package/dist/{mux-2YFCYFM7.js → mux-GT7FWVLH.js} +3 -5
  74. package/dist/{mux-2YFCYFM7.js.map → mux-GT7FWVLH.js.map} +1 -1
  75. package/dist/{nemoclaw-QDB6O22A.js → nemoclaw-GQMS6CUM.js} +3 -4
  76. package/dist/{nemoclaw-QDB6O22A.js.map → nemoclaw-GQMS6CUM.js.map} +1 -1
  77. package/dist/{omp-P2JNAEPN.js → omp-2RPYIZUF.js} +2 -3
  78. package/dist/{omp-P2JNAEPN.js.map → omp-2RPYIZUF.js.map} +1 -1
  79. package/dist/{openclaw-3UMBSSZM.js → openclaw-P5GMEEGC.js} +3 -4
  80. package/dist/openclaw-P5GMEEGC.js.map +1 -0
  81. package/dist/{opencode-Q6H4YT66.js → opencode-5D2SK3EX.js} +3 -5
  82. package/dist/{opencode-Q6H4YT66.js.map → opencode-5D2SK3EX.js.map} +1 -1
  83. package/dist/{package-IXBSG7HD.js → package-EDYQF6C6.js} +10 -7
  84. package/dist/{package-IXBSG7HD.js.map → package-EDYQF6C6.js.map} +1 -1
  85. package/dist/{pi-GW25LPC3.js → pi-ZMM4KJTO.js} +2 -3
  86. package/dist/{pi-GW25LPC3.js.map → pi-ZMM4KJTO.js.map} +1 -1
  87. package/dist/{qwen-code-R6XXEEHJ.js → qwen-code-4ZLVGN2C.js} +9 -11
  88. package/dist/qwen-code-4ZLVGN2C.js.map +1 -0
  89. package/dist/{roo-code-EZPNFC5V.js → roo-code-67QGLQRM.js} +4 -5
  90. package/dist/roo-code-67QGLQRM.js.map +1 -0
  91. package/dist/runtime/index.js +6 -6
  92. package/dist/sdk/index.js +3 -3
  93. package/dist/sdk/test.js +5 -5
  94. package/dist/{serve-CFBQYKRB.js → serve-427CCEYA.js} +8 -8
  95. package/dist/{status-ASBFEFQQ.js → status-6IHRW6PI.js} +6 -6
  96. package/dist/{statusline-WKLWSM7I.js → statusline-2CKH5RHO.js} +7 -7
  97. package/dist/{telemetry-64GCGNIW.js → telemetry-WNVKL7HW.js} +5 -5
  98. package/dist/{trae-6VQW2UVP.js → trae-TMJPHWZ5.js} +3 -5
  99. package/dist/{trae-6VQW2UVP.js.map → trae-TMJPHWZ5.js.map} +1 -1
  100. package/dist/{uninstall-KDJYE5ET.js → uninstall-QFCDXGKR.js} +13 -10
  101. package/dist/{uninstall-KDJYE5ET.js.map → uninstall-QFCDXGKR.js.map} +1 -1
  102. package/dist/{upgrade-YQRVYR5U.js → upgrade-PP46DURC.js} +13 -10
  103. package/dist/{upgrade-YQRVYR5U.js.map → upgrade-PP46DURC.js.map} +1 -1
  104. package/dist/{usage-OV2BDZKF.js → usage-VDORZJPT.js} +2 -2
  105. package/dist/{usage-event-KPI3NEX3.js → usage-event-4533OURF.js} +7 -7
  106. package/dist/{vscode-copilot-UOEEV4P3.js → vscode-copilot-H7JKUKLZ.js} +19 -8
  107. package/dist/vscode-copilot-H7JKUKLZ.js.map +1 -0
  108. package/dist/{warp-LUK2BPCU.js → warp-SVDVKQQI.js} +3 -5
  109. package/dist/{warp-LUK2BPCU.js.map → warp-SVDVKQQI.js.map} +1 -1
  110. package/dist/{windsurf-NZ3G42NQ.js → windsurf-H36YKOMR.js} +3 -5
  111. package/dist/{windsurf-NZ3G42NQ.js.map → windsurf-H36YKOMR.js.map} +1 -1
  112. package/dist/{zed-LGWGZ4EO.js → zed-LHWJALLZ.js} +3 -5
  113. package/dist/{zed-LGWGZ4EO.js.map → zed-LHWJALLZ.js.map} +1 -1
  114. package/package.json +1 -1
  115. package/dist/amazon-q-BWSOHTW5.js.map +0 -1
  116. package/dist/chunk-3I7UG52L.js.map +0 -1
  117. package/dist/chunk-HZDU3J4U.js.map +0 -1
  118. package/dist/chunk-IEGR4TP3.js +0 -70
  119. package/dist/chunk-IEGR4TP3.js.map +0 -1
  120. package/dist/codex-5CZR5XKX.js.map +0 -1
  121. package/dist/copilot-cli-IH4P3GRZ.js.map +0 -1
  122. package/dist/crush-FDBL3JEK.js.map +0 -1
  123. package/dist/cursor-R5QB4YR4.js.map +0 -1
  124. package/dist/goose-ILMM76JP.js.map +0 -1
  125. package/dist/hermes-YX2ODUZL.js.map +0 -1
  126. package/dist/kilo-cli-MO6FSMH2.js.map +0 -1
  127. package/dist/kimi-RXS36OJP.js.map +0 -1
  128. package/dist/kiro-VTLX7CMF.js.map +0 -1
  129. package/dist/qwen-code-R6XXEEHJ.js.map +0 -1
  130. package/dist/roo-code-EZPNFC5V.js.map +0 -1
  131. package/dist/vscode-copilot-UOEEV4P3.js.map +0 -1
  132. /package/dist/{action-AZRZ3V7E.js.map → action-ZUHMOGLV.js.map} +0 -0
  133. /package/dist/{antigravity-3XHBPXZK.js.map → antigravity-NWP2TUG6.js.map} +0 -0
  134. /package/dist/{chunk-25BNMXPP.js.map → chunk-3ZZK4KXG.js.map} +0 -0
  135. /package/dist/{chunk-ZVTPSV5Z.js.map → chunk-4CBHYWUG.js.map} +0 -0
  136. /package/dist/{chunk-YEJCNOET.js.map → chunk-54B5HAVT.js.map} +0 -0
  137. /package/dist/{chunk-HU6DZZBG.js.map → chunk-5HSLICR3.js.map} +0 -0
  138. /package/dist/{chunk-OLI5SD6I.js.map → chunk-AQ53TOH4.js.map} +0 -0
  139. /package/dist/{chunk-JLMD3IGK.js.map → chunk-H3BATOBP.js.map} +0 -0
  140. /package/dist/{chunk-IW46JIQM.js.map → chunk-RAJBLK2V.js.map} +0 -0
  141. /package/dist/{chunk-YKVNI44Y.js.map → chunk-VDSXVNEH.js.map} +0 -0
  142. /package/dist/{chunk-Q5HR4ADS.js.map → chunk-YG3KFOOQ.js.map} +0 -0
  143. /package/dist/{openclaw-3UMBSSZM.js.map → cursor-F4HYO2FP.js.map} +0 -0
  144. /package/dist/{detect-L5OZPVFO.js.map → detect-FXGBSNQU.js.map} +0 -0
  145. /package/dist/{hook-JRDQ56BN.js.map → hook-D3PY6TDK.js.map} +0 -0
  146. /package/dist/{leaderboard-ASGR3E2U.js.map → leaderboard-ZMZST52G.js.map} +0 -0
  147. /package/dist/{serve-CFBQYKRB.js.map → serve-427CCEYA.js.map} +0 -0
  148. /package/dist/{status-ASBFEFQQ.js.map → status-6IHRW6PI.js.map} +0 -0
  149. /package/dist/{statusline-WKLWSM7I.js.map → statusline-2CKH5RHO.js.map} +0 -0
  150. /package/dist/{telemetry-64GCGNIW.js.map → telemetry-WNVKL7HW.js.map} +0 -0
  151. /package/dist/{usage-OV2BDZKF.js.map → usage-VDORZJPT.js.map} +0 -0
  152. /package/dist/{usage-event-KPI3NEX3.js.map → usage-event-4533OURF.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/package.ts","../src/core/package-formats/claude-family.ts","../src/core/package-formats/shared.ts","../src/core/package-formats/cursor.ts","../src/core/package-formats/gemini.ts","../src/core/package-formats/agy.ts","../src/core/package-formats/kimi.ts","../src/core/package-formats/npm.ts","../src/core/package-formats/mcp-server.ts","../src/core/package-formats/mcpb.ts"],"sourcesContent":["/**\n * core/package — emit a marketplace/extension-installable connector bundle.\n *\n * Turns a {@link ResolvedConnector} into a self-contained plugin/extension bundle\n * for ANY of the emit-feasible plugin/marketplace formats the agent ecosystem\n * supports. The format-specific emitters live under `package-formats/<family>.ts`,\n * each conforming to the shared {@link FormatEmitter} signature; this module is\n * the single, consistent dispatch over them.\n *\n * Supported formats (PackageFormat):\n * • claude-plugin — Claude Code / codex / vscode-copilot / openclaw / omp\n * • codex-plugin — Codex `.codex-plugin/` manifest variant of claude-plugin\n * • factory-plugin — droid `.factory-plugin/` (droids/, mcp.json) variant\n * • gemini-extension — Gemini CLI extension (gemini-extension.json + TOML commands)\n * • qwen-extension — Qwen Code extension (qwen-extension.json + Markdown commands)\n * • agy-plugin — Antigravity CLI/IDE (root plugin.json + mcp_config.json)\n * • cursor-plugin — Cursor (.cursor-plugin/ + pointer fields + marketplace.json)\n * • kimi-plugin — Kimi (skills + MCP only; hooks/commands/subagents dropped)\n * • npm-plugin — opencode / kilo-cli / pi (publishable npm package + bridge)\n *\n * The command / skill / subagent markdown is rendered through the SAME shared\n * claude-code renderers the live adapters write with (where the target uses\n * markdown), hooks via buildHomeBinHookCommand, and MCP via buildServeWrapperCommand\n * with `--host <platform>` — so telemetry-wrap + the universal home-bin pointer\n * carry through every bundle exactly as an `agent-connector install` would.\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\n\nimport type { ResolvedConnector } from \"./types.js\";\nimport { homeBinPath as defaultHomeBinPath } from \"./paths.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./package-formats/shared.js\";\nimport {\n emitClaudePlugin,\n emitCodexPlugin,\n emitFactoryPlugin,\n} from \"./package-formats/claude-family.js\";\nimport { emitCursorPlugin } from \"./package-formats/cursor.js\";\nimport {\n emitGeminiExtension,\n emitQwenExtension,\n} from \"./package-formats/gemini.js\";\nimport { emitAgyPlugin } from \"./package-formats/agy.js\";\nimport { emitKimiPlugin } from \"./package-formats/kimi.js\";\nimport { emitNpmPlugin } from \"./package-formats/npm.js\";\nimport { emitMcpServerJson } from \"./package-formats/mcp-server.js\";\nimport { emitMcpbBundle } from \"./package-formats/mcpb.js\";\n\nexport type { PackageResult } from \"./package-formats/shared.js\";\n\n/** Every packaging format `package` can emit. */\nexport type PackageFormat =\n | \"claude-plugin\"\n | \"codex-plugin\"\n | \"factory-plugin\"\n | \"gemini-extension\"\n | \"qwen-extension\"\n | \"agy-plugin\"\n | \"cursor-plugin\"\n | \"kimi-plugin\"\n | \"npm-plugin\"\n // Official MCP standard artifacts (describe the dev's REAL upstream server,\n // not our serve wrapper; require `publish` metadata, so they are opt-in and\n // excluded from `--format all`).\n | \"mcp-server-json\"\n | \"mcpb\";\n\n/** The single consistent dispatch map: format → emitter. */\nconst EMITTERS: Record<PackageFormat, FormatEmitter> = {\n \"claude-plugin\": emitClaudePlugin,\n \"codex-plugin\": emitCodexPlugin,\n \"factory-plugin\": emitFactoryPlugin,\n \"gemini-extension\": emitGeminiExtension,\n \"qwen-extension\": emitQwenExtension,\n \"agy-plugin\": emitAgyPlugin,\n \"cursor-plugin\": emitCursorPlugin,\n \"kimi-plugin\": emitKimiPlugin,\n \"npm-plugin\": emitNpmPlugin,\n \"mcp-server-json\": emitMcpServerJson,\n mcpb: emitMcpbBundle,\n};\n\n/** All formats, in a stable, documented order. */\nexport const ALL_FORMATS: readonly PackageFormat[] = [\n \"claude-plugin\",\n \"codex-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n \"npm-plugin\",\n \"mcp-server-json\",\n \"mcpb\",\n] as const;\n\n/**\n * The formats `--format all` emits — the host plugin/marketplace bundles that\n * work for ANY connector. The official MCP standard artifacts (mcp-server-json,\n * and the MCPB bundle) are deliberately EXCLUDED: they require `publish`\n * metadata (a namespace the dev owns, their published package) and would error\n * for a connector that has not opted into publishing, so they are emitted only\n * when requested explicitly by name.\n */\nexport const FEASIBLE_FORMATS: readonly PackageFormat[] = [\n \"claude-plugin\",\n \"codex-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n \"npm-plugin\",\n] as const;\n\n/** Type guard: is `s` a supported {@link PackageFormat}? */\nexport function isPackageFormat(s: string): s is PackageFormat {\n return Object.prototype.hasOwnProperty.call(EMITTERS, s);\n}\n\nexport interface PackageOptions {\n /** Directory the bundle is written under (the format root). */\n outDir: string;\n /** Output format. Defaults to \"claude-plugin\". */\n format?: PackageFormat;\n /**\n * Absolute path to agent-connector's stable home-bin that hooks + the MCP\n * serve-wrapper point at. Defaults to {@link defaultHomeBinPath}.\n */\n homeBinPath?: string;\n /** Compute the file list without writing anything. */\n dryRun?: boolean;\n}\n\n/**\n * Emit a bundle for `connector` in a single `format` (default claude-plugin).\n *\n * Writes (or, for dryRun, only enumerates) the bundle under `opts.outDir`.\n * Returns the absolute file list, the plugin root dir, an optional marketplace\n * path, and optional drop notes (for lossy formats like kimi-plugin).\n */\n/**\n * Host-bundle formats whose hooks/MCP entries embed the ABSOLUTE home-bin path\n * of the machine that ran `package`. They install fine locally, but on another\n * machine/user the baked path points at nothing — so every emit carries a note.\n * (npm-plugin resolves the CLI by name on PATH; mcp-server-json/mcpb describe\n * the dev's real upstream server — none of those embed a local path.)\n */\nconst HOME_BIN_EMBED_FORMATS: ReadonlySet<PackageFormat> = new Set([\n \"claude-plugin\",\n \"codex-plugin\",\n \"factory-plugin\",\n \"gemini-extension\",\n \"qwen-extension\",\n \"agy-plugin\",\n \"cursor-plugin\",\n \"kimi-plugin\",\n]);\n\nexport function packageConnector(\n connector: ResolvedConnector,\n opts: PackageOptions,\n): PackageResult {\n const format = opts.format ?? \"claude-plugin\";\n const emitter = EMITTERS[format];\n if (!emitter) {\n throw new Error(`unsupported package format: ${format}`);\n }\n\n const ctx: EmitContext = {\n outDir: resolve(opts.outDir),\n homeBinPath: opts.homeBinPath ?? defaultHomeBinPath(),\n dryRun: opts.dryRun ?? false,\n };\n const result = emitter(connector, ctx);\n if (HOME_BIN_EMBED_FORMATS.has(format)) {\n const note =\n `bundle embeds this machine's agent-connector launcher path (${ctx.homeBinPath}) — ` +\n \"valid for LOCAL install; for a shared marketplace, consumers need agent-connector \" +\n \"at the same home path (run `agent-connector upgrade` there) or re-run `package` per machine\";\n result.notes = [...(result.notes ?? []), note];\n }\n return result;\n}\n\n/** One entry in a multi-format ({@link packageConnectorAll}) emit. */\nexport interface MultiPackageResult {\n format: PackageFormat;\n result: PackageResult;\n}\n\n/**\n * Emit EVERY feasible format, each into its own `<outDir>/<format>/` subdir, so a\n * single `package --format all` produces the whole matrix without collisions.\n */\nexport function packageConnectorAll(\n connector: ResolvedConnector,\n opts: { outDir: string; homeBinPath?: string; dryRun?: boolean },\n): MultiPackageResult[] {\n const base = resolve(opts.outDir);\n const homeBin = opts.homeBinPath ?? defaultHomeBinPath();\n const dryRun = opts.dryRun ?? false;\n return FEASIBLE_FORMATS.map((format) => ({\n format,\n result: packageConnector(connector, {\n outDir: resolve(base, format),\n format,\n homeBinPath: homeBin,\n dryRun,\n }),\n }));\n}\n\n/**\n * Per-format MANUAL install commands (the accurate two-step add+install where\n * applicable). Lives in core (not the CLI) so both `package`'s printed\n * instructions and the marketplace method's skip-warn records for non-drivable\n * hosts quote the SAME commands — one copy, no drift.\n */\nexport function installInstructions(\n format: PackageFormat,\n id: string,\n outDir: string,\n): string[] {\n switch (format) {\n case \"claude-plugin\":\n return [\n `/plugin marketplace add ${outDir}`,\n `/plugin install ${id}@agent-connector`,\n `(CLI: claude plugin marketplace add ${outDir} && claude plugin install ${id}@agent-connector)`,\n ];\n case \"codex-plugin\":\n return [\n `codex plugin marketplace add ${outDir}`,\n `codex plugin add ${id}@agent-connector`,\n ];\n case \"factory-plugin\":\n return [\n `droid plugin marketplace add ${outDir}`,\n `droid plugin install ${id}@agent-connector`,\n ];\n case \"gemini-extension\":\n return [`gemini extensions install ${join(outDir, id)}`];\n case \"qwen-extension\":\n return [`qwen extensions install ${join(outDir, id)}`];\n case \"agy-plugin\":\n return [\n `agy plugin install ${join(outDir, id)}`,\n `(validate: agy plugin validate ${join(outDir, id)})`,\n ];\n case \"cursor-plugin\":\n return [\n `link ${join(outDir, id)} into ~/.cursor/plugins/local/${id}/ then Developer: Reload Window`,\n `(or publish ${outDir} as a Cursor marketplace repo)`,\n ];\n case \"kimi-plugin\":\n return [`kimi plugin install ${join(outDir, id)}`];\n case \"npm-plugin\":\n return [\n `npm publish ${join(outDir, id)} (then: opencode plugin install <pkg> | kilo plugin <pkg> | pi install npm:<pkg>)`,\n ];\n case \"mcp-server-json\":\n return [\n `mcp-publisher login <github|dns|http> (prove ownership of your namespace once)`,\n `cd ${outDir} && mcp-publisher publish (uploads server.json to the official MCP Registry)`,\n ];\n case \"mcpb\":\n return [\n `vendor your built server under ${join(outDir, \"server\")}/ (see the emitted README)`,\n `npx @anthropic-ai/mcpb pack ${outDir} (then optionally: mcpb sign)`,\n ];\n default:\n return [];\n }\n}\n\n/** Read + parse a JSON file (used by callers/tests). Returns null on absence/parse error. */\nexport function readPackagedJson<T = unknown>(path: string): T | null {\n if (!existsSync(path)) return null;\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as T;\n } catch {\n return null;\n }\n}\n","/**\n * core/package-formats/claude-family — the claude-plugin emitter + its two\n * manifest-rename siblings (codex-plugin, factory-plugin).\n *\n * All three share ONE component tree (commands/ agents-or-droids/ skills/<n>/\n * SKILL.md + hooks/hooks.json + an MCP json) and differ only in:\n * • the manifest DIR + filename (.claude-plugin/ | .codex-plugin/ | .factory-plugin/)\n * • the subagent dir name (agents/ vs droids/ for factory)\n * • the MCP filename (.mcp.json vs mcp.json for factory)\n * • the manifest extra fields (claude adds $schema; factory pins version+author)\n * • the marketplace catalog shape (claude/codex object-owner; factory git-repo catalog)\n *\n * The command / skill / subagent markdown is rendered through the SAME shared\n * claude-code renderers the live adapter writes with, so an installed plugin and\n * an `agent-connector install` produce byte-identical content files. Hooks use\n * the universal home-bin command (telemetry-routed) and the MCP entry is\n * serve-wrapped with `--host <platform>` so telemetry carries through.\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\n/** Per-variant layout + manifest knobs for a Claude-family bundle. */\ninterface ClaudeFamilySpec {\n /** Host platform stamped into the serve-wrapper + hook command (--host). */\n platformId: PlatformId;\n /** Manifest directory under the plugin root (e.g. \".claude-plugin\"). */\n manifestDir: string;\n /** Subagent directory name (claude/codex: \"agents\"; factory: \"droids\"). */\n subagentDir: string;\n /** MCP filename at the plugin root (claude/codex: \".mcp.json\"; factory: \"mcp.json\"). */\n mcpFile: string;\n /** Add `$schema` to plugin.json (claude only). */\n schemaUrl?: string;\n /** Always carry a version in plugin.json, defaulting placeholder to \"0.0.1\" (factory requires it). */\n requireVersion?: boolean;\n /** Always carry an `author` object in plugin.json (factory pins it). */\n alwaysAuthor?: boolean;\n /**\n * Where to write the marketplace catalog, relative to outDir, and which shape.\n * \"claude\": <outDir>/.claude-plugin/marketplace.json (object owner).\n * \"codex\": <outDir>/.agents/plugins/marketplace.json (same object-owner\n * catalog; codex's documented location — `codex plugin marketplace\n * add` REJECTS a `.codex-plugin/` catalog with \"marketplace root\n * does not contain a supported manifest\"; live-verified 0.139.0).\n * \"factory\":<outDir>/marketplace.json (git-repo catalog at the repo root).\n */\n marketplace: { dir: string | null; file: string; shape: \"claude\" | \"factory\" };\n}\n\nconst SPECS: Record<string, ClaudeFamilySpec> = {\n \"claude-plugin\": {\n platformId: \"claude-code\",\n manifestDir: \".claude-plugin\",\n subagentDir: \"agents\",\n mcpFile: \".mcp.json\",\n schemaUrl: \"https://json.schemastore.org/claude-code-plugin-manifest.json\",\n marketplace: { dir: \".claude-plugin\", file: \"marketplace.json\", shape: \"claude\" },\n },\n \"codex-plugin\": {\n platformId: \"codex\",\n manifestDir: \".codex-plugin\",\n subagentDir: \"agents\",\n mcpFile: \".mcp.json\",\n marketplace: {\n dir: join(\".agents\", \"plugins\"),\n file: \"marketplace.json\",\n shape: \"claude\",\n },\n },\n \"factory-plugin\": {\n platformId: \"droid\",\n manifestDir: \".factory-plugin\",\n subagentDir: \"droids\",\n mcpFile: \"mcp.json\",\n requireVersion: true,\n alwaysAuthor: true,\n // droid marketplaces are Git-repo catalogs; the catalog sits at the repo root.\n marketplace: { dir: null, file: \"marketplace.json\", shape: \"factory\" },\n },\n};\n\n/** Build the plugin manifest for a Claude-family variant. */\nfunction buildManifest(\n connector: ResolvedConnector,\n spec: ClaudeFamilySpec,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {};\n if (spec.schemaUrl) manifest.$schema = spec.schemaUrl;\n manifest.name = connector.id;\n manifest.description = `${connector.displayName} — connector emitted by agent-connector`;\n\n const hasRealVersion = connector.version && connector.version !== \"0.0.0\";\n if (hasRealVersion) {\n manifest.version = connector.version;\n } else if (spec.requireVersion) {\n // factory requires a semver version; supply a sane default when unpinned.\n manifest.version = \"0.0.1\";\n }\n // Attribute the bundle to the connector developer when they declared an\n // author (publish.author); the framework name is only the fallback.\n if (spec.alwaysAuthor) {\n manifest.author = { name: connector.publish?.author?.name ?? \"agent-connector\" };\n }\n return manifest;\n}\n\n/** Build the marketplace catalog for a Claude-family variant. */\nfunction buildMarketplace(connector: ResolvedConnector): Record<string, unknown> {\n // Both the claude/codex object-owner catalog and the droid git-repo catalog\n // use the same minimal { name, owner, plugins:[{name,source,description}] }\n // shape — droid reads source as a path relative to the marketplace repo root.\n // The catalog NAME stays \"agent-connector\" (the printed install instructions\n // `<id>@agent-connector` key on it); the OWNER is the developer when known.\n return {\n name: \"agent-connector\",\n owner: { name: connector.publish?.author?.name ?? \"agent-connector\" },\n plugins: [\n {\n name: connector.id,\n source: `./${connector.id}`,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n },\n ],\n };\n}\n\n/** Emit a Claude-family bundle (claude-plugin | codex-plugin | factory-plugin). */\nfunction emitClaudeFamily(\n connector: ResolvedConnector,\n ctx: EmitContext,\n format: keyof typeof SPECS,\n): PackageResult {\n const spec = SPECS[format];\n if (!spec) throw new Error(`unknown claude-family format: ${format}`);\n\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── plugin.json (the ONLY file inside the manifest dir) ───────────────────\n emit(\n join(pluginDir, spec.manifestDir, \"plugin.json\"),\n json(buildManifest(connector, spec)),\n );\n\n // ── commands/<name>.md ────────────────────────────────────────────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents|droids/<name>.md ───────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(\n join(pluginDir, spec.subagentDir, `${agent.name}.md`),\n renderSubagentMd(agent),\n );\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue; // never write outside the skill dir\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json (mapped events only) ─────────────────────────────────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, spec.platformId);\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // ── MCP json (serve-wrapped stdio server) ─────────────────────────────────\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, spec.platformId);\n if (mcp) {\n emit(\n join(pluginDir, spec.mcpFile),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n // ── marketplace catalog ───────────────────────────────────────────────────\n const marketplacePath = spec.marketplace.dir\n ? join(ctx.outDir, spec.marketplace.dir, spec.marketplace.file)\n : join(ctx.outDir, spec.marketplace.file);\n emit(marketplacePath, json(buildMarketplace(connector)));\n\n return { files, pluginDir, marketplacePath };\n}\n\nexport const emitClaudePlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"claude-plugin\");\n\nexport const emitCodexPlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"codex-plugin\");\n\nexport const emitFactoryPlugin: FormatEmitter = (connector, ctx) =>\n emitClaudeFamily(connector, ctx, \"factory-plugin\");\n","/**\n * core/package-formats/shared — the common emitter contract + helpers every\n * format family is built on.\n *\n * A format emitter is a pure function conforming to {@link FormatEmitter}: it\n * takes a {@link ResolvedConnector} plus an {@link EmitContext} ({outDir,\n * homeBinPath, dryRun}) and either writes the bundle (dryRun=false) or only\n * enumerates the files it WOULD write (dryRun=true), returning a\n * {@link PackageResult} ({pluginDir, files[], marketplacePath?, notes?}).\n *\n * Everything below is shared across families so each emitter file is just the\n * format-specific manifest + layout, never a re-implementation of file writing,\n * JSON serialization, traversal-safe resource placement, the home-bin hooks\n * block, or the serve-wrapper MCP entry. Reusing these keeps telemetry-wrap +\n * the universal home-bin hook command byte-identical to the live adapters.\n */\n\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport { writeFileSync } from \"node:fs\";\n\nimport type {\n HookEventName,\n PlatformId,\n ResolvedConnector,\n} from \"../types.js\";\nimport { ensureDir, firstSymlinkInPath } from \"../paths.js\";\nimport {\n buildHomeBinHookCommand,\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../spawn.js\";\n\n/** Inputs every format emitter receives. */\nexport interface EmitContext {\n /** Directory the bundle is written under (the format root). */\n outDir: string;\n /** Absolute path to agent-connector's stable home-bin (hooks + serve wrapper point here). */\n homeBinPath: string;\n /** Enumerate the file list without writing anything. */\n dryRun: boolean;\n}\n\n/** What every format emitter returns. */\nexport interface PackageResult {\n /** Absolute paths of every file the bundle comprises (written, or planned for dryRun). */\n files: string[];\n /** Absolute path to the plugin/extension root directory. */\n pluginDir: string;\n /** Absolute path to the emitted marketplace catalog, when the format has one. */\n marketplacePath?: string;\n /**\n * Human-readable notes about surfaces the format intentionally DROPS (e.g.\n * Kimi ignores hooks/commands/subagents). The CLI surfaces these so a lossy\n * bundle is never silent. Empty when nothing was dropped.\n */\n notes?: string[];\n}\n\n/** The shared signature every `package-formats/<family>.ts` exports. */\nexport type FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n) => PackageResult;\n\n/** A small file-collecting writer bound to one emit run (honors dryRun). */\nexport interface Emitter {\n /** Write `contents` to `path` (skipped under dryRun) and record it. */\n emit(path: string, contents: string): void;\n /** The accumulated absolute file list (in emit order). */\n readonly files: string[];\n}\n\n/** Build a dryRun-aware {@link Emitter} that records every (would-be) write. */\nexport function createEmitter(dryRun: boolean): Emitter {\n const files: string[] = [];\n return {\n files,\n emit(path: string, contents: string): void {\n if (!dryRun) {\n const symlink = firstSymlinkInPath(path);\n if (symlink !== null) {\n throw new Error(`refusing to emit through symbolic link: ${path} (${symlink})`);\n }\n ensureDir(dirname(path));\n writeFileSync(path, contents, \"utf8\");\n }\n files.push(path);\n },\n };\n}\n\n/** Pretty-print a value as 2-space JSON with a trailing newline. */\nexport function json(value: unknown): string {\n return `${JSON.stringify(value, null, 2)}\\n`;\n}\n\n/**\n * Resolve a skill-resource relative key against `baseDir`, returning the\n * absolute target ONLY when it stays inside the dir (defense-in-depth — config\n * validation already rejects traversal, but never trust input). Null otherwise.\n */\nexport function resolveWithin(baseDir: string, rel: string): string | null {\n const base = resolve(baseDir);\n const target = resolve(base, rel);\n if (target === base) return null;\n const rind = relative(base, target);\n if (rind === \"\" || rind.startsWith(\"..\") || resolve(base, rind) !== target) {\n return null;\n }\n if (rind === \"..\" || rind.startsWith(`..${sep}`)) return null;\n return target;\n}\n\n/** Pass env through unchanged when present, else undefined (drops empty objects). */\nexport function renderEnv(\n env: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return { ...env };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Hooks — the Claude-shaped hooks.json block, shared by every format whose\n// hooks file mirrors Claude Code's `{ type:\"command\", command:\"<string>\" }`.\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Claude event names a Claude-style plugin's hooks.json may key on. */\nexport const CLAUDE_MAPPED_EVENTS: ReadonlySet<HookEventName> =\n new Set<HookEventName>([\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"SessionStart\",\n \"SessionEnd\",\n \"UserPromptSubmit\",\n \"Stop\",\n \"Notification\",\n \"PermissionRequest\",\n \"PostToolUseFailure\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PostCompact\",\n ]);\n\n/** A single hooks.json entry (identical in shape to a settings.json hooks block). */\nexport interface PluginHookEntry {\n matcher?: string;\n hooks: Array<{ type: \"command\"; command: string }>;\n}\n\n/**\n * Build the Claude-shaped hooks.json body for the MAPPED events the connector\n * declares. Each command is the SAME single-string home-bin form the live\n * adapters write (via buildHomeBinHookCommand). `platformId` lets a format point\n * the hook at the right host (e.g. \"cursor\", \"claude-code\"). Returns null when\n * the connector declares no mapped events.\n */\nexport function buildClaudeHooksJson(\n connector: ResolvedConnector,\n homeBin: string,\n platformId: PlatformId,\n): { hooks: Record<string, PluginHookEntry[]> } | null {\n const events = connector.hookEvents.filter((e) => CLAUDE_MAPPED_EVENTS.has(e));\n if (events.length === 0) return null;\n\n const hooks: Record<string, PluginHookEntry[]> = {};\n for (const event of events) {\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n const command = {\n type: \"command\" as const,\n command: buildHomeBinHookCommand(homeBin, platformId, event, connector.id),\n };\n hooks[event] = [matcher ? { matcher, hooks: [command] } : { hooks: [command] }];\n }\n return { hooks };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// MCP — the serve-wrapped stdio server entry, shared by every format whose MCP\n// file carries a launchable { command, args, env?, cwd? } (the Claude .mcp.json\n// dialect). Remote/non-stdio servers are out of scope for a launchable bundle.\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Native MCP server entry shape a Claude-dialect mcpServers map accepts. */\nexport interface PluginMcpEntry {\n command: string;\n args: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/**\n * Render the connector's ServerDef into a serve-wrapped MCP entry for\n * `platformId`, so per-tool telemetry carries through the bundle exactly as the\n * live adapter's install does. Returns null when there is no stdio command to\n * launch (remote / server-less connectors). The returned `serverName` is the\n * connector id (the conventional single-server key).\n */\nexport function buildMcpEntry(\n connector: ResolvedConnector,\n homeBin: string,\n platformId: PlatformId,\n): { serverName: string; entry: PluginMcpEntry } | null {\n const server = connector.server;\n if (!server) return null;\n // A launchable bundle entry can only carry stdio servers; remote (http/sse/ws)\n // servers register a URL elsewhere, out of scope for the bundled plugin.\n if (server.transport !== \"stdio\") return null;\n\n const realCommand = server.command ?? \"\";\n if (realCommand === \"\") return null;\n const realArgs = [...(server.args ?? [])];\n\n let entry: PluginMcpEntry;\n if (shouldWrapForTelemetry(server, connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n homeBin,\n connector.id,\n realCommand,\n realArgs,\n undefined,\n platformId,\n );\n entry = { command: wrapped.command, args: wrapped.args };\n } else {\n entry = { command: realCommand, args: realArgs };\n }\n\n const env = renderEnv(server.env);\n if (env) entry.env = env;\n if (server.cwd) entry.cwd = server.cwd;\n\n return { serverName: connector.id, entry };\n}\n","/**\n * core/package-formats/cursor — the `cursor-plugin` emitter.\n *\n * Cursor's bundle is near-isomorphic to claude-plugin: manifest at\n * `.cursor-plugin/plugin.json` (only `name` required) with the surface fields\n * declared as POINTERS (\"skills\":\"./skills/\", \"hooks\":\"./hooks/hooks.json\",\n * \"mcpServers\":\"./mcp.json\") so a validator/IDE finds each dir; components live\n * at the plugin root: commands/<n>.md, agents/<n>.md, skills/<n>/SKILL.md,\n * mcp.json, hooks/hooks.json. A multi-plugin repo adds .cursor-plugin/\n * marketplace.json { name, owner:{name,email?}, plugins:[{name,source,description}] }.\n *\n * Markdown reuses the shared claude-code renderers (Cursor reads the same md +\n * frontmatter command/agent/skill documents). Hooks + MCP use the shared\n * builders with --host cursor so the home-bin hook + serve-wrapper telemetry\n * carry through.\n *\n * (Cursor also supports `rules/*.mdc`, but a connector declares no rules surface,\n * so no rules/ dir is emitted and the manifest omits the `rules` pointer.)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"cursor\";\n\n/** Build .cursor-plugin/plugin.json with pointer surface fields for what exists. */\nfunction buildManifest(\n connector: ResolvedConnector,\n has: { commands: boolean; agents: boolean; skills: boolean; hooks: boolean; mcp: boolean },\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n if (connector.version && connector.version !== \"0.0.0\") {\n manifest.version = connector.version;\n }\n // Pointer fields: only declare a surface that actually ships in the bundle.\n if (has.commands) manifest.commands = \"./commands/\";\n if (has.agents) manifest.agents = \"./agents/\";\n if (has.skills) manifest.skills = \"./skills/\";\n if (has.hooks) manifest.hooks = \"./hooks/hooks.json\";\n if (has.mcp) manifest.mcpServers = \"./mcp.json\";\n return manifest;\n}\n\n/** Build .cursor-plugin/marketplace.json (owner object carries name; email optional). */\nfunction buildMarketplace(connector: ResolvedConnector): Record<string, unknown> {\n // Catalog NAME stays \"agent-connector\" (install instructions key on it); the\n // OWNER is the connector developer when publish.author is declared.\n return {\n name: \"agent-connector\",\n owner: { name: connector.publish?.author?.name ?? \"agent-connector\" },\n plugins: [\n {\n name: connector.id,\n source: `./${connector.id}`,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n },\n ],\n };\n}\n\nexport const emitCursorPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, PLATFORM);\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, PLATFORM);\n\n const has = {\n commands: connector.commands.length > 0,\n agents: connector.subagents.length > 0,\n skills: connector.skills.length > 0,\n hooks: hooksJson !== null,\n mcp: mcp !== null,\n };\n\n // ── .cursor-plugin/plugin.json (ONLY file under .cursor-plugin/) ───────────\n emit(\n join(pluginDir, \".cursor-plugin\", \"plugin.json\"),\n json(buildManifest(connector, has)),\n );\n\n // ── commands/<name>.md ────────────────────────────────────────────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json ──────────────────────────────────────────────────────\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // ── mcp.json (Cursor's MCP filename, no leading dot) ──────────────────────\n if (mcp) {\n emit(\n join(pluginDir, \"mcp.json\"),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n // ── .cursor-plugin/marketplace.json ───────────────────────────────────────\n const marketplacePath = join(ctx.outDir, \".cursor-plugin\", \"marketplace.json\");\n emit(marketplacePath, json(buildMarketplace(connector)));\n\n return { files, pluginDir, marketplacePath };\n};\n\n/** True when a local install of this plugin already exists (used by the CLI hint). */\nexport function cursorLocalInstallExists(name: string, home: string): boolean {\n return existsSync(join(home, \".cursor\", \"plugins\", \"local\", name));\n}\n","/**\n * core/package-formats/gemini — the `gemini-extension` emitter + its `qwen-extension`\n * variant.\n *\n * A Gemini CLI extension is a directory with `gemini-extension.json` at its root\n * carrying `{ name, version, description, mcpServers, contextFileName }` plus the\n * component dirs: commands/<n>.toml (slash commands), skills/<n>/SKILL.md,\n * agents/<n>.md, hooks/hooks.json, and a GEMINI.md context file. UNLIKE the\n * Claude family, MCP is declared INLINE in the manifest's `mcpServers` map (not a\n * separate .mcp.json) — we still serve-wrap it so telemetry carries through.\n *\n * Qwen Code is a Gemini-CLI fork with its own `qwen-extension.json` (same shape)\n * but two differences captured here: commands are MARKDOWN (commands/<n>.md) not\n * TOML, and the context file is QWEN.md.\n *\n * Commands render to Gemini's native TOML `{ description, prompt }` (the same\n * shape the live gemini-cli adapter writes); skills/subagents reuse the shared\n * claude-code renderers (Gemini/Qwen read the same SKILL.md + md+frontmatter).\n * Hooks use the universal home-bin command; the MCP entry is serve-wrapped with\n * --host gemini-cli | qwen-code.\n */\n\nimport { join } from \"node:path\";\n\nimport type { CommandDef, PlatformId, ResolvedConnector } from \"../types.js\";\nimport { writeTomlString } from \"../toml.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\n/** Per-variant knobs for a Gemini-family extension. */\ninterface GeminiFamilySpec {\n platformId: PlatformId;\n /** Manifest filename at the extension root. */\n manifestFile: string;\n /** Context file name (GEMINI.md | QWEN.md). */\n contextFile: string;\n /** Command file format: TOML (gemini) or Markdown (qwen). */\n commandFormat: \"toml\" | \"md\";\n}\n\nconst SPECS: Record<string, GeminiFamilySpec> = {\n \"gemini-extension\": {\n platformId: \"gemini-cli\",\n manifestFile: \"gemini-extension.json\",\n contextFile: \"GEMINI.md\",\n commandFormat: \"toml\",\n },\n \"qwen-extension\": {\n platformId: \"qwen-code\",\n manifestFile: \"qwen-extension.json\",\n contextFile: \"QWEN.md\",\n commandFormat: \"md\",\n },\n};\n\n/** Render a command to Gemini's native TOML `{ description, prompt }`. */\nfunction renderCommandToml(cmd: CommandDef): string {\n const obj: Record<string, unknown> = {};\n if (cmd.description !== undefined) obj.description = cmd.description;\n obj.prompt = cmd.prompt;\n return writeTomlString(obj);\n}\n\n/** Build gemini-extension.json | qwen-extension.json (with optional inline mcpServers). */\nfunction buildManifest(\n connector: ResolvedConnector,\n spec: GeminiFamilySpec,\n homeBin: string,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n // gemini requires a version; default a placeholder to a real semver.\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n\n const mcp = buildMcpEntry(connector, homeBin, spec.platformId);\n if (mcp) {\n manifest.mcpServers = { [mcp.serverName]: mcp.entry };\n }\n manifest.contextFileName = spec.contextFile;\n return manifest;\n}\n\nfunction emitGeminiFamily(\n connector: ResolvedConnector,\n ctx: EmitContext,\n format: keyof typeof SPECS,\n): PackageResult {\n const spec = SPECS[format];\n if (!spec) throw new Error(`unknown gemini-family format: ${format}`);\n\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── gemini-extension.json | qwen-extension.json (MCP is inline here) ──────\n emit(\n join(pluginDir, spec.manifestFile),\n json(buildManifest(connector, spec, ctx.homeBinPath)),\n );\n\n // ── context file (GEMINI.md | QWEN.md) ────────────────────────────────────\n emit(\n join(pluginDir, spec.contextFile),\n `# ${connector.displayName}\\n\\nConnector context emitted by agent-connector.\\n`,\n );\n\n // ── commands/<name>.{toml|md} ─────────────────────────────────────────────\n for (const cmd of connector.commands) {\n if (spec.commandFormat === \"toml\") {\n emit(join(pluginDir, \"commands\", `${cmd.name}.toml`), renderCommandToml(cmd));\n } else {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks/hooks.json ──────────────────────────────────────────────────────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, spec.platformId);\n if (hooksJson) emit(join(pluginDir, \"hooks\", \"hooks.json\"), json(hooksJson));\n\n // A Gemini/Qwen extension has no separate marketplace catalog (it installs by\n // URL/path); marketplacePath is left undefined.\n return { files, pluginDir };\n}\n\nexport const emitGeminiExtension: FormatEmitter = (connector, ctx) =>\n emitGeminiFamily(connector, ctx, \"gemini-extension\");\n\nexport const emitQwenExtension: FormatEmitter = (connector, ctx) =>\n emitGeminiFamily(connector, ctx, \"qwen-extension\");\n","/**\n * core/package-formats/agy — the `agy plugin` bundle emitter (Antigravity CLI +\n * Antigravity IDE, which share the bundle).\n *\n * Live-confirmed layout (`agy plugin validate`):\n * • REQUIRED root `plugin.json` marker { name, version, description } — its\n * absence is the one hard error the validator reports.\n * • MCP MUST be a SEPARATE `mcp_config.json` { mcpServers:{...} } — an inline\n * `mcpServers` in plugin.json is NOT picked up. (This is the one structural\n * difference from the Claude family.)\n * • hooks.json at the BUNDLE ROOT keyed { hooks:{ <Event>:[{matcher,hooks:[{type,command}]}] } }\n * — agy 1.0.7 NEVER reads hooks/hooks.json: validate+install report\n * \"hooks: skipped (not found)\" and copy the file unprocessed. The root\n * location was fix-proven live (\"hooks: 1 processed\", components +hooks).\n * • skills/<n>/SKILL.md, agents/<n>.md, commands/<n>.md (commands are converted\n * to skills on validate — still emitted as Markdown command files).\n *\n * Markdown reuses the shared claude-code renderers; hooks use the universal\n * home-bin command; the MCP entry is serve-wrapped with --host antigravity-cli so\n * telemetry carries through. No marketplace catalog ships in the bundle (agy\n * installs by target / plugin@marketplace).\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport {\n renderCommandMd,\n renderSkillMd,\n renderSubagentMd,\n} from \"../../adapters/claude-code/render.js\";\nimport {\n buildClaudeHooksJson,\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"antigravity-cli\";\n\n/** Build the required root plugin.json marker. */\nfunction buildManifest(connector: ResolvedConnector): Record<string, unknown> {\n return {\n name: connector.id,\n // agy expects a version on the marker; default a placeholder to a real semver.\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n}\n\nexport const emitAgyPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n\n // ── plugin.json (REQUIRED root marker) ────────────────────────────────────\n emit(join(pluginDir, \"plugin.json\"), json(buildManifest(connector)));\n\n // ── commands/<name>.md (validator converts these to skills) ───────────────\n for (const cmd of connector.commands) {\n emit(join(pluginDir, \"commands\", `${cmd.name}.md`), renderCommandMd(cmd));\n }\n\n // ── agents/<name>.md ──────────────────────────────────────────────────────\n for (const agent of connector.subagents) {\n emit(join(pluginDir, \"agents\", `${agent.name}.md`), renderSubagentMd(agent));\n }\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── hooks.json (bundle ROOT — agy silently ignores hooks/hooks.json) ──────\n const hooksJson = buildClaudeHooksJson(connector, ctx.homeBinPath, PLATFORM);\n if (hooksJson) emit(join(pluginDir, \"hooks.json\"), json(hooksJson));\n\n // ── mcp_config.json (SEPARATE file — inline mcpServers is NOT read by agy) ─\n const mcp = buildMcpEntry(connector, ctx.homeBinPath, PLATFORM);\n if (mcp) {\n emit(\n join(pluginDir, \"mcp_config.json\"),\n json({ mcpServers: { [mcp.serverName]: mcp.entry } }),\n );\n }\n\n return { files, pluginDir };\n};\n","/**\n * core/package-formats/kimi — the `kimi-plugin` emitter (skills + MCP ONLY).\n *\n * A Kimi plugin is a directory whose manifest is `kimi.plugin.json` at the root\n * carrying { name, version, description, skills, mcpServers }. Kimi plugins carry\n * exactly TWO functional surfaces:\n * • skills/<n>/SKILL.md (declared via the `skills` pointer)\n * • mcpServers (a standard MCP map, stdio + http)\n *\n * Kimi EXPLICITLY ignores `tools`, `commands`, `hooks`, `apps`, `inject`,\n * `configFile` (they surface as diagnostics). So when the connector declares\n * commands, subagents, or hooks, those surfaces are DROPPED — and a note is\n * returned so the lossy bundle is never silent. The MCP entry is still\n * serve-wrapped with --host kimi so telemetry carries through; hooks are NOT\n * emitted because Kimi has no hooks surface.\n */\n\nimport { join } from \"node:path\";\n\nimport type { PlatformId, ResolvedConnector } from \"../types.js\";\nimport { renderSkillMd } from \"../../adapters/claude-code/render.js\";\nimport {\n buildMcpEntry,\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\nconst PLATFORM: PlatformId = \"kimi\";\n\n/** Build kimi.plugin.json (skills pointer + inline mcpServers when present). */\nfunction buildManifest(\n connector: ResolvedConnector,\n hasSkills: boolean,\n homeBin: string,\n): Record<string, unknown> {\n const manifest: Record<string, unknown> = {\n name: connector.id,\n version:\n connector.version && connector.version !== \"0.0.0\"\n ? connector.version\n : \"0.0.1\",\n description: `${connector.displayName} — connector emitted by agent-connector`,\n };\n if (hasSkills) manifest.skills = \"./skills/\";\n const mcp = buildMcpEntry(connector, homeBin, PLATFORM);\n if (mcp) manifest.mcpServers = { [mcp.serverName]: mcp.entry };\n return manifest;\n}\n\nexport const emitKimiPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n const notes: string[] = [];\n\n const hasSkills = connector.skills.length > 0;\n\n // ── kimi.plugin.json (root manifest; MCP inline; hooks/commands ignored) ──\n emit(join(pluginDir, \"kimi.plugin.json\"), json(buildManifest(connector, hasSkills, ctx.homeBinPath)));\n\n // ── skills/<name>/SKILL.md (+ resources) ──────────────────────────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── Surfaces Kimi cannot carry → DROPPED, with an explicit note ───────────\n if (connector.commands.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.commands.length} command(s) — Kimi plugins ignore commands`,\n );\n }\n if (connector.subagents.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.subagents.length} subagent(s) — Kimi plugins ignore subagents`,\n );\n }\n if (connector.hookEvents.length > 0) {\n notes.push(\n `kimi-plugin: dropped ${connector.hookEvents.length} hook event(s) — Kimi plugins ignore hooks`,\n );\n }\n\n return { files, pluginDir, ...(notes.length > 0 ? { notes } : {}) };\n};\n","/**\n * core/package-formats/npm — the `npm-plugin` emitter (opencode + kilo-cli + pi).\n *\n * This is the one genuinely NET-NEW artifact: a publishable npm package whose\n * default export is a plugin module. It is emitted ONLY in its clean form — a\n * real package.json + a self-contained ESM `index.js` bridge — never a\n * half-baked stub. The surface limit (documented, and returned as notes) is\n * inherent to the opencode/kilo plugin contract: ONLY hook code rides inside the\n * npm package; commands/skills/subagents are native host dirs and MCP is a\n * config key, so they do NOT ride inside the published module.\n *\n * Layout:\n * <outDir>/<id>/\n * ├── package.json (type:module, exports \".\", keywords incl. \"opencode-plugin\"\n * │ + \"pi-package\", engines.node)\n * ├── index.js (default-export plugin fn; bridges each declared hook event\n * │ to `<homeBin> hook opencode <event> --connector <id>`)\n * ├── skills/<n>/SKILL.md (pi packages DO bundle skills; opencode ignores them)\n * └── README.md\n *\n * The bridge shells out to the ONE stable home binary over child_process, so the\n * SAME universal json-stdio dispatcher every other host uses serves the npm host\n * too — and telemetry continues to flow through the home-bin. (MCP wrapping is\n * NOT inlined here: opencode's MCP is the opencode.json \"mcp\" key, out of band\n * for the npm package; a note records this.)\n */\n\nimport { join } from \"node:path\";\n\nimport type { HookEventName, ResolvedConnector } from \"../types.js\";\nimport { renderSkillMd } from \"../../adapters/claude-code/render.js\";\nimport {\n createEmitter,\n json,\n resolveWithin,\n type EmitContext,\n type FormatEmitter,\n type PackageResult,\n} from \"./shared.js\";\n\n/** OpenCode event keys this connector can bridge (PreToolUse/PostToolUse/SessionStart). */\nconst EVENT_TO_OPENCODE: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n SessionStart: \"experimental.chat.system.transform\",\n};\n\n/** Build the publishable package.json for an opencode/kilo/pi plugin package. */\nfunction buildPackageJson(connector: ResolvedConnector): Record<string, unknown> {\n // Use an opencode- name prefix (the discovery-confirmed convention) so the\n // package is discoverable; keywords cover opencode + pi-package.\n const pkgName = connector.id.startsWith(\"opencode-\")\n ? connector.id\n : `opencode-${connector.id}`;\n const version =\n connector.version && connector.version !== \"0.0.0\" ? connector.version : \"0.0.1\";\n const pkg: Record<string, unknown> = {\n name: pkgName,\n version,\n description: `${connector.displayName} — connector emitted by agent-connector`,\n type: \"module\",\n main: \"index.js\",\n exports: { \".\": \"./index.js\" },\n keywords: [\"opencode\", \"opencode-plugin\", \"pi-package\", \"agent-connector\"],\n // pi reads skills/prompts/themes/extensions from the package.json \"pi\" key.\n pi: { extensions: [\"./index.js\"], skills: [\"./skills\"] },\n engines: { node: \">=18.17\", opencode: \">=1.0.0\" },\n // NOTE: no hardcoded license — this is the DEVELOPER'S publishable package\n // and agent-connector has no authority to license it. The emitter returns a\n // note telling the dev to set license (and author) before `npm publish`.\n };\n if (connector.publish?.author?.name) {\n pkg.author = connector.publish.author.name;\n }\n return pkg;\n}\n\n/** Compose the self-contained ESM plugin bridge (default-export plugin fn). */\nfunction buildIndexJs(connector: ResolvedConnector): string {\n const homeBin = JSON.stringify(\"agent-connector\");\n const connectorId = JSON.stringify(connector.id);\n\n const events = connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_OPENCODE[e] !== undefined,\n );\n const has = (e: HookEventName): boolean => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Publishable OpenCode/Kilo/Pi plugin for connector ${connector.id}. It imports\n * nothing from agent-connector: every hook invocation shells out to the stable\n * home binary's universal entrypoint and JSON-parses the normalized response.\n * Fail-open: any bridge error degrades to \"allow\".\n */\nimport { execFileSync, execSync } from \"node:child_process\";\n\nconst HOME_BIN = ${homeBin};\nconst CONNECTOR_ID = ${connectorId};\n\nfunction bridge(event, payload) {\n try {\n // The published bridge resolves HOME_BIN by bare name via the consumer's\n // PATH, where on Windows it is agent-connector.cmd. Node cannot execFile a\n // .cmd, and shell+args is deprecated (DEP0190), so on Windows run one quoted\n // command line via a shell (cmd.exe applies PATHEXT). POSIX keeps execFile.\n const args = [\"hook\", \"opencode\", event, \"--connector\", CONNECTOR_ID];\n const opts = { input: JSON.stringify(payload), encoding: \"utf8\" };\n const stdout =\n process.platform === \"win32\"\n ? execSync([HOME_BIN, ...args].map((a) => '\"' + a + '\"').join(\" \"), opts)\n : execFileSync(HOME_BIN, args, opts);\n const text = (stdout || \"\").trim();\n if (text === \"\") return { decision: \"allow\" };\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n`;\n\n const handlers: string[] = [];\n if (has(\"PreToolUse\")) {\n handlers.push(` \"tool.execute.before\": async (input, output) => {\n const res = bridge(\"PreToolUse\", {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${connector.id}\");\n }\n if (res.updatedInput && output && output.args) Object.assign(output.args, res.updatedInput);\n },`);\n }\n if (has(\"PostToolUse\")) {\n handlers.push(` \"tool.execute.after\": async (input, output) => {\n const res = bridge(\"PostToolUse\", {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) output.output = res.updatedOutput;\n },`);\n }\n if (has(\"SessionStart\")) {\n handlers.push(` \"experimental.chat.system.transform\": async (input, output) => {\n const res = bridge(\"SessionStart\", {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n });\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n const factory = `\nexport default async function (ctx) {\n const PROJECT_DIR =\n (ctx && (ctx.directory || (ctx.worktree && ctx.worktree.path))) || process.cwd();\n return {\n${handlers.join(\"\\n\")}\n };\n}\n`;\n return header + factory;\n}\n\nexport const emitNpmPlugin: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const { emit, files } = createEmitter(ctx.dryRun);\n const pluginDir = join(ctx.outDir, connector.id);\n const notes: string[] = [];\n\n // ── package.json (publishable) ────────────────────────────────────────────\n emit(join(pluginDir, \"package.json\"), json(buildPackageJson(connector)));\n\n // ── index.js (the default-export plugin bridge) ───────────────────────────\n emit(join(pluginDir, \"index.js\"), buildIndexJs(connector));\n\n // ── skills/<name>/SKILL.md (+ resources) — pi bundles skills ──────────────\n for (const skill of connector.skills) {\n const skillDir = join(pluginDir, \"skills\", skill.name);\n emit(join(skillDir, \"SKILL.md\"), renderSkillMd(skill));\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = resolveWithin(skillDir, rel);\n if (target === null) continue;\n emit(target, contents);\n }\n }\n\n // ── README.md ─────────────────────────────────────────────────────────────\n emit(\n join(pluginDir, \"README.md\"),\n `# ${connector.displayName}\\n\\nOpenCode / Kilo / Pi plugin package emitted by agent-connector.\\n\\n` +\n \"Install with `opencode plugin install <pkg>` / `kilo plugin <pkg>` / `pi install <pkg>`.\\n\\n\" +\n \"Local install (no npm publish needed — live-verified on opencode 1.17.0 / kilo 7.3.16):\\n\" +\n \"`opencode plugin --global file:///<abs-dir>` or `kilo plugin --global file:///<abs-dir>`\\n\" +\n \"(bare absolute paths work too; the entry lands in the config `plugin` array —\\n\" +\n \"there is no uninstall verb, remove it by editing that array).\\n\\n\" +\n \"## Prerequisite\\n\\n\" +\n \"Hooks shell out to the `agent-connector` CLI resolved from the consumer's PATH —\\n\" +\n \"the consumer machine needs `npm i -g @ken-jo/agent-connector` (hooks silently no-op,\\n\" +\n \"fail-open, without it).\\n\\n\" +\n \"## Before you publish\\n\\n\" +\n \"The emitted package.json carries **no `license` and no `author`** unless your\\n\" +\n \"connector declared `publish.author` — set them to YOUR terms before `npm publish`.\\n\",\n );\n\n // The published bridge resolves the CLI by bare name on the consumer's PATH.\n notes.push(\n \"npm-plugin: hooks require `npm i -g @ken-jo/agent-connector` on the consumer machine (bridge resolves the CLI by name on PATH; silently fail-open without it)\",\n );\n notes.push(\n \"npm-plugin: set license/author in the emitted package.json before `npm publish` — agent-connector does not license your plugin for you\",\n );\n\n // Surface the inherent limits of the npm-plugin contract.\n if (connector.commands.length > 0) {\n notes.push(\n `npm-plugin: ${connector.commands.length} command(s) NOT bundled — opencode/kilo commands are native host dirs`,\n );\n }\n if (connector.subagents.length > 0) {\n notes.push(\n `npm-plugin: ${connector.subagents.length} subagent(s) NOT bundled — opencode/kilo subagents are native host dirs`,\n );\n }\n if (connector.server) {\n notes.push(\n `npm-plugin: MCP server NOT bundled inside the package — register it via the opencode.json \"mcp\" key`,\n );\n }\n\n return { files, pluginDir, ...(notes.length > 0 ? { notes } : {}) };\n};\n","/**\n * core/package-formats/mcp-server — emit an official MCP Registry `server.json`.\n *\n * Unlike the host plugin/marketplace bundles, server.json is a DISCOVERY +\n * PUBLISH artifact: it describes the developer's REAL upstream MCP server (what\n * a registry installer runs DIRECTLY), so it must NOT carry agent-connector's\n * `serve` telemetry wrapper. It is emitted from the connector's `publish`\n * metadata (the namespace the dev proved ownership of + their published package)\n * and conforms to the pinned 2025-12-11 schema:\n * • name = `${publish.registryNamespace}/${connector.id}` (one '/', regex-checked)\n * • version = concrete SemVer (ranges are rejected by the registry)\n * • stdio → packages[] { registryType:\"npm\", identifier:<dev pkg>, transport:{type:\"stdio\"} }\n * • remote → remotes[] { type:\"streamable-http\"|\"sse\", url, headers }\n * • token env vars are marked isSecret.\n *\n * agent-connector EMITS a conformant server.json; the dev runs the publish-time\n * ownership proof + upload themselves with the official `mcp-publisher` CLI.\n */\n\nimport { resolve } from \"node:path\";\n\nimport type { ResolvedConnector, ServerDef } from \"../types.js\";\nimport {\n MCP_SERVER_SCHEMA_URL,\n NPM_REGISTRY_BASE_URL,\n REGISTRY_NAME_RE,\n isConcreteSemver,\n isPlaceholderVersion,\n registryTransportType,\n} from \"../mcp-standard.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./shared.js\";\nimport { createEmitter, json } from \"./shared.js\";\n\n/** A server.json KeyValueInput (environmentVariables[] / headers[] entry). */\ninterface KeyValueInput {\n name: string;\n isSecret?: boolean;\n isRequired?: boolean;\n}\n\n/** Build environmentVariables[] from a stdio ServerDef, marking the bearer token secret. */\nfunction buildEnvVars(server: ServerDef): KeyValueInput[] {\n const vars: KeyValueInput[] = [];\n const byName = new Map<string, KeyValueInput>();\n for (const key of Object.keys(server.env ?? {})) {\n const v: KeyValueInput = { name: key };\n vars.push(v);\n byName.set(key, v);\n }\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n const name = server.auth.bearerEnvVar;\n const existing = byName.get(name);\n if (existing) {\n existing.isSecret = true;\n existing.isRequired = true;\n } else {\n vars.push({ name, isSecret: true, isRequired: true });\n }\n }\n return vars;\n}\n\n/** Build the conformant server.json object (throws a clear error on missing inputs). */\nfunction buildServerJson(\n connector: ResolvedConnector,\n notes: string[],\n): Record<string, unknown> {\n const publish = connector.publish ?? {};\n\n if (!publish.registryNamespace) {\n throw new Error(\n 'package --format mcp-server-json needs publish.registryNamespace — a reverse-DNS ' +\n 'namespace you OWN (e.g. \"io.github.<your-handle>\" or \"com.<your-domain>\"). ' +\n \"agent-connector never publishes under a namespace it owns; set it in your connector config.\",\n );\n }\n const name = `${publish.registryNamespace}/${connector.id}`;\n if (!REGISTRY_NAME_RE.test(name)) {\n throw new Error(\n `server.json name \"${name}\" must match ${REGISTRY_NAME_RE} (exactly one \"/\").`,\n );\n }\n if (!isConcreteSemver(connector.version)) {\n throw new Error(\n `server.json version must be a concrete SemVer (the registry rejects ranges); got \"${connector.version}\".`,\n );\n }\n if (isPlaceholderVersion(connector.version)) {\n notes.push(\n 'version is the unset placeholder \"0.0.0\" — set a real version before publishing to the registry.',\n );\n }\n\n const out: Record<string, unknown> = {\n $schema: MCP_SERVER_SCHEMA_URL,\n name,\n description: connector.displayName,\n version: connector.version,\n };\n\n const server = connector.server;\n if (!server) {\n notes.push(\n \"connector declares no server — emitted server.json carries neither packages nor remotes \" +\n \"(a hooks/commands-only connector is not a registry server).\",\n );\n return out;\n }\n\n const tt = registryTransportType(server.transport);\n if (tt === null) {\n notes.push(\n `transport \"${server.transport}\" is not an MCP spec transport and cannot be represented in ` +\n \"server.json; emitted server metadata without a package/remote entry.\",\n );\n return out;\n }\n\n if (server.transport === \"stdio\") {\n if (!publish.packageName) {\n throw new Error(\n \"package --format mcp-server-json needs publish.packageName — your REAL published npm \" +\n 'package that runs the MCP server (e.g. \"@acme/acme-db-mcp\"). The registry runs that ' +\n \"package directly, not agent-connector's serve wrapper.\",\n );\n }\n const pkg: Record<string, unknown> = {\n registryType: \"npm\",\n registryBaseUrl: publish.registryBaseUrl ?? NPM_REGISTRY_BASE_URL,\n identifier: publish.packageName,\n version: connector.version,\n transport: { type: \"stdio\" },\n };\n const envVars = buildEnvVars(server);\n if (envVars.length > 0) pkg.environmentVariables = envVars;\n out.packages = [pkg];\n } else {\n // streamable-http | sse → remotes[]\n const remote: Record<string, unknown> = { type: tt, url: server.url };\n const headers = Object.keys(server.headers ?? {}).map((k): KeyValueInput => ({ name: k }));\n if (headers.length > 0) remote.headers = headers;\n if (server.auth && server.auth.type !== \"none\") {\n notes.push(\n `remote server uses auth \"${server.auth.type}\" — add the credential header (isSecret) to ` +\n \"the emitted remotes[].headers before publishing.\",\n );\n }\n out.remotes = [remote];\n }\n\n return out;\n}\n\n/** Emit a registry-conformant server.json for `connector` into ctx.outDir. */\nexport const emitMcpServerJson: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const emitter = createEmitter(ctx.dryRun);\n const notes: string[] = [];\n const serverJson = buildServerJson(connector, notes);\n const path = resolve(ctx.outDir, \"server.json\");\n emitter.emit(path, json(serverJson));\n return {\n files: emitter.files,\n pluginDir: ctx.outDir,\n ...(notes.length > 0 ? { notes } : {}),\n };\n};\n","/**\n * core/package-formats/mcpb — emit an MCPB (.mcpb, formerly DXT) bundle manifest.\n *\n * MCPB is the official cross-client one-click LOCAL-install bundle (Claude\n * Desktop + any MCPB host). A real .mcpb is a SELF-CONTAINED zip (manifest.json\n * + the server + vendored node_modules), which agent-connector cannot assemble\n * at emit time — we do not have the developer's built server tree. So, per the\n * conformance analysis, we emit a CONFORMANT manifest.json describing a\n * self-contained node bundle (NOT an out-of-spec `npx` command-reference, which\n * would assume network + node on PATH at launch and break offline/signing) plus\n * a packaging RECIPE, and leave the `mcpb pack`/`mcpb sign` to the developer —\n * mirroring how server.json defers the publish-time ownership proof.\n *\n * Secrets (the bearer token / sensitive env) are routed through `user_config`\n * (sensitive:true) and referenced as `${user_config.<key>}` in mcp_config.env,\n * so credentials are collected by the host keychain, never inlined.\n */\n\nimport { resolve } from \"node:path\";\n\nimport type { ResolvedConnector, ServerDef } from \"../types.js\";\nimport {\n MCPB_MANIFEST_VERSION,\n isConcreteSemver,\n isPlaceholderVersion,\n} from \"../mcp-standard.js\";\nimport type { EmitContext, FormatEmitter, PackageResult } from \"./shared.js\";\nimport { createEmitter, json } from \"./shared.js\";\n\n/** \"ACME_DB_TOKEN\" → \"Acme Db Token\" for a user_config field title. */\nfunction titleize(s: string): string {\n return s\n .toLowerCase()\n .split(/[_-]+/)\n .filter(Boolean)\n .map((w) => w[0]!.toUpperCase() + w.slice(1))\n .join(\" \");\n}\n\n/** The names of env vars that hold secrets (the bearer token). */\nfunction secretEnvNames(server: ServerDef): Set<string> {\n const names = new Set<string>();\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n names.add(server.auth.bearerEnvVar);\n }\n return names;\n}\n\nfunction recipeReadme(connector: ResolvedConnector): string {\n return `# ${connector.displayName} — MCPB bundle\n\n\\`agent-connector package --format mcpb\\` emitted the conformant **manifest.json**\n(manifest_version ${MCPB_MANIFEST_VERSION}) for this connector. It does NOT build\nthe \\`.mcpb\\` zip — that step vendors your server and is yours to run, so the\nbundle stays self-contained and signable.\n\n## Finish the bundle\n\n1. Put your built, self-contained MCP server at \\`server/index.js\\`\n (the manifest's \\`entry_point\\` / \\`mcp_config\\`).\n2. Vendor production dependencies into the bundle:\n\n \\`\\`\\`bash\n cd server && npm install --omit=dev && cd ..\n \\`\\`\\`\n\n3. Pack (and optionally sign) with the official MCPB CLI:\n\n \\`\\`\\`bash\n npx @anthropic-ai/mcpb pack . # → ${connector.id}.mcpb\n npx @anthropic-ai/mcpb sign ${connector.id}.mcpb\n \\`\\`\\`\n\nThe resulting \\`.mcpb\\` installs one-click into Claude Desktop and any MCPB host.\nSecrets are declared under \\`user_config\\` and collected by the host keychain at\ninstall time — never inline them in the manifest.\n`;\n}\n\n/** Emit a conformant MCPB manifest.json + packaging recipe for `connector`. */\nexport const emitMcpbBundle: FormatEmitter = (\n connector: ResolvedConnector,\n ctx: EmitContext,\n): PackageResult => {\n const publish = connector.publish ?? {};\n if (!publish.author?.name) {\n throw new Error(\n \"package --format mcpb needs publish.author.name — the MCPB manifest requires an author.\",\n );\n }\n if (!isConcreteSemver(connector.version)) {\n throw new Error(\n `mcpb manifest version must be a concrete SemVer; got \"${connector.version}\".`,\n );\n }\n\n const server = connector.server;\n if (!server) {\n throw new Error(\"package --format mcpb needs a server (an MCPB bundle packages an MCP server).\");\n }\n if (server.transport !== \"stdio\") {\n throw new Error(\n `package --format mcpb supports stdio servers; \"${server.transport}\" is a remote server — ` +\n \"publish it via the registry (--format mcp-server-json) instead.\",\n );\n }\n\n const notes: string[] = [];\n if (isPlaceholderVersion(connector.version)) {\n notes.push('version is the unset placeholder \"0.0.0\" — set a real version before packing.');\n }\n\n // Route secret env vars through user_config; pass the rest through verbatim.\n const secrets = secretEnvNames(server);\n const env: Record<string, string> = {};\n const userConfig: Record<string, Record<string, unknown>> = {};\n for (const [k, v] of Object.entries(server.env ?? {})) {\n if (secrets.has(k)) {\n const key = k.toLowerCase();\n userConfig[key] = {\n type: \"string\",\n title: titleize(k),\n description: `Value for ${k}`,\n sensitive: true,\n required: true,\n };\n env[k] = `\\${user_config.${key}}`;\n } else {\n env[k] = v;\n }\n }\n // A bearer-token env not already present in server.env still needs a field.\n for (const name of secrets) {\n if (!(name in env)) {\n const key = name.toLowerCase();\n userConfig[key] = {\n type: \"string\",\n title: titleize(name),\n description: `Value for ${name}`,\n sensitive: true,\n required: true,\n };\n env[name] = `\\${user_config.${key}}`;\n }\n }\n\n const author: Record<string, string> = { name: publish.author.name };\n if (publish.author.email) author.email = publish.author.email;\n if (publish.author.url) author.url = publish.author.url;\n\n const mcpConfig: Record<string, unknown> = {\n command: \"node\",\n args: [\"${__dirname}/server/index.js\"],\n };\n if (Object.keys(env).length > 0) mcpConfig.env = env;\n\n const manifest: Record<string, unknown> = {\n manifest_version: MCPB_MANIFEST_VERSION,\n name: connector.id,\n version: connector.version,\n description: connector.displayName,\n author,\n server: {\n type: \"node\",\n entry_point: \"server/index.js\",\n mcp_config: mcpConfig,\n },\n };\n if (Object.keys(userConfig).length > 0) manifest.user_config = userConfig;\n\n // If the dev's real command is not node-ish, the node template needs adjusting.\n if (server.command && !/\\b(node|npx)\\b/.test(server.command)) {\n notes.push(\n `your server command is \"${server.command}\" — the emitted manifest assumes a node ` +\n \"server (server.type:node); adjust server.type/entry_point for your runtime (python|binary).\",\n );\n }\n notes.push(\n \"emitted manifest.json + README recipe; this format does NOT build the .mcpb zip. \" +\n \"Place your self-contained server at server/index.js, vendor deps, then run `mcpb pack` (see README).\",\n );\n\n const emitter = createEmitter(ctx.dryRun);\n emitter.emit(resolve(ctx.outDir, \"manifest.json\"), json(manifest));\n emitter.emit(resolve(ctx.outDir, \"README.md\"), recipeReadme(connector));\n return { files: emitter.files, pluginDir: ctx.outDir, notes };\n};\n"],"mappings":"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","names":["existsSync","join","resolve","join","buildManifest","buildMarketplace","join","join","SPECS","buildManifest","join","join","PLATFORM","buildManifest","join","join","PLATFORM","buildManifest","join","join","join","resolve","resolve","resolve","resolve","resolve","join"]}
@@ -1,70 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // src/adapters/claude-code/render.ts
4
- import { stringify as stringifyYaml } from "yaml";
5
- function renderFrontmatterMd(frontmatter, body) {
6
- return `---
7
- ${stringifyYaml(frontmatter)}---
8
-
9
- ${body}
10
- `;
11
- }
12
- function renderCommandMd(cmd, opts = {}) {
13
- const { includeToolsAndModel = true } = opts;
14
- const frontmatter = {};
15
- if (cmd.description !== void 0) frontmatter.description = cmd.description;
16
- if (cmd.argumentHint !== void 0) frontmatter["argument-hint"] = cmd.argumentHint;
17
- if (includeToolsAndModel) {
18
- const allow = cmd.tools?.allow;
19
- if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
20
- if (cmd.model !== void 0) frontmatter.model = cmd.model;
21
- }
22
- if (cmd.extra) Object.assign(frontmatter, cmd.extra);
23
- return renderFrontmatterMd(frontmatter, cmd.prompt);
24
- }
25
- function renderSkillMd(skill) {
26
- const frontmatter = {
27
- name: skill.name,
28
- description: skill.description
29
- };
30
- if (skill.model !== void 0) frontmatter.model = skill.model;
31
- const allow = skill.tools?.allow;
32
- if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
33
- if (skill.disableModelInvocation !== void 0) {
34
- frontmatter["disable-model-invocation"] = skill.disableModelInvocation;
35
- }
36
- if (skill.extra) Object.assign(frontmatter, skill.extra);
37
- return renderFrontmatterMd(frontmatter, skill.body);
38
- }
39
- function renderSubagentMd(agent) {
40
- const frontmatter = {
41
- name: agent.name,
42
- description: agent.description
43
- };
44
- const allow = agent.tools?.allow;
45
- if (allow && allow.length > 0) frontmatter.tools = allow.join(", ");
46
- if (agent.model !== void 0) frontmatter.model = agent.model;
47
- if (agent.extra) Object.assign(frontmatter, agent.extra);
48
- return renderFrontmatterMd(frontmatter, agent.prompt);
49
- }
50
- function renderOpenCodeSubagentMd(agent) {
51
- const frontmatter = {
52
- description: agent.description,
53
- mode: "subagent"
54
- };
55
- if (agent.model !== void 0) frontmatter.model = agent.model;
56
- if (agent.readonly === true) {
57
- frontmatter.permission = { edit: "deny", bash: "deny" };
58
- }
59
- if (agent.extra) Object.assign(frontmatter, agent.extra);
60
- return renderFrontmatterMd(frontmatter, agent.prompt);
61
- }
62
-
63
- export {
64
- renderFrontmatterMd,
65
- renderCommandMd,
66
- renderSkillMd,
67
- renderSubagentMd,
68
- renderOpenCodeSubagentMd
69
- };
70
- //# sourceMappingURL=chunk-IEGR4TP3.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/claude-code/render.ts"],"sourcesContent":["/**\n * adapters/claude-code/render — shared content-surface renderers.\n *\n * The single source of truth for how a connector's commands / skills / subagents\n * are serialized into Claude Code's native `md + YAML-frontmatter` documents.\n * BOTH the live claude-code adapter (which writes into ~/.claude or .claude when\n * installing) AND `core/package` (which emits a marketplace-installable plugin\n * bundle) import these so the two paths produce BYTE-IDENTICAL output — there is\n * no second, subtly-different copy to drift.\n *\n * The frontmatter serializer reuses the `yaml` package (the same serializer\n * core/yaml and BaseAdapter.renderFrontmatterMd use): a `---` fence, the YAML\n * block, a closing `---`, a blank line, then the markdown body and a trailing\n * newline.\n */\n\nimport { stringify as stringifyYaml } from \"yaml\";\n\nimport type { CommandDef, SkillDef, SubagentDef } from \"../../core/types.js\";\n\n/**\n * Render a YAML-frontmatter + markdown body document:\n * \"---\\n\" + <yaml> + \"---\\n\\n\" + <body> + \"\\n\".\n * Identical to BaseAdapter.renderFrontmatterMd (which now delegates here).\n */\nexport function renderFrontmatterMd(\n frontmatter: Record<string, unknown>,\n body: string,\n): string {\n return `---\\n${stringifyYaml(frontmatter)}---\\n\\n${body}\\n`;\n}\n\n/**\n * Render a command to md+frontmatter\n * (description, argument-hint, allowed-tools, model + verbatim extra).\n *\n * `opts.includeToolsAndModel` (default `true`) controls the allowed-tools and\n * model insertions. Hosts whose command frontmatter is only\n * (description, argument-hint + verbatim extra) — i.e. they have no native\n * allowed-tools/model keys — pass `{ includeToolsAndModel: false }` to suppress\n * both; the default reproduces the full shape byte-for-byte.\n */\nexport function renderCommandMd(\n cmd: CommandDef,\n opts: { includeToolsAndModel?: boolean } = {},\n): string {\n const { includeToolsAndModel = true } = opts;\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n if (cmd.argumentHint !== undefined) frontmatter[\"argument-hint\"] = cmd.argumentHint;\n if (includeToolsAndModel) {\n const allow = cmd.tools?.allow;\n if (allow && allow.length > 0) frontmatter[\"allowed-tools\"] = allow.join(\", \");\n if (cmd.model !== undefined) frontmatter.model = cmd.model;\n }\n if (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return renderFrontmatterMd(frontmatter, cmd.prompt);\n}\n\n/**\n * Render a skill's SKILL.md: frontmatter (name, description + optional model,\n * allowed-tools, disable-model-invocation, verbatim extra) + body.\n */\nexport function renderSkillMd(skill: SkillDef): string {\n const frontmatter: Record<string, unknown> = {\n name: skill.name,\n description: skill.description,\n };\n if (skill.model !== undefined) frontmatter.model = skill.model;\n const allow = skill.tools?.allow;\n if (allow && allow.length > 0) frontmatter[\"allowed-tools\"] = allow.join(\", \");\n if (skill.disableModelInvocation !== undefined) {\n frontmatter[\"disable-model-invocation\"] = skill.disableModelInvocation;\n }\n if (skill.extra) Object.assign(frontmatter, skill.extra);\n return renderFrontmatterMd(frontmatter, skill.body);\n}\n\n/** Render a subagent to md+frontmatter (name, description, tools, model) + prompt body. */\nexport function renderSubagentMd(agent: SubagentDef): string {\n const frontmatter: Record<string, unknown> = {\n name: agent.name,\n description: agent.description,\n };\n const allow = agent.tools?.allow;\n if (allow && allow.length > 0) frontmatter.tools = allow.join(\", \");\n if (agent.model !== undefined) frontmatter.model = agent.model;\n if (agent.extra) Object.assign(frontmatter, agent.extra);\n return renderFrontmatterMd(frontmatter, agent.prompt);\n}\n\n/**\n * Render a subagent in OpenCode's shape (shared by opencode/kilo/mimo-code):\n * frontmatter (description, mode:\"subagent\", model?, permission? + verbatim\n * extra) with the system prompt as the body. `name` is NOT a frontmatter\n * field — it comes from the filename. `permission` is derived from the coarse\n * `readonly` knob: a readonly agent gets a per-tool deny map (edit/bash) so it\n * cannot mutate the workspace.\n */\nexport function renderOpenCodeSubagentMd(agent: SubagentDef): string {\n const frontmatter: Record<string, unknown> = {\n description: agent.description,\n mode: \"subagent\",\n };\n if (agent.model !== undefined) frontmatter.model = agent.model;\n if (agent.readonly === true) {\n // Per-tool permission map: deny mutating tools for a readonly subagent.\n frontmatter.permission = { edit: \"deny\", bash: \"deny\" };\n }\n if (agent.extra) Object.assign(frontmatter, agent.extra);\n return renderFrontmatterMd(frontmatter, agent.prompt);\n}\n"],"mappings":";;;AAgBA,SAAS,aAAa,qBAAqB;AASpC,SAAS,oBACd,aACA,MACQ;AACR,SAAO;AAAA,EAAQ,cAAc,WAAW,CAAC;AAAA;AAAA,EAAU,IAAI;AAAA;AACzD;AAYO,SAAS,gBACd,KACA,OAA2C,CAAC,GACpC;AACR,QAAM,EAAE,uBAAuB,KAAK,IAAI;AACxC,QAAM,cAAuC,CAAC;AAC9C,MAAI,IAAI,gBAAgB,OAAW,aAAY,cAAc,IAAI;AACjE,MAAI,IAAI,iBAAiB,OAAW,aAAY,eAAe,IAAI,IAAI;AACvE,MAAI,sBAAsB;AACxB,UAAM,QAAQ,IAAI,OAAO;AACzB,QAAI,SAAS,MAAM,SAAS,EAAG,aAAY,eAAe,IAAI,MAAM,KAAK,IAAI;AAC7E,QAAI,IAAI,UAAU,OAAW,aAAY,QAAQ,IAAI;AAAA,EACvD;AACA,MAAI,IAAI,MAAO,QAAO,OAAO,aAAa,IAAI,KAAK;AACnD,SAAO,oBAAoB,aAAa,IAAI,MAAM;AACpD;AAMO,SAAS,cAAc,OAAyB;AACrD,QAAM,cAAuC;AAAA,IAC3C,MAAM,MAAM;AAAA,IACZ,aAAa,MAAM;AAAA,EACrB;AACA,MAAI,MAAM,UAAU,OAAW,aAAY,QAAQ,MAAM;AACzD,QAAM,QAAQ,MAAM,OAAO;AAC3B,MAAI,SAAS,MAAM,SAAS,EAAG,aAAY,eAAe,IAAI,MAAM,KAAK,IAAI;AAC7E,MAAI,MAAM,2BAA2B,QAAW;AAC9C,gBAAY,0BAA0B,IAAI,MAAM;AAAA,EAClD;AACA,MAAI,MAAM,MAAO,QAAO,OAAO,aAAa,MAAM,KAAK;AACvD,SAAO,oBAAoB,aAAa,MAAM,IAAI;AACpD;AAGO,SAAS,iBAAiB,OAA4B;AAC3D,QAAM,cAAuC;AAAA,IAC3C,MAAM,MAAM;AAAA,IACZ,aAAa,MAAM;AAAA,EACrB;AACA,QAAM,QAAQ,MAAM,OAAO;AAC3B,MAAI,SAAS,MAAM,SAAS,EAAG,aAAY,QAAQ,MAAM,KAAK,IAAI;AAClE,MAAI,MAAM,UAAU,OAAW,aAAY,QAAQ,MAAM;AACzD,MAAI,MAAM,MAAO,QAAO,OAAO,aAAa,MAAM,KAAK;AACvD,SAAO,oBAAoB,aAAa,MAAM,MAAM;AACtD;AAUO,SAAS,yBAAyB,OAA4B;AACnE,QAAM,cAAuC;AAAA,IAC3C,aAAa,MAAM;AAAA,IACnB,MAAM;AAAA,EACR;AACA,MAAI,MAAM,UAAU,OAAW,aAAY,QAAQ,MAAM;AACzD,MAAI,MAAM,aAAa,MAAM;AAE3B,gBAAY,aAAa,EAAE,MAAM,QAAQ,MAAM,OAAO;AAAA,EACxD;AACA,MAAI,MAAM,MAAO,QAAO,OAAO,aAAa,MAAM,KAAK;AACvD,SAAO,oBAAoB,aAAa,MAAM,MAAM;AACtD;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/codex/index.ts"],"sourcesContent":["/**\n * adapters/codex — Codex CLI platform adapter for agent-connector.\n *\n * Codex CLI hook paradigm is \"json-stdio\": the host pipes a JSON payload to a\n * command on stdin and reads JSON/exit-code back — the same wire protocol as\n * Claude Code (PascalCase fields, `hookSpecificOutput` reply wrapper).\n *\n * Two native config files live under the Codex config dir\n * (`$CODEX_HOME` || `~/.codex`, mirrored to `<projectDir>/.codex` for project\n * scope):\n * - config.toml → `[mcp_servers.<id>]` MCP registration (TOML, NO native\n * interpolation, so env-refs are resolved to literals at install time).\n * - hooks.json → Claude-compatible hook registration ({ matcher, hooks }).\n *\n * Grounded in context-mode's proven Codex adapter (configs/codex/{config.toml,\n * hooks.json}, src/adapters/codex/*) — exact TOML MCP shape + hook JSON schema.\n *\n * Known Codex limitations (upstream): PreToolUse deny works but updatedInput is\n * not yet honored (openai/codex#18491); PostToolUse updatedMCPToolOutput is\n * parsed-but-unsupported — hence canModifyArgs / canModifyOutput are false.\n *\n * E1 extension events (verified against developers.openai.com/codex/hooks):\n * - PermissionRequest — native, decision-capable via the nested\n * hookSpecificOutput.decision{behavior:\"allow\"|\"deny\", message?} envelope.\n * Codex docs: updatedInput / updatedPermissions / interrupt FAIL CLOSED on\n * this event, so they are never emitted here.\n * - SubagentStart — native; hookSpecificOutput.additionalContext is injected\n * as developer context for the subagent (not blockable).\n * - SubagentStop — native; the documented continuation shape is the TOP-LEVEL\n * {\"decision\":\"block\",\"reason\"} (Stop semantics: keeps the subagent going).\n * - PostToolUseFailure — NO Codex analog (PostToolUse only); declared hooks\n * for it warn-skip at install and the capability flag stays unset.\n * - PostCompact — native (Codex's hook system fires both PreCompact and\n * PostCompact); observe-only, normalizing the `trigger` (manual|auto)\n * exactly like PreCompact, with a passthrough formatReply.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\n\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n SkillDef,\n SubagentDef,\n} from \"../../core/types.js\";\nimport { ensureDir } from \"../../core/paths.js\";\nimport { codexConfigHome } from \"../../core/host-paths.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n removeFromObjectMap,\n upsertInObjectMap,\n type ObjectMapCodec,\n} from \"../../core/object-map.js\";\nimport { writeTomlString } from \"../../core/toml.js\";\nimport {\n buildHomeBinHookCommand,\n buildWrappedStdio,\n} from \"../../core/spawn.js\";\nimport { renderCommandMd, renderSkillMd } from \"../claude-code/render.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\nimport { BaseAdapter, type HookMergeDescriptor } from \"../base.js\";\nimport type {\n HookReply,\n InstallContext,\n MemoryTarget,\n NormalizedEvent,\n} from \"../spi.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Native shapes\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Raw Codex hook payload (PascalCase event, snake_case fields — Claude-style). */\ninterface CodexHookInput {\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: string;\n session_id?: string;\n cwd?: string;\n hook_event_name?: string;\n source?: string;\n prompt?: string;\n is_error?: boolean;\n stop_hook_active?: boolean;\n trigger?: string;\n message?: string;\n // PostToolUseFailure-style failure field. Codex has NO failure event today;\n // parsed defensively only (the Claude-compatible wire would carry it).\n error?: string;\n // SubagentStart / SubagentStop (agent_type is the matcher subject).\n agent_id?: string;\n agent_type?: string;\n // SubagentStop only — the subagent's own transcript + final message.\n agent_transcript_path?: string;\n last_assistant_message?: string;\n}\n\n/** One hook entry inside hooks.json (Claude-compatible). */\ninterface CodexHookEntry {\n matcher?: string;\n hooks: Array<{ type: \"command\"; command: string }>;\n}\n\n/** Rendered `[mcp_servers.<id>]` table — string env table, no interpolation. */\ninterface CodexMcpEntry {\n // stdio transport\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n // streamable HTTP transport (remote): codex infers the transport from `url`\n // (no explicit transport key). Verified against codex-cli 0.139.0.\n url?: string;\n bearer_token_env_var?: string;\n http_headers?: Record<string, string>;\n}\n\n/**\n * Codex hook events agent-connector registers, in the canonical → native order.\n * Codex uses the same PascalCase event names as Claude Code; the home-binary\n * hook command receives the lowercased event token.\n */\nconst CODEX_HOOK_EVENTS = [\n \"SessionStart\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"UserPromptSubmit\",\n \"Stop\",\n \"PermissionRequest\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PostCompact\",\n] as const;\n\ntype CodexHookEventName = (typeof CODEX_HOOK_EVENTS)[number];\n\n/**\n * Newer canonical events with NO Codex analog: Codex ships PostToolUse only —\n * there is no failure event on the live hooks page. Declared hooks for these\n * warn-skip at install so the degradation is reported, never silent. (The\n * legacy SessionEnd / Notification silent filter predates this convention and\n * is deliberately left untouched.)\n */\nconst WARN_SKIP_EVENTS: ReadonlySet<HookEventName> = new Set([\"PostToolUseFailure\"]);\n\n/**\n * PreToolUse matcher — canonical Codex tool names + bare MCP tool names +\n * external MCP catch-all literal. Charset-clean ([A-Za-z0-9_|] only) so Codex's\n * Rust `regex` exact-matcher short-circuits (no look-around, which Codex\n * rejects at boot). Copied from context-mode's proven matcher.\n */\nconst PRE_TOOL_USE_MATCHER =\n \"local_shell|shell|shell_command|exec_command|Bash|Shell|apply_patch|Edit|Write|grep_files|mcp__\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Adapter\n// ─────────────────────────────────────────────────────────────────────────\n\nexport class CodexAdapter extends BaseAdapter {\n readonly id: PlatformId = \"codex\";\n readonly name = \"Codex CLI\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block. memoryTargets below probes\n // AGENTS.override.md first (it shadows AGENTS.md per directory on codex).\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: true,\n stop: true,\n notification: false,\n // E1 events: PermissionRequest (decision-capable) + SubagentStart/Stop are\n // Codex-native. postToolUseFailure stays unset — Codex has no failure event,\n // so a declared hook for it warn-skips at install.\n permissionRequest: true,\n subagentStart: true,\n subagentStop: true,\n // PostCompact: Codex's hook system fires both PreCompact and PostCompact\n // (developers.openai.com/codex/hooks). Observational only — the reply\n // contract mirrors PreCompact (cannot block/modify a completed compaction).\n postCompact: true,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n transports: [\"stdio\", \"http\"],\n // Content surfaces: Codex implements all three.\n // command → ~/.codex/prompts/<name>.md (md+frontmatter, USER SCOPE ONLY)\n // skill → project: .codex/skills/<name>/SKILL.md · user: ~/.agents/skills/<name>/SKILL.md\n // subagent → <codexDir>/agents/<name>.toml (TOML)\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ──────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = this.userConfigDir();\n const projDir = join(projectDir, \".codex\");\n const userCfg = join(userDir, \"config.toml\");\n const projCfg = join(projDir, \"config.toml\");\n\n const userInstalled = existsSync(userDir) || existsSync(userCfg);\n const projInstalled = existsSync(projDir) || existsSync(projCfg);\n const installed = userInstalled || projInstalled;\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projCfg : userCfg;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? `Found Codex config dir (${scope})`\n : `No .codex config dir at ${userDir} or ${projDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n override getConfigDir(ctx: InstallContext): string {\n if (ctx.scope === \"project\") return join(ctx.projectDir, \".codex\");\n return this.userConfigDir();\n }\n\n override getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"config.toml\");\n }\n\n override getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"hooks.json\");\n }\n\n // ── Memory surface: AGENTS.override.md probe + 32 KiB doc-cap budget ─────\n // Codex reads AGENTS.override.md > AGENTS.md per directory (one file per\n // directory), so when the override file exists OUR block must live there or\n // it is never loaded. Combined project docs are capped at 32 KiB\n // (`project_doc_max_bytes`), hence the ~28 KiB per-file budget warn.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n // An explicit path override keeps the base resolution (escape hatch wins).\n if (this.memoryOverride(ctx)?.path) return super.memoryTargets(ctx);\n if (ctx.scope !== \"project\" && ctx.scope !== \"user\") return [];\n const budgetBytes = 28 * 1024;\n const dir = ctx.scope === \"project\" ? ctx.projectDir : this.userConfigDir();\n const overrideMd = join(dir, \"AGENTS.override.md\");\n if (existsSync(overrideMd)) {\n return [\n {\n path: overrideMd,\n reason: \"AGENTS.override.md shadows AGENTS.md on codex (one doc per directory)\",\n budgetBytes,\n },\n ];\n }\n return [\n {\n path: join(dir, \"AGENTS.md\"),\n reason:\n ctx.scope === \"project\"\n ? \"AGENTS.md standard (project root; codex is the format's originator)\"\n : \"codex global guidance ($CODEX_HOME/AGENTS.md)\",\n budgetBytes,\n },\n ];\n }\n\n /** `$CODEX_HOME` (tilde-expanded, then resolved) || `~/.codex` for user\n * scope. Shared with marketplace detection via `codexConfigHome` so the\n * config writer and the install probe never target different dirs. */\n private userConfigDir(): string {\n return codexConfigHome();\n }\n\n // ── TOML config IO (override JSON helpers — config.toml is TOML) ─────────\n\n private readToml(path: string): Record<string, unknown> {\n if (!existsSync(path)) return {};\n try {\n return TOML.parse(readFileSync(path, \"utf8\")) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n\n private writeToml(path: string, data: Record<string, unknown>, dryRun: boolean): void {\n if (dryRun) return;\n ensureDir(dirname(path));\n // @iarna/toml's stringify type wants its JsonMap; our object is structurally compatible.\n writeFileSync(path, TOML.stringify(data as never), \"utf8\");\n }\n\n /** An ObjectMapCodec over config.toml for the core/object-map engine.\n * `isPresentButUnparseable` is `() => false`: readToml fail-softs to {} and the\n * server path has historically coerced/overwritten rather than warn-skip on an\n * unparseable file — preserved here for byte-identical behavior. */\n private tomlObjectMapCodec(): ObjectMapCodec {\n return {\n parse: (path) => this.readToml(path),\n serialize: (path, data, dryRun) => this.writeToml(path, data, dryRun),\n isPresentButUnparseable: () => false,\n };\n }\n\n // ── Install server (config.toml → [mcp_servers.<id>]) ───────────────────\n\n override installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const server = this.effectiveServer(ctx);\n const path = this.getServerConfigPath(ctx);\n\n if (!server) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no server declared\" }];\n }\n const isStdio = server.transport === \"stdio\" && !!server.command;\n const isHttp = server.transport === \"http\" && !!server.url;\n if (!isStdio && !isHttp) {\n // Codex config.toml [mcp_servers] supports stdio (command) + streamable\n // HTTP (url). Other remote transports (sse/ws) have no codex analog.\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `transport \"${server.transport}\" not registrable in config.toml (stdio + streamable-http only)`,\n },\n ];\n }\n\n const entry = this.renderMcpEntry(ctx, server);\n\n return [\n upsertInObjectMap({\n codec: this.tomlObjectMapCodec(),\n rootKey: \"mcp_servers\",\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n entry,\n dryRun,\n }),\n ];\n }\n\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n return [\n removeFromObjectMap({\n codec: this.tomlObjectMapCodec(),\n rootKey: \"mcp_servers\",\n policy: \"coerce\",\n platform: this.id,\n configPath: path,\n entryId: connector.id,\n dryRun,\n }),\n ];\n }\n\n // ── Install hooks (hooks.json) ──────────────────────────────────────────\n\n override installHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const events = this.effectiveHookEvents(ctx);\n const dropped = this.warnSkipHookEvents(ctx);\n\n if (events.length === 0 && dropped.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks declared\" }];\n }\n\n // HOST-ORDERED pending: warn-skip events (mapEvent → undefined → warn) FIRST,\n // then the supported events in CODEX_HOOK_EVENTS order. Events neither\n // supported nor in WARN_SKIP_EVENTS are never enqueued → silently dropped, as\n // before. matcher is \"\" for every item; renderEntry derives the real matcher\n // from the event (PreToolUse/PermissionRequest), never from this field.\n const pending = [\n ...dropped.map((event) => ({ event: event as string, matcher: \"\" })),\n ...events.map((event) => ({ event: event as string, matcher: \"\" })),\n ];\n return this.upsertHookEntries(ctx, path, pending, this.hookDescriptor(ctx));\n }\n\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor(ctx));\n }\n\n /**\n * Codex hook-merge policy for the shared object-map engine. EVENT-SPECIFIC by\n * construction: every observable (coerce root + bucket, the path-normalized\n * per-event ownership find, the event-derived matcher with `hooks`-then-\n * `matcher` key order, the BARE `hooks.<event>` skip/remove details with NO\n * count, the warn wording, and the absent/no-match skips) is carried here so\n * the engine reproduces the prior in-adapter loop byte-for-byte.\n */\n private hookDescriptor(ctx: InstallContext): HookMergeDescriptor<CodexHookEntry> {\n return {\n // Codex's server path coerces a malformed root; the hook path matches it.\n malformedPolicy: \"coerce\",\n // Supported event → identity; a WARN_SKIP event (PostToolUseFailure, which\n // is the only thing `dropped` ever contains) → undefined → warn.\n mapEvent: (e) =>\n (CODEX_HOOK_EVENTS as readonly string[]).includes(e) ? e : undefined,\n unmappedWarnDetail: (e) => `${e} has no Codex hook equivalent — skipped`,\n renderEntry: (event, _matcher, command) => {\n const entry: CodexHookEntry = { hooks: [{ type: \"command\", command }] };\n // KEY ORDER: hooks THEN matcher. Matcher is EVENT-derived, not from the\n // connector's declared matcher: PermissionRequest matches tool names like\n // PreToolUse (charset-clean), everything else registers \"\" (all).\n entry.matcher =\n event === \"PreToolUse\" || event === \"PermissionRequest\" ? PRE_TOOL_USE_MATCHER : \"\";\n return entry;\n },\n // Idempotency find for the CANONICAL event the engine built `command` from —\n // path-normalized, exact-command, the body of isOurEntry's command check.\n entryOwnsCommand: (entry, command) =>\n Array.isArray(entry.hooks) &&\n entry.hooks.some(\n (h) => (h.command ?? \"\").replace(/\\\\/g, \"/\") === command.replace(/\\\\/g, \"/\"),\n ),\n // FLAT whole-entry removal, EVENT-SPECIFIC: isOurEntry rebuilds our command\n // from the event key being stripped, so a SubagentStop entry is never matched\n // while iterating the PreToolUse bucket.\n ownsEntryForRemove: (c, event) => (entry) =>\n this.isOurEntry(c, event as CodexHookEventName, entry),\n skipDetail: (e) => `hooks.${e}`,\n removeDetail: (e, _n) => `hooks.${e}`,\n absentDetail: \"no hooks.json\",\n noMatchDetail: \"no agent-connector hooks present\",\n // Uninstall scans EXACTLY codex's fixed event set (not Object.keys), so a\n // home-bin command hand-placed under a foreign event key is left untouched —\n // byte-identical to the prior `for (const event of CODEX_HOOK_EVENTS)` loop.\n removeEventKeys: CODEX_HOOK_EVENTS,\n };\n }\n\n // ── Health checks (default doctor renders these) ────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const path = this.getServerConfigPath(ctx);\n const id = ctx.connector.id;\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: config.toml exists`,\n check: () =>\n existsSync(path)\n ? { status: \"OK\", detail: path }\n : { status: \"FAIL\", detail: `not found: ${path}` },\n },\n {\n name: `${this.name}: mcp_servers.${id} registered`,\n check: () => {\n // Only assert what the connector declares (same rule as the\n // content-surface checks below): a server-less connector — e.g. a\n // catalog-only bundle of agents/skills/commands — never writes an\n // [mcp_servers.<id>] table, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readToml(path);\n const bucket = cfg[\"mcp_servers\"];\n const present =\n typeof bucket === \"object\" &&\n bucket !== null &&\n id in (bucket as Record<string, unknown>);\n return present\n ? { status: \"OK\", detail: `mcp_servers.${id}` }\n : { status: \"FAIL\", detail: `mcp_servers.${id} not found in ${path}` };\n },\n },\n ];\n\n // Content-surface checks: assert presence only for surfaces this connector\n // declares. Codex commands are user-scope only, so a project-scope install\n // won't have written them — only check command files in user scope.\n if (ctx.scope !== \"project\") {\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(cmd.name);\n checks.push({\n name: `${this.name}: command ${cmd.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n }\n for (const skill of ctx.connector.skills) {\n const p = join(this.skillDir(ctx, skill.name), \"SKILL.md\");\n checks.push({\n name: `${this.name}: skill ${skill.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n for (const agent of ctx.connector.subagents) {\n const p = this.subagentPath(ctx, agent.name);\n checks.push({\n name: `${this.name}: subagent ${agent.name} present`,\n check: () =>\n existsSync(p) ? { status: \"OK\", detail: p } : { status: \"FAIL\", detail: `not found: ${p}` },\n });\n }\n return checks;\n }\n\n // ── Content surfaces: commands / skills / subagents ──────────────────────\n // CONTENT-ONLY: pure native-file writers. No runtime dispatch, no home-bin\n // pointer, no telemetry wrap. Each method is idempotent (byte-identical →\n // skip) via writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"codex\"] per-surface false to skip.\n //\n // Native locations:\n // command → ~/.codex/prompts/<name>.md md+frontmatter(description,argument-hint)\n // USER SCOPE ONLY — project scope yields a single \"warn\".\n // skill → project: <projectDir>/.codex/skills/<name>/SKILL.md (+ resources)\n // user: ~/.agents/skills/<name>/SKILL.md (~/.codex/skills is deprecated)\n // subagent → <codexDir>/agents/<name>.toml TOML via writeTomlString\n\n /** Command files always live under the USER codex dir: ~/.codex/prompts. */\n private commandPath(name: string): string {\n return join(this.userConfigDir(), \"prompts\", `${name}.md`);\n }\n private skillDir(ctx: InstallContext, name: string): string {\n // Project scope: <projectDir>/.codex/skills/<name> — the Project config-layer\n // skills root (codex-rs/core-skills/src/loader.rs, ConfigLayerSource::Project),\n // NOT deprecated. User scope: $HOME/.agents/skills/<name> — codex's CURRENT\n // user skills root. The older $CODEX_HOME/skills (~/.codex/skills) is still\n // read but the loader labels it a \"Deprecated user skills location, kept for\n // backward compatibility\". .agents is anchored to the OS home (home_dir), NOT\n // $CODEX_HOME — so use homedir() here, never userConfigDir() (which honors\n // CODEX_HOME).\n if (ctx.scope === \"project\") return join(this.getConfigDir(ctx), \"skills\", name);\n return join(homedir(), \".agents\", \"skills\", name);\n }\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.getConfigDir(ctx), \"agents\", `${name}.toml`);\n }\n\n // ── Commands (USER SCOPE ONLY) ───────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for codex\" }];\n }\n if (ctx.scope === \"project\") {\n return [{ platform: this.id, action: \"warn\", detail: \"codex commands are user-scope only\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.writeContentFile(\n this.commandPath(cmd.name),\n renderCommandMd(cmd, { includeToolsAndModel: false }),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (ctx.scope === \"project\") {\n return [{ platform: this.id, action: \"warn\", detail: \"codex commands are user-scope only\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(cmd.name), ctx.dryRun),\n );\n }\n\n // ── Skills ───────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for codex\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n const rendered = renderSkillMd(skill);\n changes.push(this.writeContentFile(join(dir, \"SKILL.md\"), rendered, ctx.dryRun));\n // Bundle any resource files beside SKILL.md (relative path → contents).\n // Defense-in-depth: skip+warn on any key that escapes the skill dir\n // (config-time validation already rejects these, but never trust input).\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n // Migrate away an AC-owned copy at the deprecated user skills root so the\n // skill is not double-registered after the move to ~/.agents/skills.\n changes.push(...this.migrateDeprecatedUserSkill(ctx, skill, rendered));\n }\n return changes;\n }\n\n /**\n * One-time, opt-out-safe migration: prior AC versions wrote user-scope skills\n * to the now-deprecated $CODEX_HOME/skills/<name> root, which codex STILL reads\n * (kept for backward compatibility). Once we write the same skill to the current\n * ~/.agents/skills root, codex would register it TWICE (same frontmatter name,\n * two User-scope roots). If a SKILL.md exists at the deprecated path AND is\n * byte-identical to what we render — i.e. AC-owned, not hand-authored — remove\n * it (and its now-empty dir). The content-equality guard guarantees we never\n * delete a skill a user placed there by hand. No-op for project scope (where\n * .codex/skills is the valid, non-deprecated Project config-layer path) and when\n * a custom CODEX_HOME would make the deprecated path coincide with the new one.\n */\n private migrateDeprecatedUserSkill(\n ctx: InstallContext,\n skill: SkillDef,\n rendered: string,\n ): ChangeRecord[] {\n if (ctx.scope === \"project\") return [];\n const deprecated = join(this.userConfigDir(), \"skills\", skill.name, \"SKILL.md\");\n // Never touch the file we just wrote (pathological CODEX_HOME === ~/.agents).\n if (deprecated === join(this.skillDir(ctx, skill.name), \"SKILL.md\")) return [];\n if (!existsSync(deprecated)) return [];\n if (readFileSync(deprecated, \"utf8\") !== rendered) return []; // hand-authored — leave it\n return [\n this.removeContentFile(deprecated, ctx.dryRun),\n this.removeDirIfEmpty(dirname(deprecated), ctx.dryRun),\n ];\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n // Remove only the files we wrote (SKILL.md + declared resources), then the\n // skill dir itself when we own its full contents.\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue; // never delete outside the skill dir\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n // Only remove the skill dir when WE own its full contents — never rm -rf a\n // dir that still holds user-added / sibling-tool / shared files.\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Subagents (TOML) ─────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[this.id]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for codex\" }];\n }\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.writeContentFile(this.subagentPath(ctx, agent.name), this.renderSubagent(agent), ctx.dryRun),\n );\n }\n\n override uninstallSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.subagents.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no subagents\" }];\n }\n return connector.subagents.map((agent) =>\n this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun),\n );\n }\n\n /**\n * Render a subagent to a Codex agent TOML file:\n * { name, description, developer_instructions: prompt, model }.\n * model is omitted when undefined so Codex applies its default.\n */\n private renderSubagent(agent: SubagentDef): string {\n const table: Record<string, unknown> = {\n name: agent.name,\n description: agent.description,\n developer_instructions: agent.prompt,\n };\n if (agent.model !== undefined) table.model = agent.model;\n if (agent.extra) Object.assign(table, agent.extra);\n return writeTomlString(table);\n }\n\n // ── Runtime dispatch ────────────────────────────────────────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as CodexHookInput;\n const base = {\n hostPlatform: this.id,\n connectorId: \"\",\n sessionId: input.session_id ?? `pid-${process.ppid}`,\n projectDir: input.cwd ?? process.env.CODEX_PROJECT_DIR ?? process.cwd(),\n raw,\n };\n\n switch (event) {\n case \"PreToolUse\":\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n case \"PostToolUse\":\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n toolOutput: input.tool_response,\n isError: input.is_error ?? false,\n };\n case \"SessionStart\":\n return { ...base, source: normalizeSessionSource(input.source) };\n case \"SessionEnd\":\n return { ...base, reason: input.message };\n case \"UserPromptSubmit\":\n return { ...base, prompt: input.prompt ?? \"\" };\n case \"PreCompact\":\n return { ...base, trigger: input.trigger === \"manual\" ? \"manual\" : \"auto\" };\n case \"PostCompact\":\n // Post-compaction sibling of PreCompact — same `trigger` normalization\n // (manual|auto), observe-only. Codex's PostCompact payload mirrors\n // PreCompact's; everything else rides on `raw`.\n return { ...base, trigger: input.trigger === \"manual\" ? \"manual\" : \"auto\" };\n case \"Stop\":\n return { ...base, stopHookActive: input.stop_hook_active ?? false };\n case \"Notification\":\n return { ...base, message: input.message ?? \"\" };\n case \"PermissionRequest\":\n // Codex documents tool_name/tool_input (+tool_input.description); it has\n // no permission_suggestions field, so the normalized optional stays unset.\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n case \"PostToolUseFailure\":\n // No Codex analog — never fired natively. Parsed defensively (Claude-\n // compatible wire) so a manual `hook codex PostToolUseFailure` invocation\n // still normalizes instead of throwing.\n return {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n error: input.error ?? \"\",\n };\n case \"SubagentStart\":\n return {\n ...base,\n ...(typeof input.agent_id === \"string\" ? { agentId: input.agent_id } : {}),\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n };\n case \"SubagentStop\":\n // agent_id/agent_type stay optional — never depend on hosts populating\n // them on stop (the Claude-family SDK quirk).\n return {\n ...base,\n ...(typeof input.agent_id === \"string\" ? { agentId: input.agent_id } : {}),\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n ...(typeof input.agent_transcript_path === \"string\"\n ? { agentTranscriptPath: input.agent_transcript_path }\n : {}),\n ...(typeof input.last_assistant_message === \"string\"\n ? { lastAssistantMessage: input.last_assistant_message }\n : {}),\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n }\n }\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n // Codex (like Claude Code) reads a `hookSpecificOutput` JSON wrapper from\n // stdout; exit code 0 = allow. Fields the host cannot honor are dropped.\n\n // PermissionRequest uses Codex's nested decision{behavior} envelope and is\n // the ONE event where an EXPLICIT \"allow\" is an ACTIVE grant (suppresses the\n // approval prompt). ask/context/void → NO decision output: fall through to\n // the normal approval flow (the prompt IS the ask). Codex docs: updatedInput\n // / updatedPermissions / interrupt FAIL CLOSED on this event, so \"modify\"\n // also falls through — emitting a bare allow would grant the ORIGINAL input\n // the handler wanted rewritten.\n if (event === \"PermissionRequest\") {\n if (response.decision === \"deny\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PermissionRequest\",\n decision: {\n behavior: \"deny\",\n message: response.reason ?? \"Blocked by hook\",\n },\n },\n }),\n };\n }\n if (response.decision === \"allow\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PermissionRequest\",\n decision: { behavior: \"allow\" },\n },\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n // SubagentStart is observe/context-only on Codex (continue:false is parsed\n // but does not stop the subagent): \"context\" injects additionalContext as\n // developer context for the SUBAGENT, and a \"deny\" DEGRADES to the same\n // shape carrying the reason.\n if (event === \"SubagentStart\") {\n const context =\n response.decision === \"context\"\n ? response.additionalContext\n : response.decision === \"deny\"\n ? response.reason ?? response.additionalContext\n : undefined;\n if (context) {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"SubagentStart\",\n additionalContext: context,\n },\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n if (response.decision === \"deny\") {\n // PreToolUse deny is honored; other events fail-open to allow.\n if (event === \"PreToolUse\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n }),\n };\n }\n // SubagentStop deny = Stop semantics: the documented continuation shape is\n // the TOP-LEVEL {\"decision\":\"block\",\"reason\"} (keeps the subagent going\n // with `reason` as its next instruction).\n if (event === \"SubagentStop\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n }),\n };\n }\n return { exitCode: 0 };\n }\n\n // Context injection: honored on SessionStart and PostToolUse (additionalContext).\n // (SubagentStop accepts only the common output fields — no additionalContext.)\n if (response.additionalContext && (event === \"SessionStart\" || event === \"PostToolUse\")) {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: event,\n additionalContext: response.additionalContext,\n },\n }),\n };\n }\n\n // \"allow\" / unsupported-on-Codex (modify, ask) → passthrough.\n return { exitCode: 0 };\n }\n\n // ── Internal helpers ────────────────────────────────────────────────────\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[this.id]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override ? { ...base, ...override } : base;\n }\n\n /** Which canonical hook events to register for Codex, honoring overrides. */\n private effectiveHookEvents(ctx: InstallContext): CodexHookEventName[] {\n const override = ctx.connector.platforms[this.id]?.hooks;\n if (override === false) return [];\n return CODEX_HOOK_EVENTS.filter((e) => ctx.connector.hookEvents.includes(e));\n }\n\n /** Declared events Codex has no analog for — install reports a warn-skip. */\n private warnSkipHookEvents(ctx: InstallContext): HookEventName[] {\n const override = ctx.connector.platforms[this.id]?.hooks;\n if (override === false) return [];\n return ctx.connector.hookEvents.filter((e) => WARN_SKIP_EVENTS.has(e));\n }\n\n /**\n * Render the `[mcp_servers.<id>]` table. TOML has NO interpolation, so every\n * `${env:VAR}` is resolved to a literal at install time. The env table is a\n * plain string→string map. Honors the telemetry serve-wrapper.\n */\n private renderMcpEntry(ctx: InstallContext, server: ServerDef): CodexMcpEntry {\n // Streamable HTTP server: codex infers the transport from `url` (no explicit\n // transport key). VERIFIED against codex-cli 0.139.0 — `codex mcp add <id>\n // --url <U> --bearer-token-env-var <E>` writes:\n // [mcp_servers.<id>]\n // url = \"…\"\n // bearer_token_env_var = \"…\" (only with bearerEnv auth)\n // Telemetry serve-wrapping is stdio-only (remote cannot be intercepted).\n // installServer's guard only lets stdio+command or http+url reach here, so\n // this branch is exactly the streamable-HTTP case (lock-step with the guard).\n if (server.transport === \"http\") {\n const remote: CodexMcpEntry = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n if (server.auth?.type === \"bearerEnv\" && server.auth.bearerEnvVar) {\n remote.bearer_token_env_var = server.auth.bearerEnvVar;\n }\n if (server.headers && Object.keys(server.headers).length > 0) {\n const headers: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.headers))) {\n headers[k] = String(v);\n }\n remote.http_headers = headers;\n }\n return remote;\n }\n let command = server.command as string;\n let args = [...(server.args ?? [])];\n\n ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n // Resolve env-refs to literals (TOML cannot interpolate).\n command = resolveEnvRefsDeep(command);\n args = resolveEnvRefsDeep(args);\n\n const entry: CodexMcpEntry = { command };\n if (args.length > 0) entry.args = args;\n\n if (server.env && Object.keys(server.env).length > 0) {\n const env: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {\n env[k] = String(v);\n }\n entry.env = env;\n }\n return entry;\n }\n\n /**\n * Does this hooks.json entry belong to this connector for `event`? EVENT-\n * SPECIFIC + path-normalized exact-command match. The engine binds this per\n * event in the uninstall (whole-entry FLAT removal) and the install idempotency\n * find reuses its command body via the descriptor's entryOwnsCommand.\n */\n private isOurEntry(ctx: InstallContext, event: CodexHookEventName, entry: CodexHookEntry): boolean {\n if (!entry || typeof entry !== \"object\" || !Array.isArray(entry.hooks)) return false;\n const ours = buildHomeBinHookCommand(ctx.homeBinPath, \"codex\", event, ctx.connector.id);\n const needle = ours.replace(/\\\\/g, \"/\");\n return entry.hooks.some((h) => (h.command ?? \"\").replace(/\\\\/g, \"/\") === needle);\n }\n}\n\nexport const adapter = new CodexAdapter();\nexport default adapter;\n"],"mappings":"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","names":[]}