@deepseek-harness-tui/dsh-tui 0.8.1 → 0.8.3
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 +30 -15
- package/bin/dsh-tui.js +43 -7
- 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 +97 -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 +22 -6
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +14 -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
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/** dsh-TUI private, lifecycle-owned manifest contribution definitions. */
|
|
2
|
+
|
|
3
|
+
export const API_VERSION = 'tui.dsh/v1alpha1'
|
|
4
|
+
|
|
5
|
+
export const SETTINGS_SECTION = Object.freeze({
|
|
6
|
+
apiVersion: API_VERSION,
|
|
7
|
+
kind: 'SettingsSection',
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
export const SCENE = Object.freeze({
|
|
11
|
+
apiVersion: API_VERSION,
|
|
12
|
+
kind: 'Scene',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export const settingsSectionExtensionDefinition = Object.freeze({
|
|
16
|
+
...SETTINGS_SECTION,
|
|
17
|
+
validateMetadata(metadata) {
|
|
18
|
+
contributionName(metadata?.name, 'SettingsSection metadata.name')
|
|
19
|
+
},
|
|
20
|
+
validateSpec: validateSettingsSectionSpec,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export function validateSettingsSectionSpec(value) {
|
|
24
|
+
const spec = exactRecord(value, ['namespace', 'title', 'titles', 'fields'], 'SettingsSection content')
|
|
25
|
+
contributionName(spec.namespace, 'SettingsSection content.namespace')
|
|
26
|
+
nonEmpty(spec.title, 'SettingsSection content.title')
|
|
27
|
+
localized(spec.titles, 'SettingsSection content.titles')
|
|
28
|
+
if (!Array.isArray(spec.fields)) throw new TypeError('SettingsSection content.fields must be an array')
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
namespace: spec.namespace,
|
|
31
|
+
title: spec.title,
|
|
32
|
+
...(spec.titles === undefined ? {} : { titles: freezeRecord(spec.titles) }),
|
|
33
|
+
fields: Object.freeze(spec.fields.map((field, index) => validateSettingsField(field, index))),
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const sceneExtensionDefinition = Object.freeze({
|
|
38
|
+
...SCENE,
|
|
39
|
+
validateMetadata(metadata) {
|
|
40
|
+
contributionName(metadata?.name, 'Scene metadata.name')
|
|
41
|
+
},
|
|
42
|
+
validateSpec: validateSceneSpec,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
export function validateSceneSpec(value) {
|
|
46
|
+
const spec = exactRecord(value, ['title', 'titles'], 'Scene content')
|
|
47
|
+
if (spec.title !== undefined) nonEmpty(spec.title, 'Scene content.title')
|
|
48
|
+
localized(spec.titles, 'Scene content.titles')
|
|
49
|
+
return Object.freeze({
|
|
50
|
+
...(spec.title === undefined ? {} : { title: spec.title }),
|
|
51
|
+
...(spec.titles === undefined ? {} : { titles: freezeRecord(spec.titles) }),
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export const contributionExtensionDefinitions = Object.freeze([
|
|
56
|
+
settingsSectionExtensionDefinition,
|
|
57
|
+
sceneExtensionDefinition,
|
|
58
|
+
])
|
|
59
|
+
|
|
60
|
+
export function registerTuiContributionExtensions(catalog) {
|
|
61
|
+
const disposers = contributionExtensionDefinitions.map(definition => catalog.registerExtension(definition))
|
|
62
|
+
return () => { for (const dispose of disposers.reverse()) dispose() }
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function assertSettingsSectionHandler(value) {
|
|
66
|
+
runtimeObject(value, 'SettingsSection handler')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function assertSceneHandler(value) {
|
|
70
|
+
const handler = runtimeObject(value, 'Scene handler')
|
|
71
|
+
if (typeof handler.component !== 'function') throw new TypeError('Scene handler.component must be a function')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function validateSettingsField(value, index) {
|
|
75
|
+
const label = `SettingsSection spec.fields[${index}]`
|
|
76
|
+
const field = exactRecord(value, [
|
|
77
|
+
'path', 'label', 'titles', 'hint', 'hintTitles', 'kind', 'options', 'placeholder', 'secretRef',
|
|
78
|
+
], label)
|
|
79
|
+
if (!Array.isArray(field.path) || field.path.length === 0
|
|
80
|
+
|| field.path.some(segment => typeof segment !== 'string' || segment.length === 0)) {
|
|
81
|
+
throw new TypeError(`${label}.path must be a non-empty string array`)
|
|
82
|
+
}
|
|
83
|
+
nonEmpty(field.label, `${label}.label`)
|
|
84
|
+
localized(field.titles, `${label}.titles`)
|
|
85
|
+
if (field.hint !== undefined) nonEmpty(field.hint, `${label}.hint`)
|
|
86
|
+
localized(field.hintTitles, `${label}.hintTitles`)
|
|
87
|
+
if (!['text', 'number', 'boolean', 'select'].includes(field.kind)) {
|
|
88
|
+
throw new TypeError(`${label}.kind is invalid`)
|
|
89
|
+
}
|
|
90
|
+
if (field.placeholder !== undefined && typeof field.placeholder !== 'string') {
|
|
91
|
+
throw new TypeError(`${label}.placeholder must be a string`)
|
|
92
|
+
}
|
|
93
|
+
if (field.secretRef !== undefined) nonEmpty(field.secretRef, `${label}.secretRef`)
|
|
94
|
+
if (field.options !== undefined) {
|
|
95
|
+
if (!Array.isArray(field.options)) throw new TypeError(`${label}.options must be an array`)
|
|
96
|
+
for (const [optionIndex, valueOption] of field.options.entries()) {
|
|
97
|
+
const option = exactRecord(valueOption, ['value', 'label', 'titles'], `${label}.options[${optionIndex}]`)
|
|
98
|
+
nonEmpty(option.value, `${label}.options[${optionIndex}].value`)
|
|
99
|
+
nonEmpty(option.label, `${label}.options[${optionIndex}].label`)
|
|
100
|
+
localized(option.titles, `${label}.options[${optionIndex}].titles`)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return Object.freeze(structuredClone(field))
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function exactRecord(value, allowed, label) {
|
|
107
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
108
|
+
throw new TypeError(`${label} must be an object`)
|
|
109
|
+
}
|
|
110
|
+
const unknown = Object.keys(value).filter(key => !allowed.includes(key) && !key.startsWith('x-'))
|
|
111
|
+
if (unknown.length > 0) throw new TypeError(`${label} contains unknown field ${JSON.stringify(unknown[0])}`)
|
|
112
|
+
return value
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function runtimeObject(value, label) {
|
|
116
|
+
if ((typeof value !== 'object' && typeof value !== 'function') || value === null || Array.isArray(value)) {
|
|
117
|
+
throw new TypeError(`${label} must be an object`)
|
|
118
|
+
}
|
|
119
|
+
return value
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function contributionName(value, label) {
|
|
123
|
+
if (typeof value !== 'string' || !/^[a-z][a-z0-9_-]*$/u.test(value)) {
|
|
124
|
+
throw new TypeError(`${label} is invalid`)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function nonEmpty(value, label) {
|
|
129
|
+
if (typeof value !== 'string' || value.trim() === '') throw new TypeError(`${label} must be a non-empty string`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function localized(value, label) {
|
|
133
|
+
if (value === undefined) return
|
|
134
|
+
const record = exactRecord(value, Object.keys(value), label)
|
|
135
|
+
for (const [locale, text] of Object.entries(record)) {
|
|
136
|
+
if (locale.trim() === '') throw new TypeError(`${label} contains an empty locale`)
|
|
137
|
+
nonEmpty(text, `${label}.${locale}`)
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function freezeRecord(value) {
|
|
142
|
+
return Object.freeze({ ...value })
|
|
143
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# dsh-TUI Admission Protocol Profile
|
|
2
|
+
|
|
3
|
+
[`registry-0.15.json`](registry-0.15.json) 不是全局协议注册表。它描述本 TUI admission profile 使用的 definition 集合:
|
|
4
|
+
|
|
5
|
+
- `imports` 引用固定 dsh-std revision 已提供的 definitions;
|
|
6
|
+
- `definitions` 只收录 dsh-TUI 私有 definitions。
|
|
7
|
+
|
|
8
|
+
导入条目不复制 dsh-std 的 schema 或 contract 正文。Community v0.15 的 `Command`、`LocalStorage`、`MessageObserver`、Presentation 与 Workspace 定义分别由 `@dsh-std/command`、`@dsh-std/storage`、`@dsh-std/messages`、`@dsh-std/presentation` 与 `@dsh-std/workspace` 注册。
|
|
9
|
+
|
|
10
|
+
本地 definition 的 contract profile 使用 SHA-256 固定。修改 profile 内容必须更新 digest,并按兼容性决定保留坐标或发布新 `apiVersion`。digest 只证明字节一致,不证明发布者身份。
|
|
11
|
+
|
|
12
|
+
`tui.dsh/*` 是 dsh-TUI 私有 namespace。私有 definition 与公共 definition 一样注册到 dsh-std `ProtocolCatalog`;目录收录本身不产生 live support。
|
|
13
|
+
|
|
14
|
+
权限目录仍是 TUI authorization policy 的输入。permission grant 与 protocol support 分开判断,安装 definition 不自动授权操作。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name":"tui.scene","version":"v1alpha1","kind":"extension",
|
|
3
|
+
"coordinates":{"apiVersion":"tui.dsh/v1alpha1","kind":"Scene"},
|
|
4
|
+
"caller":"trusted in-process dsh-TUI scene shell",
|
|
5
|
+
"permissions":[],
|
|
6
|
+
"operations":["open","close","render"],
|
|
7
|
+
"errors":["SCENE_INVALID","SCENE_CONFLICT","RENDERER_INCOMPATIBLE"],
|
|
8
|
+
"concurrency":"one scene may own the full-screen surface at a time",
|
|
9
|
+
"timeout":"scene operations are local; domain calls made by a scene retain their own deadlines",
|
|
10
|
+
"cleanup":"an open scene closes when its owning facet deactivates",
|
|
11
|
+
"privacyClass":"sensitive",
|
|
12
|
+
"securityBoundary":false
|
|
13
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name":"tui.settings-section","version":"v1alpha1","kind":"extension",
|
|
3
|
+
"coordinates":{"apiVersion":"tui.dsh/v1alpha1","kind":"SettingsSection"},
|
|
4
|
+
"caller":"dsh-TUI settings contribution binder",
|
|
5
|
+
"permissions":[],
|
|
6
|
+
"operations":["render"],
|
|
7
|
+
"errors":["SECTION_INVALID","NAMESPACE_CONFLICT","NAMESPACE_UNAVAILABLE"],
|
|
8
|
+
"concurrency":"one active section owns each settings namespace",
|
|
9
|
+
"timeout":"not applicable to declarative rendering; writes use the settings protocol deadline",
|
|
10
|
+
"cleanup":"removing a section removes only UI metadata and preserves settings and credentials",
|
|
11
|
+
"privacyClass":"public",
|
|
12
|
+
"securityBoundary":false
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tui.channel",
|
|
3
|
+
"version": "v1alpha1",
|
|
4
|
+
"coordinates": {
|
|
5
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
6
|
+
"kind": "Channel"
|
|
7
|
+
},
|
|
8
|
+
"kind": "capability",
|
|
9
|
+
"caller": "a negotiated TUI endpoint",
|
|
10
|
+
"permissions": [],
|
|
11
|
+
"operations": [
|
|
12
|
+
{"name": "open", "input": "workspace/session selector", "output": "complete channel snapshot"},
|
|
13
|
+
{"name": "subscribe", "input": "channel id and last observed version", "output": "snapshot progress stream"},
|
|
14
|
+
{"name": "invoke", "input": "channel method and JSON arguments", "output": "method progress, JSON result and optional snapshot"},
|
|
15
|
+
{"name": "close", "input": "channel id", "output": "closed acknowledgement"}
|
|
16
|
+
],
|
|
17
|
+
"wireRevision": 6,
|
|
18
|
+
"features": [
|
|
19
|
+
"commands", "credentials", "diagnostics", "files", "models", "modes",
|
|
20
|
+
"presets", "presentation", "provider-setup", "scenes", "session-history", "session-input",
|
|
21
|
+
"session-lifecycle", "session-state", "settings", "skills", "subagents",
|
|
22
|
+
"trace", "workspaces"
|
|
23
|
+
],
|
|
24
|
+
"errors": ["CHANNEL_NOT_FOUND", "FEATURE_UNAVAILABLE", "INVALID_ARGUMENT", "PERMISSION_DENIED", "REVISION_MISMATCH", "PROVIDER_FAILURE"],
|
|
25
|
+
"concurrency": "state mutations are serialized per channel; independent read operations may run concurrently",
|
|
26
|
+
"timeout": "the caller supplies connection invocation cancellation; subscriptions remain open until cancelled or closed",
|
|
27
|
+
"cleanup": "connection close or facet deactivate releases subscriptions, uploads and channel attachments",
|
|
28
|
+
"privacyClass": "sensitive",
|
|
29
|
+
"securityBoundary": false
|
|
30
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
{"name":"storage.local.write","default":"deny","revocable":true,"scope":"plugin namespace"},
|
|
6
6
|
{"name":"commands.invoke","default":"allow","revocable":true,"scope":"declared command id","rationale":"调用由宿主或用户通过一次 invocation 主动发起,不同于数据访问类权限——插件无法仅凭此权限被动读取任何数据,故默认允许;撤销只关闭该 command ID 的调用入口"},
|
|
7
7
|
{"name":"messages.observe.read","default":"deny","revocable":true,"scope":"message observation scope"},
|
|
8
|
-
{"name":"session.input.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"拦截类订阅(RFC 0005 D-7):能否决/改写用户输入,严格强于观察,故默认拒绝;TUI 实验实现见 tui.dsh
|
|
8
|
+
{"name":"session.input.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"拦截类订阅(RFC 0005 D-7):能否决/改写用户输入,严格强于观察,故默认拒绝;TUI 实验实现见 tui.dsh.decision-events"},
|
|
9
9
|
{"name":"session.rewind.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决会话回退或注入回退模式"},
|
|
10
10
|
{"name":"session.switch.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决会话切换"},
|
|
11
11
|
{"name":"session.compact.intercept","default":"deny","revocable":true,"scope":"decision event subscription","rationale":"同 session.input.intercept——可否决手动压缩"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profileVersion": "tui-admission/0.15",
|
|
3
|
+
"std": {
|
|
4
|
+
"repository": "https://github.com/Yan-Zero/dsh-std",
|
|
5
|
+
"submodule": "vendor/dsh-std",
|
|
6
|
+
"manifestVersion": "0.15"
|
|
7
|
+
},
|
|
8
|
+
"imports": [
|
|
9
|
+
{
|
|
10
|
+
"name": "commands",
|
|
11
|
+
"coordinates": {
|
|
12
|
+
"apiVersion": "commands.dsh/v1alpha1",
|
|
13
|
+
"kind": "Command"
|
|
14
|
+
},
|
|
15
|
+
"package": "@dsh-std/command",
|
|
16
|
+
"kind": "capability",
|
|
17
|
+
"permissions": [
|
|
18
|
+
"commands.invoke"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "storage.local",
|
|
23
|
+
"coordinates": {
|
|
24
|
+
"apiVersion": "storage.dsh/v1alpha1",
|
|
25
|
+
"kind": "LocalStorage"
|
|
26
|
+
},
|
|
27
|
+
"package": "@dsh-std/storage",
|
|
28
|
+
"kind": "capability",
|
|
29
|
+
"permissions": [
|
|
30
|
+
"storage.local.read",
|
|
31
|
+
"storage.local.write"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "messages.observe",
|
|
36
|
+
"coordinates": {
|
|
37
|
+
"apiVersion": "messages.dsh/v1alpha1",
|
|
38
|
+
"kind": "MessageObserver"
|
|
39
|
+
},
|
|
40
|
+
"package": "@dsh-std/messages",
|
|
41
|
+
"kind": "event",
|
|
42
|
+
"permissions": [
|
|
43
|
+
"messages.observe.read"
|
|
44
|
+
],
|
|
45
|
+
"eventEnvelope": "@dsh-std/messages/schema/message-observer-envelope-0.15.json"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "presentation.open-external",
|
|
49
|
+
"coordinates": {
|
|
50
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
51
|
+
"kind": "OpenExternal"
|
|
52
|
+
},
|
|
53
|
+
"package": "@dsh-std/presentation",
|
|
54
|
+
"kind": "capability",
|
|
55
|
+
"permissions": []
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "presentation.user-interaction",
|
|
59
|
+
"coordinates": {
|
|
60
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
61
|
+
"kind": "UserInteraction"
|
|
62
|
+
},
|
|
63
|
+
"package": "@dsh-std/presentation",
|
|
64
|
+
"kind": "capability",
|
|
65
|
+
"permissions": []
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "presentation.external-redirect",
|
|
69
|
+
"coordinates": {
|
|
70
|
+
"apiVersion": "presentation.dsh/v1alpha1",
|
|
71
|
+
"kind": "ExternalRedirect"
|
|
72
|
+
},
|
|
73
|
+
"package": "@dsh-std/presentation",
|
|
74
|
+
"kind": "capability",
|
|
75
|
+
"permissions": []
|
|
76
|
+
}
|
|
77
|
+
],
|
|
78
|
+
"definitions": [
|
|
79
|
+
{
|
|
80
|
+
"name": "tui.decision-events",
|
|
81
|
+
"authority": "dsh-tui",
|
|
82
|
+
"coordinates": {
|
|
83
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
84
|
+
"kind": "DecisionEvents"
|
|
85
|
+
},
|
|
86
|
+
"kind": "capability",
|
|
87
|
+
"profile": "registry/contracts/decision-events-v1alpha1.json",
|
|
88
|
+
"profileHash": "sha256:56440dde1b00c210b22761a0cba139ce0a20207330567777cebe1e48b494ceb0",
|
|
89
|
+
"permissions": [
|
|
90
|
+
"session.input.intercept",
|
|
91
|
+
"session.rewind.intercept",
|
|
92
|
+
"session.switch.intercept",
|
|
93
|
+
"session.compact.intercept"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"name": "tui.channel",
|
|
98
|
+
"authority": "dsh-tui",
|
|
99
|
+
"coordinates": {
|
|
100
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
101
|
+
"kind": "Channel"
|
|
102
|
+
},
|
|
103
|
+
"kind": "capability",
|
|
104
|
+
"profile": "registry/contracts/tui-channel-v1alpha1.json",
|
|
105
|
+
"profileHash": "sha256:2d0668656d999a8cacd363cd3c76207f9392118be8a83e6dd5f81b54ae063fe6",
|
|
106
|
+
"permissions": []
|
|
107
|
+
}
|
|
108
|
+
],
|
|
109
|
+
"extensions": [
|
|
110
|
+
{
|
|
111
|
+
"name": "workspace.provider",
|
|
112
|
+
"authority": "dsh-std",
|
|
113
|
+
"coordinates": {
|
|
114
|
+
"apiVersion": "workspace.dsh/v1alpha1",
|
|
115
|
+
"kind": "WorkspaceProvider"
|
|
116
|
+
},
|
|
117
|
+
"kind": "extension",
|
|
118
|
+
"package": "@dsh-std/workspace",
|
|
119
|
+
"permissions": []
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"name": "tui.settings-section",
|
|
123
|
+
"authority": "dsh-tui",
|
|
124
|
+
"coordinates": {
|
|
125
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
126
|
+
"kind": "SettingsSection"
|
|
127
|
+
},
|
|
128
|
+
"kind": "extension",
|
|
129
|
+
"profile": "registry/contracts/settings-section-v1alpha1.json",
|
|
130
|
+
"profileHash": "sha256:685b0f17fe489f458e9b799811f61c42b858330584e95ecb97e7216b5be100ac",
|
|
131
|
+
"permissions": []
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"name": "tui.scene",
|
|
135
|
+
"authority": "dsh-tui",
|
|
136
|
+
"coordinates": {
|
|
137
|
+
"apiVersion": "tui.dsh/v1alpha1",
|
|
138
|
+
"kind": "Scene"
|
|
139
|
+
},
|
|
140
|
+
"kind": "extension",
|
|
141
|
+
"profile": "registry/contracts/scene-v1alpha1.json",
|
|
142
|
+
"profileHash": "sha256:69ce3ae26d60dea2ed170376db8a1fb5860c94bd192c62681423c1d848ec2b26",
|
|
143
|
+
"permissions": []
|
|
144
|
+
}
|
|
145
|
+
],
|
|
146
|
+
"facetApiVersions": [
|
|
147
|
+
"v1alpha1"
|
|
148
|
+
]
|
|
149
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { name, TuiCommandTreeRuntime } from './dsh-adapter/command-trees.js';
|
|
2
|
+
export type { TuiCommandTreeProvider } from './dsh-adapter/command-trees.js';
|
|
2
3
|
export { default } from './dsh-adapter/command-trees.js';
|
|
3
4
|
//# sourceMappingURL=command-trees.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../src/command-trees.ts"],"names":[],"mappings":"AAEA,
|
|
1
|
+
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../src/command-trees.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,gCAAgC,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, TuiCommandTreeRuntime } from './dsh-adapter/command-trees.js';
|
|
4
4
|
export { default } from './dsh-adapter/command-trees.js';
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { LoadedContext } from '../dsh-adapter/channel.js';
|
|
3
3
|
/**
|
|
4
|
-
* The startup context
|
|
4
|
+
* The startup context panel: a collapsed one-line summary of what a
|
|
5
5
|
* fresh conversation will load for the current agent (system prompt
|
|
6
6
|
* sections, workspace instruction files, dynamic context, skill catalog,
|
|
7
|
-
* tools)
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* tools), expandable to the grouped details with Ctrl+P. The `/context`
|
|
8
|
+
* local command still prints the same details as a transcript report.
|
|
9
|
+
* The panel renders only while the transcript is still empty — the first
|
|
10
|
+
* message's rows take over. Renders nothing for an empty snapshot.
|
|
10
11
|
* @param context - the channel's loaded-context snapshot.
|
|
12
|
+
* @param open - whether the grouped details are shown.
|
|
13
|
+
* @param onToggle - flips `open`; fired by the Ctrl+P keybinding.
|
|
11
14
|
*/
|
|
12
|
-
export declare function LoadedContextPanel({ context }: {
|
|
15
|
+
export declare function LoadedContextPanel({ context, open, onToggle, }: {
|
|
13
16
|
context: LoadedContext;
|
|
17
|
+
open: boolean;
|
|
18
|
+
onToggle: () => void;
|
|
14
19
|
}): React.ReactNode;
|
|
15
20
|
//# sourceMappingURL=LoadedContextPanel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoadedContextPanel.d.ts","sourceRoot":"","sources":["../../../src/components/LoadedContextPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"LoadedContextPanel.d.ts","sourceRoot":"","sources":["../../../src/components/LoadedContextPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,2BAA2B,CAAA;AA+BlF;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,aAAa,CAAA;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,QAAQ,EAAE,MAAM,IAAI,CAAA;CACrB,GAAG,KAAK,CAAC,SAAS,CAoElB"}
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { t } from '../i18n.js';
|
|
3
3
|
import { Box, Text } from '../ui.js';
|
|
4
|
-
import { summarizeLoadedContext } from '../utils/loaded-context.js';
|
|
4
|
+
import { summarizeLoadedContext, truncateContextText } from '../utils/loaded-context.js';
|
|
5
|
+
/** One named entry (section or dynamic context) with its full text. */
|
|
6
|
+
function Entry({ entry }) {
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: entry.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(entry.text) })] }));
|
|
8
|
+
}
|
|
9
|
+
/** A titled group of rows inside the expanded panel. */
|
|
10
|
+
function Group({ title, children }) {
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: "subtle", children: title }), _jsx(Box, { flexDirection: "column", paddingLeft: 2, children: children })] }));
|
|
12
|
+
}
|
|
5
13
|
/**
|
|
6
|
-
* The startup context
|
|
14
|
+
* The startup context panel: a collapsed one-line summary of what a
|
|
7
15
|
* fresh conversation will load for the current agent (system prompt
|
|
8
16
|
* sections, workspace instruction files, dynamic context, skill catalog,
|
|
9
|
-
* tools)
|
|
10
|
-
*
|
|
11
|
-
*
|
|
17
|
+
* tools), expandable to the grouped details with Ctrl+P. The `/context`
|
|
18
|
+
* local command still prints the same details as a transcript report.
|
|
19
|
+
* The panel renders only while the transcript is still empty — the first
|
|
20
|
+
* message's rows take over. Renders nothing for an empty snapshot.
|
|
12
21
|
* @param context - the channel's loaded-context snapshot.
|
|
22
|
+
* @param open - whether the grouped details are shown.
|
|
23
|
+
* @param onToggle - flips `open`; fired by the Ctrl+P keybinding.
|
|
13
24
|
*/
|
|
14
|
-
export function LoadedContextPanel({ context }) {
|
|
25
|
+
export function LoadedContextPanel({ context, open, onToggle, }) {
|
|
15
26
|
const summary = summarizeLoadedContext(context);
|
|
16
27
|
if (summary === '')
|
|
17
28
|
return null;
|
|
18
|
-
return (
|
|
29
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [_jsx(Box, { paddingX: 1, backgroundColor: open ? 'userMessageBackground' : undefined, children: _jsxs(Text, { bold: open, wrap: "truncate", children: [open ? '▼' : '▶', " ", _jsxs(Text, { dimColor: true, children: ["\uFF08Ctrl+P", open ? t('context-panel-collapse') : t('context-panel-expand'), "\uFF09"] }), " ", t('context-loaded'), " \u00B7 ", summary] }) }), open && (_jsxs(Box, { flexDirection: "column", paddingX: 1, paddingTop: 1, children: [context.sections.length > 0 && (_jsx(Group, { title: t('context-panel-sections', { n: context.sections.length }), children: context.sections.map(section => (_jsx(Entry, { entry: section }, section.name))) })), context.files.length > 0 && (_jsx(Group, { title: t('context-panel-files', { n: context.files.length }), children: context.files.map(file => (_jsx(Text, { dimColor: true, children: file.displayPath }, file.displayPath))) })), context.contexts.length > 0 && (_jsx(Group, { title: t('context-panel-runtime', { n: context.contexts.length }), children: context.contexts.map(entry => (_jsx(Entry, { entry: entry }, entry.name))) })), context.skills.length > 0 && (_jsx(Group, { title: t('context-panel-skills', { n: context.skills.length }), children: context.skills.map(skill => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: skill.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: skill.description })] }, skill.name))) })), context.tools.length > 0 && (_jsx(Group, { title: t('context-panel-tools', { n: context.tools.length }), children: context.tools.map(tool => (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { bold: true, dimColor: true, children: tool.name }), _jsx(Text, { dimColor: true, wrap: "wrap", children: truncateContextText(tool.description, 160) })] }, tool.name))) })), _jsx(Text, { dimColor: true, children: "\u00B7 /context" })] }))] }));
|
|
19
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"LogoV2.d.ts","sourceRoot":"","sources":["../../../src/components/LogoV2.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAwDzB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,MAAM,CAAC,EACrB,KAAK,EACL,MAAM,EACN,GAAG,EACH,SAAiB,GAClB,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,iFAAiF;IACjF,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GAAG,KAAK,CAAC,SAAS,CAqFlB"}
|
|
@@ -9,6 +9,7 @@ import { getTheme } from '../theme.js';
|
|
|
9
9
|
import { useTheme } from './design-system/ThemeProvider.js';
|
|
10
10
|
import { parseRGB } from './Spinner/spinnerUtils.js';
|
|
11
11
|
import { renderBigText } from './bigfont.js';
|
|
12
|
+
import { stringWidth } from '../ink/stringWidth.js';
|
|
12
13
|
import { BRAND, FLASH, ICE, PALE, sweep } from './shimmer.js';
|
|
13
14
|
import { STANDARD_FRAME_INDEX, WhaleArt } from './Whale.js';
|
|
14
15
|
import { OPENING_SEQUENCE } from './whaleFrames.js';
|
|
@@ -35,13 +36,16 @@ const WHALE_MIN_COLUMNS = 64;
|
|
|
35
36
|
*/
|
|
36
37
|
const FULL_WHALE_WIDTH = 40;
|
|
37
38
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
39
|
+
* Center of the whale art's bounding box: sprite columns 3..34 (center
|
|
40
|
+
* 18.5) of the 40-wide box. The welcome tagline is indented so its own
|
|
41
|
+
* center lands on this column — for the 14-column Chinese tagline that is
|
|
42
|
+
* 18.5 − 7 = 11.5 → 12 leading spaces. (Centering on the full 40-column
|
|
43
|
+
* box would need 13, which reads one column right of the whale body.)
|
|
44
|
+
* The pad is recomputed from the rendered tagline's display width so
|
|
45
|
+
* longer locales — e.g. the 21-column English tagline → 8 — stay
|
|
46
|
+
* centered under the art too.
|
|
43
47
|
*/
|
|
44
|
-
const
|
|
48
|
+
const WHALE_CENTER = 18.5;
|
|
45
49
|
/** `max` → `Max` (effort levels arrive lower-case from the adapter). */
|
|
46
50
|
function capitalize(text) {
|
|
47
51
|
return text.length === 0 ? text : text[0].toUpperCase() + text.slice(1);
|
|
@@ -89,7 +93,12 @@ export function LogoV2({ model, effort, cwd, skipIntro = false, }) {
|
|
|
89
93
|
// Frozen clock for the settled header: t=0 parks every sweep highlight
|
|
90
94
|
// off-screen, leaving the static gradient behind.
|
|
91
95
|
const t = settled ? 0 : time;
|
|
96
|
+
const tagline = tr('logo-tagline');
|
|
97
|
+
// Indent that centers the tagline under the whale art's bounding box.
|
|
98
|
+
const welcomePad = showWhale
|
|
99
|
+
? Math.max(0, Math.round(WHALE_CENTER - stringWidth(tagline) / 2))
|
|
100
|
+
: 2;
|
|
92
101
|
const bigDeepSeek = renderBigText('DEEPSEEK', t, wordmarkRGB, taglineRGB, FLASH, 60);
|
|
93
102
|
const bigHarness = renderBigText('HARNESS', t, taglineRGB, PALE, FLASH, 60);
|
|
94
|
-
return (_jsxs(Box, { ref: ref, flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, width: "100%", alignItems: "center", children: [showWhale && _jsx(WhaleArt, { frameIndex: frameIndex, width: FULL_WHALE_WIDTH }), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-TUI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), "/model", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-model'), " \u00B7 "] }), "/help", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-help'), " \u00B7 "] }), "Tab", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-tab')] })] })] })] }), _jsx(Box, { marginTop: 1, paddingLeft:
|
|
103
|
+
return (_jsxs(Box, { ref: ref, flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", gap: 2, width: "100%", alignItems: "center", children: [showWhale && _jsx(WhaleArt, { frameIndex: frameIndex, width: FULL_WHALE_WIDTH }), _jsxs(Box, { flexDirection: "column", flexShrink: 1, children: [_jsxs(Text, { wrap: "truncate-end", children: [sweep('✦ dsh-TUI', t, wordmarkRGB, wordmarkShimmerRGB, 60), _jsx(Text, { dimColor: true, children: ' v' + VERSION })] }), bigDeepSeek.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `ds-${index}`))), bigHarness.map((row, index) => (_jsx(Text, { wrap: "truncate-end", children: row }, `h-${index}`))), _jsxs(Text, { wrap: "truncate-end", children: [model, effort !== undefined && _jsx(Text, { dimColor: true, children: ' · ' + capitalize(effort) + ' effort' })] }), _jsx(Text, { dimColor: true, wrap: "truncate-end", children: cwd }), _jsxs(Text, { wrap: "truncate-end", children: [_jsx(Text, { dimColor: true, children: tr('logo-tip-prefix') }), "/model", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-model'), " \u00B7 "] }), "/help", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-help'), " \u00B7 "] }), "Tab", _jsxs(Text, { dimColor: true, children: [" ", tr('logo-tip-tab')] })] })] })] }), _jsx(Box, { marginTop: 1, paddingLeft: welcomePad, children: _jsx(Text, { children: sweep(tagline, t, taglineRGB, FLASH, 60) }) })] }));
|
|
95
104
|
}
|
|
@@ -18,7 +18,19 @@ type Props = {
|
|
|
18
18
|
/**
|
|
19
19
|
* 混合渲染 Markdown 内容:表格用带边框的 flexbox 组件,其余内容由
|
|
20
20
|
* formatToken 生成 ANSI 字符串放入 Text。高亮对象异步就绪后自动刷新。
|
|
21
|
+
*
|
|
22
|
+
* memo by content: finished transcript blocks render with the SAME string
|
|
23
|
+
* identity for the whole session (StreamingMarkdown keeps its stable prefix
|
|
24
|
+
* identity-stable precisely to hit this); without the memo every parent
|
|
25
|
+
* re-render re-ran the full token→ANSI→yoga pipeline for every settled
|
|
26
|
+
* block — the dominant long-output stall (string-width via wrap-ansi, 60%+
|
|
27
|
+
* of CPU in streaming profiles).
|
|
28
|
+
*/
|
|
29
|
+
declare function MarkdownImpl({ children, dimColor, cacheTokens }: Props): React.ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* Memoized Markdown: skips the whole token→ANSI→layout pipeline when the
|
|
32
|
+
* content string is the same reference (see MarkdownImpl's doc comment).
|
|
21
33
|
*/
|
|
22
|
-
export declare
|
|
34
|
+
export declare const Markdown: React.MemoExoticComponent<typeof MarkdownImpl>;
|
|
23
35
|
export {};
|
|
24
36
|
//# sourceMappingURL=Markdown.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;;;;GAQG;AAEH,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AA4GD
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../../src/components/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAOzB;;;;;;;;GAQG;AAEH,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,+CAA+C;IAC/C,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB,CAAA;AA4GD;;;;;;;;;;GAUG;AACH,iBAAS,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAgB,EAAE,WAAkB,EAAE,EAAE,KAAK,GAAG,KAAK,CAAC,SAAS,CA6BhG;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,gDAMpB,CAAA"}
|
|
@@ -90,8 +90,15 @@ function renderTokensToNodes(tokens, highlight, dimColor) {
|
|
|
90
90
|
/**
|
|
91
91
|
* 混合渲染 Markdown 内容:表格用带边框的 flexbox 组件,其余内容由
|
|
92
92
|
* formatToken 生成 ANSI 字符串放入 Text。高亮对象异步就绪后自动刷新。
|
|
93
|
+
*
|
|
94
|
+
* memo by content: finished transcript blocks render with the SAME string
|
|
95
|
+
* identity for the whole session (StreamingMarkdown keeps its stable prefix
|
|
96
|
+
* identity-stable precisely to hit this); without the memo every parent
|
|
97
|
+
* re-render re-ran the full token→ANSI→yoga pipeline for every settled
|
|
98
|
+
* block — the dominant long-output stall (string-width via wrap-ansi, 60%+
|
|
99
|
+
* of CPU in streaming profiles).
|
|
93
100
|
*/
|
|
94
|
-
|
|
101
|
+
function MarkdownImpl({ children, dimColor = false, cacheTokens = true }) {
|
|
95
102
|
const [highlight, setHighlight] = React.useState(null);
|
|
96
103
|
React.useEffect(() => {
|
|
97
104
|
let mounted = true;
|
|
@@ -110,3 +117,10 @@ export function Markdown({ children, dimColor = false, cacheTokens = true }) {
|
|
|
110
117
|
}, [children, dimColor, highlight, cacheTokens]);
|
|
111
118
|
return (_jsx(Box, { flexDirection: "column", gap: 1, children: renderedNodes }));
|
|
112
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Memoized Markdown: skips the whole token→ANSI→layout pipeline when the
|
|
122
|
+
* content string is the same reference (see MarkdownImpl's doc comment).
|
|
123
|
+
*/
|
|
124
|
+
export const Markdown = React.memo(MarkdownImpl, (prev, next) => prev.children === next.children &&
|
|
125
|
+
prev.dimColor === next.dimColor &&
|
|
126
|
+
prev.cacheTokens === next.cacheTokens);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { type ScrollBoxHandle } from '../ui.js';
|
|
3
3
|
import type { ChatRow } from '../dsh-adapter/channel.js';
|
|
4
4
|
import type { DOMElement } from '../ink/dom.js';
|
|
5
|
-
export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
|
|
5
|
+
export declare function MessageList({ rows, expanded, expandedRows, selectedId, onToggleRow, model, diffLayout, thinkingFold, showAll, onToggleAll, onLoadOlder, thinkingVisible, registerRowRef, scrollHandle, forceMountRowId, newSinceRowId, onUnseenCount, failureHintRowId, failureHint, }: {
|
|
6
6
|
rows: readonly ChatRow[];
|
|
7
7
|
expanded: boolean;
|
|
8
8
|
expandedRows: ReadonlySet<number>;
|
|
@@ -11,6 +11,8 @@ export declare function MessageList({ rows, expanded, expandedRows, selectedId,
|
|
|
11
11
|
model: string;
|
|
12
12
|
/** Edit/Write diff presentation preference (forwarded to tool cards). */
|
|
13
13
|
diffLayout?: 'auto' | 'split' | 'unified';
|
|
14
|
+
/** Thinking-block display mode from channel (`preview`/`full`). */
|
|
15
|
+
thinkingFold?: 'preview' | 'full';
|
|
14
16
|
showAll: boolean;
|
|
15
17
|
onToggleAll: () => void;
|
|
16
18
|
/** Restore folded-away older rows from the session log (CC-style "load
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/components/MessageList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAA8B,KAAK,eAAe,EAAE,MAAM,UAAU,CAAA;AAC3E,OAAO,KAAK,EAAE,OAAO,EAAyC,MAAM,2BAA2B,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAuC/C,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,QAAQ,EACR,YAAY,EACZ,UAAU,EACV,WAAW,EACX,KAAK,EACL,UAAmB,EACnB,YAAwB,EACxB,OAAO,EACP,WAAW,EACX,WAAW,EACX,eAAsB,EACtB,cAAc,EACd,YAAY,EACZ,eAAe,EACf,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,GACZ,EAAE;IACD,IAAI,EAAE,SAAS,OAAO,EAAE,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACjC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,KAAK,EAAE,MAAM,CAAA;IACb,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC,mEAAmE;IACnE,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,WAAW,EAAE,MAAM,IAAI,CAAA;IACvB;2EACuE;IACvE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAA;IACxB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/D,oDAAoD;IACpD,YAAY,CAAC,EAAE,eAAe,GAAG,IAAI,CAAA;IACrC,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B;8EAC0E;IAC1E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,4DAA4D;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,qBA6VA;AAmRD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,MAAM,EACN,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,CAAA;CACZ,GAAG,KAAK,CAAC,SAAS,CAMlB"}
|