@12ui/design 0.2.13 → 0.2.14

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 (172) hide show
  1. package/README.md +35 -9
  2. package/dist/branch-client.d.ts +155 -0
  3. package/dist/branch-client.d.ts.map +1 -0
  4. package/dist/branch-client.js +179 -0
  5. package/dist/branch-client.js.map +1 -0
  6. package/dist/branch-completion.d.ts +37 -0
  7. package/dist/branch-completion.d.ts.map +1 -0
  8. package/dist/branch-completion.js +137 -0
  9. package/dist/branch-completion.js.map +1 -0
  10. package/dist/branch-dispatch-loop.d.ts +84 -0
  11. package/dist/branch-dispatch-loop.d.ts.map +1 -0
  12. package/dist/branch-dispatch-loop.js +206 -0
  13. package/dist/branch-dispatch-loop.js.map +1 -0
  14. package/dist/branch-downloads.d.ts +43 -0
  15. package/dist/branch-downloads.d.ts.map +1 -0
  16. package/dist/branch-downloads.js +94 -0
  17. package/dist/branch-downloads.js.map +1 -0
  18. package/dist/branch-execution-types.d.ts +54 -0
  19. package/dist/branch-execution-types.d.ts.map +1 -0
  20. package/dist/branch-execution-types.js +2 -0
  21. package/dist/branch-execution-types.js.map +1 -0
  22. package/dist/branch-execution.d.ts +18 -0
  23. package/dist/branch-execution.d.ts.map +1 -0
  24. package/dist/branch-execution.js +261 -0
  25. package/dist/branch-execution.js.map +1 -0
  26. package/dist/branch-identity.d.ts +71 -0
  27. package/dist/branch-identity.d.ts.map +1 -0
  28. package/dist/branch-identity.js +72 -0
  29. package/dist/branch-identity.js.map +1 -0
  30. package/dist/branch-materialize.d.ts +22 -0
  31. package/dist/branch-materialize.d.ts.map +1 -0
  32. package/dist/branch-materialize.js +47 -0
  33. package/dist/branch-materialize.js.map +1 -0
  34. package/dist/branch-page-conversion.d.ts +39 -0
  35. package/dist/branch-page-conversion.d.ts.map +1 -0
  36. package/dist/branch-page-conversion.js +206 -0
  37. package/dist/branch-page-conversion.js.map +1 -0
  38. package/dist/branch-plan.d.ts +63 -0
  39. package/dist/branch-plan.d.ts.map +1 -0
  40. package/dist/branch-plan.js +95 -0
  41. package/dist/branch-plan.js.map +1 -0
  42. package/dist/branch-progress.d.ts +75 -0
  43. package/dist/branch-progress.d.ts.map +1 -0
  44. package/dist/branch-progress.js +159 -0
  45. package/dist/branch-progress.js.map +1 -0
  46. package/dist/branch-run-record.d.ts +153 -0
  47. package/dist/branch-run-record.d.ts.map +1 -0
  48. package/dist/branch-run-record.js +94 -0
  49. package/dist/branch-run-record.js.map +1 -0
  50. package/dist/branch-schedule.d.ts +74 -0
  51. package/dist/branch-schedule.d.ts.map +1 -0
  52. package/dist/branch-schedule.js +130 -0
  53. package/dist/branch-schedule.js.map +1 -0
  54. package/dist/branch-status.d.ts +11 -0
  55. package/dist/branch-status.d.ts.map +1 -0
  56. package/dist/branch-status.js +115 -0
  57. package/dist/branch-status.js.map +1 -0
  58. package/dist/branch-viewport-normalization.d.ts +74 -0
  59. package/dist/branch-viewport-normalization.d.ts.map +1 -0
  60. package/dist/branch-viewport-normalization.js +120 -0
  61. package/dist/branch-viewport-normalization.js.map +1 -0
  62. package/dist/cli-arguments.d.ts.map +1 -1
  63. package/dist/cli-arguments.js +4 -0
  64. package/dist/cli-arguments.js.map +1 -1
  65. package/dist/cli-branch-command.d.ts +46 -0
  66. package/dist/cli-branch-command.d.ts.map +1 -0
  67. package/dist/cli-branch-command.js +426 -0
  68. package/dist/cli-branch-command.js.map +1 -0
  69. package/dist/cli-capabilities.d.ts +28 -0
  70. package/dist/cli-capabilities.d.ts.map +1 -1
  71. package/dist/cli-capabilities.js +29 -1
  72. package/dist/cli-capabilities.js.map +1 -1
  73. package/dist/cli-create-command.d.ts +21 -0
  74. package/dist/cli-create-command.d.ts.map +1 -0
  75. package/dist/cli-create-command.js +319 -0
  76. package/dist/cli-create-command.js.map +1 -0
  77. package/dist/cli-detach.d.ts +62 -0
  78. package/dist/cli-detach.d.ts.map +1 -0
  79. package/dist/cli-detach.js +123 -0
  80. package/dist/cli-detach.js.map +1 -0
  81. package/dist/cli-draft-command.d.ts +63 -0
  82. package/dist/cli-draft-command.d.ts.map +1 -0
  83. package/dist/cli-draft-command.js +220 -0
  84. package/dist/cli-draft-command.js.map +1 -0
  85. package/dist/cli-export-command.d.ts.map +1 -1
  86. package/dist/cli-export-command.js +2 -3
  87. package/dist/cli-export-command.js.map +1 -1
  88. package/dist/cli-image-batch-command.d.ts +21 -0
  89. package/dist/cli-image-batch-command.d.ts.map +1 -1
  90. package/dist/cli-image-batch-command.js +65 -4
  91. package/dist/cli-image-batch-command.js.map +1 -1
  92. package/dist/cli-image-batch-resume.d.ts +7 -0
  93. package/dist/cli-image-batch-resume.d.ts.map +1 -1
  94. package/dist/cli-image-batch-resume.js +19 -2
  95. package/dist/cli-image-batch-resume.js.map +1 -1
  96. package/dist/cli-package-command.d.ts +18 -0
  97. package/dist/cli-package-command.d.ts.map +1 -0
  98. package/dist/cli-package-command.js +112 -0
  99. package/dist/cli-package-command.js.map +1 -0
  100. package/dist/cli-progress.d.ts +61 -0
  101. package/dist/cli-progress.d.ts.map +1 -1
  102. package/dist/cli-progress.js +53 -0
  103. package/dist/cli-progress.js.map +1 -1
  104. package/dist/cli-select-command.d.ts +12 -0
  105. package/dist/cli-select-command.d.ts.map +1 -0
  106. package/dist/cli-select-command.js +66 -0
  107. package/dist/cli-select-command.js.map +1 -0
  108. package/dist/cli.js +140 -7
  109. package/dist/cli.js.map +1 -1
  110. package/dist/create-identity.d.ts +25 -0
  111. package/dist/create-identity.d.ts.map +1 -0
  112. package/dist/create-identity.js +0 -0
  113. package/dist/create-identity.js.map +1 -0
  114. package/dist/draft-identity.d.ts +30 -0
  115. package/dist/draft-identity.d.ts.map +1 -0
  116. package/dist/draft-identity.js +0 -0
  117. package/dist/draft-identity.js.map +1 -0
  118. package/dist/draft-prompts.d.ts +35 -0
  119. package/dist/draft-prompts.d.ts.map +1 -0
  120. package/dist/draft-prompts.js +51 -0
  121. package/dist/draft-prompts.js.map +1 -0
  122. package/dist/draft-run.d.ts +32 -0
  123. package/dist/draft-run.d.ts.map +1 -0
  124. package/dist/draft-run.js +152 -0
  125. package/dist/draft-run.js.map +1 -0
  126. package/dist/draft-workspace.d.ts +90 -0
  127. package/dist/draft-workspace.d.ts.map +1 -0
  128. package/dist/draft-workspace.js +64 -0
  129. package/dist/draft-workspace.js.map +1 -0
  130. package/dist/image-batch-status.d.ts +42 -0
  131. package/dist/image-batch-status.d.ts.map +1 -0
  132. package/dist/image-batch-status.js +142 -0
  133. package/dist/image-batch-status.js.map +1 -0
  134. package/dist/image-dimensions.d.ts +12 -0
  135. package/dist/image-dimensions.d.ts.map +1 -0
  136. package/dist/image-dimensions.js +14 -0
  137. package/dist/image-dimensions.js.map +1 -0
  138. package/dist/image-generation-resume.d.ts +13 -0
  139. package/dist/image-generation-resume.d.ts.map +1 -1
  140. package/dist/image-generation-resume.js +13 -0
  141. package/dist/image-generation-resume.js.map +1 -1
  142. package/dist/index.d.ts +5 -0
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js +4 -0
  145. package/dist/index.js.map +1 -1
  146. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  147. package/dist/legacy-skill-catalog.js +115 -0
  148. package/dist/legacy-skill-catalog.js.map +1 -1
  149. package/dist/package-manifest-file.d.ts +21 -0
  150. package/dist/package-manifest-file.d.ts.map +1 -0
  151. package/dist/package-manifest-file.js +119 -0
  152. package/dist/package-manifest-file.js.map +1 -0
  153. package/dist/package-manifest-template.d.ts +23 -0
  154. package/dist/package-manifest-template.d.ts.map +1 -0
  155. package/dist/package-manifest-template.js +60 -0
  156. package/dist/package-manifest-template.js.map +1 -0
  157. package/dist/package-submission.d.ts +103 -0
  158. package/dist/package-submission.d.ts.map +1 -0
  159. package/dist/package-submission.js +173 -0
  160. package/dist/package-submission.js.map +1 -0
  161. package/dist/selection-record.d.ts +95 -0
  162. package/dist/selection-record.d.ts.map +1 -0
  163. package/dist/selection-record.js +121 -0
  164. package/dist/selection-record.js.map +1 -0
  165. package/package.json +1 -1
  166. package/skills/design/SKILL.md +40 -266
  167. package/skills/design-branch/SKILL.md +36 -116
  168. package/skills/design-convert/SKILL.md +62 -148
  169. package/skills/design-draft/SKILL.md +71 -135
  170. package/skills/design-search/SKILL.md +29 -78
  171. package/skills/design/references/continuation-contract.md +0 -60
  172. package/skills/design/references/selection-contract.md +0 -112
