(snapshot)
| 998 | |
| 999 | const campaigns = readCampaigns(projectRoot); |
| 1000 | const outcomeLedger = readOutcomeLedger(projectRoot); |
| 1001 | const fleetSessions = readFleetSessions(projectRoot); |
| 1002 | const recentActivity = readRecentActivity(projectRoot, recentLimit, now); |
| 1003 | const hookActivity = readHookActivity(projectRoot, recentLimit, now); |
| 1004 | const hookOverhead = readHookOverhead(projectRoot); |
| 1005 | const hookValue = readHookValue(projectRoot); |
| 1006 | const health = readHealth(projectRoot); |
| 1007 | const cost = safeCostDashboard(projectRoot); |
| 1008 | const coordination = readCoordination(projectRoot); |
| 1009 | const worktrees = readWorktrees(projectRoot); |
| 1010 | // Planning-file invalidations can reuse the last git snapshot. The caller |
| 1011 | // performs a full refresh after the TTL, so this avoids spawning git for |
| 1012 | // every SSE update without making repository state indefinitely stale. |
| 1013 | const gitStatus = options.gitStatus || readGitStatus(projectRoot); |
| 1014 | const worktreeReadiness = readWorktreeReadiness(projectRoot); |
| 1015 | const operatorArtifacts = readOperatorArtifacts(projectRoot); |
| 1016 | const pending = readQueueCounts(projectRoot); |
| 1017 | const problems = readProblems(projectRoot, now); |
| 1018 | const routineQuota = readRoutineQuota(projectRoot, now); |
| 1019 | |
| 1020 | const mostRecentTimestamp = [ |
| 1021 | ...recentActivity.map((entry) => entry.timestamp), |
| 1022 | ...hookActivity.map((entry) => entry.timestamp), |
| 1023 | ...campaigns.campaigns.map((campaign) => campaign.modifiedAt), |
| 1024 | ...fleetSessions.map((session) => session.modifiedAt), |
| 1025 | ].filter(Boolean).sort((left, right) => new Date(right).getTime() - new Date(left).getTime())[0] || now.toISOString(); |
| 1026 | |
| 1027 | const snapshot = { |
| 1028 | projectRoot, |
| 1029 | generatedAt: now.toISOString(), |
| 1030 | asOf: relativeTime(mostRecentTimestamp, now), |
| 1031 | planningExists, |
| 1032 | campaigns: campaigns.campaigns, |
| 1033 | skippedCampaigns: campaigns.skipped, |
| 1034 | outcomeLedger, |
| 1035 | fleetSessions, |
| 1036 | cost, |
| 1037 | recentActivity, |
| 1038 | hookActivity, |
| 1039 | hookOverhead, |
| 1040 | hookValue, |
| 1041 | pending, |
| 1042 | health: { |
| 1043 | ...health, |
| 1044 | circuitBreakerTripsThisSession: hookValue.circuitBreakerTrips, |
| 1045 | }, |
| 1046 | coordination, |
| 1047 | worktrees, |
| 1048 | gitStatus, |
| 1049 | worktreeReadiness, |
| 1050 | operatorArtifacts, |
| 1051 | problems: problems.items, |
| 1052 | problemSummary: problems.summary, |
| 1053 | routineQuota, |
| 1054 | }; |
| 1055 | |
| 1056 | snapshot.repairs = buildRepairItems(snapshot); |
| 1057 | snapshot.nextAction = chooseNextAction(snapshot); |
no test coverage detected