@ken-jo/agent-connector 0.4.1 → 0.4.6

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 (92) hide show
  1. package/README.md +2 -2
  2. package/dist/{action-WT7GVRCC.js → action-EV63GAPY.js} +8 -8
  3. package/dist/amp-XJQ4TDAU.js +666 -0
  4. package/dist/amp-XJQ4TDAU.js.map +1 -0
  5. package/dist/{chunk-QREL7LZJ.js → chunk-2X4EH2D7.js} +2 -2
  6. package/dist/{chunk-RIMVWCZY.js → chunk-5G4EPJ4Y.js} +5 -5
  7. package/dist/{chunk-DCKFYWGM.js → chunk-BMD7ANKF.js} +10 -10
  8. package/dist/{chunk-4ENJK5S2.js → chunk-DCK5FADX.js} +2 -2
  9. package/dist/{chunk-EGCBZ2DC.js → chunk-EROJDXMW.js} +2 -2
  10. package/dist/{chunk-5OWS5CMA.js → chunk-H67V7DEL.js} +5 -5
  11. package/dist/{chunk-24IDL5RW.js → chunk-MZF2YCXX.js} +2 -2
  12. package/dist/{chunk-O5TWCIJN.js → chunk-QC5A3TFQ.js} +18 -18
  13. package/dist/{chunk-2AVLX7GH.js → chunk-QOGMDOUX.js} +3 -3
  14. package/dist/{chunk-URHQMFB3.js → chunk-RQPKL62M.js} +61 -15
  15. package/dist/chunk-RQPKL62M.js.map +1 -0
  16. package/dist/{chunk-XJ4S47CT.js → chunk-SRVAA2VN.js} +2 -2
  17. package/dist/{claude-code-W4PUFZL5.js → claude-code-T2LPFNC3.js} +4 -4
  18. package/dist/cli/sdk.js +4 -4
  19. package/dist/cli.js +1 -1
  20. package/dist/{codebuff-DH5Y7GAT.js → codebuff-PODYPOOP.js} +126 -5
  21. package/dist/codebuff-PODYPOOP.js.map +1 -0
  22. package/dist/{codex-DDHIV767.js → codex-O4G7D7KK.js} +19 -3
  23. package/dist/codex-O4G7D7KK.js.map +1 -0
  24. package/dist/{detect-KG5FG3EV.js → detect-AHJIUMBO.js} +4 -4
  25. package/dist/{doctor-FLZF34Y3.js → doctor-G5MLCPAB.js} +8 -8
  26. package/dist/{hook-XR3Z45FB.js → hook-76JBKTUX.js} +8 -8
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +2 -2
  29. package/dist/{install-BSR62UHJ.js → install-R7252QFH.js} +8 -8
  30. package/dist/{introspect-Nw8hTReX.d.ts → introspect-Cn3MSA4_.d.ts} +1 -1
  31. package/dist/{kilo-5NWOXVSD.js → kilo-IX4T3OHJ.js} +100 -4
  32. package/dist/kilo-IX4T3OHJ.js.map +1 -0
  33. package/dist/{kilo-cli-UZ7R5UOP.js → kilo-cli-2AYCXBQD.js} +107 -11
  34. package/dist/kilo-cli-2AYCXBQD.js.map +1 -0
  35. package/dist/{leaderboard-MJG24O35.js → leaderboard-V6VWA5ZV.js} +2 -2
  36. package/dist/{nemoclaw-W5KEJ3WX.js → nemoclaw-CQYXZVQN.js} +2 -2
  37. package/dist/{openclaw-EXJEFNZI.js → openclaw-UZC437RW.js} +2 -2
  38. package/dist/{opencode-WNXYJR4X.js → opencode-L4BGFP25.js} +4 -1
  39. package/dist/opencode-L4BGFP25.js.map +1 -0
  40. package/dist/{package-ACZXJHWB.js → package-DNLQTPNN.js} +6 -6
  41. package/dist/runtime/index.d.ts +1 -1
  42. package/dist/runtime/index.js +6 -6
  43. package/dist/sdk/index.d.ts +3 -3
  44. package/dist/sdk/index.js +3 -3
  45. package/dist/sdk/test.d.ts +2 -2
  46. package/dist/sdk/test.js +5 -5
  47. package/dist/{serve-GER7URPR.js → serve-EOVWYBGZ.js} +8 -8
  48. package/dist/{status-LAJE3BM5.js → status-VTD6XXLW.js} +6 -6
  49. package/dist/{statusline-L376ZPZU.js → statusline-3ET5YPQ5.js} +7 -7
  50. package/dist/{telemetry-B3DX3PWU.js → telemetry-QCTMKDBQ.js} +5 -5
  51. package/dist/{types-CRVrFWeU.d.ts → types-_6arHbX9.d.ts} +5 -4
  52. package/dist/{uninstall-ZYTW7YMZ.js → uninstall-FL3SH2DT.js} +8 -8
  53. package/dist/{upgrade-4LUEEOZW.js → upgrade-SLFG2FCT.js} +8 -8
  54. package/dist/{usage-ZFBVQF3H.js → usage-IRBLVUZM.js} +2 -2
  55. package/dist/{usage-event-GZ32AGEB.js → usage-event-VFF77WYY.js} +7 -7
  56. package/package.json +1 -1
  57. package/dist/amp-4U33CU7E.js +0 -300
  58. package/dist/amp-4U33CU7E.js.map +0 -1
  59. package/dist/chunk-URHQMFB3.js.map +0 -1
  60. package/dist/codebuff-DH5Y7GAT.js.map +0 -1
  61. package/dist/codex-DDHIV767.js.map +0 -1
  62. package/dist/kilo-5NWOXVSD.js.map +0 -1
  63. package/dist/kilo-cli-UZ7R5UOP.js.map +0 -1
  64. package/dist/opencode-WNXYJR4X.js.map +0 -1
  65. /package/dist/{action-WT7GVRCC.js.map → action-EV63GAPY.js.map} +0 -0
  66. /package/dist/{chunk-QREL7LZJ.js.map → chunk-2X4EH2D7.js.map} +0 -0
  67. /package/dist/{chunk-RIMVWCZY.js.map → chunk-5G4EPJ4Y.js.map} +0 -0
  68. /package/dist/{chunk-DCKFYWGM.js.map → chunk-BMD7ANKF.js.map} +0 -0
  69. /package/dist/{chunk-4ENJK5S2.js.map → chunk-DCK5FADX.js.map} +0 -0
  70. /package/dist/{chunk-EGCBZ2DC.js.map → chunk-EROJDXMW.js.map} +0 -0
  71. /package/dist/{chunk-5OWS5CMA.js.map → chunk-H67V7DEL.js.map} +0 -0
  72. /package/dist/{chunk-24IDL5RW.js.map → chunk-MZF2YCXX.js.map} +0 -0
  73. /package/dist/{chunk-O5TWCIJN.js.map → chunk-QC5A3TFQ.js.map} +0 -0
  74. /package/dist/{chunk-2AVLX7GH.js.map → chunk-QOGMDOUX.js.map} +0 -0
  75. /package/dist/{chunk-XJ4S47CT.js.map → chunk-SRVAA2VN.js.map} +0 -0
  76. /package/dist/{claude-code-W4PUFZL5.js.map → claude-code-T2LPFNC3.js.map} +0 -0
  77. /package/dist/{detect-KG5FG3EV.js.map → detect-AHJIUMBO.js.map} +0 -0
  78. /package/dist/{doctor-FLZF34Y3.js.map → doctor-G5MLCPAB.js.map} +0 -0
  79. /package/dist/{hook-XR3Z45FB.js.map → hook-76JBKTUX.js.map} +0 -0
  80. /package/dist/{install-BSR62UHJ.js.map → install-R7252QFH.js.map} +0 -0
  81. /package/dist/{leaderboard-MJG24O35.js.map → leaderboard-V6VWA5ZV.js.map} +0 -0
  82. /package/dist/{nemoclaw-W5KEJ3WX.js.map → nemoclaw-CQYXZVQN.js.map} +0 -0
  83. /package/dist/{openclaw-EXJEFNZI.js.map → openclaw-UZC437RW.js.map} +0 -0
  84. /package/dist/{package-ACZXJHWB.js.map → package-DNLQTPNN.js.map} +0 -0
  85. /package/dist/{serve-GER7URPR.js.map → serve-EOVWYBGZ.js.map} +0 -0
  86. /package/dist/{status-LAJE3BM5.js.map → status-VTD6XXLW.js.map} +0 -0
  87. /package/dist/{statusline-L376ZPZU.js.map → statusline-3ET5YPQ5.js.map} +0 -0
  88. /package/dist/{telemetry-B3DX3PWU.js.map → telemetry-QCTMKDBQ.js.map} +0 -0
  89. /package/dist/{uninstall-ZYTW7YMZ.js.map → uninstall-FL3SH2DT.js.map} +0 -0
  90. /package/dist/{upgrade-4LUEEOZW.js.map → upgrade-SLFG2FCT.js.map} +0 -0
  91. /package/dist/{usage-ZFBVQF3H.js.map → usage-IRBLVUZM.js.map} +0 -0
  92. /package/dist/{usage-event-GZ32AGEB.js.map → usage-event-VFF77WYY.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/amp/index.ts"],"sourcesContent":["/**\n * adapters/amp — Amp (Sourcegraph / AmpCode) platform adapter for agent-connector.\n *\n * Amp is a **ts-plugin** host: alongside MCP it loads TypeScript plugin modules\n * from `.amp/plugins/<name>.ts`, each default-exporting a function `(amp) => void`\n * that registers lifecycle handlers via `amp.on(\"<event>\", async (event, ctx) =>\n * …)` (ampcode.com/manual → Plugins). This adapter wires the five amp.on events\n * that have a canonical analog and bridges them to the universal home-bin\n * entrypoint, exactly like the OMP / OpenCode ts-plugin adapters.\n *\n * Event mapping (only events the connector declares are subscribed):\n * SessionStart → amp.on(\"session.start\", …) (thread begins; id = event.thread.id)\n * UserPromptSubmit → amp.on(\"agent.start\", …) (user submits a prompt; observe-only)\n * PreToolUse → amp.on(\"tool.call\", …) (before a tool runs; deny → return\n * { action: \"reject-and-continue\" }, else { action: \"allow\" })\n * PostToolUse → amp.on(\"tool.result\", …) (after a tool finishes; observe-only)\n * Stop → amp.on(\"agent.end\", …) (turn ends; observe-only)\n * Amp documents NO session.end event, so SessionEnd is an honest gap (warn-skip\n * via the unsupported-here detail). tool.call's decision surface is the\n * { action } union (canModifyArgs:false — the \"modify\" input shape is not\n * documented); tool.result CAN return a replacement but the manual never\n * documents its object shape, so PostToolUse is observe-only (canModifyOutput:\n * false) rather than ship a guessed mutation; session.start has no documented\n * context-injection surface (canInjectSessionContext:false).\n *\n * Why we SYNTHESIZE a self-contained module instead of importing handlers:\n * the connector's hook handlers are arbitrary developer code we must not import\n * into Amp's (Bun) runtime — wrong cwd, wrong deps, version skew. So, like the\n * OMP / OpenCode adapters, we generate a tiny ESM/TS plugin that imports NOTHING\n * from agent-connector: each `amp.on(...)` handler shells out to the ONE stable\n * home binary's universal entrypoint (`<homeBin> hook amp <event> --connector\n * <id>`) over child_process, feeds it the amp-shaped payload as JSON on stdin,\n * and JSON.parses the normalized HookResponse back from stdout. Fail-open: any\n * bridge error → no-op. One entrypoint, every paradigm.\n *\n * Plugin scope: the `.amp/plugins/` dir is documented at PROJECT scope only; Amp\n * documents no user-scope plugins dir, so installHooks writes the plugin for\n * project scope and warn-skips user scope (the MCP + skills surfaces keep their\n * own user-scope paths). MCP config (report §2 / §5.3):\n * - user scope → ~/.config/amp/settings.json\n * - project scope → <projectDir>/.amp/settings.json\n * Both are JSONC (we write plain JSON, which is valid JSONC). The settings file\n * is SHARED with the rest of Amp's configuration, so we MERGE our entry into\n * the existing object and never clobber unrelated keys.\n *\n * QUIRK 1 — dotted top-level key: Amp does NOT use a nested `mcpServers` object.\n * The MCP registry is a single FLAT settings key literally named\n * `\"amp.mcpServers\"`, whose value is an object of `{ id: { command, args, env } }`.\n * We therefore set `settings[\"amp.mcpServers\"][connectorId] = entry`. Because the\n * base JSON helpers index `config[rootKey][serverId]`, passing the dotted string\n * as the root key writes exactly that flat key while preserving every sibling\n * setting (true merge).\n *\n * QUIRK 2 — native interpolation: Amp expands `${VAR_NAME}` in stdio entries at\n * runtime, so we KEEP env/header/url refs native by rewriting the portable\n * `${env:VAR}` syntax to Amp's `${VAR}` token rather than resolving to literals\n * (secrets stay out of the settings file).\n *\n * Skills surface: Amp reads SKILL.md files (dir-per-skill, same shape as\n * claude-code) from a skill root that is NOT under the config dir\n * (`~/.config/amp`):\n * - user scope → ~/.config/agents/skills/<name>/SKILL.md (the sibling\n * cross-agent `agents` dir — `~/.config/amp/skills/` is also documented-native,\n * but the `agents` root is the cross-agent standard we standardize on)\n * - project scope → <projectDir>/.agents/skills/<name>/SKILL.md\n * Because that root differs from getConfigDir, skills use a dedicated skillDir()\n * helper rather than reusing getConfigDir.\n */\n\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type {\n Adapter,\n GeneratedPluginFile,\n HookReply,\n InstallContext,\n NormalizedEvent,\n} from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PreToolUseEvent,\n ServerDef,\n SessionStartEvent,\n SkillDef,\n StopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { rewriteEnvRefs } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\n\nconst HOST: PlatformId = \"amp\";\n/**\n * QUIRK: a single FLAT, dotted settings key — NOT a nested object. The base\n * JSON helpers treat this as `config[\"amp.mcpServers\"][serverId]`.\n */\nconst MCP_ROOT_KEY = \"amp.mcpServers\";\n\n/**\n * Canonical → Amp plugin event name map. A connector hook event is only\n * subscribed by the generated plugin when it appears here AND is declared by the\n * connector. Names verified against ampcode.com/manual (Plugins → amp.on events).\n * Amp documents NO `session.end`, so SessionEnd has no entry (honest gap).\n */\nconst EVENT_TO_AMP: Partial<Record<HookEventName, string>> = {\n SessionStart: \"session.start\",\n UserPromptSubmit: \"agent.start\",\n PreToolUse: \"tool.call\",\n PostToolUse: \"tool.result\",\n Stop: \"agent.end\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface AmpBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n prompt?: string;\n sessionId?: string;\n projectDir?: string;\n}\n\n/** Native MCP server entry shapes Amp accepts under `amp.mcpServers`. */\ninterface AmpStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface AmpHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class AmpAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Amp\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block via the BaseAdapter default\n // (memoryTargets: project <projectDir>/AGENTS.md; user scope where documented).\n supportsMemory: true,\n // amp.on lifecycle events with a canonical analog (EVENT_TO_AMP):\n // tool.call / tool.result / session.start / agent.start / agent.end.\n preToolUse: true,\n postToolUse: true,\n // Amp has no documented compaction hook.\n preCompact: false,\n sessionStart: true,\n // Amp documents NO session.end event — SessionEnd is an honest gap.\n sessionEnd: false,\n userPromptSubmit: true,\n stop: true,\n notification: false,\n // Newer events: Amp documents no permission/approval, post-tool-failure, or\n // subagent lifecycle hook with a canonical analog, so permissionRequest /\n // postToolUseFailure / subagentStart / subagentStop stay unset — the\n // generated bridge never references them and install reports them as\n // \"unsupported here\".\n // tool.call's documented decision surface is { action: \"allow\" |\n // \"reject-and-continue\" | \"modify\" | \"synthesize\" } (ampcode.com/manual →\n // Plugins → tool.call). We wire allow + reject-and-continue (block); the\n // \"modify\" input-rewrite shape is not byte-documented, so canModifyArgs:false.\n canModifyArgs: false,\n // tool.result says \"return a replacement status/output\" but the manual never\n // documents the replacement OBJECT SHAPE (which keys). Rather than guess it,\n // PostToolUse is observe-only and canModifyOutput stays false until the shape\n // is primary-source-verified (honesty bar: under-claim, never emit a guessed\n // mutation contract).\n canModifyOutput: false,\n // session.start has no documented context-injection surface.\n canInjectSessionContext: false,\n // Amp registers stdio and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"http\"],\n // Skills: Amp reads SKILL.md from ~/.config/agents/skills/<name>/SKILL.md\n // (user) and <projectDir>/.agents/skills/<name>/SKILL.md (project) — a root\n // OUTSIDE the config dir, so the skillDir() helper resolves it explicitly.\n supportsSkills: true,\n // Native passthrough hooks: amp.on events with no canonical HookEventName\n // analog are reachable via platforms[\"amp\"].nativeHooks; the generated plugin\n // registers + bridges each declared native event verbatim and the home-bin\n // runtime dispatches it host-generically via runNativeHook.\n supportsNativeHooks: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".config\", \"amp\");\n const userSettings = join(userDir, \"settings.json\");\n const projectDirAmp = join(projectDir, \".amp\");\n const projectSettings = join(projectDirAmp, \"settings.json\");\n\n const userInstalled = existsSync(userDir) || existsSync(userSettings);\n const projectInstalled = existsSync(projectDirAmp) || existsSync(projectSettings);\n const installed = userInstalled || projectInstalled;\n const scope = projectInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectSettings : userSettings;\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 Amp config (${scope}) at ${configPath}`\n : `no Amp config at ${userSettings} or ${projectSettings}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".amp\")\n : join(homedir(), \".config\", \"amp\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"settings.json\");\n }\n\n /**\n * For this ts-plugin host the \"hook config path\" is the generated plugin\n * MODULE. Amp loads every `.ts` file in `.amp/plugins/`, so writing this file\n * IS the registration. The `.amp/plugins/` dir is documented at PROJECT scope\n * (Amp documents no user-scope plugins dir — see pluginsDir); the user-scope\n * path is returned for doctor/uninstall symmetry but installHooks warn-skips it.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.pluginsDir(ctx), `${ctx.connector.id}.ts`);\n }\n\n /**\n * Plugin directory Amp auto-loads `.ts` modules from. PROJECT scope is the\n * documented `<projectDir>/.amp/plugins`; user scope mirrors the MCP config dir\n * (`~/.config/amp/plugins`) for path symmetry only — installHooks never writes\n * there because Amp documents no user-scope plugins dir.\n */\n private pluginsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".amp\", \"plugins\")\n : join(this.getConfigDir(ctx), \"plugins\");\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for amp\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n // Upsert into the flat \"amp.mcpServers\" key, merging into existing settings.\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /** Render a normalized ServerDef into Amp's native `amp.mcpServers` entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): AmpStdioServer | AmpHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n ctx.homeBinPath,\n ctx.connector.id,\n command,\n args,\n ctx.scope,\n this.id,\n );\n command = wrapped.command;\n args = wrapped.args;\n }\n\n // Amp expands ${VAR_NAME} natively, so keep refs native (no literals).\n const entry: AmpStdioServer = { command: this.rewrite(command) };\n if (args.length > 0) entry.args = args.map((a) => this.rewrite(a));\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // http (and any other remote transport we surface) — Amp registers a URL.\n const entry: AmpHttpServer = { url: this.rewrite(server.url ?? \"\") };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Amp supports native `${VAR_NAME}` interpolation,\n * so translate `${env:VAR}` refs to that native token rather than baking\n * secrets into the file. Literals pass through unchanged.\n */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(env)) out[k] = this.rewrite(v);\n return out;\n }\n\n /** Translate `${env:VAR(:-default)}` to Amp's native `${VAR}` token. */\n private rewrite(value: string): string {\n return rewriteEnvRefs(value, ampEnvToken);\n }\n\n // ── Skills surface ───────────────────────────────────────────────────────\n // CONTENT-ONLY: pure native-file writers under the skill root. No runtime\n // dispatch, no home-bin pointer, no telemetry wrap. Idempotent (byte-identical\n // → skip) via writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"amp\"].skills === false to skip.\n //\n // QUIRK: the skill root is NOT under getConfigDir (~/.config/amp). Amp reads\n // SKILL.md from the sibling cross-agent `agents` tree:\n // user scope → ~/.config/agents/skills/<name>/SKILL.md\n // project scope → <projectDir>/.agents/skills/<name>/SKILL.md\n // so skillDir() resolves it explicitly rather than reusing getConfigDir.\n\n /** Skill root: user `~/.config/agents/skills`, project `<projectDir>/.agents/skills`. */\n private skillsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".agents\", \"skills\")\n : join(homedir(), \".config\", \"agents\", \"skills\");\n }\n\n /** Native skill dir: <skillRoot>/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for amp\" }];\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 changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), this.renderSkill(skill), ctx.dryRun),\n );\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 }\n return changes;\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 /** Render a skill's SKILL.md (delegates to the shared renderer). */\n private renderSkill(skill: SkillDef): string {\n return renderSkillMd(skill);\n }\n\n // ── Hook install / uninstall (ts-plugin module) ──────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n\n // Amp documents no user-scope plugins dir — only `.amp/plugins/` at project\n // scope. Degradation is never silent: warn-skip rather than write to an\n // unverified user path.\n if (ctx.scope !== \"project\") {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path: pluginPath,\n detail:\n \"amp plugins are project-scoped (.amp/plugins/) — no user-scope plugins dir is documented; skipped\",\n },\n ];\n }\n\n // Native passthrough events are a sibling, amp-scoped declaration: `hooks:\n // false` disables only the CANONICAL events, and the generated native loop\n // reads platforms.amp.nativeHooks directly (independent of hookEvents). So\n // whenever native events exist the plugin must still be synthesized.\n const canonicalDisabled = ctx.connector.platforms[HOST]?.hooks === false;\n const hasCanonical = !canonicalDisabled && ctx.connector.hookEvents.length > 0;\n const hasNative = this.nativeHookEvents(ctx).length > 0;\n\n if (!hasCanonical && !hasNative) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: canonicalDisabled\n ? \"hooks disabled for amp\"\n : \"connector declares no hooks\",\n },\n ];\n }\n\n const files = this.synthesizePlugin(ctx);\n const changes: ChangeRecord[] = [];\n\n for (const file of files) {\n // Idempotent: compare existing contents before writing.\n const before = existsSync(file.path) ? this.safeRead(file.path) : undefined;\n let action: ChangeRecord[\"action\"];\n if (before === undefined) action = \"create\";\n else if (before === file.contents) action = \"skip\";\n else action = \"update\";\n\n if (action !== \"skip\" && !ctx.dryRun) {\n ensureDir(dirname(file.path));\n writeFileSync(file.path, file.contents, \"utf8\");\n chmodSync(file.path, file.executable ? 0o755 : 0o644);\n }\n\n changes.push({\n platform: this.id,\n action,\n path: file.path,\n detail: `amp plugin module (${this.hookDetail(ctx)})`,\n });\n }\n\n return changes;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n if (!existsSync(pluginPath)) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"no amp plugin module present\",\n },\n ];\n }\n if (!ctx.dryRun) rmSync(pluginPath, { force: true });\n return [\n {\n platform: this.id,\n action: \"remove\",\n path: pluginPath,\n detail: \"amp plugin module\",\n },\n ];\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module ACTUALLY\n * wires. Only events present in EVENT_TO_AMP are mapped/wired; any declared\n * event with no Amp mapping (e.g. SessionEnd) is reported separately as\n * \"unsupported here\" so the detail never overstates coverage.\n */\n private hookDetail(ctx: InstallContext): string {\n // `hooks: false` suppresses the canonical handlers, so the detail must not\n // claim them; native events are still reported below.\n const canonicalOff = ctx.connector.platforms[HOST]?.hooks === false;\n const declared = canonicalOff ? [] : ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_AMP[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_AMP[e] === undefined);\n const native = this.nativeHookEvents(ctx);\n const parts: string[] = [];\n if (mapped.length > 0) parts.push(mapped.join(\",\"));\n if (native.length > 0) parts.push(`native: ${native.join(\",\")}`);\n const base = parts.join(\"; \") || \"no canonical hooks\";\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n /**\n * Amp-native passthrough events declared on platforms[\"amp\"].nativeHooks\n * (amp.on event names with no canonical HookEventName analog). Emitted as\n * generic bridge registrations and dispatched host-generically by the home-bin's\n * runNativeHook.\n */\n private nativeHookEvents(ctx: InstallContext): string[] {\n return Object.keys(ctx.connector.platforms[HOST]?.nativeHooks ?? {});\n }\n\n // ── ts-plugin synthesis ──────────────────────────────────────────────────\n\n /**\n * Build ONE self-contained Amp plugin module (`.amp/plugins/<id>.ts`). It\n * imports nothing from agent-connector; each `amp.on(...)` handler shells out to\n * the universal hook entrypoint via child_process and applies the normalized\n * HookResponse. Its default export is the Amp plugin function `(amp) => void`.\n */\n synthesizePlugin(ctx: InstallContext): GeneratedPluginFile[] {\n const path = this.getHookConfigPath(ctx);\n const contents = this.buildPluginSource(ctx);\n return [{ path, contents, executable: false }];\n }\n\n /** Compose the generated plugin source with plain string concatenation. */\n private buildPluginSource(ctx: InstallContext): string {\n const homeBin = JSON.stringify(ctx.homeBinPath);\n const connectorId = JSON.stringify(ctx.connector.id);\n\n // `platforms.amp.hooks === false` disables only the CANONICAL events (the\n // native loop below reads platforms.amp.nativeHooks directly and is a sibling,\n // unaffected). When canonical hooks are off the module may still be\n // synthesized for native events, so the canonical handler set collapses to\n // empty here rather than short-circuiting the whole plugin.\n const canonicalOff = ctx.connector.platforms[HOST]?.hooks === false;\n const events = canonicalOff\n ? []\n : ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_AMP[e] !== undefined,\n );\n const has = (e: HookEventName) => events.includes(e);\n\n const header = `/**\n * AUTO-GENERATED by agent-connector — DO NOT EDIT.\n *\n * Self-contained Amp plugin for connector ${ctx.connector.id}.\n * It imports nothing from agent-connector: every hook invocation shells out to\n * the stable home binary's universal entrypoint and JSON-parses the normalized\n * response. Fail-open: any bridge error degrades to a no-op (never wedges Amp).\n *\n * Amp loads this module from .amp/plugins/${ctx.connector.id}.ts; the default\n * export is the plugin function (amp) => void called once with the PluginAPI.\n */\nimport type { PluginAPI } from \"@ampcode/plugin\";\nimport { execFileSync, execSync } from \"node:child_process\";\n\nconst HOME_BIN = ${homeBin};\nconst CONNECTOR_ID = ${connectorId};\n\n/**\n * Invoke the universal hook entrypoint for one event.\n * @param {string} event canonical event name\n * @param {object} payload amp-shaped payload posted on stdin\n * @returns {object|null} normalized HookResponse, or null on any failure\n */\nfunction bridge(event, payload) {\n try {\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run one\n // quoted command line via a shell. POSIX keeps the direct execFile (no shell).\n const args = [\"hook\", \"amp\", 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 // Fail-open — never wedge an Amp tool call / lifecycle event.\n return null;\n }\n}\n\n// Amp documents no project-dir env var; the plugin process runs in the workspace\n// root, so resolve once at load. Session id is rebound on each session.start.\nconst PROJECT_DIR = process.cwd();\nlet SESSION_ID = \"\";\n`;\n\n const handlers: string[] = [];\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart → rebind the session id and notify the connector.\n // Amp's session.start event carries event.thread.id (ampcode.com/manual →\n // Plugins → session.start: \"Example session.start for \\${event.thread.id}\").\n amp.on(\"session.start\", async (event) => {\n SESSION_ID =\n (event && event.thread && event.thread.id) || \"amp-session\";\n bridge(\"SessionStart\", { sessionId: SESSION_ID, projectDir: PROJECT_DIR });\n });`);\n }\n\n if (has(\"UserPromptSubmit\")) {\n handlers.push(` // UserPromptSubmit → agent.start \"fires when the user submits a prompt\"\n // (ampcode.com/manual). The manual's example takes (_event) and documents no\n // prompt field or return surface, so this is observe-only — the raw event is\n // forwarded for the connector to inspect; any deny/context decision is a no-op.\n amp.on(\"agent.start\", async (event) => {\n bridge(\"UserPromptSubmit\", {\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n raw: event,\n });\n });`);\n }\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → Amp's tool.call returns a decision union (ampcode.com/manual →\n // Plugins → tool.call): { action: \"allow\" } to run, or { action:\n // \"reject-and-continue\", message } to block and let the agent continue. The\n // tool name is event.tool (verified); the input field is not byte-documented,\n // so event.input is a best-effort hint for the connector's matcher (the matcher\n // keys on the verified tool name). A deny/ask decision maps to reject-and-\n // continue; everything else allows.\n amp.on(\"tool.call\", async (event) => {\n const payload = {\n toolName: (event && event.tool) || \"\",\n toolInput: (event && event.input) || {},\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (res && (res.decision === \"deny\" || res.decision === \"ask\")) {\n return {\n action: \"reject-and-continue\",\n message: res.reason || \"Blocked by ${ctx.connector.id}\",\n };\n }\n return { action: \"allow\" };\n });`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → tool.result \"fires after a tool finishes and before the result\n // is sent back to the model\" (ampcode.com/manual). The tool name is event.tool\n // and the error signal is event.status === \"error\" (both verified). The manual\n // says a replacement status/output CAN be returned but never documents the\n // replacement object shape, so this is observe-only (canModifyOutput:false) —\n // the raw event is forwarded; we never return a guessed replacement.\n amp.on(\"tool.result\", async (event) => {\n bridge(\"PostToolUse\", {\n toolName: (event && event.tool) || \"\",\n isError: !!(event && event.status === \"error\"),\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n raw: event,\n });\n });`);\n }\n\n if (has(\"Stop\")) {\n handlers.push(` // Stop → observe turn end. Amp's agent.end exposes no decision surface, so\n // this is observe-only (a deny decision degrades to a no-op).\n amp.on(\"agent.end\", async (event) => {\n bridge(\"Stop\", { sessionId: SESSION_ID, projectDir: PROJECT_DIR, raw: event });\n });`);\n }\n\n // NATIVE passthrough events: amp.on event names with no canonical analog,\n // declared on platforms.amp.nativeHooks (independent of hookEvents, so they\n // install even with hooks:false). Each bridges the NATIVE event name verbatim\n // to the home-bin → runNativeHook dispatches it host-generically.\n for (const ev of this.nativeHookEvents(ctx)) {\n const key = JSON.stringify(ev);\n handlers.push(` // nativeHooks passthrough → ${ev}\n amp.on(${key}, async (event) => {\n bridge(${key}, { sessionId: SESSION_ID, projectDir: PROJECT_DIR, raw: event });\n });`);\n }\n\n const factory = `\nexport default function plugin(amp: PluginAPI) {\n${handlers.join(\"\\n\\n\")}\n}\n`;\n\n return header + factory;\n }\n\n // ── Runtime: parse OUR bridge payload → normalized event ─────────────────\n\n /**\n * `raw` is the payload OUR generated plugin posts (NOT a host-native shape):\n * { toolName?, toolInput?, toolOutput?, isError?, prompt?, sessionId?, projectDir? }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as AmpBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\"\n ? { projectDir: input.projectDir }\n : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.toolName ?? \"\",\n toolInput: input.toolInput ?? {},\n ...(typeof input.toolOutput === \"string\"\n ? { toolOutput: input.toolOutput }\n : {}),\n ...(typeof input.isError === \"boolean\"\n ? { isError: input.isError }\n : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = { ...base };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\n return ev;\n }\n default:\n // Other canonical events are not surfaced by Amp; treat as a\n // session-start-shaped no-op so the dispatcher fails open gracefully.\n return { ...base, source: \"startup\" } satisfies SessionStartEvent;\n }\n }\n\n // ── Runtime: normalized response → reply the generated bridge parses ─────\n\n /**\n * Unlike json-stdio hosts (whose reply is the host's NATIVE control payload),\n * OUR generated bridge consumes this stdout directly. So the reply body is the\n * NORMALIZED HookResponse itself — the bridge JSON.parses it and, for tool.call,\n * maps a deny/ask decision → { action: \"reject-and-continue\" } (else allow).\n * Other events are observe-only, so their reply is ignored by the handler.\n */\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n return {\n exitCode: 0,\n stdout: JSON.stringify(response ?? { decision: \"allow\" }),\n };\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const settingsPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n return [\n {\n name: `${this.name}: settings.json present`,\n check: () =>\n existsSync(settingsPath)\n ? { status: \"OK\", detail: settingsPath }\n : { status: \"FAIL\", detail: `not found: ${settingsPath}` },\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector\n // never writes a server entry, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(settingsPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no \"${MCP_ROOT_KEY}\" in ${settingsPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `\"${MCP_ROOT_KEY}\".${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no \"${MCP_ROOT_KEY}\".${connectorId} in ${settingsPath}`,\n };\n },\n },\n {\n name: `${this.name}: plugin module present`,\n check: () => {\n const hasHooks =\n ctx.connector.hookEvents.length > 0 ||\n this.nativeHookEvents(ctx).length > 0;\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n // Amp plugins are project-scoped; a user-scope install warn-skips the\n // plugin, so its absence there is healthy.\n if (ctx.scope !== \"project\") {\n return {\n status: \"OK\",\n detail: \"amp plugins are project-scoped (user scope skipped)\",\n };\n }\n const pluginPath = this.getHookConfigPath(ctx);\n return existsSync(pluginPath)\n ? { status: \"OK\", detail: pluginPath }\n : { status: \"FAIL\", detail: `not found: ${pluginPath}` };\n },\n },\n ];\n }\n\n /** Read a file, returning undefined on any error (idempotency compare). */\n private safeRead(path: string): string | undefined {\n try {\n return readFileSync(path, \"utf8\");\n } catch {\n return undefined;\n }\n }\n}\n\n/** Create a directory (recursive) if it does not already exist. */\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) mkdirSync(dir, { recursive: true });\n}\n\n/**\n * Amp native interpolation token: `${env:VAR}` → `${VAR}`.\n *\n * When the portable ref carried a default (`${env:VAR:-fallback}`), Amp's native\n * `${VAR}` token has no way to express it — so a bare native token would silently\n * DROP the default. Instead, resolve the default at install time: emit the live\n * value when VAR is set and non-empty, else the literal fallback. The native\n * token is only emitted when there is no default to preserve.\n */\nfunction ampEnvToken(name: string, def?: string): string {\n if (def !== undefined) {\n const v = process.env[name];\n return v != null && v !== \"\" ? v : def;\n }\n return `\\${${name}}`;\n}\n\nexport const adapter = new AmpAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -7,7 +7,7 @@ import {
7
7
  isConcreteSemver,
8
8
  isPlaceholderVersion,
9
9
  registryTransportType
10
- } from "./chunk-4ENJK5S2.js";
10
+ } from "./chunk-DCK5FADX.js";
11
11
  import {
12
12
  writeTomlString
13
13
  } from "./chunk-OPXAP3AC.js";
