@deepseek-harness-tui/dsh-tui 0.8.4 → 0.8.5
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/bin/dsh-tui.js +0 -0
- package/dsh-ecosystem-spec/protocols/profile-definitions.d.ts +13 -13
- package/dsh-ecosystem-spec/protocols/profile-definitions.js +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel-http.d.ts +15 -15
- package/dsh-ecosystem-spec/protocols/tui-channel-http.js +32 -32
- package/dsh-ecosystem-spec/protocols/tui-channel.d.ts +59 -59
- package/dsh-ecosystem-spec/protocols/tui-channel.js +166 -166
- package/dsh-ecosystem-spec/protocols/tui-contributions.d.ts +42 -42
- package/dsh-ecosystem-spec/protocols/tui-contributions.js +143 -143
- package/dsh-ecosystem-spec/registry/README.md +14 -14
- package/dsh-ecosystem-spec/registry/host-descriptor.tui.example.json +56 -56
- package/dsh-ecosystem-spec/registry/permissions-0.1.json +13 -13
- package/dsh-ecosystem-spec/registry/registry-0.15.json +149 -149
- package/lib/types/activityPrefs.d.ts +10 -0
- package/lib/types/activityPrefs.d.ts.map +1 -1
- package/lib/types/activityPrefs.js +17 -0
- package/lib/types/components/MessageList.d.ts +4 -1
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +4 -4
- package/lib/types/components/SplitDiffView.d.ts +3 -1
- package/lib/types/components/SplitDiffView.d.ts.map +1 -1
- package/lib/types/components/SplitDiffView.js +12 -5
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -1
- package/lib/types/components/StreamingMarkdown.js +10 -2
- package/lib/types/components/activityFrames.d.ts +7 -28
- package/lib/types/components/activityFrames.d.ts.map +1 -1
- package/lib/types/components/activityFrames.js +7 -94
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +4 -1
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +14 -3
- package/lib/types/dsh-adapter/channel.d.ts +17 -0
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel.js +161 -19
- package/lib/types/dsh-adapter/index.d.ts +5 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +19 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +176 -4
- package/lib/types/dsh-adapter/settings-sections.d.ts +13 -0
- package/lib/types/dsh-adapter/settings-sections.d.ts.map +1 -1
- package/lib/types/dsh-adapter/settings-sections.js +31 -6
- package/lib/types/ink/ink.d.ts +9 -0
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +24 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +34 -4
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +109 -50
- package/lib/types/screens/StatusLine.d.ts +8 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +62 -39
- package/lib/types/settings-sections.d.ts +1 -1
- package/lib/types/settings-sections.d.ts.map +1 -1
- package/lib/types/tips.js +2 -2
- package/lib/types/tuiDisplayPrefs.d.ts +47 -0
- package/lib/types/tuiDisplayPrefs.d.ts.map +1 -0
- package/lib/types/tuiDisplayPrefs.js +60 -0
- package/node_modules/@dsh-std/command/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/command/LICENSE +21 -21
- package/node_modules/@dsh-std/command/README.md +26 -26
- package/node_modules/@dsh-std/command/README.zh.md +28 -28
- package/node_modules/@dsh-std/command/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/command/package.json +22 -22
- package/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/node_modules/@dsh-std/connection/README.md +42 -42
- package/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/memory.js.map +1 -1
- package/node_modules/@dsh-std/connection/lib/resolve-3X6ausgz.js.map +1 -1
- package/node_modules/@dsh-std/connection/package.json +20 -20
- package/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/core/LICENSE +21 -21
- package/node_modules/@dsh-std/core/README.md +13 -13
- package/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/core/package.json +21 -21
- package/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/node_modules/@dsh-std/manifest/README.md +5 -5
- package/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/manifest/package.json +20 -20
- package/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/node_modules/@dsh-std/messages/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/messages/LICENSE +21 -21
- package/node_modules/@dsh-std/messages/README.md +5 -5
- package/node_modules/@dsh-std/messages/README.zh.md +7 -7
- package/node_modules/@dsh-std/messages/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/messages/package.json +20 -20
- package/node_modules/@dsh-std/messages/schema/message-observer-envelope-0.15.schema.json +54 -54
- package/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/node_modules/@dsh-std/presentation/README.md +27 -27
- package/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- package/node_modules/@dsh-std/presentation/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/presentation/package.json +25 -25
- package/node_modules/@dsh-std/storage/CHANGELOG.md +8 -8
- package/node_modules/@dsh-std/storage/LICENSE +21 -21
- package/node_modules/@dsh-std/storage/README.md +5 -5
- package/node_modules/@dsh-std/storage/README.zh.md +7 -7
- package/node_modules/@dsh-std/storage/lib/index.js.map +1 -1
- package/node_modules/@dsh-std/storage/package.json +20 -20
- package/node_modules/@dsh-std/storage/schema/local-storage-0.15.schema.json +56 -56
- package/package.json +6 -3
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- 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/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/README.zh.md +5 -5
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/package.json +20 -20
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/manifest/schema/dsh-plugin-0.15.schema.json +144 -144
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/CHANGELOG.md +9 -9
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/LICENSE +21 -21
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.md +27 -27
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/README.zh.md +29 -29
- package/vendor/dsh-std/packages/command/node_modules/@dsh-std/presentation/lib/callback.js.map +1 -1
- 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 +25 -25
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/connection/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/manifest/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/messages/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/README.zh.md +42 -42
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/lib/index.js.map +1 -1
- 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/lib/resolve-3X6ausgz.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/connection/package.json +20 -20
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/presentation/node_modules/@dsh-std/core/package.json +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/CHANGELOG.md +8 -8
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/LICENSE +21 -21
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/README.zh.md +13 -13
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/lib/index.js.map +1 -1
- package/vendor/dsh-std/packages/storage/node_modules/@dsh-std/core/package.json +21 -21
|
@@ -24,7 +24,10 @@ import { homeDir, LEGACY_DATA_DIR } from '../utils/paths.js';
|
|
|
24
24
|
import { extractMentions } from '../utils/mentions.js';
|
|
25
25
|
import { t } from '../i18n.js';
|
|
26
26
|
import { modeDisplayName, resolveSessionModes } from '../sessionModes.js';
|
|
27
|
+
import { normalizeStatusBar, normalizeToolBackground } from '../tuiDisplayPrefs.js';
|
|
27
28
|
import { ActivityTracker } from 'dsh-working-activity/status';
|
|
29
|
+
import { featureOn } from 'dsh-working-activity/config';
|
|
30
|
+
import { readActivityConfig } from '../activityPrefs.js';
|
|
28
31
|
import { attachSessionToWorkspace } from './workspace.js';
|
|
29
32
|
import { createLocalWorkspaceRuntime, getHostWorkspaceRuntime } from './workspaces.js';
|
|
30
33
|
import { getHostCommandTrees } from './command-trees.js';
|
|
@@ -968,6 +971,8 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
968
971
|
activityFrames: options.activityFrames,
|
|
969
972
|
diffLayout: options.diffLayout ?? 'auto',
|
|
970
973
|
thinkingFold: options.thinkingFold ?? 'preview',
|
|
974
|
+
toolBackground: normalizeToolBackground(options.toolBackground),
|
|
975
|
+
statusBar: normalizeStatusBar(options.statusBar),
|
|
971
976
|
activityEnabled: options.activity !== false,
|
|
972
977
|
contextBarEnabled: options.contextBar !== false,
|
|
973
978
|
agentPreset: options.agentPreset,
|
|
@@ -1613,10 +1618,16 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
1613
1618
|
streaming = undefined;
|
|
1614
1619
|
reasoning = undefined;
|
|
1615
1620
|
// Stale sealed/thinking bookkeeping belongs to the OLD agent's rows;
|
|
1616
|
-
// keep it out of the next turn's settle logs and revive cache.
|
|
1621
|
+
// keep it out of the next turn's settle logs and revive cache. Event
|
|
1622
|
+
// sequence numbers restart in the fresh session, so its dedupe ledgers
|
|
1623
|
+
// must not retain the old session's sequence ids.
|
|
1617
1624
|
sealedReasoning.length = 0;
|
|
1618
1625
|
lastReasoningRow = undefined;
|
|
1619
1626
|
toolCards.clear();
|
|
1627
|
+
handledAssistantMessages.clear();
|
|
1628
|
+
handledAssistantChunks.clear();
|
|
1629
|
+
assistantRowsByStep.clear();
|
|
1630
|
+
lastTextDelta.clear();
|
|
1620
1631
|
nextRowId = 0;
|
|
1621
1632
|
state.rows.length = 0;
|
|
1622
1633
|
// Goal/todo/title are session-scoped; the replay re-derives them for
|
|
@@ -1644,6 +1655,7 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
1644
1655
|
state.tpsSamples = [];
|
|
1645
1656
|
state.lastUsage = undefined;
|
|
1646
1657
|
state.workingActivity = undefined;
|
|
1658
|
+
state.loadedContext = undefined;
|
|
1647
1659
|
state.contextWindow = undefined;
|
|
1648
1660
|
state.contextSegments = {
|
|
1649
1661
|
system: 0,
|
|
@@ -1837,6 +1849,8 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
1837
1849
|
agent = handle.agent;
|
|
1838
1850
|
currentHandle = handle;
|
|
1839
1851
|
bindAgent();
|
|
1852
|
+
// Model-switch quip rides the fresh tracker (pi parity).
|
|
1853
|
+
activityTracker.onModelSwitch(model);
|
|
1840
1854
|
refreshCommandList();
|
|
1841
1855
|
void refreshLoadedContext();
|
|
1842
1856
|
void refreshSkillCommands();
|
|
@@ -1913,6 +1927,21 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
1913
1927
|
state.thinkingFold = mode;
|
|
1914
1928
|
state.emit();
|
|
1915
1929
|
},
|
|
1930
|
+
setToolBackground(background) {
|
|
1931
|
+
const normalized = normalizeToolBackground(background);
|
|
1932
|
+
if (normalized === state.toolBackground)
|
|
1933
|
+
return;
|
|
1934
|
+
state.toolBackground = normalized;
|
|
1935
|
+
state.emit();
|
|
1936
|
+
},
|
|
1937
|
+
setStatusBar(config) {
|
|
1938
|
+
const next = normalizeStatusBar({ ...state.statusBar, ...config });
|
|
1939
|
+
const changed = Object.keys(next).some(key => next[key] !== state.statusBar[key]);
|
|
1940
|
+
if (!changed)
|
|
1941
|
+
return;
|
|
1942
|
+
state.statusBar = next;
|
|
1943
|
+
state.emit();
|
|
1944
|
+
},
|
|
1916
1945
|
setActivityFrames(name) {
|
|
1917
1946
|
if (!isPresetName(name)) {
|
|
1918
1947
|
state.notify(t('unknown-activity-preset', { name }), { color: 'error' });
|
|
@@ -2318,6 +2347,9 @@ export function createChannel(ctx, initialAgent, options) {
|
|
|
2318
2347
|
.compactNow(agent, signal)
|
|
2319
2348
|
.then((result) => {
|
|
2320
2349
|
state.notify(result ? t('compact-done') : t('compact-nothing'));
|
|
2350
|
+
// Compaction quip rides the next thinking rotation (pi parity).
|
|
2351
|
+
if (result)
|
|
2352
|
+
activityTracker.onCompact('done');
|
|
2321
2353
|
})
|
|
2322
2354
|
.catch((error) => {
|
|
2323
2355
|
state.notify(t('compact-failed', { err: error instanceof Error ? error.message : String(error) }), { color: 'error', timeoutMs: 8000 });
|
|
@@ -2983,6 +3015,39 @@ ${output}
|
|
|
2983
3015
|
let tpsStep;
|
|
2984
3016
|
/** Tool cards by callId, so tool/result can settle the running card. */
|
|
2985
3017
|
const toolCards = new Map();
|
|
3018
|
+
/**
|
|
3019
|
+
* Session events are delivered live and can also be replayed around a
|
|
3020
|
+
* reconnect. A repeated sealed message must not create a second assistant
|
|
3021
|
+
* row for the same durable sequence number.
|
|
3022
|
+
*/
|
|
3023
|
+
const handledAssistantMessages = new Set();
|
|
3024
|
+
const handledAssistantChunks = new Set();
|
|
3025
|
+
const assistantRowsByStep = new Map();
|
|
3026
|
+
const lastTextDelta = new Map();
|
|
3027
|
+
const stepKey = (turn, step) => `${turn}:${step}`;
|
|
3028
|
+
/** Append a stream delta idempotently. Providers normally send a pure
|
|
3029
|
+
* delta, but reconnect/proxy paths can resend a cumulative prefix or a
|
|
3030
|
+
* delta whose beginning overlaps the previous tail. Merge the overlap
|
|
3031
|
+
* instead of blindly concatenating it into the visible transcript. */
|
|
3032
|
+
const appendTextDelta = (row, delta) => {
|
|
3033
|
+
if (delta === '')
|
|
3034
|
+
return;
|
|
3035
|
+
if (lastTextDelta.get(row) === delta)
|
|
3036
|
+
return;
|
|
3037
|
+
lastTextDelta.set(row, delta);
|
|
3038
|
+
if (delta.startsWith(row.text)) {
|
|
3039
|
+
row.text = delta;
|
|
3040
|
+
return;
|
|
3041
|
+
}
|
|
3042
|
+
const maxOverlap = Math.min(row.text.length, delta.length, 4096);
|
|
3043
|
+
for (let size = maxOverlap; size > 0; size--) {
|
|
3044
|
+
if (row.text.endsWith(delta.slice(0, size))) {
|
|
3045
|
+
row.text += delta.slice(size);
|
|
3046
|
+
return;
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
row.text += delta;
|
|
3050
|
+
};
|
|
2986
3051
|
/** The host-plane tools registry (dsh-tools). Resolved once; absent in
|
|
2987
3052
|
* bare embedders — every presenter call soft-fails to undefined and the
|
|
2988
3053
|
* card falls back to raw text. */
|
|
@@ -3034,11 +3099,22 @@ ${output}
|
|
|
3034
3099
|
*/
|
|
3035
3100
|
const firstTextOf = (content) => (content ?? []).find(block => block.type === 'text')?.text.trim() ?? '';
|
|
3036
3101
|
const ensureStreaming = (seq) => {
|
|
3037
|
-
if (streaming
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3102
|
+
if (streaming !== undefined)
|
|
3103
|
+
return streaming;
|
|
3104
|
+
// A reconnect can replay the first delta after the sealed message was
|
|
3105
|
+
// already observed. Reuse that durable row instead of opening a second
|
|
3106
|
+
// assistant bubble for the same event sequence.
|
|
3107
|
+
const existing = seq === undefined
|
|
3108
|
+
? undefined
|
|
3109
|
+
: [...state.rows].reverse().find(row => row.kind === 'assistant' && row.seq === seq);
|
|
3110
|
+
if (existing !== undefined) {
|
|
3111
|
+
existing.streaming = true;
|
|
3112
|
+
streaming = existing;
|
|
3113
|
+
return existing;
|
|
3041
3114
|
}
|
|
3115
|
+
streaming = { id: nextRowId, kind: 'assistant', text: '', streaming: true, ...seq !== undefined ? { seq } : {} };
|
|
3116
|
+
nextRowId += 1;
|
|
3117
|
+
state.rows.push(streaming);
|
|
3042
3118
|
return streaming;
|
|
3043
3119
|
};
|
|
3044
3120
|
/** Latest reasoning row keyed by its (turn, step) — lets a resumed
|
|
@@ -3169,6 +3245,13 @@ ${output}
|
|
|
3169
3245
|
* using it would rebuild a second thinking block per step. */
|
|
3170
3246
|
let replaying = false;
|
|
3171
3247
|
const replayEvents = (events) => {
|
|
3248
|
+
// Event sequence numbers restart with a replacement session; reset the
|
|
3249
|
+
// idempotency ledger before replay so an old session cannot suppress a
|
|
3250
|
+
// legitimate message in the new transcript.
|
|
3251
|
+
handledAssistantMessages.clear();
|
|
3252
|
+
handledAssistantChunks.clear();
|
|
3253
|
+
assistantRowsByStep.clear();
|
|
3254
|
+
lastTextDelta.clear();
|
|
3172
3255
|
replaying = true;
|
|
3173
3256
|
try {
|
|
3174
3257
|
for (const event of prepareReplayEvents(events))
|
|
@@ -3256,6 +3339,9 @@ ${output}
|
|
|
3256
3339
|
break;
|
|
3257
3340
|
}
|
|
3258
3341
|
case 'assistant/chunk': {
|
|
3342
|
+
if (handledAssistantChunks.has(event.seq))
|
|
3343
|
+
break;
|
|
3344
|
+
handledAssistantChunks.add(event.seq);
|
|
3259
3345
|
const chunk = event.data.chunk;
|
|
3260
3346
|
if (chunk.type === 'text-delta') {
|
|
3261
3347
|
if (chunk.text) {
|
|
@@ -3263,13 +3349,20 @@ ${output}
|
|
|
3263
3349
|
// window (see foldLiveReasoning) — before this text grows the
|
|
3264
3350
|
// transcript and pushes the block into scrollback.
|
|
3265
3351
|
foldLiveReasoning('first text token');
|
|
3266
|
-
|
|
3267
|
-
|
|
3352
|
+
const key = stepKey(event.data.turn, event.data.step);
|
|
3353
|
+
const row = assistantRowsByStep.get(key) ?? ensureStreaming(event.seq);
|
|
3354
|
+
assistantRowsByStep.set(key, row);
|
|
3355
|
+
streaming = row;
|
|
3356
|
+
row.streaming = true;
|
|
3357
|
+
const before = row.text.length;
|
|
3358
|
+
appendTextDelta(row, chunk.text);
|
|
3359
|
+
state.responseChars += Math.max(0, row.text.length - before);
|
|
3268
3360
|
}
|
|
3269
3361
|
}
|
|
3270
3362
|
else if (chunk.type === 'reasoning-delta') {
|
|
3271
3363
|
if (chunk.text) {
|
|
3272
|
-
ensureReasoning(event.seq, event.data.turn, event.data.step)
|
|
3364
|
+
const row = ensureReasoning(event.seq, event.data.turn, event.data.step);
|
|
3365
|
+
appendTextDelta(row, chunk.text);
|
|
3273
3366
|
}
|
|
3274
3367
|
}
|
|
3275
3368
|
const step = tpsStep;
|
|
@@ -3290,6 +3383,9 @@ ${output}
|
|
|
3290
3383
|
break;
|
|
3291
3384
|
}
|
|
3292
3385
|
case 'assistant/message': {
|
|
3386
|
+
if (handledAssistantMessages.has(event.seq))
|
|
3387
|
+
break;
|
|
3388
|
+
handledAssistantMessages.add(event.seq);
|
|
3293
3389
|
const text = textOf(event.data.message.content);
|
|
3294
3390
|
// Replay without chunk deltas (prepareReplayEvents drops settled
|
|
3295
3391
|
// ones): rebuild the reasoning row from the sealed message's
|
|
@@ -3319,8 +3415,22 @@ ${output}
|
|
|
3319
3415
|
// anyway leaves an empty `●` bullet in the transcript. A pre-existing
|
|
3320
3416
|
// streaming row always has text (ensureStreaming is only reached on
|
|
3321
3417
|
// non-empty text deltas), so only create one when text arrives.
|
|
3322
|
-
|
|
3418
|
+
// Key the step→row ledger only when the event carries a durable
|
|
3419
|
+
// turn/step; a message without them must never collide onto a
|
|
3420
|
+
// previous step's row (a bare `undefined:undefined` key would make
|
|
3421
|
+
// every turn/step-less message reuse the FIRST one's assistant row).
|
|
3422
|
+
const msgTurn = event.data.turn;
|
|
3423
|
+
const msgStep = event.data.step;
|
|
3424
|
+
const msgKey = msgTurn !== undefined && msgStep !== undefined
|
|
3425
|
+
? stepKey(msgTurn, msgStep)
|
|
3426
|
+
: undefined;
|
|
3427
|
+
const row = (msgKey !== undefined ? assistantRowsByStep.get(msgKey) : undefined) ?? streaming ??
|
|
3428
|
+
(text
|
|
3429
|
+
? ([...state.rows].reverse().find(candidate => candidate.kind === 'assistant' && candidate.seq === event.seq) ?? ensureStreaming(event.seq))
|
|
3430
|
+
: undefined);
|
|
3323
3431
|
if (row !== undefined) {
|
|
3432
|
+
if (msgKey !== undefined)
|
|
3433
|
+
assistantRowsByStep.set(msgKey, row);
|
|
3324
3434
|
row.time = event.time;
|
|
3325
3435
|
if (text)
|
|
3326
3436
|
row.text = text;
|
|
@@ -3616,11 +3726,36 @@ ${output}
|
|
|
3616
3726
|
// Live subscription list and activity timer, rebound to every replacement
|
|
3617
3727
|
// agent so no status from the previous session can leak across a swap.
|
|
3618
3728
|
let agentSubscriptions = [];
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3729
|
+
/** Tracker knobs + custom actions from the persisted pi-style config
|
|
3730
|
+
* (`~/.dsh-tui/working-activity.json`); a missing file means lively
|
|
3731
|
+
* defaults (all eggs on). */
|
|
3732
|
+
const activityPrefsSnapshot = () => {
|
|
3733
|
+
const cfg = readActivityConfig();
|
|
3734
|
+
if (cfg === undefined) {
|
|
3735
|
+
return { config: { phrases: true, detailLimit: 40, showIdle: false } };
|
|
3736
|
+
}
|
|
3737
|
+
return {
|
|
3738
|
+
config: {
|
|
3739
|
+
phrases: featureOn(cfg, 'phrases'),
|
|
3740
|
+
detailLimit: 40,
|
|
3741
|
+
showIdle: false,
|
|
3742
|
+
features: {
|
|
3743
|
+
rareEggs: featureOn(cfg, 'rareEggs'),
|
|
3744
|
+
weekend: featureOn(cfg, 'weekend'),
|
|
3745
|
+
holidays: featureOn(cfg, 'holidays'),
|
|
3746
|
+
nightPhrases: featureOn(cfg, 'nightPhrases'),
|
|
3747
|
+
},
|
|
3748
|
+
customPhrases: cfg.customPhrases,
|
|
3749
|
+
showTokPerSec: cfg.showTokPerSec,
|
|
3750
|
+
workRemindAt: cfg.workRemindAt,
|
|
3751
|
+
},
|
|
3752
|
+
customActions: cfg.customActions,
|
|
3753
|
+
};
|
|
3754
|
+
};
|
|
3755
|
+
let activityTracker = (() => {
|
|
3756
|
+
const prefs = activityPrefsSnapshot();
|
|
3757
|
+
return new ActivityTracker(prefs.config, Date.now, prefs.customActions);
|
|
3758
|
+
})();
|
|
3624
3759
|
let activityTickTimer;
|
|
3625
3760
|
const stopActivityTick = () => {
|
|
3626
3761
|
if (activityTickTimer === undefined)
|
|
@@ -3642,11 +3777,8 @@ ${output}
|
|
|
3642
3777
|
for (const dispose of agentSubscriptions)
|
|
3643
3778
|
dispose();
|
|
3644
3779
|
stopActivityTick();
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
detailLimit: 40,
|
|
3648
|
-
showIdle: false,
|
|
3649
|
-
});
|
|
3780
|
+
const prefs = activityPrefsSnapshot();
|
|
3781
|
+
activityTracker = new ActivityTracker(prefs.config, Date.now, prefs.customActions);
|
|
3650
3782
|
activityTracker.onAgentStatus(agent.status);
|
|
3651
3783
|
renderWorkingActivity();
|
|
3652
3784
|
activityTickTimer = setInterval(() => {
|
|
@@ -3742,6 +3874,14 @@ ${output}
|
|
|
3742
3874
|
// publish never throws into this arm.
|
|
3743
3875
|
messageObserver?.publish(session, event);
|
|
3744
3876
|
activityTracker.onSessionEvent(event);
|
|
3877
|
+
// Interrupt quip: an aborted/interrupted turn ends the round; the
|
|
3878
|
+
// comeback copy shows on the next thinking rotation (pi parity).
|
|
3879
|
+
if (event.type === 'turn/end') {
|
|
3880
|
+
const reason = event.data.reason;
|
|
3881
|
+
if (reason?.kind === 'aborted' || reason?.kind === 'interrupted') {
|
|
3882
|
+
activityTracker.onInterrupted();
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3745
3885
|
renderWorkingActivity();
|
|
3746
3886
|
// Mode-affecting atoms fold into the Shift+Tab mode indicator the
|
|
3747
3887
|
// moment they land (whether appended by cycleMode or by hand).
|
|
@@ -3809,6 +3949,8 @@ ${output}
|
|
|
3809
3949
|
// only show a branch for sessions this install actually used — which
|
|
3810
3950
|
// is exactly what the column claims.
|
|
3811
3951
|
noteBranch(agent.session.id, branch);
|
|
3952
|
+
// Feed the working line so git tools can show ` · git <branch>`.
|
|
3953
|
+
activityTracker.onGitBranch(branch);
|
|
3812
3954
|
state.emit();
|
|
3813
3955
|
}
|
|
3814
3956
|
})
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Context } from '@deepseek-ai/cordis';
|
|
10
10
|
import Schema from '@deepseek-ai/schemastery';
|
|
11
11
|
import type { SessionModeSpec } from '../sessionModes.js';
|
|
12
|
+
import { type StatusBarConfig, type ToolBackground } from '../tuiDisplayPrefs.js';
|
|
12
13
|
export declare const name = "dsh-tui";
|
|
13
14
|
export declare const inject: string[];
|
|
14
15
|
/**
|
|
@@ -70,6 +71,10 @@ export interface Config {
|
|
|
70
71
|
* preview and folds each step when it settles; `full` keeps thinking
|
|
71
72
|
* expanded until the whole turn ends. Editable live from `/settings`. */
|
|
72
73
|
thinkingFold?: 'preview' | 'full';
|
|
74
|
+
/** Tool-card background strength; defaults to no added background. */
|
|
75
|
+
toolBackground?: ToolBackground;
|
|
76
|
+
/** Status-footer field visibility and compact presentation preferences. */
|
|
77
|
+
statusBar?: Partial<StatusBarConfig>;
|
|
73
78
|
/** Shift+Tab session-mode cycle (array order IS the cycle order; index 0
|
|
74
79
|
* is the unmarked base mode). Each entry bundles any subset of the
|
|
75
80
|
* `plan`/`sandbox`/`approval` atoms; absent → the built-in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,MAAM,MAAM,0BAA0B,CAAA;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EAAsB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAErG,eAAO,MAAM,IAAI,YAAY,CAAA;AAU7B,eAAO,MAAM,MAAM,UAAa,CAAA;AAEhC;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;;yEAKqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;gDAC4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;gFAE4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ;oCACgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;sBAIkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;4BAGwB;IACxB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;wDAEoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;kFAC8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;gCAG4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;6DAEyD;IACzD,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAA;IACzC;;8EAE0E;IAC1E,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;IACjC,sEAAsE;IACtE,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACpC;;;yDAGqD;IACrD,KAAK,CAAC,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,CA8ChC,CAAA;AAEF;;;;;;GAMG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWvE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Schema from '@deepseek-ai/schemastery';
|
|
2
|
+
import { DEFAULT_STATUS_BAR } from '../tuiDisplayPrefs.js';
|
|
2
3
|
export const name = 'dsh-tui';
|
|
3
4
|
// `tuiWorkspaces` must stay OUT of this code-level inject (issue #183): the
|
|
4
5
|
// dsh CLI resolves the bundle's cordis.patch.yml from the FIRST copy of this
|
|
@@ -29,6 +30,24 @@ export const Config = Schema.object({
|
|
|
29
30
|
preset: Schema.string().required(false),
|
|
30
31
|
diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
|
|
31
32
|
thinkingFold: Schema.union(['preview', 'full']).default('preview'),
|
|
33
|
+
toolBackground: Schema.union(['none', 'subtle', 'strong']).default('none'),
|
|
34
|
+
statusBar: Schema.object({
|
|
35
|
+
compact: Schema.boolean().default(DEFAULT_STATUS_BAR.compact),
|
|
36
|
+
model: Schema.boolean().default(DEFAULT_STATUS_BAR.model),
|
|
37
|
+
thinking: Schema.boolean().default(DEFAULT_STATUS_BAR.thinking),
|
|
38
|
+
cwd: Schema.boolean().default(DEFAULT_STATUS_BAR.cwd),
|
|
39
|
+
contextUsage: Schema.boolean().default(DEFAULT_STATUS_BAR.contextUsage),
|
|
40
|
+
cache: Schema.boolean().default(DEFAULT_STATUS_BAR.cache),
|
|
41
|
+
tokens: Schema.boolean().default(DEFAULT_STATUS_BAR.tokens),
|
|
42
|
+
tps: Schema.boolean().default(DEFAULT_STATUS_BAR.tps),
|
|
43
|
+
gitBranch: Schema.boolean().default(DEFAULT_STATUS_BAR.gitBranch),
|
|
44
|
+
sessionTitle: Schema.boolean().default(DEFAULT_STATUS_BAR.sessionTitle),
|
|
45
|
+
mode: Schema.boolean().default(DEFAULT_STATUS_BAR.mode),
|
|
46
|
+
contextBar: Schema.boolean().default(DEFAULT_STATUS_BAR.contextBar),
|
|
47
|
+
activity: Schema.boolean().default(DEFAULT_STATUS_BAR.activity),
|
|
48
|
+
trajectory: Schema.boolean().default(DEFAULT_STATUS_BAR.trajectory),
|
|
49
|
+
shortcutHint: Schema.boolean().default(DEFAULT_STATUS_BAR.shortcutHint),
|
|
50
|
+
}).default({ ...DEFAULT_STATUS_BAR }),
|
|
32
51
|
modes: Schema.array(Schema.object({
|
|
33
52
|
id: Schema.string(),
|
|
34
53
|
label: Schema.string().required(false),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,wBAAwB,CAAA;AAGhE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAoCnC;;;;;;;;GAQG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsyBvE;AA6GD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CAAE,GAAG;IACjF,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB,CAcA;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,KAAK,GAAG,SAAS,CAAA;IAC5B,YAAY,EAAE,KAAK,CAAA;CACpB,GAAG,OAAO,CAQV"}
|
|
@@ -23,6 +23,7 @@ import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
|
|
|
23
23
|
import { resolveSessionCwd } from '../utils/workspaceRoot.js';
|
|
24
24
|
import { checkForTuiUpdate, installedTuiVersion, isBootDeadlockTarget, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
25
25
|
import { getLang, isLang, resolveStartupLang, setLang, t, writeLangPref } from '../i18n.js';
|
|
26
|
+
import { DEFAULT_STATUS_BAR, normalizeStatusBar, normalizeToolBackground } from '../tuiDisplayPrefs.js';
|
|
26
27
|
import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
|
|
27
28
|
import { Chat } from '../screens/Chat.js';
|
|
28
29
|
import { getHostDialogStore } from './dialogs.js';
|
|
@@ -326,6 +327,8 @@ export async function apply(ctx, config) {
|
|
|
326
327
|
// screen edits this key live through the dsh-tui namespace.
|
|
327
328
|
diffLayout: config.diffLayout,
|
|
328
329
|
thinkingFold: config.thinkingFold,
|
|
330
|
+
toolBackground: config.toolBackground,
|
|
331
|
+
statusBar: config.statusBar,
|
|
329
332
|
handle,
|
|
330
333
|
});
|
|
331
334
|
// Register the dsh-tui settings namespace so the /settings screen can
|
|
@@ -336,6 +339,24 @@ export async function apply(ctx, config) {
|
|
|
336
339
|
const scope = settingsCtx.settings.register(settingsNamespace('dsh-tui'), Schema.object({
|
|
337
340
|
diffLayout: Schema.union(['auto', 'split', 'unified']).default('auto'),
|
|
338
341
|
thinkingFold: Schema.union(['preview', 'full']).default('preview'),
|
|
342
|
+
toolBackground: Schema.union(['none', 'subtle', 'strong']).default('none'),
|
|
343
|
+
statusBar: Schema.object({
|
|
344
|
+
compact: Schema.boolean().default(DEFAULT_STATUS_BAR.compact),
|
|
345
|
+
model: Schema.boolean().default(DEFAULT_STATUS_BAR.model),
|
|
346
|
+
thinking: Schema.boolean().default(DEFAULT_STATUS_BAR.thinking),
|
|
347
|
+
cwd: Schema.boolean().default(DEFAULT_STATUS_BAR.cwd),
|
|
348
|
+
contextUsage: Schema.boolean().default(DEFAULT_STATUS_BAR.contextUsage),
|
|
349
|
+
cache: Schema.boolean().default(DEFAULT_STATUS_BAR.cache),
|
|
350
|
+
tokens: Schema.boolean().default(DEFAULT_STATUS_BAR.tokens),
|
|
351
|
+
tps: Schema.boolean().default(DEFAULT_STATUS_BAR.tps),
|
|
352
|
+
gitBranch: Schema.boolean().default(DEFAULT_STATUS_BAR.gitBranch),
|
|
353
|
+
sessionTitle: Schema.boolean().default(DEFAULT_STATUS_BAR.sessionTitle),
|
|
354
|
+
mode: Schema.boolean().default(DEFAULT_STATUS_BAR.mode),
|
|
355
|
+
contextBar: Schema.boolean().default(DEFAULT_STATUS_BAR.contextBar),
|
|
356
|
+
activity: Schema.boolean().default(DEFAULT_STATUS_BAR.activity),
|
|
357
|
+
trajectory: Schema.boolean().default(DEFAULT_STATUS_BAR.trajectory),
|
|
358
|
+
shortcutHint: Schema.boolean().default(DEFAULT_STATUS_BAR.shortcutHint),
|
|
359
|
+
}).default({ ...DEFAULT_STATUS_BAR }),
|
|
339
360
|
// No default on purpose: an unset `lang` keeps the field showing
|
|
340
361
|
// the effective language (see the section's format below) and lets
|
|
341
362
|
// cordis.yml / lang.json keep their precedence.
|
|
@@ -355,15 +376,17 @@ export async function apply(ctx, config) {
|
|
|
355
376
|
writeLangPref(value.lang);
|
|
356
377
|
}
|
|
357
378
|
};
|
|
358
|
-
//
|
|
359
|
-
//
|
|
360
|
-
const
|
|
379
|
+
// Display preferences ride the same namespace: /settings writes them
|
|
380
|
+
// live and future render consumers observe the channel version bump.
|
|
381
|
+
const applyDisplay = (value) => {
|
|
361
382
|
channel.setThinkingFold(value.thinkingFold ?? config.thinkingFold ?? 'preview');
|
|
383
|
+
channel.setToolBackground(normalizeToolBackground(value.toolBackground ?? config.toolBackground));
|
|
384
|
+
channel.setStatusBar(normalizeStatusBar(value.statusBar ?? config.statusBar));
|
|
362
385
|
};
|
|
363
386
|
const apply = (next) => {
|
|
364
387
|
applyLayout(next);
|
|
365
388
|
applyLang(next);
|
|
366
|
-
|
|
389
|
+
applyDisplay(next);
|
|
367
390
|
};
|
|
368
391
|
apply(scope.get());
|
|
369
392
|
scope.watch(next => {
|
|
@@ -379,6 +402,7 @@ export async function apply(ctx, config) {
|
|
|
379
402
|
const unregister = settingsSections.register({
|
|
380
403
|
ns: 'dsh-tui',
|
|
381
404
|
title: 'dsh-tui',
|
|
405
|
+
groups: [{ id: 'status-bar', title: 'Status bar', descriptions: { zh: '底栏设置' } }],
|
|
382
406
|
fields: [
|
|
383
407
|
{
|
|
384
408
|
path: ['lang'],
|
|
@@ -423,6 +447,154 @@ export async function apply(ctx, config) {
|
|
|
423
447
|
{ value: 'full', label: 'Full until turn end', descriptions: { zh: '展开至轮末' } },
|
|
424
448
|
],
|
|
425
449
|
},
|
|
450
|
+
{
|
|
451
|
+
path: ['toolBackground'],
|
|
452
|
+
label: 'Tool background',
|
|
453
|
+
descriptions: { zh: '工具卡背景' },
|
|
454
|
+
hint: 'Choose whether tool-call cards add no, subtle, or strong background emphasis.',
|
|
455
|
+
hintDescriptions: { zh: '选择工具调用卡片不添加、轻微或明显的背景强调。' },
|
|
456
|
+
kind: 'select',
|
|
457
|
+
options: [
|
|
458
|
+
{ value: 'none', label: 'None', descriptions: { zh: '无' } },
|
|
459
|
+
{ value: 'subtle', label: 'Subtle', descriptions: { zh: '轻微' } },
|
|
460
|
+
{ value: 'strong', label: 'Strong', descriptions: { zh: '明显' } },
|
|
461
|
+
],
|
|
462
|
+
},
|
|
463
|
+
{
|
|
464
|
+
path: ['statusBar', 'compact'],
|
|
465
|
+
label: 'Compact status bar',
|
|
466
|
+
descriptions: { zh: '紧凑状态栏' },
|
|
467
|
+
hint: 'Prefer the compact status presentation when terminal space allows.',
|
|
468
|
+
hintDescriptions: { zh: '终端空间允许时优先使用紧凑状态栏布局。' },
|
|
469
|
+
group: 'status-bar',
|
|
470
|
+
kind: 'boolean',
|
|
471
|
+
},
|
|
472
|
+
{
|
|
473
|
+
path: ['statusBar', 'model'],
|
|
474
|
+
label: 'Show model',
|
|
475
|
+
descriptions: { zh: '显示模型' },
|
|
476
|
+
hint: 'Show the live model id in the status bar.',
|
|
477
|
+
hintDescriptions: { zh: '在状态栏显示当前模型标识。' },
|
|
478
|
+
group: 'status-bar',
|
|
479
|
+
kind: 'boolean',
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
path: ['statusBar', 'thinking'],
|
|
483
|
+
label: 'Show thinking',
|
|
484
|
+
descriptions: { zh: '显示思考' },
|
|
485
|
+
hint: 'Show the live reasoning effort or thinking mode.',
|
|
486
|
+
hintDescriptions: { zh: '显示当前推理强度或思考模式。' },
|
|
487
|
+
group: 'status-bar',
|
|
488
|
+
kind: 'boolean',
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
path: ['statusBar', 'cwd'],
|
|
492
|
+
label: 'Show working directory',
|
|
493
|
+
descriptions: { zh: '显示工作目录' },
|
|
494
|
+
hint: 'Show the session working directory.',
|
|
495
|
+
hintDescriptions: { zh: '显示当前会话的工作目录。' },
|
|
496
|
+
group: 'status-bar',
|
|
497
|
+
kind: 'boolean',
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
path: ['statusBar', 'contextUsage'],
|
|
501
|
+
label: 'Show context usage',
|
|
502
|
+
descriptions: { zh: '显示上下文用量' },
|
|
503
|
+
hint: 'Show current context-window consumption.',
|
|
504
|
+
hintDescriptions: { zh: '显示当前上下文窗口占用情况。' },
|
|
505
|
+
group: 'status-bar',
|
|
506
|
+
kind: 'boolean',
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
path: ['statusBar', 'cache'],
|
|
510
|
+
label: 'Show cache',
|
|
511
|
+
descriptions: { zh: '显示缓存' },
|
|
512
|
+
hint: 'Show prompt-cache hit information.',
|
|
513
|
+
hintDescriptions: { zh: '显示提示词缓存命中信息。' },
|
|
514
|
+
group: 'status-bar',
|
|
515
|
+
kind: 'boolean',
|
|
516
|
+
},
|
|
517
|
+
{
|
|
518
|
+
path: ['statusBar', 'tokens'],
|
|
519
|
+
label: 'Show token totals',
|
|
520
|
+
descriptions: { zh: '显示 Token 总量' },
|
|
521
|
+
hint: 'Show running input and output token totals.',
|
|
522
|
+
hintDescriptions: { zh: '显示累计输入与输出 Token。' },
|
|
523
|
+
group: 'status-bar',
|
|
524
|
+
kind: 'boolean',
|
|
525
|
+
},
|
|
526
|
+
{
|
|
527
|
+
path: ['statusBar', 'tps'],
|
|
528
|
+
label: 'Show output speed',
|
|
529
|
+
descriptions: { zh: '显示输出速度' },
|
|
530
|
+
hint: 'Show live and recent tokens-per-second metrics.',
|
|
531
|
+
hintDescriptions: { zh: '显示实时及近期每秒 Token 指标。' },
|
|
532
|
+
group: 'status-bar',
|
|
533
|
+
kind: 'boolean',
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
path: ['statusBar', 'gitBranch'],
|
|
537
|
+
label: 'Show git branch',
|
|
538
|
+
descriptions: { zh: '显示 Git 分支' },
|
|
539
|
+
hint: 'Show the current git branch when available.',
|
|
540
|
+
hintDescriptions: { zh: '可用时显示当前 Git 分支。' },
|
|
541
|
+
group: 'status-bar',
|
|
542
|
+
kind: 'boolean',
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
path: ['statusBar', 'sessionTitle'],
|
|
546
|
+
label: 'Show session title',
|
|
547
|
+
descriptions: { zh: '显示会话标题' },
|
|
548
|
+
hint: 'Show the current session title.',
|
|
549
|
+
hintDescriptions: { zh: '显示当前会话标题。' },
|
|
550
|
+
group: 'status-bar',
|
|
551
|
+
kind: 'boolean',
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
path: ['statusBar', 'mode'],
|
|
555
|
+
label: 'Show session mode',
|
|
556
|
+
descriptions: { zh: '显示会话模式' },
|
|
557
|
+
hint: 'Show the active non-default session mode.',
|
|
558
|
+
hintDescriptions: { zh: '显示当前启用的非默认会话模式。' },
|
|
559
|
+
group: 'status-bar',
|
|
560
|
+
kind: 'boolean',
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
path: ['statusBar', 'contextBar'],
|
|
564
|
+
label: 'Show context progress bar',
|
|
565
|
+
descriptions: { zh: '显示上下文进度条' },
|
|
566
|
+
hint: 'Show the segmented context progress bar on its own footer row.',
|
|
567
|
+
hintDescriptions: { zh: '在底部单独一行显示分段上下文进度条。' },
|
|
568
|
+
group: 'status-bar',
|
|
569
|
+
kind: 'boolean',
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
path: ['statusBar', 'activity'],
|
|
573
|
+
label: 'Show activity summary',
|
|
574
|
+
descriptions: { zh: '显示活动摘要' },
|
|
575
|
+
hint: 'Show the idle working-activity summary.',
|
|
576
|
+
hintDescriptions: { zh: '显示空闲时的工作活动摘要。' },
|
|
577
|
+
group: 'status-bar',
|
|
578
|
+
kind: 'boolean',
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
path: ['statusBar', 'trajectory'],
|
|
582
|
+
label: 'Show trajectory strip',
|
|
583
|
+
descriptions: { zh: '显示轨迹条' },
|
|
584
|
+
hint: 'Show the animated mini trajectory strip at the footer edge.',
|
|
585
|
+
hintDescriptions: { zh: '在状态栏边缘显示动态迷你轨迹条。' },
|
|
586
|
+
group: 'status-bar',
|
|
587
|
+
kind: 'boolean',
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
path: ['statusBar', 'shortcutHint'],
|
|
591
|
+
label: 'Show shortcut reminder',
|
|
592
|
+
descriptions: { zh: '显示快捷键提示' },
|
|
593
|
+
hint: 'Control only the idle `? for shortcuts` reminder; pressing ? and the Esc shortcut hints are unaffected.',
|
|
594
|
+
hintDescriptions: { zh: '仅控制空闲时的 `? for shortcuts` 提示;按 ? 打开快捷键以及 Esc 快捷提示均不受影响。' },
|
|
595
|
+
group: 'status-bar',
|
|
596
|
+
kind: 'boolean',
|
|
597
|
+
},
|
|
426
598
|
],
|
|
427
599
|
});
|
|
428
600
|
ctx.effect(() => unregister);
|
|
@@ -21,6 +21,15 @@ export interface TuiSettingsFieldOption {
|
|
|
21
21
|
/** Provider-owned translations for the label. */
|
|
22
22
|
descriptions?: LocalizedDescriptions;
|
|
23
23
|
}
|
|
24
|
+
/** Optional navigation group inside one settings section. */
|
|
25
|
+
export interface TuiSettingsGroup {
|
|
26
|
+
/** Stable identifier, unique inside the section. */
|
|
27
|
+
id: string;
|
|
28
|
+
/** Group title (English; also the fallback). */
|
|
29
|
+
title: string;
|
|
30
|
+
/** Provider-owned translations for the title. */
|
|
31
|
+
descriptions?: LocalizedDescriptions;
|
|
32
|
+
}
|
|
24
33
|
/** The write one field's draft stages when the section is saved. */
|
|
25
34
|
export type TuiSettingsFieldWrite = {
|
|
26
35
|
kind: 'set';
|
|
@@ -42,6 +51,8 @@ export interface TuiSettingsField {
|
|
|
42
51
|
hint?: string;
|
|
43
52
|
/** Provider-owned translations for the hint. */
|
|
44
53
|
hintDescriptions?: LocalizedDescriptions;
|
|
54
|
+
/** Optional group id; grouped fields render on that group's subpage. */
|
|
55
|
+
group?: string;
|
|
45
56
|
kind: TuiSettingsFieldKind;
|
|
46
57
|
/** Choices for `kind: 'select'` (ignored otherwise). */
|
|
47
58
|
options?: readonly TuiSettingsFieldOption[];
|
|
@@ -83,6 +94,8 @@ export interface TuiSettingsSection {
|
|
|
83
94
|
title: string;
|
|
84
95
|
/** Provider-owned translations for the title. */
|
|
85
96
|
descriptions?: LocalizedDescriptions;
|
|
97
|
+
/** Optional navigation groups, in display order. */
|
|
98
|
+
groups?: readonly TuiSettingsGroup[];
|
|
86
99
|
/** Editable fields, in display order. */
|
|
87
100
|
fields: readonly TuiSettingsField[];
|
|
88
101
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/settings-sections.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAG3D,iEAAiE;AACjE,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAE3E,MAAM,WAAW,sBAAsB;IACrC,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;CACrC;AAED,oEAAoE;AACpE,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAErB,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,qBAAqB,CAAA;IACxC,IAAI,EAAE,oBAAoB,CAAA;IAC1B,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,sBAAsB,EAAE,CAAA;IAC3C,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;IACxB;;;OAGG;IACH,MAAM,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B;;;;;;OAMG;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,CAAA;CACxD;AAED,2DAA2D;AAC3D,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,EAAE,EAAE,MAAM,CAAA;IACV,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,iDAAiD;IACjD,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,yCAAyC;IACzC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAA;CACpC;AAED,6EAA6E;AAC7E,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI,CAAA;IACjD,IAAI,IAAI,SAAS,kBAAkB,EAAE,CAAA;IACrC,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;CAC5C;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,mBAAmB,EAAE,0BAA0B,CAAA;KAChD;CACF;AAED,eAAO,MAAM,IAAI,8BAA8B,CAAA;AAE/C;;;GAGG;AACH,qBAAa,0BAA2B,SAAQ,OAAO;gBACzC,GAAG,EAAE,OAAO;IAmBxB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,IAAI;IASjD,iDAAiD;IACjD,IAAI,IAAI,SAAS,kBAAkB,EAAE;IAQrC,sDAAsD;IACtD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAQnD;;;OAGG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;CAS5C;
|
|
1
|
+
{"version":3,"file":"settings-sections.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/settings-sections.ts"],"names":[],"mappings":"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"}
|