@ken-jo/agent-connector 0.1.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 (203) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +6 -0
  3. package/README.md +348 -0
  4. package/dist/amp-QSFH2V7Y.js +217 -0
  5. package/dist/amp-QSFH2V7Y.js.map +1 -0
  6. package/dist/amp-TULUPXXL.js +237 -0
  7. package/dist/amp-TULUPXXL.js.map +1 -0
  8. package/dist/antigravity-CX2YLSY7.js +17 -0
  9. package/dist/antigravity-CX2YLSY7.js.map +1 -0
  10. package/dist/antigravity-STHZWMP3.js +171 -0
  11. package/dist/antigravity-STHZWMP3.js.map +1 -0
  12. package/dist/antigravity-cli-P6HADOAO.js +121 -0
  13. package/dist/antigravity-cli-P6HADOAO.js.map +1 -0
  14. package/dist/antigravity-cli-YQDFVV4U.js +86 -0
  15. package/dist/antigravity-cli-YQDFVV4U.js.map +1 -0
  16. package/dist/chunk-54EMKTTX.js +191 -0
  17. package/dist/chunk-54EMKTTX.js.map +1 -0
  18. package/dist/chunk-7L6ITC4T.js +54 -0
  19. package/dist/chunk-7L6ITC4T.js.map +1 -0
  20. package/dist/chunk-7MSDGHJW.js +316 -0
  21. package/dist/chunk-7MSDGHJW.js.map +1 -0
  22. package/dist/chunk-BCHWFTV4.js +196 -0
  23. package/dist/chunk-BCHWFTV4.js.map +1 -0
  24. package/dist/chunk-DBQMX75U.js +36 -0
  25. package/dist/chunk-DBQMX75U.js.map +1 -0
  26. package/dist/chunk-EXLS7BSI.js +29 -0
  27. package/dist/chunk-EXLS7BSI.js.map +1 -0
  28. package/dist/chunk-JNM3TPLX.js +593 -0
  29. package/dist/chunk-JNM3TPLX.js.map +1 -0
  30. package/dist/chunk-JWNT5KW7.js +197 -0
  31. package/dist/chunk-JWNT5KW7.js.map +1 -0
  32. package/dist/chunk-KHO5WNTP.js +30 -0
  33. package/dist/chunk-KHO5WNTP.js.map +1 -0
  34. package/dist/chunk-LTT56GI3.js +155 -0
  35. package/dist/chunk-LTT56GI3.js.map +1 -0
  36. package/dist/chunk-MEH7GC7R.js +111 -0
  37. package/dist/chunk-MEH7GC7R.js.map +1 -0
  38. package/dist/chunk-MQPNU2CY.js +64 -0
  39. package/dist/chunk-MQPNU2CY.js.map +1 -0
  40. package/dist/chunk-OPXAP3AC.js +12 -0
  41. package/dist/chunk-OPXAP3AC.js.map +1 -0
  42. package/dist/chunk-RK6VBLXP.js +50 -0
  43. package/dist/chunk-RK6VBLXP.js.map +1 -0
  44. package/dist/chunk-TIIP3RG2.js +420 -0
  45. package/dist/chunk-TIIP3RG2.js.map +1 -0
  46. package/dist/chunk-TRKWUNO4.js +702 -0
  47. package/dist/chunk-TRKWUNO4.js.map +1 -0
  48. package/dist/chunk-TRQKHP7D.js +93 -0
  49. package/dist/chunk-TRQKHP7D.js.map +1 -0
  50. package/dist/chunk-WCETQWWK.js +59 -0
  51. package/dist/chunk-WCETQWWK.js.map +1 -0
  52. package/dist/chunk-WV63X7IK.js +357 -0
  53. package/dist/chunk-WV63X7IK.js.map +1 -0
  54. package/dist/chunk-XD7MY6HB.js +343 -0
  55. package/dist/chunk-XD7MY6HB.js.map +1 -0
  56. package/dist/chunk-XNAM7F35.js +276 -0
  57. package/dist/chunk-XNAM7F35.js.map +1 -0
  58. package/dist/chunk-XUCWLJY5.js +238 -0
  59. package/dist/chunk-XUCWLJY5.js.map +1 -0
  60. package/dist/chunk-YNZU6PAV.js +800 -0
  61. package/dist/chunk-YNZU6PAV.js.map +1 -0
  62. package/dist/chunk-YT43MUSJ.js +146 -0
  63. package/dist/chunk-YT43MUSJ.js.map +1 -0
  64. package/dist/claude-code-HKDV7T32.js +637 -0
  65. package/dist/claude-code-HKDV7T32.js.map +1 -0
  66. package/dist/claude-code-W74MNTAC.js +652 -0
  67. package/dist/claude-code-W74MNTAC.js.map +1 -0
  68. package/dist/cli/sdk.d.ts +54 -0
  69. package/dist/cli/sdk.js +82 -0
  70. package/dist/cli/sdk.js.map +1 -0
  71. package/dist/cli.d.ts +2 -0
  72. package/dist/cli.js +15 -0
  73. package/dist/cli.js.map +1 -0
  74. package/dist/codebuff-3PMZJJHP.js +307 -0
  75. package/dist/codebuff-3PMZJJHP.js.map +1 -0
  76. package/dist/codebuff-QX57FJDN.js +220 -0
  77. package/dist/codebuff-QX57FJDN.js.map +1 -0
  78. package/dist/codex-JFQTS6LU.js +593 -0
  79. package/dist/codex-JFQTS6LU.js.map +1 -0
  80. package/dist/codex-Q3ATRRX3.js +364 -0
  81. package/dist/codex-Q3ATRRX3.js.map +1 -0
  82. package/dist/copilot-cli-MTCGHZ2T.js +622 -0
  83. package/dist/copilot-cli-MTCGHZ2T.js.map +1 -0
  84. package/dist/copilot-cli-SJGIXVSD.js +369 -0
  85. package/dist/copilot-cli-SJGIXVSD.js.map +1 -0
  86. package/dist/crush-I7PK3FGI.js +360 -0
  87. package/dist/crush-I7PK3FGI.js.map +1 -0
  88. package/dist/crush-LN5QFFR2.js +183 -0
  89. package/dist/crush-LN5QFFR2.js.map +1 -0
  90. package/dist/cursor-4TMXKJOZ.js +603 -0
  91. package/dist/cursor-4TMXKJOZ.js.map +1 -0
  92. package/dist/cursor-QZ6MTO74.js +194 -0
  93. package/dist/cursor-QZ6MTO74.js.map +1 -0
  94. package/dist/detect-WIAGVYS4.js +68 -0
  95. package/dist/detect-WIAGVYS4.js.map +1 -0
  96. package/dist/doctor-EZW2K4NI.js +372 -0
  97. package/dist/doctor-EZW2K4NI.js.map +1 -0
  98. package/dist/droid-KN6VRMMT.js +424 -0
  99. package/dist/droid-KN6VRMMT.js.map +1 -0
  100. package/dist/droid-W5WF5XEX.js +224 -0
  101. package/dist/droid-W5WF5XEX.js.map +1 -0
  102. package/dist/gemini-cli-CIRW37TU.js +369 -0
  103. package/dist/gemini-cli-CIRW37TU.js.map +1 -0
  104. package/dist/gemini-cli-Y35FFK4M.js +705 -0
  105. package/dist/gemini-cli-Y35FFK4M.js.map +1 -0
  106. package/dist/goose-A3M5GODH.js +212 -0
  107. package/dist/goose-A3M5GODH.js.map +1 -0
  108. package/dist/goose-ZTGTSUFJ.js +480 -0
  109. package/dist/goose-ZTGTSUFJ.js.map +1 -0
  110. package/dist/hermes-H2KV44GK.js +470 -0
  111. package/dist/hermes-H2KV44GK.js.map +1 -0
  112. package/dist/hermes-ZYLMOFLZ.js +196 -0
  113. package/dist/hermes-ZYLMOFLZ.js.map +1 -0
  114. package/dist/hook-YVDILAMZ.js +75 -0
  115. package/dist/hook-YVDILAMZ.js.map +1 -0
  116. package/dist/index.d.ts +22 -0
  117. package/dist/index.js +10 -0
  118. package/dist/index.js.map +1 -0
  119. package/dist/install-HQRYZOQ2.js +60 -0
  120. package/dist/install-HQRYZOQ2.js.map +1 -0
  121. package/dist/jetbrains-copilot-HWA3DMH7.js +633 -0
  122. package/dist/jetbrains-copilot-HWA3DMH7.js.map +1 -0
  123. package/dist/kilo-NSWAVP6P.js +235 -0
  124. package/dist/kilo-NSWAVP6P.js.map +1 -0
  125. package/dist/kilo-QXJRCSLT.js +384 -0
  126. package/dist/kilo-QXJRCSLT.js.map +1 -0
  127. package/dist/kilo-cli-EAQTHXUW.js +587 -0
  128. package/dist/kilo-cli-EAQTHXUW.js.map +1 -0
  129. package/dist/kilo-cli-EVBKUODA.js +160 -0
  130. package/dist/kilo-cli-EVBKUODA.js.map +1 -0
  131. package/dist/kimi-EI3UM3ZV.js +155 -0
  132. package/dist/kimi-EI3UM3ZV.js.map +1 -0
  133. package/dist/kimi-GQ7VXNYT.js +423 -0
  134. package/dist/kimi-GQ7VXNYT.js.map +1 -0
  135. package/dist/kiro-UCLSLBW2.js +217 -0
  136. package/dist/kiro-UCLSLBW2.js.map +1 -0
  137. package/dist/kiro-VQTT6LO2.js +451 -0
  138. package/dist/kiro-VQTT6LO2.js.map +1 -0
  139. package/dist/leaderboard-K6ON3SWW.js +137 -0
  140. package/dist/leaderboard-K6ON3SWW.js.map +1 -0
  141. package/dist/mux-T2TV4CIQ.js +211 -0
  142. package/dist/mux-T2TV4CIQ.js.map +1 -0
  143. package/dist/mux-ZMLVAXOO.js +96 -0
  144. package/dist/mux-ZMLVAXOO.js.map +1 -0
  145. package/dist/omp-PB4VDKS6.js +586 -0
  146. package/dist/omp-PB4VDKS6.js.map +1 -0
  147. package/dist/openclaw-ETN2M63O.js +751 -0
  148. package/dist/openclaw-ETN2M63O.js.map +1 -0
  149. package/dist/openclaw-IYA7ASL6.js +150 -0
  150. package/dist/openclaw-IYA7ASL6.js.map +1 -0
  151. package/dist/opencode-FZ33JKUZ.js +734 -0
  152. package/dist/opencode-FZ33JKUZ.js.map +1 -0
  153. package/dist/opencode-HWT3RSMN.js +216 -0
  154. package/dist/opencode-HWT3RSMN.js.map +1 -0
  155. package/dist/package-DLOVE2E4.js +1132 -0
  156. package/dist/package-DLOVE2E4.js.map +1 -0
  157. package/dist/pi-CIU2QHT4.js +208 -0
  158. package/dist/pi-CIU2QHT4.js.map +1 -0
  159. package/dist/pi-UFX2OYFV.js +139 -0
  160. package/dist/pi-UFX2OYFV.js.map +1 -0
  161. package/dist/qwen-code-5POCNU6P.js +573 -0
  162. package/dist/qwen-code-5POCNU6P.js.map +1 -0
  163. package/dist/qwen-code-W7NUCDEN.js +134 -0
  164. package/dist/qwen-code-W7NUCDEN.js.map +1 -0
  165. package/dist/roo-code-IOIUXRDE.js +242 -0
  166. package/dist/roo-code-IOIUXRDE.js.map +1 -0
  167. package/dist/roo-code-ZLKH4A7N.js +229 -0
  168. package/dist/roo-code-ZLKH4A7N.js.map +1 -0
  169. package/dist/runtime/index.d.ts +157 -0
  170. package/dist/runtime/index.js +20 -0
  171. package/dist/runtime/index.js.map +1 -0
  172. package/dist/serve-HVWWY4B6.js +65 -0
  173. package/dist/serve-HVWWY4B6.js.map +1 -0
  174. package/dist/status-FE7TECZD.js +128 -0
  175. package/dist/status-FE7TECZD.js.map +1 -0
  176. package/dist/synthetic-UKR6SMGS.js +178 -0
  177. package/dist/synthetic-UKR6SMGS.js.map +1 -0
  178. package/dist/telemetry-36GESKQQ.js +349 -0
  179. package/dist/telemetry-36GESKQQ.js.map +1 -0
  180. package/dist/trae-JSNDZFKL.js +204 -0
  181. package/dist/trae-JSNDZFKL.js.map +1 -0
  182. package/dist/trae-PA26DPBW.js +157 -0
  183. package/dist/trae-PA26DPBW.js.map +1 -0
  184. package/dist/types-CYUB1OTr.d.ts +427 -0
  185. package/dist/uninstall-IGCKNOSF.js +72 -0
  186. package/dist/uninstall-IGCKNOSF.js.map +1 -0
  187. package/dist/upgrade-JV2VK242.js +104 -0
  188. package/dist/upgrade-JV2VK242.js.map +1 -0
  189. package/dist/usage-6ER6EMEY.js +324 -0
  190. package/dist/usage-6ER6EMEY.js.map +1 -0
  191. package/dist/usage-event-JKBI6XCF.js +48 -0
  192. package/dist/usage-event-JKBI6XCF.js.map +1 -0
  193. package/dist/vscode-copilot-CK3NO54M.js +715 -0
  194. package/dist/vscode-copilot-CK3NO54M.js.map +1 -0
  195. package/dist/warp-JNQA7PBU.js +126 -0
  196. package/dist/warp-JNQA7PBU.js.map +1 -0
  197. package/dist/warp-QNVDXOG4.js +199 -0
  198. package/dist/warp-QNVDXOG4.js.map +1 -0
  199. package/dist/zed-NNNX5MNT.js +272 -0
  200. package/dist/zed-NNNX5MNT.js.map +1 -0
  201. package/dist/zed-VRJKWYUR.js +209 -0
  202. package/dist/zed-VRJKWYUR.js.map +1 -0
  203. package/package.json +79 -0
