makersclaw 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (401) hide show
  1. package/README.md +9 -3
  2. package/package.json +1 -1
  3. package/r/activity-log.json +52 -0
  4. package/r/agent-changes.json +51 -0
  5. package/r/agent-chat.json +53 -0
  6. package/r/agent-column.json +85 -0
  7. package/r/agent-dock.json +57 -0
  8. package/r/agent-kit.json +49 -0
  9. package/r/agent-marks.json +49 -0
  10. package/r/agent-pane.json +93 -0
  11. package/r/ai-action.json +56 -0
  12. package/r/annotate.json +3 -3
  13. package/r/approval-request.json +2 -2
  14. package/r/approval.json +54 -0
  15. package/r/ask-bar.json +50 -0
  16. package/r/audio-player.json +2 -2
  17. package/r/auth-form.json +2 -2
  18. package/r/automation-editor.json +66 -0
  19. package/r/automation-list.json +57 -0
  20. package/r/automation-model.json +118 -0
  21. package/r/automations-screen.json +71 -0
  22. package/r/board.json +2 -2
  23. package/r/calendar-view.json +3 -3
  24. package/r/cart.json +2 -2
  25. package/r/chart.json +2 -2
  26. package/r/chat-pane.json +84 -0
  27. package/r/chat.json +2 -2
  28. package/r/code-editor.json +2 -2
  29. package/r/comment-box.json +3 -3
  30. package/r/connect-card.json +51 -0
  31. package/r/contact-section.json +2 -2
  32. package/r/core.json +13 -7
  33. package/r/cost.json +51 -0
  34. package/r/csv-import.json +3 -3
  35. package/r/data-picker.json +60 -0
  36. package/r/data-table.json +2 -2
  37. package/r/diagram.json +2 -2
  38. package/r/doc-editor.json +2 -2
  39. package/r/doc-page.json +3 -3
  40. package/r/email-render.json +2 -2
  41. package/r/faq.json +2 -2
  42. package/r/file-upload.json +2 -2
  43. package/r/first-run.json +63 -0
  44. package/r/fix-note.json +57 -0
  45. package/r/flow-canvas.json +2 -2
  46. package/r/flow-editor.json +79 -0
  47. package/r/footer.json +2 -2
  48. package/r/gantt.json +3 -3
  49. package/r/job-panel.json +2 -2
  50. package/r/json-editor.json +3 -3
  51. package/r/library-shelf.json +56 -0
  52. package/r/map.json +2 -2
  53. package/r/margin-notes.json +67 -0
  54. package/r/menubar.json +2 -2
  55. package/r/mind-map.json +3 -3
  56. package/r/navigation-menu.json +2 -2
  57. package/r/needs-you.json +55 -0
  58. package/r/order-detail.json +2 -2
  59. package/r/org-chart.json +3 -3
  60. package/r/pace-bar.json +69 -0
  61. package/r/page-builder.json +2 -2
  62. package/r/payment-methods.json +2 -2
  63. package/r/pdf-document.json +2 -2
  64. package/r/pdf-viewer.json +2 -2
  65. package/r/product-detail.json +2 -2
  66. package/r/product-grid.json +3 -3
  67. package/r/record-form.json +2 -2
  68. package/r/record-grid.json +52 -0
  69. package/r/record-notes.json +4 -4
  70. package/r/registry.json +4086 -1512
  71. package/r/run-history.json +52 -0
  72. package/r/run-view.json +80 -0
  73. package/r/schedule-card.json +54 -0
  74. package/r/schedule-engine.json +79 -0
  75. package/r/schedule-gantt.json +83 -0
  76. package/r/schedule-ruler.json +64 -0
  77. package/r/search-dialog.json +2 -2
  78. package/r/settings-list.json +2 -2
  79. package/r/setup-checklist.json +2 -2
  80. package/r/share-dialog.json +2 -2
  81. package/r/sidebar.json +2 -2
  82. package/r/signature-pad.json +2 -2
  83. package/r/sketch-canvas.json +2 -2
  84. package/r/source-receipt.json +52 -0
  85. package/r/spreadsheet.json +3 -3
  86. package/r/stat-cards.json +3 -3
  87. package/r/step-picker.json +53 -0
  88. package/r/step-settings.json +72 -0
  89. package/r/suggestion.json +58 -0
  90. package/r/sum-bar.json +64 -0
  91. package/r/task-list.json +3 -3
  92. package/r/task-model.json +2 -2
  93. package/r/testimonials.json +2 -2
  94. package/r/tier-map.json +67 -0
  95. package/r/time-grid.json +73 -0
  96. package/r/time-strip.json +64 -0
  97. package/r/top-bar.json +66 -0
  98. package/r/transaction-list.json +2 -2
  99. package/r/trigger-picker.json +61 -0
  100. package/r/whiteboard.json +3 -3
  101. package/r/workflow-view.json +55 -0
  102. package/registry/blocks/activity-log/README.md +112 -0
  103. package/registry/blocks/activity-log/activity-log.jsx +351 -0
  104. package/registry/blocks/activity-log/block.json +33 -0
  105. package/registry/blocks/activity-log/demo.jsx +48 -0
  106. package/registry/blocks/activity-log/index.js +4 -0
  107. package/registry/blocks/agent-changes/README.md +94 -0
  108. package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
  109. package/registry/blocks/agent-changes/block.json +28 -0
  110. package/registry/blocks/agent-changes/demo.jsx +39 -0
  111. package/registry/blocks/agent-changes/index.js +3 -0
  112. package/registry/blocks/agent-chat/README.md +145 -0
  113. package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
  114. package/registry/blocks/agent-chat/block.json +30 -0
  115. package/registry/blocks/agent-chat/demo.jsx +165 -0
  116. package/registry/blocks/agent-chat/index.js +3 -0
  117. package/registry/blocks/agent-column/README.md +197 -0
  118. package/registry/blocks/agent-column/agent-column.jsx +492 -0
  119. package/registry/blocks/agent-column/block.json +67 -0
  120. package/registry/blocks/agent-column/column-picker.jsx +163 -0
  121. package/registry/blocks/agent-column/demo.jsx +50 -0
  122. package/registry/blocks/agent-column/index.js +7 -0
  123. package/registry/blocks/agent-column/model.js +164 -0
  124. package/registry/blocks/agent-column/receipt.jsx +483 -0
  125. package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
  126. package/registry/blocks/agent-dock/README.md +210 -0
  127. package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
  128. package/registry/blocks/agent-dock/block.json +47 -0
  129. package/registry/blocks/agent-dock/demo.jsx +153 -0
  130. package/registry/blocks/agent-dock/dock-model.js +118 -0
  131. package/registry/blocks/agent-dock/index.js +5 -0
  132. package/registry/blocks/agent-kit/README.md +73 -0
  133. package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
  134. package/registry/blocks/agent-kit/block.json +10 -0
  135. package/registry/blocks/agent-kit/demo.jsx +35 -0
  136. package/registry/blocks/agent-kit/index.js +3 -0
  137. package/registry/blocks/agent-marks/README.md +80 -0
  138. package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
  139. package/registry/blocks/agent-marks/block.json +27 -0
  140. package/registry/blocks/agent-marks/demo.jsx +49 -0
  141. package/registry/blocks/agent-marks/index.js +3 -0
  142. package/registry/blocks/agent-pane/README.md +234 -0
  143. package/registry/blocks/agent-pane/agent-pane.jsx +246 -0
  144. package/registry/blocks/agent-pane/block.json +41 -0
  145. package/registry/blocks/agent-pane/composer.jsx +6 -0
  146. package/registry/blocks/agent-pane/demo.jsx +233 -0
  147. package/registry/blocks/agent-pane/dock-context.js +10 -0
  148. package/registry/blocks/agent-pane/index.js +4 -0
  149. package/registry/blocks/agent-pane/prose.jsx +84 -0
  150. package/registry/blocks/agent-pane/questions.jsx +134 -0
  151. package/registry/blocks/agent-pane/transcript.jsx +268 -0
  152. package/registry/blocks/agent-pane/work.jsx +368 -0
  153. package/registry/blocks/ai-action/README.md +94 -0
  154. package/registry/blocks/ai-action/ai-action.jsx +188 -0
  155. package/registry/blocks/ai-action/block.json +34 -0
  156. package/registry/blocks/ai-action/demo.jsx +93 -0
  157. package/registry/blocks/ai-action/index.js +3 -0
  158. package/registry/blocks/approval/README.md +145 -0
  159. package/registry/blocks/approval/approval.jsx +163 -0
  160. package/registry/blocks/approval/block.json +31 -0
  161. package/registry/blocks/approval/demo.jsx +121 -0
  162. package/registry/blocks/approval/index.js +3 -0
  163. package/registry/blocks/ask-bar/README.md +105 -0
  164. package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
  165. package/registry/blocks/ask-bar/block.json +26 -0
  166. package/registry/blocks/ask-bar/demo.jsx +78 -0
  167. package/registry/blocks/ask-bar/index.js +3 -0
  168. package/registry/blocks/automation-editor/README.md +291 -0
  169. package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
  170. package/registry/blocks/automation-editor/block.json +39 -0
  171. package/registry/blocks/automation-editor/demo.jsx +284 -0
  172. package/registry/blocks/automation-editor/index.js +4 -0
  173. package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
  174. package/registry/blocks/automation-list/README.md +129 -0
  175. package/registry/blocks/automation-list/automation-list.jsx +476 -0
  176. package/registry/blocks/automation-list/block.json +35 -0
  177. package/registry/blocks/automation-list/demo.jsx +67 -0
  178. package/registry/blocks/automation-list/index.js +3 -0
  179. package/registry/blocks/automation-model/README.md +109 -0
  180. package/registry/blocks/automation-model/block.json +135 -0
  181. package/registry/blocks/automation-model/catalog.js +256 -0
  182. package/registry/blocks/automation-model/check.js +161 -0
  183. package/registry/blocks/automation-model/demo.jsx +42 -0
  184. package/registry/blocks/automation-model/edit.js +262 -0
  185. package/registry/blocks/automation-model/fixes.js +287 -0
  186. package/registry/blocks/automation-model/glyph.jsx +13 -0
  187. package/registry/blocks/automation-model/graph.js +410 -0
  188. package/registry/blocks/automation-model/index.js +33 -0
  189. package/registry/blocks/automation-model/overlay.js +175 -0
  190. package/registry/blocks/automation-model/parts.jsx +94 -0
  191. package/registry/blocks/automation-model/schedule.js +53 -0
  192. package/registry/blocks/automation-model/templates.js +128 -0
  193. package/registry/blocks/automation-model/values.js +29 -0
  194. package/registry/blocks/automation-model/words.js +439 -0
  195. package/registry/blocks/automations-screen/README.md +207 -0
  196. package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
  197. package/registry/blocks/automations-screen/block.json +47 -0
  198. package/registry/blocks/automations-screen/demo.jsx +364 -0
  199. package/registry/blocks/automations-screen/index.js +4 -0
  200. package/registry/blocks/automations-screen/screen-model.js +129 -0
  201. package/registry/blocks/chat-pane/README.md +143 -0
  202. package/registry/blocks/chat-pane/block.json +48 -0
  203. package/registry/blocks/chat-pane/chat-attach.js +166 -0
  204. package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
  205. package/registry/blocks/chat-pane/chat-context.js +17 -0
  206. package/registry/blocks/chat-pane/chat-model.js +43 -0
  207. package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
  208. package/registry/blocks/chat-pane/chats-list.jsx +52 -0
  209. package/registry/blocks/chat-pane/demo.jsx +103 -0
  210. package/registry/blocks/chat-pane/index.js +9 -0
  211. package/registry/blocks/connect-card/README.md +99 -0
  212. package/registry/blocks/connect-card/block.json +10 -0
  213. package/registry/blocks/connect-card/connect-card.jsx +103 -0
  214. package/registry/blocks/connect-card/demo.jsx +49 -0
  215. package/registry/blocks/connect-card/index.js +3 -0
  216. package/registry/blocks/cost/README.md +115 -0
  217. package/registry/blocks/cost/block.json +10 -0
  218. package/registry/blocks/cost/cost.jsx +176 -0
  219. package/registry/blocks/cost/demo.jsx +66 -0
  220. package/registry/blocks/cost/index.js +3 -0
  221. package/registry/blocks/data-picker/README.md +81 -0
  222. package/registry/blocks/data-picker/block.json +38 -0
  223. package/registry/blocks/data-picker/data-picker.jsx +210 -0
  224. package/registry/blocks/data-picker/demo.jsx +34 -0
  225. package/registry/blocks/data-picker/fields.js +89 -0
  226. package/registry/blocks/data-picker/index.js +4 -0
  227. package/registry/blocks/data-table/demo.jsx +1 -1
  228. package/registry/blocks/first-run/README.md +118 -0
  229. package/registry/blocks/first-run/block.json +11 -0
  230. package/registry/blocks/first-run/demo.jsx +88 -0
  231. package/registry/blocks/first-run/first-run-model.js +51 -0
  232. package/registry/blocks/first-run/first-run.jsx +156 -0
  233. package/registry/blocks/first-run/index.js +5 -0
  234. package/registry/blocks/first-run/probe-rules.js +26 -0
  235. package/registry/blocks/fix-note/README.md +79 -0
  236. package/registry/blocks/fix-note/block.json +35 -0
  237. package/registry/blocks/fix-note/demo.jsx +30 -0
  238. package/registry/blocks/fix-note/fix-note.jsx +235 -0
  239. package/registry/blocks/fix-note/index.js +3 -0
  240. package/registry/blocks/flow-editor/README.md +108 -0
  241. package/registry/blocks/flow-editor/block.json +44 -0
  242. package/registry/blocks/flow-editor/demo.jsx +115 -0
  243. package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
  244. package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
  245. package/registry/blocks/flow-editor/index.js +6 -0
  246. package/registry/blocks/flow-editor/minimap.jsx +78 -0
  247. package/registry/blocks/flow-editor/outline.jsx +134 -0
  248. package/registry/blocks/library-shelf/README.md +117 -0
  249. package/registry/blocks/library-shelf/block.json +28 -0
  250. package/registry/blocks/library-shelf/demo.jsx +68 -0
  251. package/registry/blocks/library-shelf/index.js +3 -0
  252. package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
  253. package/registry/blocks/library-shelf/probe-rules.js +15 -0
  254. package/registry/blocks/margin-notes/README.md +222 -0
  255. package/registry/blocks/margin-notes/block.json +10 -0
  256. package/registry/blocks/margin-notes/demo.jsx +144 -0
  257. package/registry/blocks/margin-notes/index.js +20 -0
  258. package/registry/blocks/margin-notes/margin-model.js +224 -0
  259. package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
  260. package/registry/blocks/needs-you/README.md +177 -0
  261. package/registry/blocks/needs-you/block.json +34 -0
  262. package/registry/blocks/needs-you/demo.jsx +143 -0
  263. package/registry/blocks/needs-you/index.js +3 -0
  264. package/registry/blocks/needs-you/needs-you.jsx +441 -0
  265. package/registry/blocks/pace-bar/README.md +230 -0
  266. package/registry/blocks/pace-bar/block.json +10 -0
  267. package/registry/blocks/pace-bar/demo.jsx +255 -0
  268. package/registry/blocks/pace-bar/index.js +22 -0
  269. package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
  270. package/registry/blocks/pace-bar/pace-model.js +288 -0
  271. package/registry/blocks/record-grid/README.md +100 -0
  272. package/registry/blocks/record-grid/block.json +28 -0
  273. package/registry/blocks/record-grid/demo.jsx +43 -0
  274. package/registry/blocks/record-grid/index.js +3 -0
  275. package/registry/blocks/record-grid/record-grid.jsx +251 -0
  276. package/registry/blocks/run-history/README.md +138 -0
  277. package/registry/blocks/run-history/block.json +10 -0
  278. package/registry/blocks/run-history/demo.jsx +74 -0
  279. package/registry/blocks/run-history/index.js +3 -0
  280. package/registry/blocks/run-history/run-history.jsx +218 -0
  281. package/registry/blocks/run-view/README.md +174 -0
  282. package/registry/blocks/run-view/block.json +50 -0
  283. package/registry/blocks/run-view/demo.jsx +286 -0
  284. package/registry/blocks/run-view/index.js +5 -0
  285. package/registry/blocks/run-view/run-controls.jsx +266 -0
  286. package/registry/blocks/run-view/run-view.jsx +236 -0
  287. package/registry/blocks/run-view/runs-list.jsx +99 -0
  288. package/registry/blocks/schedule-card/README.md +121 -0
  289. package/registry/blocks/schedule-card/block.json +10 -0
  290. package/registry/blocks/schedule-card/demo.jsx +82 -0
  291. package/registry/blocks/schedule-card/index.js +3 -0
  292. package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
  293. package/registry/blocks/schedule-engine/README.md +137 -0
  294. package/registry/blocks/schedule-engine/block.json +10 -0
  295. package/registry/blocks/schedule-engine/demo.jsx +82 -0
  296. package/registry/blocks/schedule-engine/engine.js +769 -0
  297. package/registry/blocks/schedule-engine/index.js +9 -0
  298. package/registry/blocks/schedule-engine/ops.js +71 -0
  299. package/registry/blocks/schedule-engine/place.js +294 -0
  300. package/registry/blocks/schedule-engine/tree.js +79 -0
  301. package/registry/blocks/schedule-engine/waits.js +80 -0
  302. package/registry/blocks/schedule-gantt/README.md +159 -0
  303. package/registry/blocks/schedule-gantt/block.json +10 -0
  304. package/registry/blocks/schedule-gantt/demo.jsx +223 -0
  305. package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
  306. package/registry/blocks/schedule-gantt/geometry.js +176 -0
  307. package/registry/blocks/schedule-gantt/index.js +26 -0
  308. package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
  309. package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
  310. package/registry/blocks/schedule-gantt/track.jsx +190 -0
  311. package/registry/blocks/schedule-ruler/README.md +148 -0
  312. package/registry/blocks/schedule-ruler/block.json +10 -0
  313. package/registry/blocks/schedule-ruler/demo.jsx +181 -0
  314. package/registry/blocks/schedule-ruler/index.js +21 -0
  315. package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
  316. package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
  317. package/registry/blocks/source-receipt/README.md +97 -0
  318. package/registry/blocks/source-receipt/block.json +30 -0
  319. package/registry/blocks/source-receipt/demo.jsx +71 -0
  320. package/registry/blocks/source-receipt/index.js +3 -0
  321. package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
  322. package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
  323. package/registry/blocks/step-picker/README.md +78 -0
  324. package/registry/blocks/step-picker/block.json +31 -0
  325. package/registry/blocks/step-picker/demo.jsx +23 -0
  326. package/registry/blocks/step-picker/index.js +3 -0
  327. package/registry/blocks/step-picker/step-picker.jsx +144 -0
  328. package/registry/blocks/step-settings/README.md +100 -0
  329. package/registry/blocks/step-settings/block.json +44 -0
  330. package/registry/blocks/step-settings/demo.jsx +93 -0
  331. package/registry/blocks/step-settings/fields.jsx +58 -0
  332. package/registry/blocks/step-settings/flow-settings.jsx +115 -0
  333. package/registry/blocks/step-settings/index.js +5 -0
  334. package/registry/blocks/step-settings/step-settings.jsx +290 -0
  335. package/registry/blocks/suggestion/README.md +171 -0
  336. package/registry/blocks/suggestion/block.json +40 -0
  337. package/registry/blocks/suggestion/demo.jsx +91 -0
  338. package/registry/blocks/suggestion/index.js +3 -0
  339. package/registry/blocks/suggestion/suggestion.jsx +436 -0
  340. package/registry/blocks/sum-bar/README.md +122 -0
  341. package/registry/blocks/sum-bar/block.json +10 -0
  342. package/registry/blocks/sum-bar/demo.jsx +110 -0
  343. package/registry/blocks/sum-bar/index.js +5 -0
  344. package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
  345. package/registry/blocks/sum-bar/sum-model.js +126 -0
  346. package/registry/blocks/tier-map/README.md +217 -0
  347. package/registry/blocks/tier-map/block.json +10 -0
  348. package/registry/blocks/tier-map/demo.jsx +222 -0
  349. package/registry/blocks/tier-map/index.js +24 -0
  350. package/registry/blocks/tier-map/tier-map.jsx +574 -0
  351. package/registry/blocks/tier-map/tier-model.js +318 -0
  352. package/registry/blocks/time-grid/README.md +305 -0
  353. package/registry/blocks/time-grid/block.json +10 -0
  354. package/registry/blocks/time-grid/demo.jsx +279 -0
  355. package/registry/blocks/time-grid/grid-model.js +322 -0
  356. package/registry/blocks/time-grid/index.js +25 -0
  357. package/registry/blocks/time-grid/time-grid.jsx +1325 -0
  358. package/registry/blocks/time-strip/README.md +141 -0
  359. package/registry/blocks/time-strip/block.json +10 -0
  360. package/registry/blocks/time-strip/demo.jsx +129 -0
  361. package/registry/blocks/time-strip/index.js +19 -0
  362. package/registry/blocks/time-strip/strip-model.js +178 -0
  363. package/registry/blocks/time-strip/time-strip.jsx +260 -0
  364. package/registry/blocks/top-bar/README.md +149 -0
  365. package/registry/blocks/top-bar/block.json +35 -0
  366. package/registry/blocks/top-bar/demo.jsx +78 -0
  367. package/registry/blocks/top-bar/index.js +5 -0
  368. package/registry/blocks/top-bar/probe-rules.js +74 -0
  369. package/registry/blocks/top-bar/top-bar-model.js +152 -0
  370. package/registry/blocks/top-bar/top-bar.jsx +244 -0
  371. package/registry/blocks/trigger-picker/README.md +98 -0
  372. package/registry/blocks/trigger-picker/block.json +38 -0
  373. package/registry/blocks/trigger-picker/demo.jsx +59 -0
  374. package/registry/blocks/trigger-picker/index.js +3 -0
  375. package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
  376. package/registry/blocks/workflow-view/README.md +123 -0
  377. package/registry/blocks/workflow-view/block.json +10 -0
  378. package/registry/blocks/workflow-view/demo.jsx +90 -0
  379. package/registry/blocks/workflow-view/index.js +3 -0
  380. package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
  381. package/src/install.mjs +77 -16
  382. package/src/registry.mjs +3 -0
  383. package/templates/next/browser/lib/data.js +6 -1
  384. package/templates/next/files/README.md +627 -24
  385. package/templates/next/files/check/automation-format.ts +2103 -0
  386. package/templates/next/files/check/automation-package.ts +142 -0
  387. package/templates/next/files/check/run.mjs +968 -9
  388. package/templates/next/files/components/ui/field.jsx +17 -4
  389. package/templates/next/files/components/ui/icon.jsx +13 -0
  390. package/templates/next/files/components/ui/index.js +2 -1
  391. package/templates/next/files/components/ui/layout.jsx +77 -2
  392. package/templates/next/files/components/ui/notice.jsx +70 -0
  393. package/templates/next/files/components/ui/page.jsx +124 -0
  394. package/templates/next/files/components/ui/stat.jsx +22 -7
  395. package/templates/next/files/components/ui/toast.jsx +6 -3
  396. package/templates/next/files/lib/automations.js +660 -0
  397. package/templates/next/files/lib/claw.js +241 -5
  398. package/templates/next/files/lib/door.js +92 -0
  399. package/templates/next/files/lib/hooks.js +1677 -8
  400. package/templates/next/files/lib/platform.js +529 -21
  401. package/templates/next/template.json +13 -3
