@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
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
* The map is keyed by the cordis ROOT so the row and the channel (two
|
|
27
27
|
* different contexts of one runtime) share one view.
|
|
28
28
|
*/
|
|
29
|
+
import { compositionRoot } from './host-access.js';
|
|
29
30
|
const ownerMaps = new WeakMap();
|
|
30
31
|
function rootKeyOf(ctx) {
|
|
31
|
-
|
|
32
|
-
return typeof root === 'object' && root !== null ? root : undefined;
|
|
32
|
+
return compositionRoot(ctx);
|
|
33
33
|
}
|
|
34
34
|
/** The registrant's display name for diagnostics only: the passed context's
|
|
35
35
|
* fiber name (nearest named ancestor), 'root' for host-side or degraded
|
|
@@ -9,6 +9,12 @@ export interface TuiCommandTreeProvider {
|
|
|
9
9
|
/** Children for the full canonical path, including `root` at index zero. */
|
|
10
10
|
children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
|
|
11
11
|
}
|
|
12
|
+
/** Host-only completion access. Plugins see only their own provider through
|
|
13
|
+
* the traceable service; the channel uses this facade to merge all providers. */
|
|
14
|
+
export interface TuiCommandTreeHost {
|
|
15
|
+
children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
|
|
16
|
+
descriptions(root: string): LocalizedDescriptions | undefined;
|
|
17
|
+
}
|
|
12
18
|
declare module '@deepseek-ai/cordis' {
|
|
13
19
|
interface Context {
|
|
14
20
|
tuiCommandTrees: TuiCommandTreeRuntime;
|
|
@@ -17,11 +23,11 @@ declare module '@deepseek-ai/cordis' {
|
|
|
17
23
|
export declare const name = "dsh-tui-command-trees";
|
|
18
24
|
/** Small host-only registry; command execution remains owned by dsh-commands. */
|
|
19
25
|
export declare class TuiCommandTreeRuntime extends Service {
|
|
20
|
-
private readonly providers;
|
|
21
26
|
constructor(ctx: Context);
|
|
22
27
|
register(provider: TuiCommandTreeProvider): () => void;
|
|
23
28
|
children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
|
|
24
29
|
descriptions(root: string): LocalizedDescriptions | undefined;
|
|
25
30
|
}
|
|
31
|
+
export declare function getHostCommandTrees(runtime: TuiCommandTreeRuntime | undefined): TuiCommandTreeHost | undefined;
|
|
26
32
|
export default TuiCommandTreeRuntime;
|
|
27
33
|
//# sourceMappingURL=command-trees.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAGlF,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;CAC7E;AAED;iFACiF;AACjF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;IAC5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAA;CAC9D;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,qBAAqB,CAAA;KACvC;CACF;AAED,eAAO,MAAM,IAAI,0BAA0B,CAAA;AAE3C,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,OAAO;gBACpC,GAAG,EAAE,OAAO;IAYxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAoBtD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE;IAM5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;CAK9D;AAyCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAO9G;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -1,42 +1,92 @@
|
|
|
1
1
|
/** Provider-neutral subcommand completion registry for terminal front doors. */
|
|
2
2
|
import { Service } from '@deepseek-ai/cordis';
|
|
3
|
+
import { activationFiber, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
|
|
3
4
|
export const name = 'dsh-tui-command-trees';
|
|
4
5
|
/** Small host-only registry; command execution remains owned by dsh-commands. */
|
|
5
6
|
export class TuiCommandTreeRuntime extends Service {
|
|
6
|
-
providers = new Map();
|
|
7
7
|
constructor(ctx) {
|
|
8
8
|
super(ctx, 'tuiCommandTrees');
|
|
9
|
+
compositionRoot(ctx);
|
|
10
|
+
const runtime = this;
|
|
11
|
+
const state = { providers: new Map(), owners: new Map(), host: undefined };
|
|
12
|
+
state.host = Object.freeze({
|
|
13
|
+
children: path => childrenFor(runtime, path),
|
|
14
|
+
descriptions: root => descriptionsFor(runtime, root),
|
|
15
|
+
});
|
|
16
|
+
commandTreeStates.set(this, state);
|
|
9
17
|
}
|
|
10
18
|
register(provider) {
|
|
19
|
+
const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.register', this);
|
|
20
|
+
const state = commandTreeStateFor(this);
|
|
21
|
+
const owner = activationFiber(caller);
|
|
22
|
+
if (owner === undefined)
|
|
23
|
+
throw new Error('dsh-tui: tuiCommandTrees.register requires a live activation');
|
|
11
24
|
const root = provider.root.trim().toLowerCase();
|
|
12
25
|
if (!/^[a-z][a-z0-9_-]*$/u.test(root))
|
|
13
26
|
throw new TypeError(`invalid TUI command-tree root: ${provider.root}`);
|
|
14
|
-
if (
|
|
27
|
+
if (state.providers.has(root))
|
|
15
28
|
throw new Error(`TUI command-tree root "${root}" is already registered`);
|
|
16
29
|
const normalized = { ...provider, root };
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
30
|
+
state.providers.set(root, normalized);
|
|
31
|
+
state.owners.set(root, owner);
|
|
32
|
+
const dispose = () => {
|
|
33
|
+
if (state.providers.get(root) !== normalized)
|
|
34
|
+
return;
|
|
35
|
+
state.providers.delete(root);
|
|
36
|
+
state.owners.delete(root);
|
|
21
37
|
};
|
|
38
|
+
bindCallerEffect(caller, dispose);
|
|
39
|
+
return dispose;
|
|
22
40
|
}
|
|
23
41
|
children(canonicalPath) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const provider = this.providers.get(root);
|
|
28
|
-
if (provider === undefined)
|
|
29
|
-
return [];
|
|
30
|
-
try {
|
|
31
|
-
return provider.children(canonicalPath);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
// Completion is optional UI metadata and must never block execution.
|
|
35
|
-
return [];
|
|
36
|
-
}
|
|
42
|
+
const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.children', this);
|
|
43
|
+
const owner = activationFiber(caller);
|
|
44
|
+
return childrenFor(this, canonicalPath, owner);
|
|
37
45
|
}
|
|
38
46
|
descriptions(root) {
|
|
39
|
-
|
|
47
|
+
const caller = requirePluginCaller(this.ctx, 'tuiCommandTrees.descriptions', this);
|
|
48
|
+
const owner = activationFiber(caller);
|
|
49
|
+
return descriptionsFor(this, root, owner);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const commandTreeStates = new WeakMap();
|
|
53
|
+
function commandTreeStateFor(runtime) {
|
|
54
|
+
const state = commandTreeStates.get(concreteService(runtime));
|
|
55
|
+
if (state === undefined)
|
|
56
|
+
throw new Error('tuiCommandTrees host state is unavailable');
|
|
57
|
+
return state;
|
|
58
|
+
}
|
|
59
|
+
function childrenFor(runtime, canonicalPath, owner) {
|
|
60
|
+
const state = commandTreeStateFor(runtime);
|
|
61
|
+
const root = canonicalPath[0]?.toLowerCase();
|
|
62
|
+
if (root === undefined || (owner !== undefined && state.owners.get(root) !== owner))
|
|
63
|
+
return [];
|
|
64
|
+
const provider = state.providers.get(root);
|
|
65
|
+
if (provider === undefined)
|
|
66
|
+
return [];
|
|
67
|
+
try {
|
|
68
|
+
return provider.children(canonicalPath);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// Completion is optional UI metadata and must never block execution.
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function descriptionsFor(runtime, root, owner) {
|
|
76
|
+
const state = commandTreeStateFor(runtime);
|
|
77
|
+
const normalized = root.trim().toLowerCase();
|
|
78
|
+
if (owner !== undefined && state.owners.get(normalized) !== owner)
|
|
79
|
+
return undefined;
|
|
80
|
+
return state.providers.get(normalized)?.descriptions;
|
|
81
|
+
}
|
|
82
|
+
export function getHostCommandTrees(runtime) {
|
|
83
|
+
if (runtime === undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
try {
|
|
86
|
+
return commandTreeStateFor(runtime).host;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
40
90
|
}
|
|
41
91
|
}
|
|
42
92
|
export default TuiCommandTreeRuntime;
|
|
@@ -25,4 +25,9 @@ export declare function declaresPermission(identity: VerifiedComponentIdentity,
|
|
|
25
25
|
export declare function declaresCommand(identity: VerifiedComponentIdentity, commandId: string): boolean;
|
|
26
26
|
export declare function declaresObserverScope(identity: VerifiedComponentIdentity, actualScope: string): boolean;
|
|
27
27
|
export declare function requiresDecisionEvents(identity: VerifiedComponentIdentity): boolean;
|
|
28
|
+
/** Whether admission negotiated the protocol that backs a mediated runtime
|
|
29
|
+
* capability. Permissions alone are not a capability grant: a plugin must
|
|
30
|
+
* explicitly require the corresponding contract before the host can expose
|
|
31
|
+
* its calls. */
|
|
32
|
+
export declare function requiresContract(identity: VerifiedComponentIdentity, apiVersion: string, kind: string): boolean;
|
|
28
33
|
//# sourceMappingURL=component-identity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component-identity.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/component-identity.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"component-identity.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/component-identity.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAI1E,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,GAAG,4BAA4B,CAAA;AAEhG,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,0BAA0B;gBAAhC,IAAI,EAAE,0BAA0B,EAAE,OAAO,EAAE,MAAM;CAIvE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;CACvC;AAED;;oDAEoD;AACpD,eAAO,MAAM,wBAAwB,MAAM,CAAA;AAqB3C,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,cAAc,EACxB,UAAU,EAAE,iBAAiB,EAC7B,YAAY,GAAE,MAAqB,GAClC,yBAAyB,CAyB3B;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAM3F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CASpF;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAQT;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE/F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,yBAAyB,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAUvG;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,yBAAyB,GAAG,OAAO,CAEnF;AAED;;;gBAGgB;AAChB,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,yBAAyB,EACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAGT"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** Verified Component identity bound to one Cordis activation owner. */
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { normalizePermissionScope, scopeCovers } from '../plugin-spec/permission-scope.js';
|
|
4
|
+
import { activationFiber, bindCallerEffect } from './host-access.js';
|
|
4
5
|
export class ComponentIdentityError extends Error {
|
|
5
6
|
code;
|
|
6
7
|
constructor(code, message) {
|
|
@@ -22,14 +23,9 @@ function validateActivationId(value) {
|
|
|
22
23
|
}
|
|
23
24
|
const identities = new WeakMap();
|
|
24
25
|
function ownerKey(context) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
return fiber;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
// A real plugin context always has a fiber; reject degraded callers below.
|
|
32
|
-
}
|
|
26
|
+
const fiber = activationFiber(context);
|
|
27
|
+
if (fiber !== undefined)
|
|
28
|
+
return fiber;
|
|
33
29
|
throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED', 'a Component activation requires an owning Cordis fiber');
|
|
34
30
|
}
|
|
35
31
|
export function bindComponentIdentity(context, manifest, projection, activationId = randomUUID()) {
|
|
@@ -50,12 +46,9 @@ export function bindComponentIdentity(context, manifest, projection, activationI
|
|
|
50
46
|
if (identities.get(key) === identity)
|
|
51
47
|
identities.delete(key);
|
|
52
48
|
};
|
|
53
|
-
|
|
54
|
-
context.effect(() => release);
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
49
|
+
if (!bindCallerEffect(context, release)) {
|
|
57
50
|
identities.delete(key);
|
|
58
|
-
throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED',
|
|
51
|
+
throw new ComponentIdentityError('COMPONENT_NOT_ADMITTED', 'cannot bind Component identity to an inactive activation');
|
|
59
52
|
}
|
|
60
53
|
return identity;
|
|
61
54
|
}
|
|
@@ -104,5 +97,12 @@ export function declaresObserverScope(identity, actualScope) {
|
|
|
104
97
|
});
|
|
105
98
|
}
|
|
106
99
|
export function requiresDecisionEvents(identity) {
|
|
107
|
-
return identity
|
|
100
|
+
return requiresContract(identity, 'tui.dsh/v1alpha1', 'DecisionEvents');
|
|
101
|
+
}
|
|
102
|
+
/** Whether admission negotiated the protocol that backs a mediated runtime
|
|
103
|
+
* capability. Permissions alone are not a capability grant: a plugin must
|
|
104
|
+
* explicitly require the corresponding contract before the host can expose
|
|
105
|
+
* its calls. */
|
|
106
|
+
export function requiresContract(identity, apiVersion, kind) {
|
|
107
|
+
return identity.manifest.requires.contracts.some(requirement => requirement.apiVersion === apiVersion && requirement.kind === kind);
|
|
108
108
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decision-guard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/decision-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EACL,qBAAqB,EAGrB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"decision-guard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/decision-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EACL,qBAAqB,EAGrB,KAAK,UAAU,EAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,yBAAyB,CAAA;AAShC;;qDAEqD;AACrD,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKtE,CAAA;AAMF,OAAO,EAAE,qBAAqB,EAAE,CAAA;AAEhC,2EAA2E;AAC3E,MAAM,MAAM,eAAe,GAAG,UAAU,CAAA;AAExC,wDAAwD;AACxD,eAAO,MAAM,oBAAoB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAA4B,CAAA;AAEjF,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,UAA2B,CAAA;AAgB/E,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAGD;;;cAGc;AACd,MAAM,WAAW,2BAA2B;IAC1C;kFAC8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;sEACkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAA;IAC5C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAA;CACjE;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAA;IAClB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAA;CAC9D;AAoBD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,CAEjE;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,GACpB,SAAS,yBAAyB,EAAE,CA6BtC;AAsCD,2DAA2D;AAC3D,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,yBAAyB,EACnC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,EACvD,OAAO,GAAE,2BAAgC,EACzC,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,MAAM,OAAO,CA8Ff;AAkBD,kEAAkE;AAClE,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAI9E;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,QAAQ,GAAG,uBAAuB,GAAG,SAAS,CAEjG;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CA+D3E"}
|
|
@@ -30,15 +30,16 @@ import { EXTENSION_GRANTS_FILE, parseGrantStore, readGrantStore, } from './grant
|
|
|
30
30
|
import { componentIdentityOf, requiresDecisionEvents, } from './component-identity.js';
|
|
31
31
|
import { INTERCEPT_EVENT_SCOPE_BY_PERMISSION, normalizePermissionScope, permissionScopeCovers, } from '../plugin-spec/permission-scope.js';
|
|
32
32
|
import { TUI_DECISION_EVENT_NAMES } from '../plugin-spec/tui-extension.js';
|
|
33
|
+
import { bindCallerEffect, compositionRoot } from './host-access.js';
|
|
33
34
|
/** The intercept permission each decision event requires (D-7 naming:
|
|
34
35
|
* `domain.resource.intercept`). Observe-class events (tui/rewind-done,
|
|
35
36
|
* tui/session-switched) are deliberately absent. */
|
|
36
|
-
export const DECISION_EVENT_PERMISSIONS = {
|
|
37
|
+
export const DECISION_EVENT_PERMISSIONS = Object.freeze({
|
|
37
38
|
'tui/input': 'session.input.intercept',
|
|
38
39
|
'tui/rewind-prompt': 'session.rewind.intercept',
|
|
39
40
|
'tui/session-switch': 'session.switch.intercept',
|
|
40
41
|
'tui/compact': 'session.compact.intercept',
|
|
41
|
-
};
|
|
42
|
+
});
|
|
42
43
|
// ── Compatibility aliases (pre-GrantStore names) ────────────────────────────
|
|
43
44
|
// The grant-file format and these entry points predate the unified store;
|
|
44
45
|
// keep them working — verify batteries and any embedder code import them
|
|
@@ -65,10 +66,7 @@ const guardedRoots = new WeakSet();
|
|
|
65
66
|
const handlerMetadata = new WeakMap();
|
|
66
67
|
const registries = new WeakMap();
|
|
67
68
|
function rootKey(ctx) {
|
|
68
|
-
|
|
69
|
-
if (typeof root === 'object' && root !== null)
|
|
70
|
-
return root;
|
|
71
|
-
return ctx;
|
|
69
|
+
return compositionRoot(ctx);
|
|
72
70
|
}
|
|
73
71
|
function registryFor(ctx, grants) {
|
|
74
72
|
const key = rootKey(ctx);
|
|
@@ -244,11 +242,10 @@ export function registerDecisionHandler(pluginCtx, identity, event, listener, op
|
|
|
244
242
|
}
|
|
245
243
|
return true;
|
|
246
244
|
};
|
|
247
|
-
// Both deactivation and grant-file revocation are release boundaries.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
catch { /* degraded test context */ }
|
|
245
|
+
// Both deactivation and grant-file revocation are release boundaries. Bind
|
|
246
|
+
// through the host-captured Fiber effect so an explicit Context shadow
|
|
247
|
+
// cannot replace the cleanup function.
|
|
248
|
+
bindCallerEffect(pluginCtx, release);
|
|
252
249
|
if (permission !== undefined) {
|
|
253
250
|
const stop = registry.grants.onChange?.(() => {
|
|
254
251
|
const principal = { componentId: identity.componentId, activationId: identity.activationId };
|
|
@@ -257,10 +254,7 @@ export function registerDecisionHandler(pluginCtx, identity, event, listener, op
|
|
|
257
254
|
});
|
|
258
255
|
stopGrantWatch = stop;
|
|
259
256
|
if (stop !== undefined) {
|
|
260
|
-
|
|
261
|
-
pluginCtx.effect(() => stop);
|
|
262
|
-
}
|
|
263
|
-
catch { /* degraded test context */ }
|
|
257
|
+
bindCallerEffect(pluginCtx, stop);
|
|
264
258
|
}
|
|
265
259
|
}
|
|
266
260
|
return release;
|
|
@@ -295,7 +289,7 @@ export function installDecisionGuard(ctx, grants) {
|
|
|
295
289
|
// `root` or `on` entirely — the gate is best-effort there, matching the
|
|
296
290
|
// channel's soft-degradation posture: no dedup bookkeeping without a root
|
|
297
291
|
// object, no hook without an `on`.
|
|
298
|
-
const root = ctx
|
|
292
|
+
const root = compositionRoot(ctx);
|
|
299
293
|
// Keep the live grant source even when another row installed the Cordis
|
|
300
294
|
// hook first. The file-backed GrantStore evaluates each operation again.
|
|
301
295
|
registryFor(ctx, grants);
|
|
@@ -89,7 +89,7 @@ export declare class TuiDialogStore {
|
|
|
89
89
|
private readonly queue;
|
|
90
90
|
private active;
|
|
91
91
|
/** Park a request. The snapshot argument must already be sanitized. */
|
|
92
|
-
ask(snapshot: WithoutKey<TuiDialogSnapshot>, signal?: AbortSignal, timeoutMs?: number, owner?: Context): Promise<TuiDialogAnswer>;
|
|
92
|
+
ask(snapshot: WithoutKey<TuiDialogSnapshot>, signal?: AbortSignal, timeoutMs?: number, owner?: Context, bindOwnerEffect?: (disposer: () => unknown, onRegistered: (cleanup: () => unknown) => void) => boolean): Promise<TuiDialogAnswer>;
|
|
93
93
|
/** The dialog the UI should render right now, if any. */
|
|
94
94
|
getSnapshot(): TuiDialogSnapshot | null;
|
|
95
95
|
/**
|
|
@@ -124,8 +124,6 @@ declare module '@deepseek-ai/cordis' {
|
|
|
124
124
|
* down; callers get a logger warning instead.
|
|
125
125
|
*/
|
|
126
126
|
export declare class TuiDialogRuntime extends Service {
|
|
127
|
-
/** The queue the chat screen renders. Exposed for the host, not plugins. */
|
|
128
|
-
readonly store: TuiDialogStore;
|
|
129
127
|
constructor(ctx: Context);
|
|
130
128
|
/** Cordis traceable services normally provide the caller through `this.ctx`;
|
|
131
129
|
* the explicit overloads below make ownership unambiguous for embedders and
|
|
@@ -142,5 +140,6 @@ export declare class TuiDialogRuntime extends Service {
|
|
|
142
140
|
input(request: TuiDialogInputRequest): Promise<string | undefined>;
|
|
143
141
|
input(owner: Context, request: TuiDialogInputRequest): Promise<string | undefined>;
|
|
144
142
|
}
|
|
143
|
+
export declare function getHostDialogStore(runtime: TuiDialogRuntime | undefined): TuiDialogStore | undefined;
|
|
145
144
|
export default TuiDialogRuntime;
|
|
146
145
|
//# sourceMappingURL=dialogs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/dialogs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"dialogs.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/dialogs.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { Context, Service } from '@deepseek-ai/cordis';
|
|
22
22
|
import { cleanScalarText } from './sanitize.js';
|
|
23
|
+
import { activationContext, bindCallerEffect, compositionRoot, concreteService, requirePluginCaller } from './host-access.js';
|
|
23
24
|
/** Render-path strings are untrusted: sanitization (control-char stripping,
|
|
24
25
|
* cell-width caps, scalar-only coercion) lives in ./sanitize.js — the one
|
|
25
26
|
* implementation of the Track A contract. `clean` drops non-scalars to ''
|
|
@@ -45,7 +46,7 @@ export class TuiDialogStore {
|
|
|
45
46
|
queue = [];
|
|
46
47
|
active = null;
|
|
47
48
|
/** Park a request. The snapshot argument must already be sanitized. */
|
|
48
|
-
ask(snapshot, signal, timeoutMs, owner) {
|
|
49
|
+
ask(snapshot, signal, timeoutMs, owner, bindOwnerEffect) {
|
|
49
50
|
if (signal?.aborted)
|
|
50
51
|
return Promise.resolve(undefined);
|
|
51
52
|
return new Promise((resolve) => {
|
|
@@ -98,12 +99,10 @@ export class TuiDialogStore {
|
|
|
98
99
|
pending.timer = setTimeout(pending.onAbort, timeoutMs);
|
|
99
100
|
}
|
|
100
101
|
if (owner !== undefined) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
catch {
|
|
106
|
-
// An inactive activation must never leave an orphan in the queue.
|
|
102
|
+
const bound = bindOwnerEffect?.(pending.onAbort, cleanup => { pending.ownerCleanup = cleanup; }) ?? false;
|
|
103
|
+
if (!bound) {
|
|
104
|
+
// An inactive or untrusted activation must never leave an orphan in
|
|
105
|
+
// the queue. The binder also rolls back partial owner state.
|
|
107
106
|
pending.onAbort();
|
|
108
107
|
return;
|
|
109
108
|
}
|
|
@@ -179,17 +178,32 @@ export class TuiDialogStore {
|
|
|
179
178
|
* down; callers get a logger warning instead.
|
|
180
179
|
*/
|
|
181
180
|
export class TuiDialogRuntime extends Service {
|
|
182
|
-
/** The queue the chat screen renders. Exposed for the host, not plugins. */
|
|
183
|
-
store = new TuiDialogStore();
|
|
184
181
|
constructor(ctx) {
|
|
185
182
|
super(ctx, 'tuiDialogs');
|
|
186
|
-
ctx
|
|
183
|
+
compositionRoot(ctx);
|
|
184
|
+
// Keep queue state off the service object. Cordis invokes public methods
|
|
185
|
+
// through a caller-bound proxy, so JS `#private` fields are unsuitable
|
|
186
|
+
// here; the module-local WeakMap preserves both encapsulation and proxy
|
|
187
|
+
// compatibility.
|
|
188
|
+
const store = new TuiDialogStore();
|
|
189
|
+
hostDialogStores.set(this, store);
|
|
190
|
+
ctx.effect(() => () => store.settleAll());
|
|
187
191
|
}
|
|
188
192
|
/** Cordis traceable services normally provide the caller through `this.ctx`;
|
|
189
193
|
* the explicit overloads below make ownership unambiguous for embedders and
|
|
190
194
|
* tests that retain the service instance directly. */
|
|
191
195
|
callContext(value) {
|
|
192
|
-
|
|
196
|
+
const caller = requirePluginCaller(this.ctx, 'tuiDialogs', this);
|
|
197
|
+
if (!Context.is(value))
|
|
198
|
+
return caller;
|
|
199
|
+
// An explicit owner is accepted only when it is the activation that made
|
|
200
|
+
// the service call. Otherwise a plugin could pass the root (or another
|
|
201
|
+
// plugin's context) and leave an orphaned dialog alive after deactivation.
|
|
202
|
+
const canonical = activationContext(value);
|
|
203
|
+
if (canonical === undefined || activationContext(caller) !== canonical) {
|
|
204
|
+
throw new Error('tuiDialogs owner context must be the calling activation');
|
|
205
|
+
}
|
|
206
|
+
return canonical;
|
|
193
207
|
}
|
|
194
208
|
timeoutOf(value) {
|
|
195
209
|
return typeof value === 'number' && Number.isFinite(value) && value > 0
|
|
@@ -197,66 +211,106 @@ export class TuiDialogRuntime extends Service {
|
|
|
197
211
|
: DIALOG_DEFAULT_TIMEOUT_MS;
|
|
198
212
|
}
|
|
199
213
|
select(ownerOrRequest, explicitRequest) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
214
|
+
try {
|
|
215
|
+
const owner = this.callContext(ownerOrRequest);
|
|
216
|
+
const request = (explicitRequest ?? ownerOrRequest);
|
|
217
|
+
const title = clean(request?.title, TITLE_CELLS);
|
|
218
|
+
const rawOptions = Array.isArray(request?.options) ? request.options : [];
|
|
219
|
+
const options = [];
|
|
220
|
+
for (const raw of rawOptions.slice(0, MAX_OPTIONS)) {
|
|
221
|
+
// The id is NOT render-path data — it is the opaque token the promise
|
|
222
|
+
// resolves with, matched by the plugin against its own options. Sanitizing
|
|
223
|
+
// it (whitespace collapse, cell truncation) would hand back a DIFFERENT
|
|
224
|
+
// string the plugin cannot look up; validate and keep it verbatim.
|
|
225
|
+
const id = raw?.id;
|
|
226
|
+
const label = clean(raw?.label, LABEL_CELLS);
|
|
227
|
+
if (typeof id !== 'string' || id === '' || !label)
|
|
228
|
+
continue;
|
|
229
|
+
// '' (absent, blank, or a dropped non-scalar) means no description row.
|
|
230
|
+
const description = clean(raw?.description, MESSAGE_CELLS);
|
|
231
|
+
options.push({ id, label, ...(description === '' ? {} : { description }) });
|
|
232
|
+
}
|
|
233
|
+
if (!title || options.length === 0) {
|
|
234
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.select called without a title or options; cancelled');
|
|
235
|
+
return Promise.resolve(undefined);
|
|
236
|
+
}
|
|
237
|
+
return dialogStoreFor(this)
|
|
238
|
+
.ask({ kind: 'select', title, options }, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
|
|
239
|
+
.then(value => (typeof value === 'string' ? value : undefined));
|
|
217
240
|
}
|
|
218
|
-
|
|
219
|
-
this.ctx.logger.warn('dsh-tui: tuiDialogs.select
|
|
241
|
+
catch {
|
|
242
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.select received malformed data; cancelled');
|
|
220
243
|
return Promise.resolve(undefined);
|
|
221
244
|
}
|
|
222
|
-
return this.store
|
|
223
|
-
.ask({ kind: 'select', title, options }, request.signal, this.timeoutOf(request.timeoutMs), owner)
|
|
224
|
-
.then(value => (typeof value === 'string' ? value : undefined));
|
|
225
245
|
}
|
|
226
246
|
confirm(ownerOrRequest, explicitRequest) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
247
|
+
try {
|
|
248
|
+
const owner = this.callContext(ownerOrRequest);
|
|
249
|
+
const request = (explicitRequest ?? ownerOrRequest);
|
|
250
|
+
const title = clean(request?.title, TITLE_CELLS);
|
|
251
|
+
if (!title) {
|
|
252
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.confirm called without a title; cancelled');
|
|
253
|
+
return Promise.resolve(false);
|
|
254
|
+
}
|
|
255
|
+
const message = clean(request?.message, MESSAGE_CELLS);
|
|
256
|
+
const confirmLabel = clean(request?.confirmLabel, LABEL_CELLS);
|
|
257
|
+
const cancelLabel = clean(request?.cancelLabel, LABEL_CELLS);
|
|
258
|
+
return dialogStoreFor(this)
|
|
259
|
+
.ask({
|
|
260
|
+
kind: 'confirm',
|
|
261
|
+
title,
|
|
262
|
+
...(message === '' ? {} : { message }),
|
|
263
|
+
confirmLabel,
|
|
264
|
+
cancelLabel,
|
|
265
|
+
}, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
|
|
266
|
+
.then(value => value === true);
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.confirm received malformed data; cancelled');
|
|
232
270
|
return Promise.resolve(false);
|
|
233
271
|
}
|
|
234
|
-
const message = clean(request?.message, MESSAGE_CELLS);
|
|
235
|
-
const confirmLabel = clean(request?.confirmLabel, LABEL_CELLS);
|
|
236
|
-
const cancelLabel = clean(request?.cancelLabel, LABEL_CELLS);
|
|
237
|
-
return this.store
|
|
238
|
-
.ask({
|
|
239
|
-
kind: 'confirm',
|
|
240
|
-
title,
|
|
241
|
-
...(message === '' ? {} : { message }),
|
|
242
|
-
confirmLabel,
|
|
243
|
-
cancelLabel,
|
|
244
|
-
}, request.signal, this.timeoutOf(request.timeoutMs), owner)
|
|
245
|
-
.then(value => value === true);
|
|
246
272
|
}
|
|
247
273
|
input(ownerOrRequest, explicitRequest) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
274
|
+
try {
|
|
275
|
+
const owner = this.callContext(ownerOrRequest);
|
|
276
|
+
const request = (explicitRequest ?? ownerOrRequest);
|
|
277
|
+
const title = clean(request?.title, TITLE_CELLS);
|
|
278
|
+
if (!title) {
|
|
279
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.input called without a title; cancelled');
|
|
280
|
+
return Promise.resolve(undefined);
|
|
281
|
+
}
|
|
282
|
+
const placeholder = clean(request?.placeholder, LABEL_CELLS);
|
|
283
|
+
const initial = clean(request?.initial, INPUT_CELLS);
|
|
284
|
+
return dialogStoreFor(this)
|
|
285
|
+
.ask({ kind: 'input', title, ...(placeholder === '' ? {} : { placeholder }), initial }, request.signal, this.timeoutOf(request.timeoutMs), owner, (disposer, onRegistered) => bindCallerEffect(owner, disposer, onRegistered))
|
|
286
|
+
.then(value => (typeof value === 'string' ? value : undefined));
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
this.ctx.logger.warn('dsh-tui: tuiDialogs.input received malformed data; cancelled');
|
|
253
290
|
return Promise.resolve(undefined);
|
|
254
291
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Host-only queue accessor. This module is intentionally not a package
|
|
296
|
+
* export; plugins receive only the traceable `tuiDialogs` capability, whose
|
|
297
|
+
* public surface is select/confirm/input.
|
|
298
|
+
*/
|
|
299
|
+
const hostDialogStores = new WeakMap();
|
|
300
|
+
function dialogStoreFor(runtime) {
|
|
301
|
+
const store = hostDialogStores.get(concreteService(runtime));
|
|
302
|
+
if (store === undefined)
|
|
303
|
+
throw new Error('tuiDialogs host store is unavailable');
|
|
304
|
+
return store;
|
|
305
|
+
}
|
|
306
|
+
export function getHostDialogStore(runtime) {
|
|
307
|
+
if (runtime === undefined)
|
|
308
|
+
return undefined;
|
|
309
|
+
try {
|
|
310
|
+
return hostDialogStores.get(concreteService(runtime));
|
|
311
|
+
}
|
|
312
|
+
catch {
|
|
313
|
+
return undefined;
|
|
260
314
|
}
|
|
261
315
|
}
|
|
262
316
|
export default TuiDialogRuntime;
|
|
@@ -66,14 +66,6 @@ declare module '@deepseek-ai/cordis' {
|
|
|
66
66
|
}
|
|
67
67
|
/** `ctx.tuiEffectLedger` — append-only effect journal (C-060). */
|
|
68
68
|
export declare class TuiEffectLedgerRuntime extends Service {
|
|
69
|
-
private readonly file;
|
|
70
|
-
private readonly optionsGenerationId;
|
|
71
|
-
private generationId;
|
|
72
|
-
private readonly ledgerSchema;
|
|
73
|
-
private readonly activations;
|
|
74
|
-
private nextActivation;
|
|
75
|
-
private sequence;
|
|
76
|
-
private schemaWarned;
|
|
77
69
|
constructor(ctx: Context, options?: {
|
|
78
70
|
file?: string;
|
|
79
71
|
generationId?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effect-ledger.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/effect-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"effect-ledger.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/effect-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAOtD,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,QAAwC,CAAA;AAEvE,4DAA4D;AAC5D,eAAO,MAAM,qBAAqB,oHASxB,CAAA;AAEV,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,gBAAgB,CAAA;AAC1F,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3D,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,eAAe,CAAA;IAC1B,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;IACtC,MAAM,EAAE,YAAY,CAAA;IACpB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,yDAAyD;IACzD,QAAQ,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC/D,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,sBAAsB,CAAA;KACxC;CACF;AAWD,kEAAkE;AAClE,qBAAa,sBAAuB,SAAQ,OAAO;gBAE/C,GAAG,EAAE,OAAO,EACZ,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAO;IA0BhG;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI;IA6DpD;;yCAEqC;IACrC,OAAO,CAAC,UAAU;IAOlB,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,YAAY;CAarB;AA6CD,eAAe,sBAAsB,CAAA"}
|