@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.
@@ -0,0 +1,23 @@
1
+ {
2
+ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
3
+ "name": "popover",
4
+ "description": "Talk to your teammates' Claude Code agents.",
5
+ "owner": {
6
+ "name": "Quolabs",
7
+ "url": "https://github.com/many-ideations/popover"
8
+ },
9
+ "plugins": [
10
+ {
11
+ "name": "popover",
12
+ "source": "./plugin",
13
+ "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.",
14
+ "category": "collaboration",
15
+ "tags": [
16
+ "team",
17
+ "agents",
18
+ "mcp",
19
+ "collaboration"
20
+ ]
21
+ }
22
+ ]
23
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Quolabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # popover
2
+
3
+ See your teammates' active Claude Code agents, and ask them questions.
4
+
5
+ When a teammate's agent has already worked out why the retry logic lives where it does, you
6
+ should be able to ask it — without interrupting your teammate. popover shows you everyone's
7
+ running agents in the same repo, and answers from a read-only fork of the agent's full
8
+ context.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ npm install -g @popoverinstall/cli
14
+ popover login
15
+ ```
16
+
17
+ Requires **Node.js 20+** and **Claude Code 2.1.229+**.
18
+
19
+ `popover login` connects this machine to your team and registers the Claude Code plugin. It
20
+ prints a short code to confirm in your browser; the device token it stores is generated
21
+ locally and never transmitted.
22
+
23
+ ## Use
24
+
25
+ Inside Claude Code, `/team` shows everyone's agents in the repo you are working in. From the
26
+ shell:
27
+
28
+ ```
29
+ popover team Print the team roster
30
+ popover ask <who> <question> Ask a teammate's agent directly
31
+ popover status This machine's sessions and connection
32
+ popover log Recent questions asked of your agents
33
+ popover doctor Diagnose setup problems
34
+ popover update Upgrade and restart the daemon
35
+ ```
36
+
37
+ Agents are only visible to each other **inside the same repo**, so the directory you run from
38
+ is what scopes the roster.
39
+
40
+ ## How it works
41
+
42
+ Three pieces install together:
43
+
44
+ - **the CLI** — the `popover` command
45
+ - **the daemon** — a detached background process that publishes this machine's sessions and
46
+ answers teammates' questions. It stores state in `~/.popover/`.
47
+ - **the Claude Code plugin** — provides `/team` and the MCP tools agents use to reach each
48
+ other. Registered automatically on first login.
49
+
50
+ Answers are produced by a read-only fork of the teammate's agent, billed to their account.
51
+ Their session is never interrupted.
52
+
53
+ ## Uninstall
54
+
55
+ ```bash
56
+ popover uninstall # stop the daemon, unhook Claude Code
57
+ npm uninstall -g @popoverinstall/cli
58
+ ```
59
+
60
+ Credentials and logs are left in `~/.popover/`; delete the directory to remove those too.
61
+
62
+ ## Links
63
+
64
+ - [Source](https://github.com/many-ideations/popover)
65
+ - [Issues](https://github.com/many-ideations/popover/issues)
66
+
67
+ MIT
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Where the daemon build lives.
3
+ *
4
+ * Node's own resolver goes first because it is correct under every layout — npm's nested
5
+ * global tree, a hoisted one, pnpm's store, and the workspace symlink in a dev checkout —
6
+ * without this function having to know which it is looking at. The relative candidates
7
+ * remain for the one case the resolver cannot help with: a source checkout that has been
8
+ * built but never `npm install`ed.
9
+ *
10
+ * Lives in its own module so `setup.ts` can use it without importing `index.ts`, which
11
+ * runs the CLI on import.
12
+ */
13
+ export declare function resolveDaemonEntry(): string | null;
14
+ //# sourceMappingURL=daemon-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-entry.d.ts","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAclD"}
@@ -0,0 +1,35 @@
1
+ import { existsSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ const HERE = path.dirname(fileURLToPath(import.meta.url));
6
+ const require_ = createRequire(import.meta.url);
7
+ /**
8
+ * Where the daemon build lives.
9
+ *
10
+ * Node's own resolver goes first because it is correct under every layout — npm's nested
11
+ * global tree, a hoisted one, pnpm's store, and the workspace symlink in a dev checkout —
12
+ * without this function having to know which it is looking at. The relative candidates
13
+ * remain for the one case the resolver cannot help with: a source checkout that has been
14
+ * built but never `npm install`ed.
15
+ *
16
+ * Lives in its own module so `setup.ts` can use it without importing `index.ts`, which
17
+ * runs the CLI on import.
18
+ */
19
+ export function resolveDaemonEntry() {
20
+ if (process.env.POPOVER_DAEMON_ENTRY && existsSync(process.env.POPOVER_DAEMON_ENTRY)) {
21
+ return process.env.POPOVER_DAEMON_ENTRY;
22
+ }
23
+ try {
24
+ return require_.resolve("@popoverinstall/daemon/entry");
25
+ }
26
+ catch {
27
+ /* not installed as a dependency — fall through to the checkout layout */
28
+ }
29
+ const candidates = [
30
+ path.join(HERE, "..", "..", "daemon", "dist", "index.js"),
31
+ path.join(HERE, "..", "node_modules", "@popoverinstall", "daemon", "dist", "index.js"),
32
+ ];
33
+ return candidates.find((p) => existsSync(p)) ?? null;
34
+ }
35
+ //# sourceMappingURL=daemon-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-entry.js","sourceRoot":"","sources":["../src/daemon-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEhD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAAE,CAAC;QACrF,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAC1C,CAAC;IACD,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;IACD,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;KACvF,CAAC;IACF,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AACvD,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** Minimum Claude Code version. Below this, `claude agents --json` and the fork flags we depend on are missing or differ. */
2
+ export declare const MIN_CLAUDE_VERSION: readonly [2, 1, 229];
3
+ /**
4
+ * Diagnose a machine end to end.
5
+ *
6
+ * Ordered so the first failure is the root cause: no point reporting "roster empty" when
7
+ * the real problem is that the CLI is not installed.
8
+ */
9
+ export declare function doctor(): Promise<number>;
10
+ export declare function claudeVersion(): Promise<string | null>;
11
+ export declare function versionAtLeast(version: string, min: readonly [number, number, number]): boolean;
12
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAUA,6HAA6H;AAC7H,eAAO,MAAM,kBAAkB,sBAAuB,CAAC;AAEvD;;;;;GAKG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CA0H9C;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAY5D;AAcD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAS/F"}
package/dist/doctor.js ADDED
@@ -0,0 +1,199 @@
1
+ import { execFile } from "node:child_process";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { claudeHome, daemonAddress, loadCredentials } from "@popoverinstall/shared";
6
+ import { askDaemon } from "./ipc-client.js";
7
+ import { bad, dim, ok, warn } from "./ui.js";
8
+ const execFileAsync = promisify(execFile);
9
+ /** Minimum Claude Code version. Below this, `claude agents --json` and the fork flags we depend on are missing or differ. */
10
+ export const MIN_CLAUDE_VERSION = [2, 1, 229];
11
+ /**
12
+ * Diagnose a machine end to end.
13
+ *
14
+ * Ordered so the first failure is the root cause: no point reporting "roster empty" when
15
+ * the real problem is that the CLI is not installed.
16
+ */
17
+ export async function doctor() {
18
+ let failures = 0;
19
+ const fail = (msg, hint) => {
20
+ bad(msg);
21
+ if (hint)
22
+ dim(hint);
23
+ failures += 1;
24
+ };
25
+ // 1. Claude Code
26
+ const version = await claudeVersion();
27
+ if (!version) {
28
+ fail("claude CLI not found on PATH", "Install Claude Code, or set POPOVER_CLAUDE_BIN.");
29
+ }
30
+ else if (!versionAtLeast(version, MIN_CLAUDE_VERSION)) {
31
+ fail(`claude ${version} is too old (need ${MIN_CLAUDE_VERSION.join(".")}+)`, "Earlier versions lack `claude agents --json` and the fork flags popover relies on.");
32
+ }
33
+ else {
34
+ ok(`claude ${version}`);
35
+ }
36
+ // 2. Plugin hooks
37
+ const hooksInstalled = pluginLooksInstalled();
38
+ if (hooksInstalled)
39
+ ok("popover plugin found");
40
+ else {
41
+ warn("popover plugin not detected in ~/.claude");
42
+ dim("Install it with: claude plugin install popover@popoverinstall");
43
+ dim("Without it, your sessions will not appear to your team.");
44
+ }
45
+ // 3. Credentials
46
+ const creds = loadCredentials();
47
+ if (!creds) {
48
+ fail("this machine is not signed in", "Run `popover login`.");
49
+ }
50
+ else {
51
+ ok(`signed in (machine ${creds.machine_id.slice(0, 8)}…)`);
52
+ }
53
+ // 4. Daemon
54
+ const pong = await askDaemon({ t: "ping", id: "doctor" }, 2000);
55
+ if (!pong || pong.t !== "pong") {
56
+ fail("daemon is not running", `Start it with \`popover daemon start\`. Socket: ${daemonAddress()}`);
57
+ }
58
+ else {
59
+ ok(`daemon running (v${pong.version})`);
60
+ if (!pong.authenticated) {
61
+ fail("daemon is running but not authenticated", "Its token exchange failed. Check the backend, then `popover daemon restart`.");
62
+ }
63
+ }
64
+ // 5. Backend round trip — the check that actually exercises the JWT path.
65
+ if (creds) {
66
+ try {
67
+ const res = await fetch(`${creds.api_url}/api/device/session`, {
68
+ method: "POST",
69
+ headers: { "content-type": "application/json" },
70
+ // No daemon_version: this is the CLI exercising the token path, not the daemon
71
+ // checking in. Sending one overwrote the recorded version with "doctor", so a
72
+ // machine's Daemon column read "doctor" for as long as nobody restarted it.
73
+ body: JSON.stringify({ device_token: creds.device_token }),
74
+ });
75
+ if (res.ok) {
76
+ ok(`backend reachable (${creds.api_url})`);
77
+ }
78
+ else if (res.status === 401) {
79
+ fail("this machine's access was revoked", "Run `popover login` to reconnect.");
80
+ }
81
+ else {
82
+ fail(`backend returned ${res.status}`, "Check SUPABASE_JWT_SECRET on the server.");
83
+ }
84
+ }
85
+ catch (err) {
86
+ fail(`cannot reach ${creds.api_url}`, err instanceof Error ? err.message : String(err));
87
+ }
88
+ }
89
+ // 6. git — how repos are identified, and therefore who can see whom.
90
+ if (await gitVersion()) {
91
+ ok("git found");
92
+ }
93
+ else {
94
+ fail("git not found on PATH", "popover matches agents by their git remote. Without git every session looks like a " +
95
+ "private directory, and no teammate will ever be visible.");
96
+ }
97
+ // 7. Roster. Scoped to this directory, exactly as `popover team` is.
98
+ if (pong?.t === "pong" && pong.authenticated) {
99
+ const roster = await askDaemon({ t: "roster", id: "doctor", refresh: true, cwd: process.cwd() }, 15000);
100
+ if (roster?.t === "roster.ok") {
101
+ // Reported from the daemon's own answer rather than recomputed here, so this says
102
+ // what `popover team` will actually do in this directory.
103
+ if (roster.scope?.kind === "repo")
104
+ ok(`this directory is ${roster.scope.repo}`);
105
+ else if (roster.scope?.kind === "all") {
106
+ warn("this directory is not a git repository");
107
+ dim("Agents here are private to this machine. Run popover from inside a clone.");
108
+ }
109
+ const others = roster.entries.filter((e) => !e.isSelf).length;
110
+ ok(`roster: ${roster.entries.length} agent(s), ${others} from teammates`);
111
+ if (roster.entries.length === 0) {
112
+ dim("No sessions visible yet. Open a Claude Code session and re-run.");
113
+ }
114
+ if (roster.hiddenOlderClients) {
115
+ warn(`${roster.hiddenOlderClients} teammate machine(s) are on an older popover`);
116
+ dim("They stay hidden until they run `popover update`.");
117
+ }
118
+ }
119
+ else if (roster?.t === "error") {
120
+ fail(`roster failed: ${roster.message}`);
121
+ }
122
+ }
123
+ console.log("");
124
+ if (failures === 0)
125
+ ok("Everything looks healthy.");
126
+ else
127
+ bad(`${failures} problem(s) found.`);
128
+ return failures === 0 ? 0 : 1;
129
+ }
130
+ export async function claudeVersion() {
131
+ const bin = process.env.POPOVER_CLAUDE_BIN ?? "claude";
132
+ try {
133
+ const { stdout } = await execFileAsync(bin, ["--version"], {
134
+ timeout: 10_000,
135
+ windowsHide: true,
136
+ shell: process.platform === "win32",
137
+ });
138
+ return stdout.trim().split(/\s+/)[0] ?? null;
139
+ }
140
+ catch {
141
+ return null;
142
+ }
143
+ }
144
+ async function gitVersion() {
145
+ try {
146
+ const { stdout } = await execFileAsync("git", ["--version"], {
147
+ timeout: 5_000,
148
+ windowsHide: true,
149
+ });
150
+ return stdout.trim() || null;
151
+ }
152
+ catch {
153
+ return null;
154
+ }
155
+ }
156
+ export function versionAtLeast(version, min) {
157
+ const parts = version.split(".").map((p) => Number.parseInt(p, 10));
158
+ for (let i = 0; i < 3; i += 1) {
159
+ const got = parts[i] ?? 0;
160
+ const want = min[i];
161
+ if (got > want)
162
+ return true;
163
+ if (got < want)
164
+ return false;
165
+ }
166
+ return true;
167
+ }
168
+ /**
169
+ * Look for the plugin in Claude Code's settings.
170
+ *
171
+ * Deliberately a soft check: plugins can be enabled at several scopes and loaded from
172
+ * places we cannot enumerate, so a negative result is a warning rather than a failure.
173
+ */
174
+ function pluginLooksInstalled() {
175
+ const candidates = [
176
+ path.join(claudeHome(), "settings.json"),
177
+ path.join(process.cwd(), ".claude", "settings.json"),
178
+ path.join(process.cwd(), ".claude", "settings.local.json"),
179
+ ];
180
+ for (const file of candidates) {
181
+ try {
182
+ if (!existsSync(file))
183
+ continue;
184
+ if (JSON.stringify(JSON.parse(readFileSync(file, "utf8"))).includes("popover")) {
185
+ return true;
186
+ }
187
+ }
188
+ catch {
189
+ /* unreadable settings are not proof of anything */
190
+ }
191
+ }
192
+ // Deliberately no fallback. This used to answer "does ~/.popover/daemon.log exist?",
193
+ // which was a fair proxy when the installer registered the plugin and started the daemon
194
+ // in one step. Under npm the two are separate — `popover daemon start` works fine without
195
+ // `popover setup` — so that fallback reported the plugin as present in exactly the
196
+ // situation this check exists to catch.
197
+ return false;
198
+ }
199
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * This package's own version, read from the manifest npm installed beside us.
4
+ *
5
+ * `import.meta.url` is `<pkg>/dist/index.js` under every layout — global install, dev
6
+ * checkout, `npm link` — so `../package.json` is always this package's. Reading it beats a
7
+ * hardcoded constant that silently drifts from what was published.
8
+ */
9
+ export declare const VERSION: string;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAyBA;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,EAAE,MAEb,CAAC"}