@@ -0,0 +1,423 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ resolveEnvRefsDeep
4
+ } from "./chunk-DBQMX75U.js";
5
+ import {
6
+ BaseAdapter
7
+ } from "./chunk-TIIP3RG2.js";
8
+ import "./chunk-7L6ITC4T.js";
9
+ import {
10
+ buildHomeBinHookCommand,
11
+ buildServeWrapperCommand,
12
+ isHomeBinHookCommand,
13
+ shouldWrapForTelemetry
14
+ } from "./chunk-MEH7GC7R.js";
15
+ import {
16
+ ensureDir
17
+ } from "./chunk-TRQKHP7D.js";
18
+
19
+ // src/adapters/kimi/index.ts
20
+ import { existsSync, readFileSync, writeFileSync } from "fs";
21
+ import { homedir } from "os";
22
+ import { dirname, join } from "path";
23
+ import TOML from "@iarna/toml";
24
+ var HOST = "kimi";
25
+ var MCP_ROOT_KEY = "mcpServers";
26
+ var KIMI_HOOK_EVENTS = ["PreToolUse"];
27
+ var PRE_TOOL_USE_MATCHER = "Bash|Shell|shell|exec_command|Read|Edit|Write|WebFetch|Agent|mcp__";
28
+ var KimiAdapter = class extends BaseAdapter {
29
+ id = HOST;
30
+ name = "Kimi CLI";
31
+ paradigm = "json-stdio";
32
+ capabilities = {
33
+ // PreToolUse deny is the only honored hook decision on Kimi CLI.
34
+ preToolUse: true,
35
+ postToolUse: false,
36
+ preCompact: false,
37
+ sessionStart: false,
38
+ sessionEnd: false,
39
+ userPromptSubmit: false,
40
+ stop: false,
41
+ notification: false,
42
+ // Kimi cannot rewrite args/output nor inject session context — deny-only.
43
+ canModifyArgs: false,
44
+ canModifyOutput: false,
45
+ canInjectSessionContext: false,
46
+ transports: ["stdio", "http"]
47
+ };
48
+ // ── Detection ────────────────────────────────────────────────────────────
49
+ detectInstalled(_projectDir) {
50
+ const baseDir = this.baseDir();
51
+ const mcpPath = join(baseDir, "mcp.json");
52
+ const configPath = join(baseDir, "config.toml");
53
+ const installed = existsSync(baseDir) || existsSync(mcpPath) || existsSync(configPath);
54
+ return {
55
+ id: this.id,
56
+ name: this.name,
57
+ installed,
58
+ paradigm: this.paradigm,
59
+ capabilities: this.capabilities,
60
+ configPath: mcpPath,
61
+ scope: "user",
62
+ reason: installed ? `found Kimi CLI config under ${baseDir}` : `no Kimi CLI config at ${baseDir}`,
63
+ // Path confidence is medium even when present: the ~/.kimi-code layout is the
64
+ // documented shape but less battle-tested than Claude/Codex.
65
+ confidence: "medium"
66
+ };
67
+ }
68
+ // ── Native paths ───────────────────────────────────────────────────────
69
+ getConfigDir(_ctx) {
70
+ return this.baseDir();
71
+ }
72
+ /** MCP registration file (JSON). */
73
+ getServerConfigPath(ctx) {
74
+ return join(this.getConfigDir(ctx), "mcp.json");
75
+ }
76
+ /** Hook registration file (TOML) — distinct from the MCP file. */
77
+ getHookConfigPath(ctx) {
78
+ return join(this.getConfigDir(ctx), "config.toml");
79
+ }
80
+ /**
81
+ * `$KIMI_HOME` || `$KIMI_CODE_HOME` (with `~` expansion) || `~/.kimi`.
82
+ * The real Moonshot Kimi CLI (v1.46.0) keeps its config under `~/.kimi`
83
+ * (mcp.json · mcpServers) — verified by a live `kimi mcp` probe; the legacy
84
+ * `~/.kimi-code` guess was wrong. `$KIMI_CODE_HOME` is still honored as an
85
+ * override for back-compat alongside the newer `$KIMI_HOME`.
86
+ */
87
+ baseDir() {
88
+ const env = process.env.KIMI_HOME ?? process.env.KIMI_CODE_HOME;
89
+ if (env && env.trim() !== "") {
90
+ if (env.startsWith("~")) {
91
+ return join(homedir(), env.replace(/^~[/\\]?/, ""));
92
+ }
93
+ return env;
94
+ }
95
+ return join(homedir(), ".kimi");
96
+ }
97
+ // ── MCP server install / uninstall (mcp.json → mcpServers.<id>) ──────────
98
+ installServer(ctx) {
99
+ const { connector } = ctx;
100
+ const override = connector.platforms[HOST]?.server;
101
+ if (!connector.server || override === false) {
102
+ return [
103
+ {
104
+ platform: this.id,
105
+ action: "skip",
106
+ detail: connector.server ? "server registration disabled for kimi" : "connector declares no MCP server"
107
+ }
108
+ ];
109
+ }
110
+ const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
111
+ const serverPath = this.getServerConfigPath(ctx);
112
+ const entry = this.renderServerEntry(ctx, server);
113
+ return [
114
+ this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
115
+ ];
116
+ }
117
+ uninstallServer(ctx) {
118
+ const serverPath = this.getServerConfigPath(ctx);
119
+ return [
120
+ this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
121
+ ];
122
+ }
123
+ /**
124
+ * Render a normalized ServerDef into Kimi's native mcpServers entry. Kimi's
125
+ * mcp.json has no documented native interpolation, so `${env:VAR}` refs are
126
+ * resolved to literals at install time (same posture as the TOML hosts).
127
+ */
128
+ renderServerEntry(ctx, server) {
129
+ const transport = server.transport;
130
+ if (transport === "stdio") {
131
+ let command = server.command ?? "";
132
+ let args = [...server.args ?? []];
133
+ if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
134
+ const wrapped = buildServeWrapperCommand(
135
+ ctx.homeBinPath,
136
+ ctx.connector.id,
137
+ command,
138
+ args,
139
+ ctx.scope,
140
+ this.id
141
+ );
142
+ command = wrapped.command;
143
+ args = wrapped.args;
144
+ }
145
+ command = resolveEnvRefsDeep(command);
146
+ args = resolveEnvRefsDeep(args);
147
+ const entry2 = { command };
148
+ if (args.length > 0) entry2.args = args;
149
+ const env = this.renderEnv(server.env);
150
+ if (env) entry2.env = env;
151
+ return entry2;
152
+ }
153
+ const entry = { url: resolveEnvRefsDeep(server.url ?? "") };
154
+ const headers = this.renderEnv(server.headers);
155
+ if (headers) entry.headers = headers;
156
+ return entry;
157
+ }
158
+ /** Resolve env/header values to literals (no native interpolation on Kimi). */
159
+ renderEnv(env) {
160
+ if (!env || Object.keys(env).length === 0) return void 0;
161
+ const out = {};
162
+ for (const [k, v] of Object.entries(resolveEnvRefsDeep(env))) {
163
+ out[k] = String(v);
164
+ }
165
+ return out;
166
+ }
167
+ // ── Hook install / uninstall (config.toml → [[hooks]]) ───────────────────
168
+ installHooks(ctx) {
169
+ const { connector } = ctx;
170
+ if (connector.platforms[HOST]?.hooks === false) {
171
+ return [{ platform: this.id, action: "skip", detail: "hooks disabled for kimi" }];
172
+ }
173
+ const events = this.effectiveHookEvents(ctx);
174
+ const path = this.getHookConfigPath(ctx);
175
+ if (events.length === 0) {
176
+ return [{ platform: this.id, action: "skip", path, detail: "no hooks declared" }];
177
+ }
178
+ const cfg = this.readToml(path);
179
+ const hooks = cfg.hooks ??= [];
180
+ const changes = [];
181
+ let mutated = false;
182
+ for (const event of events) {
183
+ const desired = this.renderHook(ctx, event);
184
+ const idx = hooks.findIndex((h) => this.isOurHook(ctx, h));
185
+ if (idx < 0) {
186
+ hooks.push(desired);
187
+ changes.push({ platform: this.id, action: "create", path, detail: `hooks.${event}` });
188
+ mutated = true;
189
+ } else if (JSON.stringify(hooks[idx]) !== JSON.stringify(desired)) {
190
+ hooks[idx] = desired;
191
+ changes.push({ platform: this.id, action: "update", path, detail: `hooks.${event}` });
192
+ mutated = true;
193
+ } else {
194
+ changes.push({ platform: this.id, action: "skip", path, detail: `hooks.${event}` });
195
+ }
196
+ }
197
+ if (mutated) this.writeToml(path, cfg, ctx.dryRun);
198
+ return changes;
199
+ }
200
+ uninstallHooks(ctx) {
201
+ const path = this.getHookConfigPath(ctx);
202
+ if (!existsSync(path)) {
203
+ return [{ platform: this.id, action: "skip", path, detail: "no config.toml" }];
204
+ }
205
+ const cfg = this.readToml(path);
206
+ const hooks = cfg.hooks;
207
+ if (!Array.isArray(hooks) || hooks.length === 0) {
208
+ return [{ platform: this.id, action: "skip", path, detail: "no hooks present" }];
209
+ }
210
+ const kept = hooks.filter((h) => !this.isOurHook(ctx, h));
211
+ const removed = hooks.length - kept.length;
212
+ if (removed === 0) {
213
+ return [{ platform: this.id, action: "skip", path, detail: "no agent-connector hooks present" }];
214
+ }
215
+ if (kept.length > 0) cfg.hooks = kept;
216
+ else delete cfg.hooks;
217
+ this.writeToml(path, cfg, ctx.dryRun);
218
+ return [{ platform: this.id, action: "remove", path, detail: `hooks (${removed})` }];
219
+ }
220
+ // ── Diagnostics ──────────────────────────────────────────────────────────
221
+ getHealthChecks(ctx) {
222
+ const serverPath = this.getServerConfigPath(ctx);
223
+ const hookPath = this.getHookConfigPath(ctx);
224
+ const connectorId = ctx.connector.id;
225
+ const homeBin = ctx.homeBinPath;
226
+ const hookEvents = this.effectiveHookEvents(ctx);
227
+ return [
228
+ {
229
+ name: `${this.name}: mcp.json present`,
230
+ check: () => existsSync(serverPath) ? { status: "OK", detail: serverPath } : { status: "FAIL", detail: `not found: ${serverPath}` }
231
+ },
232
+ {
233
+ name: `${this.name}: mcpServers.${connectorId} registered`,
234
+ check: () => {
235
+ const cfg = this.readJson(serverPath);
236
+ const bucket = cfg?.[MCP_ROOT_KEY];
237
+ const present = typeof bucket === "object" && bucket !== null && connectorId in bucket;
238
+ return present ? { status: "OK", detail: `mcpServers.${connectorId}` } : { status: "FAIL", detail: `mcpServers.${connectorId} not found in ${serverPath}` };
239
+ }
240
+ },
241
+ {
242
+ name: `${this.name}: hook command registered`,
243
+ check: () => {
244
+ if (hookEvents.length === 0) {
245
+ return { status: "OK", detail: "no hooks declared" };
246
+ }
247
+ if (!existsSync(hookPath)) {
248
+ return { status: "FAIL", detail: `not found: ${hookPath}` };
249
+ }
250
+ const cfg = this.readToml(hookPath);
251
+ const registered = (cfg.hooks ?? []).some(
252
+ (h) => isHomeBinHookCommand(h?.command, homeBin, connectorId)
253
+ );
254
+ return registered ? { status: "OK", detail: "hook command present" } : { status: "FAIL", detail: `no hook for ${connectorId} in ${hookPath}` };
255
+ }
256
+ }
257
+ ];
258
+ }
259
+ // ── Runtime: parse Kimi stdin JSON → normalized event ────────────────────
260
+ parseEvent(event, raw) {
261
+ const input = raw ?? {};
262
+ const connectorId = typeof input.connector === "string" ? input.connector : "";
263
+ const sessionId = input.session_id ?? `pid-${process.ppid}`;
264
+ const projectDir = input.cwd ?? process.env.KIMI_PROJECT_DIR ?? process.cwd();
265
+ const base = {
266
+ hostPlatform: HOST,
267
+ connectorId,
268
+ sessionId,
269
+ projectDir,
270
+ raw
271
+ };
272
+ switch (event) {
273
+ case "PreToolUse": {
274
+ const ev = {
275
+ ...base,
276
+ toolName: input.tool_name ?? "",
277
+ toolInput: input.tool_input ?? {}
278
+ };
279
+ return ev;
280
+ }
281
+ case "PostToolUse": {
282
+ const ev = {
283
+ ...base,
284
+ toolName: input.tool_name ?? "",
285
+ toolInput: input.tool_input ?? {},
286
+ ...toolResponseToString(input.tool_response) !== void 0 ? { toolOutput: toolResponseToString(input.tool_response) } : {},
287
+ isError: input.is_error ?? false
288
+ };
289
+ return ev;
290
+ }
291
+ case "SessionStart": {
292
+ const ev = {
293
+ ...base,
294
+ source: normalizeSessionSource(input.source)
295
+ };
296
+ return ev;
297
+ }
298
+ case "SessionEnd": {
299
+ const ev = {
300
+ ...base,
301
+ ...typeof input.message === "string" ? { reason: input.message } : {}
302
+ };
303
+ return ev;
304
+ }
305
+ case "UserPromptSubmit": {
306
+ const ev = {
307
+ ...base,
308
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
309
+ };
310
+ return ev;
311
+ }
312
+ case "PreCompact": {
313
+ const ev = {
314
+ ...base,
315
+ ...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
316
+ };
317
+ return ev;
318
+ }
319
+ case "Stop": {
320
+ const ev = {
321
+ ...base,
322
+ ...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
323
+ };
324
+ return ev;
325
+ }
326
+ case "Notification": {
327
+ const ev = {
328
+ ...base,
329
+ message: typeof input.message === "string" ? input.message : ""
330
+ };
331
+ return ev;
332
+ }
333
+ default: {
334
+ const _never = event;
335
+ throw new Error(`unsupported kimi hook event: ${String(_never)}`);
336
+ }
337
+ }
338
+ }
339
+ // ── Runtime: normalized response → Kimi native hook reply ────────────────
340
+ formatReply(event, response) {
341
+ const decision = response.decision ?? "allow";
342
+ if (decision === "deny" && event === "PreToolUse") {
343
+ return {
344
+ exitCode: 0,
345
+ stdout: JSON.stringify({
346
+ hookSpecificOutput: {
347
+ hookEventName: "PreToolUse",
348
+ permissionDecision: "deny",
349
+ permissionDecisionReason: response.reason ?? "Blocked by hook"
350
+ }
351
+ })
352
+ };
353
+ }
354
+ return { exitCode: 0 };
355
+ }
356
+ // ── Internal helpers ───────────────────────────────────────────────────
357
+ /** Which canonical hook events to register for Kimi, honoring overrides. */
358
+ effectiveHookEvents(ctx) {
359
+ if (ctx.connector.platforms[HOST]?.hooks === false) return [];
360
+ return KIMI_HOOK_EVENTS.filter((e) => ctx.connector.hookEvents.includes(e));
361
+ }
362
+ /** Render one `[[hooks]]` entry pointing at the stable home binary. */
363
+ renderHook(ctx, event) {
364
+ const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, ctx.connector.id);
365
+ return {
366
+ event,
367
+ matcher: event === "PreToolUse" ? PRE_TOOL_USE_MATCHER : "",
368
+ command
369
+ };
370
+ }
371
+ /**
372
+ * Does this `[[hooks]]` entry belong to this connector? Anchored on the
373
+ * home-bin + connector-id token (isHomeBinHookCommand) so uninstalling a
374
+ * shared-prefix connector id never strips a sibling's hook.
375
+ */
376
+ isOurHook(ctx, hook) {
377
+ if (!hook || typeof hook !== "object") return false;
378
+ return isHomeBinHookCommand(hook.command, ctx.homeBinPath, ctx.connector.id);
379
+ }
380
+ // ── TOML config IO (config.toml is TOML; MCP stays JSON via BaseAdapter) ──
381
+ readToml(path) {
382
+ if (!existsSync(path)) return {};
383
+ try {
384
+ return TOML.parse(readFileSync(path, "utf8"));
385
+ } catch {
386
+ return {};
387
+ }
388
+ }
389
+ writeToml(path, data, dryRun) {
390
+ if (dryRun) return;
391
+ ensureDir(dirname(path));
392
+ writeFileSync(path, TOML.stringify(data), "utf8");
393
+ }
394
+ };
395
+ function toolResponseToString(value) {
396
+ if (value === void 0 || value === null) return void 0;
397
+ if (typeof value === "string") return value;
398
+ try {
399
+ return JSON.stringify(value);
400
+ } catch {
401
+ return void 0;
402
+ }
403
+ }
404
+ function normalizeSessionSource(source) {
405
+ switch (source) {
406
+ case "compact":
407
+ return "compact";
408
+ case "resume":
409
+ return "resume";
410
+ case "clear":
411
+ return "clear";
412
+ default:
413
+ return "startup";
414
+ }
415
+ }
416
+ var adapter = new KimiAdapter();
417
+ var kimi_default = adapter;
418
+ export {
419
+ KimiAdapter,
420
+ adapter,
421
+ kimi_default as default
422
+ };
423
+ //# sourceMappingURL=kimi-GQ7VXNYT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/kimi/index.ts"],"sourcesContent":["/**\n * adapters/kimi — Kimi CLI (Moonshot) platform adapter for agent-connector.\n *\n * Kimi CLI is a json-stdio host: the runner pipes a JSON payload to a command on\n * stdin and reads an exit code (and optional reason) back. Two native config\n * files live under the Kimi base dir (`$KIMI_HOME` || `$KIMI_CODE_HOME` || `~/.kimi`):\n * - mcp.json → `mcpServers.<id>` MCP registration (JSON, stdio shape:\n * {command,args,env}). Handled via BaseAdapter's JSON helpers.\n * - config.toml → `[[hooks]]` array-of-tables (TOML), each table\n * { event, matcher, command }. Parsed/serialized with @iarna/toml: every\n * config VALUE (unrelated sections, sibling hooks, scalars) is preserved,\n * but a parse→stringify round-trip does NOT preserve user COMMENTS or the\n * original key ordering/formatting in config.toml (values survive; comments\n * and layout do not).\n *\n * Hook surface is intentionally narrow: Kimi CLI only honors a PreToolUse DENY.\n * It cannot rewrite tool args, rewrite tool output, or inject session context —\n * so every other decision degrades to a silent allow (exit 0). Kimi Code uses\n * the Claude/Codex reply shape: a PreToolUse deny is signalled with EXIT 0 plus\n * a `hookSpecificOutput` JSON object on stdout carrying\n * permissionDecision:\"deny\" + permissionDecisionReason — that is how Kimi's\n * runner blocks the pending tool call. An allow is exit 0 with empty stdout.\n *\n * Path confidence: the `~/.kimi` base + mcp.json (`mcpServers`) layout is\n * LIVE-CONFIRMED against the real Moonshot Kimi CLI (v1.46.0, `pip install\n * kimi-cli`) via a `kimi mcp` probe. We still install + doctor-report presence\n * so a future path move surfaces as a FAIL rather than silently misbehaving.\n *\n * FUTURE COVERAGE (non-functional note — no behavior change here): this adapter\n * intentionally wires only PreToolUse, but Kimi CLI actually supports a much\n * wider event surface — Stop, UserPromptSubmit, PostToolUse, SessionStart,\n * SessionEnd, PreCompact, Notification, and SubagentStart/SubagentStop. Kimi\n * also has a PLUGIN system (plugins live at\n * `<base>/plugins/<name>/kimi.plugin.json`) and a SKILLS surface\n * (`~/.kimi/skills/`). None of these are covered yet; they are flagged here\n * as candidates for a future events/plugins/skills expansion of the adapter.\n */\n\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport TOML from \"@iarna/toml\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookEventName,\n HookParadigm,\n HookResponse,\n NotificationEvent,\n PlatformCapabilities,\n PlatformId,\n PostToolUseEvent,\n PreCompactEvent,\n PreToolUseEvent,\n SessionEndEvent,\n SessionStartEvent,\n ServerDef,\n StopEvent,\n Transport,\n UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { ensureDir } from \"../../core/paths.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildHomeBinHookCommand,\n buildServeWrapperCommand,\n isHomeBinHookCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"kimi\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Native shapes\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Raw Kimi CLI hook payload (Claude-style: PascalCase event, snake_case fields). */\ninterface KimiHookInput {\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: unknown;\n session_id?: string;\n cwd?: string;\n hook_event_name?: string;\n source?: string;\n prompt?: string;\n is_error?: boolean;\n stop_hook_active?: boolean;\n trigger?: string;\n message?: string;\n reason?: string;\n connector?: string;\n}\n\n/** One `[[hooks]]` array-of-tables entry as Kimi stores it in config.toml. */\ninterface KimiTomlHook {\n event: string;\n matcher?: string;\n command: string;\n [key: string]: unknown;\n}\n\n/** Parsed config.toml shape we care about (rest preserved verbatim). */\ninterface KimiConfigToml {\n hooks?: KimiTomlHook[];\n [key: string]: unknown;\n}\n\n/** Native stdio MCP server entry under `mcpServers`. */\ninterface KimiStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n/** Native remote MCP server entry under `mcpServers`. */\ninterface KimiHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\n/**\n * Kimi CLI hook events agent-connector can register. Only PreToolUse carries a\n * meaningful (deny) decision; it is the single event we wire. The matcher below\n * is charset-clean (Rust-regex safe: no look-around) so Kimi's matcher accepts\n * it. Copied in spirit from the Codex/context-mode matchers.\n */\nconst KIMI_HOOK_EVENTS = [\"PreToolUse\"] as const;\ntype KimiHookEventName = (typeof KIMI_HOOK_EVENTS)[number];\n\nconst PRE_TOOL_USE_MATCHER =\n \"Bash|Shell|shell|exec_command|Read|Edit|Write|WebFetch|Agent|mcp__\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Adapter\n// ─────────────────────────────────────────────────────────────────────────\n\nexport class KimiAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Kimi CLI\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n // PreToolUse deny is the only honored hook decision on Kimi CLI.\n preToolUse: true,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // Kimi cannot rewrite args/output nor inject session context — deny-only.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n transports: [\"stdio\", \"http\"],\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const baseDir = this.baseDir();\n const mcpPath = join(baseDir, \"mcp.json\");\n const configPath = join(baseDir, \"config.toml\");\n const installed = existsSync(baseDir) || existsSync(mcpPath) || existsSync(configPath);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath: mcpPath,\n scope: \"user\",\n reason: installed\n ? `found Kimi CLI config under ${baseDir}`\n : `no Kimi CLI config at ${baseDir}`,\n // Path confidence is medium even when present: the ~/.kimi-code layout is the\n // documented shape but less battle-tested than Claude/Codex.\n confidence: \"medium\",\n };\n }\n\n // ── Native paths ───────────────────────────────────────────────────────\n\n getConfigDir(_ctx: InstallContext): string {\n return this.baseDir();\n }\n\n /** MCP registration file (JSON). */\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /** Hook registration file (TOML) — distinct from the MCP file. */\n getHookConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"config.toml\");\n }\n\n /**\n * `$KIMI_HOME` || `$KIMI_CODE_HOME` (with `~` expansion) || `~/.kimi`.\n * The real Moonshot Kimi CLI (v1.46.0) keeps its config under `~/.kimi`\n * (mcp.json · mcpServers) — verified by a live `kimi mcp` probe; the legacy\n * `~/.kimi-code` guess was wrong. `$KIMI_CODE_HOME` is still honored as an\n * override for back-compat alongside the newer `$KIMI_HOME`.\n */\n private baseDir(): string {\n const env = process.env.KIMI_HOME ?? process.env.KIMI_CODE_HOME;\n if (env && env.trim() !== \"\") {\n if (env.startsWith(\"~\")) {\n return join(homedir(), env.replace(/^~[/\\\\]?/, \"\"));\n }\n return env;\n }\n return join(homedir(), \".kimi\");\n }\n\n // ── MCP server install / uninstall (mcp.json → mcpServers.<id>) ──────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for kimi\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /**\n * Render a normalized ServerDef into Kimi's native mcpServers entry. Kimi's\n * mcp.json has no documented native interpolation, so `${env:VAR}` refs are\n * resolved to literals at install time (same posture as the TOML hosts).\n */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): KimiStdioServer | KimiHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n ctx.homeBinPath,\n ctx.connector.id,\n command,\n args,\n ctx.scope,\n this.id,\n );\n command = wrapped.command;\n args = wrapped.args;\n }\n\n command = resolveEnvRefsDeep(command);\n args = resolveEnvRefsDeep(args);\n\n const entry: KimiStdioServer = { command };\n if (args.length > 0) entry.args = args;\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // http (and any other remote transport) — Kimi registers a URL entry.\n const entry: KimiHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /** Resolve env/header values to literals (no native interpolation on Kimi). */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(env))) {\n out[k] = String(v);\n }\n return out;\n }\n\n // ── Hook install / uninstall (config.toml → [[hooks]]) ───────────────────\n\n installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.hooks === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"hooks disabled for kimi\" }];\n }\n\n const events = this.effectiveHookEvents(ctx);\n const path = this.getHookConfigPath(ctx);\n\n if (events.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks declared\" }];\n }\n\n const cfg = this.readToml(path);\n const hooks = (cfg.hooks ??= []);\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of events) {\n const desired = this.renderHook(ctx, event);\n const idx = hooks.findIndex((h) => this.isOurHook(ctx, h));\n if (idx < 0) {\n hooks.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `hooks.${event}` });\n mutated = true;\n } else if (JSON.stringify(hooks[idx]) !== JSON.stringify(desired)) {\n hooks[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `hooks.${event}` });\n mutated = true;\n } else {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `hooks.${event}` });\n }\n }\n\n if (mutated) this.writeToml(path, cfg, ctx.dryRun);\n return changes;\n }\n\n uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n if (!existsSync(path)) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no config.toml\" }];\n }\n const cfg = this.readToml(path);\n const hooks = cfg.hooks;\n if (!Array.isArray(hooks) || hooks.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks present\" }];\n }\n\n const kept = hooks.filter((h) => !this.isOurHook(ctx, h));\n const removed = hooks.length - kept.length;\n if (removed === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no agent-connector hooks present\" }];\n }\n\n if (kept.length > 0) cfg.hooks = kept;\n else delete cfg.hooks;\n this.writeToml(path, cfg, ctx.dryRun);\n return [{ platform: this.id, action: \"remove\", path, detail: `hooks (${removed})` }];\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const serverPath = this.getServerConfigPath(ctx);\n const hookPath = this.getHookConfigPath(ctx);\n const connectorId = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = this.effectiveHookEvents(ctx);\n return [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: mcpServers.${connectorId} registered`,\n check: () => {\n const cfg = this.readJson<Record<string, Record<string, unknown>>>(serverPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n const present =\n typeof bucket === \"object\" && bucket !== null && connectorId in bucket;\n return present\n ? { status: \"OK\", detail: `mcpServers.${connectorId}` }\n : { status: \"FAIL\", detail: `mcpServers.${connectorId} not found in ${serverPath}` };\n },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) {\n return { status: \"OK\", detail: \"no hooks declared\" };\n }\n if (!existsSync(hookPath)) {\n return { status: \"FAIL\", detail: `not found: ${hookPath}` };\n }\n const cfg = this.readToml(hookPath);\n const registered = (cfg.hooks ?? []).some((h) =>\n isHomeBinHookCommand(h?.command, homeBin, connectorId),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${connectorId} in ${hookPath}` };\n },\n },\n ];\n }\n\n // ── Runtime: parse Kimi stdin JSON → normalized event ────────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as KimiHookInput;\n const connectorId = typeof input.connector === \"string\" ? input.connector : \"\";\n const sessionId = input.session_id ?? `pid-${process.ppid}`;\n const projectDir = input.cwd ?? process.env.KIMI_PROJECT_DIR ?? process.cwd();\n\n const base = {\n hostPlatform: HOST,\n connectorId,\n sessionId,\n projectDir,\n raw,\n } as const;\n\n switch (event) {\n case \"PreToolUse\": {\n const ev: PreToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n };\n return ev;\n }\n case \"PostToolUse\": {\n const ev: PostToolUseEvent = {\n ...base,\n toolName: input.tool_name ?? \"\",\n toolInput: input.tool_input ?? {},\n ...(toolResponseToString(input.tool_response) !== undefined\n ? { toolOutput: toolResponseToString(input.tool_response) }\n : {}),\n isError: input.is_error ?? false,\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = {\n ...base,\n source: normalizeSessionSource(input.source),\n };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.message === \"string\" ? { reason: input.message } : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"PreCompact\": {\n const ev: PreCompactEvent = {\n ...base,\n ...(input.trigger === \"auto\" || input.trigger === \"manual\"\n ? { trigger: input.trigger }\n : {}),\n };\n return ev;\n }\n case \"Stop\": {\n const ev: StopEvent = {\n ...base,\n ...(typeof input.stop_hook_active === \"boolean\"\n ? { stopHookActive: input.stop_hook_active }\n : {}),\n };\n return ev;\n }\n case \"Notification\": {\n const ev: NotificationEvent = {\n ...base,\n message: typeof input.message === \"string\" ? input.message : \"\",\n };\n return ev;\n }\n default: {\n const _never: never = event;\n throw new Error(`unsupported kimi hook event: ${String(_never)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Kimi native hook reply ────────────────\n\n formatReply(event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // deny → block the pending tool call. Kimi Code uses the Claude/Codex reply\n // shape: EXIT 0 + a `hookSpecificOutput` JSON object on stdout carrying\n // permissionDecision:\"deny\". Only PreToolUse deny is honored; every other\n // event (or decision) degrades to a silent allow.\n if (decision === \"deny\" && event === \"PreToolUse\") {\n return {\n exitCode: 0,\n stdout: JSON.stringify({\n hookSpecificOutput: {\n hookEventName: \"PreToolUse\",\n permissionDecision: \"deny\",\n permissionDecisionReason: response.reason ?? \"Blocked by hook\",\n },\n }),\n };\n }\n\n // allow / modify / context / ask / unsupported-event → passthrough (exit 0,\n // empty stdout). Kimi cannot rewrite args/output or inject context, so those\n // are dropped.\n return { exitCode: 0 };\n }\n\n // ── Internal helpers ───────────────────────────────────────────────────\n\n /** Which canonical hook events to register for Kimi, honoring overrides. */\n private effectiveHookEvents(ctx: InstallContext): KimiHookEventName[] {\n if (ctx.connector.platforms[HOST]?.hooks === false) return [];\n return KIMI_HOOK_EVENTS.filter((e) => ctx.connector.hookEvents.includes(e));\n }\n\n /** Render one `[[hooks]]` entry pointing at the stable home binary. */\n private renderHook(ctx: InstallContext, event: KimiHookEventName): KimiTomlHook {\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, ctx.connector.id);\n return {\n event,\n matcher: event === \"PreToolUse\" ? PRE_TOOL_USE_MATCHER : \"\",\n command,\n };\n }\n\n /**\n * Does this `[[hooks]]` entry belong to this connector? Anchored on the\n * home-bin + connector-id token (isHomeBinHookCommand) so uninstalling a\n * shared-prefix connector id never strips a sibling's hook.\n */\n private isOurHook(ctx: InstallContext, hook: KimiTomlHook | undefined): boolean {\n if (!hook || typeof hook !== \"object\") return false;\n return isHomeBinHookCommand(hook.command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── TOML config IO (config.toml is TOML; MCP stays JSON via BaseAdapter) ──\n\n private readToml(path: string): KimiConfigToml {\n if (!existsSync(path)) return {};\n try {\n return TOML.parse(readFileSync(path, \"utf8\")) as unknown as KimiConfigToml;\n } catch {\n return {};\n }\n }\n\n private writeToml(path: string, data: KimiConfigToml, dryRun: boolean): void {\n if (dryRun) return;\n ensureDir(dirname(path));\n // NOTE: a @iarna/toml parse→stringify round-trip preserves config VALUES but\n // NOT user comments or the original key ordering/formatting in config.toml.\n // Values are safe; comments authored by the user are not preserved.\n writeFileSync(path, TOML.stringify(data as never), \"utf8\");\n }\n}\n\n/** Best-effort stringify of Kimi's tool_response into a normalized toolOutput. */\nfunction toolResponseToString(value: unknown): string | undefined {\n if (value === undefined || value === null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return undefined;\n }\n}\n\nfunction normalizeSessionSource(source: string | undefined): SessionStartEvent[\"source\"] {\n switch (source) {\n case \"compact\":\n return \"compact\";\n case \"resume\":\n return \"resume\";\n case \"clear\":\n return \"clear\";\n default:\n return \"startup\";\n }\n}\n\nexport const adapter = new KimiAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}