@deepseek-harness-tui/dsh-tui 0.7.3 → 0.8.1
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 +15 -7
- package/bin/dsh-tui.js +19 -3
- package/cordis.patch.yml +43 -11
- package/cordis.yml +20 -1
- package/ecosystem-spec/registry/contracts/decision-events-v1alpha1.json +13 -0
- package/ecosystem-spec/registry/host-descriptor.tui.example.json +56 -0
- package/ecosystem-spec/registry/permissions-0.1.json +13 -0
- package/ecosystem-spec/registry/registry-0.15.json +57 -0
- package/ecosystem-spec/schemas/conformance-claim.schema.json +15 -0
- package/ecosystem-spec/schemas/effect-ledger-record.schema.json +16 -0
- package/ecosystem-spec/schemas/host-descriptor.schema.json +26 -0
- package/lib/types/cc/figures.d.ts +4 -0
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +4 -0
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +4 -1
- package/lib/types/components/ExtensionDialog.d.ts +40 -0
- package/lib/types/components/ExtensionDialog.d.ts.map +1 -0
- package/lib/types/components/ExtensionDialog.js +210 -0
- package/lib/types/components/HelpMenu.js +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts +5 -10
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +7 -18
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +1 -2
- package/lib/types/components/MessageList.d.ts +3 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +29 -5
- package/lib/types/components/PluginSceneBoundary.d.ts +31 -0
- package/lib/types/components/PluginSceneBoundary.d.ts.map +1 -0
- package/lib/types/components/PluginSceneBoundary.js +29 -0
- package/lib/types/components/RewindPicker.d.ts +13 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +26 -2
- package/lib/types/components/SkillsPicker.d.ts +18 -0
- package/lib/types/components/SkillsPicker.d.ts.map +1 -0
- package/lib/types/components/SkillsPicker.js +50 -0
- package/lib/types/components/SplitDiffView.d.ts +28 -0
- package/lib/types/components/SplitDiffView.d.ts.map +1 -0
- package/lib/types/components/SplitDiffView.js +417 -0
- package/lib/types/components/ToolUseLoader.d.ts +8 -3
- package/lib/types/components/ToolUseLoader.d.ts.map +1 -1
- package/lib/types/components/ToolUseLoader.js +43 -9
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +3 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +17 -7
- package/lib/types/dsh-adapter/channel.d.ts +98 -7
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +623 -26
- package/lib/types/dsh-adapter/command-attribution.d.ts +51 -0
- package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-attribution.js +93 -0
- package/lib/types/dsh-adapter/command-errors.d.ts +42 -0
- package/lib/types/dsh-adapter/command-errors.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-errors.js +63 -0
- package/lib/types/dsh-adapter/component-identity.d.ts +28 -0
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -0
- package/lib/types/dsh-adapter/component-identity.js +108 -0
- package/lib/types/dsh-adapter/contract.d.ts +2 -2
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +3 -2
- package/lib/types/dsh-adapter/decision-guard.d.ts +84 -0
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/decision-guard.js +354 -0
- package/lib/types/dsh-adapter/dialogs.d.ts +146 -0
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -0
- package/lib/types/dsh-adapter/dialogs.js +262 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts +99 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -0
- package/lib/types/dsh-adapter/effect-ledger.js +231 -0
- package/lib/types/dsh-adapter/extension-events.d.ts +193 -0
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extension-events.js +169 -0
- package/lib/types/dsh-adapter/extensions.d.ts +32 -0
- package/lib/types/dsh-adapter/extensions.d.ts.map +1 -0
- package/lib/types/dsh-adapter/extensions.js +42 -0
- package/lib/types/dsh-adapter/grants.d.ts +25 -0
- package/lib/types/dsh-adapter/grants.d.ts.map +1 -0
- package/lib/types/dsh-adapter/grants.js +184 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts +24 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-descriptor.js +146 -0
- package/lib/types/dsh-adapter/index.d.ts +4 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +1 -0
- package/lib/types/dsh-adapter/message-observer.d.ts +178 -0
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -0
- package/lib/types/dsh-adapter/message-observer.js +509 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts +103 -0
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-host.js +270 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts +113 -0
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-storage.js +385 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +106 -1
- package/lib/types/dsh-adapter/plugins-info.d.ts +43 -0
- package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugins-info.js +276 -0
- package/lib/types/dsh-adapter/promptDebug.d.ts +10 -0
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -0
- package/lib/types/dsh-adapter/promptDebug.js +148 -0
- package/lib/types/dsh-adapter/renderers.d.ts +65 -0
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -0
- package/lib/types/dsh-adapter/renderers.js +138 -0
- package/lib/types/dsh-adapter/sanitize.d.ts +36 -0
- package/lib/types/dsh-adapter/sanitize.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sanitize.js +65 -0
- package/lib/types/dsh-adapter/scenes.d.ts +81 -0
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -0
- package/lib/types/dsh-adapter/scenes.js +93 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts +116 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settings-sections.js +63 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts +128 -0
- package/lib/types/dsh-adapter/settingsEditor.d.ts.map +1 -0
- package/lib/types/dsh-adapter/settingsEditor.js +244 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts +109 -0
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -0
- package/lib/types/dsh-adapter/shortcuts.js +268 -0
- package/lib/types/dsh-adapter/status.d.ts +75 -0
- package/lib/types/dsh-adapter/status.d.ts.map +1 -0
- package/lib/types/dsh-adapter/status.js +168 -0
- package/lib/types/extensions.d.ts +8 -0
- package/lib/types/extensions.d.ts.map +1 -0
- package/lib/types/extensions.js +15 -0
- package/lib/types/i18n.d.ts +299 -26
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +89 -8
- package/lib/types/ink/ink.d.ts +11 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +33 -0
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +101 -51
- package/lib/types/ink/output.d.ts +7 -0
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +125 -4
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -1
- package/lib/types/ink/render-node-to-output.js +14 -6
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +18 -6
- package/lib/types/jsx-runtime.d.ts +2 -0
- package/lib/types/jsx-runtime.d.ts.map +1 -0
- package/lib/types/jsx-runtime.js +13 -0
- package/lib/types/modelRoute.d.ts +10 -2
- package/lib/types/modelRoute.d.ts.map +1 -1
- package/lib/types/modelRoute.js +33 -4
- package/lib/types/plugin-host.d.ts +13 -0
- package/lib/types/plugin-host.d.ts.map +1 -0
- package/lib/types/plugin-host.js +17 -0
- package/lib/types/plugin-spec/negotiate.d.ts +11 -0
- package/lib/types/plugin-spec/negotiate.d.ts.map +1 -0
- package/lib/types/plugin-spec/negotiate.js +97 -0
- package/lib/types/plugin-spec/permission-scope.d.ts +32 -0
- package/lib/types/plugin-spec/permission-scope.d.ts.map +1 -0
- package/lib/types/plugin-spec/permission-scope.js +90 -0
- package/lib/types/plugin-spec/registry.d.ts +23 -0
- package/lib/types/plugin-spec/registry.d.ts.map +1 -0
- package/lib/types/plugin-spec/registry.js +157 -0
- package/lib/types/plugin-spec/schema-check.d.ts +17 -0
- package/lib/types/plugin-spec/schema-check.d.ts.map +1 -0
- package/lib/types/plugin-spec/schema-check.js +165 -0
- package/lib/types/plugin-spec/tui-extension.d.ts +16 -0
- package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -0
- package/lib/types/plugin-spec/tui-extension.js +77 -0
- package/lib/types/plugin-spec/types.d.ts +114 -0
- package/lib/types/plugin-spec/types.d.ts.map +1 -0
- package/lib/types/plugin-spec/types.js +10 -0
- package/lib/types/plugin-spec/validate.d.ts +21 -0
- package/lib/types/plugin-spec/validate.d.ts.map +1 -0
- package/lib/types/plugin-spec/validate.js +119 -0
- package/lib/types/scenes.d.ts +3 -0
- package/lib/types/scenes.d.ts.map +1 -0
- package/lib/types/scenes.js +4 -0
- package/lib/types/screens/Chat.d.ts +14 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +247 -48
- package/lib/types/screens/Settings.d.ts +20 -0
- package/lib/types/screens/Settings.d.ts.map +1 -0
- package/lib/types/screens/Settings.js +333 -0
- package/lib/types/screens/StatusLine.js +1 -1
- package/lib/types/settings-sections.d.ts +3 -0
- package/lib/types/settings-sections.d.ts.map +1 -0
- package/lib/types/settings-sections.js +4 -0
- package/lib/types/theme.d.ts +17 -0
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +51 -0
- package/lib/types/update.d.ts +20 -0
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +54 -7
- package/lib/types/utils/loaded-context.d.ts +8 -3
- package/lib/types/utils/loaded-context.d.ts.map +1 -1
- package/lib/types/utils/loaded-context.js +39 -3
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +3 -2
- package/lib/types/working-activity.d.ts +12 -0
- package/lib/types/working-activity.d.ts.map +1 -1
- package/lib/types/working-activity.js +13 -0
- package/node_modules/@dsh-std/command/LICENSE +21 -0
- package/node_modules/@dsh-std/command/README.md +26 -0
- package/node_modules/@dsh-std/command/README.zh.md +28 -0
- package/node_modules/@dsh-std/command/lib/index.d.ts +144 -0
- package/node_modules/@dsh-std/command/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/command/lib/index.js +252 -0
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/command/package.json +22 -0
- package/node_modules/@dsh-std/connection/LICENSE +21 -0
- package/node_modules/@dsh-std/connection/README.md +42 -0
- package/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.js +257 -0
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/node_modules/@dsh-std/connection/package.json +20 -0
- package/node_modules/@dsh-std/core/LICENSE +21 -0
- package/node_modules/@dsh-std/core/README.md +13 -0
- package/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/core/package.json +21 -0
- package/node_modules/@dsh-std/manifest/LICENSE +21 -0
- package/node_modules/@dsh-std/manifest/README.md +5 -0
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -0
- package/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
- package/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/manifest/lib/index.js +625 -0
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/manifest/package.json +20 -0
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
- package/node_modules/@dsh-std/messages/LICENSE +21 -0
- package/node_modules/@dsh-std/messages/README.md +5 -0
- package/node_modules/@dsh-std/messages/README.zh.md +7 -0
- package/node_modules/@dsh-std/messages/lib/index.d.ts +50 -0
- package/node_modules/@dsh-std/messages/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/messages/lib/index.js +151 -0
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/messages/package.json +20 -0
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -0
- package/node_modules/@dsh-std/presentation/LICENSE +21 -0
- package/node_modules/@dsh-std/presentation/README.md +26 -0
- package/node_modules/@dsh-std/presentation/README.zh.md +28 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/index.js +547 -0
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
- package/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
- package/node_modules/@dsh-std/presentation/package.json +21 -0
- package/node_modules/@dsh-std/storage/LICENSE +21 -0
- package/node_modules/@dsh-std/storage/README.md +5 -0
- package/node_modules/@dsh-std/storage/README.zh.md +7 -0
- package/node_modules/@dsh-std/storage/lib/index.d.ts +48 -0
- package/node_modules/@dsh-std/storage/lib/index.d.ts.map +1 -0
- package/node_modules/@dsh-std/storage/lib/index.js +104 -0
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -0
- package/node_modules/@dsh-std/storage/package.json +20 -0
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -0
- package/package.json +118 -67
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +257 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts +182 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js +625 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +26 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +28 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +219 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +547 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/interaction.js +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/operations.js +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +21 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts +125 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/connection-CdGcSQnu.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts +89 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js +158 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +24 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +257 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js +226 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts +112 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.d.ts.map +1 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js +424 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* storage.local contract surface (C-040, `storage.dsh/v1alpha1#LocalStorage`):
|
|
3
|
+
* per-plugin private persistence, mounted by the dsh-tui-plugin-host row as
|
|
4
|
+
* `ctx.tuiPluginStorage`.
|
|
5
|
+
*
|
|
6
|
+
* The plugin-facing API is `open(ctx)` → `{ get, set, delete }`:
|
|
7
|
+
*
|
|
8
|
+
* - VERIFIED IDENTITY: the namespace is derived from the admitted Component
|
|
9
|
+
* identity bound to the PASSED activation — there is no parameter to name
|
|
10
|
+
* another plugin, so cross-plugin access is rejected by construction.
|
|
11
|
+
* - GRANTS AT CALL TIME: `get` requires `storage.local.read`, `set`/`delete`
|
|
12
|
+
* require `storage.local.write` — checked per call against the live grant
|
|
13
|
+
* store (a revoked grant blocks the very next operation without restart).
|
|
14
|
+
* - Backend: `~/.dsh-tui/plugin-storage/<namespace>.json`, one flat JSON
|
|
15
|
+
* object per namespace. Writes go through dsh-atomic-write (`withFileLock`
|
|
16
|
+
* for the read-modify-write cycle + `writeFileAtomic` for the commit), and
|
|
17
|
+
* an in-process per-namespace promise chain serializes operations in
|
|
18
|
+
* invocation order (contract concurrency rule — the lock alone does not
|
|
19
|
+
* order contenders).
|
|
20
|
+
* - QUOTA (host-defined): 256 keys AND 256 KiB of serialized content per
|
|
21
|
+
* namespace; a `set` that would cross either fails with QUOTA_EXCEEDED and
|
|
22
|
+
* changes nothing.
|
|
23
|
+
* - Keys stay ordinary data even when they collide with Object.prototype
|
|
24
|
+
* names ("__proto__", "toString", "constructor"): namespace tables are
|
|
25
|
+
* null-prototype and membership is decided with Object.hasOwn. Values
|
|
26
|
+
* must be EXACT JSON values — inputs JSON.stringify would silently
|
|
27
|
+
* mutate (undefined, NaN/±Infinity, functions, class instances, sparse
|
|
28
|
+
* arrays, cycles) are rejected instead of round-tripping a lie.
|
|
29
|
+
* - A corrupt namespace file is NEVER overwritten silently: every operation
|
|
30
|
+
* fails with STORAGE_UNAVAILABLE and the bytes stay on disk for manual
|
|
31
|
+
* recovery. Closing a handle (plugin unload) retains data (contract
|
|
32
|
+
* cleanup rule); later calls on a closed handle fail STORAGE_UNAVAILABLE.
|
|
33
|
+
* - privacyClass: sensitive — keys AND values are never logged.
|
|
34
|
+
*/
|
|
35
|
+
import { mkdirSync, readFileSync } from 'node:fs';
|
|
36
|
+
import { join } from 'node:path';
|
|
37
|
+
import { writeFileAtomic, withFileLock } from '@deepseek-ai/dsh-atomic-write';
|
|
38
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
39
|
+
import { validateDeleteInput, validateGetInput, validateSetInput, validateGetOutput, validateSetOutput, validateDeleteOutput, } from '@dsh-std/storage';
|
|
40
|
+
import { DATA_DIR } from '../utils/paths.js';
|
|
41
|
+
import { declaresPermission, requireComponentIdentity } from './component-identity.js';
|
|
42
|
+
import { readGrantStore } from './grants.js';
|
|
43
|
+
/** Quota: max distinct keys per namespace. */
|
|
44
|
+
export const STORAGE_MAX_KEYS = 256;
|
|
45
|
+
/** Quota: max serialized file size per namespace (bytes). */
|
|
46
|
+
export const STORAGE_MAX_BYTES = 256 * 1024;
|
|
47
|
+
/** Max key length (characters). */
|
|
48
|
+
export const STORAGE_KEY_MAX_LENGTH = 128;
|
|
49
|
+
/** Storage failure with the contract's error code on `.code`. */
|
|
50
|
+
export class PluginStorageError extends Error {
|
|
51
|
+
code;
|
|
52
|
+
constructor(code, message) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.name = 'PluginStorageError';
|
|
55
|
+
this.code = code;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Namespace directory under the data dir. */
|
|
59
|
+
export const PLUGIN_STORAGE_DIR = 'plugin-storage';
|
|
60
|
+
/**
|
|
61
|
+
* Plugin name → safe, collision-free file name. encodeURIComponent keeps
|
|
62
|
+
* alphanumerics and `- _ . ! ~ * ' ( )`, so scoped names like `@foo/bar`
|
|
63
|
+
* encode reversibly; pathological results ('', '.', '..') map to '_'.
|
|
64
|
+
*/
|
|
65
|
+
export function storageFileName(plugin) {
|
|
66
|
+
const encoded = encodeURIComponent(plugin);
|
|
67
|
+
return encoded === '' || encoded === '.' || encoded === '..' ? '_' : encoded;
|
|
68
|
+
}
|
|
69
|
+
function assertKey(key) {
|
|
70
|
+
if (typeof key !== 'string' || key === '' || key.length > STORAGE_KEY_MAX_LENGTH || /[\x00-\x1f\x7f-\x9f]/.test(key)) {
|
|
71
|
+
throw new PluginStorageError('INVALID_KEY', 'storage keys are non-empty control-free strings of at most 128 characters');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function validateStorageInput(operation, input) {
|
|
75
|
+
try {
|
|
76
|
+
if (operation === 'get')
|
|
77
|
+
validateGetInput(input);
|
|
78
|
+
else if (operation === 'set')
|
|
79
|
+
validateSetInput(input);
|
|
80
|
+
else
|
|
81
|
+
validateDeleteInput(input);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
85
|
+
if (operation !== 'set')
|
|
86
|
+
throw new PluginStorageError('INVALID_KEY', message);
|
|
87
|
+
// The standard validator intentionally reports exact-record failures in a
|
|
88
|
+
// single stream. Preserve the contract's distinction: malformed/missing
|
|
89
|
+
// `key` is INVALID_KEY; once the key itself is valid, every value/shape
|
|
90
|
+
// failure (including a missing `value`) is INVALID_VALUE.
|
|
91
|
+
let keyValid = false;
|
|
92
|
+
try {
|
|
93
|
+
const candidate = input;
|
|
94
|
+
assertKey(candidate?.key);
|
|
95
|
+
keyValid = true;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
keyValid = false;
|
|
99
|
+
}
|
|
100
|
+
throw new PluginStorageError(keyValid ? 'INVALID_VALUE' : 'INVALID_KEY', message);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Exact JSON values only. JSON.stringify silently MUTATES edge inputs
|
|
105
|
+
* (NaN/±Infinity → null, undefined array items → null, undefined object
|
|
106
|
+
* properties dropped, class instances reduced to own fields) — a storage
|
|
107
|
+
* contract must not round-trip a value the caller never stored, so those
|
|
108
|
+
* inputs are rejected instead. Accepts: null, boolean, string, finite
|
|
109
|
+
* number, arrays (dense), and plain objects (Object.prototype or null
|
|
110
|
+
* prototype only). Every own property is inspected because JSON.stringify
|
|
111
|
+
* ignores array side-properties, symbols, and non-enumerable fields, while
|
|
112
|
+
* accessors/toJSON can replace the value being serialized. Those inputs,
|
|
113
|
+
* cycles, and anything whose inspection throws are rejected.
|
|
114
|
+
*/
|
|
115
|
+
function assertJsonValue(value) {
|
|
116
|
+
let ok = false;
|
|
117
|
+
try {
|
|
118
|
+
ok = isJsonValue(value, new Set());
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
ok = false;
|
|
122
|
+
}
|
|
123
|
+
if (!ok) {
|
|
124
|
+
throw new PluginStorageError('INVALID_VALUE', 'storage values must be exact JSON values (no undefined, functions, symbols, BigInt, NaN/Infinity, class instances, sparse arrays, or cycles)');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function isJsonValue(value, seen) {
|
|
128
|
+
if (value === null)
|
|
129
|
+
return true;
|
|
130
|
+
switch (typeof value) {
|
|
131
|
+
case 'boolean':
|
|
132
|
+
case 'string':
|
|
133
|
+
return true;
|
|
134
|
+
case 'number':
|
|
135
|
+
return Number.isFinite(value);
|
|
136
|
+
case 'object': {
|
|
137
|
+
const object = value;
|
|
138
|
+
if (seen.has(object))
|
|
139
|
+
return false;
|
|
140
|
+
seen.add(object);
|
|
141
|
+
try {
|
|
142
|
+
if (Array.isArray(value)) {
|
|
143
|
+
// Array subclasses/custom prototypes can supply an inherited toJSON
|
|
144
|
+
// hook. JSON would serialize its replacement, not this array.
|
|
145
|
+
if (Object.getPrototypeOf(value) !== Array.prototype)
|
|
146
|
+
return false;
|
|
147
|
+
if (Object.getOwnPropertySymbols(value).length > 0)
|
|
148
|
+
return false;
|
|
149
|
+
const ownNames = Object.getOwnPropertyNames(value);
|
|
150
|
+
for (const name of ownNames) {
|
|
151
|
+
if (name === 'length')
|
|
152
|
+
continue;
|
|
153
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, name);
|
|
154
|
+
// JSON arrays serialize only their indexed elements. Any other
|
|
155
|
+
// own property (especially toJSON) would be silently lost.
|
|
156
|
+
const index = Number(name);
|
|
157
|
+
if (descriptor === undefined || !('value' in descriptor) ||
|
|
158
|
+
!Number.isSafeInteger(index) || index < 0 || String(index) !== name || index >= value.length)
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
for (let index = 0; index < value.length; index++) {
|
|
162
|
+
// A sparse hole would serialize as null — a value never stored.
|
|
163
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
164
|
+
if (descriptor === undefined || !('value' in descriptor))
|
|
165
|
+
return false;
|
|
166
|
+
if (!isJsonValue(descriptor.value, seen))
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
const proto = Object.getPrototypeOf(value);
|
|
172
|
+
if (proto !== Object.prototype && proto !== null)
|
|
173
|
+
return false;
|
|
174
|
+
// A modified Object.prototype can add an inherited toJSON hook; own
|
|
175
|
+
// non-enumerable/accessor properties are likewise not exact JSON.
|
|
176
|
+
if (typeof value.toJSON === 'function')
|
|
177
|
+
return false;
|
|
178
|
+
if (Object.getOwnPropertySymbols(value).length > 0)
|
|
179
|
+
return false;
|
|
180
|
+
for (const name of Object.getOwnPropertyNames(value)) {
|
|
181
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, name);
|
|
182
|
+
if (descriptor === undefined || !descriptor.enumerable || !('value' in descriptor))
|
|
183
|
+
return false;
|
|
184
|
+
if (!isJsonValue(descriptor.value, seen))
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
finally {
|
|
190
|
+
// DAGs (shared references without cycles) serialize fine — only
|
|
191
|
+
// reject a value reachable from ITSELF.
|
|
192
|
+
seen.delete(object);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
default:
|
|
196
|
+
// undefined / function / symbol / bigint
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* `ctx.tuiPluginStorage` — storage.local contract surface. Mounted by the
|
|
202
|
+
* dsh-tui-plugin-host row; grants come from that row's store when present
|
|
203
|
+
* (normal path) or a private read otherwise (bare mounts in tests).
|
|
204
|
+
*/
|
|
205
|
+
export class TuiPluginStorageRuntime extends Service {
|
|
206
|
+
grantsOption;
|
|
207
|
+
fallbackGrants;
|
|
208
|
+
ledgerOption;
|
|
209
|
+
namespaces = new Map();
|
|
210
|
+
dir;
|
|
211
|
+
constructor(ctx, options = {}) {
|
|
212
|
+
super(ctx, 'tuiPluginStorage');
|
|
213
|
+
this.grantsOption = options.grants;
|
|
214
|
+
this.fallbackGrants = readGrantStore();
|
|
215
|
+
this.ledgerOption = options.ledger;
|
|
216
|
+
this.dir = options.dir ?? join(DATA_DIR, PLUGIN_STORAGE_DIR);
|
|
217
|
+
}
|
|
218
|
+
/** Grants: the plugin-host row's store when mounted, else a private read.
|
|
219
|
+
* Resolved PER CALL — sibling services mounted later by the same apply()
|
|
220
|
+
* are not visible to constructors (cordis), so a constructor-time probe
|
|
221
|
+
* would silently stick to the fallback. */
|
|
222
|
+
grants() {
|
|
223
|
+
return this.grantsOption ?? this.ctx.get('tuiPluginHost')?.grants ?? this.fallbackGrants;
|
|
224
|
+
}
|
|
225
|
+
/** Optional observability; a bare mount (tests) simply records nothing. */
|
|
226
|
+
ledger() {
|
|
227
|
+
return this.ledgerOption ?? this.ctx.get('tuiEffectLedger');
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Open the caller's private namespace. Identity = the PASSED context's
|
|
231
|
+
* verified Component identity (no way to name another plugin). The handle
|
|
232
|
+
* closes automatically when the caller's context unloads (idempotent
|
|
233
|
+
* disposer); data is retained (contract cleanup rule).
|
|
234
|
+
*/
|
|
235
|
+
open(pluginCtx) {
|
|
236
|
+
const identity = requireComponentIdentity(pluginCtx);
|
|
237
|
+
const plugin = identity.componentId;
|
|
238
|
+
let state = this.namespaces.get(plugin);
|
|
239
|
+
if (state === undefined) {
|
|
240
|
+
state = { chain: Promise.resolve() };
|
|
241
|
+
this.namespaces.set(plugin, state);
|
|
242
|
+
}
|
|
243
|
+
this.ledger()?.record({ operation: 'create', resource: { kind: 'storage-namespace', id: plugin }, result: 'applied' }, pluginCtx);
|
|
244
|
+
// `closed` is PER HANDLE, not per namespace: unloading one fiber must not
|
|
245
|
+
// kill another handle opened on the same namespace. Close on unload;
|
|
246
|
+
// idempotent (a double-close stays harmless by design); degraded contexts
|
|
247
|
+
// without `effect` simply never auto-close.
|
|
248
|
+
let closed = false;
|
|
249
|
+
try {
|
|
250
|
+
pluginCtx.effect(() => () => {
|
|
251
|
+
if (closed)
|
|
252
|
+
return;
|
|
253
|
+
closed = true;
|
|
254
|
+
this.ledger()?.record({ operation: 'release', resource: { kind: 'storage-namespace', id: plugin }, result: 'applied' }, pluginCtx);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// Degraded context: the handle lives until process end.
|
|
259
|
+
}
|
|
260
|
+
const file = join(this.dir, `${storageFileName(plugin)}.json`);
|
|
261
|
+
const grants = () => this.grants();
|
|
262
|
+
const ledger = () => this.ledger();
|
|
263
|
+
const enqueue = (operation) => {
|
|
264
|
+
if (closed) {
|
|
265
|
+
return Promise.reject(new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" handle is closed`));
|
|
266
|
+
}
|
|
267
|
+
const run = state.chain.then(operation);
|
|
268
|
+
// Keep the chain alive after a failure without unhandled rejections.
|
|
269
|
+
state.chain = run.catch(() => { });
|
|
270
|
+
return run;
|
|
271
|
+
};
|
|
272
|
+
const readTable = () => {
|
|
273
|
+
let raw;
|
|
274
|
+
try {
|
|
275
|
+
raw = readFileSync(file, 'utf8');
|
|
276
|
+
}
|
|
277
|
+
catch (error) {
|
|
278
|
+
if (error.code === 'ENOENT')
|
|
279
|
+
return Object.create(null);
|
|
280
|
+
throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" is unreadable; the file was left untouched for manual recovery`);
|
|
281
|
+
}
|
|
282
|
+
let parsed;
|
|
283
|
+
try {
|
|
284
|
+
parsed = JSON.parse(raw);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" is corrupt on disk; the file was left untouched for manual recovery`);
|
|
288
|
+
}
|
|
289
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
290
|
+
throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" holds a non-object document; the file was left untouched for manual recovery`);
|
|
291
|
+
}
|
|
292
|
+
// Rebuild on a NULL-PROTOTYPE table: key membership is decided with
|
|
293
|
+
// Object.hasOwn, and keys like "__proto__" / "toString" must behave
|
|
294
|
+
// as ordinary data (a prototype-chain read would leak host objects
|
|
295
|
+
// into plugin results and fake membership for never-stored keys).
|
|
296
|
+
const table = Object.create(null);
|
|
297
|
+
for (const [key, value] of Object.entries(parsed))
|
|
298
|
+
table[key] = value;
|
|
299
|
+
return table;
|
|
300
|
+
};
|
|
301
|
+
const requireGrant = (permission) => {
|
|
302
|
+
if (!declaresPermission(identity, permission, plugin)
|
|
303
|
+
|| !grants().allows({ componentId: identity.componentId, activationId: identity.activationId }, permission, plugin)) {
|
|
304
|
+
ledger()?.record({
|
|
305
|
+
operation: 'bind',
|
|
306
|
+
resource: { kind: 'permission', id: permission },
|
|
307
|
+
result: 'failed',
|
|
308
|
+
errorCode: 'PERMISSION_NOT_GRANTED',
|
|
309
|
+
}, pluginCtx);
|
|
310
|
+
throw new PluginStorageError('PERMISSION_NOT_GRANTED', `storage.${permission.endsWith('.read') ? 'get' : 'set/delete'} from plugin "${plugin}" denied — grant "${permission}" ` +
|
|
311
|
+
`for "${plugin}" in ~/.dsh-tui/extension-grants.json first`);
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
// withFileLock creates its lock as a SIBLING of the file and does not
|
|
315
|
+
// create parent directories — ensure the tree exists before any write
|
|
316
|
+
// path (read paths tolerate ENOENT as an empty namespace and never
|
|
317
|
+
// materialize the tree).
|
|
318
|
+
const ensureDir = () => {
|
|
319
|
+
mkdirSync(this.dir, { recursive: true, mode: 0o700 });
|
|
320
|
+
};
|
|
321
|
+
return {
|
|
322
|
+
get: (input) => enqueue(async () => {
|
|
323
|
+
validateStorageInput('get', input);
|
|
324
|
+
const key = input.key;
|
|
325
|
+
assertKey(key);
|
|
326
|
+
requireGrant('storage.local.read');
|
|
327
|
+
const table = readTable();
|
|
328
|
+
const output = { value: Object.hasOwn(table, key) ? table[key] : null };
|
|
329
|
+
try {
|
|
330
|
+
validateGetOutput(output);
|
|
331
|
+
}
|
|
332
|
+
catch {
|
|
333
|
+
throw new PluginStorageError('STORAGE_UNAVAILABLE', `storage namespace "${plugin}" contains an invalid JSON value`);
|
|
334
|
+
}
|
|
335
|
+
return output;
|
|
336
|
+
}),
|
|
337
|
+
set: (input) => enqueue(async () => {
|
|
338
|
+
validateStorageInput('set', input);
|
|
339
|
+
const key = input.key;
|
|
340
|
+
const value = input.value;
|
|
341
|
+
assertKey(key);
|
|
342
|
+
assertJsonValue(value);
|
|
343
|
+
requireGrant('storage.local.write');
|
|
344
|
+
ensureDir();
|
|
345
|
+
return withFileLock(file, async () => {
|
|
346
|
+
const table = readTable();
|
|
347
|
+
const isNewKey = !Object.hasOwn(table, key);
|
|
348
|
+
if (isNewKey && Object.keys(table).length >= STORAGE_MAX_KEYS) {
|
|
349
|
+
throw new PluginStorageError('QUOTA_EXCEEDED', `storage namespace "${plugin}" holds ${STORAGE_MAX_KEYS} keys already`);
|
|
350
|
+
}
|
|
351
|
+
table[key] = value;
|
|
352
|
+
const content = JSON.stringify(table);
|
|
353
|
+
if (Buffer.byteLength(content, 'utf8') > STORAGE_MAX_BYTES) {
|
|
354
|
+
throw new PluginStorageError('QUOTA_EXCEEDED', `storage namespace "${plugin}" would exceed ${STORAGE_MAX_BYTES} bytes`);
|
|
355
|
+
}
|
|
356
|
+
// 0o600/0o700: the namespace is privacyClass sensitive.
|
|
357
|
+
await writeFileAtomic(file, content, { mode: 0o600, dirMode: 0o700 });
|
|
358
|
+
const output = { stored: true };
|
|
359
|
+
validateSetOutput(output);
|
|
360
|
+
return output;
|
|
361
|
+
});
|
|
362
|
+
}),
|
|
363
|
+
delete: (input) => enqueue(async () => {
|
|
364
|
+
validateStorageInput('delete', input);
|
|
365
|
+
const key = input.key;
|
|
366
|
+
assertKey(key);
|
|
367
|
+
requireGrant('storage.local.write');
|
|
368
|
+
ensureDir();
|
|
369
|
+
return withFileLock(file, async () => {
|
|
370
|
+
const table = readTable();
|
|
371
|
+
if (!Object.hasOwn(table, key)) {
|
|
372
|
+
const output = { deleted: false };
|
|
373
|
+
validateDeleteOutput(output);
|
|
374
|
+
return output;
|
|
375
|
+
}
|
|
376
|
+
delete table[key];
|
|
377
|
+
await writeFileAtomic(file, JSON.stringify(table), { mode: 0o600, dirMode: 0o700 });
|
|
378
|
+
const output = { deleted: true };
|
|
379
|
+
validateDeleteOutput(output);
|
|
380
|
+
return output;
|
|
381
|
+
});
|
|
382
|
+
}),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAiCnC;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6iBvE;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAcA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV"}
|
|
@@ -3,12 +3,15 @@ import React from 'react';
|
|
|
3
3
|
import { SessionId } from '@deepseek-ai/dsh-session';
|
|
4
4
|
import UserQuestionService from '@deepseek-ai/dsh-user-questions';
|
|
5
5
|
import * as toolAskUser from '@deepseek-ai/dsh-tool-ask-user';
|
|
6
|
+
import { settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
7
|
+
import Schema from '@deepseek-ai/schemastery';
|
|
6
8
|
import { createChannel } from './channel.js';
|
|
7
9
|
import { createChildStderrReporter, installChildStderrGuard } from './childStderr.js';
|
|
8
10
|
import { logForDebugging } from '../utils/debug.js';
|
|
9
11
|
import { QuestionStore } from './questions.js';
|
|
10
12
|
import { ApprovalStore } from './approvals.js';
|
|
11
13
|
import { registerPackagedSkills } from './packaged-skills.js';
|
|
14
|
+
import { registerPromptDebug } from './promptDebug.js';
|
|
12
15
|
import { readActivityFrames } from '../activityPrefs.js';
|
|
13
16
|
import { readModelPref } from '../modelPrefs.js';
|
|
14
17
|
import { explicitModelRoute, recordedModelRoute, resolveModelRoute, validateModelRoute } from '../modelRoute.js';
|
|
@@ -18,7 +21,7 @@ import { ensurePackagedPresets } from './packaged-presets.js';
|
|
|
18
21
|
import { ensureLegacySessionEventTypes } from './compat/index.js';
|
|
19
22
|
import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
|
|
20
23
|
import { resolveSessionCwd } from '../utils/workspaceRoot.js';
|
|
21
|
-
import { checkForTuiUpdate, installedTuiVersion, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
24
|
+
import { checkForTuiUpdate, installedTuiVersion, isBootDeadlockTarget, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
22
25
|
import { isLang, resolveStartupLang, setLang, t } from '../i18n.js';
|
|
23
26
|
import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
|
|
24
27
|
import { Chat } from '../screens/Chat.js';
|
|
@@ -130,6 +133,9 @@ export async function apply(ctx, config) {
|
|
|
130
133
|
// Packaged skills (/audit, /bug, …): contribute them through the host's
|
|
131
134
|
// skill registry so they resolve with zero manual copying.
|
|
132
135
|
registerPackagedSkills(ctx);
|
|
136
|
+
// `/debug-prompt` snapshots the final provider-neutral request at the
|
|
137
|
+
// llm/stream boundary, after every prompt and tool contributor has run.
|
|
138
|
+
registerPromptDebug(ctx);
|
|
133
139
|
// Yield to an incumbent provider instead of crashing the whole plugin tree
|
|
134
140
|
// (issue #98): the harness allows exactly ONE user-questions provider per
|
|
135
141
|
// context, and stacking this TUI onto a profile that already carries
|
|
@@ -211,6 +217,32 @@ export async function apply(ctx, config) {
|
|
|
211
217
|
'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
|
|
212
218
|
}
|
|
213
219
|
const workspaceService = mountedWorkspaceService ?? createLocalWorkspaceRuntime();
|
|
220
|
+
// Same skew guard for the plugin-scene registry (dsh-tui-scenes row): the
|
|
221
|
+
// channel degrades to never opening scenes when the service is absent, so
|
|
222
|
+
// say why on profile launches — a plugin's open() otherwise fails with only
|
|
223
|
+
// its own warn to go on.
|
|
224
|
+
if (ctx.get('tuiScenes') === undefined && resolveDshProfileName() !== undefined) {
|
|
225
|
+
ctx.logger.warn('dsh-tui: tuiScenes service is not mounted; plugin scenes will never open. ' +
|
|
226
|
+
'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
|
|
227
|
+
}
|
|
228
|
+
// Same skew guard for the plugin-UI services (dsh-tui-extensions row):
|
|
229
|
+
// managed dialogs park unanswered, status contributions never render,
|
|
230
|
+
// shortcuts never match, and custom-entry renderers stay invisible when
|
|
231
|
+
// the row is absent — say why on profile launches.
|
|
232
|
+
if (ctx.get('tuiDialogs') === undefined && resolveDshProfileName() !== undefined) {
|
|
233
|
+
ctx.logger.warn('dsh-tui: tuiDialogs/tuiStatus/tuiShortcuts/tuiRenderers services are not mounted; plugin dialogs, status contributions, shortcuts and custom-entry renderers are off. ' +
|
|
234
|
+
'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
|
|
235
|
+
}
|
|
236
|
+
// Same skew guard for the plugin-host row (dsh-tui-plugin-host): without
|
|
237
|
+
// it there is no runtime generation id, no unified grant store service,
|
|
238
|
+
// and no Host Descriptor — plugin interop surfaces degrade silently
|
|
239
|
+
// otherwise. The D-7 decision gate does NOT depend on this row (the
|
|
240
|
+
// channel installs its own), so interception gating stays intact either
|
|
241
|
+
// way — what breaks is everything that rides on tuiPluginHost.
|
|
242
|
+
if (ctx.get('tuiPluginHost') === undefined && resolveDshProfileName() !== undefined) {
|
|
243
|
+
ctx.logger.warn('dsh-tui: tuiPluginHost service is not mounted; plugin grant store, runtime generation and Host Descriptor are unavailable. ' +
|
|
244
|
+
'The bundle patch is older than the installed dsh-tui package — update the globally installed dsh-tui launcher to match the profile (issue #183).');
|
|
245
|
+
}
|
|
214
246
|
const initialWorkspace = requestedWorkspace === undefined
|
|
215
247
|
? undefined
|
|
216
248
|
: await workspaceService.resolve(requestedWorkspace);
|
|
@@ -267,8 +299,53 @@ export async function apply(ctx, config) {
|
|
|
267
299
|
// Shift+Tab session-mode cycle (undefined → the built-in default/
|
|
268
300
|
// plan/full cycle in sessionModes.ts).
|
|
269
301
|
modes: config.modes,
|
|
302
|
+
// Edit/Write diff presentation (schema default 'auto'); the /settings
|
|
303
|
+
// screen edits this key live through the dsh-tui namespace.
|
|
304
|
+
diffLayout: config.diffLayout,
|
|
270
305
|
handle,
|
|
271
306
|
});
|
|
307
|
+
// Register the dsh-tui settings namespace so the /settings screen can
|
|
308
|
+
// edit it (the section below was '命名空间未注册' without this): the
|
|
309
|
+
// user layer in settings.yaml wins over cordis.yml's diffLayout, and
|
|
310
|
+
// watch() lands commits on the live channel — no recompose needed.
|
|
311
|
+
ctx.inject(['settings'], (settingsCtx) => {
|
|
312
|
+
const scope = settingsCtx.settings.register(settingsNamespace('dsh-tui'), Schema.object({
|
|
313
|
+
diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
|
|
314
|
+
}));
|
|
315
|
+
const applyLayout = (value) => {
|
|
316
|
+
channel.setDiffLayout(value.diffLayout ?? config.diffLayout ?? 'auto');
|
|
317
|
+
};
|
|
318
|
+
applyLayout(scope.get());
|
|
319
|
+
scope.watch(next => {
|
|
320
|
+
applyLayout(next);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
// The /settings screen's own section: the dsh-tui namespace comes from
|
|
324
|
+
// this plugin's Config schema, and the declared select writes diffLayout
|
|
325
|
+
// back through the settings service's revision-fenced mutate.
|
|
326
|
+
const settingsSections = ctx.get('tuiSettingsSections');
|
|
327
|
+
if (settingsSections !== undefined) {
|
|
328
|
+
const unregister = settingsSections.register({
|
|
329
|
+
ns: 'dsh-tui',
|
|
330
|
+
title: 'dsh-tui',
|
|
331
|
+
fields: [
|
|
332
|
+
{
|
|
333
|
+
path: ['diffLayout'],
|
|
334
|
+
label: 'Diff layout',
|
|
335
|
+
descriptions: { zh: 'diff 布局' },
|
|
336
|
+
hint: 'Edit/Write tool cards: auto picks by terminal width, or force one layout.',
|
|
337
|
+
hintDescriptions: { zh: 'Edit/Write 工具卡的 diff 呈现:auto 按终端宽度选择,或强制一种布局。' },
|
|
338
|
+
kind: 'select',
|
|
339
|
+
options: [
|
|
340
|
+
{ value: 'auto', label: 'Auto (by width)', descriptions: { zh: '自动(按宽度)' } },
|
|
341
|
+
{ value: 'split', label: 'Side-by-side', descriptions: { zh: '双栏对照' } },
|
|
342
|
+
{ value: 'unified', label: 'Unified', descriptions: { zh: '统一式' } },
|
|
343
|
+
],
|
|
344
|
+
},
|
|
345
|
+
],
|
|
346
|
+
});
|
|
347
|
+
ctx.effect(() => unregister);
|
|
348
|
+
}
|
|
272
349
|
// DSH approval seam: the permission layer asks ApprovalService.request(),
|
|
273
350
|
// which dispatches an `approval/request` waterfall. With no answerer the
|
|
274
351
|
// chain falls through to the fail-closed 'unavailable', so register this
|
|
@@ -369,6 +446,12 @@ export async function apply(ctx, config) {
|
|
|
369
446
|
channel,
|
|
370
447
|
questionStore,
|
|
371
448
|
approvalStore,
|
|
449
|
+
// The dsh-tui-extensions row's services (managed dialogs, status line,
|
|
450
|
+
// shortcuts). Soft-consumed: absent the row (stale patch, bare embed),
|
|
451
|
+
// Chat falls back to inert stores and no shortcut registry.
|
|
452
|
+
extensionDialogs: ctx.get('tuiDialogs')?.store,
|
|
453
|
+
extensionStatus: ctx.get('tuiStatus')?.store,
|
|
454
|
+
extensionShortcuts: ctx.get('tuiShortcuts'),
|
|
372
455
|
// Full-screen surfaces inside Chat — the trajectory scene and the session
|
|
373
456
|
// browser — enter the alt screen themselves in inline mode; in fullscreen
|
|
374
457
|
// the tree is already wrapped below, so they must not nest.
|
|
@@ -394,6 +477,21 @@ export async function apply(ctx, config) {
|
|
|
394
477
|
channel.notify(t('update-check-failed'));
|
|
395
478
|
}
|
|
396
479
|
else {
|
|
480
|
+
// 0.7.0/0.7.1 hard-inject tuiWorkspaces at the code level; under
|
|
481
|
+
// an older global launcher patch (no service row) that is a
|
|
482
|
+
// permanent boot deadlock (issues #183/#307, the exact report
|
|
483
|
+
// "pending (waiting for service: tuiWorkspaces)"). A stale mirror
|
|
484
|
+
// pinning /update onto that range must be refused, not installed.
|
|
485
|
+
if (isBootDeadlockTarget(target.latest)) {
|
|
486
|
+
channel.notify(t('update-refused-deadlock', {
|
|
487
|
+
latest: target.latest,
|
|
488
|
+
authoritative: target.authoritative ?? target.latest,
|
|
489
|
+
}), { color: 'warning' });
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
if (target.authoritative !== undefined) {
|
|
493
|
+
channel.notify(t('update-mirror-lag', { latest: target.latest, authoritative: target.authoritative }));
|
|
494
|
+
}
|
|
397
495
|
updateTargetVersion = target.latest;
|
|
398
496
|
}
|
|
399
497
|
channel.notify(t('update-starting'));
|
|
@@ -585,6 +683,11 @@ async function finishExit(ctx, instance, fullscreen, notice, stderrNotice, done)
|
|
|
585
683
|
const cursor = fullscreen ? '' : cursorMoveToFrameEnd(runtime);
|
|
586
684
|
try {
|
|
587
685
|
runtime?.detachForShutdown?.();
|
|
686
|
+
// The /update continuation spawns children that inherit this stdin;
|
|
687
|
+
// strip the readable pump so the parent cannot swallow their input
|
|
688
|
+
// (issues #284/#307). Harmless on plain exits — the process exits
|
|
689
|
+
// right after this cleanup anyway.
|
|
690
|
+
runtime?.detachStdinForHandoff?.();
|
|
588
691
|
}
|
|
589
692
|
catch {
|
|
590
693
|
ctx.logger.debug('dsh-tui: Ink shutdown detach failed; continuing with generic terminal cleanup');
|
|
@@ -619,6 +722,8 @@ function readInkShutdownState(value) {
|
|
|
619
722
|
const candidate = value;
|
|
620
723
|
if (candidate.detachForShutdown !== undefined && typeof candidate.detachForShutdown !== 'function')
|
|
621
724
|
return undefined;
|
|
725
|
+
if (candidate.detachStdinForHandoff !== undefined && typeof candidate.detachStdinForHandoff !== 'function')
|
|
726
|
+
return undefined;
|
|
622
727
|
if (candidate.frontFrame !== undefined && !isFrameState(candidate.frontFrame))
|
|
623
728
|
return undefined;
|
|
624
729
|
if (candidate.displayCursor !== undefined && candidate.displayCursor !== null && !isCursorState(candidate.displayCursor))
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /plugins diagnostics surface (C-070 trust disclosure + C-030 negotiation
|
|
3
|
+
* diagnostics): assembles the lines behind the `/plugins` command.
|
|
4
|
+
*
|
|
5
|
+
* Sections (overview):
|
|
6
|
+
*
|
|
7
|
+
* 1. TRUST BANNER — always the first line (C-070): plugins run in-process;
|
|
8
|
+
* grants are behavioral constraints, not a security boundary; passing
|
|
9
|
+
* validation is not proof of safety.
|
|
10
|
+
* 2. HOST DESCRIPTOR summary — what the running host actually advertises
|
|
11
|
+
* (coordinates + generation), including drift-dropped contracts.
|
|
12
|
+
* 3. GRANT MATRIX — plugins × the registered permissions. The plugin set is
|
|
13
|
+
* the union of FOOTPRINTS ONLY: keys of the grants file, pluginIds seen
|
|
14
|
+
* in the effect ledger, and storage namespaces on disk (the host cannot
|
|
15
|
+
* enumerate installed plugins — that knowledge lives in the dsh CLI
|
|
16
|
+
* Loader). The header says so honestly.
|
|
17
|
+
* 4. LEDGER TAIL — the last 5 effect-ledger records.
|
|
18
|
+
*
|
|
19
|
+
* `/plugins check <path>` uses the parser and projection from the pinned
|
|
20
|
+
* @dsh-std/manifest revision, then evaluates every public/private protocol
|
|
21
|
+
* through one ProtocolCatalog. Manifests and on-disk files are UNTRUSTED input:
|
|
22
|
+
* every derived line passes cleanScalarText before it reaches the
|
|
23
|
+
* transcript.
|
|
24
|
+
*/
|
|
25
|
+
import type { GrantStore } from './grants.js';
|
|
26
|
+
import type { HostDescriptorBuild } from './host-descriptor.js';
|
|
27
|
+
/** How many plugins the matrix shows before an overflow note. */
|
|
28
|
+
export declare const PLUGINS_MATRIX_MAX_ROWS = 20;
|
|
29
|
+
/** How many ledger records the tail section shows. */
|
|
30
|
+
export declare const PLUGINS_LEDGER_TAIL = 5;
|
|
31
|
+
export interface PluginsInfoDeps {
|
|
32
|
+
/** Effective grant answers (the plugin-host row's store when mounted). */
|
|
33
|
+
grants: GrantStore;
|
|
34
|
+
/** The plugin-host row's descriptor build; undefined → row not mounted. */
|
|
35
|
+
host?: HostDescriptorBuild;
|
|
36
|
+
/** Test overrides; default under DATA_DIR. */
|
|
37
|
+
dataDir?: string;
|
|
38
|
+
ledgerFile?: string;
|
|
39
|
+
storageDir?: string;
|
|
40
|
+
}
|
|
41
|
+
/** The `/plugins` overview lines (banner always first). */
|
|
42
|
+
export declare function pluginsInfoLines(args: string, deps: PluginsInfoDeps): string[];
|
|
43
|
+
//# sourceMappingURL=plugins-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins-info.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugins-info.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAYH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAK/D,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,KAAK,CAAA;AACzC,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAIpC,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,MAAM,EAAE,UAAU,CAAA;IAClB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,mBAAmB,CAAA;IAC1B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA2JD,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAmF9E"}
|