Hook observability: sync activity log, stats.json, agent hooks logs + agent hooks stats#25
Merged
Merged
Conversation
…stats` In hook mode `agent session sync` is a quiet no-op on every failure path by design, which made background sync failures invisible. Now every sync attempt appends one JSONL line to $ELLIPSIS_CONFIG_DIR/hooks/sync.log.jsonl (capped, best-effort — a logging failure never breaks the exit-0 guarantee) and atomically rewrites hooks/stats.json, a plain JSON object anything can read without invoking the CLI. - `agent hooks logs [--tail N] [--failures] [--json]`: did the background process fail, and why (outcomes: synced / skipped_unenrolled / not_logged_in / no_transcript / spooled / rejected) - `agent hooks stats [--json]`: last sync, last error, 24h synced/failed counts, pending spool, total synced, recent v1 session ids - `agent hooks status`: one-line sync summary appended
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by @hbrooks (Slack). In hook mode
agent session syncis a quiet no-op on every failure path by design (src/commands/session.tsx), and Claude Code discards async hook output — so a failed background sync was invisible everywhere except (partially) the spool dir. This adds local observability without touching that exit-0 guarantee.What changed
1. Every sync attempt is logged locally (
src/lib/laptop.ts,src/commands/session.tsx)syncTranscript()appends one JSONL line to$ELLIPSIS_CONFIG_DIR/hooks/sync.log.jsonlper attempt:{ts, outcome, cc_session_id, repo, reason, session_id?, event_count?, error?}withoutcome ∈ synced | skipped_unenrolled | not_logged_in | no_transcript | spooled | rejected. Capped at 1000 lines. Recording is best-effort and never throws, so hook mode stays a quiet exit-0 no-op.2.
agent hooks logs—--tail N(default 20),--failures(non-syncedoutcomes only),--json(NDJSON). Answers "did that background process fail, and why".3. Stats object:
$ELLIPSIS_CONFIG_DIR/hooks/stats.json— atomically rewritten (temp file + rename) on every attempt; a plain JSON file anything can read without invoking the CLI:{ "last_sync_at": "...", "last_outcome": "synced", "last_error": "...", "synced_24h": 12, "failed_24h": 1, "spooled_pending": 0, "total_synced": 240, "recent_session_ids": ["ses_..."] }24h windows are derived from the log;
total_syncedcarries forward so the log cap can't shrink it. Exposed viaagent hooks stats [--json], plus a one-liner inagent hooks status(Last sync 4m ago (synced) · 12 synced / 1 failed in 24h · 0 spooled pending).Notes
skipped_unenrolledis logged but not counted as a failure (it's the consent gate working as intended).spooled_pendingis refreshed live from the spool dir when read via the CLI.test/laptop.test.ts(not run locally per workflow — typecheck passes).