@popoverinstall/cli 0.8.1 → 0.9.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +159 -78
  2. package/LICENSE +21 -21
  3. package/README.md +142 -141
  4. package/dist/config-command.d.ts +2 -0
  5. package/dist/config-command.d.ts.map +1 -0
  6. package/dist/config-command.js +80 -0
  7. package/dist/config-command.js.map +1 -0
  8. package/dist/cursor-hooks.d.ts +18 -0
  9. package/dist/cursor-hooks.d.ts.map +1 -0
  10. package/dist/cursor-hooks.js +105 -0
  11. package/dist/cursor-hooks.js.map +1 -0
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +46 -25
  14. package/dist/index.js.map +1 -1
  15. package/dist/keys.d.ts +10 -0
  16. package/dist/keys.d.ts.map +1 -0
  17. package/dist/keys.js +44 -0
  18. package/dist/keys.js.map +1 -0
  19. package/dist/repo-scan.d.ts +130 -0
  20. package/dist/repo-scan.d.ts.map +1 -0
  21. package/dist/repo-scan.js +281 -0
  22. package/dist/repo-scan.js.map +1 -0
  23. package/dist/repos.d.ts +180 -0
  24. package/dist/repos.d.ts.map +1 -0
  25. package/dist/repos.js +1002 -0
  26. package/dist/repos.js.map +1 -0
  27. package/dist/snapshot.d.ts +35 -0
  28. package/dist/snapshot.d.ts.map +1 -1
  29. package/dist/snapshot.js +16 -16
  30. package/dist/snapshot.js.map +1 -1
  31. package/dist/vaults.d.ts +175 -0
  32. package/dist/vaults.d.ts.map +1 -0
  33. package/dist/vaults.js +945 -0
  34. package/dist/vaults.js.map +1 -0
  35. package/package.json +3 -3
  36. package/plugin/.claude-plugin/plugin.json +1 -1
  37. package/plugin/.mcp.json +9 -9
  38. package/plugin/README.md +84 -77
  39. package/plugin/commands/ask.md +65 -65
  40. package/plugin/commands/fork.md +119 -119
  41. package/plugin/commands/repos.md +107 -0
  42. package/plugin/commands/team.md +60 -60
  43. package/plugin/commands/tell.md +66 -66
  44. package/plugin/commands/vault.md +173 -0
  45. package/plugin/hooks/hooks.json +111 -111
  46. package/plugin/mcp/index.mjs +410 -0
  47. package/plugin/scripts/_ipc.mjs +146 -146
  48. package/plugin/scripts/announce-roster.mjs +141 -141
  49. package/plugin/scripts/deliver-messages.mjs +77 -77
  50. package/plugin/scripts/emit-event.mjs +44 -44
  51. package/plugin/scripts/ensure-daemon.mjs +156 -156
  52. package/plugin/scripts/roster.mjs +52 -52
  53. package/plugin/skills/popover/SKILL.md +42 -5
