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.
- {argus_code-0.6.0 → argus_code-0.7.1}/PKG-INFO +29 -20
- {argus_code-0.6.0 → argus_code-0.7.1}/README.md +26 -17
- argus_code-0.7.1/dashboard-dist/assets/AlertsPage-hQBct4uk.js +1 -0
- argus_code-0.6.0/dashboard-dist/assets/AreaLine-DULy1vR8.js → argus_code-0.7.1/dashboard-dist/assets/AreaLine-BKfPVgnO.js +1 -1
- argus_code-0.6.0/dashboard-dist/assets/AttentionStrip-0x1TKexK.js → argus_code-0.7.1/dashboard-dist/assets/AttentionStrip-DQUV5LTN.js +1 -1
- 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
- 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
- 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
- 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
- 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
- argus_code-0.6.0/dashboard-dist/assets/ModelsPage-Cr6lRqQu.js → argus_code-0.7.1/dashboard-dist/assets/ModelsPage-DwKKIQAH.js +1 -1
- argus_code-0.7.1/dashboard-dist/assets/MultiLine-Bp4Mitsq.js +1 -0
- argus_code-0.6.0/dashboard-dist/assets/OverviewPage-aSPc0cOY.js → argus_code-0.7.1/dashboard-dist/assets/OverviewPage-CAx6S0a6.js +1 -1
- argus_code-0.6.0/dashboard-dist/assets/Panel-NdM4AeT3.js → argus_code-0.7.1/dashboard-dist/assets/Panel-rzVYig0L.js +1 -1
- argus_code-0.7.1/dashboard-dist/assets/SearchPage-DIj0iG5P.js +1 -0
- argus_code-0.7.1/dashboard-dist/assets/SessionPage-B5py8aO_.js +2 -0
- argus_code-0.6.0/dashboard-dist/assets/SessionsPage-BUzlxT4V.js → argus_code-0.7.1/dashboard-dist/assets/SessionsPage-Br0MV0yN.js +2 -2
- argus_code-0.7.1/dashboard-dist/assets/SettingsPage-BFb2-hq_.js +1 -0
- 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
- argus_code-0.6.0/dashboard-dist/assets/Tile-C4mpgbF2.js → argus_code-0.7.1/dashboard-dist/assets/Tile-BlnGo9bN.js +1 -1
- 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
- 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
- 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
- argus_code-0.7.1/dashboard-dist/assets/agents-CDuRxAZi.js +1 -0
- argus_code-0.6.0/dashboard-dist/assets/index-CpQkAwD7.css → argus_code-0.7.1/dashboard-dist/assets/index-B8TteJkn.css +1 -1
- argus_code-0.6.0/dashboard-dist/assets/index-B3DMfZOx.js → argus_code-0.7.1/dashboard-dist/assets/index-kRaX6JLH.js +13 -13
- argus_code-0.6.0/dashboard-dist/assets/uplotTheme-eHUsIKi3.js → argus_code-0.7.1/dashboard-dist/assets/uplotTheme-Dv4lAb8e.js +1 -1
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/index.html +2 -2
- argus_code-0.7.1/pricing/2026-10-04.json +68 -0
- argus_code-0.7.1/pricing/2026-10-26.json +74 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/pyproject.toml +21 -3
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/AGENTS.md +8 -5
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/__init__.py +1 -1
- argus_code-0.7.1/python/argus/adapters/AGENTS.md +152 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/__init__.py +1 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/base.py +15 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/adapter.py +3 -0
- argus_code-0.7.1/python/argus/adapters/codex/__init__.py +5 -0
- argus_code-0.7.1/python/argus/adapters/codex/adapter.py +94 -0
- argus_code-0.7.1/python/argus/adapters/codex/discover.py +172 -0
- argus_code-0.7.1/python/argus/adapters/codex/ingest_file.py +181 -0
- argus_code-0.7.1/python/argus/adapters/codex/lines.py +79 -0
- argus_code-0.7.1/python/argus/adapters/codex/records.py +224 -0
- argus_code-0.7.1/python/argus/adapters/codex/state.py +150 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/AGENTS.md +6 -1
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/first_run.py +37 -41
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/pipeline.py +9 -3
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/search_backfill.py +18 -29
- argus_code-0.7.1/python/argus/collector/session_files.py +18 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/core/runtime.py +3 -3
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/AGENTS.md +4 -1
- argus_code-0.7.1/tests/adapters/codex/test_adapter.py +109 -0
- argus_code-0.7.1/tests/adapters/codex/test_discover.py +95 -0
- argus_code-0.7.1/tests/adapters/codex/test_ingest_file.py +139 -0
- argus_code-0.7.1/tests/adapters/codex/test_lines.py +52 -0
- argus_code-0.7.1/tests/adapters/codex/test_real_root.py +64 -0
- argus_code-0.7.1/tests/adapters/codex/test_records.py +109 -0
- argus_code-0.7.1/tests/adapters/codex/test_state.py +76 -0
- argus_code-0.7.1/tests/collector/test_codex_incremental_invariant.py +165 -0
- argus_code-0.7.1/tests/collector/test_pipeline_codex.py +133 -0
- argus_code-0.7.1/tests/collector/test_session_files.py +58 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/conftest.py +8 -0
- argus_code-0.7.1/tests/pricing/test_load.py +163 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/uv.lock +1 -1
- argus_code-0.6.0/.claude/settings.local.json +0 -7
- argus_code-0.6.0/.github/ISSUE_TEMPLATE/bug_report.yml +0 -68
- argus_code-0.6.0/.github/ISSUE_TEMPLATE/config.yml +0 -5
- argus_code-0.6.0/.github/ISSUE_TEMPLATE/feature_request.yml +0 -46
- argus_code-0.6.0/.github/pull_request_template.md +0 -36
- argus_code-0.6.0/.github/workflows/test.yml +0 -74
- argus_code-0.6.0/AGENTS.md +0 -131
- argus_code-0.6.0/ARCHITECTURE.md +0 -347
- argus_code-0.6.0/CLAUDE.md +0 -14
- argus_code-0.6.0/CONTRIBUTING.md +0 -178
- argus_code-0.6.0/PRD.md +0 -387
- argus_code-0.6.0/SECURITY.md +0 -116
- argus_code-0.6.0/TESTING.md +0 -406
- argus_code-0.6.0/assets/hero.png +0 -0
- argus_code-0.6.0/assets/logo.svg +0 -7
- argus_code-0.6.0/assets/screenshots/alerts.png +0 -0
- argus_code-0.6.0/assets/screenshots/models.png +0 -0
- argus_code-0.6.0/assets/screenshots/overview.png +0 -0
- argus_code-0.6.0/assets/screenshots/search.png +0 -0
- argus_code-0.6.0/assets/screenshots/session-detail.png +0 -0
- argus_code-0.6.0/assets/screenshots/session-timeline.png +0 -0
- argus_code-0.6.0/assets/screenshots/sessions.png +0 -0
- argus_code-0.6.0/assets/screenshots/settings.png +0 -0
- argus_code-0.6.0/assets/screenshots/subagents.png +0 -0
- argus_code-0.6.0/assets/screenshots/tools.png +0 -0
- argus_code-0.6.0/assets/screenshots/trends.png +0 -0
- argus_code-0.6.0/assets - Shortcut.lnk +0 -0
- argus_code-0.6.0/dashboard/.astro/content-assets.mjs +0 -1
- argus_code-0.6.0/dashboard/.astro/content-modules.mjs +0 -1
- argus_code-0.6.0/dashboard/.astro/content.d.ts +0 -155
- argus_code-0.6.0/dashboard/.astro/types.d.ts +0 -2
- argus_code-0.6.0/dashboard/AGENTS.md +0 -79
- argus_code-0.6.0/dashboard/e2e/smoke.spec.ts +0 -35
- argus_code-0.6.0/dashboard/index.html +0 -12
- argus_code-0.6.0/dashboard/package-lock.json +0 -4414
- argus_code-0.6.0/dashboard/package.json +0 -44
- argus_code-0.6.0/dashboard/playwright.config.ts +0 -17
- argus_code-0.6.0/dashboard/scripts/size.mjs +0 -19
- argus_code-0.6.0/dashboard/src/App.test.tsx +0 -15
- argus_code-0.6.0/dashboard/src/app/queryClient.ts +0 -5
- argus_code-0.6.0/dashboard/src/app/router.tsx +0 -19
- argus_code-0.6.0/dashboard/src/app/shell/CommandPalette.test.tsx +0 -16
- argus_code-0.6.0/dashboard/src/app/shell/CommandPalette.tsx +0 -52
- argus_code-0.6.0/dashboard/src/app/shell/Shell.tsx +0 -13
- argus_code-0.6.0/dashboard/src/app/shell/Sidebar.test.tsx +0 -21
- argus_code-0.6.0/dashboard/src/app/shell/Sidebar.tsx +0 -73
- argus_code-0.6.0/dashboard/src/app/shell/TopBar.tsx +0 -28
- argus_code-0.6.0/dashboard/src/components/charts/AlertStrip.tsx +0 -22
- argus_code-0.6.0/dashboard/src/components/charts/AreaLine.test.tsx +0 -14
- argus_code-0.6.0/dashboard/src/components/charts/AreaLine.tsx +0 -50
- argus_code-0.6.0/dashboard/src/components/charts/Bars.test.tsx +0 -12
- argus_code-0.6.0/dashboard/src/components/charts/Bars.tsx +0 -28
- argus_code-0.6.0/dashboard/src/components/charts/CalendarHeatmap.test.tsx +0 -8
- argus_code-0.6.0/dashboard/src/components/charts/CalendarHeatmap.tsx +0 -30
- argus_code-0.6.0/dashboard/src/components/charts/ChartTable.tsx +0 -40
- argus_code-0.6.0/dashboard/src/components/charts/GridHeatmap.tsx +0 -27
- argus_code-0.6.0/dashboard/src/components/charts/Legend.tsx +0 -12
- argus_code-0.6.0/dashboard/src/components/charts/Meter.test.tsx +0 -8
- argus_code-0.6.0/dashboard/src/components/charts/Meter.tsx +0 -21
- argus_code-0.6.0/dashboard/src/components/charts/Minimap.test.tsx +0 -17
- argus_code-0.6.0/dashboard/src/components/charts/Minimap.tsx +0 -35
- argus_code-0.6.0/dashboard/src/components/charts/MultiLine.tsx +0 -5
- argus_code-0.6.0/dashboard/src/components/charts/README.md +0 -22
- argus_code-0.6.0/dashboard/src/components/charts/Scatter.tsx +0 -83
- argus_code-0.6.0/dashboard/src/components/charts/Sparkline.tsx +0 -14
- argus_code-0.6.0/dashboard/src/components/charts/StackedColumns.tsx +0 -67
- argus_code-0.6.0/dashboard/src/components/charts/UPlotChart.tsx +0 -36
- argus_code-0.6.0/dashboard/src/components/charts/ramp.ts +0 -3
- argus_code-0.6.0/dashboard/src/components/charts/uplotTheme.ts +0 -14
- argus_code-0.6.0/dashboard/src/components/ui/Button.tsx +0 -18
- argus_code-0.6.0/dashboard/src/components/ui/Chip.tsx +0 -16
- argus_code-0.6.0/dashboard/src/components/ui/CopyId.tsx +0 -28
- argus_code-0.6.0/dashboard/src/components/ui/DataTable.tsx +0 -70
- argus_code-0.6.0/dashboard/src/components/ui/EmptyState.tsx +0 -6
- argus_code-0.6.0/dashboard/src/components/ui/ErrorPanel.tsx +0 -5
- argus_code-0.6.0/dashboard/src/components/ui/Icon.tsx +0 -30
- argus_code-0.6.0/dashboard/src/components/ui/Kbd.tsx +0 -3
- argus_code-0.6.0/dashboard/src/components/ui/Panel.tsx +0 -18
- argus_code-0.6.0/dashboard/src/components/ui/Pill.test.tsx +0 -11
- argus_code-0.6.0/dashboard/src/components/ui/Pill.tsx +0 -24
- argus_code-0.6.0/dashboard/src/components/ui/Seg.test.tsx +0 -10
- argus_code-0.6.0/dashboard/src/components/ui/Seg.tsx +0 -18
- argus_code-0.6.0/dashboard/src/components/ui/Skeleton.tsx +0 -3
- argus_code-0.6.0/dashboard/src/components/ui/Tile.test.tsx +0 -31
- argus_code-0.6.0/dashboard/src/components/ui/Tile.tsx +0 -38
- argus_code-0.6.0/dashboard/src/features/alerts/AlertsPage.tsx +0 -98
- argus_code-0.6.0/dashboard/src/features/models/ModelsPage.tsx +0 -83
- argus_code-0.6.0/dashboard/src/features/overview/AttentionStrip.tsx +0 -40
- argus_code-0.6.0/dashboard/src/features/overview/OverviewPage.tsx +0 -113
- argus_code-0.6.0/dashboard/src/features/overview/TopSessions.tsx +0 -45
- argus_code-0.6.0/dashboard/src/features/overview/useOverviewModel.test.ts +0 -33
- argus_code-0.6.0/dashboard/src/features/overview/useOverviewModel.ts +0 -55
- argus_code-0.6.0/dashboard/src/features/search/SearchPage.tsx +0 -112
- argus_code-0.6.0/dashboard/src/features/search/cleanSnippet.test.ts +0 -11
- argus_code-0.6.0/dashboard/src/features/search/cleanSnippet.ts +0 -24
- argus_code-0.6.0/dashboard/src/features/session/OverviewTab.tsx +0 -61
- argus_code-0.6.0/dashboard/src/features/session/SessionPage.tsx +0 -88
- argus_code-0.6.0/dashboard/src/features/session/SubagentsTab.tsx +0 -183
- argus_code-0.6.0/dashboard/src/features/session/TimelineTab.tsx +0 -139
- argus_code-0.6.0/dashboard/src/features/session/model.test.ts +0 -22
- argus_code-0.6.0/dashboard/src/features/session/model.ts +0 -37
- argus_code-0.6.0/dashboard/src/features/sessions/AnalysisStrip.tsx +0 -67
- argus_code-0.6.0/dashboard/src/features/sessions/SessionsPage.tsx +0 -66
- argus_code-0.6.0/dashboard/src/features/sessions/SessionsTable.tsx +0 -44
- argus_code-0.6.0/dashboard/src/features/sessions/filters.test.ts +0 -15
- argus_code-0.6.0/dashboard/src/features/sessions/filters.ts +0 -19
- argus_code-0.6.0/dashboard/src/features/settings/SettingsPage.tsx +0 -89
- argus_code-0.6.0/dashboard/src/features/tools/ToolsPage.tsx +0 -86
- argus_code-0.6.0/dashboard/src/features/tools/toolsOverTime.test.ts +0 -15
- argus_code-0.6.0/dashboard/src/features/tools/toolsOverTime.ts +0 -29
- argus_code-0.6.0/dashboard/src/features/trends/TrendsPage.tsx +0 -101
- argus_code-0.6.0/dashboard/src/lib/analysis/composition.test.ts +0 -7
- argus_code-0.6.0/dashboard/src/lib/analysis/composition.ts +0 -14
- argus_code-0.6.0/dashboard/src/lib/analysis/cumulative.test.ts +0 -3
- argus_code-0.6.0/dashboard/src/lib/analysis/cumulative.ts +0 -4
- argus_code-0.6.0/dashboard/src/lib/analysis/deltas.test.ts +0 -14
- argus_code-0.6.0/dashboard/src/lib/analysis/deltas.ts +0 -13
- argus_code-0.6.0/dashboard/src/lib/analysis/hourWeekday.test.ts +0 -9
- argus_code-0.6.0/dashboard/src/lib/analysis/hourWeekday.ts +0 -13
- argus_code-0.6.0/dashboard/src/lib/analysis/rollups.test.ts +0 -36
- argus_code-0.6.0/dashboard/src/lib/analysis/rollups.ts +0 -37
- argus_code-0.6.0/dashboard/src/lib/analysis/series.test.ts +0 -25
- argus_code-0.6.0/dashboard/src/lib/analysis/series.ts +0 -32
- argus_code-0.6.0/dashboard/src/lib/analysis/testutil.ts +0 -23
- argus_code-0.6.0/dashboard/src/lib/analysis/trendsMetrics.test.ts +0 -31
- argus_code-0.6.0/dashboard/src/lib/analysis/trendsMetrics.ts +0 -53
- argus_code-0.6.0/dashboard/src/lib/analysis/windows.test.ts +0 -17
- argus_code-0.6.0/dashboard/src/lib/analysis/windows.ts +0 -23
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/alerts.json +0 -1
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/overview.json +0 -1
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/sessions.json +0 -1
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/timeline.json +0 -2785
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/tools-overview.json +0 -1
- argus_code-0.6.0/dashboard/src/lib/api/__fixtures__/trends.json +0 -1
- argus_code-0.6.0/dashboard/src/lib/api/client.test.ts +0 -26
- argus_code-0.6.0/dashboard/src/lib/api/client.ts +0 -74
- argus_code-0.6.0/dashboard/src/lib/api/hooks.ts +0 -31
- argus_code-0.6.0/dashboard/src/lib/api/schemas.ts +0 -197
- argus_code-0.6.0/dashboard/src/lib/api/timezone.test.ts +0 -48
- argus_code-0.6.0/dashboard/src/lib/format/format.test.ts +0 -54
- argus_code-0.6.0/dashboard/src/lib/format/format.ts +0 -51
- argus_code-0.6.0/dashboard/src/main.tsx +0 -18
- argus_code-0.6.0/dashboard/src/routeTree.gen.ts +0 -273
- argus_code-0.6.0/dashboard/src/routes/__root.tsx +0 -10
- argus_code-0.6.0/dashboard/src/routes/alerts.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/index.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/models.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/prompts.tsx +0 -8
- argus_code-0.6.0/dashboard/src/routes/search.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/session.tsx +0 -10
- argus_code-0.6.0/dashboard/src/routes/sessions.$id.tsx +0 -9
- argus_code-0.6.0/dashboard/src/routes/sessions.index.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/settings.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/tools.tsx +0 -3
- argus_code-0.6.0/dashboard/src/routes/trends.tsx +0 -3
- argus_code-0.6.0/dashboard/src/styles.css +0 -62
- argus_code-0.6.0/dashboard/tsconfig.json +0 -17
- argus_code-0.6.0/dashboard/vite.config.ts +0 -19
- argus_code-0.6.0/dashboard/vitest.config.ts +0 -15
- argus_code-0.6.0/dashboard/vitest.setup.ts +0 -25
- argus_code-0.6.0/dashboard-dist/assets/AlertsPage-wRJbF_gs.js +0 -1
- argus_code-0.6.0/dashboard-dist/assets/MultiLine-PWsvBuFC.js +0 -1
- argus_code-0.6.0/dashboard-dist/assets/SearchPage-DjBBvR08.js +0 -1
- argus_code-0.6.0/dashboard-dist/assets/SessionPage-UuHPkPWG.js +0 -2
- argus_code-0.6.0/dashboard-dist/assets/SettingsPage-DhimL0WE.js +0 -1
- argus_code-0.6.0/python/argus/adapters/AGENTS.md +0 -73
- argus_code-0.6.0/scripts/screenshots/capture.mjs +0 -176
- argus_code-0.6.0/scripts/screenshots/frame.mjs +0 -67
- argus_code-0.6.0/tests/pricing/test_load.py +0 -88
- {argus_code-0.6.0 → argus_code-0.7.1}/.gitignore +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/LICENSE +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/NOTICE +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/cumulative-C3-3HW0n.js +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/rollups-Dqiwg3gD.js +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/series-BjP-80tt.js +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/uplotTheme-D1GxaB_c.css +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/dashboard-dist/assets/windows-B3y4OLGl.js +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-05-02.json +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-06-12.json +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/pricing/2026-09-22.json +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/discover.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_tool_calls.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_transcript.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/extract_turns.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/history_jsonl.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/ingest_file.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/model.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/claude_code/schemas.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/adapters/registry.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/cli.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/aggregate.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/rollup_subagents.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/scheduler.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/collector/watcher.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/core/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/logging.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/pidfile.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/process.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/daemon/service.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/base.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/cache_hit_drop.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/cost_spike.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/registry.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/detectors/tool_error_rate_spike.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/compute.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/load.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/refresh.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/pricing/types.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/scaffolder.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/snapshot.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/scaffold/storage.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/schema/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/schema/types.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/AGENTS.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/api.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/server/app.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/AGENTS.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/db.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/migrations/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/migrations/inline.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/python/argus/store/repository.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/agents/code-reviewer.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/agents/security-auditor.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/commit.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/deploy.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/fix-issue.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/pr.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/commands/review.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/api-conventions.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/code-style.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/rules/testing.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/settings.json +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/.claude/skills/example/SKILL.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/templates/default/CLAUDE.md +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_adapter.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_discover.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_tool_calls.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_transcript.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_extract_turns.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_history_jsonl.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_ingest_file.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_integration.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_model.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_path_containment.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/claude_code/test_schemas.py +0 -0
- {argus_code-0.6.0/tests/cli → argus_code-0.7.1/tests/adapters/codex}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/adapters/test_registry.py +0 -0
- {argus_code-0.6.0/tests/collector → argus_code-0.7.1/tests/cli}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/cli/test_indexing_cli.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/cli/test_pricing_refresh_cli.py +0 -0
- {argus_code-0.6.0/tests/core → argus_code-0.7.1/tests/collector}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_aggregate.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_first_run.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_first_run_shutdown.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_fork_dedup.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_fork_dedup_db.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_incremental_invariant.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_incremental_repairs.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_pipeline.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_rollup_subagents.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_scheduler.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/collector/test_watcher.py +0 -0
- {argus_code-0.6.0/tests/daemon → argus_code-0.7.1/tests/core}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/core/test_runtime.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/core/test_runtime_shutdown.py +0 -0
- {argus_code-0.6.0/tests/dashboard → argus_code-0.7.1/tests/daemon}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_logs.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_no_claude_dir.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_pidfile.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_pidfile_identity.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_process.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_service.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_spawn_safe_path.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/daemon/test_yield.py +0 -0
- {argus_code-0.6.0/tests/detectors → argus_code-0.7.1/tests/dashboard}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/dashboard/test_no_raw_html.py +0 -0
- {argus_code-0.6.0/tests/pricing → argus_code-0.7.1/tests/detectors}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_base_helpers.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_cache_hit_drop.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_cost_spike.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_registry.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/detectors/test_tool_error_rate_spike.py +0 -0
- {argus_code-0.6.0/tests/scaffold → argus_code-0.7.1/tests/pricing}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/pricing/test_compute.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/pricing/test_refresh.py +0 -0
- {argus_code-0.6.0/tests/schema → argus_code-0.7.1/tests/scaffold}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_bundled_template.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_cli_claude.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_scaffold_containment.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_scaffolder.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_snapshot.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_snapshot_secrets.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/scaffold/test_storage.py +0 -0
- {argus_code-0.6.0/tests/server → argus_code-0.7.1/tests/schema}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/schema/test_types.py +0 -0
- {argus_code-0.6.0/tests/store → argus_code-0.7.1/tests/server}/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_api.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_api_search.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_day_buckets.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_param_bounds.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_read_cache.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_server.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_spa_fallback.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/server/test_week_of.py +0 -0
- /argus_code-0.6.0/.npmrc → /argus_code-0.7.1/tests/store/__init__.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_db.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_repository.py +0 -0
- {argus_code-0.6.0 → argus_code-0.7.1}/tests/store/test_transactions.py +0 -0
- {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.
|
|
4
|
-
Summary: Local-first
|
|
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
|
|
81
|
-
every token, every tool call, every sub-agent
|
|
82
|
-
nothing about it. Argus tails those files into
|
|
83
|
-
each turn, and serves a dashboard at
|
|
84
|
-
the transcripts never do: *what am I
|
|
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`
|
|
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
|
|
286
|
-
2. **Cost.** Per-turn cost comes from a bundled price table
|
|
287
|
-
3. **Tools.**
|
|
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
|
|
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 # ~
|
|
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
|
|
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
|
|
29
|
-
every token, every tool call, every sub-agent
|
|
30
|
-
nothing about it. Argus tails those files into
|
|
31
|
-
each turn, and serves a dashboard at
|
|
32
|
-
the transcripts never do: *what am I
|
|
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`
|
|
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
|
|
234
|
-
2. **Cost.** Per-turn cost comes from a bundled price table
|
|
235
|
-
3. **Tools.**
|
|
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
|
|
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 # ~
|
|
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
|
|
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-
|
|
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{
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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};
|