@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,633 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ BaseAdapter
4
+ } from "./chunk-TIIP3RG2.js";
5
+ import "./chunk-7L6ITC4T.js";
6
+ import {
7
+ buildHomeBinHookCommand,
8
+ isHomeBinHookCommand
9
+ } from "./chunk-MEH7GC7R.js";
10
+ import "./chunk-TRQKHP7D.js";
11
+
12
+ // src/adapters/jetbrains-copilot/index.ts
13
+ import { existsSync, rmSync } from "fs";
14
+ import { dirname, join } from "path";
15
+ var HOST = "jetbrains-copilot";
16
+ var JETBRAINS_HOOKS_VERSION = 1;
17
+ var EVENT_MAP = {
18
+ PreToolUse: "PreToolUse",
19
+ PostToolUse: "PostToolUse",
20
+ PreCompact: "PreCompact",
21
+ SessionStart: "SessionStart"
22
+ };
23
+ var JetBrainsCopilotAdapter = class extends BaseAdapter {
24
+ id = HOST;
25
+ name = "JetBrains Copilot";
26
+ paradigm = "json-stdio";
27
+ capabilities = {
28
+ // JetBrains Copilot's Preview hooks runtime delivers Pre/PostToolUse,
29
+ // PreCompact, and SessionStart (the four events its schema documents) —
30
+ // same surface as VS Code Copilot.
31
+ preToolUse: true,
32
+ postToolUse: true,
33
+ preCompact: true,
34
+ sessionStart: true,
35
+ sessionEnd: false,
36
+ userPromptSubmit: false,
37
+ stop: false,
38
+ notification: false,
39
+ // Per the JetBrains spec this host is deny/ask-only: a PreToolUse hook
40
+ // CANNOT rewrite tool input, and PostToolUse cannot rewrite tool output.
41
+ canModifyArgs: false,
42
+ canModifyOutput: false,
43
+ canInjectSessionContext: true,
44
+ // MCP is managed via the IDE Settings UI; the only transport that surfaces
45
+ // there is a local stdio server.
46
+ transports: ["stdio"],
47
+ // Content surfaces: JetBrains Copilot consumes the GitHub Copilot .github/
48
+ // files (it has no distinct authoring location), so it is an ALIAS of the
49
+ // vscode-copilot writer for prompt files and Agent Skills. It has no native
50
+ // subagent/chat-mode surface, so subagents stay unsupported (BaseAdapter
51
+ // returns the skip/warn default).
52
+ supportsCommands: true,
53
+ supportsSkills: true,
54
+ supportsSubagents: false
55
+ };
56
+ // ── Detection ────────────────────────────────────────────────────────────
57
+ detectInstalled(projectDir) {
58
+ const githubDir = join(projectDir, ".github");
59
+ const hooksDir = join(githubDir, "hooks");
60
+ const installed = existsSync(hooksDir) || existsSync(githubDir);
61
+ const configPath = hooksDir;
62
+ return {
63
+ id: this.id,
64
+ name: this.name,
65
+ installed,
66
+ paradigm: this.paradigm,
67
+ capabilities: this.capabilities,
68
+ configPath,
69
+ scope: "project",
70
+ reason: installed ? `found JetBrains Copilot hooks tree at ${hooksDir}` : `no JetBrains Copilot hooks tree at ${hooksDir}`,
71
+ confidence: installed ? "medium" : "low"
72
+ };
73
+ }
74
+ // ── Native paths ─────────────────────────────────────────────────────────
75
+ /** Hooks live under the workspace .github tree for both scopes. */
76
+ getConfigDir(ctx) {
77
+ return join(ctx.projectDir, ".github");
78
+ }
79
+ /**
80
+ * MCP server registration has NO writable file on JetBrains — the IDE owns it
81
+ * behind the Settings UI. We still return a stable path (the hooks file) so the
82
+ * base-adapter `doctor`/`backupSettings` helpers have a sensible target rather
83
+ * than a nonexistent/bogus MCP path. `installServer` never writes here.
84
+ */
85
+ getServerConfigPath(ctx) {
86
+ return this.getHookConfigPath(ctx);
87
+ }
88
+ /**
89
+ * Hook registration lives in the workspace-discovered .github/hooks tree, which
90
+ * JetBrains Copilot scans for *.json hook files. We write one file per connector
91
+ * so installs/uninstalls never clobber another connector's hooks. Anchored on
92
+ * projectDir for both scopes — .github/hooks is a workspace concept (there is no
93
+ * user-profile equivalent in the Copilot hooks schema).
94
+ */
95
+ getHookConfigPath(ctx) {
96
+ return join(ctx.projectDir, ".github", "hooks", `${ctx.connector.id}.json`);
97
+ }
98
+ // ── MCP server install / uninstall ───────────────────────────────────────
99
+ /**
100
+ * JetBrains MCP registration is UI-only. We never write a file: a bogus file is
101
+ * ignored at best and corrupts real UI-managed state at worst. Emit a "warn"
102
+ * ChangeRecord that tells the user exactly where to add the server by hand.
103
+ */
104
+ installServer(ctx) {
105
+ const { connector } = ctx;
106
+ const override = connector.platforms[HOST]?.server;
107
+ if (!connector.server || override === false) {
108
+ return [
109
+ {
110
+ platform: this.id,
111
+ action: "skip",
112
+ detail: connector.server ? "server registration disabled for jetbrains-copilot" : "connector declares no MCP server"
113
+ }
114
+ ];
115
+ }
116
+ return [
117
+ {
118
+ platform: this.id,
119
+ action: "warn",
120
+ detail: `JetBrains Copilot manages MCP servers via the IDE Settings UI \u2014 add "${connector.id}" manually under Settings > Tools > GitHub Copilot > MCP > Configure (no file is written here).`
121
+ }
122
+ ];
123
+ }
124
+ /**
125
+ * Nothing was written for the MCP server, so there is nothing to remove. Mirror
126
+ * the install-time guidance as a "warn" so an uninstall report is honest about
127
+ * the UI-managed entry the user may still want to remove by hand.
128
+ */
129
+ uninstallServer(ctx) {
130
+ const { connector } = ctx;
131
+ if (!connector.server || connector.platforms[HOST]?.server === false) {
132
+ return [
133
+ {
134
+ platform: this.id,
135
+ action: "skip",
136
+ detail: "no MCP server was registered for jetbrains-copilot"
137
+ }
138
+ ];
139
+ }
140
+ return [
141
+ {
142
+ platform: this.id,
143
+ action: "warn",
144
+ detail: `JetBrains Copilot MCP servers are UI-managed \u2014 if "${connector.id}" was added manually, remove it under Settings > Tools > GitHub Copilot > MCP.`
145
+ }
146
+ ];
147
+ }
148
+ // ── Hook install / uninstall ─────────────────────────────────────────────
149
+ installHooks(ctx) {
150
+ const { connector } = ctx;
151
+ if (connector.platforms[HOST]?.hooks === false) {
152
+ return [
153
+ { platform: this.id, action: "skip", detail: "hooks disabled for jetbrains-copilot" }
154
+ ];
155
+ }
156
+ if (connector.hookEvents.length === 0) {
157
+ return [{ platform: this.id, action: "skip", detail: "connector declares no hooks" }];
158
+ }
159
+ const hooksPath = this.getHookConfigPath(ctx);
160
+ const file = this.readJson(hooksPath) ?? {};
161
+ const hooks = file.hooks ??= {};
162
+ const changes = [];
163
+ let mutated = false;
164
+ for (const event of connector.hookEvents) {
165
+ const jetbrainsEvent = EVENT_MAP[event];
166
+ if (!jetbrainsEvent) {
167
+ changes.push({
168
+ platform: this.id,
169
+ action: "warn",
170
+ path: hooksPath,
171
+ detail: `${event} has no JetBrains Copilot hook equivalent \u2014 skipped`
172
+ });
173
+ continue;
174
+ }
175
+ const command = buildHomeBinHookCommand(ctx.homeBinPath, HOST, event, connector.id);
176
+ const entry = { type: "command", command };
177
+ const bucket = hooks[jetbrainsEvent] ??= [];
178
+ const existingIdx = bucket.findIndex((e) => this.isOurCommand(e.command, ctx));
179
+ if (existingIdx >= 0) {
180
+ if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {
181
+ changes.push({
182
+ platform: this.id,
183
+ action: "skip",
184
+ path: hooksPath,
185
+ detail: `hooks.${jetbrainsEvent} already registered`
186
+ });
187
+ continue;
188
+ }
189
+ bucket[existingIdx] = entry;
190
+ changes.push({
191
+ platform: this.id,
192
+ action: "update",
193
+ path: hooksPath,
194
+ detail: `hooks.${jetbrainsEvent}`
195
+ });
196
+ } else {
197
+ bucket.push(entry);
198
+ changes.push({
199
+ platform: this.id,
200
+ action: "create",
201
+ path: hooksPath,
202
+ detail: `hooks.${jetbrainsEvent}`
203
+ });
204
+ }
205
+ mutated = true;
206
+ }
207
+ if (mutated) {
208
+ file.version = JETBRAINS_HOOKS_VERSION;
209
+ this.writeJson(hooksPath, file, ctx.dryRun);
210
+ }
211
+ return changes;
212
+ }
213
+ uninstallHooks(ctx) {
214
+ const hooksPath = this.getHookConfigPath(ctx);
215
+ const file = this.readJson(hooksPath);
216
+ const hooks = file?.hooks;
217
+ if (!file || !hooks) {
218
+ return [
219
+ {
220
+ platform: this.id,
221
+ action: "skip",
222
+ path: hooksPath,
223
+ detail: "no hooks section present"
224
+ }
225
+ ];
226
+ }
227
+ const changes = [];
228
+ let mutated = false;
229
+ for (const jetbrainsEvent of Object.keys(hooks)) {
230
+ const bucket = hooks[jetbrainsEvent];
231
+ if (!Array.isArray(bucket)) continue;
232
+ const before = bucket.length;
233
+ const next = bucket.filter((e) => !this.isOurCommand(e.command, ctx));
234
+ const removed = before - next.length;
235
+ if (removed > 0) {
236
+ if (next.length > 0) hooks[jetbrainsEvent] = next;
237
+ else delete hooks[jetbrainsEvent];
238
+ changes.push({
239
+ platform: this.id,
240
+ action: "remove",
241
+ path: hooksPath,
242
+ detail: `hooks.${jetbrainsEvent} (${removed})`
243
+ });
244
+ mutated = true;
245
+ }
246
+ }
247
+ if (mutated) {
248
+ if (Object.keys(hooks).length === 0) {
249
+ if (!ctx.dryRun) rmSync(hooksPath, { force: true });
250
+ changes.push({
251
+ platform: this.id,
252
+ action: "remove",
253
+ path: hooksPath,
254
+ detail: "removed empty connector hooks file"
255
+ });
256
+ changes.push(this.removeDirIfEmpty(dirname(hooksPath), ctx.dryRun));
257
+ } else {
258
+ this.writeJson(hooksPath, file, ctx.dryRun);
259
+ }
260
+ }
261
+ if (changes.length === 0) {
262
+ changes.push({
263
+ platform: this.id,
264
+ action: "skip",
265
+ path: hooksPath,
266
+ detail: "no matching hook entries"
267
+ });
268
+ }
269
+ return changes;
270
+ }
271
+ /** True when a hook command references our home binary AND this connector id
272
+ * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand). */
273
+ isOurCommand(command, ctx) {
274
+ return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);
275
+ }
276
+ // ── Content surfaces: commands / skills ──────────────────────────────────
277
+ // CONTENT-ONLY: pure native-file writers under the workspace .github/ tree
278
+ // ({prompts,skills}). No runtime dispatch, no home-bin pointer, no telemetry
279
+ // wrap. Each method is idempotent (byte-identical → skip) via
280
+ // BaseAdapter.writeContentFile and reversible via removeContentFile. Honors
281
+ // platforms["jetbrains-copilot"] per-surface false to skip.
282
+ //
283
+ // ALIAS of vscode-copilot: JetBrains consumes the GitHub Copilot .github/
284
+ // files and has no distinct authoring location, so the rendered content +
285
+ // paths here are IDENTICAL to the vscode-copilot writer.
286
+ //
287
+ // SHARED .github TREE: vscode-copilot, copilot-cli, and jetbrains-copilot all
288
+ // write under the SAME project <projectDir>/.github tree. The rendered content
289
+ // is identical and idempotent across those connectors, and uninstall here only
290
+ // removes the files THIS connector declared — never another writer's files.
291
+ //
292
+ // SCOPE NOTE: .github is a workspace concept and this adapter is project-
293
+ // scoped (no user-profile .github authoring location exists in the Copilot
294
+ // prompt/skill discovery), so the content root is always the project .github
295
+ // tree — the same dir getConfigDir already anchors on.
296
+ /** Root of the content tree — the project .github tree (see getConfigDir). */
297
+ contentRootDir(ctx) {
298
+ return this.getConfigDir(ctx);
299
+ }
300
+ promptsDir(ctx) {
301
+ return join(this.contentRootDir(ctx), "prompts");
302
+ }
303
+ skillsDir(ctx) {
304
+ return join(this.contentRootDir(ctx), "skills");
305
+ }
306
+ /** Native command file path: <ghDir>/prompts/<name>.prompt.md. */
307
+ commandPath(ctx, name) {
308
+ return join(this.promptsDir(ctx), `${name}.prompt.md`);
309
+ }
310
+ /** Native skill dir: <ghDir>/skills/<name>. */
311
+ skillDir(ctx, name) {
312
+ return join(this.skillsDir(ctx), name);
313
+ }
314
+ // ── Commands ──────────────────────────────────────────────────────────────
315
+ installCommands(ctx) {
316
+ const { connector } = ctx;
317
+ if (connector.platforms[HOST]?.commands === false) {
318
+ return [{ platform: this.id, action: "skip", detail: "commands disabled for jetbrains-copilot" }];
319
+ }
320
+ if (connector.commands.length === 0) {
321
+ return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
322
+ }
323
+ return connector.commands.map(
324
+ (cmd) => this.writeContentFile(
325
+ this.commandPath(ctx, cmd.name),
326
+ this.renderCommand(cmd),
327
+ ctx.dryRun
328
+ )
329
+ );
330
+ }
331
+ uninstallCommands(ctx) {
332
+ const { connector } = ctx;
333
+ if (connector.commands.length === 0) {
334
+ return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
335
+ }
336
+ return connector.commands.map(
337
+ (cmd) => this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun)
338
+ );
339
+ }
340
+ /** Render a Copilot prompt file: md+frontmatter(description, tools, model, argument-hint). */
341
+ renderCommand(cmd) {
342
+ const frontmatter = {};
343
+ if (cmd.description !== void 0) frontmatter.description = cmd.description;
344
+ const allow = cmd.tools?.allow;
345
+ if (allow && allow.length > 0) frontmatter.tools = [...allow];
346
+ if (cmd.model !== void 0) frontmatter.model = cmd.model;
347
+ if (cmd.argumentHint !== void 0) frontmatter["argument-hint"] = cmd.argumentHint;
348
+ if (cmd.extra) Object.assign(frontmatter, cmd.extra);
349
+ return this.renderFrontmatterMd(frontmatter, cmd.prompt);
350
+ }
351
+ // ── Skills ────────────────────────────────────────────────────────────────
352
+ installSkills(ctx) {
353
+ const { connector } = ctx;
354
+ if (connector.platforms[HOST]?.skills === false) {
355
+ return [{ platform: this.id, action: "skip", detail: "skills disabled for jetbrains-copilot" }];
356
+ }
357
+ if (connector.skills.length === 0) {
358
+ return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
359
+ }
360
+ const changes = [];
361
+ for (const skill of connector.skills) {
362
+ const dir = this.skillDir(ctx, skill.name);
363
+ changes.push(
364
+ this.writeContentFile(join(dir, "SKILL.md"), this.renderSkill(skill), ctx.dryRun)
365
+ );
366
+ for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
367
+ const target = this.resolveWithin(dir, rel);
368
+ if (target === null) {
369
+ changes.push({
370
+ platform: this.id,
371
+ action: "warn",
372
+ detail: `skill resource "${rel}" escapes the skill dir; skipped`
373
+ });
374
+ continue;
375
+ }
376
+ changes.push(this.writeContentFile(target, contents, ctx.dryRun));
377
+ }
378
+ }
379
+ return changes;
380
+ }
381
+ uninstallSkills(ctx) {
382
+ const { connector } = ctx;
383
+ if (connector.skills.length === 0) {
384
+ return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
385
+ }
386
+ const changes = [];
387
+ for (const skill of connector.skills) {
388
+ const dir = this.skillDir(ctx, skill.name);
389
+ changes.push(this.removeContentFile(join(dir, "SKILL.md"), ctx.dryRun));
390
+ for (const rel of Object.keys(skill.resources ?? {})) {
391
+ const target = this.resolveWithin(dir, rel);
392
+ if (target === null) continue;
393
+ changes.push(this.removeContentFile(target, ctx.dryRun));
394
+ }
395
+ changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));
396
+ }
397
+ return changes;
398
+ }
399
+ /**
400
+ * Render a skill's SKILL.md — the uniform Agent Skills format: frontmatter
401
+ * (name, description + optional model, allowed-tools, disable-model-invocation)
402
+ * + body. Byte-identical to the other .github-sharing connectors so a shared
403
+ * skill folder never thrashes.
404
+ */
405
+ renderSkill(skill) {
406
+ const frontmatter = {
407
+ name: skill.name,
408
+ description: skill.description
409
+ };
410
+ if (skill.model !== void 0) frontmatter.model = skill.model;
411
+ const allow = skill.tools?.allow;
412
+ if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
413
+ if (skill.disableModelInvocation !== void 0) {
414
+ frontmatter["disable-model-invocation"] = skill.disableModelInvocation;
415
+ }
416
+ if (skill.extra) Object.assign(frontmatter, skill.extra);
417
+ return this.renderFrontmatterMd(frontmatter, skill.body);
418
+ }
419
+ // ── Diagnostics ──────────────────────────────────────────────────────────
420
+ getHealthChecks(ctx) {
421
+ const hooksPath = this.getHookConfigPath(ctx);
422
+ const connectorId = ctx.connector.id;
423
+ const homeBin = ctx.homeBinPath;
424
+ const hookEvents = ctx.connector.hookEvents;
425
+ const hasServer = ctx.connector.server != null && ctx.connector.platforms[HOST]?.server !== false;
426
+ const checks = [
427
+ {
428
+ // MCP cannot be verified from disk — JetBrains owns it behind the UI.
429
+ // BaseAdapter.doctor maps != OK to a hard FAIL, but an unverifiable
430
+ // UI-managed surface must NOT hard-fail doctor (that contradicts the
431
+ // install-time WARN). Return OK with a verify-in-UI detail instead.
432
+ name: `${this.name}: MCP server (UI-managed)`,
433
+ check: () => hasServer ? {
434
+ status: "OK",
435
+ detail: "MCP is UI-managed \u2014 verify in Settings > Tools > GitHub Copilot > MCP"
436
+ } : { status: "OK", detail: "connector declares no MCP server" }
437
+ },
438
+ {
439
+ name: `${this.name}: hook command registered`,
440
+ check: () => {
441
+ if (hookEvents.length === 0) {
442
+ return { status: "OK", detail: "no hooks declared" };
443
+ }
444
+ const file = this.readJson(hooksPath);
445
+ if (!file) return { status: "FAIL", detail: `not found: ${hooksPath}` };
446
+ if (file.version !== JETBRAINS_HOOKS_VERSION) {
447
+ return {
448
+ status: "FAIL",
449
+ detail: `${hooksPath} missing required "version": ${JETBRAINS_HOOKS_VERSION} \u2014 Copilot rejects it`
450
+ };
451
+ }
452
+ const registered = Object.values(file.hooks ?? {}).some(
453
+ (entries) => (entries ?? []).some(
454
+ (e) => isHomeBinHookCommand(e.command, homeBin, connectorId)
455
+ )
456
+ );
457
+ return registered ? { status: "OK", detail: "hook command present" } : { status: "FAIL", detail: `no hook for ${connectorId} in ${hooksPath}` };
458
+ }
459
+ }
460
+ ];
461
+ for (const cmd of ctx.connector.commands) {
462
+ const p = this.commandPath(ctx, cmd.name);
463
+ checks.push({
464
+ name: `${this.name}: command ${cmd.name} present`,
465
+ check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
466
+ });
467
+ }
468
+ for (const skill of ctx.connector.skills) {
469
+ const p = join(this.skillDir(ctx, skill.name), "SKILL.md");
470
+ checks.push({
471
+ name: `${this.name}: skill ${skill.name} present`,
472
+ check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
473
+ });
474
+ }
475
+ return checks;
476
+ }
477
+ // ── Runtime: parse JetBrains Copilot stdin JSON → normalized event ────────
478
+ parseEvent(event, raw) {
479
+ const input = raw ?? {};
480
+ const connectorId = typeof input.connector === "string" ? input.connector : "";
481
+ const sessionId = extractSessionId(input);
482
+ const projectDir = this.getProjectDir(input);
483
+ const base = {
484
+ hostPlatform: HOST,
485
+ connectorId,
486
+ sessionId,
487
+ raw,
488
+ ...projectDir !== void 0 ? { projectDir } : {}
489
+ };
490
+ switch (event) {
491
+ case "PreToolUse": {
492
+ const ev = {
493
+ ...base,
494
+ toolName: input.tool_name ?? "",
495
+ toolInput: input.tool_input ?? {}
496
+ };
497
+ return ev;
498
+ }
499
+ case "PostToolUse": {
500
+ const toolOutput = toolResponseToString(input.tool_response) ?? input.tool_output ?? input.error_message;
501
+ const ev = {
502
+ ...base,
503
+ toolName: input.tool_name ?? "",
504
+ toolInput: input.tool_input ?? {},
505
+ ...toolOutput !== void 0 ? { toolOutput } : {},
506
+ ...input.error_message ? { isError: true } : {}
507
+ };
508
+ return ev;
509
+ }
510
+ case "PreCompact": {
511
+ const ev = {
512
+ ...base,
513
+ ...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
514
+ };
515
+ return ev;
516
+ }
517
+ case "SessionStart": {
518
+ const ev = {
519
+ ...base,
520
+ source: normalizeSessionSource(input.source ?? input.trigger)
521
+ };
522
+ return ev;
523
+ }
524
+ case "SessionEnd": {
525
+ const ev = {
526
+ ...base,
527
+ ...typeof input.reason === "string" ? { reason: input.reason } : {}
528
+ };
529
+ return ev;
530
+ }
531
+ case "UserPromptSubmit": {
532
+ const ev = {
533
+ ...base,
534
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
535
+ };
536
+ return ev;
537
+ }
538
+ case "Stop": {
539
+ const ev = {
540
+ ...base,
541
+ ...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
542
+ };
543
+ return ev;
544
+ }
545
+ case "Notification": {
546
+ const ev = {
547
+ ...base,
548
+ message: typeof input.message === "string" ? input.message : ""
549
+ };
550
+ return ev;
551
+ }
552
+ default: {
553
+ const _never = event;
554
+ throw new Error(`unsupported jetbrains-copilot hook event: ${String(_never)}`);
555
+ }
556
+ }
557
+ }
558
+ /** Resolve the project dir from the wire payload, preferring the explicit cwd. */
559
+ getProjectDir(input) {
560
+ return input.cwd ?? input.workspace_roots?.[0] ?? void 0;
561
+ }
562
+ // ── Runtime: normalized response → JetBrains Copilot native hook reply ────
563
+ formatReply(event, response) {
564
+ const hookEventName = event;
565
+ const decision = response.decision ?? "allow";
566
+ if (decision === "deny") {
567
+ return this.stdout({
568
+ hookSpecificOutput: {
569
+ hookEventName,
570
+ permissionDecision: "deny",
571
+ permissionDecisionReason: response.reason ?? "Blocked by hook"
572
+ }
573
+ });
574
+ }
575
+ if (decision === "ask") {
576
+ return this.stdout({
577
+ hookSpecificOutput: {
578
+ hookEventName,
579
+ permissionDecision: "ask",
580
+ permissionDecisionReason: response.reason ?? "Confirmation required by hook"
581
+ }
582
+ });
583
+ }
584
+ if (decision === "context" && response.additionalContext) {
585
+ return this.stdout({
586
+ hookSpecificOutput: { hookEventName, additionalContext: response.additionalContext }
587
+ });
588
+ }
589
+ return { exitCode: 0 };
590
+ }
591
+ stdout(payload) {
592
+ return { exitCode: 0, stdout: JSON.stringify(payload) };
593
+ }
594
+ };
595
+ function extractSessionId(input) {
596
+ if (typeof input.transcript_path === "string") {
597
+ const m = input.transcript_path.match(/([a-f0-9-]{36})\.jsonl$/);
598
+ if (m && m[1]) return m[1];
599
+ }
600
+ if (typeof input.session_id === "string" && input.session_id !== "") {
601
+ return input.session_id;
602
+ }
603
+ return "";
604
+ }
605
+ function toolResponseToString(value) {
606
+ if (value == null) return void 0;
607
+ if (typeof value === "string") return value;
608
+ try {
609
+ return JSON.stringify(value);
610
+ } catch {
611
+ return String(value);
612
+ }
613
+ }
614
+ function normalizeSessionSource(source) {
615
+ switch (source) {
616
+ case "compact":
617
+ return "compact";
618
+ case "resume":
619
+ return "resume";
620
+ case "clear":
621
+ return "clear";
622
+ default:
623
+ return "startup";
624
+ }
625
+ }
626
+ var adapter = new JetBrainsCopilotAdapter();
627
+ var jetbrains_copilot_default = adapter;
628
+ export {
629
+ JetBrainsCopilotAdapter,
630
+ adapter,
631
+ jetbrains_copilot_default as default
632
+ };
633
+ //# sourceMappingURL=jetbrains-copilot-HWA3DMH7.js.map