@12ui/design 0.2.91 → 0.2.93

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 (230) hide show
  1. package/SKILL.md +1 -1
  2. package/codex-plugin/plugin.json +14 -14
  3. package/dist/branch-client.d.ts +16 -0
  4. package/dist/branch-client.d.ts.map +1 -1
  5. package/dist/branch-client.js +1 -0
  6. package/dist/branch-client.js.map +1 -1
  7. package/dist/branch-completion.d.ts +2 -0
  8. package/dist/branch-completion.d.ts.map +1 -1
  9. package/dist/branch-completion.js +1 -1
  10. package/dist/branch-completion.js.map +1 -1
  11. package/dist/branch-core/branch-canvas.d.ts +41 -0
  12. package/dist/branch-core/branch-canvas.d.ts.map +1 -0
  13. package/dist/branch-core/branch-canvas.js +87 -0
  14. package/dist/branch-core/branch-canvas.js.map +1 -0
  15. package/dist/branch-core/branch-gates.d.ts +62 -0
  16. package/dist/branch-core/branch-gates.d.ts.map +1 -0
  17. package/dist/branch-core/branch-gates.js +56 -0
  18. package/dist/branch-core/branch-gates.js.map +1 -0
  19. package/dist/branch-core/branch-plan-model.d.ts +115 -0
  20. package/dist/branch-core/branch-plan-model.d.ts.map +1 -0
  21. package/dist/branch-core/branch-plan-model.js +75 -0
  22. package/dist/branch-core/branch-plan-model.js.map +1 -0
  23. package/dist/branch-core/branch-planner.d.ts +92 -0
  24. package/dist/branch-core/branch-planner.d.ts.map +1 -0
  25. package/dist/branch-core/branch-planner.js +483 -0
  26. package/dist/branch-core/branch-planner.js.map +1 -0
  27. package/dist/branch-core/branch-prompt.d.ts +40 -0
  28. package/dist/branch-core/branch-prompt.d.ts.map +1 -0
  29. package/dist/branch-core/branch-prompt.js +180 -0
  30. package/dist/branch-core/branch-prompt.js.map +1 -0
  31. package/dist/branch-core/branch-scope.d.ts +73 -0
  32. package/dist/branch-core/branch-scope.d.ts.map +1 -0
  33. package/dist/branch-core/branch-scope.js +88 -0
  34. package/dist/branch-core/branch-scope.js.map +1 -0
  35. package/dist/branch-core/index.d.ts +18 -0
  36. package/dist/branch-core/index.d.ts.map +1 -0
  37. package/dist/branch-core/index.js +20 -0
  38. package/dist/branch-core/index.js.map +1 -0
  39. package/dist/branch-dispatch-loop.d.ts +2 -2
  40. package/dist/branch-dispatch-loop.d.ts.map +1 -1
  41. package/dist/branch-dispatch-loop.js +4 -0
  42. package/dist/branch-dispatch-loop.js.map +1 -1
  43. package/dist/branch-downloads.d.ts +2 -2
  44. package/dist/branch-downloads.d.ts.map +1 -1
  45. package/dist/branch-engine.d.ts +61 -0
  46. package/dist/branch-engine.d.ts.map +1 -0
  47. package/dist/branch-engine.js +94 -0
  48. package/dist/branch-engine.js.map +1 -0
  49. package/dist/branch-execution-types.d.ts +5 -0
  50. package/dist/branch-execution-types.d.ts.map +1 -1
  51. package/dist/branch-execution.d.ts +16 -3
  52. package/dist/branch-execution.d.ts.map +1 -1
  53. package/dist/branch-execution.js +83 -17
  54. package/dist/branch-execution.js.map +1 -1
  55. package/dist/branch-identity.d.ts +22 -1
  56. package/dist/branch-identity.d.ts.map +1 -1
  57. package/dist/branch-identity.js +23 -4
  58. package/dist/branch-identity.js.map +1 -1
  59. package/dist/branch-local-call-wait.d.ts +58 -0
  60. package/dist/branch-local-call-wait.d.ts.map +1 -0
  61. package/dist/branch-local-call-wait.js +122 -0
  62. package/dist/branch-local-call-wait.js.map +1 -0
  63. package/dist/branch-local-client.d.ts +108 -0
  64. package/dist/branch-local-client.d.ts.map +1 -0
  65. package/dist/branch-local-client.js +478 -0
  66. package/dist/branch-local-client.js.map +1 -0
  67. package/dist/branch-local-plan.d.ts +67 -0
  68. package/dist/branch-local-plan.d.ts.map +1 -0
  69. package/dist/branch-local-plan.js +282 -0
  70. package/dist/branch-local-plan.js.map +1 -0
  71. package/dist/branch-local-session-adoption.d.ts +35 -0
  72. package/dist/branch-local-session-adoption.d.ts.map +1 -0
  73. package/dist/branch-local-session-adoption.js +185 -0
  74. package/dist/branch-local-session-adoption.js.map +1 -0
  75. package/dist/branch-materialize.d.ts +2 -2
  76. package/dist/branch-materialize.d.ts.map +1 -1
  77. package/dist/branch-page-conversion.js +1 -1
  78. package/dist/branch-page-conversion.js.map +1 -1
  79. package/dist/branch-page-rollover.js +2 -2
  80. package/dist/branch-page-rollover.js.map +1 -1
  81. package/dist/branch-plan.d.ts +9 -0
  82. package/dist/branch-plan.d.ts.map +1 -1
  83. package/dist/branch-plan.js +3 -0
  84. package/dist/branch-plan.js.map +1 -1
  85. package/dist/branch-run-observation.d.ts +2 -2
  86. package/dist/branch-run-observation.d.ts.map +1 -1
  87. package/dist/branch-run-observation.js.map +1 -1
  88. package/dist/branch-run-outcome.d.ts +24 -0
  89. package/dist/branch-run-outcome.d.ts.map +1 -0
  90. package/dist/branch-run-outcome.js +31 -0
  91. package/dist/branch-run-outcome.js.map +1 -0
  92. package/dist/branch-run-record.d.ts +21 -0
  93. package/dist/branch-run-record.d.ts.map +1 -1
  94. package/dist/branch-run-record.js.map +1 -1
  95. package/dist/branch-run-supersede.d.ts +41 -0
  96. package/dist/branch-run-supersede.d.ts.map +1 -0
  97. package/dist/branch-run-supersede.js +64 -0
  98. package/dist/branch-run-supersede.js.map +1 -0
  99. package/dist/branch-schedule.d.ts +1 -1
  100. package/dist/branch-schedule.js +1 -1
  101. package/dist/cli-arguments.d.ts.map +1 -1
  102. package/dist/cli-arguments.js +1 -0
  103. package/dist/cli-arguments.js.map +1 -1
  104. package/dist/cli-branch-command.d.ts +9 -2
  105. package/dist/cli-branch-command.d.ts.map +1 -1
  106. package/dist/cli-branch-command.js +74 -17
  107. package/dist/cli-branch-command.js.map +1 -1
  108. package/dist/cli-help/design.d.ts +2 -2
  109. package/dist/cli-help/design.d.ts.map +1 -1
  110. package/dist/cli-help/design.js +3 -1
  111. package/dist/cli-help/design.js.map +1 -1
  112. package/dist/cli-help/index.d.ts +2 -2
  113. package/dist/cli-local-dispatch.d.ts.map +1 -1
  114. package/dist/cli-local-dispatch.js +6 -2
  115. package/dist/cli-local-dispatch.js.map +1 -1
  116. package/dist/cli-next-command.d.ts.map +1 -1
  117. package/dist/cli-next-command.js +3 -1
  118. package/dist/cli-next-command.js.map +1 -1
  119. package/dist/cli-usage.js +1 -1
  120. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  121. package/dist/legacy-skill-catalog.js +10 -0
  122. package/dist/legacy-skill-catalog.js.map +1 -1
  123. package/dist/mcp-slate-ui-copy.d.ts +16 -6
  124. package/dist/mcp-slate-ui-copy.d.ts.map +1 -1
  125. package/dist/mcp-slate-ui-copy.js +11 -4
  126. package/dist/mcp-slate-ui-copy.js.map +1 -1
  127. package/dist/mcp-slate-ui-locales/de-DE.d.ts.map +1 -1
  128. package/dist/mcp-slate-ui-locales/de-DE.js +8 -3
  129. package/dist/mcp-slate-ui-locales/de-DE.js.map +1 -1
  130. package/dist/mcp-slate-ui-locales/es-419.d.ts.map +1 -1
  131. package/dist/mcp-slate-ui-locales/es-419.js +8 -3
  132. package/dist/mcp-slate-ui-locales/es-419.js.map +1 -1
  133. package/dist/mcp-slate-ui-locales/es-ES.d.ts.map +1 -1
  134. package/dist/mcp-slate-ui-locales/es-ES.js +8 -3
  135. package/dist/mcp-slate-ui-locales/es-ES.js.map +1 -1
  136. package/dist/mcp-slate-ui-locales/fr-FR.d.ts.map +1 -1
  137. package/dist/mcp-slate-ui-locales/fr-FR.js +8 -3
  138. package/dist/mcp-slate-ui-locales/fr-FR.js.map +1 -1
  139. package/dist/mcp-slate-ui-locales/hi-IN.d.ts.map +1 -1
  140. package/dist/mcp-slate-ui-locales/hi-IN.js +8 -3
  141. package/dist/mcp-slate-ui-locales/hi-IN.js.map +1 -1
  142. package/dist/mcp-slate-ui-locales/it-IT.d.ts.map +1 -1
  143. package/dist/mcp-slate-ui-locales/it-IT.js +7 -2
  144. package/dist/mcp-slate-ui-locales/it-IT.js.map +1 -1
  145. package/dist/mcp-slate-ui-locales/ja-JP.d.ts.map +1 -1
  146. package/dist/mcp-slate-ui-locales/ja-JP.js +7 -2
  147. package/dist/mcp-slate-ui-locales/ja-JP.js.map +1 -1
  148. package/dist/mcp-slate-ui-locales/ko-KR.d.ts.map +1 -1
  149. package/dist/mcp-slate-ui-locales/ko-KR.js +8 -3
  150. package/dist/mcp-slate-ui-locales/ko-KR.js.map +1 -1
  151. package/dist/mcp-slate-ui-locales/pt-BR.d.ts.map +1 -1
  152. package/dist/mcp-slate-ui-locales/pt-BR.js +8 -3
  153. package/dist/mcp-slate-ui-locales/pt-BR.js.map +1 -1
  154. package/dist/mcp-slate-ui-locales/zh-CN.d.ts.map +1 -1
  155. package/dist/mcp-slate-ui-locales/zh-CN.js +8 -3
  156. package/dist/mcp-slate-ui-locales/zh-CN.js.map +1 -1
  157. package/dist/mcp-slate-ui-locales/zh-TW.d.ts.map +1 -1
  158. package/dist/mcp-slate-ui-locales/zh-TW.js +8 -3
  159. package/dist/mcp-slate-ui-locales/zh-TW.js.map +1 -1
  160. package/dist/mcp-slate-ui-script-designs.d.ts.map +1 -1
  161. package/dist/mcp-slate-ui-script-designs.js +25 -4
  162. package/dist/mcp-slate-ui-script-designs.js.map +1 -1
  163. package/dist/mcp-slate-ui-script-remote.js +2 -2
  164. package/dist/mcp-slate-ui-script-viewer.d.ts +4 -3
  165. package/dist/mcp-slate-ui-script-viewer.d.ts.map +1 -1
  166. package/dist/mcp-slate-ui-script-viewer.js +13 -4
  167. package/dist/mcp-slate-ui-script-viewer.js.map +1 -1
  168. package/dist/mcp-slate-ui-styles-designs.d.ts.map +1 -1
  169. package/dist/mcp-slate-ui-styles-designs.js +7 -0
  170. package/dist/mcp-slate-ui-styles-designs.js.map +1 -1
  171. package/dist/slate-branch-runner.d.ts +9 -3
  172. package/dist/slate-branch-runner.d.ts.map +1 -1
  173. package/dist/slate-branch-runner.js +40 -7
  174. package/dist/slate-branch-runner.js.map +1 -1
  175. package/dist/slate-image-executor.d.ts +1 -0
  176. package/dist/slate-image-executor.d.ts.map +1 -1
  177. package/dist/slate-image-executor.js +1 -1
  178. package/dist/slate-image-executor.js.map +1 -1
  179. package/dist/slate-retry.d.ts +2 -1
  180. package/dist/slate-retry.d.ts.map +1 -1
  181. package/dist/slate-retry.js +32 -0
  182. package/dist/slate-retry.js.map +1 -1
  183. package/dist/slate-run-action.js +9 -4
  184. package/dist/slate-run-action.js.map +1 -1
  185. package/dist/slate-runner-context.d.ts +6 -0
  186. package/dist/slate-runner-context.d.ts.map +1 -1
  187. package/dist/slate-runner-context.js.map +1 -1
  188. package/dist/slate-runner-main.d.ts +3 -0
  189. package/dist/slate-runner-main.d.ts.map +1 -1
  190. package/dist/slate-runner-main.js +4 -0
  191. package/dist/slate-runner-main.js.map +1 -1
  192. package/dist/slate-view-contract.d.ts +9 -1
  193. package/dist/slate-view-contract.d.ts.map +1 -1
  194. package/dist/slate-view-contract.js +3 -1
  195. package/dist/slate-view-contract.js.map +1 -1
  196. package/dist/slate-view.d.ts.map +1 -1
  197. package/dist/slate-view.js +1 -0
  198. package/dist/slate-view.js.map +1 -1
  199. package/dist/slate-workspace-parse.d.ts.map +1 -1
  200. package/dist/slate-workspace-parse.js +4 -0
  201. package/dist/slate-workspace-parse.js.map +1 -1
  202. package/dist/slate-workspace-types.d.ts +8 -0
  203. package/dist/slate-workspace-types.d.ts.map +1 -1
  204. package/dist/workspace-draw-branch.d.ts +7 -3
  205. package/dist/workspace-draw-branch.d.ts.map +1 -1
  206. package/dist/workspace-draw-branch.js +42 -27
  207. package/dist/workspace-draw-branch.js.map +1 -1
  208. package/dist/workspace-draw-client.d.ts +1 -0
  209. package/dist/workspace-draw-client.d.ts.map +1 -1
  210. package/dist/workspace-draw-client.js +6 -3
  211. package/dist/workspace-draw-client.js.map +1 -1
  212. package/dist/workspace-draw-codex.d.ts +5 -1
  213. package/dist/workspace-draw-codex.d.ts.map +1 -1
  214. package/dist/workspace-draw-codex.js +1 -0
  215. package/dist/workspace-draw-codex.js.map +1 -1
  216. package/dist/workspace-draw-messages.d.ts +13 -0
  217. package/dist/workspace-draw-messages.d.ts.map +1 -1
  218. package/dist/workspace-draw-messages.js +17 -0
  219. package/dist/workspace-draw-messages.js.map +1 -1
  220. package/dist/workspace-draw-run.d.ts +2 -1
  221. package/dist/workspace-draw-run.d.ts.map +1 -1
  222. package/dist/workspace-draw-run.js +7 -2
  223. package/dist/workspace-draw-run.js.map +1 -1
  224. package/dist/workspace-draw-types.d.ts +1 -0
  225. package/dist/workspace-draw-types.d.ts.map +1 -1
  226. package/dist/workspace-draw-types.js +2 -0
  227. package/dist/workspace-draw-types.js.map +1 -1
  228. package/open-design.json +2 -2
  229. package/package.json +1 -1
  230. package/skills/12ui-design/outputs.md +1 -1
