@crazyhappyone/dsh-tui 0.1.0-alpha.43 → 0.1.0-alpha.45
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/dist/index.js +215 -68
- package/dist/zen-proxy.js +27 -8
- package/package.json +2 -2
- package/tui/cordis.patch.yml +10 -0
package/dist/index.js
CHANGED
|
@@ -69421,25 +69421,44 @@ function renderCode(value, width, rowOffset, sourceStart) {
|
|
|
69421
69421
|
const lines = value.split("\n");
|
|
69422
69422
|
const out = [];
|
|
69423
69423
|
let row = rowOffset;
|
|
69424
|
+
const digits = Math.max(2, String(lines.length).length);
|
|
69425
|
+
const gutterWidth = digits + 4;
|
|
69426
|
+
const codeWidth = Math.max(1, width - gutterWidth);
|
|
69424
69427
|
for (const [index2, line5] of lines.entries()) {
|
|
69425
|
-
const
|
|
69428
|
+
const lineNum = index2 + 1;
|
|
69429
|
+
const gutterPrefix = ` ${String(lineNum).padStart(digits, " ")} \u2502 `;
|
|
69430
|
+
const continuationGutter = ` ${" ".repeat(digits)} \u2502 `;
|
|
69431
|
+
const wrapped = wrapDisplayLines(escapeContent(line5), codeWidth);
|
|
69426
69432
|
if (wrapped.length === 0) {
|
|
69427
|
-
|
|
69433
|
+
const buffer = makeBuffer();
|
|
69434
|
+
appendSegment(buffer, { text: gutterPrefix, token: "fgDim", bold: false });
|
|
69435
|
+
const emptyLine2 = freezeLine(buffer, row, index2 === 0 ? sourceStart : -1);
|
|
69436
|
+
out.push({
|
|
69437
|
+
...emptyLine2,
|
|
69438
|
+
background: "codeBg",
|
|
69439
|
+
backgroundColumns: Math.max(width, emptyLine2.displayWidth)
|
|
69440
|
+
});
|
|
69428
69441
|
row += 1;
|
|
69429
69442
|
continue;
|
|
69430
69443
|
}
|
|
69431
69444
|
for (const [partIndex, part] of wrapped.entries()) {
|
|
69432
69445
|
const buffer = makeBuffer();
|
|
69433
|
-
const
|
|
69446
|
+
const gutter = partIndex === 0 ? gutterPrefix : continuationGutter;
|
|
69447
|
+
appendSegment(buffer, { text: gutter, token: "fgDim", bold: false });
|
|
69448
|
+
const tokens = tokenizeCodeLine(part);
|
|
69434
69449
|
for (const tk of tokens) {
|
|
69435
69450
|
appendSegment(buffer, { text: tk.text, token: tk.token, bold: tk.bold });
|
|
69436
69451
|
}
|
|
69437
|
-
const
|
|
69452
|
+
const codeLine = freezeLine(
|
|
69438
69453
|
buffer,
|
|
69439
69454
|
row,
|
|
69440
69455
|
index2 === 0 && partIndex === 0 ? sourceStart : -1
|
|
69441
69456
|
);
|
|
69442
|
-
out.push({
|
|
69457
|
+
out.push({
|
|
69458
|
+
...codeLine,
|
|
69459
|
+
background: "codeBg",
|
|
69460
|
+
backgroundColumns: Math.max(width, codeLine.displayWidth)
|
|
69461
|
+
});
|
|
69443
69462
|
row += 1;
|
|
69444
69463
|
}
|
|
69445
69464
|
}
|
|
@@ -72510,6 +72529,7 @@ var ScreenAtlas = class {
|
|
|
72510
72529
|
snapshotRanges = [];
|
|
72511
72530
|
snapshotRows = /* @__PURE__ */ new Map();
|
|
72512
72531
|
snapshotRail;
|
|
72532
|
+
snapshotGeometry;
|
|
72513
72533
|
/**
|
|
72514
72534
|
* @param width - terminal columns.
|
|
72515
72535
|
* @param height - terminal rows.
|
|
@@ -72694,6 +72714,7 @@ var ScreenAtlas = class {
|
|
|
72694
72714
|
this.snapshotRanges = [];
|
|
72695
72715
|
this.snapshotRows.clear();
|
|
72696
72716
|
this.snapshotRail = snapshot.geometry.rail;
|
|
72717
|
+
this.snapshotGeometry = snapshot.geometry;
|
|
72697
72718
|
const saved = {
|
|
72698
72719
|
col: this.cursorCol,
|
|
72699
72720
|
row: this.cursorRow,
|
|
@@ -72764,6 +72785,34 @@ var ScreenAtlas = class {
|
|
|
72764
72785
|
}
|
|
72765
72786
|
return this.cells[(row - 1) * this.width + (col - 1)];
|
|
72766
72787
|
}
|
|
72788
|
+
/** Bounding terminal rows for the transcript content area. */
|
|
72789
|
+
get transcriptBounds() {
|
|
72790
|
+
if (this.snapshotGeometry !== void 0 && this.snapshotGeometry.rows >= 10) {
|
|
72791
|
+
const top = this.snapshotGeometry.transcriptTop;
|
|
72792
|
+
const rows = this.snapshotGeometry.transcriptRows;
|
|
72793
|
+
return { top, bottom: Math.max(top, top + rows - 1) };
|
|
72794
|
+
}
|
|
72795
|
+
return { top: 1, bottom: this.height };
|
|
72796
|
+
}
|
|
72797
|
+
/** Clamp screen point to selectable transcript rows and valid columns. */
|
|
72798
|
+
clampToTranscript(point3) {
|
|
72799
|
+
const { top, bottom } = this.transcriptBounds;
|
|
72800
|
+
return {
|
|
72801
|
+
col: Math.max(1, Math.min(this.width, point3.col)),
|
|
72802
|
+
row: Math.max(top, Math.min(bottom, point3.row))
|
|
72803
|
+
};
|
|
72804
|
+
}
|
|
72805
|
+
/** Plain text for a horizontal slice of one row with rail excluded. */
|
|
72806
|
+
extractRowText(row, fromCol = 1, toCol = this.width) {
|
|
72807
|
+
let line5 = "";
|
|
72808
|
+
for (let col = fromCol; col <= toCol; col++) {
|
|
72809
|
+
if (this.isSnapshotRailControlCell(col, row)) continue;
|
|
72810
|
+
const cell = this.cellAt(col, row);
|
|
72811
|
+
if (cell === void 0 || cell.ch === "") continue;
|
|
72812
|
+
line5 += cell.ch;
|
|
72813
|
+
}
|
|
72814
|
+
return line5.replace(/ +$/u, "");
|
|
72815
|
+
}
|
|
72767
72816
|
/**
|
|
72768
72817
|
* Reading-order plain text between two inclusive endpoints. Published rail
|
|
72769
72818
|
* cells are excluded, trailing spaces are trimmed, and rows join with `\n`.
|
|
@@ -72777,14 +72826,7 @@ var ScreenAtlas = class {
|
|
|
72777
72826
|
for (let row = start.row; row <= end.row; row++) {
|
|
72778
72827
|
const from2 = row === start.row ? start.col : 1;
|
|
72779
72828
|
const to = row === end.row ? end.col : this.width;
|
|
72780
|
-
|
|
72781
|
-
for (let col = from2; col <= to; col++) {
|
|
72782
|
-
if (this.isSnapshotRailControlCell(col, row)) continue;
|
|
72783
|
-
const cell = this.cellAt(col, row);
|
|
72784
|
-
if (cell === void 0 || cell.ch === "") continue;
|
|
72785
|
-
line5 += cell.ch;
|
|
72786
|
-
}
|
|
72787
|
-
lines.push(line5.replace(/ +$/u, ""));
|
|
72829
|
+
lines.push(this.extractRowText(row, from2, to));
|
|
72788
72830
|
}
|
|
72789
72831
|
return lines.join("\n");
|
|
72790
72832
|
}
|
|
@@ -73153,6 +73195,9 @@ var MouseSession = class {
|
|
|
73153
73195
|
selection;
|
|
73154
73196
|
paintedSelection;
|
|
73155
73197
|
railDrag;
|
|
73198
|
+
dragVirtualStartRow = 0;
|
|
73199
|
+
scrolledOffAbove = [];
|
|
73200
|
+
scrolledOffBelow = [];
|
|
73156
73201
|
edgeTimer;
|
|
73157
73202
|
openHref;
|
|
73158
73203
|
copy;
|
|
@@ -73180,7 +73225,7 @@ var MouseSession = class {
|
|
|
73180
73225
|
*/
|
|
73181
73226
|
handle(event) {
|
|
73182
73227
|
if (event.kind === "wheel" && event.delta !== void 0) {
|
|
73183
|
-
this.
|
|
73228
|
+
this.scroll(event.delta);
|
|
73184
73229
|
return "";
|
|
73185
73230
|
}
|
|
73186
73231
|
const point3 = { col: event.col, row: event.row };
|
|
@@ -73194,8 +73239,12 @@ var MouseSession = class {
|
|
|
73194
73239
|
this.onRail(railFraction(region, event.row));
|
|
73195
73240
|
return this.repaintSelection();
|
|
73196
73241
|
}
|
|
73197
|
-
|
|
73198
|
-
this.
|
|
73242
|
+
const clampedPoint = this.atlas.clampToTranscript(point3);
|
|
73243
|
+
this.drag = { start: clampedPoint, moved: false };
|
|
73244
|
+
this.dragVirtualStartRow = clampedPoint.row;
|
|
73245
|
+
this.scrolledOffAbove = [];
|
|
73246
|
+
this.scrolledOffBelow = [];
|
|
73247
|
+
this.selection = { start: clampedPoint, end: clampedPoint };
|
|
73199
73248
|
return "";
|
|
73200
73249
|
}
|
|
73201
73250
|
if (event.kind === "drag" && this.railDrag !== void 0 && event.button === "left") {
|
|
@@ -73208,27 +73257,52 @@ var MouseSession = class {
|
|
|
73208
73257
|
return "";
|
|
73209
73258
|
}
|
|
73210
73259
|
if (event.kind === "drag" && this.drag !== void 0 && event.button === "left") {
|
|
73211
|
-
|
|
73260
|
+
const clampedPoint = this.atlas.clampToTranscript(point3);
|
|
73261
|
+
if (clampedPoint.col !== this.drag.start.col || clampedPoint.row !== this.drag.start.row) {
|
|
73212
73262
|
this.drag.moved = true;
|
|
73213
73263
|
}
|
|
73214
|
-
|
|
73264
|
+
const { top, bottom } = this.atlas.transcriptBounds;
|
|
73265
|
+
const visualStartRow = Math.max(top, Math.min(bottom, this.dragVirtualStartRow));
|
|
73266
|
+
this.selection = {
|
|
73267
|
+
start: { col: this.drag.start.col, row: visualStartRow },
|
|
73268
|
+
end: clampedPoint
|
|
73269
|
+
};
|
|
73215
73270
|
this.syncEdge(event.row);
|
|
73216
73271
|
return this.repaintSelection();
|
|
73217
73272
|
}
|
|
73218
73273
|
if (event.kind === "release" && this.drag !== void 0) {
|
|
73219
73274
|
this.stopEdge();
|
|
73220
|
-
|
|
73275
|
+
const clampedPoint = this.atlas.clampToTranscript(point3);
|
|
73276
|
+
if (clampedPoint.col !== this.drag.start.col || clampedPoint.row !== this.drag.start.row) {
|
|
73221
73277
|
this.drag.moved = true;
|
|
73222
|
-
this.selection = { start: this.drag.start, end: point3 };
|
|
73223
73278
|
}
|
|
73279
|
+
const { top, bottom } = this.atlas.transcriptBounds;
|
|
73280
|
+
const visualStartRow = Math.max(top, Math.min(bottom, this.dragVirtualStartRow));
|
|
73281
|
+
this.selection = {
|
|
73282
|
+
start: { col: this.drag.start.col, row: visualStartRow },
|
|
73283
|
+
end: clampedPoint
|
|
73284
|
+
};
|
|
73224
73285
|
if (this.drag.moved) {
|
|
73225
73286
|
const range = this.selection;
|
|
73226
|
-
this.
|
|
73287
|
+
if (this.scrolledOffAbove.length === 0 && this.scrolledOffBelow.length === 0) {
|
|
73288
|
+
this.copy(this.atlas.extract(range.start, range.end));
|
|
73289
|
+
} else {
|
|
73290
|
+
const visibleText = this.atlas.extract(range.start, range.end);
|
|
73291
|
+
const parts = [];
|
|
73292
|
+
if (this.scrolledOffAbove.length > 0) parts.push(...this.scrolledOffAbove);
|
|
73293
|
+
if (visibleText.length > 0) parts.push(visibleText);
|
|
73294
|
+
if (this.scrolledOffBelow.length > 0) parts.push(...this.scrolledOffBelow);
|
|
73295
|
+
const textToCopy = parts.join("\n");
|
|
73296
|
+
if (textToCopy.length > 0) this.copy(textToCopy);
|
|
73297
|
+
}
|
|
73227
73298
|
} else {
|
|
73228
73299
|
const href = this.atlas.urlAt(event.col, event.row);
|
|
73229
73300
|
if (href !== void 0) this.openHref(href);
|
|
73230
73301
|
}
|
|
73231
73302
|
this.drag = void 0;
|
|
73303
|
+
this.dragVirtualStartRow = 0;
|
|
73304
|
+
this.scrolledOffAbove = [];
|
|
73305
|
+
this.scrolledOffBelow = [];
|
|
73232
73306
|
this.selection = void 0;
|
|
73233
73307
|
return this.repaintSelection();
|
|
73234
73308
|
}
|
|
@@ -73270,19 +73344,41 @@ var MouseSession = class {
|
|
|
73270
73344
|
this.railDrag = void 0;
|
|
73271
73345
|
}
|
|
73272
73346
|
syncEdge(row) {
|
|
73273
|
-
|
|
73274
|
-
const
|
|
73275
|
-
|
|
73347
|
+
if (this.atlas.height < 6) return;
|
|
73348
|
+
const top = 2;
|
|
73349
|
+
const bottom = this.atlas.height - 1;
|
|
73350
|
+
const atTop = row <= top;
|
|
73351
|
+
const atBottom = row >= bottom;
|
|
73352
|
+
if (!atTop && !atBottom) {
|
|
73276
73353
|
this.stopEdge();
|
|
73277
73354
|
return;
|
|
73278
73355
|
}
|
|
73279
|
-
const delta =
|
|
73356
|
+
const delta = atTop ? 1 : -1;
|
|
73280
73357
|
if (this.edgeTimer !== void 0) return;
|
|
73281
|
-
this.
|
|
73358
|
+
this.scroll(delta);
|
|
73282
73359
|
this.edgeTimer = this.startInterval(() => {
|
|
73283
|
-
this.
|
|
73360
|
+
this.scroll(delta);
|
|
73284
73361
|
}, 80);
|
|
73285
73362
|
}
|
|
73363
|
+
scroll(delta) {
|
|
73364
|
+
if (this.drag !== void 0 && this.drag.moved) {
|
|
73365
|
+
const { top, bottom } = this.atlas.transcriptBounds;
|
|
73366
|
+
if (delta > 0) {
|
|
73367
|
+
if (this.dragVirtualStartRow > bottom) {
|
|
73368
|
+
const text4 = this.atlas.extractRowText(bottom);
|
|
73369
|
+
if (text4.length > 0) this.scrolledOffBelow.unshift(text4);
|
|
73370
|
+
}
|
|
73371
|
+
this.dragVirtualStartRow += delta;
|
|
73372
|
+
} else if (delta < 0) {
|
|
73373
|
+
if (this.dragVirtualStartRow < top) {
|
|
73374
|
+
const text4 = this.atlas.extractRowText(top);
|
|
73375
|
+
if (text4.length > 0) this.scrolledOffAbove.push(text4);
|
|
73376
|
+
}
|
|
73377
|
+
this.dragVirtualStartRow += delta;
|
|
73378
|
+
}
|
|
73379
|
+
}
|
|
73380
|
+
this.onScroll(delta);
|
|
73381
|
+
}
|
|
73286
73382
|
stopEdge() {
|
|
73287
73383
|
if (this.edgeTimer === void 0) return;
|
|
73288
73384
|
this.stopInterval(this.edgeTimer);
|
|
@@ -79119,7 +79215,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
|
|
|
79119
79215
|
renaming: state.renaming
|
|
79120
79216
|
};
|
|
79121
79217
|
}
|
|
79122
|
-
if (commandMode && (keyInfo.downArrow || keyInfo.upArrow)) {
|
|
79218
|
+
if (commandMode && state.historyIndex === void 0 && (keyInfo.downArrow || keyInfo.upArrow)) {
|
|
79123
79219
|
const query = state.commandQuery ?? state.text.slice(1);
|
|
79124
79220
|
const count = filterCommands(commands, query).length;
|
|
79125
79221
|
const delta = keyInfo.downArrow ? 1 : -1;
|
|
@@ -79397,6 +79493,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
|
|
|
79397
79493
|
commandQuery: void 0,
|
|
79398
79494
|
prefixG: false,
|
|
79399
79495
|
renaming: state.renaming,
|
|
79496
|
+
commandDismissed: true,
|
|
79400
79497
|
caretIndex: nextText.length,
|
|
79401
79498
|
historyIndex: nextIndex,
|
|
79402
79499
|
historyDraft: savedDraft
|
|
@@ -79423,6 +79520,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
|
|
|
79423
79520
|
commandQuery: void 0,
|
|
79424
79521
|
prefixG: false,
|
|
79425
79522
|
renaming: state.renaming,
|
|
79523
|
+
commandDismissed: true,
|
|
79426
79524
|
caretIndex: nextText.length,
|
|
79427
79525
|
historyIndex: nextIndex,
|
|
79428
79526
|
historyDraft: state.historyDraft
|
|
@@ -79796,18 +79894,18 @@ function TuiLoop({
|
|
|
79796
79894
|
helpLinesRef.current = helpPane.lines;
|
|
79797
79895
|
const historyLengthRef = (0, import_react39.useRef)(model.history.length);
|
|
79798
79896
|
historyLengthRef.current = model.history.length;
|
|
79799
|
-
const
|
|
79897
|
+
const [sentHistory, setSentHistory] = (0, import_react39.useState)([]);
|
|
79800
79898
|
const inputHistory = (0, import_react39.useMemo)(() => {
|
|
79801
79899
|
const fromModel = model.history.filter((m) => m.kind === "user" && typeof m.text === "string" && m.text.trim().length > 0).map((m) => m.text);
|
|
79802
79900
|
const combined = [];
|
|
79803
|
-
for (const item of [...fromModel, ...
|
|
79901
|
+
for (const item of [...fromModel, ...sentHistory]) {
|
|
79804
79902
|
const trimmed = item.trim();
|
|
79805
79903
|
if (trimmed.length > 0 && combined.at(-1) !== trimmed) {
|
|
79806
79904
|
combined.push(trimmed);
|
|
79807
79905
|
}
|
|
79808
79906
|
}
|
|
79809
79907
|
return combined;
|
|
79810
|
-
}, [model.history]);
|
|
79908
|
+
}, [model.history, sentHistory]);
|
|
79811
79909
|
const chordTimerRef = (0, import_react39.useRef)(
|
|
79812
79910
|
void 0
|
|
79813
79911
|
);
|
|
@@ -79961,19 +80059,19 @@ function TuiLoop({
|
|
|
79961
80059
|
issueViewportCommand({ kind: "edge", edge: action.edge });
|
|
79962
80060
|
} else if (action.kind === "send") {
|
|
79963
80061
|
const trimmed = action.text.trim();
|
|
79964
|
-
if (trimmed.length > 0
|
|
79965
|
-
|
|
80062
|
+
if (trimmed.length > 0) {
|
|
80063
|
+
setSentHistory((prev) => prev.at(-1) === trimmed ? prev : [...prev, trimmed]);
|
|
79966
80064
|
}
|
|
79967
80065
|
issueViewportCommand({ kind: "reset" });
|
|
79968
80066
|
controller.dispatch(action);
|
|
79969
80067
|
} else if (action.kind === "command") {
|
|
79970
80068
|
const queryText = action.query.trim().startsWith("/") ? action.query.trim() : `/${action.query.trim()}`;
|
|
79971
|
-
if (queryText.length > 0
|
|
79972
|
-
|
|
80069
|
+
if (queryText.length > 0) {
|
|
80070
|
+
setSentHistory((prev) => prev.at(-1) === queryText ? prev : [...prev, queryText]);
|
|
79973
80071
|
}
|
|
79974
80072
|
controller.dispatch(action);
|
|
79975
80073
|
} else if (action.kind === "new-session" || action.kind === "select-session") {
|
|
79976
|
-
|
|
80074
|
+
setSentHistory([]);
|
|
79977
80075
|
issueViewportCommand({ kind: "reset" });
|
|
79978
80076
|
controller.dispatch(action);
|
|
79979
80077
|
} else if (action.kind === "intake-clipboard-image") {
|
|
@@ -80141,7 +80239,13 @@ function TuiLoop({
|
|
|
80141
80239
|
let status;
|
|
80142
80240
|
let statusRowCount;
|
|
80143
80241
|
if (feedback !== void 0) {
|
|
80144
|
-
|
|
80242
|
+
const rawLines = feedback.split("\n");
|
|
80243
|
+
const maxBudget = Math.max(1, Math.min(rawLines.length, Math.max(4, Math.floor((rows - 8) / 2))));
|
|
80244
|
+
const visibleLines = rawLines.slice(0, maxBudget);
|
|
80245
|
+
if (rawLines.length > maxBudget) {
|
|
80246
|
+
visibleLines[visibleLines.length - 1] = `${visibleLines[visibleLines.length - 1]} \u2026 (+${rawLines.length - maxBudget} \u884C)`;
|
|
80247
|
+
}
|
|
80248
|
+
statusRowCount = visibleLines.length;
|
|
80145
80249
|
status = (0, import_react39.createElement)(
|
|
80146
80250
|
Box_default,
|
|
80147
80251
|
{
|
|
@@ -80149,11 +80253,14 @@ function TuiLoop({
|
|
|
80149
80253
|
width: "100%",
|
|
80150
80254
|
backgroundColor: inkColor("bg")
|
|
80151
80255
|
},
|
|
80152
|
-
(
|
|
80153
|
-
|
|
80154
|
-
|
|
80155
|
-
|
|
80156
|
-
|
|
80256
|
+
...visibleLines.map((line5, index2) => {
|
|
80257
|
+
const painted = index2 === 0 ? feedbackLine(line5) : paintRow([styled(escapeContent(line5), line5.includes("*") || line5.includes("\u6D3B\u8DC3") ? "accentText" : "fg")]);
|
|
80258
|
+
return (0, import_react39.createElement)(
|
|
80259
|
+
Text,
|
|
80260
|
+
{ key: index2 },
|
|
80261
|
+
paintBackgroundRow([painted], "bg", columns)
|
|
80262
|
+
);
|
|
80263
|
+
})
|
|
80157
80264
|
);
|
|
80158
80265
|
} else if (adaptiveRows.length > 0) {
|
|
80159
80266
|
const goalLine = goalRuns === void 0 ? void 0 : `${goalRuns.head} \xB7 ${goalRuns.objective}`;
|
|
@@ -82205,6 +82312,7 @@ var LOCAL_COMMANDS = [
|
|
|
82205
82312
|
{ name: "key", description: "Set or update API key", input: { hint: "[KEY_NAME] <SECRET>" } },
|
|
82206
82313
|
{ name: "login", description: "Set or update API key", input: { hint: "[KEY_NAME] <SECRET>" } },
|
|
82207
82314
|
{ name: "model", description: "Switch the active model" },
|
|
82315
|
+
{ name: "new", description: "Start a new session" },
|
|
82208
82316
|
{ name: "reload", description: "Relaunch this process and resume the session" },
|
|
82209
82317
|
{ name: "resume", description: "Switch or resume a session" },
|
|
82210
82318
|
{ name: "settings", description: "Edit settings, catalogs, and General" }
|
|
@@ -82437,6 +82545,7 @@ var RuntimeController = class _RuntimeController {
|
|
|
82437
82545
|
modelOpen = false;
|
|
82438
82546
|
modelFilter = "";
|
|
82439
82547
|
modelRows = [];
|
|
82548
|
+
cachedModelRows;
|
|
82440
82549
|
modelSelectedIndex = 0;
|
|
82441
82550
|
modelStatus = "idle";
|
|
82442
82551
|
modelError;
|
|
@@ -84418,7 +84527,8 @@ var RuntimeController = class _RuntimeController {
|
|
|
84418
84527
|
turnEndReason: last.kind,
|
|
84419
84528
|
...last.abortCause === void 0 ? {} : { abortCause: last.abortCause },
|
|
84420
84529
|
...last.errorText === void 0 ? {} : { errorText: last.errorText },
|
|
84421
|
-
sessionTitle: this.notifySessionTitle()
|
|
84530
|
+
sessionTitle: this.notifySessionTitle(),
|
|
84531
|
+
currentPrompt: this.currentPromptText()
|
|
84422
84532
|
}));
|
|
84423
84533
|
}
|
|
84424
84534
|
/**
|
|
@@ -84433,7 +84543,8 @@ var RuntimeController = class _RuntimeController {
|
|
|
84433
84543
|
secondsSinceLastInput: this.secondsSinceLastInput(),
|
|
84434
84544
|
toolName: input.toolName,
|
|
84435
84545
|
questionText: input.questionText,
|
|
84436
|
-
sessionTitle: this.notifySessionTitle()
|
|
84546
|
+
sessionTitle: this.notifySessionTitle(),
|
|
84547
|
+
currentPrompt: this.currentPromptText()
|
|
84437
84548
|
}));
|
|
84438
84549
|
}
|
|
84439
84550
|
/**
|
|
@@ -84483,6 +84594,15 @@ var RuntimeController = class _RuntimeController {
|
|
|
84483
84594
|
notifySessionTitle() {
|
|
84484
84595
|
return this.session === void 0 ? void 0 : notifySessionTitle(getSessionEvents(this.session));
|
|
84485
84596
|
}
|
|
84597
|
+
currentPromptText() {
|
|
84598
|
+
if (this.session === void 0) return void 0;
|
|
84599
|
+
const events = getSessionEvents(this.session);
|
|
84600
|
+
if (!Array.isArray(events)) return void 0;
|
|
84601
|
+
const lastUser = events.findLast(isHumanUserMessage);
|
|
84602
|
+
if (lastUser === void 0) return void 0;
|
|
84603
|
+
const text4 = joinTextBlocks(lastUser.data.content, " ").trim();
|
|
84604
|
+
return text4.length > 0 ? text4 : void 0;
|
|
84605
|
+
}
|
|
84486
84606
|
/** Record local user input for the notification quiet window. */
|
|
84487
84607
|
noteUserActivity() {
|
|
84488
84608
|
this.lastInputAt = Date.now();
|
|
@@ -85271,6 +85391,12 @@ var RuntimeController = class _RuntimeController {
|
|
|
85271
85391
|
this.ownWork(this.exportLive(), "session export");
|
|
85272
85392
|
return;
|
|
85273
85393
|
}
|
|
85394
|
+
if (query === "new" || query === "new ") {
|
|
85395
|
+
if (this.blockingHead() !== void 0) return;
|
|
85396
|
+
this.closeOtherPanels();
|
|
85397
|
+
this.dispatch({ kind: "new-session" });
|
|
85398
|
+
return;
|
|
85399
|
+
}
|
|
85274
85400
|
if (query === "reload") {
|
|
85275
85401
|
this.requestReload();
|
|
85276
85402
|
return;
|
|
@@ -85351,7 +85477,7 @@ var RuntimeController = class _RuntimeController {
|
|
|
85351
85477
|
return;
|
|
85352
85478
|
}
|
|
85353
85479
|
if (execution.result.kind !== "success") {
|
|
85354
|
-
this.reportCommandFailure(
|
|
85480
|
+
this.reportCommandFailure(execution.result.text.trim());
|
|
85355
85481
|
return;
|
|
85356
85482
|
}
|
|
85357
85483
|
const text4 = execution.result.text;
|
|
@@ -85371,7 +85497,7 @@ var RuntimeController = class _RuntimeController {
|
|
|
85371
85497
|
if (wasPermission || wasPlanDirectory) this.emit();
|
|
85372
85498
|
return;
|
|
85373
85499
|
}
|
|
85374
|
-
this.setFeedback(`\u2713 ${
|
|
85500
|
+
this.setFeedback(`\u2713 ${text4.trim()}`);
|
|
85375
85501
|
},
|
|
85376
85502
|
(error51) => {
|
|
85377
85503
|
if (seq !== this.commandSeq) return;
|
|
@@ -86030,7 +86156,7 @@ var RuntimeController = class _RuntimeController {
|
|
|
86030
86156
|
"\u2191\u2193/jk \u6EDA\u52A8 \xB7 g s \u4F1A\u8BDD\u5217\u8868 \xB7 Tab \u8865\u5168 \xB7 Esc \u5173\u95ED \xB7 / \u547D\u4EE4 \xB7 @ \u63D0\u53CA",
|
|
86031
86157
|
"\u6EDA\u8F6E\u6EDA\u52A8 \xB7 \u70B9\u51FB\u6253\u5F00\u94FE\u63A5 \xB7 \u62D6\u9009\u590D\u5236",
|
|
86032
86158
|
"/plan \u8BA1\u5212 \xB7 /goal \u76EE\u6807 \xB7 /compact \u538B\u7F29",
|
|
86033
|
-
"/model \u6A21\u578B\u9009\u62E9 \xB7 /help \u5E2E\u52A9 \xB7 /export \u5BFC\u51FA\u4F1A\u8BDD \xB7 /settings \u8BBE\u7F6E \xB7 /resume \u4F1A\u8BDD \xB7 /reload \u91CD\u8F7D"
|
|
86159
|
+
"/model \u6A21\u578B\u9009\u62E9 \xB7 /new \u65B0\u4F1A\u8BDD \xB7 /help \u5E2E\u52A9 \xB7 /export \u5BFC\u51FA\u4F1A\u8BDD \xB7 /settings \u8BBE\u7F6E \xB7 /resume \u4F1A\u8BDD \xB7 /reload \u91CD\u8F7D"
|
|
86034
86160
|
];
|
|
86035
86161
|
}
|
|
86036
86162
|
/**
|
|
@@ -86048,11 +86174,21 @@ var RuntimeController = class _RuntimeController {
|
|
|
86048
86174
|
* the panel transients, then load the provider/model catalog concurrently.
|
|
86049
86175
|
*/
|
|
86050
86176
|
openModelPane() {
|
|
86051
|
-
this.resetModelState();
|
|
86052
86177
|
this.closeOtherPanels();
|
|
86178
|
+
this.modelFilter = "";
|
|
86179
|
+
this.modelSelectedIndex = 0;
|
|
86053
86180
|
this.modelOpen = true;
|
|
86181
|
+
if (this.cachedModelRows !== void 0 && this.cachedModelRows.length > 0) {
|
|
86182
|
+
this.modelRows = [...this.cachedModelRows];
|
|
86183
|
+
this.modelStatus = "idle";
|
|
86184
|
+
this.emit();
|
|
86185
|
+
this.ownWork(this.loadModelCatalog(true), "model catalog background refresh");
|
|
86186
|
+
return;
|
|
86187
|
+
}
|
|
86188
|
+
this.modelRows = [];
|
|
86189
|
+
this.modelStatus = "loading";
|
|
86054
86190
|
this.emit();
|
|
86055
|
-
this.ownWork(this.loadModelCatalog(), "model catalog load");
|
|
86191
|
+
this.ownWork(this.loadModelCatalog(false), "model catalog load");
|
|
86056
86192
|
}
|
|
86057
86193
|
/**
|
|
86058
86194
|
* The catalog rows narrowed by the live filter: case-insensitive substring
|
|
@@ -86074,18 +86210,22 @@ var RuntimeController = class _RuntimeController {
|
|
|
86074
86210
|
* degrades to a single `provider 当前默认` row carrying the live default
|
|
86075
86211
|
* model when the provider is the current one.
|
|
86076
86212
|
*/
|
|
86077
|
-
async loadModelCatalog() {
|
|
86213
|
+
async loadModelCatalog(isBackground = false) {
|
|
86078
86214
|
const seq = ++this.modelSeq;
|
|
86079
86215
|
const llm = this.ctx.get("llm");
|
|
86080
86216
|
const defaultModel = this.ctx.get("agentDefaultModel");
|
|
86081
86217
|
if (llm === void 0 || defaultModel === void 0) {
|
|
86082
|
-
|
|
86083
|
-
|
|
86084
|
-
|
|
86218
|
+
if (!isBackground) {
|
|
86219
|
+
this.modelStatus = "error";
|
|
86220
|
+
this.modelError = "\u6A21\u578B\u670D\u52A1\u4E0D\u53EF\u7528";
|
|
86221
|
+
this.emit();
|
|
86222
|
+
}
|
|
86085
86223
|
return;
|
|
86086
86224
|
}
|
|
86087
|
-
|
|
86088
|
-
|
|
86225
|
+
if (!isBackground) {
|
|
86226
|
+
this.modelStatus = "loading";
|
|
86227
|
+
this.emit();
|
|
86228
|
+
}
|
|
86089
86229
|
const current = defaultModel.currentSelection();
|
|
86090
86230
|
try {
|
|
86091
86231
|
const providers = llm.listProviders();
|
|
@@ -86107,7 +86247,9 @@ var RuntimeController = class _RuntimeController {
|
|
|
86107
86247
|
);
|
|
86108
86248
|
}));
|
|
86109
86249
|
if (seq !== this.modelSeq) return;
|
|
86110
|
-
|
|
86250
|
+
const rows = groups.flat();
|
|
86251
|
+
this.cachedModelRows = rows;
|
|
86252
|
+
this.modelRows = [...rows];
|
|
86111
86253
|
if (this.modelSelectedIndex >= this.modelRows.length) {
|
|
86112
86254
|
this.modelSelectedIndex = Math.max(0, this.modelRows.length - 1);
|
|
86113
86255
|
}
|
|
@@ -86116,10 +86258,12 @@ var RuntimeController = class _RuntimeController {
|
|
|
86116
86258
|
} catch (error51) {
|
|
86117
86259
|
if (seq !== this.modelSeq) return;
|
|
86118
86260
|
this.ctx.logger.warn(`model catalog load failed: ${String(error51)}`);
|
|
86119
|
-
|
|
86120
|
-
|
|
86121
|
-
|
|
86122
|
-
|
|
86261
|
+
if (!isBackground) {
|
|
86262
|
+
this.modelRows = [];
|
|
86263
|
+
this.modelStatus = "error";
|
|
86264
|
+
this.modelError = error51 instanceof Error ? error51.message : String(error51);
|
|
86265
|
+
this.emit();
|
|
86266
|
+
}
|
|
86123
86267
|
}
|
|
86124
86268
|
}
|
|
86125
86269
|
/** Fold one advertised model into a catalog row. */
|
|
@@ -86464,7 +86608,7 @@ var RuntimeController = class _RuntimeController {
|
|
|
86464
86608
|
isEmpty: isSessionEmpty(events)
|
|
86465
86609
|
};
|
|
86466
86610
|
} catch {
|
|
86467
|
-
return { id, title: id, updatedAt: 0, isEmpty:
|
|
86611
|
+
return { id, title: id, updatedAt: 0, isEmpty: true };
|
|
86468
86612
|
}
|
|
86469
86613
|
}
|
|
86470
86614
|
/** Queue the newest query and enter loading before its debounce delay. */
|
|
@@ -86935,9 +87079,16 @@ function foldTitle(events) {
|
|
|
86935
87079
|
if (!Array.isArray(events)) return void 0;
|
|
86936
87080
|
const folded = foldSessionTitle(events);
|
|
86937
87081
|
if (folded !== void 0) return folded.title;
|
|
86938
|
-
const
|
|
86939
|
-
if (
|
|
86940
|
-
const
|
|
87082
|
+
const userMessages = events.filter(isHumanUserMessage);
|
|
87083
|
+
if (userMessages.length > 0) {
|
|
87084
|
+
const nonGreeting = userMessages.find((m) => {
|
|
87085
|
+
const text5 = joinTextBlocks(m.data.content, " ").trim().toLowerCase();
|
|
87086
|
+
return !["\u4F60\u597D", "hello", "hi", "hey", "\u60A8\u597D", "test", "say hi"].includes(text5) && text5.length > 2;
|
|
87087
|
+
});
|
|
87088
|
+
const firstUser = userMessages[0];
|
|
87089
|
+
if (firstUser === void 0) return void 0;
|
|
87090
|
+
const chosenUser = nonGreeting ?? firstUser;
|
|
87091
|
+
const text4 = joinTextBlocks(chosenUser.data.content, " ");
|
|
86941
87092
|
const fallback = fallbackSessionTitle(
|
|
86942
87093
|
text4,
|
|
86943
87094
|
LIST_TITLE_MAX_WORDS,
|
|
@@ -86967,10 +87118,6 @@ function isSessionEmpty(events) {
|
|
|
86967
87118
|
if (isBootstrapOnlySession(events)) return true;
|
|
86968
87119
|
return !events.some(isHumanUserMessage) && foldTitle(events) === void 0;
|
|
86969
87120
|
}
|
|
86970
|
-
function firstLine2(text4) {
|
|
86971
|
-
const line5 = text4.split("\n", 1)[0];
|
|
86972
|
-
return line5.trimEnd();
|
|
86973
|
-
}
|
|
86974
87121
|
function planReviewOf(questions) {
|
|
86975
87122
|
if (questions.length !== 1) return void 0;
|
|
86976
87123
|
const question = questions[0];
|
package/dist/zen-proxy.js
CHANGED
|
@@ -814,6 +814,7 @@ defineMethod("transform", [
|
|
|
814
814
|
], ({ inner }, isInner) => inner.toString(isInner));
|
|
815
815
|
|
|
816
816
|
// ../dsh-tui/plugins/zen-proxy/index.js
|
|
817
|
+
import crypto from "node:crypto";
|
|
817
818
|
import http from "node:http";
|
|
818
819
|
import https from "node:https";
|
|
819
820
|
var name = "zen-proxy";
|
|
@@ -822,21 +823,30 @@ var Config = Schema.object({
|
|
|
822
823
|
port: Schema.number().default(4097),
|
|
823
824
|
upstreamHost: Schema.string().default("opencode.ai"),
|
|
824
825
|
upstreamBasePath: Schema.string().default("/zen/v1"),
|
|
825
|
-
userAgent: Schema.string().default("opencode/1.
|
|
826
|
+
userAgent: Schema.string().default("opencode/1.18.30"),
|
|
826
827
|
clientHeader: Schema.string().default("cli"),
|
|
827
828
|
projectHeader: Schema.string().default("global")
|
|
828
829
|
});
|
|
829
830
|
var inject = [];
|
|
830
|
-
var rnd = (p) => `${p}${
|
|
831
|
+
var rnd = (p) => `${p}${crypto.randomBytes(13).toString("hex")}`;
|
|
831
832
|
function apply(ctx, config) {
|
|
832
833
|
const server = http.createServer((req, res) => {
|
|
833
834
|
const { method, url } = req;
|
|
834
|
-
|
|
835
|
+
const parsed = new URL(url, "http://127.0.0.1");
|
|
836
|
+
const pathname = parsed.pathname.replace(/^(\/v1)+/, "/v1").replace(/\/+$/, "") || "/";
|
|
837
|
+
if (method === "GET" && (pathname === "/v1/models" || pathname === "/models")) {
|
|
835
838
|
forward(req, res, { method: "GET", path: `${config.upstreamBasePath}/models`, body: null });
|
|
836
839
|
return;
|
|
837
840
|
}
|
|
838
|
-
|
|
839
|
-
if (
|
|
841
|
+
let targetRoute = null;
|
|
842
|
+
if (pathname === "/v1/chat/completions" || pathname === "/chat/completions") {
|
|
843
|
+
targetRoute = "/chat/completions";
|
|
844
|
+
} else if (pathname === "/v1/responses" || pathname === "/responses") {
|
|
845
|
+
targetRoute = "/responses";
|
|
846
|
+
} else if (pathname === "/v1/messages" || pathname === "/messages") {
|
|
847
|
+
targetRoute = "/messages";
|
|
848
|
+
}
|
|
849
|
+
if (method !== "POST" || !targetRoute) {
|
|
840
850
|
res.writeHead(404, { "content-type": "application/json" });
|
|
841
851
|
res.end(JSON.stringify({ error: { type: "not_found", message: `zen-proxy: unsupported ${method} ${url}` } }));
|
|
842
852
|
return;
|
|
@@ -846,8 +856,7 @@ function apply(ctx, config) {
|
|
|
846
856
|
body += c;
|
|
847
857
|
});
|
|
848
858
|
req.on("end", () => {
|
|
849
|
-
|
|
850
|
-
forward(req, res, { method: "POST", path: `${config.upstreamBasePath}${upstreamPath}`, body });
|
|
859
|
+
forward(req, res, { method: "POST", path: `${config.upstreamBasePath}${targetRoute}`, body });
|
|
851
860
|
});
|
|
852
861
|
});
|
|
853
862
|
server.on("error", (error) => {
|
|
@@ -864,17 +873,27 @@ function apply(ctx, config) {
|
|
|
864
873
|
};
|
|
865
874
|
}, "zen-proxy.server");
|
|
866
875
|
function forward(req, res, { method, path, body }) {
|
|
876
|
+
const sessionId = rnd("ses_");
|
|
867
877
|
const headers = {
|
|
868
878
|
"content-type": "application/json",
|
|
869
879
|
"user-agent": config.userAgent,
|
|
870
880
|
"x-opencode-client": config.clientHeader,
|
|
871
881
|
"x-opencode-project": config.projectHeader,
|
|
872
|
-
"x-opencode-session":
|
|
882
|
+
"x-opencode-session": sessionId,
|
|
883
|
+
"x-session-id": sessionId,
|
|
873
884
|
"x-opencode-request": rnd("msg_")
|
|
874
885
|
};
|
|
875
886
|
if (req.headers.authorization !== void 0) {
|
|
876
887
|
headers.authorization = req.headers.authorization;
|
|
877
888
|
}
|
|
889
|
+
if (req.headers["anthropic-version"] !== void 0) {
|
|
890
|
+
headers["anthropic-version"] = req.headers["anthropic-version"];
|
|
891
|
+
} else if (path.endsWith("/messages")) {
|
|
892
|
+
headers["anthropic-version"] = "2023-06-01";
|
|
893
|
+
}
|
|
894
|
+
if (req.headers["anthropic-beta"] !== void 0) {
|
|
895
|
+
headers["anthropic-beta"] = req.headers["anthropic-beta"];
|
|
896
|
+
}
|
|
878
897
|
if (body !== null) {
|
|
879
898
|
headers["content-length"] = Buffer.byteLength(body);
|
|
880
899
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crazyhappyone/dsh-tui",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.45",
|
|
4
4
|
"description": "Source-runtime launcher for the DeepSeek Harness terminal interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"LICENSE"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"test": "node --test",
|
|
22
|
+
"test": "node --test tests/*.test.js",
|
|
23
23
|
"pack:check": "npm pack --dry-run --json"
|
|
24
24
|
},
|
|
25
25
|
"engines": {
|
package/tui/cordis.patch.yml
CHANGED
|
@@ -76,6 +76,16 @@
|
|
|
76
76
|
# pi-lens-ignore: YAML:0
|
|
77
77
|
model: !!js "process.env.DSH_MODEL ?? 'deepseek-v4-flash'"
|
|
78
78
|
|
|
79
|
+
# pi-lens-ignore: YAML:0
|
|
80
|
+
- id: session-title-llm
|
|
81
|
+
name: "@deepseek-ai/dsh-session-title-all-prompts-llm"
|
|
82
|
+
config:
|
|
83
|
+
targetWords: 5
|
|
84
|
+
targetCjkCharacters: 10
|
|
85
|
+
maxInputBytes: 16384
|
|
86
|
+
maxOutputTokens: 64
|
|
87
|
+
timeoutMs: 60000
|
|
88
|
+
|
|
79
89
|
- insert:
|
|
80
90
|
# Code Mode is a core execution capability, not a Web component.
|
|
81
91
|
- id: code-runtime
|