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.
- package/README.md +17 -4
- package/package.json +1 -1
- package/r/activity-log.json +52 -0
- package/r/agent-changes.json +51 -0
- package/r/agent-chat.json +53 -0
- package/r/agent-column.json +85 -0
- package/r/agent-dock.json +57 -0
- package/r/agent-kit.json +49 -0
- package/r/agent-marks.json +49 -0
- package/r/agent-pane.json +93 -0
- package/r/ai-action.json +56 -0
- package/r/annotate.json +4 -4
- package/r/approval-request.json +2 -2
- package/r/approval.json +54 -0
- package/r/ask-bar.json +50 -0
- package/r/audio-player.json +2 -2
- package/r/auth-form.json +2 -2
- package/r/automation-editor.json +66 -0
- package/r/automation-list.json +57 -0
- package/r/automation-model.json +118 -0
- package/r/automations-screen.json +71 -0
- package/r/board.json +2 -2
- package/r/calendar-view.json +3 -3
- package/r/cart.json +2 -2
- package/r/chart.json +5 -5
- package/r/chat-pane.json +84 -0
- package/r/chat.json +3 -3
- package/r/code-editor.json +2 -2
- package/r/comment-box.json +3 -3
- package/r/connect-card.json +51 -0
- package/r/contact-section.json +2 -2
- package/r/core.json +18 -6
- package/r/cost.json +51 -0
- package/r/csv-import.json +3 -3
- package/r/data-picker.json +60 -0
- package/r/data-table.json +2 -2
- package/r/diagram.json +2 -2
- package/r/doc-editor.json +2 -2
- package/r/doc-page.json +3 -3
- package/r/email-render.json +2 -2
- package/r/faq.json +2 -2
- package/r/file-upload.json +2 -2
- package/r/first-run.json +63 -0
- package/r/fix-note.json +57 -0
- package/r/flow-canvas.json +3 -3
- package/r/flow-editor.json +79 -0
- package/r/footer.json +3 -3
- package/r/gantt.json +3 -3
- package/r/job-panel.json +2 -2
- package/r/json-editor.json +3 -3
- package/r/library-shelf.json +56 -0
- package/r/map.json +2 -2
- package/r/margin-notes.json +67 -0
- package/r/menubar.json +2 -2
- package/r/mind-map.json +4 -4
- package/r/navigation-menu.json +2 -2
- package/r/needs-you.json +55 -0
- package/r/order-detail.json +2 -2
- package/r/org-chart.json +4 -4
- package/r/pace-bar.json +69 -0
- package/r/page-builder.json +3 -3
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +3 -3
- package/r/product-detail.json +2 -2
- package/r/product-grid.json +3 -3
- package/r/record-form.json +2 -2
- package/r/record-grid.json +52 -0
- package/r/record-notes.json +4 -4
- package/r/registry.json +4089 -1510
- package/r/run-history.json +52 -0
- package/r/run-view.json +80 -0
- package/r/schedule-card.json +54 -0
- package/r/schedule-engine.json +79 -0
- package/r/schedule-gantt.json +83 -0
- package/r/schedule-ruler.json +64 -0
- package/r/search-dialog.json +2 -2
- package/r/settings-list.json +2 -2
- package/r/setup-checklist.json +2 -2
- package/r/share-dialog.json +2 -2
- package/r/sidebar.json +3 -3
- package/r/signature-pad.json +2 -2
- package/r/sketch-canvas.json +3 -3
- package/r/source-receipt.json +52 -0
- package/r/spreadsheet.json +3 -3
- package/r/stat-cards.json +3 -3
- package/r/step-picker.json +53 -0
- package/r/step-settings.json +72 -0
- package/r/suggestion.json +58 -0
- package/r/sum-bar.json +64 -0
- package/r/task-list.json +3 -3
- package/r/task-model.json +2 -2
- package/r/testimonials.json +2 -2
- package/r/tier-map.json +67 -0
- package/r/time-grid.json +73 -0
- package/r/time-strip.json +64 -0
- package/r/top-bar.json +66 -0
- package/r/transaction-list.json +2 -2
- package/r/trigger-picker.json +61 -0
- package/r/whiteboard.json +4 -4
- package/r/workflow-view.json +55 -0
- package/registry/blocks/activity-log/README.md +112 -0
- package/registry/blocks/activity-log/activity-log.jsx +351 -0
- package/registry/blocks/activity-log/block.json +33 -0
- package/registry/blocks/activity-log/demo.jsx +48 -0
- package/registry/blocks/activity-log/index.js +4 -0
- package/registry/blocks/agent-changes/README.md +94 -0
- package/registry/blocks/agent-changes/agent-changes.jsx +118 -0
- package/registry/blocks/agent-changes/block.json +28 -0
- package/registry/blocks/agent-changes/demo.jsx +39 -0
- package/registry/blocks/agent-changes/index.js +3 -0
- package/registry/blocks/agent-chat/README.md +145 -0
- package/registry/blocks/agent-chat/agent-chat.jsx +415 -0
- package/registry/blocks/agent-chat/block.json +30 -0
- package/registry/blocks/agent-chat/demo.jsx +165 -0
- package/registry/blocks/agent-chat/index.js +3 -0
- package/registry/blocks/agent-column/README.md +197 -0
- package/registry/blocks/agent-column/agent-column.jsx +492 -0
- package/registry/blocks/agent-column/block.json +67 -0
- package/registry/blocks/agent-column/column-picker.jsx +163 -0
- package/registry/blocks/agent-column/demo.jsx +50 -0
- package/registry/blocks/agent-column/index.js +7 -0
- package/registry/blocks/agent-column/model.js +164 -0
- package/registry/blocks/agent-column/receipt.jsx +483 -0
- package/registry/blocks/agent-column/spreadsheet-type.jsx +24 -0
- package/registry/blocks/agent-dock/README.md +210 -0
- package/registry/blocks/agent-dock/agent-dock.jsx +356 -0
- package/registry/blocks/agent-dock/block.json +47 -0
- package/registry/blocks/agent-dock/demo.jsx +153 -0
- package/registry/blocks/agent-dock/dock-model.js +118 -0
- package/registry/blocks/agent-dock/index.js +5 -0
- package/registry/blocks/agent-kit/README.md +73 -0
- package/registry/blocks/agent-kit/agent-kit.jsx +86 -0
- package/registry/blocks/agent-kit/block.json +10 -0
- package/registry/blocks/agent-kit/demo.jsx +35 -0
- package/registry/blocks/agent-kit/index.js +3 -0
- package/registry/blocks/agent-marks/README.md +80 -0
- package/registry/blocks/agent-marks/agent-marks.jsx +133 -0
- package/registry/blocks/agent-marks/block.json +27 -0
- package/registry/blocks/agent-marks/demo.jsx +49 -0
- package/registry/blocks/agent-marks/index.js +3 -0
- package/registry/blocks/agent-pane/README.md +225 -0
- package/registry/blocks/agent-pane/agent-pane.jsx +244 -0
- package/registry/blocks/agent-pane/block.json +41 -0
- package/registry/blocks/agent-pane/composer.jsx +6 -0
- package/registry/blocks/agent-pane/demo.jsx +233 -0
- package/registry/blocks/agent-pane/dock-context.js +10 -0
- package/registry/blocks/agent-pane/index.js +4 -0
- package/registry/blocks/agent-pane/prose.jsx +84 -0
- package/registry/blocks/agent-pane/questions.jsx +134 -0
- package/registry/blocks/agent-pane/transcript.jsx +268 -0
- package/registry/blocks/agent-pane/work.jsx +368 -0
- package/registry/blocks/ai-action/README.md +94 -0
- package/registry/blocks/ai-action/ai-action.jsx +188 -0
- package/registry/blocks/ai-action/block.json +34 -0
- package/registry/blocks/ai-action/demo.jsx +93 -0
- package/registry/blocks/ai-action/index.js +3 -0
- package/registry/blocks/annotate/README.md +14 -11
- package/registry/blocks/approval/README.md +145 -0
- package/registry/blocks/approval/approval.jsx +163 -0
- package/registry/blocks/approval/block.json +31 -0
- package/registry/blocks/approval/demo.jsx +121 -0
- package/registry/blocks/approval/index.js +3 -0
- package/registry/blocks/ask-bar/README.md +105 -0
- package/registry/blocks/ask-bar/ask-bar.jsx +166 -0
- package/registry/blocks/ask-bar/block.json +26 -0
- package/registry/blocks/ask-bar/demo.jsx +78 -0
- package/registry/blocks/ask-bar/index.js +3 -0
- package/registry/blocks/automation-editor/README.md +291 -0
- package/registry/blocks/automation-editor/automation-editor.jsx +656 -0
- package/registry/blocks/automation-editor/block.json +39 -0
- package/registry/blocks/automation-editor/demo.jsx +284 -0
- package/registry/blocks/automation-editor/index.js +4 -0
- package/registry/blocks/automation-editor/run-inputs.jsx +82 -0
- package/registry/blocks/automation-list/README.md +129 -0
- package/registry/blocks/automation-list/automation-list.jsx +476 -0
- package/registry/blocks/automation-list/block.json +35 -0
- package/registry/blocks/automation-list/demo.jsx +67 -0
- package/registry/blocks/automation-list/index.js +3 -0
- package/registry/blocks/automation-model/README.md +109 -0
- package/registry/blocks/automation-model/block.json +135 -0
- package/registry/blocks/automation-model/catalog.js +256 -0
- package/registry/blocks/automation-model/check.js +161 -0
- package/registry/blocks/automation-model/demo.jsx +42 -0
- package/registry/blocks/automation-model/edit.js +262 -0
- package/registry/blocks/automation-model/fixes.js +287 -0
- package/registry/blocks/automation-model/glyph.jsx +13 -0
- package/registry/blocks/automation-model/graph.js +410 -0
- package/registry/blocks/automation-model/index.js +33 -0
- package/registry/blocks/automation-model/overlay.js +175 -0
- package/registry/blocks/automation-model/parts.jsx +94 -0
- package/registry/blocks/automation-model/schedule.js +53 -0
- package/registry/blocks/automation-model/templates.js +128 -0
- package/registry/blocks/automation-model/values.js +29 -0
- package/registry/blocks/automation-model/words.js +439 -0
- package/registry/blocks/automations-screen/README.md +207 -0
- package/registry/blocks/automations-screen/automations-screen.jsx +452 -0
- package/registry/blocks/automations-screen/block.json +47 -0
- package/registry/blocks/automations-screen/demo.jsx +364 -0
- package/registry/blocks/automations-screen/index.js +4 -0
- package/registry/blocks/automations-screen/screen-model.js +129 -0
- package/registry/blocks/chart/cartesian.jsx +1 -1
- package/registry/blocks/chart/core.jsx +33 -23
- package/registry/blocks/chart/pie.jsx +1 -1
- package/registry/blocks/chat/README.md +4 -1
- package/registry/blocks/chat/demo.jsx +2 -2
- package/registry/blocks/chat-pane/README.md +143 -0
- package/registry/blocks/chat-pane/block.json +48 -0
- package/registry/blocks/chat-pane/chat-attach.js +166 -0
- package/registry/blocks/chat-pane/chat-composer.jsx +195 -0
- package/registry/blocks/chat-pane/chat-context.js +17 -0
- package/registry/blocks/chat-pane/chat-model.js +43 -0
- package/registry/blocks/chat-pane/chat-pane.jsx +398 -0
- package/registry/blocks/chat-pane/chats-list.jsx +52 -0
- package/registry/blocks/chat-pane/demo.jsx +103 -0
- package/registry/blocks/chat-pane/index.js +9 -0
- package/registry/blocks/connect-card/README.md +99 -0
- package/registry/blocks/connect-card/block.json +10 -0
- package/registry/blocks/connect-card/connect-card.jsx +103 -0
- package/registry/blocks/connect-card/demo.jsx +49 -0
- package/registry/blocks/connect-card/index.js +3 -0
- package/registry/blocks/cost/README.md +115 -0
- package/registry/blocks/cost/block.json +10 -0
- package/registry/blocks/cost/cost.jsx +176 -0
- package/registry/blocks/cost/demo.jsx +66 -0
- package/registry/blocks/cost/index.js +3 -0
- package/registry/blocks/data-picker/README.md +81 -0
- package/registry/blocks/data-picker/block.json +38 -0
- package/registry/blocks/data-picker/data-picker.jsx +210 -0
- package/registry/blocks/data-picker/demo.jsx +34 -0
- package/registry/blocks/data-picker/fields.js +89 -0
- package/registry/blocks/data-picker/index.js +4 -0
- package/registry/blocks/data-table/demo.jsx +1 -1
- package/registry/blocks/first-run/README.md +118 -0
- package/registry/blocks/first-run/block.json +11 -0
- package/registry/blocks/first-run/demo.jsx +88 -0
- package/registry/blocks/first-run/first-run-model.js +51 -0
- package/registry/blocks/first-run/first-run.jsx +156 -0
- package/registry/blocks/first-run/index.js +5 -0
- package/registry/blocks/first-run/probe-rules.js +26 -0
- package/registry/blocks/fix-note/README.md +79 -0
- package/registry/blocks/fix-note/block.json +35 -0
- package/registry/blocks/fix-note/demo.jsx +30 -0
- package/registry/blocks/fix-note/fix-note.jsx +235 -0
- package/registry/blocks/fix-note/index.js +3 -0
- package/registry/blocks/flow-canvas/README.md +15 -8
- package/registry/blocks/flow-editor/README.md +108 -0
- package/registry/blocks/flow-editor/block.json +44 -0
- package/registry/blocks/flow-editor/demo.jsx +115 -0
- package/registry/blocks/flow-editor/flow-canvas.jsx +568 -0
- package/registry/blocks/flow-editor/flow-editor.jsx +154 -0
- package/registry/blocks/flow-editor/index.js +6 -0
- package/registry/blocks/flow-editor/minimap.jsx +78 -0
- package/registry/blocks/flow-editor/outline.jsx +134 -0
- package/registry/blocks/footer/README.md +3 -2
- package/registry/blocks/library-shelf/README.md +117 -0
- package/registry/blocks/library-shelf/block.json +28 -0
- package/registry/blocks/library-shelf/demo.jsx +68 -0
- package/registry/blocks/library-shelf/index.js +3 -0
- package/registry/blocks/library-shelf/library-shelf.jsx +211 -0
- package/registry/blocks/library-shelf/probe-rules.js +15 -0
- package/registry/blocks/margin-notes/README.md +222 -0
- package/registry/blocks/margin-notes/block.json +10 -0
- package/registry/blocks/margin-notes/demo.jsx +144 -0
- package/registry/blocks/margin-notes/index.js +20 -0
- package/registry/blocks/margin-notes/margin-model.js +224 -0
- package/registry/blocks/margin-notes/margin-notes.jsx +465 -0
- package/registry/blocks/mind-map/README.md +4 -2
- package/registry/blocks/needs-you/README.md +177 -0
- package/registry/blocks/needs-you/block.json +34 -0
- package/registry/blocks/needs-you/demo.jsx +143 -0
- package/registry/blocks/needs-you/index.js +3 -0
- package/registry/blocks/needs-you/needs-you.jsx +441 -0
- package/registry/blocks/org-chart/README.md +4 -2
- package/registry/blocks/pace-bar/README.md +230 -0
- package/registry/blocks/pace-bar/block.json +10 -0
- package/registry/blocks/pace-bar/demo.jsx +255 -0
- package/registry/blocks/pace-bar/index.js +22 -0
- package/registry/blocks/pace-bar/pace-bar.jsx +461 -0
- package/registry/blocks/pace-bar/pace-model.js +288 -0
- package/registry/blocks/page-builder/README.md +1 -1
- package/registry/blocks/page-builder/demo.jsx +3 -3
- package/registry/blocks/pdf-viewer/README.md +4 -1
- package/registry/blocks/record-grid/README.md +100 -0
- package/registry/blocks/record-grid/block.json +28 -0
- package/registry/blocks/record-grid/demo.jsx +43 -0
- package/registry/blocks/record-grid/index.js +3 -0
- package/registry/blocks/record-grid/record-grid.jsx +251 -0
- package/registry/blocks/run-history/README.md +138 -0
- package/registry/blocks/run-history/block.json +10 -0
- package/registry/blocks/run-history/demo.jsx +74 -0
- package/registry/blocks/run-history/index.js +3 -0
- package/registry/blocks/run-history/run-history.jsx +218 -0
- package/registry/blocks/run-view/README.md +174 -0
- package/registry/blocks/run-view/block.json +50 -0
- package/registry/blocks/run-view/demo.jsx +286 -0
- package/registry/blocks/run-view/index.js +5 -0
- package/registry/blocks/run-view/run-controls.jsx +266 -0
- package/registry/blocks/run-view/run-view.jsx +236 -0
- package/registry/blocks/run-view/runs-list.jsx +99 -0
- package/registry/blocks/schedule-card/README.md +121 -0
- package/registry/blocks/schedule-card/block.json +10 -0
- package/registry/blocks/schedule-card/demo.jsx +82 -0
- package/registry/blocks/schedule-card/index.js +3 -0
- package/registry/blocks/schedule-card/schedule-card.jsx +136 -0
- package/registry/blocks/schedule-engine/README.md +137 -0
- package/registry/blocks/schedule-engine/block.json +10 -0
- package/registry/blocks/schedule-engine/demo.jsx +82 -0
- package/registry/blocks/schedule-engine/engine.js +769 -0
- package/registry/blocks/schedule-engine/index.js +9 -0
- package/registry/blocks/schedule-engine/ops.js +71 -0
- package/registry/blocks/schedule-engine/place.js +294 -0
- package/registry/blocks/schedule-engine/tree.js +79 -0
- package/registry/blocks/schedule-engine/waits.js +80 -0
- package/registry/blocks/schedule-gantt/README.md +159 -0
- package/registry/blocks/schedule-gantt/block.json +10 -0
- package/registry/blocks/schedule-gantt/demo.jsx +223 -0
- package/registry/blocks/schedule-gantt/gantt-model.js +219 -0
- package/registry/blocks/schedule-gantt/geometry.js +176 -0
- package/registry/blocks/schedule-gantt/index.js +26 -0
- package/registry/blocks/schedule-gantt/schedule-gantt.jsx +882 -0
- package/registry/blocks/schedule-gantt/sheet.jsx +372 -0
- package/registry/blocks/schedule-gantt/track.jsx +190 -0
- package/registry/blocks/schedule-ruler/README.md +148 -0
- package/registry/blocks/schedule-ruler/block.json +10 -0
- package/registry/blocks/schedule-ruler/demo.jsx +181 -0
- package/registry/blocks/schedule-ruler/index.js +21 -0
- package/registry/blocks/schedule-ruler/ruler-model.js +239 -0
- package/registry/blocks/schedule-ruler/schedule-ruler.jsx +548 -0
- package/registry/blocks/sidebar/README.md +23 -13
- package/registry/blocks/sketch-canvas/README.md +15 -9
- package/registry/blocks/source-receipt/README.md +97 -0
- package/registry/blocks/source-receipt/block.json +30 -0
- package/registry/blocks/source-receipt/demo.jsx +71 -0
- package/registry/blocks/source-receipt/index.js +3 -0
- package/registry/blocks/source-receipt/source-receipt.jsx +107 -0
- package/registry/blocks/spreadsheet/spreadsheet.jsx +15 -1
- package/registry/blocks/step-picker/README.md +78 -0
- package/registry/blocks/step-picker/block.json +31 -0
- package/registry/blocks/step-picker/demo.jsx +23 -0
- package/registry/blocks/step-picker/index.js +3 -0
- package/registry/blocks/step-picker/step-picker.jsx +144 -0
- package/registry/blocks/step-settings/README.md +100 -0
- package/registry/blocks/step-settings/block.json +44 -0
- package/registry/blocks/step-settings/demo.jsx +93 -0
- package/registry/blocks/step-settings/fields.jsx +58 -0
- package/registry/blocks/step-settings/flow-settings.jsx +115 -0
- package/registry/blocks/step-settings/index.js +5 -0
- package/registry/blocks/step-settings/step-settings.jsx +290 -0
- package/registry/blocks/suggestion/README.md +171 -0
- package/registry/blocks/suggestion/block.json +40 -0
- package/registry/blocks/suggestion/demo.jsx +91 -0
- package/registry/blocks/suggestion/index.js +3 -0
- package/registry/blocks/suggestion/suggestion.jsx +436 -0
- package/registry/blocks/sum-bar/README.md +122 -0
- package/registry/blocks/sum-bar/block.json +10 -0
- package/registry/blocks/sum-bar/demo.jsx +110 -0
- package/registry/blocks/sum-bar/index.js +5 -0
- package/registry/blocks/sum-bar/sum-bar.jsx +209 -0
- package/registry/blocks/sum-bar/sum-model.js +126 -0
- package/registry/blocks/tier-map/README.md +217 -0
- package/registry/blocks/tier-map/block.json +10 -0
- package/registry/blocks/tier-map/demo.jsx +222 -0
- package/registry/blocks/tier-map/index.js +24 -0
- package/registry/blocks/tier-map/tier-map.jsx +574 -0
- package/registry/blocks/tier-map/tier-model.js +318 -0
- package/registry/blocks/time-grid/README.md +305 -0
- package/registry/blocks/time-grid/block.json +10 -0
- package/registry/blocks/time-grid/demo.jsx +279 -0
- package/registry/blocks/time-grid/grid-model.js +322 -0
- package/registry/blocks/time-grid/index.js +25 -0
- package/registry/blocks/time-grid/time-grid.jsx +1325 -0
- package/registry/blocks/time-strip/README.md +141 -0
- package/registry/blocks/time-strip/block.json +10 -0
- package/registry/blocks/time-strip/demo.jsx +129 -0
- package/registry/blocks/time-strip/index.js +19 -0
- package/registry/blocks/time-strip/strip-model.js +178 -0
- package/registry/blocks/time-strip/time-strip.jsx +260 -0
- package/registry/blocks/top-bar/README.md +149 -0
- package/registry/blocks/top-bar/block.json +35 -0
- package/registry/blocks/top-bar/demo.jsx +78 -0
- package/registry/blocks/top-bar/index.js +5 -0
- package/registry/blocks/top-bar/probe-rules.js +74 -0
- package/registry/blocks/top-bar/top-bar-model.js +152 -0
- package/registry/blocks/top-bar/top-bar.jsx +244 -0
- package/registry/blocks/trigger-picker/README.md +98 -0
- package/registry/blocks/trigger-picker/block.json +38 -0
- package/registry/blocks/trigger-picker/demo.jsx +59 -0
- package/registry/blocks/trigger-picker/index.js +3 -0
- package/registry/blocks/trigger-picker/trigger-picker.jsx +374 -0
- package/registry/blocks/whiteboard/README.md +20 -14
- package/registry/blocks/workflow-view/README.md +123 -0
- package/registry/blocks/workflow-view/block.json +10 -0
- package/registry/blocks/workflow-view/demo.jsx +90 -0
- package/registry/blocks/workflow-view/index.js +3 -0
- package/registry/blocks/workflow-view/workflow-view.jsx +203 -0
- package/src/cli.mjs +2 -2
- package/src/install.mjs +100 -22
- package/src/registry.mjs +37 -3
- package/templates/next/browser/lib/data.js +6 -1
- package/templates/next/files/README.md +909 -26
- package/templates/next/files/app/shell.jsx +54 -37
- package/templates/next/files/check/automation-format.ts +2103 -0
- package/templates/next/files/check/automation-package.ts +142 -0
- package/templates/next/files/check/run.mjs +1043 -12
- package/templates/next/files/components/ui/field.jsx +17 -4
- package/templates/next/files/components/ui/icon.jsx +13 -0
- package/templates/next/files/components/ui/index.js +3 -1
- package/templates/next/files/components/ui/layout.jsx +382 -0
- package/templates/next/files/components/ui/notice.jsx +70 -0
- package/templates/next/files/components/ui/page.jsx +124 -0
- package/templates/next/files/components/ui/stat.jsx +22 -7
- package/templates/next/files/components/ui/toast.jsx +6 -3
- package/templates/next/files/lib/automations.js +660 -0
- package/templates/next/files/lib/claw.js +244 -5
- package/templates/next/files/lib/door.js +92 -0
- package/templates/next/files/lib/hooks.js +1694 -6
- package/templates/next/files/lib/platform.js +611 -14
- package/templates/next/template.json +22 -3
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# SourceReceipt
|
|
2
|
+
|
|
3
|
+
Where one value came from, drawn as a clipping:
|
|
4
|
+
|
|
5
|
+
- the page's or the mail's title, with the trust mark's shape beside it;
|
|
6
|
+
- its address (linked) or the mailbox, and the date it was read;
|
|
7
|
+
- the words on it, with the **deciding words underlined** wherever they
|
|
8
|
+
appear;
|
|
9
|
+
- a trust word ("their own site", "a 2023 directory");
|
|
10
|
+
- **Open the source**.
|
|
11
|
+
|
|
12
|
+
A member reads the claim and its proof in one look, and decides how far
|
|
13
|
+
to trust it.
|
|
14
|
+
|
|
15
|
+
It is not a second receipt. The clipping is `agent-column`'s (Data
|
|
16
|
+
Enrichment's "the receipt"); this block wraps it for one source standing
|
|
17
|
+
on its own: a CRM's found title, a note's proof margin, a newsletter's
|
|
18
|
+
source line. Inside a column of answers, use `agent-column`'s `Receipt`.
|
|
19
|
+
|
|
20
|
+
```jsx
|
|
21
|
+
import { SourceReceipt } from "../components/blocks/source-receipt"; // a Makersclaw app ("./blocks/source-receipt" from components/)
|
|
22
|
+
import { SourceReceipt } from "@/components/makersclaw/blocks/source-receipt"; // a shadcn project
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
A client component. It requires `agent-column` (and through it
|
|
26
|
+
`agent-marks`), laid with it.
|
|
27
|
+
|
|
28
|
+
## Which hook feeds it
|
|
29
|
+
|
|
30
|
+
None. The source is app data the agent wrote beside the value: its
|
|
31
|
+
address, its title, the words it read, the words that decided. Keep
|
|
32
|
+
them in the record (a `source` column, a `sources` table) and pass them
|
|
33
|
+
in.
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
- `title` — the page's or the mail's title ("Careers · Klarwerk").
|
|
38
|
+
- `url` — the source's address. The clipping shows it short
|
|
39
|
+
("klarwerk.de/careers") and links it.
|
|
40
|
+
- `site` — where, when there is no `url`: a mailbox ("Sofia Reyes
|
|
41
|
+
<sofia@crumb.co>") or a site's name. From `url` when left out.
|
|
42
|
+
- `kind` — `site` (default) or `mail`: the icon before the trust word.
|
|
43
|
+
- `date` — when it was read or sent, in words ("read 22 Sep").
|
|
44
|
+
- `trust` — a word for how far to trust it ("their own site", "her
|
|
45
|
+
signature", "a 2023 directory").
|
|
46
|
+
- `sure` — `sure` · `likely` · `guess`: the trust mark's shape beside
|
|
47
|
+
the title (filled, half, dashed).
|
|
48
|
+
- `excerpt` — the words on it.
|
|
49
|
+
- `marks` — the deciding words, `string[]`. Every occurrence of each is
|
|
50
|
+
underlined, whatever its case. Without `marks`, an excerpt's own
|
|
51
|
+
`[[…]]` (the agent's marking) are underlined instead.
|
|
52
|
+
- `onOpen()` — opens the source your way. Without it, a `url` opens in a
|
|
53
|
+
new tab.
|
|
54
|
+
- `openLabel` — default "Open the source".
|
|
55
|
+
- `action` — a node at the head's end: a "Pick 70" when two sources
|
|
56
|
+
disagree.
|
|
57
|
+
- `picked` — drawn as the one chosen.
|
|
58
|
+
- `className` — layout around it. Never colour.
|
|
59
|
+
|
|
60
|
+
`markExcerpt(excerpt, marks)` is exported: the excerpt with `[[…]]`
|
|
61
|
+
around every deciding word, as the clipping reads it.
|
|
62
|
+
|
|
63
|
+
## Who may do what
|
|
64
|
+
|
|
65
|
+
Anyone who can see the value can see its source. The receipt has no
|
|
66
|
+
writes; a Pick is your own `action`, and your own action's rules hold.
|
|
67
|
+
|
|
68
|
+
## Never
|
|
69
|
+
|
|
70
|
+
- Never build the excerpt from HTML or inject it: it is drawn as text,
|
|
71
|
+
and the underlines are elements, never markup in a string.
|
|
72
|
+
- Never show a value as found with no receipt to open.
|
|
73
|
+
- Never colour the trust alone: the mark's shape and the word say it.
|
|
74
|
+
|
|
75
|
+
## Example
|
|
76
|
+
|
|
77
|
+
The source of a contact's job title, under the field.
|
|
78
|
+
|
|
79
|
+
```jsx
|
|
80
|
+
import { SourceReceipt } from "./blocks/source-receipt";
|
|
81
|
+
|
|
82
|
+
export function TitleSource({ person }) {
|
|
83
|
+
const s = person.title_source;
|
|
84
|
+
if (!s) return null;
|
|
85
|
+
return (
|
|
86
|
+
<SourceReceipt
|
|
87
|
+
title={s.title}
|
|
88
|
+
url={s.url}
|
|
89
|
+
date={`read ${s.read_on}`}
|
|
90
|
+
trust={s.trust}
|
|
91
|
+
sure={s.sure}
|
|
92
|
+
excerpt={s.words}
|
|
93
|
+
marks={[person.job_title]}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "source-receipt",
|
|
3
|
+
"title": "SourceReceipt",
|
|
4
|
+
"description": "Where one value came from, as a clipping: the page or the mail and its title, the address, the date it was read, a trust word (\"their own site\", \"a 2023 directory\") and the trust mark's shape, the words on it with the deciding ones underlined wherever they appear (case-insensitive, never HTML), and Open the source. A thin wrapper over agent-column's clipping (Data Enrichment's receipt) for a value that stands on its own, so every app draws a source the same way.",
|
|
5
|
+
"useWhen": "A value the agent found should show its proof beside it: a contact's title from an email signature, a company's size from its site, a figure in a note or a newsletter with its source in the margin, two sources side by side for a person to pick. For a whole column of answers across records use agent-column; for a value proposed but not kept yet, put the receipt under a suggestion.",
|
|
6
|
+
"tags": [
|
|
7
|
+
"source",
|
|
8
|
+
"citation",
|
|
9
|
+
"receipt",
|
|
10
|
+
"provenance",
|
|
11
|
+
"evidence",
|
|
12
|
+
"quote",
|
|
13
|
+
"clipping",
|
|
14
|
+
"trust",
|
|
15
|
+
"proof",
|
|
16
|
+
"reference",
|
|
17
|
+
"found"
|
|
18
|
+
],
|
|
19
|
+
"exports": [
|
|
20
|
+
"SourceReceipt",
|
|
21
|
+
"markExcerpt"
|
|
22
|
+
],
|
|
23
|
+
"files": [
|
|
24
|
+
"index.js",
|
|
25
|
+
"source-receipt.jsx"
|
|
26
|
+
],
|
|
27
|
+
"requires": [
|
|
28
|
+
"agent-column"
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// SourceReceipt for a page, a mail, two sources to pick from, and a
|
|
4
|
+
// source with nothing to underline — the gallery's and the smoke test's
|
|
5
|
+
// surface. Not installed into apps.
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import { Button } from "../components/ui";
|
|
8
|
+
import { SourceReceipt } from "../components/blocks/source-receipt";
|
|
9
|
+
|
|
10
|
+
export default function SourceReceiptDemo() {
|
|
11
|
+
const [picked, setPicked] = useState(null);
|
|
12
|
+
const pick = (which, words) =>
|
|
13
|
+
picked === which ? (
|
|
14
|
+
<Button size="sm" variant="primary" disabled>
|
|
15
|
+
Picked
|
|
16
|
+
</Button>
|
|
17
|
+
) : (
|
|
18
|
+
<Button size="sm" onClick={() => setPicked(which)}>
|
|
19
|
+
{words}
|
|
20
|
+
</Button>
|
|
21
|
+
);
|
|
22
|
+
return (
|
|
23
|
+
<div className="grid gap-6 p-6 [grid-template-columns:repeat(auto-fit,minmax(min(100%,20rem),1fr))]">
|
|
24
|
+
<SourceReceipt
|
|
25
|
+
title="Careers · Klarwerk"
|
|
26
|
+
url="https://www.klarwerk.de/careers"
|
|
27
|
+
date="read 22 Sep"
|
|
28
|
+
trust="their own site, five months old"
|
|
29
|
+
sure="likely"
|
|
30
|
+
excerpt="We're a team of 70 across Berlin and Leipzig. Our team of 70 ships payroll software for 2,000 shops."
|
|
31
|
+
marks={["team of 70"]}
|
|
32
|
+
/>
|
|
33
|
+
<SourceReceipt
|
|
34
|
+
kind="mail"
|
|
35
|
+
title="Re: scheduling for all the shops"
|
|
36
|
+
site="Sofia Reyes <sofia@crumb.co>"
|
|
37
|
+
date="Sat 12 Sep"
|
|
38
|
+
trust="her email signature"
|
|
39
|
+
sure="sure"
|
|
40
|
+
excerpt="Sofia Reyes — Head of Retail Operations, Crumb & Co. +1 612 555 0142"
|
|
41
|
+
marks={["head of retail operations"]}
|
|
42
|
+
onOpen={() => undefined}
|
|
43
|
+
openLabel="Open the mail"
|
|
44
|
+
/>
|
|
45
|
+
<SourceReceipt
|
|
46
|
+
title="Klarwerk on LinkedIn"
|
|
47
|
+
url="linkedin.com/company/klarwerk"
|
|
48
|
+
date="read 22 Sep"
|
|
49
|
+
trust="a profile the company keeps"
|
|
50
|
+
sure="likely"
|
|
51
|
+
excerpt="[[51–200 employees]] · [[85]] members"
|
|
52
|
+
action={pick("one", "Pick 85")}
|
|
53
|
+
picked={picked === "one"}
|
|
54
|
+
/>
|
|
55
|
+
<SourceReceipt
|
|
56
|
+
title="A 2023 directory"
|
|
57
|
+
url="https://directory.example.org/companies/klarwerk-gmbh-berlin-leipzig-payroll-software-2023"
|
|
58
|
+
date="read 22 Sep"
|
|
59
|
+
trust="a 2023 directory"
|
|
60
|
+
sure="guess"
|
|
61
|
+
excerpt="Klarwerk GmbH, payroll software, Berlin. About 60 staff."
|
|
62
|
+
marks={["about 60", "nothing that appears"]}
|
|
63
|
+
action={pick("other", "Pick 60")}
|
|
64
|
+
picked={picked === "other"}
|
|
65
|
+
/>
|
|
66
|
+
<div className="w-80 max-w-full">
|
|
67
|
+
<SourceReceipt title="A source with no words kept" url="nordlicht.io/team" date="read 21 Sep" />
|
|
68
|
+
</div>
|
|
69
|
+
</div>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { Button, Icon, cx } from "../../ui";
|
|
4
|
+
import { Clipping } from "../agent-column";
|
|
5
|
+
|
|
6
|
+
// SourceReceipt — where one value came from, as a clipping (the app kit,
|
|
7
|
+
// D15): the page or the mail, its date, a trust word ("their own site",
|
|
8
|
+
// "a 2023 directory"), the words on it with the deciding ones underlined,
|
|
9
|
+
// and Open the source. For a value that is not in an agent column: a
|
|
10
|
+
// CRM's found title, a note's proof margin, a newsletter's source line.
|
|
11
|
+
//
|
|
12
|
+
// It is NOT a second receipt. The clipping is agent-column's (Data
|
|
13
|
+
// Enrichment's "the receipt"); this wraps it for one source standing on
|
|
14
|
+
// its own, so both draw the same thing. No door: the source is app data
|
|
15
|
+
// the agent wrote. Props in, callbacks out.
|
|
16
|
+
|
|
17
|
+
/** Wrap every occurrence of each mark in [[…]] (the clipping's mark for
|
|
18
|
+
* deciding words), case-insensitive, longest first so no mark lands
|
|
19
|
+
* inside another. With no marks, the excerpt's own [[…]] (the agent's)
|
|
20
|
+
* stand; with marks, they replace them. Plain strings only: never HTML. */
|
|
21
|
+
export function markExcerpt(excerpt, marks) {
|
|
22
|
+
const list = [...new Set((marks ?? []).map((m) => String(m ?? "").trim()).filter((m) => m && !/[[\]]/.test(m)))].sort((a, b) => b.length - a.length);
|
|
23
|
+
if (!list.length) return String(excerpt ?? "");
|
|
24
|
+
const text = String(excerpt ?? "").replace(/\[\[|\]\]/g, "");
|
|
25
|
+
if (!text) return text;
|
|
26
|
+
const re = new RegExp(list.map((m) => m.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"), "gi");
|
|
27
|
+
return text.replace(re, (hit) => `[[${hit}]]`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** "acme.com", from a URL; null when it is not one. */
|
|
31
|
+
function siteOf(url) {
|
|
32
|
+
try {
|
|
33
|
+
return new URL(/^https?:/i.test(url) ? url : `https://${url}`).hostname.replace(/^www\./i, "");
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* title the page's or the mail's title ("Careers · Klarwerk")
|
|
41
|
+
* site where: a site ("klarwerk.de") or a mailbox ("Sofia Reyes
|
|
42
|
+
* <sofia@crumb.co>"); from `url` when left out
|
|
43
|
+
* url the source's address; the clipping links it
|
|
44
|
+
* kind "site" (default) or "mail": the icon before the trust word
|
|
45
|
+
* date when it was read or sent, in words ("read 22 Sep")
|
|
46
|
+
* trust a word for how far to trust it ("their own site")
|
|
47
|
+
* sure sure · likely · guess: the trust mark's shape, beside the title
|
|
48
|
+
* excerpt the words on it
|
|
49
|
+
* marks the deciding words, underlined wherever they appear
|
|
50
|
+
* onOpen() opens the source; without it, with a url, the source opens
|
|
51
|
+
* in a new tab
|
|
52
|
+
* openLabel default "Open the source"
|
|
53
|
+
* action a node at the head's end (a "Pick" for one of two)
|
|
54
|
+
* picked drawn as the one chosen
|
|
55
|
+
*/
|
|
56
|
+
export function SourceReceipt({
|
|
57
|
+
title,
|
|
58
|
+
site,
|
|
59
|
+
url,
|
|
60
|
+
kind = "site",
|
|
61
|
+
date,
|
|
62
|
+
trust,
|
|
63
|
+
sure,
|
|
64
|
+
excerpt,
|
|
65
|
+
marks = [],
|
|
66
|
+
onOpen,
|
|
67
|
+
openLabel = "Open the source",
|
|
68
|
+
action,
|
|
69
|
+
picked = false,
|
|
70
|
+
className,
|
|
71
|
+
}) {
|
|
72
|
+
const where = site ?? (url ? siteOf(url) : null);
|
|
73
|
+
// The clipping draws a url as its linked address; a mailbox or a site
|
|
74
|
+
// without one rides in its date line instead.
|
|
75
|
+
const read = [url ? null : where, date].filter(Boolean).join(" · ") || undefined;
|
|
76
|
+
const href = url ? (/^https?:/i.test(url) ? url : `https://${url}`) : null;
|
|
77
|
+
return (
|
|
78
|
+
<Clipping
|
|
79
|
+
source={{ url: url || undefined, title: title || where || undefined, evidence: excerpt ? markExcerpt(excerpt, marks) : undefined, read }}
|
|
80
|
+
trust={sure}
|
|
81
|
+
title={title || where || "A source"}
|
|
82
|
+
action={action}
|
|
83
|
+
picked={picked}
|
|
84
|
+
className={cx("min-w-0 text-sm", className)}
|
|
85
|
+
>
|
|
86
|
+
{trust || onOpen || href ? (
|
|
87
|
+
<div className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-1 text-xs">
|
|
88
|
+
{trust ? (
|
|
89
|
+
<span className="inline-flex min-w-0 items-center gap-1 text-muted-foreground">
|
|
90
|
+
<Icon name={kind === "mail" ? "mail" : "globe"} size={12} className="shrink-0" />
|
|
91
|
+
<span className="min-w-0 break-words">{trust}</span>
|
|
92
|
+
</span>
|
|
93
|
+
) : null}
|
|
94
|
+
{onOpen ? (
|
|
95
|
+
<Button variant="link" size="inherit" onClick={onOpen} className="ml-auto">
|
|
96
|
+
{openLabel} <Icon name="external" size={12} />
|
|
97
|
+
</Button>
|
|
98
|
+
) : href ? (
|
|
99
|
+
<Button variant="link" size="inherit" href={href} target="_blank" rel="noreferrer" className="ml-auto">
|
|
100
|
+
{openLabel} <Icon name="external" size={12} />
|
|
101
|
+
</Button>
|
|
102
|
+
) : null}
|
|
103
|
+
</div>
|
|
104
|
+
) : null}
|
|
105
|
+
</Clipping>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -154,13 +154,22 @@ export function Spreadsheet({
|
|
|
154
154
|
const el = rootRef.current;
|
|
155
155
|
if (!el) return;
|
|
156
156
|
setBoxW(el.clientWidth);
|
|
157
|
-
|
|
157
|
+
// The new width is taken in the next frame, never inside the observer's
|
|
158
|
+
// own delivery: a change made there that touches anything observed
|
|
159
|
+
// (the virtualisers watch this grid too) makes the browser report
|
|
160
|
+
// "ResizeObserver loop completed with undelivered notifications".
|
|
161
|
+
let frame = 0;
|
|
162
|
+
const ro = new ResizeObserver(() => {
|
|
163
|
+
cancelAnimationFrame(frame);
|
|
164
|
+
frame = requestAnimationFrame(() => setBoxW(el.clientWidth));
|
|
165
|
+
});
|
|
158
166
|
ro.observe(el);
|
|
159
167
|
const mq = window.matchMedia?.("(pointer: coarse)");
|
|
160
168
|
const onMq = () => setCoarse(Boolean(mq?.matches));
|
|
161
169
|
onMq();
|
|
162
170
|
mq?.addEventListener?.("change", onMq);
|
|
163
171
|
return () => {
|
|
172
|
+
cancelAnimationFrame(frame);
|
|
164
173
|
ro.disconnect();
|
|
165
174
|
mq?.removeEventListener?.("change", onMq);
|
|
166
175
|
};
|
|
@@ -1065,6 +1074,10 @@ export function Spreadsheet({
|
|
|
1065
1074
|
overscan: 10,
|
|
1066
1075
|
scrollMargin: headH,
|
|
1067
1076
|
initialRect: { width: 1200, height: typeof height === "number" ? height : 560 },
|
|
1077
|
+
// The scroller's new size is read in the next frame, not inside the
|
|
1078
|
+
// observer's delivery (a synchronous re-render there is what the
|
|
1079
|
+
// browser reports as a ResizeObserver loop).
|
|
1080
|
+
useAnimationFrameWithResizeObserver: true,
|
|
1068
1081
|
rangeExtractor: keepRow,
|
|
1069
1082
|
getItemKey: (i) => viewRows[i]?.id ?? i,
|
|
1070
1083
|
});
|
|
@@ -1077,6 +1090,7 @@ export function Spreadsheet({
|
|
|
1077
1090
|
overscan: 2,
|
|
1078
1091
|
scrollMargin: gutterW + frozenW,
|
|
1079
1092
|
initialRect: { width: 1200, height: typeof height === "number" ? height : 560 },
|
|
1093
|
+
useAnimationFrameWithResizeObserver: true,
|
|
1080
1094
|
rangeExtractor: keepCol,
|
|
1081
1095
|
getItemKey: (i) => scrollCols[i]?.key ?? i,
|
|
1082
1096
|
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# StepPicker
|
|
2
|
+
|
|
3
|
+
The two ways to choose a step of an automation. They only say which kind a
|
|
4
|
+
person chose; where the step goes is the editor's call (`flow-editor` and
|
|
5
|
+
`automation-editor` do it for you).
|
|
6
|
+
|
|
7
|
+
- `StepPicker` — the popover a **+** on a connector opens: a search box,
|
|
8
|
+
then the kinds grouped Your apps · Think · Flow · Data · Tell · More,
|
|
9
|
+
each with one line on what it does and a tag: **free**, **paid** (it
|
|
10
|
+
costs credits when it runs) or **soon** (the platform does not run it
|
|
11
|
+
yet).
|
|
12
|
+
- `PaletteBar` — the strip along the bottom of a canvas: one icon per
|
|
13
|
+
kind, grouped, with an "AI" mark on a model call and an "A" on the agent.
|
|
14
|
+
|
|
15
|
+
```jsx
|
|
16
|
+
import { StepPicker, PaletteBar } from "../components/blocks/step-picker"; // a Makersclaw app
|
|
17
|
+
import { StepPicker, PaletteBar } from "@/components/makersclaw/blocks/step-picker"; // a shadcn project
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`makersclaw add step-picker` lays `automation-model` with it, which holds
|
|
21
|
+
the catalog both read. Client components. Tokens only: an agent step is
|
|
22
|
+
drawn in the app's accent (`primary`, as the kit's AgentMark draws the agent: solid for the agent, outlined for one model call) and everything else plain.
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
### StepPicker
|
|
27
|
+
|
|
28
|
+
- `onPick(kind)` — a kind was chosen: `action` · `tool` · `llm` · `agent` ·
|
|
29
|
+
`condition` · `loop` · `wait` · `stop` · `set` · `brain.read` · `search` ·
|
|
30
|
+
`notify` · `automation`.
|
|
31
|
+
- `onClose()` — Escape, or a press outside it.
|
|
32
|
+
- `title` — the dialog's name for a screen reader (default "Add a step").
|
|
33
|
+
- `inline` — in the flow of a page (the outline view), not floating over a
|
|
34
|
+
canvas.
|
|
35
|
+
- `runnable` — a `Set` of the kinds the platform runs. The rest say
|
|
36
|
+
"soon". Default: the kinds the engine runs today.
|
|
37
|
+
- `style`, `className` — where the floating panel sits. Never colour.
|
|
38
|
+
|
|
39
|
+
### PaletteBar
|
|
40
|
+
|
|
41
|
+
- `onAdd(kind)` — a kind was pressed.
|
|
42
|
+
- `className`.
|
|
43
|
+
|
|
44
|
+
## Never
|
|
45
|
+
|
|
46
|
+
- Never offer a kind the platform cannot run without saying "soon": the
|
|
47
|
+
save would refuse it later.
|
|
48
|
+
- Never a price in the picker beyond free or paid: a step's price comes
|
|
49
|
+
from the automation's estimate, on its card.
|
|
50
|
+
|
|
51
|
+
## Example
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
"use client";
|
|
55
|
+
import { useState } from "react";
|
|
56
|
+
import { StepPicker } from "../components/blocks/step-picker";
|
|
57
|
+
import { Button } from "../components/ui";
|
|
58
|
+
|
|
59
|
+
export default function AddStep({ onAdd }) {
|
|
60
|
+
const [open, setOpen] = useState(false);
|
|
61
|
+
return (
|
|
62
|
+
<div className="relative">
|
|
63
|
+
<Button variant="secondary" icon="plus" onClick={() => setOpen(true)}>
|
|
64
|
+
Add a step
|
|
65
|
+
</Button>
|
|
66
|
+
{open ? (
|
|
67
|
+
<StepPicker
|
|
68
|
+
onClose={() => setOpen(false)}
|
|
69
|
+
onPick={(kind) => {
|
|
70
|
+
setOpen(false);
|
|
71
|
+
onAdd(kind);
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
) : null}
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
```
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "step-picker",
|
|
3
|
+
"title": "StepPicker",
|
|
4
|
+
"description": "The two ways to choose a step of an automation: StepPicker, the popover a + on a connector opens (a search box, the kinds grouped Your apps / Think / Flow / Data / Tell, one line on what each does and whether it is free, paid or coming), and PaletteBar, the strip along the bottom of a canvas (one icon per kind). Both only say which kind a person chose; where it goes is the editor's call.",
|
|
5
|
+
"useWhen": "A screen lets a person add a step to an automation: from a + on the canvas or the outline (flow-editor does it for you), or from a button of your own. Not a general command palette (use Command).",
|
|
6
|
+
"tags": [
|
|
7
|
+
"automation",
|
|
8
|
+
"workflow",
|
|
9
|
+
"step",
|
|
10
|
+
"picker",
|
|
11
|
+
"palette",
|
|
12
|
+
"add",
|
|
13
|
+
"node",
|
|
14
|
+
"search",
|
|
15
|
+
"kinds",
|
|
16
|
+
"trigger",
|
|
17
|
+
"n8n",
|
|
18
|
+
"make"
|
|
19
|
+
],
|
|
20
|
+
"exports": [
|
|
21
|
+
"PaletteBar",
|
|
22
|
+
"StepPicker"
|
|
23
|
+
],
|
|
24
|
+
"files": [
|
|
25
|
+
"index.js",
|
|
26
|
+
"step-picker.jsx"
|
|
27
|
+
],
|
|
28
|
+
"requires": [
|
|
29
|
+
"automation-model"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// StepPicker and PaletteBar — the gallery's and the smoke test's surface.
|
|
4
|
+
// Not installed into apps. Press a kind: the page says which.
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { PaletteBar, StepPicker } from "../components/blocks/step-picker";
|
|
7
|
+
|
|
8
|
+
export default function StepPickerDemo() {
|
|
9
|
+
const [said, setSaid] = useState("Nothing chosen yet.");
|
|
10
|
+
return (
|
|
11
|
+
<div className="grid gap-6 p-4">
|
|
12
|
+
<p className="m-0 text-sm" role="status">
|
|
13
|
+
{said}
|
|
14
|
+
</p>
|
|
15
|
+
<div className="max-w-sm">
|
|
16
|
+
<StepPicker inline onClose={() => setSaid("Closed.")} onPick={(kind) => setSaid(`Chose ${kind}.`)} />
|
|
17
|
+
</div>
|
|
18
|
+
<div className="max-w-full">
|
|
19
|
+
<PaletteBar onAdd={(kind) => setSaid(`Added ${kind}.`)} />
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// Two ways to choose a step: the picker a + on a connector opens (search,
|
|
4
|
+
// the kinds grouped, what each does), and the palette along the bottom of
|
|
5
|
+
// a canvas (one icon per kind, grouped). Both read the catalog
|
|
6
|
+
// (automation-model); both only say which kind a person chose. Where it
|
|
7
|
+
// goes is the editor's call. Props in, callbacks out; tokens only.
|
|
8
|
+
|
|
9
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
10
|
+
import { Input, cx } from "../../ui";
|
|
11
|
+
import { Glyph, KINDS, isRunnable, paletteGroups } from "../automation-model";
|
|
12
|
+
|
|
13
|
+
const matches = (k, q) => {
|
|
14
|
+
if (!q) return true;
|
|
15
|
+
const hay = `${k.name} ${k.blurb} ${k.kind}`.toLowerCase();
|
|
16
|
+
return q
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.split(/\s+/)
|
|
19
|
+
.every((w) => hay.includes(w));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/** How a kind is dressed: the agent solid in the app's accent, a model
|
|
23
|
+
* call outlined in it, every other kind plain. */
|
|
24
|
+
const TILE = {
|
|
25
|
+
plain: "border-border bg-card text-muted-foreground",
|
|
26
|
+
model: "border-primary/55 bg-card text-primary",
|
|
27
|
+
agent: "border-primary bg-primary/15 text-primary",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* onPick(kind) a kind was chosen ("action", "condition", "llm" …)
|
|
32
|
+
* onClose() Escape, or a press outside
|
|
33
|
+
* title the dialog's name (default "Add a step")
|
|
34
|
+
* inline in the flow of a page (the outline), not floating
|
|
35
|
+
* runnable a Set of the kinds the platform runs; the rest say "soon"
|
|
36
|
+
* (default: automation-model's RUNNABLE)
|
|
37
|
+
* className, style the floating panel's place (the editor sets it)
|
|
38
|
+
*/
|
|
39
|
+
export function StepPicker({ onPick, onClose, title = "Add a step", inline = false, runnable, className, style }) {
|
|
40
|
+
const [q, setQ] = useState("");
|
|
41
|
+
const ref = useRef(null);
|
|
42
|
+
const groups = useMemo(
|
|
43
|
+
() =>
|
|
44
|
+
paletteGroups()
|
|
45
|
+
.map((g) => ({ ...g, kinds: g.kinds.filter((k) => matches(k, q)) }))
|
|
46
|
+
.filter((g) => g.kinds.length),
|
|
47
|
+
[q],
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
const onDown = (e) => {
|
|
52
|
+
if (ref.current && !ref.current.contains(e.target)) onClose?.();
|
|
53
|
+
};
|
|
54
|
+
const onKey = (e) => {
|
|
55
|
+
if (e.key === "Escape") {
|
|
56
|
+
e.preventDefault();
|
|
57
|
+
onClose?.();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
document.addEventListener("pointerdown", onDown, true);
|
|
61
|
+
document.addEventListener("keydown", onKey, true);
|
|
62
|
+
return () => {
|
|
63
|
+
document.removeEventListener("pointerdown", onDown, true);
|
|
64
|
+
document.removeEventListener("keydown", onKey, true);
|
|
65
|
+
};
|
|
66
|
+
}, [onClose]);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
ref={ref}
|
|
71
|
+
role="dialog"
|
|
72
|
+
aria-label={title}
|
|
73
|
+
style={style}
|
|
74
|
+
onPointerDown={(e) => e.stopPropagation()}
|
|
75
|
+
className={cx(
|
|
76
|
+
"z-20 flex min-w-0 flex-col gap-2 rounded-lg border border-border bg-popover p-2 text-popover-foreground",
|
|
77
|
+
inline ? "w-full" : "absolute w-[330px] max-w-[calc(100%_-_1rem)] shadow-lg",
|
|
78
|
+
className,
|
|
79
|
+
)}
|
|
80
|
+
>
|
|
81
|
+
<Input type="search" placeholder="Search steps" aria-label="Search steps" value={q} autoFocus onChange={(e) => setQ(e.target.value)} />
|
|
82
|
+
<div data-scroll className={cx("grid min-w-0 gap-2 overflow-y-auto", inline ? "max-h-72" : "max-h-[320px]")}>
|
|
83
|
+
{groups.length === 0 ? <p className="m-0 p-2 text-sm text-muted-foreground">No step matches “{q}”.</p> : null}
|
|
84
|
+
{groups.map((g) => (
|
|
85
|
+
<section key={g.group} aria-label={g.label} className="grid gap-0.5">
|
|
86
|
+
<h4 className="m-0 px-2 pt-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground">{g.label}</h4>
|
|
87
|
+
{g.kinds.map((k) => (
|
|
88
|
+
<button
|
|
89
|
+
key={k.kind}
|
|
90
|
+
type="button"
|
|
91
|
+
onClick={() => onPick?.(k.kind)}
|
|
92
|
+
className="flex min-w-0 items-center gap-2.5 rounded-md border border-transparent px-2 py-1.5 text-left hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
93
|
+
>
|
|
94
|
+
<span className={cx("inline-flex size-9 shrink-0 items-center justify-center rounded-lg border", TILE[k.tone] ?? TILE.plain)}>
|
|
95
|
+
<Glyph name={k.glyph} size={18} />
|
|
96
|
+
</span>
|
|
97
|
+
<span className="grid min-w-0 flex-1 gap-0.5">
|
|
98
|
+
<b className="text-[13px] font-semibold">{k.name}</b>
|
|
99
|
+
<span className="text-xs leading-snug text-muted-foreground">{k.blurb}</span>
|
|
100
|
+
</span>
|
|
101
|
+
<span className="shrink-0 rounded-full border border-border px-1.5 text-2xs text-muted-foreground">{k.paid ? "paid" : !isRunnable(k.kind, runnable) ? "soon" : "free"}</span>
|
|
102
|
+
</button>
|
|
103
|
+
))}
|
|
104
|
+
</section>
|
|
105
|
+
))}
|
|
106
|
+
</div>
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The bar along the bottom of a canvas: every kind, one icon each, grouped.
|
|
113
|
+
* onAdd(kind) a kind was pressed
|
|
114
|
+
*/
|
|
115
|
+
export function PaletteBar({ onAdd, className }) {
|
|
116
|
+
const groups = paletteGroups();
|
|
117
|
+
return (
|
|
118
|
+
<div role="toolbar" aria-label="Add a step" className={cx("flex max-w-full items-end gap-3 overflow-x-auto rounded-xl border border-border bg-card p-1.5 text-card-foreground shadow-md", className)}>
|
|
119
|
+
{groups.map((g) => (
|
|
120
|
+
<div key={g.group} className="grid shrink-0 gap-1">
|
|
121
|
+
<span className="px-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground">{g.label}</span>
|
|
122
|
+
<div className="flex gap-0.5">
|
|
123
|
+
{g.kinds.map((k) => (
|
|
124
|
+
<button
|
|
125
|
+
key={k.kind}
|
|
126
|
+
type="button"
|
|
127
|
+
title={`${k.name}: ${k.blurb}`}
|
|
128
|
+
aria-label={`Add ${KINDS[k.kind].name}`}
|
|
129
|
+
onClick={() => onAdd?.(k.kind)}
|
|
130
|
+
className={cx(
|
|
131
|
+
"relative inline-flex size-9 items-center justify-center rounded-lg border border-transparent hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
132
|
+
k.tone === "plain" ? "text-muted-foreground hover:text-foreground" : "text-primary",
|
|
133
|
+
)}
|
|
134
|
+
>
|
|
135
|
+
<Glyph name={k.glyph} size={16} />
|
|
136
|
+
{k.mark ? <em className="absolute -bottom-0.5 -right-0.5 rounded-full bg-primary px-1 text-2xs font-bold not-italic leading-none text-primary-foreground">{k.mark === "model" ? "AI" : "A"}</em> : null}
|
|
137
|
+
</button>
|
|
138
|
+
))}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
))}
|
|
142
|
+
</div>
|
|
143
|
+
);
|
|
144
|
+
}
|