@productbrain/cli 0.1.0-beta.30 → 0.1.0-beta.32
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/README.md +62 -178
- package/dist/__tests__/constants.test.js +1 -1
- package/dist/__tests__/constants.test.js.map +1 -1
- package/dist/__tests__/errors.test.d.ts +2 -0
- package/dist/__tests__/errors.test.d.ts.map +1 -0
- package/dist/__tests__/errors.test.js +117 -0
- package/dist/__tests__/errors.test.js.map +1 -0
- package/dist/__tests__/glossary.test.d.ts +2 -0
- package/dist/__tests__/glossary.test.d.ts.map +1 -0
- package/dist/__tests__/glossary.test.js +32 -0
- package/dist/__tests__/glossary.test.js.map +1 -0
- package/dist/__tests__/login.test.js +1 -1
- package/dist/__tests__/login.test.js.map +1 -1
- package/dist/__tests__/profiles.test.d.ts +2 -0
- package/dist/__tests__/profiles.test.d.ts.map +1 -0
- package/dist/__tests__/profiles.test.js +168 -0
- package/dist/__tests__/profiles.test.js.map +1 -0
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +3 -2
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/doctor.d.ts +9 -2
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +112 -25
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.d.ts +2 -1
- package/dist/commands/doctor.test.d.ts.map +1 -1
- package/dist/commands/doctor.test.js +166 -3
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/profile.d.ts +24 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +82 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/promote.d.ts.map +1 -1
- package/dist/commands/promote.js +3 -2
- package/dist/commands/promote.js.map +1 -1
- package/dist/formatters/promote.d.ts +1 -0
- package/dist/formatters/promote.d.ts.map +1 -1
- package/dist/formatters/promote.js +1 -0
- package/dist/formatters/promote.js.map +1 -1
- package/dist/index.js +240 -299
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +2 -2
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +30 -11
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/config.d.ts +9 -3
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +49 -12
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +1 -1
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +1 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/errors.d.ts +57 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +65 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/glossary.d.ts +19 -0
- package/dist/lib/glossary.d.ts.map +1 -0
- package/dist/lib/glossary.js +53 -0
- package/dist/lib/glossary.js.map +1 -0
- package/dist/lib/profiles.d.ts +34 -0
- package/dist/lib/profiles.d.ts.map +1 -0
- package/dist/lib/profiles.js +173 -0
- package/dist/lib/profiles.js.map +1 -0
- package/dist/lib/runner.d.ts +2 -0
- package/dist/lib/runner.d.ts.map +1 -1
- package/dist/lib/runner.js +33 -4
- package/dist/lib/runner.js.map +1 -1
- package/dist/lib/style.d.ts +65 -0
- package/dist/lib/style.d.ts.map +1 -0
- package/dist/lib/style.js +108 -0
- package/dist/lib/style.js.map +1 -0
- package/dist/lib/style.test.d.ts +7 -0
- package/dist/lib/style.test.d.ts.map +1 -0
- package/dist/lib/style.test.js +195 -0
- package/dist/lib/style.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* glossary.ts — Key CLI terms and their definitions.
|
|
3
|
+
*
|
|
4
|
+
* Provides a static glossary of Product Brain CLI terminology,
|
|
5
|
+
* plus a formatter for TTY output.
|
|
6
|
+
*
|
|
7
|
+
* WP-302 Slice 4.
|
|
8
|
+
*/
|
|
9
|
+
import { bold, dim } from './style.js';
|
|
10
|
+
export const GLOSSARY = [
|
|
11
|
+
{
|
|
12
|
+
term: 'workspace',
|
|
13
|
+
definition: 'Your product knowledge space. One workspace = one product.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
term: 'entry',
|
|
17
|
+
definition: 'A unit of product knowledge (bet, decision, tension, standard, etc.).',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
term: 'collection',
|
|
21
|
+
definition: 'A group of related entries (work-packages, decisions, tensions, etc.).',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
term: 'relation',
|
|
25
|
+
definition: 'A typed link between entries (part_of, depends_on, addresses, etc.).',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
term: 'session',
|
|
29
|
+
definition: 'A tracked write session. Required before creating or updating entries.',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
term: 'capture',
|
|
33
|
+
definition: 'Create a new entry on the Chain via pb capture.',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
term: 'profile',
|
|
37
|
+
definition: 'A named workspace configuration with API key and endpoint.',
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* Format the glossary for TTY output.
|
|
42
|
+
* Returns a multi-line string with bold terms and dimmed definitions.
|
|
43
|
+
*/
|
|
44
|
+
export function formatGlossary() {
|
|
45
|
+
const lines = [];
|
|
46
|
+
const maxTermLen = Math.max(...GLOSSARY.map((g) => g.term.length));
|
|
47
|
+
for (const entry of GLOSSARY) {
|
|
48
|
+
const paddedTerm = entry.term.padEnd(maxTermLen);
|
|
49
|
+
lines.push(` ${bold(paddedTerm)} ${dim(entry.definition)}`);
|
|
50
|
+
}
|
|
51
|
+
return lines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=glossary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"glossary.js","sourceRoot":"","sources":["../../src/lib/glossary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAOvC,MAAM,CAAC,MAAM,QAAQ,GAAoB;IACvC;QACE,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,4DAA4D;KACzE;IACD;QACE,IAAI,EAAE,OAAO;QACb,UAAU,EAAE,uEAAuE;KACpF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,UAAU,EAAE,wEAAwE;KACrF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,UAAU,EAAE,sEAAsE;KACnF;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,wEAAwE;KACrF;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,iDAAiD;KAC9D;IACD;QACE,IAAI,EAAE,SAAS;QACf,UAAU,EAAE,4DAA4D;KACzE;CACF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile storage and resolution — multi-workspace support for the Product Brain CLI.
|
|
3
|
+
* WP-302 Slice 2: Workspace Profiles + Config Refactor.
|
|
4
|
+
*
|
|
5
|
+
* Profile directory: ~/.config/productbrain/profiles/
|
|
6
|
+
* Active profile tracked in: ~/.config/productbrain/active-profile
|
|
7
|
+
* Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
|
|
8
|
+
*/
|
|
9
|
+
declare const HOME_CONFIG_DIR: string;
|
|
10
|
+
declare const PROFILES_DIR: string;
|
|
11
|
+
declare const ACTIVE_PROFILE_PATH: string;
|
|
12
|
+
declare const LEGACY_ENV_PATH: string;
|
|
13
|
+
export interface ProfileConfig {
|
|
14
|
+
apiKey: string;
|
|
15
|
+
siteUrl?: string;
|
|
16
|
+
}
|
|
17
|
+
/** List all profile names (sorted). */
|
|
18
|
+
export declare function listProfiles(): string[];
|
|
19
|
+
/** Get the active profile name. */
|
|
20
|
+
export declare function getActiveProfile(): string | null;
|
|
21
|
+
/** Create a new profile. */
|
|
22
|
+
export declare function createProfile(name: string, apiKey: string, siteUrl?: string): void;
|
|
23
|
+
/** Switch the active profile. */
|
|
24
|
+
export declare function useProfile(name: string): void;
|
|
25
|
+
/** Delete a profile. Cannot delete the last profile or the active profile. */
|
|
26
|
+
export declare function deleteProfile(name: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Resolve config from the active profile.
|
|
29
|
+
* Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
|
|
30
|
+
* Returns null if no profile or config is available.
|
|
31
|
+
*/
|
|
32
|
+
export declare function resolveProfileConfig(): ProfileConfig | null;
|
|
33
|
+
export { PROFILES_DIR, ACTIVE_PROFILE_PATH, LEGACY_ENV_PATH, HOME_CONFIG_DIR };
|
|
34
|
+
//# sourceMappingURL=profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/lib/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,QAAA,MAAM,eAAe,QAAgD,CAAC;AACtE,QAAA,MAAM,YAAY,QAAuC,CAAC;AAC1D,QAAA,MAAM,mBAAmB,QAA6C,CAAC;AACvE,QAAA,MAAM,eAAe,QAAmC,CAAC;AAKzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAoDD,uCAAuC;AACvC,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAOvC;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAWhD;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAwBlF;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAS7C;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBhD;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,aAAa,GAAG,IAAI,CAgC3D;AAGD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Profile storage and resolution — multi-workspace support for the Product Brain CLI.
|
|
3
|
+
* WP-302 Slice 2: Workspace Profiles + Config Refactor.
|
|
4
|
+
*
|
|
5
|
+
* Profile directory: ~/.config/productbrain/profiles/
|
|
6
|
+
* Active profile tracked in: ~/.config/productbrain/active-profile
|
|
7
|
+
* Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
|
|
8
|
+
*/
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, readdirSync } from 'fs';
|
|
10
|
+
import { resolve } from 'path';
|
|
11
|
+
import { homedir } from 'os';
|
|
12
|
+
import { CLIError, ErrorCode } from './errors.js';
|
|
13
|
+
const HOME_CONFIG_DIR = resolve(homedir(), '.config', 'productbrain');
|
|
14
|
+
const PROFILES_DIR = resolve(HOME_CONFIG_DIR, 'profiles');
|
|
15
|
+
const ACTIVE_PROFILE_PATH = resolve(HOME_CONFIG_DIR, 'active-profile');
|
|
16
|
+
const LEGACY_ENV_PATH = resolve(HOME_CONFIG_DIR, '.env');
|
|
17
|
+
/** Profile name validation: lowercase alphanumeric + hyphens, 1-32 chars. */
|
|
18
|
+
const PROFILE_NAME_RE = /^[a-z0-9][a-z0-9-]{0,31}$/;
|
|
19
|
+
function validateProfileName(name) {
|
|
20
|
+
if (!PROFILE_NAME_RE.test(name)) {
|
|
21
|
+
throw new CLIError(`Invalid profile name "${name}". Must be 1-32 chars, lowercase alphanumeric + hyphens, starting with alphanumeric.`, { code: ErrorCode.PROFILE_NAME_INVALID, category: 'profile' });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function profilePath(name) {
|
|
25
|
+
return resolve(PROFILES_DIR, `${name}.env`);
|
|
26
|
+
}
|
|
27
|
+
function parseEnvFile(content) {
|
|
28
|
+
const vars = {};
|
|
29
|
+
for (const line of content.split('\n')) {
|
|
30
|
+
const m = line.match(/^([^#=]+)=(.*)$/);
|
|
31
|
+
if (m) {
|
|
32
|
+
vars[m[1].trim()] = m[2].trim().replace(/^["']|["']$/g, '');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return vars;
|
|
36
|
+
}
|
|
37
|
+
function readProfileFile(path) {
|
|
38
|
+
if (!existsSync(path))
|
|
39
|
+
return null;
|
|
40
|
+
const vars = parseEnvFile(readFileSync(path, 'utf8'));
|
|
41
|
+
const apiKey = vars['PRODUCTBRAIN_API_KEY'] || '';
|
|
42
|
+
if (!apiKey)
|
|
43
|
+
return null;
|
|
44
|
+
return {
|
|
45
|
+
apiKey,
|
|
46
|
+
siteUrl: vars['CONVEX_SITE_URL'] || undefined,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Auto-migrate legacy ~/.config/productbrain/.env to profiles/default.env.
|
|
51
|
+
* Only runs if legacy file exists AND no profiles directory exists.
|
|
52
|
+
*/
|
|
53
|
+
function autoMigrate() {
|
|
54
|
+
if (existsSync(PROFILES_DIR))
|
|
55
|
+
return false;
|
|
56
|
+
if (!existsSync(LEGACY_ENV_PATH))
|
|
57
|
+
return false;
|
|
58
|
+
mkdirSync(PROFILES_DIR, { recursive: true });
|
|
59
|
+
const content = readFileSync(LEGACY_ENV_PATH, 'utf8');
|
|
60
|
+
writeFileSync(profilePath('default'), content, { mode: 0o600 });
|
|
61
|
+
writeFileSync(ACTIVE_PROFILE_PATH, 'default', { mode: 0o600 });
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
/** List all profile names (sorted). */
|
|
65
|
+
export function listProfiles() {
|
|
66
|
+
autoMigrate();
|
|
67
|
+
if (!existsSync(PROFILES_DIR))
|
|
68
|
+
return [];
|
|
69
|
+
return readdirSync(PROFILES_DIR)
|
|
70
|
+
.filter((f) => f.endsWith('.env'))
|
|
71
|
+
.map((f) => f.replace(/\.env$/, ''))
|
|
72
|
+
.sort();
|
|
73
|
+
}
|
|
74
|
+
/** Get the active profile name. */
|
|
75
|
+
export function getActiveProfile() {
|
|
76
|
+
// PB_PROFILE env var takes precedence
|
|
77
|
+
const envProfile = process.env.PB_PROFILE?.trim();
|
|
78
|
+
if (envProfile)
|
|
79
|
+
return envProfile;
|
|
80
|
+
if (existsSync(ACTIVE_PROFILE_PATH)) {
|
|
81
|
+
const name = readFileSync(ACTIVE_PROFILE_PATH, 'utf8').trim();
|
|
82
|
+
if (name)
|
|
83
|
+
return name;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
/** Create a new profile. */
|
|
88
|
+
export function createProfile(name, apiKey, siteUrl) {
|
|
89
|
+
validateProfileName(name);
|
|
90
|
+
if (existsSync(profilePath(name))) {
|
|
91
|
+
throw new CLIError(`Profile "${name}" already exists.`, { code: ErrorCode.PROFILE_ALREADY_EXISTS, category: 'profile' });
|
|
92
|
+
}
|
|
93
|
+
mkdirSync(PROFILES_DIR, { recursive: true });
|
|
94
|
+
const lines = [
|
|
95
|
+
`# Product Brain CLI profile: ${name}`,
|
|
96
|
+
`PRODUCTBRAIN_API_KEY=${apiKey}`,
|
|
97
|
+
];
|
|
98
|
+
if (siteUrl) {
|
|
99
|
+
lines.push(`CONVEX_SITE_URL=${siteUrl}`);
|
|
100
|
+
}
|
|
101
|
+
lines.push('');
|
|
102
|
+
writeFileSync(profilePath(name), lines.join('\n'), { mode: 0o600 });
|
|
103
|
+
// If this is the first profile, make it active
|
|
104
|
+
if (!existsSync(ACTIVE_PROFILE_PATH)) {
|
|
105
|
+
writeFileSync(ACTIVE_PROFILE_PATH, name, { mode: 0o600 });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Switch the active profile. */
|
|
109
|
+
export function useProfile(name) {
|
|
110
|
+
validateProfileName(name);
|
|
111
|
+
if (!existsSync(profilePath(name))) {
|
|
112
|
+
throw new CLIError(`Profile "${name}" does not exist.`, { code: ErrorCode.PROFILE_NOT_FOUND, category: 'profile' });
|
|
113
|
+
}
|
|
114
|
+
mkdirSync(HOME_CONFIG_DIR, { recursive: true });
|
|
115
|
+
writeFileSync(ACTIVE_PROFILE_PATH, name, { mode: 0o600 });
|
|
116
|
+
}
|
|
117
|
+
/** Delete a profile. Cannot delete the last profile or the active profile. */
|
|
118
|
+
export function deleteProfile(name) {
|
|
119
|
+
validateProfileName(name);
|
|
120
|
+
const path = profilePath(name);
|
|
121
|
+
if (!existsSync(path)) {
|
|
122
|
+
throw new CLIError(`Profile "${name}" does not exist.`, { code: ErrorCode.PROFILE_NOT_FOUND, category: 'profile' });
|
|
123
|
+
}
|
|
124
|
+
const profiles = listProfiles();
|
|
125
|
+
if (profiles.length <= 1) {
|
|
126
|
+
throw new CLIError(`Cannot delete the last profile "${name}".`, { code: ErrorCode.PROFILE_IS_LAST, category: 'profile' });
|
|
127
|
+
}
|
|
128
|
+
const active = getActiveProfile();
|
|
129
|
+
if (active === name) {
|
|
130
|
+
throw new CLIError(`Cannot delete the active profile "${name}". Switch to another profile first.`, { code: ErrorCode.PROFILE_IS_ACTIVE, category: 'profile', guidance: 'Run `pb profile use <other-profile>` first.' });
|
|
131
|
+
}
|
|
132
|
+
unlinkSync(path);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve config from the active profile.
|
|
136
|
+
* Resolution order: PB_PROFILE env > active-profile file > "default" > legacy .env
|
|
137
|
+
* Returns null if no profile or config is available.
|
|
138
|
+
*/
|
|
139
|
+
export function resolveProfileConfig() {
|
|
140
|
+
autoMigrate();
|
|
141
|
+
// 1. Check PB_PROFILE env var
|
|
142
|
+
const envProfile = process.env.PB_PROFILE?.trim();
|
|
143
|
+
if (envProfile) {
|
|
144
|
+
const config = readProfileFile(profilePath(envProfile));
|
|
145
|
+
if (config)
|
|
146
|
+
return config;
|
|
147
|
+
}
|
|
148
|
+
// 2. Check active-profile file
|
|
149
|
+
if (existsSync(ACTIVE_PROFILE_PATH)) {
|
|
150
|
+
const name = readFileSync(ACTIVE_PROFILE_PATH, 'utf8').trim();
|
|
151
|
+
if (name) {
|
|
152
|
+
const config = readProfileFile(profilePath(name));
|
|
153
|
+
if (config)
|
|
154
|
+
return config;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// 3. Check "default" profile
|
|
158
|
+
{
|
|
159
|
+
const config = readProfileFile(profilePath('default'));
|
|
160
|
+
if (config)
|
|
161
|
+
return config;
|
|
162
|
+
}
|
|
163
|
+
// 4. Fall back to legacy .env
|
|
164
|
+
{
|
|
165
|
+
const config = readProfileFile(LEGACY_ENV_PATH);
|
|
166
|
+
if (config)
|
|
167
|
+
return config;
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
// Exported for testing
|
|
172
|
+
export { PROFILES_DIR, ACTIVE_PROFILE_PATH, LEGACY_ENV_PATH, HOME_CONFIG_DIR };
|
|
173
|
+
//# sourceMappingURL=profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/lib/profiles.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACjG,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;AACtE,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC;AAC1D,MAAM,mBAAmB,GAAG,OAAO,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAAC;AACvE,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAOpD,SAAS,mBAAmB,CAAC,IAAY;IACvC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,QAAQ,CAChB,yBAAyB,IAAI,sFAAsF,EACnH,EAAE,IAAI,EAAE,SAAS,CAAC,oBAAoB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,OAAO,CAAC,YAAY,EAAE,GAAG,IAAI,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,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,EAAE,CAAC;YACN,IAAI,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;QAC9D,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,IAAI,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO;QACL,MAAM;QACN,OAAO,EAAE,IAAI,CAAC,iBAAiB,CAAC,IAAI,SAAS;KAC9C,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW;IAClB,IAAI,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC;QAAE,OAAO,KAAK,CAAC;IAE/C,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACtD,aAAa,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAChE,aAAa,CAAC,mBAAmB,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,YAAY;IAC1B,WAAW,EAAE,CAAC;IACd,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,WAAW,CAAC,YAAY,CAAC;SAC7B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SACjC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;SACnC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,gBAAgB;IAC9B,sCAAsC;IACtC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,IAAI,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC;IACxB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4BAA4B;AAC5B,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAc,EAAE,OAAgB;IAC1E,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAE1B,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,QAAQ,CAAC,YAAY,IAAI,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,sBAAsB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3H,CAAC;IAED,SAAS,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,KAAK,GAAG;QACZ,gCAAgC,IAAI,EAAE;QACtC,wBAAwB,MAAM,EAAE;KACjC,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAEpE,+CAA+C;IAC/C,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACrC,aAAa,CAAC,mBAAmB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,iCAAiC;AACjC,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAE1B,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,QAAQ,CAAC,YAAY,IAAI,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtH,CAAC;IAED,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,aAAa,CAAC,mBAAmB,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,QAAQ,CAAC,YAAY,IAAI,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IACtH,CAAC;IAED,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,QAAQ,CAAC,mCAAmC,IAAI,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC5H,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,QAAQ,CAAC,qCAAqC,IAAI,qCAAqC,EAAE,EAAE,IAAI,EAAE,SAAS,CAAC,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,6CAA6C,EAAE,CAAC,CAAC;IAC1N,CAAC;IAED,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB;IAClC,WAAW,EAAE,CAAC;IAEd,8BAA8B;IAC9B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;QACxD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,+BAA+B;IAC/B,IAAI,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,YAAY,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;YAClD,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;QAC5B,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,CAAC;QACC,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC;QACvD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,8BAA8B;IAC9B,CAAC;QACC,MAAM,MAAM,GAAG,eAAe,CAAC,eAAe,CAAC,CAAC;QAChD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uBAAuB;AACvB,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/lib/runner.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export declare function setOutputMode(mode: 'auto' | 'json' | 'pretty'): void;
|
|
|
14
14
|
export declare function getOutputMode(): 'auto' | 'json' | 'pretty';
|
|
15
15
|
/** Returns true if the current output mode resolves to JSON. */
|
|
16
16
|
export declare function isJsonMode(): boolean;
|
|
17
|
+
export declare function setQuietMode(quiet: boolean): void;
|
|
18
|
+
export declare function isQuietMode(): boolean;
|
|
17
19
|
export interface RunCliCommandOptions<T> {
|
|
18
20
|
/** The async function that performs the MCP call and returns data. */
|
|
19
21
|
fn: () => Promise<T>;
|
package/dist/lib/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,IAAI,CAEpE;AAED,wBAAgB,aAAa,IAAI,MAAM,GAAG,MAAM,GAAG,QAAQ,CAE1D;AAED,gEAAgE;AAChE,wBAAgB,UAAU,IAAI,OAAO,CAKpC;AASD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEjD;AAED,wBAAgB,WAAW,IAAI,OAAO,CAIrC;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,sEAAsE;IACtE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;IACrB,kDAAkD;IAClD,YAAY,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,CAAC;CACnC;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCtF"}
|
package/dist/lib/runner.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* Chain: DEC-299 (JSON-default), STD-65 (agent responses: structured, parseable, minimal)
|
|
12
12
|
*/
|
|
13
13
|
import { stripConvexInternals } from './strip.js';
|
|
14
|
+
import { CLIError } from './errors.js';
|
|
14
15
|
/**
|
|
15
16
|
* Global output mode — set by the CLI entry point when --json or --pretty flags are parsed.
|
|
16
17
|
* 'auto' = detect via TTY; 'json' = force JSON; 'pretty' = force human.
|
|
@@ -31,6 +32,21 @@ export function isJsonMode() {
|
|
|
31
32
|
// auto: non-TTY (piped) → JSON, TTY → human
|
|
32
33
|
return !process.stdout.isTTY;
|
|
33
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Quiet mode — suppresses non-essential output (banners, hints, progress).
|
|
37
|
+
* Only the essential result (data line or error) is shown.
|
|
38
|
+
* WP-302 Slice 1.
|
|
39
|
+
*/
|
|
40
|
+
let quietMode = false;
|
|
41
|
+
export function setQuietMode(quiet) {
|
|
42
|
+
quietMode = quiet;
|
|
43
|
+
}
|
|
44
|
+
export function isQuietMode() {
|
|
45
|
+
// JSON mode is inherently quiet — no decorative output needed
|
|
46
|
+
if (isJsonMode())
|
|
47
|
+
return true;
|
|
48
|
+
return quietMode;
|
|
49
|
+
}
|
|
34
50
|
/**
|
|
35
51
|
* Execute a CLI command with unified output handling.
|
|
36
52
|
*
|
|
@@ -52,12 +68,25 @@ export async function runCliCommand(options) {
|
|
|
52
68
|
}
|
|
53
69
|
}
|
|
54
70
|
catch (err) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
if (err instanceof CLIError) {
|
|
72
|
+
if (json) {
|
|
73
|
+
process.stderr.write(JSON.stringify(err.toJSON()) + '\n');
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
process.stderr.write(err.message + '\n');
|
|
77
|
+
if (err.guidance) {
|
|
78
|
+
process.stderr.write(err.guidance + '\n');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
58
81
|
}
|
|
59
82
|
else {
|
|
60
|
-
|
|
83
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
84
|
+
if (json) {
|
|
85
|
+
process.stderr.write(JSON.stringify({ error: message, code: 'INTERNAL', category: 'internal' }) + '\n');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
process.stderr.write(message + '\n');
|
|
89
|
+
}
|
|
61
90
|
}
|
|
62
91
|
process.exit(1);
|
|
63
92
|
}
|
package/dist/lib/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/lib/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI voice and style — centralized output formatting for Product Brain CLI.
|
|
3
|
+
* WP-302 Slice 1: Brand Voice + --quiet.
|
|
4
|
+
*
|
|
5
|
+
* Design: "instrument panel" — clear status, clear next action.
|
|
6
|
+
* Tone: confident, concise, helpful. Not chatty. Not corporate.
|
|
7
|
+
*
|
|
8
|
+
* All color output respects NO_COLOR env (https://no-color.org/) and TTY detection.
|
|
9
|
+
* Quiet mode suppresses banners, hints, and progress — only essential results show.
|
|
10
|
+
*/
|
|
11
|
+
/** Returns true if the terminal supports color output. */
|
|
12
|
+
export declare function supportsColor(): boolean;
|
|
13
|
+
export declare const green: (s: string) => string;
|
|
14
|
+
export declare const red: (s: string) => string;
|
|
15
|
+
export declare const yellow: (s: string) => string;
|
|
16
|
+
export declare const cyan: (s: string) => string;
|
|
17
|
+
export declare const dim: (s: string) => string;
|
|
18
|
+
export declare const bold: (s: string) => string;
|
|
19
|
+
export declare const icons: {
|
|
20
|
+
readonly pass: "✓";
|
|
21
|
+
readonly fail: "✗";
|
|
22
|
+
readonly warn: "⚠";
|
|
23
|
+
readonly arrow: "→";
|
|
24
|
+
readonly dot: "·";
|
|
25
|
+
};
|
|
26
|
+
export declare const copy: {
|
|
27
|
+
readonly captured: "Captured.";
|
|
28
|
+
readonly promoted: "Promoted.";
|
|
29
|
+
readonly linked: "Linked.";
|
|
30
|
+
readonly updated: "Updated.";
|
|
31
|
+
readonly sessionStarted: "Session started.";
|
|
32
|
+
readonly sessionClosed: "Session closed.";
|
|
33
|
+
readonly noSession: "No active session. Run `pb session start` first.";
|
|
34
|
+
readonly sessionRequired: "Write access requires a tracked session (DEC-9).";
|
|
35
|
+
readonly notFound: "Not found.";
|
|
36
|
+
readonly authFailed: "Authentication failed.";
|
|
37
|
+
readonly nextOrient: "Next: pb orient -b";
|
|
38
|
+
readonly nextCapture: "Next: pb capture \"...\"";
|
|
39
|
+
readonly nextGet: (entryId: string) => string;
|
|
40
|
+
readonly nextFields: (collection: string) => string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Print a command banner. Suppressed in quiet mode.
|
|
44
|
+
* Example: "Product Brain — Doctor"
|
|
45
|
+
*/
|
|
46
|
+
export declare function banner(title: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Print an actionable hint line. Suppressed in quiet mode.
|
|
49
|
+
* Example: " Hint: Run `pb orient -b` to see your workspace."
|
|
50
|
+
*/
|
|
51
|
+
export declare function hint(text: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Print a progress line (e.g. "Classifying..."). Suppressed in quiet mode.
|
|
54
|
+
*/
|
|
55
|
+
export declare function progress(text: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Format a section heading — bold cyan text.
|
|
58
|
+
*/
|
|
59
|
+
export declare function heading(text: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Format a check result line for doctor-style output.
|
|
62
|
+
* Uses colored icons for pass/fail/warn.
|
|
63
|
+
*/
|
|
64
|
+
export declare function formatCheck(status: 'pass' | 'fail' | 'warn', label: string, detail: string): string;
|
|
65
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/lib/style.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,0DAA0D;AAC1D,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAMD,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,KAAG,MAAuD,CAAC;AAC1F,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,KAAG,MAAuD,CAAC;AACxF,eAAO,MAAM,MAAM,GAAI,GAAG,MAAM,KAAG,MAAuD,CAAC;AAC3F,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,KAAG,MAAuD,CAAC;AACzF,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,KAAG,MAAsD,CAAC;AACvF,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,KAAG,MAAsD,CAAC;AAMxF,eAAO,MAAM,KAAK;;;;;;CAMR,CAAC;AAMX,eAAO,MAAM,IAAI;;;;;;;;;;;;;gCAkBI,MAAM;sCACA,MAAM;CACvB,CAAC;AAMX;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAG1C;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAGvC;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG3C;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASnG"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI voice and style — centralized output formatting for Product Brain CLI.
|
|
3
|
+
* WP-302 Slice 1: Brand Voice + --quiet.
|
|
4
|
+
*
|
|
5
|
+
* Design: "instrument panel" — clear status, clear next action.
|
|
6
|
+
* Tone: confident, concise, helpful. Not chatty. Not corporate.
|
|
7
|
+
*
|
|
8
|
+
* All color output respects NO_COLOR env (https://no-color.org/) and TTY detection.
|
|
9
|
+
* Quiet mode suppresses banners, hints, and progress — only essential results show.
|
|
10
|
+
*/
|
|
11
|
+
import { isQuietMode } from './runner.js';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Color support detection
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/** Returns true if the terminal supports color output. */
|
|
16
|
+
export function supportsColor() {
|
|
17
|
+
return Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
|
|
18
|
+
}
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Color helpers — degrade gracefully when NO_COLOR is set or not a TTY
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
export const green = (s) => (supportsColor() ? `\x1b[32m${s}\x1b[0m` : s);
|
|
23
|
+
export const red = (s) => (supportsColor() ? `\x1b[31m${s}\x1b[0m` : s);
|
|
24
|
+
export const yellow = (s) => (supportsColor() ? `\x1b[33m${s}\x1b[0m` : s);
|
|
25
|
+
export const cyan = (s) => (supportsColor() ? `\x1b[36m${s}\x1b[0m` : s);
|
|
26
|
+
export const dim = (s) => (supportsColor() ? `\x1b[2m${s}\x1b[0m` : s);
|
|
27
|
+
export const bold = (s) => (supportsColor() ? `\x1b[1m${s}\x1b[0m` : s);
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Status icons
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
export const icons = {
|
|
32
|
+
pass: '\u2713', // checkmark
|
|
33
|
+
fail: '\u2717', // x
|
|
34
|
+
warn: '\u26A0', // warning triangle
|
|
35
|
+
arrow: '\u2192', // right arrow
|
|
36
|
+
dot: '\u00B7', // middle dot
|
|
37
|
+
};
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// Copy constants — instrument panel voice
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
export const copy = {
|
|
42
|
+
// Success preambles
|
|
43
|
+
captured: 'Captured.',
|
|
44
|
+
promoted: 'Promoted.',
|
|
45
|
+
linked: 'Linked.',
|
|
46
|
+
updated: 'Updated.',
|
|
47
|
+
sessionStarted: 'Session started.',
|
|
48
|
+
sessionClosed: 'Session closed.',
|
|
49
|
+
// Error preambles
|
|
50
|
+
noSession: 'No active session. Run `pb session start` first.',
|
|
51
|
+
sessionRequired: 'Write access requires a tracked session (DEC-9).',
|
|
52
|
+
notFound: 'Not found.',
|
|
53
|
+
authFailed: 'Authentication failed.',
|
|
54
|
+
// Next-step prompts
|
|
55
|
+
nextOrient: 'Next: pb orient -b',
|
|
56
|
+
nextCapture: 'Next: pb capture "..."',
|
|
57
|
+
nextGet: (entryId) => `View: pb get ${entryId}`,
|
|
58
|
+
nextFields: (collection) => `Fields: pb fields ${collection}`,
|
|
59
|
+
};
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Structured output helpers
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Print a command banner. Suppressed in quiet mode.
|
|
65
|
+
* Example: "Product Brain — Doctor"
|
|
66
|
+
*/
|
|
67
|
+
export function banner(title) {
|
|
68
|
+
if (isQuietMode())
|
|
69
|
+
return;
|
|
70
|
+
process.stdout.write(`\n${bold(`Product Brain — ${title}`)}\n\n`);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Print an actionable hint line. Suppressed in quiet mode.
|
|
74
|
+
* Example: " Hint: Run `pb orient -b` to see your workspace."
|
|
75
|
+
*/
|
|
76
|
+
export function hint(text) {
|
|
77
|
+
if (isQuietMode())
|
|
78
|
+
return;
|
|
79
|
+
process.stdout.write(` ${dim(text)}\n`);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Print a progress line (e.g. "Classifying..."). Suppressed in quiet mode.
|
|
83
|
+
*/
|
|
84
|
+
export function progress(text) {
|
|
85
|
+
if (isQuietMode())
|
|
86
|
+
return;
|
|
87
|
+
process.stdout.write(`${text}\n`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Format a section heading — bold cyan text.
|
|
91
|
+
*/
|
|
92
|
+
export function heading(text) {
|
|
93
|
+
return bold(cyan(text));
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Format a check result line for doctor-style output.
|
|
97
|
+
* Uses colored icons for pass/fail/warn.
|
|
98
|
+
*/
|
|
99
|
+
export function formatCheck(status, label, detail) {
|
|
100
|
+
const icon = status === 'pass'
|
|
101
|
+
? green(icons.pass)
|
|
102
|
+
: status === 'fail'
|
|
103
|
+
? red(icons.fail)
|
|
104
|
+
: yellow(icons.warn);
|
|
105
|
+
const paddedLabel = label.padEnd(16);
|
|
106
|
+
return `${icon} ${paddedLabel}${detail}`;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/lib/style.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.test.d.ts","sourceRoot":"","sources":["../../src/lib/style.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|