@productbrain/cli 0.1.0-beta.1 → 0.1.0-beta.15

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 (278) hide show
  1. package/README.md +167 -0
  2. package/dist/__tests__/audit.test.d.ts +2 -0
  3. package/dist/__tests__/audit.test.d.ts.map +1 -0
  4. package/dist/__tests__/audit.test.js +394 -0
  5. package/dist/__tests__/audit.test.js.map +1 -0
  6. package/dist/__tests__/capture.test.d.ts +2 -0
  7. package/dist/__tests__/capture.test.d.ts.map +1 -0
  8. package/dist/__tests__/capture.test.js +86 -0
  9. package/dist/__tests__/capture.test.js.map +1 -0
  10. package/dist/__tests__/constellation.test.d.ts +2 -0
  11. package/dist/__tests__/constellation.test.d.ts.map +1 -0
  12. package/dist/__tests__/constellation.test.js +260 -0
  13. package/dist/__tests__/constellation.test.js.map +1 -0
  14. package/dist/__tests__/context-strategy.test.d.ts +2 -0
  15. package/dist/__tests__/context-strategy.test.d.ts.map +1 -0
  16. package/dist/__tests__/context-strategy.test.js +79 -0
  17. package/dist/__tests__/context-strategy.test.js.map +1 -0
  18. package/dist/__tests__/fields.test.d.ts +2 -0
  19. package/dist/__tests__/fields.test.d.ts.map +1 -0
  20. package/dist/__tests__/fields.test.js +238 -0
  21. package/dist/__tests__/fields.test.js.map +1 -0
  22. package/dist/__tests__/handshake.test.d.ts +2 -0
  23. package/dist/__tests__/handshake.test.d.ts.map +1 -0
  24. package/dist/__tests__/handshake.test.js +187 -0
  25. package/dist/__tests__/handshake.test.js.map +1 -0
  26. package/dist/__tests__/ingest.test.d.ts +2 -0
  27. package/dist/__tests__/ingest.test.d.ts.map +1 -0
  28. package/dist/__tests__/ingest.test.js +185 -0
  29. package/dist/__tests__/ingest.test.js.map +1 -0
  30. package/dist/__tests__/promote.test.d.ts +2 -0
  31. package/dist/__tests__/promote.test.d.ts.map +1 -0
  32. package/dist/__tests__/promote.test.js +139 -0
  33. package/dist/__tests__/promote.test.js.map +1 -0
  34. package/dist/__tests__/proposals.test.d.ts +2 -0
  35. package/dist/__tests__/proposals.test.d.ts.map +1 -0
  36. package/dist/__tests__/proposals.test.js +190 -0
  37. package/dist/__tests__/proposals.test.js.map +1 -0
  38. package/dist/__tests__/relate.test.d.ts +2 -0
  39. package/dist/__tests__/relate.test.d.ts.map +1 -0
  40. package/dist/__tests__/relate.test.js +105 -0
  41. package/dist/__tests__/relate.test.js.map +1 -0
  42. package/dist/__tests__/repo-detect.test.d.ts +2 -0
  43. package/dist/__tests__/repo-detect.test.d.ts.map +1 -0
  44. package/dist/__tests__/repo-detect.test.js +119 -0
  45. package/dist/__tests__/repo-detect.test.js.map +1 -0
  46. package/dist/__tests__/runner.test.d.ts +2 -0
  47. package/dist/__tests__/runner.test.d.ts.map +1 -0
  48. package/dist/__tests__/runner.test.js +215 -0
  49. package/dist/__tests__/runner.test.js.map +1 -0
  50. package/dist/__tests__/session-touch.test.d.ts +2 -0
  51. package/dist/__tests__/session-touch.test.d.ts.map +1 -0
  52. package/dist/__tests__/session-touch.test.js +134 -0
  53. package/dist/__tests__/session-touch.test.js.map +1 -0
  54. package/dist/__tests__/session.test.d.ts +2 -0
  55. package/dist/__tests__/session.test.d.ts.map +1 -0
  56. package/dist/__tests__/session.test.js +52 -0
  57. package/dist/__tests__/session.test.js.map +1 -0
  58. package/dist/__tests__/strip.test.d.ts +2 -0
  59. package/dist/__tests__/strip.test.d.ts.map +1 -0
  60. package/dist/__tests__/strip.test.js +136 -0
  61. package/dist/__tests__/strip.test.js.map +1 -0
  62. package/dist/__tests__/update.test.d.ts +2 -0
  63. package/dist/__tests__/update.test.d.ts.map +1 -0
  64. package/dist/__tests__/update.test.js +237 -0
  65. package/dist/__tests__/update.test.js.map +1 -0
  66. package/dist/commands/accept.d.ts +18 -0
  67. package/dist/commands/accept.d.ts.map +1 -0
  68. package/dist/commands/accept.js +72 -0
  69. package/dist/commands/accept.js.map +1 -0
  70. package/dist/commands/audit.d.ts +25 -0
  71. package/dist/commands/audit.d.ts.map +1 -0
  72. package/dist/commands/audit.js +188 -0
  73. package/dist/commands/audit.js.map +1 -0
  74. package/dist/commands/brand-pack.d.ts +2 -0
  75. package/dist/commands/brand-pack.d.ts.map +1 -0
  76. package/dist/commands/brand-pack.js +25 -0
  77. package/dist/commands/brand-pack.js.map +1 -0
  78. package/dist/commands/brief.d.ts +28 -0
  79. package/dist/commands/brief.d.ts.map +1 -0
  80. package/dist/commands/brief.js +70 -0
  81. package/dist/commands/brief.js.map +1 -0
  82. package/dist/commands/capture.d.ts +25 -0
  83. package/dist/commands/capture.d.ts.map +1 -0
  84. package/dist/commands/capture.js +103 -0
  85. package/dist/commands/capture.js.map +1 -0
  86. package/dist/commands/chain-walk.d.ts +14 -0
  87. package/dist/commands/chain-walk.d.ts.map +1 -0
  88. package/dist/commands/chain-walk.js +33 -0
  89. package/dist/commands/chain-walk.js.map +1 -0
  90. package/dist/commands/changes.d.ts +11 -0
  91. package/dist/commands/changes.d.ts.map +1 -0
  92. package/dist/commands/changes.js +41 -0
  93. package/dist/commands/changes.js.map +1 -0
  94. package/dist/commands/constellation.d.ts +11 -0
  95. package/dist/commands/constellation.d.ts.map +1 -0
  96. package/dist/commands/constellation.js +28 -0
  97. package/dist/commands/constellation.js.map +1 -0
  98. package/dist/commands/context.d.ts +2 -1
  99. package/dist/commands/context.d.ts.map +1 -1
  100. package/dist/commands/context.js +19 -9
  101. package/dist/commands/context.js.map +1 -1
  102. package/dist/commands/cross-cut.d.ts +11 -0
  103. package/dist/commands/cross-cut.d.ts.map +1 -0
  104. package/dist/commands/cross-cut.js +23 -0
  105. package/dist/commands/cross-cut.js.map +1 -0
  106. package/dist/commands/fields.d.ts +9 -0
  107. package/dist/commands/fields.d.ts.map +1 -0
  108. package/dist/commands/fields.js +26 -0
  109. package/dist/commands/fields.js.map +1 -0
  110. package/dist/commands/get.d.ts +8 -1
  111. package/dist/commands/get.d.ts.map +1 -1
  112. package/dist/commands/get.js +55 -6
  113. package/dist/commands/get.js.map +1 -1
  114. package/dist/commands/handshake.d.ts +18 -0
  115. package/dist/commands/handshake.d.ts.map +1 -0
  116. package/dist/commands/handshake.js +378 -0
  117. package/dist/commands/handshake.js.map +1 -0
  118. package/dist/commands/ingest.d.ts +14 -0
  119. package/dist/commands/ingest.d.ts.map +1 -0
  120. package/dist/commands/ingest.js +181 -0
  121. package/dist/commands/ingest.js.map +1 -0
  122. package/dist/commands/login.d.ts +5 -0
  123. package/dist/commands/login.d.ts.map +1 -0
  124. package/dist/commands/login.js +53 -0
  125. package/dist/commands/login.js.map +1 -0
  126. package/dist/commands/orient.d.ts +2 -0
  127. package/dist/commands/orient.d.ts.map +1 -1
  128. package/dist/commands/orient.js +17 -8
  129. package/dist/commands/orient.js.map +1 -1
  130. package/dist/commands/promote.d.ts +12 -0
  131. package/dist/commands/promote.d.ts.map +1 -0
  132. package/dist/commands/promote.js +48 -0
  133. package/dist/commands/promote.js.map +1 -0
  134. package/dist/commands/proposals.d.ts +9 -0
  135. package/dist/commands/proposals.d.ts.map +1 -0
  136. package/dist/commands/proposals.js +24 -0
  137. package/dist/commands/proposals.js.map +1 -0
  138. package/dist/commands/reject.d.ts +14 -0
  139. package/dist/commands/reject.d.ts.map +1 -0
  140. package/dist/commands/reject.js +37 -0
  141. package/dist/commands/reject.js.map +1 -0
  142. package/dist/commands/relate.d.ts +16 -0
  143. package/dist/commands/relate.d.ts.map +1 -0
  144. package/dist/commands/relate.js +80 -0
  145. package/dist/commands/relate.js.map +1 -0
  146. package/dist/commands/search.d.ts +1 -0
  147. package/dist/commands/search.d.ts.map +1 -1
  148. package/dist/commands/search.js +9 -3
  149. package/dist/commands/search.js.map +1 -1
  150. package/dist/commands/session.d.ts +20 -0
  151. package/dist/commands/session.d.ts.map +1 -0
  152. package/dist/commands/session.js +134 -0
  153. package/dist/commands/session.js.map +1 -0
  154. package/dist/commands/update.d.ts +16 -0
  155. package/dist/commands/update.d.ts.map +1 -0
  156. package/dist/commands/update.js +139 -0
  157. package/dist/commands/update.js.map +1 -0
  158. package/dist/commands/verify.d.ts +13 -0
  159. package/dist/commands/verify.d.ts.map +1 -0
  160. package/dist/commands/verify.js +43 -0
  161. package/dist/commands/verify.js.map +1 -0
  162. package/dist/formatters/audit.d.ts +46 -0
  163. package/dist/formatters/audit.d.ts.map +1 -0
  164. package/dist/formatters/audit.js +81 -0
  165. package/dist/formatters/audit.js.map +1 -0
  166. package/dist/formatters/brief.d.ts +112 -0
  167. package/dist/formatters/brief.d.ts.map +1 -0
  168. package/dist/formatters/brief.js +179 -0
  169. package/dist/formatters/brief.js.map +1 -0
  170. package/dist/formatters/capture.d.ts +30 -0
  171. package/dist/formatters/capture.d.ts.map +1 -0
  172. package/dist/formatters/capture.js +58 -0
  173. package/dist/formatters/capture.js.map +1 -0
  174. package/dist/formatters/chain-walk.d.ts +33 -0
  175. package/dist/formatters/chain-walk.d.ts.map +1 -0
  176. package/dist/formatters/chain-walk.js +54 -0
  177. package/dist/formatters/chain-walk.js.map +1 -0
  178. package/dist/formatters/changes.d.ts +25 -0
  179. package/dist/formatters/changes.d.ts.map +1 -0
  180. package/dist/formatters/changes.js +60 -0
  181. package/dist/formatters/changes.js.map +1 -0
  182. package/dist/formatters/constellation.d.ts +34 -0
  183. package/dist/formatters/constellation.d.ts.map +1 -0
  184. package/dist/formatters/constellation.js +38 -0
  185. package/dist/formatters/constellation.js.map +1 -0
  186. package/dist/formatters/cross-cut.d.ts +21 -0
  187. package/dist/formatters/cross-cut.d.ts.map +1 -0
  188. package/dist/formatters/cross-cut.js +32 -0
  189. package/dist/formatters/cross-cut.js.map +1 -0
  190. package/dist/formatters/entry.d.ts +11 -0
  191. package/dist/formatters/entry.d.ts.map +1 -1
  192. package/dist/formatters/entry.js +14 -1
  193. package/dist/formatters/entry.js.map +1 -1
  194. package/dist/formatters/fields.d.ts +32 -0
  195. package/dist/formatters/fields.d.ts.map +1 -0
  196. package/dist/formatters/fields.js +49 -0
  197. package/dist/formatters/fields.js.map +1 -0
  198. package/dist/formatters/handshake.d.ts +17 -0
  199. package/dist/formatters/handshake.d.ts.map +1 -0
  200. package/dist/formatters/handshake.js +51 -0
  201. package/dist/formatters/handshake.js.map +1 -0
  202. package/dist/formatters/orient.d.ts +1 -0
  203. package/dist/formatters/orient.d.ts.map +1 -1
  204. package/dist/formatters/orient.js +4 -2
  205. package/dist/formatters/orient.js.map +1 -1
  206. package/dist/formatters/promote.d.ts +29 -0
  207. package/dist/formatters/promote.d.ts.map +1 -0
  208. package/dist/formatters/promote.js +38 -0
  209. package/dist/formatters/promote.js.map +1 -0
  210. package/dist/formatters/proposals.d.ts +45 -0
  211. package/dist/formatters/proposals.d.ts.map +1 -0
  212. package/dist/formatters/proposals.js +62 -0
  213. package/dist/formatters/proposals.js.map +1 -0
  214. package/dist/formatters/relate.d.ts +12 -0
  215. package/dist/formatters/relate.d.ts.map +1 -0
  216. package/dist/formatters/relate.js +13 -0
  217. package/dist/formatters/relate.js.map +1 -0
  218. package/dist/formatters/session.d.ts +11 -0
  219. package/dist/formatters/session.d.ts.map +1 -0
  220. package/dist/formatters/session.js +51 -0
  221. package/dist/formatters/session.js.map +1 -0
  222. package/dist/formatters/update.d.ts +17 -0
  223. package/dist/formatters/update.d.ts.map +1 -0
  224. package/dist/formatters/update.js +43 -0
  225. package/dist/formatters/update.js.map +1 -0
  226. package/dist/formatters/verify.d.ts +11 -0
  227. package/dist/formatters/verify.d.ts.map +1 -0
  228. package/dist/formatters/verify.js +11 -0
  229. package/dist/formatters/verify.js.map +1 -0
  230. package/dist/generators/adapters.d.ts +10 -0
  231. package/dist/generators/adapters.d.ts.map +1 -0
  232. package/dist/generators/adapters.js +102 -0
  233. package/dist/generators/adapters.js.map +1 -0
  234. package/dist/generators/briefing-md.d.ts +8 -0
  235. package/dist/generators/briefing-md.d.ts.map +1 -0
  236. package/dist/generators/briefing-md.js +51 -0
  237. package/dist/generators/briefing-md.js.map +1 -0
  238. package/dist/generators/context-md.d.ts +8 -0
  239. package/dist/generators/context-md.d.ts.map +1 -0
  240. package/dist/generators/context-md.js +123 -0
  241. package/dist/generators/context-md.js.map +1 -0
  242. package/dist/generators/portable-knowledge.d.ts +72 -0
  243. package/dist/generators/portable-knowledge.d.ts.map +1 -0
  244. package/dist/generators/portable-knowledge.js +246 -0
  245. package/dist/generators/portable-knowledge.js.map +1 -0
  246. package/dist/generators/portable-knowledge.test.d.ts +2 -0
  247. package/dist/generators/portable-knowledge.test.d.ts.map +1 -0
  248. package/dist/generators/portable-knowledge.test.js +399 -0
  249. package/dist/generators/portable-knowledge.test.js.map +1 -0
  250. package/dist/index.d.ts +3 -2
  251. package/dist/index.d.ts.map +1 -1
  252. package/dist/index.js +466 -6
  253. package/dist/index.js.map +1 -1
  254. package/dist/lib/client.d.ts +34 -0
  255. package/dist/lib/client.d.ts.map +1 -1
  256. package/dist/lib/client.js +114 -9
  257. package/dist/lib/client.js.map +1 -1
  258. package/dist/lib/config.d.ts +19 -2
  259. package/dist/lib/config.d.ts.map +1 -1
  260. package/dist/lib/config.js +95 -14
  261. package/dist/lib/config.js.map +1 -1
  262. package/dist/lib/repo-detect.d.ts +14 -0
  263. package/dist/lib/repo-detect.d.ts.map +1 -0
  264. package/dist/lib/repo-detect.js +58 -0
  265. package/dist/lib/repo-detect.js.map +1 -0
  266. package/dist/lib/runner.d.ts +31 -0
  267. package/dist/lib/runner.d.ts.map +1 -0
  268. package/dist/lib/runner.js +65 -0
  269. package/dist/lib/runner.js.map +1 -0
  270. package/dist/lib/session.d.ts +17 -0
  271. package/dist/lib/session.d.ts.map +1 -0
  272. package/dist/lib/session.js +43 -0
  273. package/dist/lib/session.js.map +1 -0
  274. package/dist/lib/strip.d.ts +11 -0
  275. package/dist/lib/strip.d.ts.map +1 -0
  276. package/dist/lib/strip.js +26 -0
  277. package/dist/lib/strip.js.map +1 -0
  278. package/package.json +8 -4
