@popoverinstall/cli 0.8.1 → 0.9.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 +147 -78
- package/LICENSE +21 -21
- package/README.md +142 -141
- package/dist/config-command.d.ts +2 -0
- package/dist/config-command.d.ts.map +1 -0
- package/dist/config-command.js +80 -0
- package/dist/config-command.js.map +1 -0
- package/dist/cursor-hooks.d.ts +18 -0
- package/dist/cursor-hooks.d.ts.map +1 -0
- package/dist/cursor-hooks.js +105 -0
- package/dist/cursor-hooks.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -25
- package/dist/index.js.map +1 -1
- package/dist/keys.d.ts +10 -0
- package/dist/keys.d.ts.map +1 -0
- package/dist/keys.js +44 -0
- package/dist/keys.js.map +1 -0
- package/dist/repo-scan.d.ts +130 -0
- package/dist/repo-scan.d.ts.map +1 -0
- package/dist/repo-scan.js +281 -0
- package/dist/repo-scan.js.map +1 -0
- package/dist/repos.d.ts +180 -0
- package/dist/repos.d.ts.map +1 -0
- package/dist/repos.js +1002 -0
- package/dist/repos.js.map +1 -0
- package/dist/snapshot.d.ts +35 -0
- package/dist/snapshot.d.ts.map +1 -1
- package/dist/snapshot.js +16 -16
- package/dist/snapshot.js.map +1 -1
- package/dist/vaults.d.ts +276 -0
- package/dist/vaults.d.ts.map +1 -0
- package/dist/vaults.js +1224 -0
- package/dist/vaults.js.map +1 -0
- package/package.json +47 -47
- package/plugin/.claude-plugin/plugin.json +19 -19
- package/plugin/.mcp.json +9 -9
- package/plugin/README.md +84 -77
- package/plugin/commands/ask.md +65 -65
- package/plugin/commands/fork.md +119 -119
- package/plugin/commands/repos.md +107 -0
- package/plugin/commands/team.md +60 -60
- package/plugin/commands/tell.md +66 -66
- package/plugin/commands/vault.md +173 -0
- package/plugin/hooks/hooks.json +111 -111
- package/plugin/mcp/index.mjs +585 -355
- package/plugin/scripts/_ipc.mjs +146 -146
- package/plugin/scripts/announce-roster.mjs +141 -141
- package/plugin/scripts/deliver-messages.mjs +77 -77
- package/plugin/scripts/emit-event.mjs +44 -44
- package/plugin/scripts/ensure-daemon.mjs +156 -156
- package/plugin/scripts/roster.mjs +52 -52
- package/plugin/skills/popover/SKILL.md +175 -168
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Publish this conversation to your team's vault, or search and ask the ones already there
|
|
3
|
+
# Quoted because an unquoted value starting with `[` is parsed as a YAML flow sequence,
|
|
4
|
+
# which fails and silently drops EVERY field here, allowed-tools included.
|
|
5
|
+
argument-hint: "[create|find|ask|note] <text>"
|
|
6
|
+
# Narrow on purpose. `create` and `note` are the only writes reachable from here; archiving is
|
|
7
|
+
# a terminal command for the reason given under "Archiving".
|
|
8
|
+
allowed-tools: Bash(popover vault create *), Bash(popover vault note *), mcp__plugin_popover_popover__vault_search, mcp__plugin_popover_popover__vault_ask, AskUserQuestion
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Vaults
|
|
12
|
+
|
|
13
|
+
The user ran `/popover:vault`. Arguments, which may be empty: **$ARGUMENTS**
|
|
14
|
+
|
|
15
|
+
This session's id is `${CLAUDE_SESSION_ID}`. You will need it for `create`.
|
|
16
|
+
|
|
17
|
+
A vault is a conversation frozen deliberately and published to a **team**. It does not
|
|
18
|
+
expire, it is never carried on, and it is only ever asked. That makes it a different thing
|
|
19
|
+
from both of its neighbours:
|
|
20
|
+
|
|
21
|
+
- an **ask** (`/popover:ask`) reaches a teammate's *live* agent, which has to be online, and
|
|
22
|
+
spends *their* tokens;
|
|
23
|
+
- a **fork** (`/popover:fork`) hands the whole conversation to *one named person* for 24
|
|
24
|
+
hours, and they continue it as their own session.
|
|
25
|
+
|
|
26
|
+
A vault needs nobody to be online, nobody to still be employed, and costs the person asking
|
|
27
|
+
rather than the person who wrote it. It answers from what it knew when it was frozen and
|
|
28
|
+
nothing else — it has no tools, cannot read the repository as it stands today, and will say
|
|
29
|
+
so rather than guess.
|
|
30
|
+
|
|
31
|
+
The first word of the arguments chooses what to do.
|
|
32
|
+
|
|
33
|
+
## `create` — freeze this conversation into the team's archive
|
|
34
|
+
|
|
35
|
+
Write the description first, because it is the whole retrieval surface and it cannot be
|
|
36
|
+
edited afterwards.
|
|
37
|
+
|
|
38
|
+
- **`--title`** is a short human label for a card in a grid.
|
|
39
|
+
- **`--answers`** is the load-bearing one, and it holds **questions this conversation can
|
|
40
|
+
answer** — not a summary of what happened. Write each one the way a teammate would type it
|
|
41
|
+
months from now: *"Why did we reject the repo key as a vault credential?"*, not *"discussed
|
|
42
|
+
encryption options"*. Three to six is right. The reason is retrieval: the incoming query is
|
|
43
|
+
a question, and matching a question against a summary retrieves badly where question
|
|
44
|
+
against question does not. It also forces you to be honest about scope at the one moment
|
|
45
|
+
you actually know what the scope was — now.
|
|
46
|
+
|
|
47
|
+
Then run:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
popover vault create --session ${CLAUDE_SESSION_ID} --title "<title>" --answers "<a question this can answer>" --answers "<another one>" --json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
On `ok: false`, relay `message` and the `hints` verbatim and stop. Do not retry with
|
|
54
|
+
different flags.
|
|
55
|
+
|
|
56
|
+
On `ok: true`, tell the user, briefly:
|
|
57
|
+
|
|
58
|
+
- What it is called and which team can see it.
|
|
59
|
+
- That it is frozen at `frozen_at`, so nothing said after this point is in it.
|
|
60
|
+
- **That a vault is readable by the popover service.** Say this plainly, once, in your own
|
|
61
|
+
words. `/popover:fork` is end-to-end encrypted and a vault is not — anyone who has
|
|
62
|
+
internalised the first will assume the second, so it has to be said rather than implied.
|
|
63
|
+
The transcript is encrypted at rest under a key held outside the database, which is
|
|
64
|
+
defence in depth and is not the same promise.
|
|
65
|
+
|
|
66
|
+
## `find` (or `list`) — search the archive, free
|
|
67
|
+
|
|
68
|
+
Call `mcp__plugin_popover_popover__vault_search` with the user's question as `query`. Costs
|
|
69
|
+
nothing, runs no model, resumes nothing.
|
|
70
|
+
|
|
71
|
+
Show what came back as a short list: title, who froze it and when, the questions it says it
|
|
72
|
+
can answer, and the staleness note where there is one — a vault whose files nobody has
|
|
73
|
+
touched since it was frozen is current however old it is, and one whose files have churned is
|
|
74
|
+
suspect even if it is recent.
|
|
75
|
+
|
|
76
|
+
Then stop, unless the user asked you to ask one. Searching is free; asking is not.
|
|
77
|
+
|
|
78
|
+
## `ask` — put one question to one vault
|
|
79
|
+
|
|
80
|
+
Always `find` first, in the same turn if you have to, and ask the single vault that best
|
|
81
|
+
fits. Then call `mcp__plugin_popover_popover__vault_ask` with its `id` and a **self-contained**
|
|
82
|
+
question — expand every pronoun, name files by path, and ask about what was decided and why
|
|
83
|
+
rather than about what the code looks like now.
|
|
84
|
+
|
|
85
|
+
Show the answer attributed and dated, exactly as it comes back:
|
|
86
|
+
|
|
87
|
+
> The **repo-key-gating** vault, frozen 15 Aug 2026, says: …
|
|
88
|
+
|
|
89
|
+
Never merge it into your own reasoning as bare fact. A vault can hold a hypothesis the team
|
|
90
|
+
later disproved, and the attribution is what lets a reader discount it.
|
|
91
|
+
|
|
92
|
+
Then say what it means for the work in front of you, and flag anything it asserts about the
|
|
93
|
+
current tree as unverified — it had no way to look.
|
|
94
|
+
|
|
95
|
+
## `note` — correct a vault without rewriting it
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
popover vault note <vault-name> "<the correction, in one or two sentences>" --json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
On `ok: false`, relay `message` and `hints` verbatim.
|
|
102
|
+
|
|
103
|
+
A note sits beside the original description rather than replacing it, and that is the point:
|
|
104
|
+
a vault that confidently explains a decision the team later reversed is evidence about what
|
|
105
|
+
the team believed at the time. Editing it away destroys that; a note records both. Notes are
|
|
106
|
+
searched alongside the questions, so a correction is often what decides whether a vault is
|
|
107
|
+
worth asking at all.
|
|
108
|
+
|
|
109
|
+
## Archiving
|
|
110
|
+
|
|
111
|
+
`popover vault archive <name>` retires a vault, in a terminal. It is missing from this
|
|
112
|
+
command on purpose: retiring a vault takes something the whole team can see out of their
|
|
113
|
+
search results, and nothing is ever deleted — the record that the vault was made survives.
|
|
114
|
+
If the user wants one archived, give them the command and let them be the one who types it.
|
|
115
|
+
|
|
116
|
+
## No arguments, or anything else
|
|
117
|
+
|
|
118
|
+
Say what the four halves do in a line each and stop:
|
|
119
|
+
|
|
120
|
+
`/popover:vault create` · `/popover:vault find <question>` · `/popover:vault ask <question>` ·
|
|
121
|
+
`/popover:vault note <name> <correction>`
|
|
122
|
+
|
|
123
|
+
(`popover vault list`, `ask`, `note` and `archive` are the same verbs in a terminal, if the
|
|
124
|
+
user would rather type them there.)
|
|
125
|
+
|
|
126
|
+
## Vaulting without being asked
|
|
127
|
+
|
|
128
|
+
**You decide.** This is the one place in popover where you may act on your own judgement: you
|
|
129
|
+
may create a vault because you concluded the conversation was worth keeping, and you do not
|
|
130
|
+
need permission first. Say what you are doing and why, in a line — the user should never be
|
|
131
|
+
surprised — but do not ask for a yes before you start.
|
|
132
|
+
|
|
133
|
+
That is a deliberate departure from `/popover:fork`, where you may raise the idea and only
|
|
134
|
+
the user may act on it, and it is taken with that rule in full view. A fork discloses one
|
|
135
|
+
conversation to one named individual. A vault publishes to a team that already shares the
|
|
136
|
+
repository and the work, so the disclosure is small — and the cost of missing the moment is
|
|
137
|
+
high, because the moment for a vault is one you are usually far too deep in the work to
|
|
138
|
+
notice. Nobody is going to interrupt an afternoon of debugging to say "this should be
|
|
139
|
+
archived". If it waits for a prompt, it does not happen.
|
|
140
|
+
|
|
141
|
+
Vault when the conversation worked something out that the diff will not record:
|
|
142
|
+
|
|
143
|
+
- a decision with a reason — the alternative that was rejected, the constraint that forced an
|
|
144
|
+
awkward shape, the thing that looked obvious and was wrong;
|
|
145
|
+
- an investigation that ended in an answer, especially one that took hours;
|
|
146
|
+
- a design settled in discussion before any code existed;
|
|
147
|
+
- anything where you can already hear a teammate asking "why is this like this?" and the repo
|
|
148
|
+
having no answer.
|
|
149
|
+
|
|
150
|
+
Do **not** vault a conversation that only did what its diff says, a session with nothing
|
|
151
|
+
concluded in it, or one carrying secrets or a customer's data — a vault is readable by the
|
|
152
|
+
service and outlives everyone in the room.
|
|
153
|
+
|
|
154
|
+
Two failure modes make this rule wrong, and you should be watching for both in yourself:
|
|
155
|
+
vaulting everything, which produces an index nobody trusts, and vaulting nothing, which is
|
|
156
|
+
the ask-first rule's own failure wearing a different hat.
|
|
157
|
+
|
|
158
|
+
## Rules
|
|
159
|
+
|
|
160
|
+
- **Never invent a vault id.** Use only ones `vault_search` returned. If the tool says a vault
|
|
161
|
+
does not exist, relay that and search again rather than trying a neighbouring id.
|
|
162
|
+
- **One vault per question.** Never fan out across several to see which answers best. Each ask
|
|
163
|
+
costs a full context load — roughly $0.50 and up to 90 seconds — and it is billed to the
|
|
164
|
+
user in front of you, not to the vault's author.
|
|
165
|
+
- **Search before you ask, every time.** The two are separate tools so that looking can be
|
|
166
|
+
free. Treating `vault_ask` as the way to find things spends real money invisibly.
|
|
167
|
+
- A vault is never edited. The description it was created with is what it claims forever; a
|
|
168
|
+
correction is a `note`. If the user wants to change what a vault says, that is a note, or a
|
|
169
|
+
new vault, and it is worth saying which.
|
|
170
|
+
- A vault cannot ask another vault, and cannot read a file, run a command, or change
|
|
171
|
+
anything. If the user wants a colleague to *do* something, popover does not do that.
|
|
172
|
+
- If a tool errors or times out, relay it plainly. Do not silently re-ask, and do not try a
|
|
173
|
+
different vault unless the user asks.
|
package/plugin/hooks/hooks.json
CHANGED
|
@@ -1,111 +1,111 @@
|
|
|
1
|
-
{
|
|
2
|
-
"description": "Publishes this machine's Claude Code session activity to the popover daemon.",
|
|
3
|
-
"hooks": {
|
|
4
|
-
"SessionStart": [
|
|
5
|
-
{
|
|
6
|
-
"hooks": [
|
|
7
|
-
{
|
|
8
|
-
"type": "command",
|
|
9
|
-
"command": "node",
|
|
10
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/ensure-daemon.mjs"],
|
|
11
|
-
"async": true,
|
|
12
|
-
"timeout": 30
|
|
13
|
-
}
|
|
14
|
-
]
|
|
15
|
-
}
|
|
16
|
-
],
|
|
17
|
-
"UserPromptSubmit": [
|
|
18
|
-
{
|
|
19
|
-
"hooks": [
|
|
20
|
-
{
|
|
21
|
-
"type": "command",
|
|
22
|
-
"command": "node",
|
|
23
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
24
|
-
"async": true,
|
|
25
|
-
"timeout": 15
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
"type": "command",
|
|
29
|
-
"command": "node",
|
|
30
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/deliver-messages.mjs"],
|
|
31
|
-
"timeout": 5
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"type": "command",
|
|
35
|
-
"command": "node",
|
|
36
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/announce-roster.mjs"],
|
|
37
|
-
"timeout": 5
|
|
38
|
-
}
|
|
39
|
-
]
|
|
40
|
-
}
|
|
41
|
-
],
|
|
42
|
-
"PreToolUse": [
|
|
43
|
-
{
|
|
44
|
-
"matcher": "*",
|
|
45
|
-
"hooks": [
|
|
46
|
-
{
|
|
47
|
-
"type": "command",
|
|
48
|
-
"command": "node",
|
|
49
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
50
|
-
"async": true,
|
|
51
|
-
"timeout": 15
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
}
|
|
55
|
-
],
|
|
56
|
-
"PostToolUse": [
|
|
57
|
-
{
|
|
58
|
-
"matcher": "*",
|
|
59
|
-
"hooks": [
|
|
60
|
-
{
|
|
61
|
-
"type": "command",
|
|
62
|
-
"command": "node",
|
|
63
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
64
|
-
"async": true,
|
|
65
|
-
"timeout": 15
|
|
66
|
-
}
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
],
|
|
70
|
-
"Notification": [
|
|
71
|
-
{
|
|
72
|
-
"matcher": "agent_needs_input",
|
|
73
|
-
"hooks": [
|
|
74
|
-
{
|
|
75
|
-
"type": "command",
|
|
76
|
-
"command": "node",
|
|
77
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
78
|
-
"async": true,
|
|
79
|
-
"timeout": 15
|
|
80
|
-
}
|
|
81
|
-
]
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
"Stop": [
|
|
85
|
-
{
|
|
86
|
-
"hooks": [
|
|
87
|
-
{
|
|
88
|
-
"type": "command",
|
|
89
|
-
"command": "node",
|
|
90
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
91
|
-
"async": true,
|
|
92
|
-
"timeout": 15
|
|
93
|
-
}
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
],
|
|
97
|
-
"SessionEnd": [
|
|
98
|
-
{
|
|
99
|
-
"hooks": [
|
|
100
|
-
{
|
|
101
|
-
"type": "command",
|
|
102
|
-
"command": "node",
|
|
103
|
-
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
104
|
-
"async": true,
|
|
105
|
-
"timeout": 5
|
|
106
|
-
}
|
|
107
|
-
]
|
|
108
|
-
}
|
|
109
|
-
]
|
|
110
|
-
}
|
|
111
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"description": "Publishes this machine's Claude Code session activity to the popover daemon.",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"SessionStart": [
|
|
5
|
+
{
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "node",
|
|
10
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/ensure-daemon.mjs"],
|
|
11
|
+
"async": true,
|
|
12
|
+
"timeout": 30
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
"UserPromptSubmit": [
|
|
18
|
+
{
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "node",
|
|
23
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
24
|
+
"async": true,
|
|
25
|
+
"timeout": 15
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"type": "command",
|
|
29
|
+
"command": "node",
|
|
30
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/deliver-messages.mjs"],
|
|
31
|
+
"timeout": 5
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"type": "command",
|
|
35
|
+
"command": "node",
|
|
36
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/announce-roster.mjs"],
|
|
37
|
+
"timeout": 5
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"PreToolUse": [
|
|
43
|
+
{
|
|
44
|
+
"matcher": "*",
|
|
45
|
+
"hooks": [
|
|
46
|
+
{
|
|
47
|
+
"type": "command",
|
|
48
|
+
"command": "node",
|
|
49
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
50
|
+
"async": true,
|
|
51
|
+
"timeout": 15
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"PostToolUse": [
|
|
57
|
+
{
|
|
58
|
+
"matcher": "*",
|
|
59
|
+
"hooks": [
|
|
60
|
+
{
|
|
61
|
+
"type": "command",
|
|
62
|
+
"command": "node",
|
|
63
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
64
|
+
"async": true,
|
|
65
|
+
"timeout": 15
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"Notification": [
|
|
71
|
+
{
|
|
72
|
+
"matcher": "agent_needs_input",
|
|
73
|
+
"hooks": [
|
|
74
|
+
{
|
|
75
|
+
"type": "command",
|
|
76
|
+
"command": "node",
|
|
77
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
78
|
+
"async": true,
|
|
79
|
+
"timeout": 15
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
"Stop": [
|
|
85
|
+
{
|
|
86
|
+
"hooks": [
|
|
87
|
+
{
|
|
88
|
+
"type": "command",
|
|
89
|
+
"command": "node",
|
|
90
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
91
|
+
"async": true,
|
|
92
|
+
"timeout": 15
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"SessionEnd": [
|
|
98
|
+
{
|
|
99
|
+
"hooks": [
|
|
100
|
+
{
|
|
101
|
+
"type": "command",
|
|
102
|
+
"command": "node",
|
|
103
|
+
"args": ["${CLAUDE_PLUGIN_ROOT}/scripts/emit-event.mjs"],
|
|
104
|
+
"async": true,
|
|
105
|
+
"timeout": 5
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
}
|