@@ -0,0 +1,112 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { booleanFlag, stringFlag } from './cli-arguments.js';
4
+ import { readConversionConfig } from './config.js';
5
+ import { conversionPackageKey } from './branch-identity.js';
6
+ import { normalizeOptionalIdempotencyKey } from './idempotency-key.js';
7
+ import { TwelveUiConversionPackageClient } from './package-client.js';
8
+ import { readLocalPackageManifest } from './package-manifest-file.js';
9
+ import { PACKAGE_RESULT_FILENAME, submitConversionPackage, writePackageResultRecord, } from './package-submission.js';
10
+ import { formatDuration, nextActionLine } from './cli-progress.js';
11
+ /**
12
+ * `12ui convert package` — the ordered-viewport submission that had no CLI at
13
+ * all. Without it the terminal step of the branch path was the least supported
14
+ * operation in the product, and an agent that got that far fell back to
15
+ * per-image conversion, losing page order and stitching.
16
+ */
17
+ export const PACKAGE_USAGE = 'Usage: 12ui convert package --manifest <package.json>'
18
+ + ' --out-dir <directory> [--idempotency-key <key>] [--timeout-ms <ms>] [--wait] [--quiet]'
19
+ + '\n 12ui convert package --template > package.json';
20
+ /** A multi-viewport page converts its viewports in parallel, then composes. */
21
+ export const PACKAGE_DURATION_SECONDS = 360;
22
+ const parseTimeoutMs = (value) => {
23
+ if (value === undefined)
24
+ return undefined;
25
+ const timeoutMs = Number(value);
26
+ if (!Number.isFinite(timeoutMs) || timeoutMs < 1_000) {
27
+ throw new Error('--timeout-ms must be a number of at least 1000');
28
+ }
29
+ return Math.floor(timeoutMs);
30
+ };
31
+ const refuseExistingResult = async (outDir) => {
32
+ const existing = path.join(outDir, PACKAGE_RESULT_FILENAME);
33
+ try {
34
+ await stat(existing);
35
+ }
36
+ catch (error) {
37
+ if (error.code === 'ENOENT')
38
+ return;
39
+ throw error;
40
+ }
41
+ throw new Error(`A package result already exists at ${existing}. It names the package id and every page's`
42
+ + ' conversion id — read it back rather than submitting the same pages again, or choose a'
43
+ + ' new --out-dir if you genuinely want another package.');
44
+ };
45
+ export const runPackageCommand = async (flags, dependencies = {}) => {
46
+ const manifestFlag = stringFlag(flags, 'manifest')?.trim();
47
+ const outDirFlag = stringFlag(flags, 'out-dir')?.trim();
48
+ if (!manifestFlag || !outDirFlag)
49
+ throw new Error(PACKAGE_USAGE);
50
+ const manifestPath = path.resolve(manifestFlag);
51
+ const outDir = path.resolve(outDirFlag);
52
+ const quiet = booleanFlag(flags, 'quiet');
53
+ await refuseExistingResult(outDir);
54
+ const manifest = await readLocalPackageManifest(manifestPath);
55
+ const idempotencyKey = normalizeOptionalIdempotencyKey(stringFlag(flags, 'idempotency-key'), '--idempotency-key') ?? conversionPackageKey({
56
+ manifestSha256: manifest.manifestSha256,
57
+ output: manifest.output,
58
+ });
59
+ const config = (dependencies.readConfig ?? readConversionConfig)({
60
+ origin: stringFlag(flags, 'origin'),
61
+ apiKey: stringFlag(flags, 'api-key'),
62
+ });
63
+ const client = (dependencies.createClient ?? ((value) => (new TwelveUiConversionPackageClient(value))))(config);
64
+ const viewportCount = manifest.pages.reduce((total, page) => total + page.viewports.length, 0);
65
+ if (!quiet) {
66
+ process.stderr.write(`12ui convert package — ${manifest.pages.length} page(s), ${viewportCount} viewport(s)`
67
+ + ` to ${manifest.output}; expect about ${formatDuration(PACKAGE_DURATION_SECONDS)}\n`);
68
+ }
69
+ const startedAt = Date.now();
70
+ const result = await submitConversionPackage({
71
+ client,
72
+ outDir,
73
+ submission: {
74
+ output: manifest.output,
75
+ ...(manifest.model ? { model: manifest.model } : {}),
76
+ ...(manifest.responsiveQuality ? { responsiveQuality: manifest.responsiveQuality } : {}),
77
+ pages: manifest.pages,
78
+ idempotencyKey,
79
+ },
80
+ ...(parseTimeoutMs(stringFlag(flags, 'timeout-ms')) === undefined
81
+ ? {}
82
+ : { timeoutMs: parseTimeoutMs(stringFlag(flags, 'timeout-ms')) }),
83
+ onSubmitted: quiet
84
+ ? undefined
85
+ : (packageId) => {
86
+ process.stderr.write(`12ui convert package ${packageId} submitted.\n${nextActionLine({
87
+ what: 'A multi-viewport page conversion',
88
+ typicalSeconds: PACKAGE_DURATION_SECONDS,
89
+ statusCommand: `GET /api/v1/convert/package/${packageId}`,
90
+ waitHint: 'or leave this command running, which is what --wait already does by default',
91
+ })}\n`);
92
+ },
93
+ onProgress: quiet
94
+ ? undefined
95
+ : (event) => {
96
+ const elapsed = formatDuration((Date.now() - startedAt) / 1000);
97
+ const percent = event.percent === undefined ? '' : ` ${event.percent}%`;
98
+ process.stderr.write(`[${elapsed}] package: ${event.stage}${percent}\n`);
99
+ },
100
+ });
101
+ const resultPath = await writePackageResultRecord(outDir, result);
102
+ const reported = { ...result, resultPath };
103
+ console.log(JSON.stringify({ manifestPath, outDir, ...reported }, null, 2));
104
+ const failed = reported.pages.filter((page) => page.status === 'failed');
105
+ if (failed.length > 0) {
106
+ throw new Error(`Package ${reported.packageId} converted ${reported.pages.length - failed.length} of`
107
+ + ` ${reported.pages.length} page(s). Failed: ${failed.map((page) => page.id).join(', ')}.`
108
+ + ` Evidence: ${resultPath}`);
109
+ }
110
+ return reported;
111
+ };
112
+ //# sourceMappingURL=cli-package-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-package-command.js","sourceRoot":"","sources":["../src/cli-package-command.ts"],"names":[],"mappings":"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"}
@@ -20,8 +20,69 @@ export declare const CONVERSION_DURATION_HINTS: {
20
20
  readonly fused: 300;
21
21
  };
