Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 1x 1x 1x 1x 1x 1x 1x | #!/usr/bin/env node
import 'reflect-metadata';
import { NestFactory } from '@nestjs/core';
import { LoggerService } from '@nestjs/common';
import { AppModule } from '../nest/app.module';
import { McpCliCommand } from './mcp-cli.command';
import { spawn } from 'child_process';
import * as path from 'path';
/**
* Custom logger that writes all logs to stderr instead of stdout.
* This is required for stdio-based MCP communication where only
* JSON-RPC messages should go to stdout.
*/
class StderrLogger implements LoggerService {
log(message: string): void {
process.stderr.write(`[LOG] ${message}\n`);
}
error(message: string, trace?: string): void {
process.stderr.write(`[ERROR] ${message}\n`);
if (trace) {
process.stderr.write(`[TRACE] ${trace}\n`);
}
}
warn(message: string): void {
process.stderr.write(`[WARN] ${message}\n`);
}
debug(message: string): void {
process.stderr.write(`[DEBUG] ${message}\n`);
}
verbose(message: string): void {
process.stderr.write(`[VERBOSE] ${message}\n`);
}
}
async function bootstrap(): Promise<void> {
const app = await NestFactory.createApplicationContext(AppModule, {
logger: new StderrLogger()
});
// If invoked as "gs-squad-mcp dashboard" (or with --dashboard),
// initialize DB via Nest + TypeORM,
// then spawn the dashboard TUI process and exit when it exits.
const argv = process.argv.slice(2);
const wantsDashboard =
argv.includes('dashboard') || argv.includes('--dashboard');
if (wantsDashboard) {
const projectRoot = path.resolve(__dirname, '../../');
const dashboardEntry = path.join(
projectRoot,
'packages/gs-squad-dashboard/dist/cli.js'
);
const child = spawn(process.execPath, [ dashboardEntry ], {
stdio: 'inherit',
env: { ...process.env }
});
child.on('exit', async (code) => {
try {
await app.close();
} finally {
process.exit(code ?? 0);
}
});
return;
}
const cliCommand = app.get(McpCliCommand);
await cliCommand.run();
}
// Only execute bootstrap if this file is run directly (not imported)
Iif (require.main === module) {
bootstrap().catch((error) => {
process.stderr.write(
`[FATAL] Failed to start MCP server: ${
error instanceof Error ? error.message : String(error)
}\n`
);
if (error instanceof Error && error.stack) {
process.stderr.write(`[STACK] ${error.stack}\n`);
}
process.exit(1);
});
}
|