feat: analytics parity — tool cost, date ranges, budgets, query explorer, replay, snapshots (v2.4.0)

Analytics parity phases 2–7 (docs/plans/analytics-parity/), built on
138e706 and ported onto v2.3.1:
- Cost by AI tool (?tool= on cost/analytics/stats/workflows, by_tool,
  Codex fast/priority and flex tiers, agenthub_cost_usd_total{tool,model})
- Date ranges (from/to) on cost/analytics/workflows; Analytics range select
  with Today / This week (Monday) / This month (1st) / 7d / 30d / 90d / All /
  Custom; workflow filters carried into workflow-stats.js (read worker)
- Budgets and cost alerts as alert rule types (alert_rules rebuilt without
  its rule_type CHECK), GET /api/budgets/status, rule preview, spend pace,
  status-bar budget chip; rules stay editable in place
- Query Explorer (/query, allowlisted sort, CSV/JSON export) and scheduled
  reports (report_definitions/report_runs, Settings → Reports)
- Session Replay tab and immutable snapshots (session_snapshots, /snapshot/:token)
- Remote Codex sync, push ingest with a hashed token, privacy redaction and
  ignored folders (Settings → Data), Cursor sessions (no cost)
- Read-only MCP server, statusline, Grafana/Prometheus files

Also: resizable sidebar, pet run/wave animations, the workspace home keeps a
half-typed prompt, and the pre-commit hook runs only the related tests for a
small commit.
This commit is contained in:
2026-10-06 17:12:28 +07:00
parent 837da6e5de
commit 4aae61297f
146 changed files with 13565 additions and 537 deletions
+49
View File
@@ -54,6 +54,55 @@
"copyId": "Copy session ID",
"copyFolder": "Copy folder path"
},
"replay": {
"tab": "Replay",
"loading": "Loading events…",
"label": "Session replay",
"truncated": "Replaying the newest {{shown}} of {{total}} events.",
"start": "Jump to start (Home)",
"back": "Step back (←)",
"play": "Play (Space)",
"pause": "Pause (Space)",
"forward": "Step forward (→)",
"end": "Jump to end (End)",
"speed": "Playback speed",
"position": "{{at}} / {{n}}",
"scrubber": "Event position",
"minimap": "Lifecycle markers",
"marker": {
"SessionStart": "Session start",
"UserPromptSubmit": "Prompt",
"Compaction": "Compaction",
"SubagentStop": "Subagent done",
"APIError": "API error",
"Stop": "Turn end"
},
"state": {
"status": "Status",
"tool": "Running tool",
"prompts": "Prompts",
"errors": "Errors",
"compactions": "Compactions",
"elapsed": "Elapsed",
"toolCounts": "Tool calls so far"
}
},
"snapshot": {
"create": "Snapshot",
"hint": "Freeze this session into a read-only copy with a share link",
"title": "Create a snapshot",
"body": "Freezes this session as it is now — its agents, events, stats and cost — into a read-only copy under a private link. Later activity does not change it, and it survives Clear Data.",
"redactPaths": "Redact file paths (working directory, transcript and file paths)",
"confirm": "Create and copy link",
"cancel": "Cancel",
"open": "Open snapshot",
"notFound": "Snapshot not found",
"banner": "Snapshot taken {{date}}",
"bannerBody": "A read-only copy of the session as it was then. Nothing here updates.",
"redacted": "Paths redacted",
"openLive": "Open live session",
"timeline": "Timeline ({{n}})"
},
"exportCsv": "CSV",
"exportJson": "JSON",
"exportCapped": "The file holds {{shown}} of {{total}} sessions (the export limit) — narrow the filters to export the rest.",