@12ui/design 0.2.13 → 0.2.15

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 (188) hide show
  1. package/README.md +35 -9
  2. package/dist/bounded-concurrency.d.ts +13 -0
  3. package/dist/bounded-concurrency.d.ts.map +1 -0
  4. package/dist/bounded-concurrency.js +43 -0
  5. package/dist/bounded-concurrency.js.map +1 -0
  6. package/dist/branch-client.d.ts +155 -0
  7. package/dist/branch-client.d.ts.map +1 -0
  8. package/dist/branch-client.js +179 -0
  9. package/dist/branch-client.js.map +1 -0
  10. package/dist/branch-completion.d.ts +37 -0
  11. package/dist/branch-completion.d.ts.map +1 -0
  12. package/dist/branch-completion.js +137 -0
  13. package/dist/branch-completion.js.map +1 -0
  14. package/dist/branch-dispatch-loop.d.ts +84 -0
  15. package/dist/branch-dispatch-loop.d.ts.map +1 -0
  16. package/dist/branch-dispatch-loop.js +206 -0
  17. package/dist/branch-dispatch-loop.js.map +1 -0
  18. package/dist/branch-downloads.d.ts +53 -0
  19. package/dist/branch-downloads.d.ts.map +1 -0
  20. package/dist/branch-downloads.js +114 -0
  21. package/dist/branch-downloads.js.map +1 -0
  22. package/dist/branch-execution-types.d.ts +54 -0
  23. package/dist/branch-execution-types.d.ts.map +1 -0
  24. package/dist/branch-execution-types.js +2 -0
  25. package/dist/branch-execution-types.js.map +1 -0
  26. package/dist/branch-execution.d.ts +20 -0
  27. package/dist/branch-execution.d.ts.map +1 -0
  28. package/dist/branch-execution.js +380 -0
  29. package/dist/branch-execution.js.map +1 -0
  30. package/dist/branch-identity.d.ts +71 -0
  31. package/dist/branch-identity.d.ts.map +1 -0
  32. package/dist/branch-identity.js +72 -0
  33. package/dist/branch-identity.js.map +1 -0
  34. package/dist/branch-materialize.d.ts +33 -0
  35. package/dist/branch-materialize.d.ts.map +1 -0
  36. package/dist/branch-materialize.js +64 -0
  37. package/dist/branch-materialize.js.map +1 -0
  38. package/dist/branch-page-conversion.d.ts +127 -0
  39. package/dist/branch-page-conversion.d.ts.map +1 -0
  40. package/dist/branch-page-conversion.js +382 -0
  41. package/dist/branch-page-conversion.js.map +1 -0
  42. package/dist/branch-plan.d.ts +63 -0
  43. package/dist/branch-plan.d.ts.map +1 -0
  44. package/dist/branch-plan.js +95 -0
  45. package/dist/branch-plan.js.map +1 -0
  46. package/dist/branch-progress.d.ts +99 -0
  47. package/dist/branch-progress.d.ts.map +1 -0
  48. package/dist/branch-progress.js +188 -0
  49. package/dist/branch-progress.js.map +1 -0
  50. package/dist/branch-run-record.d.ts +164 -0
  51. package/dist/branch-run-record.d.ts.map +1 -0
  52. package/dist/branch-run-record.js +94 -0
  53. package/dist/branch-run-record.js.map +1 -0
  54. package/dist/branch-schedule.d.ts +74 -0
  55. package/dist/branch-schedule.d.ts.map +1 -0
  56. package/dist/branch-schedule.js +130 -0
  57. package/dist/branch-schedule.js.map +1 -0
  58. package/dist/branch-status.d.ts +11 -0
  59. package/dist/branch-status.d.ts.map +1 -0
  60. package/dist/branch-status.js +118 -0
  61. package/dist/branch-status.js.map +1 -0
  62. package/dist/branch-viewport-normalization.d.ts +74 -0
  63. package/dist/branch-viewport-normalization.d.ts.map +1 -0
  64. package/dist/branch-viewport-normalization.js +120 -0
  65. package/dist/branch-viewport-normalization.js.map +1 -0
  66. package/dist/cli-arguments.d.ts.map +1 -1
  67. package/dist/cli-arguments.js +5 -0
  68. package/dist/cli-arguments.js.map +1 -1
  69. package/dist/cli-branch-command.d.ts +55 -0
  70. package/dist/cli-branch-command.d.ts.map +1 -0
  71. package/dist/cli-branch-command.js +475 -0
  72. package/dist/cli-branch-command.js.map +1 -0
  73. package/dist/cli-capabilities.d.ts +51 -0
  74. package/dist/cli-capabilities.d.ts.map +1 -1
  75. package/dist/cli-capabilities.js +52 -1
  76. package/dist/cli-capabilities.js.map +1 -1
  77. package/dist/cli-create-command.d.ts +21 -0
  78. package/dist/cli-create-command.d.ts.map +1 -0
  79. package/dist/cli-create-command.js +319 -0
  80. package/dist/cli-create-command.js.map +1 -0
  81. package/dist/cli-detach.d.ts +62 -0
  82. package/dist/cli-detach.d.ts.map +1 -0
  83. package/dist/cli-detach.js +123 -0
  84. package/dist/cli-detach.js.map +1 -0
  85. package/dist/cli-draft-command.d.ts +63 -0
  86. package/dist/cli-draft-command.d.ts.map +1 -0
  87. package/dist/cli-draft-command.js +220 -0
  88. package/dist/cli-draft-command.js.map +1 -0
  89. package/dist/cli-export-command.d.ts.map +1 -1
  90. package/dist/cli-export-command.js +2 -3
  91. package/dist/cli-export-command.js.map +1 -1
  92. package/dist/cli-image-batch-command.d.ts +21 -0
  93. package/dist/cli-image-batch-command.d.ts.map +1 -1
  94. package/dist/cli-image-batch-command.js +65 -4
  95. package/dist/cli-image-batch-command.js.map +1 -1
  96. package/dist/cli-image-batch-resume.d.ts +7 -0
  97. package/dist/cli-image-batch-resume.d.ts.map +1 -1
  98. package/dist/cli-image-batch-resume.js +19 -2
  99. package/dist/cli-image-batch-resume.js.map +1 -1
  100. package/dist/cli-package-command.d.ts +29 -0
  101. package/dist/cli-package-command.d.ts.map +1 -0
  102. package/dist/cli-package-command.js +128 -0
  103. package/dist/cli-package-command.js.map +1 -0
  104. package/dist/cli-progress.d.ts +137 -0
  105. package/dist/cli-progress.d.ts.map +1 -1
  106. package/dist/cli-progress.js +156 -0
  107. package/dist/cli-progress.js.map +1 -1
  108. package/dist/cli-select-command.d.ts +12 -0
  109. package/dist/cli-select-command.d.ts.map +1 -0
  110. package/dist/cli-select-command.js +66 -0
  111. package/dist/cli-select-command.js.map +1 -0
  112. package/dist/cli.js +150 -7
  113. package/dist/cli.js.map +1 -1
  114. package/dist/conversion-receipt.d.ts +127 -0
  115. package/dist/conversion-receipt.d.ts.map +1 -0
  116. package/dist/conversion-receipt.js +184 -0
  117. package/dist/conversion-receipt.js.map +1 -0
  118. package/dist/create-identity.d.ts +25 -0
  119. package/dist/create-identity.d.ts.map +1 -0
  120. package/dist/create-identity.js +0 -0
  121. package/dist/create-identity.js.map +1 -0
  122. package/dist/draft-identity.d.ts +30 -0
  123. package/dist/draft-identity.d.ts.map +1 -0
  124. package/dist/draft-identity.js +0 -0
  125. package/dist/draft-identity.js.map +1 -0
  126. package/dist/draft-prompts.d.ts +35 -0
  127. package/dist/draft-prompts.d.ts.map +1 -0
  128. package/dist/draft-prompts.js +51 -0
  129. package/dist/draft-prompts.js.map +1 -0
  130. package/dist/draft-run.d.ts +32 -0
  131. package/dist/draft-run.d.ts.map +1 -0
  132. package/dist/draft-run.js +152 -0
  133. package/dist/draft-run.js.map +1 -0
  134. package/dist/draft-workspace.d.ts +90 -0
  135. package/dist/draft-workspace.d.ts.map +1 -0
  136. package/dist/draft-workspace.js +64 -0
  137. package/dist/draft-workspace.js.map +1 -0
  138. package/dist/image-batch-status.d.ts +42 -0
  139. package/dist/image-batch-status.d.ts.map +1 -0
  140. package/dist/image-batch-status.js +142 -0
  141. package/dist/image-batch-status.js.map +1 -0
  142. package/dist/image-dimensions.d.ts +12 -0
  143. package/dist/image-dimensions.d.ts.map +1 -0
  144. package/dist/image-dimensions.js +14 -0
  145. package/dist/image-dimensions.js.map +1 -0
  146. package/dist/image-generation-resume.d.ts +13 -0
  147. package/dist/image-generation-resume.d.ts.map +1 -1
  148. package/dist/image-generation-resume.js +13 -0
  149. package/dist/image-generation-resume.js.map +1 -1
  150. package/dist/index.d.ts +6 -1
  151. package/dist/index.d.ts.map +1 -1
  152. package/dist/index.js +5 -1
  153. package/dist/index.js.map +1 -1
  154. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  155. package/dist/legacy-skill-catalog.js +140 -0
  156. package/dist/legacy-skill-catalog.js.map +1 -1
  157. package/dist/package-client.d.ts +28 -0
  158. package/dist/package-client.d.ts.map +1 -1
  159. package/dist/package-client.js +21 -1
  160. package/dist/package-client.js.map +1 -1
  161. package/dist/package-manifest-file.d.ts +21 -0
  162. package/dist/package-manifest-file.d.ts.map +1 -0
  163. package/dist/package-manifest-file.js +119 -0
  164. package/dist/package-manifest-file.js.map +1 -0
  165. package/dist/package-manifest-template.d.ts +23 -0
  166. package/dist/package-manifest-template.d.ts.map +1 -0
  167. package/dist/package-manifest-template.js +60 -0
  168. package/dist/package-manifest-template.js.map +1 -0
  169. package/dist/package-source-refusal.d.ts +17 -0
  170. package/dist/package-source-refusal.d.ts.map +1 -0
  171. package/dist/package-source-refusal.js +61 -0
  172. package/dist/package-source-refusal.js.map +1 -0
  173. package/dist/package-submission.d.ts +134 -0
  174. package/dist/package-submission.d.ts.map +1 -0
  175. package/dist/package-submission.js +196 -0
  176. package/dist/package-submission.js.map +1 -0
  177. package/dist/selection-record.d.ts +95 -0
  178. package/dist/selection-record.d.ts.map +1 -0
  179. package/dist/selection-record.js +121 -0
  180. package/dist/selection-record.js.map +1 -0
  181. package/package.json +1 -1
  182. package/skills/design/SKILL.md +43 -266
  183. package/skills/design-branch/SKILL.md +37 -116
  184. package/skills/design-convert/SKILL.md +62 -148
  185. package/skills/design-draft/SKILL.md +71 -135
  186. package/skills/design-search/SKILL.md +29 -78
  187. package/skills/design/references/continuation-contract.md +0 -60
  188. package/skills/design/references/selection-contract.md +0 -112
