@12ui/design 0.2.56 → 0.2.58

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 (429) 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/branch-client.d.ts +86 -2
  6. package/dist/branch-client.d.ts.map +1 -1
  7. package/dist/branch-client.js +31 -0
  8. package/dist/branch-client.js.map +1 -1
  9. package/dist/cli-arguments.d.ts.map +1 -1
  10. package/dist/cli-arguments.js +3 -1
  11. package/dist/cli-arguments.js.map +1 -1
  12. package/dist/cli-capabilities.d.ts +1 -1
  13. package/dist/cli-conversion-derivation.js +2 -2
  14. package/dist/cli-conversion-derivation.js.map +1 -1
  15. package/dist/cli-convert-command.d.ts +2 -0
  16. package/dist/cli-convert-command.d.ts.map +1 -1
  17. package/dist/cli-convert-command.js +176 -38
  18. package/dist/cli-convert-command.js.map +1 -1
  19. package/dist/cli-corpus-command.js +2 -2
  20. package/dist/cli-corpus-command.js.map +1 -1
  21. package/dist/cli-corpus-evidence.d.ts.map +1 -1
  22. package/dist/cli-corpus-evidence.js +2 -1
  23. package/dist/cli-corpus-evidence.js.map +1 -1
  24. package/dist/cli-corpus-reference-downloads.d.ts +1 -0
  25. package/dist/cli-corpus-reference-downloads.d.ts.map +1 -1
  26. package/dist/cli-corpus-reference-downloads.js +13 -3
  27. package/dist/cli-corpus-reference-downloads.js.map +1 -1
  28. package/dist/cli-corpus-types.d.ts +2 -0
  29. package/dist/cli-corpus-types.d.ts.map +1 -1
  30. package/dist/cli-draft-command.d.ts +9 -0
  31. package/dist/cli-draft-command.d.ts.map +1 -1
  32. package/dist/cli-draft-command.js +26 -1
  33. package/dist/cli-draft-command.js.map +1 -1
  34. package/dist/cli-help/design.d.ts +7 -4
  35. package/dist/cli-help/design.d.ts.map +1 -1
  36. package/dist/cli-help/design.js +23 -6
  37. package/dist/cli-help/design.js.map +1 -1
  38. package/dist/cli-help/index.d.ts +9 -6
  39. package/dist/cli-help/index.d.ts.map +1 -1
  40. package/dist/cli-help/meta.d.ts +2 -2
  41. package/dist/cli-help/meta.d.ts.map +1 -1
  42. package/dist/cli-help/meta.js +4 -1
  43. package/dist/cli-help/meta.js.map +1 -1
  44. package/dist/cli-improve-command.d.ts.map +1 -1
  45. package/dist/cli-improve-command.js +273 -28
  46. package/dist/cli-improve-command.js.map +1 -1
  47. package/dist/cli-redesign-command.d.ts.map +1 -1
  48. package/dist/cli-redesign-command.js +97 -24
  49. package/dist/cli-redesign-command.js.map +1 -1
  50. package/dist/cli-run.d.ts.map +1 -1
  51. package/dist/cli-run.js +13 -3
  52. package/dist/cli-run.js.map +1 -1
  53. package/dist/cli-spend-command.d.ts +12 -1
  54. package/dist/cli-spend-command.d.ts.map +1 -1
  55. package/dist/cli-spend-command.js +94 -2
  56. package/dist/cli-spend-command.js.map +1 -1
  57. package/dist/cli-usage.js +5 -5
  58. package/dist/cli-usage.js.map +1 -1
  59. package/dist/concept-input.d.ts +6 -56
  60. package/dist/concept-input.d.ts.map +1 -1
  61. package/dist/concept-input.js +6 -65
  62. package/dist/concept-input.js.map +1 -1
  63. package/dist/conversion-client.d.ts +92 -3
  64. package/dist/conversion-client.d.ts.map +1 -1
  65. package/dist/conversion-client.js +317 -23
  66. package/dist/conversion-client.js.map +1 -1
  67. package/dist/corpus-client.d.ts +7 -1
  68. package/dist/corpus-client.d.ts.map +1 -1
  69. package/dist/corpus-client.js +3 -2
  70. package/dist/corpus-client.js.map +1 -1
  71. package/dist/corpus-reference-download-retry.d.ts +68 -0
  72. package/dist/corpus-reference-download-retry.d.ts.map +1 -0
  73. package/dist/corpus-reference-download-retry.js +123 -0
  74. package/dist/corpus-reference-download-retry.js.map +1 -0
  75. package/dist/corpus-request-error.d.ts +17 -0
  76. package/dist/corpus-request-error.d.ts.map +1 -0
  77. package/dist/corpus-request-error.js +21 -0
  78. package/dist/corpus-request-error.js.map +1 -0
  79. package/dist/draft-run.d.ts +15 -0
  80. package/dist/draft-run.d.ts.map +1 -1
  81. package/dist/draft-run.js +32 -5
  82. package/dist/draft-run.js.map +1 -1
  83. package/dist/draft-workspace.d.ts +2 -1
  84. package/dist/draft-workspace.d.ts.map +1 -1
  85. package/dist/draft-workspace.js.map +1 -1
  86. package/dist/hosted-draft-identity.d.ts +9 -0
  87. package/dist/hosted-draft-identity.d.ts.map +1 -1
  88. package/dist/hosted-draft-identity.js +2 -0
  89. package/dist/hosted-draft-identity.js.map +1 -1
  90. package/dist/improve-added-specs.d.ts +12 -31
  91. package/dist/improve-added-specs.d.ts.map +1 -1
  92. package/dist/improve-added-specs.js +64 -152
  93. package/dist/improve-added-specs.js.map +1 -1
  94. package/dist/improve-artifact-writer.d.ts +13 -0
  95. package/dist/improve-artifact-writer.d.ts.map +1 -0
  96. package/dist/improve-artifact-writer.js +27 -0
  97. package/dist/improve-artifact-writer.js.map +1 -0
  98. package/dist/improve-bootstrap-history.d.ts +21 -0
  99. package/dist/improve-bootstrap-history.d.ts.map +1 -0
  100. package/dist/improve-bootstrap-history.js +43 -0
  101. package/dist/improve-bootstrap-history.js.map +1 -0
  102. package/dist/improve-bootstrap-secret.d.ts +35 -0
  103. package/dist/improve-bootstrap-secret.d.ts.map +1 -0
  104. package/dist/improve-bootstrap-secret.js +61 -0
  105. package/dist/improve-bootstrap-secret.js.map +1 -0
  106. package/dist/improve-branch-stage.d.ts +10 -0
  107. package/dist/improve-branch-stage.d.ts.map +1 -0
  108. package/dist/improve-branch-stage.js +325 -0
  109. package/dist/improve-branch-stage.js.map +1 -0
  110. package/dist/improve-capture-redirect.d.ts +65 -0
  111. package/dist/improve-capture-redirect.d.ts.map +1 -0
  112. package/dist/improve-capture-redirect.js +85 -0
  113. package/dist/improve-capture-redirect.js.map +1 -0
  114. package/dist/improve-capture-words.d.ts +43 -0
  115. package/dist/improve-capture-words.d.ts.map +1 -0
  116. package/dist/improve-capture-words.js +25 -0
  117. package/dist/improve-capture-words.js.map +1 -0
  118. package/dist/improve-concept.d.ts +6 -7
  119. package/dist/improve-concept.d.ts.map +1 -1
  120. package/dist/improve-concept.js +12 -38
  121. package/dist/improve-concept.js.map +1 -1
  122. package/dist/improve-conversion-attempts.d.ts +21 -9
  123. package/dist/improve-conversion-attempts.d.ts.map +1 -1
  124. package/dist/improve-conversion-attempts.js +6 -1
  125. package/dist/improve-conversion-attempts.js.map +1 -1
  126. package/dist/improve-conversion-stage.d.ts +20 -2
  127. package/dist/improve-conversion-stage.d.ts.map +1 -1
  128. package/dist/improve-conversion-stage.js +386 -178
  129. package/dist/improve-conversion-stage.js.map +1 -1
  130. package/dist/improve-convert-progress.d.ts +44 -0
  131. package/dist/improve-convert-progress.d.ts.map +1 -0
  132. package/dist/improve-convert-progress.js +47 -0
  133. package/dist/improve-convert-progress.js.map +1 -0
  134. package/dist/improve-convert-resilience.d.ts +96 -58
  135. package/dist/improve-convert-resilience.d.ts.map +1 -1
  136. package/dist/improve-convert-resilience.js +128 -72
  137. package/dist/improve-convert-resilience.js.map +1 -1
  138. package/dist/improve-core/concept-input.d.ts +80 -0
  139. package/dist/improve-core/concept-input.d.ts.map +1 -0
  140. package/dist/improve-core/concept-input.js +92 -0
  141. package/dist/improve-core/concept-input.js.map +1 -0
  142. package/dist/improve-core/improve-added-specs.d.ts +62 -0
  143. package/dist/improve-core/improve-added-specs.d.ts.map +1 -0
  144. package/dist/improve-core/improve-added-specs.js +160 -0
  145. package/dist/improve-core/improve-added-specs.js.map +1 -0
  146. package/dist/improve-core/improve-artifacts.d.ts +18 -0
  147. package/dist/improve-core/improve-artifacts.d.ts.map +1 -0
  148. package/dist/improve-core/improve-artifacts.js +4 -0
  149. package/dist/improve-core/improve-artifacts.js.map +1 -0
  150. package/dist/improve-core/improve-concept.d.ts +7 -0
  151. package/dist/improve-core/improve-concept.d.ts.map +1 -0
  152. package/dist/improve-core/improve-concept.js +185 -0
  153. package/dist/improve-core/improve-concept.js.map +1 -0
  154. package/dist/improve-core/improve-discovery.d.ts +84 -0
  155. package/dist/improve-core/improve-discovery.d.ts.map +1 -0
  156. package/dist/improve-core/improve-discovery.js +154 -0
  157. package/dist/improve-core/improve-discovery.js.map +1 -0
  158. package/dist/improve-core/improve-dom-anchor.d.ts.map +1 -0
  159. package/dist/{improve-dom-anchor.js → improve-core/improve-dom-anchor.js} +2 -0
  160. package/dist/improve-core/improve-dom-anchor.js.map +1 -0
  161. package/dist/improve-core/improve-dom-diff.d.ts +59 -0
  162. package/dist/improve-core/improve-dom-diff.d.ts.map +1 -0
  163. package/dist/improve-core/improve-dom-diff.js +151 -0
  164. package/dist/improve-core/improve-dom-diff.js.map +1 -0
  165. package/dist/improve-core/improve-dom-extract.d.ts.map +1 -0
  166. package/dist/{improve-dom-extract.js → improve-core/improve-dom-extract.js} +2 -0
  167. package/dist/improve-core/improve-dom-extract.js.map +1 -0
  168. package/dist/improve-core/improve-dom-gate.d.ts +49 -0
  169. package/dist/improve-core/improve-dom-gate.d.ts.map +1 -0
  170. package/dist/improve-core/improve-dom-gate.js +99 -0
  171. package/dist/improve-core/improve-dom-gate.js.map +1 -0
  172. package/dist/improve-core/improve-dom-neighbour.d.ts.map +1 -0
  173. package/dist/{improve-dom-neighbour.js → improve-core/improve-dom-neighbour.js} +2 -0
  174. package/dist/improve-core/improve-dom-neighbour.js.map +1 -0
  175. package/dist/improve-core/improve-dom-scale.d.ts.map +1 -0
  176. package/dist/{improve-dom-scale.js → improve-core/improve-dom-scale.js} +2 -0
  177. package/dist/improve-core/improve-dom-scale.js.map +1 -0
  178. package/dist/improve-core/improve-icon-svg.d.ts +29 -0
  179. package/dist/improve-core/improve-icon-svg.d.ts.map +1 -0
  180. package/dist/improve-core/improve-icon-svg.js +85 -0
  181. package/dist/improve-core/improve-icon-svg.js.map +1 -0
  182. package/dist/improve-core/improve-kit-asset-model.d.ts +177 -0
  183. package/dist/improve-core/improve-kit-asset-model.d.ts.map +1 -0
  184. package/dist/improve-core/improve-kit-asset-model.js +269 -0
  185. package/dist/improve-core/improve-kit-asset-model.js.map +1 -0
  186. package/dist/improve-core/improve-layerdoc-diff.d.ts.map +1 -0
  187. package/dist/{improve-layerdoc-diff.js → improve-core/improve-layerdoc-diff.js} +2 -0
  188. package/dist/improve-core/improve-layerdoc-diff.js.map +1 -0
  189. package/dist/{improve-layerdoc-types.d.ts → improve-core/improve-layerdoc-types.d.ts} +9 -0
  190. package/dist/improve-core/improve-layerdoc-types.d.ts.map +1 -0
  191. package/dist/improve-core/improve-layerdoc-types.js +4 -0
  192. package/dist/improve-core/improve-layerdoc-types.js.map +1 -0
  193. package/dist/improve-core/improve-page-words.d.ts +180 -0
  194. package/dist/improve-core/improve-page-words.d.ts.map +1 -0
  195. package/dist/improve-core/improve-page-words.js +303 -0
  196. package/dist/improve-core/improve-page-words.js.map +1 -0
  197. package/dist/{improve-plan-annotated-render.d.ts → improve-core/improve-plan-annotated-render.d.ts} +19 -2
  198. package/dist/improve-core/improve-plan-annotated-render.d.ts.map +1 -0
  199. package/dist/{improve-plan-annotated-render.js → improve-core/improve-plan-annotated-render.js} +77 -28
  200. package/dist/improve-core/improve-plan-annotated-render.js.map +1 -0
  201. package/dist/improve-core/improve-plan-annotator.d.ts +34 -0
  202. package/dist/improve-core/improve-plan-annotator.d.ts.map +1 -0
  203. package/dist/improve-core/improve-plan-annotator.js +52 -0
  204. package/dist/improve-core/improve-plan-annotator.js.map +1 -0
  205. package/dist/{improve-plan-render.d.ts → improve-core/improve-plan-render.d.ts} +2 -1
  206. package/dist/improve-core/improve-plan-render.d.ts.map +1 -0
  207. package/dist/{improve-plan-render.js → improve-core/improve-plan-render.js} +7 -1
  208. package/dist/improve-core/improve-plan-render.js.map +1 -0
  209. package/dist/improve-core/improve-plan-vector-keep.d.ts +29 -0
  210. package/dist/improve-core/improve-plan-vector-keep.d.ts.map +1 -0
  211. package/dist/improve-core/improve-plan-vector-keep.js +68 -0
  212. package/dist/improve-core/improve-plan-vector-keep.js.map +1 -0
  213. package/dist/{improve-raster-layers-section.d.ts → improve-core/improve-raster-layers-section.d.ts} +9 -1
  214. package/dist/improve-core/improve-raster-layers-section.d.ts.map +1 -0
  215. package/dist/{improve-raster-layers-section.js → improve-core/improve-raster-layers-section.js} +5 -2
  216. package/dist/improve-core/improve-raster-layers-section.js.map +1 -0
  217. package/dist/improve-core/improve-refusal.d.ts +6 -0
  218. package/dist/improve-core/improve-refusal.d.ts.map +1 -0
  219. package/dist/improve-core/improve-refusal.js +27 -0
  220. package/dist/improve-core/improve-refusal.js.map +1 -0
  221. package/dist/improve-core/improve-retain.d.ts +121 -0
  222. package/dist/improve-core/improve-retain.d.ts.map +1 -0
  223. package/dist/improve-core/improve-retain.js +115 -0
  224. package/dist/improve-core/improve-retain.js.map +1 -0
  225. package/dist/improve-core/improve-site-plan.d.ts +75 -0
  226. package/dist/improve-core/improve-site-plan.d.ts.map +1 -0
  227. package/dist/improve-core/improve-site-plan.js +135 -0
  228. package/dist/improve-core/improve-site-plan.js.map +1 -0
  229. package/dist/improve-core/improve-site-shell.d.ts +56 -0
  230. package/dist/improve-core/improve-site-shell.d.ts.map +1 -0
  231. package/dist/improve-core/improve-site-shell.js +152 -0
  232. package/dist/improve-core/improve-site-shell.js.map +1 -0
  233. package/dist/improve-core/improve-site-tokens.d.ts +44 -0
  234. package/dist/improve-core/improve-site-tokens.d.ts.map +1 -0
  235. package/dist/improve-core/improve-site-tokens.js +87 -0
  236. package/dist/improve-core/improve-site-tokens.js.map +1 -0
  237. package/dist/improve-core/improve-source-hints.d.ts +25 -0
  238. package/dist/improve-core/improve-source-hints.d.ts.map +1 -0
  239. package/dist/improve-core/improve-source-hints.js +17 -0
  240. package/dist/improve-core/improve-source-hints.js.map +1 -0
  241. package/dist/{improve-token-patch.d.ts → improve-core/improve-token-patch.d.ts} +2 -0
  242. package/dist/improve-core/improve-token-patch.d.ts.map +1 -0
  243. package/dist/{improve-token-patch.js → improve-core/improve-token-patch.js} +25 -5
  244. package/dist/improve-core/improve-token-patch.js.map +1 -0
  245. package/dist/improve-core/index.d.ts +47 -0
  246. package/dist/improve-core/index.d.ts.map +1 -0
  247. package/dist/improve-core/index.js +49 -0
  248. package/dist/improve-core/index.js.map +1 -0
  249. package/dist/improve-delivery-stages.d.ts +6 -0
  250. package/dist/improve-delivery-stages.d.ts.map +1 -1
  251. package/dist/improve-delivery-stages.js +91 -6
  252. package/dist/improve-delivery-stages.js.map +1 -1
  253. package/dist/improve-dom-diff.d.ts +8 -24
  254. package/dist/improve-dom-diff.d.ts.map +1 -1
  255. package/dist/improve-dom-diff.js +23 -123
  256. package/dist/improve-dom-diff.js.map +1 -1
  257. package/dist/improve-dom-gate.d.ts +1 -18
  258. package/dist/improve-dom-gate.d.ts.map +1 -1
  259. package/dist/improve-dom-gate.js +1 -46
  260. package/dist/improve-dom-gate.js.map +1 -1
  261. package/dist/improve-generation-stages.d.ts +0 -2
  262. package/dist/improve-generation-stages.d.ts.map +1 -1
  263. package/dist/improve-generation-stages.js +191 -15
  264. package/dist/improve-generation-stages.js.map +1 -1
  265. package/dist/improve-kit-assets.d.ts +8 -116
  266. package/dist/improve-kit-assets.d.ts.map +1 -1
  267. package/dist/improve-kit-assets.js +9 -229
  268. package/dist/improve-kit-assets.js.map +1 -1
  269. package/dist/improve-kit-ignore.d.ts +32 -0
  270. package/dist/improve-kit-ignore.d.ts.map +1 -0
  271. package/dist/improve-kit-ignore.js +111 -0
  272. package/dist/improve-kit-ignore.js.map +1 -0
  273. package/dist/improve-kit-readme.d.ts +4 -0
  274. package/dist/improve-kit-readme.d.ts.map +1 -1
  275. package/dist/improve-kit-readme.js +155 -24
  276. package/dist/improve-kit-readme.js.map +1 -1
  277. package/dist/improve-kit-stall.d.ts +51 -3
  278. package/dist/improve-kit-stall.d.ts.map +1 -1
  279. package/dist/improve-kit-stall.js +205 -21
  280. package/dist/improve-kit-stall.js.map +1 -1
  281. package/dist/improve-kit-status.d.ts +36 -0
  282. package/dist/improve-kit-status.d.ts.map +1 -1
  283. package/dist/improve-kit-status.js +82 -7
  284. package/dist/improve-kit-status.js.map +1 -1
  285. package/dist/improve-options.d.ts +14 -0
  286. package/dist/improve-options.d.ts.map +1 -1
  287. package/dist/improve-options.js +95 -12
  288. package/dist/improve-options.js.map +1 -1
  289. package/dist/improve-passthrough-flags.d.ts +8 -0
  290. package/dist/improve-passthrough-flags.d.ts.map +1 -0
  291. package/dist/improve-passthrough-flags.js +11 -0
  292. package/dist/improve-passthrough-flags.js.map +1 -0
  293. package/dist/improve-plan-annotator.d.ts +13 -2
  294. package/dist/improve-plan-annotator.d.ts.map +1 -1
  295. package/dist/improve-plan-annotator.js +35 -37
  296. package/dist/improve-plan-annotator.js.map +1 -1
  297. package/dist/improve-pricing-plan.d.ts +3 -0
  298. package/dist/improve-pricing-plan.d.ts.map +1 -1
  299. package/dist/improve-pricing-plan.js +33 -5
  300. package/dist/improve-pricing-plan.js.map +1 -1
  301. package/dist/improve-recheck.d.ts +9 -0
  302. package/dist/improve-recheck.d.ts.map +1 -0
  303. package/dist/improve-recheck.js +200 -0
  304. package/dist/improve-recheck.js.map +1 -0
  305. package/dist/improve-reset.d.ts.map +1 -1
  306. package/dist/improve-reset.js +11 -0
  307. package/dist/improve-reset.js.map +1 -1
  308. package/dist/improve-run-summary.d.ts +6 -0
  309. package/dist/improve-run-summary.d.ts.map +1 -1
  310. package/dist/improve-run-summary.js +77 -7
  311. package/dist/improve-run-summary.js.map +1 -1
  312. package/dist/improve-site-plan.d.ts +57 -0
  313. package/dist/improve-site-plan.d.ts.map +1 -0
  314. package/dist/improve-site-plan.js +79 -0
  315. package/dist/improve-site-plan.js.map +1 -0
  316. package/dist/improve-site-shell.d.ts +11 -0
  317. package/dist/improve-site-shell.d.ts.map +1 -0
  318. package/dist/improve-site-shell.js +24 -0
  319. package/dist/improve-site-shell.js.map +1 -0
  320. package/dist/improve-site-stage.d.ts +10 -0
  321. package/dist/improve-site-stage.d.ts.map +1 -0
  322. package/dist/improve-site-stage.js +84 -0
  323. package/dist/improve-site-stage.js.map +1 -0
  324. package/dist/improve-site-tokens.d.ts +9 -0
  325. package/dist/improve-site-tokens.d.ts.map +1 -0
  326. package/dist/improve-site-tokens.js +17 -0
  327. package/dist/improve-site-tokens.js.map +1 -0
  328. package/dist/improve-source-hints.d.ts +3 -12
  329. package/dist/improve-source-hints.d.ts.map +1 -1
  330. package/dist/improve-source-hints.js +4 -5
  331. package/dist/improve-source-hints.js.map +1 -1
  332. package/dist/improve-spend-ledger.d.ts +69 -0
  333. package/dist/improve-spend-ledger.d.ts.map +1 -0
  334. package/dist/improve-spend-ledger.js +118 -0
  335. package/dist/improve-spend-ledger.js.map +1 -0
  336. package/dist/improve-stage-runners.d.ts +5 -2
  337. package/dist/improve-stage-runners.d.ts.map +1 -1
  338. package/dist/improve-stage-runners.js +5 -2
  339. package/dist/improve-stage-runners.js.map +1 -1
  340. package/dist/improve-stage-shared.d.ts +49 -2
  341. package/dist/improve-stage-shared.d.ts.map +1 -1
  342. package/dist/improve-stage-shared.js +80 -3
  343. package/dist/improve-stage-shared.js.map +1 -1
  344. package/dist/improve-stop-handler.d.ts +15 -0
  345. package/dist/improve-stop-handler.d.ts.map +1 -1
  346. package/dist/improve-stop-handler.js +74 -3
  347. package/dist/improve-stop-handler.js.map +1 -1
  348. package/dist/improve-terminal-event.d.ts.map +1 -1
  349. package/dist/improve-terminal-event.js +13 -4
  350. package/dist/improve-terminal-event.js.map +1 -1
  351. package/dist/improve-workspace.d.ts +282 -9
  352. package/dist/improve-workspace.d.ts.map +1 -1
  353. package/dist/improve-workspace.js +250 -78
  354. package/dist/improve-workspace.js.map +1 -1
  355. package/dist/index.d.ts +2 -1
  356. package/dist/index.d.ts.map +1 -1
  357. package/dist/index.js +1 -0
  358. package/dist/index.js.map +1 -1
  359. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  360. package/dist/legacy-skill-catalog.js +202 -0
  361. package/dist/legacy-skill-catalog.js.map +1 -1
  362. package/dist/mcp-convert.js +1 -1
  363. package/dist/mcp-convert.js.map +1 -1
  364. package/dist/redesign-capture.d.ts +146 -15
  365. package/dist/redesign-capture.d.ts.map +1 -1
  366. package/dist/redesign-capture.js +182 -65
  367. package/dist/redesign-capture.js.map +1 -1
  368. package/dist/redesign-workspace.d.ts +13 -0
  369. package/dist/redesign-workspace.d.ts.map +1 -1
  370. package/dist/redesign-workspace.js +14 -0
  371. package/dist/redesign-workspace.js.map +1 -1
  372. package/dist/responsive-alternative-materializer.d.ts +24 -0
  373. package/dist/responsive-alternative-materializer.d.ts.map +1 -0
  374. package/dist/responsive-alternative-materializer.js +93 -0
  375. package/dist/responsive-alternative-materializer.js.map +1 -0
  376. package/dist/result-integrity.d.ts +38 -0
  377. package/dist/result-integrity.d.ts.map +1 -0
  378. package/dist/result-integrity.js +46 -0
  379. package/dist/result-integrity.js.map +1 -0
  380. package/dist/review-edit-source.d.ts.map +1 -1
  381. package/dist/review-edit-source.js +6 -2
  382. package/dist/review-edit-source.js.map +1 -1
  383. package/dist/review-edit.js +2 -2
  384. package/dist/review-edit.js.map +1 -1
  385. package/dist/review-prototype-gap.js +1 -1
  386. package/dist/review-prototype-gap.js.map +1 -1
  387. package/dist/spend-run-filter.d.ts +21 -0
  388. package/dist/spend-run-filter.d.ts.map +1 -0
  389. package/dist/spend-run-filter.js +65 -0
  390. package/dist/spend-run-filter.js.map +1 -0
  391. package/dist/spend-scoped-report-lines.d.ts +4 -0
  392. package/dist/spend-scoped-report-lines.d.ts.map +1 -0
  393. package/dist/spend-scoped-report-lines.js +46 -0
  394. package/dist/spend-scoped-report-lines.js.map +1 -0
  395. package/dist/spend-scoped-report.d.ts +28 -0
  396. package/dist/spend-scoped-report.d.ts.map +1 -0
  397. package/dist/spend-scoped-report.js +45 -0
  398. package/dist/spend-scoped-report.js.map +1 -0
  399. package/open-design.json +2 -2
  400. package/package.json +5 -5
  401. package/skills/12ui-design/SKILL.md +14 -4
  402. package/skills/12ui-design/improve.md +67 -5
  403. package/skills/12ui-design/inspire.md +1 -1
  404. package/dist/improve-dom-anchor.d.ts.map +0 -1
  405. package/dist/improve-dom-anchor.js.map +0 -1
  406. package/dist/improve-dom-extract.d.ts.map +0 -1
  407. package/dist/improve-dom-extract.js.map +0 -1
  408. package/dist/improve-dom-neighbour.d.ts.map +0 -1
  409. package/dist/improve-dom-neighbour.js.map +0 -1
  410. package/dist/improve-dom-scale.d.ts.map +0 -1
  411. package/dist/improve-dom-scale.js.map +0 -1
  412. package/dist/improve-layerdoc-diff.d.ts.map +0 -1
  413. package/dist/improve-layerdoc-diff.js.map +0 -1
  414. package/dist/improve-layerdoc-types.d.ts.map +0 -1
  415. package/dist/improve-layerdoc-types.js +0 -2
  416. package/dist/improve-layerdoc-types.js.map +0 -1
  417. package/dist/improve-plan-annotated-render.d.ts.map +0 -1
  418. package/dist/improve-plan-annotated-render.js.map +0 -1
  419. package/dist/improve-plan-render.d.ts.map +0 -1
  420. package/dist/improve-plan-render.js.map +0 -1
  421. package/dist/improve-raster-layers-section.d.ts.map +0 -1
  422. package/dist/improve-raster-layers-section.js.map +0 -1
  423. package/dist/improve-token-patch.d.ts.map +0 -1
  424. package/dist/improve-token-patch.js.map +0 -1
  425. /package/dist/{improve-dom-anchor.d.ts → improve-core/improve-dom-anchor.d.ts} +0 -0
  426. /package/dist/{improve-dom-extract.d.ts → improve-core/improve-dom-extract.d.ts} +0 -0
  427. /package/dist/{improve-dom-neighbour.d.ts → improve-core/improve-dom-neighbour.d.ts} +0 -0
  428. /package/dist/{improve-dom-scale.d.ts → improve-core/improve-dom-scale.d.ts} +0 -0
  429. /package/dist/{improve-layerdoc-diff.d.ts → improve-core/improve-layerdoc-diff.d.ts} +0 -0
