makersclaw 0.8.0 → 0.8.1

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 (401) hide show
  1. package/README.md +9 -3
  2. package/package.json +1 -1
  3. package/r/activity-log.json +52 -0
  4. package/r/agent-changes.json +51 -0
  5. package/r/agent-chat.json +53 -0
  6. package/r/agent-column.json +85 -0
  7. package/r/agent-dock.json +57 -0
  8. package/r/agent-kit.json +49 -0
  9. package/r/agent-marks.json +49 -0
  10. package/r/agent-pane.json +93 -0
  11. package/r/ai-action.json +56 -0
  12. package/r/annotate.json +3 -3
  13. package/r/approval-request.json +2 -2
  14. package/r/approval.json +54 -0
  15. package/r/ask-bar.json +50 -0
  16. package/r/audio-player.json +2 -2
  17. package/r/auth-form.json +2 -2
  18. package/r/automation-editor.json +66 -0
  19. package/r/automation-list.json +57 -0
  20. package/r/automation-model.json +118 -0
  21. package/r/automations-screen.json +71 -0
  22. package/r/board.json +2 -2
  23. package/r/calendar-view.json +3 -3
  24. package/r/cart.json +2 -2
  25. package/r/chart.json +2 -2
  26. package/r/chat-pane.json +84 -0
  27. package/r/chat.json +2 -2
  28. package/r/code-editor.json +2 -2
  29. package/r/comment-box.json +3 -3
  30. package/r/connect-card.json +51 -0
  31. package/r/contact-section.json +2 -2
  32. package/r/core.json +13 -7
  33. package/r/cost.json +51 -0
  34. package/r/csv-import.json +3 -3
  35. package/r/data-picker.json +60 -0
  36. package/r/data-table.json +2 -2
  37. package/r/diagram.json +2 -2
  38. package/r/doc-editor.json +2 -2
  39. package/r/doc-page.json +3 -3
  40. package/r/email-render.json +2 -2
  41. package/r/faq.json +2 -2
  42. package/r/file-upload.json +2 -2
  43. package/r/first-run.json +63 -0
  44. package/r/fix-note.json +57 -0
  45. package/r/flow-canvas.json +2 -2
  46. package/r/flow-editor.json +79 -0
  47. package/r/footer.json +2 -2
  48. package/r/gantt.json +3 -3
  49. package/r/job-panel.json +2 -2
  50. package/r/json-editor.json +3 -3
  51. package/r/library-shelf.json +56 -0
  52. package/r/map.json +2 -2
  53. package/r/margin-notes.json +67 -0
  54. package/r/menubar.json +2 -2
  55. package/r/mind-map.json +3 -3
  56. package/r/navigation-menu.json +2 -2
  57. package/r/needs-you.json +55 -0
  58. package/r/order-detail.json +2 -2
  59. package/r/org-chart.json +3 -3
  60. package/r/pace-bar.json +69 -0
  61. package/r/page-builder.json +2 -2
  62. package/r/payment-methods.json +2 -2
  63. package/r/pdf-document.json +2 -2
  64. package/r/pdf-viewer.json +2 -2
  65. package/r/product-detail.json +2 -2
  66. package/r/product-grid.json +3 -3
  67. package/r/record-form.json +2 -2
  68. package/r/record-grid.json +52 -0
  69. package/r/record-notes.json +4 -4
  70. package/r/registry.json +4086 -1512
  71. package/r/run-history.json +52 -0
  72. package/r/run-view.json +80 -0
  73. package/r/schedule-card.json +54 -0
  74. package/r/schedule-engine.json +79 -0
  75. package/r/schedule-gantt.json +83 -0
  76. package/r/schedule-ruler.json +64 -0
  77. package/r/search-dialog.json +2 -2
  78. package/r/settings-list.json +2 -2
  79. package/r/setup-checklist.json +2 -2
  80. package/r/share-dialog.json +2 -2
  81. package/r/sidebar.json +2 -2
  82. package/r/signature-pad.json +2 -2
  83. package/r/sketch-canvas.json +2 -2
  84. package/r/source-receipt.json +52 -0
  85. package/r/spreadsheet.json +3 -3
  86. package/r/stat-cards.json +3 -3
  87. package/r/step-picker.json +53 -0
  88. package/r/step-settings.json +72 -0
  89. package/r/suggestion.json +58 -0
  90. package/r/sum-bar.json +64 -0
  91. package/r/task-list.json +3 -3
  92. package/r/task-model.json +2 -2
  93. package/r/testimonials.json +2 -2
  94. package/r/tier-map.json +67 -0
  95. package/r/time-grid.json +73 -0
  96. package/r/time-strip.json +64 -0
  97. package/r/top-bar.json +66 -0
  98. package/r/transaction-list.json +2 -2
  99. package/r/trigger-picker.json +61 -0
  100. package/r/whiteboard.json +3 -3
  101. package/r/workflow-view.json +55 -0
  102. package/registry/blocks/activity-log/README.md +112 -0
  103. package/registry/blocks/activity-log/activity-log.jsx +351 -0
  104. package/registry/blocks/activity-log/block.json +33 -0
  105. package/registry/blocks/activity-log/demo.jsx +48 -0
  106. package/registry/blocks/activity-log/index.js +4 -0
  107. package/registry/blocks/agent-changes/README.md +94 -0
  108. package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
  109. package/registry/blocks/agent-changes/block.json +28 -0
  110. package/registry/blocks/agent-changes/demo.jsx +39 -0
  111. package/registry/blocks/agent-changes/index.js +3 -0
  112. package/registry/blocks/agent-chat/README.md +145 -0
  113. package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
  114. package/registry/blocks/agent-chat/block.json +30 -0
  115. package/registry/blocks/agent-chat/demo.jsx +165 -0
  116. package/registry/blocks/agent-chat/index.js +3 -0
  117. package/registry/blocks/agent-column/README.md +197 -0
  118. package/registry/blocks/agent-column/agent-column.jsx +492 -0
  119. package/registry/blocks/agent-column/block.json +67 -0
  120. package/registry/blocks/agent-column/column-picker.jsx +163 -0
  121. package/registry/blocks/agent-column/demo.jsx +50 -0
  122. package/registry/blocks/agent-column/index.js +7 -0
  123. package/registry/blocks/agent-column/model.js +164 -0
  124. package/registry/blocks/agent-column/receipt.jsx +483 -0
  125. package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
  126. package/registry/blocks/agent-dock/README.md +210 -0
  127. package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
  128. package/registry/blocks/agent-dock/block.json +47 -0
  129. package/registry/blocks/agent-dock/demo.jsx +153 -0
  130. package/registry/blocks/agent-dock/dock-model.js +118 -0
  131. package/registry/blocks/agent-dock/index.js +5 -0
  132. package/registry/blocks/agent-kit/README.md +73 -0
  133. package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
  134. package/registry/blocks/agent-kit/block.json +10 -0
  135. package/registry/blocks/agent-kit/demo.jsx +35 -0
  136. package/registry/blocks/agent-kit/index.js +3 -0
  137. package/registry/blocks/agent-marks/README.md +80 -0
  138. package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
  139. package/registry/blocks/agent-marks/block.json +27 -0
  140. package/registry/blocks/agent-marks/demo.jsx +49 -0
  141. package/registry/blocks/agent-marks/index.js +3 -0
  142. package/registry/blocks/agent-pane/README.md +225 -0
  143. package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
  144. package/registry/blocks/agent-pane/block.json +41 -0
  145. package/registry/blocks/agent-pane/composer.jsx +6 -0
  146. package/registry/blocks/agent-pane/demo.jsx +233 -0
  147. package/registry/blocks/agent-pane/dock-context.js +10 -0
  148. package/registry/blocks/agent-pane/index.js +4 -0
  149. package/registry/blocks/agent-pane/prose.jsx +84 -0
  150. package/registry/blocks/agent-pane/questions.jsx +134 -0
  151. package/registry/blocks/agent-pane/transcript.jsx +268 -0
  152. package/registry/blocks/agent-pane/work.jsx +368 -0
  153. package/registry/blocks/ai-action/README.md +94 -0
  154. package/registry/blocks/ai-action/ai-action.jsx +188 -0
  155. package/registry/blocks/ai-action/block.json +34 -0
  156. package/registry/blocks/ai-action/demo.jsx +93 -0
  157. package/registry/blocks/ai-action/index.js +3 -0
  158. package/registry/blocks/approval/README.md +145 -0
  159. package/registry/blocks/approval/approval.jsx +163 -0
  160. package/registry/blocks/approval/block.json +31 -0
  161. package/registry/blocks/approval/demo.jsx +121 -0
  162. package/registry/blocks/approval/index.js +3 -0
  163. package/registry/blocks/ask-bar/README.md +105 -0
  164. package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
  165. package/registry/blocks/ask-bar/block.json +26 -0
  166. package/registry/blocks/ask-bar/demo.jsx +78 -0
  167. package/registry/blocks/ask-bar/index.js +3 -0
  168. package/registry/blocks/automation-editor/README.md +291 -0
  169. package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
  170. package/registry/blocks/automation-editor/block.json +39 -0
  171. package/registry/blocks/automation-editor/demo.jsx +284 -0
  172. package/registry/blocks/automation-editor/index.js +4 -0
  173. package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
  174. package/registry/blocks/automation-list/README.md +129 -0
  175. package/registry/blocks/automation-list/automation-list.jsx +476 -0
  176. package/registry/blocks/automation-list/block.json +35 -0
  177. package/registry/blocks/automation-list/demo.jsx +67 -0
  178. package/registry/blocks/automation-list/index.js +3 -0
  179. package/registry/blocks/automation-model/README.md +109 -0
  180. package/registry/blocks/automation-model/block.json +135 -0
  181. package/registry/blocks/automation-model/catalog.js +256 -0
  182. package/registry/blocks/automation-model/check.js +161 -0
  183. package/registry/blocks/automation-model/demo.jsx +42 -0
  184. package/registry/blocks/automation-model/edit.js +262 -0
  185. package/registry/blocks/automation-model/fixes.js +287 -0
  186. package/registry/blocks/automation-model/glyph.jsx +13 -0
  187. package/registry/blocks/automation-model/graph.js +410 -0
  188. package/registry/blocks/automation-model/index.js +33 -0
  189. package/registry/blocks/automation-model/overlay.js +175 -0
  190. package/registry/blocks/automation-model/parts.jsx +94 -0
  191. package/registry/blocks/automation-model/schedule.js +53 -0
  192. package/registry/blocks/automation-model/templates.js +128 -0
  193. package/registry/blocks/automation-model/values.js +29 -0
  194. package/registry/blocks/automation-model/words.js +439 -0
  195. package/registry/blocks/automations-screen/README.md +207 -0
  196. package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
  197. package/registry/blocks/automations-screen/block.json +47 -0
  198. package/registry/blocks/automations-screen/demo.jsx +364 -0
  199. package/registry/blocks/automations-screen/index.js +4 -0
  200. package/registry/blocks/automations-screen/screen-model.js +129 -0
  201. package/registry/blocks/chat-pane/README.md +143 -0
  202. package/registry/blocks/chat-pane/block.json +48 -0
  203. package/registry/blocks/chat-pane/chat-attach.js +166 -0
  204. package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
  205. package/registry/blocks/chat-pane/chat-context.js +17 -0
  206. package/registry/blocks/chat-pane/chat-model.js +43 -0
  207. package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
  208. package/registry/blocks/chat-pane/chats-list.jsx +52 -0
  209. package/registry/blocks/chat-pane/demo.jsx +103 -0
  210. package/registry/blocks/chat-pane/index.js +9 -0
  211. package/registry/blocks/connect-card/README.md +99 -0
  212. package/registry/blocks/connect-card/block.json +10 -0
  213. package/registry/blocks/connect-card/connect-card.jsx +103 -0
  214. package/registry/blocks/connect-card/demo.jsx +49 -0
  215. package/registry/blocks/connect-card/index.js +3 -0
  216. package/registry/blocks/cost/README.md +115 -0
  217. package/registry/blocks/cost/block.json +10 -0
  218. package/registry/blocks/cost/cost.jsx +176 -0
  219. package/registry/blocks/cost/demo.jsx +66 -0
  220. package/registry/blocks/cost/index.js +3 -0
  221. package/registry/blocks/data-picker/README.md +81 -0
  222. package/registry/blocks/data-picker/block.json +38 -0
  223. package/registry/blocks/data-picker/data-picker.jsx +210 -0
  224. package/registry/blocks/data-picker/demo.jsx +34 -0
  225. package/registry/blocks/data-picker/fields.js +89 -0
  226. package/registry/blocks/data-picker/index.js +4 -0
  227. package/registry/blocks/data-table/demo.jsx +1 -1
  228. package/registry/blocks/first-run/README.md +118 -0
  229. package/registry/blocks/first-run/block.json +11 -0
  230. package/registry/blocks/first-run/demo.jsx +88 -0
  231. package/registry/blocks/first-run/first-run-model.js +51 -0
  232. package/registry/blocks/first-run/first-run.jsx +156 -0
  233. package/registry/blocks/first-run/index.js +5 -0
  234. package/registry/blocks/first-run/probe-rules.js +26 -0
  235. package/registry/blocks/fix-note/README.md +79 -0
  236. package/registry/blocks/fix-note/block.json +35 -0
  237. package/registry/blocks/fix-note/demo.jsx +30 -0
  238. package/registry/blocks/fix-note/fix-note.jsx +235 -0
  239. package/registry/blocks/fix-note/index.js +3 -0
  240. package/registry/blocks/flow-editor/README.md +108 -0
  241. package/registry/blocks/flow-editor/block.json +44 -0
  242. package/registry/blocks/flow-editor/demo.jsx +115 -0
  243. package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
  244. package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
  245. package/registry/blocks/flow-editor/index.js +6 -0
  246. package/registry/blocks/flow-editor/minimap.jsx +78 -0
  247. package/registry/blocks/flow-editor/outline.jsx +134 -0
  248. package/registry/blocks/library-shelf/README.md +117 -0
  249. package/registry/blocks/library-shelf/block.json +28 -0
  250. package/registry/blocks/library-shelf/demo.jsx +68 -0
  251. package/registry/blocks/library-shelf/index.js +3 -0
  252. package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
  253. package/registry/blocks/library-shelf/probe-rules.js +15 -0
  254. package/registry/blocks/margin-notes/README.md +222 -0
  255. package/registry/blocks/margin-notes/block.json +10 -0
  256. package/registry/blocks/margin-notes/demo.jsx +144 -0
  257. package/registry/blocks/margin-notes/index.js +20 -0
  258. package/registry/blocks/margin-notes/margin-model.js +224 -0
  259. package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
  260. package/registry/blocks/needs-you/README.md +177 -0
  261. package/registry/blocks/needs-you/block.json +34 -0
  262. package/registry/blocks/needs-you/demo.jsx +143 -0
  263. package/registry/blocks/needs-you/index.js +3 -0
  264. package/registry/blocks/needs-you/needs-you.jsx +441 -0
  265. package/registry/blocks/pace-bar/README.md +230 -0
  266. package/registry/blocks/pace-bar/block.json +10 -0
  267. package/registry/blocks/pace-bar/demo.jsx +255 -0
  268. package/registry/blocks/pace-bar/index.js +22 -0
  269. package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
  270. package/registry/blocks/pace-bar/pace-model.js +288 -0
  271. package/registry/blocks/record-grid/README.md +100 -0
  272. package/registry/blocks/record-grid/block.json +28 -0
  273. package/registry/blocks/record-grid/demo.jsx +43 -0
  274. package/registry/blocks/record-grid/index.js +3 -0
  275. package/registry/blocks/record-grid/record-grid.jsx +251 -0
  276. package/registry/blocks/run-history/README.md +138 -0
  277. package/registry/blocks/run-history/block.json +10 -0
  278. package/registry/blocks/run-history/demo.jsx +74 -0
  279. package/registry/blocks/run-history/index.js +3 -0
  280. package/registry/blocks/run-history/run-history.jsx +218 -0
  281. package/registry/blocks/run-view/README.md +174 -0
  282. package/registry/blocks/run-view/block.json +50 -0
  283. package/registry/blocks/run-view/demo.jsx +286 -0
  284. package/registry/blocks/run-view/index.js +5 -0
  285. package/registry/blocks/run-view/run-controls.jsx +266 -0
  286. package/registry/blocks/run-view/run-view.jsx +236 -0
  287. package/registry/blocks/run-view/runs-list.jsx +99 -0
  288. package/registry/blocks/schedule-card/README.md +121 -0
  289. package/registry/blocks/schedule-card/block.json +10 -0
  290. package/registry/blocks/schedule-card/demo.jsx +82 -0
  291. package/registry/blocks/schedule-card/index.js +3 -0
  292. package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
  293. package/registry/blocks/schedule-engine/README.md +137 -0
  294. package/registry/blocks/schedule-engine/block.json +10 -0
  295. package/registry/blocks/schedule-engine/demo.jsx +82 -0
  296. package/registry/blocks/schedule-engine/engine.js +769 -0
  297. package/registry/blocks/schedule-engine/index.js +9 -0
  298. package/registry/blocks/schedule-engine/ops.js +71 -0
  299. package/registry/blocks/schedule-engine/place.js +294 -0
  300. package/registry/blocks/schedule-engine/tree.js +79 -0
  301. package/registry/blocks/schedule-engine/waits.js +80 -0
  302. package/registry/blocks/schedule-gantt/README.md +159 -0
  303. package/registry/blocks/schedule-gantt/block.json +10 -0
  304. package/registry/blocks/schedule-gantt/demo.jsx +223 -0
  305. package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
  306. package/registry/blocks/schedule-gantt/geometry.js +176 -0
  307. package/registry/blocks/schedule-gantt/index.js +26 -0
  308. package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
  309. package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
  310. package/registry/blocks/schedule-gantt/track.jsx +190 -0
  311. package/registry/blocks/schedule-ruler/README.md +148 -0
  312. package/registry/blocks/schedule-ruler/block.json +10 -0
  313. package/registry/blocks/schedule-ruler/demo.jsx +181 -0
  314. package/registry/blocks/schedule-ruler/index.js +21 -0
  315. package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
  316. package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
  317. package/registry/blocks/source-receipt/README.md +97 -0
  318. package/registry/blocks/source-receipt/block.json +30 -0
  319. package/registry/blocks/source-receipt/demo.jsx +71 -0
  320. package/registry/blocks/source-receipt/index.js +3 -0
  321. package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
  322. package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
  323. package/registry/blocks/step-picker/README.md +78 -0
  324. package/registry/blocks/step-picker/block.json +31 -0
  325. package/registry/blocks/step-picker/demo.jsx +23 -0
  326. package/registry/blocks/step-picker/index.js +3 -0
  327. package/registry/blocks/step-picker/step-picker.jsx +144 -0
  328. package/registry/blocks/step-settings/README.md +100 -0
  329. package/registry/blocks/step-settings/block.json +44 -0
  330. package/registry/blocks/step-settings/demo.jsx +93 -0
  331. package/registry/blocks/step-settings/fields.jsx +58 -0
  332. package/registry/blocks/step-settings/flow-settings.jsx +115 -0
  333. package/registry/blocks/step-settings/index.js +5 -0
  334. package/registry/blocks/step-settings/step-settings.jsx +290 -0
  335. package/registry/blocks/suggestion/README.md +171 -0
  336. package/registry/blocks/suggestion/block.json +40 -0
  337. package/registry/blocks/suggestion/demo.jsx +91 -0
  338. package/registry/blocks/suggestion/index.js +3 -0
  339. package/registry/blocks/suggestion/suggestion.jsx +436 -0
  340. package/registry/blocks/sum-bar/README.md +122 -0
  341. package/registry/blocks/sum-bar/block.json +10 -0
  342. package/registry/blocks/sum-bar/demo.jsx +110 -0
  343. package/registry/blocks/sum-bar/index.js +5 -0
  344. package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
  345. package/registry/blocks/sum-bar/sum-model.js +126 -0
  346. package/registry/blocks/tier-map/README.md +217 -0
  347. package/registry/blocks/tier-map/block.json +10 -0
  348. package/registry/blocks/tier-map/demo.jsx +222 -0
  349. package/registry/blocks/tier-map/index.js +24 -0
  350. package/registry/blocks/tier-map/tier-map.jsx +574 -0
  351. package/registry/blocks/tier-map/tier-model.js +318 -0
  352. package/registry/blocks/time-grid/README.md +305 -0
  353. package/registry/blocks/time-grid/block.json +10 -0
  354. package/registry/blocks/time-grid/demo.jsx +279 -0
  355. package/registry/blocks/time-grid/grid-model.js +322 -0
  356. package/registry/blocks/time-grid/index.js +25 -0
  357. package/registry/blocks/time-grid/time-grid.jsx +1325 -0
  358. package/registry/blocks/time-strip/README.md +141 -0
  359. package/registry/blocks/time-strip/block.json +10 -0
  360. package/registry/blocks/time-strip/demo.jsx +129 -0
  361. package/registry/blocks/time-strip/index.js +19 -0
  362. package/registry/blocks/time-strip/strip-model.js +178 -0
  363. package/registry/blocks/time-strip/time-strip.jsx +260 -0
  364. package/registry/blocks/top-bar/README.md +149 -0
  365. package/registry/blocks/top-bar/block.json +35 -0
  366. package/registry/blocks/top-bar/demo.jsx +78 -0
  367. package/registry/blocks/top-bar/index.js +5 -0
  368. package/registry/blocks/top-bar/probe-rules.js +74 -0
  369. package/registry/blocks/top-bar/top-bar-model.js +152 -0
  370. package/registry/blocks/top-bar/top-bar.jsx +244 -0
  371. package/registry/blocks/trigger-picker/README.md +98 -0
  372. package/registry/blocks/trigger-picker/block.json +38 -0
  373. package/registry/blocks/trigger-picker/demo.jsx +59 -0
  374. package/registry/blocks/trigger-picker/index.js +3 -0
  375. package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
  376. package/registry/blocks/workflow-view/README.md +123 -0
  377. package/registry/blocks/workflow-view/block.json +10 -0
  378. package/registry/blocks/workflow-view/demo.jsx +90 -0
  379. package/registry/blocks/workflow-view/index.js +3 -0
  380. package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
  381. package/src/install.mjs +77 -16
  382. package/src/registry.mjs +3 -0
  383. package/templates/next/browser/lib/data.js +6 -1
  384. package/templates/next/files/README.md +627 -24
  385. package/templates/next/files/check/automation-format.ts +2103 -0
  386. package/templates/next/files/check/automation-package.ts +142 -0
  387. package/templates/next/files/check/run.mjs +968 -9
  388. package/templates/next/files/components/ui/field.jsx +17 -4
  389. package/templates/next/files/components/ui/icon.jsx +13 -0
  390. package/templates/next/files/components/ui/index.js +2 -1
  391. package/templates/next/files/components/ui/layout.jsx +77 -2
  392. package/templates/next/files/components/ui/notice.jsx +70 -0
  393. package/templates/next/files/components/ui/page.jsx +124 -0
  394. package/templates/next/files/components/ui/stat.jsx +22 -7
  395. package/templates/next/files/components/ui/toast.jsx +6 -3
  396. package/templates/next/files/lib/automations.js +660 -0
  397. package/templates/next/files/lib/claw.js +241 -5
  398. package/templates/next/files/lib/door.js +92 -0
  399. package/templates/next/files/lib/hooks.js +1627 -8
  400. package/templates/next/files/lib/platform.js +529 -21
  401. package/templates/next/template.json +13 -3