22
22
  export type ConversionDurationHintKind = keyof typeof CONVERSION_DURATION_HINTS;
23
+ /**
24
+ * Every long operation's typical wall time, in one place, so a status line, a
25
+ * skill sentence, and a capability document can never quote three different
26
+ * numbers for the same wait.
27
+ */
28
+ export declare const OPERATION_DURATION_HINTS: {
29
+ /** One generated candidate from the local image provider. */
30
+ readonly imageCandidate: 90;
31
+ /** Four candidates, started concurrently. */
32
+ readonly imageBatch: 90;
33
+ /** The build claim: the planner runs inline and buys no image. */
34
+ readonly branchClaim: 15;
35
+ /** One branch screen. The server's own provider budget is 150 s. */
36
+ readonly branchScreen: 90;
37
+ readonly branchScreenBudget: 150;
38
+ /** A whole `--scope page` run: serial trunk continuations plus one package. */
39
+ readonly branchPage: 720;
40
+ /** A whole `--scope site` run: several pages, one package each. */
41
+ readonly branchSite: 1200;
42
+ /** One package conversion of a multi-viewport page to responsive HTML. */
43
+ readonly package: 360;
44
+ /** image -> LayerDoc. Extraction plus materialization. */
45
+ readonly convert: 240;
46
+ /** A responsive HTML export run on its own, after the conversion finished. */
47
+ readonly export: 240;
48
+ /**
49
+ * Fused convert + export. The export's reference and anchor conversions run
50
+ * alongside the conversion, so the bundle costs about the slower half plus
51
+ * assembly rather than the sum of both.
52
+ */
53
+ readonly fused: 300;
54
+ };
55
+ export type OperationDurationHintKind = keyof typeof OPERATION_DURATION_HINTS;
23
56
  export declare const formatDuration: (seconds: number) => string;
