feat: add status readiness rollup

This commit is contained in:
Affaan Mustafa 2026-05-11 10:40:10 -04:00 committed by Affaan Mustafa
parent d2760d0359
commit fb9a8f2973
4 changed files with 71 additions and 9 deletions

View File

@ -94,7 +94,7 @@ This repo is the raw code only. The guides explain everything.
- **Media and launch tooling**`manim-video`, `remotion-video-creation`, and upgraded social publishing surfaces make technical explainers and launch content part of the same system.
- **Framework and product surface growth**`nestjs-patterns`, richer Codex/OpenCode install surfaces, and expanded cross-harness packaging keep the repo usable beyond Claude Code alone.
- **ECC 2.0 alpha is in-tree** — the Rust control-plane prototype in `ecc2/` now builds locally and exposes `dashboard`, `start`, `sessions`, `status`, `stop`, `resume`, and `daemon` commands. It is usable as an alpha, not yet a general release.
- **Operator status snapshots**`ecc status --markdown --write status.md` turns the local state store into a portable handoff covering active sessions, skill-run health, install health, and pending governance events.
- **Operator status snapshots**`ecc status --markdown --write status.md` turns the local state store into a portable handoff covering readiness, active sessions, skill-run health, install health, and pending governance events.
- **Ecosystem hardening** — AgentShield, ECC Tools cost controls, billing portal work, and website refreshes continue to ship around the core plugin instead of drifting into separate silos.
### v1.9.0 — Selective Install & Language Expansion (Mar 2026)

View File