@@ -0,0 +1,210 @@
1
+ # AgentDock
2
+
3
+ Where an app's agent lives (0.8.1): a column on the right, beside the work,
4
+ like the desk's own agent sidebar.
5
+
6
+ The founder, testing an app: "why are we still using this weak ai sidebar
7
+ component? I thought we had created the original agent sidebar as component
8
+ in the template". We had: `agent-pane` is the desk's sidebar. What was
9
+ missing was its host. Every app invented one: a modal `Sheet` that dimmed
10
+ the work, an inspector tab, a card. So no two apps felt alike, and none felt
11
+ like the sidebar. This is the host, once.
12
+
13
+ - A **column beside the content**, under the top bar and right of the rail.
14
+ The work reflows beside it. Nothing is dimmed.
15
+ - **Resizable.** A quarter of the body until dragged, never under 280 px,
16
+ never over half. The divider is a separator a keyboard can move: arrows
17
+ nudge it, Home goes back to a quarter, End to the widest.
18
+ - **Remembered.** The open state and the width are kept in this browser, per
19
+ app (`storageKey`), in `localStorage` with a `try/catch`; with no storage
20
+ it still works.
21
+ - **A sheet where there is no room.** Where the body is under `columnAt`
22
+ (900 px; a measure of the frame's own width, never the window) the dock is
23
+ a sheet laid over the app from the right. Escape folds it. The chat is not
24
+ remounted on the way: a turn in flight survives a resize.
25
+ - **The pane keeps its head.** The `agent-pane` inside draws title, New chat,
26
+ Chats and the close; its empty state lists the past chats (or "No chats
27
+ yet"), then the app's suggestions, then the box: the desk's message box
28
+ (the `chat-pane` block's), with the words on top and + to attach and a
29
+ round send under them. The dock only tells the pane how to close, and
30
+ hands it a starting line when a "have the agent do it" button asked for one.
31
+ - **Stays mounted once opened**, so a draft and a running turn survive
32
+ folding the column.
33
+
34
+ ```jsx
35
+ import { AgentDock, useAgentDock } from "../components/blocks/agent-dock"; // a Makersclaw app ("./blocks/agent-dock" from components/)
36
+ import { AgentDock, useAgentDock } from "@/components/makersclaw/blocks/agent-dock"; // a shadcn project
37
+ ```
38
+
39
+ A client component. It needs the kit's `AppLayout` with its `dock` slot
40
+ (0.8.1), or any flex row it is the last child of.
41
+
42
+ ## Adopting it in a shell (a few lines)
43
+
44
+ The shell is the app's one `AppLayout`. Give it the dock, and make every Ask
45
+ button open it: the top bar's own Ask does that when the shell wraps the
46
+ layout in `AskProvider` (blocks/top-bar).
47
+
48
+ ```jsx
49
+ "use client";
50
+ import { AppLayout } from "../components/ui";
51
+ import { AgentDock, useAgentDock } from "../components/blocks/agent-dock";
52
+ import { AskProvider } from "../components/blocks/top-bar";
53
+ import { AskPanel } from "../components/ask-panel"; // the app's own pane over AgentPane
54
+
55
+ export default function Shell({ children, budget }) {
56
+ const dock = useAgentDock({ storageKey: "crm" }); // { open, setOpen, toggle }
57
+ return (
58
+ <AskProvider dock={dock} allowance={{ used: budget.used, cap: budget.cap }} findEvent="crm:find">
59
+ <AppLayout
60
+ navigation={<Rail />}
61
+ dock={
62
+ <AgentDock dock={dock} label="Ask the agent">
63
+ <AskPanel /> {/* useAgentPane({ row }) inside, AgentPane (not bare) */}
64
+ </AgentDock>
65
+ }
66
+ >
67
+ {children} {/* each screen draws its own <TopBar crumb=… action=…/> */}
68
+ </AppLayout>
69
+ </AskProvider>
70
+ );
71
+ }
72
+ ```
73
+
74
+ Delete the shell's old `<Sheet>` for the agent, and drop `bare` from the pane
75
+ (the dock's pane has its own head).
76
+
77
+ **One dock per app, in the shell.** A record's own pane (a meeting, a
78
+ person) is this same dock with a chat scoped to the open record: make the
79
+ `AskPanel` read the record the page has open and pass it as
80
+ `useAgentPane({ row })`. The thread follows the record; the column stays
81
+ where it is. Do not add a second column.
82
+
83
+ Also set `"agent_pane": true` in the package's blueprint (see `agent-pane`)
84
+ so the desk draws no second sidebar for the window.
85
+
86
+ ## Just open it
87
+
88
+ **To open the dock and send nothing, call `openAgent()` with no line.** One
89
+ way, from anywhere on the page:
90
+
91
+ ```jsx
92
+ import { openAgent } from "../components/blocks/agent-dock";
93
+
94
+ <Button variant="link" onClick={() => openAgent()}>Talk to the agent</Button>
95
+ ```
96
+
97
+ - `openAgent()` and `openAgent({ ask: "" })` open the dock (column or sheet),
98
+ put the cursor in the box, send nothing and start no chat. It returns
99
+ `true` when a dock took it.
100
+ - It only ever **opens**. The top bar's Ask **toggles** (it also closes);
101
+ `useAsk()` is for reading whether the agent is open (`open`) and for that
102
+ toggle, not for opening it from a screen.
103
+ - From the shell, where `useAgentDock()` is held, `dock.setOpen(true)` is the
104
+ same thing, and `dock.openAgent()` too. A screen far from the shell uses the
105
+ exported `openAgent()`: do not write your own event, ref or context for it.
106
+ - With a line, it is the next section: the dock opens and the pane sends it.
107
+
108
+ ## Have the agent do it
109
+
110
+ **Every button that says the agent will do the work calls `openAgent`.** It
111
+ never opens a form, a route or a sheet first. The founder, on a project
112
+ planner whose "Have the agent draft it" first asked for a name, a code and
113
+ two dates: "the agent should be able to create these".
114
+
115
+ ```jsx
116
+ import { openAgent } from "../components/blocks/agent-dock";
117
+
118
+ <Button variant="primary" icon="sparkles" onClick={() => openAgent("Draft a project plan for me")}>
119
+ Have the agent draft it
120
+ </Button>
121
+ ```
122
+
123
+ `openAgent("…")` opens the dock and hands the pane its first line. The pane
124
+ starts a new chat and sends the line as the member's first words; the agent
125
+ asks only for what it is missing (the name, the target date), in the chat
126
+ as a question the member answers there; then it creates the record through
127
+ the app's own actions. A form stays only for "type it yourself".
128
+
129
+ - `openAgent("Draft a project plan for me")`, or an object:
130
+ - `ask`: the starting line. Say what the member wants done, in their words.
131
+ Left out or empty, the dock only opens ("Just open it", above).
132
+ - `send`: `true` (the default) sends it. `false` puts it in the box for the
133
+ member to finish: `openAgent({ ask: "Draft a project plan for ", send: false })`.
134
+ - `fresh`: `true` (the default) is a new chat, so it is its own ask and not a
135
+ follow-up to the last one. `false` carries on in the chat that is open.
136
+ - `storageKey`: only that app's dock (default: any dock on the page, and an
137
+ app has one).
138
+ - It returns `true` when a dock took it and `false` when the page has none.
139
+ Do not use the `false` to open a form: an app that has an agent has the dock
140
+ in its shell (AppLayout's `dock` slot). `npm run check` (rule `agentfirst`)
141
+ refuses a button whose words say the agent will do the work ("Have the
142
+ agent draft it", "Let the agent plan it") when it submits a form, follows a
143
+ link or only changes a step; it must call `openAgent` or ask the agent
144
+ (`ask`, `chat.send`). A choice labelled that way inside a form fails too.
145
+
146
+ From the shell, where `useAgentDock()` is held, `dock.openAgent(ask)` does the
147
+ same without the page event. A screen far from the shell uses the exported
148
+ `openAgent`; a line the member is shown first (a chip, an ask bar) uses
149
+ `chat.send` as before.
150
+
151
+ The agent's side: its brief names the app's create actions in
152
+ `references/actions.md`, and the draft action takes its inputs as optional
153
+ (`name`, `start`, `target`), so a line like "Draft a project plan for me"
154
+ reaches it with nothing and it asks. Write the line so it carries what the
155
+ screen already knows ("Draft a project plan for the Pinewood launch").
156
+
157
+ ## Props
158
+
159
+ - `dock`: what `useAgentDock()` returns (`open`, `setOpen`, `storageKey`,
160
+ `asked`, `start`, `startTaken`). Or pass the parts:
161
+ - `open`, `onOpenChange`: the dock is yours to open and close.
162
+ - `storageKey`: where the width is kept (default the dock's, else `"app"`).
163
+ - `label`: the column's name for a screen reader. Default `"Agent"`.
164
+ - `columnAt`: body width in px from which it is a column. Default `900`.
165
+ - `children`: the pane. Your own component over `AgentPane` (the app's yes
166
+ card, its titles). Without children the dock draws an `AgentPane` from:
167
+ - `chat`, `title`, `suggestions`, `empty`, `placeholder`, `yes`, `mark`,
168
+ `onOpen`, `recent`: the `AgentPane`'s own props.
169
+ - `className`: the column's layout. Never colour.
170
+
171
+ ### useAgentDock({ storageKey, defaultOpen, listen })
172
+
173
+ Returns `{ open, setOpen(bool | fn), toggle(), openAgent(ask), storageKey,
174
+ asked, start, startTaken }`. `listen` (default true) is whether it hears
175
+ `openAgent()` calls from anywhere on the page; the shell's one hook is the
176
+ one that does. The
177
+ choice is read from storage after the first paint (so the server's and the
178
+ browser's first render agree) and written when the member changes it.
179
+ `defaultOpen` (false) holds until they choose. `asked` counts the member's
180
+ opens: when it rises the dock puts the cursor in the box. A restored open
181
+ dock never steals focus. Folding the dock gives focus back to what had it
182
+ when it opened (the Ask button), unless the member has gone elsewhere.
183
+
184
+ ### The model (plain functions)
185
+
186
+ `MIN_W`, `COLUMN_AT`, `maxWidth(body)`, `clampWidth(w, body)`,
187
+ `storedWidth(raw)`, `columnWidth(width, body)`, `hasRoom(body, columnAt)`,
188
+ `dragged(startWidth, startX, x, body)`, `nudged(key, now, body)`,
189
+ `dockKeys(storageKey)`, `openRequest(input)`, `OPEN_EVENT`.
190
+
191
+ ## Example
192
+
193
+ ```jsx
194
+ // Without an app-owned pane: the dock draws the AgentPane itself.
195
+ const dock = useAgentDock({ storageKey: "notes" });
196
+ const chat = useAgentPane();
197
+ <AppLayout
198
+ dock={<AgentDock dock={dock} chat={chat} title="Ask about your notes" suggestions={["Summarise this week"]} />}
199
+ >
200
+ …
201
+ </AppLayout>;
202
+ ```
203
+
204
+ ## States drawn in the demo
205
+
206
+ Closed (nothing drawn but the app); open as a column at 1100 px with past
207
+ chats, and with "No chats yet"; dragged and nudged; a sheet at 700 px with
208
+ Escape; a chat answering; "Have the agent draft it" on the page, which opens
209
+ the dock with its line already sent in a new chat (and "Start a line" beside
210
+ it, which puts the line in the box instead).
@@ -0,0 +1,356 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
4
+ import { cx } from "../../ui";
5
+ import { AgentDockContext, AgentPane } from "../agent-pane";
6
+ import { COLUMN_AT, MIN_W, OPEN_EVENT, carriesLine, columnWidth, dockKeys, dragged, hasRoom, nudged, openRequest, storedWidth } from "./dock-model";
7
+
8
+ // AgentDock — where the app's agent lives: a column on the right, beside the
9
+ // work, like the desk's own agent sidebar (2026-10-12). The founder: "why are
10
+ // we still using this weak ai sidebar component?" The pane was the desk's
11
+ // sidebar, but every app invented its own host for it (a modal sheet that
12
+ // dimmed the work, an inspector tab), so none felt like the sidebar. This is
13
+ // the host, once.
14
+ //
15
+ // const dock = useAgentDock({ storageKey: "crm" }); // dock.open, dock.toggle
16
+ // <AppLayout dock={<AgentDock dock={dock}><AskPanel /></AgentDock>} …>…</AppLayout>
17
+ // <Button onClick={dock.toggle}>Ask</Button>
18
+ //
19
+ // It draws the head-less shell around the pane: the column (a quarter of the
20
+ // body until dragged, never under MIN_W, never over half), the divider that
21
+ // is dragged or nudged with the arrow keys (width kept in this browser, per
22
+ // app), the work reflowing beside it, and a sheet laid over the app where the
23
+ // body has no room for both. The pane inside draws its own head (title, New
24
+ // chat, Chats, close); the dock only tells it how to close, through
25
+ // AgentDockContext. The chat stays mounted once opened, so a turn in flight
26
+ // and a draft survive folding the column.
27
+ //
28
+ // A button that says the agent will do the work calls openAgent("Draft a
29
+ // project plan for me") (X9): the dock opens and the pane sends that line in
30
+ // a new chat, and the agent asks only for what it is missing. Never a form
31
+ // first.
32
+
33
+ const readKey = (key) => {
34
+ try {
35
+ return localStorage.getItem(key);
36
+ } catch {
37
+ return null;
38
+ }
39
+ };
40
+ const writeKey = (key, value) => {
41
+ try {
42
+ if (value === null) localStorage.removeItem(key);
43
+ else localStorage.setItem(key, value);
44
+ } catch {
45
+ /* private mode, blocked storage */
46
+ }
47
+ };
48
+
49
+ /**
50
+ * Whether the dock is open, remembered in this browser per app.
51
+ *
52
+ * storageKey the app (a short word: "crm"); the open state and the
53
+ * width are kept under it
54
+ * defaultOpen until the member has chosen (default false)
55
+ * listen hear openAgent() calls from anywhere on the page (default
56
+ * true; the one dock in the shell is the one that listens)
57
+ *
58
+ * Returns { open, setOpen(bool), toggle(), openAgent(ask), storageKey,
59
+ * asked, start, startTaken }. `asked` counts the member's opens: the dock
60
+ * puts the cursor in the box when it rises, never on a page load that
61
+ * restores an open dock. `start` is the starting line an openAgent call
62
+ * left for the pane, until the pane takes it (`startTaken`).
63
+ */
64
+ export function useAgentDock({ storageKey = "app", defaultOpen = false, listen = true } = {}) {
65
+ const [open, setOpenState] = useState(defaultOpen);
66
+ const [asked, setAsked] = useState(0);
67
+ const [start, setStart] = useState(null);
68
+ const now = useRef(open);
69
+ now.current = open;
70
+ // The stored choice is read after the first paint, so the server's and the
71
+ // browser's first render agree.
72
+ useEffect(() => {
73
+ const v = readKey(dockKeys(storageKey).open);
74
+ if (v === "1") setOpenState(true);
75
+ else if (v === "0") setOpenState(false);
76
+ }, [storageKey]);
77
+ const setOpen = useCallback(
78
+ (next) => {
79
+ const v = Boolean(typeof next === "function" ? next(now.current) : next);
80
+ now.current = v;
81
+ setOpenState(v);
82
+ if (v) setAsked((n) => n + 1);
83
+ writeKey(dockKeys(storageKey).open, v ? "1" : "0");
84
+ },
85
+ [storageKey],
86
+ );
87
+ const toggle = useCallback(() => setOpen(!now.current), [setOpen]);
88
+ // "Have the agent do it": open, and leave the pane its first line.
89
+ const openWith = useCallback(
90
+ (request) => {
91
+ setOpen(true);
92
+ if (carriesLine(request)) setStart(request);
93
+ },
94
+ [setOpen],
95
+ );
96
+ const openHere = useCallback((input) => openWith(openRequest(input)), [openWith]);
97
+ const startTaken = useCallback((nonce) => setStart((s) => (s && s.nonce === nonce ? null : s)), []);
98
+ useEffect(() => {
99
+ if (!listen || typeof window === "undefined") return undefined;
100
+ const on = (e) => {
101
+ const d = e.detail;
102
+ if (!d || (d.storageKey && d.storageKey !== storageKey)) return;
103
+ d.handled = true;
104
+ openWith(d);
105
+ };
106
+ window.addEventListener(OPEN_EVENT, on);
107
+ return () => window.removeEventListener(OPEN_EVENT, on);
108
+ }, [listen, storageKey, openWith]);
109
+ return { open, setOpen, toggle, openAgent: openHere, storageKey, asked, start, startTaken };
110
+ }
111
+
112
+ /**
113
+ * "Have the agent do it": open the agent with its first line already in
114
+ * hand. Call it from anywhere on the page (a button on a screen, a card's
115
+ * action); the app's one dock hears it.
116
+ *
117
+ * openAgent("Draft a project plan for me")
118
+ * openAgent({ ask: "Draft a project plan for …", send: false })
119
+ *
120
+ * The line is sent as the member's first words in a new chat, and the agent
121
+ * asks for only what it is missing, in the chat; it then does the work with
122
+ * the app's own actions. `send: false` puts the line in the box instead, to
123
+ * finish. `fresh: false` carries on in the open chat. `storageKey` aims at
124
+ * one app's dock. → true when a dock took it; false when the page has none
125
+ * (the caller's own fallback, e.g. a form, may run then).
126
+ *
127
+ * With no line (`openAgent()`, or `{ ask: "" }`) it only opens the dock: it
128
+ * sends nothing and starts no chat. That is the one way to open the agent
129
+ * from a screen far from the shell (a "Talk to the agent" link, an empty
130
+ * state). Ask in the top bar toggles; this only ever opens.
131
+ */
132
+ export function openAgent(input) {
133
+ if (typeof window === "undefined") return false;
134
+ const detail = { ...openRequest(input), handled: false };
135
+ window.dispatchEvent(new CustomEvent(OPEN_EVENT, { detail }));
136
+ return detail.handled;
137
+ }
138
+
139
+ /**
140
+ * dock what useAgentDock() returns: the open state, its setter and
141
+ * the storage key. Or pass the parts:
142
+ * open, onOpenChange the dock is yours to open and close (controlled)
143
+ * storageKey where the width is kept (default "app", or dock's)
144
+ * label the column's name for a screen reader (default "Agent")
145
+ * columnAt the body width in px from which it is a column beside the
146
+ * work; under it, a sheet over the app (default 900)
147
+ * children the pane: your own component over AgentPane (the app's
148
+ * yes card, its title). Without children the dock draws an
149
+ * AgentPane from chat and the props below
150
+ * chat, title, suggestions, empty, placeholder, yes, mark, onOpen, recent
151
+ * the AgentPane's own (see agent-pane)
152
+ * className the column's own layout. Never colour.
153
+ */
154
+ export function AgentDock({
155
+ dock,
156
+ open: openProp,
157
+ onOpenChange,
158
+ storageKey: keyProp,
159
+ label = "Agent",
160
+ columnAt = COLUMN_AT,
161
+ children,
162
+ chat,
163
+ title,
164
+ suggestions,
165
+ empty,
166
+ placeholder,
167
+ yes,
168
+ mark,
169
+ onOpen,
170
+ recent,
171
+ className,
172
+ }) {
173
+ const storageKey = keyProp ?? dock?.storageKey ?? "app";
174
+ // Without a dock from the shell the column keeps its own state (and hears
175
+ // openAgent); with one, the shell's hook is the one that listens.
176
+ const own = useAgentDock({ storageKey, listen: !dock });
177
+ const open = Boolean(openProp ?? dock?.open ?? own.open);
178
+ const setOpen = onOpenChange ?? dock?.setOpen ?? own.setOpen;
179
+ const asked = (dock ?? own).asked;
180
+ const start = (dock ?? own).start ?? null;
181
+ const startTaken = (dock ?? own).startTaken;
182
+ // A controlled dock (open + onOpenChange, no dock) is told when openAgent
183
+ // asks it to open.
184
+ const ownAsked = useRef(own.asked);
185
+ useEffect(() => {
186
+ if (ownAsked.current === own.asked) return;
187
+ ownAsked.current = own.asked;
188
+ if (!dock && openProp !== undefined) onOpenChange?.(true);
189
+ }, [own.asked, dock, openProp, onOpenChange]);
190
+
191
+ const asideRef = useRef(null);
192
+ const bodyRef = useRef(null);
193
+ const [body, setBody] = useState(0);
194
+ const [width, setWidth] = useState(null);
195
+ const widthRef = useRef(null);
196
+ const [mounted, setMounted] = useState(open);
197
+ const column = hasRoom(body, columnAt);
198
+
199
+ useEffect(() => {
200
+ if (open) setMounted(true);
201
+ }, [open]);
202
+
203
+ // The width this browser kept for this app.
204
+ useEffect(() => {
205
+ const w = storedWidth(readKey(dockKeys(storageKey).width));
206
+ widthRef.current = w;
207
+ setWidth(w);
208
+ }, [storageKey]);
209
+ const keepWidth = useCallback(
210
+ (w) => {
211
+ widthRef.current = w;
212
+ setWidth(w);
213
+ writeKey(dockKeys(storageKey).width, w === null ? null : String(w));
214
+ },
215
+ [storageKey],
216
+ );
217
+
218
+ // The body it sits beside (the frame's row), measured, never the window.
219
+ useEffect(() => {
220
+ const el = asideRef.current?.parentElement;
221
+ if (!el) return undefined;
222
+ bodyRef.current = el;
223
+ const measure = () => setBody(el.clientWidth);
224
+ measure();
225
+ if (typeof ResizeObserver === "undefined") return undefined;
226
+ const ro = new ResizeObserver(measure);
227
+ ro.observe(el);
228
+ return () => ro.disconnect();
229
+ }, []);
230
+
231
+ // The member opened it: the cursor goes to the box. The pane mounts on the
232
+ // same render that opens the column, so the box may not exist for a frame or
233
+ // two: try on each frame until it does (and give up after a second). What
234
+ // had focus (the Ask button) is remembered, and folding the dock gives focus
235
+ // back to it.
236
+ const firstAsk = useRef(asked);
237
+ const opener = useRef(null);
238
+ useEffect(() => {
239
+ if (asked === firstAsk.current || !open) return undefined;
240
+ firstAsk.current = asked;
241
+ const here = document.activeElement;
242
+ if (here && here !== document.body && !asideRef.current?.contains(here)) opener.current = here;
243
+ let id = 0;
244
+ let tries = 0;
245
+ const attempt = () => {
246
+ const box = asideRef.current?.querySelector("textarea:not([disabled])");
247
+ if (box) {
248
+ box.focus({ preventScroll: true });
249
+ if (document.activeElement === box) return;
250
+ }
251
+ if (++tries < 60) id = requestAnimationFrame(attempt);
252
+ };
253
+ id = requestAnimationFrame(attempt);
254
+ return () => cancelAnimationFrame(id);
255
+ }, [asked, open]);
256
+ const wasOpen = useRef(open);
257
+ useEffect(() => {
258
+ const was = wasOpen.current;
259
+ wasOpen.current = open;
260
+ if (!was || open) return;
261
+ const back = opener.current;
262
+ opener.current = null;
263
+ const active = document.activeElement;
264
+ // Only when focus was inside the dock (or lost): never steal it from
265
+ // somewhere the member has since gone.
266
+ if (back && back.isConnected && (!active || active === document.body || asideRef.current?.contains(active))) back.focus({ preventScroll: true });
267
+ }, [open]);
268
+
269
+ // A sheet lays over the app, so Escape folds it.
270
+ useEffect(() => {
271
+ if (!open || column) return undefined;
272
+ const onKey = (e) => {
273
+ if (e.key === "Escape" && !e.defaultPrevented) setOpen(false);
274
+ };
275
+ document.addEventListener("keydown", onKey);
276
+ return () => document.removeEventListener("keydown", onKey);
277
+ }, [open, column, setOpen]);
278
+
279
+ const bodyWidth = () => bodyRef.current?.clientWidth ?? body;
280
+ const onPointerDown = (e) => {
281
+ if (e.button !== 0) return;
282
+ e.preventDefault();
283
+ const b = bodyWidth();
284
+ const startWidth = asideRef.current?.offsetWidth ?? columnWidth(widthRef.current, b);
285
+ const startX = e.clientX;
286
+ try {
287
+ e.currentTarget.setPointerCapture(e.pointerId);
288
+ } catch {
289
+ /* a pointer the runtime does not know */
290
+ }
291
+ const onMove = (ev) => {
292
+ const w = dragged(startWidth, startX, ev.clientX, b);
293
+ widthRef.current = w;
294
+ setWidth(w);
295
+ };
296
+ const onUp = () => {
297
+ window.removeEventListener("pointermove", onMove);
298
+ window.removeEventListener("pointerup", onUp);
299
+ window.removeEventListener("pointercancel", onUp);
300
+ keepWidth(widthRef.current);
301
+ };
302
+ window.addEventListener("pointermove", onMove);
303
+ window.addEventListener("pointerup", onUp);
304
+ window.addEventListener("pointercancel", onUp);
305
+ };
306
+ const onKeyDown = (e) => {
307
+ const b = bodyWidth();
308
+ const next = nudged(e.key, asideRef.current?.offsetWidth ?? columnWidth(widthRef.current, b), b);
309
+ if (next === undefined) return;
310
+ e.preventDefault();
311
+ keepWidth(next);
312
+ };
313
+
314
+ const ctx = useMemo(() => ({ close: () => setOpen(false), mode: column ? "column" : "sheet", start, taken: startTaken }), [setOpen, column, start, startTaken]);
315
+ const pane =
316
+ children ??
317
+ (chat ? (
318
+ <AgentPane chat={chat} title={title} suggestions={suggestions} empty={empty} placeholder={placeholder} yes={yes} mark={mark} onOpen={onOpen} recent={recent} />
319
+ ) : null);
320
+
321
+ return (
322
+ <AgentDockContext.Provider value={ctx}>
323
+ {open && column ? (
324
+ <div
325
+ role="separator"
326
+ aria-orientation="vertical"
327
+ aria-label="Resize the agent column"
328
+ aria-valuemin={MIN_W}
329
+ aria-valuenow={width ?? undefined}
330
+ title="Drag to resize · ← → to nudge · Home for a quarter"
331
+ tabIndex={0}
332
+ onPointerDown={onPointerDown}
333
+ onKeyDown={onKeyDown}
334
+ className="group relative z-10 -mx-[3px] w-1.5 shrink-0 cursor-col-resize touch-none outline-none print:hidden"
335
+ >
336
+ <span aria-hidden="true" className="absolute inset-y-0 left-[2px] right-[2px] rounded-sm transition-colors group-hover:bg-border group-focus-visible:bg-ring group-active:bg-ring motion-reduce:transition-none" />
337
+ </div>
338
+ ) : null}
339
+ <aside
340
+ ref={asideRef}
341
+ aria-label={label}
342
+ data-agent-dock={column ? "column" : "sheet"}
343
+ data-open={open ? "" : undefined}
344
+ style={column ? { width: "clamp(280px, var(--agent-dock-w, 25%), 50%)", "--agent-dock-w": width !== null ? `${width}px` : undefined } : undefined}
345
+ className={cx(
346
+ open ? "flex" : "hidden",
347
+ "min-h-0 min-w-0 flex-col border-l border-border bg-background text-foreground print:hidden",
348
+ column ? "shrink-0" : "fixed inset-y-0 right-0 z-40 w-[min(100%,26rem)] shadow-xl",
349
+ className,
350
+ )}
351
+ >
352
+ <div className="flex min-h-0 flex-1 flex-col">{mounted ? pane : null}</div>
353
+ </aside>
354
+ </AgentDockContext.Provider>
355
+ );
356
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "agent-dock",
3
+ "title": "AgentDock",
4
+ "description": "Where an app's agent lives, as the desk's agent sidebar does: a column on the right beside the work, under the top bar, with the content reflowing beside it. A quarter of the body until the member drags the divider (never under 280 px, never over half), the width and the open state remembered in this browser per app; the divider is a separator a keyboard can move (arrows nudge, Home goes back to a quarter, End to the widest). Where the body is under 900 px (a container measure, not the window) the dock becomes a sheet laid over the app from the right, folded by Escape, and the chat does not remount on the way. It is the host only: the pane inside draws its own head (title, New chat, Chats, close) and its empty state (past chats listed, suggestions, the box); the dock tells the pane how to close. The pane stays mounted once opened, so a turn in flight and a draft survive folding. It sits in the `dock` slot of the kit's AppLayout. useAgentDock() holds the open state for the app's Ask button, remembered per app, and puts the cursor in the box when the member opens it. openAgent({ ask }) is how every \"have the agent do it\" button works (X9): it opens the dock with the agent's first line already sent in a new chat (or put in the box), so the agent asks only for what it is missing, in the chat, and no form comes first.",
5
+ "useWhen": "Any app that has an agent the member asks from the shell: the top bar's Ask, a chip that sends a question, a record whose Ask follows the open record. One dock per app, in the shell; the record's own pane is the same dock with a chat scoped to that record (useAgentPane({ row })), never a second column. Replaces a modal Sheet or an inspector tab as the agent's place. Not for work the member commissions from a verb and watches land (job-panel), and not for a conversation that fills a whole screen (agent-pane in a page of its own).",
6
+ "tags": [
7
+ "dock",
8
+ "sidebar",
9
+ "column",
10
+ "ask",
11
+ "chat",
12
+ "copilot",
13
+ "resize",
14
+ "panel",
15
+ "sheet",
16
+ "shell"
17
+ ],
18
+ "exports": [
19
+ "AgentDock",
20
+ "useAgentDock",
21
+ "openAgent",
22
+ "COLUMN_AT",
23
+ "DEFAULT_SHARE",
24
+ "MIN_W",
25
+ "OPEN_EVENT",
26
+ "STEP",
27
+ "carriesLine",
28
+ "clampWidth",
29
+ "columnWidth",
30
+ "dockKeys",
31
+ "dragged",
32
+ "hasRoom",
33
+ "maxWidth",
34
+ "nudged",
35
+ "openRequest",
36
+ "storedWidth"
37
+ ],
38
+ "files": [
39
+ "index.js",
40
+ "agent-dock.jsx",
41
+ "dock-model.js"
42
+ ],
43
+ "requires": [
44
+ "agent-pane"
45
+ ],
46
+ "offer": { "since": "0.8.1", "why": "where the app's agent lives, a column beside the work, with openAgent() for every have-the-agent-do-it button" }
47
+ }