@deepseek-harness-tui/dsh-tui 0.8.0 → 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 +13 -5
- package/cordis.patch.yml +21 -2
- package/cordis.yml +12 -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 +2 -0
- 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.map +1 -1
- package/lib/types/components/MessageList.js +25 -1
- 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/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.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +1 -1
- package/lib/types/dsh-adapter/channel.d.ts +30 -7
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +503 -21
- 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 +1 -1
- package/lib/types/dsh-adapter/contract.js +2 -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/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 +47 -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/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 +7 -1
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +17 -2
- 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 +162 -16
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +53 -5
- 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/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/screens/Chat.d.ts +14 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +142 -39
- package/lib/types/theme.d.ts +5 -0
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +15 -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 +105 -70
- 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;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,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"}
|
|
@@ -21,7 +21,7 @@ import { ensurePackagedPresets } from './packaged-presets.js';
|
|
|
21
21
|
import { ensureLegacySessionEventTypes } from './compat/index.js';
|
|
22
22
|
import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
|
|
23
23
|
import { resolveSessionCwd } from '../utils/workspaceRoot.js';
|
|
24
|
-
import { checkForTuiUpdate, installedTuiVersion, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
24
|
+
import { checkForTuiUpdate, installedTuiVersion, isBootDeadlockTarget, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
25
25
|
import { isLang, resolveStartupLang, setLang, t } from '../i18n.js';
|
|
26
26
|
import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
|
|
27
27
|
import { Chat } from '../screens/Chat.js';
|
|
@@ -225,6 +225,24 @@ export async function apply(ctx, config) {
|
|
|
225
225
|
ctx.logger.warn('dsh-tui: tuiScenes service is not mounted; plugin scenes will never open. ' +
|
|
226
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
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
|
+
}
|
|
228
246
|
const initialWorkspace = requestedWorkspace === undefined
|
|
229
247
|
? undefined
|
|
230
248
|
: await workspaceService.resolve(requestedWorkspace);
|
|
@@ -428,6 +446,12 @@ export async function apply(ctx, config) {
|
|
|
428
446
|
channel,
|
|
429
447
|
questionStore,
|
|
430
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'),
|
|
431
455
|
// Full-screen surfaces inside Chat — the trajectory scene and the session
|
|
432
456
|
// browser — enter the alt screen themselves in inline mode; in fullscreen
|
|
433
457
|
// the tree is already wrapped below, so they must not nest.
|
|
@@ -453,6 +477,21 @@ export async function apply(ctx, config) {
|
|
|
453
477
|
channel.notify(t('update-check-failed'));
|
|
454
478
|
}
|
|
455
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
|
+
}
|
|
456
495
|
updateTargetVersion = target.latest;
|
|
457
496
|
}
|
|
458
497
|
channel.notify(t('update-starting'));
|
|
@@ -644,6 +683,11 @@ async function finishExit(ctx, instance, fullscreen, notice, stderrNotice, done)
|
|
|
644
683
|
const cursor = fullscreen ? '' : cursorMoveToFrameEnd(runtime);
|
|
645
684
|
try {
|
|
646
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?.();
|
|
647
691
|
}
|
|
648
692
|
catch {
|
|
649
693
|
ctx.logger.debug('dsh-tui: Ink shutdown detach failed; continuing with generic terminal cleanup');
|
|
@@ -678,6 +722,8 @@ function readInkShutdownState(value) {
|
|
|
678
722
|
const candidate = value;
|
|
679
723
|
if (candidate.detachForShutdown !== undefined && typeof candidate.detachForShutdown !== 'function')
|
|
680
724
|
return undefined;
|
|
725
|
+
if (candidate.detachStdinForHandoff !== undefined && typeof candidate.detachStdinForHandoff !== 'function')
|
|
726
|
+
return undefined;
|
|
681
727
|
if (candidate.frontFrame !== undefined && !isFrameState(candidate.frontFrame))
|
|
682
728
|
return undefined;
|
|
683
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"}
|