feat(mosaic): route prdy and mission --plan through PrdService (#1275)

- mosaic prdy becomes a thin adapter: --init/--update (wizard for TTY,
  service otherwise), --import with --accept-successor, --export
- mosaic mission --plan persists the mission↔PRD linkage (mission id +
  version marker, PRD id + version) through the service instead of invoking
  the wizard as a second writer; non-TTY runs create non-interactively
This commit is contained in:
fargo
2026-08-17 16:46:06 -05:00
parent e291bfb837
commit 2c5d208691
2 changed files with 97 additions and 11 deletions
+32 -5
View File
@@ -256,14 +256,41 @@ async function planMission(
console.log(`Planning mission: ${mission.name}\n`);
try {
const { runPrdWizard } = await import('@mosaicstack/prdy');
await runPrdWizard({
// Thin adapter: the PRD authority (create + mission↔PRD linkage) lives in
// PrdService — no second writer path. The mission's updatedAt serves as
// its version marker (the gateway exposes no numeric mission version).
const { PrdService, runPrdWizard } = await import('@mosaicstack/prdy');
const service = new PrdService({ projectPath: process.cwd() });
if (process.stdout.isTTY) {
const created = await runPrdWizard({
name: mission.name,
projectPath: process.cwd(),
interactive: true,
});
const linked = await service.linkMission({
prdId: created.id,
missionId: mission.id,
missionVersion: mission.updatedAt,
requirementIds: [],
});
console.log(
`\nMission ${mission.id} linked to PRD ${linked.id} v${linked.version} (docs/prdy/).`,
);
return;
}
const doc = await service.planForMission({
name: mission.name,
projectPath: process.cwd(),
interactive: true,
missionId: mission.id,
missionVersion: mission.updatedAt,
requirementIds: [],
});
console.log(
`PRD created and linked: ${doc.id} v${doc.version} — mission ${mission.id} (docs/prdy/).`,
);
} catch (err) {
console.error(`PRD wizard failed: ${err instanceof Error ? err.message : String(err)}`);
console.error(`PRD planning failed: ${err instanceof Error ? err.message : String(err)}`);
process.exit(1);
}
}