@ken-jo/agent-connector 0.4.79 → 0.4.91
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 +3 -3
- package/dist/{action-OHGFVKMC.js → action-L44DXFHT.js} +9 -9
- package/dist/antigravity-cli-JO6GUTV7.js +436 -0
- package/dist/antigravity-cli-JO6GUTV7.js.map +1 -0
- package/dist/{chunk-X457NOFE.js → chunk-25CPWJA7.js} +91 -11
- package/dist/chunk-25CPWJA7.js.map +1 -0
- package/dist/{chunk-VKRGQLY4.js → chunk-7HUUINPB.js} +18 -18
- package/dist/{chunk-LKAVD4HP.js → chunk-BLTVZACS.js} +8 -8
- package/dist/{chunk-PZHB5TVA.js → chunk-G4CEELKO.js} +2 -2
- package/dist/{chunk-VD4EG6SG.js → chunk-KIRCPLM4.js} +5 -5
- package/dist/{chunk-ZXX5DVSE.js → chunk-LAIITCMW.js} +6 -6
- package/dist/{chunk-UYZ53KWS.js → chunk-LF76VPGQ.js} +5 -5
- package/dist/{chunk-IRUYJD23.js → chunk-NLE2J5P4.js} +1 -1
- package/dist/{chunk-7NXEHZAK.js → chunk-NWLRJNXM.js} +2 -2
- package/dist/{chunk-YJP3KGLM.js → chunk-QARPXSIV.js} +4 -4
- package/dist/{chunk-AMK2K6XZ.js → chunk-R6LML2YS.js} +2 -2
- package/dist/{chunk-S4E6QQEM.js → chunk-ZMLVR4J7.js} +7 -2
- package/dist/chunk-ZMLVR4J7.js.map +1 -0
- package/dist/{claude-code-T6ZRCMA7.js → claude-code-WS4NAGZT.js} +4 -4
- package/dist/cli/sdk.js +4 -4
- package/dist/cli.js +1 -1
- package/dist/codebuddy-RBEZGXBG.js +643 -0
- package/dist/codebuddy-RBEZGXBG.js.map +1 -0
- package/dist/{codex-RHKQKNNG.js → codex-ZZ434GYR.js} +4 -4
- package/dist/{detect-ALAKE54S.js → detect-3S46RUMK.js} +4 -4
- package/dist/devin-PRJY2TTD.js +510 -0
- package/dist/devin-PRJY2TTD.js.map +1 -0
- package/dist/{doctor-UNF7FCF4.js → doctor-3CUBPQKU.js} +14 -14
- package/dist/grok-cli-5QD235UB.js +482 -0
- package/dist/grok-cli-5QD235UB.js.map +1 -0
- package/dist/{hook-GM2IDA3C.js → hook-P6EKDINW.js} +9 -9
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{install-7O4XWH7T.js → install-7DMK53SB.js} +10 -10
- package/dist/{introspect-5o5ick0_.d.ts → introspect-DYOIX8Ov.d.ts} +1 -1
- package/dist/{jetbrains-copilot-4IOT3I2Y.js → jetbrains-copilot-T2EPKROP.js} +9 -3
- package/dist/jetbrains-copilot-T2EPKROP.js.map +1 -0
- package/dist/junie-SQ4SDLGK.js +227 -0
- package/dist/junie-SQ4SDLGK.js.map +1 -0
- package/dist/{kilo-TAHOPT2Q.js → kilo-OU2ZLZKB.js} +4 -4
- package/dist/{kilo-cli-X4NPJWGX.js → kilo-cli-NMWGYF4F.js} +4 -4
- package/dist/{kiro-YZ4TTZGD.js → kiro-4IN5IH46.js} +77 -2
- package/dist/kiro-4IN5IH46.js.map +1 -0
- package/dist/{leaderboard-DVW4WYJ6.js → leaderboard-LF5SP6X2.js} +4 -4
- package/dist/mistral-vibe-TRQDHAWV.js +300 -0
- package/dist/mistral-vibe-TRQDHAWV.js.map +1 -0
- package/dist/open-interpreter-4PKL56AA.js +264 -0
- package/dist/open-interpreter-4PKL56AA.js.map +1 -0
- package/dist/openhands-5LNH3BKB.js +384 -0
- package/dist/openhands-5LNH3BKB.js.map +1 -0
- package/dist/{package-H5V3AZHR.js → package-2EAIYSJ4.js} +7 -7
- package/dist/{pi-I7BLL4EI.js → pi-BUADR5MJ.js} +139 -2
- package/dist/pi-BUADR5MJ.js.map +1 -0
- package/dist/{qwen-code-JG7AF442.js → qwen-code-TUJNHKNI.js} +4 -4
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +7 -7
- 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 +7 -7
- package/dist/{serve-WMO2TUW3.js → serve-K62FW3V7.js} +9 -9
- package/dist/{status-WRLBTBRE.js → status-E5MCFZM6.js} +7 -7
- package/dist/{statusline-EUD4DMIP.js → statusline-LIPF2KVP.js} +8 -8
- package/dist/{telemetry-U3LGMR3D.js → telemetry-4OC56NTM.js} +5 -5
- package/dist/{types-D6RWGXm1.d.ts → types-C4qMgbJn.d.ts} +10 -9
- package/dist/{uninstall-TWPUEJEC.js → uninstall-2YYKN5DX.js} +10 -10
- package/dist/{upgrade-EM6Y7QLH.js → upgrade-55AFPJEF.js} +10 -10
- package/dist/{usage-3HQDTXGY.js → usage-3PB3WZSL.js} +3 -3
- package/dist/{usage-event-DWIGKO7V.js → usage-event-KD5FW6W4.js} +8 -8
- package/dist/{zed-LLOAUXSA.js → zed-ZF2OQ75O.js} +119 -3
- package/dist/zed-ZF2OQ75O.js.map +1 -0
- package/package.json +1 -1
- package/dist/antigravity-cli-KODEKUTM.js +0 -87
- package/dist/antigravity-cli-KODEKUTM.js.map +0 -1
- package/dist/chunk-S4E6QQEM.js.map +0 -1
- package/dist/chunk-X457NOFE.js.map +0 -1
- package/dist/jetbrains-copilot-4IOT3I2Y.js.map +0 -1
- package/dist/kiro-YZ4TTZGD.js.map +0 -1
- package/dist/pi-I7BLL4EI.js.map +0 -1
- package/dist/zed-LLOAUXSA.js.map +0 -1
- /package/dist/{action-OHGFVKMC.js.map → action-L44DXFHT.js.map} +0 -0
- /package/dist/{chunk-VKRGQLY4.js.map → chunk-7HUUINPB.js.map} +0 -0
- /package/dist/{chunk-LKAVD4HP.js.map → chunk-BLTVZACS.js.map} +0 -0
- /package/dist/{chunk-PZHB5TVA.js.map → chunk-G4CEELKO.js.map} +0 -0
- /package/dist/{chunk-VD4EG6SG.js.map → chunk-KIRCPLM4.js.map} +0 -0
- /package/dist/{chunk-ZXX5DVSE.js.map → chunk-LAIITCMW.js.map} +0 -0
- /package/dist/{chunk-UYZ53KWS.js.map → chunk-LF76VPGQ.js.map} +0 -0
- /package/dist/{chunk-IRUYJD23.js.map → chunk-NLE2J5P4.js.map} +0 -0
- /package/dist/{chunk-7NXEHZAK.js.map → chunk-NWLRJNXM.js.map} +0 -0
- /package/dist/{chunk-YJP3KGLM.js.map → chunk-QARPXSIV.js.map} +0 -0
- /package/dist/{chunk-AMK2K6XZ.js.map → chunk-R6LML2YS.js.map} +0 -0
- /package/dist/{claude-code-T6ZRCMA7.js.map → claude-code-WS4NAGZT.js.map} +0 -0
- /package/dist/{codex-RHKQKNNG.js.map → codex-ZZ434GYR.js.map} +0 -0
- /package/dist/{detect-ALAKE54S.js.map → detect-3S46RUMK.js.map} +0 -0
- /package/dist/{doctor-UNF7FCF4.js.map → doctor-3CUBPQKU.js.map} +0 -0
- /package/dist/{hook-GM2IDA3C.js.map → hook-P6EKDINW.js.map} +0 -0
- /package/dist/{install-7O4XWH7T.js.map → install-7DMK53SB.js.map} +0 -0
- /package/dist/{kilo-TAHOPT2Q.js.map → kilo-OU2ZLZKB.js.map} +0 -0
- /package/dist/{kilo-cli-X4NPJWGX.js.map → kilo-cli-NMWGYF4F.js.map} +0 -0
- /package/dist/{leaderboard-DVW4WYJ6.js.map → leaderboard-LF5SP6X2.js.map} +0 -0
- /package/dist/{package-H5V3AZHR.js.map → package-2EAIYSJ4.js.map} +0 -0
- /package/dist/{qwen-code-JG7AF442.js.map → qwen-code-TUJNHKNI.js.map} +0 -0
- /package/dist/{serve-WMO2TUW3.js.map → serve-K62FW3V7.js.map} +0 -0
- /package/dist/{status-WRLBTBRE.js.map → status-E5MCFZM6.js.map} +0 -0
- /package/dist/{statusline-EUD4DMIP.js.map → statusline-LIPF2KVP.js.map} +0 -0
- /package/dist/{telemetry-U3LGMR3D.js.map → telemetry-4OC56NTM.js.map} +0 -0
- /package/dist/{uninstall-TWPUEJEC.js.map → uninstall-2YYKN5DX.js.map} +0 -0
- /package/dist/{upgrade-EM6Y7QLH.js.map → upgrade-55AFPJEF.js.map} +0 -0
- /package/dist/{usage-3HQDTXGY.js.map → usage-3PB3WZSL.js.map} +0 -0
- /package/dist/{usage-event-DWIGKO7V.js.map → usage-event-KD5FW6W4.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/grok-cli/index.ts"],"sourcesContent":["/**\n * adapters/grok-cli — Grok CLI (the community superagent-ai/grok-cli, npm\n * `grok-dev`, bin `grok`, MIT) platform adapter for agent-connector.\n *\n * Disambiguation: id is `grok-cli` (NOT `grok`) to keep it distinct from xAI's\n * separate \"Grok Build\" product. This adapter targets the OPEN-SOURCE community\n * CLI only — byte-confirmed against its source on 2026-06-21:\n * - package.json → name \"grok-dev\", bin { \"grok\": \"dist/index.js\" }, MIT.\n * - src/utils/settings.ts → USER settings at ~/.grok/user-settings.json\n * (USER_SETTINGS_PATH = join(homedir(), \".grok\", \"user-settings.json\")).\n *\n * Grok CLI is a **json-stdio** host. Its native surfaces are USER-SCOPE ONLY and\n * BOTH live in the SAME file (~/.grok/user-settings.json):\n *\n * 1. MCP servers — under the NESTED key `mcp.servers`, which is a JSON **ARRAY**\n * of McpServerConfig objects (NOT a top-level `mcpServers` keyed object map —\n * the README's casual \"(mcpServers)\" wording is misleading; the source reads\n * `loadUserSettings().mcp?.servers`). Each entry:\n * { id, label, enabled, transport: \"stdio\"|\"http\"|\"sse\",\n * url?, headers?, command?, args?, env?, cwd? }\n * (src/utils/settings.ts `McpServerConfig`). We key entries on `id` =\n * connector id (mirrors continue's array-by-name merge, but JSON not YAML).\n * Project `.grok/settings.json` holds ONLY { model, sandboxMode, sandbox,\n * lsp } — NO mcp, NO hooks — so this adapter is user-scope.\n *\n * 2. Hooks — under the top-level `hooks` key (Claude NESTED-rule shape:\n * { hooks: { <Event>: [ { matcher?, hooks:[{ type:\"command\", command,\n * timeout? }] } ] } }), loaded from user-settings.json ONLY (project-level\n * hooks are DELIBERATELY excluded by Grok for security — a committed repo\n * file must not execute unsandboxed host commands). So `hooks` is wired\n * through the SAME shared object-map hook-merge engine droid/claude use.\n *\n * Supported hook events (byte-confirmed src/hooks/types.ts HOOK_EVENTS): the\n * Grok set is a SUPERSET of our canonical names plus host-specific ones. We wire\n * the canonical events Grok fires (PascalCase, 1:1): PreToolUse, PostToolUse,\n * PostToolUseFailure, UserPromptSubmit, SessionStart, SessionEnd, Stop,\n * SubagentStart, SubagentStop, PreCompact, PostCompact, Notification. Grok also\n * fires StopFailure, TaskCreated, TaskCompleted, InstructionsLoaded, CwdChanged\n * (no canonical analog — they ride the nativeHooks passthrough) and has no\n * PermissionRequest event (warn/skip at install).\n *\n * Stdin wire field names DIFFER from Claude's in two false-friend spots\n * (byte-confirmed src/hooks/types.ts): UserPromptSubmit carries `user_prompt`\n * (NOT `prompt`), and PostToolUse carries `tool_output` (NOT `tool_response`).\n * PostToolUseFailure/StopFailure carry `error` (string); SubagentStart/Stop carry\n * `agent_type` + `description`; SessionStart carries `source`; PreCompact/\n * PostCompact carry `trigger`; Notification carries `message`. `session_id` is\n * optional; `cwd` is always present.\n *\n * Reply protocol (byte-confirmed src/hooks/executor.ts aggregateHookResults):\n * stdout is parsed as JSON when it starts with `{`. A hook BLOCKS via either\n * exit code 2 OR a stdout `{ \"decision\": \"block\" }`; `{ \"decision\": \"approve\" }`\n * explicitly approves; `additionalContext` is injected as context; `continue:\n * false` + `stopReason` prevents continuation. We emit exit 0 + a structured\n * stdout object (so the JSON is always parsed): deny → {decision:\"block\",reason};\n * context → {additionalContext}. Grok has no \"ask\"/\"modify\" reply path — those\n * degrade to a plain exit-0 passthrough (canModifyArgs/Output stay false).\n *\n * Env handling: Grok documents no native ${VAR} server interpolation, so env/\n * header/url refs resolve to literals at install time via resolveEnvRefsDeep\n * (the safe default matching continue/droid).\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter, type HookMergeDescriptor } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PlatformCapabilities,\n PlatformId,\n PostCompactEvent,\n PostToolUseEvent,\n PostToolUseFailureEvent,\n PreCompactEvent,\n PreToolUseEvent,\n ServerDef,\n SessionEndEvent,\n SessionStartEvent,\n StopEvent,\n SubagentStartEvent,\n SubagentStopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport { buildWrappedStdio, isHomeBinHookCommand } from \"../../core/spawn.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"grok-cli\";\n\n/**\n * Canonical events Grok fires (PascalCase, 1:1 with our names). PermissionRequest\n * is absent from Grok's HOOK_EVENTS, so it warn/skips at install. The host-only\n * events (StopFailure, TaskCreated, TaskCompleted, InstructionsLoaded, CwdChanged)\n * have no canonical analog and ride the nativeHooks passthrough.\n */\nconst SUPPORTED_EVENTS: ReadonlySet<HookEventName> = new Set<HookEventName>([\n \"PreToolUse\",\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"UserPromptSubmit\",\n \"SessionStart\",\n \"SessionEnd\",\n \"Stop\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreCompact\",\n \"PostCompact\",\n \"Notification\",\n]);\n\n/**\n * Native MCP server entry shape (src/utils/settings.ts `McpServerConfig`). The\n * array lives at `mcp.servers`. `id`/`label`/`enabled`/`transport` are required;\n * stdio carries command/args/env/cwd, remote carries url/headers.\n */\ninterface GrokMcpServer {\n id: string;\n label: string;\n enabled: boolean;\n transport: Transport;\n url?: string;\n headers?: Record<string, string>;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n cwd?: string;\n}\n\n/** The shape of user-settings.json (only the parts this adapter touches). */\ninterface GrokUserSettings {\n mcp?: { servers?: GrokMcpServer[] };\n hooks?: Record<string, GrokHookEntry[]>;\n [key: string]: unknown;\n}\n\n/** A single Grok native hook registration entry (Claude-shaped, nested). */\ninterface GrokHookEntry {\n matcher?: string;\n hooks: Array<{ type: \"command\"; command: string; timeout?: number }>;\n}\n\n/** Raw Grok CLI hook stdin payload (snake_case; field names per src/hooks/types.ts). */\ninterface GrokWireInput {\n hook_event_name?: string;\n session_id?: string;\n cwd?: string;\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n /** PostToolUse — NOTE Grok sends `tool_output` (NOT Claude's `tool_response`). */\n tool_output?: unknown;\n /** PostToolUseFailure / StopFailure — the captured error message (string). */\n error?: unknown;\n /** UserPromptSubmit — NOTE Grok sends `user_prompt` (NOT Claude's `prompt`). */\n user_prompt?: unknown;\n /** SessionStart — startup | resume | clear. */\n source?: string;\n /** PreCompact / PostCompact — auto | manual. */\n trigger?: \"auto\" | \"manual\";\n /** Notification — the user-facing message. */\n message?: unknown;\n /** SubagentStart / SubagentStop / TaskCreated / TaskCompleted. */\n agent_type?: unknown;\n description?: unknown;\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\n connector?: unknown;\n}\n\nexport class GrokCliAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Grok CLI\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: Grok reads AGENTS.md (\"merged from git root down to your\n // cwd; AGENTS.override.md wins per directory\" — README). The BaseAdapter\n // AGENTS.md-first default handles it.\n supportsMemory: true,\n preToolUse: true,\n postToolUse: true,\n postToolUseFailure: true,\n userPromptSubmit: true,\n sessionStart: true,\n sessionEnd: true,\n stop: true,\n notification: true,\n preCompact: true,\n // Grok fires PostCompact (its HOOK_EVENTS lists it beside PreCompact).\n postCompact: true,\n // Grok fires SubagentStart AND SubagentStop (both in HOOK_EVENTS).\n subagentStart: true,\n subagentStop: true,\n // No PermissionRequest event in Grok's HOOK_EVENTS → warn/skip at install.\n // Grok's reply protocol is block/approve/context only — it cannot rewrite\n // tool args or already-emitted output.\n canModifyArgs: false,\n canModifyOutput: false,\n // Grok injects `additionalContext` from a hook's stdout JSON.\n canInjectSessionContext: true,\n // Grok's settings.json hook keys are free-form event names (its HOOK_EVENTS\n // superset includes StopFailure/TaskCreated/TaskCompleted/InstructionsLoaded/\n // CwdChanged with no canonical analog), so any host event declared under\n // platforms[\"grok-cli\"].nativeHooks installs verbatim.\n supportsNativeHooks: true,\n // MCP entry supports stdio + remote (http / sse) per McpServerConfig.transport.\n transports: [\"stdio\", \"http\", \"sse\"],\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".grok\");\n const userSettings = join(userDir, \"user-settings.json\");\n const installed = existsSync(userDir) || existsSync(userSettings);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n // MCP + hooks both live in user-settings.json (user scope only).\n configPath: userSettings,\n scope: \"user\",\n reason: installed\n ? `found Grok CLI config at ${userSettings}`\n : `no Grok CLI config at ${userDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ───────────────────────────────────────────────────────────\n // BOTH MCP servers (mcp.servers array) and hooks (top-level hooks map) live in\n // the SAME user-settings.json. Project .grok/settings.json holds neither, so\n // every scope resolves to the user file.\n\n getConfigDir(_ctx: InstallContext): string {\n return join(homedir(), \".grok\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"user-settings.json\");\n }\n\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"user-settings.json\");\n }\n\n // ── MCP server install / uninstall (JSON — nested mcp.servers ARRAY) ───────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(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 path,\n detail: connector.server\n ? \"server registration disabled for grok-cli\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\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 const entry = this.renderServerEntry(ctx, server);\n\n // OVERWRITE GUARD: never round-trip a present-but-unparseable file into `{}`.\n if (this.isPresentButUnparseable(path)) {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path,\n detail: `existing ${path} is not parseable; left untouched (back it up / fix it, then re-run)`,\n },\n ];\n }\n const cfg = this.readJson<GrokUserSettings>(path) ?? {};\n\n // NEVER clobber a malformed mcp.servers: if `mcp` exists but is not an object,\n // or `mcp.servers` exists but is not an array, WARN + write nothing (leave the\n // user's hand-edited value) rather than silently replacing it.\n const existingMcp = cfg.mcp;\n if (existingMcp !== undefined && (typeof existingMcp !== \"object\" || Array.isArray(existingMcp))) {\n return [{ platform: this.id, action: \"warn\", path, detail: \"mcp is not an object — left untouched (manual fix needed)\" }];\n }\n const existingServers = existingMcp?.servers;\n if (existingServers !== undefined && !Array.isArray(existingServers)) {\n return [{ platform: this.id, action: \"warn\", path, detail: \"mcp.servers is not an array — left untouched (manual fix needed)\" }];\n }\n\n const list: GrokMcpServer[] = Array.isArray(existingServers) ? [...existingServers] : [];\n const idx = list.findIndex((e) => e?.id === connector.id);\n\n let action: ChangeRecord[\"action\"];\n if (idx < 0) {\n list.push(entry);\n action = \"create\";\n } else if (JSON.stringify(list[idx]) === JSON.stringify(entry)) {\n action = \"skip\";\n } else {\n list[idx] = entry;\n action = \"update\";\n }\n\n if (action !== \"skip\") {\n cfg.mcp = { ...(existingMcp ?? {}), servers: list };\n this.writeJson(path, cfg, dryRun);\n }\n return [{ platform: this.id, action, path, detail: `mcp.servers[id=${connector.id}]` }];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const symlink = this.symlinkPathWarning(path);\n if (symlink) return [symlink];\n\n const cfg = this.readJson<GrokUserSettings>(path);\n const rawList = cfg?.mcp?.servers;\n if (!cfg || !Array.isArray(rawList)) {\n return [{ platform: this.id, action: \"skip\", path, detail: `mcp.servers[id=${connector.id}] absent` }];\n }\n\n const list = rawList as GrokMcpServer[];\n const kept = list.filter((e) => e?.id !== connector.id);\n if (kept.length === list.length) {\n return [{ platform: this.id, action: \"skip\", path, detail: `mcp.servers[id=${connector.id}] absent` }];\n }\n\n cfg.mcp = { ...cfg.mcp, servers: kept };\n this.writeJson(path, cfg, dryRun);\n return [{ platform: this.id, action: \"remove\", path, detail: `mcp.servers[id=${connector.id}]` }];\n }\n\n /** Render a normalized ServerDef into Grok's native McpServerConfig entry. */\n private renderServerEntry(ctx: InstallContext, server: ServerDef): GrokMcpServer {\n const transport: Transport = server.transport;\n const enabled = server.enabled !== false;\n const id = ctx.connector.id;\n // `label` is a required display field; reuse the connector displayName.\n const label = ctx.connector.displayName?.trim() || id;\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 ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n const entry: GrokMcpServer = {\n id,\n label,\n enabled,\n transport: \"stdio\",\n command: resolveEnvRefsDeep(command),\n };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n if (typeof server.cwd === \"string\" && server.cwd.length > 0) {\n entry.cwd = resolveEnvRefsDeep(server.cwd);\n }\n return entry;\n }\n\n // Remote (http / sse) — Grok registers a URL (+ optional headers). `ws` has no\n // Grok analog; fall back to http (the closest remote shape Grok validates).\n const entry: GrokMcpServer = {\n id,\n label,\n enabled,\n transport: transport === \"sse\" ? \"sse\" : \"http\",\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. Grok documents no native ${VAR} server\n * interpolation, so resolve `${env:VAR}` references to literals at install\n * time (the safe path; matches continue/droid).\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 (top-level hooks, Claude nested-rule shape) ───\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST];\n\n // `hooks: false` disables only the NORMALIZED hooks; nativeHooks is a\n // sibling grok-cli-scoped declaration that installs regardless.\n const normalizedEvents = override?.hooks === false ? [] : connector.hookEvents;\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n\n if (normalizedEvents.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail:\n override?.hooks === false\n ? \"hooks disabled for grok-cli\"\n : \"connector declares no hooks\",\n },\n ];\n }\n\n const pending = normalizedEvents.map((event) => ({\n event: event as string,\n matcher: connector.hooks[event]?.matcher ?? \"\",\n }));\n const native = nativeEvents.map((event) => ({\n event,\n matcher: nativeHooks[event]?.matcher ?? \"\",\n }));\n\n return this.upsertHookEntries(\n ctx,\n this.getHookConfigPath(ctx),\n pending,\n this.hookDescriptor(ctx),\n native,\n );\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor(ctx));\n }\n\n /**\n * Grok's hook-merge descriptor (NESTED shape `{ matcher?, hooks: [...] }`).\n * Connector-generic ownership (any of our home-bin commands in the inner\n * `hooks`), matching droid:\n * - mapEvent drops events outside SUPPORTED_EVENTS (Grok has no\n * PermissionRequest); supported events map 1:1 (PascalCase identical);\n * - the native pass installs free-form host-only event keys verbatim;\n * - uninstall = inner-strip ONLY (ownsEntryForRemove never-true).\n */\n private hookDescriptor(ctx: InstallContext): HookMergeDescriptor<GrokHookEntry> {\n const stripInner = (c: InstallContext) => (entry: GrokHookEntry) => {\n const innerBefore = entry.hooks?.length ?? 0;\n const inner = (entry.hooks ?? []).filter((h) => !this.isOurCommand(h.command, c));\n return {\n next: inner.length > 0 ? { matcher: entry.matcher ?? \"\", hooks: inner } : null,\n removed: innerBefore - inner.length,\n };\n };\n return {\n mapEvent: (e) => (SUPPORTED_EVENTS.has(e as HookEventName) ? e : undefined),\n unmappedWarnDetail: (e) => `${e} has no Grok CLI hook equivalent — skipped`,\n renderEntry: (_event, matcher, command) => ({\n matcher,\n hooks: [{ type: \"command\", command }],\n }),\n entryOwnsCommand: (entry, _command) =>\n (entry.hooks ?? []).some((h) => this.isOurCommand(h.command, ctx)),\n nativeOwnsCommand: (entry, command) =>\n (entry.hooks ?? []).some((h) => h.command === command),\n ownsEntryForRemove: () => () => false,\n stripInner,\n skipDetail: (event) => `hooks.${event} already registered`,\n removeDetail: (event, removed) => `hooks.${event} (${removed})`,\n nativeSkipDetail: (event) => `hooks.${event} already registered (native)`,\n nativeMutateDetail: (event) => `hooks.${event} (native)`,\n absentDetail: \"no hooks section present\",\n noMatchDetail: \"no matching hook entries\",\n };\n }\n\n /** True when a hook command references our home binary AND this connector id. */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const path = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n return [\n {\n name: `${this.name}: user-settings.json present`,\n check: () =>\n existsSync(path)\n ? { status: \"OK\", detail: path }\n : { status: \"FAIL\", detail: `not found: ${path}` },\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<GrokUserSettings>(path);\n const list = cfg?.mcp?.servers;\n if (!cfg || !Array.isArray(list)) {\n return { status: \"FAIL\", detail: `no mcp.servers array in ${path}` };\n }\n return list.some((e) => e?.id === connectorId)\n ? { status: \"OK\", detail: `mcp.servers[id=${connectorId}] present` }\n : { status: \"FAIL\", detail: `no mcp.servers[id=${connectorId}] in ${path}` };\n },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n const cfg = this.readJson<GrokUserSettings>(path);\n const hooks = cfg?.hooks ?? {};\n const registered = Object.values(hooks).some((entries) =>\n (entries ?? []).some((e) =>\n (e.hooks ?? []).some((h) => isHomeBinHookCommand(h.command, homeBin, connectorId)),\n ),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${path}` };\n },\n },\n ];\n }\n\n // ── Runtime: parse Grok stdin JSON → normalized event ──────────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as GrokWireInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = typeof input.session_id === \"string\" ? input.session_id : \"\";\n const projectDir = typeof input.cwd === \"string\" ? input.cwd : undefined;\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n raw,\n ...(projectDir !== undefined ? { projectDir } : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: typeof input.tool_name === \"string\" ? input.tool_name : \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n // Grok sends `tool_output` (NOT Claude's `tool_response`).\n const ev: PostToolUseEvent = {\n ...base,\n toolName: typeof input.tool_name === \"string\" ? input.tool_name : \"\",\n toolInput: input.tool_input ?? {},\n ...(toolOutputToString(input.tool_output) !== undefined\n ? { toolOutput: toolOutputToString(input.tool_output) }\n : {}),\n };\n return ev;\n }\n case \"PostToolUseFailure\": {\n const ev: PostToolUseFailureEvent = {\n ...base,\n toolName: typeof input.tool_name === \"string\" ? input.tool_name : \"\",\n toolInput: input.tool_input ?? {},\n error: typeof input.error === \"string\" ? input.error : \"\",\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n // Grok sends `user_prompt` (NOT Claude's `prompt`).\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.user_prompt === \"string\" ? input.user_prompt : \"\",\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(input.source),\n };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = { ...base };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = { ...base };\n return ev;\n }\n case \"Notification\": {\n const ev: NotificationEvent = {\n ...base,\n message: typeof input.message === \"string\" ? input.message : \"\",\n };\n return ev;\n }\n case \"PreCompact\": {\n const ev: PreCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"PostCompact\": {\n const ev: PostCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"SubagentStart\": {\n const ev: SubagentStartEvent = {\n ...base,\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n };\n return ev;\n }\n case \"SubagentStop\": {\n const ev: SubagentStopEvent = {\n ...base,\n ...(typeof input.agent_type === \"string\" ? { agentType: input.agent_type } : {}),\n };\n return ev;\n }\n default: {\n // Grok never delivers PermissionRequest (no native equivalent — see\n // SUPPORTED_EVENTS). Surface a dispatch of one loudly rather than\n // silently mis-parse.\n throw new Error(`unsupported grok-cli hook event: ${String(event)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Grok native hook reply ──────────────────\n // Grok parses stdout as JSON when it starts with `{` and aggregates:\n // decision:\"block\" (or exit 2) → block; decision:\"approve\" → approve;\n // additionalContext → injected context; continue:false + stopReason → halt.\n // We emit exit 0 + a structured stdout object so the JSON is always parsed.\n\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // deny → block the action with a reason (decision:\"block\").\n if (decision === \"deny\") {\n return this.stdout({ decision: \"block\", reason: response.reason ?? \"Blocked by hook\" });\n }\n\n // context → inject soft guidance (Grok honors additionalContext).\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({ additionalContext: response.additionalContext });\n }\n\n // allow / modify (unsupported) / ask (no Grok analog) / void → passthrough.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n}\n\n/** Coerce a Grok PostToolUse `tool_output` into a string for the normalized event. */\nfunction toolOutputToString(value: unknown): string | undefined {\n if (value == null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const adapter = new GrokCliAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
fail
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-7HUUINPB.js";
|
|
5
|
+
import "./chunk-BLTVZACS.js";
|
|
6
6
|
import "./chunk-OP4KBXUO.js";
|
|
7
7
|
import "./chunk-LN76OGNR.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-ZMLVR4J7.js";
|
|
9
9
|
import {
|
|
10
10
|
isNativeHookDeclared,
|
|
11
11
|
runHook,
|
|
12
12
|
runNativeHook
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import "./chunk-4FWETID5.js";
|
|
13
|
+
} from "./chunk-LAIITCMW.js";
|
|
15
14
|
import "./chunk-KHO5WNTP.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-4FWETID5.js";
|
|
16
|
+
import "./chunk-NWLRJNXM.js";
|
|
17
|
+
import "./chunk-G4CEELKO.js";
|
|
18
|
+
import "./chunk-25CPWJA7.js";
|
|
19
19
|
import "./chunk-56R2ER7K.js";
|
|
20
20
|
import "./chunk-HORHRHNG.js";
|
|
21
21
|
import "./chunk-YYNXIUR2.js";
|
|
@@ -93,4 +93,4 @@ export {
|
|
|
93
93
|
HOOK_EVENTS,
|
|
94
94
|
run
|
|
95
95
|
};
|
|
96
|
-
//# sourceMappingURL=hook-
|
|
96
|
+
//# sourceMappingURL=hook-P6EKDINW.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as ActionDef, C as CommandDef, c as ConfigPatchDef, d as ConnectorConfig, R as ResolvedConnector, e as HookEventName, H as HookDefinition, M as MemoryDef, N as NativeHookDef, w as SkillDef, y as StatuslineDef, B as SubagentDef } from './types-
|
|
2
|
-
export { a as ActionResult, b as AuthSpec, V as ChangeRecord, W as DetectedPlatform, X as DiagnosticResult, E as EventPayloadMap, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, Y as InstallResult, I as InstallScope, j as NativeHookEvent, k as NotificationEvent, l as PermissionRequestEvent, m as PlatformCapabilities, P as PlatformId, n as PlatformMemoryOverride, o as PlatformOverride, p as PostToolUseEvent, q as PostToolUseFailureEvent, r as PreCompactEvent, s as PreToolUseEvent, S as ServerDef, u as SessionEndEvent, v as SessionStartEvent, x as StatuslineContext, z as StopEvent, D as SubagentStartEvent, F as SubagentStopEvent, T as TelemetryAccessor, K as TelemetryConfig, L as TelemetryUsageSummary, O as ToolFilter, Q as Transport, U as UserPromptSubmitEvent } from './types-
|
|
1
|
+
import { A as ActionDef, C as CommandDef, c as ConfigPatchDef, d as ConnectorConfig, R as ResolvedConnector, e as HookEventName, H as HookDefinition, M as MemoryDef, N as NativeHookDef, w as SkillDef, y as StatuslineDef, B as SubagentDef } from './types-C4qMgbJn.js';
|
|
2
|
+
export { a as ActionResult, b as AuthSpec, V as ChangeRecord, W as DetectedPlatform, X as DiagnosticResult, E as EventPayloadMap, f as HookParadigm, g as HookResponse, h as HooksConfig, i as HostCtx, Y as InstallResult, I as InstallScope, j as NativeHookEvent, k as NotificationEvent, l as PermissionRequestEvent, m as PlatformCapabilities, P as PlatformId, n as PlatformMemoryOverride, o as PlatformOverride, p as PostToolUseEvent, q as PostToolUseFailureEvent, r as PreCompactEvent, s as PreToolUseEvent, S as ServerDef, u as SessionEndEvent, v as SessionStartEvent, x as StatuslineContext, z as StopEvent, D as SubagentStartEvent, F as SubagentStopEvent, T as TelemetryAccessor, K as TelemetryConfig, L as TelemetryUsageSummary, O as ToolFilter, Q as Transport, U as UserPromptSubmitEvent } from './types-C4qMgbJn.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* core/define-connector — the public write-once entry point.
|
package/dist/index.js
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
defineSkill,
|
|
12
12
|
defineStatusline,
|
|
13
13
|
defineSubagent
|
|
14
|
-
} from "./chunk-
|
|
15
|
-
import "./chunk-
|
|
14
|
+
} from "./chunk-G4CEELKO.js";
|
|
15
|
+
import "./chunk-25CPWJA7.js";
|
|
16
16
|
import "./chunk-56R2ER7K.js";
|
|
17
17
|
import "./chunk-YYNXIUR2.js";
|
|
18
18
|
import "./chunk-IXOQDZWC.js";
|
|
@@ -3,29 +3,29 @@ import {
|
|
|
3
3
|
installConnector,
|
|
4
4
|
installViaMarketplace,
|
|
5
5
|
parseInstallMethod
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-KIRCPLM4.js";
|
|
7
|
+
import "./chunk-LF76VPGQ.js";
|
|
8
8
|
import "./chunk-QKLJU4JX.js";
|
|
9
|
+
import "./chunk-UM5S7DKK.js";
|
|
9
10
|
import "./chunk-NBUEL74R.js";
|
|
11
|
+
import "./chunk-OPXAP3AC.js";
|
|
10
12
|
import {
|
|
11
13
|
fail,
|
|
12
14
|
parseScope,
|
|
13
15
|
parseTargets,
|
|
14
16
|
print,
|
|
15
17
|
renderInstallResult
|
|
16
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-7HUUINPB.js";
|
|
17
19
|
import "./chunk-LN76OGNR.js";
|
|
18
|
-
import "./chunk-
|
|
20
|
+
import "./chunk-ZMLVR4J7.js";
|
|
19
21
|
import "./chunk-KHO5WNTP.js";
|
|
20
22
|
import {
|
|
21
23
|
findConnectorConfig,
|
|
22
24
|
loadConnectorFromPath
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
25
|
+
} from "./chunk-NWLRJNXM.js";
|
|
26
|
+
import "./chunk-G4CEELKO.js";
|
|
27
|
+
import "./chunk-25CPWJA7.js";
|
|
26
28
|
import "./chunk-56R2ER7K.js";
|
|
27
|
-
import "./chunk-OPXAP3AC.js";
|
|
28
|
-
import "./chunk-UM5S7DKK.js";
|
|
29
29
|
import "./chunk-H53QZQJI.js";
|
|
30
30
|
import "./chunk-BEFVJ2OE.js";
|
|
31
31
|
import "./chunk-VVFDU4IX.js";
|
|
@@ -93,4 +93,4 @@ async function run(argv) {
|
|
|
93
93
|
export {
|
|
94
94
|
run
|
|
95
95
|
};
|
|
96
|
-
//# sourceMappingURL=install-
|
|
96
|
+
//# sourceMappingURL=install-7DMK53SB.js.map
|
|
@@ -619,9 +619,15 @@ var JetBrainsCopilotAdapter = class extends BaseAdapter {
|
|
|
619
619
|
}
|
|
620
620
|
}
|
|
621
621
|
}
|
|
622
|
-
/**
|
|
622
|
+
/**
|
|
623
|
+
* Resolve the project dir from the wire payload. PRIMARY SOURCE (VS Code
|
|
624
|
+
* `.github/hooks` dialect this host aliases): the only working-directory field
|
|
625
|
+
* sent is `cwd`. There is no `workspace_roots` field — the old
|
|
626
|
+
* `?? workspace_roots[0]` fallback read a host-nonexistent field and is removed
|
|
627
|
+
* (parity with vscode-copilot #211).
|
|
628
|
+
*/
|
|
623
629
|
getProjectDir(input) {
|
|
624
|
-
return input.cwd
|
|
630
|
+
return typeof input.cwd === "string" ? input.cwd : void 0;
|
|
625
631
|
}
|
|
626
632
|
// ── Runtime: normalized response → JetBrains Copilot native hook reply ────
|
|
627
633
|
formatReply(event, response) {
|
|
@@ -688,4 +694,4 @@ export {
|
|
|
688
694
|
adapter,
|
|
689
695
|
jetbrains_copilot_default as default
|
|
690
696
|
};
|
|
691
|
-
//# sourceMappingURL=jetbrains-copilot-
|
|
697
|
+
//# sourceMappingURL=jetbrains-copilot-T2EPKROP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/jetbrains-copilot/index.ts"],"sourcesContent":["/**\n * adapters/jetbrains-copilot — JetBrains Copilot platform adapter for agent-connector.\n *\n * JetBrains Copilot shares the Copilot hook paradigm with VS Code Copilot\n * (Claude-compatible json-stdio), but diverges on MCP registration:\n *\n * - MCP servers: JetBrains stores MCP server registration via the IDE Settings\n * UI (Settings > Tools > GitHub Copilot > MCP > Configure), NOT in any file\n * we can reliably write — the runtime owns the `servers` key behind the UI.\n * So `installServer` writes NOTHING and returns a \"warn\" ChangeRecord telling\n * the user to add the server via the JetBrains MCP settings UI. Writing a\n * bogus file would be ignored at best and corrupt real UI state at worst.\n * `getHealthChecks` surfaces this as a WARN (not FAIL).\n *\n * - Hooks (Copilot Preview hooks): file-based and identical in shape to VS Code\n * Copilot. We write one per-connector file at\n * <projectDir>/.github/hooks/<connector-id>.json shaped as:\n * { \"version\": 1, \"hooks\": { <Event>: [ { \"type\": \"command\", \"command\" } ] } }\n * The top-level `version: 1` is REQUIRED — the Copilot hooks runtime rejects a\n * version-less file and no hooks fire. Each entry is a FLAT { type, command }\n * object (no Claude-style { matcher, hooks:[...] } wrapper). JetBrains parses\n * matchers but IGNORES them — ALL hooks fire on ALL tools — so we omit the\n * matcher entirely rather than persist an advisory one that never applies.\n *\n * - Reply: Claude-compatible JSON on stdout (exit 0), a `hookSpecificOutput`\n * object keyed by the PascalCase `hookEventName` carrying permissionDecision\n * (deny|ask) + permissionDecisionReason and additionalContext. This mirrors\n * vscode-copilot/claude-code exactly EXCEPT JetBrains cannot rewrite tool\n * input (canModifyArgs:false), so a \"modify\" decision degrades to allow.\n *\n * Env interpolation: GitHub Copilot does not document a portable native env\n * token for the hooks file, and the hooks file only ever carries our home-bin\n * hook command (no secrets), so there is nothing to interpolate here. MCP env\n * interpolation is moot because we never write the MCP file.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n CommandDef,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PostCompactEvent,\n PreCompactEvent,\n PreToolUseEvent,\n SessionEndEvent,\n SessionStartEvent,\n StopEvent,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport {\n buildHomeBinHookCommand,\n isHomeBinHookCommand,\n} from \"../../core/spawn.js\";\nimport { renderSkillMd } from \"../claude-code/render.js\";\nimport { normalizeSessionSource } from \"../claude-code/wire.js\";\n\nconst HOST: PlatformId = \"jetbrains-copilot\";\n\n/** Top-level version the Copilot hooks runtime requires; a version-less file is rejected. */\nconst JETBRAINS_HOOKS_VERSION = 1;\n\n/**\n * JetBrains Copilot reads PascalCase hook event names from its hooks file —\n * identical to VS Code Copilot / Claude Code. Only the events JetBrains actually\n * delivers are registered; everything else has no Copilot equivalent and is\n * reported as a warn/skip at install time.\n */\nconst EVENT_MAP: Partial<Record<HookEventName, string>> = {\n PreToolUse: \"PreToolUse\",\n PostToolUse: \"PostToolUse\",\n PreCompact: \"PreCompact\",\n SessionStart: \"SessionStart\",\n SessionEnd: \"SessionEnd\",\n UserPromptSubmit: \"UserPromptSubmit\",\n};\n\n/** A single JetBrains Copilot native hook entry — a flat command object. */\ninterface JetBrainsHookEntry {\n type: \"command\";\n command: string;\n}\n\n/** The shape of a JetBrains Copilot .github/hooks/<connector>.json file. */\ninterface JetBrainsHooksFile {\n version?: number;\n hooks?: Record<string, JetBrainsHookEntry[]>;\n}\n\n/**\n * Raw JetBrains Copilot hook stdin payload (Claude-compatible snake_case fields).\n *\n * Common input fields (every event): session_id, transcript_path, cwd,\n * hook_event_name. There is NO `workspace_roots` field — JetBrains aliases the\n * VS Code `.github/hooks` surface which sends only `cwd` (workspace_roots was a\n * dead fallback; removed — getProjectDir now relies on `cwd` only, matching\n * vscode-copilot #211).\n */\ninterface JetBrainsWireInput {\n session_id?: string;\n transcript_path?: string;\n cwd?: string;\n hook_event_name?: string;\n\n // tool events. PostToolUse fires ONLY after a tool completes SUCCESSFULLY and\n // sends { tool_name, tool_input, tool_use_id, tool_response } — the VS Code\n // `.github/hooks` dialect this host ALIASES (vscode-copilot), NOT copilot-cli's\n // `tool_result`. `tool_response` is the sole result field; there is NO\n // `tool_output` and NO `error_message`, so those reads are dead here.\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: unknown;\n\n // SessionStart\n source?: string;\n // SessionEnd\n reason?: string;\n // UserPromptSubmit\n prompt?: string;\n // PreCompact\n trigger?: string;\n // Stop\n stop_hook_active?: boolean;\n // Notification\n message?: string;\n\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\n connector?: string;\n}\n\nexport class JetBrainsCopilotAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"JetBrains Copilot\";\n readonly paradigm: HookParadigm = \"json-stdio\";\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 // JetBrains Copilot's Preview hooks runtime delivers Pre/PostToolUse,\n // PreCompact, SessionStart, SessionEnd, and UserPromptSubmit (GitHub's\n // hooks-reference) — same surface as VS Code Copilot, whose reply contract\n // this adapter mirrors exactly (see formatReply: UserPromptSubmit/PostToolUse\n // deny → top-level {decision:block}). Stop stays unwired (refuted for\n // JetBrains: an unimplemented feature request, not in the documented schema).\n preToolUse: true,\n postToolUse: true,\n preCompact: true,\n sessionStart: true,\n sessionEnd: true,\n userPromptSubmit: true,\n stop: false,\n notification: false,\n // Newer events: the JetBrains Copilot Preview hooks runtime documents no\n // permission-dialog, tool-failure, or subagent lifecycle events, so\n // permissionRequest / postToolUseFailure / subagentStart / subagentStop\n // stay unset — install reports the standard skip-warn for them.\n // Per the JetBrains spec this host is deny/ask-only: a PreToolUse hook\n // CANNOT rewrite tool input, and PostToolUse cannot rewrite tool output.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n // MCP is managed via the IDE Settings UI (Settings > Tools > GitHub Copilot\n // > MCP). The UI accepts local stdio servers AND remote Streamable HTTP / SSE\n // servers; AC writes no file, so this list only describes what the UI accepts\n // (install reports a UI-managed warn for every transport).\n transports: [\"stdio\", \"http\", \"sse\"],\n // Content surfaces: JetBrains Copilot consumes the GitHub Copilot .github/\n // files (it has no distinct authoring location), so it is an ALIAS of the\n // vscode-copilot writer for prompt files and Agent Skills. It has no native\n // subagent/chat-mode surface, so subagents stay unsupported (BaseAdapter\n // returns the skip/warn default).\n supportsCommands: true,\n supportsSkills: true,\n supportsSubagents: false,\n // Native passthrough: GitHub's JetBrains-Copilot changelog documents an\n // errorOccurred / ErrorOccurred lifecycle event with NO canonical\n // HookEventName analog (PostToolUseFailure is tool-scoped, not a session-wide\n // error event). A connector reaches it via platforms[\"jetbrains-copilot\"].\n // nativeHooks; installHooks files the event-name key VERBATIM and the generic\n // uninstall reverses it. PascalCase ErrorOccurred matches the adapter's\n // Claude-compatible payload dialect (GitHub hooks-reference accepts both).\n supportsNativeHooks: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n // JetBrains Copilot integration is observable through two markers:\n // • the project hooks tree (<projectDir>/.github/hooks) we write to, and\n // • our per-connector hooks file specifically.\n // There is no reliable user-profile MCP file to probe (the UI owns it), so\n // detection is project-scoped and keyed on the hooks footprint.\n const githubDir = join(projectDir, \".github\");\n const hooksDir = join(githubDir, \"hooks\");\n const installed = existsSync(hooksDir) || existsSync(githubDir);\n const configPath = hooksDir;\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope: \"project\",\n reason: installed\n ? `found JetBrains Copilot hooks tree at ${hooksDir}`\n : `no JetBrains Copilot hooks tree at ${hooksDir}`,\n confidence: installed ? \"medium\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /** Hooks live under the workspace .github tree for both scopes. */\n getConfigDir(ctx: InstallContext): string {\n return join(ctx.projectDir, \".github\");\n }\n\n /**\n * MCP server registration has NO writable file on JetBrains — the IDE owns it\n * behind the Settings UI. We still return a stable path (the hooks file) so the\n * base-adapter `doctor`/`backupSettings` helpers have a sensible target rather\n * than a nonexistent/bogus MCP path. `installServer` never writes here.\n */\n getServerConfigPath(ctx: InstallContext): string {\n return this.getHookConfigPath(ctx);\n }\n\n /**\n * Hook registration lives in the workspace-discovered .github/hooks tree, which\n * JetBrains Copilot scans for *.json hook files. We write one file per connector\n * so installs/uninstalls never clobber another connector's hooks. Anchored on\n * projectDir for both scopes — .github/hooks is a workspace concept (there is no\n * user-profile equivalent in the Copilot hooks schema).\n */\n getHookConfigPath(ctx: InstallContext): string {\n return join(ctx.projectDir, \".github\", \"hooks\", `${ctx.connector.id}.json`);\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n /**\n * JetBrains MCP registration is UI-only. We never write a file: a bogus file is\n * ignored at best and corrupts real UI-managed state at worst. Emit a \"warn\"\n * ChangeRecord that tells the user exactly where to add the server by hand.\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 jetbrains-copilot\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `JetBrains Copilot manages MCP servers via the IDE Settings UI — ` +\n `add \"${connector.id}\" manually under Settings > Tools > GitHub Copilot ` +\n `> MCP > Configure (no file is written here).`,\n },\n ];\n }\n\n /**\n * Nothing was written for the MCP server, so there is nothing to remove. Mirror\n * the install-time guidance as a \"warn\" so an uninstall report is honest about\n * the UI-managed entry the user may still want to remove by hand.\n */\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (!connector.server || connector.platforms[HOST]?.server === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"no MCP server was registered for jetbrains-copilot\",\n },\n ];\n }\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `JetBrains Copilot MCP servers are UI-managed — if \"${connector.id}\" was ` +\n `added manually, remove it under Settings > Tools > GitHub Copilot > MCP.`,\n },\n ];\n }\n\n // ── Hook install / uninstall ─────────────────────────────────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST];\n const hooksDisabled = override?.hooks === false;\n // `hooks: false` disables only the NORMALIZED events; nativeHooks is a\n // sibling, jetbrains-copilot-scoped declaration that installs regardless.\n const normalizedEvents = hooksDisabled ? [] : connector.hookEvents;\n const nativeHooks = override?.nativeHooks ?? {};\n const nativeEvents = Object.keys(nativeHooks);\n\n if (normalizedEvents.length === 0 && nativeEvents.length === 0) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: hooksDisabled\n ? \"hooks disabled for jetbrains-copilot\"\n : \"connector declares no hooks\",\n },\n ];\n }\n\n const hooksPath = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(hooksPath);\n if (symlink) return [symlink];\n\n const file = this.readJson<JetBrainsHooksFile>(hooksPath) ?? {};\n const __skip = this.malformedHookRootSkip(hooksPath, (file as Record<string, unknown>).hooks);\n if (__skip) return [__skip];\n const hooks = (file.hooks ??= {});\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of normalizedEvents) {\n const jetbrainsEvent = EVENT_MAP[event];\n if (!jetbrainsEvent) {\n // No JetBrains Copilot equivalent for this normalized event — report+skip.\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: hooksPath,\n detail: `${event} has no JetBrains Copilot hook equivalent — skipped`,\n });\n continue;\n }\n\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n // Matchers are IGNORED by JetBrains (all hooks fire on all tools), so we omit\n // the matcher entirely — a flat { type, command } entry.\n const entry: JetBrainsHookEntry = { type: \"command\", command };\n\n const bucket = (hooks[jetbrainsEvent] ??= []);\n const existingIdx = bucket.findIndex((e) => this.isOurCommand(e.command, ctx));\n\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent} already registered`,\n });\n continue;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent}`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent}`,\n });\n }\n mutated = true;\n }\n\n // NATIVE passthrough events: jetbrains-copilot-native event-name keys (e.g.\n // ErrorOccurred) filed VERBATIM into the hooks map — no EVENT_MAP, since they\n // ARE Copilot events. Flat { type, command } entry (matchers are ignored);\n // matched by EXACT command so a native key coinciding with a normalized one\n // never clobbers it.\n for (const nativeEvent of nativeEvents) {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, nativeEvent, connector.id);\n const entry: JetBrainsHookEntry = { type: \"command\", command };\n const bucket = (hooks[nativeEvent] ??= []);\n const existingIdx = bucket.findIndex((e) => e.command === command);\n if (existingIdx >= 0) {\n if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native) already registered`,\n });\n continue;\n }\n bucket[existingIdx] = entry;\n changes.push({\n platform: this.id,\n action: \"update\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native)`,\n });\n } else {\n bucket.push(entry);\n changes.push({\n platform: this.id,\n action: \"create\",\n path: hooksPath,\n detail: `hooks.${nativeEvent} (native)`,\n });\n }\n mutated = true;\n }\n\n if (mutated) {\n // The top-level version is REQUIRED — a version-less file is rejected and\n // no hooks fire. Always (re)assert it when we write.\n file.version = JETBRAINS_HOOKS_VERSION;\n this.writeJson(hooksPath, file, ctx.dryRun);\n }\n return changes;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const hooksPath = this.getHookConfigPath(ctx);\n const symlink = this.symlinkPathWarning(hooksPath);\n if (symlink) return [symlink];\n\n const file = this.readJson<JetBrainsHooksFile>(hooksPath);\n const hooks = file?.hooks;\n if (!file || !hooks) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no hooks section present\",\n },\n ];\n }\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const jetbrainsEvent of Object.keys(hooks)) {\n const bucket = hooks[jetbrainsEvent];\n if (!Array.isArray(bucket)) continue;\n\n const before = bucket.length;\n // Only strip OUR connector's home-bin commands — never another connector's\n // (isHomeBinHookCommand is id-anchored against a shared-prefix collision).\n const next = bucket.filter((e) => !this.isOurCommand(e.command, ctx));\n const removed = before - next.length;\n if (removed > 0) {\n if (next.length > 0) hooks[jetbrainsEvent] = next;\n else delete hooks[jetbrainsEvent];\n changes.push({\n platform: this.id,\n action: \"remove\",\n path: hooksPath,\n detail: `hooks.${jetbrainsEvent} (${removed})`,\n });\n mutated = true;\n }\n }\n\n if (mutated) {\n // The hooks file is connector-OWNED (<connector-id>.json), so when our\n // strip leaves it with NO hooks we must DELETE the whole file rather than\n // rewrite a `{ \"hooks\": {}, \"version\": 1 }` shell — an empty shell is an\n // orphan per-connector file that lingers after uninstall. A non-empty\n // result still belongs to us, so we rewrite it as before. dryRun reports\n // the would-be remove without mutating the filesystem.\n if (Object.keys(hooks).length === 0) {\n changes.push(\n this.removeManagedFile(\n hooksPath,\n ctx.dryRun,\n \"removed empty connector hooks file\",\n \"no hooks file present\",\n ),\n );\n // Clean up the parent .github/hooks dir only when it is now empty (it is\n // a per-connector tree; leave it in place if other connectors' files\n // remain).\n changes.push(this.removeDirIfEmpty(dirname(hooksPath), ctx.dryRun));\n } else {\n this.writeJson(hooksPath, file, ctx.dryRun);\n }\n }\n if (changes.length === 0) {\n changes.push({\n platform: this.id,\n action: \"skip\",\n path: hooksPath,\n detail: \"no matching hook entries\",\n });\n }\n return changes;\n }\n\n /** True when a hook command references our home binary AND this connector id\n * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand). */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── Content surfaces: commands / skills ──────────────────────────────────\n // CONTENT-ONLY: pure native-file writers under the workspace .github/ tree\n // ({prompts,skills}). No runtime dispatch, no home-bin pointer, no telemetry\n // wrap. Each method is idempotent (byte-identical → skip) via\n // BaseAdapter.writeContentFile and reversible via removeContentFile. Honors\n // platforms[\"jetbrains-copilot\"] per-surface false to skip.\n //\n // ALIAS of vscode-copilot: JetBrains consumes the GitHub Copilot .github/\n // files and has no distinct authoring location, so the rendered content +\n // paths here are IDENTICAL to the vscode-copilot writer.\n //\n // SHARED .github TREE: vscode-copilot, copilot-cli, and jetbrains-copilot all\n // write under the SAME project <projectDir>/.github tree. The rendered content\n // is identical and idempotent across those connectors, and uninstall here only\n // removes the files THIS connector declared — never another writer's files.\n //\n // SCOPE NOTE: .github is a workspace concept and this adapter is project-\n // scoped (no user-profile .github authoring location exists in the Copilot\n // prompt/skill discovery), so the content root is always the project .github\n // tree — the same dir getConfigDir already anchors on.\n\n /** Root of the content tree — the project .github tree (see getConfigDir). */\n private contentRootDir(ctx: InstallContext): string {\n return this.getConfigDir(ctx);\n }\n\n private promptsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"prompts\");\n }\n private skillsDir(ctx: InstallContext): string {\n return join(this.contentRootDir(ctx), \"skills\");\n }\n\n /** Native command file path: <ghDir>/prompts/<name>.prompt.md. */\n private commandPath(ctx: InstallContext, name: string): string {\n return join(this.promptsDir(ctx), `${name}.prompt.md`);\n }\n /** Native skill dir: <ghDir>/skills/<name>. */\n private skillDir(ctx: InstallContext, name: string): string {\n return join(this.skillsDir(ctx), name);\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 jetbrains-copilot\" }];\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 Copilot prompt file: md+frontmatter(description, tools, model, argument-hint). */\n private renderCommand(cmd: CommandDef): string {\n const frontmatter: Record<string, unknown> = {};\n if (cmd.description !== undefined) frontmatter.description = cmd.description;\n // Copilot prompt files express tool access as a `tools` array, sourced from\n // the portable tools.allow policy.\n const allow = cmd.tools?.allow;\n if (allow && allow.length > 0) frontmatter.tools = [...allow];\n if (cmd.model !== undefined) frontmatter.model = cmd.model;\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[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for jetbrains-copilot\" }];\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 // 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 // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const hooksPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n const hasServer =\n ctx.connector.server != null &&\n ctx.connector.platforms[HOST]?.server !== false;\n const checks: HealthCheck[] = [\n {\n // MCP cannot be verified from disk — JetBrains owns it behind the UI.\n // BaseAdapter.doctor maps != OK to a hard FAIL, but an unverifiable\n // UI-managed surface must NOT hard-fail doctor (that contradicts the\n // install-time WARN). Return OK with a verify-in-UI detail instead.\n name: `${this.name}: MCP server (UI-managed)`,\n check: () =>\n hasServer\n ? {\n status: \"OK\",\n detail:\n \"MCP is UI-managed — verify in Settings > Tools > GitHub Copilot > MCP\",\n }\n : { status: \"OK\", detail: \"connector declares no MCP server\" },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n const file = this.readJson<JetBrainsHooksFile>(hooksPath);\n if (!file) return { status: \"FAIL\", detail: `not found: ${hooksPath}` };\n if (file.version !== JETBRAINS_HOOKS_VERSION) {\n return {\n status: \"FAIL\",\n detail: `${hooksPath} missing required \"version\": ${JETBRAINS_HOOKS_VERSION} — Copilot rejects it`,\n };\n }\n const registered = Object.values(file.hooks ?? {}).some((entries) =>\n (entries ?? []).some((e) =>\n isHomeBinHookCommand(e.command, homeBin, connectorId),\n ),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${hooksPath}` };\n },\n },\n ];\n\n // Content-surface checks: only assert presence of the files this connector\n // declares (skip silently for surfaces it never asked for). Subagents are\n // unsupported here, so they are never checked.\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 return checks;\n }\n\n // ── Runtime: parse JetBrains Copilot stdin JSON → normalized event ────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as JetBrainsWireInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = extractSessionId(input);\n const projectDir = this.getProjectDir(input);\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n raw,\n ...(projectDir !== undefined ? { projectDir } : {}),\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n // PRIMARY SOURCE (VS Code Copilot hooks docs, \"PostToolUse input\"):\n // JetBrains aliases the VS Code `.github/hooks` surface, which fires\n // PostToolUse only after a tool completes SUCCESSFULLY and serializes a\n // single result field, `tool_response`. There is NO `tool_output` and NO\n // `error_message` in this dialect, so the old fallback legs read\n // host-nonexistent fields and the `error_message`-driven `isError` could\n // never become true. Read only `tool_response`; a tool-failure event\n // (PostToolUseFailure) is not part of this surface and is not wired.\n const toolOutput = toolResponseToString(input.tool_response);\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(toolOutput !== undefined ? { toolOutput } : {}),\n };\n return ev;\n }\n case \"PreCompact\": {\n const ev: PreCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"PostCompact\": {\n // JetBrains Copilot does not fire PostCompact natively (postCompact\n // unset → warn-skip at install). Parsed defensively, mirroring\n // PreCompact, so a manual/mis-routed dispatch normalizes instead of\n // hitting the guard.\n const ev: PostCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(input.source ?? input.trigger),\n };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.reason === \"string\" ? { reason: input.reason } : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = {\n ...base,\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n return ev;\n }\n case \"Notification\": {\n const ev: NotificationEvent = {\n ...base,\n message: typeof input.message === \"string\" ? input.message : \"\",\n };\n return ev;\n }\n case \"PermissionRequest\":\n case \"PostToolUseFailure\":\n case \"SubagentStart\":\n case \"SubagentStop\": {\n // No JetBrains Copilot analog — its Preview hooks runtime documents no\n // permission-dialog, tool-failure, or subagent lifecycle events.\n // Install already skip-warns these via EVENT_MAP; a runtime dispatch is\n // a mis-route — fail loudly.\n throw new Error(`unsupported jetbrains-copilot hook event: ${String(event)}`);\n }\n default: {\n // Exhaustive guard — every HookEventName is handled above. (JetBrains only\n // delivers the four it declares; the rest are handled defensively so a\n // mis-dispatch stays inert rather than crashing.)\n const _never: never = event;\n throw new Error(`unsupported jetbrains-copilot hook event: ${String(_never)}`);\n }\n }\n }\n\n /**\n * Resolve the project dir from the wire payload. PRIMARY SOURCE (VS Code\n * `.github/hooks` dialect this host aliases): the only working-directory field\n * sent is `cwd`. There is no `workspace_roots` field — the old\n * `?? workspace_roots[0]` fallback read a host-nonexistent field and is removed\n * (parity with vscode-copilot #211).\n */\n private getProjectDir(input: JetBrainsWireInput): string | undefined {\n return typeof input.cwd === \"string\" ? input.cwd : undefined;\n }\n\n // ── Runtime: normalized response → JetBrains Copilot native hook reply ────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const hookEventName = event;\n const decision = response.decision ?? \"allow\";\n\n // deny → block the action with a reason (exit 0; JSON carries the decision).\n // JetBrains Copilot's reply is Claude-compatible, identical to vscode-copilot:\n // `hookSpecificOutput.permissionDecision` is read ONLY for the pre-execution\n // PreToolUse permission event. The post-execution / turn-control events —\n // PostToolUse, UserPromptSubmit, Stop, SubagentStop — block via the TOP-LEVEL\n // {\"decision\":\"block\",\"reason\"} instead (PostToolUse runs AFTER the tool, so a\n // permissionDecision there is silently ignored). Mirrors vscode-copilot #56/#58.\n if (decision === \"deny\") {\n if (\n event === \"PostToolUse\" ||\n event === \"UserPromptSubmit\" ||\n event === \"Stop\" ||\n event === \"SubagentStop\"\n ) {\n return this.stdout({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n });\n }\n return this.stdout({\n hookSpecificOutput: {\n hookEventName,\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n });\n }\n\n // ask → prompt the user to confirm.\n if (decision === \"ask\") {\n return this.stdout({\n hookSpecificOutput: {\n hookEventName,\n permissionDecision: \"ask\",\n permissionDecisionReason:\n response.reason ?? \"Confirmation required by hook\",\n },\n });\n }\n\n // modify → unsupported on JetBrains (canModifyArgs:false): a PreToolUse hook\n // cannot rewrite tool input here, so degrade to allow rather than emit an\n // updatedInput the host will ignore.\n\n // context → inject soft guidance (also the SessionStart context path).\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({\n hookSpecificOutput: { hookEventName, additionalContext: response.additionalContext },\n });\n }\n\n // allow / void / modify-degradation / unsupported → pass through with exit 0.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n}\n\n/**\n * Extract a stable session id from a JetBrains Copilot wire payload. Priority\n * mirrors the Claude-compatible wire: transcript UUID > session_id > \"\" (the\n * framework uses \"\" when no id is available — no ppid fabrication here).\n */\nfunction extractSessionId(input: JetBrainsWireInput): string {\n if (typeof input.transcript_path === \"string\") {\n const m = input.transcript_path.match(/([a-f0-9-]{36})\\.jsonl$/);\n if (m && m[1]) return m[1];\n }\n if (typeof input.session_id === \"string\" && input.session_id !== \"\") {\n return input.session_id;\n }\n return \"\";\n}\n\n/** Coerce a Claude-compatible PostToolUse `tool_response` into a string. */\nfunction toolResponseToString(value: unknown): string | undefined {\n if (value == null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nexport const adapter = new JetBrainsCopilotAdapter();\nexport default adapter;\n"],"mappings":";;;;;;;;;;;;;;;;AAoCA,SAAS,kBAAkB;AAC3B,SAAS,SAAS,YAAY;AA+B9B,IAAM,OAAmB;AAGzB,IAAM,0BAA0B;AAQhC,IAAM,YAAoD;AAAA,EACxD,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,kBAAkB;AACpB;AAuDO,IAAM,0BAAN,cAAsC,YAA+B;AAAA,EACjE,KAAiB;AAAA,EACjB,OAAO;AAAA,EACP,WAAyB;AAAA,EAEzB,eAAqC;AAAA;AAAA;AAAA,IAG5C,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOhB,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,kBAAkB;AAAA,IAClB,MAAM;AAAA,IACN,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOd,eAAe;AAAA,IACf,iBAAiB;AAAA,IACjB,yBAAyB;AAAA;AAAA;AAAA;AAAA;AAAA,IAKzB,YAAY,CAAC,SAAS,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMnC,kBAAkB;AAAA,IAClB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQnB,qBAAqB;AAAA,EACvB;AAAA;AAAA,EAIA,gBAAgB,YAAsC;AAMpD,UAAM,YAAY,KAAK,YAAY,SAAS;AAC5C,UAAM,WAAW,KAAK,WAAW,OAAO;AACxC,UAAM,YAAY,WAAW,QAAQ,KAAK,WAAW,SAAS;AAC9D,UAAM,aAAa;AACnB,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX;AAAA,MACA,UAAU,KAAK;AAAA,MACf,cAAc,KAAK;AAAA,MACnB;AAAA,MACA,OAAO;AAAA,MACP,QAAQ,YACJ,yCAAyC,QAAQ,KACjD,sCAAsC,QAAQ;AAAA,MAClD,YAAY,YAAY,WAAW;AAAA,IACrC;AAAA,EACF;AAAA;AAAA;AAAA,EAKA,aAAa,KAA6B;AACxC,WAAO,KAAK,IAAI,YAAY,SAAS;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,oBAAoB,KAA6B;AAC/C,WAAO,KAAK,kBAAkB,GAAG;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,kBAAkB,KAA6B;AAC7C,WAAO,KAAK,IAAI,YAAY,WAAW,SAAS,GAAG,IAAI,UAAU,EAAE,OAAO;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,cAAc,KAAqC;AACjD,UAAM,EAAE,UAAU,IAAI;AACtB,UAAM,WAAW,UAAU,UAAU,IAAI,GAAG;AAC5C,QAAI,CAAC,UAAU,UAAU,aAAa,OAAO;AAC3C,aAAO;AAAA,QACL;AAAA,UACE,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,QAAQ,UAAU,SACd,uDACA;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,QACE,UAAU,KAAK;AAAA,QACf,QAAQ;AAAA,QACR,QACE,6EACQ,UAAU,EAAE;AAAA,MAExB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,gBAAgB,KAAqC;AACnD,UAAM,EAAE,UAAU,IAAI;AACtB,QAAI,CAAC,UAAU,UAAU,UAAU,UAAU,IAAI,GAAG,WAAW,OAAO;AACpE,aAAO;AAAA,QACL;AAAA,UACE,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,QACE,UAAU,KAAK;AAAA,QACf,QAAQ;AAAA,QACR,QACE,2DAAsD,UAAU,EAAE;AAAA,MAEtE;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,aAAa,KAAqC;AAChD,UAAM,EAAE,UAAU,IAAI;AACtB,UAAM,WAAW,UAAU,UAAU,IAAI;AACzC,UAAM,gBAAgB,UAAU,UAAU;AAG1C,UAAM,mBAAmB,gBAAgB,CAAC,IAAI,UAAU;AACxD,UAAM,cAAc,UAAU,eAAe,CAAC;AAC9C,UAAM,eAAe,OAAO,KAAK,WAAW;AAE5C,QAAI,iBAAiB,WAAW,KAAK,aAAa,WAAW,GAAG;AAC9D,aAAO;AAAA,QACL;AAAA,UACE,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,QAAQ,gBACJ,yCACA;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,kBAAkB,GAAG;AAC5C,UAAM,UAAU,KAAK,mBAAmB,SAAS;AACjD,QAAI,QAAS,QAAO,CAAC,OAAO;AAE5B,UAAM,OAAO,KAAK,SAA6B,SAAS,KAAK,CAAC;AAC9D,UAAM,SAAS,KAAK,sBAAsB,WAAY,KAAiC,KAAK;AAC5F,QAAI,OAAQ,QAAO,CAAC,MAAM;AAC1B,UAAM,QAAS,KAAK,UAAU,CAAC;AAE/B,UAAM,UAA0B,CAAC;AACjC,QAAI,UAAU;AAEd,eAAW,SAAS,kBAAkB;AACpC,YAAM,iBAAiB,UAAU,KAAK;AACtC,UAAI,CAAC,gBAAgB;AAEnB,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,GAAG,KAAK;AAAA,QAClB,CAAC;AACD;AAAA,MACF;AAEA,YAAM,UAAU,wBAAwB,IAAI,aAAa,MAAM,OAAO,UAAU,EAAE;AAGlF,YAAM,QAA4B,EAAE,MAAM,WAAW,QAAQ;AAE7D,YAAM,SAAU,MAAM,cAAc,MAAM,CAAC;AAC3C,YAAM,cAAc,OAAO,UAAU,CAAC,MAAM,KAAK,aAAa,EAAE,SAAS,GAAG,CAAC;AAE7E,UAAI,eAAe,GAAG;AACpB,YAAI,KAAK,UAAU,OAAO,WAAW,CAAC,MAAM,KAAK,UAAU,KAAK,GAAG;AACjE,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK;AAAA,YACf,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,QAAQ,SAAS,cAAc;AAAA,UACjC,CAAC;AACD;AAAA,QACF;AACA,eAAO,WAAW,IAAI;AACtB,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,SAAS,cAAc;AAAA,QACjC,CAAC;AAAA,MACH,OAAO;AACL,eAAO,KAAK,KAAK;AACjB,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,SAAS,cAAc;AAAA,QACjC,CAAC;AAAA,MACH;AACA,gBAAU;AAAA,IACZ;AAOA,eAAW,eAAe,cAAc;AACtC,YAAM,UAAU,wBAAwB,IAAI,aAAa,MAAM,aAAa,UAAU,EAAE;AACxF,YAAM,QAA4B,EAAE,MAAM,WAAW,QAAQ;AAC7D,YAAM,SAAU,MAAM,WAAW,MAAM,CAAC;AACxC,YAAM,cAAc,OAAO,UAAU,CAAC,MAAM,EAAE,YAAY,OAAO;AACjE,UAAI,eAAe,GAAG;AACpB,YAAI,KAAK,UAAU,OAAO,WAAW,CAAC,MAAM,KAAK,UAAU,KAAK,GAAG;AACjE,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK;AAAA,YACf,QAAQ;AAAA,YACR,MAAM;AAAA,YACN,QAAQ,SAAS,WAAW;AAAA,UAC9B,CAAC;AACD;AAAA,QACF;AACA,eAAO,WAAW,IAAI;AACtB,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,SAAS,WAAW;AAAA,QAC9B,CAAC;AAAA,MACH,OAAO;AACL,eAAO,KAAK,KAAK;AACjB,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,SAAS,WAAW;AAAA,QAC9B,CAAC;AAAA,MACH;AACA,gBAAU;AAAA,IACZ;AAEA,QAAI,SAAS;AAGX,WAAK,UAAU;AACf,WAAK,UAAU,WAAW,MAAM,IAAI,MAAM;AAAA,IAC5C;AACA,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,KAAqC;AAClD,UAAM,YAAY,KAAK,kBAAkB,GAAG;AAC5C,UAAM,UAAU,KAAK,mBAAmB,SAAS;AACjD,QAAI,QAAS,QAAO,CAAC,OAAO;AAE5B,UAAM,OAAO,KAAK,SAA6B,SAAS;AACxD,UAAM,QAAQ,MAAM;AACpB,QAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,aAAO;AAAA,QACL;AAAA,UACE,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAA0B,CAAC;AACjC,QAAI,UAAU;AAEd,eAAW,kBAAkB,OAAO,KAAK,KAAK,GAAG;AAC/C,YAAM,SAAS,MAAM,cAAc;AACnC,UAAI,CAAC,MAAM,QAAQ,MAAM,EAAG;AAE5B,YAAM,SAAS,OAAO;AAGtB,YAAM,OAAO,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,aAAa,EAAE,SAAS,GAAG,CAAC;AACpE,YAAM,UAAU,SAAS,KAAK;AAC9B,UAAI,UAAU,GAAG;AACf,YAAI,KAAK,SAAS,EAAG,OAAM,cAAc,IAAI;AAAA,YACxC,QAAO,MAAM,cAAc;AAChC,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK;AAAA,UACf,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,QAAQ,SAAS,cAAc,KAAK,OAAO;AAAA,QAC7C,CAAC;AACD,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,QAAI,SAAS;AAOX,UAAI,OAAO,KAAK,KAAK,EAAE,WAAW,GAAG;AACnC,gBAAQ;AAAA,UACN,KAAK;AAAA,YACH;AAAA,YACA,IAAI;AAAA,YACJ;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAIA,gBAAQ,KAAK,KAAK,iBAAiB,QAAQ,SAAS,GAAG,IAAI,MAAM,CAAC;AAAA,MACpE,OAAO;AACL,aAAK,UAAU,WAAW,MAAM,IAAI,MAAM;AAAA,MAC5C;AAAA,IACF;AACA,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK;AAAA,QACf,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,QAAQ;AAAA,MACV,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA,EAIQ,aAAa,SAA6B,KAA8B;AAC9E,WAAO,qBAAqB,SAAS,IAAI,aAAa,IAAI,UAAU,EAAE;AAAA,EACxE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwBQ,eAAe,KAA6B;AAClD,WAAO,KAAK,aAAa,GAAG;AAAA,EAC9B;AAAA,EAEQ,WAAW,KAA6B;AAC9C,WAAO,KAAK,KAAK,eAAe,GAAG,GAAG,SAAS;AAAA,EACjD;AAAA,EACQ,UAAU,KAA6B;AAC7C,WAAO,KAAK,KAAK,eAAe,GAAG,GAAG,QAAQ;AAAA,EAChD;AAAA;AAAA,EAGQ,YAAY,KAAqB,MAAsB;AAC7D,WAAO,KAAK,KAAK,WAAW,GAAG,GAAG,GAAG,IAAI,YAAY;AAAA,EACvD;AAAA;AAAA,EAEQ,SAAS,KAAqB,MAAsB;AAC1D,WAAO,KAAK,KAAK,UAAU,GAAG,GAAG,IAAI;AAAA,EACvC;AAAA;AAAA,EAIS,gBAAgB,KAAqC;AAC5D,UAAM,EAAE,UAAU,IAAI;AACtB,QAAI,UAAU,UAAU,IAAI,GAAG,aAAa,OAAO;AACjD,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,0CAA0C,CAAC;AAAA,IAClG;AACA,QAAI,UAAU,SAAS,WAAW,GAAG;AACnC,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,iCAAiC,CAAC;AAAA,IACzF;AACA,WAAO,UAAU,SAAS;AAAA,MAAI,CAAC,QAC7B,KAAK;AAAA,QACH,KAAK,YAAY,KAAK,IAAI,IAAI;AAAA,QAC9B,KAAK,cAAc,GAAG;AAAA,QACtB,IAAI;AAAA,MACN;AAAA,IACF;AAAA,EACF;AAAA,EAES,kBAAkB,KAAqC;AAC9D,UAAM,EAAE,UAAU,IAAI;AACtB,QAAI,UAAU,SAAS,WAAW,GAAG;AACnC,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,iCAAiC,CAAC;AAAA,IACzF;AACA,WAAO,UAAU,SAAS;AAAA,MAAI,CAAC,QAC7B,KAAK,kBAAkB,KAAK,YAAY,KAAK,IAAI,IAAI,GAAG,IAAI,MAAM;AAAA,IACpE;AAAA,EACF;AAAA;AAAA,EAGQ,cAAc,KAAyB;AAC7C,UAAM,cAAuC,CAAC;AAC9C,QAAI,IAAI,gBAAgB,OAAW,aAAY,cAAc,IAAI;AAGjE,UAAM,QAAQ,IAAI,OAAO;AACzB,QAAI,SAAS,MAAM,SAAS,EAAG,aAAY,QAAQ,CAAC,GAAG,KAAK;AAC5D,QAAI,IAAI,UAAU,OAAW,aAAY,QAAQ,IAAI;AACrD,QAAI,IAAI,iBAAiB,OAAW,aAAY,eAAe,IAAI,IAAI;AACvE,QAAI,IAAI,MAAO,QAAO,OAAO,aAAa,IAAI,KAAK;AACnD,WAAO,KAAK,oBAAoB,aAAa,IAAI,MAAM;AAAA,EACzD;AAAA;AAAA,EAIS,cAAc,KAAqC;AAC1D,UAAM,EAAE,UAAU,IAAI;AACtB,QAAI,UAAU,UAAU,IAAI,GAAG,WAAW,OAAO;AAC/C,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,wCAAwC,CAAC;AAAA,IAChG;AACA,QAAI,UAAU,OAAO,WAAW,GAAG;AACjC,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,+BAA+B,CAAC;AAAA,IACvF;AACA,UAAM,UAA0B,CAAC;AACjC,eAAW,SAAS,UAAU,QAAQ;AACpC,YAAM,MAAM,KAAK,SAAS,KAAK,MAAM,IAAI;AACzC,cAAQ;AAAA,QACN,KAAK,iBAAiB,KAAK,KAAK,UAAU,GAAG,cAAc,KAAK,GAAG,IAAI,MAAM;AAAA,MAC/E;AAIA,iBAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,MAAM,aAAa,CAAC,CAAC,GAAG;AACnE,cAAM,SAAS,KAAK,cAAc,KAAK,GAAG;AAC1C,YAAI,WAAW,MAAM;AACnB,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK;AAAA,YACf,QAAQ;AAAA,YACR,QAAQ,mBAAmB,GAAG;AAAA,UAChC,CAAC;AACD;AAAA,QACF;AACA,gBAAQ,KAAK,KAAK,iBAAiB,QAAQ,UAAU,IAAI,MAAM,CAAC;AAAA,MAClE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAES,gBAAgB,KAAqC;AAC5D,UAAM,EAAE,UAAU,IAAI;AACtB,QAAI,UAAU,OAAO,WAAW,GAAG;AACjC,aAAO,CAAC,EAAE,UAAU,KAAK,IAAI,QAAQ,QAAQ,QAAQ,+BAA+B,CAAC;AAAA,IACvF;AACA,UAAM,UAA0B,CAAC;AACjC,eAAW,SAAS,UAAU,QAAQ;AACpC,YAAM,MAAM,KAAK,SAAS,KAAK,MAAM,IAAI;AAGzC,cAAQ,KAAK,KAAK,kBAAkB,KAAK,KAAK,UAAU,GAAG,IAAI,MAAM,CAAC;AACtE,iBAAW,OAAO,OAAO,KAAK,MAAM,aAAa,CAAC,CAAC,GAAG;AACpD,cAAM,SAAS,KAAK,cAAc,KAAK,GAAG;AAC1C,YAAI,WAAW,KAAM;AACrB,gBAAQ,KAAK,KAAK,kBAAkB,QAAQ,IAAI,MAAM,CAAC;AAAA,MACzD;AAGA,cAAQ,KAAK,KAAK,iBAAiB,KAAK,IAAI,MAAM,CAAC;AAAA,IACrD;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIS,gBAAgB,KAA6C;AACpE,UAAM,YAAY,KAAK,kBAAkB,GAAG;AAC5C,UAAM,cAAc,IAAI,UAAU;AAClC,UAAM,UAAU,IAAI;AACpB,UAAM,aAAa,IAAI,UAAU;AACjC,UAAM,YACJ,IAAI,UAAU,UAAU,QACxB,IAAI,UAAU,UAAU,IAAI,GAAG,WAAW;AAC5C,UAAM,SAAwB;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,QAKE,MAAM,GAAG,KAAK,IAAI;AAAA,QAClB,OAAO,MACL,YACI;AAAA,UACE,QAAQ;AAAA,UACR,QACE;AAAA,QACJ,IACA,EAAE,QAAQ,MAAM,QAAQ,mCAAmC;AAAA,MACnE;AAAA,MACA;AAAA,QACE,MAAM,GAAG,KAAK,IAAI;AAAA,QAClB,OAAO,MAAM;AACX,cAAI,WAAW,WAAW,GAAG;AAC3B,mBAAO,EAAE,QAAQ,MAAM,QAAQ,oBAAoB;AAAA,UACrD;AACA,gBAAM,OAAO,KAAK,SAA6B,SAAS;AACxD,cAAI,CAAC,KAAM,QAAO,EAAE,QAAQ,QAAQ,QAAQ,cAAc,SAAS,GAAG;AACtE,cAAI,KAAK,YAAY,yBAAyB;AAC5C,mBAAO;AAAA,cACL,QAAQ;AAAA,cACR,QAAQ,GAAG,SAAS,gCAAgC,uBAAuB;AAAA,YAC7E;AAAA,UACF;AACA,gBAAM,aAAa,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,EAAE;AAAA,YAAK,CAAC,aACtD,WAAW,CAAC,GAAG;AAAA,cAAK,CAAC,MACpB,qBAAqB,EAAE,SAAS,SAAS,WAAW;AAAA,YACtD;AAAA,UACF;AACA,iBAAO,aACH,EAAE,QAAQ,MAAM,QAAQ,uBAAuB,IAC/C,EAAE,QAAQ,QAAQ,QAAQ,eAAe,WAAW,OAAO,SAAS,GAAG;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AAKA,eAAW,OAAO,IAAI,UAAU,UAAU;AACxC,YAAM,IAAI,KAAK,YAAY,KAAK,IAAI,IAAI;AACxC,aAAO,KAAK;AAAA,QACV,MAAM,GAAG,KAAK,IAAI,aAAa,IAAI,IAAI;AAAA,QACvC,OAAO,MACL,WAAW,CAAC,IAAI,EAAE,QAAQ,MAAM,QAAQ,EAAE,IAAI,EAAE,QAAQ,QAAQ,QAAQ,cAAc,CAAC,GAAG;AAAA,MAC9F,CAAC;AAAA,IACH;AACA,eAAW,SAAS,IAAI,UAAU,QAAQ;AACxC,YAAM,IAAI,KAAK,KAAK,SAAS,KAAK,MAAM,IAAI,GAAG,UAAU;AACzD,aAAO,KAAK;AAAA,QACV,MAAM,GAAG,KAAK,IAAI,WAAW,MAAM,IAAI;AAAA,QACvC,OAAO,MACL,WAAW,CAAC,IAAI,EAAE,QAAQ,MAAM,QAAQ,EAAE,IAAI,EAAE,QAAQ,QAAQ,QAAQ,cAAc,CAAC,GAAG;AAAA,MAC9F,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,WAAW,OAAsB,KAA+B;AAC9D,UAAM,QAAS,OAAO,CAAC;AACvB,UAAM,cAAc,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;AAC5E,UAAM,YAAY,iBAAiB,KAAK;AACxC,UAAM,aAAa,KAAK,cAAc,KAAK;AAE3C,UAAM,OAAO;AAAA,MACX,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,IACnD;AAEA,YAAQ,OAAO;AAAA,MACb,KAAK,cAAc;AACjB,cAAM,KAAsB;AAAA,UAC1B,GAAG;AAAA,UACH,UAAU,MAAM,aAAa;AAAA,UAC7B,WAAW,MAAM,cAAc,CAAC;AAAA,QAClC;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,eAAe;AASlB,cAAM,aAAa,qBAAqB,MAAM,aAAa;AAC3D,cAAM,KAAuB;AAAA,UAC3B,GAAG;AAAA,UACH,UAAU,MAAM,aAAa;AAAA,UAC7B,WAAW,MAAM,cAAc,CAAC;AAAA,UAChC,GAAI,eAAe,SAAY,EAAE,WAAW,IAAI,CAAC;AAAA,QACnD;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,KAAsB;AAAA,UAC1B,GAAG;AAAA,UACH,GAAI,MAAM,YAAY,UAAU,MAAM,YAAY,WAC9C,EAAE,SAAS,MAAM,QAAQ,IACzB,CAAC;AAAA,QACP;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,eAAe;AAKlB,cAAM,KAAuB;AAAA,UAC3B,GAAG;AAAA,UACH,GAAI,MAAM,YAAY,UAAU,MAAM,YAAY,WAC9C,EAAE,SAAS,MAAM,QAAQ,IACzB,CAAC;AAAA,QACP;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,gBAAgB;AACnB,cAAM,KAAwB;AAAA,UAC5B,GAAG;AAAA,UACH,QAAQ,uBAAuB,MAAM,UAAU,MAAM,OAAO;AAAA,QAC9D;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,cAAc;AACjB,cAAM,KAAsB;AAAA,UAC1B,GAAG;AAAA,UACH,GAAI,OAAO,MAAM,WAAW,WAAW,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,QACrE;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,oBAAoB;AACvB,cAAM,KAA4B;AAAA,UAChC,GAAG;AAAA,UACH,QAAQ,OAAO,MAAM,WAAW,WAAW,MAAM,SAAS;AAAA,QAC5D;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,QAAQ;AACX,cAAM,KAAgB;AAAA,UACpB,GAAG;AAAA,UACH,GAAI,OAAO,MAAM,qBAAqB,YAClC,EAAE,gBAAgB,MAAM,iBAAiB,IACzC,CAAC;AAAA,QACP;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK,gBAAgB;AACnB,cAAM,KAAwB;AAAA,UAC5B,GAAG;AAAA,UACH,SAAS,OAAO,MAAM,YAAY,WAAW,MAAM,UAAU;AAAA,QAC/D;AACA,eAAO;AAAA,MACT;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,gBAAgB;AAKnB,cAAM,IAAI,MAAM,6CAA6C,OAAO,KAAK,CAAC,EAAE;AAAA,MAC9E;AAAA,MACA,SAAS;AAIP,cAAM,SAAgB;AACtB,cAAM,IAAI,MAAM,6CAA6C,OAAO,MAAM,CAAC,EAAE;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASQ,cAAc,OAA+C;AACnE,WAAO,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM;AAAA,EACrD;AAAA;AAAA,EAIA,YAAY,OAAsB,UAAmC;AACnE,UAAM,gBAAgB;AACtB,UAAM,WAAW,SAAS,YAAY;AAStC,QAAI,aAAa,QAAQ;AACvB,UACE,UAAU,iBACV,UAAU,sBACV,UAAU,UACV,UAAU,gBACV;AACA,eAAO,KAAK,OAAO;AAAA,UACjB,UAAU;AAAA,UACV,QAAQ,SAAS,UAAU;AAAA,QAC7B,CAAC;AAAA,MACH;AACA,aAAO,KAAK,OAAO;AAAA,QACjB,oBAAoB;AAAA,UAClB;AAAA,UACA,oBAAoB;AAAA,UACpB,0BAA0B,SAAS,UAAU;AAAA,QAC/C;AAAA,MACF,CAAC;AAAA,IACH;AAGA,QAAI,aAAa,OAAO;AACtB,aAAO,KAAK,OAAO;AAAA,QACjB,oBAAoB;AAAA,UAClB;AAAA,UACA,oBAAoB;AAAA,UACpB,0BACE,SAAS,UAAU;AAAA,QACvB;AAAA,MACF,CAAC;AAAA,IACH;AAOA,QAAI,aAAa,aAAa,SAAS,mBAAmB;AACxD,aAAO,KAAK,OAAO;AAAA,QACjB,oBAAoB,EAAE,eAAe,mBAAmB,SAAS,kBAAkB;AAAA,MACrF,CAAC;AAAA,IACH;AAGA,WAAO,EAAE,UAAU,EAAE;AAAA,EACvB;AAAA,EAEQ,OAAO,SAA6B;AAC1C,WAAO,EAAE,UAAU,GAAG,QAAQ,KAAK,UAAU,OAAO,EAAE;AAAA,EACxD;AACF;AAOA,SAAS,iBAAiB,OAAmC;AAC3D,MAAI,OAAO,MAAM,oBAAoB,UAAU;AAC7C,UAAM,IAAI,MAAM,gBAAgB,MAAM,yBAAyB;AAC/D,QAAI,KAAK,EAAE,CAAC,EAAG,QAAO,EAAE,CAAC;AAAA,EAC3B;AACA,MAAI,OAAO,MAAM,eAAe,YAAY,MAAM,eAAe,IAAI;AACnE,WAAO,MAAM;AAAA,EACf;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,OAAoC;AAChE,MAAI,SAAS,KAAM,QAAO;AAC1B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B,QAAQ;AACN,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAEO,IAAM,UAAU,IAAI,wBAAwB;AACnD,IAAO,4BAAQ;","names":[]}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveEnvRefsDeep
|
|
4
|
+
} from "./chunk-BEFVJ2OE.js";
|
|
5
|
+
import {
|
|
6
|
+
BaseAdapter
|
|
7
|
+
} from "./chunk-VVFDU4IX.js";
|
|
8
|
+
import {
|
|
9
|
+
buildWrappedStdio
|
|
10
|
+
} from "./chunk-HORHRHNG.js";
|
|
11
|
+
import "./chunk-YYNXIUR2.js";
|
|
12
|
+
import "./chunk-IXOQDZWC.js";
|
|
13
|
+
|
|
14
|
+
// src/adapters/junie/index.ts
|
|
15
|
+
import { existsSync } from "fs";
|
|
16
|
+
import { homedir } from "os";
|
|
17
|
+
import { join } from "path";
|
|
18
|
+
var HOST = "junie";
|
|
19
|
+
var MCP_ROOT_KEY = "mcpServers";
|
|
20
|
+
var JunieAdapter = class extends BaseAdapter {
|
|
21
|
+
id = HOST;
|
|
22
|
+
name = "Junie";
|
|
23
|
+
paradigm = "mcp-only";
|
|
24
|
+
capabilities = {
|
|
25
|
+
// Memory surface: BaseAdapter AGENTS.md-first default. Junie documents its
|
|
26
|
+
// own guidelines/memory surface; AC's AGENTS.md default lands in the open
|
|
27
|
+
// standard file Junie also reads. (Junie-specific guideline files are not
|
|
28
|
+
// wired here — the AGENTS.md default is the host-agnostic baseline.)
|
|
29
|
+
supportsMemory: true,
|
|
30
|
+
//
|
|
31
|
+
// mcp-only: Junie documents NO user-installable lifecycle hook / event-
|
|
32
|
+
// callback surface (junie.jetbrains.com/docs). Every hook flag is false.
|
|
33
|
+
preToolUse: false,
|
|
34
|
+
postToolUse: false,
|
|
35
|
+
preCompact: false,
|
|
36
|
+
sessionStart: false,
|
|
37
|
+
sessionEnd: false,
|
|
38
|
+
userPromptSubmit: false,
|
|
39
|
+
stop: false,
|
|
40
|
+
notification: false,
|
|
41
|
+
// No hook layer → no arg/output rewrite, no context injection.
|
|
42
|
+
canModifyArgs: false,
|
|
43
|
+
canModifyOutput: false,
|
|
44
|
+
canInjectSessionContext: false,
|
|
45
|
+
// Junie registers stdio MCP servers (Local: Docker/npx/binary) and remote
|
|
46
|
+
// (HTTP/HTTPS) servers — the remote entry is distinguished by `url` (vs
|
|
47
|
+
// stdio's `command`).
|
|
48
|
+
transports: ["stdio", "http"]
|
|
49
|
+
// Content surfaces (Agent Skills, subagents, custom slash commands) exist
|
|
50
|
+
// natively in Junie but are NOT wired by this adapter — the initial scope is
|
|
51
|
+
// MCP-only. They stay UNSET so the base skip-warns; this is an honest
|
|
52
|
+
// CEILING, not a host gap.
|
|
53
|
+
};
|
|
54
|
+
// ── Detection ────────────────────────────────────────────────────────────
|
|
55
|
+
detectInstalled(projectDir) {
|
|
56
|
+
const userDir = join(homedir(), ".junie");
|
|
57
|
+
const userMcp = join(userDir, "mcp", "mcp.json");
|
|
58
|
+
const projectDirJunie = join(projectDir, ".junie");
|
|
59
|
+
const installed = existsSync(userDir) || existsSync(projectDirJunie);
|
|
60
|
+
return {
|
|
61
|
+
id: this.id,
|
|
62
|
+
name: this.name,
|
|
63
|
+
installed,
|
|
64
|
+
paradigm: this.paradigm,
|
|
65
|
+
capabilities: this.capabilities,
|
|
66
|
+
configPath: userMcp,
|
|
67
|
+
scope: "user",
|
|
68
|
+
reason: installed ? `found Junie config under ${userDir}` : `no Junie config at ${userDir}`,
|
|
69
|
+
confidence: installed ? "high" : "low"
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// ── Native paths ─────────────────────────────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Junie's MCP config dir is `<scope-root>/.junie/mcp`: project scope at
|
|
75
|
+
* <projectDir>/.junie/mcp, user scope at ~/.junie/mcp (BYTE-CONFIRMED —
|
|
76
|
+
* junie.jetbrains.com/docs/junie-cli-mcp-configuration.html).
|
|
77
|
+
*/
|
|
78
|
+
getConfigDir(ctx) {
|
|
79
|
+
return ctx.scope === "project" ? join(ctx.projectDir, ".junie", "mcp") : join(homedir(), ".junie", "mcp");
|
|
80
|
+
}
|
|
81
|
+
getServerConfigPath(ctx) {
|
|
82
|
+
return join(this.getConfigDir(ctx), "mcp.json");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Junie has no separate hook file — the hook config path aliases the MCP file
|
|
86
|
+
* so the generic doctor/backup helpers behave sensibly (windsurf/cline idiom).
|
|
87
|
+
*/
|
|
88
|
+
getHookConfigPath(ctx) {
|
|
89
|
+
return this.getServerConfigPath(ctx);
|
|
90
|
+
}
|
|
91
|
+
// ── MCP server install / uninstall ───────────────────────────────────────
|
|
92
|
+
installServer(ctx) {
|
|
93
|
+
const { connector } = ctx;
|
|
94
|
+
const override = connector.platforms[HOST]?.server;
|
|
95
|
+
if (!connector.server || override === false) {
|
|
96
|
+
return [
|
|
97
|
+
{
|
|
98
|
+
platform: this.id,
|
|
99
|
+
action: "skip",
|
|
100
|
+
detail: connector.server ? "server registration disabled for junie" : "connector declares no MCP server"
|
|
101
|
+
}
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
|
|
105
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
106
|
+
const malformed = this.malformedRootKey(serverPath);
|
|
107
|
+
if (malformed) return [malformed];
|
|
108
|
+
const entry = this.renderServerEntry(ctx, server);
|
|
109
|
+
return [
|
|
110
|
+
this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
|
|
111
|
+
];
|
|
112
|
+
}
|
|
113
|
+
uninstallServer(ctx) {
|
|
114
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
115
|
+
const malformed = this.malformedRootKey(serverPath);
|
|
116
|
+
if (malformed) return [malformed];
|
|
117
|
+
return [
|
|
118
|
+
this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Guard for a PRESENT-but-non-object `mcpServers` root key: returns a
|
|
123
|
+
* skip-warn ChangeRecord when the existing config parses but its `mcpServers`
|
|
124
|
+
* value is not a plain object (an array / string / number / null). Returns
|
|
125
|
+
* undefined when the file is absent, unparseable (the base upsert's own
|
|
126
|
+
* overwrite guard handles that), or `mcpServers` is absent / a plain object.
|
|
127
|
+
*/
|
|
128
|
+
malformedRootKey(configPath) {
|
|
129
|
+
const cfg = this.readJson(configPath);
|
|
130
|
+
if (!cfg || !(MCP_ROOT_KEY in cfg)) return void 0;
|
|
131
|
+
const root = cfg[MCP_ROOT_KEY];
|
|
132
|
+
if (root !== null && typeof root === "object" && !Array.isArray(root)) {
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
platform: this.id,
|
|
137
|
+
action: "warn",
|
|
138
|
+
path: configPath,
|
|
139
|
+
detail: `existing ${MCP_ROOT_KEY} in ${configPath} is not an object map; left untouched (back it up / fix it, then re-run)`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/** Render a normalized ServerDef into Junie's native mcpServers entry. */
|
|
143
|
+
renderServerEntry(ctx, server) {
|
|
144
|
+
const transport = server.transport;
|
|
145
|
+
if (transport === "stdio") {
|
|
146
|
+
let command = server.command ?? "";
|
|
147
|
+
let args = [...server.args ?? []];
|
|
148
|
+
({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));
|
|
149
|
+
const entry2 = {
|
|
150
|
+
command: resolveEnvRefsDeep(command)
|
|
151
|
+
};
|
|
152
|
+
if (args.length > 0) entry2.args = resolveEnvRefsDeep(args);
|
|
153
|
+
const env = this.renderEnv(server.env);
|
|
154
|
+
if (env) entry2.env = env;
|
|
155
|
+
return entry2;
|
|
156
|
+
}
|
|
157
|
+
const entry = {
|
|
158
|
+
url: resolveEnvRefsDeep(server.url ?? "")
|
|
159
|
+
};
|
|
160
|
+
const headers = this.renderEnv(server.headers);
|
|
161
|
+
if (headers) entry.headers = headers;
|
|
162
|
+
return entry;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Render env/header values. Junie documents no native interpolation token, so
|
|
166
|
+
* resolve `${env:VAR}` references to literals at install time.
|
|
167
|
+
*/
|
|
168
|
+
renderEnv(env) {
|
|
169
|
+
if (!env || Object.keys(env).length === 0) return void 0;
|
|
170
|
+
return resolveEnvRefsDeep({ ...env });
|
|
171
|
+
}
|
|
172
|
+
// ── Hooks (unavailable — Junie is mcp-only) ──────────────────────────────
|
|
173
|
+
installHooks(_ctx) {
|
|
174
|
+
return [
|
|
175
|
+
{
|
|
176
|
+
platform: this.id,
|
|
177
|
+
action: "skip",
|
|
178
|
+
detail: "hooks unavailable (Junie is mcp-only)"
|
|
179
|
+
}
|
|
180
|
+
];
|
|
181
|
+
}
|
|
182
|
+
uninstallHooks(_ctx) {
|
|
183
|
+
return [
|
|
184
|
+
{
|
|
185
|
+
platform: this.id,
|
|
186
|
+
action: "skip",
|
|
187
|
+
detail: "hooks unavailable (Junie is mcp-only)"
|
|
188
|
+
}
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
// ── Diagnostics ──────────────────────────────────────────────────────────
|
|
192
|
+
getHealthChecks(ctx) {
|
|
193
|
+
const mcpPath = this.getServerConfigPath(ctx);
|
|
194
|
+
const connectorId = ctx.connector.id;
|
|
195
|
+
return [
|
|
196
|
+
{
|
|
197
|
+
name: `${this.name}: mcp.json present`,
|
|
198
|
+
check: () => existsSync(mcpPath) ? { status: "OK", detail: mcpPath } : { status: "FAIL", detail: `not found: ${mcpPath}` }
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
name: `${this.name}: server entry registered`,
|
|
202
|
+
check: () => {
|
|
203
|
+
if (!ctx.connector.server) {
|
|
204
|
+
return { status: "OK", detail: "no MCP server declared" };
|
|
205
|
+
}
|
|
206
|
+
const cfg = this.readJson(mcpPath);
|
|
207
|
+
const bucket = cfg?.[MCP_ROOT_KEY];
|
|
208
|
+
if (!cfg || !bucket) {
|
|
209
|
+
return { status: "FAIL", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };
|
|
210
|
+
}
|
|
211
|
+
return connectorId in bucket ? { status: "OK", detail: `${MCP_ROOT_KEY}.${connectorId} present` } : {
|
|
212
|
+
status: "FAIL",
|
|
213
|
+
detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${mcpPath}`
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
];
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
var adapter = new JunieAdapter();
|
|
221
|
+
var junie_default = adapter;
|
|
222
|
+
export {
|
|
223
|
+
JunieAdapter,
|
|
224
|
+
adapter,
|
|
225
|
+
junie_default as default
|
|
226
|
+
};
|
|
227
|
+
//# sourceMappingURL=junie-SQ4SDLGK.js.map
|