@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.
- package/README.md +2 -2
- package/dist/{action-WT7GVRCC.js → action-EV63GAPY.js} +8 -8
- package/dist/amp-XJQ4TDAU.js +666 -0
- package/dist/amp-XJQ4TDAU.js.map +1 -0
- package/dist/{chunk-QREL7LZJ.js → chunk-2X4EH2D7.js} +2 -2
- package/dist/{chunk-RIMVWCZY.js → chunk-5G4EPJ4Y.js} +5 -5
- package/dist/{chunk-DCKFYWGM.js → chunk-BMD7ANKF.js} +10 -10
- package/dist/{chunk-4ENJK5S2.js → chunk-DCK5FADX.js} +2 -2
- package/dist/{chunk-EGCBZ2DC.js → chunk-EROJDXMW.js} +2 -2
- package/dist/{chunk-5OWS5CMA.js → chunk-H67V7DEL.js} +5 -5
- package/dist/{chunk-24IDL5RW.js → chunk-MZF2YCXX.js} +2 -2
- package/dist/{chunk-O5TWCIJN.js → chunk-QC5A3TFQ.js} +18 -18
- package/dist/{chunk-2AVLX7GH.js → chunk-QOGMDOUX.js} +3 -3
- package/dist/{chunk-URHQMFB3.js → chunk-RQPKL62M.js} +61 -15
- package/dist/chunk-RQPKL62M.js.map +1 -0
- package/dist/{chunk-XJ4S47CT.js → chunk-SRVAA2VN.js} +2 -2
- package/dist/{claude-code-W4PUFZL5.js → claude-code-T2LPFNC3.js} +4 -4
- package/dist/cli/sdk.js +4 -4
- package/dist/cli.js +1 -1
- package/dist/{codebuff-DH5Y7GAT.js → codebuff-PODYPOOP.js} +126 -5
- package/dist/codebuff-PODYPOOP.js.map +1 -0
- package/dist/{codex-DDHIV767.js → codex-O4G7D7KK.js} +19 -3
- package/dist/codex-O4G7D7KK.js.map +1 -0
- package/dist/{detect-KG5FG3EV.js → detect-AHJIUMBO.js} +4 -4
- package/dist/{doctor-FLZF34Y3.js → doctor-G5MLCPAB.js} +8 -8
- package/dist/{hook-XR3Z45FB.js → hook-76JBKTUX.js} +8 -8
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{install-BSR62UHJ.js → install-R7252QFH.js} +8 -8
- package/dist/{introspect-Nw8hTReX.d.ts → introspect-Cn3MSA4_.d.ts} +1 -1
- package/dist/{kilo-5NWOXVSD.js → kilo-IX4T3OHJ.js} +100 -4
- package/dist/kilo-IX4T3OHJ.js.map +1 -0
- package/dist/{kilo-cli-UZ7R5UOP.js → kilo-cli-2AYCXBQD.js} +107 -11
- package/dist/kilo-cli-2AYCXBQD.js.map +1 -0
- package/dist/{leaderboard-MJG24O35.js → leaderboard-V6VWA5ZV.js} +2 -2
- package/dist/{nemoclaw-W5KEJ3WX.js → nemoclaw-CQYXZVQN.js} +2 -2
- package/dist/{openclaw-EXJEFNZI.js → openclaw-UZC437RW.js} +2 -2
- package/dist/{opencode-WNXYJR4X.js → opencode-L4BGFP25.js} +4 -1
- package/dist/opencode-L4BGFP25.js.map +1 -0
- package/dist/{package-ACZXJHWB.js → package-DNLQTPNN.js} +6 -6
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +6 -6
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +5 -5
- package/dist/{serve-GER7URPR.js → serve-EOVWYBGZ.js} +8 -8
- package/dist/{status-LAJE3BM5.js → status-VTD6XXLW.js} +6 -6
- package/dist/{statusline-L376ZPZU.js → statusline-3ET5YPQ5.js} +7 -7
- package/dist/{telemetry-B3DX3PWU.js → telemetry-QCTMKDBQ.js} +5 -5
- package/dist/{types-CRVrFWeU.d.ts → types-_6arHbX9.d.ts} +5 -4
- package/dist/{uninstall-ZYTW7YMZ.js → uninstall-FL3SH2DT.js} +8 -8
- package/dist/{upgrade-4LUEEOZW.js → upgrade-SLFG2FCT.js} +8 -8
- package/dist/{usage-ZFBVQF3H.js → usage-IRBLVUZM.js} +2 -2
- package/dist/{usage-event-GZ32AGEB.js → usage-event-VFF77WYY.js} +7 -7
- package/package.json +1 -1
- package/dist/amp-4U33CU7E.js +0 -300
- package/dist/amp-4U33CU7E.js.map +0 -1
- package/dist/chunk-URHQMFB3.js.map +0 -1
- package/dist/codebuff-DH5Y7GAT.js.map +0 -1
- package/dist/codex-DDHIV767.js.map +0 -1
- package/dist/kilo-5NWOXVSD.js.map +0 -1
- package/dist/kilo-cli-UZ7R5UOP.js.map +0 -1
- package/dist/opencode-WNXYJR4X.js.map +0 -1
- /package/dist/{action-WT7GVRCC.js.map → action-EV63GAPY.js.map} +0 -0
- /package/dist/{chunk-QREL7LZJ.js.map → chunk-2X4EH2D7.js.map} +0 -0
- /package/dist/{chunk-RIMVWCZY.js.map → chunk-5G4EPJ4Y.js.map} +0 -0
- /package/dist/{chunk-DCKFYWGM.js.map → chunk-BMD7ANKF.js.map} +0 -0
- /package/dist/{chunk-4ENJK5S2.js.map → chunk-DCK5FADX.js.map} +0 -0
- /package/dist/{chunk-EGCBZ2DC.js.map → chunk-EROJDXMW.js.map} +0 -0
- /package/dist/{chunk-5OWS5CMA.js.map → chunk-H67V7DEL.js.map} +0 -0
- /package/dist/{chunk-24IDL5RW.js.map → chunk-MZF2YCXX.js.map} +0 -0
- /package/dist/{chunk-O5TWCIJN.js.map → chunk-QC5A3TFQ.js.map} +0 -0
- /package/dist/{chunk-2AVLX7GH.js.map → chunk-QOGMDOUX.js.map} +0 -0
- /package/dist/{chunk-XJ4S47CT.js.map → chunk-SRVAA2VN.js.map} +0 -0
- /package/dist/{claude-code-W4PUFZL5.js.map → claude-code-T2LPFNC3.js.map} +0 -0
- /package/dist/{detect-KG5FG3EV.js.map → detect-AHJIUMBO.js.map} +0 -0
- /package/dist/{doctor-FLZF34Y3.js.map → doctor-G5MLCPAB.js.map} +0 -0
- /package/dist/{hook-XR3Z45FB.js.map → hook-76JBKTUX.js.map} +0 -0
- /package/dist/{install-BSR62UHJ.js.map → install-R7252QFH.js.map} +0 -0
- /package/dist/{leaderboard-MJG24O35.js.map → leaderboard-V6VWA5ZV.js.map} +0 -0
- /package/dist/{nemoclaw-W5KEJ3WX.js.map → nemoclaw-CQYXZVQN.js.map} +0 -0
- /package/dist/{openclaw-EXJEFNZI.js.map → openclaw-UZC437RW.js.map} +0 -0
- /package/dist/{package-ACZXJHWB.js.map → package-DNLQTPNN.js.map} +0 -0
- /package/dist/{serve-GER7URPR.js.map → serve-EOVWYBGZ.js.map} +0 -0
- /package/dist/{status-LAJE3BM5.js.map → status-VTD6XXLW.js.map} +0 -0
- /package/dist/{statusline-L376ZPZU.js.map → statusline-3ET5YPQ5.js.map} +0 -0
- /package/dist/{telemetry-B3DX3PWU.js.map → telemetry-QCTMKDBQ.js.map} +0 -0
- /package/dist/{uninstall-ZYTW7YMZ.js.map → uninstall-FL3SH2DT.js.map} +0 -0
- /package/dist/{upgrade-4LUEEOZW.js.map → upgrade-SLFG2FCT.js.map} +0 -0
- /package/dist/{usage-ZFBVQF3H.js.map → usage-IRBLVUZM.js.map} +0 -0
- /package/dist/{usage-event-GZ32AGEB.js.map → usage-event-VFF77WYY.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/codebuff/index.ts"],"sourcesContent":["/**\n * adapters/codebuff — Codebuff platform adapter for agent-connector.\n *\n * Codebuff is an **mcp-only** host: it exposes no lifecycle hook system, and MCP\n * is its extensibility mechanism. This adapter therefore installs only the MCP\n * server and reports hooks as unavailable (mirrors the Warp reference path that\n * validates the `mcp-only` paradigm end-to-end).\n *\n * MCP config (SPEC):\n * - project scope (preferred) → <projectDir>/.agents/mcp.json\n * - user scope → ~/.agents/mcp.json\n * Both are JSON, root key \"mcpServers\". There is no separate hook file — the\n * hook \"config path\" is the same mcp.json so the generic doctor/backup behave\n * sensibly.\n *\n * A stdio server entry is the standard `{ type:\"stdio\", command, args, env }`\n * shape. Codebuff supports native `$VAR` interpolation, so `${env:VAR}` refs are\n * rewritten to Codebuff's native `$VAR` token (rewriteEnvRefs) rather than being\n * resolved to literals — secrets are never baked into the config file.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, InstallContext } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookParadigm,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n SkillDef,\n Transport,\n} from \"../../core/types.js\";\nimport { rewriteEnvRefs } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"codebuff\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Render `${env:VAR}`/`${env:VAR:-default}` into Codebuff's native `$VAR` token.\n *\n * When the portable ref carried a default (`${env:VAR:-fallback}`), Codebuff's\n * native `$VAR` token cannot 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 */\nconst toNativeRef = (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\n/** Recursively rewrite every `${env:VAR}` ref in a JSON-ish value to `$VAR`. */\nfunction rewriteEnvRefsDeep<T>(value: T): T {\n if (typeof value === \"string\") {\n return rewriteEnvRefs(value, toNativeRef) as unknown as T;\n }\n if (Array.isArray(value)) {\n return value.map((v) => rewriteEnvRefsDeep(v)) as unknown as T;\n }\n if (value && typeof value === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value)) out[k] = rewriteEnvRefsDeep(v);\n return out as T;\n }\n return value;\n}\n\n/**\n * Native MCP server entry shapes Codebuff accepts under `mcpServers`.\n * A stdio entry is tagged with `type:\"stdio\"`; remote transports carry a `url`.\n */\ninterface CodebuffStdioServer {\n type: \"stdio\";\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface CodebuffHttpServer {\n type: \"http\";\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class CodebuffAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Codebuff\";\n readonly paradigm: HookParadigm = \"mcp-only\";\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 // Codebuff has no lifecycle hook system — every hook capability is false.\n preToolUse: false,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Codebuff registers stdio and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"http\"],\n // Content surfaces: Codebuff reads AgentSkills from\n // <configDir>/skills/<name>/SKILL.md (configDir is .agents, so the path is\n // .agents/skills/<name>/SKILL.md). Verified against codebuff source\n // sdk/src/skills/load-skills.ts — the frontmatter `name` MUST equal the dir\n // name. Commands have no native Codebuff surface. Subagents ARE natively\n // supported — executable .agents/*.ts AgentDefinition modules (codebuff docs:\n // \"Create a new TypeScript file in .agents/\") — but rendering one is coupled\n // to the codebuff SDK's AgentDefinition schema, so supportsSubagents stays\n // false (deferred), NOT because the surface is absent.\n supportsSkills: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".agents\");\n const userMcp = join(userDir, \"mcp.json\");\n const projDir = join(projectDir, \".agents\");\n const projMcp = join(projDir, \"mcp.json\");\n\n const userInstalled = existsSync(userDir) || existsSync(userMcp);\n const projInstalled = existsSync(projDir) || existsSync(projMcp);\n const installed = userInstalled || projInstalled;\n // Project is the preferred scope; fall back to user when only that matched.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projMcp : userMcp;\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 Codebuff config (${scope})`\n : `no .agents config dir at ${userDir} or ${projDir}`,\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, \".agents\")\n : join(homedir(), \".agents\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /**\n * Codebuff has no hook file — hooks are not a thing here. The hook \"config\n * path\" is the same mcp.json so the generic doctor/backup behave sensibly.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\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 codebuff\"\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 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 Codebuff's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): CodebuffStdioServer | CodebuffHttpServer {\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 // Codebuff supports native `$VAR` interpolation, so rewrite every\n // ${env:VAR} ref to `$VAR` rather than baking literals into the config.\n const entry: CodebuffStdioServer = {\n type: \"stdio\",\n command: rewriteEnvRefsDeep(command),\n };\n if (args.length > 0) entry.args = rewriteEnvRefsDeep(args);\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) — Codebuff registers a URL.\n const entry: CodebuffHttpServer = {\n type: \"http\",\n url: rewriteEnvRefsDeep(server.url ?? \"\"),\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Codebuff supports native `$VAR` interpolation, so\n * rewrite `${env:VAR}` references to `$VAR` rather than resolving to literals.\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 return rewriteEnvRefsDeep({ ...env });\n }\n\n // ── Content surfaces: skills ──────────────────────────────────────────────\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[\"codebuff\"].skills === false to skip. Both user and project scope\n // are supported (configDir resolves per scope).\n //\n // Native location:\n // skill → <configDir>/skills/<name>/SKILL.md (+ resources)\n // configDir is .agents, so .agents/skills/<name>/SKILL.md. Verified\n // against codebuff source sdk/src/skills/load-skills.ts — the\n // frontmatter `name` MUST equal the dir name.\n\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.getConfigDir(ctx), \"skills\", 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 codebuff\" }];\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 /**\n * Render a skill's SKILL.md: frontmatter (name, description + optional model,\n * allowed-tools, disable-model-invocation) + body. UNIFORM with every other\n * skill-supporting platform — only the parent dir differs. Codebuff requires\n * the frontmatter `name` to equal the dir name (load-skills.ts), which holds\n * because skillDir uses skill.name for both.\n */\n private renderSkill(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 this.renderFrontmatterMd(frontmatter, skill.body);\n }\n\n // ── Hooks (unavailable — Codebuff is mcp-only) ────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Codebuff is mcp-only)\",\n },\n ];\n }\n\n uninstallHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Codebuff is mcp-only)\",\n },\n ];\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\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> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\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 ${mcpPath}`,\n };\n },\n },\n ];\n\n // Content-surface checks: assert presence only for the skills this connector\n // declares (a skill-less connector writes none, so absence is healthy).\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 return checks;\n }\n}\n\nexport const adapter = new CodebuffAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
|
@@ -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 CommandDef,\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 { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { writeTomlString } from \"../../core/toml.js\";\nimport {\n buildHomeBinHookCommand,\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\nimport { BaseAdapter } 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\ninterface CodexHooksFile {\n hooks?: Record<string, CodexHookEntry[]>;\n [key: string]: unknown;\n}\n\n/** Rendered `[mcp_servers.<id>]` table — string env table, no interpolation. */\ninterface CodexMcpEntry {\n command: string;\n args?: string[];\n env?: 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` || `~/.codex` for user scope. */\n private userConfigDir(): string {\n const env = process.env.CODEX_HOME;\n if (env && env.trim() !== \"\") {\n if (env.startsWith(\"~\")) {\n return join(homedir(), env.replace(/^~[/\\\\]?/, \"\"));\n }\n return env;\n }\n return join(homedir(), \".codex\");\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 // ── 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 if (server.transport !== \"stdio\" || !server.command) {\n // Codex config.toml [mcp_servers] is stdio-only; remote transports skip here.\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `transport \"${server.transport}\" not registrable in config.toml (stdio only)`,\n },\n ];\n }\n\n const entry = this.renderMcpEntry(ctx, server);\n\n const cfg = this.readToml(path);\n const bucket = this.tomlBucket(cfg, \"mcp_servers\");\n const before = JSON.stringify(bucket[connector.id]);\n const after = JSON.stringify(entry);\n\n let action: ChangeRecord[\"action\"];\n if (before === undefined) action = \"create\";\n else if (before === after) action = \"skip\";\n else action = \"update\";\n\n if (action !== \"skip\") {\n bucket[connector.id] = entry as unknown as Record<string, unknown>;\n this.writeToml(path, cfg, dryRun);\n }\n return [{ platform: this.id, action, path, detail: `mcp_servers.${connector.id}` }];\n }\n\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const cfg = this.readToml(path);\n const bucket = cfg[\"mcp_servers\"];\n if (\n !existsSync(path) ||\n typeof bucket !== \"object\" ||\n bucket === null ||\n !(connector.id in (bucket as Record<string, unknown>))\n ) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `mcp_servers.${connector.id} absent`,\n },\n ];\n }\n delete (bucket as Record<string, unknown>)[connector.id];\n this.writeToml(path, cfg, dryRun);\n return [{ platform: this.id, action: \"remove\", path, detail: `mcp_servers.${connector.id}` }];\n }\n\n // ── Install hooks (hooks.json) ──────────────────────────────────────────\n\n override installHooks(ctx: InstallContext): ChangeRecord[] {\n const { dryRun } = ctx;\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 const file = this.readHooksFile(path);\n const hooks = (file.hooks ??= {});\n const changes: ChangeRecord[] = [];\n\n // Declared events Codex cannot fire are reported, never silently dropped.\n for (const event of dropped) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path,\n detail: `${event} has no Codex hook equivalent — skipped`,\n });\n }\n\n for (const event of events) {\n const desired = this.renderHookEntry(ctx, event);\n const list = Array.isArray(hooks[event]) ? hooks[event] : (hooks[event] = []);\n const idx = list.findIndex((e) => this.isOurEntry(ctx, event, e));\n if (idx < 0) {\n list.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `hooks.${event}` });\n } else if (JSON.stringify(list[idx]) !== JSON.stringify(desired)) {\n list[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `hooks.${event}` });\n } else {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `hooks.${event}` });\n }\n }\n\n // Only a real entry mutation rewrites the file (a warn-skip must not\n // create/touch hooks.json by itself).\n if (changes.some((c) => c.action === \"create\" || c.action === \"update\")) {\n this.writeJson(path, file, dryRun);\n }\n return changes;\n }\n\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const file = this.readJson<CodexHooksFile>(path);\n const hooks = file?.hooks;\n if (!file || !hooks) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks.json\" }];\n }\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n for (const event of CODEX_HOOK_EVENTS) {\n const list = hooks[event];\n if (!Array.isArray(list)) continue;\n const kept = list.filter((e) => !this.isOurEntry(ctx, event, e));\n if (kept.length === list.length) continue;\n mutated = true;\n if (kept.length > 0) hooks[event] = kept;\n else delete hooks[event];\n changes.push({ platform: this.id, action: \"remove\", path, detail: `hooks.${event}` });\n }\n\n if (mutated) this.writeJson(path, file, ctx.dryRun);\n if (changes.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no agent-connector hooks present\" }];\n }\n return changes;\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(this.commandPath(cmd.name), this.renderCommand(cmd), ctx.dryRun),\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 /** Render a command to md+frontmatter (description, argument-hint). */\n private renderCommand(cmd: CommandDef): string {\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 (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return this.renderFrontmatterMd(frontmatter, cmd.prompt);\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 = this.renderSkill(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 /**\n * Render a skill's SKILL.md: frontmatter (name, description + optional model,\n * allowed-tools, disable-model-invocation) + body. UNIFORM with every other\n * skill-supporting platform — only the parent dir differs.\n */\n private renderSkill(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 this.renderFrontmatterMd(frontmatter, skill.body);\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: this.normalizeSource(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 let command = server.command as string;\n let args = [...(server.args ?? [])];\n\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(ctx.homeBinPath, ctx.connector.id, command, args, ctx.scope, this.id);\n command = wrapped.command;\n args = wrapped.args;\n }\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 /** Render one hooks.json entry pointing at the stable home binary. */\n private renderHookEntry(ctx: InstallContext, event: CodexHookEventName): CodexHookEntry {\n const command = buildHomeBinHookCommand(\n ctx.homeBinPath,\n \"codex\",\n event,\n ctx.connector.id,\n );\n const entry: CodexHookEntry = { hooks: [{ type: \"command\", command }] };\n // PermissionRequest matches tool names exactly like PreToolUse (Bash,\n // apply_patch aliases, mcp__* names), so it carries the same charset-clean\n // matcher. Subagent* match agent_type — register \"\" (all agents) and let the\n // universal entrypoint apply the connector's own matcher at runtime.\n if (event === \"PreToolUse\" || event === \"PermissionRequest\") {\n entry.matcher = PRE_TOOL_USE_MATCHER;\n } else entry.matcher = \"\";\n return entry;\n }\n\n /** Does this hooks.json entry belong to this connector (by home-bin command)? */\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 private readHooksFile(path: string): CodexHooksFile {\n return this.readJson<CodexHooksFile>(path) ?? {};\n }\n\n /** Get-or-create a nested table inside a parsed TOML object. */\n private tomlBucket(cfg: Record<string, unknown>, key: string): Record<string, unknown> {\n const existing = cfg[key];\n if (existing && typeof existing === \"object\" && !Array.isArray(existing)) {\n return existing as Record<string, unknown>;\n }\n const fresh: Record<string, unknown> = {};\n cfg[key] = fresh;\n return fresh;\n }\n\n private normalizeSource(raw: string | undefined): \"startup\" | \"compact\" | \"resume\" | \"clear\" {\n switch (raw) {\n case \"compact\":\n return \"compact\";\n case \"resume\":\n return \"resume\";\n case \"clear\":\n return \"clear\";\n default:\n return \"startup\";\n }\n }\n}\n\nexport const adapter = new CodexAdapter();\nexport default adapter;\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/kilo/index.ts"],"sourcesContent":["/**\n * adapters/kilo — Kilo Code (VS Code extension) platform adapter.\n *\n * Kilo Code (`kilocode.kilo-code`) is a Roo/Cline-fork VS Code extension that\n * as of vsix 7.x was REBUILT on the Kilo CLI server and shares ONE backend with\n * the Kilo CLI (adapter id \"kilo-cli\"). Paradigm: **ts-plugin** (same plugin\n * layer the CLI uses).\n *\n * MCP config (vsix 7.3.28 — delegated to the kilo backend):\n * - user scope → ~/.config/kilo/kilo.json (XDG: $XDG_CONFIG_HOME/kilo)\n * - project scope → <projectDir>/.kilo/kilo.json\n * Both are JSON, root key **\"mcp\"**, entry shape\n * { type:\"local\", command:[exe,...args], environment:{} } (array command).\n * The legacy globalStorage `<vscodeUserDir>/globalStorage/kilocode.kilo-code/\n * settings/mcp_settings.json` (root \"mcpServers\") is MIGRATION-ONLY in 7.3.28\n * and is no longer the live write target — detectInstalled() still probes it so\n * an older install is recognized, but we install into kilo.json.\n *\n * SHARED BACKEND NOTE: kilo.json (VS Code ext) AND kilo.jsonc (CLI) are MERGED\n * by the ONE shared backend at user / project-root / .kilo/ levels — 3-way merge\n * verified live. The two platform IDs remain distinct for collision tracking, but\n * they share the same config dir and the backend dedupes across both files.\n *\n * Env interpolation: {env:VARIABLE_NAME} is documented by the pi/kilo backend.\n * We still resolve env refs to literals at install time (the conservative path,\n * consistent with kilo-cli) to avoid any version dependency on the interpolation\n * feature being present at runtime.\n *\n * Hooks (ts-plugin — same layer as kilo-cli):\n * The plugins doc banner reads \"applies to current VSCode extension & CLI\".\n * Plugin dirs: project → <projectDir>/.kilo/plugin/, user → ~/.config/kilo/plugin/.\n * Auto-discovery applies (as in the CLI ≥ 7.3.16), and we ALSO register the\n * module path in kilo.json's `plugin` array for explicit load (both loaded).\n * Event names: same as kilo-cli (\"tool.execute.before\", \"tool.execute.after\",\n * \"experimental.chat.system.transform\"). Bridge shims to \"kilo\" (not \"kilo-cli\").\n *\n * Content surfaces:\n * Commands → .kilo/commands (project) / ~/.config/kilo/commands (user)\n * Skills → .kilo/skills/<name>/SKILL.md (project) / ~/.kilo/skills (user)\n * Subagents → .kilo/agents (project) / ~/.config/kilo/agents (user)\n */\n\nimport {\n chmodSync,\n existsSync,\n mkdirSync,\n readFileSync,\n rmSync,\n writeFileSync,\n} from \"node:fs\";\nimport { homedir, platform as osPlatform } 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 MemoryTarget,\n NormalizedEvent,\n} from \"../spi.js\";\nimport type {\n ChangeRecord,\n CommandDef,\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 SubagentDef,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"kilo\";\n/** vsix 7.3.28 root key in kilo.json (delegated kilo backend). */\nconst MCP_ROOT_KEY = \"mcp\";\n/** kilo.json array of plugin module paths (also supports auto-discovery). */\nconst PLUGIN_ARRAY_KEY = \"plugin\";\n/** Live config filename for the VS Code ext (DISTINCT from the CLI's kilo.jsonc). */\nconst CONFIG_FILE = \"kilo.json\";\n\n/** Kilo Code extension id → its (legacy, migration-only) VS Code globalStorage folder. */\nconst KILO_EXTENSION_ID = \"kilocode.kilo-code\";\n/**\n * Legacy globalStorage MCP settings filenames (MIGRATION-ONLY in 7.3.28). The\n * Cline-family alternative is probed during detection so an older install is\n * still recognized; we no longer WRITE there.\n */\nconst LEGACY_MCP_SETTINGS_FILE = \"mcp_settings.json\";\nconst LEGACY_CLINE_SETTINGS_FILE = \"cline_mcp_settings.json\";\n\n/**\n * Canonical → Kilo (shared ts-plugin layer) event name map. Identical to the\n * kilo-cli mapping: the extension and CLI share the same plugin event model.\n */\nconst EVENT_TO_KILO: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n SessionStart: \"experimental.chat.system.transform\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface KiloBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n sessionId?: string;\n projectDir?: string;\n}\n\n/**\n * Native MCP server entry shapes kilo.json accepts under `mcp` (the delegated\n * kilo backend). Local (stdio) servers use a SINGLE array command that folds the\n * executable and its args together; env lives under `environment`.\n */\ninterface KiloLocalServer {\n type: \"local\";\n command: string[];\n environment: Record<string, string>;\n}\ninterface KiloRemoteServer {\n type: \"remote\";\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Resolve the kilo backend user config dir: `$XDG_CONFIG_HOME/kilo` when set,\n * else `~/.config/kilo`. This is the SAME backend dir kilo-cli uses (the two\n * differ only by filename — kilo.json here vs kilo.jsonc for the CLI).\n */\nfunction kiloConfigDir(): string {\n const xdg = process.env.XDG_CONFIG_HOME;\n const base =\n xdg && xdg.trim() !== \"\" ? xdg : join(homedir(), \".config\");\n return join(base, \"kilo\");\n}\n\n/**\n * Resolve the cross-OS VS Code per-user data directory (the \"User\" folder that\n * contains `globalStorage`) — used ONLY to probe the legacy migration-only MCP\n * settings file during detection. See module header for the per-platform mapping.\n */\nfunction vscodeUserDir(): string {\n const home = homedir();\n switch (osPlatform()) {\n case \"darwin\":\n return join(home, \"Library\", \"Application Support\", \"Code\", \"User\");\n case \"win32\": {\n const appData = process.env.APPDATA ?? join(home, \"AppData\", \"Roaming\");\n return join(appData, \"Code\", \"User\");\n }\n default:\n // Linux / other POSIX: XDG-style config dir.\n return join(home, \".config\", \"Code\", \"User\");\n }\n}\n\nexport class KiloAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Kilo Code\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block (project <projectDir>/AGENTS.md\n // via the base default; user scope → ~/.kilocode/rules/agent-connector.md below).\n supportsMemory: true,\n // Kilo Code 7.x shares the ts-plugin layer with the Kilo CLI — same events.\n preToolUse: true,\n postToolUse: true,\n preCompact: false,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n canModifyArgs: true,\n canModifyOutput: true,\n canInjectSessionContext: true,\n // Kilo Code registers stdio, SSE, and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: commands, skills (since 7.x rebuild), and subagents.\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userConfig = this.userConfigPath();\n const userBackendDir = kiloConfigDir();\n // Probe the legacy (migration-only) globalStorage MCP settings too so an\n // older install is still recognized; we never WRITE there anymore.\n const legacyExtDir = join(vscodeUserDir(), \"globalStorage\", KILO_EXTENSION_ID);\n const legacySettings = join(legacyExtDir, \"settings\", LEGACY_MCP_SETTINGS_FILE);\n const legacyClineSettings = join(\n legacyExtDir,\n \"settings\",\n LEGACY_CLINE_SETTINGS_FILE,\n );\n const projectConfig = join(projectDir, \".kilo\", CONFIG_FILE);\n\n const userMatch =\n existsSync(userConfig) ||\n existsSync(userBackendDir) ||\n existsSync(legacySettings) ||\n existsSync(legacyClineSettings) ||\n existsSync(legacyExtDir);\n const projectMatch = existsSync(projectConfig);\n const installed = userMatch || projectMatch;\n\n // Prefer the user scope/path when present; otherwise surface the project one.\n const scope = userMatch || !projectMatch ? \"user\" : \"project\";\n const configPath = scope === \"user\" ? userConfig : projectConfig;\n const reason = installed\n ? userMatch\n ? `found Kilo Code config under ${userBackendDir}`\n : `found Kilo Code project config at ${projectConfig}`\n : `no Kilo Code config at ${userBackendDir} or ${projectConfig}`;\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,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /** Absolute path to the user-scope kilo.json (kilo backend, XDG dir). */\n private userConfigPath(): string {\n return join(kiloConfigDir(), CONFIG_FILE);\n }\n\n // ── Memory surface: global rules dir at user scope ──────────────────────\n // Project scope stays on the AGENTS.md base default. User scope targets a\n // dedicated agent-connector.md in the legacy-compatible ~/.kilocode/rules/\n // dir (always loaded; avoids JSONC `instructions` edits in kilo.jsonc; the\n // AC-created file is cleanly deletable on uninstall). Shared backend with\n // kilo-cli — the convergent write dedupes via the content hash.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"user\") {\n return super.memoryTargets(ctx);\n }\n return [\n {\n path: join(homedir(), \".kilocode\", \"rules\", \"agent-connector.md\"),\n reason: \"kilo global rules dir (~/.kilocode/rules; agent-connector-owned file)\",\n },\n ];\n }\n\n /**\n * MCP config dir. Note the project surface is `.kilo/` (kilo backend), NOT the\n * extension's `.kilocode/` content tree (which still hosts commands/subagents).\n */\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\")\n : kiloConfigDir();\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", CONFIG_FILE)\n : this.userConfigPath();\n }\n\n /**\n * For ts-plugin hosts the \"hook config path\" is the generated plugin FILE.\n * The backend also supports auto-discovery from the plugin dir, but we ALSO\n * register the path in kilo.json's `plugin` array for explicit load (idempotent).\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.pluginDir(ctx), this.pluginFileName(ctx));\n }\n\n /** Plugin directory the synthesized module is written into, per scope. */\n private pluginDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", \"plugin\")\n : join(kiloConfigDir(), \"plugin\");\n }\n\n /** Plugin module file name (one per connector, kebab-case id). */\n private pluginFileName(ctx: InstallContext): string {\n return `${ctx.connector.id}.js`;\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 kilo\"\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 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 /**\n * Render a normalized ServerDef into kilo.json's native `mcp` entry. Local\n * (stdio) servers fold the executable + args into a SINGLE `command` array and\n * carry env under `environment`; remote servers use a `type:\"remote\"` URL entry.\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): KiloLocalServer | KiloRemoteServer {\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 // Resolve ${env:VAR} to literals at install time (conservative; consistent\n // with kilo-cli even though {env:VARIABLE_NAME} is documented).\n const argv: string[] = [\n resolveEnvRefsDeep(command),\n ...resolveEnvRefsDeep(args),\n ];\n const entry: KiloLocalServer = {\n type: \"local\",\n command: argv,\n environment: this.renderEnv(server.env) ?? {},\n };\n return entry;\n }\n\n // sse / http (and any other remote transport) — kilo registers a remote URL.\n const entry: KiloRemoteServer = {\n type: \"remote\",\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Resolve `${env:VAR}` references to literals at\n * install time for consistency with kilo-cli.\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 return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hook install / uninstall (ts-plugin + explicit `plugin` array) ────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n const configPath = this.getServerConfigPath(ctx);\n\n if (ctx.connector.platforms[HOST]?.hooks === false) {\n return [\n { platform: this.id, action: \"skip\", path: pluginPath, detail: \"hooks disabled for kilo\" },\n ];\n }\n if (ctx.connector.hookEvents.length === 0) {\n return [\n { platform: this.id, action: \"skip\", path: pluginPath, detail: \"connector declares no hooks\" },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n\n // 1. Write the synthesized plugin module.\n for (const file of this.synthesizePlugin(ctx)) {\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 changes.push({\n platform: this.id,\n action,\n path: file.path,\n detail: `kilo plugin module (${this.hookDetail(ctx)})`,\n });\n }\n\n // 2. Register the module path in kilo.json's `plugin` array. The backend also\n // auto-discovers from the plugin dir, but explicit registration is idempotent\n // and ensures loading even if auto-discovery is disabled.\n changes.push(this.upsertPluginInArray(configPath, pluginPath, ctx.dryRun));\n\n return changes;\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module ACTUALLY\n * wires. Only events present in EVENT_TO_KILO are mapped/wired; any declared\n * event with no Kilo mapping is reported separately as \"unsupported here\".\n */\n private hookDetail(ctx: InstallContext): string {\n const declared = ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_KILO[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_KILO[e] === undefined);\n const base = mapped.join(\",\");\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n const configPath = this.getServerConfigPath(ctx);\n const changes: ChangeRecord[] = [];\n\n // 1. Deregister the module path from kilo.json's `plugin` array.\n changes.push(this.removePluginFromArray(configPath, pluginPath, ctx.dryRun));\n\n // 2. Remove the plugin module on disk.\n if (existsSync(pluginPath)) {\n if (!ctx.dryRun) rmSync(pluginPath, { force: true });\n changes.push({\n platform: this.id,\n action: \"remove\",\n path: pluginPath,\n detail: \"kilo plugin module\",\n });\n } else {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"no kilo plugin module present\",\n });\n }\n\n // 3. Drop the now-empty plugin dir (only if WE own its full contents).\n changes.push(this.removeDirIfEmpty(this.pluginDir(ctx), ctx.dryRun));\n\n return changes;\n }\n\n /** Upsert the module path into kilo.json's top-level `plugin` array (idempotent). */\n private upsertPluginInArray(\n configPath: string,\n modulePath: string,\n dryRun: boolean,\n ): ChangeRecord {\n if (this.isPresentButUnparseable(configPath)) {\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${configPath} is not parseable; left untouched (back it up / fix it, then re-run)`,\n };\n }\n const cfg = this.readJson<Record<string, unknown>>(configPath) ?? {};\n const plugins = this.pluginArrayBucket(cfg);\n if (plugins.includes(modulePath)) {\n return {\n platform: this.id,\n action: \"skip\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] already includes module`,\n };\n }\n plugins.push(modulePath);\n this.writeJson(configPath, cfg, dryRun);\n return {\n platform: this.id,\n action: \"create\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] += module`,\n };\n }\n\n /** Remove the module path from kilo.json's `plugin` array. */\n private removePluginFromArray(\n configPath: string,\n modulePath: string,\n dryRun: boolean,\n ): ChangeRecord {\n if (this.isPresentButUnparseable(configPath)) {\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${configPath} is not parseable; left untouched (back it up / fix it, then re-run)`,\n };\n }\n const cfg = this.readJson<Record<string, unknown>>(configPath);\n const raw = cfg?.[PLUGIN_ARRAY_KEY];\n const plugins = Array.isArray(raw) ? (raw as unknown[]) : undefined;\n const idx = plugins ? plugins.indexOf(modulePath) : -1;\n if (!cfg || !plugins || idx < 0) {\n return {\n platform: this.id,\n action: \"skip\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] does not include module`,\n };\n }\n plugins.splice(idx, 1);\n this.writeJson(configPath, cfg, dryRun);\n return {\n platform: this.id,\n action: \"remove\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] -= module`,\n };\n }\n\n /** Get-or-create the top-level `plugin` array as a mutable string array. */\n private pluginArrayBucket(cfg: Record<string, unknown>): string[] {\n const existing = cfg[PLUGIN_ARRAY_KEY];\n const plugins = Array.isArray(existing)\n ? existing.filter((p): p is string => typeof p === \"string\")\n : [];\n cfg[PLUGIN_ARRAY_KEY] = plugins;\n return plugins;\n }\n\n // ── ts-plugin synthesis ────────────────────────────────────────────────\n\n /**\n * Build ONE self-contained ESM plugin module for Kilo Code (the VS Code\n * extension). Structurally identical to the kilo-cli plugin but bridges to\n * \"kilo\" (not \"kilo-cli\") so the dispatcher routes to the correct adapter.\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 const events = ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_KILO[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 Kilo Code (VS Code extension) plugin bridge 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 \"allow\".\n *\n * Default export is the @kilocode/plugin PluginModule shape\n * ({ id, server: async (input) => Hooks }); the extension loads it via the\n * plugin dir auto-discovery and/or the \"plugin\" array in kilo.json.\n */\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 (PreToolUse|PostToolUse|SessionStart)\n * @param {object} payload Kilo-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\", \"kilo\", 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 a tool call on a bridge error.\n return null;\n }\n}\n`;\n\n const handlers: string[] = [];\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → block (throw) / rewrite args (mutate output.args).\n \"tool.execute.before\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (!res) return;\n // Kilo has no \"ask\" gate — degrade \"ask\" to a block (safe direction).\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${ctx.connector.id}\");\n }\n if (res.updatedInput && output && output.args) {\n Object.assign(output.args, res.updatedInput);\n }\n },`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → observe / rewrite tool output (mutate output.output).\n \"tool.execute.after\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PostToolUse\", payload);\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) {\n output.output = res.updatedOutput;\n }\n },`);\n }\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart surrogate → inject context into the system prompt.\n // The extension has no real SessionStart hook; the system-prompt transform is\n // the verified injection point (mirrors OpenCode and kilo-cli).\n \"experimental.chat.system.transform\": async (input, output) => {\n const payload = {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"SessionStart\", payload);\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n // Insert at index 1 (after the header) to preserve the prompt-cache fold\n // (header must remain system[0]).\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n const definition = `\nconst plugin = {\n id: CONNECTOR_ID,\n // @kilocode/plugin PluginModule: server(input) returns the Hooks object keyed\n // by the fork's event names. ctx.directory is the project root; fall back to cwd.\n server: async (input) => {\n const PROJECT_DIR =\n (input && (input.directory || (input.worktree && input.worktree.path))) ||\n process.cwd();\n\n return {\n${handlers.join(\"\\n\")}\n };\n },\n};\n\nexport default plugin;\n`;\n\n return header + definition;\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?, sessionId, projectDir }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as KiloBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\" ? { projectDir: input.projectDir } : {}),\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\" ? { toolOutput: input.toolOutput } : {}),\n ...(typeof input.isError === \"boolean\" ? { isError: input.isError } : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: \"startup\" };\n return ev;\n }\n default:\n return { ...base, source: \"startup\" } satisfies SessionStartEvent;\n }\n }\n\n // ── Runtime: normalized response → reply the generated bridge parses ───\n\n /**\n * OUR generated bridge consumes this stdout directly. The reply body IS the\n * normalized HookResponse itself — the bridge JSON.parses it and reads\n * decision / updatedInput / updatedOutput / additionalContext.\n */\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n return {\n exitCode: 0,\n stdout: JSON.stringify(response ?? { decision: \"allow\" }),\n };\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 BaseAdapter.writeContentFile and reversible via removeContentFile.\n // Honors platforms[\"kilo\"] per-surface false to skip.\n //\n // NOTE on dirs: the CURRENT kilo backend (7.x, shared with kilo-cli) reads\n // commands, subagents, and skills from the .kilo/ tree (project) + the XDG\n // backend config dir ~/.config/kilo (user) — NOT the .kilocode/ VS Code\n // extension legacy tree (which only carries legacy workflows). Verified against\n // kilo.ai/docs/customize/{custom-subagents,workflows,skills} (2026-06-16):\n // commands → <projectDir>/.kilo/commands | ~/.config/kilo/commands\n // subagents → <projectDir>/.kilo/agents | ~/.config/kilo/agents\n // skills → <projectDir>/.kilo/skills | ~/.kilo/skills (skills keep the\n // ~/.kilo user root per the docs — surface-specific).\n\n /** Skills root: project → <projectDir>/.kilo/skills; user → ~/.kilo/skills. */\n private skillsRootDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", \"skills\")\n : join(homedir(), \".kilo\", \"skills\");\n }\n\n /** Commands root: project → <projectDir>/.kilo/commands; user → ~/.config/kilo/commands. */\n private commandsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", \"commands\")\n : join(kiloConfigDir(), \"commands\");\n }\n\n /** Subagents root: project → <projectDir>/.kilo/agents; user → ~/.config/kilo/agents. */\n private agentsDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", \"agents\")\n : join(kiloConfigDir(), \"agents\");\n }\n\n /** Native command file path: <commandsDir>/<name>.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.commandsDir(ctx), `${name}.md`);\n }\n\n /** Native skill dir: <skillsRootDir>/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsRootDir(ctx), name);\n }\n\n /** Native subagent file path: <agentsDir>/<name>.md. */\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.agentsDir(ctx), `${name}.md`);\n }\n\n // ── Commands ──────────────────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for kilo\" }];\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(ctx, cmd.name),\n this.renderCommand(cmd),\n ctx.dryRun,\n ),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\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(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n /** Render a command to md+frontmatter (description, argument-hint, mode, model). */\n private renderCommand(cmd: CommandDef): string {\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 (cmd.model !== undefined) frontmatter.model = cmd.model;\n if (cmd.extra) Object.assign(frontmatter, cmd.extra);\n return this.renderFrontmatterMd(frontmatter, cmd.prompt);\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\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 kilo\" }];\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 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 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;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n /**\n * Render a skill's SKILL.md: frontmatter (name, description + optional model,\n * allowed-tools, disable-model-invocation) + markdown body.\n */\n private renderSkill(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 this.renderFrontmatterMd(frontmatter, skill.body);\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for kilo\" }];\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(\n this.subagentPath(ctx, agent.name),\n this.renderSubagent(agent),\n ctx.dryRun,\n ),\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 md+frontmatter. Kilo Code's shape is\n * (description, mode:\"subagent\", model, permission) with the system prompt as\n * the body. `name` is NOT a frontmatter field — it comes from the filename.\n * `permission` is derived from the coarse `readonly` knob: a readonly agent\n * gets a per-tool deny map (edit/bash) so it cannot mutate the workspace.\n */\n private renderSubagent(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 frontmatter.permission = { edit: \"deny\", bash: \"deny\" };\n }\n if (agent.extra) Object.assign(frontmatter, agent.extra);\n return this.renderFrontmatterMd(frontmatter, agent.prompt);\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const pluginPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const hasHooks = ctx.connector.hookEvents.length > 0;\n\n const checks: HealthCheck[] = [\n {\n name: `${this.name}: kilo.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\n },\n {\n // The backend merges kilo.json AND kilo.jsonc at user/project/.kilo/ levels.\n name: `${this.name}: MCP delegated to kilo backend`,\n check: () => ({\n status: \"OK\",\n detail:\n ctx.scope === \"user\"\n ? `using ${CONFIG_FILE} under ${kiloConfigDir()} (merged with kilo.jsonc by shared backend)`\n : `project scope uses .kilo/${CONFIG_FILE} (merged with kilo.jsonc by shared backend)`,\n }),\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\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> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\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 ${mcpPath}`,\n };\n },\n },\n {\n name: `${this.name}: plugin module present`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n return existsSync(pluginPath)\n ? { status: \"OK\", detail: pluginPath }\n : { status: \"FAIL\", detail: `not found: ${pluginPath}` };\n },\n },\n {\n name: `${this.name}: plugin registered in ${PLUGIN_ARRAY_KEY}[]`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n const cfg = this.readJson<Record<string, unknown>>(mcpPath);\n const raw = cfg?.[PLUGIN_ARRAY_KEY];\n const plugins = Array.isArray(raw) ? (raw as unknown[]) : undefined;\n return plugins && plugins.includes(pluginPath)\n ? { status: \"OK\", detail: `${PLUGIN_ARRAY_KEY}[] includes module` }\n : {\n status: \"FAIL\",\n detail: `module not in ${PLUGIN_ARRAY_KEY}[] of ${mcpPath}`,\n };\n },\n },\n ];\n\n // Content-surface checks.\n for (const cmd of ctx.connector.commands) {\n const p = this.commandPath(ctx, 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 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 /** 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\nexport const adapter = new KiloAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/kilo-cli/index.ts"],"sourcesContent":["/**\n * adapters/kilo-cli — Kilo CLI platform adapter for agent-connector.\n *\n * The Kilo CLI (the `kilo` binary) is a **live-confirmed OpenCode fork**: a\n * SQLite-backed command-line agent (storage `~/.local/share/kilo/kilo.db`) that\n * loads `@kilocode/plugin` modules. It is DISTINCT from the Kilo Code VS Code\n * extension (adapter id \"kilo\", a Roo/Cline fork) — the two products carry\n * different platformIds so their config and usage never merge.\n *\n * Paradigm — **ts-plugin** (mirrors the OpenCode adapter):\n * The fork has no JSON hook table. Instead it loads JS/TS plugin modules whose\n * default export is a `@kilocode/plugin` PluginModule:\n * { id?, server: async (input) => Hooks }\n * where the returned `Hooks` object is keyed by the fork's event names\n * (\"tool.execute.before\", \"tool.execute.after\", a session/system event). The\n * `server` factory runs in-process inside Kilo and is handed mutable args/output\n * objects; it throws to block a tool call.\n *\n * Why we BRIDGE instead of importing handlers (identical rationale to OpenCode):\n * the connector's hook handlers are arbitrary developer code we must not import\n * into Kilo's runtime (wrong cwd, wrong deps, version skew). So instead of\n * importing handlers we synthesize a tiny, fully self-contained ESM plugin\n * module that imports NOTHING from agent-connector and, on each hook firing,\n * shells out to the ONE stable home binary's universal entrypoint\n * <homeBin> hook kilo-cli <event> --connector <id>\n * feeding the event payload on stdin and JSON.parsing the normalized\n * HookResponse back from stdout. Fail-open: any bridge error → no-op.\n *\n * Registration (hooks — array + auto-discovery both work):\n * Since kilo v7.3.16 the fork auto-discovers every file in its plugin dir\n * (.kilo/plugin/*.js, ~/.config/kilo/plugin/*.js), so writing the file is\n * sufficient for discovery. We ALSO register the path in kilo.jsonc's `plugin`\n * array because both loading mechanisms coexist and the array write is harmless\n * (idempotent); older versions relied on it exclusively.\n *\n * Plugin module location (project | user):\n * user → ~/.config/kilo/plugin/<id>.js\n * project → <projectDir>/.kilo/plugin/<id>.js\n *\n * MCP config (the CLI's new-gen dialect — already correct, KEPT verbatim):\n * - user scope → ~/.config/kilo/kilo.jsonc\n * - project scope → <projectDir>/.kilo/kilo.jsonc (project overrides global)\n * Both are JSON/JSONC; we write plain JSON, which is valid JSONC. The root key\n * is \"mcp\" (NOT the extension's \"mcpServers\").\n *\n * Server entry shape (mirrors OpenCode's new-gen dialect):\n * - stdio → { type: \"local\", command: [exe, ...args], environment: {...} }\n * NOTE the command is a single ARRAY (exe + args together), unlike\n * Claude/Cursor's scalar `command` + `args[]` split.\n * - remote → { type: \"remote\", url }\n *\n * The Kilo CLI documents no native `${env:VAR}` interpolation token, so env/url\n * refs are resolved to literals at install time (the no-native-token path).\n *\n * Content surfaces (live-confirmed, kilo v7.3.16):\n * - commands → .kilo/command/<name>.md (user ~/.config/kilo/command/)\n * - skills → .kilo/skills/<name>/SKILL.md (user ~/.config/kilo/skills/ or ~/.agents/skills)\n * - subagents → .kilo/agent/<name>.md with frontmatter mode:subagent\n *\n * Capability degradations (documented, never thrown):\n * - The fork has no \"ask\" gate. A decision of \"ask\" degrades to a block (throw\n * with the reason) in tool.execute.before — the safe direction.\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 { renderCommandMd, renderSkillMd } from \"../claude-code/render.js\";\nimport type {\n Adapter,\n GeneratedPluginFile,\n HookReply,\n InstallContext,\n MemoryTarget,\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 Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"kilo-cli\";\n/** New-generation root key for MCP servers — \"mcp\", not the extension's \"mcpServers\". */\nconst MCP_ROOT_KEY = \"mcp\";\n/** kilo.jsonc array of plugin module paths the fork loads (NOT auto-discovery). */\nconst PLUGIN_ARRAY_KEY = \"plugin\";\n/** New-generation config filename (JSON/JSONC). */\nconst CONFIG_FILE = \"kilo.jsonc\";\n/** The Kilo CLI's SQLite session store — a CLI-exclusive detection marker. */\nconst CLI_DB_RELPATH = [\".local\", \"share\", \"kilo\", \"kilo.db\"] as const;\n\n/**\n * Canonical → Kilo (OpenCode-fork) event name map. A connector hook event is\n * only emitted by the generated plugin when it appears here AND is declared by\n * the connector.\n *\n * The fork inherits OpenCode's tool-execution events; like OpenCode it has no\n * real SessionStart hook, so SessionStart maps to the same system-prompt\n * transform surrogate (the verified context-injection point) — we inject\n * additionalContext into the system prompt there.\n */\nconst EVENT_TO_KILO: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"tool.execute.before\",\n PostToolUse: \"tool.execute.after\",\n SessionStart: \"experimental.chat.system.transform\",\n};\n\n/** Raw payload the generated plugin posts to the universal hook entrypoint. */\ninterface KiloBridgePayload {\n toolName?: string;\n toolInput?: Record<string, unknown>;\n toolOutput?: string;\n isError?: boolean;\n sessionId?: string;\n projectDir?: string;\n}\n\n/**\n * Native MCP server entry shapes the Kilo CLI's new-gen config accepts under\n * `mcp`. QUIRK: a local (stdio) server keys its whole invocation as\n * `command: [...]` — a single array of [executable, ...args] — and env as\n * `environment`.\n */\ninterface KiloLocalServer {\n type: \"local\";\n command: string[];\n environment?: Record<string, string>;\n}\ninterface KiloRemoteServer {\n type: \"remote\";\n url: string;\n}\n\nexport class KiloCliAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Kilo CLI\";\n readonly paradigm: HookParadigm = \"ts-plugin\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block (project <projectDir>/AGENTS.md\n // via the base default; user scope → ~/.kilocode/rules/agent-connector.md below).\n supportsMemory: true,\n // Matches the OpenCode capability surface — the fork inherits its plugin\n // event model.\n preToolUse: true,\n postToolUse: true,\n // The fork's compaction hook is experimental and not wired here.\n preCompact: false,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // Newer events: like OpenCode, the fork ships a decision-capable\n // `permission.ask` plugin hook upstream, but it is NOT wired here (E1\n // keeps this adapter degrade-only); subagents run as child sessions (bus\n // events only) and tool failure is merged into tool.execute.after /\n // session.error. permissionRequest / postToolUseFailure / subagentStart /\n // subagentStop stay unset — the generated bridge never references them and\n // install reports them as \"unsupported here\".\n // tool.execute.before mutates output.args → input rewrite supported.\n canModifyArgs: true,\n // tool.execute.after mutates output.output → output rewrite supported.\n canModifyOutput: true,\n // injected via the system-prompt transform at session start.\n canInjectSessionContext: true,\n // The Kilo CLI registers stdio (local), SSE, and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n // Content surfaces: live-confirmed on kilo v7.3.16 (see header).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".config\", \"kilo\");\n const userConfig = join(userDir, CONFIG_FILE);\n const projectConfig = join(projectDir, \".kilo\", CONFIG_FILE);\n // The SQLite session DB is a CLI-exclusive marker (the VS Code extension\n // never writes it), so it disambiguates the CLI from the \"kilo\" extension\n // even when neither writes a kilo.jsonc yet.\n const cliDb = join(homedir(), ...CLI_DB_RELPATH);\n const userInstalled = existsSync(userDir) || existsSync(cliDb);\n const projInstalled = existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n // Report the scope/path/reason for the marker that actually matched, so a\n // project-only install isn't misreported as a (non-existent) user install.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectConfig : userConfig;\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 ? scope === \"project\"\n ? `found project Kilo CLI config at ${projectConfig}`\n : existsSync(cliDb)\n ? `found Kilo CLI session store at ${cliDb}`\n : `found Kilo CLI config under ${userDir}`\n : `no Kilo CLI config at ${userDir} or session store at ${cliDb}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Memory surface: global rules dir at user scope ──────────────────────\n // Project scope stays on the AGENTS.md base default. User scope targets a\n // dedicated agent-connector.md in the legacy-compatible ~/.kilocode/rules/\n // dir (always loaded; avoids JSONC `instructions` edits in kilo.jsonc; the\n // AC-created file is cleanly deletable on uninstall). Shared backend with\n // the kilo extension — the convergent write dedupes via the content hash.\n protected override memoryTargets(ctx: InstallContext): MemoryTarget[] {\n if (this.memoryOverride(ctx)?.path || ctx.scope !== \"user\") {\n return super.memoryTargets(ctx);\n }\n return [\n {\n path: join(homedir(), \".kilocode\", \"rules\", \"agent-connector.md\"),\n reason: \"kilo global rules dir (~/.kilocode/rules; agent-connector-owned file)\",\n },\n ];\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\")\n : join(homedir(), \".config\", \"kilo\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), CONFIG_FILE);\n }\n\n /**\n * For ts-plugin hosts the \"hook config path\" is the generated plugin FILE.\n * Unlike OpenCode, writing the file is NOT sufficient: the fork loads only the\n * module paths listed in kilo.jsonc's `plugin` array, so installHooks also\n * registers this path there.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.pluginDir(ctx), this.pluginFileName(ctx));\n }\n\n /** Plugin directory the synthesized module is written into, per scope. */\n private pluginDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".kilo\", \"plugin\")\n : join(homedir(), \".config\", \"kilo\", \"plugin\");\n }\n\n /** Plugin module file name (one per connector, kebab-case id). */\n private pluginFileName(ctx: InstallContext): string {\n return `${ctx.connector.id}.js`;\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 kilo-cli\"\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 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 the Kilo CLI's new-gen `mcp` entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): KiloLocalServer | KiloRemoteServer {\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 // QUIRK: the Kilo CLI's new-gen local server keys its whole invocation as\n // a single `command` ARRAY (executable + args together), like OpenCode.\n // The CLI has no documented native interpolation token, so resolve every\n // ${env:VAR} to a literal at install time.\n const entry: KiloLocalServer = {\n type: \"local\",\n command: resolveEnvRefsDeep([command, ...args]),\n };\n const env = this.renderEnv(server.env);\n if (env) entry.environment = env;\n return entry;\n }\n\n // sse / http (and any other remote transport) — the Kilo CLI registers a URL.\n const entry: KiloRemoteServer = {\n type: \"remote\",\n url: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n return entry;\n }\n\n /**\n * Render env values. The Kilo CLI documents no native interpolation token, so\n * resolve `${env:VAR}` references to literals at install time.\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 return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hook install / uninstall (ts-plugin + explicit `plugin` array) ────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n const configPath = this.getServerConfigPath(ctx);\n\n if (ctx.connector.platforms[HOST]?.hooks === false) {\n return [\n { platform: this.id, action: \"skip\", path: pluginPath, detail: \"hooks disabled for kilo-cli\" },\n ];\n }\n if (ctx.connector.hookEvents.length === 0) {\n return [\n { platform: this.id, action: \"skip\", path: pluginPath, detail: \"connector declares no hooks\" },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n\n // 1. Write the synthesized plugin module.\n for (const file of this.synthesizePlugin(ctx)) {\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 changes.push({\n platform: this.id,\n action,\n path: file.path,\n detail: `kilo plugin module (${this.hookDetail(ctx)})`,\n });\n }\n\n // 2. Register the module path in kilo.jsonc's `plugin` array (the fork does\n // NOT auto-discover by directory — it reads this array).\n changes.push(this.upsertPluginInArray(configPath, pluginPath, ctx.dryRun));\n\n return changes;\n }\n\n /**\n * Human-facing summary of which declared events the synthesized module ACTUALLY\n * wires. Only events present in EVENT_TO_KILO are mapped/wired; any declared\n * event with no Kilo mapping is reported separately as \"unsupported here\" so\n * the detail never overstates coverage.\n */\n private hookDetail(ctx: InstallContext): string {\n const declared = ctx.connector.hookEvents;\n const mapped = declared.filter((e) => EVENT_TO_KILO[e] !== undefined);\n const unsupported = declared.filter((e) => EVENT_TO_KILO[e] === undefined);\n const base = mapped.join(\",\");\n return unsupported.length > 0\n ? `${base}; unsupported here: ${unsupported.join(\",\")}`\n : base;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const pluginPath = this.getHookConfigPath(ctx);\n const configPath = this.getServerConfigPath(ctx);\n const changes: ChangeRecord[] = [];\n\n // 1. Deregister the module path from kilo.jsonc's `plugin` array.\n changes.push(this.removePluginFromArray(configPath, pluginPath, ctx.dryRun));\n\n // 2. Remove the plugin module on disk.\n if (existsSync(pluginPath)) {\n if (!ctx.dryRun) rmSync(pluginPath, { force: true });\n changes.push({\n platform: this.id,\n action: \"remove\",\n path: pluginPath,\n detail: \"kilo plugin module\",\n });\n } else {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: pluginPath,\n detail: \"no kilo plugin module present\",\n });\n }\n\n // 3. Drop the now-empty plugin dir (only if WE own its full contents).\n changes.push(this.removeDirIfEmpty(this.pluginDir(ctx), ctx.dryRun));\n\n return changes;\n }\n\n /** Upsert the module path into kilo.jsonc's top-level `plugin` array (idempotent). */\n private upsertPluginInArray(\n configPath: string,\n modulePath: string,\n dryRun: boolean,\n ): ChangeRecord {\n // OVERWRITE GUARD: never blank a present-but-unparseable kilo.jsonc.\n if (this.isPresentButUnparseable(configPath)) {\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${configPath} is not parseable; left untouched (back it up / fix it, then re-run)`,\n };\n }\n const cfg = this.readJson<Record<string, unknown>>(configPath) ?? {};\n const plugins = this.pluginArrayBucket(cfg);\n if (plugins.includes(modulePath)) {\n return {\n platform: this.id,\n action: \"skip\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] already includes module`,\n };\n }\n plugins.push(modulePath);\n this.writeJson(configPath, cfg, dryRun);\n return {\n platform: this.id,\n action: \"create\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] += module`,\n };\n }\n\n /** Remove the module path from kilo.jsonc's `plugin` array. */\n private removePluginFromArray(\n configPath: string,\n modulePath: string,\n dryRun: boolean,\n ): ChangeRecord {\n // OVERWRITE GUARD: a present-but-unparseable file would round-trip to `{}`.\n if (this.isPresentButUnparseable(configPath)) {\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${configPath} is not parseable; left untouched (back it up / fix it, then re-run)`,\n };\n }\n const cfg = this.readJson<Record<string, unknown>>(configPath);\n const raw = cfg?.[PLUGIN_ARRAY_KEY];\n const plugins = Array.isArray(raw) ? (raw as unknown[]) : undefined;\n const idx = plugins ? plugins.indexOf(modulePath) : -1;\n if (!cfg || !plugins || idx < 0) {\n return {\n platform: this.id,\n action: \"skip\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] does not include module`,\n };\n }\n plugins.splice(idx, 1);\n this.writeJson(configPath, cfg, dryRun);\n return {\n platform: this.id,\n action: \"remove\",\n path: configPath,\n detail: `${PLUGIN_ARRAY_KEY}[] -= module`,\n };\n }\n\n /** Get-or-create the top-level `plugin` array as a mutable string array. */\n private pluginArrayBucket(cfg: Record<string, unknown>): string[] {\n const existing = cfg[PLUGIN_ARRAY_KEY];\n // Normalize to a fresh string[] (drop any non-string a user may have placed\n // here) and write it back so the caller mutates the live array.\n const plugins = Array.isArray(existing)\n ? existing.filter((p): p is string => typeof p === \"string\")\n : [];\n cfg[PLUGIN_ARRAY_KEY] = plugins;\n return plugins;\n }\n\n // ── Content surfaces: commands / skills / subagents ─────────────────────\n // CONTENT-ONLY: pure native-file writers under the kilo config dir.\n // No runtime dispatch, no home-bin pointer, no telemetry wrap. Each method\n // is idempotent (byte-identical → skip) via BaseAdapter.writeContentFile and\n // reversible via removeContentFile. Honors platforms[\"kilo-cli\"] per-surface\n // false opt-outs.\n //\n // Dirs (live-confirmed kilo v7.3.16 — kilo-pi-ground-truth.md):\n // commands → <kiloDir>/command/<name>.md\n // skills → <kiloDir>/skills/<name>/SKILL.md\n // subagents → <kiloDir>/agent/<name>.md (frontmatter mode:subagent)\n //\n // <kiloDir>:\n // project scope → <projectDir>/.kilo\n // user scope → ~/.config/kilo\n\n private commandsDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"command\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"skills\");\n }\n private agentDir(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"agent\");\n }\n\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.commandsDir(ctx), `${name}.md`);\n }\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\n }\n private subagentPath(ctx: InstallContext, name: string): string {\n return join(this.agentDir(ctx), `${name}.md`);\n }\n\n // ── Commands ───────────────────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for kilo-cli\" }];\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(this.commandPath(ctx, cmd.name), renderCommandMd(cmd), ctx.dryRun),\n );\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\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(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n // ── Skills ─────────────────────────────────────────────────────────────────\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 kilo-cli\" }];\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\"), renderSkillMd(skill), ctx.dryRun),\n );\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 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;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\n }\n\n // ── Subagents ──────────────────────────────────────────────────────────────\n\n override installSubagents(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.subagents === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"subagents disabled for kilo-cli\" }];\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(\n this.subagentPath(ctx, agent.name),\n this.renderKiloSubagent(agent),\n ctx.dryRun,\n ),\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 md+frontmatter for kilo-cli.\n * Kilo's shape is (description, mode:\"subagent\", model, permission) with the\n * system prompt as the body — mirrors the opencode adapter's renderSubagent.\n * `name` is NOT a frontmatter field — it comes from the filename.\n * `permission` is derived from the coarse `readonly` knob.\n */\n private renderKiloSubagent(agent: import(\"../../core/types.js\").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 frontmatter.permission = { edit: \"deny\", bash: \"deny\" };\n }\n if (agent.extra) Object.assign(frontmatter, agent.extra);\n // renderFrontmatterMd is inherited from BaseAdapter (delegates to render.ts).\n return this.renderFrontmatterMd(frontmatter, agent.prompt);\n }\n\n // ── ts-plugin synthesis ────────────────────────────────────────────────\n\n /**\n * Build ONE self-contained ESM plugin module for the Kilo CLI fork.\n *\n * The module imports nothing from agent-connector. It embeds two constants\n * (the absolute home-bin path and the connector id) and a `bridge()` helper\n * that shells out to the universal hook entrypoint via execFileSync, feeding\n * the Kilo payload on stdin and JSON.parsing the normalized HookResponse back\n * from stdout (fail-open: any error → null). Its default export is the\n * `@kilocode/plugin` PluginModule shape — { id, server: async (input) =>\n * ({ \"tool.execute.before\": …, \"tool.execute.after\": …, … }) } — keyed only by\n * the fork event names for the events this connector actually declares.\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 // The Kilo event keys this connector declares (and that we can map).\n const events = ctx.connector.hookEvents.filter(\n (e): e is HookEventName => EVENT_TO_KILO[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 Kilo CLI plugin bridge 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 \"allow\".\n *\n * Default export is the @kilocode/plugin PluginModule shape\n * ({ id, server: async (input) => Hooks }); the fork loads it because its path\n * is registered in kilo.jsonc's \"plugin\" array.\n */\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 (PreToolUse|PostToolUse|SessionStart)\n * @param {object} payload Kilo-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\", \"kilo-cli\", 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 a tool call on a bridge error.\n return null;\n }\n}\n`;\n\n const handlers: string[] = [];\n\n if (has(\"PreToolUse\")) {\n handlers.push(` // PreToolUse → block (throw) / rewrite args (mutate output.args).\n \"tool.execute.before\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: (output && output.args) ?? {},\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PreToolUse\", payload);\n if (!res) return;\n // Kilo has no \"ask\" gate — degrade \"ask\" to a block (safe direction).\n if (res.decision === \"deny\" || res.decision === \"ask\") {\n throw new Error(res.reason || \"Blocked by ${ctx.connector.id}\");\n }\n if (res.updatedInput && output && output.args) {\n Object.assign(output.args, res.updatedInput);\n }\n },`);\n }\n\n if (has(\"PostToolUse\")) {\n handlers.push(` // PostToolUse → observe / rewrite tool output (mutate output.output).\n \"tool.execute.after\": async (input, output) => {\n const payload = {\n toolName: input.tool ?? \"\",\n toolInput: input.args ?? {},\n toolOutput: output ? output.output : undefined,\n sessionId: input.sessionID ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"PostToolUse\", payload);\n if (!res) return;\n if (typeof res.updatedOutput === \"string\" && output) {\n output.output = res.updatedOutput;\n }\n },`);\n }\n\n if (has(\"SessionStart\")) {\n handlers.push(` // SessionStart surrogate → inject context into the system prompt.\n // The fork has no real SessionStart hook; the system-prompt transform is the\n // verified injection point (mirrors OpenCode).\n \"experimental.chat.system.transform\": async (input, output) => {\n const payload = {\n sessionId: (input && input.sessionID) ?? \"\",\n projectDir: PROJECT_DIR,\n };\n const res = bridge(\"SessionStart\", payload);\n if (!res) return;\n if (res.additionalContext && output && Array.isArray(output.system)) {\n // Insert at index 1 (after the header) to preserve the prompt-cache fold\n // (header must remain system[0]).\n output.system.splice(1, 0, res.additionalContext);\n }\n },`);\n }\n\n const definition = `\nconst plugin = {\n id: CONNECTOR_ID,\n // @kilocode/plugin PluginModule: server(input) returns the Hooks object keyed\n // by the fork's event names. ctx.directory is the project root; fall back to cwd.\n server: async (input) => {\n const PROJECT_DIR =\n (input && (input.directory || (input.worktree && input.worktree.path))) ||\n process.cwd();\n\n return {\n${handlers.join(\"\\n\")}\n };\n },\n};\n\nexport default plugin;\n`;\n\n return header + definition;\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?, sessionId, projectDir }\n * so this maps straight through.\n */\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as KiloBridgePayload;\n const base = {\n hostPlatform: HOST,\n connectorId: \"\",\n sessionId: typeof input.sessionId === \"string\" ? input.sessionId : \"\",\n raw,\n ...(typeof input.projectDir === \"string\" ? { projectDir: input.projectDir } : {}),\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\" ? { toolOutput: input.toolOutput } : {}),\n ...(typeof input.isError === \"boolean\" ? { isError: input.isError } : {}),\n };\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 Kilo; 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 reads\n * decision / updatedInput / updatedOutput / additionalContext.\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 configPath = this.getServerConfigPath(ctx);\n const pluginPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const hasHooks = ctx.connector.hookEvents.length > 0;\n\n return [\n {\n name: `${this.name}: ${CONFIG_FILE} present`,\n check: () =>\n existsSync(configPath)\n ? { status: \"OK\", detail: configPath }\n : { status: \"FAIL\", detail: `not found: ${configPath}` },\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\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> }>(configPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${configPath}` };\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 ${configPath}`,\n };\n },\n },\n {\n name: `${this.name}: plugin module present`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n return existsSync(pluginPath)\n ? { status: \"OK\", detail: pluginPath }\n : { status: \"FAIL\", detail: `not found: ${pluginPath}` };\n },\n },\n {\n name: `${this.name}: plugin registered in ${PLUGIN_ARRAY_KEY}[]`,\n check: () => {\n if (!hasHooks) return { status: \"OK\", detail: \"no hooks declared\" };\n const cfg = this.readJson<Record<string, unknown>>(configPath);\n const raw = cfg?.[PLUGIN_ARRAY_KEY];\n const plugins = Array.isArray(raw) ? (raw as unknown[]) : undefined;\n return plugins && plugins.includes(pluginPath)\n ? { status: \"OK\", detail: `${PLUGIN_ARRAY_KEY}[] includes module` }\n : {\n status: \"FAIL\",\n detail: `module not in ${PLUGIN_ARRAY_KEY}[] of ${configPath} (fork will not load it)`,\n };\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\nexport const adapter = new KiloCliAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|