Squashes the pg-push-service branch. Included changes:
- chore: gitignore graphify-out analysis directory
- feat: add pidlock package for single-instance locking
- refactor: harden pidlock (EPERM-as-alive, idempotent Release, more tests)
- refactor: make startFileWatcher accept an onChange callback
- refactor: add setupLogFileNamed helper
- refactor: extract resolvePushProjects; add watch fields to PGPushConfig
- test: cover config-conflict branches in resolvePushProjects
- feat: add coalescing push control loop for pg watch
- feat: bound pushLoop shutdown flush with a timeout
- feat: add lazy-reconnecting pgPusher and resolveWatchTargets
- test: cover pgPusher reconnect after EnsureSchema error
- feat: add pg push --watch auto-push daemon
- refactor: log unwatched roots and document classifier wiring in pg watch
- feat: add service spec and manager interface for pg service
- feat: add launchd service manager for pg service
- fix: stop launchd service via bootout so KeepAlive does not restart it
- feat: add systemd --user service manager and platform selector
- fix: quote paths in systemd unit and add start/stop/uninstall tests
- feat: add pg service command group (install/uninstall/status/start/stop/logs)
- fix: recover from log truncation in pg service logs -f; test tailFile and promptYesNo
- docs: document pg push --watch and pg service
- fix: respect result_content_blocked_categories on pg push and pg push --watch
- feat: show last-push in pg service status; warn on watch-only flags; note KeepAlive tradeoff
- fix session aggregate token columns, add more models
- address lock issues, reject env dependent URLs
- fix: harden pg service rendering and dedupe env-URL check
- feat: warn at pg service install about uninherited runtime env vars
- fix: clear lint findings and make pg-service path tests cross-platform
- fix: capture systemd stdout/stderr in log and inject promptYesNo reader
- fix(pg): sync usage_events for zero-message sessions on push
- fix(hermes): catalog-price "included" usage with no cost source
- chore(db): bump dataVersion to 30 for hermes cost re-parse
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Problem
I track token usage across AI tools with agentsview, and lately I've been
running more remote agent tools on machines other than my primary dev box.
Each of those machines records its own sessions locally. The Postgres support
(
pg push/pg serve) already lets me review everything together, butkeeping the shared database current meant either remembering to run
pg pushby hand on each machine or wiring up a bespoke cron job per host. I wanted a
touchless way to sync data from multiple machines into one place so remote
agent token usage shows up in my primary dashboard automatically, without
maintaining custom cron entries everywhere.
I also made some updates to hermes specific code because although tokens
were being passed through, the associated costs were not being aggregated
properly.
pg push service
A long-running auto-push daemon and a first-class way to install it as an OS
service, so a recorder machine keeps the shared Postgres current on its own.
agentsview pg push --watchstart a foreground daemon that pushes to Postgresshortly after sessions change, with a periodic floor as a safety net:
serve) coalesces changeevents over a debounce window (
--debounce, default 30s) and triggers alocal sync + incremental push.
--interval, default 15m) pushes regardless of fileevents and covers any directories the watch budget couldn't cover.
reconnecting on error. A transiently unreachable database is logged and
retried on the next trigger rather than crashing the daemon.
watermarks. On shutdown (SIGINT/SIGTERM) it performs one bounded final flush.
[pg]config and project filters aspg push, andhonors
result_content_blocked_categoriesso the push path no longerdiverges from
serve.agentsview pg service install|uninstall|status|start|stop|logsinstalls and manages the daemon as a per-user OS service:
systemd --userunit on Linux, behind a smallplatform abstraction with pure (golden-tested) unit-file rendering.
installvalidates that the Postgres DSN is resolvable before creating theservice, and surfaces the systemd linger requirement so the service keeps
running on headless boxes after logout.
statusreports the manager state plus the last successful push time;logs -ftails the daemon log and survives log rotation.The daemon reads the DSN from the existing config file (no credentials are
copied into unit files), so protecting
config.tomlis sufficient.Notes
systemd --user); thedaemon command itself is cross-platform Go.
AGENTSVIEW_DATA_DIRto the install-time datadir, so the service resolves the same config regardless of the environment it
starts in.
Vacuum/BackfillSignalssteps, since signal recomputation happens on theserve side.
windows machine that I could use for testing.