argus-code 0.4.4__tar.gz → 0.5.0__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 (380) hide show
  1. argus_code-0.5.0/.github/workflows/test.yml +74 -0
  2. {argus_code-0.4.4 → argus_code-0.5.0}/.gitignore +8 -0
  3. {argus_code-0.4.4 → argus_code-0.5.0}/AGENTS.md +5 -4
  4. {argus_code-0.4.4 → argus_code-0.5.0}/ARCHITECTURE.md +29 -15
  5. {argus_code-0.4.4 → argus_code-0.5.0}/CONTRIBUTING.md +30 -8
  6. argus_code-0.5.0/PKG-INFO +301 -0
  7. {argus_code-0.4.4 → argus_code-0.5.0}/PRD.md +7 -0
  8. argus_code-0.5.0/README.md +249 -0
  9. {argus_code-0.4.4 → argus_code-0.5.0}/TESTING.md +22 -0
  10. argus_code-0.5.0/dashboard/AGENTS.md +73 -0
  11. argus_code-0.5.0/dashboard/e2e/smoke.spec.ts +35 -0
  12. argus_code-0.5.0/dashboard/index.html +12 -0
  13. argus_code-0.5.0/dashboard/package-lock.json +4414 -0
  14. argus_code-0.5.0/dashboard/package.json +44 -0
  15. argus_code-0.5.0/dashboard/playwright.config.ts +17 -0
  16. argus_code-0.5.0/dashboard/scripts/size.mjs +19 -0
  17. argus_code-0.5.0/dashboard/src/App.test.tsx +15 -0
  18. argus_code-0.5.0/dashboard/src/app/queryClient.ts +5 -0
  19. argus_code-0.5.0/dashboard/src/app/router.tsx +19 -0
  20. argus_code-0.5.0/dashboard/src/app/shell/CommandPalette.test.tsx +16 -0
  21. argus_code-0.5.0/dashboard/src/app/shell/CommandPalette.tsx +52 -0
  22. argus_code-0.5.0/dashboard/src/app/shell/Shell.tsx +13 -0
  23. argus_code-0.5.0/dashboard/src/app/shell/Sidebar.test.tsx +21 -0
  24. argus_code-0.5.0/dashboard/src/app/shell/Sidebar.tsx +74 -0
  25. argus_code-0.5.0/dashboard/src/app/shell/TopBar.tsx +28 -0
  26. argus_code-0.5.0/dashboard/src/components/charts/AlertStrip.tsx +22 -0
  27. argus_code-0.5.0/dashboard/src/components/charts/AreaLine.test.tsx +14 -0
  28. argus_code-0.5.0/dashboard/src/components/charts/AreaLine.tsx +50 -0
  29. argus_code-0.5.0/dashboard/src/components/charts/Bars.test.tsx +12 -0
  30. argus_code-0.5.0/dashboard/src/components/charts/Bars.tsx +28 -0
  31. argus_code-0.5.0/dashboard/src/components/charts/CalendarHeatmap.test.tsx +8 -0
  32. argus_code-0.5.0/dashboard/src/components/charts/CalendarHeatmap.tsx +30 -0
  33. argus_code-0.5.0/dashboard/src/components/charts/ChartTable.tsx +40 -0
  34. argus_code-0.5.0/dashboard/src/components/charts/GridHeatmap.tsx +27 -0
  35. argus_code-0.5.0/dashboard/src/components/charts/Legend.tsx +12 -0
  36. argus_code-0.5.0/dashboard/src/components/charts/Meter.test.tsx +8 -0
  37. argus_code-0.5.0/dashboard/src/components/charts/Meter.tsx +21 -0
  38. argus_code-0.5.0/dashboard/src/components/charts/Minimap.test.tsx +17 -0
  39. argus_code-0.5.0/dashboard/src/components/charts/Minimap.tsx +35 -0
  40. argus_code-0.5.0/dashboard/src/components/charts/MultiLine.tsx +5 -0
  41. argus_code-0.5.0/dashboard/src/components/charts/README.md +22 -0
  42. argus_code-0.5.0/dashboard/src/components/charts/Scatter.tsx +83 -0
  43. argus_code-0.5.0/dashboard/src/components/charts/Sparkline.tsx +14 -0
  44. argus_code-0.5.0/dashboard/src/components/charts/StackedColumns.tsx +67 -0
  45. argus_code-0.5.0/dashboard/src/components/charts/UPlotChart.tsx +36 -0
  46. argus_code-0.5.0/dashboard/src/components/charts/ramp.ts +3 -0
  47. argus_code-0.5.0/dashboard/src/components/charts/uplotTheme.ts +14 -0
  48. argus_code-0.5.0/dashboard/src/components/ui/Button.tsx +18 -0
  49. argus_code-0.5.0/dashboard/src/components/ui/Chip.tsx +16 -0
  50. argus_code-0.5.0/dashboard/src/components/ui/CopyId.tsx +28 -0
  51. argus_code-0.5.0/dashboard/src/components/ui/DataTable.tsx +70 -0
  52. argus_code-0.5.0/dashboard/src/components/ui/EmptyState.tsx +6 -0
  53. argus_code-0.5.0/dashboard/src/components/ui/ErrorPanel.tsx +5 -0
  54. argus_code-0.5.0/dashboard/src/components/ui/Icon.tsx +30 -0
  55. argus_code-0.5.0/dashboard/src/components/ui/Kbd.tsx +3 -0
  56. argus_code-0.5.0/dashboard/src/components/ui/Panel.tsx +18 -0
  57. argus_code-0.5.0/dashboard/src/components/ui/Pill.test.tsx +11 -0
  58. argus_code-0.5.0/dashboard/src/components/ui/Pill.tsx +24 -0
  59. argus_code-0.5.0/dashboard/src/components/ui/Seg.test.tsx +10 -0
  60. argus_code-0.5.0/dashboard/src/components/ui/Seg.tsx +18 -0
  61. argus_code-0.5.0/dashboard/src/components/ui/Skeleton.tsx +3 -0
  62. argus_code-0.5.0/dashboard/src/components/ui/Tile.test.tsx +23 -0
  63. argus_code-0.5.0/dashboard/src/components/ui/Tile.tsx +28 -0
  64. argus_code-0.5.0/dashboard/src/features/alerts/AlertsPage.tsx +91 -0
  65. argus_code-0.5.0/dashboard/src/features/budgets/BudgetsPage.tsx +26 -0
  66. argus_code-0.5.0/dashboard/src/features/models/ModelsPage.tsx +83 -0
  67. argus_code-0.5.0/dashboard/src/features/overview/AttentionStrip.tsx +40 -0
  68. argus_code-0.5.0/dashboard/src/features/overview/OverviewPage.tsx +113 -0
  69. argus_code-0.5.0/dashboard/src/features/overview/TopSessions.tsx +45 -0
  70. argus_code-0.5.0/dashboard/src/features/overview/useOverviewModel.test.ts +31 -0
  71. argus_code-0.5.0/dashboard/src/features/overview/useOverviewModel.ts +57 -0
  72. argus_code-0.5.0/dashboard/src/features/search/SearchPage.tsx +112 -0
  73. argus_code-0.5.0/dashboard/src/features/search/cleanSnippet.test.ts +11 -0
  74. argus_code-0.5.0/dashboard/src/features/search/cleanSnippet.ts +24 -0
  75. argus_code-0.5.0/dashboard/src/features/session/OverviewTab.tsx +61 -0
  76. argus_code-0.5.0/dashboard/src/features/session/SessionPage.tsx +88 -0
  77. argus_code-0.5.0/dashboard/src/features/session/SubagentsTab.tsx +183 -0
  78. argus_code-0.5.0/dashboard/src/features/session/TimelineTab.tsx +139 -0
  79. argus_code-0.5.0/dashboard/src/features/session/model.test.ts +22 -0
  80. argus_code-0.5.0/dashboard/src/features/session/model.ts +37 -0
  81. argus_code-0.5.0/dashboard/src/features/sessions/AnalysisStrip.tsx +67 -0
  82. argus_code-0.5.0/dashboard/src/features/sessions/SessionsPage.tsx +66 -0
  83. argus_code-0.5.0/dashboard/src/features/sessions/SessionsTable.tsx +44 -0
  84. argus_code-0.5.0/dashboard/src/features/sessions/filters.test.ts +15 -0
  85. argus_code-0.5.0/dashboard/src/features/sessions/filters.ts +19 -0
  86. argus_code-0.5.0/dashboard/src/features/settings/SettingsPage.tsx +89 -0
  87. argus_code-0.5.0/dashboard/src/features/tools/ToolsPage.tsx +86 -0
  88. argus_code-0.5.0/dashboard/src/features/tools/toolsOverTime.test.ts +15 -0
  89. argus_code-0.5.0/dashboard/src/features/tools/toolsOverTime.ts +29 -0
  90. argus_code-0.5.0/dashboard/src/features/trends/TrendsPage.tsx +101 -0
  91. argus_code-0.5.0/dashboard/src/lib/analysis/composition.test.ts +7 -0
  92. argus_code-0.5.0/dashboard/src/lib/analysis/composition.ts +14 -0
  93. argus_code-0.5.0/dashboard/src/lib/analysis/cumulative.test.ts +3 -0
  94. argus_code-0.5.0/dashboard/src/lib/analysis/cumulative.ts +4 -0
  95. argus_code-0.5.0/dashboard/src/lib/analysis/deltas.test.ts +14 -0
  96. argus_code-0.5.0/dashboard/src/lib/analysis/deltas.ts +13 -0
  97. argus_code-0.5.0/dashboard/src/lib/analysis/hourWeekday.test.ts +9 -0
  98. argus_code-0.5.0/dashboard/src/lib/analysis/hourWeekday.ts +13 -0
  99. argus_code-0.5.0/dashboard/src/lib/analysis/rollups.test.ts +43 -0
  100. argus_code-0.5.0/dashboard/src/lib/analysis/rollups.ts +49 -0
  101. argus_code-0.5.0/dashboard/src/lib/analysis/series.test.ts +25 -0
  102. argus_code-0.5.0/dashboard/src/lib/analysis/series.ts +32 -0
  103. argus_code-0.5.0/dashboard/src/lib/analysis/testutil.ts +23 -0
  104. argus_code-0.5.0/dashboard/src/lib/analysis/trendsMetrics.test.ts +31 -0
  105. argus_code-0.5.0/dashboard/src/lib/analysis/trendsMetrics.ts +53 -0
  106. argus_code-0.5.0/dashboard/src/lib/analysis/windows.test.ts +19 -0
  107. argus_code-0.5.0/dashboard/src/lib/analysis/windows.ts +33 -0
  108. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/alerts.json +1 -0
  109. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/overview.json +1 -0
  110. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/sessions.json +1 -0
  111. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/timeline.json +2785 -0
  112. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/tools-overview.json +1 -0
  113. argus_code-0.5.0/dashboard/src/lib/api/__fixtures__/trends.json +1 -0
  114. argus_code-0.5.0/dashboard/src/lib/api/client.test.ts +26 -0
  115. argus_code-0.5.0/dashboard/src/lib/api/client.ts +68 -0
  116. argus_code-0.5.0/dashboard/src/lib/api/hooks.ts +29 -0
  117. argus_code-0.5.0/dashboard/src/lib/api/schemas.ts +195 -0
  118. argus_code-0.5.0/dashboard/src/lib/format/format.test.ts +54 -0
  119. argus_code-0.5.0/dashboard/src/lib/format/format.ts +51 -0
  120. argus_code-0.5.0/dashboard/src/main.tsx +18 -0
  121. argus_code-0.5.0/dashboard/src/routeTree.gen.ts +294 -0
  122. argus_code-0.5.0/dashboard/src/routes/__root.tsx +10 -0
  123. argus_code-0.5.0/dashboard/src/routes/alerts.tsx +3 -0
  124. argus_code-0.5.0/dashboard/src/routes/budgets.tsx +3 -0
  125. argus_code-0.5.0/dashboard/src/routes/index.tsx +3 -0
  126. argus_code-0.5.0/dashboard/src/routes/models.tsx +3 -0
  127. argus_code-0.5.0/dashboard/src/routes/prompts.tsx +8 -0
  128. argus_code-0.5.0/dashboard/src/routes/search.tsx +3 -0
  129. argus_code-0.5.0/dashboard/src/routes/session.tsx +10 -0
  130. argus_code-0.5.0/dashboard/src/routes/sessions.$id.tsx +9 -0
  131. argus_code-0.5.0/dashboard/src/routes/sessions.index.tsx +3 -0
  132. argus_code-0.5.0/dashboard/src/routes/settings.tsx +3 -0
  133. argus_code-0.5.0/dashboard/src/routes/tools.tsx +3 -0
  134. argus_code-0.5.0/dashboard/src/routes/trends.tsx +3 -0
  135. argus_code-0.5.0/dashboard/src/styles.css +62 -0
  136. argus_code-0.5.0/dashboard/tsconfig.json +18 -0
  137. argus_code-0.5.0/dashboard/vite.config.ts +19 -0
  138. argus_code-0.5.0/dashboard/vitest.config.ts +15 -0
  139. argus_code-0.5.0/dashboard/vitest.setup.ts +25 -0
  140. argus_code-0.5.0/dashboard-dist/assets/AlertsPage-Cs8_bu24.js +1 -0
  141. argus_code-0.5.0/dashboard-dist/assets/AreaLine-VUt7zZPY.js +1 -0
  142. argus_code-0.5.0/dashboard-dist/assets/AttentionStrip-uulCqq7B.js +1 -0
  143. argus_code-0.5.0/dashboard-dist/assets/Bars-gdNIlXNl.js +1 -0
  144. argus_code-0.5.0/dashboard-dist/assets/BudgetsPage-DNk4EMLO.js +1 -0
  145. argus_code-0.5.0/dashboard-dist/assets/Button-BqHL1YGs.js +1 -0
  146. argus_code-0.5.0/dashboard-dist/assets/ChartTable-C2SF4hxC.js +1 -0
  147. argus_code-0.5.0/dashboard-dist/assets/Chip-CSAZEvs5.js +1 -0
  148. argus_code-0.5.0/dashboard-dist/assets/ErrorPanel-YJvBzoti.js +1 -0
  149. argus_code-0.5.0/dashboard-dist/assets/ModelsPage-CC5HgXSC.js +1 -0
  150. argus_code-0.5.0/dashboard-dist/assets/MultiLine-DaOioHM_.js +1 -0
  151. argus_code-0.5.0/dashboard-dist/assets/OverviewPage-DtYtpPeA.js +1 -0
  152. argus_code-0.5.0/dashboard-dist/assets/Panel-C0lmkoau.js +1 -0
  153. argus_code-0.5.0/dashboard-dist/assets/Pill-BaEMC6Uo.js +1 -0
  154. argus_code-0.5.0/dashboard-dist/assets/SearchPage-DENLda5C.js +1 -0
  155. argus_code-0.5.0/dashboard-dist/assets/SessionPage-h4KU-Iel.js +2 -0
  156. argus_code-0.5.0/dashboard-dist/assets/SessionsPage-BQOKS0MJ.js +4 -0
  157. argus_code-0.5.0/dashboard-dist/assets/SettingsPage-JyOusfCm.js +1 -0
  158. argus_code-0.5.0/dashboard-dist/assets/StackedColumns-D_Ewnsrg.js +1 -0
  159. argus_code-0.5.0/dashboard-dist/assets/Tile-kzNeIivi.js +1 -0
  160. argus_code-0.5.0/dashboard-dist/assets/TimelineTab-D86rkM-N.js +1 -0
  161. argus_code-0.5.0/dashboard-dist/assets/ToolsPage-DAKkhNxC.js +1 -0
  162. argus_code-0.5.0/dashboard-dist/assets/TrendsPage-tRubbqz4.js +1 -0
  163. argus_code-0.5.0/dashboard-dist/assets/cumulative-C3-3HW0n.js +1 -0
  164. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  165. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  166. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  167. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  168. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
  169. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
  170. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
  171. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
  172. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
  173. argus_code-0.5.0/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
  174. argus_code-0.5.0/dashboard-dist/assets/index-CiLtq5Ja.js +50 -0
  175. argus_code-0.5.0/dashboard-dist/assets/index-DwJcAbKT.css +1 -0
  176. argus_code-0.5.0/dashboard-dist/assets/rollups-C1zMwbci.js +1 -0
  177. argus_code-0.5.0/dashboard-dist/assets/series-BjP-80tt.js +1 -0
  178. argus_code-0.5.0/dashboard-dist/assets/uplotTheme-D1GxaB_c.css +1 -0
  179. argus_code-0.5.0/dashboard-dist/assets/uplotTheme-dVdt58Jw.js +3 -0
  180. argus_code-0.5.0/dashboard-dist/assets/windows-7ctt19Z4.js +1 -0
  181. argus_code-0.5.0/dashboard-dist/index.html +13 -0
  182. {argus_code-0.4.4 → argus_code-0.5.0}/pyproject.toml +1 -1
  183. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/__init__.py +1 -1
  184. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/AGENTS.md +57 -44
  185. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/extract_tool_calls.py +6 -1
  186. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/extract_turns.py +9 -1
  187. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/AGENTS.md +13 -0
  188. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/first_run.py +114 -5
  189. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/core/runtime.py +6 -1
  190. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/server/AGENTS.md +56 -46
  191. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/server/api.py +54 -0
  192. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/server/app.py +25 -1
  193. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/AGENTS.md +4 -1
  194. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/repository.py +69 -4
  195. {argus_code-0.4.4 → argus_code-0.5.0}/tests/AGENTS.md +18 -2
  196. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_extract_tool_calls.py +12 -0
  197. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_extract_turns.py +29 -0
  198. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_first_run.py +103 -2
  199. argus_code-0.5.0/tests/collector/test_first_run_shutdown.py +87 -0
  200. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_scheduler.py +10 -3
  201. {argus_code-0.4.4 → argus_code-0.5.0}/tests/conftest.py +9 -0
  202. argus_code-0.5.0/tests/dashboard/test_no_raw_html.py +43 -0
  203. argus_code-0.5.0/tests/server/test_read_cache.py +77 -0
  204. argus_code-0.5.0/tests/server/test_spa_fallback.py +68 -0
  205. {argus_code-0.4.4 → argus_code-0.5.0}/tests/store/test_repository.py +55 -0
  206. {argus_code-0.4.4 → argus_code-0.5.0}/uv.lock +983 -983
  207. argus_code-0.4.4/PKG-INFO +0 -312
  208. argus_code-0.4.4/README.md +0 -260
  209. argus_code-0.4.4/dashboard/AGENTS.md +0 -35
  210. argus_code-0.4.4/dashboard/astro.config.mjs +0 -9
  211. argus_code-0.4.4/dashboard/package-lock.json +0 -4787
  212. argus_code-0.4.4/dashboard/package.json +0 -18
  213. argus_code-0.4.4/dashboard/public/styles/global.css +0 -307
  214. argus_code-0.4.4/dashboard/src/layouts/Default.astro +0 -68
  215. argus_code-0.4.4/dashboard/src/pages/index.astro +0 -129
  216. argus_code-0.4.4/dashboard/src/pages/models.astro +0 -131
  217. argus_code-0.4.4/dashboard/src/pages/prompts.astro +0 -407
  218. argus_code-0.4.4/dashboard/src/pages/session.astro +0 -568
  219. argus_code-0.4.4/dashboard/src/pages/sessions/index.astro +0 -87
  220. argus_code-0.4.4/dashboard/src/pages/settings.astro +0 -283
  221. argus_code-0.4.4/dashboard/src/pages/tools.astro +0 -216
  222. argus_code-0.4.4/dashboard/src/pages/trends.astro +0 -55
  223. argus_code-0.4.4/dashboard/src/scripts/alerts.ts +0 -85
  224. argus_code-0.4.4/dashboard/src/scripts/api.ts +0 -197
  225. argus_code-0.4.4/dashboard/src/scripts/charts.ts +0 -246
  226. argus_code-0.4.4/dashboard/src/scripts/format.ts +0 -70
  227. argus_code-0.4.4/dashboard/src/styles/global.css +0 -307
  228. argus_code-0.4.4/dashboard/tsconfig.json +0 -4
  229. argus_code-0.4.4/dashboard-dist/_astro/charts.36uaSAWt.js +0 -1
  230. argus_code-0.4.4/dashboard-dist/_astro/format.BexCUztC.js +0 -1
  231. argus_code-0.4.4/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.BF0nZzma.js +0 -11
  232. argus_code-0.4.4/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.D-QKQJAF.js +0 -24
  233. argus_code-0.4.4/dashboard-dist/_astro/installCanvasRenderer.XK5yP7fW.js +0 -18
  234. argus_code-0.4.4/dashboard-dist/_astro/models.astro_astro_type_script_index_0_lang.0Aczy7Vm.js +0 -13
  235. argus_code-0.4.4/dashboard-dist/_astro/prompts.astro_astro_type_script_index_0_lang.B1i5N4zM.js +0 -17
  236. argus_code-0.4.4/dashboard-dist/_astro/session.CGJ-XRoC.css +0 -1
  237. argus_code-0.4.4/dashboard-dist/_astro/session.astro_astro_type_script_index_0_lang.SRsknMTL.js +0 -126
  238. argus_code-0.4.4/dashboard-dist/_astro/settings.astro_astro_type_script_index_0_lang.DyHh8NQi.js +0 -24
  239. argus_code-0.4.4/dashboard-dist/_astro/tools.astro_astro_type_script_index_0_lang.DHTUv2RL.js +0 -12
  240. argus_code-0.4.4/dashboard-dist/_astro/trends.astro_astro_type_script_index_0_lang.CBtUcxGK.js +0 -5
  241. argus_code-0.4.4/dashboard-dist/index.html +0 -2
  242. argus_code-0.4.4/dashboard-dist/models/index.html +0 -1
  243. argus_code-0.4.4/dashboard-dist/prompts/index.html +0 -18
  244. argus_code-0.4.4/dashboard-dist/session/index.html +0 -1
  245. argus_code-0.4.4/dashboard-dist/sessions/index.html +0 -1
  246. argus_code-0.4.4/dashboard-dist/settings/index.html +0 -8
  247. argus_code-0.4.4/dashboard-dist/styles/global.css +0 -307
  248. argus_code-0.4.4/dashboard-dist/tools/index.html +0 -1
  249. argus_code-0.4.4/dashboard-dist/trends/index.html +0 -1
  250. argus_code-0.4.4/tests/dashboard/test_chart_tooltip_escaping.py +0 -87
  251. {argus_code-0.4.4 → argus_code-0.5.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  252. {argus_code-0.4.4 → argus_code-0.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  253. {argus_code-0.4.4 → argus_code-0.5.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  254. {argus_code-0.4.4 → argus_code-0.5.0}/.github/pull_request_template.md +0 -0
  255. {argus_code-0.4.4 → argus_code-0.5.0}/.npmrc +0 -0
  256. {argus_code-0.4.4 → argus_code-0.5.0}/CLAUDE.md +0 -0
  257. {argus_code-0.4.4 → argus_code-0.5.0}/LICENSE +0 -0
  258. {argus_code-0.4.4 → argus_code-0.5.0}/NOTICE +0 -0
  259. {argus_code-0.4.4 → argus_code-0.5.0}/SECURITY.md +0 -0
  260. {argus_code-0.4.4 → argus_code-0.5.0}/dashboard/.astro/content-assets.mjs +0 -0
  261. {argus_code-0.4.4 → argus_code-0.5.0}/dashboard/.astro/content-modules.mjs +0 -0
  262. {argus_code-0.4.4 → argus_code-0.5.0}/dashboard/.astro/content.d.ts +0 -0
  263. {argus_code-0.4.4 → argus_code-0.5.0}/dashboard/.astro/types.d.ts +0 -0
  264. {argus_code-0.4.4 → argus_code-0.5.0}/pricing/2026-05-02.json +0 -0
  265. {argus_code-0.4.4 → argus_code-0.5.0}/pricing/2026-06-12.json +0 -0
  266. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/AGENTS.md +0 -0
  267. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/__init__.py +0 -0
  268. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/base.py +0 -0
  269. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/__init__.py +0 -0
  270. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/adapter.py +0 -0
  271. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/discover.py +0 -0
  272. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/extract_transcript.py +0 -0
  273. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/history_jsonl.py +0 -0
  274. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/ingest_file.py +0 -0
  275. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/model.py +0 -0
  276. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/claude_code/schemas.py +0 -0
  277. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/adapters/registry.py +0 -0
  278. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/cli.py +0 -0
  279. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/__init__.py +0 -0
  280. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/aggregate.py +0 -0
  281. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/pipeline.py +0 -0
  282. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/rollup_subagents.py +0 -0
  283. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/scheduler.py +0 -0
  284. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/search_backfill.py +0 -0
  285. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/collector/watcher.py +0 -0
  286. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/core/__init__.py +0 -0
  287. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/daemon/__init__.py +0 -0
  288. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/daemon/logging.py +0 -0
  289. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/daemon/pidfile.py +0 -0
  290. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/daemon/process.py +0 -0
  291. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/daemon/service.py +0 -0
  292. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/detectors/__init__.py +0 -0
  293. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/detectors/base.py +0 -0
  294. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/detectors/registry.py +0 -0
  295. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/detectors/tool_error_rate_spike.py +0 -0
  296. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/pricing/__init__.py +0 -0
  297. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/pricing/compute.py +0 -0
  298. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/pricing/load.py +0 -0
  299. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/pricing/refresh.py +0 -0
  300. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/pricing/types.py +0 -0
  301. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/scaffold/__init__.py +0 -0
  302. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/scaffold/scaffolder.py +0 -0
  303. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/scaffold/snapshot.py +0 -0
  304. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/scaffold/storage.py +0 -0
  305. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/schema/__init__.py +0 -0
  306. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/schema/types.py +0 -0
  307. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/server/__init__.py +0 -0
  308. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/__init__.py +0 -0
  309. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/db.py +0 -0
  310. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/migrations/__init__.py +0 -0
  311. {argus_code-0.4.4 → argus_code-0.5.0}/python/argus/store/migrations/inline.py +0 -0
  312. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/agents/code-reviewer.md +0 -0
  313. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/agents/security-auditor.md +0 -0
  314. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/commands/commit.md +0 -0
  315. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/commands/deploy.md +0 -0
  316. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/commands/fix-issue.md +0 -0
  317. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/commands/pr.md +0 -0
  318. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/commands/review.md +0 -0
  319. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/rules/api-conventions.md +0 -0
  320. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/rules/code-style.md +0 -0
  321. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/rules/testing.md +0 -0
  322. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/settings.json +0 -0
  323. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/.claude/skills/example/SKILL.md +0 -0
  324. {argus_code-0.4.4 → argus_code-0.5.0}/templates/default/CLAUDE.md +0 -0
  325. {argus_code-0.4.4 → argus_code-0.5.0}/tests/__init__.py +0 -0
  326. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/__init__.py +0 -0
  327. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/__init__.py +0 -0
  328. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_adapter.py +0 -0
  329. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_discover.py +0 -0
  330. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_extract_transcript.py +0 -0
  331. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_history_jsonl.py +0 -0
  332. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_ingest_file.py +0 -0
  333. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_integration.py +0 -0
  334. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_model.py +0 -0
  335. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_path_containment.py +0 -0
  336. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/claude_code/test_schemas.py +0 -0
  337. {argus_code-0.4.4 → argus_code-0.5.0}/tests/adapters/test_registry.py +0 -0
  338. {argus_code-0.4.4 → argus_code-0.5.0}/tests/cli/__init__.py +0 -0
  339. {argus_code-0.4.4 → argus_code-0.5.0}/tests/cli/test_indexing_cli.py +0 -0
  340. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/__init__.py +0 -0
  341. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_aggregate.py +0 -0
  342. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_pipeline.py +0 -0
  343. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_rollup_subagents.py +0 -0
  344. {argus_code-0.4.4 → argus_code-0.5.0}/tests/collector/test_watcher.py +0 -0
  345. {argus_code-0.4.4 → argus_code-0.5.0}/tests/core/__init__.py +0 -0
  346. {argus_code-0.4.4 → argus_code-0.5.0}/tests/core/test_runtime.py +0 -0
  347. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/__init__.py +0 -0
  348. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_logs.py +0 -0
  349. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_pidfile.py +0 -0
  350. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_process.py +0 -0
  351. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_service.py +0 -0
  352. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_spawn_safe_path.py +0 -0
  353. {argus_code-0.4.4 → argus_code-0.5.0}/tests/daemon/test_yield.py +0 -0
  354. {argus_code-0.4.4 → argus_code-0.5.0}/tests/dashboard/__init__.py +0 -0
  355. {argus_code-0.4.4 → argus_code-0.5.0}/tests/detectors/__init__.py +0 -0
  356. {argus_code-0.4.4 → argus_code-0.5.0}/tests/detectors/test_registry.py +0 -0
  357. {argus_code-0.4.4 → argus_code-0.5.0}/tests/detectors/test_tool_error_rate_spike.py +0 -0
  358. {argus_code-0.4.4 → argus_code-0.5.0}/tests/pricing/__init__.py +0 -0
  359. {argus_code-0.4.4 → argus_code-0.5.0}/tests/pricing/test_compute.py +0 -0
  360. {argus_code-0.4.4 → argus_code-0.5.0}/tests/pricing/test_load.py +0 -0
  361. {argus_code-0.4.4 → argus_code-0.5.0}/tests/pricing/test_refresh.py +0 -0
  362. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/__init__.py +0 -0
  363. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_bundled_template.py +0 -0
  364. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_cli_claude.py +0 -0
  365. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_scaffold_containment.py +0 -0
  366. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_scaffolder.py +0 -0
  367. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_snapshot.py +0 -0
  368. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_snapshot_secrets.py +0 -0
  369. {argus_code-0.4.4 → argus_code-0.5.0}/tests/scaffold/test_storage.py +0 -0
  370. {argus_code-0.4.4 → argus_code-0.5.0}/tests/schema/__init__.py +0 -0
  371. {argus_code-0.4.4 → argus_code-0.5.0}/tests/schema/test_types.py +0 -0
  372. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/__init__.py +0 -0
  373. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/test_api.py +0 -0
  374. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/test_api_search.py +0 -0
  375. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/test_param_bounds.py +0 -0
  376. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/test_server.py +0 -0
  377. {argus_code-0.4.4 → argus_code-0.5.0}/tests/server/test_week_of.py +0 -0
  378. {argus_code-0.4.4 → argus_code-0.5.0}/tests/store/__init__.py +0 -0
  379. {argus_code-0.4.4 → argus_code-0.5.0}/tests/store/test_db.py +0 -0
  380. {argus_code-0.4.4 → argus_code-0.5.0}/tests/test_e2e.py +0 -0
@@ -0,0 +1,74 @@
1
+ name: test
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ concurrency:
9
+ group: ${{ github.workflow }}-${{ github.ref }}
10
+ cancel-in-progress: true
11
+
12
+ jobs:
13
+ pytest:
14
+ name: pytest (${{ matrix.os }}, py${{ matrix.python-version }})
15
+ runs-on: ${{ matrix.os }}
16
+ strategy:
17
+ # Don't cancel the whole matrix on one platform's failure — path
18
+ # handling, symlink behaviour and signal delivery all differ per OS,
19
+ # and seeing which combination broke is the point.
20
+ fail-fast: false
21
+ matrix:
22
+ os: [ubuntu-latest, macos-latest, windows-latest]
23
+ python-version: ["3.11", "3.12", "3.13"]
24
+
25
+ steps:
26
+ - uses: actions/checkout@v4
27
+
28
+ - name: Install uv
29
+ uses: astral-sh/setup-uv@v5
30
+ with:
31
+ enable-cache: true
32
+
33
+ - name: Install dependencies
34
+ run: uv sync --dev --python ${{ matrix.python-version }}
35
+
36
+ - name: Run tests
37
+ run: uv run pytest -q
38
+
39
+ dashboard:
40
+ name: dashboard build
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+
45
+ - uses: actions/setup-node@v4
46
+ with:
47
+ node-version: "22"
48
+ cache: npm
49
+ cache-dependency-path: dashboard/package-lock.json
50
+
51
+ - name: Install and build
52
+ working-directory: dashboard
53
+ run: |
54
+ npm ci
55
+ npm run build
56
+
57
+ # The wheel ships dashboard-dist/, not dashboard/dist/. If a source edit
58
+ # is committed without refreshing the shipped copy, users get the old UI
59
+ # — including, historically, an unfixed XSS. Fail loudly on drift.
60
+ #
61
+ # Compare file *names*, not bytes: Astro content-hashes asset filenames,
62
+ # so any real source change renames the asset. Byte comparison would
63
+ # instead trip over line endings, since dashboard-dist/ is tracked (and
64
+ # so checked out CRLF on Windows) while dashboard/dist/ is a fresh LF
65
+ # build — a difference that says nothing about staleness.
66
+ - name: Check dashboard-dist is in sync with dashboard/src
67
+ run: |
68
+ (cd dashboard/dist && find . -type f | sort) > /tmp/built.txt
69
+ (cd dashboard-dist && find . -type f | sort) > /tmp/shipped.txt
70
+ if ! diff -u /tmp/shipped.txt /tmp/built.txt; then
71
+ echo "::error::dashboard-dist/ is stale. Rebuild and commit it — see dashboard/AGENTS.md."
72
+ exit 1
73
+ fi
74
+ echo "dashboard-dist matches the build."
@@ -27,3 +27,11 @@ venv/
27
27
  htmlcov/
28
28
  *.egg-info/
29
29
  build/
30
+
31
+ # Dashboard e2e artifacts
32
+ dashboard/playwright-report/
33
+ dashboard/test-results/
34
+ dashboard/.e2e-data/
35
+
36
+ # TypeScript incremental build cache
37
+ dashboard/*.tsbuildinfo
@@ -16,7 +16,7 @@
16
16
 
17
17
  Argus is a **local-first** analytics dashboard for Claude Code (and other coding
18
18
  agents). A watcher ingests Claude Code's `.jsonl` session transcripts into a local
19
- SQLite archive (`~/.argus/argus.db`); a FastAPI server serves a static Astro
19
+ SQLite archive (`~/.argus/argus.db`); a FastAPI server serves a static React
20
20
  dashboard at `http://localhost:4242`. No network, no telemetry, no LLM calls
21
21
  (except opt-in `argus pricing refresh`). Backend + dashboard ship together in the
22
22
  `argus-code` wheel on PyPI.
@@ -92,8 +92,9 @@ Global engineering rules (binding):
92
92
 
93
93
  ## Verification
94
94
 
95
- - Backend: `uv run pytest` (must be green; ~290 tests, ~25s on Windows).
96
- - Dashboard: `cd dashboard && npm run build` (must succeed).
95
+ - Backend: `uv run pytest` (must be green; ~480 tests, ~35s on Windows).
96
+ - Dashboard: `cd dashboard && npm test && npm run build && npm run size` (all must
97
+ succeed); `npm run e2e` before a release.
97
98
  - Built form smoke test: see `CONTRIBUTING.md` "Running the built form".
98
99
 
99
100
  ## User Preferences
@@ -115,5 +116,5 @@ Global engineering rules (binding):
115
116
  - `python/argus/adapters/AGENTS.md` — Claude Code adapter and transcript-segment
116
117
  extraction; sub-agent file layout.
117
118
  - `python/argus/server/AGENTS.md` — FastAPI routes, static serving, clean shutdown.
118
- - `dashboard/AGENTS.md` — Astro dashboard and the `dashboard-dist` ship chain.
119
+ - `dashboard/AGENTS.md` — React SPA dashboard and the `dashboard-dist` ship chain.
119
120
  - `tests/AGENTS.md` — pytest conventions and platform quirks.
@@ -26,8 +26,9 @@ No network calls (except optional `argus pricing refresh`). No
26
26
  telemetry. No LLM calls. Everything stays on your machine.
27
27
 
28
28
  The backend is Python (≥3.11, FastAPI + uvicorn + pydantic + watchdog
29
- + stdlib sqlite3 + typer). The dashboard is Astro + ECharts, statically
30
- built. Both ship together in the `argus-code` wheel on PyPI.
29
+ + stdlib sqlite3 + typer). The dashboard is a Vite + React SPA (TanStack
30
+ Router/Query/Table, uPlot + SVG charts, Tailwind tokens), statically built.
31
+ Both ship together in the `argus-code` wheel on PyPI.
31
32
 
32
33
  ## The data layer
33
34
 
@@ -119,12 +120,19 @@ python/argus/server/api.py /api/overview, /api/sessions, /api/tools, …
119
120
  python/argus/store/repository.py parameterized SQL queries
120
121
  │
121
122
  ▼
122
- dashboard-dist/ static HTML+JS bundled from dashboard/src/ (Astro + ECharts)
123
+ dashboard-dist/ static SPA bundled from dashboard/src/ (Vite + React)
123
124
  ```
124
125
 
125
126
  The dashboard is **statically built**. No server-side rendering, no
126
- Node in the browser. Pages just `fetch('/api/...')` and render with
127
- ECharts.
127
+ Node at runtime. Pages fetch `/api/...` through a typed, Zod-validated
128
+ client (`dashboard/src/lib/api/`) via TanStack Query and render with uPlot
129
+ (time series, scatter) and hand-rolled SVG (bars, meters, heatmaps, the
130
+ session minimap). Derived analyses (prior-window deltas, per-project
131
+ rollups, weekday x hour, tool calls per day) are pure functions in
132
+ `dashboard/src/lib/analysis/`, computed client-side from existing endpoints;
133
+ each carries a `// candidate-endpoint:` note where a server aggregate would
134
+ scale better. Deep links such as `/sessions/<id>` are served by the
135
+ `index.html` fallback in `server/app.py` and resolved by the client router.
128
136
 
129
137
  ## Detection (alerts)
130
138
 
@@ -223,10 +231,11 @@ A few patterns to absorb before adding code:
223
231
  `ON CONFLICT(id) DO UPDATE`. Re-ingesting a file from offset 0 is
224
232
  safe — useful for backfilling derived data after a schema change.
225
233
 
226
- - **HTML-escape every user-controlled string.** Anything from the
227
- JSONL that ends up in `innerHTML` goes through `escapeHtml()` from
228
- `dashboard/src/scripts/format.ts`. The only HTML allowed through
229
- raw is `<mark>` from FTS5 snippets, via `safeSnippet()`.
234
+ - **Never write raw HTML in the dashboard.** React renders every
235
+ JSONL-derived string as a text node; `dangerouslySetInnerHTML` and
236
+ `innerHTML` are forbidden (`tests/dashboard/test_no_raw_html.py`). FTS5
237
+ `<mark>` snippets are split into text runs by
238
+ `dashboard/src/features/search/cleanSnippet.ts`.
230
239
 
231
240
  - **CSRF Origin check.** All non-GET `/api/*` routes verify the
232
241
  `Origin` header is loopback. Implemented as FastAPI middleware in
@@ -266,10 +275,15 @@ python/argus/
266
275
 
267
276
  dashboard/
268
277
  src/
269
- layouts/Default.astro nav, footer, font, styles
270
- pages/ one .astro per route
271
- scripts/ api client, charts, formatters
272
- styles/global.css single theme stylesheet
278
+ app/ router, query client, shell (sidebar, top bar, Ctrl+K)
279
+ routes/ TanStack file routes (one per page + legacy redirects)
280
+ features/<page>/ page components and page-specific hooks
281
+ components/ui/ Panel, Tile, Pill, Chip, Seg, Button, DataTable, ...
282
+ components/charts/ uPlot wrappers + SVG charts (rules in README.md)
283
+ lib/api/ Zod schemas, typed client, React Query hooks, fixtures
284
+ lib/analysis/ pure derived analyses (unit-tested)
285
+ lib/format/ number / date formatters
286
+ styles.css Tailwind v4 tokens (@theme) + base rules
273
287
  dashboard-dist/ built dashboard, shipped in the wheel as data
274
288
 
275
289
  pricing/ bundled LiteLLM price tables (shipped in wheel as data)
@@ -296,12 +310,12 @@ tests/ pytest suite, mirrors python/argus/ layout
296
310
 
297
311
  | Want to… | Touch these |
298
312
  |---|---|
299
- | Add a new dashboard page | `dashboard/src/pages/<name>.astro`, add nav link in `dashboard/src/layouts/Default.astro` |
313
+ | Add a new dashboard page | `dashboard/src/routes/<name>.tsx` + `dashboard/src/features/<name>/<Name>Page.tsx`, add it to `GROUPS` in `dashboard/src/app/shell/Sidebar.tsx` and `PAGES` in `CommandPalette.tsx` |
300
314
  | Add a new API endpoint | `python/argus/server/api.py`, add a `repo.<method_name>()` in `python/argus/store/repository.py` |
301
315
  | Add a new SQL table or column | New `MIGRATION_N+1` in `python/argus/store/migrations/inline.py`, bump schema check in `db.py`, add `repo` method, add pydantic model in `python/argus/schema/types.py` |
302
316
  | Parse a new JSONL field | `python/argus/adapters/claude_code/schemas.py` (pydantic), wire into `pipeline.py` |
303
317
  | Tweak cost computation | `python/argus/pricing/compute.py`, then re-ingest to recompute via a backfill |
304
- | Add a new chart | `dashboard/src/scripts/charts.ts` (theme is shared) |
318
+ | Add a new chart | `dashboard/src/components/charts/` (read its `README.md` first; series colours in `uplotTheme.ts`) |
305
319
  | Add a new adapter (Codex, OpenClaw, Hermes, …) | New folder `python/argus/adapters/<agent>/` + `@register class` in `adapter.py`. No edits to CLI / watcher / pipeline / server. |
306
320
  | Add an alert detector | New file in `python/argus/detectors/` with a `@register` class whose pure `detect()` returns `Finding`s, plus the side-effect import in `detectors/__init__.py`. The scheduler picks it up automatically. |
307
321
  | Change the bundled scaffold template | Edit files under `templates/default/`; they're force-included into the wheel. New top-level dirs need a `force-include` entry in `pyproject.toml`. |
@@ -15,7 +15,7 @@ first** — it's a 5-minute tour of how the pieces fit together.
15
15
  git clone https://github.com/KrishBhimani/argus-code.git
16
16
  cd argus-code
17
17
  uv sync # creates .venv and installs deps + dev tools
18
- uv run pytest # ~215 tests, ~20s
18
+ uv run pytest # ~380 tests, ~30s
19
19
  uv run argus start # fast iteration loop — runs directly from source
20
20
  ```
21
21
 
@@ -24,6 +24,18 @@ Change a file, restart, see the result.
24
24
 
25
25
  If you don't have `uv` yet: <https://docs.astral.sh/uv/getting-started/installation/>.
26
26
 
27
+ ## Dashboard dev loop
28
+
29
+ ```sh
30
+ uv run argus start # backend on :4242
31
+ cd dashboard && npm install && npm run dev # Vite on :5173, proxies /api to :4242
32
+ npm test && npm run build && npm run size # before committing
33
+ ```
34
+
35
+ The dashboard is a Vite + React SPA; see `dashboard/AGENTS.md` for the ship
36
+ chain (`dashboard-dist/` must be refreshed and committed with every source
37
+ change) and `npm run e2e` for the Playwright smoke test.
38
+
27
39
  ## Running the built form
28
40
 
29
41
  CI builds and tests on every push. To smoke-test the built wheel
@@ -32,11 +44,15 @@ locally exactly as a user would:
32
44
  ```sh
33
45
  cd dashboard && npm ci && npm run build && cd ..
34
46
  cp -r dashboard/dist dashboard-dist # bundle the dashboard
35
- uv build # wheel + sdist in dist/
36
- uv tool install ./dist/argus_cli-*.whl # install globally
47
+ rm -rf dist && uv build # wheel + sdist in dist/
48
+ uv tool install ./dist/argus_code-*.whl # install globally
37
49
  argus start
38
50
  ```
39
51
 
52
+ The distribution is `argus-code` on PyPI (the `argus_code-*.whl` above); the
53
+ command it installs is `argus`. Clear `dist/` first or a stale wheel from an
54
+ earlier version can be picked up by the glob.
55
+
40
56
  ## Tests
41
57
 
42
58
  ```sh
@@ -54,11 +70,17 @@ for the full catalog.
54
70
 
55
71
  ## CI
56
72
 
57
- `.github/workflows/test.yml` runs on every push and PR:
58
-
59
- - **Test matrix:** Ubuntu, macOS, Windows × Python 3.11, 3.12, 3.13.
60
- - **Dashboard build** (release-only): runs `npm ci && npm run build`
61
- before `uv build` to bundle the static dashboard into the wheel.
73
+ `.github/workflows/test.yml` runs on every push to `main` and every PR:
74
+
75
+ - **Test matrix:** Ubuntu, macOS, Windows × Python 3.11, 3.12, 3.13 (9 jobs,
76
+ `fail-fast: false` so you can see which platform broke).
77
+ - **Dashboard build:** `npm ci && npm run build`, then a check that the
78
+ tracked `dashboard-dist/` matches what the build produces. A source edit
79
+ committed without refreshing the shipped copy means users run the old UI —
80
+ that has historically shipped an unfixed XSS, so the check is a hard fail.
81
+ It compares file *names*, which Vite content-hashes, rather than bytes
82
+ (`dashboard-dist/` is tracked and so checked out CRLF on Windows, while a
83
+ fresh build is LF — a difference that says nothing about staleness).
62
84
 
63
85
  The Windows runner is non-negotiable — path normalisation, WAL `-shm`
64
86
  cleanup, and short-name path quirks are all platform-sensitive.
@@ -0,0 +1,301 @@
1
+ Metadata-Version: 2.5
2
+ Name: argus-code
3
+ Version: 0.5.0
4
+ Summary: Local-first dashboard for Claude Code cost, token, tool-usage, and full-text search analytics
5
+ Project-URL: Homepage, https://github.com/KrishBhimani/argus-code
6
+ Project-URL: Repository, https://github.com/KrishBhimani/argus-code.git
7
+ Project-URL: Issues, https://github.com/KrishBhimani/argus-code/issues
8
+ Author: Krish Bhimani
9
+ License: MIT License
10
+
11
+ Copyright (c) 2026 Krish Bhimani
12
+
13
+ Permission is hereby granted, free of charge, to any person obtaining a copy
14
+ of this software and associated documentation files (the "Software"), to deal
15
+ in the Software without restriction, including without limitation the rights
16
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
+ copies of the Software, and to permit persons to whom the Software is
18
+ furnished to do so, subject to the following conditions:
19
+
20
+ The above copyright notice and this permission notice shall be included in all
21
+ copies or substantial portions of the Software.
22
+
23
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
+ SOFTWARE.
30
+ License-File: LICENSE
31
+ License-File: NOTICE
32
+ Keywords: ai-tools,analytics,anthropic,claude,claude-code,cli,cost,dashboard,llm,local-first,tokens,usage
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Environment :: Console
35
+ Classifier: Environment :: Web Environment
36
+ Classifier: Intended Audience :: Developers
37
+ Classifier: License :: OSI Approved :: MIT License
38
+ Classifier: Operating System :: MacOS
39
+ Classifier: Operating System :: Microsoft :: Windows
40
+ Classifier: Operating System :: POSIX :: Linux
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Requires-Python: >=3.11
45
+ Requires-Dist: fastapi>=0.115
46
+ Requires-Dist: httpx>=0.27
47
+ Requires-Dist: pydantic>=2.9
48
+ Requires-Dist: typer>=0.12
49
+ Requires-Dist: uvicorn[standard]>=0.32
50
+ Requires-Dist: watchdog>=5.0
51
+ Description-Content-Type: text/markdown
52
+
53
+ # Argus
54
+
55
+ **The observability console for Claude Code — local-first, permanent, and honest about cost.**
56
+
57
+ [![PyPI](https://img.shields.io/pypi/v/argus-code)](https://pypi.org/project/argus-code/)
58
+ [![Python ≥ 3.11](https://img.shields.io/badge/python-%E2%89%A5%203.11-blue)](#requirements)
59
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
60
+
61
+ Claude Code writes a detailed transcript of every session to `~/.claude/` — every turn,
62
+ every token, every tool call, every sub-agent it spawned — and then **deletes it after
63
+ 30 days**. Argus tails those files into a SQLite archive on your machine, prices each
64
+ turn from a bundled table, and serves a dashboard at `http://localhost:4242` that
65
+ answers the questions the transcripts never do:
66
+
67
+ - *How much am I actually spending, and is it going up?*
68
+ - *Which sessions were expensive — and which turn made them so?*
69
+ - *Where do my tools fail, and when did that start?*
70
+ - *What did that sub-agent get told, and what did it do?*
71
+ - *When do I actually work, and on what?*
72
+
73
+ Nothing leaves your computer. No telemetry, no API calls, no embeddings — SQLite and
74
+ a static web app, bound to `127.0.0.1`.
75
+
76
+ ```sh
77
+ pipx install argus-code # or: uv tool install argus-code
78
+ argus start
79
+ ```
80
+
81
+ Your browser opens once the first pass finishes (5–10 s for a typical install). From
82
+ then on, every session you run is ingested live.
83
+
84
+ ---
85
+
86
+ ## Why it exists
87
+
88
+ Tools like `ccusage` read what's on disk *right now*. Claude Code rotates its own
89
+ logs (`cleanupPeriodDays`, default 30), so "right now" is a sliding month. Once
90
+ Argus has ingested a session into `~/.argus/argus.db` the row stays forever — a few
91
+ months in, Argus remembers sessions Claude has already forgotten. **It accumulates.**
92
+
93
+ And because it keeps the *structure* of each session (turns, tool calls, sub-agents,
94
+ cache hits), it can do forensics, not just totals.
95
+
96
+ ---
97
+
98
+ ## What you get
99
+
100
+ The dashboard is organised by the job you came to do.
101
+
102
+ ### Monitor
103
+
104
+ | Page | What it answers |
105
+ |---|---|
106
+ | **Overview** | Four tiles — tokens, estimated cost, sessions, tool error rate — each with its **change vs. the previous window**. A "Needs attention" strip that is always visible (it says *all clear* when there's nothing). Tokens per day, stackable by model. A 90-day activity heatmap and a **weekday × hour** map of when you start sessions. Top sessions in the window. |
107
+ | **Alerts** | The inbox for detector findings, with unseen / all / severity filters and a 30-day strip. Today's detector flags any tool whose error rate doubled against its 4-week baseline; more arrive with Budgets. |
108
+
109
+ ### Analyze
110
+
111
+ | Page | What it answers |
112
+ |---|---|
113
+ | **Sessions** | A virtualised, sortable grid of every session with inline token bars. Above it, a **duration × tokens scatter** (log–log, coloured by model) that makes outliers obvious, or a per-project rollup. Filter by text, project, model, window. |
114
+ | **Session detail** | Tiles, then a **session-shape minimap** — one bar per turn, cache reads beneath fresh tokens, failing turns in red; click a bar to jump. A cumulative-cost line. A compact timeline where every row expands into its tool calls, their sizes, status and output, and error text inline. Resumed sessions are stitched into one chronological thread. |
115
+ | **Sub-agents** | For sessions that delegated: a sticky list with an at-a-glance strip (tokens per agent, red where one failed), filter and sort, and ↑↓ stepping. Each agent's **task as given**, tools, shape and full timeline, inline. |
116
+ | **Tools** | Leaderboard with error segments, **tool calls per day** (columns / area / table), MCP servers, sub-agent invocations by type. |
117
+ | **Models** | Tokens and cost per model, **$ per million tokens** as you actually experienced it, and each model's share over time. |
118
+ | **Trends** | Built around **rates, not totals**: this period vs last, a run-rate projection, tokens per session, cache-read share, unit cost — plus the by-model lines, cumulative total and a full breakdown table. |
119
+
120
+ ### Search *(opt-in)*
121
+
122
+ Full-text search over every prompt you've typed **and** every assistant reply,
123
+ thinking block and tool output. SQLite FTS5 — sub-millisecond, lexical,
124
+ deterministic, offline. Off by default; see [Privacy](#privacy--security).
125
+
126
+ ### Govern
127
+
128
+ **Settings** (indexing toggle, pricing version, export, parse errors) today;
129
+ **Budgets** — monthly ceilings with threshold alerts — is the next slot.
130
+
131
+ Every chart follows a few house rules: one axis per chart, a legend whenever there's
132
+ more than one series, status colours always paired with an icon and a label, and a
133
+ table view behind every chart. Tokens are exact; costs are estimates, and the UI says so.
134
+
135
+ ---
136
+
137
+ ## CLI
138
+
139
+ ```sh
140
+ argus # top-level command group
141
+ ├─ start [--port 4242] [--host 127.0.0.1] [--data-dir <path>]
142
+ │ # watcher + ingester + dashboard server
143
+ ├─ pricing
144
+ │ └─ refresh # pull latest model prices from LiteLLM
145
+ ├─ indexing # (was `search` — still works, hidden alias)
146
+ │ ├─ status # is transcript indexing on?
147
+ │ ├─ enable # turn it on (next start backfills)
148
+ │ ├─ disable # turn it off, keep data
149
+ │ └─ clear # wipe all indexed segments + disable
150
+ ├─ claude # scaffold & manage .claude/ setups
151
+ │ ├─ init [path] [--template <name>] [--force]
152
+ │ │ # stamp CLAUDE.md + .claude/ into a project
153
+ │ └─ template
154
+ │ ├─ list # list templates (bundled + user)
155
+ │ └─ create <name> [--path <dir>] [--all]
156
+ │ # save a project's .claude/ as a template
157
+ ├─ daemon # argusd — background ingestion + detectors
158
+ │ ├─ start # start argusd detached, write PID file
159
+ │ ├─ stop # stop argusd gracefully
160
+ │ ├─ restart # stop then start
161
+ │ ├─ status # running? PID + uptime
162
+ │ └─ logs [-n N] [-f] # tail ~/.argus/argusd.log
163
+ └─ wipe # delete ~/.argus/ entirely
164
+ ```
165
+
166
+ `--help` works at every level.
167
+
168
+ ### `argus daemon` — keep ingesting when the dashboard is closed
169
+
170
+ By default the watcher and detector scheduler run *inside* `argus start`; close it
171
+ and ingestion stops. **argusd** moves that work into a long-running background
172
+ process. It does not serve the dashboard — port 4242 is still only bound by
173
+ `argus start`.
174
+
175
+ ```sh
176
+ argus daemon start # run argusd in the background (survives closing the terminal)
177
+ argus daemon status # PID + uptime
178
+ argus daemon logs -f # follow the log
179
+ argus daemon stop
180
+ ```
181
+
182
+ **Coexistence.** When argusd is running, `argus start` sees its PID file and becomes a
183
+ read-only viewer of the database the daemon keeps fresh (the sidebar footer says
184
+ *argusd daemon*). When it isn't, `argus start` ingests in-process exactly as before.
185
+
186
+ **Living with it.** Idle cost is negligible: the watcher is event-driven and the
187
+ scheduler wakes every 10 minutes — expect ~40–70 MB RAM and no idle CPU. Logs rotate
188
+ at ~1 MB × 3 in `~/.argus/argusd.log`. Things to know:
189
+
190
+ - **Restart after upgrading** (`argus daemon restart`) — a running daemon holds the old code.
191
+ - **No auto-restart yet.** A crashed daemon stays down until you start it again; the stale PID file is cleaned up. OS-native autostart (`argus install`) is a follow-up.
192
+ - **If argusd dies while a read-only dashboard is open**, the footer keeps saying *argusd* and ingestion pauses until you restart the dashboard, which then resumes in-process.
193
+ - **Windows `stop` is a hard kill** — safe (no critical in-memory state), but no `argusd stopped.` line lands in the log.
194
+ - **Toggling search:** the dashboard's *Enable indexing* button indexes immediately; the CLI `argus indexing enable` flips the flag and backfills on the next `argus start` / `argus daemon restart`.
195
+
196
+ ### `argus claude` — scaffold good agent config
197
+
198
+ Set things up well *before* you run, not just observe afterwards. `init` copies a
199
+ template into a project: `CLAUDE.md` to the root, everything else into `.claude/`.
200
+ Existing files are skipped (`--force` overwrites — except `CLAUDE.md`, which is never
201
+ overwritten). The bundled `default` template ships a sensible `settings.json`, agents,
202
+ commands, rules and a placeholder skill. Save your own project's setup with
203
+ `template create`; user templates live in `~/.argus/templates/` and win over bundled ones.
204
+
205
+ ---
206
+
207
+ ## Privacy & security
208
+
209
+ Argus is built for one person on one machine, and the defaults say so.
210
+
211
+ - **Binds to `127.0.0.1` only.** Nothing on your LAN, Wi-Fi or VPN can reach it. `--host 0.0.0.0` exists, and prints a loud warning.
212
+ - **No external requests, ever** — except `argus pricing refresh`, a manual command that fetches one JSON file from LiteLLM's GitHub. No telemetry, no analytics, no LLM calls.
213
+ - **Transcript indexing is opt-in.** Cost and token analytics need no text content. Full-text search over prompts and transcripts requires an explicit opt-in (Settings or `argus indexing enable`), and opting out means the API returns nothing even if data is on disk.
214
+ - **Cross-origin writes are rejected.** State-changing endpoints check the `Origin` header against Argus's own origin — exactly — so neither a random tab nor another localhost app can flip your settings.
215
+ - **A loopback `Host` header is required.** This defeats DNS rebinding, where a site you visit repoints its domain at `127.0.0.1` to read your history. Anything else gets a 421 (skipped only when you deliberately bind `0.0.0.0`).
216
+ - **Transcript text never becomes HTML.** The dashboard renders every transcript-derived string as text; a test forbids raw-HTML sinks in the source.
217
+ - **No embeddings, no model weights.** Search is a plain inverted index.
218
+
219
+ Your data is one file, `~/.argus/argus.db`. `argus wipe` deletes it; so does `rm`.
220
+ Vulnerability reports: [SECURITY.md](./SECURITY.md).
221
+
222
+ ---
223
+
224
+ ## How it works
225
+
226
+ 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.
227
+ 2. **Cost.** Per-turn cost comes from a bundled `pricing/<version>.json` sourced from [LiteLLM](https://github.com/BerriAI/litellm). Tokens are exact; costs are estimates.
228
+ 3. **Tools.** Each `tool_use` block becomes a `tool_calls` 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.
229
+ 4. **Search (opt-in).** Two FTS5 tables: one over `~/.claude/history.jsonl` (every prompt, ~150 KB for a heavy user), one over assistant text, thinking, user content and tool output (~30–60 MB for hundreds of sessions). Indexed incrementally during the normal ingest tick.
230
+ 5. **Detection.** A scheduler thread runs registered *detectors* every 10 minutes. Each reads the DB and returns findings; the scheduler upserts them into `alerts` with a seen / resolved lifecycle, so an issue that recovers and recurs fires again instead of staying silent.
231
+ 6. **Dashboard.** A Vite + React single-page app (uPlot and hand-drawn SVG charts), statically built and served by the FastAPI app. Analyses that aren't in the API yet — prior-window deltas, tokens per session, cache-read share, calls per day — are derived client-side from the existing endpoints. No Node at runtime, no network beyond `/api/*`.
232
+ 7. **One runtime, two hosts.** The watcher, scheduler and first-pass ingest live in a single `CoreRuntime` that both `argus start` and `argusd` construct, so they can never double-ingest.
233
+
234
+ Want the deeper tour? [ARCHITECTURE.md](./ARCHITECTURE.md).
235
+
236
+ ---
237
+
238
+ ## Configuration
239
+
240
+ | Where | Knob |
241
+ |---|---|
242
+ | `argus start --port <n>` | Port (default 4242). |
243
+ | `argus start --host <h>` | Bind host (default `127.0.0.1`; `0.0.0.0` for LAN exposure). |
244
+ | `argus start --data-dir <path>` | Override `~/.argus/`. |
245
+ | `pricing/*.json` | Bundled price tables; refresh with `argus pricing refresh`. |
246
+
247
+ ### Keep more history in Claude Code itself
248
+
249
+ Claude Code deletes session files after 30 days by default. Raise it in
250
+ `~/.claude/settings.json` (minimum 1; it can't be disabled):
251
+
252
+ ```json
253
+ { "cleanupPeriodDays": 365 }
254
+ ```
255
+
256
+ Argus keeps its own copy regardless — this only widens what Claude itself retains.
257
+
258
+ ## Requirements
259
+
260
+ - **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).
261
+ - A `~/.claude/` directory with real session JSONL — i.e. you've used Claude Code at least once.
262
+
263
+ ---
264
+
265
+ ## Development
266
+
267
+ ```sh
268
+ git clone https://github.com/KrishBhimani/argus-code.git
269
+ cd argus-code
270
+ uv sync # install deps + create venv
271
+ uv run pytest # ~490 tests, ~35 s
272
+ uv run argus start # runs directly from source
273
+ ```
274
+
275
+ Dashboard work happens in `dashboard/` (Vite + React): `npm install && npm run dev`
276
+ proxies `/api` to a running `argus start`; `npm test`, `npm run build`, `npm run size`
277
+ and `npm run e2e` are the gates. The built copy in `dashboard-dist/` ships inside the
278
+ wheel, so end users never touch `npm`. See [CONTRIBUTING.md](./CONTRIBUTING.md).
279
+
280
+ ```
281
+ python/argus/ Python ingest, store, server, CLI
282
+ adapters/ Claude Code JSONL parsers + adapter registry
283
+ store/ SQLite schema + migrations + repo
284
+ server/ FastAPI app + /api routes
285
+ collector/ watcher + pipeline + first-run + search backfill + alert scheduler
286
+ core/ CoreRuntime — shared watcher+scheduler+ingest lifecycle
287
+ daemon/ argusd: pidfile, foreground service, process control, logging
288
+ detectors/ alert detectors (pure reads) + @register registry
289
+ scaffold/ `argus claude` template storage / init / snapshot
290
+ pricing/ LiteLLM-derived price table + cost compute
291
+ schema/ pydantic data models
292
+ dashboard/ React SPA source (Vite)
293
+ dashboard-dist/ Vite build output (shipped in wheel as data)
294
+ pricing/ Bundled pricing JSON (shipped in wheel as data)
295
+ templates/ Bundled .claude/ scaffolding templates (shipped in wheel as data)
296
+ tests/ pytest suite, mirrors python/argus/ layout
297
+ ```
298
+
299
+ ## License
300
+
301
+ MIT — see [LICENSE](./LICENSE).
@@ -1,3 +1,10 @@
1
+ > **Historical document.** This is the original planning PRD, kept for the
2
+ > design rationale. It predates several decisions that went the other way and
3
+ > is **not** an accurate description of what shipped. Notably: distribution is
4
+ > PyPI (`pip install argus-code`), not npm; the only supported agent is Claude
5
+ > Code, not Claude Code + Codex. For what Argus actually does today, read
6
+ > [README.md](./README.md) and [ARCHITECTURE.md](./ARCHITECTURE.md).
7
+
1
8
  # Argus — Product Requirements Document (v0.2, MVP)
2
9
 
3
10
  > v0.2 supersedes v0.1 (working name "AgentLens"). Schemas verified against on-disk logs. Tech stack and data model locked. Most v0.1 open questions are resolved; remaining ones are flagged in §10.