@theoremjs/studio 0.0.0-stage → 0.3.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/LICENSE +21 -0
- package/README.md +295 -2
- package/agreement.d.ts +14 -0
- package/agreement.js +80 -0
- package/asks.d.ts +47 -0
- package/asks.js +54 -0
- package/browser-connection.d.ts +49 -0
- package/browser-connection.js +215 -0
- package/browser-engine.d.ts +11 -0
- package/browser-engine.js +11 -0
- package/browser-execution.d.ts +6 -0
- package/browser-execution.js +18 -0
- package/browser-live.d.ts +4 -0
- package/browser-live.js +132 -0
- package/browser-transport.d.ts +33 -0
- package/browser-transport.js +229 -0
- package/browser.d.ts +4 -0
- package/browser.js +4 -0
- package/canonical.d.ts +10 -0
- package/canonical.js +25 -0
- package/compile-workspace.d.ts +28 -0
- package/compile-workspace.js +295 -0
- package/compile.d.ts +65 -0
- package/compile.js +1605 -0
- package/concierge-demo.d.ts +17 -0
- package/concierge-demo.js +1230 -0
- package/conversation-key.d.ts +5 -0
- package/conversation-key.js +10 -0
- package/decision-example-images.d.ts +30 -0
- package/decision-example-images.js +30 -0
- package/deno.json +3 -0
- package/draft.d.ts +407 -0
- package/draft.js +505 -0
- package/editors.d.ts +29 -0
- package/editors.js +51 -0
- package/example-embedding-files.d.ts +11 -0
- package/example-embedding-files.js +20 -0
- package/example.d.ts +36 -0
- package/example.js +357 -0
- package/guardrail-probe.d.ts +100 -0
- package/guardrail-probe.js +722 -0
- package/held-credentials.d.ts +28 -0
- package/held-credentials.js +87 -0
- package/installed.mjs +40 -0
- package/lent-keys.d.ts +122 -0
- package/lent-keys.js +47 -0
- package/line-diff.d.ts +15 -0
- package/line-diff.js +41 -0
- package/live-connection.d.ts +22 -0
- package/live-connection.js +27 -0
- package/live-session-bridge.d.ts +15 -0
- package/live-session-bridge.js +202 -0
- package/map-line.d.ts +19 -0
- package/map-line.js +42 -0
- package/map.d.ts +154 -0
- package/map.js +525 -0
- package/media-accept.d.ts +19 -0
- package/media-accept.js +65 -0
- package/mod.d.ts +39 -0
- package/mod.js +33 -0
- package/origins.d.ts +52 -0
- package/origins.js +165 -0
- package/package.json +85 -4
- package/page/assets/Banner-BISz3nXA.js +2 -0
- package/page/assets/BottomSheet-BwfBDtje.js +1 -0
- package/page/assets/Card-Lp-0P5eL.js +1 -0
- package/page/assets/CardWall-CBRLdDZW.js +1 -0
- package/page/assets/Center-nHS1JSux.js +1 -0
- package/page/assets/CheckboxInput-Cj5pk-KI.js +2 -0
- package/page/assets/CodeBlock-C7XJ4ioE.js +51 -0
- package/page/assets/CollapsibleGroup-N7_SOjbm.js +2 -0
- package/page/assets/ContextMenu-CBu9H-9H.js +2 -0
- package/page/assets/DateInput-BGrQ5tPC.js +1 -0
- package/page/assets/Dialog-DELWQo-v.js +1 -0
- package/page/assets/EmptyState-C8W4JKBZ.js +1 -0
- package/page/assets/HoverCard-D1Y1ltWQ.js +1 -0
- package/page/assets/Icon-JrysT8aU.js +3 -0
- package/page/assets/IconAlertTriangle-BqAEqqdU.js +1 -0
- package/page/assets/IconButton-DlOGzJIX.js +1 -0
- package/page/assets/IconEye-BB5aY-wQ.js +1 -0
- package/page/assets/IconFileText-6zOFKKrF.js +1 -0
- package/page/assets/IconSearch-BTx66a40.js +1 -0
- package/page/assets/IconShield-DDOh7Gr5.js +1 -0
- package/page/assets/ItemSwipeLayer-Ckn4X6h9.js +1 -0
- package/page/assets/PaneState-BvA2tLQg.js +1 -0
- package/page/assets/PaneState-eUzUkNE8.css +1 -0
- package/page/assets/ScrollableArea-Ckugdj1N.js +1 -0
- package/page/assets/Section-DJ97F7QE.js +1 -0
- package/page/assets/SegmentedControlItem-h-aaXzyS.js +1 -0
- package/page/assets/SidePanel-BL32abk8.js +1 -0
- package/page/assets/StackItem-CQviqAfM.js +1 -0
- package/page/assets/Text-bum6zWWx.js +2 -0
- package/page/assets/TimestampHoverCard-DQIG0RZF.js +1 -0
- package/page/assets/ToolResultCharts-CgshSv9Q.js +1 -0
- package/page/assets/Tooltip-BH9xiRMl.js +1 -0
- package/page/assets/TraceInspector-_yZiz05W.js +1 -0
- package/page/assets/TraceOverview-BPO-HIYK.js +57 -0
- package/page/assets/VStack-CkVMcNiK.js +1 -0
- package/page/assets/_virtual_studio-type-sources-ByxqQaOG.js +12936 -0
- package/page/assets/arrive-DvbqpeRS.js +1 -0
- package/page/assets/browser-engine-CYq9DQAM.js +9 -0
- package/page/assets/browser-transport-D-2jDYe7.js +47 -0
- package/page/assets/codicon-DF1abBS2.ttf +0 -0
- package/page/assets/compile-egress-BSxOdX4K.js +23 -0
- package/page/assets/container.stylex-BmOi-8DQ.js +1 -0
- package/page/assets/createReactComponent-CZwsv6DD.js +1 -0
- package/page/assets/decision-example-images-CZGr7YIT.js +1 -0
- package/page/assets/devWarning-DxuplmRl.js +1 -0
- package/page/assets/editor-DjpsE8to.css +1 -0
- package/page/assets/editor.api-Cd3ViPQa.js +908 -0
- package/page/assets/editor.worker-6GY8RhDc.js +1 -0
- package/page/assets/editor.worker-BmdWdrHZ.js +33 -0
- package/page/assets/editors-BJX_S59A.js +1 -0
- package/page/assets/egress-automata-B5ZGE1mT.js +1 -0
- package/page/assets/embedding-space-view-CfQBPDxD.js +140 -0
- package/page/assets/encode-files-Bc3HJyAh.js +1 -0
- package/page/assets/export-agent-C3yyzXH8.js +43 -0
- package/page/assets/figtree-latin-400-normal-BD4aNku5.woff +0 -0
- package/page/assets/figtree-latin-400-normal-g7Dtegnw.woff2 +0 -0
- package/page/assets/figtree-latin-500-normal-BWnGEVsr.woff2 +0 -0
- package/page/assets/figtree-latin-500-normal-B_yy1phn.woff +0 -0
- package/page/assets/figtree-latin-600-normal-BM_oTo4n.woff +0 -0
- package/page/assets/figtree-latin-600-normal-Cv_xCTDl.woff2 +0 -0
- package/page/assets/figtree-latin-700-normal-BCCt2T1q.woff +0 -0
- package/page/assets/figtree-latin-700-normal-th6qEP7c.woff2 +0 -0
- package/page/assets/focusOutline.stylex-BT0kfa4t.js +1 -0
- package/page/assets/focusableSelector-DXZeMU85.js +1 -0
- package/page/assets/groupStyles-C7Ter7zC.js +1 -0
- package/page/assets/guardrail-tester-Gut5xK4a.js +9 -0
- package/page/assets/host-patterns-C9RMP16Q.js +1 -0
- package/page/assets/index-CvvmFKgS.js +105 -0
- package/page/assets/index-DOaHlqBo.css +1 -0
- package/page/assets/isRtlElement-BG33-k_H.js +1 -0
- package/page/assets/labels-provider-4TIWDvsE.js +3 -0
- package/page/assets/lent-keys-C32ems-I.js +1 -0
- package/page/assets/live-ingress-lDUGPwth.js +1 -0
- package/page/assets/live-messages-CnkL4GWi.js +1 -0
- package/page/assets/mergeProps-ptS-gIMz.js +1 -0
- package/page/assets/padding.stylex-B76907Zf.js +1 -0
- package/page/assets/preload-helper-DpV6A1kQ.js +1 -0
- package/page/assets/reader-BOCCYaRp.js +7 -0
- package/page/assets/register-CDgivxvX.js +2 -0
- package/page/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/page/assets/schemas-BQ9Jydzb.js +56 -0
- package/page/assets/shaped-data-BcarWqd5.js +16 -0
- package/page/assets/sharedResizeObserver-4U9Xq5Oq.js +1 -0
- package/page/assets/stub-DhdcU_Ew.js +471 -0
- package/page/assets/studio-code-pane-C_SAbcOa.js +8 -0
- package/page/assets/studio-console-DZwlEsvr.js +3 -0
- package/page/assets/studio-decision-B0FnCAXA.js +1 -0
- package/page/assets/studio-embedding-CmA51HVo.js +2 -0
- package/page/assets/studio-host-console-By7hqu2l.js +2 -0
- package/page/assets/studio-live-BrcVQcyV.js +1 -0
- package/page/assets/studio-map-B_xSia-z.js +1 -0
- package/page/assets/studio-map-Bb06Tw1F.css +1 -0
- package/page/assets/studio-monaco-CbKf90i6.css +1 -0
- package/page/assets/studio-monaco-xfyfezQS.js +34 -0
- package/page/assets/studio-ts.worker-B-EXG4Sv.js +67741 -0
- package/page/assets/studio-ts.worker-BXtW3z-O.js +1 -0
- package/page/assets/studio-type-checker-BOvxudki.js +23 -0
- package/page/assets/themeProps-3IqahpCr.js +1 -0
- package/page/assets/tokens.stylex-DkHf0P9C.js +1 -0
- package/page/assets/tool-schema-idaOe2nI.js +18 -0
- package/page/assets/trace-patterns-DnYJa0nI.js +1 -0
- package/page/assets/trace-record-C3zNksA_.js +1 -0
- package/page/assets/trace-schema-9CdEyG6Q.js +1 -0
- package/page/assets/tree-DqyAMsbI.js +3 -0
- package/page/assets/turn-client-Du3Um3Mg.js +2 -0
- package/page/assets/types-BhfXQCLx.js +1 -0
- package/page/assets/typescript-20GgZ8PJ.js +1 -0
- package/page/assets/use-one-call-Hcs8YBp1.js +1 -0
- package/page/assets/useAdaptivePresentation-BzmPCddb.js +1 -0
- package/page/assets/useClipboard-BgGRxRMJ.js +1 -0
- package/page/assets/useContainerReveal-BFy8N_QU.js +1 -0
- package/page/assets/useDevWarning-Z9SoixOP.js +1 -0
- package/page/assets/useLayerDismissal-B_G7IWpC.js +1 -0
- package/page/assets/useMediaQuery-BCT0NUeZ.js +1 -0
- package/page/assets/useScrollLock-Dyf6PHJt.js +1 -0
- package/page/assets/useScrollableArea-0NzdiBCq.js +1 -0
- package/page/assets/useTooltip-CJM_xhLB.js +1 -0
- package/page/assets/workspace-DZALqEDX.js +1 -0
- package/page/assets/zip-DTcEfps6.js +1 -0
- package/page/index.html +90 -0
- package/page.mjs +49 -0
- package/people.d.ts +87 -0
- package/people.js +110 -0
- package/policy.d.ts +43 -0
- package/policy.js +102 -0
- package/ports.d.mts +32 -0
- package/ports.mjs +85 -0
- package/probe-battery.d.ts +13 -0
- package/probe-battery.js +404 -0
- package/providers.d.ts +149 -0
- package/providers.js +306 -0
- package/read-source.d.ts +48 -0
- package/read-source.js +1301 -0
- package/read-steps.d.ts +23 -0
- package/read-steps.js +2 -0
- package/reader.d.ts +11 -0
- package/reader.js +11 -0
- package/registrations.d.ts +83 -0
- package/registrations.js +1 -0
- package/requirements.d.ts +22 -0
- package/requirements.js +38 -0
- package/run-payload-core.d.ts +28 -0
- package/run-payload-core.js +123 -0
- package/run-payload.d.ts +32 -0
- package/run-payload.js +26 -0
- package/runtime-scope.d.ts +84 -0
- package/runtime-scope.js +308 -0
- package/runtime.d.ts +84 -0
- package/runtime.js +387 -0
- package/section-notes.d.ts +33 -0
- package/section-notes.js +38 -0
- package/serve-page.mjs +96 -0
- package/server/draft-decide.d.ts +72 -0
- package/server/draft-decide.js +111 -0
- package/server/draft-embedding.d.ts +3 -0
- package/server/draft-embedding.js +35 -0
- package/server/draft-handler.d.ts +82 -0
- package/server/draft-handler.js +213 -0
- package/server/draft-probe.d.ts +14 -0
- package/server/draft-probe.js +61 -0
- package/server/draft-replies.d.ts +22 -0
- package/server/draft-replies.js +46 -0
- package/server/edited-session.d.ts +28 -0
- package/server/edited-session.js +83 -0
- package/server/edits.d.ts +38 -0
- package/server/edits.js +195 -0
- package/server/handler.d.ts +133 -0
- package/server/handler.js +598 -0
- package/server/lent-draft.d.ts +19 -0
- package/server/lent-draft.js +23 -0
- package/server/live.d.ts +15 -0
- package/server/live.js +96 -0
- package/server/open-editor.d.ts +63 -0
- package/server/open-editor.js +115 -0
- package/server/origins.d.ts +18 -0
- package/server/origins.js +330 -0
- package/server/project-source.d.ts +208 -0
- package/server/project-source.js +1042 -0
- package/server/project.d.ts +22 -0
- package/server/project.js +56 -0
- package/server/run-traces.d.ts +20 -0
- package/server/run-traces.js +96 -0
- package/server/save-new.d.ts +29 -0
- package/server/save-new.js +514 -0
- package/server/save-plan.d.ts +46 -0
- package/server/save-plan.js +1134 -0
- package/server/save-remove.d.ts +21 -0
- package/server/save-remove.js +528 -0
- package/server/save-session.d.ts +96 -0
- package/server/save-session.js +418 -0
- package/server/save-wire.d.ts +235 -0
- package/server/save-wire.js +8 -0
- package/server/save.d.ts +52 -0
- package/server/save.js +209 -0
- package/server/serve.d.ts +23 -0
- package/server/serve.js +413 -0
- package/server/test-connection.d.ts +17 -0
- package/server/test-connection.js +362 -0
- package/server/test-key.d.ts +2 -0
- package/server/test-key.js +83 -0
- package/server/watch.d.ts +28 -0
- package/server/watch.js +93 -0
- package/server/zod-edit.d.ts +74 -0
- package/server/zod-edit.js +558 -0
- package/server.d.ts +8 -0
- package/server.js +8 -0
- package/setups.mjs +170 -0
- package/shared-carry.d.ts +114 -0
- package/shared-carry.js +523 -0
- package/shared-settings.d.ts +34 -0
- package/shared-settings.js +70 -0
- package/source.d.ts +75 -0
- package/source.js +414 -0
- package/start.mjs +169 -0
- package/stream-lines.d.ts +9 -0
- package/stream-lines.js +27 -0
- package/stub.d.ts +6 -0
- package/stub.js +33 -0
- package/surface.d.ts +53 -0
- package/surface.js +631 -0
- package/system-markup.d.ts +20 -0
- package/system-markup.js +51 -0
- package/tool-schema.d.ts +23 -0
- package/tool-schema.js +69 -0
- package/tools.d.ts +16 -0
- package/tools.js +91 -0
- package/traces.d.ts +24 -0
- package/traces.js +29 -0
- package/transport.d.ts +57 -0
- package/transport.js +187 -0
- package/tree.d.ts +32 -0
- package/tree.js +83 -0
- package/types.d.ts +62 -0
- package/types.js +6 -0
- package/ui/acting-as-button.d.ts +2 -0
- package/ui/acting-as-button.js +16 -0
- package/ui/add-provider.d.ts +13 -0
- package/ui/add-provider.js +20 -0
- package/ui/boot-mark.css +53 -0
- package/ui/boot-mark.d.ts +19 -0
- package/ui/boot-mark.js +128 -0
- package/ui/boot-paint.d.ts +8 -0
- package/ui/boot-paint.js +8 -0
- package/ui/brand-icons.d.ts +57 -0
- package/ui/brand-icons.js +148 -0
- package/ui/built/theme.css +830 -0
- package/ui/built/theme.css.d.ts +9 -0
- package/ui/built/theorem-studio.d.ts +13 -0
- package/ui/built/theorem-studio.js +705 -0
- package/ui/built/theorem-studio.variants.d.ts +28 -0
- package/ui/code/monaco-contributions.d.ts +45 -0
- package/ui/code/studio-code.d.ts +7 -0
- package/ui/code/studio-code.js +253 -0
- package/ui/code/studio-monaco.d.ts +44 -0
- package/ui/code/studio-monaco.js +48 -0
- package/ui/code/studio-ts.worker.d.ts +1 -0
- package/ui/code/studio-ts.worker.js +16 -0
- package/ui/code/studio-type-checker.d.ts +12 -0
- package/ui/code/studio-type-checker.js +308 -0
- package/ui/code/studio-type-sources.d.ts +26 -0
- package/ui/confirm-write.d.ts +12 -0
- package/ui/confirm-write.js +45 -0
- package/ui/diff-block.d.ts +21 -0
- package/ui/diff-block.js +17 -0
- package/ui/figtree.css +59 -0
- package/ui/file-place.d.ts +4 -0
- package/ui/file-place.js +26 -0
- package/ui/guardrail-tester.d.ts +18 -0
- package/ui/guardrail-tester.js +248 -0
- package/ui/inspector-context.d.ts +119 -0
- package/ui/inspector-context.js +84 -0
- package/ui/inspector.d.ts +247 -0
- package/ui/inspector.js +284 -0
- package/ui/lib/acting-as.d.ts +25 -0
- package/ui/lib/acting-as.js +90 -0
- package/ui/lib/boot-sequence.d.ts +32 -0
- package/ui/lib/boot-sequence.js +57 -0
- package/ui/lib/export-agent.d.ts +11 -0
- package/ui/lib/export-agent.js +335 -0
- package/ui/lib/facet-icons.d.ts +20 -0
- package/ui/lib/facet-icons.js +21 -0
- package/ui/lib/panel-motion.d.ts +8 -0
- package/ui/lib/panel-motion.js +74 -0
- package/ui/lib/project-address.d.ts +14 -0
- package/ui/lib/project-address.js +24 -0
- package/ui/lib/project-starting.d.ts +13 -0
- package/ui/lib/project-starting.js +30 -0
- package/ui/lib/project-traces.d.ts +17 -0
- package/ui/lib/project-traces.js +54 -0
- package/ui/lib/read-map.d.ts +30 -0
- package/ui/lib/read-map.js +173 -0
- package/ui/lib/read-progress.d.ts +14 -0
- package/ui/lib/read-progress.js +12 -0
- package/ui/lib/refusal-lines.d.ts +3 -0
- package/ui/lib/refusal-lines.js +8 -0
- package/ui/lib/studio-activity.d.ts +5 -0
- package/ui/lib/studio-activity.js +17 -0
- package/ui/lib/studio-console.d.ts +27 -0
- package/ui/lib/studio-console.js +9 -0
- package/ui/lib/studio-conversation.d.ts +20 -0
- package/ui/lib/studio-conversation.js +130 -0
- package/ui/lib/studio-examples.d.ts +31 -0
- package/ui/lib/studio-examples.js +25 -0
- package/ui/lib/studio-labels.d.ts +6 -0
- package/ui/lib/studio-labels.js +13 -0
- package/ui/lib/studio-map-kept.d.ts +17 -0
- package/ui/lib/studio-map-kept.js +48 -0
- package/ui/lib/studio-open.d.ts +22 -0
- package/ui/lib/studio-open.js +54 -0
- package/ui/lib/studio-page.d.ts +33 -0
- package/ui/lib/studio-page.js +121 -0
- package/ui/lib/studio-prefs.d.ts +26 -0
- package/ui/lib/studio-prefs.js +87 -0
- package/ui/lib/studio-project.d.ts +106 -0
- package/ui/lib/studio-project.js +177 -0
- package/ui/lib/studio-restore.d.ts +49 -0
- package/ui/lib/studio-restore.js +251 -0
- package/ui/lib/studio-run-open.d.ts +15 -0
- package/ui/lib/studio-run-open.js +16 -0
- package/ui/lib/studio-session.d.ts +34 -0
- package/ui/lib/studio-session.js +17 -0
- package/ui/lib/studio-settings.d.ts +15 -0
- package/ui/lib/studio-settings.js +48 -0
- package/ui/lib/studio-store.d.ts +64 -0
- package/ui/lib/studio-store.js +391 -0
- package/ui/lib/studio-watch.d.ts +12 -0
- package/ui/lib/studio-watch.js +27 -0
- package/ui/lib/tab-fills.d.ts +6 -0
- package/ui/lib/tab-fills.js +14 -0
- package/ui/lib/tool-credentials.d.ts +3 -0
- package/ui/lib/tool-credentials.js +23 -0
- package/ui/lib/tool-probe.d.ts +19 -0
- package/ui/lib/tool-probe.js +104 -0
- package/ui/lib/type-icons.d.ts +35 -0
- package/ui/lib/type-icons.js +38 -0
- package/ui/lib/when-idle.d.ts +5 -0
- package/ui/lib/when-idle.js +14 -0
- package/ui/lib/zip.d.ts +5 -0
- package/ui/lib/zip.js +8 -0
- package/ui/map-token.css +11 -0
- package/ui/map-token.d.ts +17 -0
- package/ui/map-token.js +29 -0
- package/ui/mcp-icon.d.ts +6 -0
- package/ui/mcp-icon.js +8 -0
- package/ui/motion.css +113 -0
- package/ui/pan.d.ts +32 -0
- package/ui/pan.js +90 -0
- package/ui/profile-editor.d.ts +33 -0
- package/ui/profile-editor.js +2638 -0
- package/ui/provider-editor.d.ts +15 -0
- package/ui/provider-editor.js +92 -0
- package/ui/read-map.css +48 -0
- package/ui/read-map.d.ts +7 -0
- package/ui/read-map.js +163 -0
- package/ui/refusal-detail.d.ts +4 -0
- package/ui/refusal-detail.js +21 -0
- package/ui/shared-change.d.ts +9 -0
- package/ui/shared-change.js +28 -0
- package/ui/shell-motion.css +121 -0
- package/ui/shell-motion.d.ts +73 -0
- package/ui/shell-motion.js +194 -0
- package/ui/studio-code-pane.d.ts +19 -0
- package/ui/studio-code-pane.js +44 -0
- package/ui/studio-compare.d.ts +80 -0
- package/ui/studio-compare.js +326 -0
- package/ui/studio-conflicts.d.ts +17 -0
- package/ui/studio-conflicts.js +87 -0
- package/ui/studio-connection.d.ts +64 -0
- package/ui/studio-connection.js +286 -0
- package/ui/studio-decision.d.ts +6 -0
- package/ui/studio-decision.js +49 -0
- package/ui/studio-embedding.d.ts +6 -0
- package/ui/studio-embedding.js +30 -0
- package/ui/studio-host-console.d.ts +6 -0
- package/ui/studio-host-console.js +17 -0
- package/ui/studio-host.d.ts +73 -0
- package/ui/studio-host.js +12 -0
- package/ui/studio-live.d.ts +17 -0
- package/ui/studio-live.js +26 -0
- package/ui/studio-map.css +273 -0
- package/ui/studio-map.d.ts +17 -0
- package/ui/studio-map.js +397 -0
- package/ui/studio-nav.d.ts +24 -0
- package/ui/studio-nav.js +17 -0
- package/ui/studio-no-project.d.ts +5 -0
- package/ui/studio-no-project.js +9 -0
- package/ui/studio-run.css +76 -0
- package/ui/studio-run.d.ts +14 -0
- package/ui/studio-run.js +119 -0
- package/ui/studio-runner.d.ts +45 -0
- package/ui/studio-runner.js +187 -0
- package/ui/studio-save.d.ts +49 -0
- package/ui/studio-save.js +307 -0
- package/ui/studio-screen.d.ts +61 -0
- package/ui/studio-screen.js +2078 -0
- package/ui/studio-settings.d.ts +31 -0
- package/ui/studio-settings.js +288 -0
- package/ui/studio-shell.css +27 -0
- package/ui/studio-shell.d.ts +43 -0
- package/ui/studio-shell.js +87 -0
- package/ui/studio-theme.d.ts +7 -0
- package/ui/studio-theme.js +94 -0
- package/ui/studio.css +427 -0
- package/ui/theorem-mark.css +84 -0
- package/ui/theorem-mark.d.ts +22 -0
- package/ui/theorem-mark.js +21 -0
- package/vite.d.mts +30 -0
- package/vite.mjs +277 -0
- package/workspace.d.ts +230 -0
- package/workspace.js +1054 -0
|
@@ -0,0 +1,558 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tool's schema as the builder's file writes it in Zod: the `z.` call it starts from, each
|
|
3
|
+
* method called on it, and the object its fields are written in. Save reads a schema this way to
|
|
4
|
+
* change one part of it where that part is written, and writes a new part as Zod.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { slowPatternProblem } from '@theoremjs/agents/guardrails/compile';
|
|
9
|
+
import { jsonSchemaFromZod } from '@theoremjs/agents/kernel';
|
|
10
|
+
import ts from 'typescript';
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { canonical } from "../canonical.js";
|
|
13
|
+
import { valueSource } from "../source.js";
|
|
14
|
+
import { keySource, quoteSource } from "../tool-schema.js";
|
|
15
|
+
import { followed, propertyName, shapeOf, unwrapped, } from "./project-source.js";
|
|
16
|
+
const ZOD_NAMES = new WeakMap();
|
|
17
|
+
/** The names a file knows Zod by: `z`, as a rule. */
|
|
18
|
+
function zodNames(source) {
|
|
19
|
+
const known = ZOD_NAMES.get(source);
|
|
20
|
+
if (known)
|
|
21
|
+
return known;
|
|
22
|
+
const names = new Set();
|
|
23
|
+
for (const statement of source.statements) {
|
|
24
|
+
if (!ts.isImportDeclaration(statement) || !ts.isStringLiteralLike(statement.moduleSpecifier))
|
|
25
|
+
continue;
|
|
26
|
+
if (!/^(npm:)?zod(@[^/]*)?(\/.*)?$/.test(statement.moduleSpecifier.text))
|
|
27
|
+
continue;
|
|
28
|
+
const clause = statement.importClause;
|
|
29
|
+
if (clause?.name)
|
|
30
|
+
names.add(clause.name.text);
|
|
31
|
+
const bindings = clause?.namedBindings;
|
|
32
|
+
if (bindings && ts.isNamespaceImport(bindings))
|
|
33
|
+
names.add(bindings.name.text);
|
|
34
|
+
if (bindings && ts.isNamedImports(bindings)) {
|
|
35
|
+
for (const element of bindings.elements) {
|
|
36
|
+
if ((element.propertyName ?? element.name).text === 'z')
|
|
37
|
+
names.add(element.name.text);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
ZOD_NAMES.set(source, names);
|
|
42
|
+
return names;
|
|
43
|
+
}
|
|
44
|
+
/** The name `source` calls Zod by, to write a new schema in it. */
|
|
45
|
+
export function zodName(source) {
|
|
46
|
+
const [first] = zodNames(source);
|
|
47
|
+
return first;
|
|
48
|
+
}
|
|
49
|
+
/** How far a schema is followed through names and calls. */
|
|
50
|
+
const MAX_HOPS = 32;
|
|
51
|
+
/**
|
|
52
|
+
* Reads the schema an expression stands for. A name is followed to the constant it stands for,
|
|
53
|
+
* and a project function to what it returns. Undefined when it does not lead to a `z.` call.
|
|
54
|
+
*/
|
|
55
|
+
export function readZod(project, at) {
|
|
56
|
+
const chain = [];
|
|
57
|
+
let here = { ...at, node: unwrapped(at.node) };
|
|
58
|
+
let named = false;
|
|
59
|
+
for (let hop = 0; hop < MAX_HOPS; hop += 1) {
|
|
60
|
+
const { node, source, env } = here;
|
|
61
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
62
|
+
const owner = unwrapped(node.expression.expression);
|
|
63
|
+
const call = { name: node.expression.name.text, call: node, source, ...(env ? { env } : {}) };
|
|
64
|
+
if (ts.isIdentifier(owner) &&
|
|
65
|
+
zodNames(source).has(owner.text) &&
|
|
66
|
+
!env?.bound.has(owner.text)) {
|
|
67
|
+
return { base: call, chain, named };
|
|
68
|
+
}
|
|
69
|
+
chain.push(call);
|
|
70
|
+
here = { ...here, node: owner };
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const next = followed(project, here);
|
|
74
|
+
if (next.node === node && next.source === source)
|
|
75
|
+
return undefined;
|
|
76
|
+
named = true;
|
|
77
|
+
here = next;
|
|
78
|
+
}
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
/** The methods a schema keeps its fields, its description, and its kind through. */
|
|
82
|
+
const READ_THROUGH = new Set([
|
|
83
|
+
'describe',
|
|
84
|
+
'optional',
|
|
85
|
+
'nullable',
|
|
86
|
+
'extend',
|
|
87
|
+
'refine',
|
|
88
|
+
'superRefine',
|
|
89
|
+
'check',
|
|
90
|
+
'brand',
|
|
91
|
+
'readonly',
|
|
92
|
+
'strict',
|
|
93
|
+
'passthrough',
|
|
94
|
+
'loose',
|
|
95
|
+
'min',
|
|
96
|
+
'max',
|
|
97
|
+
'length',
|
|
98
|
+
'nonempty',
|
|
99
|
+
'int',
|
|
100
|
+
'positive',
|
|
101
|
+
'negative',
|
|
102
|
+
'nonnegative',
|
|
103
|
+
'nonpositive',
|
|
104
|
+
'gt',
|
|
105
|
+
'gte',
|
|
106
|
+
'lt',
|
|
107
|
+
'lte',
|
|
108
|
+
'multipleOf',
|
|
109
|
+
'email',
|
|
110
|
+
'url',
|
|
111
|
+
'uuid',
|
|
112
|
+
'regex',
|
|
113
|
+
'trim',
|
|
114
|
+
'toLowerCase',
|
|
115
|
+
'toUpperCase',
|
|
116
|
+
'startsWith',
|
|
117
|
+
'endsWith',
|
|
118
|
+
'includes',
|
|
119
|
+
]);
|
|
120
|
+
/** The first method the studio does not read a schema through: what it returns is for code to say. */
|
|
121
|
+
export function unread(read) {
|
|
122
|
+
return read.chain.find((call) => !READ_THROUGH.has(call.name));
|
|
123
|
+
}
|
|
124
|
+
/** The last call of a method on a schema: the one that counts. */
|
|
125
|
+
export function methodCall(read, name) {
|
|
126
|
+
return read.chain.find((call) => call.name === name);
|
|
127
|
+
}
|
|
128
|
+
/** The text of a method call with its dot, from the end of what it is called on. */
|
|
129
|
+
export function methodSpan(call) {
|
|
130
|
+
return {
|
|
131
|
+
start: call.call.expression.expression.end,
|
|
132
|
+
end: call.call.end,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const OBJECTS = new Set(['object', 'strictObject', 'looseObject']);
|
|
136
|
+
/**
|
|
137
|
+
* The fields of an object schema. Undefined for another kind of schema, and for an object whose
|
|
138
|
+
* fields the studio cannot list: a spread it could not follow, a key the file computes.
|
|
139
|
+
*/
|
|
140
|
+
export function zodObject(project, read) {
|
|
141
|
+
if (!OBJECTS.has(read.base.name))
|
|
142
|
+
return undefined;
|
|
143
|
+
const calls = [read.base, ...read.chain.filter((call) => call.name === 'extend').reverse()];
|
|
144
|
+
const entries = new Map();
|
|
145
|
+
let own;
|
|
146
|
+
for (const { call, source, env } of calls) {
|
|
147
|
+
const [fields] = call.arguments;
|
|
148
|
+
if (!fields || ts.isSpreadElement(fields) || call.arguments.length !== 1)
|
|
149
|
+
return undefined;
|
|
150
|
+
const shape = shapeOf(project, followed(project, { node: fields, source, ...(env ? { env } : {}) }));
|
|
151
|
+
if (!shape?.own || shape.open)
|
|
152
|
+
return undefined;
|
|
153
|
+
for (const entry of shape.entries.values()) {
|
|
154
|
+
entries.delete(entry.key);
|
|
155
|
+
entries.set(entry.key, entry);
|
|
156
|
+
}
|
|
157
|
+
own = shape.own;
|
|
158
|
+
}
|
|
159
|
+
return own ? { entries, own, extended: calls.length > 1 } : undefined;
|
|
160
|
+
}
|
|
161
|
+
/** The kinds of schema the studio writes itself, so it can write one of them again whole. */
|
|
162
|
+
const WRITTEN_KINDS = new Set([
|
|
163
|
+
'string',
|
|
164
|
+
'number',
|
|
165
|
+
'int',
|
|
166
|
+
'boolean',
|
|
167
|
+
'null',
|
|
168
|
+
'unknown',
|
|
169
|
+
'any',
|
|
170
|
+
'enum',
|
|
171
|
+
'literal',
|
|
172
|
+
'array',
|
|
173
|
+
'union',
|
|
174
|
+
'record',
|
|
175
|
+
'email',
|
|
176
|
+
'url',
|
|
177
|
+
'uuid',
|
|
178
|
+
...OBJECTS,
|
|
179
|
+
]);
|
|
180
|
+
/** The methods whose effect the JSON Schema shows, so writing the schema again from it keeps them. */
|
|
181
|
+
const WRITTEN_METHODS = new Set([
|
|
182
|
+
'describe',
|
|
183
|
+
'optional',
|
|
184
|
+
'nullable',
|
|
185
|
+
'default',
|
|
186
|
+
'min',
|
|
187
|
+
'max',
|
|
188
|
+
'nonempty',
|
|
189
|
+
'int',
|
|
190
|
+
'positive',
|
|
191
|
+
'negative',
|
|
192
|
+
'nonnegative',
|
|
193
|
+
'nonpositive',
|
|
194
|
+
'gt',
|
|
195
|
+
'gte',
|
|
196
|
+
'lt',
|
|
197
|
+
'lte',
|
|
198
|
+
'multipleOf',
|
|
199
|
+
'email',
|
|
200
|
+
'url',
|
|
201
|
+
'uuid',
|
|
202
|
+
'regex',
|
|
203
|
+
]);
|
|
204
|
+
/**
|
|
205
|
+
* Whether a schema is written out in full where it stands, in Zod the studio writes itself. Such
|
|
206
|
+
* a schema can be written again from its JSON Schema with nothing lost: no name stands for a part
|
|
207
|
+
* of it, and it has no check or change that only its code holds.
|
|
208
|
+
*/
|
|
209
|
+
export function isWrittenOut(project, at) {
|
|
210
|
+
const read = readZod(project, at);
|
|
211
|
+
if (!read || read.named || !WRITTEN_KINDS.has(read.base.name))
|
|
212
|
+
return false;
|
|
213
|
+
if (read.chain.some((call) => !WRITTEN_METHODS.has(call.name)))
|
|
214
|
+
return false;
|
|
215
|
+
const { source, env } = read.base;
|
|
216
|
+
const parts = partsWritten(read.base);
|
|
217
|
+
return (parts?.every((node) => isWrittenOut(project, { node, source, ...(env ? { env } : {}) })) ??
|
|
218
|
+
false);
|
|
219
|
+
}
|
|
220
|
+
/** The schemas a `z.` call holds, when it lists each one. */
|
|
221
|
+
function partsWritten(base) {
|
|
222
|
+
const parts = [];
|
|
223
|
+
for (const argument of base.call.arguments) {
|
|
224
|
+
const node = unwrapped(argument);
|
|
225
|
+
if (ts.isSpreadElement(node))
|
|
226
|
+
return undefined;
|
|
227
|
+
if (OBJECTS.has(base.name)) {
|
|
228
|
+
const fields = fieldsWritten(node);
|
|
229
|
+
if (!fields)
|
|
230
|
+
return undefined;
|
|
231
|
+
parts.push(...fields);
|
|
232
|
+
}
|
|
233
|
+
else if (base.name === 'union') {
|
|
234
|
+
if (!ts.isArrayLiteralExpression(node) || node.elements.some(ts.isSpreadElement))
|
|
235
|
+
return undefined;
|
|
236
|
+
parts.push(...node.elements);
|
|
237
|
+
}
|
|
238
|
+
else if (base.name === 'array' || base.name === 'record')
|
|
239
|
+
parts.push(node);
|
|
240
|
+
}
|
|
241
|
+
return parts;
|
|
242
|
+
}
|
|
243
|
+
/** The schema of each field an object lists by name. */
|
|
244
|
+
function fieldsWritten(node) {
|
|
245
|
+
if (!ts.isObjectLiteralExpression(node))
|
|
246
|
+
return undefined;
|
|
247
|
+
const fields = [];
|
|
248
|
+
for (const property of node.properties) {
|
|
249
|
+
if (!ts.isPropertyAssignment(property) || propertyName(property) === undefined)
|
|
250
|
+
return undefined;
|
|
251
|
+
fields.push(property.initializer);
|
|
252
|
+
}
|
|
253
|
+
return fields;
|
|
254
|
+
}
|
|
255
|
+
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
256
|
+
const SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
|
|
257
|
+
class Writer {
|
|
258
|
+
name;
|
|
259
|
+
side;
|
|
260
|
+
style;
|
|
261
|
+
constructor(name, side, style) {
|
|
262
|
+
this.name = name;
|
|
263
|
+
this.side = side;
|
|
264
|
+
this.style = style;
|
|
265
|
+
}
|
|
266
|
+
quote(text) {
|
|
267
|
+
return valueSource(text, this.style);
|
|
268
|
+
}
|
|
269
|
+
pads(depth) {
|
|
270
|
+
const { base, unit } = this.style;
|
|
271
|
+
return [base + unit.repeat(depth + 1), base + unit.repeat(depth)];
|
|
272
|
+
}
|
|
273
|
+
only(schema, known) {
|
|
274
|
+
return Object.keys(schema).every((key) => known.includes(key));
|
|
275
|
+
}
|
|
276
|
+
/** A schema with its description and default. Undefined for one the studio does not write as Zod. */
|
|
277
|
+
schema(schema, depth) {
|
|
278
|
+
if (!isRecord(schema))
|
|
279
|
+
return undefined;
|
|
280
|
+
const { description, default: preset, ...rest } = schema;
|
|
281
|
+
let draft = this.kind(rest, depth);
|
|
282
|
+
if (!draft)
|
|
283
|
+
return undefined;
|
|
284
|
+
if (description !== undefined) {
|
|
285
|
+
if (typeof description !== 'string')
|
|
286
|
+
return undefined;
|
|
287
|
+
draft = {
|
|
288
|
+
text: `${draft.text}.describe(${this.quote(description)})`,
|
|
289
|
+
live: draft.live.describe(description),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
if ('default' in schema) {
|
|
293
|
+
let written;
|
|
294
|
+
try {
|
|
295
|
+
written = valueSource(preset, { ...this.style, base: this.pads(depth)[1] });
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
return undefined;
|
|
299
|
+
}
|
|
300
|
+
draft = { text: `${draft.text}.default(${written})`, live: draft.live.default(preset) };
|
|
301
|
+
}
|
|
302
|
+
return draft;
|
|
303
|
+
}
|
|
304
|
+
kind(schema, depth) {
|
|
305
|
+
const { type } = schema;
|
|
306
|
+
if (Object.keys(schema).length === 0)
|
|
307
|
+
return { text: `${this.name}.unknown()`, live: z.unknown() };
|
|
308
|
+
if (Array.isArray(type))
|
|
309
|
+
return this.kinds(schema, type, depth);
|
|
310
|
+
if (Array.isArray(schema.anyOf))
|
|
311
|
+
return this.only(schema, ['anyOf']) ? this.union(schema.anyOf, depth) : undefined;
|
|
312
|
+
if ('const' in schema)
|
|
313
|
+
return this.literal(schema);
|
|
314
|
+
if (Array.isArray(schema.enum))
|
|
315
|
+
return this.choice(schema, schema.enum);
|
|
316
|
+
return this.typed(schema, depth);
|
|
317
|
+
}
|
|
318
|
+
/** A schema of more than one type: the one type that can be null, or a union of them. */
|
|
319
|
+
kinds(schema, type, depth) {
|
|
320
|
+
const kinds = type.filter((each) => each !== 'null');
|
|
321
|
+
const [one] = kinds;
|
|
322
|
+
const held = kinds.length === 1 && one
|
|
323
|
+
? this.kind({ ...schema, type: one }, depth)
|
|
324
|
+
: this.only(schema, ['type'])
|
|
325
|
+
? this.union(kinds.map((each) => ({ type: each })), depth)
|
|
326
|
+
: undefined;
|
|
327
|
+
if (!held || kinds.length === type.length)
|
|
328
|
+
return held;
|
|
329
|
+
return { text: `${held.text}.nullable()`, live: held.live.nullable() };
|
|
330
|
+
}
|
|
331
|
+
literal(schema) {
|
|
332
|
+
const { const: value } = schema;
|
|
333
|
+
const plain = typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean';
|
|
334
|
+
if (!plain || !this.only(schema, ['type', 'const']))
|
|
335
|
+
return undefined;
|
|
336
|
+
return {
|
|
337
|
+
text: `${this.name}.literal(${valueSource(value, this.style)})`,
|
|
338
|
+
live: z.literal(value),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
choice(schema, among) {
|
|
342
|
+
const values = among.filter((each) => typeof each === 'string');
|
|
343
|
+
const [first, ...others] = values;
|
|
344
|
+
if (first === undefined ||
|
|
345
|
+
values.length !== among.length ||
|
|
346
|
+
!this.only(schema, ['type', 'enum']))
|
|
347
|
+
return undefined;
|
|
348
|
+
const items = values.map((each) => this.quote(each)).join(', ');
|
|
349
|
+
return { text: `${this.name}.enum([${items}])`, live: z.enum([first, ...others]) };
|
|
350
|
+
}
|
|
351
|
+
/** A schema of one type. */
|
|
352
|
+
typed(schema, depth) {
|
|
353
|
+
const n = this.name;
|
|
354
|
+
const { type } = schema;
|
|
355
|
+
if (type === 'string')
|
|
356
|
+
return this.text(schema);
|
|
357
|
+
if (type === 'number' || type === 'integer')
|
|
358
|
+
return this.number(schema);
|
|
359
|
+
if (type === 'boolean' && this.only(schema, ['type']))
|
|
360
|
+
return { text: `${n}.boolean()`, live: z.boolean() };
|
|
361
|
+
if (type === 'null' && this.only(schema, ['type']))
|
|
362
|
+
return { text: `${n}.null()`, live: z.null() };
|
|
363
|
+
if (type === 'array')
|
|
364
|
+
return this.list(schema, depth);
|
|
365
|
+
if (type === 'object')
|
|
366
|
+
return this.object(schema, depth);
|
|
367
|
+
return undefined;
|
|
368
|
+
}
|
|
369
|
+
union(members, depth) {
|
|
370
|
+
const drafts = members.map((member) => this.schema(member, depth + 1));
|
|
371
|
+
const held = drafts.filter((draft) => draft !== undefined);
|
|
372
|
+
const [first, second, ...others] = held;
|
|
373
|
+
if (!first || !second || held.length !== drafts.length)
|
|
374
|
+
return undefined;
|
|
375
|
+
const [pad, close] = this.pads(depth);
|
|
376
|
+
const lines = held.map((draft) => `${pad}${draft.text},`).join('\n');
|
|
377
|
+
return {
|
|
378
|
+
text: `${this.name}.union([\n${lines}\n${close}])`,
|
|
379
|
+
live: z.union([first.live, second.live, ...others.map((draft) => draft.live)]),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
text(schema) {
|
|
383
|
+
const n = this.name;
|
|
384
|
+
const { minLength, maxLength, pattern, format } = schema;
|
|
385
|
+
if (!this.only(schema, ['type', 'minLength', 'maxLength', 'pattern', 'format']))
|
|
386
|
+
return undefined;
|
|
387
|
+
let draft;
|
|
388
|
+
if (format === undefined)
|
|
389
|
+
draft = { text: `${n}.string()`, live: z.string() };
|
|
390
|
+
else if (format === 'email')
|
|
391
|
+
draft = { text: `${n}.email()`, live: z.email() };
|
|
392
|
+
else if (format === 'uri')
|
|
393
|
+
draft = { text: `${n}.url()`, live: z.url() };
|
|
394
|
+
else if (format === 'uuid')
|
|
395
|
+
draft = { text: `${n}.uuid()`, live: z.uuid() };
|
|
396
|
+
else
|
|
397
|
+
return undefined;
|
|
398
|
+
if (typeof minLength === 'number')
|
|
399
|
+
draft = { text: `${draft.text}.min(${String(minLength)})`, live: draft.live.min(minLength) };
|
|
400
|
+
if (typeof maxLength === 'number')
|
|
401
|
+
draft = { text: `${draft.text}.max(${String(maxLength)})`, live: draft.live.max(maxLength) };
|
|
402
|
+
// A format brings its own pattern: the check below says whether this one is it.
|
|
403
|
+
if (typeof pattern === 'string' && format === undefined) {
|
|
404
|
+
// invariant: A pattern that could hang on what it reads never becomes a live check; the schema stays as it was written.
|
|
405
|
+
if (slowPatternProblem(pattern) !== undefined)
|
|
406
|
+
return undefined;
|
|
407
|
+
let held;
|
|
408
|
+
try {
|
|
409
|
+
held = new RegExp(pattern);
|
|
410
|
+
}
|
|
411
|
+
catch {
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
draft = {
|
|
415
|
+
text: `${draft.text}.regex(new RegExp(${this.quote(pattern)}))`,
|
|
416
|
+
live: draft.live.regex(held),
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
return draft;
|
|
420
|
+
}
|
|
421
|
+
number(schema) {
|
|
422
|
+
const n = this.name;
|
|
423
|
+
if (!this.only(schema, [
|
|
424
|
+
'type',
|
|
425
|
+
'minimum',
|
|
426
|
+
'maximum',
|
|
427
|
+
'exclusiveMinimum',
|
|
428
|
+
'exclusiveMaximum',
|
|
429
|
+
'multipleOf',
|
|
430
|
+
]))
|
|
431
|
+
return undefined;
|
|
432
|
+
const whole = schema.type === 'integer';
|
|
433
|
+
let draft = whole
|
|
434
|
+
? { text: `${n}.int()`, live: z.int() }
|
|
435
|
+
: { text: `${n}.number()`, live: z.number() };
|
|
436
|
+
const limits = [
|
|
437
|
+
['minimum', 'min', whole ? -SAFE_INTEGER : undefined],
|
|
438
|
+
['maximum', 'max', whole ? SAFE_INTEGER : undefined],
|
|
439
|
+
['exclusiveMinimum', 'gt'],
|
|
440
|
+
['exclusiveMaximum', 'lt'],
|
|
441
|
+
['multipleOf', 'multipleOf'],
|
|
442
|
+
];
|
|
443
|
+
for (const [key, method, given] of limits) {
|
|
444
|
+
const value = schema[key];
|
|
445
|
+
if (value === undefined || value === given)
|
|
446
|
+
continue;
|
|
447
|
+
if (typeof value !== 'number')
|
|
448
|
+
return undefined;
|
|
449
|
+
draft = {
|
|
450
|
+
text: `${draft.text}.${method}(${String(value)})`,
|
|
451
|
+
live: draft.live[method](value),
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
return draft;
|
|
455
|
+
}
|
|
456
|
+
list(schema, depth) {
|
|
457
|
+
if (!this.only(schema, ['type', 'items', 'minItems', 'maxItems']))
|
|
458
|
+
return undefined;
|
|
459
|
+
const items = this.schema(schema.items ?? {}, depth);
|
|
460
|
+
if (!items)
|
|
461
|
+
return undefined;
|
|
462
|
+
let draft = { text: `${this.name}.array(${items.text})`, live: z.array(items.live) };
|
|
463
|
+
const { minItems, maxItems } = schema;
|
|
464
|
+
if (typeof minItems === 'number')
|
|
465
|
+
draft = { text: `${draft.text}.min(${String(minItems)})`, live: draft.live.min(minItems) };
|
|
466
|
+
if (typeof maxItems === 'number')
|
|
467
|
+
draft = { text: `${draft.text}.max(${String(maxItems)})`, live: draft.live.max(maxItems) };
|
|
468
|
+
return draft;
|
|
469
|
+
}
|
|
470
|
+
object(schema, depth) {
|
|
471
|
+
const n = this.name;
|
|
472
|
+
if (!this.only(schema, [
|
|
473
|
+
'type',
|
|
474
|
+
'properties',
|
|
475
|
+
'required',
|
|
476
|
+
'additionalProperties',
|
|
477
|
+
'propertyNames',
|
|
478
|
+
]))
|
|
479
|
+
return undefined;
|
|
480
|
+
const { properties = {}, required = [], additionalProperties: more, propertyNames } = schema;
|
|
481
|
+
if (!isRecord(properties) || !Array.isArray(required))
|
|
482
|
+
return undefined;
|
|
483
|
+
const fields = Object.entries(properties);
|
|
484
|
+
if (isRecord(more) && Object.keys(more).length > 0) {
|
|
485
|
+
// Any key, each with one kind of value.
|
|
486
|
+
const values = fields.length === 0 &&
|
|
487
|
+
canonical(propertyNames ?? { type: 'string' }) === canonical({ type: 'string' })
|
|
488
|
+
? this.schema(more, depth)
|
|
489
|
+
: undefined;
|
|
490
|
+
return (values && {
|
|
491
|
+
text: `${n}.record(${n}.string(), ${values.text})`,
|
|
492
|
+
live: z.record(z.string(), values.live),
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
if (propertyNames !== undefined)
|
|
496
|
+
return undefined;
|
|
497
|
+
const open = more === true || isRecord(more);
|
|
498
|
+
if (!open && more !== undefined && more !== false)
|
|
499
|
+
return undefined;
|
|
500
|
+
// The kernel reads an object a tool returns as closed, so there a plain one says so.
|
|
501
|
+
const kind = open
|
|
502
|
+
? 'looseObject'
|
|
503
|
+
: more === false && this.side === 'input'
|
|
504
|
+
? 'strictObject'
|
|
505
|
+
: 'object';
|
|
506
|
+
const shape = {};
|
|
507
|
+
const lines = [];
|
|
508
|
+
const [pad, close] = this.pads(depth);
|
|
509
|
+
for (const [key, value] of fields) {
|
|
510
|
+
const field = this.field(value, !required.includes(key), depth + 1);
|
|
511
|
+
if (!field)
|
|
512
|
+
return undefined;
|
|
513
|
+
shape[key] = field.live;
|
|
514
|
+
lines.push(`${pad}${keySource(key)}: ${field.text},`);
|
|
515
|
+
}
|
|
516
|
+
const text = lines.length
|
|
517
|
+
? `${n}.${kind}({\n${lines.join('\n')}\n${close}})`
|
|
518
|
+
: `${n}.${kind}({})`;
|
|
519
|
+
return { text, live: z[kind](shape) };
|
|
520
|
+
}
|
|
521
|
+
/** A field of an object: its schema, and whether the object can leave it out. */
|
|
522
|
+
field(schema, optional, depth) {
|
|
523
|
+
const draft = this.schema(schema, depth);
|
|
524
|
+
// A field with a default can be left out as it is.
|
|
525
|
+
if (!draft || !optional || (isRecord(schema) && 'default' in schema))
|
|
526
|
+
return draft;
|
|
527
|
+
return { text: `${draft.text}.optional()`, live: draft.live.optional() };
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/** A schema as the kernel reads it once the studio has run it: Zod's reading of the JSON. */
|
|
531
|
+
function asRun(schema, side) {
|
|
532
|
+
return jsonSchemaFromZod(z.fromJSONSchema(schema), side);
|
|
533
|
+
}
|
|
534
|
+
const STUDIO_STYLE = { unit: ' ', base: '', template: true, quote: quoteSource };
|
|
535
|
+
/**
|
|
536
|
+
* A JSON Schema as Zod, laid out in `style`, with `name` for Zod. `optional` writes a field its
|
|
537
|
+
* object can leave out. Undefined when the studio has no Zod for it, or when the kernel would
|
|
538
|
+
* not read that Zod back as the schema the builder ran: Save then leaves it for code.
|
|
539
|
+
*/
|
|
540
|
+
export function zodSource(schema, optional, side, name, style = STUDIO_STYLE) {
|
|
541
|
+
try {
|
|
542
|
+
const field = new Writer(name, side, style).field(schema, optional, 0);
|
|
543
|
+
if (!field)
|
|
544
|
+
return undefined;
|
|
545
|
+
const read = jsonSchemaFromZod(z.object({ field: field.live }), side);
|
|
546
|
+
const fields = isRecord(read.properties) ? read.properties : {};
|
|
547
|
+
const left = !(Array.isArray(read.required) && read.required.includes('field'));
|
|
548
|
+
if (left !== optional)
|
|
549
|
+
return undefined;
|
|
550
|
+
// The same schema, or the same once Zod has read both: `integer` gains its bounds there.
|
|
551
|
+
const held = canonical(fields.field) === canonical(schema) ||
|
|
552
|
+
canonical(asRun(fields.field, side)) === canonical(asRun(schema, side));
|
|
553
|
+
return held ? field.text : undefined;
|
|
554
|
+
}
|
|
555
|
+
catch {
|
|
556
|
+
return undefined;
|
|
557
|
+
}
|
|
558
|
+
}
|
package/server.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The studio screen's server, for a host that shows the screen: `createStudioDraftHandler`
|
|
3
|
+
* answers every request the screen makes under `/api/studio`.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
export { decisionRequestSchema } from './server/draft-decide.ts';
|
|
8
|
+
export { createStudioDraftHandler, type LentRuntime, type ProbeEntry, STUDIO_BASE, type StudioDraftHandler, type StudioDraftHandlerOptions, type StudioSpend, } from './server/draft-handler.ts';
|
package/server.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The studio screen's server, for a host that shows the screen: `createStudioDraftHandler`
|
|
3
|
+
* answers every request the screen makes under `/api/studio`.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
export { decisionRequestSchema } from "./server/draft-decide.js";
|
|
8
|
+
export { createStudioDraftHandler, STUDIO_BASE, } from "./server/draft-handler.js";
|