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
@@ -0,0 +1,93 @@
1
+ "use client";
2
+
3
+ // AiAction over a pretend useLlmAction(): priced, running, answered,
4
+ // refused, shaped by a schema, and not connected yet — the gallery's and
5
+ // the smoke test's surface. Not installed into apps.
6
+ import { useEffect, useRef, useState } from "react";
7
+ import { Card } from "../components/ui";
8
+ import { AiAction } from "../components/blocks/ai-action";
9
+
10
+ /** Shaped as useLlmAction returns it; `answer` is what run() resolves. */
11
+ function usePretendCall(answer, { estimate = { credits: 1, credits_max: 1 }, ms = 1200 } = {}) {
12
+ const [state, setState] = useState({ result: null, loading: false, error: null });
13
+ const [estimating, setEstimating] = useState(true);
14
+ const timers = useRef([]);
15
+ useEffect(() => {
16
+ timers.current.push(setTimeout(() => setEstimating(false), 500));
17
+ return () => timers.current.forEach(clearTimeout);
18
+ }, []);
19
+ return {
20
+ estimate: estimating ? null : estimate,
21
+ estimating,
22
+ loading: state.loading,
23
+ result: state.result,
24
+ error: state.error,
25
+ unavailable: false,
26
+ run: () =>
27
+ new Promise((resolve) => {
28
+ setState({ result: null, loading: true, error: null });
29
+ timers.current.push(
30
+ setTimeout(() => {
31
+ const r = typeof answer === "function" ? answer() : answer;
32
+ setState(r.ok === false ? { result: null, loading: false, error: r.error } : { result: r, loading: false, error: null });
33
+ resolve(r);
34
+ }, ms),
35
+ );
36
+ }),
37
+ reset: () => setState({ result: null, loading: false, error: null }),
38
+ };
39
+ }
40
+
41
+ const DRAFT =
42
+ "Thanks so much for taking the time to meet with us last Thursday. We really enjoyed hearing about how Crumb & Co schedules its 22 shops, and we think there is a lot we could do together over the coming months.";
43
+
44
+ export default function AiActionDemo() {
45
+ const [draft, setDraft] = useState(DRAFT);
46
+ const shorter = usePretendCall({ ok: true, text: "Thanks for meeting last Thursday. We'd love to help Crumb & Co schedule all 22 shops." });
47
+ const why = usePretendCall(
48
+ { ok: true, data: { reasons: ["Two replies in a week", "Asked for pricing", "A new head of operations"] } },
49
+ { estimate: { credits: 2, credits_max: 6 } },
50
+ );
51
+ const refused = usePretendCall({ ok: false, error: "The app's weekly allowance is used up. It starts again on Monday." });
52
+ const running = usePretendCall({ ok: true, text: "…" }, { ms: 1e9 });
53
+ return (
54
+ <div className="grid gap-6 p-6 [grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr))]">
55
+ <Card title="A draft">
56
+ <div className="grid gap-3">
57
+ <p className="text-sm">{draft}</p>
58
+ <AiAction label="Shorter" action={shorter} useLabel="Replace the draft" onUse={(r) => setDraft(r.text)} />
59
+ </div>
60
+ </Card>
61
+ <Card title="A score">
62
+ <AiAction
63
+ label="Why is it 82?"
64
+ icon="lightbulb"
65
+ action={why}
66
+ render={(r) => (
67
+ <ul className="list-disc pl-5">
68
+ {r.data.reasons.map((x) => (
69
+ <li key={x}>{x}</li>
70
+ ))}
71
+ </ul>
72
+ )}
73
+ />
74
+ </Card>
75
+ <Card title="Refused">
76
+ <AiAction label="Summarize the thread" action={refused} />
77
+ </Card>
78
+ <Card title="Running">
79
+ <AiAction label="Summarize" action={{ ...running, estimate: { credits: 0.4, credits_max: 0.4 }, estimating: false, loading: true, run: () => undefined }} />
80
+ </Card>
81
+ <Card title="Not connected yet">
82
+ <AiAction label="Shorter" action={{ unavailable: true }} />
83
+ </Card>
84
+ <div className="w-80 max-w-full">
85
+ <AiAction
86
+ label="Explain why this account's health score moved down this week"
87
+ action={{ estimate: { credits: 1200, credits_max: 2400 }, estimating: false, run: () => undefined, result: { text: "Two of its five shops stopped scheduling on Monday, and the owner hasn't opened the last three emails." }, reset: () => undefined }}
88
+ onUse={() => undefined}
89
+ />
90
+ </div>
91
+ </div>
92
+ );
93
+ }
@@ -0,0 +1,3 @@
1
+ // The AiAction block — `makersclaw add ai-action`. Fixed: compose it
2
+ // through its props (README.md beside this file).
3
+ export { AiAction, priceWords } from "./ai-action";
@@ -0,0 +1,145 @@
1
+ # Approval
2
+
3
+ The yes, given in the app. The app draws the card in its own theme: what
4
+ will happen, to whom, the exact words, the cost. The press is not the
5
+ app's. Under the card sits a small page of Makersclaw's, in the app's
6
+ colours, that app code cannot script. It shows the server's own words for
7
+ the request and only counts a press a person made on a card they can see.
8
+
9
+ ```jsx
10
+ import { Approval } from "../components/blocks/approval"; // a Makersclaw app ("./blocks/approval" from components/)
11
+ import { Approval } from "@/components/makersclaw/blocks/approval"; // a shadcn project
12
+ ```
13
+
14
+ A client component. The Example is at the end.
15
+
16
+ ## Why a frame
17
+
18
+ App code is written by an agent, and an in-app Approve button could be
19
+ pressed by that same code, or by a script that got into the page. So the
20
+ button that gives the yes is not in the app's page. It is a Makersclaw
21
+ page, embedded in the card:
22
+
23
+ - **Another origin.** The app cannot reach into it, read it or click it.
24
+ - **The server's words.** It shows what Makersclaw holds for the request:
25
+ the agent's one question, who it goes to, from which account, the first
26
+ message in full, and the rule "Always allow this kind" would save. Never
27
+ the app's text. The app's card above it shows the same thing in the
28
+ app's own design; the frame is the one to trust.
29
+ - **A press a person made, on a card they can see.** Where the browser
30
+ can tell (Chrome, Edge) the Approve button works only after the card
31
+ has been in view, uncovered and not faded, for half a second. Where it
32
+ cannot (Safari, Firefox) Approve is press and hold, for most of a
33
+ second. A click the page's script makes does nothing.
34
+ - **The member's own sign-in.** The press carries the member's token from
35
+ the desk's storage, which the app has no way to read, and the server
36
+ checks it is the member who asked, for this app, for the question the
37
+ card showed.
38
+ - **The same path as the desk's Approve.** The answer goes to the agent
39
+ as a structured answer from the member, so the audit trail, the rules
40
+ and the Standing yes stay one.
41
+
42
+ "Always allow this kind" is in the same card: one tick, and the server
43
+ writes one bounded line into the app's Standing yes (the kind: what is
44
+ sent, to whom, from which account), shown beside the box before it is
45
+ ticked. Rules, not items: the next one of that kind goes without asking.
46
+ Anything wider still asks.
47
+
48
+ ## Which hook feeds it
49
+
50
+ ```js
51
+ const approval = useApproval(item.id); // lib/hooks.js; item from useNeedsYou
52
+ // → { approval, state, always, fallback, frame, height, loading, error, … }
53
+ ```
54
+
55
+ It reads `GET _claw/requests/:id/approval` once, for the request that
56
+ waits on this member's yes (`item.via === "press"`), and listens to the
57
+ frame. It approves nothing.
58
+
59
+ ## Props
60
+
61
+ - `approval` — `useApproval(...)`'s answer (required).
62
+ - `title` — what is about to happen, in the app's words ("Send 3
63
+ follow-ups to the Replies list").
64
+ - `kicker` — the line over it. Default "Waiting for your yes".
65
+ - `children` — the app's own card content: the draft, the recipients, the
66
+ exact words. Drawn above the press, in the app's theme.
67
+ - `cost` — a node for the price (the `cost` block's `CostTag`), beside the
68
+ title.
69
+ - `onOpenDesk()` — opens the desk on this ask (`needs.open(item)`): the
70
+ press of the fallback.
71
+ - `onDone({ state, always })` — once, when the member has said yes
72
+ (`"approved"`) or not now (`"declined"`); `always` is true when "Always
73
+ allow this kind" was saved. Refresh what the yes unlocks.
74
+ - `className` — layout around it. Never colour.
75
+
76
+ ## The states
77
+
78
+ `approval.state` is one of: `loading` (a skeleton) · `ready` (the frame)
79
+ · `approved` ("You said yes · the agent is on it", and "Always allowed for
80
+ this kind" when it was) · `declined` ("Not now. Nothing went out.") ·
81
+ `stale` (the question moved on since the card was drawn; it looks again
82
+ by itself) · `gone` (nothing waits any more: answered elsewhere).
83
+
84
+ When the frame cannot do its part, `approval.fallback` is true and the
85
+ block draws `WaitingYes` instead: "Waiting for your yes on the desk",
86
+ with **Open the desk**. That is the case when the frame did not load in
87
+ seven seconds (`blocked`), the member must sign in again on the desk
88
+ (`signin`), the claw is from before this door (`unavailable`) or the read
89
+ failed (`error`). Nothing is lost: the yes is the same yes.
90
+
91
+ ## Who may do what
92
+
93
+ - The member who asked gives the yes. Owners and admins do not give a
94
+ teammate's: the door refuses them (`not_your_request`).
95
+ - Only a yes: one question, one Approve and Not now. A tool approval, a
96
+ connect, a spend and several questions at once go to the desk.
97
+ - A question (not a yes) is answered in place, with `QuestionBox`
98
+ (`needs-you`), never here.
99
+ - Topping up credits and signing in to an account stay on the desk.
100
+
101
+ ## Never
102
+
103
+ - **Never an Approve, Yes or Send button of your own that gives the
104
+ yes.** The app's card may have a "Review the draft" press; the
105
+ approval is the frame's.
106
+ - Never hide, cover, fade, scale or position the frame so that part of it
107
+ is out of view: a press then does not count, by design.
108
+ - Never put the frame in an element with `pointer-events: none`,
109
+ `opacity` below 1 or a `transform`.
110
+ - Never show another member's asks here.
111
+
112
+ ## Example
113
+
114
+ The post that waits for its yes, inside the page that already shows it.
115
+
116
+ ```jsx
117
+ "use client";
118
+ import { useNeedsYou, useApproval } from "../lib/hooks";
119
+ import { Approval } from "../components/blocks/approval";
120
+ import { CostTag } from "../components/blocks/cost";
121
+
122
+ export function SendCard({ item, draft }) {
123
+ const needs = useNeedsYou();
124
+ const approval = useApproval(item.id);
125
+ return (
126
+ <Approval
127
+ approval={approval}
128
+ title={`Send ${draft.count} follow-ups to ${draft.list}`}
129
+ cost={<CostTag credits={draft.credits} />}
130
+ onOpenDesk={() => needs.open(item)}
131
+ onDone={({ state }) => state === "approved" && refreshRows()}
132
+ >
133
+ <DraftList draft={draft} />
134
+ </Approval>
135
+ );
136
+ }
137
+
138
+ // …and in a queue of everything that waits:
139
+ <NeedsYou
140
+ items={needs.items}
141
+ onOpen={needs.open}
142
+ onAnswer={needs.answer}
143
+ renderYes={(item) => <SendCard item={item} draft={draftFor(item)} />}
144
+ />
145
+ ```
@@ -0,0 +1,163 @@
1
+ "use client";
2
+
3
+ import { useEffect, useRef } from "react";
4
+ import { Button, Icon, Skeleton, Spinner, cx } from "../../ui";
5
+ import { WaitingYes } from "../needs-you";
6
+
7
+ // Approval — the yes, given in the app (the app kit, D18). The app draws
8
+ // the card in its own theme: what will happen, to whom, the exact words,
9
+ // the cost. The press is not the app's. Under the card sits a small page
10
+ // of Makersclaw's, in another origin, that app code cannot script: it
11
+ // shows the SERVER's words for the request (the agent's question, who,
12
+ // from which account, the first message, the rule "Always allow this
13
+ // kind" would save), in the app's colours, and only counts a press a
14
+ // person made on a card they can see (in view and uncovered, or held).
15
+ // The block draws that frame and what it says back; it never draws an
16
+ // Approve of its own.
17
+ //
18
+ // const approval = useApproval(item.id); // lib/hooks.js
19
+ // <Approval approval={approval} title="Send 3 follow-ups" onOpenDesk={…}>
20
+ // …the draft the app already shows…
21
+ // </Approval>
22
+ //
23
+ // If the frame cannot do its part (it did not load in time, the member
24
+ // must sign in again, a claw from before this door) the block falls back
25
+ // to WaitingYes: "Waiting for your yes on the desk", with the desk one
26
+ // press away. Props in, callbacks out.
27
+
28
+ /** A frame that has not said how tall it wants to be. */
29
+ const FRAME_HEIGHT = 240;
30
+
31
+ /** Why the fallback is showing, in a sentence. */
32
+ const WHY = {
33
+ signin: "Sign in again on Makersclaw to say yes here. The desk has it.",
34
+ blocked: "The press could not load here. The desk has it.",
35
+ unavailable: "Saying yes here needs a newer Makersclaw. The desk has it.",
36
+ error: "The press could not be loaded just now. The desk has it.",
37
+ };
38
+
39
+ /** The card's receipt, once the press has been used. */
40
+ function Receipt({ icon, tone, head, children }) {
41
+ return (
42
+ <div role="status" className="grid grid-cols-1 min-w-0 gap-1">
43
+ <p className={cx("flex min-w-0 items-center gap-2 font-medium", tone)}>
44
+ <Icon name={icon} size={16} className="shrink-0" />
45
+ <span className="min-w-0 break-words">{head}</span>
46
+ </p>
47
+ {children ? <p className="text-muted-foreground">{children}</p> : null}
48
+ </div>
49
+ );
50
+ }
51
+
52
+ /**
53
+ * approval what useApproval(requestId) returns (required)
54
+ * title what is about to happen, in the app's words ("Send 3
55
+ * follow-ups to the Replies list")
56
+ * kicker the line over it; default "Waiting for your yes"
57
+ * children the app's own card content: the draft, the recipients,
58
+ * the exact words. Drawn above the press, in the app's
59
+ * theme
60
+ * cost a node for the price ("about 700 cr": the `cost`
61
+ * block's CostTag); shown beside the title
62
+ * onOpenDesk() opens the desk on this ask: the press of the fallback
63
+ * (useNeedsYou's `open(item)`); without it the fallback
64
+ * only says where the yes is
65
+ * onDone({ state, always }) called once when the member has said yes
66
+ * or not now ("approved" or "declined"; `always` true when
67
+ * "Always allow this kind" was saved): refresh what the
68
+ * yes unlocks
69
+ * className layout around it. Never colour.
70
+ */
71
+ export function Approval({ approval, title, kicker = "Waiting for your yes", children, cost, onOpenDesk, onDone, className }) {
72
+ const state = approval?.state ?? "idle";
73
+ const spoken = useRef(null);
74
+ useEffect(() => {
75
+ if ((state === "approved" || state === "declined") && spoken.current !== state) {
76
+ spoken.current = state;
77
+ onDone?.({ state, always: Boolean(approval?.always) });
78
+ }
79
+ if (state !== "approved" && state !== "declined") spoken.current = null;
80
+ }, [state, approval?.always]);
81
+
82
+ if (state === "idle") return null;
83
+
84
+ if (state === "loading")
85
+ return (
86
+ <section aria-busy="true" aria-label="Waiting for your yes" className={cx("@container grid grid-cols-1 min-w-0 gap-3 rounded-lg border border-border bg-card p-3.5", className)}>
87
+ <Skeleton className="w-1/3" />
88
+ <Skeleton className="w-3/4" />
89
+ <Skeleton className="h-16 w-full" />
90
+ </section>
91
+ );
92
+
93
+ // The frame cannot be used: the desk's card, with the words the app drew.
94
+ if (approval?.fallback)
95
+ return (
96
+ <WaitingYes
97
+ title={title}
98
+ frozen={children}
99
+ kicker={kicker}
100
+ body={WHY[state] ?? WHY.error}
101
+ onOpen={onOpenDesk}
102
+ className={className}
103
+ />
104
+ );
105
+
106
+ const done = state === "approved" || state === "declined";
107
+ const head = (
108
+ <div className="grid grid-cols-1 min-w-0 gap-1">
109
+ <div className="flex min-w-0 items-start gap-2">
110
+ <div className="grid grid-cols-1 min-w-0 flex-1 gap-1">
111
+ {kicker ? (
112
+ <p className="flex items-center gap-1.5 text-xs font-semibold uppercase tracking-wide text-muted-foreground">
113
+ {done ? null : <Icon name="shield-check" size={12} className="shrink-0" />}
114
+ {kicker}
115
+ </p>
116
+ ) : null}
117
+ {title ? <p className="break-words text-[15px] font-semibold leading-snug">{title}</p> : null}
118
+ </div>
119
+ {cost ? <div className="shrink-0 pt-0.5 text-xs text-muted-foreground">{cost}</div> : null}
120
+ </div>
121
+ </div>
122
+ );
123
+
124
+ return (
125
+ <section
126
+ aria-label={typeof title === "string" ? title : "Waiting for your yes"}
127
+ className={cx("@container grid grid-cols-1 min-w-0 content-start gap-3 rounded-lg border border-border bg-card p-3.5 text-sm text-card-foreground", className)}
128
+ >
129
+ {head}
130
+ {children != null && children !== "" ? <div className={cx("min-w-0 break-words", done && "text-muted-foreground")}>{children}</div> : null}
131
+
132
+ {state === "approved" ? (
133
+ <Receipt icon="check" tone="text-success" head="You said yes · the agent is on it">
134
+ {approval?.always ? "Always allowed for this kind. It will not ask again for the same." : null}
135
+ </Receipt>
136
+ ) : state === "declined" ? (
137
+ <Receipt icon="x" tone="text-muted-foreground" head="Not now. Nothing went out." />
138
+ ) : state === "gone" ? (
139
+ <Receipt icon="check" tone="text-muted-foreground" head="This has been answered." />
140
+ ) : state === "stale" ? (
141
+ <p role="status" className="flex items-center gap-2 text-muted-foreground">
142
+ <Spinner size="sm" label="Looking again" /> This changed since the card was drawn. Looking again…
143
+ </p>
144
+ ) : approval?.frame ? (
145
+ <iframe
146
+ ref={approval.frame.ref}
147
+ src={approval.frame.src}
148
+ srcDoc={approval.frame.srcDoc}
149
+ title={approval.frame.title ?? "Approve"}
150
+ scrolling="no"
151
+ className="block w-full border-0 bg-transparent"
152
+ style={{ height: approval.height ?? FRAME_HEIGHT }}
153
+ />
154
+ ) : null}
155
+ {state === "ready" && approval?.error ? <p className="text-xs text-destructive">{approval.error}</p> : null}
156
+ {state === "gone" && onOpenDesk ? (
157
+ <Button size="sm" variant="quiet" className="justify-self-start" onClick={onOpenDesk}>
158
+ Open it on the desk
159
+ </Button>
160
+ ) : null}
161
+ </section>
162
+ );
163
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "approval",
3
+ "title": "Approval",
4
+ "description": "The yes, given in the app. The app draws the card in its own theme — what will happen, to whom, the exact words, the cost — and under it sits the press: a small Makersclaw-origin frame, in the app's colours, that app code cannot script. It shows the server's own words for the request (the agent's question, who, from which account, the first message, the rule \"Always allow this kind\" would save) and only counts a press a person made on a card they can see. Fed by useApproval(requestId) (lib/hooks.js). If the frame cannot load or the member must sign in again, the card falls back to WaitingYes: \"Waiting for your yes on the desk\".",
5
+ "useWhen": "Anywhere the agent is about to do something public or paid and waits for the member's yes — a send, a post, a purchase: put the app's own card (the draft, the recipients, the cost) inside it, give it useApproval(item.id) for the request that waits, and the member says yes without leaving the app. For the queue of everything that waits use needs-you; for the conversation, agent-chat.",
6
+ "tags": [
7
+ "approval",
8
+ "approve",
9
+ "yes",
10
+ "send",
11
+ "confirm",
12
+ "needs you",
13
+ "agent",
14
+ "trust",
15
+ "always allow",
16
+ "rule",
17
+ "desk",
18
+ "publish",
19
+ "spend"
20
+ ],
21
+ "exports": [
22
+ "Approval"
23
+ ],
24
+ "files": [
25
+ "index.js",
26
+ "approval.jsx"
27
+ ],
28
+ "requires": [
29
+ "needs-you"
30
+ ]
31
+ }
@@ -0,0 +1,121 @@
1
+ "use client";
2
+
3
+ // Approval in every state, with fake data shaped as useApproval() returns
4
+ // it — the gallery's and the smoke test's surface. Not installed into
5
+ // apps. The press frame is a page of Makersclaw's in another origin; here
6
+ // a stand-in of the same shape (`srcDoc`) takes its place, so the card's
7
+ // layout can be looked at at every width.
8
+ import { useEffect, useRef, useState } from "react";
9
+ import { Approval } from "../components/blocks/approval";
10
+
11
+ // Inline styles and the browser's own colour names only: the check refuses
12
+ // a hex, a colour function or a <style> tag in a surface, and this is a
13
+ // stand-in, not a design.
14
+ const BOX = "border:1px solid GrayText;border-radius:10px;padding:12px 14px;display:flex;flex-direction:column;gap:10px";
15
+ const BTN = "font:inherit;font-weight:600;padding:8px 14px;border-radius:8px;border:1px solid GrayText;background:transparent;color:inherit;min-height:36px";
16
+ const standIn = (scheme) =>
17
+ `<!doctype html><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="${scheme}">` +
18
+ `<body style="margin:0;background:transparent;font:14px/1.45 system-ui,sans-serif">` +
19
+ `<main style="${BOX}"><span style="font-size:11px;letter-spacing:.06em;text-transform:uppercase;opacity:.65">Waiting for your yes</span>` +
20
+ `<p style="margin:0;font-size:15px;font-weight:600">Send 3 follow-ups from ada@acme.com to the Replies list?</p>` +
21
+ `<div style="display:grid;grid-template-columns:auto 1fr;gap:2px 10px;font-size:13px"><span style="opacity:.65">To</span><span>3 investors on the Replies list</span>` +
22
+ `<span style="opacity:.65">From</span><span>ada@acme.com</span><span style="opacity:.65">First to</span><span>Maya Chen</span></div>` +
23
+ `<pre style="margin:0;padding:8px 10px;border-radius:8px;border:1px solid GrayText;font:13px/1.4 inherit;white-space:pre-wrap">Hi Maya, a short note on where we are&hellip;</pre>` +
24
+ `<label style="display:flex;gap:8px;font-size:13px"><input type="checkbox"><span>Always allow this kind: Send messages like &ldquo;Quick question about Northwind&rdquo; to the Replies list, from ada@acme.com.</span></label>` +
25
+ `<div style="display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap"><button style="${BTN}">Not now</button><button style="${BTN};background:Highlight;color:HighlightText;border-color:transparent">Send 3</button></div></main>`;
26
+
27
+ // The real frame wears the app's theme sheet, whose :root names the same
28
+ // colour scheme as the page around it, so its transparent ground stays
29
+ // transparent. The stand-in reads the page's scheme for the same reason.
30
+ function useScheme() {
31
+ const [scheme, setScheme] = useState("light dark");
32
+ useEffect(() => {
33
+ const read = getComputedStyle(document.documentElement).colorScheme;
34
+ if (read && read !== "normal") setScheme(read);
35
+ }, []);
36
+ return scheme;
37
+ }
38
+
39
+ const FACTS = {
40
+ request_id: "r1",
41
+ question: "Send 3 follow-ups from ada@acme.com to the Replies list?",
42
+ label: "Send 3",
43
+ covers: null,
44
+ always: "Send messages like “Quick question about Northwind” to the Replies list, from ada@acme.com.",
45
+ cap_credits: null,
46
+ at: "t1",
47
+ };
48
+
49
+ /** What useApproval() returns, for a state. */
50
+ function fake(state, scheme, over = {}) {
51
+ const ref = useRef(null);
52
+ const framed = state === "ready";
53
+ return {
54
+ approval: FACTS,
55
+ state,
56
+ always: false,
57
+ fallback: state === "signin" || state === "blocked" || state === "unavailable" || state === "error",
58
+ frame: framed ? { src: undefined, srcDoc: standIn(scheme), ref, title: "Approve" } : null,
59
+ height: 440,
60
+ loading: state === "loading",
61
+ error: null,
62
+ code: null,
63
+ unavailable: state === "unavailable",
64
+ reload: () => {},
65
+ ...over,
66
+ };
67
+ }
68
+
69
+ const DRAFT = (
70
+ <div className="grid gap-2">
71
+ <p className="text-muted-foreground">3 follow-ups, ready to go</p>
72
+ <ul className="grid gap-1 pl-4 [list-style:disc]">
73
+ <li>Maya Chen · Northwind</li>
74
+ <li>Priya Nair · Harbor Seed</li>
75
+ <li>Tom Osei · Coastline</li>
76
+ </ul>
77
+ <p className="whitespace-pre-wrap rounded-[var(--radius)] bg-muted p-2.5">{"Hi Maya,\n\nA short note on where we are after the demo. Happy to answer anything before Friday."}</p>
78
+ </div>
79
+ );
80
+
81
+ export default function ApprovalDemo() {
82
+ const scheme = useScheme();
83
+ const ready = fake("ready", scheme);
84
+ const approved = fake("approved", scheme, { always: true });
85
+ const declined = fake("declined", scheme);
86
+ const stale = fake("stale", scheme);
87
+ const gone = fake("gone", scheme);
88
+ const loading = fake("loading", scheme);
89
+ const signin = fake("signin", scheme);
90
+ const blocked = fake("blocked", scheme);
91
+ const unavailable = fake("unavailable", scheme);
92
+ return (
93
+ <div className="grid gap-4 p-6 [grid-template-columns:repeat(auto-fit,minmax(min(100%,22rem),1fr))]">
94
+ <Approval approval={ready} title="Send 3 follow-ups" cost={<span>about 12 cr</span>} onOpenDesk={() => true}>
95
+ {DRAFT}
96
+ </Approval>
97
+ <Approval approval={approved} title="Send 3 follow-ups">
98
+ {DRAFT}
99
+ </Approval>
100
+ <Approval approval={declined} title="Send 3 follow-ups">
101
+ {DRAFT}
102
+ </Approval>
103
+ <Approval approval={stale} title="Send 3 follow-ups">
104
+ {DRAFT}
105
+ </Approval>
106
+ <Approval approval={gone} title="Send 3 follow-ups" onOpenDesk={() => true}>
107
+ {DRAFT}
108
+ </Approval>
109
+ <Approval approval={loading} title="Send 3 follow-ups" />
110
+ <Approval approval={signin} title="Send 3 follow-ups" onOpenDesk={() => true}>
111
+ {DRAFT}
112
+ </Approval>
113
+ <Approval approval={blocked} title="Send 3 follow-ups" onOpenDesk={() => true}>
114
+ {DRAFT}
115
+ </Approval>
116
+ <Approval approval={unavailable} title="Send 3 follow-ups">
117
+ {DRAFT}
118
+ </Approval>
119
+ </div>
120
+ );
121
+ }
@@ -0,0 +1,3 @@
1
+ // The Approval block — `makersclaw add approval`. Fixed: compose it
2
+ // through its props (README.md beside this file).
3
+ export { Approval } from "./approval";
@@ -0,0 +1,105 @@
1
+ # AskBar
2
+
3
+ One line to ask the app's agent, in the app's look. Chips under it offer
4
+ asks that fit the moment; a chip sends its words. Long chips wrap; they
5
+ never run off the screen.
6
+
7
+ After a send the bar says where the ask stands, in one line:
8
+
9
+ - "Working…" while the agent is on it;
10
+ - "Waiting for you" when it needs the member's yes or answer;
11
+ - "Answered", "Stopped", or "It didn't finish".
12
+
13
+ Beside the line, **Open** shows the conversation. Where it shows is the
14
+ screen's choice: a `Sheet` with the `agent-chat` block, the inspector,
15
+ a side column. When the agent waits on a question or a yes the app can
16
+ settle (`chat.needs.in_app` is `"answer"` or `"press"`), Open shows that
17
+ chat, where the answer is given (`agent-chat`) and the yes is pressed
18
+ (`approval`). A need the app cannot settle goes to the desk instead
19
+ (`chat.openOnDesk()`).
20
+
21
+ It is a door into the conversation, not the conversation. The thread is
22
+ the same one `agent-chat` and the desk's agent column draw.
23
+
24
+ ```jsx
25
+ import { AskBar } from "../components/blocks/ask-bar"; // a Makersclaw app ("./blocks/ask-bar" from components/)
26
+ import { AskBar } from "@/components/makersclaw/blocks/ask-bar"; // a shadcn project
27
+ ```
28
+
29
+ A client component. The Example is at the end.
30
+
31
+ ## Props
32
+
33
+ - `chat` — what `useAgentThread()` returns (lib/hooks.js). A send calls
34
+ `chat.send(text)`; the line reads `chat.state`, the last ask from
35
+ `chat.turns` or `chat.pending`, and `chat.error`.
36
+ - `onAsk(text)` — instead of `chat`: your own sender. It may be async; an
37
+ answer of `{ ok: false, error }` (or a throw) shows its words under the
38
+ bar.
39
+ - `state` — with `onAsk` only: where your ask stands, in
40
+ `useAgentThread`'s words (`queued` · `working` · `needs_you` · `done` ·
41
+ `stopped` · `failed`).
42
+ - `suggestions` — asks that fit the moment, as chips. Say them in the
43
+ app's words ("Who should I call today?").
44
+ - `placeholder` — the box's words. Default "Ask the agent…".
45
+ - `label` — the box's name for a screen reader. Default "Ask the agent".
46
+ - `onOpen()` — shows the conversation. Without it there is no Open.
47
+ - `openOnSend` — `true`: a send also calls `onOpen`, so the chat opens at
48
+ once.
49
+ - `className` — layout around it. Never colour.
50
+
51
+ ## Which hook feeds it
52
+
53
+ `useAgentThread({ row, how, key })` (lib/hooks.js) over
54
+ `POST _claw/ask` and `GET _claw/threads/<session>`. Give the same `row`
55
+ the chat on the same screen gets, and both draw one thread.
56
+
57
+ ## Who may do what
58
+
59
+ Any member who can open the app may ask. Each member sees only their own
60
+ thread. Stop lives in the chat (`agent-chat`), not here.
61
+
62
+ ## Never
63
+
64
+ - **Never an Approve.** The yes is the `approval` block's frame, which the
65
+ app's code cannot press. The bar says "Waiting for you" and Open shows
66
+ the chat that holds it.
67
+ - Never answer the agent's question here: that is the chat's
68
+ `QuestionBox`.
69
+ - Never show the agent's answer in the bar. One line of state, then Open.
70
+
71
+ ## Outside Makersclaw
72
+
73
+ Any object of the same shape works: `state`, `turns` (`[{ member }]`),
74
+ `pending`, `error`, `unavailable`, `send(text)` and `openOnDesk()`. Or
75
+ use `onAsk` and `state`.
76
+
77
+ ## Example
78
+
79
+ A home screen with the ask on top and the chat in a sheet.
80
+
81
+ ```jsx
82
+ "use client";
83
+ import { useState } from "react";
84
+ import { Sheet } from "../components/ui";
85
+ import { useAgentThread } from "../lib/hooks";
86
+ import { AskBar } from "../components/blocks/ask-bar";
87
+ import { AgentChat } from "../components/blocks/agent-chat";
88
+
89
+ export default function Today() {
90
+ const [open, setOpen] = useState(false);
91
+ const chat = useAgentThread({ key: "today" });
92
+ return (
93
+ <>
94
+ <AskBar
95
+ chat={chat}
96
+ suggestions={["Who should I call today?", "What changed since Friday?"]}
97
+ onOpen={() => setOpen(true)}
98
+ />
99
+ <Sheet open={open} onClose={() => setOpen(false)} title="Ask the agent">
100
+ <AgentChat chat={chat} bare />
101
+ </Sheet>
102
+ </>
103
+ );
104
+ }
105
+ ```