@productbrain/cli 0.1.0-beta.9222 → 0.1.0-beta.9237
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.
- package/dist/__tests__/config.test.js +110 -18
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/missingPin.test.js +1 -2
- package/dist/__tests__/missingPin.test.js.map +1 -1
- package/dist/__tests__/session-list-show.test.js +0 -1
- package/dist/__tests__/session-list-show.test.js.map +1 -1
- package/dist/__tests__/session-switch.test.js +0 -1
- package/dist/__tests__/session-switch.test.js.map +1 -1
- package/dist/commands/profile.d.ts +5 -6
- package/dist/commands/profile.d.ts.map +1 -1
- package/dist/commands/profile.js +17 -30
- package/dist/commands/profile.js.map +1 -1
- package/dist/lib/config.d.ts +10 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +29 -60
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/configResult.d.ts +5 -6
- package/dist/lib/configResult.d.ts.map +1 -1
- package/dist/lib/configResult.js +0 -1
- package/dist/lib/configResult.js.map +1 -1
- package/dist/lib/projectConfig.d.ts +4 -14
- package/dist/lib/projectConfig.d.ts.map +1 -1
- package/dist/lib/projectConfig.js +4 -35
- package/dist/lib/projectConfig.js.map +1 -1
- package/dist/lib/workspaceNotice.d.ts +2 -2
- package/dist/lib/workspaceNotice.js +4 -4
- package/package.json +1 -1
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* cannot participate in an import cycle.
|
|
9
9
|
*
|
|
10
10
|
* Split config design:
|
|
11
|
-
* - config.json (committed):
|
|
11
|
+
* - config.json (committed): its PRESENCE declares a Product Brain project. The CLI never reads
|
|
12
|
+
* its siteUrl: a cloned repo controls that file, so it must not route a key (TEN-4500).
|
|
12
13
|
* - config.local.json (gitignored): profile pin — machine-local, never committed. Because it
|
|
13
14
|
* is gitignored, a fresh clone or worktree does NOT inherit it (INS-2462) — the caller must
|
|
14
15
|
* treat "no pin" as an explicit state, never as permission to guess a workspace.
|
|
@@ -21,7 +22,7 @@ import { API_KEY_PREFIX } from './tokenConstants.js';
|
|
|
21
22
|
* Walk up the directory tree (git-style) to find the nearest CLI project root.
|
|
22
23
|
*
|
|
23
24
|
* A `.productbrain/` directory only counts as a CLI project root when it carries
|
|
24
|
-
* CLI configuration — `config.json` (committed
|
|
25
|
+
* CLI configuration — `config.json` (committed project declaration) or
|
|
25
26
|
* `config.local.json` (machine-local profile pin or preview binding). A
|
|
26
27
|
* projection-only `.productbrain/` written by `pb handshake` (briefing.md,
|
|
27
28
|
* context.md, rules/, etc.) does NOT count — otherwise a subrepo like
|
|
@@ -48,42 +49,10 @@ export function findProjectRoot(startDir) {
|
|
|
48
49
|
dir = parent;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Read .productbrain/config.json from the walked-up project root.
|
|
53
|
-
* Only reads siteUrl — profile and apiKey fields are ignored (legacy or misplaced).
|
|
54
|
-
* Returns null if file missing or project root not found.
|
|
55
|
-
* Warns to stderr on invalid JSON but does not throw.
|
|
56
|
-
*/
|
|
57
|
-
export function readProjectConfig() {
|
|
58
|
-
const projectRoot = findProjectRoot(process.cwd());
|
|
59
|
-
if (!projectRoot)
|
|
60
|
-
return null;
|
|
61
|
-
const configPath = resolve(projectRoot, '.productbrain', 'config.json');
|
|
62
|
-
if (!existsSync(configPath))
|
|
63
|
-
return null;
|
|
64
|
-
try {
|
|
65
|
-
const raw = readFileSync(configPath, 'utf8');
|
|
66
|
-
const parsed = JSON.parse(raw);
|
|
67
|
-
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
68
|
-
process.stderr.write('Warning: .productbrain/config.json is not a JSON object, skipping.\n');
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
const result = {};
|
|
72
|
-
if (typeof parsed.siteUrl === 'string' && parsed.siteUrl) {
|
|
73
|
-
result.siteUrl = parsed.siteUrl;
|
|
74
|
-
}
|
|
75
|
-
// Silently ignore `profile` and `apiKey` in config.json — those must be in config.local.json
|
|
76
|
-
return result;
|
|
77
|
-
}
|
|
78
|
-
catch {
|
|
79
|
-
process.stderr.write('Warning: .productbrain/config.json contains invalid JSON, skipping.\n');
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
52
|
/**
|
|
84
53
|
* Does the committed `.productbrain/config.json` EXIST, independent of whether it parses?
|
|
85
54
|
*
|
|
86
|
-
* The project's self-declaration is the file's PRESENCE, not its contents.
|
|
55
|
+
* The project's self-declaration is the file's PRESENCE, not its contents. A content reader
|
|
87
56
|
* returns null for a malformed or non-object file exactly as it does for an absent one, so a
|
|
88
57
|
* caller asking "is this a project" through that value reads a DAMAGED declaration as no
|
|
89
58
|
* declaration at all — and falls through to whatever workspace the global profile names. A
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"projectConfig.js","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"projectConfig.js","sourceRoot":"","sources":["../../src/lib/projectConfig.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
* copy-paste.
|
|
55
55
|
*
|
|
56
56
|
* `pb admin` is a SEPARATE credential cascade (`adminConfig.ts`'s `resolveAdminConfig`) that
|
|
57
|
-
* deliberately excludes
|
|
58
|
-
* resolve a different tenant than the cascade above, so it gets its own formatter-reusing
|
|
57
|
+
* deliberately excludes CWD env files (TEN-1334); neither cascade reads committed `config.json`
|
|
58
|
+
* siteUrl (TEN-4500). It can resolve a different tenant than the cascade above, so it gets its own formatter-reusing
|
|
59
59
|
* emitter (`emitAdminTenantNotice`/`describeAdminTenantForRefusal` below) rather than sharing
|
|
60
60
|
* `emitEffectiveTenantNotice`'s guard or resolution path.
|
|
61
61
|
*/
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
* copy-paste.
|
|
55
55
|
*
|
|
56
56
|
* `pb admin` is a SEPARATE credential cascade (`adminConfig.ts`'s `resolveAdminConfig`) that
|
|
57
|
-
* deliberately excludes
|
|
58
|
-
* resolve a different tenant than the cascade above, so it gets its own formatter-reusing
|
|
57
|
+
* deliberately excludes CWD env files (TEN-1334); neither cascade reads committed `config.json`
|
|
58
|
+
* siteUrl (TEN-4500). It can resolve a different tenant than the cascade above, so it gets its own formatter-reusing
|
|
59
59
|
* emitter (`emitAdminTenantNotice`/`describeAdminTenantForRefusal` below) rather than sharing
|
|
60
60
|
* `emitEffectiveTenantNotice`'s guard or resolution path.
|
|
61
61
|
*/
|
|
@@ -268,8 +268,8 @@ export async function emitEffectiveTenantNotice() {
|
|
|
268
268
|
* `ReportedProfileSource` vocabulary, so `pb admin` reuses the SAME formatter and label rules
|
|
269
269
|
* (`formatEffectiveTenantNotice`/`describeReportedTenant`) instead of a parallel copy. This is
|
|
270
270
|
* deliberately NOT a call to `resolveReportedProfile()` — that walks a DIFFERENT cascade
|
|
271
|
-
* (`config.ts`'s `resolveConfig`, which DOES read
|
|
272
|
-
*
|
|
271
|
+
* (`config.ts`'s `resolveConfig`, which DOES read CWD env files — a key and its URL as a pair
|
|
272
|
+
* from the same file, never committed `config.json` siteUrl, TEN-4500) and can disagree with what `resolveAdminConfig()` actually resolved, which would name
|
|
273
273
|
* a tenant this admin call is not actually about to use. `'legacy'` (the nameless
|
|
274
274
|
* `~/.config/productbrain/.env` fallback) has no direct analog in `ReportedProfileSource` — it
|
|
275
275
|
* maps to `'default'`, the closest existing "implicit, no deliberate per-repo pin" qualifier.
|