@productbrain/cli 0.1.0-beta.30 → 0.1.0-beta.34

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 (214) hide show
  1. package/README.md +62 -178
  2. package/dist/__tests__/capture.test.js +2 -11
  3. package/dist/__tests__/capture.test.js.map +1 -1
  4. package/dist/__tests__/config.test.d.ts +8 -0
  5. package/dist/__tests__/config.test.d.ts.map +1 -0
  6. package/dist/__tests__/config.test.js +166 -0
  7. package/dist/__tests__/config.test.js.map +1 -0
  8. package/dist/__tests__/constants.test.js +1 -1
  9. package/dist/__tests__/constants.test.js.map +1 -1
  10. package/dist/__tests__/constellation.test.js +2 -8
  11. package/dist/__tests__/constellation.test.js.map +1 -1
  12. package/dist/__tests__/errors.test.d.ts +2 -0
  13. package/dist/__tests__/errors.test.d.ts.map +1 -0
  14. package/dist/__tests__/errors.test.js +117 -0
  15. package/dist/__tests__/errors.test.js.map +1 -0
  16. package/dist/__tests__/fields.test.js +14 -14
  17. package/dist/__tests__/fields.test.js.map +1 -1
  18. package/dist/__tests__/glossary.test.d.ts +2 -0
  19. package/dist/__tests__/glossary.test.d.ts.map +1 -0
  20. package/dist/__tests__/glossary.test.js +32 -0
  21. package/dist/__tests__/glossary.test.js.map +1 -0
  22. package/dist/__tests__/handshake.test.js +9 -17
  23. package/dist/__tests__/handshake.test.js.map +1 -1
  24. package/dist/__tests__/init.test.d.ts +7 -0
  25. package/dist/__tests__/init.test.d.ts.map +1 -0
  26. package/dist/__tests__/init.test.js +146 -0
  27. package/dist/__tests__/init.test.js.map +1 -0
  28. package/dist/__tests__/login.test.js +29 -30
  29. package/dist/__tests__/login.test.js.map +1 -1
  30. package/dist/__tests__/onboarding.test.d.ts +6 -0
  31. package/dist/__tests__/onboarding.test.d.ts.map +1 -0
  32. package/dist/__tests__/onboarding.test.js +199 -0
  33. package/dist/__tests__/onboarding.test.js.map +1 -0
  34. package/dist/__tests__/profiles.test.d.ts +2 -0
  35. package/dist/__tests__/profiles.test.d.ts.map +1 -0
  36. package/dist/__tests__/profiles.test.js +168 -0
  37. package/dist/__tests__/profiles.test.js.map +1 -0
  38. package/dist/__tests__/promote.test.js +4 -16
  39. package/dist/__tests__/promote.test.js.map +1 -1
  40. package/dist/__tests__/prompts.test.d.ts +6 -0
  41. package/dist/__tests__/prompts.test.d.ts.map +1 -0
  42. package/dist/__tests__/prompts.test.js +146 -0
  43. package/dist/__tests__/prompts.test.js.map +1 -0
  44. package/dist/__tests__/proposals.test.js +6 -29
  45. package/dist/__tests__/proposals.test.js.map +1 -1
  46. package/dist/__tests__/relate.test.js +6 -23
  47. package/dist/__tests__/relate.test.js.map +1 -1
  48. package/dist/__tests__/runner.test.js +19 -15
  49. package/dist/__tests__/runner.test.js.map +1 -1
  50. package/dist/__tests__/session.test.js +2 -8
  51. package/dist/__tests__/session.test.js.map +1 -1
  52. package/dist/__tests__/setup.test.js +39 -25
  53. package/dist/__tests__/setup.test.js.map +1 -1
  54. package/dist/__tests__/spinner-labels.test.d.ts +2 -0
  55. package/dist/__tests__/spinner-labels.test.d.ts.map +1 -0
  56. package/dist/__tests__/spinner-labels.test.js +23 -0
  57. package/dist/__tests__/spinner-labels.test.js.map +1 -0
  58. package/dist/__tests__/update.test.js +27 -61
  59. package/dist/__tests__/update.test.js.map +1 -1
  60. package/dist/__tests__/workspace.test.d.ts +2 -0
  61. package/dist/__tests__/workspace.test.d.ts.map +1 -0
  62. package/dist/__tests__/workspace.test.js +308 -0
  63. package/dist/__tests__/workspace.test.js.map +1 -0
  64. package/dist/commands/accept.d.ts.map +1 -1
  65. package/dist/commands/accept.js +6 -2
  66. package/dist/commands/accept.js.map +1 -1
  67. package/dist/commands/brief.d.ts.map +1 -1
  68. package/dist/commands/brief.js +6 -1
  69. package/dist/commands/brief.js.map +1 -1
  70. package/dist/commands/capture.d.ts.map +1 -1
  71. package/dist/commands/capture.js +20 -12
  72. package/dist/commands/capture.js.map +1 -1
  73. package/dist/commands/chain-walk.d.ts.map +1 -1
  74. package/dist/commands/chain-walk.js +6 -1
  75. package/dist/commands/chain-walk.js.map +1 -1
  76. package/dist/commands/changes.d.ts.map +1 -1
  77. package/dist/commands/changes.js +6 -1
  78. package/dist/commands/changes.js.map +1 -1
  79. package/dist/commands/codex-prep.d.ts.map +1 -1
  80. package/dist/commands/codex-prep.js +6 -2
  81. package/dist/commands/codex-prep.js.map +1 -1
  82. package/dist/commands/collections.d.ts.map +1 -1
  83. package/dist/commands/collections.js +6 -2
  84. package/dist/commands/collections.js.map +1 -1
  85. package/dist/commands/constellation.d.ts.map +1 -1
  86. package/dist/commands/constellation.js +6 -1
  87. package/dist/commands/constellation.js.map +1 -1
  88. package/dist/commands/context.d.ts.map +1 -1
  89. package/dist/commands/context.js +6 -1
  90. package/dist/commands/context.js.map +1 -1
  91. package/dist/commands/doctor.d.ts +9 -2
  92. package/dist/commands/doctor.d.ts.map +1 -1
  93. package/dist/commands/doctor.js +125 -28
  94. package/dist/commands/doctor.js.map +1 -1
  95. package/dist/commands/doctor.test.d.ts +3 -1
  96. package/dist/commands/doctor.test.d.ts.map +1 -1
  97. package/dist/commands/doctor.test.js +206 -10
  98. package/dist/commands/doctor.test.js.map +1 -1
  99. package/dist/commands/fields.d.ts.map +1 -1
  100. package/dist/commands/fields.js +6 -2
  101. package/dist/commands/fields.js.map +1 -1
  102. package/dist/commands/get.d.ts.map +1 -1
  103. package/dist/commands/get.js +11 -3
  104. package/dist/commands/get.js.map +1 -1
  105. package/dist/commands/handshake.d.ts.map +1 -1
  106. package/dist/commands/handshake.js +21 -22
  107. package/dist/commands/handshake.js.map +1 -1
  108. package/dist/commands/ingest.d.ts.map +1 -1
  109. package/dist/commands/ingest.js +11 -3
  110. package/dist/commands/ingest.js.map +1 -1
  111. package/dist/commands/init.d.ts +14 -0
  112. package/dist/commands/init.d.ts.map +1 -0
  113. package/dist/commands/init.js +117 -0
  114. package/dist/commands/init.js.map +1 -0
  115. package/dist/commands/login.d.ts.map +1 -1
  116. package/dist/commands/login.js +32 -20
  117. package/dist/commands/login.js.map +1 -1
  118. package/dist/commands/profile.d.ts +24 -0
  119. package/dist/commands/profile.d.ts.map +1 -0
  120. package/dist/commands/profile.js +82 -0
  121. package/dist/commands/profile.js.map +1 -0
  122. package/dist/commands/promote.d.ts.map +1 -1
  123. package/dist/commands/promote.js +22 -7
  124. package/dist/commands/promote.js.map +1 -1
  125. package/dist/commands/reject.d.ts.map +1 -1
  126. package/dist/commands/reject.js +11 -5
  127. package/dist/commands/reject.js.map +1 -1
  128. package/dist/commands/relate.d.ts.map +1 -1
  129. package/dist/commands/relate.js +21 -10
  130. package/dist/commands/relate.js.map +1 -1
  131. package/dist/commands/session.d.ts.map +1 -1
  132. package/dist/commands/session.js +16 -6
  133. package/dist/commands/session.js.map +1 -1
  134. package/dist/commands/setup.d.ts +1 -2
  135. package/dist/commands/setup.d.ts.map +1 -1
  136. package/dist/commands/setup.js +17 -38
  137. package/dist/commands/setup.js.map +1 -1
  138. package/dist/commands/update.d.ts.map +1 -1
  139. package/dist/commands/update.js +45 -27
  140. package/dist/commands/update.js.map +1 -1
  141. package/dist/commands/verify.d.ts.map +1 -1
  142. package/dist/commands/verify.js +11 -5
  143. package/dist/commands/verify.js.map +1 -1
  144. package/dist/commands/workspace.d.ts +41 -0
  145. package/dist/commands/workspace.d.ts.map +1 -0
  146. package/dist/commands/workspace.js +239 -0
  147. package/dist/commands/workspace.js.map +1 -0
  148. package/dist/formatters/promote.d.ts +1 -0
  149. package/dist/formatters/promote.d.ts.map +1 -1
  150. package/dist/formatters/promote.js +1 -0
  151. package/dist/formatters/promote.js.map +1 -1
  152. package/dist/index.js +328 -299
  153. package/dist/index.js.map +1 -1
  154. package/dist/lib/client.d.ts +4 -2
  155. package/dist/lib/client.d.ts.map +1 -1
  156. package/dist/lib/client.js +143 -68
  157. package/dist/lib/client.js.map +1 -1
  158. package/dist/lib/config.d.ts +63 -4
  159. package/dist/lib/config.d.ts.map +1 -1
  160. package/dist/lib/config.js +230 -36
  161. package/dist/lib/config.js.map +1 -1
  162. package/dist/lib/constants.d.ts +1 -1
  163. package/dist/lib/constants.d.ts.map +1 -1
  164. package/dist/lib/constants.js +1 -1
  165. package/dist/lib/constants.js.map +1 -1
  166. package/dist/lib/errors.d.ts +58 -0
  167. package/dist/lib/errors.d.ts.map +1 -0
  168. package/dist/lib/errors.js +67 -0
  169. package/dist/lib/errors.js.map +1 -0
  170. package/dist/lib/format.d.ts +10 -0
  171. package/dist/lib/format.d.ts.map +1 -0
  172. package/dist/lib/format.js +27 -0
  173. package/dist/lib/format.js.map +1 -0
  174. package/dist/lib/glossary.d.ts +19 -0
  175. package/dist/lib/glossary.d.ts.map +1 -0
  176. package/dist/lib/glossary.js +53 -0
  177. package/dist/lib/glossary.js.map +1 -0
  178. package/dist/lib/onboarding.d.ts +19 -0
  179. package/dist/lib/onboarding.d.ts.map +1 -0
  180. package/dist/lib/onboarding.js +373 -0
  181. package/dist/lib/onboarding.js.map +1 -0
  182. package/dist/lib/profiles.d.ts +34 -0
  183. package/dist/lib/profiles.d.ts.map +1 -0
  184. package/dist/lib/profiles.js +173 -0
  185. package/dist/lib/profiles.js.map +1 -0
  186. package/dist/lib/prompts.d.ts +38 -0
  187. package/dist/lib/prompts.d.ts.map +1 -0
  188. package/dist/lib/prompts.js +90 -0
  189. package/dist/lib/prompts.js.map +1 -0
  190. package/dist/lib/runner.d.ts +2 -0
  191. package/dist/lib/runner.d.ts.map +1 -1
  192. package/dist/lib/runner.js +21 -7
  193. package/dist/lib/runner.js.map +1 -1
  194. package/dist/lib/spinner.d.ts +27 -0
  195. package/dist/lib/spinner.d.ts.map +1 -0
  196. package/dist/lib/spinner.js +76 -0
  197. package/dist/lib/spinner.js.map +1 -0
  198. package/dist/lib/spinner.test.d.ts +2 -0
  199. package/dist/lib/spinner.test.d.ts.map +1 -0
  200. package/dist/lib/spinner.test.js +39 -0
  201. package/dist/lib/spinner.test.js.map +1 -0
  202. package/dist/lib/style.d.ts +65 -0
  203. package/dist/lib/style.d.ts.map +1 -0
  204. package/dist/lib/style.js +108 -0
  205. package/dist/lib/style.js.map +1 -0
  206. package/dist/lib/style.test.d.ts +7 -0
  207. package/dist/lib/style.test.d.ts.map +1 -0
  208. package/dist/lib/style.test.js +195 -0
  209. package/dist/lib/style.test.js.map +1 -0
  210. package/dist/lib/workspace-probe.d.ts +16 -0
  211. package/dist/lib/workspace-probe.d.ts.map +1 -0
  212. package/dist/lib/workspace-probe.js +33 -0
  213. package/dist/lib/workspace-probe.js.map +1 -0
  214. package/package.json +2 -1
