UNPKG

framework

Version:

The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.

118 lines 5.1 kB
/** * The latest checklist verdict (#431), from the `checklist`/`improve`/`done` bootstrap * events. Null until a checklist has run — a prototype build never loops, and neither * does a run with no review configured (#1372: no preset, no serve); `done` with zero * passes is not a loop ending, so it does not open a status either. `done` closes an * open status out with the final verdict. */ export function loopStatus(events) { let status = null; for (const event of events) { if (event.kind !== 'bootstrap') continue; const e = event.event; if (e.type === 'checklist') { status = { pass: e.pass, passing: e.passing, blockers: [...e.blockers], productionGrade: e.passing, finished: false }; } else if (e.type === 'improve') { status = { pass: e.pass, passing: false, blockers: [...e.blockers], productionGrade: false, finished: false }; } else if (e.type === 'done') { const r = e.result; if (r.passes === 0 && !status) continue; status = { pass: r.passes, passing: r.productionGrade, blockers: [...r.blockers], productionGrade: r.productionGrade, finished: true, }; } } return status; } /** The deploy plan the run decided on, or null before the deploy phase ran. Latest wins. */ export function deployPlan(events) { for (let i = events.length - 1; i >= 0; i--) { const event = events[i]; if (event.kind !== 'bootstrap' || event.event.type !== 'deploy') continue; const p = event.event.plan; return { render: p.render, target: p.target, reason: p.reason }; } return null; } /** * The run's lifecycle progress (#326): the latest `session-name` the agent set and whether * a `ready-for-merge` has fired. Drives the dashboard status label + dot (orange building, * green ready). Always returns a value — an untouched run is `{ readyForMerge: false }`. */ export function runProgress(events) { const progress = { readyForMerge: false }; for (const event of events) { if (event.kind === 'session-name') progress.sessionName = event.name; else if (event.kind === 'ready-for-merge') progress.readyForMerge = true; } return progress; } /** * What the session is armed to hand back, folded from its own events (#1102). * * Both halves start armed, so a run from before this existed — which emits no `handoff-armed` — * reads as armed, which is what it will actually do once it is running new code. Latest wins: the * checkboxes re-emit on every change. * * `initial` seeds the armed pair for a reader whose event stream missed the opening * `handoff-armed` (#1376): the run writes it as its very first event, before the live channel has * attached, so a live tab can only learn the real state from the run record's mirror * (`RunRecord.handoff`) — without it, a session the launcher armed push-only reads as "Open PR". * A `handoff-armed` event in the stream still wins: it is newer than any record snapshot. */ export function handoffState(events, initial) { const state = { push: initial?.push ?? true, pr: initial?.pr ?? true, merge: initial?.merge ?? false }; for (const event of events) { if (event.kind === 'handoff-armed') { state.push = event.push; state.pr = event.pr; // Absent on pre-#1382 events: keep the seed rather than flipping an armed merge off. if (event.merge !== undefined) state.merge = event.merge; } else if (event.kind === 'handoff') { state.result = event.outcome === 'done' ? { outcome: 'done', ...(event.url ? { url: event.url } : {}) } : event.outcome === 'failed' ? { outcome: 'failed', error: event.error } : { outcome: 'skipped', reason: event.reason }; } } return state; } /** * The session behind the run (#431): the driver + workspace from the opening `session` * event, then the id and any deep link from the latest `session-update`. Null before the * session opens. The link is what the old dashboard surfaced as "open session". */ export function sessionInfo(events) { let info = null; for (const event of events) { if (event.kind === 'session') { info = { driver: event.driver, fake: event.fake, workspace: event.workspace, ...(event.sessionLink ? { sessionLink: event.sessionLink } : {}), ...(event.model ? { model: event.model } : {}), }; } else if (event.kind === 'session-update') { info = { ...(info ?? {}), sessionId: event.sessionId, ...(event.sessionLink ? { sessionLink: event.sessionLink } : {}) }; } } return info; } //# sourceMappingURL=run-view.js.map