@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
@@ -1,21 +1,143 @@
1
1
  /**
2
2
  * CLI config — reads PRODUCTBRAIN_API_KEY + CONVEX_SITE_URL from:
3
- * 1. Environment variables
4
- * 2. ~/.config/productbrain/.env (works from any directory)
5
- * 3. CWD .env.mcp / packages/mcp-server/.env.mcp / .env
3
+ * 1. Environment variables (always highest priority)
4
+ * 2. Project config: .productbrain/config.json in CWD (WP-303 S0)
5
+ * 3. Profile system (~/.config/productbrain/profiles/{name}.env)
6
+ * 4. Legacy ~/.config/productbrain/.env (auto-migrated to profiles on first use)
7
+ * 5. CWD .env.mcp / packages/mcp-server/.env.mcp / .env
8
+ *
9
+ * Config loading is lazy — loadEnv() runs on first getConfig()/getConfigOrGuide() call.
10
+ * This enables profile switching without import-time side effects (TEN-1276).
6
11
  *
7
12
  * When key is missing and retry is provided (TTY), runs guided flow per docs/cli-unauthenticated-user-journey.md.
8
13
  */
9
14
  import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'fs';
10
15
  import { resolve } from 'path';
11
16
  import { homedir } from 'os';
12
- import { createInterface } from 'readline';
13
17
  import { DEFAULT_SITE_URL, isDevMode } from './constants.js';
18
+ import { resolveProfileConfig } from './profiles.js';
19
+ import { CLIError, ErrorCode } from './errors.js';
20
+ import { confirm as promptConfirm, password as promptPassword } from './prompts.js';
14
21
  const HOME_CONFIG_DIR = resolve(homedir(), '.config', 'productbrain');
15
22
  const HOME_ENV_PATH = resolve(HOME_CONFIG_DIR, '.env');
16
23
  const CWD_ENV_PATHS = ['.env.mcp', 'packages/mcp-server/.env.mcp', '.env'];
17
24
  // Short error when not TTY (scripts/pipes must not hang)
18
25
  const NON_TTY_MESSAGE = 'No API key. Set PRODUCTBRAIN_API_KEY or run pb login.';
