@12ui/design 0.2.57 → 0.2.59

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 (456) hide show
  1. package/SKILL.md +1 -1
  2. package/dist/artifact-materializer.d.ts.map +1 -1
  3. package/dist/artifact-materializer.js +4 -1
  4. package/dist/artifact-materializer.js.map +1 -1
  5. package/dist/atomic-file-replace.d.ts +21 -0
  6. package/dist/atomic-file-replace.d.ts.map +1 -0
  7. package/dist/atomic-file-replace.js +48 -0
  8. package/dist/atomic-file-replace.js.map +1 -0
  9. package/dist/branch-client.d.ts +84 -2
  10. package/dist/branch-client.d.ts.map +1 -1
  11. package/dist/branch-client.js +30 -0
  12. package/dist/branch-client.js.map +1 -1
  13. package/dist/cli-arguments.d.ts.map +1 -1
  14. package/dist/cli-arguments.js +2 -1
  15. package/dist/cli-arguments.js.map +1 -1
  16. package/dist/cli-capabilities.d.ts +1 -1
  17. package/dist/cli-conversion-derivation.d.ts +14 -1
  18. package/dist/cli-conversion-derivation.d.ts.map +1 -1
  19. package/dist/cli-conversion-derivation.js +14 -7
  20. package/dist/cli-conversion-derivation.js.map +1 -1
  21. package/dist/cli-convert-command.d.ts +2 -0
  22. package/dist/cli-convert-command.d.ts.map +1 -1
  23. package/dist/cli-convert-command.js +86 -34
  24. package/dist/cli-convert-command.js.map +1 -1
  25. package/dist/cli-corpus-command.d.ts.map +1 -1
  26. package/dist/cli-corpus-command.js +0 -3
  27. package/dist/cli-corpus-command.js.map +1 -1
  28. package/dist/cli-draft-command.d.ts +16 -0
  29. package/dist/cli-draft-command.d.ts.map +1 -1
  30. package/dist/cli-draft-command.js +47 -9
  31. package/dist/cli-draft-command.js.map +1 -1
  32. package/dist/cli-help/design.d.ts +7 -4
  33. package/dist/cli-help/design.d.ts.map +1 -1
  34. package/dist/cli-help/design.js +20 -7
  35. package/dist/cli-help/design.js.map +1 -1
  36. package/dist/cli-help/index.d.ts +9 -6
  37. package/dist/cli-help/index.d.ts.map +1 -1
  38. package/dist/cli-help/meta.d.ts +2 -2
  39. package/dist/cli-help/meta.d.ts.map +1 -1
  40. package/dist/cli-help/meta.js +4 -1
  41. package/dist/cli-help/meta.js.map +1 -1
  42. package/dist/cli-improve-command.d.ts.map +1 -1
  43. package/dist/cli-improve-command.js +215 -33
  44. package/dist/cli-improve-command.js.map +1 -1
  45. package/dist/cli-redesign-command.d.ts.map +1 -1
  46. package/dist/cli-redesign-command.js +268 -156
  47. package/dist/cli-redesign-command.js.map +1 -1
  48. package/dist/cli-run.d.ts.map +1 -1
  49. package/dist/cli-run.js +13 -3
  50. package/dist/cli-run.js.map +1 -1
  51. package/dist/cli-spend-command.d.ts +12 -1
  52. package/dist/cli-spend-command.d.ts.map +1 -1
  53. package/dist/cli-spend-command.js +94 -2
  54. package/dist/cli-spend-command.js.map +1 -1
  55. package/dist/cli-usage.js +5 -5
  56. package/dist/cli-usage.js.map +1 -1
  57. package/dist/concept-input.d.ts +6 -77
  58. package/dist/concept-input.d.ts.map +1 -1
  59. package/dist/concept-input.js +6 -87
  60. package/dist/concept-input.js.map +1 -1
  61. package/dist/conversion-client.d.ts +106 -17
  62. package/dist/conversion-client.d.ts.map +1 -1
  63. package/dist/conversion-client.js +244 -80
  64. package/dist/conversion-client.js.map +1 -1
  65. package/dist/corpus-client.d.ts.map +1 -1
  66. package/dist/corpus-client.js +0 -3
  67. package/dist/corpus-client.js.map +1 -1
  68. package/dist/draft-identity.d.ts +7 -0
  69. package/dist/draft-identity.d.ts.map +1 -1
  70. package/dist/draft-identity.js +4 -0
  71. package/dist/draft-identity.js.map +1 -1
  72. package/dist/draft-run.d.ts +13 -0
  73. package/dist/draft-run.d.ts.map +1 -1
  74. package/dist/draft-run.js +20 -2
  75. package/dist/draft-run.js.map +1 -1
  76. package/dist/draft-workspace.d.ts +4 -0
  77. package/dist/draft-workspace.d.ts.map +1 -1
  78. package/dist/draft-workspace.js.map +1 -1
  79. package/dist/hosted-draft-identity.d.ts +18 -0
  80. package/dist/hosted-draft-identity.d.ts.map +1 -1
  81. package/dist/hosted-draft-identity.js +8 -0
  82. package/dist/hosted-draft-identity.js.map +1 -1
  83. package/dist/hosted-draft-run.d.ts +15 -0
  84. package/dist/hosted-draft-run.d.ts.map +1 -1
  85. package/dist/hosted-draft-run.js +27 -0
  86. package/dist/hosted-draft-run.js.map +1 -1
  87. package/dist/improve-added-specs.d.ts +12 -40
  88. package/dist/improve-added-specs.d.ts.map +1 -1
  89. package/dist/improve-added-specs.js +63 -172
  90. package/dist/improve-added-specs.js.map +1 -1
  91. package/dist/improve-artifact-writer.d.ts +13 -0
  92. package/dist/improve-artifact-writer.d.ts.map +1 -0
  93. package/dist/improve-artifact-writer.js +27 -0
  94. package/dist/improve-artifact-writer.js.map +1 -0
  95. package/dist/improve-bootstrap-history.d.ts +21 -0
  96. package/dist/improve-bootstrap-history.d.ts.map +1 -0
  97. package/dist/improve-bootstrap-history.js +43 -0
  98. package/dist/improve-bootstrap-history.js.map +1 -0
  99. package/dist/improve-branch-stage.d.ts +10 -0
  100. package/dist/improve-branch-stage.d.ts.map +1 -0
  101. package/dist/improve-branch-stage.js +325 -0
  102. package/dist/improve-branch-stage.js.map +1 -0
  103. package/dist/improve-capture-redirect.d.ts +19 -0
  104. package/dist/improve-capture-redirect.d.ts.map +1 -1
  105. package/dist/improve-capture-redirect.js +18 -1
  106. package/dist/improve-capture-redirect.js.map +1 -1
  107. package/dist/improve-capture-words.d.ts +43 -0
  108. package/dist/improve-capture-words.d.ts.map +1 -0
  109. package/dist/improve-capture-words.js +25 -0
  110. package/dist/improve-capture-words.js.map +1 -0
  111. package/dist/improve-concept.d.ts +6 -20
  112. package/dist/improve-concept.d.ts.map +1 -1
  113. package/dist/improve-concept.js +12 -59
  114. package/dist/improve-concept.js.map +1 -1
  115. package/dist/improve-conversion-attempts.d.ts +12 -4
  116. package/dist/improve-conversion-attempts.d.ts.map +1 -1
  117. package/dist/improve-conversion-attempts.js.map +1 -1
  118. package/dist/improve-conversion-stage.d.ts +13 -2
  119. package/dist/improve-conversion-stage.d.ts.map +1 -1
  120. package/dist/improve-conversion-stage.js +211 -20
  121. package/dist/improve-conversion-stage.js.map +1 -1
  122. package/dist/improve-convert-progress.d.ts +10 -2
  123. package/dist/improve-convert-progress.d.ts.map +1 -1
  124. package/dist/improve-convert-progress.js +7 -3
  125. package/dist/improve-convert-progress.js.map +1 -1
  126. package/dist/improve-convert-resilience.d.ts +60 -13
  127. package/dist/improve-convert-resilience.d.ts.map +1 -1
  128. package/dist/improve-convert-resilience.js +85 -22
  129. package/dist/improve-convert-resilience.js.map +1 -1
  130. package/dist/improve-core/concept-input.d.ts +80 -0
  131. package/dist/improve-core/concept-input.d.ts.map +1 -0
  132. package/dist/improve-core/concept-input.js +92 -0
  133. package/dist/improve-core/concept-input.js.map +1 -0
  134. package/dist/improve-core/improve-added-specs.d.ts +62 -0
  135. package/dist/improve-core/improve-added-specs.d.ts.map +1 -0
  136. package/dist/improve-core/improve-added-specs.js +160 -0
  137. package/dist/improve-core/improve-added-specs.js.map +1 -0
  138. package/dist/improve-core/improve-artifacts.d.ts +18 -0
  139. package/dist/improve-core/improve-artifacts.d.ts.map +1 -0
  140. package/dist/improve-core/improve-artifacts.js +4 -0
  141. package/dist/improve-core/improve-artifacts.js.map +1 -0
  142. package/dist/improve-core/improve-concept.d.ts +11 -0
  143. package/dist/improve-core/improve-concept.d.ts.map +1 -0
  144. package/dist/improve-core/improve-concept.js +190 -0
  145. package/dist/improve-core/improve-concept.js.map +1 -0
  146. package/dist/improve-core/improve-discovery.d.ts +84 -0
  147. package/dist/improve-core/improve-discovery.d.ts.map +1 -0
  148. package/dist/improve-core/improve-discovery.js +154 -0
  149. package/dist/improve-core/improve-discovery.js.map +1 -0
  150. package/dist/improve-core/improve-dom-anchor.d.ts.map +1 -0
  151. package/dist/{improve-dom-anchor.js → improve-core/improve-dom-anchor.js} +2 -0
  152. package/dist/improve-core/improve-dom-anchor.js.map +1 -0
  153. package/dist/improve-core/improve-dom-diff.d.ts +59 -0
  154. package/dist/improve-core/improve-dom-diff.d.ts.map +1 -0
  155. package/dist/improve-core/improve-dom-diff.js +151 -0
  156. package/dist/improve-core/improve-dom-diff.js.map +1 -0
  157. package/dist/improve-core/improve-dom-extract.d.ts.map +1 -0
  158. package/dist/{improve-dom-extract.js → improve-core/improve-dom-extract.js} +2 -0
  159. package/dist/improve-core/improve-dom-extract.js.map +1 -0
  160. package/dist/improve-core/improve-dom-gate.d.ts +49 -0
  161. package/dist/improve-core/improve-dom-gate.d.ts.map +1 -0
  162. package/dist/improve-core/improve-dom-gate.js +99 -0
  163. package/dist/improve-core/improve-dom-gate.js.map +1 -0
  164. package/dist/improve-core/improve-dom-neighbour.d.ts.map +1 -0
  165. package/dist/{improve-dom-neighbour.js → improve-core/improve-dom-neighbour.js} +2 -0
  166. package/dist/improve-core/improve-dom-neighbour.js.map +1 -0
  167. package/dist/improve-core/improve-dom-scale.d.ts.map +1 -0
  168. package/dist/{improve-dom-scale.js → improve-core/improve-dom-scale.js} +2 -0
  169. package/dist/improve-core/improve-dom-scale.js.map +1 -0
  170. package/dist/improve-core/improve-icon-svg.d.ts +29 -0
  171. package/dist/improve-core/improve-icon-svg.d.ts.map +1 -0
  172. package/dist/{improve-icon-svg.js → improve-core/improve-icon-svg.js} +2 -0
  173. package/dist/improve-core/improve-icon-svg.js.map +1 -0
  174. package/dist/improve-core/improve-kit-asset-model.d.ts +177 -0
  175. package/dist/improve-core/improve-kit-asset-model.d.ts.map +1 -0
  176. package/dist/improve-core/improve-kit-asset-model.js +269 -0
  177. package/dist/improve-core/improve-kit-asset-model.js.map +1 -0
  178. package/dist/improve-core/improve-layerdoc-diff.d.ts.map +1 -0
  179. package/dist/{improve-layerdoc-diff.js → improve-core/improve-layerdoc-diff.js} +2 -0
  180. package/dist/improve-core/improve-layerdoc-diff.js.map +1 -0
  181. package/dist/{improve-layerdoc-types.d.ts → improve-core/improve-layerdoc-types.d.ts} +9 -0
  182. package/dist/improve-core/improve-layerdoc-types.d.ts.map +1 -0
  183. package/dist/improve-core/improve-layerdoc-types.js +4 -0
  184. package/dist/improve-core/improve-layerdoc-types.js.map +1 -0
  185. package/dist/improve-core/improve-page-words.d.ts +180 -0
  186. package/dist/improve-core/improve-page-words.d.ts.map +1 -0
  187. package/dist/improve-core/improve-page-words.js +303 -0
  188. package/dist/improve-core/improve-page-words.js.map +1 -0
  189. package/dist/{improve-plan-annotated-render.d.ts → improve-core/improve-plan-annotated-render.d.ts} +6 -1
  190. package/dist/improve-core/improve-plan-annotated-render.d.ts.map +1 -0
  191. package/dist/{improve-plan-annotated-render.js → improve-core/improve-plan-annotated-render.js} +56 -28
  192. package/dist/{improve-plan-annotated-render.js.map → improve-core/improve-plan-annotated-render.js.map} +1 -1
  193. package/dist/improve-core/improve-plan-annotator.d.ts +34 -0
  194. package/dist/improve-core/improve-plan-annotator.d.ts.map +1 -0
  195. package/dist/improve-core/improve-plan-annotator.js +52 -0
  196. package/dist/improve-core/improve-plan-annotator.js.map +1 -0
  197. package/dist/{improve-plan-render.d.ts → improve-core/improve-plan-render.d.ts} +2 -1
  198. package/dist/improve-core/improve-plan-render.d.ts.map +1 -0
  199. package/dist/{improve-plan-render.js → improve-core/improve-plan-render.js} +7 -1
  200. package/dist/improve-core/improve-plan-render.js.map +1 -0
  201. package/dist/improve-core/improve-plan-vector-keep.d.ts +29 -0
  202. package/dist/improve-core/improve-plan-vector-keep.d.ts.map +1 -0
  203. package/dist/improve-core/improve-plan-vector-keep.js +68 -0
  204. package/dist/improve-core/improve-plan-vector-keep.js.map +1 -0
  205. package/dist/{improve-raster-layers-section.d.ts → improve-core/improve-raster-layers-section.d.ts} +9 -1
  206. package/dist/improve-core/improve-raster-layers-section.d.ts.map +1 -0
  207. package/dist/{improve-raster-layers-section.js → improve-core/improve-raster-layers-section.js} +5 -2
  208. package/dist/improve-core/improve-raster-layers-section.js.map +1 -0
  209. package/dist/improve-core/improve-refusal.d.ts +6 -0
  210. package/dist/improve-core/improve-refusal.d.ts.map +1 -0
  211. package/dist/improve-core/improve-refusal.js +27 -0
  212. package/dist/improve-core/improve-refusal.js.map +1 -0
  213. package/dist/improve-core/improve-retain.d.ts +121 -0
  214. package/dist/improve-core/improve-retain.d.ts.map +1 -0
  215. package/dist/improve-core/improve-retain.js +115 -0
  216. package/dist/improve-core/improve-retain.js.map +1 -0
  217. package/dist/improve-core/improve-site-plan.d.ts +75 -0
  218. package/dist/improve-core/improve-site-plan.d.ts.map +1 -0
  219. package/dist/improve-core/improve-site-plan.js +135 -0
  220. package/dist/improve-core/improve-site-plan.js.map +1 -0
  221. package/dist/improve-core/improve-site-shell.d.ts +56 -0
  222. package/dist/improve-core/improve-site-shell.d.ts.map +1 -0
  223. package/dist/improve-core/improve-site-shell.js +152 -0
  224. package/dist/improve-core/improve-site-shell.js.map +1 -0
  225. package/dist/improve-core/improve-site-tokens.d.ts +44 -0
  226. package/dist/improve-core/improve-site-tokens.d.ts.map +1 -0
  227. package/dist/improve-core/improve-site-tokens.js +87 -0
  228. package/dist/improve-core/improve-site-tokens.js.map +1 -0
  229. package/dist/improve-core/improve-source-hints.d.ts +25 -0
  230. package/dist/improve-core/improve-source-hints.d.ts.map +1 -0
  231. package/dist/improve-core/improve-source-hints.js +17 -0
  232. package/dist/improve-core/improve-source-hints.js.map +1 -0
  233. package/dist/improve-core/improve-token-patch.d.ts.map +1 -0
  234. package/dist/{improve-token-patch.js → improve-core/improve-token-patch.js} +2 -0
  235. package/dist/improve-core/improve-token-patch.js.map +1 -0
  236. package/dist/improve-core/index.d.ts +47 -0
  237. package/dist/improve-core/index.d.ts.map +1 -0
  238. package/dist/improve-core/index.js +49 -0
  239. package/dist/improve-core/index.js.map +1 -0
  240. package/dist/improve-delivery-stages.d.ts +6 -0
  241. package/dist/improve-delivery-stages.d.ts.map +1 -1
  242. package/dist/improve-delivery-stages.js +87 -6
  243. package/dist/improve-delivery-stages.js.map +1 -1
  244. package/dist/improve-dom-diff.d.ts +8 -24
  245. package/dist/improve-dom-diff.d.ts.map +1 -1
  246. package/dist/improve-dom-diff.js +23 -123
  247. package/dist/improve-dom-diff.js.map +1 -1
  248. package/dist/improve-dom-gate.d.ts +1 -18
  249. package/dist/improve-dom-gate.d.ts.map +1 -1
  250. package/dist/improve-dom-gate.js +1 -46
  251. package/dist/improve-dom-gate.js.map +1 -1
  252. package/dist/improve-generation-stages.d.ts +0 -2
  253. package/dist/improve-generation-stages.d.ts.map +1 -1
  254. package/dist/improve-generation-stages.js +162 -15
  255. package/dist/improve-generation-stages.js.map +1 -1
  256. package/dist/improve-kit-assets.d.ts +8 -116
  257. package/dist/improve-kit-assets.d.ts.map +1 -1
  258. package/dist/improve-kit-assets.js +9 -229
  259. package/dist/improve-kit-assets.js.map +1 -1
  260. package/dist/improve-kit-readme.d.ts +4 -0
  261. package/dist/improve-kit-readme.d.ts.map +1 -1
  262. package/dist/improve-kit-readme.js +57 -16
  263. package/dist/improve-kit-readme.js.map +1 -1
  264. package/dist/improve-kit-stall.d.ts +3 -1
  265. package/dist/improve-kit-stall.d.ts.map +1 -1
  266. package/dist/improve-kit-stall.js +46 -14
  267. package/dist/improve-kit-stall.js.map +1 -1
  268. package/dist/improve-kit-status.d.ts.map +1 -1
  269. package/dist/improve-kit-status.js +8 -3
  270. package/dist/improve-kit-status.js.map +1 -1
  271. package/dist/improve-options.d.ts +8 -0
  272. package/dist/improve-options.d.ts.map +1 -1
  273. package/dist/improve-options.js +92 -12
  274. package/dist/improve-options.js.map +1 -1
  275. package/dist/improve-passthrough-flags.d.ts +8 -0
  276. package/dist/improve-passthrough-flags.d.ts.map +1 -0
  277. package/dist/improve-passthrough-flags.js +11 -0
  278. package/dist/improve-passthrough-flags.js.map +1 -0
  279. package/dist/improve-plan-annotator.d.ts +8 -2
  280. package/dist/improve-plan-annotator.d.ts.map +1 -1
  281. package/dist/improve-plan-annotator.js +35 -38
  282. package/dist/improve-plan-annotator.js.map +1 -1
  283. package/dist/improve-pricing-plan.d.ts +3 -0
  284. package/dist/improve-pricing-plan.d.ts.map +1 -1
  285. package/dist/improve-pricing-plan.js +33 -5
  286. package/dist/improve-pricing-plan.js.map +1 -1
  287. package/dist/improve-recheck.d.ts +9 -0
  288. package/dist/improve-recheck.d.ts.map +1 -0
  289. package/dist/improve-recheck.js +200 -0
  290. package/dist/improve-recheck.js.map +1 -0
  291. package/dist/improve-reset.d.ts.map +1 -1
  292. package/dist/improve-reset.js +11 -0
  293. package/dist/improve-reset.js.map +1 -1
  294. package/dist/improve-run-summary.d.ts +6 -0
  295. package/dist/improve-run-summary.d.ts.map +1 -1
  296. package/dist/improve-run-summary.js +29 -5
  297. package/dist/improve-run-summary.js.map +1 -1
  298. package/dist/improve-site-plan.d.ts +57 -0
  299. package/dist/improve-site-plan.d.ts.map +1 -0
  300. package/dist/improve-site-plan.js +79 -0
  301. package/dist/improve-site-plan.js.map +1 -0
  302. package/dist/improve-site-shell.d.ts +11 -0
  303. package/dist/improve-site-shell.d.ts.map +1 -0
  304. package/dist/improve-site-shell.js +24 -0
  305. package/dist/improve-site-shell.js.map +1 -0
  306. package/dist/improve-site-stage.d.ts +10 -0
  307. package/dist/improve-site-stage.d.ts.map +1 -0
  308. package/dist/improve-site-stage.js +84 -0
  309. package/dist/improve-site-stage.js.map +1 -0
  310. package/dist/improve-site-tokens.d.ts +9 -0
  311. package/dist/improve-site-tokens.d.ts.map +1 -0
  312. package/dist/improve-site-tokens.js +17 -0
  313. package/dist/improve-site-tokens.js.map +1 -0
  314. package/dist/improve-source-hints.d.ts +3 -12
  315. package/dist/improve-source-hints.d.ts.map +1 -1
  316. package/dist/improve-source-hints.js +4 -5
  317. package/dist/improve-source-hints.js.map +1 -1
  318. package/dist/improve-spend-ledger.d.ts +69 -0
  319. package/dist/improve-spend-ledger.d.ts.map +1 -0
  320. package/dist/improve-spend-ledger.js +118 -0
  321. package/dist/improve-spend-ledger.js.map +1 -0
  322. package/dist/improve-stage-runners.d.ts +5 -2
  323. package/dist/improve-stage-runners.d.ts.map +1 -1
  324. package/dist/improve-stage-runners.js +5 -2
  325. package/dist/improve-stage-runners.js.map +1 -1
  326. package/dist/improve-stage-shared.d.ts +10 -1
  327. package/dist/improve-stage-shared.d.ts.map +1 -1
  328. package/dist/improve-stage-shared.js.map +1 -1
  329. package/dist/improve-stop-handler.d.ts +15 -0
  330. package/dist/improve-stop-handler.d.ts.map +1 -1
  331. package/dist/improve-stop-handler.js +74 -3
  332. package/dist/improve-stop-handler.js.map +1 -1
  333. package/dist/improve-terminal-event.d.ts.map +1 -1
  334. package/dist/improve-terminal-event.js +7 -4
  335. package/dist/improve-terminal-event.js.map +1 -1
  336. package/dist/improve-workspace.d.ts +198 -2
  337. package/dist/improve-workspace.d.ts.map +1 -1
  338. package/dist/improve-workspace.js +249 -92
  339. package/dist/improve-workspace.js.map +1 -1
  340. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  341. package/dist/legacy-skill-catalog.js +79 -0
  342. package/dist/legacy-skill-catalog.js.map +1 -1
  343. package/dist/mcp-convert.js +1 -1
  344. package/dist/mcp-convert.js.map +1 -1
  345. package/dist/mcp-tool-definitions.js +1 -1
  346. package/dist/mcp-tool-definitions.js.map +1 -1
  347. package/dist/mcp-tool-handler.d.ts.map +1 -1
  348. package/dist/mcp-tool-handler.js +0 -3
  349. package/dist/mcp-tool-handler.js.map +1 -1
  350. package/dist/redesign-branch-adoption.d.ts +29 -0
  351. package/dist/redesign-branch-adoption.d.ts.map +1 -0
  352. package/dist/redesign-branch-adoption.js +183 -0
  353. package/dist/redesign-branch-adoption.js.map +1 -0
  354. package/dist/redesign-branch-identity.d.ts +23 -0
  355. package/dist/redesign-branch-identity.d.ts.map +1 -0
  356. package/dist/redesign-branch-identity.js +27 -0
  357. package/dist/redesign-branch-identity.js.map +1 -0
  358. package/dist/redesign-branch-record-verification.d.ts +51 -0
  359. package/dist/redesign-branch-record-verification.d.ts.map +1 -0
  360. package/dist/redesign-branch-record-verification.js +127 -0
  361. package/dist/redesign-branch-record-verification.js.map +1 -0
  362. package/dist/redesign-branch-stage.d.ts +17 -0
  363. package/dist/redesign-branch-stage.d.ts.map +1 -0
  364. package/dist/redesign-branch-stage.js +218 -0
  365. package/dist/redesign-branch-stage.js.map +1 -0
  366. package/dist/redesign-capture.d.ts +145 -15
  367. package/dist/redesign-capture.d.ts.map +1 -1
  368. package/dist/redesign-capture.js +182 -71
  369. package/dist/redesign-capture.js.map +1 -1
  370. package/dist/redesign-page-candidates.d.ts +40 -0
  371. package/dist/redesign-page-candidates.d.ts.map +1 -0
  372. package/dist/redesign-page-candidates.js +131 -0
  373. package/dist/redesign-page-candidates.js.map +1 -0
  374. package/dist/redesign-page-ownership.d.ts +36 -0
  375. package/dist/redesign-page-ownership.d.ts.map +1 -0
  376. package/dist/redesign-page-ownership.js +174 -0
  377. package/dist/redesign-page-ownership.js.map +1 -0
  378. package/dist/redesign-plan-identity.d.ts +3 -1
  379. package/dist/redesign-plan-identity.d.ts.map +1 -1
  380. package/dist/redesign-plan-identity.js +4 -1
  381. package/dist/redesign-plan-identity.js.map +1 -1
  382. package/dist/redesign-plan.d.ts.map +1 -1
  383. package/dist/redesign-plan.js +12 -6
  384. package/dist/redesign-plan.js.map +1 -1
  385. package/dist/redesign-record-validation.d.ts +4 -0
  386. package/dist/redesign-record-validation.d.ts.map +1 -0
  387. package/dist/redesign-record-validation.js +210 -0
  388. package/dist/redesign-record-validation.js.map +1 -0
  389. package/dist/redesign-workspace.d.ts +43 -5
  390. package/dist/redesign-workspace.d.ts.map +1 -1
  391. package/dist/redesign-workspace.js +66 -7
  392. package/dist/redesign-workspace.js.map +1 -1
  393. package/dist/responsive-alternative-materializer.d.ts +8 -3
  394. package/dist/responsive-alternative-materializer.d.ts.map +1 -1
  395. package/dist/responsive-alternative-materializer.js +68 -51
  396. package/dist/responsive-alternative-materializer.js.map +1 -1
  397. package/dist/result-integrity.d.ts +38 -0
  398. package/dist/result-integrity.d.ts.map +1 -0
  399. package/dist/result-integrity.js +46 -0
  400. package/dist/result-integrity.js.map +1 -0
  401. package/dist/review-edit-source.d.ts.map +1 -1
  402. package/dist/review-edit-source.js +6 -2
  403. package/dist/review-edit-source.js.map +1 -1
  404. package/dist/review-edit.js +2 -2
  405. package/dist/review-edit.js.map +1 -1
  406. package/dist/review-prototype-gap.js +1 -1
  407. package/dist/review-prototype-gap.js.map +1 -1
  408. package/dist/run-journal.d.ts +3 -1
  409. package/dist/run-journal.d.ts.map +1 -1
  410. package/dist/run-journal.js +7 -1
  411. package/dist/run-journal.js.map +1 -1
  412. package/dist/spend-run-filter.d.ts +21 -0
  413. package/dist/spend-run-filter.d.ts.map +1 -0
  414. package/dist/spend-run-filter.js +67 -0
  415. package/dist/spend-run-filter.js.map +1 -0
  416. package/dist/spend-scoped-report-lines.d.ts +4 -0
  417. package/dist/spend-scoped-report-lines.d.ts.map +1 -0
  418. package/dist/spend-scoped-report-lines.js +46 -0
  419. package/dist/spend-scoped-report-lines.js.map +1 -0
  420. package/dist/spend-scoped-report.d.ts +28 -0
  421. package/dist/spend-scoped-report.d.ts.map +1 -0
  422. package/dist/spend-scoped-report.js +45 -0
  423. package/dist/spend-scoped-report.js.map +1 -0
  424. package/open-design.json +2 -2
  425. package/package.json +5 -5
  426. package/skills/12ui-design/SKILL.md +8 -4
  427. package/skills/12ui-design/improve.md +50 -3
  428. package/dist/improve-dom-anchor.d.ts.map +0 -1
  429. package/dist/improve-dom-anchor.js.map +0 -1
  430. package/dist/improve-dom-extract.d.ts.map +0 -1
  431. package/dist/improve-dom-extract.js.map +0 -1
  432. package/dist/improve-dom-neighbour.d.ts.map +0 -1
  433. package/dist/improve-dom-neighbour.js.map +0 -1
  434. package/dist/improve-dom-scale.d.ts.map +0 -1
  435. package/dist/improve-dom-scale.js.map +0 -1
  436. package/dist/improve-icon-svg.d.ts +0 -47
  437. package/dist/improve-icon-svg.d.ts.map +0 -1
  438. package/dist/improve-icon-svg.js.map +0 -1
  439. package/dist/improve-layerdoc-diff.d.ts.map +0 -1
  440. package/dist/improve-layerdoc-diff.js.map +0 -1
  441. package/dist/improve-layerdoc-types.d.ts.map +0 -1
  442. package/dist/improve-layerdoc-types.js +0 -2
  443. package/dist/improve-layerdoc-types.js.map +0 -1
  444. package/dist/improve-plan-annotated-render.d.ts.map +0 -1
  445. package/dist/improve-plan-render.d.ts.map +0 -1
  446. package/dist/improve-plan-render.js.map +0 -1
  447. package/dist/improve-raster-layers-section.d.ts.map +0 -1
  448. package/dist/improve-raster-layers-section.js.map +0 -1
  449. package/dist/improve-token-patch.d.ts.map +0 -1
  450. package/dist/improve-token-patch.js.map +0 -1
  451. /package/dist/{improve-dom-anchor.d.ts → improve-core/improve-dom-anchor.d.ts} +0 -0
  452. /package/dist/{improve-dom-extract.d.ts → improve-core/improve-dom-extract.d.ts} +0 -0
  453. /package/dist/{improve-dom-neighbour.d.ts → improve-core/improve-dom-neighbour.d.ts} +0 -0
  454. /package/dist/{improve-dom-scale.d.ts → improve-core/improve-dom-scale.d.ts} +0 -0
  455. /package/dist/{improve-layerdoc-diff.d.ts → improve-core/improve-layerdoc-diff.d.ts} +0 -0
  456. /package/dist/{improve-token-patch.d.ts → improve-core/improve-token-patch.d.ts} +0 -0