package/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # Product Brain CLI (`pb`)
2
+
3
+ CLI for Chain knowledge: read, search, gather context, and **write back**. Uses your Product Brain API key (same as MCP). Write commands require a readwrite key.
4
+
5
+ **Requirements:** Node 18+, API key from Product Brain → Settings → API Keys (`pb_sk_*`).
6
+
7
+ ---
8
+
9
+ ## Install
10
+
11
+ ### From npm (beta)
12
+
13
+ ```bash
14
+ npm install -g @productbrain/cli@beta
15
+ ```
16
+
17
+ Updates require a new publish to npm (and, if you use 2FA, a one-time password). Use this when you want a stable beta from the registry.
18
+
19
+ ### From main (no publish needed)
20
+
21
+ If you have the repo and want **latest from `main`** without publishing to npm:
22
+
23
+ ```bash
24
+ git clone https://github.com/synergyai-os/Product-OS.git
25
+ cd Product-OS
26
+ npm ci
27
+ cd packages/cli && npm run build && npm install -g .
28
+ ```
29
+
30
+ After that, `pb` runs from your global path. Pull and re-run the last two commands to update:
31
+
32
+ ```bash
33
+ cd Product-OS && git pull && cd packages/cli && npm run build && npm install -g .
34
+ ```
35
+
36
+ See [Deployment strategy — CLI vs MCP](../../docs/deployment-strategy.md#cli-vs-mcp-distribution) for why this avoids `cli:publish` / OTP.
37
+
38
+ ---
39
+
40
+ ## First run
41
+
42
+ - **No key yet:** Run any command (e.g. `pb orient -b`). You’ll get a short guided flow: “Do you have an API key? (y/n)” → paste key → saved to `~/.config/productbrain/.env`. Your command then runs.
43
+ - **Or:** Run `pb login` to paste and save your key once. Get a key: Product Brain app → Settings → API Keys.
44
+
45
+ Config is read from (in order): env vars → `~/.config/productbrain/.env` → `.env.mcp` in the current directory.
46
+
47
+ ---
48
+
49
+ ## Commands
50
+
51
+ ### Read (no session required)
52
+
53
+ | Command | Description |
54
+ |--------|-------------|
55
+ | `pb orient` | Workspace stage, bets, governance, tensions. Use `-b` for a brief view. |
56
+ | `pb search <query>` | Full-text search across the Chain. |
57
+ | `pb get <entry-id>` | Full entry (data, relations, last 10 history events). |
58
+ | `pb context <entry-id>` | Constellation context (pipe-friendly markdown when not a TTY). |
59
+ | `pb handshake` | Generate context files for AI developer tools. See below. |
60
+ | `pb login` | Save your API key to `~/.config/productbrain/.env`. |
61
+
62
+ **Internal (Product-OS repo only):** `pb brand-pack` forwards to `scripts/brand-pack.mjs` — structured community marketing JSON via **OpenRouter** (`OPENROUTER_API_KEY`, not the Product Brain API key). Use `npm run brand-pack -- --help` from repo root for script options. Not published behavior for global npm installs unless built from this monorepo.
63
+
64
+ ### Write (session required — DEC-9)
65
+
66
+ | Command | Description |
67
+ |--------|-------------|
68
+ | `pb session start` | Open a tracked write session. Refreshes context files. |
69
+ | `pb capture "<text>"` | Capture a decision, tension, insight, or any knowledge to the Chain. Auto-classifies. |
70
+ | `pb session close` | Close the session. Shows captured entries, runs wrapup, refreshes context. |
71
+
72
+ `pb --help` for options.
73
+
74
+ ### Delivery + Chain (when you ship code in Product-OS)
75
+
76
+ Progressive delivery and deploy ordering are documented in the monorepo — not inside the `pb` binary:
77
+
78
+ | SSOT | Purpose |
79
+ |------|---------|
80
+ | [`docs/system/design/progressive-delivery-thesis.md`](../../docs/system/design/progressive-delivery-thesis.md) | Ladder (dark launch → GA), rollback (**STA-10**), flags, edge/Cloudflare notes |
81
+ | **MAP-13** on the Chain | Map entry pointing at the thesis — `pb get MAP-13` / `pb context MAP-13` |
82
+ | [`docs/deployment-strategy.md`](../../docs/deployment-strategy.md) | CI target, Convex vs Railway, CLI vs MCP distribution |
83
+
84
+ **BR-157:** If your push includes changes under `convex/`, run **`npx convex deploy`** (correct deployment) **before** `git push origin main` so Railway never serves a frontend that calls missing Convex functions.
85
+
86
+ **Typical ship loop with `pb`:**
87
+
88
+ ```bash
89
+ pb session start
90
+ # … commit, merge, push per .productbrain/skills/commit-to-main …
91
+ pb capture "DEC: Shipped <short>. Rollback: <flag OFF | Railway revert | …>. Convex deploy before push: <yes | N/A>."
92
+ pb session close
93
+ # If you changed .productbrain rules or skills:
94
+ cd ../.. && pb handshake # from repo root
95
+ ```
96
+
97
+ ---
98
+
99
+ ## `pb handshake` — AI Developer Onboarding
100
+
101
+ One command generates context files for every major AI coding tool:
102
+
103
+ ```bash
104
+ pb handshake
105
+ ```
106
+
107
+ **What it generates:**
108
+
109
+ | File | Purpose |
110
+ |------|---------|
111
+ | `.productbrain/context.md` | Workspace briefing — stage, bets, governance, architecture, tensions |
112
+ | `.productbrain/briefing.md` | Chain entries matched to this specific repo |
113
+ | `CLAUDE.md` | Adapter for Claude Code |
114
+ | `.cursor/rules/chain.mdc` | Adapter for Cursor |
115
+ | `.github/copilot-instructions.md` | Adapter for GitHub Copilot |
116
+
117
+ **Options:**
118
+
119
+ - `--force` — Overwrite adapter files even if they have custom content
120
+ - `--dry-run` — Preview what would be generated without writing files
121
+
122
+ **Safety:** Adapter files are marked with `auto-generated by pb handshake`. If you customize one and remove the marker, future runs skip it (unless `--force`). The `.productbrain/` directory contains workspace-specific context and should be in `.gitignore`.
123
+
124
+ **Governance:** Context export surface per DEC-161 and GLO-63. Architecture: ARCH-63 (surfaces are peers consuming the kernel).
125
+
126
+ ---
127
+
128
+ ## `pb session` + `pb capture` — Close the Loop
129
+
130
+ The Chain compounds from every AI coding session. Instead of knowledge dying in chat transcripts (TEN-27), capture it as you work.
131
+
132
+ ### Flow
133
+
134
+ ```bash
135
+ # Start of session
136
+ pb session start # opens session, refreshes context
137
+
138
+ # During work — capture what you learn
139
+ pb capture "TEN: topology query returns stale containers when initiatives are archived"
140
+ pb capture "DEC: excluded archived initiatives at the query level, not the UI filter"
141
+ pb capture "INS: learned that the containerIds array references soft-deleted entries"
142
+
143
+ # End of session
144
+ pb session close # shows summary, runs wrapup, refreshes context
145
+ ```
146
+
147
+ ### How capture works
148
+
149
+ 1. Text is sent to the Chain's classification pipeline — auto-assigns collection
150
+ 2. Entry is created as a **draft** (nothing auto-commits)
151
+ 3. Receipt shows: entry ID, collection, confidence, reasoning, alternatives
152
+ 4. You review and commit drafts in Product Brain Studio
153
+
154
+ ### Options
155
+
156
+ - `pb capture --collection tensions "text"` — skip auto-classification, use explicit collection
157
+ - `pb capture --name "Short title" --description "Full explanation"` — separate name and description
158
+ - `pb session close --force` — clear local session state even if server close fails
159
+
160
+ ### Governance
161
+
162
+ - Write access requires a tracked session (DEC-9, BR-8)
163
+ - Session attribution via API key; `clientKind: 'cli'` discriminator per DEC-184 (pending schema extension)
164
+ - All captures are drafts — human reviews and commits (TEN-374)
165
+ - Solves TEN-264 (CLI write access session attribution) with explicit session token in `.productbrain/session.json`
166
+ - Addresses TEN-27 (strategic conversations generate decisions that never reach the Chain)
167
+ - Implements INS-80 (proactive capture during coding)
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/audit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,394 @@
1
+ /**
2
+ * pb audit — unit tests.
3
+ * BET-182 Slice 2: CLI command + auto-fix.
4
+ *
5
+ * Verifies:
6
+ * 1. JSON mode: correct structure on pipe (mock mcpCall with fixture)
7
+ * 2. TTY mode: PASS gates collapsed, FAIL gates expanded
8
+ * 3. Exit codes: 0/1/2/3 for each verdict
9
+ * 4. --gate flag: only specified gate runs
10
+ * 5. --phase flag: passed through to MCP call
11
+ * 6. --fix: calls update with fix values, reruns audit, stops after 1 rerun
12
+ * 7. Batch mode: multiple entryIds processed sequentially
13
+ * 8. Edge case: entry not found returns error
14
+ */
15
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
16
+ import { runAudit } from '../commands/audit.js';
17
+ import { setOutputMode } from '../lib/runner.js';
18
+ const mcpCallMock = vi.fn();
19
+ const mcpCallWithSessionMock = vi.fn();
20
+ vi.mock('../lib/client.js', () => ({
21
+ mcpCall: (...args) => mcpCallMock(...args),
22
+ mcpCallWithSession: (...args) => mcpCallWithSessionMock(...args),
23
+ }));
24
+ vi.mock('../lib/config.js', () => ({
25
+ getConfigOrGuide: vi.fn((_fn) => Promise.resolve({ apiKey: 'pb_sk_test', siteUrl: 'https://test.convex.site' })),
26
+ }));
27
+ // Session mock — controlled per test
28
+ let mockSession = { sessionId: 'sess-test' };
29
+ vi.mock('../lib/session.js', () => ({
30
+ readSession: () => mockSession,
31
+ }));
32
+ // ─── Fixtures ───────────────────────────────────────────────────────────────
33
+ const PASS_FIXTURE = {
34
+ entryId: 'BET-182',
35
+ entryName: 'CLI Audit Gate',
36
+ phase: 'shaping',
37
+ verdict: 'pass',
38
+ gates: [
39
+ { gate: 'intentional-relations', status: 'pass', blocking: true, detail: '3 intentional relations found' },
40
+ { gate: 'strategic-anchor', status: 'pass', blocking: true, detail: 'Linked to WS-5' },
41
+ { gate: 'field-completeness', status: 'pass', blocking: true, detail: 'All 4 required fields populated' },
42
+ ],
43
+ summary: { total: 3, passed: 3, failed: 0, warned: 0 },
44
+ elapsed_ms: 42,
45
+ };
46
+ const FAIL_FIXTURE = {
47
+ entryId: 'BET-200',
48
+ entryName: 'Broken Bet',
49
+ phase: 'shaping',
50
+ verdict: 'fail',
51
+ gates: [
52
+ { gate: 'intentional-relations', status: 'fail', blocking: true, detail: '0 intentional relations', fix: "Set field 'problem' to 'needs definition'", fixType: 'exact' },
53
+ { gate: 'strategic-anchor', status: 'pass', blocking: true, detail: 'Linked to WS-5' },
54
+ { gate: 'field-completeness', status: 'fail', blocking: true, detail: 'Missing: appetite, doneWhen', fix: "Set field 'appetite' to '6 weeks'", fixType: 'exact', hint: 'STD-113 requires these fields' },
55
+ ],
56
+ summary: { total: 3, passed: 1, failed: 2, warned: 0 },
57
+ elapsed_ms: 55,
58
+ };
59
+ const WARN_FIXTURE = {
60
+ entryId: 'BET-201',
61
+ entryName: 'Warn Bet',
62
+ phase: 'handoff',
63
+ verdict: 'warn',
64
+ gates: [
65
+ { gate: 'auto-link-noise', status: 'warn', blocking: false, detail: '2 auto-link relations found', hint: 'Consider removing auto-link noise' },
66
+ { gate: 'strategic-anchor', status: 'pass', blocking: true, detail: 'Linked to WS-5' },
67
+ ],
68
+ summary: { total: 2, passed: 1, failed: 0, warned: 1 },
69
+ elapsed_ms: 33,
70
+ };
71
+ // ─── Helpers ────────────────────────────────────────────────────────────────
72
+ let stdoutOutput;
73
+ let stderrOutput;
74
+ let stdoutWriteSpy;
75
+ let stderrWriteSpy;
76
+ let exitSpy;
77
+ function withTty(isTty, fn) {
78
+ return async () => {
79
+ const original = process.stdout.isTTY;
80
+ Object.defineProperty(process.stdout, 'isTTY', { value: isTty, configurable: true, writable: true });
81
+ try {
82
+ await fn();
83
+ }
84
+ finally {
85
+ Object.defineProperty(process.stdout, 'isTTY', { value: original, configurable: true, writable: true });
86
+ }
87
+ };
88
+ }
89
+ /**
90
+ * Catch process.exit without actually exiting.
91
+ * Returns the exit code that was called with.
92
+ */
93
+ function catchExit() {
94
+ const state = { code: undefined };
95
+ exitSpy = vi.spyOn(process, 'exit').mockImplementation(((code) => {
96
+ state.code = code;
97
+ throw new Error(`process.exit(${code})`);
98
+ }));
99
+ return state;
100
+ }
101
+ beforeEach(() => {
102
+ stdoutOutput = '';
103
+ stderrOutput = '';
104
+ stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
105
+ stdoutOutput += String(chunk);
106
+ return true;
107
+ });
108
+ stderrWriteSpy = vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => {
109
+ stderrOutput += String(chunk);
110
+ return true;
111
+ });
112
+ setOutputMode('auto');
113
+ mockSession = { sessionId: 'sess-test' };
114
+ vi.clearAllMocks();
115
+ });
116
+ afterEach(() => {
117
+ stdoutWriteSpy.mockRestore();
118
+ stderrWriteSpy.mockRestore();
119
+ exitSpy?.mockRestore();
120
+ setOutputMode('auto');
121
+ });
122
+ // ─── Tests ──────────────────────────────────────────────────────────────────
123
+ describe('runAudit — JSON mode (non-TTY)', () => {
124
+ it('outputs correct JSON structure on pipe', withTty(false, async () => {
125
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
126
+ const exit = catchExit();
127
+ await expect(runAudit({ entryIds: ['BET-182'] })).rejects.toThrow('process.exit');
128
+ const parsed = JSON.parse(stdoutOutput);
129
+ expect(parsed.entryId).toBe('BET-182');
130
+ expect(parsed.entryName).toBe('CLI Audit Gate');
131
+ expect(parsed.verdict).toBe('pass');
132
+ expect(parsed.gates).toHaveLength(3);
133
+ expect(parsed.summary).toEqual({ total: 3, passed: 3, failed: 0, warned: 0 });
134
+ expect(parsed.elapsed_ms).toBe(42);
135
+ expect(exit.code).toBe(0);
136
+ }));
137
+ it('calls chain.auditBet with correct entryId', withTty(false, async () => {
138
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
139
+ catchExit();
140
+ await expect(runAudit({ entryIds: ['BET-182'] })).rejects.toThrow('process.exit');
141
+ expect(mcpCallMock).toHaveBeenCalledWith('chain.auditBet', { entryId: 'BET-182' });
142
+ }));
143
+ it('strips Convex internals from JSON output', withTty(false, async () => {
144
+ const fixtureWithInternals = {
145
+ ...PASS_FIXTURE,
146
+ _id: 'sys-internal-id',
147
+ _creationTime: 123456,
148
+ };
149
+ mcpCallMock.mockResolvedValue(fixtureWithInternals);
150
+ catchExit();
151
+ await expect(runAudit({ entryIds: ['BET-182'] })).rejects.toThrow('process.exit');
152
+ const parsed = JSON.parse(stdoutOutput);
153
+ expect(parsed).not.toHaveProperty('_id');
154
+ expect(parsed).not.toHaveProperty('_creationTime');
155
+ }));
156
+ });
157
+ describe('runAudit — TTY mode', () => {
158
+ it('collapses PASS gates (shows count), expands FAIL gates', withTty(true, async () => {
159
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
160
+ catchExit();
161
+ await expect(runAudit({ entryIds: ['BET-200'] })).rejects.toThrow('process.exit');
162
+ // FAIL gates should be expanded with detail
163
+ expect(stdoutOutput).toContain('intentional-relations');
164
+ expect(stdoutOutput).toContain('0 intentional relations');
165
+ expect(stdoutOutput).toContain('field-completeness');
166
+ expect(stdoutOutput).toContain('Missing: appetite, doneWhen');
167
+ // PASS gate should be in collapsed summary
168
+ expect(stdoutOutput).toContain('PASS: 1 gate(s)');
169
+ expect(stdoutOutput).toContain('strategic-anchor');
170
+ }));
171
+ it('shows WARN gates expanded with hints', withTty(true, async () => {
172
+ mcpCallMock.mockResolvedValue(WARN_FIXTURE);
173
+ catchExit();
174
+ await expect(runAudit({ entryIds: ['BET-201'] })).rejects.toThrow('process.exit');
175
+ expect(stdoutOutput).toContain('WARN:');
176
+ expect(stdoutOutput).toContain('auto-link-noise');
177
+ expect(stdoutOutput).toContain('2 auto-link relations found');
178
+ expect(stdoutOutput).toContain('Consider removing auto-link noise');
179
+ }));
180
+ it('--verbose expands all gates including PASS', withTty(true, async () => {
181
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
182
+ catchExit();
183
+ await expect(runAudit({ entryIds: ['BET-182'], verbose: true })).rejects.toThrow('process.exit');
184
+ // PASS gates should show detail, not just count
185
+ expect(stdoutOutput).toContain('PASS:');
186
+ expect(stdoutOutput).toContain('intentional-relations: 3 intentional relations found');
187
+ expect(stdoutOutput).toContain('strategic-anchor: Linked to WS-5');
188
+ // Should NOT have the collapsed format
189
+ expect(stdoutOutput).not.toContain('gate(s)');
190
+ }));
191
+ });
192
+ describe('runAudit — exit codes', () => {
193
+ it('exit 0 for pass verdict', withTty(false, async () => {
194
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
195
+ const exit = catchExit();
196
+ await expect(runAudit({ entryIds: ['BET-182'] })).rejects.toThrow('process.exit');
197
+ expect(exit.code).toBe(0);
198
+ }));
199
+ it('exit 1 for fail verdict', withTty(false, async () => {
200
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
201
+ const exit = catchExit();
202
+ await expect(runAudit({ entryIds: ['BET-200'] })).rejects.toThrow('process.exit');
203
+ expect(exit.code).toBe(1);
204
+ }));
205
+ it('exit 2 for warn verdict', withTty(false, async () => {
206
+ mcpCallMock.mockResolvedValue(WARN_FIXTURE);
207
+ const exit = catchExit();
208
+ await expect(runAudit({ entryIds: ['BET-201'] })).rejects.toThrow('process.exit');
209
+ expect(exit.code).toBe(2);
210
+ }));
211
+ it('exit 3 for error (entry not found)', withTty(false, async () => {
212
+ mcpCallMock.mockRejectedValue(new Error('Entry "BET-999" not found.'));
213
+ const exit = catchExit();
214
+ await expect(runAudit({ entryIds: ['BET-999'] })).rejects.toThrow('process.exit');
215
+ expect(exit.code).toBe(3);
216
+ }));
217
+ });
218
+ describe('runAudit — --gate flag', () => {
219
+ it('filters JSON output to only specified gate(s)', withTty(false, async () => {
220
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
221
+ catchExit();
222
+ await expect(runAudit({ entryIds: ['BET-200'], gate: ['field-completeness'] })).rejects.toThrow('process.exit');
223
+ const parsed = JSON.parse(stdoutOutput);
224
+ // Only the filtered gate should appear
225
+ expect(parsed.gates).toHaveLength(1);
226
+ expect(parsed.gates[0].gate).toBe('field-completeness');
227
+ }));
228
+ it('filters TTY output to only specified gate(s)', withTty(true, async () => {
229
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
230
+ catchExit();
231
+ await expect(runAudit({ entryIds: ['BET-200'], gate: ['field-completeness'] })).rejects.toThrow('process.exit');
232
+ // Should show the filtered gate
233
+ expect(stdoutOutput).toContain('field-completeness');
234
+ // Should NOT show other gates
235
+ expect(stdoutOutput).not.toContain('intentional-relations');
236
+ }));
237
+ it('supports multiple --gate values', withTty(false, async () => {
238
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
239
+ catchExit();
240
+ await expect(runAudit({ entryIds: ['BET-200'], gate: ['intentional-relations', 'field-completeness'] })).rejects.toThrow('process.exit');
241
+ const parsed = JSON.parse(stdoutOutput);
242
+ expect(parsed.gates).toHaveLength(2);
243
+ const gateNames = parsed.gates.map((g) => g.gate);
244
+ expect(gateNames).toContain('intentional-relations');
245
+ expect(gateNames).toContain('field-completeness');
246
+ }));
247
+ });
248
+ describe('runAudit — --phase flag', () => {
249
+ it('passes phase through to MCP call', withTty(false, async () => {
250
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
251
+ catchExit();
252
+ await expect(runAudit({ entryIds: ['BET-182'], phase: 'handoff' })).rejects.toThrow('process.exit');
253
+ expect(mcpCallMock).toHaveBeenCalledWith('chain.auditBet', { entryId: 'BET-182', phase: 'handoff' });
254
+ }));
255
+ it('omits phase from MCP call when not specified', withTty(false, async () => {
256
+ mcpCallMock.mockResolvedValue(PASS_FIXTURE);
257
+ catchExit();
258
+ await expect(runAudit({ entryIds: ['BET-182'] })).rejects.toThrow('process.exit');
259
+ expect(mcpCallMock).toHaveBeenCalledWith('chain.auditBet', { entryId: 'BET-182' });
260
+ }));
261
+ });
262
+ describe('runAudit — --fix', () => {
263
+ it('calls updateEntry for exact fixes and reruns audit once', withTty(false, async () => {
264
+ // First call: failing audit
265
+ // Second call (after fix): passing audit
266
+ mcpCallMock
267
+ .mockResolvedValueOnce(FAIL_FIXTURE)
268
+ .mockResolvedValueOnce({ ...PASS_FIXTURE, entryId: 'BET-200', entryName: 'Broken Bet' });
269
+ mcpCallWithSessionMock.mockResolvedValue({ id: 'result-id', warnings: [] });
270
+ const exit = catchExit();
271
+ await expect(runAudit({ entryIds: ['BET-200'], fix: true })).rejects.toThrow('process.exit');
272
+ // Should have called updateEntry for each exact fix
273
+ expect(mcpCallWithSessionMock).toHaveBeenCalledWith('chain.updateEntry', {
274
+ entryId: 'BET-200',
275
+ data: { problem: 'needs definition' },
276
+ changeNote: 'Auto-fix via pb audit: set problem',
277
+ });
278
+ expect(mcpCallWithSessionMock).toHaveBeenCalledWith('chain.updateEntry', {
279
+ entryId: 'BET-200',
280
+ data: { appetite: '6 weeks' },
281
+ changeNote: 'Auto-fix via pb audit: set appetite',
282
+ });
283
+ // Should have rerun the audit (2 mcpCall invocations total)
284
+ expect(mcpCallMock).toHaveBeenCalledTimes(2);
285
+ // Exit code should reflect the rerun result (pass = 0)
286
+ expect(exit.code).toBe(0);
287
+ }));
288
+ it('does not fix when no session is active', withTty(false, async () => {
289
+ mockSession = null;
290
+ mcpCallMock.mockResolvedValue(FAIL_FIXTURE);
291
+ catchExit();
292
+ await expect(runAudit({ entryIds: ['BET-200'], fix: true })).rejects.toThrow('process.exit');
293
+ // Should NOT have called updateEntry
294
+ expect(mcpCallWithSessionMock).not.toHaveBeenCalled();
295
+ // Should still show the result
296
+ const parsed = JSON.parse(stdoutOutput);
297
+ expect(parsed.verdict).toBe('fail');
298
+ }));
299
+ it('skips non-exact fixType gates', withTty(false, async () => {
300
+ const manualFixFixture = {
301
+ ...FAIL_FIXTURE,
302
+ gates: [
303
+ { gate: 'intentional-relations', status: 'fail', blocking: true, detail: '0 relations', fix: 'Add relations manually', fixType: 'manual' },
304
+ { gate: 'strategic-anchor', status: 'pass', blocking: true, detail: 'OK' },
305
+ ],
306
+ };
307
+ mcpCallMock.mockResolvedValue(manualFixFixture);
308
+ catchExit();
309
+ await expect(runAudit({ entryIds: ['BET-200'], fix: true })).rejects.toThrow('process.exit');
310
+ // No exact fixes → no updateEntry calls, no rerun
311
+ expect(mcpCallWithSessionMock).not.toHaveBeenCalled();
312
+ expect(mcpCallMock).toHaveBeenCalledTimes(1);
313
+ }));
314
+ it('stops after one rerun even if issues remain', withTty(false, async () => {
315
+ // Both calls return failing audit (fix didn't resolve everything)
316
+ mcpCallMock
317
+ .mockResolvedValueOnce(FAIL_FIXTURE)
318
+ .mockResolvedValueOnce(FAIL_FIXTURE);
319
+ mcpCallWithSessionMock.mockResolvedValue({ id: 'result-id', warnings: [] });
320
+ const exit = catchExit();
321
+ await expect(runAudit({ entryIds: ['BET-200'], fix: true })).rejects.toThrow('process.exit');
322
+ // Should have run audit exactly 2 times (initial + 1 rerun), not 3
323
+ expect(mcpCallMock).toHaveBeenCalledTimes(2);
324
+ expect(exit.code).toBe(1);
325
+ }));
326
+ });
327
+ describe('runAudit — batch mode', () => {
328
+ it('audits multiple bets sequentially', withTty(false, async () => {
329
+ mcpCallMock
330
+ .mockResolvedValueOnce(PASS_FIXTURE)
331
+ .mockResolvedValueOnce(FAIL_FIXTURE);
332
+ const exit = catchExit();
333
+ await expect(runAudit({ entryIds: ['BET-182', 'BET-200'] })).rejects.toThrow('process.exit');
334
+ // Both auditBet calls should have been made
335
+ expect(mcpCallMock).toHaveBeenCalledWith('chain.auditBet', { entryId: 'BET-182' });
336
+ expect(mcpCallMock).toHaveBeenCalledWith('chain.auditBet', { entryId: 'BET-200' });
337
+ // Exit code should be worst verdict (fail = 1)
338
+ expect(exit.code).toBe(1);
339
+ // Should have batch summary as last line of output
340
+ const lines = stdoutOutput.trim().split('\n');
341
+ const lastLine = lines[lines.length - 1];
342
+ const batchSummary = JSON.parse(lastLine);
343
+ expect(batchSummary.batch).toBe(true);
344
+ expect(batchSummary.count).toBe(2);
345
+ expect(batchSummary.passed).toBe(1);
346
+ expect(batchSummary.failed).toBe(1);
347
+ }));
348
+ it('shows separator between entries in TTY mode', withTty(true, async () => {
349
+ mcpCallMock
350
+ .mockResolvedValueOnce(PASS_FIXTURE)
351
+ .mockResolvedValueOnce(WARN_FIXTURE);
352
+ catchExit();
353
+ await expect(runAudit({ entryIds: ['BET-182', 'BET-201'] })).rejects.toThrow('process.exit');
354
+ // Should have separator
355
+ expect(stdoutOutput).toContain('---');
356
+ // Both entries present
357
+ expect(stdoutOutput).toContain('BET-182');
358
+ expect(stdoutOutput).toContain('BET-201');
359
+ }));
360
+ it('continues after error on one entry', withTty(false, async () => {
361
+ mcpCallMock
362
+ .mockRejectedValueOnce(new Error('Entry "BET-999" not found.'))
363
+ .mockResolvedValueOnce(PASS_FIXTURE);
364
+ const exit = catchExit();
365
+ await expect(runAudit({ entryIds: ['BET-999', 'BET-182'] })).rejects.toThrow('process.exit');
366
+ // Error is worst (3 > 0)
367
+ expect(exit.code).toBe(3);
368
+ // stderr should have the error
369
+ expect(stderrOutput).toContain('BET-999');
370
+ // stdout should have the successful result
371
+ expect(stdoutOutput).toContain('BET-182');
372
+ }));
373
+ });
374
+ describe('runAudit — error handling', () => {
375
+ it('outputs JSON error on pipe when entry not found', withTty(false, async () => {
376
+ mcpCallMock.mockRejectedValue(new Error('Entry "BET-999" not found.'));
377
+ const exit = catchExit();
378
+ await expect(runAudit({ entryIds: ['BET-999'] })).rejects.toThrow('process.exit');
379
+ expect(exit.code).toBe(3);
380
+ const errParsed = JSON.parse(stderrOutput);
381
+ expect(errParsed).toHaveProperty('error');
382
+ expect(errParsed.error).toContain('BET-999');
383
+ expect(errParsed.entryId).toBe('BET-999');
384
+ }));
385
+ it('outputs human error in TTY when entry not found', withTty(true, async () => {
386
+ mcpCallMock.mockRejectedValue(new Error('Entry "BET-999" not found.'));
387
+ const exit = catchExit();
388
+ await expect(runAudit({ entryIds: ['BET-999'] })).rejects.toThrow('process.exit');
389
+ expect(exit.code).toBe(3);
390
+ expect(stderrOutput).toContain('Error auditing BET-999');
391
+ expect(stderrOutput).toContain('not found');
392
+ }));
393
+ });
394
+ //# sourceMappingURL=audit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.test.js","sourceRoot":"","sources":["../../src/__tests__/audit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=capture.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/capture.test.ts"],"names":[],"mappings":""}