@popoverinstall/cli 0.4.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/dist/index.js ADDED
@@ -0,0 +1,398 @@
1
+ #!/usr/bin/env node
2
+ import { execFile, spawn } from "node:child_process";
3
+ import { existsSync, mkdirSync, openSync, readFileSync, rmSync } from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { promisify } from "node:util";
7
+ import { PACKAGE_NAME, clearCredentials, daemonEntryPointerPath, daemonLogPath, defaultApiUrl, installCommand, loadCredentials, popoverHome, } from "@popoverinstall/shared";
8
+ import { resolveDaemonEntry } from "./daemon-entry.js";
9
+ import { doctor } from "./doctor.js";
10
+ import { askDaemon, daemonIsRunning } from "./ipc-client.js";
11
+ import { login } from "./login.js";
12
+ import { setup } from "./setup.js";
13
+ import { bad, c, dim, info, ok, warn } from "./ui.js";
14
+ const execFileAsync = promisify(execFile);
15
+ /**
16
+ * This package's own version, read from the manifest npm installed beside us.
17
+ *
18
+ * `import.meta.url` is `<pkg>/dist/index.js` under every layout — global install, dev
19
+ * checkout, `npm link` — so `../package.json` is always this package's. Reading it beats a
20
+ * hardcoded constant that silently drifts from what was published.
21
+ */
22
+ export const VERSION = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
23
+ async function main() {
24
+ const [command = "help", ...rest] = process.argv.slice(2);
25
+ switch (command) {
26
+ case "login":
27
+ return login(flag(rest, "--api") ?? defaultApiUrl());
28
+ case "setup":
29
+ return setup({ force: rest.includes("--force") });
30
+ case "logout":
31
+ clearCredentials();
32
+ ok("Signed out. The daemon will stop publishing after it restarts.");
33
+ dim("Revoke the machine at the dashboard to cut off access immediately.");
34
+ return 0;
35
+ case "update":
36
+ return update();
37
+ case "status":
38
+ return status();
39
+ case "doctor":
40
+ return doctor();
41
+ case "team":
42
+ return team();
43
+ case "ask":
44
+ return ask(rest);
45
+ case "daemon":
46
+ return daemonCommand(rest[0] ?? "status");
47
+ case "log":
48
+ return showLog(Number(flag(rest, "--lines") ?? 20));
49
+ case "uninstall":
50
+ return uninstall();
51
+ case "help":
52
+ case "--help":
53
+ case "-h":
54
+ usage();
55
+ return 0;
56
+ case "--version":
57
+ case "-v":
58
+ console.log(VERSION);
59
+ return 0;
60
+ default:
61
+ bad(`Unknown command: ${command}`);
62
+ usage();
63
+ return 1;
64
+ }
65
+ }
66
+ function usage() {
67
+ console.log(`
68
+ ${c.bold("popover")} — talk to your teammates' Claude Code agents
69
+
70
+ ${c.bold("popover login")} [--api URL] Connect this machine to your team
71
+ ${c.bold("popover logout")} Forget this machine's credentials
72
+ ${c.bold("popover setup")} [--force] Re-register the Claude Code plugin
73
+ ${c.bold("popover update")} Upgrade to the newest version and restart the daemon
74
+ ${c.bold("popover status")} Show this machine's sessions and connection
75
+ ${c.bold("popover team")} Print the team roster
76
+ ${c.bold("popover ask")} <who> <question> Ask a teammate's agent directly
77
+ ${c.bold("popover doctor")} Diagnose setup problems
78
+ ${c.bold("popover daemon")} <start|stop|restart|status|logs>
79
+ ${c.bold("popover log")} [--lines N] Recent questions asked of your agents
80
+ ${c.bold("popover uninstall")} Remove popover from this machine
81
+ `);
82
+ }
83
+ /**
84
+ * Upgrade this machine through npm, then bring the daemon back up on the new build.
85
+ *
86
+ * Two details survive from the old installer-based version and still matter:
87
+ *
88
+ * 1. **npm replaces the directory this process is executing from.** Node has already read
89
+ * the CLI's modules into memory so execution survives, but on Windows a directory that
90
+ * is a process's cwd cannot be removed — hence `cwd: os.tmpdir()`. Nothing below may
91
+ * lazily import after that point either.
92
+ * 2. **A file another process holds open cannot be replaced.** The daemon runs out of the
93
+ * tree being swapped, so it has to be down first.
94
+ *
95
+ * Everything else got simpler: npm exits nonzero on failure, so the old stdout regex and
96
+ * the VERSION-file readback are gone.
97
+ *
98
+ * `setup()` has to run afterwards. Claude Code caches plugins by version, so without
99
+ * re-registering, the user keeps running the previous plugin against the new daemon — a
100
+ * version skew that produces no error, just quietly stale behaviour.
101
+ */
102
+ async function update() {
103
+ // Asked before stopping it, because the daemon is the only thing that knows which
104
+ // version the backend publishes.
105
+ const pong = await askDaemon({ t: "ping", id: "update" }, 2_000);
106
+ const expected = pong?.t === "pong" ? pong.update?.latest : undefined;
107
+ // Rewriting a running `.cmd` shim can corrupt it mid-execution, because cmd.exe reads
108
+ // batch files incrementally. Hand the command over instead of running it ourselves.
109
+ if (process.platform === "win32") {
110
+ info("Run this to upgrade, then `popover setup`:");
111
+ console.log(`\n ${installCommand()}\n`);
112
+ return 0;
113
+ }
114
+ info(`Updating ${PACKAGE_NAME} (${VERSION} → ${expected ?? "latest"})`);
115
+ await daemonCommand("stop").catch(() => 0);
116
+ try {
117
+ const { stdout } = await execFileAsync("npm", ["install", "-g", `${PACKAGE_NAME}@latest`], {
118
+ cwd: os.tmpdir(),
119
+ timeout: 300_000,
120
+ maxBuffer: 16 * 1024 * 1024,
121
+ });
122
+ process.stdout.write(stdout);
123
+ }
124
+ catch (err) {
125
+ process.stdout.write(err.stdout ?? "");
126
+ bad(`npm failed: ${err instanceof Error ? err.message : String(err)}`);
127
+ dim(`To upgrade by hand: ${installCommand()}`);
128
+ // Never leave the machine with no daemon because an update went wrong.
129
+ await daemonCommand("start");
130
+ return 1;
131
+ }
132
+ // Re-register the plugin at its new version before restarting, so Claude Code and the
133
+ // daemon come back up on the same build.
134
+ await setup({ force: true });
135
+ const started = await daemonCommand("start");
136
+ ok("Updated.");
137
+ dim("Restart Claude Code to pick up the new plugin; the daemon is already on the new build.");
138
+ return started;
139
+ }
140
+ /**
141
+ * Undo what `popover setup` did, in the order that keeps the machine consistent if any
142
+ * single step fails: stop publishing, then unhook Claude Code.
143
+ *
144
+ * Deliberately does not revoke the machine server-side — that would silently drop a
145
+ * teammate's audit trail. `popover logout` before this if you want the token dead too.
146
+ */
147
+ async function uninstall() {
148
+ await daemonCommand("stop").catch(() => 0);
149
+ for (const args of [
150
+ ["plugin", "uninstall", "popover"],
151
+ ["plugin", "marketplace", "remove", "popover"],
152
+ ]) {
153
+ try {
154
+ await execFileAsync("claude", args, { timeout: 20_000 });
155
+ }
156
+ catch {
157
+ // Already gone, or Claude Code is not installed. Neither should stop the removal.
158
+ }
159
+ }
160
+ ok("unhooked from Claude Code");
161
+ // The pointer file names a path inside the npm tree that is about to go away. Left
162
+ // behind, it would send the next SessionStart hook at a daemon that no longer exists.
163
+ const home = popoverHome();
164
+ rmSync(daemonEntryPointerPath(), { force: true });
165
+ ok("removed the daemon pointer");
166
+ dim(`Credentials and logs are left in ${home}. Delete the directory to remove those too.`);
167
+ dim(`Remove the command itself with: npm uninstall -g ${PACKAGE_NAME}`);
168
+ return 0;
169
+ }
170
+ async function status() {
171
+ const creds = loadCredentials();
172
+ const pong = await askDaemon({ t: "ping", id: "status" }, 2000);
173
+ if (!pong || pong.t !== "pong") {
174
+ warn("Daemon not running. Start it with `popover daemon start`.");
175
+ return 1;
176
+ }
177
+ ok(`Daemon running (v${pong.version})`);
178
+ if (!creds || !pong.authenticated) {
179
+ warn(creds ? "Daemon is not authenticated." : "Not signed in. Run `popover login`.");
180
+ // Still show what this machine can see locally — it separates "the status feed is
181
+ // broken" from "we just cannot reach the backend".
182
+ return localSessions();
183
+ }
184
+ info(`Signed in · ${creds.api_url}`);
185
+ return team();
186
+ }
187
+ async function localSessions() {
188
+ const reply = await askDaemon({ t: "local", id: "status-local" }, 5000);
189
+ if (reply?.t !== "local.ok")
190
+ return 1;
191
+ console.log("");
192
+ console.log(c.dim(" This machine's sessions:"));
193
+ console.log("");
194
+ console.log(reply.rendered);
195
+ console.log("");
196
+ return 0;
197
+ }
198
+ async function team() {
199
+ // The directory you are standing in is what scopes the roster: agents are only visible to
200
+ // each other inside the same repo, and a bare `popover team` has no session to speak for it.
201
+ const reply = await askDaemon({ t: "roster", id: "team", refresh: true, cwd: process.cwd() }, 15000);
202
+ if (!reply) {
203
+ bad("The daemon is not responding. Try `popover daemon restart`.");
204
+ return 1;
205
+ }
206
+ if (reply.t === "error") {
207
+ bad(reply.message);
208
+ return 1;
209
+ }
210
+ if (reply.t !== "roster.ok") {
211
+ bad("Unexpected response from the daemon.");
212
+ return 1;
213
+ }
214
+ console.log("");
215
+ console.log(reply.rendered);
216
+ console.log("");
217
+ return 0;
218
+ }
219
+ async function ask(args) {
220
+ const [target, ...questionParts] = args;
221
+ const question = questionParts.join(" ").trim();
222
+ if (!target || !question) {
223
+ bad("Usage: popover ask <agent> <question>");
224
+ dim('e.g. popover ask B1 "why did you rule out redis?"');
225
+ return 1;
226
+ }
227
+ process.stdout.write(c.dim(` Asking ${target}…`));
228
+ const started = Date.now();
229
+ const ticker = setInterval(() => process.stdout.write(c.dim(".")), 2000);
230
+ const reply = await askDaemon({
231
+ t: "ask",
232
+ id: "cli-ask",
233
+ req: { target, question, timeoutSeconds: 90 },
234
+ cwd: process.cwd(),
235
+ }, 120_000);
236
+ clearInterval(ticker);
237
+ console.log("");
238
+ if (!reply) {
239
+ bad("The daemon is not responding.");
240
+ return 1;
241
+ }
242
+ if (reply.t === "error") {
243
+ bad(reply.message);
244
+ return 1;
245
+ }
246
+ if (reply.t !== "ask.ok") {
247
+ bad("Unexpected response from the daemon.");
248
+ return 1;
249
+ }
250
+ const { answer } = reply;
251
+ const by = answer.answeredBy;
252
+ console.log("");
253
+ console.log(c.bold(by ? `${by.handle} — ${by.ownerName} (${by.repo})` : "Answer"));
254
+ console.log("");
255
+ console.log(answer.answer ?? "(no answer)");
256
+ console.log("");
257
+ dim(`${((Date.now() - started) / 1000).toFixed(1)}s` +
258
+ (answer.costUsd != null ? ` · $${answer.costUsd.toFixed(3)} on their account` : ""));
259
+ return 0;
260
+ }
261
+ async function daemonCommand(sub) {
262
+ switch (sub) {
263
+ case "start": {
264
+ if (await daemonIsRunning()) {
265
+ ok("Daemon is already running.");
266
+ return 0;
267
+ }
268
+ const entry = resolveDaemonEntry();
269
+ if (!entry) {
270
+ bad("Could not find the daemon build.");
271
+ dim("Run `npm run build` in the popover repo, or set POPOVER_DAEMON_ENTRY.");
272
+ return 1;
273
+ }
274
+ mkdirSync(popoverHome(), { recursive: true });
275
+ const out = openSync(path.join(popoverHome(), "daemon-stdout.log"), "a");
276
+ const child = spawn(process.execPath, [entry], {
277
+ detached: true,
278
+ stdio: ["ignore", out, out],
279
+ windowsHide: true,
280
+ });
281
+ child.unref();
282
+ for (let i = 0; i < 20; i += 1) {
283
+ await sleep(250);
284
+ if (await daemonIsRunning()) {
285
+ ok("Daemon started.");
286
+ return 0;
287
+ }
288
+ }
289
+ bad("Daemon did not come up. Check `popover daemon logs`.");
290
+ return 1;
291
+ }
292
+ case "stop": {
293
+ // Ask over the pipe before resorting to a signal. The daemon marks its sessions
294
+ // offline on the way down, but only if that code runs — and on Windows
295
+ // `process.kill(pid, "SIGTERM")` force-terminates, so it never does and every stop
296
+ // leaves teammates looking at rows for agents that are gone.
297
+ const reply = await askDaemon({ t: "stop", id: "cli" }, 3_000);
298
+ if (reply?.t === "stopping") {
299
+ for (let i = 0; i < 40; i += 1) {
300
+ if (!(await daemonIsRunning())) {
301
+ ok("Daemon stopped.");
302
+ return 0;
303
+ }
304
+ await sleep(250);
305
+ }
306
+ warn("The daemon accepted the stop but is still running; signalling it.");
307
+ }
308
+ // Fallback: a daemon too old to know this request, or one that is wedged.
309
+ const lock = path.join(popoverHome(), "daemon.lock");
310
+ if (!existsSync(lock)) {
311
+ warn("No daemon lock file; it may not be running.");
312
+ return 0;
313
+ }
314
+ const pid = Number(readFileSync(lock, "utf8").trim());
315
+ if (!Number.isFinite(pid)) {
316
+ bad("Lock file is unreadable.");
317
+ return 1;
318
+ }
319
+ try {
320
+ process.kill(pid, "SIGTERM");
321
+ ok(`Signalled daemon (pid ${pid}).`);
322
+ return 0;
323
+ }
324
+ catch {
325
+ warn("Daemon was not running.");
326
+ return 0;
327
+ }
328
+ }
329
+ case "restart":
330
+ await daemonCommand("stop");
331
+ await sleep(1200);
332
+ return daemonCommand("start");
333
+ case "status":
334
+ if (await daemonIsRunning()) {
335
+ ok("Daemon is running.");
336
+ return 0;
337
+ }
338
+ warn("Daemon is not running.");
339
+ return 1;
340
+ case "logs": {
341
+ const file = daemonLogPath();
342
+ if (!existsSync(file)) {
343
+ warn("No daemon log yet.");
344
+ return 0;
345
+ }
346
+ const lines = readFileSync(file, "utf8").split("\n").filter(Boolean).slice(-40);
347
+ for (const line of lines) {
348
+ try {
349
+ const entry = JSON.parse(line);
350
+ const colour = entry.level === "error" ? c.red : entry.level === "warn" ? c.yellow : c.dim;
351
+ console.log(`${c.dim(entry.t)} ${colour(entry.level)} ${entry.message}`);
352
+ }
353
+ catch {
354
+ console.log(line);
355
+ }
356
+ }
357
+ return 0;
358
+ }
359
+ default:
360
+ bad(`Unknown daemon command: ${sub}`);
361
+ return 1;
362
+ }
363
+ }
364
+ function showLog(limit) {
365
+ const file = path.join(popoverHome(), "notifications.jsonl");
366
+ if (!existsSync(file)) {
367
+ info("No teammate has asked your agents anything yet.");
368
+ return 0;
369
+ }
370
+ const lines = readFileSync(file, "utf8").split("\n").filter(Boolean).slice(-limit);
371
+ console.log("");
372
+ for (const line of lines) {
373
+ try {
374
+ const entry = JSON.parse(line);
375
+ console.log(`${c.dim(new Date(entry.at).toLocaleString())} ${c.bold(entry.askerName)} → ${entry.handle} ${c.dim(`(${entry.repo})`)}`);
376
+ console.log(` ${entry.question}`);
377
+ console.log("");
378
+ }
379
+ catch {
380
+ /* skip malformed */
381
+ }
382
+ }
383
+ return 0;
384
+ }
385
+ function flag(args, name) {
386
+ const idx = args.indexOf(name);
387
+ return idx === -1 ? undefined : args[idx + 1];
388
+ }
389
+ function sleep(ms) {
390
+ return new Promise((r) => setTimeout(r, ms));
391
+ }
392
+ main()
393
+ .then((code) => process.exit(code))
394
+ .catch((err) => {
395
+ bad(err instanceof Error ? err.message : String(err));
396
+ process.exit(1);
397
+ });
398
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { type IpcRequest, type IpcResponse } from "@popoverinstall/shared";
2
+ /** Send one request to the daemon and wait for its reply. */
3
+ export declare function askDaemon(req: IpcRequest, timeoutMs?: number): Promise<IpcResponse | null>;
4
+ export declare function daemonIsRunning(): Promise<boolean>;
5
+ //# sourceMappingURL=ipc-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc-client.d.ts","sourceRoot":"","sources":["../src/ipc-client.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,WAAW,EACjB,MAAM,wBAAwB,CAAC;AAEhC,6DAA6D;AAC7D,wBAAgB,SAAS,CACvB,GAAG,EAAE,UAAU,EACf,SAAS,SAAS,GACjB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CA6B7B;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAGxD"}
@@ -0,0 +1,38 @@
1
+ import net from "node:net";
2
+ import { IpcResponseSchema, LineDecoder, daemonAddress, encodeMessage, } from "@popoverinstall/shared";
3
+ /** Send one request to the daemon and wait for its reply. */
4
+ export function askDaemon(req, timeoutMs = 10_000) {
5
+ return new Promise((resolve) => {
6
+ const socket = net.createConnection(daemonAddress());
7
+ const decoder = new LineDecoder();
8
+ let done = false;
9
+ const finish = (value) => {
10
+ if (done)
11
+ return;
12
+ done = true;
13
+ clearTimeout(timer);
14
+ socket.destroy();
15
+ resolve(value);
16
+ };
17
+ const timer = setTimeout(() => finish(null), timeoutMs);
18
+ socket.on("connect", () => socket.write(encodeMessage(req)));
19
+ socket.on("data", (chunk) => {
20
+ for (const line of decoder.push(chunk)) {
21
+ try {
22
+ const parsed = IpcResponseSchema.safeParse(JSON.parse(line));
23
+ if (parsed.success)
24
+ return finish(parsed.data);
25
+ }
26
+ catch {
27
+ /* keep reading */
28
+ }
29
+ }
30
+ });
31
+ socket.on("error", () => finish(null));
32
+ });
33
+ }
34
+ export async function daemonIsRunning() {
35
+ const reply = await askDaemon({ t: "ping", id: "cli" }, 1500);
36
+ return reply?.t === "pong";
37
+ }
38
+ //# sourceMappingURL=ipc-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ipc-client.js","sourceRoot":"","sources":["../src/ipc-client.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EACL,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,aAAa,GAGd,MAAM,wBAAwB,CAAC;AAEhC,6DAA6D;AAC7D,MAAM,UAAU,SAAS,CACvB,GAAe,EACf,SAAS,GAAG,MAAM;IAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAC;QACrD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,IAAI,IAAI,GAAG,KAAK,CAAC;QAEjB,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAE,EAAE;YAC3C,IAAI,IAAI;gBAAE,OAAO;YACjB,IAAI,GAAG,IAAI,CAAC;YACZ,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC,CAAC;QAEF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAExD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAC1B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;oBAC7D,IAAI,MAAM,CAAC,OAAO;wBAAE,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,kBAAkB;gBACpB,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9D,OAAO,KAAK,EAAE,CAAC,KAAK,MAAM,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Device authorization flow.
3
+ *
4
+ * The device token is generated HERE and never sent anywhere — only its hash goes to the
5
+ * server. So there is no point in the flow, and no log or response body, where a usable
6
+ * long-lived credential is in transit. The separate device code authenticates polling
7
+ * and is discarded once claimed.
8
+ */
9
+ export declare function login(apiUrl: string): Promise<number>;
10
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4G3D"}
package/dist/login.js ADDED
@@ -0,0 +1,128 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import os from "node:os";
3
+ import { saveCredentials } from "@popoverinstall/shared";
4
+ import { c, dim, info, ok, bad, openBrowser } from "./ui.js";
5
+ import { askDaemon } from "./ipc-client.js";
6
+ const sha256 = (v) => createHash("sha256").update(v, "utf8").digest("hex");
7
+ const secret = () => randomBytes(32).toString("base64url");
8
+ /**
9
+ * Device authorization flow.
10
+ *
11
+ * The device token is generated HERE and never sent anywhere — only its hash goes to the
12
+ * server. So there is no point in the flow, and no log or response body, where a usable
13
+ * long-lived credential is in transit. The separate device code authenticates polling
14
+ * and is discarded once claimed.
15
+ */
16
+ export async function login(apiUrl) {
17
+ const deviceToken = secret();
18
+ const deviceCode = secret();
19
+ let start;
20
+ try {
21
+ const res = await fetch(`${apiUrl}/api/device/start`, {
22
+ method: "POST",
23
+ headers: { "content-type": "application/json" },
24
+ body: JSON.stringify({
25
+ device_token_hash: sha256(deviceToken),
26
+ device_code_hash: sha256(deviceCode),
27
+ hostname: os.hostname(),
28
+ os: `${os.type()} ${os.release()}`,
29
+ }),
30
+ });
31
+ if (!res.ok) {
32
+ bad(`Could not start login (${res.status}). Is ${apiUrl} reachable?`);
33
+ return 1;
34
+ }
35
+ start = (await res.json());
36
+ }
37
+ catch (err) {
38
+ bad(`Could not reach ${apiUrl}: ${err instanceof Error ? err.message : String(err)}`);
39
+ return 1;
40
+ }
41
+ console.log("");
42
+ info("Confirm this code in your browser:");
43
+ console.log("");
44
+ console.log(` ${c.bold(c.cyan(start.user_code))}`);
45
+ console.log("");
46
+ dim(start.verify_url);
47
+ console.log("");
48
+ await openBrowser(start.verify_url_complete);
49
+ const intervalMs = (start.poll_interval_seconds ?? 2) * 1000;
50
+ const deadline = Date.parse(start.expires_at);
51
+ process.stdout.write(c.dim(" Waiting for approval"));
52
+ for (;;) {
53
+ if (Date.now() > deadline) {
54
+ console.log("");
55
+ bad("That code expired. Run `popover login` again.");
56
+ return 1;
57
+ }
58
+ await sleep(intervalMs);
59
+ process.stdout.write(c.dim("."));
60
+ let status;
61
+ try {
62
+ const res = await fetch(`${apiUrl}/api/device/poll`, {
63
+ method: "POST",
64
+ headers: { "content-type": "application/json" },
65
+ body: JSON.stringify({ device_code: deviceCode }),
66
+ });
67
+ status = (await res.json());
68
+ }
69
+ catch {
70
+ continue; // transient network blip; keep waiting
71
+ }
72
+ if (status.status === "pending")
73
+ continue;
74
+ console.log("");
75
+ if (status.status === "denied") {
76
+ bad("Login denied. Nothing was connected.");
77
+ return 1;
78
+ }
79
+ if (status.status !== "approved" || !status.machine_id) {
80
+ bad(`Login ${status.status}. Run \`popover login\` again.`);
81
+ return 1;
82
+ }
83
+ // Immediately exercise the token so a broken backend config surfaces now, at a
84
+ // prompt, rather than later inside a detached daemon.
85
+ const session = await exchange(apiUrl, deviceToken);
86
+ if (!session) {
87
+ bad("Connected, but the machine could not obtain an access token.");
88
+ dim("Check SUPABASE_JWT_SECRET on the server, then run `popover doctor`.");
89
+ return 1;
90
+ }
91
+ saveCredentials({
92
+ api_url: apiUrl,
93
+ device_token: deviceToken,
94
+ machine_id: status.machine_id,
95
+ clerk_user_id: session.clerk_user_id,
96
+ display_name: "",
97
+ });
98
+ // Nudge a daemon that is already running. It read credentials at boot — before this
99
+ // login — and a ping makes it pick them up now, instead of telling the user to run
100
+ // `popover login` the next time they open /team. Best effort: no daemon is fine, the
101
+ // next start reads the file anyway.
102
+ await askDaemon({ t: "ping", id: "login" }, 5_000);
103
+ ok("This machine is connected.");
104
+ dim("Your Claude Code sessions will appear to your team while they are running.");
105
+ dim("Run `/team` inside Claude Code to see everyone.");
106
+ return 0;
107
+ }
108
+ }
109
+ async function exchange(apiUrl, deviceToken) {
110
+ try {
111
+ const res = await fetch(`${apiUrl}/api/device/session`, {
112
+ method: "POST",
113
+ headers: { "content-type": "application/json" },
114
+ // Same reason as doctor's call: only the daemon may report a daemon version.
115
+ body: JSON.stringify({ device_token: deviceToken }),
116
+ });
117
+ if (!res.ok)
118
+ return null;
119
+ return (await res.json());
120
+ }
121
+ catch {
122
+ return null;
123
+ }
124
+ }
125
+ function sleep(ms) {
126
+ return new Promise((r) => setTimeout(r, ms));
127
+ }
128
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnF,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAE3D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,MAAc;IACxC,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC;IAC7B,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC;IAE5B,IAAI,KAMH,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,mBAAmB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,iBAAiB,EAAE,MAAM,CAAC,WAAW,CAAC;gBACtC,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC;gBACpC,QAAQ,EAAE,EAAE,CAAC,QAAQ,EAAE;gBACvB,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;aACnC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,GAAG,CAAC,0BAA0B,GAAG,CAAC,MAAM,SAAS,MAAM,aAAa,CAAC,CAAC;YACtE,OAAO,CAAC,CAAC;QACX,CAAC;QACD,KAAK,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiB,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,mBAAmB,MAAM,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,CAAC,oCAAoC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,MAAM,WAAW,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAE7C,MAAM,UAAU,GAAG,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC9C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAEtD,SAAS,CAAC;QACR,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,GAAG,CAAC,+CAA+C,CAAC,CAAC;YACrD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAEjC,IAAI,MAA+C,CAAC;QACpD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,kBAAkB,EAAE;gBACnD,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;aAClD,CAAC,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAkB,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,uCAAuC;QACnD,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;YAAE,SAAS;QAC1C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,GAAG,CAAC,sCAAsC,CAAC,CAAC;YAC5C,OAAO,CAAC,CAAC;QACX,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACvD,GAAG,CAAC,SAAS,MAAM,CAAC,MAAM,gCAAgC,CAAC,CAAC;YAC5D,OAAO,CAAC,CAAC;QACX,CAAC;QAED,+EAA+E;QAC/E,sDAAsD;QACtD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,8DAA8D,CAAC,CAAC;YACpE,GAAG,CAAC,qEAAqE,CAAC,CAAC;YAC3E,OAAO,CAAC,CAAC;QACX,CAAC;QAED,eAAe,CAAC;YACd,OAAO,EAAE,MAAM;YACf,YAAY,EAAE,WAAW;YACzB,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,YAAY,EAAE,EAAE;SACjB,CAAC,CAAC;QAEH,oFAAoF;QACpF,mFAAmF;QACnF,qFAAqF;QACrF,oCAAoC;QACpC,MAAM,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAEnD,EAAE,CAAC,4BAA4B,CAAC,CAAC;QACjC,GAAG,CAAC,4EAA4E,CAAC,CAAC;QAClF,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,qBAAqB,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,6EAA6E;YAC7E,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;SACpD,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA8B,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Connect this npm install to Claude Code.
3
+ *
4
+ * `npm install -g` can place files, but it cannot register a Claude Code plugin or tell the
5
+ * plugin's hooks where the daemon ended up. Those are the two things this does, and they
6
+ * are why installing is two commands rather than one. A `postinstall` script would hide it,
7
+ * but `--ignore-scripts` is common, corporate registries strip scripts, and writing to
8
+ * `~/.claude` from an install hook is not something a package should do unannounced.
9
+ *
10
+ * Safe to re-run: every step is idempotent, and `update` re-runs it on every upgrade.
11
+ */
12
+ export declare function setup({ force }?: {
13
+ force?: boolean | undefined;
14
+ }): Promise<number>;
15
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,EAAE,KAAa,EAAE;;CAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAuCnE"}