24
57
  export declare const durationHint: (kind: ConversionDurationHintKind) => string;
58
+ /**
59
+ * `45s elapsed, ~90s typical`. A bare elapsed time reads as a stall; the pair
60
+ * is what tells a caller the wait is still inside the expected envelope.
61
+ */
62
+ export declare const elapsedAgainstTypical: (elapsedSeconds: number, typicalSeconds: number) => string;
63
+ /**
64
+ * THE mandatory closing line of any output that is not yet terminal.
65
+ *
66
+ * A poll surface that answers with bare absence is what makes a model conclude
67
+ * the process stalled and improvise around it. Every not-yet-done response ends
68
+ * by naming the typical duration, the exact command that narrates progress, and
69
+ * the blocking alternative — so the caller can sleep, schedule, or block
70
+ * according to what it can actually do.
71
+ */
72
+ export declare const nextActionLine: (args: {
73
+ what: string;
74
+ typicalSeconds: number;
75
+ statusCommand: string;
76
+ checkAgainSeconds?: number;
77
+ waitHint?: string;
78
+ }) => string;
79
+ /** `3 complete, 2 generating, 4 waiting, 0 blocked` — zeros included on purpose. */
80
+ export declare const narrateCounts: (counts: readonly {
81
+ label: string;
82
+ count: number;
83
+ detail?: string;
84
+ }[]) => string;
85
+ export declare const secondsSince: (iso: string | undefined, now: number) => number | undefined;
25
86
  export declare const stageLabel: (stage: string) => string;
