@popoverinstall/cli 0.9.1 → 0.10.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.
@@ -0,0 +1,576 @@
1
+ import { FIELD_MAX, displayWidth, formatAge, padTo, sanitizeField, truncateTo, } from "@popoverinstall/shared";
2
+ import { askDaemon, daemonIsRunning } from "./ipc-client.js";
3
+ import { bad, c, dim, ok, warn } from "./ui.js";
4
+ /**
5
+ * `popover threads` and `popover thread close` — the visibility and the kill switch.
6
+ *
7
+ * The design is docs/messages.md; this file is §9's CLI half. What these two are for is not
8
+ * obvious from the commands themselves, so it is worth stating: **they are what replaced the
9
+ * tell rate limit.** `messages_rate_limit` used to cap an agent at ten messages per recipient
10
+ * per hour, and §2 threw it out on the grounds that a numeric cap is a proxy for consent —
11
+ * nobody had asked the recipient's human anything, so the schema guessed a number on their
12
+ * behalf, and the guess severed conversations mid-sentence at an arbitrary count.
13
+ *
14
+ * What stands in its place is exactly this: every thread is listable, cost-so-far is on screen,
15
+ * and either party's human can close one. A cap says "no" at ten; a kill switch says the human
16
+ * is in control. That is the whole argument, and it only holds if these two commands work — so
17
+ * the failure modes below are handled rather than discovered.
18
+ *
19
+ * Three things run through the file.
20
+ *
21
+ * **State is read, never derived.** `state` reaches here from `public.thread_states` (§12) by
22
+ * way of the daemon's `threads` arm, and this file puts it in a column. Every input to the
23
+ * derivation — the peer's status, whether a message is undelivered — is available to this
24
+ * process, so computing it here would work, and it is the one thing that must not be done:
25
+ * `MACHINE_STALE_MS` is already duplicated between `packages/daemon/src/cloud.ts` and
26
+ * `apps/web/src/lib/format.ts`, and the comment on the second calls the resulting disagreement
27
+ * "the entire bug this path exists to fix". Staleness is worse than that threshold, not better,
28
+ * because it has nothing to eyeball — it is a join, and a second copy would drift silently.
29
+ * There is one definition, in the view, and neither surface gets an opinion.
30
+ *
31
+ * **The cost column is a partial and says so.** `costUsd` totals the *ask* rows in a thread. A
32
+ * message delivered into a live session is answered by that session, inside the recipient's own
33
+ * Claude usage, and popover cannot see a cent of it. §8's sharp form is that the transport we
34
+ * can bill looks expensive and the one we cannot looks free, and routing prefers the unbillable
35
+ * one exactly when the target is busiest — so the figure is *inversely* correlated with the
36
+ * disruption it appears to describe. Hence "cost (asks only)" on the column, on the close
37
+ * confirmation, and on every row of `--json`. §8 makes that a requirement rather than a
38
+ * preference: a total which silently excludes half the spend is worse than a labelled partial,
39
+ * because it will be trusted, and somebody will read a low number and conclude the thread was
40
+ * cheap for the person on the other end.
41
+ *
42
+ * **Closing does not retract.** §7 states it and says implementers get it backwards by default,
43
+ * so the confirmation is written to make the opposite unreadable into it: a closed thread bars
44
+ * new sends, and an already-filed message still drains when the peer's session resumes. Saying
45
+ * "closed" and stopping would let the person who closed it in a hurry — the one who most wants
46
+ * to believe the last message went away — believe it had.
47
+ */
48
+ // ---------------------------------------------------------------------------
49
+ // The cost caveat, written once
50
+ // ---------------------------------------------------------------------------
51
+ /**
52
+ * The label §8 requires, as a constant rather than three hand-typed copies.
53
+ *
54
+ * Three copies of a required caveat is three chances for one of them to be dropped as clutter
55
+ * by somebody tidying a column header, and the one dropped would be the one that mattered.
56
+ */
57
+ export const COST_LABEL = "cost (asks only)";
58
+ export const COST_CAVEAT = [
59
+ "cost counts the ask transport only. A message delivered into a live session is answered",
60
+ "by that session, inside its own Claude usage, and popover cannot see what it spent — so",
61
+ "this is a floor, not a total, and it is lowest when the interruption was largest.",
62
+ ];
63
+ /** The same sentence for a `--json` consumer, which will never read the paragraph above. */
64
+ export const COST_NOTE = "Ask transport only. A message injected into a live session is answered by that session " +
65
+ "and cannot be metered, so this is a floor rather than a total.";
66
+ /**
67
+ * A dollar figure, or an honest gap.
68
+ *
69
+ * `<$0.01` rather than `$0.00` for a real sub-cent spend: rounding a charge down prints "free"
70
+ * for something that was not, and this column exists to stop exactly that reading. "—" for an
71
+ * absent figure, which the wire contract does not currently produce — `costUsd` defaults to 0
72
+ * — but which keeps "nobody told us" and "it cost nothing" from collapsing into one cell if it
73
+ * ever does.
74
+ */
75
+ export function formatCost(value) {
76
+ if (value === undefined)
77
+ return "—";
78
+ if (value === 0)
79
+ return "$0.00";
80
+ if (value > 0 && value < 0.005)
81
+ return "<$0.01";
82
+ return `$${value.toFixed(2)}`;
83
+ }
84
+ const HEADERS = {
85
+ id: "id",
86
+ peer: "peer",
87
+ opened: "opened",
88
+ state: "state",
89
+ messages: "msgs",
90
+ last: "last",
91
+ cost: COST_LABEL,
92
+ };
93
+ /**
94
+ * One thread as a person reads it in a row, uncoloured.
95
+ *
96
+ * Separated from the printing so the awkward cells can be asserted rather than eyeballed, the
97
+ * way `summaryLines` is in `vaults.ts`. Three details are load-bearing:
98
+ *
99
+ * - **The peer's name is sanitised here.** The roster is rendered by the daemon and sanitised
100
+ * there; this table is rendered by the CLI, so the CLI has to do it. A teammate's display
101
+ * name is a string another person typed, and an escape sequence in a fixed-width cell does
102
+ * not misrender one line — it shears the whole table, and it is a teammate writing to your
103
+ * terminal. Same failure, same helper, as `renderRoster`.
104
+ * - **`opened` says who started it, not who may end it.** Either party's human can close
105
+ * (§7), so this column is about whose human granted the consent the thread runs on (§2),
106
+ * which is the fact a person weighing whether to close it actually wants.
107
+ * - **`last` is the age of the last activity, not of the thread.** That is the clock which
108
+ * closes a thread after 24 hours (§7.2), so it is what says whether a thread is about to
109
+ * close itself or wants closing by hand. The thread's own age is in `--json`, where nothing
110
+ * is competing for the width.
111
+ */
112
+ export function threadCells(t, nowMs = Date.now()) {
113
+ const handle = sanitizeField(t.peer.handle ?? "", FIELD_MAX.handle);
114
+ const name = sanitizeField(t.peer.ownerName ?? "", FIELD_MAX.ownerName);
115
+ const peer = [handle, name].filter(Boolean).join(" ");
116
+ return {
117
+ // Short, because this is the string somebody retypes into `thread close`, and a UUID is not
118
+ // retypable. `resolveThreadRef` expands a prefix back to a whole id before anything is sent.
119
+ id: t.id.slice(0, 8),
120
+ // A thread whose peer the roster no longer knows still has to be listable and closable —
121
+ // in fact it is the likeliest one to want closing — so an unknown peer is a gap, not a
122
+ // dropped row.
123
+ peer: peer || "—",
124
+ opened: t.direction === "outgoing" ? "you" : "them",
125
+ state: t.state,
126
+ messages: String(t.messageCount),
127
+ last: age(t.lastActivityAt, nowMs),
128
+ cost: formatCost(t.costUsd),
129
+ };
130
+ }
131
+ function age(iso, nowMs) {
132
+ if (!iso)
133
+ return "—";
134
+ const at = Date.parse(iso);
135
+ return Number.isFinite(at) ? formatAge(at, nowMs) : "—";
136
+ }
137
+ /** Colour is decoration. The word in the cell is the truth, and is what `--json` carries. */
138
+ function paint(state) {
139
+ if (state === "open")
140
+ return c.green(state);
141
+ if (state === "stale")
142
+ return c.yellow(state);
143
+ return c.dim(state);
144
+ }
145
+ /**
146
+ * The whole table, header included, indented and ready to print.
147
+ *
148
+ * Widths are measured in terminal columns rather than code units, for the reason `width.ts`
149
+ * records: a teammate called 李明 is two code units and four columns, and padding by
150
+ * `String.length` shears every row below theirs. The peer column is capped as well as padded,
151
+ * because a sixty-character display name would push the cost column off the edge of a narrow
152
+ * terminal and the cost column is the one §8 insists on being read.
153
+ */
154
+ export function renderThreadTable(threads, nowMs = Date.now()) {
155
+ const rows = threads.map((t) => threadCells(t, nowMs));
156
+ const all = [HEADERS, ...rows];
157
+ const width = (pick, cap = Infinity) => Math.min(cap, Math.max(...all.map((cells) => displayWidth(pick(cells)))));
158
+ const idW = width((r) => r.id);
159
+ const peerW = width((r) => r.peer, 28);
160
+ const openedW = width((r) => r.opened);
161
+ const stateW = width((r) => r.state);
162
+ const msgW = width((r) => r.messages);
163
+ const lastW = width((r) => r.last);
164
+ const line = (cells, state) => [
165
+ ` ${padTo(cells.id, idW)}`,
166
+ padTo(truncateTo(cells.peer, peerW), peerW),
167
+ padTo(cells.opened, openedW),
168
+ padTo(state, stateW),
169
+ padTo(cells.messages, msgW),
170
+ padTo(cells.last, lastW),
171
+ // Last column, so it is never padded: nothing lines up against its right edge.
172
+ cells.cost,
173
+ ]
174
+ .join(" ")
175
+ .trimEnd();
176
+ // Coloured from the thread rather than from the cell, so `paint` keeps the closed vocabulary
177
+ // the schema gives it and cannot be handed a free-text state to guess a colour for.
178
+ return [
179
+ c.dim(line(HEADERS, HEADERS.state)),
180
+ ...rows.map((r, i) => line(r, paint(threads[i].state))),
181
+ ];
182
+ }
183
+ /** One thread as a script reads it. Absent values are null, never missing — as `summaryJson`. */
184
+ export function threadJson(t, nowMs = Date.now()) {
185
+ return {
186
+ id: t.id,
187
+ state: t.state,
188
+ direction: t.direction,
189
+ peer_handle: t.peer.handle ?? null,
190
+ peer_name: t.peer.ownerName ?? null,
191
+ peer_repo: t.peer.repo ?? null,
192
+ message_count: t.messageCount,
193
+ cost_usd: t.costUsd,
194
+ // On every row, not only at the top of the payload. The reader §8 is worried about is the
195
+ // one that reads `threads[i].cost_usd` and never looks up, and a caveat a consumer has to
196
+ // reassemble is a caveat it can forget — the same reason `vaults.ts` puts the assembled
197
+ // attribution on the answer rather than leaving the caller to build it.
198
+ cost_basis: "asks_only",
199
+ created_at: t.createdAt,
200
+ last_activity_at: t.lastActivityAt,
201
+ last_activity_age: age(t.lastActivityAt, nowMs),
202
+ closed_at: t.closedAt ?? null,
203
+ close_reason: t.closeReason ?? null,
204
+ };
205
+ }
206
+ /**
207
+ * The shape of a thread id. The same test `looksLikeVaultId` makes, under its own name.
208
+ *
209
+ * Deliberately not shared with it: two one-line assertions about UUID syntax that happen to
210
+ * coincide are not one derivation used twice, and importing a vault helper here would couple
211
+ * two commands that have nothing else to say to each other.
212
+ */
213
+ export function looksLikeThreadId(ref) {
214
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(ref.trim());
215
+ }
216
+ /**
217
+ * Which thread a typed reference means: by whole id, then by id prefix, then by peer handle.
218
+ *
219
+ * Every match is returned rather than the first, on the same grounds as `resolveVaultRef`:
220
+ * closing cannot be undone except by opening a new thread and consenting again, and closing
221
+ * the wrong one silently ends a conversation somebody was relying on.
222
+ *
223
+ * **A prefix must be at least four characters.** `popover threads` prints eight, so four is
224
+ * already a deliberate abbreviation of what is on screen, while one or two would match a third
225
+ * of anybody's threads. Ambiguity is reported either way; the floor is about refusing to treat
226
+ * a typo as a reference at all.
227
+ *
228
+ * **A handle resolves against live threads first.** Somebody typing `popover thread close B1`
229
+ * means the conversation they are having with B1, not the one that closed on Tuesday. A closed
230
+ * thread is still matched when no live one exists, so the command can say "already closed"
231
+ * rather than "no such thread" — different facts, and only one of them is a typo.
232
+ */
233
+ export function resolveThreadRef(threads, typed) {
234
+ const needle = typed.trim().toLowerCase();
235
+ if (!needle)
236
+ return { kind: "none" };
237
+ const byId = threads.filter((t) => t.id.toLowerCase() === needle);
238
+ if (byId.length === 1)
239
+ return { kind: "one", thread: byId[0] };
240
+ if (needle.length >= 4) {
241
+ const prefix = threads.filter((t) => t.id.toLowerCase().startsWith(needle));
242
+ if (prefix.length === 1)
243
+ return { kind: "one", thread: prefix[0] };
244
+ if (prefix.length > 1)
245
+ return { kind: "many", matches: prefix };
246
+ }
247
+ const byHandle = threads.filter((t) => (t.peer.handle ?? "").toLowerCase() === needle);
248
+ const live = byHandle.filter((t) => t.state !== "closed");
249
+ const candidates = live.length > 0 ? live : byHandle;
250
+ if (candidates.length === 1)
251
+ return { kind: "one", thread: candidates[0] };
252
+ if (candidates.length > 1)
253
+ return { kind: "many", matches: candidates };
254
+ return { kind: "none" };
255
+ }
256
+ // ---------------------------------------------------------------------------
257
+ // What closing says
258
+ // ---------------------------------------------------------------------------
259
+ /**
260
+ * The sentences printed after a close, and the reason they are a function with a test.
261
+ *
262
+ * §7: "Closing does not retract what was already filed. A closed thread's undelivered rows
263
+ * still drain on resume. Closure bars new sends; it does not reach back and cancel a message
264
+ * the sender was entitled to send. Implementers get this backwards by default, so it is stated
265
+ * rather than implied."
266
+ *
267
+ * A confirmation saying only "thread closed" would leave the reader to supply the second half
268
+ * themselves, and the reader closing a thread in a hurry supplies the wrong one. So both halves
269
+ * are said, in order: what stopped, then what did not.
270
+ */
271
+ export function closureLines() {
272
+ return [
273
+ "No new message can be sent either way. One tried now is refused, not queued.",
274
+ "What was already sent stands: an undelivered message still lands when that session",
275
+ "resumes. Closing bars new sends; it does not recall one already filed.",
276
+ ];
277
+ }
278
+ // ---------------------------------------------------------------------------
279
+ // Entry points
280
+ // ---------------------------------------------------------------------------
281
+ /**
282
+ * `popover threads` — and `popover threads close <id>`, because insisting on the singular
283
+ * would be pedantry about grammar in the one command somebody reaches for when they want
284
+ * something stopped.
285
+ */
286
+ export async function threadsCommand(argv) {
287
+ const words = argv.filter((a) => !a.startsWith("-"));
288
+ if (words[0] === "close")
289
+ return close(argv.slice(argv.indexOf(words[0]) + 1));
290
+ if (argv.includes("--help") || argv.includes("-h")) {
291
+ usage();
292
+ return 0;
293
+ }
294
+ return list(argv);
295
+ }
296
+ /** `popover thread close <id>`, which is the spelling docs/messages.md §9 fixes. */
297
+ export async function threadCommand(argv) {
298
+ const words = argv.filter((a) => !a.startsWith("-"));
299
+ const sub = argv.includes("--help") || argv.includes("-h") ? "help" : (words[0] ?? "help");
300
+ const rest = words[0] === undefined ? argv : argv.slice(argv.indexOf(words[0]) + 1);
301
+ switch (sub) {
302
+ case "close":
303
+ return close(rest);
304
+ case "list":
305
+ case "ls":
306
+ return list(rest);
307
+ case "help":
308
+ usage();
309
+ return 0;
310
+ default:
311
+ bad(`Unknown thread command: ${sub}`);
312
+ usage();
313
+ return 1;
314
+ }
315
+ }
316
+ function usage() {
317
+ console.log(`
318
+ ${c.bold("popover threads")} — conversations between your agents and your teammates' agents
319
+
320
+ ${c.bold("popover threads")} [--all] Open threads, both directions, with cost so far
321
+ ${c.bold("popover thread close")} <id> Stop one. Either party's human may.
322
+
323
+ A thread is opened by ${c.cyan("/popover:message")} and consented to once, by the sender's human,
324
+ rather than per sentence. There is no message cap: closing one is the control, and
325
+ a thread with no activity for 24 hours closes itself, because consent has a shelf life.
326
+
327
+ Closing bars new messages. It does not recall one already sent — an undelivered
328
+ message still lands when the other session resumes.
329
+ `);
330
+ }
331
+ // ---------------------------------------------------------------------------
332
+ // popover threads
333
+ // ---------------------------------------------------------------------------
334
+ async function list(argv) {
335
+ const asJson = argv.includes("--json");
336
+ const includeClosed = argv.includes("--all") || argv.includes("--closed");
337
+ const now = Date.now();
338
+ const threads = await fetchThreads(includeClosed, asJson, "list threads");
339
+ if (!Array.isArray(threads))
340
+ return threads;
341
+ if (asJson) {
342
+ console.log(JSON.stringify({
343
+ ok: true,
344
+ count: threads.length,
345
+ include_closed: includeClosed,
346
+ cost_basis: "asks_only",
347
+ cost_note: COST_NOTE,
348
+ threads: threads.map((t) => threadJson(t, now)),
349
+ }));
350
+ return 0;
351
+ }
352
+ if (threads.length === 0) {
353
+ warn(includeClosed ? "You have no threads." : "You have no open threads.");
354
+ dim("One opens the first time you /popover:message a teammate's agent, or they message");
355
+ dim("yours. Closed ones are hidden unless you pass --all.");
356
+ return 0;
357
+ }
358
+ console.log("");
359
+ for (const row of renderThreadTable(threads, now))
360
+ console.log(row);
361
+ console.log("");
362
+ // Only the states actually on screen are explained. A legend for a condition nobody has is
363
+ // noise, and noise is what makes the two lines that matter easy to skip.
364
+ if (threads.some((t) => t.state === "stale")) {
365
+ dim("stale: their session has ended and a reply is filed for it. Not closed — it drains");
366
+ dim("when they resume, and nothing new can be sent meanwhile.");
367
+ }
368
+ for (const caveat of COST_CAVEAT)
369
+ dim(caveat);
370
+ dim(`Stop one with: popover thread close ${threadCells(threads[0], now).id}`);
371
+ console.log("");
372
+ return 0;
373
+ }
374
+ // ---------------------------------------------------------------------------
375
+ // popover thread close
376
+ // ---------------------------------------------------------------------------
377
+ async function close(argv) {
378
+ const asJson = argv.includes("--json");
379
+ const ref = argv.find((a) => !a.startsWith("-"));
380
+ if (!ref) {
381
+ return fail(asJson, "bad_request", "Closing a thread takes the thread to close.", [
382
+ "Usage: popover thread close <id>",
383
+ "`popover threads` prints the ids. The first few characters are enough.",
384
+ ]);
385
+ }
386
+ /*
387
+ * A whole id is sent without looking anything up first.
388
+ *
389
+ * Same reasoning as `resolveThroughApi` in `vaults.ts`: it keeps the kill switch working when
390
+ * the listing does not. A hiccup between here and `thread_states` must not be the thing
391
+ * standing between somebody and stopping a conversation that is spending their teammate's
392
+ * afternoon. The price is that the confirmation cannot name the peer, which is much the
393
+ * smaller loss — and it is not paid in the common case, where the id was copied off the table
394
+ * a moment ago and is a prefix.
395
+ */
396
+ let thread;
397
+ let threadId = ref;
398
+ if (!looksLikeThreadId(ref)) {
399
+ // Closed threads included, so an already-closed one reads as closed rather than as missing.
400
+ const threads = await fetchThreads(true, asJson, "close a thread");
401
+ if (!Array.isArray(threads))
402
+ return threads;
403
+ const match = resolveThreadRef(threads, ref);
404
+ if (match.kind !== "one")
405
+ return reportNoMatch(match, ref, asJson);
406
+ thread = match.thread;
407
+ threadId = thread.id;
408
+ if (thread.state === "closed") {
409
+ return fail(asJson, "thread_closed", "That thread is already closed.", [
410
+ thread.closeReason === "idle"
411
+ ? "It closed itself after 24 hours without activity — consent has a shelf life."
412
+ : "Either party's human can close one, so it need not have been you.",
413
+ "Anything already filed on it still delivers when the other session resumes.",
414
+ ]);
415
+ }
416
+ }
417
+ const reply = await askDaemon({ t: "threadClose", id: "thread-close", req: { threadId } }, 20_000);
418
+ if (!reply)
419
+ return daemonSilent(asJson, "close a thread");
420
+ if (reply.t === "error") {
421
+ return fail(asJson, reply.code, reply.message, [
422
+ ...(reply.hints ?? []),
423
+ ...hintsForCode(reply.code),
424
+ ]);
425
+ }
426
+ if (reply.t !== "threadClose.ok")
427
+ return unexpectedReply(asJson);
428
+ const who = thread ? peerLabel(thread) : "that thread";
429
+ if (asJson) {
430
+ console.log(JSON.stringify({
431
+ ok: true,
432
+ id: threadId,
433
+ state: "closed",
434
+ close_reason: "explicit",
435
+ peer_handle: thread?.peer.handle ?? null,
436
+ peer_name: thread?.peer.ownerName ?? null,
437
+ cost_usd: thread?.costUsd ?? null,
438
+ cost_basis: "asks_only",
439
+ cost_note: COST_NOTE,
440
+ // Stated structurally as well as in prose, the way `readable_by_service` is on a
441
+ // published vault. This is the fact about closing a reader is likeliest to assume the
442
+ // opposite of, and an agent relaying the result should not have to parse English to
443
+ // get it right. docs/messages.md §7.
444
+ undelivered_messages_still_deliver: true,
445
+ closed_at: new Date().toISOString(),
446
+ }));
447
+ return 0;
448
+ }
449
+ console.log("");
450
+ ok(`Closed the thread with ${who}.`);
451
+ for (const line of closureLines())
452
+ dim(line);
453
+ if (thread) {
454
+ // The same label as the column, word for word. This is the last thing anybody reads about
455
+ // the thread, so it is the last chance to stop the figure being remembered as a total.
456
+ dim(`${COST_LABEL}: ${formatCost(thread.costUsd)}. Anything answered by their live session`);
457
+ dim("was spent inside their own Claude usage and is not in that number.");
458
+ }
459
+ console.log("");
460
+ return 0;
461
+ }
462
+ function peerLabel(t) {
463
+ const handle = sanitizeField(t.peer.handle ?? "", FIELD_MAX.handle);
464
+ const name = sanitizeField(t.peer.ownerName ?? "", FIELD_MAX.ownerName);
465
+ if (handle && name)
466
+ return `${c.bold(handle)} (${name})`;
467
+ return c.bold(handle || name || t.id.slice(0, 8));
468
+ }
469
+ function reportNoMatch(match, ref, asJson) {
470
+ if (match.kind === "many") {
471
+ return fail(asJson, "ambiguous_thread", `\`${ref}\` matches ${match.matches.length} threads.`, [
472
+ `Type more of the id: ${match.matches.map((t) => t.id.slice(0, 8)).join(", ")}`,
473
+ "`popover threads --json` prints them whole.",
474
+ ]);
475
+ }
476
+ return fail(asJson, "thread_not_found", `No thread of yours matches \`${ref}\`.`, [
477
+ "Run `popover threads --all` to see them, closed ones included. You only see threads you",
478
+ "are a party to — that is the rule on the server, not a filter applied here.",
479
+ ]);
480
+ }
481
+ // ---------------------------------------------------------------------------
482
+ // Talking to the daemon
483
+ // ---------------------------------------------------------------------------
484
+ /**
485
+ * The listing, or an exit code that has already been reported.
486
+ *
487
+ * `what` is what the caller was trying to do, not what this function does, because `close`
488
+ * reads the listing to turn a typed prefix into an id — and "this daemon cannot list threads
489
+ * yet" in answer to `popover thread close` describes a step the person did not ask for.
490
+ */
491
+ async function fetchThreads(includeClosed, asJson, what) {
492
+ const reply = await askDaemon({
493
+ t: "threads",
494
+ id: "threads",
495
+ req: { includeClosed },
496
+ // As on `roster`, `ask` and `vaults`: which repo the caller is standing in, since a CLI
497
+ // has no session to speak for it.
498
+ cwd: process.cwd(),
499
+ }, 20_000);
500
+ if (!reply)
501
+ return daemonSilent(asJson, what);
502
+ if (reply.t === "error") {
503
+ return fail(asJson, reply.code, reply.message, [
504
+ ...(reply.hints ?? []),
505
+ ...hintsForCode(reply.code),
506
+ ]);
507
+ }
508
+ if (reply.t !== "threads.ok")
509
+ return unexpectedReply(asJson);
510
+ return reply.threads;
511
+ }
512
+ /**
513
+ * Nothing answered, which has two causes needing different sentences.
514
+ *
515
+ * A daemon that predates these arms does not refuse the request — it drops it. `IpcServer.
516
+ * dispatch` logs an unparseable line and sends nothing back, because hook scripts are
517
+ * fire-and-forget and never read a reply, so a request its schema does not recognise is
518
+ * indistinguishable from a daemon that is not running *unless somebody asks*. So we ask. A ping
519
+ * costs a second and a half on a path that has already failed, and it turns "the daemon is not
520
+ * responding" — which would send a person to restart a daemon that is working perfectly — into
521
+ * a version skew with an obvious fix. It is worth the extra round trip here in particular:
522
+ * these two commands are the ones somebody runs when they want spending to stop, and being
523
+ * sent to debug the wrong thing is expensive in exactly that moment.
524
+ */
525
+ async function daemonSilent(asJson, what) {
526
+ if (await daemonIsRunning()) {
527
+ return fail(asJson, "daemon_too_old", `This machine's daemon cannot ${what} yet.`, [
528
+ "It answered a ping and then ignored the request, which is what a daemon older than this",
529
+ "CLI does with one it has never heard of.",
530
+ "Run `popover update` to bring both halves to the same build.",
531
+ ]);
532
+ }
533
+ return fail(asJson, "daemon_unreachable", "The popover daemon is not responding.", [
534
+ "Start it with `popover daemon start`, or check `popover doctor`.",
535
+ ]);
536
+ }
537
+ function unexpectedReply(asJson) {
538
+ return fail(asJson, "unexpected_response", "Unexpected response from the daemon.", [
539
+ "The daemon may be older than this CLI. Run `popover update`.",
540
+ ]);
541
+ }
542
+ function hintsForCode(code) {
543
+ if (code === "thread_not_found") {
544
+ return [
545
+ "Run `popover threads --all` — it may have closed itself since you listed it. The same",
546
+ "code answers a backend that has no threads table yet, so `popover update` if this",
547
+ "machine has never seen one work.",
548
+ ];
549
+ }
550
+ if (code === "thread_closed") {
551
+ return [
552
+ "Either party can close one, and 24 hours of no activity closes it too.",
553
+ "Anything already filed on it still delivers when that session resumes.",
554
+ ];
555
+ }
556
+ if (code === "not_authenticated")
557
+ return ["Run `popover login` to reconnect this machine."];
558
+ if (code === "cloud_unreachable") {
559
+ return [
560
+ "A thread lives in the database rather than in either session (§3), so neither listing",
561
+ "nor closing one can be served from this machine alone. Check the network, then retry.",
562
+ ];
563
+ }
564
+ return [];
565
+ }
566
+ function fail(asJson, code, message, hints) {
567
+ if (asJson) {
568
+ console.log(JSON.stringify({ ok: false, error: code, message, hints }));
569
+ return 1;
570
+ }
571
+ bad(message);
572
+ for (const hint of hints)
573
+ dim(hint);
574
+ return 1;
575
+ }
576
+ //# sourceMappingURL=threads.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threads.js","sourceRoot":"","sources":["../src/threads.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"vaults.d.ts","sourceRoot":"","sources":["../src/vaults.ts"],"names":[],"mappings":"AAEA,OAAO,EAkBL,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAKhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlE;AAyCD,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYpD;AAOD,+FAA+F;AAC/F,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9D;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,aAAa,CA8BzD;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAiBjF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,MAAM,CAGT;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKnE;AAED,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAUtD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE,GAAG,IAAI,CAqClE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAK,GAAG,MAAM,CAIzE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAK,GAAG,MAAM,CAI3E;AAokBD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,EAAE,OAAO,CAAC;CACf"}
1
+ {"version":3,"file":"vaults.d.ts","sourceRoot":"","sources":["../src/vaults.ts"],"names":[],"mappings":"AAEA,OAAO,EAmBL,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAC;AAMhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAMH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBlE;AA2CD,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYpD;AAOD,+FAA+F;AAC/F,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAM9D;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,aAAa,CA8BzD;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAiBjF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG,MAAM,CAGT;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKnE;AAED,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,EAAE,CAUtD;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYpE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,EAAE,GAAG,IAAI,CAqClE;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAK,GAAG,MAAM,CAIzE;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAK,GAAG,MAAM,CAI3E;AAgoBD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,KAAK,CAAC;IACV,MAAM,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB;;;;;;;OAOG;IACH,IAAI,EAAE,OAAO,CAAC;CACf"}