@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,171 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ nonEmptyStr,
4
+ resolveAlias,
5
+ toSafeInt
6
+ } from "./chunk-MQPNU2CY.js";
7
+ import {
8
+ readJsonFile,
9
+ readJsonlLines
10
+ } from "./chunk-RK6VBLXP.js";
11
+ import {
12
+ firstExistingRoot,
13
+ isDir,
14
+ listSubdirs,
15
+ walkFiles
16
+ } from "./chunk-JWNT5KW7.js";
17
+ import {
18
+ emptyTokens,
19
+ inferProvider
20
+ } from "./chunk-XD7MY6HB.js";
21
+
22
+ // src/usage/readers/antigravity.ts
23
+ import { existsSync } from "fs";
24
+ import { homedir } from "os";
25
+ import { basename, isAbsolute, join, resolve, sep } from "path";
26
+ var PLATFORM_ID = "antigravity";
27
+ var DEFAULT_MODEL = "unknown";
28
+ var DEFAULT_PROVIDER = "antigravity";
29
+ function parseCacheFile(path) {
30
+ const lines = readJsonlLines(path);
31
+ if (lines.length === 0) return [];
32
+ const out = [];
33
+ let sessionModel;
34
+ for (const raw of lines) {
35
+ if (typeof raw !== "object" || raw === null) continue;
36
+ const line = raw;
37
+ const rowType = typeof line.type === "string" ? line.type : "";
38
+ if (rowType === "session_meta") {
39
+ const meta = nonEmptyStr(line.modelId);
40
+ if (meta !== void 0) sessionModel = meta;
41
+ continue;
42
+ }
43
+ if (rowType !== "usage") continue;
44
+ const record = parseCacheUsageRow(line, sessionModel);
45
+ if (record !== void 0) out.push(record);
46
+ }
47
+ return out;
48
+ }
49
+ function parseCacheUsageRow(line, fallbackModel) {
50
+ const sessionId = nonEmptyStr(line.sessionId);
51
+ if (sessionId === void 0) return void 0;
52
+ const timestamp = toSafeInt(line.timestamp);
53
+ if (timestamp <= 0) return void 0;
54
+ const rawModel = nonEmptyStr(line.modelId) ?? fallbackModel ?? DEFAULT_MODEL;
55
+ const modelId = resolveAlias(rawModel) ?? rawModel;
56
+ const providerId = nonEmptyStr(line.providerId) ?? inferProvider(modelId) ?? DEFAULT_PROVIDER;
57
+ const input = toSafeInt(line.input);
58
+ const output = toSafeInt(line.output);
59
+ const cacheRead = toSafeInt(line.cacheRead);
60
+ const cacheWrite = toSafeInt(line.cacheWrite);
61
+ const reasoning = toSafeInt(line.reasoning);
62
+ if (input === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0 && reasoning === 0) {
63
+ return void 0;
64
+ }
65
+ const tokens = emptyTokens();
66
+ tokens.input = input;
67
+ tokens.output = output;
68
+ tokens.cacheRead = cacheRead;
69
+ tokens.cacheWrite = cacheWrite;
70
+ tokens.reasoning = reasoning;
71
+ const record = {
72
+ platformId: PLATFORM_ID,
73
+ modelId,
74
+ providerId,
75
+ sessionId,
76
+ tokens,
77
+ ts: timestamp,
78
+ messageCount: 1,
79
+ confidence: "host-reported"
80
+ };
81
+ const dedupKey = nonEmptyStr(line.responseId);
82
+ if (dedupKey !== void 0) record.dedupKey = dedupKey;
83
+ return record;
84
+ }
85
+ function manifestArtifacts(cacheDir) {
86
+ const manifestPath = join(cacheDir, "manifest.json");
87
+ if (!existsSync(manifestPath)) return [];
88
+ const data = readJsonFile(manifestPath);
89
+ if (data === void 0 || data === null) return [];
90
+ let entries;
91
+ if (Array.isArray(data)) {
92
+ entries = data;
93
+ } else if (typeof data === "object") {
94
+ const obj = data;
95
+ entries = Array.isArray(obj.sessions) ? obj.sessions : Array.isArray(obj.entries) ? obj.entries : [];
96
+ } else {
97
+ return [];
98
+ }
99
+ const cacheRootResolved = resolve(cacheDir);
100
+ const out = [];
101
+ for (const entry of entries) {
102
+ if (typeof entry !== "object" || entry === null) continue;
103
+ const e = entry;
104
+ const rel = nonEmptyStr(e.artifact_path) ?? nonEmptyStr(e.artifactPath);
105
+ if (rel === void 0) continue;
106
+ if (isAbsolute(rel)) continue;
107
+ const abs = resolve(cacheDir, rel);
108
+ if (abs !== cacheRootResolved && !abs.startsWith(cacheRootResolved + sep)) continue;
109
+ out.push(abs);
110
+ }
111
+ return out;
112
+ }
113
+ function filesystemArtifacts() {
114
+ const home = homedir();
115
+ if (!isDir(home)) return [];
116
+ const out = [];
117
+ for (const child of listSubdirs(home)) {
118
+ const name = basename(child);
119
+ if (!name.startsWith("antigravity")) continue;
120
+ for (const sub of ["brain", "conversations"]) {
121
+ const dir = join(child, sub);
122
+ if (!isDir(dir)) continue;
123
+ for (const f of walkFiles(dir, (fname) => fname.endsWith(".jsonl"))) {
124
+ out.push(f);
125
+ }
126
+ }
127
+ }
128
+ return out;
129
+ }
130
+ function readTokscaleCache() {
131
+ const cacheRoot = firstExistingRoot(PLATFORM_ID);
132
+ const files = /* @__PURE__ */ new Set();
133
+ if (cacheRoot !== void 0) {
134
+ for (const f of manifestArtifacts(cacheRoot)) files.add(f);
135
+ const sessionsDir = join(cacheRoot, "sessions");
136
+ if (isDir(sessionsDir)) {
137
+ for (const f of walkFiles(sessionsDir, (name) => name.endsWith(".jsonl"))) files.add(f);
138
+ }
139
+ }
140
+ for (const f of filesystemArtifacts()) files.add(f);
141
+ if (files.size === 0) return [];
142
+ const out = [];
143
+ for (const file of files) {
144
+ if (!existsSync(file)) continue;
145
+ for (const row of parseCacheFile(file)) out.push(row);
146
+ }
147
+ return out;
148
+ }
149
+ var antigravityReader = {
150
+ platformId: PLATFORM_ID,
151
+ kind: "synced",
152
+ async read({ sinceMs }) {
153
+ let cacheRows;
154
+ try {
155
+ cacheRows = readTokscaleCache();
156
+ } catch {
157
+ cacheRows = [];
158
+ }
159
+ const records = [];
160
+ for (const row of cacheRows) {
161
+ if (sinceMs !== void 0 && row.ts < sinceMs) continue;
162
+ records.push(row);
163
+ }
164
+ return records;
165
+ }
166
+ };
167
+ var antigravity_default = antigravityReader;
168
+ export {
169
+ antigravity_default as default
170
+ };
171
+ //# sourceMappingURL=antigravity-STHZWMP3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/readers/antigravity.ts"],"sourcesContent":["/**\n * usage/readers/antigravity — Antigravity IDE usage reader (SYNCED platform).\n *\n * CONFIRMED-BY-INSTALL (2026-06-03, docs/research/antigravity-paths-confirmed.md):\n * the native Antigravity store is `~/.gemini/antigravity/conversations/<uuid>.pb`\n * — PROTOBUF with NO public schema — and `brain/<uuid>/` holds only media +\n * `*.metadata.json`. There are NO `transcript*.jsonl` files. The earlier\n * \"read native brain transcript*.jsonl with usage_metadata\" approach was based on\n * a shape that does not exist on disk.\n *\n * So this reader does NOT attempt to parse `.pb` (no schema). Like the other\n * SYNCED platforms (cursor/trae/warp), it reads only the tokscale synced-cache\n * if a separate tokscale run already produced one; otherwise it returns [] and\n * the scan layer reports \"requires sync (no local cache found)\" — i.e. the native\n * store is protobuf (.pb), not readable.\n *\n * - cache present → parse the tokscale cache (manifest.json + sessions/*.jsonl,\n * plus any loose ~/antigravity* brain/conversations *.jsonl dumps) using the\n * tokscale Rust line schema (`session_meta` / `usage` rows);\n * - cache absent → [] (kind:\"synced\" → scan notes \"requires sync\").\n *\n * The native `~/.gemini/antigravity/` dir is used ONLY for platform detection (in\n * the adapter), NOT for usage parsing here. The cached rows carry real host token\n * counts → \"host-reported\".\n *\n * Fail-open: no cache → []; unreadable/malformed file or line → skipped; we NEVER\n * touch `.pb` protobuf.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, isAbsolute, join, resolve, sep } from \"node:path\";\n\nimport type { UsageReader, UsageRecord } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { readJsonFile, readJsonlLines } from \"../jsonl.js\";\nimport { inferProvider } from \"../normalize.js\";\nimport { firstExistingRoot, isDir, listSubdirs, walkFiles } from \"../paths.js\";\nimport { nonEmptyStr, resolveAlias, toSafeInt } from \"./antigravity-shared.js\";\n\nconst PLATFORM_ID = \"antigravity\" as const;\nconst DEFAULT_MODEL = \"unknown\";\nconst DEFAULT_PROVIDER = \"antigravity\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// TOKSCALE CACHE — port of tokscale parse_antigravity_file\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Fields we read off a tokscale-cache Antigravity JSONL line (all optional). */\ninterface AntigravityLine {\n type?: unknown;\n modelId?: unknown;\n providerId?: unknown;\n sessionId?: unknown;\n timestamp?: unknown;\n input?: unknown;\n output?: unknown;\n cacheRead?: unknown;\n cacheWrite?: unknown;\n reasoning?: unknown;\n responseId?: unknown;\n}\n\n/**\n * Parse one tokscale-cache Antigravity JSONL file into usage records (port of\n * parse_antigravity_file + parse_usage_row). A `session_meta` line updates the\n * running fallback model; a `usage` line emits a record when valid.\n */\nfunction parseCacheFile(path: string): UsageRecord[] {\n const lines = readJsonlLines(path);\n if (lines.length === 0) return [];\n\n const out: UsageRecord[] = [];\n let sessionModel: string | undefined;\n\n for (const raw of lines) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const line = raw as AntigravityLine;\n\n const rowType = typeof line.type === \"string\" ? line.type : \"\";\n if (rowType === \"session_meta\") {\n const meta = nonEmptyStr(line.modelId);\n if (meta !== undefined) sessionModel = meta;\n continue;\n }\n if (rowType !== \"usage\") continue;\n\n const record = parseCacheUsageRow(line, sessionModel);\n if (record !== undefined) out.push(record);\n }\n\n return out;\n}\n\n/** Port of parse_usage_row: build a UsageRecord from a \"usage\" line, or undefined. */\nfunction parseCacheUsageRow(line: AntigravityLine, fallbackModel: string | undefined): UsageRecord | undefined {\n const sessionId = nonEmptyStr(line.sessionId);\n if (sessionId === undefined) return undefined;\n\n const timestamp = toSafeInt(line.timestamp);\n if (timestamp <= 0) return undefined;\n\n const rawModel = nonEmptyStr(line.modelId) ?? fallbackModel ?? DEFAULT_MODEL;\n const modelId = resolveAlias(rawModel) ?? rawModel;\n const providerId = nonEmptyStr(line.providerId) ?? inferProvider(modelId) ?? DEFAULT_PROVIDER;\n\n const input = toSafeInt(line.input);\n const output = toSafeInt(line.output);\n const cacheRead = toSafeInt(line.cacheRead);\n const cacheWrite = toSafeInt(line.cacheWrite);\n const reasoning = toSafeInt(line.reasoning);\n if (input === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0 && reasoning === 0) {\n return undefined;\n }\n\n const tokens = emptyTokens();\n tokens.input = input;\n tokens.output = output;\n tokens.cacheRead = cacheRead;\n tokens.cacheWrite = cacheWrite;\n tokens.reasoning = reasoning;\n\n const record: UsageRecord = {\n platformId: PLATFORM_ID,\n modelId,\n providerId,\n sessionId,\n tokens,\n ts: timestamp,\n messageCount: 1,\n confidence: \"host-reported\",\n };\n const dedupKey = nonEmptyStr(line.responseId);\n if (dedupKey !== undefined) record.dedupKey = dedupKey;\n return record;\n}\n\n/** A manifest entry's relative artifact path, tolerant of the field spelling. */\ninterface ManifestEntry {\n artifact_path?: unknown;\n artifactPath?: unknown;\n}\n\n/**\n * Read manifest.json (if present) and return the cache-relative artifact paths it\n * lists, resolved to absolute paths that stay INSIDE the cache dir (a traversal\n * or absolute path in the manifest is rejected, fail-open).\n */\nfunction manifestArtifacts(cacheDir: string): string[] {\n const manifestPath = join(cacheDir, \"manifest.json\");\n if (!existsSync(manifestPath)) return [];\n const data = readJsonFile(manifestPath);\n if (data === undefined || data === null) return [];\n\n let entries: unknown[];\n if (Array.isArray(data)) {\n entries = data;\n } else if (typeof data === \"object\") {\n const obj = data as { sessions?: unknown; entries?: unknown };\n entries = Array.isArray(obj.sessions) ? obj.sessions : Array.isArray(obj.entries) ? obj.entries : [];\n } else {\n return [];\n }\n\n const cacheRootResolved = resolve(cacheDir);\n const out: string[] = [];\n for (const entry of entries) {\n if (typeof entry !== \"object\" || entry === null) continue;\n const e = entry as ManifestEntry;\n const rel = nonEmptyStr(e.artifact_path) ?? nonEmptyStr(e.artifactPath);\n if (rel === undefined) continue;\n if (isAbsolute(rel)) continue;\n const abs = resolve(cacheDir, rel);\n if (abs !== cacheRootResolved && !abs.startsWith(cacheRootResolved + sep)) continue;\n out.push(abs);\n }\n return out;\n}\n\n/**\n * Loose local-filesystem trajectory dumps: ~/antigravity-prefixed dirs, each with\n * a brain/ and/or conversations/ subdir (the local half of tokscale's merge).\n * Returns every *.jsonl under those dirs (`.pb` is naturally excluded — these are\n * tokscale-produced JSONL mirrors, NOT the native protobuf store).\n */\nfunction filesystemArtifacts(): string[] {\n const home = homedir();\n if (!isDir(home)) return [];\n\n const out: string[] = [];\n for (const child of listSubdirs(home)) {\n const name = basename(child);\n if (!name.startsWith(\"antigravity\")) continue;\n for (const sub of [\"brain\", \"conversations\"]) {\n const dir = join(child, sub);\n if (!isDir(dir)) continue;\n for (const f of walkFiles(dir, (fname) => fname.endsWith(\".jsonl\"))) {\n out.push(f);\n }\n }\n }\n return out;\n}\n\n/** Collect tokscale-cache records (manifest ∪ sessions/*.jsonl ∪ loose ~/antigravity*). */\nfunction readTokscaleCache(): UsageRecord[] {\n const cacheRoot = firstExistingRoot(PLATFORM_ID);\n\n const files = new Set<string>();\n if (cacheRoot !== undefined) {\n for (const f of manifestArtifacts(cacheRoot)) files.add(f);\n const sessionsDir = join(cacheRoot, \"sessions\");\n if (isDir(sessionsDir)) {\n for (const f of walkFiles(sessionsDir, (name) => name.endsWith(\".jsonl\"))) files.add(f);\n }\n }\n for (const f of filesystemArtifacts()) files.add(f);\n\n if (files.size === 0) return [];\n\n const out: UsageRecord[] = [];\n for (const file of files) {\n if (!existsSync(file)) continue; // stale manifest reference → skip\n for (const row of parseCacheFile(file)) out.push(row);\n }\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Reader\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * The Antigravity IDE usage reader singleton (SYNCED). The native store is\n * protobuf (.pb) with no public schema → not parseable; we read only the tokscale\n * synced-cache if present, else [] (scan reports \"requires sync\").\n */\nconst antigravityReader: UsageReader = {\n platformId: PLATFORM_ID,\n kind: \"synced\",\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\n let cacheRows: UsageRecord[];\n try {\n cacheRows = readTokscaleCache();\n } catch {\n cacheRows = []; // fail-open\n }\n\n const records: UsageRecord[] = [];\n for (const row of cacheRows) {\n if (sinceMs !== undefined && row.ts < sinceMs) continue;\n records.push(row);\n }\n return records;\n },\n};\n\nexport default antigravityReader;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ nonEmptyStr,
4
+ resolveAlias,
5
+ toSafeInt
6
+ } from "./chunk-MQPNU2CY.js";
7
+ import {
8
+ readJsonlLines
9
+ } from "./chunk-RK6VBLXP.js";
10
+ import {
11
+ firstExistingRoot,
12
+ isDir,
13
+ walkFiles
14
+ } from "./chunk-JWNT5KW7.js";
15
+ import {
16
+ emptyTokens,
17
+ inferProvider
18
+ } from "./chunk-XD7MY6HB.js";
19
+
20
+ // src/usage/readers/antigravity-cli.ts
21
+ import { existsSync } from "fs";
22
+ import { join } from "path";
23
+ var PLATFORM_ID = "antigravity-cli";
24
+ var DEFAULT_MODEL = "unknown";
25
+ var DEFAULT_PROVIDER = "antigravity";
26
+ function parseCacheFile(path) {
27
+ const lines = readJsonlLines(path);
28
+ if (lines.length === 0) return [];
29
+ const out = [];
30
+ let sessionModel;
31
+ for (const raw of lines) {
32
+ if (typeof raw !== "object" || raw === null) continue;
33
+ const line = raw;
34
+ const rowType = typeof line.type === "string" ? line.type : "";
35
+ if (rowType === "session_meta") {
36
+ const meta = nonEmptyStr(line.modelId);
37
+ if (meta !== void 0) sessionModel = meta;
38
+ continue;
39
+ }
40
+ if (rowType !== "usage") continue;
41
+ const record = parseCacheUsageRow(line, sessionModel);
42
+ if (record !== void 0) out.push(record);
43
+ }
44
+ return out;
45
+ }
46
+ function parseCacheUsageRow(line, fallbackModel) {
47
+ const sessionId = nonEmptyStr(line.sessionId);
48
+ if (sessionId === void 0) return void 0;
49
+ const timestamp = toSafeInt(line.timestamp);
50
+ if (timestamp <= 0) return void 0;
51
+ const rawModel = nonEmptyStr(line.modelId) ?? fallbackModel ?? DEFAULT_MODEL;
52
+ const modelId = resolveAlias(rawModel) ?? rawModel;
53
+ const providerId = nonEmptyStr(line.providerId) ?? inferProvider(modelId) ?? DEFAULT_PROVIDER;
54
+ const input = toSafeInt(line.input);
55
+ const output = toSafeInt(line.output);
56
+ const cacheRead = toSafeInt(line.cacheRead);
57
+ const cacheWrite = toSafeInt(line.cacheWrite);
58
+ const reasoning = toSafeInt(line.reasoning);
59
+ if (input === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0 && reasoning === 0) {
60
+ return void 0;
61
+ }
62
+ const tokens = emptyTokens();
63
+ tokens.input = input;
64
+ tokens.output = output;
65
+ tokens.cacheRead = cacheRead;
66
+ tokens.cacheWrite = cacheWrite;
67
+ tokens.reasoning = reasoning;
68
+ const record = {
69
+ platformId: PLATFORM_ID,
70
+ modelId,
71
+ providerId,
72
+ sessionId,
73
+ tokens,
74
+ ts: timestamp,
75
+ messageCount: 1,
76
+ confidence: "host-reported"
77
+ };
78
+ const dedupKey = nonEmptyStr(line.responseId);
79
+ if (dedupKey !== void 0) record.dedupKey = dedupKey;
80
+ return record;
81
+ }
82
+ function readTokscaleCache() {
83
+ const cacheRoot = firstExistingRoot(PLATFORM_ID);
84
+ if (cacheRoot === void 0) return [];
85
+ const files = /* @__PURE__ */ new Set();
86
+ const sessionsDir = join(cacheRoot, "sessions");
87
+ if (isDir(sessionsDir)) {
88
+ for (const f of walkFiles(sessionsDir, (name) => name.endsWith(".jsonl"))) files.add(f);
89
+ }
90
+ for (const f of walkFiles(cacheRoot, (name) => name.endsWith(".jsonl"))) files.add(f);
91
+ if (files.size === 0) return [];
92
+ const out = [];
93
+ for (const file of files) {
94
+ if (!existsSync(file)) continue;
95
+ for (const row of parseCacheFile(file)) out.push(row);
96
+ }
97
+ return out;
98
+ }
99
+ var antigravityCliReader = {
100
+ platformId: PLATFORM_ID,
101
+ kind: "synced",
102
+ async read({ sinceMs }) {
103
+ let cacheRows;
104
+ try {
105
+ cacheRows = readTokscaleCache();
106
+ } catch {
107
+ cacheRows = [];
108
+ }
109
+ const records = [];
110
+ for (const row of cacheRows) {
111
+ if (sinceMs !== void 0 && row.ts < sinceMs) continue;
112
+ records.push(row);
113
+ }
114
+ return records;
115
+ }
116
+ };
117
+ var antigravity_cli_default = antigravityCliReader;
118
+ export {
119
+ antigravity_cli_default as default
120
+ };
121
+ //# sourceMappingURL=antigravity-cli-P6HADOAO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/readers/antigravity-cli.ts"],"sourcesContent":["/**\n * usage/readers/antigravity-cli — Antigravity CLI (`agy`) usage reader (SYNCED).\n *\n * CONFIRMED-BY-INSTALL (2026-06-03, docs/research/antigravity-paths-confirmed.md):\n * the `agy` CLI v1.0.0 has NO separate config/storage dir — it SHARES the IDE's\n * `~/.gemini/antigravity/` tree, whose native conversation store is\n * `conversations/<uuid>.pb` (PROTOBUF, no public schema) with `brain/<uuid>/`\n * holding only media + `*.metadata.json`. There are NO `transcript*.jsonl` files\n * and NO separate `~/.gemini/antigravity-cli/` dir. The earlier \"read native\n * brain transcript*.jsonl with usage_metadata\" approach targeted a non-existent\n * shape.\n *\n * So this reader does NOT attempt to parse `.pb` (no schema). Like the IDE reader\n * (and the other SYNCED platforms cursor/trae/warp), it reads only the tokscale\n * synced-cache if a separate tokscale run already produced one; otherwise it\n * returns [] and the scan layer reports \"requires sync (no local cache found)\"\n * — i.e. the native store is protobuf (.pb), not readable.\n *\n * The native `~/.gemini/antigravity/` dir (shared with the IDE) is used ONLY for\n * platform detection (in the adapter), NOT for usage parsing here. Cached rows\n * carry real host token counts → \"host-reported\".\n *\n * Fail-open: no cache → []; unreadable/malformed file or line → skipped; we NEVER\n * touch `.pb` protobuf.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nimport type { UsageReader, UsageRecord } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { readJsonlLines } from \"../jsonl.js\";\nimport { inferProvider } from \"../normalize.js\";\nimport { firstExistingRoot, isDir, walkFiles } from \"../paths.js\";\nimport { nonEmptyStr, resolveAlias, toSafeInt } from \"./antigravity-shared.js\";\n\nconst PLATFORM_ID = \"antigravity-cli\" as const;\nconst DEFAULT_MODEL = \"unknown\";\nconst DEFAULT_PROVIDER = \"antigravity\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// TOKSCALE CACHE — same line schema as the IDE reader\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Fields we read off a tokscale-cache Antigravity JSONL line (all optional). */\ninterface AntigravityLine {\n type?: unknown;\n modelId?: unknown;\n providerId?: unknown;\n sessionId?: unknown;\n timestamp?: unknown;\n input?: unknown;\n output?: unknown;\n cacheRead?: unknown;\n cacheWrite?: unknown;\n reasoning?: unknown;\n responseId?: unknown;\n}\n\n/** Parse one tokscale-cache JSONL file into usage records (session_meta + usage rows). */\nfunction parseCacheFile(path: string): UsageRecord[] {\n const lines = readJsonlLines(path);\n if (lines.length === 0) return [];\n\n const out: UsageRecord[] = [];\n let sessionModel: string | undefined;\n\n for (const raw of lines) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const line = raw as AntigravityLine;\n\n const rowType = typeof line.type === \"string\" ? line.type : \"\";\n if (rowType === \"session_meta\") {\n const meta = nonEmptyStr(line.modelId);\n if (meta !== undefined) sessionModel = meta;\n continue;\n }\n if (rowType !== \"usage\") continue;\n\n const record = parseCacheUsageRow(line, sessionModel);\n if (record !== undefined) out.push(record);\n }\n\n return out;\n}\n\n/** Build a UsageRecord from a \"usage\" line, or undefined when invalid/empty. */\nfunction parseCacheUsageRow(line: AntigravityLine, fallbackModel: string | undefined): UsageRecord | undefined {\n const sessionId = nonEmptyStr(line.sessionId);\n if (sessionId === undefined) return undefined;\n\n const timestamp = toSafeInt(line.timestamp);\n if (timestamp <= 0) return undefined;\n\n const rawModel = nonEmptyStr(line.modelId) ?? fallbackModel ?? DEFAULT_MODEL;\n const modelId = resolveAlias(rawModel) ?? rawModel;\n const providerId = nonEmptyStr(line.providerId) ?? inferProvider(modelId) ?? DEFAULT_PROVIDER;\n\n const input = toSafeInt(line.input);\n const output = toSafeInt(line.output);\n const cacheRead = toSafeInt(line.cacheRead);\n const cacheWrite = toSafeInt(line.cacheWrite);\n const reasoning = toSafeInt(line.reasoning);\n if (input === 0 && output === 0 && cacheRead === 0 && cacheWrite === 0 && reasoning === 0) {\n return undefined;\n }\n\n const tokens = emptyTokens();\n tokens.input = input;\n tokens.output = output;\n tokens.cacheRead = cacheRead;\n tokens.cacheWrite = cacheWrite;\n tokens.reasoning = reasoning;\n\n const record: UsageRecord = {\n platformId: PLATFORM_ID,\n modelId,\n providerId,\n sessionId,\n tokens,\n ts: timestamp,\n messageCount: 1,\n confidence: \"host-reported\",\n };\n const dedupKey = nonEmptyStr(line.responseId);\n if (dedupKey !== undefined) record.dedupKey = dedupKey;\n return record;\n}\n\n/** Collect tokscale-cache records (sessions/*.jsonl under the cache root). */\nfunction readTokscaleCache(): UsageRecord[] {\n const cacheRoot = firstExistingRoot(PLATFORM_ID);\n if (cacheRoot === undefined) return [];\n\n const files = new Set<string>();\n const sessionsDir = join(cacheRoot, \"sessions\");\n if (isDir(sessionsDir)) {\n for (const f of walkFiles(sessionsDir, (name) => name.endsWith(\".jsonl\"))) files.add(f);\n }\n // Also tolerate loose *.jsonl directly under the cache root.\n for (const f of walkFiles(cacheRoot, (name) => name.endsWith(\".jsonl\"))) files.add(f);\n\n if (files.size === 0) return [];\n\n const out: UsageRecord[] = [];\n for (const file of files) {\n if (!existsSync(file)) continue;\n for (const row of parseCacheFile(file)) out.push(row);\n }\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Reader\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * The Antigravity CLI usage reader singleton (SYNCED). `agy` shares the IDE's\n * protobuf (.pb) native store with no public schema → not parseable; we read only\n * the tokscale synced-cache if present, else [] (scan reports \"requires sync\").\n */\nconst antigravityCliReader: UsageReader = {\n platformId: PLATFORM_ID,\n kind: \"synced\",\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\n let cacheRows: UsageRecord[];\n try {\n cacheRows = readTokscaleCache();\n } catch {\n cacheRows = []; // fail-open\n }\n\n const records: UsageRecord[] = [];\n for (const row of cacheRows) {\n if (sinceMs !== undefined && row.ts < sinceMs) continue;\n records.push(row);\n }\n return records;\n },\n};\n\nexport default antigravityCliReader;\n"],"mappings":"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","names":[]}
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ AntigravityAdapter
4
+ } from "./chunk-TRKWUNO4.js";
5
+ import "./chunk-DBQMX75U.js";
6
+ import "./chunk-TIIP3RG2.js";
7
+ import "./chunk-7L6ITC4T.js";
8
+ import "./chunk-MEH7GC7R.js";
9
+ import "./chunk-TRQKHP7D.js";
10
+
11
+ // src/adapters/antigravity-cli/index.ts
12
+ import { existsSync } from "fs";
13
+ import { homedir } from "os";
14
+ import { join } from "path";
15
+ var HOST = "antigravity-cli";
16
+ var AntigravityCliAdapter = class _AntigravityCliAdapter extends AntigravityAdapter {
17
+ id = HOST;
18
+ name = "Antigravity CLI";
19
+ // ── Detection ────────────────────────────────────────────────────────────
20
+ /**
21
+ * Probe the CLI's runtime markers, DISTINCT from the IDE app even though the
22
+ * two share `~/.gemini/antigravity/`: the `agy` binary at ~/.local/bin/agy
23
+ * (the definitive CLI marker, CONFIRMED present) and the shared
24
+ * ~/.gemini/antigravity/ tree (or a user-scope mcp_config candidate / the
25
+ * project config). Reported before the IDE adapter in the registry so the
26
+ * more-specific CLI marker (the `agy` binary) wins host detection. Note: a
27
+ * machine with ONLY the IDE (no `agy` binary) will not match here, while one
28
+ * with the CLI matches on the binary regardless of the shared config dir.
29
+ */
30
+ detectInstalled(projectDir) {
31
+ const home = homedir();
32
+ const userConfig = this.resolveUserConfigPath();
33
+ const agyBin = join(home, ".local", "bin", "agy");
34
+ const sharedDir = join(home, ".gemini", "antigravity");
35
+ const projectConfig = join(projectDir, ".agents", "mcp_config.json");
36
+ const cliMarker = existsSync(agyBin);
37
+ const userInstalled = cliMarker || existsSync(sharedDir) || this.userConfigCandidates().some((parts) => existsSync(join(home, ...parts)));
38
+ const projInstalled = existsSync(projectConfig);
39
+ const installed = userInstalled || projInstalled;
40
+ const scope = projInstalled && !userInstalled ? "project" : "user";
41
+ const configPath = scope === "project" ? projectConfig : userConfig;
42
+ return {
43
+ id: this.id,
44
+ name: this.name,
45
+ installed,
46
+ paradigm: this.paradigm,
47
+ capabilities: this.capabilities,
48
+ configPath,
49
+ scope,
50
+ reason: installed ? scope === "project" ? `found project Antigravity CLI config at ${projectConfig}` : `found Antigravity CLI (agy) at ${agyBin} / shared ${sharedDir}` : `no Antigravity CLI install at ${agyBin}, ${sharedDir}, or ${projectConfig}`,
51
+ // The `agy` binary is a high-confidence CLI marker; matching only the shared
52
+ // config dir is weaker (it could be a pure-IDE install).
53
+ confidence: cliMarker ? "high" : installed ? "medium" : "low"
54
+ };
55
+ }
56
+ /**
57
+ * MCP user-config path — LIVE-PROVEN for `agy` v1.0.5 (2026-06-04). The
58
+ * standalone CLI reads user MCP servers from `~/.gemini/config/mcp_config.json`
59
+ * (root key `mcpServers`), NOT the IDE's `~/.gemini/antigravity/mcp_config.json`:
60
+ * a real `agy -p` session spawned an MCP server ONLY when it was placed in
61
+ * `config/` (negative control: a server in `antigravity/` was ignored), and the
62
+ * binary carries the error string "failed to read mcp_config.json" + a literal
63
+ * "/.gemini/config" path. `agy mcp` is TUI-only (no headless add) and there is
64
+ * no `--mcp-config` flag. So the CLI must PREFER `config/` over the inherited
65
+ * `antigravity/` default; the IDE path stays as a prefer-existing fallback.
66
+ * (Skills/workflows/hooks dirs remain inherited; project scope
67
+ * `<proj>/.agents/mcp_config.json` is already correct and live-proven.)
68
+ */
69
+ static CLI_USER_CONFIG_CANDIDATES = [
70
+ [".gemini", "config", "mcp_config.json"],
71
+ // CONFIRMED canonical for agy v1.0.5
72
+ [".gemini", "antigravity", "mcp_config.json"]
73
+ // legacy IDE layout (prefer-existing)
74
+ ];
75
+ userConfigCandidates() {
76
+ return _AntigravityCliAdapter.CLI_USER_CONFIG_CANDIDATES;
77
+ }
78
+ };
79
+ var adapter = new AntigravityCliAdapter();
80
+ var antigravity_cli_default = adapter;
81
+ export {
82
+ AntigravityCliAdapter,
83
+ adapter,
84
+ antigravity_cli_default as default
85
+ };
86
+ //# sourceMappingURL=antigravity-cli-YQDFVV4U.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/antigravity-cli/index.ts"],"sourcesContent":["/**\n * adapters/antigravity-cli — Google Antigravity CLI (`agy`) platform adapter.\n *\n * Antigravity ships in two distinct runtimes that share the Gemini-family\n * `~/.gemini` tree and ALL of the same native formats (the JSON `mcp_config.json`\n * shape, the `hooks.json` lifecycle-hook shape, markdown Workflows, and Agent\n * Skills `SKILL.md`): the IDE/desktop app (the parent `AntigravityAdapter`,\n * id \"antigravity\") and this standalone CLI binary `agy` (id \"antigravity-cli\").\n *\n * This adapter is a thin fork of the IDE adapter. It REUSES every render / hook /\n * parse / surface path from {@link AntigravityAdapter} unchanged — the only\n * differences are identity and detection:\n *\n * - id = \"antigravity-cli\", name = \"Antigravity CLI\". Identity flows into the\n * universal hook command (`<homeBin> hook antigravity-cli <event> …`) and the\n * `hostPlatform` stamp, so a CLI-installed hook dispatches back to THIS\n * adapter at runtime — the reason the parent's install/parse logic was made\n * to read `this.id` rather than a fixed host constant.\n * - Detection probes the `agy` binary at ~/.local/bin/agy and/or the SHARED\n * ~/.gemini/antigravity/ presence (distinct runtime markers from the IDE).\n *\n * CONFIRMED-BY-INSTALL (2026-06-03, docs/research/antigravity-paths-confirmed.md):\n * the `agy` CLI v1.0.0 has NO separate config dir — `~/.gemini/antigravity-cli/`,\n * `~/.config/antigravity*`, and `~/.agy` are ALL ABSENT. `agy` SHARES the IDE's\n * `~/.gemini/antigravity/` tree (mcp_config.json, hooks.json, workflows, skills).\n * So the user-scope config resolution here is IDENTICAL to the IDE adapter (the\n * inherited USER_CONFIG_CANDIDATES) — installing both the IDE and CLI connectors\n * therefore writes the SAME files and is idempotent (observed as skip), which is\n * expected and correct. `agy`'s own extension surface is the `agy plugin` system\n * (install/uninstall/list/enable/disable) — future work would deploy as an agy\n * plugin; for now the MCP/workflows/skills surfaces ride the shared IDE files.\n *\n * LIVE-TEST RESOLUTION (2026-06-04, real `agy` v1.0.5 login + spawn): the prior\n * \"shares the IDE's ~/.gemini/antigravity/ file\" claim was WRONG for the CLI. The\n * standalone `agy` reads user MCP from **~/.gemini/config/mcp_config.json**\n * (root key `mcpServers`; project scope <proj>/.agents/mcp_config.json) — PROVEN:\n * a live `agy -p` session spawned an MCP server placed in `config/` and completed\n * a real initialize+tools/list+tools/call handshake; a negative control in\n * `antigravity/` was ignored. The binary carries \"failed to read mcp_config.json\"\n * + a literal \"/.gemini/config\" path; there is NO `--mcp-config` flag and `agy\n * mcp` is TUI-only. So this adapter now OVERRIDES userConfigCandidates to prefer\n * `~/.gemini/config/mcp_config.json` (canonical) over the inherited IDE\n * `antigravity/` default (kept as a prefer-existing fallback). Telemetry-wrap is\n * compatible: agy spawns command+args verbatim, so the home-bin serve wrapper is\n * spawned as written — i.e. a real agy session now emits a per-MCP telemetry row.\n * (agy also keeps its own home ~/.gemini/antigravity-cli/ for auth/state, but MCP\n * config lives in the shared ~/.gemini/config/.)\n *\n * Project scope is IDENTICAL to the IDE adapter (`<proj>/.agents/…`), as is every\n * hook/command/skill render and the runtime parse/format — all inherited.\n *\n * The user-scope config paths shared with the IDE (hooks.json + the global skills\n * dir) remain MEDIUM-CONFIDENCE / PATH-PROBED in the parent (not present on the\n * observed install) and surfaced by the doctor; user-scope mcp_config + workflows\n * are CONFIRMED at ~/.gemini/antigravity/.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { AntigravityAdapter } from \"../antigravity/index.js\";\nimport type { Adapter } from \"../spi.js\";\nimport type { DetectedPlatform, PlatformId } from \"../../core/types.js\";\n\nconst HOST: PlatformId = \"antigravity-cli\";\n\nexport class AntigravityCliAdapter extends AntigravityAdapter implements Adapter {\n override readonly id: PlatformId = HOST;\n override readonly name = \"Antigravity CLI\";\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n /**\n * Probe the CLI's runtime markers, DISTINCT from the IDE app even though the\n * two share `~/.gemini/antigravity/`: the `agy` binary at ~/.local/bin/agy\n * (the definitive CLI marker, CONFIRMED present) and the shared\n * ~/.gemini/antigravity/ tree (or a user-scope mcp_config candidate / the\n * project config). Reported before the IDE adapter in the registry so the\n * more-specific CLI marker (the `agy` binary) wins host detection. Note: a\n * machine with ONLY the IDE (no `agy` binary) will not match here, while one\n * with the CLI matches on the binary regardless of the shared config dir.\n */\n override detectInstalled(projectDir: string): DetectedPlatform {\n const home = homedir();\n const userConfig = this.resolveUserConfigPath();\n const agyBin = join(home, \".local\", \"bin\", \"agy\");\n const sharedDir = join(home, \".gemini\", \"antigravity\");\n const projectConfig = join(projectDir, \".agents\", \"mcp_config.json\");\n\n // The `agy` binary is the definitive CLI marker. The shared antigravity dir\n // and the user-scope mcp_config candidates are secondary signals (they also\n // match a pure-IDE install, so the binary is what truly distinguishes the CLI).\n const cliMarker = existsSync(agyBin);\n const userInstalled =\n cliMarker ||\n existsSync(sharedDir) ||\n this.userConfigCandidates().some((parts) => existsSync(join(home, ...parts)));\n const projInstalled = existsSync(projectConfig);\n const installed = userInstalled || projInstalled;\n\n // Report the scope/path that actually matched, so a project-only install\n // isn't misreported as a (non-existent) user install.\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projectConfig : userConfig;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? scope === \"project\"\n ? `found project Antigravity CLI config at ${projectConfig}`\n : `found Antigravity CLI (agy) at ${agyBin} / shared ${sharedDir}`\n : `no Antigravity CLI install at ${agyBin}, ${sharedDir}, or ${projectConfig}`,\n // The `agy` binary is a high-confidence CLI marker; matching only the shared\n // config dir is weaker (it could be a pure-IDE install).\n confidence: cliMarker ? \"high\" : installed ? \"medium\" : \"low\",\n };\n }\n\n /**\n * MCP user-config path — LIVE-PROVEN for `agy` v1.0.5 (2026-06-04). The\n * standalone CLI reads user MCP servers from `~/.gemini/config/mcp_config.json`\n * (root key `mcpServers`), NOT the IDE's `~/.gemini/antigravity/mcp_config.json`:\n * a real `agy -p` session spawned an MCP server ONLY when it was placed in\n * `config/` (negative control: a server in `antigravity/` was ignored), and the\n * binary carries the error string \"failed to read mcp_config.json\" + a literal\n * \"/.gemini/config\" path. `agy mcp` is TUI-only (no headless add) and there is\n * no `--mcp-config` flag. So the CLI must PREFER `config/` over the inherited\n * `antigravity/` default; the IDE path stays as a prefer-existing fallback.\n * (Skills/workflows/hooks dirs remain inherited; project scope\n * `<proj>/.agents/mcp_config.json` is already correct and live-proven.)\n */\n private static readonly CLI_USER_CONFIG_CANDIDATES = [\n [\".gemini\", \"config\", \"mcp_config.json\"], // CONFIRMED canonical for agy v1.0.5\n [\".gemini\", \"antigravity\", \"mcp_config.json\"], // legacy IDE layout (prefer-existing)\n ] as const;\n\n protected override userConfigCandidates(): ReadonlyArray<readonly string[]> {\n return AntigravityCliAdapter.CLI_USER_CONFIG_CANDIDATES;\n }\n}\n\nexport const adapter = new AntigravityCliAdapter();\nexport default adapter;\n"],"mappings":";;;;;;;;;;;AAyDA,SAAS,kBAAkB;AAC3B,SAAS,eAAe;AACxB,SAAS,YAAY;AAMrB,IAAM,OAAmB;AAElB,IAAM,wBAAN,MAAM,+BAA8B,mBAAsC;AAAA,EAC7D,KAAiB;AAAA,EACjB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAchB,gBAAgB,YAAsC;AAC7D,UAAM,OAAO,QAAQ;AACrB,UAAM,aAAa,KAAK,sBAAsB;AAC9C,UAAM,SAAS,KAAK,MAAM,UAAU,OAAO,KAAK;AAChD,UAAM,YAAY,KAAK,MAAM,WAAW,aAAa;AACrD,UAAM,gBAAgB,KAAK,YAAY,WAAW,iBAAiB;AAKnE,UAAM,YAAY,WAAW,MAAM;AACnC,UAAM,gBACJ,aACA,WAAW,SAAS,KACpB,KAAK,qBAAqB,EAAE,KAAK,CAAC,UAAU,WAAW,KAAK,MAAM,GAAG,KAAK,CAAC,CAAC;AAC9E,UAAM,gBAAgB,WAAW,aAAa;AAC9C,UAAM,YAAY,iBAAiB;AAInC,UAAM,QAAQ,iBAAiB,CAAC,gBAAgB,YAAY;AAC5D,UAAM,aAAa,UAAU,YAAY,gBAAgB;AAEzD,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,MAAM,KAAK;AAAA,MACX;AAAA,MACA,UAAU,KAAK;AAAA,MACf,cAAc,KAAK;AAAA,MACnB;AAAA,MACA;AAAA,MACA,QAAQ,YACJ,UAAU,YACR,2CAA2C,aAAa,KACxD,kCAAkC,MAAM,aAAa,SAAS,KAChE,iCAAiC,MAAM,KAAK,SAAS,QAAQ,aAAa;AAAA;AAAA;AAAA,MAG9E,YAAY,YAAY,SAAS,YAAY,WAAW;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAwB,6BAA6B;AAAA,IACnD,CAAC,WAAW,UAAU,iBAAiB;AAAA;AAAA,IACvC,CAAC,WAAW,eAAe,iBAAiB;AAAA;AAAA,EAC9C;AAAA,EAEmB,uBAAyD;AAC1E,WAAO,uBAAsB;AAAA,EAC/B;AACF;AAEO,IAAM,UAAU,IAAI,sBAAsB;AACjD,IAAO,0BAAQ;","names":[]}
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/cli/app.ts
4
+ import { createRequire } from "module";
5
+ function print(line) {
6
+ process.stdout.write(`${line}
7
+ `);
8
+ }
9
+ var activeProgramName = "agent-connector";
10
+ function fail(message, code = 2) {
11
+ process.stderr.write(`${activeProgramName}: ${message}
12
+ `);
13
+ return code;
14
+ }
15
+ function resolveOwnVersion() {
16
+ const req = createRequire(import.meta.url);
17
+ for (const rel of ["../package.json", "../../package.json", "../../../package.json"]) {
18
+ try {
19
+ const pkg = req(rel);
20
+ if (pkg.name === "@ken-jo/agent-connector" && typeof pkg.version === "string") {
21
+ return pkg.version;
22
+ }
23
+ } catch {
24
+ }
25
+ }
26
+ return "0.0.0";
27
+ }
28
+ function parseScope(value) {
29
+ if (value === "user" || value === "project") return value;
30
+ return null;
31
+ }
32
+ function parseTargets(value) {
33
+ if (value == null || value.trim() === "") return void 0;
34
+ const ids = value.split(",").map((s) => s.trim()).filter((s) => s !== "");
35
+ return ids.length > 0 ? ids : void 0;
36
+ }
37
+ var ACTION_GLYPH = {
38
+ create: "+",
39
+ update: "~",
40
+ remove: "-",
41
+ skip: "=",
42
+ warn: "!"
43
+ };
44
+ function renderInstallResult(result, verb) {
45
+ const lines = [];
46
+ const mode = result.dryRun ? " (dry-run \u2014 nothing written)" : "";
47
+ lines.push(`${verb} "${result.connectorId}"${mode}`);
48
+ if (result.changes.length === 0) {
49
+ lines.push(" (no changes)");
50
+ } else {
51
+ for (const c of result.changes) {
52
+ const glyph = ACTION_GLYPH[c.action];
53
+ const where = c.path ? ` ${c.path}` : "";
54
+ lines.push(` ${glyph} [${c.platform}] ${c.action}: ${c.detail}${where}`);
55
+ }
56
+ }
57
+ if (result.warnings.length > 0) {
58
+ lines.push("");
59
+ lines.push("warnings:");
60
+ for (const w of result.warnings) lines.push(` ! ${w}`);
61
+ }
62
+ const tally = result.changes.reduce(
63
+ (acc, c) => {
64
+ acc[c.action] += 1;
65
+ return acc;
66
+ },
67
+ { create: 0, update: 0, remove: 0, skip: 0, warn: 0 }
68
+ );
69
+ lines.push("");
70
+ lines.push(
71
+ `summary: ${tally.create} created, ${tally.update} updated, ${tally.remove} removed, ${tally.skip} skipped, ${tally.warn} warning(s)`
72
+ );
73
+ return lines.join("\n");
74
+ }
75
+ var COMMANDS = {
76
+ detect: () => import("./detect-WIAGVYS4.js"),
77
+ install: () => import("./install-HQRYZOQ2.js"),
78
+ uninstall: () => import("./uninstall-IGCKNOSF.js"),
79
+ // `upgrade` is the single "bring everything current" verb (re-render host
80
+ // config + refresh the home pointer + managed channel guidance). `sync` and
81
+ // `update` are kept as back-compat aliases that route to the same module so
82
+ // existing scripts/docs keep working without a second concept to learn.
83
+ upgrade: () => import("./upgrade-JV2VK242.js"),
84
+ sync: () => import("./upgrade-JV2VK242.js"),
85
+ update: () => import("./upgrade-JV2VK242.js"),
86
+ package: () => import("./package-DLOVE2E4.js"),
87
+ doctor: () => import("./doctor-EZW2K4NI.js"),
88
+ status: () => import("./status-FE7TECZD.js"),
89
+ telemetry: () => import("./telemetry-36GESKQQ.js"),
90
+ usage: () => import("./usage-6ER6EMEY.js"),
91
+ leaderboard: () => import("./leaderboard-K6ON3SWW.js"),
92
+ hook: () => import("./hook-YVDILAMZ.js"),
93
+ serve: () => import("./serve-HVWWY4B6.js"),
94
+ // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an
95
+ // AfterModel / PostInvocation hook points at. Always exits 0; records a
96
+ // distinct `model_turn` row. See cli/commands/usage-event.ts.
97
+ "usage-event": () => import("./usage-event-JKBI6XCF.js")
98
+ };
99
+ var DEFAULT_PROGRAM_NAME = "agent-connector";
100
+ var COMMAND_USAGE = {
101
+ detect: "detect [--json] [--project <dir>]",
102
+ install: "install [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run]",
103
+ uninstall: "uninstall [--connector <path>] [--connector-id <id>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--purge]",
104
+ upgrade: "upgrade [--channel stable|latest] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run]",
105
+ sync: "sync \u2014 alias of upgrade (see `upgrade --help`)",
106
+ update: "update \u2014 alias of upgrade (see `upgrade --help`)",
107
+ package: "package [--connector <path>] [--format <fmt>|all] [--out <dir>] [--project <dir>] [--dry-run]",
108
+ doctor: "doctor [--targets a,b] [--connector <path>] [--scope user|project] [--project <dir>] [--probe] [--json]",
109
+ status: "status [--connector <path>] [--scope user|project] [--project <dir>] [--json]",
110
+ telemetry: "telemetry report|export|leaderboard [--by <dim>] [--since <dur>] [--connector <id>] [--scope <slice>] [--format csv|json] [--out <file>] [--json]",
111
+ usage: "usage report|export|leaderboard [--by <dim>] [--since <dur>] [--platform <id>] [--format csv|json] [--out <file>] [--json]",
112
+ leaderboard: "leaderboard [--since <dur>] [--connector <id>] [--scope <slice>] [--json]",
113
+ hook: "hook <platform> <event> --connector <id> (internal \u2014 host hook configs point here)",
114
+ serve: "serve --connector <id> [--scope user|project] [--host <platformId>] -- <command> [args...] (internal \u2014 host MCP entries point here)"
115
+ };
116
+ function buildUsage(programName) {
117
+ return `${programName} \u2014 write your MCP server + hooks once, install everywhere.
118
+
119
+ usage: ${programName} <command> [flags]
120
+
121
+ commands:
122
+ detect List the AI-agent platforms installed on this machine.
123
+ install Deploy a connector across its target platforms.
124
+ uninstall Remove a connector's MCP + hook registrations.
125
+ upgrade Bring everything current: re-render host config + heal the home pointer + managed update guidance (alias: update, sync).
126
+ package Emit a marketplace/extension bundle (9 host formats, or the standard artifacts mcp-server-json | mcpb).
127
+ doctor Health-check every detected platform; non-zero exit on any failure.
128
+ status Light install-state summary: which connectors are present on which hosts (always exits 0).
129
+ telemetry Inspect local per-tool token telemetry (report | export | leaderboard).
130
+ usage Inspect host-native token usage from agent CLI logs (report | export | leaderboard).
131
+ leaderboard Three leaderboards: \u{1F50C} MCP/plugin (mcp-self) + \u{1F5A5}\uFE0F host/user (host-scan-logs) + \u{1F6F0}\uFE0F host-native turns (host-native-live) \u2014 never summed.
132
+ hook Universal json-stdio hook entrypoint (hosts call this).
133
+ serve Telemetry-wrapping MCP stdio proxy (wraps a real server command).
134
+
135
+ Run \`${programName} <command> --help\` for command-specific flags.`;
136
+ }
137
+ async function main(argv, opts = {}) {
138
+ const programName = opts.programName ?? DEFAULT_PROGRAM_NAME;
139
+ activeProgramName = programName;
140
+ const usage = buildUsage(programName);
141
+ const command = argv[0];
142
+ if (command == null || command === "--help" || command === "-h" || command === "help") {
143
+ print(usage);
144
+ return command == null ? 1 : 0;
145
+ }
146
+ if (command === "--version" || command === "-v") {
147
+ print(`${programName} ${resolveOwnVersion()}`);
148
+ return 0;
149
+ }
150
+ const loader = COMMANDS[command];
151
+ if (!loader) {
152
+ process.stderr.write(`${programName}: unknown command "${command}"
153
+
154
+ `);
155
+ process.stderr.write(`${usage}
156
+ `);
157
+ return 2;
158
+ }
159
+ const rest = argv.slice(1);
160
+ if (rest.includes("--help") || rest.includes("-h")) {
161
+ const sig = COMMAND_USAGE[command];
162
+ if (sig) {
163
+ print(`usage: ${programName} ${sig}`);
164
+ return 0;
165
+ }
166
+ }
167
+ const mod = await loader();
168
+ try {
169
+ return await mod.run(rest);
170
+ } catch (err) {
171
+ const code = err.code;
172
+ if (typeof code === "string" && code.startsWith("ERR_PARSE_ARGS")) {
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ const sig = COMMAND_USAGE[command];
175
+ if (sig) process.stderr.write(`usage: ${programName} ${sig}
176
+ `);
177
+ return fail(message);
178
+ }
179
+ throw err;
180
+ }
181
+ }
182
+
183
+ export {
184
+ print,
185
+ fail,
186
+ parseScope,
187
+ parseTargets,
188
+ renderInstallResult,
189
+ main
190
+ };
191
+ //# sourceMappingURL=chunk-54EMKTTX.js.map