@codemieai/code 0.11.0 → 0.13.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 (253) hide show
  1. package/README.md +109 -56
  2. package/bin/codemie-copilot.js +224 -0
  3. package/bin/codemie-pi.js +18 -0
  4. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  5. package/dist/agents/core/AgentCLI.js +16 -10
  6. package/dist/agents/core/AgentCLI.js.map +1 -1
  7. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  8. package/dist/agents/core/BaseAgentAdapter.js +43 -19
  9. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  10. package/dist/agents/core/agent-aliases.d.ts +17 -0
  11. package/dist/agents/core/agent-aliases.d.ts.map +1 -0
  12. package/dist/agents/core/agent-aliases.js +41 -0
  13. package/dist/agents/core/agent-aliases.js.map +1 -0
  14. package/dist/agents/core/session/BaseSessionAdapter.d.ts +19 -0
  15. package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
  16. package/dist/agents/core/session/session-origin-audit.d.ts +13 -0
  17. package/dist/agents/core/session/session-origin-audit.d.ts.map +1 -1
  18. package/dist/agents/core/session/session-origin-audit.js +34 -0
  19. package/dist/agents/core/session/session-origin-audit.js.map +1 -1
  20. package/dist/agents/core/session/stale-session-reconciliation.d.ts +42 -0
  21. package/dist/agents/core/session/stale-session-reconciliation.d.ts.map +1 -0
  22. package/dist/agents/core/session/stale-session-reconciliation.js +141 -0
  23. package/dist/agents/core/session/stale-session-reconciliation.js.map +1 -0
  24. package/dist/agents/core/session/types.d.ts +19 -0
  25. package/dist/agents/core/session/types.d.ts.map +1 -1
  26. package/dist/agents/core/session/types.js +17 -1
  27. package/dist/agents/core/session/types.js.map +1 -1
  28. package/dist/agents/core/types.d.ts +11 -0
  29. package/dist/agents/core/types.d.ts.map +1 -1
  30. package/dist/agents/plugins/codex/codex.reconciliation.d.ts +15 -35
  31. package/dist/agents/plugins/codex/codex.reconciliation.d.ts.map +1 -1
  32. package/dist/agents/plugins/codex/codex.reconciliation.js +8 -139
  33. package/dist/agents/plugins/codex/codex.reconciliation.js.map +1 -1
  34. package/dist/agents/plugins/copilot-cli/copilot-cli-event-types.d.ts +146 -0
  35. package/dist/agents/plugins/copilot-cli/copilot-cli-event-types.d.ts.map +1 -0
  36. package/dist/agents/plugins/copilot-cli/copilot-cli-event-types.js +12 -0
  37. package/dist/agents/plugins/copilot-cli/copilot-cli-event-types.js.map +1 -0
  38. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts +15 -0
  39. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.d.ts.map +1 -0
  40. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js +15 -0
  41. package/dist/agents/plugins/copilot-cli/copilot-cli.constants.js.map +1 -0
  42. package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts +8 -0
  43. package/dist/agents/plugins/copilot-cli/copilot-cli.models.d.ts.map +1 -0
  44. package/dist/agents/plugins/copilot-cli/copilot-cli.models.js +195 -0
  45. package/dist/agents/plugins/copilot-cli/copilot-cli.models.js.map +1 -0
  46. package/dist/agents/plugins/copilot-cli/copilot-cli.paths.d.ts +11 -0
  47. package/dist/agents/plugins/copilot-cli/copilot-cli.paths.d.ts.map +1 -0
  48. package/dist/agents/plugins/copilot-cli/copilot-cli.paths.js +21 -0
  49. package/dist/agents/plugins/copilot-cli/copilot-cli.paths.js.map +1 -0
  50. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts +14 -0
  51. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.d.ts.map +1 -0
  52. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js +263 -0
  53. package/dist/agents/plugins/copilot-cli/copilot-cli.plugin.js.map +1 -0
  54. package/dist/agents/plugins/copilot-cli/copilot-cli.session.d.ts +43 -0
  55. package/dist/agents/plugins/copilot-cli/copilot-cli.session.d.ts.map +1 -0
  56. package/dist/agents/plugins/copilot-cli/copilot-cli.session.js +343 -0
  57. package/dist/agents/plugins/copilot-cli/copilot-cli.session.js.map +1 -0
  58. package/dist/agents/plugins/copilot-cli/copilot-cli.storage-utils.d.ts +10 -0
  59. package/dist/agents/plugins/copilot-cli/copilot-cli.storage-utils.d.ts.map +1 -0
  60. package/dist/agents/plugins/copilot-cli/copilot-cli.storage-utils.js +41 -0
  61. package/dist/agents/plugins/copilot-cli/copilot-cli.storage-utils.js.map +1 -0
  62. package/dist/agents/plugins/copilot-cli/copilot-cli.usage.d.ts +37 -0
  63. package/dist/agents/plugins/copilot-cli/copilot-cli.usage.d.ts.map +1 -0
  64. package/dist/agents/plugins/copilot-cli/copilot-cli.usage.js +96 -0
  65. package/dist/agents/plugins/copilot-cli/copilot-cli.usage.js.map +1 -0
  66. package/dist/agents/plugins/copilot-cli/copilot-cli.workspace.d.ts +17 -0
  67. package/dist/agents/plugins/copilot-cli/copilot-cli.workspace.d.ts.map +1 -0
  68. package/dist/agents/plugins/copilot-cli/copilot-cli.workspace.js +58 -0
  69. package/dist/agents/plugins/copilot-cli/copilot-cli.workspace.js.map +1 -0
  70. package/dist/agents/plugins/copilot-cli/index.d.ts +3 -0
  71. package/dist/agents/plugins/copilot-cli/index.d.ts.map +1 -0
  72. package/dist/agents/plugins/copilot-cli/index.js +3 -0
  73. package/dist/agents/plugins/copilot-cli/index.js.map +1 -0
  74. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts +18 -0
  75. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.d.ts.map +1 -0
  76. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js +313 -0
  77. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.conversations-processor.js.map +1 -0
  78. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.metrics-processor.d.ts +16 -0
  79. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.metrics-processor.d.ts.map +1 -0
  80. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.metrics-processor.js +22 -0
  81. package/dist/agents/plugins/copilot-cli/session/processors/copilot-cli.metrics-processor.js.map +1 -0
  82. package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts +12 -0
  83. package/dist/agents/plugins/pi/__tests__/home-redirect.d.ts.map +1 -0
  84. package/dist/agents/plugins/pi/__tests__/home-redirect.js +27 -0
  85. package/dist/agents/plugins/pi/__tests__/home-redirect.js.map +1 -0
  86. package/dist/agents/plugins/pi/extension/README.md +68 -0
  87. package/dist/agents/plugins/pi/extension/index.js +161 -0
  88. package/dist/agents/plugins/pi/extension/package.json +8 -0
  89. package/dist/agents/plugins/pi/index.d.ts +3 -0
  90. package/dist/agents/plugins/pi/index.d.ts.map +1 -0
  91. package/dist/agents/plugins/pi/index.js +3 -0
  92. package/dist/agents/plugins/pi/index.js.map +1 -0
  93. package/dist/agents/plugins/pi/pi.extension.d.ts +60 -0
  94. package/dist/agents/plugins/pi/pi.extension.d.ts.map +1 -0
  95. package/dist/agents/plugins/pi/pi.extension.js +201 -0
  96. package/dist/agents/plugins/pi/pi.extension.js.map +1 -0
  97. package/dist/agents/plugins/pi/pi.incremental-sync.d.ts +63 -0
  98. package/dist/agents/plugins/pi/pi.incremental-sync.d.ts.map +1 -0
  99. package/dist/agents/plugins/pi/pi.incremental-sync.js +266 -0
  100. package/dist/agents/plugins/pi/pi.incremental-sync.js.map +1 -0
  101. package/dist/agents/plugins/pi/pi.models.d.ts +20 -0
  102. package/dist/agents/plugins/pi/pi.models.d.ts.map +1 -0
  103. package/dist/agents/plugins/pi/pi.models.js +201 -0
  104. package/dist/agents/plugins/pi/pi.models.js.map +1 -0
  105. package/dist/agents/plugins/pi/pi.packages.d.ts +11 -0
  106. package/dist/agents/plugins/pi/pi.packages.d.ts.map +1 -0
  107. package/dist/agents/plugins/pi/pi.packages.js +35 -0
  108. package/dist/agents/plugins/pi/pi.packages.js.map +1 -0
  109. package/dist/agents/plugins/pi/pi.paths.d.ts +37 -0
  110. package/dist/agents/plugins/pi/pi.paths.d.ts.map +1 -0
  111. package/dist/agents/plugins/pi/pi.paths.js +146 -0
  112. package/dist/agents/plugins/pi/pi.paths.js.map +1 -0
  113. package/dist/agents/plugins/pi/pi.plugin.d.ts +30 -0
  114. package/dist/agents/plugins/pi/pi.plugin.d.ts.map +1 -0
  115. package/dist/agents/plugins/pi/pi.plugin.js +453 -0
  116. package/dist/agents/plugins/pi/pi.plugin.js.map +1 -0
  117. package/dist/agents/plugins/pi/pi.session.d.ts +114 -0
  118. package/dist/agents/plugins/pi/pi.session.d.ts.map +1 -0
  119. package/dist/agents/plugins/pi/pi.session.js +388 -0
  120. package/dist/agents/plugins/pi/pi.session.js.map +1 -0
  121. package/dist/agents/plugins/pi/pi.setup.d.ts +2 -0
  122. package/dist/agents/plugins/pi/pi.setup.d.ts.map +1 -0
  123. package/dist/agents/plugins/pi/pi.setup.js +33 -0
  124. package/dist/agents/plugins/pi/pi.setup.js.map +1 -0
  125. package/dist/agents/plugins/pi/pi.types.d.ts +143 -0
  126. package/dist/agents/plugins/pi/pi.types.d.ts.map +1 -0
  127. package/dist/agents/plugins/pi/pi.types.js +74 -0
  128. package/dist/agents/plugins/pi/pi.types.js.map +1 -0
  129. package/dist/agents/plugins/pi/session/pi-file-operations.d.ts +17 -0
  130. package/dist/agents/plugins/pi/session/pi-file-operations.d.ts.map +1 -0
  131. package/dist/agents/plugins/pi/session/pi-file-operations.js +98 -0
  132. package/dist/agents/plugins/pi/session/pi-file-operations.js.map +1 -0
  133. package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts +52 -0
  134. package/dist/agents/plugins/pi/session/pi-named-invocations.d.ts.map +1 -0
  135. package/dist/agents/plugins/pi/session/pi-named-invocations.js +189 -0
  136. package/dist/agents/plugins/pi/session/pi-named-invocations.js.map +1 -0
  137. package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts +14 -0
  138. package/dist/agents/plugins/pi/session/pi-user-prompt.d.ts.map +1 -0
  139. package/dist/agents/plugins/pi/session/pi-user-prompt.js +51 -0
  140. package/dist/agents/plugins/pi/session/pi-user-prompt.js.map +1 -0
  141. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts +52 -0
  142. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.d.ts.map +1 -0
  143. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js +716 -0
  144. package/dist/agents/plugins/pi/session/processors/pi.conversations-processor.js.map +1 -0
  145. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts +104 -0
  146. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.d.ts.map +1 -0
  147. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js +595 -0
  148. package/dist/agents/plugins/pi/session/processors/pi.metrics-processor.js.map +1 -0
  149. package/dist/agents/registry.d.ts +20 -0
  150. package/dist/agents/registry.d.ts.map +1 -1
  151. package/dist/agents/registry.js +29 -2
  152. package/dist/agents/registry.js.map +1 -1
  153. package/dist/cli/commands/analytics/agent-labels.d.ts +3 -0
  154. package/dist/cli/commands/analytics/agent-labels.d.ts.map +1 -0
  155. package/dist/cli/commands/analytics/agent-labels.js +20 -0
  156. package/dist/cli/commands/analytics/agent-labels.js.map +1 -0
  157. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
  158. package/dist/cli/commands/analytics/cost/cost-enricher.js +12 -0
  159. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  160. package/dist/cli/commands/analytics/cost/types.d.ts +10 -0
  161. package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
  162. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +24 -0
  163. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  164. package/dist/cli/commands/analytics/cost/usage-readers.js +253 -54
  165. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  166. package/dist/cli/commands/analytics/formatter.d.ts.map +1 -1
  167. package/dist/cli/commands/analytics/formatter.js +10 -2
  168. package/dist/cli/commands/analytics/formatter.js.map +1 -1
  169. package/dist/cli/commands/analytics/index.d.ts.map +1 -1
  170. package/dist/cli/commands/analytics/index.js +22 -0
  171. package/dist/cli/commands/analytics/index.js.map +1 -1
  172. package/dist/cli/commands/analytics/native-loader.d.ts +21 -4
  173. package/dist/cli/commands/analytics/native-loader.d.ts.map +1 -1
  174. package/dist/cli/commands/analytics/native-loader.js +267 -88
  175. package/dist/cli/commands/analytics/native-loader.js.map +1 -1
  176. package/dist/cli/commands/analytics/report/client/app.js +77 -15
  177. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  178. package/dist/cli/commands/analytics/report/payload-builder.js +32 -2
  179. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  180. package/dist/cli/commands/analytics/report/types.d.ts +11 -0
  181. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  182. package/dist/cli/commands/hook.d.ts.map +1 -1
  183. package/dist/cli/commands/hook.js +71 -29
  184. package/dist/cli/commands/hook.js.map +1 -1
  185. package/dist/cli/commands/install.d.ts.map +1 -1
  186. package/dist/cli/commands/install.js +9 -7
  187. package/dist/cli/commands/install.js.map +1 -1
  188. package/dist/cli/commands/list.d.ts.map +1 -1
  189. package/dist/cli/commands/list.js +4 -2
  190. package/dist/cli/commands/list.js.map +1 -1
  191. package/dist/cli/commands/setup.d.ts +3 -1
  192. package/dist/cli/commands/setup.d.ts.map +1 -1
  193. package/dist/cli/commands/setup.js +87 -63
  194. package/dist/cli/commands/setup.js.map +1 -1
  195. package/dist/cli/commands/uninstall.d.ts.map +1 -1
  196. package/dist/cli/commands/uninstall.js +6 -4
  197. package/dist/cli/commands/uninstall.js.map +1 -1
  198. package/dist/cli/commands/update.d.ts.map +1 -1
  199. package/dist/cli/commands/update.js +7 -5
  200. package/dist/cli/commands/update.js.map +1 -1
  201. package/dist/cli/first-time.d.ts.map +1 -1
  202. package/dist/cli/first-time.js +10 -9
  203. package/dist/cli/first-time.js.map +1 -1
  204. package/dist/providers/core/auth-validation.d.ts +7 -2
  205. package/dist/providers/core/auth-validation.d.ts.map +1 -1
  206. package/dist/providers/core/auth-validation.js +11 -5
  207. package/dist/providers/core/auth-validation.js.map +1 -1
  208. package/dist/providers/core/types.d.ts +16 -0
  209. package/dist/providers/core/types.d.ts.map +1 -1
  210. package/dist/providers/core/types.js.map +1 -1
  211. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts +8 -3
  212. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.d.ts.map +1 -1
  213. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js +46 -11
  214. package/dist/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.js.map +1 -1
  215. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts +23 -13
  216. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.d.ts.map +1 -1
  217. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js +75 -18
  218. package/dist/providers/plugins/sso/proxy/plugins/codex-encrypted-content-sanitizer.plugin.js.map +1 -1
  219. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts +21 -0
  220. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.d.ts.map +1 -0
  221. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js +133 -0
  222. package/dist/providers/plugins/sso/proxy/plugins/copilot-encrypted-content-sanitizer.plugin.js.map +1 -0
  223. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js +1 -1
  224. package/dist/providers/plugins/sso/proxy/plugins/header-injection.plugin.js.map +1 -1
  225. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +2 -1
  226. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  227. package/dist/providers/plugins/sso/proxy/plugins/index.js +4 -2
  228. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  229. package/dist/providers/plugins/sso/proxy/plugins/types.d.ts +11 -0
  230. package/dist/providers/plugins/sso/proxy/plugins/types.d.ts.map +1 -1
  231. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts +2 -0
  232. package/dist/providers/plugins/sso/proxy/sso.proxy.d.ts.map +1 -1
  233. package/dist/providers/plugins/sso/proxy/sso.proxy.js +37 -1
  234. package/dist/providers/plugins/sso/proxy/sso.proxy.js.map +1 -1
  235. package/dist/providers/plugins/sso/session/SessionSyncer.d.ts.map +1 -1
  236. package/dist/providers/plugins/sso/session/SessionSyncer.js +13 -0
  237. package/dist/providers/plugins/sso/session/SessionSyncer.js.map +1 -1
  238. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js +6 -0
  239. package/dist/providers/plugins/sso/session/processors/conversations/syncProcessor.js.map +1 -1
  240. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts +0 -6
  241. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.d.ts.map +1 -1
  242. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js +28 -19
  243. package/dist/providers/plugins/sso/session/processors/metrics/metrics-post-processor.js.map +1 -1
  244. package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -1
  245. package/dist/providers/plugins/sso/sso.setup-steps.js +39 -22
  246. package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
  247. package/dist/utils/interactive.d.ts +14 -0
  248. package/dist/utils/interactive.d.ts.map +1 -0
  249. package/dist/utils/interactive.js +16 -0
  250. package/dist/utils/interactive.js.map +1 -0
  251. package/package.json +6 -5
  252. package/scripts/copy-plugins.js +6 -0
  253. package/scripts/release.sh +54 -0
