@deepseek-harness-tui/dsh-tui 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -0
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -0
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -0
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -0
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -0
- package/dsh-ecosystem-spec/registry/README.md +14 -0
- package/dsh-ecosystem-spec/registry/contracts/scene-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/settings-section-v1alpha1.json +13 -0
- package/dsh-ecosystem-spec/registry/contracts/tui-channel-v1alpha1.json +30 -0
- package/dsh-ecosystem-spec/registry/contracts/workspace-provider-v1alpha1.json +6 -0
- package/{ecosystem-spec → dsh-ecosystem-spec}/registry/permissions-0.1.json +1 -1
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -0
- package/lib/types/command-trees.d.ts +2 -1
- package/lib/types/command-trees.d.ts.map +1 -1
- package/lib/types/command-trees.js +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts +10 -5
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LoadedContextPanel.js +18 -7
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +16 -7
- package/lib/types/components/Markdown.d.ts +13 -1
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +15 -1
- 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 +90 -9
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +26 -12
- package/lib/types/components/StreamingMarkdown.d.ts +2 -8
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +51 -9
- package/lib/types/components/activityFrames.d.ts +1 -1
- package/lib/types/components/activityFrames.d.ts.map +1 -1
- package/lib/types/components/activityFrames.js +4 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +5 -1
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +26 -3
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +12 -1
- package/lib/types/dsh-adapter/channel.d.ts +31 -4
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +267 -102
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -1
- package/lib/types/dsh-adapter/childStderr.js +10 -0
- package/lib/types/dsh-adapter/command-attribution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-attribution.js +2 -2
- package/lib/types/dsh-adapter/command-trees.d.ts +7 -1
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -1
- package/lib/types/dsh-adapter/command-trees.js +70 -20
- package/lib/types/dsh-adapter/component-identity.d.ts +5 -0
- package/lib/types/dsh-adapter/component-identity.d.ts.map +1 -1
- package/lib/types/dsh-adapter/component-identity.js +14 -14
- package/lib/types/dsh-adapter/decision-guard.d.ts.map +1 -1
- package/lib/types/dsh-adapter/decision-guard.js +10 -16
- package/lib/types/dsh-adapter/dialogs.d.ts +2 -3
- package/lib/types/dsh-adapter/dialogs.d.ts.map +1 -1
- package/lib/types/dsh-adapter/dialogs.js +114 -60
- package/lib/types/dsh-adapter/effect-ledger.d.ts +0 -8
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +73 -53
- package/lib/types/dsh-adapter/extension-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/extension-events.js +39 -1
- package/lib/types/dsh-adapter/grants.d.ts.map +1 -1
- package/lib/types/dsh-adapter/grants.js +43 -14
- package/lib/types/dsh-adapter/host-access.d.ts +37 -0
- package/lib/types/dsh-adapter/host-access.d.ts.map +1 -0
- package/lib/types/dsh-adapter/host-access.js +652 -0
- package/lib/types/dsh-adapter/host-descriptor.d.ts +2 -2
- package/lib/types/dsh-adapter/host-descriptor.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-descriptor.js +31 -8
- 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 +10 -15
- package/lib/types/dsh-adapter/message-observer.d.ts.map +1 -1
- package/lib/types/dsh-adapter/message-observer.js +114 -70
- package/lib/types/dsh-adapter/plugin-host.d.ts +39 -6
- package/lib/types/dsh-adapter/plugin-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-host.js +139 -44
- package/lib/types/dsh-adapter/plugin-storage.d.ts +0 -5
- package/lib/types/dsh-adapter/plugin-storage.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-storage.js +48 -36
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +80 -16
- package/lib/types/dsh-adapter/promptDebug.d.ts +0 -6
- package/lib/types/dsh-adapter/promptDebug.d.ts.map +1 -1
- package/lib/types/dsh-adapter/promptDebug.js +13 -4
- package/lib/types/dsh-adapter/renderers.d.ts +6 -14
- package/lib/types/dsh-adapter/renderers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/renderers.js +81 -46
- package/lib/types/dsh-adapter/scenes.d.ts +8 -4
- package/lib/types/dsh-adapter/scenes.d.ts.map +1 -1
- package/lib/types/dsh-adapter/scenes.js +136 -37
- package/lib/types/dsh-adapter/settings-sections.d.ts +7 -3
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +106 -26
- package/lib/types/dsh-adapter/shortcuts.d.ts +8 -10
- package/lib/types/dsh-adapter/shortcuts.d.ts.map +1 -1
- package/lib/types/dsh-adapter/shortcuts.js +108 -36
- package/lib/types/dsh-adapter/status.d.ts +6 -7
- package/lib/types/dsh-adapter/status.d.ts.map +1 -1
- package/lib/types/dsh-adapter/status.js +88 -22
- package/lib/types/dsh-adapter/workspaces.d.ts +16 -5
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -1
- package/lib/types/dsh-adapter/workspaces.js +287 -170
- package/lib/types/extensions.d.ts +10 -5
- package/lib/types/extensions.d.ts.map +1 -1
- package/lib/types/extensions.js +11 -5
- package/lib/types/force-production-react.d.ts +1 -0
- package/lib/types/force-production-react.d.ts.map +1 -0
- package/lib/types/force-production-react.js +12 -0
- package/lib/types/i18n.d.ts +14 -6
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +4 -2
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +1 -0
- package/lib/types/ink/components/App.d.ts +2 -0
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +4 -0
- package/lib/types/ink/ink.d.ts +20 -3
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +57 -5
- package/lib/types/ink/log-update.d.ts.map +1 -1
- package/lib/types/ink/log-update.js +128 -9
- package/lib/types/ink/output.d.ts +28 -2
- package/lib/types/ink/output.d.ts.map +1 -1
- package/lib/types/ink/output.js +158 -12
- package/lib/types/ink/screen.d.ts +39 -0
- package/lib/types/ink/screen.d.ts.map +1 -1
- package/lib/types/ink/screen.js +117 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +10 -2
- package/lib/types/ink/wrapAnsi.d.ts +1 -1
- package/lib/types/ink/wrapAnsi.d.ts.map +1 -1
- package/lib/types/ink/wrapAnsi.js +29 -2
- package/lib/types/plugin-host.d.ts +13 -11
- package/lib/types/plugin-host.d.ts.map +1 -1
- package/lib/types/plugin-host.js +16 -16
- package/lib/types/plugin-spec/registry.d.ts +2 -2
- package/lib/types/plugin-spec/registry.d.ts.map +1 -1
- package/lib/types/plugin-spec/registry.js +113 -18
- package/lib/types/plugin-spec/tui-extension.d.ts.map +1 -1
- package/lib/types/plugin-spec/tui-extension.js +2 -0
- package/lib/types/plugin-spec/validate.d.ts.map +1 -1
- package/lib/types/plugin-spec/validate.js +20 -1
- package/lib/types/scenes.d.ts +2 -1
- package/lib/types/scenes.d.ts.map +1 -1
- package/lib/types/scenes.js +1 -1
- package/lib/types/screens/Chat.d.ts +3 -3
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +38 -17
- package/lib/types/screens/SessionBrowser.d.ts.map +1 -1
- package/lib/types/screens/SessionBrowser.js +10 -3
- package/lib/types/sessions/view.d.ts +3 -2
- package/lib/types/sessions/view.d.ts.map +1 -1
- package/lib/types/sessions/view.js +18 -0
- package/lib/types/settings-sections.d.ts +2 -1
- package/lib/types/settings-sections.d.ts.map +1 -1
- package/lib/types/settings-sections.js +1 -1
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +3 -0
- package/lib/types/workspaces.d.ts +2 -1
- package/lib/types/workspaces.d.ts.map +1 -1
- package/lib/types/workspaces.js +1 -1
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/command/package.json +1 -1
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +1 -1
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/core/package.json +1 -1
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/manifest/package.json +1 -1
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/messages/package.json +1 -1
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/node_modules/@dsh-std/presentation/README.md +2 -1
- package/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +7 -3
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -0
- package/node_modules/@dsh-std/storage/package.json +1 -1
- package/package.json +10 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +2 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.d.ts +2 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js +179 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -0
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts +44 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.d.ts.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js +6 -3
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/package.json +7 -3
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.d.ts.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js +1 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -0
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +1 -1
- package/ecosystem-spec/registry/registry-0.15.json +0 -57
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/contracts/decision-events-v1alpha1.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/registry/host-descriptor.tui.example.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/conformance-claim.schema.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/effect-ledger-record.schema.json +0 -0
- /package/{ecosystem-spec → dsh-ecosystem-spec}/schemas/host-descriptor.schema.json +0 -0
package/lib/types/plugin-host.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
//
|
|
2
|
-
// boundary
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
export { DECISION_EVENT_PERMISSIONS,
|
|
16
|
-
export { DECISION_HANDLER_TIMEOUT_MS, DECISION_TOTAL_TIMEOUT_MS,
|
|
1
|
+
// Public plugin-host shim. Keep the Cordis-backed implementation behind the
|
|
2
|
+
// adapter boundary: plugin authors receive protocol types and mediated service
|
|
3
|
+
// contracts, while loader-only admission, host ingress, mutable stores and
|
|
4
|
+
// attribution registries remain adapter-internal. Type-only runtime exports
|
|
5
|
+
// still load the adapter declarations so Context augmentation is available.
|
|
6
|
+
export { name, apply } from './dsh-adapter/plugin-host.js';
|
|
7
|
+
export { PluginStorageError, STORAGE_KEY_MAX_LENGTH, STORAGE_MAX_BYTES, STORAGE_MAX_KEYS } from './dsh-adapter/plugin-storage.js';
|
|
8
|
+
// The host-only message ingress accessor stays in the adapter module. Plugin
|
|
9
|
+
// authors receive the broker's subscribe surface and envelope vocabulary only.
|
|
10
|
+
export { OBSERVE_CALLBACK_QUEUE_LIMIT, OBSERVE_CALLBACK_TIMEOUT_MS, OBSERVE_CONTENT_MAX_CHARS, OBSERVE_ID_MAX_CHARS, OBSERVE_IMAGE_BASE64_MAX_CHARS, OBSERVE_IMAGE_MAX_BYTES, OBSERVE_SCOPE_MAX_CHARS, OBSERVE_SUMMARY_CELLS, } from './dsh-adapter/message-observer.js';
|
|
11
|
+
export { COMMAND_ERROR_CODES, hasCommandErrorCode, mapCommandError, withCommandErrorMapping, } from './dsh-adapter/command-errors.js';
|
|
12
|
+
// Command attribution and decision registration are host-internal. Exposing
|
|
13
|
+
// these functions would let a plugin inspect or rewrite another plugin's
|
|
14
|
+
// checkpoint, or install an unmediated handler.
|
|
15
|
+
export { DECISION_EVENT_PERMISSIONS, } from './dsh-adapter/decision-guard.js';
|
|
16
|
+
export { DECISION_HANDLER_TIMEOUT_MS, DECISION_TOTAL_TIMEOUT_MS, } from './dsh-adapter/extension-events.js';
|
|
17
17
|
export { DECISION_EVENTS_COORDINATE, TUI_EXTENSION_API_VERSION, TUI_DECISION_EVENT_NAMES, TUI_EXTENSION_PERMISSION_NAMES, createAdmissionCatalog, } from './plugin-spec/tui-extension.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Load and verify the pinned dsh-TUI admission profile. */
|
|
2
2
|
import type { ContractRegistry, PermissionRegistry, RegistryEntry } from './types.js';
|
|
3
|
-
export declare const DSH_STD_REVISION = "
|
|
4
|
-
export declare const ECOSYSTEM_SPEC_REVISION = "
|
|
3
|
+
export declare const DSH_STD_REVISION = "614dfa1ac168db79fcf4577cf0ebb34e2e3b944b";
|
|
4
|
+
export declare const ECOSYSTEM_SPEC_REVISION = "e1b902b0f95f4280a8e68d414ec7a4d25d6ce106";
|
|
5
5
|
export interface SpecData {
|
|
6
6
|
dir: string;
|
|
7
7
|
registry: ContractRegistry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/registry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAO5D,OAAO,KAAK,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/registry.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAO5D,OAAO,KAAK,EAAE,gBAAgB,EAAmB,kBAAkB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAEtG,eAAO,MAAM,gBAAgB,6CAA6C,CAAA;AAC1E,eAAO,MAAM,uBAAuB,6CAA6C,CAAA;AAEjF,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAC/B,CAAA;CACF;AAuBD,wBAAgB,aAAa,CAAC,KAAK,GAAE,MAAgD,GAAG,MAAM,GAAG,SAAS,CASzG;AAiFD,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,GAAG,SAA2B,GAAG,QAAQ,GAAG,SAAS,CAiB5F;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,gBAAgB,GAAG,aAAa,EAAE,CAI3E;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,MAAM,EAAE,CAE5E;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAuCvD;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CA2C/D"}
|
|
@@ -4,14 +4,32 @@ import { existsSync, readFileSync } from 'node:fs';
|
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
6
|
import { createAdmissionCatalog } from './tui-extension.js';
|
|
7
|
-
export const DSH_STD_REVISION = '
|
|
8
|
-
export const ECOSYSTEM_SPEC_REVISION = '
|
|
7
|
+
export const DSH_STD_REVISION = '614dfa1ac168db79fcf4577cf0ebb34e2e3b944b';
|
|
8
|
+
export const ECOSYSTEM_SPEC_REVISION = 'e1b902b0f95f4280a8e68d414ec7a4d25d6ce106';
|
|
9
9
|
const REGISTRY_FILE = join('registry', 'registry-0.15.json');
|
|
10
|
+
const EXPECTED_PROFILE_VERSION = 'tui-admission/0.15';
|
|
11
|
+
const EXPECTED_STD_REPOSITORY = 'https://github.com/Yan-Zero/dsh-std';
|
|
12
|
+
const EXPECTED_STD_SUBMODULE = 'vendor/dsh-std';
|
|
13
|
+
const EXPECTED_STD_MANIFEST_VERSION = '0.15';
|
|
14
|
+
const EXPECTED_PERMISSION_REGISTRY_VERSION = '0.1';
|
|
15
|
+
// The permission registry is policy, not merely input data. Keep the
|
|
16
|
+
// admission defaults and scopes pinned to the reviewed dsh-ecosystem-spec
|
|
17
|
+
// revision so a locally modified copy cannot silently widen a capability.
|
|
18
|
+
const EXPECTED_PERMISSIONS = Object.freeze([
|
|
19
|
+
{ name: 'storage.local.read', default: 'deny', revocable: true, scope: 'plugin namespace' },
|
|
20
|
+
{ name: 'storage.local.write', default: 'deny', revocable: true, scope: 'plugin namespace' },
|
|
21
|
+
{ name: 'commands.invoke', default: 'allow', revocable: true, scope: 'declared command id' },
|
|
22
|
+
{ name: 'messages.observe.read', default: 'deny', revocable: true, scope: 'message observation scope' },
|
|
23
|
+
{ name: 'session.input.intercept', default: 'deny', revocable: true, scope: 'decision event subscription' },
|
|
24
|
+
{ name: 'session.rewind.intercept', default: 'deny', revocable: true, scope: 'decision event subscription' },
|
|
25
|
+
{ name: 'session.switch.intercept', default: 'deny', revocable: true, scope: 'decision event subscription' },
|
|
26
|
+
{ name: 'session.compact.intercept', default: 'deny', revocable: true, scope: 'decision event subscription' },
|
|
27
|
+
]);
|
|
10
28
|
export function locateSpecDir(start = dirname(fileURLToPath(import.meta.url))) {
|
|
11
29
|
let dir = start;
|
|
12
30
|
for (let index = 0; index < 8; index++) {
|
|
13
|
-
if (existsSync(join(dir, 'ecosystem-spec', REGISTRY_FILE)))
|
|
14
|
-
return join(dir, 'ecosystem-spec');
|
|
31
|
+
if (existsSync(join(dir, 'dsh-ecosystem-spec', REGISTRY_FILE)))
|
|
32
|
+
return join(dir, 'dsh-ecosystem-spec');
|
|
15
33
|
const parent = dirname(dir);
|
|
16
34
|
if (parent === dir)
|
|
17
35
|
return undefined;
|
|
@@ -26,41 +44,89 @@ function isRecord(value) {
|
|
|
26
44
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
27
45
|
}
|
|
28
46
|
function soundEntry(value, privateDefinition) {
|
|
29
|
-
if (!isRecord(value) || typeof value.name !== 'string' ||
|
|
47
|
+
if (!isRecord(value) || typeof value.name !== 'string' || value.name === ''
|
|
48
|
+
|| (value.kind !== 'capability' && value.kind !== 'event'))
|
|
30
49
|
return false;
|
|
31
50
|
if (!isRecord(value.coordinates)
|
|
32
|
-
|| typeof value.coordinates.apiVersion !== 'string'
|
|
33
|
-
|| typeof value.coordinates.kind !== 'string')
|
|
51
|
+
|| typeof value.coordinates.apiVersion !== 'string' || value.coordinates.apiVersion === ''
|
|
52
|
+
|| typeof value.coordinates.kind !== 'string' || value.coordinates.kind === '')
|
|
34
53
|
return false;
|
|
35
54
|
if (!Array.isArray(value.permissions) || !value.permissions.every(permission => typeof permission === 'string'))
|
|
36
55
|
return false;
|
|
37
56
|
if (privateDefinition) {
|
|
38
57
|
return value.authority === 'dsh-tui'
|
|
39
58
|
&& typeof value.profile === 'string'
|
|
40
|
-
&&
|
|
59
|
+
&& value.profile.length > 0
|
|
60
|
+
&& typeof value.profileHash === 'string'
|
|
61
|
+
&& /^sha256:[0-9a-f]{64}$/u.test(value.profileHash);
|
|
41
62
|
}
|
|
42
|
-
return typeof value.package === 'string' && value.package
|
|
63
|
+
return typeof value.package === 'string' && /^@dsh-std\/[a-z0-9][a-z0-9-]*$/u.test(value.package);
|
|
43
64
|
}
|
|
44
65
|
function structurallySound(data) {
|
|
45
66
|
if (!isRecord(data.registry)
|
|
46
|
-
||
|
|
67
|
+
|| data.registry.profileVersion !== EXPECTED_PROFILE_VERSION
|
|
47
68
|
|| !isRecord(data.registry.std)
|
|
69
|
+
|| data.registry.std.repository !== EXPECTED_STD_REPOSITORY
|
|
70
|
+
|| data.registry.std.submodule !== EXPECTED_STD_SUBMODULE
|
|
71
|
+
|| data.registry.std.manifestVersion !== EXPECTED_STD_MANIFEST_VERSION
|
|
48
72
|
|| !Array.isArray(data.registry.imports)
|
|
49
73
|
|| !Array.isArray(data.registry.definitions)
|
|
50
74
|
|| !Array.isArray(data.registry.facetApiVersions)
|
|
51
|
-
||
|
|
75
|
+
|| data.registry.facetApiVersions.length === 0
|
|
76
|
+
|| !data.registry.facetApiVersions.every(version => typeof version === 'string'
|
|
77
|
+
&& /^v[0-9]+(?:alpha[0-9]+|beta[0-9]+)?$/u.test(version)))
|
|
78
|
+
return false;
|
|
79
|
+
if (new Set(data.registry.facetApiVersions).size !== data.registry.facetApiVersions.length)
|
|
52
80
|
return false;
|
|
53
81
|
if (!data.registry.imports.every(entry => soundEntry(entry, false)))
|
|
54
82
|
return false;
|
|
55
83
|
if (!data.registry.definitions.every(entry => soundEntry(entry, true)))
|
|
56
84
|
return false;
|
|
57
|
-
|
|
85
|
+
const entries = [...data.registry.imports, ...data.registry.definitions];
|
|
86
|
+
const names = new Set();
|
|
87
|
+
const coordinates = new Set();
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
if (names.has(entry.name))
|
|
90
|
+
return false;
|
|
91
|
+
names.add(entry.name);
|
|
92
|
+
const key = `${entry.coordinates.apiVersion}#${entry.coordinates.kind}`;
|
|
93
|
+
if (coordinates.has(key))
|
|
94
|
+
return false;
|
|
95
|
+
coordinates.add(key);
|
|
96
|
+
if ('authority' in entry && !entry.coordinates.apiVersion.startsWith('tui.dsh/'))
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
if (!isRecord(data.permissions)
|
|
100
|
+
|| data.permissions.registryVersion !== EXPECTED_PERMISSION_REGISTRY_VERSION
|
|
101
|
+
|| !Array.isArray(data.permissions.permissions)
|
|
102
|
+
|| data.permissions.permissions.length !== EXPECTED_PERMISSIONS.length)
|
|
58
103
|
return false;
|
|
104
|
+
const expectedPermissions = new Map(EXPECTED_PERMISSIONS.map(permission => [permission.name, permission]));
|
|
105
|
+
const permissionNames = new Set();
|
|
59
106
|
for (const permission of data.permissions.permissions) {
|
|
60
107
|
if (!isRecord(permission) || typeof permission.name !== 'string'
|
|
61
|
-
|| (permission.default !== 'allow' && permission.default !== 'deny')
|
|
108
|
+
|| (permission.default !== 'allow' && permission.default !== 'deny')
|
|
109
|
+
|| typeof permission.revocable !== 'boolean'
|
|
110
|
+
|| typeof permission.scope !== 'string'
|
|
111
|
+
|| permission.scope.trim() === '')
|
|
112
|
+
return false;
|
|
113
|
+
if (permissionNames.has(permission.name))
|
|
114
|
+
return false;
|
|
115
|
+
permissionNames.add(permission.name);
|
|
116
|
+
const expected = expectedPermissions.get(permission.name);
|
|
117
|
+
if (expected === undefined
|
|
118
|
+
|| permission.default !== expected.default
|
|
119
|
+
|| permission.revocable !== expected.revocable
|
|
120
|
+
|| permission.scope !== expected.scope)
|
|
121
|
+
return false;
|
|
122
|
+
if ('rationale' in permission && permission.rationale !== undefined && typeof permission.rationale !== 'string')
|
|
62
123
|
return false;
|
|
63
124
|
}
|
|
125
|
+
if (permissionNames.size !== expectedPermissions.size)
|
|
126
|
+
return false;
|
|
127
|
+
const knownPermissions = new Set(expectedPermissions.keys());
|
|
128
|
+
if (!entries.every(entry => entry.permissions.every(permission => knownPermissions.has(permission))))
|
|
129
|
+
return false;
|
|
64
130
|
return Object.values(data.schemas).every(isRecord);
|
|
65
131
|
}
|
|
66
132
|
export function loadSpecData(dir = locateSpecDir()) {
|
|
@@ -94,13 +160,32 @@ export function digestFile(dir, relative) {
|
|
|
94
160
|
/** Verify definition availability and private profile digest pins. */
|
|
95
161
|
export function verifyRegistry(data) {
|
|
96
162
|
const failures = [];
|
|
97
|
-
|
|
98
|
-
|
|
163
|
+
const registry = data?.registry;
|
|
164
|
+
if (!isRecord(registry)
|
|
165
|
+
|| !Array.isArray(registry.imports)
|
|
166
|
+
|| !Array.isArray(registry.definitions)) {
|
|
99
167
|
return ['registry imports/definitions are malformed'];
|
|
100
168
|
}
|
|
169
|
+
const names = new Set();
|
|
170
|
+
const coordinates = new Set();
|
|
101
171
|
const { protocols } = createAdmissionCatalog();
|
|
102
|
-
for (const
|
|
172
|
+
for (const raw of [...registry.imports, ...registry.definitions]) {
|
|
173
|
+
const privateDefinition = registry.definitions.includes(raw);
|
|
174
|
+
if (!soundEntry(raw, privateDefinition)) {
|
|
175
|
+
failures.push('registry entry is malformed');
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
const entry = raw;
|
|
103
179
|
const key = `${entry.coordinates.apiVersion}#${entry.coordinates.kind}`;
|
|
180
|
+
if (names.has(entry.name))
|
|
181
|
+
failures.push(`${entry.name}: duplicate registry name`);
|
|
182
|
+
names.add(entry.name);
|
|
183
|
+
if (coordinates.has(key))
|
|
184
|
+
failures.push(`${key}: duplicate registry coordinate`);
|
|
185
|
+
coordinates.add(key);
|
|
186
|
+
if ('authority' in entry && !entry.coordinates.apiVersion.startsWith('tui.dsh/')) {
|
|
187
|
+
failures.push(`${key}: dsh-tui definition must use the private protocol group`);
|
|
188
|
+
}
|
|
104
189
|
if (!protocols.understands(entry.coordinates))
|
|
105
190
|
failures.push(`${key}: ProtocolCatalog definition unavailable`);
|
|
106
191
|
if ('profile' in entry) {
|
|
@@ -125,13 +210,23 @@ export function verifyContractProfiles(data) {
|
|
|
125
210
|
'errors', 'concurrency', 'timeout', 'cleanup', 'privacyClass', 'securityBoundary',
|
|
126
211
|
];
|
|
127
212
|
const failures = [];
|
|
128
|
-
if (!
|
|
213
|
+
if (!isRecord(data?.registry)
|
|
214
|
+
|| !Array.isArray(data.registry.definitions)) {
|
|
129
215
|
return ['registry definitions are malformed'];
|
|
130
216
|
}
|
|
131
217
|
for (const entry of data.registry.definitions) {
|
|
218
|
+
if (!soundEntry(entry, true)) {
|
|
219
|
+
failures.push('registry definition is malformed');
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
132
222
|
let profile;
|
|
133
223
|
try {
|
|
134
|
-
|
|
224
|
+
const loaded = loadJson(data.dir, entry.profile);
|
|
225
|
+
if (!isRecord(loaded)) {
|
|
226
|
+
failures.push(`${entry.name}: private profile is not an object (${entry.profile})`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
profile = loaded;
|
|
135
230
|
}
|
|
136
231
|
catch {
|
|
137
232
|
failures.push(`${entry.name}: private profile unreadable (${entry.profile})`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-extension.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/tui-extension.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"tui-extension.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/tui-extension.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAE3E,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAsB,MAAM,eAAe,CAAA;AAC5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAM7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,eAAO,MAAM,yBAAyB,qBAAqB,CAAA;AAE3D,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,kBAAkB,CAGlE,CAAA;AAEF,eAAO,MAAM,wBAAwB,6HAO1B,CAAA;AAEX,eAAO,MAAM,8BAA8B,2HAKhC,CAAA;AAiBX,eAAO,MAAM,wBAAwB,EAAE,kBAsBrC,CAAA;AAEF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,eAAe,CAAA;IAC1B,SAAS,EAAE,yBAAyB,CAAA;CACrC;AAED,gFAAgF;AAChF,wBAAgB,sBAAsB,IAAI,gBAAgB,CAUzD"}
|
|
@@ -5,6 +5,7 @@ import { register as registerCommand } from '@dsh-std/command';
|
|
|
5
5
|
import { register as registerMessages } from '@dsh-std/messages';
|
|
6
6
|
import { register as registerPresentation } from '@dsh-std/presentation';
|
|
7
7
|
import { register as registerStorage } from '@dsh-std/storage';
|
|
8
|
+
import { tuiChannelDefinition } from '#dsh-ecosystem-spec/tui-channel';
|
|
8
9
|
export const TUI_EXTENSION_API_VERSION = 'tui.dsh/v1alpha1';
|
|
9
10
|
export const DECISION_EVENTS_COORDINATE = Object.freeze({
|
|
10
11
|
apiVersion: TUI_EXTENSION_API_VERSION,
|
|
@@ -73,5 +74,6 @@ export function createAdmissionCatalog() {
|
|
|
73
74
|
registerMessages(protocols);
|
|
74
75
|
registerPresentation(protocols);
|
|
75
76
|
protocols.register(decisionEventsDefinition);
|
|
77
|
+
protocols.register(tuiChannelDefinition);
|
|
76
78
|
return { protocols, manifests };
|
|
77
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/validate.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAG9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,SAAS,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,WAAW,CAAC,CAAA;IACjE,SAAS,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,WAAW,CAAC,CAAA;IACjE,cAAc,CAAC,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAA;IACzE,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG;QAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,CAAA;IAC1G,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAAA;CACzD;AAGD,eAAO,MAAM,OAAO,GAAI,YAAY,MAAM,KAAG,MAAwC,CAAA;AAErF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,GAAG,aAAa,CAsC9G;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/plugin-spec/validate.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAG9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AAG3D,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,WAAW,EAAE,kBAAkB,CAAA;IAC/B,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,SAAS,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,WAAW,CAAC,CAAA;IACjE,SAAS,EAAE,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,WAAW,CAAC,CAAA;IACjE,cAAc,CAAC,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAAG,SAAS,CAAA;IACzE,kBAAkB,CAAC,GAAG,EAAE,kBAAkB,GAAG;QAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;QAAC,mBAAmB,EAAE,OAAO,CAAA;KAAE,CAAA;IAC1G,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,aAAa,CAAA;CACzD;AAGD,eAAO,MAAM,OAAO,GAAI,YAAY,MAAM,KAAG,MAAwC,CAAA;AAErF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,kBAAkB,GAAG,aAAa,CAsC9G;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,cAAc,GAAG,IAAI,CA4DnF;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CA4B7E"}
|
|
@@ -58,7 +58,18 @@ export function validatePlugin(index, manifest) {
|
|
|
58
58
|
index.resolveSubscription(subscription);
|
|
59
59
|
const knownPermissions = new Set(index.permissions.permissions.map(permission => permission.name));
|
|
60
60
|
const commandIds = new Set(manifest.contributes.commands.map(command => command.id));
|
|
61
|
-
const requiresDecisionEvents = manifest.requires.contracts.some(requirement => requirement.
|
|
61
|
+
const requiresDecisionEvents = manifest.requires.contracts.some(requirement => requirement.kind === 'DecisionEvents'
|
|
62
|
+
&& groupOf(requirement.apiVersion) === groupOf('tui.dsh/v1alpha1'));
|
|
63
|
+
const capabilityForPermission = {
|
|
64
|
+
'commands.invoke': { apiVersion: 'commands.dsh/v1alpha1', kind: 'Command' },
|
|
65
|
+
'storage.local.read': { apiVersion: 'storage.dsh/v1alpha1', kind: 'LocalStorage' },
|
|
66
|
+
'storage.local.write': { apiVersion: 'storage.dsh/v1alpha1', kind: 'LocalStorage' },
|
|
67
|
+
'messages.observe.read': { apiVersion: 'messages.dsh/v1alpha1', kind: 'MessageObserver' },
|
|
68
|
+
'session.input.intercept': { apiVersion: 'tui.dsh/v1alpha1', kind: 'DecisionEvents' },
|
|
69
|
+
'session.rewind.intercept': { apiVersion: 'tui.dsh/v1alpha1', kind: 'DecisionEvents' },
|
|
70
|
+
'session.switch.intercept': { apiVersion: 'tui.dsh/v1alpha1', kind: 'DecisionEvents' },
|
|
71
|
+
'session.compact.intercept': { apiVersion: 'tui.dsh/v1alpha1', kind: 'DecisionEvents' },
|
|
72
|
+
};
|
|
62
73
|
for (const permission of manifest.permissions) {
|
|
63
74
|
if (!knownPermissions.has(permission.name)) {
|
|
64
75
|
throw new Error(`permission is not admitted by the TUI profile: ${permission.name}`);
|
|
@@ -72,6 +83,14 @@ export function validatePlugin(index, manifest) {
|
|
|
72
83
|
if (INTERCEPT_PERMISSIONS.has(permission.name) && !requiresDecisionEvents) {
|
|
73
84
|
throw new Error(`${permission.name} requires tui.dsh/v1alpha1#DecisionEvents`);
|
|
74
85
|
}
|
|
86
|
+
const capability = capabilityForPermission[permission.name];
|
|
87
|
+
// An otherwise valid contract reference may use an unregistered version
|
|
88
|
+
// from the same protocol group. Keep that manifest structurally valid so
|
|
89
|
+
// negotiation can return UNKNOWN_PROTOCOL_VERSION rather than letting the
|
|
90
|
+
// permission/capability cross-check mask the version-drift decision.
|
|
91
|
+
if (capability !== undefined && !manifest.requires.contracts.some(requirement => requirement.kind === capability.kind && groupOf(requirement.apiVersion) === groupOf(capability.apiVersion))) {
|
|
92
|
+
throw new Error(`${permission.name} requires ${capability.apiVersion}#${capability.kind}`);
|
|
93
|
+
}
|
|
75
94
|
}
|
|
76
95
|
for (const commandId of commandIds) {
|
|
77
96
|
if (!manifest.permissions.some(permission => permission.name === 'commands.invoke' && permission.scope === commandId)) {
|
package/lib/types/scenes.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { name, TuiSceneRuntime } from './dsh-adapter/scenes.js';
|
|
2
|
+
export type { TuiSceneProps, TuiSceneDescriptor } from './dsh-adapter/scenes.js';
|
|
2
3
|
export { default } from './dsh-adapter/scenes.js';
|
|
3
4
|
//# sourceMappingURL=scenes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../src/scenes.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"scenes.d.ts","sourceRoot":"","sources":["../../src/scenes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAC/D,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA"}
|
package/lib/types/scenes.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Re-export shim: the Cordis-backed implementation lives behind the adapter
|
|
2
2
|
// boundary so UI consumers never import official @deepseek-ai/* packages.
|
|
3
|
-
export
|
|
3
|
+
export { name, TuiSceneRuntime } from './dsh-adapter/scenes.js';
|
|
4
4
|
export { default } from './dsh-adapter/scenes.js';
|
|
@@ -3,7 +3,7 @@ import { type Channel } from '../dsh-adapter/channel.js';
|
|
|
3
3
|
import type { QuestionStore } from '../dsh-adapter/questions.js';
|
|
4
4
|
import { TuiDialogStore } from '../dsh-adapter/dialogs.js';
|
|
5
5
|
import { TuiStatusStore } from '../dsh-adapter/status.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { TuiShortcutHost } from '../dsh-adapter/shortcuts.js';
|
|
7
7
|
import { ApprovalStore } from '../dsh-adapter/approvals.js';
|
|
8
8
|
export declare function Chat({ channel, questionStore, approvalStore, extensionDialogs, extensionStatus, extensionShortcuts, onExit, onUpdate, fullscreen, trajectorySeen: trajectorySeenProp, }: {
|
|
9
9
|
channel: Channel;
|
|
@@ -22,8 +22,8 @@ export declare function Chat({ channel, questionStore, approvalStore, extensionD
|
|
|
22
22
|
extensionDialogs?: TuiDialogStore;
|
|
23
23
|
/** Plugin status-line contributions (tuiStatus service's store). */
|
|
24
24
|
extensionStatus?: TuiStatusStore;
|
|
25
|
-
/**
|
|
26
|
-
extensionShortcuts?:
|
|
25
|
+
/** Host-only keyboard shortcut dispatch path. */
|
|
26
|
+
extensionShortcuts?: TuiShortcutHost;
|
|
27
27
|
onExit: () => void;
|
|
28
28
|
/** Update the installed package and restart the current TUI process. */
|
|
29
29
|
onUpdate?: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/screens/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,EAAqB,KAAK,OAAO,EAAsE,MAAM,2BAA2B,CAAA;AAC/I,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/screens/Chat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AASzB,OAAO,EAAqB,KAAK,OAAO,EAAsE,MAAM,2BAA2B,CAAA;AAC/I,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAwI3D,wBAAgB,IAAI,CAAC,EACnB,OAAO,EACP,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,QAAQ,EACR,UAAkB,EAClB,cAAc,EAAE,kBAAkB,GACnC,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,aAAa,EAAE,aAAa,CAAA;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAA;IACjC,oEAAoE;IACpE,eAAe,CAAC,EAAE,cAAc,CAAA;IAChC,iDAAiD;IACjD,kBAAkB,CAAC,EAAE,eAAe,CAAA;IACpC,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAA;IACrB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,qBAwlEA"}
|
|
@@ -164,12 +164,9 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
164
164
|
React.useEffect(() => {
|
|
165
165
|
if (extensionShortcuts === undefined)
|
|
166
166
|
return;
|
|
167
|
-
extensionShortcuts.
|
|
167
|
+
return extensionShortcuts.setErrorHandler(combo => {
|
|
168
168
|
channel.notify(t('ext-shortcut-failed', { combo }), { color: 'error', timeoutMs: 4000 });
|
|
169
|
-
};
|
|
170
|
-
return () => {
|
|
171
|
-
extensionShortcuts.onError = undefined;
|
|
172
|
-
};
|
|
169
|
+
});
|
|
173
170
|
}, [extensionShortcuts, channel]);
|
|
174
171
|
// When a questionnaire batch completes, fold a Q&A summary into the
|
|
175
172
|
// transcript (the tool card itself is hidden from the message list).
|
|
@@ -277,15 +274,9 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
277
274
|
/**
|
|
278
275
|
* Close the scene.
|
|
279
276
|
*
|
|
280
|
-
* Leaving the alternate screen makes the terminal restore the main buffer
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* round trip — the same, already-accepted cost as the Ctrl+X external-editor
|
|
284
|
-
* handoff, and bounded per OPEN rather than per keystroke. Making it zero
|
|
285
|
-
* needs the render core to save and restore the pre-alt front frame, which
|
|
286
|
-
* is a separate change to `setAltScreenActive` and deliberately not made
|
|
287
|
-
* here. `verify-trace-scene` pins the property that matters meanwhile:
|
|
288
|
-
* navigating inside the scene adds nothing at all.
|
|
277
|
+
* Leaving the alternate screen makes the terminal restore the main buffer;
|
|
278
|
+
* Ink restores the matching saved frame and diffs any conversation changes
|
|
279
|
+
* that happened while the scene was open.
|
|
289
280
|
*/
|
|
290
281
|
const closeScene = React.useCallback(() => {
|
|
291
282
|
setSceneOpen(false);
|
|
@@ -302,6 +293,8 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
302
293
|
}, []);
|
|
303
294
|
/** The startup summary gives way to transcript rows after the first local command or message. */
|
|
304
295
|
const loadedContextVisible = channel.rows.length === 0 && channel.loadedContext !== undefined;
|
|
296
|
+
/** Startup context panel: collapsed by default, toggled with Ctrl+P. */
|
|
297
|
+
const [loadedContextOpen, setLoadedContextOpen] = React.useState(false);
|
|
305
298
|
/** `/` transcript search (less-style incsearch, ported from CC's REPL). */
|
|
306
299
|
const [searchOpen, setSearchOpen] = React.useState(false);
|
|
307
300
|
const [searchQuery, setSearchQuery] = React.useState('');
|
|
@@ -581,7 +574,8 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
581
574
|
case 'lang': {
|
|
582
575
|
// `/lang` shows the current UI language, `/lang en|zh` switches
|
|
583
576
|
// (hot-swap, persisted to ~/.dsh-tui/lang.json). Precedence on next
|
|
584
|
-
// launch: DSH_TUI_LANG >
|
|
577
|
+
// launch: DSH_TUI_LANG > settings.yaml `dsh-tui.lang` > cordis.yml
|
|
578
|
+
// `lang` > the persisted choice.
|
|
585
579
|
const parts = rawInput.trim().split(/\s+/).filter(Boolean);
|
|
586
580
|
if (parts[0] === 'status') {
|
|
587
581
|
setHelpOpen(false);
|
|
@@ -597,6 +591,16 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
597
591
|
if (isLang(parts[0])) {
|
|
598
592
|
const ok = writeLangPref(parts[0]);
|
|
599
593
|
setLang(parts[0]);
|
|
594
|
+
// Mirror into the dsh-tui settings namespace when it is served,
|
|
595
|
+
// so /settings and the next boot see the same last-write-wins
|
|
596
|
+
// choice (best effort; lang.json stays the fallback).
|
|
597
|
+
const settingsHost = channel.settingsHost();
|
|
598
|
+
const tuiView = settingsHost?.listNamespaces().find(entry => entry.ns === 'dsh-tui');
|
|
599
|
+
if (settingsHost !== undefined && tuiView !== undefined) {
|
|
600
|
+
void settingsHost
|
|
601
|
+
.write('dsh-tui', [{ op: 'set', path: ['lang'], value: parts[0] }], tuiView.revision)
|
|
602
|
+
.catch(() => { });
|
|
603
|
+
}
|
|
600
604
|
channel.notify(ok ? t('lang-switched', { lang: parts[0] }) : t('lang-switch-failed', { lang: parts[0] }), { color: ok ? 'success' : 'error' });
|
|
601
605
|
}
|
|
602
606
|
else {
|
|
@@ -1805,10 +1809,17 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
1805
1809
|
return;
|
|
1806
1810
|
}
|
|
1807
1811
|
if (isMod(key) && input === 't') {
|
|
1808
|
-
// Ctrl+T
|
|
1812
|
+
// Ctrl+T opens the trajectory scene at any point in the session.
|
|
1809
1813
|
openScene();
|
|
1810
1814
|
return;
|
|
1811
1815
|
}
|
|
1816
|
+
if (isMod(key) && input === 'p' && loadedContextVisible) {
|
|
1817
|
+
// Ctrl+P toggles the startup loaded-context panel while it is on
|
|
1818
|
+
// screen (transcript still empty); once rows take over and the
|
|
1819
|
+
// panel disappears the key has nothing left to do.
|
|
1820
|
+
setLoadedContextOpen(previous => !previous);
|
|
1821
|
+
return;
|
|
1822
|
+
}
|
|
1812
1823
|
if (isMod(key) && input === 'r' && !helpOpen) {
|
|
1813
1824
|
setHistoryQuery('');
|
|
1814
1825
|
setHistoryCursor(0);
|
|
@@ -1854,6 +1865,16 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
1854
1865
|
else if (isMod(key) && input === 'o') {
|
|
1855
1866
|
// Leaving transcript mode (Ctrl+O) — search was already handled above.
|
|
1856
1867
|
setExpanded(previous => !previous);
|
|
1868
|
+
// The toggle rewrites every thinking row's layout at once. The
|
|
1869
|
+
// ordinary scroll-based diff pushes rows into terminal scrollback on
|
|
1870
|
+
// each expand and nothing removes them on collapse — rapid toggling
|
|
1871
|
+
// drifts the virtual↔scrollback mapping until writes misland
|
|
1872
|
+
// (garbled transcript, duplicated rows). Re-anchor the next frame:
|
|
1873
|
+
// in-place viewport repaint, nothing added to scrollback. Lookup
|
|
1874
|
+
// falls back to the only live instance for embedders whose stdout
|
|
1875
|
+
// isn't process.stdout (test harnesses).
|
|
1876
|
+
const ink = instances.get(process.stdout) ?? instances.values().next().value;
|
|
1877
|
+
ink?.reanchorViewport();
|
|
1857
1878
|
}
|
|
1858
1879
|
else if (input === '/' && !key.ctrl && !key.meta && !key.super) {
|
|
1859
1880
|
// `/` in transcript mode (Ctrl+O expanded, CC's REPL semantics:
|
|
@@ -1986,7 +2007,7 @@ export function Chat({ channel, questionStore, approvalStore, extensionDialogs,
|
|
|
1986
2007
|
seekRow(lastUser.id);
|
|
1987
2008
|
else
|
|
1988
2009
|
handle?.scrollToBottom();
|
|
1989
|
-
} })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
|
|
2010
|
+
} })), _jsxs(ScrollBox, { ref: setHandle, flexDirection: "column", flexGrow: 1, flexShrink: 1, stickyScroll: true, children: [_jsx(LogoHeader, { model: channel.model, effort: channel.reasoningEffort, cwd: channel.displayCwd }), loadedContextVisible && (_jsx(LoadedContextPanel, { context: channel.loadedContext, open: loadedContextOpen, onToggle: () => { setLoadedContextOpen(previous => !previous); } })), _jsx(MessageList, { rows: channel.rows, failureHintRowId: failureHintRowId, failureHint: t('traj-hint-failure', { key: `${modLabel}t` }), expanded: expanded, expandedRows: expandedRows, selectedId: selectionActive ? selectedId : null, onToggleRow: toggleRowExpanded, model: channel.model, diffLayout: channel.diffLayout, thinkingFold: channel.thinkingFold, showAll: showAllMessages, thinkingVisible: thinkingVisible, onToggleAll: () => { setShowAllMessages(previous => !previous); }, onLoadOlder: () => channel.loadOlder(), registerRowRef: registerRowRef, scrollHandle: handle, forceMountRowId: forceMountRowId, newSinceRowId: isSticky ? null : lastSeenRowIdRef.current, onUnseenCount: setUnseenCount })] }), _jsxs(Box, { flexDirection: "column", flexShrink: 0, children: [showPill && (_jsx(NewMessagesPill, { count: unseenCount, onClick: () => handle?.scrollToBottom() })), channel.working &&
|
|
1990
2011
|
(channel.activityEnabled &&
|
|
1991
2012
|
channel.workingActivity !== undefined &&
|
|
1992
2013
|
channel.workingActivity.line !== '' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionBrowser.d.ts","sourceRoot":"","sources":["../../../src/screens/SessionBrowser.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAsBzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAoDxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,WAAW,EACX,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,
|
|
1
|
+
{"version":3,"file":"SessionBrowser.d.ts","sourceRoot":"","sources":["../../../src/screens/SessionBrowser.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAsBzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAA;AAoDxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,IAAI,EACJ,WAAW,EACX,OAAO,GACR,EAAE;IACD,OAAO,EAAE,OAAO,CAAA;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;IAC9C,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CA4elB"}
|
|
@@ -354,13 +354,20 @@ export function SessionBrowser({ channel, home, sameProject, onClose, }) {
|
|
|
354
354
|
// did. `resumeTo` reports its own reasons; this only has to stay put.
|
|
355
355
|
runAction(async () => {
|
|
356
356
|
try {
|
|
357
|
-
const
|
|
358
|
-
if (ok) {
|
|
357
|
+
const result = await channel.resumeTo(target.id);
|
|
358
|
+
if (result.ok) {
|
|
359
359
|
channel.notify(t('resume-resumed'));
|
|
360
360
|
onClose();
|
|
361
361
|
}
|
|
362
362
|
else {
|
|
363
|
-
|
|
363
|
+
if (result.reason === 'cancelled')
|
|
364
|
+
return;
|
|
365
|
+
const text = result.reason === 'working'
|
|
366
|
+
? t('resume-while-working')
|
|
367
|
+
: result.reason === 'unavailable'
|
|
368
|
+
? t('resume-unavailable')
|
|
369
|
+
: t('session-resume-failed', { err: result.error });
|
|
370
|
+
setNotice({ text, tone: 'error' });
|
|
364
371
|
}
|
|
365
372
|
}
|
|
366
373
|
catch (error) {
|
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
* flat list of rows. Two reasons it is shaped that way:
|
|
7
7
|
*
|
|
8
8
|
* - Filtering is where this feature's bugs were. Keeping it pure means the
|
|
9
|
-
* truth table — a sub-agent run is hidden,
|
|
10
|
-
* artifact is hidden but counted — is checkable without rendering
|
|
9
|
+
* truth table — a sub-agent run is hidden, an unrelated rewind fork is not,
|
|
10
|
+
* a boot artifact is hidden but counted — is checkable without rendering
|
|
11
|
+
* anything.
|
|
11
12
|
* - Rows are flattened rather than nested. A windowed list of variable-height
|
|
12
13
|
* groups has to guess how much room each group needs; a flat list of
|
|
13
14
|
* single-line rows is windowed by arithmetic, and the group headers simply
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/sessions/view.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"view.d.ts","sourceRoot":"","sources":["../../../src/sessions/view.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AAEtE,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,wEAAwE;IACxE,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;IAC7B,8DAA8D;IAC9D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;IAC5B,qEAAqE;IACrE,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAChC;AAED,oEAAoE;AACpE,eAAO,MAAM,eAAe,EAAE,cAK7B,CAAA;AAED,sCAAsC;AACtC,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE1F,uDAAuD;AACvD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,CAAA;IACpC,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CACrC;AAgBD;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GACtH,WAAW,CAqHb;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAK9F;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAKhG;AAED,+DAA+D;AAC/D,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAGhG;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAEjD;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,MAAM,CAoBR;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAU1F"}
|
|
@@ -32,7 +32,25 @@ function matches(session, needle) {
|
|
|
32
32
|
*/
|
|
33
33
|
export function buildView(sessions, filters, context) {
|
|
34
34
|
const needle = filters.query.trim().toLowerCase();
|
|
35
|
+
// `/model` and `/rewind` continue the live conversation in a fork. Offering
|
|
36
|
+
// that fork's ancestors in `/resume` makes one conversation look like many,
|
|
37
|
+
// and selecting one silently jumps back before the fork. Only the live
|
|
38
|
+
// lineage is excluded: unrelated forks remain recoverable. Treat malformed
|
|
39
|
+
// cycles as a closed chain rather than looping forever over foreign data.
|
|
40
|
+
const byId = new Map(sessions.map(session => [session.id, session]));
|
|
41
|
+
const currentAncestors = new Set();
|
|
42
|
+
const seen = new Set([context.currentId]);
|
|
43
|
+
let cursor = byId.get(context.currentId);
|
|
44
|
+
while (cursor?.kind.kind === 'fork') {
|
|
45
|
+
const parent = cursor.kind.parent;
|
|
46
|
+
if (seen.has(parent))
|
|
47
|
+
break;
|
|
48
|
+
seen.add(parent);
|
|
49
|
+
currentAncestors.add(parent);
|
|
50
|
+
cursor = byId.get(parent);
|
|
51
|
+
}
|
|
35
52
|
const inScope = (session) => session.id !== context.currentId &&
|
|
53
|
+
!currentAncestors.has(session.id) &&
|
|
36
54
|
(filters.allProjects || context.sameProject(context.cwd, session.cwd));
|
|
37
55
|
// Empty sessions never reach a view, but they are counted — and the count
|
|
38
56
|
// feeds a DESTRUCTIVE action, so it is scoped exactly as the list is.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { name, TuiSettingsSectionsRuntime } from './dsh-adapter/settings-sections.js';
|
|
2
|
+
export type { TuiSettingsFieldKind, TuiSettingsFieldOption, TuiSettingsFieldWrite, TuiSettingsField, TuiSettingsSection, } from './dsh-adapter/settings-sections.js';
|
|
2
3
|
export { default } from './dsh-adapter/settings-sections.js';
|
|
3
4
|
//# sourceMappingURL=settings-sections.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../src/settings-sections.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../src/settings-sections.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AACrF,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// Re-export shim: the Cordis-backed implementation lives behind the adapter
|
|
2
2
|
// boundary so UI consumers never import official @deepseek-ai/* packages.
|
|
3
|
-
export
|
|
3
|
+
export { name, TuiSettingsSectionsRuntime } from './dsh-adapter/settings-sections.js';
|
|
4
4
|
export { default } from './dsh-adapter/settings-sections.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execFileNoThrow.d.ts","sourceRoot":"","sources":["../../../src/utils/execFileNoThrow.ts"],"names":[],"mappings":"AAEA,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"execFileNoThrow.d.ts","sourceRoot":"","sources":["../../../src/utils/execFileNoThrow.ts"],"names":[],"mappings":"AAEA,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,OAAO,CAAC,qBAAqB,CAAC,CAiChC"}
|
|
@@ -20,6 +20,9 @@ export function execFileNoThrow(file, args, options) {
|
|
|
20
20
|
child.stderr.on('data', (chunk) => {
|
|
21
21
|
stderrChunks.push(chunk);
|
|
22
22
|
});
|
|
23
|
+
// A child may exit before consuming the supplied input. The resulting
|
|
24
|
+
// EPIPE/EOF belongs to that child outcome and must not crash the caller.
|
|
25
|
+
child.stdin.on('error', () => { });
|
|
23
26
|
child.on('error', () => {
|
|
24
27
|
resolve({
|
|
25
28
|
code: 1,
|