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.

54 lines 2.45 kB
import { basename } from 'node:path'; import { listProjects } from '../registry.js'; import { isActivated } from '../project.js'; import { loadFrameworkConfig } from '../config.js'; import { readAllAgents } from '../store/index.js'; /** A project's runs, live prepended to the archived history. Forgiving: a failed read is `[]`. */ /** * Derive a {@link ProjectSummary} from a registry record: its display name, whether * it is still activated, and its last activity. Forgiving: a failed read reads as an * inactive project with no activity, never a throw. * * Activity is the sessions themselves (B3). It used to be the newest of those and the latest * `LOGS.md` entry — a committed markdown re-narration of the same sessions, which could only ever * be older than the agent it described. */ export async function summarizeProject(record, deps = {}) { const checkActivated = deps.isActivated ?? isActivated; const loadAgents = deps.readAgents ?? readAllAgents; const loadFileConfig = deps.readFileConfig ?? (path => loadFrameworkConfig(path)); const activated = await checkActivated(record.path).catch(() => false); const [agents, fileConfig] = await Promise.all([ loadAgents(record.path).catch(() => []), loadFileConfig(record.path).catch(() => ({})), ]); // ISO timestamps sort chronologically. const agentActivity = agents.map(r => r.updatedAt || r.startedAt).filter(Boolean); const lastActivityAt = agentActivity.filter((a) => !!a).sort().at(-1); const summary = { id: record.id, path: record.path, name: basename(record.path), activated, }; if (lastActivityAt) summary.lastActivityAt = lastActivityAt; // Omitted when the repo sets nothing, so a project with no yml carries no key at all. if (Object.keys(fileConfig).length) summary.fileConfig = fileConfig; return summary; } /** A {@link ProjectsProvider} backed by the global registry (#390). */ export function defaultProjectsProvider() { return { async list() { const records = await listProjects().catch(() => []); return Promise.all(records.map(record => summarizeProject(record))); }, async resolvePath(id) { const records = await listProjects().catch(() => []); return records.find(record => record.id === id)?.path; }, }; } //# sourceMappingURL=projects.js.map