@@ -19,7 +19,7 @@
19
19
 
20
20
  // ---- palette ------------------------------------------------------------
21
21
  var PALETTE = ['#7C5CFC', '#2297F6', '#F5A534', '#06B6D4', '#259F4C', '#F9303C', '#C084FC', '#E879A6'];
22
- var AGENT_COLORS = { claude: '#7C5CFC', 'claude-acp': '#9D7BFF', 'claude-desktop': '#B79DFF', gemini: '#F5A534', codex: '#06B6D4', 'codemie-codex': '#06B6D4', opencode: '#259F4C', 'codemie-code': '#2297F6' };
22
+ var AGENT_COLORS = { claude: '#7C5CFC', 'claude-acp': '#9D7BFF', 'claude-desktop': '#B79DFF', gemini: '#F5A534', codex: '#06B6D4', 'codemie-codex': '#06B6D4', opencode: '#259F4C', 'codemie-code': '#2297F6', 'copilot-cli': '#6E7681', pi: '#E879A6' };
23
23
  var seenAgentColor = {};
24
24
  var colorCursor = 0;
25
25
  function colorFor(agent) {
@@ -27,6 +27,10 @@
27
27
  if (!seenAgentColor[agent]) { seenAgentColor[agent] = PALETTE[colorCursor % PALETTE.length]; colorCursor++; }
28
28
  return seenAgentColor[agent];
29
29
  }
