@productbrain/cli 0.1.0-beta.4809 → 0.1.0-beta.4818

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 (53) hide show
  1. package/dist/__tests__/config-prod-fallthrough.test.js +23 -12
  2. package/dist/__tests__/config-prod-fallthrough.test.js.map +1 -1
  3. package/dist/__tests__/config.test.js +343 -11
  4. package/dist/__tests__/config.test.js.map +1 -1
  5. package/dist/__tests__/init.test.js +51 -14
  6. package/dist/__tests__/init.test.js.map +1 -1
  7. package/dist/__tests__/state.test.js +21 -1
  8. package/dist/__tests__/state.test.js.map +1 -1
  9. package/dist/commands/__tests__/setup-state.test.js +1 -1
  10. package/dist/commands/__tests__/setup-state.test.js.map +1 -1
  11. package/dist/commands/doctor.d.ts.map +1 -1
  12. package/dist/commands/doctor.js +101 -35
  13. package/dist/commands/doctor.js.map +1 -1
  14. package/dist/commands/doctor.test.js +182 -6
  15. package/dist/commands/doctor.test.js.map +1 -1
  16. package/dist/commands/init.d.ts +1 -1
  17. package/dist/commands/init.d.ts.map +1 -1
  18. package/dist/commands/init.js +20 -9
  19. package/dist/commands/init.js.map +1 -1
  20. package/dist/commands/status.d.ts +7 -0
  21. package/dist/commands/status.d.ts.map +1 -0
  22. package/dist/commands/status.js +102 -0
  23. package/dist/commands/status.js.map +1 -0
  24. package/dist/commands/status.test.d.ts +2 -0
  25. package/dist/commands/status.test.d.ts.map +1 -0
  26. package/dist/commands/status.test.js +75 -0
  27. package/dist/commands/status.test.js.map +1 -0
  28. package/dist/commands/welcome.d.ts.map +1 -1
  29. package/dist/commands/welcome.js +5 -2
  30. package/dist/commands/welcome.js.map +1 -1
  31. package/dist/index.js +3 -112
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/config.d.ts +9 -22
  34. package/dist/lib/config.d.ts.map +1 -1
  35. package/dist/lib/config.js +37 -99
  36. package/dist/lib/config.js.map +1 -1
  37. package/dist/lib/configResult.d.ts +80 -0
  38. package/dist/lib/configResult.d.ts.map +1 -0
  39. package/dist/lib/configResult.js +176 -0
  40. package/dist/lib/configResult.js.map +1 -0
  41. package/dist/lib/localBinding.d.ts +51 -0
  42. package/dist/lib/localBinding.d.ts.map +1 -0
  43. package/dist/lib/localBinding.js +90 -0
  44. package/dist/lib/localBinding.js.map +1 -0
  45. package/dist/lib/projectConfig.d.ts +6 -0
  46. package/dist/lib/projectConfig.d.ts.map +1 -1
  47. package/dist/lib/projectConfig.js +14 -2
  48. package/dist/lib/projectConfig.js.map +1 -1
  49. package/dist/lib/state.d.ts +7 -0
  50. package/dist/lib/state.d.ts.map +1 -1
  51. package/dist/lib/state.js +7 -2
  52. package/dist/lib/state.js.map +1 -1
  53. package/package.json +1 -1