@@ -1,13 +1,10 @@
1
- import { createHash } from 'node:crypto';
2
1
  import { mkdir, readFile } from 'node:fs/promises';
3
2
  import path from 'node:path';
4
- import { TwelveUiBranchClient } from './branch-client.js';
5
- import { executeBranchRun } from './branch-execution.js';
6
- import { branchAttemptPath, readBranchAttempt } from './branch-run-record.js';
7
- import { imageWinner } from './branch-winner.js';
8
- import { booleanFlag, stringFlag } from './cli-arguments.js';
3
+ import { createConcurrencyLimiter } from './bounded-concurrency.js';
4
+ import { booleanFlag, stringFlag, stringFlags } from './cli-arguments.js';
9
5
  import { CliRefusal } from './cli-refusal.js';
10
6
  import { prepareOutputDirectory } from './cli-output-paths.js';
7
+ import { BRANCH_PAGE_CONCURRENCY_DEFAULT } from './cli-progress.js';
11
8
  import { usageRefusal } from './cli-usage.js';
12
9
  import { readConceptValue } from './concept-input.js';
13
10
  import { readConversionConfig } from './config.js';
@@ -15,14 +12,19 @@ import { isConversionModel } from './conversion-models.js';
15
12
  import { runDraftCommand } from './cli-draft-command.js';
