@cpretzinger/boss-claude 1.0.0 ā 1.0.2
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 +304 -1
- package/bin/boss-claude.js +1138 -0
- package/bin/commands/mode.js +250 -0
- package/bin/onyx-guard.js +259 -0
- package/bin/onyx-guard.sh +251 -0
- package/bin/prompts.js +284 -0
- package/bin/rollback.js +85 -0
- package/bin/setup-wizard.js +492 -0
- package/config/.env.example +17 -0
- package/lib/README.md +83 -0
- package/lib/agent-logger.js +61 -0
- package/lib/agents/memory-engineers/github-memory-engineer.js +251 -0
- package/lib/agents/memory-engineers/postgres-memory-engineer.js +633 -0
- package/lib/agents/memory-engineers/qdrant-memory-engineer.js +358 -0
- package/lib/agents/memory-engineers/redis-memory-engineer.js +383 -0
- package/lib/agents/memory-supervisor.js +526 -0
- package/lib/agents/registry.js +135 -0
- package/lib/auto-monitor.js +131 -0
- package/lib/checkpoint-hook.js +112 -0
- package/lib/checkpoint.js +319 -0
- package/lib/commentator.js +213 -0
- package/lib/context-scribe.js +120 -0
- package/lib/delegation-strategies.js +326 -0
- package/lib/hierarchy-validator.js +643 -0
- package/lib/index.js +15 -0
- package/lib/init-with-mode.js +261 -0
- package/lib/init.js +44 -6
- package/lib/memory-result-aggregator.js +252 -0
- package/lib/memory.js +35 -7
- package/lib/mode-enforcer.js +473 -0
- package/lib/onyx-banner.js +169 -0
- package/lib/onyx-identity.js +214 -0
- package/lib/onyx-monitor.js +381 -0
- package/lib/onyx-reminder.js +188 -0
- package/lib/onyx-tool-interceptor.js +341 -0
- package/lib/onyx-wrapper.js +315 -0
- package/lib/orchestrator-gate.js +334 -0
- package/lib/output-formatter.js +296 -0
- package/lib/postgres.js +1 -1
- package/lib/prompt-injector.js +220 -0
- package/lib/prompts.js +532 -0
- package/lib/session.js +153 -6
- package/lib/setup/README.md +187 -0
- package/lib/setup/env-manager.js +785 -0
- package/lib/setup/error-recovery.js +630 -0
- package/lib/setup/explain-scopes.js +385 -0
- package/lib/setup/github-instructions.js +333 -0
- package/lib/setup/github-repo.js +254 -0
- package/lib/setup/import-credentials.js +498 -0
- package/lib/setup/index.js +62 -0
- package/lib/setup/init-postgres.js +785 -0
- package/lib/setup/init-redis.js +456 -0
- package/lib/setup/integration-test.js +652 -0
- package/lib/setup/progress.js +357 -0
- package/lib/setup/rollback.js +670 -0
- package/lib/setup/rollback.test.js +452 -0
- package/lib/setup/setup-with-rollback.example.js +351 -0
- package/lib/setup/summary.js +400 -0
- package/lib/setup/test-github-setup.js +10 -0
- package/lib/setup/test-postgres-init.js +98 -0
- package/lib/setup/verify-setup.js +102 -0
- package/lib/task-agent-worker.js +235 -0
- package/lib/token-monitor.js +466 -0
- package/lib/tool-wrapper-integration.js +369 -0
- package/lib/tool-wrapper.js +387 -0
- package/lib/validators/README.md +497 -0
- package/lib/validators/config.js +583 -0
- package/lib/validators/config.test.js +175 -0
- package/lib/validators/github.js +310 -0
- package/lib/validators/github.test.js +61 -0
- package/lib/validators/index.js +15 -0
- package/lib/validators/postgres.js +525 -0
- package/package.json +98 -13
- package/scripts/benchmark-memory.js +433 -0
- package/scripts/check-secrets.sh +12 -0
- package/scripts/fetch-todos.mjs +148 -0
- package/scripts/graceful-shutdown.sh +156 -0
- package/scripts/install-onyx-hooks.js +373 -0
- package/scripts/install.js +119 -18
- package/scripts/redis-monitor.js +284 -0
- package/scripts/redis-setup.js +412 -0
- package/scripts/test-memory-retrieval.js +201 -0
- package/scripts/validate-exports.js +68 -0
- package/scripts/validate-package.js +120 -0
- package/scripts/verify-onyx-deployment.js +309 -0
- package/scripts/verify-redis-deployment.js +354 -0
- package/scripts/verify-redis-init.js +219 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { exec } from 'child_process';
|
|
4
|
+
import { promisify } from 'util';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import os from 'os';
|
|
8
|
+
import dotenv from 'dotenv';
|
|
9
|
+
import chalk from 'chalk';
|
|
10
|
+
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Credential Import System
|
|
15
|
+
* Auto-detects credentials from multiple sources and offers intelligent importing
|
|
16
|
+
*
|
|
17
|
+
* Sources (in priority order):
|
|
18
|
+
* 1. Environment variables (current process)
|
|
19
|
+
* 2. GitHub CLI (gh auth token)
|
|
20
|
+
* 3. Existing .env files (project, user home, common locations)
|
|
21
|
+
* 4. User input (fallback)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// Common .env file locations to scan
|
|
25
|
+
const ENV_SEARCH_PATHS = [
|
|
26
|
+
path.join(process.cwd(), '.env'),
|
|
27
|
+
path.join(process.cwd(), '.env.local'),
|
|
28
|
+
path.join(os.homedir(), '.env'),
|
|
29
|
+
path.join(os.homedir(), 'projects', 'ai-assistant-simple', 'apps', 'web', '.env.local'),
|
|
30
|
+
path.join(os.homedir(), 'projects', 'zara2', '.env'),
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
// Credential definitions
|
|
34
|
+
const CREDENTIALS = {
|
|
35
|
+
REDIS_URL: {
|
|
36
|
+
name: 'Redis URL',
|
|
37
|
+
description: 'Redis connection string for Boss identity and session storage',
|
|
38
|
+
required: true,
|
|
39
|
+
pattern: /^redis:\/\//,
|
|
40
|
+
example: 'redis://default:password@host:port',
|
|
41
|
+
},
|
|
42
|
+
GITHUB_TOKEN: {
|
|
43
|
+
name: 'GitHub Token',
|
|
44
|
+
description: 'GitHub personal access token (needs repo scope)',
|
|
45
|
+
required: true,
|
|
46
|
+
pattern: /^(ghp_|github_pat_)[a-zA-Z0-9_]+$/,
|
|
47
|
+
example: 'ghp_your_token_here',
|
|
48
|
+
},
|
|
49
|
+
GITHUB_OWNER: {
|
|
50
|
+
name: 'GitHub Owner',
|
|
51
|
+
description: 'GitHub username/organization for memory storage',
|
|
52
|
+
required: false,
|
|
53
|
+
pattern: /^[a-zA-Z0-9-]+$/,
|
|
54
|
+
example: 'cpretzinger',
|
|
55
|
+
},
|
|
56
|
+
GITHUB_MEMORY_REPO: {
|
|
57
|
+
name: 'GitHub Memory Repository',
|
|
58
|
+
description: 'Repository name for storing session memories',
|
|
59
|
+
required: false,
|
|
60
|
+
pattern: /^[a-zA-Z0-9-_]+$/,
|
|
61
|
+
example: 'boss-claude-memory',
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Check if GitHub CLI is installed and authenticated
|
|
67
|
+
*/
|
|
68
|
+
async function checkGitHubCLI() {
|
|
69
|
+
try {
|
|
70
|
+
const { stdout } = await execAsync('gh auth status 2>&1');
|
|
71
|
+
if (stdout.includes('Logged in to github.com')) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
} catch (error) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get GitHub token from gh CLI
|
|
82
|
+
*/
|
|
83
|
+
async function getGitHubTokenFromCLI() {
|
|
84
|
+
try {
|
|
85
|
+
const { stdout } = await execAsync('gh auth token');
|
|
86
|
+
const token = stdout.trim();
|
|
87
|
+
if (token && CREDENTIALS.GITHUB_TOKEN.pattern.test(token)) {
|
|
88
|
+
return token;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Get GitHub username from gh CLI
|
|
98
|
+
*/
|
|
99
|
+
async function getGitHubUserFromCLI() {
|
|
100
|
+
try {
|
|
101
|
+
const { stdout } = await execAsync('gh api user --jq .login');
|
|
102
|
+
return stdout.trim();
|
|
103
|
+
} catch (error) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Scan environment variables for credentials
|
|
110
|
+
*/
|
|
111
|
+
function scanEnvironmentVariables() {
|
|
112
|
+
const found = {};
|
|
113
|
+
|
|
114
|
+
for (const [key, config] of Object.entries(CREDENTIALS)) {
|
|
115
|
+
if (process.env[key]) {
|
|
116
|
+
const value = process.env[key];
|
|
117
|
+
if (config.pattern && !config.pattern.test(value)) {
|
|
118
|
+
continue; // Skip invalid patterns
|
|
119
|
+
}
|
|
120
|
+
found[key] = {
|
|
121
|
+
value,
|
|
122
|
+
source: 'environment',
|
|
123
|
+
confidence: 'high',
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return found;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Parse a .env file and extract credentials
|
|
133
|
+
*/
|
|
134
|
+
function parseEnvFile(filePath) {
|
|
135
|
+
try {
|
|
136
|
+
if (!fs.existsSync(filePath)) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
141
|
+
const parsed = dotenv.parse(content);
|
|
142
|
+
const found = {};
|
|
143
|
+
|
|
144
|
+
for (const [key, config] of Object.entries(CREDENTIALS)) {
|
|
145
|
+
if (parsed[key]) {
|
|
146
|
+
const value = parsed[key];
|
|
147
|
+
if (config.pattern && !config.pattern.test(value)) {
|
|
148
|
+
continue; // Skip invalid patterns
|
|
149
|
+
}
|
|
150
|
+
found[key] = {
|
|
151
|
+
value,
|
|
152
|
+
source: filePath,
|
|
153
|
+
confidence: 'medium',
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return Object.keys(found).length > 0 ? found : null;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Scan all common .env file locations
|
|
166
|
+
*/
|
|
167
|
+
function scanEnvFiles() {
|
|
168
|
+
const allFound = {};
|
|
169
|
+
|
|
170
|
+
for (const envPath of ENV_SEARCH_PATHS) {
|
|
171
|
+
const found = parseEnvFile(envPath);
|
|
172
|
+
if (found) {
|
|
173
|
+
for (const [key, data] of Object.entries(found)) {
|
|
174
|
+
// Keep first found (higher priority)
|
|
175
|
+
if (!allFound[key]) {
|
|
176
|
+
allFound[key] = data;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return allFound;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Auto-detect credentials from all sources
|
|
187
|
+
*/
|
|
188
|
+
export async function autoDetectCredentials() {
|
|
189
|
+
console.log(chalk.blue('\nš Auto-detecting credentials from multiple sources...\n'));
|
|
190
|
+
|
|
191
|
+
const detected = {};
|
|
192
|
+
|
|
193
|
+
// 1. Check environment variables
|
|
194
|
+
console.log(chalk.gray('Checking environment variables...'));
|
|
195
|
+
const envVars = scanEnvironmentVariables();
|
|
196
|
+
Object.assign(detected, envVars);
|
|
197
|
+
|
|
198
|
+
// 2. Check GitHub CLI
|
|
199
|
+
console.log(chalk.gray('Checking GitHub CLI (gh)...'));
|
|
200
|
+
const ghAuthed = await checkGitHubCLI();
|
|
201
|
+
if (ghAuthed) {
|
|
202
|
+
const ghToken = await getGitHubTokenFromCLI();
|
|
203
|
+
const ghUser = await getGitHubUserFromCLI();
|
|
204
|
+
|
|
205
|
+
if (ghToken && !detected.GITHUB_TOKEN) {
|
|
206
|
+
detected.GITHUB_TOKEN = {
|
|
207
|
+
value: ghToken,
|
|
208
|
+
source: 'gh CLI',
|
|
209
|
+
confidence: 'high',
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (ghUser && !detected.GITHUB_OWNER) {
|
|
214
|
+
detected.GITHUB_OWNER = {
|
|
215
|
+
value: ghUser,
|
|
216
|
+
source: 'gh CLI',
|
|
217
|
+
confidence: 'high',
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 3. Scan .env files
|
|
223
|
+
console.log(chalk.gray('Scanning .env files in common locations...'));
|
|
224
|
+
const envFiles = scanEnvFiles();
|
|
225
|
+
for (const [key, data] of Object.entries(envFiles)) {
|
|
226
|
+
if (!detected[key]) {
|
|
227
|
+
detected[key] = data;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return detected;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Display detected credentials summary
|
|
236
|
+
*/
|
|
237
|
+
export function displayDetectedCredentials(detected) {
|
|
238
|
+
console.log(chalk.green('\nā
Credential Detection Complete\n'));
|
|
239
|
+
|
|
240
|
+
const found = Object.keys(detected).length;
|
|
241
|
+
const required = Object.entries(CREDENTIALS).filter(([_, c]) => c.required).length;
|
|
242
|
+
const total = Object.keys(CREDENTIALS).length;
|
|
243
|
+
|
|
244
|
+
console.log(chalk.bold(`Found ${found}/${total} credentials (${required} required)`));
|
|
245
|
+
console.log(chalk.gray('ā'.repeat(60)));
|
|
246
|
+
|
|
247
|
+
for (const [key, config] of Object.entries(CREDENTIALS)) {
|
|
248
|
+
const data = detected[key];
|
|
249
|
+
const status = data ? chalk.green('ā') : chalk.red('ā');
|
|
250
|
+
const required = config.required ? chalk.red('*') : ' ';
|
|
251
|
+
|
|
252
|
+
console.log(`${status} ${required} ${chalk.bold(config.name)}`);
|
|
253
|
+
|
|
254
|
+
if (data) {
|
|
255
|
+
// Mask sensitive values
|
|
256
|
+
const maskedValue = maskCredential(key, data.value);
|
|
257
|
+
console.log(chalk.gray(` Value: ${maskedValue}`));
|
|
258
|
+
console.log(chalk.gray(` Source: ${data.source}`));
|
|
259
|
+
console.log(chalk.gray(` Confidence: ${data.confidence}`));
|
|
260
|
+
} else {
|
|
261
|
+
console.log(chalk.gray(` ${config.description}`));
|
|
262
|
+
console.log(chalk.dim(` Example: ${config.example}`));
|
|
263
|
+
}
|
|
264
|
+
console.log();
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log(chalk.gray('ā'.repeat(60)));
|
|
268
|
+
console.log(chalk.dim('* = Required credential\n'));
|
|
269
|
+
|
|
270
|
+
return { found, required, total };
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Mask credential value for display
|
|
275
|
+
*/
|
|
276
|
+
function maskCredential(key, value) {
|
|
277
|
+
if (!value) return 'N/A';
|
|
278
|
+
|
|
279
|
+
if (key === 'REDIS_URL') {
|
|
280
|
+
// Show protocol and host, mask password
|
|
281
|
+
return value.replace(/:(.*?)@/, ':***@');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (key === 'GITHUB_TOKEN') {
|
|
285
|
+
// Show first 4 and last 4 characters
|
|
286
|
+
if (value.length > 12) {
|
|
287
|
+
return `${value.slice(0, 8)}...${value.slice(-4)}`;
|
|
288
|
+
}
|
|
289
|
+
return '***';
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Other credentials - show in full (not sensitive)
|
|
293
|
+
return value;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Write credentials to ~/.boss-claude/.env
|
|
298
|
+
*/
|
|
299
|
+
export function writeCredentialsFile(credentials) {
|
|
300
|
+
const bossDirPath = path.join(os.homedir(), '.boss-claude');
|
|
301
|
+
const envPath = path.join(bossDirPath, '.env');
|
|
302
|
+
|
|
303
|
+
// Create directory if it doesn't exist
|
|
304
|
+
if (!fs.existsSync(bossDirPath)) {
|
|
305
|
+
fs.mkdirSync(bossDirPath, { recursive: true });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Build .env content
|
|
309
|
+
const lines = [
|
|
310
|
+
'# Boss Claude Configuration',
|
|
311
|
+
'# Auto-generated by credential import system',
|
|
312
|
+
`# Created: ${new Date().toISOString()}`,
|
|
313
|
+
'',
|
|
314
|
+
];
|
|
315
|
+
|
|
316
|
+
for (const [key, config] of Object.entries(CREDENTIALS)) {
|
|
317
|
+
const data = credentials[key];
|
|
318
|
+
lines.push(`# ${config.description}`);
|
|
319
|
+
if (data && data.value) {
|
|
320
|
+
lines.push(`${key}=${data.value}`);
|
|
321
|
+
} else {
|
|
322
|
+
lines.push(`# ${key}=${config.example}`);
|
|
323
|
+
}
|
|
324
|
+
lines.push('');
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
fs.writeFileSync(envPath, lines.join('\n'));
|
|
328
|
+
return envPath;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Interactive credential import
|
|
333
|
+
*/
|
|
334
|
+
export async function importCredentials(options = {}) {
|
|
335
|
+
const { autoAccept = false } = options;
|
|
336
|
+
|
|
337
|
+
// Auto-detect credentials
|
|
338
|
+
const detected = await autoDetectCredentials();
|
|
339
|
+
|
|
340
|
+
// Display summary
|
|
341
|
+
const { found, required } = displayDetectedCredentials(detected);
|
|
342
|
+
|
|
343
|
+
// Check if we have all required credentials
|
|
344
|
+
const hasAllRequired = Object.entries(CREDENTIALS)
|
|
345
|
+
.filter(([_, c]) => c.required)
|
|
346
|
+
.every(([key, _]) => detected[key]);
|
|
347
|
+
|
|
348
|
+
if (hasAllRequired) {
|
|
349
|
+
console.log(chalk.green('ā
All required credentials detected!\n'));
|
|
350
|
+
} else {
|
|
351
|
+
console.log(chalk.yellow('ā ļø Missing required credentials\n'));
|
|
352
|
+
|
|
353
|
+
// List missing required credentials
|
|
354
|
+
const missing = Object.entries(CREDENTIALS)
|
|
355
|
+
.filter(([key, config]) => config.required && !detected[key])
|
|
356
|
+
.map(([_, config]) => config.name);
|
|
357
|
+
|
|
358
|
+
console.log(chalk.red('Missing required credentials:'));
|
|
359
|
+
missing.forEach(name => console.log(chalk.red(` ⢠${name}`)));
|
|
360
|
+
console.log();
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Write credentials file
|
|
364
|
+
const envPath = writeCredentialsFile(detected);
|
|
365
|
+
console.log(chalk.green(`ā
Credentials written to: ${envPath}\n`));
|
|
366
|
+
|
|
367
|
+
// Show next steps
|
|
368
|
+
if (!hasAllRequired) {
|
|
369
|
+
console.log(chalk.yellow('ā ļø Next steps:'));
|
|
370
|
+
console.log(chalk.gray(`1. Edit ${envPath}`));
|
|
371
|
+
console.log(chalk.gray('2. Fill in missing credentials'));
|
|
372
|
+
console.log(chalk.gray('3. Run: boss-claude init\n'));
|
|
373
|
+
} else {
|
|
374
|
+
console.log(chalk.green('ā
Ready to use Boss Claude!'));
|
|
375
|
+
console.log(chalk.gray('Run: boss-claude init\n'));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
return {
|
|
379
|
+
detected,
|
|
380
|
+
envPath,
|
|
381
|
+
hasAllRequired,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Validate existing credentials
|
|
387
|
+
*/
|
|
388
|
+
export async function validateCredentials() {
|
|
389
|
+
const bossDirPath = path.join(os.homedir(), '.boss-claude');
|
|
390
|
+
const envPath = path.join(bossDirPath, '.env');
|
|
391
|
+
|
|
392
|
+
if (!fs.existsSync(envPath)) {
|
|
393
|
+
return {
|
|
394
|
+
valid: false,
|
|
395
|
+
errors: ['Credentials file not found at ~/.boss-claude/.env'],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Load credentials
|
|
400
|
+
const content = fs.readFileSync(envPath, 'utf8');
|
|
401
|
+
const parsed = dotenv.parse(content);
|
|
402
|
+
const errors = [];
|
|
403
|
+
|
|
404
|
+
// Validate each credential
|
|
405
|
+
for (const [key, config] of Object.entries(CREDENTIALS)) {
|
|
406
|
+
const value = parsed[key];
|
|
407
|
+
|
|
408
|
+
if (config.required && !value) {
|
|
409
|
+
errors.push(`Missing required credential: ${config.name}`);
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
if (value && config.pattern && !config.pattern.test(value)) {
|
|
414
|
+
errors.push(`Invalid format for ${config.name}: ${value}`);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return {
|
|
419
|
+
valid: errors.length === 0,
|
|
420
|
+
errors,
|
|
421
|
+
credentials: parsed,
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* List all detected sources
|
|
427
|
+
*/
|
|
428
|
+
export async function listSources() {
|
|
429
|
+
console.log(chalk.blue('\nš Credential Sources\n'));
|
|
430
|
+
|
|
431
|
+
// 1. Environment variables
|
|
432
|
+
console.log(chalk.bold('1. Environment Variables'));
|
|
433
|
+
const envVars = scanEnvironmentVariables();
|
|
434
|
+
if (Object.keys(envVars).length > 0) {
|
|
435
|
+
for (const [key, data] of Object.entries(envVars)) {
|
|
436
|
+
console.log(chalk.gray(` ${key}: ${maskCredential(key, data.value)}`));
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
console.log(chalk.gray(' (none found)'));
|
|
440
|
+
}
|
|
441
|
+
console.log();
|
|
442
|
+
|
|
443
|
+
// 2. GitHub CLI
|
|
444
|
+
console.log(chalk.bold('2. GitHub CLI (gh)'));
|
|
445
|
+
const ghAuthed = await checkGitHubCLI();
|
|
446
|
+
if (ghAuthed) {
|
|
447
|
+
const ghToken = await getGitHubTokenFromCLI();
|
|
448
|
+
const ghUser = await getGitHubUserFromCLI();
|
|
449
|
+
console.log(chalk.gray(` Authenticated: Yes`));
|
|
450
|
+
console.log(chalk.gray(` Token: ${maskCredential('GITHUB_TOKEN', ghToken)}`));
|
|
451
|
+
console.log(chalk.gray(` User: ${ghUser}`));
|
|
452
|
+
} else {
|
|
453
|
+
console.log(chalk.gray(' Authenticated: No'));
|
|
454
|
+
}
|
|
455
|
+
console.log();
|
|
456
|
+
|
|
457
|
+
// 3. .env files
|
|
458
|
+
console.log(chalk.bold('3. .env Files'));
|
|
459
|
+
for (const envPath of ENV_SEARCH_PATHS) {
|
|
460
|
+
const found = parseEnvFile(envPath);
|
|
461
|
+
if (found) {
|
|
462
|
+
console.log(chalk.green(` ā ${envPath}`));
|
|
463
|
+
for (const [key, data] of Object.entries(found)) {
|
|
464
|
+
console.log(chalk.gray(` ${key}: ${maskCredential(key, data.value)}`));
|
|
465
|
+
}
|
|
466
|
+
} else {
|
|
467
|
+
console.log(chalk.dim(` ā ${envPath}`));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
console.log();
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// CLI interface
|
|
474
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
475
|
+
const command = process.argv[2] || 'import';
|
|
476
|
+
|
|
477
|
+
if (command === 'import') {
|
|
478
|
+
await importCredentials();
|
|
479
|
+
} else if (command === 'list') {
|
|
480
|
+
await listSources();
|
|
481
|
+
} else if (command === 'validate') {
|
|
482
|
+
const result = await validateCredentials();
|
|
483
|
+
if (result.valid) {
|
|
484
|
+
console.log(chalk.green('\nā
All credentials valid\n'));
|
|
485
|
+
} else {
|
|
486
|
+
console.log(chalk.red('\nā Validation failed:\n'));
|
|
487
|
+
result.errors.forEach(error => console.log(chalk.red(` ⢠${error}`)));
|
|
488
|
+
console.log();
|
|
489
|
+
process.exit(1);
|
|
490
|
+
}
|
|
491
|
+
} else {
|
|
492
|
+
console.log(chalk.yellow(`\nUnknown command: ${command}`));
|
|
493
|
+
console.log(chalk.gray('\nAvailable commands:'));
|
|
494
|
+
console.log(chalk.gray(' import - Auto-detect and import credentials'));
|
|
495
|
+
console.log(chalk.gray(' list - List all credential sources'));
|
|
496
|
+
console.log(chalk.gray(' validate - Validate existing credentials\n'));
|
|
497
|
+
}
|
|
498
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boss Claude Setup Utilities
|
|
3
|
+
*
|
|
4
|
+
* Centralized exports for all setup modules
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export {
|
|
8
|
+
setupGitHubRepo,
|
|
9
|
+
setupGitHubRepoCommand,
|
|
10
|
+
getGitHubToken,
|
|
11
|
+
getGitHubUsername,
|
|
12
|
+
repositoryExists,
|
|
13
|
+
createRepository
|
|
14
|
+
} from './github-repo.js';
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
initializeRedis,
|
|
18
|
+
getRedisStats,
|
|
19
|
+
resetRedis,
|
|
20
|
+
verifyRedis,
|
|
21
|
+
printInitResults as printRedisInitResults,
|
|
22
|
+
setupRedisForWizard,
|
|
23
|
+
DEFAULT_IDENTITY,
|
|
24
|
+
ACHIEVEMENTS
|
|
25
|
+
} from './init-redis.js';
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
initializePostgres,
|
|
29
|
+
getPostgresStats,
|
|
30
|
+
resetPostgres,
|
|
31
|
+
verifyPostgres,
|
|
32
|
+
printInitResults as printPostgresInitResults,
|
|
33
|
+
setupPostgresForWizard
|
|
34
|
+
} from './init-postgres.js';
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
runIntegrationTests,
|
|
38
|
+
testEnvironmentVariables,
|
|
39
|
+
testRedisConnection,
|
|
40
|
+
testPostgreSQLConnection,
|
|
41
|
+
testGitHubIntegration,
|
|
42
|
+
testSystemIntegration
|
|
43
|
+
} from './integration-test.js';
|
|
44
|
+
|
|
45
|
+
export {
|
|
46
|
+
RollbackManager,
|
|
47
|
+
SetupState,
|
|
48
|
+
quickRollback,
|
|
49
|
+
createSnapshot,
|
|
50
|
+
recordAction
|
|
51
|
+
} from './rollback.js';
|
|
52
|
+
|
|
53
|
+
export { EnvManager } from './env-manager.js';
|
|
54
|
+
|
|
55
|
+
export {
|
|
56
|
+
displaySetupSummary,
|
|
57
|
+
displayQuickSummary,
|
|
58
|
+
displayPartialSummary,
|
|
59
|
+
displayRollbackSummary,
|
|
60
|
+
displayValidationSummary,
|
|
61
|
+
createSummaryConfig
|
|
62
|
+
} from './summary.js';
|