@wrongstack/tui 1.0.7 → 1.0.8
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 +49 -24
- package/dist/input-tokens.d.ts +0 -10
- package/dist/layout-engine.d.ts +1 -1
- package/dist/run-tui-options.d.ts +2 -0
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -25299,6 +25299,10 @@ var INLINE_TOKEN_SRC = `${ATTACHMENT_TOKEN_SRC}|${PROTOCOL_TOKEN_SRC}`;
|
|
|
25299
25299
|
var AT_END = new RegExp(`(?:${INLINE_TOKEN_SRC})$`, "i");
|
|
25300
25300
|
var AT_START = new RegExp(`^(?:${INLINE_TOKEN_SRC})`, "i");
|
|
25301
25301
|
var GLOBAL = new RegExp(INLINE_TOKEN_SRC, "gi");
|
|
25302
|
+
function rowWouldOverflow(rowChars, next, width) {
|
|
25303
|
+
if (!rowChars) return false;
|
|
25304
|
+
return displayWidth(rowChars + next) > width;
|
|
25305
|
+
}
|
|
25302
25306
|
function deleteTokenBackward(buffer, cursor) {
|
|
25303
25307
|
const m = buffer.slice(0, cursor).match(AT_END);
|
|
25304
25308
|
if (!m) return null;
|
|
@@ -25354,24 +25358,30 @@ function layoutInputRows(prompt, value, cursor, width) {
|
|
|
25354
25358
|
}
|
|
25355
25359
|
const rows = [];
|
|
25356
25360
|
let row = [];
|
|
25361
|
+
let rowChars = "";
|
|
25357
25362
|
for (const cell of cells) {
|
|
25358
25363
|
if (cell.ch === "\n") {
|
|
25359
25364
|
if (cell.cursor) {
|
|
25360
|
-
if (
|
|
25365
|
+
if (rowWouldOverflow(rowChars, " ", w)) {
|
|
25361
25366
|
rows.push(row);
|
|
25362
25367
|
row = [];
|
|
25368
|
+
rowChars = "";
|
|
25363
25369
|
}
|
|
25364
25370
|
row.push({ ch: " ", chip: false, prompt: false, cursor: true });
|
|
25371
|
+
rowChars += " ";
|
|
25365
25372
|
}
|
|
25366
25373
|
rows.push(row);
|
|
25367
25374
|
row = [];
|
|
25375
|
+
rowChars = "";
|
|
25368
25376
|
continue;
|
|
25369
25377
|
}
|
|
25370
|
-
|
|
25371
|
-
if (row.length >= w) {
|
|
25378
|
+
if (rowWouldOverflow(rowChars, cell.ch, w)) {
|
|
25372
25379
|
rows.push(row);
|
|
25373
25380
|
row = [];
|
|
25381
|
+
rowChars = "";
|
|
25374
25382
|
}
|
|
25383
|
+
row.push(cell);
|
|
25384
|
+
rowChars += cell.ch;
|
|
25375
25385
|
}
|
|
25376
25386
|
if (row.length > 0 || rows.length === 0) rows.push(row);
|
|
25377
25387
|
return rows;
|
|
@@ -25384,23 +25394,27 @@ function inputIndexAtRowCol(prompt, value, width, row, col) {
|
|
|
25384
25394
|
const rows = [];
|
|
25385
25395
|
const starts = [];
|
|
25386
25396
|
let cur = [];
|
|
25397
|
+
let curChars = "";
|
|
25387
25398
|
let curStart = 0;
|
|
25388
25399
|
for (const cell of flat) {
|
|
25389
25400
|
if (cell.ch === "\n") {
|
|
25390
25401
|
rows.push(cur);
|
|
25391
25402
|
starts.push(curStart);
|
|
25392
25403
|
cur = [];
|
|
25404
|
+
curChars = "";
|
|
25393
25405
|
curStart = cell.buf + 1;
|
|
25394
25406
|
continue;
|
|
25395
25407
|
}
|
|
25396
|
-
if (
|
|
25397
|
-
cur.push({ buf: cell.buf });
|
|
25398
|
-
if (cur.length >= w) {
|
|
25408
|
+
if (rowWouldOverflow(curChars, cell.ch, w)) {
|
|
25399
25409
|
rows.push(cur);
|
|
25400
25410
|
starts.push(curStart);
|
|
25401
25411
|
cur = [];
|
|
25412
|
+
curChars = "";
|
|
25402
25413
|
curStart = -1;
|
|
25403
25414
|
}
|
|
25415
|
+
if (cur.length === 0 && cell.buf >= 0) curStart = cell.buf;
|
|
25416
|
+
cur.push({ buf: cell.buf, ch: cell.ch });
|
|
25417
|
+
curChars += cell.ch;
|
|
25404
25418
|
}
|
|
25405
25419
|
if (cur.length > 0 || rows.length === 0) {
|
|
25406
25420
|
rows.push(cur);
|
|
@@ -25411,9 +25425,14 @@ function inputIndexAtRowCol(prompt, value, width, row, col) {
|
|
|
25411
25425
|
if (row >= rows.length) return value.length;
|
|
25412
25426
|
const r = rows[row];
|
|
25413
25427
|
const c = Math.max(0, col);
|
|
25414
|
-
|
|
25415
|
-
|
|
25416
|
-
|
|
25428
|
+
let visual = 0;
|
|
25429
|
+
for (const cell of r) {
|
|
25430
|
+
const span = displayWidth(cell.ch);
|
|
25431
|
+
const hit = span <= 0 ? visual === c : c >= visual && c < visual + span;
|
|
25432
|
+
if (hit) {
|
|
25433
|
+
return cell.buf < 0 ? 0 : clamp2(cell.buf);
|
|
25434
|
+
}
|
|
25435
|
+
visual += span;
|
|
25417
25436
|
}
|
|
25418
25437
|
for (let k = r.length - 1; k >= 0; k--) {
|
|
25419
25438
|
const b = r[k].buf;
|
|
@@ -26643,7 +26662,7 @@ function statusBarLineRow(opts) {
|
|
|
26643
26662
|
}
|
|
26644
26663
|
|
|
26645
26664
|
// src/layout-engine.ts
|
|
26646
|
-
var LAYOUT_VERSION =
|
|
26665
|
+
var LAYOUT_VERSION = 3;
|
|
26647
26666
|
var FALLBACK_ROWS = 3;
|
|
26648
26667
|
var MAX_ESTIMATE_ROWS = 2e3;
|
|
26649
26668
|
var MIN_CONTENT_WIDTH = 16;
|
|
@@ -26654,8 +26673,9 @@ function wrappedRows(text, width, maxRows = MAX_ESTIMATE_ROWS) {
|
|
|
26654
26673
|
let lineStart = 0;
|
|
26655
26674
|
for (let index = 0; index <= text.length; index++) {
|
|
26656
26675
|
if (index < text.length && text.charCodeAt(index) !== 10) continue;
|
|
26657
|
-
const
|
|
26658
|
-
|
|
26676
|
+
const line = text.slice(lineStart, index);
|
|
26677
|
+
const cols = displayWidth(line);
|
|
26678
|
+
rows += line.length === 0 ? 1 : Math.max(1, Math.ceil(cols / w));
|
|
26659
26679
|
if (rows >= maxRows) return maxRows;
|
|
26660
26680
|
lineStart = index + 1;
|
|
26661
26681
|
}
|
|
@@ -26676,12 +26696,8 @@ function computeEntryRows(kind, text, termWidth, meta) {
|
|
|
26676
26696
|
case "user": {
|
|
26677
26697
|
const contentWidth = w - 2;
|
|
26678
26698
|
const baseText = text;
|
|
26679
|
-
const
|
|
26680
|
-
|
|
26681
|
-
for (const line of lines) {
|
|
26682
|
-
rows += Math.max(1, Math.ceil(line.length / contentWidth));
|
|
26683
|
-
}
|
|
26684
|
-
return Math.max(1, rows + 1);
|
|
26699
|
+
const bodyRows = wrappedRows(baseText, contentWidth);
|
|
26700
|
+
return Math.max(1, bodyRows + 1);
|
|
26685
26701
|
}
|
|
26686
26702
|
// ── Assistant entry ──
|
|
26687
26703
|
// Header (1) + body (wrapped at contentWidth) + chrome (2: border + padding)
|
|
@@ -33805,9 +33821,9 @@ function validatePasteContent(content) {
|
|
|
33805
33821
|
var BEGIN = "[200~";
|
|
33806
33822
|
var END = "[201~";
|
|
33807
33823
|
var OVERFLOW_STATE = Object.freeze({ overflow: true });
|
|
33808
|
-
var BEGIN_RE = /\x1b?\[200
|
|
33809
|
-
var END_RE = /\x1b?\[201
|
|
33810
|
-
var PARTIAL_ANSI_RE = /^\[[\x30-\x3f]*[\x20-\x2f]*[
|
|
33824
|
+
var BEGIN_RE = /\x1b?\[200~/;
|
|
33825
|
+
var END_RE = /\x1b?\[201~/;
|
|
33826
|
+
var PARTIAL_ANSI_RE = /^\[[\x30-\x3f]*[\x20-\x2f]*[mHJKfA-Dhlnsu]$/;
|
|
33811
33827
|
var ANSI_RE2 = new RegExp(
|
|
33812
33828
|
[
|
|
33813
33829
|
// CSI: ESC [ params* intermediates* final
|
|
@@ -33847,15 +33863,23 @@ function feedPaste(accum, input) {
|
|
|
33847
33863
|
}
|
|
33848
33864
|
}
|
|
33849
33865
|
const combined = `${accum ?? ""}${input}`;
|
|
33850
|
-
const
|
|
33866
|
+
const stripOpeningBegin = accum === null || typeof accum === "string" && isMarkerPrefix(accum);
|
|
33867
|
+
let working = stripOpeningBegin ? combined.replace(BEGIN_RE, "") : combined;
|
|
33868
|
+
const endMatches = [...working.matchAll(new RegExp(END_RE, "g"))];
|
|
33869
|
+
const closed = endMatches.length > 0;
|
|
33870
|
+
if (closed) {
|
|
33871
|
+
const last = endMatches[endMatches.length - 1];
|
|
33872
|
+
if (last && last.index !== void 0) working = working.slice(0, last.index);
|
|
33873
|
+
}
|
|
33874
|
+
const stripped = working.replace(ANSI_RE2, "");
|
|
33851
33875
|
if (stripped.length > MAX_PASTE_CHARS) {
|
|
33852
33876
|
return {
|
|
33853
|
-
accum:
|
|
33877
|
+
accum: closed ? null : OVERFLOW_STATE,
|
|
33854
33878
|
complete: null,
|
|
33855
33879
|
error: `Paste rejected: exceeds ${MAX_PASTE_CHARS.toLocaleString()} characters.`
|
|
33856
33880
|
};
|
|
33857
33881
|
}
|
|
33858
|
-
if (
|
|
33882
|
+
if (closed) return { accum: null, complete: stripped };
|
|
33859
33883
|
return { accum: stripped, complete: null };
|
|
33860
33884
|
}
|
|
33861
33885
|
|
|
@@ -53069,6 +53093,7 @@ async function runTui(opts) {
|
|
|
53069
53093
|
getBrainData: opts.getBrainData,
|
|
53070
53094
|
onBrainRiskLevel: opts.onBrainRiskLevel,
|
|
53071
53095
|
brainPanelHost: opts.brainPanelHost,
|
|
53096
|
+
subagentModelsHost: opts.subagentModelsHost,
|
|
53072
53097
|
getShadowData: opts.getShadowData,
|
|
53073
53098
|
onShadowStart: opts.onShadowStart,
|
|
53074
53099
|
onShadowStop: opts.onShadowStop,
|
package/dist/input-tokens.d.ts
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Inline chip token grammar, shared by the editable input for chip rendering
|
|
3
|
-
* and whole-token cursor deletion. Attachment shapes stay in sync with the
|
|
4
|
-
* AttachmentStore placeholder regex in @wrongstack/core:
|
|
5
|
-
* - seq-keyed `[pasted|image|file #N …]` (a cosmetic suffix after the seq,
|
|
6
|
-
* e.g. `, 123 lines`, is tolerated; legacy `[file #N]` is included)
|
|
7
|
-
* - path-keyed `[file:<path>]`
|
|
8
|
-
* `[VIBE]` is a protocol chip: it renders and deletes as a token, but it is
|
|
9
|
-
* not an attachment and must stay in the prompt sent to the refiner/agent.
|
|
10
|
-
*/
|
|
11
1
|
/** Attachment placeholders only. Protocol tags must not be stripped as chips. */
|
|
12
2
|
export declare const ATTACHMENT_TOKEN_SRC = "\\[(?:pasted|image|file) #\\d+[^\\]]*\\]|\\[file:[^\\]]+\\]";
|
|
13
3
|
/** Protocol trigger rendered as a chip but kept in the prompt text. */
|
package/dist/layout-engine.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface LayoutSnapshot {
|
|
|
50
50
|
entries: Record<number, EntryLayout>;
|
|
51
51
|
}
|
|
52
52
|
/** Current layout computation version. Bump when the algorithm changes. */
|
|
53
|
-
export declare const LAYOUT_VERSION =
|
|
53
|
+
export declare const LAYOUT_VERSION = 3;
|
|
54
54
|
/** Default fallback row count for entries without computed layout. */
|
|
55
55
|
export declare const FALLBACK_ROWS = 3;
|
|
56
56
|
/**
|
|
@@ -425,6 +425,8 @@ export interface RunTuiOptions {
|
|
|
425
425
|
onBrainRiskLevel?: ((level: 'off' | 'low' | 'medium' | 'high' | 'all') => string | undefined) | undefined;
|
|
426
426
|
/** Full Brain settings editor bridge (live apply + persist to global config). */
|
|
427
427
|
brainPanelHost?: import('./brain-panel-model.js').BrainPanelHost | undefined;
|
|
428
|
+
/** Session-scoped model-lane bridge for the interactive `/subagent-models` panel. */
|
|
429
|
+
subagentModelsHost?: import('./subagent-models-panel-model.js').SubagentModelsPanelHost | undefined;
|
|
428
430
|
/** Get current Shadow Agent state. */
|
|
429
431
|
getShadowData?: (() => {
|
|
430
432
|
activeId: string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/tui",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack terminal UI: Ink-based interactive renderer with history, pickers, and slash menus.",
|
|
6
6
|
"repository": {
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"!dist/**/*.map"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@wrongstack/core": "1.0.
|
|
30
|
-
"@wrongstack/kanban": "1.0.
|
|
31
|
-
"@wrongstack/runtime": "1.0.
|
|
32
|
-
"@wrongstack/sage": "1.0.
|
|
33
|
-
"@wrongstack/sdd": "1.0.
|
|
34
|
-
"@wrongstack/tools": "1.0.
|
|
29
|
+
"@wrongstack/core": "1.0.8",
|
|
30
|
+
"@wrongstack/kanban": "1.0.8",
|
|
31
|
+
"@wrongstack/runtime": "1.0.8",
|
|
32
|
+
"@wrongstack/sage": "1.0.8",
|
|
33
|
+
"@wrongstack/sdd": "1.0.8",
|
|
34
|
+
"@wrongstack/tools": "1.0.8",
|
|
35
35
|
"ink": "7.1.1",
|
|
36
36
|
"react": "^19.2.8",
|
|
37
37
|
"string-width": "8.2.2",
|