@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 @@
1
+ {"version":3,"sources":["../src/usage/readers/gemini-cli.ts"],"sourcesContent":["/**\n * usage/readers/gemini-cli — Gemini CLI native session-log reader.\n *\n * Faithful port of tokscale sessions/gemini.rs. Reads ~/.gemini/tmp/ recursively\n * and supports the three on-disk shapes the Gemini CLI has shipped:\n * 1. legacy structured JSON — `session-*.json` with a top-level\n * { sessionId, messages: [{ type, model, timestamp, tokens }] } object;\n * 2. headless single-value JSON — one object carrying either a direct `tokens`\n * block (type:\"gemini\") or a `stats` / `result.stats` rollup;\n * 3. headless JSONL stream — newline-delimited events: `init` (carries\n * model + session_id), direct-token `gemini` events (keyed by `id`), and\n * `result`/`stats` rollups.\n *\n * Discovery (port of the path filter in parse_gemini_file_with_cache_status):\n * - legacy files whose name starts with \"session-\" are accepted on ANY path;\n * - any other file must sit at exactly `.../tmp/<id>/chats/<file>` (the three\n * components right after a `tmp` segment), so a backup/nested chats dir is\n * rejected. Both .json and .jsonl are read.\n *\n * Token fields (alias list honored exactly as gemini.rs first_i64 / extract_*):\n * input ← input, prompt, input_tokens, prompt_tokens, promptTokenCount\n * output ← output, candidates, output_tokens, completion_tokens,\n * candidates_tokens, candidatesTokenCount\n * cacheRead ← cached, cached_tokens, cachedContentTokenCount\n * reasoning ← thoughts, reasoning, thoughts_tokens, reasoning_tokens\n * tool ← tool, tool_tokens (folded INTO input after normalization)\n * total ← total, totalTokenCount, total_tokens\n * cacheWrite is always 0 (Gemini does not report it).\n *\n * Cache-inclusive input normalization (matches gemini.rs exactly):\n * - structured session messages: promptTokenCount is normally cache-inclusive.\n * normalize_gemini_session_input_and_cache only subtracts the cached portion\n * when a `total` is present AND total == input+output+reasoning+tool (i.e.\n * cached is NOT already counted in input); otherwise input is left as-is.\n * Then `tool` is added to the (possibly net) input.\n * - headless stats: when the chosen input alias is a cache-INCLUSIVE one\n * (prompt*, or a `tokens`-wrapper `input`, or the only alias present),\n * subtract the cached overlap (clamped ≥ 0); when a net `input` alias was\n * used directly, keep it as-is.\n *\n * Dedup (the double-count guard): within a single JSONL file, direct-token\n * events carrying an `id` are deduped LAST-WINS — a later event with the same id\n * replaces the earlier one (port of direct_message_indices HashMap). Stats-\n * derived rows and id-less direct rows are never deduped. The cross-file\n * dedupKey we expose is `<sessionId>:<id>` for the keyed direct rows.\n *\n * Provider is hard-coded \"google\", confidence \"host-reported\".\n *\n * Fail-open: no ~/.gemini/tmp → []; unreadable/malformed file or line → skipped.\n */\n\nimport { basename } from \"node:path\";\n\nimport type { UsageReader, UsageRecord } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { fileMtimeMs, readJsonFile, readJsonlLines } from \"../jsonl.js\";\nimport { firstExistingRoot, walkFiles } from \"../paths.js\";\n\nconst PLATFORM_ID = \"gemini-cli\" as const;\nconst PROVIDER = \"google\";\nconst DEFAULT_MODEL = \"unknown\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Scalar coercion (ports of utils.rs extract_i64 / extract_string)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** extract_i64: number (int or via Number) or a numeric string → integer, else null. */\nfunction extractI64(v: unknown): number | null {\n if (typeof v === \"number\" && Number.isFinite(v)) return Math.trunc(v);\n if (typeof v === \"string\") {\n const n = Number(v);\n if (Number.isInteger(n)) return n;\n }\n return null;\n}\n\n/** extract_string: a non-undefined string value, else null. */\nfunction extractString(v: unknown): string | null {\n return typeof v === \"string\" ? v : null;\n}\n\n/** first_i64(value, keys): first key whose value coerces to an integer. */\nfunction firstI64(obj: Record<string, unknown>, keys: readonly string[]): number | null {\n for (const k of keys) {\n const got = extractI64(obj[k]);\n if (got !== null) return got;\n }\n return null;\n}\n\n/** Clamp to a non-negative integer (the Rust `.max(0)` on i64 values). */\nfunction nonNeg(n: number): number {\n return n > 0 ? Math.trunc(n) : 0;\n}\n\n/** Saturating add of two non-negative ints (i64 saturating_add ≈ JS add for our ranges). */\nfunction satAdd(a: number, b: number): number {\n return a + b;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Timestamp (ports of utils.rs parse_timestamp_value + extract_timestamp_from_value)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** parse_timestamp_value: RFC3339 string, numeric (s→ms unless already ms), >0 only. */\nfunction parseTimestampValue(v: unknown): number | null {\n if (typeof v === \"string\") {\n const ms = Date.parse(v);\n if (!Number.isNaN(ms)) return ms;\n const numeric = Number(v);\n if (Number.isInteger(numeric)) {\n if (numeric <= 0) return null;\n return numeric >= 1_000_000_000_000 ? numeric : numeric * 1000;\n }\n return null;\n }\n if (typeof v === \"number\" && Number.isFinite(v)) {\n const numeric = Math.trunc(v);\n if (numeric <= 0) return null;\n return numeric >= 1_000_000_000_000 ? numeric : numeric * 1000;\n }\n return null;\n}\n\n/** extract_timestamp_from_value: `timestamp` then `created_at`, via parse_timestamp_value. */\nfunction extractTimestampFromValue(obj: Record<string, unknown>): number | null {\n const ts = obj.timestamp;\n if (ts !== undefined) {\n const got = parseTimestampValue(ts);\n if (got !== null) return got;\n }\n const created = obj.created_at;\n if (created !== undefined) {\n const got = parseTimestampValue(created);\n if (got !== null) return got;\n }\n return null;\n}\n\n/** Parse an RFC3339 timestamp string only (used for structured session messages). */\nfunction parseRfc3339(v: unknown): number | null {\n if (typeof v !== \"string\") return null;\n const ms = Date.parse(v);\n return Number.isNaN(ms) ? null : ms;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Cache-inclusive input normalization (ports of gemini.rs)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** subtract_cached_overlap: net input = max(0, input - min(cached, input)); cached unchanged. */\nfunction subtractCachedOverlap(input: number, cached: number): [number, number] {\n const i = nonNeg(input);\n const c = nonNeg(cached);\n const cachedPortion = Math.min(c, i);\n return [i - cachedPortion, c];\n}\n\n/**\n * normalize_gemini_session_input_and_cache: only subtract the cached overlap\n * when a total is present and equals the cache-EXCLUSIVE sum\n * (input+output+reasoning+tool), i.e. cached is not already inside `input`.\n */\nfunction normalizeSessionInputAndCache(\n input: number,\n cached: number,\n output: number,\n reasoning: number,\n tool: number,\n total: number | null,\n): [number, number] {\n const i = nonNeg(input);\n const c = nonNeg(cached);\n\n if (total === null) return [i, c];\n const t = nonNeg(total);\n\n const inclusiveTotal = satAdd(satAdd(satAdd(i, nonNeg(output)), nonNeg(reasoning)), nonNeg(tool));\n const exclusiveTotal = satAdd(inclusiveTotal, c);\n\n if (c > 0 && t === inclusiveTotal && t !== exclusiveTotal) {\n return subtractCachedOverlap(i, c);\n }\n return [i, c];\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Token deserialization\n// ─────────────────────────────────────────────────────────────────────────\n\ninterface GeminiTokens {\n input: number | null;\n output: number | null;\n cached: number | null;\n thoughts: number | null;\n tool: number | null;\n total: number | null;\n}\n\n/** deserialize_tokens: structured-message alias list via first_i64. */\nfunction deserializeTokens(value: unknown): GeminiTokens | null {\n if (typeof value !== \"object\" || value === null) return null;\n const obj = value as Record<string, unknown>;\n return {\n input: firstI64(obj, [\"input\", \"prompt\", \"input_tokens\", \"prompt_tokens\", \"promptTokenCount\"]),\n output: firstI64(obj, [\n \"output\",\n \"candidates\",\n \"output_tokens\",\n \"completion_tokens\",\n \"candidatesTokenCount\",\n ]),\n cached: firstI64(obj, [\"cached\", \"cached_tokens\", \"cachedContentTokenCount\"]),\n thoughts: firstI64(obj, [\"thoughts\", \"reasoning\", \"thoughts_tokens\"]),\n tool: firstI64(obj, [\"tool\", \"tool_tokens\"]),\n total: firstI64(obj, [\"total\", \"totalTokenCount\", \"total_tokens\"]),\n };\n}\n\n/**\n * build_gemini_token_message: structured-message → record. `tool` is folded into\n * input after the (possibly cache-net) normalization; cacheWrite stays 0.\n */\nfunction buildTokenRecord(\n model: string,\n sessionId: string,\n ts: number,\n tokens: GeminiTokens,\n): UsageRecord {\n const [input, cacheRead] = normalizeSessionInputAndCache(\n tokens.input ?? 0,\n tokens.cached ?? 0,\n tokens.output ?? 0,\n tokens.thoughts ?? 0,\n tokens.tool ?? 0,\n tokens.total,\n );\n const tool = nonNeg(tokens.tool ?? 0);\n\n const tk = emptyTokens();\n tk.input = satAdd(input, tool);\n tk.output = nonNeg(tokens.output ?? 0);\n tk.cacheRead = cacheRead;\n tk.cacheWrite = 0;\n tk.reasoning = nonNeg(tokens.thoughts ?? 0);\n\n return {\n platformId: PLATFORM_ID,\n modelId: model,\n providerId: PROVIDER,\n sessionId,\n tokens: tk,\n ts,\n messageCount: 1,\n confidence: \"host-reported\",\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Headless stats extraction (ports of extract_gemini_usage* + build_messages_from_stats)\n// ─────────────────────────────────────────────────────────────────────────\n\ninterface GeminiHeadlessUsage {\n model: string;\n input: number;\n output: number;\n cached: number;\n reasoning: number;\n inputIncludesCache: boolean;\n}\n\n/** extract_gemini_usage_from_value: pull a usage from a stats blob (optionally `tokens`-wrapped). */\nfunction extractUsageFromValue(model: string, value: unknown): GeminiHeadlessUsage | null {\n if (typeof value !== \"object\" || value === null) return null;\n const outer = value as Record<string, unknown>;\n const hasTokensWrapper = outer.tokens !== undefined;\n const tokens =\n hasTokensWrapper && typeof outer.tokens === \"object\" && outer.tokens !== null\n ? (outer.tokens as Record<string, unknown>)\n : outer;\n\n const promptInput =\n extractI64(tokens.prompt) ??\n extractI64(tokens.input_tokens) ??\n extractI64(tokens.prompt_tokens);\n const netInput = extractI64(tokens.input);\n const wrapperInput = hasTokensWrapper ? netInput : null;\n const input = promptInput ?? wrapperInput ?? netInput ?? 0;\n\n const output =\n extractI64(tokens.candidates) ??\n extractI64(tokens.output) ??\n extractI64(tokens.output_tokens) ??\n extractI64(tokens.candidates_tokens) ??\n 0;\n const cached = extractI64(tokens.cached) ?? extractI64(tokens.cached_tokens) ?? 0;\n const reasoning =\n extractI64(tokens.thoughts) ??\n extractI64(tokens.thoughts_tokens) ??\n extractI64(tokens.reasoning) ??\n extractI64(tokens.reasoning_tokens) ??\n 0;\n\n if (input === 0 && output === 0 && cached === 0 && reasoning === 0) return null;\n\n return {\n model,\n input,\n output,\n cached,\n reasoning,\n inputIncludesCache: promptInput !== null || wrapperInput !== null || netInput === null,\n };\n}\n\n/** extract_gemini_usages: per-model breakdown under stats.models, else a single flat usage. */\nfunction extractUsages(stats: Record<string, unknown>, modelHint: string | null): GeminiHeadlessUsage[] {\n const models = stats.models;\n if (typeof models === \"object\" && models !== null && !Array.isArray(models)) {\n const usages: GeminiHeadlessUsage[] = [];\n for (const [model, data] of Object.entries(models as Record<string, unknown>)) {\n const usage = extractUsageFromValue(model, data);\n if (usage !== null) usages.push(usage);\n }\n if (usages.length > 0) return usages;\n }\n const single = extractUsageFromValue(modelHint ?? DEFAULT_MODEL, stats);\n return single === null ? [] : [single];\n}\n\n/** build_messages_from_stats: usages → records (net input via headless normalization). */\nfunction buildRecordsFromStats(\n stats: Record<string, unknown>,\n modelHint: string | null,\n sessionId: string,\n ts: number,\n): UsageRecord[] {\n return extractUsages(stats, modelHint).map((usage) => {\n const [input, cacheRead] = usage.inputIncludesCache\n ? subtractCachedOverlap(usage.input, usage.cached) // normalize_gemini_headless_input_and_cache\n : [nonNeg(usage.input), nonNeg(usage.cached)];\n const tk = emptyTokens();\n tk.input = input;\n tk.output = nonNeg(usage.output);\n tk.cacheRead = cacheRead;\n tk.cacheWrite = 0;\n tk.reasoning = nonNeg(usage.reasoning);\n return {\n platformId: PLATFORM_ID,\n modelId: usage.model,\n providerId: PROVIDER,\n sessionId,\n tokens: tk,\n ts,\n messageCount: 1,\n confidence: \"host-reported\",\n };\n });\n}\n\n/** stats = value.stats || value.result.stats (the rollup container). */\nfunction findStats(obj: Record<string, unknown>): Record<string, unknown> | null {\n if (typeof obj.stats === \"object\" && obj.stats !== null) return obj.stats as Record<string, unknown>;\n const result = obj.result;\n if (typeof result === \"object\" && result !== null) {\n const inner = (result as Record<string, unknown>).stats;\n if (typeof inner === \"object\" && inner !== null) return inner as Record<string, unknown>;\n }\n return null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Direct-token messages (type:\"gemini\" or a `tokens` block present)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** parse_direct_gemini_token_message: needs a model (own or hint) and a `tokens` block. */\nfunction parseDirectTokenRecord(\n obj: Record<string, unknown>,\n modelHint: string | null,\n sessionId: string,\n fallbackTs: number,\n): UsageRecord | null {\n const model = extractString(obj.model) ?? modelHint;\n if (model === null) return null;\n if (obj.tokens === undefined) return null;\n const tokens = deserializeTokens(obj.tokens);\n if (tokens === null) return null;\n const ts = extractTimestampFromValue(obj) ?? fallbackTs;\n return buildTokenRecord(model, sessionId, ts, tokens);\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Path discovery (port of the parse_gemini_file_with_cache_status filter)\n// ─────────────────────────────────────────────────────────────────────────\n\nfunction pathComponents(abs: string): string[] {\n return abs.split(/[\\\\/]+/).filter((c) => c !== \"\");\n}\n\n/**\n * Accept this file? Legacy `session-*` names pass anywhere. Otherwise the path\n * must end `.../tmp/<id>/chats/<file>` — exactly three components after a `tmp`\n * segment, with the middle one literally \"chats\" and the last being this file.\n */\nfunction isAcceptedFile(abs: string): boolean {\n const name = basename(abs);\n if (name.startsWith(\"session-\")) return true;\n const comps = pathComponents(abs);\n for (let i = 0; i + 1 < comps.length; i++) {\n if (comps[i] === \"tmp\") {\n const afterTmp = comps.slice(i + 1);\n if (afterTmp.length === 3 && afterTmp[1] === \"chats\" && afterTmp[2] === name) {\n return true;\n }\n }\n }\n return false;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Per-file parsing\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Is a parsed JSON value a structured GeminiSession (has a messages array)? */\nfunction asGeminiSession(value: unknown): { sessionId: string; messages: unknown[] } | null {\n if (typeof value !== \"object\" || value === null) return null;\n const obj = value as Record<string, unknown>;\n if (!Array.isArray(obj.messages)) return null;\n // serde requires sessionId/projectHash/startTime/lastUpdated as strings; mirror\n // the strict struct shape so a headless value (no sessionId) falls through.\n if (typeof obj.sessionId !== \"string\") return null;\n return { sessionId: obj.sessionId, messages: obj.messages };\n}\n\n/** parse_gemini_session: structured messages with a `tokens` block and a `model`. */\nfunction parseSession(\n session: { sessionId: string; messages: unknown[] },\n fallbackTs: number,\n): UsageRecord[] {\n const out: UsageRecord[] = [];\n for (const raw of session.messages) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const msg = raw as Record<string, unknown>;\n const tokens = deserializeTokens(msg.tokens);\n if (tokens === null) continue; // only messages with token data\n const model = extractString(msg.model);\n if (model === null) continue; // model required\n const ts = parseRfc3339(msg.timestamp) ?? fallbackTs;\n out.push(buildTokenRecord(model, session.sessionId, ts, tokens));\n }\n return out;\n}\n\n/** parse_gemini_headless_value: one JSON value → direct-token row or stats rows. */\nfunction parseHeadlessValue(\n value: unknown,\n sessionId: string,\n fallbackTs: number,\n): UsageRecord[] {\n if (typeof value !== \"object\" || value === null) return [];\n const obj = value as Record<string, unknown>;\n\n if (obj.type === \"gemini\" || obj.tokens !== undefined) {\n const direct = parseDirectTokenRecord(obj, null, sessionId, fallbackTs);\n if (direct !== null) return [direct];\n }\n\n const stats = findStats(obj);\n if (stats === null) return [];\n const modelHint = extractString(obj.model);\n const ts = extractTimestampFromValue(obj) ?? fallbackTs;\n return buildRecordsFromStats(stats, modelHint, sessionId, ts);\n}\n\n/**\n * parse_gemini_headless_jsonl: stateful newline-delimited stream.\n * - `init` sets current_model + session_id;\n * - any line may carry session_id/sessionId (updates the running id);\n * - direct-token events (type:\"gemini\" or has `tokens`) build a row, deduped\n * LAST-WINS by `id` (a later same-id event overwrites the earlier row);\n * - `stats`/`result.stats` rollups append non-deduped rows.\n * Session id seeds from the file stem.\n */\nfunction parseHeadlessJsonl(path: string, fallbackTs: number): UsageRecord[] {\n const lines = readJsonlLines(path);\n let sessionId = stripExt(basename(path)) || \"unknown\";\n let currentModel: string | null = null;\n const records: UsageRecord[] = [];\n const directIndexById = new Map<string, number>();\n\n for (const raw of lines) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const obj = raw as Record<string, unknown>;\n const eventType = extractString(obj.type) ?? \"\";\n\n if (eventType === \"init\") {\n const model = extractString(obj.model);\n if (model !== null) currentModel = model;\n const id = extractString(obj.session_id) ?? extractString(obj.sessionId);\n if (id !== null) sessionId = id;\n continue;\n }\n\n const lineSession = extractString(obj.session_id) ?? extractString(obj.sessionId);\n if (lineSession !== null) sessionId = lineSession;\n\n if (eventType === \"gemini\" || obj.tokens !== undefined) {\n const model = extractString(obj.model);\n if (model !== null) currentModel = model;\n\n const record = parseDirectTokenRecord(obj, currentModel, sessionId, fallbackTs);\n if (record !== null) {\n const id = extractString(obj.id);\n if (id !== null) {\n record.dedupKey = `${sessionId}:${id}`;\n const existing = directIndexById.get(id);\n if (existing !== undefined) {\n records[existing] = record; // replace (last-wins)\n } else {\n directIndexById.set(id, records.length);\n records.push(record);\n }\n } else {\n records.push(record);\n }\n }\n continue;\n }\n\n const stats = findStats(obj);\n if (stats !== null) {\n const ts = extractTimestampFromValue(obj) ?? fallbackTs;\n for (const rec of buildRecordsFromStats(stats, currentModel, sessionId, ts)) {\n records.push(rec);\n }\n }\n }\n\n return records;\n}\n\nfunction stripExt(name: string): string {\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(0, dot) : name;\n}\n\n/** Parse one Gemini file (port of parse_gemini_file_with_cache_status). */\nfunction parseGeminiFile(path: string): UsageRecord[] {\n const fallbackTs = fileMtimeMs(path);\n\n // .jsonl always uses the streaming parser.\n if (path.endsWith(\".jsonl\")) {\n return parseHeadlessJsonl(path, fallbackTs);\n }\n\n // .json: try structured session, then headless value, then JSONL fallback.\n const value = readJsonFile(path);\n if (value !== undefined) {\n const session = asGeminiSession(value);\n if (session !== null) {\n return parseSession(session, fallbackTs);\n }\n const sessionId = stripExt(basename(path)) || \"unknown\";\n const headless = parseHeadlessValue(value, sessionId, fallbackTs);\n if (headless.length > 0) return headless;\n }\n\n // Last resort: treat as JSONL (mirrors the Rust fall-through).\n return parseHeadlessJsonl(path, fallbackTs);\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Reader\n// ─────────────────────────────────────────────────────────────────────────\n\nconst geminiReader: UsageReader = {\n platformId: PLATFORM_ID,\n kind: \"local\",\n async read({ sinceMs }: { sinceMs?: number }): Promise<UsageRecord[]> {\n const root = firstExistingRoot(PLATFORM_ID);\n if (root === undefined) return []; // no ~/.gemini/tmp → fail-open\n\n const files = walkFiles(root, (name, abs) => {\n if (!name.endsWith(\".json\") && !name.endsWith(\".jsonl\")) return false;\n return isAcceptedFile(abs);\n });\n\n const records: UsageRecord[] = [];\n for (const file of files) {\n let rows: UsageRecord[];\n try {\n rows = parseGeminiFile(file);\n } catch {\n rows = []; // fail-open per file\n }\n for (const row of rows) {\n if (sinceMs !== undefined && row.ts < sinceMs) continue;\n records.push(row);\n }\n }\n return records;\n },\n};\n\nexport default geminiReader;\n"],"mappings":"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","names":[]}