@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,217 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ fileMtimeMs,
4
+ readJsonFile,
5
+ readJsonlLines
6
+ } from "./chunk-RK6VBLXP.js";
7
+ import {
8
+ firstExistingRoot,
9
+ walkFiles
10
+ } from "./chunk-JWNT5KW7.js";
11
+ import {
12
+ emptyTokens,
13
+ normalizeWorkspaceKey,
14
+ workspaceLabelFromKey
15
+ } from "./chunk-XD7MY6HB.js";
16
+
17
+ // src/usage/readers/kiro.ts
18
+ import { basename } from "path";
19
+ var PLATFORM_ID = "kiro";
20
+ var PROVIDER_ID = "amazon-bedrock";
21
+ var UNKNOWN_MODEL = "unknown";
22
+ function toNum(v) {
23
+ if (typeof v === "number" && Number.isFinite(v)) return v;
24
+ if (typeof v === "string") {
25
+ const n = Number(v);
26
+ if (Number.isFinite(n)) return n;
27
+ }
28
+ return null;
29
+ }
30
+ function toNonNegInt(v) {
31
+ const n = toNum(v);
32
+ if (n === null) return 0;
33
+ return Math.max(0, Math.trunc(n));
34
+ }
35
+ function estimateTokens(chars) {
36
+ return Math.ceil(Math.max(0, chars) / 4);
37
+ }
38
+ function secondsToMillis(seconds) {
39
+ return Math.trunc(seconds * 1e3);
40
+ }
41
+ function stripExt(name) {
42
+ const dot = name.lastIndexOf(".");
43
+ return dot > 0 ? name.slice(0, dot) : name;
44
+ }
45
+ function parseTimestampValue(v) {
46
+ if (typeof v === "number" && Number.isFinite(v)) {
47
+ return Math.abs(v) < 1e12 ? secondsToMillis(v) : Math.trunc(v);
48
+ }
49
+ if (typeof v === "string") {
50
+ const ms = Date.parse(v);
51
+ if (!Number.isNaN(ms)) return ms;
52
+ const n = Number(v);
53
+ if (Number.isFinite(n)) return secondsToMillis(n);
54
+ }
55
+ return null;
56
+ }
57
+ function textCharCount(content) {
58
+ if (!Array.isArray(content)) return 0;
59
+ let total = 0;
60
+ for (const part of content) {
61
+ if (typeof part !== "object" || part === null) continue;
62
+ const kind = part.kind;
63
+ const isText = kind === void 0 || kind === null || kind === "text";
64
+ if (!isText) continue;
65
+ const data = part.data;
66
+ if (typeof data === "string") total += [...data].length;
67
+ }
68
+ return total;
69
+ }
70
+ function readJsonlContent(jsonlPath) {
71
+ const byId = /* @__PURE__ */ new Map();
72
+ const lines = readJsonlLines(jsonlPath);
73
+ if (lines.length === 0) return byId;
74
+ let pendingPromptChars = null;
75
+ let pendingPromptTs = null;
76
+ for (const raw of lines) {
77
+ if (typeof raw !== "object" || raw === null) continue;
78
+ const entry = raw;
79
+ const kind = entry.kind;
80
+ const data = entry.data;
81
+ if (typeof data !== "object" || data === null) continue;
82
+ const messageId = data.message_id;
83
+ if (typeof messageId !== "string") continue;
84
+ const textChars = textCharCount(data.content);
85
+ if (kind === "Prompt") {
86
+ const metaTs = data.meta?.timestamp;
87
+ const tsNum = toNum(metaTs);
88
+ pendingPromptChars = textChars;
89
+ pendingPromptTs = tsNum === null ? null : secondsToMillis(tsNum);
90
+ } else if (kind === "AssistantMessage") {
91
+ let msg = byId.get(messageId);
92
+ if (msg === void 0) {
93
+ msg = { promptChars: 0, assistantChars: 0, promptTimestampMs: null };
94
+ byId.set(messageId, msg);
95
+ }
96
+ if (pendingPromptChars !== null) {
97
+ msg.promptChars += pendingPromptChars;
98
+ if (msg.promptTimestampMs === null) msg.promptTimestampMs = pendingPromptTs;
99
+ pendingPromptChars = null;
100
+ pendingPromptTs = null;
101
+ }
102
+ msg.assistantChars += textChars;
103
+ }
104
+ }
105
+ return byId;
106
+ }
107
+ function parseKiroFile(jsonPath) {
108
+ const header = readJsonFile(jsonPath);
109
+ if (typeof header !== "object" || header === null) return [];
110
+ const h = header;
111
+ const fallbackTs = fileMtimeMs(jsonPath);
112
+ const sessionId = typeof h.session_id === "string" && h.session_id !== "" ? h.session_id : stripExt(basename(jsonPath)) || "unknown";
113
+ const modelInfo = h.session_state?.rts_model_state?.model_info;
114
+ const rawModel = modelInfo?.model_id;
115
+ const modelId = typeof rawModel === "string" && rawModel.trim() !== "" ? rawModel : UNKNOWN_MODEL;
116
+ const contextWindow = toNonNegInt(modelInfo?.context_window_tokens);
117
+ let projectKey;
118
+ let projectLabel;
119
+ if (typeof h.cwd === "string") {
120
+ projectKey = normalizeWorkspaceKey(h.cwd);
121
+ if (projectKey !== void 0) projectLabel = workspaceLabelFromKey(projectKey);
122
+ }
123
+ const turnsRaw = h.session_state?.conversation_metadata?.user_turn_metadatas;
124
+ const turns = Array.isArray(turnsRaw) ? turnsRaw : [];
125
+ if (turns.length === 0) return [];
126
+ const jsonlPath = jsonPath.replace(/\.json$/, ".jsonl");
127
+ const contentById = readJsonlContent(jsonlPath);
128
+ const out = [];
129
+ turns.forEach((turn, index) => {
130
+ if (typeof turn !== "object" || turn === null) return;
131
+ let promptChars = 0;
132
+ let assistantChars = 0;
133
+ let promptTimestampMs = null;
134
+ const messageIds = turn.message_ids;
135
+ if (Array.isArray(messageIds)) {
136
+ for (const mid of messageIds) {
137
+ if (typeof mid !== "string") continue;
138
+ const content = contentById.get(mid);
139
+ if (content === void 0) continue;
140
+ promptChars += content.promptChars;
141
+ assistantChars += content.assistantChars;
142
+ if (promptTimestampMs === null) promptTimestampMs = content.promptTimestampMs;
143
+ }
144
+ }
145
+ const explicitInput = toNonNegInt(turn.input_token_count);
146
+ const explicitOutput = toNonNegInt(turn.output_token_count);
147
+ let input;
148
+ let inputEstimated;
149
+ if (explicitInput > 0) {
150
+ input = explicitInput;
151
+ inputEstimated = false;
152
+ } else {
153
+ inputEstimated = true;
154
+ const ctxPct = toNum(turn.context_usage_percentage) ?? 0;
155
+ if (contextWindow > 0 && ctxPct > 0) {
156
+ input = Math.trunc(contextWindow * ctxPct / 100);
157
+ } else {
158
+ input = estimateTokens(promptChars);
159
+ }
160
+ }
161
+ let output;
162
+ let outputEstimated;
163
+ if (explicitOutput > 0) {
164
+ output = explicitOutput;
165
+ outputEstimated = false;
166
+ } else {
167
+ output = estimateTokens(assistantChars);
168
+ outputEstimated = true;
169
+ }
170
+ if (input + output === 0) return;
171
+ const endTs = parseTimestampValue(turn.end_timestamp);
172
+ const ts = promptTimestampMs ?? endTs ?? fallbackTs;
173
+ const messageCount = Math.max(1, toNonNegInt(turn.total_request_count) || 1);
174
+ const tokens = emptyTokens();
175
+ tokens.input = input;
176
+ tokens.output = output;
177
+ const confidence = inputEstimated || outputEstimated ? "host-estimated" : "host-reported";
178
+ const record = {
179
+ platformId: PLATFORM_ID,
180
+ modelId,
181
+ providerId: PROVIDER_ID,
182
+ sessionId,
183
+ tokens,
184
+ ts,
185
+ messageCount,
186
+ dedupKey: `${sessionId}:${index}`,
187
+ confidence
188
+ };
189
+ if (projectKey !== void 0) record.projectKey = projectKey;
190
+ if (projectLabel !== void 0) record.projectLabel = projectLabel;
191
+ out.push(record);
192
+ });
193
+ return out;
194
+ }
195
+ var kiroReader = {
196
+ platformId: PLATFORM_ID,
197
+ kind: "local",
198
+ async read({ sinceMs }) {
199
+ const root = firstExistingRoot(PLATFORM_ID);
200
+ if (root === void 0) return [];
201
+ const files = walkFiles(root, (name) => name.endsWith(".json"));
202
+ const records = [];
203
+ for (const file of files) {
204
+ const rows = parseKiroFile(file);
205
+ for (const row of rows) {
206
+ if (sinceMs !== void 0 && row.ts < sinceMs) continue;
207
+ records.push(row);
208
+ }
209
+ }
210
+ return records;
211
+ }
212
+ };
213
+ var kiro_default = kiroReader;
214
+ export {
215
+ kiro_default as default
216
+ };
217
+ //# sourceMappingURL=kiro-UCLSLBW2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/usage/readers/kiro.ts"],"sourcesContent":["/**\n * usage/readers/kiro — Kiro CLI (Amazon Bedrock) native session reader.\n *\n * Faithful port of tokscale sessions/kiro.rs (parse_kiro_file). Each session is a\n * pair of adjacent files under ~/.kiro/sessions/cli/:\n * <stem>.json — header: session_id, cwd, and session_state with the model\n * info (model_id, context_window_tokens) and the per-turn\n * metadata list (user_turn_metadatas[*]).\n * <stem>.jsonl — a transcript of Prompt / AssistantMessage entries keyed by\n * message_id, used ONLY to estimate per-turn char counts when\n * the header carries no explicit token counts.\n *\n * Token logic (per turn), ported exactly from the Rust:\n * input = input_token_count when > 0 (host-reported)\n * else context_window × context_usage_percentage/100 when both > 0\n * else ceil(promptChars / 4) (host-estimated)\n * output = output_token_count when > 0 (host-reported)\n * else ceil(assistantChars / 4) (host-estimated)\n * cacheRead / cacheWrite / reasoning are always 0 (Kiro reports none).\n * A turn whose input+output == 0 is dropped (matches the Rust filter_map).\n *\n * Confidence is per-record: \"host-reported\" only when BOTH dimensions came from\n * explicit host counts; any estimation (context% × window, or chars/4) makes the\n * row \"host-estimated\" (design §6: Kiro token counts are often estimated).\n *\n * Provider is hardcoded \"amazon-bedrock\". Session id is the header's session_id\n * (else the JSON file stem). Project is header.cwd normalized to a workspace key.\n * Timestamp prefers the matched Prompt entry's meta.timestamp (float seconds →\n * ms), then end_timestamp (int/float seconds-or-ms / RFC3339 string), then file\n * mtime. Dedup key is `<sessionId>:<turnIndex>` (turn-level uniqueness across\n * file rewrites), exactly the Rust format!(\"{}:{}\", session_id, index).\n *\n * NOTE: kiro.rs also reads a macOS SQLite source\n * (~/Library/Application Support/kiro-cli/data.sqlite3, table conversations_v2).\n * That source is intentionally NOT read in v1 — only the json/jsonl file pairs\n * are parsed here.\n *\n * Fail-open: no root → []; unreadable/malformed json or jsonl → that file is\n * skipped (the jsonl is optional — its absence just leaves char estimation at 0).\n */\n\nimport { basename } from \"node:path\";\n\nimport type { UsageReader, UsageRecord, UsageConfidence } from \"../types.js\";\nimport { emptyTokens } from \"../aggregate.js\";\nimport { fileMtimeMs, readJsonFile, readJsonlLines } from \"../jsonl.js\";\nimport { normalizeWorkspaceKey, workspaceLabelFromKey } from \"../normalize.js\";\nimport { firstExistingRoot, walkFiles } from \"../paths.js\";\n\nconst PLATFORM_ID = \"kiro\" as const;\nconst PROVIDER_ID = \"amazon-bedrock\";\nconst UNKNOWN_MODEL = \"unknown\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Header (.json) shapes — every field optional / unknown (host may omit any).\n// ─────────────────────────────────────────────────────────────────────────\n\ninterface KiroHeader {\n session_id?: unknown;\n cwd?: unknown;\n session_state?: {\n rts_model_state?: {\n model_info?: {\n model_id?: unknown;\n context_window_tokens?: unknown;\n };\n };\n conversation_metadata?: {\n user_turn_metadatas?: unknown;\n };\n };\n}\n\ninterface KiroTurn {\n input_token_count?: unknown;\n output_token_count?: unknown;\n end_timestamp?: unknown;\n total_request_count?: unknown;\n message_ids?: unknown;\n context_usage_percentage?: unknown;\n}\n\n/** Accumulated char counts (and first prompt ts) for one message_id. */\ninterface KiroMessageContent {\n promptChars: number;\n assistantChars: number;\n promptTimestampMs: number | null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Coercion helpers (tolerant — garbage degrades to a safe default).\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Coerce to a finite number, or null when not numeric. */\nfunction toNum(v: unknown): number | null {\n if (typeof v === \"number\" && Number.isFinite(v)) return v;\n if (typeof v === \"string\") {\n const n = Number(v);\n if (Number.isFinite(n)) return n;\n }\n return null;\n}\n\n/** Coerce to an integer clamped ≥ 0 (Rust `.unwrap_or(0).max(0)`). */\nfunction toNonNegInt(v: unknown): number {\n const n = toNum(v);\n if (n === null) return 0;\n return Math.max(0, Math.trunc(n));\n}\n\n/** ceil(chars / 4) — Rust div_ceil estimation (4 chars per token). */\nfunction estimateTokens(chars: number): number {\n return Math.ceil(Math.max(0, chars) / 4);\n}\n\n/** float seconds → epoch ms (Rust seconds_to_millis: truncating). */\nfunction secondsToMillis(seconds: number): number {\n return Math.trunc(seconds * 1000);\n}\n\n/** Strip a single file extension from a basename. */\nfunction stripExt(name: string): string {\n const dot = name.lastIndexOf(\".\");\n return dot > 0 ? name.slice(0, dot) : name;\n}\n\n/**\n * Parse end_timestamp (port of parse_timestamp_value): a number < 1e12 is\n * seconds (→ ms), ≥ 1e12 is already ms; a string is RFC3339, else numeric\n * seconds. Returns null when unusable.\n */\nfunction parseTimestampValue(v: unknown): number | null {\n if (typeof v === \"number\" && Number.isFinite(v)) {\n return Math.abs(v) < 1_000_000_000_000 ? secondsToMillis(v) : Math.trunc(v);\n }\n if (typeof v === \"string\") {\n const ms = Date.parse(v);\n if (!Number.isNaN(ms)) return ms;\n const n = Number(v);\n if (Number.isFinite(n)) return secondsToMillis(n);\n }\n return null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// JSONL transcript → per-message char counts (port of the BufReader loop).\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Sum chars of the \"text\" parts of a content array (kind absent ⇒ text). */\nfunction textCharCount(content: unknown): number {\n if (!Array.isArray(content)) return 0;\n let total = 0;\n for (const part of content) {\n if (typeof part !== \"object\" || part === null) continue;\n const kind = (part as { kind?: unknown }).kind;\n const isText = kind === undefined || kind === null || kind === \"text\";\n if (!isText) continue;\n const data = (part as { data?: unknown }).data;\n if (typeof data === \"string\") total += [...data].length; // chars, not UTF-16 units\n }\n return total;\n}\n\n/**\n * Build message_id → char-count map from the adjacent .jsonl, exactly as the\n * Rust: a \"Prompt\" entry stages a pending (chars, ts); the next\n * \"AssistantMessage\" attaches the staged prompt to that assistant's message_id\n * and adds the assistant's own chars. A missing/empty jsonl yields an empty map.\n */\nfunction readJsonlContent(jsonlPath: string): Map<string, KiroMessageContent> {\n const byId = new Map<string, KiroMessageContent>();\n const lines = readJsonlLines(jsonlPath);\n if (lines.length === 0) return byId;\n\n let pendingPromptChars: number | null = null;\n let pendingPromptTs: number | null = null;\n\n for (const raw of lines) {\n if (typeof raw !== \"object\" || raw === null) continue;\n const entry = raw as { kind?: unknown; data?: unknown };\n const kind = entry.kind;\n const data = entry.data;\n if (typeof data !== \"object\" || data === null) continue;\n\n const messageId = (data as { message_id?: unknown }).message_id;\n if (typeof messageId !== \"string\") continue;\n\n const textChars = textCharCount((data as { content?: unknown }).content);\n\n if (kind === \"Prompt\") {\n const metaTs = (data as { meta?: { timestamp?: unknown } }).meta?.timestamp;\n const tsNum = toNum(metaTs);\n pendingPromptChars = textChars;\n pendingPromptTs = tsNum === null ? null : secondsToMillis(tsNum);\n } else if (kind === \"AssistantMessage\") {\n let msg = byId.get(messageId);\n if (msg === undefined) {\n msg = { promptChars: 0, assistantChars: 0, promptTimestampMs: null };\n byId.set(messageId, msg);\n }\n if (pendingPromptChars !== null) {\n msg.promptChars += pendingPromptChars;\n if (msg.promptTimestampMs === null) msg.promptTimestampMs = pendingPromptTs;\n pendingPromptChars = null;\n pendingPromptTs = null;\n }\n msg.assistantChars += textChars;\n }\n // other kinds are ignored\n }\n return byId;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// One session (.json + adjacent .jsonl) → usage records.\n// ─────────────────────────────────────────────────────────────────────────\n\nfunction parseKiroFile(jsonPath: string): UsageRecord[] {\n const header = readJsonFile(jsonPath);\n if (typeof header !== \"object\" || header === null) return []; // malformed → skip\n const h = header as KiroHeader;\n\n const fallbackTs = fileMtimeMs(jsonPath);\n\n const sessionId =\n typeof h.session_id === \"string\" && h.session_id !== \"\"\n ? h.session_id\n : stripExt(basename(jsonPath)) || \"unknown\";\n\n const modelInfo = h.session_state?.rts_model_state?.model_info;\n const rawModel = modelInfo?.model_id;\n const modelId =\n typeof rawModel === \"string\" && rawModel.trim() !== \"\" ? rawModel : UNKNOWN_MODEL;\n const contextWindow = toNonNegInt(modelInfo?.context_window_tokens);\n\n let projectKey: string | undefined;\n let projectLabel: string | undefined;\n if (typeof h.cwd === \"string\") {\n projectKey = normalizeWorkspaceKey(h.cwd);\n if (projectKey !== undefined) projectLabel = workspaceLabelFromKey(projectKey);\n }\n\n const turnsRaw = h.session_state?.conversation_metadata?.user_turn_metadatas;\n const turns: KiroTurn[] = Array.isArray(turnsRaw) ? (turnsRaw as KiroTurn[]) : [];\n if (turns.length === 0) return [];\n\n // Adjacent .jsonl (same stem) drives char-based estimation.\n const jsonlPath = jsonPath.replace(/\\.json$/, \".jsonl\");\n const contentById = readJsonlContent(jsonlPath);\n\n const out: UsageRecord[] = [];\n\n turns.forEach((turn, index) => {\n if (typeof turn !== \"object\" || turn === null) return;\n\n // Aggregate char counts / first prompt ts over this turn's message_ids.\n let promptChars = 0;\n let assistantChars = 0;\n let promptTimestampMs: number | null = null;\n const messageIds = turn.message_ids;\n if (Array.isArray(messageIds)) {\n for (const mid of messageIds) {\n if (typeof mid !== \"string\") continue;\n const content = contentById.get(mid);\n if (content === undefined) continue;\n promptChars += content.promptChars;\n assistantChars += content.assistantChars;\n if (promptTimestampMs === null) promptTimestampMs = content.promptTimestampMs;\n }\n }\n\n const explicitInput = toNonNegInt(turn.input_token_count);\n const explicitOutput = toNonNegInt(turn.output_token_count);\n\n let input: number;\n let inputEstimated: boolean;\n if (explicitInput > 0) {\n input = explicitInput;\n inputEstimated = false;\n } else {\n inputEstimated = true;\n const ctxPct = toNum(turn.context_usage_percentage) ?? 0;\n if (contextWindow > 0 && ctxPct > 0) {\n input = Math.trunc((contextWindow * ctxPct) / 100);\n } else {\n input = estimateTokens(promptChars);\n }\n }\n\n let output: number;\n let outputEstimated: boolean;\n if (explicitOutput > 0) {\n output = explicitOutput;\n outputEstimated = false;\n } else {\n output = estimateTokens(assistantChars);\n outputEstimated = true;\n }\n\n if (input + output === 0) return; // matches Rust filter_map drop\n\n const endTs = parseTimestampValue(turn.end_timestamp);\n const ts = promptTimestampMs ?? endTs ?? fallbackTs;\n\n const messageCount = Math.max(1, toNonNegInt(turn.total_request_count) || 1);\n\n const tokens = emptyTokens();\n tokens.input = input;\n tokens.output = output;\n // cacheRead / cacheWrite / reasoning stay 0 (Kiro reports none).\n\n // host-reported only when BOTH dimensions are explicit host counts.\n const confidence: UsageConfidence =\n inputEstimated || outputEstimated ? \"host-estimated\" : \"host-reported\";\n\n const record: UsageRecord = {\n platformId: PLATFORM_ID,\n modelId,\n providerId: PROVIDER_ID,\n sessionId,\n tokens,\n ts,\n messageCount,\n dedupKey: `${sessionId}:${index}`,\n confidence,\n };\n if (projectKey !== undefined) record.projectKey = projectKey;\n if (projectLabel !== undefined) record.projectLabel = projectLabel;\n out.push(record);\n });\n\n return out;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Reader singleton.\n// ─────────────────────────────────────────────────────────────────────────\n\nconst kiroReader: 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 ~/.kiro/sessions/cli → fail-open\n\n // Drive off the .json headers; each pulls its adjacent .jsonl when present.\n const files = walkFiles(root, (name) => name.endsWith(\".json\"));\n\n const records: UsageRecord[] = [];\n for (const file of files) {\n const rows = parseKiroFile(file);\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 kiroReader;\n"],"mappings":"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","names":[]}