* feat: add SQLite-backed activity event logging layer Implements a structured diagnostic event trail for the orchestrator. When unexpected behavior occurs (stuck sessions, silent CI failures, missed PR transitions), operators can now reconstruct timelines with `ao events` rather than guessing from logs. Key design decisions driven by Codex review: - FTS5 external-content table uses INSERT/DELETE triggers so search actually works without manual rebuild - ts_epoch (epoch ms) used for all time comparisons to avoid text vs SQLite datetime() ambiguity near cutoff - PRAGMA busy_timeout=3000 handles WAL lock contention across CLI/lifecycle/web processes - user_version schema versioning for future migrations - EventType renamed to ActivityEventKind to avoid collision with existing types.ts export - Event names match existing vocabulary (ci.failing, review.pending) - ActivityStateCache (Map) tracks previous activity state so lifecycle-manager can emit activity.transition diffs - session.spawn_failed captures failed spawns via wrapper try/catch - better-sqlite3 in optionalDependencies: AO keeps working if native build fails; getDb() returns null and writes become no-ops New files: - packages/core/src/events-db.ts — lazy DB init, WAL, schema+triggers - packages/core/src/activity-events.ts — write API, sanitizer - packages/core/src/query-activity-events.ts — query + FTS + stats - packages/cli/src/commands/events.ts — `ao events list/search/stats` Wired into: - lifecycle-manager.ts: lifecycle.transition + activity.transition - session-manager.ts: session.spawned, session.spawn_failed, session.killed Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(activity-events): address PR review comments - redactValue: remove value-string regex check that silently erased error messages mentioning auth terms (key-based redaction is sufficient) - sanitizeData: reject payloads >16KB instead of slicing (sliced JSON is malformed and corrupts JSON output) - lifecycle-manager: prune activityStateCache alongside states in the per-poll stale-entry cleanup loop (prevents unbounded growth) - events CLI: warn on unrecognised --since duration format instead of silently applying no time filter - searchActivityEvents: accept optional projectId and push it into SQL WHERE clause instead of post-LIMIT in-memory filter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(activity-events): review pass fixes - formatRow: pad level string before chalk-wrapping so ANSI codes don't corrupt column alignment in ao events output - events-db: add PRAGMA synchronous=NORMAL (WAL+NORMAL is standard recommendation; avoids per-write fsync in the poll hot path) - events-db: emit console.warn when _dbFailed is set so operators know events are being dropped instead of failing silently forever - activity-events: remove dead redactValue wrapper (was a no-op after the previous fix; call site now directly assigns the value) - activity-events: remove unused session.cleanup from ActivityEventKind (no call site emitted it; dead API surface) - query-activity-events: add optional limit param to searchActivityEvents (default 100, max 1000, parameterized); add --limit flag to ao events search Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(activity-events): widen source/kind to allow plugin-defined values ActivityEventInput.source and .kind accept ActivityEventSource|string and ActivityEventKind|string respectively, so new event sources (e.g. scm-github, notifier-slack) don't require editing core types. The named union members are preserved for IDE autocomplete on known values. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(events): level column alignment, filter kind widening, negative limit guard - events.ts: padEnd(5) → padEnd(9) so level column aligns with the 9-char LEVEL header - query-activity-events.ts: ActivityEventFilter.kind widened to ActivityEventKind|string for consistency with ActivityEventInput.kind (plugin-defined kinds can now be queried) - query-activity-events.ts: negative/NaN limit values sanitized with Number.isFinite + Math.max(1,...) to prevent SQLite LIMIT -N returning the full table Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(events): FTS alias, credential URL sanitization, periodic retention - query-activity-events.ts: use full table name in MATCH (activity_events_fts MATCH ?) instead of alias to avoid 'no such column: fts' in some FTS5 builds - activity-events.ts: redact https://token@host URL credentials in string values; add hourly retention sweep so long-lived processes don't grow DB indefinitely - events-fts-integration.test.ts: real SQLite integration test for FTS5 search, projectId filter, and epoch-based time filter Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(lint): remove inline import() type annotations in integration test ESLint @typescript-eslint/consistent-type-imports forbids import() in type positions — replaced with any to keep the test working without the type imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(events): parse data to structured JSON in --json output; add test proving value sanitizer correctness - ao events list/search --json now parses ActivityEvent.data from JSON string back to a structured object, making it jq-friendly without requiring double-parsing by callers (P1 finding from PR review) - Add test "preserves error messages that mention sensitive words in values" to refute Greptile's false-positive P1 finding: SENSITIVE_KEY_RE only matches key names, not string values; "token expired" and "authorization header missing" values are preserved correctly Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(events): BM25 relevance ordering for FTS search; add versioned JSON envelope Search now orders by FTS5 rank (BM25) instead of ts_epoch, returning most relevant events first. --json output now wraps events in { version, query, meta, events } for stable CLI contracts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(events): quote FTS tokens to prevent false negatives on operator-like terms Searching for words like "OR", "AND", or "NOT" would produce empty results because SQLite FTS5 treated them as operators after token joining. Wrapping each token in double quotes forces literal phrase matching. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(tests): update FTS assertion for quoted tokens; raise timeout on slow audit test query-activity-events test expected the old unquoted join format; update to match the quoted form added in the previous commit. The agent-report audit trail test occasionally exceeds the 5 s default on CI runners; raise to 15 s. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(qa): ISSUE-001 - type events stats entries * test(events): cover session and lifecycle event call sites * test(core): wait for lifecycle branch adoption * chore: add activity events changeset * fix activity event review feedback * batch prune old activity events * record activity event when spawn starts * Fix activity event FTS rebuild and sanitization guard --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| README.md | ||
| activity-events-log.md | ||
| agent-plugin-safety-costs.md | ||
| auto-cleanup-on-merge.md | ||
| cli-session-ls-terminated.md | ||
| collapsible-agent-reports.md | ||
| config.json | ||
| filter-terminated-sessions-from-ls.md | ||
| fix-activity-unavailable-stuck.md | ||
| fix-bugbot-detail-dispatch.md | ||
| fix-start-restore-and-codex-resume.md | ||
| fix-web-lifecycle-restore-affordances.md | ||
| fix-web-tmux-resolver-wrapped-storagekey.md | ||
| fixed-orchestrator-identity.md | ||
| harden-worker-branch-refresh.md | ||
| isolate-lifecycle-terminal-logs.md | ||
| late-lions-share.md | ||
| lifecycle-activity-signal-contract.md | ||
| lifecycle-transitions-report-watcher.md | ||
| opencode-tmpdir-and-shared-cache.md | ||
| optional-repo-field.md | ||
| pr1300-review-followups.md | ||
| refactor-session-detail.md | ||
| scm-github-ci-merge-pending-detectpr-cache.md | ||
| scm-github-pr-cache.md | ||
| session-ui-audit-oscillation.md | ||
| stage2-evidence-recovery.md | ||
| stage4-pr-policy.md | ||
| stage5-ui-api-rollout.md | ||
| tracker-github-issue-cache.md | ||
| web-copy-debug-bundle.md | ||
| web-merge-conflict-actions.md | ||
| worker-system-prompt-split.md | ||
README.md
Changesets
Hello and welcome! This folder has been automatically generated by @changesets/cli, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it in our repository
We have a quick list of common questions to get you started engaging with this project in
our documentation