@vincemakes/kiso-tui 0.46.2 → 0.47.1
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/ask-panel.d.ts +10 -5
- package/dist/ask-panel.js +109 -54
- package/dist/at-picker.d.ts +38 -68
- package/dist/at-picker.js +50 -141
- package/dist/compositor.d.ts +79 -10
- package/dist/compositor.js +339 -57
- package/dist/context-ledger.d.ts +28 -0
- package/dist/context-ledger.js +62 -0
- package/dist/editor.d.ts +17 -0
- package/dist/editor.js +76 -15
- package/dist/index.d.ts +10 -10
- package/dist/index.js +10 -10
- package/dist/lines.d.ts +11 -0
- package/dist/lines.js +38 -0
- package/dist/notice-meta.d.ts +25 -0
- package/dist/notice-meta.js +85 -0
- package/dist/panel-input.d.ts +2 -2
- package/dist/panel-input.js +70 -60
- package/dist/pick-input.d.ts +23 -3
- package/dist/pick-input.js +9 -29
- package/dist/session-picker.d.ts +37 -22
- package/dist/session-picker.js +270 -57
- package/dist/status.d.ts +73 -69
- package/dist/status.js +177 -96
- package/package.json +2 -2
package/dist/panel-input.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* one band, in an order the editor keeps in one place: the panel first,
|
|
7
7
|
* then the session picker, then the composer's own bands. What the
|
|
8
8
|
* panel may do to the composer is the `BandHost` surface and nothing
|
|
9
|
-
* else: it types its amend reason, its custom ask answer and
|
|
10
|
-
*
|
|
9
|
+
* else: it types its amend reason, its custom ask answer and a pick's
|
|
10
|
+
* filter into the composer, stashes the composer at open, restores it at
|
|
11
11
|
* close — that is the whole coupling, and it is visible here.
|
|
12
12
|
*
|
|
13
13
|
* DECLARED MOVE (S5, 2026-09-06): every method below stood in editor.ts
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* and the mouse hit. The bodies are the same; only the buffer access
|
|
17
17
|
* goes through the host.
|
|
18
18
|
*/
|
|
19
|
-
import {
|
|
19
|
+
import { panelOptions, pickList, pickWindowOf, saferDegradedNote, startLevel, stepLevel, } from "./approval-panel.js";
|
|
20
20
|
import { askCommitCustom, askKey, askOnCustomRow, askStart } from "./ask-panel.js";
|
|
21
21
|
export class PanelInput {
|
|
22
22
|
host;
|
|
@@ -52,7 +52,7 @@ export class PanelInput {
|
|
|
52
52
|
safer: opts?.safer,
|
|
53
53
|
saferRun: null,
|
|
54
54
|
ask: view.ask === undefined ? null : askStart(view.ask),
|
|
55
|
-
pick: view.pick === undefined ? null : { cursor: start,
|
|
55
|
+
pick: view.pick === undefined ? null : { cursor: start, level: startLevel(view.pick.options[start]) },
|
|
56
56
|
onCommit,
|
|
57
57
|
stash: this.host.stash(),
|
|
58
58
|
};
|
|
@@ -78,9 +78,20 @@ export class PanelInput {
|
|
|
78
78
|
...(panel.note === null ? {} : { note: panel.note }),
|
|
79
79
|
...(panel.saferRun === null ? {} : { safer: panel.saferRun }),
|
|
80
80
|
...(panel.ask === null ? {} : { ask: panel.ask }),
|
|
81
|
-
...(panel.pick === null ? {} : { pick: panel.pick }),
|
|
81
|
+
...(panel.pick === null ? {} : { pick: this.#pickNow(panel.view, panel.pick) }),
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
+
/** The pick's runtime as the renderer and the keys read it (Graphite
|
|
85
|
+
* P3): a filter's query is the composer's text, read now, and the
|
|
86
|
+
* cursor and level are the CORRECTED ones — a row the filter took away
|
|
87
|
+
* is never reported as the selection. */
|
|
88
|
+
#pickNow(view, pick) {
|
|
89
|
+
const now = view.pick?.input === "filter" ? { ...pick, query: this.host.line() } : pick;
|
|
90
|
+
if (view.pick === undefined)
|
|
91
|
+
return now;
|
|
92
|
+
const list = pickList(view.pick, now);
|
|
93
|
+
return { ...now, cursor: list.cursor, level: list.level };
|
|
94
|
+
}
|
|
84
95
|
/**
|
|
85
96
|
* A parsed key while the panel is up. Returns the bytes it consumed,
|
|
86
97
|
* or null when the key falls through to the composer — the amend
|
|
@@ -97,14 +108,16 @@ export class PanelInput {
|
|
|
97
108
|
return null;
|
|
98
109
|
const enterBytes = key.kind === "enter" && key.crlf ? 2 : 1;
|
|
99
110
|
if (panel.pick !== null) {
|
|
100
|
-
const
|
|
111
|
+
const filter = panel.view.pick?.input === "filter";
|
|
101
112
|
if (key.kind === "esc") {
|
|
102
|
-
this.#
|
|
113
|
+
this.#close({ action: "cancel" });
|
|
103
114
|
return 1;
|
|
104
115
|
}
|
|
105
116
|
if (key.kind === "enter") {
|
|
106
117
|
if (pasting) {
|
|
107
|
-
|
|
118
|
+
// a pasted line break is not a pick, and a filter is one line
|
|
119
|
+
if (!filter)
|
|
120
|
+
this.host.newline();
|
|
108
121
|
return enterBytes;
|
|
109
122
|
}
|
|
110
123
|
this.#pickPanelEnter();
|
|
@@ -112,20 +125,27 @@ export class PanelInput {
|
|
|
112
125
|
}
|
|
113
126
|
if (key.kind === "char") {
|
|
114
127
|
const c = key.ch;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
128
|
+
// Graphite P3: a filter takes every printable key — a digit or an
|
|
129
|
+
// `h` is a letter of a model name there. Backspace and the
|
|
130
|
+
// composer's other editing keys fall through to the composer,
|
|
131
|
+
// and the list re-derives from its text on the next read.
|
|
132
|
+
if (filter) {
|
|
133
|
+
if (c >= " " && c !== "\x7f") {
|
|
134
|
+
this.host.insert(c.codePointAt(0));
|
|
135
|
+
this.host.render();
|
|
136
|
+
return 1;
|
|
137
|
+
}
|
|
118
138
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
this
|
|
125
|
-
|
|
139
|
+
else {
|
|
140
|
+
if ((panel.view.pick?.input ?? "digits") === "digits" && c >= "1" && c <= "9") {
|
|
141
|
+
this.#pickPanelDigit(Number(c) - 1);
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
if ((c === "h" || c === "l") && this.#levelStep(c === "h" ? -1 : 1))
|
|
145
|
+
return 1;
|
|
146
|
+
if (c >= " " && c !== "\x7f")
|
|
147
|
+
return 1;
|
|
126
148
|
}
|
|
127
|
-
if (!typing && c >= " " && c !== "\x7f")
|
|
128
|
-
return 1;
|
|
129
149
|
}
|
|
130
150
|
}
|
|
131
151
|
if (panel.ask !== null) {
|
|
@@ -208,19 +228,20 @@ export class PanelInput {
|
|
|
208
228
|
const panel = this.#panel;
|
|
209
229
|
if (panel === null)
|
|
210
230
|
return false;
|
|
211
|
-
if (panel.pick !== null
|
|
231
|
+
if (panel.pick !== null) {
|
|
212
232
|
// DC-58: EVERY option is reachable by ↑↓ — the window follows the
|
|
213
|
-
// cursor
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
const
|
|
217
|
-
const
|
|
218
|
-
const
|
|
233
|
+
// cursor. P3: the walk is over what the list SHOWS (a filter's
|
|
234
|
+
// matches, then the direct row), so ↑↓ never lands on a row the
|
|
235
|
+
// person cannot see.
|
|
236
|
+
const list = pickList(panel.view.pick, this.#pickNow(panel.view, panel.pick));
|
|
237
|
+
const at = list.shown.indexOf(list.cursor);
|
|
238
|
+
const to = list.shown[dir === "up" ? Math.max(0, at - 1) : Math.min(list.shown.length - 1, at + 1)];
|
|
219
239
|
// OR-7: the second axis belongs to the highlighted option, so it
|
|
220
240
|
// re-lands on THAT option's own level. Carrying the previous
|
|
221
241
|
// row's index across would point at a level this model may not
|
|
222
242
|
// have — the silent clamp the coordination note exists to end.
|
|
223
|
-
|
|
243
|
+
if (to !== undefined)
|
|
244
|
+
panel.pick = { cursor: to, level: startLevel(panel.view.pick.options[to]) };
|
|
224
245
|
}
|
|
225
246
|
else if (panel.ask !== null && panel.ask.phase === "options")
|
|
226
247
|
this.#askStep(dir);
|
|
@@ -252,12 +273,13 @@ export class PanelInput {
|
|
|
252
273
|
* no axis to walk, which is what leaves the key to the composer. */
|
|
253
274
|
#levelStep(dir) {
|
|
254
275
|
const panel = this.#panel;
|
|
255
|
-
if (panel === null || panel.pick === null
|
|
276
|
+
if (panel === null || panel.pick === null)
|
|
256
277
|
return false;
|
|
257
|
-
const
|
|
258
|
-
|
|
278
|
+
const list = pickList(panel.view.pick, this.#pickNow(panel.view, panel.pick));
|
|
279
|
+
const o = panel.view.pick.options[list.cursor];
|
|
280
|
+
if (o?.levels === undefined || o.levels.length === 0)
|
|
259
281
|
return false;
|
|
260
|
-
panel.pick = { cursor:
|
|
282
|
+
panel.pick = { cursor: list.cursor, level: stepLevel(o, list.level, dir) };
|
|
261
283
|
this.host.render();
|
|
262
284
|
return true;
|
|
263
285
|
}
|
|
@@ -455,47 +477,35 @@ export class PanelInput {
|
|
|
455
477
|
const panel = this.#panel;
|
|
456
478
|
if (panel === null || panel.pick === null)
|
|
457
479
|
return;
|
|
458
|
-
const count = panel.view.pick.options.length;
|
|
459
480
|
// DC-58: a digit names the row ON SCREEN. The window's origin is what
|
|
460
|
-
// turns a visible position into an option
|
|
461
|
-
//
|
|
462
|
-
//
|
|
463
|
-
const
|
|
481
|
+
// turns a visible position into an option — the same window the
|
|
482
|
+
// renderer drew the rows with, so what the row says and what the key
|
|
483
|
+
// does cannot drift apart.
|
|
484
|
+
const now = this.#pickNow(panel.view, panel.pick);
|
|
485
|
+
const { first, size } = this.host.pickWindow?.() ?? pickWindowOf(panel.view, now, Number.MAX_SAFE_INTEGER, process.stdout.rows ?? 24);
|
|
464
486
|
if (index < 0 || index >= size)
|
|
465
487
|
return;
|
|
466
|
-
const target = first + index;
|
|
467
|
-
if (target >=
|
|
488
|
+
const target = pickList(panel.view.pick, now).shown[first + index];
|
|
489
|
+
if (target === undefined || target >= panel.view.pick.options.length)
|
|
468
490
|
return;
|
|
469
|
-
panel.pick = { cursor: target,
|
|
491
|
+
panel.pick = { cursor: target, level: startLevel(panel.view.pick.options[target]) };
|
|
470
492
|
this.host.render();
|
|
471
493
|
}
|
|
472
494
|
#pickPanelEnter() {
|
|
473
495
|
const panel = this.#panel;
|
|
474
496
|
if (panel === null || panel.pick === null)
|
|
475
497
|
return;
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if (line === "")
|
|
479
|
-
return;
|
|
480
|
-
this.#close({ action: "picked", result: { custom: line } });
|
|
481
|
-
return;
|
|
482
|
-
}
|
|
483
|
-
if (panel.view.pick.options.length === 0)
|
|
498
|
+
const list = pickList(panel.view.pick, this.#pickNow(panel.view, panel.pick));
|
|
499
|
+
if (list.cursor < 0)
|
|
484
500
|
return; // nothing to take
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
const panel = this.#panel;
|
|
490
|
-
if (panel === null || panel.pick === null)
|
|
491
|
-
return;
|
|
492
|
-
if (panel.pick.phase === "custom") {
|
|
493
|
-
panel.pick = { cursor: panel.pick.cursor, phase: "options", level: panel.pick.level };
|
|
494
|
-
this.host.clear();
|
|
495
|
-
this.host.render();
|
|
501
|
+
// P3: the direct row hands back what was typed — the old `t` row's result
|
|
502
|
+
if (list.cursor === panel.view.pick.options.length) {
|
|
503
|
+
if (list.direct !== null)
|
|
504
|
+
this.#close({ action: "picked", result: { custom: list.direct } });
|
|
496
505
|
return;
|
|
497
506
|
}
|
|
498
|
-
|
|
507
|
+
const level = list.level;
|
|
508
|
+
this.#close({ action: "picked", result: { index: list.cursor }, ...(level === null ? {} : { level }) });
|
|
499
509
|
}
|
|
500
510
|
/** Close: the state is cleared FIRST, the stashed composer comes
|
|
501
511
|
* back, the Enter that closed the panel is swallowed, and only then
|
package/dist/pick-input.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The SESSION PICKER's input controller — S5 (finding C10). TUI2-R2 ②:
|
|
3
|
+
* the band's third occupant. Its filter is the @ picker's rank aimed at
|
|
4
|
+
* the session id; this controller owns the keys, the compositor draws
|
|
5
|
+
* the rows.
|
|
6
|
+
*
|
|
7
|
+
* The picker is MODAL in a way the @ picker is not: it opens before a
|
|
8
|
+
* session exists, owns the whole composer (the buffer IS the filter
|
|
9
|
+
* query, derived on every read rather than stored, so every buffer op —
|
|
10
|
+
* backspace, the kills, paste — filters correctly with no handler of
|
|
11
|
+
* its own), and the only ways out are a pick and an esc. That is why
|
|
12
|
+
* the commit callback lives here rather than on the line channel: the
|
|
13
|
+
* caller is waiting for an id, not for a turn.
|
|
14
|
+
*
|
|
15
|
+
* DECLARED MOVE (S5, 2026-09-06): `beginPick`, `#pickView`, `pickState`,
|
|
16
|
+
* `#pickUp`, `#pickRows`, `#pickClose`, `#pickAccept` and the ↑↓ branch
|
|
17
|
+
* stood in editor.ts; the bodies are the same, the buffer access goes
|
|
18
|
+
* through the host.
|
|
19
|
+
*/
|
|
1
20
|
import type { BandHost } from "./panel-input.js";
|
|
2
21
|
import { type SessionCardView, type SessionPickState } from "./session-picker.js";
|
|
3
22
|
export declare class PickInput {
|
|
@@ -20,9 +39,10 @@ export declare class PickInput {
|
|
|
20
39
|
* key (the buffer IS the query), so the toggle cannot be one. True when
|
|
21
40
|
* the picker owned the key. */
|
|
22
41
|
toggleScope(): boolean;
|
|
23
|
-
/** The band's height estimate: the header
|
|
24
|
-
* the one "no match" row)
|
|
25
|
-
|
|
42
|
+
/** The band's height estimate: the header, the windowed rows and the
|
|
43
|
+
* selected row's opened second row (or the one "no match" row), and
|
|
44
|
+
* the key row — sessionPickerRows' shape at this terminal height. */
|
|
45
|
+
rows(height: number): number;
|
|
26
46
|
/** ↑↓: the selection walks the matches and stops at both ends. True
|
|
27
47
|
* when the picker owned the key (the caller renders). */
|
|
28
48
|
arrow(dir: "up" | "down"): boolean;
|
package/dist/pick-input.js
CHANGED
|
@@ -1,24 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* The SESSION PICKER's input controller — S5 (finding C10). TUI2-R2 ②:
|
|
3
|
-
* the band's third occupant. Its filter is the @ picker's rank aimed at
|
|
4
|
-
* the session id; this controller owns the keys, the compositor draws
|
|
5
|
-
* the rows.
|
|
6
|
-
*
|
|
7
|
-
* The picker is MODAL in a way the @ picker is not: it opens before a
|
|
8
|
-
* session exists, owns the whole composer (the buffer IS the filter
|
|
9
|
-
* query, derived on every read rather than stored, so every buffer op —
|
|
10
|
-
* backspace, the kills, paste — filters correctly with no handler of
|
|
11
|
-
* its own), and the only ways out are a pick and an esc. That is why
|
|
12
|
-
* the commit callback lives here rather than on the line channel: the
|
|
13
|
-
* caller is waiting for an id, not for a turn.
|
|
14
|
-
*
|
|
15
|
-
* DECLARED MOVE (S5, 2026-09-06): `beginPick`, `#pickView`, `pickState`,
|
|
16
|
-
* `#pickUp`, `#pickRows`, `#pickClose`, `#pickAccept` and the ↑↓ branch
|
|
17
|
-
* stood in editor.ts; the bodies are the same, the buffer access goes
|
|
18
|
-
* through the host.
|
|
19
|
-
*/
|
|
20
|
-
import { AT_VISIBLE } from "./at-picker.js";
|
|
21
|
-
import { scopeSessions, sessionFilter } from "./session-picker.js";
|
|
1
|
+
import { resumeVisible, scopeSessions, sessionFilter } from "./session-picker.js";
|
|
22
2
|
export class PickInput {
|
|
23
3
|
host;
|
|
24
4
|
#cards = null;
|
|
@@ -61,8 +41,9 @@ export class PickInput {
|
|
|
61
41
|
// title says is showing, never reaches past it
|
|
62
42
|
const scoped = this.#here === undefined ? null : scopeSessions(this.#cards(), this.#here, this.#all);
|
|
63
43
|
const cards = scoped === null ? this.#cards() : scoped.cards;
|
|
64
|
-
const
|
|
65
|
-
|
|
44
|
+
const query = this.host.line();
|
|
45
|
+
const matches = sessionFilter(cards, query);
|
|
46
|
+
return { cards, matches, selected: Math.max(0, Math.min(this.#sel, matches.length - 1)), scope: scoped?.scope ?? null, query };
|
|
66
47
|
}
|
|
67
48
|
/** 0.40.0 — tab flips CURRENT ↔ ALL. The filter owns every printable
|
|
68
49
|
* key (the buffer IS the query), so the toggle cannot be one. True when
|
|
@@ -77,15 +58,14 @@ export class PickInput {
|
|
|
77
58
|
this.host.render();
|
|
78
59
|
return true;
|
|
79
60
|
}
|
|
80
|
-
/** The band's height estimate: the header
|
|
81
|
-
* the one "no match" row)
|
|
82
|
-
|
|
61
|
+
/** The band's height estimate: the header, the windowed rows and the
|
|
62
|
+
* selected row's opened second row (or the one "no match" row), and
|
|
63
|
+
* the key row — sessionPickerRows' shape at this terminal height. */
|
|
64
|
+
rows(height) {
|
|
83
65
|
const view = this.state();
|
|
84
66
|
if (view === null)
|
|
85
67
|
return 0;
|
|
86
|
-
|
|
87
|
-
const unknownRow = view.scope != null && !view.scope.all && view.scope.unknown > 0 ? 1 : 0;
|
|
88
|
-
return Math.min(Math.max(view.matches.length, 1), AT_VISIBLE) + 2 + unknownRow;
|
|
68
|
+
return view.matches.length === 0 ? 3 : Math.min(view.matches.length, resumeVisible(height)) + 3;
|
|
89
69
|
}
|
|
90
70
|
/** ↑↓: the selection walks the matches and stops at both ends. True
|
|
91
71
|
* when the picker owned the key (the caller renders). */
|
package/dist/session-picker.d.ts
CHANGED
|
@@ -62,8 +62,14 @@ export declare function scopeSessions(cards: readonly SessionCardView[], here: s
|
|
|
62
62
|
readonly cards: readonly SessionCardView[];
|
|
63
63
|
readonly scope: PickScopeState;
|
|
64
64
|
};
|
|
65
|
-
/** The band's title —
|
|
66
|
-
|
|
65
|
+
/** The band's title — named after the command that opened it, then the
|
|
66
|
+
* scope and its counts. Graphite P1 (owner, 2026-09-30): the key that
|
|
67
|
+
* flips the scope moved to the key row, and a filter says how many of
|
|
68
|
+
* the scope match. */
|
|
69
|
+
export declare function scopeTitle(scope: PickScopeState | null, filter?: {
|
|
70
|
+
readonly matches: number;
|
|
71
|
+
readonly of: number;
|
|
72
|
+
} | null): string;
|
|
67
73
|
/**
|
|
68
74
|
* What the row SAYS about the state. The interrupted note is the
|
|
69
75
|
* product's promise stated in the place the promise matters: the run
|
|
@@ -108,19 +114,6 @@ export declare function idColumn(cards: readonly SessionCardView[]): number;
|
|
|
108
114
|
* the list.
|
|
109
115
|
*/
|
|
110
116
|
export declare function sessionFilter(cards: readonly SessionCardView[], query: string): SessionCardView[];
|
|
111
|
-
/**
|
|
112
|
-
* ONE picker row. The selection is a FULL-ROW reverse bar — the R1.5
|
|
113
|
-
* ⑧ ruling's shape, shared with the @ picker and the user chip: a
|
|
114
|
-
* two-cell marker in an eighty-column row is a selection you have to
|
|
115
|
-
* hunt for.
|
|
116
|
-
*
|
|
117
|
-
* The inner spans close with rvEnd inside the bar (never SGR 0, which
|
|
118
|
-
* would punch a hole in it) — the same composition atRow uses.
|
|
119
|
-
*/
|
|
120
|
-
export declare function sessionRow(card: SessionCardView, selected: boolean, W: number, now: number, idCol: number, here?: string | null): string;
|
|
121
|
-
/** The counter row — the SELECTION's 1-based place in the whole
|
|
122
|
-
* filtered list, which the visible window cannot tell the user. */
|
|
123
|
-
export declare function sessionCounterRow(selected: number, total: number, W: number): string;
|
|
124
117
|
/** The picker's bound state — the editor owns it, the compositor reads
|
|
125
118
|
* it (the @ picker's contract, one surface over). */
|
|
126
119
|
export interface SessionPickState {
|
|
@@ -129,16 +122,38 @@ export interface SessionPickState {
|
|
|
129
122
|
readonly selected: number;
|
|
130
123
|
/** 0.40.0: null when the picker was opened without a workspace. */
|
|
131
124
|
readonly scope?: PickScopeState | null;
|
|
125
|
+
/** Graphite P1: the filter as typed — the title lights the letters it
|
|
126
|
+
* matched, and the band says how many match. Absent = no filter. */
|
|
127
|
+
readonly query?: string;
|
|
132
128
|
}
|
|
129
|
+
/** How many sessions the band shows: eight on a terminal 30 rows or
|
|
130
|
+
* taller, five below (owner, 2026-09-30). */
|
|
131
|
+
export declare function resumeVisible(height: number): number;
|
|
132
|
+
/** The window over the matches, with a scroll-off of one: while more lies
|
|
133
|
+
* past an edge, the cursor stays a row inside it, so the edge row that
|
|
134
|
+
* carries a more-mark is never the selected one. Stateless, like
|
|
135
|
+
* bandWindow: the same (total, selected) always draws the same window. */
|
|
136
|
+
export declare function resumeWindow(total: number, selected: number, visible: number): {
|
|
137
|
+
first: number;
|
|
138
|
+
count: number;
|
|
139
|
+
};
|
|
140
|
+
/** The row's state word — empty for the quiet default, a finished session. */
|
|
141
|
+
export declare function sessionStateWord(card: SessionCardView): string;
|
|
142
|
+
/** When the session started, read from its id — the id IS the UTC stamp
|
|
143
|
+
* it was made at (apps/cli session-id.ts) — in local time. Null for an
|
|
144
|
+
* id that is not one. */
|
|
145
|
+
export declare function sessionStarted(id: string): string | null;
|
|
146
|
+
/** What the empty input says while the picker is up: typing there filters. */
|
|
147
|
+
export declare const RESUME_FILTER_HINT = "filter by title or id";
|
|
133
148
|
/**
|
|
134
|
-
* The whole band: the
|
|
135
|
-
*
|
|
136
|
-
* rows,
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
149
|
+
* The whole band: the named hairline, the windowed table with the
|
|
150
|
+
* selected row opened, and the key row. Returned as plain strings for the
|
|
151
|
+
* menu-rows channel, which already accounts them in chromeRows — the
|
|
152
|
+
* picker needs no geometry of its own, which is the entire reason it
|
|
153
|
+
* rides that channel. `height` is the terminal's: it sets how many
|
|
154
|
+
* sessions show (resumeVisible).
|
|
140
155
|
*/
|
|
141
|
-
export declare function sessionPickerRows(state: SessionPickState, W: number, now: number): string[];
|
|
156
|
+
export declare function sessionPickerRows(state: SessionPickState, W: number, now: number, height?: number): string[];
|
|
142
157
|
/**
|
|
143
158
|
* Slice ③ — the `kiso sessions` TTY row: the same projection, printed
|
|
144
159
|
* rather than picked. No selection bar (nothing is selected on a
|