@@ -0,0 +1,53 @@
1
+ /**
2
+ * glossary.ts — Key CLI terms and their definitions.
3
+ *
4
+ * Provides a static glossary of Product Brain CLI terminology,
5
+ * plus a formatter for TTY output.
6
+ *
7
+ * WP-302 Slice 4.
8
+ */
9
+ import { bold, dim } from './style.js';
10
+ export const GLOSSARY = [
11
+ {
12
+ term: 'workspace',
13
+ definition: 'Your product knowledge space. One workspace = one product.',
14
+ },
15
+ {
16
+ term: 'entry',
17
+ definition: 'A unit of product knowledge (bet, decision, tension, standard, etc.).',
18
+ },
19
+ {
20
+ term: 'collection',
21
+ definition: 'A group of related entries (work-packages, decisions, tensions, etc.).',
22
+ },
23
+ {
24
+ term: 'relation',
25
+ definition: 'A typed link between entries (part_of, depends_on, addresses, etc.).',
26
+ },
27
+ {
28
+ term: 'session',
29
+ definition: 'A tracked write session. Required before creating or updating entries.',
30
+ },
31
+ {
32
+ term: 'capture',
33
+ definition: 'Create a new entry on the Chain via pb capture.',
34
+ },
35
+ {
36
+ term: 'profile',
37
+ definition: 'A named workspace configuration with API key and endpoint.',
38
+ },
39
+ ];
40
+ /**
41
+ * Format the glossary for TTY output.
42
+ * Returns a multi-line string with bold terms and dimmed definitions.
43
+ */
44
+ export function formatGlossary() {
45
+ const lines = [];
46
+ const maxTermLen = Math.max(...GLOSSARY.map((g) => g.term.length));
47
+ for (const entry of GLOSSARY) {
48
+ const paddedTerm = entry.term.padEnd(maxTermLen);
49
+ lines.push(` ${bold(paddedTerm)} ${dim(entry.definition)}`);
50
+ }
51
+ return lines.join('\n');
52
+ }
53
+ //# sourceMappingURL=glossary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/lib/glossary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAOvC,MAAM,CAAC,MAAM,QAAQ,GAAoB;IACvC;QACE,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,4DAA4D;KACzE;IACD;QACE,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,uEAAuE;KACpF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE,wEAAwE;KACrF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,sEAAsE;KACnF;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,wEAAwE;KACrF;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,iDAAiD;KAC9D;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,4DAA4D;KACzE;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Onboarding conversation — LLM-powered natural conversation for new workspaces.
3
+ * WP-304 Slice 0: Single-turn proof of concept.
4
+ * WP-304 Slice 1: Multi-turn conversation + extraction + auto-capture.
5
+ *
6
+ * Uses @clack/prompts (WP-303 S1) and the MCP gateway to call the
7
+ * Convex onboardingChat action for conversation and extraction,
8
+ * then chain.createEntry for batch-capture.
9
+ */
10
+ /**
11
+ * Run the onboarding conversation: multi-turn chat, extraction, and auto-capture.
12
+ */
13
+ export declare function runOnboardingConversation(workspaceName: string): Promise<void>;
14
+ /**
15
+ * Deterministic fallback when LLM is unavailable.
16
+ * Asks 3 hardcoded questions and maps answers to the same capture pipeline.
17
+ */
18
+ export declare function runFallbackOnboarding(workspaceName: string): Promise<void>;
19
+ //# sourceMappingURL=onboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.d.ts","sourceRoot":"","sources":["../../src/lib/onboarding.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgLH;;GAEG;AACH,wBAAsB,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyLpF;AAmCD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DhF"}
@@ -0,0 +1,373 @@
1
+ /**
2
+ * Onboarding conversation — LLM-powered natural conversation for new workspaces.
3
+ * WP-304 Slice 0: Single-turn proof of concept.
4
+ * WP-304 Slice 1: Multi-turn conversation + extraction + auto-capture.
5
+ *
6
+ * Uses @clack/prompts (WP-303 S1) and the MCP gateway to call the
7
+ * Convex onboardingChat action for conversation and extraction,
8
+ * then chain.createEntry for batch-capture.
9
+ */
10
+ import { mcpCall, mcpCallWithSession } from './client.js';
11
+ import { ask, confirm } from './prompts.js';
12
+ import { bold, dim, green, icons } from './style.js';
13
+ import { trackEvent } from './telemetry.js';
14
+ /** Max conversation exchanges (including the initial greeting). */
15
+ const MAX_TURNS = 5;
16
+ /** Signals that the LLM is ready to synthesize (present in its response). */
17
+ const SYNTHESIS_SIGNALS = [
18
+ 'good picture',
19
+ 'organize what',
20
+ 'let me organize',
21
+ 'enough to get started',
22
+ 'have a good sense',
23
+ 'got a clear picture',
24
+ 'great start',
25
+ 'let me pull',
26
+ 'let me put',
27
+ ];
28
+ // ── Extraction → Entries Mapping ────────────────────────────────────────────
29
+ // SYNC: Must match packages/mcp-server/src/tools/start-interview.ts:extractionToBatchEntries
30
+ // Duplicated due to monorepo import boundary (BR-165). TEN tracked for shared-package extraction.
31
+ function truncate(str, maxLen) {
32
+ return str.length <= maxLen ? str : str.slice(0, maxLen);
33
+ }
34
+ function firstNWords(str, n) {
35
+ return str.split(/\s+/).slice(0, n).join(' ');
36
+ }
37
+ function extractionToEntries(extracted) {
38
+ const entries = [];
39
+ if (extracted.vision?.trim()) {
40
+ entries.push({
41
+ collection: 'strategy',
42
+ name: 'Product Vision',
43
+ description: extracted.vision,
44
+ });
45
+ }
46
+ if (extracted.audience) {
47
+ entries.push({
48
+ collection: 'audiences',
49
+ name: firstNWords(extracted.audience, 6),
50
+ description: extracted.audience,
51
+ });
52
+ }
53
+ if (extracted.techStack?.length) {
54
+ entries.push({
55
+ collection: 'architecture',
56
+ name: 'Tech Stack',
57
+ description: `Technology choices: ${extracted.techStack.join(', ')}`,
58
+ });
59
+ for (const tech of extracted.techStack.slice(0, 3)) {
60
+ entries.push({
61
+ collection: 'glossary',
62
+ name: tech,
63
+ description: `${tech} — part of the tech stack`,
64
+ });
65
+ }
66
+ }
67
+ if (extracted.keyTerms?.length) {
68
+ for (const term of extracted.keyTerms) {
69
+ const alreadyAdded = entries.some((e) => e.collection === 'glossary' && e.name.toLowerCase() === term.toLowerCase());
70
+ if (!alreadyAdded) {
71
+ entries.push({
72
+ collection: 'glossary',
73
+ name: term,
74
+ description: `Core domain term: ${term}`,
75
+ });
76
+ }
77
+ }
78
+ }
79
+ if (extracted.keyDecisions?.length) {
80
+ for (const decision of extracted.keyDecisions) {
81
+ entries.push({
82
+ collection: 'decisions',
83
+ name: truncate(decision, 80),
84
+ description: decision,
85
+ });
86
+ }
87
+ }
88
+ if (extracted.tensions?.length) {
89
+ for (const tension of extracted.tensions) {
90
+ entries.push({
91
+ collection: 'tensions',
92
+ name: truncate(tension, 80),
93
+ description: tension,
94
+ });
95
+ }
96
+ }
97
+ return entries;
98
+ }
99
+ // ── Display helpers ─────────────────────────────────────────────────────────
100
+ function displayExtraction(extracted) {
101
+ process.stdout.write(`\n Here's what I picked up:\n\n`);
102
+ if (extracted.vision) {
103
+ process.stdout.write(` ${green('\u2726')} Your product vision: ${extracted.vision}\n`);
104
+ }
105
+ if (extracted.audience) {
106
+ process.stdout.write(` ${green('\u2726')} Your audience: ${extracted.audience}\n`);
107
+ }
108
+ if (extracted.techStack?.length) {
109
+ process.stdout.write(` ${green('\u2726')} Tech stack: ${extracted.techStack.join(', ')}\n`);
110
+ }
111
+ if (extracted.keyTerms?.length) {
112
+ process.stdout.write(` ${green('\u2726')} Key terms: ${extracted.keyTerms.join(', ')}\n`);
113
+ }
114
+ if (extracted.keyDecisions?.length) {
115
+ process.stdout.write(` ${green('\u2726')} Key decisions: ${extracted.keyDecisions.join('; ')}\n`);
116
+ }
117
+ if (extracted.tensions?.length) {
118
+ process.stdout.write(` ${green('\u2726')} Challenges: ${extracted.tensions.join('; ')}\n`);
119
+ }
120
+ process.stdout.write('\n');
121
+ }
122
+ function hasSynthesisSignal(text) {
123
+ const lower = text.toLowerCase();
124
+ return SYNTHESIS_SIGNALS.some((signal) => lower.includes(signal));
125
+ }
126
+ // ── Main conversation ───────────────────────────────────────────────────────
127
+ /**
128
+ * Run the onboarding conversation: multi-turn chat, extraction, and auto-capture.
129
+ */
130
+ export async function runOnboardingConversation(workspaceName) {
131
+ trackEvent('setup_started', { mode: 'llm' });
132
+ const messages = [];
133
+ // Step 1: Get the LLM's opening greeting
134
+ let greeting;
135
+ try {
136
+ const result = await mcpCall('onboarding.chat', {
137
+ messages: [],
138
+ workspaceName,
139
+ });
140
+ if (!result?.content) {
141
+ // LLM unavailable — fall back to deterministic conversation
142
+ await runFallbackOnboarding(workspaceName);
143
+ return;
144
+ }
145
+ greeting = result.content;
146
+ }
147
+ catch {
148
+ // LLM unavailable — fall back to deterministic conversation
149
+ await runFallbackOnboarding(workspaceName);
150
+ return;
151
+ }
152
+ // Display greeting and start conversation loop
153
+ process.stdout.write(`\n ${greeting}\n\n`);
154
+ messages.push({ role: 'assistant', content: greeting });
155
+ // Step 2: Multi-turn conversation (max MAX_TURNS exchanges total)
156
+ let turnCount = 1; // greeting counts as turn 1
157
+ let readyToExtract = false;
158
+ while (turnCount < MAX_TURNS && !readyToExtract) {
159
+ // Get user input
160
+ let userInput;
161
+ try {
162
+ userInput = await ask({
163
+ message: 'You',
164
+ placeholder: turnCount === 1 ? 'Tell me about your product...' : 'Continue...',
165
+ });
166
+ }
167
+ catch {
168
+ // User cancelled
169
+ process.stdout.write(`\n ${dim('No worries! Tell me about your product anytime with')} ${bold('pb capture')}\n\n`);
170
+ return;
171
+ }
172
+ if (!userInput.trim()) {
173
+ process.stdout.write(`\n ${dim('No worries! Tell me about your product anytime with')} ${bold('pb capture')}\n\n`);
174
+ return;
175
+ }
176
+ messages.push({ role: 'user', content: userInput });
177
+ turnCount++;
178
+ // Get LLM response
179
+ try {
180
+ const result = await mcpCall('onboarding.chat', {
181
+ messages,
182
+ workspaceName,
183
+ });
184
+ if (result?.content) {
185
+ process.stdout.write(`\n ${result.content}\n\n`);
186
+ messages.push({ role: 'assistant', content: result.content });
187
+ // Check if LLM signals readiness to synthesize
188
+ if (hasSynthesisSignal(result.content)) {
189
+ readyToExtract = true;
190
+ }
191
+ }
192
+ else {
193
+ // LLM returned nothing — extract what we have
194
+ readyToExtract = true;
195
+ }
196
+ }
197
+ catch {
198
+ // LLM call failed — extract what we have
199
+ readyToExtract = true;
200
+ }
201
+ }
202
+ trackEvent('first_capture_prompted', { mode: 'llm', turnCount });
203
+ // Step 3: Extract structured data from conversation
204
+ if (messages.filter((m) => m.role === 'user').length === 0) {
205
+ // No user messages — nothing to extract
206
+ process.stdout.write(`\n ${dim('No worries! Tell me about your product anytime with')} ${bold('pb capture')}\n\n`);
207
+ return;
208
+ }
209
+ let extraction;
210
+ try {
211
+ const result = await mcpCall('onboarding.chat', {
212
+ messages,
213
+ workspaceName,
214
+ mode: 'extract',
215
+ });
216
+ if (!result?.extraction?.vision) {
217
+ process.stdout.write(`\n ${dim("Couldn't organize your answers just yet. Try")} ${bold('pb capture')} ${dim('to add knowledge manually.')}\n\n`);
218
+ return;
219
+ }
220
+ extraction = result.extraction;
221
+ }
222
+ catch {
223
+ process.stdout.write(`\n ${dim("Couldn't organize your answers just yet. Try")} ${bold('pb capture')} ${dim('to add knowledge manually.')}\n\n`);
224
+ return;
225
+ }
226
+ // Step 4: Display extracted items and ask for approval
227
+ displayExtraction(extraction);
228
+ let approved;
229
+ try {
230
+ approved = await confirm({
231
+ message: 'Ready to save these to your product brain?',
232
+ initialValue: true,
233
+ });
234
+ }
235
+ catch {
236
+ process.stdout.write(`\n ${dim('No problem. Your answers are safe — run')} ${bold('pb capture')} ${dim('anytime.')}\n\n`);
237
+ return;
238
+ }
239
+ if (!approved) {
240
+ process.stdout.write(`\n ${dim('No problem. Your answers are safe — run')} ${bold('pb capture')} ${dim('anytime.')}\n\n`);
241
+ return;
242
+ }
243
+ // Step 5: Batch-capture entries via chain.createEntry
244
+ const entriesToCapture = extractionToEntries(extraction);
245
+ if (entriesToCapture.length === 0) {
246
+ process.stdout.write(`\n ${dim('Nothing to save. Try')} ${bold('pb capture')} ${dim('to add knowledge manually.')}\n\n`);
247
+ return;
248
+ }
249
+ let capturedCount = 0;
250
+ const errors = [];
251
+ for (const entry of entriesToCapture) {
252
+ try {
253
+ await mcpCallWithSession('chain.createEntry', {
254
+ collectionSlug: entry.collection,
255
+ name: entry.name,
256
+ status: 'active',
257
+ data: { description: entry.description },
258
+ });
259
+ capturedCount++;
260
+ }
261
+ catch (err) {
262
+ const msg = err instanceof Error ? err.message : String(err);
263
+ errors.push(`${entry.name}: ${msg}`);
264
+ }
265
+ }
266
+ // Step 6: Report results
267
+ if (capturedCount > 0) {
268
+ process.stdout.write(`\n ${green(icons.pass)} Saved ${capturedCount} item${capturedCount === 1 ? '' : 's'} to your product brain.\n`);
269
+ trackEvent('capture_completed', { mode: 'llm', count: capturedCount });
270
+ }
271
+ if (errors.length > 0) {
272
+ process.stdout.write(`\n ${dim(`${errors.length} item${errors.length === 1 ? '' : 's'} couldn't be saved:`)}\n`);
273
+ for (const err of errors.slice(0, 3)) {
274
+ process.stdout.write(` ${dim(err)}\n`);
275
+ }
276
+ }
277
+ // Step 7: Auto-retrieval proof (BR-141, PRI-58, FEAT-149)
278
+ await showRetrievalProof();
279
+ // Step 8: Closing message with community link
280
+ process.stdout.write(` ${dim('Join the community:')} ${bold('community.productbrain.io')}\n`);
281
+ process.stdout.write(` ${dim('Your product brain gets smarter every time you capture.')}\n\n`);
282
+ process.stdout.write(` ${dim('Explore with')} ${bold('pb orient -b')} ${dim('or add more with')} ${bold('pb capture')}\n\n`);
283
+ trackEvent('setup_completed', { capturedCount });
284
+ }
285
+ // ── Auto-retrieval proof ──────────────────────────────────────────────────
286
+ async function showRetrievalProof() {
287
+ try {
288
+ const orient = await mcpCall('orient', { brief: true });
289
+ const items = orient?.sections?.flatMap((s) => s.items ?? []).filter((i) => i.name) ?? [];
290
+ if (items.length > 0) {
291
+ process.stdout.write(`\n ${bold('Here\'s how your product brain will use this:')}\n\n`);
292
+ for (const item of items.slice(0, 5)) {
293
+ process.stdout.write(` ${dim(icons.dot)} ${item.name}\n`);
294
+ }
295
+ if (items.length > 5) {
296
+ process.stdout.write(` ${dim(`...and ${items.length - 5} more`)}\n`);
297
+ }
298
+ process.stdout.write('\n');
299
+ }
300
+ }
301
+ catch {
302
+ // Retrieval proof is best-effort — never block onboarding
303
+ }
304
+ }
305
+ // ── Deterministic fallback ────────────────────────────────────────────────
306
+ const FALLBACK_QUESTIONS = [
307
+ { message: 'What are you building?', placeholder: 'A tool for...' },
308
+ { message: 'Who is it for?', placeholder: 'Developers, designers, teams...' },
309
+ { message: 'What\'s the biggest challenge right now?', placeholder: 'Scaling, onboarding, pricing...' },
310
+ ];
311
+ /**
312
+ * Deterministic fallback when LLM is unavailable.
313
+ * Asks 3 hardcoded questions and maps answers to the same capture pipeline.
314
+ */
315
+ export async function runFallbackOnboarding(workspaceName) {
316
+ trackEvent('setup_started', { mode: 'fallback' });
317
+ process.stdout.write(`\n ${bold(`Let me learn about ${workspaceName}.`)} ${dim('(Quick — 3 questions)')}\n\n`);
318
+ const answers = [];
319
+ for (const q of FALLBACK_QUESTIONS) {
320
+ try {
321
+ const answer = await ask({ message: q.message, placeholder: q.placeholder });
322
+ if (answer.trim())
323
+ answers.push(answer.trim());
324
+ }
325
+ catch {
326
+ break;
327
+ }
328
+ }
329
+ if (answers.length === 0) {
330
+ process.stdout.write(`\n ${dim('No worries! Add knowledge anytime with')} ${bold('pb capture')}\n\n`);
331
+ return;
332
+ }
333
+ trackEvent('first_capture_prompted', { mode: 'fallback' });
334
+ // Build extraction from answers
335
+ const extraction = {
336
+ vision: answers[0],
337
+ audience: answers[1] || null,
338
+ tensions: answers[2] ? [answers[2]] : null,
339
+ };
340
+ displayExtraction(extraction);
341
+ let approved;
342
+ try {
343
+ approved = await confirm({ message: 'Ready to save these to your product brain?', initialValue: true });
344
+ }
345
+ catch {
346
+ return;
347
+ }
348
+ if (!approved)
349
+ return;
350
+ const entriesToCapture = extractionToEntries(extraction);
351
+ let capturedCount = 0;
352
+ for (const entry of entriesToCapture) {
353
+ try {
354
+ await mcpCallWithSession('chain.createEntry', {
355
+ collectionSlug: entry.collection,
356
+ name: entry.name,
357
+ status: 'active',
358
+ data: { description: entry.description },
359
+ });
360
+ capturedCount++;
361
+ }
362
+ catch { /* continue on error */ }
363
+ }
364
+ if (capturedCount > 0) {
365
+ process.stdout.write(`\n ${green(icons.pass)} Saved ${capturedCount} item${capturedCount === 1 ? '' : 's'} to your product brain.\n`);
366
+ trackEvent('capture_completed', { mode: 'fallback', count: capturedCount });
367
+ }
368
+ await showRetrievalProof();
369
+ process.stdout.write(` ${dim('Join the community:')} ${bold('community.productbrain.io')}\n`);
370
+ process.stdout.write(` ${dim('Your product brain gets smarter every time you capture.')}\n\n`);
371
+ trackEvent('setup_completed', { mode: 'fallback', capturedCount });
372
+ }
373
+ //# sourceMappingURL=onboarding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding.js","sourceRoot":"","sources":["../../src/lib/onboarding.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Profile storage and resolution — multi-workspace support for the Product Brain CLI.
3
+ * WP-302 Slice 2: Workspace Profiles + Config Refactor.
4
+ *
5
+ * Profile directory: ~/.config/productbrain/profiles/
6
+ * Active profile tracked in: ~/.config/productbrain/active-profile
7
+ * Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
8
+ */
9
+ declare const HOME_CONFIG_DIR: string;
10
+ declare const PROFILES_DIR: string;
11
+ declare const ACTIVE_PROFILE_PATH: string;
12
+ declare const LEGACY_ENV_PATH: string;
13
+ export interface ProfileConfig {
14
+ apiKey: string;
15
+ siteUrl?: string;
16
+ }
17
+ /** List all profile names (sorted). */
18
+ export declare function listProfiles(): string[];
19
+ /** Get the active profile name. */
20
+ export declare function getActiveProfile(): string | null;
21
+ /** Create a new profile. */
22
+ export declare function createProfile(name: string, apiKey: string, siteUrl?: string): void;
23
+ /** Switch the active profile. */
24
+ export declare function useProfile(name: string): void;
25
+ /** Delete a profile. Cannot delete the last profile or the active profile. */
26
+ export declare function deleteProfile(name: string): void;
27
+ /**
28
+ * Resolve config from the active profile.
29
+ * Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
30
+ * Returns null if no profile or config is available.
31
+ */
32
+ export declare function resolveProfileConfig(): ProfileConfig | null;
33
+ export { PROFILES_DIR, ACTIVE_PROFILE_PATH, LEGACY_ENV_PATH, HOME_CONFIG_DIR };
34
+ //# sourceMappingURL=profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/lib/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,QAAA,MAAM,eAAe,QAAgD,CAAC;AACtE,QAAA,MAAM,YAAY,QAAuC,CAAC;AAC1D,QAAA,MAAM,mBAAmB,QAA6C,CAAC;AACvE,QAAA,MAAM,eAAe,QAAmC,CAAC;AAKzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoDD,uCAAuC;AACvC,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAOvC;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAWhD;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAwBlF;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAS7C;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBhD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,GAAG,IAAI,CAgC3D;AAGD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}