@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,480 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ readYaml,
4
+ writeYaml
5
+ } from "./chunk-EXLS7BSI.js";
6
+ import {
7
+ resolveEnvRefsDeep
8
+ } from "./chunk-DBQMX75U.js";
9
+ import {
10
+ BaseAdapter
11
+ } from "./chunk-TIIP3RG2.js";
12
+ import "./chunk-7L6ITC4T.js";
13
+ import {
14
+ buildHomeBinHookCommand,
15
+ buildServeWrapperCommand,
16
+ isHomeBinHookCommand,
17
+ shouldWrapForTelemetry
18
+ } from "./chunk-MEH7GC7R.js";
19
+ import {
20
+ ensureDir
21
+ } from "./chunk-TRQKHP7D.js";
22
+
23
+ // src/adapters/goose/index.ts
24
+ import { existsSync, writeFileSync } from "fs";
25
+ import { homedir } from "os";
26
+ import { dirname, join } from "path";
27
+ var HOST = "goose";
28
+ var MCP_ROOT_KEY = "extensions";
29
+ var EVENT_CAPABILITY = {
30
+ SessionStart: "sessionStart",
31
+ SessionEnd: "sessionEnd",
32
+ UserPromptSubmit: "userPromptSubmit",
33
+ PreToolUse: "preToolUse",
34
+ PostToolUse: "postToolUse",
35
+ PreCompact: "preCompact",
36
+ Stop: "stop",
37
+ Notification: "notification"
38
+ };
39
+ var GooseAdapter = class extends BaseAdapter {
40
+ id = HOST;
41
+ name = "Goose";
42
+ paradigm = "json-stdio";
43
+ capabilities = {
44
+ preToolUse: true,
45
+ postToolUse: true,
46
+ preCompact: false,
47
+ sessionStart: true,
48
+ sessionEnd: false,
49
+ userPromptSubmit: false,
50
+ stop: false,
51
+ notification: false,
52
+ // Open Plugins documents PreToolUse/PostToolUse/SessionStart; argument
53
+ // rewrite is not guaranteed across versions, so default to the safe value.
54
+ canModifyArgs: false,
55
+ canModifyOutput: false,
56
+ canInjectSessionContext: true,
57
+ transports: ["stdio", "sse", "http"]
58
+ };
59
+ // ── Detection ────────────────────────────────────────────────────────────
60
+ detectInstalled(_projectDir) {
61
+ const configPath = this.userConfigPath();
62
+ const configDir = dirname(configPath);
63
+ const installed = existsSync(configDir) || existsSync(configPath);
64
+ return {
65
+ id: this.id,
66
+ name: this.name,
67
+ installed,
68
+ paradigm: this.paradigm,
69
+ capabilities: this.capabilities,
70
+ configPath,
71
+ scope: "user",
72
+ reason: installed ? `found Goose config at ${configPath}` : `no Goose config at ${configPath}`,
73
+ confidence: installed ? "high" : "low"
74
+ };
75
+ }
76
+ // ── Native paths ─────────────────────────────────────────────────────────
77
+ getConfigDir(_ctx) {
78
+ return dirname(this.userConfigPath());
79
+ }
80
+ /** MCP config: the YAML config.yaml (user scope). */
81
+ getServerConfigPath(_ctx) {
82
+ return this.userConfigPath();
83
+ }
84
+ /**
85
+ * Hooks: Open-Plugins hooks.json under the `.agents/plugins/<plugin-name>/`
86
+ * dir. The connector id is the plugin name. Project scope roots at
87
+ * `<projectDir>/.agents`; user scope roots at `~/.agents`.
88
+ */
89
+ getHookConfigPath(ctx) {
90
+ const root = ctx.scope === "project" ? ctx.projectDir : homedir();
91
+ return join(root, ".agents", "plugins", ctx.connector.id, "hooks", "hooks.json");
92
+ }
93
+ /**
94
+ * OS-correct user config.yaml path:
95
+ * - Windows: %APPDATA%/Block/goose/config/config.yaml
96
+ * - macOS/Linux: ~/.config/goose/config.yaml
97
+ */
98
+ userConfigPath() {
99
+ if (process.platform === "win32") {
100
+ const appData = process.env.APPDATA && process.env.APPDATA.trim() !== "" ? process.env.APPDATA : join(homedir(), "AppData", "Roaming");
101
+ return join(appData, "Block", "goose", "config", "config.yaml");
102
+ }
103
+ return join(homedir(), ".config", "goose", "config.yaml");
104
+ }
105
+ // ── MCP server install / uninstall (YAML — merge via readYaml/writeYaml) ──
106
+ installServer(ctx) {
107
+ const { connector, dryRun } = ctx;
108
+ const path = this.getServerConfigPath(ctx);
109
+ const server = this.effectiveServer(ctx);
110
+ if (!server) {
111
+ return [
112
+ {
113
+ platform: this.id,
114
+ action: "skip",
115
+ path,
116
+ detail: connector.server ? "server registration disabled for goose" : "connector declares no MCP server"
117
+ }
118
+ ];
119
+ }
120
+ const entry = this.renderExtension(ctx, server);
121
+ const cfg = readYaml(path) ?? {};
122
+ const bucketRaw = cfg[MCP_ROOT_KEY];
123
+ const bucket = bucketRaw && typeof bucketRaw === "object" && !Array.isArray(bucketRaw) ? bucketRaw : {};
124
+ cfg[MCP_ROOT_KEY] = bucket;
125
+ const before = JSON.stringify(bucket[connector.id]);
126
+ const after = JSON.stringify(entry);
127
+ let action;
128
+ if (before === void 0) action = "create";
129
+ else if (before === after) action = "skip";
130
+ else action = "update";
131
+ if (action !== "skip") {
132
+ bucket[connector.id] = entry;
133
+ writeYaml(path, cfg, dryRun);
134
+ }
135
+ return [{ platform: this.id, action, path, detail: `${MCP_ROOT_KEY}.${connector.id}` }];
136
+ }
137
+ uninstallServer(ctx) {
138
+ const { connector, dryRun } = ctx;
139
+ const path = this.getServerConfigPath(ctx);
140
+ const cfg = readYaml(path);
141
+ const bucketRaw = cfg?.[MCP_ROOT_KEY];
142
+ if (!cfg || !bucketRaw || typeof bucketRaw !== "object" || Array.isArray(bucketRaw) || !(connector.id in bucketRaw)) {
143
+ return [
144
+ {
145
+ platform: this.id,
146
+ action: "skip",
147
+ path,
148
+ detail: `${MCP_ROOT_KEY}.${connector.id} absent`
149
+ }
150
+ ];
151
+ }
152
+ delete bucketRaw[connector.id];
153
+ writeYaml(path, cfg, dryRun);
154
+ return [
155
+ { platform: this.id, action: "remove", path, detail: `${MCP_ROOT_KEY}.${connector.id}` }
156
+ ];
157
+ }
158
+ /**
159
+ * Render a normalized ServerDef into Goose's native extension entry. Goose has
160
+ * no native env interpolation, so `${env:VAR}` refs are resolved to literals at
161
+ * install time. Honors the telemetry serve-wrapper (cmd=homeBin, args=[serve…]).
162
+ */
163
+ renderExtension(ctx, server) {
164
+ let cmd = server.command ?? "";
165
+ let args = [...server.args ?? []];
166
+ if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
167
+ const wrapped = buildServeWrapperCommand(
168
+ ctx.homeBinPath,
169
+ ctx.connector.id,
170
+ cmd,
171
+ args,
172
+ ctx.scope,
173
+ this.id
174
+ );
175
+ cmd = wrapped.command;
176
+ args = wrapped.args;
177
+ }
178
+ cmd = resolveEnvRefsDeep(cmd);
179
+ args = resolveEnvRefsDeep(args);
180
+ const timeoutMs = server.timeoutMs;
181
+ const timeout = typeof timeoutMs === "number" && timeoutMs > 0 ? Math.round(timeoutMs / 1e3) : 300;
182
+ const entry = {
183
+ type: "stdio",
184
+ cmd,
185
+ args,
186
+ timeout,
187
+ enabled: server.enabled !== false
188
+ };
189
+ if (server.env && Object.keys(server.env).length > 0) {
190
+ const envs = {};
191
+ for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {
192
+ envs[k] = String(v);
193
+ }
194
+ entry.envs = envs;
195
+ }
196
+ return entry;
197
+ }
198
+ // ── Hook install / uninstall (JSON Open-Plugins hooks.json) ───────────────
199
+ installHooks(ctx) {
200
+ const { connector, dryRun } = ctx;
201
+ const path = this.getHookConfigPath(ctx);
202
+ if (connector.platforms[HOST]?.hooks === false) {
203
+ return [{ platform: this.id, action: "skip", path, detail: "hooks disabled for goose" }];
204
+ }
205
+ const events = connector.hookEvents;
206
+ if (events.length === 0) {
207
+ return [{ platform: this.id, action: "skip", path, detail: "connector declares no hooks" }];
208
+ }
209
+ const file = this.readHooksFile(path);
210
+ const changes = [];
211
+ let mutated = false;
212
+ for (const event of events) {
213
+ if (this.capabilities[EVENT_CAPABILITY[event]] !== true) {
214
+ changes.push({
215
+ platform: this.id,
216
+ action: "warn",
217
+ path,
218
+ detail: `${event} unsupported on goose \u2014 skipped`
219
+ });
220
+ continue;
221
+ }
222
+ const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);
223
+ const matcher = connector.hooks[event]?.matcher ?? "";
224
+ const desired = {
225
+ matcher,
226
+ hooks: [{ type: "command", command }]
227
+ };
228
+ const bucket = file.hooks[event] ??= [];
229
+ const idx = bucket.findIndex((rule) => this.ruleHasOurCommand(rule, ctx));
230
+ if (idx >= 0) {
231
+ if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {
232
+ changes.push({ platform: this.id, action: "skip", path, detail: `hooks.${event}` });
233
+ continue;
234
+ }
235
+ bucket[idx] = desired;
236
+ changes.push({ platform: this.id, action: "update", path, detail: `hooks.${event}` });
237
+ } else {
238
+ bucket.push(desired);
239
+ changes.push({ platform: this.id, action: "create", path, detail: `hooks.${event}` });
240
+ }
241
+ mutated = true;
242
+ }
243
+ if (mutated) this.writeHooksFile(path, file, dryRun);
244
+ return changes;
245
+ }
246
+ uninstallHooks(ctx) {
247
+ const path = this.getHookConfigPath(ctx);
248
+ const file = this.readJson(path);
249
+ if (!file || !file.hooks || typeof file.hooks !== "object") {
250
+ return [{ platform: this.id, action: "skip", path, detail: "no hooks.json" }];
251
+ }
252
+ const changes = [];
253
+ let mutated = false;
254
+ for (const event of Object.keys(file.hooks)) {
255
+ const bucket = file.hooks[event];
256
+ if (!Array.isArray(bucket)) continue;
257
+ const next = [];
258
+ let removed = 0;
259
+ for (const rule of bucket) {
260
+ const innerBefore = rule.hooks?.length ?? 0;
261
+ const inner = (rule.hooks ?? []).filter((h) => !this.isOurCommand(h.command, ctx));
262
+ removed += innerBefore - inner.length;
263
+ if (inner.length > 0) {
264
+ next.push({ ...rule.matcher !== void 0 ? { matcher: rule.matcher } : {}, hooks: inner });
265
+ }
266
+ }
267
+ if (removed === 0) continue;
268
+ mutated = true;
269
+ if (next.length > 0) file.hooks[event] = next;
270
+ else delete file.hooks[event];
271
+ changes.push({
272
+ platform: this.id,
273
+ action: "remove",
274
+ path,
275
+ detail: `hooks.${event} (${removed})`
276
+ });
277
+ }
278
+ if (mutated) this.writeHooksFile(path, file, ctx.dryRun);
279
+ if (changes.length === 0) {
280
+ return [{ platform: this.id, action: "skip", path, detail: "no matching hook entries" }];
281
+ }
282
+ return changes;
283
+ }
284
+ /** True when a hook command is ours (anchored home-bin + connector id). */
285
+ isOurCommand(command, ctx) {
286
+ return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);
287
+ }
288
+ /** True when any inner command of a nested rule is ours. */
289
+ ruleHasOurCommand(rule, ctx) {
290
+ return (rule.hooks ?? []).some((h) => this.isOurCommand(h.command, ctx));
291
+ }
292
+ readHooksFile(path) {
293
+ const existing = this.readJson(path);
294
+ if (existing && existing.hooks && typeof existing.hooks === "object") {
295
+ return { hooks: existing.hooks };
296
+ }
297
+ return { hooks: {} };
298
+ }
299
+ writeHooksFile(path, file, dryRun) {
300
+ if (dryRun) return;
301
+ ensureDir(dirname(path));
302
+ writeFileSync(path, `${JSON.stringify(file, null, 2)}
303
+ `, "utf8");
304
+ }
305
+ // ── Diagnostics ──────────────────────────────────────────────────────────
306
+ getHealthChecks(ctx) {
307
+ const serverPath = this.getServerConfigPath(ctx);
308
+ const hookPath = this.getHookConfigPath(ctx);
309
+ const id = ctx.connector.id;
310
+ const homeBin = ctx.homeBinPath;
311
+ const hookEvents = ctx.connector.hookEvents;
312
+ return [
313
+ {
314
+ name: `${this.name}: config.yaml present`,
315
+ check: () => existsSync(serverPath) ? { status: "OK", detail: serverPath } : { status: "FAIL", detail: `not found: ${serverPath}` }
316
+ },
317
+ {
318
+ name: `${this.name}: ${MCP_ROOT_KEY}.${id} registered`,
319
+ check: () => {
320
+ const cfg = readYaml(serverPath);
321
+ const bucket = cfg?.[MCP_ROOT_KEY];
322
+ const present = typeof bucket === "object" && bucket !== null && !Array.isArray(bucket) && id in bucket;
323
+ return present ? { status: "OK", detail: `${MCP_ROOT_KEY}.${id}` } : { status: "FAIL", detail: `${MCP_ROOT_KEY}.${id} not found in ${serverPath}` };
324
+ }
325
+ },
326
+ {
327
+ name: `${this.name}: hook command registered`,
328
+ check: () => {
329
+ if (hookEvents.length === 0) return { status: "OK", detail: "no hooks declared" };
330
+ const file = this.readJson(hookPath);
331
+ if (!file || !file.hooks) {
332
+ return { status: "FAIL", detail: `cannot read ${hookPath}` };
333
+ }
334
+ const registered = Object.values(file.hooks).some(
335
+ (bucket) => (bucket ?? []).some(
336
+ (rule) => (rule.hooks ?? []).some((h) => isHomeBinHookCommand(h.command, homeBin, id))
337
+ )
338
+ );
339
+ return registered ? { status: "OK", detail: "hook command present" } : { status: "FAIL", detail: `no hook for ${id} in ${hookPath}` };
340
+ }
341
+ }
342
+ ];
343
+ }
344
+ // ── Runtime: parse Goose stdin JSON → normalized event ───────────────────
345
+ parseEvent(event, raw) {
346
+ const input = raw ?? {};
347
+ const projectDir = typeof input.working_dir === "string" ? input.working_dir : typeof input.cwd === "string" ? input.cwd : void 0;
348
+ const base = {
349
+ hostPlatform: HOST,
350
+ connectorId: typeof input.connector === "string" ? input.connector : "",
351
+ sessionId: typeof input.session_id === "string" ? input.session_id : "",
352
+ ...projectDir !== void 0 ? { projectDir } : {},
353
+ raw
354
+ };
355
+ switch (event) {
356
+ case "PreToolUse": {
357
+ const ev = {
358
+ ...base,
359
+ toolName: input.tool_name ?? "",
360
+ toolInput: input.tool_input ?? {}
361
+ };
362
+ return ev;
363
+ }
364
+ case "PostToolUse": {
365
+ const ev = {
366
+ ...base,
367
+ toolName: input.tool_name ?? "",
368
+ toolInput: input.tool_input ?? {},
369
+ ...toolResponseToString(input.tool_response) !== void 0 ? { toolOutput: toolResponseToString(input.tool_response) } : {},
370
+ ...typeof input.is_error === "boolean" ? { isError: input.is_error } : {}
371
+ };
372
+ return ev;
373
+ }
374
+ case "SessionStart": {
375
+ const ev = { ...base, source: normalizeSource(input.source) };
376
+ return ev;
377
+ }
378
+ case "SessionEnd": {
379
+ const ev = {
380
+ ...base,
381
+ ...typeof input.reason === "string" ? { reason: input.reason } : {}
382
+ };
383
+ return ev;
384
+ }
385
+ case "UserPromptSubmit": {
386
+ const ev = {
387
+ ...base,
388
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
389
+ };
390
+ return ev;
391
+ }
392
+ case "PreCompact": {
393
+ const ev = {
394
+ ...base,
395
+ ...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
396
+ };
397
+ return ev;
398
+ }
399
+ case "Stop": {
400
+ const ev = {
401
+ ...base,
402
+ ...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
403
+ };
404
+ return ev;
405
+ }
406
+ case "Notification": {
407
+ const ev = {
408
+ ...base,
409
+ message: typeof input.message === "string" ? input.message : ""
410
+ };
411
+ return ev;
412
+ }
413
+ default: {
414
+ const _never = event;
415
+ throw new Error(`unsupported goose hook event: ${String(_never)}`);
416
+ }
417
+ }
418
+ }
419
+ // ── Runtime: normalized response → Goose native hook reply (Claude-shaped) ─
420
+ formatReply(_event, response) {
421
+ const decision = response.decision ?? "allow";
422
+ if (decision === "deny") {
423
+ return this.stdout({
424
+ decision: "block",
425
+ reason: response.reason ?? "Blocked by hook"
426
+ });
427
+ }
428
+ if (decision === "ask") {
429
+ return this.stdout({
430
+ decision: "block",
431
+ reason: response.reason ?? "Confirmation required by hook"
432
+ });
433
+ }
434
+ if (decision === "context" && response.additionalContext) {
435
+ return this.stdout({ additionalContext: response.additionalContext });
436
+ }
437
+ return { exitCode: 0 };
438
+ }
439
+ stdout(payload) {
440
+ return { exitCode: 0, stdout: JSON.stringify(payload) };
441
+ }
442
+ // ── Internal helpers ──────────────────────────────────────────────────────
443
+ /** Resolve the per-platform server override into an effective ServerDef. */
444
+ effectiveServer(ctx) {
445
+ const override = ctx.connector.platforms[this.id]?.server;
446
+ if (override === false) return void 0;
447
+ const base = ctx.connector.server;
448
+ if (!base) return void 0;
449
+ return override && typeof override === "object" ? { ...base, ...override } : base;
450
+ }
451
+ };
452
+ function toolResponseToString(value) {
453
+ if (value == null) return void 0;
454
+ if (typeof value === "string") return value;
455
+ try {
456
+ return JSON.stringify(value);
457
+ } catch {
458
+ return String(value);
459
+ }
460
+ }
461
+ function normalizeSource(raw) {
462
+ switch (raw) {
463
+ case "compact":
464
+ return "compact";
465
+ case "resume":
466
+ return "resume";
467
+ case "clear":
468
+ return "clear";
469
+ default:
470
+ return "startup";
471
+ }
472
+ }
473
+ var adapter = new GooseAdapter();
474
+ var goose_default = adapter;
475
+ export {
476
+ GooseAdapter,
477
+ adapter,
478
+ goose_default as default
479
+ };
480
+ //# sourceMappingURL=goose-ZTGTSUFJ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/goose/index.ts"],"sourcesContent":["/**\n * adapters/goose — Block's Goose platform adapter for agent-connector.\n *\n * Goose is a json-stdio host, but its two config surfaces use DIFFERENT formats:\n *\n * - MCP servers (Goose calls them \"extensions\") live in a YAML config under the\n * root key `extensions`. The native stdio entry shape is Goose-specific:\n * { type: \"stdio\", cmd: <exe>, args: [...], envs: {...}, timeout, enabled }\n * NOTE the field is `cmd` (NOT `command`) and the env map is `envs` (NOT\n * `env`). Because the file is YAML, the BaseAdapter JSON helpers do not apply\n * — we merge via core/yaml's readYaml/writeYaml, preserving any other config.\n *\n * - Hooks use Goose's Open Plugins system, which stores hook registrations in\n * JSON at <root>/.agents/plugins/<plugin-name>/hooks/hooks.json (project root\n * = <projectDir>/.agents; user root = ~/.agents):\n * { hooks: { <Event>: [ { matcher?, hooks:[{ type:\"command\", command }] } ] } }\n * The shape is the Claude-style NESTED rule (an optional `matcher` plus an\n * inner `hooks` array), and there is NO top-level `version` key. This file is\n * plain JSON, so the standard fs/JSON helpers are used for it.\n *\n * Wire protocol (parse) is Claude-compatible JSON on stdin, except Goose names\n * the working directory field `working_dir` (not `cwd`). The deny reply is\n * Goose's `{ decision: \"block\", reason }` (NOT Claude's hookSpecificOutput\n * permissionDecision shape).\n *\n * Native config locations (user scope):\n * - Linux/macOS: ~/.config/goose/config.yaml\n * - Windows: %APPDATA%/Block/goose/config/config.yaml\n */\n\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, HookReply, InstallContext, NormalizedEvent } from \"../spi.js\";\nimport type {\n ChangeRecord,\n 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 UserPromptSubmitEvent,\n} from \"../../core/types.js\";\nimport { ensureDir } from \"../../core/paths.js\";\nimport { readYaml, writeYaml } from \"../../core/yaml.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 = \"goose\";\n/** Root key under which Goose stores MCP servers (\"extensions\") in config.yaml. */\nconst MCP_ROOT_KEY = \"extensions\";\n\n/**\n * Map each normalized hook event to the matching capability flag on this\n * adapter. The adapter's own `capabilities` literal is the single source of\n * truth for what Goose's Open-Plugins runtime delivers (PreToolUse/PostToolUse/\n * SessionStart); installHooks filters declared events through this map so an\n * unsupported event (e.g. UserPromptSubmit) is never written verbatim into\n * hooks.json — it is reported as a graceful warn/skip instead.\n */\nconst EVENT_CAPABILITY: Record<HookEventName, keyof PlatformCapabilities> = {\n SessionStart: \"sessionStart\",\n SessionEnd: \"sessionEnd\",\n UserPromptSubmit: \"userPromptSubmit\",\n PreToolUse: \"preToolUse\",\n PostToolUse: \"postToolUse\",\n PreCompact: \"preCompact\",\n Stop: \"stop\",\n Notification: \"notification\",\n};\n\n/**\n * Goose extension (MCP server) entry — note the Goose-specific field names:\n * `cmd` (not `command`) and `envs` (not `env`).\n */\ninterface GooseStdioExtension {\n type: \"stdio\";\n cmd: string;\n args: string[];\n envs?: Record<string, string>;\n timeout: number;\n enabled: boolean;\n}\n\n/** One inner command entry inside a hook rule. */\ninterface GooseHookCommand {\n type: \"command\";\n command: string;\n}\n\n/**\n * One nested-rule entry under a hook event. Goose's Open Plugins spec uses the\n * Claude-shaped nested rule: an optional `matcher` plus an inner `hooks` array\n * of `{ type, command }` commands (NOT a flat list of commands).\n */\ninterface GooseHookRule {\n matcher?: string;\n hooks: GooseHookCommand[];\n}\n\n/**\n * Goose Open-Plugins hooks.json shape: `{ hooks: { <Event>: [ rule, ... ] } }`.\n * There is NO top-level `version` key in the spec.\n */\ninterface GooseHooksFile {\n hooks: Record<string, GooseHookRule[]>;\n}\n\n/** Raw Goose hook stdin payload (Claude-compatible JSON). */\ninterface GooseWireInput {\n session_id?: string;\n /** Goose names the working directory `working_dir`; `cwd` is a fallback. */\n working_dir?: string;\n cwd?: string;\n hook_event_name?: string;\n tool_name?: string;\n tool_input?: Record<string, unknown>;\n tool_response?: unknown;\n source?: string;\n reason?: string;\n prompt?: string;\n trigger?: string;\n stop_hook_active?: boolean;\n message?: string;\n is_error?: boolean;\n /** Injected by the entrypoint so the runtime knows which connector to dispatch. */\n connector?: string;\n}\n\nexport class GooseAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Goose\";\n readonly paradigm: HookParadigm = \"json-stdio\";\n\n readonly capabilities: PlatformCapabilities = {\n preToolUse: true,\n postToolUse: true,\n preCompact: false,\n sessionStart: true,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n // Open Plugins documents PreToolUse/PostToolUse/SessionStart; argument\n // rewrite is not guaranteed across versions, so default to the safe value.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: true,\n transports: [\"stdio\", \"sse\", \"http\"],\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const configPath = this.userConfigPath();\n const configDir = dirname(configPath);\n const installed = existsSync(configDir) || existsSync(configPath);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope: \"user\",\n reason: installed\n ? `found Goose config at ${configPath}`\n : `no Goose config at ${configPath}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n override getConfigDir(_ctx: InstallContext): string {\n return dirname(this.userConfigPath());\n }\n\n /** MCP config: the YAML config.yaml (user scope). */\n override getServerConfigPath(_ctx: InstallContext): string {\n return this.userConfigPath();\n }\n\n /**\n * Hooks: Open-Plugins hooks.json under the `.agents/plugins/<plugin-name>/`\n * dir. The connector id is the plugin name. Project scope roots at\n * `<projectDir>/.agents`; user scope roots at `~/.agents`.\n */\n override getHookConfigPath(ctx: InstallContext): string {\n const root = ctx.scope === \"project\" ? ctx.projectDir : homedir();\n return join(root, \".agents\", \"plugins\", ctx.connector.id, \"hooks\", \"hooks.json\");\n }\n\n /**\n * OS-correct user config.yaml path:\n * - Windows: %APPDATA%/Block/goose/config/config.yaml\n * - macOS/Linux: ~/.config/goose/config.yaml\n */\n private userConfigPath(): string {\n if (process.platform === \"win32\") {\n const appData =\n process.env.APPDATA && process.env.APPDATA.trim() !== \"\"\n ? process.env.APPDATA\n : join(homedir(), \"AppData\", \"Roaming\");\n return join(appData, \"Block\", \"goose\", \"config\", \"config.yaml\");\n }\n return join(homedir(), \".config\", \"goose\", \"config.yaml\");\n }\n\n // ── MCP server install / uninstall (YAML — merge via readYaml/writeYaml) ──\n\n override installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const server = this.effectiveServer(ctx);\n\n if (!server) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: connector.server\n ? \"server registration disabled for goose\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n const entry = this.renderExtension(ctx, server);\n\n // Merge into existing YAML, preserving every other config key + extension.\n const cfg = readYaml<Record<string, unknown>>(path) ?? {};\n const bucketRaw = cfg[MCP_ROOT_KEY];\n const bucket: Record<string, unknown> =\n bucketRaw && typeof bucketRaw === \"object\" && !Array.isArray(bucketRaw)\n ? (bucketRaw as Record<string, unknown>)\n : {};\n cfg[MCP_ROOT_KEY] = bucket;\n\n const before = JSON.stringify(bucket[connector.id]);\n const after = JSON.stringify(entry);\n let action: ChangeRecord[\"action\"];\n if (before === undefined) action = \"create\";\n else if (before === after) action = \"skip\";\n else action = \"update\";\n\n if (action !== \"skip\") {\n bucket[connector.id] = entry;\n writeYaml(path, cfg, dryRun);\n }\n return [{ platform: this.id, action, path, detail: `${MCP_ROOT_KEY}.${connector.id}` }];\n }\n\n override uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getServerConfigPath(ctx);\n const cfg = readYaml<Record<string, unknown>>(path);\n const bucketRaw = cfg?.[MCP_ROOT_KEY];\n if (\n !cfg ||\n !bucketRaw ||\n typeof bucketRaw !== \"object\" ||\n Array.isArray(bucketRaw) ||\n !(connector.id in (bucketRaw as Record<string, unknown>))\n ) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n path,\n detail: `${MCP_ROOT_KEY}.${connector.id} absent`,\n },\n ];\n }\n delete (bucketRaw as Record<string, unknown>)[connector.id];\n writeYaml(path, cfg, dryRun);\n return [\n { platform: this.id, action: \"remove\", path, detail: `${MCP_ROOT_KEY}.${connector.id}` },\n ];\n }\n\n /**\n * Render a normalized ServerDef into Goose's native extension entry. Goose has\n * no native env interpolation, so `${env:VAR}` refs are resolved to literals at\n * install time. Honors the telemetry serve-wrapper (cmd=homeBin, args=[serve…]).\n */\n private renderExtension(ctx: InstallContext, server: ServerDef): GooseStdioExtension {\n let cmd = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n ctx.homeBinPath,\n ctx.connector.id,\n cmd,\n args,\n ctx.scope,\n this.id,\n );\n cmd = wrapped.command;\n args = wrapped.args;\n }\n\n cmd = resolveEnvRefsDeep(cmd);\n args = resolveEnvRefsDeep(args);\n\n const timeoutMs = server.timeoutMs;\n const timeout =\n typeof timeoutMs === \"number\" && timeoutMs > 0 ? Math.round(timeoutMs / 1000) : 300;\n\n const entry: GooseStdioExtension = {\n type: \"stdio\",\n cmd,\n args,\n timeout,\n enabled: server.enabled !== false,\n };\n\n if (server.env && Object.keys(server.env).length > 0) {\n const envs: Record<string, string> = {};\n for (const [k, v] of Object.entries(resolveEnvRefsDeep(server.env))) {\n envs[k] = String(v);\n }\n entry.envs = envs;\n }\n return entry;\n }\n\n // ── Hook install / uninstall (JSON Open-Plugins hooks.json) ───────────────\n\n override installHooks(ctx: InstallContext): ChangeRecord[] {\n const { connector, dryRun } = ctx;\n const path = this.getHookConfigPath(ctx);\n\n if (connector.platforms[HOST]?.hooks === false) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"hooks disabled for goose\" }];\n }\n const events = connector.hookEvents;\n if (events.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"connector declares no hooks\" }];\n }\n\n const file = this.readHooksFile(path);\n const changes: ChangeRecord[] = [];\n let mutated = false;\n\n for (const event of events) {\n // CAPABILITY FILTER: only write events Goose's Open-Plugins runtime\n // actually delivers. Derive support from THIS adapter's capabilities (the\n // single source of truth) so an event Goose does not support (e.g.\n // UserPromptSubmit) is reported as a graceful warn and never written\n // verbatim into hooks.json — mirroring the cursor adapter's pattern.\n if (this.capabilities[EVENT_CAPABILITY[event]] !== true) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path,\n detail: `${event} unsupported on goose — skipped`,\n });\n continue;\n }\n\n const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);\n const matcher = connector.hooks[event]?.matcher ?? \"\";\n const desired: GooseHookRule = {\n matcher,\n hooks: [{ type: \"command\", command }],\n };\n const bucket = (file.hooks[event] ??= []);\n const idx = bucket.findIndex((rule) => this.ruleHasOurCommand(rule, ctx));\n\n if (idx >= 0) {\n if (JSON.stringify(bucket[idx]) === JSON.stringify(desired)) {\n changes.push({ platform: this.id, action: \"skip\", path, detail: `hooks.${event}` });\n continue;\n }\n bucket[idx] = desired;\n changes.push({ platform: this.id, action: \"update\", path, detail: `hooks.${event}` });\n } else {\n bucket.push(desired);\n changes.push({ platform: this.id, action: \"create\", path, detail: `hooks.${event}` });\n }\n mutated = true;\n }\n\n if (mutated) this.writeHooksFile(path, file, dryRun);\n return changes;\n }\n\n override uninstallHooks(ctx: InstallContext): ChangeRecord[] {\n const path = this.getHookConfigPath(ctx);\n const file = this.readJson<GooseHooksFile>(path);\n if (!file || !file.hooks || typeof file.hooks !== \"object\") {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no hooks.json\" }];\n }\n\n const changes: ChangeRecord[] = [];\n let mutated = false;\n for (const event of Object.keys(file.hooks)) {\n const bucket = file.hooks[event];\n if (!Array.isArray(bucket)) continue;\n\n // Strip our command from each rule's inner `hooks` array; drop rules left\n // empty so we never remove another connector's (or the user's own) hooks.\n const next: GooseHookRule[] = [];\n let removed = 0;\n for (const rule of bucket) {\n const innerBefore = rule.hooks?.length ?? 0;\n const inner = (rule.hooks ?? []).filter((h) => !this.isOurCommand(h.command, ctx));\n removed += innerBefore - inner.length;\n if (inner.length > 0) {\n next.push({ ...(rule.matcher !== undefined ? { matcher: rule.matcher } : {}), hooks: inner });\n }\n }\n\n if (removed === 0) continue;\n mutated = true;\n if (next.length > 0) file.hooks[event] = next;\n else delete file.hooks[event];\n changes.push({\n platform: this.id,\n action: \"remove\",\n path,\n detail: `hooks.${event} (${removed})`,\n });\n }\n\n if (mutated) this.writeHooksFile(path, file, ctx.dryRun);\n if (changes.length === 0) {\n return [{ platform: this.id, action: \"skip\", path, detail: \"no matching hook entries\" }];\n }\n return changes;\n }\n\n /** True when a hook command is ours (anchored home-bin + connector id). */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n /** True when any inner command of a nested rule is ours. */\n private ruleHasOurCommand(rule: GooseHookRule, ctx: InstallContext): boolean {\n return (rule.hooks ?? []).some((h) => this.isOurCommand(h.command, ctx));\n }\n\n private readHooksFile(path: string): GooseHooksFile {\n const existing = this.readJson<GooseHooksFile>(path);\n if (existing && existing.hooks && typeof existing.hooks === \"object\") {\n return { hooks: existing.hooks };\n }\n return { hooks: {} };\n }\n\n private writeHooksFile(path: string, file: GooseHooksFile, dryRun: boolean): void {\n if (dryRun) return;\n ensureDir(dirname(path));\n writeFileSync(path, `${JSON.stringify(file, null, 2)}\\n`, \"utf8\");\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 id = ctx.connector.id;\n const homeBin = ctx.homeBinPath;\n const hookEvents = ctx.connector.hookEvents;\n return [\n {\n name: `${this.name}: config.yaml present`,\n check: () =>\n existsSync(serverPath)\n ? { status: \"OK\", detail: serverPath }\n : { status: \"FAIL\", detail: `not found: ${serverPath}` },\n },\n {\n name: `${this.name}: ${MCP_ROOT_KEY}.${id} registered`,\n check: () => {\n const cfg = readYaml<Record<string, unknown>>(serverPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n const present =\n typeof bucket === \"object\" &&\n bucket !== null &&\n !Array.isArray(bucket) &&\n id in (bucket as Record<string, unknown>);\n return present\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${id}` }\n : { status: \"FAIL\", detail: `${MCP_ROOT_KEY}.${id} not found in ${serverPath}` };\n },\n },\n {\n name: `${this.name}: hook command registered`,\n check: () => {\n if (hookEvents.length === 0) return { status: \"OK\", detail: \"no hooks declared\" };\n const file = this.readJson<GooseHooksFile>(hookPath);\n if (!file || !file.hooks) {\n return { status: \"FAIL\", detail: `cannot read ${hookPath}` };\n }\n const registered = Object.values(file.hooks).some((bucket) =>\n (bucket ?? []).some((rule) =>\n (rule.hooks ?? []).some((h) => isHomeBinHookCommand(h.command, homeBin, id)),\n ),\n );\n return registered\n ? { status: \"OK\", detail: \"hook command present\" }\n : { status: \"FAIL\", detail: `no hook for ${id} in ${hookPath}` };\n },\n },\n ];\n }\n\n // ── Runtime: parse Goose stdin JSON → normalized event ───────────────────\n\n parseEvent(event: HookEventName, raw: unknown): NormalizedEvent {\n const input = (raw ?? {}) as GooseWireInput;\n // Goose sends the working directory as `working_dir`; fall back to `cwd`.\n const projectDir =\n typeof input.working_dir === \"string\"\n ? input.working_dir\n : typeof input.cwd === \"string\"\n ? input.cwd\n : undefined;\n const base = {\n hostPlatform: HOST,\n connectorId: typeof input.connector === \"string\" ? input.connector : \"\",\n sessionId: typeof input.session_id === \"string\" ? input.session_id : \"\",\n ...(projectDir !== undefined ? { 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 ...(typeof input.is_error === \"boolean\" ? { isError: input.is_error } : {}),\n };\n return ev;\n }\n case \"SessionStart\": {\n const ev: SessionStartEvent = { ...base, source: normalizeSource(input.source) };\n return ev;\n }\n case \"SessionEnd\": {\n const ev: SessionEndEvent = {\n ...base,\n ...(typeof input.reason === \"string\" ? { reason: input.reason } : {}),\n };\n return ev;\n }\n case \"UserPromptSubmit\": {\n const ev: UserPromptSubmitEvent = {\n ...base,\n prompt: typeof input.prompt === \"string\" ? input.prompt : \"\",\n };\n return ev;\n }\n case \"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 goose hook event: ${String(_never)}`);\n }\n }\n }\n\n // ── Runtime: normalized response → Goose native hook reply (Claude-shaped) ─\n\n formatReply(_event: HookEventName, response: HookResponse): HookReply {\n const decision = response.decision ?? \"allow\";\n\n // deny → Goose blocks via `{ decision: \"block\", reason }` on stdout JSON\n // (NOT Claude's hookSpecificOutput.permissionDecision shape).\n if (decision === \"deny\") {\n return this.stdout({\n decision: \"block\",\n reason: response.reason ?? \"Blocked by hook\",\n });\n }\n\n // ask → Goose has no native \"ask\"; degrade to block to stay fail-safe.\n if (decision === \"ask\") {\n return this.stdout({\n decision: \"block\",\n reason: response.reason ?? \"Confirmation required by hook\",\n });\n }\n\n if (decision === \"context\" && response.additionalContext) {\n return this.stdout({ additionalContext: response.additionalContext });\n }\n\n // allow / modify (unsupported) / void → pass through.\n return { exitCode: 0 };\n }\n\n private stdout(payload: unknown): HookReply {\n return { exitCode: 0, stdout: JSON.stringify(payload) };\n }\n\n // ── Internal helpers ──────────────────────────────────────────────────────\n\n /** Resolve the per-platform server override into an effective ServerDef. */\n private effectiveServer(ctx: InstallContext): ServerDef | undefined {\n const override = ctx.connector.platforms[this.id]?.server;\n if (override === false) return undefined;\n const base = ctx.connector.server;\n if (!base) return undefined;\n return override && typeof override === \"object\" ? { ...base, ...override } : base;\n }\n}\n\n/** Coerce a Goose PostToolUse `tool_response` into a string. */\nfunction toolResponseToString(value: unknown): string | undefined {\n if (value == null) return undefined;\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction normalizeSource(raw: string | undefined): SessionStartEvent[\"source\"] {\n switch (raw) {\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 GooseAdapter();\nexport default adapter;\n"],"mappings":"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","names":[]}