UNPKG

rigjs

Version:

A multi-repos dev tool based on yarn and git.Rigjs is intended to be the simplest way to develop,share and deliver codes between different developers or different projects.

65 lines (56 loc) 3.11 kB
import fs from 'fs'; import path from 'path'; import print from '../print'; import { requireCrew } from '../crew/config'; import { readPlanTasks } from '../crew/planTask'; import { parseEntityMap } from './journal'; // Cross-entity task-status rollup, shared by `rig om status` (print) and `rig om sync` (→ overmind.md). export interface ProjectRollup { name: string; registered: boolean; counts: Record<string, number>; total: number; } export interface EntityRollup { entity: string; projects: ProjectRollup[]; } const STATUS_ORDER = ['ready', 'in-progress', 'blocked', 'pending', 'draft', 'done']; export function collectRollup(vault: string, projPath: Map<string, string>): EntityRollup[] { const indexPath = path.join(vault, 'journal', 'INDEX.md'); if (!fs.existsSync(indexPath)) return []; const out: EntityRollup[] = []; for (const [entity, projects] of parseEntityMap(fs.readFileSync(indexPath, 'utf8'))) { const projs: ProjectRollup[] = projects.map(name => { const p = projPath.get(name); const counts: Record<string, number> = {}; let total = 0; if (p) for (const t of readPlanTasks(p)) { counts[t.status] = (counts[t.status] || 0) + 1; total++; } return { name, registered: !!p, counts, total }; }); out.push({ entity, projects: projs }); } return out; } export function fmtCounts(counts: Record<string, number>): string { const known = STATUS_ORDER.filter(s => counts[s]).map(s => `${s}:${counts[s]}`); const extra = Object.keys(counts).filter(k => !STATUS_ORDER.includes(k)).map(k => `${k}:${counts[k]}`); return [...known, ...extra].join(' ') || '—'; } // `rig orchestrate overview [--write]` — cross-entity task-status rollup. Prints by default; // `--write` (re)generates overmind.md. (Merged from the former `om status` + `om sync`.) export function crewOverview(opts: { crew?: string; write?: boolean }): void { const crew = requireCrew(opts.crew); const projPath = new Map((crew.projects || []).map(p => [p.name, p.path])); const rollup = collectRollup(crew.vault, projPath); if (rollup.length === 0) { print.info('no entities found in journal/INDEX.md'); return; } for (const e of rollup) { print.info(e.entity); for (const p of e.projects) { // eslint-disable-next-line no-console console.log(` ${p.name}${p.registered ? '' : ' (not registered in crew)'}: ${fmtCounts(p.counts)}`); } } if (!opts.write) return; const lines = ['# overmind', '', '> Generated by `rig orchestrate overview --write` — cross-entity project + task-status index. Do not hand-edit; re-run.', '']; for (const e of rollup) { lines.push(`## ${e.entity}`, ''); for (const p of e.projects) lines.push(`- **${p.name}**${p.registered ? '' : ' _(not registered)_'}${p.total} task(s): ${fmtCounts(p.counts)}`); lines.push(''); } const file = path.join(crew.vault, 'overmind.md'); fs.writeFileSync(file, `${lines.join('\n').replace(/\n{3,}/g, '\n\n').replace(/\n*$/, '')}\n`, 'utf8'); print.succeed(`wrote ${file} (${rollup.length} entit${rollup.length === 1 ? 'y' : 'ies'})`); }