@ken-jo/agent-connector 0.3.1 → 0.4.1
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 +180 -16
- package/dist/action-WT7GVRCC.js +55 -0
- package/dist/action-WT7GVRCC.js.map +1 -0
- package/dist/amazon-q-COAL3764.js +276 -0
- package/dist/amazon-q-COAL3764.js.map +1 -0
- package/dist/{amp-YGV66GJT.js → amp-4U33CU7E.js} +81 -5
- package/dist/amp-4U33CU7E.js.map +1 -0
- package/dist/{antigravity-7IBYFO6P.js → antigravity-AMKKKHS4.js} +4 -4
- package/dist/{antigravity-cli-JEOUP2VN.js → antigravity-cli-XERXEH5W.js} +4 -4
- package/dist/{chunk-3JCRUROU.js → chunk-24IDL5RW.js} +13 -4
- package/dist/chunk-24IDL5RW.js.map +1 -0
- package/dist/chunk-2AVLX7GH.js +351 -0
- package/dist/chunk-2AVLX7GH.js.map +1 -0
- package/dist/{chunk-GSGDG2BV.js → chunk-4ENJK5S2.js} +106 -176
- package/dist/chunk-4ENJK5S2.js.map +1 -0
- package/dist/{chunk-ZAM4M7LI.js → chunk-5OWS5CMA.js} +136 -296
- package/dist/chunk-5OWS5CMA.js.map +1 -0
- package/dist/{chunk-PD4VFEBY.js → chunk-CPLK7GTE.js} +79 -5
- package/dist/chunk-CPLK7GTE.js.map +1 -0
- package/dist/chunk-DCKFYWGM.js +237 -0
- package/dist/chunk-DCKFYWGM.js.map +1 -0
- package/dist/chunk-EGCBZ2DC.js +83 -0
- package/dist/chunk-EGCBZ2DC.js.map +1 -0
- package/dist/chunk-F5RX62T7.js +21 -0
- package/dist/chunk-F5RX62T7.js.map +1 -0
- package/dist/chunk-FAHIMJRU.js +177 -0
- package/dist/chunk-FAHIMJRU.js.map +1 -0
- package/dist/{chunk-MEH7GC7R.js → chunk-I5MLE6S7.js} +33 -3
- package/dist/chunk-I5MLE6S7.js.map +1 -0
- package/dist/{chunk-KVAAFYRR.js → chunk-KHO5WNTP.js} +2 -18
- package/dist/chunk-KHO5WNTP.js.map +1 -0
- package/dist/{chunk-KQSNDFBN.js → chunk-LQRAPXS4.js} +3 -3
- package/dist/{chunk-3RBLIHPZ.js → chunk-O5TWCIJN.js} +27 -17
- package/dist/chunk-O5TWCIJN.js.map +1 -0
- package/dist/{chunk-WNREHWKL.js → chunk-QREL7LZJ.js} +5 -4
- package/dist/chunk-QREL7LZJ.js.map +1 -0
- package/dist/{chunk-KMAKDD3Z.js → chunk-RIMVWCZY.js} +37 -12
- package/dist/chunk-RIMVWCZY.js.map +1 -0
- package/dist/{openclaw-UZ5BMCGQ.js → chunk-URHQMFB3.js} +210 -41
- package/dist/chunk-URHQMFB3.js.map +1 -0
- package/dist/chunk-WZA4CSGJ.js +28 -0
- package/dist/chunk-WZA4CSGJ.js.map +1 -0
- package/dist/chunk-XJ4S47CT.js +44 -0
- package/dist/chunk-XJ4S47CT.js.map +1 -0
- package/dist/{claude-code-4275HQU4.js → claude-code-W4PUFZL5.js} +194 -52
- package/dist/claude-code-W4PUFZL5.js.map +1 -0
- package/dist/cli/sdk.js +5 -3
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cline-WRYMNS7Z.js +442 -0
- package/dist/cline-WRYMNS7Z.js.map +1 -0
- package/dist/{codebuff-LE3KBZGM.js → codebuff-DH5Y7GAT.js} +106 -5
- package/dist/codebuff-DH5Y7GAT.js.map +1 -0
- package/dist/{codex-4BY2ZJIW.js → codex-DDHIV767.js} +43 -11
- package/dist/codex-DDHIV767.js.map +1 -0
- package/dist/continue-K43SUHLQ.js +790 -0
- package/dist/continue-K43SUHLQ.js.map +1 -0
- package/dist/{copilot-cli-IPISKO3V.js → copilot-cli-Q3SSPT4V.js} +70 -12
- package/dist/copilot-cli-Q3SSPT4V.js.map +1 -0
- package/dist/{crush-X3E25EQG.js → crush-MBEH2R3I.js} +130 -6
- package/dist/crush-MBEH2R3I.js.map +1 -0
- package/dist/{cursor-UH3W622V.js → cursor-TMBXDYR4.js} +119 -16
- package/dist/cursor-TMBXDYR4.js.map +1 -0
- package/dist/{detect-U3E7NVNW.js → detect-KG5FG3EV.js} +5 -3
- package/dist/{detect-U3E7NVNW.js.map → detect-KG5FG3EV.js.map} +1 -1
- package/dist/{doctor-DZTWED4O.js → doctor-FLZF34Y3.js} +226 -96
- package/dist/doctor-FLZF34Y3.js.map +1 -0
- package/dist/{droid-T5VBRXZF.js → droid-JC2NT6S4.js} +298 -10
- package/dist/droid-JC2NT6S4.js.map +1 -0
- package/dist/{gemini-cli-ZSUK55UA.js → gemini-cli-ILR7M5X3.js} +62 -10
- package/dist/gemini-cli-ILR7M5X3.js.map +1 -0
- package/dist/{goose-M3RR3CZG.js → goose-SFO5BBGW.js} +112 -10
- package/dist/goose-SFO5BBGW.js.map +1 -0
- package/dist/{hermes-CUNKIAR5.js → hermes-3N7WN4WS.js} +329 -15
- package/dist/hermes-3N7WN4WS.js.map +1 -0
- package/dist/{hook-EVY7LOUQ.js → hook-XR3Z45FB.js} +16 -10
- package/dist/hook-XR3Z45FB.js.map +1 -0
- package/dist/index.d.ts +71 -3
- package/dist/index.js +23 -3
- package/dist/{install-OWAS5UIE.js → install-BSR62UHJ.js} +12 -9
- package/dist/{install-OWAS5UIE.js.map → install-BSR62UHJ.js.map} +1 -1
- package/dist/introspect-Nw8hTReX.d.ts +53 -0
- package/dist/{jetbrains-copilot-C3HDGGML.js → jetbrains-copilot-NRZHI5PC.js} +85 -18
- package/dist/jetbrains-copilot-NRZHI5PC.js.map +1 -0
- package/dist/{kilo-PKAJCWPX.js → kilo-5NWOXVSD.js} +16 -16
- package/dist/kilo-5NWOXVSD.js.map +1 -0
- package/dist/{kilo-cli-QWUVXG2O.js → kilo-cli-UZ7R5UOP.js} +3 -3
- package/dist/{kimi-EVD7YKXS.js → kimi-2YFK2GBA.js} +87 -25
- package/dist/kimi-2YFK2GBA.js.map +1 -0
- package/dist/{kiro-UQRY6EIO.js → kiro-YL6AWUYG.js} +3 -3
- package/dist/{leaderboard-CSWHI4UY.js → leaderboard-MJG24O35.js} +2 -2
- package/dist/mimo-code-FTMGSKMQ.js +790 -0
- package/dist/mimo-code-FTMGSKMQ.js.map +1 -0
- package/dist/{mux-5CI5FP2W.js → mux-5XZFB44C.js} +156 -6
- package/dist/mux-5XZFB44C.js.map +1 -0
- package/dist/nemoclaw-W5KEJ3WX.js +58 -0
- package/dist/nemoclaw-W5KEJ3WX.js.map +1 -0
- package/dist/{omp-AXA7XY22.js → omp-2QMEY6HD.js} +138 -18
- package/dist/omp-2QMEY6HD.js.map +1 -0
- package/dist/openclaw-EXJEFNZI.js +18 -0
- package/dist/openclaw-EXJEFNZI.js.map +1 -0
- package/dist/{opencode-NZBRLJN3.js → opencode-WNXYJR4X.js} +84 -27
- package/dist/opencode-WNXYJR4X.js.map +1 -0
- package/dist/{package-WFOS4QVU.js → package-ACZXJHWB.js} +8 -6
- package/dist/{package-WFOS4QVU.js.map → package-ACZXJHWB.js.map} +1 -1
- package/dist/{pi-WMTUX6ES.js → pi-PVVPVWKG.js} +3 -2
- package/dist/{pi-WMTUX6ES.js.map → pi-PVVPVWKG.js.map} +1 -1
- package/dist/{qwen-code-MRRIUQ3P.js → qwen-code-G4CXKUHR.js} +426 -10
- package/dist/qwen-code-G4CXKUHR.js.map +1 -0
- package/dist/{roo-code-NI5UU6JB.js → roo-code-67TYJIQR.js} +137 -4
- package/dist/roo-code-67TYJIQR.js.map +1 -0
- package/dist/runtime/index.d.ts +96 -2
- package/dist/runtime/index.js +19 -10
- package/dist/sdk/index.d.ts +52 -0
- package/dist/sdk/index.js +82 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/test.d.ts +74 -0
- package/dist/sdk/test.js +292 -0
- package/dist/sdk/test.js.map +1 -0
- package/dist/{serve-3C2VFPAY.js → serve-GER7URPR.js} +13 -9
- package/dist/{serve-3C2VFPAY.js.map → serve-GER7URPR.js.map} +1 -1
- package/dist/{status-MKQYX5MW.js → status-LAJE3BM5.js} +10 -7
- package/dist/{status-MKQYX5MW.js.map → status-LAJE3BM5.js.map} +1 -1
- package/dist/statusline-L376ZPZU.js +60 -0
- package/dist/statusline-L376ZPZU.js.map +1 -0
- package/dist/{telemetry-3DN6XGYB.js → telemetry-B3DX3PWU.js} +6 -4
- package/dist/{telemetry-3DN6XGYB.js.map → telemetry-B3DX3PWU.js.map} +1 -1
- package/dist/{trae-CQC72RHH.js → trae-7CZZGOGI.js} +99 -5
- package/dist/trae-7CZZGOGI.js.map +1 -0
- package/dist/{types-CNigfEuR.d.ts → types-CRVrFWeU.d.ts} +322 -18
- package/dist/{uninstall-WG6PFWF3.js → uninstall-ZYTW7YMZ.js} +12 -9
- package/dist/{uninstall-WG6PFWF3.js.map → uninstall-ZYTW7YMZ.js.map} +1 -1
- package/dist/{upgrade-32NC2RKI.js → upgrade-4LUEEOZW.js} +12 -9
- package/dist/{upgrade-32NC2RKI.js.map → upgrade-4LUEEOZW.js.map} +1 -1
- package/dist/{usage-CJOM2WQM.js → usage-ZFBVQF3H.js} +2 -2
- package/dist/{usage-event-472X3DOY.js → usage-event-GZ32AGEB.js} +12 -8
- package/dist/{usage-event-472X3DOY.js.map → usage-event-GZ32AGEB.js.map} +1 -1
- package/dist/{vscode-copilot-4RVRTCKV.js → vscode-copilot-MF2CDNMT.js} +23 -10
- package/dist/vscode-copilot-MF2CDNMT.js.map +1 -0
- package/dist/{warp-X6MB67NT.js → warp-VKG55TAT.js} +55 -4
- package/dist/warp-VKG55TAT.js.map +1 -0
- package/dist/windsurf-FU5G4SHF.js +443 -0
- package/dist/windsurf-FU5G4SHF.js.map +1 -0
- package/dist/{zed-NTCYW4V2.js → zed-SFUHL3GS.js} +3 -3
- package/package.json +10 -2
- package/dist/amp-YGV66GJT.js.map +0 -1
- package/dist/chunk-3JCRUROU.js.map +0 -1
- package/dist/chunk-3RBLIHPZ.js.map +0 -1
- package/dist/chunk-GSGDG2BV.js.map +0 -1
- package/dist/chunk-KMAKDD3Z.js.map +0 -1
- package/dist/chunk-KVAAFYRR.js.map +0 -1
- package/dist/chunk-MEH7GC7R.js.map +0 -1
- package/dist/chunk-NJU275US.js +0 -238
- package/dist/chunk-NJU275US.js.map +0 -1
- package/dist/chunk-PD4VFEBY.js.map +0 -1
- package/dist/chunk-WNREHWKL.js.map +0 -1
- package/dist/chunk-ZAM4M7LI.js.map +0 -1
- package/dist/claude-code-4275HQU4.js.map +0 -1
- package/dist/codebuff-LE3KBZGM.js.map +0 -1
- package/dist/codex-4BY2ZJIW.js.map +0 -1
- package/dist/copilot-cli-IPISKO3V.js.map +0 -1
- package/dist/crush-X3E25EQG.js.map +0 -1
- package/dist/cursor-UH3W622V.js.map +0 -1
- package/dist/doctor-DZTWED4O.js.map +0 -1
- package/dist/droid-T5VBRXZF.js.map +0 -1
- package/dist/gemini-cli-ZSUK55UA.js.map +0 -1
- package/dist/goose-M3RR3CZG.js.map +0 -1
- package/dist/hermes-CUNKIAR5.js.map +0 -1
- package/dist/hook-EVY7LOUQ.js.map +0 -1
- package/dist/jetbrains-copilot-C3HDGGML.js.map +0 -1
- package/dist/kilo-PKAJCWPX.js.map +0 -1
- package/dist/kimi-EVD7YKXS.js.map +0 -1
- package/dist/mux-5CI5FP2W.js.map +0 -1
- package/dist/omp-AXA7XY22.js.map +0 -1
- package/dist/openclaw-UZ5BMCGQ.js.map +0 -1
- package/dist/opencode-NZBRLJN3.js.map +0 -1
- package/dist/qwen-code-MRRIUQ3P.js.map +0 -1
- package/dist/roo-code-NI5UU6JB.js.map +0 -1
- package/dist/trae-CQC72RHH.js.map +0 -1
- package/dist/vscode-copilot-4RVRTCKV.js.map +0 -1
- package/dist/warp-X6MB67NT.js.map +0 -1
- /package/dist/{antigravity-7IBYFO6P.js.map → antigravity-AMKKKHS4.js.map} +0 -0
- /package/dist/{antigravity-cli-JEOUP2VN.js.map → antigravity-cli-XERXEH5W.js.map} +0 -0
- /package/dist/{chunk-KQSNDFBN.js.map → chunk-LQRAPXS4.js.map} +0 -0
- /package/dist/{kilo-cli-QWUVXG2O.js.map → kilo-cli-UZ7R5UOP.js.map} +0 -0
- /package/dist/{kiro-UQRY6EIO.js.map → kiro-YL6AWUYG.js.map} +0 -0
- /package/dist/{leaderboard-CSWHI4UY.js.map → leaderboard-MJG24O35.js.map} +0 -0
- /package/dist/{usage-CJOM2WQM.js.map → usage-ZFBVQF3H.js.map} +0 -0
- /package/dist/{zed-NTCYW4V2.js.map → zed-SFUHL3GS.js.map} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/adapters/claude-code/wire.ts
|
|
4
|
+
function extractSessionId(input) {
|
|
5
|
+
if (typeof input.transcript_path === "string") {
|
|
6
|
+
const m = input.transcript_path.match(/([a-f0-9-]{36})\.jsonl$/);
|
|
7
|
+
if (m && m[1]) return m[1];
|
|
8
|
+
}
|
|
9
|
+
if (typeof input.session_id === "string" && input.session_id !== "") {
|
|
10
|
+
return input.session_id;
|
|
11
|
+
}
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
function toolResponseToString(value) {
|
|
15
|
+
if (value == null) return void 0;
|
|
16
|
+
if (typeof value === "string") return value;
|
|
17
|
+
try {
|
|
18
|
+
return JSON.stringify(value);
|
|
19
|
+
} catch {
|
|
20
|
+
return String(value);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export {
|
|
25
|
+
extractSessionId,
|
|
26
|
+
toolResponseToString
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=chunk-WZA4CSGJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/claude-code/wire.ts"],"sourcesContent":["/**\n * adapters/claude-code/wire — Claude Code hook wire protocol.\n *\n * Claude Code pipes a JSON object to a hook command on stdin and reads a JSON\n * object (or empty) from stdout, interpreting the exit code as well. This module\n * captures the exact stdin shape and the canonical reply shape so the adapter's\n * parse/format methods are a single source of truth.\n *\n * Stdin (documented Claude Code hook input):\n * {\n * session_id, transcript_path, cwd, hook_event_name,\n * tool_name, tool_input, tool_response, // tool events\n * permission_suggestions, // PermissionRequest\n * tool_use_id, error, is_interrupt, duration_ms, // PostToolUseFailure\n * agent_id, agent_type, // SubagentStart/Stop\n * agent_transcript_path, last_assistant_message, // SubagentStop\n * source, // SessionStart\n * reason, // SessionEnd\n * prompt, // UserPromptSubmit\n * trigger, // PreCompact\n * stop_hook_active, // Stop / SubagentStop\n * message // Notification\n * }\n *\n * Stdout (canonical reply): a `hookSpecificOutput` object keyed by\n * `hookEventName`, carrying `permissionDecision` (allow|deny|ask) +\n * `permissionDecisionReason`, `additionalContext`, and (PreToolUse)\n * `updatedInput`; PermissionRequest instead takes a nested\n * `decision: { behavior: \"allow\"|\"deny\", ... }`; Stop-class blocks\n * (Stop / SubagentStop / UserPromptSubmit / PostToolUse) take the TOP-LEVEL\n * `{\"decision\":\"block\",\"reason\"}`. Exit 0 = proceed; the JSON refines the\n * decision.\n */\n\n/** Canonical Claude Code hook event names (the values of `hook_event_name`). */\nexport const CLAUDE_HOOK_EVENTS = [\n \"PreToolUse\",\n \"PostToolUse\",\n \"PreCompact\",\n \"SessionStart\",\n \"SessionEnd\",\n \"UserPromptSubmit\",\n \"Stop\",\n \"Notification\",\n \"PermissionRequest\",\n \"PostToolUseFailure\",\n \"SubagentStart\",\n \"SubagentStop\",\n] as const;\n\nexport type ClaudeHookEvent = (typeof CLAUDE_HOOK_EVENTS)[number];\n\n/**\n * Raw Claude Code hook stdin payload. Every field is optional — a given event\n * only populates the subset relevant to it. `connector` is NOT a Claude field;\n * it is threaded in by the universal entrypoint so parseEvent can recover the\n * connector id (the home binary passes `--connector <id>` and may inject it).\n */\nexport interface ClaudeWireInput {\n session_id?: string;\n transcript_path?: string;\n cwd?: string;\n hook_event_name?: string;\n\n // tool events\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n /** PostToolUse result payload (string or structured). */\n tool_response?: unknown;\n\n // PermissionRequest — permission-update entries the dialog would offer.\n // NOTE: the docs explicitly state PermissionRequest has NO tool_use_id.\n permission_suggestions?: unknown[];\n\n // PostToolUseFailure\n tool_use_id?: string;\n error?: string;\n is_interrupt?: boolean;\n duration_ms?: number;\n\n // SubagentStart / SubagentStop — agent_type is unreliable on SubagentStop\n // (the SDK may not populate it); treat both as optional everywhere.\n agent_id?: string;\n agent_type?: string;\n // SubagentStop — the subagent's OWN transcript (transcript_path stays the\n // parent session's) + the text of its final response.\n agent_transcript_path?: string;\n last_assistant_message?: string;\n\n // SessionStart\n source?: string;\n // SessionEnd\n reason?: string;\n // UserPromptSubmit\n prompt?: string;\n // PreCompact\n trigger?: string;\n // Stop / SubagentStop\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\n/**\n * Extract a stable session id from a Claude wire payload.\n * Priority mirrors the proven adapter: transcript UUID > session_id > \"\".\n * (The framework's normalized event uses \"\" when no id is available, per\n * core/types BaseEvent.sessionId docstring — no ppid fabrication here.)\n */\nexport function extractSessionId(input: ClaudeWireInput): 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 PostToolUse `tool_response` into a string for the normalized event. */\nexport function 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"],"mappings":";;;AAgHO,SAAS,iBAAiB,OAAgC;AAC/D,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;AAGO,SAAS,qBAAqB,OAAoC;AACvE,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;","names":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
allAdapters,
|
|
4
|
+
loadAdapter
|
|
5
|
+
} from "./chunk-DCKFYWGM.js";
|
|
6
|
+
|
|
7
|
+
// src/sdk/introspect.ts
|
|
8
|
+
var SURFACE_PREDICATES = {
|
|
9
|
+
server: (c) => c.transports.length > 0,
|
|
10
|
+
hooks: (c) => c.sessionStart || c.preToolUse || c.postToolUse || c.userPromptSubmit || c.stop || c.sessionEnd || c.preCompact || c.notification || (c.permissionRequest ?? false) || (c.postToolUseFailure ?? false) || (c.subagentStart ?? false) || (c.subagentStop ?? false),
|
|
11
|
+
commands: (c) => c.supportsCommands ?? false,
|
|
12
|
+
skills: (c) => c.supportsSkills ?? false,
|
|
13
|
+
subagents: (c) => c.supportsSubagents ?? false,
|
|
14
|
+
memory: (c) => c.supportsMemory ?? false,
|
|
15
|
+
statusline: (c) => c.supportsStatusline ?? false,
|
|
16
|
+
// Emitters ship on droid + hermes + warp plus the ts-plugin slash-command
|
|
17
|
+
// hosts omp + openclaw (+ the nemoclaw fork) — the hosts with a verifiable
|
|
18
|
+
// target. Every other host leaves supportsActions unset, so explain() marks
|
|
19
|
+
// actions skip-warn there — the honest state for a host with no emission target.
|
|
20
|
+
actions: (c) => c.supportsActions ?? false,
|
|
21
|
+
configPatch: (c) => c.supportsConfigPatch ?? false,
|
|
22
|
+
nativeHooks: (c) => c.supportsNativeHooks ?? false
|
|
23
|
+
};
|
|
24
|
+
async function capabilitiesOf(host) {
|
|
25
|
+
const adapter = await loadAdapter(host);
|
|
26
|
+
return adapter?.capabilities;
|
|
27
|
+
}
|
|
28
|
+
async function hostsSupporting(surface) {
|
|
29
|
+
const predicate = SURFACE_PREDICATES[surface];
|
|
30
|
+
const adapters = await allAdapters();
|
|
31
|
+
return adapters.filter((adapter) => predicate(adapter.capabilities)).map((adapter) => adapter.id).sort();
|
|
32
|
+
}
|
|
33
|
+
async function surfaceSupport(host, surface) {
|
|
34
|
+
const capabilities = await capabilitiesOf(host);
|
|
35
|
+
return capabilities ? SURFACE_PREDICATES[surface](capabilities) : false;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
SURFACE_PREDICATES,
|
|
40
|
+
capabilitiesOf,
|
|
41
|
+
hostsSupporting,
|
|
42
|
+
surfaceSupport
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=chunk-XJ4S47CT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sdk/introspect.ts"],"sourcesContent":["/**\n * sdk/introspect — host-capability introspection over the adapter registry.\n *\n * A thin, READ-ONLY query layer above {@link loadAdapter} / {@link allAdapters}:\n * \"which hosts can honor surface X?\" and \"what can host Y do?\". It exists so a\n * connector author (or a docs/CLI surface) can answer those questions WITHOUT\n * reaching into adapter internals or re-deriving the per-surface capability\n * rules — the predicates below are the single source of truth for mapping the\n * raw {@link PlatformCapabilities} flags onto the developer-facing surface names.\n *\n * Everything is async because adapters load lazily (one entry per platform in\n * the registry, imported only when queried).\n */\n\nimport type { PlatformCapabilities, PlatformId } from \"../core/types.js\";\nimport { allAdapters, loadAdapter } from \"../adapters/registry.js\";\n\n/**\n * The developer-facing surface names a connector can declare. These mirror the\n * top-level {@link import(\"../core/types.js\").ConnectorConfig} keys (server,\n * hooks, commands, …) plus the platform-scoped `configPatch` / `nativeHooks`\n * escape hatches — the same vocabulary the install diff and `explain` use.\n */\nexport type SurfaceName =\n | \"server\"\n | \"hooks\"\n | \"commands\"\n | \"skills\"\n | \"subagents\"\n | \"memory\"\n | \"statusline\"\n | \"actions\"\n | \"configPatch\"\n | \"nativeHooks\";\n\n/**\n * Pure capability predicate per surface — `true` when the host can NATIVELY\n * honor that surface. The optional capability flags are read as `?? false`\n * (the supportsCommands precedent in core/types), so a host that simply leaves\n * a flag unset reports the surface as unsupported (the installer skip-warns it).\n *\n * `hooks` is satisfied by ANY normalized hook event (i.e. the host has at least\n * one event it can dispatch); the per-event flags map 1:1 onto the\n * {@link import(\"../core/types.js\").HookEventName} union.\n */\nexport const SURFACE_PREDICATES: Record<\n SurfaceName,\n (c: PlatformCapabilities) => boolean\n> = {\n server: (c) => c.transports.length > 0,\n hooks: (c) =>\n c.sessionStart ||\n c.preToolUse ||\n c.postToolUse ||\n c.userPromptSubmit ||\n c.stop ||\n c.sessionEnd ||\n c.preCompact ||\n c.notification ||\n (c.permissionRequest ?? false) ||\n (c.postToolUseFailure ?? false) ||\n (c.subagentStart ?? false) ||\n (c.subagentStop ?? false),\n commands: (c) => c.supportsCommands ?? false,\n skills: (c) => c.supportsSkills ?? false,\n subagents: (c) => c.supportsSubagents ?? false,\n memory: (c) => c.supportsMemory ?? false,\n statusline: (c) => c.supportsStatusline ?? false,\n // Emitters ship on droid + hermes + warp plus the ts-plugin slash-command\n // hosts omp + openclaw (+ the nemoclaw fork) — the hosts with a verifiable\n // target. Every other host leaves supportsActions unset, so explain() marks\n // actions skip-warn there — the honest state for a host with no emission target.\n actions: (c) => c.supportsActions ?? false,\n configPatch: (c) => c.supportsConfigPatch ?? false,\n nativeHooks: (c) => c.supportsNativeHooks ?? false,\n};\n\n/**\n * The {@link PlatformCapabilities} a host advertises, or `undefined` for an id\n * that is not in the registry (`\"unknown\"`, a usage-only id like `\"synthetic\"`,\n * or a typo) — callers branch on undefined rather than crash.\n */\nexport async function capabilitiesOf(\n host: PlatformId | string,\n): Promise<PlatformCapabilities | undefined> {\n const adapter = await loadAdapter(host);\n return adapter?.capabilities;\n}\n\n/**\n * Every registered host that can NATIVELY honor `surface`, as a sorted id list\n * (stable output for snapshots/docs). Loads all adapters in parallel and keeps\n * only those whose capabilities pass {@link SURFACE_PREDICATES}.\n */\nexport async function hostsSupporting(surface: SurfaceName): Promise<PlatformId[]> {\n const predicate = SURFACE_PREDICATES[surface];\n const adapters = await allAdapters();\n return adapters\n .filter((adapter) => predicate(adapter.capabilities))\n .map((adapter) => adapter.id)\n .sort();\n}\n\n/**\n * Convenience: does `host` natively support `surface`? `false` for an unknown\n * id (no capabilities → cannot support anything).\n */\nexport async function surfaceSupport(\n host: PlatformId | string,\n surface: SurfaceName,\n): Promise<boolean> {\n const capabilities = await capabilitiesOf(host);\n return capabilities ? SURFACE_PREDICATES[surface](capabilities) : false;\n}\n"],"mappings":";;;;;;;AA6CO,IAAM,qBAGT;AAAA,EACF,QAAQ,CAAC,MAAM,EAAE,WAAW,SAAS;AAAA,EACrC,OAAO,CAAC,MACN,EAAE,gBACF,EAAE,cACF,EAAE,eACF,EAAE,oBACF,EAAE,QACF,EAAE,cACF,EAAE,cACF,EAAE,iBACD,EAAE,qBAAqB,WACvB,EAAE,sBAAsB,WACxB,EAAE,iBAAiB,WACnB,EAAE,gBAAgB;AAAA,EACrB,UAAU,CAAC,MAAM,EAAE,oBAAoB;AAAA,EACvC,QAAQ,CAAC,MAAM,EAAE,kBAAkB;AAAA,EACnC,WAAW,CAAC,MAAM,EAAE,qBAAqB;AAAA,EACzC,QAAQ,CAAC,MAAM,EAAE,kBAAkB;AAAA,EACnC,YAAY,CAAC,MAAM,EAAE,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA,EAK3C,SAAS,CAAC,MAAM,EAAE,mBAAmB;AAAA,EACrC,aAAa,CAAC,MAAM,EAAE,uBAAuB;AAAA,EAC7C,aAAa,CAAC,MAAM,EAAE,uBAAuB;AAC/C;AAOA,eAAsB,eACpB,MAC2C;AAC3C,QAAM,UAAU,MAAM,YAAY,IAAI;AACtC,SAAO,SAAS;AAClB;AAOA,eAAsB,gBAAgB,SAA6C;AACjF,QAAM,YAAY,mBAAmB,OAAO;AAC5C,QAAM,WAAW,MAAM,YAAY;AACnC,SAAO,SACJ,OAAO,CAAC,YAAY,UAAU,QAAQ,YAAY,CAAC,EACnD,IAAI,CAAC,YAAY,QAAQ,EAAE,EAC3B,KAAK;AACV;AAMA,eAAsB,eACpB,MACA,SACkB;AAClB,QAAM,eAAe,MAAM,eAAe,IAAI;AAC9C,SAAO,eAAe,mBAAmB,OAAO,EAAE,YAAY,IAAI;AACpE;","names":[]}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractSessionId,
|
|
4
|
+
toolResponseToString
|
|
5
|
+
} from "./chunk-WZA4CSGJ.js";
|
|
2
6
|
import {
|
|
3
7
|
readRegisteredMeta
|
|
4
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-24IDL5RW.js";
|
|
9
|
+
import "./chunk-4ENJK5S2.js";
|
|
10
|
+
import "./chunk-DCKFYWGM.js";
|
|
5
11
|
import {
|
|
6
12
|
addLedgerOwner,
|
|
7
13
|
configPatchManualEdit,
|
|
@@ -17,14 +23,14 @@ import {
|
|
|
17
23
|
loadConfigPatchLedger,
|
|
18
24
|
removeLedgerOwner,
|
|
19
25
|
saveConfigPatchLedger
|
|
20
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-FAHIMJRU.js";
|
|
21
27
|
import {
|
|
22
28
|
resolveEnvRefsDeep,
|
|
23
29
|
rewriteEnvRefs
|
|
24
30
|
} from "./chunk-DBQMX75U.js";
|
|
25
31
|
import {
|
|
26
32
|
BaseAdapter
|
|
27
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-CPLK7GTE.js";
|
|
28
34
|
import {
|
|
29
35
|
renderCommandMd,
|
|
30
36
|
renderSkillMd,
|
|
@@ -32,10 +38,12 @@ import {
|
|
|
32
38
|
} from "./chunk-7L6ITC4T.js";
|
|
33
39
|
import {
|
|
34
40
|
buildHomeBinHookCommand,
|
|
41
|
+
buildHomeBinStatuslineCommand,
|
|
35
42
|
buildServeWrapperCommand,
|
|
36
43
|
isHomeBinHookCommand,
|
|
44
|
+
isHomeBinStatuslineCommand,
|
|
37
45
|
shouldWrapForTelemetry
|
|
38
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-I5MLE6S7.js";
|
|
39
47
|
import {
|
|
40
48
|
linesOutsideFences,
|
|
41
49
|
listManagedBlocks,
|
|
@@ -55,31 +63,9 @@ import {
|
|
|
55
63
|
import { copyFileSync, existsSync, lstatSync, readFileSync, realpathSync } from "fs";
|
|
56
64
|
import { homedir } from "os";
|
|
57
65
|
import { basename, dirname, join } from "path";
|
|
58
|
-
|
|
59
|
-
// src/adapters/claude-code/wire.ts
|
|
60
|
-
function extractSessionId(input) {
|
|
61
|
-
if (typeof input.transcript_path === "string") {
|
|
62
|
-
const m = input.transcript_path.match(/([a-f0-9-]{36})\.jsonl$/);
|
|
63
|
-
if (m && m[1]) return m[1];
|
|
64
|
-
}
|
|
65
|
-
if (typeof input.session_id === "string" && input.session_id !== "") {
|
|
66
|
-
return input.session_id;
|
|
67
|
-
}
|
|
68
|
-
return "";
|
|
69
|
-
}
|
|
70
|
-
function toolResponseToString(value) {
|
|
71
|
-
if (value == null) return void 0;
|
|
72
|
-
if (typeof value === "string") return value;
|
|
73
|
-
try {
|
|
74
|
-
return JSON.stringify(value);
|
|
75
|
-
} catch {
|
|
76
|
-
return String(value);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// src/adapters/claude-code/index.ts
|
|
81
66
|
var HOST = "claude-code";
|
|
82
67
|
var MCP_ROOT_KEY = "mcpServers";
|
|
68
|
+
var STATUSLINE_KEY = "statusLine";
|
|
83
69
|
var CLAUDE_AGENTS_IMPORT_BLOCK_ID = "_shared/claude-agents-import";
|
|
84
70
|
var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
85
71
|
id = HOST;
|
|
@@ -112,6 +98,11 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
112
98
|
// (set-if-absent leaf keys in settings.json, refcounted ownership ledger,
|
|
113
99
|
// sensitive-key denylist — see SENSITIVE_KEY_RULES below).
|
|
114
100
|
supportsConfigPatch: true,
|
|
101
|
+
// Statusline surface: claude-code is the ONLY v1 host. installStatusline
|
|
102
|
+
// wires settings.json.statusLine = {type:"command", command:<home-bin
|
|
103
|
+
// statusline cmd>} through the SAME set-if-absent ownership ledger as
|
|
104
|
+
// configPatch (never clobbers a statusLine agent-connector does not own).
|
|
105
|
+
supportsStatusline: true,
|
|
115
106
|
transports: ["stdio", "http"],
|
|
116
107
|
// Content surfaces: Claude Code is the reference implementation for all three.
|
|
117
108
|
supportsCommands: true,
|
|
@@ -374,6 +365,20 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
374
365
|
{ platform: this.id, action: "skip", detail: "connector declares no configPatch entries" }
|
|
375
366
|
];
|
|
376
367
|
}
|
|
368
|
+
return this.applyConfigPatches(ctx, patches);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* The shared set-if-absent / ownership-ledger apply loop behind BOTH
|
|
372
|
+
* {@link installConfigPatches} and {@link installStatusline}. Routing the
|
|
373
|
+
* statusline through the EXACT same path is how a connector's statusLine
|
|
374
|
+
* inherits the configPatch contract verbatim: never clobber a statusLine
|
|
375
|
+
* agent-connector does not own (skip-warn), record prior state + owner,
|
|
376
|
+
* refcounted across connectors, reversible by uninstallConfigPatches.
|
|
377
|
+
*/
|
|
378
|
+
applyConfigPatches(ctx, patches, opts = {}) {
|
|
379
|
+
const surfaceLabel = opts.surfaceLabel ?? "configPatch";
|
|
380
|
+
const internal = surfaceLabel !== "configPatch";
|
|
381
|
+
const { connector } = ctx;
|
|
377
382
|
const filePath = this.getPatchableConfigPath(ctx);
|
|
378
383
|
if (this.isPresentButUnparseable(filePath)) {
|
|
379
384
|
return [
|
|
@@ -409,14 +414,16 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
409
414
|
});
|
|
410
415
|
continue;
|
|
411
416
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
417
|
+
if (!internal) {
|
|
418
|
+
const namespace = configPatchNamespaceViolation(patch.key);
|
|
419
|
+
if (namespace) {
|
|
420
|
+
changes.push({
|
|
421
|
+
platform: this.id,
|
|
422
|
+
action: "warn",
|
|
423
|
+
detail: `configPatch refused: ${namespace}`
|
|
424
|
+
});
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
420
427
|
}
|
|
421
428
|
const sensitive = claudeSensitiveKeyViolation(patch.key);
|
|
422
429
|
if (sensitive) {
|
|
@@ -436,7 +443,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
436
443
|
platform: this.id,
|
|
437
444
|
action: "warn",
|
|
438
445
|
path: filePath,
|
|
439
|
-
detail:
|
|
446
|
+
detail: `${surfaceLabel} ${patch.key} skipped: "${leaf.atPath}" exists but is not an object \u2014 ${configPatchManualEdit(patch)}`
|
|
440
447
|
});
|
|
441
448
|
continue;
|
|
442
449
|
}
|
|
@@ -462,7 +469,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
462
469
|
platform: this.id,
|
|
463
470
|
action: "create",
|
|
464
471
|
path: filePath,
|
|
465
|
-
detail:
|
|
472
|
+
detail: `${surfaceLabel} ${patch.key}: <absent> \u2192 ${describeJsonValue(desired)} (${patch.reason})`
|
|
466
473
|
});
|
|
467
474
|
continue;
|
|
468
475
|
}
|
|
@@ -471,7 +478,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
471
478
|
platform: this.id,
|
|
472
479
|
action: "warn",
|
|
473
480
|
path: filePath,
|
|
474
|
-
detail:
|
|
481
|
+
detail: `${surfaceLabel} ${patch.key} skipped: already set to ${describeJsonValue(leaf.value)} (not created by agent-connector; desired ${describeJsonValue(desired)}) \u2014 ` + configPatchManualEdit(patch)
|
|
475
482
|
});
|
|
476
483
|
continue;
|
|
477
484
|
}
|
|
@@ -480,7 +487,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
480
487
|
platform: this.id,
|
|
481
488
|
action: "warn",
|
|
482
489
|
path: filePath,
|
|
483
|
-
detail:
|
|
490
|
+
detail: `${surfaceLabel} ${patch.key}: value changed since install (current ${describeJsonValue(leaf.value)}, wrote ${describeJsonValue(entry.writtenValue)}); leaving in place \u2014 ${configPatchManualEdit(patch)}`
|
|
484
491
|
});
|
|
485
492
|
continue;
|
|
486
493
|
}
|
|
@@ -492,14 +499,14 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
492
499
|
platform: this.id,
|
|
493
500
|
action: "skip",
|
|
494
501
|
path: filePath,
|
|
495
|
-
detail:
|
|
502
|
+
detail: `${surfaceLabel} ${patch.key} already installed; registered as co-owner (co-owned with ${owners.join(", ")})`
|
|
496
503
|
});
|
|
497
504
|
} else {
|
|
498
505
|
changes.push({
|
|
499
506
|
platform: this.id,
|
|
500
507
|
action: "skip",
|
|
501
508
|
path: filePath,
|
|
502
|
-
detail:
|
|
509
|
+
detail: `${surfaceLabel} ${patch.key} already installed`
|
|
503
510
|
});
|
|
504
511
|
}
|
|
505
512
|
continue;
|
|
@@ -508,7 +515,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
508
515
|
platform: this.id,
|
|
509
516
|
action: "warn",
|
|
510
517
|
path: filePath,
|
|
511
|
-
detail:
|
|
518
|
+
detail: `${surfaceLabel} ${patch.key} skipped: already owned by ${entry.owners.map((o) => o.connectorId).join(", ")} with a different value (current ${describeJsonValue(leaf.value)}, desired ${describeJsonValue(desired)}) \u2014 ` + configPatchManualEdit(patch)
|
|
512
519
|
});
|
|
513
520
|
}
|
|
514
521
|
if (fileMutated) this.writeJson(filePath, settings, ctx.dryRun);
|
|
@@ -518,7 +525,9 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
518
525
|
uninstallConfigPatches(ctx) {
|
|
519
526
|
const connectorId = ctx.connector.id;
|
|
520
527
|
const ledger = loadConfigPatchLedger(ctx.dataRoot);
|
|
521
|
-
const owned = ledgerEntriesOwnedBy(ledger, HOST, connectorId)
|
|
528
|
+
const owned = ledgerEntriesOwnedBy(ledger, HOST, connectorId).filter(
|
|
529
|
+
(e) => e.key !== STATUSLINE_KEY
|
|
530
|
+
);
|
|
522
531
|
const declared = ctx.connector.platforms[HOST]?.configPatch ?? [];
|
|
523
532
|
const changes = [];
|
|
524
533
|
const ownedKeys = new Set(owned.map((e) => e.key));
|
|
@@ -532,6 +541,20 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
532
541
|
}
|
|
533
542
|
}
|
|
534
543
|
if (owned.length === 0) return changes;
|
|
544
|
+
changes.push(...this.releaseOwnedConfigPatches(ctx, ledger, owned));
|
|
545
|
+
return changes;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* The shared last-owner-verified release loop behind BOTH
|
|
549
|
+
* {@link uninstallConfigPatches} and {@link uninstallStatusline}: for each
|
|
550
|
+
* already-selected owned ledger entry, drop this connector's ownership and
|
|
551
|
+
* remove the key ONLY when last-owner ∧ value-unchanged ∧ prior-absent (else
|
|
552
|
+
* skip-warn + leave the key). Saves the ledger when it mutated.
|
|
553
|
+
*/
|
|
554
|
+
releaseOwnedConfigPatches(ctx, ledger, owned, opts = {}) {
|
|
555
|
+
const surfaceLabel = opts.surfaceLabel ?? "configPatch";
|
|
556
|
+
const connectorId = ctx.connector.id;
|
|
557
|
+
const changes = [];
|
|
535
558
|
let ledgerMutated = false;
|
|
536
559
|
const backedUp = /* @__PURE__ */ new Set();
|
|
537
560
|
const byFile = /* @__PURE__ */ new Map();
|
|
@@ -552,7 +575,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
552
575
|
platform: this.id,
|
|
553
576
|
action: "skip",
|
|
554
577
|
path: filePath,
|
|
555
|
-
detail:
|
|
578
|
+
detail: `${surfaceLabel} ${entry.key} retained: still owned by ${entry.owners.map((o) => o.connectorId).join(", ")}`
|
|
556
579
|
});
|
|
557
580
|
continue;
|
|
558
581
|
}
|
|
@@ -562,7 +585,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
562
585
|
platform: this.id,
|
|
563
586
|
action: "warn",
|
|
564
587
|
path: filePath,
|
|
565
|
-
detail:
|
|
588
|
+
detail: `${surfaceLabel} ${entry.key}: ${filePath} is not parseable; key left in place (ownership released)`
|
|
566
589
|
});
|
|
567
590
|
continue;
|
|
568
591
|
}
|
|
@@ -571,7 +594,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
571
594
|
platform: this.id,
|
|
572
595
|
action: "skip",
|
|
573
596
|
path: filePath,
|
|
574
|
-
detail:
|
|
597
|
+
detail: `${surfaceLabel} ${entry.key} already absent (no settings file); ownership record dropped`
|
|
575
598
|
});
|
|
576
599
|
continue;
|
|
577
600
|
}
|
|
@@ -581,7 +604,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
581
604
|
platform: this.id,
|
|
582
605
|
action: "skip",
|
|
583
606
|
path: filePath,
|
|
584
|
-
detail:
|
|
607
|
+
detail: `${surfaceLabel} ${entry.key} already absent; ownership record dropped`
|
|
585
608
|
});
|
|
586
609
|
continue;
|
|
587
610
|
}
|
|
@@ -590,7 +613,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
590
613
|
platform: this.id,
|
|
591
614
|
action: "warn",
|
|
592
615
|
path: filePath,
|
|
593
|
-
detail:
|
|
616
|
+
detail: `${surfaceLabel} ${entry.key}: value changed since install (current ${describeJsonValue(leaf.value)}, wrote ${describeJsonValue(entry.writtenValue)}); left in place`
|
|
594
617
|
});
|
|
595
618
|
continue;
|
|
596
619
|
}
|
|
@@ -612,7 +635,7 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
612
635
|
platform: this.id,
|
|
613
636
|
action: "remove",
|
|
614
637
|
path: filePath,
|
|
615
|
-
detail:
|
|
638
|
+
detail: `${surfaceLabel} ${entry.key} removed (was ${describeJsonValue(entry.writtenValue)})`
|
|
616
639
|
});
|
|
617
640
|
}
|
|
618
641
|
if (fileMutated && settings) this.writeJson(filePath, settings, ctx.dryRun);
|
|
@@ -620,6 +643,91 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
620
643
|
if (ledgerMutated && !ctx.dryRun) saveConfigPatchLedger(ctx.dataRoot, ledger);
|
|
621
644
|
return changes;
|
|
622
645
|
}
|
|
646
|
+
// ── Statusline surface (a HUD/status line) ────────────────────────────────
|
|
647
|
+
// Wires settings.json.statusLine = { type:"command", command:<home-bin
|
|
648
|
+
// statusline cmd> } through the SAME ownership ledger as configPatch: a
|
|
649
|
+
// synthetic ConfigPatchDef routed through applyConfigPatches, so the statusLine
|
|
650
|
+
// inherits the full set-if-absent contract verbatim — never clobbers a
|
|
651
|
+
// statusLine agent-connector does not own (skip-warn), records prior state +
|
|
652
|
+
// owner, reversible. The home-bin command makes the host exec
|
|
653
|
+
// `<homeBin> statusline claude-code --connector <id>` for every status refresh,
|
|
654
|
+
// which re-imports the connector module and renders the line (runtime/
|
|
655
|
+
// statusline-entrypoint). No telemetry in v1.
|
|
656
|
+
/** The synthetic statusLine configPatch this connector would write. */
|
|
657
|
+
statuslineConfigPatch(ctx) {
|
|
658
|
+
const command = buildHomeBinStatuslineCommand(ctx.homeBinPath, HOST, ctx.connector.id);
|
|
659
|
+
return {
|
|
660
|
+
key: STATUSLINE_KEY,
|
|
661
|
+
value: { type: "command", command },
|
|
662
|
+
reason: "agent-connector statusline surface"
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
installStatusline(ctx) {
|
|
666
|
+
const { connector } = ctx;
|
|
667
|
+
if (connector.statusline == null) {
|
|
668
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no statusline" }];
|
|
669
|
+
}
|
|
670
|
+
if (connector.platforms[HOST]?.statusline === false) {
|
|
671
|
+
return [{ platform: this.id, action: "skip", detail: "statusline disabled for claude-code" }];
|
|
672
|
+
}
|
|
673
|
+
return this.applyConfigPatches(ctx, [this.statuslineConfigPatch(ctx)], {
|
|
674
|
+
surfaceLabel: "statusline"
|
|
675
|
+
});
|
|
676
|
+
}
|
|
677
|
+
uninstallStatusline(ctx) {
|
|
678
|
+
const ledger = loadConfigPatchLedger(ctx.dataRoot);
|
|
679
|
+
const owned = ledgerEntriesOwnedBy(ledger, HOST, ctx.connector.id).filter(
|
|
680
|
+
(e) => e.key === STATUSLINE_KEY
|
|
681
|
+
);
|
|
682
|
+
if (owned.length === 0) {
|
|
683
|
+
return [
|
|
684
|
+
{
|
|
685
|
+
platform: this.id,
|
|
686
|
+
action: "skip",
|
|
687
|
+
detail: "statusline: no ownership recorded; left untouched"
|
|
688
|
+
}
|
|
689
|
+
];
|
|
690
|
+
}
|
|
691
|
+
return this.releaseOwnedConfigPatches(ctx, ledger, owned, {
|
|
692
|
+
surfaceLabel: "statusline"
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Parse Claude Code's statusLine stdin JSON into the normalized
|
|
697
|
+
* {@link StatuslineContext}. Claude pipes a JSON object to the statusLine
|
|
698
|
+
* command on stdin (model, workspace, cost, etc.); fields the payload omits
|
|
699
|
+
* stay undefined. `raw` keeps the verbatim payload (incl. `version`).
|
|
700
|
+
*/
|
|
701
|
+
parseStatusInput(raw) {
|
|
702
|
+
const input = raw ?? {};
|
|
703
|
+
const model = {};
|
|
704
|
+
if (typeof input.model?.id === "string") model.id = input.model.id;
|
|
705
|
+
if (typeof input.model?.display_name === "string") {
|
|
706
|
+
model.displayName = input.model.display_name;
|
|
707
|
+
}
|
|
708
|
+
const cwd = typeof input.cwd === "string" ? input.cwd : typeof input.workspace?.current_dir === "string" ? input.workspace.current_dir : void 0;
|
|
709
|
+
const ctx = {
|
|
710
|
+
host: HOST,
|
|
711
|
+
capabilities: this.capabilities,
|
|
712
|
+
raw
|
|
713
|
+
};
|
|
714
|
+
if (typeof input.session_id === "string" && input.session_id !== "") {
|
|
715
|
+
ctx.sessionId = input.session_id;
|
|
716
|
+
}
|
|
717
|
+
if (cwd !== void 0) ctx.cwd = cwd;
|
|
718
|
+
if (model.id !== void 0 || model.displayName !== void 0) ctx.model = model;
|
|
719
|
+
if (typeof input.cost?.total_cost_usd === "number") {
|
|
720
|
+
ctx.cost = { totalUsd: input.cost.total_cost_usd };
|
|
721
|
+
}
|
|
722
|
+
if (typeof input.transcript_path === "string") {
|
|
723
|
+
ctx.transcriptPath = input.transcript_path;
|
|
724
|
+
}
|
|
725
|
+
return ctx;
|
|
726
|
+
}
|
|
727
|
+
/** Format the rendered status line into Claude's native reply: stdout = line, exit 0. */
|
|
728
|
+
formatStatusOutput(rendered) {
|
|
729
|
+
return { exitCode: 0, stdout: rendered };
|
|
730
|
+
}
|
|
623
731
|
/**
|
|
624
732
|
* Back up ONE exact file (the ledger-recorded patch target, which may belong
|
|
625
733
|
* to a different scope than the current ctx) into the standard backups dir.
|
|
@@ -651,7 +759,9 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
651
759
|
const results = [];
|
|
652
760
|
const ledger = loadConfigPatchLedger(ctx.dataRoot);
|
|
653
761
|
const connectorId = ctx.connector.id;
|
|
654
|
-
const platformEntries = ledger.entries.filter(
|
|
762
|
+
const platformEntries = ledger.entries.filter(
|
|
763
|
+
(e) => e.platform === this.id && e.key !== STATUSLINE_KEY
|
|
764
|
+
);
|
|
655
765
|
for (const entry of platformEntries) {
|
|
656
766
|
const ownedByThis = entry.owners.some((o) => o.connectorId === connectorId);
|
|
657
767
|
if (!ownedByThis) {
|
|
@@ -678,7 +788,8 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
678
788
|
check: `${this.name}: configPatch ${entry.key}`,
|
|
679
789
|
status: "warn",
|
|
680
790
|
message: `missing \u2014 key deleted from ${entry.file} since install`,
|
|
681
|
-
fix: `agent-connector install (sync) will re-assert it
|
|
791
|
+
fix: `agent-connector install (sync) will re-assert it`,
|
|
792
|
+
fixable: true
|
|
682
793
|
});
|
|
683
794
|
} else {
|
|
684
795
|
results.push({
|
|
@@ -1144,6 +1255,30 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
1144
1255
|
check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
|
|
1145
1256
|
});
|
|
1146
1257
|
}
|
|
1258
|
+
const statuslineLedgerOwned = ledgerEntriesOwnedBy(
|
|
1259
|
+
loadConfigPatchLedger(ctx.dataRoot),
|
|
1260
|
+
HOST,
|
|
1261
|
+
connectorId
|
|
1262
|
+
).some((e) => e.key === STATUSLINE_KEY);
|
|
1263
|
+
if ((ctx.connector.statusline != null || statuslineLedgerOwned) && ctx.connector.platforms[HOST]?.statusline !== false) {
|
|
1264
|
+
checks.push({
|
|
1265
|
+
name: `${this.name}: statusline wired`,
|
|
1266
|
+
check: () => {
|
|
1267
|
+
const settings = this.readJson(settingsPath);
|
|
1268
|
+
const command = settings?.statusLine?.command;
|
|
1269
|
+
if (command === void 0) {
|
|
1270
|
+
return { status: "FAIL", detail: `statusLine not set in ${settingsPath}` };
|
|
1271
|
+
}
|
|
1272
|
+
if (typeof command === "string" && isHomeBinStatuslineCommand(command, homeBin, connectorId)) {
|
|
1273
|
+
return { status: "OK", detail: "statusLine command present" };
|
|
1274
|
+
}
|
|
1275
|
+
return {
|
|
1276
|
+
status: "FAIL",
|
|
1277
|
+
detail: `statusLine in ${settingsPath} is not agent-connector's (left untouched)`
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
1281
|
+
}
|
|
1147
1282
|
return checks;
|
|
1148
1283
|
}
|
|
1149
1284
|
// ── Runtime: parse Claude stdin JSON → normalized event ──────────────────
|
|
@@ -1259,6 +1394,13 @@ var ClaudeCodeAdapter = class extends BaseAdapter {
|
|
|
1259
1394
|
};
|
|
1260
1395
|
return ev;
|
|
1261
1396
|
}
|
|
1397
|
+
case "PostCompact": {
|
|
1398
|
+
const ev = {
|
|
1399
|
+
...base,
|
|
1400
|
+
...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
|
|
1401
|
+
};
|
|
1402
|
+
return ev;
|
|
1403
|
+
}
|
|
1262
1404
|
default: {
|
|
1263
1405
|
const _never = event;
|
|
1264
1406
|
throw new Error(`unsupported claude-code hook event: ${String(_never)}`);
|
|
@@ -1429,4 +1571,4 @@ export {
|
|
|
1429
1571
|
claudeSensitiveKeyViolation,
|
|
1430
1572
|
claude_code_default as default
|
|
1431
1573
|
};
|
|
1432
|
-
//# sourceMappingURL=claude-code-
|
|
1574
|
+
//# sourceMappingURL=claude-code-W4PUFZL5.js.map
|