@try-works/dsh-tool-mode 0.0.0-stage → 0.5.45
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 +205 -0
- package/README.md +303 -2
- package/bin/dsh-tool-mode-credentials.mjs +20 -0
- package/bin/dsh-tool-mode-mcp-stdio.mjs +80 -0
- package/bin/dsh-tool-mode.mjs +211 -0
- package/builtins.lock.json +26 -0
- package/catalog/desert-ant-models.json +693 -0
- package/catalog/playbooks.json +531 -0
- package/client/client.model-tools.js +1910 -0
- package/client/index.js +4158 -0
- package/cordis.patch.yml +39 -0
- package/lib/adapters/index.d.ts +61 -0
- package/lib/adapters/index.d.ts.map +1 -0
- package/lib/adapters/index.js +82 -0
- package/lib/adapters/types.d.ts +106 -0
- package/lib/adapters/types.d.ts.map +1 -0
- package/lib/adapters/types.js +85 -0
- package/lib/approval.d.ts +189 -0
- package/lib/approval.d.ts.map +1 -0
- package/lib/approval.js +510 -0
- package/lib/asset-acquisition.d.ts +149 -0
- package/lib/asset-acquisition.d.ts.map +1 -0
- package/lib/asset-acquisition.js +175 -0
- package/lib/authority.d.ts +185 -0
- package/lib/authority.d.ts.map +1 -0
- package/lib/authority.js +223 -0
- package/lib/bindings.d.ts +144 -0
- package/lib/bindings.d.ts.map +1 -0
- package/lib/bindings.js +314 -0
- package/lib/builtins.d.ts +27 -0
- package/lib/builtins.d.ts.map +1 -0
- package/lib/builtins.js +37 -0
- package/lib/capability.d.ts +58 -0
- package/lib/capability.d.ts.map +1 -0
- package/lib/capability.js +192 -0
- package/lib/capture-path.d.ts +97 -0
- package/lib/capture-path.d.ts.map +1 -0
- package/lib/capture-path.js +152 -0
- package/lib/catalog.d.ts +37 -0
- package/lib/catalog.d.ts.map +1 -0
- package/lib/catalog.js +274 -0
- package/lib/contract-payload.d.ts +39 -0
- package/lib/contract-payload.d.ts.map +1 -0
- package/lib/contract-payload.js +56 -0
- package/lib/custom-tools/compile.d.ts +25 -0
- package/lib/custom-tools/compile.d.ts.map +1 -0
- package/lib/custom-tools/compile.js +61 -0
- package/lib/custom-tools/composite-executor.d.ts +42 -0
- package/lib/custom-tools/composite-executor.d.ts.map +1 -0
- package/lib/custom-tools/composite-executor.js +113 -0
- package/lib/custom-tools/dispatch.d.ts +28 -0
- package/lib/custom-tools/dispatch.d.ts.map +1 -0
- package/lib/custom-tools/dispatch.js +34 -0
- package/lib/custom-tools/http-executor.d.ts +48 -0
- package/lib/custom-tools/http-executor.d.ts.map +1 -0
- package/lib/custom-tools/http-executor.js +241 -0
- package/lib/custom-tools/index.d.ts +12 -0
- package/lib/custom-tools/index.d.ts.map +1 -0
- package/lib/custom-tools/index.js +12 -0
- package/lib/custom-tools/mcp-surface.d.ts +14 -0
- package/lib/custom-tools/mcp-surface.d.ts.map +1 -0
- package/lib/custom-tools/mcp-surface.js +41 -0
- package/lib/custom-tools/prompt-executor.d.ts +39 -0
- package/lib/custom-tools/prompt-executor.d.ts.map +1 -0
- package/lib/custom-tools/prompt-executor.js +59 -0
- package/lib/custom-tools/registry.d.ts +69 -0
- package/lib/custom-tools/registry.d.ts.map +1 -0
- package/lib/custom-tools/registry.js +130 -0
- package/lib/custom-tools/schema.d.ts +26 -0
- package/lib/custom-tools/schema.d.ts.map +1 -0
- package/lib/custom-tools/schema.js +375 -0
- package/lib/custom-tools/service.d.ts +90 -0
- package/lib/custom-tools/service.d.ts.map +1 -0
- package/lib/custom-tools/service.js +203 -0
- package/lib/custom-tools/store.d.ts +61 -0
- package/lib/custom-tools/store.d.ts.map +1 -0
- package/lib/custom-tools/store.js +240 -0
- package/lib/custom-tools/types.d.ts +131 -0
- package/lib/custom-tools/types.d.ts.map +1 -0
- package/lib/custom-tools/types.js +11 -0
- package/lib/decision-combine.d.ts +113 -0
- package/lib/decision-combine.d.ts.map +1 -0
- package/lib/decision-combine.js +156 -0
- package/lib/decision-evaluate.d.ts +185 -0
- package/lib/decision-evaluate.d.ts.map +1 -0
- package/lib/decision-evaluate.js +227 -0
- package/lib/deployment-coordinator.d.ts +213 -0
- package/lib/deployment-coordinator.d.ts.map +1 -0
- package/lib/deployment-coordinator.js +274 -0
- package/lib/diagnostics.d.ts +169 -0
- package/lib/diagnostics.d.ts.map +1 -0
- package/lib/diagnostics.js +136 -0
- package/lib/discovery-contracts.d.ts +14 -0
- package/lib/discovery-contracts.d.ts.map +1 -0
- package/lib/discovery-contracts.js +90 -0
- package/lib/discovery-describe.d.ts +35 -0
- package/lib/discovery-describe.d.ts.map +1 -0
- package/lib/discovery-describe.js +99 -0
- package/lib/embedding-index.d.ts +55 -0
- package/lib/embedding-index.d.ts.map +1 -0
- package/lib/embedding-index.js +126 -0
- package/lib/extension-dependencies.d.ts +355 -0
- package/lib/extension-dependencies.d.ts.map +1 -0
- package/lib/extension-dependencies.js +987 -0
- package/lib/extension-dispatch.d.ts +150 -0
- package/lib/extension-dispatch.d.ts.map +1 -0
- package/lib/extension-dispatch.js +178 -0
- package/lib/extension-page-state.d.ts +69 -0
- package/lib/extension-page-state.d.ts.map +1 -0
- package/lib/extension-page-state.js +82 -0
- package/lib/extension-registrar.d.ts +116 -0
- package/lib/extension-registrar.d.ts.map +1 -0
- package/lib/extension-registrar.js +144 -0
- package/lib/extensions-api.d.ts +346 -0
- package/lib/extensions-api.d.ts.map +1 -0
- package/lib/extensions-api.js +17 -0
- package/lib/extensions-remote.d.ts +57 -0
- package/lib/extensions-remote.d.ts.map +1 -0
- package/lib/extensions-remote.js +69 -0
- package/lib/extensions-service.d.ts +568 -0
- package/lib/extensions-service.d.ts.map +1 -0
- package/lib/extensions-service.js +2552 -0
- package/lib/harness-budgets.d.ts +158 -0
- package/lib/harness-budgets.d.ts.map +1 -0
- package/lib/harness-budgets.js +152 -0
- package/lib/harness-llm.d.ts +138 -0
- package/lib/harness-llm.d.ts.map +1 -0
- package/lib/harness-llm.js +218 -0
- package/lib/harness-serving.d.ts +115 -0
- package/lib/harness-serving.d.ts.map +1 -0
- package/lib/harness-serving.js +176 -0
- package/lib/headless.d.ts +97 -0
- package/lib/headless.d.ts.map +1 -0
- package/lib/headless.js +407 -0
- package/lib/http-acquisition.d.ts +27 -0
- package/lib/http-acquisition.d.ts.map +1 -0
- package/lib/http-acquisition.js +140 -0
- package/lib/index.d.ts +546 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +5273 -0
- package/lib/invocation-accounting.d.ts +169 -0
- package/lib/invocation-accounting.d.ts.map +1 -0
- package/lib/invocation-accounting.js +148 -0
- package/lib/jev.d.ts +218 -0
- package/lib/jev.d.ts.map +1 -0
- package/lib/jev.js +366 -0
- package/lib/legacy-migration.d.ts +95 -0
- package/lib/legacy-migration.d.ts.map +1 -0
- package/lib/legacy-migration.js +429 -0
- package/lib/license-basis.d.ts +29 -0
- package/lib/license-basis.d.ts.map +1 -0
- package/lib/license-basis.js +58 -0
- package/lib/managed-workers.d.ts +158 -0
- package/lib/managed-workers.d.ts.map +1 -0
- package/lib/managed-workers.js +269 -0
- package/lib/mcp/auth-selection.d.ts +35 -0
- package/lib/mcp/auth-selection.d.ts.map +1 -0
- package/lib/mcp/auth-selection.js +64 -0
- package/lib/mcp/client-grant.d.ts +89 -0
- package/lib/mcp/client-grant.d.ts.map +1 -0
- package/lib/mcp/client-grant.js +63 -0
- package/lib/mcp/credential-cli.d.ts +38 -0
- package/lib/mcp/credential-cli.d.ts.map +1 -0
- package/lib/mcp/credential-cli.js +148 -0
- package/lib/mcp/credential-store.d.ts +143 -0
- package/lib/mcp/credential-store.d.ts.map +1 -0
- package/lib/mcp/credential-store.js +461 -0
- package/lib/mcp/export-policy.d.ts +25 -0
- package/lib/mcp/export-policy.d.ts.map +1 -0
- package/lib/mcp/export-policy.js +31 -0
- package/lib/mcp/host-binding.d.ts +144 -0
- package/lib/mcp/host-binding.d.ts.map +1 -0
- package/lib/mcp/host-binding.js +280 -0
- package/lib/mcp/http.d.ts +180 -0
- package/lib/mcp/http.d.ts.map +1 -0
- package/lib/mcp/http.js +602 -0
- package/lib/mcp/oauth.d.ts +149 -0
- package/lib/mcp/oauth.d.ts.map +1 -0
- package/lib/mcp/oauth.js +396 -0
- package/lib/mcp/protocol.d.ts +329 -0
- package/lib/mcp/protocol.d.ts.map +1 -0
- package/lib/mcp/protocol.js +459 -0
- package/lib/mcp/rate-limit.d.ts +68 -0
- package/lib/mcp/rate-limit.d.ts.map +1 -0
- package/lib/mcp/rate-limit.js +114 -0
- package/lib/mcp/sdk-v2.d.ts +17 -0
- package/lib/mcp/sdk-v2.d.ts.map +1 -0
- package/lib/mcp/sdk-v2.js +204 -0
- package/lib/mcp/server.d.ts +149 -0
- package/lib/mcp/server.d.ts.map +1 -0
- package/lib/mcp/server.js +302 -0
- package/lib/mcp/stdio.d.ts +80 -0
- package/lib/mcp/stdio.d.ts.map +1 -0
- package/lib/mcp/stdio.js +184 -0
- package/lib/mcp/subscriptions.d.ts +177 -0
- package/lib/mcp/subscriptions.d.ts.map +1 -0
- package/lib/mcp/subscriptions.js +288 -0
- package/lib/mcp-status.d.ts +96 -0
- package/lib/mcp-status.d.ts.map +1 -0
- package/lib/mcp-status.js +70 -0
- package/lib/mcp-usage.d.ts +110 -0
- package/lib/mcp-usage.d.ts.map +1 -0
- package/lib/mcp-usage.js +189 -0
- package/lib/model-qualification.d.ts +192 -0
- package/lib/model-qualification.d.ts.map +1 -0
- package/lib/model-qualification.js +178 -0
- package/lib/model-runtime-lane.d.ts +69 -0
- package/lib/model-runtime-lane.d.ts.map +1 -0
- package/lib/model-runtime-lane.js +122 -0
- package/lib/model-runtime-recipe.d.ts +132 -0
- package/lib/model-runtime-recipe.d.ts.map +1 -0
- package/lib/model-runtime-recipe.js +291 -0
- package/lib/planning.d.ts +256 -0
- package/lib/planning.d.ts.map +1 -0
- package/lib/planning.js +471 -0
- package/lib/playbook.d.ts +42 -0
- package/lib/playbook.d.ts.map +1 -0
- package/lib/playbook.js +65 -0
- package/lib/prepared-assets.d.ts +269 -0
- package/lib/prepared-assets.d.ts.map +1 -0
- package/lib/prepared-assets.js +471 -0
- package/lib/provider-bridge.d.ts +107 -0
- package/lib/provider-bridge.d.ts.map +1 -0
- package/lib/provider-bridge.js +423 -0
- package/lib/ptc-authority.d.ts +154 -0
- package/lib/ptc-authority.d.ts.map +1 -0
- package/lib/ptc-authority.js +242 -0
- package/lib/ptc-confinement.d.ts +60 -0
- package/lib/ptc-confinement.d.ts.map +1 -0
- package/lib/ptc-confinement.js +212 -0
- package/lib/ptc-runtime.d.ts +166 -0
- package/lib/ptc-runtime.d.ts.map +1 -0
- package/lib/ptc-runtime.js +231 -0
- package/lib/publication.d.ts +161 -0
- package/lib/publication.d.ts.map +1 -0
- package/lib/publication.js +181 -0
- package/lib/receipt-store.d.ts +57 -0
- package/lib/receipt-store.d.ts.map +1 -0
- package/lib/receipt-store.js +143 -0
- package/lib/receipt.d.ts +231 -0
- package/lib/receipt.d.ts.map +1 -0
- package/lib/receipt.js +165 -0
- package/lib/registrar.d.ts +75 -0
- package/lib/registrar.d.ts.map +1 -0
- package/lib/registrar.js +152 -0
- package/lib/resource-governance.d.ts +204 -0
- package/lib/resource-governance.d.ts.map +1 -0
- package/lib/resource-governance.js +213 -0
- package/lib/server-lifecycle.d.ts +175 -0
- package/lib/server-lifecycle.d.ts.map +1 -0
- package/lib/server-lifecycle.js +269 -0
- package/lib/skills.d.ts +31 -0
- package/lib/skills.d.ts.map +1 -0
- package/lib/skills.js +170 -0
- package/lib/speech-bridge.d.ts +74 -0
- package/lib/speech-bridge.d.ts.map +1 -0
- package/lib/speech-bridge.js +115 -0
- package/lib/state.d.ts +100 -0
- package/lib/state.d.ts.map +1 -0
- package/lib/state.js +160 -0
- package/lib/title-proposal.d.ts +194 -0
- package/lib/title-proposal.d.ts.map +1 -0
- package/lib/title-proposal.js +244 -0
- package/lib/tool-inventory.d.ts +90 -0
- package/lib/tool-inventory.d.ts.map +1 -0
- package/lib/tool-inventory.js +102 -0
- package/lib/tool-mode-run.d.ts +310 -0
- package/lib/tool-mode-run.d.ts.map +1 -0
- package/lib/tool-mode-run.js +411 -0
- package/lib/tool-sources.d.ts +80 -0
- package/lib/tool-sources.d.ts.map +1 -0
- package/lib/tool-sources.js +123 -0
- package/lib/tool-usage-projection.d.ts +390 -0
- package/lib/tool-usage-projection.d.ts.map +1 -0
- package/lib/tool-usage-projection.js +1038 -0
- package/lib/tool-usage-report.d.ts +153 -0
- package/lib/tool-usage-report.d.ts.map +1 -0
- package/lib/tool-usage-report.js +274 -0
- package/lib/transport.d.ts +158 -0
- package/lib/transport.d.ts.map +1 -0
- package/lib/transport.js +332 -0
- package/lib/types.d.ts +134 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +8 -0
- package/lib/update-surface.d.ts +79 -0
- package/lib/update-surface.d.ts.map +1 -0
- package/lib/update-surface.js +224 -0
- package/lib/version.d.ts +3 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +27 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contract-metadata.d.ts +13 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contract-metadata.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contract-metadata.js +85 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.d.ts +16 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.js +87 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts +38 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.js +445 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.d.ts +20 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.js +112 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts +14 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.js +63 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts +14 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.js +76 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts +82 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +274 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +26 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.js +53 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts +133 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.js +64 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +121 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +246 -0
- package/node_modules/@try-works/tool-mode-contracts/package.json +35 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/bin/dsh-tool-mode.mjs +20 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts +80 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.js +533 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts +86 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.js +145 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts +70 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.js +201 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts +57 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.js +83 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts +33 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.js +33 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts +86 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.js +191 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts +137 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.js +349 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts +274 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.js +932 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts +210 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.js +368 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts +63 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.js +149 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts +35 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.js +179 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts +179 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.js +299 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts +395 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.js +839 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts +44 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.js +255 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts +185 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.js +504 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts +17 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.js +80 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/licensing.d.ts +221 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/licensing.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/licensing.js +188 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts +52 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.js +102 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts +171 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.js +271 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts +242 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.js +58 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts +128 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.js +113 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/test-host.d.ts +41 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/test-host.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/test-host.js +52 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts +2 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.js +351 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts +157 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.js +688 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/package.json +54 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/schema/extension-manifest-1.1.0.schema.json +253 -0
- package/node_modules/@try-works/tool-mode-recipes/bin/tool-mode-recipe.mjs +15 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts +460 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.js +647 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts +61 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.js +1106 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts +237 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.js +205 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts +85 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.js +176 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts +119 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.js +201 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts +25 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.js +25 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts +345 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.js +1465 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts +51 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.js +310 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts +231 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.js +435 -0
- package/node_modules/@try-works/tool-mode-recipes/package.json +56 -0
- package/node_modules/@try-works/tool-mode-recipes/recipes/describe-image.json +38 -0
- package/node_modules/@try-works/tool-mode-recipes/recipes/text-title.json +45 -0
- package/node_modules/@try-works/tool-mode-recipes/schema/harness-model-recipe.schema.json +273 -0
- package/package.json +127 -4
- package/remote/spec.mjs +993 -0
- package/remote/typert.host.mjs +14 -0
- package/remote/typert.remote-client.mjs +16 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The operator-owned client credential store (SEC-01).
|
|
3
|
+
*
|
|
4
|
+
* SEC-01's generation clause: credentials are generated with high-entropy secrets,
|
|
5
|
+
* stored with suitable host protection (owner-only), and revocable independently per
|
|
6
|
+
* application. Before this module the OAuth client registry was in-memory only and the
|
|
7
|
+
* static-token mode accepted exactly one configured token — nothing could GENERATE a
|
|
8
|
+
* credential and nothing persisted it, so a restart lost every client and a generated
|
|
9
|
+
* secret could not exist.
|
|
10
|
+
*
|
|
11
|
+
* This store is the durable half. The security properties it now holds, each pinned
|
|
12
|
+
* by test:
|
|
13
|
+
*
|
|
14
|
+
* - one JSON document per deployment (`credentials.json`), written to a CRYPTO-RANDOM
|
|
15
|
+
* temp name opened EXCLUSIVELY (`wx`) — a predictable temp name is a hardlink target
|
|
16
|
+
* an attacker on the same account can pre-plant, so the name is unguessable and a
|
|
17
|
+
* pre-existing name FAILS instead of being overwritten — then fsync'd and atomically
|
|
18
|
+
* renamed over the document. A rename replaces a planted SYMLINK at the target rather
|
|
19
|
+
* than following it;
|
|
20
|
+
* - Windows: an EXPLICIT owner-only DACL is applied to the temp file BEFORE the rename
|
|
21
|
+
* (inheritance removed, the owner alone granted full control) and the store fails
|
|
22
|
+
* closed when the ACL cannot be secured. POSIX mode 0600 alone is not sufficient on
|
|
23
|
+
* Windows, and "the profile directory inherits it" is not a control;
|
|
24
|
+
* - MUTATIONS serialize through an in-process mutex AND an exclusive sidecar lock file,
|
|
25
|
+
* and re-read the document inside the critical section — two concurrent writers can
|
|
26
|
+
* no longer each persist a snapshot that silently drops the other's entry;
|
|
27
|
+
* - a CORRUPT or unreadable document makes MUTATIONS fail closed (a generation refused,
|
|
28
|
+
* the bytes untouched) while READS deny: authentication cannot succeed on a store
|
|
29
|
+
* the host cannot vouch for, and a generation can never overwrite a malformed
|
|
30
|
+
* document "as if empty". A MISSING document is the only empty start;
|
|
31
|
+
* - reads are served from the FILE, fresh on every lookup, so a revocation through any
|
|
32
|
+
* surface takes effect on the very next request;
|
|
33
|
+
* - `bySecret` matches STATIC-TOKEN credentials only: an OAuth resource-server secret
|
|
34
|
+
* presented as a static bearer must never authenticate through this path (scheme
|
|
35
|
+
* confusion);
|
|
36
|
+
* - the secret is compared CONSTANT-TIME (SHA-256 digests over equal-length input);
|
|
37
|
+
* - every mutation throws when it cannot persist: a generation that cannot be written
|
|
38
|
+
* must leave nothing usable rather than an in-memory-only credential that a restart
|
|
39
|
+
* silently forgets (fail-closed, SEC-01).
|
|
40
|
+
*
|
|
41
|
+
* @module @try-works/dsh-tool-mode/mcp/credential-store
|
|
42
|
+
*/
|
|
43
|
+
import { createHash, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
44
|
+
import { closeSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'node:fs';
|
|
45
|
+
import { spawnSync } from 'node:child_process';
|
|
46
|
+
import { basename, dirname, join, parse } from 'node:path';
|
|
47
|
+
import { homedir } from 'node:os';
|
|
48
|
+
/** A document that EXISTS but cannot be vouched for. Mutations refuse; reads deny. */
|
|
49
|
+
export class CorruptCredentialStoreError extends Error {
|
|
50
|
+
constructor(message) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = 'CorruptCredentialStoreError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate a fresh client credential directly over the store (the primitive
|
|
57
|
+
* the human-only CLI and tests use — the model-visible `model_tools` surface
|
|
58
|
+
* refuses generation entirely, SEC-01: the secret must never reach a model).
|
|
59
|
+
* @param store - the durable store.
|
|
60
|
+
* @param options - clientId (≤64 chars), scheme, scope.
|
|
61
|
+
* @returns the credential with the secret exactly once.
|
|
62
|
+
*/
|
|
63
|
+
export function generateCredential(store, options) {
|
|
64
|
+
if (typeof options.clientId !== 'string' || options.clientId.length === 0 || options.clientId.length > 64) {
|
|
65
|
+
throw new Error('clientId must be a non-empty string of at most 64 characters');
|
|
66
|
+
}
|
|
67
|
+
if (options.scheme !== 'static-token' && options.scheme !== 'oauth-resource-server') {
|
|
68
|
+
throw new Error('scheme must be static-token or oauth-resource-server');
|
|
69
|
+
}
|
|
70
|
+
if (store.get(options.clientId) !== undefined) {
|
|
71
|
+
throw new Error(`a credential for ${JSON.stringify(options.clientId)} already exists; revoke it first`);
|
|
72
|
+
}
|
|
73
|
+
const secret = randomBytes(32).toString('base64url');
|
|
74
|
+
const scope = options.scope === undefined || options.scope.length === 0 ? ['mcp:call'] : [...options.scope];
|
|
75
|
+
const createdAt = new Date().toISOString();
|
|
76
|
+
store.upsert({ clientId: options.clientId, secret, scheme: options.scheme, scope, createdAt });
|
|
77
|
+
return { clientId: options.clientId, secret, scheme: options.scheme, scope, createdAt };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Derive the default credential-store file, next to the host's own state
|
|
81
|
+
* (SEC-01: owner-only home protection).
|
|
82
|
+
* @param env - the environment to read; defaults to the process environment.
|
|
83
|
+
* @returns the absolute path.
|
|
84
|
+
*/
|
|
85
|
+
export function defaultCredentialStoreFile(env = process.env) {
|
|
86
|
+
const home = env.DSH_HOME !== undefined && env.DSH_HOME.length > 0
|
|
87
|
+
? env.DSH_HOME
|
|
88
|
+
: join(homedir(), '.dsh');
|
|
89
|
+
return join(home, 'model-as-tool', 'credentials.json');
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Apply an explicit owner-only DACL to one file on Windows (icacls: inheritance
|
|
93
|
+
* removed, the current owner alone granted full control), and fail closed when
|
|
94
|
+
* the ACL cannot be secured. On POSIX the caller's 0600 mode bits are the
|
|
95
|
+
* control and this is a no-op.
|
|
96
|
+
* @param file - the file to secure, BEFORE it is published (renamed) into place.
|
|
97
|
+
*/
|
|
98
|
+
export function applyOwnerOnlyDacl(file) {
|
|
99
|
+
if (process.platform !== 'win32')
|
|
100
|
+
return;
|
|
101
|
+
const owner = process.env.USERNAME;
|
|
102
|
+
if (owner === undefined || owner.length === 0) {
|
|
103
|
+
throw new Error('the credential file ACL cannot be secured: no Windows USERNAME to grant ownership to');
|
|
104
|
+
}
|
|
105
|
+
const result = spawnSync('icacls', [file, '/inheritance:r', '/grant:r', `${owner}:(F)`], {
|
|
106
|
+
windowsHide: true,
|
|
107
|
+
encoding: 'utf8',
|
|
108
|
+
});
|
|
109
|
+
if (result.status !== 0) {
|
|
110
|
+
throw new Error(`the credential file ACL cannot be secured: icacls failed with status ${result.status ?? 'unknown'}`
|
|
111
|
+
+ `: ${(result.stderr ?? result.stdout ?? '').trim()}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Refuse a reparse point (symlink or Windows junction) at a path the store is
|
|
116
|
+
* about to write THROUGH: a junctioned credential home is an untrusted target,
|
|
117
|
+
* and the store fails closed rather than persisting plaintext secrets into a
|
|
118
|
+
* location the operator did not own by construction.
|
|
119
|
+
* @param path - the directory (or file) to check.
|
|
120
|
+
*/
|
|
121
|
+
function assertNoReparsePoint(path) {
|
|
122
|
+
try {
|
|
123
|
+
if (lstatSync(path).isSymbolicLink()) {
|
|
124
|
+
throw new Error(`the credential store refuses ${path}: it is a symbolic link or junction (untrusted target)`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (error.code === 'ENOENT')
|
|
129
|
+
return;
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The trusted root the credential store lives under by default: DSH_HOME when
|
|
135
|
+
* set, otherwise `~/.dsh`. Ancestor validation walks from HERE down to the
|
|
136
|
+
* store directory — system junctions ABOVE the trusted root are never part of
|
|
137
|
+
* the trust question. A store outside the trusted root (an explicit --store)
|
|
138
|
+
* is validated from the filesystem root instead, and any reparse point in the
|
|
139
|
+
* chain fails it closed.
|
|
140
|
+
*/
|
|
141
|
+
function trustedCredentialRoot(env = process.env) {
|
|
142
|
+
return env.DSH_HOME !== undefined && env.DSH_HOME.length > 0
|
|
143
|
+
? env.DSH_HOME
|
|
144
|
+
: join(homedir(), '.dsh');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Walk EVERY ancestor component from the bounded trusted root down to the
|
|
148
|
+
* store directory and refuse any reparse point — not just the immediate parent:
|
|
149
|
+
* a junction higher in the chain redirects the whole write just as surely.
|
|
150
|
+
* @param file - the credential document path.
|
|
151
|
+
*/
|
|
152
|
+
function assertTrustedStoreAncestors(file) {
|
|
153
|
+
const dir = dirname(file);
|
|
154
|
+
const root = trustedCredentialRoot();
|
|
155
|
+
const start = dir === root || dir.startsWith(root + '\\') || dir.startsWith(root + '/')
|
|
156
|
+
? root
|
|
157
|
+
: parse(dir).root;
|
|
158
|
+
// Collect the ancestor chain from `start` down to `dir` (bounded by the path
|
|
159
|
+
// depth, which is small), then check each component that EXISTS.
|
|
160
|
+
const chain = [];
|
|
161
|
+
let cursor = dir;
|
|
162
|
+
while (cursor !== start && cursor !== parse(cursor).root && cursor.length > 0) {
|
|
163
|
+
chain.push(cursor);
|
|
164
|
+
const parent = dirname(cursor);
|
|
165
|
+
if (parent === cursor)
|
|
166
|
+
break;
|
|
167
|
+
cursor = parent;
|
|
168
|
+
}
|
|
169
|
+
chain.push(cursor);
|
|
170
|
+
for (const component of chain.reverse()) {
|
|
171
|
+
assertNoReparsePoint(component);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** Is the pid alive? `undefined` means "cannot tell" — callers fail closed. */
|
|
175
|
+
function isProcessAlive(pid) {
|
|
176
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
177
|
+
return undefined;
|
|
178
|
+
try {
|
|
179
|
+
process.kill(pid, 0);
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (error.code === 'ESRCH')
|
|
184
|
+
return false;
|
|
185
|
+
return undefined;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Read a lock record; undefined when the lock is unreadable or corrupt. */
|
|
189
|
+
function readLockRecord(lockPath) {
|
|
190
|
+
try {
|
|
191
|
+
const parsed = JSON.parse(readFileSync(lockPath, 'utf8'));
|
|
192
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
193
|
+
return undefined;
|
|
194
|
+
const candidate = parsed;
|
|
195
|
+
if (typeof candidate.token !== 'string' || candidate.token.length === 0
|
|
196
|
+
|| typeof candidate.pid !== 'number' || typeof candidate.at !== 'number') {
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
return { token: candidate.token, pid: candidate.pid, at: candidate.at };
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** A real blocking sleep, without burning the CPU. */
|
|
206
|
+
function sleep(ms) {
|
|
207
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Create (or open) the file-backed credential store.
|
|
211
|
+
* @param file - the absolute path of the credentials document.
|
|
212
|
+
* @param hooks - TEST-ONLY lock hooks; production passes nothing.
|
|
213
|
+
* @returns the store.
|
|
214
|
+
*/
|
|
215
|
+
export function createFileCredentialStore(file, hooks = {}) {
|
|
216
|
+
const staleLockMs = hooks.staleLockMs ?? 30_000;
|
|
217
|
+
const lockDeadlineMs = hooks.lockDeadlineMs ?? 10_000;
|
|
218
|
+
const probeAlive = hooks.isProcessAlive ?? isProcessAlive;
|
|
219
|
+
/**
|
|
220
|
+
* The cross-process lock: an unguessable ownership token plus the holder's
|
|
221
|
+
* pid, so a stale lock is only ever stolen from a holder PROVEN DEAD. A live
|
|
222
|
+
* holder is never stolen from, unknown liveness fails closed (the contender
|
|
223
|
+
* keeps waiting, then refuses), and release removes ONLY a token-owned lock
|
|
224
|
+
* — a successor's lock is never touched.
|
|
225
|
+
*/
|
|
226
|
+
const acquireFileLock = () => {
|
|
227
|
+
const lockPath = `${file}.lock`;
|
|
228
|
+
const token = randomBytes(16).toString('hex');
|
|
229
|
+
const deadline = Date.now() + lockDeadlineMs;
|
|
230
|
+
for (;;) {
|
|
231
|
+
try {
|
|
232
|
+
const fd = openSync(lockPath, 'wx');
|
|
233
|
+
try {
|
|
234
|
+
writeFileSync(fd, JSON.stringify({ token, pid: process.pid, at: Date.now() }), 'utf8');
|
|
235
|
+
}
|
|
236
|
+
finally {
|
|
237
|
+
closeSync(fd);
|
|
238
|
+
}
|
|
239
|
+
const release = () => {
|
|
240
|
+
// Release ONLY a token-owned lock: if the record no longer carries OUR
|
|
241
|
+
// token, the lock is a successor's (or was removed) — never remove it.
|
|
242
|
+
const held = readLockRecord(lockPath);
|
|
243
|
+
if (held === undefined || held.token !== token)
|
|
244
|
+
return;
|
|
245
|
+
try {
|
|
246
|
+
rmSync(lockPath, { force: true });
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
// Already gone: nothing to release.
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
return { token, release };
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
const code = error.code;
|
|
256
|
+
/**
|
|
257
|
+
* Windows reports EPERM rather than EEXIST when `open(..., 'wx')` loses the
|
|
258
|
+
* race to an existing lock file (the two-process test caught this as an
|
|
259
|
+
* occasional hard failure). Both mean "somebody holds it": treat EPERM as
|
|
260
|
+
* contention and let the normal holder/stale logic decide, never as a
|
|
261
|
+
* permanent failure that drops a writer.
|
|
262
|
+
*/
|
|
263
|
+
if (code !== 'EEXIST' && code !== 'EPERM')
|
|
264
|
+
throw error;
|
|
265
|
+
// A held lock: examine WHO holds it before even considering theft.
|
|
266
|
+
const held = readLockRecord(lockPath);
|
|
267
|
+
if (held !== undefined) {
|
|
268
|
+
const age = Date.now() - held.at;
|
|
269
|
+
const alive = probeAlive(held.pid);
|
|
270
|
+
if (alive === false && age > staleLockMs) {
|
|
271
|
+
// The holder is PROVEN DEAD and the lock is stale: take it over.
|
|
272
|
+
// (An unreadable/corrupt record is NOT this case — fail closed below.)
|
|
273
|
+
try {
|
|
274
|
+
rmSync(lockPath, { force: true });
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
// Released between the read and the removal: retry the acquire.
|
|
278
|
+
}
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
// A LIVE holder (or unknown liveness) is never stolen from — the
|
|
282
|
+
// contender waits, then fails closed at the deadline.
|
|
283
|
+
}
|
|
284
|
+
if (Date.now() > deadline) {
|
|
285
|
+
throw new Error('the credential store is locked by another writer; the mutation was not attempted');
|
|
286
|
+
}
|
|
287
|
+
sleep(25);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
};
|
|
291
|
+
/** Read the CURRENT document. STRICT for mutations: corruption refuses them. */
|
|
292
|
+
const read = (strict) => {
|
|
293
|
+
let text;
|
|
294
|
+
try {
|
|
295
|
+
text = readFileSync(file, 'utf8');
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
if (error.code === 'ENOENT') {
|
|
299
|
+
// A MISSING document is the only empty start. Nothing else is.
|
|
300
|
+
return new Map();
|
|
301
|
+
}
|
|
302
|
+
if (strict) {
|
|
303
|
+
throw new CorruptCredentialStoreError(`the credentials document cannot be read and no mutation will guess its contents: `
|
|
304
|
+
+ `${error instanceof Error ? error.message : String(error)}`);
|
|
305
|
+
}
|
|
306
|
+
return new Map();
|
|
307
|
+
}
|
|
308
|
+
let parsed;
|
|
309
|
+
try {
|
|
310
|
+
parsed = JSON.parse(text);
|
|
311
|
+
}
|
|
312
|
+
catch (error) {
|
|
313
|
+
if (strict) {
|
|
314
|
+
throw new CorruptCredentialStoreError(`the credentials document is not valid JSON and will not be overwritten as if empty: `
|
|
315
|
+
+ `${error instanceof Error ? error.message : String(error)}`);
|
|
316
|
+
}
|
|
317
|
+
return new Map();
|
|
318
|
+
}
|
|
319
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
320
|
+
if (strict)
|
|
321
|
+
throw new CorruptCredentialStoreError('the credentials document is not a JSON object');
|
|
322
|
+
return new Map();
|
|
323
|
+
}
|
|
324
|
+
const document = parsed;
|
|
325
|
+
if (!Array.isArray(document.clients)) {
|
|
326
|
+
if (strict)
|
|
327
|
+
throw new CorruptCredentialStoreError('the credentials document has no clients array');
|
|
328
|
+
return new Map();
|
|
329
|
+
}
|
|
330
|
+
const next = new Map();
|
|
331
|
+
for (const entry of document.clients) {
|
|
332
|
+
const candidate = entry;
|
|
333
|
+
if (typeof candidate.clientId !== 'string' || typeof candidate.secret !== 'string'
|
|
334
|
+
|| (candidate.scheme !== 'static-token' && candidate.scheme !== 'oauth-resource-server')
|
|
335
|
+
|| !Array.isArray(candidate.scope)) {
|
|
336
|
+
// A malformed ENTRY corrupts the document: a mutation would silently drop
|
|
337
|
+
// it on the next persist, and authentication cannot vouch for it either.
|
|
338
|
+
if (strict) {
|
|
339
|
+
throw new CorruptCredentialStoreError(`the credentials document carries a malformed client entry (id ${JSON.stringify(candidate.clientId)})`);
|
|
340
|
+
}
|
|
341
|
+
return new Map();
|
|
342
|
+
}
|
|
343
|
+
next.set(candidate.clientId, candidate);
|
|
344
|
+
}
|
|
345
|
+
return next;
|
|
346
|
+
};
|
|
347
|
+
const persist = (clients, token) => {
|
|
348
|
+
const document = {
|
|
349
|
+
version: 1,
|
|
350
|
+
clients: [...clients.values()],
|
|
351
|
+
};
|
|
352
|
+
// SEC-01: the temp name is crypto-random and opened EXCLUSIVELY — a planted
|
|
353
|
+
// hardlink/symlink at a predictable name cannot be overwritten, and a
|
|
354
|
+
// pre-existing name fails the write instead of clobbering an unrelated file.
|
|
355
|
+
const temp = join(dirname(file), `.${basename(file)}.tmp-${randomBytes(12).toString('hex')}`);
|
|
356
|
+
const fd = openSync(temp, 'wx', 0o600);
|
|
357
|
+
try {
|
|
358
|
+
// The file WE created must be a regular file: 'wx' already excludes
|
|
359
|
+
// pre-existing entries (hardlinks and junctions included); this is the
|
|
360
|
+
// belt-and-braces check.
|
|
361
|
+
const created = lstatSync(temp);
|
|
362
|
+
if (!created.isFile() || created.isSymbolicLink()) {
|
|
363
|
+
throw new Error(`the credential temp file is not a regular file: refusing to write plaintext secrets through it`);
|
|
364
|
+
}
|
|
365
|
+
// Owner-only BEFORE the first secret byte: the empty file's ACL is
|
|
366
|
+
// secured while it holds NOTHING, so no plaintext ever exists under an
|
|
367
|
+
// inherited broad ACL (the reviewer's inherited Everyone:R +
|
|
368
|
+
// Authenticated Users:M finding).
|
|
369
|
+
applyOwnerOnlyDacl(temp);
|
|
370
|
+
writeFileSync(fd, JSON.stringify(document, null, 2), 'utf8');
|
|
371
|
+
fsyncSync(fd);
|
|
372
|
+
}
|
|
373
|
+
finally {
|
|
374
|
+
closeSync(fd);
|
|
375
|
+
}
|
|
376
|
+
// The publish is refused unless OUR token still owns the lock: a writer
|
|
377
|
+
// that somehow lost its lock must never publish a stale snapshot over the
|
|
378
|
+
// successor's state.
|
|
379
|
+
const held = readLockRecord(`${file}.lock`);
|
|
380
|
+
if (held === undefined || held.token !== token) {
|
|
381
|
+
rmSync(temp, { force: true });
|
|
382
|
+
throw new Error('the credential store lost its write lock; the publish is refused');
|
|
383
|
+
}
|
|
384
|
+
renameSync(temp, file);
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* One serialized mutation: the ancestor chain is checked for reparse points
|
|
388
|
+
* BEFORE anything (lock file included) is written through it, the parent
|
|
389
|
+
* directory is created (a first-generation store starts from nothing), then
|
|
390
|
+
* the file lock excludes other processes and the read-modify-write runs
|
|
391
|
+
* fully SYNCHRONOUSLY inside it — Node's single thread makes the section
|
|
392
|
+
* atomic for this process too, so two concurrent writers cannot each persist
|
|
393
|
+
* a snapshot that drops the other's entry or resurrects a just-revoked
|
|
394
|
+
* credential.
|
|
395
|
+
*/
|
|
396
|
+
const mutation = (body) => {
|
|
397
|
+
assertTrustedStoreAncestors(file);
|
|
398
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
399
|
+
const { token, release } = acquireFileLock();
|
|
400
|
+
try {
|
|
401
|
+
const clients = read(true);
|
|
402
|
+
// TEST-ONLY: simulate a writer paused after its strict read, holding the
|
|
403
|
+
// lock while other processes contend (the reviewer's 31 s repro, without
|
|
404
|
+
// the wait).
|
|
405
|
+
if (hooks.holdLockAfterReadMs !== undefined)
|
|
406
|
+
sleep(hooks.holdLockAfterReadMs);
|
|
407
|
+
return body(clients, token);
|
|
408
|
+
}
|
|
409
|
+
finally {
|
|
410
|
+
release();
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
return {
|
|
414
|
+
file,
|
|
415
|
+
list() {
|
|
416
|
+
// Reads DENY on corruption (empty list) rather than crash the auth path.
|
|
417
|
+
return [...read(false).values()];
|
|
418
|
+
},
|
|
419
|
+
get(clientId) {
|
|
420
|
+
return read(false).get(clientId);
|
|
421
|
+
},
|
|
422
|
+
bySecret(secret) {
|
|
423
|
+
// CONSTANT-TIME over the STATIC-TOKEN entries: the digest equalizes lengths,
|
|
424
|
+
// and the loop never exits early on a match. OAuth resource-server secrets
|
|
425
|
+
// are NEVER matched here — scheme confusion would let an OAuth secret pass
|
|
426
|
+
// as a static bearer.
|
|
427
|
+
const digest = createHash('sha256').update(secret).digest();
|
|
428
|
+
let found;
|
|
429
|
+
for (const candidate of read(false).values()) {
|
|
430
|
+
if (candidate.scheme !== 'static-token')
|
|
431
|
+
continue;
|
|
432
|
+
const candidateDigest = createHash('sha256').update(candidate.secret).digest();
|
|
433
|
+
if (timingSafeEqual(digest, candidateDigest))
|
|
434
|
+
found = candidate;
|
|
435
|
+
}
|
|
436
|
+
return found;
|
|
437
|
+
},
|
|
438
|
+
upsert(credential) {
|
|
439
|
+
mutation((clients, token) => {
|
|
440
|
+
// PERSIST FIRST inside the critical section: a credential that cannot be
|
|
441
|
+
// written must never be registered as usable anywhere (SEC-01).
|
|
442
|
+
clients.set(credential.clientId, credential);
|
|
443
|
+
persist(clients, token);
|
|
444
|
+
});
|
|
445
|
+
},
|
|
446
|
+
delete(clientId) {
|
|
447
|
+
mutation((clients, token) => {
|
|
448
|
+
if (!clients.has(clientId))
|
|
449
|
+
return;
|
|
450
|
+
clients.delete(clientId);
|
|
451
|
+
persist(clients, token);
|
|
452
|
+
});
|
|
453
|
+
},
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
/** Remove a credential store file, for tests that need a fresh deployment. */
|
|
457
|
+
export function removeCredentialStoreFile(file) {
|
|
458
|
+
rmSync(file, { force: true });
|
|
459
|
+
rmSync(`${file}.lock`, { force: true });
|
|
460
|
+
}
|
|
461
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BASE-06 — the MCP export allowlist is a separate control from the native
|
|
3
|
+
* `models` selection.
|
|
4
|
+
*
|
|
5
|
+
* `undefined` or a list containing `*` means the deployment did not configure a
|
|
6
|
+
* separate MCP allowlist and preserves the existing surface. An EMPTY allowlist is
|
|
7
|
+
* meaningful: it exports no inference tools. A named allowlist admits exactly those
|
|
8
|
+
* names.
|
|
9
|
+
*
|
|
10
|
+
* Denied rows are returned as WITHHELD rows (with a reason) rather than removed,
|
|
11
|
+
* so the existing MCP host status surface can explain why a tool is absent.
|
|
12
|
+
*
|
|
13
|
+
* @module @try-works/dsh-tool-mode/mcp/export-policy
|
|
14
|
+
*/
|
|
15
|
+
import type { PublishedTool } from './host-binding.ts';
|
|
16
|
+
/** The stable reason recorded for a tool denied by the allowlist. */
|
|
17
|
+
export declare const MCP_EXPORT_DENIED_REASON = "the MCP export allowlist does not name this tool";
|
|
18
|
+
/**
|
|
19
|
+
* Apply the operator's MCP export allowlist to the assembled publication surface.
|
|
20
|
+
* @param published - every tool the host could publish.
|
|
21
|
+
* @param allowlist - configured names; undefined means no separate MCP restriction.
|
|
22
|
+
* @returns the same rows, with denied rows carrying a withholding reason.
|
|
23
|
+
*/
|
|
24
|
+
export declare function applyMcpExportPolicy(published: readonly PublishedTool[], allowlist: readonly string[] | undefined): readonly PublishedTool[];
|
|
25
|
+
//# sourceMappingURL=export-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export-policy.d.ts","sourceRoot":"","sources":["../../src/mcp/export-policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAEtD,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,qDAAqD,CAAA;AAE1F;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,SAAS,aAAa,EAAE,EACnC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,SAAS,aAAa,EAAE,CAM1B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BASE-06 — the MCP export allowlist is a separate control from the native
|
|
3
|
+
* `models` selection.
|
|
4
|
+
*
|
|
5
|
+
* `undefined` or a list containing `*` means the deployment did not configure a
|
|
6
|
+
* separate MCP allowlist and preserves the existing surface. An EMPTY allowlist is
|
|
7
|
+
* meaningful: it exports no inference tools. A named allowlist admits exactly those
|
|
8
|
+
* names.
|
|
9
|
+
*
|
|
10
|
+
* Denied rows are returned as WITHHELD rows (with a reason) rather than removed,
|
|
11
|
+
* so the existing MCP host status surface can explain why a tool is absent.
|
|
12
|
+
*
|
|
13
|
+
* @module @try-works/dsh-tool-mode/mcp/export-policy
|
|
14
|
+
*/
|
|
15
|
+
/** The stable reason recorded for a tool denied by the allowlist. */
|
|
16
|
+
export const MCP_EXPORT_DENIED_REASON = 'the MCP export allowlist does not name this tool';
|
|
17
|
+
/**
|
|
18
|
+
* Apply the operator's MCP export allowlist to the assembled publication surface.
|
|
19
|
+
* @param published - every tool the host could publish.
|
|
20
|
+
* @param allowlist - configured names; undefined means no separate MCP restriction.
|
|
21
|
+
* @returns the same rows, with denied rows carrying a withholding reason.
|
|
22
|
+
*/
|
|
23
|
+
export function applyMcpExportPolicy(published, allowlist) {
|
|
24
|
+
if (allowlist === undefined || allowlist.includes('*'))
|
|
25
|
+
return published;
|
|
26
|
+
const allowed = new Set(allowlist);
|
|
27
|
+
return published.map(tool => allowed.has(tool.toolName)
|
|
28
|
+
? tool
|
|
29
|
+
: { ...tool, notExportableReason: MCP_EXPORT_DENIED_REASON });
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=export-policy.js.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Binding the MCP surface to the real DSH tool registry (MCP-08, MCP-09, MCP-12).
|
|
3
|
+
*
|
|
4
|
+
* Two requirements shape this module, and both are about where data comes from
|
|
5
|
+
* rather than what it looks like:
|
|
6
|
+
*
|
|
7
|
+
* - **MCP-09**: DSH's model-facing `schemas()` projection INTENTIONALLY omits the
|
|
8
|
+
* output schema, so an export built from it would publish a tool with no declared
|
|
9
|
+
* result shape. The canonical schemas therefore come from the CONTRACTS, which is
|
|
10
|
+
* the only place that has them; `schemas()` is never consulted for a schema.
|
|
11
|
+
* - **MCP-08**: invocation goes through the host's `execute` path with a
|
|
12
|
+
* server-issued call identity and the caller's abort signal. Resolving a tool and
|
|
13
|
+
* calling it directly would bypass the grant, the receipt and the result policy —
|
|
14
|
+
* the three things the host path exists to apply — so this module is given an
|
|
15
|
+
* executor rather than a registry to reach into.
|
|
16
|
+
*
|
|
17
|
+
* §16.4 defines the payload derivation precisely: an implementation returns the
|
|
18
|
+
* domain payload with the reserved root `meta` OMITTED, and the payload schema is
|
|
19
|
+
* the final tool schema with only that property and its required entry removed.
|
|
20
|
+
* Everything else is preserved, because a schema that quietly dropped more would
|
|
21
|
+
* under-declare the result.
|
|
22
|
+
*
|
|
23
|
+
* @module @try-works/dsh-tool-mode/mcp/host-binding
|
|
24
|
+
*/
|
|
25
|
+
import type { ToolContract } from '@try-works/tool-mode-contracts';
|
|
26
|
+
import type { ExternalCaller } from './client-grant.ts';
|
|
27
|
+
import type { McpHost } from './server.ts';
|
|
28
|
+
import { type InvocationAccounting } from '../invocation-accounting.ts';
|
|
29
|
+
/**
|
|
30
|
+
* Derive the payload schema from a contract's final output schema (§16.4).
|
|
31
|
+
*
|
|
32
|
+
* Only the reserved `meta` property and its `required` entry are removed. The rest
|
|
33
|
+
* of the schema — including constraints on the remaining properties — is preserved
|
|
34
|
+
* verbatim, because removing anything else would advertise a looser result than the
|
|
35
|
+
* contract actually enforces.
|
|
36
|
+
* @param outputSchema - the contract's output schema, including `meta`.
|
|
37
|
+
* @returns the payload schema.
|
|
38
|
+
*/
|
|
39
|
+
export declare function derivePayloadSchema(outputSchema: Readonly<Record<string, unknown>>): Record<string, unknown>;
|
|
40
|
+
/** One published tool as the host knows it. */
|
|
41
|
+
export interface PublishedTool {
|
|
42
|
+
/** The tool name a caller uses. */
|
|
43
|
+
readonly toolName: string;
|
|
44
|
+
/** The contract it implements, which carries the canonical schemas. */
|
|
45
|
+
readonly contract: ToolContract;
|
|
46
|
+
/**
|
|
47
|
+
* Why this tool is not exportable, when it is not (MCP-12).
|
|
48
|
+
*
|
|
49
|
+
* A host tool using a non-JSON callback, a UI-only API, an unsupported attachment
|
|
50
|
+
* or a non-exportable policy must be REJECTED WITH A REASON rather than partly
|
|
51
|
+
* serialized, so the reason travels with the tool instead of being discovered by a
|
|
52
|
+
* caller whose call fails in a way nobody can explain.
|
|
53
|
+
*/
|
|
54
|
+
readonly notExportableReason?: string;
|
|
55
|
+
}
|
|
56
|
+
/** What the binding needs from the host. */
|
|
57
|
+
export interface HostSurface {
|
|
58
|
+
/** The tools the host currently publishes. */
|
|
59
|
+
readonly published: readonly PublishedTool[];
|
|
60
|
+
/**
|
|
61
|
+
* Tools the host deliberately WITHHELD, by name, with the recorded reason (MCP-12).
|
|
62
|
+
*
|
|
63
|
+
* A caller that guesses a withheld name must learn why it is absent rather than
|
|
64
|
+
* receiving the same `unknown tool` answer as a name that never existed. The map
|
|
65
|
+
* is the publication decision, not a second lookup: it may include names omitted
|
|
66
|
+
* from `published` entirely.
|
|
67
|
+
*/
|
|
68
|
+
readonly withheld?: ReadonlyMap<string, string>;
|
|
69
|
+
/**
|
|
70
|
+
* Execute one tool through the host path (MCP-08).
|
|
71
|
+
*
|
|
72
|
+
* Takes a server-issued call identity and the caller's signal; the implementation
|
|
73
|
+
* MUST route this through the same execution path a native call uses.
|
|
74
|
+
*/
|
|
75
|
+
execute(request: {
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly arguments: Readonly<Record<string, unknown>>;
|
|
78
|
+
readonly signal: AbortSignal;
|
|
79
|
+
/** Server-issued. A caller-supplied id would let a caller forge a receipt. */
|
|
80
|
+
readonly callId: string;
|
|
81
|
+
/**
|
|
82
|
+
* The AUTHENTICATED external caller and its derived grant (SEC-04).
|
|
83
|
+
*
|
|
84
|
+
* Absent for calls with no client identity (native paths). When present, the
|
|
85
|
+
* implementation MUST authorize the call against THIS caller's grant rather than
|
|
86
|
+
* the host's own — an external client is not the operator.
|
|
87
|
+
*/
|
|
88
|
+
readonly caller?: ExternalCaller;
|
|
89
|
+
}): Promise<{
|
|
90
|
+
readonly isError: boolean;
|
|
91
|
+
readonly value?: unknown;
|
|
92
|
+
readonly message?: string;
|
|
93
|
+
}>;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build the MCP host surface over a DSH tool surface.
|
|
97
|
+
*
|
|
98
|
+
* @param options - the host surface and this server's identity.
|
|
99
|
+
* @returns the MCP host the dispatch layer consumes.
|
|
100
|
+
*/
|
|
101
|
+
export declare function createMcpHost(options: {
|
|
102
|
+
readonly surface: HostSurface;
|
|
103
|
+
readonly serverInfo: {
|
|
104
|
+
readonly name: string;
|
|
105
|
+
readonly version: string;
|
|
106
|
+
};
|
|
107
|
+
/** Called for each tool withheld, so a reason is recorded rather than lost. */
|
|
108
|
+
readonly onWithheld?: (tool: PublishedTool) => void;
|
|
109
|
+
/**
|
|
110
|
+
* Called once per EXTERNAL invocation, with its accounting (OBS-02).
|
|
111
|
+
*
|
|
112
|
+
* Wired EXPLICITLY because an external call is not automatically an agent-loop
|
|
113
|
+
* transcript: DSH observes `ctx.tools.execute`, and an MCP caller reaches the same
|
|
114
|
+
* pipeline through a different door. Without this the external half of the traffic has
|
|
115
|
+
* no receipt at all.
|
|
116
|
+
*
|
|
117
|
+
* It receives TIMINGS, A CLASS and SIZES — never the payload. The result is deliberately
|
|
118
|
+
* NOT passed in, so an implementation of this hook cannot duplicate a large result into a
|
|
119
|
+
* second log, which is the other half of what OBS-02 forbids.
|
|
120
|
+
*
|
|
121
|
+
* The invoked TOOL NAME rides alongside the accounting (task-13): external MCP calls are
|
|
122
|
+
* not session events, so a ledger that answers "which tools were used over MCP" needs
|
|
123
|
+
* the name here rather than re-deriving it from a session log that does not exist.
|
|
124
|
+
*/
|
|
125
|
+
readonly onAccounted?: (accounting: InvocationAccounting, toolName: string) => void;
|
|
126
|
+
/** The engine that served the call, recorded WITH the measurement (OBS-05). */
|
|
127
|
+
readonly engineVersion?: string;
|
|
128
|
+
/** Operator-blocked confidential tools (MCP-11); refused before lookup/execution. */
|
|
129
|
+
readonly confidentialTools?: readonly string[];
|
|
130
|
+
/**
|
|
131
|
+
* The catalog caching policy carried on `tools/list` and `server/discover` (P26-14).
|
|
132
|
+
*
|
|
133
|
+
* Accepted as the UNVALIDATED config shape and validated HERE, once, so a bad
|
|
134
|
+
* operator value is refused with a named error at construction rather than surfacing
|
|
135
|
+
* as a per-request failure. Absent = private/0.
|
|
136
|
+
*/
|
|
137
|
+
readonly cachePolicy?: {
|
|
138
|
+
readonly ttlMs?: number;
|
|
139
|
+
readonly cacheScope?: string;
|
|
140
|
+
};
|
|
141
|
+
/** Explicit catalog facts attached to discovery results (P26-14). */
|
|
142
|
+
readonly catalogFacts?: () => Record<string, unknown>;
|
|
143
|
+
}): McpHost;
|
|
144
|
+
//# sourceMappingURL=host-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-binding.d.ts","sourceRoot":"","sources":["../../src/mcp/host-binding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAGlE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAA4C,MAAM,aAAa,CAAA;AACpF,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAA;AAsBpC;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC9C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B;;;;;;;OAOG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CACtC;AA+CD,4CAA4C;AAC5C,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAA;IAC5C;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/C;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE;QACf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;QACrB,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;QACrD,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;QAC5B,8EAA8E;QAC9E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB;;;;;;WAMG;QACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAA;KACjC,GAAG,OAAO,CAAC;QACV,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;QACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;QACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAC,CAAA;CACH;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACxE,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAA;IACnD;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,UAAU,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IACnF,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,qFAAqF;IACrF,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC9C;;;;;;OAMG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChF,qEAAqE;IACrE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACtD,GAAG,OAAO,CA2JV"}
|