30
+ // Agent keys are internal ids; these are what a human should read. Unmapped agents fall
31
+ // through to the key itself, so listing an agent here is optional.
32
+ var AGENT_LABELS = { 'copilot-cli': 'GitHub Copilot CLI', pi: 'Pi' };
33
+ function labelFor(agent) { return AGENT_LABELS[agent] || agent; }
30
34
 
31
35
  // ---- formatting ---------------------------------------------------------
32
36
  function fmtNum(n) { return (n || 0).toLocaleString('en-US'); }
@@ -393,7 +397,7 @@
393
397
  agentList.forEach(function (a) {
394
398
  var ss = byAgent.get(a);
395
399
  var c = el('div', 'acard'); c.style.setProperty('--ac', colorFor(a));
396
- c.appendChild(el('h3', null, '<span class="pill"></span>' + esc(a)));
400
+ c.appendChild(el('h3', null, '<span class="pill"></span>' + esc(labelFor(a))));
397
401
  c.appendChild(el('span', 'text-muted', '<span style="font-size:12px">' + ss.length + ' sessions · ' + Math.round((ss.length / fs.length) * 100) + '% of activity</span>'));
398
402
  var mini = el('div', 'mini');
399
403
  var stats = [
@@ -440,7 +444,9 @@
440
444
  agentList.map(function (a) {
441
445
  var ss = byAgent.get(a);
442
446
  var topModel = topOf(ss.flatMap(function (s) { return s.models; }));
443
- return ['<span class="tag tag-sm" style="text-transform:capitalize">' + esc(a) + '</span>', fmtNum(ss.length), tdNum(sum(ss, function (s) { return s.turns; })), tdNum(sum(ss, function (s) { return s.fileOps; })), tdNum(sum(ss, function (s) { return s.netLines; })), '<span class="tag tag-sm">' + esc(topModel || '—') + '</span>', tdNum(successRate(ss) + '%'), tdNum(fmtUSD(sum(ss, function (s) { return s.costUSD; })))];
447
+ // No text-transform: it would render a mapped label as "Github Copilot Cli".
448
+ // Unmapped keys keep their original look via the capitalize fallback below.
449
+ return ['<span class="tag tag-sm"' + (AGENT_LABELS[a] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(a)) + '</span>', fmtNum(ss.length), tdNum(sum(ss, function (s) { return s.turns; })), tdNum(sum(ss, function (s) { return s.fileOps; })), tdNum(sum(ss, function (s) { return s.netLines; })), '<span class="tag tag-sm">' + esc(topModel || '—') + '</span>', tdNum(successRate(ss) + '%'), tdNum(fmtUSD(sum(ss, function (s) { return s.costUSD; })))];
444
450
  }),
445
451
  [false, true, true, true, true, false, true, true]);
446
452
  host.appendChild(detail);
@@ -604,7 +610,7 @@
604
610
  bloated.map(function (x) {
605
611
  var s = x.s;
606
612
  return ['<span title="' + esc(sessTitle(s)) + '">' + esc(truncStr(sessTitle(s), 44)) + '</span>',
607
- '<span class="tag tag-sm" style="text-transform:capitalize">' + esc(s.agentName) + '</span>',
613
+ '<span class="tag tag-sm"' + (AGENT_LABELS[s.agentName] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(s.agentName)) + '</span>',
608
614
  '<span class="tag tag-sm">' + esc((s.models && s.models[0]) || '—') + '</span>',
609
615
  fmtTokens(Math.round(x.ctx)), fmtTokens(s.tokens ? s.tokens.cacheRead : 0), fmtUSD(s.costUSD), (Math.round(x.bloat * 10) / 10) + '%'];
610
616
  }),
@@ -635,7 +641,7 @@
635
641
  dw.innerHTML = tableHTML(['Session', 'Agent', 'Model', 'Turns', 'Cost'],
636
642
  topDead.map(function (s) {
637
643
  return ['<span title="' + esc(sessTitle(s)) + '">' + esc(truncStr(sessTitle(s), 44)) + '</span>',
638
- '<span class="tag tag-sm" style="text-transform:capitalize">' + esc(s.agentName) + '</span>',
644
+ '<span class="tag tag-sm"' + (AGENT_LABELS[s.agentName] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(s.agentName)) + '</span>',
639
645
  '<span class="tag tag-sm">' + esc((s.models && s.models[0]) || '—') + '</span>',
640
646
  fmtNum(s.turns), fmtUSD(s.costUSD)];
641
647
  }), [false, false, false, true, true]);
@@ -738,7 +744,7 @@
738
744
  else if (c.withLog === 0) status = '<span class="cov-warn">no native log</span>';
739
745
  else if (c.priced === 0) status = '<span class="cov-warn">no token reader</span>';
740
746
  else status = '<span class="cov-warn">partial</span>';
741
- return ['<span class="tag tag-sm" style="text-transform:capitalize">' + esc(c.agentName) + '</span>',
747
+ return ['<span class="tag tag-sm"' + (AGENT_LABELS[c.agentName] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(c.agentName)) + '</span>',
742
748
  fmtNum(c.total), c.priced + '/' + c.total, fmtNum(c.withLog), status];
743
749
  }),
744
750
  [false, true, true, true, false]) + '</div>';
