makersclaw 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (419) hide show
  1. package/README.md +17 -4
  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 +4 -4
  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 +5 -5
  26. package/r/chat-pane.json +84 -0
  27. package/r/chat.json +3 -3
  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 +18 -6
  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 +3 -3
  46. package/r/flow-editor.json +79 -0
  47. package/r/footer.json +3 -3
  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 +4 -4
  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 +4 -4
  60. package/r/pace-bar.json +69 -0
  61. package/r/page-builder.json +3 -3
  62. package/r/payment-methods.json +2 -2
  63. package/r/pdf-document.json +2 -2
  64. package/r/pdf-viewer.json +3 -3
  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 +4089 -1510
  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 +3 -3
  82. package/r/signature-pad.json +2 -2
  83. package/r/sketch-canvas.json +3 -3
  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 +4 -4
  101. package/r/workflow-view.json +55 -0
  102. package/registry/blocks/activity-log/README.md +112 -0
  103. package/registry/blocks/activity-log/activity-log.jsx +351 -0
  104. package/registry/blocks/activity-log/block.json +33 -0
  105. package/registry/blocks/activity-log/demo.jsx +48 -0
  106. package/registry/blocks/activity-log/index.js +4 -0
  107. package/registry/blocks/agent-changes/README.md +94 -0
  108. package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
  109. package/registry/blocks/agent-changes/block.json +28 -0
  110. package/registry/blocks/agent-changes/demo.jsx +39 -0
  111. package/registry/blocks/agent-changes/index.js +3 -0
  112. package/registry/blocks/agent-chat/README.md +145 -0
  113. package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
  114. package/registry/blocks/agent-chat/block.json +30 -0
  115. package/registry/blocks/agent-chat/demo.jsx +165 -0
  116. package/registry/blocks/agent-chat/index.js +3 -0
  117. package/registry/blocks/agent-column/README.md +197 -0
  118. package/registry/blocks/agent-column/agent-column.jsx +492 -0
  119. package/registry/blocks/agent-column/block.json +67 -0
  120. package/registry/blocks/agent-column/column-picker.jsx +163 -0
  121. package/registry/blocks/agent-column/demo.jsx +50 -0
  122. package/registry/blocks/agent-column/index.js +7 -0
  123. package/registry/blocks/agent-column/model.js +164 -0
  124. package/registry/blocks/agent-column/receipt.jsx +483 -0
  125. package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
  126. package/registry/blocks/agent-dock/README.md +210 -0
  127. package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
  128. package/registry/blocks/agent-dock/block.json +47 -0
  129. package/registry/blocks/agent-dock/demo.jsx +153 -0
  130. package/registry/blocks/agent-dock/dock-model.js +118 -0
  131. package/registry/blocks/agent-dock/index.js +5 -0
  132. package/registry/blocks/agent-kit/README.md +73 -0
  133. package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
  134. package/registry/blocks/agent-kit/block.json +10 -0
  135. package/registry/blocks/agent-kit/demo.jsx +35 -0
  136. package/registry/blocks/agent-kit/index.js +3 -0
  137. package/registry/blocks/agent-marks/README.md +80 -0
  138. package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
  139. package/registry/blocks/agent-marks/block.json +27 -0
  140. package/registry/blocks/agent-marks/demo.jsx +49 -0
  141. package/registry/blocks/agent-marks/index.js +3 -0
  142. package/registry/blocks/agent-pane/README.md +225 -0
  143. package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
  144. package/registry/blocks/agent-pane/block.json +41 -0
  145. package/registry/blocks/agent-pane/composer.jsx +6 -0
  146. package/registry/blocks/agent-pane/demo.jsx +233 -0
  147. package/registry/blocks/agent-pane/dock-context.js +10 -0
  148. package/registry/blocks/agent-pane/index.js +4 -0
  149. package/registry/blocks/agent-pane/prose.jsx +84 -0
  150. package/registry/blocks/agent-pane/questions.jsx +134 -0
  151. package/registry/blocks/agent-pane/transcript.jsx +268 -0
  152. package/registry/blocks/agent-pane/work.jsx +368 -0
  153. package/registry/blocks/ai-action/README.md +94 -0
  154. package/registry/blocks/ai-action/ai-action.jsx +188 -0
  155. package/registry/blocks/ai-action/block.json +34 -0
  156. package/registry/blocks/ai-action/demo.jsx +93 -0
  157. package/registry/blocks/ai-action/index.js +3 -0
  158. package/registry/blocks/annotate/README.md +14 -11
  159. package/registry/blocks/approval/README.md +145 -0
  160. package/registry/blocks/approval/approval.jsx +163 -0
  161. package/registry/blocks/approval/block.json +31 -0
  162. package/registry/blocks/approval/demo.jsx +121 -0
  163. package/registry/blocks/approval/index.js +3 -0
  164. package/registry/blocks/ask-bar/README.md +105 -0
  165. package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
  166. package/registry/blocks/ask-bar/block.json +26 -0
  167. package/registry/blocks/ask-bar/demo.jsx +78 -0
  168. package/registry/blocks/ask-bar/index.js +3 -0
  169. package/registry/blocks/automation-editor/README.md +291 -0
  170. package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
  171. package/registry/blocks/automation-editor/block.json +39 -0
  172. package/registry/blocks/automation-editor/demo.jsx +284 -0
  173. package/registry/blocks/automation-editor/index.js +4 -0
  174. package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
  175. package/registry/blocks/automation-list/README.md +129 -0
  176. package/registry/blocks/automation-list/automation-list.jsx +476 -0
  177. package/registry/blocks/automation-list/block.json +35 -0
  178. package/registry/blocks/automation-list/demo.jsx +67 -0
  179. package/registry/blocks/automation-list/index.js +3 -0
  180. package/registry/blocks/automation-model/README.md +109 -0
  181. package/registry/blocks/automation-model/block.json +135 -0
  182. package/registry/blocks/automation-model/catalog.js +256 -0
  183. package/registry/blocks/automation-model/check.js +161 -0
  184. package/registry/blocks/automation-model/demo.jsx +42 -0
  185. package/registry/blocks/automation-model/edit.js +262 -0
  186. package/registry/blocks/automation-model/fixes.js +287 -0
  187. package/registry/blocks/automation-model/glyph.jsx +13 -0
  188. package/registry/blocks/automation-model/graph.js +410 -0
  189. package/registry/blocks/automation-model/index.js +33 -0
  190. package/registry/blocks/automation-model/overlay.js +175 -0
  191. package/registry/blocks/automation-model/parts.jsx +94 -0
  192. package/registry/blocks/automation-model/schedule.js +53 -0
  193. package/registry/blocks/automation-model/templates.js +128 -0
  194. package/registry/blocks/automation-model/values.js +29 -0
  195. package/registry/blocks/automation-model/words.js +439 -0
  196. package/registry/blocks/automations-screen/README.md +207 -0
  197. package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
  198. package/registry/blocks/automations-screen/block.json +47 -0
  199. package/registry/blocks/automations-screen/demo.jsx +364 -0
  200. package/registry/blocks/automations-screen/index.js +4 -0
  201. package/registry/blocks/automations-screen/screen-model.js +129 -0
  202. package/registry/blocks/chart/cartesian.jsx +1 -1
  203. package/registry/blocks/chart/core.jsx +33 -23
  204. package/registry/blocks/chart/pie.jsx +1 -1
  205. package/registry/blocks/chat/README.md +4 -1
  206. package/registry/blocks/chat/demo.jsx +2 -2
  207. package/registry/blocks/chat-pane/README.md +143 -0
  208. package/registry/blocks/chat-pane/block.json +48 -0
  209. package/registry/blocks/chat-pane/chat-attach.js +166 -0
  210. package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
  211. package/registry/blocks/chat-pane/chat-context.js +17 -0
  212. package/registry/blocks/chat-pane/chat-model.js +43 -0
  213. package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
  214. package/registry/blocks/chat-pane/chats-list.jsx +52 -0
  215. package/registry/blocks/chat-pane/demo.jsx +103 -0
  216. package/registry/blocks/chat-pane/index.js +9 -0
  217. package/registry/blocks/connect-card/README.md +99 -0
  218. package/registry/blocks/connect-card/block.json +10 -0
  219. package/registry/blocks/connect-card/connect-card.jsx +103 -0
  220. package/registry/blocks/connect-card/demo.jsx +49 -0
  221. package/registry/blocks/connect-card/index.js +3 -0
  222. package/registry/blocks/cost/README.md +115 -0
  223. package/registry/blocks/cost/block.json +10 -0
  224. package/registry/blocks/cost/cost.jsx +176 -0
  225. package/registry/blocks/cost/demo.jsx +66 -0
  226. package/registry/blocks/cost/index.js +3 -0
  227. package/registry/blocks/data-picker/README.md +81 -0
  228. package/registry/blocks/data-picker/block.json +38 -0
  229. package/registry/blocks/data-picker/data-picker.jsx +210 -0
  230. package/registry/blocks/data-picker/demo.jsx +34 -0
  231. package/registry/blocks/data-picker/fields.js +89 -0
  232. package/registry/blocks/data-picker/index.js +4 -0
  233. package/registry/blocks/data-table/demo.jsx +1 -1
  234. package/registry/blocks/first-run/README.md +118 -0
  235. package/registry/blocks/first-run/block.json +11 -0
  236. package/registry/blocks/first-run/demo.jsx +88 -0
  237. package/registry/blocks/first-run/first-run-model.js +51 -0
  238. package/registry/blocks/first-run/first-run.jsx +156 -0
  239. package/registry/blocks/first-run/index.js +5 -0
  240. package/registry/blocks/first-run/probe-rules.js +26 -0
  241. package/registry/blocks/fix-note/README.md +79 -0
  242. package/registry/blocks/fix-note/block.json +35 -0
  243. package/registry/blocks/fix-note/demo.jsx +30 -0
  244. package/registry/blocks/fix-note/fix-note.jsx +235 -0
  245. package/registry/blocks/fix-note/index.js +3 -0
  246. package/registry/blocks/flow-canvas/README.md +15 -8
  247. package/registry/blocks/flow-editor/README.md +108 -0
  248. package/registry/blocks/flow-editor/block.json +44 -0
  249. package/registry/blocks/flow-editor/demo.jsx +115 -0
  250. package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
  251. package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
  252. package/registry/blocks/flow-editor/index.js +6 -0
  253. package/registry/blocks/flow-editor/minimap.jsx +78 -0
  254. package/registry/blocks/flow-editor/outline.jsx +134 -0
  255. package/registry/blocks/footer/README.md +3 -2
  256. package/registry/blocks/library-shelf/README.md +117 -0
  257. package/registry/blocks/library-shelf/block.json +28 -0
  258. package/registry/blocks/library-shelf/demo.jsx +68 -0
  259. package/registry/blocks/library-shelf/index.js +3 -0
  260. package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
  261. package/registry/blocks/library-shelf/probe-rules.js +15 -0
  262. package/registry/blocks/margin-notes/README.md +222 -0
  263. package/registry/blocks/margin-notes/block.json +10 -0
  264. package/registry/blocks/margin-notes/demo.jsx +144 -0
  265. package/registry/blocks/margin-notes/index.js +20 -0
  266. package/registry/blocks/margin-notes/margin-model.js +224 -0
  267. package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
  268. package/registry/blocks/mind-map/README.md +4 -2
  269. package/registry/blocks/needs-you/README.md +177 -0
  270. package/registry/blocks/needs-you/block.json +34 -0
  271. package/registry/blocks/needs-you/demo.jsx +143 -0
  272. package/registry/blocks/needs-you/index.js +3 -0
  273. package/registry/blocks/needs-you/needs-you.jsx +441 -0
  274. package/registry/blocks/org-chart/README.md +4 -2
  275. package/registry/blocks/pace-bar/README.md +230 -0
  276. package/registry/blocks/pace-bar/block.json +10 -0
  277. package/registry/blocks/pace-bar/demo.jsx +255 -0
  278. package/registry/blocks/pace-bar/index.js +22 -0
  279. package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
  280. package/registry/blocks/pace-bar/pace-model.js +288 -0
  281. package/registry/blocks/page-builder/README.md +1 -1
  282. package/registry/blocks/page-builder/demo.jsx +3 -3
  283. package/registry/blocks/pdf-viewer/README.md +4 -1
  284. package/registry/blocks/record-grid/README.md +100 -0
  285. package/registry/blocks/record-grid/block.json +28 -0
  286. package/registry/blocks/record-grid/demo.jsx +43 -0
  287. package/registry/blocks/record-grid/index.js +3 -0
  288. package/registry/blocks/record-grid/record-grid.jsx +251 -0
  289. package/registry/blocks/run-history/README.md +138 -0
  290. package/registry/blocks/run-history/block.json +10 -0
  291. package/registry/blocks/run-history/demo.jsx +74 -0
  292. package/registry/blocks/run-history/index.js +3 -0
  293. package/registry/blocks/run-history/run-history.jsx +218 -0
  294. package/registry/blocks/run-view/README.md +174 -0
  295. package/registry/blocks/run-view/block.json +50 -0
  296. package/registry/blocks/run-view/demo.jsx +286 -0
  297. package/registry/blocks/run-view/index.js +5 -0
  298. package/registry/blocks/run-view/run-controls.jsx +266 -0
  299. package/registry/blocks/run-view/run-view.jsx +236 -0
  300. package/registry/blocks/run-view/runs-list.jsx +99 -0
  301. package/registry/blocks/schedule-card/README.md +121 -0
  302. package/registry/blocks/schedule-card/block.json +10 -0
  303. package/registry/blocks/schedule-card/demo.jsx +82 -0
  304. package/registry/blocks/schedule-card/index.js +3 -0
  305. package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
  306. package/registry/blocks/schedule-engine/README.md +137 -0
  307. package/registry/blocks/schedule-engine/block.json +10 -0
  308. package/registry/blocks/schedule-engine/demo.jsx +82 -0
  309. package/registry/blocks/schedule-engine/engine.js +769 -0
  310. package/registry/blocks/schedule-engine/index.js +9 -0
  311. package/registry/blocks/schedule-engine/ops.js +71 -0
  312. package/registry/blocks/schedule-engine/place.js +294 -0
  313. package/registry/blocks/schedule-engine/tree.js +79 -0
  314. package/registry/blocks/schedule-engine/waits.js +80 -0
  315. package/registry/blocks/schedule-gantt/README.md +159 -0
  316. package/registry/blocks/schedule-gantt/block.json +10 -0
  317. package/registry/blocks/schedule-gantt/demo.jsx +223 -0
  318. package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
  319. package/registry/blocks/schedule-gantt/geometry.js +176 -0
  320. package/registry/blocks/schedule-gantt/index.js +26 -0
  321. package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
  322. package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
  323. package/registry/blocks/schedule-gantt/track.jsx +190 -0
  324. package/registry/blocks/schedule-ruler/README.md +148 -0
  325. package/registry/blocks/schedule-ruler/block.json +10 -0
  326. package/registry/blocks/schedule-ruler/demo.jsx +181 -0
  327. package/registry/blocks/schedule-ruler/index.js +21 -0
  328. package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
  329. package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
  330. package/registry/blocks/sidebar/README.md +23 -13
  331. package/registry/blocks/sketch-canvas/README.md +15 -9
  332. package/registry/blocks/source-receipt/README.md +97 -0
  333. package/registry/blocks/source-receipt/block.json +30 -0
  334. package/registry/blocks/source-receipt/demo.jsx +71 -0
  335. package/registry/blocks/source-receipt/index.js +3 -0
  336. package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
  337. package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
  338. package/registry/blocks/step-picker/README.md +78 -0
  339. package/registry/blocks/step-picker/block.json +31 -0
  340. package/registry/blocks/step-picker/demo.jsx +23 -0
  341. package/registry/blocks/step-picker/index.js +3 -0
  342. package/registry/blocks/step-picker/step-picker.jsx +144 -0
  343. package/registry/blocks/step-settings/README.md +100 -0
  344. package/registry/blocks/step-settings/block.json +44 -0
  345. package/registry/blocks/step-settings/demo.jsx +93 -0
  346. package/registry/blocks/step-settings/fields.jsx +58 -0
  347. package/registry/blocks/step-settings/flow-settings.jsx +115 -0
  348. package/registry/blocks/step-settings/index.js +5 -0
  349. package/registry/blocks/step-settings/step-settings.jsx +290 -0
  350. package/registry/blocks/suggestion/README.md +171 -0
  351. package/registry/blocks/suggestion/block.json +40 -0
  352. package/registry/blocks/suggestion/demo.jsx +91 -0
  353. package/registry/blocks/suggestion/index.js +3 -0
  354. package/registry/blocks/suggestion/suggestion.jsx +436 -0
  355. package/registry/blocks/sum-bar/README.md +122 -0
  356. package/registry/blocks/sum-bar/block.json +10 -0
  357. package/registry/blocks/sum-bar/demo.jsx +110 -0
  358. package/registry/blocks/sum-bar/index.js +5 -0
  359. package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
  360. package/registry/blocks/sum-bar/sum-model.js +126 -0
  361. package/registry/blocks/tier-map/README.md +217 -0
  362. package/registry/blocks/tier-map/block.json +10 -0
  363. package/registry/blocks/tier-map/demo.jsx +222 -0
  364. package/registry/blocks/tier-map/index.js +24 -0
  365. package/registry/blocks/tier-map/tier-map.jsx +574 -0
  366. package/registry/blocks/tier-map/tier-model.js +318 -0
  367. package/registry/blocks/time-grid/README.md +305 -0
  368. package/registry/blocks/time-grid/block.json +10 -0
  369. package/registry/blocks/time-grid/demo.jsx +279 -0
  370. package/registry/blocks/time-grid/grid-model.js +322 -0
  371. package/registry/blocks/time-grid/index.js +25 -0
  372. package/registry/blocks/time-grid/time-grid.jsx +1325 -0
  373. package/registry/blocks/time-strip/README.md +141 -0
  374. package/registry/blocks/time-strip/block.json +10 -0
  375. package/registry/blocks/time-strip/demo.jsx +129 -0
  376. package/registry/blocks/time-strip/index.js +19 -0
  377. package/registry/blocks/time-strip/strip-model.js +178 -0
  378. package/registry/blocks/time-strip/time-strip.jsx +260 -0
  379. package/registry/blocks/top-bar/README.md +149 -0
  380. package/registry/blocks/top-bar/block.json +35 -0
  381. package/registry/blocks/top-bar/demo.jsx +78 -0
  382. package/registry/blocks/top-bar/index.js +5 -0
  383. package/registry/blocks/top-bar/probe-rules.js +74 -0
  384. package/registry/blocks/top-bar/top-bar-model.js +152 -0
  385. package/registry/blocks/top-bar/top-bar.jsx +244 -0
  386. package/registry/blocks/trigger-picker/README.md +98 -0
  387. package/registry/blocks/trigger-picker/block.json +38 -0
  388. package/registry/blocks/trigger-picker/demo.jsx +59 -0
  389. package/registry/blocks/trigger-picker/index.js +3 -0
  390. package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
  391. package/registry/blocks/whiteboard/README.md +20 -14
  392. package/registry/blocks/workflow-view/README.md +123 -0
  393. package/registry/blocks/workflow-view/block.json +10 -0
  394. package/registry/blocks/workflow-view/demo.jsx +90 -0
  395. package/registry/blocks/workflow-view/index.js +3 -0
  396. package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
  397. package/src/cli.mjs +2 -2
  398. package/src/install.mjs +100 -22
  399. package/src/registry.mjs +37 -3
  400. package/templates/next/browser/lib/data.js +6 -1
  401. package/templates/next/files/README.md +909 -26
  402. package/templates/next/files/app/shell.jsx +54 -37
  403. package/templates/next/files/check/automation-format.ts +2103 -0
  404. package/templates/next/files/check/automation-package.ts +142 -0
  405. package/templates/next/files/check/run.mjs +1043 -12
  406. package/templates/next/files/components/ui/field.jsx +17 -4
  407. package/templates/next/files/components/ui/icon.jsx +13 -0
  408. package/templates/next/files/components/ui/index.js +3 -1
  409. package/templates/next/files/components/ui/layout.jsx +382 -0
  410. package/templates/next/files/components/ui/notice.jsx +70 -0
  411. package/templates/next/files/components/ui/page.jsx +124 -0
  412. package/templates/next/files/components/ui/stat.jsx +22 -7
  413. package/templates/next/files/components/ui/toast.jsx +6 -3
  414. package/templates/next/files/lib/automations.js +660 -0
  415. package/templates/next/files/lib/claw.js +244 -5
  416. package/templates/next/files/lib/door.js +92 -0
  417. package/templates/next/files/lib/hooks.js +1694 -6
  418. package/templates/next/files/lib/platform.js +611 -14
  419. package/templates/next/template.json +22 -3
