@planu/cli 0.54.2 → 0.56.0

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.
Files changed (178) hide show
  1. package/dist/config/license-plans.json +1 -0
  2. package/dist/engine/doc-generator/executive-summary/executive-summary-generator.d.ts +7 -1
  3. package/dist/engine/doc-generator/executive-summary/executive-summary-generator.d.ts.map +1 -1
  4. package/dist/engine/doc-generator/executive-summary/executive-summary-generator.js +16 -3
  5. package/dist/engine/doc-generator/executive-summary/executive-summary-generator.js.map +1 -1
  6. package/dist/engine/doc-generator/executive-summary/html-template.d.ts +5 -2
  7. package/dist/engine/doc-generator/executive-summary/html-template.d.ts.map +1 -1
  8. package/dist/engine/doc-generator/executive-summary/html-template.js +7 -3
  9. package/dist/engine/doc-generator/executive-summary/html-template.js.map +1 -1
  10. package/dist/engine/doc-generator/per-spec-report/executive-report.d.ts +3 -1
  11. package/dist/engine/doc-generator/per-spec-report/executive-report.d.ts.map +1 -1
  12. package/dist/engine/doc-generator/per-spec-report/executive-report.js +22 -2
  13. package/dist/engine/doc-generator/per-spec-report/executive-report.js.map +1 -1
  14. package/dist/engine/doc-generator/per-spec-report/html-wrapper.d.ts +5 -3
  15. package/dist/engine/doc-generator/per-spec-report/html-wrapper.d.ts.map +1 -1
  16. package/dist/engine/doc-generator/per-spec-report/html-wrapper.js +27 -6
  17. package/dist/engine/doc-generator/per-spec-report/html-wrapper.js.map +1 -1
  18. package/dist/engine/doc-generator/per-spec-report/spec-data-extractor.d.ts +1 -0
  19. package/dist/engine/doc-generator/per-spec-report/spec-data-extractor.d.ts.map +1 -1
  20. package/dist/engine/doc-generator/per-spec-report/spec-data-extractor.js +29 -0
  21. package/dist/engine/doc-generator/per-spec-report/spec-data-extractor.js.map +1 -1
  22. package/dist/engine/doc-generator/per-spec-report/spec-section-builders.d.ts +8 -1
  23. package/dist/engine/doc-generator/per-spec-report/spec-section-builders.d.ts.map +1 -1
  24. package/dist/engine/doc-generator/per-spec-report/spec-section-builders.js +188 -0
  25. package/dist/engine/doc-generator/per-spec-report/spec-section-builders.js.map +1 -1
  26. package/dist/engine/doc-generator/per-spec-report/technical-report.d.ts +3 -1
  27. package/dist/engine/doc-generator/per-spec-report/technical-report.d.ts.map +1 -1
  28. package/dist/engine/doc-generator/per-spec-report/technical-report.js +24 -7
  29. package/dist/engine/doc-generator/per-spec-report/technical-report.js.map +1 -1
  30. package/dist/engine/doc-generator/portal/analytics-page.d.ts +8 -0
  31. package/dist/engine/doc-generator/portal/analytics-page.d.ts.map +1 -0
  32. package/dist/engine/doc-generator/portal/analytics-page.js +265 -0
  33. package/dist/engine/doc-generator/portal/analytics-page.js.map +1 -0
  34. package/dist/engine/doc-generator/portal/architecture-page.d.ts +6 -0
  35. package/dist/engine/doc-generator/portal/architecture-page.d.ts.map +1 -0
  36. package/dist/engine/doc-generator/portal/architecture-page.js +250 -0
  37. package/dist/engine/doc-generator/portal/architecture-page.js.map +1 -0
  38. package/dist/engine/doc-generator/portal/changelog-page.d.ts +6 -0
  39. package/dist/engine/doc-generator/portal/changelog-page.d.ts.map +1 -0
  40. package/dist/engine/doc-generator/portal/changelog-page.js +204 -0
  41. package/dist/engine/doc-generator/portal/changelog-page.js.map +1 -0
  42. package/dist/engine/doc-generator/portal/data-aggregators/accuracy-aggregator.d.ts +11 -0
  43. package/dist/engine/doc-generator/portal/data-aggregators/accuracy-aggregator.d.ts.map +1 -0
  44. package/dist/engine/doc-generator/portal/data-aggregators/accuracy-aggregator.js +24 -0
  45. package/dist/engine/doc-generator/portal/data-aggregators/accuracy-aggregator.js.map +1 -0
  46. package/dist/engine/doc-generator/portal/data-aggregators/bottleneck-detector.d.ts +9 -0
  47. package/dist/engine/doc-generator/portal/data-aggregators/bottleneck-detector.d.ts.map +1 -0
  48. package/dist/engine/doc-generator/portal/data-aggregators/bottleneck-detector.js +31 -0
  49. package/dist/engine/doc-generator/portal/data-aggregators/bottleneck-detector.js.map +1 -0
  50. package/dist/engine/doc-generator/portal/data-aggregators/burndown-aggregator.d.ts +10 -0
  51. package/dist/engine/doc-generator/portal/data-aggregators/burndown-aggregator.d.ts.map +1 -0
  52. package/dist/engine/doc-generator/portal/data-aggregators/burndown-aggregator.js +77 -0
  53. package/dist/engine/doc-generator/portal/data-aggregators/burndown-aggregator.js.map +1 -0
  54. package/dist/engine/doc-generator/portal/data-aggregators/velocity-aggregator.d.ts +9 -0
  55. package/dist/engine/doc-generator/portal/data-aggregators/velocity-aggregator.d.ts.map +1 -0
  56. package/dist/engine/doc-generator/portal/data-aggregators/velocity-aggregator.js +31 -0
  57. package/dist/engine/doc-generator/portal/data-aggregators/velocity-aggregator.js.map +1 -0
  58. package/dist/engine/doc-generator/portal/decision-page.d.ts +6 -0
  59. package/dist/engine/doc-generator/portal/decision-page.d.ts.map +1 -0
  60. package/dist/engine/doc-generator/portal/decision-page.js +169 -0
  61. package/dist/engine/doc-generator/portal/decision-page.js.map +1 -0
  62. package/dist/engine/doc-generator/portal/decision-timeline-builder.d.ts +8 -0
  63. package/dist/engine/doc-generator/portal/decision-timeline-builder.d.ts.map +1 -0
  64. package/dist/engine/doc-generator/portal/decision-timeline-builder.js +131 -0
  65. package/dist/engine/doc-generator/portal/decision-timeline-builder.js.map +1 -0
  66. package/dist/engine/doc-generator/portal/index.d.ts +19 -0
  67. package/dist/engine/doc-generator/portal/index.d.ts.map +1 -0
  68. package/dist/engine/doc-generator/portal/index.js +21 -0
  69. package/dist/engine/doc-generator/portal/index.js.map +1 -0
  70. package/dist/engine/doc-generator/portal/kanban-view-builder.d.ts +8 -0
  71. package/dist/engine/doc-generator/portal/kanban-view-builder.d.ts.map +1 -0
  72. package/dist/engine/doc-generator/portal/kanban-view-builder.js +140 -0
  73. package/dist/engine/doc-generator/portal/kanban-view-builder.js.map +1 -0
  74. package/dist/engine/doc-generator/portal/portal-breadcrumbs.d.ts +27 -0
  75. package/dist/engine/doc-generator/portal/portal-breadcrumbs.d.ts.map +1 -0
  76. package/dist/engine/doc-generator/portal/portal-breadcrumbs.js +139 -0
  77. package/dist/engine/doc-generator/portal/portal-breadcrumbs.js.map +1 -0
  78. package/dist/engine/doc-generator/portal/portal-landing-cards.d.ts +8 -0
  79. package/dist/engine/doc-generator/portal/portal-landing-cards.d.ts.map +1 -0
  80. package/dist/engine/doc-generator/portal/portal-landing-cards.js +177 -0
  81. package/dist/engine/doc-generator/portal/portal-landing-cards.js.map +1 -0
  82. package/dist/engine/doc-generator/portal/portal-navbar.d.ts +15 -0
  83. package/dist/engine/doc-generator/portal/portal-navbar.d.ts.map +1 -0
  84. package/dist/engine/doc-generator/portal/portal-navbar.js +143 -0
  85. package/dist/engine/doc-generator/portal/portal-navbar.js.map +1 -0
  86. package/dist/engine/doc-generator/portal/portal-page-detector.d.ts +22 -0
  87. package/dist/engine/doc-generator/portal/portal-page-detector.d.ts.map +1 -0
  88. package/dist/engine/doc-generator/portal/portal-page-detector.js +58 -0
  89. package/dist/engine/doc-generator/portal/portal-page-detector.js.map +1 -0
  90. package/dist/engine/doc-generator/portal/portal-theme.d.ts +7 -0
  91. package/dist/engine/doc-generator/portal/portal-theme.d.ts.map +1 -0
  92. package/dist/engine/doc-generator/portal/portal-theme.js +53 -0
  93. package/dist/engine/doc-generator/portal/portal-theme.js.map +1 -0
  94. package/dist/engine/doc-generator/portal/risk-gauge-svg.d.ts +5 -0
  95. package/dist/engine/doc-generator/portal/risk-gauge-svg.d.ts.map +1 -0
  96. package/dist/engine/doc-generator/portal/risk-gauge-svg.js +80 -0
  97. package/dist/engine/doc-generator/portal/risk-gauge-svg.js.map +1 -0
  98. package/dist/engine/doc-generator/portal/risk-matrix-svg.d.ts +11 -0
  99. package/dist/engine/doc-generator/portal/risk-matrix-svg.d.ts.map +1 -0
  100. package/dist/engine/doc-generator/portal/risk-matrix-svg.js +181 -0
  101. package/dist/engine/doc-generator/portal/risk-matrix-svg.js.map +1 -0
  102. package/dist/engine/doc-generator/portal/risk-page.d.ts +7 -0
  103. package/dist/engine/doc-generator/portal/risk-page.d.ts.map +1 -0
  104. package/dist/engine/doc-generator/portal/risk-page.js +219 -0
  105. package/dist/engine/doc-generator/portal/risk-page.js.map +1 -0
  106. package/dist/engine/doc-generator/portal/roadmap-page.d.ts +7 -0
  107. package/dist/engine/doc-generator/portal/roadmap-page.d.ts.map +1 -0
  108. package/dist/engine/doc-generator/portal/roadmap-page.js +204 -0
  109. package/dist/engine/doc-generator/portal/roadmap-page.js.map +1 -0
  110. package/dist/engine/doc-generator/portal/svg-charts/bar-chart.d.ts +4 -0
  111. package/dist/engine/doc-generator/portal/svg-charts/bar-chart.d.ts.map +1 -0
  112. package/dist/engine/doc-generator/portal/svg-charts/bar-chart.js +50 -0
  113. package/dist/engine/doc-generator/portal/svg-charts/bar-chart.js.map +1 -0
  114. package/dist/engine/doc-generator/portal/svg-charts/chart-utils.d.ts +16 -0
  115. package/dist/engine/doc-generator/portal/svg-charts/chart-utils.d.ts.map +1 -0
  116. package/dist/engine/doc-generator/portal/svg-charts/chart-utils.js +45 -0
  117. package/dist/engine/doc-generator/portal/svg-charts/chart-utils.js.map +1 -0
  118. package/dist/engine/doc-generator/portal/svg-charts/line-chart.d.ts +16 -0
  119. package/dist/engine/doc-generator/portal/svg-charts/line-chart.d.ts.map +1 -0
  120. package/dist/engine/doc-generator/portal/svg-charts/line-chart.js +159 -0
  121. package/dist/engine/doc-generator/portal/svg-charts/line-chart.js.map +1 -0
  122. package/dist/engine/doc-generator/portal/svg-charts/pie-chart.d.ts +7 -0
  123. package/dist/engine/doc-generator/portal/svg-charts/pie-chart.d.ts.map +1 -0
  124. package/dist/engine/doc-generator/portal/svg-charts/pie-chart.js +52 -0
  125. package/dist/engine/doc-generator/portal/svg-charts/pie-chart.js.map +1 -0
  126. package/dist/engine/doc-generator/proposal/proposal-gantt-builder.d.ts +8 -0
  127. package/dist/engine/doc-generator/proposal/proposal-gantt-builder.d.ts.map +1 -0
  128. package/dist/engine/doc-generator/proposal/proposal-gantt-builder.js +126 -0
  129. package/dist/engine/doc-generator/proposal/proposal-gantt-builder.js.map +1 -0
  130. package/dist/engine/doc-generator/proposal/proposal-generator.d.ts +10 -0
  131. package/dist/engine/doc-generator/proposal/proposal-generator.d.ts.map +1 -0
  132. package/dist/engine/doc-generator/proposal/proposal-generator.js +93 -0
  133. package/dist/engine/doc-generator/proposal/proposal-generator.js.map +1 -0
  134. package/dist/engine/doc-generator/proposal/proposal-html-wrapper.d.ts +7 -0
  135. package/dist/engine/doc-generator/proposal/proposal-html-wrapper.d.ts.map +1 -0
  136. package/dist/engine/doc-generator/proposal/proposal-html-wrapper.js +31 -0
  137. package/dist/engine/doc-generator/proposal/proposal-html-wrapper.js.map +1 -0
  138. package/dist/engine/doc-generator/proposal/proposal-i18n.d.ts +12 -0
  139. package/dist/engine/doc-generator/proposal/proposal-i18n.d.ts.map +1 -0
  140. package/dist/engine/doc-generator/proposal/proposal-i18n.js +230 -0
  141. package/dist/engine/doc-generator/proposal/proposal-i18n.js.map +1 -0
  142. package/dist/engine/doc-generator/proposal/proposal-kpi-builder.d.ts +8 -0
  143. package/dist/engine/doc-generator/proposal/proposal-kpi-builder.d.ts.map +1 -0
  144. package/dist/engine/doc-generator/proposal/proposal-kpi-builder.js +32 -0
  145. package/dist/engine/doc-generator/proposal/proposal-kpi-builder.js.map +1 -0
  146. package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.d.ts +14 -0
  147. package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.d.ts.map +1 -0
  148. package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.js +248 -0
  149. package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.js.map +1 -0
  150. package/dist/engine/doc-generator/proposal/proposal-section-builders.d.ts +13 -0
  151. package/dist/engine/doc-generator/proposal/proposal-section-builders.d.ts.map +1 -0
  152. package/dist/engine/doc-generator/proposal/proposal-section-builders.js +423 -0
  153. package/dist/engine/doc-generator/proposal/proposal-section-builders.js.map +1 -0
  154. package/dist/engine/doc-generator/proposal/proposal-themes.d.ts +4 -0
  155. package/dist/engine/doc-generator/proposal/proposal-themes.d.ts.map +1 -0
  156. package/dist/engine/doc-generator/proposal/proposal-themes.js +194 -0
  157. package/dist/engine/doc-generator/proposal/proposal-themes.js.map +1 -0
  158. package/dist/engine/spec-summary-html.d.ts.map +1 -1
  159. package/dist/engine/spec-summary-html.js +17 -5
  160. package/dist/engine/spec-summary-html.js.map +1 -1
  161. package/dist/index.js +2 -0
  162. package/dist/index.js.map +1 -1
  163. package/dist/tools/generate-proposal.d.ts +3 -0
  164. package/dist/tools/generate-proposal.d.ts.map +1 -0
  165. package/dist/tools/generate-proposal.js +166 -0
  166. package/dist/tools/generate-proposal.js.map +1 -0
  167. package/dist/types/docs.d.ts +75 -0
  168. package/dist/types/docs.d.ts.map +1 -1
  169. package/dist/types/portal.d.ts +128 -0
  170. package/dist/types/portal.d.ts.map +1 -0
  171. package/dist/types/portal.js +3 -0
  172. package/dist/types/portal.js.map +1 -0
  173. package/dist/types/proposal.d.ts +57 -0
  174. package/dist/types/proposal.d.ts.map +1 -0
  175. package/dist/types/proposal.js +2 -0
  176. package/dist/types/proposal.js.map +1 -0
  177. package/package.json +1 -1
  178. package/src/config/license-plans.json +1 -0