@@ -775,7 +781,7 @@
775
781
  ['Session', 'Agent', 'Project', 'Input', 'Output', 'Cached', 'Total', 'Cost'],
776
782
  top.map(function (s) {
777
783
  return [esc(s.sessionId.slice(0, 8)),
778
- '<span class="tag tag-sm" style="text-transform:capitalize">' + esc(s.agentName) + '</span>',
784
+ '<span class="tag tag-sm"' + (AGENT_LABELS[s.agentName] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(s.agentName)) + '</span>',
779
785
  '<span title="' + esc(s.project) + '">' + esc(shortPath(s.project)) + '</span>',
780
786
  fmtTokens(tkIn(s)), fmtTokens(tkOut(s)), fmtTokens(tkCached(s)), fmtTokens(s.tokens ? s.tokens.total : 0), fmtUSD(s.costUSD)];
781
787
  }),
@@ -802,7 +808,7 @@
802
808
  var list = fs.slice().sort(function (a, b) { return b.startTime - a.startTime; });
803
809
  if (q) {
804
810
  var ql = q.toLowerCase();
805
- list = list.filter(function (s) { return (s.sessionId + ' ' + s.agentName + ' ' + s.project + ' ' + s.branch + ' ' + (s.title || '') + ' ' + (s.sessionSource || '')).toLowerCase().indexOf(ql) >= 0; });
811
+ list = list.filter(function (s) { return (s.sessionId + ' ' + s.agentName + ' ' + labelFor(s.agentName) + ' ' + s.project + ' ' + s.branch + ' ' + (s.title || '') + ' ' + (s.sessionSource || '')).toLowerCase().indexOf(ql) >= 0; });
806
812
  }
807
813
  var shown = list.slice(0, 300);
