@12ui/design 0.2.76 → 0.2.78

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 (337) hide show
  1. package/SKILL.md +1 -1
  2. package/dist/cli-codex-readiness.d.ts +6 -0
  3. package/dist/cli-codex-readiness.d.ts.map +1 -1
  4. package/dist/cli-codex-readiness.js +12 -12
  5. package/dist/cli-codex-readiness.js.map +1 -1
  6. package/dist/cli-help/design.d.ts +2 -2
  7. package/dist/cli-help/design.d.ts.map +1 -1
  8. package/dist/cli-help/design.js +2 -0
  9. package/dist/cli-help/design.js.map +1 -1
  10. package/dist/cli-help/index.d.ts +2 -2
  11. package/dist/cli-review-command.d.ts.map +1 -1
  12. package/dist/cli-review-command.js +2 -0
  13. package/dist/cli-review-command.js.map +1 -1
  14. package/dist/cli-run.d.ts.map +1 -1
  15. package/dist/cli-run.js +6 -0
  16. package/dist/cli-run.js.map +1 -1
  17. package/dist/cli-workspace-draw.d.ts +1 -11
  18. package/dist/cli-workspace-draw.d.ts.map +1 -1
  19. package/dist/cli-workspace-draw.js +18 -18
  20. package/dist/cli-workspace-draw.js.map +1 -1
  21. package/dist/cli-workspace-runner.d.ts +30 -0
  22. package/dist/cli-workspace-runner.d.ts.map +1 -0
  23. package/dist/cli-workspace-runner.js +105 -0
  24. package/dist/cli-workspace-runner.js.map +1 -0
  25. package/dist/mcp-slate-image.js +1 -1
  26. package/dist/mcp-slate-image.js.map +1 -1
  27. package/dist/mcp-slate-tool-defs.js +1 -1
  28. package/dist/mcp-slate-tool-defs.js.map +1 -1
  29. package/dist/mcp-slate-ui-copy.d.ts +403 -33
  30. package/dist/mcp-slate-ui-copy.d.ts.map +1 -1
  31. package/dist/mcp-slate-ui-copy.js +247 -57
  32. package/dist/mcp-slate-ui-copy.js.map +1 -1
  33. package/dist/mcp-slate-ui-icu.d.ts +47 -0
  34. package/dist/mcp-slate-ui-icu.d.ts.map +1 -0
  35. package/dist/mcp-slate-ui-icu.js +229 -0
  36. package/dist/mcp-slate-ui-icu.js.map +1 -0
  37. package/dist/mcp-slate-ui-locale-match.d.ts +12 -0
  38. package/dist/mcp-slate-ui-locale-match.d.ts.map +1 -0
  39. package/dist/mcp-slate-ui-locale-match.js +34 -0
  40. package/dist/mcp-slate-ui-locale-match.js.map +1 -0
  41. package/dist/mcp-slate-ui-locales/de-DE.d.ts +9 -0
  42. package/dist/mcp-slate-ui-locales/de-DE.d.ts.map +1 -0
  43. package/dist/mcp-slate-ui-locales/de-DE.js +217 -0
  44. package/dist/mcp-slate-ui-locales/de-DE.js.map +1 -0
  45. package/dist/mcp-slate-ui-locales/es-419.d.ts +9 -0
  46. package/dist/mcp-slate-ui-locales/es-419.d.ts.map +1 -0
  47. package/dist/mcp-slate-ui-locales/es-419.js +217 -0
  48. package/dist/mcp-slate-ui-locales/es-419.js.map +1 -0
  49. package/dist/mcp-slate-ui-locales/es-ES.d.ts +9 -0
  50. package/dist/mcp-slate-ui-locales/es-ES.d.ts.map +1 -0
  51. package/dist/mcp-slate-ui-locales/es-ES.js +217 -0
  52. package/dist/mcp-slate-ui-locales/es-ES.js.map +1 -0
  53. package/dist/mcp-slate-ui-locales/fr-FR.d.ts +9 -0
  54. package/dist/mcp-slate-ui-locales/fr-FR.d.ts.map +1 -0
  55. package/dist/mcp-slate-ui-locales/fr-FR.js +217 -0
  56. package/dist/mcp-slate-ui-locales/fr-FR.js.map +1 -0
  57. package/dist/mcp-slate-ui-locales/hi-IN.d.ts +9 -0
  58. package/dist/mcp-slate-ui-locales/hi-IN.d.ts.map +1 -0
  59. package/dist/mcp-slate-ui-locales/hi-IN.js +217 -0
  60. package/dist/mcp-slate-ui-locales/hi-IN.js.map +1 -0
  61. package/dist/mcp-slate-ui-locales/index.d.ts +11 -0
  62. package/dist/mcp-slate-ui-locales/index.d.ts.map +1 -0
  63. package/dist/mcp-slate-ui-locales/index.js +34 -0
  64. package/dist/mcp-slate-ui-locales/index.js.map +1 -0
  65. package/dist/mcp-slate-ui-locales/it-IT.d.ts +9 -0
  66. package/dist/mcp-slate-ui-locales/it-IT.d.ts.map +1 -0
  67. package/dist/mcp-slate-ui-locales/it-IT.js +217 -0
  68. package/dist/mcp-slate-ui-locales/it-IT.js.map +1 -0
  69. package/dist/mcp-slate-ui-locales/ja-JP.d.ts +9 -0
  70. package/dist/mcp-slate-ui-locales/ja-JP.d.ts.map +1 -0
  71. package/dist/mcp-slate-ui-locales/ja-JP.js +217 -0
  72. package/dist/mcp-slate-ui-locales/ja-JP.js.map +1 -0
  73. package/dist/mcp-slate-ui-locales/ko-KR.d.ts +9 -0
  74. package/dist/mcp-slate-ui-locales/ko-KR.d.ts.map +1 -0
  75. package/dist/mcp-slate-ui-locales/ko-KR.js +217 -0
  76. package/dist/mcp-slate-ui-locales/ko-KR.js.map +1 -0
  77. package/dist/mcp-slate-ui-locales/pt-BR.d.ts +9 -0
  78. package/dist/mcp-slate-ui-locales/pt-BR.d.ts.map +1 -0
  79. package/dist/mcp-slate-ui-locales/pt-BR.js +217 -0
  80. package/dist/mcp-slate-ui-locales/pt-BR.js.map +1 -0
  81. package/dist/mcp-slate-ui-locales/zh-CN.d.ts +9 -0
  82. package/dist/mcp-slate-ui-locales/zh-CN.d.ts.map +1 -0
  83. package/dist/mcp-slate-ui-locales/zh-CN.js +217 -0
  84. package/dist/mcp-slate-ui-locales/zh-CN.js.map +1 -0
  85. package/dist/mcp-slate-ui-locales/zh-TW.d.ts +9 -0
  86. package/dist/mcp-slate-ui-locales/zh-TW.d.ts.map +1 -0
  87. package/dist/mcp-slate-ui-locales/zh-TW.js +217 -0
  88. package/dist/mcp-slate-ui-locales/zh-TW.js.map +1 -0
  89. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -1
  90. package/dist/mcp-slate-ui-script-bridge.js +8 -9
  91. package/dist/mcp-slate-ui-script-bridge.js.map +1 -1
  92. package/dist/mcp-slate-ui-script-dialog.d.ts.map +1 -1
  93. package/dist/mcp-slate-ui-script-dialog.js +60 -30
  94. package/dist/mcp-slate-ui-script-dialog.js.map +1 -1
  95. package/dist/mcp-slate-ui-script-inline.d.ts +9 -6
  96. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -1
  97. package/dist/mcp-slate-ui-script-inline.js +91 -46
  98. package/dist/mcp-slate-ui-script-inline.js.map +1 -1
  99. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts +20 -0
  100. package/dist/mcp-slate-ui-script-inspiration-collage.d.ts.map +1 -0
  101. package/dist/mcp-slate-ui-script-inspiration-collage.js +68 -0
  102. package/dist/mcp-slate-ui-script-inspiration-collage.js.map +1 -0
  103. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts +26 -0
  104. package/dist/mcp-slate-ui-script-inspiration-grid.d.ts.map +1 -0
  105. package/dist/mcp-slate-ui-script-inspiration-grid.js +246 -0
  106. package/dist/mcp-slate-ui-script-inspiration-grid.js.map +1 -0
  107. package/dist/mcp-slate-ui-script-inspiration.d.ts +10 -9
  108. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -1
  109. package/dist/mcp-slate-ui-script-inspiration.js +161 -120
  110. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -1
  111. package/dist/mcp-slate-ui-script-l10n.d.ts +29 -0
  112. package/dist/mcp-slate-ui-script-l10n.d.ts.map +1 -0
  113. package/dist/mcp-slate-ui-script-l10n.js +135 -0
  114. package/dist/mcp-slate-ui-script-l10n.js.map +1 -0
  115. package/dist/mcp-slate-ui-script-more.d.ts +3 -2
  116. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -1
  117. package/dist/mcp-slate-ui-script-more.js +19 -18
  118. package/dist/mcp-slate-ui-script-more.js.map +1 -1
  119. package/dist/mcp-slate-ui-script-pause.d.ts +33 -0
  120. package/dist/mcp-slate-ui-script-pause.d.ts.map +1 -0
  121. package/dist/mcp-slate-ui-script-pause.js +217 -0
  122. package/dist/mcp-slate-ui-script-pause.js.map +1 -0
  123. package/dist/mcp-slate-ui-script-remote.d.ts +2 -0
  124. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -1
  125. package/dist/mcp-slate-ui-script-remote.js +47 -6
  126. package/dist/mcp-slate-ui-script-remote.js.map +1 -1
  127. package/dist/mcp-slate-ui-script-scribble.js +1 -1
  128. package/dist/mcp-slate-ui-script-select.js +6 -6
  129. package/dist/mcp-slate-ui-script-stage.d.ts +3 -2
  130. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -1
  131. package/dist/mcp-slate-ui-script-stage.js +31 -19
  132. package/dist/mcp-slate-ui-script-stage.js.map +1 -1
  133. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -1
  134. package/dist/mcp-slate-ui-script-state.js +77 -57
  135. package/dist/mcp-slate-ui-script-state.js.map +1 -1
  136. package/dist/mcp-slate-ui-script.d.ts +2 -2
  137. package/dist/mcp-slate-ui-script.d.ts.map +1 -1
  138. package/dist/mcp-slate-ui-script.js +21 -7
  139. package/dist/mcp-slate-ui-script.js.map +1 -1
  140. package/dist/mcp-slate-ui-styles-dialog.d.ts +6 -7
  141. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +1 -1
  142. package/dist/mcp-slate-ui-styles-dialog.js +13 -29
  143. package/dist/mcp-slate-ui-styles-dialog.js.map +1 -1
  144. package/dist/mcp-slate-ui-styles-inspiration.d.ts +18 -0
  145. package/dist/mcp-slate-ui-styles-inspiration.d.ts.map +1 -0
  146. package/dist/mcp-slate-ui-styles-inspiration.js +43 -0
  147. package/dist/mcp-slate-ui-styles-inspiration.js.map +1 -0
  148. package/dist/mcp-slate-ui-styles-pause.d.ts +10 -0
  149. package/dist/mcp-slate-ui-styles-pause.d.ts.map +1 -0
  150. package/dist/mcp-slate-ui-styles-pause.js +25 -0
  151. package/dist/mcp-slate-ui-styles-pause.js.map +1 -0
  152. package/dist/mcp-slate-ui-styles-stage.d.ts +10 -6
  153. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -1
  154. package/dist/mcp-slate-ui-styles-stage.js +24 -16
  155. package/dist/mcp-slate-ui-styles-stage.js.map +1 -1
  156. package/dist/mcp-slate-ui-styles.d.ts +12 -5
  157. package/dist/mcp-slate-ui-styles.d.ts.map +1 -1
  158. package/dist/mcp-slate-ui-styles.js +38 -21
  159. package/dist/mcp-slate-ui-styles.js.map +1 -1
  160. package/dist/mcp-slate-ui.d.ts +11 -3
  161. package/dist/mcp-slate-ui.d.ts.map +1 -1
  162. package/dist/mcp-slate-ui.js +24 -16
  163. package/dist/mcp-slate-ui.js.map +1 -1
  164. package/dist/mosaic-bands.d.ts +44 -0
  165. package/dist/mosaic-bands.d.ts.map +1 -0
  166. package/dist/mosaic-bands.js +153 -0
  167. package/dist/mosaic-bands.js.map +1 -0
  168. package/dist/review-discovery.d.ts.map +1 -1
  169. package/dist/review-discovery.js +36 -54
  170. package/dist/review-discovery.js.map +1 -1
  171. package/dist/review-page.d.ts.map +1 -1
  172. package/dist/review-page.js +2 -1
  173. package/dist/review-page.js.map +1 -1
  174. package/dist/review-run-roots.d.ts +40 -0
  175. package/dist/review-run-roots.d.ts.map +1 -0
  176. package/dist/review-run-roots.js +94 -0
  177. package/dist/review-run-roots.js.map +1 -0
  178. package/dist/review-server.d.ts +2 -0
  179. package/dist/review-server.d.ts.map +1 -1
  180. package/dist/review-server.js +2 -0
  181. package/dist/review-server.js.map +1 -1
  182. package/dist/review-types.d.ts +10 -0
  183. package/dist/review-types.d.ts.map +1 -1
  184. package/dist/slate-actions.d.ts +3 -3
  185. package/dist/slate-actions.d.ts.map +1 -1
  186. package/dist/slate-actions.js +9 -8
  187. package/dist/slate-actions.js.map +1 -1
  188. package/dist/slate-browser-host-script.d.ts +4 -0
  189. package/dist/slate-browser-host-script.d.ts.map +1 -1
  190. package/dist/slate-browser-host-script.js +25 -6
  191. package/dist/slate-browser-host-script.js.map +1 -1
  192. package/dist/slate-browser-host.d.ts +2 -1
  193. package/dist/slate-browser-host.d.ts.map +1 -1
  194. package/dist/slate-browser-host.js +18 -5
  195. package/dist/slate-browser-host.js.map +1 -1
  196. package/dist/slate-commit.js +7 -7
  197. package/dist/slate-commit.js.map +1 -1
  198. package/dist/slate-corpus.d.ts.map +1 -1
  199. package/dist/slate-corpus.js +3 -2
  200. package/dist/slate-corpus.js.map +1 -1
  201. package/dist/slate-edit-runner.d.ts.map +1 -1
  202. package/dist/slate-edit-runner.js +5 -4
  203. package/dist/slate-edit-runner.js.map +1 -1
  204. package/dist/slate-editability.d.ts +2 -0
  205. package/dist/slate-editability.d.ts.map +1 -1
  206. package/dist/slate-editability.js +1 -1
  207. package/dist/slate-editability.js.map +1 -1
  208. package/dist/slate-errors.d.ts +7 -1
  209. package/dist/slate-errors.d.ts.map +1 -1
  210. package/dist/slate-errors.js +3 -2
  211. package/dist/slate-errors.js.map +1 -1
  212. package/dist/slate-handoff-options.d.ts +2 -1
  213. package/dist/slate-handoff-options.d.ts.map +1 -1
  214. package/dist/slate-handoff-options.js +2 -2
  215. package/dist/slate-handoff-options.js.map +1 -1
  216. package/dist/slate-handoff.js +1 -1
  217. package/dist/slate-handoff.js.map +1 -1
  218. package/dist/slate-image-executor.d.ts +28 -3
  219. package/dist/slate-image-executor.d.ts.map +1 -1
  220. package/dist/slate-image-executor.js +55 -11
  221. package/dist/slate-image-executor.js.map +1 -1
  222. package/dist/slate-inspiration.js +2 -2
  223. package/dist/slate-inspiration.js.map +1 -1
  224. package/dist/slate-local-image.d.ts.map +1 -1
  225. package/dist/slate-local-image.js +4 -1
  226. package/dist/slate-local-image.js.map +1 -1
  227. package/dist/slate-lock.js +1 -1
  228. package/dist/slate-lock.js.map +1 -1
  229. package/dist/slate-resume.js +6 -6
  230. package/dist/slate-resume.js.map +1 -1
  231. package/dist/slate-round-params.d.ts +3 -0
  232. package/dist/slate-round-params.d.ts.map +1 -1
  233. package/dist/slate-round-params.js +5 -0
  234. package/dist/slate-round-params.js.map +1 -1
  235. package/dist/slate-round-prompt.d.ts +15 -3
  236. package/dist/slate-round-prompt.d.ts.map +1 -1
  237. package/dist/slate-round-prompt.js +14 -5
  238. package/dist/slate-round-prompt.js.map +1 -1
  239. package/dist/slate-round-queries.d.ts +18 -0
  240. package/dist/slate-round-queries.d.ts.map +1 -0
  241. package/dist/slate-round-queries.js +29 -0
  242. package/dist/slate-round-queries.js.map +1 -0
  243. package/dist/slate-round-runner.d.ts.map +1 -1
  244. package/dist/slate-round-runner.js +12 -9
  245. package/dist/slate-round-runner.js.map +1 -1
  246. package/dist/slate-round-search.js +5 -5
  247. package/dist/slate-round-search.js.map +1 -1
  248. package/dist/slate-run-action.d.ts.map +1 -1
  249. package/dist/slate-run-action.js +2 -1
  250. package/dist/slate-run-action.js.map +1 -1
  251. package/dist/slate-runner-context.d.ts +3 -1
  252. package/dist/slate-runner-context.d.ts.map +1 -1
  253. package/dist/slate-runner-context.js +4 -3
  254. package/dist/slate-runner-context.js.map +1 -1
  255. package/dist/slate-runner-failure.d.ts +7 -1
  256. package/dist/slate-runner-failure.d.ts.map +1 -1
  257. package/dist/slate-runner-failure.js +6 -5
  258. package/dist/slate-runner-failure.js.map +1 -1
  259. package/dist/slate-runtime.d.ts.map +1 -1
  260. package/dist/slate-runtime.js +1 -0
  261. package/dist/slate-runtime.js.map +1 -1
  262. package/dist/slate-versions.js +3 -3
  263. package/dist/slate-versions.js.map +1 -1
  264. package/dist/slate-view-contract.d.ts +62 -1
  265. package/dist/slate-view-contract.d.ts.map +1 -1
  266. package/dist/slate-view-contract.js +30 -0
  267. package/dist/slate-view-contract.js.map +1 -1
  268. package/dist/slate-view.d.ts.map +1 -1
  269. package/dist/slate-view.js +19 -3
  270. package/dist/slate-view.js.map +1 -1
  271. package/dist/slate-workspace-parse.d.ts.map +1 -1
  272. package/dist/slate-workspace-parse.js +22 -0
  273. package/dist/slate-workspace-parse.js.map +1 -1
  274. package/dist/slate-workspace-types.d.ts +3 -1
  275. package/dist/slate-workspace-types.d.ts.map +1 -1
  276. package/dist/workspace-draw-client.d.ts +58 -5
  277. package/dist/workspace-draw-client.d.ts.map +1 -1
  278. package/dist/workspace-draw-client.js +82 -9
  279. package/dist/workspace-draw-client.js.map +1 -1
  280. package/dist/workspace-draw-codex.d.ts +9 -4
  281. package/dist/workspace-draw-codex.d.ts.map +1 -1
  282. package/dist/workspace-draw-codex.js +17 -3
  283. package/dist/workspace-draw-codex.js.map +1 -1
  284. package/dist/workspace-draw-messages.d.ts +31 -0
  285. package/dist/workspace-draw-messages.d.ts.map +1 -1
  286. package/dist/workspace-draw-messages.js +30 -0
  287. package/dist/workspace-draw-messages.js.map +1 -1
  288. package/dist/workspace-draw-run.d.ts +19 -1
  289. package/dist/workspace-draw-run.d.ts.map +1 -1
  290. package/dist/workspace-draw-run.js +98 -5
  291. package/dist/workspace-draw-run.js.map +1 -1
  292. package/dist/workspace-draw-store.d.ts +2 -0
  293. package/dist/workspace-draw-store.d.ts.map +1 -1
  294. package/dist/workspace-draw-store.js +3 -1
  295. package/dist/workspace-draw-store.js.map +1 -1
  296. package/dist/workspace-draw-types.d.ts +2 -0
  297. package/dist/workspace-draw-types.d.ts.map +1 -1
  298. package/dist/workspace-draw-types.js +2 -0
  299. package/dist/workspace-draw-types.js.map +1 -1
  300. package/dist/workspace-origin.d.ts +15 -0
  301. package/dist/workspace-origin.d.ts.map +1 -0
  302. package/dist/workspace-origin.js +36 -0
  303. package/dist/workspace-origin.js.map +1 -0
  304. package/dist/workspace-runner-children.d.ts +39 -0
  305. package/dist/workspace-runner-children.d.ts.map +1 -0
  306. package/dist/workspace-runner-children.js +139 -0
  307. package/dist/workspace-runner-children.js.map +1 -0
  308. package/dist/workspace-runner-client.d.ts +43 -0
  309. package/dist/workspace-runner-client.d.ts.map +1 -0
  310. package/dist/workspace-runner-client.js +72 -0
  311. package/dist/workspace-runner-client.js.map +1 -0
  312. package/dist/workspace-runner-main.d.ts +56 -0
  313. package/dist/workspace-runner-main.d.ts.map +1 -0
  314. package/dist/workspace-runner-main.js +378 -0
  315. package/dist/workspace-runner-main.js.map +1 -0
  316. package/dist/workspace-runner-policy.d.ts +40 -0
  317. package/dist/workspace-runner-policy.d.ts.map +1 -0
  318. package/dist/workspace-runner-policy.js +47 -0
  319. package/dist/workspace-runner-policy.js.map +1 -0
  320. package/dist/workspace-runner-spawn.d.ts +42 -0
  321. package/dist/workspace-runner-spawn.d.ts.map +1 -0
  322. package/dist/workspace-runner-spawn.js +60 -0
  323. package/dist/workspace-runner-spawn.js.map +1 -0
  324. package/dist/workspace-runner-stop.d.ts +25 -0
  325. package/dist/workspace-runner-stop.d.ts.map +1 -0
  326. package/dist/workspace-runner-stop.js +44 -0
  327. package/dist/workspace-runner-stop.js.map +1 -0
  328. package/dist/workspace-runner-store.d.ts +26 -0
  329. package/dist/workspace-runner-store.d.ts.map +1 -0
  330. package/dist/workspace-runner-store.js +114 -0
  331. package/dist/workspace-runner-store.js.map +1 -0
  332. package/open-design.json +2 -2
  333. package/package.json +1 -1
  334. package/runtime/codex-conversion/src/images/native-frame.mjs +103 -0
  335. package/runtime/codex-conversion/src/images/native-invoke.mjs +24 -5
  336. package/runtime/codex-conversion/src/images/native.mjs +14 -5
  337. package/runtime/codex-conversion/src/run-store.mjs +21 -1
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Which hosts the Design workspace's command line talks to, in one module (CLAUDE.md item 9).
3
+ *
4
+ * - `normalizeOrigin`: where `12ui workspace draw` may send the upload token: https, or http on this machine (a local
5
+ * proof worker), with no path.
6
+ * - `runnerOriginAllowed`: where a workspace runner may be left behind. A runner outlives the command and draws with
7
+ * the person's own Codex for as long as its server keeps answering, so it serves design.12ui.com alone, plus http on
8
+ * this machine for tests and a local dev worker; any other https host gets the draw and never a runner.
9
+ */
10
+ export const DEFAULT_ORIGIN = 'https://design.12ui.com';
11
+ const LOOPBACK = new Set(['localhost', '127.0.0.1', '[::1]']);
12
+ /** Only https, or http on this machine, with no path: the token goes to this host alone. Null when refused. */
13
+ export const normalizeOrigin = (value) => {
14
+ let url;
15
+ try {
16
+ url = new URL(value);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ const secure = url.protocol === 'https:' || (url.protocol === 'http:' && LOOPBACK.has(url.hostname));
22
+ if (!secure || url.username || url.password || url.search || url.hash || (url.pathname !== '/' && url.pathname !== ''))
23
+ return null;
24
+ return url.origin;
25
+ };
26
+ /** True only for design.12ui.com, or http on this machine. */
27
+ export const runnerOriginAllowed = (value) => {
28
+ const origin = normalizeOrigin(value);
29
+ if (origin === null)
30
+ return false;
31
+ if (origin === DEFAULT_ORIGIN)
32
+ return true;
33
+ const url = new URL(origin);
34
+ return url.protocol === 'http:' && LOOPBACK.has(url.hostname);
35
+ };
36
+ //# sourceMappingURL=workspace-origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-origin.js","sourceRoot":"","sources":["../src/workspace-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,yBAAyB,CAAC;AAExD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAE9D,+GAA+G;AAC/G,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAa,EAAiB,EAAE;IAC9D,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IACrG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IACpI,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC,CAAC;AAEF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAa,EAAW,EAAE;IAC5D,MAAM,MAAM,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClC,IAAI,MAAM,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,OAAO,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAChE,CAAC,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { CodexProcessOptions } from './slate-image-executor.js';
2
+ export type CodexChildRecord = {
3
+ pgid: number;
4
+ runnerPid: number;
5
+ runnerId?: string;
6
+ callDir: string;
7
+ startedAt: string;
8
+ };
9
+ /** `runnerId`: the runner that made the call, when its record names it. */
10
+ export type ReapOutcome = {
11
+ pgid: number;
12
+ callDir: string;
13
+ outcome: 'stopped' | 'gone' | 'not_ours';
14
+ runnerId?: string;
15
+ };
16
+ /** The executor hooks that keep the records: one written when a call's child starts, removed when it ends. */
17
+ export declare const codexChildRecorder: (dir: string, runnerId?: string) => Required<Pick<CodexProcessOptions, "onSpawn" | "onExit">>;
18
+ export declare const listCodexChildren: (dir: string) => Promise<CodexChildRecord[]>;
19
+ /**
20
+ * The same process hooks, each call also recorded under its request's own folder (`<opRoot>/codex/`), whoever draws it
21
+ * (the agent's command or a runner). The op lock's heartbeat stops while a Mac sleeps, so a lock that went quiet does
22
+ * not prove its run is gone; the call it started may still be drawing after the wake (`opCodexAlive`).
23
+ */
24
+ export declare const recordedForOp: (opRoot: string, options?: CodexProcessOptions) => CodexProcessOptions;
25
+ /**
26
+ * Whether a Codex call recorded for this request is still running: a live process group whose command line names the
27
+ * recorded call directory. A record whose group is gone (or now someone else's) is forgotten.
28
+ */
29
+ export declare const opCodexAlive: (opRoot: string) => Promise<boolean>;
30
+ /**
31
+ * Stop every recorded call whose runner is gone (a live runner finishes its own calls), and those of `alsoOf` (a
32
+ * runner stopping its own at its deadline), forgetting each record. A call still running gets SIGTERM, then SIGKILL
33
+ * after `graceMs`.
34
+ */
35
+ export declare const reapCodexChildren: (dir: string, options?: {
36
+ alsoOf?: number;
37
+ graceMs?: number;
38
+ }) => Promise<ReapOutcome[]>;
39
+ //# sourceMappingURL=workspace-runner-children.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-runner-children.d.ts","sourceRoot":"","sources":["../src/workspace-runner-children.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAgBrE,MAAM,MAAM,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAC1H,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAOzH,8GAA8G;AAC9G,eAAO,MAAM,kBAAkB,GAAI,KAAK,MAAM,EAAE,WAAW,MAAM,KAAG,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,QAAQ,CAAC,CAO1H,CAAC;AASH,eAAO,MAAM,iBAAiB,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,gBAAgB,EAAE,CAmB/E,CAAC;AAWF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,EAAE,UAAS,mBAAwB,KAAG,mBAOjF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,OAAO,CAOlE,CAAC;AAcF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAU,KAAK,MAAM,EAAE,UAAS;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAO,KAAG,OAAO,CAAC,WAAW,EAAE,CAsB/H,CAAC"}
@@ -0,0 +1,139 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { promisify } from 'node:util';
5
+ import { processIsAlive } from './slate-lock.js';
6
+ /**
7
+ * The Codex image calls a workspace runner has running, recorded by process group in its state folder
8
+ * (`codex/<pgid>.json`: the group, the runner's pid and id, the call directory). Each call runs in its own process group
9
+ * (native-invoke.mjs), so a runner killed outright (SIGKILL of it or of its group) leaves its calls running with no one
10
+ * to collect them. The next runner of that workspace, and `12ui workspace runner stop`, stop every recorded call whose
11
+ * runner is gone (one whose runner still lives is that runner's to finish). A call's argv names its call directory, and only a group whose command line names that same
12
+ * directory is signalled, so a process group id the system has since given to something else is never touched.
13
+ * The reaping names each dead runner's id, so the next runner can tell the server that runner's claims are over
14
+ * (its calls are stopped): its requests are then free at once instead of in flight until their quiet window ends.
15
+ */
16
+ const execFileAsync = promisify(execFile);
17
+ const RUNNER_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
18
+ const recordsDir = (dir) => path.join(dir, 'codex');
19
+ const recordFile = (dir, pgid) => path.join(recordsDir(dir), `${pgid}.json`);
20
+ /** The executor hooks that keep the records: one written when a call's child starts, removed when it ends. */
21
+ export const codexChildRecorder = (dir, runnerId) => ({
22
+ onSpawn: async ({ pgid, callDir }) => {
23
+ await mkdir(recordsDir(dir), { recursive: true, mode: 0o700 });
24
+ const record = { pgid, runnerPid: process.pid, ...(runnerId ? { runnerId } : {}), callDir, startedAt: new Date().toISOString() };
25
+ await writeFile(recordFile(dir, pgid), `${JSON.stringify(record)}\n`, { mode: 0o600 });
26
+ },
27
+ onExit: async ({ pgid }) => { await rm(recordFile(dir, pgid), { force: true }); },
28
+ });
29
+ const isRecord = (value) => {
30
+ const entry = value;
31
+ return !!entry && Number.isSafeInteger(entry.pgid) && entry.pgid > 1 && Number.isSafeInteger(entry.runnerPid)
32
+ && (entry.runnerId === undefined || (typeof entry.runnerId === 'string' && RUNNER_ID.test(entry.runnerId)))
33
+ && typeof entry.callDir === 'string' && path.isAbsolute(entry.callDir) && typeof entry.startedAt === 'string';
34
+ };
35
+ export const listCodexChildren = async (dir) => {
36
+ let names;
37
+ try {
38
+ names = await readdir(recordsDir(dir));
39
+ }
40
+ catch (error) {
41
+ if (error.code === 'ENOENT')
42
+ return [];
43
+ throw error;
44
+ }
45
+ const records = [];
46
+ for (const name of names.filter((entry) => /^\d+\.json$/u.test(entry))) {
47
+ try {
48
+ const parsed = JSON.parse(await readFile(path.join(recordsDir(dir), name), 'utf8'));
49
+ if (isRecord(parsed) && `${parsed.pgid}.json` === name)
50
+ records.push(parsed);
51
+ else
52
+ await rm(path.join(recordsDir(dir), name), { force: true });
53
+ }
54
+ catch {
55
+ await rm(path.join(recordsDir(dir), name), { force: true });
56
+ }
57
+ }
58
+ return records;
59
+ };
60
+ /** The command lines of a process group's live members, from `ps`; empty when none is alive. */
61
+ const groupCommands = async (pgid) => {
62
+ const { stdout } = await execFileAsync('ps', ['-ww', '-axo', 'pgid=,command='], { maxBuffer: 64 * 1024 * 1024 });
63
+ return stdout.split('\n').flatMap((line) => {
64
+ const match = /^\s*(\d+)\s+(.*)$/u.exec(line);
65
+ return match && Number(match[1]) === pgid ? [match[2]] : [];
66
+ });
67
+ };
68
+ /**
69
+ * The same process hooks, each call also recorded under its request's own folder (`<opRoot>/codex/`), whoever draws it
70
+ * (the agent's command or a runner). The op lock's heartbeat stops while a Mac sleeps, so a lock that went quiet does
71
+ * not prove its run is gone; the call it started may still be drawing after the wake (`opCodexAlive`).
72
+ */
73
+ export const recordedForOp = (opRoot, options = {}) => {
74
+ const op = codexChildRecorder(opRoot);
75
+ return {
76
+ ...options,
77
+ onSpawn: async (child) => { await op.onSpawn(child); await options.onSpawn?.(child); },
78
+ onExit: async (child) => { await options.onExit?.(child); await op.onExit(child); },
79
+ };
80
+ };
81
+ /**
82
+ * Whether a Codex call recorded for this request is still running: a live process group whose command line names the
83
+ * recorded call directory. A record whose group is gone (or now someone else's) is forgotten.
84
+ */
85
+ export const opCodexAlive = async (opRoot) => {
86
+ let alive = false;
87
+ for (const record of await listCodexChildren(opRoot)) {
88
+ if ((await groupCommands(record.pgid)).some((command) => command.includes(record.callDir)))
89
+ alive = true;
90
+ else
91
+ await rm(recordFile(opRoot, record.pgid), { force: true });
92
+ }
93
+ return alive;
94
+ };
95
+ const signalGroup = (pgid, signal) => {
96
+ try {
97
+ process.kill(-pgid, signal);
98
+ }
99
+ catch (error) {
100
+ // ESRCH: the group is gone. EPERM: macOS answers so for a group whose members are all zombies.
101
+ const code = error.code;
102
+ if (code !== 'ESRCH' && code !== 'EPERM')
103
+ throw error;
104
+ }
105
+ };
106
+ const sleep = (milliseconds) => new Promise((resolve) => { setTimeout(resolve, milliseconds); });
107
+ /**
108
+ * Stop every recorded call whose runner is gone (a live runner finishes its own calls), and those of `alsoOf` (a
109
+ * runner stopping its own at its deadline), forgetting each record. A call still running gets SIGTERM, then SIGKILL
110
+ * after `graceMs`.
111
+ */
112
+ export const reapCodexChildren = async (dir, options = {}) => {
113
+ const graceMs = options.graceMs ?? 3_000;
114
+ const outcomes = [];
115
+ for (const record of await listCodexChildren(dir)) {
116
+ if (record.runnerPid !== options.alsoOf && processIsAlive(record.runnerPid))
117
+ continue;
118
+ const commands = await groupCommands(record.pgid);
119
+ let outcome = 'gone';
120
+ if (commands.length > 0) {
121
+ if (commands.some((command) => command.includes(record.callDir))) {
122
+ signalGroup(record.pgid, 'SIGTERM');
123
+ const end = Date.now() + graceMs;
124
+ while ((await groupCommands(record.pgid)).length > 0 && Date.now() < end)
125
+ await sleep(100);
126
+ if ((await groupCommands(record.pgid)).length > 0)
127
+ signalGroup(record.pgid, 'SIGKILL');
128
+ outcome = 'stopped';
129
+ }
130
+ else {
131
+ outcome = 'not_ours';
132
+ }
133
+ }
134
+ await rm(recordFile(dir, record.pgid), { force: true });
135
+ outcomes.push({ pgid: record.pgid, callDir: record.callDir, outcome, ...(record.runnerId ? { runnerId: record.runnerId } : {}) });
136
+ }
137
+ return outcomes;
138
+ };
139
+ //# sourceMappingURL=workspace-runner-children.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-runner-children.js","sourceRoot":"","sources":["../src/workspace-runner-children.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { type DrawFetch } from './workspace-draw-client.js';
2
+ /**
3
+ * The workspace runner's side of its two routes on design.12ui.com (docs/slate-remote.md, "The workspace runner"):
4
+ * the heartbeat, which takes or renews the workspace's lease and lists the running requests, and the claim of one
5
+ * request. Authenticated by the upload token alone, read fresh for every call. No retry here: the runner's loop
6
+ * owns the cadence and waits out what the server names (`retryAfterSeconds`).
7
+ */
8
+ /** `waiting`: its round waits on the person (the inspiration pause); the server refuses its claim until it goes on. */
9
+ export type RunningRequest = {
10
+ opId: string;
11
+ kind: 'round' | 'edit';
12
+ drawer: string | null;
13
+ waiting: boolean;
14
+ };
15
+ export type HeartbeatAnswer = {
16
+ workspace: string;
17
+ rev: number;
18
+ runner: {
19
+ runnerId: string;
20
+ leaseUntilMs: number;
21
+ } | null;
22
+ ops: RunningRequest[];
23
+ };
24
+ /** The heartbeat answer checked before the runner acts on it: an answer this CLI cannot read is never guessed at. */
25
+ export declare const validateHeartbeat: (value: unknown) => HeartbeatAnswer;
26
+ export declare const createRunnerClient: (args: {
27
+ origin: string;
28
+ cliVersion: string;
29
+ /** The current upload token: the runner re-reads its token file for every call. */
30
+ token: () => Promise<string>;
31
+ fetch?: DrawFetch;
32
+ }) => {
33
+ heartbeat: (body: {
34
+ runnerId: string;
35
+ drawing: string[];
36
+ stopping?: boolean;
37
+ }) => Promise<HeartbeatAnswer>;
38
+ claim: (opId: string, runnerId: string) => Promise<{
39
+ replayed: boolean;
40
+ }>;
41
+ };
42
+ export type RunnerClient = ReturnType<typeof createRunnerClient>;
43
+ //# sourceMappingURL=workspace-runner-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-runner-client.d.ts","sourceRoot":"","sources":["../src/workspace-runner-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,SAAS,EACf,MAAM,4BAA4B,CAAC;AAEpC;;;;;GAKG;AAEH,uHAAuH;AACvH,MAAM,MAAM,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/G,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,GAAG,EAAE,cAAc,EAAE,CAAC;CACvB,CAAC;AAMF,qHAAqH;AACrH,eAAO,MAAM,iBAAiB,GAAI,OAAO,OAAO,KAAG,eAuBlD,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,MAAM;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,KAAK,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;sBAyB2B;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,OAAO,CAAC,eAAe,CAAC;kBAG1F,MAAM,YAAY,MAAM,KAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAMhF,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { CLI_HEADER, DrawHttpError, DrawTransportError, errorCodeOf, NO_REDIRECT, PUSH_HEADER, readBody, redirectOf, retryAfterOf, } from './workspace-draw-client.js';
2
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
3
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
4
+ /** The heartbeat answer checked before the runner acts on it: an answer this CLI cannot read is never guessed at. */
5
+ export const validateHeartbeat = (value) => {
6
+ const fail = (what) => { throw new DrawTransportError('malformed', `The heartbeat answer is not one this command can read: ${what}.`); };
7
+ if (!isRecord(value) || value.ok !== true)
8
+ return fail('not ok');
9
+ if (typeof value.workspace !== 'string' || typeof value.rev !== 'number')
10
+ return fail('no workspace');
11
+ if (!Array.isArray(value.ops))
12
+ return fail('no ops');
13
+ const ops = [];
14
+ for (const op of value.ops) {
15
+ if (!isRecord(op) || typeof op.opId !== 'string' || !UUID.test(op.opId))
16
+ return fail('an op has no id');
17
+ if (op.kind !== 'round' && op.kind !== 'edit')
18
+ return fail(`op ${op.opId} has kind ${JSON.stringify(op.kind)}`);
19
+ if (op.drawer !== null && typeof op.drawer !== 'string')
20
+ return fail(`op ${op.opId} has a drawer that is not an id`);
21
+ // `waiting: true` while its round waits on the person, absent otherwise (and from a server older than the field,
22
+ // whose claim answers for it).
23
+ if (op.waiting !== undefined && op.waiting !== true)
24
+ return fail(`op ${op.opId} has a waiting flag that is not true`);
25
+ ops.push({ opId: op.opId, kind: op.kind, drawer: op.drawer, waiting: op.waiting === true });
26
+ }
27
+ const runner = value.runner;
28
+ if (runner !== null && (!isRecord(runner) || typeof runner.runnerId !== 'string' || typeof runner.leaseUntilMs !== 'number'))
29
+ return fail('a runner that is not a lease');
30
+ return {
31
+ workspace: value.workspace,
32
+ rev: value.rev,
33
+ runner: runner === null ? null : { runnerId: runner.runnerId, leaseUntilMs: runner.leaseUntilMs },
34
+ ops,
35
+ };
36
+ };
37
+ export const createRunnerClient = (args) => {
38
+ const fetcher = args.fetch ?? ((url, init) => fetch(url, init));
39
+ const post = async (pathname, body) => {
40
+ const url = `${args.origin}${pathname}`;
41
+ let response;
42
+ try {
43
+ response = await fetcher(url, {
44
+ method: 'POST',
45
+ headers: { [PUSH_HEADER]: await args.token(), [CLI_HEADER]: args.cliVersion, 'content-type': 'application/json' },
46
+ body: JSON.stringify(body),
47
+ // The upload token travels in a header, and fetch keeps custom headers across a redirect: never follow one.
48
+ redirect: NO_REDIRECT,
49
+ });
50
+ }
51
+ catch (cause) {
52
+ throw new DrawTransportError('unreachable', `${new URL(url).host} could not be reached`, { cause });
53
+ }
54
+ const redirected = await redirectOf(url, response);
55
+ if (redirected)
56
+ throw redirected;
57
+ const parsed = await readBody(response);
58
+ if (!response.ok)
59
+ throw new DrawHttpError(response.status, errorCodeOf(parsed) ?? `http_${response.status}`, retryAfterOf(response, parsed), parsed);
60
+ return parsed;
61
+ };
62
+ return {
63
+ heartbeat: async (body) => (validateHeartbeat(await post('/api/v1/slate/runner', { ...body, cliVersion: args.cliVersion }))),
64
+ claim: async (opId, runnerId) => {
65
+ const answer = await post(`/api/v1/slate/ops/${encodeURIComponent(opId)}/claim`, { runnerId });
66
+ if (!isRecord(answer) || answer.ok !== true || answer.op !== opId)
67
+ throw new DrawTransportError('malformed', `The claim of ${opId} answered something else`);
68
+ return { replayed: answer.replayed === true };
69
+ },
70
+ };
71
+ };
72
+ //# sourceMappingURL=workspace-runner-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-runner-client.js","sourceRoot":"","sources":["../src/workspace-runner-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { type DrawFetch } from './workspace-draw-client.js';
2
+ import { type DrawArguments, type DrawDependencies, type DrawResult } from './workspace-draw-run.js';
3
+ import { RUNNER_POLICY } from './workspace-runner-policy.js';
4
+ /**
5
+ * The workspace runner (docs/slate-remote.md, "The workspace runner"): the one detached process per workspace that
6
+ * `12ui workspace draw` leaves on the user's Mac, so the person's later clicks (Generate more, Edit) are drawn
7
+ * without a turn in the agent's thread.
8
+ *
9
+ * It holds the per-workspace lock (single instance on this Mac) and the server's lease (single instance anywhere),
10
+ * heartbeats with the workspace's upload token, and for every running request nobody holds it claims the request
11
+ * and draws it with the draw command's own run, in this process: the same plan, call ids, op lock and run record as
12
+ * the agent's command, so a request is never drawn twice and a rerun repeats no image call. It leaves alone a request
13
+ * whose op lock a live run holds (the agent's own command). It stops when the workspace has been idle for
14
+ * `RUNNER_POLICY.idleMs`, when its token stops working or its token file is older than the token's 12-hour life, when
15
+ * Codex cannot draw here, or on SIGTERM; it then lets the lease go, so the screen tells the agent again.
16
+ *
17
+ * On SIGTERM or SIGINT it claims nothing new and keeps its lease while the draws in hand finish: their Codex calls do
18
+ * not stop with the signal (`interruptOnSignal: false`), so their options land. What is still drawing at
19
+ * `RUNNER_POLICY.stopDeadlineMs` is given back to the agent with the goodbye, its calls stopped, and never pushed as
20
+ * failed. A call Codex itself was stopped in (macOS signals every process at logout and kills them seconds later) is
21
+ * not pushed either: the request goes back to the agent, whose command settles it.
22
+ *
23
+ * Every Codex call is recorded by process group while it runs, so a runner killed outright leaves its calls findable:
24
+ * the next runner of the workspace stops them when it starts. On every exit that still holds the lock it deletes the
25
+ * token file before letting the lock go.
26
+ */
27
+ export type RunnerStop = 'already_running' | 'idle' | 'token_missing' | 'token_invalid' | 'token_expired' | 'cli_outdated' | 'workspace_mismatch' | 'no_engine' | 'lock_lost' | 'signal' | 'fault';
28
+ export type RunnerDependencies = {
29
+ env?: NodeJS.ProcessEnv;
30
+ dataRoot?: string;
31
+ cliVersion?: string;
32
+ fetch?: DrawFetch;
33
+ /** Draws one request; the default is the draw command's own run. */
34
+ draw?: (args: DrawArguments, deps: DrawDependencies) => Promise<DrawResult>;
35
+ /** Extra dependencies for each draw (tests hand in the executor and the readiness probe). */
36
+ drawDeps?: Partial<DrawDependencies>;
37
+ now?: () => number;
38
+ sleep?: (milliseconds: number, signal: AbortSignal) => Promise<void>;
39
+ policy?: Partial<typeof RUNNER_POLICY>;
40
+ /** Aborting it stops the runner as a signal would. */
41
+ stop?: AbortSignal;
42
+ runnerId?: string;
43
+ };
44
+ /** `handedBack`: requests still drawing at the stop deadline, given back to the agent (the process must then exit). */
45
+ export type RunnerOutcome = {
46
+ stop: RunnerStop;
47
+ runnerId: string;
48
+ drawn: string[];
49
+ handedBack: string[];
50
+ };
51
+ export declare const runWorkspaceRunner: (args: {
52
+ origin: string;
53
+ workspace: string;
54
+ deps?: RunnerDependencies;
55
+ }) => Promise<RunnerOutcome>;
56
+ //# sourceMappingURL=workspace-runner-main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-runner-main.d.ts","sourceRoot":"","sources":["../src/workspace-runner-main.ts"],"names":[],"mappings":"AAMA,OAAO,EAAqC,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC/F,OAAO,EAAoB,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAIvH,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAY7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,MAAM,MAAM,UAAU,GAClB,iBAAiB,GACjB,MAAM,GACN,eAAe,GACf,eAAe,GACf,eAAe,GACf,cAAc,GACd,oBAAoB,GACpB,WAAW,GACX,WAAW,GACX,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,oEAAoE;IACpE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5E,6FAA6F;IAC7F,QAAQ,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC;IACvC,sDAAsD;IACtD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,uHAAuH;AACvH,MAAM,MAAM,aAAa,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAuC1G,eAAO,MAAM,kBAAkB,GAAU,MAAM;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,KAAG,OAAO,CAAC,aAAa,CA8QxB,CAAC"}