16
13
  import { DRAFT_CANDIDATE_COUNT, DRAFT_CANDIDATE_COUNT_MAXIMUM, DRAFT_CANDIDATE_COUNT_MINIMUM, } from './draft-run.js';
17
14
  import { draftPaths, readDraftRecord } from './draft-workspace.js';
18
- import { TwelveUiConversionPackageClient } from './package-client.js';
19
15
  import { TwelveUiPrototypeLabelClient } from './prototype-label-client.js';
20
16
  import { isPrototypeSkippedResult, runPrototypePoststep } from './prototype-poststep.js';
21
- import { captureRedesignPages, discoverRedesignPageUrls, REDESIGN_DEFAULT_MAX_PAGES, } from './redesign-capture.js';
17
+ import { runRedesignBranchStage } from './redesign-branch-stage.js';
18
+ import { redesignBranchPageDirectory } from './redesign-branch-identity.js';
19
+ import { InvalidRedesignBranchRecordError, verifyRedesignBranchPages, } from './redesign-branch-record-verification.js';
20
+ import { captureRedesignSite, captureRedesignPages, discoverRedesignPageUrls, parseImproveBootstrap, REDESIGN_DEFAULT_MAX_PAGES, } from './redesign-capture.js';
22
21
  import { buildRedesignPlan } from './redesign-plan.js';
