cronalytics
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 73 GitHub stars
Code Warn
- process.env — Environment variable access in dashboard/build.js
- fs module — File system access in dashboard/build.js
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Hermes Agent plugin for cron analytics and observability. The dashboard for agentic automations in Hermes.
Cronalytics
/ˈkrɒn.əˌlɪt.ɪks/ (noun)
- Cron analytics and observability.
- The dashboard for agentic automations in Hermes.
Observe. Measure. Optimize.
Cronalytics is a Hermes Agent plugin that attributes session-level usage and estimated cost to every cron-originated run, so you can see what your scheduled jobs are costing you. It hooks into on_session_end, stores derived analytics in a local SQLite fact database, and surfaces them in the Hermes dashboard via a dedicated /cronalytics tab.
Turn hidden automation into visible spend.
Built for Hermes Agent, the autonomous agent framework by Nous Research.
Mini-Tour

YouTube: short video showing basic install and usage.
What It Does
- Captures every cron job run as it completes via the
on_session_endhook - Persists cost, token counts, model, duration, and success state to a local fact database
- Backfills historical data automatically on plugin load and on demand via reconciliation scanner
- Surfaces a dashboard with:
- Summary cards (total runs, estimated cost, tokens, pace)
- Leader board (top runs, top cost, top tokens, top pace)
- Cost-by-model breakdown with proportional bars
- Per-job table with runs, cost, duration, projections, and sortable columns
- Expandable detail rows showing token breakdown, schedule, and success/failure split
- Job detail modal with full run history (sortable, 200-run limit)
- Outcome filter (All / Success / Failure) with conditional card colors
- Mode filter (All / Agent / No agent) for script-only job visibility
- Sync Now button to trigger backfill on demand
- Educational modals explaining Pace, Nominal, Trend, and cost math
Documentation Index
User Documentation (docs/)
- docs/INSTALL.md — Detailed installation guide
- docs/UNINSTALL.md — Clean removal instructions
- docs/USAGE.md — Dashboard usage guide
Developer Documentation (dev/)
- dev/BRIEF.md — Product opportunity brief & positioning
- dev/DESIGN.md — Architecture, data flow, and technical decisions
- dev/FEATURES.md — Complete feature catalog with formulas
- dev/LAUNCH_PLAN.md — V1.0 launch timeline
- dev/AGENTS.md — Contributor conventions & release gates
- dev/DEV_SETUP.md — Development environment setup
- PLAN.md — Phased build plan and backlog (root)
⚠️ Important Notes
Cost data is estimated, not exact. Cronalytics reports the estimated cost that Hermes computed and stored in state.db. Your actual invoice may differ due to rate changes, credits, or rounding. Use this for directional awareness, not accounting.
Single-profile cron by default. Cronalytics monitors the Hermes profile where it is installed. Most users — even those with multiple profiles configured — run cron jobs in the default profile. For them, Cronalytics works fully.
The edge case: if you explicitly create a cron job under a non-default profile (hermes --profile <name> cron create ...), that job runs in an isolated gateway with its own state.db. Cronalytics, installed in the default profile, cannot see it. To monitor those jobs, install Cronalytics in that profile's plugins/ directory as well.
Multi-profile cron support is on our roadmap.
Installation
Dashboard Plugins Tab (Recommended)
Open the Hermes dashboard, navigate to the Plugins tab, and use the Install from GitHub / Git URL field. Enter:
owner/reposhorthand (e.g.8bit64k/cronalytics)- Or a full
https://orgit@clone URL
Check Enable after install, then click Install.
After Install
Hard-refresh your browser (Ctrl+Shift+R or Cmd+Shift+R) to clear cached JS.
Open the Cronalytics tab in the dashboard sidebar.
Reverse proxy users: If you run the Hermes dashboard behind Caddy or Nginx, ensure
/api/*routes are forwarded directly to the dashboard backend. A misconfigured proxy will return HTML instead of JSON for plugin API calls. Seedocs/INSTALL.mdfor a minimal Caddy example.For development setup, see
dev/DEV_SETUP.md.
First-Time Setup
After install, the plugin needs data:
- Wait for a cron job to run — the
on_session_endhook captures it automatically. - Or trigger a manual backfill — click Sync Now in the dashboard, or run:
curl -H "X-Hermes-Session-Token: <token>" -X POST http://localhost:9119/api/plugins/cronalytics/sync
If the dashboard shows "No cron jobs captured," click Sync Now.
Note: The sync endpoint requires the dashboard's ephemeral session token for security (injected into the SPA at startup). Most users should use the dashboard Sync Now button instead of curl.
Configuration
plugin.yaml
name: cronalytics
version: 1.0.0
description: Cost and operational observability for Hermes cron jobs
provides_hooks:
- on_session_end
config.py (static defaults)
All current settings are hardcoded defaults. There is no user-editable config file yet (planned for v1.1).
| Setting | Default | Meaning |
|---|---|---|
RETRY_DELAYS |
[3.0, 8.0, 15.0] |
Seconds to wait before each worker retry |
JITTER_MAX |
2.0 |
Max random seconds added to each retry delay |
MAX_RETRIES |
3 |
Total attempts to read a session from state.db |
Paths are resolved automatically:
STATE_DB:~/.hermes/state.db(Hermes core session store)FACT_DB:~/.hermes/plugins/cronalytics/facts.db(plugin-owned SQLite)WATERMARK_FILE:~/.hermes/plugins/cronalytics/watermark.jsonPENDING_FILE:~/.hermes/plugins/cronalytics/pending.jsonl
What the Dashboard Shows
Summary Board (Row 1)
Four cards showing aggregate metrics for the selected window:
- Job Runs — total executions with vs-prior-period delta (↑/↓ %)
- Cost — total estimated cost in amber; vs-prior delta + ✓/✗ breakdown
(Actual cost placeholder suppressed — partial coverage creates misleading comparisons) - Tokens — total tokens in blue; In/Out/Cached proportion micro-bars
- Pace — aggregate
trend_monthly / nominal_monthlyas a multiplier:< 1.0×green — under scheduled budget1.0–2.0×neutral — on track≥ 2.0×red — over budget
Click any card to open an educational modal explaining the metric.
Leader Board (Row 2)
Four spotlight cards surfacing the highest-value job in each dimension, with the leader's share of the window total:
- Top Runs — highest execution count;
% of total runssub-line - Top Cost — highest cumulative spend;
% of total costsub-line - Top Tokens — highest token consumption;
% of total tokenssub-line - Top Pace — highest pace multiplier (most at risk of exceeding budget)
Click any card to open a detail modal with job metadata.
Per-Model Breakdown
Proportional bar chart showing the top 5 models by cost, with run counts. Remaining models collapsed with "and N more."
Jobs Breakdown Table
Eight sortable columns: Job, Runs, Avg Time, Total Cost, Avg Cost, Nominal/mo, Trend/mo, Pace.
- Click a column header to sort ascending/descending
- Click any row to expand a detail panel showing:
- Token breakdown (total, in, out, cached)
- Success/failure split with cost attribution
- Schedule display, last run, model, next run
- See Runs button opening a full modal
Job Detail Modal
Full run history for the selected job:
- 95% width modal with sticky headers
- Sortable by run time, cost, duration, success, model
- 200-run default limit (backend ceiling: 500)
- Mode column showing Agent vs No agent
Toolbar Controls
- Outcome toggle —
All | Success | Failure(persists in localStorage) - Mode toggle —
All | Agent | No agent(persists in localStorage) - Day selector —
7D | 30D | 90Dpresets + custom input (0–365 days, Enter/Go) - Refresh — re-fetches summary and jobs
- Sync Now — triggers reconciliation scan with spinner + completion toast
Understanding Success
Cronalytics tracks two different notions of "success":
| Signal | What It Means | Source |
|---|---|---|
Wrapper Success (success toggle in dashboard) |
The cron wrapper finished without error — the job ran, the agent responded, and the wrapper exited cleanly. | end_reason field |
| Payload Success | The agent's actual output was correct, useful, or achieved the intended goal. | Not tracked |
How to interpret the dashboard
- Success = high, Failure = low → Your cron jobs are mechanically reliable.
- Success = high, but output quality is poor → The infrastructure is fine; the issue is in the prompt, model choice, or task definition.
- Failure = high → Investigate timeouts, API errors, or wrapper crashes.
The Success/Failure toggle is a reliability signal, not a correctness signal.
Architecture at a Glance
Cron Job Due
│
▼
run_job() ──▶ agent.run_conversation()
│
▼
Hook: on_session_end(platform="cron")
│
▼
Enqueue session_id ──▶ Deferred worker retries
│ (waits for DB flush)
▼
Query state.db ──▶ Insert into facts.db
│
▼
Dashboard queries facts.db via plugin API
API Endpoints
All endpoints are mounted at /api/plugins/cronalytics/.
| Endpoint | Method | Description |
|---|---|---|
/health |
GET |
Plugin health + sync metadata |
/summary?days=N&outcome=both&mode=all |
GET |
Aggregated totals with projections |
/jobs?days=N&outcome=both&mode=all |
GET |
Per-job rolled-up stats with projections |
/jobs/{job_id}/runs |
GET |
Individual runs for a specific job |
/models?days=N&outcome=both&mode=all |
GET |
Cost breakdown by model |
/trends?days=N&outcome=both&mode=all |
GET |
Daily cost + runs time series |
/sync |
POST |
Run reconciliation scanner manually |
Data Model
The fact database (facts.db) is append-only. Rows are inserted once and never updated or deleted.
Key fields captured per run:
session_id— unique run keyjob_id— stable job definition IDrun_time/ended_at/duration_secondsmodelinput_tokens/output_tokens/reasoning_tokens/cache_read_tokens/cache_write_tokensestimated_cost_usd— primary cost metricactual_cost_usd— ground-truth when availablecost_status,cost_source,billing_providerapi_call_count,message_count,tool_call_countend_reason,successjob_mode—agentorno_agentingested_at
File Layout
cronalytics/
├── plugin.yaml # Plugin manifest (hooks, version)
├── __init__.py # Register hook + bootstrap scanner
├── config.py # Paths + defaults
├── facts.py # SQLite fact DB: schema, insert, queries
├── ingester.py # Deferred ingestion worker + crash recovery
├── scanner.py # Reconciliation scanner + watermark I/O
├── schedule.py # Cron parsing + projection math
├── cli.py # Standalone terminal interface
├── logger.py # Shared logger
├── checkpoint.py # Session state persistence
├── dashboard/
│ ├── manifest.json # Dashboard plugin manifest
│ ├── plugin_api.py # FastAPI router
│ ├── build.js # esbuild bundler script
│ ├── src/ # Modular frontend source
│ │ ├── index.js # Entry point
│ │ ├── lib/ # SDK, formatters, icons, validators
│ │ ├── hooks/ # useApi, useModal
│ │ └── components/ # 13 React components
│ └── dist/
│ └── index.js # Bundled IIFE frontend
└── tests/ # 83 pytest tests
Known Limitations
- Wrapper-level success only. The
successboolean reflects whether the session wrapper completed, not whether the agent task succeeded. - Abandoned sessions are invisible. Sessions where the gateway crashed or the job got stuck are never ingested (they never reach
ended_at). - No user-editable config file yet. All tuning values are hardcoded in
config.py. - Actual cost is often null. Most runs only populate
estimated_cost_usd;actual_cost_usddepends on provider billing data. - Plugin directory is a static copy. Changes in the build directory are not reflected in
~/.hermes/plugins/cronalytics/unless manually copied or symlinked. - Dashboard server caches plugins per-process. Changes to
manifest.jsonorplugin_api.pyrequire a full dashboard restart. - Mobile layout tested but not optimized. The table may require horizontal scroll on narrow viewports.
- Job detail modal capped at 200 runs. High-frequency jobs show full count in the table but the drill-down is limited.
Support
This is an independent project built by a solo developer with help from an AI agent, and I'm grateful you are willing to try Cronayltics. I hope it helps optimize your cron activity. I use it daily and will fix bugs as I find them, but support and bug fixes will be on my best effort time schedule.
Found a bug? Open a GitHub issue with reproduction steps.
Have a feature idea? Open a discussion or fork it.
Caveat: The cost estimates are approximate and as recorded by the Hermes Agent framework. The success/failure signal is wrapper-level only (see Understanding Success). Verify anything mission-critical independently.
Requirements
If you are running Hermes Agent you have everything you need:
- Hermes Agent with plugin hook support (
on_session_end) - Hermes dashboard server for UI components
- SQLite (bundled with Python)
License
MIT — see LICENSE for full text.
Changelog
v1.0.1 (2026-05-13)
- Leader Board '% of total' — spotlight cards show the leader's share of the window total (e.g. "42% of total cost")
- Cost card: suppressed Actual — partial
actual_cost_usdcoverage creates misleading comparisons. The line now readsActual: —until provider billing data coverage is reliable. - Backend fix — synthetic script-only rows now insert
NULLforactual_cost_usd(was 0.0), eliminating phantom$0.00aggregates.
v1.0.0 (2026-05-12)
- Dashboard: Summary Board, Leader Board, Per-Model Breakdown, Jobs Breakdown table
- Sortable 8-column jobs table with expandable detail rows
- Job Detail Modal with full run history, sticky headers, inherited sorting
- Outcome toggle (All/Success/Failure) with conditional Cost card colors
- Mode toggle (All/Agent/No agent) with script job visibility
- Pace, Nominal, and Trend projections with educational modals
- Reconciliation scanner with watermark-based backfill
- Bootstrap scanner on plugin load (catches post-restart gaps)
- 83 pytest tests covering facts, parser, scanner, schedule, ingester, plugin API
- Lint/type check:
ruff+mypyclean - Keyboard-accessible cards and table headers (a11y)
- Large-font theme resilience
- API validation layer (JSDoc typedefs + runtime guards)
v0.1.0
- Initial release: real-time ingestion, fact DB, reconciliation scanner, dashboard API, React frontend with summary cards, jobs table, cost-by-model, sync button.
Plugin path: ~/.hermes/plugins/cronalytics/
Fact DB: ~/.hermes/plugins/cronalytics/facts.db
API base: /api/plugins/cronalytics/
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found