@geohar/unbien-cli 0.3.3 → 0.3.5

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.
@@ -0,0 +1,36 @@
1
+ import { type PairedPeer } from "./store.js";
2
+ import { SessionClient, type RoomInfo } from "./client.js";
3
+ /**
4
+ * Shared machine-control-room plumbing for the daemon-facing verbs
5
+ * (create-session, resume-session): machine discovery by name/epk, the
6
+ * control-room derivation (must match the daemon's own roomIdForControl),
7
+ * and the launch request/response exchange.
8
+ */
9
+ /** Machine discovery: name (exact or prefix) or epk prefix, over paired peers. */
10
+ export declare function resolveMachine(target: string): PairedPeer | null;
11
+ /** Resolve + print the no-match error; exits the process when unresolved. */
12
+ export declare function requireMachine(target: string): PairedPeer;
13
+ /** Control room of a machine's launcher daemon — must match the daemon's own
14
+ * roomIdForControl (base64url(sha256(NUL+'control'+NUL+epk)).prefix(12)). */
15
+ export declare function controlRoomFor(epk: string): string;
16
+ export interface LaunchOutcome {
17
+ ok: boolean;
18
+ note: string;
19
+ }
20
+ /** Send `session_launch` and await the daemon's error frame (or its absence).
21
+ * Success carries no ack — the new session announces itself via its own room. */
22
+ export declare function launchAndWait(client: SessionClient, params: {
23
+ cwd?: string;
24
+ name?: string;
25
+ resume?: string;
26
+ }, timeoutMs?: number): Promise<LaunchOutcome>;
27
+ /** Poll the machine's room list until a session matching `match` goes live
28
+ * (pi startup + mesh join take a few seconds after a launch). Resolves the
29
+ * live room, or null on timeout. */
30
+ export declare function waitForRoom(client: SessionClient, match: (room: RoomInfo) => boolean, timeoutMs?: number, intervalMs?: number): Promise<RoomInfo | null>;
31
+ /** Spawn the interactive `unbien connect` attach flow for a live session and
32
+ * wait for it (stdio inherited — the child owns the terminal). Returns the
33
+ * child's exit code. */
34
+ export declare function handoffToConnect(machine: PairedPeer, sessionId: string): Promise<number>;
35
+ /** Connect a SessionClient to a machine's control room. Exits on unreachable. */
36
+ export declare function connectControlRoom(machine: PairedPeer, relayUrlOverride?: string): Promise<SessionClient>;
@@ -0,0 +1,157 @@
1
+ import { createHash } from "node:crypto";
2
+ import { Buffer } from "node:buffer";
3
+ import { loadPeers } from "./store.js";
4
+ import { loadOrCreateIdentity } from "./identity.js";
5
+ import { SessionClient } from "./client.js";
6
+ import { Shell } from "./tui.js";
7
+ /**
8
+ * Shared machine-control-room plumbing for the daemon-facing verbs
9
+ * (create-session, resume-session): machine discovery by name/epk, the
10
+ * control-room derivation (must match the daemon's own roomIdForControl),
11
+ * and the launch request/response exchange.
12
+ */
13
+ /** Machine discovery: name (exact or prefix) or epk prefix, over paired peers. */
14
+ export function resolveMachine(target) {
15
+ const peers = loadPeers();
16
+ if (peers.length === 0)
17
+ return null;
18
+ if (!target)
19
+ return peers[peers.length - 1]; // last-paired, matching connect's default
20
+ const t = target.toLowerCase();
21
+ return (peers.find((p) => p.name?.toLowerCase() === t) ??
22
+ peers.find((p) => p.name?.toLowerCase().startsWith(t)) ??
23
+ peers.find((p) => p.epk.startsWith(target)) ??
24
+ null);
25
+ }
26
+ /** Resolve + print the no-match error; exits the process when unresolved. */
27
+ export function requireMachine(target) {
28
+ const machine = resolveMachine(target);
29
+ if (machine)
30
+ return machine;
31
+ console.error(`no machine matching '${target}'. Known:` +
32
+ loadPeers()
33
+ .map((p) => `\n ${p.name ?? p.epk.slice(0, 12)} (${p.epk.slice(0, 10)}…)`)
34
+ .join(""));
35
+ Shell.exitAfterDrain(1);
36
+ process.exit(1); // narrowing: drain is async
37
+ }
38
+ /** Control room of a machine's launcher daemon — must match the daemon's own
39
+ * roomIdForControl (base64url(sha256(NUL+'control'+NUL+epk)).prefix(12)). */
40
+ export function controlRoomFor(epk) {
41
+ const sep = String.fromCharCode(0);
42
+ // CANONICALIZE first: peers.json may store standard base64 (+//) while the
43
+ // daemon derives its room from the base64url form of the same key — the raw
44
+ // strings hash to different rooms (verified live: kVXLntWnczuI vs -R1hyjN5pwsD).
45
+ const canonical = Buffer.from(epk, "base64").toString("base64url");
46
+ return createHash("sha256")
47
+ .update(sep + "control" + sep + canonical)
48
+ .digest("base64url")
49
+ .slice(0, 12);
50
+ }
51
+ /** Send `session_launch` and await the daemon's error frame (or its absence).
52
+ * Success carries no ack — the new session announces itself via its own room. */
53
+ export async function launchAndWait(client, params, timeoutMs = 8_000) {
54
+ return new Promise((resolve) => {
55
+ let settled = false;
56
+ const onUb = (frame) => {
57
+ try {
58
+ if (settled)
59
+ return;
60
+ if (String(frame.type ?? "") === "error") {
61
+ settled = true;
62
+ resolve({
63
+ ok: false,
64
+ note: String(frame.message ?? frame.code ?? "launch rejected"),
65
+ });
66
+ }
67
+ }
68
+ catch (err) {
69
+ // A malformed frame must not crash the verb mid-wait.
70
+ console.error(`frame handling error (ignored): ${String(err).slice(0, 120)}`);
71
+ }
72
+ };
73
+ client.on("ub", onUb);
74
+ // Daemon errors ride control; relay refusals ride relayControl — both
75
+ // terminal for the launch (they'd otherwise read as a silent timeout).
76
+ const onError = (frame) => {
77
+ if (settled)
78
+ return;
79
+ if (String(frame.type ?? "") === "error") {
80
+ settled = true;
81
+ resolve({
82
+ ok: false,
83
+ note: String(frame.message ?? frame.code ?? "launch rejected"),
84
+ });
85
+ }
86
+ };
87
+ client.on("control", onError);
88
+ client.on("relayControl", onError);
89
+ client.sendUb("session_launch", params);
90
+ setTimeout(() => {
91
+ if (settled)
92
+ return;
93
+ settled = true;
94
+ client.off("ub", onUb);
95
+ resolve({ ok: true, note: "" });
96
+ }, timeoutMs);
97
+ });
98
+ }
99
+ /** Poll the machine's room list until a session matching `match` goes live
100
+ * (pi startup + mesh join take a few seconds after a launch). Resolves the
101
+ * live room, or null on timeout. */
102
+ export async function waitForRoom(client, match, timeoutMs = 30_000, intervalMs = 2_000) {
103
+ const deadline = Date.now() + timeoutMs;
104
+ while (Date.now() < deadline) {
105
+ try {
106
+ const rooms = await client.listRooms();
107
+ const found = rooms.find(match);
108
+ if (found)
109
+ return found;
110
+ }
111
+ catch {
112
+ /* transient relay hiccup — keep polling */
113
+ }
114
+ await new Promise((r) => setTimeout(r, intervalMs));
115
+ }
116
+ return null;
117
+ }
118
+ /** Spawn the interactive `unbien connect` attach flow for a live session and
119
+ * wait for it (stdio inherited — the child owns the terminal). Returns the
120
+ * child's exit code. */
121
+ export async function handoffToConnect(machine, sessionId) {
122
+ const { spawn } = await import("node:child_process");
123
+ const { fileURLToPath } = await import("node:url");
124
+ // dist/machine.js → dist/main.js (the CLI front door routes `connect`)
125
+ const mainJs = fileURLToPath(new URL("./main.js", import.meta.url));
126
+ const target = machine.name ?? machine.epk.slice(0, 8);
127
+ const child = spawn(process.execPath, [mainJs, "connect", target, "--session", sessionId], { stdio: "inherit", env: process.env });
128
+ return new Promise((resolve) => child.on("exit", (code) => resolve(code ?? 1)));
129
+ }
130
+ /** Connect a SessionClient to a machine's control room. Exits on unreachable. */
131
+ export async function connectControlRoom(machine, relayUrlOverride) {
132
+ const relayUrl = relayUrlOverride ?? machine.relayUrl;
133
+ const label = machine.name ?? machine.epk.slice(0, 12);
134
+ const client = new SessionClient(relayUrl, loadOrCreateIdentity(), {
135
+ token: "",
136
+ epk: machine.epk,
137
+ roomId: controlRoomFor(machine.epk),
138
+ });
139
+ try {
140
+ await client.connect({ roomId: controlRoomFor(machine.epk) });
141
+ }
142
+ catch {
143
+ console.error(`[relay] unreachable: ${relayUrl} (${label})`);
144
+ Shell.exitAfterDrain(1);
145
+ process.exit(1);
146
+ }
147
+ // DISCOVER the daemon's control room from its announce (caps include
148
+ // is_daemon) instead of deriving it from the stored epk — derivation
149
+ // silently targets the wrong room whenever the stored key and the
150
+ // machine's live key disagree in form or vintage.
151
+ const rooms = await client.listRooms();
152
+ const daemonRoom = rooms.find((r) => (r.caps ?? []).includes("is_daemon"));
153
+ if (daemonRoom)
154
+ client.setRoom(daemonRoom.room_id);
155
+ return client;
156
+ }
157
+ //# sourceMappingURL=machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine.js","sourceRoot":"","sources":["../src/machine.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const COMMANDS = new Map([
4
4
  ["connect", () => import("./connect.js")],
