@12ui/design 0.2.12 → 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 (203) hide show
  1. package/README.md +44 -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 +5 -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 +166 -54
  91. package/dist/cli-image-batch-command.js.map +1 -1
  92. package/dist/cli-image-batch-materialize.d.ts +27 -0
  93. package/dist/cli-image-batch-materialize.d.ts.map +1 -0
  94. package/dist/cli-image-batch-materialize.js +41 -0
  95. package/dist/cli-image-batch-materialize.js.map +1 -0
  96. package/dist/cli-image-batch-resume.d.ts +34 -0
  97. package/dist/cli-image-batch-resume.d.ts.map +1 -0
  98. package/dist/cli-image-batch-resume.js +175 -0
  99. package/dist/cli-image-batch-resume.js.map +1 -0
  100. package/dist/cli-image-command.d.ts.map +1 -1
  101. package/dist/cli-image-command.js +14 -2
  102. package/dist/cli-image-command.js.map +1 -1
  103. package/dist/cli-package-command.d.ts +18 -0
  104. package/dist/cli-package-command.d.ts.map +1 -0
  105. package/dist/cli-package-command.js +112 -0
  106. package/dist/cli-package-command.js.map +1 -0
  107. package/dist/cli-progress.d.ts +61 -0
  108. package/dist/cli-progress.d.ts.map +1 -1
  109. package/dist/cli-progress.js +53 -0
  110. package/dist/cli-progress.js.map +1 -1
  111. package/dist/cli-select-command.d.ts +12 -0
  112. package/dist/cli-select-command.d.ts.map +1 -0
  113. package/dist/cli-select-command.js +66 -0
  114. package/dist/cli-select-command.js.map +1 -0
  115. package/dist/cli.js +140 -7
  116. package/dist/cli.js.map +1 -1
  117. package/dist/create-identity.d.ts +25 -0
  118. package/dist/create-identity.d.ts.map +1 -0
  119. package/dist/create-identity.js +0 -0
  120. package/dist/create-identity.js.map +1 -0
  121. package/dist/draft-identity.d.ts +30 -0
  122. package/dist/draft-identity.d.ts.map +1 -0
  123. package/dist/draft-identity.js +0 -0
  124. package/dist/draft-identity.js.map +1 -0
  125. package/dist/draft-prompts.d.ts +35 -0
  126. package/dist/draft-prompts.d.ts.map +1 -0
  127. package/dist/draft-prompts.js +51 -0
  128. package/dist/draft-prompts.js.map +1 -0
  129. package/dist/draft-run.d.ts +32 -0
  130. package/dist/draft-run.d.ts.map +1 -0
  131. package/dist/draft-run.js +152 -0
  132. package/dist/draft-run.js.map +1 -0
  133. package/dist/draft-workspace.d.ts +90 -0
  134. package/dist/draft-workspace.d.ts.map +1 -0
  135. package/dist/draft-workspace.js +64 -0
  136. package/dist/draft-workspace.js.map +1 -0
  137. package/dist/image-batch-status.d.ts +42 -0
  138. package/dist/image-batch-status.d.ts.map +1 -0
  139. package/dist/image-batch-status.js +142 -0
  140. package/dist/image-batch-status.js.map +1 -0
  141. package/dist/image-dimensions.d.ts +12 -0
  142. package/dist/image-dimensions.d.ts.map +1 -0
  143. package/dist/image-dimensions.js +14 -0
  144. package/dist/image-dimensions.js.map +1 -0
  145. package/dist/image-generation-batch-attempt.d.ts +28 -0
  146. package/dist/image-generation-batch-attempt.d.ts.map +1 -0
  147. package/dist/image-generation-batch-attempt.js +48 -0
  148. package/dist/image-generation-batch-attempt.js.map +1 -0
  149. package/dist/image-generation-completion.d.ts +43 -0
  150. package/dist/image-generation-completion.d.ts.map +1 -0
  151. package/dist/image-generation-completion.js +54 -0
  152. package/dist/image-generation-completion.js.map +1 -0
  153. package/dist/image-generation-fs.d.ts +3 -0
  154. package/dist/image-generation-fs.d.ts.map +1 -0
  155. package/dist/image-generation-fs.js +23 -0
  156. package/dist/image-generation-fs.js.map +1 -0
  157. package/dist/image-generation-request.d.ts +13 -3
  158. package/dist/image-generation-request.d.ts.map +1 -1
  159. package/dist/image-generation-request.js +21 -19
  160. package/dist/image-generation-request.js.map +1 -1
  161. package/dist/image-generation-resume.d.ts +49 -0
  162. package/dist/image-generation-resume.d.ts.map +1 -0
  163. package/dist/image-generation-resume.js +96 -0
  164. package/dist/image-generation-resume.js.map +1 -0
  165. package/dist/image-generation-run.d.ts +11 -0
  166. package/dist/image-generation-run.d.ts.map +1 -1
  167. package/dist/image-generation-run.js +23 -9
  168. package/dist/image-generation-run.js.map +1 -1
  169. package/dist/image-generation-staging.d.ts +25 -0
  170. package/dist/image-generation-staging.d.ts.map +1 -0
  171. package/dist/image-generation-staging.js +80 -0
  172. package/dist/image-generation-staging.js.map +1 -0
  173. package/dist/index.d.ts +5 -0
  174. package/dist/index.d.ts.map +1 -1
  175. package/dist/index.js +4 -0
  176. package/dist/index.js.map +1 -1
  177. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  178. package/dist/legacy-skill-catalog.js +133 -0
  179. package/dist/legacy-skill-catalog.js.map +1 -1
  180. package/dist/package-manifest-file.d.ts +21 -0
  181. package/dist/package-manifest-file.d.ts.map +1 -0
  182. package/dist/package-manifest-file.js +119 -0
  183. package/dist/package-manifest-file.js.map +1 -0
  184. package/dist/package-manifest-template.d.ts +23 -0
  185. package/dist/package-manifest-template.d.ts.map +1 -0
  186. package/dist/package-manifest-template.js +60 -0
  187. package/dist/package-manifest-template.js.map +1 -0
  188. package/dist/package-submission.d.ts +103 -0
  189. package/dist/package-submission.d.ts.map +1 -0
  190. package/dist/package-submission.js +173 -0
  191. package/dist/package-submission.js.map +1 -0
  192. package/dist/selection-record.d.ts +95 -0
  193. package/dist/selection-record.d.ts.map +1 -0
  194. package/dist/selection-record.js +121 -0
  195. package/dist/selection-record.js.map +1 -0
  196. package/package.json +1 -1
  197. package/skills/design/SKILL.md +55 -240
  198. package/skills/design-branch/SKILL.md +36 -116
  199. package/skills/design-convert/SKILL.md +62 -132
  200. package/skills/design-draft/SKILL.md +71 -135
  201. package/skills/design-search/SKILL.md +29 -78
  202. package/skills/design/references/continuation-contract.md +0 -60
  203. package/skills/design/references/selection-contract.md +0 -96