@@ -1,4 +1,4 @@
1
- import { claw, clawBasePath, clawStream, openInDesk, publishDesk, reportError } from "./claw";
1
+ import { claw, clawBasePath, clawNdjson, clawStream, openApp, openConnections, openFile, openInDesk, publishDesk, reportError } from "./claw";
2
2
 
3
3
  // Typed wrappers over the _claw API (lib/claw.js), one per route an app
4
4
  // has a reason to call. BROWSER only — the grant cookie is the identity —
@@ -18,16 +18,42 @@ import { claw, clawBasePath, clawStream, openInDesk, publishDesk, reportError }
18
18
  // column, which the ask opens. `requests` reads this app's asks in
19
19
  // flight, so an empty surface can show the work coming instead of a
20
20
  // blank; `stopRequest` stops one; `openRequest` opens one in the column
21
- // again. That is not monitoring: the OS still draws Agent, Runs and
22
- // Activity as tabs on the window, and nothing here lists chats, runs or
23
- // activity. `startJob` / `cancelJob` are the 0.3.x door to the same work,
21
+ // again. `threads` / `thread` (0.8.1) read the member's own threads in
22
+ // this app, so the app can draw its own chat with its agent (the
23
+ // `agent-chat` block) — the same conversation the column shows, never a
24
+ // copy. `startJob` / `cancelJob` are the 0.3.x door to the same work,
24
25
  // streamed into the app; they stay for a claw that has no _claw/ask yet.