23
22
  import { TwelveUiRedesignPlanClient, } from './redesign-plan-client.js';
24
23
  import { redesignPlanIdempotencyKey } from './redesign-plan-identity.js';
25
- import { createRedesignWorkspace, isRedesignStage, loadOrStartRedesignRecord, redesignPaths, REDESIGN_STAGES, writeRedesignRecord, } from './redesign-workspace.js';
24
+ import { createRedesignWorkspace, InvalidRedesignRecordError, isRedesignStage, loadOrStartRedesignRecord, readRedesignRecord, redesignPaths, REDESIGN_STAGES, writeRedesignRecord, } from './redesign-workspace.js';
25
+ import { draftForPage, pagesNeedingDraft, pagesNeedingPick, recordedDraftPages, recordedPickPages, redesignPageDraftConcept, redesignPageDraftRoute, redesignPrimaryPage, withDraftPages, withPickPages, } from './redesign-page-candidates.js';
26
+ import { InvalidRedesignBranchArtifactError } from './redesign-branch-adoption.js';
27
+ import { InvalidRedesignPageOwnershipError } from './redesign-page-ownership.js';
26
28
  /**
27
29
  * `12ui redesign <url> --direction <text>`: capture -> plan -> draft -> pick -> branch
28
30
  * -> polish, chained through the same library entry points and client
@@ -101,6 +103,30 @@ const readStageRange = (flags) => {
101
103
  const runCaptureStage = async (args) => {
102
104
  if (args.record.capture)
103
105
  return args.record;
106
+ // Tests that inject a one-page screenshot deliberately exercise record
107
+ // plumbing without a browser. Production and browser-backed tests discover
108
+ // from the rendered session, after bootstrap has seated authentication.
109
+ if (!args.dependencies.capture?.capturePage) {
110
+ const captured = await captureRedesignSite({
111
+ url: args.record.url,
112
+ outDir: args.paths.captureDir,
113
+ maxPages: args.pageCount,
114
+ bootstrap: args.bootstrap,
115
+ ...(args.dependencies.capture ? { dependencies: args.dependencies.capture } : {}),
116
+ });
117
+ if (captured.discovery.count < captured.discovery.cap) {
118
+ const context = captured.discovery.context === 'authenticated'
119
+ ? 'the authenticated capture context'
120
+ : 'the rendered public root; pass --bootstrap to seat a session before discovery';
121
+ args.warn(`Discovered ${captured.discovery.count} page(s), below the --pages cap of ${captured.discovery.cap}, from ${context}.`);
122
+ }
123
+ const record = {
124
+ ...args.record,
125
+ capture: { pages: captured.pages, discovery: captured.discovery },
126
+ };
127
+ await writeRedesignRecord(args.paths.record, record);
128
+ return record;
129
+ }
104
130
  const urls = await (args.dependencies.discoverPages ?? discoverRedesignPageUrls)({
105
131
  url: args.record.url,
106
132
  maxPages: args.pageCount,
@@ -115,47 +141,70 @@ const runCaptureStage = async (args) => {
115
141
  return record;
116
142
  };
117
143
  const runDraftStage = async (args) => {
118
- if (args.record.draft)
119
- return args.record;
120
144
  if (!args.record.capture)
121
145
  throw new Error('Cannot draft before capture has run');
122
146
  if (!args.record.plan)
123
147
  throw new Error('Cannot draft before hosted planning has run');
124
- const homepage = args.record.capture.pages[0];
125
- if (!homepage)
126
- throw new Error('Capture recorded no pages to draft from');
127
- const draftFlags = {
128
- concept: args.record.plan.concept,
129
- reference: homepage.path,
130
- candidates: String(args.candidateCount),
131
- wait: true,
132
- };
148
+ const remaining = pagesNeedingDraft(args.record);
149
+ if (remaining.length === 0)
150
+ return args.record;
151
+ const plan = args.record.plan;
152
+ const primary = redesignPrimaryPage(args.record.capture.pages);
133
153
  const origin = stringFlag(args.flags, 'origin');
134
- if (origin)
135
- draftFlags.origin = origin;
136
154
  const apiKey = stringFlag(args.flags, 'api-key');
137
- if (apiKey)
138
- draftFlags['api-key'] = apiKey;
139
- await mkdir(args.paths.draftDir, { recursive: true });
140
- const result = await runDraftCommand(draftFlags, {
141
- ...(args.dependencies.readConfig ? { readConfig: args.dependencies.readConfig } : {}),
142
- ...(args.dependencies.createCorpusClient
143
- ? { createCorpusClient: args.dependencies.createCorpusClient } : {}),
144
- ...(args.dependencies.createHostedClient
145
- ? { createHostedClient: args.dependencies.createHostedClient } : {}),
146
- plannedDraft: {
147
- corpusQuery: args.record.plan.corpusQuery,
148
- retain: args.record.plan.retain,
149
- },
150
- workspaceRoot: args.paths.draftDir,
151
- write: () => { },
152
- ...(args.dependencies.warn ? { warn: args.dependencies.warn } : {}),
153
- });
154
- const record = {
155
- ...args.record,
156
- draft: { runDir: result.prepared.runDir, runId: result.prepared.runId },
157
- };
158
- await writeRedesignRecord(args.paths.record, record);
155
+ const limiter = createConcurrencyLimiter(BRANCH_PAGE_CONCURRENCY_DEFAULT);
156
+ const completed = await Promise.all(remaining.map((page) => limiter(async () => {
157
+ const pageRoute = redesignPageDraftRoute({ page, primary });
158
+ const draftFlags = {
159
+ concept: redesignPageDraftConcept({
160
+ planConcept: plan.concept,
161
+ page,
162
+ primary,
163
+ }),
164
+ reference: page.path,
165
+ candidates: String(args.candidateCount),
166
+ wait: true,
167
+ quiet: true,
168
+ };
169
+ if (origin)
170
+ draftFlags.origin = origin;
171
+ if (apiKey)
172
+ draftFlags['api-key'] = apiKey;
173
+ const workspaceRoot = path.join(args.paths.draftDir, page.id);
174
+ await mkdir(workspaceRoot, { recursive: true });
175
+ const result = await runDraftCommand(draftFlags, {
176
+ ...(args.dependencies.readConfig ? { readConfig: args.dependencies.readConfig } : {}),
177
+ ...(args.dependencies.createCorpusClient
178
+ ? { createCorpusClient: args.dependencies.createCorpusClient } : {}),
179
+ ...(args.dependencies.createHostedClient
180
+ ? { createHostedClient: args.dependencies.createHostedClient } : {}),
181
+ plannedDraft: {
182
+ corpusQuery: plan.corpusQuery,
183
+ retain: plan.retain,
184
+ },
185
+ workspaceRoot,
186
+ write: () => { },
187
+ referenceFromCapture: true,
188
+ ...(pageRoute ? { pageRoute } : {}),
189
+ ...(args.record.redrawGeneration ? { redrawGeneration: args.record.redrawGeneration } : {}),
190
+ ...(args.dependencies.warn ? { warn: args.dependencies.warn } : {}),
191
+ });
192
+ return { pageId: page.id, runDir: result.prepared.runDir, runId: result.prepared.runId };
193
+ })));
194
+ // Each Draft has already persisted its own paid handle. Fold the completed
195
+ // pages into redesign.json in capture order so resume and spend attribution
196
+ // stay deterministic even though independent page draws ran concurrently.
197
+ let record = args.record;
198
+ for (const page of completed) {
199
+ record = {
200
+ ...record,
201
+ draft: withDraftPages([
202
+ ...recordedDraftPages(record),
203
+ page,
204
+ ], primary.id),
205
+ };
206
+ await writeRedesignRecord(args.paths.record, record);
207
+ }
159
208
  return record;
160
209
  };
161
210
  const runPlanStage = async (args) => {
@@ -171,7 +220,9 @@ const runPlanStage = async (args) => {
171
220
  };
172
221
  const client = (args.dependencies.createRedesignPlanClient
173
222
  ?? ((config) => new TwelveUiRedesignPlanClient(config)))(args.config);
174
- const plan = await client.plan(request, redesignPlanIdempotencyKey(request));
223
+ const plan = await client.plan(request, redesignPlanIdempotencyKey(request, {
224
+ ...(args.record.redrawGeneration ? { redrawGeneration: args.record.redrawGeneration } : {}),
225
+ }));
175
226
  const record = {
176
227
  ...args.record,
177
228
  plan: {
@@ -187,107 +238,109 @@ const runPlanStage = async (args) => {
187
238
  return record;
188
239
  };
189
240
  const runPickStage = async (args) => {
190
- if (args.record.pick)
191
- return args.record;
241
+ if (!args.record.capture)
242
+ throw new Error('Cannot pick before capture has run');
192
243
  if (!args.record.draft)
193
244
  throw new Error('Cannot pick before draft has run');
245
+ const remaining = pagesNeedingPick(args.record);
246
+ if (remaining.length === 0)
247
+ return args.record;
194
248
  const requestedSlot = stringFlag(args.flags, 'slot')?.trim();
195
- const slotLetter = requestedSlot || DEFAULT_CANDIDATE_SLOT;
196
- if (!requestedSlot) {
197
- args.warn(`--slot was not given; defaulting to candidate ${DEFAULT_CANDIDATE_SLOT}.`);
249
+ const recordedSlots = new Set(recordedPickPages(args.record).map((page) => page.slot));
250
+ if (recordedSlots.size > 1) {
251
+ throw new CliRefusal(`Recorded page picks disagree on candidate slot in ${args.paths.runDir}; refusing to add another pick.`, 'redesign_pick_record_invalid');
198
252
  }
199
- const draftRunPaths = draftPaths(args.record.draft.runDir);
200
- const draftRecord = await readDraftRecord(draftRunPaths.draftRecord);
201
- if (!draftRecord)
202
- throw new Error(`No draft record in ${args.record.draft.runDir}`);
203
- const candidate = draftRecord.hosted.candidates.find((entry) => entry.id === slotLetter);
204
- if (!candidate) {
205
- throw new CliRefusal(`--slot must be one of ${draftRecord.hosted.candidates.map((entry) => entry.id).join(', ')}`, 'redesign_slot_invalid');
253
+ const recordedSlot = recordedSlots.values().next().value;
254
+ if (requestedSlot && recordedSlot && requestedSlot !== recordedSlot) {
255
+ throw new CliRefusal(`--slot ${requestedSlot} does not match the durable candidate ${recordedSlot}`
256
+ + ` already picked in ${args.paths.runDir}. Reuse ${recordedSlot} or start a new redesign.`, 'redesign_slot_mismatch');
206
257
  }
207
- const completion = await readFile(draftRunPaths.completion, 'utf8')
208
- .then((raw) => JSON.parse(raw))
209
- .catch(() => undefined);
210
- const materialized = completion?.candidates.find((entry) => entry.slot === candidate.slot);
211
- if (!materialized) {
212
- throw new CliRefusal(`Draft candidate ${slotLetter} is not materialized in ${args.record.draft.runDir};`
213
- + ' run the draft stage again with --from draft --to draft.', 'redesign_pick_not_materialized');
258
+ const slotLetter = recordedSlot ?? requestedSlot ?? DEFAULT_CANDIDATE_SLOT;
259
+ if (!requestedSlot && !recordedSlot) {
260
+ args.warn(`--slot was not given; defaulting to candidate ${DEFAULT_CANDIDATE_SLOT}.`);
214
261
  }
215
- const record = {
216
- ...args.record,
217
- pick: { slot: candidate.id, imagePath: materialized.path, sha256: materialized.sha256 },
218
- };
219
- await writeRedesignRecord(args.paths.record, record);
220
- return record;
221
- };
222
- const runBranchStage = async (args) => {
223
- if (!args.record.capture)
224
- throw new Error('Cannot branch before capture has run');
225
- if (!args.record.pick)
226
- throw new Error('Cannot branch before pick has run');
227
- const capture = args.record.capture;
228
- const pick = args.record.pick;
229
- const alreadyDone = new Map((args.record.branch?.pages ?? []).map((page) => [page.pageId, page]));
230
- const remaining = capture.pages.filter((page) => !alreadyDone.has(page.id));
231
- if (remaining.length === 0)
232
- return args.record;
233
- const branchClient = (args.dependencies.createBranchClient
234
- ?? args.dependencies.createHostedClient
235
- ?? ((value) => new TwelveUiBranchClient(value)))(args.config);
236
- const packageClient = (args.dependencies.createPackageClient
237
- ?? ((value) => new TwelveUiConversionPackageClient(value)))(args.config);
238
- const winner = await imageWinner(pick.imagePath, 'The picked candidate');
239
- const pages = [...alreadyDone.values()];
262
+ const primary = redesignPrimaryPage(args.record.capture.pages);
240
263
  let record = args.record;
241
264
  for (const page of remaining) {
242
- const branchDir = path.join(args.paths.branchDir, page.id);
243
- await prepareOutputDirectory(branchDir);
244
- const concept = readConceptValue({
245
- value: `${args.direction} Rebuild the page at ${page.url}.`,
246
- flag: '--direction',
247
- trimHint: 'Shorten the direction; each page URL is appended automatically.',
248
- });
249
- const idempotencyKey = `redesign-branch:v2:${createHash('sha256')
250
- .update(`${args.record.createdAt}\u0000${page.id}`)
251
- .digest('hex')}`;
252
- const resume = Boolean(await readBranchAttempt(branchAttemptPath(branchDir)));
253
- const result = await (args.dependencies.executeBranch ?? executeBranchRun)({
254
- branchClient,
255
- packageClient,
256
- inputs: {
257
- outDir: branchDir,
258
- scope: 'page',
259
- concept,
260
- idempotencyKey,
261
- winner,
262
- maxScreens: args.maxScreens,
263
- convert: {
264
- output: 'html',
265
- model: args.conversionModel,
265
+ let draft;
266
+ try {
267
+ draft = draftForPage(record, page.id);
268
+ }
269
+ catch {
270
+ throw new CliRefusal(`Captured page ${page.id} has no page-specific draft in ${args.paths.runDir}.`
271
+ + ' Re-run with --from draft so each remaining page can buy its own candidates.', 'redesign_page_draft_missing');
272
+ }
273
+ const draftRunPaths = draftPaths(draft.runDir);
274
+ const draftRecord = await readDraftRecord(draftRunPaths.draftRecord);
275
+ if (!draftRecord)
276
+ throw new Error(`No draft record in ${draft.runDir}`);
277
+ const candidate = draftRecord.hosted.candidates.find((entry) => entry.id === slotLetter);
278
+ if (!candidate) {
279
+ throw new CliRefusal(`--slot must be one of ${draftRecord.hosted.candidates.map((entry) => entry.id).join(', ')}`, 'redesign_slot_invalid');
280
+ }
281
+ const completion = await readFile(draftRunPaths.completion, 'utf8')
282
+ .then((raw) => JSON.parse(raw))
283
+ .catch(() => undefined);
284
+ const materialized = completion?.candidates.find((entry) => entry.slot === candidate.slot);
285
+ if (!materialized) {
286
+ throw new CliRefusal(`Draft candidate ${slotLetter} is not materialized in ${draft.runDir};`
287
+ + ' run the draft stage again with --from draft --to draft.', 'redesign_pick_not_materialized');
288
+ }
289
+ record = {
290
+ ...record,
291
+ pick: withPickPages([
292
+ ...recordedPickPages(record),
293
+ {
294
+ pageId: page.id,
295
+ slot: candidate.id,
296
+ imagePath: materialized.path,
297
+ sha256: materialized.sha256,
266
298
  },
267
- },
268
- origin: args.config.origin,
269
- resume,
270
- pageConcurrency: 1,
271
- });
272
- const labelClient = (args.dependencies.createPrototypeLabelClient
273
- ?? ((value) => new TwelveUiPrototypeLabelClient(value)))(args.config);
274
- await (args.dependencies.runPrototype ?? runPrototypePoststep)({ branchDir, labelClient });
275
- pages.push({
276
- pageId: page.id,
277
- branchDir,
278
- status: result.completion.status,
279
- completionPath: result.completionPath,
280
- });
281
- record = { ...record, branch: { pages: [...pages] } };
299
+ ], primary.id),
300
+ };
282
301
  await writeRedesignRecord(args.paths.record, record);
283
- if (result.failure)
284
- throw result.failure;
285
302
  }
286
303
  return record;
287
304
  };
288
305
  const runPolishStage = async (args) => {
289
306
  if (!args.record.branch)
290
307
  throw new Error('Cannot polish before branch has run');
308
+ if (!args.record.capture)
309
+ throw new Error('Cannot polish before capture has run');
310
+ let verified;
311
+ try {
312
+ verified = await verifyRedesignBranchPages({
313
+ record: args.record,
314
+ pages: args.record.capture.pages,
315
+ branchDirectory: (page) => redesignBranchPageDirectory({
316
+ paths: args.paths,
317
+ record: args.record,
318
+ pageId: page.id,
319
+ }),
320
+ branchConcept: (page) => readConceptValue({
321
+ value: `${args.record.direction} Rebuild the page at ${page.url}.`,
322
+ flag: '--direction',
323
+ trimHint: 'Shorten the direction; each page URL is appended automatically.',
324
+ }),
325
+ });
326
+ }
327
+ catch (error) {
328
+ if (error instanceof InvalidRedesignPageOwnershipError) {
329
+ throw new CliRefusal(`${error.message} Refusing polish.`, 'redesign_page_ownership_invalid', { cause: error });
330
+ }
331
+ if (error instanceof InvalidRedesignBranchArtifactError
332
+ || error instanceof InvalidRedesignBranchRecordError) {
333
+ throw new CliRefusal(`${error.message} Refusing polish.`, 'redesign_branch_artifact_invalid', { cause: error });
334
+ }
335
+ throw error;
336
+ }
337
+ const missing = verified.find((entry) => !entry.recorded);
338
+ if (missing) {
339
+ throw new CliRefusal(`Captured page ${missing.input.page.id} has no validated parent branch record; refusing polish.`, 'redesign_branch_missing');
340
+ }
341
+ const failure = verified.find((entry) => entry.adopted?.failure)?.adopted?.failure;
342
+ if (failure)
343
+ throw failure;
291
344
  const alreadyDone = new Map((args.record.polish?.pages ?? []).map((page) => [page.pageId, page]));
292
345
  const remaining = args.record.branch.pages.filter((page) => !alreadyDone.has(page.pageId));
293
346
  if (remaining.length === 0)
@@ -331,28 +384,31 @@ export const runRedesignCommand = async (command, flags, dependencies = {}) => {
331
384
  }
332
385
  })();
333
386
  const directionValue = stringFlag(flags, 'direction');
334
- if (!directionValue?.trim()) {
335
- throw usageRefusal({
336
- reason: 'A redesign needs a visual direction in words, and --direction was not given.',
337
- code: 'redesign_usage',
338
- verb: ['redesign'],
339
- });
340
- }
341
- const direction = readConceptValue({
342
- value: directionValue,
343
- flag: '--direction',
344
- trimHint: 'Keep the visual direction: mood, layout emphasis, and what should change.',
345
- });
346
- const pageCount = readPages(flags);
347
- const candidateCount = readCandidateCount(flags);
348
- const maxScreens = readMaxScreens(flags);
349
- const conversionModel = readConversionModel(flags);
350
- const { from, to } = readStageRange(flags);
387
+ const requestedDirection = directionValue?.trim()
388
+ ? readConceptValue({
389
+ value: directionValue,
390
+ flag: '--direction',
391
+ trimHint: 'Keep the visual direction: mood, layout emphasis, and what should change.',
392
+ })
393
+ : undefined;
394
+ const bootstrap = stringFlags(flags, 'bootstrap').map(parseImproveBootstrap);
395
+ let { from, to } = readStageRange(flags);
351
396
  const write = dependencies.write ?? ((line) => { process.stdout.write(`${line}\n`); });
352
397
  const warn = dependencies.warn ?? ((line) => { process.stderr.write(`${line}\n`); });
353
398
  if (booleanFlag(flags, 'dry-run')) {
399
+ if (!requestedDirection) {
400
+ throw usageRefusal({
401
+ reason: 'A redesign needs a visual direction in words, and --direction was not given.',
402
+ code: 'redesign_usage',
403
+ verb: ['redesign'],
404
+ });
405
+ }
406
+ const pageCount = readPages(flags);
407
+ const candidateCount = readCandidateCount(flags);
408
+ const maxScreens = readMaxScreens(flags);
409
+ const conversionModel = readConversionModel(flags);
354
410
  const plan = buildRedesignPlan({
355
- url, direction, pageCount, candidateCount, maxScreens, conversionModel,
411
+ url, direction: requestedDirection, pageCount, candidateCount, maxScreens, conversionModel,
356
412
  });
357
413
  console.log(JSON.stringify({
358
414
  dryRun: true,
@@ -366,7 +422,7 @@ export const runRedesignCommand = async (command, flags, dependencies = {}) => {
366
422
  createdAt: new Date().toISOString(),
367
423
  runDir: '',
368
424
  url,
369
- direction,
425
+ direction: requestedDirection,
370
426
  requestedPages: pageCount,
371
427
  requestedMaxScreens: maxScreens,
372
428
  requestedConversionModel: conversionModel,
@@ -391,14 +447,66 @@ export const runRedesignCommand = async (command, flags, dependencies = {}) => {
391
447
  write(paths.runDir);
392
448
  dependencies.onRunDirectory?.(paths.runDir);
393
449
  dependencies.journal?.note({ workspace: paths.runDir });
394
- let record = await loadOrStartRedesignRecord({
450
+ const existing = await readRedesignRecord(paths.record).catch((error) => {
451
+ if (error instanceof InvalidRedesignRecordError) {
452
+ throw new CliRefusal(`${error.message} Refusing to resume or start paid work in this directory.`, 'redesign_record_invalid', { cause: error });
453
+ }
454
+ throw error;
455
+ });
456
+ if (!existing && !requestedDirection) {
457
+ throw usageRefusal({
458
+ reason: 'A redesign needs a visual direction in words, and --direction was not given.',
459
+ code: 'redesign_usage',
460
+ verb: ['redesign'],
461
+ });
462
+ }
463
+ const redraw = booleanFlag(flags, 'redraw');
464
+ const reusingRecord = Boolean(existing) && !redraw;
465
+ const direction = requestedDirection ?? existing.direction;
466
+ // A resume is a replay of the durable invocation, not a chance for a
467
+ // caller's current defaults (or incidental copied flags) to drift a later
468
+ // stage. `--redraw` is the explicit boundary that accepts replacement.
469
+ const pageCount = reusingRecord ? existing.requestedPages : readPages(flags);
470
+ const candidateCount = reusingRecord
471
+ ? existing.requestedCandidateCount ?? DRAFT_CANDIDATE_COUNT
472
+ : readCandidateCount(flags);
473
+ const maxScreens = reusingRecord
474
+ ? existing.requestedMaxScreens ?? REDESIGN_MAX_SCREENS_MAXIMUM
475
+ : readMaxScreens(flags);
476
+ const conversionModel = reusingRecord
477
+ ? existing.requestedConversionModel ?? 'standard'
478
+ : readConversionModel(flags);
479
+ if (existing && requestedDirection && requestedDirection !== existing.direction
480
+ && !redraw) {
481
+ throw new CliRefusal('--direction does not match the durable redesign record. Drop --direction to reuse'
482
+ + ' the recorded direction, or pass --redraw to replace the dependent plan and draft.', 'redesign_record_mismatch');
483
+ }
484
+ let record = existing ?? await loadOrStartRedesignRecord({
395
485
  paths,
396
486
  url,
397
487
  direction,
398
488
  requestedPages: pageCount,
489
+ requestedCandidateCount: candidateCount,
399
490
  requestedMaxScreens: maxScreens,
400
491
  requestedConversionModel: conversionModel,
401
492
  });
493
+ if (existing && redraw) {
494
+ const { plan: _plan, draft: _draft, pick: _pick, branch: _branch, polish: _polish, ...retained } = existing;
495
+ record = {
496
+ ...retained,
497
+ direction,
498
+ redrawGeneration: (existing.redrawGeneration ?? 0) + 1,
499
+ requestedPages: pageCount,
500
+ requestedCandidateCount: candidateCount,
501
+ requestedMaxScreens: maxScreens,
502
+ requestedConversionModel: conversionModel,
503
+ };
504
+ // A redraw invalidates every dependent paid identity even when its words
505
+ // are unchanged. Capture remains frozen; generation names the fresh plan,
506
+ // draft, child directory, and branch idempotency namespace.
507
+ from = record.capture ? 'plan' : 'capture';
508
+ await writeRedesignRecord(paths.record, record);
509
+ }
402
510
  const config = (dependencies.readConfig ?? readConversionConfig)({
403
511
  origin: stringFlag(flags, 'origin'),
404
512
  apiKey: stringFlag(flags, 'api-key'),
@@ -408,7 +516,7 @@ export const runRedesignCommand = async (command, flags, dependencies = {}) => {
408
516
  const needed = (stage) => stageIndex(stage) <= stageIndex(to);
409
517
  if (needed('capture')) {
410
518
  if (withinRange('capture')) {
411
- record = await runCaptureStage({ record, paths, pageCount, dependencies });
519
+ record = await runCaptureStage({ record, paths, pageCount, bootstrap, dependencies, warn });
412
520
  }
413
521
  if (!record.capture) {
414
522
  throw new CliRefusal(`Stage capture has not run in ${paths.runDir}. Run this command with --to capture first,`
@@ -427,21 +535,25 @@ export const runRedesignCommand = async (command, flags, dependencies = {}) => {
427
535
  if (withinRange('draft')) {
428
536
  record = await runDraftStage({ record, paths, candidateCount, flags, dependencies });
429
537
  }
430
- if (!record.draft) {
431
- throw new CliRefusal(`Stage draft has not run in ${paths.runDir}.`, 'redesign_draft_missing');
538
+ if (!record.draft || pagesNeedingDraft(record).length > 0) {
539
+ throw new CliRefusal(pagesNeedingDraft(record).length > 0
540
+ ? `Stage draft has not produced a page-specific candidate for ${pagesNeedingDraft(record).map((page) => page.id).join(', ')} in ${paths.runDir}. Re-run with --from draft.`
541
+ : `Stage draft has not run in ${paths.runDir}.`, 'redesign_draft_missing');
432
542
  }
433
543
  }
434
544
  if (needed('pick')) {
435
545
  if (withinRange('pick')) {
436
546
  record = await runPickStage({ record, paths, flags, warn });
437
547
  }
438
- if (!record.pick) {
439
- throw new CliRefusal(`Stage pick has not run in ${paths.runDir}.`, 'redesign_pick_missing');
548
+ if (!record.pick || pagesNeedingPick(record).length > 0) {
549
+ throw new CliRefusal(pagesNeedingPick(record).length > 0
550
+ ? `Stage pick has not materialized a page-specific candidate for ${pagesNeedingPick(record).map((page) => page.id).join(', ')} in ${paths.runDir}. Re-run with --from draft.`
551
+ : `Stage pick has not run in ${paths.runDir}.`, 'redesign_pick_missing');
440
552
  }
441
553
  }
442
554
  if (needed('branch')) {
443
555
  if (withinRange('branch')) {
444
- record = await runBranchStage({
556
+ record = await runRedesignBranchStage({
445
557
  record,
446
558
  paths,
447
559
  direction,