makersclaw 0.8.0 → 0.8.2

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 +234 -0
  143. package/registry/blocks/agent-pane/agent-pane.jsx +246 -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 +1677 -8
  400. package/templates/next/files/lib/platform.js +529 -21
  401. package/templates/next/template.json +13 -3
@@ -99,7 +99,7 @@ lib/brain.js the company brain from the browser, in both modes; its ho
99
99
  lib/brain-server.js the brain's reads for a server component — a server app's
100
100
  lib/claw.js the _claw API the gateway answers, from the browser
101
101
  lib/platform.js typed wrappers over lib/claw.js (Platform)
102
- lib/hooks.js the React hooks over them: useJob, useLlm, useArtifact… (Hooks)
102
+ lib/hooks.js the React hooks over them: useJob, useLlm, useLibraryItems, useArtifact… (Hooks)
103
103
  lib/sample.js markSample, for sample rows (§3a)
104
104
  ```
105
105
 
@@ -255,7 +255,7 @@ import { Button, IconButton, ButtonGroup, ButtonGroupSeparator, Toggle, ToggleGr
255
255
  InputGroup, PasswordInput, InputOTP, Slider, Image, FileInput, FileDrop, fileMatches, Combobox, Command, CommandDialog, Calendar, DatePicker, DateInput, DATE_PRESETS,
256
256
  parseDate, isDateString, toDateString, todayString, addDays, addMonths,
257
257
  startOfMonth, endOfMonth, dayOfWeek, formatDate, toLocalDate, firstDayOfWeek,
258
- Card, Notice, Badge, Kicker, Empty, Item, ItemGroup, Avatar, AvatarGroup,
258
+ Card, ActionCard, Notice, Badge, Kicker, Empty, Item, ItemGroup, Avatar, AvatarGroup,
259
259
  Sheet, Confirm, Tabs, TabPanel, Menu, ContextMenu, Popover, Tooltip, HoverCard,
260
260
  Breadcrumb, Pagination, Collapsible, Accordion, Carousel, ScrollArea,
261
261
  ResizablePanelGroup, ResizablePanel, ResizableHandle,
@@ -263,7 +263,7 @@ import { Button, IconButton, ButtonGroup, ButtonGroupSeparator, Toggle, ToggleGr
263
263
  Spinner, Skeleton, Progress, Separator, Kbd, KbdGroup, AspectRatio,
264
264
  Stat, StatGroup, Delta, StatusDot, Legend, Meter, Distribution, Swatch, Steps,
265
265
  toast, Toaster, Depiction, Icon, ICON_NAMES, usePopoverPosition, panelClass, cx,
266
- AppLayout, DocumentLayout }
266
+ AppLayout, DocumentLayout, PageLayout }
267
267
  from "../components/ui"; // "./ui" from a component
268
268
  import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNotice, isSample,
269
269
  Examples, useExamples } from "../components/parts";
@@ -289,8 +289,12 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
289
289
  spreadsheet), `contentLabel`, `contentClassName` (spacing and token
290
290
  backgrounds only) and `scrollKey` (pass the route: when it changes the
291
291
  content scrolls back to its top and the drawer closes) · `inspector`
292
- (beside the content from `inspectorAt` md · lg · xl, lg by default;
293
- `inspectorWidth` px, 360 by default, 240 to 560; `inspectorLabel`) ·
292
+ (beside the content from `inspectorAt` md · lg · xl, lg by default, of
293
+ the window's width; `inspectorIn="frame"` counts the body between the
294
+ rail and the dock instead, 42 · 48 · 64 rem, so an agent dock that
295
+ takes a quarter of the window sends the inspector under the work
296
+ rather than squeezing it; `inspectorWidth` px, 360 by default, 240 to
297
+ 560; `inspectorLabel`) ·
294
298
  `footer` (under the content, in view) · `height` viewport · parent.
295
299
  Below `inspectorAt` there is no room for two columns: in `scroll` mode
296
300
  the content and the inspector share one scroll, the inspector after
@@ -320,6 +324,56 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
320
324
  navigation, header, inspector or footer) and the document flows onto
321
325
  pages. Inside either, bound a box by its parent (`h-full`, `flex-1
