makersclaw 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- 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 +3 -3
- 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 +2 -2
- package/r/chat-pane.json +84 -0
- package/r/chat.json +2 -2
- 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 +13 -7
- 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 +2 -2
- package/r/flow-editor.json +79 -0
- package/r/footer.json +2 -2
- 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 +3 -3
- 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 +3 -3
- package/r/pace-bar.json +69 -0
- package/r/page-builder.json +2 -2
- package/r/payment-methods.json +2 -2
- package/r/pdf-document.json +2 -2
- package/r/pdf-viewer.json +2 -2
- 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 +4086 -1512
- 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 +2 -2
- package/r/signature-pad.json +2 -2
- package/r/sketch-canvas.json +2 -2
- 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 +3 -3
- 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 +234 -0
- package/registry/blocks/agent-pane/agent-pane.jsx +246 -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/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/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-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/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/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/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/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/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/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/install.mjs +77 -16
- package/src/registry.mjs +3 -0
- package/templates/next/browser/lib/data.js +6 -1
- package/templates/next/files/README.md +627 -24
- 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 +968 -9
- 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 +2 -1
- package/templates/next/files/components/ui/layout.jsx +77 -2
- 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 +241 -5
- package/templates/next/files/lib/door.js +92 -0
- package/templates/next/files/lib/hooks.js +1677 -8
- package/templates/next/files/lib/platform.js +529 -21
- package/templates/next/template.json +13 -3
|
@@ -99,7 +99,7 @@ lib/brain.js the company brain from the browser, in both modes; its ho
|
|
|
99
99
|
lib/brain-server.js the brain's reads for a server component — a server app's
|
|
100
100
|
lib/claw.js the _claw API the gateway answers, from the browser
|
|
101
101
|
lib/platform.js typed wrappers over lib/claw.js (Platform)
|
|
102
|
-
lib/hooks.js the React hooks over them: useJob, useLlm, useArtifact… (Hooks)
|
|
102
|
+
lib/hooks.js the React hooks over them: useJob, useLlm, useLibraryItems, useArtifact… (Hooks)
|
|
103
103
|
lib/sample.js markSample, for sample rows (§3a)
|
|
104
104
|
```
|
|
105
105
|
|
|
@@ -255,7 +255,7 @@ import { Button, IconButton, ButtonGroup, ButtonGroupSeparator, Toggle, ToggleGr
|
|
|
255
255
|
InputGroup, PasswordInput, InputOTP, Slider, Image, FileInput, FileDrop, fileMatches, Combobox, Command, CommandDialog, Calendar, DatePicker, DateInput, DATE_PRESETS,
|
|
256
256
|
parseDate, isDateString, toDateString, todayString, addDays, addMonths,
|
|
257
257
|
startOfMonth, endOfMonth, dayOfWeek, formatDate, toLocalDate, firstDayOfWeek,
|
|
258
|
-
Card, Notice, Badge, Kicker, Empty, Item, ItemGroup, Avatar, AvatarGroup,
|
|
258
|
+
Card, ActionCard, Notice, Badge, Kicker, Empty, Item, ItemGroup, Avatar, AvatarGroup,
|
|
259
259
|
Sheet, Confirm, Tabs, TabPanel, Menu, ContextMenu, Popover, Tooltip, HoverCard,
|
|
260
260
|
Breadcrumb, Pagination, Collapsible, Accordion, Carousel, ScrollArea,
|
|
261
261
|
ResizablePanelGroup, ResizablePanel, ResizableHandle,
|
|
@@ -263,7 +263,7 @@ import { Button, IconButton, ButtonGroup, ButtonGroupSeparator, Toggle, ToggleGr
|
|
|
263
263
|
Spinner, Skeleton, Progress, Separator, Kbd, KbdGroup, AspectRatio,
|
|
264
264
|
Stat, StatGroup, Delta, StatusDot, Legend, Meter, Distribution, Swatch, Steps,
|
|
265
265
|
toast, Toaster, Depiction, Icon, ICON_NAMES, usePopoverPosition, panelClass, cx,
|
|
266
|
-
AppLayout, DocumentLayout }
|
|
266
|
+
AppLayout, DocumentLayout, PageLayout }
|
|
267
267
|
from "../components/ui"; // "./ui" from a component
|
|
268
268
|
import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNotice, isSample,
|
|
269
269
|
Examples, useExamples } from "../components/parts";
|
|
@@ -289,8 +289,12 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
|
|
|
289
289
|
spreadsheet), `contentLabel`, `contentClassName` (spacing and token
|
|
290
290
|
backgrounds only) and `scrollKey` (pass the route: when it changes the
|
|
291
291
|
content scrolls back to its top and the drawer closes) · `inspector`
|
|
292
|
-
(beside the content from `inspectorAt` md · lg · xl, lg by default
|
|
293
|
-
|
|
292
|
+
(beside the content from `inspectorAt` md · lg · xl, lg by default, of
|
|
293
|
+
the window's width; `inspectorIn="frame"` counts the body between the
|
|
294
|
+
rail and the dock instead, 42 · 48 · 64 rem, so an agent dock that
|
|
295
|
+
takes a quarter of the window sends the inspector under the work
|
|
296
|
+
rather than squeezing it; `inspectorWidth` px, 360 by default, 240 to
|
|
297
|
+
560; `inspectorLabel`) ·
|
|
294
298
|
`footer` (under the content, in view) · `height` viewport · parent.
|
|
295
299
|
Below `inspectorAt` there is no room for two columns: in `scroll` mode
|
|
296
300
|
the content and the inspector share one scroll, the inspector after
|
|
@@ -320,6 +324,56 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
|
|
|
320
324
|
navigation, header, inspector or footer) and the document flows onto
|
|
321
325
|
pages. Inside either, bound a box by its parent (`h-full`, `flex-1
|
|
322
326
|
min-h-0`) or by a size (`max-h-96`, `ScrollArea`), never by the window.
|
|
327
|
+
|
|
328
|
+
`PageLayout` is a screen's main area with an optional side column,
|
|
329
|
+
full height. The main is the column that scrolls; the side is the fixed
|
|
330
|
+
one. Roadmap's Today ended at
|
|
331
|
+
680px in a 1240px window because it drew its own two-column grid
|
|
332
|
+
inside the scrolling content: only as tall as its words, the side's
|
|
333
|
+
divider stopped halfway and the bottom of the window was empty. Put it
|
|
334
|
+
inside an `AppLayout` with `contentMode="fill"` and no padding on the
|
|
335
|
+
content; the columns pad themselves, so the divider runs to the edges.
|
|
336
|
+
`side` (the side column) · `sideWidth` px (304; 220 to 560) · `sideAt`
|
|
337
|
+
md · lg · xl (the page's own width from which the side sits beside the
|
|
338
|
+
main, 42 · 48 · 64 rem: a measure of the page, so an open agent dock
|
|
339
|
+
does not squeeze it; narrower, the side goes under the main in one
|
|
340
|
+
scroll) · `mainLabel`, `sideLabel` · `padded` · `fill` (the main is a
|
|
341
|
+
flex column, so a child with `flex-1` grows into the height) ·
|
|
342
|
+
`className`, `mainClassName`, `sideClassName` (spacing, never a height).
|
|
343
|
+
`npm run check` refuses a screen that draws its own main + side
|
|
344
|
+
(`grid-cols-[minmax(0,1fr)_19rem]` and a ruled `<aside>`, rule `page`).
|
|
345
|
+
|
|
346
|
+
**What belongs in the side, and what never does** (the founder, looking
|
|
347
|
+
at a first run that was a short intro on the left and a long "Name it"
|
|
348
|
+
form in the right column: "this can only work if one column is fixed,
|
|
349
|
+
usually the 3rd column, and the middle one is scrolling"). The side is
|
|
350
|
+
the fixed column: it stays put while the main scrolls, so it is short
|
|
351
|
+
and never needs a scroll of its own.
|
|
352
|
+
- In the side: a summary, the next step, a few facts about the record,
|
|
353
|
+
a small panel (an allowance, "needs you" with a few lines), a short
|
|
354
|
+
list that says its bound (`items.slice(0, 5)` and "and 3 more").
|
|
355
|
+
- Never in the side: a form (`<form`, several `Field` or `Input`, a
|
|
356
|
+
`Textarea`, a paste box), a list that grows with the data, a shelf of
|
|
357
|
+
examples. They go in the main, where the page scrolls. A "Name it" or
|
|
358
|
+
"Paste a list" step that opens reveals its own card in the main flow;
|
|
359
|
+
it does not open a form in the side.
|
|
360
|
+
- The side's own scroll (thin) is a last resort for a window shorter
|
|
361
|
+
than the side. It is not how anything is meant to be read.
|
|
362
|
+
- Narrower than `sideAt`, the side goes under the main in one scroll.
|
|
363
|
+
`npm run check` rule `sidelong` refuses a `side` or an `<aside>` that
|
|
364
|
+
holds a form, a `Textarea`, three or more fields, or a `.map(` of data
|
|
365
|
+
that is not bounded by a `.slice(`. It reads the side's own markup and
|
|
366
|
+
the components defined in the app that the side draws (three levels
|
|
367
|
+
deep). It cannot see a block or kit component's insides, content that
|
|
368
|
+
arrives from props or context, or how long a list really is at run time;
|
|
369
|
+
the docs and review carry those. A screen:
|
|
370
|
+
```jsx
|
|
371
|
+
<AppLayout header={<TopBar crumb={crumb} />} contentMode="fill">
|
|
372
|
+
<PageLayout side={<Projects />} fill>
|
|
373
|
+
<NeedsALook />
|
|
374
|
+
</PageLayout>
|
|
375
|
+
</AppLayout>
|
|
376
|
+
```
|
|
323
377
|
- `Button` — `variant` primary (one per surface, in the app's accent —
|
|
324
378
|
say it: a Button with no `variant` is secondary) · secondary · quiet ·
|
|
325
379
|
danger · link (inline text: no padding or height, wraps and truncates
|
|
@@ -427,6 +481,14 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
|
|
|
427
481
|
— a table that scrolls inside itself on a phone.
|
|
428
482
|
- `Card` (`padding` md · sm · none — none for a table or rows that run
|
|
429
483
|
to the border, never `p-0!`; `titleSize` md · lg for a 20px title),
|
|
484
|
+
`ActionCard` (one step the member takes: `icon`, `title`,
|
|
485
|
+
`description`, `children`, `status` = `{ tone, children }` above the
|
|
486
|
+
one full-width `action`; in a row it stretches to the row's height and
|
|
487
|
+
pins its status and action to the bottom, so the buttons line up (`fit`
|
|
488
|
+
is the old only-as-tall-as-its-words, for one lone card; never
|
|
489
|
+
`self-start` on a card in a row) — a connect-and-first-read card, "Add one person", "Bring in a
|
|
490
|
+
file". A screen's boxes are Card, ActionCard or Notice, never a
|
|
491
|
+
hand-drawn bordered div),
|
|
430
492
|
`Notice` (tone neutral · info · success · warning · danger),
|
|
431
493
|
`Badge` (tone neutral · primary · success · warning · danger · info;
|
|
432
494
|
`variant` label — small caps · soft — the case as written, every tone
|
|
@@ -453,7 +515,9 @@ import { RecordSwitcher, LiveEmpty, LiveWork, liveWords, useFixture, FixtureNoti
|
|
|
453
515
|
`Meter value max unit target thresholds` (a role=meter; over the limit
|
|
454
516
|
turns danger; `direction` higher · lower picks the tone against the
|
|
455
517
|
target; `valueTone`; `targetMark={false}`; tone `muted` for a plain
|
|
456
|
-
grey share
|
|
518
|
+
grey share; `compact` the bar (or ring) alone, its label and numbers
|
|
519
|
+
kept for screen readers and as the tooltip — a labelled Meter in a box of
|
|
520
|
+
8rem or less must be `compact`) — numbers and states, never a hand-drawn tile or bar.
|
|
457
521
|
`Delta hideValue` is the arrow alone; `StatusDot` and Legend items take
|
|
458
522
|
`hue` (1..5) for a category. `Distribution segments={[{ label, value,
|
|
459
523
|
tone, hue }]} legend label size` (thin · md) — parts of one whole as
|
|
@@ -1048,6 +1112,130 @@ the check refuses a raw `INSERT INTO` anywhere outside `lib/`, and, in
|
|
|
1048
1112
|
an app on its own tables, any SQL that writes in the app's code (§6,
|
|
1049
1113
|
`agent`).
|
|
1050
1114
|
|
|
1115
|
+
### Declared actions — `makersclaw.json` `actions` (0.8.1)
|
|
1116
|
+
|
|
1117
|
+
Every write a screen makes is a declared action: the screens call it by
|
|
1118
|
+
name with `runAction({ name, args })`, and the app's agent calls the same
|
|
1119
|
+
name as one of its tools, run by the platform's one runner. Once an app
|
|
1120
|
+
declares any, its agent can write no other way, so `npm run check`
|
|
1121
|
+
(§6, `actions`) fails a screen write that is not one: an undeclared
|
|
1122
|
+
name, a one-row write (`insertRow`, `updateRow`, `moveRow`, `deleteRow`,
|
|
1123
|
+
`saveSetting`: make it a function) and a company brain write from
|
|
1124
|
+
`lib/brain.js` (erase, confirm and merge stay a person's press).
|
|
1125
|
+
|
|
1126
|
+
```json
|
|
1127
|
+
"actions": [
|
|
1128
|
+
{
|
|
1129
|
+
"name": "add_people",
|
|
1130
|
+
"description": "Add up to 100 people, each linked to their company.",
|
|
1131
|
+
"input": {
|
|
1132
|
+
"type": "object",
|
|
1133
|
+
"properties": {
|
|
1134
|
+
"people": {
|
|
1135
|
+
"type": "array", "maxItems": 100,
|
|
1136
|
+
"items": { "type": "object", "properties": {
|
|
1137
|
+
"name": { "type": "string" }, "email": { "type": "string" },
|
|
1138
|
+
"company": { "type": "string" }, "company_domain": { "type": "string" } },
|
|
1139
|
+
"required": ["name"] }
|
|
1140
|
+
},
|
|
1141
|
+
"list_id": { "type": "string" }
|
|
1142
|
+
},
|
|
1143
|
+
"required": ["people"]
|
|
1144
|
+
},
|
|
1145
|
+
"brain": {
|
|
1146
|
+
"each": "people",
|
|
1147
|
+
"writes": [
|
|
1148
|
+
{ "as": "company", "kind": "company", "when": "company", "fields": { "name": "company", "domain": "company_domain" } },
|
|
1149
|
+
{ "as": "person", "kind": "contact", "fields": { "name": "name", "email": "email", "company_name": "company" } }
|
|
1150
|
+
],
|
|
1151
|
+
"links": [{ "from": "person", "to": "company", "type": "works_at" }]
|
|
1152
|
+
},
|
|
1153
|
+
"sql": "crm_people_added"
|
|
1154
|
+
},
|
|
1155
|
+
{ "name": "make_list", "description": "Make a list of people or companies.",
|
|
1156
|
+
"input": { "type": "object", "properties": { "name": { "type": "string" } }, "required": ["name"] },
|
|
1157
|
+
"sql": "crm_make_list" }
|
|
1158
|
+
]
|
|
1159
|
+
```
|
|
1160
|
+
|
|
1161
|
+
- `input` is a JSON Schema object (type, properties, required, items,
|
|
1162
|
+
enum, min/max, descriptions); the agent reads it whole, so keep it
|
|
1163
|
+
under 12,000 characters.
|
|
1164
|
+
- `sql` is a function `<name>(args jsonb) returns jsonb` in the app's
|
|
1165
|
+
schema, run as the app, with the member set, after the `brain` steps.
|
|
1166
|
+
- `brain` writes company records as the member and the app: each write
|
|
1167
|
+
is `{ as, kind, fields }`, each field read from an input key (`"name"`:
|
|
1168
|
+
the item's, with `each`; `"$.list_id"`: the input's top level;
|
|
1169
|
+
`{ "value": "lead" }`: a constant). An empty value is left out, never
|
|
1170
|
+
cleared. `when` writes it only when that key has a value; `each` runs
|
|
1171
|
+
the writes once per item of a list of at most 100; `links` join two
|
|
1172
|
+
writes (`from`/`to` an `as`, or `{ "id": <key> }`, a record id the
|
|
1173
|
+
input holds) by a link type the kind declares. Every kind is one the
|
|
1174
|
+
app writes (`brain.writes`), every field one of its fields. The `sql`
|
|
1175
|
+
function gets the input plus `records`: for each `as`, `{ id, created
|
|
1176
|
+
}` (a list in item order with `each`; null where `when` skipped it).
|
|
1177
|
+
If the function refuses, the records the call made are taken back.
|
|
1178
|
+
- A write with `"id"` changes the record that input key names (an edit,
|
|
1179
|
+
never a create), as the member and the app may: one they cannot both
|
|
1180
|
+
read, or of another kind, is not found and nothing is written.
|
|
1181
|
+
`"if_version"` names a key holding the version the screen read
|
|
1182
|
+
(refused `changed` when it moved on); `{ "value": null }` empties a
|
|
1183
|
+
field, and `"clear"` names a key listing fields to empty (an array of
|
|
1184
|
+
strings whose `items.enum` are among the write's fields); `{ "now":
|
|
1185
|
+
true }` is the time of the call. If a later step fails, the fields it
|
|
1186
|
+
changed get their old values back.
|
|
1187
|
+
- A link with `"op": "remove"` takes one off (removals run first, so one
|
|
1188
|
+
call moves a link), and an action may be `links` only, with no
|
|
1189
|
+
`writes`. Archive is an edit of the kind's own field (`archived_at`:
|
|
1190
|
+
`{ "now": true }`, back with `{ "value": null }`); erase and merge stay
|
|
1191
|
+
a person's press, from `lib/brain.js`.
|
|
1192
|
+
|
|
1193
|
+
```json
|
|
1194
|
+
{ "name": "move_deal", "description": "Move a deal to a stage and another company.",
|
|
1195
|
+
"input": { "type": "object", "properties": {
|
|
1196
|
+
"deal_id": { "type": "string" }, "version": { "type": "integer" }, "stage": { "type": "string" },
|
|
1197
|
+
"from_company": { "type": "string" }, "to_company": { "type": "string" } },
|
|
1198
|
+
"required": ["deal_id", "stage"] },
|
|
1199
|
+
"brain": {
|
|
1200
|
+
"writes": [{ "as": "deal", "kind": "deal", "id": "$.deal_id", "if_version": "$.version",
|
|
1201
|
+
"fields": { "stage": "$.stage", "stage_changed_at": { "now": true }, "closed_at": { "value": null } } }],
|
|
1202
|
+
"links": [
|
|
1203
|
+
{ "from": "deal", "to": { "id": "$.from_company" }, "type": "for_company", "op": "remove" },
|
|
1204
|
+
{ "from": "deal", "to": { "id": "$.to_company" }, "type": "for_company" }] },
|
|
1205
|
+
"sql": "crm_deal_moved" }
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
- `agent: false` only for a write the agent must never make.
|
|
1209
|
+
- `references/actions.md` says, per action, when and why: never a recipe.
|
|
1210
|
+
|
|
1211
|
+
### Shipped automations — `makersclaw.json` `automations` (0.8.1)
|
|
1212
|
+
|
|
1213
|
+
An app may ship automations: flows the platform runs for it on a schedule
|
|
1214
|
+
or by hand, made of its own declared actions. List them in
|
|
1215
|
+
`makersclaw.json`, under `automations`, next to `actions`. The store ships
|
|
1216
|
+
the same list as `seeds.automations` in `store.json`.
|
|
1217
|
+
|
|
1218
|
+
- Each entry is a definition in the platform's automation format (format
|
|
1219
|
+
1: `key`, `name`, `trigger`, `inputs`, `settings`, `steps`), exactly as
|
|
1220
|
+
the automations blocks draw and save one.
|
|
1221
|
+
- An `action` step names one of the app's declared `actions` (its `app`
|
|
1222
|
+
stays out: an app's automation runs its own app's actions).
|
|
1223
|
+
- `replaces_wake` is the one field that is not part of the definition. It
|
|
1224
|
+
is the name of a legacy wake (an older scheduled job of the app, in its
|
|
1225
|
+
`store.json` `seeds.wakes`) that this automation takes over: when the app
|
|
1226
|
+
is installed or updated the wake is switched off, so the job never fires
|
|
1227
|
+
twice. Leave it out for a new automation. Name a scheduled wake (advance
|
|
1228
|
+
or review), never an event wake, and one automation per wake. The
|
|
1229
|
+
app's `store.json` lists the same name.
|
|
1230
|
+
- At most 20 automations, keys unique.
|
|
1231
|
+
|
|
1232
|
+
`npm run check` runs the list through the platform's own validator (rule
|
|
1233
|
+
`automations`), so a flow the platform would refuse at install is refused
|
|
1234
|
+
at build. It checks the shape, the kinds of step, the expressions and that
|
|
1235
|
+
every `action` step names a declared action. Which wakes exist and which
|
|
1236
|
+
kinds of account a `tool` step may ask for are checked where the whole
|
|
1237
|
+
package is known (the store's publish).
|
|
1238
|
+
|
|
1051
1239
|
### Door — `lib/door.js` (browser, both modes)
|
|
1052
1240
|
|
|
1053
1241
|
The app's own tables, read and written from the browser through the
|
|
@@ -1107,7 +1295,10 @@ whenLanded() resolves once those reads have landed
|
|
|
1107
1295
|
Actions did. A slow save never lands after the newer one.
|
|
1108
1296
|
- A write that answers ok calls `dataChanged()`: every hook on the page
|
|
1109
1297
|
reads again, the brain's too. When the next step needs the new rows
|
|
1110
|
-
(open the row just made), `await whenLanded()` first.
|
|
1298
|
+
(open the row just made), `await whenLanded()` first. Use
|
|
1299
|
+
`afterWrite(write)`: it answers with the write's answer after the hooks
|
|
1300
|
+
hold the new rows; a record page asks `useNotFound(found, { loading })`
|
|
1301
|
+
before it says "not found".
|
|
1111
1302
|
- `loading` is true until a hook's first answer, and again when its
|
|
1112
1303
|
options change. A re-read keeps the last rows, and `loading` false,
|
|
1113
1304
|
until the new ones land; each answer is a new array. A failed re-read
|
|
@@ -1334,6 +1525,12 @@ platform.ask({ text, row, how, job, list, surface, sessionId, open })
|
|
|
1334
1525
|
POST _claw/ask → { ok, request, desk_origin }, and the column opens on it
|
|
1335
1526
|
platform.llm(input, { system, schema, maxTokens, tier, task, signal })
|
|
1336
1527
|
POST _claw/llm → { ok: true, text } | { ok: true, data } | { ok: false, error, code } (Calling a model)
|
|
1528
|
+
platform.library.collections({ q, shelf }) GET _claw/library/collections → { collections } (Showing the Library)
|
|
1529
|
+
platform.library.collection(id) GET _claw/library/collections/<id> → { collection }
|
|
1530
|
+
platform.library.items(id, { q, tag, cursor, limit }) GET _claw/library/collections/<id>/items → { items, next_cursor, total, preview_only }
|
|
1531
|
+
platform.library.rows(id, { q, filters, cursor, limit })
|
|
1532
|
+
GET _claw/library/collections/<id>/rows → { rows, next_cursor, total, preview_only }
|
|
1533
|
+
platform.library.item(id) GET _claw/library/items/<id> → { item, file_url?, text_excerpt? }
|
|
1337
1534
|
platform.requests() GET _claw/requests → { requests, run, desk_origin }
|
|
1338
1535
|
platform.requests({ id }) GET _claw/requests?id=<id> → { request }
|
|
1339
1536
|
platform.stopRequest(id) POST _claw/requests/<id>/stop → { ok, request }
|
|
@@ -1342,6 +1539,24 @@ platform.surfaceOfPath(pathname) the <key> of /s/<key> in
|
|
|
1342
1539
|
platform.reportError({ message, stack, url, source }) POST _claw/events
|
|
1343
1540
|
platform.startJob(message, { sessionId, onEvent }) POST _claw/chat → streams session · delta · tool · done · error (legacy)
|
|
1344
1541
|
platform.cancelJob(sessionId) POST _claw/cancel (legacy)
|
|
1542
|
+
|
|
1543
|
+
// The kit (0.8.1) — what the kit's blocks draw; lib/hooks.js follows each one
|
|
1544
|
+
platform.jobs() GET _claw/jobs → { app: { status, live }, jobs: [{ id, name, kind, topic, does, cron, tz, words,
|
|
1545
|
+
enabled, next_run_at, last_run_at, last_run, plan }], budget, credits, may: { run, switch, pause } }
|
|
1546
|
+
platform.setJob(id, { enabled }) PATCH _claw/jobs/<id> → { ok, job } (not_allowed 403 · unknown_job 404)
|
|
1547
|
+
platform.runNow(wakeId) POST _claw/run → { ok, run_id, wake } (spends: its price on the button)
|
|
1548
|
+
platform.pauseApp() · platform.resumeApp() POST _claw/pause · _claw/resume → { status } (the Live switch)
|
|
1549
|
+
platform.runs({ job, limit }) GET _claw/runs → { runs: [{ id, title, state, wake_id, job, trigger, by, number,
|
|
1550
|
+
started_at, ended_at, duration_ms, credits, report, status }], overview }
|
|
1551
|
+
platform.run(id) GET _claw/runs/<id> → { run, steps: [{ label, status }], text, needs }
|
|
1552
|
+
platform.activity({ row, surface, since, limit }) GET _claw/data/activity → { rows: [{ id, at, action, surface, row_ref, detail, data, by }] }
|
|
1553
|
+
platform.connections() GET _claw/connect → { connections: [{ key, label, required, connected, accounts, category, category_label }] }
|
|
1554
|
+
platform.connectLink(key) POST _claw/connect → { ok, key, label, connected, url } (outside the desk)
|
|
1555
|
+
platform.openConnections(key) ask the desk to open its connections panel for that need → true when the desk was asked
|
|
1556
|
+
platform.agentKit() GET _claw/agent → { own_skills: [{ name, title, when }], skills: [{ name, installed }],
|
|
1557
|
+
actions: [{ name, description, agent }], … }
|
|
1558
|
+
platform.llmEstimate(input, { system, schema, maxTokens, tier, task })
|
|
1559
|
+
POST _claw/llm, estimate: true → { ok: true, estimate: { credits, credits_max } } (never sent to a model, never charged)
|
|
1345
1560
|
```
|
|
1346
1561
|
|
|
1347
1562
|
A request, as `ask` and `requests` hand it back: `{ id, title, words,
|
|
@@ -1357,16 +1572,32 @@ didnt_finish. `line` is the one line every screen shows for it
|
|
|
1357
1572
|
show it as it is, never a status word of your own. `app_session_id` is
|
|
1358
1573
|
set only on your own requests.
|
|
1359
1574
|
|
|
1360
|
-
Named exports: `me, ask, llm,
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1575
|
+
Named exports: `me, ask, llm, llmEstimate, library, requests,
|
|
1576
|
+
stopRequest, openRequest, threads, thread, surfaceOfPath, startJob,
|
|
1577
|
+
cancelJob, reportError, jobs, setJob, runNow, pauseApp, resumeApp, runs,
|
|
1578
|
+
run, activity, connections, connectLink, openConnections, agentKit,
|
|
1579
|
+
platform`. That is the whole list.
|
|
1580
|
+
|
|
1581
|
+
Up to 0.8.1 the runs, Run now, Pause / Resume and the agent's settings
|
|
1582
|
+
were not here: they were MONITORING, and the OS drew them as the window's
|
|
1583
|
+
tabs so that every app showed its agent's work in one look. The kit
|
|
1584
|
+
(0.8.1) moved that one look into the template's blocks (The agent and AI
|
|
1585
|
+
kit, below), so the app now shows its agent's work itself, beside the
|
|
1586
|
+
rows the work wrote, and calls `_claw/jobs`, `_claw/runs`, `_claw/run`,
|
|
1587
|
+
`_claw/pause`, `_claw/resume`, `_claw/agent` and `_claw/connect` through
|
|
1588
|
+
these wrappers. The window's tabs stay, as the full history. Two things
|
|
1589
|
+
never move into the app: **the account sign-in and money** stay on the
|
|
1590
|
+
desk. The agent's questions are answered in the app (`answer`), and the
|
|
1591
|
+
yes is given in the app too, but never by the app: it is a press in a
|
|
1592
|
+
Makersclaw-held frame (`approval`, the `approval` block). The door decides
|
|
1593
|
+
who may press what (`may` on `jobs`): hide what the member may not press,
|
|
1594
|
+
and the door refuses it anyway.
|
|
1595
|
+
Asking is its own thing, and it belongs here too (`ask()` and `useJob`,
|
|
1596
|
+
below). `llm()` is neither: one call to a model, answered in the page
|
|
1597
|
+
(Calling a model, below). It is the one wrapper that resolves the platform's answer
|
|
1369
1598
|
as it is, `{ ok: true, text }` and not `{ ok: true, status, data }`.
|
|
1599
|
+
`library` is neither asking nor monitoring: it reads what Makersclaw
|
|
1600
|
+
keeps, read only (Showing the Library, below).
|
|
1370
1601
|
`requests` is not monitoring either: it is this app's asks in flight, so
|
|
1371
1602
|
an empty surface can show the work coming (§3a). `startJob` and
|
|
1372
1603
|
`cancelJob` are the 0.3.x door to the same work, kept so `useJob` can
|
|
@@ -1379,10 +1610,13 @@ that exact origin — never `"*"` — and only while the app is framed.
|
|
|
1379
1610
|
|
|
1380
1611
|
### Hooks — `lib/hooks.js` ("use client")
|
|
1381
1612
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1613
|
+
A generic fetch over one `_claw` route, the app's identity, a job, the
|
|
1614
|
+
app's requests, a model call, five that read the Library, the app's own
|
|
1615
|
+
chat, and the kit's eight (0.8.1). Each owns
|
|
1616
|
+
fetching, polling (while the tab is visible; once a minute while
|
|
1617
|
+
`unavailable`; the Library's read once and have nothing to poll),
|
|
1618
|
+
streaming and cleanup on unmount. A surface renders what comes back and
|
|
1619
|
+
owns every pixel.
|
|
1386
1620
|
|
|
1387
1621
|
```js
|
|
1388
1622
|
useClaw(path, { every, enabled = true }) → { data, error, loading, unavailable, reload }
|
|
@@ -1392,9 +1626,49 @@ useJob() → { running, status, queued, que
|
|
|
1392
1626
|
start, cancel, reset, open }
|
|
1393
1627
|
useRequests({ surface, job, every = 5000 }) → { requests, live, run, loading, error, unavailable, reload, open, stop }
|
|
1394
1628
|
useLlm() → { run, loading, result, error, unavailable } (Calling a model)
|
|
1629
|
+
useLibraryCollections({ q, shelf }) → { collections, loading, error, code, unavailable, reload } (Showing the Library)
|
|
1630
|
+
useLibraryCollection(id) → { collection, loading, error, code, unavailable, reload }
|
|
1631
|
+
useLibraryItems(id, { q, tag, limit }) → { items, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
|
|
1632
|
+
useLibraryRows(id, { q, filters, limit }) → { rows, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
|
|
1633
|
+
useLibraryItem(id) → { item, fileUrl, textExcerpt, loading, error, code, unavailable, reload }
|
|
1634
|
+
useAgentThread({ row, how, job, key, view }) → { sessionId, state, needs, turns, view, pending, place, request, sending, loading, error,
|
|
1635
|
+
code, unavailable, send, stop, answer({ optionId, text } | { answers }), openOnDesk, newChat,
|
|
1636
|
+
openSession(sessionId), reload } (the agent-chat block)
|
|
1637
|
+
useAgentPane({ row, how, job, key }) → useAgentThread with the desk sidebar's view, plus { chats: { items, loading, error, unavailable },
|
|
1638
|
+
callDetail(callId), openRequest(id) } (the agent-pane block, D27; GET _claw/threads/<session>?view=1)
|
|
1639
|
+
useThreadList({ every = 30000 }) → { items: [{ sessionId, requestId, title, mark, at }], loading, error, unavailable, reload } (the pane's Chats list)
|
|
1395
1640
|
jobFromRequest(request) → what useJob shows for one request (pure; for tests)
|
|
1641
|
+
|
|
1642
|
+
// The kit (0.8.1): each also returns { loading, error, code, unavailable, reload }
|
|
1643
|
+
useJobs({ every = 30000 }) → { jobs, app, budget, credits, may, busy, appBusy, runNow(id), setEnabled(id, on), pause(), resume() }
|
|
1644
|
+
useRuns({ job, limit = 20, every = 30000 }) → { runs, overview } every 5 s while a run is going
|
|
1645
|
+
useRun(id) → { run, steps, text, needs } every 2.5 s while it runs; nothing without an id
|
|
1646
|
+
useNeedsYou({ every = 8000 }) → { items: [{ id, request, kind, text, title, at, via, options, free, needsAt }], working, open(item), answer(item, { optionId, text }), takeBack(item), stop(request) }
|
|
1647
|
+
useApproval(requestId) → { approval, state, always, fallback, frame: { src, ref, title }, height } (the approval block; GET _claw/requests/<id>/approval)
|
|
1648
|
+
useActivity({ row, surface, since, limit = 50, agent = false, every = 20000 })
|
|
1649
|
+
→ { rows } agent: true keeps the agent's lines
|
|
1650
|
+
useConnections({ every }) → { connections, connecting, connect(key) → { opened: "desk" | "tab" | false, error? } }
|
|
1651
|
+
useAgentKit() → { skills: [{ name, title, when, from: "app" | "added", installed }], tools: [{ name, description }] }
|
|
1652
|
+
useLlmAction({ input, system, schema, tier, task, maxTokens, estimate = true })
|
|
1653
|
+
→ { estimate: { credits, credits_max } | null, estimating, run(), result, loading, error, unavailable, reset() }
|
|
1654
|
+
needsYouItem(request) · agentKitOf(data) · connectAccount(key) the kit hooks' pure parts (for tests)
|
|
1655
|
+
|
|
1656
|
+
// The automations engine (lib/automations.js, re-exported here): an app's own automations, from its own page
|
|
1657
|
+
useAutomations({ every = 30000 }) → { automations, busy, creating, setStatus(id, on), create(definition, { note, goLive }) } every 5 s while one runs
|
|
1658
|
+
useAutomation(id) → { automation, live, draft, definition, versions, estimate, estimateDraft, runs, busy: "save" | "keep" | "live" | "test" | null,
|
|
1659
|
+
save(definition), keep(), setLive(on), test(inputs) } resolve the platform's answer; a refusal carries `problems`
|
|
1660
|
+
useAutomationRun(runId) → { run, steps, stepsVisible, automation, definition, detail } every 2.5 s while it runs
|
|
1396
1661
|
```
|
|
1397
1662
|
|
|
1663
|
+
The kit's hooks poll only while the page is shown (not behind the
|
|
1664
|
+
window's other tabs, not in a hidden browser tab; coming back looks at
|
|
1665
|
+
once), look once a minute while their door is missing, abort on unmount
|
|
1666
|
+
and never throw. A missing door is `unavailable` with `error` null: a
|
|
1667
|
+
quiet "not connected yet". `useJobs`' Run now makes every `useRuns`,
|
|
1668
|
+
`useRequests` and `useNeedsYou` on the page look at once. `useActivity`
|
|
1669
|
+
here is the kit's: polled, with `row` and `agent`; `lib/door.js`'s
|
|
1670
|
+
`useActivity` (§5 Door) reads the same lines once.
|
|
1671
|
+
|
|
1398
1672
|
`useRequests` is the work asked of this app's agent — from a screen or
|
|
1399
1673
|
from the desk, by anyone in the workspace. `requests` is every one the
|
|
1400
1674
|
gateway returned (the live ones and those that ended in the last day);
|
|
@@ -1408,10 +1682,11 @@ while the App tab is on screen (behind the window's other tabs it asks
|
|
|
1408
1682
|
nothing; coming back looks at once); a start through `useJob` on the
|
|
1409
1683
|
same page makes it look at once. Hand it to `LiveEmpty` (§3a).
|
|
1410
1684
|
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1685
|
+
Up to 0.8.1 this said there was no chat or runs hook, because the OS
|
|
1686
|
+
drew those tabs. Since the kit there are both, and the blocks that draw
|
|
1687
|
+
them: a record's history beside the record is the `activity-log` block
|
|
1688
|
+
over `useActivity({ row })`; on the server in a server app it is
|
|
1689
|
+
`loadActivity`.
|
|
1415
1690
|
|
|
1416
1691
|
### Commissioning work — `useJob()`
|
|
1417
1692
|
|
|
@@ -1568,6 +1843,92 @@ if (!r.ok) setError(r.error); // r.code: needs_answer, queue_fu
|
|
|
1568
1843
|
It resolves once the platform took the ask (`{ ok: true, data: {
|
|
1569
1844
|
request, desk_origin } }`) or refused it; it never waits for the work.
|
|
1570
1845
|
|
|
1846
|
+
### The agent and AI kit — blocks (0.8.1)
|
|
1847
|
+
|
|
1848
|
+
The app shows its agent's work and its AI features itself, in its own
|
|
1849
|
+
look: a chat beside the record, the schedule and its runs, what waits on
|
|
1850
|
+
the member, the price before a press. Up to 0.8.1 the OS drew most of
|
|
1851
|
+
this as the window's tabs, so every app looked the same; now the same
|
|
1852
|
+
look lives in these blocks, and the tabs stay as the full history. Each
|
|
1853
|
+
block is `makersclaw add <name>`, reads nothing itself, and takes the
|
|
1854
|
+
hook's answer as props (a block never imports `lib/`):
|
|
1855
|
+
|
|
1856
|
+
- `agent-chat` (`AgentChat`) — the app's own chat with its agent, about
|
|
1857
|
+
the app or one record. `useAgentThread`.
|
|
1858
|
+
- `ask-bar` (`AskBar`) — one line to ask, with chips; it starts the
|
|
1859
|
+
thread and opens the chat. `useAgentThread`.
|
|
1860
|
+
- `needs-you` (`NeedsYou`, `QuestionBox`, `WaitingYes`, `AgentWorking`) —
|
|
1861
|
+
what waits on this member (a question answered in place, a yes through
|
|
1862
|
+
the `approval` block), the frozen "Ready to send" with Take back, the
|
|
1863
|
+
working strip with Stop. `useNeedsYou`.
|
|
1864
|
+
- `approval` (`Approval`) — the yes, given in the app: the app's own card
|
|
1865
|
+
(what goes out, to whom, the cost) over a Makersclaw-held press frame in
|
|
1866
|
+
the app's theme that app code cannot script, with "Always allow this
|
|
1867
|
+
kind". `useApproval`.
|
|
1868
|
+
- `activity-log` (`ActivityLog`) — who did what, newest first, the
|
|
1869
|
+
agent as an author; with `row`, one record's timeline. `useActivity`.
|
|
1870
|
+
- `agent-marks` (`AgentMark`, `CallMark`, `Byline`) — the agent's mark,
|
|
1871
|
+
a model call's mark, "By the agent, on Priya's ask". No hook.
|
|
1872
|
+
- `schedule-card` (`ScheduleCard`) — one job: its schedule in words, its
|
|
1873
|
+
last run, next run, Run now with its price, the on/off switch.
|
|
1874
|
+
`useJobs`.
|
|
1875
|
+
- `run-history` (`RunHistory`, `RunAccount`, `RunOverview`) — the runs,
|
|
1876
|
+
one run's account, the overview against the week's cap. `useRuns`,
|
|
1877
|
+
`useRun`.
|
|
1878
|
+
- `workflow-view` (`WorkflowView`) — the job as a graph: Trigger → steps
|
|
1879
|
+
→ result, the run picker, Live, Trigger manually, its runs beside.
|
|
1880
|
+
`useJobs`, `useRuns`, `useRun`.
|
|
1881
|
+
- `suggestion` (`FieldSuggestion`, `InlineSuggestion`, `TextSuggestion`,
|
|
1882
|
+
`Pencil`, `SuggestionGroup`, `Looking`) — a value the agent proposes,
|
|
1883
|
+
in pencil until kept. No hook: Keep and Drop call the app's declared
|
|
1884
|
+
actions (`runAction`).
|
|
1885
|
+
- `source-receipt` (`SourceReceipt`) — where a value came from, as a
|
|
1886
|
+
clipping. No hook: the source is app data.
|
|
1887
|
+
- `agent-column` — a column the agent fills, each answer with its state,
|
|
1888
|
+
how sure it is, and its receipt. The app's rows (`lib/data.js`).
|
|
1889
|
+
- `record-grid` — a virtualised grid of many records. The app's rows
|
|
1890
|
+
(`lib/data.js`).
|
|
1891
|
+
- `ai-action` (`AiAction`) — one model call on what the screen holds,
|
|
1892
|
+
its price on the button, the answer in place with Use. `useLlmAction`.
|
|
1893
|
+
- `cost` (`CostTag`, `CostConfirm`, `Allowance`) — the price on a
|
|
1894
|
+
control, the confirm before a big spend, the week's allowance.
|
|
1895
|
+
`useLlmAction`'s estimate, `useJobs`' budget.
|
|
1896
|
+
- `agent-changes` (`AgentChanges`) — the receipt of one ask, with Undo
|
|
1897
|
+
this ask. `useActivity({ agent: true, since })`.
|
|
1898
|
+
- `connect-card` (`ConnectCard`, `ConnectRow`) — the app's accounts,
|
|
1899
|
+
live or not, Connect. `useConnections`.
|
|
1900
|
+
- `agent-kit` (`AgentKit`) — what the agent knows and what it can do.
|
|
1901
|
+
`useAgentKit`.
|
|
1902
|
+
- `library-shelf` (`LibraryShelf`) — "Start from a template": a Library
|
|
1903
|
+
collection's items. `useLibraryItems`.
|
|
1904
|
+
|
|
1905
|
+
The rules:
|
|
1906
|
+
|
|
1907
|
+
1. **Use the kit.** Never redraw a chat, a schedule, a run list, a
|
|
1908
|
+
needs-you queue, a suggestion or a price tag by hand: the block is
|
|
1909
|
+
the one look every app shares, and it grows in the template.
|
|
1910
|
+
2. **The sign-in and money stay on the desk; the yes is the press
|
|
1911
|
+
frame's.** The agent's question is answered in the app (`QuestionBox`,
|
|
1912
|
+
`answer`). The agent's yes is the `approval` block: you draw what goes
|
|
1913
|
+
out, the frame holds the press, and when it cannot load the block falls
|
|
1914
|
+
back to "Waiting for your yes on the desk" and opens it
|
|
1915
|
+
(`openRequest`). Connect opens the desk's connections panel; topping up
|
|
1916
|
+
opens the desk. Never an Approve, Yes or Send of your own that gives
|
|
1917
|
+
the yes, a password field or a payment form in the app.
|
|
1918
|
+
3. **Cost on every control that spends.** Run now, Read now, Enrich,
|
|
1919
|
+
Summarize: the price is on the button (`CostTag`, `useLlmAction`'s
|
|
1920
|
+
estimate) before the press, and a big spend asks first
|
|
1921
|
+
(`CostConfirm`).
|
|
1922
|
+
4. **The door decides who may press.** `useJobs().may` says who may run,
|
|
1923
|
+
switch and pause; hide what the member may not press. The door
|
|
1924
|
+
refuses it anyway.
|
|
1925
|
+
5. **A missing door is quiet.** On a claw from before a door the hook is
|
|
1926
|
+
`unavailable`: the block shows its empty state ("No runs yet", "Not
|
|
1927
|
+
set up"), never an error.
|
|
1928
|
+
6. **Its own width decides its layout.** Every kit block lays itself out
|
|
1929
|
+
by `@container`, at 320, 368, 800 and 1280 px of its own width; give
|
|
1930
|
+
it the width, never a viewport breakpoint of yours.
|
|
1931
|
+
|
|
1571
1932
|
### Calling a model — `llm()`
|
|
1572
1933
|
|
|
1573
1934
|
`llm()` is for one-shot text work on what is on screen: sort these
|
|
@@ -1760,6 +2121,228 @@ What to keep in mind:
|
|
|
1760
2121
|
they handle what a bare `fetch` would not (a claw without the door, a
|
|
1761
2122
|
dropped network, an abort).
|
|
1762
2123
|
|
|
2124
|
+
### Showing the Library — `library`
|
|
2125
|
+
|
|
2126
|
+
The Library is what Makersclaw keeps for every workspace: **collections of
|
|
2127
|
+
files** (pitch decks, PDFs, HTML website templates, graphics) and
|
|
2128
|
+
**collections of rows** (a dataset: a list of investors, growth
|
|
2129
|
+
examples). Members browse it in the Library window on the desk. An app
|
|
2130
|
+
can show the same content inside a screen, read live from the platform.
|
|
2131
|
+
|
|
2132
|
+
Use it when the app **shows examples, templates or a dataset that
|
|
2133
|
+
Makersclaw keeps**: a gallery of pitch decks, a picker of website
|
|
2134
|
+
templates to start from, a table of investors to choose from. The screen
|
|
2135
|
+
asks the Library when it opens, so what it shows is what the Library
|
|
2136
|
+
holds today.
|
|
2137
|
+
|
|
2138
|
+
Not for:
|
|
2139
|
+
|
|
2140
|
+
- **The app's own data.** That is your tables (§5, Your tables) and the
|
|
2141
|
+
company brain. The Library is Makersclaw's, the same for every
|
|
2142
|
+
workspace; nothing a member does in the app is written to it.
|
|
2143
|
+
- **Sample rows for an empty screen.** Examples of your own app's data
|
|
2144
|
+
are `useFixture` (§3a), never the Library.
|
|
2145
|
+
- **Copying into the workspace.** The Library is read only: the door has
|
|
2146
|
+
no write. A member who wants a collection's rows in their company
|
|
2147
|
+
data, or a file in their Files, asks the agent, which has the Library's
|
|
2148
|
+
tools and records the copy:
|
|
2149
|
+
|
|
2150
|
+
```js
|
|
2151
|
+
import { ask } from "../lib/platform";
|
|
2152
|
+
|
|
2153
|
+
ask({ text: `Copy the "${collection.title}" list into our company data`, how: `The Library collection is "${collection.slug}".` });
|
|
2154
|
+
```
|
|
2155
|
+
|
|
2156
|
+
#### Reading it
|
|
2157
|
+
|
|
2158
|
+
```js
|
|
2159
|
+
import { library } from "../lib/platform";
|
|
2160
|
+
|
|
2161
|
+
library.collections({ q, shelf }) → data { collections: [card] }
|
|
2162
|
+
library.collection(id) → data { collection }
|
|
2163
|
+
library.items(id, { q, tag, cursor, limit }) → data { items, next_cursor, total, preview_only }
|
|
2164
|
+
library.rows(id, { q, filters, cursor, limit }) → data { rows, next_cursor, total, preview_only }
|
|
2165
|
+
library.item(id) → data { item, file_url?, text_excerpt? }
|
|
2166
|
+
```
|
|
2167
|
+
|
|
2168
|
+
Each resolves `{ ok, status, data }` or `{ ok: false, status, error,
|
|
2169
|
+
unavailable, code }` like `me`, and never throws. A collection's `id` is
|
|
2170
|
+
its slug (`"pitch-decks"`) or its uuid; an item's is its uuid. An id that
|
|
2171
|
+
names nothing asks nothing of the platform. Every call takes `signal`
|
|
2172
|
+
among its options.
|
|
2173
|
+
|
|
2174
|
+
- `shelf` is one of `decks`, `websites`, `designs`, `documents`,
|
|
2175
|
+
`datasets`, `examples`. `q` is a search. A card is `{ id, slug, title,
|
|
2176
|
+
blurb, kind: "files" | "rows", shelf, tags, access: "free" | "paid",
|
|
2177
|
+
status, public_page, cover_url, item_count, row_count, usable,
|
|
2178
|
+
preview_only }`; `collection` adds `body`, `columns`, `source`,
|
|
2179
|
+
`licence`, `preview_count`, `personal_data`, `published_at`.
|
|
2180
|
+
- **Items** (a files collection): `{ id, title, description, tags,
|
|
2181
|
+
format, mime, bytes, preview_url, source_url, licence, position,
|
|
2182
|
+
locked }`. `format` is `pdf`, `image`, `html`, `slides`, `document`,
|
|
2183
|
+
`sheet`, `archive` or `other`. `tag` narrows by a tag. `limit` is a
|
|
2184
|
+
whole number: 30 items a page unless you say, and more than 60 is cut
|
|
2185
|
+
to 60.
|
|
2186
|
+
- **Rows** (a rows collection): `{ id, data, source_url }`. `data` is
|
|
2187
|
+
keyed by the collection's `columns` (`{ key, label, type, filter, … }`;
|
|
2188
|
+
`type` is `text`, `long_text`, `number`, `url`, `email`, `image`,
|
|
2189
|
+
`tags` or `date`). `filters` is `{ <column key>: value }` for the
|
|
2190
|
+
columns with `filter: true`, an exact match (for a `tags` column, rows
|
|
2191
|
+
that have the tag); any other column is refused in words. `limit`: 50
|
|
2192
|
+
rows a page unless you say, and more than 100 is cut to 100.
|
|
2193
|
+
`source_url` is where the row
|
|
2194
|
+
was found: show it beside a person, an investor or a figure.
|
|
2195
|
+
- **Paging.** A page with more answers `next_cursor`: pass it back as
|
|
2196
|
+
`cursor`. Take it as given; do not read or build one.
|
|
2197
|
+
- `item(id)` is the item whole: its file's signed address as `file_url`
|
|
2198
|
+
and the first 4,000 characters of its text as `text_excerpt` (the
|
|
2199
|
+
start of a PDF's words, an HTML page's source).
|
|
2200
|
+
|
|
2201
|
+
The hooks read once, when the screen opens or an argument changes, and
|
|
2202
|
+
page for you:
|
|
2203
|
+
|
|
2204
|
+
```js
|
|
2205
|
+
useLibraryCollections({ q, shelf }) → { collections, loading, error, code, unavailable, reload }
|
|
2206
|
+
useLibraryCollection(id) → { collection, loading, error, code, unavailable, reload }
|
|
2207
|
+
useLibraryItems(id, { q, tag, limit }) → { items, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
|
|
2208
|
+
useLibraryRows(id, { q, filters, limit }) → { rows, total, previewOnly, hasMore, loading, loadingMore, error, code, unavailable, loadMore, reload }
|
|
2209
|
+
useLibraryItem(id) → { item, fileUrl, textExcerpt, loading, error, code, unavailable, reload }
|
|
2210
|
+
```
|
|
2211
|
+
|
|
2212
|
+
`items` and `rows` hold the pages read so far; `loadMore()` reads the
|
|
2213
|
+
next and adds it (`hasMore` says there is one; it does nothing while a
|
|
2214
|
+
page is out). A new `id`, `q`, `tag`, `filters` or `limit` starts the
|
|
2215
|
+
list over, showing `loading` and no rows, never the last list: type-ahead
|
|
2216
|
+
should wait for a pause before it changes `q`. Nothing is read until
|
|
2217
|
+
there is an `id` (and `enabled: false` reads nothing). `unavailable` and
|
|
2218
|
+
`error` are never both set: `unavailable` is a claw from before the door
|
|
2219
|
+
or no network (show the quiet "not connected yet"), `error` is the
|
|
2220
|
+
platform's words and `code` its code when it named one.
|
|
2221
|
+
|
|
2222
|
+
```jsx
|
|
2223
|
+
"use client";
|
|
2224
|
+
import { Badge, Button, Card, Empty, Image, Notice } from "../components/ui";
|
|
2225
|
+
import { useLibraryItems } from "../lib/hooks";
|
|
2226
|
+
|
|
2227
|
+
export default function Decks() {
|
|
2228
|
+
const { items, total, previewOnly, hasMore, loadMore, loading, loadingMore, error, unavailable } =
|
|
2229
|
+
useLibraryItems("pitch-decks", { limit: 24 });
|
|
2230
|
+
if (unavailable) return <p className="text-sm text-muted-foreground">The Library is not connected yet.</p>;
|
|
2231
|
+
if (error) return <Notice tone="danger">{error}</Notice>;
|
|
2232
|
+
if (!loading && !items.length) return <Empty title="No decks yet" body="Nothing in this collection matches." />;
|
|
2233
|
+
return (
|
|
2234
|
+
<div className="grid gap-4">
|
|
2235
|
+
<div className="grid grid-cols-2 gap-4 lg:grid-cols-4">
|
|
2236
|
+
{items.map((item) => (
|
|
2237
|
+
<Card key={item.id} padding="sm" className="grid gap-2">
|
|
2238
|
+
<Image src={item.preview_url} alt="" ratio="photo" />
|
|
2239
|
+
<p className="text-sm font-medium">{item.title}</p>
|
|
2240
|
+
<Badge>{item.format}</Badge>
|
|
2241
|
+
</Card>
|
|
2242
|
+
))}
|
|
2243
|
+
</div>
|
|
2244
|
+
{previewOnly && total > items.length ? <Notice>{total - items.length} more come with a paid plan.</Notice> : null}
|
|
2245
|
+
{hasMore ? <Button loading={loadingMore} onClick={loadMore}>Show more</Button> : null}
|
|
2246
|
+
</div>
|
|
2247
|
+
);
|
|
2248
|
+
}
|
|
2249
|
+
```
|
|
2250
|
+
|
|
2251
|
+
#### A paid collection on a Free plan
|
|
2252
|
+
|
|
2253
|
+
A collection with `access: "paid"` is for paid workspaces. On a Free plan
|
|
2254
|
+
it is a **preview**, not a refusal: the card says `usable: false` and
|
|
2255
|
+
`preview_only: true`, and `items` or `rows` answer only the first
|
|
2256
|
+
`preview_count` of them (a search or a filter runs over those), with
|
|
2257
|
+
`preview_only: true` and the **true** `total`. `total` minus what you
|
|
2258
|
+
hold is what "comes with a paid plan". The items past the preview are
|
|
2259
|
+
not in the list (the item's `locked` flag is for such an item, and a
|
|
2260
|
+
list of a preview carries only the preview's, so it reads `false`
|
|
2261
|
+
there); asking for one by its id, `library.item(id)`, is a 403 with
|
|
2262
|
+
`code: "needs_plan"` and the platform's words ("This collection comes
|
|
2263
|
+
with a paid plan."): show them, and stop. The Library window on the desk
|
|
2264
|
+
has the Upgrade button; an app has none to offer. On a paid plan the
|
|
2265
|
+
same calls answer the whole collection.
|
|
2266
|
+
|
|
2267
|
+
#### Files
|
|
2268
|
+
|
|
2269
|
+
- **`file_url` is a signed address, good for ten minutes.** Show or
|
|
2270
|
+
download from it when the member asks, and never keep it: not in a row,
|
|
2271
|
+
not in `localStorage`, not in a link that outlives the screen. A new
|
|
2272
|
+
`library.item(id)` (or `reload()`) signs another. Row cells of type
|
|
2273
|
+
`image` are signed the same way, so a table of rows with pictures that
|
|
2274
|
+
stays open should read its page again now and then.
|
|
2275
|
+
- **`preview_url` and `cover_url` are plain pictures** that stay: use
|
|
2276
|
+
them in `Image` for a card or a thumbnail. A row's image is not one;
|
|
2277
|
+
it is a signed address.
|
|
2278
|
+
- A PDF opens in a new tab (`<Button href={fileUrl} target="_blank"
|
|
2279
|
+
rel="noreferrer">`); an image is an `Image` of `fileUrl`; the other
|
|
2280
|
+
formats are a download link.
|
|
2281
|
+
- **An `html` item (a website template) is shown only in a sandboxed
|
|
2282
|
+
frame, never in the app's own page.** Read its file as text and give
|
|
2283
|
+
it to an `iframe` as `srcDoc` with `sandbox="allow-scripts"`, so its
|
|
2284
|
+
own scripts run. **Never add `allow-same-origin`**: with it the
|
|
2285
|
+
template's scripts run as your app, with the member's session and
|
|
2286
|
+
every `_claw` door. Never `dangerouslySetInnerHTML`, never
|
|
2287
|
+
`iframe src={fileUrl}`, and never your own origin: Makersclaw does not
|
|
2288
|
+
serve these files from it either.
|
|
2289
|
+
|
|
2290
|
+
```jsx
|
|
2291
|
+
"use client";
|
|
2292
|
+
import { useEffect, useState } from "react";
|
|
2293
|
+
import { Notice, Spinner } from "../components/ui";
|
|
2294
|
+
import { useLibraryItem } from "../lib/hooks";
|
|
2295
|
+
|
|
2296
|
+
export default function TemplatePreview({ id }) {
|
|
2297
|
+
const { item, fileUrl, code, error, unavailable } = useLibraryItem(id);
|
|
2298
|
+
const [html, setHtml] = useState(null);
|
|
2299
|
+
const [failed, setFailed] = useState(false);
|
|
2300
|
+
useEffect(() => {
|
|
2301
|
+
if (!fileUrl) return undefined;
|
|
2302
|
+
const controller = new AbortController();
|
|
2303
|
+
fetch(fileUrl, { signal: controller.signal })
|
|
2304
|
+
.then((res) => (res.ok ? res.text() : Promise.reject(new Error("no file"))))
|
|
2305
|
+
.then(setHtml)
|
|
2306
|
+
.catch(() => {
|
|
2307
|
+
if (!controller.signal.aborted) setFailed(true);
|
|
2308
|
+
});
|
|
2309
|
+
return () => controller.abort();
|
|
2310
|
+
}, [fileUrl]);
|
|
2311
|
+
if (unavailable) return <p className="text-sm text-muted-foreground">The Library is not connected yet.</p>;
|
|
2312
|
+
if (error) return <Notice tone={code === "needs_plan" ? "info" : "danger"}>{error}</Notice>;
|
|
2313
|
+
if (failed) return <Notice tone="danger">This template did not open. Try again.</Notice>;
|
|
2314
|
+
if (html === null) return <Spinner />;
|
|
2315
|
+
return <iframe title={item.title} srcDoc={html} sandbox="allow-scripts" className="h-96 w-full rounded-md border border-border" />;
|
|
2316
|
+
}
|
|
2317
|
+
```
|
|
2318
|
+
|
|
2319
|
+
#### What to keep in mind
|
|
2320
|
+
|
|
2321
|
+
- **Browser only, in both modes.** The read rides the member's session:
|
|
2322
|
+
`library` and the hooks run in a `"use client"` file. A server
|
|
2323
|
+
component or a server action has no member and cannot call it.
|
|
2324
|
+
- **Never by its path.** A string naming `_claw/library` fails `npm run
|
|
2325
|
+
check` (§6, `library`): the functions handle a claw without the door, a
|
|
2326
|
+
dropped network and an abort, which a bare `fetch` does not.
|
|
2327
|
+
- **A claw from before the door** answers a 404 that names no refusal:
|
|
2328
|
+
`unavailable: true`, from every call and every hook. A collection or
|
|
2329
|
+
item that is not there (or is a draft the member cannot see) is a 404
|
|
2330
|
+
that names its code, so `unavailable` stays false and `error` says so.
|
|
2331
|
+
Show a missing door as "not connected yet", and a missing collection as
|
|
2332
|
+
"not found".
|
|
2333
|
+
- **Show where it came from.** An item's `licence` and `source_url`, a
|
|
2334
|
+
row's `source_url` and a collection's `source` are in the answer for a
|
|
2335
|
+
reason: print them where the content is shown.
|
|
2336
|
+
- **A rows collection can list people** (`personal_data: true`). It is
|
|
2337
|
+
shown to the member who has the app open. Do not copy it anywhere
|
|
2338
|
+
yourself: no `insertRow` of its rows, no export, no sending it to your
|
|
2339
|
+
own server. Using it in the company's data is a copy through the
|
|
2340
|
+
agent.
|
|
2341
|
+
- **The platform notes that the app showed a collection**, once a day
|
|
2342
|
+
per app and collection.
|
|
2343
|
+
- **Read it when the screen needs it.** Not on every keystroke, and not
|
|
2344
|
+
in a loop over every collection: a shelf is one `collections` call.
|
|
2345
|
+
|
|
1763
2346
|
### Activity — the contract
|
|
1764
2347
|
|
|
1765
2348
|
`claw_app.activity` is how the founder sees the work. It is the
|
|
@@ -1840,6 +2423,8 @@ ok tables its own schema (makersclaw.json): every table named bare, and e
|
|
|
1840
2423
|
ok brain no brain block in makersclaw.json; no lib/brain.js call names a kind
|
|
1841
2424
|
ok viewport nothing in the app sizes itself by the window
|
|
1842
2425
|
ok llm no screen names _claw/llm: a model is called through llm() or useLlm() (README §5)
|
|
2426
|
+
ok library no screen names _claw/library: the Library is read through library() or its hooks (README §5)
|
|
2427
|
+
ok actions no actions declared in makersclaw.json: the app's agent writes as references/actions.md says
|
|
1843
2428
|
ok smoke built in 41s · / → 307 · /s/drafts 200 · /s/sent 200 (0.6s)
|
|
1844
2429
|
all clear
|
|
1845
2430
|
```
|
|
@@ -1851,6 +2436,16 @@ ok browser files and a door: 2 client surfaces; no server code, route, pro
|
|
|
1851
2436
|
ok smoke built in 38s (copy at ~/.claw-check/app) · export 2.1 MB in 64 files · / → 200 to /s/drafts · /s/drafts 200 · /s/sent 200 (0.1s)
|
|
1852
2437
|
```
|
|
1853
2438
|
|
|
2439
|
+
`actions` holds `makersclaw.json` `actions` to the platform's rules
|
|
2440
|
+
(§5, Declared actions) and, once any is declared, refuses every write a
|
|
2441
|
+
screen makes that is not one.
|
|
2442
|
+
|
|
2443
|
+
`automations` runs `makersclaw.json` `automations` (§5, Shipped
|
|
2444
|
+
automations) through the platform's own validator, one line per problem
|
|
2445
|
+
(its place, then what is wrong; at most 8, then "and N more"). It reads
|
|
2446
|
+
two copies of claw's format kept in `check/` and is skipped, not failed,
|
|
2447
|
+
on a node older than 22.18 (it cannot read them).
|
|
2448
|
+
|
|
1854
2449
|
`kit` refuses a fixed file that differs from the template (they are
|
|
1855
2450
|
hashed in `check/pins.json`) and any file of yours under `components/ui`
|
|
1856
2451
|
or `components/parts`. `viewport` refuses anything in your code that
|
|
@@ -1966,6 +2561,14 @@ are the door too). A path built from pieces or held in a variable is not
|
|
|
1966
2561
|
read here, as for rule 8. A longer name (`_claw/llm-notes`) is another
|
|
1967
2562
|
route, and a comment or text in JSX is not a string of code.
|
|
1968
2563
|
|
|
2564
|
+
`library` is the same rule for the Library's door: no string in the code
|
|
2565
|
+
names `_claw/library`, and none handed to `claw()`, `clawUrl()` or
|
|
2566
|
+
`clawStream()` starts `library`. The Library is read with `library` from
|
|
2567
|
+
`lib/platform.js` or the `useLibrary…` hooks (§5, Showing the Library),
|
|
2568
|
+
which handle a claw without the door, a dropped network, an id that
|
|
2569
|
+
names nothing and an abort. It reads every app, in both modes, and the
|
|
2570
|
+
path as a browser reads it (`claw("./library/items")` is the door too).
|
|
2571
|
+
|
|
1969
2572
|
`browser` reads a browser app only (`"mode": "browser"`): its pages are
|
|
1970
2573
|
files built once, and everything they read or write goes through the
|
|
1971
2574
|
platform's data door. So it refuses, file and line, a `"use server"`
|