@ken-jo/agent-connector 0.1.0 → 0.2.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.
Files changed (157) hide show
  1. package/README.md +176 -24
  2. package/dist/{amp-QSFH2V7Y.js → amp-YGV66GJT.js} +9 -2
  3. package/dist/amp-YGV66GJT.js.map +1 -0
  4. package/dist/{antigravity-CX2YLSY7.js → antigravity-7IBYFO6P.js} +4 -3
  5. package/dist/{antigravity-cli-YQDFVV4U.js → antigravity-cli-JEOUP2VN.js} +4 -3
  6. package/dist/{antigravity-cli-YQDFVV4U.js.map → antigravity-cli-JEOUP2VN.js.map} +1 -1
  7. package/dist/{chunk-LTT56GI3.js → chunk-3JCRUROU.js} +18 -5
  8. package/dist/chunk-3JCRUROU.js.map +1 -0
  9. package/dist/{chunk-YNZU6PAV.js → chunk-4ML7SZ7R.js} +69 -16
  10. package/dist/chunk-4ML7SZ7R.js.map +1 -0
  11. package/dist/{chunk-54EMKTTX.js → chunk-AKJGNTU3.js} +17 -17
  12. package/dist/chunk-AKJGNTU3.js.map +1 -0
  13. package/dist/chunk-GSGDG2BV.js +568 -0
  14. package/dist/chunk-GSGDG2BV.js.map +1 -0
  15. package/dist/{chunk-TRKWUNO4.js → chunk-KQSNDFBN.js} +13 -2
  16. package/dist/chunk-KQSNDFBN.js.map +1 -0
  17. package/dist/chunk-N6HH7K6P.js +494 -0
  18. package/dist/chunk-N6HH7K6P.js.map +1 -0
  19. package/dist/{chunk-XUCWLJY5.js → chunk-O2SBA5KR.js} +30 -30
  20. package/dist/{chunk-TIIP3RG2.js → chunk-PD4VFEBY.js} +342 -2
  21. package/dist/chunk-PD4VFEBY.js.map +1 -0
  22. package/dist/{chunk-WV63X7IK.js → chunk-SCVBYSF7.js} +2 -2
  23. package/dist/chunk-SCVBYSF7.js.map +1 -0
  24. package/dist/{chunk-7MSDGHJW.js → chunk-Z2BVYKZL.js} +60 -7
  25. package/dist/chunk-Z2BVYKZL.js.map +1 -0
  26. package/dist/claude-code-4275HQU4.js +1432 -0
  27. package/dist/claude-code-4275HQU4.js.map +1 -0
  28. package/dist/cli/sdk.js +4 -3
  29. package/dist/cli/sdk.js.map +1 -1
  30. package/dist/cli.js +1 -1
  31. package/dist/{codebuff-QX57FJDN.js → codebuff-LE3KBZGM.js} +9 -2
  32. package/dist/codebuff-LE3KBZGM.js.map +1 -0
  33. package/dist/{codex-JFQTS6LU.js → codex-4BY2ZJIW.js} +148 -7
  34. package/dist/codex-4BY2ZJIW.js.map +1 -0
  35. package/dist/{copilot-cli-MTCGHZ2T.js → copilot-cli-IPISKO3V.js} +109 -2
  36. package/dist/copilot-cli-IPISKO3V.js.map +1 -0
  37. package/dist/{crush-I7PK3FGI.js → crush-X3E25EQG.js} +31 -3
  38. package/dist/crush-X3E25EQG.js.map +1 -0
  39. package/dist/{cursor-4TMXKJOZ.js → cursor-UH3W622V.js} +66 -5
  40. package/dist/cursor-UH3W622V.js.map +1 -0
  41. package/dist/{detect-WIAGVYS4.js → detect-JK7T46N6.js} +7 -3
  42. package/dist/detect-JK7T46N6.js.map +1 -0
  43. package/dist/{doctor-EZW2K4NI.js → doctor-62BHIXOR.js} +13 -5
  44. package/dist/doctor-62BHIXOR.js.map +1 -0
  45. package/dist/{droid-KN6VRMMT.js → droid-T5VBRXZF.js} +32 -3
  46. package/dist/droid-T5VBRXZF.js.map +1 -0
  47. package/dist/{gemini-cli-Y35FFK4M.js → gemini-cli-ZSUK55UA.js} +51 -3
  48. package/dist/gemini-cli-ZSUK55UA.js.map +1 -0
  49. package/dist/{goose-ZTGTSUFJ.js → goose-M3RR3CZG.js} +63 -4
  50. package/dist/goose-M3RR3CZG.js.map +1 -0
  51. package/dist/{hermes-H2KV44GK.js → hermes-CUNKIAR5.js} +76 -3
  52. package/dist/hermes-CUNKIAR5.js.map +1 -0
  53. package/dist/{hook-YVDILAMZ.js → hook-AC7APC66.js} +26 -11
  54. package/dist/hook-AC7APC66.js.map +1 -0
  55. package/dist/index.d.ts +2 -2
  56. package/dist/index.js +3 -1
  57. package/dist/{install-HQRYZOQ2.js → install-DMW2C7SV.js} +12 -7
  58. package/dist/install-DMW2C7SV.js.map +1 -0
  59. package/dist/{jetbrains-copilot-HWA3DMH7.js → jetbrains-copilot-C3HDGGML.js} +16 -2
  60. package/dist/jetbrains-copilot-C3HDGGML.js.map +1 -0
  61. package/dist/{kilo-QXJRCSLT.js → kilo-ISR5FBBJ.js} +26 -2
  62. package/dist/kilo-ISR5FBBJ.js.map +1 -0
  63. package/dist/{kilo-cli-EAQTHXUW.js → kilo-cli-2RNODHWY.js} +30 -2
  64. package/dist/kilo-cli-2RNODHWY.js.map +1 -0
  65. package/dist/{kimi-GQ7VXNYT.js → kimi-Q5RG7CYT.js} +89 -6
  66. package/dist/kimi-Q5RG7CYT.js.map +1 -0
  67. package/dist/{kiro-VQTT6LO2.js → kiro-EKTRW424.js} +31 -2
  68. package/dist/kiro-EKTRW424.js.map +1 -0
  69. package/dist/{leaderboard-K6ON3SWW.js → leaderboard-R5HRJHNU.js} +3 -3
  70. package/dist/{mux-T2TV4CIQ.js → mux-5CI5FP2W.js} +9 -2
  71. package/dist/mux-5CI5FP2W.js.map +1 -0
  72. package/dist/{omp-PB4VDKS6.js → omp-AXA7XY22.js} +13 -2
  73. package/dist/omp-AXA7XY22.js.map +1 -0
  74. package/dist/{openclaw-ETN2M63O.js → openclaw-UZ5BMCGQ.js} +101 -4
  75. package/dist/openclaw-UZ5BMCGQ.js.map +1 -0
  76. package/dist/{opencode-FZ33JKUZ.js → opencode-NZBRLJN3.js} +53 -7
  77. package/dist/opencode-NZBRLJN3.js.map +1 -0
  78. package/dist/{package-DLOVE2E4.js → package-O63K4S7T.js} +10 -5
  79. package/dist/package-O63K4S7T.js.map +1 -0
  80. package/dist/{pi-CIU2QHT4.js → pi-SJPIL4VE.js} +6 -2
  81. package/dist/pi-SJPIL4VE.js.map +1 -0
  82. package/dist/{qwen-code-5POCNU6P.js → qwen-code-IFCM6BJY.js} +110 -2
  83. package/dist/qwen-code-IFCM6BJY.js.map +1 -0
  84. package/dist/{roo-code-IOIUXRDE.js → roo-code-NI5UU6JB.js} +26 -2
  85. package/dist/roo-code-NI5UU6JB.js.map +1 -0
  86. package/dist/runtime/index.d.ts +38 -4
  87. package/dist/runtime/index.js +9 -4
  88. package/dist/{serve-HVWWY4B6.js → serve-LFOUSZAD.js} +7 -6
  89. package/dist/{serve-HVWWY4B6.js.map → serve-LFOUSZAD.js.map} +1 -1
  90. package/dist/{status-FE7TECZD.js → status-M7JLZVLC.js} +6 -5
  91. package/dist/{status-FE7TECZD.js.map → status-M7JLZVLC.js.map} +1 -1
  92. package/dist/{telemetry-36GESKQQ.js → telemetry-3NVEXPYX.js} +5 -4
  93. package/dist/{telemetry-36GESKQQ.js.map → telemetry-3NVEXPYX.js.map} +1 -1
  94. package/dist/{trae-JSNDZFKL.js → trae-CQC72RHH.js} +9 -2
  95. package/dist/trae-CQC72RHH.js.map +1 -0
  96. package/dist/types-CNigfEuR.d.ts +757 -0
  97. package/dist/{uninstall-IGCKNOSF.js → uninstall-H6FGMIHN.js} +7 -6
  98. package/dist/{uninstall-IGCKNOSF.js.map → uninstall-H6FGMIHN.js.map} +1 -1
  99. package/dist/{upgrade-JV2VK242.js → upgrade-76BQZBMA.js} +7 -6
  100. package/dist/{upgrade-JV2VK242.js.map → upgrade-76BQZBMA.js.map} +1 -1
  101. package/dist/{usage-6ER6EMEY.js → usage-G3GSCX23.js} +3 -3
  102. package/dist/{usage-event-JKBI6XCF.js → usage-event-QUTMNBS5.js} +6 -5
  103. package/dist/{usage-event-JKBI6XCF.js.map → usage-event-QUTMNBS5.js.map} +1 -1
  104. package/dist/{vscode-copilot-CK3NO54M.js → vscode-copilot-4RVRTCKV.js} +53 -4
  105. package/dist/vscode-copilot-4RVRTCKV.js.map +1 -0
  106. package/dist/{warp-QNVDXOG4.js → warp-LLOSXR7A.js} +30 -2
  107. package/dist/warp-LLOSXR7A.js.map +1 -0
  108. package/dist/{zed-VRJKWYUR.js → zed-HYOITK7F.js} +53 -3
  109. package/dist/zed-HYOITK7F.js.map +1 -0
  110. package/package.json +4 -3
  111. package/dist/amp-QSFH2V7Y.js.map +0 -1
  112. package/dist/chunk-54EMKTTX.js.map +0 -1
  113. package/dist/chunk-7MSDGHJW.js.map +0 -1
  114. package/dist/chunk-LTT56GI3.js.map +0 -1
  115. package/dist/chunk-TIIP3RG2.js.map +0 -1
  116. package/dist/chunk-TRKWUNO4.js.map +0 -1
  117. package/dist/chunk-WV63X7IK.js.map +0 -1
  118. package/dist/chunk-XNAM7F35.js +0 -276
  119. package/dist/chunk-XNAM7F35.js.map +0 -1
  120. package/dist/chunk-YNZU6PAV.js.map +0 -1
  121. package/dist/claude-code-HKDV7T32.js +0 -637
  122. package/dist/claude-code-HKDV7T32.js.map +0 -1
  123. package/dist/codebuff-QX57FJDN.js.map +0 -1
  124. package/dist/codex-JFQTS6LU.js.map +0 -1
  125. package/dist/copilot-cli-MTCGHZ2T.js.map +0 -1
  126. package/dist/crush-I7PK3FGI.js.map +0 -1
  127. package/dist/cursor-4TMXKJOZ.js.map +0 -1
  128. package/dist/detect-WIAGVYS4.js.map +0 -1
  129. package/dist/doctor-EZW2K4NI.js.map +0 -1
  130. package/dist/droid-KN6VRMMT.js.map +0 -1
  131. package/dist/gemini-cli-Y35FFK4M.js.map +0 -1
  132. package/dist/goose-ZTGTSUFJ.js.map +0 -1
  133. package/dist/hermes-H2KV44GK.js.map +0 -1
  134. package/dist/hook-YVDILAMZ.js.map +0 -1
  135. package/dist/install-HQRYZOQ2.js.map +0 -1
  136. package/dist/jetbrains-copilot-HWA3DMH7.js.map +0 -1
  137. package/dist/kilo-QXJRCSLT.js.map +0 -1
  138. package/dist/kilo-cli-EAQTHXUW.js.map +0 -1
  139. package/dist/kimi-GQ7VXNYT.js.map +0 -1
  140. package/dist/kiro-VQTT6LO2.js.map +0 -1
  141. package/dist/mux-T2TV4CIQ.js.map +0 -1
  142. package/dist/omp-PB4VDKS6.js.map +0 -1
  143. package/dist/openclaw-ETN2M63O.js.map +0 -1
  144. package/dist/opencode-FZ33JKUZ.js.map +0 -1
  145. package/dist/package-DLOVE2E4.js.map +0 -1
  146. package/dist/pi-CIU2QHT4.js.map +0 -1
  147. package/dist/qwen-code-5POCNU6P.js.map +0 -1
  148. package/dist/roo-code-IOIUXRDE.js.map +0 -1
  149. package/dist/trae-JSNDZFKL.js.map +0 -1
  150. package/dist/types-CYUB1OTr.d.ts +0 -427
  151. package/dist/vscode-copilot-CK3NO54M.js.map +0 -1
  152. package/dist/warp-QNVDXOG4.js.map +0 -1
  153. package/dist/zed-VRJKWYUR.js.map +0 -1
  154. /package/dist/{antigravity-CX2YLSY7.js.map → antigravity-7IBYFO6P.js.map} +0 -0
  155. /package/dist/{chunk-XUCWLJY5.js.map → chunk-O2SBA5KR.js.map} +0 -0
  156. /package/dist/{leaderboard-K6ON3SWW.js.map → leaderboard-R5HRJHNU.js.map} +0 -0
  157. /package/dist/{usage-6ER6EMEY.js.map → usage-G3GSCX23.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 };