@toddzheng024/dscode-bundle 0.7.26 → 0.7.28
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 +1 -1
- package/THIRD_PARTY_NOTICES.md +10 -10
- package/bootstrap.mjs +1 -1
- package/cordis.patch.yml +418 -45
- package/package.json +279 -245
- package/plugins/auto-review/index.mjs +8 -5
- package/plugins/code-review/index.mjs +1 -1
- package/plugins/computer-use/index.mjs +37 -0
- package/plugins/cordis-config/plain.mjs +31 -0
- package/plugins/exec/cli.mjs +1 -1
- package/plugins/grok/index.mjs +28 -24
- package/plugins/memory/index.mjs +1 -1
- package/plugins/message-source/kind.mjs +20 -0
- package/plugins/openrouter/adapter.mjs +29 -13
- package/plugins/openrouter/index.mjs +31 -28
- package/plugins/session-bridge/communication.mjs +6 -3
- package/plugins/session-bridge/server.mjs +3 -2
- package/plugins/session-bridge/tasks.mjs +3 -1
- package/plugins/session-cards/index.mjs +1 -1
- package/plugins/time-marks/index.mjs +3 -2
- package/plugins/time-marks/marks.mjs +6 -5
- package/plugins/triggers/config.mjs +1 -1
- package/plugins/triggers/tools.mjs +1 -1
- package/plugins/tui-tools/doctor.mjs +1 -1
- package/plugins/tui-tools/index.mjs +16 -4
- package/plugins/ultra/policy.mjs +16 -0
- package/vendor/bash/index.js +455 -186
- package/vendor/bash/types/background.d.ts +38 -7
- package/vendor/bash/types/index.d.ts +20 -4
- package/vendor/bash/types/render.d.ts +28 -9
- package/vendor/command-goal/index.js +3 -1
- package/vendor/deepseek/index.js +1378 -1246
- package/vendor/deepseek/types/adapter.d.ts +16 -155
- package/vendor/deepseek/types/config.d.ts +127 -0
- package/vendor/deepseek/types/defaults.d.ts +24 -0
- package/vendor/deepseek/types/file-store.d.ts +5 -3
- package/vendor/deepseek/types/files-api.d.ts +12 -9
- package/vendor/deepseek/types/image-tokens.d.ts +24 -9
- package/vendor/deepseek/types/images.d.ts +35 -0
- package/vendor/deepseek/types/index.d.ts +10 -94
- package/vendor/deepseek/types/messages-api.d.ts +10 -0
- package/vendor/deepseek/types/model-info.d.ts +16 -0
- package/vendor/deepseek/types/models.d.ts +4 -0
- package/vendor/deepseek/types/replay.d.ts +27 -0
- package/vendor/deepseek/types/request-extensions.d.ts +16 -0
- package/vendor/deepseek/types/request-files.d.ts +49 -0
- package/vendor/deepseek/types/request-pricing.d.ts +32 -20
- package/vendor/deepseek/types/serialize.d.ts +17 -82
- package/vendor/deepseek/types/sse.d.ts +6 -22
- package/vendor/deepseek/types/translate.d.ts +13 -36
- package/vendor/deepseek/types/transport.d.ts +15 -0
- package/vendor/deepseek/types/types.d.ts +106 -167
- package/vendor/deepseek/types/wire-types.d.ts +62 -0
- package/vendor/persistent/index.js +9 -3
- package/vendor/subagent/index.js +11 -8
- package/vendor/subagent/model-selection-settings.js +12 -38
- package/vendor/subagent/types/index.d.ts +4 -3
- package/vendor/subagent/types/model-selection-settings.d.ts +12 -10
- package/vendor/subagent-core/index.js +401 -264
- package/vendor/subagent-core/typert.host.js +103 -113
- package/vendor/subagent-core/typert.remote-client.d.ts +1 -3
- package/vendor/subagent-core/typert.remote-client.js +23 -69
- package/vendor/subagent-core/types/archive-admission.d.ts +16 -0
- package/vendor/subagent-core/types/archive-admission.js +151 -0
- package/vendor/subagent-core/types/assistant-output.d.ts +2 -2
- package/vendor/subagent-core/types/catalog.d.ts +17 -10
- package/vendor/subagent-core/types/catalog.js +12 -6
- package/vendor/subagent-core/types/child-agent.d.ts +8 -5
- package/vendor/subagent-core/types/child-agent.js +11 -5
- package/vendor/subagent-core/types/continuation-activation.d.ts +17 -1
- package/vendor/subagent-core/types/continuation-activation.js +41 -4
- package/vendor/subagent-core/types/continuation-messages.d.ts +1 -1
- package/vendor/subagent-core/types/continuation-messages.js +7 -3
- package/vendor/subagent-core/types/continuation.d.ts +1 -1
- package/vendor/subagent-core/types/continuation.js +2 -2
- package/vendor/subagent-core/types/control-types.d.ts +29 -36
- package/vendor/subagent-core/types/control-types.js +2 -3
- package/vendor/subagent-core/types/control.d.ts +2 -28
- package/vendor/subagent-core/types/control.js +3 -40
- package/vendor/subagent-core/types/index.d.ts +45 -41
- package/vendor/subagent-core/types/index.js +46 -82
- package/vendor/subagent-core/types/internal.d.ts +2 -2
- package/vendor/subagent-core/types/internal.js +2 -2
- package/vendor/subagent-core/types/lifecycle.d.ts +1 -1
- package/vendor/subagent-core/types/lifecycle.js +5 -3
- package/vendor/subagent-core/types/list-children.d.ts +15 -32
- package/vendor/subagent-core/types/list-children.js +45 -49
- package/vendor/subagent-core/types/out-of-process.d.ts +1 -1
- package/vendor/subagent-core/types/projection-types.d.ts +9 -1
- package/vendor/subagent-core/types/projection.d.ts +5 -0
- package/vendor/subagent-core/types/projection.js +10 -4
- package/vendor/subagent-core/types/run-settlement.js +1 -1
- package/vendor/subagent-core/types/types.d.ts +2 -2
- package/vendor/terminal/index.js +94 -30
- package/vendor/tui/lib/index.mjs +2 -1
- package/vendor/tui/lib/kernel-panels.mjs +1 -1
- package/vendor/tui/lib/render/projection.mjs +50 -36
- package/presets/dscode/agent.cordis.yml +0 -321
- package/presets/dscode/preset.yml +0 -3
|
@@ -14,15 +14,18 @@ const activeIntervalSchema = z.object({
|
|
|
14
14
|
const projectionSchema = z.object({
|
|
15
15
|
settledMs: z.number().int().nonnegative(),
|
|
16
16
|
active: activeIntervalSchema.optional(),
|
|
17
|
-
|
|
17
|
+
lastTurnCompleted: z.boolean().optional(),
|
|
18
|
+
}).strict().transform(({ settledMs, active, lastTurnCompleted }) => ({
|
|
18
19
|
settledMs,
|
|
19
20
|
...active === undefined ? {} : { active },
|
|
21
|
+
...lastTurnCompleted === undefined ? {} : { lastTurnCompleted },
|
|
20
22
|
}));
|
|
21
23
|
const timingStateSchema = z.object({
|
|
22
24
|
settledMs: z.number().int().nonnegative(),
|
|
23
25
|
active: activeIntervalSchema.optional(),
|
|
24
26
|
pendingTurnStart: z.number().int().nonnegative().optional(),
|
|
25
27
|
descriptorSeen: z.boolean(),
|
|
28
|
+
lastTurnCompleted: z.boolean().optional(),
|
|
26
29
|
}).strict();
|
|
27
30
|
/**
|
|
28
31
|
* Fold turn boundaries around the child's own durable descriptor.
|
|
@@ -38,9 +41,10 @@ export const subagentTimingProjectionDefinition = {
|
|
|
38
41
|
init: () => ({ descriptorSeen: false, settledMs: 0 }),
|
|
39
42
|
apply: (state, event) => {
|
|
40
43
|
if (event.type === 'turn/start') {
|
|
44
|
+
const { lastTurnCompleted: _closed, ...openState } = state;
|
|
41
45
|
return state.descriptorSeen
|
|
42
|
-
? { ...
|
|
43
|
-
: { ...
|
|
46
|
+
? { ...openState, active: { since: event.time, through: event.time } }
|
|
47
|
+
: { ...openState, pendingTurnStart: event.time };
|
|
44
48
|
}
|
|
45
49
|
if (event.type === 'subagent/descriptor') {
|
|
46
50
|
const activeSince = state.active?.since ?? state.pendingTurnStart;
|
|
@@ -65,6 +69,7 @@ export const subagentTimingProjectionDefinition = {
|
|
|
65
69
|
return {
|
|
66
70
|
...rest,
|
|
67
71
|
settledMs: state.settledMs + Math.max(0, event.time - active.since),
|
|
72
|
+
lastTurnCompleted: event.data.reason.kind === 'completed',
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
75
|
if (state.active === undefined)
|
|
@@ -76,9 +81,10 @@ export const subagentTimingProjectionDefinition = {
|
|
|
76
81
|
view: state => ({
|
|
77
82
|
settledMs: state.settledMs,
|
|
78
83
|
...(state.active === undefined ? {} : { active: state.active }),
|
|
84
|
+
...(state.lastTurnCompleted === undefined ? {} : { lastTurnCompleted: state.lastTurnCompleted }),
|
|
79
85
|
}),
|
|
80
86
|
},
|
|
81
|
-
stateVersion:
|
|
87
|
+
stateVersion: 3,
|
|
82
88
|
};
|
|
83
89
|
// The cast bridges only the optional-label arm: Zod's optional output
|
|
84
90
|
// includes explicit `undefined`, which exactOptionalPropertyTypes excludes
|
|
@@ -30,7 +30,7 @@ function failureDetail(result) {
|
|
|
30
30
|
function runOutcome(result) {
|
|
31
31
|
switch (result.stopReason) {
|
|
32
32
|
case 'completed':
|
|
33
|
-
return { status: 'completed',
|
|
33
|
+
return { status: 'completed', result: finalText(result.output) };
|
|
34
34
|
case 'aborted':
|
|
35
35
|
return result.diagnostic === undefined
|
|
36
36
|
? { status: 'killed' }
|
|
@@ -106,7 +106,7 @@ export interface SubagentRunEndInfo {
|
|
|
106
106
|
* {@link SubagentResult.output}; absent on infrastructure rejection or when
|
|
107
107
|
* the child produced none.
|
|
108
108
|
*/
|
|
109
|
-
readonly lastAssistantMessage?: ContentBlock[];
|
|
109
|
+
readonly lastAssistantMessage?: readonly ContentBlock[];
|
|
110
110
|
}
|
|
111
111
|
/**
|
|
112
112
|
* Which START-TIME features a provider supports. Checked by the service before delegating to
|
|
@@ -260,7 +260,7 @@ export interface SubagentResult {
|
|
|
260
260
|
* are skipped. Without a non-empty message, the output is its accumulated
|
|
261
261
|
* assistant text stream, or `[]` when the child produced neither.
|
|
262
262
|
*/
|
|
263
|
-
readonly output: ContentBlock[];
|
|
263
|
+
readonly output: readonly ContentBlock[];
|
|
264
264
|
/**
|
|
265
265
|
* The structured result after a requested `outputSchema` was successfully
|
|
266
266
|
* satisfied. Requesting a schema does not guarantee presence: a provider can
|
package/vendor/terminal/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// dscode-shell-capture-v1
|
|
2
2
|
// dscode-no-history-expansion-v1
|
|
3
|
-
import { createRequire } from "node:module";
|
|
4
3
|
import { TerminalBackendCleanupError, TerminalError } from "@deepseek-ai/dsh-terminal";
|
|
5
4
|
import { ENCODING_PREAMBLE, resolvePwshPath } from "@deepseek-ai/dsh-pwsh-local";
|
|
6
5
|
import z from "@deepseek-ai/schemastery";
|
|
7
6
|
import { Buffer } from "node:buffer";
|
|
7
|
+
import { createLazyRequire } from "@deepseek-ai/dsh-lazy-require";
|
|
8
8
|
//#region lib/types/config.js
|
|
9
9
|
/** Validated configuration for the local PTY backend. */
|
|
10
10
|
/** Bash dialect default executable. */
|
|
@@ -235,7 +235,7 @@ function normalizeTerminalText(text) {
|
|
|
235
235
|
//#endregion
|
|
236
236
|
//#region lib/types/session.js
|
|
237
237
|
/** Persistent PTY session with bounded output, readiness, and terminal-protocol replies. */
|
|
238
|
-
const
|
|
238
|
+
const requireHeadless = createLazyRequire("@xterm/headless", import.meta.url);
|
|
239
239
|
function utf8Tail(text, maxBytes) {
|
|
240
240
|
if (Buffer.byteLength(text) <= maxBytes) return {
|
|
241
241
|
text,
|
|
@@ -255,34 +255,84 @@ function utf8Tail(text, maxBytes) {
|
|
|
255
255
|
truncated: true
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
|
+
const COALESCED_CHUNK_UNITS = 4096;
|
|
259
|
+
/** Retention work is amortized over appended text; reads assemble the retained chunks. */
|
|
258
260
|
const CAPTURE_MAX_BYTES = 4194304;
|
|
259
261
|
var BoundedTextBuffer = class {
|
|
260
262
|
maxBytes;
|
|
261
263
|
maxLines;
|
|
262
|
-
|
|
264
|
+
head;
|
|
265
|
+
tail;
|
|
266
|
+
bytes = 0;
|
|
267
|
+
newlines = 0;
|
|
268
|
+
lastCodeUnit = 0;
|
|
263
269
|
dropped = false;
|
|
264
270
|
constructor(maxBytes, maxLines) {
|
|
265
271
|
this.maxBytes = maxBytes;
|
|
266
272
|
this.maxLines = maxLines;
|
|
267
273
|
}
|
|
274
|
+
get truncated() {
|
|
275
|
+
return this.dropped;
|
|
276
|
+
}
|
|
277
|
+
get isEmpty() {
|
|
278
|
+
return this.head === void 0;
|
|
279
|
+
}
|
|
268
280
|
append(text) {
|
|
269
281
|
if (text.length === 0) return;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
282
|
+
text = Buffer.from(text, "utf16le").toString("utf16le");
|
|
283
|
+
this.bytes += Buffer.byteLength(text);
|
|
284
|
+
const tail = this.tail;
|
|
285
|
+
if (tail !== void 0) {
|
|
286
|
+
const last = this.lastCodeUnit;
|
|
287
|
+
const first = text.charCodeAt(0);
|
|
288
|
+
if (last >= 55296 && last <= 56319 && first >= 56320 && first <= 57343) this.bytes -= 2;
|
|
289
|
+
}
|
|
290
|
+
for (let index = text.indexOf("\n"); index !== -1; index = text.indexOf("\n", index + 1)) this.newlines += 1;
|
|
291
|
+
this.lastCodeUnit = text.charCodeAt(text.length - 1);
|
|
292
|
+
if (tail !== void 0 && tail !== this.head && tail.text.length + text.length <= COALESCED_CHUNK_UNITS) tail.text += text;
|
|
293
|
+
else {
|
|
294
|
+
if (tail !== void 0 && tail.text.length <= COALESCED_CHUNK_UNITS) tail.text = Buffer.from(tail.text, "utf16le").toString("utf16le");
|
|
295
|
+
const chunk = {
|
|
296
|
+
text,
|
|
297
|
+
start: 0,
|
|
298
|
+
next: void 0
|
|
299
|
+
};
|
|
300
|
+
if (tail === void 0) this.head = chunk;
|
|
301
|
+
else tail.next = chunk;
|
|
302
|
+
this.tail = chunk;
|
|
303
|
+
}
|
|
304
|
+
while (this.head !== void 0 && (this.bytes > this.maxBytes || this.maxLines !== void 0 && this.newlines >= this.maxLines)) {
|
|
305
|
+
const head = this.head;
|
|
306
|
+
const first = head.text.charCodeAt(head.start);
|
|
307
|
+
const second = head.start + 1 < head.text.length ? head.text.charCodeAt(head.start + 1) : head.next?.text.charCodeAt(0);
|
|
308
|
+
const paired = first >= 55296 && first <= 56319 && second !== void 0 && second >= 56320 && second <= 57343;
|
|
309
|
+
this.bytes -= paired ? 4 : first < 128 ? 1 : first < 2048 ? 2 : 3;
|
|
310
|
+
if (first === 10) this.newlines -= 1;
|
|
311
|
+
this.advance(paired ? 2 : 1);
|
|
312
|
+
this.dropped = true;
|
|
313
|
+
}
|
|
314
|
+
const head = this.head;
|
|
315
|
+
if (head !== void 0 && head.start >= head.text.length / 2) {
|
|
316
|
+
head.text = Buffer.from(head.text.slice(head.start), "utf16le").toString("utf16le");
|
|
317
|
+
head.start = 0;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
advance(units) {
|
|
321
|
+
while (units > 0 && this.head !== void 0) {
|
|
322
|
+
const head = this.head;
|
|
323
|
+
const count = Math.min(units, head.text.length - head.start);
|
|
324
|
+
head.start += count;
|
|
325
|
+
units -= count;
|
|
326
|
+
if (head.start === head.text.length) this.head = head.next;
|
|
277
327
|
}
|
|
278
|
-
|
|
279
|
-
this.value = tail.text;
|
|
280
|
-
this.dropped ||= tail.truncated;
|
|
328
|
+
if (this.head === void 0) this.tail = void 0;
|
|
281
329
|
}
|
|
282
330
|
consume() {
|
|
283
|
-
const delta = this.
|
|
284
|
-
|
|
285
|
-
this.
|
|
331
|
+
const { text: delta, truncated } = this.snapshot();
|
|
332
|
+
this.head = void 0;
|
|
333
|
+
this.tail = void 0;
|
|
334
|
+
this.bytes = 0;
|
|
335
|
+
this.newlines = 0;
|
|
286
336
|
this.dropped = false;
|
|
287
337
|
return {
|
|
288
338
|
delta,
|
|
@@ -290,8 +340,10 @@ var BoundedTextBuffer = class {
|
|
|
290
340
|
};
|
|
291
341
|
}
|
|
292
342
|
snapshot() {
|
|
343
|
+
const chunks = [];
|
|
344
|
+
for (let chunk = this.head; chunk !== void 0; chunk = chunk.next) chunks.push(chunk.text.slice(chunk.start));
|
|
293
345
|
return {
|
|
294
|
-
text:
|
|
346
|
+
text: chunks.join(""),
|
|
295
347
|
truncated: this.dropped
|
|
296
348
|
};
|
|
297
349
|
}
|
|
@@ -402,6 +454,7 @@ var LocalPtySession = class {
|
|
|
402
454
|
this.terminal = terminal;
|
|
403
455
|
this.config = config;
|
|
404
456
|
this.pid = terminal.pid;
|
|
457
|
+
const { Terminal: HeadlessTerminal } = requireHeadless();
|
|
405
458
|
this.emulator = new HeadlessTerminal({
|
|
406
459
|
cols: config.cols,
|
|
407
460
|
rows: config.rows,
|
|
@@ -661,7 +714,7 @@ var LocalPtySession = class {
|
|
|
661
714
|
return;
|
|
662
715
|
}
|
|
663
716
|
const elapsed = Date.now() - operation.startedAt;
|
|
664
|
-
const startupHasOutput = !this.initializing || this.scrollback.
|
|
717
|
+
const startupHasOutput = !this.initializing || !this.scrollback.isEmpty;
|
|
665
718
|
const acceptsStdinWait = startupHasOutput && foreground !== void 0 && operation.acceptsStdinWait(foreground.processGroupId, foreground.inputWaiting);
|
|
666
719
|
if (elapsed >= this.config.exactProbeAfterMs && acceptsStdinWait) {
|
|
667
720
|
this.settleActive("stdin_read");
|
|
@@ -766,7 +819,7 @@ var LocalPtySession = class {
|
|
|
766
819
|
settleActive(waitReason, retainOwnership = false) {
|
|
767
820
|
const operation = this.active;
|
|
768
821
|
if (operation === void 0) return;
|
|
769
|
-
const scrollbackTruncated = this.scrollback.
|
|
822
|
+
const scrollbackTruncated = this.scrollback.truncated;
|
|
770
823
|
if (retainOwnership) {
|
|
771
824
|
this.stopPolling();
|
|
772
825
|
this.activeAbort?.();
|
|
@@ -905,15 +958,15 @@ function childEnvironment(spec, dialect) {
|
|
|
905
958
|
* input are unreliable under PSReadLine.
|
|
906
959
|
*/
|
|
907
960
|
const PWSH_PROMPT_SETUP = "function prompt { [Console]::Write([char]27 + ']133;D;' + [int]$LASTEXITCODE + [char]7); 'dsh> ' }";
|
|
908
|
-
function spawnArgv(ctx, config, policy) {
|
|
961
|
+
async function spawnArgv(ctx, config, policy, signal) {
|
|
909
962
|
const argv = [config.shellPath, ...config.shellArgs];
|
|
910
963
|
if (policy.mode === "danger-full-access") return argv;
|
|
911
964
|
const sandbox = ctx.get("sandbox");
|
|
912
965
|
if (sandbox === void 0) throw new Error(`terminal-bash: sandbox mode "${policy.mode}" requires a ctx.sandbox provider in the execution world`);
|
|
913
|
-
return sandbox.confine(argv, {
|
|
966
|
+
return (await sandbox.confine(argv, {
|
|
914
967
|
...policy,
|
|
915
968
|
mode: policy.mode
|
|
916
|
-
}).argv;
|
|
969
|
+
}, signal)).argv;
|
|
917
970
|
}
|
|
918
971
|
async function startupSession(session, dialect, timeoutMs, signal) {
|
|
919
972
|
let startupOperation;
|
|
@@ -965,6 +1018,15 @@ async function startupSession(session, dialect, timeoutMs, signal) {
|
|
|
965
1018
|
if (signal !== void 0 && onAbort !== void 0) signal.removeEventListener("abort", onAbort);
|
|
966
1019
|
}
|
|
967
1020
|
}
|
|
1021
|
+
/** Reject a failed startup only after its unpublished resources reach quiescence. */
|
|
1022
|
+
async function rejectAfterStartupCleanup(error, cleanup) {
|
|
1023
|
+
try {
|
|
1024
|
+
await cleanup();
|
|
1025
|
+
} catch (cleanupError) {
|
|
1026
|
+
throw new TerminalBackendCleanupError(error, cleanupError);
|
|
1027
|
+
}
|
|
1028
|
+
throw error;
|
|
1029
|
+
}
|
|
968
1030
|
/** Local shell backend registered under the configured type. */
|
|
969
1031
|
var BashTerminalBackend = class {
|
|
970
1032
|
ctx;
|
|
@@ -983,7 +1045,8 @@ var BashTerminalBackend = class {
|
|
|
983
1045
|
spec.signal?.throwIfAborted();
|
|
984
1046
|
ensureSandboxModeFence(this.ctx, spec.owner);
|
|
985
1047
|
const policy = this.ctx.sandboxPolicy.resolve({ session: spec.owner.session });
|
|
986
|
-
const argv = spawnArgv(this.ctx, this.config, policy);
|
|
1048
|
+
const argv = await spawnArgv(this.ctx, this.config, policy, spec.signal);
|
|
1049
|
+
spec.signal?.throwIfAborted();
|
|
987
1050
|
if (argv[0] === void 0) throw new Error("terminal-bash: sandbox returned empty argv");
|
|
988
1051
|
const terminal = await this.spawnTerminal({
|
|
989
1052
|
argv,
|
|
@@ -991,20 +1054,21 @@ var BashTerminalBackend = class {
|
|
|
991
1054
|
env: childEnvironment(spec, this.config.shellDialect),
|
|
992
1055
|
rows: this.config.rows,
|
|
993
1056
|
cols: this.config.cols,
|
|
1057
|
+
terminalType: "dumb",
|
|
994
1058
|
graceMs: this.config.disposeGraceMs,
|
|
995
1059
|
signal: spec.signal
|
|
996
1060
|
});
|
|
997
|
-
|
|
1061
|
+
let session;
|
|
1062
|
+
try {
|
|
1063
|
+
session = this.createSession(terminal, this.config);
|
|
1064
|
+
} catch (error) {
|
|
1065
|
+
return rejectAfterStartupCleanup(error, () => terminal.terminate());
|
|
1066
|
+
}
|
|
998
1067
|
try {
|
|
999
1068
|
await startupSession(session, this.config.shellDialect, this.config.timeoutMs, spec.signal);
|
|
1000
1069
|
return session;
|
|
1001
1070
|
} catch (error) {
|
|
1002
|
-
|
|
1003
|
-
await session.close("PTY startup failed");
|
|
1004
|
-
} catch (closeError) {
|
|
1005
|
-
throw new TerminalBackendCleanupError(error, closeError);
|
|
1006
|
-
}
|
|
1007
|
-
throw error;
|
|
1071
|
+
return rejectAfterStartupCleanup(error, () => session.close("PTY startup failed"));
|
|
1008
1072
|
}
|
|
1009
1073
|
}
|
|
1010
1074
|
};
|
package/vendor/tui/lib/index.mjs
CHANGED
|
@@ -96,7 +96,8 @@ function listJobs(ctx, caller) {
|
|
|
96
96
|
if (jobs === undefined)
|
|
97
97
|
return [];
|
|
98
98
|
try {
|
|
99
|
-
|
|
99
|
+
// DSH 0.1.7 fences jobs by the owning session id rather than the calling Agent.
|
|
100
|
+
return jobs.list(caller?.session.id).map((job) => ({
|
|
100
101
|
id: job.id,
|
|
101
102
|
kind: job.kind,
|
|
102
103
|
label: job.label,
|
|
@@ -120,7 +120,7 @@ export function ModePanel({ current, load, select, close }) {
|
|
|
120
120
|
});
|
|
121
121
|
return createElement(ListFrame, {
|
|
122
122
|
title: t('panel.mode.title', { current }),
|
|
123
|
-
rows: visible.map(row => ({ key: row.id, disabled: row.broken !== undefined, text: `${row.id === current ? '●' : '○'} ${row.name ?? row.id} · ${row.description ?? row.
|
|
123
|
+
rows: visible.map(row => ({ key: row.id, disabled: row.broken !== undefined, text: `${row.id === current ? '●' : '○'} ${row.name ?? row.id} · ${row.description ?? row.id}${row.broken === undefined ? '' : ` · broken: ${row.broken}`}` })),
|
|
124
124
|
cursor, loading, error, query, footer: t('panel.footer.chooseSwitch'),
|
|
125
125
|
});
|
|
126
126
|
}
|
|
@@ -123,10 +123,29 @@ export function nextEveryTarget(previousTarget, acceptedAt, everySeconds) {
|
|
|
123
123
|
const missed = Math.ceil((acceptedAt - previousTarget + 1) / interval);
|
|
124
124
|
return previousTarget + missed * interval;
|
|
125
125
|
}
|
|
126
|
-
/**
|
|
127
|
-
const
|
|
128
|
-
/**
|
|
129
|
-
const
|
|
126
|
+
/** Snapshot producers folded into token stats but never rendered as rows. */
|
|
127
|
+
const HIDDEN_SNAPSHOT_KINDS = new Set(['time-context', 'tmux-context', 'dscode-time-marks']);
|
|
128
|
+
/** Producers whose prompts are rendered as full user rows (they ARE the conversation). */
|
|
129
|
+
const REMINDER_KINDS = new Set(['schedule']);
|
|
130
|
+
/**
|
|
131
|
+
* The producing subsystem behind one message source.
|
|
132
|
+
*
|
|
133
|
+
* DSH 0.1.7 retired the shared `plugin` kind: every producer declares its own `kind`.
|
|
134
|
+
* A resumed transcript also carries the two older shapes — the raw
|
|
135
|
+
* `{ kind: 'plugin', plugin: '<producer>' }` of a session written before the upgrade and
|
|
136
|
+
* the `plugin:<producer>` kind the v3-to-v4 session migration writes for a producer it
|
|
137
|
+
* does not know — so every rule below asks this function instead of the raw kind.
|
|
138
|
+
*/
|
|
139
|
+
function producerKind(source) {
|
|
140
|
+
const legacy = source;
|
|
141
|
+
if (legacy.kind === 'plugin')
|
|
142
|
+
return legacy.plugin ?? '';
|
|
143
|
+
return source.kind.startsWith('plugin:') ? source.kind.slice('plugin:'.length) : source.kind;
|
|
144
|
+
}
|
|
145
|
+
/** One-line account a `notice`-form context committed, when it carries one. */
|
|
146
|
+
function noticeSummary(source) {
|
|
147
|
+
return 'form' in source && source.form === 'notice' ? source.summary : undefined;
|
|
148
|
+
}
|
|
130
149
|
/** Assemble the effective system prompt from surface nodes: head text plus every later non-empty node. */
|
|
131
150
|
function assembleSystemPrompt(nodes) {
|
|
132
151
|
if (nodes.size === 0)
|
|
@@ -358,7 +377,7 @@ export function projectEvent(view, event) {
|
|
|
358
377
|
// Snapshot injections (time/tmux context) still spend model context but
|
|
359
378
|
// render nothing; the schedule reminder is a real prompt and renders in
|
|
360
379
|
// full — the model acts on it, so the transcript must show it.
|
|
361
|
-
if (
|
|
380
|
+
if (HIDDEN_SNAPSHOT_KINDS.has(producerKind(message.source))) {
|
|
362
381
|
return {
|
|
363
382
|
...view,
|
|
364
383
|
pending,
|
|
@@ -373,7 +392,7 @@ export function projectEvent(view, event) {
|
|
|
373
392
|
},
|
|
374
393
|
};
|
|
375
394
|
}
|
|
376
|
-
if (
|
|
395
|
+
if (REMINDER_KINDS.has(producerKind(message.source))) {
|
|
377
396
|
return {
|
|
378
397
|
...view,
|
|
379
398
|
pending,
|
|
@@ -388,11 +407,7 @@ export function projectEvent(view, event) {
|
|
|
388
407
|
},
|
|
389
408
|
};
|
|
390
409
|
}
|
|
391
|
-
const notice = message.source
|
|
392
|
-
? message.source.summary
|
|
393
|
-
: message.source.kind === 'plugin'
|
|
394
|
-
? message.source.plugin
|
|
395
|
-
: message.source.kind;
|
|
410
|
+
const notice = noticeSummary(message.source) ?? producerKind(message.source);
|
|
396
411
|
const summary = boundContextSummary(notice);
|
|
397
412
|
return {
|
|
398
413
|
...view,
|
|
@@ -625,18 +640,20 @@ export function projectEvent(view, event) {
|
|
|
625
640
|
};
|
|
626
641
|
}
|
|
627
642
|
case 'tool/result': {
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
643
|
+
// DSH 0.1.7 moved the answered call id, the error flag and the result text from
|
|
644
|
+
// the first content block onto the tool-result message itself.
|
|
645
|
+
const result = event.data.message;
|
|
646
|
+
const started = view.anchors.toolStart.get(result.toolCallId);
|
|
647
|
+
view.anchors.toolStart.delete(result.toolCallId);
|
|
631
648
|
// Deregister the call from its turn's registry so `turn/end` does not
|
|
632
649
|
// sweep a start that already paired with a result.
|
|
633
650
|
const turnTools = view.anchors.turnTools.get(event.data.turn);
|
|
634
651
|
if (turnTools !== undefined) {
|
|
635
|
-
turnTools.delete(
|
|
652
|
+
turnTools.delete(result.toolCallId);
|
|
636
653
|
if (turnTools.size === 0)
|
|
637
654
|
view.anchors.turnTools.delete(event.data.turn);
|
|
638
655
|
}
|
|
639
|
-
const rawText = textOf(
|
|
656
|
+
const rawText = textOf(result.content);
|
|
640
657
|
const summary = boundContextSummary(rawText);
|
|
641
658
|
// The verbose expansion self-serves from the persisted presentation
|
|
642
659
|
// metadata (diffs, read windows, web sources) with the bounded raw text
|
|
@@ -650,9 +667,9 @@ export function projectEvent(view, event) {
|
|
|
650
667
|
view.anchors.turnFiles.set(event.data.turn, set);
|
|
651
668
|
}
|
|
652
669
|
const entries = view.entries.map((entry) => {
|
|
653
|
-
if (entry.kind !== 'tool' || entry.callId !==
|
|
670
|
+
if (entry.kind !== 'tool' || entry.callId !== result.toolCallId)
|
|
654
671
|
return entry;
|
|
655
|
-
return { ...entry, state:
|
|
672
|
+
return { ...entry, state: result.isError === true ? 'error' : 'done', summary, detail };
|
|
656
673
|
});
|
|
657
674
|
return {
|
|
658
675
|
...view,
|
|
@@ -1172,7 +1189,7 @@ export function replayProjectEvent(acc, event) {
|
|
|
1172
1189
|
const origin = acc.claimOrigin.get(message.id);
|
|
1173
1190
|
const delivery = origin === undefined ? {} : { delivery: origin === 'next-turn' ? 'queued' : 'steered' };
|
|
1174
1191
|
acc.claimOrigin.delete(message.id);
|
|
1175
|
-
if (message.source.kind === 'user' ||
|
|
1192
|
+
if (message.source.kind === 'user' || REMINDER_KINDS.has(producerKind(message.source))) {
|
|
1176
1193
|
appendReplayEntry(acc, { kind: 'user', text, notice: false, ...delivery, ...(images.length === 0 ? {} : { images }), ...(files.length === 0 ? {} : { files }) });
|
|
1177
1194
|
acc.stats = {
|
|
1178
1195
|
...acc.stats,
|
|
@@ -1183,7 +1200,7 @@ export function replayProjectEvent(acc, event) {
|
|
|
1183
1200
|
};
|
|
1184
1201
|
return true;
|
|
1185
1202
|
}
|
|
1186
|
-
if (
|
|
1203
|
+
if (HIDDEN_SNAPSHOT_KINDS.has(producerKind(message.source))) {
|
|
1187
1204
|
acc.stats = {
|
|
1188
1205
|
...acc.stats,
|
|
1189
1206
|
contextSegments: {
|
|
@@ -1193,11 +1210,7 @@ export function replayProjectEvent(acc, event) {
|
|
|
1193
1210
|
};
|
|
1194
1211
|
return true;
|
|
1195
1212
|
}
|
|
1196
|
-
const notice = message.source
|
|
1197
|
-
? message.source.summary
|
|
1198
|
-
: message.source.kind === 'plugin'
|
|
1199
|
-
? message.source.plugin
|
|
1200
|
-
: message.source.kind;
|
|
1213
|
+
const notice = noticeSummary(message.source) ?? producerKind(message.source);
|
|
1201
1214
|
const summary = boundContextSummary(notice);
|
|
1202
1215
|
appendReplayEntry(acc, { kind: 'user', text: summary, notice: true });
|
|
1203
1216
|
acc.stats = {
|
|
@@ -1379,16 +1392,16 @@ export function replayProjectEvent(acc, event) {
|
|
|
1379
1392
|
return true;
|
|
1380
1393
|
}
|
|
1381
1394
|
case 'tool/result': {
|
|
1382
|
-
const
|
|
1383
|
-
const started = acc.toolStart.get(
|
|
1384
|
-
acc.toolStart.delete(
|
|
1395
|
+
const result = event.data.message;
|
|
1396
|
+
const started = acc.toolStart.get(result.toolCallId);
|
|
1397
|
+
acc.toolStart.delete(result.toolCallId);
|
|
1385
1398
|
const turnTools = acc.turnTools.get(event.data.turn);
|
|
1386
1399
|
if (turnTools !== undefined) {
|
|
1387
|
-
turnTools.delete(
|
|
1400
|
+
turnTools.delete(result.toolCallId);
|
|
1388
1401
|
if (turnTools.size === 0)
|
|
1389
1402
|
acc.turnTools.delete(event.data.turn);
|
|
1390
1403
|
}
|
|
1391
|
-
const rawText = textOf(
|
|
1404
|
+
const rawText = textOf(result.content);
|
|
1392
1405
|
const summary = boundContextSummary(rawText);
|
|
1393
1406
|
const detail = toolResultDetail(event.data.meta, rawText);
|
|
1394
1407
|
if (detail?.kind === 'diff') {
|
|
@@ -1399,13 +1412,13 @@ export function replayProjectEvent(acc, event) {
|
|
|
1399
1412
|
}
|
|
1400
1413
|
const update = (entry) => ({
|
|
1401
1414
|
...entry,
|
|
1402
|
-
state:
|
|
1415
|
+
state: result.isError === true ? 'error' : 'done',
|
|
1403
1416
|
summary,
|
|
1404
1417
|
detail,
|
|
1405
1418
|
});
|
|
1406
1419
|
// Every matching row updates (duplicate callIds included); an id with no
|
|
1407
1420
|
// registered index is a provable no-op — no full-array fallback scan.
|
|
1408
|
-
updateReplayById(acc, acc.toolIndex,
|
|
1421
|
+
updateReplayById(acc, acc.toolIndex, result.toolCallId, entry => entry.callId === result.toolCallId, update);
|
|
1409
1422
|
acc.stats = {
|
|
1410
1423
|
...acc.stats,
|
|
1411
1424
|
toolMs: acc.stats.toolMs + (started === undefined ? 0 : Math.max(0, event.time - started)),
|
|
@@ -1860,10 +1873,11 @@ function dscodeCloseTurn(entries) {
|
|
|
1860
1873
|
return [...entries.slice(0, -1), { ...last, turnEnded: true }];
|
|
1861
1874
|
}
|
|
1862
1875
|
/**
|
|
1863
|
-
* dscode: session-bridge relays are
|
|
1864
|
-
* user turns (the bridge delivers a peer session's message), so the replay
|
|
1865
|
-
*
|
|
1876
|
+
* dscode: session-bridge relays are injected messages that must render as visible
|
|
1877
|
+
* user turns (the bridge delivers a peer session's message), so the replay branch
|
|
1878
|
+
* admits them alongside direct human prompts.
|
|
1866
1879
|
*/
|
|
1867
1880
|
function dscodeVisibleRelay(message) {
|
|
1868
|
-
return message.source
|
|
1881
|
+
return producerKind(message.source) === 'dscode-session-bridge'
|
|
1882
|
+
&& 'form' in message.source && message.source.form === 'relay';
|
|
1869
1883
|
}
|