808
814
  holder.innerHTML = tableHTML(
@@ -813,7 +819,7 @@
813
819
  var sourceCell = '<span class="tag tag-sm">' + esc(s.sessionSource || 'Pure chat') + '</span>';
814
820
  return [new Date(s.startTime).toISOString().slice(0, 16).replace('T', ' '),
815
821
  promptCell,
816
- '<span class="tag tag-sm" style="text-transform:capitalize">' + esc(s.agentName) + '</span>',
822
+ '<span class="tag tag-sm"' + (AGENT_LABELS[s.agentName] ? '' : ' style="text-transform:capitalize"') + '>' + esc(labelFor(s.agentName)) + '</span>',
817
823
  '<span title="' + esc(s.project) + '">' + esc(shortPath(s.project)) + '</span>', branchCell, sourceCell,
818
824
  fmtNum(s.turns), fmtNum(s.netLines), fmtTokens(tkIn(s)), fmtTokens(tkOut(s)), fmtTokens(tkCached(s)), fmtUSD(s.costUSD)];
819
825
  }),
@@ -1030,6 +1036,50 @@
1030
1036
  container.appendChild(sidePane);
1031
1037
  return container;
1032
1038
  }
1039
+ /**
1040
+ * Rebuild a single-session ReportPayload matching what
1041
+ * `codemie analytics --report --report-format json --session <id>` writes:
1042
+ * { meta, sessions: [record] }, with meta.totals/coverage scoped to this one session
1043
+ * and userEmail / periodStart / periodEnd populated. Mirrors buildPayload()'s meta
1044
+ * assembly (see report/payload-builder.ts) so the exported file is drop-in comparable.
1045
+ */
1046
+ function sessionPayload(s) {
1047
+ var perModel = s.perModelCost || [];
1048
+ var priced = perModel.length > 0;
1049
+ var unpricedModels = [];
1050
+ perModel.forEach(function (m) {
1051
+ if (m.unpriced && unpricedModels.indexOf(m.model) === -1) unpricedModels.push(m.model);
1052
+ });
1053
+ var meta = {
1054
+ generatedAt: new Date().toISOString(),
1055
+ // --session applies no date filter, so the CLI stamps 'all' / 'all' here too.
1056
+ rangeLabel: 'all',
1057
+ agents: [s.agentName],
1058
+ projectFilter: 'all',
1059
+ totals: {
1060
+ sessions: 1,
1061
+ durationMs: s.durationMs,
1062
+ turns: s.turns,
1063
+ files: s.fileOps,
1064
+ netLines: s.netLines,
1065
+ toolCallsTotal: s.toolCallsTotal,
1066
+ toolSuccessRate: s.toolCallsTotal ? Math.round((s.toolCallsSuccess / s.toolCallsTotal) * 1000) / 10 : 0,
1067
+ totalCostUSD: s.costUSD,
1068
+ cacheReadCostUSD: s.cacheReadCostUSD,
1069
+ pricedSessions: priced ? 1 : 0
1070
+ },
1071
+ unpricedModels: unpricedModels,
1072
+ coverage: [{ agentName: s.agentName, total: 1, priced: priced ? 1 : 0, withLog: s.hadLog ? 1 : 0 }]
1073
+ };
1074
+ // Same conditional-spread semantics as buildPayload: omit rather than emit null.
1075
+ if (DATA.meta && DATA.meta.userEmail !== undefined) meta.userEmail = DATA.meta.userEmail;
1076
+ if (Number.isFinite(s.startTime) && s.startTime > 0) {
1077
+ meta.periodStart = new Date(s.startTime).toISOString();
1078
+ meta.periodEnd = new Date(s.startTime + Math.max(Number.isFinite(s.durationMs) ? s.durationMs : 0, 0)).toISOString();
1079
+ }
1080
+ return { meta: meta, sessions: [s] };
1081
+ }
1082
+
1033
1083
  function openSessionModal(s, onBack) {
1034
1084
  if (!s) return;
1035
1085
  closeSessionModal();
@@ -1048,7 +1098,7 @@
1048
1098
  htxt.appendChild(back);
1049
1099
  }
1050
1100
  htxt.appendChild(el('div', 'modal-title', esc(truncStr(firstWords(sessTitle(s), 10), 120))));
1051
- var metaBits = [s.agentName, (s.models && s.models[0]) || null, shortPath(s.project), s.branch].filter(Boolean);
1101
+ var metaBits = [labelFor(s.agentName), (s.models && s.models[0]) || null, shortPath(s.project), s.branch].filter(Boolean);
1052
1102
  htxt.appendChild(el('div', 'modal-meta', metaBits.map(function (b) { return esc(b); }).join(' · ')));
1053
1103
  head.appendChild(htxt);
1054
1104
  var headBtns = el('div'); headBtns.style.cssText = 'display:flex;gap:6px;align-items:center;flex-shrink:0;';
@@ -1056,7 +1106,7 @@
1056
1106
  exportBtn.setAttribute('aria-label', 'Export session as JSON');
1057
1107
  exportBtn.setAttribute('title', 'Export session details as JSON');
