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,203 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// A job drawn as a graph on a dotted ground: its Trigger, each step of the
|
|
4
|
+
// chosen run with how it went, and the result; over it the run picker and
|
|
5
|
+
// Re-run; in its head the Live switch and "Trigger manually" with its
|
|
6
|
+
// price; beside it the run history and the overview (the sibling
|
|
7
|
+
// run-history block). Before any run it draws the job's declared steps
|
|
8
|
+
// (`plan`) in pencil (dashed), with an honest line, so a job not set up
|
|
9
|
+
// still has something to look at.
|
|
10
|
+
//
|
|
11
|
+
// Props in, callbacks out; it reads nothing and formats nothing. Tokens
|
|
12
|
+
// only. Every status is a mark AND a word. Its own width decides its
|
|
13
|
+
// layout (@container): under about 768 px the history and the overview
|
|
14
|
+
// stack under the graph. The graph always runs top to bottom, each step a
|
|
15
|
+
// full-width node with its whole title: it never scrolls sideways and
|
|
16
|
+
// never cuts a title (a left-to-right strip did both at a desk window's
|
|
17
|
+
// width once a job had six steps: the CRM, 2026-10-11).
|
|
18
|
+
|
|
19
|
+
import { Button, Icon, Select, Switch, cx } from "../../ui";
|
|
20
|
+
import { RunHistory, RunOverview } from "../run-history";
|
|
21
|
+
|
|
22
|
+
const MARK = {
|
|
23
|
+
done: { icon: "circle-check", tone: "text-success", ring: "border-success", word: "Completed" },
|
|
24
|
+
ok: { icon: "circle-check", tone: "text-success", ring: "border-success", word: "Completed" },
|
|
25
|
+
complete: { icon: "circle-check", tone: "text-success", ring: "border-success", word: "Completed" },
|
|
26
|
+
failed: { icon: "circle-x", tone: "text-destructive", ring: "border-destructive", word: "Failed" },
|
|
27
|
+
running: { icon: "loader", tone: "text-info", ring: "border-info", word: "Running" },
|
|
28
|
+
needs_you: { icon: "circle-help", tone: "text-warning", ring: "border-warning", word: "Needs you" },
|
|
29
|
+
stopped: { icon: "stop", tone: "text-muted-foreground", ring: "border-border", word: "Stopped" },
|
|
30
|
+
skipped: { icon: "minus", tone: "text-muted-foreground", ring: "border-border", word: "Skipped" },
|
|
31
|
+
waiting: { icon: "circle-dashed", tone: "text-muted-foreground", ring: "border-border", word: "Not reached" },
|
|
32
|
+
planned: { icon: "pencil", tone: "text-muted-foreground", ring: "border-border", word: "Not run yet" },
|
|
33
|
+
};
|
|
34
|
+
const markOf = (s) => MARK[s] ?? MARK.waiting;
|
|
35
|
+
|
|
36
|
+
/** The dotted ground: the theme's muted ink, faded by the layer's
|
|
37
|
+
* opacity, so it reads on a light theme and a dark one alike. */
|
|
38
|
+
const GROUND = { backgroundImage: "radial-gradient(var(--color-muted-foreground) 1px, transparent 1.5px)", backgroundSize: "16px 16px" };
|
|
39
|
+
|
|
40
|
+
function StatusWord({ status }) {
|
|
41
|
+
const m = markOf(status);
|
|
42
|
+
return (
|
|
43
|
+
<span className={cx("inline-flex items-center gap-1 text-[11.5px]", m.tone)}>
|
|
44
|
+
<Icon name={m.icon} size={12} className={status === "running" ? "animate-spin motion-reduce:animate-none" : undefined} />
|
|
45
|
+
{m.word}
|
|
46
|
+
</span>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** One node: a kicker over it (Trigger, Step 2, Result), the label, a
|
|
51
|
+
* detail, its status. `pencil` draws it dashed: planned, not run. */
|
|
52
|
+
function Node({ kicker, icon, label, detail, status, pencil = false }) {
|
|
53
|
+
const m = status ? markOf(status) : null;
|
|
54
|
+
return (
|
|
55
|
+
<div className="grid w-full min-w-0 gap-1">
|
|
56
|
+
<div className="flex min-w-0 items-center justify-between gap-2 text-[11.5px] text-muted-foreground">
|
|
57
|
+
<span className="truncate">{kicker}</span>
|
|
58
|
+
{status ? <StatusWord status={status} /> : null}
|
|
59
|
+
</div>
|
|
60
|
+
<div
|
|
61
|
+
className={cx(
|
|
62
|
+
"grid min-w-0 gap-0.5 rounded-[var(--radius)] border bg-card px-3 py-2.5 text-card-foreground",
|
|
63
|
+
pencil ? "border-dashed border-muted-foreground bg-transparent" : m && status !== "waiting" && status !== "skipped" ? m.ring : "border-border",
|
|
64
|
+
)}
|
|
65
|
+
>
|
|
66
|
+
<span className="flex min-w-0 items-start gap-2">
|
|
67
|
+
{icon ? <Icon name={icon} size={14} className="mt-0.5 shrink-0 text-muted-foreground" /> : null}
|
|
68
|
+
<b className={cx("min-w-0 break-words text-[13px] font-semibold", pencil && "font-medium text-muted-foreground")}>{label}</b>
|
|
69
|
+
</span>
|
|
70
|
+
{detail ? <span className="min-w-0 break-words text-xs text-muted-foreground">{detail}</span> : null}
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The line between two nodes, going down. */
|
|
77
|
+
function Link({ pencil }) {
|
|
78
|
+
return (
|
|
79
|
+
<span aria-hidden="true" className="flex shrink-0 justify-start pl-6">
|
|
80
|
+
<span className={cx("block h-5 w-0 border-l", pencil ? "border-dashed border-muted-foreground" : "border-border")} />
|
|
81
|
+
</span>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* title the job's name ("Morning read")
|
|
87
|
+
* trigger { label: "Every weekday at 07:00", detail: "Starts on its own" }
|
|
88
|
+
* steps the chosen run's steps: [{ label, status, detail? }]
|
|
89
|
+
* status: done|failed|running|needs_you|stopped|skipped|waiting
|
|
90
|
+
* result { label: "Wrote 4 people, 1 deal move", detail, status }
|
|
91
|
+
* runs RunHistory's rows ({ id, status, title, line, when, cost })
|
|
92
|
+
* selected the run drawn; onSelect(run)
|
|
93
|
+
* overview RunOverview's props, or null
|
|
94
|
+
* live { on, onToggle(next), busy } or null (no switch)
|
|
95
|
+
* run { label: "Trigger manually", price: "about 700 cr", onRun, loading, disabled, why } or null
|
|
96
|
+
* rerun { onRun, loading, label? } or null: Re-run the chosen run
|
|
97
|
+
* plan the job's declared steps, drawn in pencil before any run
|
|
98
|
+
* empty the honest line before any run
|
|
99
|
+
*/
|
|
100
|
+
export function WorkflowView({
|
|
101
|
+
title,
|
|
102
|
+
trigger,
|
|
103
|
+
steps = [],
|
|
104
|
+
result,
|
|
105
|
+
runs = [],
|
|
106
|
+
selected,
|
|
107
|
+
onSelect,
|
|
108
|
+
overview,
|
|
109
|
+
live = null,
|
|
110
|
+
run = null,
|
|
111
|
+
rerun = null,
|
|
112
|
+
plan = null,
|
|
113
|
+
empty,
|
|
114
|
+
className,
|
|
115
|
+
}) {
|
|
116
|
+
const hasRuns = runs.length > 0;
|
|
117
|
+
const chosen = runs.find((r) => r.id === selected) ?? null;
|
|
118
|
+
const pencil = !hasRuns || (!steps.length && Boolean(plan?.length));
|
|
119
|
+
const drawn = pencil ? (plan ?? []).map((label) => ({ label, status: "planned" })) : steps;
|
|
120
|
+
|
|
121
|
+
return (
|
|
122
|
+
<section aria-label={title} className={cx("@container grid min-w-0 overflow-hidden rounded-[var(--radius)] border border-border bg-background text-foreground", className)}>
|
|
123
|
+
<header className="flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 border-b border-border px-3 py-2">
|
|
124
|
+
<b className="min-w-[10rem] flex-1 truncate text-sm font-semibold">{title}</b>
|
|
125
|
+
{live ? (
|
|
126
|
+
<Switch
|
|
127
|
+
checked={Boolean(live.on)}
|
|
128
|
+
disabled={Boolean(live.busy)}
|
|
129
|
+
onChange={(e) => live.onToggle?.(Boolean(e?.target?.checked))}
|
|
130
|
+
label={live.on ? "Live" : "Off"}
|
|
131
|
+
className="-my-1.5 text-xs"
|
|
132
|
+
/>
|
|
133
|
+
) : null}
|
|
134
|
+
{run ? (
|
|
135
|
+
<Button size="sm" icon="play" loading={run.loading} disabled={run.disabled} onClick={run.onRun} title={run.why} className="max-w-full">
|
|
136
|
+
<span className="truncate">{run.label ?? "Trigger manually"}</span>
|
|
137
|
+
{run.price ? <span className="font-normal text-muted-foreground">{run.price}</span> : null}
|
|
138
|
+
</Button>
|
|
139
|
+
) : null}
|
|
140
|
+
</header>
|
|
141
|
+
|
|
142
|
+
<div className="grid min-w-0 @3xl:grid-cols-[minmax(0,1fr)_300px]">
|
|
143
|
+
<div className="relative isolate grid min-w-0 content-start gap-4 p-3 @md:p-4">
|
|
144
|
+
<span aria-hidden="true" className="pointer-events-none absolute inset-0 -z-10 opacity-30" style={GROUND} />
|
|
145
|
+
{hasRuns ? (
|
|
146
|
+
<div className="flex min-w-0 max-w-full flex-wrap items-center gap-2 justify-self-start rounded-[var(--radius)] border border-border bg-card p-1.5 text-card-foreground">
|
|
147
|
+
<span className="block w-72 max-w-full">
|
|
148
|
+
<Select
|
|
149
|
+
aria-label="The run shown"
|
|
150
|
+
value={chosen?.id ?? ""}
|
|
151
|
+
onChange={(e) => {
|
|
152
|
+
const next = runs.find((r) => r.id === e.target.value);
|
|
153
|
+
if (next) onSelect?.(next);
|
|
154
|
+
}}
|
|
155
|
+
options={runs.map((r) => ({ value: r.id, label: r.title }))}
|
|
156
|
+
className="min-h-9 text-[13px]"
|
|
157
|
+
/>
|
|
158
|
+
</span>
|
|
159
|
+
{rerun ? (
|
|
160
|
+
<Button size="sm" variant="quiet" icon="rotate-cw" loading={rerun.loading} disabled={rerun.disabled} onClick={rerun.onRun}>
|
|
161
|
+
{rerun.label ?? "Re-run"}
|
|
162
|
+
</Button>
|
|
163
|
+
) : null}
|
|
164
|
+
</div>
|
|
165
|
+
) : null}
|
|
166
|
+
|
|
167
|
+
<ol aria-label={pencil ? "The steps it will take" : "The steps of this run"} className="m-0 flex min-w-0 max-w-xl list-none flex-col items-stretch p-0">
|
|
168
|
+
<li className="flex min-w-0 flex-col">
|
|
169
|
+
<Node kicker="Trigger" icon="zap" label={trigger?.label ?? "When it starts"} detail={trigger?.detail} pencil={pencil && !trigger} />
|
|
170
|
+
</li>
|
|
171
|
+
{drawn.map((s, i) => (
|
|
172
|
+
<li key={`${s.label}-${i}`} className="flex min-w-0 flex-col">
|
|
173
|
+
<Link pencil={pencil} />
|
|
174
|
+
<Node kicker={`Step ${i + 1}`} label={s.label} detail={s.detail} status={s.status} pencil={pencil} />
|
|
175
|
+
</li>
|
|
176
|
+
))}
|
|
177
|
+
{result || pencil ? (
|
|
178
|
+
<li className="flex min-w-0 flex-col">
|
|
179
|
+
<Link pencil={pencil} />
|
|
180
|
+
<Node
|
|
181
|
+
kicker="Result"
|
|
182
|
+
icon="flag"
|
|
183
|
+
label={result?.label ?? "What it wrote"}
|
|
184
|
+
detail={result?.detail}
|
|
185
|
+
status={pencil ? undefined : result?.status}
|
|
186
|
+
pencil={pencil}
|
|
187
|
+
/>
|
|
188
|
+
</li>
|
|
189
|
+
) : null}
|
|
190
|
+
</ol>
|
|
191
|
+
|
|
192
|
+
{pencil ? <p className="m-0 max-w-prose rounded-[var(--radius)] bg-background px-2 py-1 text-[13px] text-muted-foreground justify-self-start">{empty ?? "No runs yet."}</p> : null}
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<aside aria-label="Runs" className="grid min-w-0 content-start border-t border-border bg-card text-card-foreground @3xl:border-l @3xl:border-t-0">
|
|
196
|
+
<h3 className="m-0 px-3.5 pb-1 pt-3 text-sm font-semibold">Run history</h3>
|
|
197
|
+
<RunHistory runs={runs} selected={selected} onSelect={onSelect} label="Run history" empty={hasRuns ? undefined : "No runs yet."} />
|
|
198
|
+
{overview ? <RunOverview {...overview} className={cx("p-3.5", overview.className)} /> : null}
|
|
199
|
+
</aside>
|
|
200
|
+
</div>
|
|
201
|
+
</section>
|
|
202
|
+
);
|
|
203
|
+
}
|
package/src/cli.mjs
CHANGED
|
@@ -107,7 +107,7 @@ const listLine = (paths, n = 6) => (paths.length > n ? `${paths.slice(0, n).join
|
|
|
107
107
|
|
|
108
108
|
function packageLines(changes) {
|
|
109
109
|
if (!changes.length) return [];
|
|
110
|
-
return [` package.json: ${changes.map((c) => `${c.name} ${c.from ?? "(new)"} → ${c.to}`).join(" · ")}`];
|
|
110
|
+
return [` package.json: ${changes.map((c) => `${c.name} ${c.from ?? "(new)"} → ${c.to ?? "(removed)"}`).join(" · ")}`];
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/** The lock's line, when it was written. What it left out is a note. */
|
|
@@ -230,7 +230,7 @@ function diffText(r) {
|
|
|
230
230
|
return lines.join("\n");
|
|
231
231
|
}
|
|
232
232
|
for (const e of r.entries) lines.push(` ${e.item.padEnd(14)} ${e.status.padEnd(8)} ${e.path}${e.detail ? ` — ${e.detail}` : ""}`);
|
|
233
|
-
for (const c of r.package) lines.push(` ${"package.json".padEnd(14)} ${c.key}.${c.name}: ${c.from ?? "(new)"} → ${c.to}`);
|
|
233
|
+
for (const c of r.package) lines.push(` ${"package.json".padEnd(14)} ${c.key}.${c.name}: ${c.from ?? "(new)"} → ${c.to ?? "(removed)"}`);
|
|
234
234
|
lines.push(`next: npx makersclaw update${r.compatible ? "" : " --major"}`);
|
|
235
235
|
return lines.join("\n");
|
|
236
236
|
}
|
package/src/install.mjs
CHANGED
|
@@ -28,7 +28,7 @@ import { join } from "node:path";
|
|
|
28
28
|
import { hashFile, readJson, removeFile, sha256, walk, writeFile, writeJson } from "./fsutil.mjs";
|
|
29
29
|
import { LOCKFILE, LockError, deriveLock, parseLock } from "./lockfile.mjs";
|
|
30
30
|
import { NPM_LOCKFILE, PNPM_VERSION, installDeps } from "./pm.mjs";
|
|
31
|
-
import { BASE_MODE, BLOCK_DIR, loadBlocks, loadItems, loadTemplate, modeFiles, packageInfo, readmeOf, suggest, templateNames } from "./registry.mjs";
|
|
31
|
+
import { BASE_MODE, BLOCK_DIR, loadBlocks, loadItems, loadTemplate, modeDropScripts, modeFiles, modePackage, packageInfo, readmeOf, suggest, templateNames } from "./registry.mjs";
|
|
32
32
|
|
|
33
33
|
export const MANIFEST = "makersclaw.json";
|
|
34
34
|
export const PINS = "check/pins.json";
|
|
@@ -231,8 +231,11 @@ function loadTemplateOrFail(name) {
|
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
/** package.json: the template's scripts and dependencies win for the keys
|
|
234
|
-
* it names; every other key is the app's.
|
|
235
|
-
|
|
234
|
+
* it names; every other key is the app's. `dropScripts` are the scripts
|
|
235
|
+
* the app's mode has none of (registry modeDropScripts): removed whatever
|
|
236
|
+
* they say, so a server app switched to browser loses its `start`; a
|
|
237
|
+
* removal is a change `to: null`. */
|
|
238
|
+
function mergePackage(app, tpl, dropScripts = []) {
|
|
236
239
|
const out = { ...app };
|
|
237
240
|
const changes = [];
|
|
238
241
|
for (const key of ["scripts", "dependencies", "devDependencies"]) {
|
|
@@ -244,6 +247,12 @@ function mergePackage(app, tpl) {
|
|
|
244
247
|
out[key][name] = value;
|
|
245
248
|
}
|
|
246
249
|
}
|
|
250
|
+
for (const name of dropScripts) {
|
|
251
|
+
if (out.scripts?.[name] === undefined) continue;
|
|
252
|
+
out.scripts = { ...out.scripts };
|
|
253
|
+
changes.push({ key: "scripts", name, from: out.scripts[name], to: null });
|
|
254
|
+
delete out.scripts[name];
|
|
255
|
+
}
|
|
247
256
|
return { out, changes };
|
|
248
257
|
}
|
|
249
258
|
|
|
@@ -305,6 +314,44 @@ function ownedPath(path, tpl) {
|
|
|
305
314
|
return tpl.files.some((f) => f.class === "fixed" && f.path === path);
|
|
306
315
|
}
|
|
307
316
|
|
|
317
|
+
/**
|
|
318
|
+
* The blocks an update must add: those the installed blocks require, and
|
|
319
|
+
* those they require in turn, that the app does not have and this version
|
|
320
|
+
* ships. In the order they are needed, each with the block that asked.
|
|
321
|
+
* A requirement that is a kit component, or a block this version does not
|
|
322
|
+
* ship, is not a block to add.
|
|
323
|
+
*/
|
|
324
|
+
function requiredMissing(installed, known) {
|
|
325
|
+
const have = new Set(installed);
|
|
326
|
+
const out = [];
|
|
327
|
+
const queue = [...installed];
|
|
328
|
+
while (queue.length) {
|
|
329
|
+
const name = queue.shift();
|
|
330
|
+
for (const r of known.find((b) => b.name === name)?.requires ?? []) {
|
|
331
|
+
const block = known.find((b) => b.name === r);
|
|
332
|
+
if (!block || have.has(r)) continue;
|
|
333
|
+
have.add(r);
|
|
334
|
+
out.push({ block, by: name });
|
|
335
|
+
queue.push(r);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return out;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* The blocks an update should tell the app about and not add: those that
|
|
343
|
+
* carry an `offer` in their block.json, that the app does not have, born
|
|
344
|
+
* (`offer.since`) at or after the version the app was last laid from. An app
|
|
345
|
+
* decides to take one (`makersclaw add <name>`); update never does it for it,
|
|
346
|
+
* since a block replaces what the app drew itself. Each is
|
|
347
|
+
* { name, since, why, add }.
|
|
348
|
+
*/
|
|
349
|
+
export function offeredBlocks(known, have, appVersion) {
|
|
350
|
+
return known
|
|
351
|
+
.filter((b) => b.offer && !(b.name in have) && (!parseVersion(appVersion) || !newer(appVersion, b.offer.since)))
|
|
352
|
+
.map((b) => ({ name: b.name, since: b.offer.since, why: b.offer.why, add: `makersclaw add ${b.name}` }));
|
|
353
|
+
}
|
|
354
|
+
|
|
308
355
|
/**
|
|
309
356
|
* Lay a template — and the blocks the app already has — over `dir`: the
|
|
310
357
|
* one routine behind init, init --force, update and mode. Fixed files and
|
|
@@ -324,7 +371,7 @@ function ownedPath(path, tpl) {
|
|
|
324
371
|
* lay is not pinned, and one that was pinned is removed as a retired one
|
|
325
372
|
* is, so a switch of mode leaves only the new mode's fixed files.
|
|
326
373
|
*/
|
|
327
|
-
function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
374
|
+
function lay(dir, tpl, before, { tables, mode, offer = false } = {}) {
|
|
328
375
|
const v = version();
|
|
329
376
|
const written = [];
|
|
330
377
|
const kept = [];
|
|
@@ -346,8 +393,10 @@ function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
|
346
393
|
kept.push(f.path);
|
|
347
394
|
continue;
|
|
348
395
|
}
|
|
396
|
+
// package.json is the mode's (registry modePackage): a browser app's
|
|
397
|
+
// has no start script, whether it is laid new or merged.
|
|
349
398
|
if (f.class === "merged" && existsSync(to)) {
|
|
350
|
-
const { out, changes } = mergePackage(readJson(to),
|
|
399
|
+
const { out, changes } = mergePackage(readJson(to), modePackage(tpl, appMode), modeDropScripts(tpl, appMode));
|
|
351
400
|
if (changes.length) {
|
|
352
401
|
writeJson(to, out);
|
|
353
402
|
written.push(f.path);
|
|
@@ -355,6 +404,11 @@ function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
|
355
404
|
pkg = changes;
|
|
356
405
|
continue;
|
|
357
406
|
}
|
|
407
|
+
if (f.class === "merged") {
|
|
408
|
+
writeJson(to, modePackage(tpl, appMode));
|
|
409
|
+
written.push(f.path);
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
358
412
|
const bytes = readFileSync(f.from);
|
|
359
413
|
const hash = sha256(bytes);
|
|
360
414
|
if (hashFile(to) !== hash) {
|
|
@@ -367,6 +421,19 @@ function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
|
367
421
|
const blocks = {};
|
|
368
422
|
const blockDeps = {};
|
|
369
423
|
const known = loadBlocks();
|
|
424
|
+
const layBlock = (block) => {
|
|
425
|
+
for (const f of block.files) {
|
|
426
|
+
const bytes = readFileSync(f.from);
|
|
427
|
+
const hash = sha256(bytes);
|
|
428
|
+
if (hashFile(join(dir, f.to)) !== hash) {
|
|
429
|
+
writeFile(join(dir, f.to), bytes);
|
|
430
|
+
written.push(f.to);
|
|
431
|
+
}
|
|
432
|
+
pins[f.to] = hash;
|
|
433
|
+
}
|
|
434
|
+
blocks[block.name] = v;
|
|
435
|
+
Object.assign(blockDeps, block.dependencies);
|
|
436
|
+
};
|
|
370
437
|
for (const [name, from] of Object.entries(before.manifest?.blocks ?? {})) {
|
|
371
438
|
if (!existsSync(join(dir, BLOCK_DIR, name))) {
|
|
372
439
|
notes.push(`${name}: its folder is gone — dropped from ${MANIFEST}`);
|
|
@@ -379,18 +446,20 @@ function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
|
379
446
|
notes.push(`${name}: not in makersclaw ${v} — left as installed (${from})`);
|
|
380
447
|
continue;
|
|
381
448
|
}
|
|
382
|
-
|
|
383
|
-
const bytes = readFileSync(f.from);
|
|
384
|
-
const hash = sha256(bytes);
|
|
385
|
-
if (hashFile(join(dir, f.to)) !== hash) {
|
|
386
|
-
writeFile(join(dir, f.to), bytes);
|
|
387
|
-
written.push(f.to);
|
|
388
|
-
}
|
|
389
|
-
pins[f.to] = hash;
|
|
390
|
-
}
|
|
391
|
-
blocks[name] = v;
|
|
392
|
-
Object.assign(blockDeps, block.dependencies);
|
|
449
|
+
layBlock(block);
|
|
393
450
|
}
|
|
451
|
+
// A block this version needs and the app does not have: one an installed
|
|
452
|
+
// block now requires (agent-pane has required chat-pane since 0.8.1). It is
|
|
453
|
+
// laid with it, or the installed block's imports would not resolve.
|
|
454
|
+
for (const { block, by } of requiredMissing(Object.keys(blocks), known)) {
|
|
455
|
+
layBlock(block);
|
|
456
|
+
notes.push(`${block.name}: added — ${by} requires it`);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// What is new and the app does not have: said, not added (update only).
|
|
460
|
+
const available = offer ? offeredBlocks(known, blocks, before.manifest?.version) : [];
|
|
461
|
+
for (const a of available) notes.push(`${a.name}: new in ${a.since}, not in this app — ${a.why}. ${a.add}`);
|
|
462
|
+
if (available.length > 1) notes.push(`to take them all: makersclaw add ${available.map((a) => a.name).join(" ")}`);
|
|
394
463
|
|
|
395
464
|
// The blocks' npm packages, at the versions this release pins them to
|
|
396
465
|
// (block.json `dependencies`): a block's files and its packages move
|
|
@@ -449,6 +518,7 @@ function lay(dir, tpl, before, { tables, mode } = {}) {
|
|
|
449
518
|
install: fresh || lockWritten || pkg.some((c) => c.key !== "scripts"),
|
|
450
519
|
pinned: Object.keys(pins).length,
|
|
451
520
|
blocks: Object.keys(blocks),
|
|
521
|
+
available,
|
|
452
522
|
notes,
|
|
453
523
|
};
|
|
454
524
|
}
|
|
@@ -478,7 +548,8 @@ export function init(dir, { template = "next", force = false, tables, mode: aske
|
|
|
478
548
|
}
|
|
479
549
|
|
|
480
550
|
/** `update [--major] [--adopt]` — this version's fixed files, docs and
|
|
481
|
-
* blocks
|
|
551
|
+
* blocks (and any block an installed one now requires: `requiredMissing`).
|
|
552
|
+
* `--adopt` takes on an app laid before makersclaw kept a
|
|
482
553
|
* manifest — but only one from the kit's era (it has check/pins.json):
|
|
483
554
|
* its screens were written against this kit, so laying the fixed files
|
|
484
555
|
* again keeps them working. An older app drew its own controls; it needs
|
|
@@ -491,7 +562,7 @@ export function update(dir, { major = false, adopt = false } = {}) {
|
|
|
491
562
|
"rebuild it onto the template — its screens need writing again, not just its files replacing",
|
|
492
563
|
);
|
|
493
564
|
}
|
|
494
|
-
return { ...lay(dir, loadTemplateOrFail("next"), readState(dir)), adopted: true };
|
|
565
|
+
return { ...lay(dir, loadTemplateOrFail("next"), readState(dir), { offer: true }), adopted: true };
|
|
495
566
|
}
|
|
496
567
|
const before = requireManifest(dir);
|
|
497
568
|
const tpl = loadTemplateOrFail(before.manifest.template);
|
|
@@ -508,7 +579,7 @@ export function update(dir, { major = false, adopt = false } = {}) {
|
|
|
508
579
|
"makersclaw diff shows what changes; makersclaw update --major lays it anyway",
|
|
509
580
|
);
|
|
510
581
|
}
|
|
511
|
-
return lay(dir, tpl, before);
|
|
582
|
+
return lay(dir, tpl, before, { offer: true });
|
|
512
583
|
}
|
|
513
584
|
|
|
514
585
|
/** What an app's own code must change when it moves to a mode. The
|
|
@@ -766,15 +837,22 @@ export function diff(dir) {
|
|
|
766
837
|
}
|
|
767
838
|
}
|
|
768
839
|
|
|
840
|
+
// …and the blocks an installed block now requires, which update adds.
|
|
841
|
+
const added = requiredMissing(Object.keys(manifest.blocks ?? {}), known);
|
|
842
|
+
for (const { block, by } of added) {
|
|
843
|
+
for (const f of block.files) entries.push({ item: block.name, path: f.to, status: "new", detail: `${by} requires it` });
|
|
844
|
+
}
|
|
845
|
+
|
|
769
846
|
const pkgPath = join(dir, "package.json");
|
|
770
847
|
const tplPkg = tpl.files.find((f) => f.class === "merged");
|
|
771
|
-
const
|
|
848
|
+
const drop = modeDropScripts(tpl, appMode);
|
|
849
|
+
const pkg = existsSync(pkgPath) && tplPkg ? mergePackage(readJson(pkgPath), modePackage(tpl, appMode), drop).changes : [];
|
|
772
850
|
// …and the installed blocks' npm packages, which update lays with them.
|
|
773
|
-
const blockDeps = Object.assign({}, ...Object.keys(manifest.blocks ?? {}).map((n) => known.find((b) => b.name === n)?.dependencies ?? {}));
|
|
851
|
+
const blockDeps = Object.assign({}, ...[...Object.keys(manifest.blocks ?? {}), ...added.map((a) => a.block.name)].map((n) => known.find((b) => b.name === n)?.dependencies ?? {}));
|
|
774
852
|
if (existsSync(pkgPath) && Object.keys(blockDeps).length) pkg.push(...mergePackage(readJson(pkgPath), { dependencies: blockDeps }).changes);
|
|
775
853
|
// …and the lock update would cut for the package.json it would leave.
|
|
776
854
|
if (existsSync(pkgPath) && tplPkg) {
|
|
777
|
-
const after = mergePackage(mergePackage(readJson(pkgPath),
|
|
855
|
+
const after = mergePackage(mergePackage(readJson(pkgPath), modePackage(tpl, appMode), drop).out, { dependencies: blockDeps }).out;
|
|
778
856
|
const cut = cutLock(dir, tpl, after);
|
|
779
857
|
if (cut && cut.text !== cut.before) entries.push({ item: "template", path: LOCKFILE, status: cut.before === null ? "new" : "changed" });
|
|
780
858
|
}
|
package/src/registry.mjs
CHANGED
|
@@ -81,8 +81,10 @@ export const BASE_MODE = "server";
|
|
|
81
81
|
* - Each dropped file is a fixed file of the base: a drop the base does
|
|
82
82
|
* not ship drops nothing, without a word, and only a pinned file is
|
|
83
83
|
* the template's to remove from an app.
|
|
84
|
+
* - Each dropped script (`dropScripts`, 0.8.0) is a script of the base's
|
|
85
|
+
* package.json (`scripts`, its names), for the same reason.
|
|
84
86
|
*/
|
|
85
|
-
export function checkMode(template, mode, { base, overlay, drop }) {
|
|
87
|
+
export function checkMode(template, mode, { base, overlay, drop, scripts = [], dropScripts = [] }) {
|
|
86
88
|
const fixed = new Set(base.filter((f) => f.class === "fixed").map((f) => f.path));
|
|
87
89
|
const dropped = new Set(drop);
|
|
88
90
|
for (const path of overlay) {
|
|
@@ -94,6 +96,9 @@ export function checkMode(template, mode, { base, overlay, drop }) {
|
|
|
94
96
|
for (const path of drop) {
|
|
95
97
|
if (!fixed.has(path)) throw new Error(`template ${template}: mode ${mode} drops ${path}, which is not a fixed file of files/ — it would drop nothing`);
|
|
96
98
|
}
|
|
99
|
+
for (const name of dropScripts) {
|
|
100
|
+
if (!scripts.includes(name)) throw new Error(`template ${template}: mode ${mode} drops the script ${name}, which files/package.json has not — it would drop nothing`);
|
|
101
|
+
}
|
|
97
102
|
}
|
|
98
103
|
|
|
99
104
|
/** A mode's overlay folder: beside files/, a plain name. */
|
|
@@ -112,8 +117,11 @@ function loadModes(name, dir, meta, base) {
|
|
|
112
117
|
// files out. Browser mode's own files come after its drop list does.
|
|
113
118
|
const overlay = existsSync(root) ? walk(root) : [];
|
|
114
119
|
const drop = [...(spec.drop ?? [])];
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
const dropScripts = [...(spec.dropScripts ?? [])];
|
|
121
|
+
const merged = base.find((f) => f.class === "merged");
|
|
122
|
+
const scripts = Object.keys((merged && readJson(merged.from)?.scripts) ?? {});
|
|
123
|
+
checkMode(name, mode, { base, overlay, drop, scripts, dropScripts });
|
|
124
|
+
modes[mode] = { root, drop, dropScripts, files: overlay.map((path) => ({ path, class: "fixed", from: join(root, path) })) };
|
|
117
125
|
}
|
|
118
126
|
return modes;
|
|
119
127
|
}
|
|
@@ -132,6 +140,29 @@ export function modeFiles(template, mode = BASE_MODE) {
|
|
|
132
140
|
return template.files.filter((f) => !drop.has(f.path)).map((f) => over.get(f.path) ?? f);
|
|
133
141
|
}
|
|
134
142
|
|
|
143
|
+
/**
|
|
144
|
+
* The scripts an app in this mode has none of (template.json
|
|
145
|
+
* `modes.<mode>.dropScripts`). Browser mode drops `start` (0.8.0): a
|
|
146
|
+
* browser app is built once and served as files, nothing ever starts it,
|
|
147
|
+
* and the store refuses a browser app's package.json that names one (its
|
|
148
|
+
* own-rules.mjs, browserScriptRefusals). Until 0.8.0 init laid the base's
|
|
149
|
+
* `start` into every app.
|
|
150
|
+
*/
|
|
151
|
+
export function modeDropScripts(template, mode = BASE_MODE) {
|
|
152
|
+
return mode === BASE_MODE ? [] : [...(template.modes?.[mode]?.dropScripts ?? [])];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** The template's package.json as a mode lays it: the base's, less the
|
|
156
|
+
* scripts the mode drops. null when the template has no merged file. */
|
|
157
|
+
export function modePackage(template, mode = BASE_MODE) {
|
|
158
|
+
const merged = template.files.find((f) => f.class === "merged");
|
|
159
|
+
if (!merged) return null;
|
|
160
|
+
const pkg = readJson(merged.from);
|
|
161
|
+
const drop = modeDropScripts(template, mode);
|
|
162
|
+
if (drop.length && pkg.scripts) pkg.scripts = Object.fromEntries(Object.entries(pkg.scripts).filter(([name]) => !drop.includes(name)));
|
|
163
|
+
return pkg;
|
|
164
|
+
}
|
|
165
|
+
|
|
135
166
|
export function loadTemplate(name) {
|
|
136
167
|
const dir = join(TEMPLATES, name);
|
|
137
168
|
const meta = readJson(join(dir, "template.json"));
|
|
@@ -261,6 +292,9 @@ function loadBlocksFrom(root, defaultTier) {
|
|
|
261
292
|
tags: meta.tags ?? [],
|
|
262
293
|
useWhen: meta.useWhen ?? "",
|
|
263
294
|
requires: meta.requires ?? [],
|
|
295
|
+
// { since, why }: update tells an app that lacks this block about it
|
|
296
|
+
// (it never adds it): the one top bar, the first run…
|
|
297
|
+
offer: meta.offer?.since && meta.offer?.why ? { since: String(meta.offer.since), why: String(meta.offer.why) } : null,
|
|
264
298
|
dependencies: meta.dependencies ?? {},
|
|
265
299
|
exports: meta.exports ?? [],
|
|
266
300
|
files,
|
|
@@ -10,9 +10,12 @@ import { surfaceOfPath } from "./platform";
|
|
|
10
10
|
//
|
|
11
11
|
// Also here: the hooks, which read on mount and again on dataChanged()
|
|
12
12
|
// (every write that answers ok calls it), and whenLanded(), which waits
|
|
13
|
-
// for those reads.
|
|
13
|
+
// for those reads. afterWrite(write) is a write and then those reads, for
|
|
14
|
+
// "make a row, then open it"; useNotFound(found, { loading }) is how a
|
|
15
|
+
// record page may say "not found" (never while a write is out).
|
|
14
16
|
|
|
15
17
|
export {
|
|
18
|
+
afterWrite,
|
|
16
19
|
countBy,
|
|
17
20
|
countRows,
|
|
18
21
|
dataChanged,
|
|
@@ -22,8 +25,10 @@ export {
|
|
|
22
25
|
useActivity,
|
|
23
26
|
useCount,
|
|
24
27
|
useCountBy,
|
|
28
|
+
useNotFound,
|
|
25
29
|
useRow,
|
|
26
30
|
useRows,
|
|
31
|
+
useSettled,
|
|
27
32
|
whenLanded,
|
|
28
33
|
} from "./door";
|
|
29
34
|
|