@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
package/shared-carry.js
ADDED
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A change to a value the project's files write once, made on every agent or
|
|
3
|
+
* tool that shares it. The files hold one value, so the workspace does too.
|
|
4
|
+
* The same stop names the other code that reads the value, when some does.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import { agentToolInputSchema, compileStudio } from "./compile.js";
|
|
9
|
+
import { draftKey } from "./draft.js";
|
|
10
|
+
import { ON_OWN_KEYS } from "./lent-keys.js";
|
|
11
|
+
import { agentDraft } from "./workspace.js";
|
|
12
|
+
const text = (value) => JSON.stringify(value);
|
|
13
|
+
const same = (a, b) => text(a) === text(b);
|
|
14
|
+
const isRecord = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
15
|
+
/**
|
|
16
|
+
* One agent's profile, when the agent compiles on its own. With the builder's own keys: which
|
|
17
|
+
* models the studio's keys may call is a rule for a run, and does not change a profile's shape.
|
|
18
|
+
*/
|
|
19
|
+
function profileOf(workspace, key) {
|
|
20
|
+
const result = compiledOf(workspace, key);
|
|
21
|
+
return result?.ok ? result.profile : undefined;
|
|
22
|
+
}
|
|
23
|
+
/** A workspace does not change, so each of its agents compiles once. */
|
|
24
|
+
const COMPILED = new WeakMap();
|
|
25
|
+
function compiledOf(workspace, key) {
|
|
26
|
+
const known = COMPILED.get(workspace) ?? new Map();
|
|
27
|
+
COMPILED.set(workspace, known);
|
|
28
|
+
if (known.has(key))
|
|
29
|
+
return known.get(key);
|
|
30
|
+
const draft = agentDraft(workspace, key);
|
|
31
|
+
const idOf = (other) => workspace.agents.find((agent) => agent.key === other)?.identity.agentId.trim();
|
|
32
|
+
const inputOf = (other) => {
|
|
33
|
+
const called = agentDraft(workspace, other);
|
|
34
|
+
return called && agentToolInputSchema(called);
|
|
35
|
+
};
|
|
36
|
+
const result = draft && compileStudio(draft, ON_OWN_KEYS, idOf, inputOf);
|
|
37
|
+
known.set(key, result);
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Each agent of `workspace` as it compiles now. One that does not compile keeps what `before`
|
|
42
|
+
* holds for it, so a change made while it did not is still read once it does.
|
|
43
|
+
*/
|
|
44
|
+
export function sharedSnapshot(workspace, before) {
|
|
45
|
+
const snapshot = new Map();
|
|
46
|
+
for (const draft of workspace.agents) {
|
|
47
|
+
const profile = profileOf(workspace, draft.key);
|
|
48
|
+
const held = profile === undefined ? before?.get(draft.key) : { draft, profile };
|
|
49
|
+
if (held)
|
|
50
|
+
snapshot.set(draft.key, held);
|
|
51
|
+
}
|
|
52
|
+
return snapshot;
|
|
53
|
+
}
|
|
54
|
+
/** Each setting that differs, as the keys that lead to it: a record key by key, a list of one length item by item. */
|
|
55
|
+
function changedPaths(before, after, path = []) {
|
|
56
|
+
if (same(before, after))
|
|
57
|
+
return [];
|
|
58
|
+
if (isRecord(before) && isRecord(after)) {
|
|
59
|
+
return [...new Set([...Object.keys(before), ...Object.keys(after)])].flatMap((key) => changedPaths(before[key], after[key], [...path, key]));
|
|
60
|
+
}
|
|
61
|
+
if (Array.isArray(before) && Array.isArray(after) && before.length === after.length) {
|
|
62
|
+
return before.flatMap((each, index) => changedPaths(each, after[index], [...path, String(index)]));
|
|
63
|
+
}
|
|
64
|
+
return [path];
|
|
65
|
+
}
|
|
66
|
+
function valueAt(value, path) {
|
|
67
|
+
let held = value;
|
|
68
|
+
for (const key of path) {
|
|
69
|
+
held =
|
|
70
|
+
isRecord(held) || Array.isArray(held) ? held[key] : undefined;
|
|
71
|
+
}
|
|
72
|
+
return held;
|
|
73
|
+
}
|
|
74
|
+
const leads = (prefix, path) => prefix.length <= path.length && prefix.every((key, index) => path[index] === key);
|
|
75
|
+
/** The place that writes `path`: the deepest one that leads to it, and the last of those the files reach. */
|
|
76
|
+
function writerOf(sites, path) {
|
|
77
|
+
let found;
|
|
78
|
+
for (const site of sites) {
|
|
79
|
+
if (leads(site.path, path) && (!found || site.path.length >= found.path.length))
|
|
80
|
+
found = site;
|
|
81
|
+
}
|
|
82
|
+
return found;
|
|
83
|
+
}
|
|
84
|
+
/** `onto` with what changed from `before` to `after`: a record field by field, anything else whole. */
|
|
85
|
+
function carried(before, after, onto) {
|
|
86
|
+
if (same(before, after))
|
|
87
|
+
return onto;
|
|
88
|
+
if (!isRecord(before) || !isRecord(after) || !isRecord(onto))
|
|
89
|
+
return after;
|
|
90
|
+
const next = { ...onto };
|
|
91
|
+
for (const key of new Set([...Object.keys(before), ...Object.keys(after)])) {
|
|
92
|
+
const value = carried(before[key], after[key], onto[key]);
|
|
93
|
+
if (value === undefined)
|
|
94
|
+
delete next[key];
|
|
95
|
+
else
|
|
96
|
+
next[key] = value;
|
|
97
|
+
}
|
|
98
|
+
return next;
|
|
99
|
+
}
|
|
100
|
+
const modelOf = (path) => (path[0] === 'models' && path.length > 1 ? path[1] : undefined);
|
|
101
|
+
const bindingOf = (agent, model) => agent?.modelBindings.find((binding) => binding.modelId.trim() === model);
|
|
102
|
+
/** `agent` with what `owed` names changed as the edited agent changed it. A model is matched by its name. */
|
|
103
|
+
function withOwed(agent, owed, was, now) {
|
|
104
|
+
const [model, fromModel] = [modelOf(owed.path), modelOf(owed.fromPath)];
|
|
105
|
+
if (model === undefined || fromModel === undefined) {
|
|
106
|
+
const next = { ...agent };
|
|
107
|
+
for (const field of Object.keys(now)) {
|
|
108
|
+
if (field !== 'key' && field !== 'modelBindings')
|
|
109
|
+
next[field] = carried(was[field], now[field], agent[field]);
|
|
110
|
+
}
|
|
111
|
+
return next;
|
|
112
|
+
}
|
|
113
|
+
const [old, held, mine] = [
|
|
114
|
+
bindingOf(was, fromModel),
|
|
115
|
+
bindingOf(now, fromModel),
|
|
116
|
+
bindingOf(agent, model),
|
|
117
|
+
];
|
|
118
|
+
let modelBindings = agent.modelBindings;
|
|
119
|
+
if (old && held && mine) {
|
|
120
|
+
const next = {
|
|
121
|
+
...carried(old, held, mine),
|
|
122
|
+
key: mine.key,
|
|
123
|
+
modelId: mine.modelId,
|
|
124
|
+
};
|
|
125
|
+
modelBindings = modelBindings.map((binding) => (binding === mine ? next : binding));
|
|
126
|
+
}
|
|
127
|
+
else if (!old && held && !mine) {
|
|
128
|
+
modelBindings = [...modelBindings, { ...held, key: draftKey('model'), modelId: model }];
|
|
129
|
+
}
|
|
130
|
+
else if (old && !held && mine)
|
|
131
|
+
modelBindings = modelBindings.filter((binding) => binding !== mine);
|
|
132
|
+
return modelBindings === agent.modelBindings ? agent : { ...agent, modelBindings };
|
|
133
|
+
}
|
|
134
|
+
/** Each place `other` holds the value `edit` changed and does not hold the change yet. */
|
|
135
|
+
function owedOn(among, other, edit) {
|
|
136
|
+
const sites = among.sitesOf(other.key);
|
|
137
|
+
const held = among.now.get(other.key);
|
|
138
|
+
return (sites
|
|
139
|
+
.filter((place) => place.site === edit.site.site)
|
|
140
|
+
.map((place) => [...place.path, ...edit.rest])
|
|
141
|
+
// What the other sets apart inside the shared value is its own.
|
|
142
|
+
.filter((target) => writerOf(sites, target)?.site === edit.site.site)
|
|
143
|
+
.filter((target) => held === undefined || !same(valueAt(held, target), edit.value))
|
|
144
|
+
.map((path) => ({
|
|
145
|
+
key: other.key,
|
|
146
|
+
path,
|
|
147
|
+
from: edit.from,
|
|
148
|
+
fromPath: edit.fromPath,
|
|
149
|
+
value: edit.value,
|
|
150
|
+
site: edit.site,
|
|
151
|
+
})));
|
|
152
|
+
}
|
|
153
|
+
/** Each change one of them made since it last compiled, with the place in the files that writes it. */
|
|
154
|
+
function editsOf(among, draft) {
|
|
155
|
+
const [before, after] = [among.goodOf(draft.key)?.value, among.now.get(draft.key)];
|
|
156
|
+
if (before === undefined || after === undefined)
|
|
157
|
+
return [];
|
|
158
|
+
const sites = among.sitesOf(draft.key);
|
|
159
|
+
return changedPaths(before, after).map((path) => {
|
|
160
|
+
const site = writerOf(sites, path);
|
|
161
|
+
return { path, ...(site ? { site } : {}), value: valueAt(after, path) };
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* What each change to a shared value is owed on, and each place a change is written that other
|
|
166
|
+
* code reads too, with who made it.
|
|
167
|
+
*/
|
|
168
|
+
function owedAmong(among) {
|
|
169
|
+
const owed = new Map();
|
|
170
|
+
const read = [];
|
|
171
|
+
for (const draft of among.made) {
|
|
172
|
+
for (const { path, site, value } of editsOf(among, draft)) {
|
|
173
|
+
if (site?.readBy)
|
|
174
|
+
read.push({ site, from: draft.key });
|
|
175
|
+
if (!site?.shared)
|
|
176
|
+
continue;
|
|
177
|
+
const edit = {
|
|
178
|
+
site,
|
|
179
|
+
rest: path.slice(site.path.length),
|
|
180
|
+
value,
|
|
181
|
+
from: draft.key,
|
|
182
|
+
fromPath: path,
|
|
183
|
+
};
|
|
184
|
+
for (const mine of among.made.flatMap((other) => owedOn(among, other, edit))) {
|
|
185
|
+
const id = text([mine.key, mine.path]);
|
|
186
|
+
const known = owed.get(id);
|
|
187
|
+
// Two changed one value two ways: neither is carried.
|
|
188
|
+
if (known === undefined)
|
|
189
|
+
owed.set(id, mine);
|
|
190
|
+
else if (known && !same(known.value, value))
|
|
191
|
+
owed.set(id, null);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return { all: [...owed.values()].filter((each) => each !== null), read };
|
|
196
|
+
}
|
|
197
|
+
/** Whether what one compiles to now holds each change it is owed, and nothing else new. */
|
|
198
|
+
function holdsOwed(before, held, mine) {
|
|
199
|
+
return (same(changedPaths(before, held).map(text).sort(), mine.map((each) => text(each.path)).sort()) &&
|
|
200
|
+
mine.every((each) => same(valueAt(held, each.path), each.value)));
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Each change to a shared value made on every one that shares it. A change is carried only when
|
|
204
|
+
* the one it is owed on then compiles to that value there and to nothing else new: otherwise it
|
|
205
|
+
* is left as it is, and Save names it.
|
|
206
|
+
*/
|
|
207
|
+
function carriedAmong(among) {
|
|
208
|
+
const { all, read } = owedAmong(among);
|
|
209
|
+
const kept = new Map();
|
|
210
|
+
const left = new Set();
|
|
211
|
+
const from = all[0]?.from ?? read[0]?.from;
|
|
212
|
+
if (from === undefined)
|
|
213
|
+
return { drafts: [...among.made], kept, left };
|
|
214
|
+
const place = { ...placeOf([...all, ...read].map((each) => each.site)), from };
|
|
215
|
+
const edited = new Map(among.made.map((draft) => [draft.key, draft]));
|
|
216
|
+
const drafts = new Map(edited);
|
|
217
|
+
for (const each of all) {
|
|
218
|
+
const [old, held, draft] = [
|
|
219
|
+
among.goodOf(each.from)?.draft,
|
|
220
|
+
edited.get(each.from),
|
|
221
|
+
drafts.get(each.key),
|
|
222
|
+
];
|
|
223
|
+
// One that does not compile cannot show that it holds the value: it is left.
|
|
224
|
+
const able = old && held && draft && among.now.get(each.key) !== undefined;
|
|
225
|
+
const next = able ? among.withOwed(draft, each, old, held) : undefined;
|
|
226
|
+
if (next)
|
|
227
|
+
drafts.set(each.key, next);
|
|
228
|
+
else
|
|
229
|
+
left.add(each.key);
|
|
230
|
+
}
|
|
231
|
+
const compiled = among.compiledWith(among.made.map((draft) => drafts.get(draft.key) ?? draft));
|
|
232
|
+
for (const key of new Set(all.map((each) => each.key))) {
|
|
233
|
+
const before = among.now.get(key);
|
|
234
|
+
const held = left.has(key) || drafts.get(key) === edited.get(key) ? undefined : compiled(key);
|
|
235
|
+
const mine = all.filter((each) => each.key === key);
|
|
236
|
+
if (before !== undefined && held !== undefined && holdsOwed(before, held, mine))
|
|
237
|
+
kept.set(key, held);
|
|
238
|
+
else
|
|
239
|
+
left.add(key);
|
|
240
|
+
}
|
|
241
|
+
return {
|
|
242
|
+
drafts: among.made.map((draft) => kept.has(draft.key) ? (drafts.get(draft.key) ?? draft) : draft),
|
|
243
|
+
kept,
|
|
244
|
+
left,
|
|
245
|
+
place,
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* `made`, with each change since `good` to a shared value made on every agent that shares it.
|
|
250
|
+
* A change is carried only when the agent then compiles to that value there and to nothing else
|
|
251
|
+
* new: otherwise the agent is left as it is, and Save names it.
|
|
252
|
+
*/
|
|
253
|
+
export function withSharedCarry(good, made, sites) {
|
|
254
|
+
const { drafts, kept, left, place } = carriedAmong({
|
|
255
|
+
made: made.agents,
|
|
256
|
+
goodOf: (key) => {
|
|
257
|
+
const held = good.get(key);
|
|
258
|
+
return held && { draft: held.draft, value: held.profile };
|
|
259
|
+
},
|
|
260
|
+
now: new Map(made.agents.map((agent) => [agent.key, profileOf(made, agent.key)])),
|
|
261
|
+
sitesOf: (key) => sites[made.starts.agents[key]?.identity.agentId.trim() ?? ''] ?? [],
|
|
262
|
+
withOwed,
|
|
263
|
+
compiledWith: (agents) => {
|
|
264
|
+
const next = { ...made, agents: [...agents] };
|
|
265
|
+
return (key) => profileOf(next, key);
|
|
266
|
+
},
|
|
267
|
+
});
|
|
268
|
+
const snapshot = sharedSnapshot(made, good);
|
|
269
|
+
for (const agent of drafts) {
|
|
270
|
+
if (kept.has(agent.key))
|
|
271
|
+
snapshot.set(agent.key, { draft: agent, profile: kept.get(agent.key) });
|
|
272
|
+
}
|
|
273
|
+
const others = (keys) => [...keys].filter((key) => key !== place?.from);
|
|
274
|
+
return {
|
|
275
|
+
workspace: kept.size ? { ...made, agents: drafts } : made,
|
|
276
|
+
snapshot,
|
|
277
|
+
...(place ? { reach: { ...place, agents: others(kept.keys()), left: others(left) } } : {}),
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/** What a reach says of the places a change is written: each one, where the first is, and the code that reads them. */
|
|
281
|
+
function placeOf(sites) {
|
|
282
|
+
const [first] = sites;
|
|
283
|
+
const lines = new Map(sites
|
|
284
|
+
.flatMap((site) => site.readBy ?? [])
|
|
285
|
+
.map((each) => [`${each.file}:${String(each.line)}`, each]));
|
|
286
|
+
return {
|
|
287
|
+
sites: [...new Set(sites.map((site) => site.site))],
|
|
288
|
+
...(first?.name ? { name: first.name } : {}),
|
|
289
|
+
file: first?.file ?? '',
|
|
290
|
+
line: first?.line ?? 0,
|
|
291
|
+
...(sites.some((site) => site.readBy) ? { readBy: [...lines.values()] } : {}),
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/** Each tool an agent that compiles allows, by key, as that agent registers it. */
|
|
295
|
+
function toolsOf(workspace) {
|
|
296
|
+
const byName = new Map();
|
|
297
|
+
for (const agent of workspace.agents) {
|
|
298
|
+
const result = compiledOf(workspace, agent.key);
|
|
299
|
+
if (result?.ok)
|
|
300
|
+
for (const tool of result.customTools)
|
|
301
|
+
byName.set(tool.name, tool);
|
|
302
|
+
}
|
|
303
|
+
const held = new Map();
|
|
304
|
+
for (const tool of workspace.toolSpecs) {
|
|
305
|
+
const registered = byName.get(tool.toolName.trim());
|
|
306
|
+
if (registered !== undefined)
|
|
307
|
+
held.set(tool.key, registered);
|
|
308
|
+
}
|
|
309
|
+
return held;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Each tool of `workspace` as it registers now. One that does not compile keeps what `before`
|
|
313
|
+
* holds for it, so a change made while it did not is still read once it does.
|
|
314
|
+
*/
|
|
315
|
+
export function toolSnapshot(workspace, before) {
|
|
316
|
+
const now = toolsOf(workspace);
|
|
317
|
+
const snapshot = new Map();
|
|
318
|
+
for (const draft of workspace.toolSpecs) {
|
|
319
|
+
const tool = now.get(draft.key);
|
|
320
|
+
const held = tool === undefined ? before?.get(draft.key) : { draft, tool };
|
|
321
|
+
if (held)
|
|
322
|
+
snapshot.set(draft.key, held);
|
|
323
|
+
}
|
|
324
|
+
return snapshot;
|
|
325
|
+
}
|
|
326
|
+
/** A tool's schema as the draft holds it, by the key the tool is registered with. */
|
|
327
|
+
const SCHEMA_FIELDS = {
|
|
328
|
+
inputSchema: 'inputJson',
|
|
329
|
+
outputSchema: 'outputJson',
|
|
330
|
+
};
|
|
331
|
+
/** `value` with `to` at `path`. Nothing at the path takes the key away. */
|
|
332
|
+
function putAt(value, path, to) {
|
|
333
|
+
const [key, ...rest] = path;
|
|
334
|
+
if (key === undefined)
|
|
335
|
+
return to;
|
|
336
|
+
if (Array.isArray(value))
|
|
337
|
+
return value.map((each, index) => (String(index) === key ? putAt(each, rest, to) : each));
|
|
338
|
+
const next = { ...(isRecord(value) ? value : {}) };
|
|
339
|
+
const inner = putAt(next[key], rest, to);
|
|
340
|
+
if (inner === undefined)
|
|
341
|
+
delete next[key];
|
|
342
|
+
else
|
|
343
|
+
next[key] = inner;
|
|
344
|
+
return next;
|
|
345
|
+
}
|
|
346
|
+
/** `tool` with what `owed` names changed as the edited tool changed it. Undefined when its schema does not read. */
|
|
347
|
+
function toolWithOwed(tool, owed, was, now) {
|
|
348
|
+
const [head, ...rest] = owed.path;
|
|
349
|
+
const schema = SCHEMA_FIELDS[head ?? ''];
|
|
350
|
+
if (schema) {
|
|
351
|
+
try {
|
|
352
|
+
return {
|
|
353
|
+
...tool,
|
|
354
|
+
[schema]: JSON.stringify(putAt(JSON.parse(tool[schema]), rest, owed.value), null, 2),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
catch {
|
|
358
|
+
return undefined;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const next = { ...tool };
|
|
362
|
+
for (const field of Object.keys(now)) {
|
|
363
|
+
if (field === 'key' || field === 'toolName' || field === 'inputJson' || field === 'outputJson')
|
|
364
|
+
continue;
|
|
365
|
+
next[field] = carried(was[field], now[field], tool[field]);
|
|
366
|
+
}
|
|
367
|
+
return next;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* `made`, with each change since `good` to a value tools share made on every tool that shares it:
|
|
371
|
+
* a schema several tools take, a list they all name. A change is carried only when the tool then
|
|
372
|
+
* registers with that value there and nothing else new: otherwise the tool is left as it is, and
|
|
373
|
+
* Save names it. A tool no agent allows is not registered here, so it is not read.
|
|
374
|
+
*/
|
|
375
|
+
export function withToolCarry(good, made, sites) {
|
|
376
|
+
const { drafts, kept, left, place } = carriedAmong({
|
|
377
|
+
made: made.toolSpecs,
|
|
378
|
+
goodOf: (key) => {
|
|
379
|
+
const held = good.get(key);
|
|
380
|
+
return held && { draft: held.draft, value: held.tool };
|
|
381
|
+
},
|
|
382
|
+
now: toolsOf(made),
|
|
383
|
+
sitesOf: (key) => sites[made.starts.tools[key]?.toolName ?? ''] ?? [],
|
|
384
|
+
withOwed: toolWithOwed,
|
|
385
|
+
compiledWith: (toolSpecs) => {
|
|
386
|
+
const after = toolsOf({ ...made, toolSpecs: [...toolSpecs] });
|
|
387
|
+
return (key) => after.get(key);
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
const snapshot = toolSnapshot(made, good);
|
|
391
|
+
for (const tool of drafts) {
|
|
392
|
+
if (kept.has(tool.key))
|
|
393
|
+
snapshot.set(tool.key, { draft: tool, tool: kept.get(tool.key) });
|
|
394
|
+
}
|
|
395
|
+
const others = (keys) => [...keys].filter((key) => key !== place?.from);
|
|
396
|
+
const amongTools = { made: others(kept.keys()), left: others(left) };
|
|
397
|
+
return {
|
|
398
|
+
workspace: kept.size ? { ...made, toolSpecs: drafts } : made,
|
|
399
|
+
snapshot,
|
|
400
|
+
...(place ? { reach: { ...place, agents: [], left: [], amongTools } } : {}),
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
/** The most names the question lists before it counts the rest. */
|
|
404
|
+
const NAMED = 4;
|
|
405
|
+
/** `ids` as a sentence names them: the first few, then a count of the rest. */
|
|
406
|
+
function listed(ids) {
|
|
407
|
+
const rest = ids.length - NAMED;
|
|
408
|
+
const shown = rest > 0 ? [...ids.slice(0, NAMED), `${String(rest)} more`] : ids;
|
|
409
|
+
return shown.length > 1
|
|
410
|
+
? `${shown.slice(0, -1).join(', ')}${shown.length > 2 ? ',' : ''} and ${shown.at(-1) ?? ''}`
|
|
411
|
+
: (shown[0] ?? '');
|
|
412
|
+
}
|
|
413
|
+
/** What a change from `before` to `made`, made in the agent `from`, does to tools other agents allow. */
|
|
414
|
+
export function toolReach(before, made, from) {
|
|
415
|
+
const now = new Map(made.toolSpecs.map((tool) => [tool.key, tool]));
|
|
416
|
+
const changed = before.toolSpecs.filter((tool) => !same(now.get(tool.key), tool));
|
|
417
|
+
const keys = new Set(changed.map((tool) => tool.key));
|
|
418
|
+
const agents = before.agents
|
|
419
|
+
.filter((agent) => agent.key !== from && agent.tools.allow.some((key) => keys.has(key)))
|
|
420
|
+
.map((agent) => agent.key);
|
|
421
|
+
if (!agents.length)
|
|
422
|
+
return undefined;
|
|
423
|
+
const used = changed.filter((tool) => before.agents.some((agent) => agent.key !== from && agent.tools.allow.includes(tool.key)));
|
|
424
|
+
return {
|
|
425
|
+
tools: used.map((tool) => tool.key),
|
|
426
|
+
names: used.map((tool) => tool.toolName),
|
|
427
|
+
from,
|
|
428
|
+
agents,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
const placeText = ({ file, line }) => `${file}:${String(line)}`;
|
|
432
|
+
/** A place as the question shows it: the file's name and the line. The folders it is in are for whoever asks. */
|
|
433
|
+
export function shortPlace({ file, line }) {
|
|
434
|
+
const name = file.slice(Math.max(file.lastIndexOf('/'), file.lastIndexOf('\\')) + 1);
|
|
435
|
+
return `${name === file ? '' : '…/'}${name}:${String(line)}`;
|
|
436
|
+
}
|
|
437
|
+
/** The question's line as its text and the places it names, in the order it says them. */
|
|
438
|
+
export function askParts(ask) {
|
|
439
|
+
const parts = [];
|
|
440
|
+
let rest = ask.line;
|
|
441
|
+
for (const place of ask.places) {
|
|
442
|
+
const text = placeText(place);
|
|
443
|
+
const at = rest.indexOf(text);
|
|
444
|
+
// A long list names only its first places.
|
|
445
|
+
if (at < 0)
|
|
446
|
+
continue;
|
|
447
|
+
if (at > 0)
|
|
448
|
+
parts.push(rest.slice(0, at));
|
|
449
|
+
parts.push(place);
|
|
450
|
+
rest = rest.slice(at + text.length);
|
|
451
|
+
}
|
|
452
|
+
if (rest)
|
|
453
|
+
parts.push(rest);
|
|
454
|
+
return parts;
|
|
455
|
+
}
|
|
456
|
+
/** The ids of agents, by key, as the builder knows them. */
|
|
457
|
+
const idsOf = (workspace, keys) => keys
|
|
458
|
+
.map((key) => workspace.agents.find((agent) => agent.key === key)?.identity.agentId.trim())
|
|
459
|
+
.filter((id) => Boolean(id));
|
|
460
|
+
/** The names of tools, by key. */
|
|
461
|
+
const toolNames = (workspace, keys) => keys
|
|
462
|
+
.map((key) => workspace.toolSpecs.find((tool) => tool.key === key)?.toolName.trim())
|
|
463
|
+
.filter((name) => Boolean(name));
|
|
464
|
+
/** The question for a tool of the library that other agents allow too. */
|
|
465
|
+
function libraryAsk(reach, workspace) {
|
|
466
|
+
const [ids, one] = [idsOf(workspace, reach.agents), reach.names.length === 1];
|
|
467
|
+
return {
|
|
468
|
+
title: `Change it for ${String(ids.length)} other ${ids.length === 1 ? 'profile' : 'profiles'}?`,
|
|
469
|
+
line: `${listed(reach.names)} ${one ? 'is one tool' : 'are tools'} in the library. ` +
|
|
470
|
+
`${listed(ids)} ${ids.length === 1 ? 'uses' : 'use'} ${one ? 'it' : 'them'} too, ` +
|
|
471
|
+
`and will change with ${one ? 'it' : 'them'}.`,
|
|
472
|
+
places: [],
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
/** What the builder is asked before a change to a shared value is made: the question, then its cause and effect. */
|
|
476
|
+
export function sharedAsk(reach, workspace) {
|
|
477
|
+
if ('tools' in reach)
|
|
478
|
+
return libraryAsk(reach, workspace);
|
|
479
|
+
const among = reach.amongTools;
|
|
480
|
+
const [ids, left] = among
|
|
481
|
+
? [toolNames(workspace, among.made), toolNames(workspace, among.left)]
|
|
482
|
+
: [idsOf(workspace, reach.agents), idsOf(workspace, reach.left)];
|
|
483
|
+
const [one, many] = among ? ['tool', 'tools'] : ['profile', 'profiles'];
|
|
484
|
+
const places = [{ file: reach.file, line: reach.line }, ...(reach.readBy ?? [])];
|
|
485
|
+
const place = `${reach.name ? `${reach.name} · ` : ''}${reach.file}:${String(reach.line)}`;
|
|
486
|
+
// The other code that reads it, by line when the studio can name one.
|
|
487
|
+
const lines = reach.readBy?.map((each) => `${each.file}:${String(each.line)}`) ?? [];
|
|
488
|
+
const code = reach.readBy
|
|
489
|
+
? ` Other code in your project reads it too${lines.length ? ` (${listed(lines)})` : ''}.`
|
|
490
|
+
: '';
|
|
491
|
+
if (!ids.length && !left.length) {
|
|
492
|
+
if (reach.readBy) {
|
|
493
|
+
return {
|
|
494
|
+
title: 'Change it for your other code too?',
|
|
495
|
+
line: `${place} sets this once.${code} That code runs on the new value once you save.`,
|
|
496
|
+
places,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
title: `Change it everywhere this ${one} uses it?`,
|
|
501
|
+
line: `${place} sets this once, and this ${one} uses it in more than one place. Each of them changes.`,
|
|
502
|
+
places,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
const changes = ids.length
|
|
506
|
+
? ` ${listed(ids)} ${ids.length === 1 ? 'uses' : 'use'} it too, and will change with it.`
|
|
507
|
+
: '';
|
|
508
|
+
// The cause, the effect, and the way out.
|
|
509
|
+
const waits = left.length
|
|
510
|
+
? ` ${listed(left)} ${left.length === 1 ? 'uses' : 'use'} it too, but ${left.length === 1 ? 'has' : 'have'} ` +
|
|
511
|
+
`issues and ${left.length === 1 ? 'stays as it is' : 'stay as they are'}. ` +
|
|
512
|
+
`Fix them, then set this there too: Save writes it once every ${one} agrees.`
|
|
513
|
+
: '';
|
|
514
|
+
// The title says what agreeing does: one that is left as it is does not count.
|
|
515
|
+
const title = ids.length
|
|
516
|
+
? `Change it for ${String(ids.length)} other ${ids.length === 1 ? one : many}?`
|
|
517
|
+
: `Change it for this ${one} only?`;
|
|
518
|
+
return { title, line: `${place} sets this once.${changes}${waits}${code}`, places };
|
|
519
|
+
}
|
|
520
|
+
/** Whether agreeing to a change makes it on others too: other agents, other tools. */
|
|
521
|
+
export function reachesOthers(reach) {
|
|
522
|
+
return (reach.agents.length > 0 || ('amongTools' in reach && (reach.amongTools?.made.length ?? 0) > 0));
|
|
523
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's shared settings as the studio's workspace holds them: which
|
|
3
|
+
* agents share each one, and the section of an agent it fills.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { type ProfileGraphFacetId } from '@theoremjs/agents/schema';
|
|
8
|
+
import type { ProjectOrigins, SharedSetting, Unregistered } from './server/save-wire.ts';
|
|
9
|
+
import { type StudioWorkspace } from './workspace.ts';
|
|
10
|
+
/** One shared setting, beside the agents of the workspace that share it. */
|
|
11
|
+
export interface SharedEntry {
|
|
12
|
+
setting: SharedSetting;
|
|
13
|
+
/** The agents that share it, by key, in the workspace's order. */
|
|
14
|
+
agents: string[];
|
|
15
|
+
/**
|
|
16
|
+
* The section the studio edits it in. Unset when the constant is not the whole of one section in
|
|
17
|
+
* every profile, or a profile that reads it is not open: then it is changed in the builder's editor.
|
|
18
|
+
*/
|
|
19
|
+
facet?: ProfileGraphFacetId;
|
|
20
|
+
/** Where each agent shows the value: the node that holds the field the files set from it, by agent key. */
|
|
21
|
+
places: Record<string, string>;
|
|
22
|
+
/** The tool that shows the value, when no agent does. */
|
|
23
|
+
tool?: string;
|
|
24
|
+
/** The profiles and tools that read it and that the project did not register, so nothing opens them. */
|
|
25
|
+
idle: Unregistered[];
|
|
26
|
+
}
|
|
27
|
+
/** Each shared setting with the agents that share it, as the project opened. */
|
|
28
|
+
export declare function sharedEntries(workspace: StudioWorkspace, settings: readonly SharedSetting[], sites?: ProjectOrigins['sites'], unregistered?: readonly Unregistered[]): SharedEntry[];
|
|
29
|
+
/** The node that opens a shared setting on one of its agents: the field the files set from it. */
|
|
30
|
+
export declare function sharedNodeId(entry: SharedEntry, agentKey: string): string;
|
|
31
|
+
/** The node that opens a shared setting: the first agent that shows it, else the tool that does. */
|
|
32
|
+
export declare function sharedOpens(entry: SharedEntry): string | undefined;
|
|
33
|
+
/** The shared setting the open node edits, when it is one. A shared `models` is edited in each binding. */
|
|
34
|
+
export declare function sharedAt(entries: readonly SharedEntry[], nodeId: string): SharedEntry | undefined;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's shared settings as the studio's workspace holds them: which
|
|
3
|
+
* agents share each one, and the section of an agent it fills.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { PROFILE_GRAPH } from '@theoremjs/agents/schema';
|
|
8
|
+
import { modelBindingNodeId, toolSpecNodeId } from "./tree.js";
|
|
9
|
+
import { agentNodeId, workspaceTree } from "./workspace.js";
|
|
10
|
+
/** The node of `agent` that holds the setting at `path`: its model, its section, else the agent. */
|
|
11
|
+
function nodeAt(agent, path, sections) {
|
|
12
|
+
const [head, name] = path;
|
|
13
|
+
const binding = head === 'models' ? agent.modelBindings.find((each) => each.modelId === name) : undefined;
|
|
14
|
+
if (binding)
|
|
15
|
+
return agentNodeId(agent.key, modelBindingNodeId(binding.key));
|
|
16
|
+
const facet = PROFILE_GRAPH.find((each) => each.role === 'spine' && each.profilePath === head)?.id;
|
|
17
|
+
const section = facet ? agentNodeId(agent.key, facet) : '';
|
|
18
|
+
return sections.has(section) ? section : agentNodeId(agent.key);
|
|
19
|
+
}
|
|
20
|
+
/** The section whose whole value is the profile key `key`. */
|
|
21
|
+
function facetOf(key) {
|
|
22
|
+
return PROFILE_GRAPH.find((facet) => facet.role === 'spine' && facet.profilePath === key)?.id;
|
|
23
|
+
}
|
|
24
|
+
/** Each shared setting with the agents that share it, as the project opened. */
|
|
25
|
+
export function sharedEntries(workspace, settings, sites, unregistered = []) {
|
|
26
|
+
const sections = new Set(workspaceTree(workspace)
|
|
27
|
+
.agents.flatMap((agent) => agent.children ?? [])
|
|
28
|
+
.map((row) => row.id));
|
|
29
|
+
return settings.map((setting) => {
|
|
30
|
+
const users = workspace.agents.filter((agent) => setting.profiles.includes(agent.identity.agentId.trim()));
|
|
31
|
+
const agents = users.map((agent) => agent.key);
|
|
32
|
+
const facet = agents.length === setting.profiles.length ? facetOf(setting.key) : undefined;
|
|
33
|
+
const written = (held, id) => held?.[id]?.find((site) => site.name === setting.name && site.file === setting.file);
|
|
34
|
+
const places = Object.fromEntries(users.flatMap((agent) => {
|
|
35
|
+
const site = written(sites?.profiles, agent.identity.agentId.trim());
|
|
36
|
+
return site ? [[agent.key, nodeAt(agent, site.path, sections)]] : [];
|
|
37
|
+
}));
|
|
38
|
+
const tool = workspace.toolSpecs.find((spec) => written(sites?.tools, spec.toolName));
|
|
39
|
+
const idle = unregistered.filter(({ kind, name }) => (kind === 'profile' ? setting.profiles : setting.tools).includes(name));
|
|
40
|
+
return {
|
|
41
|
+
setting,
|
|
42
|
+
agents,
|
|
43
|
+
places,
|
|
44
|
+
idle,
|
|
45
|
+
...(facet ? { facet } : {}),
|
|
46
|
+
...(tool ? { tool: toolSpecNodeId(tool.key) } : {}),
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** The node that opens a shared setting on one of its agents: the field the files set from it. */
|
|
51
|
+
export function sharedNodeId(entry, agentKey) {
|
|
52
|
+
return entry.places[agentKey] ?? agentNodeId(agentKey, entry.facet ?? 'identity');
|
|
53
|
+
}
|
|
54
|
+
/** The node that opens a shared setting: the first agent that shows it, else the tool that does. */
|
|
55
|
+
export function sharedOpens(entry) {
|
|
56
|
+
const shown = entry.agents.find((key) => entry.places[key] !== undefined) ??
|
|
57
|
+
(entry.facet ? entry.agents[0] : undefined);
|
|
58
|
+
return shown ? sharedNodeId(entry, shown) : entry.tool;
|
|
59
|
+
}
|
|
60
|
+
/** The shared setting the open node edits, when it is one. A shared `models` is edited in each binding. */
|
|
61
|
+
export function sharedAt(entries, nodeId) {
|
|
62
|
+
return entries.find(({ facet, agents }) => facet !== undefined &&
|
|
63
|
+
agents.some((key) => {
|
|
64
|
+
const root = `${agentNodeId(key)}/`;
|
|
65
|
+
if (!nodeId.startsWith(root))
|
|
66
|
+
return false;
|
|
67
|
+
const inner = nodeId.slice(root.length);
|
|
68
|
+
return inner === facet || (facet === 'models' && inner.startsWith(modelBindingNodeId('')));
|
|
69
|
+
}));
|
|
70
|
+
}
|