26
+ /** Track whether env has been loaded to avoid redundant file reads. */
27
+ let envLoaded = false;
28
+ /**
29
+ * Read .productbrain/config.json from CWD.
30
+ * Returns null if file missing. Warns to stderr on invalid JSON but does not throw.
31
+ */
32
+ function readProjectConfig() {
33
+ const configPath = resolve(process.cwd(), '.productbrain', 'config.json');
34
+ if (!existsSync(configPath))
35
+ return null;
36
+ try {
37
+ const raw = readFileSync(configPath, 'utf8');
38
+ const parsed = JSON.parse(raw);
39
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
40
+ process.stderr.write('Warning: .productbrain/config.json is not a JSON object, skipping.\n');
41
+ return null;
42
+ }
43
+ const result = {};
44
+ if (typeof parsed.apiKey === 'string' && parsed.apiKey) {
45
+ result.apiKey = parsed.apiKey;
46
+ }
47
+ if (typeof parsed.siteUrl === 'string' && parsed.siteUrl) {
48
+ result.siteUrl = parsed.siteUrl;
49
+ }
50
+ return result;
51
+ }
52
+ catch {
53
+ process.stderr.write('Warning: .productbrain/config.json contains invalid JSON, skipping.\n');
54
+ return null;
55
+ }
56
+ }
57
+ /**
58
+ * Run the full config resolution cascade and return a typed result.
59
+ * Resolution order:
60
+ * 1. Environment variables (highest priority)
61
+ * 2. Project config (.productbrain/config.json in CWD)
62
+ * 3. Profile system (~/.config/productbrain/profiles/{name}.env)
63
+ * 4. Legacy home config (~/.config/productbrain/.env)
64
+ * 5. CWD .env files (.env.mcp, packages/mcp-server/.env.mcp, .env)
65
+ *
66
+ * siteUrl always has a value (falls back to DEFAULT_SITE_URL).
67
+ */
68
+ export function resolveConfig() {
69
+ // 1. Env vars — check directly, don't mutate process.env
70
+ const envKey = process.env.PRODUCTBRAIN_API_KEY;
71
+ const envSite = process.env.CONVEX_SITE_URL;
72
+ if (envKey) {
73
+ return {
74
+ apiKey: envKey,
75
+ siteUrl: (envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
76
+ source: 'env',
77
+ };
78
+ }
79
+ // 2. Project config
80
+ const projectConfig = readProjectConfig();
81
+ if (projectConfig?.apiKey) {
82
+ return {
83
+ apiKey: projectConfig.apiKey,
84
+ siteUrl: (projectConfig.siteUrl || envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
85
+ source: 'project',
86
+ };
87
+ }
88
+ // 3. Profile system
89
+ const profileConfig = resolveProfileConfig();
90
+ if (profileConfig?.apiKey) {
91
+ return {
92
+ apiKey: profileConfig.apiKey,
93
+ siteUrl: (profileConfig.siteUrl || envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
94
+ source: 'profile',
95
+ };
96
+ }
97
+ // 4. Legacy home config
98
+ if (existsSync(HOME_ENV_PATH)) {
99
+ const vars = parseEnvVars(readFileSync(HOME_ENV_PATH, 'utf8'));
100
+ if (vars['PRODUCTBRAIN_API_KEY']) {
101
+ return {
102
+ apiKey: vars['PRODUCTBRAIN_API_KEY'],
103
+ siteUrl: (vars['CONVEX_SITE_URL'] || envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
104
+ source: 'profile',
105
+ };
106
+ }
107
+ }
108
+ // 5. CWD .env files
109
+ for (const p of CWD_ENV_PATHS) {
110
+ const full = resolve(process.cwd(), p);
111
+ if (existsSync(full)) {
112
+ const vars = parseEnvVars(readFileSync(full, 'utf8'));
113
+ if (vars['PRODUCTBRAIN_API_KEY']) {
114
+ return {
115
+ apiKey: vars['PRODUCTBRAIN_API_KEY'],
116
+ siteUrl: (vars['CONVEX_SITE_URL'] || envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
117
+ source: 'cwd',
118
+ };
119
+ }
120
+ break;
121
+ }
122
+ }
123
+ // 6. No API key found anywhere — return with siteUrl default
124
+ return {
125
+ apiKey: undefined,
126
+ siteUrl: (envSite || DEFAULT_SITE_URL).replace(/\/$/, ''),
127
+ source: 'default',
128
+ };
129
+ }
130
+ /** Parse env file content and return key-value pairs (without mutating process.env). */
131
+ function parseEnvVars(content) {
132
+ const vars = {};
133
+ for (const line of content.split('\n')) {
134
+ const m = line.match(/^([^#=]+)=(.*)$/);
135
+ if (m) {
136
+ vars[m[1].trim()] = m[2].trim().replace(/^["']|["']$/g, '');
137
+ }
138
+ }
139
+ return vars;
140
+ }
19
141
  function parseEnvContent(content) {
20
142
  for (const line of content.split('\n')) {
21
143
  const m = line.match(/^([^#=]+)=(.*)$/);
@@ -25,9 +147,35 @@ function parseEnvContent(content) {
25
147
  }
26
148
  }
27
149
  function loadEnv() {
150
+ if (envLoaded)
151
+ return;
152
+ envLoaded = true;
153
+ // 1. Try project config first (WP-303 S0)
154
+ const projectConfig = readProjectConfig();
155
+ if (projectConfig) {
156
+ if (!process.env.PRODUCTBRAIN_API_KEY && projectConfig.apiKey) {
157
+ process.env.PRODUCTBRAIN_API_KEY = projectConfig.apiKey;
158
+ }
159
+ if (!process.env.CONVEX_SITE_URL && projectConfig.siteUrl) {
160
+ process.env.CONVEX_SITE_URL = projectConfig.siteUrl;
161
+ }
162
+ }
163
+ // 2. Try profile system (handles auto-migration from legacy .env)
164
+ const profileConfig = resolveProfileConfig();
165
+ if (profileConfig) {
166
+ // Only set if not already set by env vars or project config
167
+ if (!process.env.PRODUCTBRAIN_API_KEY) {
168
+ process.env.PRODUCTBRAIN_API_KEY = profileConfig.apiKey;
169
+ }
170
+ if (!process.env.CONVEX_SITE_URL && profileConfig.siteUrl) {
171
+ process.env.CONVEX_SITE_URL = profileConfig.siteUrl;
172
+ }
173
+ }
174
+ // 3. Legacy home config (in case profiles didn't find it)
28
175
  if (existsSync(HOME_ENV_PATH)) {
29
176
  parseEnvContent(readFileSync(HOME_ENV_PATH, 'utf8'));
30
177
  }
178
+ // 4. CWD env files
31
179
  for (const p of CWD_ENV_PATHS) {
32
180
  const full = resolve(process.cwd(), p);
33
181
  if (existsSync(full)) {
@@ -36,49 +184,55 @@ function loadEnv() {
36
184
  }
37
185
  }
38
186
  }
39
- loadEnv();
40
- function question(rl, prompt) {
41
- return new Promise((resolve) => {
42
- rl.question(prompt, (answer) => resolve((answer ?? '').trim().toLowerCase()));
43
- });
44
- }
45
- function questionRaw(rl, prompt) {
46
- return new Promise((resolve) => {
47
- rl.question(prompt, (answer) => resolve((answer ?? '').trim()));
48
- });
187
+ /** Reset env loaded state — used for profile switching. */
188
+ export function resetConfigCache() {
189
+ envLoaded = false;
49
190
  }
50
191
  /**
51
192
  * Guided flow when key is missing (TTY only). Per docs/cli-unauthenticated-user-journey.md.
52
193
  * Returns true if we saved and ran retry; false if user said No (caller should exit).
53
194
  */
54
195
  async function runGuidedFlow(retry) {
55
- const rl = createInterface({ input: process.stdin, output: process.stdout });
56
- console.log('Do you have an API key from Product Brain? (y/n)');
57
- console.log(' Get one: Product Brain app → Settings → API Keys');
58
- const hasKey = await question(rl, '> ');
59
- if (hasKey !== 'y' && hasKey !== 'yes') {
196
+ const hasKey = await promptConfirm({
197
+ message: 'Do you have an API key from Product Brain?',
198
+ initialValue: false,
199
+ });
200
+ if (!hasKey) {
60
201
  console.log('Get your key: Product Brain app → Settings → API Keys. Then run: pb login');
61
- rl.close();
62
202
  process.exit(0);
63
203
  }
64
- let apiKey = await questionRaw(rl, 'Paste your API key (pb_sk_...): ');
65
- if (!apiKey || !apiKey.startsWith('pb_sk_')) {
204
+ let apiKey = await promptPassword({
205
+ message: 'Paste your API key (pb_sk_...)',
206
+ validate: (v) => (!v ? 'Key is required' : undefined),
207
+ });
208
+ if (!apiKey.startsWith('pb_sk_')) {
66
209
  console.log('Key must start with pb_sk_. Try again or run pb login.');
67
- apiKey = await questionRaw(rl, 'Paste your API key (pb_sk_...): ');
210
+ apiKey = await promptPassword({
211
+ message: 'Paste your API key (pb_sk_...)',
212
+ validate: (v) => (!v || !v.startsWith('pb_sk_') ? 'Key must start with pb_sk_' : undefined),
213
+ });
68
214
  }
69
- rl.close();
70
215
  if (!apiKey || !apiKey.startsWith('pb_sk_')) {
71
216
  console.log('Get your key: Product Brain app → Settings → API Keys. Then run: pb login');
72
217
  process.exit(0);
73
218
  }
74
- const content = [
75
- `# Product Brain CLI saved by guided setup`,
76
- `PRODUCTBRAIN_API_KEY=${apiKey}`,
77
- `CONVEX_SITE_URL=${DEFAULT_SITE_URL.replace(/\/$/, '')}`,
78
- '',
79
- ].join('\n');
80
- mkdirSync(HOME_CONFIG_DIR, { recursive: true });
81
- writeFileSync(HOME_ENV_PATH, content, { mode: 0o600 });
219
+ // Save as a named profile via the profile system
220
+ const { createProfile, getActiveProfile } = await import('./profiles.js');
221
+ const profileName = getActiveProfile() || 'default';
222
+ try {
223
+ createProfile(profileName, apiKey, DEFAULT_SITE_URL.replace(/\/$/, ''));
224
+ }
225
+ catch {
226
+ // Profile already exists fall back to legacy path
227
+ const content = [
228
+ `# Product Brain CLI — saved by guided setup`,
229
+ `PRODUCTBRAIN_API_KEY=${apiKey}`,
230
+ `CONVEX_SITE_URL=${DEFAULT_SITE_URL.replace(/\/$/, '')}`,
231
+ '',
232
+ ].join('\n');
233
+ mkdirSync(HOME_CONFIG_DIR, { recursive: true });
234
+ writeFileSync(HOME_ENV_PATH, content, { mode: 0o600 });
235
+ }
82
236
  process.env.PRODUCTBRAIN_API_KEY = apiKey;
83
237
  process.env.CONVEX_SITE_URL = DEFAULT_SITE_URL.replace(/\/$/, '');
84
238
  console.log('Saved your key. Running your command…\n');
@@ -86,23 +240,59 @@ async function runGuidedFlow(retry) {
86
240
  return true;
87
241
  }
88
242
  export function getConfig() {
243
+ loadEnv();
89
244
  const apiKey = process.env.PRODUCTBRAIN_API_KEY ?? '';
90
245
  const siteUrl = (process.env.CONVEX_SITE_URL ?? DEFAULT_SITE_URL).replace(/\/$/, '');
91
246
  if (!apiKey || !apiKey.startsWith('pb_sk_')) {
92
- throw new Error(NON_TTY_MESSAGE);
247
+ throw new CLIError(NON_TTY_MESSAGE, {
248
+ code: ErrorCode.AUTH_MISSING,
249
+ category: 'auth',
250
+ guidance: 'Set PRODUCTBRAIN_API_KEY or run `pb login`.',
251
+ });
93
252
  }
94
253
  const allowHttp = isDevMode() && siteUrl.startsWith('http://localhost');
95
254
  if (!siteUrl.startsWith('https://') && !allowHttp) {
96
- throw new Error(`CONVEX_SITE_URL must use HTTPS (got "${siteUrl.slice(0, 30)}…"). API keys must not be sent over unencrypted connections.`);
255
+ throw new CLIError(`CONVEX_SITE_URL must use HTTPS (got "${siteUrl.slice(0, 30)}…"). API keys must not be sent over unencrypted connections.`, {
256
+ code: ErrorCode.CONFIG_INVALID,
257
+ category: 'config',
258
+ guidance: 'Set CONVEX_SITE_URL to an https:// URL.',
259
+ });
97
260
  }
98
261
  return { apiKey, siteUrl };
99
262
  }
263
+ /**
264
+ * Non-throwing alternative to getConfig().
265
+ *
266
+ * Architecture: getConfig() is the primary path for commands that require auth — it
267
+ * throws CLIError when the key is missing, which is correct for API call paths.
268
+ * getConfigSafe() is for status/probe surfaces (no-args dashboard, init) that need
269
+ * to check config availability without crashing. Both paths are intentional and
270
+ * coexist by design — see WP-303 review (DW#5).
271
+ *
272
+ * Uses resolveConfig() directly (no loadEnv) to avoid env var pollution affecting source attribution.
273
+ */
274
+ export function getConfigSafe() {
275
+ const resolved = resolveConfig();
276
+ if (!resolved.apiKey || !resolved.apiKey.startsWith('pb_sk_')) {
277
+ return { ok: false, reason: 'No API key. Run pb login or set PRODUCTBRAIN_API_KEY.' };
278
+ }
279
+ const siteUrl = resolved.siteUrl;
280
+ const allowHttp = isDevMode() && siteUrl.startsWith('http://localhost');
281
+ if (!siteUrl.startsWith('https://') && !allowHttp) {
282
+ return {
283
+ ok: false,
284
+ reason: `CONVEX_SITE_URL must use HTTPS (got "${siteUrl.slice(0, 30)}…"). API keys must not be sent over unencrypted connections.`,
285
+ };
286
+ }
287
+ return { ok: true, apiKey: resolved.apiKey, siteUrl, source: resolved.source };
288
+ }
100
289
  /**
101
290
  * Get config; if key is missing and stdin is a TTY, run guided flow (y/n → paste key → save → retry).
102
291
  * @param retry Called after saving key so the original command runs in-process.
103
292
  * @returns Config, or null if we ran retry (caller should return without running again).
104
293
  */
105
294
  export async function getConfigOrGuide(retry) {
295
+ loadEnv();
106
296
  const apiKey = process.env.PRODUCTBRAIN_API_KEY ?? '';
107
297
  const siteUrl = (process.env.CONVEX_SITE_URL ?? DEFAULT_SITE_URL).replace(/\/$/, '');
108
298
  const allowHttp = isDevMode() && siteUrl.startsWith('http://localhost');
@@ -110,10 +300,14 @@ export async function getConfigOrGuide(retry) {
110
300
  return { apiKey, siteUrl };
111
301
  }
112
302
  if (!process.stdin.isTTY) {
113
- throw new Error(NON_TTY_MESSAGE);
303
+ throw new CLIError(NON_TTY_MESSAGE, {
304
+ code: ErrorCode.AUTH_MISSING,
305
+ category: 'auth',
306
+ guidance: 'Set PRODUCTBRAIN_API_KEY or run `pb login`.',
307
+ });
114
308
  }
115
309
  const didRetry = await runGuidedFlow(retry);
116
310
  return didRetry ? null : null;
117
311
  }
118
- export { HOME_CONFIG_DIR, HOME_ENV_PATH };
312
+ export { HOME_CONFIG_DIR, HOME_ENV_PATH, readProjectConfig };
119
313
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;AACtE,MAAM,aAAa,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AAEvD,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,8BAA8B,EAAE,MAAM,CAAC,CAAC;AAE3E,yDAAyD;AACzD,MAAM,eAAe,GAAG,uDAAuD,CAAC;AAEhF,SAAS,eAAe,CAAC,OAAe;IACtC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,OAAO;IACd,IAAI,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9B,eAAe,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACvC,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,eAAe,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;YAC5C,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC;AAED,OAAO,EAAE,CAAC;AAEV,SAAS,QAAQ,CAAC,EAAsC,EAAE,MAAc;IACtE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,EAAsC,EAAE,MAAc;IACzE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,aAAa,CAAC,KAA0B;IACrD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7E,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;IAChE,OAAO,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAExC,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACvC,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;QACzF,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,kCAAkC,CAAC,CAAC;IACvE,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;QACtE,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,kCAAkC,CAAC,CAAC;IACrE,CAAC;IAED,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,2EAA2E,CAAC,CAAC;QACzF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG;QACd,6CAA6C;QAC7C,wBAAwB,MAAM,EAAE;QAChC,mBAAmB,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE;QACxD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,aAAa,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEvD,OAAO,CAAC,GAAG,CAAC,oBAAoB,GAAG,MAAM,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,gBAAgB,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,MAAM,KAAK,EAAE,CAAC;IACd,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAErF,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,SAAS,GAAG,SAAS,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACxE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,wCAAwC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,8DAA8D,CAC3H,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC7B,CAAC;AAID;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAA0B;IAC/D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,EAAE,CAAC;IACtD,MAAM,OAAO,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,gBAAgB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAErF,MAAM,SAAS,GAAG,SAAS,EAAE,IAAI,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,EAAE,CAAC;QACjF,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAChC,CAAC;AAED,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  * WP-301 Slice 0: Extract hardcoded URLs, add PB_ENV awareness.
4
4
  */
5
5
  /** Production Convex HTTP Actions endpoint. */
6
- export declare const DEFAULT_SITE_URL = "https://trustworthy-kangaroo-277.convex.site";
6
+ export declare const DEFAULT_SITE_URL = "https://gateway.productbrain.io";
7
7
  /**
8
8
  * Resolve the Convex site URL based on PB_ENV.
9
9
  * - PB_ENV=dev → local Convex dev server
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,iDAAiD,CAAC;AAW/E;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,oCAAoC,CAAC;AAWlE;;;;GAIG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAIvC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAItC;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,IAAI,OAAO,CAEnC"}
@@ -3,7 +3,7 @@
3
3
  * WP-301 Slice 0: Extract hardcoded URLs, add PB_ENV awareness.
4
4
  */
5
5
  /** Production Convex HTTP Actions endpoint. */
6
- export const DEFAULT_SITE_URL = 'https://trustworthy-kangaroo-277.convex.site';
6
+ export const DEFAULT_SITE_URL = 'https://gateway.productbrain.io';
7
7
  /** Production web app URL. */
8
8
  const PROD_APP_URL = 'https://work.productbrain.io';
9
9
  /** Local Convex dev server URL. */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,8CAA8C,CAAC;AAE/E,8BAA8B;AAC9B,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD,mCAAmC;AACnC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,yBAAyB;AACzB,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAC9C,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,YAAY,CAAC;IACvC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAC9C,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,WAAW,CAAC;IACtC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,KAAK,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,iCAAiC,CAAC;AAElE,8BAA8B;AAC9B,MAAM,YAAY,GAAG,8BAA8B,CAAC;AAEpD,mCAAmC;AACnC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,yBAAyB;AACzB,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAC9C,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,YAAY,CAAC;IACvC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAC9C,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,WAAW,CAAC;IACtC,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,KAAK,CAAC;AACrD,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * CLIError — structured error taxonomy for the Product Brain CLI.
3
+ *
4
+ * WP-302 Slice 0: Error Taxonomy + Commander Migration.
5
+ * WP-302 Slice 2: Profile error codes added.
6
+ * Every CLI error carries a machine-readable code, category, and actionable guidance.
7
+ * The global error handler in index.ts formats these for JSON or human output.
8
+ */
9
+ /** Error categories — groups of related failure modes. */
10
+ export type ErrorCategory = 'auth' | 'network' | 'config' | 'validation' | 'session' | 'profile' | 'internal';
11
+ /** Known error codes — extend as new failure modes are discovered. */
12
+ export declare const ErrorCode: {
13
+ readonly AUTH_MISSING: "AUTH_MISSING";
14
+ readonly AUTH_INVALID: "AUTH_INVALID";
15
+ readonly AUTH_DENIED: "AUTH_DENIED";
16
+ readonly NETWORK_UNREACHABLE: "NETWORK_UNREACHABLE";
17
+ readonly NETWORK_TIMEOUT: "NETWORK_TIMEOUT";
18
+ readonly CONFIG_MISSING: "CONFIG_MISSING";
19
+ readonly CONFIG_INVALID: "CONFIG_INVALID";
20
+ readonly SESSION_REQUIRED: "SESSION_REQUIRED";
21
+ readonly VALIDATION_FAILED: "VALIDATION_FAILED";
22
+ readonly PROFILE_NOT_FOUND: "PROFILE_NOT_FOUND";
23
+ readonly PROFILE_ALREADY_EXISTS: "PROFILE_ALREADY_EXISTS";
24
+ readonly PROFILE_IS_ACTIVE: "PROFILE_IS_ACTIVE";
25
+ readonly PROFILE_IS_LAST: "PROFILE_IS_LAST";
26
+ readonly PROFILE_NAME_INVALID: "PROFILE_NAME_INVALID";
27
+ readonly NON_INTERACTIVE: "NON_INTERACTIVE";
28
+ readonly INTERNAL: "INTERNAL";
29
+ };
30
+ export type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
31
+ /**
32
+ * Structured CLI error with machine-readable fields.
33
+ *
34
+ * Usage:
35
+ * throw new CLIError('No API key configured', {
36
+ * code: ErrorCode.AUTH_MISSING,
37
+ * category: 'auth',
38
+ * guidance: 'Run `pb login` to configure your API key.',
39
+ * });
40
+ */
41
+ export declare class CLIError extends Error {
42
+ readonly code: ErrorCodeValue;
43
+ readonly category: ErrorCategory;
44
+ readonly guidance?: string;
45
+ constructor(message: string, options?: {
46
+ code?: ErrorCodeValue;
47
+ category?: ErrorCategory;
48
+ guidance?: string;
49
+ });
50
+ /** Serialize for JSON error output. */
51
+ toJSON(): {
52
+ error: string;
53
+ code: string;
54
+ category: string;
55
+ guidance?: string;
56
+ };
57
+ }
58
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,0DAA0D;AAC1D,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE9G,sEAAsE;AACtE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;CAyBZ,CAAC;AAEX,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAExE;;;;;;;;;GASG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;gBAGzB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,IAAI,CAAC,EAAE,cAAc,CAAC;QACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IASH,uCAAuC;IACvC,MAAM,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;CAQ/E"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * CLIError — structured error taxonomy for the Product Brain CLI.
3
+ *
4
+ * WP-302 Slice 0: Error Taxonomy + Commander Migration.
5
+ * WP-302 Slice 2: Profile error codes added.
6
+ * Every CLI error carries a machine-readable code, category, and actionable guidance.
7
+ * The global error handler in index.ts formats these for JSON or human output.
8
+ */
9
+ /** Known error codes — extend as new failure modes are discovered. */
10
+ export const ErrorCode = {
11
+ // Auth
12
+ AUTH_MISSING: 'AUTH_MISSING',
13
+ AUTH_INVALID: 'AUTH_INVALID',
14
+ AUTH_DENIED: 'AUTH_DENIED',
15
+ // Network
16
+ NETWORK_UNREACHABLE: 'NETWORK_UNREACHABLE',
17
+ NETWORK_TIMEOUT: 'NETWORK_TIMEOUT',
18
+ // Config
19
+ CONFIG_MISSING: 'CONFIG_MISSING',
20
+ CONFIG_INVALID: 'CONFIG_INVALID',
21
+ // Session
22
+ SESSION_REQUIRED: 'SESSION_REQUIRED',
23
+ // Validation
24
+ VALIDATION_FAILED: 'VALIDATION_FAILED',
25
+ // Profile (WP-302 S2)
26
+ PROFILE_NOT_FOUND: 'PROFILE_NOT_FOUND',
27
+ PROFILE_ALREADY_EXISTS: 'PROFILE_ALREADY_EXISTS',
28
+ PROFILE_IS_ACTIVE: 'PROFILE_IS_ACTIVE',
29
+ PROFILE_IS_LAST: 'PROFILE_IS_LAST',
30
+ PROFILE_NAME_INVALID: 'PROFILE_NAME_INVALID',
31
+ // Interactive
32
+ NON_INTERACTIVE: 'NON_INTERACTIVE',
33
+ // Internal
34
+ INTERNAL: 'INTERNAL',
35
+ };
36
+ /**
37
+ * Structured CLI error with machine-readable fields.
38
+ *
39
+ * Usage:
40
+ * throw new CLIError('No API key configured', {
41
+ * code: ErrorCode.AUTH_MISSING,
42
+ * category: 'auth',
43
+ * guidance: 'Run `pb login` to configure your API key.',
44
+ * });
45
+ */
46
+ export class CLIError extends Error {
47
+ code;
48
+ category;
49
+ guidance;
50
+ constructor(message, options) {
51
+ super(message);
52
+ this.name = 'CLIError';
53
+ this.code = options?.code ?? ErrorCode.INTERNAL;
54
+ this.category = options?.category ?? 'internal';
55
+ this.guidance = options?.guidance;
56
+ }
57
+ /** Serialize for JSON error output. */
58
+ toJSON() {
59
+ return {
60
+ error: this.message,
61
+ code: this.code,
62
+ category: this.category,
63
+ ...(this.guidance ? { guidance: this.guidance } : {}),
64
+ };
65
+ }
66
+ }
67
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,OAAO;IACP,YAAY,EAAE,cAAc;IAC5B,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,UAAU;IACV,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,SAAS;IACT,cAAc,EAAE,gBAAgB;IAChC,cAAc,EAAE,gBAAgB;IAChC,UAAU;IACV,gBAAgB,EAAE,kBAAkB;IACpC,aAAa;IACb,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB;IACtB,iBAAiB,EAAE,mBAAmB;IACtC,sBAAsB,EAAE,wBAAwB;IAChD,iBAAiB,EAAE,mBAAmB;IACtC,eAAe,EAAE,iBAAiB;IAClC,oBAAoB,EAAE,sBAAsB;IAC5C,cAAc;IACd,eAAe,EAAE,iBAAiB;IAClC,WAAW;IACX,QAAQ,EAAE,UAAU;CACZ,CAAC;AAIX;;;;;;;;;GASG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAiB;IACrB,QAAQ,CAAgB;IACxB,QAAQ,CAAU;IAE3B,YACE,OAAe,EACf,OAIC;QAED,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,SAAS,CAAC,QAAQ,CAAC;QAChD,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,UAAU,CAAC;QAChD,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC;IACpC,CAAC;IAED,uCAAuC;IACvC,MAAM;QACJ,OAAO;YACL,KAAK,EAAE,IAAI,CAAC,OAAO;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shared formatting utilities for the CLI.
3
+ * Single source of truth for display helpers used across commands.
4
+ */
5
+ /**
6
+ * Format an ISO timestamp into a human-friendly elapsed string.
7
+ * e.g. "just now", "5m ago", "3h ago", "2d ago"
8
+ */
9
+ export declare function formatElapsed(isoDate: string): string;
10
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAarD"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Shared formatting utilities for the CLI.
3
+ * Single source of truth for display helpers used across commands.
4
+ */
5
+ /**
6
+ * Format an ISO timestamp into a human-friendly elapsed string.
7
+ * e.g. "just now", "5m ago", "3h ago", "2d ago"
8
+ */
9
+ export function formatElapsed(isoDate) {
10
+ try {
11
+ const ms = Date.now() - new Date(isoDate).getTime();
12
+ const minutes = Math.floor(ms / 60000);
13
+ if (minutes < 1)
14
+ return 'just now';
15
+ if (minutes < 60)
16
+ return `${minutes}m ago`;
17
+ const hours = Math.floor(minutes / 60);
18
+ if (hours < 24)
19
+ return `${hours}h ago`;
20
+ const days = Math.floor(hours / 24);
21
+ return `${days}d ago`;
22
+ }
23
+ catch {
24
+ return 'unknown';
25
+ }
26
+ }
27
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/lib/format.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;QACvC,IAAI,OAAO,GAAG,CAAC;YAAE,OAAO,UAAU,CAAC;QACnC,IAAI,OAAO,GAAG,EAAE;YAAE,OAAO,GAAG,OAAO,OAAO,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;QACvC,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,GAAG,KAAK,OAAO,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;QACpC,OAAO,GAAG,IAAI,OAAO,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
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
+ export interface GlossaryEntry {
10
+ term: string;
11
+ definition: string;
12
+ }
13
+ export declare const GLOSSARY: GlossaryEntry[];
14
+ /**
15
+ * Format the glossary for TTY output.
16
+ * Returns a multi-line string with bold terms and dimmed definitions.
17
+ */
18
+ export declare function formatGlossary(): string;
19
+ //# sourceMappingURL=glossary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glossary.d.ts","sourceRoot":"","sources":["../../src/lib/glossary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,QAAQ,EAAE,aAAa,EA6BnC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAUvC"}