package/README.md CHANGED
@@ -52,24 +52,27 @@ name) to install one skill instead of the complete bundle.
52
52
  ## Five visual interface skills
53
53
 
54
54
  - `design` routes UI, web, and mobile work. Finished screenshots go directly
55
- to conversion, tiny edits stay code-only, and rough briefs retrieve exactly
55
+ to conversion, tiny edits stay code-only, and rough briefs classify the
56
+ deliverable as one fold, one full page, or a multi-page app, retrieve exactly
56
57
  four references, generate four candidates using one different reference per
57
- candidate, select one, convert only the winner, integrate it, and verify the
58
- real surface.
58
+ candidate, select one, execute the recorded scope, integrate the result, and
59
+ verify the real surface.
59
60
  - `design-search` returns a ranked, diverse set of real Design Corpus
60
61
  references while preserving endpoint order and metrics.
61
62
  - `design-draft` drafts candidates from a brief by claiming one
62
63
  `/api/v1/create` run, dispatches each candidate slot once, and downloads the
63
64
  images without re-buying a settled slot.
64
- - `design-branch` expands one approved design into the 2-8 screens the server
65
- plans, dispatching each screen only once its dependency and footer gates
66
- clear.
65
+ - `design-branch` is required whenever the deliverable is more than one
66
+ viewport. One `12ui branch execute` run expands one approved design into the
67
+ 2-8 screens the server plans, dispatching each only once its dependency and
68
+ footer gates clear, and converts each page as one ordered package.
67
69
  - `design-convert` turns a finished PNG, JPEG, or WebP into LayerDoc and any
68
- supported responsive, fixed, project, or document export.
70
+ supported responsive, fixed, project, or document export, and converts the
71
+ ordered viewports of one page as a single package.
69
72
 
70
73
  `design-search`, `design-draft`, and `design-branch` are pipeline stages the
71
- `design` skill can also run end to end; install one when an agent only needs
72
- that stage.
74
+ `design` skill also runs end to end as part of its main flow; install one when
75
+ an agent only needs that stage.
73
76
 
74
77
  The design workflow exists because code-first agents often converge on safe,
75
78
  generic visual defaults. Corpus-conditioned image generation expands the
@@ -85,6 +88,14 @@ manual recreation.
85
88
  --out-dir ./references \
86
89
  --count 4
87
90
  12ui image generate-batch --manifest ./generation.json
91
+ 12ui image batch-status --manifest ./generation.json
92
+ 12ui branch execute \
93
+ --winner-image ./candidates/A.png \
94
+ --concept "Editorial architecture studio site" \
95
+ --scope site \
96
+ --out-dir ./branch \
97
+ --convert html
98
+ 12ui branch status --out-dir ./branch
88
99
  12ui export <base-layerdoc-conversion-id> \
89
100
  --output html,pdf,psd,pptx,sketch,web_project \
90
101
  --out-dir ./exports \
@@ -99,6 +110,15 @@ PNG output, and one stable idempotency key. Per-candidate and batch evidence
99
110
  records provider-start and completion times. It never retries a candidate or
100
111
  switches providers after dispatch.
101
112
 
113
+ Candidates are written into a hidden staging directory and moved into place only
114
+ once the batch is terminal, so a caller listing the output directory can never
115
+ observe a half-written batch. Completion is published as a
116
+ `generation.complete.json` sentinel beside the candidates, carrying each
117
+ candidate's status, sha256, and byte count. `--resume` recovers an interrupted
118
+ batch: it delivers candidates that were already generated and re-requests only
119
+ those the provider provably never billed, so it can never buy a candidate twice,
120
+ and it refuses a batch that already completed.
121
+
102
122
  The single-candidate `image generate` command remains available. Both commands
