@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,800 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ getTokenizer,
4
+ inferModelFamily,
5
+ newRecordId,
6
+ openStore,
7
+ worstConfidence
8
+ } from "./chunk-BCHWFTV4.js";
9
+ import {
10
+ log
11
+ } from "./chunk-KHO5WNTP.js";
12
+ import {
13
+ LineBuffer,
14
+ idKey,
15
+ isObject,
16
+ spawnChild
17
+ } from "./chunk-WCETQWWK.js";
18
+ import {
19
+ REGISTERED_PLATFORM_IDS,
20
+ detectRuntimeHost,
21
+ loadAdapter
22
+ } from "./chunk-XUCWLJY5.js";
23
+ import {
24
+ loadRegisteredConnector
25
+ } from "./chunk-LTT56GI3.js";
26
+ import {
27
+ detectLaunchMethod
28
+ } from "./chunk-MEH7GC7R.js";
29
+ import {
30
+ dataRoot,
31
+ ensureDir,
32
+ projectIdentity
33
+ } from "./chunk-TRQKHP7D.js";
34
+
35
+ // src/telemetry/measure.ts
36
+ var MODALITY_ESTIMATE = {
37
+ image: 85,
38
+ audio: 85,
39
+ resource: 85
40
+ };
41
+ var UNKNOWN_BLOCK_ESTIMATE = 85;
42
+ function combineSources(sources) {
43
+ let worst = "host-native";
44
+ for (const s of sources) worst = worstConfidence(worst, s);
45
+ return worst;
46
+ }
47
+ function isObject2(v) {
48
+ return typeof v === "object" && v !== null;
49
+ }
50
+ function isTextBlock(block) {
51
+ return block.type === "text";
52
+ }
53
+ function measureToolCall(args, result, family, tok = getTokenizer()) {
54
+ const input = tok.countValue(args, family);
55
+ const output = measureResult(result, family, tok);
56
+ return {
57
+ inputTokens: input.tokens,
58
+ outputTokens: output.tokens,
59
+ source: worstConfidence(input.source, output.source)
60
+ };
61
+ }
62
+ function measureResult(result, family, tok) {
63
+ if (!isObject2(result)) {
64
+ return tok.countValue(result, family);
65
+ }
66
+ const res = result;
67
+ const sources = [];
68
+ let tokens = 0;
69
+ if (Array.isArray(res.content)) {
70
+ for (const raw of res.content) {
71
+ if (!isObject2(raw)) continue;
72
+ const block = raw;
73
+ if (isTextBlock(block)) {
74
+ const text = typeof block.text === "string" ? block.text : "";
75
+ const c = tok.count(text, family);
76
+ tokens += c.tokens;
77
+ sources.push(c.source);
78
+ } else {
79
+ const key = typeof block.type === "string" ? block.type : "";
80
+ tokens += MODALITY_ESTIMATE[key] ?? UNKNOWN_BLOCK_ESTIMATE;
81
+ sources.push("tokenizer-approx");
82
+ }
83
+ }
84
+ } else if (res.content !== void 0) {
85
+ const c = tok.countValue(res.content, family);
86
+ tokens += c.tokens;
87
+ sources.push(c.source);
88
+ }
89
+ if (res.structuredContent !== void 0) {
90
+ const c = tok.countValue(res.structuredContent, family);
91
+ tokens += c.tokens;
92
+ sources.push(c.source);
93
+ }
94
+ if (sources.length === 0) {
95
+ return tok.countValue(result, family);
96
+ }
97
+ return { tokens, source: combineSources(sources) };
98
+ }
99
+ function measureToolDefs(tools, family, tok = getTokenizer()) {
100
+ return tok.countValue(tools, family);
101
+ }
102
+ function measureHook(eventPayload, handlerReturn, family, tok = getTokenizer()) {
103
+ const input = tok.countValue(eventPayload, family);
104
+ const output = tok.countValue(handlerReturn, family);
105
+ return {
106
+ inputTokens: input.tokens,
107
+ outputTokens: output.tokens,
108
+ source: worstConfidence(input.source, output.source)
109
+ };
110
+ }
111
+
112
+ // src/runtime/hook-entrypoint.ts
113
+ var ALLOW = { exitCode: 0 };
114
+ function eventToolName(evt) {
115
+ const name = evt.toolName;
116
+ return typeof name === "string" ? name : void 0;
117
+ }
118
+ function parseStdin(stdin) {
119
+ const trimmed = stdin.trim();
120
+ if (trimmed === "") return {};
121
+ try {
122
+ return JSON.parse(trimmed);
123
+ } catch {
124
+ return {};
125
+ }
126
+ }
127
+ function compileMatcher(matcher) {
128
+ if (!matcher || matcher === "") return null;
129
+ try {
130
+ return new RegExp(matcher);
131
+ } catch {
132
+ return null;
133
+ }
134
+ }
135
+ function normalizeResponse(value) {
136
+ if (value == null || typeof value !== "object") return { decision: "allow" };
137
+ return value;
138
+ }
139
+ function resolveHookHostPlatform(platformId, evt) {
140
+ const override = process.env.AGENT_CONNECTOR_HOST;
141
+ if (override !== void 0 && REGISTERED_PLATFORM_IDS.has(override)) {
142
+ return override;
143
+ }
144
+ if (REGISTERED_PLATFORM_IDS.has(platformId)) {
145
+ return platformId;
146
+ }
147
+ const fromEvent = evt.hostPlatform;
148
+ if (typeof fromEvent === "string" && REGISTERED_PLATFORM_IDS.has(fromEvent)) {
149
+ return fromEvent;
150
+ }
151
+ return "unknown";
152
+ }
153
+ function recordHookTelemetry(opts, connector, evt, response) {
154
+ if (process.env.AGENT_CONNECTOR_TELEMETRY === "0") return;
155
+ try {
156
+ const family = inferModelFamily("", connector.telemetry.modelFamilyHint);
157
+ const measurement = measureHook(evt, response, family, getTokenizer());
158
+ const sessionId = typeof evt.sessionId === "string" ? evt.sessionId : "";
159
+ const evtProjectDir = evt.projectDir;
160
+ const projectDir = typeof evtProjectDir === "string" && evtProjectDir !== "" ? evtProjectDir : process.cwd();
161
+ const id = projectIdentity(projectDir);
162
+ const store = openStore({});
163
+ try {
164
+ store.append({
165
+ id: newRecordId(0),
166
+ ts: Date.now(),
167
+ connectorId: opts.connectorId,
168
+ toolName: opts.event,
169
+ // for a hook row the per-item name IS the event
170
+ scope: "hook",
171
+ surfaceKind: "hook",
172
+ hostPlatform: resolveHookHostPlatform(opts.platformId, evt),
173
+ sessionId,
174
+ projectKey: id.key,
175
+ projectDir: id.dir,
176
+ inputTokens: measurement.inputTokens,
177
+ outputTokens: measurement.outputTokens,
178
+ confidenceSource: measurement.source,
179
+ isError: false
180
+ });
181
+ } finally {
182
+ store.close();
183
+ }
184
+ } catch {
185
+ }
186
+ }
187
+ async function runHook(opts) {
188
+ const { platformId, event, connectorId, stdin } = opts;
189
+ try {
190
+ const connector = await loadRegisteredConnector(connectorId);
191
+ const adapter = await loadAdapter(platformId);
192
+ if (!adapter || !adapter.parseEvent || !adapter.formatReply) {
193
+ return ALLOW;
194
+ }
195
+ const raw = parseStdin(stdin);
196
+ const evt = adapter.parseEvent(event, raw);
197
+ evt.connectorId = connectorId;
198
+ const definition = connector.hooks[event];
199
+ if (!definition || typeof definition.handler !== "function") {
200
+ return ALLOW;
201
+ }
202
+ const toolName = eventToolName(evt);
203
+ if (toolName !== void 0) {
204
+ const re = compileMatcher(definition.matcher);
205
+ if (re && !re.test(toolName)) return ALLOW;
206
+ }
207
+ const handlerResult = await definition.handler(
208
+ // The adapter parsed `evt` as exactly this event's payload type; the
209
+ // HooksConfig handler for the same event expects that payload.
210
+ evt
211
+ );
212
+ const response = normalizeResponse(handlerResult);
213
+ recordHookTelemetry(opts, connector, evt, response);
214
+ const reply = adapter.formatReply(event, response);
215
+ return {
216
+ exitCode: reply.exitCode,
217
+ ...reply.stdout !== void 0 ? { stdout: reply.stdout } : {},
218
+ ...reply.stderr !== void 0 ? { stderr: reply.stderr } : {}
219
+ };
220
+ } catch (err) {
221
+ const message = err instanceof Error ? err.message : String(err);
222
+ log.error(`hook ${platformId}/${event} (${connectorId}) failed:`, message);
223
+ return failOpenOrPreserveDeny(opts, message);
224
+ }
225
+ }
226
+ async function failOpenOrPreserveDeny(opts, errorMessage) {
227
+ if (opts.event !== "PreToolUse") return ALLOW;
228
+ try {
229
+ const connector = await loadRegisteredConnector(opts.connectorId);
230
+ const adapter = await loadAdapter(opts.platformId);
231
+ if (!adapter?.parseEvent || !adapter.formatReply) return ALLOW;
232
+ const definition = connector.hooks.PreToolUse;
233
+ if (!definition || typeof definition.handler !== "function") return ALLOW;
234
+ const raw = parseStdin(opts.stdin);
235
+ const evt = adapter.parseEvent("PreToolUse", raw);
236
+ evt.connectorId = opts.connectorId;
237
+ const toolName = eventToolName(evt);
238
+ if (toolName !== void 0) {
239
+ const re = compileMatcher(definition.matcher);
240
+ if (re && !re.test(toolName)) return ALLOW;
241
+ }
242
+ const response = normalizeResponse(await definition.handler(evt));
243
+ if (response.decision !== "deny") return ALLOW;
244
+ const reply = adapter.formatReply("PreToolUse", response);
245
+ return {
246
+ exitCode: reply.exitCode,
247
+ ...reply.stdout !== void 0 ? { stdout: reply.stdout } : {},
248
+ ...reply.stderr !== void 0 ? { stderr: reply.stderr } : { stderr: errorMessage }
249
+ };
250
+ } catch {
251
+ return ALLOW;
252
+ }
253
+ }
254
+
255
+ // src/runtime/serve.ts
256
+ import { randomUUID } from "crypto";
257
+
258
+ // src/telemetry/calibration.ts
259
+ import { existsSync, readFileSync, writeFileSync } from "fs";
260
+ import { join } from "path";
261
+ function isCalibrationEnabled() {
262
+ const families = (process.env.AGENT_CONNECTOR_CALIBRATE || "").split(",").map((s) => s.trim()).filter((s) => s !== "");
263
+ const key = (process.env.ANTHROPIC_API_KEY || "").trim();
264
+ return families.includes("anthropic") && key !== "";
265
+ }
266
+ function calibrationPath() {
267
+ return join(dataRoot(), "calibration.json");
268
+ }
269
+ var RATIO_MIN = 0.2;
270
+ var RATIO_MAX = 5;
271
+ function clampRatio(ratio) {
272
+ if (!Number.isFinite(ratio) || ratio <= 0) return null;
273
+ if (ratio < RATIO_MIN) return RATIO_MIN;
274
+ if (ratio > RATIO_MAX) return RATIO_MAX;
275
+ return ratio;
276
+ }
277
+ function loadFactors() {
278
+ const path = calibrationPath();
279
+ if (!existsSync(path)) return {};
280
+ try {
281
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
282
+ if (parsed === null || typeof parsed !== "object") return {};
283
+ const out = {};
284
+ for (const [family, value] of Object.entries(parsed)) {
285
+ if (value === null || typeof value !== "object") continue;
286
+ const rec = value;
287
+ const factor = rec["factor"];
288
+ const samples = rec["samples"];
289
+ if (typeof factor === "number" && Number.isFinite(factor) && factor > 0 && typeof samples === "number" && Number.isFinite(samples) && samples >= 0) {
290
+ out[family] = {
291
+ factor,
292
+ samples
293
+ };
294
+ }
295
+ }
296
+ return out;
297
+ } catch {
298
+ return {};
299
+ }
300
+ }
301
+ function recordSample(family, ratio) {
302
+ const clamped = clampRatio(ratio);
303
+ if (clamped === null) return;
304
+ try {
305
+ const factors = loadFactors();
306
+ const prior = factors[family];
307
+ let next;
308
+ if (prior === void 0 || prior.samples <= 0) {
309
+ next = { factor: clamped, samples: 1 };
310
+ } else {
311
+ const samples = prior.samples + 1;
312
+ const factor = prior.factor + (clamped - prior.factor) / samples;
313
+ next = { factor, samples };
314
+ }
315
+ const updated = { ...factors, [family]: next };
316
+ const path = calibrationPath();
317
+ ensureDir(dataRoot());
318
+ writeFileSync(path, `${JSON.stringify(updated, null, 2)}
319
+ `, "utf8");
320
+ } catch {
321
+ }
322
+ }
323
+ var DEFAULT_ANTHROPIC_MODEL = "claude-3-5-sonnet-latest";
324
+ var COUNT_TOKENS_URL = "https://api.anthropic.com/v1/messages/count_tokens";
325
+ async function countTokensAnthropic(text, model = DEFAULT_ANTHROPIC_MODEL) {
326
+ const apiKey = (process.env.ANTHROPIC_API_KEY || "").trim();
327
+ if (apiKey === "") return null;
328
+ try {
329
+ const res = await fetch(COUNT_TOKENS_URL, {
330
+ method: "POST",
331
+ headers: {
332
+ "x-api-key": apiKey,
333
+ "anthropic-version": "2023-06-01",
334
+ "content-type": "application/json"
335
+ },
336
+ body: JSON.stringify({
337
+ model,
338
+ messages: [{ role: "user", content: text }]
339
+ })
340
+ });
341
+ if (!res.ok) return null;
342
+ const body = await res.json();
343
+ const n = body.input_tokens;
344
+ if (typeof n === "number" && Number.isFinite(n) && n >= 0) {
345
+ return n;
346
+ }
347
+ return null;
348
+ } catch {
349
+ return null;
350
+ }
351
+ }
352
+ var SAMPLE_EVERY = 20;
353
+ var MAX_SAMPLES_PER_MINUTE = 10;
354
+ var callCounter = 0;
355
+ var windowStartMs = 0;
356
+ var samplesThisWindow = 0;
357
+ function shouldSample(now = Date.now()) {
358
+ if (now - windowStartMs >= 6e4) {
359
+ windowStartMs = now;
360
+ samplesThisWindow = 0;
361
+ }
362
+ callCounter += 1;
363
+ if (callCounter % SAMPLE_EVERY !== 0) return false;
364
+ if (samplesThisWindow >= MAX_SAMPLES_PER_MINUTE) return false;
365
+ samplesThisWindow += 1;
366
+ return true;
367
+ }
368
+ function applyCalibration(approxTokens, family, factors = loadFactors()) {
369
+ if (family === "anthropic") {
370
+ const f = factors[family];
371
+ if (f !== void 0 && f.samples > 0 && Number.isFinite(f.factor) && f.factor > 0) {
372
+ return {
373
+ tokens: Math.max(0, Math.round(approxTokens * f.factor)),
374
+ source: "tokenizer-calibrated"
375
+ };
376
+ }
377
+ }
378
+ return { tokens: approxTokens, source: "tokenizer-approx" };
379
+ }
380
+ function modelForFamily(_family) {
381
+ return DEFAULT_ANTHROPIC_MODEL;
382
+ }
383
+
384
+ // src/telemetry/proxy.ts
385
+ function canonicalArgs(value) {
386
+ if (typeof value === "string") return value;
387
+ try {
388
+ return JSON.stringify(value) ?? "";
389
+ } catch {
390
+ return "";
391
+ }
392
+ }
393
+ async function runServeProxy(opts) {
394
+ const {
395
+ connectorId,
396
+ command,
397
+ args,
398
+ store,
399
+ tokenizer,
400
+ modelFamilyHint,
401
+ hostPlatform,
402
+ sessionId,
403
+ projectKey,
404
+ projectDir,
405
+ measureToolDefs: shouldMeasureToolDefs,
406
+ installScope,
407
+ launchMethod
408
+ } = opts;
409
+ const measuringEnabled = process.env.AGENT_CONNECTOR_TELEMETRY !== "0";
410
+ const calibrationEnabled = isCalibrationEnabled();
411
+ const child = spawnChild(command, args, {
412
+ stdio: ["pipe", "pipe", "inherit"],
413
+ env: process.env
414
+ });
415
+ let family = inferModelFamily("", modelFamilyHint);
416
+ const pending = /* @__PURE__ */ new Map();
417
+ let seq = 0;
418
+ let toolDefsMeasured = false;
419
+ function baseRecord() {
420
+ return {
421
+ id: newRecordId(seq++),
422
+ ts: Date.now(),
423
+ connectorId,
424
+ hostPlatform,
425
+ sessionId,
426
+ projectKey,
427
+ projectDir,
428
+ ...installScope !== void 0 ? { installScope } : {},
429
+ ...launchMethod !== void 0 ? { launchMethod } : {}
430
+ };
431
+ }
432
+ function onClientMessage(msg) {
433
+ const method = msg.method;
434
+ if (method === "initialize") {
435
+ const params = isObject(msg.params) ? msg.params : void 0;
436
+ const clientInfo = params && isObject(params["clientInfo"]) ? params["clientInfo"] : void 0;
437
+ const clientName = clientInfo && typeof clientInfo["name"] === "string" ? clientInfo["name"] : "";
438
+ family = inferModelFamily(clientName, modelFamilyHint);
439
+ return;
440
+ }
441
+ if (method === "tools/call") {
442
+ const key = idKey(msg.id);
443
+ if (key === null) return;
444
+ const params = isObject(msg.params) ? msg.params : void 0;
445
+ const toolName = params && typeof params["name"] === "string" ? params["name"] : "unknown";
446
+ const callArgs = params ? params["arguments"] : void 0;
447
+ pending.set(key, { toolName, args: callArgs });
448
+ }
449
+ }
450
+ function onServerMessage(msg) {
451
+ const key = idKey(msg.id);
452
+ if (key === null) return;
453
+ const pendingCall = pending.get(key);
454
+ if (pendingCall !== void 0) {
455
+ pending.delete(key);
456
+ recordToolCall(pendingCall, msg);
457
+ return;
458
+ }
459
+ if (shouldMeasureToolDefs && !toolDefsMeasured) {
460
+ const result = isObject(msg.result) ? msg.result : void 0;
461
+ const tools = result ? result["tools"] : void 0;
462
+ if (Array.isArray(tools)) {
463
+ recordToolDefs(tools);
464
+ }
465
+ }
466
+ }
467
+ function recordToolCall(call, response) {
468
+ const hasError = response.error !== void 0;
469
+ const result = response.result;
470
+ const resultForMeasure = hasError ? {} : result;
471
+ const measurement = measureToolCall(
472
+ call.args,
473
+ resultForMeasure,
474
+ family,
475
+ tokenizer
476
+ );
477
+ let inputTokens = measurement.inputTokens;
478
+ let outputTokens = measurement.outputTokens;
479
+ let confidenceSource = measurement.source;
480
+ if (calibrationEnabled && family === "anthropic") {
481
+ try {
482
+ ({ inputTokens, outputTokens, confidenceSource } = calibrateCounts(
483
+ measurement.inputTokens,
484
+ measurement.outputTokens,
485
+ measurement.source
486
+ ));
487
+ maybeSampleCalibration(call.args, measurement.inputTokens);
488
+ } catch {
489
+ }
490
+ }
491
+ const resultIsError = isObject(result) && result["isError"] === true;
492
+ store.append({
493
+ ...baseRecord(),
494
+ toolName: call.toolName,
495
+ scope: "call",
496
+ inputTokens,
497
+ outputTokens,
498
+ confidenceSource,
499
+ isError: hasError || resultIsError
500
+ });
501
+ }
502
+ function calibrateCounts(rawIn, rawOut, rawSource) {
503
+ if (rawSource !== "tokenizer-approx") {
504
+ return { inputTokens: rawIn, outputTokens: rawOut, confidenceSource: rawSource };
505
+ }
506
+ const cin = applyCalibration(rawIn, family);
507
+ const cout = applyCalibration(rawOut, family);
508
+ const calibrated = cin.source === "tokenizer-calibrated" || cout.source === "tokenizer-calibrated";
509
+ return {
510
+ inputTokens: cin.tokens,
511
+ outputTokens: cout.tokens,
512
+ confidenceSource: calibrated ? "tokenizer-calibrated" : "tokenizer-approx"
513
+ };
514
+ }
515
+ function maybeSampleCalibration(args2, approxInputTokens) {
516
+ if (approxInputTokens <= 0) return;
517
+ if (!shouldSample()) return;
518
+ const text = canonicalArgs(args2);
519
+ if (text === "") return;
520
+ void countTokensAnthropic(text, modelForFamily(family)).then((exact) => {
521
+ if (exact !== null && exact > 0) {
522
+ recordSample(family, exact / approxInputTokens);
523
+ }
524
+ }).catch(() => {
525
+ });
526
+ }
527
+ function recordToolDefs(tools) {
528
+ toolDefsMeasured = true;
529
+ const count = measureToolDefs(tools, family, tokenizer);
530
+ store.append({
531
+ ...baseRecord(),
532
+ toolName: "*",
533
+ scope: "tool_defs",
534
+ inputTokens: count.tokens,
535
+ outputTokens: 0,
536
+ confidenceSource: count.source,
537
+ isError: false
538
+ });
539
+ }
540
+ function handleLine(line, direction) {
541
+ if (!measuringEnabled) return;
542
+ let msg;
543
+ try {
544
+ const parsed = JSON.parse(line);
545
+ if (!isObject(parsed)) return;
546
+ msg = parsed;
547
+ } catch {
548
+ return;
549
+ }
550
+ try {
551
+ if (direction === "client") onClientMessage(msg);
552
+ else onServerMessage(msg);
553
+ } catch {
554
+ }
555
+ }
556
+ const clientLines = new LineBuffer((line) => handleLine(line, "client"));
557
+ const serverLines = new LineBuffer((line) => handleLine(line, "server"));
558
+ process.stdin.on("data", (chunk) => {
559
+ if (child.stdin && child.stdin.writable) {
560
+ const ok = child.stdin.write(chunk);
561
+ if (!ok) {
562
+ process.stdin.pause();
563
+ child.stdin.once("drain", () => process.stdin.resume());
564
+ }
565
+ }
566
+ if (measuringEnabled) {
567
+ try {
568
+ clientLines.push(chunk);
569
+ } catch {
570
+ }
571
+ }
572
+ });
573
+ process.stdin.on("end", () => {
574
+ if (child.stdin && !child.stdin.destroyed) child.stdin.end();
575
+ });
576
+ if (child.stdout) {
577
+ const childStdout = child.stdout;
578
+ childStdout.on("data", (chunk) => {
579
+ const ok = process.stdout.write(chunk);
580
+ if (!ok) {
581
+ childStdout.pause();
582
+ process.stdout.once("drain", () => childStdout.resume());
583
+ }
584
+ if (measuringEnabled) {
585
+ try {
586
+ serverLines.push(chunk);
587
+ } catch {
588
+ }
589
+ }
590
+ });
591
+ }
592
+ const forwardSignal = (signal) => {
593
+ try {
594
+ if (!child.killed) child.kill(signal);
595
+ } catch {
596
+ }
597
+ };
598
+ const onSigint = () => forwardSignal("SIGINT");
599
+ const onSigterm = () => forwardSignal("SIGTERM");
600
+ process.on("SIGINT", onSigint);
601
+ process.on("SIGTERM", onSigterm);
602
+ return await new Promise((resolve) => {
603
+ const finish = (code) => {
604
+ process.removeListener("SIGINT", onSigint);
605
+ process.removeListener("SIGTERM", onSigterm);
606
+ try {
607
+ store.close();
608
+ } catch {
609
+ }
610
+ resolve(code);
611
+ };
612
+ child.on("error", () => {
613
+ finish(126);
614
+ });
615
+ child.on("close", (code, signal) => {
616
+ if (typeof code === "number") {
617
+ finish(code);
618
+ return;
619
+ }
620
+ if (signal) {
621
+ const num = signalToNumber(signal);
622
+ finish(num === void 0 ? 1 : 128 + num);
623
+ return;
624
+ }
625
+ finish(1);
626
+ });
627
+ });
628
+ }
629
+ function signalToNumber(signal) {
630
+ const table = {
631
+ SIGINT: 2,
632
+ SIGQUIT: 3,
633
+ SIGKILL: 9,
634
+ SIGTERM: 15
635
+ };
636
+ return table[signal];
637
+ }
638
+
639
+ // src/runtime/serve.ts
640
+ function resolveSessionId(env = process.env) {
641
+ return env.AGENT_CONNECTOR_SESSION || env.CLAUDE_SESSION_ID || env.CODEX_THREAD_ID || env.CURSOR_TRACE_ID || env.MCP_SESSION_ID || `proc-${randomUUID()}`;
642
+ }
643
+ async function runServe(opts) {
644
+ const { connectorId, serverCommand, serverArgs, installScope, hostPlatformOverride } = opts;
645
+ const connector = await loadRegisteredConnector(connectorId);
646
+ const id = projectIdentity(process.cwd());
647
+ const hostPlatform = hostPlatformOverride !== void 0 && REGISTERED_PLATFORM_IDS.has(hostPlatformOverride) ? hostPlatformOverride : detectRuntimeHost().platform;
648
+ const sessionId = resolveSessionId();
649
+ const launchMethod = detectLaunchMethod(serverCommand, serverArgs);
650
+ const store = openStore({});
651
+ const tok = getTokenizer();
652
+ return runServeProxy({
653
+ connectorId,
654
+ command: serverCommand,
655
+ args: serverArgs,
656
+ store,
657
+ tokenizer: tok,
658
+ modelFamilyHint: connector.telemetry.modelFamilyHint,
659
+ hostPlatform,
660
+ sessionId,
661
+ projectKey: id.key,
662
+ projectDir: id.dir,
663
+ measureToolDefs: connector.telemetry.measureToolDefs,
664
+ installScope,
665
+ launchMethod
666
+ });
667
+ }
668
+
669
+ // src/runtime/usage-event.ts
670
+ var NOOP = { exitCode: 0, recorded: false };
671
+ function isObject3(v) {
672
+ return typeof v === "object" && v !== null && !Array.isArray(v);
673
+ }
674
+ function toNonNegInt(v) {
675
+ const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
676
+ if (!Number.isFinite(n) || n < 0) return 0;
677
+ return Math.floor(n);
678
+ }
679
+ function firstStr(obj, keys) {
680
+ for (const k of keys) {
681
+ const v = obj[k];
682
+ if (typeof v === "string" && v.trim() !== "") return v;
683
+ }
684
+ return void 0;
685
+ }
686
+ function tokenField(meta, keys) {
687
+ for (const k of keys) {
688
+ if (k in meta) return toNonNegInt(meta[k]);
689
+ }
690
+ return 0;
691
+ }
692
+ function findUsageMetadata(root) {
693
+ for (const k of ["usageMetadata", "usage_metadata"]) {
694
+ if (isObject3(root[k])) return root[k];
695
+ }
696
+ for (const k of ["response", "modelResponse", "model_response"]) {
697
+ const nested = root[k];
698
+ if (isObject3(nested)) {
699
+ for (const mk of ["usageMetadata", "usage_metadata"]) {
700
+ if (isObject3(nested[mk])) return nested[mk];
701
+ }
702
+ }
703
+ }
704
+ return void 0;
705
+ }
706
+ var KNOWN_PLATFORMS = /* @__PURE__ */ new Set([
707
+ "claude-code",
708
+ "codex",
709
+ "cursor",
710
+ "vscode-copilot",
711
+ "jetbrains-copilot",
712
+ "copilot-cli",
713
+ "gemini-cli",
714
+ "opencode",
715
+ "kilo",
716
+ "kilo-cli",
717
+ "warp",
718
+ "hermes",
719
+ "openclaw",
720
+ "zed",
721
+ "antigravity",
722
+ "antigravity-cli",
723
+ "kiro",
724
+ "qwen-code",
725
+ "kimi",
726
+ "pi",
727
+ "omp",
728
+ "droid",
729
+ "roo-code",
730
+ "trae",
731
+ "amp",
732
+ "codebuff",
733
+ "mux",
734
+ "crush",
735
+ "goose",
736
+ "synthetic",
737
+ "unknown"
738
+ ]);
739
+ function asPlatformId(id) {
740
+ return KNOWN_PLATFORMS.has(id) ? id : "unknown";
741
+ }
742
+ async function runUsageEvent(opts) {
743
+ try {
744
+ const trimmed = opts.stdin.trim();
745
+ if (trimmed === "") return NOOP;
746
+ let raw;
747
+ try {
748
+ raw = JSON.parse(trimmed);
749
+ } catch {
750
+ return NOOP;
751
+ }
752
+ if (!isObject3(raw)) return NOOP;
753
+ const meta = findUsageMetadata(raw);
754
+ if (meta === void 0) return NOOP;
755
+ const promptTokens = tokenField(meta, ["promptTokenCount", "prompt_token_count"]);
756
+ const candidates = tokenField(meta, ["candidatesTokenCount", "candidates_token_count"]);
757
+ const cached = tokenField(meta, ["cachedContentTokenCount", "cached_content_token_count"]);
758
+ const thoughts = tokenField(meta, ["thoughtsTokenCount", "thoughts_token_count"]);
759
+ const inputTokens = Math.max(0, promptTokens - Math.min(cached, promptTokens));
760
+ const outputTokens = candidates + thoughts;
761
+ if (inputTokens === 0 && outputTokens === 0) return NOOP;
762
+ const sessionId = firstStr(raw, ["session_id", "sessionId", "conversationId", "conversation_id"]) ?? "";
763
+ const cwd = firstStr(raw, ["cwd", "workspace", "projectDir", "project_dir"]) ?? process.cwd();
764
+ const id = projectIdentity(cwd);
765
+ const record = {
766
+ id: newRecordId(0),
767
+ ts: Date.now(),
768
+ connectorId: opts.connectorId,
769
+ toolName: "*",
770
+ scope: "model_turn",
771
+ hostPlatform: asPlatformId(opts.platformId),
772
+ sessionId,
773
+ projectKey: id.key,
774
+ projectDir: id.dir,
775
+ inputTokens,
776
+ outputTokens,
777
+ confidenceSource: "host-native",
778
+ isError: false
779
+ };
780
+ const store = openStore({});
781
+ try {
782
+ store.append(record);
783
+ } finally {
784
+ try {
785
+ store.close();
786
+ } catch {
787
+ }
788
+ }
789
+ return { exitCode: 0, recorded: true };
790
+ } catch {
791
+ return NOOP;
792
+ }
793
+ }
794
+
795
+ export {
796
+ runHook,
797
+ runServe,
798
+ runUsageEvent
799
+ };
800
+ //# sourceMappingURL=chunk-YNZU6PAV.js.map