322
326
  min-h-0`) or by a size (`max-h-96`, `ScrollArea`), never by the window.
327
+
328
+ `PageLayout` is a screen's main area with an optional side column,
329
+ full height. The main is the column that scrolls; the side is the fixed
330
+ one. Roadmap's Today ended at
331
+ 680px in a 1240px window because it drew its own two-column grid
332
+ inside the scrolling content: only as tall as its words, the side's
333
+ divider stopped halfway and the bottom of the window was empty. Put it
334
+ inside an `AppLayout` with `contentMode="fill"` and no padding on the
335
+ content; the columns pad themselves, so the divider runs to the edges.
336
+ `side` (the side column) · `sideWidth` px (304; 220 to 560) · `sideAt`
337
+ md · lg · xl (the page's own width from which the side sits beside the
338
+ main, 42 · 48 · 64 rem: a measure of the page, so an open agent dock
339
+ does not squeeze it; narrower, the side goes under the main in one
340
+ scroll) · `mainLabel`, `sideLabel` · `padded` · `fill` (the main is a
341
+ flex column, so a child with `flex-1` grows into the height) ·
342
+ `className`, `mainClassName`, `sideClassName` (spacing, never a height).
343
+ `npm run check` refuses a screen that draws its own main + side
344
+ (`grid-cols-[minmax(0,1fr)_19rem]` and a ruled `<aside>`, rule `page`).
345
+
346
+ **What belongs in the side, and what never does** (the founder, looking
347
+ at a first run that was a short intro on the left and a long "Name it"
348
+ form in the right column: "this can only work if one column is fixed,
349
+ usually the 3rd column, and the middle one is scrolling"). The side is
350
+ the fixed column: it stays put while the main scrolls, so it is short
351
+ and never needs a scroll of its own.
352
+ - In the side: a summary, the next step, a few facts about the record,
353
+ a small panel (an allowance, "needs you" with a few lines), a short
354
+ list that says its bound (`items.slice(0, 5)` and "and 3 more").
355
+ - Never in the side: a form (`<form`, several `Field` or `Input`, a
356
+ `Textarea`, a paste box), a list that grows with the data, a shelf of
357
+ examples. They go in the main, where the page scrolls. A "Name it" or
358
+ "Paste a list" step that opens reveals its own card in the main flow;
359
+ it does not open a form in the side.
360
+ - The side's own scroll (thin) is a last resort for a window shorter
361
+ than the side. It is not how anything is meant to be read.
362
+ - Narrower than `sideAt`, the side goes under the main in one scroll.
363
+ `npm run check` rule `sidelong` refuses a `side` or an `<aside>` that
364
+ holds a form, a `Textarea`, three or more fields, or a `.map(` of data
365
+ that is not bounded by a `.slice(`. It reads the side's own markup and
366
+ the components defined in the app that the side draws (three levels
367
+ deep). It cannot see a block or kit component's insides, content that
368
+ arrives from props or context, or how long a list really is at run time;
369
+ the docs and review carry those. A screen:
370
+ ```jsx
371
+ <AppLayout header={<TopBar crumb={crumb} />} contentMode="fill">
372
+ <PageLayout side={<Projects />} fill>
373
+ <NeedsALook />
374
+ </PageLayout>
375
+ </AppLayout>
376
+ ```
323
377
  - `Button` — `variant` primary (one per surface, in the app's accent —
324
378
  say it: a Button with no `variant` is secondary) · secondary · quiet ·
325
379
  danger · link (inline text: no padding or height, wraps and truncates
@@ -427,6 +481,14 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
427
481
  — a table that scrolls inside itself on a phone.
428
482
  - `Card` (`padding` md · sm · none — none for a table or rows that run
429
483
  to the border, never `p-0!`; `titleSize` md · lg for a 20px title),
484
+ `ActionCard` (one step the member takes: `icon`, `title`,
485
+ `description`, `children`, `status` = `{ tone, children }` above the
486
+ one full-width `action`; in a row it stretches to the row's height and
487
+ pins its status and action to the bottom, so the buttons line up (`fit`
488
+ is the old only-as-tall-as-its-words, for one lone card; never
489
+ `self-start` on a card in a row) — a connect-and-first-read card, "Add one person", "Bring in a
490
+ file". A screen's boxes are Card, ActionCard or Notice, never a
491
+ hand-drawn bordered div),
430
492
  `Notice` (tone neutral · info · success · warning · danger),
431
493
  `Badge` (tone neutral · primary · success · warning · danger · info;
432
494
  `variant` label — small caps · soft — the case as written, every tone
@@ -453,7 +515,9 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
453
515
  `Meter value max unit target thresholds` (a role=meter; over the limit
454
516
  turns danger; `direction` higher · lower picks the tone against the
455
517
  target; `valueTone`; `targetMark={false}`; tone `muted` for a plain
456
- grey share) — numbers and states, never a hand-drawn tile or bar.
518
+ grey share; `compact` the bar (or ring) alone, its label and numbers
519
+ kept for screen readers and as the tooltip — a labelled Meter in a box of
520
+ 8rem or less must be `compact`) — numbers and states, never a hand-drawn tile or bar.
457
521
  `Delta hideValue` is the arrow alone; `StatusDot` and Legend items take
458
522
  `hue` (1..5) for a category. `Distribution segments={[{ label, value,
459
523
  tone, hue }]} legend label size` (thin · md) — parts of one whole as
@@ -1048,6 +1112,130 @@ the check refuses a raw `INSERT INTO` anywhere outside `lib/`, and, in
1048
1112
  an app on its own tables, any SQL that writes in the app's code (§6,
1049
1113
  `agent`).
1050
1114
 
1115
+ ### Declared actions — `makersclaw.json` `actions` (0.8.1)
1116
+
1117
+ Every write a screen makes is a declared action: the screens call it by
1118
+ name with `runAction({ name, args })`, and the app's agent calls the same
1119
+ name as one of its tools, run by the platform's one runner. Once an app
1120
+ declares any, its agent can write no other way, so `npm run check`
1121
+ (§6, `actions`) fails a screen write that is not one: an undeclared
1122
+ name, a one-row write (`insertRow`, `updateRow`, `moveRow`, `deleteRow`,
1123
+ `saveSetting`: make it a function) and a company brain write from
1124
+ `lib/brain.js` (erase, confirm and merge stay a person's press).
1125
+
1126
+ ```json
1127
+ "actions": [
1128
+ {
1129
+ "name": "add_people",
1130
+ "description": "Add up to 100 people, each linked to their company.",
1131
+ "input": {
1132
+ "type": "object",
1133
+ "properties": {
1134
+ "people": {
1135
+ "type": "array", "maxItems": 100,
1136
+ "items": { "type": "object", "properties": {
1137
+ "name": { "type": "string" }, "email": { "type": "string" },
1138
+ "company": { "type": "string" }, "company_domain": { "type": "string" } },
1139
+ "required": ["name"] }
1140
+ },
1141
+ "list_id": { "type": "string" }
1142
+ },
1143
+ "required": ["people"]
1144
+ },
1145
+ "brain": {
1146
+ "each": "people",
1147
+ "writes": [
1148
+ { "as": "company", "kind": "company", "when": "company", "fields": { "name": "company", "domain": "company_domain" } },
1149
+ { "as": "person", "kind": "contact", "fields": { "name": "name", "email": "email", "company_name": "company" } }
1150
+ ],
1151
+ "links": [{ "from": "person", "to": "company", "type": "works_at" }]
1152
+ },
1153
+ "sql": "crm_people_added"
1154
+ },
1155
+ { "name": "make_list", "description": "Make a list of people or companies.",
1156
+ "input": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] },
1157
+ "sql": "crm_make_list" }
1158
+ ]
1159
+ ```
1160
+
1161
+ - `input` is a JSON Schema object (type, properties, required, items,
1162
+ enum, min/max, descriptions); the agent reads it whole, so keep it
1163
+ under 12,000 characters.
1164
+ - `sql` is a function `<name>(args jsonb) returns jsonb` in the app's
1165
+ schema, run as the app, with the member set, after the `brain` steps.
1166
+ - `brain` writes company records as the member and the app: each write
1167
+ is `{ as, kind, fields }`, each field read from an input key (`"name"`:
1168
+ the item's, with `each`; `"$.list_id"`: the input's top level;
1169
+ `{ "value": "lead" }`: a constant). An empty value is left out, never
1170
+ cleared. `when` writes it only when that key has a value; `each` runs
1171
+ the writes once per item of a list of at most 100; `links` join two
1172
+ writes (`from`/`to` an `as`, or `{ "id": <key> }`, a record id the
1173
+ input holds) by a link type the kind declares. Every kind is one the
1174
+ app writes (`brain.writes`), every field one of its fields. The `sql`
1175
+ function gets the input plus `records`: for each `as`, `{ id, created
1176
+ }` (a list in item order with `each`; null where `when` skipped it).
1177
+ If the function refuses, the records the call made are taken back.
1178
+ - A write with `"id"` changes the record that input key names (an edit,
1179
+ never a create), as the member and the app may: one they cannot both
1180
+ read, or of another kind, is not found and nothing is written.
1181
+ `"if_version"` names a key holding the version the screen read
1182
+ (refused `changed` when it moved on); `{ "value": null }` empties a
1183
+ field, and `"clear"` names a key listing fields to empty (an array of
1184
+ strings whose `items.enum` are among the write's fields); `{ "now":
1185
+ true }` is the time of the call. If a later step fails, the fields it
1186
+ changed get their old values back.
1187
+ - A link with `"op": "remove"` takes one off (removals run first, so one
1188
+ call moves a link), and an action may be `links` only, with no
1189
+ `writes`. Archive is an edit of the kind's own field (`archived_at`:
1190
+ `{ "now": true }`, back with `{ "value": null }`); erase and merge stay
1191
+ a person's press, from `lib/brain.js`.
1192
+
1193
+ ```json
1194
+ { "name": "move_deal", "description": "Move a deal to a stage and another company.",
1195
+ "input": { "type": "object", "properties": {
1196
+ "deal_id": { "type": "string" }, "version": { "type": "integer" }, "stage": { "type": "string" },
1197
+ "from_company": { "type": "string" }, "to_company": { "type": "string" } },
1198
+ "required": ["deal_id", "stage"] },
1199
+ "brain": {
1200
+ "writes": [{ "as": "deal", "kind": "deal", "id": "$.deal_id", "if_version": "$.version",
1201
+ "fields": { "stage": "$.stage", "stage_changed_at": { "now": true }, "closed_at": { "value": null } } }],
1202
+ "links": [
1203
+ { "from": "deal", "to": { "id": "$.from_company" }, "type": "for_company", "op": "remove" },
1204
+ { "from": "deal", "to": { "id": "$.to_company" }, "type": "for_company" }] },
1205
+ "sql": "crm_deal_moved" }
1206
+ ```
1207
+
1208
+ - `agent: false` only for a write the agent must never make.
1209
+ - `references/actions.md` says, per action, when and why: never a recipe.
1210
+
1211
+ ### Shipped automations — `makersclaw.json` `automations` (0.8.1)
1212
+
1213
+ An app may ship automations: flows the platform runs for it on a schedule
1214
+ or by hand, made of its own declared actions. List them in
1215
+ `makersclaw.json`, under `automations`, next to `actions`. The store ships
1216
+ the same list as `seeds.automations` in `store.json`.
1217
+
1218
+ - Each entry is a definition in the platform's automation format (format
1219
+ 1: `key`, `name`, `trigger`, `inputs`, `settings`, `steps`), exactly as
1220
+ the automations blocks draw and save one.
1221
+ - An `action` step names one of the app's declared `actions` (its `app`
1222
+ stays out: an app's automation runs its own app's actions).
1223
+ - `replaces_wake` is the one field that is not part of the definition. It
1224
+ is the name of a legacy wake (an older scheduled job of the app, in its
1225
+ `store.json` `seeds.wakes`) that this automation takes over: when the app
1226
+ is installed or updated the wake is switched off, so the job never fires
1227
+ twice. Leave it out for a new automation. Name a scheduled wake (advance
1228
+ or review), never an event wake, and one automation per wake. The
1229
+ app's `store.json` lists the same name.
1230
+ - At most 20 automations, keys unique.
1231
+
1232
+ `npm run check` runs the list through the platform's own validator (rule
1233
+ `automations`), so a flow the platform would refuse at install is refused
1234
+ at build. It checks the shape, the kinds of step, the expressions and that
1235
+ every `action` step names a declared action. Which wakes exist and which
1236
+ kinds of account a `tool` step may ask for are checked where the whole
1237
+ package is known (the store's publish).
1238
+
1051
1239
  ### Door — `lib/door.js` (browser, both modes)
1052
1240
 
1053
1241
  The app's own tables, read and written from the browser through the
@@ -1107,7 +1295,10 @@ whenLanded() resolves once those reads have landed
1107
1295
  Actions did. A slow save never lands after the newer one.
1108
1296
  - A write that answers ok calls `dataChanged()`: every hook on the page
1109
1297
  reads again, the brain's too. When the next step needs the new rows
1110
- (open the row just made), `await whenLanded()` first.
1298
+ (open the row just made), `await whenLanded()` first. Use
1299
+ `afterWrite(write)`: it answers with the write's answer after the hooks
1300
+ hold the new rows; a record page asks `useNotFound(found, { loading })`
1301
+ before it says "not found".
1111
1302
  - `loading` is true until a hook's first answer, and again when its
1112
1303
  options change. A re-read keeps the last rows, and `loading` false,
1113
1304
  until the new ones land; each answer is a new array. A failed re-read
@@ -1334,6 +1525,12 @@ platform.ask({ text, row, how, job, list, surface, sessionId, open })
1334
1525
  POST _claw/ask → { ok, request, desk_origin }, and the column opens on it
1335
1526
  platform.llm(input, { system, schema, maxTokens, tier, task, signal })
1336
1527
  POST _claw/llm → { ok: true, text } | { ok: true, data } | { ok: false, error, code } (Calling a model)
1528
+ platform.library.collections({ q, shelf }) GET _claw/library/collections → { collections } (Showing the Library)
1529
+ platform.library.collection(id) GET _claw/library/collections/<id> → { collection }
1530
+ platform.library.items(id, { q, tag, cursor, limit }) GET _claw/library/collections/<id>/items → { items, next_cursor, total, preview_only }
1531
+ platform.library.rows(id, { q, filters, cursor, limit })
1532
+ GET _claw/library/collections/<id>/rows → { rows, next_cursor, total, preview_only }
1533
+ platform.library.item(id) GET _claw/library/items/<id> → { item, file_url?, text_excerpt? }
1337
1534
  platform.requests() GET _claw/requests → { requests, run, desk_origin }
1338
1535
  platform.requests({ id }) GET _claw/requests?id=<id> → { request }
1339
1536
  platform.stopRequest(id) POST _claw/requests/<id>/stop → { ok, request }
@@ -1342,6 +1539,24 @@ platform.surfaceOfPath(pathname) the <key> of /s/<key> in
1342
1539
  platform.reportError({ message, stack, url, source }) POST _claw/events
1343
1540
  platform.startJob(message, { sessionId, onEvent }) POST _claw/chat → streams session · delta · tool · done · error (legacy)
1344
1541
  platform.cancelJob(sessionId) POST _claw/cancel (legacy)
1542
+
1543
+ // The kit (0.8.1) — what the kit's blocks draw; lib/hooks.js follows each one
1544
+ platform.jobs() GET _claw/jobs → { app: { status, live }, jobs: [{ id, name, kind, topic, does, cron, tz, words,
1545
+ enabled, next_run_at, last_run_at, last_run, plan }], budget, credits, may: { run, switch, pause } }
1546
+ platform.setJob(id, { enabled }) PATCH _claw/jobs/<id> → { ok, job } (not_allowed 403 · unknown_job 404)
1547
+ platform.runNow(wakeId) POST _claw/run → { ok, run_id, wake } (spends: its price on the button)
1548
+ platform.pauseApp() · platform.resumeApp() POST _claw/pause · _claw/resume → { status } (the Live switch)
1549
+ platform.runs({ job, limit }) GET _claw/runs → { runs: [{ id, title, state, wake_id, job, trigger, by, number,
1550
+ started_at, ended_at, duration_ms, credits, report, status }], overview }
1551
+ platform.run(id) GET _claw/runs/<id> → { run, steps: [{ label, status }], text, needs }
1552
+ platform.activity({ row, surface, since, limit }) GET _claw/data/activity → { rows: [{ id, at, action, surface, row_ref, detail, data, by }] }
1553
+ platform.connections() GET _claw/connect → { connections: [{ key, label, required, connected, accounts, category, category_label }] }
1554
+ platform.connectLink(key) POST _claw/connect → { ok, key, label, connected, url } (outside the desk)
1555
+ platform.openConnections(key) ask the desk to open its connections panel for that need → true when the desk was asked
1556
+ platform.agentKit() GET _claw/agent → { own_skills: [{ name, title, when }], skills: [{ name, installed }],
1557
+ actions: [{ name, description, agent }], … }
1558
+ platform.llmEstimate(input, { system, schema, maxTokens, tier, task })
1559
+ POST _claw/llm, estimate: true → { ok: true, estimate: { credits, credits_max } } (never sent to a model, never charged)
1345
1560
  ```
