@toddzheng024/dscode-bundle 0.4.0 → 0.6.0
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/THIRD_PARTY_NOTICES.md +15 -0
- package/cordis.patch.yml +3 -3
- package/package.json +7 -1
- package/plugins/clipboard-image/clipboard-image.swift +56 -0
- package/plugins/clipboard-image/index.mjs +70 -0
- package/plugins/code-review/git.mjs +95 -0
- package/plugins/code-review/index.mjs +88 -0
- package/plugins/dscode/index.mjs +57 -5
- package/plugins/email-tools/index.mjs +2 -2
- package/plugins/exec/index.mjs +107 -0
- package/plugins/session-metrics/index.mjs +6 -2
- package/plugins/session-metrics/rate.mjs +62 -0
- package/plugins/session-metrics/view.mjs +15 -9
- package/plugins/tui-tools/doctor-cli.mjs +22 -0
- package/plugins/tui-tools/doctor.mjs +141 -0
- package/plugins/tui-tools/index.mjs +14 -6
- package/plugins/ultra/policy.mjs +13 -2
- package/plugins/worktree-subagent/worktree.mjs +50 -0
- package/presets/dscode/agent.cordis.yml +14 -3
- package/vendor/deepseek/index.js +12 -2
- package/vendor/subagent/index.js +39 -12
- package/vendor/subagent-core/LICENSE +21 -0
- package/vendor/subagent-core/index.js +3232 -0
- package/vendor/subagent-core/invariant.js +76 -0
- package/vendor/subagent-core/typert.host.d.ts +3 -0
- package/vendor/subagent-core/typert.host.js +964 -0
- package/vendor/subagent-core/typert.remote-client.d.ts +27 -0
- package/vendor/subagent-core/typert.remote-client.js +160 -0
- package/vendor/subagent-core/types/assistant-output.d.ts +48 -0
- package/vendor/subagent-core/types/assistant-output.js +73 -0
- package/vendor/subagent-core/types/catalog.d.ts +77 -0
- package/vendor/subagent-core/types/catalog.js +103 -0
- package/vendor/subagent-core/types/child-agent.d.ts +150 -0
- package/vendor/subagent-core/types/child-agent.js +207 -0
- package/vendor/subagent-core/types/client.d.ts +8 -0
- package/vendor/subagent-core/types/client.js +7 -0
- package/vendor/subagent-core/types/continuation-activation.d.ts +251 -0
- package/vendor/subagent-core/types/continuation-activation.js +663 -0
- package/vendor/subagent-core/types/continuation-messages.d.ts +62 -0
- package/vendor/subagent-core/types/continuation-messages.js +102 -0
- package/vendor/subagent-core/types/continuation.d.ts +124 -0
- package/vendor/subagent-core/types/continuation.js +455 -0
- package/vendor/subagent-core/types/control-types.d.ts +146 -0
- package/vendor/subagent-core/types/control-types.js +9 -0
- package/vendor/subagent-core/types/control.d.ts +71 -0
- package/vendor/subagent-core/types/control.js +116 -0
- package/vendor/subagent-core/types/depth.d.ts +31 -0
- package/vendor/subagent-core/types/depth.js +39 -0
- package/vendor/subagent-core/types/descriptor.d.ts +144 -0
- package/vendor/subagent-core/types/descriptor.js +193 -0
- package/vendor/subagent-core/types/error.d.ts +11 -0
- package/vendor/subagent-core/types/error.js +14 -0
- package/vendor/subagent-core/types/inbox.d.ts +43 -0
- package/vendor/subagent-core/types/inbox.js +61 -0
- package/vendor/subagent-core/types/index.d.ts +316 -0
- package/vendor/subagent-core/types/index.js +511 -0
- package/vendor/subagent-core/types/internal.d.ts +58 -0
- package/vendor/subagent-core/types/internal.js +58 -0
- package/vendor/subagent-core/types/invariant.d.ts +13 -0
- package/vendor/subagent-core/types/invariant.js +91 -0
- package/vendor/subagent-core/types/lifecycle.d.ts +113 -0
- package/vendor/subagent-core/types/lifecycle.js +178 -0
- package/vendor/subagent-core/types/list-children.d.ts +65 -0
- package/vendor/subagent-core/types/list-children.js +381 -0
- package/vendor/subagent-core/types/out-of-process.d.ts +118 -0
- package/vendor/subagent-core/types/out-of-process.js +219 -0
- package/vendor/subagent-core/types/projection-types.d.ts +74 -0
- package/vendor/subagent-core/types/projection-types.js +7 -0
- package/vendor/subagent-core/types/projection.d.ts +95 -0
- package/vendor/subagent-core/types/projection.js +151 -0
- package/vendor/subagent-core/types/run-settlement.d.ts +17 -0
- package/vendor/subagent-core/types/run-settlement.js +70 -0
- package/vendor/subagent-core/types/types.d.ts +377 -0
- package/vendor/subagent-core/types/types.js +19 -0
- package/vendor/subagent-driver/LICENSE +21 -0
- package/vendor/subagent-driver/index.js +255 -0
- package/vendor/subagent-driver/types/index.d.ts +33 -0
- package/vendor/subagent-driver/types/structured.d.ts +42 -0
- package/vendor/subagent-fork/LICENSE +21 -0
- package/vendor/subagent-fork/index.js +61 -0
- package/vendor/subagent-fork/types/index.d.ts +20 -0
- package/vendor/subagent-spawn/LICENSE +21 -0
- package/vendor/subagent-spawn/index.js +45 -0
- package/vendor/subagent-spawn/types/index.d.ts +19 -0
- package/vendor/terminal/LICENSE +21 -0
- package/vendor/terminal/index.js +1013 -0
- package/vendor/terminal/types/config.d.ts +71 -0
- package/vendor/terminal/types/index.d.ts +36 -0
- package/vendor/terminal/types/sanitize.d.ts +47 -0
- package/vendor/terminal/types/session.d.ts +87 -0
- package/vendor/tui/dscode-clipboard-image/clipboard-image.swift +56 -0
- package/vendor/tui/dscode-clipboard-image/index.mjs +70 -0
- package/vendor/tui/index.mjs +341 -93
package/vendor/tui/index.mjs
CHANGED
|
@@ -1,3 +1,149 @@
|
|
|
1
|
+
// dscode-welcome-v2
|
|
2
|
+
const WELCOME_ART = ["...........1.1..........","............1...........","............1...........",".........1..1..1........",".......1..22222..1......","...1...1....2....1...1..","..11...2....2....2...11.","....11.2...222...2.11...","......22.22.3.22.22.....",".....22.22.333.22.22....","....1...2.33332.2...1...","........2.33322.2.......","....1...2.33222.2...1...",".....22.22.222.22.22....","......22.22.3.22.22.....","....11.2...222...2.11...","..11...2....2....2...11.","...1...1....2....1...1..",".......1..22222..1......",".........1..1..1........","............1...........","............1...........","...........1.1..........","........................"];
|
|
3
|
+
const WELCOME_ART_SMALL = ["..........1.1.........","...........1..........","........1..1..1.......",".........1.2.1........","...1..1...222...1..1..","...1..1....2....1..1..","..1.1.2...222...2.1.1.",".....22.22.3.22.22....","....12.22.333.22.21...","...1...2.33332.2...1..",".......2.33322.2......","...1...2.33222.2...1..","....12.22.222.22.21...",".....22.22.3.22.22....","..1.1.2...222...2.1.1.","...1..1....2....1..1..","...1..1...222...1..1..",".........1.2.1........","........1..1..1.......","...........1..........","..........1.1.........","......................"];
|
|
4
|
+
function welcomeArtRows(grid, tones) {
|
|
5
|
+
const rows = [];
|
|
6
|
+
for (let y = 0; y < grid.length; y += 2) {
|
|
7
|
+
const top = grid[y] || '';
|
|
8
|
+
const bottom = grid[y + 1] || '';
|
|
9
|
+
const segments = [];
|
|
10
|
+
for (let x = 0; x < Math.max(top.length, bottom.length); x++) {
|
|
11
|
+
const upper = tones[top[x]] || '';
|
|
12
|
+
const lower = tones[bottom[x]] || '';
|
|
13
|
+
const glyph = upper && lower ? upper === lower ? '\u2588' : '\u2580' : upper ? '\u2580' : lower ? '\u2584' : ' ';
|
|
14
|
+
const color = upper || lower;
|
|
15
|
+
const background = upper && lower && upper !== lower ? lower : '';
|
|
16
|
+
const last = segments[segments.length - 1];
|
|
17
|
+
if (last && last.glyph === glyph && last.color === color && last.background === background) last.text += glyph;
|
|
18
|
+
else segments.push({ glyph, text: glyph, color, background });
|
|
19
|
+
}
|
|
20
|
+
rows.push(segments);
|
|
21
|
+
}
|
|
22
|
+
return rows;
|
|
23
|
+
}
|
|
24
|
+
import { readClipboardImage as dscodeReadClipboardImage } from "./dscode-clipboard-image/index.mjs";
|
|
25
|
+
// dscode-clipboard-image-v1
|
|
26
|
+
// dscode-large-paste-v1
|
|
27
|
+
function collapseLargePaste(text, draft, pastes) {
|
|
28
|
+
const safe = text.replaceAll('\r\n', '\n').replaceAll('\r', '\n').replace(/[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/gu, '').replaceAll('\t', ' ');
|
|
29
|
+
const count = [...safe].length;
|
|
30
|
+
if (count <= LARGE_PASTE_CHARS) return safe;
|
|
31
|
+
// Keep an executable-looking first line visible to the command router.
|
|
32
|
+
if (draft.trim() === '' && /^\s*[!/]/u.test(safe)) return safe;
|
|
33
|
+
const base = `[Pasted Content ${count} chars]`;
|
|
34
|
+
let marker = base;
|
|
35
|
+
for (let suffix = 2; draft.includes(marker) || pastes.has(marker); suffix++) marker = `${base} #${suffix}`;
|
|
36
|
+
pastes.set(marker, safe);
|
|
37
|
+
return marker;
|
|
38
|
+
}
|
|
39
|
+
function expandLargePastes(value, pastes) {
|
|
40
|
+
const markers = [...pastes.keys()].sort((left, right) => right.length - left.length);
|
|
41
|
+
let expanded = '';
|
|
42
|
+
let offset = 0;
|
|
43
|
+
while (offset < value.length) {
|
|
44
|
+
let found = -1;
|
|
45
|
+
let match;
|
|
46
|
+
for (const marker of markers) {
|
|
47
|
+
const at = value.indexOf(marker, offset);
|
|
48
|
+
if (at >= 0 && (found < 0 || at < found)) {
|
|
49
|
+
found = at;
|
|
50
|
+
match = marker;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (match === undefined) break;
|
|
54
|
+
expanded += value.slice(offset, found) + pastes.get(match);
|
|
55
|
+
offset = found + match.length;
|
|
56
|
+
}
|
|
57
|
+
return expanded + value.slice(offset);
|
|
58
|
+
}
|
|
59
|
+
function pasteAtomicEdit(before, edit, pastes) {
|
|
60
|
+
let prefix = 0;
|
|
61
|
+
while (prefix < before.length && prefix < edit.value.length && before[prefix] === edit.value[prefix]) prefix++;
|
|
62
|
+
let suffix = 0;
|
|
63
|
+
while (suffix < before.length - prefix && suffix < edit.value.length - prefix && before[before.length - suffix - 1] === edit.value[edit.value.length - suffix - 1]) suffix++;
|
|
64
|
+
let from = prefix, to = before.length - suffix;
|
|
65
|
+
const inserted = edit.value.slice(prefix, edit.value.length - suffix);
|
|
66
|
+
let touched = false;
|
|
67
|
+
const originalPastes = new Map(pastes);
|
|
68
|
+
for (const marker of pastes.keys()) {
|
|
69
|
+
const start = before.indexOf(marker);
|
|
70
|
+
if (start < 0) continue;
|
|
71
|
+
const end = start + marker.length;
|
|
72
|
+
if (from < end && to > start || from === to && from > start && from < end) {
|
|
73
|
+
from = Math.min(from, start);
|
|
74
|
+
to = Math.max(to, end);
|
|
75
|
+
pastes.delete(marker);
|
|
76
|
+
touched = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (touched) edit = { ...edit, value: before.slice(0, from) + inserted + before.slice(to), cursor: from + inserted.length,
|
|
80
|
+
killed: edit.killed === undefined ? undefined : expandLargePastes(before.slice(from, to), originalPastes) };
|
|
81
|
+
for (const marker of pastes.keys()) if (!edit.value.includes(marker) && before.includes(marker)) pastes.delete(marker);
|
|
82
|
+
return edit;
|
|
83
|
+
}
|
|
84
|
+
function pasteCursorEdge(value, previous, next, pastes) {
|
|
85
|
+
for (const marker of pastes.keys()) {
|
|
86
|
+
const start = value.indexOf(marker);
|
|
87
|
+
if (start < 0) continue;
|
|
88
|
+
const end = start + marker.length;
|
|
89
|
+
if (next > start && next < end) return next < previous ? start : end;
|
|
90
|
+
}
|
|
91
|
+
return next;
|
|
92
|
+
}
|
|
93
|
+
const LARGE_PASTE_CHARS = 200;
|
|
94
|
+
// dscode-user-background-v1
|
|
95
|
+
function userBackgroundRows(rows, columns, measure) {
|
|
96
|
+
const width = Math.max(1, Math.floor(columns));
|
|
97
|
+
return rows.map(row => {
|
|
98
|
+
const used = row.segments.reduce((sum, segment) => sum + measure(segment.text), 0);
|
|
99
|
+
return {
|
|
100
|
+
...row,
|
|
101
|
+
background: 'user',
|
|
102
|
+
segments: [...row.segments, { text: ' '.repeat(Math.max(0, width - used)), style: 'plain' }],
|
|
103
|
+
};
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// dscode-turn-divider-v1
|
|
107
|
+
function turnDividedLines(entry, columns, rendered, remaining) {
|
|
108
|
+
if (entry?.turnEnded !== true || (rendered.length > 0 && rendered.length >= remaining)) return rendered;
|
|
109
|
+
// Full terminal width: the row renders with truncate-end, so it can never wrap.
|
|
110
|
+
return [...rendered, { segments: [{ text: '─'.repeat(Math.max(1, columns)), style: 'dim' }] }];
|
|
111
|
+
}
|
|
112
|
+
// dscode-scroll-v1
|
|
113
|
+
function transcriptWindow(lines, rows, offset) {
|
|
114
|
+
if (rows <= 0) return [];
|
|
115
|
+
const end = Math.max(0, lines.length - Math.max(0, offset));
|
|
116
|
+
return lines.slice(Math.max(0, end - rows), end);
|
|
117
|
+
}
|
|
118
|
+
function mouseWheelDirection(unit) {
|
|
119
|
+
const match = /^\x1b\[<(\d+);\d+;\d+([Mm])$/.exec(unit);
|
|
120
|
+
if (!match) return null;
|
|
121
|
+
if (match[2] !== 'M') return 0;
|
|
122
|
+
const button = Number(match[1]) & ~(4 | 8 | 16);
|
|
123
|
+
return button === 64 ? 1 : button === 65 ? -1 : 0;
|
|
124
|
+
}
|
|
125
|
+
const DSCODE_MOUSE_ENABLE = "\x1b[?1000h\x1b[?1006h";
|
|
126
|
+
const DSCODE_MOUSE_DISABLE = "\x1b[?1006l\x1b[?1000l";
|
|
127
|
+
const dscodeWheelListeners = new Set();
|
|
128
|
+
function dscodeHandleMouseUnit(unit) {
|
|
129
|
+
const direction = mouseWheelDirection(unit);
|
|
130
|
+
if (direction === null) return false;
|
|
131
|
+
if (direction !== 0) for (const listener of dscodeWheelListeners) listener(direction);
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
// dscode-interrupt-v1
|
|
135
|
+
function ctrlCAction(armed, { interrupt, busy, preparingImages, active, hasDraft }) {
|
|
136
|
+
if (armed) return 'quit';
|
|
137
|
+
if (interrupt() || busy) return 'interrupt';
|
|
138
|
+
if (preparingImages) return 'cancel-prepare';
|
|
139
|
+
if (!active) return 'wait';
|
|
140
|
+
return hasDraft ? 'clear-draft' : 'quit';
|
|
141
|
+
}
|
|
142
|
+
// dscode-welcome-scroll-v1
|
|
143
|
+
function welcomeVisibleRows(capacity, maximum, demand, canScroll = true) {
|
|
144
|
+
if (!canScroll || capacity < maximum) return maximum;
|
|
145
|
+
return Math.max(0, Math.min(maximum, capacity - demand));
|
|
146
|
+
}
|
|
1
147
|
// dscode-email-v4
|
|
2
148
|
import { createImapConnector as dscodeCreateImapConnector } from "./dscode-email/imap.mjs";
|
|
3
149
|
import { createGmailConnector as dscodeCreateGmailConnector } from "./dscode-email/gmail.mjs";
|
|
@@ -148,7 +294,7 @@ function visibleSettledLines(entries, settled, budget, columns, showReasoning, r
|
|
|
148
294
|
const chunks = [];
|
|
149
295
|
let remaining = budget;
|
|
150
296
|
for (let index = settled - 1; index >= 0 && remaining > 0; index--) {
|
|
151
|
-
const lines = renderEntry(entries[index], Math.max(10, columns - 2), showReasoning);
|
|
297
|
+
const lines = turnDividedLines(entries[index], columns, renderEntry(entries[index], Math.max(10, columns - 2), showReasoning), remaining);
|
|
152
298
|
const kept = lines.slice(-remaining);
|
|
153
299
|
if (kept.length) {
|
|
154
300
|
chunks.unshift(kept);
|
|
@@ -159,6 +305,40 @@ function visibleSettledLines(entries, settled, budget, columns, showReasoning, r
|
|
|
159
305
|
}
|
|
160
306
|
// dscode-style-v1
|
|
161
307
|
|
|
308
|
+
|
|
309
|
+
// dscode-tps-colors-v1
|
|
310
|
+
function dscodeTpsTone(rate) {
|
|
311
|
+
if (!Number.isFinite(rate) || rate < 0) return null;
|
|
312
|
+
if (rate < 75) return "yellow";
|
|
313
|
+
if (rate < 150) return "green";
|
|
314
|
+
if (rate <= 250) return "blue";
|
|
315
|
+
return "purple";
|
|
316
|
+
}
|
|
317
|
+
function dscodeTpsInkColor(tone) {
|
|
318
|
+
const palette = getPalette();
|
|
319
|
+
if (tone === "yellow") return inkColor(palette.warn);
|
|
320
|
+
if (tone === "green") return inkColor(palette.success);
|
|
321
|
+
if (tone === "blue") return inkColor(palette.brandBright);
|
|
322
|
+
if (tone === "purple") return inkColor(getTheme() === "light" ? [126, 34, 206] : [192, 132, 252]);
|
|
323
|
+
return void 0;
|
|
324
|
+
}
|
|
325
|
+
function dscodeTelemetryParts(value) {
|
|
326
|
+
const result = [];
|
|
327
|
+
for (const [index, part] of value.split(" | ").entries()) {
|
|
328
|
+
if (index > 0) result.push({ text: " | ", tone: null });
|
|
329
|
+
const prefix = part.startsWith("current: ") ? "current: " : part.startsWith("average: ") ? "average: " : "";
|
|
330
|
+
if (!prefix || !part.endsWith(" tps")) { result.push({ text: part, tone: null }); continue; }
|
|
331
|
+
const display = part.slice(prefix.length, -4);
|
|
332
|
+
const rate = Number(display.startsWith("~") ? display.slice(1) : display);
|
|
333
|
+
result.push({ text: prefix, tone: null }, { text: display + " tps", tone: display && dscodeTpsTone(rate) });
|
|
334
|
+
}
|
|
335
|
+
return result;
|
|
336
|
+
}
|
|
337
|
+
function dscodeTelemetryNodes(value, key) {
|
|
338
|
+
return dscodeTelemetryParts(value).map((part, index) => (0, import_react.createElement)(Text,
|
|
339
|
+
{ key: key + "p" + index, color: dscodeTpsInkColor(part.tone) }, part.text));
|
|
340
|
+
}
|
|
341
|
+
|
|
162
342
|
function dscodeActivity(entries, streaming) {
|
|
163
343
|
const running = entries.filter(entry => entry.kind === "tool" && entry.state === "running");
|
|
164
344
|
const tool = running.at(-1);
|
|
@@ -175,19 +355,25 @@ function dscodeActivity(entries, streaming) {
|
|
|
175
355
|
return "正在执行 · " + singleLineText(tool.name) + (running.length > 1 ? " +" + (running.length - 1) : "") +
|
|
176
356
|
(description ? " · " + truncateColumns(singleLineText(description), 56) : "");
|
|
177
357
|
}
|
|
358
|
+
// A snowflake with an arc orbiting it clockwise: top-left, top-right, bottom-right, bottom-left.
|
|
359
|
+
const DSCODE_SPIN_FRAMES = [["◜", "❄", " "], [" ", "❄", "◝"], [" ", "❄", "◞"], ["◟", "❄", " "]];
|
|
178
360
|
function DscodeActivityLine({ entries, streaming, since, animated = true }) {
|
|
179
361
|
const columns = useStdout().stdout?.columns ?? 80;
|
|
180
|
-
const tick = useFrames(animated ?
|
|
362
|
+
const tick = useFrames(animated ? 220 : 1000);
|
|
181
363
|
const elapsed = since > 0 ? Math.max(0, Date.now() - since) : 0;
|
|
182
364
|
const suffix = columns >= 48 ? " · 本轮 " + runClock(elapsed) + " · Esc 中断" : " · 本轮 " + runClock(elapsed);
|
|
183
|
-
const
|
|
184
|
-
const label = truncateColumns(dscodeActivity(entries, streaming), Math.max(1, columns -
|
|
365
|
+
const [left, flake, right] = animated ? DSCODE_SPIN_FRAMES[tick % DSCODE_SPIN_FRAMES.length] : [" ", "❄", " "];
|
|
366
|
+
const label = truncateColumns(dscodeActivity(entries, streaming), Math.max(1, columns - 8 - visibleColumns(suffix)));
|
|
185
367
|
return (0, import_react.createElement)(Box, { paddingX: 2 },
|
|
186
368
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" },
|
|
187
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().
|
|
369
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandMid) }, left),
|
|
370
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, flake),
|
|
371
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandMid) }, right),
|
|
372
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " " + label),
|
|
188
373
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, suffix)));
|
|
189
374
|
}
|
|
190
375
|
|
|
376
|
+
|
|
191
377
|
// dscode-footer-v1
|
|
192
378
|
import { footerFor as dscodeFooterFor } from "../../plugins/session-metrics/view.mjs";
|
|
193
379
|
// dscode-ime-v1
|
|
@@ -240,7 +426,8 @@ function dscodeChatLines(entry, columns) {
|
|
|
240
426
|
if (!entry.text && !entry.interrupted) return [];
|
|
241
427
|
entry = { ...entry, reasoning: "" };
|
|
242
428
|
}
|
|
243
|
-
|
|
429
|
+
const rows = transcriptEntryLines(entry, columns, false, false, false);
|
|
430
|
+
return entry.kind === "user" && !entry.notice ? userBackgroundRows(rows, columns, visibleColumns) : rows;
|
|
244
431
|
}
|
|
245
432
|
import { n as __require, r as __toESM, t as __commonJSMin } from "./rolldown-runtime-CMFfr-1z.mjs";
|
|
246
433
|
import { a as inkColor, c as chalk, i as getTheme, n as dim, o as parseThemeName, r as getPalette, s as setTheme } from "./theme-DCT8Y2xf.mjs";
|
|
@@ -25874,9 +26061,18 @@ function replayProjectEvent(acc, event) {
|
|
|
25874
26061
|
acc.busy = false;
|
|
25875
26062
|
acc.busySince = 0;
|
|
25876
26063
|
for (const entry of appended) appendReplayEntry(acc, entry);
|
|
25877
|
-
|
|
25878
|
-
|
|
25879
|
-
|
|
26064
|
+
for (let index = acc.entries.length - 1; index >= 0; index--) {
|
|
26065
|
+
const entry = acc.entries[index];
|
|
26066
|
+
if (entry === void 0 || entry.kind === "pending") continue;
|
|
26067
|
+
if (entry.turnEnded !== true) {
|
|
26068
|
+
acc.entries[index] = { ...entry, turnEnded: true };
|
|
26069
|
+
acc.ops += 1;
|
|
26070
|
+
}
|
|
26071
|
+
break;
|
|
26072
|
+
}
|
|
26073
|
+
return true;
|
|
26074
|
+
}
|
|
26075
|
+
case "llm/retry": {
|
|
25880
26076
|
const data = event.data;
|
|
25881
26077
|
acc.streaming = "";
|
|
25882
26078
|
acc.streamingReasoning = "";
|
|
@@ -28353,7 +28549,7 @@ function cacheHitPercent(usage) {
|
|
|
28353
28549
|
return usage.inputTokens === 0 ? null : Math.round(usage.cacheReadTokens / usage.inputTokens * 1e3) / 10;
|
|
28354
28550
|
}
|
|
28355
28551
|
/** Separator between trailing state spans. */
|
|
28356
|
-
const STATUS_ITEM_SEPARATOR = "
|
|
28552
|
+
const STATUS_ITEM_SEPARATOR = " | ";
|
|
28357
28553
|
/** The Codex-style mode cycle hint appended to the permission badge. */
|
|
28358
28554
|
const STATUS_CYCLE_HINT = " (shift+tab to cycle)";
|
|
28359
28555
|
/** Occupancy at which the usage readout flips from brand blue to amber. */
|
|
@@ -28568,7 +28764,7 @@ function safe(text) {
|
|
|
28568
28764
|
/** Dim junction separator span inside a cluster. */
|
|
28569
28765
|
function sep() {
|
|
28570
28766
|
return {
|
|
28571
|
-
text: "
|
|
28767
|
+
text: " | ",
|
|
28572
28768
|
tone: "label"
|
|
28573
28769
|
};
|
|
28574
28770
|
}
|
|
@@ -28599,7 +28795,7 @@ function buildCandidates(facts, stats, busy, enabled, contextWidth) {
|
|
|
28599
28795
|
if (model !== "" && enabled.has("model")) {
|
|
28600
28796
|
const effort = safe(facts.effort ?? stats.reasoningEffort);
|
|
28601
28797
|
push({
|
|
28602
|
-
text: effort === "" ? model : `${model}
|
|
28798
|
+
text: effort === "" ? model : `${model} | ${effort}`,
|
|
28603
28799
|
tone: "model"
|
|
28604
28800
|
});
|
|
28605
28801
|
}
|
|
@@ -28796,7 +28992,7 @@ function layoutStatusBar(facts, stats, columns, options = {}) {
|
|
|
28796
28992
|
const budget = Math.max(1, Math.floor(columns) - WIDTH_SAFETY);
|
|
28797
28993
|
const maxContextWidth = Math.max(CONTEXT_MIN_WIDTH, Math.min(budget, Math.floor(options.contextWidth ?? 24)));
|
|
28798
28994
|
const { left, right, badge, row2 } = buildCandidates(facts, stats, busy, enabled, maxContextWidth);
|
|
28799
|
-
const groupSeparator = visibleColumns("
|
|
28995
|
+
const groupSeparator = visibleColumns(" | ");
|
|
28800
28996
|
const itemSeparator = visibleColumns(STATUS_ITEM_SEPARATOR);
|
|
28801
28997
|
const position = new Map(items.map((id, index) => [id, index]));
|
|
28802
28998
|
const byPosition = (a, b) => (position.get(a.id) ?? Number.MAX_SAFE_INTEGER) - (position.get(b.id) ?? Number.MAX_SAFE_INTEGER);
|
|
@@ -28897,7 +29093,7 @@ function layoutStatusBar(facts, stats, columns, options = {}) {
|
|
|
28897
29093
|
};
|
|
28898
29094
|
}
|
|
28899
29095
|
const row2Kept = [...orderedRow2];
|
|
28900
|
-
const row2Budget = Math.max(0, budget -
|
|
29096
|
+
const row2Budget = Math.max(0, budget - 1 - (facts.telemetry ? visibleColumns(facts.telemetry) + 3 : 0));
|
|
28901
29097
|
const row2Width = () => joinWidth(row2Kept.map((entry) => spansWidth(entry.group.spans)), groupSeparator);
|
|
28902
29098
|
while (row2Width() > row2Budget && row2Kept.length > 0) {
|
|
28903
29099
|
let dropIndex = 0;
|
|
@@ -32003,8 +32199,10 @@ function lineStyleProps(style) {
|
|
|
32003
32199
|
function StyledRows({ lines }) {
|
|
32004
32200
|
return (0, import_react.createElement)(Box, { flexDirection: "column" }, ...lines.map((line, index) => (0, import_react.createElement)(Text, {
|
|
32005
32201
|
key: index,
|
|
32006
|
-
|
|
32007
|
-
|
|
32202
|
+
wrap: "truncate-end",
|
|
32203
|
+
backgroundColor: line.background === "user" ? inkColor(getPalette().composerBand) : void 0,
|
|
32204
|
+
color: line.background === "user" ? inkColor(getPalette().text) : void 0
|
|
32205
|
+
}, line.segments.length === 0 ? " " : line.segments.map((segment, at) => (0, import_react.createElement)(Text, {
|
|
32008
32206
|
key: at,
|
|
32009
32207
|
...lineStyleProps(segment.style)
|
|
32010
32208
|
}, segment.text)))));
|
|
@@ -32073,29 +32271,25 @@ function Header({ cwd = "", model = "", effort = "" }) {
|
|
|
32073
32271
|
const modelName = singleLineText(model).split("/").at(-1) || "unknown";
|
|
32074
32272
|
const effortName = singleLineText(effort) || "default";
|
|
32075
32273
|
const project = welcomePath(cwd, detailsWidth);
|
|
32274
|
+
const palette = getPalette();
|
|
32275
|
+
const art = (stdout?.rows ?? 30) >= 26 ? WELCOME_ART : WELCOME_ART_SMALL;
|
|
32276
|
+
const luminance = ([red, green, blue]) => red * 299 + green * 587 + blue * 114;
|
|
32277
|
+
const tones = [palette.brandDeep, palette.brand, palette.brandBright].sort((left, right) => luminance(left) - luminance(right));
|
|
32076
32278
|
if (!full) return (0, import_react.createElement)(Box, { flexDirection: "column", paddingX: 2, marginBottom: 1 },
|
|
32077
32279
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" },
|
|
32078
32280
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright), bold: true }, "❄ DSCODE"),
|
|
32079
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, " v0.
|
|
32281
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, " v0.6.0")),
|
|
32080
32282
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns(modelName + " · " + effortName, width)),
|
|
32081
32283
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim), wrap: "truncate-end" }, welcomePath(cwd, width)));
|
|
32082
|
-
return (0, import_react.createElement)(Box, { flexDirection: "column", width, borderStyle: "round", borderColor: inkColor(getPalette().brand), paddingX: 1
|
|
32284
|
+
return (0, import_react.createElement)(Box, { flexDirection: "column", width, borderStyle: "round", borderColor: inkColor(getPalette().brand), paddingX: 1 },
|
|
32083
32285
|
(0, import_react.createElement)(Box, { flexDirection: "row" },
|
|
32084
32286
|
(0, import_react.createElement)(Box, { flexDirection: "column", width: 28 },
|
|
32085
|
-
(0, import_react.createElement)(Text, {
|
|
32086
|
-
|
|
32087
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▄███▄ ▀█▀ ▄███▄"),
|
|
32088
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▀██▄ █ ▄██▀"),
|
|
32089
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▄███▄"),
|
|
32090
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▀███▀"),
|
|
32091
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▄██▀ █ ▀██▄"),
|
|
32092
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▀███▀ ▄█▄ ▀███▀"),
|
|
32093
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " █▀▀█ █▀█▀█ █▀▀█"),
|
|
32094
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright) }, " ▀")),
|
|
32287
|
+
...welcomeArtRows(art, { "1": inkColor(tones[0]), "2": inkColor(tones[1]), "3": inkColor(tones[2]) }).map((segments, row) => (0, import_react.createElement)(Text, { key: row }, " ",
|
|
32288
|
+
...segments.map((segment, index) => (0, import_react.createElement)(Text, { key: index, color: segment.color || void 0, backgroundColor: segment.background || void 0 }, segment.text))))),
|
|
32095
32289
|
(0, import_react.createElement)(Box, { flexDirection: "column", width: detailsWidth, marginTop: 2 },
|
|
32096
32290
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().text), bold: true }, "DSCODE"),
|
|
32097
32291
|
(0, import_react.createElement)(Text, { color: inkColor(getPalette().brandDeep) }, "────────────"),
|
|
32098
|
-
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, "v0.
|
|
32292
|
+
(0, import_react.createElement)(Text, { color: inkColor(getPalette().dim) }, "v0.6.0"),
|
|
32099
32293
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns("model " + modelName, detailsWidth)),
|
|
32100
32294
|
(0, import_react.createElement)(Text, { wrap: "truncate-end" }, truncateColumns("effort " + effortName, detailsWidth)),
|
|
32101
32295
|
(0, import_react.createElement)(Text, null, " "),
|
|
@@ -32306,7 +32500,7 @@ function deepseekWaveHues(tier) {
|
|
|
32306
32500
|
function StatusLine({ facts, stats, busy, columns, items }) {
|
|
32307
32501
|
const [, refreshMetrics] = (0, import_react.useState)(0);
|
|
32308
32502
|
(0, import_react.useEffect)(() => { const timer = setInterval(() => refreshMetrics(n => n + 1), 1000); return () => clearInterval(timer); }, []);
|
|
32309
|
-
facts = { ...facts, telemetry: columns >=
|
|
32503
|
+
facts = { ...facts, telemetry: columns >= 48 ? dscodeFooterFor(facts.fullSessionId, stats, Math.max(1, Math.min(columns - 8, Math.max(40, Math.floor(columns * 0.8) - 4)))) : "" };
|
|
32310
32504
|
const layout = (0, import_react.useMemo)(() => layoutStatusBar(facts, stats, Math.max(8, columns - 2), {
|
|
32311
32505
|
busy,
|
|
32312
32506
|
items,
|
|
@@ -32337,7 +32531,7 @@ function StatusLine({ facts, stats, busy, columns, items }) {
|
|
|
32337
32531
|
if (groupIndex > 0) leftParts.push((0, import_react.createElement)(Text, {
|
|
32338
32532
|
key: key + "gs" + groupIndex,
|
|
32339
32533
|
color: inkColor(getPalette().dim)
|
|
32340
|
-
}, "
|
|
32534
|
+
}, " | "));
|
|
32341
32535
|
group.spans.forEach((span, spanIndex) => {
|
|
32342
32536
|
leftParts.push((0, import_react.createElement)(Text, {
|
|
32343
32537
|
key: key + "g" + groupIndex + "s" + spanIndex,
|
|
@@ -32347,6 +32541,7 @@ function StatusLine({ facts, stats, busy, columns, items }) {
|
|
|
32347
32541
|
});
|
|
32348
32542
|
});
|
|
32349
32543
|
const rightParts = [];
|
|
32544
|
+
if (key === "s2" && row.left.length > 0 && row.right.length > 0) rightParts.push((0, import_react.createElement)(Text, { key: key + "divider", color: inkColor(getPalette().dim) }, "| "));
|
|
32350
32545
|
row.right.forEach((span, index) => {
|
|
32351
32546
|
if (index > 0) rightParts.push((0, import_react.createElement)(Text, {
|
|
32352
32547
|
key: key + "rs" + index,
|
|
@@ -32356,7 +32551,7 @@ function StatusLine({ facts, stats, busy, columns, items }) {
|
|
|
32356
32551
|
key: key + "r" + index,
|
|
32357
32552
|
wrap: "truncate-end",
|
|
32358
32553
|
...statusToneProps(span.tone)
|
|
32359
|
-
}, span.text));
|
|
32554
|
+
}, key === "s2" && index === 0 ? dscodeTelemetryNodes(span.text, key + "r" + index) : span.text));
|
|
32360
32555
|
});
|
|
32361
32556
|
if (row.hint) rightParts.push((0, import_react.createElement)(Text, {
|
|
32362
32557
|
key: key + "hint",
|
|
@@ -33820,7 +34015,7 @@ function HelpPanel({ descriptors, skills, commandError, skillError, onClose }) {
|
|
|
33820
34015
|
key: "key-cancel",
|
|
33821
34016
|
dimColor: true,
|
|
33822
34017
|
wrap: "truncate-end"
|
|
33823
|
-
}, "
|
|
34018
|
+
}, " ctrl+c stop running turn · ctrl+c again exit · ctrl+d exit"),
|
|
33824
34019
|
(0, import_react.createElement)(Text, {
|
|
33825
34020
|
key: "key-queue",
|
|
33826
34021
|
dimColor: true,
|
|
@@ -34340,7 +34535,7 @@ function CompletionMenu({ active, mention, index, rows, error }) {
|
|
|
34340
34535
|
* While a modal (approval / question / model panel) owns the keys, the
|
|
34341
34536
|
* box passes every key through untouched.
|
|
34342
34537
|
*/
|
|
34343
|
-
function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, skills, dispatch, steer, interrupt, quit, openEmail, emailFill, emailConsumed, openLogin, openModel, openEffort, openHelp, openMode, openPermission, openResume, openPlugin, openJobs, openStatusline, openTheme, openHistory, openAgents, openSubagent, openTodos, openDelete, openDiff, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, cyclePermission, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, cancelQueued, historyFill, historyConsumed, animations, applyAnimations, waveTier, waveStyle, maxRows, onEditorRows, onMenuRows, sessionKey }) {
|
|
34538
|
+
function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, skills, dispatch, steer, interrupt, quit, openEmail, emailFill, emailConsumed, openLogin, openModel, openEffort, openHelp, openMode, openPermission, openResume, openPlugin, openJobs, openStatusline, openTheme, openHistory, openAgents, openSubagent, openTodos, openDelete, openDiff, reviewChanges, deleteConfirm, confirmDelete, cancelDelete, createSession, forkSession, cancelSessionSwitch, notify, applyEditorKeys, hasNotice, dismissNotice, toggleReasoning, openVerbose, clearView, refresh, loadMentions, inspectImages, prepareImages, inspectFiles, prepareFiles, readClipboardImage, cyclePermission, exportTranscript, renameTitle, copyLastResponse, recallSpace, recordLocal, recordHistory, queued, cancelQueued, historyFill, historyConsumed, animations, applyAnimations, waveTier, waveStyle, maxRows, onEditorRows, onMenuRows, onTranscriptScroll, sessionKey }) {
|
|
34344
34539
|
const columns = useStdout().stdout?.columns ?? 80;
|
|
34345
34540
|
const inputTerminalRows = useStdout().stdout?.rows ?? 30;
|
|
34346
34541
|
const dscodeImeStdout = useStdout().stdout;
|
|
@@ -34357,6 +34552,8 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34357
34552
|
const [cursor, setCursor] = (0, import_react.useState)(0);
|
|
34358
34553
|
const valueRef = (0, import_react.useRef)(value);
|
|
34359
34554
|
const cursorRef = (0, import_react.useRef)(cursor);
|
|
34555
|
+
const pendingPastesRef = (0, import_react.useRef)(new Map());
|
|
34556
|
+
const ctrlCArmedRef = (0, import_react.useRef)(false);
|
|
34360
34557
|
valueRef.current = value;
|
|
34361
34558
|
cursorRef.current = cursor;
|
|
34362
34559
|
const [draftImages, setDraftImages] = (0, import_react.useState)([]);
|
|
@@ -34400,6 +34597,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34400
34597
|
(0, import_react.useEffect)(() => {
|
|
34401
34598
|
if (historyFill === void 0) return;
|
|
34402
34599
|
const safe = sanitizeDraftText(historyFill.text);
|
|
34600
|
+
pendingPastesRef.current.clear();
|
|
34403
34601
|
draftImagesRef.current = [];
|
|
34404
34602
|
setDraftImages([]);
|
|
34405
34603
|
draftFilesRef.current = [];
|
|
@@ -34436,6 +34634,9 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34436
34634
|
return next.length === current.length ? current : next;
|
|
34437
34635
|
});
|
|
34438
34636
|
}, [value]);
|
|
34637
|
+
(0, import_react.useEffect)(() => {
|
|
34638
|
+
for (const marker of pendingPastesRef.current.keys()) if (!value.includes(marker)) pendingPastesRef.current.delete(marker);
|
|
34639
|
+
}, [value]);
|
|
34439
34640
|
(0, import_react.useEffect)(() => {
|
|
34440
34641
|
if (stdin === void 0) return;
|
|
34441
34642
|
const originalRead = stdin.read.bind(stdin);
|
|
@@ -34481,11 +34682,12 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34481
34682
|
const uniqueImageMarker = (name, source, reserved = [], kind = "image") => {
|
|
34482
34683
|
const safeName = singleLineText(sanitizeDraftText(name));
|
|
34483
34684
|
const label = kind === "file" ? "file" : "image";
|
|
34484
|
-
|
|
34685
|
+
// dscode-image-marker-v1
|
|
34686
|
+
let marker = source === "mention" ? `@${safeName}` : kind === "image" ? "[Image 1]" : `[${label}: ${safeName}]`;
|
|
34485
34687
|
let suffix = 2;
|
|
34486
34688
|
const taken = (candidate) => valueRef.current.includes(candidate) || draftImagesRef.current.some((image) => image.marker === candidate) || draftFilesRef.current.some((file) => file.marker === candidate) || reserved.includes(candidate);
|
|
34487
34689
|
while (taken(marker)) {
|
|
34488
|
-
marker = source === "mention" ? `@${safeName} (${suffix})` : `[${label}: ${safeName} ${suffix}]`;
|
|
34690
|
+
marker = source === "mention" ? `@${safeName} (${suffix})` : kind === "image" ? `[Image ${suffix}]` : `[${label}: ${safeName} ${suffix}]`;
|
|
34489
34691
|
suffix += 1;
|
|
34490
34692
|
}
|
|
34491
34693
|
return marker;
|
|
@@ -34508,9 +34710,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34508
34710
|
* durable image blocks, files ride the 0.1.5 file blocks, and both register
|
|
34509
34711
|
* visible draft markers anchored at the drop point.
|
|
34510
34712
|
*/
|
|
34511
|
-
const insertDroppedAttachments = (imagePaths, filePaths) => {
|
|
34512
|
-
const originalValue = valueRef.current;
|
|
34513
|
-
const originalCursor = cursorRef.current;
|
|
34713
|
+
const insertDroppedAttachments = (imagePaths, filePaths, originalValue = valueRef.current, originalCursor = cursorRef.current) => {
|
|
34514
34714
|
const total = imagePaths.length + filePaths.length;
|
|
34515
34715
|
if (total === 0) return;
|
|
34516
34716
|
notify(`checking ${total} attachment${total === 1 ? "" : "s"}…`);
|
|
@@ -34695,6 +34895,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34695
34895
|
};
|
|
34696
34896
|
/** Apply one editor edit: draft, cursor, kill buffer, menu reset. */
|
|
34697
34897
|
const applyEdit = (edit) => {
|
|
34898
|
+
edit = pasteAtomicEdit(valueRef.current, edit, pendingPastesRef.current);
|
|
34698
34899
|
if (edit.killed !== void 0 && edit.killed !== "") killRef.current = edit.killed;
|
|
34699
34900
|
valueRef.current = edit.value;
|
|
34700
34901
|
cursorRef.current = edit.cursor;
|
|
@@ -34709,6 +34910,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34709
34910
|
const moveCursorTo = (next) => {
|
|
34710
34911
|
resetCursorBlink();
|
|
34711
34912
|
if (next === cursorRef.current) return;
|
|
34913
|
+
next = pasteCursorEdge(valueRef.current, cursorRef.current, next, pendingPastesRef.current);
|
|
34712
34914
|
cursorRef.current = next;
|
|
34713
34915
|
setCursor(next);
|
|
34714
34916
|
preferredColumnRef.current = null;
|
|
@@ -34719,23 +34921,24 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34719
34921
|
let nextCursor = cursorRef.current;
|
|
34720
34922
|
for (const token of tokens) {
|
|
34721
34923
|
if (token.kind === "text") {
|
|
34722
|
-
const edit = insertText(nextValue, nextCursor, token.text);
|
|
34924
|
+
const edit = pasteAtomicEdit(nextValue, insertText(nextValue, nextCursor, collapseLargePaste(token.text, nextValue, pendingPastesRef.current)), pendingPastesRef.current);
|
|
34723
34925
|
nextValue = edit.value;
|
|
34724
34926
|
nextCursor = edit.cursor;
|
|
34725
34927
|
continue;
|
|
34726
34928
|
}
|
|
34727
34929
|
if (token.kind === "home") {
|
|
34728
|
-
nextCursor = moveToLineStart(nextValue, nextCursor, false);
|
|
34930
|
+
nextCursor = pasteCursorEdge(nextValue, nextCursor, moveToLineStart(nextValue, nextCursor, false), pendingPastesRef.current);
|
|
34729
34931
|
continue;
|
|
34730
34932
|
}
|
|
34731
34933
|
if (token.kind === "end") {
|
|
34732
|
-
nextCursor = moveToLineEnd(nextValue, nextCursor, false);
|
|
34934
|
+
nextCursor = pasteCursorEdge(nextValue, nextCursor, moveToLineEnd(nextValue, nextCursor, false), pendingPastesRef.current);
|
|
34733
34935
|
continue;
|
|
34734
34936
|
}
|
|
34735
34937
|
const edit = token.kind === "delete-backward" ? deleteBackward(nextValue, nextCursor) : token.kind === "delete-word-backward" ? deleteWordBackward(nextValue, nextCursor) : token.kind === "delete-forward" ? deleteForward(nextValue, nextCursor) : deleteWordForward(nextValue, nextCursor);
|
|
34736
|
-
|
|
34737
|
-
|
|
34738
|
-
|
|
34938
|
+
const atomic = pasteAtomicEdit(nextValue, edit, pendingPastesRef.current);
|
|
34939
|
+
if (atomic.killed !== void 0 && atomic.killed !== "") killRef.current = atomic.killed;
|
|
34940
|
+
nextValue = atomic.value;
|
|
34941
|
+
nextCursor = atomic.cursor;
|
|
34739
34942
|
}
|
|
34740
34943
|
valueRef.current = nextValue;
|
|
34741
34944
|
cursorRef.current = nextCursor;
|
|
@@ -34762,8 +34965,9 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34762
34965
|
const preferred = preferredColumnRef.current ?? caretSite(model, currentCursor).column;
|
|
34763
34966
|
const next = moveCursorVertically(model, currentCursor, preferred, direction);
|
|
34764
34967
|
if (next !== currentCursor) {
|
|
34765
|
-
|
|
34766
|
-
|
|
34968
|
+
const edge = pasteCursorEdge(currentValue, currentCursor, next, pendingPastesRef.current);
|
|
34969
|
+
cursorRef.current = edge;
|
|
34970
|
+
setCursor(edge);
|
|
34767
34971
|
resetCursorBlink();
|
|
34768
34972
|
preferredColumnRef.current = preferred;
|
|
34769
34973
|
return;
|
|
@@ -34784,10 +34988,29 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34784
34988
|
resetCursorBlink();
|
|
34785
34989
|
};
|
|
34786
34990
|
useStableInput((input, key) => {
|
|
34787
|
-
|
|
34788
|
-
|
|
34789
|
-
|
|
34790
|
-
|
|
34991
|
+
if (!active && !(key.ctrl && input === "c")) { ctrlCArmedRef.current = false; return; }
|
|
34992
|
+
const liveValue = valueRef.current;
|
|
34993
|
+
const liveCursor = cursorRef.current;
|
|
34994
|
+
if (key.ctrl && input === "c") {
|
|
34995
|
+
const repeated = ctrlCArmedRef.current;
|
|
34996
|
+
const action = ctrlCAction(ctrlCArmedRef.current, { interrupt, busy, preparingImages, active: active && deleteConfirm === void 0, hasDraft: liveValue !== "" });
|
|
34997
|
+
ctrlCArmedRef.current = action !== "quit";
|
|
34998
|
+
if (action === "quit") quit(repeated);
|
|
34999
|
+
else if (action === "cancel-prepare") cancelImageSubmission();
|
|
35000
|
+
else if (action === "wait" && deleteConfirm !== void 0) cancelDelete();
|
|
35001
|
+
else if (action === "clear-draft") {
|
|
35002
|
+
pendingPastesRef.current.clear();
|
|
35003
|
+
valueRef.current = ""; cursorRef.current = 0;
|
|
35004
|
+
setValue(""); setCursor(0); resetCursorBlink();
|
|
35005
|
+
draftImagesRef.current = []; setDraftImages([]);
|
|
35006
|
+
draftFilesRef.current = []; setDraftFiles([]);
|
|
35007
|
+
setCompletionIndex(0); setDismissedMenuValue(void 0);
|
|
35008
|
+
}
|
|
35009
|
+
return;
|
|
35010
|
+
}
|
|
35011
|
+
ctrlCArmedRef.current = false;
|
|
35012
|
+
if (key.pageUp || key.pageDown) { onTranscriptScroll?.(key.pageUp ? 1 : -1, true); return; }
|
|
35013
|
+
if (preparingImages) {
|
|
34791
35014
|
if (key.escape || key.ctrl && input === "c") cancelImageSubmission();
|
|
34792
35015
|
return;
|
|
34793
35016
|
}
|
|
@@ -34810,27 +35033,16 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34810
35033
|
toggleReasoning();
|
|
34811
35034
|
return;
|
|
34812
35035
|
}
|
|
35036
|
+
if ((key.ctrl || key.meta) && input === "v") {
|
|
35037
|
+
const atValue = liveValue, atCursor = liveCursor;
|
|
35038
|
+
notify("reading clipboard image…");
|
|
35039
|
+
readClipboardImage().then(path => insertDroppedAttachments([path], [], atValue, atCursor), reason => notify(reason instanceof Error ? reason.message : String(reason), "warning"));
|
|
35040
|
+
return;
|
|
35041
|
+
}
|
|
34813
35042
|
if (key.ctrl && input === "o") {
|
|
34814
35043
|
openVerbose();
|
|
34815
35044
|
return;
|
|
34816
35045
|
}
|
|
34817
|
-
if (key.ctrl && input === "c") {
|
|
34818
|
-
if (busy) interrupt();
|
|
34819
|
-
else if (liveValue !== "") {
|
|
34820
|
-
valueRef.current = "";
|
|
34821
|
-
cursorRef.current = 0;
|
|
34822
|
-
setValue("");
|
|
34823
|
-
setCursor(0);
|
|
34824
|
-
resetCursorBlink();
|
|
34825
|
-
draftImagesRef.current = [];
|
|
34826
|
-
setDraftImages([]);
|
|
34827
|
-
draftFilesRef.current = [];
|
|
34828
|
-
setDraftFiles([]);
|
|
34829
|
-
setCompletionIndex(0);
|
|
34830
|
-
setDismissedMenuValue(void 0);
|
|
34831
|
-
} else quit();
|
|
34832
|
-
return;
|
|
34833
|
-
}
|
|
34834
35046
|
if (key.ctrl && input === "d") {
|
|
34835
35047
|
if (liveValue !== "") {
|
|
34836
35048
|
applyEdit(deleteForward(liveValue, liveCursor));
|
|
@@ -34873,8 +35085,9 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34873
35085
|
return;
|
|
34874
35086
|
}
|
|
34875
35087
|
}
|
|
34876
|
-
const
|
|
34877
|
-
|
|
35088
|
+
const expandedValue = expandLargePastes(liveValue, pendingPastesRef.current);
|
|
35089
|
+
const trimmed = expandedValue.trim();
|
|
35090
|
+
const text = submissionPayload(expandedValue);
|
|
34878
35091
|
if (/^\/email(?:\s|$)/.test(trimmed)) {
|
|
34879
35092
|
if (trimmed !== "/email") { notify("Use /email to open the inbox.", "warning"); return; }
|
|
34880
35093
|
valueRef.current = ""; cursorRef.current = 0;
|
|
@@ -34906,6 +35119,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34906
35119
|
if (controller.signal.aborted || prepareEpochRef.current !== epoch) return;
|
|
34907
35120
|
prepareAbortRef.current = void 0;
|
|
34908
35121
|
setPreparingImages(false);
|
|
35122
|
+
pendingPastesRef.current.clear();
|
|
34909
35123
|
valueRef.current = "";
|
|
34910
35124
|
cursorRef.current = 0;
|
|
34911
35125
|
setValue("");
|
|
@@ -34933,6 +35147,7 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34933
35147
|
});
|
|
34934
35148
|
return;
|
|
34935
35149
|
}
|
|
35150
|
+
pendingPastesRef.current.clear();
|
|
34936
35151
|
valueRef.current = "";
|
|
34937
35152
|
cursorRef.current = 0;
|
|
34938
35153
|
setValue("");
|
|
@@ -34979,7 +35194,8 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
34979
35194
|
return;
|
|
34980
35195
|
}
|
|
34981
35196
|
if (text === "/review" || text.startsWith("/review ")) {
|
|
34982
|
-
|
|
35197
|
+
// dscode-review-command-v1
|
|
35198
|
+
dispatch(text);
|
|
34983
35199
|
return;
|
|
34984
35200
|
}
|
|
34985
35201
|
if (text === "/model" || text.startsWith("/model ")) {
|
|
@@ -35176,12 +35392,12 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
35176
35392
|
clearTimeout(timer);
|
|
35177
35393
|
pasteBracketCancelRef.current = void 0;
|
|
35178
35394
|
};
|
|
35179
|
-
text = text.replaceAll(PASTE_START_MARKER, "");
|
|
35395
|
+
text = text.replaceAll(`\x1b${PASTE_START_MARKER}`, "").replaceAll(PASTE_START_MARKER, "");
|
|
35180
35396
|
}
|
|
35181
35397
|
if (text.includes("[201~")) {
|
|
35182
35398
|
pasteBracketRef.current = false;
|
|
35183
35399
|
pasteBracketCancelRef.current?.();
|
|
35184
|
-
text = text.replaceAll(PASTE_END_MARKER, "");
|
|
35400
|
+
text = text.replaceAll(`\x1b${PASTE_END_MARKER}`, "").replaceAll(PASTE_END_MARKER, "");
|
|
35185
35401
|
}
|
|
35186
35402
|
if (text === "") return;
|
|
35187
35403
|
if (text.length > 1) {
|
|
@@ -35191,9 +35407,9 @@ function Input({ effortSurface, ultraPulse, active, frozen, busy, descriptors, s
|
|
|
35191
35407
|
return;
|
|
35192
35408
|
}
|
|
35193
35409
|
}
|
|
35194
|
-
applyEdit(insertText(valueRef.current, cursorRef.current, text));
|
|
35410
|
+
applyEdit(insertText(valueRef.current, cursorRef.current, collapseLargePaste(text, valueRef.current, pendingPastesRef.current)));
|
|
35195
35411
|
}
|
|
35196
|
-
},
|
|
35412
|
+
}, true);
|
|
35197
35413
|
const waveKey = waveTier !== null && waveStyle !== null ? `${waveTier}:${waveStyle}` : null;
|
|
35198
35414
|
const [wavePlayedKey, setWavePlayedKey] = (0, import_react.useState)(null);
|
|
35199
35415
|
(0, import_react.useEffect)(() => {
|
|
@@ -35782,19 +35998,46 @@ function App(props) {
|
|
|
35782
35998
|
const composerEditorCap = composerMaxRows(terminalRows);
|
|
35783
35999
|
const transcriptVisible = !emailOpen && !modelOpen && !helpOpen && !modeOpen && !permissionOpen && !resumeOpen && !pluginOpen && !jobsOpen && !statuslineOpen && !themeOpen && !historyOpen && !agentsOpen && !subagentOpen && !todosOpen && !verboseOpen && diffView === void 0 && !approvalPending && !questionPending;
|
|
35784
36000
|
const welcomeFull = terminalRows >= 24 && terminalColumns >= 64;
|
|
35785
|
-
const
|
|
35786
|
-
|
|
35787
|
-
const
|
|
35788
|
-
const
|
|
36001
|
+
const welcomeMaxRows = welcomeFull ? terminalRows >= 26 ? 14 : 13 : terminalRows >= 10 ? 4 : 1;
|
|
36002
|
+
// The nine fixed rows belong to the composer, footer and their gutters.
|
|
36003
|
+
const transcriptCapacity = transcriptVisible ? Math.max(0, terminalRows - 9 - composerGutterRows - (composerRows - 1) - menuRows) : 0;
|
|
36004
|
+
const streamingActive = view.streaming !== "";
|
|
36005
|
+
const deepDivingVisible = busy;
|
|
36006
|
+
const allLiveLines = (0, import_react.useMemo)(() => view.entries.slice(settled).flatMap((entry) => dscodeChatLines(entry, Math.max(1, terminalColumns - 2))), [
|
|
36007
|
+
view.entries,
|
|
36008
|
+
settled,
|
|
36009
|
+
terminalColumns,
|
|
36010
|
+
showReasoning
|
|
36011
|
+
]);
|
|
36012
|
+
const allSettledLines = (0, import_react.useMemo)(() => visibleSettledLines(view.entries, settled, Infinity, terminalColumns, showReasoning, settledEntryLines), [settled, view.entries[settled - 1], terminalColumns, showReasoning]);
|
|
36013
|
+
const settledTail = allSettledLines.slice(-transcriptCapacity);
|
|
36014
|
+
const streamingDemand = streamingActive ? textLines(view.streaming.slice(-Math.max(1, terminalColumns * transcriptCapacity)), Math.max(10, terminalColumns - 2)).length : 0;
|
|
36015
|
+
const demand = settledTail.length + allLiveLines.length + streamingDemand + (busy ? 1 : 0) + (agentRows.length > 0 ? 1 : 0);
|
|
36016
|
+
const welcomeRows = welcomeVisibleRows(transcriptCapacity, welcomeMaxRows, demand, transcriptVisible);
|
|
36017
|
+
const settledBudget = transcriptVisible ? Math.max(0, transcriptCapacity - welcomeRows) : 0;
|
|
36018
|
+
const settledViewportRows = busy || streamingActive ? Math.floor(settledBudget / 3) : settledBudget;
|
|
36019
|
+
const [scrollOffset, setScrollOffset] = (0, import_react.useState)(0);
|
|
36020
|
+
const previousHistory = (0, import_react.useRef)({ sessionKey: props.sessionKey, count: allSettledLines.length });
|
|
36021
|
+
const sameHistory = previousHistory.current.sessionKey === props.sessionKey;
|
|
36022
|
+
const growth = sameHistory ? Math.max(0, allSettledLines.length - previousHistory.current.count) : 0;
|
|
36023
|
+
const maxScrollOffset = Math.max(0, allSettledLines.length - settledViewportRows);
|
|
36024
|
+
const effectiveScrollOffset = sameHistory ? Math.min(maxScrollOffset, scrollOffset === 0 ? 0 : scrollOffset + growth) : 0;
|
|
36025
|
+
(0, import_react.useEffect)(() => {
|
|
36026
|
+
previousHistory.current = { sessionKey: props.sessionKey, count: allSettledLines.length };
|
|
36027
|
+
if (scrollOffset !== effectiveScrollOffset) setScrollOffset(effectiveScrollOffset);
|
|
36028
|
+
}, [props.sessionKey, allSettledLines.length, effectiveScrollOffset]);
|
|
36029
|
+
const scrollTranscript = (direction, page = false) => {
|
|
36030
|
+
if (!transcriptVisible || settledViewportRows <= 0) return;
|
|
36031
|
+
const step = page ? Math.max(1, settledViewportRows - 1) : 3;
|
|
36032
|
+
setScrollOffset(current => Math.max(0, Math.min(maxScrollOffset, (current === scrollOffset ? effectiveScrollOffset : current) + direction * step)));
|
|
36033
|
+
};
|
|
36034
|
+
(0, import_react.useEffect)(() => {
|
|
36035
|
+
const listener = direction => scrollTranscript(direction);
|
|
36036
|
+
dscodeWheelListeners.add(listener);
|
|
36037
|
+
return () => dscodeWheelListeners.delete(listener);
|
|
36038
|
+
});
|
|
36039
|
+
const renderedSettled = transcriptWindow(allSettledLines, settledViewportRows, effectiveScrollOffset);
|
|
35789
36040
|
const dynamicRows = Math.max(0, settledBudget - settledViewportRows);
|
|
35790
|
-
const streamingActive = view.streaming !== "";
|
|
35791
|
-
const deepDivingVisible = busy;
|
|
35792
|
-
const allLiveLines = (0, import_react.useMemo)(() => view.entries.slice(settled).flatMap((entry) => dscodeChatLines(entry, Math.max(1, terminalColumns - 2))), [
|
|
35793
|
-
view.entries,
|
|
35794
|
-
settled,
|
|
35795
|
-
terminalColumns,
|
|
35796
|
-
showReasoning
|
|
35797
|
-
]);
|
|
35798
36041
|
const liveBudget = dynamicRows === 0 ? 0 : busy || streamingActive ? Math.max(1, Math.floor(dynamicRows / 3)) : Math.max(0, dynamicRows - (deepDivingVisible ? 1 : 0));
|
|
35799
36042
|
const visibleLiveLines = liveBudget === 0 ? [] : allLiveLines.slice(-liveBudget);
|
|
35800
36043
|
const streamRows = Math.max(1, dynamicRows - visibleLiveLines.length);
|
|
@@ -36062,7 +36305,8 @@ function App(props) {
|
|
|
36062
36305
|
});
|
|
36063
36306
|
}
|
|
36064
36307
|
return (0, import_react.createElement)(Box, { flexDirection: "column", height: Math.max(1, terminalRows - 1) },
|
|
36065
|
-
|
|
36308
|
+
welcomeRows > 0 ? (0, import_react.createElement)(Box, { height: welcomeRows, overflowY: "hidden", flexDirection: "column", justifyContent: "flex-end", flexShrink: 0 },
|
|
36309
|
+
(0, import_react.createElement)(Box, { flexShrink: 0 }, !emailOpen && terminalRows >= 10 ? (0, import_react.createElement)(Header, { cwd: props.workspaceRoot ?? props.cwd, model: modelLabel, effort: effortLabel }) : (0, import_react.createElement)(Text, { color: inkColor(getPalette().brandBright), bold: true }, "DSCODE"))) : void 0,
|
|
36066
36310
|
emailOpen && !approvalPending && !questionPending ? (0, import_react.createElement)(DscodeEmailPanel, {
|
|
36067
36311
|
gmail, imap, columns: terminalColumns, rows: Math.max(3, terminalRows - 8 - composerGutterRows - composerRows),
|
|
36068
36312
|
close: () => setEmailOpen(false),
|
|
@@ -36355,7 +36599,8 @@ function App(props) {
|
|
|
36355
36599
|
waveStyle,
|
|
36356
36600
|
maxRows: composerEditorCap,
|
|
36357
36601
|
onEditorRows: handleEditorRows,
|
|
36358
|
-
onMenuRows: handleMenuRows
|
|
36602
|
+
onMenuRows: handleMenuRows,
|
|
36603
|
+
onTranscriptScroll: scrollTranscript
|
|
36359
36604
|
}), (0, import_react.createElement)(StatusLine, {
|
|
36360
36605
|
facts: {
|
|
36361
36606
|
fullSessionId: props.sessionKey,
|
|
@@ -36588,7 +36833,7 @@ function createSplitStdin(source) {
|
|
|
36588
36833
|
stalePasteTimer.unref?.();
|
|
36589
36834
|
};
|
|
36590
36835
|
const onChunk = (chunk) => {
|
|
36591
|
-
for (const unit of splitter.push(String(chunk))) stream.write(unit);
|
|
36836
|
+
for (const unit of splitter.push(String(chunk))) if (!dscodeHandleMouseUnit(unit)) stream.write(unit);
|
|
36592
36837
|
if (splitter.openPaste()) armStalePasteTimer();
|
|
36593
36838
|
else disarmStalePasteTimer();
|
|
36594
36839
|
};
|
|
@@ -36633,7 +36878,7 @@ const internals = {
|
|
|
36633
36878
|
if (process.stdin.isTTY === true) process.stdin.setRawMode?.(true);
|
|
36634
36879
|
try {
|
|
36635
36880
|
if (process.stdout.isTTY === true) process.stdout.write("\x1B[r\x1B[0m\x1B[H\x1B[2J\x1B[3J\x1B[H");
|
|
36636
|
-
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_ENABLE : "") + BRACKETED_PASTE_ENABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_ENABLE : ""));
|
|
36881
|
+
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_ENABLE : "") + BRACKETED_PASTE_ENABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_ENABLE : "") + (process.stdout.isTTY === true ? DSCODE_MOUSE_ENABLE : ""));
|
|
36637
36882
|
const tuiStdin = createSplitStdin(process.stdin);
|
|
36638
36883
|
const instance = render(element, {
|
|
36639
36884
|
exitOnCtrlC: false,
|
|
@@ -36646,7 +36891,7 @@ const internals = {
|
|
|
36646
36891
|
},
|
|
36647
36892
|
unmount() {
|
|
36648
36893
|
try {
|
|
36649
|
-
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_DISABLE : "") + BRACKETED_PASTE_DISABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_DISABLE : ""));
|
|
36894
|
+
process.stdout.write((keyboardEnhanced ? KEYBOARD_ENHANCE_DISABLE : "") + BRACKETED_PASTE_DISABLE + (focusReporting ? TERMINAL_FOCUS_REPORT_DISABLE : "") + (process.stdout.isTTY === true ? DSCODE_MOUSE_DISABLE : ""));
|
|
36650
36895
|
} finally {
|
|
36651
36896
|
try {
|
|
36652
36897
|
instance.unmount();
|
|
@@ -36658,6 +36903,7 @@ const internals = {
|
|
|
36658
36903
|
}
|
|
36659
36904
|
};
|
|
36660
36905
|
} catch (error) {
|
|
36906
|
+
if (process.stdout.isTTY === true) process.stdout.write(DSCODE_MOUSE_DISABLE);
|
|
36661
36907
|
if (process.stdin.isTTY === true) process.stdin.setRawMode?.(false);
|
|
36662
36908
|
throw error;
|
|
36663
36909
|
}
|
|
@@ -38724,7 +38970,7 @@ async function run(ctx, startup, io) {
|
|
|
38724
38970
|
};
|
|
38725
38971
|
const mountRef = {};
|
|
38726
38972
|
let quitting = false;
|
|
38727
|
-
const quit = () => {
|
|
38973
|
+
const quit = (fast = false) => {
|
|
38728
38974
|
if (quitting) return;
|
|
38729
38975
|
quitting = true;
|
|
38730
38976
|
switchQueue.cancel();
|
|
@@ -38744,6 +38990,7 @@ async function run(ctx, startup, io) {
|
|
|
38744
38990
|
} catch (error) {
|
|
38745
38991
|
report("unmount", error);
|
|
38746
38992
|
}
|
|
38993
|
+
if (fast) setTimeout(() => process.exit(0), 250);
|
|
38747
38994
|
runQuitSequence([
|
|
38748
38995
|
...currentSession === void 0 || currentActive === void 0 ? [] : [{
|
|
38749
38996
|
name: "flush",
|
|
@@ -39451,6 +39698,7 @@ async function run(ctx, startup, io) {
|
|
|
39451
39698
|
openAuthorizationUrl,
|
|
39452
39699
|
copyTextValue: copyText,
|
|
39453
39700
|
loadMentions: (query, signal) => mentions.candidates(query, signal),
|
|
39701
|
+
readClipboardImage: dscodeReadClipboardImage,
|
|
39454
39702
|
inspectImages: (paths) => inspectImagePaths(paths, ctx.get("attachments"), session?.header.cwd ?? cwd),
|
|
39455
39703
|
prepareImages: (paths, signal) => saveImagePaths(paths, ctx.get("attachments"), signal),
|
|
39456
39704
|
inspectFiles: (paths) => inspectFilePaths(paths, ctx.get("attachments"), session?.header.cwd ?? cwd),
|