@@ -0,0 +1,282 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { createHash } from 'node:crypto';
3
+ import { mkdir, open, readFile, writeFile } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
+ import { BRANCH_PLANNER_SYSTEM_PROMPT, BUILD_PLAN_MODEL, branchPlanResponseSchema, buildBranchPlannerPrompt, } from './branch-core/index.js';
7
+ import { waitForUnrecordedCall } from './branch-local-call-wait.js';
8
+ import { resolveCodexBinary } from './codex-binary.js';
9
+ /**
10
+ * The branch planner on the person's own Codex: the hosted planner call
11
+ * (workers/api/src/create/buildPlan.ts `deriveBuildPlan`) made as one
12
+ * `codex exec` turn. Same model and effort (gpt-6.1-sol, low), the same system
13
+ * text (as Codex's developer instructions), the same prompt on stdin, the same
14
+ * strict `create_branch_plan` schema as `--output-schema`, and the approved
15
+ * design as its one image. Tools are off, the sandbox is read-only, the sign-in
16
+ * is ChatGPT only, and the child gets an allowlisted environment, so no provider
17
+ * key reaches it.
18
+ *
19
+ * Each attempt is one call in the run-store under a stable id
20
+ * (`branch-plan:<run>:<attempt>`): its request, prompt, system text, schema and
21
+ * image are written into the call's own folder before it runs, and its events,
22
+ * stderr and final answer are written by the Codex process itself (file
23
+ * descriptors, a detached process group), so a `branch execute` that dies
24
+ * mid-plan leaves the call able to finish and a resume reads its answer instead
25
+ * of planning again. A call that ended without a usable answer is never
26
+ * dispatched again.
27
+ */
28
+ export const BRANCH_PLAN_EFFORT = 'low';
29
+ /** One planner turn may run this long before its process group is stopped. */
30
+ export const BRANCH_PLAN_TIMEOUT_MS = 10 * 60_000;
31
+ export const branchPlanCallId = (runId, attempt) => `branch-plan:${runId}:${attempt}`;
32
+ const importRuntime = async () => {
33
+ const base = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'runtime', 'codex-conversion', 'src');
34
+ const load = async (file) => await import(pathToFileURL(path.join(base, file)).href);
35
+ const modules = await Promise.all(['run-store.mjs', 'codex/home.mjs', 'codex/caller-home.mjs', 'codex/arguments.mjs'].map(load));
36
+ return Object.assign({}, ...modules);
37
+ };
38
+ const sha256 = (value) => createHash('sha256').update(value).digest('hex');
39
+ const extensionOf = (mediaType) => (mediaType === 'image/jpeg' ? 'jpg' : mediaType === 'image/webp' ? 'webp' : 'png');
40
+ /** The `codex exec` argv of one planner turn. Every value is ours; nothing the person typed is in it. */
41
+ export const branchPlannerArgv = (spec) => [
42
+ '-a', 'never', 'exec', '--ignore-user-config', '--ignore-rules', '--strict-config', '-C', spec.workDir,
43
+ '--skip-git-repo-check', '-s', 'read-only', '-m', BUILD_PLAN_MODEL,
44
+ '-c', `model_reasoning_effort="${BRANCH_PLAN_EFFORT}"`, '-c', 'model_provider="openai"',
45
+ '-c', 'forced_login_method="chatgpt"', '-c', 'project_doc_max_bytes=0',
46
+ // The hosted system message, as Codex's developer instructions (a TOML basic string).
47
+ '-c', `developer_instructions=${JSON.stringify(BRANCH_PLANNER_SYSTEM_PROMPT)}`,
48
+ ...(spec.serviceTier ? ['-c', `service_tier="${spec.serviceTier}"`] : []),
49
+ '--enable', 'skip_host_skill_discovery',
50
+ ...spec.disabledFeatures.flatMap((feature) => ['--disable', feature]),
51
+ '--json', '--color', 'never', '--output-last-message', spec.finalPath,
52
+ '--image', spec.imagePath, '--output-schema', spec.schemaPath, '-',
53
+ ];
54
+ const readEvents = async (file) => {
55
+ const text = await readFile(file, 'utf8').catch(() => '');
56
+ const events = { threadId: null, completed: 0, failed: 0, tools: [], malformed: 0 };
57
+ for (const line of text.split('\n')) {
58
+ if (!line.trim())
59
+ continue;
60
+ let event;
61
+ try {
62
+ event = JSON.parse(line);
63
+ }
64
+ catch {
65
+ events.malformed += 1;
66
+ continue;
67
+ }
68
+ if (event.type === 'thread.started' && typeof event.thread_id === 'string')
69
+ events.threadId ??= event.thread_id;
70
+ if (event.type === 'turn.completed')
71
+ events.completed += 1;
72
+ if (event.type === 'turn.failed')
73
+ events.failed += 1;
74
+ if (event.type === 'item.completed' && event.item && !['agent_message', 'reasoning', 'error'].includes(event.item.type)) {
75
+ events.tools.push(String(event.item.type));
76
+ }
77
+ }
78
+ return events;
79
+ };
80
+ /** The model and effort the call's own session recorded, from its rollout in the Codex home. */
81
+ const auditTurn = async (runtime, home, threadId, times) => {
82
+ const files = await runtime.callRollouts(home, threadId, times);
83
+ if (files.length === 0)
84
+ return null;
85
+ let model = null;
86
+ let effort = null;
87
+ let tools = 0;
88
+ for (const file of files) {
89
+ for (const line of (await readFile(file, 'utf8')).split('\n')) {
90
+ if (!line.trim())
91
+ continue;
92
+ let entry;
93
+ try {
94
+ entry = JSON.parse(line);
95
+ }
96
+ catch {
97
+ continue;
98
+ }
99
+ const payload = entry.payload ?? {};
100
+ if (entry.type === 'turn_context') {
101
+ model = payload.model ?? null;
102
+ effort = payload.effort ?? null;
103
+ }
104
+ if (['custom_tool_call', 'function_call'].includes(payload.type))
105
+ tools += 1;
106
+ }
107
+ }
108
+ return { model, effort, tools };
109
+ };
110
+ const pgidAlive = (pgid) => {
111
+ if (!pgid || !Number.isInteger(pgid) || pgid <= 0)
112
+ return false;
113
+ try {
114
+ process.kill(-pgid, 0);
115
+ return true;
116
+ }
117
+ catch (error) {
118
+ return error.code === 'EPERM';
119
+ }
120
+ };
121
+ /** A call whose process outlived the `branch execute` that started it is waited for, never run twice. */
122
+ export const waitForProcessGroup = async (pgid, timeoutMs, pollMs = 1_000) => {
123
+ const deadline = Date.now() + timeoutMs;
124
+ while (pgidAlive(pgid) && Date.now() < deadline) {
125
+ await new Promise((resolve) => { setTimeout(resolve, pollMs); });
126
+ }
127
+ };
128
+ /** The answer a finished call left in its folder, when its events prove a completed, tool-free turn. */
129
+ const finishedAnswer = async (callDir) => {
130
+ const [events, bytes] = await Promise.all([
131
+ readEvents(path.join(callDir, 'events.jsonl')),
132
+ readFile(path.join(callDir, 'final.txt')).catch(() => null),
133
+ ]);
134
+ if (!bytes || bytes.length === 0 || events.completed !== 1 || events.failed > 0 || events.tools.length > 0)
135
+ return null;
136
+ return bytes;
137
+ };
138
+ /** What shows a planner turn is over (its child writes its events and answer file itself): an answer, or a failed turn. */
139
+ const planCallOver = async (callDir) => {
140
+ if (await finishedAnswer(callDir))
141
+ return 'answer';
142
+ return (await readEvents(path.join(callDir, 'events.jsonl'))).failed > 0 ? 'turn-failed' : null;
143
+ };
144
+ /**
145
+ * One planner attempt. Throws the store's `NEEDS_RECONCILIATION` when a call
146
+ * that was dispatched ended without a usable answer (never re-dispatched), and
147
+ * any other error when Codex could not be started at all (nothing was sent, so
148
+ * a resume may try the same call again).
149
+ */
150
+ export const runBranchPlanCall = async (call) => {
151
+ const runtime = await importRuntime();
152
+ const store = runtime.createStore(call.root);
153
+ const binary = resolveCodexBinary(call.env);
154
+ const prompt = buildBranchPlannerPrompt({
155
+ concept: call.concept,
156
+ ...(call.maxScreens === undefined ? {} : { maxScreens: call.maxScreens }),
157
+ ...(call.scope === undefined ? {} : { scope: call.scope }),
158
+ });
159
+ const schema = JSON.stringify(branchPlanResponseSchema().schema);
160
+ const callId = branchPlanCallId(call.runId, call.attempt);
161
+ const timeoutMs = call.timeoutMs ?? BRANCH_PLAN_TIMEOUT_MS;
162
+ const request = {
163
+ kind: 'branch-plan',
164
+ model: BUILD_PLAN_MODEL,
165
+ effort: BRANCH_PLAN_EFFORT,
166
+ attempt: call.attempt,
167
+ systemSha256: sha256(BRANCH_PLANNER_SYSTEM_PROMPT),
168
+ promptSha256: sha256(prompt),
169
+ schemaSha256: sha256(schema),
170
+ winnerSha256: call.winner.sha256,
171
+ };
172
+ let home = null;
173
+ const result = await store.runCall(callId, request, async ({ callDir, persistMetadata }) => {
174
+ const workDir = path.join(callDir, 'work');
175
+ await mkdir(workDir, { recursive: true });
176
+ const finalPath = path.join(callDir, 'final.txt');
177
+ const schemaPath = path.join(callDir, 'schema.json');
178
+ const imagePath = path.join(callDir, `design.${extensionOf(call.winner.mediaType)}`);
179
+ // The exact words, schema and image this call sends, kept with it.
180
+ await Promise.all([
181
+ writeFile(path.join(callDir, 'system.txt'), BRANCH_PLANNER_SYSTEM_PROMPT, { flag: 'wx' }),
182
+ writeFile(path.join(callDir, 'prompt.txt'), prompt, { flag: 'wx' }),
183
+ writeFile(schemaPath, schema, { flag: 'wx' }),
184
+ writeFile(imagePath, call.winner.bytes, { flag: 'wx' }),
185
+ ]);
186
+ const argv = branchPlannerArgv({ workDir, finalPath, schemaPath, imagePath, disabledFeatures: runtime.disabledFeatures, serviceTier: home.serviceTier });
187
+ const startedAt = new Date().toISOString();
188
+ const invocation = { model: BUILD_PLAN_MODEL, effort: BRANCH_PLAN_EFFORT, authentication: 'chatgpt', noTools: true, home: home.home, envHome: home.envHome, argv, startedAt };
189
+ await writeFile(path.join(callDir, 'invocation.json'), `${JSON.stringify(invocation, null, 2)}\n`, { flag: 'wx' });
190
+ const stdout = await open(path.join(callDir, 'events.jsonl'), 'wx');
191
+ const stderr = await open(path.join(callDir, 'stderr.log'), 'wx');
192
+ let exit;
193
+ let timedOut = false;
194
+ try {
195
+ const child = spawn(binary, argv, { cwd: workDir, env: runtime.subscriptionEnv(home.envHome), detached: true, stdio: ['pipe', stdout.fd, stderr.fd] });
196
+ const stop = (signal) => {
197
+ if (!child.pid)
198
+ return;
199
+ try {
200
+ process.kill(-child.pid, signal);
201
+ }
202
+ catch (error) {
203
+ if (!['ESRCH', 'EPERM'].includes(error.code ?? ''))
204
+ throw error;
205
+ }
206
+ };
207
+ let killTimer;
208
+ const terminate = () => { stop('SIGTERM'); killTimer = setTimeout(() => stop('SIGKILL'), 5_000); };
209
+ const timer = setTimeout(() => { timedOut = true; terminate(); }, timeoutMs);
210
+ const interruptible = call.processOptions?.interruptOnSignal !== false;
211
+ if (interruptible) {
212
+ process.once('SIGINT', terminate);
213
+ process.once('SIGTERM', terminate);
214
+ }
215
+ const closed = new Promise((resolve) => {
216
+ child.once('error', (error) => { resolve({ exitCode: null, signal: null, spawnError: String(error) }); });
217
+ child.once('close', (exitCode, signal) => { resolve({ exitCode, signal, spawnError: null }); });
218
+ });
219
+ child.stdin?.on('error', () => undefined);
220
+ child.stdin?.end(prompt);
221
+ if (child.pid) {
222
+ await persistMetadata({ ...invocation, pgid: child.pid });
223
+ try {
224
+ await call.processOptions?.onSpawn?.({ pgid: child.pid, callDir });
225
+ }
226
+ catch { /* bookkeeping only */ }
227
+ }
228
+ exit = await closed;
229
+ clearTimeout(timer);
230
+ clearTimeout(killTimer);
231
+ if (interruptible) {
232
+ process.removeListener('SIGINT', terminate);
233
+ process.removeListener('SIGTERM', terminate);
234
+ }
235
+ if (child.pid) {
236
+ try {
237
+ await call.processOptions?.onExit?.({ pgid: child.pid });
238
+ }
239
+ catch { /* bookkeeping only */ }
240
+ }
241
+ }
242
+ finally {
243
+ await stdout.sync().catch(() => undefined);
244
+ await stderr.sync().catch(() => undefined);
245
+ await stdout.close();
246
+ await stderr.close();
247
+ }
248
+ const events = await readEvents(path.join(callDir, 'events.jsonl'));
249
+ const finishedAt = new Date().toISOString();
250
+ const audit = await auditTurn(runtime, home.home, events.threadId, [startedAt, finishedAt]);
251
+ const bytes = await readFile(finalPath).catch(() => null);
252
+ const completion = { ...exit, timedOut, threadId: events.threadId, events, audit, finalSha256: bytes ? sha256(bytes) : null, finishedAt };
253
+ await writeFile(path.join(callDir, 'completion.json'), `${JSON.stringify(completion, null, 2)}\n`, { flag: 'wx' });
254
+ if (exit.exitCode !== 0 || exit.signal || exit.spawnError || timedOut)
255
+ throw new Error('The planner turn did not complete.');
256
+ if (!bytes || bytes.length === 0 || events.completed !== 1 || events.failed > 0 || events.tools.length > 0 || events.malformed > 0) {
257
+ throw new Error('The planner turn broke the one-answer, no-tool protocol.');
258
+ }
259
+ if (!audit || audit.model !== BUILD_PLAN_MODEL || audit.effort !== BRANCH_PLAN_EFFORT || audit.tools > 0) {
260
+ throw new Error(`The planner turn's session does not prove ${BUILD_PLAN_MODEL} at ${BRANCH_PLAN_EFFORT} effort with no tools.`);
261
+ }
262
+ return { bytes, metadata: { ...invocation, pgid: null, threadId: events.threadId, audit, finishedAt } };
263
+ }, {
264
+ // Readiness for THIS call, before anything is sent: a failure here leaves the call unsent and resumable.
265
+ prepare: async () => {
266
+ home = await runtime.prepareCallerHome({ callerHome: call.env.CODEX_HOME?.trim() || null, binary, model: BUILD_PLAN_MODEL });
267
+ },
268
+ // A call dispatched by an earlier process: wait out its process group, then read the answer it left. A process that
269
+ // died between the spawn and recording the group left nothing to wait on: the call may still be running, so its
270
+ // answer is awaited until it lands, its turn fails, or the call's window closes (branch-local-call-wait.ts).
271
+ recover: async ({ callDir, metadata }) => {
272
+ if (metadata?.pgid)
273
+ await waitForProcessGroup(metadata.pgid, timeoutMs);
274
+ else
275
+ await waitForUnrecordedCall({ callDir, timeoutMs, finished: async () => planCallOver(callDir) });
276
+ const bytes = await finishedAnswer(callDir);
277
+ return bytes ? { bytes, metadata: { ...metadata, pgid: null, recovered: true } } : null;
278
+ },
279
+ });
280
+ return { raw: result.bytes.toString('utf8'), reused: result.reused, callId };
281
+ };
282
+ //# sourceMappingURL=branch-local-plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-local-plan.js","sourceRoot":"","sources":["../src/branch-local-plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export declare const SESSION_SEARCH_FILE = "session-search.json";
2
+ export type SessionSearch = {
3
+ callId: string;
4
+ searchedAt: string;
5
+ /**
6
+ * `matched`: exactly one session matched and its thread id now drives the store's recovery, which adopts its image
7
+ * (or, for a session without one, settles the call as it settles any call that drew nothing).
8
+ */
9
+ outcome: 'matched' | 'no-match' | 'ambiguous' | 'unverifiable-references';
10
+ window: {
11
+ from: string;
12
+ to: string;
13
+ };
14
+ home: string;
15
+ /** Session files written inside the window that were read. */
16
+ examined: number;
17
+ matches: Array<{
18
+ file: string;
19
+ sha256: string;
20
+ threadId: string | null;
21
+ }>;
22
+ threadId?: string;
23
+ };
24
+ /**
25
+ * The session files that carry the inputs of a dispatched call whose thread id was never announced, read only (no
26
+ * record, no adoption): what a resume watches while such a call may still be drawing (branch-local-call-wait.ts).
27
+ */
28
+ export declare const unannouncedSessionFiles: (callDir: string, now?: () => number) => Promise<string[]>;
29
+ /**
30
+ * Searches for the session of one dispatched image call that never recorded its thread id, and adopts it when exactly
31
+ * one matches (its thread id is written into the call's state). Null when there is nothing to search: no call, a call
32
+ * already settled, one the store cannot recover (no home recorded), or one whose thread id the store already knows.
33
+ */
34
+ export declare const adoptUnannouncedSession: (callDir: string, now?: () => number) => Promise<SessionSearch | null>;
35
+ //# sourceMappingURL=branch-local-session-adoption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-local-session-adoption.d.ts","sourceRoot":"","sources":["../src/branch-local-session-adoption.ts"],"names":[],"mappings":"AA2CA,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,OAAO,EAAE,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,yBAAyB,CAAC;IAC1E,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AA0IF;;;GAGG;AACH,eAAO,MAAM,uBAAuB,GAAU,SAAS,MAAM,EAAE,MAAK,MAAM,MAAiB,KAAG,OAAO,CAAC,MAAM,EAAE,CAE7G,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAU,SAAS,MAAM,EAAE,MAAK,MAAM,MAAiB,KAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAqBzH,CAAC"}
@@ -0,0 +1,185 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readdir, readFile, stat } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
+ const importRuntime = async () => {
6
+ const base = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'runtime', 'codex-conversion', 'src');
7
+ const load = async (file) => await import(pathToFileURL(path.join(base, file)).href);
8
+ const modules = await Promise.all(['run-store-io.mjs', 'codex/caller-home.mjs', 'images/native-records.mjs', 'images/native.mjs'].map(load));
9
+ return Object.assign({}, ...modules);
10
+ };
11
+ export const SESSION_SEARCH_FILE = 'session-search.json';
12
+ const sha256 = (bytes) => createHash('sha256').update(bytes).digest('hex');
13
+ /**
14
+ * The day folders (`sessions/YYYY/MM/DD`, local and UTC) the store's recovery looks in for a call's session (Codex
15
+ * files a session under the day it started): the call's dispatch day and today's.
16
+ */
17
+ const dayDirectories = (home, from, to) => {
18
+ const pad = (value) => String(value).padStart(2, '0');
19
+ const days = new Set();
20
+ for (const date of [new Date(from), new Date(to)]) {
21
+ days.add(path.join(home, 'sessions', String(date.getFullYear()), pad(date.getMonth() + 1), pad(date.getDate())));
22
+ days.add(path.join(home, 'sessions', String(date.getUTCFullYear()), pad(date.getUTCMonth() + 1), pad(date.getUTCDate())));
23
+ }
24
+ return [...days];
25
+ };
26
+ /** The call's attached images in attach order (`reference.<ext>`, `reference-<n>.<ext>`), only when each is the digest its request names. */
27
+ const verifiedReferences = async (callDir, digests) => {
28
+ if (!Array.isArray(digests) || digests.length === 0)
29
+ return null;
30
+ const byIndex = new Map();
31
+ for (const name of await readdir(callDir)) {
32
+ const match = /^reference(?:-(\d+))?\.(?:png|jpg|webp|gif)$/u.exec(name);
33
+ if (match)
34
+ byIndex.set(match[1] ? Number(match[1]) : 1, path.join(callDir, name));
35
+ }
36
+ if (byIndex.size !== digests.length)
37
+ return null;
38
+ const files = [];
39
+ for (let index = 1; index <= digests.length; index += 1) {
40
+ const file = byIndex.get(index);
41
+ if (!file || sha256(await readFile(file)) !== digests[index - 1])
42
+ return null;
43
+ files.push(file);
44
+ }
45
+ return files;
46
+ };
47
+ /** Every string value in a parsed record, however deep (a session's messages and tool inputs). */
48
+ const stringsOf = (value, into = []) => {
49
+ if (typeof value === 'string')
50
+ into.push(value);
51
+ else if (Array.isArray(value))
52
+ for (const entry of value)
53
+ stringsOf(entry, into);
54
+ else if (value && typeof value === 'object')
55
+ for (const entry of Object.values(value))
56
+ stringsOf(entry, into);
57
+ return into;
58
+ };
59
+ /** The path as it can appear in a session: raw, or escaped inside one or two levels of JSON string. */
60
+ const pathSpellings = (file) => {
61
+ const once = JSON.stringify(file).slice(1, -1);
62
+ return [...new Set([file, once, JSON.stringify(once).slice(1, -1)])];
63
+ };
64
+ const sessionMatches = (runtime, text, references, prompt, wrapper) => {
65
+ if (!references.every((file) => pathSpellings(file).some((spelling) => text.includes(spelling))))
66
+ return false;
67
+ let literals = [];
68
+ try {
69
+ literals = runtime.parseNativeRecords(text).calls.flatMap((call) => call.prompts ?? []);
70
+ }
71
+ catch {
72
+ literals = [];
73
+ }
74
+ if (literals.includes(prompt))
75
+ return true;
76
+ for (const line of text.split('\n')) {
77
+ if (!line.includes('IMAGE PROMPT'))
78
+ continue;
79
+ try {
80
+ if (stringsOf(JSON.parse(line)).some((value) => value.includes(wrapper)))
81
+ return true;
82
+ }
83
+ catch { /* a malformed line is the collector's to report */ }
84
+ }
85
+ return false;
86
+ };
87
+ /** The thread id a session file is named by, confirmed by the session's own id when it records one. */
88
+ const threadIdOfSession = (file, text) => {
89
+ const name = path.basename(file);
90
+ const firstLine = text.slice(0, text.indexOf('\n') === -1 ? text.length : text.indexOf('\n'));
91
+ try {
92
+ const record = JSON.parse(firstLine);
93
+ const id = record.type === 'session_meta' && typeof record.payload?.id === 'string' ? record.payload.id : null;
94
+ if (id && name.endsWith(`-${id}.jsonl`))
95
+ return id;
96
+ }
97
+ catch { /* fall back to the name */ }
98
+ return /^rollout-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-(.+)\.jsonl$/u.exec(name)?.[1] ?? null;
99
+ };
100
+ /** The sessions in the call's Codex home that carry the call's own inputs; null when there is nothing to search. */
101
+ const searchSessions = async (callDir, now) => {
102
+ const runtime = await importRuntime();
103
+ const statePath = path.join(callDir, 'state.json');
104
+ const state = await runtime.readJson(statePath);
105
+ const metadata = state?.metadata;
106
+ if (!state || state.status !== 'dispatched' || typeof metadata?.home !== 'string' || typeof metadata.startedAt !== 'string')
107
+ return null;
108
+ if (typeof metadata.threadId === 'string' || await runtime.threadIdOf(path.join(callDir, 'events.jsonl')))
109
+ return null;
110
+ const request = await runtime.readJson(path.join(callDir, 'request.json'));
111
+ if (!request || runtime.hash(runtime.canonical(request)) !== state.requestHash || typeof request.prompt !== 'string')
112
+ return null;
113
+ const home = metadata.home;
114
+ const from = Date.parse(metadata.startedAt);
115
+ if (Number.isNaN(from))
116
+ return null;
117
+ const to = now();
118
+ const base = { callId: String(state.id), searchedAt: new Date(to).toISOString(), window: { from: metadata.startedAt, to: new Date(to).toISOString() }, home };
119
+ const found = { runtime, state, metadata: metadata, statePath, base, examined: 0, matches: [] };
120
+ const references = await verifiedReferences(callDir, request.inputSha256);
121
+ if (!references)
122
+ return { ...found, references: null };
123
+ const wrapper = runtime.nativeCallPrompt(references, request.prompt).trimEnd();
124
+ for (const directory of dayDirectories(home, from, to)) {
125
+ let names;
126
+ try {
127
+ names = await readdir(directory);
128
+ }
129
+ catch (error) {
130
+ if (error.code === 'ENOENT')
131
+ continue;
132
+ throw error;
133
+ }
134
+ for (const name of names.filter((entry) => entry.startsWith('rollout-') && entry.endsWith('.jsonl')).sort()) {
135
+ const file = path.join(directory, name);
136
+ // Written inside the window (one second of slack for coarse file times): a session the call could have started.
137
+ const { mtimeMs } = await stat(file);
138
+ if (mtimeMs < from - 1_000 || mtimeMs > to + 1_000)
139
+ continue;
140
+ found.examined += 1;
141
+ const bytes = await readFile(file);
142
+ const text = bytes.toString('utf8');
143
+ if (sessionMatches(runtime, text, references, request.prompt, wrapper)) {
144
+ found.matches.push({ file, sha256: sha256(bytes), threadId: threadIdOfSession(file, text) });
145
+ }
146
+ }
147
+ }
148
+ return { ...found, references };
149
+ };
150
+ /**
151
+ * The session files that carry the inputs of a dispatched call whose thread id was never announced, read only (no
152
+ * record, no adoption): what a resume watches while such a call may still be drawing (branch-local-call-wait.ts).
153
+ */
154
+ export const unannouncedSessionFiles = async (callDir, now = Date.now) => ((await searchSessions(callDir, now))?.matches.map((match) => match.file) ?? []);
155
+ /**
156
+ * Searches for the session of one dispatched image call that never recorded its thread id, and adopts it when exactly
157
+ * one matches (its thread id is written into the call's state). Null when there is nothing to search: no call, a call
158
+ * already settled, one the store cannot recover (no home recorded), or one whose thread id the store already knows.
159
+ */
160
+ export const adoptUnannouncedSession = async (callDir, now = Date.now) => {
161
+ const found = await searchSessions(callDir, now);
162
+ if (!found)
163
+ return null;
164
+ const { runtime, state, metadata, statePath, base, examined, matches } = found;
165
+ const record = async (search) => {
166
+ await runtime.writeJson(path.join(callDir, SESSION_SEARCH_FILE), search);
167
+ return search;
168
+ };
169
+ if (!found.references)
170
+ return record({ ...base, outcome: 'unverifiable-references', examined: 0, matches: [] });
171
+ if (matches.length !== 1)
172
+ return record({ ...base, outcome: matches.length ? 'ambiguous' : 'no-match', examined, matches });
173
+ const [match] = matches;
174
+ // The thread id must find this one session the way the store's recovery will look it up, or nothing is adopted.
175
+ const located = match.threadId ? await runtime.callRollouts(base.home, match.threadId, [metadata.startedAt, Date.parse(base.searchedAt)]) : [];
176
+ if (located.length !== 1 || located[0] !== match.file)
177
+ return record({ ...base, outcome: 'ambiguous', examined, matches });
178
+ const search = await record({ ...base, outcome: 'matched', examined, matches, threadId: match.threadId });
179
+ await runtime.writeJson(statePath, {
180
+ ...state,
181
+ metadata: { ...metadata, threadId: match.threadId, threadIdSource: { kind: 'session-search', file: match.file, sha256: match.sha256, searchedAt: search.searchedAt } },
182
+ });
183
+ return search;
184
+ };
185
+ //# sourceMappingURL=branch-local-session-adoption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"branch-local-session-adoption.js","sourceRoot":"","sources":["../src/branch-local-session-adoption.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { TwelveUiBranchClient } from './branch-client.js';
1
+ import type { BranchRunClient } from './branch-client.js';
2
2
  import { type BranchDownloadedScreen } from './branch-downloads.js';
