argus-code 0.4.1__tar.gz → 0.4.2__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.4.1 → argus_code-0.4.2}/PKG-INFO +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/session.astro +99 -19
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/scripts/api.ts +18 -0
- argus_code-0.4.1/dashboard-dist/_astro/charts.CQF9QNgP.js → argus_code-0.4.2/dashboard-dist/_astro/charts.36uaSAWt.js +1 -1
- argus_code-0.4.2/dashboard-dist/_astro/format.BexCUztC.js +1 -0
- argus_code-0.4.1/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.cnW_pvh0.js → argus_code-0.4.2/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.BF0nZzma.js +1 -1
- argus_code-0.4.1/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.UFVBMlig.js → argus_code-0.4.2/dashboard-dist/_astro/index.astro_astro_type_script_index_0_lang.D-QKQJAF.js +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/_astro/installCanvasRenderer.XK5yP7fW.js +18 -18
- argus_code-0.4.1/dashboard-dist/_astro/models.astro_astro_type_script_index_0_lang.DsSR6D_a.js → argus_code-0.4.2/dashboard-dist/_astro/models.astro_astro_type_script_index_0_lang.0Aczy7Vm.js +1 -1
- argus_code-0.4.1/dashboard-dist/_astro/prompts.astro_astro_type_script_index_0_lang.C0Mv7sTw.js → argus_code-0.4.2/dashboard-dist/_astro/prompts.astro_astro_type_script_index_0_lang.B1i5N4zM.js +1 -1
- argus_code-0.4.2/dashboard-dist/_astro/session.astro_astro_type_script_index_0_lang.SRsknMTL.js +126 -0
- argus_code-0.4.1/dashboard-dist/_astro/settings.astro_astro_type_script_index_0_lang.Cs7bzN_0.js → argus_code-0.4.2/dashboard-dist/_astro/settings.astro_astro_type_script_index_0_lang.BLXx3usF.js +1 -1
- argus_code-0.4.1/dashboard-dist/_astro/tools.astro_astro_type_script_index_0_lang.DTzvpY-G.js → argus_code-0.4.2/dashboard-dist/_astro/tools.astro_astro_type_script_index_0_lang.OvyHH6MH.js +1 -1
- argus_code-0.4.1/dashboard-dist/_astro/trends.astro_astro_type_script_index_0_lang.5olZlQfw.js → argus_code-0.4.2/dashboard-dist/_astro/trends.astro_astro_type_script_index_0_lang.CBtUcxGK.js +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/models/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/prompts/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/session/index.html +2 -2
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/sessions/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/settings/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/tools/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/trends/index.html +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/pyproject.toml +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/__init__.py +1 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/server/api.py +19 -11
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/server/app.py +17 -1
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/store/repository.py +68 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/server/test_api.py +42 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/server/test_server.py +40 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/store/test_repository.py +48 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/uv.lock +1 -1
- argus_code-0.4.1/dashboard-dist/_astro/format.CgLh3UFa.js +0 -1
- argus_code-0.4.1/dashboard-dist/_astro/session.astro_astro_type_script_index_0_lang.IkwnKMSS.js +0 -114
- {argus_code-0.4.1 → argus_code-0.4.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/.github/pull_request_template.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/.gitignore +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/.npmrc +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/ARCHITECTURE.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/CONTRIBUTING.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/LICENSE +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/NOTICE +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/PRD.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/README.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/SECURITY.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/TESTING.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/.astro/content-assets.mjs +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/.astro/content-modules.mjs +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/.astro/content.d.ts +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/.astro/types.d.ts +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/astro.config.mjs +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/package-lock.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/package.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/public/styles/global.css +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/layouts/Default.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/index.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/models.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/prompts.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/sessions/index.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/settings.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/tools.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/pages/trends.astro +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/scripts/alerts.ts +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/scripts/charts.ts +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/scripts/format.ts +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/src/styles/global.css +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard/tsconfig.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/dashboard-dist/styles/global.css +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/pricing/2026-05-02.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/pricing/2026-06-12.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/base.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/adapter.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/discover.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/extract_tool_calls.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/extract_transcript.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/extract_turns.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/history_jsonl.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/ingest_file.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/model.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/claude_code/schemas.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/adapters/registry.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/cli.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/aggregate.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/first_run.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/pipeline.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/rollup_subagents.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/scheduler.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/search_backfill.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/collector/watcher.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/core/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/core/runtime.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/daemon/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/daemon/logging.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/daemon/pidfile.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/daemon/process.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/daemon/service.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/detectors/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/detectors/base.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/detectors/registry.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/detectors/tool_error_rate_spike.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/pricing/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/pricing/compute.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/pricing/load.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/pricing/refresh.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/pricing/types.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/scaffold/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/scaffold/scaffolder.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/scaffold/snapshot.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/scaffold/storage.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/schema/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/schema/types.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/server/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/store/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/store/db.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/store/migrations/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/python/argus/store/migrations/inline.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/agents/code-reviewer.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/agents/security-auditor.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/commands/commit.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/commands/deploy.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/commands/fix-issue.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/commands/pr.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/commands/review.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/rules/api-conventions.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/rules/code-style.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/rules/testing.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/settings.json +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/.claude/skills/example/SKILL.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/templates/default/CLAUDE.md +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_adapter.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_discover.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_extract_tool_calls.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_extract_transcript.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_extract_turns.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_history_jsonl.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_ingest_file.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_integration.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_model.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/claude_code/test_schemas.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/adapters/test_registry.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_aggregate.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_first_run.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_pipeline.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_rollup_subagents.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_scheduler.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/collector/test_watcher.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/conftest.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/core/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/core/test_runtime.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/test_logs.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/test_pidfile.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/test_process.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/test_service.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/daemon/test_yield.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/detectors/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/detectors/test_registry.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/detectors/test_tool_error_rate_spike.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/pricing/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/pricing/test_compute.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/pricing/test_load.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/pricing/test_refresh.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/test_bundled_template.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/test_cli_claude.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/test_scaffolder.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/test_snapshot.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/scaffold/test_storage.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/schema/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/schema/test_types.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/server/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/server/test_api_search.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/server/test_week_of.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/store/__init__.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/store/test_db.py +0 -0
- {argus_code-0.4.1 → argus_code-0.4.2}/tests/test_e2e.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: argus-code
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: Local-first dashboard for Claude Code cost, token, tool-usage, and full-text search analytics
|
|
5
5
|
Project-URL: Homepage, https://github.com/KrishBhimani/argus-code
|
|
6
6
|
Project-URL: Repository, https://github.com/KrishBhimani/argus-code.git
|
|
@@ -6,6 +6,7 @@ import Default from '../layouts/Default.astro';
|
|
|
6
6
|
<div class="sd-tabs">
|
|
7
7
|
<button id="tab-btn-overview" class="sd-tab active" type="button">Overview</button>
|
|
8
8
|
<button id="tab-btn-timeline" class="sd-tab" type="button">Timeline</button>
|
|
9
|
+
<button id="tab-btn-subagents" class="sd-tab" type="button" style="display:none;">Sub-agents</button>
|
|
9
10
|
</div>
|
|
10
11
|
<div id="content">
|
|
11
12
|
<div class="card"><div class="skel" style="width:60%;height:1.5em;"></div></div>
|
|
@@ -13,6 +14,7 @@ import Default from '../layouts/Default.astro';
|
|
|
13
14
|
<div id="timeline-content" style="display:none;">
|
|
14
15
|
<div class="card"><div class="skel" style="width:60%;height:1.5em;"></div></div>
|
|
15
16
|
</div>
|
|
17
|
+
<div id="subagents-content" style="display:none;"></div>
|
|
16
18
|
<button id="to-top" type="button" title="Back to top">↑</button>
|
|
17
19
|
|
|
18
20
|
<!--
|
|
@@ -116,10 +118,28 @@ import Default from '../layouts/Default.astro';
|
|
|
116
118
|
display: none; box-shadow: 0 4px 12px rgba(0,0,0,0.4);
|
|
117
119
|
}
|
|
118
120
|
#to-top:hover { color: var(--text-0); border-color: var(--accent, #f0883e); }
|
|
121
|
+
.sa-wrap { display: grid; grid-template-columns: 38% 62%; gap: 1rem; align-items: start; }
|
|
122
|
+
.sa-list { display: flex; flex-direction: column; gap: 2px; }
|
|
123
|
+
.sa-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.45rem 0.55rem; border-radius: 7px; cursor: pointer; font-size: 0.84rem; }
|
|
124
|
+
.sa-row:hover { background: var(--bg-2); }
|
|
125
|
+
.sa-row.sel { background: var(--bg-2); box-shadow: inset 0 0 0 1px var(--border); }
|
|
126
|
+
.sa-dot { font-weight: 700; }
|
|
127
|
+
.sa-dot.ok { color: var(--good); }
|
|
128
|
+
.sa-dot.error { color: #f85149; }
|
|
129
|
+
.sa-meta { margin-left: auto; color: var(--text-2); font-size: 0.76rem; white-space: nowrap; }
|
|
130
|
+
.sa-detail { padding: 1rem; }
|
|
131
|
+
.sa-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.5rem; margin-bottom: 0.8rem; }
|
|
132
|
+
.sa-stats > div { background: var(--bg-2); border-radius: 8px; padding: 0.5rem 0.6rem; }
|
|
133
|
+
.sa-stats span { display: block; color: var(--text-2); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.03em; }
|
|
134
|
+
.sa-stats b { font-size: 1rem; }
|
|
135
|
+
.sa-task { background: var(--bg-2); border-radius: 7px; padding: 0.6rem 0.7rem; font-size: 0.85rem; margin-bottom: 0.4rem; line-height: 1.4; word-break: break-word; }
|
|
136
|
+
.sa-tool { display: flex; justify-content: space-between; font-size: 0.82rem; padding: 0.25rem 0.4rem; border-radius: 5px; color: var(--text-1); }
|
|
137
|
+
.sa-tool.bad { background: rgba(248,81,73,0.1); color: #f85149; }
|
|
138
|
+
.sa-open { display: inline-block; margin-top: 0.8rem; color: var(--accent, #f0883e); font-size: 0.85rem; }
|
|
119
139
|
</style>
|
|
120
140
|
|
|
121
141
|
<script>
|
|
122
|
-
import { api, type Turn, type TimelineTurn } from '../scripts/api';
|
|
142
|
+
import { api, type Turn, type TimelineTurn, type SubagentSummary } from '../scripts/api';
|
|
123
143
|
import { turnTokensBar } from '../scripts/charts';
|
|
124
144
|
import { usd, tok, num, dur, escapeHtml } from '../scripts/format';
|
|
125
145
|
|
|
@@ -172,6 +192,12 @@ import Default from '../layouts/Default.astro';
|
|
|
172
192
|
const reportedDelta = s.agent_reported_cost_usd != null
|
|
173
193
|
? `<span style="color:var(--text-2);font-size:0.8rem;"> (agent reported: ${usd(s.agent_reported_cost_usd)})</span>` : '';
|
|
174
194
|
|
|
195
|
+
if (subAgents?.length) {
|
|
196
|
+
const subBtn = document.getElementById('tab-btn-subagents')!;
|
|
197
|
+
subBtn.textContent = `Sub-agents (${subAgents.length})`;
|
|
198
|
+
subBtn.style.display = '';
|
|
199
|
+
}
|
|
200
|
+
|
|
175
201
|
root.innerHTML = `
|
|
176
202
|
<div class="grid-cards" style="margin-bottom:1.2rem;">
|
|
177
203
|
<div class="card kpi"><span class="kpi-label">Tokens</span><span class="kpi-value tokens">${tok(totalTokens)}</span><span class="kpi-sub">${num(totalTokens)} total${subAgents?.length ? ` · incl. ${subAgents.length} sub-agent${subAgents.length === 1 ? '' : 's'}` : ''}</span></div>
|
|
@@ -199,14 +225,6 @@ import Default from '../layouts/Default.astro';
|
|
|
199
225
|
</table>
|
|
200
226
|
</div>
|
|
201
227
|
|
|
202
|
-
${subAgents?.length ? `
|
|
203
|
-
<div class="card" style="margin-bottom:1rem;">
|
|
204
|
-
<h3>Sub-agents (${subAgents.length})</h3>
|
|
205
|
-
<ul style="margin:0;padding-left:1.2rem;color:var(--text-1);font-size:0.88rem;">
|
|
206
|
-
${subAgents.map(id => `<li><a href="/session?id=${encodeURIComponent(id)}" class="mono">${escapeHtml(id)}</a></li>`).join('')}
|
|
207
|
-
</ul>
|
|
208
|
-
</div>` : ''}
|
|
209
|
-
|
|
210
228
|
<div class="card" style="margin-bottom:1rem;">
|
|
211
229
|
<div style="display:flex;gap:0.6rem;align-items:center;flex-wrap:wrap;">
|
|
212
230
|
<h3 style="margin:0;flex-shrink:0;">Search this session</h3>
|
|
@@ -303,23 +321,26 @@ import Default from '../layouts/Default.astro';
|
|
|
303
321
|
// ─── Tabs ───────────────────────────────────────────────────────
|
|
304
322
|
const overviewPane = document.getElementById('content')!;
|
|
305
323
|
const timelinePane = document.getElementById('timeline-content')!;
|
|
324
|
+
const subagentsPane = document.getElementById('subagents-content')!;
|
|
306
325
|
const btnOverview = document.getElementById('tab-btn-overview')!;
|
|
307
326
|
const btnTimeline = document.getElementById('tab-btn-timeline')!;
|
|
327
|
+
const btnSubagents = document.getElementById('tab-btn-subagents')!;
|
|
308
328
|
let timelineLoaded = false;
|
|
329
|
+
let subagentsLoaded = false;
|
|
309
330
|
|
|
310
|
-
function showTab(tab: 'overview' | 'timeline') {
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
btnOverview.classList.toggle('active',
|
|
315
|
-
btnTimeline.classList.toggle('active',
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
331
|
+
function showTab(tab: 'overview' | 'timeline' | 'subagents') {
|
|
332
|
+
overviewPane.style.display = tab === 'overview' ? '' : 'none';
|
|
333
|
+
timelinePane.style.display = tab === 'timeline' ? '' : 'none';
|
|
334
|
+
subagentsPane.style.display = tab === 'subagents' ? '' : 'none';
|
|
335
|
+
btnOverview.classList.toggle('active', tab === 'overview');
|
|
336
|
+
btnTimeline.classList.toggle('active', tab === 'timeline');
|
|
337
|
+
btnSubagents.classList.toggle('active', tab === 'subagents');
|
|
338
|
+
if (tab === 'timeline' && !timelineLoaded) { timelineLoaded = true; loadTimeline(); }
|
|
339
|
+
if (tab === 'subagents' && !subagentsLoaded) { subagentsLoaded = true; renderSubagents(); }
|
|
320
340
|
}
|
|
321
341
|
btnOverview.addEventListener('click', () => showTab('overview'));
|
|
322
342
|
btnTimeline.addEventListener('click', () => showTab('timeline'));
|
|
343
|
+
btnSubagents.addEventListener('click', () => showTab('subagents'));
|
|
323
344
|
|
|
324
345
|
// ─── Timeline tab ───────────────────────────────────────────────
|
|
325
346
|
// "Burn" = tokens this turn actually generated/consumed at full rate.
|
|
@@ -463,6 +484,65 @@ import Default from '../layouts/Default.astro';
|
|
|
463
484
|
});
|
|
464
485
|
}
|
|
465
486
|
|
|
487
|
+
// ─── Sub-agents tab ─────────────────────────────────────────────
|
|
488
|
+
function saDetail(sa: SubagentSummary): string {
|
|
489
|
+
const tools = sa.tools.length
|
|
490
|
+
? sa.tools.map(t => `<div class="sa-tool${t.errors ? ' bad' : ''}"><span>${escapeHtml(t.name)}</span><span>×${t.count}${t.errors ? ` · ${t.errors} failed` : ''}</span></div>`).join('')
|
|
491
|
+
: '<p class="sd-no-tools">No tool calls recorded.</p>';
|
|
492
|
+
return `
|
|
493
|
+
<div class="sa-stats">
|
|
494
|
+
<div><span>Turns</span><b>${num(sa.turns)}</b></div>
|
|
495
|
+
<div><span>Tool calls</span><b>${num(sa.tool_calls)}</b></div>
|
|
496
|
+
<div><span>Tokens</span><b>${tok(sa.total_tokens)}</b></div>
|
|
497
|
+
<div><span>Cost (est.)</span><b>~${usd(sa.cost_usd)}</b></div>
|
|
498
|
+
<div><span>Duration</span><b>${dur(sa.duration_sec)}</b></div>
|
|
499
|
+
<div><span>Errors</span><b>${num(sa.errors)}</b></div>
|
|
500
|
+
</div>
|
|
501
|
+
<div class="sa-task"><b>Task given →</b> ${sa.task_given ? escapeHtml(sa.task_given) : '<span class="sd-no-tools">not available (transcript not indexed)</span>'}</div>
|
|
502
|
+
<h4 style="margin:0.6rem 0 0.3rem;">Tools used</h4>${tools}
|
|
503
|
+
<a class="sa-open" href="/session?id=${encodeURIComponent(sa.id)}">Open full timeline for this sub-agent →</a>`;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
async function renderSubagents() {
|
|
507
|
+
subagentsPane.innerHTML = '<p class="empty">Loading sub-agents…</p>';
|
|
508
|
+
let subs: SubagentSummary[] = [];
|
|
509
|
+
try {
|
|
510
|
+
subs = (await api.subagents(id!)).subagents;
|
|
511
|
+
} catch {
|
|
512
|
+
subagentsPane.innerHTML = '<p class="empty">Sub-agents unavailable.</p>';
|
|
513
|
+
return;
|
|
514
|
+
}
|
|
515
|
+
if (!subs.length) {
|
|
516
|
+
subagentsPane.innerHTML = '<p class="empty">No sub-agents.</p>';
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
const rows = subs.map((sa, i) => {
|
|
520
|
+
const dotTitle = sa.status === 'error'
|
|
521
|
+
? `${sa.errors} failed tool call${sa.errors === 1 ? '' : 's'}`
|
|
522
|
+
: 'no failed tool calls';
|
|
523
|
+
const dot = sa.status === 'error' ? `✗ ${num(sa.errors)}` : '✓';
|
|
524
|
+
return `
|
|
525
|
+
<div class="sa-row${i === 0 ? ' sel' : ''}" data-i="${i}">
|
|
526
|
+
<span class="sa-dot ${sa.status}" title="${dotTitle}">${dot}</span>
|
|
527
|
+
<code class="mono">${escapeHtml(sa.model)}</code>
|
|
528
|
+
<span class="sa-meta">${num(sa.tool_calls)} tools · ${tok(sa.total_tokens)}</span>
|
|
529
|
+
</div>`;
|
|
530
|
+
}).join('');
|
|
531
|
+
subagentsPane.innerHTML = `
|
|
532
|
+
<div class="sa-wrap">
|
|
533
|
+
<div class="sa-list">${rows}</div>
|
|
534
|
+
<div class="card sa-detail" id="sa-detail">${saDetail(subs[0])}</div>
|
|
535
|
+
</div>`;
|
|
536
|
+
const detail = document.getElementById('sa-detail')!;
|
|
537
|
+
subagentsPane.querySelectorAll<HTMLElement>('.sa-row').forEach(rowEl => {
|
|
538
|
+
rowEl.addEventListener('click', () => {
|
|
539
|
+
subagentsPane.querySelectorAll('.sa-row').forEach(e => e.classList.remove('sel'));
|
|
540
|
+
rowEl.classList.add('sel');
|
|
541
|
+
detail.innerHTML = saDetail(subs[Number(rowEl.dataset.i)]);
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
466
546
|
// ─── Back-to-top ──────────────────────────────────────────────────
|
|
467
547
|
const toTop = document.getElementById('to-top')!;
|
|
468
548
|
let toTopVisible = false;
|
|
@@ -73,6 +73,21 @@ export interface ToolsOverview {
|
|
|
73
73
|
subagents: { type: string; calls: number; errors: number }[];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
export interface SubagentSummary {
|
|
77
|
+
id: string;
|
|
78
|
+
model: string;
|
|
79
|
+
status: 'ok' | 'error';
|
|
80
|
+
turns: number;
|
|
81
|
+
tool_calls: number;
|
|
82
|
+
errors: number;
|
|
83
|
+
tokens: { fresh_input: number; output: number; cache_read: number; cache_write: number };
|
|
84
|
+
total_tokens: number;
|
|
85
|
+
cost_usd: number;
|
|
86
|
+
duration_sec: number | null;
|
|
87
|
+
task_given: string | null;
|
|
88
|
+
tools: { name: string; count: number; errors: number }[];
|
|
89
|
+
}
|
|
90
|
+
|
|
76
91
|
export interface PromptHit {
|
|
77
92
|
id: number;
|
|
78
93
|
timestamp_ms: number;
|
|
@@ -105,6 +120,9 @@ export const api = {
|
|
|
105
120
|
sessionToolOutput: (id: string, toolUseId: string) =>
|
|
106
121
|
fetch(`/api/sessions/${encodeURIComponent(id)}/tool-output/${encodeURIComponent(toolUseId)}`)
|
|
107
122
|
.then(r => r.ok ? r.json() as Promise<{ search_enabled: boolean; found: boolean; text: string | null }> : null),
|
|
123
|
+
subagents: (id: string) =>
|
|
124
|
+
fetch(`/api/sessions/${encodeURIComponent(id)}/subagents`)
|
|
125
|
+
.then(r => r.json() as Promise<{ subagents: SubagentSummary[] }>),
|
|
108
126
|
overview: (window: string) => fetch('/api/overview?window=' + window).then(r => r.json() as Promise<Overview>),
|
|
109
127
|
trends: (granularity: string, groupBy: string) => fetch(`/api/trends?granularity=${granularity}&groupBy=${groupBy}`).then(r => r.json() as Promise<{ points: { bucket: string; groups: Record<string, { cost: number; tokens: number; sessions: number }> }[] }>),
|
|
110
128
|
pricing: () => fetch('/api/pricing').then(r => r.json() as Promise<{ version: string }>),
|