@solidxai/solidctl 0.1.46-beta.1 → 0.1.46-beta.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/dist/commands/agent-helper.d.ts +9 -2
- package/dist/commands/agent-helper.js +31 -15
- package/dist/commands/agent-helper.js.map +1 -1
- package/dist/commands/agent.command.js +1 -1
- package/dist/commands/agent.command.js.map +1 -1
- package/dist/commands/create-app/create-app.command.js +16 -0
- package/dist/commands/create-app/create-app.command.js.map +1 -1
- package/dist/commands/create-app/helpers.d.ts +1 -0
- package/dist/commands/create-app/helpers.js +40 -0
- package/dist/commands/create-app/helpers.js.map +1 -1
- package/dist/commands/mcp-launch.d.ts +20 -0
- package/dist/commands/mcp-launch.js +116 -0
- package/dist/commands/mcp-launch.js.map +1 -0
- package/dist/commands/mcp.command.js +3 -48
- package/dist/commands/mcp.command.js.map +1 -1
- package/dist/commands/migration.command.js +56 -5
- package/dist/commands/migration.command.js.map +1 -1
- package/dist/commands/start.command.js +146 -39
- package/dist/commands/start.command.js.map +1 -1
- package/dist/helper.d.ts +1 -0
- package/dist/helper.js +33 -0
- package/dist/helper.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.printAgentVersion = exports.getAgentVersion = exports.MCP_DEFAULT_OPTIONS = void 0;
|
|
7
|
+
exports.buildBridgedEnv = buildBridgedEnv;
|
|
8
|
+
exports.printBridgeSummary = printBridgeSummary;
|
|
9
|
+
exports.resolveMcpLaunchConfig = resolveMcpLaunchConfig;
|
|
10
|
+
exports.spawnMcpServer = spawnMcpServer;
|
|
11
|
+
const child_process_1 = require("child_process");
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const dotenv_1 = require("dotenv");
|
|
14
|
+
const helper_1 = require("../helper");
|
|
15
|
+
const agent_helper_1 = require("./agent-helper");
|
|
16
|
+
Object.defineProperty(exports, "getAgentVersion", { enumerable: true, get: function () { return agent_helper_1.getAgentVersion; } });
|
|
17
|
+
Object.defineProperty(exports, "printAgentVersion", { enumerable: true, get: function () { return agent_helper_1.printAgentVersion; } });
|
|
18
|
+
exports.MCP_DEFAULT_OPTIONS = {
|
|
19
|
+
port: '9000',
|
|
20
|
+
host: '0.0.0.0',
|
|
21
|
+
logLevel: 'INFO',
|
|
22
|
+
mountPath: '/mcp',
|
|
23
|
+
};
|
|
24
|
+
function resolveDatabaseUrl() {
|
|
25
|
+
if (process.env.DATABASE_URL) {
|
|
26
|
+
return (0, helper_1.normalizeDatabaseUrl)(process.env.DATABASE_URL);
|
|
27
|
+
}
|
|
28
|
+
const host = process.env.DEFAULT_DATABASE_HOST;
|
|
29
|
+
const port = process.env.DEFAULT_DATABASE_PORT;
|
|
30
|
+
const user = process.env.DEFAULT_DATABASE_USER;
|
|
31
|
+
const password = process.env.DEFAULT_DATABASE_PASSWORD;
|
|
32
|
+
const name = process.env.DEFAULT_DATABASE_NAME;
|
|
33
|
+
const dbType = (process.env.SOLID_CORE_DB_TYPE || 'postgres').toLowerCase();
|
|
34
|
+
if (!host || !port || !user || !name)
|
|
35
|
+
return undefined;
|
|
36
|
+
const encodedPw = password ? ':' + encodeURIComponent(password) : '';
|
|
37
|
+
if (dbType === 'mssql') {
|
|
38
|
+
return `mssql+pyodbc://${user}${encodedPw}@${host}:${port}/${name}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes&Encrypt=no`;
|
|
39
|
+
}
|
|
40
|
+
if (dbType === 'mysql') {
|
|
41
|
+
return `mysql+pymysql://${user}${encodedPw}@${host}:${port}/${name}`;
|
|
42
|
+
}
|
|
43
|
+
return `postgresql://${user}${encodedPw}@${host}:${port}/${name}`;
|
|
44
|
+
}
|
|
45
|
+
function buildBridgedEnv(projectRoot = process.cwd()) {
|
|
46
|
+
(0, dotenv_1.config)({ path: path_1.default.join(projectRoot, 'solid-api', '.env') });
|
|
47
|
+
const databaseUrl = resolveDatabaseUrl();
|
|
48
|
+
return {
|
|
49
|
+
...process.env,
|
|
50
|
+
SOLIDX_PROJECT_ROOT: projectRoot,
|
|
51
|
+
...(databaseUrl ? { DATABASE_URL: databaseUrl } : {}),
|
|
52
|
+
...(process.env.BASE_URL ? { BASE_URL: process.env.BASE_URL } : {}),
|
|
53
|
+
...(process.env.FRONTEND_BASE_URL
|
|
54
|
+
? { FRONTEND_BASE_URL: process.env.FRONTEND_BASE_URL }
|
|
55
|
+
: {}),
|
|
56
|
+
...(process.env.APP_ENCRYPTION_KEY
|
|
57
|
+
? { APP_ENCRYPTION_KEY: process.env.APP_ENCRYPTION_KEY }
|
|
58
|
+
: {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function printBridgeSummary(env) {
|
|
62
|
+
const bridgedKeys = [
|
|
63
|
+
'DATABASE_URL',
|
|
64
|
+
'SOLIDX_PROJECT_ROOT',
|
|
65
|
+
'BASE_URL',
|
|
66
|
+
'FRONTEND_BASE_URL',
|
|
67
|
+
'APP_ENCRYPTION_KEY',
|
|
68
|
+
];
|
|
69
|
+
const bridged = bridgedKeys.filter((k) => env[k]);
|
|
70
|
+
const missing = bridgedKeys.filter((k) => !env[k]);
|
|
71
|
+
console.log(`✔ Bridged env: ${bridged.join(', ') || 'none'}`);
|
|
72
|
+
if (missing.length)
|
|
73
|
+
console.warn(`⚠ Missing env: ${missing.join(', ')}`);
|
|
74
|
+
}
|
|
75
|
+
async function resolveMcpLaunchConfig(options, projectRoot = process.cwd()) {
|
|
76
|
+
await (0, agent_helper_1.checkAgentUpdate)({
|
|
77
|
+
isLocal: Boolean(options.local),
|
|
78
|
+
exitMode: 'throw',
|
|
79
|
+
});
|
|
80
|
+
const env = buildBridgedEnv(projectRoot);
|
|
81
|
+
if (!env.DATABASE_URL) {
|
|
82
|
+
throw new Error('DATABASE_URL is required for MCP mode.\n' +
|
|
83
|
+
' It is needed to validate API keys and write audit logs.\n' +
|
|
84
|
+
' Set it in your solid-api/.env or environment.');
|
|
85
|
+
}
|
|
86
|
+
const agentCommand = options.local
|
|
87
|
+
? (0, agent_helper_1.ensureAgentInstalledLocal)('throw')
|
|
88
|
+
: (0, agent_helper_1.ensureAgentInstalled)('throw');
|
|
89
|
+
(0, agent_helper_1.printAgentVersion)(agentCommand);
|
|
90
|
+
return {
|
|
91
|
+
command: agentCommand,
|
|
92
|
+
args: [
|
|
93
|
+
'mcp-remote',
|
|
94
|
+
'--host',
|
|
95
|
+
options.host,
|
|
96
|
+
'--port',
|
|
97
|
+
options.port,
|
|
98
|
+
'--log-level',
|
|
99
|
+
options.logLevel,
|
|
100
|
+
'--mount-path',
|
|
101
|
+
options.mountPath,
|
|
102
|
+
],
|
|
103
|
+
cwd: env.SOLIDX_PROJECT_ROOT,
|
|
104
|
+
env,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function spawnMcpServer(launchConfig) {
|
|
108
|
+
return (0, child_process_1.spawn)(launchConfig.command, launchConfig.args, {
|
|
109
|
+
cwd: launchConfig.cwd,
|
|
110
|
+
env: launchConfig.env,
|
|
111
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
112
|
+
shell: process.platform === 'win32',
|
|
113
|
+
detached: process.platform !== 'win32',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=mcp-launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-launch.js","sourceRoot":"","sources":["../../src/commands/mcp-launch.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,55 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.registerMcpCommand = registerMcpCommand;
|
|
7
4
|
const child_process_1 = require("child_process");
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const dotenv_1 = require("dotenv");
|
|
10
5
|
const helper_1 = require("../helper");
|
|
11
6
|
const agent_helper_1 = require("./agent-helper");
|
|
12
|
-
|
|
13
|
-
if (process.env.DATABASE_URL)
|
|
14
|
-
return process.env.DATABASE_URL;
|
|
15
|
-
const host = process.env.DEFAULT_DATABASE_HOST;
|
|
16
|
-
const port = process.env.DEFAULT_DATABASE_PORT;
|
|
17
|
-
const user = process.env.DEFAULT_DATABASE_USER;
|
|
18
|
-
const password = process.env.DEFAULT_DATABASE_PASSWORD;
|
|
19
|
-
const name = process.env.DEFAULT_DATABASE_NAME;
|
|
20
|
-
const dbType = (process.env.SOLID_CORE_DB_TYPE || 'postgres').toLowerCase();
|
|
21
|
-
if (!host || !port || !user || !name)
|
|
22
|
-
return undefined;
|
|
23
|
-
const encodedPw = password ? ':' + encodeURIComponent(password) : '';
|
|
24
|
-
if (dbType === 'mssql') {
|
|
25
|
-
return `mssql+pyodbc://${user}${encodedPw}@${host}:${port}/${name}?driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes&Encrypt=no`;
|
|
26
|
-
}
|
|
27
|
-
if (dbType === 'mysql') {
|
|
28
|
-
return `mysql+pymysql://${user}${encodedPw}@${host}:${port}/${name}`;
|
|
29
|
-
}
|
|
30
|
-
return `postgresql://${user}${encodedPw}@${host}:${port}/${name}`;
|
|
31
|
-
}
|
|
32
|
-
function buildBridgedEnv() {
|
|
33
|
-
const projectRoot = process.cwd();
|
|
34
|
-
(0, dotenv_1.config)({ path: path_1.default.join(projectRoot, 'solid-api', '.env') });
|
|
35
|
-
const databaseUrl = resolveDatabaseUrl();
|
|
36
|
-
return {
|
|
37
|
-
...process.env,
|
|
38
|
-
SOLIDX_PROJECT_ROOT: projectRoot,
|
|
39
|
-
...(databaseUrl ? { DATABASE_URL: databaseUrl } : {}),
|
|
40
|
-
...(process.env.BASE_URL ? { BASE_URL: process.env.BASE_URL } : {}),
|
|
41
|
-
...(process.env.FRONTEND_BASE_URL ? { FRONTEND_BASE_URL: process.env.FRONTEND_BASE_URL } : {}),
|
|
42
|
-
...(process.env.APP_ENCRYPTION_KEY ? { APP_ENCRYPTION_KEY: process.env.APP_ENCRYPTION_KEY } : {}),
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function printBridgeSummary(env) {
|
|
46
|
-
const bridgedKeys = ['DATABASE_URL', 'SOLIDX_PROJECT_ROOT', 'BASE_URL', 'FRONTEND_BASE_URL', 'APP_ENCRYPTION_KEY'];
|
|
47
|
-
const bridged = bridgedKeys.filter((k) => env[k]);
|
|
48
|
-
const missing = bridgedKeys.filter((k) => !env[k]);
|
|
49
|
-
console.log(`✔ Bridged env: ${bridged.join(', ') || 'none'}`);
|
|
50
|
-
if (missing.length)
|
|
51
|
-
console.warn(`⚠ Missing env: ${missing.join(', ')}`);
|
|
52
|
-
}
|
|
7
|
+
const mcp_launch_1 = require("./mcp-launch");
|
|
53
8
|
function registerMcpCommand(program) {
|
|
54
9
|
const mcp = program
|
|
55
10
|
.command('mcp')
|
|
@@ -76,7 +31,7 @@ function registerMcpCommand(program) {
|
|
|
76
31
|
.action(async (options) => {
|
|
77
32
|
await (0, agent_helper_1.checkAgentUpdate)({ isLocal: Boolean(options.local) });
|
|
78
33
|
(0, helper_1.validateProjectRoot)();
|
|
79
|
-
const env = buildBridgedEnv();
|
|
34
|
+
const env = (0, mcp_launch_1.buildBridgedEnv)();
|
|
80
35
|
if (!env.DATABASE_URL) {
|
|
81
36
|
console.error('❌ DATABASE_URL is required for MCP mode.\n' +
|
|
82
37
|
' It is needed to validate API keys and write audit logs.\n' +
|
|
@@ -85,7 +40,7 @@ function registerMcpCommand(program) {
|
|
|
85
40
|
}
|
|
86
41
|
const agentCommand = options.local ? (0, agent_helper_1.ensureAgentInstalledLocal)() : (0, agent_helper_1.ensureAgentInstalled)();
|
|
87
42
|
(0, agent_helper_1.printAgentVersion)(agentCommand);
|
|
88
|
-
printBridgeSummary(env);
|
|
43
|
+
(0, mcp_launch_1.printBridgeSummary)(env);
|
|
89
44
|
console.log(`▶ Starting SolidX MCP Server on ${options.host}:${options.port}`);
|
|
90
45
|
const result = (0, child_process_1.spawnSync)(agentCommand, [
|
|
91
46
|
'mcp-remote',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.command.js","sourceRoot":"","sources":["../../src/commands/mcp.command.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp.command.js","sourceRoot":"","sources":["../../src/commands/mcp.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -69,21 +69,28 @@ function runTypeormCli(args, solidApiDir, failureLabel) {
|
|
|
69
69
|
function registerMigrationCommand(program) {
|
|
70
70
|
program
|
|
71
71
|
.command('migration <action> [migrationName]')
|
|
72
|
-
.description('Generate, run, or
|
|
73
|
-
.
|
|
72
|
+
.description('Generate, run, revert, or remove-field TypeORM migrations for a datasource')
|
|
73
|
+
.option('-d, --datasource <datasource>', 'Datasource name (maps to src/typeorm-<datasource>-datasource.ts), required for generate/run/revert')
|
|
74
74
|
.option('-m, --module <module>', 'Module name, required for generate')
|
|
75
|
+
.option('-n, --name <modelName>', 'Model name (singularName), required for remove-field')
|
|
76
|
+
.option('--apply', 'Apply the cleanup instead of running a dry-run preview (used with remove-field)')
|
|
75
77
|
.addHelpText('after', `
|
|
76
78
|
Examples:
|
|
77
79
|
npx @solidxai/solidctl migration -d default -m onboarding generate AddPreApplicationMaster
|
|
78
80
|
npx @solidxai/solidctl migration -d default run
|
|
79
|
-
npx @solidxai/solidctl migration -d default revert
|
|
81
|
+
npx @solidxai/solidctl migration -d default revert
|
|
82
|
+
npx @solidxai/solidctl migration -n book remove-field
|
|
83
|
+
npx @solidxai/solidctl migration -n book remove-field --apply`)
|
|
80
84
|
.action((action, migrationName, options) => {
|
|
81
85
|
(0, helper_1.validateProjectRoot)();
|
|
82
86
|
const normalizedAction = action.trim().toLowerCase();
|
|
83
87
|
const projectRoot = process.cwd();
|
|
84
88
|
const solidApiDir = path_1.default.join(projectRoot, 'solid-api');
|
|
85
|
-
ensureDatasourceFile(solidApiDir, options.datasource);
|
|
86
89
|
if (normalizedAction === 'generate') {
|
|
90
|
+
if (!options.datasource) {
|
|
91
|
+
fail('Option --datasource <datasource> is required for generate.');
|
|
92
|
+
}
|
|
93
|
+
ensureDatasourceFile(solidApiDir, options.datasource);
|
|
87
94
|
const { migrationTargetPath } = validateGenerateInputs(solidApiDir, options.datasource, options.module, migrationName);
|
|
88
95
|
runTypeormCli([
|
|
89
96
|
'typeorm-ts-node-commonjs',
|
|
@@ -95,18 +102,62 @@ Examples:
|
|
|
95
102
|
return;
|
|
96
103
|
}
|
|
97
104
|
if (normalizedAction === 'run') {
|
|
105
|
+
if (!options.datasource) {
|
|
106
|
+
fail('Option --datasource <datasource> is required for run.');
|
|
107
|
+
}
|
|
108
|
+
ensureDatasourceFile(solidApiDir, options.datasource);
|
|
98
109
|
console.log(`✅ Using datasource: src/typeorm-${options.datasource}-datasource.ts`);
|
|
99
110
|
console.log('➡ Running migrations...');
|
|
100
111
|
runTypeormCli(['typeorm-ts-node-commonjs', 'migration:run', '-d', `src/typeorm-${options.datasource}-datasource.ts`], solidApiDir, 'run migrations');
|
|
101
112
|
return;
|
|
102
113
|
}
|
|
103
114
|
if (normalizedAction === 'revert') {
|
|
115
|
+
if (!options.datasource) {
|
|
116
|
+
fail('Option --datasource <datasource> is required for revert.');
|
|
117
|
+
}
|
|
118
|
+
ensureDatasourceFile(solidApiDir, options.datasource);
|
|
104
119
|
console.log(`✅ Using datasource: src/typeorm-${options.datasource}-datasource.ts`);
|
|
105
120
|
console.log('➡ Reverting last migration...');
|
|
106
121
|
runTypeormCli(['typeorm-ts-node-commonjs', 'migration:revert', '-d', `src/typeorm-${options.datasource}-datasource.ts`], solidApiDir, 'revert migration');
|
|
107
122
|
return;
|
|
108
123
|
}
|
|
109
|
-
|
|
124
|
+
if (normalizedAction === 'remove-field') {
|
|
125
|
+
if (!options.name) {
|
|
126
|
+
console.error('Option --name <model> is required for remove-field.');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
const mainCliPath = path_1.default.join(solidApiDir, 'dist', 'main-cli.js');
|
|
130
|
+
if (!fs_1.default.existsSync(mainCliPath)) {
|
|
131
|
+
console.error(`solid-api CLI not found at ${mainCliPath}. Run "npx @solidxai/solidctl build" or "cd solid-api && npm run build" first.`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
const args = [
|
|
135
|
+
path_1.default.relative(solidApiDir, mainCliPath),
|
|
136
|
+
'migrate-removed-fields',
|
|
137
|
+
'-n',
|
|
138
|
+
options.name,
|
|
139
|
+
];
|
|
140
|
+
if (options.apply) {
|
|
141
|
+
args.push('-d', 'false');
|
|
142
|
+
}
|
|
143
|
+
console.log(`▶ Running removed-field cleanup for model "${options.name}"${options.apply ? ' (apply)' : ' (dry-run)'}`);
|
|
144
|
+
const result = (0, child_process_1.spawnSync)(process.execPath, args, {
|
|
145
|
+
cwd: solidApiDir,
|
|
146
|
+
stdio: 'inherit',
|
|
147
|
+
env: process.env,
|
|
148
|
+
});
|
|
149
|
+
if (result.error) {
|
|
150
|
+
console.error(`Failed to run cleanup-removed-fields: ${result.error.message}`);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
if (result.status !== 0) {
|
|
154
|
+
console.error(`cleanup-removed-fields exited with code ${result.status}`);
|
|
155
|
+
process.exit(result.status ?? 1);
|
|
156
|
+
}
|
|
157
|
+
console.log(`✔ cleanup-removed-fields completed for model "${options.name}"`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
fail(`Unknown action "${action}". Expected generate, run, revert, or remove-field.`);
|
|
110
161
|
});
|
|
111
162
|
}
|
|
112
163
|
//# sourceMappingURL=migration.command.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.command.js","sourceRoot":"","sources":["../../src/commands/migration.command.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"migration.command.js","sourceRoot":"","sources":["../../src/commands/migration.command.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@ const path_1 = __importDefault(require("path"));
|
|
|
11
11
|
const readline_1 = __importDefault(require("readline"));
|
|
12
12
|
const helper_1 = require("../helper");
|
|
13
13
|
const embedded_1 = require("../db/embedded");
|
|
14
|
+
const agent_helper_1 = require("./agent-helper");
|
|
15
|
+
const mcp_launch_1 = require("./mcp-launch");
|
|
14
16
|
class StartSupervisor {
|
|
15
17
|
projectRoot;
|
|
16
18
|
activeServices;
|
|
@@ -22,19 +24,26 @@ class StartSupervisor {
|
|
|
22
24
|
isInteractive;
|
|
23
25
|
npmCommand;
|
|
24
26
|
isEmbedded;
|
|
27
|
+
supportsMcp;
|
|
28
|
+
mcpPort;
|
|
25
29
|
embeddedServer = null;
|
|
30
|
+
mcpLaunchConfig = null;
|
|
26
31
|
shuttingDown = false;
|
|
32
|
+
startupPhase = true;
|
|
33
|
+
startupAbortInProgress = false;
|
|
27
34
|
exitCode = 0;
|
|
28
35
|
stdinWasRaw = false;
|
|
29
|
-
constructor(projectRoot, serviceScripts, options) {
|
|
36
|
+
constructor(projectRoot, serviceScripts, options, supportsMcp = false) {
|
|
30
37
|
this.projectRoot = projectRoot;
|
|
31
38
|
this.isInteractive = Boolean(process.stdout.isTTY && process.stdin.isTTY && !options.plain);
|
|
32
39
|
this.npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
33
40
|
this.isEmbedded = (0, embedded_1.isEmbeddedProject)(projectRoot);
|
|
41
|
+
this.supportsMcp = supportsMcp;
|
|
34
42
|
this.serviceScripts = serviceScripts;
|
|
35
43
|
this.activeServices = this.resolveActiveServices(options);
|
|
36
44
|
this.apiPort = this.resolveApiPort();
|
|
37
45
|
this.uiPort = this.resolveUiPort();
|
|
46
|
+
this.mcpPort = mcp_launch_1.MCP_DEFAULT_OPTIONS.port;
|
|
38
47
|
this.serviceConfigs = {
|
|
39
48
|
api: {
|
|
40
49
|
cwd: path_1.default.join(projectRoot, 'solid-api'),
|
|
@@ -46,33 +55,62 @@ class StartSupervisor {
|
|
|
46
55
|
label: 'ui',
|
|
47
56
|
color: chalk_1.default.magenta,
|
|
48
57
|
},
|
|
58
|
+
mcp: {
|
|
59
|
+
cwd: projectRoot,
|
|
60
|
+
label: 'mcp',
|
|
61
|
+
color: chalk_1.default.green,
|
|
62
|
+
},
|
|
49
63
|
};
|
|
50
64
|
this.serviceStates = {
|
|
51
65
|
api: this.createInitialState(),
|
|
52
66
|
ui: this.createInitialState(),
|
|
67
|
+
mcp: this.createInitialState(),
|
|
53
68
|
};
|
|
54
69
|
}
|
|
55
70
|
async start() {
|
|
56
71
|
this.attachSignalHandlers();
|
|
57
|
-
this.attachKeyboardControls();
|
|
58
72
|
this.printStatus('Starting SolidX dev processes');
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
let shouldStartServices = true;
|
|
74
|
+
try {
|
|
75
|
+
if (this.isEmbedded) {
|
|
76
|
+
await this.startEmbeddedDatabase();
|
|
77
|
+
shouldStartServices = !this.shuttingDown;
|
|
78
|
+
}
|
|
79
|
+
if (shouldStartServices && this.activeServices.includes('mcp')) {
|
|
80
|
+
await this.startMcpServer();
|
|
81
|
+
shouldStartServices = !this.shuttingDown;
|
|
82
|
+
}
|
|
83
|
+
if (shouldStartServices) {
|
|
84
|
+
this.startupPhase = false;
|
|
85
|
+
this.attachKeyboardControls();
|
|
86
|
+
for (const serviceName of this.activeServices) {
|
|
87
|
+
this.spawnService(serviceName);
|
|
88
|
+
}
|
|
89
|
+
this.renderFooter();
|
|
90
|
+
await new Promise((resolve) => {
|
|
91
|
+
const poll = setInterval(() => {
|
|
92
|
+
if (!this.hasRunningChildren()) {
|
|
93
|
+
clearInterval(poll);
|
|
94
|
+
resolve();
|
|
95
|
+
}
|
|
96
|
+
}, 100);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
61
99
|
}
|
|
62
|
-
|
|
63
|
-
|
|
100
|
+
catch (error) {
|
|
101
|
+
if (error instanceof agent_helper_1.AgentCommandExit) {
|
|
102
|
+
this.exitCode = error.exitCode;
|
|
103
|
+
}
|
|
104
|
+
else if (this.exitCode === 0) {
|
|
105
|
+
this.exitCode = 1;
|
|
106
|
+
}
|
|
107
|
+
this.shuttingDown = true;
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
this.startupPhase = false;
|
|
111
|
+
await this.stopEmbeddedDatabase();
|
|
112
|
+
this.cleanupTerminal();
|
|
64
113
|
}
|
|
65
|
-
this.renderFooter();
|
|
66
|
-
await new Promise((resolve) => {
|
|
67
|
-
const poll = setInterval(() => {
|
|
68
|
-
if (!this.hasRunningChildren()) {
|
|
69
|
-
clearInterval(poll);
|
|
70
|
-
this.cleanupTerminal();
|
|
71
|
-
resolve();
|
|
72
|
-
}
|
|
73
|
-
}, 100);
|
|
74
|
-
});
|
|
75
|
-
await this.stopEmbeddedDatabase();
|
|
76
114
|
process.exit(this.exitCode);
|
|
77
115
|
}
|
|
78
116
|
async startEmbeddedDatabase() {
|
|
@@ -87,13 +125,18 @@ class StartSupervisor {
|
|
|
87
125
|
});
|
|
88
126
|
try {
|
|
89
127
|
await this.embeddedServer.ready;
|
|
128
|
+
if (this.shuttingDown) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
90
131
|
this.printStatus(`Embedded database ready on ${config.host}:${config.port}`);
|
|
91
132
|
}
|
|
92
133
|
catch (error) {
|
|
134
|
+
if (this.shuttingDown) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
93
137
|
const message = error instanceof Error ? error.message : String(error);
|
|
94
138
|
this.printStatus(`Embedded database failed to start: ${message}`);
|
|
95
|
-
|
|
96
|
-
process.exit(1);
|
|
139
|
+
throw error;
|
|
97
140
|
}
|
|
98
141
|
}
|
|
99
142
|
async stopEmbeddedDatabase() {
|
|
@@ -104,6 +147,25 @@ class StartSupervisor {
|
|
|
104
147
|
await (0, embedded_1.stopEmbeddedServer)(this.embeddedServer.child);
|
|
105
148
|
this.embeddedServer = null;
|
|
106
149
|
}
|
|
150
|
+
async startMcpServer() {
|
|
151
|
+
this.printStatus('Starting MCP server');
|
|
152
|
+
try {
|
|
153
|
+
this.mcpLaunchConfig = await (0, mcp_launch_1.resolveMcpLaunchConfig)({ ...mcp_launch_1.MCP_DEFAULT_OPTIONS }, this.projectRoot);
|
|
154
|
+
this.mcpPort = this.mcpLaunchConfig.args[this.mcpLaunchConfig.args.indexOf('--port') + 1];
|
|
155
|
+
this.printStatus(`MCP server config resolved (port ${this.mcpPort})`);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
if (this.shuttingDown) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
if (error instanceof agent_helper_1.AgentCommandExit) {
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
165
|
+
this.printStatus(`MCP server failed to initialize: ${message}`);
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
107
169
|
createInitialState() {
|
|
108
170
|
return {
|
|
109
171
|
child: null,
|
|
@@ -121,21 +183,42 @@ class StartSupervisor {
|
|
|
121
183
|
if (options.ui) {
|
|
122
184
|
selectedServices.push('ui');
|
|
123
185
|
}
|
|
124
|
-
|
|
186
|
+
if (this.supportsMcp && options.mcp) {
|
|
187
|
+
selectedServices.push('mcp');
|
|
188
|
+
}
|
|
189
|
+
if (selectedServices.length) {
|
|
190
|
+
return selectedServices;
|
|
191
|
+
}
|
|
192
|
+
const defaults = ['api', 'ui'];
|
|
193
|
+
if (this.supportsMcp) {
|
|
194
|
+
defaults.push('mcp');
|
|
195
|
+
}
|
|
196
|
+
return defaults;
|
|
125
197
|
}
|
|
126
198
|
spawnService(serviceName) {
|
|
127
199
|
const config = this.serviceConfigs[serviceName];
|
|
128
200
|
const state = this.serviceStates[serviceName];
|
|
129
|
-
const scriptName = this.serviceScripts[serviceName];
|
|
130
201
|
state.restartRequested = false;
|
|
131
202
|
state.stoppingForShutdown = false;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
203
|
+
let child;
|
|
204
|
+
if (serviceName === 'mcp') {
|
|
205
|
+
if (!this.mcpLaunchConfig) {
|
|
206
|
+
this.printLog(serviceName, 'MCP launch config not available', true);
|
|
207
|
+
this.handleUnexpectedExit(serviceName, 1);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
child = (0, mcp_launch_1.spawnMcpServer)(this.mcpLaunchConfig);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
const scriptName = this.serviceScripts[serviceName];
|
|
214
|
+
child = (0, child_process_1.spawn)(this.npmCommand, ['run', scriptName], {
|
|
215
|
+
cwd: config.cwd,
|
|
216
|
+
env: process.env,
|
|
217
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
218
|
+
shell: false,
|
|
219
|
+
detached: process.platform !== 'win32',
|
|
220
|
+
});
|
|
221
|
+
}
|
|
139
222
|
state.child = child;
|
|
140
223
|
this.printStatus(`Started ${config.label}`);
|
|
141
224
|
child.stdout?.on('data', (chunk) => {
|
|
@@ -209,12 +292,13 @@ class StartSupervisor {
|
|
|
209
292
|
const serviceSegments = [];
|
|
210
293
|
const controlSegments = ['q quit', 'c clear'];
|
|
211
294
|
if (this.activeServices.includes('api')) {
|
|
212
|
-
serviceSegments.push(`API (a restart, d
|
|
213
|
-
controlSegments.push('a restart API');
|
|
295
|
+
serviceSegments.push(`API (a restart, d docs, :${this.apiPort})`);
|
|
214
296
|
}
|
|
215
297
|
if (this.activeServices.includes('ui')) {
|
|
216
298
|
serviceSegments.push(`UI (u restart, o open, :${this.uiPort})`);
|
|
217
|
-
|
|
299
|
+
}
|
|
300
|
+
if (this.activeServices.includes('mcp')) {
|
|
301
|
+
serviceSegments.push(`MCP (m restart, :${this.mcpPort})`);
|
|
218
302
|
}
|
|
219
303
|
if (this.activeServices.length > 1) {
|
|
220
304
|
controlSegments.push('r restart all');
|
|
@@ -317,6 +401,11 @@ class StartSupervisor {
|
|
|
317
401
|
this.restartService('ui');
|
|
318
402
|
}
|
|
319
403
|
break;
|
|
404
|
+
case 'm':
|
|
405
|
+
if (this.activeServices.includes('mcp')) {
|
|
406
|
+
this.restartService('mcp');
|
|
407
|
+
}
|
|
408
|
+
break;
|
|
320
409
|
case 'r':
|
|
321
410
|
for (const serviceName of this.activeServices) {
|
|
322
411
|
this.restartService(serviceName);
|
|
@@ -423,6 +512,13 @@ class StartSupervisor {
|
|
|
423
512
|
this.exitCode = code;
|
|
424
513
|
this.shuttingDown = true;
|
|
425
514
|
this.printStatus('Shutting down');
|
|
515
|
+
if (this.startupPhase) {
|
|
516
|
+
if (!this.startupAbortInProgress) {
|
|
517
|
+
this.startupAbortInProgress = true;
|
|
518
|
+
void this.abortStartup();
|
|
519
|
+
}
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
426
522
|
for (const serviceName of this.activeServices) {
|
|
427
523
|
const state = this.serviceStates[serviceName];
|
|
428
524
|
state.stoppingForShutdown = true;
|
|
@@ -431,6 +527,11 @@ class StartSupervisor {
|
|
|
431
527
|
}
|
|
432
528
|
this.renderFooter();
|
|
433
529
|
}
|
|
530
|
+
async abortStartup() {
|
|
531
|
+
await this.stopEmbeddedDatabase();
|
|
532
|
+
this.cleanupTerminal();
|
|
533
|
+
process.exit(this.exitCode);
|
|
534
|
+
}
|
|
434
535
|
hasRunningChildren() {
|
|
435
536
|
return this.activeServices.some((serviceName) => {
|
|
436
537
|
return this.serviceStates[serviceName].child !== null;
|
|
@@ -508,32 +609,38 @@ class StartSupervisor {
|
|
|
508
609
|
}
|
|
509
610
|
}
|
|
510
611
|
function registerStartCommand(program) {
|
|
511
|
-
const registerSupervisorCommand = (commandName, description, serviceScripts) => {
|
|
512
|
-
program
|
|
612
|
+
const registerSupervisorCommand = (commandName, description, serviceScripts, supportsMcp = false) => {
|
|
613
|
+
const command = program
|
|
513
614
|
.command(commandName)
|
|
514
615
|
.description(description)
|
|
515
616
|
.option('--api', 'Only supervise solid-api')
|
|
516
617
|
.option('--controls', 'Enable interactive controls with pinned footer and keyboard shortcuts (default on TTYs)')
|
|
517
618
|
.option('--plain', 'Disable interactive controls and print merged logs only')
|
|
518
|
-
.option('--ui', 'Only supervise solid-ui')
|
|
519
|
-
|
|
619
|
+
.option('--ui', 'Only supervise solid-ui');
|
|
620
|
+
if (supportsMcp) {
|
|
621
|
+
command.option('--mcp', 'Only supervise the MCP server');
|
|
622
|
+
}
|
|
623
|
+
command.action(async (options) => {
|
|
520
624
|
(0, helper_1.validateProjectRoot)();
|
|
521
625
|
const selectedServices = [
|
|
522
626
|
...(options.api ? ['api'] : []),
|
|
523
627
|
...(options.ui ? ['ui'] : []),
|
|
628
|
+
...(supportsMcp && options.mcp ? ['mcp'] : []),
|
|
524
629
|
];
|
|
525
|
-
const activeServices = selectedServices.length ? selectedServices : ['api', 'ui'];
|
|
630
|
+
const activeServices = selectedServices.length ? selectedServices : (supportsMcp ? ['api', 'ui', 'mcp'] : ['api', 'ui']);
|
|
526
631
|
for (const serviceName of activeServices) {
|
|
632
|
+
if (serviceName === 'mcp')
|
|
633
|
+
continue;
|
|
527
634
|
(0, helper_1.validateProjectScript)(serviceName === 'api' ? 'solid-api' : 'solid-ui', serviceScripts[serviceName]);
|
|
528
635
|
}
|
|
529
|
-
const supervisor = new StartSupervisor(process.cwd(), serviceScripts, options);
|
|
636
|
+
const supervisor = new StartSupervisor(process.cwd(), serviceScripts, options, supportsMcp);
|
|
530
637
|
await supervisor.start();
|
|
531
638
|
});
|
|
532
639
|
};
|
|
533
|
-
registerSupervisorCommand('start:dev', 'Start solid-api
|
|
640
|
+
registerSupervisorCommand('start:dev', 'Start solid-api, solid-ui, and MCP dev processes in a single supervisor', {
|
|
534
641
|
api: 'solidx:dev',
|
|
535
642
|
ui: 'solidx:dev',
|
|
536
|
-
});
|
|
643
|
+
}, true);
|
|
537
644
|
registerSupervisorCommand('start', 'Start solid-api and solid-ui standard processes in a single supervisor', {
|
|
538
645
|
api: 'start',
|
|
539
646
|
ui: 'dev',
|