argus-code 0.6.0__tar.gz → 0.7.1__tar.gz

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 (394) hide show
  1. {argus_code-0.6.0 → argus_code-0.7.1}/PKG-INFO +29 -20
  2. {argus_code-0.6.0 → argus_code-0.7.1}/README.md +26 -17
  3. argus_code-0.7.1/dashboard-dist/assets/AlertsPage-hQBct4uk.js +1 -0
  4. argus_code-0.6.0/dashboard-dist/assets/AreaLine-DULy1vR8.js → argus_code-0.7.1/dashboard-dist/assets/AreaLine-BKfPVgnO.js +1 -1
  5. argus_code-0.6.0/dashboard-dist/assets/AttentionStrip-0x1TKexK.js → argus_code-0.7.1/dashboard-dist/assets/AttentionStrip-DQUV5LTN.js +1 -1
  6. argus_code-0.6.0/dashboard-dist/assets/Bars-DGflHvWv.js → argus_code-0.7.1/dashboard-dist/assets/Bars-CwquOD-V.js +1 -1
  7. argus_code-0.6.0/dashboard-dist/assets/Button-CaBiDq5j.js → argus_code-0.7.1/dashboard-dist/assets/Button-BY-h2O0Z.js +1 -1
  8. argus_code-0.6.0/dashboard-dist/assets/ChartTable-DnQkfC-d.js → argus_code-0.7.1/dashboard-dist/assets/ChartTable-iQFTYj1d.js +1 -1
  9. argus_code-0.6.0/dashboard-dist/assets/Chip-CIL0lYXp.js → argus_code-0.7.1/dashboard-dist/assets/Chip-C_zmBEC6.js +1 -1
  10. argus_code-0.6.0/dashboard-dist/assets/ErrorPanel-JuK3IhI4.js → argus_code-0.7.1/dashboard-dist/assets/ErrorPanel-lb1Tt_Cg.js +1 -1
  11. argus_code-0.6.0/dashboard-dist/assets/ModelsPage-Cr6lRqQu.js → argus_code-0.7.1/dashboard-dist/assets/ModelsPage-DwKKIQAH.js +1 -1
  12. argus_code-0.7.1/dashboard-dist/assets/MultiLine-Bp4Mitsq.js +1 -0
  13. argus_code-0.6.0/dashboard-dist/assets/OverviewPage-aSPc0cOY.js → argus_code-0.7.1/dashboard-dist/assets/OverviewPage-CAx6S0a6.js +1 -1
  14. argus_code-0.6.0/dashboard-dist/assets/Panel-NdM4AeT3.js → argus_code-0.7.1/dashboard-dist/assets/Panel-rzVYig0L.js +1 -1
  15. argus_code-0.7.1/dashboard-dist/assets/SearchPage-DIj0iG5P.js +1 -0
  16. argus_code-0.7.1/dashboard-dist/assets/SessionPage-B5py8aO_.js +2 -0
  17. argus_code-0.6.0/dashboard-dist/assets/SessionsPage-BUzlxT4V.js → argus_code-0.7.1/dashboard-dist/assets/SessionsPage-Br0MV0yN.js +2 -2
  18. argus_code-0.7.1/dashboard-dist/assets/SettingsPage-BFb2-hq_.js +1 -0
  19. argus_code-0.6.0/dashboard-dist/assets/StackedColumns-1_v1JDXl.js → argus_code-0.7.1/dashboard-dist/assets/StackedColumns-Di1FeFpF.js +1 -1
  20. argus_code-0.6.0/dashboard-dist/assets/Tile-C4mpgbF2.js → argus_code-0.7.1/dashboard-dist/assets/Tile-BlnGo9bN.js +1 -1
  21. argus_code-0.6.0/dashboard-dist/assets/TimelineTab-CaaXFc1o.js → argus_code-0.7.1/dashboard-dist/assets/TimelineTab-Cwp4_Kwm.js +1 -1
  22. argus_code-0.6.0/dashboard-dist/assets/ToolsPage-gfkohaLX.js → argus_code-0.7.1/dashboard-dist/assets/ToolsPage-1lP1X2_y.js +1 -1
  23. argus_code-0.6.0/dashboard-dist/assets/TrendsPage-D0LVzVow.js → argus_code-0.7.1/dashboard-dist/assets/TrendsPage-C-GToldA.js +1 -1
  24. argus_code-0.7.1/dashboard-dist/assets/agents-CDuRxAZi.js +1 -0
  25. argus_code-0.6.0/dashboard-dist/assets/index-CpQkAwD7.css → argus_code-0.7.1/dashboard-dist/assets/index-B8TteJkn.css +1 -1
  26. argus_code-0.6.0/dashboard-dist/assets/index-B3DMfZOx.js → argus_code-0.7.1/dashboard-dist/assets/index-kRaX6JLH.js +13 -13
  27. argus_code-0.6.0/dashboard-dist/assets/uplotTheme-eHUsIKi3.js → argus_code-0.7.1/dashboard-dist/assets/uplotTheme-Dv4lAb8e.js +1 -1
  28. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/index.html +2 -2
  29. argus_code-0.7.1/pricing/2026-10-04.json +68 -0
  30. argus_code-0.7.1/pricing/2026-10-26.json +74 -0
  31. {argus_code-0.6.0 → argus_code-0.7.1}/pyproject.toml +21 -3
  32. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/AGENTS.md +8 -5
  33. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/__init__.py +1 -1
  34. argus_code-0.7.1/python/argus/adapters/AGENTS.md +152 -0
  35. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/__init__.py +1 -0
  36. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/base.py +15 -0
  37. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/adapter.py +3 -0
  38. argus_code-0.7.1/python/argus/adapters/codex/__init__.py +5 -0
  39. argus_code-0.7.1/python/argus/adapters/codex/adapter.py +94 -0
  40. argus_code-0.7.1/python/argus/adapters/codex/discover.py +172 -0
  41. argus_code-0.7.1/python/argus/adapters/codex/ingest_file.py +181 -0
  42. argus_code-0.7.1/python/argus/adapters/codex/lines.py +79 -0
  43. argus_code-0.7.1/python/argus/adapters/codex/records.py +224 -0
  44. argus_code-0.7.1/python/argus/adapters/codex/state.py +150 -0
  45. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/AGENTS.md +6 -1
  46. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/first_run.py +37 -41
  47. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/pipeline.py +9 -3
  48. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/search_backfill.py +18 -29
  49. argus_code-0.7.1/python/argus/collector/session_files.py +18 -0
  50. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/core/runtime.py +3 -3
  51. {argus_code-0.6.0 → argus_code-0.7.1}/tests/AGENTS.md +4 -1
  52. argus_code-0.7.1/tests/adapters/codex/test_adapter.py +109 -0
  53. argus_code-0.7.1/tests/adapters/codex/test_discover.py +95 -0
  54. argus_code-0.7.1/tests/adapters/codex/test_ingest_file.py +139 -0
  55. argus_code-0.7.1/tests/adapters/codex/test_lines.py +52 -0
  56. argus_code-0.7.1/tests/adapters/codex/test_real_root.py +64 -0
  57. argus_code-0.7.1/tests/adapters/codex/test_records.py +109 -0
  58. argus_code-0.7.1/tests/adapters/codex/test_state.py +76 -0
  59. argus_code-0.7.1/tests/collector/test_codex_incremental_invariant.py +165 -0
  60. argus_code-0.7.1/tests/collector/test_pipeline_codex.py +133 -0
  61. argus_code-0.7.1/tests/collector/test_session_files.py +58 -0
  62. {argus_code-0.6.0 → argus_code-0.7.1}/tests/conftest.py +8 -0
  63. argus_code-0.7.1/tests/pricing/test_load.py +163 -0
  64. {argus_code-0.6.0 → argus_code-0.7.1}/uv.lock +1 -1
  65. argus_code-0.6.0/.claude/settings.local.json +0 -7
  66. argus_code-0.6.0/.github/ISSUE_TEMPLATE/bug_report.yml +0 -68
  67. argus_code-0.6.0/.github/ISSUE_TEMPLATE/config.yml +0 -5
  68. argus_code-0.6.0/.github/ISSUE_TEMPLATE/feature_request.yml +0 -46
  69. argus_code-0.6.0/.github/pull_request_template.md +0 -36
  70. argus_code-0.6.0/.github/workflows/test.yml +0 -74
  71. argus_code-0.6.0/AGENTS.md +0 -131
  72. argus_code-0.6.0/ARCHITECTURE.md +0 -347
  73. argus_code-0.6.0/CLAUDE.md +0 -14
  74. argus_code-0.6.0/CONTRIBUTING.md +0 -178
  75. argus_code-0.6.0/PRD.md +0 -387
  76. argus_code-0.6.0/SECURITY.md +0 -116
  77. argus_code-0.6.0/TESTING.md +0 -406
  78. argus_code-0.6.0/assets/hero.png +0 -0
  79. argus_code-0.6.0/assets/logo.svg +0 -7
  80. argus_code-0.6.0/assets/screenshots/alerts.png +0 -0
  81. argus_code-0.6.0/assets/screenshots/models.png +0 -0
  82. argus_code-0.6.0/assets/screenshots/overview.png +0 -0
  83. argus_code-0.6.0/assets/screenshots/search.png +0 -0
  84. argus_code-0.6.0/assets/screenshots/session-detail.png +0 -0
  85. argus_code-0.6.0/assets/screenshots/session-timeline.png +0 -0
  86. argus_code-0.6.0/assets/screenshots/sessions.png +0 -0
  87. argus_code-0.6.0/assets/screenshots/settings.png +0 -0
  88. argus_code-0.6.0/assets/screenshots/subagents.png +0 -0
  89. argus_code-0.6.0/assets/screenshots/tools.png +0 -0
  90. argus_code-0.6.0/assets/screenshots/trends.png +0 -0
  91. argus_code-0.6.0/assets - Shortcut.lnk +0 -0
  92. argus_code-0.6.0/dashboard/.astro/content-assets.mjs +0 -1
  93. argus_code-0.6.0/dashboard/.astro/content-modules.mjs +0 -1
  94. argus_code-0.6.0/dashboard/.astro/content.d.ts +0 -155
  95. argus_code-0.6.0/dashboard/.astro/types.d.ts +0 -2
  96. argus_code-0.6.0/dashboard/AGENTS.md +0 -79
  97. argus_code-0.6.0/dashboard/e2e/smoke.spec.ts +0 -35
  98. argus_code-0.6.0/dashboard/index.html +0 -12
  99. argus_code-0.6.0/dashboard/package-lock.json +0 -4414
  100. argus_code-0.6.0/dashboard/package.json +0 -44
  101. argus_code-0.6.0/dashboard/playwright.config.ts +0 -17
  102. argus_code-0.6.0/dashboard/scripts/size.mjs +0 -19
  103. argus_code-0.6.0/dashboard/src/App.test.tsx +0 -15
  104. argus_code-0.6.0/dashboard/src/app/queryClient.ts +0 -5
  105. argus_code-0.6.0/dashboard/src/app/router.tsx +0 -19
  106. argus_code-0.6.0/dashboard/src/app/shell/CommandPalette.test.tsx +0 -16
  107. argus_code-0.6.0/dashboard/src/app/shell/CommandPalette.tsx +0 -52
  108. argus_code-0.6.0/dashboard/src/app/shell/Shell.tsx +0 -13
  109. argus_code-0.6.0/dashboard/src/app/shell/Sidebar.test.tsx +0 -21
  110. argus_code-0.6.0/dashboard/src/app/shell/Sidebar.tsx +0 -73
  111. argus_code-0.6.0/dashboard/src/app/shell/TopBar.tsx +0 -28
  112. argus_code-0.6.0/dashboard/src/components/charts/AlertStrip.tsx +0 -22
  113. argus_code-0.6.0/dashboard/src/components/charts/AreaLine.test.tsx +0 -14
  114. argus_code-0.6.0/dashboard/src/components/charts/AreaLine.tsx +0 -50
  115. argus_code-0.6.0/dashboard/src/components/charts/Bars.test.tsx +0 -12
  116. argus_code-0.6.0/dashboard/src/components/charts/Bars.tsx +0 -28
  117. argus_code-0.6.0/dashboard/src/components/charts/CalendarHeatmap.test.tsx +0 -8
  118. argus_code-0.6.0/dashboard/src/components/charts/CalendarHeatmap.tsx +0 -30
  119. argus_code-0.6.0/dashboard/src/components/charts/ChartTable.tsx +0 -40
  120. argus_code-0.6.0/dashboard/src/components/charts/GridHeatmap.tsx +0 -27
  121. argus_code-0.6.0/dashboard/src/components/charts/Legend.tsx +0 -12
  122. argus_code-0.6.0/dashboard/src/components/charts/Meter.test.tsx +0 -8
  123. argus_code-0.6.0/dashboard/src/components/charts/Meter.tsx +0 -21
  124. argus_code-0.6.0/dashboard/src/components/charts/Minimap.test.tsx +0 -17
  125. argus_code-0.6.0/dashboard/src/components/charts/Minimap.tsx +0 -35
  126. argus_code-0.6.0/dashboard/src/components/charts/MultiLine.tsx +0 -5
  127. argus_code-0.6.0/dashboard/src/components/charts/README.md +0 -22
  128. argus_code-0.6.0/dashboard/src/components/charts/Scatter.tsx +0 -83
  129. argus_code-0.6.0/dashboard/src/components/charts/Sparkline.tsx +0 -14
  130. argus_code-0.6.0/dashboard/src/components/charts/StackedColumns.tsx +0 -67
  131. argus_code-0.6.0/dashboard/src/components/charts/UPlotChart.tsx +0 -36
  132. argus_code-0.6.0/dashboard/src/components/charts/ramp.ts +0 -3
  133. argus_code-0.6.0/dashboard/src/components/charts/uplotTheme.ts +0 -14
  134. argus_code-0.6.0/dashboard/src/components/ui/Button.tsx +0 -18
  135. argus_code-0.6.0/dashboard/src/components/ui/Chip.tsx +0 -16
  136. argus_code-0.6.0/dashboard/src/components/ui/CopyId.tsx +0 -28
  137. argus_code-0.6.0/dashboard/src/components/ui/DataTable.tsx +0 -70
  138. argus_code-0.6.0/dashboard/src/components/ui/EmptyState.tsx +0 -6
  139. argus_code-0.6.0/dashboard/src/components/ui/ErrorPanel.tsx +0 -5
  140. argus_code-0.6.0/dashboard/src/components/ui/Icon.tsx +0 -30
  141. argus_code-0.6.0/dashboard/src/components/ui/Kbd.tsx +0 -3
  142. argus_code-0.6.0/dashboard/src/components/ui/Panel.tsx +0 -18
  143. argus_code-0.6.0/dashboard/src/components/ui/Pill.test.tsx +0 -11
  144. argus_code-0.6.0/dashboard/src/components/ui/Pill.tsx +0 -24
  145. argus_code-0.6.0/dashboard/src/components/ui/Seg.test.tsx +0 -10
  146. argus_code-0.6.0/dashboard/src/components/ui/Seg.tsx +0 -18
  147. argus_code-0.6.0/dashboard/src/components/ui/Skeleton.tsx +0 -3
  148. argus_code-0.6.0/dashboard/src/components/ui/Tile.test.tsx +0 -31
  149. argus_code-0.6.0/dashboard/src/components/ui/Tile.tsx +0 -38
  150. argus_code-0.6.0/dashboard/src/features/alerts/AlertsPage.tsx +0 -98
  151. argus_code-0.6.0/dashboard/src/features/models/ModelsPage.tsx +0 -83
  152. argus_code-0.6.0/dashboard/src/features/overview/AttentionStrip.tsx +0 -40
  153. argus_code-0.6.0/dashboard/src/features/overview/OverviewPage.tsx +0 -113
  154. argus_code-0.6.0/dashboard/src/features/overview/TopSessions.tsx +0 -45
  155. argus_code-0.6.0/dashboard/src/features/overview/useOverviewModel.test.ts +0 -33
  156. argus_code-0.6.0/dashboard/src/features/overview/useOverviewModel.ts +0 -55
  157. argus_code-0.6.0/dashboard/src/features/search/SearchPage.tsx +0 -112
  158. argus_code-0.6.0/dashboard/src/features/search/cleanSnippet.test.ts +0 -11
  159. argus_code-0.6.0/dashboard/src/features/search/cleanSnippet.ts +0 -24
  160. argus_code-0.6.0/dashboard/src/features/session/OverviewTab.tsx +0 -61
  161. argus_code-0.6.0/dashboard/src/features/session/SessionPage.tsx +0 -88
  162. argus_code-0.6.0/dashboard/src/features/session/SubagentsTab.tsx +0 -183
  163. argus_code-0.6.0/dashboard/src/features/session/TimelineTab.tsx +0 -139
  164. argus_code-0.6.0/dashboard/src/features/session/model.test.ts +0 -22
  165. argus_code-0.6.0/dashboard/src/features/session/model.ts +0 -37
  166. argus_code-0.6.0/dashboard/src/features/sessions/AnalysisStrip.tsx +0 -67
  167. argus_code-0.6.0/dashboard/src/features/sessions/SessionsPage.tsx +0 -66
  168. argus_code-0.6.0/dashboard/src/features/sessions/SessionsTable.tsx +0 -44
  169. argus_code-0.6.0/dashboard/src/features/sessions/filters.test.ts +0 -15
  170. argus_code-0.6.0/dashboard/src/features/sessions/filters.ts +0 -19
  171. argus_code-0.6.0/dashboard/src/features/settings/SettingsPage.tsx +0 -89
  172. argus_code-0.6.0/dashboard/src/features/tools/ToolsPage.tsx +0 -86
  173. argus_code-0.6.0/dashboard/src/features/tools/toolsOverTime.test.ts +0 -15
  174. argus_code-0.6.0/dashboard/src/features/tools/toolsOverTime.ts +0 -29
  175. argus_code-0.6.0/dashboard/src/features/trends/TrendsPage.tsx +0 -101
  176. argus_code-0.6.0/dashboard/src/lib/analysis/composition.test.ts +0 -7
  177. argus_code-0.6.0/dashboard/src/lib/analysis/composition.ts +0 -14
  178. argus_code-0.6.0/dashboard/src/lib/analysis/cumulative.test.ts +0 -3
  179. argus_code-0.6.0/dashboard/src/lib/analysis/cumulative.ts +0 -4
  180. argus_code-0.6.0/dashboard/src/lib/analysis/deltas.test.ts +0 -14
  181. argus_code-0.6.0/dashboard/src/lib/analysis/deltas.ts +0 -13
  182. argus_code-0.6.0/dashboard/src/lib/analysis/hourWeekday.test.ts +0 -9
  183. argus_code-0.6.0/dashboard/src/lib/analysis/hourWeekday.ts +0 -13
  184. argus_code-0.6.0/dashboard/src/lib/analysis/rollups.test.ts +0 -36
  185. argus_code-0.6.0/dashboard/src/lib/analysis/rollups.ts +0 -37
  186. argus_code-0.6.0/dashboard/src/lib/analysis/series.test.ts +0 -25
  187. argus_code-0.6.0/dashboard/src/lib/analysis/series.ts +0 -32
  188. argus_code-0.6.0/dashboard/src/lib/analysis/testutil.ts +0 -23
  189. argus_code-0.6.0/dashboard/src/lib/analysis/trendsMetrics.test.ts +0 -31
  190. argus_code-0.6.0/dashboard/src/lib/analysis/trendsMetrics.ts +0 -53
  191. argus_code-0.6.0/dashboard/src/lib/analysis/windows.test.ts +0 -17
  192. argus_code-0.6.0/dashboard/src/lib/analysis/windows.ts +0 -23
  193. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/alerts.json +0 -1
  194. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/overview.json +0 -1
  195. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/sessions.json +0 -1
  196. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/timeline.json +0 -2785
  197. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/tools-overview.json +0 -1
  198. argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/trends.json +0 -1
  199. argus_code-0.6.0/dashboard/src/lib/api/client.test.ts +0 -26
  200. argus_code-0.6.0/dashboard/src/lib/api/client.ts +0 -74
  201. argus_code-0.6.0/dashboard/src/lib/api/hooks.ts +0 -31
  202. argus_code-0.6.0/dashboard/src/lib/api/schemas.ts +0 -197
  203. argus_code-0.6.0/dashboard/src/lib/api/timezone.test.ts +0 -48
  204. argus_code-0.6.0/dashboard/src/lib/format/format.test.ts +0 -54
  205. argus_code-0.6.0/dashboard/src/lib/format/format.ts +0 -51
  206. argus_code-0.6.0/dashboard/src/main.tsx +0 -18
  207. argus_code-0.6.0/dashboard/src/routeTree.gen.ts +0 -273
  208. argus_code-0.6.0/dashboard/src/routes/__root.tsx +0 -10
  209. argus_code-0.6.0/dashboard/src/routes/alerts.tsx +0 -3
  210. argus_code-0.6.0/dashboard/src/routes/index.tsx +0 -3
  211. argus_code-0.6.0/dashboard/src/routes/models.tsx +0 -3
  212. argus_code-0.6.0/dashboard/src/routes/prompts.tsx +0 -8
  213. argus_code-0.6.0/dashboard/src/routes/search.tsx +0 -3
  214. argus_code-0.6.0/dashboard/src/routes/session.tsx +0 -10
  215. argus_code-0.6.0/dashboard/src/routes/sessions.$id.tsx +0 -9
  216. argus_code-0.6.0/dashboard/src/routes/sessions.index.tsx +0 -3
  217. argus_code-0.6.0/dashboard/src/routes/settings.tsx +0 -3
  218. argus_code-0.6.0/dashboard/src/routes/tools.tsx +0 -3
  219. argus_code-0.6.0/dashboard/src/routes/trends.tsx +0 -3
  220. argus_code-0.6.0/dashboard/src/styles.css +0 -62
  221. argus_code-0.6.0/dashboard/tsconfig.json +0 -17
  222. argus_code-0.6.0/dashboard/vite.config.ts +0 -19
  223. argus_code-0.6.0/dashboard/vitest.config.ts +0 -15
  224. argus_code-0.6.0/dashboard/vitest.setup.ts +0 -25
  225. argus_code-0.6.0/dashboard-dist/assets/AlertsPage-wRJbF_gs.js +0 -1
  226. argus_code-0.6.0/dashboard-dist/assets/MultiLine-PWsvBuFC.js +0 -1
  227. argus_code-0.6.0/dashboard-dist/assets/SearchPage-DjBBvR08.js +0 -1
  228. argus_code-0.6.0/dashboard-dist/assets/SessionPage-UuHPkPWG.js +0 -2
  229. argus_code-0.6.0/dashboard-dist/assets/SettingsPage-DhimL0WE.js +0 -1
  230. argus_code-0.6.0/python/argus/adapters/AGENTS.md +0 -73
  231. argus_code-0.6.0/scripts/screenshots/capture.mjs +0 -176
  232. argus_code-0.6.0/scripts/screenshots/frame.mjs +0 -67
  233. argus_code-0.6.0/tests/pricing/test_load.py +0 -88
  234. {argus_code-0.6.0 → argus_code-0.7.1}/.gitignore +0 -0
  235. {argus_code-0.6.0 → argus_code-0.7.1}/LICENSE +0 -0
  236. {argus_code-0.6.0 → argus_code-0.7.1}/NOTICE +0 -0
  237. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/cumulative-C3-3HW0n.js +0 -0
  238. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  239. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  240. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  241. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  242. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  243. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  244. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  245. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  246. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  247. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  248. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/rollups-Dqiwg3gD.js +0 -0
  249. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/series-BjP-80tt.js +0 -0
  250. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/uplotTheme-D1GxaB_c.css +0 -0
  251. {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/windows-B3y4OLGl.js +0 -0
  252. {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-05-02.json +0 -0
  253. {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-06-12.json +0 -0
  254. {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-09-22.json +0 -0
  255. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/__init__.py +0 -0
  256. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/discover.py +0 -0
  257. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_tool_calls.py +0 -0
  258. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_transcript.py +0 -0
  259. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_turns.py +0 -0
  260. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/history_jsonl.py +0 -0
  261. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/ingest_file.py +0 -0
  262. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/model.py +0 -0
  263. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/schemas.py +0 -0
  264. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/registry.py +0 -0
  265. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/cli.py +0 -0
  266. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/__init__.py +0 -0
  267. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/aggregate.py +0 -0
  268. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/rollup_subagents.py +0 -0
  269. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/scheduler.py +0 -0
  270. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/watcher.py +0 -0
  271. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/core/__init__.py +0 -0
  272. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/__init__.py +0 -0
  273. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/logging.py +0 -0
  274. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/pidfile.py +0 -0
  275. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/process.py +0 -0
  276. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/service.py +0 -0
  277. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/__init__.py +0 -0
  278. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/base.py +0 -0
  279. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/cache_hit_drop.py +0 -0
  280. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/cost_spike.py +0 -0
  281. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/registry.py +0 -0
  282. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/tool_error_rate_spike.py +0 -0
  283. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/__init__.py +0 -0
  284. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/compute.py +0 -0
  285. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/load.py +0 -0
  286. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/refresh.py +0 -0
  287. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/types.py +0 -0
  288. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/__init__.py +0 -0
  289. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/scaffolder.py +0 -0
  290. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/snapshot.py +0 -0
  291. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/storage.py +0 -0
  292. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/schema/__init__.py +0 -0
  293. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/schema/types.py +0 -0
  294. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/AGENTS.md +0 -0
  295. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/__init__.py +0 -0
  296. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/api.py +0 -0
  297. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/app.py +0 -0
  298. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/AGENTS.md +0 -0
  299. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/__init__.py +0 -0
  300. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/db.py +0 -0
  301. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/migrations/__init__.py +0 -0
  302. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/migrations/inline.py +0 -0
  303. {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/repository.py +0 -0
  304. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/agents/code-reviewer.md +0 -0
  305. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/agents/security-auditor.md +0 -0
  306. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/commit.md +0 -0
  307. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/deploy.md +0 -0
  308. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/fix-issue.md +0 -0
  309. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/pr.md +0 -0
  310. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/review.md +0 -0
  311. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/api-conventions.md +0 -0
  312. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/code-style.md +0 -0
  313. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/testing.md +0 -0
  314. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/settings.json +0 -0
  315. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/skills/example/SKILL.md +0 -0
  316. {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/CLAUDE.md +0 -0
  317. {argus_code-0.6.0 → argus_code-0.7.1}/tests/__init__.py +0 -0
  318. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/__init__.py +0 -0
  319. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/__init__.py +0 -0
  320. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_adapter.py +0 -0
  321. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_discover.py +0 -0
  322. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_tool_calls.py +0 -0
  323. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_transcript.py +0 -0
  324. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_turns.py +0 -0
  325. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_history_jsonl.py +0 -0
  326. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_ingest_file.py +0 -0
  327. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_integration.py +0 -0
  328. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_model.py +0 -0
  329. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_path_containment.py +0 -0
  330. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_schemas.py +0 -0
  331. {argus_code-0.6.0/tests/cli → argus_code-0.7.1/tests/adapters/codex}/__init__.py +0 -0
  332. {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/test_registry.py +0 -0
  333. {argus_code-0.6.0/tests/collector → argus_code-0.7.1/tests/cli}/__init__.py +0 -0
  334. {argus_code-0.6.0 → argus_code-0.7.1}/tests/cli/test_indexing_cli.py +0 -0
  335. {argus_code-0.6.0 → argus_code-0.7.1}/tests/cli/test_pricing_refresh_cli.py +0 -0
  336. {argus_code-0.6.0/tests/core → argus_code-0.7.1/tests/collector}/__init__.py +0 -0
  337. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_aggregate.py +0 -0
  338. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_first_run.py +0 -0
  339. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_first_run_shutdown.py +0 -0
  340. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_fork_dedup.py +0 -0
  341. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_fork_dedup_db.py +0 -0
  342. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_incremental_invariant.py +0 -0
  343. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_incremental_repairs.py +0 -0
  344. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_pipeline.py +0 -0
  345. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_rollup_subagents.py +0 -0
  346. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_scheduler.py +0 -0
  347. {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_watcher.py +0 -0
  348. {argus_code-0.6.0/tests/daemon → argus_code-0.7.1/tests/core}/__init__.py +0 -0
  349. {argus_code-0.6.0 → argus_code-0.7.1}/tests/core/test_runtime.py +0 -0
  350. {argus_code-0.6.0 → argus_code-0.7.1}/tests/core/test_runtime_shutdown.py +0 -0
  351. {argus_code-0.6.0/tests/dashboard → argus_code-0.7.1/tests/daemon}/__init__.py +0 -0
  352. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_logs.py +0 -0
  353. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_no_claude_dir.py +0 -0
  354. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_pidfile.py +0 -0
  355. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_pidfile_identity.py +0 -0
  356. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_process.py +0 -0
  357. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_service.py +0 -0
  358. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_spawn_safe_path.py +0 -0
  359. {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_yield.py +0 -0
  360. {argus_code-0.6.0/tests/detectors → argus_code-0.7.1/tests/dashboard}/__init__.py +0 -0
  361. {argus_code-0.6.0 → argus_code-0.7.1}/tests/dashboard/test_no_raw_html.py +0 -0
  362. {argus_code-0.6.0/tests/pricing → argus_code-0.7.1/tests/detectors}/__init__.py +0 -0
  363. {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_base_helpers.py +0 -0
  364. {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_cache_hit_drop.py +0 -0
  365. {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_cost_spike.py +0 -0
  366. {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_registry.py +0 -0
  367. {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_tool_error_rate_spike.py +0 -0
  368. {argus_code-0.6.0/tests/scaffold → argus_code-0.7.1/tests/pricing}/__init__.py +0 -0
  369. {argus_code-0.6.0 → argus_code-0.7.1}/tests/pricing/test_compute.py +0 -0
  370. {argus_code-0.6.0 → argus_code-0.7.1}/tests/pricing/test_refresh.py +0 -0
  371. {argus_code-0.6.0/tests/schema → argus_code-0.7.1/tests/scaffold}/__init__.py +0 -0
  372. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_bundled_template.py +0 -0
  373. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_cli_claude.py +0 -0
  374. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_scaffold_containment.py +0 -0
  375. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_scaffolder.py +0 -0
  376. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_snapshot.py +0 -0
  377. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_snapshot_secrets.py +0 -0
  378. {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_storage.py +0 -0
  379. {argus_code-0.6.0/tests/server → argus_code-0.7.1/tests/schema}/__init__.py +0 -0
  380. {argus_code-0.6.0 → argus_code-0.7.1}/tests/schema/test_types.py +0 -0
  381. {argus_code-0.6.0/tests/store → argus_code-0.7.1/tests/server}/__init__.py +0 -0
  382. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_api.py +0 -0
  383. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_api_search.py +0 -0
  384. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_day_buckets.py +0 -0
  385. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_param_bounds.py +0 -0
  386. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_read_cache.py +0 -0
  387. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_server.py +0 -0
  388. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_spa_fallback.py +0 -0
  389. {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_week_of.py +0 -0
  390. /argus_code-0.6.0/.npmrc → /argus_code-0.7.1/tests/store/__init__.py +0 -0
  391. {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_db.py +0 -0
  392. {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_repository.py +0 -0
  393. {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_transactions.py +0 -0
  394. {argus_code-0.6.0 → argus_code-0.7.1}/tests/test_e2e.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: argus-code
3
- Version: 0.6.0
4
- Summary: Local-first dashboard for Claude Code cost, token, tool-usage, and full-text search analytics
3
+ Version: 0.7.1
4
+ Summary: Local-first observability for Claude Code and OpenAI Codex: per-session forensics, cost, tokens, tool health, sub-agents, alerts and full-text search
5
5
  Project-URL: Homepage, https://github.com/KrishBhimani/argus-code
6
6
  Project-URL: Repository, https://github.com/KrishBhimani/argus-code.git
7
7
  Project-URL: Issues, https://github.com/KrishBhimani/argus-code/issues
@@ -29,7 +29,7 @@ License: MIT License
29
29
  SOFTWARE.
30
30
  License-File: LICENSE
31
31
  License-File: NOTICE
32
- Keywords: ai-tools,analytics,anthropic,claude,claude-code,cli,cost,dashboard,llm,local-first,tokens,usage
32
+ Keywords: ai-tools,analytics,anthropic,claude,claude-code,cli,codex,cost,dashboard,llm,local-first,openai,tokens,usage
33
33
  Classifier: Development Status :: 4 - Beta
34
34
  Classifier: Environment :: Console
35
35
  Classifier: Environment :: Web Environment
@@ -56,7 +56,7 @@ Description-Content-Type: text/markdown
56
56
 
57
57
  <h1>Argus</h1>
58
58
 
59
- <p><strong>The observability console for Claude Code — local-first, permanent, and honest about cost.</strong></p>
59
+ <p><strong>The observability console for Claude Code and Codex — local-first, permanent, and honest about cost.</strong></p>
60
60
 
61
61
  <p>
62
62
  <a href="#-quick-start"><b>Quick start</b></a> ·
@@ -77,12 +77,12 @@ Description-Content-Type: text/markdown
77
77
 
78
78
  </div>
79
79
 
80
- Claude Code writes a detailed transcript of every session to `~/.claude/` — every turn,
81
- every token, every tool call, every sub-agent it spawned — and then tells you almost
82
- nothing about it. Argus tails those files into a SQLite archive on your machine, prices
83
- each turn, and serves a dashboard at `http://localhost:4242` that answers the questions
84
- the transcripts never do: *what am I spending, where did it go, and which turn made it
85
- so?*
80
+ Claude Code and OpenAI Codex write a detailed transcript of every session to disk
81
+ (`~/.claude/`, `~/.codex/`) — every turn, every token, every tool call, every sub-agent
82
+ they spawned — and then tell you almost nothing about it. Argus tails those files into
83
+ a SQLite archive on your machine, prices each turn, and serves a dashboard at
84
+ `http://localhost:4242` that answers the questions the transcripts never do: *what am I
85
+ spending, where did it go, and which turn made it so?*
86
86
 
87
87
  Nothing leaves your computer. No telemetry, no API calls, no embeddings — SQLite and a
88
88
  static web app, bound to `127.0.0.1`.
@@ -98,7 +98,16 @@ argus start
98
98
 
99
99
  Your browser opens once the first pass finishes (5–10 s for a typical install). From
100
100
  then on, every session you run is ingested live. All you need is Python ≥ 3.11 and a
101
- `~/.claude/` directory — i.e. you've used Claude Code at least once.
101
+ `~/.claude/` directory or a Codex home — i.e. you've used Claude Code or Codex at least once.
102
+
103
+ **Supported agents.** Argus detects whichever you use, no configuration needed:
104
+
105
+ | Agent | Reads from | Notes |
106
+ |---|---|---|
107
+ | **Claude Code** | `~/.claude/` (session transcripts under `projects/`, prompt history) | Sessions, sub-agents and your typed prompts. |
108
+ | **OpenAI Codex** | `$CODEX_HOME` (default `~/.codex`) — only `sessions/` and `archived_sessions/` | Never opens `auth.json`, config or state databases. Costs use OpenAI's standard-tier API rates — an API-equivalent figure, since Codex plans are usually billed by subscription. |
109
+
110
+ Use both and the Sessions page gains an agent filter and column.
102
111
 
103
112
  ## ✨ Why Argus
104
113
 
@@ -141,8 +150,8 @@ chronological thread.
141
150
 
142
151
  When a session delegates to sub-agents, Argus keeps each one: the **task as it was
143
152
  given**, its tools, tokens, cost, shape and full timeline — with an at-a-glance strip
144
- that turns red where an agent failed. No more guessing what that `Task` call actually
145
- did.
153
+ that turns red where an agent failed. No more guessing what that `Task` or
154
+ `spawn_agent` call actually did.
146
155
 
147
156
  <img src="https://raw.githubusercontent.com/KrishBhimani/argus-code/main/assets/screenshots/subagents.png" alt="Sub-agents — task given, tools used, per-agent shape and cost">
148
157
 
@@ -282,9 +291,9 @@ Vulnerability reports: [SECURITY.md](./SECURITY.md).
282
291
 
283
292
  ## ⚙️ How it works
284
293
 
285
- 1. **Ingest.** A `watchdog` observer tails `~/.claude/projects/<project>/<session>.jsonl`. Lines are validated with `pydantic`, de-duplicated by `message.id`, and normalised into session / turn rows in SQLite (WAL mode). Resumed sessions and sub-agent files are folded into their parent.
286
- 2. **Cost.** Per-turn cost comes from a bundled price table sourced from [LiteLLM](https://github.com/BerriAI/litellm). Tokens are exact; costs are estimates.
287
- 3. **Tools.** Each `tool_use` block becomes a row; errors come from the matching `tool_result`. MCP servers are parsed from `mcp__<server>__<tool>`; the `Agent` tool's `subagent_type` is kept so delegation is visible.
294
+ 1. **Ingest.** A `watchdog` observer tails each agent's transcripts through a per-agent adapter — Claude Code's `~/.claude/projects/<project>/<session>.jsonl` and Codex's rollouts under `$CODEX_HOME/sessions/`. Lines are validated, de-duplicated by the agent's own ids (Claude's `message.id`, Codex's `response_id`), and normalised into session / turn rows in SQLite (WAL mode). Resumed or continued sessions and sub-agent files are folded into their parent.
295
+ 2. **Cost.** Per-turn cost comes from a bundled price table (Anthropic's and OpenAI's published rates; `argus pricing refresh` can pull [LiteLLM](https://github.com/BerriAI/litellm)'s). Tokens are exact; costs are estimates.
296
+ 3. **Tools.** For Claude Code, each `tool_use` block becomes a row and errors come from the matching `tool_result`; for Codex, each completed action (shell command with its exit code, file change, MCP call, web search, `spawn_agent`) becomes a row, with errors only from explicit failure signals. MCP servers are shown as `mcp__<server>__<tool>`; sub-agent types are kept so delegation is visible.
288
297
  4. **Search (opt-in).** Two FTS5 tables — one over your prompt history, one over transcript text — indexed incrementally during the normal ingest tick.
289
298
  5. **Detection.** A scheduler runs registered *detectors* every 10 minutes; findings land in an alerts inbox with a seen / resolved lifecycle, so an issue that recovers and recurs fires again instead of staying silent.
290
299
  6. **Dashboard.** A Vite + React single-page app (uPlot and hand-drawn SVG charts), statically built and served by the FastAPI app. No Node at runtime, no network beyond `/api/*`.
@@ -314,7 +323,7 @@ Argus keeps its own copy regardless — this only widens what Claude itself reta
314
323
  ## 📋 Requirements
315
324
 
316
325
  - **Python ≥ 3.11** with an FTS5-enabled `sqlite3` (the standard CPython builds for macOS, Linux and Windows all are; Argus checks at startup and says so clearly if not).
317
- - A `~/.claude/` directory with real session JSONL — i.e. you've used Claude Code at least once.
326
+ - A `~/.claude/` directory with real session JSONL, or a Codex home (`$CODEX_HOME`, default `~/.codex`) with rollouts under `sessions/`.
318
327
 
319
328
  ## 🛠️ Development
320
329
 
@@ -322,7 +331,7 @@ Argus keeps its own copy regardless — this only widens what Claude itself reta
322
331
  git clone https://github.com/KrishBhimani/argus-code.git
323
332
  cd argus-code
324
333
  uv sync # install deps + create venv
325
- uv run pytest # ~490 tests, ~35 s
334
+ uv run pytest # ~700 tests, ~45 s
326
335
  uv run argus start # runs directly from source
327
336
  ```
328
337
 
@@ -336,7 +345,7 @@ wheel, so end users never touch `npm`. See [CONTRIBUTING.md](./CONTRIBUTING.md).
336
345
 
337
346
  ```
338
347
  python/argus/ Python ingest, store, server, CLI
339
- adapters/ Claude Code JSONL parsers + adapter registry
348
+ adapters/ Claude Code + Codex parsers + adapter registry
340
349
  store/ SQLite schema + migrations + repo
341
350
  server/ FastAPI app + /api routes
342
351
  collector/ watcher + pipeline + first-run + search backfill + alert scheduler
@@ -365,6 +374,6 @@ tests/ pytest suite, mirrors python/argus/ layout
365
374
 
366
375
  <p><i>Named for Argus Panoptes — the watchman with a hundred eyes, who never slept.</i></p>
367
376
 
368
- <p>If it keeps good watch for you, a ⭐ helps other Claude Code users find it.</p>
377
+ <p>If it keeps good watch for you, a ⭐ helps other Claude Code and Codex users find it.</p>
369
378
 
370
379
  </div>
@@ -4,7 +4,7 @@
4
4
 
5
5
  <h1>Argus</h1>
6
6
 
7
- <p><strong>The observability console for Claude Code — local-first, permanent, and honest about cost.</strong></p>
7
+ <p><strong>The observability console for Claude Code and Codex — local-first, permanent, and honest about cost.</strong></p>
8
8
 
9
9
  <p>
10
10
  <a href="#-quick-start"><b>Quick start</b></a> ·
@@ -25,12 +25,12 @@
25
25
 
26
26
  </div>
27
27
 
28
- Claude Code writes a detailed transcript of every session to `~/.claude/` — every turn,
29
- every token, every tool call, every sub-agent it spawned — and then tells you almost
30
- nothing about it. Argus tails those files into a SQLite archive on your machine, prices
31
- each turn, and serves a dashboard at `http://localhost:4242` that answers the questions
32
- the transcripts never do: *what am I spending, where did it go, and which turn made it
33
- so?*
28
+ Claude Code and OpenAI Codex write a detailed transcript of every session to disk
29
+ (`~/.claude/`, `~/.codex/`) — every turn, every token, every tool call, every sub-agent
30
+ they spawned — and then tell you almost nothing about it. Argus tails those files into
31
+ a SQLite archive on your machine, prices each turn, and serves a dashboard at
32
+ `http://localhost:4242` that answers the questions the transcripts never do: *what am I
33
+ spending, where did it go, and which turn made it so?*
34
34
 
35
35
  Nothing leaves your computer. No telemetry, no API calls, no embeddings — SQLite and a
36
36
  static web app, bound to `127.0.0.1`.
@@ -46,7 +46,16 @@ argus start
46
46
 
47
47
  Your browser opens once the first pass finishes (5–10 s for a typical install). From
48
48
  then on, every session you run is ingested live. All you need is Python ≥ 3.11 and a
49
- `~/.claude/` directory — i.e. you've used Claude Code at least once.
49
+ `~/.claude/` directory or a Codex home — i.e. you've used Claude Code or Codex at least once.
50
+
51
+ **Supported agents.** Argus detects whichever you use, no configuration needed:
52
+
53
+ | Agent | Reads from | Notes |
54
+ |---|---|---|
55
+ | **Claude Code** | `~/.claude/` (session transcripts under `projects/`, prompt history) | Sessions, sub-agents and your typed prompts. |
56
+ | **OpenAI Codex** | `$CODEX_HOME` (default `~/.codex`) — only `sessions/` and `archived_sessions/` | Never opens `auth.json`, config or state databases. Costs use OpenAI's standard-tier API rates — an API-equivalent figure, since Codex plans are usually billed by subscription. |
57
+
58
+ Use both and the Sessions page gains an agent filter and column.
50
59
 
51
60
  ## ✨ Why Argus
52
61
 
@@ -89,8 +98,8 @@ chronological thread.
89
98
 
90
99
  When a session delegates to sub-agents, Argus keeps each one: the **task as it was
91
100
  given**, its tools, tokens, cost, shape and full timeline — with an at-a-glance strip
92
- that turns red where an agent failed. No more guessing what that `Task` call actually
93
- did.
101
+ that turns red where an agent failed. No more guessing what that `Task` or
102
+ `spawn_agent` call actually did.
94
103
 
95
104
  <img src="https://raw.githubusercontent.com/KrishBhimani/argus-code/main/assets/screenshots/subagents.png" alt="Sub-agents — task given, tools used, per-agent shape and cost">
96
105
 
@@ -230,9 +239,9 @@ Vulnerability reports: [SECURITY.md](./SECURITY.md).
230
239
 
231
240
  ## ⚙️ How it works
232
241
 
233
- 1. **Ingest.** A `watchdog` observer tails `~/.claude/projects/<project>/<session>.jsonl`. Lines are validated with `pydantic`, de-duplicated by `message.id`, and normalised into session / turn rows in SQLite (WAL mode). Resumed sessions and sub-agent files are folded into their parent.
234
- 2. **Cost.** Per-turn cost comes from a bundled price table sourced from [LiteLLM](https://github.com/BerriAI/litellm). Tokens are exact; costs are estimates.
235
- 3. **Tools.** Each `tool_use` block becomes a row; errors come from the matching `tool_result`. MCP servers are parsed from `mcp__<server>__<tool>`; the `Agent` tool's `subagent_type` is kept so delegation is visible.
242
+ 1. **Ingest.** A `watchdog` observer tails each agent's transcripts through a per-agent adapter — Claude Code's `~/.claude/projects/<project>/<session>.jsonl` and Codex's rollouts under `$CODEX_HOME/sessions/`. Lines are validated, de-duplicated by the agent's own ids (Claude's `message.id`, Codex's `response_id`), and normalised into session / turn rows in SQLite (WAL mode). Resumed or continued sessions and sub-agent files are folded into their parent.
243
+ 2. **Cost.** Per-turn cost comes from a bundled price table (Anthropic's and OpenAI's published rates; `argus pricing refresh` can pull [LiteLLM](https://github.com/BerriAI/litellm)'s). Tokens are exact; costs are estimates.
244
+ 3. **Tools.** For Claude Code, each `tool_use` block becomes a row and errors come from the matching `tool_result`; for Codex, each completed action (shell command with its exit code, file change, MCP call, web search, `spawn_agent`) becomes a row, with errors only from explicit failure signals. MCP servers are shown as `mcp__<server>__<tool>`; sub-agent types are kept so delegation is visible.
236
245
  4. **Search (opt-in).** Two FTS5 tables — one over your prompt history, one over transcript text — indexed incrementally during the normal ingest tick.
237
246
  5. **Detection.** A scheduler runs registered *detectors* every 10 minutes; findings land in an alerts inbox with a seen / resolved lifecycle, so an issue that recovers and recurs fires again instead of staying silent.
238
247
  6. **Dashboard.** A Vite + React single-page app (uPlot and hand-drawn SVG charts), statically built and served by the FastAPI app. No Node at runtime, no network beyond `/api/*`.
@@ -262,7 +271,7 @@ Argus keeps its own copy regardless — this only widens what Claude itself reta
262
271
  ## 📋 Requirements
263
272
 
264
273
  - **Python ≥ 3.11** with an FTS5-enabled `sqlite3` (the standard CPython builds for macOS, Linux and Windows all are; Argus checks at startup and says so clearly if not).
265
- - A `~/.claude/` directory with real session JSONL — i.e. you've used Claude Code at least once.
274
+ - A `~/.claude/` directory with real session JSONL, or a Codex home (`$CODEX_HOME`, default `~/.codex`) with rollouts under `sessions/`.
266
275
 
267
276
  ## 🛠️ Development
268
277
 
@@ -270,7 +279,7 @@ Argus keeps its own copy regardless — this only widens what Claude itself reta
270
279
  git clone https://github.com/KrishBhimani/argus-code.git
271
280
  cd argus-code
272
281
  uv sync # install deps + create venv
273
- uv run pytest # ~490 tests, ~35 s
282
+ uv run pytest # ~700 tests, ~45 s
274
283
  uv run argus start # runs directly from source
275
284
  ```
276
285
 
@@ -284,7 +293,7 @@ wheel, so end users never touch `npm`. See [CONTRIBUTING.md](./CONTRIBUTING.md).
284
293
 
285
294
  ```
286
295
  python/argus/ Python ingest, store, server, CLI
287
- adapters/ Claude Code JSONL parsers + adapter registry
296
+ adapters/ Claude Code + Codex parsers + adapter registry
288
297
  store/ SQLite schema + migrations + repo
289
298
  server/ FastAPI app + /api routes
290
299
  collector/ watcher + pipeline + first-run + search backfill + alert scheduler
@@ -313,6 +322,6 @@ tests/ pytest suite, mirrors python/argus/ layout
313
322
 
314
323
  <p><i>Named for Argus Panoptes — the watchman with a hundred eyes, who never slept.</i></p>
315
324
 
316
- <p>If it keeps good watch for you, a ⭐ helps other Claude Code users find it.</p>
325
+ <p>If it keeps good watch for you, a ⭐ helps other Claude Code and Codex users find it.</p>
317
326
 
318
327
  </div>
@@ -0,0 +1 @@
1
+ import{j as e,g as y,h as N,r as h}from"./index-kRaX6JLH.js";import{T as u,a as g,P as p}from"./Panel-rzVYig0L.js";import{E as k,S as _}from"./ErrorPanel-lb1Tt_Cg.js";import{B as v,P as f}from"./Button-BY-h2O0Z.js";import{a as d}from"./AttentionStrip-DQUV5LTN.js";const $={info:"#3987e5",warning:"#fab219",critical:"#d03b3b"};function A({alerts:s,days:a=30,end:n=new Date,className:m=""}){const c=n.getTime(),l=c-a*864e5;return e.jsxs("svg",{className:`block w-full ${m}`,width:"100%",viewBox:"0 0 300 36",style:{aspectRatio:"300 / 36"},role:"img","aria-label":`Alerts, last ${a} days`,children:[e.jsx("line",{x1:0,y1:36/2,x2:300,y2:36/2,stroke:"#232934"}),s.filter(r=>r.at>=l&&r.at<=c).map((r,t)=>e.jsx("circle",{cx:(r.at-l)/(c-l)*292+4,cy:36/2,r:r.severity==="critical"?5:r.severity==="warning"?4:3,fill:$[r.severity],stroke:"#10131a",strokeWidth:2,children:e.jsx("title",{children:`${new Date(r.at).toLocaleDateString()} · ${r.severity}`})},t)),e.jsx("text",{x:0,y:34,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:`-${a}d`}),e.jsx("text",{x:300,y:34,fontSize:9,fill:"#667184",textAnchor:"end",fontFamily:"var(--font-mono)",children:"now"})]})}const C={info:"info",warning:"warn",critical:"crit"},S={info:"shadow-[inset_3px_0_0_var(--color-s1)]",warning:"shadow-[inset_3px_0_0_var(--color-warn)]",critical:"shadow-[inset_3px_0_0_var(--color-crit)]"},w=({children:s})=>e.jsx("span",{className:"font-mono text-[11px] text-ink-1 bg-bg-3 px-1.5 rounded-sm",children:s}),D=[{n:"tool_error_rate_spike",on:!0,note:"7d vs 28d"},{n:"cost_spike",on:!0,note:"7d vs 28d/wk"},{n:"cache_hit_drop",on:!0,note:"7d vs 28d"}],E=s=>{const a=typeof s.metadata?.tool_name=="string"?s.metadata.tool_name:null,n=typeof s.metadata?.project=="string"?s.metadata.project:null;return[a&&`tool=${a}`,n&&`project=${n}`].filter(Boolean)};function z(){const s=y(),a=N(),[n,m]=h.useState("unseen"),i=h.useMemo(()=>new Set((s.data??[]).filter(t=>!t.seen_at).map(t=>t.id)),[s.data]),o=h.useMemo(()=>[...s.data??[]].sort((t,x)=>d(x).localeCompare(d(t))),[s.data]),c=n==="all"?o:n==="unseen"?o.filter(t=>i.has(t.id)):o.filter(t=>t.severity===n),l=o.filter(t=>Date.now()-new Date(d(t)).getTime()<30*864e5),r=t=>d(t)?new Date(d(t)).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"}):"";return s.error?e.jsxs(e.Fragment,{children:[e.jsx(u,{crumbs:["Monitor","Alerts"]}),e.jsx(g,{children:e.jsx(k,{error:s.error})})]}):e.jsxs(e.Fragment,{children:[e.jsxs(u,{crumbs:["Monitor","Alerts"],children:[e.jsx(_,{options:[{value:"unseen",label:`Unseen · ${i.size}`},{value:"all",label:`All · ${o.length}`},{value:"warning",label:"Warning"},{value:"critical",label:"Critical"}],value:n,onChange:m}),e.jsx(v,{variant:"ghost",disabled:!i.size,onClick:()=>i.forEach(t=>a.mutate(t)),children:"Mark all seen"})]}),e.jsxs(g,{row:!0,children:[e.jsxs(p,{padded:!1,className:"flex-1 self-start",children:[c.length===0&&e.jsxs("div",{className:"text-center text-ink-2 py-10 flex items-center justify-center gap-2",children:[e.jsx(f,{kind:"good",children:"ALL CLEAR"}),"nothing ",n==="all"?"recorded":n]}),c.map(t=>{const x=!i.has(t.id),b=E(t);return e.jsxs("div",{className:`flex items-start gap-3.5 p-3.5 border-b border-line ${x?"opacity-70":S[t.severity]}`,children:[e.jsx(f,{kind:C[t.severity],className:"mt-px",children:t.severity.toUpperCase()}),e.jsxs("div",{className:"flex flex-col gap-1 flex-1 min-w-0",children:[e.jsx("span",{className:"font-semibold",children:t.title}),e.jsx("span",{className:"text-ink-1",children:t.message}),e.jsxs("div",{className:"flex gap-2 mt-1.5 items-center",children:[e.jsx(w,{children:t.detector}),b.map(j=>e.jsx(w,{children:j},j))]})]}),e.jsxs("div",{className:"flex flex-col items-end gap-2",children:[e.jsx("span",{className:"font-mono text-[11px] text-ink-2 whitespace-nowrap",children:r(t)}),x?e.jsx(f,{kind:"mute",children:"seen"}):e.jsx(v,{size:"sm",onClick:()=>a.mutate(t.id),children:"Mark seen"})]})]},t.id)})]}),e.jsxs("div",{className:"w-[300px] shrink-0 flex flex-col gap-3",children:[e.jsx(p,{title:"Detectors",sub:"run after each ingest",padded:!1,children:D.map(t=>e.jsxs("div",{className:`flex items-center gap-2.5 px-3.5 py-2.5 border-b border-line last:border-b-0 ${t.on?"":"text-ink-2"}`,children:[e.jsx("span",{className:`w-[7px] h-[7px] rounded-full ${t.on?"bg-good":"border border-line-2"}`}),e.jsx("span",{className:"font-mono text-[11.5px]",children:t.n}),e.jsxs("span",{className:`ml-auto font-mono text-[11px] ${t.on?"text-good":""}`,children:[t.on?"on":"off"," · ",t.note]})]},t.n))}),e.jsxs(p,{title:"Last 30 days",children:[e.jsx(A,{alerts:l.map(t=>({at:new Date(d(t)).getTime(),severity:t.severity}))}),e.jsxs("div",{className:"flex flex-col gap-2 mt-3 text-xs",children:[e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-1",children:"Alerts raised"}),e.jsx("span",{className:"font-mono num",children:l.length})]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsx("span",{className:"text-ink-1",children:"Critical"}),e.jsx("span",{className:"font-mono num",children:l.filter(t=>t.severity==="critical").length})]})]})]})]})]})]})}export{z as default};
@@ -1 +1 @@
1
- import{r as f,t as A,j as r}from"./index-B3DMfZOx.js";import{A as h,S as e,h as j,L as w,U as E}from"./uplotTheme-eHUsIKi3.js";function v({labels:s,series:o,stacked:l=!1,fill:u=!0,share:m=!1,format:x=A,height:i=220}){const c=f.useMemo(()=>{const t=s.map((n,p)=>p);if(!l)return[t,...o.map(n=>n.values)];const a=Array(s.length).fill(0);return[t,...o.map(n=>n.values.map((p,d)=>a[d]+=p))]},[s,o,l]),g=f.useMemo(()=>({cursor:{points:{size:8}},legend:{show:!1},padding:[8,12,0,0],scales:{x:{time:!1},y:m?{range:[0,1]}:{}},axes:[{...h,values:(t,a)=>a.map(n=>n==null?"":s[n]??"")},{...h,size:52,values:(t,a)=>a.map(n=>n==null?"":m?`${Math.round(n*100)}%`:x(n))}],series:[{},...o.map((t,a)=>({label:t.name,stroke:e[a%e.length],width:2,points:{show:!1},fill:u?j(e[a%e.length],l?.35:.1):void 0,...l&&a>0?{band:!0}:{}}))]}),[s,o,l,u,m,x]);return r.jsxs("div",{className:"flex flex-col gap-2 min-w-0",children:[o.length>=2&&r.jsx(w,{names:o.map(t=>t.name),colors:o.map((t,a)=>e[a%e.length])}),r.jsx(E,{options:g,data:c,height:i})]})}export{v as A};
1
+ import{r as f,t as A,j as r}from"./index-kRaX6JLH.js";import{A as h,S as e,h as j,L as w,U as E}from"./uplotTheme-Dv4lAb8e.js";function v({labels:s,series:o,stacked:l=!1,fill:u=!0,share:m=!1,format:x=A,height:i=220}){const c=f.useMemo(()=>{const t=s.map((n,p)=>p);if(!l)return[t,...o.map(n=>n.values)];const a=Array(s.length).fill(0);return[t,...o.map(n=>n.values.map((p,d)=>a[d]+=p))]},[s,o,l]),g=f.useMemo(()=>({cursor:{points:{size:8}},legend:{show:!1},padding:[8,12,0,0],scales:{x:{time:!1},y:m?{range:[0,1]}:{}},axes:[{...h,values:(t,a)=>a.map(n=>n==null?"":s[n]??"")},{...h,size:52,values:(t,a)=>a.map(n=>n==null?"":m?`${Math.round(n*100)}%`:x(n))}],series:[{},...o.map((t,a)=>({label:t.name,stroke:e[a%e.length],width:2,points:{show:!1},fill:u?j(e[a%e.length],l?.35:.1):void 0,...l&&a>0?{band:!0}:{}}))]}),[s,o,l,u,m,x]);return r.jsxs("div",{className:"flex flex-col gap-2 min-w-0",children:[o.length>=2&&r.jsx(w,{names:o.map(t=>t.name),colors:o.map((t,a)=>e[a%e.length])}),r.jsx(E,{options:g,data:c,height:i})]})}export{v as A};
@@ -1 +1 @@
1
- import{h as p,g as x,i as m,j as e,s as i,L as h}from"./index-B3DMfZOx.js";import{P as j}from"./Panel-NdM4AeT3.js";import{P as l,B as u}from"./Button-CaBiDq5j.js";const f={info:"info",warning:"warn",critical:"crit"},n=t=>t.created_at??t.first_seen_at??"";function N(){const t=p().data??[],o=x().data??[],c=m(),r=t.slice(0,3),a=[...o].sort((s,d)=>n(d).localeCompare(n(s)))[0];return e.jsx(j,{title:"Needs attention",sub:`${t.length} unseen`,right:e.jsx(h,{to:"/alerts",className:"text-[11px]",children:"All alerts →"}),padded:!1,children:r.length===0?e.jsxs("div",{className:"flex items-center gap-3 px-3.5 py-2.5 text-ink-1",children:[e.jsx(l,{kind:"good",children:"ALL CLEAR"}),a?e.jsxs("span",{children:["last alert ",i(n(a)),": ",a.title]}):e.jsx("span",{children:"no alerts recorded yet"})]}):r.map(s=>e.jsxs("div",{className:"flex items-center gap-3 px-3.5 py-2.5 border-b border-line last:border-b-0 min-w-0",children:[e.jsx(l,{kind:f[s.severity],children:s.severity.toUpperCase()}),e.jsx("span",{className:"font-medium whitespace-nowrap",children:s.title}),e.jsx("span",{className:"text-ink-1 truncate",children:s.message}),e.jsx("span",{className:"ml-auto font-mono text-[11px] text-ink-1 bg-bg-3 px-1.5 rounded-sm whitespace-nowrap",children:s.detector}),e.jsx("span",{className:"font-mono text-[11px] text-ink-2 whitespace-nowrap",children:n(s)?i(n(s)):""}),e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>c.mutate(s.id),children:"Mark seen"})]},s.id))})}export{N as A,n as a};
1
+ import{i as p,g as x,h as m,j as e,s as i,L as h}from"./index-kRaX6JLH.js";import{P as j}from"./Panel-rzVYig0L.js";import{P as l,B as u}from"./Button-BY-h2O0Z.js";const f={info:"info",warning:"warn",critical:"crit"},n=t=>t.created_at??t.first_seen_at??"";function N(){const t=p().data??[],o=x().data??[],c=m(),r=t.slice(0,3),a=[...o].sort((s,d)=>n(d).localeCompare(n(s)))[0];return e.jsx(j,{title:"Needs attention",sub:`${t.length} unseen`,right:e.jsx(h,{to:"/alerts",className:"text-[11px]",children:"All alerts →"}),padded:!1,children:r.length===0?e.jsxs("div",{className:"flex items-center gap-3 px-3.5 py-2.5 text-ink-1",children:[e.jsx(l,{kind:"good",children:"ALL CLEAR"}),a?e.jsxs("span",{children:["last alert ",i(n(a)),": ",a.title]}):e.jsx("span",{children:"no alerts recorded yet"})]}):r.map(s=>e.jsxs("div",{className:"flex items-center gap-3 px-3.5 py-2.5 border-b border-line last:border-b-0 min-w-0",children:[e.jsx(l,{kind:f[s.severity],children:s.severity.toUpperCase()}),e.jsx("span",{className:"font-medium whitespace-nowrap",children:s.title}),e.jsx("span",{className:"text-ink-1 truncate",children:s.message}),e.jsx("span",{className:"ml-auto font-mono text-[11px] text-ink-1 bg-bg-3 px-1.5 rounded-sm whitespace-nowrap",children:s.detector}),e.jsx("span",{className:"font-mono text-[11px] text-ink-2 whitespace-nowrap",children:n(s)?i(n(s)):""}),e.jsx(u,{size:"sm",variant:"ghost",onClick:()=>c.mutate(s.id),children:"Mark seen"})]},s.id))})}export{N as A,n as a};
@@ -1 +1 @@
1
- import{j as s,t as o,I as m}from"./index-B3DMfZOx.js";function d({rows:a,format:n=o,max:l,color:r="var(--color-s1)",className:i=""}){const t=l??Math.max(1,...a.map(e=>e.value));return s.jsx("div",{className:`flex flex-col gap-2.5 ${i}`,children:a.map(e=>s.jsxs("div",{className:"grid grid-cols-[minmax(0,200px)_1fr_auto] items-center gap-3 text-xs",children:[s.jsx("span",{className:"font-mono text-ink-0 truncate",title:e.name,children:e.name}),s.jsxs("div",{className:"relative h-1.5 rounded-sm bg-bg-3 overflow-hidden",children:[s.jsx("i",{"data-testid":"bar-fill",className:"absolute inset-y-0 left-0 rounded-r-sm",style:{width:`${e.value/t*100}%`,background:r}}),e.error?s.jsx("i",{"data-testid":"bar-error",className:"absolute inset-y-0 left-0",style:{width:`${e.error/t*100}%`,background:"var(--color-crit)"}}):null]}),s.jsxs("span",{className:"font-mono num text-ink-1 text-right min-w-16",children:[n(e.value),e.error?s.jsxs("span",{className:"text-crit-ink ml-2 inline-flex items-center gap-0.5",children:[s.jsx(m,{name:"x",size:9}),e.error]}):null]})]},e.name))})}export{d as B};
1
+ import{j as s,t as o,I as m}from"./index-kRaX6JLH.js";function d({rows:a,format:n=o,max:l,color:r="var(--color-s1)",className:i=""}){const t=l??Math.max(1,...a.map(e=>e.value));return s.jsx("div",{className:`flex flex-col gap-2.5 ${i}`,children:a.map(e=>s.jsxs("div",{className:"grid grid-cols-[minmax(0,200px)_1fr_auto] items-center gap-3 text-xs",children:[s.jsx("span",{className:"font-mono text-ink-0 truncate",title:e.name,children:e.name}),s.jsxs("div",{className:"relative h-1.5 rounded-sm bg-bg-3 overflow-hidden",children:[s.jsx("i",{"data-testid":"bar-fill",className:"absolute inset-y-0 left-0 rounded-r-sm",style:{width:`${e.value/t*100}%`,background:r}}),e.error?s.jsx("i",{"data-testid":"bar-error",className:"absolute inset-y-0 left-0",style:{width:`${e.error/t*100}%`,background:"var(--color-crit)"}}):null]}),s.jsxs("span",{className:"font-mono num text-ink-1 text-right min-w-16",children:[n(e.value),e.error?s.jsxs("span",{className:"text-crit-ink ml-2 inline-flex items-center gap-0.5",children:[s.jsx(m,{name:"x",size:9}),e.error]}):null]})]},e.name))})}export{d as B};
@@ -1 +1 @@
1
- import{j as o,I as a}from"./index-B3DMfZOx.js";const s={warn:"text-warn bg-warn/10 border-warn/25",crit:"text-crit-ink bg-crit/12 border-crit/30",info:"text-s1 bg-s1/12 border-s1/30",good:"text-good bg-good/12 border-good/30",mute:"text-ink-1 bg-bg-3 border-line-2"},c={warn:"warn",crit:"x",info:"info",good:"check"};function x({kind:t,children:e,icon:r=!0,className:n=""}){const i=c[t];return o.jsxs("span",{className:`inline-flex items-center gap-1.5 h-5 px-2 rounded-sm text-[11px] font-medium font-mono border whitespace-nowrap ${s[t]} ${n}`,children:[r&&i&&o.jsx(a,{name:i,size:11}),e]})}const d={default:"bg-bg-2 border-line-2 text-ink-0 hover:border-accent",primary:"bg-accent border-accent text-[#1a0f06]",ghost:"bg-transparent border-line-2 text-ink-0 hover:border-accent",danger:"bg-transparent border-crit text-crit-ink"};function g({variant:t="default",size:e="md",className:r="",...n}){return o.jsx("button",{type:"button",...n,className:`inline-flex items-center gap-1.5 ${e==="sm"?"h-6 px-2 text-[11px]":"h-7 px-2.5 text-xs"} rounded-md border font-medium whitespace-nowrap disabled:opacity-50 ${d[t]} ${r}`})}export{g as B,x as P};
1
+ import{j as o,I as a}from"./index-kRaX6JLH.js";const s={warn:"text-warn bg-warn/10 border-warn/25",crit:"text-crit-ink bg-crit/12 border-crit/30",info:"text-s1 bg-s1/12 border-s1/30",good:"text-good bg-good/12 border-good/30",mute:"text-ink-1 bg-bg-3 border-line-2"},c={warn:"warn",crit:"x",info:"info",good:"check"};function x({kind:t,children:e,icon:r=!0,className:n=""}){const i=c[t];return o.jsxs("span",{className:`inline-flex items-center gap-1.5 h-5 px-2 rounded-sm text-[11px] font-medium font-mono border whitespace-nowrap ${s[t]} ${n}`,children:[r&&i&&o.jsx(a,{name:i,size:11}),e]})}const d={default:"bg-bg-2 border-line-2 text-ink-0 hover:border-accent",primary:"bg-accent border-accent text-[#1a0f06]",ghost:"bg-transparent border-line-2 text-ink-0 hover:border-accent",danger:"bg-transparent border-crit text-crit-ink"};function g({variant:t="default",size:e="md",className:r="",...n}){return o.jsx("button",{type:"button",...n,className:`inline-flex items-center gap-1.5 ${e==="sm"?"h-6 px-2 text-[11px]":"h-7 px-2.5 text-xs"} rounded-md border font-medium whitespace-nowrap disabled:opacity-50 ${d[t]} ${r}`})}export{g as B,x as P};
@@ -1 +1 @@
1
- import{j as e,r as n}from"./index-B3DMfZOx.js";import{C as o}from"./Chip-CIL0lYXp.js";function x({columns:s,rows:a}){return e.jsx("div",{className:"overflow-auto max-h-72",children:e.jsxs("table",{className:"w-full border-collapse",children:[e.jsx("thead",{children:e.jsx("tr",{children:s.map((t,r)=>e.jsx("th",{className:`text-[10px] tracking-[0.08em] text-ink-2 font-medium px-3 py-2 border-b border-line bg-bg-1 sticky top-0 whitespace-nowrap ${r?"text-right":"text-left"}`,children:t},t))})}),e.jsx("tbody",{children:a.map((t,r)=>e.jsx("tr",{children:t.map((l,i)=>e.jsx("td",{className:`px-3 h-8 border-b border-line text-xs whitespace-nowrap ${i?"text-right font-mono num":"font-mono text-ink-1"}`,children:l},i))},r))})]})})}function h({chart:s,table:a}){const[t,r]=n.useState(!1);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(o,{active:t,onClick:()=>r(!t),children:"Table"})}),t?e.jsx(x,{...a}):s]})}export{h as C,x as a};
1
+ import{j as e,r as n}from"./index-kRaX6JLH.js";import{C as o}from"./Chip-C_zmBEC6.js";function x({columns:s,rows:a}){return e.jsx("div",{className:"overflow-auto max-h-72",children:e.jsxs("table",{className:"w-full border-collapse",children:[e.jsx("thead",{children:e.jsx("tr",{children:s.map((t,r)=>e.jsx("th",{className:`text-[10px] tracking-[0.08em] text-ink-2 font-medium px-3 py-2 border-b border-line bg-bg-1 sticky top-0 whitespace-nowrap ${r?"text-right":"text-left"}`,children:t},t))})}),e.jsx("tbody",{children:a.map((t,r)=>e.jsx("tr",{children:t.map((l,i)=>e.jsx("td",{className:`px-3 h-8 border-b border-line text-xs whitespace-nowrap ${i?"text-right font-mono num":"font-mono text-ink-1"}`,children:l},i))},r))})]})})}function h({chart:s,table:a}){const[t,r]=n.useState(!1);return e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsx("div",{className:"flex justify-end",children:e.jsx(o,{active:t,onClick:()=>r(!t),children:"Table"})}),t?e.jsx(x,{...a}):s]})}export{h as C,x as a};
@@ -1 +1 @@
1
- import{j as t,I as a}from"./index-B3DMfZOx.js";function i({active:e=!1,onClick:n,children:r,caret:s=!1}){return t.jsxs("button",{type:"button",onClick:n,"aria-pressed":e,className:`inline-flex items-center gap-1.5 h-6 px-2 rounded-md border text-[11px] whitespace-nowrap ${e?"border-accent text-accent-ink bg-accent/12":"border-line-2 text-ink-1 bg-bg-2 hover:text-ink-0"}`,children:[r,s&&t.jsx(a,{name:"chevron",size:10})]})}export{i as C};
1
+ import{j as t,I as a}from"./index-kRaX6JLH.js";function i({active:e=!1,onClick:n,children:r,caret:s=!1}){return t.jsxs("button",{type:"button",onClick:n,"aria-pressed":e,className:`inline-flex items-center gap-1.5 h-6 px-2 rounded-md border text-[11px] whitespace-nowrap ${e?"border-accent text-accent-ink bg-accent/12":"border-line-2 text-ink-1 bg-bg-2 hover:text-ink-0"}`,children:[r,s&&t.jsx(a,{name:"chevron",size:10})]})}export{i as C};
@@ -1 +1 @@
1
- import{j as n}from"./index-B3DMfZOx.js";function l({options:e,value:r,onChange:a}){return n.jsx("div",{role:"tablist",className:"inline-flex border border-line-2 rounded-md overflow-hidden font-mono text-[11px]",children:e.map(t=>n.jsx("button",{role:"tab",type:"button","aria-selected":t.value===r,onClick:()=>a(t.value),className:`px-2.5 py-[5px] whitespace-nowrap ${t.value===r?"bg-bg-3 text-ink-0":"text-ink-1 hover:text-ink-0"}`,children:t.label},t.value))})}const s=({error:e})=>n.jsxs("div",{role:"alert",className:"border border-crit/40 bg-crit/8 rounded-md p-3 text-xs text-ink-1",children:[n.jsx("span",{className:"text-crit-ink font-medium",children:"Could not load."})," ",e instanceof Error?e.message:String(e)]});export{s as E,l as S};
1
+ import{j as n}from"./index-kRaX6JLH.js";function l({options:e,value:r,onChange:a}){return n.jsx("div",{role:"tablist",className:"inline-flex border border-line-2 rounded-md overflow-hidden font-mono text-[11px]",children:e.map(t=>n.jsx("button",{role:"tab",type:"button","aria-selected":t.value===r,onClick:()=>a(t.value),className:`px-2.5 py-[5px] whitespace-nowrap ${t.value===r?"bg-bg-3 text-ink-0":"text-ink-1 hover:text-ink-0"}`,children:t.label},t.value))})}const s=({error:e})=>n.jsxs("div",{role:"alert",className:"border border-crit/40 bg-crit/8 rounded-md p-3 text-xs text-ink-1",children:[n.jsx("span",{className:"text-crit-ink font-medium",children:"Could not load."})," ",e instanceof Error?e.message:String(e)]});export{s as E,l as S};
@@ -1 +1 @@
1
- import{r as u,u as _,f as P,j as s,W as $,S as j,e as p,t as C,n as E}from"./index-B3DMfZOx.js";import{T as b,a as f,P as m}from"./Panel-NdM4AeT3.js";import{E as O,S as y}from"./ErrorPanel-JuK3IhI4.js";import{B as k}from"./Bars-DGflHvWv.js";import{S as W}from"./StackedColumns-1_v1JDXl.js";import{M as B}from"./MultiLine-PWsvBuFC.js";import{a as v}from"./ChartTable-DnQkfC-d.js";import{p as g}from"./rollups-Dqiwg3gD.js";import{d as D,w as z}from"./windows-B3y4OLGl.js";import{t as A,s as F}from"./series-BjP-80tt.js";import"./uplotTheme-eHUsIKi3.js";import"./AreaLine-DULy1vR8.js";import"./Chip-CIL0lYXp.js";function Z(){const[d,M]=u.useState("30d"),[x,S]=u.useState("lines"),a=_(d),n=z(d),N=n!=null?"day":"week",c=P(N,"model"),l=u.useMemo(()=>Object.keys({...a.data?.tokens_by_model,...a.data?.cost_by_model}).map(e=>({model:e,tokens:a.data?.tokens_by_model[e]??0,cost:a.data?.cost_by_model[e]??0})).sort((e,t)=>t.cost-e.cost),[a.data]),o=u.useMemo(()=>{if(!c.data)return null;const e=n!=null?new Set(D(new Date,n)):null,t=e?c.data.points.filter(i=>e.has(i.bucket)):c.data.points.slice(-26),r=A(t,"tokens"),T=F(r.rows);return{labels:r.labels,raw:r.names.map((i,h)=>({name:i,values:r.rows[h]})),pct:r.names.map((i,h)=>({name:i,values:T[h]}))}},[c.data,n]),w=l.reduce((e,t)=>e+t.cost,0);return a.error?s.jsxs(s.Fragment,{children:[s.jsx(b,{crumbs:["Analyze","Models"]}),s.jsx(f,{children:s.jsx(O,{error:a.error})})]}):s.jsxs(s.Fragment,{children:[s.jsx(b,{crumbs:["Analyze","Models"],children:s.jsx(y,{options:$.map(e=>({value:e,label:e})),value:d,onChange:M})}),s.jsxs(f,{children:[s.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[s.jsx(m,{title:"Tokens by model",children:a.data?l.length?s.jsx(k,{rows:l.map(e=>({name:e.model,value:e.tokens}))}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"160px"})}),s.jsx(m,{title:"Estimated cost by model",children:a.data?l.length?s.jsx(k,{rows:l.map(e=>({name:e.model,value:e.cost})),format:p,color:"#285a95"}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"160px"})})]}),s.jsx(m,{title:"Price efficiency",sub:"$ per million tokens, as experienced in this window",children:l.some(e=>e.tokens>0)?s.jsx(k,{rows:l.filter(e=>e.tokens>0).map(e=>({name:e.model,value:g(e.cost,e.tokens)??0})),format:p,color:"#3173c4"}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."})}),s.jsx(m,{title:n!=null?"Model share by day":"Model share by week",sub:`% of each ${n!=null?"day":"week"}'s fresh + output tokens · last ${d}`,right:s.jsx(y,{options:[{value:"lines",label:"lines"},{value:"columns",label:"columns"},{value:"table",label:"table"}],value:x,onChange:S}),children:o?o.raw.length?x==="lines"?s.jsx(B,{labels:o.labels,series:o.pct,share:!0,height:240}):x==="columns"?s.jsx(W,{labels:o.labels,series:o.raw,share:!0,format:C}):s.jsx(v,{columns:[n!=null?"day":"week",...o.raw.map(e=>e.name)],rows:o.labels.map((e,t)=>[e,...o.pct.map(r=>`${Math.round((r.values[t]??0)*100)}%`)])}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"240px"})}),s.jsx(m,{title:"Per-model details",padded:!1,children:s.jsx(v,{columns:["model","tokens","est. cost","$ / M tokens","share of cost"],rows:l.map(e=>{const t=g(e.cost,e.tokens);return[e.model,E(e.tokens),p(e.cost),t==null?"—":p(t),w?`${Math.round(e.cost/w*100)}%`:"—"]})})})]})]})}export{Z as default};
1
+ import{r as u,u as _,f as P,j as s,W as $,S as j,e as p,t as C,n as E}from"./index-kRaX6JLH.js";import{T as b,a as f,P as m}from"./Panel-rzVYig0L.js";import{E as O,S as y}from"./ErrorPanel-lb1Tt_Cg.js";import{B as k}from"./Bars-CwquOD-V.js";import{S as W}from"./StackedColumns-Di1FeFpF.js";import{M as B}from"./MultiLine-Bp4Mitsq.js";import{a as v}from"./ChartTable-iQFTYj1d.js";import{p as g}from"./rollups-Dqiwg3gD.js";import{d as D,w as z}from"./windows-B3y4OLGl.js";import{t as A,s as F}from"./series-BjP-80tt.js";import"./uplotTheme-Dv4lAb8e.js";import"./AreaLine-BKfPVgnO.js";import"./Chip-C_zmBEC6.js";function Z(){const[d,M]=u.useState("30d"),[x,S]=u.useState("lines"),a=_(d),n=z(d),N=n!=null?"day":"week",c=P(N,"model"),l=u.useMemo(()=>Object.keys({...a.data?.tokens_by_model,...a.data?.cost_by_model}).map(e=>({model:e,tokens:a.data?.tokens_by_model[e]??0,cost:a.data?.cost_by_model[e]??0})).sort((e,t)=>t.cost-e.cost),[a.data]),o=u.useMemo(()=>{if(!c.data)return null;const e=n!=null?new Set(D(new Date,n)):null,t=e?c.data.points.filter(i=>e.has(i.bucket)):c.data.points.slice(-26),r=A(t,"tokens"),T=F(r.rows);return{labels:r.labels,raw:r.names.map((i,h)=>({name:i,values:r.rows[h]})),pct:r.names.map((i,h)=>({name:i,values:T[h]}))}},[c.data,n]),w=l.reduce((e,t)=>e+t.cost,0);return a.error?s.jsxs(s.Fragment,{children:[s.jsx(b,{crumbs:["Analyze","Models"]}),s.jsx(f,{children:s.jsx(O,{error:a.error})})]}):s.jsxs(s.Fragment,{children:[s.jsx(b,{crumbs:["Analyze","Models"],children:s.jsx(y,{options:$.map(e=>({value:e,label:e})),value:d,onChange:M})}),s.jsxs(f,{children:[s.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[s.jsx(m,{title:"Tokens by model",children:a.data?l.length?s.jsx(k,{rows:l.map(e=>({name:e.model,value:e.tokens}))}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"160px"})}),s.jsx(m,{title:"Estimated cost by model",children:a.data?l.length?s.jsx(k,{rows:l.map(e=>({name:e.model,value:e.cost})),format:p,color:"#285a95"}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"160px"})})]}),s.jsx(m,{title:"Price efficiency",sub:"$ per million tokens, as experienced in this window",children:l.some(e=>e.tokens>0)?s.jsx(k,{rows:l.filter(e=>e.tokens>0).map(e=>({name:e.model,value:g(e.cost,e.tokens)??0})),format:p,color:"#3173c4"}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."})}),s.jsx(m,{title:n!=null?"Model share by day":"Model share by week",sub:`% of each ${n!=null?"day":"week"}'s fresh + output tokens · last ${d}`,right:s.jsx(y,{options:[{value:"lines",label:"lines"},{value:"columns",label:"columns"},{value:"table",label:"table"}],value:x,onChange:S}),children:o?o.raw.length?x==="lines"?s.jsx(B,{labels:o.labels,series:o.pct,share:!0,height:240}):x==="columns"?s.jsx(W,{labels:o.labels,series:o.raw,share:!0,format:C}):s.jsx(v,{columns:[n!=null?"day":"week",...o.raw.map(e=>e.name)],rows:o.labels.map((e,t)=>[e,...o.pct.map(r=>`${Math.round((r.values[t]??0)*100)}%`)])}):s.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}):s.jsx(j,{w:"100%",h:"240px"})}),s.jsx(m,{title:"Per-model details",padded:!1,children:s.jsx(v,{columns:["model","tokens","est. cost","$ / M tokens","share of cost"],rows:l.map(e=>{const t=g(e.cost,e.tokens);return[e.model,E(e.tokens),p(e.cost),t==null?"—":p(t),w?`${Math.round(e.cost/w*100)}%`:"—"]})})})]})]})}export{Z as default};
@@ -0,0 +1 @@
1
+ import{j as i}from"./index-kRaX6JLH.js";import{A as o}from"./AreaLine-BKfPVgnO.js";const e=s=>i.jsx(o,{...s,fill:!1});export{e as M};
@@ -1 +1 @@
1
- import{j as e,p as O,t as k,u as A,a as M,b as B,r as p,c as C,s as H,d as K,e as $,L,f as z,W as J,n as g,S as T}from"./index-B3DMfZOx.js";import{P as w,T as W,a as R}from"./Panel-NdM4AeT3.js";import{E as G,S as U}from"./ErrorPanel-JuK3IhI4.js";import{d as N,T as _}from"./Tile-C4mpgbF2.js";import{C as q}from"./Chip-CIL0lYXp.js";import{A as Q}from"./AreaLine-DULy1vR8.js";import{B as V}from"./Bars-DGflHvWv.js";import{d as E,w as S,a as X}from"./windows-B3y4OLGl.js";import{C as Y}from"./ChartTable-DnQkfC-d.js";import{i as Z}from"./rollups-Dqiwg3gD.js";import{A as ee}from"./AttentionStrip-0x1TKexK.js";import{t as se}from"./series-BjP-80tt.js";import"./uplotTheme-eHUsIKi3.js";import"./Button-CaBiDq5j.js";const te=({children:t})=>e.jsx("kbd",{className:"font-mono text-[10px] border border-line-2 rounded-sm px-1 text-ink-2",children:t});function ae({parts:t,className:o=""}){const a=t.reduce((n,s)=>n+s.value,0)||1;return e.jsxs("div",{className:`flex flex-col gap-2 ${o}`,children:[e.jsx("div",{className:"flex h-2 rounded-sm overflow-hidden gap-[2px] bg-bg-0",children:t.map(n=>e.jsx("i",{style:{width:`${n.value/a*100}%`,background:n.color}},n.name))}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-ink-1",children:t.map(n=>e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("b",{className:"w-2 h-2 rounded-[2px] inline-block",style:{background:n.color}}),n.name," ",e.jsx("span",{className:"font-mono text-ink-0",children:O(n.value/a,0)})]},n.name))})]})}const D=["#141a24","#1f3c63","#285a95","#3173c4","#3987e5"],F=(t,o)=>t<=0?D[0]:D[Math.min(4,1+Math.floor(t/o*3.999))];function oe({byDay:t,days:o=90,end:a=new Date,className:n=""}){const s=E(a,o),l=Math.max(1,...s.map(i=>t[i]??0)),d=(new Date(s[0]+"T00:00:00").getDay()+6)%7,r=11,m=2,x=Math.ceil((o+d)/7);return e.jsxs("svg",{className:`block w-full ${n}`,width:"100%",viewBox:`0 0 ${x*(r+m)+28} ${7*(r+m)+4}`,style:{aspectRatio:`${x*(r+m)+28} / ${7*(r+m)+4}`},role:"img","aria-label":`Activity, last ${o} days`,children:[["M","W","F"].map((i,f)=>e.jsx("text",{x:0,y:f*2*(r+m)+r,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:i},i)),s.map((i,f)=>{const c=f+d,v=24+Math.floor(c/7)*(r+m),y=c%7*(r+m),b=t[i]??0;return e.jsx("rect",{"data-day":i,x:v,y,width:r,height:r,rx:2,fill:F(b,l),children:e.jsx("title",{children:`${i} · ${k(b)} tokens`})},i)})]})}function ne({matrix:t,rowLabels:o,colLabels:a,className:n=""}){const s=Math.max(1,...t.flat()),l=16,d=14,r=2,m=26;return e.jsxs("svg",{className:`block w-full ${n}`,width:"100%",viewBox:`0 0 ${m+a.length*(l+r)} ${t.length*(d+r)+14}`,style:{aspectRatio:`${m+a.length*(l+r)} / ${t.length*(d+r)+14}`},role:"img","aria-label":"Sessions by weekday and hour",children:[o.map((x,i)=>e.jsx("text",{x:0,y:i*(d+r)+d-3,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:x},x)),a.map((x,i)=>i%3===0?e.jsx("text",{x:m+i*(l+r),y:t.length*(d+r)+10,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:x},x):null),t.map((x,i)=>x.map((f,c)=>e.jsx("rect",{x:m+c*(l+r),y:i*(d+r),width:l,height:d,rx:2,fill:F(f,s),children:e.jsx("title",{children:`${o[i]} ${a[c]}:00 · ${f}`})},`${i}-${c}`)))]})}const I={tokens:null,cost:null,sessions:null,errorRate:null};function re(t,o,a,n){if(S(o)==null||!t.prior_window)return I;const s=t.prior_window;let l=null;if(a&&n){const d=a.total_calls?a.total_errors/a.total_calls:0,r=n.total_calls-a.total_calls,m=n.total_errors-a.total_errors,x=r>0?m/r:null;l=x==null?null:{abs:d-x,pct:x?(d-x)/x:null,dir:d>x?"up":d<x?"down":"flat"}}return{tokens:N(t.total_tokens,s.tokens),cost:N(t.total_cost_usd,s.cost_usd),sessions:N(t.session_count,s.sessions),errorRate:l}}function le(t,o=new Date){const a=A(t),n=M(t),s=M(X(t)),l=B(),d=p.useMemo(()=>a.data?re(a.data,t,n.data,s.data):I,[a.data,n.data,s.data,t]),r=p.useMemo(()=>l.data?Z(l.data,t,o):[],[l.data,t]);return{cur:a.data,tiles:d,tools:n.data,sessionsInWindow:r,allSessions:l.data??[],isLoading:a.isLoading,error:a.error??n.error??l.error}}const ie=["STARTED","PROJECT","MODEL","TOKENS","EST. COST"];function ce({rows:t}){const o=Math.max(1,...t.map(s=>s.window_tokens)),a=C(),n=s=>a({to:"/sessions/$id",params:{id:s},search:{tab:"overview"}});return e.jsx(w,{title:"Top sessions",sub:"by tokens in window",right:e.jsx(L,{to:"/sessions",className:"text-[11px]",children:"All sessions →"}),padded:!1,children:e.jsxs("table",{className:"w-full border-collapse",children:[e.jsx("thead",{children:e.jsx("tr",{children:ie.map((s,l)=>e.jsx("th",{className:`text-[10px] tracking-[0.08em] text-ink-2 font-medium px-3 py-2 border-b border-line ${l>=3?"text-right":"text-left"} ${l===3?"w-56":""}`,children:s},s))})}),e.jsxs("tbody",{children:[t.slice(0,8).map(s=>e.jsxs("tr",{className:"hover:bg-bg-2 cursor-pointer",onClick:()=>n(s.id),onKeyDown:l=>l.key==="Enter"&&n(s.id),tabIndex:0,children:[e.jsxs("td",{className:"px-3 h-[34px] border-b border-line font-mono text-xs whitespace-nowrap",children:[e.jsx("span",{className:"text-ink-0",children:H(s.started_at)}),s.days_active>1&&e.jsxs("span",{className:"text-ink-2 text-[10px] ml-1",children:["+",s.days_active-1,"d"]})]}),e.jsx("td",{className:"px-3 border-b border-line font-mono text-xs text-ink-1 truncate max-w-[360px]",title:s.project_path,children:K(s.project_path)}),e.jsx("td",{className:"px-3 border-b border-line",children:e.jsx("span",{className:"font-mono text-[11.5px] text-ink-1 bg-bg-3 px-1.5 rounded-sm",children:s.primary_model})}),e.jsx("td",{className:"px-3 border-b border-line",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-1.5 flex-1 rounded-sm bg-bg-3 overflow-hidden",children:e.jsx("i",{className:"absolute inset-y-0 left-0 bg-s1 rounded-r-sm",style:{width:`${s.window_tokens/o*100}%`}})}),e.jsx("span",{className:"font-mono num text-xs w-14 text-right",children:k(s.window_tokens)})]})}),e.jsx("td",{className:"px-3 border-b border-line text-right font-mono num text-xs",children:$(s.window_cost_usd)})]},s.id)),t.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"text-center text-ink-2 py-8",children:"No sessions in this window."})})]})]})})}function de(t){const o={fresh:0,cacheWrite:0,cacheRead:0,output:0,total:0};for(const a of t)o.fresh+=a.total_fresh_input_tokens,o.cacheWrite+=a.total_cache_write_tokens,o.cacheRead+=a.total_cache_read_tokens,o.output+=a.total_output_tokens;return o.total=o.fresh+o.cacheWrite+o.cacheRead+o.output,o}function xe(t,o=()=>1){const a=Array.from({length:7},()=>Array(24).fill(0));for(const n of t){const s=new Date(n.started_at),l=(s.getDay()+6)%7;a[l][s.getHours()]+=o(n)}return a}const me=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],ue=Array.from({length:24},(t,o)=>String(o).padStart(2,"0"));function Me(){const[t,o]=p.useState("7d"),[a,n]=p.useState(!1),s=le(t),l=A("all"),d=z("day","model"),r=p.useMemo(()=>{const u=S(t);return u?E(new Date,u):Object.keys(s.cur?.tokens_by_day??{}).sort()},[t,s.cur]),m=p.useMemo(()=>{if(a&&d.data){const u=d.data.points.filter(j=>r.includes(j.bucket)),h=se(u,"tokens");return{labels:h.labels,series:h.names.map((j,P)=>({name:j,values:h.rows[P]}))}}return{labels:r,series:[{name:"tokens",values:r.map(u=>s.cur?.tokens_by_day[u]??0)}]}},[a,d.data,r,s.cur]),x=p.useMemo(()=>Object.entries(s.cur?.tokens_by_model??{}).map(([u,h])=>({name:u,value:h})).sort((u,h)=>h.value-u.value),[s.cur]),i=p.useMemo(()=>de(s.sessionsInWindow),[s.sessionsInWindow]),f=p.useMemo(()=>xe(s.sessionsInWindow),[s.sessionsInWindow]);if(s.error)return e.jsxs(e.Fragment,{children:[e.jsx(W,{crumbs:["Monitor","Overview"]}),e.jsx(R,{children:e.jsx(G,{error:s.error})})]});const c=s.cur,v=S(t),y=c&&c.session_count?Math.round(c.total_tokens/c.session_count):0,b=s.tools?s.tools.total_calls?s.tools.total_errors/s.tools.total_calls:0:null;return e.jsxs(e.Fragment,{children:[e.jsxs(W,{crumbs:["Monitor","Overview"],children:[e.jsx(U,{options:J.map(u=>({value:u,label:u})),value:t,onChange:o}),e.jsxs("span",{className:"text-ink-2 text-xs flex items-center gap-2",children:["Jump anywhere ",e.jsx(te,{children:"Ctrl K"})]})]}),e.jsxs(R,{children:[e.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[e.jsx(_,{label:"Tokens",value:c?k(c.total_tokens):"—",delta:s.tiles.tokens,sub:"vs prior window",note:c?`${k(y)} / session`:void 0}),e.jsx(_,{label:"Estimated cost",value:c?$(c.total_cost_usd):"—",delta:s.tiles.cost,upIsBad:!0,sub:"vs prior window",note:c&&v?`${$(c.total_cost_usd/v)} / day`:void 0}),e.jsx(_,{label:"Sessions",value:c?g(c.session_count):"—",delta:s.tiles.sessions,sub:"vs prior window"}),e.jsx(_,{label:"Tool error rate",value:b==null?"—":O(b),delta:s.tiles.errorRate,upIsBad:!0,fmt:u=>`${u.abs>=0?"+":"−"}${(Math.abs(u.abs)*100).toFixed(1)} pt`,sub:s.tools?`${g(s.tools.total_errors)} of ${g(s.tools.total_calls)} calls`:void 0})]}),e.jsx(ee,{}),e.jsxs("div",{className:"grid grid-cols-[2fr_1fr] gap-3",children:[e.jsx(w,{title:"Tokens per day",sub:a?"fresh + output, by model":"all token kinds",right:e.jsx(q,{active:a,onClick:()=>n(!a),children:"Stack by model"}),children:c?e.jsx(Y,{chart:e.jsx(Q,{labels:m.labels,series:m.series,stacked:a}),table:{columns:["day",...m.series.map(u=>u.name)],rows:m.labels.map((u,h)=>[u,...m.series.map(j=>g(j.values[h]??0))])}}):e.jsx(T,{w:"100%",h:"220px"})}),e.jsxs(w,{title:"Models",sub:"share of tokens",children:[x.length?e.jsx(V,{rows:x}):e.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}),e.jsx("div",{className:"mt-auto pt-3 border-t border-line",children:e.jsx(ae,{parts:[{name:"cache read",value:i.cacheRead,color:"#3987e5"},{name:"cache write",value:i.cacheWrite,color:"#285a95"},{name:"fresh",value:i.fresh,color:"#1f3c63"},{name:"output",value:i.output,color:"#9ec5f4"}]})})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(w,{title:"Activity",sub:"last 90 days",children:l.data?e.jsx(oe,{byDay:l.data.tokens_by_day,days:90}):e.jsx(T,{w:"100%",h:"100px"})}),e.jsx(w,{title:"When you work",sub:"sessions started, by weekday × hour",children:e.jsx(ne,{matrix:f,rowLabels:me,colLabels:ue})})]}),e.jsx(ce,{rows:c?.top_sessions??[]})]})]})}export{Me as default};
1
+ import{j as e,p as O,t as k,u as A,a as M,b as B,r as p,c as C,s as H,d as K,e as $,L,f as z,W as J,n as g,S as T}from"./index-kRaX6JLH.js";import{P as w,T as W,a as R}from"./Panel-rzVYig0L.js";import{E as G,S as U}from"./ErrorPanel-lb1Tt_Cg.js";import{d as N,T as _}from"./Tile-BlnGo9bN.js";import{C as q}from"./Chip-C_zmBEC6.js";import{A as Q}from"./AreaLine-BKfPVgnO.js";import{B as V}from"./Bars-CwquOD-V.js";import{d as E,w as S,a as X}from"./windows-B3y4OLGl.js";import{C as Y}from"./ChartTable-iQFTYj1d.js";import{i as Z}from"./rollups-Dqiwg3gD.js";import{A as ee}from"./AttentionStrip-DQUV5LTN.js";import{t as se}from"./series-BjP-80tt.js";import"./uplotTheme-Dv4lAb8e.js";import"./Button-BY-h2O0Z.js";const te=({children:t})=>e.jsx("kbd",{className:"font-mono text-[10px] border border-line-2 rounded-sm px-1 text-ink-2",children:t});function ae({parts:t,className:o=""}){const a=t.reduce((n,s)=>n+s.value,0)||1;return e.jsxs("div",{className:`flex flex-col gap-2 ${o}`,children:[e.jsx("div",{className:"flex h-2 rounded-sm overflow-hidden gap-[2px] bg-bg-0",children:t.map(n=>e.jsx("i",{style:{width:`${n.value/a*100}%`,background:n.color}},n.name))}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1 text-[11px] text-ink-1",children:t.map(n=>e.jsxs("span",{className:"inline-flex items-center gap-1.5",children:[e.jsx("b",{className:"w-2 h-2 rounded-[2px] inline-block",style:{background:n.color}}),n.name," ",e.jsx("span",{className:"font-mono text-ink-0",children:O(n.value/a,0)})]},n.name))})]})}const D=["#141a24","#1f3c63","#285a95","#3173c4","#3987e5"],F=(t,o)=>t<=0?D[0]:D[Math.min(4,1+Math.floor(t/o*3.999))];function oe({byDay:t,days:o=90,end:a=new Date,className:n=""}){const s=E(a,o),l=Math.max(1,...s.map(i=>t[i]??0)),d=(new Date(s[0]+"T00:00:00").getDay()+6)%7,r=11,m=2,x=Math.ceil((o+d)/7);return e.jsxs("svg",{className:`block w-full ${n}`,width:"100%",viewBox:`0 0 ${x*(r+m)+28} ${7*(r+m)+4}`,style:{aspectRatio:`${x*(r+m)+28} / ${7*(r+m)+4}`},role:"img","aria-label":`Activity, last ${o} days`,children:[["M","W","F"].map((i,f)=>e.jsx("text",{x:0,y:f*2*(r+m)+r,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:i},i)),s.map((i,f)=>{const c=f+d,v=24+Math.floor(c/7)*(r+m),y=c%7*(r+m),b=t[i]??0;return e.jsx("rect",{"data-day":i,x:v,y,width:r,height:r,rx:2,fill:F(b,l),children:e.jsx("title",{children:`${i} · ${k(b)} tokens`})},i)})]})}function ne({matrix:t,rowLabels:o,colLabels:a,className:n=""}){const s=Math.max(1,...t.flat()),l=16,d=14,r=2,m=26;return e.jsxs("svg",{className:`block w-full ${n}`,width:"100%",viewBox:`0 0 ${m+a.length*(l+r)} ${t.length*(d+r)+14}`,style:{aspectRatio:`${m+a.length*(l+r)} / ${t.length*(d+r)+14}`},role:"img","aria-label":"Sessions by weekday and hour",children:[o.map((x,i)=>e.jsx("text",{x:0,y:i*(d+r)+d-3,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:x},x)),a.map((x,i)=>i%3===0?e.jsx("text",{x:m+i*(l+r),y:t.length*(d+r)+10,fontSize:9,fill:"#667184",fontFamily:"var(--font-mono)",children:x},x):null),t.map((x,i)=>x.map((f,c)=>e.jsx("rect",{x:m+c*(l+r),y:i*(d+r),width:l,height:d,rx:2,fill:F(f,s),children:e.jsx("title",{children:`${o[i]} ${a[c]}:00 · ${f}`})},`${i}-${c}`)))]})}const I={tokens:null,cost:null,sessions:null,errorRate:null};function re(t,o,a,n){if(S(o)==null||!t.prior_window)return I;const s=t.prior_window;let l=null;if(a&&n){const d=a.total_calls?a.total_errors/a.total_calls:0,r=n.total_calls-a.total_calls,m=n.total_errors-a.total_errors,x=r>0?m/r:null;l=x==null?null:{abs:d-x,pct:x?(d-x)/x:null,dir:d>x?"up":d<x?"down":"flat"}}return{tokens:N(t.total_tokens,s.tokens),cost:N(t.total_cost_usd,s.cost_usd),sessions:N(t.session_count,s.sessions),errorRate:l}}function le(t,o=new Date){const a=A(t),n=M(t),s=M(X(t)),l=B(),d=p.useMemo(()=>a.data?re(a.data,t,n.data,s.data):I,[a.data,n.data,s.data,t]),r=p.useMemo(()=>l.data?Z(l.data,t,o):[],[l.data,t]);return{cur:a.data,tiles:d,tools:n.data,sessionsInWindow:r,allSessions:l.data??[],isLoading:a.isLoading,error:a.error??n.error??l.error}}const ie=["STARTED","PROJECT","MODEL","TOKENS","EST. COST"];function ce({rows:t}){const o=Math.max(1,...t.map(s=>s.window_tokens)),a=C(),n=s=>a({to:"/sessions/$id",params:{id:s},search:{tab:"overview"}});return e.jsx(w,{title:"Top sessions",sub:"by tokens in window",right:e.jsx(L,{to:"/sessions",className:"text-[11px]",children:"All sessions →"}),padded:!1,children:e.jsxs("table",{className:"w-full border-collapse",children:[e.jsx("thead",{children:e.jsx("tr",{children:ie.map((s,l)=>e.jsx("th",{className:`text-[10px] tracking-[0.08em] text-ink-2 font-medium px-3 py-2 border-b border-line ${l>=3?"text-right":"text-left"} ${l===3?"w-56":""}`,children:s},s))})}),e.jsxs("tbody",{children:[t.slice(0,8).map(s=>e.jsxs("tr",{className:"hover:bg-bg-2 cursor-pointer",onClick:()=>n(s.id),onKeyDown:l=>l.key==="Enter"&&n(s.id),tabIndex:0,children:[e.jsxs("td",{className:"px-3 h-[34px] border-b border-line font-mono text-xs whitespace-nowrap",children:[e.jsx("span",{className:"text-ink-0",children:H(s.started_at)}),s.days_active>1&&e.jsxs("span",{className:"text-ink-2 text-[10px] ml-1",children:["+",s.days_active-1,"d"]})]}),e.jsx("td",{className:"px-3 border-b border-line font-mono text-xs text-ink-1 truncate max-w-[360px]",title:s.project_path,children:K(s.project_path)}),e.jsx("td",{className:"px-3 border-b border-line",children:e.jsx("span",{className:"font-mono text-[11.5px] text-ink-1 bg-bg-3 px-1.5 rounded-sm",children:s.primary_model})}),e.jsx("td",{className:"px-3 border-b border-line",children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"relative h-1.5 flex-1 rounded-sm bg-bg-3 overflow-hidden",children:e.jsx("i",{className:"absolute inset-y-0 left-0 bg-s1 rounded-r-sm",style:{width:`${s.window_tokens/o*100}%`}})}),e.jsx("span",{className:"font-mono num text-xs w-14 text-right",children:k(s.window_tokens)})]})}),e.jsx("td",{className:"px-3 border-b border-line text-right font-mono num text-xs",children:$(s.window_cost_usd)})]},s.id)),t.length===0&&e.jsx("tr",{children:e.jsx("td",{colSpan:5,className:"text-center text-ink-2 py-8",children:"No sessions in this window."})})]})]})})}function de(t){const o={fresh:0,cacheWrite:0,cacheRead:0,output:0,total:0};for(const a of t)o.fresh+=a.total_fresh_input_tokens,o.cacheWrite+=a.total_cache_write_tokens,o.cacheRead+=a.total_cache_read_tokens,o.output+=a.total_output_tokens;return o.total=o.fresh+o.cacheWrite+o.cacheRead+o.output,o}function xe(t,o=()=>1){const a=Array.from({length:7},()=>Array(24).fill(0));for(const n of t){const s=new Date(n.started_at),l=(s.getDay()+6)%7;a[l][s.getHours()]+=o(n)}return a}const me=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],ue=Array.from({length:24},(t,o)=>String(o).padStart(2,"0"));function Me(){const[t,o]=p.useState("7d"),[a,n]=p.useState(!1),s=le(t),l=A("all"),d=z("day","model"),r=p.useMemo(()=>{const u=S(t);return u?E(new Date,u):Object.keys(s.cur?.tokens_by_day??{}).sort()},[t,s.cur]),m=p.useMemo(()=>{if(a&&d.data){const u=d.data.points.filter(j=>r.includes(j.bucket)),h=se(u,"tokens");return{labels:h.labels,series:h.names.map((j,P)=>({name:j,values:h.rows[P]}))}}return{labels:r,series:[{name:"tokens",values:r.map(u=>s.cur?.tokens_by_day[u]??0)}]}},[a,d.data,r,s.cur]),x=p.useMemo(()=>Object.entries(s.cur?.tokens_by_model??{}).map(([u,h])=>({name:u,value:h})).sort((u,h)=>h.value-u.value),[s.cur]),i=p.useMemo(()=>de(s.sessionsInWindow),[s.sessionsInWindow]),f=p.useMemo(()=>xe(s.sessionsInWindow),[s.sessionsInWindow]);if(s.error)return e.jsxs(e.Fragment,{children:[e.jsx(W,{crumbs:["Monitor","Overview"]}),e.jsx(R,{children:e.jsx(G,{error:s.error})})]});const c=s.cur,v=S(t),y=c&&c.session_count?Math.round(c.total_tokens/c.session_count):0,b=s.tools?s.tools.total_calls?s.tools.total_errors/s.tools.total_calls:0:null;return e.jsxs(e.Fragment,{children:[e.jsxs(W,{crumbs:["Monitor","Overview"],children:[e.jsx(U,{options:J.map(u=>({value:u,label:u})),value:t,onChange:o}),e.jsxs("span",{className:"text-ink-2 text-xs flex items-center gap-2",children:["Jump anywhere ",e.jsx(te,{children:"Ctrl K"})]})]}),e.jsxs(R,{children:[e.jsxs("div",{className:"grid grid-cols-4 gap-3",children:[e.jsx(_,{label:"Tokens",value:c?k(c.total_tokens):"—",delta:s.tiles.tokens,sub:"vs prior window",note:c?`${k(y)} / session`:void 0}),e.jsx(_,{label:"Estimated cost",value:c?$(c.total_cost_usd):"—",delta:s.tiles.cost,upIsBad:!0,sub:"vs prior window",note:c&&v?`${$(c.total_cost_usd/v)} / day`:void 0}),e.jsx(_,{label:"Sessions",value:c?g(c.session_count):"—",delta:s.tiles.sessions,sub:"vs prior window"}),e.jsx(_,{label:"Tool error rate",value:b==null?"—":O(b),delta:s.tiles.errorRate,upIsBad:!0,fmt:u=>`${u.abs>=0?"+":"−"}${(Math.abs(u.abs)*100).toFixed(1)} pt`,sub:s.tools?`${g(s.tools.total_errors)} of ${g(s.tools.total_calls)} calls`:void 0})]}),e.jsx(ee,{}),e.jsxs("div",{className:"grid grid-cols-[2fr_1fr] gap-3",children:[e.jsx(w,{title:"Tokens per day",sub:a?"fresh + output, by model":"all token kinds",right:e.jsx(q,{active:a,onClick:()=>n(!a),children:"Stack by model"}),children:c?e.jsx(Y,{chart:e.jsx(Q,{labels:m.labels,series:m.series,stacked:a}),table:{columns:["day",...m.series.map(u=>u.name)],rows:m.labels.map((u,h)=>[u,...m.series.map(j=>g(j.values[h]??0))])}}):e.jsx(T,{w:"100%",h:"220px"})}),e.jsxs(w,{title:"Models",sub:"share of tokens",children:[x.length?e.jsx(V,{rows:x}):e.jsx("div",{className:"text-ink-2 text-center py-6",children:"No data."}),e.jsx("div",{className:"mt-auto pt-3 border-t border-line",children:e.jsx(ae,{parts:[{name:"cache read",value:i.cacheRead,color:"#3987e5"},{name:"cache write",value:i.cacheWrite,color:"#285a95"},{name:"fresh",value:i.fresh,color:"#1f3c63"},{name:"output",value:i.output,color:"#9ec5f4"}]})})]})]}),e.jsxs("div",{className:"grid grid-cols-2 gap-3",children:[e.jsx(w,{title:"Activity",sub:"last 90 days",children:l.data?e.jsx(oe,{byDay:l.data.tokens_by_day,days:90}):e.jsx(T,{w:"100%",h:"100px"})}),e.jsx(w,{title:"When you work",sub:"sessions started, by weekday × hour",children:e.jsx(ne,{matrix:f,rowLabels:me,colLabels:ue})})]}),e.jsx(ce,{rows:c?.top_sessions??[]})]})]})}export{Me as default};
@@ -1 +1 @@
1
- import{j as e,L as i}from"./index-B3DMfZOx.js";function o({crumbs:n,children:a}){return e.jsxs("div",{className:"h-12 shrink-0 border-b border-line flex items-center gap-3 px-5 bg-bg-1",children:[e.jsx("span",{className:"text-[13px] text-ink-1 flex items-center gap-1.5 min-w-0",children:n.map((s,l)=>e.jsxs("span",{className:"flex items-center gap-1.5 min-w-0",children:[l>0&&e.jsx("span",{children:"/"}),typeof s=="string"?l===n.length-1?e.jsx("b",{className:"text-ink-0 font-semibold truncate",children:s}):e.jsx("span",{children:s}):e.jsx(i,{to:s.to,className:"text-ink-1 hover:text-ink-0",children:s.label})]},l))}),e.jsx("div",{className:"ml-auto flex items-center gap-2",children:a})]})}const c=({children:n,row:a=!1})=>e.jsx("div",{id:"page-scroll",className:`p-5 flex ${a?"flex-row":"flex-col"} gap-4 flex-1 min-h-0 overflow-auto ${a?"":"[&>*]:shrink-0"}`,children:n});function m({title:n,sub:a,right:s,children:l,className:t="",padded:r=!0}){return e.jsxs("section",{className:`bg-bg-1 border border-line rounded-md flex flex-col overflow-hidden min-w-0 ${t}`,children:[n&&e.jsxs("header",{className:"flex items-center gap-2.5 h-9 px-3.5 border-b border-line shrink-0",children:[e.jsx("h3",{className:"m-0 text-xs font-semibold text-ink-0 whitespace-nowrap",children:n}),a&&e.jsx("span",{className:"text-[11px] text-ink-2 font-mono truncate",children:a}),s&&e.jsx("div",{className:"ml-auto flex items-center gap-1.5",children:s})]}),e.jsx("div",{className:`${r?"p-3.5":""} min-h-0 flex-1 flex flex-col`,children:l})]})}export{m as P,o as T,c as a};
1
+ import{j as e,L as i}from"./index-kRaX6JLH.js";function o({crumbs:n,children:a}){return e.jsxs("div",{className:"h-12 shrink-0 border-b border-line flex items-center gap-3 px-5 bg-bg-1",children:[e.jsx("span",{className:"text-[13px] text-ink-1 flex items-center gap-1.5 min-w-0",children:n.map((s,l)=>e.jsxs("span",{className:"flex items-center gap-1.5 min-w-0",children:[l>0&&e.jsx("span",{children:"/"}),typeof s=="string"?l===n.length-1?e.jsx("b",{className:"text-ink-0 font-semibold truncate",children:s}):e.jsx("span",{children:s}):e.jsx(i,{to:s.to,className:"text-ink-1 hover:text-ink-0",children:s.label})]},l))}),e.jsx("div",{className:"ml-auto flex items-center gap-2",children:a})]})}const c=({children:n,row:a=!1})=>e.jsx("div",{id:"page-scroll",className:`p-5 flex ${a?"flex-row":"flex-col"} gap-4 flex-1 min-h-0 overflow-auto ${a?"":"[&>*]:shrink-0"}`,children:n});function m({title:n,sub:a,right:s,children:l,className:t="",padded:r=!0}){return e.jsxs("section",{className:`bg-bg-1 border border-line rounded-md flex flex-col overflow-hidden min-w-0 ${t}`,children:[n&&e.jsxs("header",{className:"flex items-center gap-2.5 h-9 px-3.5 border-b border-line shrink-0",children:[e.jsx("h3",{className:"m-0 text-xs font-semibold text-ink-0 whitespace-nowrap",children:n}),a&&e.jsx("span",{className:"text-[11px] text-ink-2 font-mono truncate",children:a}),s&&e.jsx("div",{className:"ml-auto flex items-center gap-1.5",children:s})]}),e.jsx("div",{className:`${r?"p-3.5":""} min-h-0 flex-1 flex flex-col`,children:l})]})}export{m as P,o as T,c as a};
@@ -0,0 +1 @@
1
+ import{j as e,r as i,k as I,l as P,m as E,o as F,q as L,v as T,I as $,d as b,L as C}from"./index-kRaX6JLH.js";import{T as D,a as M,P as O}from"./Panel-rzVYig0L.js";import{C as N}from"./Chip-C_zmBEC6.js";import{P as y,B as q}from"./Button-BY-h2O0Z.js";import{d as B}from"./windows-B3y4OLGl.js";import{a as Q,b as R}from"./agents-CDuRxAZi.js";function A({values:s,width:a=120,height:r=28,className:o=""}){if(!s.length)return null;const n=Math.max(1,...s),j=s.length>1?(a-4)/(s.length-1):0,c=s.map((x,u)=>[2+u*j,r-2-x/n*(r-4)]),k=c.map((x,u)=>`${u?"L":"M"}${x[0].toFixed(1)} ${x[1].toFixed(1)}`).join(" "),h=c[c.length-1];return e.jsxs("svg",{className:o,width:a,height:r,viewBox:`0 0 ${a} ${r}`,"aria-hidden":"true",children:[e.jsx("path",{d:k,fill:"none",stroke:"#3987e5",strokeWidth:2,strokeLinejoin:"round",strokeLinecap:"round"}),e.jsx("circle",{cx:h[0],cy:h[1],r:3,fill:"#3987e5",stroke:"#10131a",strokeWidth:2})]})}function K(s){return s.replace(/<command-(name|message|args)>[\s\S]*?<\/command-\1>/g,"").replace(/<local-command-caveat>[\s\S]*?<\/local-command-caveat>/g,"").replace(/<\/?local-command-stdout>/g,"").replace(/\s+/g," ").trim()}function Y(s){const a=[],r=/<mark>([\s\S]*?)<\/mark>/g;let o=0,n;for(;n=r.exec(s);)n.index>o&&a.push({t:s.slice(o,n.index),m:!1}),a.push({t:n[1],m:!0}),o=r.lastIndex;return o<s.length&&a.push({t:s.slice(o),m:!1}),a}const W=[{k:"prompt",l:"Your prompts"},{k:"user",l:"Your replies"},{k:"assistant",l:"Assistant"},{k:"thinking",l:"Thinking"},{k:"tool_result",l:"Tool output"}],z={prompt:"good",user:"good",assistant:"info"},G=(s,a)=>s==="assistant"?a?Q(R(a)):"assistant":s==="prompt"||s==="user"?"you":s;function X(s,a=250){const[r,o]=i.useState(s);return i.useEffect(()=>{const n=setTimeout(()=>o(s),a);return()=>clearTimeout(n)},[s,a]),r}function te(){const[s,a]=i.useState(""),[r,o]=i.useState(""),[n,j]=i.useState(["prompt","user","assistant"]),[c,k]=i.useState(!1),h=X(s),x=I().data??[],u=P(),v=E(),w=F({mutationFn:L.searchIndexEnable,onSuccess:()=>v.invalidateQueries({queryKey:["searchIndex"]})}),S=h.trim().length>=2,d=T({q:h,limit:200,project:r||void 0,includeSlash:c,roles:n},S),f=i.useMemo(()=>d.data?.results??[],[d.data]),_=i.useMemo(()=>{const t=B(new Date,30),m=Object.fromEntries(t.map(l=>[l,0]));for(const l of f){const p=new Date(l.timestamp_ms),g=`${p.getFullYear()}-${String(p.getMonth()+1).padStart(2,"0")}-${String(p.getDate()).padStart(2,"0")}`;g in m&&m[g]++}return t.map(l=>m[l])},[f]);return e.jsxs(e.Fragment,{children:[e.jsx(D,{crumbs:["Search","Transcripts"]}),e.jsxs(M,{children:[e.jsx("p",{className:"text-ink-2 text-xs m-0",children:"Searches every prompt you typed and every transcript your agents wrote. 100% local — SQLite FTS5, no embeddings, no API calls."}),u.data&&!u.data.enabled&&e.jsxs("div",{className:"flex items-center gap-3 border border-warn/30 bg-warn/8 rounded-md px-3.5 py-2.5 text-xs",children:[e.jsx(y,{kind:"warn",children:"INDEXING OFF"}),e.jsx("span",{className:"text-ink-1",children:"Only your prompts are searchable. Enable transcript indexing to search agent replies and tool output."}),e.jsx(q,{className:"ml-auto",onClick:()=>w.mutate(),children:"Enable indexing"})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("label",{className:"flex items-center gap-2 h-8 px-2.5 border border-line-2 rounded-md flex-1 min-w-72 text-ink-2",children:[e.jsx($,{name:"search",size:13}),e.jsx("input",{autoFocus:!0,value:s,onChange:t=>a(t.target.value),placeholder:"Search…",className:"bg-transparent outline-none text-ink-0 text-sm w-full placeholder:text-ink-2"})]}),e.jsxs("select",{value:r,onChange:t=>o(t.target.value),className:"h-8 bg-bg-2 border border-line-2 rounded-md text-xs text-ink-1 px-2 max-w-72",children:[e.jsx("option",{value:"",children:"All projects"}),x.map(t=>e.jsx("option",{value:t,children:b(t,60)},t))]})]}),e.jsxs("div",{className:"flex items-center gap-2 flex-wrap text-xs",children:[e.jsx("span",{className:"text-ink-2",children:"Show:"}),W.map(t=>e.jsx(N,{active:n.includes(t.k),onClick:()=>j(n.includes(t.k)?n.filter(m=>m!==t.k):[...n,t.k]),children:t.l},t.k)),e.jsx(N,{active:c,onClick:()=>k(!c),children:"Include slash commands"}),d.data&&e.jsxs("span",{className:"ml-auto flex items-center gap-3 font-mono text-[11px] text-ink-2",children:[d.data.total," matches · ",d.data.prompt_total," prompts · ",d.data.transcript_total," transcript",e.jsx("span",{title:"hits per day, last 30 days",children:e.jsx(A,{values:_})})]})]}),e.jsxs(O,{padded:!1,className:"grow",children:[f.length===0&&e.jsx("div",{className:"text-center text-ink-2 py-10",children:S?d.isFetching?"Searching…":"No matches.":"Type at least two characters to search."}),f.map((t,m)=>{const l=K(t.snippet||t.text);return l?e.jsxs("div",{className:"grid grid-cols-[90px_1fr_160px] gap-3 px-3.5 py-2.5 border-b border-line items-start",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[e.jsx(y,{kind:z[t.role]??"mute",icon:!1,children:G(t.role,t.session_id)}),e.jsx("span",{className:"font-mono text-[10px] text-ink-2",children:new Date(t.timestamp_ms).toLocaleString([],{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})})]}),e.jsxs("div",{className:"text-xs leading-relaxed break-words",children:[Y(l).map((p,g)=>p.m?e.jsx("mark",{className:"bg-accent/25 text-ink-0 rounded-sm px-0.5",children:p.t},g):e.jsx("span",{children:p.t},g)),t.pasted_chars>0&&e.jsxs("span",{className:"text-ink-2 font-mono text-[10px] ml-2",children:["+",t.pasted_chars," pasted chars"]})]}),e.jsxs("div",{className:"text-right flex flex-col gap-1 items-end min-w-0",children:[e.jsx("span",{className:"font-mono text-[11px] text-ink-2 truncate max-w-full",title:t.project_path??"",children:t.project_path?b(t.project_path):""}),t.session_id&&e.jsx(C,{to:"/sessions/$id",params:{id:t.session_id},search:{tab:"overview"},className:"text-[11px]",children:"Open session →"})]})]},m):null})]})]})]})}export{te as default};
@@ -0,0 +1,2 @@
1
+ import{r as g,j as e,I as T,t as S,R as C,n as f,T as D,L as X,p as B,e as M,P as F,S as A,U as Y,V as Z,c as G,X as J,Y as ee,d as te}from"./index-kRaX6JLH.js";import{P as w,T as L,a as q}from"./Panel-rzVYig0L.js";import{S as H,E as se}from"./ErrorPanel-lb1Tt_Cg.js";import{T as _}from"./Tile-BlnGo9bN.js";import{P as E}from"./Button-BY-h2O0Z.js";import{r as ne,b as re,c as z}from"./agents-CDuRxAZi.js";import{a as R,b as O,c as P,d as oe,e as ae,o as W,T as V,f as le}from"./TimelineTab-Cwp4_Kwm.js";import{A as ie}from"./AreaLine-BKfPVgnO.js";import{L as K}from"./uplotTheme-Dv4lAb8e.js";import{B as U}from"./Bars-CwquOD-V.js";import{C as ce}from"./Chip-C_zmBEC6.js";import"./cumulative-C3-3HW0n.js";function I({value:t,chars:a=8}){const[m,x]=g.useState(!1),d=t.includes(":")?t.slice(t.indexOf(":")+1):t,l=async()=>{try{await navigator.clipboard.writeText(d),x(!0),setTimeout(()=>x(!1),1400)}catch{window.prompt("Copy the session id",d)}};return e.jsxs("button",{type:"button",onClick:l,title:(()=>{const o=ne(re(t),d);return`Session id ${d}
2
+ Click to copy${o?` (use with: ${o})`:""}`})(),className:`inline-flex items-center gap-1.5 font-mono text-[11px] px-1.5 h-5 rounded-sm border transition-colors ${m?"text-good border-good/40 bg-good/10":"text-ink-1 bg-bg-3 border-transparent hover:border-line-2 hover:text-ink-0"}`,children:[m?e.jsx(T,{name:"check",size:10}):null,m?"copied":a?d.slice(0,a):"copy"]})}function Q({turns:t,onPick:a,active:m}){const x=Math.max(1,t.length),d=1160,l=96,o=80,u=(d-8)/x,n=Math.max(2,Math.min(46,u-3)),h=Math.max(1,...t.map(R)),b=x>60?10:5;return e.jsxs("svg",{width:"100%",viewBox:`0 0 ${d} ${l}`,role:"img","aria-label":"Tokens per turn",className:"block w-full",style:{aspectRatio:`${d} / ${l}`},children:[e.jsx("line",{x1:0,y1:o,x2:d,y2:o,stroke:"#232934"}),t.map((c,p)=>{const j=4+p*u,y=R(c)/h*70,$=O(c)/h*70,r=P(c);return e.jsxs("g",{"data-turn":c.sequence,onClick:()=>a(c.sequence),className:"cursor-pointer",children:[e.jsx("title",{children:`#${c.sequence} · ${S(O(c))} fresh+output · ${S(c.cache_read_tokens)} cache read`}),m===c.sequence&&e.jsx("rect",{x:j-2,y:2,width:n+4,height:o-2,fill:"none",stroke:"#f0883e"}),e.jsx("rect",{x:j,y:o-y,width:n,height:y,fill:"#1f3c63"}),e.jsx("rect",{"data-kind":"top",x:j,y:o-y,width:n,height:Math.max(2,$),rx:1,fill:r?"#d03b3b":"#3987e5"}),(p%b===0||p===t.length-1)&&e.jsx("text",{x:j+n/2,y:l-2,fontSize:10,textAnchor:"middle",fill:r?"#ff7a7a":"#667184",fontFamily:"var(--font-mono)",children:c.sequence})]},c.sequence)})]})}function de({session:t,turns:a}){const m=Intl.DateTimeFormat().resolvedOptions().timeZone,x=[["Project",t.project_path],["Primary model",t.primary_model],[z(t.agent),t.agent_version??"—"],["Started",`${C(t.started_at)} (${m})`],["Ended",t.ended_at?C(t.ended_at):"running"],["Fresh input",`${f(t.total_fresh_input_tokens)} tokens`],["Output",`${f(t.total_output_tokens)} tokens`],["Cache writes",`${f(t.total_cache_write_tokens)} tokens`],["Cache reads",`${f(t.total_cache_read_tokens)} tokens`],["Pricing version",t.pricing_table_version]],d=oe(a);return e.jsxs("div",{className:"grid grid-cols-[1fr_1fr] gap-3",children:[e.jsx(w,{title:"Session",padded:!1,children:e.jsxs("dl",{className:"grid grid-cols-[140px_1fr] text-xs m-0",children:[x.map(([l,o])=>e.jsxs("div",{className:"contents",children:[e.jsx("dt",{className:"px-3.5 py-2 border-b border-line text-ink-1",children:l}),e.jsx("dd",{className:"px-3.5 py-2 border-b border-line font-mono m-0 break-all",children:o})]},l)),e.jsxs("div",{className:"contents",children:[e.jsx("dt",{className:"px-3.5 py-2 border-b border-line text-ink-1",children:"Session id"}),e.jsxs("dd",{className:"px-3.5 py-2 border-b border-line font-mono m-0 break-all flex items-center gap-2",children:[e.jsx("span",{children:t.id}),e.jsx(I,{value:t.id,chars:0})]})]})]})}),e.jsxs("div",{className:"flex flex-col gap-3",children:[e.jsx(w,{title:"Tool mix",sub:"calls · red segment = errors",children:d.length?e.jsx(U,{rows:d,format:f}):e.jsx("div",{className:"text-ink-2 text-center py-4",children:"No tool calls."})}),e.jsx(w,{title:"Cache ratio per turn",sub:"share of each turn read from cache",children:e.jsx("svg",{className:"block w-full",viewBox:"0 0 1000 48",preserveAspectRatio:"none",style:{aspectRatio:"1000 / 48"},role:"img","aria-label":"Cache ratio per turn",children:a.map((l,o)=>{const u=1e3/Math.max(1,a.length),n=ae(l);return e.jsxs("g",{children:[e.jsx("title",{children:`#${l.sequence} · ${Math.round(n*100)}%`}),e.jsx("rect",{x:o*u,y:0,width:Math.max(.5,u-.5),height:48,fill:"#1d222c"}),e.jsx("rect",{x:o*u,y:48-n*48,width:Math.max(.5,u-.5),height:n*48,fill:"#3987e5"})]},l.sequence)})})})]})]})}const v=t=>t.total_tokens??t.tokens.fresh_input+t.tokens.output+t.tokens.cache_read+t.tokens.cache_write,xe=t=>t.tool_calls??t.tools.reduce((a,m)=>a+m.count,0);function me({subs:t,selected:a,onPick:m}){const l=Math.max(1,t.length),o=300/l,u=Math.max(1,o-(l>80?.5:1)),n=Math.max(1,...t.map(v));return e.jsx("svg",{className:"block w-full",viewBox:"0 0 300 40",preserveAspectRatio:"none",style:{aspectRatio:"300 / 40"},role:"img","aria-label":"Tokens per sub-agent",children:t.map((h,b)=>{const c=Math.max(2,v(h)/n*36),p=h.id===a;return e.jsxs("g",{onClick:()=>m(h.id),className:"cursor-pointer",children:[e.jsx("title",{children:`#${b+1} · ${S(v(h))} · ${h.errors} errors`}),e.jsx("rect",{x:b*o,y:0,width:u,height:40,fill:p?"rgba(240,136,62,0.18)":"transparent"}),e.jsx("rect",{x:b*o,y:40-c,width:u,height:c,fill:h.errors?"#d03b3b":p?"#ffb177":"#3987e5"})]},h.id)})})}function ue({sa:t,index:a}){const m=D(t.id),x=g.useMemo(()=>W(m.data?.turns??[]),[m.data]),[d,l]=g.useState(),o=v(t),u=n=>{l(n),requestAnimationFrame(()=>document.getElementById(`turn-${n}`)?.scrollIntoView({block:"center"}))};return e.jsxs("div",{className:"flex flex-col gap-3 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 text-xs text-ink-1",children:[e.jsxs("span",{className:"font-mono text-ink-2",children:["#",a+1]}),e.jsx(E,{kind:t.status==="ok"?"good":"crit",children:t.status==="ok"?"OK":`${t.errors} ERR`}),e.jsx("span",{className:"font-mono text-[11px] text-ink-1 bg-bg-3 px-1.5 rounded-sm",children:t.model}),e.jsx(I,{value:t.id}),e.jsx(X,{to:"/sessions/$id",params:{id:t.id},search:{tab:"timeline"},className:"ml-auto text-[11px]",children:"Open as its own session →"})]}),e.jsxs("div",{className:"grid grid-cols-5 gap-3",children:[e.jsx(_,{label:"Tokens",value:S(o),sub:`${B(o?t.tokens.cache_read/o:0,0)} cache read`}),e.jsx(_,{label:"Estimated cost",value:M(t.cost_usd??0)}),e.jsx(_,{label:"Turns",value:f(t.turns),sub:`${f(xe(t))} tool calls`}),e.jsx(_,{label:"Duration",value:F(t.duration_sec??null)}),e.jsx(_,{label:"Tool errors",value:f(t.errors),tone:t.errors?"crit":"default",sub:t.errors?"see red turns below":"none"})]}),e.jsx(w,{title:"Task given",sub:"first user message to the sub-agent",children:t.task_given?e.jsx("p",{className:"m-0 text-xs leading-relaxed whitespace-pre-wrap break-words max-h-40 overflow-auto",children:t.task_given}):e.jsx("span",{className:"text-ink-2 text-xs",children:"Not available — enable transcript indexing in Settings to keep sub-agent prompts."})}),e.jsxs("div",{className:"grid grid-cols-[1fr_2fr] gap-3",children:[e.jsx(w,{title:"Tools used",sub:"calls · red = errors",children:t.tools.length?e.jsx(U,{rows:t.tools.map(n=>({name:n.name,value:n.count,error:n.errors})),format:f}):e.jsx("div",{className:"text-ink-2 text-center py-4",children:"No tool calls recorded."})}),e.jsx(w,{title:"Sub-agent shape",sub:"tokens per turn · click to jump",right:e.jsx(K,{names:["fresh + output","cache read","tool error"],colors:["#3987e5","#1f3c63","#d03b3b"]}),children:x.length?e.jsx(Q,{turns:x,onPick:u,active:d}):m.isLoading?e.jsx(A,{w:"100%",h:"96px"}):e.jsx("div",{className:"text-ink-2 text-center py-4",children:"No turns recorded."})})]}),e.jsx(V,{id:t.id,turns:x,active:d})]})}function he({subs:t}){const[a,m]=g.useState(null),[x,d]=g.useState(""),[l,o]=g.useState(!1),[u,n]=g.useState("order"),h=g.useRef(null),b=g.useMemo(()=>new Map(t.map((s,k)=>[s.id,k])),[t]),c=g.useMemo(()=>{const s=x.trim().toLowerCase(),k=t.filter(i=>(!l||i.errors>0)&&(!s||(i.task_given??"").toLowerCase().includes(s)||i.model.toLowerCase().includes(s)));return u==="tokens"&&k.sort((i,N)=>v(N)-v(i)),u==="errors"&&k.sort((i,N)=>N.errors-i.errors||v(N)-v(i)),k},[t,x,l,u]),p=t.find(s=>s.id===a)??c[0]??t[0],j=s=>{m(s),document.getElementById("page-scroll")?.scrollTo({top:0,behavior:"smooth"}),h.current?.querySelector(`[data-sa="${CSS.escape(s)}"]`)?.scrollIntoView({block:"nearest"})},y=s=>{if(!p||s.key!=="ArrowDown"&&s.key!=="ArrowUp"&&s.key!=="j"&&s.key!=="k")return;const k=c.findIndex(N=>N.id===p.id),i=c[Math.max(0,Math.min(c.length-1,k+(s.key==="ArrowDown"||s.key==="j"?1:-1)))];i&&j(i.id),s.preventDefault()};if(g.useEffect(()=>{a&&!t.some(s=>s.id===a)&&m(null)},[t,a]),!t.length)return e.jsx(w,{title:"Sub-agents",children:e.jsx("div",{className:"text-ink-2 text-center py-6",children:"This session did not spawn sub-agents."})});if(!p)return null;const $=Math.max(1,...t.map(v)),r=t.filter(s=>s.errors>0).length;return e.jsxs("div",{className:"grid grid-cols-[340px_1fr] gap-3 items-start",children:[e.jsxs(w,{title:"Sub-agents",sub:`${t.length}${r?` · ${r} with errors`:""}`,padded:!1,className:"sticky top-0 max-h-[calc(100vh-7.5rem)]",children:[e.jsxs("div",{className:"px-3.5 pt-3 pb-2 border-b border-line flex flex-col gap-2 shrink-0",children:[e.jsx(me,{subs:t,selected:p.id,onPick:j}),e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[e.jsxs("label",{className:"flex items-center gap-1.5 h-6 px-2 border border-line-2 rounded-md text-ink-2 flex-1 min-w-28",children:[e.jsx(T,{name:"search",size:11}),e.jsx("input",{value:x,onChange:s=>d(s.target.value),placeholder:"Filter tasks",className:"bg-transparent outline-none text-ink-0 text-[11px] w-full placeholder:text-ink-2"})]}),e.jsx(ce,{active:l,onClick:()=>o(!l),children:"Errors"})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(H,{options:[{value:"order",label:"order"},{value:"tokens",label:"tokens"},{value:"errors",label:"errors"}],value:u,onChange:n}),e.jsxs("span",{className:"ml-auto font-mono text-[10px] text-ink-2",children:["↑↓ to step · ",c.length," shown"]})]})]}),e.jsxs("div",{ref:h,tabIndex:0,onKeyDown:y,className:"overflow-auto min-h-0 flex-1 outline-none focus-visible:shadow-[inset_0_0_0_1px_var(--color-accent)]",children:[c.map(s=>{const k=b.get(s.id)??0,i=s.id===p.id;return e.jsxs("button",{type:"button","data-sa":s.id,onClick:()=>j(s.id),title:s.task_given??void 0,className:`w-full text-left px-3.5 h-[34px] border-b border-line flex items-center gap-2 hover:bg-bg-2 ${i?"bg-bg-2 shadow-[inset_2px_0_0_var(--color-accent)]":""}`,children:[e.jsxs("span",{className:"font-mono text-[11px] text-ink-2 w-8 shrink-0",children:["#",k+1]}),s.errors?e.jsxs("span",{className:"text-crit-ink inline-flex items-center gap-0.5 font-mono text-[11px] w-8 shrink-0",children:[e.jsx(T,{name:"x",size:9}),s.errors]}):e.jsx("span",{className:"text-good inline-flex items-center w-8 shrink-0",children:e.jsx(T,{name:"check",size:10})}),e.jsx("span",{className:"text-[11px] text-ink-1 truncate flex-1 min-w-0",children:s.task_given?s.task_given.replace(/\s+/g," "):e.jsx("span",{className:"text-ink-2",children:s.model})}),e.jsx("span",{className:"relative h-1.5 w-14 shrink-0 rounded-sm bg-bg-3 overflow-hidden",children:e.jsx("i",{className:"absolute inset-y-0 left-0 bg-s1 rounded-r-sm",style:{width:`${v(s)/$*100}%`}})}),e.jsx("span",{className:"font-mono num text-[11px] w-12 text-right shrink-0",children:S(v(s))})]},s.id)}),c.length===0&&e.jsx("div",{className:"text-ink-2 text-center py-6 text-xs",children:"No sub-agents match."})]})]}),e.jsx(ue,{sa:p,index:b.get(p.id)??0},p.id)]})}function Se(){const{id:t}=Y({from:"/sessions/$id"}),{tab:a}=Z({from:"/sessions/$id"}),m=G(),x=J(t),d=D(t),l=ee(t),[o,u]=g.useState(),n=g.useMemo(()=>W(d.data?.turns??[]),[d.data]),h=n.filter(P).length,b=g.useMemo(()=>le(n),[n]),c=g.useMemo(()=>[{name:"cumulative cost",values:b}],[b]),p=g.useMemo(()=>n.map(i=>`#${i.sequence}`),[n]),j=i=>m({to:"/sessions/$id",params:{id:t},search:{tab:i}}),y=i=>{u(i),a!=="timeline"&&j("timeline"),requestAnimationFrame(()=>document.getElementById(`turn-${i}`)?.scrollIntoView({block:"center"}))},$=["Analyze",{label:"Sessions",to:"/sessions"},x.data?te(x.data.session.project_path,30):"…"];if(x.error)return e.jsxs(e.Fragment,{children:[e.jsx(L,{crumbs:[...$]}),e.jsx(q,{children:e.jsx(se,{error:x.error})})]});const r=x.data?.session,s=r?r.total_fresh_input_tokens+r.total_output_tokens+r.total_cache_read_tokens+r.total_cache_write_tokens:0,k=n.reduce((i,N)=>i+N.tool_calls.length,0);return e.jsxs(e.Fragment,{children:[e.jsxs(L,{crumbs:[...$],children:[e.jsx(I,{value:t}),e.jsx(H,{options:[{value:"overview",label:"Overview"},{value:"timeline",label:"Timeline"},{value:"subagents",label:`Sub-agents · ${l.data?.length??0}`}],value:a,onChange:j}),r&&e.jsx(E,{kind:"mute",children:r.primary_model}),r?.agent_version&&e.jsxs(E,{kind:"mute",children:[z(r.agent)," ",r.agent_version]})]}),e.jsxs(q,{children:[r?e.jsxs("div",{className:"grid grid-cols-5 gap-3",children:[e.jsx(_,{label:"Tokens",value:S(s),sub:`${f(s)} · ${B(s?r.total_cache_read_tokens/s:0,0)} cache read`}),e.jsx(_,{label:"Estimated cost",value:M(r.total_cost_usd),sub:r.turn_count?`${M(r.total_cost_usd/r.turn_count)} / turn`:void 0}),e.jsx(_,{label:"Turns",value:n.length?f(n.length):f(r.turn_count),sub:`${f(k)} tool calls`,note:n.length&&n.length!==r.turn_count?`${f(r.turn_count)} raw`:void 0}),e.jsx(_,{label:"Duration",value:r.ended_at?F(r.duration_sec):"live",sub:C(r.started_at)}),e.jsx(_,{label:"Tool errors",value:String(h),tone:h?"crit":"default",sub:h?`first at turn #${n.find(P)?.sequence}`:"none"})]}):e.jsx(A,{w:"100%",h:"80px"}),e.jsx(w,{title:"Session shape",sub:"tokens per turn · click to jump",right:e.jsx(K,{names:["fresh + output","cache read","tool error"],colors:["#3987e5","#1f3c63","#d03b3b"]}),children:n.length?e.jsxs(e.Fragment,{children:[e.jsx(Q,{turns:n,onPick:y,active:o}),e.jsx("div",{className:"mt-2",children:e.jsx(ie,{labels:p,series:c,format:i=>i===0?"$0":M(i),height:110})})]}):d.isLoading?e.jsx(A,{w:"100%",h:"96px"}):e.jsx("div",{className:"text-ink-2 text-center py-4",children:"No turns recorded."})}),a==="overview"&&r&&e.jsx(de,{session:r,turns:n}),a==="timeline"&&e.jsx(V,{id:t,turns:n,active:o}),a==="subagents"&&e.jsx(he,{subs:l.data??[]})]})]})}export{Se as default};