roadmapsmith 0.9.13 → 0.9.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -490,11 +490,12 @@ function createModel(scan, tasks, config, customSections, checkedById) {
490
490
  }
491
491
 
492
492
  const productConfig = config.product || {};
493
+ const zeroModeConfig = config.zeroMode || {};
493
494
  const inferredName = inferProjectName(scan.projectRoot || process.cwd());
494
495
  const product = {
495
496
  name: productConfig.name || inferredName,
496
497
  northStar: productConfig.northStar || '',
497
- positioning: productConfig.positioning || '',
498
+ positioning: productConfig.positioning || (zeroModeConfig.problemStatement ? `Core problem: ${zeroModeConfig.problemStatement}` : ''),
498
499
  primaryUser: productConfig.primaryUser || '',
499
500
  targetOutcome: productConfig.targetOutcome || ''
500
501
  };
@@ -510,9 +511,16 @@ function createModel(scan, tasks, config, customSections, checkedById) {
510
511
  'Do not hide validation failures from roadmap consumers'
511
512
  ];
512
513
 
513
- const risks = (productConfig.risks && productConfig.risks.length > 0) ? productConfig.risks : defaultRisks;
514
+ const derivedConstraintRisks = Array.isArray(zeroModeConfig.constraints)
515
+ ? zeroModeConfig.constraints.map((constraint) => `Constraint: ${constraint}`)
516
+ : [];
517
+ const risks = (productConfig.risks && productConfig.risks.length > 0)
518
+ ? productConfig.risks
519
+ : (derivedConstraintRisks.length > 0 ? derivedConstraintRisks : defaultRisks);
514
520
  const antiGoals = (productConfig.antiGoals && productConfig.antiGoals.length > 0) ? productConfig.antiGoals : defaultAntiGoals;
515
- const successCriteria = productConfig.successCriteria || [];
521
+ const successCriteria = (productConfig.successCriteria && productConfig.successCriteria.length > 0)
522
+ ? productConfig.successCriteria
523
+ : (Array.isArray(zeroModeConfig.doneCriteria) ? zeroModeConfig.doneCriteria : []);
516
524
 
517
525
  const northStar = productConfig.northStar
518
526
  || 'Ship validated, high-impact increments with deterministic delivery and transparent completion evidence.';
@@ -555,6 +563,7 @@ function normalizeCandidate(candidate) {
555
563
  function generateRoadmapDocument(options) {
556
564
  const projectRoot = options.projectRoot;
557
565
  const config = options.config;
566
+ const zeroModeConfig = config.zeroMode || {};
558
567
  const plugins = options.plugins || [];
559
568
  const existingContent = options.existingContent || '';
560
569
 
@@ -581,6 +590,24 @@ function generateRoadmapDocument(options) {
581
590
  items: section.items || []
582
591
  }));
583
592
 
593
+ const zeroModeBriefItems = [];
594
+ if (zeroModeConfig.problemStatement) {
595
+ zeroModeBriefItems.push(`- **Problem statement:** ${zeroModeConfig.problemStatement}`);
596
+ }
597
+ if (zeroModeConfig.preferredStack) {
598
+ zeroModeBriefItems.push(`- **Preferred stack:** ${zeroModeConfig.preferredStack}`);
599
+ }
600
+ if (Array.isArray(zeroModeConfig.constraints) && zeroModeConfig.constraints.length > 0) {
601
+ zeroModeBriefItems.push(`- **Constraints:** ${zeroModeConfig.constraints.join('; ')}`);
602
+ }
603
+ if (Array.isArray(zeroModeConfig.doneCriteria) && zeroModeConfig.doneCriteria.length > 0) {
604
+ zeroModeBriefItems.push(`- **Done means:** ${zeroModeConfig.doneCriteria.join('; ')}`);
605
+ }
606
+ const generatedZeroModeSection = zeroModeBriefItems.length > 0 ? [{
607
+ title: 'Zero Mode Brief',
608
+ items: zeroModeBriefItems
609
+ }] : [];
610
+
584
611
  const configSections = (config.customSections || []).map((section) => ({
585
612
  title: section.title,
586
613
  items: section.items || []
@@ -601,7 +628,7 @@ function generateRoadmapDocument(options) {
601
628
  const baseCandidates = buildDefaultCandidates(scan, config);
602
629
  const matcherCandidates = applyTaskMatchers(scan, config);
603
630
  const merged = mergeWithExisting([...baseCandidates, ...matcherCandidates, ...pluginTaskCandidates], existingPhaseTasks);
604
- const model = createModel(scan, merged, config, [profileSection, ...configSections, ...pluginSections], existingCheckedById);
631
+ const model = createModel(scan, merged, config, [profileSection, ...generatedZeroModeSection, ...configSections, ...pluginSections], existingCheckedById);
605
632
  const profile = config.roadmapProfile || 'compact';
606
633
  const managedBody = renderBody(model, profile);
607
634