@ -202,6 +202,22 @@ function summarizeInstallHealth(installations) {
};
}
function summarizeReadiness({ activeSessionCount, skillRuns, installHealth, pendingGovernanceCount }) {
const failedSkillRuns = skillRuns.summary.failureCount;
const warningInstallations = installHealth.warningCount;
const pendingGovernanceEvents = pendingGovernanceCount;
const attentionCount = failedSkillRuns + warningInstallations + pendingGovernanceEvents;
return {
status: attentionCount > 0 ? 'attention' : 'ok',
attentionCount,
activeSessions: activeSessionCount,
failedSkillRuns,
warningInstallations,
pendingGovernanceEvents,
};
}
function normalizeSessionInput(session) {
return {
id: session.id,
@ -568,24 +584,34 @@ function createQueryApi(db) {
const pendingLimit = normalizeLimit(options.pendingLimit, 5);
const activeSessions = listActiveSessionsStatement.all(activeLimit).map(mapSessionRow);
const activeSessionCount = countActiveSessionsStatement.get().total_count;
const recentSkillRuns = listRecentSkillRunsStatement.all(recentSkillRunLimit).map(mapSkillRunRow);
const installations = listInstallStateStatement.all().map(mapInstallStateRow);
const pendingGovernanceEvents = listPendingGovernanceStatement.all(pendingLimit).map(mapGovernanceEventRow);
const skillRuns = {
windowSize: recentSkillRunLimit,
summary: summarizeSkillRuns(recentSkillRuns),
recent: recentSkillRuns,
};
const installHealth = summarizeInstallHealth(installations);
const pendingGovernanceCount = countPendingGovernanceStatement.get().total_count;
return {
generatedAt: new Date().toISOString(),
readiness: summarizeReadiness({
activeSessionCount,
skillRuns,
installHealth,
pendingGovernanceCount,
}),
activeSessions: {
activeCount: countActiveSessionsStatement.get().total_count,
activeCount: activeSessionCount,
sessions: activeSessions,
},
skillRuns: {
windowSize: recentSkillRunLimit,
summary: summarizeSkillRuns(recentSkillRuns),
recent: recentSkillRuns,
},
installHealth: summarizeInstallHealth(installations),
skillRuns,
installHealth,
governance: {
pendingCount: countPendingGovernanceStatement.get().total_count,
pendingCount: pendingGovernanceCount,
events: pendingGovernanceEvents,
},
};

View File

@ -142,9 +142,20 @@ function printGovernance(section) {
}
}
function printReadiness(section) {
console.log(`Readiness: ${section.status}`);
console.log(` Attention items: ${section.attentionCount}`);
console.log(` Active sessions: ${section.activeSessions}`);
console.log(` Failed skill runs: ${section.failedSkillRuns}`);
console.log(` Warning installs: ${section.warningInstallations}`);
console.log(` Pending governance: ${section.pendingGovernanceEvents}`);
}
function printHuman(payload) {
console.log('ECC status\n');
console.log(`Database: ${payload.dbPath}\n`);
printReadiness(payload.readiness);
console.log();
printActiveSessions(payload.activeSessions);
console.log();
printSkillRuns(payload.skillRuns);
@ -169,6 +180,15 @@ function renderMarkdown(payload) {
`Generated: ${payload.generatedAt}`,
`Database: ${formatCode(payload.dbPath)}`,
'',
'## Readiness',
'',
`Status: ${payload.readiness.status}`,
`Attention items: ${payload.readiness.attentionCount}`,
`Active sessions: ${payload.readiness.activeSessions}`,
`Failed skill runs: ${payload.readiness.failedSkillRuns}`,
`Warning installs: ${payload.readiness.warningInstallations}`,
`Pending governance: ${payload.readiness.pendingGovernanceEvents}`,
'',
'## Active Sessions',
'',
`Active sessions: ${payload.activeSessions.activeCount}`,

View File

@ -339,6 +339,12 @@ async function runTests() {
const status = store.getStatus();
store.close();
assert.strictEqual(status.readiness.status, 'attention');
assert.strictEqual(status.readiness.attentionCount, 2);
assert.strictEqual(status.readiness.activeSessions, 1);
assert.strictEqual(status.readiness.failedSkillRuns, 1);
assert.strictEqual(status.readiness.warningInstallations, 0);
assert.strictEqual(status.readiness.pendingGovernanceEvents, 1);
assert.strictEqual(status.activeSessions.activeCount, 1);
assert.strictEqual(status.activeSessions.sessions[0].id, 'session-active');
assert.strictEqual(status.skillRuns.summary.totalCount, 4);
@ -365,6 +371,9 @@ async function runTests() {
store.close();
assert.strictEqual(missingDetail, null);
assert.strictEqual(status.readiness.status, 'ok');
assert.strictEqual(status.readiness.attentionCount, 0);
assert.strictEqual(status.readiness.activeSessions, 0);
assert.strictEqual(status.activeSessions.activeCount, 0);
assert.deepStrictEqual(status.activeSessions.sessions, []);
assert.strictEqual(status.skillRuns.summary.totalCount, 0);
@ -562,11 +571,15 @@ async function runTests() {
const jsonResult = runNode(STATUS_SCRIPT, ['--db', dbPath, '--json']);
assert.strictEqual(jsonResult.status, 0, jsonResult.stderr);
const jsonPayload = parseJson(jsonResult.stdout);
assert.strictEqual(jsonPayload.readiness.status, 'attention');
assert.strictEqual(jsonPayload.readiness.attentionCount, 2);
assert.strictEqual(jsonPayload.activeSessions.activeCount, 1);
assert.strictEqual(jsonPayload.governance.pendingCount, 1);
const humanResult = runNode(STATUS_SCRIPT, ['--db', dbPath]);
assert.strictEqual(humanResult.status, 0, humanResult.stderr);
assert.match(humanResult.stdout, /Readiness: attention/);
assert.match(humanResult.stdout, /Attention items: 2/);
assert.match(humanResult.stdout, /Active sessions: 1/);
assert.match(humanResult.stdout, /Skill runs \(last 20\):/);
assert.match(humanResult.stdout, /Install health: healthy/);
@ -592,6 +605,9 @@ async function runTests() {
assert.strictEqual(result.stdout, written);
assert.match(written, /^# ECC Status/m);
assert.match(written, /Database: `[^`]+state\.db`/);
assert.match(written, /## Readiness/);
assert.match(written, /Status: attention/);
assert.match(written, /Attention items: 2/);
assert.match(written, /- `session-active` \[claude\/dmux-tmux\] active/);
assert.match(written, /Success rate: 66\.7%/);
assert.match(written, /Install health: healthy/);