103
123
  resolve authenticated Codex first, then `OPENAI_API_KEY` from the process or
104
124
  exactly `<project-root>/.env`. They refuse a Git-tracked `.env`, never store or
@@ -247,9 +267,24 @@ export TWELVE_UI_API_KEY=your-key
247
267
  12ui convert ./screen.layerdoc.json --output pptx --out ./screen.pptx --idempotency-key screen-pptx-v1
248
268
  12ui convert ./screen.layerdoc.json --output web_project --profile ./react-tailwind.json --out ./screen-react.zip
249
269
  12ui convert ./screen.layerdoc.json --output app_project --profile '{"version":1,"framework":"swiftui","styling":"native","language":"swift","packaging":"project"}' --out ./screen-ios.zip
270
+ 12ui convert package --manifest ./package.json --out-dir ./pages
250
271
  12ui resume conversion-id --output layerdoc --out ./screen.layerdoc.json
251
272
  ```
252
273
 
274
+ `convert package` submits the ordered viewports of one continuous page as ONE
275
+ package conversion per page, which is what preserves page order and stitching;
276
+ converting a stacked page one image at a time loses both. Every viewport of a
277
+ page must share one width, checked locally before anything is bought. A viewport
278
+ may name `sourceConversionId` to reuse an already succeeded conversion of
279
+ exactly those bytes instead of paying for it twice.
280
+
281
+ Long commands block until they finish, and `--wait` names that default
282
+ explicitly. While one runs, `12ui branch status --out-dir <dir>` and
283
+ `12ui image batch-status --manifest <file>` report forward motion — per-item
284
+ state, elapsed against typical, and what to do next — without touching the run.
285
+ Do not infer progress from a directory listing: staged work is materialized in
286
+ one atomic pass at the end.
287
+
253
288
  Each conversion also writes a verified `<out>.assets/manifest.json` plus every
254
289
  signed raster artifact beside the requested result. Set `TWELVE_UI_ORIGIN` to
255
290
  override `https://12ui.com`; waits default to the operation expiry and can be