@@ -133,6 +133,7 @@
133
133
  "validate_team_results",
134
134
  "audit_claude_config",
135
135
  "generate_docs_site",
136
+ "generate_proposal",
136
137
  "export_spec",
137
138
  "analyze_spec_dependencies",
138
139
  "validate_annotations",
@@ -1,7 +1,13 @@
1
1
  import type { ProjectKnowledge, Spec, GeneratedDocument } from '../../../types/index.js';
2
2
  /**
3
3
  * Generate a self-contained HTML executive summary document.
4
+ * Output is placed at planu/executive-summary.html (portal hub location).
4
5
  * Returns a GeneratedDocument with type 'executive-summary'.
6
+ *
7
+ * @param knowledge - Project knowledge data.
8
+ * @param specs - All project specs.
9
+ * @param _language - Language hint (reserved for future i18n).
10
+ * @param availablePages - Portal pages that exist on disk (for navbar display).
5
11
  */
6
- export declare function generateExecutiveSummary(knowledge: ProjectKnowledge, specs: Spec[], _language: string): GeneratedDocument;
12
+ export declare function generateExecutiveSummary(knowledge: ProjectKnowledge, specs: Spec[], _language: string, availablePages?: string[]): GeneratedDocument;
7
13
  //# sourceMappingURL=executive-summary-generator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executive-summary-generator.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/executive-summary-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAmBzF;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,EAAE,MAAM,GAChB,iBAAiB,CAiCnB"}
