@ken-jo/agent-connector 0.1.0 → 0.3.0
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 +183 -24
- package/dist/{amp-QSFH2V7Y.js → amp-YGV66GJT.js} +9 -2
- package/dist/amp-YGV66GJT.js.map +1 -0
- package/dist/{antigravity-CX2YLSY7.js → antigravity-7IBYFO6P.js} +4 -3
- package/dist/{antigravity-cli-YQDFVV4U.js → antigravity-cli-JEOUP2VN.js} +4 -3
- package/dist/{antigravity-cli-YQDFVV4U.js.map → antigravity-cli-JEOUP2VN.js.map} +1 -1
- package/dist/{chunk-LTT56GI3.js → chunk-3JCRUROU.js} +18 -5
- package/dist/chunk-3JCRUROU.js.map +1 -0
- package/dist/chunk-44HUXXC6.js +284 -0
- package/dist/chunk-44HUXXC6.js.map +1 -0
- package/dist/{chunk-54EMKTTX.js → chunk-DS3LUFVN.js} +21 -21
- package/dist/chunk-DS3LUFVN.js.map +1 -0
- package/dist/chunk-GSGDG2BV.js +568 -0
- package/dist/chunk-GSGDG2BV.js.map +1 -0
- package/dist/{chunk-TRKWUNO4.js → chunk-KQSNDFBN.js} +13 -2
- package/dist/chunk-KQSNDFBN.js.map +1 -0
- package/dist/{chunk-KHO5WNTP.js → chunk-KVAAFYRR.js} +18 -2
- package/dist/chunk-KVAAFYRR.js.map +1 -0
- package/dist/chunk-N6HH7K6P.js +494 -0
- package/dist/chunk-N6HH7K6P.js.map +1 -0
- package/dist/{chunk-XUCWLJY5.js → chunk-NJU275US.js} +30 -30
- package/dist/{chunk-WCETQWWK.js → chunk-OP4KBXUO.js} +1 -17
- package/dist/chunk-OP4KBXUO.js.map +1 -0
- package/dist/{chunk-TIIP3RG2.js → chunk-PD4VFEBY.js} +342 -2
- package/dist/chunk-PD4VFEBY.js.map +1 -0
- package/dist/chunk-QADSG2JY.js +1989 -0
- package/dist/chunk-QADSG2JY.js.map +1 -0
- package/dist/{chunk-WV63X7IK.js → chunk-SCVBYSF7.js} +2 -2
- package/dist/chunk-SCVBYSF7.js.map +1 -0
- package/dist/{package-DLOVE2E4.js → chunk-WNREHWKL.js} +26 -115
- package/dist/chunk-WNREHWKL.js.map +1 -0
- package/dist/{chunk-YNZU6PAV.js → chunk-ZAM4M7LI.js} +74 -21
- package/dist/chunk-ZAM4M7LI.js.map +1 -0
- package/dist/claude-code-4275HQU4.js +1432 -0
- package/dist/claude-code-4275HQU4.js.map +1 -0
- package/dist/cli/sdk.js +4 -3
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/{codebuff-QX57FJDN.js → codebuff-LE3KBZGM.js} +9 -2
- package/dist/codebuff-LE3KBZGM.js.map +1 -0
- package/dist/{codex-JFQTS6LU.js → codex-4BY2ZJIW.js} +148 -7
- package/dist/codex-4BY2ZJIW.js.map +1 -0
- package/dist/{copilot-cli-MTCGHZ2T.js → copilot-cli-IPISKO3V.js} +109 -2
- package/dist/copilot-cli-IPISKO3V.js.map +1 -0
- package/dist/{crush-I7PK3FGI.js → crush-X3E25EQG.js} +31 -3
- package/dist/crush-X3E25EQG.js.map +1 -0
- package/dist/{cursor-4TMXKJOZ.js → cursor-UH3W622V.js} +66 -5
- package/dist/cursor-UH3W622V.js.map +1 -0
- package/dist/{detect-WIAGVYS4.js → detect-MNDHGLSV.js} +7 -3
- package/dist/detect-MNDHGLSV.js.map +1 -0
- package/dist/{doctor-EZW2K4NI.js → doctor-N5KZDD55.js} +45 -7
- package/dist/doctor-N5KZDD55.js.map +1 -0
- package/dist/{droid-KN6VRMMT.js → droid-T5VBRXZF.js} +32 -3
- package/dist/droid-T5VBRXZF.js.map +1 -0
- package/dist/{gemini-cli-Y35FFK4M.js → gemini-cli-ZSUK55UA.js} +51 -3
- package/dist/gemini-cli-ZSUK55UA.js.map +1 -0
- package/dist/{goose-ZTGTSUFJ.js → goose-M3RR3CZG.js} +63 -4
- package/dist/goose-M3RR3CZG.js.map +1 -0
- package/dist/{hermes-H2KV44GK.js → hermes-CUNKIAR5.js} +76 -3
- package/dist/hermes-CUNKIAR5.js.map +1 -0
- package/dist/{hook-YVDILAMZ.js → hook-7LUOKIXH.js} +28 -13
- package/dist/hook-7LUOKIXH.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/install-TQTT4F3I.js +89 -0
- package/dist/install-TQTT4F3I.js.map +1 -0
- package/dist/{jetbrains-copilot-HWA3DMH7.js → jetbrains-copilot-C3HDGGML.js} +16 -2
- package/dist/jetbrains-copilot-C3HDGGML.js.map +1 -0
- package/dist/kilo-PKAJCWPX.js +852 -0
- package/dist/kilo-PKAJCWPX.js.map +1 -0
- package/dist/{kilo-cli-EAQTHXUW.js → kilo-cli-QWUVXG2O.js} +186 -7
- package/dist/kilo-cli-QWUVXG2O.js.map +1 -0
- package/dist/{kimi-GQ7VXNYT.js → kimi-EVD7YKXS.js} +167 -9
- package/dist/kimi-EVD7YKXS.js.map +1 -0
- package/dist/{kiro-VQTT6LO2.js → kiro-UQRY6EIO.js} +98 -4
- package/dist/kiro-UQRY6EIO.js.map +1 -0
- package/dist/{leaderboard-K6ON3SWW.js → leaderboard-MUJ7DURM.js} +3 -3
- package/dist/{mux-T2TV4CIQ.js → mux-5CI5FP2W.js} +9 -2
- package/dist/mux-5CI5FP2W.js.map +1 -0
- package/dist/{omp-PB4VDKS6.js → omp-AXA7XY22.js} +13 -2
- package/dist/omp-AXA7XY22.js.map +1 -0
- package/dist/{openclaw-ETN2M63O.js → openclaw-UZ5BMCGQ.js} +101 -4
- package/dist/openclaw-UZ5BMCGQ.js.map +1 -0
- package/dist/{opencode-FZ33JKUZ.js → opencode-NZBRLJN3.js} +53 -7
- package/dist/opencode-NZBRLJN3.js.map +1 -0
- package/dist/package-SYPA5POO.js +130 -0
- package/dist/package-SYPA5POO.js.map +1 -0
- package/dist/{pi-CIU2QHT4.js → pi-WMTUX6ES.js} +106 -23
- package/dist/pi-WMTUX6ES.js.map +1 -0
- package/dist/{qwen-code-5POCNU6P.js → qwen-code-MRRIUQ3P.js} +187 -6
- package/dist/qwen-code-MRRIUQ3P.js.map +1 -0
- package/dist/{roo-code-IOIUXRDE.js → roo-code-NI5UU6JB.js} +26 -2
- package/dist/roo-code-NI5UU6JB.js.map +1 -0
- package/dist/runtime/index.d.ts +38 -4
- package/dist/runtime/index.js +11 -6
- package/dist/{serve-HVWWY4B6.js → serve-XJOSA7BY.js} +9 -8
- package/dist/{serve-HVWWY4B6.js.map → serve-XJOSA7BY.js.map} +1 -1
- package/dist/{status-FE7TECZD.js → status-DYSS6BOR.js} +19 -9
- package/dist/status-DYSS6BOR.js.map +1 -0
- package/dist/{telemetry-36GESKQQ.js → telemetry-IJ4GP2Q3.js} +5 -4
- package/dist/{telemetry-36GESKQQ.js.map → telemetry-IJ4GP2Q3.js.map} +1 -1
- package/dist/{trae-JSNDZFKL.js → trae-CQC72RHH.js} +9 -2
- package/dist/trae-CQC72RHH.js.map +1 -0
- package/dist/types-CNigfEuR.d.ts +757 -0
- package/dist/uninstall-3DXIBRCV.js +162 -0
- package/dist/uninstall-3DXIBRCV.js.map +1 -0
- package/dist/{upgrade-JV2VK242.js → upgrade-GJEB3ITY.js} +29 -10
- package/dist/upgrade-GJEB3ITY.js.map +1 -0
- package/dist/{usage-6ER6EMEY.js → usage-2BJLM3GJ.js} +3 -3
- package/dist/{usage-event-JKBI6XCF.js → usage-event-472X3DOY.js} +8 -7
- package/dist/{usage-event-JKBI6XCF.js.map → usage-event-472X3DOY.js.map} +1 -1
- package/dist/{vscode-copilot-CK3NO54M.js → vscode-copilot-4RVRTCKV.js} +53 -4
- package/dist/vscode-copilot-4RVRTCKV.js.map +1 -0
- package/dist/{warp-QNVDXOG4.js → warp-X6MB67NT.js} +110 -4
- package/dist/warp-X6MB67NT.js.map +1 -0
- package/dist/{zed-VRJKWYUR.js → zed-NTCYW4V2.js} +120 -5
- package/dist/zed-NTCYW4V2.js.map +1 -0
- package/package.json +4 -3
- package/dist/amp-QSFH2V7Y.js.map +0 -1
- package/dist/chunk-54EMKTTX.js.map +0 -1
- package/dist/chunk-7MSDGHJW.js +0 -316
- package/dist/chunk-7MSDGHJW.js.map +0 -1
- package/dist/chunk-KHO5WNTP.js.map +0 -1
- package/dist/chunk-LTT56GI3.js.map +0 -1
- package/dist/chunk-TIIP3RG2.js.map +0 -1
- package/dist/chunk-TRKWUNO4.js.map +0 -1
- package/dist/chunk-WCETQWWK.js.map +0 -1
- package/dist/chunk-WV63X7IK.js.map +0 -1
- package/dist/chunk-XNAM7F35.js +0 -276
- package/dist/chunk-XNAM7F35.js.map +0 -1
- package/dist/chunk-YNZU6PAV.js.map +0 -1
- package/dist/claude-code-HKDV7T32.js +0 -637
- package/dist/claude-code-HKDV7T32.js.map +0 -1
- package/dist/codebuff-QX57FJDN.js.map +0 -1
- package/dist/codex-JFQTS6LU.js.map +0 -1
- package/dist/copilot-cli-MTCGHZ2T.js.map +0 -1
- package/dist/crush-I7PK3FGI.js.map +0 -1
- package/dist/cursor-4TMXKJOZ.js.map +0 -1
- package/dist/detect-WIAGVYS4.js.map +0 -1
- package/dist/doctor-EZW2K4NI.js.map +0 -1
- package/dist/droid-KN6VRMMT.js.map +0 -1
- package/dist/gemini-cli-Y35FFK4M.js.map +0 -1
- package/dist/goose-ZTGTSUFJ.js.map +0 -1
- package/dist/hermes-H2KV44GK.js.map +0 -1
- package/dist/hook-YVDILAMZ.js.map +0 -1
- package/dist/install-HQRYZOQ2.js +0 -60
- package/dist/install-HQRYZOQ2.js.map +0 -1
- package/dist/jetbrains-copilot-HWA3DMH7.js.map +0 -1
- package/dist/kilo-QXJRCSLT.js +0 -384
- package/dist/kilo-QXJRCSLT.js.map +0 -1
- package/dist/kilo-cli-EAQTHXUW.js.map +0 -1
- package/dist/kimi-GQ7VXNYT.js.map +0 -1
- package/dist/kiro-VQTT6LO2.js.map +0 -1
- package/dist/mux-T2TV4CIQ.js.map +0 -1
- package/dist/omp-PB4VDKS6.js.map +0 -1
- package/dist/openclaw-ETN2M63O.js.map +0 -1
- package/dist/opencode-FZ33JKUZ.js.map +0 -1
- package/dist/package-DLOVE2E4.js.map +0 -1
- package/dist/pi-CIU2QHT4.js.map +0 -1
- package/dist/qwen-code-5POCNU6P.js.map +0 -1
- package/dist/roo-code-IOIUXRDE.js.map +0 -1
- package/dist/status-FE7TECZD.js.map +0 -1
- package/dist/trae-JSNDZFKL.js.map +0 -1
- package/dist/types-CYUB1OTr.d.ts +0 -427
- package/dist/uninstall-IGCKNOSF.js +0 -72
- package/dist/uninstall-IGCKNOSF.js.map +0 -1
- package/dist/upgrade-JV2VK242.js.map +0 -1
- package/dist/vscode-copilot-CK3NO54M.js.map +0 -1
- package/dist/warp-QNVDXOG4.js.map +0 -1
- package/dist/zed-VRJKWYUR.js.map +0 -1
- /package/dist/{antigravity-CX2YLSY7.js.map → antigravity-7IBYFO6P.js.map} +0 -0
- /package/dist/{chunk-XUCWLJY5.js.map → chunk-NJU275US.js.map} +0 -0
- /package/dist/{leaderboard-K6ON3SWW.js.map → leaderboard-MUJ7DURM.js.map} +0 -0
- /package/dist/{usage-6ER6EMEY.js.map → usage-2BJLM3GJ.js.map} +0 -0
|
@@ -0,0 +1,757 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* core/types — the shared contract surface for agent-connector.
|
|
3
|
+
*
|
|
4
|
+
* Everything in this file is type-only (no runtime), so it is safe to import
|
|
5
|
+
* from anywhere without creating module cycles. It is the single source of
|
|
6
|
+
* truth that every adapter, the telemetry layer, the CLI, and the public API
|
|
7
|
+
* code against.
|
|
8
|
+
*
|
|
9
|
+
* Grounded in the understand-phase report (docs/research/understand-report.md)
|
|
10
|
+
* and generalized from context-mode's proven 15-platform adapter SPI:
|
|
11
|
+
* - context-mode hardcoded the served identity ("context-mode"); here the
|
|
12
|
+
* identity is a parameter the developer supplies via defineConnector().
|
|
13
|
+
* - context-mode's session/memory/FTS domain logic is removed from the SPI.
|
|
14
|
+
* - MCP server registration is modeled here (root key + format differ per
|
|
15
|
+
* platform, so adapters must render it — it is NOT "100% portable").
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Stable identifiers for every host platform agent-connector can target.
|
|
19
|
+
*
|
|
20
|
+
* NOTE on usage-only platforms: `"synthetic"` is a TELEMETRY-ONLY id
|
|
21
|
+
* (Octofriend / synthetic.new). It has a usage reader (usage/readers/synthetic)
|
|
22
|
+
* but DELIBERATELY no deploy adapter and no ADAPTER_REGISTRY entry — Octofriend
|
|
23
|
+
* exposes no writable MCP config to install into. The registry-completeness test
|
|
24
|
+
* (tests/adapters/registry-completeness.test.ts) allowlists it for this reason.
|
|
25
|
+
*/
|
|
26
|
+
type PlatformId = "claude-code" | "codex" | "cursor" | "vscode-copilot" | "jetbrains-copilot" | "copilot-cli" | "gemini-cli" | "opencode" | "kilo" | "kilo-cli" | "warp" | "hermes" | "openclaw" | "zed" | "antigravity" | "antigravity-cli" | "kiro" | "qwen-code" | "kimi" | "pi" | "omp" | "droid" | "roo-code" | "trae" | "amp" | "codebuff" | "mux" | "crush" | "goose" | "synthetic" | "unknown";
|
|
27
|
+
/**
|
|
28
|
+
* Hook I/O paradigm — the deepest cross-platform divergence (report §4).
|
|
29
|
+
* Canonical shipped sets (keep in sync with src/adapters/registry.ts — this
|
|
30
|
+
* comment once drifted and seeded a docs-wide misclassification):
|
|
31
|
+
* - "json-stdio" (16): host pipes JSON to a command on stdin, reads
|
|
32
|
+
* JSON/exit-code back — Claude Code, Codex, Cursor, VS Code/JetBrains
|
|
33
|
+
* Copilot, Copilot CLI, Gemini CLI, Qwen, Kiro, Kimi, Crush, Goose, Hermes,
|
|
34
|
+
* Droid (Factory), Antigravity (+ the agy CLI). One universal entrypoint
|
|
35
|
+
* binary handles all of them.
|
|
36
|
+
* - "ts-plugin" (4): host loads a JS/TS module exporting lifecycle functions
|
|
37
|
+
* — OpenCode, Kilo CLI, OMP, OpenClaw. Framework generates the module.
|
|
38
|
+
* - "mcp-only" (9): no hook layer at all — Warp, Kilo, Roo Code, Trae, Zed,
|
|
39
|
+
* Amp, Codebuff, Mux, Pi. Only the MCP server (or skills surface) is
|
|
40
|
+
* installed; hooks are reported unavailable.
|
|
41
|
+
*/
|
|
42
|
+
type HookParadigm = "json-stdio" | "ts-plugin" | "mcp-only";
|
|
43
|
+
/**
|
|
44
|
+
* Install scope, normalized across platforms and ordered low→high precedence.
|
|
45
|
+
* Each adapter maps these to a concrete config path and knows which it supports.
|
|
46
|
+
*/
|
|
47
|
+
type InstallScope = "system" | "user" | "project" | "profile" | "managed";
|
|
48
|
+
type Transport = "stdio" | "http" | "sse" | "ws";
|
|
49
|
+
interface ToolFilter {
|
|
50
|
+
/** Glob/exact tool names to expose. Default: ["*"]. */
|
|
51
|
+
include?: string[];
|
|
52
|
+
/** Glob/exact tool names to hide. */
|
|
53
|
+
exclude?: string[];
|
|
54
|
+
}
|
|
55
|
+
interface AuthSpec {
|
|
56
|
+
type: "oauth" | "bearerEnv" | "none";
|
|
57
|
+
/** Env var holding the bearer token when type === "bearerEnv". */
|
|
58
|
+
bearerEnvVar?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A normalized, transport-polymorphic MCP server descriptor. Declared ONCE by
|
|
62
|
+
* the developer; each adapter renders it into that platform's native dialect
|
|
63
|
+
* (root key, field names, format). Adapters that cannot honor a requested
|
|
64
|
+
* transport downgrade-or-skip and report it — they never throw.
|
|
65
|
+
*/
|
|
66
|
+
interface ServerDef {
|
|
67
|
+
transport: Transport;
|
|
68
|
+
command?: string;
|
|
69
|
+
args?: string[];
|
|
70
|
+
/** Env vars passed to the server process. Values support ${env:VAR} interpolation. */
|
|
71
|
+
env?: Record<string, string>;
|
|
72
|
+
cwd?: string;
|
|
73
|
+
url?: string;
|
|
74
|
+
headers?: Record<string, string>;
|
|
75
|
+
auth?: AuthSpec;
|
|
76
|
+
tools?: ToolFilter;
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
/** Default true. When false, the entry is written disabled where supported. */
|
|
79
|
+
enabled?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Wrap the server with `agent-connector serve` so per-tool telemetry is
|
|
82
|
+
* captured transparently. Default: true for stdio servers when telemetry is
|
|
83
|
+
* enabled; false for remote servers (cannot intercept) and when explicitly off.
|
|
84
|
+
*/
|
|
85
|
+
wrapForTelemetry?: boolean;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Canonical, platform-agnostic lifecycle event names.
|
|
89
|
+
*
|
|
90
|
+
* The last four (PermissionRequest / PostToolUseFailure / SubagentStart /
|
|
91
|
+
* SubagentStop) are newer additions with cross-host analogs; hosts without a
|
|
92
|
+
* native analog mark them unsupported in capabilities and the install reports
|
|
93
|
+
* a skip-warn — an event is never silently dropped.
|
|
94
|
+
*/
|
|
95
|
+
type HookEventName = "SessionStart" | "SessionEnd" | "UserPromptSubmit" | "PreToolUse" | "PostToolUse" | "PreCompact" | "Stop" | "Notification" | "PermissionRequest" | "PostToolUseFailure" | "SubagentStart" | "SubagentStop";
|
|
96
|
+
interface BaseEvent {
|
|
97
|
+
/** Which host produced this event (from runtime detection). */
|
|
98
|
+
hostPlatform: PlatformId;
|
|
99
|
+
/** Connector id this event is dispatched to. */
|
|
100
|
+
connectorId: string;
|
|
101
|
+
/** Host session id (adapter-extracted; "" when the host provides none). */
|
|
102
|
+
sessionId: string;
|
|
103
|
+
/** Project directory if the host exposes one. */
|
|
104
|
+
projectDir?: string;
|
|
105
|
+
/** Raw host-specific payload for passthrough/escape-hatch use. */
|
|
106
|
+
raw: unknown;
|
|
107
|
+
}
|
|
108
|
+
interface PreToolUseEvent extends BaseEvent {
|
|
109
|
+
toolName: string;
|
|
110
|
+
toolInput: Record<string, unknown>;
|
|
111
|
+
}
|
|
112
|
+
interface PostToolUseEvent extends BaseEvent {
|
|
113
|
+
toolName: string;
|
|
114
|
+
toolInput: Record<string, unknown>;
|
|
115
|
+
toolOutput?: string;
|
|
116
|
+
isError?: boolean;
|
|
117
|
+
}
|
|
118
|
+
interface SessionStartEvent extends BaseEvent {
|
|
119
|
+
source: "startup" | "compact" | "resume" | "clear";
|
|
120
|
+
}
|
|
121
|
+
interface SessionEndEvent extends BaseEvent {
|
|
122
|
+
reason?: string;
|
|
123
|
+
}
|
|
124
|
+
interface UserPromptSubmitEvent extends BaseEvent {
|
|
125
|
+
prompt: string;
|
|
126
|
+
}
|
|
127
|
+
interface PreCompactEvent extends BaseEvent {
|
|
128
|
+
trigger?: "auto" | "manual";
|
|
129
|
+
}
|
|
130
|
+
interface StopEvent extends BaseEvent {
|
|
131
|
+
/** True when the stop hook itself was triggered during a previous stop hook. */
|
|
132
|
+
stopHookActive?: boolean;
|
|
133
|
+
}
|
|
134
|
+
interface NotificationEvent extends BaseEvent {
|
|
135
|
+
message: string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* PermissionRequest — the host is about to show a permission dialog for a tool
|
|
139
|
+
* call (unlike PreToolUse, which fires before EVERY execution regardless of
|
|
140
|
+
* permission status). Decision semantics differ from the other tool events:
|
|
141
|
+
* - "allow" is an ACTIVE grant that suppresses the dialog (it does NOT
|
|
142
|
+
* override host-side deny rules); `updatedInput` may replace the input.
|
|
143
|
+
* - "deny" rejects the request; `reason` is shown to the model.
|
|
144
|
+
* - "ask" / void / no decision falls through to the host's native dialog.
|
|
145
|
+
* Matchers match the tool name, like PreToolUse.
|
|
146
|
+
*/
|
|
147
|
+
interface PermissionRequestEvent extends BaseEvent {
|
|
148
|
+
toolName: string;
|
|
149
|
+
toolInput: Record<string, unknown>;
|
|
150
|
+
/**
|
|
151
|
+
* Permission-update entries the host's dialog would offer (e.g. Claude's
|
|
152
|
+
* addRules/behavior/destination records). Host-specific shapes — passthrough.
|
|
153
|
+
*/
|
|
154
|
+
permissionSuggestions?: unknown[];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* PostToolUseFailure — a tool call failed (error thrown or failure result).
|
|
158
|
+
* Feedback-only: the tool already failed, so nothing is blockable here.
|
|
159
|
+
* "context" injects `additionalContext` beside the error; a "deny" degrades to
|
|
160
|
+
* the same context shape carrying the reason. Matchers match the tool name.
|
|
161
|
+
*/
|
|
162
|
+
interface PostToolUseFailureEvent extends BaseEvent {
|
|
163
|
+
toolName: string;
|
|
164
|
+
toolInput: Record<string, unknown>;
|
|
165
|
+
/** Host correlation id for the failed tool call, when provided. */
|
|
166
|
+
toolUseId?: string;
|
|
167
|
+
/** The failure/error message the host captured. */
|
|
168
|
+
error: string;
|
|
169
|
+
/** True when a user interruption caused the failure. */
|
|
170
|
+
isInterrupt?: boolean;
|
|
171
|
+
/** Tool execution duration in milliseconds, when the host reports it. */
|
|
172
|
+
durationMs?: number;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* SubagentStart — a subagent was spawned. Observe/context-only: "context"
|
|
176
|
+
* injects `additionalContext` into the SUBAGENT's conversation before its first
|
|
177
|
+
* prompt; there is no decision control. Matchers match the agent type.
|
|
178
|
+
*/
|
|
179
|
+
interface SubagentStartEvent extends BaseEvent {
|
|
180
|
+
/** Unique subagent id, when the host provides one. */
|
|
181
|
+
agentId?: string;
|
|
182
|
+
/** Agent type (built-in name or a custom subagent's declared name). */
|
|
183
|
+
agentType?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* SubagentStop — a subagent finished responding. Stop semantics: "deny" keeps
|
|
187
|
+
* the subagent running with `reason` as its next instruction; "context" injects
|
|
188
|
+
* `additionalContext`. Matchers match the agent type. NOTE: `agentId` and
|
|
189
|
+
* `agentType` are optional because some hosts (including Claude Code) do not
|
|
190
|
+
* reliably populate agent_type on stop — never depend on them being present.
|
|
191
|
+
*/
|
|
192
|
+
interface SubagentStopEvent extends BaseEvent {
|
|
193
|
+
agentId?: string;
|
|
194
|
+
agentType?: string;
|
|
195
|
+
/** The subagent's OWN transcript path (distinct from the parent session's). */
|
|
196
|
+
agentTranscriptPath?: string;
|
|
197
|
+
/** Text of the subagent's final response, when the host provides it. */
|
|
198
|
+
lastAssistantMessage?: string;
|
|
199
|
+
/** True when the stop hook is already continuing this subagent (loop guard). */
|
|
200
|
+
stopHookActive?: boolean;
|
|
201
|
+
}
|
|
202
|
+
/** Map of event name → its normalized payload type. */
|
|
203
|
+
interface EventPayloadMap {
|
|
204
|
+
SessionStart: SessionStartEvent;
|
|
205
|
+
SessionEnd: SessionEndEvent;
|
|
206
|
+
UserPromptSubmit: UserPromptSubmitEvent;
|
|
207
|
+
PreToolUse: PreToolUseEvent;
|
|
208
|
+
PostToolUse: PostToolUseEvent;
|
|
209
|
+
PreCompact: PreCompactEvent;
|
|
210
|
+
Stop: StopEvent;
|
|
211
|
+
Notification: NotificationEvent;
|
|
212
|
+
PermissionRequest: PermissionRequestEvent;
|
|
213
|
+
PostToolUseFailure: PostToolUseFailureEvent;
|
|
214
|
+
SubagentStart: SubagentStartEvent;
|
|
215
|
+
SubagentStop: SubagentStopEvent;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Normalized hook response. A handler returns a subset of these; the adapter
|
|
219
|
+
* formats it into the host's native reply (exit codes / JSON / control fields).
|
|
220
|
+
* Adapters drop fields the host cannot honor (e.g. updatedOutput where the host
|
|
221
|
+
* cannot rewrite tool output) and the framework reports the degradation.
|
|
222
|
+
*/
|
|
223
|
+
interface HookResponse {
|
|
224
|
+
/**
|
|
225
|
+
* - "allow": pass through. On PermissionRequest ONLY, an EXPLICIT "allow"
|
|
226
|
+
* is an active grant that suppresses the host's permission
|
|
227
|
+
* dialog (a void/decision-less return falls through to the
|
|
228
|
+
* native dialog instead — an active grant is never implied).
|
|
229
|
+
* - "deny": block tool execution / stop the action. On SubagentStop this
|
|
230
|
+
* keeps the subagent running (Stop semantics); on feedback-only
|
|
231
|
+
* events (PostToolUseFailure / SubagentStart) it degrades to
|
|
232
|
+
* context carrying the reason.
|
|
233
|
+
* - "modify": replace tool input (PreToolUse / PermissionRequest) with
|
|
234
|
+
* `updatedInput`
|
|
235
|
+
* - "context": inject `additionalContext` as soft guidance
|
|
236
|
+
* - "ask": prompt the user to confirm (on PermissionRequest: fall
|
|
237
|
+
* through to the native dialog — the dialog IS the ask)
|
|
238
|
+
*/
|
|
239
|
+
decision?: "allow" | "deny" | "modify" | "context" | "ask";
|
|
240
|
+
/** Shown to the model/user; required in spirit for deny/ask. */
|
|
241
|
+
reason?: string;
|
|
242
|
+
/** Replacement tool input — only meaningful with decision "modify". */
|
|
243
|
+
updatedInput?: Record<string, unknown>;
|
|
244
|
+
/** Extra context to inject — meaningful with "context" or on SessionStart. */
|
|
245
|
+
additionalContext?: string;
|
|
246
|
+
/** Rewritten tool output — only where the host supports it (PostToolUse). */
|
|
247
|
+
updatedOutput?: string;
|
|
248
|
+
}
|
|
249
|
+
/** A handler bound to one event, optionally filtered by a tool matcher. */
|
|
250
|
+
interface HookDefinition<E extends HookEventName = HookEventName> {
|
|
251
|
+
/**
|
|
252
|
+
* Regex string matched against the tool name (tool events, including
|
|
253
|
+
* PermissionRequest / PostToolUseFailure) or the agent type (SubagentStart /
|
|
254
|
+
* SubagentStop). Empty/omitted matches all. Rendered into each host's native
|
|
255
|
+
* matcher syntax where supported, else evaluated by the universal entrypoint
|
|
256
|
+
* at runtime.
|
|
257
|
+
*/
|
|
258
|
+
matcher?: string;
|
|
259
|
+
handler(event: EventPayloadMap[E]): HookResponse | void | Promise<HookResponse | void>;
|
|
260
|
+
}
|
|
261
|
+
/** Developer-declared hooks, keyed by canonical event name. */
|
|
262
|
+
interface HooksConfig {
|
|
263
|
+
SessionStart?: HookDefinition<"SessionStart">;
|
|
264
|
+
SessionEnd?: HookDefinition<"SessionEnd">;
|
|
265
|
+
UserPromptSubmit?: HookDefinition<"UserPromptSubmit">;
|
|
266
|
+
PreToolUse?: HookDefinition<"PreToolUse">;
|
|
267
|
+
PostToolUse?: HookDefinition<"PostToolUse">;
|
|
268
|
+
PreCompact?: HookDefinition<"PreCompact">;
|
|
269
|
+
Stop?: HookDefinition<"Stop">;
|
|
270
|
+
Notification?: HookDefinition<"Notification">;
|
|
271
|
+
PermissionRequest?: HookDefinition<"PermissionRequest">;
|
|
272
|
+
PostToolUseFailure?: HookDefinition<"PostToolUseFailure">;
|
|
273
|
+
SubagentStart?: HookDefinition<"SubagentStart">;
|
|
274
|
+
SubagentStop?: HookDefinition<"SubagentStop">;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* The payload a NATIVE (passthrough) hook handler receives. Unlike the
|
|
278
|
+
* normalized {@link EventPayloadMap} events there is NO field mapping: `raw` is
|
|
279
|
+
* the host's stdin JSON exactly as it arrived, so the handler reads the host's
|
|
280
|
+
* own contract (e.g. Claude's snake_case `task_id` / `teammate_name` fields)
|
|
281
|
+
* with full native fidelity.
|
|
282
|
+
*/
|
|
283
|
+
interface NativeHookEvent {
|
|
284
|
+
/** Host-native event name, VERBATIM (e.g. "TaskCreated", "WorktreeRemove"). */
|
|
285
|
+
event: string;
|
|
286
|
+
/** Which host produced this event. */
|
|
287
|
+
hostPlatform: PlatformId;
|
|
288
|
+
/** Host session id when the payload carries one ("" when it provides none). */
|
|
289
|
+
sessionId: string;
|
|
290
|
+
/** Project directory when the host reports one (Claude Code: `cwd`). */
|
|
291
|
+
projectDir?: string;
|
|
292
|
+
/** The host's RAW stdin payload, UNTOUCHED — no normalization whatsoever. */
|
|
293
|
+
raw: unknown;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* One native passthrough hook: a handler bound to a HOST-NATIVE event name that
|
|
297
|
+
* is not part of the normalized {@link HookEventName} union.
|
|
298
|
+
*
|
|
299
|
+
* Contract (deliberately minimal — full native fidelity, zero translation):
|
|
300
|
+
* - The handler receives the host's RAW stdin payload ({@link NativeHookEvent}.raw).
|
|
301
|
+
* - Whatever the handler RETURNS is serialized VERBATIM as the stdout JSON
|
|
302
|
+
* reply with exit 0. There is no {@link HookResponse} mapping — the return
|
|
303
|
+
* value must already be the host's native reply shape. Examples from Claude
|
|
304
|
+
* Code's contracts: a TaskCreated/TaskCompleted handler returns
|
|
305
|
+
* `{continue: false, stopReason: "…"}` to stop the teammate entirely; a
|
|
306
|
+
* MessageDisplay handler returns
|
|
307
|
+
* `{hookSpecificOutput: {hookEventName: "MessageDisplay", displayContent}}`
|
|
308
|
+
* to rewrite the rendered text; an Elicitation handler returns
|
|
309
|
+
* `{hookSpecificOutput: {hookEventName: "Elicitation", action: "accept", content}}`
|
|
310
|
+
* to answer an MCP user-input request programmatically. For output-ignored
|
|
311
|
+
* events (e.g. StopFailure, InstructionsLoaded) the handler is
|
|
312
|
+
* logging/alerting-only and should return void.
|
|
313
|
+
* - void/undefined → exit 0 with NO output.
|
|
314
|
+
* - Fail-open: any throw degrades to exit 0 with no output.
|
|
315
|
+
*
|
|
316
|
+
* LIMITATION (v1): exit-2 blocking semantics are NOT modeled — a native handler
|
|
317
|
+
* always exits 0. JSON-on-exit-0 decision control covers Claude Code's events
|
|
318
|
+
* (e.g. `{continue:false, stopReason}` on TaskCreated/TaskCompleted/TeammateIdle),
|
|
319
|
+
* but contracts that REQUIRE a non-zero exit (e.g. WorktreeCreate fails creation
|
|
320
|
+
* on any non-zero exit and wants the path on stdout — which a returned string
|
|
321
|
+
* cannot express as bare text) may not be fully drivable.
|
|
322
|
+
*/
|
|
323
|
+
interface NativeHookDef {
|
|
324
|
+
/**
|
|
325
|
+
* Host-native matcher string, written VERBATIM into the host's hook config
|
|
326
|
+
* entry (e.g. Claude's tool-name / agent-type / trigger matchers). The
|
|
327
|
+
* framework does not evaluate it at runtime — the host filters.
|
|
328
|
+
*/
|
|
329
|
+
matcher?: string;
|
|
330
|
+
/** Receives the raw host payload; its return is the verbatim stdout reply. */
|
|
331
|
+
handler(evt: NativeHookEvent): unknown | Promise<unknown>;
|
|
332
|
+
}
|
|
333
|
+
/** A JSON-serializable value (what JSON.parse can produce). */
|
|
334
|
+
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
335
|
+
[k: string]: JsonValue;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* One declarative, ownership-tracked patch of a host-exclusive config key
|
|
339
|
+
* (e.g. Claude Code settings.json `statusLine`, or
|
|
340
|
+
* `env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`). SEMANTICS ARE FIXED:
|
|
341
|
+
* set-if-absent on a single leaf key, skip-warn on ANY conflict, refcounted
|
|
342
|
+
* ownership (persisted ledger at `<dataRoot>/state/config-patches.json`),
|
|
343
|
+
* reversible uninstall. No overwrite, no delete, no deep merge, no array ops.
|
|
344
|
+
*
|
|
345
|
+
* Connectors name a host + key, NEVER a file path — the adapter owns the
|
|
346
|
+
* key→file mapping ({@link PlatformCapabilities.supportsConfigPatch}; v1:
|
|
347
|
+
* claude-code only, every other adapter reports the standard skip-warn).
|
|
348
|
+
* Same-file sibling structures that belong to the MCP entry dialect (VS Code
|
|
349
|
+
* `inputs`, Zed `context_servers.<id>.settings`) are NOT configPatch targets —
|
|
350
|
+
* they stay in the adapter / `extra`. Keys agent-connector already models
|
|
351
|
+
* (`hooks*`, `mcpServers*`) are rejected at defineConnector; security-relevant
|
|
352
|
+
* keys are refused by the adapter's documented sensitive-key denylist.
|
|
353
|
+
*/
|
|
354
|
+
interface ConfigPatchDef {
|
|
355
|
+
/**
|
|
356
|
+
* Dotted LEAF path into the adapter's declared patchable file, e.g.
|
|
357
|
+
* "statusLine" or "env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS".
|
|
358
|
+
* Segments match /^[A-Za-z0-9_-]+$/ (no dots-in-key, no array indices).
|
|
359
|
+
* Intermediate objects are created only when absent; a non-object
|
|
360
|
+
* intermediate → skip-warn. The VALUE may be an object/array but is
|
|
361
|
+
* written atomically as the leaf — never merged into.
|
|
362
|
+
*/
|
|
363
|
+
key: string;
|
|
364
|
+
/**
|
|
365
|
+
* Value written when (and only when) the key is absent. `${env:VAR}` refs
|
|
366
|
+
* are resolved at install time via core/interpolate resolveEnvRefsDeep,
|
|
367
|
+
* matching server-entry behavior.
|
|
368
|
+
*/
|
|
369
|
+
value: JsonValue;
|
|
370
|
+
/**
|
|
371
|
+
* REQUIRED human-readable why — printed in the install diff, every
|
|
372
|
+
* ChangeRecord, and every skip-warn (so one declaration doubles as its own
|
|
373
|
+
* documented manual-edit fallback on skip/conflict/unsupported hosts).
|
|
374
|
+
*/
|
|
375
|
+
reason: string;
|
|
376
|
+
/** Docs link appended to the manual-edit fallback printed on skip/conflict. */
|
|
377
|
+
docsUrl?: string;
|
|
378
|
+
}
|
|
379
|
+
/** What a given host can actually honor. The single-API layer degrades to it. */
|
|
380
|
+
interface PlatformCapabilities {
|
|
381
|
+
preToolUse: boolean;
|
|
382
|
+
postToolUse: boolean;
|
|
383
|
+
preCompact: boolean;
|
|
384
|
+
sessionStart: boolean;
|
|
385
|
+
sessionEnd: boolean;
|
|
386
|
+
userPromptSubmit: boolean;
|
|
387
|
+
stop: boolean;
|
|
388
|
+
notification: boolean;
|
|
389
|
+
/**
|
|
390
|
+
* Newer per-event flags (OPTIONAL so existing adapter capability literals
|
|
391
|
+
* compile unchanged; read as `?? false`, mirroring the supportsCommands
|
|
392
|
+
* precedent below). A host that leaves a flag unset does not support the
|
|
393
|
+
* event natively — install reports the standard skip-warn for it.
|
|
394
|
+
*/
|
|
395
|
+
permissionRequest?: boolean;
|
|
396
|
+
postToolUseFailure?: boolean;
|
|
397
|
+
subagentStart?: boolean;
|
|
398
|
+
subagentStop?: boolean;
|
|
399
|
+
/** Can a PreToolUse hook rewrite tool arguments? */
|
|
400
|
+
canModifyArgs: boolean;
|
|
401
|
+
/** Can a PostToolUse hook rewrite tool output? */
|
|
402
|
+
canModifyOutput: boolean;
|
|
403
|
+
/** Can a hook inject context at session start / compaction? */
|
|
404
|
+
canInjectSessionContext: boolean;
|
|
405
|
+
/** MCP transports this host can register. */
|
|
406
|
+
transports: Transport[];
|
|
407
|
+
/**
|
|
408
|
+
* Native (passthrough) hooks support — can this adapter install
|
|
409
|
+
* {@link PlatformOverride.nativeHooks} entries verbatim into the host's hook
|
|
410
|
+
* config? OPTIONAL, read as `?? false` (supportsCommands precedent). Only
|
|
411
|
+
* claude-code opts in today; an adapter that leaves this unset and receives a
|
|
412
|
+
* nativeHooks declaration gets the standard skip-warn ChangeRecord from the
|
|
413
|
+
* installer (never silent).
|
|
414
|
+
*/
|
|
415
|
+
supportsNativeHooks?: boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Declarative host-config key patches — can this adapter apply
|
|
418
|
+
* {@link PlatformOverride.configPatch} entries (set-if-absent, ownership-
|
|
419
|
+
* tracked) to its declared patchable config file? OPTIONAL, read as
|
|
420
|
+
* `?? false` (supportsNativeHooks precedent). v1: claude-code only; an
|
|
421
|
+
* adapter that leaves this unset and receives a configPatch declaration gets
|
|
422
|
+
* the standard skip-warn ChangeRecord from the installer (never silent),
|
|
423
|
+
* plus per-patch manual-edit instructions from `reason`/`docsUrl`.
|
|
424
|
+
*/
|
|
425
|
+
supportsConfigPatch?: boolean;
|
|
426
|
+
/**
|
|
427
|
+
* Content-surface support (all OPTIONAL so existing adapter capability
|
|
428
|
+
* literals compile unchanged; read as `?? false`). Only surface-supporting
|
|
429
|
+
* adapters set these true. The BaseAdapter install/uninstall defaults
|
|
430
|
+
* handle the "unsupported" skip/warn regardless of the flag.
|
|
431
|
+
*/
|
|
432
|
+
supportsCommands?: boolean;
|
|
433
|
+
supportsSkills?: boolean;
|
|
434
|
+
supportsSubagents?: boolean;
|
|
435
|
+
/**
|
|
436
|
+
* Memory-surface support (managed marker blocks in the host's memory/rules
|
|
437
|
+
* file, AGENTS.md-first). OPTIONAL, read as `?? false` (supportsCommands
|
|
438
|
+
* precedent). Supporting adapters inherit BaseAdapter's generic
|
|
439
|
+
* installMemory/uninstallMemory; the write target comes from the
|
|
440
|
+
* per-adapter `memoryTargets()` hook.
|
|
441
|
+
*/
|
|
442
|
+
supportsMemory?: boolean;
|
|
443
|
+
}
|
|
444
|
+
/** Tool access expressed once; adapters render to allowed-tools / tools[] / readonly. */
|
|
445
|
+
interface SurfaceToolPolicy {
|
|
446
|
+
allow?: string[];
|
|
447
|
+
deny?: string[];
|
|
448
|
+
}
|
|
449
|
+
/** A slash command (= a Skill on 2026 Claude; adapters pick the right surface). */
|
|
450
|
+
interface CommandDef {
|
|
451
|
+
/** kebab-case; becomes the slash name and the filename stem. Source of truth. */
|
|
452
|
+
name: string;
|
|
453
|
+
/** One-line description for /help + model auto-selection. */
|
|
454
|
+
description?: string;
|
|
455
|
+
/** Prompt template body (markdown). The portable core of the command. */
|
|
456
|
+
prompt: string;
|
|
457
|
+
/** Shown in argument completion, e.g. "[environment]". */
|
|
458
|
+
argumentHint?: string;
|
|
459
|
+
tools?: SurfaceToolPolicy;
|
|
460
|
+
/** Model override (raw id or alias; adapters pass through or drop+warn). */
|
|
461
|
+
model?: string;
|
|
462
|
+
/** Force subagent / forked context where the platform supports it. */
|
|
463
|
+
subtask?: boolean;
|
|
464
|
+
/** Verbatim per-platform frontmatter additions (escape hatch). */
|
|
465
|
+
extra?: Record<string, unknown>;
|
|
466
|
+
}
|
|
467
|
+
/** An Agent Skill (folder + SKILL.md, Agent Skills open standard). */
|
|
468
|
+
interface SkillDef {
|
|
469
|
+
/** <=64 chars, [a-z0-9-]; MUST equal the skill dir name. Source of truth. */
|
|
470
|
+
name: string;
|
|
471
|
+
/** <=1024 chars, 3rd-person "what + when"; drives model auto-selection. Required. */
|
|
472
|
+
description: string;
|
|
473
|
+
/** SKILL.md markdown body (instructions). */
|
|
474
|
+
body: string;
|
|
475
|
+
tools?: SurfaceToolPolicy;
|
|
476
|
+
model?: string;
|
|
477
|
+
disableModelInvocation?: boolean;
|
|
478
|
+
/** Extra files bundled beside SKILL.md, relative path → contents. */
|
|
479
|
+
resources?: Record<string, string>;
|
|
480
|
+
extra?: Record<string, unknown>;
|
|
481
|
+
}
|
|
482
|
+
/** A named subagent (system-prompt + tool/model scoping). */
|
|
483
|
+
interface SubagentDef {
|
|
484
|
+
/** kebab-case identifier. Source of truth (filename stem on most platforms). */
|
|
485
|
+
name: string;
|
|
486
|
+
/** Delegation hint shown to the orchestrator. Required. */
|
|
487
|
+
description: string;
|
|
488
|
+
/** System prompt = the agent's instructions (markdown body / developer_instructions). */
|
|
489
|
+
prompt: string;
|
|
490
|
+
tools?: SurfaceToolPolicy;
|
|
491
|
+
/** Model: alias|full-id|"inherit". Default left to platform. */
|
|
492
|
+
model?: string;
|
|
493
|
+
/** Coarse permission knob → Cursor readonly, opencode/kilo permission map. */
|
|
494
|
+
readonly?: boolean;
|
|
495
|
+
extra?: Record<string, unknown>;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* A standing-guidance entry ("memory") — declared ONCE; each supporting adapter
|
|
499
|
+
* writes it as a MANAGED BLOCK (marker-fenced, hash-stamped,
|
|
500
|
+
* uninstall-reversible — see core/managed-block.ts) into the memory/rules file
|
|
501
|
+
* that host actually reads: AGENTS.md wherever the host supports the agents.md
|
|
502
|
+
* standard (27/29 hosts), the host's own file (CLAUDE.md / GEMINI.md)
|
|
503
|
+
* otherwise. CONTENT-ONLY like commands/skills/subagents: no runtime dispatch,
|
|
504
|
+
* no telemetry wrapping — a pure, surgical file edit that never touches bytes
|
|
505
|
+
* outside its own marker pair.
|
|
506
|
+
*/
|
|
507
|
+
interface MemoryDef {
|
|
508
|
+
/**
|
|
509
|
+
* kebab-case identifier; default "memory". Suffixes the connector id in the
|
|
510
|
+
* block marker (`<connectorId>/<name>`), so it must stay STABLE across
|
|
511
|
+
* versions — renaming orphans the old block until the next sync's
|
|
512
|
+
* prefix-scan reclaims it. Two entries without distinct names are a
|
|
513
|
+
* ConnectorConfigError (duplicate name).
|
|
514
|
+
*/
|
|
515
|
+
name?: string;
|
|
516
|
+
/** One-line "what this guidance is for" — status/docs output only; never written to the host file. */
|
|
517
|
+
description?: string;
|
|
518
|
+
/**
|
|
519
|
+
* The guidance markdown. Plain CommonMark, host-agnostic: no @imports, no
|
|
520
|
+
* frontmatter, no host-specific syntax — it is inlined verbatim into EVERY
|
|
521
|
+
* targeted host's prompt context. Budgets: ConnectorConfigError above
|
|
522
|
+
* 16 KiB; install-time `warn` ChangeRecord above 4 KiB (every host pays
|
|
523
|
+
* this cost on every prompt). MUST NOT contain the literal marker tokens
|
|
524
|
+
* `agent-connector:begin` / `agent-connector:end` (ConnectorConfigError).
|
|
525
|
+
*/
|
|
526
|
+
content: string;
|
|
527
|
+
}
|
|
528
|
+
/** Per-host memory tuning — the object form of {@link PlatformOverride.memory}. */
|
|
529
|
+
interface PlatformMemoryOverride {
|
|
530
|
+
/**
|
|
531
|
+
* Override the write target file. Absolute, or resolved against the project
|
|
532
|
+
* dir (project scope) / home dir (user scope). Escape hatch for org
|
|
533
|
+
* conventions (e.g. "docs/AGENTS.md") or a host whose config moved.
|
|
534
|
+
*/
|
|
535
|
+
path?: string;
|
|
536
|
+
/**
|
|
537
|
+
* claude-code ONLY (ignored elsewhere, with a `warn` ChangeRecord):
|
|
538
|
+
* - "block" (default): write the managed block directly into CLAUDE.md.
|
|
539
|
+
* Zero side-effects beyond the block itself.
|
|
540
|
+
* - "agents-import": write the canonical block into AGENTS.md and manage a
|
|
541
|
+
* shared `@AGENTS.md` import bridge block in CLAUDE.md — Anthropic's
|
|
542
|
+
* documented interop. NOTE: Claude then reads the ENTIRE AGENTS.md
|
|
543
|
+
* (user content included), which is why this is opt-in.
|
|
544
|
+
* Regardless of mode, when CLAUDE.md already imports or symlinks AGENTS.md
|
|
545
|
+
* the adapter auto-behaves as "agents-import" and never writes a duplicate
|
|
546
|
+
* block into CLAUDE.md.
|
|
547
|
+
*/
|
|
548
|
+
mode?: "block" | "agents-import";
|
|
549
|
+
}
|
|
550
|
+
interface TelemetryConfig {
|
|
551
|
+
/** On by default. Global kill switch also via AGENT_CONNECTOR_TELEMETRY=0. */
|
|
552
|
+
enabled?: boolean;
|
|
553
|
+
/** Tokenizer family selection. "auto" infers from client/host. */
|
|
554
|
+
modelFamilyHint?: "auto" | "openai" | "anthropic" | "generic";
|
|
555
|
+
/** Tokenize tools/list schemas once → fixed per-turn tool-definition overhead. */
|
|
556
|
+
measureToolDefs?: boolean;
|
|
557
|
+
/** Opt-in network calibration (sends content off-box — off by default). */
|
|
558
|
+
calibration?: {
|
|
559
|
+
anthropicCountTokens?: boolean;
|
|
560
|
+
};
|
|
561
|
+
/**
|
|
562
|
+
* OPT-IN host-native turn-usage capture (off by default). When enabled, the
|
|
563
|
+
* Gemini / Antigravity adapters ALSO install an AfterModel / PostInvocation hook
|
|
564
|
+
* that reads the host's `usageMetadata` and records a DISTINCT `model_turn`
|
|
565
|
+
* telemetry row (confidence `host-native`). Whole-conversation, never summed with
|
|
566
|
+
* the per-MCP `call` rows. May also be forced on at install via the env switch
|
|
567
|
+
* AGENT_CONNECTOR_HOST_NATIVE=1. Aggregate counts only; no raw content stored.
|
|
568
|
+
*/
|
|
569
|
+
hostNativeUsage?: boolean;
|
|
570
|
+
/** Storage backend. NDJSON (default) needs no native deps; sqlite is an upgrade. */
|
|
571
|
+
store?: "ndjson" | "sqlite";
|
|
572
|
+
}
|
|
573
|
+
/** Per-platform override / escape hatch (report §3.2). */
|
|
574
|
+
interface PlatformOverride {
|
|
575
|
+
/**
|
|
576
|
+
* false → do not install the NORMALIZED hooks on this platform; object →
|
|
577
|
+
* merge/replace hooks. Does not affect `nativeHooks` below (a sibling,
|
|
578
|
+
* explicitly platform-scoped declaration).
|
|
579
|
+
*/
|
|
580
|
+
hooks?: boolean | Partial<HooksConfig>;
|
|
581
|
+
/**
|
|
582
|
+
* NATIVE HOOKS PASSTHROUGH — wire ANY host hook event that is not in the
|
|
583
|
+
* normalized {@link HookEventName} union, keyed by the host's event name
|
|
584
|
+
* VERBATIM. This immediately covers all 30 current Claude Code events (e.g.
|
|
585
|
+
* TaskCreated, TaskCompleted, TeammateIdle, StopFailure, MessageDisplay,
|
|
586
|
+
* WorktreeCreate/WorktreeRemove, Elicitation/ElicitationResult,
|
|
587
|
+
* InstructionsLoaded, ConfigChange, FileChanged, PostCompact, …) and any
|
|
588
|
+
* future event a host adds — with zero agent-connector releases.
|
|
589
|
+
*
|
|
590
|
+
* Scoping: per-platform-keyed, so a declaration only ever applies to the
|
|
591
|
+
* platform it is declared under. Adapters without
|
|
592
|
+
* {@link PlatformCapabilities.supportsNativeHooks} report a skip-warn
|
|
593
|
+
* ChangeRecord at install (never silent). Declaring one of the 12 normalized
|
|
594
|
+
* event names here is a ConnectorConfigError — use the normalized `hooks`
|
|
595
|
+
* API for those.
|
|
596
|
+
*
|
|
597
|
+
* PROMOTION CRITERIA: an event graduates from nativeHooks to the normalized
|
|
598
|
+
* union when ≥3 hosts ship a native analog (per the living cross-host
|
|
599
|
+
* matrix); TaskCreated/TaskCompleted are the named first candidates.
|
|
600
|
+
*/
|
|
601
|
+
nativeHooks?: Record<string, NativeHookDef>;
|
|
602
|
+
/**
|
|
603
|
+
* Declarative host-config key patches (set-if-absent, ownership-tracked,
|
|
604
|
+
* skip-warn on ANY conflict — see {@link ConfigPatchDef} for the full fixed
|
|
605
|
+
* contract). Platform-scoped by construction: a declaration only ever
|
|
606
|
+
* applies to the platform it is declared under, and only adapters with
|
|
607
|
+
* {@link PlatformCapabilities.supportsConfigPatch} (v1: claude-code) apply
|
|
608
|
+
* it; every other adapter reports the standard skip-warn ChangeRecord with
|
|
609
|
+
* the per-patch manual-edit instructions (never silent).
|
|
610
|
+
*/
|
|
611
|
+
configPatch?: ConfigPatchDef[];
|
|
612
|
+
/** false → do not register the MCP server here; object → shallow-merge into ServerDef. */
|
|
613
|
+
server?: Partial<ServerDef> | false;
|
|
614
|
+
/** Force a specific scope for this platform. */
|
|
615
|
+
scope?: InstallScope;
|
|
616
|
+
/** false → skip command files on this platform. */
|
|
617
|
+
commands?: boolean;
|
|
618
|
+
/** false → skip skill files on this platform. */
|
|
619
|
+
skills?: boolean;
|
|
620
|
+
/** false → skip subagent files on this platform. */
|
|
621
|
+
subagents?: boolean;
|
|
622
|
+
/**
|
|
623
|
+
* false → do not write memory blocks on this platform;
|
|
624
|
+
* object → per-host target/mode tuning ({@link PlatformMemoryOverride}).
|
|
625
|
+
*/
|
|
626
|
+
memory?: boolean | PlatformMemoryOverride;
|
|
627
|
+
/** Verbatim fields merged into the native config (reach platform-exclusive features). */
|
|
628
|
+
extra?: Record<string, unknown>;
|
|
629
|
+
}
|
|
630
|
+
/**
|
|
631
|
+
* Distribution metadata for the OFFICIAL MCP standard artifacts `package` can
|
|
632
|
+
* emit — the registry `server.json` and the MCPB `.mcpb` bundle. These describe
|
|
633
|
+
* the developer's REAL upstream MCP server (what a registry installer / Claude
|
|
634
|
+
* Desktop runs directly), NOT agent-connector's telemetry `serve` wrapper, so
|
|
635
|
+
* they need inputs the cross-platform install does not: the namespace the dev
|
|
636
|
+
* proved ownership of, their published package name, and bundle author info.
|
|
637
|
+
*
|
|
638
|
+
* All optional — a connector that never publishes to the registry or as a
|
|
639
|
+
* bundle can omit this entirely; the relevant `package --format` raises a clear,
|
|
640
|
+
* actionable error only when its required field is missing.
|
|
641
|
+
*/
|
|
642
|
+
interface PublishConfig {
|
|
643
|
+
/**
|
|
644
|
+
* Reverse-DNS namespace the developer OWNS, e.g. "io.github.acme" or
|
|
645
|
+
* "com.acme". server.json `name` is rendered as `${registryNamespace}/${id}`.
|
|
646
|
+
* agent-connector never mints a namespace on the dev's behalf — the registry
|
|
647
|
+
* requires proven ownership (the `mcp-publisher login` step the dev runs).
|
|
648
|
+
*/
|
|
649
|
+
registryNamespace?: string;
|
|
650
|
+
/**
|
|
651
|
+
* The developer's REAL published package that runs the MCP server, e.g.
|
|
652
|
+
* "@acme/acme-db-mcp" — server.json packages[].identifier. Required to emit a
|
|
653
|
+
* registry npm package entry (we cannot guess the published name).
|
|
654
|
+
*/
|
|
655
|
+
packageName?: string;
|
|
656
|
+
/** Package registry base URL. Default https://registry.npmjs.org for npm. */
|
|
657
|
+
registryBaseUrl?: string;
|
|
658
|
+
/** Bundle author. The MCPB manifest requires author.name. */
|
|
659
|
+
author?: {
|
|
660
|
+
name: string;
|
|
661
|
+
email?: string;
|
|
662
|
+
url?: string;
|
|
663
|
+
};
|
|
664
|
+
}
|
|
665
|
+
/** What a developer passes to defineConnector(). */
|
|
666
|
+
interface ConnectorConfig {
|
|
667
|
+
/** Stable connector id (kebab-case). Replaces context-mode's hardcoded identity. */
|
|
668
|
+
id: string;
|
|
669
|
+
displayName?: string;
|
|
670
|
+
version?: string;
|
|
671
|
+
/** The MCP server to deploy. Omit for a hooks-only connector. */
|
|
672
|
+
server?: ServerDef;
|
|
673
|
+
/** Lifecycle hooks. Omit for a server-only connector. */
|
|
674
|
+
hooks?: HooksConfig;
|
|
675
|
+
/** Telemetry options. Telemetry is ON by default even if this is omitted. */
|
|
676
|
+
telemetry?: TelemetryConfig;
|
|
677
|
+
/** Slash commands to deploy as native content files. */
|
|
678
|
+
commands?: CommandDef[];
|
|
679
|
+
/** Agent Skills to deploy as native content files. */
|
|
680
|
+
skills?: SkillDef[];
|
|
681
|
+
/** Named subagents to deploy as native content files. */
|
|
682
|
+
subagents?: SubagentDef[];
|
|
683
|
+
/**
|
|
684
|
+
* Standing guidance written as managed marker blocks into each host's
|
|
685
|
+
* memory/rules file (AGENTS.md-first). Omit when the connector ships none.
|
|
686
|
+
*/
|
|
687
|
+
memory?: MemoryDef[];
|
|
688
|
+
/** Per-platform overrides / escape hatches. */
|
|
689
|
+
platforms?: Partial<Record<PlatformId, PlatformOverride>>;
|
|
690
|
+
/** "auto" (all detected) or an explicit allow-list. Default "auto". */
|
|
691
|
+
targets?: "auto" | PlatformId[];
|
|
692
|
+
/** Distribution metadata for the registry server.json + MCPB bundle formats. */
|
|
693
|
+
publish?: PublishConfig;
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* A validated, normalized connector — what defineConnector() returns and what
|
|
697
|
+
* adapters/CLI consume. All optional config fields are resolved to defaults.
|
|
698
|
+
*/
|
|
699
|
+
interface ResolvedConnector {
|
|
700
|
+
id: string;
|
|
701
|
+
displayName: string;
|
|
702
|
+
version: string;
|
|
703
|
+
server?: ServerDef;
|
|
704
|
+
hooks: HooksConfig;
|
|
705
|
+
hookEvents: HookEventName[];
|
|
706
|
+
telemetry: Required<Omit<TelemetryConfig, "calibration">> & {
|
|
707
|
+
calibration: {
|
|
708
|
+
anthropicCountTokens: boolean;
|
|
709
|
+
};
|
|
710
|
+
};
|
|
711
|
+
/** Normalized commands; defaults applied; [] when none. */
|
|
712
|
+
commands: CommandDef[];
|
|
713
|
+
/** Normalized skills; defaults applied; [] when none. */
|
|
714
|
+
skills: SkillDef[];
|
|
715
|
+
/** Normalized subagents; defaults applied; [] when none. */
|
|
716
|
+
subagents: SubagentDef[];
|
|
717
|
+
/** Normalized memory entries; names defaulted ("memory"); [] when none. */
|
|
718
|
+
memory: MemoryDef[];
|
|
719
|
+
platforms: Partial<Record<PlatformId, PlatformOverride>>;
|
|
720
|
+
targets: "auto" | PlatformId[];
|
|
721
|
+
/** Distribution metadata (registry server.json + MCPB bundle); passed through verbatim. */
|
|
722
|
+
publish?: PublishConfig;
|
|
723
|
+
}
|
|
724
|
+
/** Result of detecting one platform on this machine. */
|
|
725
|
+
interface DetectedPlatform {
|
|
726
|
+
id: PlatformId;
|
|
727
|
+
name: string;
|
|
728
|
+
installed: boolean;
|
|
729
|
+
paradigm: HookParadigm;
|
|
730
|
+
capabilities: PlatformCapabilities;
|
|
731
|
+
/** Native config path that would be written for `scope`. */
|
|
732
|
+
configPath: string;
|
|
733
|
+
scope: InstallScope;
|
|
734
|
+
reason: string;
|
|
735
|
+
confidence: "high" | "medium" | "low";
|
|
736
|
+
}
|
|
737
|
+
interface ChangeRecord {
|
|
738
|
+
platform: PlatformId;
|
|
739
|
+
action: "create" | "update" | "skip" | "remove" | "warn";
|
|
740
|
+
/** File touched (when applicable). */
|
|
741
|
+
path?: string;
|
|
742
|
+
detail: string;
|
|
743
|
+
}
|
|
744
|
+
interface InstallResult {
|
|
745
|
+
connectorId: string;
|
|
746
|
+
dryRun: boolean;
|
|
747
|
+
changes: ChangeRecord[];
|
|
748
|
+
warnings: string[];
|
|
749
|
+
}
|
|
750
|
+
interface DiagnosticResult {
|
|
751
|
+
check: string;
|
|
752
|
+
status: "pass" | "fail" | "warn";
|
|
753
|
+
message: string;
|
|
754
|
+
fix?: string;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
export type { AuthSpec as A, ConnectorConfig as C, DetectedPlatform as D, EventPayloadMap as E, HookDefinition as H, InstallResult as I, MemoryDef as M, NativeHookDef as N, PermissionRequestEvent as P, ResolvedConnector as R, ServerDef as S, TelemetryConfig as T, UserPromptSubmitEvent as U, ChangeRecord as a, DiagnosticResult as b, HookEventName as c, HookParadigm as d, HookResponse as e, HooksConfig as f, InstallScope as g, NativeHookEvent as h, NotificationEvent as i, PlatformCapabilities as j, PlatformId as k, PlatformMemoryOverride as l, PlatformOverride as m, PostToolUseEvent as n, PostToolUseFailureEvent as o, PreCompactEvent as p, PreToolUseEvent as q, SessionEndEvent as r, SessionStartEvent as s, StopEvent as t, SubagentStartEvent as u, SubagentStopEvent as v, ToolFilter as w, Transport as x };
|