@12ui/design 0.2.72 → 0.2.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +242 -54
- package/SKILL.md +28 -33
- package/dist/cli-arguments.d.ts.map +1 -1
- package/dist/cli-arguments.js +3 -0
- package/dist/cli-arguments.js.map +1 -1
- package/dist/cli-branch-command.d.ts.map +1 -1
- package/dist/cli-branch-command.js +4 -0
- package/dist/cli-branch-command.js.map +1 -1
- package/dist/cli-capabilities.d.ts +26 -1
- package/dist/cli-capabilities.d.ts.map +1 -1
- package/dist/cli-capabilities.js +26 -1
- package/dist/cli-capabilities.js.map +1 -1
- package/dist/cli-corpus-command.d.ts +5 -4
- package/dist/cli-corpus-command.d.ts.map +1 -1
- package/dist/cli-corpus-command.js +17 -26
- package/dist/cli-corpus-command.js.map +1 -1
- package/dist/cli-corpus-run.js +1 -1
- package/dist/cli-corpus-run.js.map +1 -1
- package/dist/cli-draft-command.js +1 -1
- package/dist/cli-draft-command.js.map +1 -1
- package/dist/cli-help/design.d.ts +26 -6
- package/dist/cli-help/design.d.ts.map +1 -1
- package/dist/cli-help/design.js +39 -7
- package/dist/cli-help/design.js.map +1 -1
- package/dist/cli-help/index.d.ts +113 -7
- package/dist/cli-help/index.d.ts.map +1 -1
- package/dist/cli-help/index.js +2 -0
- package/dist/cli-help/index.js.map +1 -1
- package/dist/cli-help/meta.d.ts +1 -1
- package/dist/cli-help/meta.d.ts.map +1 -1
- package/dist/cli-help/meta.js +2 -1
- package/dist/cli-help/meta.js.map +1 -1
- package/dist/cli-help/workflow.d.ts +90 -0
- package/dist/cli-help/workflow.d.ts.map +1 -0
- package/dist/cli-help/workflow.js +89 -0
- package/dist/cli-help/workflow.js.map +1 -0
- package/dist/cli-open-browser.d.ts +7 -0
- package/dist/cli-open-browser.d.ts.map +1 -0
- package/dist/cli-open-browser.js +25 -0
- package/dist/cli-open-browser.js.map +1 -0
- package/dist/cli-prototype-command.d.ts +3 -1
- package/dist/cli-prototype-command.d.ts.map +1 -1
- package/dist/cli-prototype-command.js +33 -7
- package/dist/cli-prototype-command.js.map +1 -1
- package/dist/cli-review-command.d.ts.map +1 -1
- package/dist/cli-review-command.js +1 -16
- package/dist/cli-review-command.js.map +1 -1
- package/dist/cli-run.d.ts.map +1 -1
- package/dist/cli-run.js +35 -3
- package/dist/cli-run.js.map +1 -1
- package/dist/cli-usage.d.ts.map +1 -1
- package/dist/cli-usage.js +39 -5
- package/dist/cli-usage.js.map +1 -1
- package/dist/cli-workflow-command.d.ts +8 -0
- package/dist/cli-workflow-command.d.ts.map +1 -0
- package/dist/cli-workflow-command.js +97 -0
- package/dist/cli-workflow-command.js.map +1 -0
- package/dist/cli-workspace-command.d.ts +25 -0
- package/dist/cli-workspace-command.d.ts.map +1 -0
- package/dist/cli-workspace-command.js +95 -0
- package/dist/cli-workspace-command.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -4
- package/dist/config.js.map +1 -1
- package/dist/corpus-access.d.ts +11 -0
- package/dist/corpus-access.d.ts.map +1 -0
- package/dist/corpus-access.js +18 -0
- package/dist/corpus-access.js.map +1 -0
- package/dist/corpus-client.d.ts +11 -11
- package/dist/corpus-client.d.ts.map +1 -1
- package/dist/corpus-client.js +17 -6
- package/dist/corpus-client.js.map +1 -1
- package/dist/corpus-inspiration-failure.d.ts +1 -1
- package/dist/corpus-inspiration-failure.js +2 -2
- package/dist/corpus-inspiration-failure.js.map +1 -1
- package/dist/corpus-reference-download-retry.d.ts.map +1 -1
- package/dist/corpus-reference-download-retry.js +11 -1
- package/dist/corpus-reference-download-retry.js.map +1 -1
- package/dist/corpus-request-error.d.ts +2 -0
- package/dist/corpus-request-error.d.ts.map +1 -1
- package/dist/corpus-request-error.js +2 -0
- package/dist/corpus-request-error.js.map +1 -1
- package/dist/corpus-retry-guidance.d.ts +5 -0
- package/dist/corpus-retry-guidance.d.ts.map +1 -0
- package/dist/corpus-retry-guidance.js +18 -0
- package/dist/corpus-retry-guidance.js.map +1 -0
- package/dist/improve-pricing-plan.d.ts.map +1 -1
- package/dist/improve-pricing-plan.js +2 -4
- package/dist/improve-pricing-plan.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy-skill-catalog.d.ts.map +1 -1
- package/dist/legacy-skill-catalog.js +41 -0
- package/dist/legacy-skill-catalog.js.map +1 -1
- package/dist/mcp-slate-command.d.ts +31 -0
- package/dist/mcp-slate-command.d.ts.map +1 -0
- package/dist/mcp-slate-command.js +123 -0
- package/dist/mcp-slate-command.js.map +1 -0
- package/dist/mcp-slate-image.d.ts +22 -0
- package/dist/mcp-slate-image.d.ts.map +1 -0
- package/dist/mcp-slate-image.js +28 -0
- package/dist/mcp-slate-image.js.map +1 -0
- package/dist/mcp-slate-latest.d.ts +13 -0
- package/dist/mcp-slate-latest.d.ts.map +1 -0
- package/dist/mcp-slate-latest.js +34 -0
- package/dist/mcp-slate-latest.js.map +1 -0
- package/dist/mcp-slate-names.d.ts +25 -0
- package/dist/mcp-slate-names.d.ts.map +1 -0
- package/dist/mcp-slate-names.js +49 -0
- package/dist/mcp-slate-names.js.map +1 -0
- package/dist/mcp-slate-resource.d.ts +5 -0
- package/dist/mcp-slate-resource.d.ts.map +1 -0
- package/dist/mcp-slate-resource.js +37 -0
- package/dist/mcp-slate-resource.js.map +1 -0
- package/dist/mcp-slate-run.d.ts +41 -0
- package/dist/mcp-slate-run.d.ts.map +1 -0
- package/dist/mcp-slate-run.js +88 -0
- package/dist/mcp-slate-run.js.map +1 -0
- package/dist/mcp-slate-tool-defs.d.ts +61 -0
- package/dist/mcp-slate-tool-defs.d.ts.map +1 -0
- package/dist/mcp-slate-tool-defs.js +247 -0
- package/dist/mcp-slate-tool-defs.js.map +1 -0
- package/dist/mcp-slate-tools.d.ts +8 -0
- package/dist/mcp-slate-tools.d.ts.map +1 -0
- package/dist/mcp-slate-tools.js +45 -0
- package/dist/mcp-slate-tools.js.map +1 -0
- package/dist/mcp-slate-ui-copy.d.ts +145 -0
- package/dist/mcp-slate-ui-copy.d.ts.map +1 -0
- package/dist/mcp-slate-ui-copy.js +164 -0
- package/dist/mcp-slate-ui-copy.js.map +1 -0
- package/dist/mcp-slate-ui-script-bridge.d.ts +18 -0
- package/dist/mcp-slate-ui-script-bridge.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-bridge.js +137 -0
- package/dist/mcp-slate-ui-script-bridge.js.map +1 -0
- package/dist/mcp-slate-ui-script-browser.d.ts +12 -0
- package/dist/mcp-slate-ui-script-browser.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-browser.js +19 -0
- package/dist/mcp-slate-ui-script-browser.js.map +1 -0
- package/dist/mcp-slate-ui-script-dialog.d.ts +21 -0
- package/dist/mcp-slate-ui-script-dialog.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-dialog.js +321 -0
- package/dist/mcp-slate-ui-script-dialog.js.map +1 -0
- package/dist/mcp-slate-ui-script-inline.d.ts +10 -0
- package/dist/mcp-slate-ui-script-inline.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-inline.js +224 -0
- package/dist/mcp-slate-ui-script-inline.js.map +1 -0
- package/dist/mcp-slate-ui-script-inspiration.d.ts +13 -0
- package/dist/mcp-slate-ui-script-inspiration.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-inspiration.js +236 -0
- package/dist/mcp-slate-ui-script-inspiration.js.map +1 -0
- package/dist/mcp-slate-ui-script-more.d.ts +32 -0
- package/dist/mcp-slate-ui-script-more.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-more.js +289 -0
- package/dist/mcp-slate-ui-script-more.js.map +1 -0
- package/dist/mcp-slate-ui-script-progress.d.ts +7 -0
- package/dist/mcp-slate-ui-script-progress.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-progress.js +9 -0
- package/dist/mcp-slate-ui-script-progress.js.map +1 -0
- package/dist/mcp-slate-ui-script-remote.d.ts +28 -0
- package/dist/mcp-slate-ui-script-remote.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-remote.js +147 -0
- package/dist/mcp-slate-ui-script-remote.js.map +1 -0
- package/dist/mcp-slate-ui-script-scribble.d.ts +19 -0
- package/dist/mcp-slate-ui-script-scribble.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-scribble.js +114 -0
- package/dist/mcp-slate-ui-script-scribble.js.map +1 -0
- package/dist/mcp-slate-ui-script-select.d.ts +16 -0
- package/dist/mcp-slate-ui-script-select.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-select.js +73 -0
- package/dist/mcp-slate-ui-script-select.js.map +1 -0
- package/dist/mcp-slate-ui-script-stage.d.ts +12 -0
- package/dist/mcp-slate-ui-script-stage.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-stage.js +180 -0
- package/dist/mcp-slate-ui-script-stage.js.map +1 -0
- package/dist/mcp-slate-ui-script-state.d.ts +13 -0
- package/dist/mcp-slate-ui-script-state.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script-state.js +306 -0
- package/dist/mcp-slate-ui-script-state.js.map +1 -0
- package/dist/mcp-slate-ui-script.d.ts +27 -0
- package/dist/mcp-slate-ui-script.d.ts.map +1 -0
- package/dist/mcp-slate-ui-script.js +60 -0
- package/dist/mcp-slate-ui-script.js.map +1 -0
- package/dist/mcp-slate-ui-styles-dialog.d.ts +20 -0
- package/dist/mcp-slate-ui-styles-dialog.d.ts.map +1 -0
- package/dist/mcp-slate-ui-styles-dialog.js +95 -0
- package/dist/mcp-slate-ui-styles-dialog.js.map +1 -0
- package/dist/mcp-slate-ui-styles-stage.d.ts +19 -0
- package/dist/mcp-slate-ui-styles-stage.d.ts.map +1 -0
- package/dist/mcp-slate-ui-styles-stage.js +67 -0
- package/dist/mcp-slate-ui-styles-stage.js.map +1 -0
- package/dist/mcp-slate-ui-styles.d.ts +18 -0
- package/dist/mcp-slate-ui-styles.d.ts.map +1 -0
- package/dist/mcp-slate-ui-styles.js +132 -0
- package/dist/mcp-slate-ui-styles.js.map +1 -0
- package/dist/mcp-slate-ui.d.ts +16 -0
- package/dist/mcp-slate-ui.d.ts.map +1 -0
- package/dist/mcp-slate-ui.js +59 -0
- package/dist/mcp-slate-ui.js.map +1 -0
- package/dist/mcp-slate-workspace-tools.d.ts +15 -0
- package/dist/mcp-slate-workspace-tools.d.ts.map +1 -0
- package/dist/mcp-slate-workspace-tools.js +155 -0
- package/dist/mcp-slate-workspace-tools.js.map +1 -0
- package/dist/mcp-tool-definitions.d.ts.map +1 -1
- package/dist/mcp-tool-definitions.js +9 -7
- package/dist/mcp-tool-definitions.js.map +1 -1
- package/dist/mcp-tool-handler.d.ts +8 -2
- package/dist/mcp-tool-handler.d.ts.map +1 -1
- package/dist/mcp-tool-handler.js +34 -13
- package/dist/mcp-tool-handler.js.map +1 -1
- package/dist/mcp-workflow-tools.d.ts +6 -0
- package/dist/mcp-workflow-tools.d.ts.map +1 -0
- package/dist/mcp-workflow-tools.js +108 -0
- package/dist/mcp-workflow-tools.js.map +1 -0
- package/dist/prototype-label-client.d.ts +5 -0
- package/dist/prototype-label-client.d.ts.map +1 -1
- package/dist/prototype-label-client.js.map +1 -1
- package/dist/prototype-poststep.d.ts +2 -2
- package/dist/prototype-poststep.d.ts.map +1 -1
- package/dist/prototype-poststep.js +3 -0
- package/dist/prototype-poststep.js.map +1 -1
- package/dist/prototype-run-record.d.ts +6 -2
- package/dist/prototype-run-record.d.ts.map +1 -1
- package/dist/prototype-run-record.js +6 -0
- package/dist/prototype-run-record.js.map +1 -1
- package/dist/prototype-runner.d.ts +2 -2
- package/dist/prototype-runner.d.ts.map +1 -1
- package/dist/prototype-runner.js +5 -2
- package/dist/prototype-runner.js.map +1 -1
- package/dist/prototype-workflow-contract.d.ts +13 -0
- package/dist/prototype-workflow-contract.d.ts.map +1 -0
- package/dist/prototype-workflow-contract.js +82 -0
- package/dist/prototype-workflow-contract.js.map +1 -0
- package/dist/prototype-workflow-labels.d.ts +29 -0
- package/dist/prototype-workflow-labels.d.ts.map +1 -0
- package/dist/prototype-workflow-labels.js +93 -0
- package/dist/prototype-workflow-labels.js.map +1 -0
- package/dist/run-journal-commands.d.ts.map +1 -1
- package/dist/run-journal-commands.js +18 -5
- package/dist/run-journal-commands.js.map +1 -1
- package/dist/server.d.ts +22 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +44 -8
- package/dist/server.js.map +1 -1
- package/dist/slate-actions.d.ts +43 -0
- package/dist/slate-actions.d.ts.map +1 -0
- package/dist/slate-actions.js +108 -0
- package/dist/slate-actions.js.map +1 -0
- package/dist/slate-annotate.d.ts +36 -0
- package/dist/slate-annotate.d.ts.map +1 -0
- package/dist/slate-annotate.js +71 -0
- package/dist/slate-annotate.js.map +1 -0
- package/dist/slate-approvals.d.ts +61 -0
- package/dist/slate-approvals.d.ts.map +1 -0
- package/dist/slate-approvals.js +153 -0
- package/dist/slate-approvals.js.map +1 -0
- package/dist/slate-browser-decision.d.ts +30 -0
- package/dist/slate-browser-decision.d.ts.map +1 -0
- package/dist/slate-browser-decision.js +24 -0
- package/dist/slate-browser-decision.js.map +1 -0
- package/dist/slate-browser-host-script.d.ts +14 -0
- package/dist/slate-browser-host-script.d.ts.map +1 -0
- package/dist/slate-browser-host-script.js +125 -0
- package/dist/slate-browser-host-script.js.map +1 -0
- package/dist/slate-browser-host.d.ts +9 -0
- package/dist/slate-browser-host.d.ts.map +1 -0
- package/dist/slate-browser-host.js +37 -0
- package/dist/slate-browser-host.js.map +1 -0
- package/dist/slate-browser-server.d.ts +37 -0
- package/dist/slate-browser-server.d.ts.map +1 -0
- package/dist/slate-browser-server.js +186 -0
- package/dist/slate-browser-server.js.map +1 -0
- package/dist/slate-commit.d.ts +28 -0
- package/dist/slate-commit.d.ts.map +1 -0
- package/dist/slate-commit.js +218 -0
- package/dist/slate-commit.js.map +1 -0
- package/dist/slate-corpus.d.ts +14 -0
- package/dist/slate-corpus.d.ts.map +1 -0
- package/dist/slate-corpus.js +32 -0
- package/dist/slate-corpus.js.map +1 -0
- package/dist/slate-edit-prompt.d.ts +18 -0
- package/dist/slate-edit-prompt.d.ts.map +1 -0
- package/dist/slate-edit-prompt.js +41 -0
- package/dist/slate-edit-prompt.js.map +1 -0
- package/dist/slate-edit-runner.d.ts +4 -0
- package/dist/slate-edit-runner.d.ts.map +1 -0
- package/dist/slate-edit-runner.js +90 -0
- package/dist/slate-edit-runner.js.map +1 -0
- package/dist/slate-editability.d.ts +20 -0
- package/dist/slate-editability.d.ts.map +1 -0
- package/dist/slate-editability.js +19 -0
- package/dist/slate-editability.js.map +1 -0
- package/dist/slate-errors.d.ts +15 -0
- package/dist/slate-errors.d.ts.map +1 -0
- package/dist/slate-errors.js +21 -0
- package/dist/slate-errors.js.map +1 -0
- package/dist/slate-handoff-options.d.ts +40 -0
- package/dist/slate-handoff-options.d.ts.map +1 -0
- package/dist/slate-handoff-options.js +117 -0
- package/dist/slate-handoff-options.js.map +1 -0
- package/dist/slate-handoff.d.ts +11 -0
- package/dist/slate-handoff.d.ts.map +1 -0
- package/dist/slate-handoff.js +56 -0
- package/dist/slate-handoff.js.map +1 -0
- package/dist/slate-ids.d.ts +33 -0
- package/dist/slate-ids.d.ts.map +1 -0
- package/dist/slate-ids.js +47 -0
- package/dist/slate-ids.js.map +1 -0
- package/dist/slate-image-executor.d.ts +39 -0
- package/dist/slate-image-executor.d.ts.map +1 -0
- package/dist/slate-image-executor.js +52 -0
- package/dist/slate-image-executor.js.map +1 -0
- package/dist/slate-inspiration.d.ts +22 -0
- package/dist/slate-inspiration.d.ts.map +1 -0
- package/dist/slate-inspiration.js +112 -0
- package/dist/slate-inspiration.js.map +1 -0
- package/dist/slate-labels.d.ts +11 -0
- package/dist/slate-labels.d.ts.map +1 -0
- package/dist/slate-labels.js +32 -0
- package/dist/slate-labels.js.map +1 -0
- package/dist/slate-ledger.d.ts +29 -0
- package/dist/slate-ledger.d.ts.map +1 -0
- package/dist/slate-ledger.js +65 -0
- package/dist/slate-ledger.js.map +1 -0
- package/dist/slate-liveness.d.ts +26 -0
- package/dist/slate-liveness.d.ts.map +1 -0
- package/dist/slate-liveness.js +49 -0
- package/dist/slate-liveness.js.map +1 -0
- package/dist/slate-local-image.d.ts +19 -0
- package/dist/slate-local-image.d.ts.map +1 -0
- package/dist/slate-local-image.js +36 -0
- package/dist/slate-local-image.js.map +1 -0
- package/dist/slate-lock.d.ts +64 -0
- package/dist/slate-lock.d.ts.map +1 -0
- package/dist/slate-lock.js +178 -0
- package/dist/slate-lock.js.map +1 -0
- package/dist/slate-paths.d.ts +45 -0
- package/dist/slate-paths.d.ts.map +1 -0
- package/dist/slate-paths.js +132 -0
- package/dist/slate-paths.js.map +1 -0
- package/dist/slate-pick.d.ts +29 -0
- package/dist/slate-pick.d.ts.map +1 -0
- package/dist/slate-pick.js +55 -0
- package/dist/slate-pick.js.map +1 -0
- package/dist/slate-reference-ids.d.ts +6 -0
- package/dist/slate-reference-ids.d.ts.map +1 -0
- package/dist/slate-reference-ids.js +17 -0
- package/dist/slate-reference-ids.js.map +1 -0
- package/dist/slate-reference-store.d.ts +23 -0
- package/dist/slate-reference-store.d.ts.map +1 -0
- package/dist/slate-reference-store.js +46 -0
- package/dist/slate-reference-store.js.map +1 -0
- package/dist/slate-resume.d.ts +19 -0
- package/dist/slate-resume.d.ts.map +1 -0
- package/dist/slate-resume.js +94 -0
- package/dist/slate-resume.js.map +1 -0
- package/dist/slate-round-params.d.ts +20 -0
- package/dist/slate-round-params.d.ts.map +1 -0
- package/dist/slate-round-params.js +32 -0
- package/dist/slate-round-params.js.map +1 -0
- package/dist/slate-round-prompt.d.ts +18 -0
- package/dist/slate-round-prompt.d.ts.map +1 -0
- package/dist/slate-round-prompt.js +20 -0
- package/dist/slate-round-prompt.js.map +1 -0
- package/dist/slate-round-runner.d.ts +4 -0
- package/dist/slate-round-runner.d.ts.map +1 -0
- package/dist/slate-round-runner.js +125 -0
- package/dist/slate-round-runner.js.map +1 -0
- package/dist/slate-round-search.d.ts +7 -0
- package/dist/slate-round-search.d.ts.map +1 -0
- package/dist/slate-round-search.js +77 -0
- package/dist/slate-round-search.js.map +1 -0
- package/dist/slate-run-action.d.ts +14 -0
- package/dist/slate-run-action.d.ts.map +1 -0
- package/dist/slate-run-action.js +81 -0
- package/dist/slate-run-action.js.map +1 -0
- package/dist/slate-runner-context.d.ts +57 -0
- package/dist/slate-runner-context.d.ts.map +1 -0
- package/dist/slate-runner-context.js +79 -0
- package/dist/slate-runner-context.js.map +1 -0
- package/dist/slate-runner-failure.d.ts +8 -0
- package/dist/slate-runner-failure.d.ts.map +1 -0
- package/dist/slate-runner-failure.js +17 -0
- package/dist/slate-runner-failure.js.map +1 -0
- package/dist/slate-runner-flag.d.ts +3 -0
- package/dist/slate-runner-flag.d.ts.map +1 -0
- package/dist/slate-runner-flag.js +3 -0
- package/dist/slate-runner-flag.js.map +1 -0
- package/dist/slate-runner-main.d.ts +31 -0
- package/dist/slate-runner-main.d.ts.map +1 -0
- package/dist/slate-runner-main.js +132 -0
- package/dist/slate-runner-main.js.map +1 -0
- package/dist/slate-runner-spawn.d.ts +23 -0
- package/dist/slate-runner-spawn.d.ts.map +1 -0
- package/dist/slate-runner-spawn.js +27 -0
- package/dist/slate-runner-spawn.js.map +1 -0
- package/dist/slate-runtime.d.ts +38 -0
- package/dist/slate-runtime.d.ts.map +1 -0
- package/dist/slate-runtime.js +48 -0
- package/dist/slate-runtime.js.map +1 -0
- package/dist/slate-versions.d.ts +26 -0
- package/dist/slate-versions.d.ts.map +1 -0
- package/dist/slate-versions.js +110 -0
- package/dist/slate-versions.js.map +1 -0
- package/dist/slate-view-contract.d.ts +232 -0
- package/dist/slate-view-contract.d.ts.map +1 -0
- package/dist/slate-view-contract.js +17 -0
- package/dist/slate-view-contract.js.map +1 -0
- package/dist/slate-view-types.d.ts +2 -0
- package/dist/slate-view-types.d.ts.map +1 -0
- package/dist/slate-view-types.js +2 -0
- package/dist/slate-view-types.js.map +1 -0
- package/dist/slate-view.d.ts +19 -0
- package/dist/slate-view.d.ts.map +1 -0
- package/dist/slate-view.js +184 -0
- package/dist/slate-view.js.map +1 -0
- package/dist/slate-workspace-parse.d.ts +20 -0
- package/dist/slate-workspace-parse.d.ts.map +1 -0
- package/dist/slate-workspace-parse.js +442 -0
- package/dist/slate-workspace-parse.js.map +1 -0
- package/dist/slate-workspace-store.d.ts +44 -0
- package/dist/slate-workspace-store.d.ts.map +1 -0
- package/dist/slate-workspace-store.js +270 -0
- package/dist/slate-workspace-store.js.map +1 -0
- package/dist/slate-workspace-types.d.ts +176 -0
- package/dist/slate-workspace-types.d.ts.map +1 -0
- package/dist/slate-workspace-types.js +13 -0
- package/dist/slate-workspace-types.js.map +1 -0
- package/dist/workflow/adapter-12ui.d.ts +4 -0
- package/dist/workflow/adapter-12ui.d.ts.map +1 -0
- package/dist/workflow/adapter-12ui.js +147 -0
- package/dist/workflow/adapter-12ui.js.map +1 -0
- package/dist/workflow/adapter-layerdoc.d.ts +16 -0
- package/dist/workflow/adapter-layerdoc.d.ts.map +1 -0
- package/dist/workflow/adapter-layerdoc.js +116 -0
- package/dist/workflow/adapter-layerdoc.js.map +1 -0
- package/dist/workflow/adapter-openai.d.ts +4 -0
- package/dist/workflow/adapter-openai.d.ts.map +1 -0
- package/dist/workflow/adapter-openai.js +166 -0
- package/dist/workflow/adapter-openai.js.map +1 -0
- package/dist/workflow/adapter-process.d.ts +7 -0
- package/dist/workflow/adapter-process.d.ts.map +1 -0
- package/dist/workflow/adapter-process.js +174 -0
- package/dist/workflow/adapter-process.js.map +1 -0
- package/dist/workflow/adapter-prototype-labels.d.ts +15 -0
- package/dist/workflow/adapter-prototype-labels.d.ts.map +1 -0
- package/dist/workflow/adapter-prototype-labels.js +71 -0
- package/dist/workflow/adapter-prototype-labels.js.map +1 -0
- package/dist/workflow/adapter-types.d.ts +40 -0
- package/dist/workflow/adapter-types.d.ts.map +1 -0
- package/dist/workflow/adapter-types.js +2 -0
- package/dist/workflow/adapter-types.js.map +1 -0
- package/dist/workflow/adapter-utils.d.ts +11 -0
- package/dist/workflow/adapter-utils.d.ts.map +1 -0
- package/dist/workflow/adapter-utils.js +72 -0
- package/dist/workflow/adapter-utils.js.map +1 -0
- package/dist/workflow/adapters.d.ts +6 -0
- package/dist/workflow/adapters.d.ts.map +1 -0
- package/dist/workflow/adapters.js +25 -0
- package/dist/workflow/adapters.js.map +1 -0
- package/dist/workflow/artifact.d.ts +11 -0
- package/dist/workflow/artifact.d.ts.map +1 -0
- package/dist/workflow/artifact.js +94 -0
- package/dist/workflow/artifact.js.map +1 -0
- package/dist/workflow/bundle-collect.d.ts +8 -0
- package/dist/workflow/bundle-collect.d.ts.map +1 -0
- package/dist/workflow/bundle-collect.js +56 -0
- package/dist/workflow/bundle-collect.js.map +1 -0
- package/dist/workflow/bundle-export.d.ts +16 -0
- package/dist/workflow/bundle-export.d.ts.map +1 -0
- package/dist/workflow/bundle-export.js +174 -0
- package/dist/workflow/bundle-export.js.map +1 -0
- package/dist/workflow/bundle-paths.d.ts +7 -0
- package/dist/workflow/bundle-paths.d.ts.map +1 -0
- package/dist/workflow/bundle-paths.js +35 -0
- package/dist/workflow/bundle-paths.js.map +1 -0
- package/dist/workflow/bundle.d.ts +4 -0
- package/dist/workflow/bundle.d.ts.map +1 -0
- package/dist/workflow/bundle.js +4 -0
- package/dist/workflow/bundle.js.map +1 -0
- package/dist/workflow/capture.d.ts +36 -0
- package/dist/workflow/capture.d.ts.map +1 -0
- package/dist/workflow/capture.js +81 -0
- package/dist/workflow/capture.js.map +1 -0
- package/dist/workflow/continuation-branch.d.ts +15 -0
- package/dist/workflow/continuation-branch.d.ts.map +1 -0
- package/dist/workflow/continuation-branch.js +103 -0
- package/dist/workflow/continuation-branch.js.map +1 -0
- package/dist/workflow/continuation-plans.d.ts +38 -0
- package/dist/workflow/continuation-plans.d.ts.map +1 -0
- package/dist/workflow/continuation-plans.js +78 -0
- package/dist/workflow/continuation-plans.js.map +1 -0
- package/dist/workflow/continuation.d.ts +25 -0
- package/dist/workflow/continuation.d.ts.map +1 -0
- package/dist/workflow/continuation.js +89 -0
- package/dist/workflow/continuation.js.map +1 -0
- package/dist/workflow/layerdoc-reader.d.ts +27 -0
- package/dist/workflow/layerdoc-reader.d.ts.map +1 -0
- package/dist/workflow/layerdoc-reader.js +81 -0
- package/dist/workflow/layerdoc-reader.js.map +1 -0
- package/dist/workflow/project-evidence.d.ts +48 -0
- package/dist/workflow/project-evidence.d.ts.map +1 -0
- package/dist/workflow/project-evidence.js +200 -0
- package/dist/workflow/project-evidence.js.map +1 -0
- package/dist/workflow/providers.d.ts +35 -0
- package/dist/workflow/providers.d.ts.map +1 -0
- package/dist/workflow/providers.js +110 -0
- package/dist/workflow/providers.js.map +1 -0
- package/dist/workflow/recipes-layerdoc-validation.d.ts +4 -0
- package/dist/workflow/recipes-layerdoc-validation.d.ts.map +1 -0
- package/dist/workflow/recipes-layerdoc-validation.js +98 -0
- package/dist/workflow/recipes-layerdoc-validation.js.map +1 -0
- package/dist/workflow/recipes-result-validation.d.ts +6 -0
- package/dist/workflow/recipes-result-validation.d.ts.map +1 -0
- package/dist/workflow/recipes-result-validation.js +38 -0
- package/dist/workflow/recipes-result-validation.js.map +1 -0
- package/dist/workflow/recipes-schemas.d.ts +7 -0
- package/dist/workflow/recipes-schemas.d.ts.map +1 -0
- package/dist/workflow/recipes-schemas.js +67 -0
- package/dist/workflow/recipes-schemas.js.map +1 -0
- package/dist/workflow/recipes-validation.d.ts +14 -0
- package/dist/workflow/recipes-validation.d.ts.map +1 -0
- package/dist/workflow/recipes-validation.js +68 -0
- package/dist/workflow/recipes-validation.js.map +1 -0
- package/dist/workflow/recipes.d.ts +20 -0
- package/dist/workflow/recipes.d.ts.map +1 -0
- package/dist/workflow/recipes.js +167 -0
- package/dist/workflow/recipes.js.map +1 -0
- package/dist/workflow/routing.d.ts +4 -0
- package/dist/workflow/routing.d.ts.map +1 -0
- package/dist/workflow/routing.js +28 -0
- package/dist/workflow/routing.js.map +1 -0
- package/dist/workflow/schema.d.ts +5 -0
- package/dist/workflow/schema.d.ts.map +1 -0
- package/dist/workflow/schema.js +29 -0
- package/dist/workflow/schema.js.map +1 -0
- package/dist/workflow/service.d.ts +59 -0
- package/dist/workflow/service.d.ts.map +1 -0
- package/dist/workflow/service.js +170 -0
- package/dist/workflow/service.js.map +1 -0
- package/dist/workflow/store-json.d.ts +5 -0
- package/dist/workflow/store-json.d.ts.map +1 -0
- package/dist/workflow/store-json.js +35 -0
- package/dist/workflow/store-json.js.map +1 -0
- package/dist/workflow/store-lock.d.ts +3 -0
- package/dist/workflow/store-lock.d.ts.map +1 -0
- package/dist/workflow/store-lock.js +85 -0
- package/dist/workflow/store-lock.js.map +1 -0
- package/dist/workflow/store-paths.d.ts +17 -0
- package/dist/workflow/store-paths.d.ts.map +1 -0
- package/dist/workflow/store-paths.js +67 -0
- package/dist/workflow/store-paths.js.map +1 -0
- package/dist/workflow/store-validation.d.ts +7 -0
- package/dist/workflow/store-validation.d.ts.map +1 -0
- package/dist/workflow/store-validation.js +119 -0
- package/dist/workflow/store-validation.js.map +1 -0
- package/dist/workflow/store.d.ts +10 -0
- package/dist/workflow/store.d.ts.map +1 -0
- package/dist/workflow/store.js +193 -0
- package/dist/workflow/store.js.map +1 -0
- package/dist/workflow/types.d.ts +120 -0
- package/dist/workflow/types.d.ts.map +1 -0
- package/dist/workflow/types.js +15 -0
- package/dist/workflow/types.js.map +1 -0
- package/dist/workflow-transport.d.ts +28 -0
- package/dist/workflow-transport.d.ts.map +1 -0
- package/dist/workflow-transport.js +184 -0
- package/dist/workflow-transport.js.map +1 -0
- package/open-design.json +2 -2
- package/package.json +2 -1
- package/prototype-kit/tests/rules-check.mjs +9 -0
- package/runtime/codex-conversion/src/images/native-invoke.mjs +1 -1
- package/runtime/codex-conversion/src/images/native.mjs +8 -4
- package/runtime/layerdoc-validator.mjs +1860 -0
- package/skills/12ui-design/SKILL.md +17 -63
- package/skills/12ui-design/improve.md +5 -1
- package/skills/12ui-design/inspire.md +8 -5
- package/skills/12ui-design/outputs.md +23 -2
- package/skills/12ui-design/session.md +161 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { SlateError } from './slate-errors.js';
|
|
2
|
+
import { VERSION_ID_PATTERN } from './slate-ids.js';
|
|
3
|
+
/**
|
|
4
|
+
* The actions a click can commit, validated and normalized. The same function
|
|
5
|
+
* runs at `run`, so the intent digest is over exactly what the runner gets.
|
|
6
|
+
*/
|
|
7
|
+
/** How many options a round can draw, and how many it draws when the click does not say. */
|
|
8
|
+
export const ROUND_OPTION_COUNTS = [1, 2, 4, 8, 12];
|
|
9
|
+
export const DEFAULT_ROUND_OPTION_COUNT = 4;
|
|
10
|
+
export const NOTE_MAX_CHARACTERS = 600;
|
|
11
|
+
export const EDIT_PROMPT_MAX_BYTES = 6_000;
|
|
12
|
+
/**
|
|
13
|
+
* The stored instruction of an edit that carries marks and no words: what the agent and the drawing model are told the
|
|
14
|
+
* marks mean. One constant, used only when the trimmed text is empty (the Worker keeps an equal copy, pinned by a test).
|
|
15
|
+
*/
|
|
16
|
+
export const EDIT_MARKS_ONLY_PROMPT = 'Infer the change from the marks: an X or a cross-out means remove that element, a circle or a scribble means adjust it, and any words written there are the instruction.';
|
|
17
|
+
export const STROKE_LIMITS = { strokes: 24, pointsPerStroke: 400, pointsTotal: 3_000 };
|
|
18
|
+
const isRecord = (value) => (!!value && typeof value === 'object' && !Array.isArray(value));
|
|
19
|
+
const invalid = (message) => { throw new SlateError('invalid_input', message); };
|
|
20
|
+
/** Control characters are stripped except tab and newline; the rest is the user's text. */
|
|
21
|
+
export const cleanUserText = (value) => (
|
|
22
|
+
// eslint-disable-next-line no-control-regex
|
|
23
|
+
value.replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, '').trim());
|
|
24
|
+
/** Freehand strokes as integer permille points; anything outside the limits is refused, never trimmed. */
|
|
25
|
+
export const normalizeStrokes = (value) => {
|
|
26
|
+
if (value === undefined || value === null)
|
|
27
|
+
return [];
|
|
28
|
+
if (!Array.isArray(value))
|
|
29
|
+
return invalid('strokes must be a list of strokes');
|
|
30
|
+
if (value.length > STROKE_LIMITS.strokes)
|
|
31
|
+
return invalid(`At most ${STROKE_LIMITS.strokes} strokes can be sent.`);
|
|
32
|
+
let total = 0;
|
|
33
|
+
return value.map((stroke, strokeIndex) => {
|
|
34
|
+
if (!Array.isArray(stroke) || stroke.length === 0)
|
|
35
|
+
return invalid(`stroke ${strokeIndex + 1} must hold at least one point`);
|
|
36
|
+
if (stroke.length > STROKE_LIMITS.pointsPerStroke)
|
|
37
|
+
return invalid(`A stroke can hold at most ${STROKE_LIMITS.pointsPerStroke} points.`);
|
|
38
|
+
total += stroke.length;
|
|
39
|
+
if (total > STROKE_LIMITS.pointsTotal)
|
|
40
|
+
return invalid(`Strokes can hold at most ${STROKE_LIMITS.pointsTotal} points in all.`);
|
|
41
|
+
return stroke.map((point, pointIndex) => {
|
|
42
|
+
if (!Array.isArray(point) || point.length !== 2)
|
|
43
|
+
return invalid(`stroke ${strokeIndex + 1} point ${pointIndex + 1} must be [x, y]`);
|
|
44
|
+
const [x, y] = point;
|
|
45
|
+
if (typeof x !== 'number' || typeof y !== 'number' || !Number.isFinite(x) || !Number.isFinite(y)) {
|
|
46
|
+
return invalid(`stroke ${strokeIndex + 1} point ${pointIndex + 1} must be numbers`);
|
|
47
|
+
}
|
|
48
|
+
const px = Math.round(x);
|
|
49
|
+
const py = Math.round(y);
|
|
50
|
+
if (px < 0 || px > 1000 || py < 0 || py > 1000)
|
|
51
|
+
return invalid('stroke points are thousandths of the image, 0 to 1000');
|
|
52
|
+
return [px, py];
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
/** A missing count is the default; anything but 1, 2, 4, 8 or 12 is refused, never rounded. */
|
|
57
|
+
export const normalizeRoundCount = (value) => {
|
|
58
|
+
if (value === undefined || value === null)
|
|
59
|
+
return DEFAULT_ROUND_OPTION_COUNT;
|
|
60
|
+
const allowed = ROUND_OPTION_COUNTS.find((count) => count === value);
|
|
61
|
+
if (allowed === undefined)
|
|
62
|
+
return invalid(`count must be one of ${ROUND_OPTION_COUNTS.join(', ')}`);
|
|
63
|
+
return allowed;
|
|
64
|
+
};
|
|
65
|
+
export const normalizeAction = (input) => {
|
|
66
|
+
if (!isRecord(input))
|
|
67
|
+
return invalid('action must be an object');
|
|
68
|
+
if (input.kind === 'round') {
|
|
69
|
+
if (input.mode !== 'new' && input.mode !== 'like')
|
|
70
|
+
return invalid('mode must be new or like');
|
|
71
|
+
let note = null;
|
|
72
|
+
if (input.note !== undefined && input.note !== null) {
|
|
73
|
+
if (typeof input.note !== 'string')
|
|
74
|
+
return invalid('note must be text');
|
|
75
|
+
const cleaned = cleanUserText(input.note).replace(/\s+/gu, ' ');
|
|
76
|
+
if ([...cleaned].length > NOTE_MAX_CHARACTERS)
|
|
77
|
+
return invalid(`A steer note can be at most ${NOTE_MAX_CHARACTERS} characters.`);
|
|
78
|
+
note = cleaned || null;
|
|
79
|
+
}
|
|
80
|
+
let fromVersionId = null;
|
|
81
|
+
if (input.fromVersionId !== undefined && input.fromVersionId !== null) {
|
|
82
|
+
if (typeof input.fromVersionId !== 'string' || !VERSION_ID_PATTERN.test(input.fromVersionId))
|
|
83
|
+
return invalid('fromVersionId is not a version id');
|
|
84
|
+
fromVersionId = input.fromVersionId;
|
|
85
|
+
}
|
|
86
|
+
if (input.mode === 'like' && fromVersionId === null)
|
|
87
|
+
return invalid('More like this needs the version to stay close to (fromVersionId).');
|
|
88
|
+
if (input.mode === 'new' && fromVersionId !== null)
|
|
89
|
+
return invalid('New options do not start from a version.');
|
|
90
|
+
return { kind: 'round', mode: input.mode, note, fromVersionId, count: normalizeRoundCount(input.count) };
|
|
91
|
+
}
|
|
92
|
+
if (input.kind === 'edit') {
|
|
93
|
+
const versionId = input.versionId;
|
|
94
|
+
if (typeof versionId !== 'string' || !VERSION_ID_PATTERN.test(versionId))
|
|
95
|
+
return invalid('versionId is not a version id');
|
|
96
|
+
if (input.prompt !== undefined && input.prompt !== null && typeof input.prompt !== 'string')
|
|
97
|
+
return invalid('prompt must be text');
|
|
98
|
+
const strokes = normalizeStrokes(input.strokes);
|
|
99
|
+
const words = cleanUserText(input.prompt ?? '');
|
|
100
|
+
if (!words && strokes.length === 0)
|
|
101
|
+
return invalid('Draw on the image or say what should change.');
|
|
102
|
+
if (Buffer.byteLength(words) > EDIT_PROMPT_MAX_BYTES)
|
|
103
|
+
return invalid(`An edit instruction can be at most ${EDIT_PROMPT_MAX_BYTES} bytes.`);
|
|
104
|
+
return { kind: 'edit', versionId, prompt: words || EDIT_MARKS_ONLY_PROMPT, strokes };
|
|
105
|
+
}
|
|
106
|
+
return invalid('action.kind must be round or edit');
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=slate-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-actions.js","sourceRoot":"","sources":["../src/slate-actions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SlateRegion, SlateStroke } from './slate-view-contract.js';
|
|
2
|
+
/**
|
|
3
|
+
* The annotated copy of an edit's parent: the parent's own pixels with the
|
|
4
|
+
* user's freehand strokes drawn on it. No image path takes a mask, so this
|
|
5
|
+
* second image is the only spatial signal an edit can carry. Deterministic:
|
|
6
|
+
* the same parent and strokes always produce the same bytes, and the stroke
|
|
7
|
+
* colour is chosen from four candidates by distance from the parent's mean
|
|
8
|
+
* colour, so the marks stay visible on a dark or a bright design.
|
|
9
|
+
*/
|
|
10
|
+
export declare const STROKE_COLORS: readonly [{
|
|
11
|
+
readonly name: "magenta";
|
|
12
|
+
readonly hex: "#ff00ff";
|
|
13
|
+
}, {
|
|
14
|
+
readonly name: "cyan";
|
|
15
|
+
readonly hex: "#00e5ff";
|
|
16
|
+
}, {
|
|
17
|
+
readonly name: "red";
|
|
18
|
+
readonly hex: "#ff3b30";
|
|
19
|
+
}, {
|
|
20
|
+
readonly name: "yellow";
|
|
21
|
+
readonly hex: "#ffee00";
|
|
22
|
+
}];
|
|
23
|
+
export type StrokeColor = typeof STROKE_COLORS[number];
|
|
24
|
+
/** The colour with the largest RGB distance from the parent's mean colour; the first listed wins a tie. */
|
|
25
|
+
export declare const chooseStrokeColor: (mean: readonly [number, number, number]) => StrokeColor;
|
|
26
|
+
/** The strokes' bounding box in permille; null when there are no strokes. */
|
|
27
|
+
export declare const strokesRegion: (strokes: readonly SlateStroke[]) => SlateRegion | null;
|
|
28
|
+
export type AnnotatedImage = {
|
|
29
|
+
png: Buffer;
|
|
30
|
+
color: StrokeColor;
|
|
31
|
+
region: SlateRegion;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
35
|
+
export declare const renderAnnotated: (parent: Buffer, strokes: readonly SlateStroke[]) => Promise<AnnotatedImage>;
|
|
36
|
+
//# sourceMappingURL=slate-annotate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-annotate.d.ts","sourceRoot":"","sources":["../src/slate-annotate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEzE;;;;;;;GAOG;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;EAKhB,CAAC;AACX,MAAM,MAAM,WAAW,GAAG,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAYvD,2GAA2G;AAC3G,eAAO,MAAM,iBAAiB,GAAI,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,KAAG,WAI3E,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,aAAa,GAAI,SAAS,SAAS,WAAW,EAAE,KAAG,WAAW,GAAG,IAa7E,CAAC;AAiBF,MAAM,MAAM,cAAc,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAErH,eAAO,MAAM,eAAe,GAAU,QAAQ,MAAM,EAAE,SAAS,SAAS,WAAW,EAAE,KAAG,OAAO,CAAC,cAAc,CAe7G,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import sharp from 'sharp';
|
|
2
|
+
/**
|
|
3
|
+
* The annotated copy of an edit's parent: the parent's own pixels with the
|
|
4
|
+
* user's freehand strokes drawn on it. No image path takes a mask, so this
|
|
5
|
+
* second image is the only spatial signal an edit can carry. Deterministic:
|
|
6
|
+
* the same parent and strokes always produce the same bytes, and the stroke
|
|
7
|
+
* colour is chosen from four candidates by distance from the parent's mean
|
|
8
|
+
* colour, so the marks stay visible on a dark or a bright design.
|
|
9
|
+
*/
|
|
10
|
+
export const STROKE_COLORS = [
|
|
11
|
+
{ name: 'magenta', hex: '#ff00ff' },
|
|
12
|
+
{ name: 'cyan', hex: '#00e5ff' },
|
|
13
|
+
{ name: 'red', hex: '#ff3b30' },
|
|
14
|
+
{ name: 'yellow', hex: '#ffee00' },
|
|
15
|
+
];
|
|
16
|
+
const rgbOf = (hex) => [
|
|
17
|
+
Number.parseInt(hex.slice(1, 3), 16),
|
|
18
|
+
Number.parseInt(hex.slice(3, 5), 16),
|
|
19
|
+
Number.parseInt(hex.slice(5, 7), 16),
|
|
20
|
+
];
|
|
21
|
+
const distance = (left, right) => (Math.hypot(left[0] - right[0], left[1] - right[1], left[2] - right[2]));
|
|
22
|
+
/** The colour with the largest RGB distance from the parent's mean colour; the first listed wins a tie. */
|
|
23
|
+
export const chooseStrokeColor = (mean) => (STROKE_COLORS.reduce((best, candidate) => (distance(rgbOf(candidate.hex), mean) > distance(rgbOf(best.hex), mean) ? candidate : best)));
|
|
24
|
+
/** The strokes' bounding box in permille; null when there are no strokes. */
|
|
25
|
+
export const strokesRegion = (strokes) => {
|
|
26
|
+
const points = strokes.flat();
|
|
27
|
+
if (points.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
const xs = points.map((point) => point[0]);
|
|
30
|
+
const ys = points.map((point) => point[1]);
|
|
31
|
+
const left = Math.min(...xs);
|
|
32
|
+
const top = Math.min(...ys);
|
|
33
|
+
const width = Math.max(1, Math.max(...xs) - left);
|
|
34
|
+
const height = Math.max(1, Math.max(...ys) - top);
|
|
35
|
+
// A dot on the far edge still needs one permille of room inside the image.
|
|
36
|
+
const x = Math.min(left, 999);
|
|
37
|
+
const y = Math.min(top, 999);
|
|
38
|
+
return { x, y, w: Math.min(width, 1000 - x), h: Math.min(height, 1000 - y) };
|
|
39
|
+
};
|
|
40
|
+
const coordinate = (permille, size) => ((permille * size) / 1000).toFixed(2);
|
|
41
|
+
const strokesSvg = (args) => {
|
|
42
|
+
const line = Math.max(3, 0.008 * Math.min(args.width, args.height));
|
|
43
|
+
const shapes = args.strokes.map((stroke) => {
|
|
44
|
+
if (stroke.length === 1) {
|
|
45
|
+
const [x, y] = stroke[0];
|
|
46
|
+
return `<circle cx="${coordinate(x, args.width)}" cy="${coordinate(y, args.height)}" r="${(line / 2).toFixed(2)}" fill="${args.color}"/>`;
|
|
47
|
+
}
|
|
48
|
+
const points = stroke.map(([x, y]) => `${coordinate(x, args.width)},${coordinate(y, args.height)}`).join(' ');
|
|
49
|
+
return `<polyline points="${points}" fill="none" stroke="${args.color}" stroke-width="${line.toFixed(2)}" stroke-linecap="round" stroke-linejoin="round"/>`;
|
|
50
|
+
});
|
|
51
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${args.width}" height="${args.height}" viewBox="0 0 ${args.width} ${args.height}">${shapes.join('')}</svg>`;
|
|
52
|
+
};
|
|
53
|
+
export const renderAnnotated = async (parent, strokes) => {
|
|
54
|
+
const region = strokesRegion(strokes);
|
|
55
|
+
if (!region)
|
|
56
|
+
throw new Error('renderAnnotated needs at least one stroke');
|
|
57
|
+
const source = sharp(parent, { animated: false, failOn: 'warning' });
|
|
58
|
+
const { width, height } = await source.metadata();
|
|
59
|
+
if (!width || !height)
|
|
60
|
+
throw new Error('The parent image has no readable size.');
|
|
61
|
+
const stats = await sharp(parent, { animated: false, failOn: 'warning' }).flatten({ background: '#ffffff' }).stats();
|
|
62
|
+
const mean = [stats.channels[0].mean, stats.channels[1].mean, stats.channels[2].mean];
|
|
63
|
+
const color = chooseStrokeColor(mean);
|
|
64
|
+
const svg = Buffer.from(strokesSvg({ width, height, strokes, color: color.hex }));
|
|
65
|
+
const png = await sharp(parent, { animated: false, failOn: 'warning' })
|
|
66
|
+
.composite([{ input: svg, top: 0, left: 0 }])
|
|
67
|
+
.png()
|
|
68
|
+
.toBuffer();
|
|
69
|
+
return { png, color, region, width, height };
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=slate-annotate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-annotate.js","sourceRoot":"","sources":["../src/slate-annotate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The approval store: one user-level file OUTSIDE every run directory.
|
|
3
|
+
*
|
|
4
|
+
* A click on Design or Edit writes an entry here before any work starts. It is
|
|
5
|
+
* the "no work without a click" record: `resume` and the runner refuse to act
|
|
6
|
+
* without an entry whose digest matches the op they were asked to run. The
|
|
7
|
+
* runner starts `codex exec` with full access to its own scratch folder, so a
|
|
8
|
+
* planted `workspace.json` must never be able to make it execute. The record
|
|
9
|
+
* cannot live in `workspace.json` or `ledger.jsonl`, because a run directory is
|
|
10
|
+
* a place any process can plant a file, and a consent record inside the thing
|
|
11
|
+
* being adopted is not consent. It holds no money: the workspace costs none.
|
|
12
|
+
*/
|
|
13
|
+
export declare const APPROVALS_SCHEMA = "12ui.slate.approvals/2";
|
|
14
|
+
export type ApprovalEntry = {
|
|
15
|
+
opId: string;
|
|
16
|
+
workspaceId: string;
|
|
17
|
+
rootRealpath: string;
|
|
18
|
+
kind: 'round' | 'edit';
|
|
19
|
+
paramsDigest: string;
|
|
20
|
+
approvedAt: string;
|
|
21
|
+
settledAt: string | null;
|
|
22
|
+
};
|
|
23
|
+
export declare const slateStateRoot: (env?: NodeJS.ProcessEnv) => string;
|
|
24
|
+
export declare const slateApprovalsFile: (stateRoot: string) => string;
|
|
25
|
+
export declare const slatePicksDirectory: (stateRoot: string, workspaceId: string) => string;
|
|
26
|
+
export declare const slateHandoffsDirectory: (stateRoot: string, workspaceId: string) => string;
|
|
27
|
+
export declare const approvalKey: (workspaceId: string, opId: string) => string;
|
|
28
|
+
export declare const getApproval: (stateRoot: string, workspaceId: string, opId: string) => Promise<ApprovalEntry | undefined>;
|
|
29
|
+
/**
|
|
30
|
+
* Record a click's consent. Entries are keyed by workspace and op id, so an
|
|
31
|
+
* adopted or resumed op is never recorded twice.
|
|
32
|
+
*/
|
|
33
|
+
export declare const recordApproval: (args: {
|
|
34
|
+
stateRoot: string;
|
|
35
|
+
entry: ApprovalEntry;
|
|
36
|
+
now: number;
|
|
37
|
+
}) => Promise<{
|
|
38
|
+
created: boolean;
|
|
39
|
+
}>;
|
|
40
|
+
export declare const settleApproval: (args: {
|
|
41
|
+
stateRoot: string;
|
|
42
|
+
workspaceId: string;
|
|
43
|
+
opId: string;
|
|
44
|
+
at: string;
|
|
45
|
+
}) => Promise<void>;
|
|
46
|
+
/** The checks `resume` and the runner make before they read any field of `op.params`. */
|
|
47
|
+
export declare const approvalMatches: (args: {
|
|
48
|
+
entry: ApprovalEntry | undefined;
|
|
49
|
+
rootRealpath: string;
|
|
50
|
+
kind: ApprovalEntry["kind"];
|
|
51
|
+
paramsDigest: string;
|
|
52
|
+
}) => "ok" | "approval_missing" | "approval_mismatch";
|
|
53
|
+
/** A resumed op is being worked on again: its settlement no longer holds. */
|
|
54
|
+
export declare const reopenApproval: (args: {
|
|
55
|
+
stateRoot: string;
|
|
56
|
+
workspaceId: string;
|
|
57
|
+
opId: string;
|
|
58
|
+
}) => Promise<void>;
|
|
59
|
+
/** The keys present in the store, for the view's `resumable` flag, in one read. */
|
|
60
|
+
export declare const listApprovalKeys: (stateRoot: string) => Promise<Set<string>>;
|
|
61
|
+
//# sourceMappingURL=slate-approvals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-approvals.d.ts","sourceRoot":"","sources":["../src/slate-approvals.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;GAWG;AAEH,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAKzD,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAIF,eAAO,MAAM,cAAc,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,MAGrE,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,WAAW,MAAM,KAAG,MAAyD,CAAC;AAEjH,eAAO,MAAM,mBAAmB,GAAI,WAAW,MAAM,EAAE,aAAa,MAAM,KAAG,MAE5E,CAAC;AACF,eAAO,MAAM,sBAAsB,GAAI,WAAW,MAAM,EAAE,aAAa,MAAM,KAAG,MAE/E,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,aAAa,MAAM,EAAE,MAAM,MAAM,KAAG,MAAkC,CAAC;AAsDnG,eAAO,MAAM,WAAW,GAAU,WAAW,MAAM,EAAE,aAAa,MAAM,EAAE,MAAM,MAAM,KAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAEzH,CAAC;AAqBF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,MAAM;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;CACb,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAc9B,CAAC;AAEH,eAAO,MAAM,cAAc,GAAU,MAAM;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,KAAG,OAAO,CAAC,IAAI,CAGd,CAAC;AAEH,yFAAyF;AACzF,eAAO,MAAM,eAAe,GAAI,MAAM;IACpC,KAAK,EAAE,aAAa,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB,KAAG,IAAI,GAAG,kBAAkB,GAAG,mBAQ/B,CAAC;AAEF,6EAA6E;AAC7E,eAAO,MAAM,cAAc,GAAU,MAAM;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd,KAAG,OAAO,CAAC,IAAI,CAGd,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,GAAU,WAAW,MAAM,KAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAE7E,CAAC"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { mkdir, readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { replaceFileAtomically } from './atomic-file-replace.js';
|
|
4
|
+
import { resolveCliInstallLayout } from './cli-persistence.js';
|
|
5
|
+
import { SlateError, SlateStateInvalidError } from './slate-errors.js';
|
|
6
|
+
import { OP_ID_PATTERN, SHA256_PATTERN, WORKSPACE_ID_PATTERN } from './slate-ids.js';
|
|
7
|
+
import { staleWhenProcessGone, withLock } from './slate-lock.js';
|
|
8
|
+
/**
|
|
9
|
+
* The approval store: one user-level file OUTSIDE every run directory.
|
|
10
|
+
*
|
|
11
|
+
* A click on Design or Edit writes an entry here before any work starts. It is
|
|
12
|
+
* the "no work without a click" record: `resume` and the runner refuse to act
|
|
13
|
+
* without an entry whose digest matches the op they were asked to run. The
|
|
14
|
+
* runner starts `codex exec` with full access to its own scratch folder, so a
|
|
15
|
+
* planted `workspace.json` must never be able to make it execute. The record
|
|
16
|
+
* cannot live in `workspace.json` or `ledger.jsonl`, because a run directory is
|
|
17
|
+
* a place any process can plant a file, and a consent record inside the thing
|
|
18
|
+
* being adopted is not consent. It holds no money: the workspace costs none.
|
|
19
|
+
*/
|
|
20
|
+
export const APPROVALS_SCHEMA = '12ui.slate.approvals/2';
|
|
21
|
+
/** The checkpoint build's store: read once, its priced fields dropped, its redraw entries dropped, and rewritten as /2. */
|
|
22
|
+
const PRE_V3_SCHEMA = '12ui.slate.approvals/1';
|
|
23
|
+
const PRUNE_AFTER_MS = 30 * 24 * 60 * 60 * 1000;
|
|
24
|
+
export const slateStateRoot = (env = process.env) => {
|
|
25
|
+
const override = env.TWELVE_UI_SLATE_STATE_DIR?.trim();
|
|
26
|
+
return override ? path.resolve(override) : resolveCliInstallLayout(env).dataRoot;
|
|
27
|
+
};
|
|
28
|
+
export const slateApprovalsFile = (stateRoot) => path.join(stateRoot, 'slate', 'approvals.json');
|
|
29
|
+
const approvalsLockFile = (stateRoot) => path.join(stateRoot, 'slate', 'approvals.lock');
|
|
30
|
+
export const slatePicksDirectory = (stateRoot, workspaceId) => (path.join(stateRoot, 'slate', 'picks', workspaceId));
|
|
31
|
+
export const slateHandoffsDirectory = (stateRoot, workspaceId) => (path.join(stateRoot, 'slate', 'handoffs', workspaceId));
|
|
32
|
+
export const approvalKey = (workspaceId, opId) => `${workspaceId}/${opId}`;
|
|
33
|
+
const parseEntry = (file, key, value) => {
|
|
34
|
+
const fail = (detail) => { throw new SlateStateInvalidError(file, `entry ${key}: ${detail}`); };
|
|
35
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
36
|
+
return fail('expected an object');
|
|
37
|
+
const r = value;
|
|
38
|
+
const text = (name, pattern) => {
|
|
39
|
+
const field = r[name];
|
|
40
|
+
if (typeof field !== 'string' || field.length > 4096 || (pattern && !pattern.test(field)))
|
|
41
|
+
fail(`bad ${name}`);
|
|
42
|
+
return field;
|
|
43
|
+
};
|
|
44
|
+
const kind = r.kind;
|
|
45
|
+
if (kind !== 'round' && kind !== 'edit')
|
|
46
|
+
fail('bad kind');
|
|
47
|
+
if (r.settledAt !== null && typeof r.settledAt !== 'string')
|
|
48
|
+
fail('bad settledAt');
|
|
49
|
+
return {
|
|
50
|
+
opId: text('opId', OP_ID_PATTERN),
|
|
51
|
+
workspaceId: text('workspaceId', WORKSPACE_ID_PATTERN),
|
|
52
|
+
rootRealpath: text('rootRealpath'),
|
|
53
|
+
kind: kind,
|
|
54
|
+
paramsDigest: text('paramsDigest', SHA256_PATTERN),
|
|
55
|
+
approvedAt: text('approvedAt'),
|
|
56
|
+
settledAt: r.settledAt,
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
const readStore = async (stateRoot) => {
|
|
60
|
+
const file = slateApprovalsFile(stateRoot);
|
|
61
|
+
let raw;
|
|
62
|
+
try {
|
|
63
|
+
raw = await readFile(file, 'utf8');
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
if (error.code === 'ENOENT')
|
|
67
|
+
return { schema: APPROVALS_SCHEMA, entries: {} };
|
|
68
|
+
throw error;
|
|
69
|
+
}
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(raw);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
throw new SlateStateInvalidError(file, 'not valid JSON');
|
|
76
|
+
}
|
|
77
|
+
const record = parsed;
|
|
78
|
+
const earlier = record?.schema === PRE_V3_SCHEMA;
|
|
79
|
+
if (!record || (record.schema !== APPROVALS_SCHEMA && !earlier) || !record.entries || typeof record.entries !== 'object') {
|
|
80
|
+
throw new SlateStateInvalidError(file, `expected schema ${APPROVALS_SCHEMA}`);
|
|
81
|
+
}
|
|
82
|
+
const entries = {};
|
|
83
|
+
for (const [key, value] of Object.entries(record.entries)) {
|
|
84
|
+
// A redraw was a paid op that no longer exists; nothing can resume it.
|
|
85
|
+
if (earlier && value?.kind === 'redraw')
|
|
86
|
+
continue;
|
|
87
|
+
entries[key] = parseEntry(file, key, value);
|
|
88
|
+
}
|
|
89
|
+
return { schema: APPROVALS_SCHEMA, entries };
|
|
90
|
+
};
|
|
91
|
+
export const getApproval = async (stateRoot, workspaceId, opId) => ((await readStore(stateRoot)).entries[approvalKey(workspaceId, opId)]);
|
|
92
|
+
const mutateStore = async (stateRoot, run) => {
|
|
93
|
+
await mkdir(path.join(stateRoot, 'slate'), { recursive: true, mode: 0o700 });
|
|
94
|
+
return withLock({
|
|
95
|
+
file: approvalsLockFile(stateRoot),
|
|
96
|
+
policy: staleWhenProcessGone,
|
|
97
|
+
busyMessage: 'The approval store is busy; try again in a moment.',
|
|
98
|
+
run: async () => {
|
|
99
|
+
const store = await readStore(stateRoot);
|
|
100
|
+
const result = run(store);
|
|
101
|
+
await replaceFileAtomically({
|
|
102
|
+
file: slateApprovalsFile(stateRoot),
|
|
103
|
+
contents: `${JSON.stringify(store, null, 2)}\n`,
|
|
104
|
+
mode: 0o600,
|
|
105
|
+
});
|
|
106
|
+
return result;
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Record a click's consent. Entries are keyed by workspace and op id, so an
|
|
112
|
+
* adopted or resumed op is never recorded twice.
|
|
113
|
+
*/
|
|
114
|
+
export const recordApproval = async (args) => mutateStore(args.stateRoot, (store) => {
|
|
115
|
+
const key = approvalKey(args.entry.workspaceId, args.entry.opId);
|
|
116
|
+
const existing = store.entries[key];
|
|
117
|
+
if (existing) {
|
|
118
|
+
if (existing.paramsDigest !== args.entry.paramsDigest) {
|
|
119
|
+
throw new SlateError('intent_conflict', 'This op id already has a different approved plan.');
|
|
120
|
+
}
|
|
121
|
+
return { created: false };
|
|
122
|
+
}
|
|
123
|
+
store.entries[key] = args.entry;
|
|
124
|
+
for (const [entryKey, entry] of Object.entries(store.entries)) {
|
|
125
|
+
if (entry.settledAt && args.now - Date.parse(entry.settledAt) > PRUNE_AFTER_MS)
|
|
126
|
+
delete store.entries[entryKey];
|
|
127
|
+
}
|
|
128
|
+
return { created: true };
|
|
129
|
+
});
|
|
130
|
+
export const settleApproval = async (args) => mutateStore(args.stateRoot, (store) => {
|
|
131
|
+
const entry = store.entries[approvalKey(args.workspaceId, args.opId)];
|
|
132
|
+
if (entry)
|
|
133
|
+
entry.settledAt = args.at;
|
|
134
|
+
});
|
|
135
|
+
/** The checks `resume` and the runner make before they read any field of `op.params`. */
|
|
136
|
+
export const approvalMatches = (args) => {
|
|
137
|
+
if (!args.entry)
|
|
138
|
+
return 'approval_missing';
|
|
139
|
+
if (args.entry.rootRealpath !== args.rootRealpath
|
|
140
|
+
|| args.entry.kind !== args.kind
|
|
141
|
+
|| args.entry.paramsDigest !== args.paramsDigest)
|
|
142
|
+
return 'approval_mismatch';
|
|
143
|
+
return 'ok';
|
|
144
|
+
};
|
|
145
|
+
/** A resumed op is being worked on again: its settlement no longer holds. */
|
|
146
|
+
export const reopenApproval = async (args) => mutateStore(args.stateRoot, (store) => {
|
|
147
|
+
const entry = store.entries[approvalKey(args.workspaceId, args.opId)];
|
|
148
|
+
if (entry)
|
|
149
|
+
entry.settledAt = null;
|
|
150
|
+
});
|
|
151
|
+
/** The keys present in the store, for the view's `resumable` flag, in one read. */
|
|
152
|
+
export const listApprovalKeys = async (stateRoot) => (new Set(Object.keys((await readStore(stateRoot)).entries)));
|
|
153
|
+
//# sourceMappingURL=slate-approvals.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-approvals.js","sourceRoot":"","sources":["../src/slate-approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import type { SlateWorkspaceView } from './slate-view-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* What a person decided in the browser workspace, as the command that opened it prints it.
|
|
5
|
+
*
|
|
6
|
+
* A decision is Select, or a Branch or Convert request that was sent: the three things the workspace records and then
|
|
7
|
+
* tells the agent about. The server derives it from the tool call that recorded it (the pick or the hand-off tool
|
|
8
|
+
* returning without an error), never from a message the page says it sent, so a page that lost its message still
|
|
9
|
+
* reports what is in `workspace.json`. The messages the screen would have sent to an agent ride along in `messages`.
|
|
10
|
+
*/
|
|
11
|
+
export type SlateBrowserDecisionKind = 'select' | 'branch' | 'convert';
|
|
12
|
+
export type SlateBrowserDecision = {
|
|
13
|
+
decision: SlateBrowserDecisionKind;
|
|
14
|
+
runDir: string;
|
|
15
|
+
/** The workspace's selection now (also set when the decision was a hand-off: the pick is not cleared). */
|
|
16
|
+
pick: SlateWorkspaceView['pick'];
|
|
17
|
+
/** The Branch or Convert request that was sent, or null for a Select. */
|
|
18
|
+
handoff: SlateWorkspaceView['handoffs'][number] | null;
|
|
19
|
+
/** The words the screen would have sent its host, in order. */
|
|
20
|
+
messages: string[];
|
|
21
|
+
/** What `design.slate.data` says about this workspace, and the command that continues from the decision. */
|
|
22
|
+
text: string;
|
|
23
|
+
/** The workspace as `design.slate.data` returns it. */
|
|
24
|
+
view: SlateWorkspaceView;
|
|
25
|
+
};
|
|
26
|
+
export type SlateBrowserDecided = Omit<SlateBrowserDecision, 'messages' | 'text'>;
|
|
27
|
+
/** The decision one successful tool call made, or undefined when it made none. */
|
|
28
|
+
export declare const decidedBy: (name: string, result: CallToolResult) => SlateBrowserDecided | undefined;
|
|
29
|
+
export declare const finishDecision: (decided: SlateBrowserDecided, messages: string[]) => Promise<SlateBrowserDecision>;
|
|
30
|
+
//# sourceMappingURL=slate-browser-decision.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-browser-decision.d.ts","sourceRoot":"","sources":["../src/slate-browser-decision.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAIzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE;;;;;;;GAOG;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvE,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,EAAE,wBAAwB,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,0GAA0G;IAC1G,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACjC,yEAAyE;IACzE,OAAO,EAAE,kBAAkB,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvD,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,4GAA4G;IAC5G,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,IAAI,EAAE,kBAAkB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,oBAAoB,EAAE,UAAU,GAAG,MAAM,CAAC,CAAC;AAMlF,kFAAkF;AAClF,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,QAAQ,cAAc,KAAG,mBAAmB,GAAG,SAStF,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,SAAS,mBAAmB,EAAE,UAAU,MAAM,EAAE,KAAG,OAAO,CAAC,oBAAoB,CAIlH,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SLATE_HANDOFF_TOOL, SLATE_PICK_TOOL } from './mcp-slate-names.js';
|
|
2
|
+
import { slateFallbackText } from './mcp-slate-command.js';
|
|
3
|
+
const isView = (value) => (!!value && typeof value === 'object' && Array.isArray(value.candidates));
|
|
4
|
+
/** The decision one successful tool call made, or undefined when it made none. */
|
|
5
|
+
export const decidedBy = (name, result) => {
|
|
6
|
+
if (result.isError)
|
|
7
|
+
return undefined;
|
|
8
|
+
const content = result.structuredContent;
|
|
9
|
+
if (!content || !isView(content.view) || content.view.runDir === null)
|
|
10
|
+
return undefined;
|
|
11
|
+
const { view } = content;
|
|
12
|
+
const base = { runDir: view.runDir, pick: view.pick, view };
|
|
13
|
+
if (name === SLATE_PICK_TOOL)
|
|
14
|
+
return { decision: 'select', handoff: null, ...base };
|
|
15
|
+
if (name === SLATE_HANDOFF_TOOL && content.handoff)
|
|
16
|
+
return { decision: content.handoff.kind, handoff: content.handoff, ...base };
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
export const finishDecision = async (decided, messages) => ({
|
|
20
|
+
...decided,
|
|
21
|
+
messages,
|
|
22
|
+
text: await slateFallbackText(decided.view, { browser: true }),
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=slate-browser-decision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-browser-decision.js","sourceRoot":"","sources":["../src/slate-browser-decision.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA+B3D,MAAM,MAAM,GAAG,CAAC,KAAc,EAA+B,EAAE,CAAC,CAC9D,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAE,KAA4B,CAAC,UAAU,CAAC,CAChG,CAAC;AAEF,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,MAAsB,EAAmC,EAAE;IACjG,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,iBAA4G,CAAC;IACpI,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,SAAS,CAAC;IACxF,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;IAC7D,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,CAAC;IACpF,IAAI,IAAI,KAAK,kBAAkB,IAAI,OAAO,CAAC,OAAO;QAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,CAAC;IACjI,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAAE,OAA4B,EAAE,QAAkB,EAAiC,EAAE,CAAC,CAAC;IACxH,GAAG,OAAO;IACV,QAAQ;IACR,IAAI,EAAE,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;CAC/D,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host shim of the browser workspace: the half of the MCP Apps bridge the screen expects to find on the other side
|
|
3
|
+
* of `postMessage`, implemented by the page that frames it.
|
|
4
|
+
*
|
|
5
|
+
* It answers `ui/initialize` with a host context (the theme from `prefers-color-scheme`, the display mode), delivers the
|
|
6
|
+
* workspace as the `ui/notifications/tool-result` the screen waits for (so a reload restores the workspace from disk,
|
|
7
|
+
* as the MCP host's re-render does), turns `tools/call` into `POST /api/call` and `ui/message` into `POST /api/message`,
|
|
8
|
+
* and lays the frame out: the whole window in `fullscreen`, its reported height in `inline` (`?mode=inline`). The
|
|
9
|
+
* session token is the one in this page's own URL; the frame never sees it.
|
|
10
|
+
*
|
|
11
|
+
* String.raw so escapes reach the browser unchanged: no backtick and no dollar-brace inside.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SLATE_BROWSER_HOST_SCRIPT: string;
|
|
14
|
+
//# sourceMappingURL=slate-browser-host-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slate-browser-host-script.d.ts","sourceRoot":"","sources":["../src/slate-browser-host-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,yBAAyB,QA+GrC,CAAC"}
|