1
+ {"version":3,"file":"executive-summary-generator.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/executive-summary-generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAqBzF;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,IAAI,EAAE,EACb,SAAS,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,iBAAiB,CAuCnB"}
@@ -2,17 +2,28 @@ import { buildExecutiveSummaryData } from './data-extractors.js';
2
2
  import { generateArchitectureSvg, generateTimelineSvg, generateRiskDistributionSvg, } from './svg-diagrams.js';
3
3
  import { wrapInHtmlDocument } from './html-template.js';
4
4
  import { buildHeaderSection, buildOverviewSection, buildSpecsTableSection, buildEstimationSection, buildRiskSection, buildArchitectureSection, buildTimelineSection, buildFooterSection, } from './section-builders.js';
5
+ import { buildNavbar } from '../portal/portal-navbar.js';
6
+ import { getPortalThemeCSS } from '../portal/portal-theme.js';
5
7
  /**
6
8
  * Generate a self-contained HTML executive summary document.
9
+ * Output is placed at planu/executive-summary.html (portal hub location).
7
10
  * Returns a GeneratedDocument with type 'executive-summary'.
11
+ *
12
+ * @param knowledge - Project knowledge data.
13
+ * @param specs - All project specs.
14
+ * @param _language - Language hint (reserved for future i18n).
15
+ * @param availablePages - Portal pages that exist on disk (for navbar display).
8
16
  */