@@ -9,13 +9,13 @@ export declare const CLI_HELP_CONTEXTS: {
9
9
  }];
10
10
  };
11
11
  readonly spend: {
12
- readonly summary: "Report what this account actually settled: per run, per day, and who funded it.";
12
+ readonly summary: "Report settled account spend, or exact durable identities from an improve kit or redesign run.";
13
13
  readonly sections: readonly [{
14
14
  readonly heading: "Reads";
15
15
  readonly items: readonly [string, "Wallet balance and lifetime funding, plus the current daily quota window.", string];
16
16
  }, {
17
17
  readonly heading: "Notes";
18
- readonly items: readonly [string, "Totals cover the whole window even when --limit shortens the run list."];
18
+ readonly items: readonly [string, "Totals cover the whole window even when --limit shortens the run list.", string];
19
19
  }];
20
20
  };
21
21
  readonly mcp: {
@@ -70,7 +70,7 @@ export declare const CLI_HELP_CONTEXTS: {
70
70
  readonly summary: "Search the Design Corpus and download validated visual references.";
71
71
  readonly sections: readonly [{
72
72
  readonly heading: "Behavior";
73
- readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48.", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
73
+ readonly items: readonly ["Runs in the foreground and writes an attempt record before the metered search, then a manifest, evidence, receipts, and downloaded references.", "Defaults to four references in balanced mode; --count accepts 1–48 in every mode.", "--reference-image conditions retrieval on an existing PNG, JPEG, or WebP."];
74
74
  }, {
75
75
  readonly heading: "Modes";
76
76
  readonly items: readonly ["direct stays closest to the literal query.", "balanced is the default relevance, quality, and variety trade-off.", "adventurer keeps a relevant head while exploring less expected directions."];
@@ -90,7 +90,7 @@ export declare const CLI_HELP_CONTEXTS: {
90
90
  readonly items: readonly ["Creates a resumable temporary run directory, prints it first, retrieves a balanced corpus set, and claims one hosted /api/v1/create run.", "--candidates accepts 2–16 and defaults to four; prefer at least four distinct directions.", "Every service dispatch request stays in the foreground. The command returns after no slot remains pending; generation stays server-side.", "Run `12ui next <run-dir> --wait` to poll, repair only recorded slots that never started, and download real PNGs into <run-dir>/candidates/.", "Defaults to landscape. Authentication is 12ui-only; no Codex session or caller-side image-provider key is read."];
91
91
  }, {
92
92
  readonly heading: "Redesign modes";
93
- readonly items: readonly ["Without --reference, creates a new interface and pairs one corpus reference with each candidate.", "--reference accepts a local path or HTTP(S) URL, conditions corpus retrieval, and sends those original bytes to every candidate.", "A reference retains style by default while excluding layout, content, and assets. --retain accepts comma-separated values; layout is the explicit structure-preserving opt-in.", "--redesign-source remains an alias for local redesign workflows. --mode reskin is the layout-retain shorthand."];
93
+ readonly items: readonly ["Without --reference, creates a new interface and pairs one corpus reference with each candidate.", "--reference accepts a local path or HTTP(S) URL, conditions corpus retrieval, and sends those original bytes to every candidate.", "A reference retains style by default while excluding layout, content, and assets. --retain accepts comma-separated values; layout is the explicit structure-preserving opt-in.", "--retain-source says what the reference IS. inspiration (the default) is a design you like, so an exclusion is a prohibition: do not reuse its words or its logo. subject is your own page, so the same exclusion is a licence: its words may be rewritten, its brand may be replaced. `12ui improve` sends subject. Against a subject, at least one of layout, copy, brand, and style must be left free to change: keeping all four asks for the page back unchanged and is refused.", "--redesign-source remains an alias for local redesign workflows. --mode reskin is the layout-retain shorthand."];
94
94
  }, {
95
95
  readonly heading: "Next";
96
96
  readonly items: readonly ["Run `12ui next <run-dir>` to follow generation. Convert one chosen image, or pass it to `12ui branch execute --start`."];
@@ -141,10 +141,13 @@ export declare const CLI_HELP_CONTEXTS: {
141
141
  }];
142
142
  };
143
143
  readonly improve: {
144
- readonly summary: "Improve one live interface or screenshot and produce a replayable implementation kit.";
144
+ readonly summary: "Improve one live interface, site, or screenshot and produce a replayable implementation kit.";
145
145
  readonly sections: readonly [{
146
146
  readonly heading: "Behavior";
147
- readonly items: readonly ["Five stages run in order: local capture, hosted draft candidates retaining layout and content, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "The pick is explicit and has no default. With no --pick and no pick already recorded, the run stops after the draw, prints where the candidates are and the exact command that continues (--from pick --pick <slot>), and buys no conversion: converting a candidate nobody chose spends money on a guess that cannot be cancelled. --target supplies the design instead and skips draft and pick.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", string, "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails or reaches the improve deadline after LayerDoc materialization, improve derives fixed HTML free and continues to plan with a warning.", "--convert-stall-seconds bounds every hosted wait the convert stage makes, including the free fixed-layout derivation (default: twice the model's typical wall, 480s standard and pro, 300s fast; refused below one typical wall). If a wait ends with no LayerDoc on disk there is nothing to derive, so improve records the abandoned conversion and dispatches exactly ONE fresh one; a second stall writes plan/STALL.md and exits non-zero. The retry budget belongs to the kit: a resume re-attaches to the newest conversion already bought, a kit that has spent its retry refuses to dispatch again, and a pro conversion is never retried automatically because no measured wall justifies it. Stopping the wait does not stop the conversion: there is no cancel, so an abandoned run keeps billing.", "--fresh re-buys ONE conversion of the same settled winner under a new idempotency key: it records the abandoned conversion identity and reuses capture, draft and pick untouched. --redraw is the one that buys new candidates — it discards draft, pick, convert and plan, moves the old draw to candidates.previous, records any conversion it drops, and runs the draft stage again; it is also the one path allowed to change --direction, --candidates or --retain against the record. A temporarily unavailable stage retries once after 30 seconds.", "--target brings your own design image or LayerDoc, skips draft and pick, converts an image when needed, and aligns the plan to the captured URL DOM."];
147
+ readonly items: readonly ["Page scope runs five stages in order: local capture, hosted draft candidates, explicit pick, fused LayerDoc and responsive HTML conversion, then a local implementation plan.", "The pick is explicit and has no default. With no --pick and no pick already recorded, the run stops after the draw, prints where the candidates are and the exact command that continues (--from pick --pick <slot>), and buys no conversion: converting a candidate nobody chose spends money on a guess that cannot be cancelled. --target supplies the design instead and skips draft and pick.", "--retain says what to hold from the live page, in the four-facet vocabulary: layout, content, assets, style. It defaults to assets,content — keep the product's brand and words, rework its layout and visual system. Add layout to hold the geometry, add style to work inside the existing visual language, drop assets to let the brand be replaced. The /improve page exposes the same four as Keep layout, Keep copy, Keep brand, and Keep style. At least one of the four must be left free to change: keeping all four asks for the page back unchanged and is refused before anything is bought.", "Whatever is retained, no setting licenses inventing a product fact: with content held the page says the same things; with content freed the words may be rewritten but every claim, number, offer, and control must still be present and true.", "URL input uses one Playwright context for repeated --bootstrap actions, screenshot capture, and selector-verified DOM extraction. Image input normalizes the source locally.", string, "The kit keeps every candidate, winner, target, plan, assets, and improve.json replay record. Repeating a settled stage reuses it; --from pick --pick <slot> invalidates only the old target and plan.", "--responsive-quality selects standard or pro responsive export. If that export fails, is absent, or reaches the improve deadline after LayerDoc materialization, improve continues to plan with a warning and derives fixed HTML free when possible.", "--convert-stall-seconds is a no-progress bound for every hosted convert wait, including the free fixed-layout derivation (default: 960s standard and pro, 300s fast; refused below one typical wall). A newly polled live stage or active lane resets it, so healthy tall work stays attached to its original purchase and no second conversion is dispatched. A true no-progress stall with no LayerDoc writes plan/STALL.md and exits non-zero with free re-attachment commands. With a LayerDoc, improve derives fixed HTML for the plan and plan/STALL.md gives the free resume command that later collects responsive winner.html without changing that plan basis. Stopping the wait does not stop the conversion: there is no cancel, so an open run keeps billing.", "--fresh re-buys ONE conversion of the same settled winner under a new idempotency key: it records the abandoned conversion identity and reuses capture, draft and pick untouched. --redraw is the one that buys new candidates — it discards draft, pick, convert and plan, moves the old draw to candidates.previous, records any conversion it drops, and runs the draft stage again; it is also the one path allowed to change --direction, --candidates or --retain against the record. A temporarily unavailable stage retries once after 30 seconds.", "--target brings your own design image or LayerDoc, skips draft and pick, converts an image when needed, and aligns the plan to the captured URL DOM."];
148
+ }, {
149
+ readonly heading: "Whole-site polish";
150
+ readonly items: readonly ["--scope site captures 2–8 same-origin pages including the root, then runs capture, draft, pick, branch, convert, plan, and site. The accepted root is the visual system; each current non-root page is edited against it.", "Root and page conversions share one resilience policy: an unavailable responsive export never discards its LayerDoc or blocks that page plan, and the site kit records fixed-layout or LayerDoc-only delivery honestly.", "--pages caps free one-hop discovery including the root (default 5); repeat --page to supply explicit same-origin pages instead. --page-concurrency defaults to 3, and --reference-order defaults to current-first.", "The site roll-up writes site-plan/tokens.css, shared-shell.md, pages.md, and APPLY.md. It deduplicates tokens and shared shell changes so the implementation plan applies them once before per-page residue.", "Apply APPLY.md, then run `12ui improve <url> --scope site --out-dir <kit> --recheck`. It captures the root and every page once in one browser context, writes numbered recheck evidence, and replans only against kept targets without replaying settled stages. The command never applies code."];
148
151
  }, {
149
152
  readonly heading: "Planning";
150
153
  readonly items: readonly ["URL plans require at least 60% plausible DOM-side coverage; a blocked gate writes GATE.md while target HTML and LayerDoc remain authoritative sidecars.", "Image plans are target-only by default. --plan-source-convert buys one source LayerDoc conversion for an unanchored LayerDoc comparison.", "--repo adds evidence-ranked src/ TSX, JSX, and CSS file hints to a URL plan. The command never applies code.", "--dry-run prints exact catalog price ceilings for every stage and makes no network request."];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli-help/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKK,CAAC;AAIpC,eAAO,MAAM,aAAa,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAUzE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,SAAS,MAAM,EAAE,KACzB,cAAc,GAAG,SAenB,CAAC;AAEF,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli-help/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAKK,CAAC;AAIpC,eAAO,MAAM,aAAa,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,MAAM,EAUzE,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GACzB,SAAS,SAAS,MAAM,EAAE,KACzB,cAAc,GAAG,SAenB,CAAC;AAEF,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC"}
@@ -7,13 +7,13 @@ export declare const META_HELP: {
7
7
  }];
8
8
  };
9
9
  readonly spend: {
10
- readonly summary: "Report what this account actually settled: per run, per day, and who funded it.";
10
+ readonly summary: "Report settled account spend, or exact durable identities from an improve kit or redesign run.";
11
11
  readonly sections: readonly [{
12
12
  readonly heading: "Reads";
13
13
  readonly items: readonly [string, "Wallet balance and lifetime funding, plus the current daily quota window.", string];
14
14
  }, {
15
15
  readonly heading: "Notes";
16
- readonly items: readonly [string, "Totals cover the whole window even when --limit shortens the run list."];
16
+ readonly items: readonly [string, "Totals cover the whole window even when --limit shortens the run list.", string];
17
17
  }];
18
18
  };
19
19
  readonly mcp: {
@@ -1 +1 @@
1
- {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/cli-help/meta.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDa,CAAC"}
1
+ {"version":3,"file":"meta.d.ts","sourceRoot":"","sources":["../../src/cli-help/meta.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDa,CAAC"}
@@ -10,7 +10,7 @@ export const META_HELP = {
10
10
  }],
11
11
  },
12
12
  spend: {
13
- summary: 'Report what this account actually settled: per run, per day, and who funded it.',
13
+ summary: 'Report settled account spend, or exact durable identities from an improve kit or redesign run.',
14
14
  sections: [{
15
15
  heading: 'Reads',
16
16
  items: [
@@ -26,6 +26,9 @@ export const META_HELP = {
26
26
  'Read-only, free, and account-scoped; it can only report the account its own credential'
27
27
  + ' proves.',
28
28
  'Totals cover the whole window even when --limit shortens the run list.',
29
+ '--run-dir reads durable improve.json or redesign.json identities, writes spend.json beside it,'
30
+ + ' and filters the returned account window locally. It names the searched window and truncation state'
31
+ + ' instead of treating unreturned rows as absent. --conversion and --run add exact identities directly.',
29
32
  ],
30
33
  }],
31
34
  },
@@ -1 +1 @@
1
- {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/cli-help/meta.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,YAAY,EAAE;QACZ,OAAO,EAAE,8DAA8D;QACvE,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,UAAU;gBACnB,KAAK,EAAE;oBACL,2IAA2I;oBAC3I,sGAAsG;iBACvG;aACF,CAAC;KACH;IACD,KAAK,EAAE;QACL,OAAO,EAAE,iFAAiF;QAC1F,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE;oBACL,wFAAwF;0BACtF,kEAAkE;oBACpE,2EAA2E;oBAC3E,0FAA0F;0BACxF,eAAe;iBAClB;aACF,EAAE;gBACD,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE;oBACL,wFAAwF;0BACtF,UAAU;oBACZ,wEAAwE;iBACzE;aACF,CAAC;KACH;IACD,GAAG,EAAE;QACH,OAAO,EAAE,qEAAqE;QAC9E,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,UAAU;gBACnB,KAAK,EAAE;oBACL,qFAAqF;oBACrF,iHAAiH;iBAClH;aACF,CAAC;KACH;IACD,OAAO,EAAE;QACP,OAAO,EAAE,2CAA2C;QACpD,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,CAAC,mGAAmG,CAAC;aAC7G,CAAC;KACH;CACgC,CAAC"}
1
+ {"version":3,"file":"meta.js","sourceRoot":"","sources":["../../src/cli-help/meta.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,YAAY,EAAE;QACZ,OAAO,EAAE,8DAA8D;QACvE,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,UAAU;gBACnB,KAAK,EAAE;oBACL,2IAA2I;oBAC3I,sGAAsG;iBACvG;aACF,CAAC;KACH;IACD,KAAK,EAAE;QACL,OAAO,EAAE,gGAAgG;QACzG,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE;oBACL,wFAAwF;0BACtF,kEAAkE;oBACpE,2EAA2E;oBAC3E,0FAA0F;0BACxF,eAAe;iBAClB;aACF,EAAE;gBACD,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE;oBACL,wFAAwF;0BACtF,UAAU;oBACZ,wEAAwE;oBACxE,gGAAgG;0BAC9F,qGAAqG;0BACrG,uGAAuG;iBAC1G;aACF,CAAC;KACH;IACD,GAAG,EAAE;QACH,OAAO,EAAE,qEAAqE;QAC9E,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,UAAU;gBACnB,KAAK,EAAE;oBACL,qFAAqF;oBACrF,iHAAiH;iBAClH;aACF,CAAC;KACH;IACD,OAAO,EAAE;QACP,OAAO,EAAE,2CAA2C;QACpD,QAAQ,EAAE,CAAC;gBACT,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,CAAC,mGAAmG,CAAC;aAC7G,CAAC;KACH;CACgC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cli-improve-command.d.ts","sourceRoot":"","sources":["../src/cli-improve-command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAenD,OAAO,EAQL,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,wBAAwB,CAAC;AA2FhC,eAAO,MAAM,iBAAiB,GAC5B,SAAS,SAAS,MAAM,EAAE,EAC1B,OAAO,QAAQ,EACf,eAAc,0BAA+B,KAC5C,OAAO,CAAC,aAAa,CA4SvB,CAAC"}
1
+ {"version":3,"file":"cli-improve-command.d.ts","sourceRoot":"","sources":["../src/cli-improve-command.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAiCnD,OAAO,EAaL,KAAK,0BAA0B,EAChC,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAKL,KAAK,aAAa,EAGnB,MAAM,wBAAwB,CAAC;AA8MhC,eAAO,MAAM,iBAAiB,GAC5B,SAAS,SAAS,MAAM,EAAE,EAC1B,OAAO,QAAQ,EACf,eAAc,0BAA+B,KAC5C,OAAO,CAAC,aAAa,CAgbvB,CAAC"}
@@ -5,14 +5,22 @@ import { CliRefusal } from './cli-refusal.js';
5
5
  import { prepareOutputDirectory } from './cli-output-paths.js';
6
6
  import { parseImproveOptions } from './improve-options.js';
7
7
  import { buildImprovePricingPlan } from './improve-pricing-plan.js';
8
+ import { assertImproveCaptureNotRedirected } from './improve-capture-redirect.js';
9
+ import { improveBootstrapRecordFields, redactImproveBootstrap, } from './improve-bootstrap-secret.js';
10
+ import { hasImprovePaidStage, improveBootstrapChanged, rebootstrapImproveRecord, } from './improve-bootstrap-history.js';
8
11
  import { improveStalled, retryImproveTemporarilyUnavailable } from './improve-convert-resilience.js';
9
- import { writeImproveStallReport } from './improve-kit-stall.js';
12
+ import { ensureImproveKitIgnored } from './improve-kit-ignore.js';
13
+ import { resolveImproveStall, writeImproveFallbackStall, writeImproveStallReport, } from './improve-kit-stall.js';
14
+ import { readImproveKitStatus } from './improve-kit-status.js';
10
15
  import { resetImproveDraw } from './improve-reset.js';
11
16
  import { awaitingImprovePick, buildImproveRunSummary, improveStallErrorWithSummary, } from './improve-run-summary.js';
17
+ import { readImproveSpendLedger } from './improve-spend-ledger.js';
18
+ import { markImproveStageStalled } from './improve-stage-shared.js';
12
19
  import { registerImproveStopHandler } from './improve-stop-handler.js';
13
20
  import { noteImproveTerminalEvent } from './improve-terminal-event.js';
14
- import { runImproveCaptureStage, runImproveConvertStage, runImproveDraftStage, markImproveStageSkipped, runImprovePickStage, runImprovePlanStage, writeImproveReadme, } from './improve-stage-runners.js';
15
- import { IMPROVE_STAGES, readImproveRecord, writeImproveRecord, } from './improve-workspace.js';
21
+ import { runImproveCaptureStage, runImproveConvertStage, runImproveSiteConvertStage, runImproveBranchStage, runImproveDraftStage, markImproveStageSkipped, runImprovePickStage, runImprovePlanStage, runImproveSiteRecheck, runImproveSitePlanPagesStage, runImproveSiteStage, writeImproveReadme, } from './improve-stage-runners.js';
22
+ import { discoverRedesignPageUrls, pageId } from './redesign-capture.js';
23
+ import { IMPROVE_STAGES, IMPROVE_SITE_ROOT_ID, readImproveRecord, writeImproveRecord, } from './improve-workspace.js';
16
24
  /**
17
25
  * `12ui improve`: one replay-aware local orchestrator over existing draft and
18
26
  * convert commands, redesign's Playwright provisioning, and the local plan
@@ -48,6 +56,7 @@ const assertCompatibleRecord = async (args) => {
48
56
  // match: a redraw does not license a different model or a different page.
49
57
  const drawFlags = new Set(args.parsed.redraw ? ['direction', 'candidates', 'retain'] : []);
50
58
  const explicitChecks = [
59
+ ['scope', args.record.scope, args.parsed.scope],
51
60
  ['direction', args.record.direction, args.parsed.direction],
52
61
  ['candidates', args.record.candidates, args.parsed.candidates],
53
62
  ['retain', args.record.retain, args.parsed.retain],
@@ -55,11 +64,19 @@ const assertCompatibleRecord = async (args) => {
55
64
  ['responsive-quality', args.record.responsiveQuality, args.parsed.responsiveQuality],
56
65
  ['viewport', args.record.viewport, args.parsed.viewport],
57
66
  ['full-page', args.record.fullPage, args.parsed.fullPage],
58
- ['bootstrap', args.record.bootstrap, args.parsed.bootstrapValues],
59
67
  ['repo', args.record.repo, args.parsed.repo],
60
68
  ['plan-source-convert', args.record.planSourceConvert, args.parsed.planSourceConvert],
69
+ ['pages', args.record.pageLimit, args.parsed.pages],
70
+ ['page', args.record.requestedPages, args.parsed.explicitPages],
71
+ ['page-concurrency', args.record.pageConcurrency, args.parsed.pageConcurrency],
72
+ ['reference-order', args.record.referenceOrder, args.parsed.referenceOrder],
61
73
  ['target', args.record.target && { kind: args.record.target.kind, value: args.record.target.value }, args.parsed.target],
62
74
  ];
75
+ // `--bootstrap` compares by digest, because the record deliberately holds no
76
+ // live value to compare against (F31), and neither side of the refusal may
77
+ // print the secret.
78
+ const bootstrapChanged = args.flags.bootstrap !== undefined
79
+ && improveBootstrapChanged(args.record, args.parsed.bootstrapValues);
63
80
  for (const [flag, recorded, requested] of explicitChecks) {
64
81
  if (drawFlags.has(flag))
65
82
  continue;
@@ -83,10 +100,100 @@ const assertCompatibleRecord = async (args) => {
83
100
  throw new CliRefusal('The --target bytes changed. Start a new improve directory.', 'improve_target_changed');
84
101
  }
85
102
  }
103
+ if (!bootstrapChanged)
104
+ return args.record;
105
+ if (hasImprovePaidStage(args.record)) {
106
+ throw new CliRefusal('--bootstrap does not match the durable improve record.'
107
+ + ` The record holds ${describeRecordedValue(args.record.bootstrap)}`
108
+ + ' (query values redacted; the live value is never stored);'
109
+ + ` this run asked for ${describeRecordedValue(args.parsed.bootstrapValues.map(redactImproveBootstrap))}.`
110
+ + ' Paid work has already been dispatched from this capture, so improve cannot replace it in place.'
111
+ + ' Drop --bootstrap to replay the captured page and its purchased work, or start a new kit with'
112
+ + ' a new --out-dir before using the changed bootstrap.', 'improve_record_mismatch');
113
+ }
114
+ return rebootstrapImproveRecord({
115
+ record: args.record,
116
+ bootstrapValues: args.parsed.bootstrapValues,
117
+ });
86
118
  };
87
119
  const missingStage = (stage, runDir) => {
88
120
  throw new CliRefusal(`Stage ${stage} has not settled in ${runDir}. Include it in the stage range first.`, `improve_${stage}_missing`);
89
121
  };
122
+ const uniquePageUrls = (root, candidates) => {
123
+ const urls = [];
124
+ const seen = new Set();
125
+ for (const candidate of [root, ...candidates]) {
126
+ const url = new URL(candidate, root);
127
+ url.hash = '';
128
+ const key = `${url.origin}${url.pathname}`;
129
+ if (seen.has(key))
130
+ continue;
131
+ seen.add(key);
132
+ urls.push(url.toString());
133
+ }
134
+ return urls;
135
+ };
136
+ const titleForPage = (url, id) => {
137
+ if (new URL(url).pathname === '/')
138
+ return 'Home';
139
+ return id.split('-').filter(Boolean)
140
+ .map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`)
141
+ .join(' ') || 'Page';
142
+ };
143
+ const sitePages = async (args) => {
144
+ if (args.parsed.scope === 'page')
145
+ return { rootUrl: args.parsed.input.value, pages: [] };
146
+ if (args.prior?.scope === 'site' && args.prior.pages.length > 0) {
147
+ return { rootUrl: args.prior.input.value, pages: args.prior.pages };
148
+ }
149
+ const candidates = args.parsed.explicitPages.length > 0
150
+ ? args.parsed.explicitPages
151
+ : await (args.dependencies.discoverPages ?? discoverRedesignPageUrls)({
152
+ url: args.parsed.input.value,
153
+ maxPages: args.parsed.pages,
154
+ });
155
+ // The root is represented by the top-level ImproveRecord fields. `pages`
156
+ // deliberately contains only branchable non-root routes, while the cap and
157
+ // validation below still count the root.
158
+ // Discovery's first URL is the root it actually fetched. Keeping the raw
159
+ // input ahead of it made redirecting sites capture the same root twice:
160
+ // `hubspot.com/` and `www.hubspot.com/` differ by origin, so the normal
161
+ // same-origin dedupe quite correctly could not join them. Explicit pages
162
+ // remain rooted at the requested URL; they did not perform discovery.
163
+ const discovered = uniquePageUrls(args.parsed.explicitPages.length > 0 ? args.parsed.input.value : (candidates[0] ?? args.parsed.input.value), candidates);
164
+ const urls = args.parsed.explicitPages.length > 0
165
+ ? discovered
166
+ : args.parsed.dryRun
167
+ ? discovered.slice(0, args.parsed.pages)
168
+ // Paid capture has one browser context anyway. Reserve local output
169
+ // slots through the requested cap, then let that rendered root replace
170
+ // this fetched inventory before it captures anything. This is what lets
171
+ // an SPA whose fetched shell names only `/` reach free DOM discovery;
172
+ // its placeholder is never navigated or persisted after capture.
173
+ : Array.from({ length: args.parsed.pages }, (_, index) => (discovered[index] ?? new URL(`/__12ui-discovery-slot-${index}`, discovered[0] ?? args.parsed.input.value).toString()));
174
+ if (urls.length < 2 || urls.length > 8) {
175
+ throw new CliRefusal(`--scope site requires 2–8 same-origin pages including the root; found ${urls.length}`, 'improve_pages_invalid');
176
+ }
177
+ const used = new Set();
178
+ return {
179
+ rootUrl: urls[0] ?? args.parsed.input.value,
180
+ pages: urls.slice(1).map((url, index) => {
181
+ let id = pageId(url, index + 1).slice(0, 64);
182
+ while (used.has(id)) {
183
+ const suffix = `-${index + 1}`;
184
+ id = `${id.slice(0, 64 - suffix.length)}${suffix}`;
185
+ }
186
+ used.add(id);
187
+ const parsedUrl = new URL(url);
188
+ return {
189
+ id,
190
+ url,
191
+ title: titleForPage(url, id),
192
+ route: `${parsedUrl.pathname}${parsedUrl.search}`,
193
+ };
194
+ }),
195
+ };
196
+ };
90
197
  export const runImproveCommand = async (command, flags, dependencies = {}) => {
91
198
  const parsed = parseImproveOptions({
92
199
  command,
@@ -94,11 +201,30 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
94
201
  ...(dependencies.workspaceRoot ? { workspaceRoot: dependencies.workspaceRoot } : {}),
95
202
  });
96
203
  const prior = parsed.dryRun ? undefined : await readImproveRecord(parsed.paths.record);
204
+ if (parsed.recheck) {
205
+ if (!prior || prior.scope !== 'site'
206
+ || prior.stages.site?.outcome !== 'settled' || !prior.site) {
207
+ throw new CliRefusal('--recheck requires a settled --scope site kit', 'improve_recheck_invalid');
208
+ }
209
+ await assertCompatibleRecord({ record: prior, parsed, flags });
210
+ await prepareOutputDirectory(parsed.paths.runDir);
211
+ const write = dependencies.write ?? ((line) => { process.stdout.write(`${line}\n`); });
212
+ write(parsed.paths.runDir);
213
+ dependencies.onRunDirectory?.(parsed.paths.runDir);
214
+ const record = await runImproveSiteRecheck({ record: prior, options: parsed, dependencies });
215
+ dependencies.journal?.note({ workspace: parsed.paths.runDir, writes: [parsed.paths.record] });
216
+ console.log(JSON.stringify({ recheck: record.rechecks?.at(-1), ...record }, null, 2));
217
+ return record;
218
+ }
219
+ const siteDiscovery = await sitePages({ parsed, prior, dependencies });
220
+ const pages = siteDiscovery.pages;
97
221
  const pricing = buildImprovePricingPlan({
98
222
  inputKind: parsed.input.kind,
99
223
  candidates: parsed.candidates,
100
224
  conversionModel: parsed.conversionModel,
101
225
  planSourceConvert: parsed.planSourceConvert,
226
+ scope: parsed.scope,
227
+ pages: parsed.scope === 'site' ? pages.length + 1 : 0,
102
228
  ...((parsed.target ?? prior?.target) ? { targetKind: (parsed.target ?? prior.target).kind } : {}),
103
229
  });
104
230
  const price = new Map(pricing.stages.map((stage) => [stage.stage, stage.priceCeilingUsd]));
@@ -114,10 +240,17 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
114
240
  conversionModel: parsed.conversionModel,
115
241
  responsiveQuality: parsed.responsiveQuality,
116
242
  ...pricing,
117
- note: 'Nothing was captured, read from the network, claimed, dispatched, or bought.',
243
+ scope: parsed.scope,
244
+ pages: parsed.scope === 'site'
245
+ ? [{ id: IMPROVE_SITE_ROOT_ID, url: siteDiscovery.rootUrl }, ...pages.map((page) => ({ id: page.id, url: page.url }))]
246
+ : [],
247
+ note: parsed.scope === 'site' && parsed.explicitPages.length === 0
248
+ ? 'Discovery fetched only the root HTML. Nothing was captured in a browser, claimed, dispatched, or bought.'
249
+ : 'Nothing was captured in a browser, claimed, dispatched, or bought.',
118
250
  }, null, 2));
119
251
  return {
120
- version: 1,
252
+ version: 2,
253
+ scope: parsed.scope,
121
254
  createdAt: new Date().toISOString(),
122
255
  runDir: '',
123
256
  input: parsed.input,
@@ -130,20 +263,28 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
130
263
  responsiveQuality: parsed.responsiveQuality,
131
264
  viewport: parsed.viewport,
132
265
  fullPage: parsed.fullPage,
133
- bootstrap: parsed.bootstrapValues,
266
+ ...improveBootstrapRecordFields(parsed.bootstrapValues),
134
267
  ...(parsed.repo ? { repo: parsed.repo } : {}),
135
268
  planSourceConvert: parsed.planSourceConvert,
269
+ pageLimit: parsed.pages,
270
+ requestedPages: parsed.explicitPages,
271
+ pageConcurrency: parsed.pageConcurrency,
272
+ referenceOrder: parsed.referenceOrder,
273
+ pages,
136
274
  stages: {},
137
275
  };
138
276
  }
139
277
  await prepareOutputDirectory(parsed.paths.runDir);
140
278
  const existing = prior;
141
- if (existing)
142
- await assertCompatibleRecord({ record: existing, parsed, flags });
143
- else if (parsed.from !== 'capture')
279
+ const compatible = existing
280
+ ? await assertCompatibleRecord({ record: existing, parsed, flags })
281
+ : undefined;
282
+ const rebootstrap = compatible !== undefined && compatible !== existing;
283
+ if (!existing && parsed.from !== 'capture')
144
284
  missingStage('capture', parsed.paths.runDir);
145
- let record = existing ?? {
146
- version: 1,
285
+ let record = compatible ?? {
286
+ version: 2,
287
+ scope: parsed.scope,
147
288
  createdAt: new Date().toISOString(),
148
289
  runDir: parsed.paths.runDir,
149
290
  input: parsed.input,
@@ -157,11 +298,21 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
157
298
  responsiveQuality: parsed.responsiveQuality,
158
299
  viewport: parsed.viewport,
159
300
  fullPage: parsed.fullPage,
160
- bootstrap: parsed.bootstrapValues,
301
+ ...improveBootstrapRecordFields(parsed.bootstrapValues),
161
302
  ...(parsed.repo ? { repo: parsed.repo } : {}),
162
303
  planSourceConvert: parsed.planSourceConvert,
304
+ pageLimit: parsed.pages,
305
+ requestedPages: parsed.explicitPages,
306
+ pageConcurrency: parsed.pageConcurrency,
307
+ referenceOrder: parsed.referenceOrder,
308
+ pages,
163
309
  stages: {},
164
310
  };
311
+ // A kit written inside the repository it improves is ~100 MB of paid
312
+ // artifacts one `git add -A` away from someone's history (F17). Decided every
313
+ // run, because the repository's own `.gitignore` can change between them.
314
+ const kitIgnore = await ensureImproveKitIgnored({ outDir: parsed.paths.runDir });
315
+ record = { ...record, ...(kitIgnore ? { kitIgnore } : {}) };
165
316
  await writeImproveRecord(parsed.paths.record, record);
166
317
  const write = dependencies.write ?? ((line) => { process.stdout.write(`${line}\n`); });
167
318
  write(parsed.paths.runDir);
@@ -178,6 +329,8 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
178
329
  // apart from a signal after completion. The record cannot: `--fresh` clears
179
330
  // convert and plan from the durable record inside the convert stage, and
180
331
  // `record` here is only reassigned when that stage returns.
332
+ const extendedPageRange = record.scope === 'site'
333
+ || [flags.from, flags.to].some((value) => value === 'branch' || value === 'site');
181
334
  let liveStage;
182
335
  const runStage = async (stage, action) => {
183
336
  liveStage = stage;
@@ -201,8 +354,14 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
201
354
  // lane was KILLED, not stalled, so it threw nothing the catch below could
202
355
  // have seen. The handler is armed here, before the first stage, because a
203
356
  // kill during capture, draft or pick used to leave nothing at all.
357
+ // A signal wrote this kit's `plan/STALL.md` during this very invocation, so
358
+ // nothing later in it may resolve that file away: in production the handler
359
+ // exits the process, and a harness that lets the stage unwind must not answer
360
+ // the signal by declaring the run fine (F21).
361
+ let stopped = false;
204
362
  const disarmStop = registerImproveStopHandler({
205
363
  getRecord: () => record,
364
+ onStopped: () => { stopped = true; },
206
365
  getLiveStage: () => liveStage,
207
366
  write,
208
367
  requestedTo: parsed.to,
@@ -249,13 +408,20 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
249
408
  }
250
409
  }
251
410
  if (needed('capture')) {
252
- if (within('capture'))
411
+ if (within('capture') || rebootstrap)
253
412
  record = await runStage('capture', () => runImproveCaptureStage({
254
413
  record, options: parsed, dependencies, price: price.get('capture') ?? 0,
255
414
  }));
256
415
  if (!record.capture)
257
416
  missingStage('capture', parsed.paths.runDir);
258
417
  await refreshReadme();
418
+ // Free, deterministic, and BEFORE the draft purchase: the captured page
419
+ // and the requested one have to be the same page, or nothing is bought
420
+ // (F27). The capture and the README above are already on disk, so the
421
+ // refusal costs a reader nothing and the next run replays them.
422
+ assertImproveCaptureNotRedirected({
423
+ record, allowRedirect: parsed.allowRedirect, runDir: parsed.paths.runDir,
424
+ });
259
425
  }
260
426
  if (needed('draft')) {
261
427
  if (record.target) {
@@ -264,7 +430,7 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
264
430
  else {
265
431
  if (within('draft'))
266
432
  record = await runStage('draft', () => runImproveDraftStage({
267
- record, options: parsed, flags, dependencies, price: price.get('draft') ?? 0,
433
+ record, options: parsed, dependencies, price: price.get('draft') ?? 0,
268
434
  }));
269
435
  if (!record.draft)
270
436
  missingStage('draft', parsed.paths.runDir);
@@ -290,7 +456,13 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
290
456
  // rather than quietly stopping where it was told not to.
291
457
  if (!chosen) {
292
458
  await refreshReadme();
293
- write(awaitingImprovePick({ record, options: parsed }));
459
+ write(awaitingImprovePick({
460
+ record,
461
+ options: parsed,
462
+ // The draw is paid work and this is a stop, so the ids leave with
463
+ // the reader (F33).
464
+ ledger: await readImproveSpendLedger(record),
465
+ }));
294
466
  dependencies.journal?.note({
295
467
  workspace: parsed.paths.runDir,
296
468
  artifacts: [parsed.paths.record, parsed.paths.readme],
@@ -309,28 +481,68 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
309
481
  }
310
482
  await refreshReadme();
311
483
  }
484
+ if (needed('branch')) {
485
+ if (record.scope === 'page') {
486
+ if (extendedPageRange)
487
+ record = await markImproveStageSkipped(record, 'branch');
488
+ }
489
+ else {
490
+ if (within('branch'))
491
+ record = await runStage('branch', () => runImproveBranchStage({
492
+ record, options: parsed, dependencies, price: price.get('branch') ?? 0,
493
+ }));
494
+ if (!record.branch)
495
+ missingStage('branch', parsed.paths.runDir);
496
+ }
497
+ await refreshReadme();
498
+ }
312
499
  try {
313
500
  if (needed('convert')) {
314
501
  if (within('convert'))
315
- record = await runStage('convert', () => runImproveConvertStage({
316
- record,
317
- options: parsed,
318
- dependencies,
319
- price: price.get('convert') ?? 0,
320
- ...(freshConversionNonce ? { freshConversionNonce } : {}),
321
- }));
502
+ record = await runStage('convert', () => (record.scope === 'site'
503
+ ? runImproveSiteConvertStage({
504
+ record,
505
+ options: parsed,
506
+ dependencies,
507
+ price: price.get('convert') ?? 0,
508
+ ...(freshConversionNonce ? { freshConversionNonce } : {}),
509
+ })
510
+ : runImproveConvertStage({
511
+ record,
512
+ options: parsed,
513
+ dependencies,
514
+ price: price.get('convert') ?? 0,
515
+ ...(freshConversionNonce ? { freshConversionNonce } : {}),
516
+ })));
322
517
  if (!record.convert)
323
518
  missingStage('convert', parsed.paths.runDir);
324
519
  await refreshReadme();
325
520
  }
326
521
  if (needed('plan')) {
327
522
  if (within('plan'))
328
- record = await runStage('plan', () => runImprovePlanStage({
329
- record, options: parsed, dependencies, price: price.get('plan') ?? 0,
330
- }));
523
+ record = await runStage('plan', () => (record.scope === 'site'
524
+ ? runImproveSitePlanPagesStage({
525
+ record, options: parsed, dependencies, price: price.get('plan') ?? 0,
526
+ })
527
+ : runImprovePlanStage({
528
+ record, options: parsed, dependencies, price: price.get('plan') ?? 0,
529
+ })));
331
530
  if (!record.plan)
332
531
  missingStage('plan', parsed.paths.runDir);
333
532
  }
533
+ if (needed('site')) {
534
+ if (record.scope === 'page') {
535
+ record = await markImproveStageSkipped(record, 'site');
536
+ }
537
+ else {
538
+ if (within('site'))
539
+ record = await runStage('site', () => runImproveSiteStage({
540
+ record, options: parsed, dependencies, price: price.get('site') ?? 0,
541
+ }));
542
+ if (!record.site)
543
+ missingStage('site', parsed.paths.runDir);
544
+ }
545
+ }
334
546
  }
335
547
  catch (error) {
336
548
  // The durable record is the truth here: a stage that failed still wrote
@@ -344,6 +556,14 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
344
556
  // failure, a refusal — keeps that classification: `withRunJournal` ends
345
557
  // it on the way out and the throw below is what gets there.
346
558
  const stalled = improveStalled(error);
559
+ // The durable record has to say the paid call never came back. `outcome`
560
+ // is the one field a supervisor or a parser reads, and it stayed
561
+ // `dispatched` — which reads as "in flight" long after the run ended (F28).
562
+ const marked = markImproveStageStalled({ record, stage: stalledStage, stalled });
563
+ if (marked !== record) {
564
+ record = marked;
565
+ await writeImproveRecord(parsed.paths.record, record);
566
+ }
347
567
  if (stalled) {
348
568
  // Everything the record is owed goes in HERE. The session refuses to
349
569
  // write after its end line, so the note that used to follow this call
@@ -375,16 +595,41 @@ export const runImproveCommand = async (command, flags, dependencies = {}) => {
375
595
  }
376
596
  throw improveStallErrorWithSummary(error, await buildImproveRunSummary({ record, requestedTo: parsed.to }));
377
597
  }
598
+ // A run that fell back to fixed layout finished, but something stalled on
599
+ // the way. It gets the same `plan/STALL.md` a dead run gets — written after
600
+ // the plan, so it can say the plan was built from the derivation — and the
601
+ // README, written next, links to it (F8).
602
+ const fallbackStall = await writeImproveFallbackStall({ record, requestedTo: parsed.to });
603
+ // And a run that SETTLED what an earlier one stalled on replaces the file
604
+ // that earlier one left. Freshdesk shipped a settled plan under a README
605
+ // saying "settled" beside a STALL.md saying "INCOMPLETE — no plan"; the
606
+ // reader had no way to tell which was current (F21).
607
+ const resolvedStall = fallbackStall || stopped
608
+ ? undefined
609
+ : await resolveImproveStall({
610
+ record,
611
+ status: await readImproveKitStatus({ record, requestedTo: parsed.to }),
612
+ });
613
+ const stallFile = fallbackStall ?? resolvedStall;
378
614
  const readme = await refreshReadme();
379
615
  dependencies.journal?.note({
380
616
  workspace: parsed.paths.runDir,
381
- artifacts: [parsed.paths.record, readme, ...(record.plan?.artifacts ?? [])],
617
+ artifacts: [
618
+ parsed.paths.record,
619
+ readme,
620
+ ...(stallFile ? [stallFile] : []),
621
+ ...(record.plan?.artifacts ?? []),
622
+ ...(record.pages.flatMap((page) => page.plan?.artifacts ?? [])),
623
+ ...(record.site?.artifacts ?? []),
624
+ ],
382
625
  purchased: [
383
626
  ...(record.draft ? [record.draft.runId] : []),
384
627
  ...(record.convert?.purchaseIds ?? []),
385
628
  ...(record.sourceConvert?.purchaseIds ?? []),
629
+ ...(record.pages.flatMap((page) => page.convert?.purchaseIds ?? [])),
630
+ ...(record.branch ? [record.branch.runId] : []),
386
631
  ],
387
- terminal: parsed.to === 'plan',
632
+ terminal: parsed.to === 'site' || (record.scope === 'page' && parsed.to === 'plan'),
388
633
  });
389
634
  console.log(JSON.stringify({ from: parsed.from, to: parsed.to, ...record }, null, 2));
390
635
  write(await buildImproveRunSummary({ record, requestedTo: parsed.to }));