@design-ai/cli 4.55.0 → 4.57.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 (301) hide show
  1. package/.claude-plugin/plugin.json +109 -25
  2. package/CHANGELOG.md +75 -0
  3. package/README.ko.md +15 -32
  4. package/README.md +18 -31
  5. package/cli/bin/design-ai.mjs +1 -0
  6. package/cli/commands/help.mjs +7 -4
  7. package/cli/commands/index.mjs +292 -0
  8. package/cli/commands/learn-help.mjs +149 -0
  9. package/cli/commands/learn-print-profile.mjs +373 -0
  10. package/cli/commands/learn-print-restore.mjs +349 -0
  11. package/cli/commands/learn-print-signals.mjs +453 -0
  12. package/cli/commands/learn.mjs +60 -1281
  13. package/cli/commands/pack.mjs +7 -3
  14. package/cli/commands/prompt.mjs +7 -3
  15. package/cli/commands/search.mjs +94 -1
  16. package/cli/lib/dispatch.mjs +3 -0
  17. package/cli/lib/embedding-index.mjs +199 -0
  18. package/cli/lib/embedding-provider.mjs +121 -0
  19. package/cli/lib/embedding-rerank.mjs +52 -0
  20. package/cli/lib/learn-args.mjs +490 -0
  21. package/cli/lib/learn-backup.mjs +748 -0
  22. package/cli/lib/learn-curation.mjs +612 -0
  23. package/cli/lib/learn-eval.mjs +459 -0
  24. package/cli/lib/learn-profile.mjs +763 -0
  25. package/cli/lib/learn-select.mjs +223 -0
  26. package/cli/lib/learn-shared.mjs +158 -0
  27. package/cli/lib/learn-test-support.mjs +218 -0
  28. package/cli/lib/learn-usage.mjs +360 -0
  29. package/cli/lib/learn.mjs +83 -3694
  30. package/cli/lib/lexical.mjs +137 -0
  31. package/cli/lib/local-config.mjs +110 -0
  32. package/cli/lib/mcp-server.mjs +221 -13
  33. package/cli/lib/pack.mjs +31 -4
  34. package/cli/lib/prompt.mjs +42 -4
  35. package/cli/lib/recall.mjs +193 -0
  36. package/cli/lib/retrieval-index.mjs +0 -0
  37. package/cli/lib/search-ranked.mjs +170 -0
  38. package/cli/lib/search.mjs +11 -1
  39. package/cli/lib/signals-backlog-commands.mjs +673 -0
  40. package/cli/lib/signals-backlog.mjs +361 -0
  41. package/cli/lib/signals-eval.mjs +176 -0
  42. package/cli/lib/signals-readiness.mjs +247 -0
  43. package/cli/lib/signals-registry.mjs +377 -0
  44. package/cli/lib/signals-render.mjs +478 -0
  45. package/cli/lib/signals-shared.mjs +75 -0
  46. package/cli/lib/signals.mjs +16 -2337
  47. package/cli/lib/site-analysis.mjs +297 -0
  48. package/cli/lib/site-args.mjs +433 -0
  49. package/cli/lib/site-bundle-build.mjs +127 -0
  50. package/cli/lib/site-bundle-check.mjs +454 -0
  51. package/cli/lib/site-bundle-commands.mjs +95 -0
  52. package/cli/lib/site-bundle-compare.mjs +157 -0
  53. package/cli/lib/site-bundle-contract.mjs +79 -0
  54. package/cli/lib/site-bundle-files.mjs +87 -0
  55. package/cli/lib/site-bundle-handoff-expected.mjs +173 -0
  56. package/cli/lib/site-bundle-handoff-runbook-action-summary.mjs +332 -0
  57. package/cli/lib/site-bundle-handoff-runbook-actions.mjs +113 -0
  58. package/cli/lib/site-bundle-handoff-runbook-evidence-fields.mjs +164 -0
  59. package/cli/lib/site-bundle-handoff-runbook-evidence.mjs +334 -0
  60. package/cli/lib/site-bundle-handoff-runbook-format.mjs +31 -0
  61. package/cli/lib/site-bundle-handoff-runbook-human-lines.mjs +167 -0
  62. package/cli/lib/site-bundle-handoff-runbook-maps.mjs +238 -0
  63. package/cli/lib/site-bundle-handoff-runbook-next-step.mjs +278 -0
  64. package/cli/lib/site-bundle-handoff-runbook-stage-metadata.mjs +84 -0
  65. package/cli/lib/site-bundle-handoff-runbook.mjs +444 -0
  66. package/cli/lib/site-bundle-handoff-summary.mjs +183 -0
  67. package/cli/lib/site-bundle-handoff.mjs +271 -0
  68. package/cli/lib/site-bundle-readme.mjs +98 -0
  69. package/cli/lib/site-bundle-repair-report.mjs +143 -0
  70. package/cli/lib/site-bundle-repair.mjs +68 -0
  71. package/cli/lib/site-content.mjs +399 -0
  72. package/cli/lib/site-evidence.mjs +35 -0
  73. package/cli/lib/site-mcp-commands.mjs +28 -0
  74. package/cli/lib/site-mcp-probes.mjs +159 -0
  75. package/cli/lib/site-mcp-readiness.mjs +157 -0
  76. package/cli/lib/site-mcp-report.mjs +324 -0
  77. package/cli/lib/site-next-actions.mjs +333 -0
  78. package/cli/lib/site-options.mjs +104 -0
  79. package/cli/lib/site-prompts.mjs +332 -0
  80. package/cli/lib/site-starter.mjs +153 -0
  81. package/cli/lib/site-strings.mjs +23 -0
  82. package/cli/lib/site-tasks.mjs +93 -0
  83. package/cli/lib/site-test-support.mjs +68 -0
  84. package/cli/lib/site-workflow-graph.mjs +309 -0
  85. package/cli/lib/site-workspace.mjs +492 -0
  86. package/cli/lib/site.mjs +108 -6617
  87. package/cli/lib/skill-proposals-apply-commands.mjs +135 -0
  88. package/cli/lib/skill-proposals-apply-contract.mjs +750 -0
  89. package/cli/lib/skill-proposals-apply-plan.mjs +118 -0
  90. package/cli/lib/skill-proposals-generate.mjs +298 -0
  91. package/cli/lib/skill-proposals-render.mjs +532 -0
  92. package/cli/lib/skill-proposals-review.mjs +262 -0
  93. package/cli/lib/skill-proposals.mjs +15 -2046
  94. package/cli/lib/workspace-args.mjs +83 -0
  95. package/cli/lib/workspace-git.mjs +169 -0
  96. package/cli/lib/workspace-learning.mjs +483 -0
  97. package/cli/lib/workspace-repo.mjs +139 -0
  98. package/cli/lib/workspace-report.mjs +283 -0
  99. package/cli/lib/workspace-test-support.mjs +99 -0
  100. package/cli/lib/workspace.mjs +30 -1056
  101. package/docs/AI-LEARNING-PHASE2.md +215 -0
  102. package/docs/DISTRIBUTION.ko.md +35 -6
  103. package/docs/DISTRIBUTION.md +35 -8
  104. package/docs/NEXT-SURFACE-DECISION.md +125 -0
  105. package/docs/PRODUCT-READINESS.md +3 -3
  106. package/docs/RELEASE-CHECKLIST.md +20 -3
  107. package/docs/RELEASE-GATES.ko.md +35 -0
  108. package/docs/RELEASE-GATES.md +234 -0
  109. package/docs/ROADMAP.md +2232 -8
  110. package/docs/external-status.md +20 -7
  111. package/docs/inspection-20260630.md +169 -0
  112. package/docs/integrations/design-ai-mcp-server.md +35 -3
  113. package/docs/integrations/vscode-walkthrough.ko.md +3 -3
  114. package/docs/integrations/vscode-walkthrough.md +3 -3
  115. package/docs/reference/ant-design.md +413 -0
  116. package/docs/reference/awesome-design-md.md +439 -0
  117. package/docs/reference/mui.md +783 -0
  118. package/docs/reference/shadcn-ui.md +298 -0
  119. package/docs/site-overrides/main.html +1 -1
  120. package/examples/component-accordion-actions.md +5 -5
  121. package/examples/component-accordion-details.md +5 -5
  122. package/examples/component-accordion-summary.md +5 -5
  123. package/examples/component-accordion.md +3 -3
  124. package/examples/component-affix.md +1 -1
  125. package/examples/component-alert-dialog.md +1 -1
  126. package/examples/component-alert-title.md +1 -1
  127. package/examples/component-alert.md +3 -3
  128. package/examples/component-anchor.md +1 -1
  129. package/examples/component-app-bar.md +1 -1
  130. package/examples/component-aspect-ratio.md +1 -1
  131. package/examples/component-auto-complete.md +2 -2
  132. package/examples/component-avatar-group.md +5 -5
  133. package/examples/component-avatar.md +3 -3
  134. package/examples/component-back-top.md +1 -1
  135. package/examples/component-backdrop.md +1 -1
  136. package/examples/component-badge.md +3 -3
  137. package/examples/component-border-beam.md +3 -3
  138. package/examples/component-bottom-navigation.md +1 -1
  139. package/examples/component-box.md +1 -1
  140. package/examples/component-breadcrumb.md +3 -3
  141. package/examples/component-button-base.md +3 -3
  142. package/examples/component-button-group.md +2 -2
  143. package/examples/component-button.md +3 -3
  144. package/examples/component-calendar.md +2 -2
  145. package/examples/component-card-actions.md +1 -1
  146. package/examples/component-card-content.md +1 -1
  147. package/examples/component-card-header.md +1 -1
  148. package/examples/component-card-media.md +1 -1
  149. package/examples/component-card.md +3 -3
  150. package/examples/component-carousel.md +2 -2
  151. package/examples/component-cascader.md +1 -1
  152. package/examples/component-chart.md +1 -1
  153. package/examples/component-checkbox.md +3 -3
  154. package/examples/component-click-away-listener.md +1 -1
  155. package/examples/component-code.md +1 -1
  156. package/examples/component-collapsible.md +1 -1
  157. package/examples/component-color-picker.md +1 -1
  158. package/examples/component-combobox.md +1 -1
  159. package/examples/component-command.md +1 -1
  160. package/examples/component-config-provider.md +3 -3
  161. package/examples/component-context-menu.md +1 -1
  162. package/examples/component-css-baseline.md +3 -3
  163. package/examples/component-date-picker.md +2 -2
  164. package/examples/component-descriptions.md +1 -1
  165. package/examples/component-dialog-actions.md +1 -1
  166. package/examples/component-dialog-content-text.md +1 -1
  167. package/examples/component-dialog-content.md +1 -1
  168. package/examples/component-dialog-title.md +1 -1
  169. package/examples/component-dialog.md +2 -2
  170. package/examples/component-divider.md +3 -3
  171. package/examples/component-drawer.md +3 -3
  172. package/examples/component-dropdown.md +3 -3
  173. package/examples/component-empty.md +2 -2
  174. package/examples/component-fade.md +1 -1
  175. package/examples/component-field.md +1 -1
  176. package/examples/component-filled-input.md +1 -1
  177. package/examples/component-flex.md +1 -1
  178. package/examples/component-float-button.md +2 -2
  179. package/examples/component-form-control-label.md +1 -1
  180. package/examples/component-form-control.md +1 -1
  181. package/examples/component-form-controls.md +1 -1
  182. package/examples/component-form-group.md +1 -1
  183. package/examples/component-form-helper-text.md +1 -1
  184. package/examples/component-form-label.md +1 -1
  185. package/examples/component-form.md +2 -2
  186. package/examples/component-grid.md +2 -2
  187. package/examples/component-grow.md +1 -1
  188. package/examples/component-hover-card.md +1 -1
  189. package/examples/component-icon-button.md +1 -1
  190. package/examples/component-icon.md +1 -1
  191. package/examples/component-image-list.md +1 -1
  192. package/examples/component-image.md +1 -1
  193. package/examples/component-input-adornment.md +1 -1
  194. package/examples/component-input-base.md +1 -1
  195. package/examples/component-input-number.md +1 -1
  196. package/examples/component-input-otp.md +2 -2
  197. package/examples/component-input.md +3 -3
  198. package/examples/component-item.md +1 -1
  199. package/examples/component-label.md +1 -1
  200. package/examples/component-layout.md +1 -1
  201. package/examples/component-link.md +1 -1
  202. package/examples/component-list-item-avatar.md +1 -1
  203. package/examples/component-list-item-button.md +1 -1
  204. package/examples/component-list-item-icon.md +1 -1
  205. package/examples/component-list-item-text.md +1 -1
  206. package/examples/component-list-item.md +1 -1
  207. package/examples/component-list-subheader.md +1 -1
  208. package/examples/component-list.md +2 -2
  209. package/examples/component-masonry.md +1 -1
  210. package/examples/component-mentions.md +1 -1
  211. package/examples/component-menu-item.md +1 -1
  212. package/examples/component-menu-list.md +1 -1
  213. package/examples/component-menu.md +1 -1
  214. package/examples/component-menubar.md +1 -1
  215. package/examples/component-message.md +1 -1
  216. package/examples/component-mobile-stepper.md +1 -1
  217. package/examples/component-modal.md +5 -5
  218. package/examples/component-navigation-menu.md +1 -1
  219. package/examples/component-notification.md +1 -1
  220. package/examples/component-outlined-input.md +1 -1
  221. package/examples/component-pagination.md +3 -3
  222. package/examples/component-paper.md +1 -1
  223. package/examples/component-popconfirm.md +1 -1
  224. package/examples/component-popover.md +3 -3
  225. package/examples/component-popper.md +1 -1
  226. package/examples/component-progress.md +2 -2
  227. package/examples/component-qr-code.md +1 -1
  228. package/examples/component-radio.md +3 -3
  229. package/examples/component-rate.md +2 -2
  230. package/examples/component-resizable.md +1 -1
  231. package/examples/component-result.md +1 -1
  232. package/examples/component-scroll-area.md +1 -1
  233. package/examples/component-segmented.md +3 -3
  234. package/examples/component-select.md +3 -3
  235. package/examples/component-separator.md +1 -1
  236. package/examples/component-sheet.md +1 -1
  237. package/examples/component-sidebar.md +1 -1
  238. package/examples/component-skeleton.md +3 -3
  239. package/examples/component-slide.md +1 -1
  240. package/examples/component-slider.md +3 -3
  241. package/examples/component-snackbar-content.md +1 -1
  242. package/examples/component-snackbar.md +1 -1
  243. package/examples/component-sonner.md +1 -1
  244. package/examples/component-space.md +1 -1
  245. package/examples/component-speed-dial-action.md +1 -1
  246. package/examples/component-speed-dial.md +1 -1
  247. package/examples/component-spin.md +2 -2
  248. package/examples/component-spinner.md +1 -1
  249. package/examples/component-splitter.md +2 -2
  250. package/examples/component-stack.md +1 -1
  251. package/examples/component-statistic.md +1 -1
  252. package/examples/component-step-button.md +4 -4
  253. package/examples/component-step-connector.md +4 -4
  254. package/examples/component-step-content.md +1 -1
  255. package/examples/component-step-icon.md +1 -1
  256. package/examples/component-step-label.md +1 -1
  257. package/examples/component-step.md +2 -2
  258. package/examples/component-steps.md +2 -2
  259. package/examples/component-swipeable-drawer.md +1 -1
  260. package/examples/component-switch.md +3 -3
  261. package/examples/component-tab-scroll-button.md +5 -5
  262. package/examples/component-tab.md +1 -1
  263. package/examples/component-table-body.md +1 -1
  264. package/examples/component-table-cell.md +1 -1
  265. package/examples/component-table-container.md +1 -1
  266. package/examples/component-table-footer.md +1 -1
  267. package/examples/component-table-head.md +1 -1
  268. package/examples/component-table-pagination.md +1 -1
  269. package/examples/component-table-row.md +1 -1
  270. package/examples/component-table-sort-label.md +1 -1
  271. package/examples/component-table.md +2 -2
  272. package/examples/component-tabs.md +3 -3
  273. package/examples/component-tag-badge.md +2 -2
  274. package/examples/component-tag.md +1 -1
  275. package/examples/component-textarea-autosize.md +1 -1
  276. package/examples/component-textarea.md +1 -1
  277. package/examples/component-time-picker.md +1 -1
  278. package/examples/component-timeline.md +1 -1
  279. package/examples/component-toast.md +4 -4
  280. package/examples/component-toggle-button.md +1 -1
  281. package/examples/component-toggle.md +1 -1
  282. package/examples/component-toolbar.md +1 -1
  283. package/examples/component-tooltip.md +3 -3
  284. package/examples/component-tour.md +1 -1
  285. package/examples/component-transfer.md +1 -1
  286. package/examples/component-tree-select.md +1 -1
  287. package/examples/component-tree.md +1 -1
  288. package/examples/component-typography.md +2 -2
  289. package/examples/component-upload.md +1 -1
  290. package/examples/component-watermark.md +1 -1
  291. package/examples/component-zoom.md +1 -1
  292. package/knowledge/COVERAGE.md +4 -3
  293. package/knowledge/components/INDEX.md +202 -202
  294. package/knowledge/patterns/brand-references.md +72 -72
  295. package/package.json +1 -1
  296. package/tools/audit/local-ci.py +16 -1
  297. package/tools/audit/package-smoke.py +717 -9
  298. package/tools/audit/registry-smoke.py +912 -10
  299. package/tools/audit/release-metadata.py +47 -1
  300. package/tools/audit/smoke_assertions.py +998 -35
  301. package/tools/migrations/refs-links-to-reference-pages.py +179 -0
