@12ui/design 0.2.72 → 0.2.74

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 (581) hide show
  1. package/README.md +242 -54
  2. package/SKILL.md +28 -33
  3. package/dist/cli-arguments.d.ts.map +1 -1
  4. package/dist/cli-arguments.js +3 -0
  5. package/dist/cli-arguments.js.map +1 -1
  6. package/dist/cli-branch-command.d.ts.map +1 -1
  7. package/dist/cli-branch-command.js +4 -0
  8. package/dist/cli-branch-command.js.map +1 -1
  9. package/dist/cli-capabilities.d.ts +26 -1
  10. package/dist/cli-capabilities.d.ts.map +1 -1
  11. package/dist/cli-capabilities.js +26 -1
  12. package/dist/cli-capabilities.js.map +1 -1
  13. package/dist/cli-corpus-command.d.ts +5 -4
  14. package/dist/cli-corpus-command.d.ts.map +1 -1
  15. package/dist/cli-corpus-command.js +17 -26
  16. package/dist/cli-corpus-command.js.map +1 -1
  17. package/dist/cli-corpus-run.js +1 -1
  18. package/dist/cli-corpus-run.js.map +1 -1
  19. package/dist/cli-draft-command.js +1 -1
  20. package/dist/cli-draft-command.js.map +1 -1
  21. package/dist/cli-help/design.d.ts +26 -6
  22. package/dist/cli-help/design.d.ts.map +1 -1
  23. package/dist/cli-help/design.js +39 -7
  24. package/dist/cli-help/design.js.map +1 -1
  25. package/dist/cli-help/index.d.ts +113 -7
  26. package/dist/cli-help/index.d.ts.map +1 -1
  27. package/dist/cli-help/index.js +2 -0
  28. package/dist/cli-help/index.js.map +1 -1
  29. package/dist/cli-help/meta.d.ts +1 -1
  30. package/dist/cli-help/meta.d.ts.map +1 -1
  31. package/dist/cli-help/meta.js +2 -1
  32. package/dist/cli-help/meta.js.map +1 -1
  33. package/dist/cli-help/workflow.d.ts +90 -0
  34. package/dist/cli-help/workflow.d.ts.map +1 -0
  35. package/dist/cli-help/workflow.js +89 -0
  36. package/dist/cli-help/workflow.js.map +1 -0
  37. package/dist/cli-open-browser.d.ts +7 -0
  38. package/dist/cli-open-browser.d.ts.map +1 -0
  39. package/dist/cli-open-browser.js +25 -0
  40. package/dist/cli-open-browser.js.map +1 -0
  41. package/dist/cli-prototype-command.d.ts +3 -1
  42. package/dist/cli-prototype-command.d.ts.map +1 -1
  43. package/dist/cli-prototype-command.js +33 -7
  44. package/dist/cli-prototype-command.js.map +1 -1
  45. package/dist/cli-review-command.d.ts.map +1 -1
  46. package/dist/cli-review-command.js +1 -16
  47. package/dist/cli-review-command.js.map +1 -1
  48. package/dist/cli-run.d.ts.map +1 -1
  49. package/dist/cli-run.js +35 -3
  50. package/dist/cli-run.js.map +1 -1
  51. package/dist/cli-usage.d.ts.map +1 -1
  52. package/dist/cli-usage.js +39 -5
  53. package/dist/cli-usage.js.map +1 -1
  54. package/dist/cli-workflow-command.d.ts +8 -0
  55. package/dist/cli-workflow-command.d.ts.map +1 -0
  56. package/dist/cli-workflow-command.js +97 -0
  57. package/dist/cli-workflow-command.js.map +1 -0
  58. package/dist/cli-workspace-command.d.ts +25 -0
  59. package/dist/cli-workspace-command.d.ts.map +1 -0
  60. package/dist/cli-workspace-command.js +95 -0
  61. package/dist/cli-workspace-command.js.map +1 -0
  62. package/dist/config.d.ts +6 -0
  63. package/dist/config.d.ts.map +1 -1
  64. package/dist/config.js +12 -4
  65. package/dist/config.js.map +1 -1
  66. package/dist/corpus-access.d.ts +11 -0
  67. package/dist/corpus-access.d.ts.map +1 -0
  68. package/dist/corpus-access.js +18 -0
  69. package/dist/corpus-access.js.map +1 -0
  70. package/dist/corpus-client.d.ts +11 -11
  71. package/dist/corpus-client.d.ts.map +1 -1
  72. package/dist/corpus-client.js +17 -6
  73. package/dist/corpus-client.js.map +1 -1
  74. package/dist/corpus-inspiration-failure.d.ts +1 -1
  75. package/dist/corpus-inspiration-failure.js +2 -2
  76. package/dist/corpus-inspiration-failure.js.map +1 -1
  77. package/dist/corpus-reference-download-retry.d.ts.map +1 -1
  78. package/dist/corpus-reference-download-retry.js +11 -1
  79. package/dist/corpus-reference-download-retry.js.map +1 -1
  80. package/dist/corpus-request-error.d.ts +2 -0
  81. package/dist/corpus-request-error.d.ts.map +1 -1
  82. package/dist/corpus-request-error.js +2 -0
  83. package/dist/corpus-request-error.js.map +1 -1
  84. package/dist/corpus-retry-guidance.d.ts +5 -0
  85. package/dist/corpus-retry-guidance.d.ts.map +1 -0
  86. package/dist/corpus-retry-guidance.js +18 -0
  87. package/dist/corpus-retry-guidance.js.map +1 -0
  88. package/dist/improve-pricing-plan.d.ts.map +1 -1
  89. package/dist/improve-pricing-plan.js +2 -4
  90. package/dist/improve-pricing-plan.js.map +1 -1
  91. package/dist/index.d.ts +10 -1
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +10 -1
  94. package/dist/index.js.map +1 -1
  95. package/dist/legacy-skill-catalog.d.ts.map +1 -1
  96. package/dist/legacy-skill-catalog.js +41 -0
  97. package/dist/legacy-skill-catalog.js.map +1 -1
  98. package/dist/mcp-slate-command.d.ts +31 -0
  99. package/dist/mcp-slate-command.d.ts.map +1 -0
  100. package/dist/mcp-slate-command.js +123 -0
  101. package/dist/mcp-slate-command.js.map +1 -0
  102. package/dist/mcp-slate-image.d.ts +22 -0
  103. package/dist/mcp-slate-image.d.ts.map +1 -0
  104. package/dist/mcp-slate-image.js +28 -0
  105. package/dist/mcp-slate-image.js.map +1 -0
  106. package/dist/mcp-slate-latest.d.ts +13 -0
  107. package/dist/mcp-slate-latest.d.ts.map +1 -0
  108. package/dist/mcp-slate-latest.js +34 -0
  109. package/dist/mcp-slate-latest.js.map +1 -0
  110. package/dist/mcp-slate-names.d.ts +25 -0
  111. package/dist/mcp-slate-names.d.ts.map +1 -0
  112. package/dist/mcp-slate-names.js +49 -0
  113. package/dist/mcp-slate-names.js.map +1 -0
  114. package/dist/mcp-slate-resource.d.ts +5 -0
  115. package/dist/mcp-slate-resource.d.ts.map +1 -0
  116. package/dist/mcp-slate-resource.js +37 -0
  117. package/dist/mcp-slate-resource.js.map +1 -0
  118. package/dist/mcp-slate-run.d.ts +41 -0
  119. package/dist/mcp-slate-run.d.ts.map +1 -0
  120. package/dist/mcp-slate-run.js +88 -0
  121. package/dist/mcp-slate-run.js.map +1 -0
  122. package/dist/mcp-slate-tool-defs.d.ts +61 -0
  123. package/dist/mcp-slate-tool-defs.d.ts.map +1 -0
  124. package/dist/mcp-slate-tool-defs.js +247 -0
  125. package/dist/mcp-slate-tool-defs.js.map +1 -0
  126. package/dist/mcp-slate-tools.d.ts +8 -0
  127. package/dist/mcp-slate-tools.d.ts.map +1 -0
  128. package/dist/mcp-slate-tools.js +45 -0
  129. package/dist/mcp-slate-tools.js.map +1 -0
  130. package/dist/mcp-slate-ui-copy.d.ts +145 -0
  131. package/dist/mcp-slate-ui-copy.d.ts.map +1 -0
  132. package/dist/mcp-slate-ui-copy.js +164 -0
  133. package/dist/mcp-slate-ui-copy.js.map +1 -0
  134. package/dist/mcp-slate-ui-script-bridge.d.ts +18 -0
  135. package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -0
  136. package/dist/mcp-slate-ui-script-bridge.js +137 -0
  137. package/dist/mcp-slate-ui-script-bridge.js.map +1 -0
  138. package/dist/mcp-slate-ui-script-browser.d.ts +12 -0
  139. package/dist/mcp-slate-ui-script-browser.d.ts.map +1 -0
  140. package/dist/mcp-slate-ui-script-browser.js +19 -0
  141. package/dist/mcp-slate-ui-script-browser.js.map +1 -0
  142. package/dist/mcp-slate-ui-script-dialog.d.ts +21 -0
  143. package/dist/mcp-slate-ui-script-dialog.d.ts.map +1 -0
  144. package/dist/mcp-slate-ui-script-dialog.js +321 -0
  145. package/dist/mcp-slate-ui-script-dialog.js.map +1 -0
  146. package/dist/mcp-slate-ui-script-inline.d.ts +10 -0
  147. package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -0
  148. package/dist/mcp-slate-ui-script-inline.js +224 -0
  149. package/dist/mcp-slate-ui-script-inline.js.map +1 -0
  150. package/dist/mcp-slate-ui-script-inspiration.d.ts +13 -0
  151. package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -0
  152. package/dist/mcp-slate-ui-script-inspiration.js +236 -0
  153. package/dist/mcp-slate-ui-script-inspiration.js.map +1 -0
  154. package/dist/mcp-slate-ui-script-more.d.ts +32 -0
  155. package/dist/mcp-slate-ui-script-more.d.ts.map +1 -0
  156. package/dist/mcp-slate-ui-script-more.js +289 -0
  157. package/dist/mcp-slate-ui-script-more.js.map +1 -0
  158. package/dist/mcp-slate-ui-script-progress.d.ts +7 -0
  159. package/dist/mcp-slate-ui-script-progress.d.ts.map +1 -0
  160. package/dist/mcp-slate-ui-script-progress.js +9 -0
  161. package/dist/mcp-slate-ui-script-progress.js.map +1 -0
  162. package/dist/mcp-slate-ui-script-remote.d.ts +28 -0
  163. package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -0
  164. package/dist/mcp-slate-ui-script-remote.js +147 -0
  165. package/dist/mcp-slate-ui-script-remote.js.map +1 -0
  166. package/dist/mcp-slate-ui-script-scribble.d.ts +19 -0
  167. package/dist/mcp-slate-ui-script-scribble.d.ts.map +1 -0
  168. package/dist/mcp-slate-ui-script-scribble.js +114 -0
  169. package/dist/mcp-slate-ui-script-scribble.js.map +1 -0
  170. package/dist/mcp-slate-ui-script-select.d.ts +16 -0
  171. package/dist/mcp-slate-ui-script-select.d.ts.map +1 -0
  172. package/dist/mcp-slate-ui-script-select.js +73 -0
  173. package/dist/mcp-slate-ui-script-select.js.map +1 -0
  174. package/dist/mcp-slate-ui-script-stage.d.ts +12 -0
  175. package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -0
  176. package/dist/mcp-slate-ui-script-stage.js +180 -0
  177. package/dist/mcp-slate-ui-script-stage.js.map +1 -0
  178. package/dist/mcp-slate-ui-script-state.d.ts +13 -0
  179. package/dist/mcp-slate-ui-script-state.d.ts.map +1 -0
  180. package/dist/mcp-slate-ui-script-state.js +306 -0
  181. package/dist/mcp-slate-ui-script-state.js.map +1 -0
  182. package/dist/mcp-slate-ui-script.d.ts +27 -0
  183. package/dist/mcp-slate-ui-script.d.ts.map +1 -0
  184. package/dist/mcp-slate-ui-script.js +60 -0
  185. package/dist/mcp-slate-ui-script.js.map +1 -0
  186. package/dist/mcp-slate-ui-styles-dialog.d.ts +20 -0
  187. package/dist/mcp-slate-ui-styles-dialog.d.ts.map +1 -0
  188. package/dist/mcp-slate-ui-styles-dialog.js +95 -0
  189. package/dist/mcp-slate-ui-styles-dialog.js.map +1 -0
  190. package/dist/mcp-slate-ui-styles-stage.d.ts +19 -0
  191. package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -0
  192. package/dist/mcp-slate-ui-styles-stage.js +67 -0
  193. package/dist/mcp-slate-ui-styles-stage.js.map +1 -0
  194. package/dist/mcp-slate-ui-styles.d.ts +18 -0
  195. package/dist/mcp-slate-ui-styles.d.ts.map +1 -0
  196. package/dist/mcp-slate-ui-styles.js +132 -0
  197. package/dist/mcp-slate-ui-styles.js.map +1 -0
  198. package/dist/mcp-slate-ui.d.ts +16 -0
  199. package/dist/mcp-slate-ui.d.ts.map +1 -0
  200. package/dist/mcp-slate-ui.js +59 -0
  201. package/dist/mcp-slate-ui.js.map +1 -0
  202. package/dist/mcp-slate-workspace-tools.d.ts +15 -0
  203. package/dist/mcp-slate-workspace-tools.d.ts.map +1 -0
  204. package/dist/mcp-slate-workspace-tools.js +155 -0
  205. package/dist/mcp-slate-workspace-tools.js.map +1 -0
  206. package/dist/mcp-tool-definitions.d.ts.map +1 -1
  207. package/dist/mcp-tool-definitions.js +9 -7
  208. package/dist/mcp-tool-definitions.js.map +1 -1
  209. package/dist/mcp-tool-handler.d.ts +8 -2
  210. package/dist/mcp-tool-handler.d.ts.map +1 -1
  211. package/dist/mcp-tool-handler.js +34 -13
  212. package/dist/mcp-tool-handler.js.map +1 -1
  213. package/dist/mcp-workflow-tools.d.ts +6 -0
  214. package/dist/mcp-workflow-tools.d.ts.map +1 -0
  215. package/dist/mcp-workflow-tools.js +108 -0
  216. package/dist/mcp-workflow-tools.js.map +1 -0
  217. package/dist/prototype-label-client.d.ts +5 -0
  218. package/dist/prototype-label-client.d.ts.map +1 -1
  219. package/dist/prototype-label-client.js.map +1 -1
  220. package/dist/prototype-poststep.d.ts +2 -2
  221. package/dist/prototype-poststep.d.ts.map +1 -1
  222. package/dist/prototype-poststep.js +3 -0
  223. package/dist/prototype-poststep.js.map +1 -1
  224. package/dist/prototype-run-record.d.ts +6 -2
  225. package/dist/prototype-run-record.d.ts.map +1 -1
  226. package/dist/prototype-run-record.js +6 -0
  227. package/dist/prototype-run-record.js.map +1 -1
  228. package/dist/prototype-runner.d.ts +2 -2
  229. package/dist/prototype-runner.d.ts.map +1 -1
  230. package/dist/prototype-runner.js +5 -2
  231. package/dist/prototype-runner.js.map +1 -1
  232. package/dist/prototype-workflow-contract.d.ts +13 -0
  233. package/dist/prototype-workflow-contract.d.ts.map +1 -0
  234. package/dist/prototype-workflow-contract.js +82 -0
  235. package/dist/prototype-workflow-contract.js.map +1 -0
  236. package/dist/prototype-workflow-labels.d.ts +29 -0
  237. package/dist/prototype-workflow-labels.d.ts.map +1 -0
  238. package/dist/prototype-workflow-labels.js +93 -0
  239. package/dist/prototype-workflow-labels.js.map +1 -0
  240. package/dist/run-journal-commands.d.ts.map +1 -1
  241. package/dist/run-journal-commands.js +18 -5
  242. package/dist/run-journal-commands.js.map +1 -1
  243. package/dist/server.d.ts +22 -2
  244. package/dist/server.d.ts.map +1 -1
  245. package/dist/server.js +44 -8
  246. package/dist/server.js.map +1 -1
  247. package/dist/slate-actions.d.ts +43 -0
  248. package/dist/slate-actions.d.ts.map +1 -0
  249. package/dist/slate-actions.js +108 -0
  250. package/dist/slate-actions.js.map +1 -0
  251. package/dist/slate-annotate.d.ts +36 -0
  252. package/dist/slate-annotate.d.ts.map +1 -0
  253. package/dist/slate-annotate.js +71 -0
  254. package/dist/slate-annotate.js.map +1 -0
  255. package/dist/slate-approvals.d.ts +61 -0
  256. package/dist/slate-approvals.d.ts.map +1 -0
  257. package/dist/slate-approvals.js +153 -0
  258. package/dist/slate-approvals.js.map +1 -0
  259. package/dist/slate-browser-decision.d.ts +30 -0
  260. package/dist/slate-browser-decision.d.ts.map +1 -0
  261. package/dist/slate-browser-decision.js +24 -0
  262. package/dist/slate-browser-decision.js.map +1 -0
  263. package/dist/slate-browser-host-script.d.ts +14 -0
  264. package/dist/slate-browser-host-script.d.ts.map +1 -0
  265. package/dist/slate-browser-host-script.js +125 -0
  266. package/dist/slate-browser-host-script.js.map +1 -0
  267. package/dist/slate-browser-host.d.ts +9 -0
  268. package/dist/slate-browser-host.d.ts.map +1 -0
  269. package/dist/slate-browser-host.js +37 -0
  270. package/dist/slate-browser-host.js.map +1 -0
  271. package/dist/slate-browser-server.d.ts +37 -0
  272. package/dist/slate-browser-server.d.ts.map +1 -0
  273. package/dist/slate-browser-server.js +186 -0
  274. package/dist/slate-browser-server.js.map +1 -0
  275. package/dist/slate-commit.d.ts +28 -0
  276. package/dist/slate-commit.d.ts.map +1 -0
  277. package/dist/slate-commit.js +218 -0
  278. package/dist/slate-commit.js.map +1 -0
  279. package/dist/slate-corpus.d.ts +14 -0
  280. package/dist/slate-corpus.d.ts.map +1 -0
  281. package/dist/slate-corpus.js +32 -0
  282. package/dist/slate-corpus.js.map +1 -0
  283. package/dist/slate-edit-prompt.d.ts +18 -0
  284. package/dist/slate-edit-prompt.d.ts.map +1 -0
  285. package/dist/slate-edit-prompt.js +41 -0
  286. package/dist/slate-edit-prompt.js.map +1 -0
  287. package/dist/slate-edit-runner.d.ts +4 -0
  288. package/dist/slate-edit-runner.d.ts.map +1 -0
  289. package/dist/slate-edit-runner.js +90 -0
  290. package/dist/slate-edit-runner.js.map +1 -0
  291. package/dist/slate-editability.d.ts +20 -0
  292. package/dist/slate-editability.d.ts.map +1 -0
  293. package/dist/slate-editability.js +19 -0
  294. package/dist/slate-editability.js.map +1 -0
  295. package/dist/slate-errors.d.ts +15 -0
  296. package/dist/slate-errors.d.ts.map +1 -0
  297. package/dist/slate-errors.js +21 -0
  298. package/dist/slate-errors.js.map +1 -0
  299. package/dist/slate-handoff-options.d.ts +40 -0
  300. package/dist/slate-handoff-options.d.ts.map +1 -0
  301. package/dist/slate-handoff-options.js +117 -0
  302. package/dist/slate-handoff-options.js.map +1 -0
  303. package/dist/slate-handoff.d.ts +11 -0
  304. package/dist/slate-handoff.d.ts.map +1 -0
  305. package/dist/slate-handoff.js +56 -0
  306. package/dist/slate-handoff.js.map +1 -0
  307. package/dist/slate-ids.d.ts +33 -0
  308. package/dist/slate-ids.d.ts.map +1 -0
  309. package/dist/slate-ids.js +47 -0
  310. package/dist/slate-ids.js.map +1 -0
  311. package/dist/slate-image-executor.d.ts +39 -0
  312. package/dist/slate-image-executor.d.ts.map +1 -0
  313. package/dist/slate-image-executor.js +52 -0
  314. package/dist/slate-image-executor.js.map +1 -0
  315. package/dist/slate-inspiration.d.ts +22 -0
  316. package/dist/slate-inspiration.d.ts.map +1 -0
  317. package/dist/slate-inspiration.js +112 -0
  318. package/dist/slate-inspiration.js.map +1 -0
  319. package/dist/slate-labels.d.ts +11 -0
  320. package/dist/slate-labels.d.ts.map +1 -0
  321. package/dist/slate-labels.js +32 -0
  322. package/dist/slate-labels.js.map +1 -0
  323. package/dist/slate-ledger.d.ts +29 -0
  324. package/dist/slate-ledger.d.ts.map +1 -0
  325. package/dist/slate-ledger.js +65 -0
  326. package/dist/slate-ledger.js.map +1 -0
  327. package/dist/slate-liveness.d.ts +26 -0
  328. package/dist/slate-liveness.d.ts.map +1 -0
  329. package/dist/slate-liveness.js +49 -0
  330. package/dist/slate-liveness.js.map +1 -0
  331. package/dist/slate-local-image.d.ts +19 -0
  332. package/dist/slate-local-image.d.ts.map +1 -0
  333. package/dist/slate-local-image.js +36 -0
  334. package/dist/slate-local-image.js.map +1 -0
  335. package/dist/slate-lock.d.ts +64 -0
  336. package/dist/slate-lock.d.ts.map +1 -0
  337. package/dist/slate-lock.js +178 -0
  338. package/dist/slate-lock.js.map +1 -0
  339. package/dist/slate-paths.d.ts +45 -0
  340. package/dist/slate-paths.d.ts.map +1 -0
  341. package/dist/slate-paths.js +132 -0
  342. package/dist/slate-paths.js.map +1 -0
  343. package/dist/slate-pick.d.ts +29 -0
  344. package/dist/slate-pick.d.ts.map +1 -0
  345. package/dist/slate-pick.js +55 -0
  346. package/dist/slate-pick.js.map +1 -0
  347. package/dist/slate-reference-ids.d.ts +6 -0
  348. package/dist/slate-reference-ids.d.ts.map +1 -0
  349. package/dist/slate-reference-ids.js +17 -0
  350. package/dist/slate-reference-ids.js.map +1 -0
  351. package/dist/slate-reference-store.d.ts +23 -0
  352. package/dist/slate-reference-store.d.ts.map +1 -0
  353. package/dist/slate-reference-store.js +46 -0
  354. package/dist/slate-reference-store.js.map +1 -0
  355. package/dist/slate-resume.d.ts +19 -0
  356. package/dist/slate-resume.d.ts.map +1 -0
  357. package/dist/slate-resume.js +94 -0
  358. package/dist/slate-resume.js.map +1 -0
  359. package/dist/slate-round-params.d.ts +20 -0
  360. package/dist/slate-round-params.d.ts.map +1 -0
  361. package/dist/slate-round-params.js +32 -0
  362. package/dist/slate-round-params.js.map +1 -0
  363. package/dist/slate-round-prompt.d.ts +18 -0
  364. package/dist/slate-round-prompt.d.ts.map +1 -0
  365. package/dist/slate-round-prompt.js +20 -0
  366. package/dist/slate-round-prompt.js.map +1 -0
  367. package/dist/slate-round-runner.d.ts +4 -0
  368. package/dist/slate-round-runner.d.ts.map +1 -0
  369. package/dist/slate-round-runner.js +125 -0
  370. package/dist/slate-round-runner.js.map +1 -0
  371. package/dist/slate-round-search.d.ts +7 -0
  372. package/dist/slate-round-search.d.ts.map +1 -0
  373. package/dist/slate-round-search.js +77 -0
  374. package/dist/slate-round-search.js.map +1 -0
  375. package/dist/slate-run-action.d.ts +14 -0
  376. package/dist/slate-run-action.d.ts.map +1 -0
  377. package/dist/slate-run-action.js +81 -0
  378. package/dist/slate-run-action.js.map +1 -0
  379. package/dist/slate-runner-context.d.ts +57 -0
  380. package/dist/slate-runner-context.d.ts.map +1 -0
  381. package/dist/slate-runner-context.js +79 -0
  382. package/dist/slate-runner-context.js.map +1 -0
  383. package/dist/slate-runner-failure.d.ts +8 -0
  384. package/dist/slate-runner-failure.d.ts.map +1 -0
  385. package/dist/slate-runner-failure.js +17 -0
  386. package/dist/slate-runner-failure.js.map +1 -0
  387. package/dist/slate-runner-flag.d.ts +3 -0
  388. package/dist/slate-runner-flag.d.ts.map +1 -0
  389. package/dist/slate-runner-flag.js +3 -0
  390. package/dist/slate-runner-flag.js.map +1 -0
  391. package/dist/slate-runner-main.d.ts +31 -0
  392. package/dist/slate-runner-main.d.ts.map +1 -0
  393. package/dist/slate-runner-main.js +132 -0
  394. package/dist/slate-runner-main.js.map +1 -0
  395. package/dist/slate-runner-spawn.d.ts +23 -0
  396. package/dist/slate-runner-spawn.d.ts.map +1 -0
  397. package/dist/slate-runner-spawn.js +27 -0
  398. package/dist/slate-runner-spawn.js.map +1 -0
  399. package/dist/slate-runtime.d.ts +38 -0
  400. package/dist/slate-runtime.d.ts.map +1 -0
  401. package/dist/slate-runtime.js +48 -0
  402. package/dist/slate-runtime.js.map +1 -0
  403. package/dist/slate-versions.d.ts +26 -0
  404. package/dist/slate-versions.d.ts.map +1 -0
  405. package/dist/slate-versions.js +110 -0
  406. package/dist/slate-versions.js.map +1 -0
  407. package/dist/slate-view-contract.d.ts +232 -0
  408. package/dist/slate-view-contract.d.ts.map +1 -0
  409. package/dist/slate-view-contract.js +17 -0
  410. package/dist/slate-view-contract.js.map +1 -0
  411. package/dist/slate-view-types.d.ts +2 -0
  412. package/dist/slate-view-types.d.ts.map +1 -0
  413. package/dist/slate-view-types.js +2 -0
  414. package/dist/slate-view-types.js.map +1 -0
  415. package/dist/slate-view.d.ts +19 -0
  416. package/dist/slate-view.d.ts.map +1 -0
  417. package/dist/slate-view.js +184 -0
  418. package/dist/slate-view.js.map +1 -0
  419. package/dist/slate-workspace-parse.d.ts +20 -0
  420. package/dist/slate-workspace-parse.d.ts.map +1 -0
  421. package/dist/slate-workspace-parse.js +442 -0
  422. package/dist/slate-workspace-parse.js.map +1 -0
  423. package/dist/slate-workspace-store.d.ts +44 -0
  424. package/dist/slate-workspace-store.d.ts.map +1 -0
  425. package/dist/slate-workspace-store.js +270 -0
  426. package/dist/slate-workspace-store.js.map +1 -0
  427. package/dist/slate-workspace-types.d.ts +176 -0
  428. package/dist/slate-workspace-types.d.ts.map +1 -0
  429. package/dist/slate-workspace-types.js +13 -0
  430. package/dist/slate-workspace-types.js.map +1 -0
  431. package/dist/workflow/adapter-12ui.d.ts +4 -0
  432. package/dist/workflow/adapter-12ui.d.ts.map +1 -0
  433. package/dist/workflow/adapter-12ui.js +147 -0
  434. package/dist/workflow/adapter-12ui.js.map +1 -0
  435. package/dist/workflow/adapter-layerdoc.d.ts +16 -0
  436. package/dist/workflow/adapter-layerdoc.d.ts.map +1 -0
  437. package/dist/workflow/adapter-layerdoc.js +116 -0
  438. package/dist/workflow/adapter-layerdoc.js.map +1 -0
  439. package/dist/workflow/adapter-openai.d.ts +4 -0
  440. package/dist/workflow/adapter-openai.d.ts.map +1 -0
  441. package/dist/workflow/adapter-openai.js +166 -0
  442. package/dist/workflow/adapter-openai.js.map +1 -0
  443. package/dist/workflow/adapter-process.d.ts +7 -0
  444. package/dist/workflow/adapter-process.d.ts.map +1 -0
  445. package/dist/workflow/adapter-process.js +174 -0
  446. package/dist/workflow/adapter-process.js.map +1 -0
  447. package/dist/workflow/adapter-prototype-labels.d.ts +15 -0
  448. package/dist/workflow/adapter-prototype-labels.d.ts.map +1 -0
  449. package/dist/workflow/adapter-prototype-labels.js +71 -0
  450. package/dist/workflow/adapter-prototype-labels.js.map +1 -0
  451. package/dist/workflow/adapter-types.d.ts +40 -0
  452. package/dist/workflow/adapter-types.d.ts.map +1 -0
  453. package/dist/workflow/adapter-types.js +2 -0
  454. package/dist/workflow/adapter-types.js.map +1 -0
  455. package/dist/workflow/adapter-utils.d.ts +11 -0
  456. package/dist/workflow/adapter-utils.d.ts.map +1 -0
  457. package/dist/workflow/adapter-utils.js +72 -0
  458. package/dist/workflow/adapter-utils.js.map +1 -0
  459. package/dist/workflow/adapters.d.ts +6 -0
  460. package/dist/workflow/adapters.d.ts.map +1 -0
  461. package/dist/workflow/adapters.js +25 -0
  462. package/dist/workflow/adapters.js.map +1 -0
  463. package/dist/workflow/artifact.d.ts +11 -0
  464. package/dist/workflow/artifact.d.ts.map +1 -0
  465. package/dist/workflow/artifact.js +94 -0
  466. package/dist/workflow/artifact.js.map +1 -0
  467. package/dist/workflow/bundle-collect.d.ts +8 -0
  468. package/dist/workflow/bundle-collect.d.ts.map +1 -0
  469. package/dist/workflow/bundle-collect.js +56 -0
  470. package/dist/workflow/bundle-collect.js.map +1 -0
  471. package/dist/workflow/bundle-export.d.ts +16 -0
  472. package/dist/workflow/bundle-export.d.ts.map +1 -0
  473. package/dist/workflow/bundle-export.js +174 -0
  474. package/dist/workflow/bundle-export.js.map +1 -0
  475. package/dist/workflow/bundle-paths.d.ts +7 -0
  476. package/dist/workflow/bundle-paths.d.ts.map +1 -0
  477. package/dist/workflow/bundle-paths.js +35 -0
  478. package/dist/workflow/bundle-paths.js.map +1 -0
  479. package/dist/workflow/bundle.d.ts +4 -0
  480. package/dist/workflow/bundle.d.ts.map +1 -0
  481. package/dist/workflow/bundle.js +4 -0
  482. package/dist/workflow/bundle.js.map +1 -0
  483. package/dist/workflow/capture.d.ts +36 -0
  484. package/dist/workflow/capture.d.ts.map +1 -0
  485. package/dist/workflow/capture.js +81 -0
  486. package/dist/workflow/capture.js.map +1 -0
  487. package/dist/workflow/continuation-branch.d.ts +15 -0
  488. package/dist/workflow/continuation-branch.d.ts.map +1 -0
  489. package/dist/workflow/continuation-branch.js +103 -0
  490. package/dist/workflow/continuation-branch.js.map +1 -0
  491. package/dist/workflow/continuation-plans.d.ts +38 -0
  492. package/dist/workflow/continuation-plans.d.ts.map +1 -0
  493. package/dist/workflow/continuation-plans.js +78 -0
  494. package/dist/workflow/continuation-plans.js.map +1 -0
  495. package/dist/workflow/continuation.d.ts +25 -0
  496. package/dist/workflow/continuation.d.ts.map +1 -0
  497. package/dist/workflow/continuation.js +89 -0
  498. package/dist/workflow/continuation.js.map +1 -0
  499. package/dist/workflow/layerdoc-reader.d.ts +27 -0
  500. package/dist/workflow/layerdoc-reader.d.ts.map +1 -0
  501. package/dist/workflow/layerdoc-reader.js +81 -0
  502. package/dist/workflow/layerdoc-reader.js.map +1 -0
  503. package/dist/workflow/project-evidence.d.ts +48 -0
  504. package/dist/workflow/project-evidence.d.ts.map +1 -0
  505. package/dist/workflow/project-evidence.js +200 -0
  506. package/dist/workflow/project-evidence.js.map +1 -0
  507. package/dist/workflow/providers.d.ts +35 -0
  508. package/dist/workflow/providers.d.ts.map +1 -0
  509. package/dist/workflow/providers.js +110 -0
  510. package/dist/workflow/providers.js.map +1 -0
  511. package/dist/workflow/recipes-layerdoc-validation.d.ts +4 -0
  512. package/dist/workflow/recipes-layerdoc-validation.d.ts.map +1 -0
  513. package/dist/workflow/recipes-layerdoc-validation.js +98 -0
  514. package/dist/workflow/recipes-layerdoc-validation.js.map +1 -0
  515. package/dist/workflow/recipes-result-validation.d.ts +6 -0
  516. package/dist/workflow/recipes-result-validation.d.ts.map +1 -0
  517. package/dist/workflow/recipes-result-validation.js +38 -0
  518. package/dist/workflow/recipes-result-validation.js.map +1 -0
  519. package/dist/workflow/recipes-schemas.d.ts +7 -0
  520. package/dist/workflow/recipes-schemas.d.ts.map +1 -0
  521. package/dist/workflow/recipes-schemas.js +67 -0
  522. package/dist/workflow/recipes-schemas.js.map +1 -0
  523. package/dist/workflow/recipes-validation.d.ts +14 -0
  524. package/dist/workflow/recipes-validation.d.ts.map +1 -0
  525. package/dist/workflow/recipes-validation.js +68 -0
  526. package/dist/workflow/recipes-validation.js.map +1 -0
  527. package/dist/workflow/recipes.d.ts +20 -0
  528. package/dist/workflow/recipes.d.ts.map +1 -0
  529. package/dist/workflow/recipes.js +167 -0
  530. package/dist/workflow/recipes.js.map +1 -0
  531. package/dist/workflow/routing.d.ts +4 -0
  532. package/dist/workflow/routing.d.ts.map +1 -0
  533. package/dist/workflow/routing.js +28 -0
  534. package/dist/workflow/routing.js.map +1 -0
  535. package/dist/workflow/schema.d.ts +5 -0
  536. package/dist/workflow/schema.d.ts.map +1 -0
  537. package/dist/workflow/schema.js +29 -0
  538. package/dist/workflow/schema.js.map +1 -0
  539. package/dist/workflow/service.d.ts +59 -0
  540. package/dist/workflow/service.d.ts.map +1 -0
  541. package/dist/workflow/service.js +170 -0
  542. package/dist/workflow/service.js.map +1 -0
  543. package/dist/workflow/store-json.d.ts +5 -0
  544. package/dist/workflow/store-json.d.ts.map +1 -0
  545. package/dist/workflow/store-json.js +35 -0
  546. package/dist/workflow/store-json.js.map +1 -0
  547. package/dist/workflow/store-lock.d.ts +3 -0
  548. package/dist/workflow/store-lock.d.ts.map +1 -0
  549. package/dist/workflow/store-lock.js +85 -0
  550. package/dist/workflow/store-lock.js.map +1 -0
  551. package/dist/workflow/store-paths.d.ts +17 -0
  552. package/dist/workflow/store-paths.d.ts.map +1 -0
  553. package/dist/workflow/store-paths.js +67 -0
  554. package/dist/workflow/store-paths.js.map +1 -0
  555. package/dist/workflow/store-validation.d.ts +7 -0
  556. package/dist/workflow/store-validation.d.ts.map +1 -0
  557. package/dist/workflow/store-validation.js +119 -0
  558. package/dist/workflow/store-validation.js.map +1 -0
  559. package/dist/workflow/store.d.ts +10 -0
  560. package/dist/workflow/store.d.ts.map +1 -0
  561. package/dist/workflow/store.js +193 -0
  562. package/dist/workflow/store.js.map +1 -0
  563. package/dist/workflow/types.d.ts +120 -0
  564. package/dist/workflow/types.d.ts.map +1 -0
  565. package/dist/workflow/types.js +15 -0
  566. package/dist/workflow/types.js.map +1 -0
  567. package/dist/workflow-transport.d.ts +28 -0
  568. package/dist/workflow-transport.d.ts.map +1 -0
  569. package/dist/workflow-transport.js +184 -0
  570. package/dist/workflow-transport.js.map +1 -0
  571. package/open-design.json +2 -2
  572. package/package.json +2 -1
  573. package/prototype-kit/tests/rules-check.mjs +9 -0
  574. package/runtime/codex-conversion/src/images/native-invoke.mjs +1 -1
  575. package/runtime/codex-conversion/src/images/native.mjs +8 -4
  576. package/runtime/layerdoc-validator.mjs +1860 -0
  577. package/skills/12ui-design/SKILL.md +17 -63
  578. package/skills/12ui-design/improve.md +5 -1
  579. package/skills/12ui-design/inspire.md +8 -5
  580. package/skills/12ui-design/outputs.md +23 -2
  581. package/skills/12ui-design/session.md +161 -0
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `ledger.jsonl`: an append-only audit of the workspace's boundaries, one JSON
3
+ * line per event, written BEFORE the step it names. The record in
4
+ * `workspace.json` is the resumable artifact; this file is what an operator
5
+ * reads to see what was started and what finished. It holds no money events:
6
+ * the workspace costs nothing. Lines are at most 4 KiB and are never edited.
7
+ */
8
+ export declare const LEDGER_MAX_LINE_BYTES = 4096;
9
+ export type LedgerEvent = 'approved' | 'resumed' | 'search' | 'call_started' | 'call_finished' | 'settled' | 'failed' | 'superseded' | 'runner_started' | 'pick' | 'handoff' | 'inspiration';
10
+ export type LedgerEntry = {
11
+ at: string;
12
+ event: LedgerEvent;
13
+ opId?: string;
14
+ runId?: string;
15
+ [detail: string]: unknown;
16
+ };
17
+ export type LedgerInput = {
18
+ at?: string;
19
+ event: LedgerEvent;
20
+ opId?: string;
21
+ runId?: string;
22
+ [detail: string]: unknown;
23
+ };
24
+ export declare const appendLedger: (root: string, entry: LedgerInput) => Promise<void>;
25
+ export declare const readLedger: (root: string) => Promise<{
26
+ entries: LedgerEntry[];
27
+ tornFinalLine: boolean;
28
+ }>;
29
+ //# sourceMappingURL=slate-ledger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-ledger.d.ts","sourceRoot":"","sources":["../src/slate-ledger.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,MAAM,MAAM,WAAW,GACnB,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,GAAG,eAAe,GACpE,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,gBAAgB,GAAG,MAAM,GAAG,SAAS,GAAG,aAAa,CAAC;AAEhG,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AACvH,MAAM,MAAM,WAAW,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAExH,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,EAAE,OAAO,WAAW,KAAG,OAAO,CAAC,IAAI,CAiBjF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAAC,aAAa,EAAE,OAAO,CAAA;CAAE,CA6BzG,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { open, readFile } from 'node:fs/promises';
2
+ import { ledgerFile } from './slate-paths.js';
3
+ /**
4
+ * `ledger.jsonl`: an append-only audit of the workspace's boundaries, one JSON
5
+ * line per event, written BEFORE the step it names. The record in
6
+ * `workspace.json` is the resumable artifact; this file is what an operator
7
+ * reads to see what was started and what finished. It holds no money events:
8
+ * the workspace costs nothing. Lines are at most 4 KiB and are never edited.
9
+ */
10
+ export const LEDGER_MAX_LINE_BYTES = 4096;
11
+ export const appendLedger = async (root, entry) => {
12
+ const full = { ...entry, at: entry.at ?? new Date().toISOString() };
13
+ let line = JSON.stringify(full);
14
+ if (Buffer.byteLength(line) > LEDGER_MAX_LINE_BYTES - 1) {
15
+ const message = typeof full.message === 'string' ? full.message.slice(0, 300) : undefined;
16
+ line = JSON.stringify({ ...full, ...(message === undefined ? {} : { message }), truncated: true });
17
+ }
18
+ if (Buffer.byteLength(line) > LEDGER_MAX_LINE_BYTES - 1) {
19
+ line = JSON.stringify({ at: full.at, event: full.event, opId: full.opId, truncated: true });
20
+ }
21
+ // O_APPEND and one write per line keep concurrent writers from interleaving.
22
+ const handle = await open(ledgerFile(root), 'a', 0o600);
23
+ try {
24
+ await handle.write(`${line}\n`);
25
+ }
26
+ finally {
27
+ await handle.close();
28
+ }
29
+ };
30
+ export const readLedger = async (root) => {
31
+ const file = ledgerFile(root);
32
+ let raw;
33
+ try {
34
+ raw = await readFile(file, 'utf8');
35
+ }
36
+ catch (error) {
37
+ if (error.code === 'ENOENT')
38
+ return { entries: [], tornFinalLine: false };
39
+ throw error;
40
+ }
41
+ const endsCleanly = raw.endsWith('\n');
42
+ const lines = raw.split('\n');
43
+ if (lines.at(-1) === '')
44
+ lines.pop();
45
+ const entries = [];
46
+ let tornFinalLine = false;
47
+ lines.forEach((line, index) => {
48
+ try {
49
+ const parsed = JSON.parse(line);
50
+ if (typeof parsed?.event !== 'string')
51
+ throw new Error('no event');
52
+ entries.push(parsed);
53
+ }
54
+ catch {
55
+ if (index === lines.length - 1 && !endsCleanly) {
56
+ // A crash mid-append leaves an unterminated final line: ignored and reported.
57
+ tornFinalLine = true;
58
+ return;
59
+ }
60
+ throw new Error(`${file} line ${index + 1} is not a ledger entry`);
61
+ }
62
+ });
63
+ return { entries, tornFinalLine };
64
+ };
65
+ //# sourceMappingURL=slate-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-ledger.js","sourceRoot":"","sources":["../src/slate-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { RUNNER_ALIVE_WINDOW_MS, RUNNER_HEARTBEAT_INTERVAL_MS } from './slate-lock.js';
2
+ import type { SlateOp, SlateWorkspace } from './slate-workspace-types.js';
3
+ /**
4
+ * What is actually running, derived from the per-op lock file and the clock.
5
+ * `starting` and `interrupted` are never written to `workspace.json`: a record
6
+ * written by a process that has since died must not claim it is still working.
7
+ */
8
+ export declare const RUNNER_START_GRACE_MS = 30000;
9
+ export { RUNNER_ALIVE_WINDOW_MS, RUNNER_HEARTBEAT_INTERVAL_MS };
10
+ export type RunnerState = {
11
+ alive: boolean;
12
+ pid: number | null;
13
+ heartbeatAgeMs: number | null;
14
+ };
15
+ export type DerivedOpState = 'starting' | 'running' | 'succeeded' | 'failed' | 'interrupted' | 'superseded';
16
+ /** Read-only: never creates or removes the lock. */
17
+ export declare const readRunnerState: (root: string, opId: string, now?: number) => Promise<RunnerState>;
18
+ export declare const deriveOpState: (op: SlateOp, runner: RunnerState, now?: number) => DerivedOpState;
19
+ export type Liveness = {
20
+ runners: Map<string, RunnerState>;
21
+ states: Map<string, DerivedOpState>;
22
+ digest: string;
23
+ };
24
+ /** Liveness of every non-terminal op, plus the digest that goes into the view's `stamp`. */
25
+ export declare const readLiveness: (root: string, workspace: SlateWorkspace, now?: number) => Promise<Liveness>;
26
+ //# sourceMappingURL=slate-liveness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-liveness.d.ts","sourceRoot":"","sources":["../src/slate-liveness.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,sBAAsB,EACtB,4BAA4B,EAG7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE1E;;;;GAIG;AAEH,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,CAAC;AAEhE,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAChG,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC;AAE5G,oDAAoD;AACpD,eAAO,MAAM,eAAe,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,EAAE,YAAgB,KAAG,OAAO,CAAC,WAAW,CAYvG,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,IAAI,OAAO,EAAE,QAAQ,WAAW,EAAE,YAAgB,KAAG,cAKlF,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElH,4FAA4F;AAC5F,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,EAAE,WAAW,cAAc,EAAE,YAAgB,KAAG,OAAO,CAAC,QAAQ,CAU9G,CAAC"}
@@ -0,0 +1,49 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { sha256Hex } from './slate-ids.js';
3
+ import { RUNNER_ALIVE_WINDOW_MS, RUNNER_HEARTBEAT_INTERVAL_MS, parseHolder, processIsAlive, } from './slate-lock.js';
4
+ import { opLockFile } from './slate-paths.js';
5
+ /**
6
+ * What is actually running, derived from the per-op lock file and the clock.
7
+ * `starting` and `interrupted` are never written to `workspace.json`: a record
8
+ * written by a process that has since died must not claim it is still working.
9
+ */
10
+ export const RUNNER_START_GRACE_MS = 30_000;
11
+ export { RUNNER_ALIVE_WINDOW_MS, RUNNER_HEARTBEAT_INTERVAL_MS };
12
+ /** Read-only: never creates or removes the lock. */
13
+ export const readRunnerState = async (root, opId, now = Date.now()) => {
14
+ const file = opLockFile(root, opId);
15
+ try {
16
+ const [raw, entry] = await Promise.all([readFile(file, 'utf8'), stat(file)]);
17
+ const holder = parseHolder(raw);
18
+ if (!holder)
19
+ return { alive: false, pid: null, heartbeatAgeMs: Math.round(Math.max(0, now - entry.mtimeMs)) };
20
+ const age = Math.round(Math.max(0, now - entry.mtimeMs));
21
+ return { alive: processIsAlive(holder.pid) && age <= RUNNER_ALIVE_WINDOW_MS, pid: holder.pid, heartbeatAgeMs: age };
22
+ }
23
+ catch (error) {
24
+ if (error.code === 'ENOENT')
25
+ return { alive: false, pid: null, heartbeatAgeMs: null };
26
+ throw error;
27
+ }
28
+ };
29
+ export const deriveOpState = (op, runner, now = Date.now()) => {
30
+ if (op.state !== 'running')
31
+ return op.state;
32
+ if (runner.alive)
33
+ return 'running';
34
+ const lastSpawn = Date.parse(op.spawnedAt ?? op.startedAt);
35
+ return now - lastSpawn < RUNNER_START_GRACE_MS ? 'starting' : 'interrupted';
36
+ };
37
+ /** Liveness of every non-terminal op, plus the digest that goes into the view's `stamp`. */
38
+ export const readLiveness = async (root, workspace, now = Date.now()) => {
39
+ const runners = new Map();
40
+ const states = new Map();
41
+ for (const op of workspace.ops) {
42
+ const runner = op.state === 'running' ? await readRunnerState(root, op.opId, now) : { alive: false, pid: null, heartbeatAgeMs: null };
43
+ runners.set(op.opId, runner);
44
+ states.set(op.opId, deriveOpState(op, runner, now));
45
+ }
46
+ const digest = sha256Hex([...states.entries()].map(([id, state]) => `${id}:${state}`).join('|')).slice(0, 8);
47
+ return { runners, states, digest };
48
+ };
49
+ //# sourceMappingURL=slate-liveness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-liveness.js","sourceRoot":"","sources":["../src/slate-liveness.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LocalImageState } from './slate-view.js';
2
+ /**
3
+ * Whether Design and Edit can run on this Mac: the local Codex CLI, signed in
4
+ * with ChatGPT, with the image model available. It reads only the readiness
5
+ * probe (`codex --version`, `codex login status`, `codex exec --help` and the
6
+ * model cache), which runs no inference, and is asked at most once a minute
7
+ * per server. The workspace never buys an alternative: when this says not
8
+ * ready, the dialogs show the reason and stay disabled.
9
+ */
10
+ export type SlateImageProbe = () => Promise<LocalImageState>;
11
+ export declare const LOCAL_IMAGE_PROBE_TTL_MS = 60000;
12
+ /** The Codex desktop app ships its own CLI; it is the last place looked. */
13
+ export declare const CODEX_APP_BINARY = "/Applications/Codex.app/Contents/Resources/codex";
14
+ /** `TWELVE_UI_CODEX_BIN`, then `codex` on `PATH`, then the Codex app bundle if it is installed. */
15
+ export declare const resolveCodexBinary: (env?: NodeJS.ProcessEnv, exists?: (file: string) => boolean) => string;
16
+ export declare const codexReadinessProbe: (env?: NodeJS.ProcessEnv) => SlateImageProbe;
17
+ /** The probe's answer, kept for a minute. A not-ready reason is passed through verbatim. */
18
+ export declare const cachedImageProbe: (probe: SlateImageProbe, now: () => Date) => SlateImageProbe;
19
+ //# sourceMappingURL=slate-local-image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-local-image.d.ts","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD;;;;;;;GAOG;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;AAE7D,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAE/C,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,qDAAqD,CAAC;AAEnF,mGAAmG;AACnG,eAAO,MAAM,kBAAkB,GAC7B,MAAK,MAAM,CAAC,UAAwB,EACpC,SAAQ,CAAC,IAAI,EAAE,MAAM,KAAK,OAAoB,KAC7C,MAMF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,eAM1E,CAAC;AAEF,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,GAAI,OAAO,eAAe,EAAE,KAAK,MAAM,IAAI,KAAG,eAS1E,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { existsSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { probeCodexReadiness } from './cli-codex-readiness.js';
4
+ export const LOCAL_IMAGE_PROBE_TTL_MS = 60_000;
5
+ /** The Codex desktop app ships its own CLI; it is the last place looked. */
6
+ export const CODEX_APP_BINARY = '/Applications/Codex.app/Contents/Resources/codex';
7
+ /** `TWELVE_UI_CODEX_BIN`, then `codex` on `PATH`, then the Codex app bundle if it is installed. */
8
+ export const resolveCodexBinary = (env = process.env, exists = existsSync) => {
9
+ const explicit = env.TWELVE_UI_CODEX_BIN?.trim();
10
+ if (explicit)
11
+ return explicit;
12
+ const onPath = (env.PATH ?? '').split(path.delimiter).some((directory) => directory !== '' && exists(path.join(directory, 'codex')));
13
+ if (onPath)
14
+ return 'codex';
15
+ return exists(CODEX_APP_BINARY) ? CODEX_APP_BINARY : 'codex';
16
+ };
17
+ export const codexReadinessProbe = (env = process.env) => async () => {
18
+ const result = await probeCodexReadiness({
19
+ codexBin: resolveCodexBinary(env),
20
+ ...(env.CODEX_HOME?.trim() ? { codexHome: env.CODEX_HOME.trim() } : {}),
21
+ });
22
+ return { ready: result.ready, reason: result.ready ? null : result.reason };
23
+ };
24
+ /** The probe's answer, kept for a minute. A not-ready reason is passed through verbatim. */
25
+ export const cachedImageProbe = (probe, now) => {
26
+ let cached;
27
+ return async () => {
28
+ const at = now().getTime();
29
+ if (cached && at - cached.at < LOCAL_IMAGE_PROBE_TTL_MS && at >= cached.at)
30
+ return cached.state;
31
+ const state = await probe();
32
+ cached = { at, state };
33
+ return state;
34
+ };
35
+ };
36
+ //# sourceMappingURL=slate-local-image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-local-image.js","sourceRoot":"","sources":["../src/slate-local-image.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAc/D,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAE/C,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,kDAAkD,CAAC;AAEnF,mGAAmG;AACnG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAyB,OAAO,CAAC,GAAG,EACpC,SAAoC,UAAU,EACtC,EAAE;IACV,MAAM,QAAQ,GAAG,GAAG,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IACjD,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,EAAE,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IACrI,IAAI,MAAM;QAAE,OAAO,OAAO,CAAC;IAC3B,OAAO,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC;AAC/D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAyB,OAAO,CAAC,GAAG,EAAmB,EAAE,CAAC,KAAK,IAAI,EAAE;IACvG,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC;QACvC,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC;QACjC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACxE,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;AAC9E,CAAC,CAAC;AAEF,4FAA4F;AAC5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAsB,EAAE,GAAe,EAAmB,EAAE;IAC3F,IAAI,MAA0D,CAAC;IAC/D,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC3B,IAAI,MAAM,IAAI,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,wBAAwB,IAAI,EAAE,IAAI,MAAM,CAAC,EAAE;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC;QAChG,MAAM,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC;QAC5B,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * O_EXCL lock files with guarded, compare-before-unlink stale takeover.
3
+ *
4
+ * Three locks share this code: the workspace lock and the approval-store lock
5
+ * (a holder is stale only when its PID is gone; a live holder is waited on for
6
+ * a bounded time and never taken over) and the per-op runner lock (a holder is
7
+ * alive only while its PID is alive AND its mtime, the heartbeat, is fresh).
8
+ */
9
+ export declare const LOCK_WAIT_MS = 10000;
10
+ export declare const RUNNER_HEARTBEAT_INTERVAL_MS = 5000;
11
+ export declare const RUNNER_ALIVE_WINDOW_MS = 20000;
12
+ export type LockHolder = {
13
+ pid: number;
14
+ nonce: string;
15
+ startedAt: string;
16
+ };
17
+ export declare const processIsAlive: (pid: number) => boolean;
18
+ export declare const parseHolder: (raw: string) => LockHolder | undefined;
19
+ export type StalePolicy = (holder: LockHolder, mtimeMs: number, now: number) => boolean;
20
+ /** Workspace and approval locks: stale only when the holder process is gone. */
21
+ export declare const staleWhenProcessGone: StalePolicy;
22
+ /** Per-op runner lock: alive needs the PID and a fresh heartbeat. */
23
+ export declare const staleWhenHeartbeatLapsed: StalePolicy;
24
+ export type HeldLock = {
25
+ file: string;
26
+ holder: LockHolder;
27
+ release: () => Promise<void>;
28
+ touch: () => Promise<void>;
29
+ };
30
+ /**
31
+ * Take a stale lock over, one taker at a time. Takeover is serialised behind an
32
+ * exclusive guard file (`<lock>.takeover`, created with O_EXCL). Under the
33
+ * guard the lock is re-read: it is unlinked only if it is still byte-for-byte
34
+ * the stale holder the caller judged, so a lock that a rival re-created in the
35
+ * meantime is never touched. The caller then creates the new lock with the
36
+ * ordinary exclusive create. Returns true when the stale lock was removed,
37
+ * false when the guard was busy or the lock had already changed (the caller
38
+ * simply loops and re-observes).
39
+ */
40
+ export declare const takeOverStale: (file: string, observedRaw: string) => Promise<boolean>;
41
+ export declare const holderState: (file: string, policy: StalePolicy, now?: number) => Promise<{
42
+ state: "absent";
43
+ } | {
44
+ state: "live" | "stale";
45
+ holder: LockHolder | undefined;
46
+ raw: string;
47
+ mtimeMs: number;
48
+ }>;
49
+ export declare const acquireLock: (args: {
50
+ file: string;
51
+ policy: StalePolicy;
52
+ /** How long to wait for a live holder; 0 means fail at once. */
53
+ waitMs?: number;
54
+ busyMessage?: string;
55
+ }) => Promise<HeldLock>;
56
+ /** In-process queue per lock path, then the file lock: one writer at a time in this process too. */
57
+ export declare const withLock: <T>(args: {
58
+ file: string;
59
+ policy?: StalePolicy;
60
+ waitMs?: number;
61
+ busyMessage?: string;
62
+ run: () => Promise<T>;
63
+ }) => Promise<T>;
64
+ //# sourceMappingURL=slate-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-lock.d.ts","sourceRoot":"","sources":["../src/slate-lock.ts"],"names":[],"mappings":"AAMA;;;;;;;GAOG;AAEH,eAAO,MAAM,YAAY,QAAS,CAAC;AACnC,eAAO,MAAM,4BAA4B,OAAQ,CAAC;AAClD,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3E,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,KAAG,OAQ5C,CAAC;AAIF,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,KAAG,UAAU,GAAG,SAQtD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAExF,gFAAgF;AAChF,eAAO,MAAM,oBAAoB,EAAE,WAAqD,CAAC;AAEzF,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,EAAE,WAEtC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAiBtH;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GAAU,MAAM,MAAM,EAAE,aAAa,MAAM,KAAG,OAAO,CAAC,OAAO,CAgBtF,CAAC;AAYF,eAAO,MAAM,WAAW,GACtB,MAAM,MAAM,EACZ,QAAQ,WAAW,EACnB,YAAgB,KACf,OAAO,CAAC;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAiBzH,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,MAAM;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,KAAG,OAAO,CAAC,QAAQ,CA2BnB,CAAC;AAIF,oGAAoG;AACpG,eAAO,MAAM,QAAQ,GAAU,CAAC,EAAE,MAAM;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;CACvB,KAAG,OAAO,CAAC,CAAC,CAqBZ,CAAC"}
@@ -0,0 +1,178 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { open, readFile, rm, stat, utimes } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { SlateError } from './slate-errors.js';
5
+ /**
6
+ * O_EXCL lock files with guarded, compare-before-unlink stale takeover.
7
+ *
8
+ * Three locks share this code: the workspace lock and the approval-store lock
9
+ * (a holder is stale only when its PID is gone; a live holder is waited on for
10
+ * a bounded time and never taken over) and the per-op runner lock (a holder is
11
+ * alive only while its PID is alive AND its mtime, the heartbeat, is fresh).
12
+ */
13
+ export const LOCK_WAIT_MS = 10_000;
14
+ export const RUNNER_HEARTBEAT_INTERVAL_MS = 5_000;
15
+ export const RUNNER_ALIVE_WINDOW_MS = 20_000;
16
+ export const processIsAlive = (pid) => {
17
+ try {
18
+ process.kill(pid, 0);
19
+ return true;
20
+ }
21
+ catch (error) {
22
+ // EPERM means the process exists and belongs to somebody else.
23
+ return error.code === 'EPERM';
24
+ }
25
+ };
26
+ const sleep = (milliseconds) => new Promise((resolve) => { setTimeout(resolve, milliseconds); });
27
+ export const parseHolder = (raw) => {
28
+ try {
29
+ const parsed = JSON.parse(raw);
30
+ if (Number.isSafeInteger(parsed.pid) && typeof parsed.nonce === 'string' && typeof parsed.startedAt === 'string') {
31
+ return { pid: parsed.pid, nonce: parsed.nonce, startedAt: parsed.startedAt };
32
+ }
33
+ }
34
+ catch { /* an unreadable lock is treated as held by someone else */ }
35
+ return undefined;
36
+ };
37
+ /** Workspace and approval locks: stale only when the holder process is gone. */
38
+ export const staleWhenProcessGone = (holder) => !processIsAlive(holder.pid);
39
+ /** Per-op runner lock: alive needs the PID and a fresh heartbeat. */
40
+ export const staleWhenHeartbeatLapsed = (holder, mtimeMs, now) => (!processIsAlive(holder.pid) || now - mtimeMs > RUNNER_ALIVE_WINDOW_MS);
41
+ const tryCreate = async (file, holder) => {
42
+ try {
43
+ const handle = await open(file, 'wx', 0o600);
44
+ try {
45
+ await handle.writeFile(`${JSON.stringify(holder)}\n`, 'utf8');
46
+ }
47
+ finally {
48
+ await handle.close();
49
+ }
50
+ return true;
51
+ }
52
+ catch (error) {
53
+ if (error.code === 'EEXIST')
54
+ return false;
55
+ throw error;
56
+ }
57
+ };
58
+ /**
59
+ * Take a stale lock over, one taker at a time. Takeover is serialised behind an
60
+ * exclusive guard file (`<lock>.takeover`, created with O_EXCL). Under the
61
+ * guard the lock is re-read: it is unlinked only if it is still byte-for-byte
62
+ * the stale holder the caller judged, so a lock that a rival re-created in the
63
+ * meantime is never touched. The caller then creates the new lock with the
64
+ * ordinary exclusive create. Returns true when the stale lock was removed,
65
+ * false when the guard was busy or the lock had already changed (the caller
66
+ * simply loops and re-observes).
67
+ */
68
+ export const takeOverStale = async (file, observedRaw) => {
69
+ const guardFile = `${file}.takeover`;
70
+ const guardHolder = { pid: process.pid, nonce: randomUUID(), startedAt: new Date().toISOString() };
71
+ if (!(await tryCreate(guardFile, guardHolder))) {
72
+ await clearDeadGuard(guardFile);
73
+ return false;
74
+ }
75
+ try {
76
+ const current = await readFile(file, 'utf8').catch(() => undefined);
77
+ if (current !== observedRaw)
78
+ return false;
79
+ await rm(file, { force: true });
80
+ return true;
81
+ }
82
+ finally {
83
+ const guardNow = await readFile(guardFile, 'utf8').catch(() => '');
84
+ if (parseHolder(guardNow)?.nonce === guardHolder.nonce)
85
+ await rm(guardFile, { force: true });
86
+ }
87
+ };
88
+ /** A guard is held for milliseconds; one whose creator process is gone is cleared. */
89
+ const clearDeadGuard = async (guardFile) => {
90
+ const raw = await readFile(guardFile, 'utf8').catch(() => undefined);
91
+ if (raw === undefined)
92
+ return;
93
+ const holder = parseHolder(raw);
94
+ if (holder ? processIsAlive(holder.pid) : (Date.now() - (await stat(guardFile).then((s) => s.mtimeMs, () => Date.now()))) < 2_000)
95
+ return;
96
+ const again = await readFile(guardFile, 'utf8').catch(() => undefined);
97
+ if (again === raw)
98
+ await rm(guardFile, { force: true });
99
+ };
100
+ export const holderState = async (file, policy, now = Date.now()) => {
101
+ let raw;
102
+ let mtimeMs;
103
+ try {
104
+ raw = await readFile(file, 'utf8');
105
+ mtimeMs = (await stat(file)).mtimeMs;
106
+ }
107
+ catch (error) {
108
+ if (error.code === 'ENOENT')
109
+ return { state: 'absent' };
110
+ throw error;
111
+ }
112
+ const holder = parseHolder(raw);
113
+ if (!holder) {
114
+ // A lock that has no readable holder is only stale once it is old: a
115
+ // creator may be between open and write.
116
+ return { state: now - mtimeMs > 2_000 ? 'stale' : 'live', holder, raw, mtimeMs };
117
+ }
118
+ return { state: policy(holder, mtimeMs, now) ? 'stale' : 'live', holder, raw, mtimeMs };
119
+ };
120
+ export const acquireLock = async (args) => {
121
+ const holder = { pid: process.pid, nonce: randomUUID(), startedAt: new Date().toISOString() };
122
+ const deadline = Date.now() + (args.waitMs ?? LOCK_WAIT_MS);
123
+ for (;;) {
124
+ if (await tryCreate(args.file, holder)) {
125
+ return {
126
+ file: args.file,
127
+ holder,
128
+ touch: async () => { const now = new Date(); await utimes(args.file, now, now); },
129
+ release: async () => {
130
+ // Remove only our own lock: a takeover after a long pause may have replaced it.
131
+ const current = await readFile(args.file, 'utf8').catch(() => '');
132
+ if (parseHolder(current)?.nonce === holder.nonce)
133
+ await rm(args.file, { force: true });
134
+ },
135
+ };
136
+ }
137
+ const state = await holderState(args.file, args.policy);
138
+ if (state.state === 'stale') {
139
+ if (!(await takeOverStale(args.file, state.raw)))
140
+ await sleep(2 + Math.floor(Math.random() * 6));
141
+ continue;
142
+ }
143
+ if (state.state === 'absent')
144
+ continue;
145
+ if (Date.now() >= deadline) {
146
+ throw new SlateError('workspace_busy', args.busyMessage ?? `Another process holds ${path.basename(args.file)}; try again in a moment.`);
147
+ }
148
+ await sleep(25 + Math.floor(Math.random() * 25));
149
+ }
150
+ };
151
+ const processMutexes = new Map();
152
+ /** In-process queue per lock path, then the file lock: one writer at a time in this process too. */
153
+ export const withLock = async (args) => {
154
+ const previous = processMutexes.get(args.file) ?? Promise.resolve();
155
+ const turn = previous.catch(() => undefined).then(async () => {
156
+ const lock = await acquireLock({
157
+ file: args.file,
158
+ policy: args.policy ?? staleWhenProcessGone,
159
+ ...(args.waitMs === undefined ? {} : { waitMs: args.waitMs }),
160
+ ...(args.busyMessage ? { busyMessage: args.busyMessage } : {}),
161
+ });
162
+ try {
163
+ return await args.run();
164
+ }
165
+ finally {
166
+ await lock.release();
167
+ }
168
+ });
169
+ processMutexes.set(args.file, turn);
170
+ try {
171
+ return await turn;
172
+ }
173
+ finally {
174
+ if (processMutexes.get(args.file) === turn)
175
+ processMutexes.delete(args.file);
176
+ }
177
+ };
178
+ //# sourceMappingURL=slate-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-lock.js","sourceRoot":"","sources":["../src/slate-lock.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AACnC,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAClD,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC;AAI7C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,GAAW,EAAW,EAAE;IACrD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+DAA+D;QAC/D,OAAQ,KAA+B,CAAC,IAAI,KAAK,OAAO,CAAC;IAC3D,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,KAAK,GAAG,CAAC,YAAoB,EAAiB,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAExH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,GAAW,EAA0B,EAAE;IACjE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwB,CAAC;QACtD,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACjH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,GAAa,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QACzF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,2DAA2D,CAAC,CAAC;IACvE,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAIF,gFAAgF;AAChF,MAAM,CAAC,MAAM,oBAAoB,GAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAEzF,qEAAqE;AACrE,MAAM,CAAC,MAAM,wBAAwB,GAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC,CAC7E,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,OAAO,GAAG,sBAAsB,CACtE,CAAC;AAIF,MAAM,SAAS,GAAG,KAAK,EAAE,IAAY,EAAE,MAAkB,EAAoB,EAAE;IAC7E,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAChE,CAAC;gBAAS,CAAC;YACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,IAAY,EAAE,WAAmB,EAAoB,EAAE;IACzF,MAAM,SAAS,GAAG,GAAG,IAAI,WAAW,CAAC;IACrC,MAAM,WAAW,GAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAC/G,IAAI,CAAC,CAAC,MAAM,SAAS,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;QAC/C,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACpE,IAAI,OAAO,KAAK,WAAW;YAAE,OAAO,KAAK,CAAC;QAC1C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QACnE,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,KAAK,KAAK,WAAW,CAAC,KAAK;YAAE,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC,CAAC;AAEF,sFAAsF;AACtF,MAAM,cAAc,GAAG,KAAK,EAAE,SAAiB,EAAiB,EAAE;IAChE,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACrE,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO;IAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK;QAAE,OAAO;IAC1I,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACvE,IAAI,KAAK,KAAK,GAAG;QAAE,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,IAAY,EACZ,MAAmB,EACnB,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,EAC0G,EAAE;IAC5H,IAAI,GAAW,CAAC;IAChB,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACnF,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,qEAAqE;QACrE,yCAAyC;QACzC,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;IACnF,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;AAC1F,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,IAMjC,EAAqB,EAAE;IACtB,MAAM,MAAM,GAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAC1G,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,CAAC;IAC5D,SAAS,CAAC;QACR,IAAI,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;YACvC,OAAO;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM;gBACN,KAAK,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;gBACjF,OAAO,EAAE,KAAK,IAAI,EAAE;oBAClB,gFAAgF;oBAChF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;oBAClE,IAAI,WAAW,CAAC,OAAO,CAAC,EAAE,KAAK,KAAK,MAAM,CAAC,KAAK;wBAAE,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACzF,CAAC;aACF,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACxD,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;YAC5B,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;gBAAE,MAAM,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;YACjG,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ;YAAE,SAAS;QACvC,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,IAAI,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,WAAW,IAAI,yBAAyB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAC1I,CAAC;QACD,MAAM,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;IACnD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,IAAI,GAAG,EAA4B,CAAC;AAE3D,oGAAoG;AACpG,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAK,IAMjC,EAAc,EAAE;IACf,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;QAC3D,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,oBAAoB;YAC3C,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YAC7D,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/D,CAAC,CAAC;QACH,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;gBAAS,CAAC;YACT,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,45 @@
1
+ import type { SlateWorkspace } from './slate-workspace-types.js';
2
+ /**
3
+ * The one place ids become paths. Nothing read from a workspace record is used
4
+ * as a path: every file is recomputed from ids that passed their patterns, then
5
+ * resolved with `realpath` and required to stay inside the workspace root.
6
+ */
7
+ export declare const inside: (root: string, target: string) => boolean;
8
+ export declare const WORKSPACE_SUBDIRECTORIES: readonly ["ops", "versions", "edits", "inspiration", "calls"];
9
+ export type WorkspaceSubdirectory = typeof WORKSPACE_SUBDIRECTORIES[number];
10
+ /** A real directory inside the root: not a symlink, created 0700 on first use. */
11
+ export declare const ensureRealDirectory: (root: string, name: WorkspaceSubdirectory) => Promise<string>;
12
+ export declare const opLockFile: (root: string, opId: string) => string;
13
+ export declare const opLogFile: (root: string, opId: string) => string;
14
+ export declare const workspaceFile: (root: string) => string;
15
+ export declare const workspaceLockFile: (root: string) => string;
16
+ export declare const ledgerFile: (root: string) => string;
17
+ /** Every image a workspace draws or edits lives at `versions/<versionId>.png`, written once. */
18
+ export declare const versionImageFile: (root: string, versionId: string) => string;
19
+ /** The root run's own option image: `candidates/<A-P>.png` inside the finished draft run. */
20
+ export declare const rootCandidateFile: (root: string, localSlot: string) => string;
21
+ /** The file a version's image lives in, computed only from ids in the record. */
22
+ export declare const versionFilePath: (root: string, workspace: SlateWorkspace, versionId: string) => string;
23
+ /** `edits/<opId>/`: the parent copy and the annotated image an edit was committed with. */
24
+ export declare const editDirectory: (root: string, opId: string) => string;
25
+ /** Create `edits/<opId>/` as a real directory (0700); a link or a file in its place is refused. */
26
+ export declare const ensureEditDirectory: (root: string, opId: string) => Promise<string>;
27
+ export declare const editSourceFile: (root: string, opId: string) => string;
28
+ export declare const editAnnotatedFile: (root: string, opId: string) => string;
29
+ export type ReferenceSize = 'thumb' | 'ref';
30
+ export declare const referenceFile: (root: string, referenceId: string, size: ReferenceSize) => string;
31
+ export type ReadFileResult = {
32
+ state: 'ok';
33
+ bytes: Buffer;
34
+ sha256: string;
35
+ } | {
36
+ state: 'missing';
37
+ } | {
38
+ state: 'outside';
39
+ };
40
+ /**
41
+ * Read one workspace file. A symlink out of the root is refused (`outside`); a
42
+ * missing file is `missing`. The caller compares the sha256 with the record.
43
+ */
44
+ export declare const readWorkspaceFile: (root: string, file: string) => Promise<ReadFileResult>;
45
+ //# sourceMappingURL=slate-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slate-paths.d.ts","sourceRoot":"","sources":["../src/slate-paths.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;;;GAIG;AAEH,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,OAIrD,CAAC;AAEF,eAAO,MAAM,wBAAwB,+DAAgE,CAAC;AACtG,MAAM,MAAM,qBAAqB,GAAG,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAE5E,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,GAAU,MAAM,MAAM,EAAE,MAAM,qBAAqB,KAAG,OAAO,CAAC,MAAM,CAUnG,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAGvD,CAAC;AACF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAGtD,CAAC;AACF,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAA2C,CAAC;AACzF,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,MAA2C,CAAC;AAC7F,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,MAAyC,CAAC;AAEpF,gGAAgG;AAChG,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,MAGlE,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,WAAW,MAAM,KAAG,MAGnE,CAAC;AAEF,iFAAiF;AACjF,eAAO,MAAM,eAAe,GAAI,MAAM,MAAM,EAAE,WAAW,cAAc,EAAE,WAAW,MAAM,KAAG,MAO5F,CAAC;AAEF,2FAA2F;AAC3F,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAG1D,CAAC;AACF,mGAAmG;AACnG,eAAO,MAAM,mBAAmB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,CAWpF,CAAC;AACF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAA4D,CAAC;AACzH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAA+D,CAAC;AAE/H,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,CAAC;AAC5C,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,EAAE,aAAa,MAAM,EAAE,MAAM,aAAa,KAAG,MAGtF,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9C;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAIzB;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAAU,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,cAAc,CAyB1F,CAAC"}