25
26
  // And CALLING A MODEL (0.8.0): `llm` is one shot of text work on what is
26
27
  // on screen — sort these, draft that, translate this — answered in the
27
28
  // page, with no thread, no tools and no request on the desk. It is the
28
- // opposite of `ask`, which hands work to the app's agent. `claw(path,
29
- // opts)` and `clawStream` in lib/claw.js are the generic doors for the
30
- // rest of §5.
29
+ // opposite of `ask`, which hands work to the app's agent. And SHOWING THE
30
+ // LIBRARY (0.8.1): `library` reads the collections Makersclaw keeps —
31
+ // decks, website templates, datasets — live, read-only, for a screen that
32
+ // shows examples or a dataset. A copy into the workspace is not here: it
33
+ // goes through the agent, with `ask`. And THE KIT (0.8.1, D15): the
34
+ // app's jobs (`jobs`, `setJob`, `runNow`, `pauseApp`, `resumeApp`), its
35
+ // runs (`runs`, `run`), its activity (`activity`), its accounts
36
+ // (`connections`, `connectLink`; `openConnections` asks the desk), what
37
+ // its agent knows and can do (`agentKit`), and a model call's price
38
+ // before it is made (`llmEstimate`). And THE YES AND THE AGENT'S
39
+ // QUESTIONS, IN THE APP (D18, D19): `approval` hands the facts of a yes
40
+ // that waits on the member and the address of the Makersclaw-held press
41
+ // frame to embed in the app's own card; `answer` answers the agent's
42
+ // question in the chat where it was asked.
43
+ //
44
+ // Up to the kit this header said nothing here lists runs or activity:
45
+ // the OS drew Agent, Runs and Activity as tabs on the window so every app
46
+ // looked the same, and an app that drew its own would have drawn one
47
+ // more look. The kit's blocks (schedule-card, run-history, workflow-view,
48
+ // activity-log, connect-card, agent-kit, …) are that one look now, inside
49
+ // the app, so the app shows its agent's work itself, beside the rows the
50
+ // work wrote. The OS tabs stay, as the full history. What never moves
51
+ // into the app: the yes, the account sign-in and money — the desk's.
52
+ // The door decides who may press what (`may` on `jobs`): a block hides a
53
+ // control the member may not use, and the door refuses it anyway.
54
+ //
55
+ // `claw(path, opts)` and `clawStream` in lib/claw.js are the generic
56
+ // doors for the rest of §5.
31
57
 