@@ -1,52 +1,52 @@
1
- #!/usr/bin/env node
2
- // Renders the /team menu.
3
- //
4
- // Invoked from the command's `!` injection, so its stdout becomes part of the prompt
5
- // Claude sees. Two consequences shape everything here:
6
- // - always exit 0. A non-zero exit aborts the whole slash command.
7
- // - always print something useful. If the daemon is down, say so in words the model
8
- // can relay, rather than printing an empty section and letting it invent a reason.
9
-
10
- import { callerSessionId, request } from "./_ipc.mjs";
11
-
12
- // `fromSessionId` is what lets the daemon mark this agent's own line. It comes from the
13
- // session's environment, so a bare shell run of this script sends nothing and the roster
14
- // comes back unmarked.
15
- const reply = await request(
16
- {
17
- t: "roster",
18
- id: "cli",
19
- refresh: true,
20
- ...(callerSessionId() ? { fromSessionId: callerSessionId() } : {}),
21
- // Fallback for the window where the daemon has not yet resolved this session's repo —
22
- // the same hint the MCP server sends. Without it an unplaceable caller falls through to
23
- // pure recency across every session on the machine, so `/popover:team` run in one repo
24
- // could print the roster for another, under a heading claiming it was this one.
25
- cwd: process.cwd(),
26
- },
27
- { timeoutMs: 8000 },
28
- );
29
-
30
- if (!reply) {
31
- console.log(
32
- "The popover daemon is not running on this machine, so teammate agents are not visible.\n" +
33
- "Start it with `popover daemon start`, or check `popover doctor`.",
34
- );
35
- } else if (reply.t === "error") {
36
- // The daemon distinguishes "no credentials" from "signed in but cannot connect", so
37
- // relay its message rather than assuming the user has not logged in.
38
- console.log(
39
- reply.code === "not_authenticated"
40
- ? reply.message
41
- : `Could not load the team roster: ${reply.message}`,
42
- );
43
- } else if (reply.t === "roster.ok") {
44
- console.log(reply.rendered);
45
- if (reply.stale) {
46
- console.log("\n(Showing cached data — the backend was unreachable.)");
47
- }
48
- } else {
49
- console.log("The popover daemon returned an unexpected response.");
50
- }
51
-
52
- process.exit(0);
1
+ #!/usr/bin/env node
2
+ // Renders the /team menu.
3
+ //
4
+ // Invoked from the command's `!` injection, so its stdout becomes part of the prompt
5
+ // Claude sees. Two consequences shape everything here:
6
+ // - always exit 0. A non-zero exit aborts the whole slash command.
7
+ // - always print something useful. If the daemon is down, say so in words the model
8
+ // can relay, rather than printing an empty section and letting it invent a reason.
9
+
10
+ import { callerSessionId, request } from "./_ipc.mjs";
11
+
12
+ // `fromSessionId` is what lets the daemon mark this agent's own line. It comes from the
13
+ // session's environment, so a bare shell run of this script sends nothing and the roster
14
+ // comes back unmarked.
15
+ const reply = await request(
16
+ {
17
+ t: "roster",
18
+ id: "cli",
19
+ refresh: true,
20
+ ...(callerSessionId() ? { fromSessionId: callerSessionId() } : {}),
21
+ // Fallback for the window where the daemon has not yet resolved this session's repo —
22
+ // the same hint the MCP server sends. Without it an unplaceable caller falls through to
23
+ // pure recency across every session on the machine, so `/popover:team` run in one repo
24
+ // could print the roster for another, under a heading claiming it was this one.
25
+ cwd: process.cwd(),
26
+ },
27
+ { timeoutMs: 8000 },
28
+ );
29
+
30
+ if (!reply) {
31
+ console.log(
32
+ "The popover daemon is not running on this machine, so teammate agents are not visible.\n" +
33
+ "Start it with `popover daemon start`, or check `popover doctor`.",
34
+ );
35
+ } else if (reply.t === "error") {
36
+ // The daemon distinguishes "no credentials" from "signed in but cannot connect", so
37
+ // relay its message rather than assuming the user has not logged in.
38
+ console.log(
39
+ reply.code === "not_authenticated"
40
+ ? reply.message
41
+ : `Could not load the team roster: ${reply.message}`,
42
+ );
43
+ } else if (reply.t === "roster.ok") {
44
+ console.log(reply.rendered);
45
+ if (reply.stale) {
46
+ console.log("\n(Showing cached data — the backend was unreachable.)");
47
+ }
48
+ } else {
49
+ console.log("The popover daemon returned an unexpected response.");
50
+ }
51
+
52
+ process.exit(0);
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: popover
3
- description: "Judgment for reaching a teammate's Claude Code agent *without being asked to* — when it is worth spending their tokens, and which of /popover:team, /popover:ask, /popover:tell and /popover:fork fits. Nothing to invoke by hand: use it when a question turns on what a colleague decided, ruled out, or is changing right now — why the code is the way it is when the repo does not say, whether work about to start is already in flight, or why something nobody touched is broken."
3
+ description: "Judgment for reaching a teammate's Claude Code agent *without being asked to*, and for keeping this conversation where the team can ask it later — when it is worth spending their tokens, and which of /popover:team, /popover:ask, /popover:tell, /popover:fork and /popover:vault fits. Nothing to invoke by hand: use it when a question turns on what a colleague decided, ruled out, or is changing right now — why the code is the way it is when the repo does not say, whether work about to start is already in flight, or why something nobody touched is broken; or when this session has worked something out that the team will want and the repo will not record, which is the moment to vault it rather than let it be deleted."
4
4
  ---
5
5
 
6
6
  # popover
@@ -10,7 +10,7 @@ accumulated context you do not have: the alternatives they rejected, the constra
10
10
  forced an awkward shape, what they changed twenty minutes ago and have not pushed. popover
11
11
  lets you reach those agents.
12
12
 
13
- **This skill is not a command, and there is nothing here for a user to invoke.** The four
13
+ **This skill is not a command, and there is nothing here for a user to invoke.** The five
14
14
  commands are the things a user types:
15
15
 
16
16
  | | |
@@ -19,6 +19,7 @@ commands are the things a user types:
19
19
  | `/popover:ask` | one question to one agent, and you wait for the answer |
20
20
  | `/popover:tell` | a heads-up into a teammate's live session; nothing comes back |
21
21
  | `/popover:fork` | hand this whole conversation to a teammate |
22
+ | `/popover:vault` | publish this conversation to the team's archive, or ask one already there |
22
23
 
23
24
  This file is the judgment around them: when reaching for one is worth it, which one fits, and
