@codebakers/cli 3.3.12 โ 3.3.14
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/lib/api.d.ts +138 -0
- package/dist/lib/api.js +81 -0
- package/dist/mcp/server.js +378 -2
- package/package.json +1 -1
- package/src/lib/api.ts +255 -0
- package/src/mcp/server.ts +486 -0
package/src/mcp/server.ts
CHANGED
|
@@ -1385,6 +1385,126 @@ class CodeBakersServer {
|
|
|
1385
1385
|
properties: {},
|
|
1386
1386
|
},
|
|
1387
1387
|
},
|
|
1388
|
+
// ============================================
|
|
1389
|
+
// PROJECT TRACKING - Server-Side Dashboard
|
|
1390
|
+
// ============================================
|
|
1391
|
+
{
|
|
1392
|
+
name: 'project_sync',
|
|
1393
|
+
description:
|
|
1394
|
+
'Sync project progress to the CodeBakers server for dashboard visualization. Call this after completing builds, features, tests, or other significant milestones. Data appears on the web dashboard at codebakers.ai/projects.',
|
|
1395
|
+
inputSchema: {
|
|
1396
|
+
type: 'object' as const,
|
|
1397
|
+
properties: {
|
|
1398
|
+
projectStatus: {
|
|
1399
|
+
type: 'string',
|
|
1400
|
+
enum: ['discovery', 'planning', 'building', 'testing', 'completed', 'paused', 'failed'],
|
|
1401
|
+
description: 'Current project status',
|
|
1402
|
+
},
|
|
1403
|
+
overallProgress: {
|
|
1404
|
+
type: 'number',
|
|
1405
|
+
description: 'Overall progress percentage (0-100)',
|
|
1406
|
+
},
|
|
1407
|
+
phases: {
|
|
1408
|
+
type: 'array',
|
|
1409
|
+
items: {
|
|
1410
|
+
type: 'object',
|
|
1411
|
+
properties: {
|
|
1412
|
+
phaseNumber: { type: 'number' },
|
|
1413
|
+
phaseName: { type: 'string' },
|
|
1414
|
+
phaseDescription: { type: 'string' },
|
|
1415
|
+
status: { type: 'string', enum: ['pending', 'in_progress', 'completed', 'skipped', 'failed'] },
|
|
1416
|
+
progress: { type: 'number' },
|
|
1417
|
+
aiConfidence: { type: 'number' },
|
|
1418
|
+
},
|
|
1419
|
+
},
|
|
1420
|
+
description: 'Build phases to sync',
|
|
1421
|
+
},
|
|
1422
|
+
events: {
|
|
1423
|
+
type: 'array',
|
|
1424
|
+
items: {
|
|
1425
|
+
type: 'object',
|
|
1426
|
+
properties: {
|
|
1427
|
+
eventType: { type: 'string' },
|
|
1428
|
+
eventTitle: { type: 'string' },
|
|
1429
|
+
eventDescription: { type: 'string' },
|
|
1430
|
+
filePath: { type: 'string' },
|
|
1431
|
+
fileAction: { type: 'string' },
|
|
1432
|
+
linesChanged: { type: 'number' },
|
|
1433
|
+
riskLevel: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
1434
|
+
},
|
|
1435
|
+
},
|
|
1436
|
+
description: 'Timeline events to record',
|
|
1437
|
+
},
|
|
1438
|
+
testRuns: {
|
|
1439
|
+
type: 'array',
|
|
1440
|
+
items: {
|
|
1441
|
+
type: 'object',
|
|
1442
|
+
properties: {
|
|
1443
|
+
testType: { type: 'string' },
|
|
1444
|
+
testCommand: { type: 'string' },
|
|
1445
|
+
passed: { type: 'boolean' },
|
|
1446
|
+
totalTests: { type: 'number' },
|
|
1447
|
+
passedTests: { type: 'number' },
|
|
1448
|
+
failedTests: { type: 'number' },
|
|
1449
|
+
skippedTests: { type: 'number' },
|
|
1450
|
+
durationMs: { type: 'number' },
|
|
1451
|
+
},
|
|
1452
|
+
},
|
|
1453
|
+
description: 'Test run results to sync',
|
|
1454
|
+
},
|
|
1455
|
+
riskFlags: {
|
|
1456
|
+
type: 'array',
|
|
1457
|
+
items: {
|
|
1458
|
+
type: 'object',
|
|
1459
|
+
properties: {
|
|
1460
|
+
riskLevel: { type: 'string', enum: ['low', 'medium', 'high', 'critical'] },
|
|
1461
|
+
riskCategory: { type: 'string' },
|
|
1462
|
+
riskTitle: { type: 'string' },
|
|
1463
|
+
riskDescription: { type: 'string' },
|
|
1464
|
+
triggerFile: { type: 'string' },
|
|
1465
|
+
aiRecommendation: { type: 'string' },
|
|
1466
|
+
},
|
|
1467
|
+
},
|
|
1468
|
+
description: 'Risk flags to create',
|
|
1469
|
+
},
|
|
1470
|
+
resources: {
|
|
1471
|
+
type: 'array',
|
|
1472
|
+
items: {
|
|
1473
|
+
type: 'object',
|
|
1474
|
+
properties: {
|
|
1475
|
+
resourceType: { type: 'string' },
|
|
1476
|
+
inputTokens: { type: 'number' },
|
|
1477
|
+
outputTokens: { type: 'number' },
|
|
1478
|
+
totalTokens: { type: 'number' },
|
|
1479
|
+
durationMs: { type: 'number' },
|
|
1480
|
+
estimatedCostMillicents: { type: 'number' },
|
|
1481
|
+
},
|
|
1482
|
+
},
|
|
1483
|
+
description: 'Resource usage to track (API calls, tokens, etc.)',
|
|
1484
|
+
},
|
|
1485
|
+
createSnapshot: {
|
|
1486
|
+
type: 'object',
|
|
1487
|
+
properties: {
|
|
1488
|
+
snapshotName: { type: 'string' },
|
|
1489
|
+
snapshotDescription: { type: 'string' },
|
|
1490
|
+
isAutomatic: { type: 'boolean' },
|
|
1491
|
+
gitCommitHash: { type: 'string' },
|
|
1492
|
+
gitBranch: { type: 'string' },
|
|
1493
|
+
},
|
|
1494
|
+
description: 'Create a rollback snapshot',
|
|
1495
|
+
},
|
|
1496
|
+
},
|
|
1497
|
+
},
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
name: 'project_dashboard_url',
|
|
1501
|
+
description:
|
|
1502
|
+
'Get the URL to view the project dashboard on codebakers.ai. Use when user says "show dashboard", "view progress online", or "open project page".',
|
|
1503
|
+
inputSchema: {
|
|
1504
|
+
type: 'object' as const,
|
|
1505
|
+
properties: {},
|
|
1506
|
+
},
|
|
1507
|
+
},
|
|
1388
1508
|
],
|
|
1389
1509
|
}));
|
|
1390
1510
|
|
|
@@ -1562,6 +1682,66 @@ class CodeBakersServer {
|
|
|
1562
1682
|
case 'guardian_status':
|
|
1563
1683
|
return this.handleGuardianStatus();
|
|
1564
1684
|
|
|
1685
|
+
// Project Tracking - Server-Side Dashboard
|
|
1686
|
+
case 'project_sync':
|
|
1687
|
+
return this.handleProjectSync(args as {
|
|
1688
|
+
projectStatus?: string;
|
|
1689
|
+
overallProgress?: number;
|
|
1690
|
+
phases?: Array<{
|
|
1691
|
+
phaseNumber: number;
|
|
1692
|
+
phaseName: string;
|
|
1693
|
+
phaseDescription?: string;
|
|
1694
|
+
status?: string;
|
|
1695
|
+
progress?: number;
|
|
1696
|
+
aiConfidence?: number;
|
|
1697
|
+
}>;
|
|
1698
|
+
events?: Array<{
|
|
1699
|
+
eventType: string;
|
|
1700
|
+
eventTitle: string;
|
|
1701
|
+
eventDescription?: string;
|
|
1702
|
+
filePath?: string;
|
|
1703
|
+
fileAction?: string;
|
|
1704
|
+
linesChanged?: number;
|
|
1705
|
+
riskLevel?: string;
|
|
1706
|
+
}>;
|
|
1707
|
+
testRuns?: Array<{
|
|
1708
|
+
testType: string;
|
|
1709
|
+
testCommand?: string;
|
|
1710
|
+
passed: boolean;
|
|
1711
|
+
totalTests: number;
|
|
1712
|
+
passedTests: number;
|
|
1713
|
+
failedTests: number;
|
|
1714
|
+
skippedTests: number;
|
|
1715
|
+
durationMs?: number;
|
|
1716
|
+
}>;
|
|
1717
|
+
riskFlags?: Array<{
|
|
1718
|
+
riskLevel: string;
|
|
1719
|
+
riskCategory: string;
|
|
1720
|
+
riskTitle: string;
|
|
1721
|
+
riskDescription?: string;
|
|
1722
|
+
triggerFile?: string;
|
|
1723
|
+
aiRecommendation?: string;
|
|
1724
|
+
}>;
|
|
1725
|
+
resources?: Array<{
|
|
1726
|
+
resourceType: string;
|
|
1727
|
+
inputTokens?: number;
|
|
1728
|
+
outputTokens?: number;
|
|
1729
|
+
totalTokens?: number;
|
|
1730
|
+
durationMs?: number;
|
|
1731
|
+
estimatedCostMillicents?: number;
|
|
1732
|
+
}>;
|
|
1733
|
+
createSnapshot?: {
|
|
1734
|
+
snapshotName: string;
|
|
1735
|
+
snapshotDescription?: string;
|
|
1736
|
+
isAutomatic?: boolean;
|
|
1737
|
+
gitCommitHash?: string;
|
|
1738
|
+
gitBranch?: string;
|
|
1739
|
+
};
|
|
1740
|
+
});
|
|
1741
|
+
|
|
1742
|
+
case 'project_dashboard_url':
|
|
1743
|
+
return this.handleProjectDashboardUrl();
|
|
1744
|
+
|
|
1565
1745
|
default:
|
|
1566
1746
|
throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`);
|
|
1567
1747
|
}
|
|
@@ -7076,6 +7256,312 @@ ${events.includes('call-started') ? ` case 'call-started':
|
|
|
7076
7256
|
return { content: [{ type: 'text' as const, text: response }] };
|
|
7077
7257
|
}
|
|
7078
7258
|
|
|
7259
|
+
// ============================================================================
|
|
7260
|
+
// PROJECT TRACKING - Server-Side Dashboard
|
|
7261
|
+
// ============================================================================
|
|
7262
|
+
|
|
7263
|
+
/**
|
|
7264
|
+
* Sync project progress to the CodeBakers server
|
|
7265
|
+
*/
|
|
7266
|
+
private async handleProjectSync(args: {
|
|
7267
|
+
projectStatus?: string;
|
|
7268
|
+
overallProgress?: number;
|
|
7269
|
+
phases?: Array<{
|
|
7270
|
+
phaseNumber: number;
|
|
7271
|
+
phaseName: string;
|
|
7272
|
+
phaseDescription?: string;
|
|
7273
|
+
status?: string;
|
|
7274
|
+
progress?: number;
|
|
7275
|
+
aiConfidence?: number;
|
|
7276
|
+
}>;
|
|
7277
|
+
events?: Array<{
|
|
7278
|
+
eventType: string;
|
|
7279
|
+
eventTitle: string;
|
|
7280
|
+
eventDescription?: string;
|
|
7281
|
+
filePath?: string;
|
|
7282
|
+
fileAction?: string;
|
|
7283
|
+
linesChanged?: number;
|
|
7284
|
+
riskLevel?: string;
|
|
7285
|
+
}>;
|
|
7286
|
+
testRuns?: Array<{
|
|
7287
|
+
testType: string;
|
|
7288
|
+
testCommand?: string;
|
|
7289
|
+
passed: boolean;
|
|
7290
|
+
totalTests: number;
|
|
7291
|
+
passedTests: number;
|
|
7292
|
+
failedTests: number;
|
|
7293
|
+
skippedTests: number;
|
|
7294
|
+
durationMs?: number;
|
|
7295
|
+
}>;
|
|
7296
|
+
riskFlags?: Array<{
|
|
7297
|
+
riskLevel: string;
|
|
7298
|
+
riskCategory: string;
|
|
7299
|
+
riskTitle: string;
|
|
7300
|
+
riskDescription?: string;
|
|
7301
|
+
triggerFile?: string;
|
|
7302
|
+
aiRecommendation?: string;
|
|
7303
|
+
}>;
|
|
7304
|
+
resources?: Array<{
|
|
7305
|
+
resourceType: string;
|
|
7306
|
+
inputTokens?: number;
|
|
7307
|
+
outputTokens?: number;
|
|
7308
|
+
totalTokens?: number;
|
|
7309
|
+
durationMs?: number;
|
|
7310
|
+
estimatedCostMillicents?: number;
|
|
7311
|
+
}>;
|
|
7312
|
+
createSnapshot?: {
|
|
7313
|
+
snapshotName: string;
|
|
7314
|
+
snapshotDescription?: string;
|
|
7315
|
+
isAutomatic?: boolean;
|
|
7316
|
+
gitCommitHash?: string;
|
|
7317
|
+
gitBranch?: string;
|
|
7318
|
+
};
|
|
7319
|
+
}) {
|
|
7320
|
+
const cwd = process.cwd();
|
|
7321
|
+
|
|
7322
|
+
try {
|
|
7323
|
+
// Import API functions dynamically
|
|
7324
|
+
const apiModule = await import('../lib/api.js');
|
|
7325
|
+
const { getOrCreateProject, syncProjectData, createProjectHash } = apiModule;
|
|
7326
|
+
|
|
7327
|
+
// Read package.json for project info
|
|
7328
|
+
let projectName = path.basename(cwd);
|
|
7329
|
+
let packageName: string | undefined;
|
|
7330
|
+
|
|
7331
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
7332
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
7333
|
+
try {
|
|
7334
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
7335
|
+
projectName = packageJson.name || projectName;
|
|
7336
|
+
packageName = packageJson.name;
|
|
7337
|
+
} catch {
|
|
7338
|
+
// Ignore parse errors
|
|
7339
|
+
}
|
|
7340
|
+
}
|
|
7341
|
+
|
|
7342
|
+
// Create project hash
|
|
7343
|
+
const projectHash = createProjectHash(cwd, packageName);
|
|
7344
|
+
|
|
7345
|
+
// Read .codebakers.json for detected stack
|
|
7346
|
+
let detectedStack: Record<string, string> | undefined;
|
|
7347
|
+
const codebakersPath = path.join(cwd, '.codebakers.json');
|
|
7348
|
+
if (fs.existsSync(codebakersPath)) {
|
|
7349
|
+
try {
|
|
7350
|
+
const codebakersState = JSON.parse(fs.readFileSync(codebakersPath, 'utf-8'));
|
|
7351
|
+
if (codebakersState.stack) {
|
|
7352
|
+
detectedStack = codebakersState.stack;
|
|
7353
|
+
}
|
|
7354
|
+
} catch {
|
|
7355
|
+
// Ignore parse errors
|
|
7356
|
+
}
|
|
7357
|
+
}
|
|
7358
|
+
|
|
7359
|
+
// Get or create project on server
|
|
7360
|
+
const authHeaders = this.getAuthHeaders();
|
|
7361
|
+
const { projectId, isNew } = await getOrCreateProject(
|
|
7362
|
+
projectHash,
|
|
7363
|
+
projectName,
|
|
7364
|
+
undefined,
|
|
7365
|
+
detectedStack,
|
|
7366
|
+
authHeaders
|
|
7367
|
+
);
|
|
7368
|
+
|
|
7369
|
+
// Build sync data
|
|
7370
|
+
const syncData: Record<string, unknown> = {};
|
|
7371
|
+
|
|
7372
|
+
// Add project status if provided
|
|
7373
|
+
if (args.projectStatus || args.overallProgress !== undefined) {
|
|
7374
|
+
const projectUpdate: Record<string, unknown> = {};
|
|
7375
|
+
if (args.projectStatus) {
|
|
7376
|
+
projectUpdate.status = args.projectStatus;
|
|
7377
|
+
}
|
|
7378
|
+
if (args.overallProgress !== undefined) {
|
|
7379
|
+
projectUpdate.overallProgress = args.overallProgress;
|
|
7380
|
+
}
|
|
7381
|
+
syncData.project = projectUpdate;
|
|
7382
|
+
}
|
|
7383
|
+
|
|
7384
|
+
// Add phases if provided
|
|
7385
|
+
if (args.phases && args.phases.length > 0) {
|
|
7386
|
+
syncData.phases = args.phases.map(p => ({
|
|
7387
|
+
phaseNumber: p.phaseNumber,
|
|
7388
|
+
phaseName: p.phaseName,
|
|
7389
|
+
phaseDescription: p.phaseDescription,
|
|
7390
|
+
status: p.status as 'pending' | 'in_progress' | 'completed' | 'skipped' | 'failed' | undefined,
|
|
7391
|
+
progress: p.progress,
|
|
7392
|
+
aiConfidence: p.aiConfidence,
|
|
7393
|
+
}));
|
|
7394
|
+
}
|
|
7395
|
+
|
|
7396
|
+
// Add events if provided
|
|
7397
|
+
if (args.events && args.events.length > 0) {
|
|
7398
|
+
syncData.events = args.events.map(e => ({
|
|
7399
|
+
eventType: e.eventType,
|
|
7400
|
+
eventTitle: e.eventTitle,
|
|
7401
|
+
eventDescription: e.eventDescription,
|
|
7402
|
+
filePath: e.filePath,
|
|
7403
|
+
fileAction: e.fileAction,
|
|
7404
|
+
linesChanged: e.linesChanged,
|
|
7405
|
+
riskLevel: e.riskLevel as 'low' | 'medium' | 'high' | 'critical' | undefined,
|
|
7406
|
+
}));
|
|
7407
|
+
}
|
|
7408
|
+
|
|
7409
|
+
// Add test runs if provided
|
|
7410
|
+
if (args.testRuns && args.testRuns.length > 0) {
|
|
7411
|
+
syncData.testRuns = args.testRuns;
|
|
7412
|
+
}
|
|
7413
|
+
|
|
7414
|
+
// Add risk flags if provided
|
|
7415
|
+
if (args.riskFlags && args.riskFlags.length > 0) {
|
|
7416
|
+
syncData.riskFlags = args.riskFlags.map(r => ({
|
|
7417
|
+
riskLevel: r.riskLevel as 'low' | 'medium' | 'high' | 'critical',
|
|
7418
|
+
riskCategory: r.riskCategory,
|
|
7419
|
+
riskTitle: r.riskTitle,
|
|
7420
|
+
riskDescription: r.riskDescription,
|
|
7421
|
+
triggerFile: r.triggerFile,
|
|
7422
|
+
aiRecommendation: r.aiRecommendation,
|
|
7423
|
+
}));
|
|
7424
|
+
}
|
|
7425
|
+
|
|
7426
|
+
// Add resources if provided
|
|
7427
|
+
if (args.resources && args.resources.length > 0) {
|
|
7428
|
+
syncData.resources = args.resources;
|
|
7429
|
+
}
|
|
7430
|
+
|
|
7431
|
+
// Add snapshot if provided
|
|
7432
|
+
if (args.createSnapshot) {
|
|
7433
|
+
// Get git info if available
|
|
7434
|
+
let gitCommitHash: string | undefined;
|
|
7435
|
+
let gitBranch: string | undefined;
|
|
7436
|
+
|
|
7437
|
+
try {
|
|
7438
|
+
gitCommitHash = execSync('git rev-parse HEAD', { cwd, encoding: 'utf-8' }).trim();
|
|
7439
|
+
gitBranch = execSync('git rev-parse --abbrev-ref HEAD', { cwd, encoding: 'utf-8' }).trim();
|
|
7440
|
+
} catch {
|
|
7441
|
+
// Git not available or not a repo
|
|
7442
|
+
}
|
|
7443
|
+
|
|
7444
|
+
syncData.createSnapshot = {
|
|
7445
|
+
snapshotName: args.createSnapshot.snapshotName,
|
|
7446
|
+
snapshotDescription: args.createSnapshot.snapshotDescription,
|
|
7447
|
+
isAutomatic: args.createSnapshot.isAutomatic,
|
|
7448
|
+
gitCommitHash: args.createSnapshot.gitCommitHash || gitCommitHash,
|
|
7449
|
+
gitBranch: args.createSnapshot.gitBranch || gitBranch,
|
|
7450
|
+
};
|
|
7451
|
+
}
|
|
7452
|
+
|
|
7453
|
+
// Sync to server
|
|
7454
|
+
const result = await syncProjectData(projectId, syncData, authHeaders);
|
|
7455
|
+
|
|
7456
|
+
// Build response
|
|
7457
|
+
let response = `# ๐ Project Synced to Dashboard\n\n`;
|
|
7458
|
+
|
|
7459
|
+
if (isNew) {
|
|
7460
|
+
response += `โจ **New project registered:** ${projectName}\n\n`;
|
|
7461
|
+
}
|
|
7462
|
+
|
|
7463
|
+
response += `**Project ID:** \`${projectId}\`\n\n`;
|
|
7464
|
+
|
|
7465
|
+
response += `## Synced Data\n\n`;
|
|
7466
|
+
|
|
7467
|
+
const synced = result.synced;
|
|
7468
|
+
if (synced.project) response += `- โ
Project status updated\n`;
|
|
7469
|
+
if (synced.phases > 0) response += `- โ
${synced.phases} phase(s) synced\n`;
|
|
7470
|
+
if (synced.events > 0) response += `- โ
${synced.events} event(s) recorded\n`;
|
|
7471
|
+
if (synced.testRuns > 0) response += `- โ
${synced.testRuns} test run(s) logged\n`;
|
|
7472
|
+
if (synced.riskFlags > 0) response += `- โ
${synced.riskFlags} risk flag(s) created\n`;
|
|
7473
|
+
if (synced.resources > 0) response += `- โ
${synced.resources} resource record(s) added\n`;
|
|
7474
|
+
if (synced.snapshot) response += `- โ
Rollback snapshot created\n`;
|
|
7475
|
+
|
|
7476
|
+
response += `\n---\n\n`;
|
|
7477
|
+
response += `๐ **View Dashboard:** https://codebakers.ai/projects/${projectId}\n`;
|
|
7478
|
+
|
|
7479
|
+
// Add update notice if available
|
|
7480
|
+
response += this.getUpdateNotice();
|
|
7481
|
+
|
|
7482
|
+
return { content: [{ type: 'text' as const, text: response }] };
|
|
7483
|
+
|
|
7484
|
+
} catch (error) {
|
|
7485
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
7486
|
+
let response = `# โ Sync Failed\n\n`;
|
|
7487
|
+
response += `Could not sync project to server.\n\n`;
|
|
7488
|
+
response += `**Error:** ${errorMessage}\n\n`;
|
|
7489
|
+
response += `This may be due to:\n`;
|
|
7490
|
+
response += `- Network connectivity issues\n`;
|
|
7491
|
+
response += `- Invalid API key or expired trial\n`;
|
|
7492
|
+
response += `- Server maintenance\n\n`;
|
|
7493
|
+
response += `Your local project is unaffected. Try again later.\n`;
|
|
7494
|
+
|
|
7495
|
+
return { content: [{ type: 'text' as const, text: response }] };
|
|
7496
|
+
}
|
|
7497
|
+
}
|
|
7498
|
+
|
|
7499
|
+
/**
|
|
7500
|
+
* Get the URL to view the project dashboard
|
|
7501
|
+
*/
|
|
7502
|
+
private async handleProjectDashboardUrl() {
|
|
7503
|
+
const cwd = process.cwd();
|
|
7504
|
+
|
|
7505
|
+
try {
|
|
7506
|
+
const { getOrCreateProject, createProjectHash } = await import('../lib/api.js');
|
|
7507
|
+
|
|
7508
|
+
// Read package.json for project info
|
|
7509
|
+
let projectName = path.basename(cwd);
|
|
7510
|
+
let packageName: string | undefined;
|
|
7511
|
+
|
|
7512
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
7513
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
7514
|
+
try {
|
|
7515
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
7516
|
+
projectName = packageJson.name || projectName;
|
|
7517
|
+
packageName = packageJson.name;
|
|
7518
|
+
} catch {
|
|
7519
|
+
// Ignore parse errors
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
|
|
7523
|
+
// Create project hash
|
|
7524
|
+
const projectHash = createProjectHash(cwd, packageName);
|
|
7525
|
+
|
|
7526
|
+
// Get or create project on server (this ensures the project exists)
|
|
7527
|
+
const authHeaders = this.getAuthHeaders();
|
|
7528
|
+
const { projectId } = await getOrCreateProject(
|
|
7529
|
+
projectHash,
|
|
7530
|
+
projectName,
|
|
7531
|
+
undefined,
|
|
7532
|
+
undefined,
|
|
7533
|
+
authHeaders
|
|
7534
|
+
);
|
|
7535
|
+
|
|
7536
|
+
const dashboardUrl = `https://codebakers.ai/projects/${projectId}`;
|
|
7537
|
+
|
|
7538
|
+
let response = `# ๐ Project Dashboard\n\n`;
|
|
7539
|
+
response += `**Project:** ${projectName}\n\n`;
|
|
7540
|
+
response += `**Dashboard URL:**\n${dashboardUrl}\n\n`;
|
|
7541
|
+
response += `Open this URL in your browser to view:\n`;
|
|
7542
|
+
response += `- ๐ Build progress and phases\n`;
|
|
7543
|
+
response += `- ๐งช Test run history and results\n`;
|
|
7544
|
+
response += `- ๐ File tree evolution\n`;
|
|
7545
|
+
response += `- ๐ Dependency graph\n`;
|
|
7546
|
+
response += `- โ ๏ธ Risk flags and recommendations\n`;
|
|
7547
|
+
response += `- ๐ฐ Resource usage (tokens, API calls)\n`;
|
|
7548
|
+
response += `- ๐ธ Rollback snapshots\n`;
|
|
7549
|
+
|
|
7550
|
+
// Add update notice if available
|
|
7551
|
+
response += this.getUpdateNotice();
|
|
7552
|
+
|
|
7553
|
+
return { content: [{ type: 'text' as const, text: response }] };
|
|
7554
|
+
|
|
7555
|
+
} catch (error) {
|
|
7556
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
7557
|
+
let response = `# โ Could Not Get Dashboard URL\n\n`;
|
|
7558
|
+
response += `**Error:** ${errorMessage}\n\n`;
|
|
7559
|
+
response += `Make sure you are logged in with a valid API key or trial.\n`;
|
|
7560
|
+
|
|
7561
|
+
return { content: [{ type: 'text' as const, text: response }] };
|
|
7562
|
+
}
|
|
7563
|
+
}
|
|
7564
|
+
|
|
7079
7565
|
/**
|
|
7080
7566
|
* Ripple Check - Detect all files affected by a change to a type/schema/function
|
|
7081
7567
|
* Searches the codebase for imports and usages of the entity
|