@12ui/design 0.2.27 → 0.2.28

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 (349) hide show
  1. package/README.md +72 -87
  2. package/SKILL.md +5 -5
  3. package/dist/branch-completion.d.ts.map +1 -1
  4. package/dist/branch-completion.js +37 -14
  5. package/dist/branch-completion.js.map +1 -1
  6. package/dist/branch-execution.d.ts.map +1 -1
  7. package/dist/branch-execution.js +28 -8
  8. package/dist/branch-execution.js.map +1 -1
  9. package/dist/branch-identity.d.ts +10 -4
  10. package/dist/branch-identity.d.ts.map +1 -1
  11. package/dist/branch-identity.js +9 -6
  12. package/dist/branch-identity.js.map +1 -1
  13. package/dist/branch-page-conversion.d.ts +9 -8
  14. package/dist/branch-page-conversion.d.ts.map +1 -1
  15. package/dist/branch-page-conversion.js +8 -2
  16. package/dist/branch-page-conversion.js.map +1 -1
  17. package/dist/branch-page-packaging.d.ts +31 -0
  18. package/dist/branch-page-packaging.d.ts.map +1 -0
  19. package/dist/branch-page-packaging.js +86 -0
  20. package/dist/branch-page-packaging.js.map +1 -0
  21. package/dist/branch-plan.d.ts +6 -0
  22. package/dist/branch-plan.d.ts.map +1 -1
  23. package/dist/branch-plan.js +6 -1
  24. package/dist/branch-plan.js.map +1 -1
  25. package/dist/branch-progress.d.ts +22 -0
  26. package/dist/branch-progress.d.ts.map +1 -1
  27. package/dist/branch-progress.js +33 -8
  28. package/dist/branch-progress.js.map +1 -1
  29. package/dist/branch-run-record.d.ts +9 -0
  30. package/dist/branch-run-record.d.ts.map +1 -1
  31. package/dist/branch-run-record.js.map +1 -1
  32. package/dist/branch-status.d.ts +2 -0
  33. package/dist/branch-status.d.ts.map +1 -1
  34. package/dist/branch-status.js +60 -15
  35. package/dist/branch-status.js.map +1 -1
  36. package/dist/branch-winner.d.ts +13 -15
  37. package/dist/branch-winner.d.ts.map +1 -1
  38. package/dist/branch-winner.js +25 -77
  39. package/dist/branch-winner.js.map +1 -1
  40. package/dist/cli-auth-command.d.ts.map +1 -1
  41. package/dist/cli-auth-command.js +5 -0
  42. package/dist/cli-auth-command.js.map +1 -1
  43. package/dist/cli-auth-onboarding.d.ts +12 -0
  44. package/dist/cli-auth-onboarding.d.ts.map +1 -0
  45. package/dist/cli-auth-onboarding.js +21 -0
  46. package/dist/cli-auth-onboarding.js.map +1 -0
  47. package/dist/cli-branch-command.d.ts +14 -19
  48. package/dist/cli-branch-command.d.ts.map +1 -1
  49. package/dist/cli-branch-command.js +207 -137
  50. package/dist/cli-branch-command.js.map +1 -1
  51. package/dist/cli-capabilities.d.ts +10 -51
  52. package/dist/cli-capabilities.d.ts.map +1 -1
  53. package/dist/cli-capabilities.js +13 -26
  54. package/dist/cli-capabilities.js.map +1 -1
  55. package/dist/cli-cli-command.d.ts +3 -0
  56. package/dist/cli-cli-command.d.ts.map +1 -1
  57. package/dist/cli-cli-command.js +15 -3
  58. package/dist/cli-cli-command.js.map +1 -1
  59. package/dist/cli-conversion-derivation.d.ts +30 -0
  60. package/dist/cli-conversion-derivation.d.ts.map +1 -0
  61. package/dist/{cli-export-command.js → cli-conversion-derivation.js} +178 -110
  62. package/dist/cli-conversion-derivation.js.map +1 -0
  63. package/dist/cli-conversion-output-directory.d.ts +5 -0
  64. package/dist/cli-conversion-output-directory.d.ts.map +1 -0
  65. package/dist/{cli-export-output-directory.js → cli-conversion-output-directory.js} +10 -10
  66. package/dist/cli-conversion-output-directory.js.map +1 -0
  67. package/dist/cli-convert-command.d.ts +9 -0
  68. package/dist/cli-convert-command.d.ts.map +1 -1
  69. package/dist/cli-convert-command.js +528 -158
  70. package/dist/cli-convert-command.js.map +1 -1
  71. package/dist/cli-corpus-command.d.ts.map +1 -1
  72. package/dist/cli-corpus-command.js +77 -10
  73. package/dist/cli-corpus-command.js.map +1 -1
  74. package/dist/cli-corpus-reference-downloads.d.ts +5 -0
  75. package/dist/cli-corpus-reference-downloads.d.ts.map +1 -1
  76. package/dist/cli-corpus-reference-downloads.js +18 -7
  77. package/dist/cli-corpus-reference-downloads.js.map +1 -1
  78. package/dist/cli-corpus-run.d.ts +9 -0
  79. package/dist/cli-corpus-run.d.ts.map +1 -1
  80. package/dist/cli-corpus-run.js +18 -0
  81. package/dist/cli-corpus-run.js.map +1 -1
  82. package/dist/cli-detach.d.ts +12 -4
  83. package/dist/cli-detach.d.ts.map +1 -1
  84. package/dist/cli-detach.js +49 -17
  85. package/dist/cli-detach.js.map +1 -1
  86. package/dist/cli-draft-command.d.ts +44 -61
  87. package/dist/cli-draft-command.d.ts.map +1 -1
  88. package/dist/cli-draft-command.js +307 -180
  89. package/dist/cli-draft-command.js.map +1 -1
  90. package/dist/cli-help/conversion.d.ts +30 -0
  91. package/dist/cli-help/conversion.d.ts.map +1 -0
  92. package/dist/cli-help/conversion.js +55 -0
  93. package/dist/cli-help/conversion.js.map +1 -0
  94. package/dist/cli-help/design.d.ts +74 -0
  95. package/dist/cli-help/design.d.ts.map +1 -0
  96. package/dist/cli-help/design.js +131 -0
  97. package/dist/cli-help/design.js.map +1 -0
  98. package/dist/cli-help/index.d.ts +224 -0
  99. package/dist/cli-help/index.d.ts.map +1 -0
  100. package/dist/cli-help/index.js +32 -0
  101. package/dist/cli-help/index.js.map +1 -0
  102. package/dist/cli-help/meta.d.ts +24 -0
  103. package/dist/cli-help/meta.d.ts.map +1 -0
  104. package/dist/cli-help/meta.js +30 -0
  105. package/dist/cli-help/meta.js.map +1 -0
  106. package/dist/cli-help/render.d.ts +4 -0
  107. package/dist/cli-help/render.d.ts.map +1 -0
  108. package/dist/cli-help/render.js +28 -0
  109. package/dist/cli-help/render.js.map +1 -0
  110. package/dist/cli-help/setup.d.ts +93 -0
  111. package/dist/cli-help/setup.d.ts.map +1 -0
  112. package/dist/cli-help/setup.js +142 -0
  113. package/dist/cli-help/setup.js.map +1 -0
  114. package/dist/cli-help/types.d.ts +10 -0
  115. package/dist/cli-help/types.d.ts.map +1 -0
  116. package/dist/cli-help/types.js +2 -0
  117. package/dist/cli-help/types.js.map +1 -0
  118. package/dist/cli-next-command.d.ts +11 -8
  119. package/dist/cli-next-command.d.ts.map +1 -1
  120. package/dist/cli-next-command.js +288 -88
  121. package/dist/cli-next-command.js.map +1 -1
  122. package/dist/cli-output-paths.d.ts +2 -23
  123. package/dist/cli-output-paths.d.ts.map +1 -1
  124. package/dist/cli-output-paths.js +2 -36
  125. package/dist/cli-output-paths.js.map +1 -1
  126. package/dist/cli-package-command.d.ts +1 -0
  127. package/dist/cli-package-command.d.ts.map +1 -1
  128. package/dist/cli-package-command.js +107 -34
  129. package/dist/cli-package-command.js.map +1 -1
  130. package/dist/cli-pending-auth.d.ts +20 -0
  131. package/dist/cli-pending-auth.d.ts.map +1 -0
  132. package/dist/cli-pending-auth.js +160 -0
  133. package/dist/cli-pending-auth.js.map +1 -0
  134. package/dist/cli-progress.d.ts +256 -75
  135. package/dist/cli-progress.d.ts.map +1 -1
  136. package/dist/cli-progress.js +425 -98
  137. package/dist/cli-progress.js.map +1 -1
  138. package/dist/cli-run.d.ts +2 -0
  139. package/dist/cli-run.d.ts.map +1 -1
  140. package/dist/cli-run.js +56 -75
  141. package/dist/cli-run.js.map +1 -1
  142. package/dist/cli-skill-command.d.ts +3 -0
  143. package/dist/cli-skill-command.d.ts.map +1 -1
  144. package/dist/cli-skill-command.js +26 -3
  145. package/dist/cli-skill-command.js.map +1 -1
  146. package/dist/cli-usage.d.ts +17 -8
  147. package/dist/cli-usage.d.ts.map +1 -1
  148. package/dist/cli-usage.js +55 -40
  149. package/dist/cli-usage.js.map +1 -1
  150. package/dist/config.d.ts +1 -0
  151. package/dist/config.d.ts.map +1 -1
  152. package/dist/config.js +8 -2
  153. package/dist/config.js.map +1 -1
  154. package/dist/conversion-client.d.ts +4 -0
  155. package/dist/conversion-client.d.ts.map +1 -1
  156. package/dist/conversion-client.js.map +1 -1
  157. package/dist/conversion-outputs.d.ts +11 -0
  158. package/dist/conversion-outputs.d.ts.map +1 -1
  159. package/dist/conversion-outputs.js +13 -1
  160. package/dist/conversion-outputs.js.map +1 -1
  161. package/dist/conversion-receipt.d.ts +1 -1
  162. package/dist/conversion-receipt.js +1 -1
  163. package/dist/conversion-recovery.d.ts +20 -0
  164. package/dist/conversion-recovery.d.ts.map +1 -0
  165. package/dist/conversion-recovery.js +61 -0
  166. package/dist/conversion-recovery.js.map +1 -0
  167. package/dist/conversion-status-contract.js +1 -1
  168. package/dist/conversion-status-contract.js.map +1 -1
  169. package/dist/credential-setup.d.ts +9 -1
  170. package/dist/credential-setup.d.ts.map +1 -1
  171. package/dist/credential-setup.js +13 -1
  172. package/dist/credential-setup.js.map +1 -1
  173. package/dist/draft-adoption.d.ts +9 -3
  174. package/dist/draft-adoption.d.ts.map +1 -1
  175. package/dist/draft-adoption.js +26 -41
  176. package/dist/draft-adoption.js.map +1 -1
  177. package/dist/draft-identity.d.ts +9 -12
  178. package/dist/draft-identity.d.ts.map +1 -1
  179. package/dist/draft-identity.js +0 -0
  180. package/dist/draft-identity.js.map +1 -1
  181. package/dist/draft-run.d.ts +9 -19
  182. package/dist/draft-run.d.ts.map +1 -1
  183. package/dist/draft-run.js +67 -95
  184. package/dist/draft-run.js.map +1 -1
  185. package/dist/draft-workspace.d.ts +26 -18
  186. package/dist/draft-workspace.d.ts.map +1 -1
  187. package/dist/draft-workspace.js +16 -5
  188. package/dist/draft-workspace.js.map +1 -1
  189. package/dist/hosted-draft-identity.d.ts +20 -0
  190. package/dist/hosted-draft-identity.d.ts.map +1 -0
  191. package/dist/hosted-draft-identity.js +30 -0
  192. package/dist/hosted-draft-identity.js.map +1 -0
  193. package/dist/hosted-draft-run.d.ts +60 -0
  194. package/dist/hosted-draft-run.d.ts.map +1 -0
  195. package/dist/hosted-draft-run.js +97 -0
  196. package/dist/hosted-draft-run.js.map +1 -0
  197. package/dist/legacy-codex-cleanup.d.ts +13 -0
  198. package/dist/legacy-codex-cleanup.d.ts.map +1 -1
  199. package/dist/legacy-codex-cleanup.js +83 -0
  200. package/dist/legacy-codex-cleanup.js.map +1 -1
  201. package/dist/legacy-skill-catalog.d.ts +2 -2
  202. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  203. package/dist/legacy-skill-catalog.js +76 -5
  204. package/dist/legacy-skill-catalog.js.map +1 -1
  205. package/dist/login-auth.d.ts +38 -0
  206. package/dist/login-auth.d.ts.map +1 -1
  207. package/dist/login-auth.js +67 -16
  208. package/dist/login-auth.js.map +1 -1
  209. package/dist/mcp-tool-definitions.js +1 -1
  210. package/dist/mcp-tool-definitions.js.map +1 -1
  211. package/dist/next-target.d.ts +1 -4
  212. package/dist/next-target.d.ts.map +1 -1
  213. package/dist/next-target.js +5 -9
  214. package/dist/next-target.js.map +1 -1
  215. package/dist/next-wait-lease.d.ts +17 -0
  216. package/dist/next-wait-lease.d.ts.map +1 -0
  217. package/dist/next-wait-lease.js +92 -0
  218. package/dist/next-wait-lease.js.map +1 -0
  219. package/dist/package-client.d.ts +30 -0
  220. package/dist/package-client.d.ts.map +1 -1
  221. package/dist/package-client.js.map +1 -1
  222. package/dist/package-submission.d.ts +17 -0
  223. package/dist/package-submission.d.ts.map +1 -1
  224. package/dist/package-submission.js +13 -0
  225. package/dist/package-submission.js.map +1 -1
  226. package/dist/pending-auth-store.d.ts +15 -0
  227. package/dist/pending-auth-store.d.ts.map +1 -0
  228. package/dist/pending-auth-store.js +90 -0
  229. package/dist/pending-auth-store.js.map +1 -0
  230. package/dist/responsive-quality.d.ts +2 -2
  231. package/dist/responsive-quality.js +2 -2
  232. package/dist/run-journal-commands.d.ts.map +1 -1
  233. package/dist/run-journal-commands.js +30 -78
  234. package/dist/run-journal-commands.js.map +1 -1
  235. package/dist/run-journal-in-flight.d.ts +2 -2
  236. package/dist/run-journal-in-flight.d.ts.map +1 -1
  237. package/dist/run-journal-in-flight.js +0 -0
  238. package/dist/run-journal-in-flight.js.map +1 -1
  239. package/dist/skill-installer.d.ts +2 -2
  240. package/dist/skill-installer.d.ts.map +1 -1
  241. package/dist/skill-installer.js +2 -2
  242. package/dist/skill-installer.js.map +1 -1
  243. package/open-design.json +3 -3
  244. package/package.json +1 -1
  245. package/skills/12ui-design/SKILL.md +62 -0
  246. package/skills/12ui-design/agents/openai.yaml +6 -0
  247. package/skills/12ui-design/inspire.md +11 -0
  248. package/dist/cli-create-command.d.ts +0 -59
  249. package/dist/cli-create-command.d.ts.map +0 -1
  250. package/dist/cli-create-command.js +0 -354
  251. package/dist/cli-create-command.js.map +0 -1
  252. package/dist/cli-export-command.d.ts +0 -26
  253. package/dist/cli-export-command.d.ts.map +0 -1
  254. package/dist/cli-export-command.js.map +0 -1
  255. package/dist/cli-export-output-directory.d.ts +0 -5
  256. package/dist/cli-export-output-directory.d.ts.map +0 -1
  257. package/dist/cli-export-output-directory.js.map +0 -1
  258. package/dist/cli-image-batch-command.d.ts +0 -29
  259. package/dist/cli-image-batch-command.d.ts.map +0 -1
  260. package/dist/cli-image-batch-command.js +0 -236
  261. package/dist/cli-image-batch-command.js.map +0 -1
  262. package/dist/cli-image-batch-materialize.d.ts +0 -27
  263. package/dist/cli-image-batch-materialize.d.ts.map +0 -1
  264. package/dist/cli-image-batch-materialize.js +0 -41
  265. package/dist/cli-image-batch-materialize.js.map +0 -1
  266. package/dist/cli-image-batch-resume.d.ts +0 -36
  267. package/dist/cli-image-batch-resume.d.ts.map +0 -1
  268. package/dist/cli-image-batch-resume.js +0 -176
  269. package/dist/cli-image-batch-resume.js.map +0 -1
  270. package/dist/cli-image-command.d.ts +0 -10
  271. package/dist/cli-image-command.d.ts.map +0 -1
  272. package/dist/cli-image-command.js +0 -106
  273. package/dist/cli-image-command.js.map +0 -1
  274. package/dist/cli-select-command.d.ts +0 -16
  275. package/dist/cli-select-command.d.ts.map +0 -1
  276. package/dist/cli-select-command.js +0 -60
  277. package/dist/cli-select-command.js.map +0 -1
  278. package/dist/create-identity.d.ts +0 -25
  279. package/dist/create-identity.d.ts.map +0 -1
  280. package/dist/create-identity.js +0 -0
  281. package/dist/create-identity.js.map +0 -1
  282. package/dist/draft-prompts.d.ts +0 -35
  283. package/dist/draft-prompts.d.ts.map +0 -1
  284. package/dist/draft-prompts.js +0 -51
  285. package/dist/draft-prompts.js.map +0 -1
  286. package/dist/image-batch-status.d.ts +0 -42
  287. package/dist/image-batch-status.d.ts.map +0 -1
  288. package/dist/image-batch-status.js +0 -143
  289. package/dist/image-batch-status.js.map +0 -1
  290. package/dist/image-generation-batch-attempt.d.ts +0 -28
  291. package/dist/image-generation-batch-attempt.d.ts.map +0 -1
  292. package/dist/image-generation-batch-attempt.js +0 -48
  293. package/dist/image-generation-batch-attempt.js.map +0 -1
  294. package/dist/image-generation-batch-manifest.d.ts +0 -25
  295. package/dist/image-generation-batch-manifest.d.ts.map +0 -1
  296. package/dist/image-generation-batch-manifest.js +0 -97
  297. package/dist/image-generation-batch-manifest.js.map +0 -1
  298. package/dist/image-generation-completion.d.ts +0 -43
  299. package/dist/image-generation-completion.d.ts.map +0 -1
  300. package/dist/image-generation-completion.js +0 -54
  301. package/dist/image-generation-completion.js.map +0 -1
  302. package/dist/image-generation-error.d.ts +0 -3
  303. package/dist/image-generation-error.d.ts.map +0 -1
  304. package/dist/image-generation-error.js +0 -30
  305. package/dist/image-generation-error.js.map +0 -1
  306. package/dist/image-generation-evidence.d.ts +0 -43
  307. package/dist/image-generation-evidence.d.ts.map +0 -1
  308. package/dist/image-generation-evidence.js +0 -28
  309. package/dist/image-generation-evidence.js.map +0 -1
  310. package/dist/image-generation-fs.d.ts +0 -3
  311. package/dist/image-generation-fs.d.ts.map +0 -1
  312. package/dist/image-generation-fs.js +0 -23
  313. package/dist/image-generation-fs.js.map +0 -1
  314. package/dist/image-generation-output.d.ts +0 -3
  315. package/dist/image-generation-output.d.ts.map +0 -1
  316. package/dist/image-generation-output.js +0 -51
  317. package/dist/image-generation-output.js.map +0 -1
  318. package/dist/image-generation-request.d.ts +0 -43
  319. package/dist/image-generation-request.d.ts.map +0 -1
  320. package/dist/image-generation-request.js +0 -52
  321. package/dist/image-generation-request.js.map +0 -1
  322. package/dist/image-generation-resume.d.ts +0 -49
  323. package/dist/image-generation-resume.d.ts.map +0 -1
  324. package/dist/image-generation-resume.js +0 -96
  325. package/dist/image-generation-resume.js.map +0 -1
  326. package/dist/image-generation-run.d.ts +0 -46
  327. package/dist/image-generation-run.d.ts.map +0 -1
  328. package/dist/image-generation-run.js +0 -158
  329. package/dist/image-generation-run.js.map +0 -1
  330. package/dist/image-generation-staging.d.ts +0 -25
  331. package/dist/image-generation-staging.d.ts.map +0 -1
  332. package/dist/image-generation-staging.js +0 -80
  333. package/dist/image-generation-staging.js.map +0 -1
  334. package/dist/image-generation-usage.d.ts +0 -75
  335. package/dist/image-generation-usage.d.ts.map +0 -1
  336. package/dist/image-generation-usage.js +0 -219
  337. package/dist/image-generation-usage.js.map +0 -1
  338. package/dist/image-provider-preflight.d.ts +0 -21
  339. package/dist/image-provider-preflight.d.ts.map +0 -1
  340. package/dist/image-provider-preflight.js +0 -184
  341. package/dist/image-provider-preflight.js.map +0 -1
  342. package/dist/selection-record.d.ts +0 -97
  343. package/dist/selection-record.d.ts.map +0 -1
  344. package/dist/selection-record.js +0 -138
  345. package/dist/selection-record.js.map +0 -1
  346. package/skills/design/SKILL.md +0 -116
  347. package/skills/design/agents/openai.yaml +0 -8
  348. package/skills/design/assets/large-logo.svg +0 -3
  349. package/skills/design/assets/small-400px.png +0 -0
