@baselineos/cli 0.1.0

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/src/badge.ts ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * "Baseline-governed" Trust Signal Badge Generator
3
+ *
4
+ * Generates a machine-readable trust signal that can be embedded
5
+ * in applications, documents, or registries to indicate that
6
+ * AI operations are governed by Baseline Protocol.
7
+ */
8
+
9
+ import { createHash } from 'node:crypto';
10
+
11
+ export interface BadgeData {
12
+ version: string;
13
+ governedBy: 'baseline-protocol';
14
+ standards: string[];
15
+ verificationHash: string;
16
+ issuedAt: string;
17
+ expiresAt: string;
18
+ issuer: string;
19
+ subject: string;
20
+ }
21
+
22
+ export interface BadgeOptions {
23
+ subject: string;
24
+ issuer?: string;
25
+ standards?: string[];
26
+ validityDays?: number;
27
+ verificationHash?: string;
28
+ }
29
+
30
+ export function generateBadge(options: BadgeOptions): BadgeData {
31
+ const now = new Date();
32
+ const validityDays = options.validityDays ?? 90;
33
+ const expiresAt = new Date(now.getTime() + validityDays * 86_400_000);
34
+
35
+ const hashInput = [
36
+ options.subject,
37
+ options.issuer ?? 'self',
38
+ ...(options.standards ?? []),
39
+ now.toISOString(),
40
+ ].join('|');
41
+
42
+ const verificationHash = options.verificationHash ??
43
+ createHash('sha256').update(hashInput).digest('hex').slice(0, 32);
44
+
45
+ return {
46
+ version: '1.0.0',
47
+ governedBy: 'baseline-protocol',
48
+ standards: options.standards ?? [],
49
+ verificationHash,
50
+ issuedAt: now.toISOString(),
51
+ expiresAt: expiresAt.toISOString(),
52
+ issuer: options.issuer ?? 'self',
53
+ subject: options.subject,
54
+ };
55
+ }
56
+
57
+ export function validateBadge(badge: BadgeData): { valid: boolean; reason?: string } {
58
+ if (badge.governedBy !== 'baseline-protocol') {
59
+ return { valid: false, reason: 'Not a Baseline Protocol badge' };
60
+ }
61
+
62
+ if (!badge.verificationHash || badge.verificationHash.length < 16) {
63
+ return { valid: false, reason: 'Invalid verification hash' };
64
+ }
65
+
66
+ const now = new Date();
67
+ if (new Date(badge.expiresAt) < now) {
68
+ return { valid: false, reason: 'Badge has expired' };
69
+ }
70
+
71
+ if (!badge.subject) {
72
+ return { valid: false, reason: 'Badge has no subject' };
73
+ }
74
+
75
+ return { valid: true };
76
+ }
77
+
78
+ export function formatBadgeText(badge: BadgeData): string {
79
+ const lines = [
80
+ `Baseline-Governed`,
81
+ `Subject: ${badge.subject}`,
82
+ `Standards: ${badge.standards.length > 0 ? badge.standards.join(', ') : 'none specified'}`,
83
+ `Issued: ${badge.issuedAt.split('T')[0]}`,
84
+ `Expires: ${badge.expiresAt.split('T')[0]}`,
85
+ `Hash: ${badge.verificationHash}`,
86
+ ];
87
+ return lines.join('\n');
88
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,314 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Baseline Protocol CLI
5
+ * Entry point for the `baseline` command.
6
+ */
7
+
8
+ import { BaselineLangSystem } from '@baselineos/lang';
9
+ import { BaselineFrameSystem } from '@baselineos/frame';
10
+ import { BaselineStudioSystem } from '@baselineos/studio';
11
+ import { BaselineGovernSystem } from '@baselineos/govern';
12
+ import { BaselineExperienceSystem } from '@baselineos/experience';
13
+ import { BaselineAutonomySystem } from '@baselineos/autonomy';
14
+ import { BaselinePersonaEngine } from '@baselineos/persona';
15
+ import { BaselineCommandSystem } from './commands.js';
16
+ import { runVerify } from './verify.js';
17
+ import type { VerifyOptions } from './verify.js';
18
+ import { createInterface } from 'node:readline/promises';
19
+ import { stdin as input, stdout as output } from 'node:process';
20
+
21
+ const VERSION = '0.1.0';
22
+
23
+ export function buildCommandLine(args: string[]): string {
24
+ const raw = args.join(' ').trim();
25
+ if (!raw) return '';
26
+ return raw.startsWith('--') ? raw : `--${raw}`;
27
+ }
28
+
29
+ async function main(): Promise<void> {
30
+ const args = process.argv.slice(2);
31
+ const command = args[0];
32
+
33
+ switch (command) {
34
+ case '--help':
35
+ case '-h':
36
+ case 'help':
37
+ case undefined:
38
+ showStartScreen();
39
+ showHelp();
40
+ break;
41
+ case 'status':
42
+ case '--status':
43
+ showStatus();
44
+ break;
45
+ case 'init': {
46
+ const cmdSystem = new BaselineCommandSystem();
47
+ const commandLine = buildCommandLine(['--init', ...args.slice(1), '--write-config']);
48
+ const result = await cmdSystem.executeCommand(commandLine);
49
+ if (!result.success) {
50
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
51
+ process.exit(1);
52
+ }
53
+ console.log(JSON.stringify(result, null, 2));
54
+ break;
55
+ }
56
+ case 'version':
57
+ case '--version':
58
+ case '-v':
59
+ console.log(`baseline v${VERSION}`);
60
+ break;
61
+ case 'onboard':
62
+ case 'onboarding': {
63
+ const cmdSystem = new BaselineCommandSystem();
64
+ const rawArgs = args.slice(1).filter((arg) => arg !== '--interactive');
65
+ const interactive = args.length <= 1 || args.includes('--interactive');
66
+
67
+ let result;
68
+ if (interactive) {
69
+ showStartScreen();
70
+ const options = await promptOnboardingOptions();
71
+ result = await cmdSystem.executeOnboarding(options);
72
+ } else {
73
+ const commandLine = buildCommandLine(['--onboard', ...rawArgs]);
74
+ result = await cmdSystem.executeCommand(commandLine);
75
+ }
76
+ if (!result.success) {
77
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
78
+ process.exit(1);
79
+ }
80
+ console.log(JSON.stringify(result, null, 2));
81
+ break;
82
+ }
83
+ case 'experience': {
84
+ const cmdSystem = new BaselineCommandSystem();
85
+ const rawArgs = args.slice(1);
86
+ const commandLine = buildCommandLine(['--experience', ...rawArgs]);
87
+ const result = await cmdSystem.executeCommand(commandLine);
88
+ if (!result.success) {
89
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
90
+ process.exit(1);
91
+ }
92
+ console.log(JSON.stringify(result, null, 2));
93
+ break;
94
+ }
95
+ case 'serve': {
96
+ const cmdSystem = new BaselineCommandSystem();
97
+ const commandLine = buildCommandLine(['--serve', ...args.slice(1)]);
98
+ const result = await cmdSystem.executeCommand(commandLine);
99
+ if (!result.success) {
100
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
101
+ process.exit(1);
102
+ }
103
+ // Do not print JSON to stdout; MCP uses stdout for protocol.
104
+ break;
105
+ }
106
+ case 'verify': {
107
+ const verifyOpts: VerifyOptions = {};
108
+ for (let i = 1; i < args.length; i++) {
109
+ if (args[i] === '--policy' && args[i + 1]) { verifyOpts.policyPath = args[++i]; }
110
+ else if (args[i] === '--evidence' && args[i + 1]) { verifyOpts.evidencePath = args[++i]; }
111
+ else if (args[i] === '--audit-trail' && args[i + 1]) { verifyOpts.auditTrailPath = args[++i]; }
112
+ }
113
+ const verifyResult = await runVerify(verifyOpts);
114
+ console.log(JSON.stringify(verifyResult, null, 2));
115
+ if (!verifyResult.success) process.exit(1);
116
+ break;
117
+ }
118
+ case 'doctor': {
119
+ const cmdSystem = new BaselineCommandSystem();
120
+ const commandLine = buildCommandLine(['--doctor', ...args.slice(1)]);
121
+ const result = await cmdSystem.executeCommand(commandLine);
122
+ if (!result.success) {
123
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
124
+ process.exit(1);
125
+ }
126
+ console.log(JSON.stringify(result, null, 2));
127
+ break;
128
+ }
129
+ default: {
130
+ const cmdSystem = new BaselineCommandSystem();
131
+ const commandLine = buildCommandLine(args);
132
+ if (!commandLine) {
133
+ showHelp();
134
+ return;
135
+ }
136
+ const result = await cmdSystem.executeCommand(commandLine);
137
+ if (!result.success) {
138
+ console.error(`Error: ${result.error ?? 'Unknown error'}`);
139
+ process.exit(1);
140
+ }
141
+ console.log(JSON.stringify(result, null, 2));
142
+ break;
143
+ }
144
+ }
145
+ }
146
+
147
+ function showHelp(): void {
148
+ console.log(`
149
+ Baseline Protocol CLI v${VERSION}
150
+
151
+ Usage: baseline <command> [options]
152
+
153
+ Commands:
154
+ help Show this help message
155
+ status Show status of all protocol layers
156
+ onboard Run the guided onboarding flow
157
+ experience Run immersive onboarding experiences
158
+ init Initialize Baseline and write config
159
+ run Run the full Baseline workflow
160
+ index Index docs or context for retrieval
161
+ verify Verify policy compliance and evidence integrity
162
+ serve Start the Baseline MCP server
163
+ agents Show agent registry status
164
+ config Configure Baseline preferences
165
+ doctor Run diagnostics for Baseline readiness
166
+ version Show version information
167
+
168
+ Layer Commands:
169
+ --baseline Run full Baseline Protocol workflow
170
+ --baseline-lang Run Language layer only
171
+ --baseline-frame Run Frame layer only
172
+ --baseline-studio Run Studio layer only
173
+ --baseline-govern Run Governance layer only
174
+ --init Initialize a new Baseline project
175
+ --run Run the full workflow
176
+ --status Show system status
177
+ --help Show help information
178
+ `);
179
+ }
180
+
181
+ function showStartScreen(): void {
182
+ console.log(`
183
+ ██████╗ █████╗ ███████╗███████╗██╗ ██╗███╗ ██╗███████╗
184
+ ██╔══██╗██╔══██╗██╔════╝██╔════╝██║ ██║████╗ ██║██╔════╝
185
+ ██████╔╝███████║███████╗█████╗ ██║ ██║██╔██╗ ██║█████╗
186
+ ██╔══██╗██╔══██║╚════██║██╔══╝ ██║ ██║██║╚██╗██║██╔══╝
187
+ ██████╔╝██║ ██║███████║███████╗███████╗██║██║ ╚████║███████╗
188
+ ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝╚══════╝
189
+
190
+ Baseline Protocol • Guided Onboarding
191
+ `);
192
+ }
193
+
194
+ async function promptOnboardingOptions(): Promise<Record<string, unknown>> {
195
+ const rl = createInterface({ input, output });
196
+ try {
197
+ const nameInput = (await rl.question('Your name (default: User): ')).trim();
198
+ const roleInput = (await rl.question('Role (default: Operator): ')).trim();
199
+ const emailInput = (await rl.question('Email (optional): ')).trim();
200
+ const companyInput = (await rl.question('Company name (default: Acme Corp): ')).trim();
201
+ const languageInput = (await rl.question(
202
+ 'Preferred language (en/es/fr/de/ja/zh/ko/ar/hi/pt, default: en): '
203
+ )).trim();
204
+ const learningStyleInput = (await rl.question(
205
+ 'Learning style (visual/auditory/kinesthetic/reading, default: visual): '
206
+ )).trim();
207
+ const paceInput = (await rl.question(
208
+ 'Learning pace (slow/moderate/fast/lightning, default: moderate): '
209
+ )).trim();
210
+ const focusInput = (await rl.question(
211
+ 'Learning focus (practical/theoretical/mixed, default: practical): '
212
+ )).trim();
213
+ const learningPathInput = (await rl.question(
214
+ 'Learning path (standard/accelerated/hands-on/theoretical, default: standard): '
215
+ )).trim();
216
+ const teamInput =
217
+ (await rl.question('Team name (optional, press enter to skip): ')).trim();
218
+ const projectInput =
219
+ (await rl.question('Project name (optional, press enter to skip): ')).trim();
220
+ const contextInput = (await rl.question(`Context path (default: ${process.cwd()}): `)).trim();
221
+ const modeInput = (await rl.question(
222
+ 'Mode (development/staging/production, default: development): '
223
+ ))
224
+ .trim()
225
+ .toLowerCase();
226
+ const runWorkflow =
227
+ (await rl.question('Run full workflow now? (Y/n): ')).trim().toLowerCase();
228
+ const skipWorkflow = runWorkflow === 'n' || runWorkflow === 'no';
229
+
230
+ return {
231
+ name: nameInput || undefined,
232
+ role: roleInput || undefined,
233
+ email: emailInput || undefined,
234
+ company: companyInput || undefined,
235
+ language: languageInput || undefined,
236
+ 'learning-style': learningStyleInput || undefined,
237
+ pace: paceInput || undefined,
238
+ focus: focusInput || undefined,
239
+ 'learning-path': learningPathInput || undefined,
240
+ team: teamInput || undefined,
241
+ project: projectInput || undefined,
242
+ context: contextInput || undefined,
243
+ mode: modeInput || undefined,
244
+ 'skip-workflow': skipWorkflow,
245
+ };
246
+ } finally {
247
+ rl.close();
248
+ }
249
+ }
250
+
251
+ function showStatus(): void {
252
+ console.log(`\nBaseline Protocol v${VERSION}\n`);
253
+ console.log('Layer Status:');
254
+ console.log('-'.repeat(60));
255
+
256
+ const safeLine = (label: string, fn: () => string) => {
257
+ try {
258
+ console.log(` ${label.padEnd(10)}: ${fn()}`);
259
+ } catch (err) {
260
+ const msg = err instanceof Error ? err.message : String(err);
261
+ console.log(` ${label.padEnd(10)}: error (${msg})`);
262
+ }
263
+ };
264
+
265
+ safeLine('Lang', () => {
266
+ const lang = new BaselineLangSystem();
267
+ const langCommands = lang.getCommandRegistry().size;
268
+ return `initialized (${langCommands} commands registered)`;
269
+ });
270
+
271
+ safeLine('Frame', () => {
272
+ const frame = new BaselineFrameSystem();
273
+ const frameStatus = frame.getStatus();
274
+ return `${frameStatus.initialized ? 'initialized' : 'not initialized'} (mode: ${frameStatus.currentMode?.name ?? 'default'})`;
275
+ });
276
+
277
+ safeLine('Studio', () => {
278
+ const studio = new BaselineStudioSystem();
279
+ const studioStatus = studio.getStatus() as { system: string };
280
+ return `initialized (${studioStatus.system})`;
281
+ });
282
+
283
+ safeLine('Govern', () => {
284
+ const govern = new BaselineGovernSystem();
285
+ const governStatus = govern.getStatus();
286
+ return `${governStatus.initialized ? 'initialized' : 'not initialized'} (${governStatus.policies} policies)`;
287
+ });
288
+
289
+ safeLine('Experience', () => {
290
+ const experience = new BaselineExperienceSystem();
291
+ const expStatus = experience.getStatus();
292
+ return `${expStatus.initialized ? 'initialized' : 'not initialized'}`;
293
+ });
294
+
295
+ safeLine('Autonomy', () => {
296
+ const autonomy = new BaselineAutonomySystem();
297
+ const autoStatus = autonomy.getSystemStatus();
298
+ return `${autoStatus.status} (${autoStatus.agentCount} agents)`;
299
+ });
300
+
301
+ safeLine('Persona', () => {
302
+ const persona = new BaselinePersonaEngine();
303
+ const personaStatus = persona.getStatus();
304
+ return `${personaStatus.initialized ? 'initialized' : 'not initialized'} (${personaStatus.totalPersonas} personas)`;
305
+ });
306
+
307
+ console.log('');
308
+ console.log('All systems operational.');
309
+ }
310
+
311
+ main().catch((err: unknown) => {
312
+ console.error('Fatal error:', err instanceof Error ? err.message : String(err));
313
+ process.exit(1);
314
+ });