24
25
  what each one spends. It exists because the moment to use popover rarely announces itself. The
@@ -26,13 +27,13 @@ user asks why something is the way it is, and the honest answer is that the repo
26
27
  record it — but a colleague's agent worked it out this morning. Nobody will type `/popover:ask`
27
28
  for you. Noticing is your job.
28
29
 
29
- ## The three tools
30
+ ## The six tools
30
31
 
31
32
  They arrive as deferred MCP tools, so you have their names but not their schemas. Load them
32
33
  before use:
33
34
 
34
35
  ```
35
- ToolSearch("select:mcp__plugin_popover_popover__team_list,mcp__plugin_popover_popover__team_ask,mcp__plugin_popover_popover__team_tell")
36
+ ToolSearch("select:mcp__plugin_popover_popover__team_list,mcp__plugin_popover_popover__team_ask,mcp__plugin_popover_popover__team_tell,mcp__plugin_popover_popover__vault_search,mcp__plugin_popover_popover__vault_ask,mcp__plugin_popover_popover__vault_create")
36
37
  ```
37
38
 
38
39
  Their own descriptions are detailed and authoritative on arguments and limits — read them
@@ -45,6 +46,17 @@ once loaded rather than guessing. In short:
45
46
  cannot be changed by it. Takes up to ~90s by default.
46
47
  - **`team_tell`** — a one- or two-sentence heads-up delivered into a teammate's live session
47
48
  before its next prompt. Nothing comes back, and their user is notified that you sent it.
49
+ - **`vault_search`** — search the conversations your team has frozen and published. Free, no
50
+ model, nothing resumed. Not limited to this repo, and not limited to people who are working
51
+ right now. Always the first of the two.
52
+ - **`vault_ask`** — one question to one vault, answered from its frozen context on *this*
53
+ machine at your user's expense. Roughly $0.50 and up to 90 seconds. Never call it on a
54
+ vault you have not seen in a search result.
55
+ - **`vault_create`** — publish *this* conversation into the archive the other two read.
56
+ The only one of the six that writes something permanent: the whole conversation goes to
57
+ everyone on the team, it does not expire, and it cannot be edited afterwards. You may call
58
+ it on your own judgement — see *Vaults are a different thing again* below — but say plainly
59
+ that a vault is **readable by the popover service**, which a fork is not.
48
60
 
49
61
  ## When to reach for it on your own
50
62
 
@@ -144,6 +156,31 @@ include, and leave it there. If they pass, do not raise it again.
144
156
  When the user wants an *answer* rather than to hand over the whole conversation, an ask is the
145
157
  cheaper and more private thing. Offer that instead.
146
158
 
159
+ ## Vaults are a different thing again
160
+
161
+ A vault is this conversation published to the **team**, permanently, and asked later by
162
+ whoever needs it. Nobody has to be online for it, nobody has to still be at the company, and
163
+ the person asking pays rather than the person who wrote it.
164
+
165
+ **Unlike a fork, creating one is yours to decide.** Not to offer and wait on — to decide. The
166
+ rule differs from the fork rule deliberately: a fork discloses one conversation to one named
167
+ individual, while a vault goes to a team that already shares the repository and the work, so
168
+ the disclosure is smaller and the cost of missing the moment is higher. The moment for a vault
169
+ is one the user is usually too deep in the work to notice, and a conversation nobody vaults is
170
+ deleted when the session ends.
171
+
172
+ It is still a real disclosure, and two things must be said plainly when you make one:
173
+
174
+ - **A vault is readable by the popover service.** A fork is end-to-end and this is not.
175
+ Anyone who has internalized the first will assume the second unless you say otherwise.
176
+ - **It cannot be edited or withdrawn.** A correction is a *note* appended beside the original;
177
+ `popover vault archive` retires a vault without erasing the record that it was made.
178
+
179
+ Vault a conversation that worked something out the team will want and the repo will not
180
+ record — a decision and its reasons, an approach tried and rejected, an investigation into why
181
+ something is the way it is. Do not vault routine work: an index full of everything is one
182
+ nobody trusts, which fails in the same way as vaulting nothing.
183
+
147
184
  ## When it does not work
148
185
 
149
186
  The tools return errors as text; relay them rather than retrying with different arguments.
@@ -158,7 +195,7 @@ The tools return errors as text; relay them rather than retrying with different
158
195
 
159
196
  ## The user-facing commands
160
197
 
161
- The four commands carry the full flows for when the user drives this explicitly — how to
198
+ The five commands carry the full flows for when the user drives this explicitly — how to
162
199
  present a roster, how to word an ask, how to take delivery of a fork. Do not restate their
163
200
  steps here or work around them: **when the user invokes a command, follow that command.** This
164
201
  skill is for the other case, where nobody invoked anything and you noticed the moment yourself.