3
3
  import type { BranchExecutionInputs } from './branch-execution-types.js';
4
4
  /**
@@ -24,7 +24,7 @@ export type BranchRunMaterializer = {
24
24
  finish: () => Promise<void>;
25
25
  };
26
26
  export declare const createRunMaterializer: (args: {
27
- client: TwelveUiBranchClient;
27
+ client: BranchRunClient;
28
28
  runId: string;
29
29
  inputs: BranchExecutionInputs;
30
30
  screensDirectory: string;
@@ -1 +1 @@
1
- {"version":3,"file":"branch-materialize.d.ts","sourceRoot":"","sources":["../src/branch-materialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAKL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEzE;;;;;;;;;GASG;AAEH,MAAM,MAAM,qBAAqB,GAAG;IAClC,0EAA0E;IAC1E,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACnF;;;;OAIG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9C,oEAAoE;IACpE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM;IAC1C,MAAM,EAAE,oBAAoB,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,KAAG,qBAqEH,CAAC"}
1
+ {"version":3,"file":"branch-materialize.d.ts","sourceRoot":"","sources":["../src/branch-materialize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAKL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAEzE;;;;;;;;;GASG;AAEH,MAAM,MAAM,qBAAqB,GAAG;IAClC,0EAA0E;IAC1E,MAAM,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC;IACnF;;;;OAIG;IACH,MAAM,EAAE,MAAM,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAC9C,oEAAoE;IACpE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM;IAC1C,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,qBAAqB,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,KAAG,qBAqEH,CAAC"}
@@ -249,7 +249,7 @@ export const convertBranchPage = async (args) => {
249
249
  const branchAttempt = recovery && recoveryTarget
250
250
  ? {
251
251
  version: 1,
252
- workflow_revision: BRANCH_WORKFLOW_REVISION,
252
+ workflow_revision: args.branchWorkflowRevision ?? BRANCH_WORKFLOW_REVISION,
253
253
  logical_run_id: args.plan.runId,
254
254
  logical_page_id: page.id,
255
255
  generation: recovery.generation,