9
- export function generateExecutiveSummary(knowledge, specs, _language) {
17
+ export function generateExecutiveSummary(knowledge, specs, _language, availablePages) {
10
18
  const data = buildExecutiveSummaryData(knowledge, specs);
11
19
  const archSvg = generateArchitectureSvg(data.architecture);
12
20
  const timelineSvg = generateTimelineSvg(data.specs);
13
21
  const riskSvg = generateRiskDistributionSvg(data.riskProfile);
14
22
  const hasActuals = data.specs.some((s) => s.actualDevHours !== undefined);
23
+ // Navbar is at root level (planu/), so basePath is empty
24
+ const navbar = buildNavbar('executive-summary', '', availablePages);
15
25
  const body = [
26
+ navbar,
16
27
  buildHeaderSection(data.projectName, data.generatedAt, data.specs.length),
17
28
  buildOverviewSection(data.architecture),
18
29
  buildSpecsTableSection(data.specs),
@@ -23,11 +34,13 @@ export function generateExecutiveSummary(knowledge, specs, _language) {
23
34
  buildFooterSection(),
24
35
  ].join('\n');
25
36
  const title = `Executive Summary — ${data.projectName}`;
26
- const content = wrapInHtmlDocument(title, body);
37
+ // Inject portal theme CSS before the existing document CSS
38
+ const content = wrapInHtmlDocument(title, body, getPortalThemeCSS());
27
39
  return {
28
40
  type: 'executive-summary',
29
41
  title,
30
- path: 'docs/executive-summary.html',
42
+ // Changed from docs/ to planu/ — this is now part of the portal hub
43
+ path: 'planu/executive-summary.html',
31
44
  content,
32
45
  audience: 'stakeholder',
33
46
  sections: [],
@@ -1 +1 @@
1
- {"version":3,"file":"executive-summary-generator.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/executive-summary-generator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAA2B,EAC3B,KAAa,EACb,SAAiB;IAEjB,MAAM,IAAI,GAAG,yBAAyB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEzD,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC;IAE1E,MAAM,IAAI,GAAG;QACX,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACzE,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC;QACvC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;QACnD,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;QAC3C,wBAAwB,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;QACpD,oBAAoB,CAAC,WAAW,CAAC;QACjC,kBAAkB,EAAE;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,KAAK,GAAG,uBAAuB,IAAI,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEhD,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,KAAK;QACL,IAAI,EAAE,6BAA6B;QACnC,OAAO;QACP,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"executive-summary-generator.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/executive-summary-generator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAA2B,EAC3B,KAAa,EACb,SAAiB,EACjB,cAAyB;IAEzB,MAAM,IAAI,GAAG,yBAAyB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEzD,MAAM,OAAO,GAAG,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC3D,MAAM,WAAW,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAE9D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC;IAE1E,yDAAyD;IACzD,MAAM,MAAM,GAAG,WAAW,CAAC,mBAAmB,EAAE,EAAE,EAAE,cAAc,CAAC,CAAC;IAEpE,MAAM,IAAI,GAAG;QACX,MAAM;QACN,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;QACzE,oBAAoB,CAAC,IAAI,CAAC,YAAY,CAAC;QACvC,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC,sBAAsB,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC;QACnD,gBAAgB,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC;QAC3C,wBAAwB,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC;QACpD,oBAAoB,CAAC,WAAW,CAAC;QACjC,kBAAkB,EAAE;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,KAAK,GAAG,uBAAuB,IAAI,CAAC,WAAW,EAAE,CAAC;IACxD,2DAA2D;IAC3D,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAAC,CAAC;IAErE,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,KAAK;QACL,oEAAoE;QACpE,IAAI,EAAE,8BAA8B;QACpC,OAAO;QACP,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC1C,CAAC;AACJ,CAAC"}
@@ -1,3 +1,6 @@
1
- /** Wrap body content in a full HTML document with inline CSS. */
2
- export declare function wrapInHtmlDocument(title: string, bodyContent: string): string;
1
+ /**
2
+ * Wrap body content in a full HTML document with inline CSS.
3
+ * Optionally prepend extra CSS (e.g. portal theme variables) before the page CSS.
4
+ */
5
+ export declare function wrapInHtmlDocument(title: string, bodyContent: string, extraCss?: string): string;
3
6
  //# sourceMappingURL=html-template.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/html-template.ts"],"names":[],"mappings":"AAgCA,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAa7E"}
1
+ {"version":3,"file":"html-template.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/html-template.ts"],"names":[],"mappings":"AAgCA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAchG"}
@@ -28,15 +28,19 @@ const CSS = `
28
28
  svg { max-width: 100%; height: auto; }
29
29
  .footer { margin-top: 32px; padding-top: 16px; border-top: 1px solid #e5e7eb; font-size: 0.78em; color: #9ca3af; text-align: center; }
30
30
  `;
31
- /** Wrap body content in a full HTML document with inline CSS. */
32
- export function wrapInHtmlDocument(title, bodyContent) {
31
+ /**
32
+ * Wrap body content in a full HTML document with inline CSS.
33
+ * Optionally prepend extra CSS (e.g. portal theme variables) before the page CSS.
34
+ */
35
+ export function wrapInHtmlDocument(title, bodyContent, extraCss) {
36
+ const styles = extraCss !== undefined ? `${extraCss}${CSS}` : CSS;
33
37
  return `<!DOCTYPE html>
34
38
  <html lang="en">
35
39
  <head>
36
40
  <meta charset="UTF-8"/>
37
41
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
38
42
  <title>${escapeHtml(title)}</title>
39
- <style>${CSS}</style>
43
+ <style>${styles}</style>
40
44
  </head>
41
45
  <body>
42
46
  ${bodyContent}
@@ -1 +1 @@
1
- {"version":3,"file":"html-template.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/html-template.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BX,CAAC;AAEF,iEAAiE;AACjE,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,WAAmB;IACnE,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;WACjB,GAAG;;;EAGZ,WAAW;;QAEL,CAAC;AACT,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
1
+ {"version":3,"file":"html-template.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/executive-summary/html-template.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BX,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,WAAmB,EAAE,QAAiB;IACtF,MAAM,MAAM,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,OAAO;;;;;WAKE,UAAU,CAAC,KAAK,CAAC;WACjB,MAAM;;;EAGf,WAAW;;QAEL,CAAC;AACT,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import type { Spec, GeneratedDocument } from '../../../types/index.js';
2
2
  /**
3
3
  * Generate a self-contained HTML executive report for a single spec.
4
- * Includes: header, metrics, dependencies, effort distribution SVG, tags.
4
+ * Includes: header, metrics, actuals comparison, acceptance criteria,
5
+ * risk scorecard, living spec status, dependencies, effort SVG, tags.
6
+ * All rich sections are conditionally rendered based on data availability.
5
7
  */
6
8
  export declare function generatePerSpecExecutiveReport(spec: Spec, affectedFiles: string[], architecturalDecisions: string[]): GeneratedDocument;
7
9
  //# sourceMappingURL=executive-report.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executive-report.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/executive-report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAYvE;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EAAE,EACvB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,iBAAiB,CA2BnB"}
1
+ {"version":3,"file":"executive-report.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/executive-report.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAiBvE;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EAAE,EACvB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,iBAAiB,CA4DnB"}
@@ -1,18 +1,38 @@
1
1
  import { extractPerSpecData } from './spec-data-extractor.js';
2
- import { buildSpecHeaderSection, buildSpecMetricsSection, buildSpecDependenciesSection, buildSpecTagsSection, buildEffortDistributionSvg, buildSpecFooterSection, } from './spec-section-builders.js';
2
+ import { buildSpecHeaderSection, buildSpecMetricsSection, buildSpecDependenciesSection, buildSpecTagsSection, buildEffortDistributionSvg, buildSpecFooterSection, buildAcceptanceCriteriaSection, buildActualsComparisonSection, buildRiskScorecard, buildLivingSpecSection, buildSimilarSpecsSection, } from './spec-section-builders.js';
3
3
  import { wrapPerSpecHtml } from './html-wrapper.js';
4
4
  /**
5
5
  * Generate a self-contained HTML executive report for a single spec.
6
- * Includes: header, metrics, dependencies, effort distribution SVG, tags.
6
+ * Includes: header, metrics, actuals comparison, acceptance criteria,
7
+ * risk scorecard, living spec status, dependencies, effort SVG, tags.
8
+ * All rich sections are conditionally rendered based on data availability.
7
9
  */
8
10
  export function generatePerSpecExecutiveReport(spec, affectedFiles, architecturalDecisions) {
9
11
  const data = extractPerSpecData(spec, affectedFiles, architecturalDecisions);
12
+ const actualsSection = data.actuals !== undefined
13
+ ? buildActualsComparisonSection(data.actuals, data.devHours, data.reviewHours, data.totalCostUsd)
14
+ : '';
15
+ const acSection = data.acceptanceCriteria !== undefined && data.acceptanceCriteria.length > 0
16
+ ? buildAcceptanceCriteriaSection(data.acceptanceCriteria)
17
+ : '';
18
+ const riskSection = data.riskBreakdown !== undefined && data.riskBreakdown.length > 0
19
+ ? buildRiskScorecard(data.riskBreakdown)
20
+ : '';
21
+ const livingSection = data.livingSpec !== undefined ? buildLivingSpecSection(data.livingSpec) : '';
22
+ const similarSection = data.similarSpecs !== undefined && data.similarSpecs.length > 0
23
+ ? buildSimilarSpecsSection(data.similarSpecs)
24
+ : '';
10
25
  const body = [
11
26
  buildSpecHeaderSection(data),
12
27
  buildSpecMetricsSection(data),
28
+ actualsSection,
13
29
  buildEffortDistributionSvg(data.devHours, data.reviewHours),
30
+ acSection,
31
+ riskSection,
32
+ livingSection,
14
33
  buildSpecDependenciesSection(data),
15
34
  buildSpecTagsSection(data),
35
+ similarSection,
16
36
  buildSpecFooterSection(),
17
37
  ]
18
38
  .filter(Boolean)
@@ -1 +1 @@
1
- {"version":3,"file":"executive-report.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/executive-report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,GACvB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,8BAA8B,CAC5C,IAAU,EACV,aAAuB,EACvB,sBAAgC;IAEhC,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAE7E,MAAM,IAAI,GAAG;QACX,sBAAsB,CAAC,IAAI,CAAC;QAC5B,uBAAuB,CAAC,IAAI,CAAC;QAC7B,0BAA0B,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC;QAC3D,4BAA4B,CAAC,IAAI,CAAC;QAClC,oBAAoB,CAAC,IAAI,CAAC;QAC1B,sBAAsB,EAAE;KACzB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,KAAK,GAAG,sBAAsB,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACjE,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,KAAK;QACL,IAAI,EAAE,uBAAuB;QAC7B,OAAO;QACP,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;KAC5B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"executive-report.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/executive-report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,sBAAsB,EACtB,uBAAuB,EACvB,4BAA4B,EAC5B,oBAAoB,EACpB,0BAA0B,EAC1B,sBAAsB,EACtB,8BAA8B,EAC9B,6BAA6B,EAC7B,kBAAkB,EAClB,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,UAAU,8BAA8B,CAC5C,IAAU,EACV,aAAuB,EACvB,sBAAgC;IAEhC,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,sBAAsB,CAAC,CAAC;IAE7E,MAAM,cAAc,GAClB,IAAI,CAAC,OAAO,KAAK,SAAS;QACxB,CAAC,CAAC,6BAA6B,CAC3B,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,WAAW,EAChB,IAAI,CAAC,YAAY,CAClB;QACH,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,SAAS,GACb,IAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,GAAG,CAAC;QACzE,CAAC,CAAC,8BAA8B,CAAC,IAAI,CAAC,kBAAkB,CAAC;QACzD,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,WAAW,GACf,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QAC/D,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,CAAC;QACxC,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,aAAa,GACjB,IAAI,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/E,MAAM,cAAc,GAClB,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;QAC7D,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC;QAC7C,CAAC,CAAC,EAAE,CAAC;IAET,MAAM,IAAI,GAAG;QACX,sBAAsB,CAAC,IAAI,CAAC;QAC5B,uBAAuB,CAAC,IAAI,CAAC;QAC7B,cAAc;QACd,0BAA0B,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC;QAC3D,SAAS;QACT,WAAW;QACX,aAAa;QACb,4BAA4B,CAAC,IAAI,CAAC;QAClC,oBAAoB,CAAC,IAAI,CAAC;QAC1B,cAAc;QACd,sBAAsB,EAAE;KACzB;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,KAAK,GAAG,sBAAsB,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;IACjE,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAE7C,OAAO;QACL,IAAI,EAAE,oBAAoB;QAC1B,KAAK;QACL,IAAI,EAAE,uBAAuB;QAC7B,OAAO;QACP,QAAQ,EAAE,aAAa;QACvB,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,YAAY,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;KAC5B,CAAC;AACJ,CAAC"}
@@ -1,6 +1,8 @@
1
+ import type { PerSpecHtmlOptions } from '../../../types/docs.js';
2
+ export type { PerSpecHtmlOptions };
1
3
  /**
2
- * Wrap body content in a full HTML document with per-spec report CSS.
3
- * Optionally includes extra scripts (e.g. Mermaid.js CDN).
4
+ * Wrap body content in a full HTML document with per-spec report CSS + portal navbar.
5
+ * basePath is always "../../" because per-spec reports live in planu/specs/SPEC-XXX/.
4
6
  */
5
- export declare function wrapPerSpecHtml(title: string, bodyContent: string, extraScripts?: string): string;
7
+ export declare function wrapPerSpecHtml(title: string, bodyContent: string, extraScriptsOrOptions?: string | PerSpecHtmlOptions): string;
6
8
  //# sourceMappingURL=html-wrapper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"html-wrapper.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/html-wrapper.ts"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBjG"}
1
+ {"version":3,"file":"html-wrapper.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/html-wrapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AA+BjE,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAEnC;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,qBAAqB,CAAC,EAAE,MAAM,GAAG,kBAAkB,GAClD,MAAM,CA0CR"}
@@ -1,9 +1,12 @@
1
- // Planu — HTML wrapper for per-spec reports (shared CSS)
1
+ // Planu — HTML wrapper for per-spec reports (shared CSS + portal navbar)
2
+ import { getPortalThemeCSS } from '../portal/portal-theme.js';
3
+ import { buildNavbar } from '../portal/portal-navbar.js';
4
+ import { buildBreadcrumbs } from '../portal/portal-breadcrumbs.js';
2
5
  const CSS = `
3
6
  @page { margin: 2cm; size: A4; }
4
7
  @media print { print-color-adjust: exact; -webkit-print-color-adjust: exact; }
5
8
  * { box-sizing: border-box; margin: 0; padding: 0; }
6
- body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: 14px; color: #1f2937; max-width: 900px; margin: 0 auto; padding: 24px; background: #fff; }
9
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; font-size: 14px; color: #1f2937; max-width: 960px; margin: 0 auto; padding: 24px; background: #fff; }
7
10
  .header { border-bottom: 3px solid #4F46E5; padding-bottom: 16px; margin-bottom: 24px; }
8
11
  .header h1 { font-size: 1.1em; color: #6b7280; font-weight: 400; margin-bottom: 4px; }
9
12
  .header h2 { font-size: 1.8em; color: #111827; font-weight: 700; }
@@ -28,24 +31,42 @@ const CSS = `
28
31
  .footer { margin-top: 32px; padding-top: 16px; border-top: 1px solid #e5e7eb; font-size: 0.78em; color: #9ca3af; text-align: center; }
29
32
  `;
30
33
  /**
31
- * Wrap body content in a full HTML document with per-spec report CSS.
32
- * Optionally includes extra scripts (e.g. Mermaid.js CDN).
34
+ * Wrap body content in a full HTML document with per-spec report CSS + portal navbar.
35
+ * basePath is always "../../" because per-spec reports live in planu/specs/SPEC-XXX/.
33
36
  */
34
- export function wrapPerSpecHtml(title, bodyContent, extraScripts) {
37
+ export function wrapPerSpecHtml(title, bodyContent, extraScriptsOrOptions) {
38
+ // Backward-compatible: accept plain string (extraScripts) or options object
39
+ let extraScripts;
40
+ let options = {};
41
+ if (typeof extraScriptsOrOptions === 'string') {
42
+ extraScripts = extraScriptsOrOptions;
43
+ }
44
+ else if (extraScriptsOrOptions !== undefined) {
45
+ options = extraScriptsOrOptions;
46
+ extraScripts = options.extraScripts;
47
+ }
35
48
  const escapedTitle = title
36
49
  .replace(/&/g, '&amp;')
37
50
  .replace(/</g, '&lt;')
38
51
  .replace(/>/g, '&gt;')
39
52
  .replace(/"/g, '&quot;');
53
+ // Per-spec reports are always 2 levels deep: planu/specs/SPEC-XXX/report.html
54
+ const basePath = '../../';
55
+ const navbar = buildNavbar(options.activePage ?? 'dashboard', basePath, options.availablePages);
56
+ const breadcrumbsHtml = options.breadcrumbs && options.breadcrumbs.length > 0
57
+ ? buildBreadcrumbs(options.breadcrumbs)
58
+ : '';
40
59
  return `<!DOCTYPE html>
41
60
  <html lang="en">
42
61
  <head>
43
62
  <meta charset="UTF-8"/>
44
63
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
45
64
  <title>${escapedTitle}</title>
46
- <style>${CSS}</style>
65
+ <style>${getPortalThemeCSS()}${CSS}</style>
47
66
  </head>
48
67
  <body>
68
+ ${navbar}
69
+ ${breadcrumbsHtml}
49
70
  ${bodyContent}
50
71
  ${extraScripts ?? ''}
51
72
  </body>
@@ -1 +1 @@
1
- {"version":3,"file":"html-wrapper.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/html-wrapper.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BX,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,WAAmB,EAAE,YAAqB;IACvF,MAAM,YAAY,GAAG,KAAK;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE3B,OAAO;;;;;WAKE,YAAY;WACZ,GAAG;;;EAGZ,WAAW;EACX,YAAY,IAAI,EAAE;;QAEZ,CAAC;AACT,CAAC"}
1
+ {"version":3,"file":"html-wrapper.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/html-wrapper.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAGnE,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BX,CAAC;AAIF;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,WAAmB,EACnB,qBAAmD;IAEnD,4EAA4E;IAC5E,IAAI,YAAgC,CAAC;IACrC,IAAI,OAAO,GAAuB,EAAE,CAAC;IAErC,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE,CAAC;QAC9C,YAAY,GAAG,qBAAqB,CAAC;IACvC,CAAC;SAAM,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;QAC/C,OAAO,GAAG,qBAAqB,CAAC;QAChC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IACtC,CAAC;IAED,MAAM,YAAY,GAAG,KAAK;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAE3B,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC1B,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,IAAI,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC,CAAC;IAEhG,MAAM,eAAe,GACnB,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;QACnD,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC;QACvC,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;;;;;WAKE,YAAY;WACZ,iBAAiB,EAAE,GAAG,GAAG;;;EAGlC,MAAM;EACN,eAAe;EACf,WAAW;EACX,YAAY,IAAI,EAAE;;QAEZ,CAAC;AACT,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import type { Spec, PerSpecReportData } from '../../../types/index.js';
2
2
  /**
3
3
  * Extract report data from a single spec for HTML reports.
4
+ * Populates all available fields including impactAnalysis, actuals, etc.
4
5
  */
5
6
  export declare function extractPerSpecData(spec: Spec, affectedFiles: string[], architecturalDecisions: string[]): PerSpecReportData;
6
7
  //# sourceMappingURL=spec-data-extractor.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-data-extractor.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,iBAAiB,EAAe,MAAM,yBAAyB,CAAC;AAEpF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EAAE,EACvB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,iBAAiB,CAqBnB"}
1
+ {"version":3,"file":"spec-data-extractor.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-data-extractor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,IAAI,EACJ,iBAAiB,EAIlB,MAAM,yBAAyB,CAAC;AAEjC;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EAAE,EACvB,sBAAsB,EAAE,MAAM,EAAE,GAC/B,iBAAiB,CAwBnB"}
@@ -1,5 +1,6 @@
1
1
  /**
2
2
  * Extract report data from a single spec for HTML reports.
3
+ * Populates all available fields including impactAnalysis, actuals, etc.
3
4
  */
4
5
  export function extractPerSpecData(spec, affectedFiles, architecturalDecisions) {
5
6
  return {
@@ -21,6 +22,34 @@ export function extractPerSpecData(spec, affectedFiles, architecturalDecisions)
21
22
  affectedFiles,
22
23
  architecturalDecisions,
23
24
  generatedAt: new Date().toISOString(),
25
+ impactAnalysis: extractImpactAnalysis(spec),
26
+ actuals: extractActuals(spec),
27
+ estimationReasoning: spec.estimation.tokenOptimization.reasoning || undefined,
28
+ };
29
+ }
30
+ function extractImpactAnalysis(spec) {
31
+ if (!spec.impactAnalysis) {
32
+ return undefined;
33
+ }
34
+ const ia = spec.impactAnalysis;
35
+ return {
36
+ affectedModules: ia.affectedModules,
37
+ affectedFiles: ia.affectedFiles,
38
+ breakingChanges: ia.breakingChanges,
39
+ rollbackPlan: ia.rollbackPlan,
40
+ };
41
+ }
42
+ function extractActuals(spec) {
43
+ if (!spec.actuals) {
44
+ return undefined;
45
+ }
46
+ const a = spec.actuals;
47
+ return {
48
+ devHours: a.devHours,
49
+ reviewHours: a.reviewHours,
50
+ totalCostUsd: a.totalCostUsd,
51
+ completedAt: a.completedAt,
52
+ notes: a.notes,
24
53
  };
25
54
  }
26
55
  //# sourceMappingURL=spec-data-extractor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-data-extractor.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-data-extractor.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAU,EACV,aAAuB,EACvB,sBAAgC;IAEhC,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ;QAClC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW;QACxC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY;QAC1C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,EAAmB;QAC7B,aAAa;QACb,sBAAsB;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"spec-data-extractor.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-data-extractor.ts"],"names":[],"mappings":"AASA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAU,EACV,aAAuB,EACvB,sBAAgC;IAEhC,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QACnC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ;QAClC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW;QACxC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY;QAC1C,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,EAAmB;QAC7B,aAAa;QACb,sBAAsB;QACtB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,cAAc,EAAE,qBAAqB,CAAC,IAAI,CAAC;QAC3C,OAAO,EAAE,cAAc,CAAC,IAAI,CAAC;QAC7B,mBAAmB,EAAE,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,SAAS,IAAI,SAAS;KAC9E,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAU;IACvC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC;IAC/B,OAAO;QACL,eAAe,EAAE,EAAE,CAAC,eAAe;QACnC,aAAa,EAAE,EAAE,CAAC,aAAa;QAC/B,eAAe,EAAE,EAAE,CAAC,eAAe;QACnC,YAAY,EAAE,EAAE,CAAC,YAAY;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,IAAU;IAChC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACvB,OAAO;QACL,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,WAAW,EAAE,CAAC,CAAC,WAAW;QAC1B,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { PerSpecReportData } from '../../../types/index.js';
1
+ import type { PerSpecReportData, PerSpecAcceptanceCriterion, PerSpecActuals, PerSpecImpactAnalysis, PerSpecLivingSpec, PerSpecRiskDimension } from '../../../types/index.js';
2
2
  export declare function buildSpecHeaderSection(data: PerSpecReportData): string;
3
3
  export declare function buildSpecMetricsSection(data: PerSpecReportData): string;
4
4
  export declare function buildSpecDependenciesSection(data: PerSpecReportData): string;
@@ -7,4 +7,11 @@ export declare function buildEffortDistributionSvg(devHours: number, reviewHours
7
7
  export declare function buildAffectedFilesSection(files: string[]): string;
8
8
  export declare function buildArchDecisionsSection(decisions: string[]): string;
9
9
  export declare function buildSpecFooterSection(): string;
10
+ export declare function buildAcceptanceCriteriaSection(criteria: PerSpecAcceptanceCriterion[]): string;
11
+ export declare function buildActualsComparisonSection(actuals: PerSpecActuals, devHours: number, reviewHours: number, totalCostUsd: number): string;
12
+ export declare function buildImpactAnalysisSection(impact: PerSpecImpactAnalysis): string;
13
+ export declare function buildRiskScorecard(risks: PerSpecRiskDimension[]): string;
14
+ export declare function buildLivingSpecSection(living: PerSpecLivingSpec): string;
15
+ export declare function buildEstimationReasoningSection(reasoning: string): string;
16
+ export declare function buildSimilarSpecsSection(similarSpecs: string[]): string;
10
17
  //# sourceMappingURL=spec-section-builders.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-section-builders.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-section-builders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAUjE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAiBtE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAWvE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkB5E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAapE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAoBxF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAWjE;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAWrE;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C"}
1
+ {"version":3,"file":"spec-section-builders.d.ts","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-section-builders.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,0BAA0B,EAC1B,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACrB,MAAM,yBAAyB,CAAC;AAUjC,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAiBtE;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAWvE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkB5E;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAapE;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAoBxF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAWjE;AAED,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAWrE;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAI/C;AAUD,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,0BAA0B,EAAE,GAAG,MAAM,CA8B7F;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,CA0DR;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CA6BhF;AASD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,MAAM,CAgCxE;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAexE;AAED,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQzE;AAED,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,CAWvE"}
@@ -105,6 +105,194 @@ export function buildSpecFooterSection() {
105
105
  Generated by <strong>Planu</strong> &mdash; Spec Driven Development
106
106
  </div>`;
107
107
  }
108
+ // ── SPEC-139: Rich data section builders ──────────────────────────────────────
109
+ const AC_STATUS_CONFIG = {
110
+ met: { icon: '●', color: '#059669', label: 'Met' },
111
+ pending: { icon: '○', color: '#d97706', label: 'Pending' },
112
+ drift: { icon: '▲', color: '#dc2626', label: 'Drift' },
113
+ };
114
+ export function buildAcceptanceCriteriaSection(criteria) {
115
+ if (criteria.length === 0) {
116
+ return '';
117
+ }
118
+ const rows = criteria
119
+ .map((c) => {
120
+ const defaultAcConfig = { icon: '○', color: '#d97706', label: 'Pending' };
121
+ const cfg = AC_STATUS_CONFIG[c.status] ?? defaultAcConfig;
122
+ return `<tr>
123
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;">${escapeHtml(c.criterion)}</td>
124
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;white-space:nowrap;">
125
+ <span style="color:${cfg.color};font-weight:600;">${cfg.icon} ${escapeHtml(cfg.label)}</span>
126
+ </td>
127
+ </tr>`;
128
+ })
129
+ .join('\n');
130
+ return `<div class="section">
131
+ <h2>Acceptance Criteria</h2>
132
+ <table style="width:100%;border-collapse:collapse;font-size:14px;">
133
+ <thead>
134
+ <tr style="background:#f9fafb;">
135
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Criterion</th>
136
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Status</th>
137
+ </tr>
138
+ </thead>
139
+ <tbody>${rows}</tbody>
140
+ </table>
141
+ </div>`;
142
+ }
143
+ export function buildActualsComparisonSection(actuals, devHours, reviewHours, totalCostUsd) {
144
+ const devVariance = actuals.devHours - devHours;
145
+ const costVariance = actuals.totalCostUsd - totalCostUsd;
146
+ const devVariancePct = devHours > 0 ? Math.round((Math.abs(devVariance) / devHours) * 100) : 0;
147
+ const costVariancePct = totalCostUsd > 0 ? Math.round((Math.abs(costVariance) / totalCostUsd) * 100) : 0;
148
+ const devSign = devVariance >= 0 ? '+' : '-';
149
+ const costSign = costVariance >= 0 ? '+' : '-';
150
+ const devColor = devVariance > 0 ? '#dc2626' : '#059669';
151
+ const costColor = costVariance > 0 ? '#dc2626' : '#059669';
152
+ const completedDate = actuals.completedAt
153
+ ? new Date(actuals.completedAt).toLocaleDateString('en-US', {
154
+ year: 'numeric',
155
+ month: 'long',
156
+ day: 'numeric',
157
+ })
158
+ : '—';
159
+ const notesRow = actuals.notes
160
+ ? `<p style="margin-top:12px;font-size:13px;color:#6b7280;"><strong>Notes:</strong> ${escapeHtml(actuals.notes)}</p>`
161
+ : '';
162
+ return `<div class="section">
163
+ <h2>Estimated vs Actual</h2>
164
+ <p style="font-size:13px;color:#6b7280;margin-bottom:12px;">Completed: ${escapeHtml(completedDate)}</p>
165
+ <table style="width:100%;border-collapse:collapse;font-size:14px;">
166
+ <thead>
167
+ <tr style="background:#f9fafb;">
168
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Metric</th>
169
+ <th style="padding:10px 12px;text-align:right;border-bottom:2px solid #e5e7eb;font-weight:600;">Estimated</th>
170
+ <th style="padding:10px 12px;text-align:right;border-bottom:2px solid #e5e7eb;font-weight:600;">Actual</th>
171
+ <th style="padding:10px 12px;text-align:right;border-bottom:2px solid #e5e7eb;font-weight:600;">Variance</th>
172
+ </tr>
173
+ </thead>
174
+ <tbody>
175
+ <tr>
176
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;">Dev Hours</td>
177
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;">${String(devHours)}h</td>
178
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;">${String(actuals.devHours)}h</td>
179
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;color:${devColor};font-weight:600;">${devSign}${String(devVariancePct)}%</td>
180
+ </tr>
181
+ <tr>
182
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;">Review Hours</td>
183
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;">${String(reviewHours)}h</td>
184
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;">${String(actuals.reviewHours)}h</td>
185
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;text-align:right;color:#6b7280;">—</td>
186
+ </tr>
187
+ <tr>
188
+ <td style="padding:8px 12px;">Total Cost</td>
189
+ <td style="padding:8px 12px;text-align:right;">$${String(totalCostUsd)}</td>
190
+ <td style="padding:8px 12px;text-align:right;">$${String(actuals.totalCostUsd)}</td>
191
+ <td style="padding:8px 12px;text-align:right;color:${costColor};font-weight:600;">${costSign}${String(costVariancePct)}%</td>
192
+ </tr>
193
+ </tbody>
194
+ </table>
195
+ ${notesRow}
196
+ </div>`;
197
+ }
198
+ export function buildImpactAnalysisSection(impact) {
199
+ const breakingBadge = impact.breakingChanges
200
+ ? `<span style="background:#fee2e2;color:#dc2626;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;">BREAKING CHANGES</span>`
201
+ : `<span style="background:#d1fae5;color:#059669;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;">No Breaking Changes</span>`;
202
+ const modulesHtml = impact.affectedModules.length > 0
203
+ ? `<p><strong>Affected Modules:</strong> ${impact.affectedModules.map(escapeHtml).join(', ')}</p>`
204
+ : '';
205
+ const filesHtml = impact.affectedFiles.length > 0
206
+ ? `<p><strong>Affected Files (${String(impact.affectedFiles.length)}):</strong></p>
207
+ <ul style="font-size:13px;margin:4px 0 8px 0;">
208
+ ${impact.affectedFiles.map((f) => `<li><code>${escapeHtml(f)}</code></li>`).join('\n ')}
209
+ </ul>`
210
+ : '';
211
+ const rollbackHtml = impact.rollbackPlan
212
+ ? `<p><strong>Rollback Plan:</strong> ${escapeHtml(impact.rollbackPlan)}</p>`
213
+ : '';
214
+ return `<div class="section">
215
+ <h2>Impact Analysis</h2>
216
+ <p>${breakingBadge}</p>
217
+ ${modulesHtml}
218
+ ${filesHtml}
219
+ ${rollbackHtml}
220
+ </div>`;
221
+ }
222
+ const RISK_LEVEL_COLORS = {
223
+ low: { bg: '#d1fae5', fg: '#065f46' },
224
+ medium: { bg: '#fef3c7', fg: '#92400e' },
225
+ high: { bg: '#fee2e2', fg: '#991b1b' },
226
+ critical: { bg: '#fce7f3', fg: '#9d174d' },
227
+ };
228
+ export function buildRiskScorecard(risks) {
229
+ if (risks.length === 0) {
230
+ return '';
231
+ }
232
+ const rows = risks
233
+ .map((r) => {
234
+ const defaultColors = { bg: '#e5e7eb', fg: '#374151' };
235
+ const colors = RISK_LEVEL_COLORS[r.level.toLowerCase()] ?? defaultColors;
236
+ return `<tr>
237
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;font-weight:500;">${escapeHtml(r.dimension)}</td>
238
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;">
239
+ <span style="background:${colors.bg};color:${colors.fg};padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;">${escapeHtml(r.level)}</span>
240
+ </td>
241
+ <td style="padding:8px 12px;border-bottom:1px solid #e5e7eb;font-size:13px;color:#6b7280;">${escapeHtml(r.detail)}</td>
242
+ </tr>`;
243
+ })
244
+ .join('\n');
245
+ return `<div class="section">
246
+ <h2>Risk Scorecard</h2>
247
+ <table style="width:100%;border-collapse:collapse;font-size:14px;">
248
+ <thead>
249
+ <tr style="background:#f9fafb;">
250
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Dimension</th>
251
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Level</th>
252
+ <th style="padding:10px 12px;text-align:left;border-bottom:2px solid #e5e7eb;font-weight:600;">Detail</th>
253
+ </tr>
254
+ </thead>
255
+ <tbody>${rows}</tbody>
256
+ </table>
257
+ </div>`;
258
+ }
259
+ export function buildLivingSpecSection(living) {
260
+ const pct = Math.min(100, Math.max(0, living.completionPercent));
261
+ const barColor = pct >= 80 ? '#059669' : pct >= 50 ? '#d97706' : '#dc2626';
262
+ const driftBadge = living.driftDetected
263
+ ? `<span style="background:#fee2e2;color:#dc2626;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;margin-left:8px;">DRIFT DETECTED</span>`
264
+ : `<span style="background:#d1fae5;color:#059669;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;margin-left:8px;">In Sync</span>`;
265
+ return `<div class="section">
266
+ <h2>Living Spec Status</h2>
267
+ <p><strong>Completion:</strong> ${String(pct)}%${driftBadge}</p>
268
+ <div style="background:#e5e7eb;border-radius:8px;height:12px;width:100%;margin:8px 0;">
269
+ <div style="background:${barColor};border-radius:8px;height:12px;width:${String(pct)}%;transition:width 0.3s;"></div>
270
+ </div>
271
+ <p style="font-size:13px;color:#6b7280;">Changed files tracked: ${String(living.changedFileCount)}</p>
272
+ </div>`;
273
+ }
274
+ export function buildEstimationReasoningSection(reasoning) {
275
+ if (!reasoning) {
276
+ return '';
277
+ }
278
+ return `<div class="section">
279
+ <h2>Estimation Reasoning</h2>
280
+ <p style="font-size:14px;color:#374151;line-height:1.6;">${escapeHtml(reasoning)}</p>
281
+ </div>`;
282
+ }
283
+ export function buildSimilarSpecsSection(similarSpecs) {
284
+ if (similarSpecs.length === 0) {
285
+ return '';
286
+ }
287
+ const badges = similarSpecs
288
+ .map((s) => `<span class="badge badge-draft" style="margin-right:4px;">${escapeHtml(s)}</span>`)
289
+ .join('');
290
+ return `<div class="section">
291
+ <h2>Similar Specs</h2>
292
+ <p>${badges}</p>
293
+ </div>`;
294
+ }
295
+ // ── Internal helpers ──────────────────────────────────────────────────────────
108
296
  function metricCard(value, label) {
109
297
  return `<div class="metric-card">
110
298
  <div class="metric-value">${escapeHtml(value)}</div>
@@ -1 +1 @@
1
- {"version":3,"file":"spec-section-builders.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-section-builders.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec-section-builders.js","sourceRoot":"","sources":["../../../../src/engine/doc-generator/per-spec-report/spec-section-builders.ts"],"names":[],"mappings":"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"}