5
5
  ["create-session", () => import("./create_session.js")],
6
+ ["resume-session", () => import("./resume_session.js")],
6
7
  ["replay", () => import("./replay.js")],
7
8
  ["pair", () => import("./pair.js")],
8
9
  ["relay", () => import("./relay.js")],
@@ -34,6 +35,8 @@ if (!load) {
34
35
  " connect attach to a live pi session over the relay (default)\n" +
35
36
  " create-session <machine> [--dir <cwd>] [--name <name>]\n" +
36
37
  " spawn a fresh pi session on an idle machine\n" +
38
+ " resume-session <machine> [--dir <cwd>] [--filter <text>] [--all]\n" +
39
+ " resume a stored session (picker: name/summary, recency)\n" +
37
40
  " replay render a captured envelope stream from a file\n" +
38
41
  " pair pair with a machine (paste its unbien:// invite)\n" +
39
42
  " relay manage remembered relays (add / remove / list)\n\n" +
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,6CAA6C;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;CACtC,CAAC,CAAA;AAEF,4EAA4E;AAC5E,wEAAwE;AACxE,6DAA6D;AAC7D,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAClE,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACvC,2EAA2E;AAC3E,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACzE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAElD,IAAI,CAAC,IAAI,EAAE,CAAC;IACV,OAAO,CAAC,KAAK,CACX,uCAAuC;QACrC,oEAAoE;QACpE,4DAA4D;QAC5D,2DAA2D;QAC3D,6DAA6D;QAC7D,gEAAgE;QAChE,gEAAgE;QAChE,2DAA2D,CAC9D,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,8EAA8E;AAC9E,IAAI,IAAI;IAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACnC,MAAM,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA,6CAA6C;AAE7C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC;IACvB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACvD,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;CACtC,CAAC,CAAA;AAEF,4EAA4E;AAC5E,wEAAwE;AACxE,6DAA6D;AAC7D,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAClE,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACxB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,4EAA4E;QAC5E,OAAO,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AACvC,2EAA2E;AAC3E,6EAA6E;AAC7E,qDAAqD;AACrD,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;AACzE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AAElD,IAAI,CAAC,IAAI,EAAE,CAAC;IACV,OAAO,CAAC,KAAK,CACX,uCAAuC;QACrC,oEAAoE;QACpE,4DAA4D;QAC5D,2DAA2D;QAC3D,sEAAsE;QACtE,uEAAuE;QACvE,6DAA6D;QAC7D,gEAAgE;QAChE,gEAAgE;QAChE,2DAA2D,CAC9D,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AAC/B,CAAC;AAED,8EAA8E;AAC9E,IAAI,IAAI;IAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACnC,MAAM,IAAI,EAAE,CAAA"}
package/dist/picker.d.ts CHANGED
@@ -1,6 +1,18 @@
1
+ import { type SelectItem } from "@earendil-works/pi-tui";
1
2
  import type { RoomInfo } from "./client.js";
2
3
  /**
3
4
  * Renders on stderr in raw mode so stdout stays clean for the transcript.
4
5
  * Resolves to the chosen session, or null if cancelled.
5
6
  */
6
7
  export declare function pickSession(rooms: readonly RoomInfo[]): Promise<RoomInfo | null>;
8
+ /**
9
+ * Generic variant: raw-mode SelectList over caller-built items (the resume
10
+ * chooser reuses this — its rows carry name/summary/recency, not RoomInfo).
11
+ * Resolves the chosen `value`, or null if cancelled.
12
+ */
13
+ export declare function pickRaw(items: readonly SelectItem[], opts?: {
14
+ /** Substring filter over the caller's semantics (name/summary/cwd) —
15
+ * SelectList's own setFilter is prefix-on-value only, which never
16
+ * matches what the rows display. Without it, prefix-on-value applies. */
17
+ filter?: (filter: string, all: readonly SelectItem[]) => SelectItem[];
18
+ }): Promise<string | null>;
package/dist/picker.js CHANGED
@@ -1,15 +1,80 @@
1
1
  /**
2
2
  * Session picker built on pi's own `SelectList` — arrow-key highlight,
3
3
  * type-to-filter, and pi's list theme, rather than "enter a number".
4
+ *
5
+ * Rendering goes to stderr (raw mode) so stdout stays clean for transcripts.
6
+ * Input: readline keypress events — arrows/enter/escape feed SelectList's own
7
+ * handleInput (its keybindings decode the escape sequences); printable chars
8
+ * drive type-to-filter. The legacy raw-"data" parsing ignored multi-byte
9
+ * escape sequences entirely, which is why arrows never moved.
4
10
  */
5
- import { getSelectListTheme } from "@earendil-works/pi-coding-agent";
11
+ import { getSelectListTheme, initTheme } from "@earendil-works/pi-coding-agent";
6
12
  import { SelectList } from "@earendil-works/pi-tui";
13
+ import { StdinBuffer } from "@earendil-works/pi-tui";
7
14
  const MAX_VISIBLE = 12;
15
+ let themeInitialized = false;
16
+ /** The SDK's theme must be initialized before any get*Theme() call; the CLI
17
+ * has no interactive theme bootstrapping, so the default (no name) it is. */
18
+ function ensureTheme() {
19
+ if (themeInitialized)
20
+ return;
21
+ initTheme();
22
+ themeInitialized = true;
23
+ }
8
24
  /**
9
- * `SelectList.setFilter` prefix-matches on `value`, so the value must be what a
10
- * person would type the session name, not its routing id. Names are not
11
- * unique, so collisions get a short session-id suffix to stay addressable.
25
+ * Shared keypress wiring for the pickers: arrows/enter/escape feed the list's
26
+ * own handleInput (keybindings decode the raw sequences); printable chars
27
+ * drive type-to-filter; backspace trims; Ctrl-C cancels. Registers on the
28
+ * input stream; returns the unsubscribe (finish must call it).
29
+ * `paint(filter)` re-renders after any filter change.
12
30
  */
31
+ function wireKeys(input, list, paint, finish, applyFilter) {
32
+ // pi-tui's own input decoder: buffers split escape sequences and emits
33
+ // COMPLETE sequences — the same decoding pi's TUI pickers rely on. Hand-
34
+ // parsing raw "data" chunks loses arrows whenever ESC and [A arrive apart.
35
+ const buffer = new StdinBuffer();
36
+ let filter = "";
37
+ buffer.on("data", (sequence) => {
38
+ // Navigation + confirm + cancel: the list's keybindings decode sequences.
39
+ // NAVIGATION MUST REPAINT: handleInput moves the selection internally —
40
+ // without paint() the highlight moves invisibly (the "arrows don't work"
41
+ // symptom).
42
+ if (sequence === "\x1b[A" ||
43
+ sequence === "\x1b[B") {
44
+ list.handleInput(sequence);
45
+ paint(filter);
46
+ return;
47
+ }
48
+ if (sequence === "\r" || sequence === "\x1b") {
49
+ return list.handleInput(sequence);
50
+ }
51
+ if (sequence === "\x7f" || sequence === "\b") {
52
+ filter = filter.slice(0, -1);
53
+ applyFilter ? applyFilter(filter) : list.setFilter(filter);
54
+ paint(filter);
55
+ return;
56
+ }
57
+ if (sequence === "\x03")
58
+ return finish(null);
59
+ // Printable run: type-to-filter (a paste arrives as one chunk).
60
+ if (/^[\x20-\x7e]+$/.test(sequence)) {
61
+ filter += sequence;
62
+ applyFilter ? applyFilter(filter) : list.setFilter(filter);
63
+ paint(filter);
64
+ }
65
+ // Anything else (mouse, kitty CSI-u, …): silently ignored.
66
+ });
67
+ const onData = (chunk) => {
68
+ buffer.process(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
69
+ };
70
+ input.on("data", onData);
71
+ return () => {
72
+ input.off("data", onData);
73
+ buffer.destroy();
74
+ };
75
+ }
76
+ /** Build picker items from session rooms: name (or id), deduped with a short
77
+ * session-id suffix so same-named sessions stay addressable. */
13
78
  function buildItems(rooms) {
14
79
  const seen = new Map();
15
80
  const items = [];
@@ -34,14 +99,14 @@ function buildItems(rooms) {
34
99
  * Resolves to the chosen session, or null if cancelled.
35
100
  */
36
101
  export function pickSession(rooms) {
102
+ ensureTheme();
37
103
  const { items, byValue } = buildItems(rooms);
38
104
  const list = new SelectList(items, MAX_VISIBLE, getSelectListTheme());
39
105
  const input = process.stdin;
40
106
  const output = process.stderr;
41
107
  const width = output.columns ?? 100;
42
- let filter = "";
43
108
  let lastHeight = 0;
44
- const paint = () => {
109
+ const paint = (filter = "") => {
45
110
  if (lastHeight > 0)
46
111
  output.write(`\u001b[${lastHeight}A`);
47
112
  const lines = [
@@ -54,7 +119,7 @@ export function pickSession(rooms) {
54
119
  };
55
120
  return new Promise((resolve) => {
56
121
  const finish = (room) => {
57
- input.off("data", onData);
122
+ offKeys();
58
123
  if (input.isTTY)
59
124
  input.setRawMode(false);
60
125
  // Deliberately NOT paused: the shell takes stdin over next, and a paused
@@ -62,33 +127,68 @@ export function pickSession(rooms) {
62
127
  output.write("\u001b[?25h");
63
128
  resolve(room);
64
129
  };
130
+ const offKeys = wireKeys(input, list, paint, () => finish(null));
65
131
  list.onSelect = (item) => finish(byValue.get(item.value) ?? null);
66
132
  list.onCancel = () => finish(null);
67
- const onData = (chunk) => {
68
- const data = chunk.toString("utf8");
69
- if (data === "\u0003") {
70
- finish(null);
71
- return;
72
- }
73
- if (data === "\u007f" || data === "\b") {
74
- filter = filter.slice(0, -1);
75
- list.setFilter(filter);
76
- }
77
- else if (/^[\x20-\x7e]+$/.test(data)) {
78
- filter += data;
79
- list.setFilter(filter);
80
- }
81
- else {
82
- list.handleInput(data);
83
- }
84
- paint();
133
+ if (input.isTTY)
134
+ input.setRawMode(true);
135
+ paint();
136
+ });
137
+ }
138
+ /**
139
+ * Generic variant: raw-mode SelectList over caller-built items (the resume
140
+ * chooser reuses this — its rows carry name/summary/recency, not RoomInfo).
141
+ * Resolves the chosen `value`, or null if cancelled.
142
+ */
143
+ export function pickRaw(items, opts) {
144
+ ensureTheme();
145
+ const all = [...items];
146
+ const list = new SelectList([...items], MAX_VISIBLE, getSelectListTheme());
147
+ // Apply the caller's substring filter by REASSIGNING items — SelectList's
148
+ // own setFilter is prefix-on-value and can't match displayed text.
149
+ const applyFilter = (filter) => {
150
+ if (opts?.filter) {
151
+ // SAFETY: `items` is a plain instance field at runtime ( SelectList's
152
+ // `private` is type-only); assigning it is the only way to run a
153
+ // SUBSTRING filter — the class's own setFilter is prefix-on-value.
154
+ // Invariant: after this assignment, setFilter("") rebuilds
155
+ // filteredItems from exactly the filtered set.
156
+ const mutable = list;
157
+ mutable.items = filter ? opts.filter(filter, all) : all;
158
+ list.setFilter(""); // items already filtered; reset the internal filter
159
+ }
160
+ else {
161
+ list.setFilter(filter);
162
+ }
163
+ };
164
+ const input = process.stdin;
165
+ const output = process.stderr;
166
+ const width = output.columns ?? 100;
167
+ let lastHeight = 0;
168
+ const paint = (filter = "") => {
169
+ if (lastHeight > 0)
170
+ output.write(`\u001b[${lastHeight}A`);
171
+ const lines = [
172
+ ` filter: ${filter}\u001b[K`,
173
+ ...list.render(width).map((line) => `${line}\u001b[K`),
174
+ ];
175
+ for (const line of lines)
176
+ output.write(`${line}\n`);
177
+ lastHeight = lines.length;
178
+ };
179
+ return new Promise((resolve) => {
180
+ const finish = (value) => {
181
+ offKeys();
182
+ if (input.isTTY)
183
+ input.setRawMode(false);
184
+ output.write("\u001b[?25h");
185
+ resolve(value);
85
186
  };
86
- output.write("Select a session (↑/↓ move · type to filter · enter · esc)\n\n");
87
- output.write("\u001b[?25l");
187
+ const offKeys = wireKeys(input, list, paint, () => finish(null), applyFilter);
188
+ list.onSelect = (item) => finish(item.value);
189
+ list.onCancel = () => finish(null);
88
190
  if (input.isTTY)
89
191
  input.setRawMode(true);
90
- input.resume();
91
- input.on("data", onData);
92
192
  paint();
93
193
  });
94
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"picker.js","sourceRoot":"","sources":["../src/picker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"picker.js","sourceRoot":"","sources":["../src/picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function run(argv: string[]): Promise<void>;