@@ -0,0 +1,80 @@
1
+ /** Structured, non-throwing view of the CLI configuration cascade. */
2
+ import { CLIError, type ErrorCategory, type ErrorCodeValue } from './errors.js';
3
+ export type ConfigSource = 'env' | 'project' | 'profile' | 'cwd' | 'default';
4
+ /**
5
+ * Where the resolved `siteUrl` came from — tracked SEPARATELY from `ConfigSource`.
6
+ *
7
+ * The credential and the gateway are picked by two different fallback chains: almost every
8
+ * credential branch prefers `.productbrain/config.json`'s siteUrl over its own. So a result
9
+ * labelled `profile`/`cwd` can be carrying a URL that came from config.json, and naming the
10
+ * credential's source in a URL repair would send the operator to edit a file that does not
11
+ * control the failing URL.
12
+ */
13
+ export type SiteUrlSource = 'env' | 'local-binding' | 'profile-pin' | 'project-config' | 'profile' | 'legacy' | 'cwd' | 'default';
14
+ export interface ResolvedConfig {
15
+ apiKey?: string;
16
+ siteUrl: string;
17
+ source: ConfigSource;
18
+ /**
19
+ * Which candidate supplied `siteUrl`. Optional because a caller may construct a
20
+ * ResolvedConfig without observing the cascade; diagnostics must then name NO source
21
+ * rather than guess one.
22
+ */
23
+ siteUrlSource?: SiteUrlSource;
24
+ /**
25
+ * The concrete file a source resolved to, where the source alone is ambiguous — `cwd` covers
26
+ * three different candidate paths, so naming the generic one would point the operator at a
27
+ * file that is not the one being read.
28
+ */
29
+ siteUrlDetail?: string;
30
+ /**
31
+ * Which named profile supplied a `profile`-sourced credential or URL. Absent when the profile
32
+ * cascade landed on the nameless legacy `~/.config/productbrain/.env`, so diagnostics can name
33
+ * the profile that actually won instead of an "active profile" that may not be the one read.
34
+ */
35
+ profileName?: string;
36
+ }
37
+ /**
38
+ * Pick the first present siteUrl candidate and record which one won, so the URL and its
39
+ * reported origin are produced by one expression and cannot disagree. Candidates are given
40
+ * in the caller's existing precedence order; `DEFAULT_SITE_URL` closes every chain.
41
+ */
42
+ export declare function pickSiteUrl(candidates: ReadonlyArray<readonly [SiteUrlSource, string | undefined, string?]>): {
43
+ siteUrl: string;
44
+ siteUrlSource: SiteUrlSource;
45
+ siteUrlDetail?: string;
46
+ };
47
+ export type ConfigFailureKind = 'missing-key' | 'invalid-key' | 'profile-pin' | 'preview-binding' | 'invalid-url' | 'unknown';
48
+ export type ConfigResult = {
49
+ ok: true;
50
+ apiKey: string;
51
+ siteUrl: string;
52
+ source: ConfigSource;
53
+ } | {
54
+ ok: false;
55
+ kind: ConfigFailureKind;
56
+ reason: string;
57
+ guidance: string;
58
+ nextCommand: string;
59
+ };
60
+ /**
61
+ * The transport-security bar every cascade enforces: HTTPS, or http://localhost while in dev mode.
62
+ * Both the structured result below and `getConfigOrGuide()`'s throwing path read it from here so
63
+ * the two can never diverge on what counts as a safe gateway to send an API key to.
64
+ */
65
+ export declare function isInsecureSiteUrl(siteUrl: string): boolean;
66
+ /** A resolution refusal that diagnostic surfaces must preserve instead of relabelling. */
67
+ export declare class ConfigResolutionError extends CLIError {
68
+ readonly kind: ConfigFailureKind;
69
+ readonly nextCommand: string;
70
+ constructor(message: string, options: {
71
+ kind: ConfigFailureKind;
72
+ nextCommand: string;
73
+ code?: ErrorCodeValue;
74
+ category?: ErrorCategory;
75
+ guidance: string;
76
+ });
77
+ }
78
+ /** Convert a throwing resolution cascade into the single diagnostic contract. */
79
+ export declare function resolveConfigResult(resolveConfig: () => ResolvedConfig): ConfigResult;
80
+ //# sourceMappingURL=configResult.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configResult.d.ts","sourceRoot":"","sources":["../../src/lib/configResult.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAGtE,OAAO,EAAE,QAAQ,EAAa,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAG3F,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;AAE7E;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GACrB,KAAK,GACL,eAAe,GACf,aAAa,GACb,gBAAgB,GAChB,SAAS,GACT,QAAQ,GACR,KAAK,GACL,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,GAC/E;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,aAAa,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAK3E;AAED,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,aAAa,GACb,SAAS,CAAC;AAEd,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,CAAA;CAAE,GACnE;IACE,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AA2EN;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED,0FAA0F;AAC1F,qBAAa,qBAAsB,SAAQ,QAAQ;IACjD,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAG3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,IAAI,EAAE,iBAAiB,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,IAAI,CAAC,EAAE,cAAc,CAAC;QACtB,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,QAAQ,EAAE,MAAM,CAAC;KAClB;CAOJ;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,cAAc,GAAG,YAAY,CAqErF"}
@@ -0,0 +1,176 @@
1
+ /** Structured, non-throwing view of the CLI configuration cascade. */
2
+ import { DEFAULT_SITE_URL, isDevMode } from './constants.js';
3
+ import { CLIError } from './errors.js';
4
+ import { API_KEY_PREFIX } from './tokenConstants.js';
5
+ /**
6
+ * Pick the first present siteUrl candidate and record which one won, so the URL and its
7
+ * reported origin are produced by one expression and cannot disagree. Candidates are given
8
+ * in the caller's existing precedence order; `DEFAULT_SITE_URL` closes every chain.
9
+ */
10
+ export function pickSiteUrl(candidates) {
11
+ for (const [siteUrlSource, value, siteUrlDetail] of candidates) {
12
+ if (value)
13
+ return { siteUrl: value.replace(/\/$/, ''), siteUrlSource, siteUrlDetail };
14
+ }
15
+ return { siteUrl: DEFAULT_SITE_URL.replace(/\/$/, ''), siteUrlSource: 'default' };
16
+ }
17
+ /**
18
+ * What to call a `profile` source that has no name.
19
+ *
20
+ * `resolveProfileConfig()` reaches a credential four ways — `PB_PROFILE`, the active-profile
21
+ * marker, a `default` fallback, and the legacy `~/.config/productbrain/.env` — and `resolveConfig()`
22
+ * reports the legacy home file as `profile` too. Only the first three have a name, so a fixed
23
+ * "the active profile" label would claim the operator's active profile supplied a credential that
24
+ * came from `PB_PROFILE`, from `default`, or from a file that is not a profile at all.
25
+ */
26
+ const UNNAMED_PROFILE_ORIGIN = 'the stored profile configuration';
27
+ /** Name the profile that won, or fall back to the nameless label above. */
28
+ function describeProfileOrigin(profileName) {
29
+ return profileName ? `the profile "${profileName}"` : UNNAMED_PROFILE_ORIGIN;
30
+ }
31
+ /** The repo pin knows which profile it names, so say so rather than "the profile it pins". */
32
+ function describePinnedOrigin(profileName) {
33
+ return profileName
34
+ ? `the profile "${profileName}" pinned by .productbrain/config.local.json`
35
+ : 'the profile pinned by .productbrain/config.local.json';
36
+ }
37
+ /**
38
+ * The operator-facing name of each siteUrl origin.
39
+ *
40
+ * Only an environment API key outranks a file in the cascade, so every file-sourced URL keeps
41
+ * winning over `CONVEX_SITE_URL`. Telling every caller to set that variable would send the
42
+ * operator around the same failure again — the repair has to name the origin that actually won.
43
+ */
44
+ const SITE_URL_ORIGIN = {
45
+ env: 'the CONVEX_SITE_URL environment variable',
46
+ 'local-binding': '.productbrain/config.local.json',
47
+ 'profile-pin': 'the profile pinned by .productbrain/config.local.json',
48
+ 'project-config': '.productbrain/config.json',
49
+ profile: UNNAMED_PROFILE_ORIGIN,
50
+ legacy: 'the legacy config at ~/.config/productbrain/.env',
51
+ cwd: 'the .env file in this directory',
52
+ default: 'the built-in default',
53
+ };
54
+ /**
55
+ * Name the origin, preferring the concrete file or profile when the source covers several.
56
+ * `cwd` spans three candidate paths (`.env.mcp`, `packages/mcp-server/.env.mcp`, `.env`), so the
57
+ * generic label would send the operator to edit a file the cascade never read.
58
+ */
59
+ function describeSiteUrlOrigin(source, detail, profileName) {
60
+ if (detail)
61
+ return `${detail} in this directory`;
62
+ if (source === 'profile')
63
+ return describeProfileOrigin(profileName);
64
+ if (source === 'profile-pin')
65
+ return describePinnedOrigin(profileName);
66
+ return SITE_URL_ORIGIN[source];
67
+ }
68
+ /** The operator-facing name of each credential origin, for `invalid-key` messages. */
69
+ const API_KEY_ORIGIN = {
70
+ env: 'the PRODUCTBRAIN_API_KEY environment variable',
71
+ project: '.productbrain/config.local.json (or the profile it pins)',
72
+ profile: UNNAMED_PROFILE_ORIGIN,
73
+ cwd: 'the .env file in this directory',
74
+ default: 'the built-in default',
75
+ };
76
+ /**
77
+ * Name the credential's origin, preferring the profile that actually supplied it.
78
+ * `project` covers both the direct local binding (no profile) and the repo pin (which names one),
79
+ * so the pin is only claimed when a profile name is actually present.
80
+ */
81
+ function describeApiKeyOrigin(source, profileName) {
82
+ if (source === 'profile')
83
+ return describeProfileOrigin(profileName);
84
+ if (source === 'project' && profileName)
85
+ return describePinnedOrigin(profileName);
86
+ return API_KEY_ORIGIN[source];
87
+ }
88
+ /**
89
+ * The transport-security bar every cascade enforces: HTTPS, or http://localhost while in dev mode.
90
+ * Both the structured result below and `getConfigOrGuide()`'s throwing path read it from here so
91
+ * the two can never diverge on what counts as a safe gateway to send an API key to.
92
+ */
93
+ export function isInsecureSiteUrl(siteUrl) {
94
+ return !siteUrl.startsWith('https://') && !(isDevMode() && siteUrl.startsWith('http://localhost'));
95
+ }
96
+ /** A resolution refusal that diagnostic surfaces must preserve instead of relabelling. */
97
+ export class ConfigResolutionError extends CLIError {
98
+ kind;
99
+ nextCommand;
100
+ constructor(message, options) {
101
+ super(message, options);
102
+ this.name = 'ConfigResolutionError';
103
+ this.kind = options.kind;
104
+ this.nextCommand = options.nextCommand;
105
+ }
106
+ }
107
+ /** Convert a throwing resolution cascade into the single diagnostic contract. */
108
+ export function resolveConfigResult(resolveConfig) {
109
+ let resolved;
110
+ try {
111
+ resolved = resolveConfig();
112
+ }
113
+ catch (error) {
114
+ if (error instanceof ConfigResolutionError) {
115
+ return {
116
+ ok: false,
117
+ kind: error.kind,
118
+ reason: error.message,
119
+ guidance: error.guidance ?? `Run \`${error.nextCommand}\`.`,
120
+ nextCommand: error.nextCommand,
121
+ };
122
+ }
123
+ const reason = error instanceof Error ? error.message : String(error);
124
+ return {
125
+ ok: false,
126
+ kind: 'unknown',
127
+ reason,
128
+ guidance: 'Run `pb doctor` to diagnose the configuration.',
129
+ nextCommand: 'pb doctor',
130
+ };
131
+ }
132
+ if (!resolved.apiKey) {
133
+ return {
134
+ ok: false,
135
+ kind: 'missing-key',
136
+ reason: 'No API key configured.',
137
+ guidance: 'Run `pb login` to configure your API key, or set PRODUCTBRAIN_API_KEY.',
138
+ nextCommand: 'pb login',
139
+ };
140
+ }
141
+ if (!resolved.apiKey.startsWith(API_KEY_PREFIX)) {
142
+ // `source` IS the credential's origin by definition, so it can be named without hedging.
143
+ // An exported key wins step 1 of the cascade, which `pb login` cannot outrank: login
144
+ // persists into a profile or the legacy home file, both of which lose to the env var —
145
+ // so telling the operator to log in would replay the identical failure forever.
146
+ const fromEnv = resolved.source === 'env';
147
+ return {
148
+ ok: false,
149
+ kind: 'invalid-key',
150
+ reason: `Invalid API key format (expected ${API_KEY_PREFIX}..., from ${describeApiKeyOrigin(resolved.source, resolved.profileName)}).`,
151
+ guidance: fromEnv
152
+ ? `Unset PRODUCTBRAIN_API_KEY, or replace it with a valid ${API_KEY_PREFIX} key — it outranks every stored profile, so \`pb login\` cannot repair this.`
153
+ : 'Run `pb login` to configure a valid API key.',
154
+ nextCommand: fromEnv ? 'pb doctor' : 'pb login',
155
+ };
156
+ }
157
+ if (isInsecureSiteUrl(resolved.siteUrl)) {
158
+ const got = `got "${resolved.siteUrl.slice(0, 30)}…"`;
159
+ // No recorded provenance means the URL's origin was never observed. Naming a specific file
160
+ // here would be a guess, and a wrong repair target is worse than an unnamed one.
161
+ const origin = resolved.siteUrlSource
162
+ ? describeSiteUrlOrigin(resolved.siteUrlSource, resolved.siteUrlDetail, resolved.profileName)
163
+ : null;
164
+ return {
165
+ ok: false,
166
+ kind: 'invalid-url',
167
+ reason: `Site URL must use HTTPS (${got}${origin ? `, from ${origin}` : ''}). API keys must not be sent over unencrypted connections.`,
168
+ guidance: origin
169
+ ? `Set an https:// URL in ${origin}.`
170
+ : 'Run `pb doctor` to see which source supplied the URL, then set an https:// URL there.',
171
+ nextCommand: 'pb doctor',
172
+ };
173
+ }
174
+ return { ok: true, ...resolved, apiKey: resolved.apiKey };
175
+ }
176
+ //# sourceMappingURL=configResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configResult.js","sourceRoot":"","sources":["../../src/lib/configResult.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Repo-local binding resolution — turns what `.productbrain/config.local.json` declares into a
3
+ * credential, or refuses outright.
4
+ *
5
+ * Both cascades that serve ordinary commands (`resolveConfig()`'s return path and `loadEnv()`'s
6
+ * process.env path) call these two helpers, so the refusal rules cannot drift apart between them
7
+ * (STD-3). The shared rule is the same in both: when the repo has declared a tenant, resolution
8
+ * either honors that declaration or fails loudly — it never substitutes a different workspace and
9
+ * carries on. Fail loud, fail closed, fail fast (PRI-24); default closed, explicitly opened
10
+ * (PRI-22).
11
+ *
12
+ * `adminConfig.ts` keeps its own inline copy on purpose: it excludes config.json's siteUrl and the
13
+ * CWD .env files, so it is a narrower cascade, not this one. Folding it in is the remaining step
14
+ * toward a single code path (STA-3).
15
+ */
16
+ import type { LocalProjectConfig } from './projectConfig.js';
17
+ /**
18
+ * Resolve the repo-local profile pin to a credential, or refuse outright.
19
+ *
20
+ * FAILS CLOSED on a DANGLING pin: a pin naming a profile that has since been deleted, or whose
21
+ * file carries no key, must NEVER fall through to the global active profile. The repo has
22
+ * explicitly declared its tenant; substituting a different one silently retargets every read AND
23
+ * write at a foreign workspace, and the gateway derives the workspace from the credential (BR-18)
24
+ * — so nothing downstream catches it.
25
+ *
26
+ * INS-2455 is the admin-path instance of exactly this fall-through: `resolveAdminConfig()` was
27
+ * hardened on its own, which left the two cascades every other command uses still fail-open.
28
+ */
29
+ export declare function resolvePinnedProfile(profileName: string): {
30
+ apiKey: string;
31
+ siteUrl?: string;
32
+ };
33
+ /**
34
+ * Resolve the direct credential binding in config.local.json, or null when the file does not
35
+ * claim one (the profile pin then owns resolution).
36
+ *
37
+ * The claim is the `preview` marker OR a credential of its own — deliberately NOT the marker
38
+ * alone. A file carrying an apiKey is asserting which workspace this repo talks to whether or not
39
+ * `pb:preview` stamped the marker, so gating on the marker would let a hand-written or
40
+ * partially-scrubbed binding be skipped and a sibling profile pin silently supply a different
41
+ * tenant's credential instead (the failure class TEN-3237/TEN-3238 closed for the pin path).
42
+ *
43
+ * Once claimed, only the atomic apiKey+siteUrl pair (SF-3) may bind — never a preview key paired
44
+ * with config.json's real-dev gateway (STD-261). Anything else refuses here, ahead of the pin, so
45
+ * a broken binding is named rather than routed around.
46
+ */
47
+ export declare function resolveLocalBinding(localConfig: LocalProjectConfig | null): {
48
+ apiKey: string;
49
+ siteUrl: string;
50
+ } | null;
51
+ //# sourceMappingURL=localBinding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localBinding.d.ts","sourceRoot":"","sources":["../../src/lib/localBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAG7D;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAqB9F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,kBAAkB,GAAG,IAAI,GACrC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA2B5C"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Repo-local binding resolution — turns what `.productbrain/config.local.json` declares into a
3
+ * credential, or refuses outright.
4
+ *
5
+ * Both cascades that serve ordinary commands (`resolveConfig()`'s return path and `loadEnv()`'s
6
+ * process.env path) call these two helpers, so the refusal rules cannot drift apart between them
7
+ * (STD-3). The shared rule is the same in both: when the repo has declared a tenant, resolution
8
+ * either honors that declaration or fails loudly — it never substitutes a different workspace and
9
+ * carries on. Fail loud, fail closed, fail fast (PRI-24); default closed, explicitly opened
10
+ * (PRI-22).
11
+ *
12
+ * `adminConfig.ts` keeps its own inline copy on purpose: it excludes config.json's siteUrl and the
13
+ * CWD .env files, so it is a narrower cascade, not this one. Folding it in is the remaining step
14
+ * toward a single code path (STA-3).
15
+ */
16
+ import { ConfigResolutionError } from './configResult.js';
17
+ import { ErrorCode } from './errors.js';
18
+ import { resolveNamedProfileConfig } from './profiles.js';
19
+ import { API_KEY_PREFIX } from './tokenConstants.js';
20
+ /**
21
+ * Resolve the repo-local profile pin to a credential, or refuse outright.
22
+ *
23
+ * FAILS CLOSED on a DANGLING pin: a pin naming a profile that has since been deleted, or whose
24
+ * file carries no key, must NEVER fall through to the global active profile. The repo has
25
+ * explicitly declared its tenant; substituting a different one silently retargets every read AND
26
+ * write at a foreign workspace, and the gateway derives the workspace from the credential (BR-18)
27
+ * — so nothing downstream catches it.
28
+ *
29
+ * INS-2455 is the admin-path instance of exactly this fall-through: `resolveAdminConfig()` was
30
+ * hardened on its own, which left the two cascades every other command uses still fail-open.
31
+ */
32
+ export function resolvePinnedProfile(profileName) {
33
+ const namedConfig = resolveNamedProfileConfig(profileName);
34
+ // Same validity bar as adminConfig.ts: a present-but-malformed key is a broken pin, not a
35
+ // credential. Accepting it here would surface as a generic "no API key, run pb login" far
36
+ // downstream, pointing the operator away from the pin that actually broke.
37
+ if (!namedConfig?.apiKey?.startsWith(API_KEY_PREFIX)) {
38
+ throw new ConfigResolutionError(`This repo is pinned to profile "${profileName}" (.productbrain/config.local.json), ` +
39
+ `but that profile has no valid API key — it may have been deleted or never fully set up. ` +
40
+ `Refusing to silently fall back to a different workspace. ` +
41
+ `Run \`pb profile use --local <profile>\` to fix the pin, or \`pb profile create ${profileName}\` to restore it.`, {
42
+ code: ErrorCode.AUTH_MISSING,
43
+ category: 'auth',
44
+ kind: 'profile-pin',
45
+ nextCommand: 'pb profile use --local <profile>',
46
+ guidance: 'Run `pb profile use --local <profile>` to fix the repo pin.',
47
+ });
48
+ }
49
+ return { apiKey: namedConfig.apiKey, siteUrl: namedConfig.siteUrl };
50
+ }
51
+ /**
52
+ * Resolve the direct credential binding in config.local.json, or null when the file does not
53
+ * claim one (the profile pin then owns resolution).
54
+ *
55
+ * The claim is the `preview` marker OR a credential of its own — deliberately NOT the marker
56
+ * alone. A file carrying an apiKey is asserting which workspace this repo talks to whether or not
57
+ * `pb:preview` stamped the marker, so gating on the marker would let a hand-written or
58
+ * partially-scrubbed binding be skipped and a sibling profile pin silently supply a different
59
+ * tenant's credential instead (the failure class TEN-3237/TEN-3238 closed for the pin path).
60
+ *
61
+ * Once claimed, only the atomic apiKey+siteUrl pair (SF-3) may bind — never a preview key paired
62
+ * with config.json's real-dev gateway (STD-261). Anything else refuses here, ahead of the pin, so
63
+ * a broken binding is named rather than routed around.
64
+ */
65
+ export function resolveLocalBinding(localConfig) {
66
+ if (!localConfig)
67
+ return null;
68
+ const claimsBinding = localConfig.preview === true || Boolean(localConfig.apiKey) || localConfig.apiKeyMalformed === true;
69
+ if (!claimsBinding)
70
+ return null;
71
+ if (localConfig.apiKey && localConfig.siteUrl) {
72
+ return { apiKey: localConfig.apiKey, siteUrl: localConfig.siteUrl.replace(/\/$/, '') };
73
+ }
74
+ // A malformed key is present-but-unusable, not absent — readLocalProjectConfig() withholds it
75
+ // from `apiKey` so it can never bind, and flags it so this refusal can name the real fault.
76
+ const fault = localConfig.apiKeyMalformed
77
+ ? `its API key is not a valid ${API_KEY_PREFIX} key`
78
+ : !localConfig.apiKey
79
+ ? 'missing API key'
80
+ : 'missing deployment URL';
81
+ throw new ConfigResolutionError(`This repo has an incomplete preview binding (.productbrain/config.local.json): ` +
82
+ `${fault}. Refusing to use its profile pin or another workspace instead.`, {
83
+ code: ErrorCode.CONFIG_INVALID,
84
+ category: 'config',
85
+ kind: 'preview-binding',
86
+ nextCommand: 'npm run pb:preview',
87
+ guidance: 'Run `npm run pb:preview` to repair the preview binding, or `npm run pb:real` to return to the repo pin.',
88
+ });
89
+ }
90
+ //# sourceMappingURL=localBinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localBinding.js","sourceRoot":"","sources":["../../src/lib/localBinding.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,MAAM,WAAW,GAAG,yBAAyB,CAAC,WAAW,CAAC,CAAC;IAC3D,0FAA0F;IAC1F,0FAA0F;IAC1F,2EAA2E;IAC3E,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,qBAAqB,CAC7B,mCAAmC,WAAW,uCAAuC;YACnF,0FAA0F;YAC1F,2DAA2D;YAC3D,mFAAmF,WAAW,mBAAmB,EACnH;YACE,IAAI,EAAE,SAAS,CAAC,YAAY;YAC5B,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,kCAAkC;YAC/C,QAAQ,EAAE,6DAA6D;SACxE,CACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE,CAAC;AACtE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAAsC;IAEtC,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,aAAa,GACjB,WAAW,CAAC,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,KAAK,IAAI,CAAC;IACtG,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,WAAW,CAAC,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QAC9C,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC;IAED,8FAA8F;IAC9F,4FAA4F;IAC5F,MAAM,KAAK,GAAG,WAAW,CAAC,eAAe;QACvC,CAAC,CAAC,8BAA8B,cAAc,MAAM;QACpD,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM;YACnB,CAAC,CAAC,iBAAiB;YACnB,CAAC,CAAC,wBAAwB,CAAC;IAC/B,MAAM,IAAI,qBAAqB,CAC7B,iFAAiF;QAC/E,GAAG,KAAK,iEAAiE,EAC3E;QACE,IAAI,EAAE,SAAS,CAAC,cAAc;QAC9B,QAAQ,EAAE,QAAQ;QAClB,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,oBAAoB;QACjC,QAAQ,EAAE,yGAAyG;KACpH,CACF,CAAC;AACJ,CAAC"}
@@ -22,6 +22,12 @@ export interface LocalProjectConfig {
22
22
  profile?: string;
23
23
  /** Direct preview API key — set by `npm run pb:preview`, cleared by `npm run pb:real`. */
24
24
  apiKey?: string;
25
+ /**
26
+ * An `apiKey` was present but failed the `API_KEY_PREFIX` bar, so it was not loaded.
27
+ * Kept apart from `apiKey` so a malformed key can never bind, while diagnostics can still
28
+ * say "malformed" instead of misreporting it as absent.
29
+ */
30
+ apiKeyMalformed?: boolean;
25
31
  /** Preview site URL — set alongside apiKey by `npm run pb:preview`. */
26
32
  siteUrl?: string;
27
33
  /** Marks this config as preview-bound; the CLI shows a loud banner on every command. */
@@ -1 +1 @@
1
- {"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB/D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAuBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,GAAG,IAAI,CAmClE"}
1
+ {"version":3,"file":"projectConfig.d.ts","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wFAAwF;IACxF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgB/D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,aAAa,GAAG,IAAI,CAuBxD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,kBAAkB,GAAG,IAAI,CA8ClE"}
@@ -107,8 +107,20 @@ export function readLocalProjectConfig() {
107
107
  result.profile = parsed.profile;
108
108
  }
109
109
  // Preview binding fields — written by `npm run pb:preview`, cleared by `npm run pb:real`.
110
- if (typeof parsed.apiKey === 'string' && parsed.apiKey.startsWith(API_KEY_PREFIX)) {
111
- result.apiKey = parsed.apiKey;
110
+ //
111
+ // Fail closed on ANY present-but-invalid apiKey, not just a wrong-prefix string: a number,
112
+ // an empty string, a boolean or an object is a corrupt or hand-written binding, and treating
113
+ // it as absent would let the caller skip the claimed binding and adopt a sibling profile pin
114
+ // — the workspace substitution this whole path exists to prevent. Only `undefined`/`null`
115
+ // count as absent: JSON `null` conventionally means "no value", and `npm run pb:real` strips
116
+ // the preview keys entirely rather than nulling them.
117
+ if (parsed.apiKey !== undefined && parsed.apiKey !== null) {
118
+ if (typeof parsed.apiKey === 'string' && parsed.apiKey.startsWith(API_KEY_PREFIX)) {
119
+ result.apiKey = parsed.apiKey;
120
+ }
121
+ else {
122
+ result.apiKeyMalformed = true;
123
+ }
112
124
  }
113
125
  if (typeof parsed.siteUrl === 'string' && parsed.siteUrl) {
114
126
  result.siteUrl = parsed.siteUrl;
@@ -1 +1 @@
1
- {"version":3,"file":"projectConfig.js","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projectConfig.js","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AA0BrD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC;QAC5C,IACE,UAAU,CAAC,KAAK,CAAC;YACjB,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;gBACxC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAClD,CAAC;YACD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,GAAG,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAChD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,eAAe,EAAE,aAAa,CAAC,CAAC;IACxE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;YAC7F,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,CAAC;QACD,6FAA6F;QAC7F,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC9F,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;IAC9E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4EAA4E,CAAC,CAAC;YACnG,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,MAAM,GAAuB,EAAE,CAAC;QACtC,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,CAAC;QACD,0FAA0F;QAC1F,EAAE;QACF,2FAA2F;QAC3F,6FAA6F;QAC7F,6FAA6F;QAC7F,0FAA0F;QAC1F,6FAA6F;QAC7F,sDAAsD;QACtD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YAC1D,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;gBAClF,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC;YAChC,CAAC;QACH,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACzD,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;QAClC,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACrE,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC;QAC9C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -11,6 +11,7 @@
11
11
  * workspace-bound → key + workspace reachable, but no active session
12
12
  * active → key + workspace + active session
13
13
  */
14
+ import { type ConfigFailureKind } from './config.js';
14
15
  /** Four-stage setup journey from cold start to active use. */
15
16
  export type SetupStage = 'unconfigured' | 'authenticated' | 'workspace-bound' | 'active';
16
17
  export interface SetupState {
@@ -25,6 +26,12 @@ export interface SetupState {
25
26
  entryCount?: number;
26
27
  /** Whether a write session is currently active. */
27
28
  sessionActive?: boolean;
29
+ /** Exact local-binding failure, when this is more specific than ordinary first-time setup. */
30
+ configurationIssue?: {
31
+ kind: ConfigFailureKind;
32
+ reason: string;
33
+ guidance: string;
34
+ };
28
35
  }
29
36
  /** Output render tier for the current runtime context. */
30
37
  export type RenderTier = 'json' | 'plain' | 'ink';
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAWH,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAEzF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,mFAAmF;IACnF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAMlD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CA2C7D;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAI7C"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AASpE,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,eAAe,GAAG,iBAAiB,GAAG,QAAQ,CAAC;AAEzF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,CAAC;IAClB,mFAAmF;IACnF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8FAA8F;IAC9F,kBAAkB,CAAC,EAAE;QACnB,IAAI,EAAE,iBAAiB,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,0DAA0D;AAC1D,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAMlD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,UAAU,CAAC,CAgD7D;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAI7C"}
package/dist/lib/state.js CHANGED
@@ -34,8 +34,13 @@ export async function resolveSetupState() {
34
34
  if (!configResult.ok) {
35
35
  return {
36
36
  stage: 'unconfigured',
37
- missingSteps: ['API key not found'],
38
- nextAction: 'pb login',
37
+ missingSteps: [configResult.reason],
38
+ nextAction: configResult.nextCommand,
39
+ configurationIssue: {
40
+ kind: configResult.kind,
41
+ reason: configResult.reason,
42
+ guidance: configResult.guidance,
43
+ },
39
44
  };
40
45
  }
41
46
  // Step 2 — can we reach the workspace?
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA0BzC,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,qCAAqC;IACrC,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;IACrC,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,YAAY,EAAE,CAAC,mBAAmB,CAAC;YACnC,UAAU,EAAE,UAAU;SACvB,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,CAAC,wCAAwC,CAAC;YACxD,UAAU,EAAE,YAAY;SACzB,CAAC;IACJ,CAAC;IAED,6CAA6C;IAC7C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,iBAAiB;YACxB,YAAY,EAAE,CAAC,yBAAyB,CAAC;YACzC,UAAU,EAAE,kBAAkB;YAC9B,aAAa,EAAE,MAAM,CAAC,IAAI;YAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,aAAa,EAAE,KAAK;SACrB,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,MAAM,CAAC,IAAI;QAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,UAAU,EAAE;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,aAAa,EAA0B,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgCzC,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,qCAAqC;IACrC,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;IACrC,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,OAAO;YACL,KAAK,EAAE,cAAc;YACrB,YAAY,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;YACnC,UAAU,EAAE,YAAY,CAAC,WAAW;YACpC,kBAAkB,EAAE;gBAClB,IAAI,EAAE,YAAY,CAAC,IAAI;gBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;gBAC3B,QAAQ,EAAE,YAAY,CAAC,QAAQ;aAChC;SACF,CAAC;IACJ,CAAC;IAED,uCAAuC;IACvC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,CAAC,wCAAwC,CAAC;YACxD,UAAU,EAAE,YAAY;SACzB,CAAC;IACJ,CAAC;IAED,6CAA6C;IAC7C,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO;YACL,KAAK,EAAE,iBAAiB;YACxB,YAAY,EAAE,CAAC,yBAAyB,CAAC;YACzC,UAAU,EAAE,kBAAkB;YAC9B,aAAa,EAAE,MAAM,CAAC,IAAI;YAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;YAC7B,aAAa,EAAE,KAAK;SACrB,CAAC;IACJ,CAAC;IAED,qCAAqC;IACrC,OAAO;QACL,KAAK,EAAE,QAAQ;QACf,YAAY,EAAE,EAAE;QAChB,UAAU,EAAE,cAAc;QAC1B,aAAa,EAAE,MAAM,CAAC,IAAI;QAC1B,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,aAAa,EAAE,IAAI;KACpB,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,UAAU,EAAE;QAAE,OAAO,MAAM,CAAC;IAChC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@productbrain/cli",
3
- "version": "0.1.0-beta.4809",
3
+ "version": "0.1.0-beta.4818",
4
4
  "description": "Product Brain — Chain knowledge and write-back CLI",
5
5
  "type": "module",
6
6
  "bin": {