@popoverinstall/cli 0.9.1 → 0.10.0
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/CHANGELOG.md +79 -0
- package/README.md +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/threads.d.ts +163 -0
- package/dist/threads.d.ts.map +1 -0
- package/dist/threads.js +576 -0
- package/dist/threads.js.map +1 -0
- package/package.json +3 -3
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/commands/ask.md +18 -9
- package/plugin/commands/message.md +152 -0
- package/plugin/commands/team.md +9 -7
- package/plugin/commands/tell.md +12 -3
- package/plugin/commands/vault.md +34 -13
- package/plugin/hooks/hooks.json +25 -1
- package/plugin/mcp/index.mjs +323 -7
- package/plugin/scripts/_ipc.mjs +49 -1
- package/plugin/scripts/announce-roster.mjs +5 -4
- package/plugin/scripts/deliver-messages.mjs +7 -5
- package/plugin/scripts/emit-event.mjs +11 -2
- package/plugin/scripts/inject-message.mjs +297 -0
- package/plugin/scripts/nudge-vault.mjs +517 -0
- package/plugin/skills/popover/SKILL.md +159 -70
package/dist/threads.js
ADDED
|
@@ -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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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@popoverinstall/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "See your teammates' active Claude Code agents and ask them questions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"prepack": "node ../../scripts/stage-plugin.mjs && tsc -b"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@popoverinstall/daemon": "0.
|
|
45
|
-
"@popoverinstall/shared": "0.
|
|
44
|
+
"@popoverinstall/daemon": "0.10.0",
|
|
45
|
+
"@popoverinstall/shared": "0.10.0"
|
|
46
46
|
}
|
|
47
47
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "popover",
|
|
4
4
|
"displayName": "Popover",
|
|
5
5
|
"description": "See your teammates' active Claude Code agents and ask them questions. A read-only fork answers from the agent's full context without interrupting your teammate.",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.10.0",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Quolabs"
|
|
9
9
|
},
|