@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,715 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ rewriteEnvRefs
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 "./chunk-TRQKHP7D.js";
16
+
17
+ // src/adapters/vscode-copilot/index.ts
18
+ import { existsSync } from "fs";
19
+ import { homedir } from "os";
20
+ import { join } from "path";
21
+ var HOST = "vscode-copilot";
22
+ var MCP_ROOT_KEY = "servers";
23
+ var VSCODE_HOOKS_VERSION = 1;
24
+ var EVENT_MAP = {
25
+ PreToolUse: "PreToolUse",
26
+ PostToolUse: "PostToolUse",
27
+ PreCompact: "PreCompact",
28
+ SessionStart: "SessionStart"
29
+ };
30
+ var VSCodeCopilotAdapter = class extends BaseAdapter {
31
+ id = HOST;
32
+ name = "VS Code Copilot";
33
+ paradigm = "json-stdio";
34
+ capabilities = {
35
+ // VS Code Copilot's Preview hooks runtime delivers Pre/PostToolUse,
36
+ // PreCompact, and SessionStart (the four events its schema documents).
37
+ preToolUse: true,
38
+ postToolUse: true,
39
+ preCompact: true,
40
+ sessionStart: true,
41
+ sessionEnd: false,
42
+ userPromptSubmit: false,
43
+ stop: false,
44
+ notification: false,
45
+ // PreToolUse can rewrite tool input (updatedInput) but a PostToolUse hook
46
+ // cannot rewrite already-emitted tool output — same as Claude/Cursor.
47
+ canModifyArgs: true,
48
+ canModifyOutput: false,
49
+ canInjectSessionContext: true,
50
+ transports: ["stdio", "http"],
51
+ // Content surfaces: VS Code Copilot authors prompt files, Agent Skills, and
52
+ // chat-mode agent files under the workspace .github/ tree (see content-file
53
+ // path helpers below). All three are supported.
54
+ supportsCommands: true,
55
+ supportsSkills: true,
56
+ supportsSubagents: true
57
+ };
58
+ // ── Detection ────────────────────────────────────────────────────────────
59
+ detectInstalled(projectDir) {
60
+ const userDir = join(homedir(), ".vscode");
61
+ const userMcp = join(userDir, "mcp.json");
62
+ const userInsidersDir = join(homedir(), ".vscode-insiders");
63
+ const projectVscode = join(projectDir, ".vscode");
64
+ const projectMcp = join(projectVscode, "mcp.json");
65
+ const projInstalled = existsSync(projectMcp) || existsSync(projectVscode);
66
+ const userInstalled = existsSync(userMcp) || existsSync(userDir) || existsSync(userInsidersDir);
67
+ const installed = projInstalled || userInstalled;
68
+ const scope = projInstalled && !userInstalled ? "project" : "user";
69
+ const configPath = scope === "project" ? projectMcp : userMcp;
70
+ return {
71
+ id: this.id,
72
+ name: this.name,
73
+ installed,
74
+ paradigm: this.paradigm,
75
+ capabilities: this.capabilities,
76
+ configPath,
77
+ scope,
78
+ reason: installed ? scope === "project" ? `found project VS Code config at ${projectVscode}` : `found VS Code config under ${userDir}` : `no VS Code config at ${userDir}`,
79
+ confidence: installed ? "high" : "low"
80
+ };
81
+ }
82
+ // ── Native paths ─────────────────────────────────────────────────────────
83
+ /**
84
+ * Config dir choice (documented per task brief): project (workspace) scope →
85
+ * <projectDir>/.vscode; user-profile scope → ~/.vscode. The real VS Code user
86
+ * profile dir is OS-specific and not reliably discoverable without launching
87
+ * VS Code, so ~/.vscode is the reasonable, cross-OS, no-launch choice — it is
88
+ * also where "MCP: Open User Configuration" writes on a default profile.
89
+ */
90
+ getConfigDir(ctx) {
91
+ return ctx.scope === "project" ? join(ctx.projectDir, ".vscode") : join(homedir(), ".vscode");
92
+ }
93
+ /** MCP server registration lives in <configDir>/mcp.json under root "servers". */
94
+ getServerConfigPath(ctx) {
95
+ return join(this.getConfigDir(ctx), "mcp.json");
96
+ }
97
+ /**
98
+ * Hook registration lives in the workspace-discovered .github/hooks tree,
99
+ * which VS Code Copilot scans for *.json hook files. We write one file per
100
+ * connector so installs/uninstalls never clobber another connector's hooks.
101
+ * Anchored on projectDir for both scopes — .github/hooks is a workspace
102
+ * concept (there is no user-profile equivalent in the Copilot hooks schema).
103
+ */
104
+ getHookConfigPath(ctx) {
105
+ return join(ctx.projectDir, ".github", "hooks", `${ctx.connector.id}.json`);
106
+ }
107
+ // ── MCP server install / uninstall ───────────────────────────────────────
108
+ installServer(ctx) {
109
+ const { connector } = ctx;
110
+ const override = connector.platforms[HOST]?.server;
111
+ if (!connector.server || override === false) {
112
+ return [
113
+ {
114
+ platform: this.id,
115
+ action: "skip",
116
+ detail: connector.server ? "server registration disabled for vscode-copilot" : "connector declares no MCP server"
117
+ }
118
+ ];
119
+ }
120
+ const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
121
+ const serverPath = this.getServerConfigPath(ctx);
122
+ const entry = this.renderServerEntry(ctx, server);
123
+ return [
124
+ this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
125
+ ];
126
+ }
127
+ uninstallServer(ctx) {
128
+ const serverPath = this.getServerConfigPath(ctx);
129
+ return [
130
+ this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
131
+ ];
132
+ }
133
+ /** Render a normalized ServerDef into VS Code's native `servers` entry. */
134
+ renderServerEntry(ctx, server) {
135
+ const transport = server.transport;
136
+ if (transport === "stdio") {
137
+ let command = server.command ?? "";
138
+ let args = [...server.args ?? []];
139
+ if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
140
+ const wrapped = buildServeWrapperCommand(
141
+ ctx.homeBinPath,
142
+ ctx.connector.id,
143
+ command,
144
+ args,
145
+ ctx.scope,
146
+ this.id
147
+ );
148
+ command = wrapped.command;
149
+ args = wrapped.args;
150
+ }
151
+ const entry2 = { type: "stdio", command: this.rewrite(command) };
152
+ if (args.length > 0) entry2.args = args.map((a) => this.rewrite(a));
153
+ const env = this.renderEnv(server.env);
154
+ if (env) entry2.env = env;
155
+ if (server.cwd) entry2.cwd = this.rewrite(server.cwd);
156
+ return entry2;
157
+ }
158
+ const entry = {
159
+ type: "http",
160
+ url: this.rewrite(server.url ?? "")
161
+ };
162
+ const headers = this.renderEnv(server.headers);
163
+ if (headers) entry.headers = headers;
164
+ return entry;
165
+ }
166
+ /**
167
+ * Render env/header values. VS Code supports its own `${env:VAR}` native
168
+ * interpolation, so translate `${env:VAR}` refs to that native token rather
169
+ * than baking secrets into the file. Literals pass through unchanged.
170
+ */
171
+ renderEnv(env) {
172
+ if (!env || Object.keys(env).length === 0) return void 0;
173
+ const out = {};
174
+ for (const [k, v] of Object.entries(env)) out[k] = this.rewrite(v);
175
+ return out;
176
+ }
177
+ /** Translate `${env:VAR(:-default)}` to VS Code's native `${env:VAR}` token. */
178
+ rewrite(value) {
179
+ return rewriteEnvRefs(value, vscodeEnvToken);
180
+ }
181
+ // ── Hook install / uninstall ─────────────────────────────────────────────
182
+ installHooks(ctx) {
183
+ const { connector } = ctx;
184
+ if (connector.platforms[HOST]?.hooks === false) {
185
+ return [
186
+ { platform: this.id, action: "skip", detail: "hooks disabled for vscode-copilot" }
187
+ ];
188
+ }
189
+ if (connector.hookEvents.length === 0) {
190
+ return [{ platform: this.id, action: "skip", detail: "connector declares no hooks" }];
191
+ }
192
+ const hooksPath = this.getHookConfigPath(ctx);
193
+ const file = this.readJson(hooksPath) ?? {};
194
+ const hooks = file.hooks ??= {};
195
+ const changes = [];
196
+ let mutated = false;
197
+ for (const event of connector.hookEvents) {
198
+ const vscodeEvent = EVENT_MAP[event];
199
+ if (!vscodeEvent) {
200
+ changes.push({
201
+ platform: this.id,
202
+ action: "warn",
203
+ path: hooksPath,
204
+ detail: `${event} has no VS Code Copilot hook equivalent \u2014 skipped`
205
+ });
206
+ continue;
207
+ }
208
+ const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);
209
+ const entry = { type: "command", command };
210
+ const bucket = hooks[vscodeEvent] ??= [];
211
+ const existingIdx = bucket.findIndex((e) => this.isOurCommand(e.command, ctx));
212
+ if (existingIdx >= 0) {
213
+ if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {
214
+ changes.push({
215
+ platform: this.id,
216
+ action: "skip",
217
+ path: hooksPath,
218
+ detail: `hooks.${vscodeEvent} already registered`
219
+ });
220
+ continue;
221
+ }
222
+ bucket[existingIdx] = entry;
223
+ changes.push({
224
+ platform: this.id,
225
+ action: "update",
226
+ path: hooksPath,
227
+ detail: `hooks.${vscodeEvent}`
228
+ });
229
+ } else {
230
+ bucket.push(entry);
231
+ changes.push({
232
+ platform: this.id,
233
+ action: "create",
234
+ path: hooksPath,
235
+ detail: `hooks.${vscodeEvent}`
236
+ });
237
+ }
238
+ mutated = true;
239
+ }
240
+ if (mutated) {
241
+ file.version = VSCODE_HOOKS_VERSION;
242
+ this.writeJson(hooksPath, file, ctx.dryRun);
243
+ }
244
+ return changes;
245
+ }
246
+ uninstallHooks(ctx) {
247
+ const hooksPath = this.getHookConfigPath(ctx);
248
+ const file = this.readJson(hooksPath);
249
+ const hooks = file?.hooks;
250
+ if (!file || !hooks) {
251
+ return [
252
+ {
253
+ platform: this.id,
254
+ action: "skip",
255
+ path: hooksPath,
256
+ detail: "no hooks section present"
257
+ }
258
+ ];
259
+ }
260
+ const changes = [];
261
+ let mutated = false;
262
+ for (const vscodeEvent of Object.keys(hooks)) {
263
+ const bucket = hooks[vscodeEvent];
264
+ if (!Array.isArray(bucket)) continue;
265
+ const before = bucket.length;
266
+ const next = bucket.filter((e) => !this.isOurCommand(e.command, ctx));
267
+ const removed = before - next.length;
268
+ if (removed > 0) {
269
+ if (next.length > 0) hooks[vscodeEvent] = next;
270
+ else delete hooks[vscodeEvent];
271
+ changes.push({
272
+ platform: this.id,
273
+ action: "remove",
274
+ path: hooksPath,
275
+ detail: `hooks.${vscodeEvent} (${removed})`
276
+ });
277
+ mutated = true;
278
+ }
279
+ }
280
+ if (mutated) this.writeJson(hooksPath, file, ctx.dryRun);
281
+ if (changes.length === 0) {
282
+ changes.push({
283
+ platform: this.id,
284
+ action: "skip",
285
+ path: hooksPath,
286
+ detail: "no matching hook entries"
287
+ });
288
+ }
289
+ return changes;
290
+ }
291
+ /** True when a hook command references our home binary AND this connector id
292
+ * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand). */
293
+ isOurCommand(command, ctx) {
294
+ return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);
295
+ }
296
+ // ── Content surfaces: commands / skills / subagents ──────────────────────
297
+ // CONTENT-ONLY: pure native-file writers under the workspace .github/ tree
298
+ // ({prompts,skills,agents}). No runtime dispatch, no home-bin pointer, no
299
+ // telemetry wrap. Each method is idempotent (byte-identical → skip) via
300
+ // BaseAdapter.writeContentFile and reversible via removeContentFile. Honors
301
+ // platforms["vscode-copilot"] per-surface false to skip.
302
+ //
303
+ // SHARED .github TREE: vscode-copilot, copilot-cli, and jetbrains-copilot all
304
+ // write under the SAME project <projectDir>/.github tree. The rendered content
305
+ // is identical and idempotent across those connectors, and uninstall here only
306
+ // removes the files THIS connector declared — never another writer's files.
307
+ //
308
+ // SCOPE NOTE: .github is a workspace concept; the Copilot prompt/skill/agent
309
+ // discovery is workspace-rooted and there is no documented per-user .github
310
+ // authoring location. VS Code's reliable per-user authoring root is the user
311
+ // profile prompts dir under the OS app-data path, which is not discoverable
312
+ // without launching VS Code. So for user scope we anchor on
313
+ // <homedir>/.config/github-copilot (the documented cross-OS Copilot user dir;
314
+ // see contentRootDir) rather than fabricating a profile path. Project scope is
315
+ // the primary, fully-supported path.
316
+ /**
317
+ * Root of the content tree. Project (workspace) scope → <projectDir>/.github,
318
+ * which VS Code Copilot scans for prompt/skill/agent files (and which
319
+ * copilot-cli + jetbrains-copilot share). User scope has no documented
320
+ * workspace-independent .github equivalent, so we anchor on the documented
321
+ * cross-OS Copilot user dir ~/.config/github-copilot to keep user-scope writes
322
+ * deterministic and removable.
323
+ */
324
+ contentRootDir(ctx) {
325
+ return ctx.scope === "project" ? join(ctx.projectDir, ".github") : join(homedir(), ".config", "github-copilot");
326
+ }
327
+ promptsDir(ctx) {
328
+ return join(this.contentRootDir(ctx), "prompts");
329
+ }
330
+ skillsDir(ctx) {
331
+ return join(this.contentRootDir(ctx), "skills");
332
+ }
333
+ agentsDir(ctx) {
334
+ return join(this.contentRootDir(ctx), "agents");
335
+ }
336
+ /** Native command file path: <ghDir>/prompts/<name>.prompt.md. */
337
+ commandPath(ctx, name) {
338
+ return join(this.promptsDir(ctx), `${name}.prompt.md`);
339
+ }
340
+ /** Native skill dir: <ghDir>/skills/<name>. */
341
+ skillDir(ctx, name) {
342
+ return join(this.skillsDir(ctx), name);
343
+ }
344
+ /** Native subagent file path: <ghDir>/agents/<name>.agent.md. */
345
+ subagentPath(ctx, name) {
346
+ return join(this.agentsDir(ctx), `${name}.agent.md`);
347
+ }
348
+ // ── Commands ──────────────────────────────────────────────────────────────
349
+ installCommands(ctx) {
350
+ const { connector } = ctx;
351
+ if (connector.platforms[HOST]?.commands === false) {
352
+ return [{ platform: this.id, action: "skip", detail: "commands disabled for vscode-copilot" }];
353
+ }
354
+ if (connector.commands.length === 0) {
355
+ return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
356
+ }
357
+ return connector.commands.map(
358
+ (cmd) => this.writeContentFile(
359
+ this.commandPath(ctx, cmd.name),
360
+ this.renderCommand(cmd),
361
+ ctx.dryRun
362
+ )
363
+ );
364
+ }
365
+ uninstallCommands(ctx) {
366
+ const { connector } = ctx;
367
+ if (connector.commands.length === 0) {
368
+ return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
369
+ }
370
+ return connector.commands.map(
371
+ (cmd) => this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun)
372
+ );
373
+ }
374
+ /** Render a VS Code Copilot prompt file: md+frontmatter(description, tools, model, argument-hint). */
375
+ renderCommand(cmd) {
376
+ const frontmatter = {};
377
+ if (cmd.description !== void 0) frontmatter.description = cmd.description;
378
+ const allow = cmd.tools?.allow;
379
+ if (allow && allow.length > 0) frontmatter.tools = [...allow];
380
+ if (cmd.model !== void 0) frontmatter.model = cmd.model;
381
+ if (cmd.argumentHint !== void 0) frontmatter["argument-hint"] = cmd.argumentHint;
382
+ if (cmd.extra) Object.assign(frontmatter, cmd.extra);
383
+ return this.renderFrontmatterMd(frontmatter, cmd.prompt);
384
+ }
385
+ // ── Skills ────────────────────────────────────────────────────────────────
386
+ installSkills(ctx) {
387
+ const { connector } = ctx;
388
+ if (connector.platforms[HOST]?.skills === false) {
389
+ return [{ platform: this.id, action: "skip", detail: "skills disabled for vscode-copilot" }];
390
+ }
391
+ if (connector.skills.length === 0) {
392
+ return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
393
+ }
394
+ const changes = [];
395
+ for (const skill of connector.skills) {
396
+ const dir = this.skillDir(ctx, skill.name);
397
+ changes.push(
398
+ this.writeContentFile(join(dir, "SKILL.md"), this.renderSkill(skill), ctx.dryRun)
399
+ );
400
+ for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
401
+ const target = this.resolveWithin(dir, rel);
402
+ if (target === null) {
403
+ changes.push({
404
+ platform: this.id,
405
+ action: "warn",
406
+ detail: `skill resource "${rel}" escapes the skill dir; skipped`
407
+ });
408
+ continue;
409
+ }
410
+ changes.push(this.writeContentFile(target, contents, ctx.dryRun));
411
+ }
412
+ }
413
+ return changes;
414
+ }
415
+ uninstallSkills(ctx) {
416
+ const { connector } = ctx;
417
+ if (connector.skills.length === 0) {
418
+ return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
419
+ }
420
+ const changes = [];
421
+ for (const skill of connector.skills) {
422
+ const dir = this.skillDir(ctx, skill.name);
423
+ changes.push(this.removeContentFile(join(dir, "SKILL.md"), ctx.dryRun));
424
+ for (const rel of Object.keys(skill.resources ?? {})) {
425
+ const target = this.resolveWithin(dir, rel);
426
+ if (target === null) continue;
427
+ changes.push(this.removeContentFile(target, ctx.dryRun));
428
+ }
429
+ changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));
430
+ }
431
+ return changes;
432
+ }
433
+ /**
434
+ * Render a skill's SKILL.md — the uniform Agent Skills format: frontmatter
435
+ * (name, description + optional model, allowed-tools, disable-model-invocation)
436
+ * + body. Byte-identical to the other .github-sharing connectors so a shared
437
+ * skill folder never thrashes.
438
+ */
439
+ renderSkill(skill) {
440
+ const frontmatter = {
441
+ name: skill.name,
442
+ description: skill.description
443
+ };
444
+ if (skill.model !== void 0) frontmatter.model = skill.model;
445
+ const allow = skill.tools?.allow;
446
+ if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
447
+ if (skill.disableModelInvocation !== void 0) {
448
+ frontmatter["disable-model-invocation"] = skill.disableModelInvocation;
449
+ }
450
+ if (skill.extra) Object.assign(frontmatter, skill.extra);
451
+ return this.renderFrontmatterMd(frontmatter, skill.body);
452
+ }
453
+ // ── Subagents ───────────────────────────────────────────────────────────────
454
+ installSubagents(ctx) {
455
+ const { connector } = ctx;
456
+ if (connector.platforms[HOST]?.subagents === false) {
457
+ return [{ platform: this.id, action: "skip", detail: "subagents disabled for vscode-copilot" }];
458
+ }
459
+ if (connector.subagents.length === 0) {
460
+ return [{ platform: this.id, action: "skip", detail: "connector declares no subagents" }];
461
+ }
462
+ return connector.subagents.map(
463
+ (agent) => this.writeContentFile(
464
+ this.subagentPath(ctx, agent.name),
465
+ this.renderSubagent(agent),
466
+ ctx.dryRun
467
+ )
468
+ );
469
+ }
470
+ uninstallSubagents(ctx) {
471
+ const { connector } = ctx;
472
+ if (connector.subagents.length === 0) {
473
+ return [{ platform: this.id, action: "skip", detail: "connector declares no subagents" }];
474
+ }
475
+ return connector.subagents.map(
476
+ (agent) => this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun)
477
+ );
478
+ }
479
+ /** Render a subagent agent file: md+frontmatter(name, description, tools, model) + prompt body. */
480
+ renderSubagent(agent) {
481
+ const frontmatter = {
482
+ name: agent.name,
483
+ description: agent.description
484
+ };
485
+ const allow = agent.tools?.allow;
486
+ if (allow && allow.length > 0) frontmatter.tools = allow.join(", ");
487
+ if (agent.model !== void 0) frontmatter.model = agent.model;
488
+ if (agent.extra) Object.assign(frontmatter, agent.extra);
489
+ return this.renderFrontmatterMd(frontmatter, agent.prompt);
490
+ }
491
+ // ── Diagnostics ──────────────────────────────────────────────────────────
492
+ getHealthChecks(ctx) {
493
+ const mcpPath = this.getServerConfigPath(ctx);
494
+ const hooksPath = this.getHookConfigPath(ctx);
495
+ const connectorId = ctx.connector.id;
496
+ const homeBin = ctx.homeBinPath;
497
+ const hookEvents = ctx.connector.hookEvents;
498
+ const checks = [
499
+ {
500
+ name: `${this.name}: mcp.json present`,
501
+ check: () => existsSync(mcpPath) ? { status: "OK", detail: mcpPath } : { status: "FAIL", detail: `not found: ${mcpPath}` }
502
+ },
503
+ {
504
+ name: `${this.name}: hook command registered`,
505
+ check: () => {
506
+ if (hookEvents.length === 0) {
507
+ return { status: "OK", detail: "no hooks declared" };
508
+ }
509
+ const file = this.readJson(hooksPath);
510
+ if (!file) return { status: "FAIL", detail: `not found: ${hooksPath}` };
511
+ if (file.version !== VSCODE_HOOKS_VERSION) {
512
+ return {
513
+ status: "FAIL",
514
+ detail: `${hooksPath} missing required "version": ${VSCODE_HOOKS_VERSION} \u2014 Copilot rejects it`
515
+ };
516
+ }
517
+ const registered = Object.values(file.hooks ?? {}).some(
518
+ (entries) => (entries ?? []).some(
519
+ (e) => isHomeBinHookCommand(e.command, homeBin, connectorId)
520
+ )
521
+ );
522
+ return registered ? { status: "OK", detail: "hook command present" } : { status: "FAIL", detail: `no hook for ${connectorId} in ${hooksPath}` };
523
+ }
524
+ }
525
+ ];
526
+ for (const cmd of ctx.connector.commands) {
527
+ const p = this.commandPath(ctx, cmd.name);
528
+ checks.push({
529
+ name: `${this.name}: command ${cmd.name} present`,
530
+ check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
531
+ });
532
+ }
533
+ for (const skill of ctx.connector.skills) {
534
+ const p = join(this.skillDir(ctx, skill.name), "SKILL.md");
535
+ checks.push({
536
+ name: `${this.name}: skill ${skill.name} present`,
537
+ check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
538
+ });
539
+ }
540
+ for (const agent of ctx.connector.subagents) {
541
+ const p = this.subagentPath(ctx, agent.name);
542
+ checks.push({
543
+ name: `${this.name}: subagent ${agent.name} present`,
544
+ check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
545
+ });
546
+ }
547
+ return checks;
548
+ }
549
+ // ── Runtime: parse VS Code Copilot stdin JSON → normalized event ──────────
550
+ parseEvent(event, raw) {
551
+ const input = raw ?? {};
552
+ const connectorId = typeof input.connector === "string" ? input.connector : "";
553
+ const sessionId = extractSessionId(input);
554
+ const projectDir = this.getProjectDir(input);
555
+ const base = {
556
+ hostPlatform: HOST,
557
+ connectorId,
558
+ sessionId,
559
+ raw,
560
+ ...projectDir !== void 0 ? { projectDir } : {}
561
+ };
562
+ switch (event) {
563
+ case "PreToolUse": {
564
+ const ev = {
565
+ ...base,
566
+ toolName: input.tool_name ?? "",
567
+ toolInput: input.tool_input ?? {}
568
+ };
569
+ return ev;
570
+ }
571
+ case "PostToolUse": {
572
+ const toolOutput = toolResponseToString(input.tool_response) ?? input.tool_output ?? input.error_message;
573
+ const ev = {
574
+ ...base,
575
+ toolName: input.tool_name ?? "",
576
+ toolInput: input.tool_input ?? {},
577
+ ...toolOutput !== void 0 ? { toolOutput } : {},
578
+ ...input.error_message ? { isError: true } : {}
579
+ };
580
+ return ev;
581
+ }
582
+ case "PreCompact": {
583
+ const ev = {
584
+ ...base,
585
+ ...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
586
+ };
587
+ return ev;
588
+ }
589
+ case "SessionStart": {
590
+ const ev = {
591
+ ...base,
592
+ source: normalizeSessionSource(input.source ?? input.trigger)
593
+ };
594
+ return ev;
595
+ }
596
+ case "SessionEnd": {
597
+ const ev = {
598
+ ...base,
599
+ ...typeof input.reason === "string" ? { reason: input.reason } : {}
600
+ };
601
+ return ev;
602
+ }
603
+ case "UserPromptSubmit": {
604
+ const ev = {
605
+ ...base,
606
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
607
+ };
608
+ return ev;
609
+ }
610
+ case "Stop": {
611
+ const ev = {
612
+ ...base,
613
+ ...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
614
+ };
615
+ return ev;
616
+ }
617
+ case "Notification": {
618
+ const ev = {
619
+ ...base,
620
+ message: typeof input.message === "string" ? input.message : ""
621
+ };
622
+ return ev;
623
+ }
624
+ default: {
625
+ const _never = event;
626
+ throw new Error(`unsupported vscode-copilot hook event: ${String(_never)}`);
627
+ }
628
+ }
629
+ }
630
+ /** Resolve the project dir from the wire payload, preferring the explicit cwd. */
631
+ getProjectDir(input) {
632
+ return input.cwd ?? input.workspace_roots?.[0] ?? void 0;
633
+ }
634
+ // ── Runtime: normalized response → VS Code Copilot native hook reply ──────
635
+ formatReply(event, response) {
636
+ const hookEventName = event;
637
+ const decision = response.decision ?? "allow";
638
+ if (decision === "deny") {
639
+ return this.stdout({
640
+ hookSpecificOutput: {
641
+ hookEventName,
642
+ permissionDecision: "deny",
643
+ permissionDecisionReason: response.reason ?? "Blocked by hook"
644
+ }
645
+ });
646
+ }
647
+ if (decision === "ask") {
648
+ return this.stdout({
649
+ hookSpecificOutput: {
650
+ hookEventName,
651
+ permissionDecision: "ask",
652
+ permissionDecisionReason: response.reason ?? "Confirmation required by hook"
653
+ }
654
+ });
655
+ }
656
+ if (decision === "modify") {
657
+ if (event === "PreToolUse" && response.updatedInput) {
658
+ return this.stdout({
659
+ hookSpecificOutput: { hookEventName, updatedInput: response.updatedInput }
660
+ });
661
+ }
662
+ }
663
+ if (decision === "context" && response.additionalContext) {
664
+ return this.stdout({
665
+ hookSpecificOutput: { hookEventName, additionalContext: response.additionalContext }
666
+ });
667
+ }
668
+ return { exitCode: 0 };
669
+ }
670
+ stdout(payload) {
671
+ return { exitCode: 0, stdout: JSON.stringify(payload) };
672
+ }
673
+ };
674
+ function vscodeEnvToken(name) {
675
+ return `\${env:${name}}`;
676
+ }
677
+ function extractSessionId(input) {
678
+ if (typeof input.transcript_path === "string") {
679
+ const m = input.transcript_path.match(/([a-f0-9-]{36})\.jsonl$/);
680
+ if (m && m[1]) return m[1];
681
+ }
682
+ if (typeof input.session_id === "string" && input.session_id !== "") {
683
+ return input.session_id;
684
+ }
685
+ return "";
686
+ }
687
+ function toolResponseToString(value) {
688
+ if (value == null) return void 0;
689
+ if (typeof value === "string") return value;
690
+ try {
691
+ return JSON.stringify(value);
692
+ } catch {
693
+ return String(value);
694
+ }
695
+ }
696
+ function normalizeSessionSource(source) {
697
+ switch (source) {
698
+ case "compact":
699
+ return "compact";
700
+ case "resume":
701
+ return "resume";
702
+ case "clear":
703
+ return "clear";
704
+ default:
705
+ return "startup";
706
+ }
707
+ }
708
+ var adapter = new VSCodeCopilotAdapter();
709
+ var vscode_copilot_default = adapter;
710
+ export {
711
+ VSCodeCopilotAdapter,
712
+ adapter,
713
+ vscode_copilot_default as default
714
+ };
715
+ //# sourceMappingURL=vscode-copilot-CK3NO54M.js.map