@@ -0,0 +1,63 @@
1
+ import type { BranchRunEnvelope, BranchScreenStatus } from './branch-client.js';
2
+ import type { BranchScope } from './branch-identity.js';
3
+ /**
4
+ * Plan normalisation. The wire envelope keeps ordering and per-screen facts in
5
+ * two different places — `plan.pages[].slots` and `candidates[]` — so this is
6
+ * the one module that joins them back into the page/viewport structure the
7
+ * scheduler, the downloads, and the package manifests all read.
8
+ *
9
+ * The approved winner is NOT a slot. The server plans continuations of the
10
+ * source page starting at `viewportOrdinal` 2; ordinal 1 of that page is the
11
+ * image the run branched from. Additional pages start at ordinal 1 because
12
+ * every one of their viewports is generated.
13
+ */
14
+ export type BranchPlannedScreen = {
15
+ slot: string;
16
+ pageIndex: number;
17
+ viewportOrdinal: number;
18
+ status: BranchScreenStatus;
19
+ direction: string;
20
+ header: boolean | null;
21
+ footer: boolean | null;
22
+ pageEndsHere: boolean;
23
+ dependsOnSlot: string | null;
24
+ width: number;
25
+ height: number;
26
+ content?: string;
27
+ error?: {
28
+ code: string;
29
+ message: string;
30
+ };
31
+ };
32
+ export type BranchPlannedPage = {
33
+ index: number;
34
+ id: string;
35
+ kind: 'source' | 'additional';
36
+ title: string;
37
+ pageType: string;
38
+ surfaceType: string;
39
+ purpose: string;
40
+ /** True when viewport 1 of this page is the approved winner, not a slot. */
41
+ startsFromWinner: boolean;
42
+ slots: string[];
43
+ };
44
+ export type BranchNormalizedPlan = {
45
+ runId: string;
46
+ concept: string;
47
+ aspect: string;
48
+ scope: BranchScope;
49
+ sitePurpose: string;
50
+ statusUpdate: string;
51
+ approvedScreenSummary: string;
52
+ pages: BranchPlannedPage[];
53
+ screens: BranchPlannedScreen[];
54
+ };
55
+ /** Stable, filesystem-safe, and self-describing: `p0-pricing`, `p2`. */
56
+ export declare const branchPageId: (index: number, title: string) => string;
57
+ export declare const normalizeBranchPlan: (envelope: BranchRunEnvelope, options: {
58
+ scope: BranchScope;
59
+ maxScreens?: number;
60
+ }) => BranchNormalizedPlan;
61
+ /** Refresh statuses from a later envelope without re-deriving the structure. */
62
+ export declare const applyBranchEnvelope: (plan: BranchNormalizedPlan, envelope: BranchRunEnvelope) => BranchNormalizedPlan;
63
+ //# sourceMappingURL=branch-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-plan.d.ts","sourceRoot":"","sources":["../src/branch-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAEjB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,GAAG,YAAY,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC,CAAC;AASF,wEAAwE;AACxE,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,EAAE,OAAO,MAAM,KAAG,MAQ3D,CAAC;AAqBF,eAAO,MAAM,mBAAmB,GAC9B,UAAU,iBAAiB,EAC3B,SAAS;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,KACnD,oBA0DF,CAAC;AAEF,gFAAgF;AAChF,eAAO,MAAM,mBAAmB,GAC9B,MAAM,oBAAoB,EAC1B,UAAU,iBAAiB,KAC1B,oBAWF,CAAC"}
@@ -0,0 +1,95 @@
1
+ const PAGE_TITLE_LIMIT = 200;
2
+ const PAGE_PURPOSE_LIMIT = 1_000;
3
+ const clamp = (value, limit) => (value.length <= limit ? value : `${value.slice(0, limit - 1)}…`);
4
+ /** Stable, filesystem-safe, and self-describing: `p0-pricing`, `p2`. */
5
+ export const branchPageId = (index, title) => {
6
+ const slug = title
7
+ .toLowerCase()
8
+ .replace(/[^a-z0-9]+/gu, '-')
9
+ .replace(/^-+|-+$/gu, '')
10
+ .slice(0, 40)
11
+ .replace(/-+$/u, '');
12
+ return slug ? `p${index}-${slug}` : `p${index}`;
13
+ };
14
+ const screenFor = (candidate) => {
15
+ if (candidate.pageIndex === undefined || candidate.viewportOrdinal === undefined)
16
+ return null;
17
+ return {
18
+ slot: candidate.slot,
19
+ pageIndex: candidate.pageIndex,
20
+ viewportOrdinal: candidate.viewportOrdinal,
21
+ status: candidate.status,
22
+ direction: candidate.direction,
23
+ header: candidate.header ?? null,
24
+ footer: candidate.footer ?? null,
25
+ pageEndsHere: candidate.pageEndsHere ?? false,
26
+ dependsOnSlot: candidate.dependsOnSlot ?? null,
27
+ width: candidate.width,
28
+ height: candidate.height,
29
+ ...(candidate.content ? { content: candidate.content } : {}),
30
+ ...(candidate.error ? { error: candidate.error } : {}),
31
+ };
32
+ };
33
+ export const normalizeBranchPlan = (envelope, options) => {
34
+ const plan = envelope.plan;
35
+ if (!plan || !Array.isArray(plan.pages)) {
36
+ throw new Error(`Run ${envelope.id} carries no build plan. Only a run started with source "build" can be`
37
+ + ' branched.');
38
+ }
39
+ const bySlot = new Map(envelope.candidates.map((candidate) => [candidate.slot, candidate]));
40
+ // Plan order is page order then viewport order, which is also slot order.
41
+ // Everything downstream — the footer seed, the dependency chains, the
42
+ // `--max-screens` trim — depends on keeping exactly that sequence.
43
+ const orderedSlots = plan.pages.flatMap((page) => ((page.slots ?? []).filter((slot) => bySlot.has(slot))));
44
+ const scopedPages = options.scope === 'page'
45
+ ? plan.pages.filter((page) => page.kind === 'source')
46
+ : plan.pages;
47
+ const scopedSlots = new Set(scopedPages.flatMap((page) => page.slots ?? []));
48
+ const trimmed = options.maxScreens === undefined
49
+ ? null
50
+ : new Set(orderedSlots.filter((slot) => scopedSlots.has(slot)).slice(0, options.maxScreens));
51
+ const keeps = (slot) => (scopedSlots.has(slot) && (trimmed === null || trimmed.has(slot)));
52
+ const pages = scopedPages.map((page) => ({
53
+ index: page.index,
54
+ id: branchPageId(page.index, page.title ?? ''),
55
+ kind: page.kind,
56
+ title: clamp(page.title ?? `Page ${page.index}`, PAGE_TITLE_LIMIT),
57
+ pageType: page.pageType ?? 'other',
58
+ surfaceType: page.surfaceType ?? 'web_page',
59
+ purpose: clamp(page.purpose ?? '', PAGE_PURPOSE_LIMIT),
60
+ startsFromWinner: page.kind === 'source',
61
+ slots: (page.slots ?? []).filter(keeps),
62
+ }));
63
+ const screens = orderedSlots
64
+ .filter(keeps)
65
+ .flatMap((slot) => {
66
+ const screen = screenFor(bySlot.get(slot));
67
+ return screen ? [screen] : [];
68
+ });
69
+ return {
70
+ runId: envelope.id,
71
+ concept: envelope.concept,
72
+ aspect: envelope.aspect,
73
+ scope: options.scope,
74
+ sitePurpose: plan.sitePurpose ?? '',
75
+ statusUpdate: plan.statusUpdate ?? '',
76
+ approvedScreenSummary: plan.approvedScreenSummary ?? '',
77
+ pages,
78
+ screens,
79
+ };
80
+ };
81
+ /** Refresh statuses from a later envelope without re-deriving the structure. */
82
+ export const applyBranchEnvelope = (plan, envelope) => {
83
+ const bySlot = new Map(envelope.candidates.map((candidate) => [candidate.slot, candidate]));
84
+ return {
85
+ ...plan,
86
+ screens: plan.screens.map((screen) => {
87
+ const candidate = bySlot.get(screen.slot);
88
+ if (!candidate)
89
+ return screen;
90
+ const next = screenFor(candidate);
91
+ return next ? { ...screen, ...next } : screen;
92
+ }),
93
+ };
94
+ };
95
+ //# sourceMappingURL=branch-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-plan.js","sourceRoot":"","sources":["../src/branch-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import type { BranchNormalizedPlan } from './branch-plan.js';
2
+ import type { BranchCompletion } from './branch-run-record.js';
3
+ /**
4
+ * The motion surface. A long command that answers a poll with bare absence is
5
+ * the measured trigger for a caller deciding the process stalled and improvising
6
+ * around it, so every observation of a branch run — the command's own streamed
7
+ * lines and `12ui branch status` from another session — reports what changed,
8
+ * how long each screen has been running against its typical duration, and what
9
+ * to do next.
10
+ */
11
+ export declare const BRANCH_PROGRESS_FILENAME = "branch.progress.json";
12
+ export type BranchProgressPhase = 'claiming' | 'dispatching' | 'downloading' | 'converting' | 'terminal';
13
+ export type BranchProgressScreen = {
14
+ slot: string;
15
+ status: 'pending' | 'dispatched' | 'succeeded' | 'failed' | 'blocked';
16
+ pageIndex: number;
17
+ viewportOrdinal: number;
18
+ dispatchedAt?: string;
19
+ waitingOn?: string;
20
+ };
21
+ /**
22
+ * One page's package conversion, as last published by the server.
23
+ *
24
+ * `12ui branch status` is the command a second session is told to poll, and
25
+ * until now it carried per-screen state only — so the entire second half of a
26
+ * run, the half that takes the longest, answered every poll with the same
27
+ * sentence. These are the per-page facts that make it report motion.
28
+ */
29
+ export type BranchProgressPackage = {
30
+ pageId: string;
31
+ stage: string;
32
+ percent?: number;
33
+ completed?: number;
34
+ total?: number;
35
+ running?: number;
36
+ stageSince?: string;
37
+ pagesAvailable?: number;
38
+ updatedAt: string;
39
+ };
40
+ export type BranchProgressRecord = {
41
+ version: 1;
42
+ runId: string;
43
+ phase: BranchProgressPhase;
44
+ startedAt: string;
45
+ updatedAt: string;
46
+ screens: BranchProgressScreen[];
47
+ /** Absent until the first page starts converting. */
48
+ packages?: BranchProgressPackage[];
49
+ };
50
+ export declare const branchProgressPath: (outDir: string) => string;
51
+ export declare const writeBranchProgress: (file: string, record: BranchProgressRecord) => Promise<void>;
52
+ export declare const readBranchProgress: (file: string) => Promise<BranchProgressRecord | undefined>;
53
+ export declare const branchProgressScreens: (plan: BranchNormalizedPlan, dispatchedAt: Readonly<Record<string, string>>) => BranchProgressScreen[];
54
+ export type BranchStatusCounts = {
55
+ total: number;
56
+ complete: number;
57
+ generating: number;
58
+ waiting: number;
59
+ blocked: number;
60
+ failed: number;
61
+ };
62
+ export type BranchStatusReport = {
63
+ outDir: string;
64
+ runId?: string;
65
+ phase: BranchProgressPhase;
66
+ complete: boolean;
67
+ counts: BranchStatusCounts;
68
+ screens: BranchProgressScreen[];
69
+ /** Always populated: what is moving, and how long it has been moving. */
70
+ narrative: string;
71
+ /** Per-page package progress, once any page has started converting. */
72
+ packages?: BranchProgressPackage[];
73
+ /** Present only while work remains. A finished run has no next action. */
74
+ nextAction?: string;
75
+ startedAt?: string;
76
+ updatedAt?: string;
77
+ elapsedSeconds?: number;
78
+ completionPath?: string;
79
+ planPath?: string;
80
+ pages?: BranchCompletion['pages'];
81
+ };
82
+ /**
83
+ * One line of motion plus, while anything remains, one line of instruction.
84
+ * A terminal report carries neither: there is nothing in flight to narrate and
85
+ * nothing left to check.
86
+ */
87
+ export declare const summarizeBranchProgress: (args: {
88
+ outDir: string;
89
+ runId?: string;
90
+ phase: BranchProgressPhase;
91
+ screens: readonly BranchProgressScreen[];
92
+ packages?: readonly BranchProgressPackage[];
93
+ startedAt?: string;
94
+ updatedAt?: string;
95
+ completion?: BranchCompletion;
96
+ statusCommand?: string;
97
+ now?: number;
98
+ }) => BranchStatusReport;
99
+ //# sourceMappingURL=branch-progress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-progress.d.ts","sourceRoot":"","sources":["../src/branch-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,188 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { BRANCH_PAGE_CONCURRENCY_DEFAULT, OPERATION_DURATION_HINTS, elapsedAgainstTypical, formatDuration, narrateCounts, nextActionLine, packageProgressLine, secondsSince, } from './cli-progress.js';
5
+ import { branchBlockedSlots } from './branch-schedule.js';
6
+ /**
7
+ * The motion surface. A long command that answers a poll with bare absence is
8
+ * the measured trigger for a caller deciding the process stalled and improvising
9
+ * around it, so every observation of a branch run — the command's own streamed
10
+ * lines and `12ui branch status` from another session — reports what changed,
11
+ * how long each screen has been running against its typical duration, and what
12
+ * to do next.
13
+ */
14
+ export const BRANCH_PROGRESS_FILENAME = 'branch.progress.json';
15
+ export const branchProgressPath = (outDir) => (path.join(outDir, BRANCH_PROGRESS_FILENAME));
16
+ export const writeBranchProgress = async (file, record) => {
17
+ await mkdir(path.dirname(file), { recursive: true });
18
+ const temporary = `${file}.${randomUUID()}.tmp`;
19
+ try {
20
+ await writeFile(temporary, `${JSON.stringify(record, null, 2)}\n`, {
21
+ encoding: 'utf8',
22
+ flag: 'wx',
23
+ mode: 0o600,
24
+ });
25
+ await rename(temporary, file);
26
+ }
27
+ finally {
28
+ await rm(temporary, { force: true });
29
+ }
30
+ };
31
+ export const readBranchProgress = async (file) => {
32
+ try {
33
+ return JSON.parse(await readFile(file, 'utf8'));
34
+ }
35
+ catch {
36
+ return undefined;
37
+ }
38
+ };
39
+ export const branchProgressScreens = (plan, dispatchedAt) => {
40
+ const blocked = new Map(branchBlockedSlots(plan.screens.map((screen) => ({
41
+ slot: screen.slot,
42
+ status: screen.status,
43
+ footer: screen.footer,
44
+ dependsOnSlot: screen.dependsOnSlot,
45
+ }))).map((entry) => [entry.slot, entry]));
46
+ return plan.screens.map((screen) => {
47
+ const block = blocked.get(screen.slot);
48
+ return {
49
+ slot: screen.slot,
50
+ status: block ? 'blocked' : screen.status,
51
+ pageIndex: screen.pageIndex,
52
+ viewportOrdinal: screen.viewportOrdinal,
53
+ ...(dispatchedAt[screen.slot] ? { dispatchedAt: dispatchedAt[screen.slot] } : {}),
54
+ ...(block
55
+ ? { waitingOn: block.waitingOn }
56
+ : screen.status === 'pending' && screen.dependsOnSlot
57
+ ? { waitingOn: screen.dependsOnSlot }
58
+ : {}),
59
+ };
60
+ });
61
+ };
62
+ const countScreens = (screens) => ({
63
+ total: screens.length,
64
+ complete: screens.filter((screen) => screen.status === 'succeeded').length,
65
+ generating: screens.filter((screen) => screen.status === 'dispatched').length,
66
+ waiting: screens.filter((screen) => screen.status === 'pending').length,
67
+ blocked: screens.filter((screen) => screen.status === 'blocked').length,
68
+ failed: screens.filter((screen) => screen.status === 'failed').length,
69
+ });
70
+ const generatingDetail = (screens, now) => {
71
+ const running = screens
72
+ .filter((screen) => screen.status === 'dispatched')
73
+ .map((screen) => secondsSince(screen.dispatchedAt, now))
74
+ .filter((seconds) => seconds !== undefined);
75
+ if (running.length === 0)
76
+ return undefined;
77
+ return elapsedAgainstTypical(Math.max(...running), OPERATION_DURATION_HINTS.branchScreen);
78
+ };
79
+ /**
80
+ * `p0-home converting viewports 32% — 1 of 3 viewports, 2 running, 1m 20s in
81
+ * stage`. One line per page still converting, so a poll during the longest half
82
+ * of the run reports advancing facts rather than one unchanging sentence.
83
+ */
84
+ const packageDetail = (packages, now) => {
85
+ if (packages.length === 0)
86
+ return undefined;
87
+ // A settled page has nothing left to narrate, so it becomes a tally and the
88
+ // detail stays on the pages that are still moving.
89
+ const converted = packages.filter((entry) => entry.stage === 'succeeded').length;
90
+ const failed = packages.filter((entry) => entry.stage === 'failed').length;
91
+ const moving = packages.filter((entry) => entry.stage !== 'succeeded' && entry.stage !== 'failed');
92
+ return [
93
+ ...(converted > 0 ? [`${converted} converted`] : []),
94
+ ...(failed > 0 ? [`${failed} failed`] : []),
95
+ ...moving.map((entry) => `${entry.pageId} ${packageProgressLine(entry, now)}`),
96
+ ].join('; ');
97
+ };
98
+ /**
99
+ * One line of motion plus, while anything remains, one line of instruction.
100
+ * A terminal report carries neither: there is nothing in flight to narrate and
101
+ * nothing left to check.
102
+ */
103
+ export const summarizeBranchProgress = (args) => {
104
+ const now = args.now ?? Date.now();
105
+ const packages = args.packages ?? [];
106
+ const counts = countScreens(args.screens);
107
+ const complete = args.phase === 'terminal' || Boolean(args.completion);
108
+ const elapsedSeconds = secondsSince(args.startedAt, now);
109
+ const statusCommand = args.statusCommand ?? `12ui branch status --out-dir ${args.outDir}`;
110
+ if (complete) {
111
+ const settled = args.completion;
112
+ const narrative = settled
113
+ ? `Branch run ${settled.runId} finished ${settled.status}:`
114
+ + ` ${settled.succeededCount} of ${settled.screenCount} screen(s) generated,`
115
+ + ` ${settled.failedCount} failed, ${settled.blockedCount} blocked.`
116
+ + ` Screens and pages are on disk under ${settled.outDir}.`
117
+ : `Branch run ${args.runId ?? '(unclaimed)'} is finished; read the completion sentinel.`;
118
+ return {
119
+ outDir: args.outDir,
120
+ ...(args.runId ? { runId: args.runId } : {}),
121
+ phase: 'terminal',
122
+ complete: true,
123
+ counts,
124
+ screens: [...args.screens],
125
+ narrative,
126
+ ...(args.startedAt ? { startedAt: args.startedAt } : {}),
127
+ ...(args.updatedAt ? { updatedAt: args.updatedAt } : {}),
128
+ ...(elapsedSeconds === undefined ? {} : { elapsedSeconds: Math.round(elapsedSeconds) }),
129
+ ...(settled ? { pages: settled.pages } : {}),
130
+ };
131
+ }
132
+ const converting = args.phase === 'converting'
133
+ ? `Converting each whole page as one package, up to ${BRANCH_PAGE_CONCURRENCY_DEFAULT} at a`
134
+ + ` time (${formatDuration(OPERATION_DURATION_HINTS.branchPackage)} typical per page).`
135
+ : null;
136
+ const phaseNarrative = args.phase === 'claiming'
137
+ ? `Planning the screens (${elapsedAgainstTypical(elapsedSeconds ?? 0, OPERATION_DURATION_HINTS.branchClaim)}); no image bought yet.`
138
+ : args.phase === 'downloading'
139
+ ? `Screens settled; downloading ${counts.complete} image(s).`
140
+ : converting
141
+ ? converting
142
+ : `screens: ${narrateCounts([
143
+ { label: 'complete', count: counts.complete },
144
+ {
145
+ label: 'generating',
146
+ count: counts.generating,
147
+ ...(generatingDetail(args.screens, now) ? { detail: generatingDetail(args.screens, now) } : {}),
148
+ },
149
+ { label: 'waiting on dependencies', count: counts.waiting },
150
+ { label: 'blocked', count: counts.blocked },
151
+ { label: 'failed', count: counts.failed },
152
+ ])}`;
153
+ const typicalSeconds = args.phase === 'claiming'
154
+ ? OPERATION_DURATION_HINTS.branchClaim
155
+ : args.phase === 'converting'
156
+ ? OPERATION_DURATION_HINTS.branchPackage
157
+ : OPERATION_DURATION_HINTS.branchScreen;
158
+ // Pages convert as their own screens land, so package motion belongs on a
159
+ // dispatching report too — that is exactly when the two overlap.
160
+ const detail = packageDetail(packages, now);
161
+ const narrated = detail ? `${phaseNarrative} pages: ${detail}` : phaseNarrative;
162
+ return {
163
+ outDir: args.outDir,
164
+ ...(args.runId ? { runId: args.runId } : {}),
165
+ phase: args.phase,
166
+ complete: false,
167
+ counts,
168
+ screens: [...args.screens],
169
+ ...(packages.length > 0 ? { packages: [...packages] } : {}),
170
+ narrative: elapsedSeconds === undefined
171
+ ? narrated
172
+ : `${narrated} — ${formatDuration(elapsedSeconds)} into the run`,
173
+ nextAction: nextActionLine({
174
+ what: args.phase === 'converting'
175
+ ? 'A page conversion'
176
+ : args.phase === 'claiming'
177
+ ? 'The plan call'
178
+ : 'Each screen',
179
+ typicalSeconds,
180
+ statusCommand,
181
+ waitHint: 'or leave `12ui branch execute` running, which blocks until the whole run finishes',
182
+ }),
183
+ ...(args.startedAt ? { startedAt: args.startedAt } : {}),
184
+ ...(args.updatedAt ? { updatedAt: args.updatedAt } : {}),
185
+ ...(elapsedSeconds === undefined ? {} : { elapsedSeconds: Math.round(elapsedSeconds) }),
186
+ };
187
+ };
188
+ //# sourceMappingURL=branch-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-progress.js","sourceRoot":"","sources":["../src/branch-progress.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,164 @@
1
+ import type { BranchScope } from './branch-identity.js';
2
+ import type { BranchNormalizedPlan } from './branch-plan.js';
3
+ /**
4
+ * The two durable records of a branch run.
5
+ *
6
+ * `branch.attempt.json` is written BEFORE any spend, exclusively, so a plain
7
+ * re-run in the same directory refuses instead of buying a second run; only
8
+ * `--resume` may proceed. `branch.complete.json` is the sentinel: written once,
9
+ * atomically, only at a terminal state. Its ABSENCE means the run is still
10
+ * going — never that it failed. It is deliberately not named
11
+ * `generation.complete.json`, which is `image generate-batch`'s record and a
12
+ * different thing entirely.
13
+ */
14
+ export declare const BRANCH_ATTEMPT_FILENAME = "branch.attempt.json";
15
+ export declare const BRANCH_COMPLETION_FILENAME = "branch.complete.json";
16
+ export declare const BRANCH_PLAN_FILENAME = "branch.plan.json";
17
+ export declare const BRANCH_SCREENS_DIRECTORY = "screens";
18
+ export declare const BRANCH_PAGES_DIRECTORY = "pages";
19
+ export type BranchAttemptStatus = 'claiming' | 'dispatching' | 'downloading' | 'converting' | 'succeeded' | 'partial' | 'failed';
20
+ export type BranchAttempt = {
21
+ version: 1;
22
+ status: BranchAttemptStatus;
23
+ runKey: string;
24
+ runId?: string;
25
+ origin: string;
26
+ scope: BranchScope;
27
+ concept: string;
28
+ conceptSha256: string;
29
+ winner: {
30
+ kind: 'run';
31
+ runId: string;
32
+ slot: string;
33
+ } | {
34
+ kind: 'image';
35
+ imagePath: string;
36
+ sha256: string;
37
+ mediaType: 'image/png' | 'image/jpeg' | 'image/webp';
38
+ };
39
+ aspect?: string;
40
+ maxScreens?: number;
41
+ convert?: {
42
+ output: 'html';
43
+ model: string;
44
+ responsiveQuality?: string;
45
+ };
46
+ sourceConversionId?: string;
47
+ createdAt: string;
48
+ resumedAt?: string[];
49
+ completionPath?: string;
50
+ completedAt?: string;
51
+ errors?: string[];
52
+ };
53
+ export declare const branchAttemptPath: (outDir: string) => string;
54
+ export declare const branchCompletionPath: (outDir: string) => string;
55
+ export declare const branchPlanPath: (outDir: string) => string;
56
+ export declare const writeBranchAttempt: (file: string, attempt: BranchAttempt, exclusive?: boolean) => Promise<void>;
57
+ export declare const readBranchAttempt: (file: string) => Promise<BranchAttempt | undefined>;
58
+ export declare const writeBranchPlanRecord: (file: string, plan: BranchNormalizedPlan) => Promise<void>;
59
+ export type BranchCompletionScreen = {
60
+ slot: string;
61
+ pageIndex: number;
62
+ pageId: string;
63
+ viewportOrdinal: number;
64
+ /** `blocked` is a screen a FAILED dependency put permanently out of reach. */
65
+ status: 'succeeded' | 'failed' | 'blocked';
66
+ direction: string;
67
+ path?: string;
68
+ sha256?: string;
69
+ bytes?: number;
70
+ width?: number;
71
+ height?: number;
72
+ dependsOnSlot?: string;
73
+ footer?: boolean;
74
+ blockedBy?: string;
75
+ blockedReason?: 'dependency' | 'footer-seed';
76
+ error?: {
77
+ code: string;
78
+ message: string;
79
+ };
80
+ };
81
+ export type BranchCompletionPage = {
82
+ index: number;
83
+ id: string;
84
+ kind: 'source' | 'additional';
85
+ title: string;
86
+ slots: string[];
87
+ /** Viewport 1 of a source page is the approved winner, not a generated slot. */
88
+ startsFromWinner: boolean;
89
+ conversion?: {
90
+ status: 'succeeded' | 'failed' | 'skipped';
91
+ reason?: string;
92
+ packageId?: string;
93
+ idempotencyKey?: string;
94
+ conversionId?: string;
95
+ output?: string;
96
+ outFile?: string;
97
+ sha256?: string;
98
+ bytes?: number;
99
+ error?: string;
100
+ /** The width every viewport of this page was reconciled to. */
101
+ canonicalWidth?: number;
102
+ /**
103
+ * Reuse claims the server refused at admission, which this page then bought
104
+ * fresh under the same key. A page that silently paid for a screen it
105
+ * expected to attach is exactly what an operator needs to see, and the
106
+ * refusal detail is the server's own reason.
107
+ */
108
+ disprovenReuse?: {
109
+ viewportId: string;
110
+ conversionId: string;
111
+ detail: string;
112
+ }[];
113
+ /**
114
+ * Viewports resized to reach it, with both digests. The winner comes from a
115
+ * different canvas than the server's screens, and a page only stitches when
116
+ * they share a width, so the resize is recorded rather than silent.
117
+ */
118
+ normalizedViewports?: {
119
+ id: string;
120
+ fromWidth: number;
121
+ fromHeight: number;
122
+ fromSha256: string;
123
+ toWidth: number;
124
+ toHeight: number;
125
+ toSha256: string;
126
+ }[];
127
+ };
128
+ };
129
+ export type BranchCompletion = {
130
+ version: 1;
131
+ /** `partial` means some screens or pages are missing and were reported. */
132
+ status: 'succeeded' | 'partial' | 'failed';
133
+ runId: string;
134
+ runKey: string;
135
+ workflowRevision: string;
136
+ scope: BranchScope;
137
+ concept: string;
138
+ conceptSha256: string;
139
+ origin: string;
140
+ outDir: string;
141
+ attemptPath: string;
142
+ planPath: string;
143
+ startedAt: string;
144
+ completedAt: string;
145
+ screenCount: number;
146
+ succeededCount: number;
147
+ failedCount: number;
148
+ blockedCount: number;
149
+ /** The approved design the run branched from: viewport 1 of the source page. */
150
+ winner?: {
151
+ path: string;
152
+ sha256: string;
153
+ bytes: number;
154
+ width: number;
155
+ height: number;
156
+ sourceConversionId?: string;
157
+ };
158
+ screens: BranchCompletionScreen[];
159
+ pages: BranchCompletionPage[];
160
+ notes?: string[];
161
+ };
162
+ export declare const writeBranchCompletion: (file: string, completion: BranchCompletion) => Promise<void>;
163
+ export declare const readBranchCompletion: (file: string) => Promise<BranchCompletion | undefined>;
164
+ //# sourceMappingURL=branch-run-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-run-record.d.ts","sourceRoot":"","sources":["../src/branch-run-record.ts"],"names":[],"mappings":"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"}