1058
1108
  exportBtn.addEventListener('click', function () {
1059
- var json = JSON.stringify(s, null, 2);
1109
+ var json = JSON.stringify(sessionPayload(s), null, 2);
1060
1110
  var blob = new Blob([json], { type: 'application/json' });
1061
1111
  var url = URL.createObjectURL(blob);
1062
1112
  var a = document.createElement('a');
@@ -1076,12 +1126,24 @@
1076
1126
  // Cost & Time / Token Usage / Activity — light borderless stats, equal-height cards.
1077
1127
  var t = s.tokens || { input: 0, output: 0, cacheRead: 0, cacheCreation: 0, total: 0 };
1078
1128
  var grid3 = el('div', 'grid-3');
1079
- var costCard = card('Cost & Time'); costCard._body.appendChild(statsEl([
1080
- ['Cost', fmtUSD(s.costUSD), 'API-equivalent'],
1129
+ // Usage provenance (optional, present only for agents that report it — e.g. Copilot CLI,
1130
+ // which bills in premium requests rather than tokens, and whose older CLI versions
1131
+ // recorded no telemetry at all). Appended so other agents' cards are unchanged.
1132
+ var costRows = [
1133
+ ['Cost', s.usageUnavailableReason ? '—' : fmtUSD(s.costUSD), s.usageUnavailableReason ? 'not measurable' : 'API-equivalent'],
1081
1134
  ['Cache-read', s.cacheReadCostUSD ? fmtUSD(s.cacheReadCostUSD) : '—', ''],
1082
1135
  ['Duration', fmtDuration(s.durationMs || 0), ''],
1083
1136
  ['Started', '<span class="mval-sm">' + esc(fmtWhen(s.startTime)) + '</span>', '']
1084
- ]));
1137
+ ];
1138
+ if (s.premiumRequests !== undefined) {
1139
+ costRows.push(['Premium requests', fmtNum(s.premiumRequests), 'provider billing unit']);
1140
+ }
1141
+ var costCard = card('Cost & Time'); costCard._body.appendChild(statsEl(costRows));
1142
+ if (s.usageUnavailableReason) {
1143
+ costCard._body.appendChild(el('div', 'text-muted', '<span style="font-size:12px">' + esc(s.usageUnavailableReason) + '</span>'));
1144
+ } else if (s.usagePartial) {
1145
+ costCard._body.appendChild(el('div', 'text-muted', '<span style="font-size:12px">Partial usage — output tokens only; this session recorded no full rollup, so cost is understated.</span>'));
1146
+ }
1085
1147
  var tokCard = card('Token usage'); tokCard._body.appendChild(statsEl([
1086
1148
  ['Input', fmtTokens(t.input), ''], ['Output', fmtTokens(t.output), ''],
1087
1149
  ['Cache read', fmtTokens(t.cacheRead), ''], ['Cache create', fmtTokens(t.cacheCreation), ''],
@@ -1300,7 +1362,7 @@
1300
1362
  var chips = document.getElementById('agent-chips');
1301
1363
  DATA.meta.agents.forEach(function (a) {
1302
1364
  var chip = el('span', 'chip-tog');
1303
- chip.innerHTML = '<span class="dot" style="background:' + colorFor(a) + '"></span>' + esc(a);
1365
+ chip.innerHTML = '<span class="dot" style="background:' + colorFor(a) + '"></span>' + esc(labelFor(a));
1304
1366
  chip.addEventListener('click', function () {
1305
1367
  if (state.agents.has(a)) { state.agents.delete(a); chip.classList.add('off'); }
1306
1368
  else { state.agents.add(a); chip.classList.remove('off'); }
@@ -1 +1 @@
1
- {"version":3,"file":"payload-builder.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/payload-builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAiB,MAAM,kBAAkB,CAAC;AAErF,OAAO,KAAK,EAAE,aAAa,EAAmC,MAAM,YAAY,CAAC;AAGjF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,cAAc,GAClB,aAAa,CA2Hf"}
1
+ {"version":3,"file":"payload-builder.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/payload-builder.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAiB,MAAM,kBAAkB,CAAC;AAErF,OAAO,KAAK,EAAE,aAAa,EAAmC,MAAM,YAAY,CAAC;AAGjF,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,cAAc,GAClB,aAAa,CAyJf"}
@@ -15,6 +15,10 @@ export function buildPayload(root, costIndex, summary, ctx) {
15
15
  // the full (duplicated) session metrics. Dedupe by sessionId so the flat record
16
16
  // list — the single source of truth for the client — counts each session once.
17
17
  const seen = new Set();
18
+ // Track earliest/latest activity across included sessions so the meta block can
19
+ // fall back to derived period when the caller did not stamp explicit dates.
20
+ let minStartMs;
21
+ let maxEndMs;
18
22
  for (const project of root.projects) {
19
23
  for (const branch of project.branches) {
20
24
  for (const s of branch.sessions) {
@@ -22,6 +26,16 @@ export function buildPayload(root, costIndex, summary, ctx) {
22
26
  continue;
23
27
  }
24
28
  seen.add(s.sessionId);
29
+ if (Number.isFinite(s.startTime) && s.startTime > 0) {
30
+ if (minStartMs === undefined || s.startTime < minStartMs) {
31
+ minStartMs = s.startTime;
32
+ }
33
+ const dur = Number.isFinite(s.duration) ? Math.max(s.duration, 0) : 0;
34
+ const endMs = s.startTime + dur;
35
+ if (maxEndMs === undefined || endMs > maxEndMs) {
36
+ maxEndMs = endMs;
37
+ }
38
+ }
25
39
  const cost = costIndex.get(s.sessionId);
26
40
  agents.add(s.agentName);
27
41
  const skillInvocations = s.skillInvocations ?? [];
@@ -66,6 +80,14 @@ export function buildPayload(root, costIndex, summary, ctx) {
66
80
  costUSD: cost?.costUSD ?? 0,
67
81
  cacheReadCostUSD: cost?.cacheReadCostUSD ?? 0,
68
82
  perModelCost: cost?.perModel ?? [],
83
+ hadLog: cost?.hadLog ?? false,
84
+ // Optional and additive — omitted entirely for agents that record full usage,
85
+ // so no other agent's record changes shape.
86
+ ...(cost?.premiumRequests !== undefined ? { premiumRequests: cost.premiumRequests } : {}),
87
+ ...(cost?.usagePartial ? { usagePartial: true } : {}),
88
+ ...(cost?.usageUnavailableReason
89
+ ? { usageUnavailableReason: cost.usageUnavailableReason }
90
+ : {}),
69
91
  ...(cost?.costSeries && cost.costSeries.length ? { costSeries: cost.costSeries } : {}),
70
92
  ...(cost?.dispatches && cost.dispatches.length ? { dispatches: cost.dispatches } : {}),
71
93
  skillInvocations,
@@ -120,8 +142,16 @@ export function buildPayload(root, costIndex, summary, ctx) {
120
142
  unpricedModels: summary.unpricedModels,
121
143
  coverage: [...coverageMap.values()].sort((a, b) => b.total - a.total),
122
144
  ...(ctx.userEmail !== undefined && { userEmail: ctx.userEmail }),
123
- ...(ctx.periodStart !== undefined && { periodStart: ctx.periodStart }),
124
- ...(ctx.periodEnd !== undefined && { periodEnd: ctx.periodEnd }),
145
+ ...(ctx.periodStart !== undefined
146
+ ? { periodStart: ctx.periodStart }
147
+ : minStartMs !== undefined
148
+ ? { periodStart: new Date(minStartMs).toISOString() }
149
+ : {}),
150
+ ...(ctx.periodEnd !== undefined
151
+ ? { periodEnd: ctx.periodEnd }
152
+ : maxEndMs !== undefined
153
+ ? { periodEnd: new Date(maxEndMs).toISOString() }
154
+ : {}),
125
155
  };
126
156
  return { meta, sessions };
127
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"payload-builder.js","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/payload-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"payload-builder.js","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/payload-builder.ts"],"names":[],"mappings":"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"}
@@ -38,8 +38,19 @@ export interface ReportSessionRecord {
38
38
  costUSD: number;
39
39
  cacheReadCostUSD: number;
40
40
  perModelCost: ModelCost[];
41
+ hadLog: boolean;
41
42
  costSeries?: CostSeriesPoint[];
42
43
  dispatches?: DispatchEvent[];
44
+ /**
45
+ * The provider's own billing unit, when it differs from tokens. Currently only GitHub
46
+ * Copilot CLI ("premium requests") — `costUSD` there is a token-derived estimate for
47
+ * cross-agent comparison, not GitHub's invoice.
48
+ */
49
+ premiumRequests?: number;
50
+ /** True when usage was reconstructed from partial data and understates actual use. */
51
+ usagePartial?: boolean;
52
+ /** Why this session shows no tokens or cost; absent when priced. */
53
+ usageUnavailableReason?: string;
43
54
  }
44
55
  export interface ReportMeta {
45
56
  generatedAt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;IAC3C,qGAAqG;IACrG,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/cli/commands/analytics/report/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7G,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnE,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;IACzC,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;IAC3C,qGAAqG;IACrG,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,SAAS,EAAE,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAG7B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sFAAsF;IACtF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,CAAC;QACxB,YAAY,EAAE,MAAM,CAAC;QACrB,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EAAE,aAAa,EAA4D,MAAM,wBAAwB,CAAC;AAGtH;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,eAAe,EAAE,cAAc,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,eAAe,EAAE,YAAY,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,eAAe,EAAE,cAAc,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmsCD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAkG3C"}
1
+ {"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,OAAO,KAAK,EAAE,aAAa,EAA4D,MAAM,wBAAwB,CAAC;AAGtH;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,eAAe,EAAE,cAAc,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,eAAe,EAAE,YAAY,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,eAAe,EAAE,cAAc,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mBAAmB;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAmvCD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoBrG;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAkG3C"}
@@ -2,6 +2,7 @@ import { Command } from 'commander';
2
2
  import { logger } from '../../utils/logger.js';
3
3
  import { AgentRegistry } from '../../agents/registry.js';
4
4
  import { getSessionPath, getSessionMetricsPath, getSessionConversationPath } from '../../agents/core/session/session-config.js';
5
+ import { SESSION_ORIGIN, SESSION_ORIGIN_ENV_KEY } from '../../agents/core/session/types.js';
5
6
  /**
6
7
  * Read JSON from stdin
7
8
  */
@@ -201,13 +202,19 @@ async function performIncrementalSync(event, hookName, sessionId, config) {
201
202
  logger.warn(`[hook:${hookName}] Missing CODEMIE_AGENT, skipping extraction`);
202
203
  return;
203
204
  }
204
- // Use transcript_path directly from event
205
- const agentSessionFile = event.transcript_path;
206
- if (!agentSessionFile) {
205
+ // Agents may provide a single transcript path or a list of paths (e.g. Pi's
206
+ // /new and /fork operations switch to a new file in the same run). Process
207
+ // every path so metrics are not lost.
208
+ const agentSessionFiles = event.transcript_paths?.length
209
+ ? event.transcript_paths
210
+ : event.transcript_path
211
+ ? [event.transcript_path]
212
+ : [];
213
+ if (agentSessionFiles.length === 0) {
207
214
  logger.warn(`[hook:${hookName}] No transcript_path in event, skipping incremental sync`);
208
215
  return;
209
216
  }
210
- logger.debug(`[hook:${hookName}] Using transcript: ${agentSessionFile}`);
217
+ logger.debug(`[hook:${hookName}] Using transcript(s): ${agentSessionFiles.join(', ')}`);
211
218
  // Get agent from registry
212
219
  const agent = AgentRegistry.getAgent(agentName);
213
220
  if (!agent) {
@@ -226,25 +233,27 @@ async function performIncrementalSync(event, hookName, sessionId, config) {
226
233
  logger.warn(`[hook:${hookName}] No session adapter available for agent ${agentName}`);
227
234
  return;
228
235
  }
229
- // Build processing context
230
- const context = await buildProcessingContext(sessionId, event.session_id, agentSessionFile, config);
231
- // Process session with all processors (metrics + conversations)
232
- logger.debug(`[hook:${hookName}] Calling SessionAdapter.processSession()`);
233
- const result = await sessionAdapter.processSession(agentSessionFile, sessionId, context);
234
- if (result.success) {
235
- logger.info(`[hook:${hookName}] Session processing complete: ${result.totalRecords} records processed`);
236
- }
237
- else {
238
- logger.warn(`[hook:${hookName}] Session processing had failures: ${result.failedProcessors.join(', ')}`);
239
- }
240
- // Log processor results
241
- for (const [name, procResult] of Object.entries(result.processors)) {
242
- const result = procResult;
236
+ const context = await buildProcessingContext(sessionId, event.session_id, agentSessionFiles[0], config);
237
+ // Process every transcript file. Per-file entry deduplication inside the
238
+ // adapter prevents forked/copied history from being double-counted.
239
+ for (const agentSessionFile of agentSessionFiles) {
240
+ logger.debug(`[hook:${hookName}] Calling SessionAdapter.processSession()`);
241
+ const result = await sessionAdapter.processSession(agentSessionFile, sessionId, context);
243
242
  if (result.success) {
244
- logger.debug(`[hook:${hookName}] Processor ${name}: ${result.message || 'success'}`);
243
+ logger.info(`[hook:${hookName}] Session processing complete: ${result.totalRecords} records processed`);
245
244
  }
246
245
  else {
247
- logger.error(`[hook:${hookName}] Processor ${name}: ${result.message || 'failed'}`);
246
+ logger.warn(`[hook:${hookName}] Session processing had failures: ${result.failedProcessors.join(', ')}`);
247
+ }
248
+ // Log processor results
249
+ for (const [name, procResult] of Object.entries(result.processors)) {
250
+ const result = procResult;
251
+ if (result.success) {
252
+ logger.debug(`[hook:${hookName}] Processor ${name}: ${result.message || 'success'}`);
253
+ }
254
+ else {
255
+ logger.error(`[hook:${hookName}] Processor ${name}: ${result.message || 'failed'}`);
256
+ }
248
257
  }
249
258
  }
250
259
  }
@@ -484,8 +493,14 @@ async function routeHookEvent(event, rawInput, sessionId, agentName, config) {
484
493
  // it skips if the per-Claude-session sidecar already exists.
485
494
  if (event.transcript_path &&
486
495
  (normalizedEventName === 'UserPromptSubmit' || normalizedEventName === 'Stop')) {
487
- const { appendTranscriptMarker } = await import('../../agents/core/session/session-origin-audit.js');
488
- appendTranscriptMarker(event.transcript_path, sessionId, agentName);
496
+ const { appendTranscriptMarker, isExternalOrigin } = await import('../../agents/core/session/session-origin-audit.js');
497
+ const { SessionStore } = await import('../../agents/core/session/SessionStore.js');
498
+ const session = await new SessionStore().loadSession(sessionId);
499
+ // Never (re-)stamp a transcript that's flagged external-resume — doing so would
500
+ // re-adopt it into the local analytics ownership index (native-loader.ts).
501
+ if (!isExternalOrigin(session)) {
502
+ appendTranscriptMarker(event.transcript_path, sessionId, agentName);
503
+ }
489
504
  }
490
505
  const duration = Date.now() - startTime;
491
506
  logger.info(`[hook:router] Event handled successfully: ${normalizedEventName} (${duration}ms)`);
@@ -554,6 +569,7 @@ async function createSessionRecord(event, sessionId, config) {
554
569
  // process with a fresh CODEMIE_SESSION_ID, so it never reaches this branch.)
555
570
  const existing = await sessionStore.loadSession(sessionId);
556
571
  if (existing && existing.status === 'active' && existing.endTime === undefined) {
572
+ const { appendTranscriptMarker: writeMarker, appendAuditEvent: writeAudit, isExternalOrigin, } = await import('../../agents/core/session/session-origin-audit.js');
557
573
  existing.status = 'active';
558
574
  if (gitBranch)
559
575
  existing.gitBranch = gitBranch;
@@ -565,9 +581,13 @@ async function createSessionRecord(event, sessionId, config) {
565
581
  ...(event.session_id && { agentSessionId: event.session_id }),
566
582
  ...(event.transcript_path && { agentSessionFile: event.transcript_path }),
567
583
  };
584
+ // Preserve an already-set origin; only derive from env for pre-existing records that
585
+ // predate this field. An established origin must never flip on re-entry.
586
+ if (!existing.origin && getConfigValue(SESSION_ORIGIN_ENV_KEY, config) === SESSION_ORIGIN.EXTERNAL_RESUME) {
587
+ existing.origin = SESSION_ORIGIN.EXTERNAL_RESUME;
588
+ }
568
589
  await sessionStore.saveSession(existing);
569
- const { appendTranscriptMarker: writeMarker, appendAuditEvent: writeAudit } = await import('../../agents/core/session/session-origin-audit.js');
570
- if (event.transcript_path) {
590
+ if (event.transcript_path && !isExternalOrigin(existing)) {
571
591
  writeMarker(event.transcript_path, sessionId, agentName);
572
592
  writeAudit('transcript_marker_written', {
573
593
  codemieSessionId: sessionId,
@@ -579,6 +599,10 @@ async function createSessionRecord(event, sessionId, config) {
579
599
  `startTime=${existing.startTime} activeDurationMs=${existing.activeDurationMs}`);
580
600
  return;
581
601
  }
602
+ const { appendTranscriptMarker, appendAuditEvent, isExternalOrigin } = await import('../../agents/core/session/session-origin-audit.js');
603
+ const origin = getConfigValue(SESSION_ORIGIN_ENV_KEY, config) === SESSION_ORIGIN.EXTERNAL_RESUME
604
+ ? SESSION_ORIGIN.EXTERNAL_RESUME
605
+ : undefined;
582
606
  // Create session record with correlation already matched
583
607
  const session = {
584
608
  sessionId,
@@ -591,6 +615,7 @@ async function createSessionRecord(event, sessionId, config) {
591
615
  ...(gitBranch && { gitBranch }),
592
616
  status: 'active',
593
617
  activeDurationMs: 0, // Initialize active duration tracking
618
+ ...(origin && { origin }),
594
619
  correlation: {
595
620
  status: 'matched',
596
621
  agentSessionId: event.session_id,
@@ -600,8 +625,9 @@ async function createSessionRecord(event, sessionId, config) {
600
625
  };
601
626
  // Save session
602
627
  await sessionStore.saveSession(session);
603
- const { appendTranscriptMarker, appendAuditEvent } = await import('../../agents/core/session/session-origin-audit.js');
604
- if (session.correlation.agentSessionFile) {
628
+ // Never stamp a transcript that's flagged external-resume — doing so would re-adopt it
629
+ // into the local analytics ownership index (native-loader.ts) and undo the exclusion.
630
+ if (session.correlation.agentSessionFile && !isExternalOrigin(session)) {
605
631
  appendTranscriptMarker(session.correlation.agentSessionFile, sessionId, agentName);
606
632
  appendAuditEvent('transcript_marker_written', {
607
633
  codemieSessionId: sessionId,
@@ -642,6 +668,15 @@ async function sendSessionStartMetrics(event, sessionId, agentSessionId, config)
642
668
  logger.debug('[hook:SessionStart] Missing required config for metrics');
643
669
  return;
644
670
  }
671
+ // Session record is created (with origin persisted) immediately before this is called —
672
+ // see handleSessionStart. Never upload lifecycle metrics for a confirmed external resume.
673
+ const { isExternalOrigin } = await import('../../agents/core/session/session-origin-audit.js');
674
+ const { SessionStore } = await import('../../agents/core/session/SessionStore.js');
675
+ const session = await new SessionStore().loadSession(sessionId);
676
+ if (isExternalOrigin(session)) {
677
+ logger.debug('[hook:SessionStart] Skipping start metrics for external-resume session');
678
+ return;
679
+ }
645
680
  // Determine working directory
646
681
  const workingDirectory = event.cwd || process.cwd();
647
682
  // Detect git-derived repository (owner/repo) so the lifecycle metric
@@ -890,6 +925,11 @@ async function sendSessionEndMetrics(event, sessionId, agentSessionId, config) {
890
925
  logger.warn(`[hook:SessionEnd] Session not found for metrics: ${sessionId}`);
891
926
  return;
892
927
  }
928
+ const { isExternalOrigin } = await import('../../agents/core/session/session-origin-audit.js');
929
+ if (isExternalOrigin(session)) {
930
+ logger.debug('[hook:SessionEnd] Skipping end metrics for external-resume session');
931
+ return;
932
+ }
893
933
  // Calculate durations
894
934
  const wallClockDurationMs = Date.now() - session.startTime;
895
935
  const activeDurationMs = session.activeDurationMs || undefined;
@@ -983,10 +1023,12 @@ function validateHookEvent(event, config) {
983
1023
  process.exitCode = 2;
984
1024
  return;
985
1025
  }
986
- // transcript_path is optional for SessionStart/SessionEnd in programmatic mode
987
- // (transcript may not exist yet at start, or may not be discoverable at end)
1026
+ // transcript_path/transcript_paths are optional for SessionStart/SessionEnd in
1027
+ // programmatic mode (transcript may not exist yet at start, or may not be
1028
+ // discoverable at end). Some agents provide multiple transcript paths.
988
1029
  const transcriptOptionalEvents = ['SessionStart', 'SessionEnd'];
989
- if (!event.transcript_path && !transcriptOptionalEvents.includes(event.hook_event_name)) {
1030
+ const hasTranscriptPath = Boolean(event.transcript_path) || (event.transcript_paths && event.transcript_paths.length > 0);
1031
+ if (!hasTranscriptPath && !transcriptOptionalEvents.includes(event.hook_event_name)) {
990
1032
  const error = new Error('Missing required field: transcript_path');
991
1033
  if (config) {
992
1034
  throw error;