26
87
  export type ProgressReporter = {
27
88
  onProgress: (operation: ConversionOperation) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"cli-progress.d.ts","sourceRoot":"","sources":["../src/cli-progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB;IACpC,0DAA0D;;IAE1D,8EAA8E;;IAE9E;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,MAAM,OAAO,yBAAyB,CAAC;AAEhF,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAMhD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,0BAA0B,KAAG,MAE/D,CAAC;AAsBF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAAsC,CAAC;AAElF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACrD,2CAA2C;IAC3C,IAAI,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,KAAG,gBAsBH,CAAC"}
1
+ {"version":3,"file":"cli-progress.d.ts","sourceRoot":"","sources":["../src/cli-progress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAElE;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB;IACpC,0DAA0D;;IAE1D,8EAA8E;;IAE9E;;;;OAIG;;CAEK,CAAC;AAEX,MAAM,MAAM,0BAA0B,GAAG,MAAM,OAAO,yBAAyB,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;IAEnC,6DAA6D;;IAE7D,6CAA6C;;IAE7C,kEAAkE;;IAElE,oEAAoE;;;IAGpE,+EAA+E;;IAE/E,mEAAmE;;IAEnE,0EAA0E;;IAlC1E,0DAA0D;;IAE1D,8EAA8E;;IAE9E;;;;OAIG;;CA4BK,CAAC;AAEX,MAAM,MAAM,yBAAyB,GAAG,MAAM,OAAO,wBAAwB,CAAC;AAE9E,eAAO,MAAM,cAAc,GAAI,SAAS,MAAM,KAAG,MAMhD,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,MAAM,0BAA0B,KAAG,MAE/D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,GAChC,gBAAgB,MAAM,EACtB,gBAAgB,MAAM,KACrB,MAEF,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KAAG,MAKH,CAAC;AAEF,oFAAoF;AACpF,eAAO,MAAM,aAAa,GACxB,QAAQ,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KACnE,MAEU,CAAC;AAEd,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,GAAG,SAAS,EAAE,KAAK,MAAM,KAAG,MAAM,GAAG,SAI5E,CAAC;AAsBF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,KAAG,MAAsC,CAAC;AAElF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACrD,2CAA2C;IAC3C,IAAI,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAChD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,MAAM;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB,KAAG,gBAsBH,CAAC"}
@@ -18,6 +18,29 @@ export const CONVERSION_DURATION_HINTS = {
18
18
  */
19
19
  fused: 300,
20
20
  };
21
+ /**
22
+ * Every long operation's typical wall time, in one place, so a status line, a
23
+ * skill sentence, and a capability document can never quote three different
24
+ * numbers for the same wait.
25
+ */
26
+ export const OPERATION_DURATION_HINTS = {
27
+ ...CONVERSION_DURATION_HINTS,
28
+ /** One generated candidate from the local image provider. */
29
+ imageCandidate: 90,
30
+ /** Four candidates, started concurrently. */
31
+ imageBatch: 90,
32
+ /** The build claim: the planner runs inline and buys no image. */
33
+ branchClaim: 15,
34
+ /** One branch screen. The server's own provider budget is 150 s. */
35
+ branchScreen: 90,
36
+ branchScreenBudget: 150,
37
+ /** A whole `--scope page` run: serial trunk continuations plus one package. */
38
+ branchPage: 720,
39
+ /** A whole `--scope site` run: several pages, one package each. */
40
+ branchSite: 1_200,
41
+ /** One package conversion of a multi-viewport page to responsive HTML. */
42
+ package: 360,
43
+ };
21
44
  export const formatDuration = (seconds) => {
22
45
  const whole = Math.max(0, Math.round(seconds));
23
46
  if (whole < 90)
@@ -27,6 +50,36 @@ export const formatDuration = (seconds) => {
27
50
  return rest === 0 ? `${minutes}m` : `${minutes}m ${rest}s`;
28
51
  };
29
52
  export const durationHint = (kind) => (`expect about ${formatDuration(CONVERSION_DURATION_HINTS[kind])}`);
53
+ /**
54
+ * `45s elapsed, ~90s typical`. A bare elapsed time reads as a stall; the pair
55
+ * is what tells a caller the wait is still inside the expected envelope.
56
+ */
57
+ export const elapsedAgainstTypical = (elapsedSeconds, typicalSeconds) => (`${formatDuration(elapsedSeconds)} elapsed, ~${formatDuration(typicalSeconds)} typical`);
58
+ /**
59
+ * THE mandatory closing line of any output that is not yet terminal.
60
+ *
61
+ * A poll surface that answers with bare absence is what makes a model conclude
62
+ * the process stalled and improvise around it. Every not-yet-done response ends
63
+ * by naming the typical duration, the exact command that narrates progress, and
64
+ * the blocking alternative — so the caller can sleep, schedule, or block
65
+ * according to what it can actually do.
66
+ */
67
+ export const nextActionLine = (args) => {
68
+ const checkAgain = formatDuration(args.checkAgainSeconds ?? Math.max(30, Math.round(args.typicalSeconds / 3)));
69
+ const wait = args.waitHint ?? 'or re-run the command with --wait to block until it finishes';
70
+ return `${args.what} typically takes about ${formatDuration(args.typicalSeconds)}.`
71
+ + ` Check again in ${checkAgain} with \`${args.statusCommand}\`, ${wait}.`;
72
+ };
73
+ /** `3 complete, 2 generating, 4 waiting, 0 blocked` — zeros included on purpose. */
74
+ export const narrateCounts = (counts) => counts
75
+ .map((entry) => `${entry.count} ${entry.label}${entry.detail ? ` (${entry.detail})` : ''}`)
76
+ .join(', ');
77
+ export const secondsSince = (iso, now) => {
78
+ if (!iso)
79
+ return undefined;
80
+ const started = Date.parse(iso);
81
+ return Number.isFinite(started) ? Math.max(0, (now - started) / 1000) : undefined;
82
+ };
30
83
  /** Human-readable name for a pipeline stage, for progress lines. */
31
84
  const STAGE_LABELS = {
32
85
  queued: 'queued',
@@ -1 +1 @@
1
- {"version":3,"file":"cli-progress.js","sourceRoot":"","sources":["../src/cli-progress.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-progress.js","sourceRoot":"","sources":["../src/cli-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type CliFlags } from './cli-arguments.js';
2
+ /**
3
+ * `12ui select` — the choice, recorded.
4
+ *
5
+ * The judgement stays the model's: it has to look at four images and say which
6
+ * one and why. Assembling the evidence around that judgement does not, and used
7
+ * to be a contract the skill asked an agent to fill in from four other files by
8
+ * hand.
9
+ */
10
+ export declare const SELECT_USAGE: string;
11
+ export declare const runSelectCommand: (runDirArgument: string | undefined, flags: CliFlags) => Promise<void>;
12
+ //# sourceMappingURL=cli-select-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-select-command.d.ts","sourceRoot":"","sources":["../src/cli-select-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAQ/D;;;;;;;GAOG;AAEH,eAAO,MAAM,YAAY,QAC4D,CAAC;AAWtF,eAAO,MAAM,gBAAgB,GAC3B,gBAAgB,MAAM,GAAG,SAAS,EAClC,OAAO,QAAQ,KACd,OAAO,CAAC,IAAI,CA8Cd,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { stringFlag } from './cli-arguments.js';
2
+ import { draftPaths, readDraftRecord } from './draft-workspace.js';
3
+ import { buildSelectionRecord, readSelectionRecord, writeSelectionRecord, } from './selection-record.js';
4
+ /**
5
+ * `12ui select` — the choice, recorded.
6
+ *
7
+ * The judgement stays the model's: it has to look at four images and say which
8
+ * one and why. Assembling the evidence around that judgement does not, and used
9
+ * to be a contract the skill asked an agent to fill in from four other files by
10
+ * hand.
11
+ */
12
+ export const SELECT_USAGE = 'Usage: 12ui select <run-dir> --winner <id> --reason <text>'
13
+ + ' [--recommended <id>] [--recommendation-source <text>] [--reject <id>=<reason>]';
14
+ /** `--reject B=too generic --reject C=illegible headline` */
15
+ const parseRejections = (flags) => {
16
+ const raw = stringFlag(flags, 'reject');
17
+ if (!raw)
18
+ return {};
19
+ const separator = raw.indexOf('=');
20
+ if (separator <= 0)
21
+ throw new Error('--reject must be <candidate-id>=<reason>');
22
+ return { [raw.slice(0, separator).trim()]: [raw.slice(separator + 1).trim()] };
23
+ };
24
+ export const runSelectCommand = async (runDirArgument, flags) => {
25
+ if (!runDirArgument)
26
+ throw new Error(SELECT_USAGE);
27
+ const winner = stringFlag(flags, 'winner')?.trim();
28
+ const reason = stringFlag(flags, 'reason')?.trim();
29
+ if (!winner || !reason)
30
+ throw new Error(SELECT_USAGE);
31
+ const paths = draftPaths(runDirArgument);
32
+ const draft = await readDraftRecord(paths.draftRecord);
33
+ if (!draft) {
34
+ throw new Error(`No draft run in ${paths.runDir} — there is nothing to select from, and nothing has failed.`
35
+ + ' Start one with `12ui draft --query "<product, audience, surface, goal, personality>"`.');
36
+ }
37
+ const existing = await readSelectionRecord(paths.selection);
38
+ if (existing) {
39
+ throw new Error(`A selection already exists at ${paths.selection}: candidate ${existing.winner}. Read it`
40
+ + ' rather than choosing again, or start a new draft to explore other directions.');
41
+ }
42
+ const recommended = stringFlag(flags, 'recommended')?.trim();
43
+ const record = await buildSelectionRecord({
44
+ draft,
45
+ winner,
46
+ reason,
47
+ recommendation: {
48
+ candidateId: recommended ?? null,
49
+ source: recommended ? stringFlag(flags, 'recommendation-source')?.trim() ?? 'run' : null,
50
+ },
51
+ rejectionReasons: parseRejections(flags),
52
+ });
53
+ await writeSelectionRecord(paths.selection, record);
54
+ console.log(JSON.stringify({
55
+ runDir: paths.runDir,
56
+ selection: paths.selection,
57
+ winner: record.winner,
58
+ winnerPath: record.candidates.find((candidate) => candidate.id === record.winner)?.path,
59
+ selectionSource: record.selectionSource,
60
+ nextAction: `Convert the winner alone with \`12ui convert ${paths.candidatesDir}/${record.winner}.png`
61
+ + ' --export html`, or grow the whole surface with'
62
+ + ` \`12ui branch execute ${paths.runDir} --concept "<what the rest must cover>"`
63
+ + ' --scope page|site --convert html`.',
64
+ }, null, 2));
65
+ };
66
+ //# sourceMappingURL=cli-select-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-select-command.js","sourceRoot":"","sources":["../src/cli-select-command.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -1,19 +1,28 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFile, writeFile } from 'node:fs/promises';
3
3
  import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
4
5
  import { materializeConversionArtifacts } from './artifact-materializer.js';
5
6
  import { booleanFlag, parseCliArguments, stringFlag, } from './cli-arguments.js';
6
7
  import { runAuthCommand } from './cli-auth-command.js';
8
+ import { runBranchCommand } from './cli-branch-command.js';
7
9
  import { CLI_CAPABILITIES } from './cli-capabilities.js';
8
10
  import { runCliCommand } from './cli-cli-command.js';
9
11
  import { runCorpusCommand } from './cli-corpus-command.js';
10
12
  import { runExportCommand } from './cli-export-command.js';
11
- import { runImageBatchCommand } from './cli-image-batch-command.js';
13
+ import { runImageBatchCommand, runImageBatchStatusCommand, } from './cli-image-batch-command.js';
12
14
  import { runImageCommand } from './cli-image-command.js';
15
+ import { runCreateCommand } from './cli-create-command.js';
16
+ import { runPackageCommand } from './cli-package-command.js';
17
+ import { PACKAGE_MANIFEST_TEMPLATE_NOTES, renderPackageManifestTemplate, } from './package-manifest-template.js';
13
18
  import { runSkillCommand } from './cli-skill-command.js';
14
19
  import { isConversionModel } from './conversion-models.js';
15
20
  import { TwelveUiConversionClient, } from './conversion-client.js';
16
- import { createProgressReporter, durationHint } from './cli-progress.js';
21
+ import { detachBranchRun, detachImageBatch } from './cli-detach.js';
22
+ import { runDraftCommand, runDraftStatusCommand } from './cli-draft-command.js';
23
+ import { runSelectCommand } from './cli-select-command.js';
24
+ import { resolveBranchDirectory } from './cli-branch-command.js';
25
+ import { CONVERSION_DURATION_HINTS, OPERATION_DURATION_HINTS, createProgressReporter, durationHint, nextActionLine, } from './cli-progress.js';
17
26
  import { CONVERSION_OUTPUTS, isConversionOutput } from './conversion-outputs.js';
18
27
  import { readConversionConfig } from './config.js';
19
28
  import { classifyLocalConversionInput, createInputForLocalFile, defaultConversionOutputPath, } from './local-conversion-input.js';
@@ -37,10 +46,23 @@ const usage = (exitCode = 1) => {
37
46
  12ui corpus inspire --query <text>|--query-file <file> --out-dir <directory> [--mode direct|balanced|adventurer] [--count <1-48>] [--reference-image <png|jpeg|webp>] [--idempotency-key <key>] [--origin <url>] [--api-key <key>]
38
47
  12ui corpus resume --out-dir <directory> [--origin <url>] [--api-key <key>]
39
48
  12ui image generate --prompt <text>|--prompt-file <file> --reference <file> --out <file.png> [--aspect landscape|portrait|square] [--reference-mode inspiration|preserve-structure] [--provider auto|codex|openai] --project-root <directory> --idempotency-key <key>
40
- 12ui image generate-batch --manifest <batch.json> [--resume]
49
+ 12ui draft --query <text> [--redesign-source <png>] [--mode exploratory|reskin] [--aspect landscape|portrait|square] [--provider auto|codex|openai] [--project-root <directory>] [--wait] [--quiet] [--origin <url>] [--api-key <key>]
50
+ 12ui draft status <run-dir> [--json]
51
+ 12ui select <run-dir> --winner <id> --reason <text> [--recommended <id>] [--recommendation-source <text>] [--reject <id>=<reason>]
52
+ 12ui create claim --concept <text>|--concept-file <file> --candidates <json>|@<file> [--aspect landscape|portrait|square] [--mode inspiration|preserve-structure] [--reference-image <png|jpeg|webp>] [--idempotency-key <key>] [--origin <url>] [--api-key <key>]
53
+ 12ui create dispatch <run-id> [--slot <a,b,...>] [--quiet] [--origin <url>] [--api-key <key>]
54
+ 12ui create status <run-id> [--json] [--origin <url>] [--api-key <key>]
55
+ 12ui create download <run-id> --out-dir <directory> [--slot <a,b,...>] [--origin <url>] [--api-key <key>]
56
+ 12ui image generate-batch --manifest <batch.json> [--resume] [--wait] [--quiet]
57
+ 12ui image batch-status --manifest <batch.json> [--json]
58
+ 12ui branch execute <run-dir> --concept <text>|--concept-file <file> --scope page|site [--convert html] [--convert-model fast|standard|pro] [--convert-quality standard|pro] [--winner-image <file>|--winner-run <crt-id> --winner-slot <slot>] [--source-conversion-id <id>] [--max-screens <n>] [--idempotency-key <key>] [--out-dir <directory>] [--resume] [--dry-run] [--wait] [--quiet] [--origin <url>] [--api-key <key>]
59
+ 12ui branch resume <run-dir> [--quiet] [--origin <url>] [--api-key <key>]
60
+ 12ui branch status <run-dir> [--json] [--origin <url>] [--api-key <key>]
41
61
  12ui capabilities [--json]
42
62
  12ui convert <image.png|jpg|webp|layerdoc.json> --output ${outputs} [--model fast|standard|pro] [--width <px>] [--export html] [--export-quality standard|pro] [--export-out <file>] [--responsive-quality standard|pro] [--profile <json|file>] [--out <file>] [--detach] [--quiet] [--timeout-ms <ms>] [--idempotency-key <key>] [--origin <url>] [--api-key <key>]
43
- 12ui export <source-conversion-id> --output <comma-separated-formats> --out-dir <directory> --idempotency-key <key> [--responsive-quality standard|pro] [--web-profile <json|file>] [--app-profile <json|file>] [--timeout-ms <ms>] [--origin <url>] [--api-key <key>]
63
+ 12ui convert package --manifest <package.json> --out-dir <directory> [--idempotency-key <key>] [--timeout-ms <ms>] [--wait] [--quiet] [--origin <url>] [--api-key <key>]
64
+ 12ui convert package --template
65
+ 12ui export <source-conversion-id> --output <comma-separated-formats> --out-dir <directory> [--idempotency-key <key>] [--responsive-quality standard|pro] [--web-profile <json|file>] [--app-profile <json|file>] [--timeout-ms <ms>] [--origin <url>] [--api-key <key>]
44
66
  12ui resume <conversion-id> --output ${outputs} --out <file> [--timeout-ms <ms>] [--origin <url>] [--api-key <key>]
45
67
  12ui mcp [--origin <url>] [--api-key <key>]
46
68
  12ui --version
@@ -50,9 +72,23 @@ export runs alongside the conversion, so the pair finishes in about the time of
50
72
  the conversion alone (~5m) instead of ~8m. Progress goes to stderr; --quiet
51
73
  silences it.
52
74
 
75
+ \`branch execute\`, \`branch resume\` and \`image generate-batch\` START the work and
76
+ return: the run continues in its own process group and survives the shell that
77
+ launched it. Follow it with \`12ui branch status --out-dir <dir>\` or
78
+ \`12ui image batch-status --manifest <file>\`; both always report what is moving
79
+ and what to do next. Add --wait to block in this shell instead. Never list an
80
+ output directory to decide whether work is still running.
81
+
53
82
  Omit --client to discover and target every supported CLI installation.`);
54
83
  process.exit(exitCode);
55
84
  };
85
+ /** This file, as the worker re-executes it. */
86
+ const CLI_PATH = fileURLToPath(import.meta.url);
87
+ /**
88
+ * Long dispatches detach by default. `--wait` keeps the work in this shell for
89
+ * a human at a terminal; `--dry-run` never starts anything to detach from.
90
+ */
91
+ const detaches = (flags) => (!booleanFlag(flags, 'wait') && !booleanFlag(flags, 'dry-run'));
56
92
  const parseTimeoutMs = (value) => {
57
93
  if (value === undefined)
58
94
  return undefined;
@@ -108,6 +144,21 @@ const printVersion = async () => {
108
144
  };
109
145
  const runConversionCommand = async (command, flags) => {
110
146
  const verb = command[0];
147
+ // The hosted candidate API as commands: claim, dispatch, status, download.
148
+ if (verb === 'create') {
149
+ await runCreateCommand(command, flags);
150
+ return;
151
+ }
152
+ // Ordered viewports of one page are ONE package conversion, not N converts.
153
+ if (verb === 'convert' && command[1] === 'package') {
154
+ if (booleanFlag(flags, 'template')) {
155
+ process.stderr.write(`${PACKAGE_MANIFEST_TEMPLATE_NOTES}\n`);
156
+ process.stdout.write(renderPackageManifestTemplate());
157
+ return;
158
+ }
159
+ await runPackageCommand(flags);
160
+ return;
161
+ }
111
162
  const config = readConversionConfig({
112
163
  origin: stringFlag(flags, 'origin'),
113
164
  apiKey: stringFlag(flags, 'api-key'),
@@ -116,7 +167,11 @@ const runConversionCommand = async (command, flags) => {
116
167
  await startMcpServer({ config });
117
168
  return;
118
169
  }
119
- const outputValue = stringFlag(flags, 'output');
170
+ // `12ui convert <image> --export html` is the whole command for a single
171
+ // screen. The export is derived from a LayerDoc conversion, so asking for the
172
+ // output as well is asking the caller to restate the only value it can have.
173
+ const outputValue = stringFlag(flags, 'output')
174
+ ?? (stringFlag(flags, 'export') !== undefined ? 'layerdoc' : undefined);
120
175
  const output = isConversionOutput(outputValue) ? outputValue : usage();
121
176
  const client = new TwelveUiConversionClient(config);
122
177
  const timeoutMs = parseTimeoutMs(stringFlag(flags, 'timeout-ms'));
@@ -236,19 +291,34 @@ const runConversionCommand = async (command, flags) => {
236
291
  waitSeconds: detach ? 0 : 20,
237
292
  });
238
293
  if (detach) {
294
+ const resumeCommand = `12ui resume ${created.id} --output ${output} --out <file>`;
239
295
  console.log(JSON.stringify({
240
296
  id: created.id,
241
297
  status: created.status,
242
298
  output: created.output,
243
299
  ...(created.export ? { export: created.export } : {}),
244
300
  expiresAt: created.expires_at,
301
+ // A detached operation is the one case with nothing streaming, so the
302
+ // response has to say how long it takes and how to collect it.
303
+ nextAction: nextActionLine({
304
+ what: 'A conversion',
305
+ typicalSeconds: CONVERSION_DURATION_HINTS[created.export ? 'fused' : 'convert'],
306
+ statusCommand: resumeCommand,
307
+ waitHint: 'which blocks until it finishes and writes the result',
308
+ }),
245
309
  }, null, 2));
246
310
  return;
247
311
  }
248
312
  const exportOperationId = created.export?.conversion_id ?? null;
249
313
  if (!quiet) {
250
314
  process.stderr.write(`12ui convert ${created.id}${exportOperationId ? ` (+ export ${exportOperationId})` : ''}`
251
- + ` — ${durationHint(exportOperationId ? 'fused' : 'convert')}\n`);
315
+ + ` — ${durationHint(exportOperationId ? 'fused' : 'convert')}\n`
316
+ + `${nextActionLine({
317
+ what: 'A conversion',
318
+ typicalSeconds: CONVERSION_DURATION_HINTS[exportOperationId ? 'fused' : 'convert'],
319
+ statusCommand: `12ui resume ${created.id} --output ${output} --out <file>`,
320
+ waitHint: 'or leave this command running, which is what --wait already does by default',
321
+ })}\n`);
252
322
  }
253
323
  const reporter = createProgressReporter({ label: 'convert', quiet });
254
324
  let operation;
@@ -333,12 +403,75 @@ const main = async () => {
333
403
  return;
334
404
  }
335
405
  if (command[0] === 'image') {
336
- if (command[1] === 'generate-batch')
406
+ if (command[1] === 'generate-batch') {
407
+ if (detaches(flags)) {
408
+ const manifest = stringFlag(flags, 'manifest')?.trim();
409
+ if (!manifest)
410
+ throw new Error('--manifest is required');
411
+ console.log(JSON.stringify(await detachImageBatch({
412
+ cliPath: CLI_PATH,
413
+ argv: process.argv.slice(2),
414
+ manifestPath: path.resolve(manifest),
415
+ typicalSeconds: OPERATION_DURATION_HINTS.imageBatch,
416
+ }), null, 2));
417
+ return;
418
+ }
337
419
  await runImageBatchCommand(flags);
420
+ }
421
+ else if (command[1] === 'batch-status')
422
+ await runImageBatchStatusCommand(flags);
338
423
  else
339
424
  await runImageCommand(command[1], flags);
340
425
  return;
341
426
  }
427
+ if (command[0] === 'draft') {
428
+ if (command[1] === 'status') {
429
+ console.log(JSON.stringify(await runDraftStatusCommand(command[2], flags), null, 2));
430
+ return;
431
+ }
432
+ await runDraftCommand(flags, {
433
+ generate: async ({ manifestPath, detach }) => {
434
+ if (!detach)
435
+ return runImageBatchCommand({ ...flags, manifest: manifestPath });
436
+ return console.log(JSON.stringify(await detachImageBatch({
437
+ cliPath: CLI_PATH,
438
+ argv: ['image', 'generate-batch', '--manifest', manifestPath],
439
+ manifestPath,
440
+ typicalSeconds: OPERATION_DURATION_HINTS.imageBatch,
441
+ }), null, 2));
442
+ },
443
+ });
444
+ return;
445
+ }
446
+ if (command[0] === 'select') {
447
+ await runSelectCommand(command[1], flags);
448
+ return;
449
+ }
450
+ if (command[0] === 'branch') {
451
+ // `branch execute <run-dir>` — the directory `12ui draft` printed.
452
+ const runDirArgument = command[2]?.trim();
453
+ if ((command[1] === 'execute' || command[1] === 'resume') && detaches(flags)) {
454
+ const resolved = await resolveBranchDirectory({
455
+ ...(stringFlag(flags, 'out-dir')?.trim()
456
+ ? { outDirFlag: stringFlag(flags, 'out-dir').trim() }
457
+ : {}),
458
+ ...(runDirArgument ? { runDirArgument } : {}),
459
+ });
460
+ console.log(JSON.stringify(await detachBranchRun({
461
+ cliPath: CLI_PATH,
462
+ argv: process.argv.slice(2),
463
+ outDir: resolved.branchDir,
464
+ typicalSeconds: stringFlag(flags, 'scope') === 'site'
465
+ ? OPERATION_DURATION_HINTS.branchSite
466
+ : OPERATION_DURATION_HINTS.branchPage,
467
+ }), null, 2));
468
+ return;
469
+ }
470
+ await runBranchCommand(command[1], flags, {
471
+ ...(runDirArgument ? { runDirArgument } : {}),
472
+ });
473
+ return;
474
+ }
342
475
  if (command[0] === 'export') {
343
476
  await runExportCommand(command[1], flags);
344
477
  return;