@@ -0,0 +1,318 @@
1
+ // The tier map's data and arithmetic — plain functions, no React, no DOM.
2
+ // They run anywhere (the server, an agent's tool, a test).
3
+ //
4
+ // Items come in flat, the way a table holds them: each row names its
5
+ // parent. buildTierModel turns them into a forest and sorts every item into
6
+ // one of three places:
7
+ //
8
+ // tree reachable from a top: drawn in tiers, one layer open at a time
9
+ // unparented real (not a draft), not reachable from any top
10
+ // ghost a draft (`ghost: true`): drawn apart, dashed, never counted
11
+ //
12
+ // A parent that is not in the list is no parent. A loop of parents is
13
+ // broken at the item that comes first in the list, which becomes parentless.
14
+ // Nothing here hangs on bad data.
15
+
16
+ /** Equal columns of this many rem, at least, are what a tier needs to sit in one row. */
17
+ export const CARD_REM = 11;
18
+ /** A tier of more cards than this never sits in one row; it stacks. */
19
+ export const MAX_COLUMNS = 8;
20
+
21
+ /**
22
+ * The key a tier's layout classes are looked up by: how many equal columns
23
+ * the widest tier so far needs, 1 to MAX_COLUMNS, or NEVER when a tier has
24
+ * too many cards to sit in one row.
25
+ */
26
+ export const NEVER = MAX_COLUMNS + 1;
27
+ export function fitKey(count) {
28
+ const n = Math.floor(Number(count));
29
+ if (!(n > 1)) return 1;
30
+ return n > MAX_COLUMNS ? NEVER : n;
31
+ }
32
+
33
+ /** The container width, in rem, from which a tier of this fit key sits in one row (Infinity: never). */
34
+ export function thresholdRem(key) {
35
+ if (key >= NEVER) return Infinity;
36
+ return key <= 1 ? 0 : key * CARD_REM;
37
+ }
38
+
39
+ const idOf = (value) => (value == null || value === "" ? null : String(value));
40
+
41
+ /**
42
+ * Flat items to a model.
43
+ *
44
+ * items [{ id, parent?, ghost?, ... }]; any other key is kept on `item`
45
+ * tops ids drawn as the first tier, in that order. Default: the real
46
+ * items that have no parent and have children.
47
+ *
48
+ * Returns { nodes, order, tops, unparented, ghostRoots, ghostOrder }.
49
+ * A node is { id, item, ghost, parent, up, kids, tier, group, total }:
50
+ * parent the id it names, after bad ones and loops are dropped (or null)
51
+ * up who it hangs under on screen (null for a top, an unparented card)
52
+ * kids ids drawn under it when it is opened (a draft's kids are drafts)
53
+ * tier 0 for a top, 1 for its kids… (-1 for what is not in the tree)
54
+ * group "tree" | "unparented" | "ghost"
55
+ * total everything under it, counting kids of kids
56
+ */
57
+ export function buildTierModel(items, { tops } = {}) {
58
+ const nodes = new Map();
59
+ const order = [];
60
+ for (const item of Array.isArray(items) ? items : []) {
61
+ const id = idOf(item?.id);
62
+ if (id == null || nodes.has(id)) continue;
63
+ nodes.set(id, { id, item, ghost: item.ghost === true, parent: null, up: null, kids: [], tier: -1, group: "unparented", total: 0 });
64
+ order.push(id);
65
+ }
66
+
67
+ // The parent each item names, if it is somebody in the list and not itself.
68
+ for (const id of order) {
69
+ const node = nodes.get(id);
70
+ const parent = idOf(node.item.parent);
71
+ node.parent = parent != null && parent !== id && nodes.has(parent) ? parent : null;
72
+ }
73
+ breakLoops(nodes, order);
74
+
75
+ // Kids: a real item under a real parent; a draft under a draft.
76
+ for (const id of order) {
77
+ const node = nodes.get(id);
78
+ const parent = node.parent == null ? null : nodes.get(node.parent);
79
+ if (parent && parent.ghost === node.ghost) parent.kids.push(id);
80
+ }
81
+
82
+ // The tops.
83
+ const real = (id) => nodes.has(id) && !nodes.get(id).ghost;
84
+ let topIds;
85
+ if (Array.isArray(tops)) topIds = [...new Set(tops.map(idOf).filter((id) => id != null && real(id)))];
86
+ else topIds = order.filter((id) => real(id) && nodes.get(id).parent == null && nodes.get(id).kids.length > 0);
87
+ const topSet = new Set(topIds);
88
+ // A top is drawn as a top and nowhere else, so it leaves its parent's kids.
89
+ for (const id of topIds) {
90
+ const parent = nodes.get(id).parent;
91
+ if (parent != null) nodes.get(parent).kids = nodes.get(parent).kids.filter((k) => k !== id);
92
+ }
93
+
94
+ // Walk down from the tops; the first way in wins.
95
+ const walk = (id, tier, up) => {
96
+ const node = nodes.get(id);
97
+ node.tier = tier;
98
+ node.up = up;
99
+ node.group = "tree";
100
+ let total = 0;
101
+ for (const kid of node.kids) {
102
+ if (nodes.get(kid).group === "tree") continue;
103
+ walk(kid, tier + 1, id);
104
+ total += 1 + nodes.get(kid).total;
105
+ }
106
+ node.kids = node.kids.filter((k) => nodes.get(k).up === id && nodes.get(k).group === "tree");
107
+ node.total = total;
108
+ };
109
+ for (const id of topIds) walk(id, 0, null);
110
+
111
+ // Real items the tops do not reach.
112
+ const unparented = order.filter((id) => !nodes.get(id).ghost && nodes.get(id).group !== "tree");
113
+ for (const id of unparented) {
114
+ const node = nodes.get(id);
115
+ node.kids = [];
116
+ node.up = null;
117
+ }
118
+
119
+ // Drafts: a forest of their own, parents first.
120
+ const ghostRoots = [];
121
+ const ghostOrder = [];
122
+ for (const id of order) {
123
+ const node = nodes.get(id);
124
+ if (!node.ghost) continue;
125
+ node.group = "ghost";
126
+ node.up = node.parent != null && nodes.get(node.parent).ghost ? node.parent : null;
127
+ if (node.up == null) ghostRoots.push(id);
128
+ }
129
+ const lay = (id, depth) => {
130
+ ghostOrder.push({ id, depth });
131
+ const node = nodes.get(id);
132
+ node.tier = depth;
133
+ let total = 0;
134
+ for (const kid of node.kids) {
135
+ lay(kid, depth + 1);
136
+ total += 1 + nodes.get(kid).total;
137
+ }
138
+ node.total = total;
139
+ };
140
+ for (const id of ghostRoots) lay(id, 0);
141
+
142
+ return { nodes, order, tops: topIds, unparented, ghostRoots, ghostOrder, isTop: (id) => topSet.has(id) };
143
+ }
144
+
145
+ // A chain of parents that comes back to itself: the member that comes first
146
+ // in the list becomes parentless, so the rest hang under it.
147
+ function breakLoops(nodes, order) {
148
+ const place = new Map(order.map((id, i) => [id, i]));
149
+ const seen = new Map(); // id -> 1 on the walk now, 2 done
150
+ for (const start of order) {
151
+ if (seen.has(start)) continue;
152
+ const walked = [];
153
+ let cur = start;
154
+ while (cur != null && !seen.has(cur)) {
155
+ seen.set(cur, 1);
156
+ walked.push(cur);
157
+ cur = nodes.get(cur).parent;
158
+ }
159
+ if (cur != null && seen.get(cur) === 1) {
160
+ const loop = walked.slice(walked.indexOf(cur));
161
+ let first = loop[0];
162
+ for (const id of loop) if (place.get(id) < place.get(first)) first = id;
163
+ nodes.get(first).parent = null;
164
+ }
165
+ for (const id of walked) seen.set(id, 2);
166
+ }
167
+ }
168
+
169
+ // ---- the open path
170
+
171
+ /**
172
+ * The ids that are open, one per tier: the first is a top, the second one
173
+ * of its kids, and so on. Whatever cannot be (an id that is not there, one
174
+ * with nothing under it, one that is not under the one before) ends the
175
+ * path there.
176
+ */
177
+ export function openPath(model, requested) {
178
+ const out = [];
179
+ let level = model.tops;
180
+ for (const raw of Array.isArray(requested) ? requested : []) {
181
+ const id = idOf(raw);
182
+ if (id == null || !level.includes(id)) break;
183
+ const node = model.nodes.get(id);
184
+ if (!node.kids.length) break;
185
+ out.push(id);
186
+ level = node.kids;
187
+ }
188
+ return out;
189
+ }
190
+
191
+ /**
192
+ * The path after pressing a card in the tree: the card opens (and what was
193
+ * open at its tier and below closes), or, if it was open, it closes with
194
+ * everything under it. Any other id leaves the path as it is.
195
+ */
196
+ export function togglePath(model, path, id) {
197
+ const key = idOf(id);
198
+ const node = key == null ? null : model.nodes.get(key);
199
+ if (!node || node.group !== "tree" || !node.kids.length) return path;
200
+ const base = path.slice(0, node.tier);
201
+ return path[node.tier] === key ? base : [...base, key];
202
+ }
203
+
204
+ /** The ids to open so that this one is on screen: its parents, top first. */
205
+ export function pathTo(model, id) {
206
+ const out = [];
207
+ let node = model.nodes.get(idOf(id));
208
+ if (!node || node.group !== "tree") return out;
209
+ while (node && node.up != null) {
210
+ out.unshift(node.up);
211
+ node = model.nodes.get(node.up);
212
+ }
213
+ return out;
214
+ }
215
+
216
+ /** The tiers on screen for a path: [{ ids, openId }], the tops first. */
217
+ export function tiersOf(model, path) {
218
+ const tiers = [];
219
+ let ids = model.tops;
220
+ for (let i = 0; ids.length; i += 1) {
221
+ const openId = path[i] ?? null;
222
+ tiers.push({ ids, openId });
223
+ if (openId == null) break;
224
+ ids = model.nodes.get(openId).kids;
225
+ }
226
+ return tiers;
227
+ }
228
+
229
+ // ---- the keys
230
+
231
+ /** The cards beside this one: same parent, same group, in order. */
232
+ export function siblingsOf(model, id) {
233
+ const node = model.nodes.get(idOf(id));
234
+ if (!node) return [];
235
+ if (node.group === "unparented") return model.unparented;
236
+ if (node.group === "ghost") return node.up == null ? model.ghostRoots : model.nodes.get(node.up).kids;
237
+ return node.up == null ? model.tops : model.nodes.get(node.up).kids;
238
+ }
239
+
240
+ /**
241
+ * Where an arrow key goes from a card: ← → the card beside it, ↓ its first
242
+ * kid, ↑ its parent, Home and End the first and last beside it. null when
243
+ * there is nowhere to go.
244
+ */
245
+ export function neighbour(model, id, key) {
246
+ const node = model.nodes.get(idOf(id));
247
+ if (!node) return null;
248
+ const side = siblingsOf(model, node.id);
249
+ const at = side.indexOf(node.id);
250
+ switch (key) {
251
+ case "ArrowLeft":
252
+ return side[at - 1] ?? null;
253
+ case "ArrowRight":
254
+ return side[at + 1] ?? null;
255
+ case "Home":
256
+ return side[0] ?? null;
257
+ case "End":
258
+ return side[side.length - 1] ?? null;
259
+ case "ArrowDown":
260
+ return node.kids[0] ?? null;
261
+ case "ArrowUp":
262
+ return node.up ?? null;
263
+ default:
264
+ return null;
265
+ }
266
+ }
267
+
268
+ // ---- what a card says
269
+
270
+ /** "6 serving it": the count and the app's words for what is under a card. */
271
+ export function countText(count, label = "below") {
272
+ const text = typeof label === "function" ? label(count) : `${count} ${label}`;
273
+ return String(text);
274
+ }
275
+
276
+ /** A bar on a card: { pct, share } for a value 0..1, or null (no bar). A draft has none. */
277
+ export function barOf(item) {
278
+ if (!item || item.ghost === true) return null;
279
+ const v = item.value;
280
+ if (v == null || v === "" || typeof v === "boolean") return null;
281
+ const n = Number(v);
282
+ if (!Number.isFinite(n)) return null;
283
+ const share = Math.min(1, Math.max(0, n));
284
+ return { share, pct: Math.round(share * 100) };
285
+ }
286
+
287
+ export const TONES = ["ink", "quiet", "info", "success", "warning", "danger"];
288
+
289
+ /**
290
+ * The bar's colour: one of TONES. `auto` (or none) is ink, and success when
291
+ * the bar is full; a word that is not a tone is ink. A status only.
292
+ */
293
+ export function toneOf(tone, share) {
294
+ if (TONES.includes(tone)) return tone;
295
+ return share != null && share >= 1 ? "success" : "ink";
296
+ }
297
+
298
+ // ---- the lines between tiers (percentages of the tier's width)
299
+
300
+ const round = (n) => Math.round(n * 1000) / 1000;
301
+
302
+ /** The middle of column `index` of `count` equal columns, in percent of the row. */
303
+ export function centreOf(index, count) {
304
+ return count > 0 ? round(((index + 0.5) / count) * 100) : 50;
305
+ }
306
+
307
+ /**
308
+ * The elbow from a card to the row of its kids, as positions in percent:
309
+ * `parent` (where the line leaves the card), `from` and `to` (the bar across,
310
+ * from the leftmost to the rightmost of the parent and every kid), `kids`
311
+ * (where each kid's line drops).
312
+ */
313
+ export function elbowOf(parentIndex, parentCount, kidCount) {
314
+ const parent = centreOf(parentIndex, parentCount);
315
+ const kids = Array.from({ length: kidCount }, (_, i) => centreOf(i, kidCount));
316
+ const all = [parent, ...kids];
317
+ return { parent, from: Math.min(...all), to: Math.max(...all), kids };
318
+ }
@@ -0,0 +1,305 @@
1
+ # TimeGrid
2
+
3
+ Days side by side on an hour grid, with **the agent's proposals in pencil**.
4
+
5
+ What is already there is **ink**: an event in its kind's colour, a lock on the
6
+ ones another calendar owns. What the agent suggests is **pencil**: a hatched
7
+ card on a dashed edge, sitting on its hour, with a **tag** hanging off it that
8
+ quotes the words it came from ("Thursday at 3pm your time"). A person keeps a
9
+ block and it inks in: the same block, its colours fading from pencil to ink.
10
+ Keep a few at once and they ink in one by one, in the order of the week.
11
+
12
+ - **Keep all says what it will do before it does it:** "Keeps 7 of 8 in ink:
13
+ 5 Focus, 2 Admin. Leaves "Offer letter" in pencil: it clashes with Standup
14
+ 9:30."
15
+ - **A clash is hatched where two things overlap**, before anything is kept.
16
+ - **A goals strip** (`GoalStrip`) can sit above the days: goals in pencil until
17
+ kept, and a total against a target that turns red once it is over.
18
+ - Blocks are **events, not tasks**: a date, a start, an end. Drag one to move
19
+ it, pull its edge to resize (snapping to 15 minutes), drag across free
20
+ working hours to make one, drop an item in from a list, arrow keys move a
21
+ focused block, **J** and **K** walk the proposals that are waiting.
22
+ - Hours outside the working day are hatched but still there. Today has a now
23
+ line. Under 36rem of its own width it shows one day at a time under a strip
24
+ of days.
25
+
26
+ ```jsx
27
+ import { TimeGrid, GoalStrip } from "../components/blocks/time-grid"; // a Makersclaw app ("./blocks/time-grid" from components/)
28
+ import { TimeGrid, GoalStrip } from "@/components/makersclaw/blocks/time-grid"; // a shadcn project
29
+ ```
30
+
31
+ A client component. No other block is laid with it. The helpers (`planKeepAll`,
32
+ `clashesOf`, `loadOf`…) are plain functions and work on the server.
33
+
34
+ ## Which one: TimeGrid or calendar-view
35
+
36
+ `calendar-view` is the **tasks** calendar: it is built on `task-model`, takes
37
+ tasks with `start` and `due`, and saves task changes. Use it for work that has
38
+ dates and lives in a task list, for a month, for an agenda, and for a booking
39
+ page's open slots. It does not hold events that are not tasks, and it has no
40
+ pencil.
41
+
42
+ `time-grid` is for **a person reviewing what an agent would put on their
43
+ week**: plain events plus proposals, kept or dropped one at a time or all at
44
+ once. It reads and saves nothing; every press goes out through a callback.
45
+
46
+ ## Which hook feeds it
47
+
48
+ None. The events are the app's rows (a calendar mirrored into a table, blocks
49
+ a person made); the proposals are rows the agent wrote. Keep them in the app's
50
+ tables and pass them in. The block never reads or writes: a press goes out
51
+ through `onAction`, `onKeepAll` or `onChange`, the app does the write, and
52
+ hands back the changed rows. **A kept proposal keeps its id.** Either give the
53
+ same row `state: "kept"` (it stays a proposal until the week is committed), or
54
+ move the row into `events` under the same id: the block is the same element
55
+ either way, so it inks in instead of blinking out and back.
56
+
57
+ ## Props
58
+
59
+ ### The week
60
+
61
+ - `days` — the days shown, in order, `["2026-09-21", …]` (one to seven). An
62
+ item whose `date` is not one of them is not drawn.
63
+ - `today` — "YYYY-MM-DD", marks the day's header and column.
64
+ - `now` — "HH:MM" (or minutes) for the now line; leave it out and it follows
65
+ the viewer's clock after mount.
66
+ - `startHour` (5) · `endHour` (21) — the hours on the grid. Time outside is
67
+ not drawn; an item that crosses an edge is cut to it.
68
+ - `workStart` · `workEnd` — "08:30", "17:30": the working day. Hours outside
69
+ it are hatched (still there), and a new block can only be made inside it.
70
+ - `hourHeight` (40) — pixels per hour. `snap` (15) — minutes a drag snaps to.
71
+ - `height` — the hour grid's scrolling height, `"34rem"` (never `vh`), or
72
+ `"fill"`: the grid fills what is left of a bounded parent (a flex column
73
+ with a height: an `AppLayout` content in `contentMode="fill"`, a bounded
74
+ `Card`) and its hours scroll inside it, so no app measures the box. Leave
75
+ it out and the grid is as tall as its hours. `scrollTo` ("08:00") — where
76
+ it opens; default the working day's start.
77
+ - `locale` ("en-GB") — weekday names. `formatTime(minutes)` — how the grid
78
+ prints a time (default 24-hour, `9:30`).
79
+ - `corner` — a small label in the top-left (a time zone, "BST").
80
+ - `dayNotes` — `{ "2026-09-21": { text: "5.3 of 9 h", tone: "danger" } }`, a
81
+ number beside a day's header. `tone`: `neutral` · `primary` · `info` ·
82
+ `success` · `warning` · `danger`. `loadOf` and `hoursOf` add the minutes up.
83
+ - `renderDayHeader(day, { isToday, index, compact, selected })` — your own
84
+ header.
85
+ - `above` — a node drawn above the days: `<GoalStrip …/>`, or your own.
86
+
87
+ ### What is drawn
88
+
89
+ - `events` — ink. `[{ id, date, start, end, title, kind?, locked?, done?,
90
+ allDay?, caption?, sub?, icon?, draggable? }]`. `start`/`end` are "09:30".
91
+ No `start` (or `allDay`) puts it in the all-day row. `locked` shows a lock
92
+ and the block cannot be moved (`explainBlock` says why). `caption` follows
93
+ the time ("Maya's calendar"); `sub` is a line under the title when the block
94
+ is tall; `icon` is a kit icon.
95
+ - `proposals` — pencil. The same fields, and:
96
+ - `state` — `"pencil"` (default) · `"kept"` (drawn in ink, still a proposal,
97
+ with **Back to pencil**) · `"failed"` ("Didn't add", solid red edge) ·
98
+ `"replaced"` (struck, faint) · `"was"` (a dotted marker where it used to
99
+ be, under everything).
100
+ - `unsure: true` — a dotted edge and "Unsure".
101
+ - `tag` — `{ quote, source }` (or a string, the quote): hangs off the block
102
+ when it is selected (`tags="all"` shows every one). Under the block from
103
+ the left in the first half of the days, from the right in the second
104
+ half, above it when there is no room below.
105
+ - `label` — the small line over the title; default the kind's label,
106
+ "Unsure", "Didn't add"… and for a clash "Clash · Standup 9:30".
107
+ - `note` — a line at the foot of a tall block ("pencilled in Mon 06:00").
108
+ - `kinds` — `{ focus: { label: "Focus", tone: "primary", solid: true },
109
+ meeting: { label: "Meeting", tone: "neutral", locked: true }, personal: {
110
+ label: "Personal", hue: 5 } }`. `tone` is `neutral` · `primary` · `info` ·
111
+ `success` · `warning` · `danger`; `hue` is `1`–`5` (a categorical colour).
112
+ Ink is the kind's colour on its edge and a faint wash; `solid` fills it with
113
+ the accent. `locked` draws a lock on every block of that kind. `icon` is
114
+ a kit icon.
115
+ - `pencilColor` — `"neutral"` (default; pencil has no colour of its own) or
116
+ `"kind"` (the dashed edge takes the kind's colour).
117
+ - `pencilClassName` — a class for pencil titles, to set them in the app's
118
+ display face. Layout and type only, never colour.
119
+ - `drafting` — `[{ date, start, end, label? }]`: the agent still pencilling
120
+ this in, as a pulsing outline.
121
+ - `draft` — `{ date, start, end, title }`: the block being made while its
122
+ editor is open.
123
+ - `tags` — `"selected"` (default) · `"all"` · `"none"`.
124
+ - `clashAmong` (false) — also hatch two waiting proposals that overlap each
125
+ other (by default only a proposal against ink or a kept one).
126
+
127
+ ### What a press does
128
+
129
+ - `selectedId`, `defaultSelectedId`, `onSelect(id | null)` — the selected
130
+ block. Pass `selectedId` to control it (from the address, say); leave it out
131
+ and the block keeps it. A press on empty hours clears it; <kbd>Esc</kbd> too.
132
+ - `onOpen(item, element)` — a block was clicked (or Enter on it): open your
133
+ record. The block is selected as well.
134
+ - `onAction(item, "keep" | "dismiss" | "unkeep")` — `async`, returns `{ ok:
135
+ true }` or `{ ok: false, error? }`. Keep and Dismiss are drawn on every
136
+ waiting proposal (in the block when it is tall, on hover or selection when it
137
+ is short; the all-day row shows them on the selected one), **Back to
138
+ pencil** on a kept one. A failure puts a notice over the grid with Try
139
+ again. **Without `onAction` no buttons are drawn.** The buttons are small
140
+ because a block is: put the same two in your side panel, full size.
141
+ - `keepAll` — `true`, or `{ label?, skip?, primary? }`. Draws the bar over
142
+ the grid: the sentence from `planKeepAll` and a **Keep all (7)** button.
143
+ `skip` is what stays in pencil: `["clash"]` (default), `["clash", "unsure"]`,
144
+ or `[]`.
145
+ - `onKeepAll(plan)` — `async`, same return. `plan.keep` is the ids to keep,
146
+ `plan.leave` the ones left and why, `plan.words` the sentence.
147
+ - `onChange(item, change, { proposal })` — `async`, same return. A block was
148
+ moved or resized: `change` is `{ date, start, end, mode: "move" | "start" |
149
+ "end", from: { date, start, end } }`, times as "09:30". It shows at once; a
150
+ failure puts it back and says so. Pencil blocks can be moved too
151
+ (`proposal: true`). A locked block, a failed or replaced proposal, and an
152
+ item with `draggable: false` stay put. Without `onChange` nothing moves.
153
+ - `onCompose({ date, start, end })` — a press, or a drag across free working
154
+ hours, on an empty day. Open your editor (and pass `draft` meanwhile).
155
+ - `onDrop(item, { date, start, end })` — an item from a list was dropped on
156
+ an hour. Make the list item draggable with `{...timeGridDragProps({ id,
157
+ title, minutes: 45 })}`. Same return as `onChange`.
158
+ - `explainBlock(item)` — a node: why a locked block cannot be moved ("From
159
+ Google Calendar · change it there"), shown once where it is when someone
160
+ tries. `explainOffHours({ date, minute, before })` — the same for a press
161
+ outside the working day.
162
+ - `readOnly` — to read: no buttons, no drags, no compose, no Keep all.
163
+ - `keys` (true) — <kbd>J</kbd> and <kbd>K</kbd> walk the proposals that are
164
+ waiting (by day, then by time) and move to their day on a narrow container.
165
+ The region takes focus with <kbd>Tab</kbd>. They are left alone while someone
166
+ is typing in a field.
167
+
168
+ ### States and words
169
+
170
+ - `status` — `ready` (default) · `loading` (grey blocks on the grid) · `failed`
171
+ (a notice with `error`, and Try again if you pass `onRetry`).
172
+ - `emptyText` — what to say over a grid with nothing on it; `false` says
173
+ nothing.
174
+ - `words` — the block's few words, to be changed: `allDay`, `keep`, `dismiss`,
175
+ `unkeep`, `keepAll`, `pencilled`, `unsure`, `failed`, `replaced`, `was`,
176
+ `clash`, `locked`, `drafting`, `newBlock`, `empty`, `retry`, `back`.
177
+ - `label` ("Week") — the region's accessible name. `className` — layout:
178
+ width, margin. Never colour.
179
+
180
+ ### GoalStrip
181
+
182
+ ```jsx
183
+ <GoalStrip
184
+ items={[{ id: "g1", title: "Pricing page live", state: "pencil", mark: "pencilled in" }, …]}
185
+ summary={{ label: "Focus", value: 11, of: 15, unit: "h", over: false, note: "all placed" }}
186
+ onSelect={(id) => …}
187
+ />
188
+ ```
189
+
190
+ `items`: `{ id, title, number?, state: "ink" | "pencil" | "done" | "empty",
191
+ meta?, mark? }`. A goal in pencil is hatched with a dashed edge and fades to
192
+ ink when its `state` changes. `summary`: a total against a target; `over: true`
193
+ turns it red and says "over". `empty`: a node for no goals at all.
194
+ `selectedId` / `onSelect(id)` make the goals buttons.
195
+
196
+ ### Helpers
197
+
198
+ Plain functions (`import` them from the same folder):
199
+
200
+ - `planKeepAll(items, { clashes?, kinds?, skip?, fmt? })` — `{ keep, leave,
201
+ counts, total, words }`: what Keep all will do. The block calls it itself;
202
+ call it too when a button of yours (a "Commit the week") should say the same.
203
+ - `clashesOf(items, { among? })` — Map id → `[{ withId, title, s, e }]`.
204
+ `items` are what `readItem` returns.
205
+ - `readItem(raw, { days, lo, hi, snap, pencil })` — an item as the grid draws
206
+ it (minutes for `s`/`e`).
207
+ - `loadOf(items, date, where?)` — minutes of timed items on a day;
208
+ `hoursOf(minutes)` → "5.3"; `durationWords(minutes)` → "1 h 30 min".
209
+ - `lookOf(item)`, `isWaiting(item)`, `waitingOrder`, `walkProposal`,
210
+ `newlyInked`, `previewOf`, `tagPlacement`, `gridLanes`, `namesOf`, `toMin`,
211
+ `toHHMM`, `clock`.
212
+
213
+ ## Example
214
+
215
+ A week the agent drafted on Monday, kept one block at a time or all at once:
216
+
217
+ ```jsx
218
+ "use client";
219
+ import { useRows } from "../lib/data";
220
+ import { updateRow, deleteRow } from "../lib/actions";
221
+ import { GoalStrip, TimeGrid } from "../components/blocks/time-grid";
222
+
223
+ const KINDS = {
224
+ focus: { label: "Focus", tone: "primary", solid: true },
225
+ meeting: { label: "Meeting", tone: "neutral", locked: true },
226
+ admin: { label: "Admin", tone: "success" },
227
+ };
228
+
229
+ export default function Week({ days }) {
230
+ const blocks = useRows({ source: "blocks", filter: { week: days[0] } });
231
+ const goals = useRows({ source: "goals", filter: { week: days[0] } });
232
+ const rows = blocks.rows ?? [];
233
+ const toItem = (b) => ({ id: b.id, date: b.day, start: b.starts, end: b.ends, title: b.title, kind: b.kind, note: b.reason });
234
+ const keep = (ids) => Promise.all(ids.map((id) => updateRow({ source: "blocks", id, patch: { state: "kept" } })));
235
+
236
+ return (
237
+ <TimeGrid
238
+ days={days}
239
+ today={days[3]}
240
+ workStart="08:30"
241
+ workEnd="17:30"
242
+ height="36rem"
243
+ kinds={KINDS}
244
+ status={blocks.loading ? "loading" : blocks.error ? "failed" : "ready"}
245
+ error={blocks.error}
246
+ events={rows.filter((b) => b.state === "committed" || b.kind === "meeting").map(toItem)}
247
+ proposals={rows.filter((b) => b.state === "pencil" || b.state === "kept").map((b) => ({ ...toItem(b), state: b.state }))}
248
+ keepAll
249
+ onKeepAll={async (plan) => (await keep(plan.keep), { ok: true })}
250
+ onAction={async (item, action) => {
251
+ if (action === "dismiss") return deleteRow({ source: "blocks", id: item.id });
252
+ return updateRow({ source: "blocks", id: item.id, patch: { state: action === "keep" ? "kept" : "pencil" } });
253
+ }}
254
+ onChange={(item, c) => updateRow({ source: "blocks", id: item.id, patch: { day: c.date, starts: c.start, ends: c.end } })}
255
+ above={<GoalStrip items={(goals.rows ?? []).map((g) => ({ id: g.id, title: g.title, state: g.kept ? "ink" : "pencil" }))} />}
256
+ />
257
+ );
258
+ }
259
+ ```
260
+
261
+ In a server-mode app the same calls are `loadRows` in a server surface and the Server Actions of `lib/actions`.
262
+
263
+ Proposals on the hours they came for, with the sender's words:
264
+
265
+ ```jsx
266
+ <TimeGrid
267
+ days={days}
268
+ pencilColor="kind"
269
+ kinds={{ meeting: { label: "Meeting", hue: 1 }, todo: { label: "To-do", hue: 4 } }}
270
+ events={calendar}
271
+ proposals={found.map((f) => ({
272
+ id: f.id, date: f.day, start: f.start, end: f.end, title: f.title, kind: f.kind,
273
+ unsure: f.sureness < 0.7,
274
+ tag: { quote: f.phrase, source: `${f.sender} · ${f.subject}` },
275
+ }))}
276
+ selectedId={openId}
277
+ onSelect={setOpenId}
278
+ onAction={(item, action) => decide(item.id, action)}
279
+ />
280
+ ```
281
+
282
+ ## States
283
+
284
+ Drawn in `demo.jsx`: a planner's week with goals above, locked meetings, focus
285
+ in pencil, Keep, Dismiss, Keep all, a failing drag, a drop from a list;
286
+ proposals with a tag and a hatched clash, a "was" marker and a failed add;
287
+ 320 px (one day at a time); seven days and five kinds; one event; very long
288
+ words; empty; loading; failed; read-only.
289
+
290
+ ## What it will not do
291
+
292
+ - Recurring events, time zones, or blocks that cross midnight: a time is wall
293
+ time on one day.
294
+ - Fetch or save. Rows come in as props, saves go out through the callbacks.
295
+ - Decide what clashes beyond overlap: two blocks that touch end to start do
296
+ not clash, and all-day items never do. A rule such as "no meetings after 5"
297
+ is the app's; mark it in the proposal's `label`.
298
+ - Take the place of the record: a click goes out through `onOpen`; the form,
299
+ the Commit and the Undo are the page's.
300
+ - Show a month, an agenda or a booking page's open slots. That is
301
+ `calendar-view`.
302
+
303
+ A grid it cannot be is your own component in `components/` — not an edit to
304
+ this block. Its files are fixed: `npm run check` refuses a change, and
305
+ `makersclaw add time-grid` restores them.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "time-grid",
3
+ "title": "Time grid",
4
+ "description": "Days side by side on an hour grid, with the agent's proposals in pencil. What is already there is ink (events in their kind's colour, a lock on the ones another calendar owns); what the agent suggests is pencil: a hatched card on a dashed edge sitting on its hour, with a tag hanging off it that quotes the words it came from (\"Thursday at 3pm your time\"). Keep inks a block in (the same block, so its colours fade from pencil to ink; kept together they ink one by one), Dismiss drops it, Back to pencil takes a kept one back. \"Keep all\" says what it will do before it does it (\"Keeps 7 of 8 in ink: 5 Focus, 2 Admin. Leaves 1 in pencil: it clashes with Standup 9:30.\"). A clash is hatched where a proposal overlaps something already there, before anything is kept. A goals strip (GoalStrip) can sit above the days, goals in pencil until kept, with a total against a target that turns red once it is over. Blocks are events, not tasks: drag to move or resize (snapping to 15 minutes), drag across free working hours to make one, drop an item in from a list, arrow keys move a focused block, J and K walk the proposals that are waiting. Hours outside the working day are hatched but still there; a now line on today; one day at a time under a strip of days when the container is narrow. Loading, failed, empty and read-only are drawn.",
5
+ "useWhen": "A screen where a person reviews what an agent would put on their week: a weekly planner whose focus blocks are drafted in pencil and committed in ink, an inbox that finds meetings and deadlines in mail and shows each on its hour next to the real calendar with the sender's own words, a shift or room plan an assistant drafts, a day plan with proposals. Events are plain items with a date, a start and an end (not tasks). Not for tasks with start and due dates that live in a task list (calendar-view), for a month, for long timelines (gantt), or for a booking page's open slots (calendar-view).",
6
+ "tags": ["calendar", "week", "day", "hour grid", "time grid", "schedule", "planner", "pencil", "ink", "proposal", "suggestion", "draft", "keep", "keep all", "dismiss", "ghost", "tag", "clash", "conflict", "overlap", "goals", "focus time", "agent", "inbox to calendar", "weekly planner", "drag", "resize"],
7
+ "exports": ["TimeGrid", "GoalStrip", "TIME_GRID_MIME", "timeGridDragProps", "PENCIL_STATES", "clashesOf", "clock", "durationWords", "gridLanes", "hoursOf", "isWaiting", "loadOf", "lookOf", "namesOf", "newlyInked", "planKeepAll", "previewOf", "readItem", "tagPlacement", "toHHMM", "toMin", "walkProposal", "waitingOrder"],
8
+ "files": ["index.js", "time-grid.jsx", "grid-model.js"],
9
+ "requires": []
10
+ }