@@ -1041,4 +1041,4 @@ export {
1041
1041
  packageConnectorAll,
1042
1042
  installInstructions
1043
1043
  };
1044
- //# sourceMappingURL=chunk-QREL7LZJ.js.map
1044
+ //# sourceMappingURL=chunk-2X4EH2D7.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  installInstructions,
4
4
  packageConnector
5
- } from "./chunk-QREL7LZJ.js";
5
+ } from "./chunk-2X4EH2D7.js";
6
6
  import {
7
7
  MARKETPLACE_NAME,
8
8
  agyPluginInstalled,
@@ -44,7 +44,7 @@ import {
44
44
  } from "./chunk-F5RX62T7.js";
45
45
  import {
46
46
  detectInstalledPlatforms
47
- } from "./chunk-EGCBZ2DC.js";
47
+ } from "./chunk-EROJDXMW.js";
48
48
  import {
49
49
  log
50
50
  } from "./chunk-KHO5WNTP.js";
@@ -52,11 +52,11 @@ import {
52
52
  deregisterConnector,
53
53
  loadRegisteredConnector,
54
54
  registerConnector
55
- } from "./chunk-24IDL5RW.js";
55
+ } from "./chunk-MZF2YCXX.js";
56
56
  import {
57
57
  REGISTERED_PLATFORM_IDS,
58
58
  loadAdapter
59
- } from "./chunk-DCKFYWGM.js";
59
+ } from "./chunk-BMD7ANKF.js";
60
60
  import {
61
61
  configPatchManualEdit
62
62
  } from "./chunk-FAHIMJRU.js";