@@ -0,0 +1,155 @@
1
+ import type { ConversionConfig } from './config.js';
2
+ /**
3
+ * The create/build API as the CLI needs it: a port of the web app's
4
+ * `apps/web/src/pages/create/createApi.ts` with the browser identity, Turnstile,
5
+ * and object-URL machinery removed and Bearer key auth in their place.
6
+ *
7
+ * The wire envelope is deliberately NOT `BranchPlan` verbatim. `plan.pages[]`
8
+ * carries the ordering (`slots`), while every per-screen fact —
9
+ * `viewportOrdinal`, `header`, `footer`, `pageEndsHere`, `dependsOnSlot`,
10
+ * `content` — lives on `candidates[]`. Those are two different places and both
11
+ * are needed to reconstruct the page grouping.
12
+ */
13
+ export declare const BRANCH_MAX_CONCEPT_CHARACTERS = 600;
14
+ export type BranchAspect = 'landscape' | 'portrait' | 'square';
15
+ export type BranchPageKind = 'source' | 'additional';
16
+ export type BranchScreenStatus = 'pending' | 'dispatched' | 'succeeded' | 'failed';
17
+ export type BranchPlanPageEnvelope = {
18
+ index: number;
19
+ kind: BranchPageKind;
20
+ title: string;
21
+ pageType: string;
22
+ surfaceType: string;
23
+ purpose: string;
24
+ /** Source page only: the approved screen already reaches its natural end. */
25
+ sourceEndsHere?: boolean;
26
+ /** This page's slots, in viewport order. */
27
+ slots: string[];
28
+ };
29
+ export type BranchPlanEnvelope = {
30
+ sitePurpose: string;
31
+ /** First person, written for the user. Safe to render verbatim. */
32
+ statusUpdate: string;
33
+ approvedScreenSummary: string;
34
+ pages: BranchPlanPageEnvelope[];
35
+ };
36
+ export type BranchCandidateEnvelope = {
37
+ slot: string;
38
+ status: BranchScreenStatus;
39
+ direction: string;
40
+ width: number;
41
+ height: number;
42
+ image?: string;
43
+ error?: {
44
+ code: string;
45
+ message: string;
46
+ };
47
+ pageIndex?: number;
48
+ /** 1-based within an additional page; source continuations begin at 2. */
49
+ viewportOrdinal?: number;
50
+ /** null means webpage chrome semantics do not apply to this surface. */
51
+ header?: boolean | null;
52
+ footer?: boolean | null;
53
+ pageEndsHere?: boolean;
54
+ /** The previous viewport of the same page, which must succeed first. */
55
+ dependsOnSlot?: string | null;
56
+ content?: string;
57
+ };
58
+ export type BranchRunEnvelope = {
59
+ id: string;
60
+ concept: string;
61
+ aspect: BranchAspect;
62
+ source?: 'create' | 'build';
63
+ createdAt?: string;
64
+ expiresAt?: string;
65
+ plan?: BranchPlanEnvelope;
66
+ candidates: BranchCandidateEnvelope[];
67
+ };
68
+ export type BranchStartInput = {
69
+ concept: string;
70
+ aspect?: BranchAspect;
71
+ winner?: {
72
+ createRunId: string;
73
+ slot: string;
74
+ };
75
+ referenceImage?: {
76
+ data: string;
77
+ mediaType: string;
78
+ sha256: string;
79
+ };
80
+ };
81
+ /**
82
+ * The other shape the same endpoint accepts: an explicit candidate list rather
83
+ * than a planned build. `12ui draft` covers the four-candidate case; this is
84
+ * the one with per-slot directions and references.
85
+ */
86
+ export type CreateStartInput = {
87
+ concept: string;
88
+ aspect?: BranchAspect;
89
+ mode?: 'inspiration' | 'preserve-structure';
90
+ candidates: readonly {
91
+ slot: string;
92
+ direction?: string;
93
+ referenceId?: string;
94
+ useReferenceImage?: boolean;
95
+ }[];
96
+ referenceImage?: {
97
+ data: string;
98
+ mediaType: string;
99
+ sha256: string;
100
+ };
101
+ };
102
+ export declare class BranchApiError extends Error {
103
+ readonly status: number;
104
+ readonly code: string;
105
+ readonly retryAfterSeconds?: number;
106
+ /** Branch gating only: the slot that must succeed before this one runs. */
107
+ readonly dependsOn?: string;
108
+ constructor(message: string, status: number, code: string, options?: {
109
+ retryAfterSeconds?: number;
110
+ dependsOn?: string;
111
+ });
112
+ }
113
+ /**
114
+ * TWO error shapes live behind one status. The dependency gates answer 409 with
115
+ * a NESTED object — `{"error":{"code","dependsOn","message"}}` — while every
116
+ * other refusal, `candidate_in_flight` included, uses the FLAT helper —
117
+ * `{"error":"candidate_in_flight","message":…}` — where `error.code` is
118
+ * undefined. Reading only one of the two silently mis-routes the other, which
119
+ * is exactly the trap the branch skill used to invite.
120
+ */
121
+ export declare const parseBranchFailure: (status: number, body: unknown, retryAfterHeader?: string | null) => BranchApiError;
122
+ export type BranchClientOptions = ConversionConfig & {
123
+ fetch?: typeof fetch;
124
+ };
125
+ export declare class TwelveUiBranchClient {
126
+ #private;
127
+ readonly origin: string;
128
+ constructor(options: BranchClientOptions);
129
+ /**
130
+ * Claim the build run. The planner runs inline — 10 to 20 seconds — and buys
131
+ * no image. The key derives the run id, so replaying it returns the same run.
132
+ */
133
+ startBuildRun(input: BranchStartInput, idempotencyKey: string, signal?: AbortSignal): Promise<BranchRunEnvelope>;
134
+ /**
135
+ * Claim a candidate run. Buys no image; the key derives the run, so replaying
136
+ * it returns the same run and its stored images rather than a second set.
137
+ */
138
+ startCreateRun(input: CreateStartInput, idempotencyKey: string, signal?: AbortSignal): Promise<BranchRunEnvelope>;
139
+ /**
140
+ * Dispatch one screen. Unkeyed by default and by design: an unkeyed repeat
141
+ * replays the settled screen for free, while a NEW key on a settled slot buys
142
+ * another image. Only an explicit redraw passes one.
143
+ */
144
+ dispatchScreen(runId: string, slot: string, options?: {
145
+ idempotencyKey?: string;
146
+ signal?: AbortSignal;
147
+ }): Promise<BranchRunEnvelope>;
148
+ getRun(runId: string, signal?: AbortSignal): Promise<BranchRunEnvelope>;
149
+ /** Candidate images are owner-authenticated rather than signed. */
150
+ downloadScreen(runId: string, slot: string, signal?: AbortSignal): Promise<{
151
+ bytes: Uint8Array;
152
+ sha256: string;
153
+ }>;
154
+ }
155
+ //# sourceMappingURL=branch-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-client.d.ts","sourceRoot":"","sources":["../src/branch-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { appendClientAuthGuidance } from './client-auth-guidance.js';
3
+ import { normalizeConversionOrigin } from './config.js';
4
+ /**
5
+ * The create/build API as the CLI needs it: a port of the web app's
6
+ * `apps/web/src/pages/create/createApi.ts` with the browser identity, Turnstile,
7
+ * and object-URL machinery removed and Bearer key auth in their place.
8
+ *
9
+ * The wire envelope is deliberately NOT `BranchPlan` verbatim. `plan.pages[]`
10
+ * carries the ordering (`slots`), while every per-screen fact —
11
+ * `viewportOrdinal`, `header`, `footer`, `pageEndsHere`, `dependsOnSlot`,
12
+ * `content` — lives on `candidates[]`. Those are two different places and both
13
+ * are needed to reconstruct the page grouping.
14
+ */
15
+ export const BRANCH_MAX_CONCEPT_CHARACTERS = 600;
16
+ export class BranchApiError extends Error {
17
+ status;
18
+ code;
19
+ retryAfterSeconds;
20
+ /** Branch gating only: the slot that must succeed before this one runs. */
21
+ dependsOn;
22
+ constructor(message, status, code, options = {}) {
23
+ super(message);
24
+ this.name = 'BranchApiError';
25
+ this.status = status;
26
+ this.code = code;
27
+ if (options.retryAfterSeconds !== undefined)
28
+ this.retryAfterSeconds = options.retryAfterSeconds;
29
+ if (options.dependsOn !== undefined)
30
+ this.dependsOn = options.dependsOn;
31
+ }
32
+ }
33
+ /**
34
+ * TWO error shapes live behind one status. The dependency gates answer 409 with
35
+ * a NESTED object — `{"error":{"code","dependsOn","message"}}` — while every
36
+ * other refusal, `candidate_in_flight` included, uses the FLAT helper —
37
+ * `{"error":"candidate_in_flight","message":…}` — where `error.code` is
38
+ * undefined. Reading only one of the two silently mis-routes the other, which
39
+ * is exactly the trap the branch skill used to invite.
40
+ */
41
+ export const parseBranchFailure = (status, body, retryAfterHeader) => {
42
+ const parsed = (body && typeof body === 'object' && !Array.isArray(body)
43
+ ? body
44
+ : null);
45
+ const nested = parsed?.error && typeof parsed.error === 'object' && !Array.isArray(parsed.error)
46
+ ? parsed.error
47
+ : null;
48
+ const flat = typeof parsed?.error === 'string' ? parsed.error : undefined;
49
+ const code = nested?.code ?? flat ?? 'error';
50
+ const message = nested?.message
51
+ ?? parsed?.message
52
+ ?? (status === 429
53
+ ? 'The daily generation allowance is used up.'
54
+ : `The create service failed (${status}).`);
55
+ const retryAfter = Number(retryAfterHeader ?? '');
56
+ return new BranchApiError(appendClientAuthGuidance(message, status), status, code, {
57
+ ...(Number.isFinite(retryAfter) && retryAfter > 0
58
+ ? { retryAfterSeconds: Math.round(retryAfter) }
59
+ : {}),
60
+ ...(typeof nested?.dependsOn === 'string' ? { dependsOn: nested.dependsOn } : {}),
61
+ });
62
+ };
63
+ const parseEnvelope = (payload) => {
64
+ const record = payload;
65
+ if (!record || typeof record.id !== 'string' || !Array.isArray(record.candidates)) {
66
+ throw new BranchApiError('The create service returned an unexpected response.', 0, 'error');
67
+ }
68
+ return record;
69
+ };
70
+ export class TwelveUiBranchClient {
71
+ origin;
72
+ #apiKey;
73
+ #fetch;
74
+ constructor(options) {
75
+ this.origin = normalizeConversionOrigin(options.origin);
76
+ this.#apiKey = options.apiKey.trim();
77
+ this.#fetch = options.fetch ?? fetch;
78
+ if (!this.#apiKey)
79
+ throw new Error('A 12ui API key is required');
80
+ }
81
+ /**
82
+ * Claim the build run. The planner runs inline — 10 to 20 seconds — and buys
83
+ * no image. The key derives the run id, so replaying it returns the same run.
84
+ */
85
+ async startBuildRun(input, idempotencyKey, signal) {
86
+ const body = {
87
+ source: 'build',
88
+ concept: input.concept,
89
+ ...(input.aspect ? { aspect: input.aspect } : {}),
90
+ ...(input.winner ? { winner: input.winner } : {}),
91
+ ...(input.referenceImage ? { referenceImage: input.referenceImage } : {}),
92
+ };
93
+ return parseEnvelope(await this.#json('/api/v1/create', {
94
+ method: 'POST',
95
+ headers: { 'content-type': 'application/json', 'Idempotency-Key': idempotencyKey },
96
+ body: JSON.stringify(body),
97
+ ...(signal ? { signal } : {}),
98
+ }, [200, 201]));
99
+ }
100
+ /**
101
+ * Claim a candidate run. Buys no image; the key derives the run, so replaying
102
+ * it returns the same run and its stored images rather than a second set.
103
+ */
104
+ async startCreateRun(input, idempotencyKey, signal) {
105
+ const body = {
106
+ concept: input.concept,
107
+ ...(input.aspect ? { aspect: input.aspect } : {}),
108
+ ...(input.mode ? { mode: input.mode } : {}),
109
+ candidates: input.candidates.map((candidate) => ({
110
+ slot: candidate.slot,
111
+ ...(candidate.direction ? { direction: candidate.direction } : {}),
112
+ ...(candidate.referenceId ? { referenceId: candidate.referenceId } : {}),
113
+ ...(candidate.useReferenceImage ? { useReferenceImage: true } : {}),
114
+ })),
115
+ ...(input.referenceImage ? { referenceImage: input.referenceImage } : {}),
116
+ };
117
+ return parseEnvelope(await this.#json('/api/v1/create', {
118
+ method: 'POST',
119
+ headers: { 'content-type': 'application/json', 'Idempotency-Key': idempotencyKey },
120
+ body: JSON.stringify(body),
121
+ ...(signal ? { signal } : {}),
122
+ }, [200, 201]));
123
+ }
124
+ /**
125
+ * Dispatch one screen. Unkeyed by default and by design: an unkeyed repeat
126
+ * replays the settled screen for free, while a NEW key on a settled slot buys
127
+ * another image. Only an explicit redraw passes one.
128
+ */
129
+ async dispatchScreen(runId, slot, options = {}) {
130
+ return parseEnvelope(await this.#json(`/api/v1/create/${encodeURIComponent(runId)}/candidates/${encodeURIComponent(slot)}`, {
131
+ method: 'POST',
132
+ headers: {
133
+ 'content-length': '0',
134
+ ...(options.idempotencyKey ? { 'Idempotency-Key': options.idempotencyKey } : {}),
135
+ },
136
+ ...(options.signal ? { signal: options.signal } : {}),
137
+ }));
138
+ }
139
+ async getRun(runId, signal) {
140
+ return parseEnvelope(await this.#json(`/api/v1/create/${encodeURIComponent(runId)}`, { method: 'GET', ...(signal ? { signal } : {}) }));
141
+ }
142
+ /** Candidate images are owner-authenticated rather than signed. */
143
+ async downloadScreen(runId, slot, signal) {
144
+ const response = await this.#fetch(`${this.origin}/api/v1/create/${encodeURIComponent(runId)}/candidates/${encodeURIComponent(slot)}/image`, {
145
+ method: 'GET',
146
+ headers: this.#headers({ accept: 'image/png' }),
147
+ ...(signal ? { signal } : {}),
148
+ });
149
+ if (!response.ok) {
150
+ throw parseBranchFailure(response.status, await response.json().catch(() => null), response.headers.get('retry-after'));
151
+ }
152
+ const bytes = new Uint8Array(await response.arrayBuffer());
153
+ return { bytes, sha256: createHash('sha256').update(bytes).digest('hex') };
154
+ }
155
+ async #json(path, init, okStatuses = [200]) {
156
+ let response;
157
+ try {
158
+ response = await this.#fetch(`${this.origin}${path}`, {
159
+ ...init,
160
+ headers: this.#headers({ accept: 'application/json', ...init.headers }),
161
+ });
162
+ }
163
+ catch (error) {
164
+ if (error instanceof Error && error.name === 'AbortError')
165
+ throw error;
166
+ throw new BranchApiError('Could not reach the create service.', 0, 'network');
167
+ }
168
+ if (!response.ok && !okStatuses.includes(response.status)) {
169
+ throw parseBranchFailure(response.status, await response.json().catch(() => null), response.headers.get('retry-after'));
170
+ }
171
+ return await response.json().catch(() => null);
172
+ }
173
+ #headers(values) {
174
+ const headers = new Headers(values);
175
+ headers.set('authorization', `Bearer ${this.#apiKey}`);
176
+ return headers;
177
+ }
178
+ }
179
+ //# sourceMappingURL=branch-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-client.js","sourceRoot":"","sources":["../src/branch-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAExD;;;;;;;;;;GAUG;AAEH,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAmFjD,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,MAAM,CAAS;IACf,IAAI,CAAS;IACb,iBAAiB,CAAU;IACpC,2EAA2E;IAClE,SAAS,CAAU;IAE5B,YACE,OAAe,EACf,MAAc,EACd,IAAY,EACZ,UAA8D,EAAE;QAEhE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,OAAO,CAAC,iBAAiB,KAAK,SAAS;YAAE,IAAI,CAAC,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;QAChG,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAC1E,CAAC;CACF;AAOD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAc,EACd,IAAa,EACb,gBAAgC,EAChB,EAAE;IAClB,MAAM,MAAM,GAAG,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;QACtE,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,IAAI,CAA2B,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,EAAE,KAAK,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;QAC9F,CAAC,CAAC,MAAM,CAAC,KAAK;QACd,CAAC,CAAC,IAAI,CAAC;IACT,MAAM,IAAI,GAAG,OAAO,MAAM,EAAE,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,MAAM,IAAI,GAAG,MAAM,EAAE,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,EAAE,OAAO;WAC1B,MAAM,EAAE,OAAO;WACf,CAAC,MAAM,KAAK,GAAG;YAChB,CAAC,CAAC,4CAA4C;YAC9C,CAAC,CAAC,8BAA8B,MAAM,IAAI,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC;IAClD,OAAO,IAAI,cAAc,CAAC,wBAAwB,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE;QACjF,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC;YAC/C,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE;YAC/C,CAAC,CAAC,EAAE,CAAC;QACP,GAAG,CAAC,OAAO,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClF,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,OAAgB,EAAqB,EAAE;IAC5D,MAAM,MAAM,GAAG,OAAmC,CAAC;IACnD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,cAAc,CAAC,qDAAqD,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9F,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAIF,MAAM,OAAO,oBAAoB;IACtB,MAAM,CAAS;IACf,OAAO,CAAS;IAChB,MAAM,CAAe;IAE9B,YAAY,OAA4B;QACtC,IAAI,CAAC,MAAM,GAAG,yBAAyB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACnE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,aAAa,CACjB,KAAuB,EACvB,cAAsB,EACtB,MAAoB;QAEpB,MAAM,IAAI,GAAG;YACX,MAAM,EAAE,OAAgB;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1E,CAAC;QACF,OAAO,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE;YAClF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,cAAc,CAClB,KAAuB,EACvB,cAAsB,EACtB,MAAoB;QAEpB,MAAM,IAAI,GAAG;YACX,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBAC/C,IAAI,EAAE,SAAS,CAAC,IAAI;gBACpB,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxE,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE,CAAC,CAAC;YACH,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC1E,CAAC;QACF,OAAO,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,cAAc,EAAE;YAClF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAY,EACZ,UAA6D,EAAE;QAE/D,OAAO,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,CACnC,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,eAAe,kBAAkB,CAAC,IAAI,CAAC,EAAE,EACpF;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,gBAAgB,EAAE,GAAG;gBACrB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACjF;YACD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CACF,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,MAAoB;QAC9C,OAAO,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,CACnC,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,EAAE,EAC7C,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CACjD,CAAC,CAAC;IACL,CAAC;IAED,mEAAmE;IACnE,KAAK,CAAC,cAAc,CAClB,KAAa,EACb,IAAY,EACZ,MAAoB;QAEpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAChC,GAAG,IAAI,CAAC,MAAM,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,eAAe,kBAAkB,CAAC,IAAI,CAAC,QAAQ,EACxG;YACE,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;YAC/C,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CACF,CAAC;QACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,kBAAkB,CACtB,QAAQ,CAAC,MAAM,EACf,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CACpC,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,KAAK,CACT,IAAY,EACZ,IAAiB,EACjB,aAAgC,CAAC,GAAG,CAAC;QAErC,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,EAAE,EAAE;gBACpD,GAAG,IAAI;gBACP,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,GAAI,IAAI,CAAC,OAAkC,EAAE,CAAC;aACpG,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;gBAAE,MAAM,KAAK,CAAC;YACvE,MAAM,IAAI,cAAc,CAAC,qCAAqC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1D,MAAM,kBAAkB,CACtB,QAAQ,CAAC,MAAM,EACf,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CACpC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,QAAQ,CAAC,MAA8B;QACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,UAAU,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACvD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { BranchDispatchStop } from './branch-dispatch-loop.js';
2
+ import type { BranchDownloadedScreen } from './branch-downloads.js';
3
+ import type { BranchExecutionInputs } from './branch-execution-types.js';
4
+ import type { BranchNormalizedPlan } from './branch-plan.js';
5
+ import { type BranchCompletion, type BranchCompletionPage } from './branch-run-record.js';
6
+ /**
7
+ * The completion sentinel and the exit disposition: the two things that decide
8
+ * what a caller believes happened. Every screen is accounted for as succeeded,
9
+ * failed, or blocked-by-a-failure, so a run always reaches a terminal story
10
+ * rather than leaving a screen that will never move looking merely pending.
11
+ */
12
+ export declare const buildCompletion: (args: {
13
+ plan: BranchNormalizedPlan;
14
+ inputs: BranchExecutionInputs;
15
+ runKey: string;
16
+ origin: string;
17
+ outDir: string;
18
+ attemptFile: string;
19
+ startedAt: string;
20
+ screens: ReadonlyMap<string, BranchDownloadedScreen>;
21
+ winner?: BranchDownloadedScreen;
22
+ conversions: ReadonlyMap<string, BranchCompletionPage["conversion"]>;
23
+ stopped: BranchDispatchStop | null;
24
+ }) => BranchCompletion;
25
+ /**
26
+ * Park or fail, per CLAUDE.md §5. A run that lost some screens still delivered
27
+ * the pages that are whole, so it exits 0 with the gaps named. A run that lost
28
+ * everything, was cut off by quota or funds, or converted nothing it attempted
29
+ * has no artifact to hand over and says so.
30
+ */
31
+ export declare const terminalFailure: (args: {
32
+ completion: BranchCompletion;
33
+ stopped: BranchDispatchStop | null;
34
+ completionFile: string;
35
+ convert: boolean;
36
+ }) => Error | null;
37
+ //# sourceMappingURL=branch-completion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-completion.d.ts","sourceRoot":"","sources":["../src/branch-completion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAE1B,MAAM,wBAAwB,CAAC;AAEhC;;;;;GAKG;AAEH,eAAO,MAAM,eAAe,GAAI,MAAM;IACpC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACrD,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC;IACrE,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACpC,KAAG,gBA6GH,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,MAAM;IACpC,UAAU,EAAE,gBAAgB,CAAC;IAC7B,OAAO,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB,KAAG,KAAK,GAAG,IAwBX,CAAC"}
@@ -0,0 +1,137 @@
1
+ import { BRANCH_WORKFLOW_REVISION, branchConceptDigest } from './branch-identity.js';
2
+ import { branchBlockedSlots } from './branch-schedule.js';
3
+ import { branchPlanPath, } from './branch-run-record.js';
4
+ /**
5
+ * The completion sentinel and the exit disposition: the two things that decide
6
+ * what a caller believes happened. Every screen is accounted for as succeeded,
7
+ * failed, or blocked-by-a-failure, so a run always reaches a terminal story
8
+ * rather than leaving a screen that will never move looking merely pending.
9
+ */
10
+ export const buildCompletion = (args) => {
11
+ const blocked = new Map(branchBlockedSlots(args.plan.screens.map((screen) => ({
12
+ slot: screen.slot,
13
+ status: screen.status,
14
+ footer: screen.footer,
15
+ dependsOnSlot: screen.dependsOnSlot,
16
+ }))).map((entry) => [entry.slot, entry]));
17
+ const pageIdByIndex = new Map(args.plan.pages.map((page) => [page.index, page.id]));
18
+ const screens = args.plan.screens.map((screen) => {
19
+ const downloaded = args.screens.get(screen.slot);
20
+ const block = blocked.get(screen.slot);
21
+ const status = screen.status === 'succeeded' && downloaded
22
+ ? 'succeeded'
23
+ : block
24
+ ? 'blocked'
25
+ : 'failed';
26
+ return {
27
+ slot: screen.slot,
28
+ pageIndex: screen.pageIndex,
29
+ pageId: pageIdByIndex.get(screen.pageIndex) ?? `p${screen.pageIndex}`,
30
+ viewportOrdinal: screen.viewportOrdinal,
31
+ status,
32
+ direction: screen.direction,
33
+ ...(downloaded
34
+ ? {
35
+ path: downloaded.path,
36
+ sha256: downloaded.sha256,
37
+ bytes: downloaded.bytes,
38
+ width: downloaded.width,
39
+ height: downloaded.height,
40
+ }
41
+ : {}),
42
+ ...(screen.dependsOnSlot ? { dependsOnSlot: screen.dependsOnSlot } : {}),
43
+ ...(screen.footer === true ? { footer: true } : {}),
44
+ ...(block ? { blockedBy: block.waitingOn, blockedReason: block.reason } : {}),
45
+ ...(screen.error ? { error: screen.error } : {}),
46
+ };
47
+ });
48
+ const succeededCount = screens.filter((screen) => screen.status === 'succeeded').length;
49
+ const blockedCount = screens.filter((screen) => screen.status === 'blocked').length;
50
+ const failedCount = screens.length - succeededCount - blockedCount;
51
+ const pages = args.plan.pages.map((page) => ({
52
+ index: page.index,
53
+ id: page.id,
54
+ kind: page.kind,
55
+ title: page.title,
56
+ slots: page.slots,
57
+ startsFromWinner: page.startsFromWinner,
58
+ ...(args.conversions.has(page.id) ? { conversion: args.conversions.get(page.id) } : {}),
59
+ }));
60
+ const notes = [];
61
+ if (blockedCount > 0) {
62
+ notes.push(`${blockedCount} screen(s) can never run: their dependency failed, so the run is terminal`
63
+ + ' rather than still waiting. Redraw the failed screen to unblock them.');
64
+ }
65
+ if (args.stopped)
66
+ notes.push(`Dispatch stopped early: ${args.stopped.code} — ${args.stopped.message}`);
67
+ const conversionsAttempted = [...args.conversions.values()];
68
+ const conversionFailed = conversionsAttempted.some((conversion) => conversion?.status === 'failed');
69
+ const status = succeededCount === 0 && screens.length > 0
70
+ ? 'failed'
71
+ : (failedCount > 0 || blockedCount > 0 || args.stopped || conversionFailed)
72
+ ? 'partial'
73
+ : 'succeeded';
74
+ return {
75
+ version: 1,
76
+ status,
77
+ runId: args.plan.runId,
78
+ runKey: args.runKey,
79
+ workflowRevision: BRANCH_WORKFLOW_REVISION,
80
+ scope: args.inputs.scope,
81
+ concept: args.inputs.concept,
82
+ conceptSha256: branchConceptDigest(args.inputs.concept),
83
+ origin: args.origin,
84
+ outDir: args.outDir,
85
+ attemptPath: args.attemptFile,
86
+ planPath: branchPlanPath(args.outDir),
87
+ startedAt: args.startedAt,
88
+ completedAt: new Date().toISOString(),
89
+ screenCount: screens.length,
90
+ succeededCount,
91
+ failedCount,
92
+ blockedCount,
93
+ ...(args.winner
94
+ ? {
95
+ winner: {
96
+ path: args.winner.path,
97
+ sha256: args.winner.sha256,
98
+ bytes: args.winner.bytes,
99
+ width: args.winner.width,
100
+ height: args.winner.height,
101
+ ...(args.inputs.convert?.sourceConversionId
102
+ ? { sourceConversionId: args.inputs.convert.sourceConversionId }
103
+ : {}),
104
+ },
105
+ }
106
+ : {}),
107
+ screens,
108
+ pages,
109
+ ...(notes.length > 0 ? { notes } : {}),
110
+ };
111
+ };
112
+ /**
113
+ * Park or fail, per CLAUDE.md §5. A run that lost some screens still delivered
114
+ * the pages that are whole, so it exits 0 with the gaps named. A run that lost
115
+ * everything, was cut off by quota or funds, or converted nothing it attempted
116
+ * has no artifact to hand over and says so.
117
+ */
118
+ export const terminalFailure = (args) => {
119
+ if (args.stopped) {
120
+ return new Error(`Branch run ${args.completion.runId} stopped: ${args.stopped.code} — ${args.stopped.message}`
121
+ + ` Whatever settled is materialized. Evidence: ${args.completionFile}`);
122
+ }
123
+ if (args.completion.screenCount > 0 && args.completion.succeededCount === 0) {
124
+ return new Error(`Branch run ${args.completion.runId} produced no screen. Evidence: ${args.completionFile}`);
125
+ }
126
+ if (args.convert) {
127
+ const attempted = args.completion.pages
128
+ .map((page) => page.conversion)
129
+ .filter((conversion) => conversion && conversion.status !== 'skipped');
130
+ if (attempted.length > 0 && attempted.every((conversion) => conversion.status === 'failed')) {
131
+ return new Error(`Branch run ${args.completion.runId} generated its screens but converted no page.`
132
+ + ` The screens are on disk. Evidence: ${args.completionFile}`);
133
+ }
134
+ }
135
+ return null;
136
+ };
137
+ //# sourceMappingURL=branch-completion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-completion.js","sourceRoot":"","sources":["../src/branch-completion.ts"],"names":[],"mappings":"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"}