/** * ChronicleMetricsStore — derived, queryable aggregates over the raw * Chronicle journal ("process, don't hoard"). * * The journal is the durable evidence log; this store is a disposable * projection kept in `/metrics.db` (node:sqlite, WAL). Each * `refresh()` incrementally consumes only the journal bytes appended since * the previous run (per-partition byte offsets in `ingest_state`), so the * raw JSONL partitions can be purged by retention without losing metrics: * * - `provider_daily` — provider×model×day attempt/success/failure/retry/ * fallback counts, token totals, duration stats. * - `task_outcomes` — one row per task (kanban/SDD/subagent) with status, * timing, retry counts, and board/run/session lineage. * - `file_lineage` — one row per observed file mutation with full * session/agent/task/board/tool/model attribution. * - `token_cost` — latest cumulative token.accounted cost snapshot per * scope (same latest-wins semantics as the query * engine's summary). * * The schema is a cache: on version mismatch it is dropped and re-ingested * from whatever journal partitions still exist. */ export interface ChronicleMetricsRefreshResult { ingestedEvents: number; ingestedBytes: number; sourceFiles: number; invalidLines: number; } export interface ChronicleProviderDailyRow { day: string; providerId: string; modelId: string; attempts: number; completed: number; failed: number; retries: number; fallbacks: number; inputTokens: number; outputTokens: number; cacheReadTokens: number; cacheWriteTokens: number; avgDurationMs: number; maxDurationMs: number; } export interface ChronicleTaskOutcomeRow { taskId: string; runId: string; boardId: string; sessionId: string; agentId: string; status: string; startedAt: string | null; endedAt: string | null; durationMs: number | null; retries: number; verificationFailures: number; filesTouched: number; } export interface ChronicleFileLineageRow { path: string; operation: string; occurredAt: string; sessionId: string; agentId: string; taskId: string; boardId: string; runId: string; toolName: string; providerId: string; modelId: string; source: string; } export interface ChronicleMetricsSummary { providers: { attempts: number; completed: number; failed: number; successRate: number; }; tasks: Record; files: { mutations: number; uniquePaths: number; }; estimatedCostUsd: number; } /** Non-throwing availability probe for callers that degrade gracefully. */ export declare function isChronicleMetricsAvailable(): boolean; export declare class ChronicleMetricsStore { private readonly db; private readonly directory; private readonly dbPath; private constructor(); static open(chronicleDirectory: string): ChronicleMetricsStore; close(): void; /** Incrementally ingest journal bytes appended since the last refresh. * Safe across processes: guarded by a file lock on the database path. */ refresh(): Promise; providerDaily(options?: { from?: string; to?: string; }): ChronicleProviderDailyRow[]; taskOutcomes(options?: { runId?: string; boardId?: string; sessionId?: string; status?: string; limit?: number; }): ChronicleTaskOutcomeRow[]; fileLineage(options?: { path?: string; taskId?: string; boardId?: string; sessionId?: string; limit?: number; }): ChronicleFileLineageRow[]; summary(): ChronicleMetricsSummary; private ensureSchema; private loadOffsets; private pruneOffsets; /** Read complete lines appended after `consumed` bytes. The trailing * partial line of an actively-written partition is left for the next * refresh — `ingest_state.bytes` only ever advances past full lines. */ private ingestFile; private ingestEvent; private ingestProvider; private ingestTokenCost; private ingestTask; private ingestFileEvent; } //# sourceMappingURL=metrics-store.d.ts.map