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,211 @@
1
+ "use client";
2
+
3
+ // A shelf of starting points from the Library, in named columns, each
4
+ // with a Use (the app kit, D15; grown in the CRM, 0.7.0). Two ways in:
5
+ // `sections` you shaped, or `library` — what useLibraryItems() returns
6
+ // (lib/hooks.js) — with `onUse(item)`, which draws one column of the
7
+ // collection's items, each with its cover, and the hook's paging, preview
8
+ // and "not connected yet". Props in, callbacks out; the block never reads
9
+ // the Library itself. Tokens only.
10
+
11
+ import { useState } from "react";
12
+ import { Button, Icon, Image, Skeleton, cx } from "../../ui";
13
+
14
+ /** A Library item's format, as a word and a glyph. */
15
+ const FORMATS = {
16
+ pdf: { word: "PDF", icon: "file" },
17
+ image: { word: "Picture", icon: "image" },
18
+ html: { word: "Web page", icon: "globe" },
19
+ slides: { word: "Slides", icon: "layers" },
20
+ document: { word: "Document", icon: "file" },
21
+ sheet: { word: "Sheet", icon: "table" },
22
+ archive: { word: "Archive", icon: "archive" },
23
+ };
24
+
25
+ /** Library items (useLibraryItems' `items`) as shelf items. */
26
+ export function libraryShelfItems(items, { onUse, useLabel, once } = {}) {
27
+ return (items ?? []).filter(Boolean).map((item) => {
28
+ const f = FORMATS[item.format] ?? { word: null, icon: "file" };
29
+ return {
30
+ id: item.id,
31
+ label: item.title ?? "Untitled",
32
+ meta: item.locked ? "Paid plan" : f.word,
33
+ mark: item.preview_url ? (
34
+ <Image src={item.preview_url} alt="" ratio="square" rounded="sm" className="size-7 shrink-0" />
35
+ ) : (
36
+ <Icon name={f.icon} size={14} className="shrink-0 text-muted-foreground" />
37
+ ),
38
+ locked: Boolean(item.locked),
39
+ onUse: onUse && !item.locked ? () => onUse(item) : undefined,
40
+ useLabel,
41
+ once,
42
+ };
43
+ });
44
+ }
45
+
46
+ function ShelfItem({ item }) {
47
+ const [state, setState] = useState(item.used ? "used" : "idle");
48
+ const [error, setError] = useState(null);
49
+ async function use() {
50
+ if (!item.onUse || state === "busy") return;
51
+ setState("busy");
52
+ setError(null);
53
+ let r;
54
+ try {
55
+ r = await item.onUse();
56
+ } catch (e) {
57
+ r = { ok: false, error: e?.message ?? String(e) };
58
+ }
59
+ if (r && r.ok === false) {
60
+ setState("idle");
61
+ setError(r.error || "Couldn't use it. Try again.");
62
+ return;
63
+ }
64
+ setState(item.once === false ? "idle" : "used");
65
+ }
66
+ const used = state === "used" || item.used;
67
+ return (
68
+ <li className="grid grid-cols-1 min-w-0 gap-0.5 border-b border-border py-1 last:border-b-0" data-shelf-item>
69
+ <div className="flex min-h-[30px] min-w-0 items-center gap-2">
70
+ {item.mark ?? null}
71
+ {/* The meta gives way, to an ellipsis, before the label does. It was
72
+ shrink-0, and a long meta ran the label down to nothing (UI
73
+ review X3). Neither may be wider than the row. */}
74
+ <span className="min-w-0 truncate" title={typeof item.label === "string" ? item.label : undefined} data-shelf-label>
75
+ {item.label}
76
+ </span>
77
+ {item.meta ? (
78
+ <span className="min-w-0 shrink-[4] truncate text-xs text-muted-foreground" title={typeof item.meta === "string" ? item.meta : undefined}>
79
+ {item.meta}
80
+ </span>
81
+ ) : null}
82
+ <span className="ml-auto shrink-0">
83
+ {item.locked ? (
84
+ <Icon name="lock" size={12} className="text-muted-foreground" label="Comes with a paid plan" />
85
+ ) : used ? (
86
+ <span className="inline-flex items-center gap-1 text-xs text-success">
87
+ <Icon name="check" size={12} />
88
+ {item.usedLabel ?? "Used"}
89
+ </span>
90
+ ) : item.onUse ? (
91
+ <Button size="sm" variant="quiet" loading={state === "busy"} onClick={use} aria-label={`${item.useLabel ?? "Use"}: ${typeof item.label === "string" ? item.label : "this"}`}>
92
+ {item.useLabel ?? "Use"}
93
+ </Button>
94
+ ) : null}
95
+ </span>
96
+ </div>
97
+ {item.description ? <p className="m-0 min-w-0 break-words pb-1 text-xs text-muted-foreground">{item.description}</p> : null}
98
+ {error ? (
99
+ <p role="alert" className="pb-1 text-xs text-destructive">
100
+ {error}
101
+ </p>
102
+ ) : null}
103
+ </li>
104
+ );
105
+ }
106
+
107
+ /** What a library read says under its items: loading, more, a preview, refusals. */
108
+ function LibraryFoot({ library, count }) {
109
+ const l = library ?? {};
110
+ if (l.unavailable) return <p className="text-[13px] text-muted-foreground">The Library is not connected yet.</p>;
111
+ if (l.error) return <p role="alert" className="text-[13px] text-destructive">{l.error}</p>;
112
+ const hidden = l.previewOnly && typeof l.total === "number" ? l.total - count : 0;
113
+ return (
114
+ <>
115
+ {hidden > 0 ? (
116
+ <p className="flex items-center gap-1.5 text-[13px] text-muted-foreground">
117
+ <Icon name="lock" size={12} className="shrink-0" />
118
+ {hidden} more come with a paid plan.
119
+ </p>
120
+ ) : null}
121
+ {l.hasMore && l.loadMore ? (
122
+ <Button size="sm" variant="quiet" className="justify-self-start" loading={l.loadingMore} onClick={() => l.loadMore()}>
123
+ Show more
124
+ </Button>
125
+ ) : null}
126
+ </>
127
+ );
128
+ }
129
+
130
+ /**
131
+ * The shelf.
132
+ *
133
+ * title "Start from a template"
134
+ * source "CRM starting points, from the Library"
135
+ * icon a kit Icon name before the title (default "layers")
136
+ * sections [{ key, title, items: [{ id, label, meta?, description?, mark?, onUse?, useLabel?,
137
+ * used?, usedLabel?, once?, locked? }] }]
138
+ * meta is ONE short fact ("6 stages", "PDF"); it truncates, and
139
+ * so does the label, so no row is ever wider than its box. A
140
+ * sentence is a `description`: it sits under the label and wraps.
141
+ *
142
+ * Or straight from the Library:
143
+ *
144
+ * library what useLibraryItems(id) returns ({ items, total,
145
+ * previewOnly, hasMore, loadMore, loading, loadingMore,
146
+ * error, unavailable })
147
+ * onUse(item) async → { ok } | { ok: false, error }: what Use does
148
+ * with a Library item (ask the agent to copy it in, open
149
+ * it as a draft); a locked item has no Use
150
+ * sectionTitle the column's title (default none)
151
+ * useLabel default "Use"; once — false: an item can be used again
152
+ * empty the line when the collection has nothing
153
+ */
154
+ export function LibraryShelf({
155
+ title = "Start from a template",
156
+ source,
157
+ icon = "layers",
158
+ sections: given,
159
+ library,
160
+ onUse,
161
+ sectionTitle,
162
+ useLabel,
163
+ once,
164
+ empty = "Nothing on this shelf yet.",
165
+ className,
166
+ }) {
167
+ const fromLibrary = !given && Boolean(library);
168
+ const libItems = fromLibrary ? libraryShelfItems(library.items, { onUse, useLabel, once }) : [];
169
+ const sections = given ?? (fromLibrary && libItems.length ? [{ key: "library", title: sectionTitle, items: libItems }] : []);
170
+ const loading = fromLibrary && library.loading && !libItems.length;
171
+ return (
172
+ <section data-library-shelf aria-label={title} className={cx("grid grid-cols-1 min-w-0 gap-3", className)}>
173
+ <div className="flex flex-wrap items-center gap-2 text-[13px]">
174
+ <Icon name={icon} size={16} className="text-muted-foreground" />
175
+ <b className="font-semibold">{title}</b>
176
+ {source ? <span className="text-muted-foreground">· {source}</span> : null}
177
+ </div>
178
+ {loading ? (
179
+ <div aria-busy="true" aria-label="Loading" className="grid grid-cols-1 gap-2 rounded-[var(--radius)] border border-border px-3.5 py-3">
180
+ <Skeleton className="w-2/3" />
181
+ <Skeleton className="w-1/2" />
182
+ <Skeleton className="w-3/5" />
183
+ </div>
184
+ ) : fromLibrary && !libItems.length && !library.unavailable && !library.error ? (
185
+ <p className="text-[13px] text-muted-foreground">{empty}</p>
186
+ ) : null}
187
+ {sections.length ? (
188
+ <>
189
+ {/* Side by side by the shelf's own width, not the window's: an app on
190
+ the desk is often 800px with a rail beside it, where three columns
191
+ cut every name to its first letter (CRM 0.7.1). */}
192
+ <div className="@container min-w-0">
193
+ <div className="grid grid-cols-1 min-w-0 rounded-[var(--radius)] border border-border @3xl:grid-cols-[repeat(auto-fit,minmax(14rem,1fr))]">
194
+ {sections.map((s) => (
195
+ <div key={s.key ?? s.title} className="grid grid-cols-1 min-w-0 content-start gap-0.5 border-b border-border px-3.5 py-3 last:border-b-0 @3xl:border-b-0 @3xl:border-r @3xl:last:border-r-0">
196
+ {s.title ? <h3 className="text-xs font-semibold text-muted-foreground">{s.title}</h3> : null}
197
+ <ul className="m-0 grid grid-cols-1 list-none p-0 text-[13px]">
198
+ {s.items.map((it) => (
199
+ <ShelfItem key={it.id} item={it} />
200
+ ))}
201
+ </ul>
202
+ </div>
203
+ ))}
204
+ </div>
205
+ </div>
206
+ </>
207
+ ) : null}
208
+ {fromLibrary ? <LibraryFoot library={library} count={libItems.length} /> : null}
209
+ </section>
210
+ );
211
+ }
@@ -0,0 +1,15 @@
1
+ // The layout rules this block ships for the store's probe (makersclaw-store
2
+ // scripts/probe.mjs --suite); see top-bar/probe-rules.js. Nothing imports this.
3
+ export default {
4
+ block: "library-shelf",
5
+ rules: [
6
+ {
7
+ id: "label-never-cut-to-nothing",
8
+ kind: "visible-text",
9
+ note: "UI review X3: the meta ran the label down to a letter",
10
+ scope: "[data-library-shelf]",
11
+ target: "[data-shelf-label], li > div > span.truncate:not(.text-xs)",
12
+ min: 3,
13
+ },
14
+ ],
15
+ };
@@ -0,0 +1,222 @@
1
+ # MarginNotes
2
+
3
+ Passages of text with notes in the margin, **level with the words they are
4
+ about**. On a wide container each passage is a row: the words on one side,
5
+ its notes on the other. On a narrow one (under about 42rem) the notes stack
6
+ under the passage they belong to.
7
+
8
+ A note is one of four kinds, each with its own tone and its own buttons:
9
+
10
+ - **source** — where the words came from: a title, a line of detail, the
11
+ words that were read, a link.
12
+ - **flag** — "No source. Check this line." with **It's true**, **Cut it**,
13
+ **Ask where it came from**.
14
+ - **cut** — the words struck through where they stand, the reason in the
15
+ margin, **Put back** (or a lock when nobody may put them back).
16
+ - **comment** — what someone thought of the line.
17
+
18
+ An app can change any of them or add its own kind.
19
+
20
+ The words a note is about (`quote`) are marked in the passage: dotted for a
21
+ source, wavy for a flag, struck for a cut, washed for a comment. **The
22
+ selected note and its passage are linked**: click a passage or a note, or
23
+ press <kbd>J</kbd> and <kbd>K</kbd> to walk the notes that still need a
24
+ person. A settled note folds to one line with what was decided and a
25
+ **Reopen**.
26
+
27
+ ```jsx
28
+ import { MarginNotes } from "../components/blocks/margin-notes"; // a Makersclaw app ("./blocks/margin-notes" from components/)
29
+ import { MarginNotes } from "@/components/makersclaw/blocks/margin-notes"; // a shadcn project
30
+ ```
31
+
32
+ A client component. `makersclaw add margin-notes` lays `agent-marks` with
33
+ it. The helpers (`walkNext`, `inlineMarks`, `countNotes`…) are plain
34
+ functions and work on the server.
35
+
36
+ ## Which hook feeds it
37
+
38
+ None. The passages are the app's words (a draft, a transcript); the notes are
39
+ rows the agent or a person wrote beside them. Keep them in the app's tables
40
+ and pass them in. The block never reads or writes: a press goes out through
41
+ `onAction`, the app does the write, and hands back the changed notes.
42
+
43
+ ## Props
44
+
45
+ - `passages` — the words, in reading order: `[{ id, text, lead?, label?,
46
+ level?, node? }]`. `text` is plain words. `lead` is a short figure before
47
+ them (a time `00:12`, a number); `label` a name above them (a speaker, a
48
+ section); `level` `2` · `3` · `4` draws the passage as a heading. `node`
49
+ (a React node) draws your own markup instead of `text`: a note's `quote`
50
+ cannot mark inside it (the card shows the quote instead), but a cut still
51
+ strikes it whole.
52
+ - `notes` — `[{ id, passage, kind, … }]`. `passage` is the id of the
53
+ passage it sits by; a note whose passage is not in the list is drawn
54
+ after the last row under `orphanTitle`. The rest:
55
+ - `kind` — `source` · `flag` · `cut` · `comment`, or one of your `kinds`.
56
+ - `title` — the note's heading ("v3.0.0", "No source. Check this line.").
57
+ - `meta` — a muted line under it ("tern-app/tern · shipped Tue 22 Sep").
58
+ - `text` — the note's words (a reason, a comment).
59
+ - `detail` — the proof: the words that were read, under a dashed rule.
60
+ - `quote` — the words **in the passage** the note is about. The first
61
+ place they appear (ignoring case) is marked. Without one a `cut` strikes
62
+ the whole passage; the other kinds mark nothing in the words.
63
+ - `by` — `"agent"` or `{ agent: true }` draws the agent's mark; any other
64
+ string or `{ name }` is shown as a name.
65
+ - `at` — when, in words ("12:31", "Tue 22 Sep").
66
+ - `href`, `hrefLabel` — "Open the source" (default) as a link that opens
67
+ in a new tab.
68
+ - `locked` — words for why nothing can be done to this note ("On the
69
+ never-list: margins"). A locked note shows a lock and no buttons.
70
+ - `state` — `"settled"` folds the note to a line: `answer` ("You said
71
+ it's true") and `at`, and the kind's **Reopen** if it has one. Settled
72
+ notes mark nothing in the words and are skipped by <kbd>J</kbd> and
73
+ <kbd>K</kbd>.
74
+ - `actions` — `[{ id, label, variant?, icon? }]`, replacing the kind's
75
+ buttons for this note.
76
+ - `label`, `tone`, `hue`, `mark` — this note's chip words, status tone
77
+ (`neutral` · `primary` · `info` · `success` · `warning` · `danger`),
78
+ categorical colour `1`–`5` (for a family of cuts: pricing, other people,
79
+ in confidence, length), and mark (`underline` · `wavy` · `strike` ·
80
+ `highlight` · `none`) over the kind's.
81
+ - `selected`, `defaultSelected`, `onSelect(id | null)` — the selected
82
+ note's id. Pass `selected` to control it (from the address, say); leave it
83
+ out and the block keeps it. <kbd>Esc</kbd> clears it.
84
+ - `onAction(note, actionId)` — `async`, returns `{ ok: true }` or
85
+ `{ ok: false, error? }`. Called when a button is pressed; the button shows
86
+ its spinner until it answers, and a failure prints its `error` under the
87
+ note, where it happened. A throw counts as a failure. A settled note's
88
+ Reopen calls it with `"reopen"`. **Without `onAction` no buttons are
89
+ drawn.**
90
+ - `kinds` — changes to the built-ins, or new kinds, by id: `{ flag: {
91
+ label: "Check" }, aside: { label: "Aside", tone: "primary", icon:
92
+ "message-circle", mark: "highlight", actions: [] } }`. Fields are `label`,
93
+ `icon` (a kit icon), `tone`, `mark`, `actions`, and `reopen` (`false`, or
94
+ `{ label }`). Each field you give replaces that one field.
95
+ - `side` — `right` (default) or `left`: which side of the words the margin
96
+ is on. Narrow, the notes are always under the words.
97
+ - `marginWidth` — `sm` (15rem) · `md` (18rem, default) · `lg` (22rem).
98
+ - `marginTitle` — a heading over the whole thing ("Where each paragraph
99
+ came from"), with the count line beside it.
100
+ - `showNotes` — `false` hides the margin and its marks: the words alone.
101
+ - `textSize` — `sm` · `md` (default) · `lg`.
102
+ - `status` — `ready` (default) · `loading` (rows of grey bars) · `failed`
103
+ (a notice with `error`, and Try again if you pass `onRetry`).
104
+ - `readOnly` — notes to read: no buttons, no Reopen.
105
+ - `keys` — <kbd>J</kbd> and <kbd>K</kbd> walk the notes (default `true`).
106
+ - `noNotes`, `orphanTitle`, `emptyTitle`, `emptyBody`, `countLabels` — the
107
+ block's few words, to be changed (`countLabels`: `{ open, settled }`).
108
+ - `label` — the region's accessible name.
109
+ - `className` — layout: width, margin, height. Never colour.
110
+
111
+ ### Keys
112
+
113
+ On the region (it takes focus with Tab): <kbd>J</kbd> the next note that
114
+ still needs a person, <kbd>K</kbd> the one before, <kbd>Esc</kbd> clears the
115
+ selection. On a passage with notes: <kbd>Enter</kbd> or <kbd>Space</kbd>
116
+ selects its first note, again its next, after the last none. The walk moves
117
+ focus to the note, scrolls it into view (without animation when the person
118
+ has asked for less motion) and a hidden line says "Note 2 of 5". The keys
119
+ are left alone while someone is typing in a field.
120
+
121
+ ### Helpers
122
+
123
+ Plain functions (`import` them from the same folder):
124
+
125
+ - `walkNext(notes, currentId, dir)` — the id J (`1`) or K (`-1`) goes to.
126
+ - `inlineMarks(text, notes, markOf)` — a passage's words cut into pieces
127
+ by the notes' quotes: `{ segments: [{ text, ids }], whole }`.
128
+ - `arrangeNotes(passages, notes)` — `{ byPassage, ordered, orphans }`.
129
+ - `countNotes(notes)`, `countWords(counts)` — `{ total, open, settled,
130
+ byKind }` and "3 open · 1 settled".
131
+ - `resolveKinds(changes)`, `noteLook(note, kinds)`, `actionsOf(note, kinds)`
132
+ — the kinds, and what a note looks like and offers.
133
+ - `MARGIN_KINDS` — the built-in kinds.
134
+
135
+ ## Example
136
+
137
+ An issue with a source beside each paragraph, and a line the agent could
138
+ not source:
139
+
140
+ ```jsx
141
+ "use client";
142
+ import { useRows } from "../lib/data";
143
+ import { updateRow } from "../lib/actions";
144
+ import { MarginNotes } from "../components/blocks/margin-notes";
145
+
146
+ export default function Issue({ issueId }) {
147
+ const paragraphs = useRows({ source: "issue_paragraphs", filter: { issue_id: issueId }, orderBy: "position asc" });
148
+ const notes = useRows({ source: "paragraph_notes", filter: { issue_id: issueId } });
149
+ if (paragraphs.loading || notes.loading) return <MarginNotes status="loading" />;
150
+ return (
151
+ <MarginNotes
152
+ marginTitle="Where each paragraph came from"
153
+ passages={(paragraphs.rows ?? []).map((p) => ({ id: p.id, text: p.body, level: p.is_heading ? 3 : undefined }))}
154
+ notes={(notes.rows ?? []).map((n) => ({
155
+ id: n.id,
156
+ passage: n.paragraph_id,
157
+ kind: n.kind, // "source" · "flag"
158
+ title: n.title,
159
+ meta: n.meta,
160
+ detail: n.excerpt,
161
+ quote: n.quote,
162
+ by: n.by_agent ? "agent" : undefined,
163
+ state: n.settled_at ? "settled" : undefined,
164
+ answer: n.answer,
165
+ }))}
166
+ onAction={(note, action) =>
167
+ updateRow({ source: "paragraph_notes", id: note.id, patch: { answer: action, settled_at: action === "reopen" ? null : new Date().toISOString() } })
168
+ }
169
+ />
170
+ );
171
+ }
172
+ ```
173
+
174
+ In a server-mode app the same calls are `loadRows` in a server surface and the Server Actions of `lib/actions`.
175
+
176
+ A transcript with the cut words struck, a family colour per reason, and a
177
+ lock for what may never come back:
178
+
179
+ ```jsx
180
+ <MarginNotes
181
+ side="left"
182
+ marginWidth="lg"
183
+ textSize="sm"
184
+ passages={lines.map((l) => ({ id: l.id, lead: l.clock, label: l.speaker, text: l.words }))}
185
+ notes={cuts.map((c) => ({
186
+ id: c.id,
187
+ passage: c.line_id,
188
+ kind: "cut",
189
+ hue: c.family, // 1..5, one colour per reason family
190
+ label: c.reason, // "Pricing", "A third party"…
191
+ text: c.note,
192
+ locked: c.on_never_list ? `On the never-list: ${c.on_never_list}.` : undefined,
193
+ state: c.put_back ? "settled" : undefined,
194
+ answer: "Put back",
195
+ }))}
196
+ onAction={(note, action) => putBack(note.id)}
197
+ />
198
+ ```
199
+
200
+ ## States
201
+
202
+ Drawn in `demo.jsx`: sources and a flag that settles in place, cuts with
203
+ the margin on the left, 320 px (notes under the words), one passage, very
204
+ long words, passages with an empty margin, no passages, loading, failed,
205
+ read-only.
206
+
207
+ ## What it will not do
208
+
209
+ - Edit the words. A passage is read; to change it, open it in your editor
210
+ (a flag's "Cut it" goes out through `onAction` and your app changes the
211
+ text).
212
+ - Mark the same quote twice in one passage, or a quote that spans two
213
+ passages: the first place it appears is marked, in the passage the note
214
+ is on.
215
+ - Put a note anywhere but beside its passage's row. A long note makes its
216
+ row taller.
217
+ - Keep the app's data. Settled, cut, put back: all come back in through
218
+ `notes`.
219
+
220
+ A margin it cannot be is your own component in `components/` — not an edit
221
+ to this block. Its files are fixed: `npm run check` refuses a change, and
222
+ `makersclaw add margin-notes` restores them.
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "margin-notes",
3
+ "title": "MarginNotes",
4
+ "description": "Passages of text with notes in the margin, level with the words they are about (stacked under each passage when the container is narrow). Four kinds of note, each with its tone and its buttons: source (where the words came from: a title, a line of detail, the words read), flag (\"No source. Check this line.\" with It's true, Cut it, Ask where it came from), cut (the words struck through, with the reason, Put back, or a lock when nobody may put them back) and comment. The words a note is about are marked in the passage; the selected passage and its note are linked, and J and K walk the notes that still need a person. A settled note folds to one line with what was decided and a Reopen. Saves go out through one callback, onAction(note, actionId).",
5
+ "useWhen": "A piece of writing is read against what stands behind it: a newsletter issue with a source beside every paragraph, a blog post with the claims that need a person, minutes whose transcript shows what was cut and why, a review with a reviewer's comments beside the lines. Not a thread of comments with no text beside it (comment-box), not one note log for a record (record-notes), not suggested edits inside an editor (doc-editor), not a screenshot with pins (annotate).",
6
+ "tags": ["margin", "notes", "marginalia", "sources", "citations", "provenance", "fact check", "flag", "claim", "check", "cut", "struck", "redact", "transcript", "minutes", "review", "comment", "proof", "annotation", "agent"],
7
+ "exports": ["MarginNotes", "MARGIN_KINDS", "TONES", "MARKS", "resolveKinds", "noteLook", "actionsOf", "isSettled", "arrangeNotes", "walkNext", "cycleNote", "findQuote", "inlineMarks", "countNotes", "countWords"],
8
+ "files": ["index.js", "margin-notes.jsx", "margin-model.js"],
9
+ "requires": ["agent-marks"]
10
+ }
@@ -0,0 +1,144 @@
1
+ "use client";
2
+
3
+ // MarginNotes in the states a screen meets — the gallery's and the smoke
4
+ // test's surface. Not installed into apps: `makersclaw add margin-notes`
5
+ // lays index.js, margin-notes.jsx and margin-model.js only.
6
+ // Sources an issue, a source beside each paragraph, one line with
7
+ // none to flag (It's true, Cut it, Ask where; settles in place)
8
+ // Cuts a transcript with the cut words struck and the reason in
9
+ // the margin on the left, four hues, a lock, Put back
10
+ // Narrow the same issue in a 320 px column: notes under the words
11
+ // One a single passage with a single note
12
+ // Long words and a note with no break to wrap at
13
+ // Empty no passages; and passages with no notes
14
+ // Loading, failed, read-only
15
+ import { useState } from "react";
16
+ import { Switch } from "../components/ui";
17
+ import { MarginNotes } from "../components/blocks/margin-notes";
18
+
19
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
20
+
21
+ const ISSUE = [
22
+ { id: "p1", level: 3, text: "Offline mode, for the whole day" },
23
+ { id: "p2", text: "At 6am the tech app downloads the day’s jobs, maps and forms. In a basement plant room or past the last mast, your techs open jobs and fill in forms as usual." },
24
+ { id: "p3", text: "Search now finds a job by address, customer or part number, so nobody scrolls a list at the van door." },
25
+ { id: "p4", text: "PS. Offline mode cut sync errors by 90% in the pilot." },
26
+ { id: "p5", text: "You get this because you use Tern." },
27
+ ];
28
+
29
+ const ISSUE_NOTES = [
30
+ { id: "s1", passage: "p1", kind: "source", title: "v3.0.0", meta: "tern-app/tern-mobile · shipped Tue 22 Sep", detail: "Release v3.0.0 of the tech app", href: "https://example.com/releases/v3.0.0", hrefLabel: "Open the release", quote: "Offline mode" },
31
+ { id: "s2", passage: "p2", kind: "source", title: "v3.0.0", meta: "tern-app/tern-mobile · shipped Tue 22 Sep", detail: "offline queue for jobs, maps and forms; background sync on reconnect", quote: "downloads the day’s jobs, maps and forms" },
32
+ { id: "s3", passage: "p3", kind: "source", title: "PR 482", meta: "tern-app/tern · merged Wed 23 Sep · Leo Brandt", detail: "search: index part numbers on job lines; add address and customer fields", quote: "address, customer or part number" },
33
+ { id: "s3b", passage: "p3", kind: "comment", by: "Maya", at: "12:31", text: "Say it as one sentence, not a list.", quote: "scrolls a list" },
34
+ { id: "f1", passage: "p4", kind: "flag", by: "agent", title: "No source. Check this line.", text: "The PS claims a 90% drop in sync errors. Nothing in the log or the blog says so.", quote: "90% in the pilot" },
35
+ ];
36
+
37
+ function useNotes(start) {
38
+ const [notes, setNotes] = useState(start);
39
+ const [log, setLog] = useState("");
40
+ const onAction = async (note, id) => {
41
+ await wait(350);
42
+ if (note.id === "f1" && id === "ask") return { ok: false, error: "The mail did not go. Try again." };
43
+ setNotes((all) =>
44
+ all.map((n) => {
45
+ if (n.id !== note.id) return n;
46
+ if (id === "confirm") return { ...n, state: "settled", answer: "You said it’s true", at: "12:48" };
47
+ if (id === "cut") return { ...n, kind: "cut", title: "Cut by you", text: "No source for it.", quote: undefined, actions: undefined };
48
+ if (id === "putback") return { ...n, state: "settled", answer: "Put back", at: "12:50" };
49
+ if (id === "reopen") return { ...n, state: "open", answer: undefined };
50
+ return n;
51
+ }),
52
+ );
53
+ setLog(`${id}: ${note.id}`);
54
+ return { ok: true };
55
+ };
56
+ return { notes, onAction, log };
57
+ }
58
+
59
+ const FAMILY = { 1: "Commercial", 2: "Other people", 3: "In confidence", 4: "Length" };
60
+ const CALL = [
61
+ { id: "t1", lead: "00:04", label: "Leo Park", text: "Honestly, our margin on this account is basically gone." },
62
+ { id: "t2", lead: "00:12", label: "Dana Whitfield", text: "Our last agency was useless with reporting, so this is already better." },
63
+ { id: "t3", lead: "00:31", label: "Sam Ortiz", text: "We agreed the TikTok pilot runs in Q4, owner to be agreed." },
64
+ { id: "t4", lead: "01:02", label: "Leo Park", text: "Ha, I do love a Friday afternoon call. Anyway." },
65
+ ];
66
+ const CALL_NOTES = [
67
+ { id: "c1", passage: "t1", kind: "cut", hue: 1, label: FAMILY[1], by: "agent", text: "Our margin; before the client joined.", locked: "On the never-list: margins. Nobody can put this back." },
68
+ { id: "c2", passage: "t2", kind: "cut", hue: 2, label: FAMILY[2], by: "agent", text: "About their previous agency." },
69
+ { id: "c3", passage: "t4", kind: "cut", hue: 4, label: FAMILY[4], by: "agent", text: "A joke; nothing decided." },
70
+ ];
71
+
72
+ const LONG = "Supercalifragilisticexpialidocious".repeat(4);
73
+
74
+ export default function MarginNotesDemo() {
75
+ const issue = useNotes(ISSUE_NOTES);
76
+ const narrow = useNotes(ISSUE_NOTES);
77
+ const call = useNotes(CALL_NOTES);
78
+ const [showNotes, setShowNotes] = useState(true);
79
+ const [picked, setPicked] = useState(null);
80
+
81
+ return (
82
+ <div className="grid gap-10 p-6">
83
+ <section className="grid gap-3">
84
+ <div className="flex flex-wrap items-center gap-3">
85
+ <h3 className="m-0 text-base font-semibold">Sources and a flag</h3>
86
+ <Switch id="mn-show" label="Show the margin" checked={showNotes} onChange={(e) => setShowNotes(e.target.checked)} />
87
+ </div>
88
+ <MarginNotes passages={ISSUE} notes={issue.notes} onAction={issue.onAction} showNotes={showNotes} marginTitle="Where each paragraph came from" selected={picked} onSelect={setPicked} />
89
+ <p className="m-0 text-xs text-muted-foreground">{issue.log ? `Last: ${issue.log}` : "Press J or K, or click a paragraph."}</p>
90
+ </section>
91
+
92
+ <section className="grid gap-3">
93
+ <h3 className="m-0 text-base font-semibold">Cuts, struck where they were said (margin on the left)</h3>
94
+ <MarginNotes passages={CALL} notes={call.notes} onAction={call.onAction} side="left" marginWidth="lg" marginTitle="The call, with every cut" textSize="sm" />
95
+ </section>
96
+
97
+ <section className="grid gap-3">
98
+ <h3 className="m-0 text-base font-semibold">Narrow (320)</h3>
99
+ <div className="w-80 max-w-full">
100
+ <MarginNotes passages={ISSUE} notes={narrow.notes} onAction={narrow.onAction} defaultSelected="f1" />
101
+ </div>
102
+ </section>
103
+
104
+ <section className="grid gap-3">
105
+ <h3 className="m-0 text-base font-semibold">One passage, one note</h3>
106
+ <MarginNotes passages={[ISSUE[3]]} notes={[ISSUE_NOTES[4]]} keys={false} />
107
+ </section>
108
+
109
+ <section className="grid gap-3">
110
+ <h3 className="m-0 text-base font-semibold">Very long words</h3>
111
+ <MarginNotes
112
+ passages={[{ id: "l1", label: LONG, text: `${LONG} is the whole of this line, and it has no break to wrap at: ${LONG}.` }]}
113
+ notes={[{ id: "ln", passage: "l1", kind: "flag", title: LONG, text: `${LONG}`, detail: `${LONG} ${LONG}`, quote: LONG.slice(0, 20) }]}
114
+ onAction={async () => ({ ok: true })}
115
+ />
116
+ </section>
117
+
118
+ <section className="grid gap-3">
119
+ <h3 className="m-0 text-base font-semibold">Passages, nothing in the margin</h3>
120
+ <MarginNotes passages={ISSUE.slice(0, 3)} notes={[]} marginTitle="Sources" />
121
+ </section>
122
+
123
+ <section className="grid gap-3">
124
+ <h3 className="m-0 text-base font-semibold">No passages</h3>
125
+ <MarginNotes passages={[]} notes={[]} emptyTitle="No issue drafted yet" emptyBody="When the agent drafts one, each paragraph appears here beside where it came from." />
126
+ </section>
127
+
128
+ <section className="grid gap-3">
129
+ <h3 className="m-0 text-base font-semibold">Loading</h3>
130
+ <MarginNotes status="loading" />
131
+ </section>
132
+
133
+ <section className="grid gap-3">
134
+ <h3 className="m-0 text-base font-semibold">Failed</h3>
135
+ <MarginNotes status="failed" error="The sources could not be read." onRetry={() => undefined} />
136
+ </section>
137
+
138
+ <section className="grid gap-3">
139
+ <h3 className="m-0 text-base font-semibold">Read-only</h3>
140
+ <MarginNotes passages={ISSUE} notes={ISSUE_NOTES} readOnly marginTitle="Where each paragraph came from" />
141
+ </section>
142
+ </div>
143
+ );
144
+ }
@@ -0,0 +1,20 @@
1
+ // The MarginNotes block — `makersclaw add margin-notes`. Fixed: compose it
2
+ // through its props (README.md beside this file). The model's helpers are
3
+ // plain functions; they work on the server too.
4
+ export { MarginNotes } from "./margin-notes";
5
+ export {
6
+ MARGIN_KINDS,
7
+ TONES,
8
+ MARKS,
9
+ resolveKinds,
10
+ noteLook,
11
+ actionsOf,
12
+ isSettled,
13
+ arrangeNotes,
14
+ walkNext,
15
+ cycleNote,
16
+ findQuote,
17
+ inlineMarks,
18
+ countNotes,
19
+ countWords,
20
+ } from "./margin-model";