@@ -0,0 +1,271 @@
1
+ // Target-repo handoff reports for Website Improvement bundles.
2
+
3
+ import {
4
+ existsSync,
5
+ readFileSync,
6
+ statSync,
7
+ } from "node:fs";
8
+ import path from "node:path";
9
+
10
+ import {
11
+ buildSitePrompt,
12
+ resolveSitePromptTask,
13
+ } from "./site-prompts.mjs";
14
+ import { analyzeSiteWorkspace } from "./site-analysis.mjs";
15
+ import { buildBundleCheckCommand } from "./site-bundle-commands.mjs";
16
+ import { formatBundleRepairGuidanceLines } from "./site-bundle-repair.mjs";
17
+ import { buildSiteBundleCheckReport } from "./site-bundle-check.mjs";
18
+ import {
19
+ buildBundleHandoffCommandManifest,
20
+ buildBundleHandoffOperatorRunbook,
21
+ formatBundleHandoffOperatorRunbookLines,
22
+ } from "./site-bundle-handoff-runbook.mjs";
23
+ import {
24
+ SITE_TARGET_REPO_EXECUTION_CHECKLIST,
25
+ buildSiteBundleHandoffBoundaries,
26
+ emptyBundleTaskCatalog,
27
+ formatBundleHandoffIssueLines,
28
+ formatBundleHandoffTaskCatalogLines,
29
+ summarizeBundleTaskCatalog,
30
+ summarizeSelectedTask,
31
+ summarizeSiteBundleHandoffSource,
32
+ } from "./site-bundle-handoff-summary.mjs";
33
+ import { readBundleTextIfPresent } from "./site-bundle-files.mjs";
34
+ import { formatGeneratedContractDriftSummary } from "./site-bundle-contract.mjs";
35
+
36
+ function loadSiteBundleWorkspace(directory) {
37
+ const relativePath = "website-workspace.tasks.json";
38
+ const targetPath = path.join(directory, relativePath);
39
+ if (!existsSync(targetPath) || !statSync(targetPath).isFile()) {
40
+ throw new Error(`Cannot select a handoff task because ${relativePath} is missing from the bundle`);
41
+ }
42
+
43
+ let raw;
44
+ try {
45
+ raw = JSON.parse(readFileSync(targetPath, "utf8"));
46
+ } catch (error) {
47
+ throw new Error(`Cannot select a handoff task because ${relativePath} is invalid JSON: ${error.message}`);
48
+ }
49
+
50
+ return analyzeSiteWorkspace(raw, { filePath: targetPath }).workspace;
51
+ }
52
+
53
+ function buildSiteBundleHandoffPrompt(checkReport, bundleTexts) {
54
+ const bundleDigest = checkReport.summary.checksumBundleDigest || "not recorded";
55
+ const checksumStatus = `${checkReport.counts.verifiedChecksumFiles}/${checkReport.counts.expectedChecksumFiles} verified`;
56
+ const handoffBoundaries = buildSiteBundleHandoffBoundaries(checkReport);
57
+ const taskSelectionLine = bundleTexts.selectedTask
58
+ ? `${bundleTexts.selectedTask.id} (${bundleTexts.selectedTask.title}; ${bundleTexts.selectedTask.source})`
59
+ : "bundled codex-implementation.md default";
60
+ const bundleReadinessLine = checkReport.status === "pass"
61
+ ? "The bundle passed local bundle-check validation. Proceed in the target website repo after confirming the repo path."
62
+ : "The bundle did not fully pass local bundle-check validation. Resolve the listed bundle issues before treating this as implementation authority.";
63
+ return [
64
+ "# Website improvement target-repo handoff prompt",
65
+ "",
66
+ "You are Codex working in the target website repository, not in the design-ai repository.",
67
+ "Use this verified Website Improvement handoff bundle as read-only planning evidence. Do not modify the design-ai repo while executing this prompt.",
68
+ "",
69
+ "## Verified Bundle",
70
+ `- Bundle directory: ${checkReport.directory}`,
71
+ `- Source bundle provenance: ${checkReport.status}/${checkReport.valid ? "valid" : "invalid"} from ${checkReport.directory}`,
72
+ `- Source bundle strict check command: \`${buildBundleCheckCommand(checkReport.directory, { strict: true })}\``,
73
+ `- Site: ${checkReport.summary.siteName || "unknown"}`,
74
+ `- Source workspace: ${checkReport.summary.source || "unknown"}`,
75
+ `- Bundle status: ${checkReport.status}`,
76
+ `- Workspace status: ${checkReport.workspaceStatus}`,
77
+ `- MCP status: ${checkReport.mcpStatus}`,
78
+ `- MCP probe status: ${checkReport.mcpProbeStatus}`,
79
+ `- MCP probes: ${checkReport.mcpProbeCounts.pass}/${checkReport.mcpProbeCounts.count} passing, ${checkReport.mcpProbeCounts.warn} warning, ${checkReport.mcpProbeCounts.fail} failing`,
80
+ `- Tasks: ${checkReport.summary.totalTasks}`,
81
+ `- Primary task selection: ${taskSelectionLine}`,
82
+ `- Evidence counts: executed work ${checkReport.summary.implementationEvidence.executedWork}, verification ${checkReport.summary.implementationEvidence.verificationResults}, risks ${checkReport.summary.implementationEvidence.remainingRisks}, next actions ${checkReport.summary.implementationEvidence.nextActions}`,
83
+ `- Generated files: ${checkReport.counts.verifiedGeneratedFiles}/${checkReport.counts.expectedGeneratedFiles} match the current CLI bundle contract`,
84
+ `- Generated drift files: ${formatGeneratedContractDriftSummary(checkReport.generatedContract)}`,
85
+ `- SHA-256 bundle digest: ${bundleDigest}`,
86
+ `- Checksums: ${checksumStatus}`,
87
+ `- Handoff generation boundary flags: external calls no; target repo mutation no`,
88
+ `- Handoff boundaries: ${handoffBoundaries.join(", ")}`,
89
+ "",
90
+ "## Available Bundle Tasks",
91
+ `Task catalog source: ${bundleTexts.taskCatalog?.source || "unknown"}`,
92
+ `Default task: ${bundleTexts.taskCatalog?.defaultTaskId || "none"}`,
93
+ ...(bundleTexts.defaultTask?.strictHandoffCommand
94
+ ? [`Default task strict command: \`${bundleTexts.defaultTask.strictHandoffCommand}\``]
95
+ : []),
96
+ `Selected task: ${bundleTexts.taskCatalog?.selectedTaskId || "none"}`,
97
+ ...(bundleTexts.selectedTask?.strictHandoffCommand
98
+ ? [`Selected task strict command: \`${bundleTexts.selectedTask.strictHandoffCommand}\``]
99
+ : []),
100
+ `Effective task: ${bundleTexts.effectiveTask?.id || "none"}`,
101
+ ...(bundleTexts.effectiveTask?.strictHandoffCommand
102
+ ? [`Effective task strict command: \`${bundleTexts.effectiveTask.strictHandoffCommand}\``]
103
+ : []),
104
+ "To choose a specific task, re-run this handoff with `--task <number-or-id>`.",
105
+ ...formatBundleHandoffTaskCatalogLines(bundleTexts.taskCatalog),
106
+ "",
107
+ "## Operator Runbook",
108
+ `Runbook stages: ${bundleTexts.operatorRunbook?.stageCount || 0} (${bundleTexts.operatorRunbook?.requiredStageCount || 0} required, ${bundleTexts.operatorRunbook?.optionalStageCount || 0} optional)`,
109
+ `Next command key: ${bundleTexts.operatorRunbook?.nextCommandKey || "none"}`,
110
+ ...formatBundleHandoffOperatorRunbookLines(bundleTexts.operatorRunbook),
111
+ "",
112
+ "## Bundle Gate",
113
+ bundleReadinessLine,
114
+ formatBundleHandoffIssueLines(checkReport.issues),
115
+ "",
116
+ "Repair guidance:",
117
+ ...formatBundleRepairGuidanceLines(checkReport.repairGuidance),
118
+ "",
119
+ "## Operating Rules",
120
+ "1. Confirm the current working directory is the target website repo before editing files.",
121
+ "2. Inspect the target repo architecture, existing components, design tokens, routing, styling, and test scripts before implementation.",
122
+ "3. Reuse existing UI/system patterns and keep the change scoped to the selected improvement task.",
123
+ "4. Do not add production dependencies unless the target repo clearly requires them and the tradeoff is documented.",
124
+ "5. Preserve WCAG 2.1 AA expectations: visible focus, keyboard reachability, semantic structure, and text contrast.",
125
+ "6. Verify desktop, tablet, and mobile behavior plus target repo lint/typecheck/build commands when available.",
126
+ "7. Keep the handoff bundle files read-only; record implementation evidence in the target repo final response or report.",
127
+ "",
128
+ "## Target Repo Execution Checklist",
129
+ ...SITE_TARGET_REPO_EXECUTION_CHECKLIST.map((item) => `- [ ] ${item.label}: ${item.evidence}`),
130
+ "",
131
+ "## Primary Codex Implementation Prompt",
132
+ bundleTexts.codexImplementation || "_codex-implementation.md was not readable from the bundle._",
133
+ "",
134
+ "## Additional Bundle Context",
135
+ "Use these files only as supporting evidence:",
136
+ "- `website-handoff.md`: audit summary, priority recommendations, and remaining risk context.",
137
+ "- `mcp-probes.json`: read-only MCP probe evidence for repo, Figma, Browser, and deployment references.",
138
+ "- `mcp-action-plan.md`: MCP readiness gaps and operator sequence.",
139
+ "- `website-prompts.md`: alternate Codex/Claude review, QA, deployment, research, and copy prompts.",
140
+ "- `summary.json`: bundle manifest, source workspace, task count, and checksum digest.",
141
+ "",
142
+ "### Handoff Report Snapshot",
143
+ bundleTexts.websiteHandoff || "_website-handoff.md was not readable from the bundle._",
144
+ "",
145
+ "## Required Final Response",
146
+ "Return a concise implementation report with:",
147
+ "- Files changed in the target repo",
148
+ "- The specific website improvement task completed",
149
+ "- Verification commands and browser/viewport checks performed",
150
+ "- Remaining risks or follow-up work",
151
+ `- Bundle digest used for handoff: ${bundleDigest}`,
152
+ ].join("\n");
153
+ }
154
+
155
+ export function buildSiteBundleHandoffReport({
156
+ target,
157
+ cwd = process.cwd(),
158
+ taskSelector = "",
159
+ } = {}) {
160
+ const checkReport = buildSiteBundleCheckReport({ target, cwd });
161
+ const includedFilePaths = [
162
+ "summary.json",
163
+ "mcp-probes.json",
164
+ "mcp-action-plan.md",
165
+ "website-handoff.md",
166
+ "website-prompts.md",
167
+ "codex-implementation.md",
168
+ ];
169
+ let bundleWorkspace = null;
170
+ let taskCatalogError = "";
171
+ let selectedTask = null;
172
+ let codexImplementation = readBundleTextIfPresent(checkReport.directory, "codex-implementation.md");
173
+ try {
174
+ bundleWorkspace = loadSiteBundleWorkspace(checkReport.directory);
175
+ } catch (error) {
176
+ taskCatalogError = error.message;
177
+ }
178
+ if (String(taskSelector || "").trim()) {
179
+ if (!bundleWorkspace) {
180
+ throw new Error(taskCatalogError || "Cannot select a handoff task because the bundle workspace is unavailable");
181
+ }
182
+ const task = resolveSitePromptTask(bundleWorkspace, taskSelector);
183
+ selectedTask = summarizeSelectedTask(task, taskSelector, "bundle-workspace", checkReport.directory);
184
+ codexImplementation = buildSitePrompt(bundleWorkspace, "codex-implementation", { taskSelector });
185
+ }
186
+ const taskCatalog = bundleWorkspace
187
+ ? summarizeBundleTaskCatalog(bundleWorkspace, checkReport.directory, selectedTask)
188
+ : emptyBundleTaskCatalog(taskCatalogError);
189
+ const defaultTask = taskCatalog.items[0] || null;
190
+ const effectiveTask = selectedTask || defaultTask;
191
+
192
+ const bundleTexts = {
193
+ taskCatalog,
194
+ defaultTask,
195
+ effectiveTask,
196
+ selectedTask,
197
+ codexImplementation,
198
+ websiteHandoff: readBundleTextIfPresent(checkReport.directory, "website-handoff.md"),
199
+ };
200
+ const boundaries = buildSiteBundleHandoffBoundaries(checkReport);
201
+ const sourceBundle = summarizeSiteBundleHandoffSource(checkReport);
202
+ const commandManifest = buildBundleHandoffCommandManifest({
203
+ sourceBundle,
204
+ taskCatalog,
205
+ defaultTask,
206
+ selectedTask,
207
+ effectiveTask,
208
+ });
209
+ const operatorRunbook = buildBundleHandoffOperatorRunbook(commandManifest);
210
+ const runbookPrompt = buildSiteBundleHandoffPrompt(checkReport, {
211
+ ...bundleTexts,
212
+ operatorRunbook,
213
+ });
214
+ return {
215
+ status: checkReport.status,
216
+ valid: checkReport.valid,
217
+ directory: checkReport.directory,
218
+ sourceBundle,
219
+ commandManifest,
220
+ operatorRunbook,
221
+ boundaries,
222
+ externalCalls: false,
223
+ targetRepoMutation: false,
224
+ bundle: {
225
+ directory: checkReport.directory,
226
+ siteName: checkReport.summary.siteName || "",
227
+ source: checkReport.summary.source || "",
228
+ sourceBundle,
229
+ workspaceStatus: checkReport.workspaceStatus || "unknown",
230
+ mcpStatus: checkReport.mcpStatus || "unknown",
231
+ mcpProbeStatus: checkReport.mcpProbeStatus || "unknown",
232
+ mcpProbeCounts: { ...checkReport.mcpProbeCounts },
233
+ totalTasks: checkReport.summary.totalTasks || 0,
234
+ implementationEvidence: { ...checkReport.summary.implementationEvidence },
235
+ checksumAlgorithm: checkReport.summary.checksumAlgorithm || "",
236
+ checksumBundleDigest: checkReport.summary.checksumBundleDigest || "",
237
+ expectedChecksumFiles: checkReport.counts.expectedChecksumFiles,
238
+ verifiedChecksumFiles: checkReport.counts.verifiedChecksumFiles,
239
+ checksumFailures: checkReport.counts.checksumFailures,
240
+ expectedGeneratedFiles: checkReport.counts.expectedGeneratedFiles,
241
+ verifiedGeneratedFiles: checkReport.counts.verifiedGeneratedFiles,
242
+ generatedFailures: checkReport.counts.generatedFailures,
243
+ generatedDriftFiles: [...checkReport.generatedContract.driftFiles],
244
+ taskCatalog,
245
+ defaultTask,
246
+ effectiveTask,
247
+ selectedTask,
248
+ commandManifest,
249
+ operatorRunbook,
250
+ boundaries,
251
+ externalCalls: false,
252
+ targetRepoMutation: false,
253
+ repairGuidance: { ...checkReport.repairGuidance },
254
+ executionChecklist: SITE_TARGET_REPO_EXECUTION_CHECKLIST,
255
+ },
256
+ prompt: runbookPrompt,
257
+ files: checkReport.files.map((file) => ({
258
+ ...file,
259
+ included: includedFilePaths.includes(file.path),
260
+ })),
261
+ issues: checkReport.issues,
262
+ };
263
+ }
264
+
265
+ export function formatSiteBundleHandoffJson(report) {
266
+ return JSON.stringify(report, null, 2);
267
+ }
268
+
269
+ export function formatSiteBundleHandoffHuman(report) {
270
+ return report.prompt;
271
+ }
@@ -0,0 +1,98 @@
1
+ // README and handoff guidance builders for Website Improvement bundles.
2
+
3
+ import { markdownTable } from "./site-strings.mjs";
4
+ import { SITE_TARGET_REPO_EXECUTION_CHECKLIST } from "./site-bundle-handoff-summary.mjs";
5
+
6
+ export function buildSiteBundleHandoffGuidance(bundleStatus) {
7
+ const strictCommand = "design-ai site <bundle-dir> --bundle-handoff --strict --out target-repo-handoff.md";
8
+ const draftCommand = "design-ai site <bundle-dir> --bundle-handoff --out target-repo-handoff.md";
9
+ const verifyCommand = "design-ai site <bundle-dir> --bundle-check --strict --json";
10
+ const strictReady = bundleStatus === "pass";
11
+ return {
12
+ strictReady,
13
+ readiness: strictReady ? "ready-for-strict-handoff" : "review-warnings-before-strict-handoff",
14
+ recommendedCommand: strictReady ? strictCommand : draftCommand,
15
+ strictCommand,
16
+ draftCommand,
17
+ verifyCommand,
18
+ note: strictReady
19
+ ? "Use the strict handoff command before target-repo implementation."
20
+ : "Use the draft handoff command only for planning while readiness warnings remain; use the strict handoff command before treating the bundle as implementation authority.",
21
+ executionChecklist: SITE_TARGET_REPO_EXECUTION_CHECKLIST,
22
+ };
23
+ }
24
+
25
+ export function buildSiteBundleReadme(workspace, bundleSummary, mcpReport, mcpProbeReport, filePaths) {
26
+ const commandTarget = bundleSummary.source === "stdin" ? "<workspace.json>" : bundleSummary.source;
27
+ const handoff = bundleSummary.handoff;
28
+ return [
29
+ `# Website improvement handoff bundle: ${workspace.siteProfile.name}`,
30
+ "",
31
+ "> Generated by `design-ai site --bundle` from a Website Improvement Console workspace export.",
32
+ "",
33
+ "## Contents",
34
+ markdownTable(
35
+ ["File", "Purpose"],
36
+ filePaths.map((filePath) => {
37
+ const purpose = {
38
+ "summary.json": "Machine-readable bundle manifest and readiness summary",
39
+ "website-workspace.tasks.json": "Workspace JSON with deterministic starter refactor tasks added",
40
+ "mcp-check.json": "Machine-readable MCP readiness gate output",
41
+ "mcp-probes.json": "Machine-readable read-only MCP probe readiness output",
42
+ "mcp-action-plan.md": "Operator-facing MCP readiness action plan",
43
+ "website-handoff.md": "Markdown handoff report for implementation planning",
44
+ "website-prompts.md": "Full Codex and Claude prompt bundle",
45
+ "codex-implementation.md": "Top-priority Codex implementation prompt",
46
+ }[filePath] || "Bundle artifact";
47
+ return [filePath, purpose];
48
+ }),
49
+ ),
50
+ "",
51
+ "## Status",
52
+ `- Bundle status: ${mcpReport.status}`,
53
+ `- Workspace status: ${bundleSummary.workspaceStatus}`,
54
+ `- Source: ${bundleSummary.source}`,
55
+ `- Site: ${workspace.siteProfile.name}`,
56
+ `- Live URL: ${workspace.siteProfile.liveUrl || "not provided"}`,
57
+ `- Repo: ${workspace.siteProfile.repoUrl || workspace.siteProfile.localPath || "not provided"}`,
58
+ `- Tasks: ${bundleSummary.taskGeneration.totalTasks}`,
59
+ `- Evidence entries: ${bundleSummary.implementationEvidence.executedWork + bundleSummary.implementationEvidence.verificationResults}`,
60
+ `- MCP ready: ${mcpReport.counts.ready}/${mcpReport.counts.total}`,
61
+ `- MCP probes: ${mcpProbeReport.pass}/${mcpProbeReport.count} passing`,
62
+ "",
63
+ "## Handoff Readiness",
64
+ `- Strict-ready: ${handoff.strictReady ? "yes" : "no"}`,
65
+ `- Readiness: ${handoff.readiness}`,
66
+ `- Recommended command: \`${handoff.recommendedCommand}\``,
67
+ `- Strict command: \`${handoff.strictCommand}\``,
68
+ `- Draft command: \`${handoff.draftCommand}\``,
69
+ `- Verify command: \`${handoff.verifyCommand}\``,
70
+ `- Note: ${handoff.note}`,
71
+ "",
72
+ "## Target Repo Execution Checklist",
73
+ ...handoff.executionChecklist.map((item) => `- [ ] ${item.label}: ${item.evidence}`),
74
+ "",
75
+ "## Suggested Sequence",
76
+ "1. Read `summary.json`, `mcp-check.json`, `mcp-probes.json`, and `mcp-action-plan.md` first.",
77
+ "2. Run `design-ai site <bundle-dir> --bundle-check --strict --json`; if it exits non-zero, review the warnings or failures before implementation.",
78
+ "3. Run the recommended handoff command above. Use the draft command only for planning while readiness warnings remain.",
79
+ "4. Use `codex-implementation.md` in the target website repo for the top-priority task when you need the raw task prompt.",
80
+ "5. Use `website-prompts.md` for deeper Codex/Claude review, visual QA, deployment verification, competitor research, and final handoff.",
81
+ "6. Record target-repo executed work, verification results, remaining risks, and next actions in `website-handoff.md` after implementation.",
82
+ "",
83
+ "## Regenerate",
84
+ `- \`design-ai site ${commandTarget} --bundle --out website-handoff-bundle --force\``,
85
+ `- \`design-ai site ${commandTarget} --mcp-check --strict --json\``,
86
+ `- \`design-ai site website-handoff-bundle --bundle-check --strict --json\``,
87
+ `- \`design-ai site website-handoff-bundle --bundle-handoff --strict --out target-repo-handoff.md\``,
88
+ "",
89
+ "## Checksum Verification",
90
+ "- `summary.json` records SHA-256 checksums for every generated bundle file except `summary.json` itself.",
91
+ "- `summary.json.checksums.bundleDigest` records a deterministic fingerprint of the checksum manifest for quick bundle identity comparison.",
92
+ "- `design-ai site <bundle-dir> --bundle-check --strict --json` recomputes those checksums so transferred or manually edited bundles fail before target-repo handoff.",
93
+ "",
94
+ "## Boundaries",
95
+ "- This bundle is deterministic and local.",
96
+ "- It does not call external MCPs, mutate the target website repo, run Lighthouse/axe, capture screenshots, or write to deployment/CMS/Sentry systems.",
97
+ ].join("\n");
98
+ }
@@ -0,0 +1,143 @@
1
+ // Repair report orchestration for Website Improvement handoff bundles.
2
+
3
+ import path from "node:path";
4
+
5
+ import {
6
+ addIssue,
7
+ analyzeSiteWorkspace,
8
+ loadSiteWorkspaceInput,
9
+ statusFromIssues,
10
+ } from "./site-analysis.mjs";
11
+ import { buildSiteHandoffBundle } from "./site-bundle-build.mjs";
12
+ import { buildSiteBundleCheckReport } from "./site-bundle-check.mjs";
13
+ import {
14
+ formatBundleRepairGuidanceLines,
15
+ summarizeBundleRepairCheck,
16
+ } from "./site-bundle-repair.mjs";
17
+
18
+ function buildSiteBundleRepairReportFromChecks({
19
+ beforeReport,
20
+ afterReport = null,
21
+ written = null,
22
+ applied = false,
23
+ } = {}) {
24
+ const issues = [];
25
+ const repairGuidance = beforeReport.repairGuidance;
26
+
27
+ if (!repairGuidance.available) {
28
+ addIssue(issues, "fail", "bundle-repair-unavailable", repairGuidance.reason);
29
+ } else if (!applied) {
30
+ addIssue(issues, "pass", "bundle-repair-preview-ready", "Bundle repair preview is ready; run again with --yes to rewrite the handoff bundle directory");
31
+ } else if (!afterReport || afterReport.status !== "pass") {
32
+ addIssue(issues, "fail", "bundle-repair-verify-fail", "Bundle repair applied, but the repaired bundle did not pass bundle-check verification");
33
+ } else {
34
+ addIssue(issues, "pass", "bundle-repair-applied", "Bundle repair applied and the regenerated bundle passed local bundle-check verification");
35
+ }
36
+
37
+ const status = statusFromIssues(issues);
38
+ return {
39
+ directory: beforeReport.directory,
40
+ workspaceFile: path.join(beforeReport.directory, "website-workspace.tasks.json"),
41
+ dryRun: !applied,
42
+ applied,
43
+ valid: status !== "fail",
44
+ status,
45
+ repairGuidance,
46
+ before: summarizeBundleRepairCheck(beforeReport),
47
+ after: afterReport ? summarizeBundleRepairCheck(afterReport) : null,
48
+ written: written ? {
49
+ directory: written.directory,
50
+ files: written.files,
51
+ count: written.files.length,
52
+ } : null,
53
+ issues,
54
+ };
55
+ }
56
+
57
+ export function buildSiteBundleRepairPreview({
58
+ target,
59
+ cwd = process.cwd(),
60
+ } = {}) {
61
+ const beforeReport = buildSiteBundleCheckReport({ target, cwd });
62
+ return buildSiteBundleRepairReportFromChecks({ beforeReport });
63
+ }
64
+
65
+ export function buildSiteBundleRepairBundle({
66
+ target,
67
+ cwd = process.cwd(),
68
+ } = {}) {
69
+ const beforeReport = buildSiteBundleCheckReport({ target, cwd });
70
+ const preview = buildSiteBundleRepairReportFromChecks({ beforeReport });
71
+ if (!preview.repairGuidance.available) {
72
+ return {
73
+ preview,
74
+ beforeReport,
75
+ bundle: null,
76
+ };
77
+ }
78
+
79
+ const input = loadSiteWorkspaceInput({
80
+ target: preview.workspaceFile,
81
+ cwd,
82
+ });
83
+ const analyzed = analyzeSiteWorkspace(input.raw, { filePath: input.filePath });
84
+ const bundle = buildSiteHandoffBundle(analyzed.workspace, analyzed.summary);
85
+ return {
86
+ preview,
87
+ beforeReport,
88
+ bundle,
89
+ };
90
+ }
91
+
92
+ export function buildSiteBundleRepairAppliedReport({
93
+ beforeReport,
94
+ written,
95
+ cwd = process.cwd(),
96
+ } = {}) {
97
+ const afterReport = buildSiteBundleCheckReport({
98
+ target: beforeReport.directory,
99
+ cwd,
100
+ });
101
+ return buildSiteBundleRepairReportFromChecks({
102
+ beforeReport,
103
+ afterReport,
104
+ written,
105
+ applied: true,
106
+ });
107
+ }
108
+
109
+ export function formatSiteBundleRepairJson(report) {
110
+ return JSON.stringify(report, null, 2);
111
+ }
112
+
113
+ export function formatSiteBundleRepairHuman(report) {
114
+ const afterLines = report.after ? [
115
+ `After status: ${report.after.status}`,
116
+ `After generated drift files: ${report.after.generatedDriftFiles.length ? report.after.generatedDriftFiles.join(", ") : "none"}`,
117
+ `After bundle digest: ${report.after.checksumBundleDigest || "not recorded"}`,
118
+ ] : [
119
+ "After status: not applied",
120
+ ];
121
+ return [
122
+ `Website Improvement handoff bundle repair: ${report.directory}`,
123
+ "",
124
+ `Status: ${report.status}`,
125
+ `Dry run: ${report.dryRun ? "yes" : "no"}`,
126
+ `Applied: ${report.applied ? "yes" : "no"}`,
127
+ `Workspace: ${report.workspaceFile}`,
128
+ `Before status: ${report.before.status}`,
129
+ `Before generated drift files: ${report.before.generatedDriftFiles.length ? report.before.generatedDriftFiles.join(", ") : "none"}`,
130
+ `Before bundle digest: ${report.before.checksumBundleDigest || "not recorded"}`,
131
+ ...afterLines,
132
+ ...(report.written ? [
133
+ `Written directory: ${report.written.directory}`,
134
+ `Written files: ${report.written.count}`,
135
+ ] : []),
136
+ "",
137
+ "Repair guidance:",
138
+ ...formatBundleRepairGuidanceLines(report.repairGuidance),
139
+ "",
140
+ "Issues:",
141
+ ...report.issues.map((issue) => `- [${issue.level}] ${issue.id}: ${issue.message}`),
142
+ ].join("\n");
143
+ }
@@ -0,0 +1,68 @@
1
+ // Repair guidance helpers for Website Improvement handoff bundles.
2
+
3
+ import {
4
+ existsSync,
5
+ statSync,
6
+ } from "node:fs";
7
+ import path from "node:path";
8
+
9
+ import { shellQuote } from "./site-bundle-commands.mjs";
10
+
11
+ export function buildBundleRepairGuidance(directory, generatedContract) {
12
+ const workspacePath = path.join(directory, "website-workspace.tasks.json");
13
+ const reportBaseName = path.basename(directory);
14
+ const reportDirectory = path.dirname(directory);
15
+ const previewReportPath = path.join(reportDirectory, `${reportBaseName}-repair-preview.json`);
16
+ const appliedReportPath = path.join(reportDirectory, `${reportBaseName}-repair-applied.json`);
17
+ const hasWorkspace = existsSync(workspacePath) && statSync(workspacePath).isFile();
18
+ const available = Boolean(generatedContract.available && hasWorkspace);
19
+ return {
20
+ available,
21
+ reason: available
22
+ ? "Regenerate the bundle from its embedded website-workspace.tasks.json when generated contract drift is reported."
23
+ : "Repair guidance requires a readable website-workspace.tasks.json and generated contract analysis.",
24
+ command: available ? `design-ai site ${shellQuote(workspacePath)} --bundle --out ${shellQuote(directory)} --force` : "",
25
+ previewCommand: available ? `design-ai site ${shellQuote(directory)} --bundle-repair --json` : "",
26
+ applyCommand: available ? `design-ai site ${shellQuote(directory)} --bundle-repair --yes --json` : "",
27
+ previewReportCommand: available ? `design-ai site ${shellQuote(directory)} --bundle-repair --json --out ${shellQuote(previewReportPath)}` : "",
28
+ applyReportCommand: available ? `design-ai site ${shellQuote(directory)} --bundle-repair --yes --json --out ${shellQuote(appliedReportPath)}` : "",
29
+ verifyCommand: available ? `design-ai site ${shellQuote(directory)} --bundle-check --strict --json` : "",
30
+ mutates: available ? "handoff-bundle-directory-only" : "none",
31
+ targetRepoMutation: false,
32
+ externalCalls: false,
33
+ };
34
+ }
35
+
36
+ export function formatBundleRepairGuidanceLines(repairGuidance) {
37
+ if (!repairGuidance.available) {
38
+ return [
39
+ `- Available: no`,
40
+ `- Reason: ${repairGuidance.reason}`,
41
+ ];
42
+ }
43
+ return [
44
+ "- Available: yes",
45
+ `- Reason: ${repairGuidance.reason}`,
46
+ `- Regenerate: ${repairGuidance.command}`,
47
+ `- Preview repair: ${repairGuidance.previewCommand}`,
48
+ `- Apply repair: ${repairGuidance.applyCommand}`,
49
+ `- Preview report: ${repairGuidance.previewReportCommand}`,
50
+ `- Apply report: ${repairGuidance.applyReportCommand}`,
51
+ `- Verify: ${repairGuidance.verifyCommand}`,
52
+ `- Scope: ${repairGuidance.mutates}; target repo mutation ${repairGuidance.targetRepoMutation ? "yes" : "no"}; external calls ${repairGuidance.externalCalls ? "yes" : "no"}`,
53
+ ];
54
+ }
55
+
56
+ export function summarizeBundleRepairCheck(report) {
57
+ return {
58
+ status: report.status,
59
+ valid: report.valid,
60
+ checksumBundleDigest: report.summary.checksumBundleDigest || "",
61
+ checksumFailures: report.counts.checksumFailures,
62
+ generatedFailures: report.counts.generatedFailures,
63
+ verifiedGeneratedFiles: report.counts.verifiedGeneratedFiles,
64
+ expectedGeneratedFiles: report.counts.expectedGeneratedFiles,
65
+ generatedDriftFiles: [...report.generatedContract.driftFiles],
66
+ issueCount: report.issues.length,
67
+ };
68
+ }