@@ -3032,4 +3032,4 @@ export {
3032
3032
  upgradeViaMarketplace,
3033
3033
  marketplaceDoctorChecks
3034
3034
  };
3035
- //# sourceMappingURL=chunk-RIMVWCZY.js.map
3035
+ //# sourceMappingURL=chunk-5G4EPJ4Y.js.map
@@ -4,11 +4,11 @@
4
4
  var ADAPTER_REGISTRY = [
5
5
  {
6
6
  id: "claude-code",
7
- load: () => import("./claude-code-W4PUFZL5.js").then((m) => m.default)
7
+ load: () => import("./claude-code-T2LPFNC3.js").then((m) => m.default)
8
8
  },
9
9
  {
10
10
  id: "codex",
11
- load: () => import("./codex-DDHIV767.js").then((m) => m.default)
11
+ load: () => import("./codex-O4G7D7KK.js").then((m) => m.default)
12
12
  },
13
13
  {
14
14
  id: "cursor",
@@ -36,7 +36,7 @@ var ADAPTER_REGISTRY = [
36
36
  // its in-process events to the universal hook entrypoint.
37
37
  {
38
38
  id: "opencode",
39
- load: () => import("./opencode-WNXYJR4X.js").then((m) => m.default)
39
+ load: () => import("./opencode-L4BGFP25.js").then((m) => m.default)
40
40
  },
41
41
  // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK
42
42
  // (ts-plugin, MCP root key "mcp", ~/.config/mimocode/mimocode.json). Grouped
@@ -54,7 +54,7 @@ var ADAPTER_REGISTRY = [
54
54
  // the "kilo" extension so there is no fork-ordering constraint between them.
55
55
  {
56
56
  id: "kilo-cli",
57
- load: () => import("./kilo-cli-UZ7R5UOP.js").then((m) => m.default)
57
+ load: () => import("./kilo-cli-2AYCXBQD.js").then((m) => m.default)
58
58
  },
59
59
  // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).
60
60
  {
@@ -70,7 +70,7 @@ var ADAPTER_REGISTRY = [
70
70
  // globalStorage / .kilocode project scope). Distinct host from "kilo-cli".
71
71
  {
72
72
  id: "kilo",
73
- load: () => import("./kilo-5NWOXVSD.js").then((m) => m.default)
73
+ load: () => import("./kilo-IX4T3OHJ.js").then((m) => m.default)
74
74
  },
75
75
  // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-
76
76
  // installed AI coding extension and the PARENT that roo-code and kilo forked.
@@ -105,11 +105,11 @@ var ADAPTER_REGISTRY = [
105
105
  },
106
106
  {
107
107
  id: "amp",
108
- load: () => import("./amp-4U33CU7E.js").then((m) => m.default)
108
+ load: () => import("./amp-XJQ4TDAU.js").then((m) => m.default)
109
109
  },
110
110
  {
111
111
  id: "codebuff",
112
- load: () => import("./codebuff-DH5Y7GAT.js").then((m) => m.default)
112
+ load: () => import("./codebuff-PODYPOOP.js").then((m) => m.default)
113
113
  },
114
114
  {
115
115
  id: "mux",
@@ -168,11 +168,11 @@ var ADAPTER_REGISTRY = [
168
168
  // lands in the wrapped openclaw.json.
169
169
  {
170
170
  id: "nemoclaw",
171
- load: () => import("./nemoclaw-W5KEJ3WX.js").then((m) => m.default)
171
+ load: () => import("./nemoclaw-CQYXZVQN.js").then((m) => m.default)
172
172
  },
173
173
  {
174
174
  id: "openclaw",
175
- load: () => import("./openclaw-EXJEFNZI.js").then((m) => m.default)
175
+ load: () => import("./openclaw-UZC437RW.js").then((m) => m.default)
176
176
  },
177
177
  // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/
178
178
  // (user) and .amazonq/ (project); root key "mcpServers"; bare stdio entry
@@ -234,4 +234,4 @@ export {
234
234
  loadAdapter,
235
235
  allAdapters
236
236
  };
237
- //# sourceMappingURL=chunk-DCKFYWGM.js.map
237
+ //# sourceMappingURL=chunk-BMD7ANKF.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  REGISTERED_PLATFORM_IDS
4
- } from "./chunk-DCKFYWGM.js";
4
+ } from "./chunk-BMD7ANKF.js";
5
5
  import {
6
6
  CONFIG_PATCH_SEGMENT_RE,
7
7
  configPatchNamespaceViolation,
@@ -495,4 +495,4 @@ export {
495
495
  defineConfigPatch,
496
496
  defineNativeHook
497
497
  };
498
- //# sourceMappingURL=chunk-4ENJK5S2.js.map
498
+ //# sourceMappingURL=chunk-DCK5FADX.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ADAPTER_REGISTRY
4
- } from "./chunk-DCKFYWGM.js";
4
+ } from "./chunk-BMD7ANKF.js";
5
5
 
6
6
  // src/adapters/detect.ts
7
7
  async function detectInstalledPlatforms(projectDir) {
@@ -80,4 +80,4 @@ export {
80
80
  detectInstalledPlatforms,
81
81
  detectRuntimeHost
82
82
  };
83
- //# sourceMappingURL=chunk-EGCBZ2DC.js.map
83
+ //# sourceMappingURL=chunk-EROJDXMW.js.map
@@ -9,12 +9,12 @@ import {
9
9
  } from "./chunk-F5RX62T7.js";
10
10
  import {
11
11
  detectRuntimeHost
12
- } from "./chunk-EGCBZ2DC.js";
12
+ } from "./chunk-EROJDXMW.js";
13
13
  import {
14
14
  buildTelemetryAccessor,
15
15
  measureToolCall,
16
16
  measureToolDefs
17
- } from "./chunk-2AVLX7GH.js";
17
+ } from "./chunk-QOGMDOUX.js";
18
18
  import {
19
19
  getTokenizer,
20
20
  inferModelFamily,
@@ -27,11 +27,11 @@ import {
27
27
  import {
28
28
  loadRegisteredConnector,
29
29
  readRegisteredMeta
30
- } from "./chunk-24IDL5RW.js";
30
+ } from "./chunk-MZF2YCXX.js";
31
31
  import {
32
32
  REGISTERED_PLATFORM_IDS,
33
33
  loadAdapter
34
- } from "./chunk-DCKFYWGM.js";
34
+ } from "./chunk-BMD7ANKF.js";
35
35
  import {
36
36
  detectLaunchMethod
37
37
  } from "./chunk-I5MLE6S7.js";
@@ -690,4 +690,4 @@ export {
690
690
  runStatusline,
691
691
  runAction
692
692
  };
693
- //# sourceMappingURL=chunk-5OWS5CMA.js.map
693
+ //# sourceMappingURL=chunk-H67V7DEL.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  defineConnector
4
- } from "./chunk-4ENJK5S2.js";
4
+ } from "./chunk-DCK5FADX.js";
5
5
  import {
6
6
  connectorDir,
7
7
  connectorsDir,
@@ -174,4 +174,4 @@ export {
174
174
  connectorFromMeta,
175
175
  listRegisteredConnectors
176
176
  };
177
- //# sourceMappingURL=chunk-24IDL5RW.js.map
177
+ //# sourceMappingURL=chunk-MZF2YCXX.js.map
@@ -73,36 +73,36 @@ function renderInstallResult(result, verb) {
73
73
  return lines.join("\n");
74
74
  }
75
75
  var COMMANDS = {
76
- detect: () => import("./detect-KG5FG3EV.js"),
77
- install: () => import("./install-BSR62UHJ.js"),
78
- uninstall: () => import("./uninstall-ZYTW7YMZ.js"),
76
+ detect: () => import("./detect-AHJIUMBO.js"),
77
+ install: () => import("./install-R7252QFH.js"),
78
+ uninstall: () => import("./uninstall-FL3SH2DT.js"),
79
79
  // `upgrade` is the single "bring everything current" verb (re-render host
80
80
  // config + refresh the home pointer + managed channel guidance). `sync` and
81
81
  // `update` are kept as back-compat aliases that route to the same module so
82
82
  // existing scripts/docs keep working without a second concept to learn.
83
- upgrade: () => import("./upgrade-4LUEEOZW.js"),
84
- sync: () => import("./upgrade-4LUEEOZW.js"),
85
- update: () => import("./upgrade-4LUEEOZW.js"),
86
- package: () => import("./package-ACZXJHWB.js"),
87
- doctor: () => import("./doctor-FLZF34Y3.js"),
88
- status: () => import("./status-LAJE3BM5.js"),
89
- telemetry: () => import("./telemetry-B3DX3PWU.js"),
90
- usage: () => import("./usage-ZFBVQF3H.js"),
91
- leaderboard: () => import("./leaderboard-MJG24O35.js"),
92
- hook: () => import("./hook-XR3Z45FB.js"),
83
+ upgrade: () => import("./upgrade-SLFG2FCT.js"),
84
+ sync: () => import("./upgrade-SLFG2FCT.js"),
85
+ update: () => import("./upgrade-SLFG2FCT.js"),
86
+ package: () => import("./package-DNLQTPNN.js"),
87
+ doctor: () => import("./doctor-G5MLCPAB.js"),
88
+ status: () => import("./status-VTD6XXLW.js"),
89
+ telemetry: () => import("./telemetry-QCTMKDBQ.js"),
90
+ usage: () => import("./usage-IRBLVUZM.js"),
91
+ leaderboard: () => import("./leaderboard-V6VWA5ZV.js"),
92
+ hook: () => import("./hook-76JBKTUX.js"),
93
93
  // Internal (omitted from USAGE): the statusline (HUD) entrypoint a host's
94
94
  // status line config points at. Fail-safe: always exits 0 with at most a
95
95
  // rendered line. See cli/commands/statusline.ts.
96
- statusline: () => import("./statusline-L376ZPZU.js"),
96
+ statusline: () => import("./statusline-3ET5YPQ5.js"),
97
97
  // Internal (omitted from USAGE): the user-invokable action entrypoint a future
98
98
  // host affordance points at. USER-TRIGGERED: surfaces errors (exit 1 + stderr),
99
99
  // unlike the fail-open hook / fail-safe statusline. See cli/commands/action.ts.
100
- action: () => import("./action-WT7GVRCC.js"),
101
- serve: () => import("./serve-GER7URPR.js"),
100
+ action: () => import("./action-EV63GAPY.js"),
101
+ serve: () => import("./serve-EOVWYBGZ.js"),
102
102
  // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an
103
103
  // AfterModel / PostInvocation hook points at. Always exits 0; records a
104
104
  // distinct `model_turn` row. See cli/commands/usage-event.ts.
105
- "usage-event": () => import("./usage-event-GZ32AGEB.js")
105
+ "usage-event": () => import("./usage-event-VFF77WYY.js")
106
106
  };
107
107
  var DEFAULT_PROGRAM_NAME = "agent-connector";
108
108
  var COMMAND_USAGE = {
@@ -198,4 +198,4 @@ export {
198
198
  renderInstallResult,
199
199
  main
200
200
  };
201
- //# sourceMappingURL=chunk-O5TWCIJN.js.map
201
+ //# sourceMappingURL=chunk-QC5A3TFQ.js.map
@@ -12,11 +12,11 @@ import {
12
12
  import {
13
13
  loadRegisteredConnector,
14
14
  readRegisteredMeta
15
- } from "./chunk-24IDL5RW.js";
15
+ } from "./chunk-MZF2YCXX.js";
16
16
  import {
17
17
  REGISTERED_PLATFORM_IDS,
18
18
  loadAdapter
19
- } from "./chunk-DCKFYWGM.js";
19
+ } from "./chunk-BMD7ANKF.js";
20
20
  import {
21
21
  projectIdentity
22
22
  } from "./chunk-TRQKHP7D.js";
@@ -348,4 +348,4 @@ export {
348
348
  isNativeHookDeclared,
349
349
  runNativeHook
350
350
  };
351
- //# sourceMappingURL=chunk-2AVLX7GH.js.map
351
+ //# sourceMappingURL=chunk-QOGMDOUX.js.map
@@ -34,6 +34,8 @@ var EVENT_TO_OPENCLAW = {
34
34
  PreToolUse: "before_tool_call",
35
35
  PostToolUse: "after_tool_call",
36
36
  SessionStart: "session_start",
37
+ // Per-turn context injection at prompt assembly (context-only, no blocking).
38
+ UserPromptSubmit: "before_prompt_build",
37
39
  // Subagent lifecycle: OpenClaw observes launch + completion (no decision
38
40
  // control on either). PermissionRequest is deliberately ABSENT — OpenClaw's
39
41
  // permission gate is the requireApproval RETURN VALUE of before_tool_call,
@@ -63,7 +65,10 @@ var OpenClawAdapter = class extends BaseAdapter {
63
65
  preCompact: false,
64
66
  sessionStart: true,
65
67
  sessionEnd: false,
66
- userPromptSubmit: false,
68
+ // before_prompt_build fires per-turn and injects context (no blocking), so
69
+ // UserPromptSubmit is supported as CONTEXT-INJECTION-ONLY: a block/deny
70
+ // decision degrades to a no-op (it cannot stop the prompt here).
71
+ userPromptSubmit: true,
67
72
  stop: false,
68
73
  notification: false,
69
74
  // Newer events: OpenClaw observes the full subagent lifecycle via
@@ -96,7 +101,12 @@ var OpenClawAdapter = class extends BaseAdapter {
96
101
  // shelling out to the home-bin action verb with the install target baked as
97
102
  // the host token (this.id), so a fork like NemoClaw emits `action nemoclaw`.
98
103
  // supportsActions -> the installActions/uninstallActions overrides below.
99
- supportsActions: true
104
+ supportsActions: true,
105
+ // Native passthrough: OpenClaw lifecycle hook names with no canonical analog
106
+ // (declared on platforms.<id>.nativeHooks) are bridged verbatim by the
107
+ // generated plugin via the same on(...) helper → home-bin runNativeHook
108
+ // dispatch (mirrors omp/opencode). Independent of hooks:false.
109
+ supportsNativeHooks: true
100
110
  };
101
111
  // ── Tolerant JSON5/JSONC read (override base strict JSON.parse) ──────────
102
112
  /**
@@ -348,18 +358,16 @@ var OpenClawAdapter = class extends BaseAdapter {
348
358
  // ── Hook install / uninstall (ts-plugin + DUAL REGISTRATION) ────────────
349
359
  installHooks(ctx) {
350
360
  const pluginPath = this.getHookConfigPath(ctx);
351
- if (ctx.connector.platforms[this.id]?.hooks === false) {
352
- return [
353
- { platform: this.id, action: "skip", path: pluginPath, detail: `hooks disabled for ${this.id}` }
354
- ];
355
- }
356
- if (ctx.connector.hookEvents.length === 0) {
361
+ const canonicalDisabled = ctx.connector.platforms[this.id]?.hooks === false;
362
+ const hasCanonical = !canonicalDisabled && ctx.connector.hookEvents.length > 0;
363
+ const hasNative = this.nativeHookEvents(ctx).length > 0;
364
+ if (!hasCanonical && !hasNative) {
357
365
  return [
358
366
  {
359
367
  platform: this.id,
360
368
  action: "skip",
361
369
  path: pluginPath,
362
- detail: this.actionTriggers(ctx).length > 0 ? "no hooks (plugin written for actions)" : "connector declares no hooks"
370
+ detail: canonicalDisabled ? `hooks disabled for ${this.id}` : this.actionTriggers(ctx).length > 0 ? "no hooks (plugin written for actions)" : "connector declares no hooks"
363
371
  }
364
372
  ];
365
373
  }
@@ -442,12 +450,25 @@ var OpenClawAdapter = class extends BaseAdapter {
442
450
  * as "unsupported here" so the detail never overstates coverage.
443
451
  */
444
452
  hookDetail(ctx) {
445
- const declared = ctx.connector.hookEvents;
453
+ const declared = ctx.connector.platforms[this.id]?.hooks === false ? [] : ctx.connector.hookEvents;
446
454
  const mapped = declared.filter((e) => EVENT_TO_OPENCLAW[e] !== void 0);
447
455
  const unsupported = declared.filter((e) => EVENT_TO_OPENCLAW[e] === void 0);
448
- const base = mapped.join(",");
456
+ const native = this.nativeHookEvents(ctx);
457
+ const parts = [];
458
+ if (mapped.length > 0) parts.push(mapped.join(","));
459
+ if (native.length > 0) parts.push(`native: ${native.join(",")}`);
460
+ const base = parts.join("; ") || "no canonical hooks";
449
461
  return unsupported.length > 0 ? `${base}; unsupported here: ${unsupported.join(",")}` : base;
450
462
  }
463
+ /**
464
+ * OpenClaw-native passthrough events declared on platforms.<id>.nativeHooks
465
+ * (host lifecycle hook names with no canonical HookEventName). Emitted as
466
+ * generic on(...) bridge registrations and dispatched host-generically by the
467
+ * home-bin's runNativeHook. Independent of hooks:false (supportsNativeHooks).
468
+ */
469
+ nativeHookEvents(ctx) {
470
+ return Object.keys(ctx.connector.platforms[this.id]?.nativeHooks ?? {});
471
+ }
451
472
  uninstallHooks(ctx) {
452
473
  const pluginPath = this.getHookConfigPath(ctx);
453
474
  const configPath = this.getServerConfigPath(ctx);
@@ -730,7 +751,7 @@ var OpenClawAdapter = class extends BaseAdapter {
730
751
  */
731
752
  import { execFileSync, execSync } from "node:child_process";
732
753
 
733
- const HOME_BIN = ` + homeBin + ";\nconst CONNECTOR_ID = " + connectorId + ';\n\n/**\n * Invoke the universal hook entrypoint for one canonical event.\n * @param {string} event canonical event name\n * (PreToolUse|PostToolUse|SessionStart|SubagentStart|SubagentStop)\n * @param {object} payload OpenClaw-shaped payload posted on stdin\n * @returns {object|null} normalized HookResponse, or null on any failure\n */\nfunction bridge(event, payload) {\n try {\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run\n // one quoted command line via a shell. POSIX keeps the direct execFile.\n const args = ["hook", ' + JSON.stringify(this.id) + `, event, "--connector", CONNECTOR_ID];
754
+ const HOME_BIN = ` + homeBin + ";\nconst CONNECTOR_ID = " + connectorId + ';\n\n/**\n * Invoke the universal hook entrypoint for one canonical event.\n * @param {string} event canonical (or native passthrough) event name\n * (PreToolUse|PostToolUse|SessionStart|UserPromptSubmit|SubagentStart|SubagentStop)\n * @param {object} payload OpenClaw-shaped payload posted on stdin\n * @returns {object|null} normalized HookResponse, or null on any failure\n */\nfunction bridge(event, payload) {\n try {\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run\n // one quoted command line via a shell. POSIX keeps the direct execFile.\n const args = ["hook", ' + JSON.stringify(this.id) + `, event, "--connector", CONNECTOR_ID];
734
755
  const opts = { input: JSON.stringify(payload), encoding: "utf8" };
735
756
  const stdout =
736
757
  process.platform === "win32"
@@ -797,7 +818,25 @@ let contextInjected = false;
797
818
  }
798
819
  if (has("SessionStart")) {
799
820
  reg.push(
800
- '\n // SessionStart \u2192 session_start records the real session id and fetches\n // the additionalContext to inject; before_prompt_build performs the\n // injection (the verified context-injection point upstream).\n on("session_start", async (event) => {\n const e = event || {};\n SESSION_ID = e.sessionId || e.sessionKey || SESSION_ID;\n const res = bridge("SessionStart", {\n sessionId: SESSION_ID,\n source: e.resumedFrom ? "resume" : "startup",\n projectDir: PROJECT_DIR,\n });\n contextInjected = false;\n pendingContext =\n res && typeof res.additionalContext === "string" && res.additionalContext\n ? res.additionalContext\n : null;\n return undefined;\n });\n\n // Inject the session-start context once, at prompt-build time.\n on("before_prompt_build", () => {\n if (contextInjected || !pendingContext) return undefined;\n contextInjected = true;\n return { appendSystemContext: pendingContext };\n });\n'
821
+ '\n // SessionStart \u2192 session_start records the real session id and fetches\n // the additionalContext to inject; before_prompt_build performs the\n // injection (the verified context-injection point upstream).\n on("session_start", async (event) => {\n const e = event || {};\n SESSION_ID = e.sessionId || e.sessionKey || SESSION_ID;\n const res = bridge("SessionStart", {\n sessionId: SESSION_ID,\n source: e.resumedFrom ? "resume" : "startup",\n projectDir: PROJECT_DIR,\n });\n contextInjected = false;\n pendingContext =\n res && typeof res.additionalContext === "string" && res.additionalContext\n ? res.additionalContext\n : null;\n return undefined;\n });\n'
822
+ );
823
+ }
824
+ if (has("SessionStart") || has("UserPromptSubmit")) {
825
+ let body = "";
826
+ if (has("SessionStart")) {
827
+ body += " // SessionStart: inject the session-start context exactly once.\n if (!contextInjected && pendingContext) {\n contextInjected = true;\n out.appendSystemContext = pendingContext;\n }\n";
828
+ }
829
+ if (has("UserPromptSubmit")) {
830
+ body += ' // UserPromptSubmit: per-turn context injection. before_prompt_build\n // cannot block, so a deny/block decision degrades to a no-op.\n const e = event || {};\n const ures = bridge("UserPromptSubmit", {\n prompt: typeof e.prompt === "string" ? e.prompt : "",\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n });\n if (ures && typeof ures.additionalContext === "string" && ures.additionalContext) {\n out.appendContext = ures.additionalContext;\n }\n';
831
+ }
832
+ reg.push(
833
+ '\n // before_prompt_build \u2192 coexisting SessionStart (once) + UserPromptSubmit\n // (per-turn) context injection. Context-only: it cannot block a prompt.\n on("before_prompt_build", (event) => {\n const out = {};\n' + body + " return Object.keys(out).length > 0 ? out : undefined;\n });\n"
834
+ );
835
+ }
836
+ for (const ev of this.nativeHookEvents(ctx)) {
837
+ const key = JSON.stringify(ev);
838
+ reg.push(
839
+ "\n // nativeHooks passthrough \u2192 " + ev + "\n on(" + key + ", (event) => {\n bridge(" + key + ", { sessionId: SESSION_ID, projectDir: PROJECT_DIR, raw: event });\n return undefined;\n });\n"
801
840
  );
802
841
  }
803
842
  for (const action of this.actionTriggers(ctx)) {
@@ -857,6 +896,13 @@ let contextInjected = false;
857
896
  const ev = { ...base, source };
858
897
  return ev;
859
898
  }
899
+ case "UserPromptSubmit": {
900
+ const ev = {
901
+ ...base,
902
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
903
+ };
904
+ return ev;
905
+ }
860
906
  case "SubagentStart": {
861
907
  const ev = {
862
908
  ...base,
@@ -897,7 +943,7 @@ let contextInjected = false;
897
943
  const pluginPath = this.getHookConfigPath(ctx);
898
944
  const pluginDir = this.pluginDir(ctx);
899
945
  const id = ctx.connector.id;
900
- const hasHooks = ctx.connector.hookEvents.length > 0 || this.actionTriggers(ctx).length > 0;
946
+ const hasHooks = ctx.connector.hookEvents.length > 0 || this.nativeHookEvents(ctx).length > 0 || this.actionTriggers(ctx).length > 0;
901
947
  const hasServer = Boolean(ctx.connector.server);
902
948
  return [
903
949
  {
@@ -1014,4 +1060,4 @@ export {
1014
1060
  adapter,
1015
1061
  openclaw_default
1016
1062
  };
1017
- //# sourceMappingURL=chunk-URHQMFB3.js.map
1063
+ //# sourceMappingURL=chunk-RQPKL62M.js.map