@xp266/dshtui 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cordis.patch.yml +5 -0
- package/lib/index.mjs +21 -17
- package/package.json +25 -24
- package/src/chat/bridge.ts +12 -11
- package/src/chat/interactions.ts +7 -8
- package/src/chat/session-list.ts +4 -4
- package/src/contract/upstream.ts +1 -1
- package/src/index.tsx +6 -5
- package/src/ui/hooks/use-chat-events.ts +1 -0
package/cordis.patch.yml
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
# session-projection-cache) is inserted by the dsh-base bundle since
|
|
4
4
|
# 0.1.2-rc.1 with the same configuration this file used to carry —
|
|
5
5
|
# re-inserting it here would collide with duplicate loader entry ids.
|
|
6
|
+
# The standard preset's subagent tool enables modelSelectionSettings,
|
|
7
|
+
# which requires this settings service in the host scope (the web bundle
|
|
8
|
+
# mounts the same row for its own roster).
|
|
9
|
+
- id: subagent-model-selection-settings
|
|
10
|
+
name: '@deepseek-ai/dsh-tool-subagent/model-selection-settings'
|
|
6
11
|
- id: workspace
|
|
7
12
|
name: '@deepseek-ai/dsh-workspace'
|
|
8
13
|
- id: agent-presets
|
package/lib/index.mjs
CHANGED
|
@@ -6200,7 +6200,7 @@ function MessageList({ messages, height, width, scrollTop, onScroll, interactive
|
|
|
6200
6200
|
}
|
|
6201
6201
|
//#endregion
|
|
6202
6202
|
//#region src/contract/upstream.ts
|
|
6203
|
-
const UPSTREAM_FLOOR_VERSION = "0.1.
|
|
6203
|
+
const UPSTREAM_FLOOR_VERSION = "0.1.2-rc.1";
|
|
6204
6204
|
const UPSTREAM_CEILING_VERSION = "0.2.0";
|
|
6205
6205
|
const UPSTREAM_FRAMEWORK_MAJORS = {
|
|
6206
6206
|
"@deepseek-ai/cordis": 4,
|
|
@@ -7203,9 +7203,9 @@ async function computeSessionList(ctx) {
|
|
|
7203
7203
|
attached.add(id);
|
|
7204
7204
|
if (session.header.origin === "subagent") continue;
|
|
7205
7205
|
if (archived.has(id)) continue;
|
|
7206
|
-
if (isBlankSession(session.
|
|
7207
|
-
const title = titleService?.get?.(session)?.title ?? firstUserText(session.
|
|
7208
|
-
summaries.push(toSummary(id, title, session.header.cwd, session.header.createdAt, lastPromptAt(session.
|
|
7206
|
+
if (isBlankSession(session.snapshotEvents())) continue;
|
|
7207
|
+
const title = titleService?.get?.(session)?.title ?? firstUserText(session.snapshotEvents());
|
|
7208
|
+
summaries.push(toSummary(id, title, session.header.cwd, session.header.createdAt, lastPromptAt(session.snapshotEvents()), workspacePaths));
|
|
7209
7209
|
}
|
|
7210
7210
|
const persistence = ctx.get("sessionPersistence");
|
|
7211
7211
|
await mergeColdSummaries(ctx, persistence, await listColdHeaders(ctx, persistence, attached), archived, workspacePaths, summaries);
|
|
@@ -9649,12 +9649,12 @@ function registerInteractionChannels(ctx, store) {
|
|
|
9649
9649
|
const offApproval = ctx.on("approval/request", async (req) => {
|
|
9650
9650
|
return store.pushApproval(req.toolName, req.callId, req.reason, req.signal);
|
|
9651
9651
|
});
|
|
9652
|
-
const
|
|
9652
|
+
const offQuestions = ctx.on("user-questions/request", async (request) => {
|
|
9653
9653
|
return store.pushQuestion(request, request.signal);
|
|
9654
|
-
}
|
|
9654
|
+
});
|
|
9655
9655
|
return () => {
|
|
9656
9656
|
offApproval();
|
|
9657
|
-
|
|
9657
|
+
offQuestions();
|
|
9658
9658
|
};
|
|
9659
9659
|
}
|
|
9660
9660
|
//#endregion
|
|
@@ -10173,8 +10173,9 @@ async function createChatBridge(ctx) {
|
|
|
10173
10173
|
};
|
|
10174
10174
|
}
|
|
10175
10175
|
function resolveSessionPreset(session) {
|
|
10176
|
-
|
|
10177
|
-
|
|
10176
|
+
const events = session.snapshotEvents();
|
|
10177
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
10178
|
+
const event = events[index];
|
|
10178
10179
|
if (event?.type === "agent-preset/selected") {
|
|
10179
10180
|
const data = event.data;
|
|
10180
10181
|
if (data?.agentPreset !== void 0) return data.agentPreset;
|
|
@@ -10254,21 +10255,21 @@ async function createChatBridge(ctx) {
|
|
|
10254
10255
|
async function openSession(id) {
|
|
10255
10256
|
const sessionId = SessionId(id);
|
|
10256
10257
|
if (activeAgent.id === sessionId) {
|
|
10257
|
-
for (const event of activeAgent.session.
|
|
10258
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event);
|
|
10258
10259
|
return;
|
|
10259
10260
|
}
|
|
10260
10261
|
const existing = ctx.agents.get(sessionId);
|
|
10261
10262
|
if (existing !== void 0) {
|
|
10262
10263
|
await activateAgent(void 0, existing);
|
|
10263
10264
|
syncCwd();
|
|
10264
|
-
for (const event of activeAgent.session.
|
|
10265
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event);
|
|
10265
10266
|
refreshAgentState();
|
|
10266
10267
|
return;
|
|
10267
10268
|
}
|
|
10268
10269
|
const handle = await resumeAgent(sessionId);
|
|
10269
10270
|
await activateAgent(handle, handle.agent);
|
|
10270
10271
|
syncCwd();
|
|
10271
|
-
for (const event of activeAgent.session.
|
|
10272
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event);
|
|
10272
10273
|
refreshAgentState();
|
|
10273
10274
|
}
|
|
10274
10275
|
function syncCwd() {
|
|
@@ -10321,7 +10322,7 @@ async function createChatBridge(ctx) {
|
|
|
10321
10322
|
if (presets === void 0) throw new Error("agent presets are not configured");
|
|
10322
10323
|
if (currentPreset() === id) return;
|
|
10323
10324
|
const session = activeAgent.session;
|
|
10324
|
-
if (!isBlankSession(session.
|
|
10325
|
+
if (!isBlankSession(session.snapshotEvents())) throw new Error("the preset is fixed once the session has started; use /new to start a new session");
|
|
10325
10326
|
const preset = await presets.recompose(activeAgent.ctx, id);
|
|
10326
10327
|
session.append("agent-preset/selected", { agentPreset: preset.id });
|
|
10327
10328
|
}
|
|
@@ -10496,12 +10497,12 @@ async function createChatBridge(ctx) {
|
|
|
10496
10497
|
currentEffort,
|
|
10497
10498
|
effortName,
|
|
10498
10499
|
selectEffort,
|
|
10499
|
-
permissionMode: () => permission()?.current(activeAgent.session.
|
|
10500
|
+
permissionMode: () => permission()?.current(activeAgent.session.snapshotEvents()) ?? PERMISSION_PRESETS[0],
|
|
10500
10501
|
cyclePermission: () => {
|
|
10501
10502
|
const service = permission();
|
|
10502
10503
|
if (service === void 0) return;
|
|
10503
10504
|
try {
|
|
10504
|
-
const current = service.current(activeAgent.session.
|
|
10505
|
+
const current = service.current(activeAgent.session.snapshotEvents());
|
|
10505
10506
|
const names = service.names.length > 0 ? service.names : PERMISSION_PRESETS;
|
|
10506
10507
|
const next = names[(names.indexOf(current) + 1) % names.length];
|
|
10507
10508
|
service.set(activeAgent.session, next);
|
|
@@ -11303,7 +11304,11 @@ function apply(ctx, config = Config(DEFAULT_CONFIG)) {
|
|
|
11303
11304
|
const restorePerformance = startPerformanceGuard();
|
|
11304
11305
|
const disposeCrashHandlers = installCrashHandlers({ exit: env.crashExit });
|
|
11305
11306
|
const drift = upstreamDriftSummary();
|
|
11306
|
-
if (drift !== void 0)
|
|
11307
|
+
if (drift !== void 0) {
|
|
11308
|
+
const message = `dshtui requires dsh harness packages in ${UPSTREAM_SUPPORTED_RANGE} (found ${drift.kind}: ${drift.versions.join(", ")}); upgrade the dsh CLI with: npm install -g @deepseek-ai/dsh@latest`;
|
|
11309
|
+
error("boot", message);
|
|
11310
|
+
throw new Error(message);
|
|
11311
|
+
}
|
|
11307
11312
|
const capture = createScreenCapture();
|
|
11308
11313
|
let bridge;
|
|
11309
11314
|
let app;
|
|
@@ -11371,7 +11376,6 @@ function apply(ctx, config = Config(DEFAULT_CONFIG)) {
|
|
|
11371
11376
|
};
|
|
11372
11377
|
const themeScope = registerThemeSettings(ctx);
|
|
11373
11378
|
openBootLog();
|
|
11374
|
-
if (drift !== void 0) emitBootLine(`warning: upstream version drift (${drift.kind})`);
|
|
11375
11379
|
emitBootLine("terminal: probing color support");
|
|
11376
11380
|
(async () => {
|
|
11377
11381
|
const probed = await probeColorLevel();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xp266/dshtui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ink-based terminal UI plugin for DeepSeek Harness",
|
|
6
6
|
"engines": {
|
|
@@ -38,17 +38,17 @@
|
|
|
38
38
|
],
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"peerDependencies": {
|
|
41
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
42
|
-
"@deepseek-ai/dsh-agent": "^0.1.
|
|
43
|
-
"@deepseek-ai/dsh-agent-default-model": "^0.1.
|
|
44
|
-
"@deepseek-ai/dsh-agent-loop": "^0.1.
|
|
45
|
-
"@deepseek-ai/dsh-agent-presets": "^0.1.
|
|
46
|
-
"@deepseek-ai/dsh-attachment": "^0.1.
|
|
47
|
-
"@deepseek-ai/dsh-credentials": "^0.1.
|
|
48
|
-
"@deepseek-ai/dsh-llm": "^0.1.
|
|
49
|
-
"@deepseek-ai/dsh-session": "^0.1.
|
|
50
|
-
"@deepseek-ai/dsh-settings": "^0.1.
|
|
51
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
41
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
42
|
+
"@deepseek-ai/dsh-agent": "^0.1.2-rc.1",
|
|
43
|
+
"@deepseek-ai/dsh-agent-default-model": "^0.1.2-rc.1",
|
|
44
|
+
"@deepseek-ai/dsh-agent-loop": "^0.1.2-rc.1",
|
|
45
|
+
"@deepseek-ai/dsh-agent-presets": "^0.1.2-rc.1",
|
|
46
|
+
"@deepseek-ai/dsh-attachment": "^0.1.2-rc.1",
|
|
47
|
+
"@deepseek-ai/dsh-credentials": "^0.1.2-rc.1",
|
|
48
|
+
"@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-session": "^0.1.2-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-settings": "^0.1.2-rc.1",
|
|
51
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
52
52
|
},
|
|
53
53
|
"peerDependenciesMeta": {
|
|
54
54
|
"@deepseek-ai/cordis": {
|
|
@@ -94,23 +94,24 @@
|
|
|
94
94
|
"string-width": "^8.2.2"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
98
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
99
|
-
"@deepseek-ai/dsh-agent-default-model": "0.1.
|
|
100
|
-
"@deepseek-ai/dsh-agent-loop": "0.1.
|
|
101
|
-
"@deepseek-ai/dsh-agent-presets": "0.1.
|
|
102
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
103
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
104
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
105
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
106
|
-
"@deepseek-ai/dsh-settings": "0.1.
|
|
107
|
-
"@deepseek-ai/schemastery": "^3.18.
|
|
97
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
98
|
+
"@deepseek-ai/dsh-agent": "0.1.2-rc.1",
|
|
99
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
|
|
100
|
+
"@deepseek-ai/dsh-agent-loop": "0.1.2-rc.1",
|
|
101
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.2-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-credentials": "0.1.2-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-llm": "0.1.2-rc.1",
|
|
105
|
+
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
106
|
+
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
107
|
+
"@deepseek-ai/schemastery": "^3.18.2",
|
|
108
108
|
"@types/node": "^24.0.0",
|
|
109
109
|
"@types/prismjs": "^1.26.6",
|
|
110
110
|
"@types/react": "^19.2.0",
|
|
111
111
|
"tsdown": "^0.22.14",
|
|
112
112
|
"tsx": "^4.0.0",
|
|
113
|
-
"typescript": "^5.9.0"
|
|
113
|
+
"typescript": "^5.9.0",
|
|
114
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.2-rc.1"
|
|
114
115
|
},
|
|
115
116
|
"dsh": {
|
|
116
117
|
"bundle": {
|
package/src/chat/bridge.ts
CHANGED
|
@@ -136,7 +136,7 @@ async function sendContent(
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
interface PresetSessionLike {
|
|
139
|
-
|
|
139
|
+
snapshotEvents(): ReadonlyArray<{ type?: string; data?: unknown }>
|
|
140
140
|
header?: { agentPreset?: string }
|
|
141
141
|
}
|
|
142
142
|
|
|
@@ -672,8 +672,9 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
672
672
|
// creation-time header value, matching the upstream semantics on every
|
|
673
673
|
// host version the peer range admits.
|
|
674
674
|
function resolveSessionPreset(session: PresetSessionLike): string | undefined {
|
|
675
|
-
|
|
676
|
-
|
|
675
|
+
const events = session.snapshotEvents()
|
|
676
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
677
|
+
const event = events[index]
|
|
677
678
|
if (event?.type === 'agent-preset/selected') {
|
|
678
679
|
const data = event.data as { agentPreset?: string } | undefined
|
|
679
680
|
if (data?.agentPreset !== undefined) return data.agentPreset
|
|
@@ -720,7 +721,7 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
720
721
|
const setup = async (agentCtx: Context) => {
|
|
721
722
|
installSelection(agentCtx)
|
|
722
723
|
const session = agentCtx.agent?.session
|
|
723
|
-
const resolved = session === undefined ? undefined : resolveSessionPreset(session
|
|
724
|
+
const resolved = session === undefined ? undefined : resolveSessionPreset(session)
|
|
724
725
|
await presets?.mount(agentCtx, resolved)
|
|
725
726
|
}
|
|
726
727
|
const spawnResumedAgent = async (snapshot: { session: { cwd?: string }; events: SessionEvent[] }): Promise<AgentHandle> => {
|
|
@@ -761,21 +762,21 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
761
762
|
async function openSession(id: string): Promise<void> {
|
|
762
763
|
const sessionId = SessionId(id)
|
|
763
764
|
if (activeAgent.id === sessionId) {
|
|
764
|
-
for (const event of activeAgent.session.
|
|
765
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event)
|
|
765
766
|
return
|
|
766
767
|
}
|
|
767
768
|
const existing = ctx.agents.get(sessionId)
|
|
768
769
|
if (existing !== undefined) {
|
|
769
770
|
await activateAgent(undefined, existing)
|
|
770
771
|
syncCwd()
|
|
771
|
-
for (const event of activeAgent.session.
|
|
772
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event)
|
|
772
773
|
refreshAgentState()
|
|
773
774
|
return
|
|
774
775
|
}
|
|
775
776
|
const handle = await resumeAgent(sessionId)
|
|
776
777
|
await activateAgent(handle, handle.agent)
|
|
777
778
|
syncCwd()
|
|
778
|
-
for (const event of activeAgent.session.
|
|
779
|
+
for (const event of activeAgent.session.snapshotEvents()) emit(event)
|
|
779
780
|
refreshAgentState()
|
|
780
781
|
}
|
|
781
782
|
|
|
@@ -828,7 +829,7 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
828
829
|
}
|
|
829
830
|
|
|
830
831
|
function currentPreset(): string {
|
|
831
|
-
const resolved = resolveSessionPreset(activeAgent.session
|
|
832
|
+
const resolved = resolveSessionPreset(activeAgent.session)
|
|
832
833
|
return resolved ?? presets?.defaultId ?? 'standard'
|
|
833
834
|
}
|
|
834
835
|
|
|
@@ -836,7 +837,7 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
836
837
|
if (presets === undefined) throw new Error('agent presets are not configured')
|
|
837
838
|
if (currentPreset() === id) return
|
|
838
839
|
const session = activeAgent.session
|
|
839
|
-
if (!isBlankSession(session.
|
|
840
|
+
if (!isBlankSession(session.snapshotEvents())) {
|
|
840
841
|
throw new Error('the preset is fixed once the session has started; use /new to start a new session')
|
|
841
842
|
}
|
|
842
843
|
const preset = await presets.recompose(activeAgent.ctx, id)
|
|
@@ -1039,12 +1040,12 @@ export async function createChatBridge(ctx: Context): Promise<ChatBridge> {
|
|
|
1039
1040
|
currentEffort,
|
|
1040
1041
|
effortName,
|
|
1041
1042
|
selectEffort,
|
|
1042
|
-
permissionMode: () => permission()?.current(activeAgent.session.
|
|
1043
|
+
permissionMode: () => permission()?.current(activeAgent.session.snapshotEvents()) ?? PERMISSION_PRESETS[0],
|
|
1043
1044
|
cyclePermission: () => {
|
|
1044
1045
|
const service = permission()
|
|
1045
1046
|
if (service === undefined) return
|
|
1046
1047
|
try {
|
|
1047
|
-
const current = service.current(activeAgent.session.
|
|
1048
|
+
const current = service.current(activeAgent.session.snapshotEvents())
|
|
1048
1049
|
const names = service.names.length > 0 ? service.names : PERMISSION_PRESETS
|
|
1049
1050
|
const index = names.indexOf(current)
|
|
1050
1051
|
const next = names[(index + 1) % names.length]
|
package/src/chat/interactions.ts
CHANGED
|
@@ -308,22 +308,21 @@ type ApprovalRequestLike = {
|
|
|
308
308
|
|
|
309
309
|
type CtxLike = {
|
|
310
310
|
on(event: 'approval/request', handler: (req: ApprovalRequestLike) => Promise<ApprovalOutcome>): () => void
|
|
311
|
-
|
|
312
|
-
registerProvider(provider: { ask(request: AskUserQuestionRequestLike): Promise<AskUserQuestionAnswerLike> }): () => void
|
|
313
|
-
} | undefined
|
|
311
|
+
on(event: 'user-questions/request', handler: (req: AskUserQuestionRequestLike) => Promise<AskUserQuestionAnswerLike>): () => void
|
|
314
312
|
}
|
|
315
313
|
|
|
316
314
|
export function registerInteractionChannels(ctx: CtxLike, store: InteractionStore): () => void {
|
|
317
315
|
const offApproval = ctx.on('approval/request', async req => {
|
|
318
316
|
return store.pushApproval(req.toolName, req.callId, req.reason, req.signal)
|
|
319
317
|
})
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
318
|
+
// The 0.1.2 user-questions service routes asks through the scoped
|
|
319
|
+
// `user-questions/request` waterfall; answering without calling `next`
|
|
320
|
+
// claims the request for this terminal.
|
|
321
|
+
const offQuestions = ctx.on('user-questions/request', async request => {
|
|
322
|
+
return store.pushQuestion(request, request.signal)
|
|
324
323
|
})
|
|
325
324
|
return () => {
|
|
326
325
|
offApproval()
|
|
327
|
-
|
|
326
|
+
offQuestions()
|
|
328
327
|
}
|
|
329
328
|
}
|
package/src/chat/session-list.ts
CHANGED
|
@@ -32,16 +32,16 @@ export async function computeSessionList(ctx: Context): Promise<SessionSummary[]
|
|
|
32
32
|
const summaries: SessionSummary[] = []
|
|
33
33
|
const attached = new Set<string>()
|
|
34
34
|
const titleService = ctx.get('sessionTitle') as
|
|
35
|
-
| { get?(session: { id: string;
|
|
35
|
+
| { get?(session: { id: string; snapshotEvents(): readonly SessionEvent[] }): { title?: string } | undefined }
|
|
36
36
|
| undefined
|
|
37
37
|
for (const session of ctx.sessions.list()) {
|
|
38
38
|
const id = String(session.id)
|
|
39
39
|
attached.add(id)
|
|
40
40
|
if (session.header.origin === 'subagent') continue
|
|
41
41
|
if (archived.has(id)) continue
|
|
42
|
-
if (isBlankSession(session.
|
|
43
|
-
const title = titleService?.get?.(session)?.title ?? firstUserText(session.
|
|
44
|
-
summaries.push(toSummary(id, title, session.header.cwd, session.header.createdAt, lastPromptAt(session.
|
|
42
|
+
if (isBlankSession(session.snapshotEvents())) continue
|
|
43
|
+
const title = titleService?.get?.(session)?.title ?? firstUserText(session.snapshotEvents())
|
|
44
|
+
summaries.push(toSummary(id, title, session.header.cwd, session.header.createdAt, lastPromptAt(session.snapshotEvents()), workspacePaths))
|
|
45
45
|
}
|
|
46
46
|
const persistence = ctx.get('sessionPersistence') as PersistenceLike | undefined
|
|
47
47
|
const cold = await listColdHeaders(ctx, persistence, attached)
|
package/src/contract/upstream.ts
CHANGED
package/src/index.tsx
CHANGED
|
@@ -23,7 +23,7 @@ import { warmRenderPipeline } from './ui/message/warmup.ts'
|
|
|
23
23
|
import { createTuiExtensionPoint, exposeRuntimeFaces } from './ui/extension-point.ts'
|
|
24
24
|
import { registerBuiltinToolViews } from './chat/builtin-tool-views.ts'
|
|
25
25
|
import { closeBootLog, emitBootLine, openBootLog } from './boot-log.ts'
|
|
26
|
-
import { configureLogs, error as logError, installCrashHandlers
|
|
26
|
+
import { configureLogs, error, error as logError, installCrashHandlers } from './log.ts'
|
|
27
27
|
import { env } from './env.ts'
|
|
28
28
|
import { upstreamDriftSummary, UPSTREAM_SUPPORTED_RANGE } from './contract/upstream.ts'
|
|
29
29
|
|
|
@@ -67,9 +67,13 @@ export function apply(ctx: Context, config: Config = Config(DEFAULT_CONFIG)) {
|
|
|
67
67
|
configureLogs({ stderr: env.debug, file: env.logFile, dir: env.logDir, level: env.logLevel, maxFileBytes: env.logMaxBytes })
|
|
68
68
|
const restorePerformance = startPerformanceGuard()
|
|
69
69
|
const disposeCrashHandlers = installCrashHandlers({ exit: env.crashExit })
|
|
70
|
+
// Fail before any surface mounts: an out-of-range host breaks the bridge
|
|
71
|
+
// in ways that render as a dead interface instead of an actionable error.
|
|
70
72
|
const drift = upstreamDriftSummary()
|
|
71
73
|
if (drift !== undefined) {
|
|
72
|
-
|
|
74
|
+
const message = `dshtui requires dsh harness packages in ${UPSTREAM_SUPPORTED_RANGE} (found ${drift.kind}: ${drift.versions.join(', ')}); upgrade the dsh CLI with: npm install -g @deepseek-ai/dsh@latest`
|
|
75
|
+
error('boot', message)
|
|
76
|
+
throw new Error(message)
|
|
73
77
|
}
|
|
74
78
|
const capture = createScreenCapture()
|
|
75
79
|
let bridge: ChatBridge | undefined
|
|
@@ -138,9 +142,6 @@ export function apply(ctx: Context, config: Config = Config(DEFAULT_CONFIG)) {
|
|
|
138
142
|
}
|
|
139
143
|
const themeScope = registerThemeSettings(ctx)
|
|
140
144
|
openBootLog()
|
|
141
|
-
if (drift !== undefined) {
|
|
142
|
-
emitBootLine(`warning: upstream version drift (${drift.kind})`)
|
|
143
|
-
}
|
|
144
145
|
emitBootLine('terminal: probing color support')
|
|
145
146
|
void (async () => {
|
|
146
147
|
const probed = await probeColorLevel()
|