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

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 +21 -0
  83. package/dist/commands/capture.d.ts.map +1 -0
  84. package/dist/commands/capture.js +100 -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 +5 -0
  191. package/dist/formatters/entry.d.ts.map +1 -1
  192. package/dist/formatters/entry.js +5 -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 +462 -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
@@ -0,0 +1,378 @@
1
+ /**
2
+ * pb handshake — generate context files for AI developer tools.
3
+ * The fourth delivery surface: context export (GLO-63, DEC-161).
4
+ */
5
+ import { mkdirSync, writeFileSync, existsSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { homedir } from 'os';
8
+ import { createInterface } from 'readline';
9
+ import { getConfigOrGuide } from '../lib/config.js';
10
+ import { mcpCall } from '../lib/client.js';
11
+ import { detectRepo } from '../lib/repo-detect.js';
12
+ import { generateContextMd } from '../generators/context-md.js';
13
+ import { generateBriefingMd } from '../generators/briefing-md.js';
14
+ import { MARKER, generateClaudeMd, generateCursorMdc, generateCopilotMd } from '../generators/adapters.js';
15
+ import { readCanonicalSkills, readCanonicalRules, generateCursorSkill, generateCursorRule, generateClaudeRule, generateClaudeSkillRouter, shouldEmitToTarget, filterByLevel, } from '../generators/portable-knowledge.js';
16
+ import { formatHandshakeReport } from '../formatters/handshake.js';
17
+ const LEVELS = {
18
+ guide: {
19
+ label: 'Guide me',
20
+ description: "Explain what you're doing, ask before anything unfamiliar",
21
+ defaultMode: 'auto',
22
+ allow: ['Bash(pb:*)', 'Bash(git:*)'],
23
+ },
24
+ work: {
25
+ label: 'Just work',
26
+ description: 'Ask only when something could be risky or irreversible',
27
+ defaultMode: 'auto',
28
+ allow: ['Bash(pb:*)', 'Bash(git:*)', 'Bash(npm run:*)'],
29
+ },
30
+ silent: {
31
+ label: 'Silent',
32
+ description: "I'll review the diff; don't ask unless it's destructive",
33
+ defaultMode: 'acceptEdits',
34
+ allow: ['Bash(pb:*)', 'Bash(git:*)', 'Bash(npm run:*)', 'Bash(npx:*)'],
35
+ },
36
+ 'full-trust': {
37
+ label: 'Full trust',
38
+ description: 'Never ask (your machine, your call)',
39
+ defaultMode: 'bypassPermissions',
40
+ allow: [],
41
+ },
42
+ };
43
+ // Explicit ordering — determines menu numbering in promptLevel(). Do not reorder.
44
+ const LEVEL_KEYS = ['guide', 'work', 'silent', 'full-trust'];
45
+ // Hook failure contract (TEN-712): all hook commands MUST end with '2>/dev/null || true'
46
+ // so Claude Code always starts even if pb is unavailable. Never remove this suffix.
47
+ const INIT_PERMISSION = 'Bash(pb:*)';
48
+ const INIT_SESSION_START_CMD = 'pb session start 2>/dev/null || true';
49
+ const INIT_SESSION_CLOSE_CMD = 'pb session close 2>/dev/null || true';
50
+ const INIT_PRECOMPACT_CMD = 'pb session id > /dev/null 2>&1 && echo \'{"systemMessage": "pb session active — capture decisions/tensions before compacting: pb capture \\"DEC: ...\\""}\' || true';
51
+ function readSettings(filePath) {
52
+ if (!existsSync(filePath))
53
+ return {};
54
+ try {
55
+ return JSON.parse(readFileSync(filePath, 'utf8'));
56
+ }
57
+ catch {
58
+ console.error(`Warning: ${filePath} has invalid JSON — starting fresh.`);
59
+ return {};
60
+ }
61
+ }
62
+ function hasCommand(groups, cmd) {
63
+ return (groups ?? []).some((g) => g.hooks?.some((h) => h.command === cmd));
64
+ }
65
+ // Team write: hooks + Bash(pb:*) → .claude/settings.json (safe to commit)
66
+ function writeTeamSettings(cwd, dryRun) {
67
+ const claudeDir = join(cwd, '.claude');
68
+ const settingsPath = join(claudeDir, 'settings.json');
69
+ const settings = readSettings(settingsPath);
70
+ const added = [];
71
+ const permissions = (settings.permissions ?? {});
72
+ const allow = permissions.allow ?? [];
73
+ if (!allow.includes(INIT_PERMISSION)) {
74
+ allow.push(INIT_PERMISSION);
75
+ permissions.allow = allow;
76
+ added.push('Bash(pb:*) permission');
77
+ }
78
+ settings.permissions = permissions;
79
+ const hooks = (settings.hooks ?? {});
80
+ if (!hasCommand(hooks.SessionStart, INIT_SESSION_START_CMD)) {
81
+ hooks.SessionStart = [
82
+ ...(hooks.SessionStart ?? []),
83
+ { hooks: [{ type: 'command', command: INIT_SESSION_START_CMD, statusMessage: 'Opening pb session...' }] },
84
+ ];
85
+ added.push('SessionStart → pb session start');
86
+ }
87
+ if (!hasCommand(hooks.Stop, INIT_SESSION_CLOSE_CMD)) {
88
+ hooks.Stop = [
89
+ ...(hooks.Stop ?? []),
90
+ { hooks: [{ type: 'command', command: INIT_SESSION_CLOSE_CMD, statusMessage: 'Closing pb session...' }] },
91
+ ];
92
+ added.push('Stop → pb session close');
93
+ }
94
+ if (!hasCommand(hooks.PreCompact, INIT_PRECOMPACT_CMD)) {
95
+ hooks.PreCompact = [
96
+ ...(hooks.PreCompact ?? []),
97
+ { hooks: [{ type: 'command', command: INIT_PRECOMPACT_CMD }] },
98
+ ];
99
+ added.push('PreCompact → decision capture reminder');
100
+ }
101
+ settings.hooks = hooks;
102
+ if (!dryRun) {
103
+ mkdirSync(claudeDir, { recursive: true });
104
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
105
+ }
106
+ return added;
107
+ }
108
+ // Personal write: trust level → ~/.claude/settings.json (never committed)
109
+ function writePersonalSettings(levelKey, dryRun) {
110
+ const level = LEVELS[levelKey];
111
+ const globalDir = join(homedir(), '.claude');
112
+ const globalPath = join(globalDir, 'settings.json');
113
+ const settings = readSettings(globalPath);
114
+ const added = [];
115
+ const permissions = (settings.permissions ?? {});
116
+ if (permissions.defaultMode !== level.defaultMode) {
117
+ permissions.defaultMode = level.defaultMode;
118
+ added.push(`defaultMode → ${level.defaultMode}`);
119
+ }
120
+ const allow = permissions.allow ?? [];
121
+ for (const entry of level.allow) {
122
+ if (!allow.includes(entry)) {
123
+ allow.push(entry);
124
+ added.push(`allow: ${entry}`);
125
+ }
126
+ }
127
+ permissions.allow = allow;
128
+ settings.permissions = permissions;
129
+ if (!dryRun) {
130
+ mkdirSync(globalDir, { recursive: true });
131
+ writeFileSync(globalPath, JSON.stringify(settings, null, 2) + '\n');
132
+ }
133
+ return added;
134
+ }
135
+ async function promptLevel() {
136
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
137
+ console.log('\nHow much should Claude explain before acting?\n');
138
+ LEVEL_KEYS.forEach((key, i) => {
139
+ const l = LEVELS[key];
140
+ console.log(` ${i + 1}. ${l.label.padEnd(12)} — ${l.description}`);
141
+ });
142
+ console.log('');
143
+ return new Promise((resolve) => {
144
+ rl.question('> ', (answer) => {
145
+ rl.close();
146
+ const n = parseInt(answer.trim(), 10);
147
+ if (!(n >= 1 && n <= LEVEL_KEYS.length)) {
148
+ console.log(' (Invalid choice — defaulting to "Just work")');
149
+ }
150
+ resolve(n >= 1 && n <= LEVEL_KEYS.length ? LEVEL_KEYS[n - 1] : 'work');
151
+ });
152
+ });
153
+ }
154
+ export async function runHandshakeInit(options = {}) {
155
+ const cwd = process.cwd();
156
+ const dryRun = options.dryRun ?? false;
157
+ const suffix = dryRun ? ' (dry run)' : '';
158
+ if (options.level && !LEVEL_KEYS.includes(options.level)) {
159
+ console.error(`Unknown level "${options.level}". Valid: ${LEVEL_KEYS.join(', ')}`);
160
+ process.exit(1);
161
+ }
162
+ console.log('Setting up Claude Code integration...\n');
163
+ // Step 1: Team config — always, no prompt
164
+ const teamAdded = writeTeamSettings(cwd, dryRun);
165
+ const teamPath = join(cwd, '.claude', 'settings.json');
166
+ if (teamAdded.length === 0) {
167
+ console.log(`✓ ${teamPath} — already up to date${suffix}`);
168
+ }
169
+ else {
170
+ console.log(`✓ ${teamPath}${suffix}`);
171
+ for (const item of teamAdded)
172
+ console.log(` + ${item}`);
173
+ }
174
+ // Step 2: Personal config — wizard or --level flag
175
+ // Cast is safe: LEVEL_KEYS.includes() validated above; invalid level already called process.exit(1).
176
+ const levelKey = options.level ? options.level : await promptLevel();
177
+ const level = LEVELS[levelKey];
178
+ const personalAdded = writePersonalSettings(levelKey, dryRun);
179
+ const personalPath = join(homedir(), '.claude', 'settings.json');
180
+ if (personalAdded.length === 0) {
181
+ console.log(`✓ ${personalPath} — already at "${level.label}"${suffix}`);
182
+ }
183
+ else {
184
+ console.log(`✓ ${personalPath} — set to "${level.label}"${suffix}`);
185
+ for (const item of personalAdded)
186
+ console.log(` + ${item}`);
187
+ }
188
+ console.log('');
189
+ console.log('Team config → commit .claude/settings.json to share hooks with your team');
190
+ console.log('Personal config → ~/.claude/settings.json is private to this machine, never commit');
191
+ console.log('');
192
+ console.log('Hook failure: if pb is unavailable, hooks fail silently — Claude Code always starts.');
193
+ console.log('');
194
+ if (!dryRun)
195
+ console.log('Reload /hooks in Claude Code (or restart) to activate.');
196
+ console.log('Run `pb handshake --init --level <guide|work|silent|full-trust>` to change level.');
197
+ }
198
+ function shouldWriteAdapter(filePath, force) {
199
+ if (force)
200
+ return true;
201
+ if (!existsSync(filePath))
202
+ return true;
203
+ const content = readFileSync(filePath, 'utf8');
204
+ return content.includes(MARKER);
205
+ }
206
+ function deduplicateEntries(entries) {
207
+ const seen = new Set();
208
+ const result = [];
209
+ for (const e of entries) {
210
+ const key = e.entryId ?? e.name;
211
+ if (!seen.has(key)) {
212
+ seen.add(key);
213
+ result.push(e);
214
+ }
215
+ }
216
+ return result;
217
+ }
218
+ export async function runHandshake(options = {}) {
219
+ const config = await getConfigOrGuide(() => runHandshake(options));
220
+ if (!config)
221
+ return;
222
+ const cwd = process.cwd();
223
+ const force = options.force ?? false;
224
+ const dryRun = options.dryRun ?? false;
225
+ const level = options.level;
226
+ const quiet = options.quiet ?? false;
227
+ const timestamp = new Date().toISOString();
228
+ // Helper: emit progress line only when not quiet (used when handshake is a sub-step)
229
+ const log = (msg) => { if (!quiet)
230
+ process.stdout.write(msg + '\n'); };
231
+ const logErr = (msg) => { if (!quiet)
232
+ process.stderr.write(msg + '\n'); };
233
+ // Validate --level if provided (for handshake content filtering, not --init trust level)
234
+ const VALID_HANDSHAKE_LEVELS = ['beginner', 'intermediate', 'expert'];
235
+ if (level && !VALID_HANDSHAKE_LEVELS.includes(level)) {
236
+ process.stderr.write(`Unknown level "${level}". Valid levels: ${VALID_HANDSHAKE_LEVELS.join(', ')}\n`);
237
+ process.exit(1);
238
+ }
239
+ // 1. Detect repo
240
+ const repo = detectRepo(cwd);
241
+ log(`Detecting repo: ${repo.name ?? 'unknown'}${repo.repoSlug ? ` (${repo.repoSlug})` : ''}`);
242
+ if (repo.detectedStack.length > 0) {
243
+ log(`Stack: ${repo.detectedStack.join(', ')}`);
244
+ }
245
+ // 2. Fetch orient view
246
+ log('Fetching workspace context...');
247
+ let orientView = null;
248
+ try {
249
+ orientView = await mcpCall('chain.getOrientView', {});
250
+ }
251
+ catch (err) {
252
+ logErr(`Warning: could not fetch workspace context — ${err instanceof Error ? err.message : err}`);
253
+ logErr('Continuing with limited context (Chain search + portable knowledge only).');
254
+ }
255
+ // 3. Build search queries from repo context
256
+ const searchQueries = [];
257
+ if (repo.name && repo.name.length >= 2)
258
+ searchQueries.push(repo.name);
259
+ // Add repo slug parts (e.g. "Product-OS" -> "Product-OS")
260
+ if (repo.repoSlug) {
261
+ const repoPart = repo.repoSlug.split('/').pop();
262
+ if (repoPart && repoPart.length >= 2 && repoPart !== repo.name) {
263
+ searchQueries.push(repoPart);
264
+ }
265
+ }
266
+ // Limit to 5 unique queries
267
+ const uniqueQueries = [...new Set(searchQueries.filter((q) => q.length >= 2))].slice(0, 5);
268
+ // 4. Search the Chain
269
+ let matchedEntries = [];
270
+ if (uniqueQueries.length > 0) {
271
+ log(`Searching Chain for: ${uniqueQueries.join(', ')}...`);
272
+ const searchResults = await Promise.all(uniqueQueries.map((q) => mcpCall('chain.searchEntries', { query: q }).catch(() => [])));
273
+ matchedEntries = deduplicateEntries(searchResults.flat());
274
+ }
275
+ // 5. Read canonical skills & rules from .productbrain/
276
+ const pbDir = join(cwd, '.productbrain');
277
+ const allSkills = readCanonicalSkills(pbDir);
278
+ const allRules = readCanonicalRules(pbDir);
279
+ // Apply level filtering (after read, before target filtering in write loop)
280
+ const canonicalSkills = filterByLevel(allSkills, level);
281
+ const canonicalRules = filterByLevel(allRules, level);
282
+ if (canonicalSkills.length > 0 || canonicalRules.length > 0) {
283
+ const levelSuffix = level ? ` (level: ${level})` : '';
284
+ log(`Portable knowledge: ${canonicalSkills.length} skill(s), ${canonicalRules.length} rule(s)${levelSuffix}`);
285
+ }
286
+ // 6. Generate file contents
287
+ const contextContent = orientView ? generateContextMd(orientView, repo, timestamp) : null;
288
+ const briefingContent = generateBriefingMd(matchedEntries, repo, uniqueQueries, timestamp);
289
+ const claudeContent = generateClaudeMd(timestamp);
290
+ const cursorContent = generateCursorMdc(timestamp);
291
+ const copilotContent = generateCopilotMd(timestamp);
292
+ // 7. Write files
293
+ const filesWritten = [];
294
+ const filesSkipped = [];
295
+ const writes = [
296
+ ...(contextContent ? [{ path: join(cwd, '.productbrain', 'context.md'), relative: '.productbrain/context.md', content: contextContent, dirs: join(cwd, '.productbrain'), isAdapter: false }] : []),
297
+ { path: join(cwd, '.productbrain', 'briefing.md'), relative: '.productbrain/briefing.md', content: briefingContent, isAdapter: false },
298
+ { path: join(cwd, 'CLAUDE.md'), relative: 'CLAUDE.md', content: claudeContent, isAdapter: true },
299
+ { path: join(cwd, '.cursor', 'rules', 'chain.mdc'), relative: '.cursor/rules/chain.mdc', content: cursorContent, dirs: join(cwd, '.cursor', 'rules'), isAdapter: true },
300
+ { path: join(cwd, '.github', 'copilot-instructions.md'), relative: '.github/copilot-instructions.md', content: copilotContent, dirs: join(cwd, '.github'), isAdapter: true },
301
+ ];
302
+ // Add Cursor skill copies (filtered by target)
303
+ for (const skill of canonicalSkills) {
304
+ if (!shouldEmitToTarget(skill, 'cursor'))
305
+ continue;
306
+ const skillDir = join(cwd, '.cursor', 'skills', skill.name);
307
+ writes.push({
308
+ path: join(skillDir, 'SKILL.md'),
309
+ relative: `.cursor/skills/${skill.name}/SKILL.md`,
310
+ content: generateCursorSkill(skill),
311
+ dirs: skillDir,
312
+ isAdapter: true,
313
+ });
314
+ }
315
+ // Add Cursor rule copies (filtered by target)
316
+ for (const rule of canonicalRules) {
317
+ if (!shouldEmitToTarget(rule, 'cursor'))
318
+ continue;
319
+ writes.push({
320
+ path: join(cwd, '.cursor', 'rules', `${rule.name}.mdc`),
321
+ relative: `.cursor/rules/${rule.name}.mdc`,
322
+ content: generateCursorRule(rule),
323
+ dirs: join(cwd, '.cursor', 'rules'),
324
+ isAdapter: true,
325
+ });
326
+ }
327
+ // Add Claude Code rule copies (filtered by target)
328
+ for (const rule of canonicalRules) {
329
+ if (!shouldEmitToTarget(rule, 'claude'))
330
+ continue;
331
+ writes.push({
332
+ path: join(cwd, '.claude', 'rules', `${rule.name}.md`),
333
+ relative: `.claude/rules/${rule.name}.md`,
334
+ content: generateClaudeRule(rule),
335
+ dirs: join(cwd, '.claude', 'rules'),
336
+ isAdapter: true,
337
+ });
338
+ }
339
+ // Add Claude Code skill router (filtered by target)
340
+ const claudeSkills = canonicalSkills.filter((s) => shouldEmitToTarget(s, 'claude'));
341
+ const skillRouterContent = generateClaudeSkillRouter(claudeSkills);
342
+ if (skillRouterContent) {
343
+ writes.push({
344
+ path: join(cwd, '.claude', 'rules', 'skill-router.md'),
345
+ relative: '.claude/rules/skill-router.md',
346
+ content: skillRouterContent,
347
+ dirs: join(cwd, '.claude', 'rules'),
348
+ isAdapter: true,
349
+ });
350
+ }
351
+ for (const w of writes) {
352
+ if (w.isAdapter && !shouldWriteAdapter(w.path, force)) {
353
+ filesSkipped.push({ path: w.relative, reason: 'exists without auto-generated marker (use --force to overwrite)' });
354
+ continue;
355
+ }
356
+ if (dryRun) {
357
+ filesWritten.push(w.relative + ' (dry run)');
358
+ continue;
359
+ }
360
+ if (w.dirs)
361
+ mkdirSync(w.dirs, { recursive: true });
362
+ writeFileSync(w.path, w.content);
363
+ filesWritten.push(w.relative);
364
+ }
365
+ // 8. Report
366
+ const report = {
367
+ filesWritten,
368
+ filesSkipped,
369
+ matchedEntries,
370
+ searchQueries: uniqueQueries,
371
+ repo,
372
+ };
373
+ if (!quiet) {
374
+ process.stdout.write('\n');
375
+ process.stdout.write(formatHandshakeReport(report) + '\n');
376
+ }
377
+ }
378
+ //# sourceMappingURL=handshake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../../src/commands/handshake.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * pb ingest — bulk document ingestion to Chain as drafts.
3
+ * BET-81 Slice 1: CLI-first ingestion with clientKind attribution (DEC-184).
4
+ * BET-181 Slice 0: uses isJsonMode() for output branching.
5
+ * BET-221 S7 (FEAT-697): --dry-run, --resume, --concurrency flags.
6
+ */
7
+ export interface IngestOptions {
8
+ pattern: string;
9
+ dryRun?: boolean;
10
+ resume?: boolean;
11
+ concurrency?: number;
12
+ }
13
+ export declare function runIngest(options: IngestOptions): Promise<void>;
14
+ //# sourceMappingURL=ingest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.d.ts","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAeH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAqCD,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAiJrE"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * pb ingest — bulk document ingestion to Chain as drafts.
3
+ * BET-81 Slice 1: CLI-first ingestion with clientKind attribution (DEC-184).
4
+ * BET-181 Slice 0: uses isJsonMode() for output branching.
5
+ * BET-221 S7 (FEAT-697): --dry-run, --resume, --concurrency flags.
6
+ */
7
+ import { readFile } from 'fs/promises';
8
+ import { homedir } from 'os';
9
+ import { resolve } from 'path';
10
+ import { globSync } from 'glob';
11
+ import { randomUUID } from 'crypto';
12
+ import { getConfigOrGuide } from '../lib/config.js';
13
+ import { mcpCall } from '../lib/client.js';
14
+ import { isJsonMode } from '../lib/runner.js';
15
+ import { stripConvexInternals } from '../lib/strip.js';
16
+ /** Max concurrency limit to prevent overwhelming the backend. */
17
+ const MAX_CONCURRENCY = 5;
18
+ function expandGlob(pattern) {
19
+ const cwd = process.cwd();
20
+ const expanded = pattern.startsWith('~') ? pattern.replace('~', homedir()) : pattern;
21
+ const normalized = expanded.replace(/^\.\//, '');
22
+ const resolved = expanded.startsWith('/') ? expanded : resolve(cwd, normalized);
23
+ return globSync(resolved, { nodir: true, absolute: true });
24
+ }
25
+ /**
26
+ * Process files with bounded concurrency using a simple pool.
27
+ * Executes up to `concurrency` tasks simultaneously, returning results in input order.
28
+ */
29
+ async function processWithConcurrency(items, concurrency, fn) {
30
+ const results = new Array(items.length);
31
+ let nextIndex = 0;
32
+ async function worker() {
33
+ while (nextIndex < items.length) {
34
+ const i = nextIndex++;
35
+ results[i] = await fn(items[i], i);
36
+ }
37
+ }
38
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, () => worker());
39
+ await Promise.all(workers);
40
+ return results;
41
+ }
42
+ export async function runIngest(options) {
43
+ const config = await getConfigOrGuide(() => runIngest(options));
44
+ if (!config)
45
+ return;
46
+ const json = isJsonMode();
47
+ const dryRun = options.dryRun ?? false;
48
+ const resume = options.resume ?? false;
49
+ const concurrency = Math.max(1, Math.min(options.concurrency ?? 1, MAX_CONCURRENCY));
50
+ let files = expandGlob(options.pattern);
51
+ if (files.length === 0) {
52
+ process.stderr.write(`No files matched: ${options.pattern}\n`);
53
+ process.exit(1);
54
+ }
55
+ const ingestionRunId = randomUUID();
56
+ // Resolve workspace + keyId — startSession requires apiKeyId (MCP server passes it; CLI gets from resolveWorkspace)
57
+ const workspace = await mcpCall('resolveWorkspace', {});
58
+ if (!workspace?.keyId) {
59
+ throw new Error('API key has no keyId. Use a readwrite key from Settings → API Keys.');
60
+ }
61
+ // --resume: filter out files whose sourceRef is already committed in staging
62
+ let resumeSkipped = 0;
63
+ if (resume) {
64
+ const committedRefs = await mcpCall('staging.getCommittedSourceRefs', {});
65
+ const committedSet = new Set(committedRefs ?? []);
66
+ const originalCount = files.length;
67
+ files = files.filter((f) => !committedSet.has(f));
68
+ resumeSkipped = originalCount - files.length;
69
+ if (!json && resumeSkipped > 0) {
70
+ process.stdout.write(`Resume: skipping ${resumeSkipped} already-committed file(s).\n`);
71
+ }
72
+ if (files.length === 0) {
73
+ if (json) {
74
+ process.stdout.write(JSON.stringify({ totalCreated: 0, resumeSkipped, files: [], ingestionRunId }) + '\n');
75
+ }
76
+ else {
77
+ process.stdout.write('All files already committed. Nothing to do.\n');
78
+ }
79
+ return;
80
+ }
81
+ }
82
+ const startRes = await mcpCall('agent.startSession', {
83
+ workspaceId: workspace._id,
84
+ apiKeyId: workspace.keyId,
85
+ clientKind: 'cli',
86
+ });
87
+ const sessionId = startRes.sessionId;
88
+ let totalCreated = 0;
89
+ let totalSkipped = 0;
90
+ let totalRejected = 0;
91
+ const total = files.length;
92
+ const allResults = [];
93
+ const processFile = async (filePath, i) => {
94
+ try {
95
+ const content = await readFile(filePath, 'utf8');
96
+ const sourceRef = filePath;
97
+ const result = await mcpCall('chain.ingestDocument', {
98
+ content,
99
+ sourceRef,
100
+ ingestionRunId,
101
+ sessionId,
102
+ ...(dryRun && { dryRun: true }),
103
+ });
104
+ const created = result?.entriesCreated?.length ?? 0;
105
+ const skipped = result?.skipped ?? 0;
106
+ const rejected = result?.rejected?.length ?? 0;
107
+ return { filePath, created, skipped, rejected, index: i };
108
+ }
109
+ catch (err) {
110
+ const msg = err instanceof Error ? err.message : String(err);
111
+ if (!json) {
112
+ process.stderr.write(`Error processing ${filePath.split('/').pop()}: ${msg}\n`);
113
+ }
114
+ return { filePath, created: 0, skipped: 0, rejected: 1, index: i };
115
+ }
116
+ };
117
+ try {
118
+ if (concurrency === 1) {
119
+ // Sequential: original behavior with progress output
120
+ for (let i = 0; i < files.length; i++) {
121
+ const { filePath, created, skipped, rejected } = await processFile(files[i], i);
122
+ totalCreated += created;
123
+ totalSkipped += skipped;
124
+ totalRejected += rejected;
125
+ allResults.push({ file: filePath.split('/').pop() ?? filePath, created, skipped, rejected });
126
+ if (!json) {
127
+ const parts = [`${created} created`];
128
+ if (skipped > 0)
129
+ parts.push(`${skipped} skipped`);
130
+ if (rejected > 0)
131
+ parts.push(`${rejected} rejected`);
132
+ process.stdout.write(`Ingesting [${i + 1}/${total}]: ${filePath.split('/').pop()} — ${parts.join(', ')}\n`);
133
+ }
134
+ }
135
+ }
136
+ else {
137
+ // Concurrent: process with pool, then output aggregated results
138
+ if (!json) {
139
+ process.stdout.write(`Processing ${total} file(s) with concurrency ${concurrency}...\n`);
140
+ }
141
+ const results = await processWithConcurrency(files, concurrency, processFile);
142
+ for (const { filePath, created, skipped, rejected } of results) {
143
+ totalCreated += created;
144
+ totalSkipped += skipped;
145
+ totalRejected += rejected;
146
+ allResults.push({ file: filePath.split('/').pop() ?? filePath, created, skipped, rejected });
147
+ }
148
+ if (!json) {
149
+ for (let i = 0; i < allResults.length; i++) {
150
+ const r = allResults[i];
151
+ const parts = [`${r.created} created`];
152
+ if (r.skipped > 0)
153
+ parts.push(`${r.skipped} skipped`);
154
+ if (r.rejected > 0)
155
+ parts.push(`${r.rejected} rejected`);
156
+ process.stdout.write(` [${i + 1}/${total}]: ${r.file} — ${parts.join(', ')}\n`);
157
+ }
158
+ }
159
+ }
160
+ }
161
+ finally {
162
+ await mcpCall('agent.closeSession', { sessionId, status: 'closed' });
163
+ }
164
+ if (json) {
165
+ process.stdout.write(JSON.stringify(stripConvexInternals({
166
+ totalCreated,
167
+ totalSkipped,
168
+ totalRejected,
169
+ ...(resume && { resumeSkipped }),
170
+ dryRun,
171
+ files: allResults,
172
+ ingestionRunId,
173
+ })) + '\n');
174
+ }
175
+ else {
176
+ const dryRunSuffix = dryRun ? ' (dry run — staged only, not committed)' : '';
177
+ const resumeSuffix = resumeSkipped > 0 ? ` ${resumeSkipped} file(s) skipped by --resume.` : '';
178
+ process.stdout.write(`\nDone. ${totalCreated} entries created as drafts.${dryRunSuffix}${resumeSuffix} Open Cortex to review.\n`);
179
+ }
180
+ }
181
+ //# sourceMappingURL=ingest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * pb login — save API key to ~/.config/productbrain/.env so pb works from any directory.
3
+ */
4
+ export declare function runLogin(): Promise<void>;
5
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAuD9C"}