@@ -1,8 +1,10 @@
1
1
  import { readStoredConversionCredentials, removeStoredConversionCredentials, resolveCredentialFile, } from './credential-store.js';
2
+ import { MissingTwelveUiCredentialError } from './cli-auth-onboarding.js';
2
3
  import { setUpConversionCredentials } from './credential-setup.js';
3
4
  import { booleanFlag, stringFlag } from './cli-arguments.js';
4
5
  import { declareClientVersion } from './client-version.js';
5
6
  import { usageRefusal } from './cli-usage.js';
7
+ import { hasConfiguredConversionCredential } from './config.js';
6
8
  import { revokeConvertApiKey, TWELVE_UI_DEVICE_SCOPES, verifyTwelveUiCredential, } from './login-auth.js';
7
9
  const readQuota = async (origin, apiKey) => {
8
10
  const response = await fetch(`${origin}/api/v1/convert/quota`, {
@@ -57,6 +59,9 @@ export const runAuthCommand = async (action, flags) => {
57
59
  }
58
60
  const stored = await readStoredConversionCredentials();
59
61
  if (!stored) {
62
+ if (!hasConfiguredConversionCredential(stringFlag(flags, 'api-key'))) {
63
+ throw new MissingTwelveUiCredentialError();
64
+ }
60
65
  throw new Error(`12ui credentials are not configured at ${resolveCredentialFile()}`);
61
66
  }
62
67
  if (action === 'status') {
@@ -1 +1 @@
1
- {"version":3,"file":"cli-auth-command.js","sourceRoot":"","sources":["../src/cli-auth-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-auth-command.js","sourceRoot":"","sources":["../src/cli-auth-command.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,+BAA+B,EAC/B,iCAAiC,EACjC,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,8BAA8B,EAAE,MAAM,0BAA0B,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iCAAiC,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GAEzB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,SAAS,GAAG,KAAK,EAAE,MAAc,EAAE,MAAc,EAAoB,EAAE;IAC3E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,uBAAuB,EAAE;QAC7D,OAAO,EAAE,oBAAoB,CAAC,IAAI,OAAO,CAAC;YACxC,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,UAAU,MAAM,EAAE;SAClC,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;eACrD,OAAQ,KAAiC,CAAC,MAAM,KAAK,QAAQ;YAChE,CAAC,CAAE,KAAiC,CAAC,MAAM;YAC3C,CAAC,CAAC,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAM,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,8BAA8B,GAAG,KAAK,EAC1C,MAAc,EACd,WAA+B,EACM,EAAE;IACvC,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,KAAK,IAAI,uBAAuB,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,OAAO,MAAM,wBAAwB,CAAC;gBACpC,MAAM;gBACN,WAAW;gBACX,cAAc,EAAE,CAAC,KAAK,CAAC;aACxB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,MAAM,IAAI,cAAc,CACtB,QAAQ,EACR,iFAAiF,CAClF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,MAA0B,EAC1B,KAAe,EACA,EAAE;IACjB,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC;IACtD,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,MAAM,0BAA0B,CAAC;YACnD,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC;YACpC,MAAM,EAAE,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC;YACnC,WAAW;YACX,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC;YACtC,mBAAmB,EAAE,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,SAAS;YAC/D,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrB,OAAO,CAAC,GAAG,CAAC,4DAA4D,CAAC,CAAC;gBAC1E,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CACT,gCAAgC,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE;cACzF,oBAAoB,WAAW,CAAC,cAAc,GAAG,CACpD,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,+BAA+B,EAAE,CAAC;IACvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,IAAI,CAAC,iCAAiC,CAAC,UAAU,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,8BAA8B,EAAE,CAAC;QAC7C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,0CAA0C,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,YAAY,GAAG,MAAM,8BAA8B,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACtF,MAAM,eAAe,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;QACvE,MAAM,KAAK,GAAG,eAAe;YAC3B,CAAC,CAAC,MAAM,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;YAC/C,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,MAAM,GAAG;YACb,MAAM,EAAE,eAAe;YACvB,WAAW,EAAE,YAAY,CAAC,WAAW;YACrC,SAAS,EAAE,YAAY,CAAC,SAAS;YACjC,YAAY,EAAE,YAAY,CAAC,YAAY;YACvC,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,cAAc,EAAE,qBAAqB,EAAE;YACvC,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtC,CAAC;QACF,IAAI,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;aACxE,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,mCAAmC,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,eAAe,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,GAAG,CAAC,WAAW,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACxC,OAAO,CAAC,GAAG,CAAC,eAAe;gBACzB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChC,CAAC,CAAC,wEAAwE,CAAC,CAAC;QAChF,CAAC;QACD,OAAO;IACT,CAAC;IACD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,MAAM,mBAAmB,CAAC;YACxB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,WAAW;SACZ,CAAC,CAAC;QACH,MAAM,iCAAiC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,wEAAwE,CAAC,CAAC;QACtF,OAAO;IACT,CAAC;IACD,MAAM,YAAY,CAAC;QACjB,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,WAAW,CAAC,CAAC,CAAC,0BAA0B,EAAE;cACrE,mEAAmE;QACvE,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,CAAC,MAAM,CAAC;KACf,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ export declare const TWELVE_UI_CONNECT_CLI_URL = "https://12ui.com/connect-cli";
2
+ export declare const authOnboardingMessage: (options?: {
3
+ agentFacing?: boolean;
4
+ approvalUrl?: string;
5
+ }) => string;
6
+ export declare const printAuthOnboarding: (options?: {
7
+ approvalUrl?: string;
8
+ }) => void;
9
+ export declare class MissingTwelveUiCredentialError extends Error {
10
+ constructor(approvalUrl?: string);
11
+ }
12
+ //# sourceMappingURL=cli-auth-onboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-auth-onboarding.d.ts","sourceRoot":"","sources":["../src/cli-auth-onboarding.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,iCAAiC,CAAC;AASxE,eAAO,MAAM,qBAAqB,GAAI,UAAS;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,MAGG,CAAC;AAEb,eAAO,MAAM,mBAAmB,GAAI,UAAS;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,KAAG,IAIR,CAAC;AAEF,qBAAa,8BAA+B,SAAQ,KAAK;gBAC3C,WAAW,CAAC,EAAE,MAAM;CAIjC"}
@@ -0,0 +1,21 @@
1
+ export const TWELVE_UI_CONNECT_CLI_URL = 'https://12ui.com/connect-cli';
2
+ const ownerAuthOnboardingLines = (approvalUrl) => [
3
+ `Sign in/Create an account with this magic link: ${approvalUrl}`,
4
+ 'Takes 5 seconds and you can use 12ui for free.',
5
+ ];
6
+ const AGENT_AUTH_ONBOARDING_LINE = 'Agent: Give this link to your user, then retry after they connect 12ui.';
7
+ export const authOnboardingMessage = (options = {}) => [
8
+ ...ownerAuthOnboardingLines(options.approvalUrl ?? TWELVE_UI_CONNECT_CLI_URL),
9
+ ...(options.agentFacing ? [AGENT_AUTH_ONBOARDING_LINE] : []),
10
+ ].join('\n');
11
+ export const printAuthOnboarding = (options = {}) => {
12
+ for (const line of ownerAuthOnboardingLines(options.approvalUrl ?? TWELVE_UI_CONNECT_CLI_URL))
13
+ console.log(line);
14
+ };
15
+ export class MissingTwelveUiCredentialError extends Error {
16
+ constructor(approvalUrl) {
17
+ super(authOnboardingMessage({ agentFacing: true, approvalUrl }));
18
+ this.name = 'MissingTwelveUiCredentialError';
19
+ }
20
+ }
21
+ //# sourceMappingURL=cli-auth-onboarding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-auth-onboarding.js","sourceRoot":"","sources":["../src/cli-auth-onboarding.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,8BAA8B,CAAC;AAExE,MAAM,wBAAwB,GAAG,CAAC,WAAmB,EAAqB,EAAE,CAAC;IAC3E,mDAAmD,WAAW,EAAE;IAChE,gDAAgD;CACjD,CAAC;AAEF,MAAM,0BAA0B,GAAG,yEAAyE,CAAC;AAE7G,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,UAGlC,EAAE,EAAU,EAAE,CAAC;IACjB,GAAG,wBAAwB,CAAC,OAAO,CAAC,WAAW,IAAI,yBAAyB,CAAC;IAC7E,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;CAC7D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,UAEhC,EAAE,EAAQ,EAAE;IACd,KAAK,MAAM,IAAI,IAAI,wBAAwB,CACzC,OAAO,CAAC,WAAW,IAAI,yBAAyB,CACjD;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,OAAO,8BAA+B,SAAQ,KAAK;IACvD,YAAY,WAAoB;QAC9B,KAAK,CAAC,qBAAqB,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACjE,IAAI,CAAC,IAAI,GAAG,gCAAgC,CAAC;IAC/C,CAAC;CACF"}
@@ -17,10 +17,9 @@ export type ResolvedBranchDirectory = {
17
17
  runDir: string | null;
18
18
  };
19
19
  /**
20
- * `12ui branch execute <run-dir>` takes the DRAFT run directory and keeps its
21
- * own records in `<run-dir>/branch`, which is where the skill says the pages
22
- * land. `--out-dir` stays an alias that names the branch directory outright,
23
- * for a branch run with no draft behind it.
20
+ * Execute creates a run directory when none is supplied. `--out-dir` and the
21
+ * positional used by resume both name the run directory; records live beneath
22
+ * it in `<run-dir>/branch`.
24
23
  *
25
24
  * `branch status` accepts either spelling: a directory that already holds
26
25
  * branch records is one, and otherwise `<dir>/branch` is tried, so a caller who
@@ -31,26 +30,22 @@ export declare const resolveBranchDirectory: (args: {
31
30
  runDirArgument?: string;
32
31
  outDirFlag?: string;
33
32
  }) => Promise<ResolvedBranchDirectory>;
34
- /**
35
- * The opening line is the only estimate a caller has before anything moves, so
36
- * it is derived from the run's phases rather than asserted. Pages now convert as
37
- * their own screens land and several at a time, which is why the old sentence —
38
- * one package per page, serial, ~20m for a site — would now overstate a normal
39
- * run by roughly a factor of two, and an overstated wait is what makes a caller
40
- * abandon a run that is on time.
41
- */
42
- export declare const branchExecuteBanner: (args: {
43
- scope: "page" | "site";
44
- outDir: string;
45
- convert: boolean;
46
- concurrency?: number;
47
- }) => string;
33
+ /** Validate every execute input before a detached parent creates its workspace. */
34
+ export declare const prepareDetachedBranchDirectory: (args: {
35
+ flags: CliFlags;
36
+ workspaceRoot?: string;
37
+ }) => Promise<ResolvedBranchDirectory>;
48
38
  export declare const runBranchCommand: (action: string | undefined, flags: CliFlags, dependencies?: {
49
39
  readConfig?: typeof readConversionConfig;
50
40
  createBranchClient?: (config: ReturnType<typeof readConversionConfig>) => TwelveUiBranchClient;
51
41
  createPackageClient?: (config: ReturnType<typeof readConversionConfig>) => TwelveUiConversionPackageClient;
52
- /** The positional `<run-dir>` from `12ui branch execute <run-dir>`. */
42
+ /** Internal detached-worker positional, or the public resume run directory. */
53
43
  runDirArgument?: string;
44
+ /** Test-only root for an automatically created run directory. */
45
+ workspaceRoot?: string;
46
+ /** Receives the run directory as the command's first output line. */
47
+ write?: (line: string) => void;
48
+ onRunDirectory?: (runDir: string) => void;
54
49
  /** Where this command writes down what it did. */
55
50
  journal?: RunJournalNotes;
56
51
  }) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"cli-branch-command.d.ts","sourceRoot":"","sources":["../src/cli-branch-command.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAqB,MAAM,oBAAoB,CAAC;AAyB7E,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAQtE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,IAOnE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAU,MAAM;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,KAAG,OAAO,CAAC,uBAAuB,CAwBlC,CAAC;AAyFF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,MAAM;IACxC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,KAAG,MA4BH,CAAC;AAaF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,GAAG,SAAS,EAC1B,OAAO,QAAQ,EACf,eAAc;IACZ,UAAU,CAAC,EAAE,OAAO,oBAAoB,CAAC;IACzC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,KAAK,oBAAoB,CAAC;IAC/F,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,KAC5C,+BAA+B,CAAC;IACrC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,OAAO,CAAC,EAAE,eAAe,CAAC;CACtB,KACL,OAAO,CAAC,IAAI,CAsPd,CAAC"}
1
+ {"version":3,"file":"cli-branch-command.d.ts","sourceRoot":"","sources":["../src/cli-branch-command.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2B,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAI5E,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAqB,MAAM,oBAAoB,CAAC;AAsB7E,OAAO,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAMtE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,MAAM,GAAG,IAOnE,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GAAU,MAAM;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,KAAG,OAAO,CAAC,uBAAuB,CAuBlC,CAAC;AAoGF,mFAAmF;AACnF,eAAO,MAAM,8BAA8B,GAAU,MAAM;IACzD,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,KAAG,OAAO,CAAC,uBAAuB,CAoBlC,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,MAAM,GAAG,SAAS,EAC1B,OAAO,QAAQ,EACf,eAAc;IACZ,UAAU,CAAC,EAAE,OAAO,oBAAoB,CAAC;IACzC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,KAAK,oBAAoB,CAAC;IAC/F,mBAAmB,CAAC,EAAE,CACpB,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,KAC5C,+BAA+B,CAAC;IACrC,+EAA+E;IAC/E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,kDAAkD;IAClD,OAAO,CAAC,EAAE,eAAe,CAAC;CACtB,KACL,OAAO,CAAC,IAAI,CA2Ud,CAAC"}
@@ -4,6 +4,7 @@ import path from 'node:path';
4
4
  import { booleanFlag, stringFlag } from './cli-arguments.js';
5
5
  import { CliRefusal } from './cli-refusal.js';
6
6
  import { usageRefusal } from './cli-usage.js';
7
+ import { prepareOutputDirectory } from './cli-output-paths.js';
7
8
  import { readConversionConfig } from './config.js';
8
9
  import { TwelveUiBranchClient } from './branch-client.js';
9
10
  import { deriveBranchRunKey, executeBranchRun } from './branch-execution.js';
@@ -11,13 +12,12 @@ import { resolveBranchWinner } from './branch-winner.js';
11
12
  import { MAX_CONCEPT_CHARACTERS, readConceptValue } from './concept-input.js';
12
13
  import { BRANCH_ATTEMPT_FILENAME, BRANCH_COMPLETION_FILENAME, branchAttemptPath, readBranchAttempt, } from './branch-run-record.js';
13
14
  import { BRANCH_PROGRESS_FILENAME } from './branch-progress.js';
14
- import { DRAFT_BRANCH_DIRECTORY } from './draft-workspace.js';
15
- import { BRANCH_PAGE_CONCURRENCY_DEFAULT, BRANCH_TYPICAL_SITE_PAGES, OPERATION_DURATION_HINTS, branchRunEstimateSeconds, createPackageProgressReporter, formatDuration, narrateCounts, nextActionLine, } from './cli-progress.js';
15
+ import { createDraftWorkspace, DRAFT_BRANCH_DIRECTORY } from './draft-workspace.js';
16
+ import { BRANCH_PAGE_CONCURRENCY_DEFAULT, BRANCH_TYPICAL_SITE_PAGES, branchRunEstimateSeconds, createLongRunningProgress, packageStageUnit, } from './cli-progress.js';
16
17
  import { isConversionModel } from './conversion-models.js';
17
18
  import { normalizeOptionalIdempotencyKey } from './idempotency-key.js';
18
19
  import { TwelveUiConversionPackageClient } from './package-client.js';
19
20
  import { isResponsiveConversionQuality, } from './responsive-quality.js';
20
- const HEARTBEAT_MS = 15_000;
21
21
  /**
22
22
  * `.12ui/site/.12ui/site/candidates/D.png` — measured in the harness pass, from
23
23
  * an agent that resolved the run-directory convention against a cwd that was
@@ -34,10 +34,9 @@ export const nestedRunDirectoryWarning = (target) => {
34
34
  + ' working directory — check the run directory you meant before the next command.';
35
35
  };
36
36
  /**
37
- * `12ui branch execute <run-dir>` takes the DRAFT run directory and keeps its
38
- * own records in `<run-dir>/branch`, which is where the skill says the pages
39
- * land. `--out-dir` stays an alias that names the branch directory outright,
40
- * for a branch run with no draft behind it.
37
+ * Execute creates a run directory when none is supplied. `--out-dir` and the
38
+ * positional used by resume both name the run directory; records live beneath
39
+ * it in `<run-dir>/branch`.
41
40
  *
42
41
  * `branch status` accepts either spelling: a directory that already holds
43
42
  * branch records is one, and otherwise `<dir>/branch` is tried, so a caller who
@@ -45,13 +44,11 @@ export const nestedRunDirectoryWarning = (target) => {
45
44
  * answer instead of a lecture.
46
45
  */
47
46
  export const resolveBranchDirectory = async (args) => {
48
- if (args.outDirFlag)
49
- return { branchDir: path.resolve(args.outDirFlag), runDir: null };
50
- if (!args.runDirArgument) {
51
- throw new CliRefusal('A run directory is required: `12ui branch execute <run-dir>` (the directory `12ui draft`'
52
- + ' printed), or `--out-dir <directory>` to name the branch directory outright.', 'branch_run_directory_missing');
47
+ const named = args.outDirFlag ?? args.runDirArgument;
48
+ if (!named) {
49
+ throw new CliRefusal('A run directory is required for resume: `12ui branch resume <run-dir>`.', 'branch_run_directory_missing');
53
50
  }
54
- const given = path.resolve(args.runDirArgument);
51
+ const given = path.resolve(named);
55
52
  const holdsBranchRecords = await Promise.all([
56
53
  BRANCH_ATTEMPT_FILENAME,
57
54
  BRANCH_COMPLETION_FILENAME,
@@ -66,7 +63,7 @@ export const resolveBranchDirectory = async (args) => {
66
63
  }
67
64
  }));
68
65
  if (holdsBranchRecords.some(Boolean))
69
- return { branchDir: given, runDir: null };
66
+ return { branchDir: given, runDir: path.dirname(given) };
70
67
  return { branchDir: path.join(given, DRAFT_BRANCH_DIRECTORY), runDir: given };
71
68
  };
72
69
  const warnOnNestedRunDirectory = (targets) => {
@@ -141,43 +138,6 @@ const runEstimate = (args) => branchRunEstimateSeconds({
141
138
  concurrency: args.concurrency,
142
139
  convert: args.convert,
143
140
  });
144
- /**
145
- * The opening line is the only estimate a caller has before anything moves, so
146
- * it is derived from the run's phases rather than asserted. Pages now convert as
147
- * their own screens land and several at a time, which is why the old sentence —
148
- * one package per page, serial, ~20m for a site — would now overstate a normal
149
- * run by roughly a factor of two, and an overstated wait is what makes a caller
150
- * abandon a run that is on time.
151
- */
152
- export const branchExecuteBanner = (args) => {
153
- const concurrency = args.concurrency ?? BRANCH_PAGE_CONCURRENCY_DEFAULT;
154
- const exact = runEstimate({ scope: args.scope, convert: args.convert, concurrency });
155
- // An estimate quoted to the second reads as a promise. The machine-readable
156
- // figure stays exact in `--dry-run`; the sentence rounds to the minute.
157
- const minutes = (seconds) => Math.max(60, Math.round(seconds / 60) * 60);
158
- const estimate = { floor: minutes(exact.floor), ceiling: minutes(exact.ceiling) };
159
- const pages = plannedPages(args.scope);
160
- return [
161
- `12ui branch execute — scope ${args.scope}, blocking until the whole run finishes.`,
162
- `Claim and plan ~${formatDuration(OPERATION_DURATION_HINTS.branchClaim)} (buys no image), then`
163
- + ` each screen ~${formatDuration(OPERATION_DURATION_HINTS.branchScreen)}`
164
- + ` (server budget ${formatDuration(OPERATION_DURATION_HINTS.branchScreenBudget)})`
165
- + `${args.convert
166
- ? `, then each page converts as its own screens land, up to ${concurrency} at a time`
167
- + ` ~${formatDuration(OPERATION_DURATION_HINTS.branchPackage)} each`
168
- + ` — about ${estimate.floor === estimate.ceiling
169
- ? formatDuration(estimate.ceiling)
170
- : `${formatDuration(estimate.floor)} to ${formatDuration(estimate.ceiling)}`}`
171
- + `${args.scope === 'page' ? ' for one page' : ` for a ${pages}-page site`}`
172
- : ''}.`,
173
- nextActionLine({
174
- what: `A --scope ${args.scope} run`,
175
- typicalSeconds: estimate.ceiling,
176
- statusCommand: `12ui next ${args.outDir}`,
177
- waitHint: 'or leave this command running, which is what --wait already does by default',
178
- }),
179
- ].join('\n');
180
- };
181
141
  const readPageConcurrency = (flags) => {
182
142
  const value = stringFlag(flags, 'page-concurrency');
183
143
  if (value === undefined)
@@ -189,6 +149,29 @@ const readPageConcurrency = (flags) => {
189
149
  }
190
150
  return parsed;
191
151
  };
152
+ /** Validate every execute input before a detached parent creates its workspace. */
153
+ export const prepareDetachedBranchDirectory = async (args) => {
154
+ const existing = stringFlag(args.flags, 'out-dir')?.trim();
155
+ if (existing)
156
+ return resolveBranchDirectory({ outDirFlag: existing });
157
+ await resolveBranchWinner({ flags: args.flags });
158
+ readScope(args.flags);
159
+ const concept = await readConcept(args.flags);
160
+ readConvert(args.flags);
161
+ readMaxScreens(args.flags);
162
+ readPageConcurrency(args.flags);
163
+ const aspect = stringFlag(args.flags, 'aspect')?.trim();
164
+ if (aspect !== undefined && !['landscape', 'portrait', 'square'].includes(aspect)) {
165
+ throw new CliRefusal('--aspect must be landscape, portrait, or square', 'branch_aspect_invalid');
166
+ }
167
+ normalizeOptionalIdempotencyKey(stringFlag(args.flags, 'idempotency-key'), '--idempotency-key');
168
+ const paths = await createDraftWorkspace({
169
+ query: concept,
170
+ ...(args.workspaceRoot ? { root: args.workspaceRoot } : {}),
171
+ });
172
+ await prepareOutputDirectory(paths.branchDir);
173
+ return { runDir: paths.runDir, branchDir: paths.branchDir };
174
+ };
192
175
  export const runBranchCommand = async (action, flags, dependencies = {}) => {
193
176
  if (action === 'status') {
194
177
  // Merged into `12ui next` in 0.2.20, along with the other three status
@@ -206,14 +189,21 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
206
189
  });
207
190
  }
208
191
  const outDirFlag = stringFlag(flags, 'out-dir')?.trim();
209
- const resolvedDirectory = await resolveBranchDirectory({
210
- ...(outDirFlag ? { outDirFlag } : {}),
211
- ...(dependencies.runDirArgument ? { runDirArgument: dependencies.runDirArgument } : {}),
212
- });
213
- const outDir = resolvedDirectory.branchDir;
192
+ let resolvedDirectory = outDirFlag || dependencies.runDirArgument
193
+ ? await resolveBranchDirectory({
194
+ ...(outDirFlag ? { outDirFlag } : {}),
195
+ ...(dependencies.runDirArgument ? { runDirArgument: dependencies.runDirArgument } : {}),
196
+ })
197
+ : undefined;
198
+ if (action === 'resume' && !resolvedDirectory) {
199
+ await resolveBranchDirectory({});
200
+ }
201
+ let outDir = resolvedDirectory?.branchDir;
202
+ if (outDir)
203
+ await prepareOutputDirectory(outDir);
214
204
  warnOnNestedRunDirectory([
215
205
  outDirFlag ?? dependencies.runDirArgument,
216
- stringFlag(flags, 'winner-image'),
206
+ stringFlag(flags, 'start'),
217
207
  ]);
218
208
  const readConfig = dependencies.readConfig ?? readConversionConfig;
219
209
  const quiet = booleanFlag(flags, 'quiet');
@@ -221,11 +211,12 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
221
211
  const pageConcurrency = readPageConcurrency(flags) ?? BRANCH_PAGE_CONCURRENCY_DEFAULT;
222
212
  let inputs;
223
213
  if (action === 'resume') {
224
- const attempt = await readBranchAttempt(branchAttemptPath(outDir));
214
+ const resumeOutDir = outDir;
215
+ const attempt = await readBranchAttempt(branchAttemptPath(resumeOutDir));
225
216
  if (!attempt) {
226
217
  throw new CliRefusal(`This branch run has never been started — there is nothing to resume, and nothing has`
227
- + ` failed. There is no branch attempt at ${branchAttemptPath(outDir)}. Start it with`
228
- + ' `12ui branch execute --winner-run <crt-id> --winner-slot <slot>'
218
+ + ` failed. There is no branch attempt at ${branchAttemptPath(resumeOutDir)}. Start it with`
219
+ + ' `12ui branch execute --start <image.png>'
229
220
  + ` --concept <text,1-${MAX_CONCEPT_CHARACTERS}-chars>`
230
221
  + ' --scope page|site --out-dir <directory>`.', 'branch_nothing_to_resume');
231
222
  }
@@ -244,7 +235,7 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
244
235
  winner = { kind: 'image', imagePath: recorded.imagePath, bytes, mediaType: recorded.mediaType, sha256 };
245
236
  }
246
237
  inputs = {
247
- outDir,
238
+ outDir: resumeOutDir,
248
239
  scope: attempt.scope,
249
240
  concept: attempt.concept,
250
241
  winner,
@@ -276,15 +267,25 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
276
267
  * this image before any screen is dispatched. Scope and concept are cheap
277
268
  * to re-ask for; a plan call on the wrong design is not.
278
269
  */
279
- const winner = await resolveBranchWinner({
280
- flags,
281
- runDir: resolvedDirectory.runDir,
282
- outDir,
283
- });
270
+ const winner = await resolveBranchWinner({ flags, ...(outDir ? { outDir } : {}) });
271
+ const scope = readScope(flags);
272
+ const concept = await readConcept(flags);
273
+ if (!resolvedDirectory) {
274
+ const paths = await createDraftWorkspace({
275
+ query: concept,
276
+ ...(dependencies.workspaceRoot ? { root: dependencies.workspaceRoot } : {}),
277
+ });
278
+ resolvedDirectory = { runDir: paths.runDir, branchDir: paths.branchDir };
279
+ outDir = paths.branchDir;
280
+ await prepareOutputDirectory(outDir);
281
+ (dependencies.write ?? ((line) => { process.stdout.write(`${line}\n`); }))(paths.runDir);
282
+ dependencies.onRunDirectory?.(paths.runDir);
283
+ dependencies.journal?.note({ workspace: paths.branchDir });
284
+ }
284
285
  inputs = {
285
- outDir,
286
- scope: readScope(flags),
287
- concept: await readConcept(flags),
286
+ outDir: outDir,
287
+ scope,
288
+ concept,
288
289
  winner,
289
290
  ...(aspect ? { aspect: aspect } : {}),
290
291
  ...(readMaxScreens(flags) === undefined ? {} : { maxScreens: readMaxScreens(flags) }),
@@ -305,7 +306,7 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
305
306
  dependencies.journal?.note({ terminal: false });
306
307
  console.log(JSON.stringify({
307
308
  dryRun: true,
308
- outDir,
309
+ outDir: outDir,
309
310
  origin: config.origin,
310
311
  scope: inputs.scope,
311
312
  concept: inputs.concept,
@@ -327,75 +328,121 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
327
328
  }
328
329
  const branchClient = (dependencies.createBranchClient ?? ((value) => (new TwelveUiBranchClient(value))))(config);
329
330
  const packageClient = (dependencies.createPackageClient ?? ((value) => (new TwelveUiConversionPackageClient(value))))(config);
330
- const startedAt = Date.now();
331
- const write = (line) => {
332
- if (!quiet)
333
- process.stderr.write(`${line}\n`);
334
- };
335
- if (!quiet) {
336
- write(branchExecuteBanner({
337
- scope: inputs.scope,
338
- outDir,
339
- convert: Boolean(inputs.convert),
340
- concurrency: pageConcurrency,
341
- }));
342
- }
343
- let lastHeartbeat = 0;
344
- const elapsed = () => formatDuration((Date.now() - startedAt) / 1000);
345
- const reportPackage = createPackageProgressReporter({ write, elapsed });
346
- const result = await executeBranchRun({
347
- branchClient,
348
- packageClient,
349
- inputs,
350
- origin: config.origin,
351
- resume,
352
- pageConcurrency,
353
- onEvent: (event) => {
354
- if (quiet)
355
- return;
356
- if (event.kind === 'progress') {
357
- // A heartbeat even when nothing changed: silence is what a caller reads
358
- // as a stall.
359
- if (Date.now() - lastHeartbeat < HEARTBEAT_MS)
360
- return;
361
- lastHeartbeat = Date.now();
362
- const counts = event.screens.reduce((totals, screen) => ({
363
- ...totals,
364
- [screen.status]: (totals[screen.status] ?? 0) + 1,
365
- }), {});
366
- write(`[${elapsed()}] ${event.phase}: ${narrateCounts([
367
- { label: 'complete', count: counts.succeeded ?? 0 },
368
- { label: 'generating', count: counts.dispatched ?? 0 },
369
- { label: 'waiting on dependencies', count: counts.pending ?? 0 },
370
- { label: 'blocked', count: counts.blocked ?? 0 },
371
- { label: 'failed', count: counts.failed ?? 0 },
372
- ])}`);
373
- return;
374
- }
375
- if (event.kind === 'phase') {
376
- write(`[${elapsed()}] ${event.phase}${event.detail ? `: ${event.detail}` : ''}`);
377
- return;
378
- }
379
- if (event.kind === 'package') {
380
- reportPackage(event.pageId, event.progress);
381
- return;
382
- }
383
- if (event.kind === 'blocked') {
384
- write(`[${elapsed()}] screen ${event.slot}: blocked — ${event.waitingOn} failed, so this screen`
385
- + ' can never run. It is terminal, not pending.');
386
- return;
387
- }
388
- if (event.kind === 'failed') {
389
- write(`[${elapsed()}] screen ${event.slot}: failed (${event.code})`);
390
- return;
391
- }
392
- if (event.kind === 'succeeded' || event.kind === 'dispatched' || event.kind === 'held' || event.kind === 'in-flight') {
393
- write(`[${elapsed()}] screen ${event.slot}: ${event.kind}`);
394
- return;
395
- }
396
- write(`[${elapsed()}] stopped: ${event.code} — ${event.message}`);
331
+ const estimate = runEstimate({
332
+ scope: inputs.scope,
333
+ convert: Boolean(inputs.convert),
334
+ concurrency: pageConcurrency,
335
+ });
336
+ const progress = createLongRunningProgress({
337
+ label: action === 'resume' ? 'branch resume' : 'branch execute',
338
+ typicalSeconds: estimate.ceiling,
339
+ quiet,
340
+ });
341
+ progress.brief({
342
+ request: `${action === 'resume' ? 'branch resume' : 'branch execute'}:`
343
+ + ` scope ${inputs.scope}${inputs.convert ? `, converting pages to ${inputs.convert.output}` : ''}`,
344
+ ...(resume
345
+ ? { free: 'already-settled screens replay free; only unfinished work continues' }
346
+ : {
347
+ paid: 'one branch screen per planned slot, plus one package conversion per exported page;'
348
+ + ' each complete app state is an exported page',
349
+ }),
350
+ done: `screens in ${outDir}/branch/screens${inputs.convert ? `, pages in ${outDir}/branch/pages` : ''}`,
351
+ expectation: {
352
+ typicalSeconds: estimate.ceiling,
353
+ basis: `measured phase medians; a run whose page conversions all overlap generation`
354
+ + ` finishes nearer ${Math.round(estimate.floor / 60)}m`,
397
355
  },
356
+ blocking: true,
357
+ });
358
+ progress.update({
359
+ stage: resume ? 'resuming' : 'claiming',
398
360
  });
361
+ let result;
362
+ try {
363
+ result = await executeBranchRun({
364
+ branchClient,
365
+ packageClient,
366
+ inputs,
367
+ origin: config.origin,
368
+ resume,
369
+ pageConcurrency,
370
+ onEvent: (event) => {
371
+ if (event.kind === 'progress') {
372
+ // The completion sentinel below owns the one terminal line. The
373
+ // orchestrator publishes its terminal phase just before returning;
374
+ // rendering that observation as an update says "running | stage
375
+ // complete" and then prints completion again.
376
+ if (event.phase === 'terminal')
377
+ return;
378
+ const counts = event.screens.reduce((totals, screen) => ({
379
+ ...totals,
380
+ [screen.status]: (totals[screen.status] ?? 0) + 1,
381
+ }), {});
382
+ progress.update({
383
+ stage: event.phase,
384
+ completed: counts.succeeded ?? 0,
385
+ total: event.screens.length,
386
+ unit: 'screens generated',
387
+ running: counts.dispatched ?? 0,
388
+ detail: `${counts.pending ?? 0} waiting, ${counts.blocked ?? 0} blocked,`
389
+ + ` ${counts.failed ?? 0} failed`,
390
+ });
391
+ return;
392
+ }
393
+ if (event.kind === 'phase') {
394
+ progress.update({
395
+ stage: event.phase,
396
+ ...(event.detail ? { detail: event.detail } : {}),
397
+ });
398
+ return;
399
+ }
400
+ if (event.kind === 'package') {
401
+ // A child package may be terminal while the branch that owns it is
402
+ // still live. Do not render the contradictory "running | stage
403
+ // succeeded" pair: publishing the child's artifacts is the current
404
+ // work from the branch caller's point of view.
405
+ const childTerminal = event.progress.stage === 'succeeded';
406
+ progress.update({
407
+ stage: childTerminal ? 'collecting' : event.progress.stage,
408
+ ...(event.progress.completed === undefined ? {} : {
409
+ completed: event.progress.completed,
410
+ total: event.progress.total,
411
+ unit: packageStageUnit(event.progress.stage),
412
+ }),
413
+ ...(event.progress.running === undefined ? {} : { running: event.progress.running }),
414
+ detail: `page ${event.pageId}`,
415
+ });
416
+ return;
417
+ }
418
+ if (event.kind === 'blocked') {
419
+ progress.update({
420
+ stage: 'dispatching',
421
+ detail: `screen ${event.slot} blocked by failed dependency ${event.waitingOn}`,
422
+ });
423
+ return;
424
+ }
425
+ if (event.kind === 'failed') {
426
+ progress.update({ stage: 'dispatching', detail: `screen ${event.slot} failed (${event.code})` });
427
+ return;
428
+ }
429
+ if (event.kind === 'succeeded' || event.kind === 'dispatched' || event.kind === 'held' || event.kind === 'in-flight') {
430
+ progress.update({ stage: 'dispatching', detail: `screen ${event.slot} ${event.kind}` });
431
+ return;
432
+ }
433
+ progress.update({ stage: 'stopped', detail: `${event.code}: ${event.message}` });
434
+ },
435
+ });
436
+ }
437
+ catch (error) {
438
+ // The CLI's outer error boundary prints the actionable failure once.
439
+ // Repeating it here after a structured terminal line is the same noise
440
+ // class as printing a success terminal twice.
441
+ progress.finish('stopped', {
442
+ next: `12ui branch resume ${outDir} continues this run, replaying settled screens free`,
443
+ });
444
+ throw error;
445
+ }
399
446
  // The completion sentinel names every screen and page; the journal names the
400
447
  // sentinel. A run is terminal here whatever its status: `partial` and
401
448
  // `failed` are settled answers, not states to keep polling.
@@ -409,6 +456,29 @@ export const runBranchCommand = async (action, flags, dependencies = {}) => {
409
456
  ],
410
457
  terminal: true,
411
458
  });
459
+ progress.finish(result.completion.status === 'succeeded' ? 'succeeded' : 'partial', {
460
+ ...(result.completion.status === 'succeeded'
461
+ ? {}
462
+ : {
463
+ detail: `${result.completion.failedCount} failed,`
464
+ + ` ${result.completion.blockedCount} blocked`,
465
+ }),
466
+ artifacts: [
467
+ {
468
+ name: `${result.completion.succeededCount} of ${result.completion.screenCount} screen(s)`,
469
+ state: 'generated',
470
+ path: `${result.completion.outDir}/branch/screens`,
471
+ },
472
+ ...result.completion.pages.map((page) => ({
473
+ name: `page ${page.id}`,
474
+ state: page.conversion?.status ?? 'not converted',
475
+ ...(page.conversion && 'outFile' in page.conversion && page.conversion.outFile
476
+ ? { path: String(page.conversion.outFile) }
477
+ : {}),
478
+ })),
479
+ ],
480
+ next: `completion record: ${result.completionPath}`,
481
+ });
412
482
  console.log(JSON.stringify({
413
483
  completionPath: result.completionPath,
414
484
  ...result.completion,