1346
1561
 
1347
1562
  A request, as `ask` and `requests` hand it back: `{ id, title, words,
@@ -1357,16 +1572,32 @@ didnt_finish. `line` is the one line every screen shows for it
1357
1572
  show it as it is, never a status word of your own. `app_session_id` is
1358
1573
  set only on your own requests.
1359
1574
 
1360
- Named exports: `me, ask, llm, requests, stopRequest, openRequest,
1361
- surfaceOfPath, startJob, cancelJob, reportError, platform`. That is the
1362
- whole list. Note what is **not** there: the runs, the chat history, Run
1363
- now, Pause / Resume. Those are MONITORING and they are the OS's — the
1364
- window's tabs and title bar — so an app never calls `_claw/agent`,
1365
- `_claw/runs`, `_claw/run`, `_claw/pause` or `_claw/resume`. Asking is the
1366
- opposite thing, and it belongs here (`ask()` and `useJob`, below).
1367
- `llm()` is neither: one call to a model, answered in the page (Calling a
1368
- model, below). It is the one wrapper that resolves the platform's answer
1575
+ Named exports: `me, ask, llm, llmEstimate, library, requests,
1576
+ stopRequest, openRequest, threads, thread, surfaceOfPath, startJob,
1577
+ cancelJob, reportError, jobs, setJob, runNow, pauseApp, resumeApp, runs,
1578
+ run, activity, connections, connectLink, openConnections, agentKit,
1579
+ platform`. That is the whole list.
1580
+
1581
+ Up to 0.8.1 the runs, Run now, Pause / Resume and the agent's settings
1582
+ were not here: they were MONITORING, and the OS drew them as the window's
1583
+ tabs so that every app showed its agent's work in one look. The kit
1584
+ (0.8.1) moved that one look into the template's blocks (The agent and AI
1585
+ kit, below), so the app now shows its agent's work itself, beside the
1586
+ rows the work wrote, and calls `_claw/jobs`, `_claw/runs`, `_claw/run`,
1587
+ `_claw/pause`, `_claw/resume`, `_claw/agent` and `_claw/connect` through
1588
+ these wrappers. The window's tabs stay, as the full history. Two things
1589
+ never move into the app: **the account sign-in and money** stay on the
1590
+ desk. The agent's questions are answered in the app (`answer`), and the
1591
+ yes is given in the app too, but never by the app: it is a press in a
1592
+ Makersclaw-held frame (`approval`, the `approval` block). The door decides
1593
+ who may press what (`may` on `jobs`): hide what the member may not press,
1594
+ and the door refuses it anyway.
1595
+ Asking is its own thing, and it belongs here too (`ask()` and `useJob`,
1596
+ below). `llm()` is neither: one call to a model, answered in the page
1597
+ (Calling a model, below). It is the one wrapper that resolves the platform's answer
1369
1598
  as it is, `{ ok: true, text }` and not `{ ok: true, status, data }`.
1599
+ `library` is neither asking nor monitoring: it reads what Makersclaw
1600
+ keeps, read only (Showing the Library, below).
1370
1601
  `requests` is not monitoring either: it is this app's asks in flight, so
1371
1602
  an empty surface can show the work coming (§3a). `startJob` and
1372
1603
  `cancelJob` are the 0.3.x door to the same work, kept so `useJob` can
@@ -1379,10 +1610,13 @@ that exact origin — never `"*"` — and only while the app is framed.
1379
1610
 
1380
1611
  ### Hooks — `lib/hooks.js` ("use client")
1381
1612
 
1382
- Five hooks: a generic fetch over one `_claw` route, the app's identity,
1383
- a job, the app's requests, and a model call. Each owns fetching, polling (while the
1384
- tab is visible; once a minute while `unavailable`), streaming and cleanup
1385
- on unmount. A surface renders what comes back and owns every pixel.
1613
+ A generic fetch over one `_claw` route, the app's identity, a job, the
1614
+ app's requests, a model call, five that read the Library, the app's own
1615
+ chat, and the kit's eight (0.8.1). Each owns
1616
+ fetching, polling (while the tab is visible; once a minute while
1617
+ `unavailable`; the Library's read once and have nothing to poll),
1618
+ streaming and cleanup on unmount. A surface renders what comes back and
1619
+ owns every pixel.
1386
1620
 
1387
1621
  ```js