32
58
  /** GET _claw/me → { artifact: { id, name, vehicle, status, home },
33
59
  * user: { id, email }, blueprint, desk_origin } */
@@ -70,13 +96,21 @@ function currentSurface() {
70
96
  * list the list it belongs to, for an app that declares lists
71
97
  * surface defaults to the <key> of /s/<key> in the page's path
72
98
  * sessionId continue this thread instead of starting one
99
+ * files [{ name, type, data }] sent with the words (0.8.1, D27
100
+ * phase 4: the `agent-pane` block's attach). `data` is a
101
+ * base64 data URL (readAsDataURL). At most 4 files and 3 MB
102
+ * together; the agent reads them as the desk's attachments.
103
+ * `data.files_attached` in the answer is false when the ask
104
+ * was taken but is queued behind another: the files did not
105
+ * go, send them again once it starts.
73
106
  *
74
- * → { ok: true, status, data: { ok, request, desk_origin } }, or a
75
- * refusal with its `code`: `not_your_thread` (403, a teammate's thread:
76
- * start your own), `needs_answer` (409, the thread waits on an answer in
77
- * the column), `queue_full` (409).
107
+ * → { ok: true, status, data: { ok, request, desk_origin, files_attached? } },
108
+ * or a refusal with its `code`: `not_your_thread` (403, a teammate's
109
+ * thread: start your own), `needs_answer` (409, the thread waits on an
110
+ * answer in the column), `queue_full` (409), `files_too_large` (413),
111
+ * `too_many_files`, `bad_files` (400).
78
112
  */
79
- export async function ask({ text, row, how, job, list, surface, sessionId, open = true, signal } = {}) {
113
+ export async function ask({ text, row, how, job, list, surface, sessionId, files, open = true, signal } = {}) {
80
114
  const words = String(text ?? "").trim();
81
115
  if (!words) return { ok: false, status: 0, error: "nothing to ask", unavailable: false };
82
116
  const r = await claw("ask", {
@@ -90,6 +124,10 @@ export async function ask({ text, row, how, job, list, surface, sessionId, open
90
124
  list: list ?? undefined,
91
125
  surface: surface ?? currentSurface(),
92
126
  session_id: sessionId || undefined,
127
+ files:
128
+ Array.isArray(files) && files.length > 0
129
+ ? files.map((f) => ({ name: f?.name, type: f?.type || undefined, data: f?.data }))
130
+ : undefined,
93
131
  },
94
132
  signal,
95
133
  });
@@ -117,10 +155,187 @@ export function stopRequest(id) {
117
155
 
118
156
  /** Open a request's conversation in the desk's agent column again. Takes
119
157
  * the request (its thread opens with it when it is yours) or its id.
120
- * → true when the desk was asked. */
158
+ * A member's press, so it opens the column even for an app that draws
159
+ * its own chat (lib/claw.js openInDesk, `show`). → true when the desk
160
+ * was asked. */
121
161
  export function openRequest(requestOrId) {
122
162
  const request = requestOrId && typeof requestOrId === "object" ? requestOrId : { id: requestOrId };
123
- return openInDesk({ requestId: request.id, sessionId: request.app_session_id ?? null });
163
+ return openInDesk({ requestId: request.id, sessionId: request.app_session_id ?? null, show: true });
164
+ }
165
+
166
+ /** GET _claw/threads → { threads: [{ session_id, request_id, title,
167
+ * status, updated_at }], desk_origin }: the member's own threads in this
168
+ * app, newest first — asks made from its screens or its chat. Never a
169
+ * teammate's. */
170
+ export function threads({ signal } = {}) {
171
+ return claw("threads", { signal });
172
+ }
173
+
174
+ /**
175
+ * GET _claw/threads/<session> → one of the member's threads, as the app's
176
+ * own chat shows it (0.8.1; the `agent-chat` block, useAgentThread):
177
+ *
178
+ * { session_id, thread: "app" | "makersclaw",
179
+ * state: "queued" | "working" | "needs_you" | "done" | "stopped" | "failed",
180
+ * needs: { kind, text, at, in_app, options?, free? } | null,
181
+ * // what waits on the member. `in_app` is how the app can
182
+ * // settle it: "answer" (a question: answer(), with its
183
+ * // `options` and whether `free` words are welcome),
184
+ * // "press" (the one ask's yes: approval(), the press
185
+ * // frame), or null (on the desk)
186
+ * request, // as _claw/requests shows one
187
+ * turns: [{ id, at, member, status, writing,
188
+ * parts: [{ type: "text", text } | { type: "step", label, status }] }],
189
+ * desk_origin }
190
+ *
191
+ * The same conversation the desk's agent column shows: one session, two
192
+ * views. `member` is the member's words; `parts` the agent's text and one
193
+ * line per step, in order; `writing` the text being written now. Refusals:
194
+ * `not_your_thread` (403, a teammate's), `unknown_thread` (404). A turn
195
+ * typed in the app is ask({ sessionId }); a Stop is stopRequest(request.id);
196
+ * a question is answer(request.id, …) (0.8.1), a yes is the press frame
197
+ * (approval(request.id)); only what `needs.in_app` leaves null goes to the
198
+ * desk (openRequest).
199
+ *
200
+ * With `view: true` (0.8.1, D27: the `agent-pane` block) the answer also
201
+ * carries `view`, the thread as the desk's sidebar draws it:
202
+ *
203
+ * view: { messages: [{ id, role: "user", text, files } |
204
+ * { id, role: "assistant", live, blocks }],
205
+ * thinking, failure: { kind, words } | null,
206
+ * questions: [{ id, prompt, options, free }] }
207
+ *
208
+ * `blocks` are the sidebar's own: text, plan, work (steps folded into
209
+ * "Worked through N steps", reads folded, retries fixed, helpers), approval,
210
+ * receipt, app, made, file, authorization. A step opens with threadCall().
211
+ * A claw from before `thread_view` ignores the flag and sends no `view`.
212
+ */
213
+ export function thread(sessionId, { signal, view = false } = {}) {
214
+ return claw(`threads/${encodeURIComponent(String(sessionId ?? ""))}${view ? "?view=1" : ""}`, { signal });
215
+ }
216
+
217
+ /**
218
+ * GET _claw/threads/<session>/calls/<call> → { ok, call }: one step of the
219
+ * member's own thread, opened (0.8.1, D27; the `agent-pane` block). The
220
+ * digest the desk's sidebar shows under a line, bounded, never the raw
221
+ * input or output:
222
+ *
223
+ * { id, line, status, reason, said,
224
+ * facts: [{ label, value }], code: { label, text } | null, result }
225
+ *
226
+ * Refusals: `not_your_thread` (403), `unknown_thread` (404),
227
+ * `unknown_call` (404). A claw from before the door answers 404 with no
228
+ * `code` (`unavailable`).
229
+ */
230
+ export function threadCall(sessionId, callId, { signal } = {}) {
231
+ const session = segment(sessionId);
232
+ const call = segment(callId);
233
+ if (!session || !call) return noId("step");
234
+ return claw(`threads/${session}/calls/${call}`, { signal });
235
+ }
236
+
237
+ /**
238
+ * GET _claw/threads/<session>/stream → the thread, pushed as the agent
239
+ * writes (0.8.1, D27 phase 4: "live streaming of the turn, not only
240
+ * polling"). `onThread(data)` gets the same object `thread(session, { view:
241
+ * true })` answers, after each burst of the agent's events (no legacy
242
+ * `turns`); `onLine()` hears every line, a ping included, as proof the
243
+ * stream is alive. Resolves when it ends: { ok: true, reason } with the
244
+ * server's reason (`settled` the turn is over, `max` open another, `gone`,
245
+ * `closed` eve's stream broke), or a refusal like claw()'s (`unavailable`
246
+ * for a claw with no stream: keep polling). Aborting resolves `aborted`.
247
+ * `/me` says `thread_stream: 1` where it exists.
248
+ */
249
+ export async function streamThread(sessionId, { onThread, onLine, signal } = {}) {
250
+ const session = segment(sessionId);
251
+ if (!session) return noId("thread");
252
+ let reason = "closed";
253
+ const r = await clawNdjson(
254
+ `threads/${session}/stream`,
255
+ (line) => {
256
+ onLine?.(line);
257
+ if (line.type === "thread" && line.data && typeof line.data === "object") onThread?.(line.data);
258
+ else if (line.type === "end" && typeof line.reason === "string") reason = line.reason;
259
+ },
260
+ { signal },
261
+ );
262
+ return r.ok ? { ok: true, status: r.status, reason } : r;
263
+ }
264
+
265
+ /**
266
+ * GET _claw/requests/<id>/approval → the facts of a yes that waits on this
267
+ * member, in the SERVER's words, and the address of the press frame
268
+ * (0.8.1; the `approval` block, useApproval):
269
+ *
270
+ * { ok: true,
271
+ * approval: { request_id,
272
+ * question, the agent's one question, as the server holds it
273
+ * label, the Approve button's words ("Send 50")
274
+ * covers, { to: { label, count }, from, then, first:
275
+ * { to, subject, body }, more, more_note } | null
276
+ * always, the rule "Always allow this kind" would save,
277
+ * in words, or null when it is not offered
278
+ * cap_credits, at, the request's spend cap; the version
279
+ * of the question this card is for
280
+ * frame: { src, origin }, the page to embed
281
+ * expires_at },
282
+ * desk_origin }
283
+ *
284
+ * This call approves nothing. The press is the frame's: a page of
285
+ * Makersclaw's, in another origin, that app code cannot script, which
286
+ * shows these words and only counts a press a person made on a card they
287
+ * can see. Refusals: `not_your_request` (403, a teammate's: only the
288
+ * member who asked gives the yes), `unknown_request` (404),
289
+ * `nothing_to_approve` (409, it is not waiting on a yes any more),
290
+ * `not_one_yes` (409, several asks wait: the desk).
291
+ */
292
+ export function approval(id, { signal } = {}) {
293
+ const which = segment(id);
294
+ if (!which) return noId("request");
295
+ return claw(`requests/${which}/approval`, { signal });
296
+ }
297
+
298
+ /**
299
+ * POST _claw/requests/<id>/answer → { ok, request }: the agent's question,
300
+ * answered where it was asked (0.8.1, D19). `optionId` is one of the
301
+ * question's options, or `text` is the member's own words where it
302
+ * welcomes them (`needs.free`); never both. `at` is the question's `at`
303
+ * from the thread: an answer to one that has moved on is refused
304
+ * (`moved_on`, 409). The same checks as the desk's form: the member who
305
+ * asked, this app's request only. Refusals carry a `code`:
306
+ * `not_your_request` (403), `needs_a_press` (403: a YES is never an
307
+ * answer; embed the `approval` block), `answer_required`,
308
+ * `either_option_or_text`, `unknown_option`, `no_free_text`,
309
+ * `text_too_long` (400), `many_questions` (409: answer on the desk),
310
+ * `moved_on` (409), `no_credits`/`member_cap` (402).
311
+ */
312
+ export function answer(id, { optionId, text, at, answers } = {}) {
313
+ const which = segment(id);
314
+ if (!which) return noId("request");
315
+ // Several questions at once (0.8.1, D27: the sidebar's form): `answers`
316
+ // is [{ requestId, optionId | text }], one per question the view lists,
317
+ // sent as one resume. The door checks each against the session's own log.
318
+ if (Array.isArray(answers)) {
319
+ return claw(`requests/${which}/answer`, {
320
+ method: "POST",
321
+ body: {
322
+ answers: answers.map((a) => ({
323
+ request_id: a?.requestId,
324
+ option_id: typeof a?.optionId === "string" && a.optionId ? a.optionId : undefined,
325
+ text: typeof a?.text === "string" && a.text !== "" ? a.text : undefined,
326
+ })),
327
+ at: typeof at === "string" && at ? at : undefined,
328
+ },
329
+ });
330
+ }
331
+ return claw(`requests/${which}/answer`, {
332
+ method: "POST",
333
+ body: {
334
+ option_id: typeof optionId === "string" && optionId ? optionId : undefined,
335
+ text: typeof text === "string" && text !== "" ? text : undefined,
336
+ at: typeof at === "string" && at ? at : undefined,
337
+ },
338
+ });
124
339
  }
125
340
 
126
341
  /**
@@ -209,9 +424,34 @@ export function cancelJob(sessionId) {
209
424
  * Nothing throws. An empty input asks nothing of the platform.
210
425
  */
211
426
  export async function llm(input, opts) {
212
- const { system, schema, maxTokens, tier, task, signal } = opts ?? {};
213
- const said = typeof input === "string" ? input.trim() !== "" : Array.isArray(input) && input.length > 0;
214
- if (!said) return refused("nothing to send");
427
+ const body = llmBody(input, opts);
428
+ if (body.refused) return body.refused;
429
+ return llmAnswer(await claw("llm", { method: "POST", body, signal: opts?.signal }));
430
+ }
431
+
432
+ /**
433
+ * What a model call would cost, before it is made (0.8.1, the kit): POST
434
+ * _claw/llm with `estimate: true` and llm()'s arguments. The platform runs
435
+ * every check a call would (the origin, the member, the size, the input)
436
+ * and answers the price — never sending anything to a model, never
437
+ * charging. Put it on the control that spends ("Shorter · 1 cr"; the
438
+ * `cost` block's CostTag); useLlmAction fetches it for you.
439
+ *
440
+ * → { ok: true, estimate: { credits, credits_max } } credits to a tenth
441
+ * a refusal, as llm()'s (an empty input asks nothing of the platform)
442
+ * { ok: false, unavailable: true } a claw with no estimate yet
443
+ */
444
+ export async function llmEstimate(input, opts) {
445
+ const body = llmBody(input, opts);
446
+ if (body.refused) return body.refused;
447
+ return llmAnswer(await claw("llm", { method: "POST", body: { ...body, estimate: true }, signal: opts?.signal }));
448
+ }
449
+
450
+ /** llm()'s body from its arguments, or `{ refused }` for one it will not
451
+ * send. */
452
+ function llmBody(input, opts) {
453
+ const { system, schema, maxTokens, tier, task } = opts ?? {};
454
+ if (!saidSomething(input)) return { refused: refused("nothing to send") };
215
455
  const body = {
216
456
  input,
217
457
  system: typeof system === "string" && system ? system : undefined,
@@ -224,9 +464,19 @@ export async function llm(input, opts) {
224
464
  try {
225
465
  JSON.stringify(body);
226
466
  } catch {
227
- return refused("that cannot be sent as JSON");
467
+ return { refused: refused("that cannot be sent as JSON") };
228
468
  }
229
- const r = await claw("llm", { method: "POST", body, signal });
469
+ return body;
470
+ }
471
+
472
+ /** Is there anything to send: a string with words, or a conversation? */
473
+ export function saidSomething(input) {
474
+ return typeof input === "string" ? input.trim() !== "" : Array.isArray(input) && input.length > 0;
475
+ }
476
+
477
+ /** The model door's answer as it is, or a refusal for one that is not
478
+ * the door's. */
479
+ function llmAnswer(r) {
230
480
  if (!r.ok) return r;
231
481
  const answer = r.data;
232
482
  if (answer && typeof answer === "object" && !Array.isArray(answer) && typeof answer.ok === "boolean") return answer;
@@ -239,8 +489,266 @@ function refused(error) {
239
489
  return { ok: false, status: 0, error, code: "bad_input", unavailable: false };
240
490
  }
241
491
 
242
- export { reportError };
492
+ /** A query string from [name, value] pairs: the ones with a value only,
493
+ * names and values encoded, "" when none. A string is trimmed and an
494
+ * empty one is no value; a number or a boolean is sent as its text;
495
+ * anything else (null, an object) is left out. */
496
+ function queryOf(pairs) {
497
+ const parts = [];
498
+ for (const [name, value] of pairs) {
499
+ const text = typeof value === "string" ? value.trim() : typeof value === "number" || typeof value === "boolean" ? String(value) : "";
500
+ if (text) parts.push(`${encodeURIComponent(name)}=${encodeURIComponent(text)}`);
501
+ }
502
+ return parts.length ? `?${parts.join("&")}` : "";
503
+ }
504
+
505
+ /** A page's size when it is a whole number of 1 or more, else none: the
506
+ * platform cuts it to what a page may be (60 items, 100 rows). */
507
+ const pageSize = (limit) => (Number.isInteger(limit) && limit >= 1 ? limit : undefined);
508
+
509
+ /** One path segment from a collection's slug or an item's id, or null for
510
+ * an id that names nothing. */
511
+ function segment(id) {
512
+ const text = typeof id === "string" || typeof id === "number" ? String(id).trim() : "";
513
+ return text ? encodeURIComponent(text) : null;
514
+ }
515
+
516
+ /** What a library call resolves for an id that names nothing: no request
517
+ * made, and not a missing door. */
518
+ const unnamed = (error) => Promise.resolve({ ok: false, status: 0, error, unavailable: false });
519
+
520
+ /**
521
+ * Show the Library: GET _claw/library/…, read-only, answered for the
522
+ * member who has the app open. The Library is Makersclaw's, not the
523
+ * workspace's: collections of FILES (pitch decks, PDFs, HTML website
524
+ * templates, graphics) and of ROWS (a dataset: investors, growth
525
+ * examples), each on a shelf. Every call resolves { ok, status, data } or
526
+ * { ok: false, status, error, unavailable, code? }, like `me`: nothing
527
+ * throws, and `unavailable: true` is a claw from before the door (render a
528
+ * quiet "not connected yet"). A copy into the workspace is the agent's,
529
+ * through ask(); the door never writes.
530
+ *
531
+ * library.collections({ q, shelf }) → data { collections: [card] }
532
+ * library.collection(id) → data { collection }
533
+ * library.items(id, { q, tag, cursor, limit })
534
+ * → data { items, next_cursor, total, preview_only }
535
+ * library.rows(id, { q, filters, cursor, limit })
536
+ * → data { rows, next_cursor, total, preview_only }
537
+ * library.item(id) → data { item, file_url?, text_excerpt? }
538
+ *
539
+ * A collection's `id` is its slug or its uuid; an item's is its uuid.
540
+ * `shelf` is one of decks, websites, designs, documents, datasets,
541
+ * examples. `filters` is { <column key>: value } for the columns the
542
+ * collection marks as filters (an exact match; for a tags column, has the
543
+ * tag), sent as f.<key>=<value>. `cursor` is the `next_cursor` of the page
544
+ * before, as given. Every call takes `signal`, an AbortSignal, among its
545
+ * options (the last argument).
546
+ *
547
+ * A paid collection on a Free plan answers `preview_only: true`, with its
548
+ * first few items or rows and the true `total`; an item past the preview
549
+ * is not listed, and library.item(id) on it is a 403 with `code:
550
+ * "needs_plan"`. `file_url` is a signed address, good for ten minutes:
551
+ * show or download from it at once, and never keep it. `preview_url` and
552
+ * `cover_url` are plain pictures that stay. An id that names nothing asks
553
+ * nothing of the platform.
554
+ */
555
+ export const library = {
556
+ collections(opts) {
557
+ const { q, shelf, signal } = opts ?? {};
558
+ return claw(`library/collections${queryOf([["q", q], ["shelf", shelf]])}`, { signal });
559
+ },
560
+ collection(id, opts) {
561
+ const slug = segment(id);
562
+ if (!slug) return unnamed("no collection named");
563
+ return claw(`library/collections/${slug}`, { signal: opts?.signal });
564
+ },
565
+ items(id, opts) {
566
+ const slug = segment(id);
567
+ if (!slug) return unnamed("no collection named");
568
+ const { q, tag, cursor, limit, signal } = opts ?? {};
569
+ const query = queryOf([["q", q], ["tag", tag], ["cursor", cursor], ["limit", pageSize(limit)]]);
570
+ return claw(`library/collections/${slug}/items${query}`, { signal });
571
+ },
572
+ rows(id, opts) {
573
+ const slug = segment(id);
574
+ if (!slug) return unnamed("no collection named");
575
+ const { q, filters, cursor, limit, signal } = opts ?? {};
576
+ const filtered = filters && typeof filters === "object" && !Array.isArray(filters) ? Object.entries(filters) : [];
577
+ const query = queryOf([["q", q], ...filtered.map(([key, value]) => [`f.${key}`, value]), ["cursor", cursor], ["limit", pageSize(limit)]]);
578
+ return claw(`library/collections/${slug}/rows${query}`, { signal });
579
+ },
580
+ item(id, opts) {
581
+ const item = segment(id);
582
+ if (!item) return unnamed("no item named");
583
+ return claw(`library/items/${item}`, { signal: opts?.signal });
584
+ },
585
+ };
586
+
587
+ // ---------------------------------------------------------------------------
588
+ // The kit (0.8.1, D15): the app's jobs, runs, activity, accounts and agent
589
+
590
+ /** What a kit call resolves for an id that names nothing: no request
591
+ * made, and not a missing door. */
592
+ const noId = (what) => Promise.resolve({ ok: false, status: 0, error: `no ${what} named`, unavailable: false });
593
+
594
+ /**
595
+ * GET _claw/jobs → the app's declared jobs (its wakes), as the
596
+ * `schedule-card` and `workflow-view` blocks draw them:
597
+ *
598
+ * { app: { status, live }, live: the app is running (not paused)
599
+ * jobs: [{ id, name, kind, topic, does, cron, tz,
600
+ * words, "Weekdays at 07:00", or null
601
+ * enabled, next_run_at, last_run_at,
602
+ * last_run: { id, status, ended_at } | null,
603
+ * plan }], the job's declared steps, or null
604
+ * budget: { week_cap_credits, week_used_credits } | null,
605
+ * credits, _claw/me's credits, as is, or null
606
+ * may: { run, switch, pause } } what this member may press
607
+ *
608
+ * `may` is the door's word, not a guess: owner, admin or the app's owner.
609
+ * Hide a control the member may not press; the door refuses it anyway.
610
+ */
611
+ export function jobs({ signal } = {}) {
612
+ return claw("jobs", { signal });
613
+ }
614
+
615
+ /** PATCH _claw/jobs/<id> { enabled } → { ok, job }: switch one job on or
616
+ * off. Refusals: `not_allowed` (403, below the bar), `unknown_job` (404),
617
+ * 409 when the job may not go live (an unlaunched app's). */
618
+ export function setJob(id, { enabled } = {}) {
619
+ const job = segment(id);
620
+ if (!job) return noId("job");
621
+ return claw(`jobs/${job}`, { method: "PATCH", body: { enabled: Boolean(enabled) } });
622
+ }
623
+
624
+ /** POST _claw/run { wake_id } → { ok, run_id, wake }: run one job now,
625
+ * on the member's press. Spends: say its price on the control. 403 below
626
+ * the bar. */
627
+ export function runNow(wakeId) {
628
+ const wake = typeof wakeId === "string" || typeof wakeId === "number" ? String(wakeId).trim() : "";
629
+ if (!wake) return noId("job");
630
+ return claw("run", { method: "POST", body: { wake_id: wake } });
631
+ }
632
+
633
+ /** POST _claw/pause → { status }: the app's Live switch off. Its jobs
634
+ * stop firing until it is resumed. */
635
+ export function pauseApp() {
636
+ return claw("pause", { method: "POST", body: {} });
637
+ }
638
+
639
+ /** POST _claw/resume → { status }: the app's Live switch on again. */
640
+ export function resumeApp() {
641
+ return claw("resume", { method: "POST", body: {} });
642
+ }
643
+
644
+ /**
645
+ * GET _claw/runs → the app's runs, newest first, and their overview:
646
+ *
647
+ * { runs: [{ id, title, status, started_at, ended_at, report,
648
+ * state, running | done | failed | stopped | needs_you
649
+ * wake_id, job, the job's id and name, or null for an ask
650
+ * trigger, schedule | manual | event | ask
651
+ * by, who pressed Run now, when manual
652
+ * number, 1-based, the oldest is 1
653
+ * duration_ms, credits }],
654
+ * overview: { completed, failed, running, avg_ms, credits_week, cap_week_credits } }
655
+ *
656
+ * `job` narrows to one job (its wake id), `limit` to that many (at most
657
+ * 60). Only the jobs' runs and the member's own asks: never a
658
+ * teammate's ask.
659
+ */
660
+ export function runs({ job, limit, signal } = {}) {
661
+ return claw(`runs${queryOf([["job", job], ["limit", pageSize(limit)]])}`, { signal });
662
+ }
663
+
664
+ /** GET _claw/runs/<id> → { run, steps: [{ label, status }], text, needs }:
665
+ * one run's account — its steps, the agent's report, and what it waits
666
+ * on (answered on the desk). 404 `unknown_run` for another app's run or
667
+ * a teammate's ask. */
668
+ export function run(id, { signal } = {}) {
669
+ const which = segment(id);
670
+ if (!which) return noId("run");
671
+ return claw(`runs/${which}`, { signal });
672
+ }
673
+
674
+ /** GET _claw/data/activity → { rows }: who did what in this app, newest
675
+ * first. Rows: { id, at, action, surface, row_ref, detail, data, by };
676
+ * `by` is `user:<email>`, `agent:<email>` (the agent on a member's ask)
677
+ * or `agent:job` (on a run). `row` narrows to one record's lines (its
678
+ * row_ref), `surface` to one surface, `since` (ISO or a Date) to lines
679
+ * after it, `limit` 100 (at most 1,000). lib/door.js's loadActivity reads
680
+ * the same lines once; this is the kit's, followed by useActivity in
681
+ * lib/hooks.js. */
682
+ export function activity({ row, surface, since, limit, signal } = {}) {
683
+ const after = since instanceof Date ? (Number.isNaN(since.getTime()) ? undefined : since.toISOString()) : since;
684
+ const query = queryOf([["row", row], ["surface", surface], ["since", after], ["limit", pageSize(limit)]]);
685
+ return claw(`data/activity${query}`, { signal });
686
+ }
687
+
688
+ /** GET _claw/connect → { connections: [{ key, label, toolkits, required,
689
+ * connected, accounts, category, category_label }], desk_url }: the
690
+ * accounts the app declares, each with whether it is connected now and
691
+ * the labels of the accounts that meet it. A read: nothing is minted. */
692
+ export function connections({ signal } = {}) {
693
+ return claw("connect", { signal });
694
+ }
695
+
696
+ /** POST _claw/connect { key } → { ok, key, label, toolkit, connected, url }:
697
+ * the link a member opens, in a new tab, to connect one declared account
698
+ * outside the desk. Connected already: no link (`url: null`). Inside the
699
+ * desk ask it instead (openConnections, lib/claw.js): its panel lists
700
+ * every provider of the kind. useConnections chooses for you. */
701
+ export function connectLink(key, { signal } = {}) {
702
+ const need = typeof key === "string" ? key.trim() : "";
703
+ if (!need) return noId("account");
704
+ return claw("connect", { method: "POST", body: { key: need }, signal });
705
+ }
706
+
707
+ /** GET _claw/agent → what the app's agent is: { model, brief, schedule,
708
+ * connections, skills: [{ name, installed }] (added on top),
709
+ * own_skills: [{ name, title, when }] (the app's references),
710
+ * actions: [{ name, description, agent }] (the declared actions: its
711
+ * tools) }. Read by any member; adding a skill stays in the window's
712
+ * Settings › Skills. */
713
+ export function agentKit({ signal } = {}) {
714
+ return claw("agent", { signal });
715
+ }
716
+
717
+ export { openApp, openConnections, openFile, reportError };
243
718
 
244
- export const platform = { me, ask, llm, requests, stopRequest, openRequest, surfaceOfPath, startJob, cancelJob, reportError };
719
+ export const platform = {
720
+ me,
721
+ ask,
722
+ llm,
723
+ library,
724
+ requests,
725
+ stopRequest,
726
+ openRequest,
727
+ threads,
728
+ thread,
729
+ threadCall,
730
+ streamThread,
731
+ approval,
732
+ answer,
733
+ surfaceOfPath,
734
+ startJob,
735
+ cancelJob,
736
+ reportError,
737
+ jobs,
738
+ setJob,
739
+ runNow,
740
+ pauseApp,
741
+ resumeApp,
742
+ runs,
743
+ run,
744
+ activity,
745
+ connections,
746
+ connectLink,
747
+ openConnections,
748
+ openApp,
749
+ openFile,
750
+ agentKit,
751
+ llmEstimate,
752
+ };
245
753
 
246
754
  export default platform;
@@ -20,6 +20,8 @@
20
20
  "components/ui/*",
21
21
  "components/parts/*",
22
22
  "check/run.mjs",
23
+ "check/automation-format.ts",
24
+ "check/automation-package.ts",
23
25
  "proxy.js",
24
26
  "next.config.mjs",
25
27
  "postcss.config.mjs"
@@ -56,8 +58,8 @@
56
58
  {
57
59
  "name": "notice",
58
60
  "type": "component",
59
- "title": "Card, Notice, Badge, Kicker, Empty",
60
- "description": "Containers and signals: Card (padding md · sm · none; titleSize md · lg), Notice (tone neutral · info · success · warning · danger), Badge (tone neutral · primary · success · warning · danger · info; variant label — small caps · soft — sentence case, every tone tinted, primary included · outline — sentence case, a hairline on no fill · code — the mono face in its own case for a version tag or a commit hash; hue 1..5 a categorical colour from --color-chart-N for kinds of things, never status: soft a hue tint with a hue dot, label filled, outline a hue hairline, the text always readable), Kicker (the small line above a heading), Empty (a search or filter with no matches).",
61
+ "title": "Card, ActionCard, Notice, Badge, Kicker, Empty",
62
+ "description": "Containers and signals: Card (padding md · sm · none; titleSize md · lg), ActionCard (one step: icon, title, description, status {tone, children} above one full-width action; stacked, never stretched to a neighbour), Notice (tone neutral · info · success · warning · danger), Badge (tone neutral · primary · success · warning · danger · info; variant label — small caps · soft — sentence case, every tone tinted, primary included · outline — sentence case, a hairline on no fill · code — the mono face in its own case for a version tag or a commit hash; hue 1..5 a categorical colour from --color-chart-N for kinds of things, never status: soft a hue tint with a hue dot, label filled, outline a hue hairline, the text always readable), Kicker (the small line above a heading), Empty (a search or filter with no matches).",
61
63
  "tags": ["card", "alert", "notice", "badge", "empty state", "status"],
62
64
  "files": ["components/ui/notice.jsx"]
63
65
  },
@@ -337,10 +339,18 @@
337
339
  "name": "layout",
338
340
  "type": "component",
339
341
  "title": "AppLayout, DocumentLayout",
340
- "description": "Who owns the window's height, and who scrolls. AppLayout is the app frame, the one viewport owner (the outermost; one inside another fills its slot instead): header (the top bar, in view), navigation (a rail from md, navigationWidth px, 176; below md a Sheet behind the menu button, navigationLabel), the content (contentMode scroll: its region scrolls · fill: a bounded column for a canvas or a grid that scrolls itself; contentLabel, contentClassName for spacing, scrollKey = the route to scroll back to the top), inspector (beside the content from inspectorAt md · lg · xl, inspectorWidth px, 360, 240 to 560; below it the content and the inspector share one scroll in scroll mode, and in fill mode the inspector is a bounded pane under the content), footer (under the content, in view), height viewport · parent. In print it lets go. DocumentLayout is a page that flows, for print and export: toolbar (held at the top, never printed), width prose · page (A4) · letter · full, paper, align start · center. Nothing in an app sizes itself by the window: npm run check refuses min-h-dvh, h-screen, 100vh and h-[80vh] outside the kit.",
342
+ "description": "Who owns the window's height, and who scrolls. AppLayout is the app frame, the one viewport owner (the outermost; one inside another fills its slot instead): header (the top bar, in view), navigation (a rail from md, navigationWidth px, 176; below md a Sheet behind the menu button, navigationLabel), the content (contentMode scroll: its region scrolls · fill: a bounded column for a canvas or a grid that scrolls itself; contentLabel, contentClassName for spacing, scrollKey = the route to scroll back to the top), inspector (beside the content from inspectorAt md · lg · xl of the window's width, or with inspectorIn frame of the body's own width between the rail and the dock: 42, 48, 64 rem; inspectorWidth px, 360, 240 to 560; below it the content and the inspector share one scroll in scroll mode, and in fill mode the inspector is a bounded pane under the content), footer (under the content, in view), height viewport · parent. In print it lets go. DocumentLayout is a page that flows, for print and export: toolbar (held at the top, never printed), width prose · page (A4) · letter · full, paper, align start · center. Nothing in an app sizes itself by the window: npm run check refuses min-h-dvh, h-screen, 100vh and h-[80vh] outside the kit.",
341
343
  "tags": ["layout", "app frame", "shell", "viewport", "scroll", "inspector", "sidebar", "navigation", "footer", "fill", "canvas", "document", "print", "export", "page"],
342
344
  "files": ["components/ui/layout.jsx"]
343
345
  },
346
+ {
347
+ "name": "page-layout",
348
+ "type": "component",
349
+ "title": "PageLayout",
350
+ "description": "A screen's main area with an optional side column, taking the full height of the content it sits in (inside an AppLayout, ideally contentMode fill with no padding on the content). The main is the column that scrolls; the side is the fixed one, holding its place with its divider running top to bottom, and it is short (a summary, the next step, a few facts, a small panel; never a long form or a long list, which belong in the main). side (the side column), sideWidth px (304, 220 to 560), sideAt md · lg · xl (the page's own width from which the side sits beside the main: 42, 48, 64 rem; a measure of the page, not the window, so an open agent dock does not squeeze it; narrower, the side goes under the main in one scroll), mainLabel and sideLabel (names for a screen reader), padded (p-4 sm:p-6 on the main, p-4 on the side), fill (the main is a flex column, so a child with flex-1 grows into the height), className, mainClassName, sideClassName (spacing and tokens, never a height). Screens use it instead of a hand-drawn grid with a ruled aside, which is only as tall as its words: npm run check refuses that (rule page), and refuses a side column that holds a form or a long list (rule sidelong).",
351
+ "tags": ["page layout", "side column", "two column", "main and side", "split", "height", "fill", "scroll", "divider", "inspector", "aside", "master detail", "layout"],
352
+ "files": ["components/ui/page.jsx"]
353
+ },
344
354
  {
345
355
  "name": "toast",
346
356
  "type": "component",