1388
1622
  useClaw(path, { every, enabled = true }) → { data, error, loading, unavailable, reload }
@@ -1392,9 +1626,49 @@ useJob() → { running, status, queued, que
1392
1626
  start, cancel, reset, open }
1393
1627
  useRequests({ surface, job, every = 5000 }) → { requests, live, run, loading, error, unavailable, reload, open, stop }
1394
1628
  useLlm() → { run, loading, result, error, unavailable } (Calling a model)
1629
+ useLibraryCollections({ q, shelf }) → { collections, loading, error, code, unavailable, reload } (Showing the Library)
1630
+ useLibraryCollection(id) → { collection, loading, error, code, unavailable, reload }
1631
+ useLibraryItems(id, { q, tag, limit }) → { items, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
1632
+ useLibraryRows(id, { q, filters, limit }) → { rows, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
1633
+ useLibraryItem(id) → { item, fileUrl, textExcerpt, loading, error, code, unavailable, reload }
1634
+ useAgentThread({ row, how, job, key, view }) → { sessionId, state, needs, turns, view, pending, place, request, sending, loading, error,
1635
+ code, unavailable, send, stop, answer({ optionId, text } | { answers }), openOnDesk, newChat,
1636
+ openSession(sessionId), reload } (the agent-chat block)
1637
+ useAgentPane({ row, how, job, key }) → useAgentThread with the desk sidebar's view, plus { chats: { items, loading, error, unavailable },
1638
+ callDetail(callId), openRequest(id) } (the agent-pane block, D27; GET _claw/threads/<session>?view=1)
1639
+ useThreadList({ every = 30000 }) → { items: [{ sessionId, requestId, title, mark, at }], loading, error, unavailable, reload } (the pane's Chats list)
1395
1640
  jobFromRequest(request) → what useJob shows for one request (pure; for tests)
1641
+
1642
+ // The kit (0.8.1): each also returns { loading, error, code, unavailable, reload }
1643
+ useJobs({ every = 30000 }) → { jobs, app, budget, credits, may, busy, appBusy, runNow(id), setEnabled(id, on), pause(), resume() }
1644
+ useRuns({ job, limit = 20, every = 30000 }) → { runs, overview } every 5 s while a run is going
1645
+ useRun(id) → { run, steps, text, needs } every 2.5 s while it runs; nothing without an id
1646
+ useNeedsYou({ every = 8000 }) → { items: [{ id, request, kind, text, title, at, via, options, free, needsAt }], working, open(item), answer(item, { optionId, text }), takeBack(item), stop(request) }
1647
+ useApproval(requestId) → { approval, state, always, fallback, frame: { src, ref, title }, height } (the approval block; GET _claw/requests/<id>/approval)
1648
+ useActivity({ row, surface, since, limit = 50, agent = false, every = 20000 })
1649
+ → { rows } agent: true keeps the agent's lines
1650
+ useConnections({ every }) → { connections, connecting, connect(key) → { opened: "desk" | "tab" | false, error? } }
1651
+ useAgentKit() → { skills: [{ name, title, when, from: "app" | "added", installed }], tools: [{ name, description }] }
1652
+ useLlmAction({ input, system, schema, tier, task, maxTokens, estimate = true })
1653
+ → { estimate: { credits, credits_max } | null, estimating, run(), result, loading, error, unavailable, reset() }
1654
+ needsYouItem(request) · agentKitOf(data) · connectAccount(key) the kit hooks' pure parts (for tests)
1655
+
1656
+ // The automations engine (lib/automations.js, re-exported here): an app's own automations, from its own page
1657
+ useAutomations({ every = 30000 }) → { automations, busy, creating, setStatus(id, on), create(definition, { note, goLive }) } every 5 s while one runs
1658
+ useAutomation(id) → { automation, live, draft, definition, versions, estimate, estimateDraft, runs, busy: "save" | "keep" | "live" | "test" | null,
1659
+ save(definition), keep(), setLive(on), test(inputs) } resolve the platform's answer; a refusal carries `problems`
1660
+ useAutomationRun(runId) → { run, steps, stepsVisible, automation, definition, detail } every 2.5 s while it runs
1396
1661
  ```
1397
1662
 
1663
+ The kit's hooks poll only while the page is shown (not behind the
1664
+ window's other tabs, not in a hidden browser tab; coming back looks at
1665
+ once), look once a minute while their door is missing, abort on unmount
1666
+ and never throw. A missing door is `unavailable` with `error` null: a
1667
+ quiet "not connected yet". `useJobs`' Run now makes every `useRuns`,
1668
+ `useRequests` and `useNeedsYou` on the page look at once. `useActivity`
1669
+ here is the kit's: polled, with `row` and `agent`; `lib/door.js`'s
1670
+ `useActivity` (§5 Door) reads the same lines once.
1671
+
1398
1672
  `useRequests` is the work asked of this app's agent — from a screen or
1399
1673
  from the desk, by anyone in the workspace. `requests` is every one the
1400
1674
  gateway returned (the live ones and those that ended in the last day);
@@ -1408,10 +1682,11 @@ while the App tab is on screen (behind the window's other tabs it asks
1408
1682
  nothing; coming back looks at once); a start through `useJob` on the
1409
1683
  same page makes it look at once. Hand it to `LiveEmpty` (§3a).
1410
1684
 
1411
- There is no chat or runs hook: the OS draws those tabs. A domain
1412
- surface that wants a slice of the activity (a row's history beside the
1413
- row, say) reads it with `loadActivity`: on the server in a server app,
1414
- or with `useActivity` (`lib/door.js`, §5 Door) from the browser.
1685
+ Up to 0.8.1 this said there was no chat or runs hook, because the OS
1686
+ drew those tabs. Since the kit there are both, and the blocks that draw
1687
+ them: a record's history beside the record is the `activity-log` block
1688
+ over `useActivity({ row })`; on the server in a server app it is
1689
+ `loadActivity`.
1415
1690
 
1416
1691
  ### Commissioning work — `useJob()`
1417
1692
 
@@ -1568,6 +1843,92 @@ if (!r.ok) setError(r.error); // r.code: needs_answer, queue_fu
1568
1843
  It resolves once the platform took the ask (`{ ok: true, data: {
1569
1844
  request, desk_origin } }`) or refused it; it never waits for the work.
1570
1845
 
1846
+ ### The agent and AI kit — blocks (0.8.1)
1847
+
1848
+ The app shows its agent's work and its AI features itself, in its own
1849
+ look: a chat beside the record, the schedule and its runs, what waits on
1850
+ the member, the price before a press. Up to 0.8.1 the OS drew most of
1851
+ this as the window's tabs, so every app looked the same; now the same
1852
+ look lives in these blocks, and the tabs stay as the full history. Each
1853
+ block is `makersclaw add <name>`, reads nothing itself, and takes the
1854
+ hook's answer as props (a block never imports `lib/`):
1855
+
1856
+ - `agent-chat` (`AgentChat`) — the app's own chat with its agent, about
1857
+ the app or one record. `useAgentThread`.
1858
+ - `ask-bar` (`AskBar`) — one line to ask, with chips; it starts the
1859
+ thread and opens the chat. `useAgentThread`.
1860
+ - `needs-you` (`NeedsYou`, `QuestionBox`, `WaitingYes`, `AgentWorking`) —
1861
+ what waits on this member (a question answered in place, a yes through
1862
+ the `approval` block), the frozen "Ready to send" with Take back, the
1863
+ working strip with Stop. `useNeedsYou`.
1864
+ - `approval` (`Approval`) — the yes, given in the app: the app's own card
1865
+ (what goes out, to whom, the cost) over a Makersclaw-held press frame in
1866
+ the app's theme that app code cannot script, with "Always allow this
1867
+ kind". `useApproval`.
1868
+ - `activity-log` (`ActivityLog`) — who did what, newest first, the
1869
+ agent as an author; with `row`, one record's timeline. `useActivity`.
1870
+ - `agent-marks` (`AgentMark`, `CallMark`, `Byline`) — the agent's mark,
1871
+ a model call's mark, "By the agent, on Priya's ask". No hook.
1872
+ - `schedule-card` (`ScheduleCard`) — one job: its schedule in words, its
1873
+ last run, next run, Run now with its price, the on/off switch.
1874
+ `useJobs`.
1875
+ - `run-history` (`RunHistory`, `RunAccount`, `RunOverview`) — the runs,
1876
+ one run's account, the overview against the week's cap. `useRuns`,
1877
+ `useRun`.
1878
+ - `workflow-view` (`WorkflowView`) — the job as a graph: Trigger → steps
1879
+ → result, the run picker, Live, Trigger manually, its runs beside.
1880
+ `useJobs`, `useRuns`, `useRun`.
1881
+ - `suggestion` (`FieldSuggestion`, `InlineSuggestion`, `TextSuggestion`,
1882
+ `Pencil`, `SuggestionGroup`, `Looking`) — a value the agent proposes,
1883
+ in pencil until kept. No hook: Keep and Drop call the app's declared
1884
+ actions (`runAction`).
1885
+ - `source-receipt` (`SourceReceipt`) — where a value came from, as a
1886
+ clipping. No hook: the source is app data.
1887
+ - `agent-column` — a column the agent fills, each answer with its state,
1888
+ how sure it is, and its receipt. The app's rows (`lib/data.js`).
1889
+ - `record-grid` — a virtualised grid of many records. The app's rows
1890
+ (`lib/data.js`).
1891
+ - `ai-action` (`AiAction`) — one model call on what the screen holds,
1892
+ its price on the button, the answer in place with Use. `useLlmAction`.
1893
+ - `cost` (`CostTag`, `CostConfirm`, `Allowance`) — the price on a
1894
+ control, the confirm before a big spend, the week's allowance.
1895
+ `useLlmAction`'s estimate, `useJobs`' budget.
1896
+ - `agent-changes` (`AgentChanges`) — the receipt of one ask, with Undo
1897
+ this ask. `useActivity({ agent: true, since })`.
1898
+ - `connect-card` (`ConnectCard`, `ConnectRow`) — the app's accounts,
1899
+ live or not, Connect. `useConnections`.
1900
+ - `agent-kit` (`AgentKit`) — what the agent knows and what it can do.
1901
+ `useAgentKit`.
1902
+ - `library-shelf` (`LibraryShelf`) — "Start from a template": a Library
1903
+ collection's items. `useLibraryItems`.
1904
+
1905
+ The rules:
1906
+
1907
+ 1. **Use the kit.** Never redraw a chat, a schedule, a run list, a
1908
+ needs-you queue, a suggestion or a price tag by hand: the block is
1909
+ the one look every app shares, and it grows in the template.
1910
+ 2. **The sign-in and money stay on the desk; the yes is the press
1911
+ frame's.** The agent's question is answered in the app (`QuestionBox`,
1912
+ `answer`). The agent's yes is the `approval` block: you draw what goes
1913
+ out, the frame holds the press, and when it cannot load the block falls
1914
+ back to "Waiting for your yes on the desk" and opens it
1915
+ (`openRequest`). Connect opens the desk's connections panel; topping up
1916
+ opens the desk. Never an Approve, Yes or Send of your own that gives
1917
+ the yes, a password field or a payment form in the app.
1918
+ 3. **Cost on every control that spends.** Run now, Read now, Enrich,
1919
+ Summarize: the price is on the button (`CostTag`, `useLlmAction`'s
1920
+ estimate) before the press, and a big spend asks first
1921
+ (`CostConfirm`).
1922
+ 4. **The door decides who may press.** `useJobs().may` says who may run,
1923
+ switch and pause; hide what the member may not press. The door
1924
+ refuses it anyway.
1925
+ 5. **A missing door is quiet.** On a claw from before a door the hook is
1926
+ `unavailable`: the block shows its empty state ("No runs yet", "Not
1927
+ set up"), never an error.
1928
+ 6. **Its own width decides its layout.** Every kit block lays itself out
1929
+ by `@container`, at 320, 368, 800 and 1280 px of its own width; give
1930
+ it the width, never a viewport breakpoint of yours.
1931
+
1571
1932
  ### Calling a model — `llm()`
1572
1933
 
1573
1934
  `llm()` is for one-shot text work on what is on screen: sort these
@@ -1760,6 +2121,228 @@ What to keep in mind:
1760
2121
  they handle what a bare `fetch` would not (a claw without the door, a
1761
2122
  dropped network, an abort).
1762
2123
 
2124
+ ### Showing the Library — `library`
2125
+
2126
+ The Library is what Makersclaw keeps for every workspace: **collections of
2127
+ files** (pitch decks, PDFs, HTML website templates, graphics) and
2128
+ **collections of rows** (a dataset: a list of investors, growth
2129
+ examples). Members browse it in the Library window on the desk. An app
2130
+ can show the same content inside a screen, read live from the platform.
2131
+
2132
+ Use it when the app **shows examples, templates or a dataset that
2133
+ Makersclaw keeps**: a gallery of pitch decks, a picker of website
2134
+ templates to start from, a table of investors to choose from. The screen
2135
+ asks the Library when it opens, so what it shows is what the Library
2136
+ holds today.
2137
+
2138
+ Not for:
2139
+
2140
+ - **The app's own data.** That is your tables (§5, Your tables) and the
2141
+ company brain. The Library is Makersclaw's, the same for every
2142
+ workspace; nothing a member does in the app is written to it.
2143
+ - **Sample rows for an empty screen.** Examples of your own app's data
2144
+ are `useFixture` (§3a), never the Library.
2145
+ - **Copying into the workspace.** The Library is read only: the door has
2146
+ no write. A member who wants a collection's rows in their company
2147
+ data, or a file in their Files, asks the agent, which has the Library's
2148
+ tools and records the copy:
2149
+
2150
+ ```js
2151
+ import { ask } from "../lib/platform";
2152
+
2153
+ ask({ text: `Copy the "${collection.title}" list into our company data`, how: `The Library collection is "${collection.slug}".` });
2154
+ ```
2155
+
2156
+ #### Reading it
2157
+
2158
+ ```js
2159
+ import { library } from "../lib/platform";
2160
+
2161
+ library.collections({ q, shelf }) → data { collections: [card] }
2162
+ library.collection(id) → data { collection }
2163
+ library.items(id, { q, tag, cursor, limit }) → data { items, next_cursor, total, preview_only }
2164
+ library.rows(id, { q, filters, cursor, limit }) → data { rows, next_cursor, total, preview_only }
2165
+ library.item(id) → data { item, file_url?, text_excerpt? }
2166
+ ```
2167
+
2168
+ Each resolves `{ ok, status, data }` or `{ ok: false, status, error,
2169
+ unavailable, code }` like `me`, and never throws. A collection's `id` is
2170
+ its slug (`"pitch-decks"`) or its uuid; an item's is its uuid. An id that
2171
+ names nothing asks nothing of the platform. Every call takes `signal`
2172
+ among its options.
2173
+
2174
+ - `shelf` is one of `decks`, `websites`, `designs`, `documents`,
2175
+ `datasets`, `examples`. `q` is a search. A card is `{ id, slug, title,
2176
+ blurb, kind: "files" | "rows", shelf, tags, access: "free" | "paid",
2177
+ status, public_page, cover_url, item_count, row_count, usable,
2178
+ preview_only }`; `collection` adds `body`, `columns`, `source`,
2179
+ `licence`, `preview_count`, `personal_data`, `published_at`.
2180
+ - **Items** (a files collection): `{ id, title, description, tags,
2181
+ format, mime, bytes, preview_url, source_url, licence, position,
2182
+ locked }`. `format` is `pdf`, `image`, `html`, `slides`, `document`,
2183
+ `sheet`, `archive` or `other`. `tag` narrows by a tag. `limit` is a
2184
+ whole number: 30 items a page unless you say, and more than 60 is cut
2185
+ to 60.
2186
+ - **Rows** (a rows collection): `{ id, data, source_url }`. `data` is
2187
+ keyed by the collection's `columns` (`{ key, label, type, filter, … }`;
2188
+ `type` is `text`, `long_text`, `number`, `url`, `email`, `image`,
2189
+ `tags` or `date`). `filters` is `{ <column key>: value }` for the
2190
+ columns with `filter: true`, an exact match (for a `tags` column, rows
2191
+ that have the tag); any other column is refused in words. `limit`: 50
2192
+ rows a page unless you say, and more than 100 is cut to 100.
2193
+ `source_url` is where the row
2194
+ was found: show it beside a person, an investor or a figure.
2195
+ - **Paging.** A page with more answers `next_cursor`: pass it back as
2196
+ `cursor`. Take it as given; do not read or build one.
2197
+ - `item(id)` is the item whole: its file's signed address as `file_url`
2198
+ and the first 4,000 characters of its text as `text_excerpt` (the
2199
+ start of a PDF's words, an HTML page's source).
2200
+
2201
+ The hooks read once, when the screen opens or an argument changes, and
2202
+ page for you:
2203
+
2204
+ ```js
2205
+ useLibraryCollections({ q, shelf }) → { collections, loading, error, code, unavailable, reload }
2206
+ useLibraryCollection(id) → { collection, loading, error, code, unavailable, reload }
2207
+ useLibraryItems(id, { q, tag, limit }) → { items, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
2208
+ useLibraryRows(id, { q, filters, limit }) → { rows, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
2209
+ useLibraryItem(id) → { item, fileUrl, textExcerpt, loading, error, code, unavailable, reload }
2210
+ ```
2211
+
2212
+ `items` and `rows` hold the pages read so far; `loadMore()` reads the
2213
+ next and adds it (`hasMore` says there is one; it does nothing while a
2214
+ page is out). A new `id`, `q`, `tag`, `filters` or `limit` starts the
2215
+ list over, showing `loading` and no rows, never the last list: type-ahead
2216
+ should wait for a pause before it changes `q`. Nothing is read until
2217
+ there is an `id` (and `enabled: false` reads nothing). `unavailable` and
2218
+ `error` are never both set: `unavailable` is a claw from before the door
2219
+ or no network (show the quiet "not connected yet"), `error` is the
2220
+ platform's words and `code` its code when it named one.
2221
+
2222
+ ```jsx
2223
+ "use client";
2224
+ import { Badge, Button, Card, Empty, Image, Notice } from "../components/ui";
2225
+ import { useLibraryItems } from "../lib/hooks";
2226
+
2227
+ export default function Decks() {
2228
+ const { items, total, previewOnly, hasMore, loadMore, loading, loadingMore, error, unavailable } =
2229
+ useLibraryItems("pitch-decks", { limit: 24 });
2230
+ if (unavailable) return <p className="text-sm text-muted-foreground">The Library is not connected yet.</p>;
2231
+ if (error) return <Notice tone="danger">{error}</Notice>;
2232
+ if (!loading && !items.length) return <Empty title="No decks yet" body="Nothing in this collection matches." />;
2233
+ return (
2234
+ <div className="grid gap-4">
2235
+ <div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
2236
+ {items.map((item) => (
2237
+ <Card key={item.id} padding="sm" className="grid gap-2">
2238
+ <Image src={item.preview_url} alt="" ratio="photo" />
2239
+ <p className="text-sm font-medium">{item.title}</p>
2240
+ <Badge>{item.format}</Badge>
2241
+ </Card>
2242
+ ))}
2243
+ </div>
2244
+ {previewOnly && total > items.length ? <Notice>{total - items.length} more come with a paid plan.</Notice> : null}
2245
+ {hasMore ? <Button loading={loadingMore} onClick={loadMore}>Show more</Button> : null}
2246
+ </div>
2247
+ );
2248
+ }
2249
+ ```
2250
+
2251
+ #### A paid collection on a Free plan
2252
+
2253
+ A collection with `access: "paid"` is for paid workspaces. On a Free plan
2254
+ it is a **preview**, not a refusal: the card says `usable: false` and
2255
+ `preview_only: true`, and `items` or `rows` answer only the first
2256
+ `preview_count` of them (a search or a filter runs over those), with
2257
+ `preview_only: true` and the **true** `total`. `total` minus what you
2258
+ hold is what "comes with a paid plan". The items past the preview are
2259
+ not in the list (the item's `locked` flag is for such an item, and a
2260
+ list of a preview carries only the preview's, so it reads `false`
2261
+ there); asking for one by its id, `library.item(id)`, is a 403 with
2262
+ `code: "needs_plan"` and the platform's words ("This collection comes
2263
+ with a paid plan."): show them, and stop. The Library window on the desk
2264
+ has the Upgrade button; an app has none to offer. On a paid plan the
2265
+ same calls answer the whole collection.
2266
+
2267
+ #### Files
2268
+
2269
+ - **`file_url` is a signed address, good for ten minutes.** Show or
2270
+ download from it when the member asks, and never keep it: not in a row,
2271
+ not in `localStorage`, not in a link that outlives the screen. A new
2272
+ `library.item(id)` (or `reload()`) signs another. Row cells of type
2273
+ `image` are signed the same way, so a table of rows with pictures that
2274
+ stays open should read its page again now and then.
2275
+ - **`preview_url` and `cover_url` are plain pictures** that stay: use
2276
+ them in `Image` for a card or a thumbnail. A row's image is not one;
2277
+ it is a signed address.
2278
+ - A PDF opens in a new tab (`<Button href={fileUrl} target="_blank"
2279
+ rel="noreferrer">`); an image is an `Image` of `fileUrl`; the other
2280
+ formats are a download link.
2281
+ - **An `html` item (a website template) is shown only in a sandboxed
2282
+ frame, never in the app's own page.** Read its file as text and give
2283
+ it to an `iframe` as `srcDoc` with `sandbox="allow-scripts"`, so its
2284
+ own scripts run. **Never add `allow-same-origin`**: with it the
2285
+ template's scripts run as your app, with the member's session and
2286
+ every `_claw` door. Never `dangerouslySetInnerHTML`, never
2287
+ `iframe src={fileUrl}`, and never your own origin: Makersclaw does not
2288
+ serve these files from it either.
2289
+
2290
+ ```jsx
2291
+ "use client";
2292
+ import { useEffect, useState } from "react";
2293
+ import { Notice, Spinner } from "../components/ui";
2294
+ import { useLibraryItem } from "../lib/hooks";
2295
+
2296
+ export default function TemplatePreview({ id }) {
2297
+ const { item, fileUrl, code, error, unavailable } = useLibraryItem(id);
2298
+ const [html, setHtml] = useState(null);
2299
+ const [failed, setFailed] = useState(false);
2300
+ useEffect(() => {
2301
+ if (!fileUrl) return undefined;
2302
+ const controller = new AbortController();
2303
+ fetch(fileUrl, { signal: controller.signal })
2304
+ .then((res) => (res.ok ? res.text() : Promise.reject(new Error("no file"))))
2305
+ .then(setHtml)
2306
+ .catch(() => {
2307
+ if (!controller.signal.aborted) setFailed(true);
2308
+ });
2309
+ return () => controller.abort();
2310
+ }, [fileUrl]);
2311
+ if (unavailable) return <p className="text-sm text-muted-foreground">The Library is not connected yet.</p>;
2312
+ if (error) return <Notice tone={code === "needs_plan" ? "info" : "danger"}>{error}</Notice>;
2313
+ if (failed) return <Notice tone="danger">This template did not open. Try again.</Notice>;
2314
+ if (html === null) return <Spinner />;
2315
+ return <iframe title={item.title} srcDoc={html} sandbox="allow-scripts" className="h-96 w-full rounded-md border border-border" />;
2316
+ }
2317
+ ```
2318
+
2319
+ #### What to keep in mind
2320
+
2321
+ - **Browser only, in both modes.** The read rides the member's session:
2322
+ `library` and the hooks run in a `"use client"` file. A server
2323
+ component or a server action has no member and cannot call it.
2324
+ - **Never by its path.** A string naming `_claw/library` fails `npm run
2325
+ check` (§6, `library`): the functions handle a claw without the door, a
2326
+ dropped network and an abort, which a bare `fetch` does not.
2327
+ - **A claw from before the door** answers a 404 that names no refusal:
2328
+ `unavailable: true`, from every call and every hook. A collection or
2329
+ item that is not there (or is a draft the member cannot see) is a 404
2330
+ that names its code, so `unavailable` stays false and `error` says so.
2331
+ Show a missing door as "not connected yet", and a missing collection as
2332
+ "not found".
2333
+ - **Show where it came from.** An item's `licence` and `source_url`, a
2334
+ row's `source_url` and a collection's `source` are in the answer for a
2335
+ reason: print them where the content is shown.
2336
+ - **A rows collection can list people** (`personal_data: true`). It is
2337
+ shown to the member who has the app open. Do not copy it anywhere
2338
+ yourself: no `insertRow` of its rows, no export, no sending it to your
2339
+ own server. Using it in the company's data is a copy through the
2340
+ agent.
2341
+ - **The platform notes that the app showed a collection**, once a day
2342
+ per app and collection.
2343
+ - **Read it when the screen needs it.** Not on every keystroke, and not
2344
+ in a loop over every collection: a shelf is one `collections` call.
2345
+
1763
2346
  ### Activity — the contract
1764
2347
 
1765
2348
  `claw_app.activity` is how the founder sees the work. It is the
@@ -1840,6 +2423,8 @@ ok tables its own schema (makersclaw.json): every table named bare, and e
1840
2423
  ok brain no brain block in makersclaw.json; no lib/brain.js call names a kind
1841
2424
  ok viewport nothing in the app sizes itself by the window
1842
2425
  ok llm no screen names _claw/llm: a model is called through llm() or useLlm() (README §5)
2426
+ ok library no screen names _claw/library: the Library is read through library() or its hooks (README §5)
2427
+ ok actions no actions declared in makersclaw.json: the app's agent writes as references/actions.md says
1843
2428
  ok smoke built in 41s · / → 307 · /s/drafts 200 · /s/sent 200 (0.6s)
1844
2429
  all clear
1845
2430
  ```
@@ -1851,6 +2436,16 @@ ok browser files and a door: 2 client surfaces; no server code, route, pro
1851
2436
  ok smoke built in 38s (copy at ~/.claw-check/app) · export 2.1 MB in 64 files · / → 200 to /s/drafts · /s/drafts 200 · /s/sent 200 (0.1s)
1852
2437
  ```
1853
2438
 
2439
+ `actions` holds `makersclaw.json` `actions` to the platform's rules
2440
+ (§5, Declared actions) and, once any is declared, refuses every write a
2441
+ screen makes that is not one.
2442
+
2443
+ `automations` runs `makersclaw.json` `automations` (§5, Shipped
2444
+ automations) through the platform's own validator, one line per problem
2445
+ (its place, then what is wrong; at most 8, then "and N more"). It reads
2446
+ two copies of claw's format kept in `check/` and is skipped, not failed,
2447
+ on a node older than 22.18 (it cannot read them).
2448
+
1854
2449
  `kit` refuses a fixed file that differs from the template (they are
1855
2450
  hashed in `check/pins.json`) and any file of yours under `components/ui`
1856
2451
  or `components/parts`. `viewport` refuses anything in your code that
@@ -1966,6 +2561,14 @@ are the door too). A path built from pieces or held in a variable is not
1966
2561
  read here, as for rule 8. A longer name (`_claw/llm-notes`) is another
1967
2562
  route, and a comment or text in JSX is not a string of code.
1968
2563
 
2564
+ `library` is the same rule for the Library's door: no string in the code
2565
+ names `_claw/library`, and none handed to `claw()`, `clawUrl()` or
2566
+ `clawStream()` starts `library`. The Library is read with `library` from
2567
+ `lib/platform.js` or the `useLibrary…` hooks (§5, Showing the Library),
2568
+ which handle a claw without the door, a dropped network, an id that
2569
+ names nothing and an abort. It reads every app, in both modes, and the
2570
+ path as a browser reads it (`claw("./library/items")` is the door too).
2571
+
1969
2572
  `browser` reads a browser app only (`"mode": "browser"`): its pages are
1970
2573
  files built once, and everything they read or write goes through the
1971
2574
  platform's data door. So it refuses, file and line, a `"use server"`