@defai.digital/automatosx 11.2.4 → 11.2.6
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 +1 -1
- package/dist/index.js +296 -200
- package/dist/mcp/index.js +172 -105
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as path4 from 'path';
|
|
3
|
-
import path4__default, { dirname, join, isAbsolute, basename, resolve, extname as extname$1,
|
|
3
|
+
import path4__default, { dirname, join, isAbsolute, basename, resolve, extname as extname$1, sep, relative, normalize, parse as parse$1, delimiter } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import * as fs4 from 'fs/promises';
|
|
6
6
|
import { mkdir, appendFile, access as access$1, readFile, stat, rm, readdir, copyFile, writeFile, rename, unlink, constants as constants$1, realpath as realpath$1 } from 'fs/promises';
|
|
@@ -393,7 +393,7 @@ var init_process_manager = __esm({
|
|
|
393
393
|
if (child.killed || child.exitCode !== null) {
|
|
394
394
|
continue;
|
|
395
395
|
}
|
|
396
|
-
killPromises.push(new Promise((
|
|
396
|
+
killPromises.push(new Promise((resolve13) => {
|
|
397
397
|
let mainTimeoutId = null;
|
|
398
398
|
let fallbackTimeoutId = null;
|
|
399
399
|
let resolved = false;
|
|
@@ -408,7 +408,7 @@ var init_process_manager = __esm({
|
|
|
408
408
|
}
|
|
409
409
|
if (!resolved) {
|
|
410
410
|
resolved = true;
|
|
411
|
-
|
|
411
|
+
resolve13();
|
|
412
412
|
}
|
|
413
413
|
};
|
|
414
414
|
child.once("exit", () => {
|
|
@@ -433,8 +433,8 @@ var init_process_manager = __esm({
|
|
|
433
433
|
try {
|
|
434
434
|
await Promise.race([
|
|
435
435
|
Promise.all(killPromises),
|
|
436
|
-
new Promise((
|
|
437
|
-
finalTimeoutId = setTimeout(
|
|
436
|
+
new Promise((resolve13) => {
|
|
437
|
+
finalTimeoutId = setTimeout(resolve13, timeout);
|
|
438
438
|
})
|
|
439
439
|
]);
|
|
440
440
|
} finally {
|
|
@@ -2582,7 +2582,8 @@ var init_base_provider = __esm({
|
|
|
2582
2582
|
try {
|
|
2583
2583
|
const cliCommand2 = this.getCLICommand();
|
|
2584
2584
|
const cliArgs = await this.getCLIArgs();
|
|
2585
|
-
const
|
|
2585
|
+
const escapedArgs = cliArgs.map((arg) => this.escapeShellArg(arg));
|
|
2586
|
+
const argsString = escapedArgs.length > 0 ? escapedArgs.join(" ") + " " : "";
|
|
2586
2587
|
const escapedPrompt = this.escapeShellArg(prompt);
|
|
2587
2588
|
const fullCommand = `${cliCommand2} ${argsString}${escapedPrompt}`;
|
|
2588
2589
|
const commandLength = fullCommand.length;
|
|
@@ -2625,7 +2626,7 @@ var init_base_provider = __esm({
|
|
|
2625
2626
|
* @returns Promise resolving to stdout and stderr
|
|
2626
2627
|
*/
|
|
2627
2628
|
async executeWithSpawn(command, cliCommand2) {
|
|
2628
|
-
return new Promise((
|
|
2629
|
+
return new Promise((resolve13, reject) => {
|
|
2629
2630
|
const child = spawn(command, [], {
|
|
2630
2631
|
shell: true,
|
|
2631
2632
|
// Auto-detects: cmd.exe on Windows, /bin/sh on Unix
|
|
@@ -2724,11 +2725,16 @@ var init_base_provider = __esm({
|
|
|
2724
2725
|
if (stderr) {
|
|
2725
2726
|
logger.debug(`${cliCommand2} CLI stderr output`, { stderr: stderr.trim() });
|
|
2726
2727
|
}
|
|
2727
|
-
if (code === 0 || code === null) {
|
|
2728
|
+
if ((code === 0 || code === null) && !signal) {
|
|
2728
2729
|
if (progressParser) {
|
|
2729
2730
|
progressParser.succeed(`${cliCommand2} completed successfully`);
|
|
2730
2731
|
}
|
|
2731
|
-
|
|
2732
|
+
resolve13({ stdout, stderr });
|
|
2733
|
+
} else if (signal) {
|
|
2734
|
+
if (progressParser) {
|
|
2735
|
+
progressParser.fail(`${cliCommand2} killed by signal ${signal}`);
|
|
2736
|
+
}
|
|
2737
|
+
reject(new Error(`${cliCommand2} CLI killed by signal ${signal}. stderr: ${stderr || "none"}`));
|
|
2732
2738
|
} else {
|
|
2733
2739
|
if (progressParser) {
|
|
2734
2740
|
progressParser.fail(`${cliCommand2} failed with code ${code}`);
|
|
@@ -2778,7 +2784,7 @@ var init_base_provider = __esm({
|
|
|
2778
2784
|
* @returns Promise resolving to stdout and stderr
|
|
2779
2785
|
*/
|
|
2780
2786
|
async executeWithStdin(cliCommand2, cliArgs, prompt) {
|
|
2781
|
-
return new Promise((
|
|
2787
|
+
return new Promise((resolve13, reject) => {
|
|
2782
2788
|
const commandArgs = cliArgs ? cliArgs.split(" ").filter(Boolean) : [];
|
|
2783
2789
|
logger.debug(`Executing ${cliCommand2} CLI with stdin`, {
|
|
2784
2790
|
command: cliCommand2,
|
|
@@ -2891,7 +2897,7 @@ var init_base_provider = __esm({
|
|
|
2891
2897
|
if (progressParser) {
|
|
2892
2898
|
progressParser.succeed(`${cliCommand2} completed successfully`);
|
|
2893
2899
|
}
|
|
2894
|
-
|
|
2900
|
+
resolve13({ stdout, stderr });
|
|
2895
2901
|
} else {
|
|
2896
2902
|
if (progressParser) {
|
|
2897
2903
|
progressParser.fail(`${cliCommand2} failed with code ${code}`);
|
|
@@ -3014,6 +3020,10 @@ ${fullPrompt}
|
|
|
3014
3020
|
errors: responseValidation.error.issues,
|
|
3015
3021
|
response
|
|
3016
3022
|
});
|
|
3023
|
+
throw new ProviderError(
|
|
3024
|
+
`Provider returned invalid response structure: ${responseValidation.error.issues.map((i) => i.message).join(", ")}`,
|
|
3025
|
+
"E1305" /* PROVIDER_EXEC_ERROR */
|
|
3026
|
+
);
|
|
3017
3027
|
}
|
|
3018
3028
|
return response;
|
|
3019
3029
|
} catch (error) {
|
|
@@ -3643,7 +3653,7 @@ var init_cli_wrapper = __esm({
|
|
|
3643
3653
|
* Spawn codex process
|
|
3644
3654
|
*/
|
|
3645
3655
|
async spawnProcess(args, prompt, timeout) {
|
|
3646
|
-
return new Promise((
|
|
3656
|
+
return new Promise((resolve13, reject) => {
|
|
3647
3657
|
let stdout = "";
|
|
3648
3658
|
let stderr = "";
|
|
3649
3659
|
let hasTimedOut = false;
|
|
@@ -3700,7 +3710,7 @@ var init_cli_wrapper = __esm({
|
|
|
3700
3710
|
return;
|
|
3701
3711
|
}
|
|
3702
3712
|
if (code === 0) {
|
|
3703
|
-
|
|
3713
|
+
resolve13({ stdout, stderr, exitCode: code });
|
|
3704
3714
|
} else {
|
|
3705
3715
|
reject(
|
|
3706
3716
|
new CodexError(
|
|
@@ -3733,7 +3743,7 @@ var init_cli_wrapper = __esm({
|
|
|
3733
3743
|
* Spawn codex process with streaming support
|
|
3734
3744
|
*/
|
|
3735
3745
|
async spawnProcessWithStreaming(args, prompt, timeout, renderer) {
|
|
3736
|
-
return new Promise((
|
|
3746
|
+
return new Promise((resolve13, reject) => {
|
|
3737
3747
|
let stdout = "";
|
|
3738
3748
|
let stderr = "";
|
|
3739
3749
|
let hasTimedOut = false;
|
|
@@ -3803,7 +3813,7 @@ var init_cli_wrapper = __esm({
|
|
|
3803
3813
|
if (renderer) {
|
|
3804
3814
|
renderer.succeed("Execution complete");
|
|
3805
3815
|
}
|
|
3806
|
-
|
|
3816
|
+
resolve13({ stdout, stderr, exitCode: code });
|
|
3807
3817
|
} else {
|
|
3808
3818
|
if (renderer) {
|
|
3809
3819
|
renderer.fail(`Process exited with code ${code}`);
|
|
@@ -4291,16 +4301,16 @@ var init_command_builder = __esm({
|
|
|
4291
4301
|
const args = [];
|
|
4292
4302
|
args.push("-p", this.escape(prompt));
|
|
4293
4303
|
if (options.provider) {
|
|
4294
|
-
args.push("--provider", options.provider);
|
|
4304
|
+
args.push("--provider", this.escape(options.provider));
|
|
4295
4305
|
}
|
|
4296
4306
|
if (options.model) {
|
|
4297
|
-
args.push("--model", options.model);
|
|
4307
|
+
args.push("--model", this.escape(options.model));
|
|
4298
4308
|
}
|
|
4299
4309
|
if (options.apiKey) {
|
|
4300
|
-
args.push("--api-key", options.apiKey);
|
|
4310
|
+
args.push("--api-key", this.escape(options.apiKey));
|
|
4301
4311
|
}
|
|
4302
4312
|
if (options.baseUrl) {
|
|
4303
|
-
args.push("--base-url", options.baseUrl);
|
|
4313
|
+
args.push("--base-url", this.escape(options.baseUrl));
|
|
4304
4314
|
}
|
|
4305
4315
|
if (options.directory) {
|
|
4306
4316
|
args.push("--directory", this.escape(options.directory));
|
|
@@ -4318,7 +4328,7 @@ var init_command_builder = __esm({
|
|
|
4318
4328
|
args.push("--selection", this.escape(options.selection));
|
|
4319
4329
|
}
|
|
4320
4330
|
if (options.lineRange) {
|
|
4321
|
-
args.push("--line-range", options.lineRange);
|
|
4331
|
+
args.push("--line-range", this.escape(options.lineRange));
|
|
4322
4332
|
}
|
|
4323
4333
|
if (options.gitDiff) {
|
|
4324
4334
|
args.push("--git-diff");
|
|
@@ -9279,7 +9289,7 @@ var PRECOMPILED_CONFIG = {
|
|
|
9279
9289
|
"enableFreeTierPrioritization": true,
|
|
9280
9290
|
"enableWorkloadAwareRouting": true
|
|
9281
9291
|
},
|
|
9282
|
-
"version": "11.2.
|
|
9292
|
+
"version": "11.2.6"
|
|
9283
9293
|
};
|
|
9284
9294
|
|
|
9285
9295
|
// src/core/config-schemas.ts
|
|
@@ -10902,7 +10912,7 @@ var configCommand = {
|
|
|
10902
10912
|
} else if (process.env.AUTOMATOSX_CONFIG_PATH) {
|
|
10903
10913
|
configPath = process.env.AUTOMATOSX_CONFIG_PATH;
|
|
10904
10914
|
} else {
|
|
10905
|
-
const projectConfig = resolve(process.cwd(), "
|
|
10915
|
+
const projectConfig = resolve(process.cwd(), "ax.config.json");
|
|
10906
10916
|
const hiddenConfig = resolve(process.cwd(), ".automatosx", "config.json");
|
|
10907
10917
|
const fs7 = await import('fs');
|
|
10908
10918
|
if (fs7.existsSync(projectConfig)) {
|
|
@@ -11165,9 +11175,9 @@ var PromptHelper = class {
|
|
|
11165
11175
|
*/
|
|
11166
11176
|
async question(query) {
|
|
11167
11177
|
const rl = this.ensureInterface();
|
|
11168
|
-
return new Promise((
|
|
11178
|
+
return new Promise((resolve13) => {
|
|
11169
11179
|
rl.question(query, (answer) => {
|
|
11170
|
-
|
|
11180
|
+
resolve13(answer.trim());
|
|
11171
11181
|
});
|
|
11172
11182
|
});
|
|
11173
11183
|
}
|
|
@@ -12128,7 +12138,7 @@ var __filename2 = fileURLToPath(import.meta.url);
|
|
|
12128
12138
|
var __dirname3 = dirname(__filename2);
|
|
12129
12139
|
function getPackageRoot() {
|
|
12130
12140
|
const currentDir = __dirname3;
|
|
12131
|
-
if (currentDir.includes("/dist")) {
|
|
12141
|
+
if (currentDir.includes(`${sep}dist`) || currentDir.includes("/dist")) {
|
|
12132
12142
|
return join(currentDir, "..");
|
|
12133
12143
|
} else {
|
|
12134
12144
|
return join(currentDir, "../..");
|
|
@@ -13362,18 +13372,30 @@ var setupCommand = {
|
|
|
13362
13372
|
} else if (axCliConfigured === "manual_required") {
|
|
13363
13373
|
console.log(chalk5.yellow(" \u26A0 ax-cli detected - manual MCP configuration required"));
|
|
13364
13374
|
console.log(chalk5.gray(" Run: ax-cli mcp add automatosx --transport stdio --command ax --args mcp server"));
|
|
13375
|
+
} else if (axCliConfigured === "error") {
|
|
13376
|
+
console.log(chalk5.yellow(" \u26A0 ax-cli MCP configuration failed"));
|
|
13377
|
+
console.log(chalk5.gray(" CLI integration still works via subprocess"));
|
|
13365
13378
|
} else {
|
|
13366
13379
|
console.log(chalk5.green(" \u2713 ax-cli MCP integration configured"));
|
|
13367
13380
|
}
|
|
13381
|
+
let geminiMcpStatus = "skipped";
|
|
13368
13382
|
if (providers["gemini-cli"]) {
|
|
13369
13383
|
console.log(chalk5.cyan("\u{1F50C} Setting up Gemini CLI integration..."));
|
|
13370
13384
|
const geminiDir = join(projectDir, ".gemini");
|
|
13371
13385
|
const geminiDirExistedBefore = await checkExists2(geminiDir);
|
|
13372
|
-
await setupGeminiIntegration(projectDir, packageRoot);
|
|
13386
|
+
geminiMcpStatus = await setupGeminiIntegration(projectDir, packageRoot);
|
|
13373
13387
|
if (!geminiDirExistedBefore) {
|
|
13374
13388
|
createdResources.push(geminiDir);
|
|
13375
13389
|
}
|
|
13376
|
-
|
|
13390
|
+
if (geminiMcpStatus === "configured") {
|
|
13391
|
+
console.log(chalk5.green(" \u2713 Gemini CLI MCP integration configured"));
|
|
13392
|
+
} else if (geminiMcpStatus === "skipped") {
|
|
13393
|
+
console.log(chalk5.yellow(" \u26A0 Gemini CLI MCP skipped (MCP server not found)"));
|
|
13394
|
+
console.log(chalk5.gray(" CLI integration still works via subprocess"));
|
|
13395
|
+
} else {
|
|
13396
|
+
console.log(chalk5.yellow(" \u26A0 Gemini CLI MCP configuration failed"));
|
|
13397
|
+
console.log(chalk5.gray(" CLI integration still works via subprocess"));
|
|
13398
|
+
}
|
|
13377
13399
|
}
|
|
13378
13400
|
console.log(chalk5.cyan("\u{1F4C2} Creating workspace directories..."));
|
|
13379
13401
|
await createWorkspaceDirectories(projectDir);
|
|
@@ -13382,17 +13404,11 @@ var setupCommand = {
|
|
|
13382
13404
|
const isGitRepo = await checkExists2(gitDir);
|
|
13383
13405
|
if (!isGitRepo) {
|
|
13384
13406
|
console.log(chalk5.cyan("\u{1F527} Initializing git repository..."));
|
|
13385
|
-
await initializeGitRepository(projectDir);
|
|
13386
|
-
|
|
13387
|
-
|
|
13388
|
-
|
|
13389
|
-
const codexDir = join(projectDir, ".codex");
|
|
13390
|
-
const codexDirExistedBefore = await checkExists2(codexDir);
|
|
13391
|
-
await setupCodexIntegration(projectDir, packageRoot);
|
|
13392
|
-
if (!codexDirExistedBefore) {
|
|
13393
|
-
createdResources.push(codexDir);
|
|
13407
|
+
const gitInitSuccess = await initializeGitRepository(projectDir);
|
|
13408
|
+
if (gitInitSuccess) {
|
|
13409
|
+
console.log(chalk5.green(" \u2713 Git repository initialized"));
|
|
13410
|
+
}
|
|
13394
13411
|
}
|
|
13395
|
-
console.log(chalk5.green(" \u2713 Codex CLI MCP integration configured"));
|
|
13396
13412
|
console.log(chalk5.cyan("\u{1F4DD} Updating .gitignore..."));
|
|
13397
13413
|
await updateGitignore(projectDir);
|
|
13398
13414
|
console.log(chalk5.green(" \u2713 .gitignore updated"));
|
|
@@ -13889,10 +13905,10 @@ async function initializeGitRepository(projectDir) {
|
|
|
13889
13905
|
const isGitRepo = await checkExists2(gitDir);
|
|
13890
13906
|
if (isGitRepo) {
|
|
13891
13907
|
logger.info("Git repository already exists, skipping initialization");
|
|
13892
|
-
return;
|
|
13908
|
+
return true;
|
|
13893
13909
|
}
|
|
13894
13910
|
const { spawn: spawn9 } = await import('child_process');
|
|
13895
|
-
await new Promise((
|
|
13911
|
+
await new Promise((resolve13, reject) => {
|
|
13896
13912
|
const child = spawn9("git", ["init"], {
|
|
13897
13913
|
cwd: projectDir,
|
|
13898
13914
|
stdio: "pipe",
|
|
@@ -13908,7 +13924,7 @@ async function initializeGitRepository(projectDir) {
|
|
|
13908
13924
|
reject(new Error(`git init failed with code ${code}: ${stderr}`));
|
|
13909
13925
|
} else {
|
|
13910
13926
|
logger.info("Git repository set up successfully");
|
|
13911
|
-
|
|
13927
|
+
resolve13();
|
|
13912
13928
|
}
|
|
13913
13929
|
});
|
|
13914
13930
|
child.on("error", (error) => {
|
|
@@ -13927,6 +13943,7 @@ async function initializeGitRepository(projectDir) {
|
|
|
13927
13943
|
return;
|
|
13928
13944
|
}
|
|
13929
13945
|
});
|
|
13946
|
+
return true;
|
|
13930
13947
|
} catch (error) {
|
|
13931
13948
|
const errorMessage = error.message;
|
|
13932
13949
|
if (errorMessage.includes("ENOENT") || errorMessage.includes("spawn git")) {
|
|
@@ -13942,6 +13959,7 @@ async function initializeGitRepository(projectDir) {
|
|
|
13942
13959
|
error: errorMessage
|
|
13943
13960
|
});
|
|
13944
13961
|
}
|
|
13962
|
+
return false;
|
|
13945
13963
|
}
|
|
13946
13964
|
}
|
|
13947
13965
|
async function updateGitignore(projectDir) {
|
|
@@ -14124,24 +14142,25 @@ async function initializeSpecKit(projectDir) {
|
|
|
14124
14142
|
async function setupGeminiIntegration(projectDir, packageRoot) {
|
|
14125
14143
|
const geminiDir = join(projectDir, ".gemini");
|
|
14126
14144
|
await mkdir(geminiDir, { recursive: true });
|
|
14127
|
-
await setupGeminiMCPConfig(projectDir, packageRoot);
|
|
14145
|
+
const mcpStatus = await setupGeminiMCPConfig(projectDir, packageRoot);
|
|
14146
|
+
return mcpStatus;
|
|
14128
14147
|
}
|
|
14129
14148
|
async function setupGeminiMCPConfig(projectDir, packageRoot) {
|
|
14130
14149
|
const mcpServersPath = join(projectDir, ".gemini", "mcp-servers.json");
|
|
14131
14150
|
try {
|
|
14132
|
-
const globalMcpPath = join(packageRoot, "dist", "mcp", "index.js");
|
|
14133
14151
|
const localMcpPath = join(projectDir, "node_modules", "@defai.digital", "automatosx", "dist", "mcp", "index.js");
|
|
14152
|
+
const globalMcpPath = join(packageRoot, "dist", "mcp", "index.js");
|
|
14134
14153
|
let mcpServerPath;
|
|
14135
|
-
if (await checkExists2(
|
|
14136
|
-
mcpServerPath = globalMcpPath;
|
|
14137
|
-
} else if (await checkExists2(localMcpPath)) {
|
|
14154
|
+
if (await checkExists2(localMcpPath)) {
|
|
14138
14155
|
mcpServerPath = localMcpPath;
|
|
14156
|
+
} else if (await checkExists2(globalMcpPath)) {
|
|
14157
|
+
mcpServerPath = globalMcpPath;
|
|
14139
14158
|
} else {
|
|
14140
14159
|
logger.warn("AutomatosX MCP server not found, skipping Gemini CLI MCP configuration", {
|
|
14141
|
-
|
|
14142
|
-
|
|
14160
|
+
localPath: localMcpPath,
|
|
14161
|
+
globalPath: globalMcpPath
|
|
14143
14162
|
});
|
|
14144
|
-
return;
|
|
14163
|
+
return "skipped";
|
|
14145
14164
|
}
|
|
14146
14165
|
let mcpConfig = {};
|
|
14147
14166
|
if (await checkExists2(mcpServersPath)) {
|
|
@@ -14173,32 +14192,15 @@ async function setupGeminiMCPConfig(projectDir, packageRoot) {
|
|
|
14173
14192
|
path: mcpServersPath,
|
|
14174
14193
|
mcpServerPath
|
|
14175
14194
|
});
|
|
14195
|
+
return "configured";
|
|
14176
14196
|
} catch (error) {
|
|
14177
14197
|
logger.warn("Failed to setup Gemini CLI MCP configuration", {
|
|
14178
14198
|
error: error.message,
|
|
14179
14199
|
path: mcpServersPath
|
|
14180
14200
|
});
|
|
14201
|
+
return "failed";
|
|
14181
14202
|
}
|
|
14182
14203
|
}
|
|
14183
|
-
async function setupCodexIntegration(projectDir, packageRoot) {
|
|
14184
|
-
const codexDir = join(projectDir, ".codex");
|
|
14185
|
-
await mkdir(codexDir, { recursive: true });
|
|
14186
|
-
await setupCodexMCPConfig(projectDir);
|
|
14187
|
-
}
|
|
14188
|
-
async function setupCodexMCPConfig(_projectDir, _packageRoot) {
|
|
14189
|
-
const mcpServersPath = join(_projectDir, ".codex", "mcp-servers.json");
|
|
14190
|
-
if (await checkExists2(mcpServersPath)) {
|
|
14191
|
-
try {
|
|
14192
|
-
const { unlink: unlink7 } = await import('fs/promises');
|
|
14193
|
-
await unlink7(mcpServersPath);
|
|
14194
|
-
logger.info("Removed .codex/mcp-servers.json - using CLI mode instead of MCP", {
|
|
14195
|
-
path: mcpServersPath
|
|
14196
|
-
});
|
|
14197
|
-
} catch {
|
|
14198
|
-
}
|
|
14199
|
-
}
|
|
14200
|
-
logger.debug("Codex integration configured for CLI mode (MCP disabled)");
|
|
14201
|
-
}
|
|
14202
14204
|
async function createWorkspaceDirectories(projectDir) {
|
|
14203
14205
|
const workspaceDirs = [
|
|
14204
14206
|
join(projectDir, "automatosx"),
|
|
@@ -16068,7 +16070,7 @@ var configureCommand = {
|
|
|
16068
16070
|
}
|
|
16069
16071
|
console.log(chalk5.bold.cyan("\n\u2728 AutomatosX Setup Wizard\n"));
|
|
16070
16072
|
console.log(chalk5.dim("This wizard will help you configure the OpenAI integration mode.\n"));
|
|
16071
|
-
const configPath = resolve(process.cwd(), "
|
|
16073
|
+
const configPath = resolve(process.cwd(), "ax.config.json");
|
|
16072
16074
|
const config = await loadConfig(configPath);
|
|
16073
16075
|
if (!config.providers.openai) {
|
|
16074
16076
|
console.log(chalk5.red("\n\u274C OpenAI provider not found in configuration\n"));
|
|
@@ -18237,23 +18239,29 @@ var Router = class {
|
|
|
18237
18239
|
const isCircuitOpen = this.circuitBreaker.isOpen(provider.name);
|
|
18238
18240
|
healthMultipliers.set(provider.name, isCircuitOpen ? 0.5 : 1);
|
|
18239
18241
|
}
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18254
|
-
|
|
18255
|
-
|
|
18256
|
-
|
|
18242
|
+
try {
|
|
18243
|
+
const scores = await getProviderMetricsTracker().getAllScores(
|
|
18244
|
+
providerNames,
|
|
18245
|
+
strategyManager.getWeights(),
|
|
18246
|
+
healthMultipliers
|
|
18247
|
+
);
|
|
18248
|
+
if (scores.length > 0) {
|
|
18249
|
+
const scoreMap = new Map(scores.map((s) => [s.provider, s.totalScore]));
|
|
18250
|
+
const originalOrder = providersToTry.map((p) => p.name);
|
|
18251
|
+
providersToTry = [...providersToTry].sort((a, b) => {
|
|
18252
|
+
const scoreA = scoreMap.get(a.name) ?? 0;
|
|
18253
|
+
const scoreB = scoreMap.get(b.name) ?? 0;
|
|
18254
|
+
return scoreB - scoreA;
|
|
18255
|
+
});
|
|
18256
|
+
logger.debug("Provider order after multi-factor routing", {
|
|
18257
|
+
original: originalOrder,
|
|
18258
|
+
reordered: providersToTry.map((p) => p.name),
|
|
18259
|
+
scores: Object.fromEntries(scoreMap)
|
|
18260
|
+
});
|
|
18261
|
+
}
|
|
18262
|
+
} catch (scoringError) {
|
|
18263
|
+
logger.warn("Multi-factor scoring failed, using priority order", {
|
|
18264
|
+
error: scoringError.message
|
|
18257
18265
|
});
|
|
18258
18266
|
}
|
|
18259
18267
|
}
|
|
@@ -20132,8 +20140,11 @@ var MemoryManager = class _MemoryManager {
|
|
|
20132
20140
|
}
|
|
20133
20141
|
const tempPath = `${this.config.dbPath}.restore.tmp`;
|
|
20134
20142
|
const srcDb = new Database2(srcPath, { readonly: true });
|
|
20135
|
-
|
|
20136
|
-
|
|
20143
|
+
try {
|
|
20144
|
+
await srcDb.backup(tempPath);
|
|
20145
|
+
} finally {
|
|
20146
|
+
srcDb.close();
|
|
20147
|
+
}
|
|
20137
20148
|
try {
|
|
20138
20149
|
const tempDb = new Database2(tempPath, { readonly: true });
|
|
20139
20150
|
tempDb.prepare("SELECT COUNT(*) FROM memory_entries").get();
|
|
@@ -22725,7 +22736,7 @@ var __filename4 = fileURLToPath(import.meta.url);
|
|
|
22725
22736
|
var __dirname5 = dirname(__filename4);
|
|
22726
22737
|
function getPackageRoot3() {
|
|
22727
22738
|
const currentDir = __dirname5;
|
|
22728
|
-
if (currentDir.includes("/dist")) {
|
|
22739
|
+
if (currentDir.includes(`${sep}dist`) || currentDir.includes("/dist")) {
|
|
22729
22740
|
return join(currentDir, "..");
|
|
22730
22741
|
} else {
|
|
22731
22742
|
return join(currentDir, "../..");
|
|
@@ -22856,6 +22867,7 @@ init_path_resolver();
|
|
|
22856
22867
|
// src/core/conversation-context-store.ts
|
|
22857
22868
|
init_esm_shims();
|
|
22858
22869
|
init_logger();
|
|
22870
|
+
var VALID_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
22859
22871
|
var ConversationContextStore = class {
|
|
22860
22872
|
storePath;
|
|
22861
22873
|
maxEntries;
|
|
@@ -22865,6 +22877,33 @@ var ConversationContextStore = class {
|
|
|
22865
22877
|
this.maxEntries = options.maxEntries ?? 100;
|
|
22866
22878
|
this.ttlMs = options.ttlMs ?? 24 * 60 * 60 * 1e3;
|
|
22867
22879
|
}
|
|
22880
|
+
/**
|
|
22881
|
+
* Validate and sanitize context ID to prevent path traversal attacks
|
|
22882
|
+
*
|
|
22883
|
+
* SECURITY: This is critical to prevent path traversal vulnerabilities.
|
|
22884
|
+
* A malicious ID like "../../.ssh/id_rsa" could read/write/delete files
|
|
22885
|
+
* outside the context store directory.
|
|
22886
|
+
*
|
|
22887
|
+
* @param id - Context ID to validate
|
|
22888
|
+
* @returns Sanitized file path within storePath
|
|
22889
|
+
* @throws Error if ID is invalid or path escapes storePath
|
|
22890
|
+
*/
|
|
22891
|
+
validateAndResolvePath(id) {
|
|
22892
|
+
if (!VALID_ID_PATTERN.test(id)) {
|
|
22893
|
+
throw new Error(
|
|
22894
|
+
`Invalid context ID: "${id}". IDs must be 1-64 characters, alphanumeric with underscores/hyphens only.`
|
|
22895
|
+
);
|
|
22896
|
+
}
|
|
22897
|
+
const filePath = join(this.storePath, `${id}.json`);
|
|
22898
|
+
const resolvedPath = resolve(filePath);
|
|
22899
|
+
const resolvedStorePath = resolve(this.storePath);
|
|
22900
|
+
const relativePath = relative(resolvedStorePath, resolvedPath);
|
|
22901
|
+
if (relativePath.startsWith("..") || relativePath.includes("/..") || relativePath.includes("\\..")) {
|
|
22902
|
+
logger.error("[ContextStore] Path traversal attempt blocked", { id, resolvedPath });
|
|
22903
|
+
throw new Error(`Security violation: context ID "${id}" would escape store directory`);
|
|
22904
|
+
}
|
|
22905
|
+
return resolvedPath;
|
|
22906
|
+
}
|
|
22868
22907
|
/**
|
|
22869
22908
|
* Initialize store (create directory if needed)
|
|
22870
22909
|
*/
|
|
@@ -22882,7 +22921,7 @@ var ConversationContextStore = class {
|
|
|
22882
22921
|
*/
|
|
22883
22922
|
async save(context) {
|
|
22884
22923
|
await this.initialize();
|
|
22885
|
-
const filePath =
|
|
22924
|
+
const filePath = this.validateAndResolvePath(context.id);
|
|
22886
22925
|
const data = JSON.stringify(context, null, 2);
|
|
22887
22926
|
try {
|
|
22888
22927
|
await writeFile(filePath, data, "utf-8");
|
|
@@ -22901,7 +22940,7 @@ var ConversationContextStore = class {
|
|
|
22901
22940
|
* Get conversation context by ID
|
|
22902
22941
|
*/
|
|
22903
22942
|
async get(id) {
|
|
22904
|
-
const filePath =
|
|
22943
|
+
const filePath = this.validateAndResolvePath(id);
|
|
22905
22944
|
try {
|
|
22906
22945
|
const data = await readFile(filePath, "utf-8");
|
|
22907
22946
|
const context = JSON.parse(data);
|
|
@@ -22955,7 +22994,7 @@ var ConversationContextStore = class {
|
|
|
22955
22994
|
* Delete context entry
|
|
22956
22995
|
*/
|
|
22957
22996
|
async delete(id) {
|
|
22958
|
-
const filePath =
|
|
22997
|
+
const filePath = this.validateAndResolvePath(id);
|
|
22959
22998
|
try {
|
|
22960
22999
|
await unlink(filePath);
|
|
22961
23000
|
logger.info("[ContextStore] Context deleted", { id });
|
|
@@ -25339,7 +25378,7 @@ ${context.task}`;
|
|
|
25339
25378
|
* @param signal - Optional AbortSignal to cancel the sleep
|
|
25340
25379
|
*/
|
|
25341
25380
|
sleep(ms, signal) {
|
|
25342
|
-
return new Promise((
|
|
25381
|
+
return new Promise((resolve13, reject) => {
|
|
25343
25382
|
if (signal?.aborted) {
|
|
25344
25383
|
reject(new Error("Sleep cancelled"));
|
|
25345
25384
|
return;
|
|
@@ -25349,7 +25388,7 @@ ${context.task}`;
|
|
|
25349
25388
|
if (abortHandler && signal) {
|
|
25350
25389
|
signal.removeEventListener("abort", abortHandler);
|
|
25351
25390
|
}
|
|
25352
|
-
|
|
25391
|
+
resolve13();
|
|
25353
25392
|
}, ms);
|
|
25354
25393
|
if (signal) {
|
|
25355
25394
|
abortHandler = () => {
|
|
@@ -26767,10 +26806,10 @@ var McpClient = class extends EventEmitter {
|
|
|
26767
26806
|
return;
|
|
26768
26807
|
}
|
|
26769
26808
|
if (this.state.status === "connecting") {
|
|
26770
|
-
return new Promise((
|
|
26809
|
+
return new Promise((resolve13, reject) => {
|
|
26771
26810
|
const onConnected = () => {
|
|
26772
26811
|
this.off("error", onError);
|
|
26773
|
-
|
|
26812
|
+
resolve13();
|
|
26774
26813
|
};
|
|
26775
26814
|
const onError = (err) => {
|
|
26776
26815
|
this.off("connected", onConnected);
|
|
@@ -26937,14 +26976,14 @@ var McpClient = class extends EventEmitter {
|
|
|
26937
26976
|
method,
|
|
26938
26977
|
params
|
|
26939
26978
|
};
|
|
26940
|
-
return new Promise((
|
|
26979
|
+
return new Promise((resolve13, reject) => {
|
|
26941
26980
|
const timeoutMs = timeout ?? this.config.timeout;
|
|
26942
26981
|
const timeoutHandle = setTimeout(() => {
|
|
26943
26982
|
this.pendingRequests.delete(id);
|
|
26944
26983
|
reject(new Error(`Request timed out after ${timeoutMs}ms: ${method}`));
|
|
26945
26984
|
}, timeoutMs);
|
|
26946
26985
|
this.pendingRequests.set(id, {
|
|
26947
|
-
resolve:
|
|
26986
|
+
resolve: resolve13,
|
|
26948
26987
|
reject,
|
|
26949
26988
|
timeout: timeoutHandle
|
|
26950
26989
|
});
|
|
@@ -27402,15 +27441,15 @@ var McpClientPool = class extends EventEmitter {
|
|
|
27402
27441
|
}
|
|
27403
27442
|
}
|
|
27404
27443
|
async waitForConnection(provider, pool) {
|
|
27405
|
-
return new Promise((
|
|
27444
|
+
return new Promise((resolve13, reject) => {
|
|
27406
27445
|
const timeout = setTimeout(() => {
|
|
27407
|
-
const index = pool.waitQueue.findIndex((w) => w.resolve ===
|
|
27446
|
+
const index = pool.waitQueue.findIndex((w) => w.resolve === resolve13);
|
|
27408
27447
|
if (index !== -1) {
|
|
27409
27448
|
pool.waitQueue.splice(index, 1);
|
|
27410
27449
|
}
|
|
27411
27450
|
reject(new ConnectionTimeoutError(provider, this.config.acquireTimeoutMs));
|
|
27412
27451
|
}, this.config.acquireTimeoutMs);
|
|
27413
|
-
pool.waitQueue.push({ resolve:
|
|
27452
|
+
pool.waitQueue.push({ resolve: resolve13, reject, timeout });
|
|
27414
27453
|
logger.debug("[MCP Pool] Waiting for connection", {
|
|
27415
27454
|
provider,
|
|
27416
27455
|
queuePosition: pool.waitQueue.length
|
|
@@ -28887,6 +28926,8 @@ var McpServer = class _McpServer {
|
|
|
28887
28926
|
initializationPromise = null;
|
|
28888
28927
|
initializationMutex = new Mutex();
|
|
28889
28928
|
// BUG FIX (v9.0.1): Prevent concurrent initialization
|
|
28929
|
+
stdinMutex = new Mutex();
|
|
28930
|
+
// BUG FIX: Prevent race conditions in stdin message processing
|
|
28890
28931
|
version;
|
|
28891
28932
|
ajv;
|
|
28892
28933
|
compiledValidators = /* @__PURE__ */ new Map();
|
|
@@ -29262,7 +29303,15 @@ var McpServer = class _McpServer {
|
|
|
29262
29303
|
* v10.5.0: Capture clientInfo for Smart Routing
|
|
29263
29304
|
*/
|
|
29264
29305
|
async handleInitialize(request, id) {
|
|
29265
|
-
const clientInfo = request.params
|
|
29306
|
+
const clientInfo = request.params?.clientInfo;
|
|
29307
|
+
if (!clientInfo || typeof clientInfo.name !== "string" || typeof clientInfo.version !== "string") {
|
|
29308
|
+
logger.warn("[MCP Server] Invalid initialize request: missing or invalid clientInfo", {
|
|
29309
|
+
hasParams: !!request.params,
|
|
29310
|
+
hasClientInfo: !!clientInfo,
|
|
29311
|
+
clientInfo
|
|
29312
|
+
});
|
|
29313
|
+
return this.createErrorResponse(id, -32600 /* InvalidRequest */, "Invalid initialize request: clientInfo with name and version is required");
|
|
29314
|
+
}
|
|
29266
29315
|
logger.info("[MCP Server] Initialize request received (fast handshake mode)", { clientInfo });
|
|
29267
29316
|
this.session = {
|
|
29268
29317
|
clientInfo: {
|
|
@@ -29388,67 +29437,77 @@ ${json}`;
|
|
|
29388
29437
|
logger.info("[MCP Server] Starting stdio JSON-RPC server...");
|
|
29389
29438
|
let buffer = "";
|
|
29390
29439
|
let contentLength = null;
|
|
29391
|
-
process.stdin.on("data",
|
|
29392
|
-
|
|
29393
|
-
|
|
29394
|
-
|
|
29395
|
-
|
|
29396
|
-
|
|
29397
|
-
|
|
29398
|
-
|
|
29399
|
-
|
|
29400
|
-
|
|
29401
|
-
|
|
29402
|
-
|
|
29403
|
-
|
|
29404
|
-
iterations
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
|
|
29409
|
-
|
|
29410
|
-
|
|
29411
|
-
const
|
|
29412
|
-
|
|
29413
|
-
|
|
29414
|
-
|
|
29415
|
-
|
|
29416
|
-
|
|
29417
|
-
|
|
29418
|
-
|
|
29440
|
+
process.stdin.on("data", (chunk) => {
|
|
29441
|
+
void this.stdinMutex.runExclusive(async () => {
|
|
29442
|
+
buffer += chunk.toString("utf-8");
|
|
29443
|
+
if (buffer.length > STDIO_MAX_BUFFER_SIZE) {
|
|
29444
|
+
logger.error("[MCP Server] Buffer size exceeded maximum", {
|
|
29445
|
+
bufferSize: buffer.length,
|
|
29446
|
+
maxSize: STDIO_MAX_BUFFER_SIZE
|
|
29447
|
+
});
|
|
29448
|
+
buffer = "";
|
|
29449
|
+
contentLength = null;
|
|
29450
|
+
return;
|
|
29451
|
+
}
|
|
29452
|
+
let iterations = 0;
|
|
29453
|
+
while (iterations < STDIO_MAX_ITERATIONS) {
|
|
29454
|
+
iterations++;
|
|
29455
|
+
if (contentLength === null) {
|
|
29456
|
+
const delimiter2 = buffer.includes("\r\n\r\n") ? "\r\n\r\n" : buffer.includes("\n\n") ? "\n\n" : null;
|
|
29457
|
+
if (!delimiter2) break;
|
|
29458
|
+
const headerEndIndex = buffer.indexOf(delimiter2);
|
|
29459
|
+
const headerBlock = buffer.slice(0, headerEndIndex);
|
|
29460
|
+
for (const line of headerBlock.split(delimiter2 === "\r\n\r\n" ? "\r\n" : "\n")) {
|
|
29461
|
+
const [key, value] = line.split(":", 2).map((s) => s.trim());
|
|
29462
|
+
if (key && key.toLowerCase() === "content-length" && value) {
|
|
29463
|
+
contentLength = parseInt(value, 10);
|
|
29464
|
+
if (isNaN(contentLength) || contentLength <= 0 || contentLength > STDIO_MAX_MESSAGE_SIZE) {
|
|
29465
|
+
logger.error("[MCP Server] Invalid Content-Length", { contentLength });
|
|
29466
|
+
this.writeResponse({
|
|
29467
|
+
jsonrpc: "2.0",
|
|
29468
|
+
id: null,
|
|
29469
|
+
error: {
|
|
29470
|
+
code: -32600 /* InvalidRequest */,
|
|
29471
|
+
message: `Invalid Content-Length: ${contentLength}`
|
|
29472
|
+
}
|
|
29473
|
+
});
|
|
29474
|
+
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
29475
|
+
contentLength = null;
|
|
29476
|
+
continue;
|
|
29477
|
+
}
|
|
29419
29478
|
}
|
|
29420
29479
|
}
|
|
29421
|
-
|
|
29422
|
-
|
|
29423
|
-
|
|
29480
|
+
if (contentLength === null) {
|
|
29481
|
+
logger.error("[MCP Server] No Content-Length header found");
|
|
29482
|
+
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
29483
|
+
continue;
|
|
29484
|
+
}
|
|
29424
29485
|
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
29425
|
-
continue;
|
|
29426
29486
|
}
|
|
29427
|
-
|
|
29428
|
-
|
|
29429
|
-
|
|
29430
|
-
|
|
29431
|
-
|
|
29432
|
-
|
|
29433
|
-
|
|
29434
|
-
|
|
29435
|
-
|
|
29436
|
-
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29487
|
+
if (Buffer.byteLength(buffer, "utf-8") < contentLength) break;
|
|
29488
|
+
const messageBuffer = Buffer.from(buffer, "utf-8");
|
|
29489
|
+
const jsonMessage = messageBuffer.slice(0, contentLength).toString("utf-8");
|
|
29490
|
+
buffer = messageBuffer.slice(contentLength).toString("utf-8");
|
|
29491
|
+
contentLength = null;
|
|
29492
|
+
try {
|
|
29493
|
+
const request = JSON.parse(jsonMessage);
|
|
29494
|
+
logger.debug("[MCP Server] Request received", { method: request.method, id: request.id });
|
|
29495
|
+
const response = await this.handleRequest(request);
|
|
29496
|
+
if (request.id !== void 0 && request.id !== null) {
|
|
29497
|
+
this.writeResponse(response);
|
|
29498
|
+
}
|
|
29499
|
+
} catch (error) {
|
|
29500
|
+
logger.error("[MCP Server] Failed to parse or handle request", { jsonMessage, error });
|
|
29501
|
+
this.writeResponse({ jsonrpc: "2.0", id: null, error: { code: -32700 /* ParseError */, message: "Parse error: Invalid JSON" } });
|
|
29440
29502
|
}
|
|
29441
|
-
} catch (error) {
|
|
29442
|
-
logger.error("[MCP Server] Failed to parse or handle request", { jsonMessage, error });
|
|
29443
|
-
this.writeResponse({ jsonrpc: "2.0", id: null, error: { code: -32700 /* ParseError */, message: "Parse error: Invalid JSON" } });
|
|
29444
29503
|
}
|
|
29445
|
-
|
|
29446
|
-
|
|
29447
|
-
|
|
29448
|
-
|
|
29449
|
-
|
|
29450
|
-
}
|
|
29451
|
-
}
|
|
29504
|
+
if (iterations >= STDIO_MAX_ITERATIONS) {
|
|
29505
|
+
logger.warn("[MCP Server] Maximum iterations reached in message processing", {
|
|
29506
|
+
iterations,
|
|
29507
|
+
bufferSize: buffer.length
|
|
29508
|
+
});
|
|
29509
|
+
}
|
|
29510
|
+
});
|
|
29452
29511
|
});
|
|
29453
29512
|
const shutdown = (reason) => {
|
|
29454
29513
|
logger.info(`[MCP Server] ${reason}`);
|
|
@@ -30339,7 +30398,7 @@ var UnifiedMCPManager = class {
|
|
|
30339
30398
|
};
|
|
30340
30399
|
this.setupProcessHandlers(config.name, childProcess, serverProcess);
|
|
30341
30400
|
this.servers.set(config.name, serverProcess);
|
|
30342
|
-
await new Promise((
|
|
30401
|
+
await new Promise((resolve13) => setTimeout(resolve13, 100));
|
|
30343
30402
|
if (childProcess.killed || childProcess.exitCode !== null) {
|
|
30344
30403
|
throw new Error(
|
|
30345
30404
|
`Server process exited immediately with code ${childProcess.exitCode}`
|
|
@@ -30362,6 +30421,14 @@ var UnifiedMCPManager = class {
|
|
|
30362
30421
|
name: config.name,
|
|
30363
30422
|
error: error.message
|
|
30364
30423
|
});
|
|
30424
|
+
const serverProcess = this.servers.get(config.name);
|
|
30425
|
+
if (serverProcess?.process && !serverProcess.process.killed) {
|
|
30426
|
+
try {
|
|
30427
|
+
serverProcess.process.kill("SIGTERM");
|
|
30428
|
+
} catch {
|
|
30429
|
+
}
|
|
30430
|
+
}
|
|
30431
|
+
this.servers.delete(config.name);
|
|
30365
30432
|
throw error;
|
|
30366
30433
|
}
|
|
30367
30434
|
}
|
|
@@ -30442,7 +30509,7 @@ var UnifiedMCPManager = class {
|
|
|
30442
30509
|
async restartServer(serverName) {
|
|
30443
30510
|
logger.info("UnifiedMCPManager: Restarting server", { name: serverName });
|
|
30444
30511
|
await this.stopServer(serverName);
|
|
30445
|
-
await new Promise((
|
|
30512
|
+
await new Promise((resolve13) => setTimeout(resolve13, 1e3));
|
|
30446
30513
|
const serverConfig = this.config.servers.find((s) => s.name === serverName);
|
|
30447
30514
|
if (!serverConfig) {
|
|
30448
30515
|
throw new Error(`Server configuration not found: ${serverName}`);
|
|
@@ -30689,31 +30756,34 @@ var UnifiedMCPManager = class {
|
|
|
30689
30756
|
this.pendingRestarts.set(serverName, restartTimer);
|
|
30690
30757
|
}
|
|
30691
30758
|
});
|
|
30692
|
-
|
|
30693
|
-
|
|
30694
|
-
|
|
30759
|
+
const shouldLog = this.config.logging?.logServerOutput;
|
|
30760
|
+
if (process2.stdout) {
|
|
30761
|
+
process2.stdout.on("data", (data) => {
|
|
30762
|
+
if (shouldLog) {
|
|
30695
30763
|
logger.debug(`MCP[${serverName}] stdout:`, {
|
|
30696
30764
|
data: data.toString().trim()
|
|
30697
30765
|
});
|
|
30698
|
-
}
|
|
30699
|
-
}
|
|
30700
|
-
|
|
30701
|
-
|
|
30766
|
+
}
|
|
30767
|
+
});
|
|
30768
|
+
}
|
|
30769
|
+
if (process2.stderr) {
|
|
30770
|
+
process2.stderr.on("data", (data) => {
|
|
30771
|
+
if (shouldLog) {
|
|
30702
30772
|
logger.debug(`MCP[${serverName}] stderr:`, {
|
|
30703
30773
|
data: data.toString().trim()
|
|
30704
30774
|
});
|
|
30705
|
-
}
|
|
30706
|
-
}
|
|
30775
|
+
}
|
|
30776
|
+
});
|
|
30707
30777
|
}
|
|
30708
30778
|
}
|
|
30709
30779
|
/**
|
|
30710
30780
|
* Wait for process to exit
|
|
30711
30781
|
*/
|
|
30712
30782
|
async waitForExit(process2, timeoutMs) {
|
|
30713
|
-
return new Promise((
|
|
30783
|
+
return new Promise((resolve13, reject) => {
|
|
30714
30784
|
const exitListener = () => {
|
|
30715
30785
|
clearTimeout(timeout);
|
|
30716
|
-
|
|
30786
|
+
resolve13();
|
|
30717
30787
|
};
|
|
30718
30788
|
const timeout = setTimeout(() => {
|
|
30719
30789
|
process2.removeListener("exit", exitListener);
|
|
@@ -31768,8 +31838,8 @@ var deleteCommand = {
|
|
|
31768
31838
|
input: process.stdin,
|
|
31769
31839
|
output: process.stdout
|
|
31770
31840
|
});
|
|
31771
|
-
const answer = await new Promise((
|
|
31772
|
-
rl.question(chalk5.yellow("\nAre you sure you want to delete this entry? (y/N): "),
|
|
31841
|
+
const answer = await new Promise((resolve13) => {
|
|
31842
|
+
rl.question(chalk5.yellow("\nAre you sure you want to delete this entry? (y/N): "), resolve13);
|
|
31773
31843
|
});
|
|
31774
31844
|
rl.close();
|
|
31775
31845
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
@@ -32729,7 +32799,7 @@ ${this.config.locale === "zh" ? "\u8ACB\u9078\u64C7" : "Select"}${defaultDisplay
|
|
|
32729
32799
|
async promptWithTimeout(prompt, parser, defaultValue) {
|
|
32730
32800
|
const rl = this.getReadline();
|
|
32731
32801
|
const template = this.getTemplate();
|
|
32732
|
-
return new Promise((
|
|
32802
|
+
return new Promise((resolve13) => {
|
|
32733
32803
|
let resolved = false;
|
|
32734
32804
|
let timeoutHandle;
|
|
32735
32805
|
let warningHandle;
|
|
@@ -32743,7 +32813,7 @@ ${this.config.locale === "zh" ? "\u8ACB\u9078\u64C7" : "Select"}${defaultDisplay
|
|
|
32743
32813
|
${template.timedOut}`);
|
|
32744
32814
|
rl.close();
|
|
32745
32815
|
this.rl = null;
|
|
32746
|
-
|
|
32816
|
+
resolve13({
|
|
32747
32817
|
value: defaultValue,
|
|
32748
32818
|
timedOut: true
|
|
32749
32819
|
});
|
|
@@ -32767,7 +32837,7 @@ ${template.timeoutWarning(30)}`);
|
|
|
32767
32837
|
clearTimeout(warningHandle);
|
|
32768
32838
|
}
|
|
32769
32839
|
const value = parser(answer);
|
|
32770
|
-
|
|
32840
|
+
resolve13({
|
|
32771
32841
|
value,
|
|
32772
32842
|
timedOut: false
|
|
32773
32843
|
});
|
|
@@ -33849,9 +33919,9 @@ ${action.modifications}`;
|
|
|
33849
33919
|
)
|
|
33850
33920
|
);
|
|
33851
33921
|
console.log(chalk5.gray(` Waiting ${delay}ms before retry...`));
|
|
33852
|
-
await new Promise((
|
|
33922
|
+
await new Promise((resolve13) => setTimeout(resolve13, delay));
|
|
33853
33923
|
} else {
|
|
33854
|
-
await new Promise((
|
|
33924
|
+
await new Promise((resolve13) => setTimeout(resolve13, delay));
|
|
33855
33925
|
}
|
|
33856
33926
|
}
|
|
33857
33927
|
const executionOptions = {
|
|
@@ -36988,7 +37058,7 @@ Result: ${result.stages.map((s) => s.output).join("\n\n")}`;
|
|
|
36988
37058
|
if (argv.save) {
|
|
36989
37059
|
try {
|
|
36990
37060
|
const savePath = argv.save;
|
|
36991
|
-
const saveDir =
|
|
37061
|
+
const saveDir = dirname(savePath);
|
|
36992
37062
|
await mkdir(saveDir, { recursive: true });
|
|
36993
37063
|
const outputData = formatForSave(result, argv.format || "text", {
|
|
36994
37064
|
agent: resolvedAgentName,
|
|
@@ -37036,7 +37106,7 @@ Response: ${result.response.content}`;
|
|
|
37036
37106
|
if (router) {
|
|
37037
37107
|
router.destroy();
|
|
37038
37108
|
}
|
|
37039
|
-
await new Promise((
|
|
37109
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
37040
37110
|
if (!verbosity.isQuiet()) {
|
|
37041
37111
|
const executionTime = ((Date.now() - executionStartTime) / 1e3).toFixed(1);
|
|
37042
37112
|
if (verbosity.isNormal()) {
|
|
@@ -37103,7 +37173,7 @@ Response: ${result.response.content}`;
|
|
|
37103
37173
|
logger.debug("Context cleanup error", { error: errMsg });
|
|
37104
37174
|
});
|
|
37105
37175
|
}
|
|
37106
|
-
await new Promise((
|
|
37176
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
37107
37177
|
try {
|
|
37108
37178
|
const { processManager: processManager2 } = await Promise.resolve().then(() => (init_process_manager(), process_manager_exports));
|
|
37109
37179
|
await processManager2.shutdown(3e3);
|
|
@@ -38002,10 +38072,10 @@ async function getCurrentVersion() {
|
|
|
38002
38072
|
return result.dependencies["@defai.digital/automatosx"]?.version || "unknown";
|
|
38003
38073
|
} catch (error) {
|
|
38004
38074
|
const { readFile: readFile24 } = await import('fs/promises');
|
|
38005
|
-
const { dirname:
|
|
38075
|
+
const { dirname: dirname17, join: join48 } = await import('path');
|
|
38006
38076
|
const { fileURLToPath: fileURLToPath8 } = await import('url');
|
|
38007
38077
|
const __filename7 = fileURLToPath8(import.meta.url);
|
|
38008
|
-
const __dirname8 =
|
|
38078
|
+
const __dirname8 = dirname17(__filename7);
|
|
38009
38079
|
const pkgPath = join48(__dirname8, "../../../package.json");
|
|
38010
38080
|
const content = await readFile24(pkgPath, "utf-8");
|
|
38011
38081
|
const pkg = JSON.parse(content);
|
|
@@ -38160,16 +38230,22 @@ var cleanupCommand = {
|
|
|
38160
38230
|
},
|
|
38161
38231
|
handler: async (argv) => {
|
|
38162
38232
|
try {
|
|
38233
|
+
const olderThan = argv.olderThan ?? 7;
|
|
38234
|
+
if (isNaN(olderThan) || olderThan < 0) {
|
|
38235
|
+
console.error(chalk5.red.bold("\n\u2717 Invalid --older-than value\n"));
|
|
38236
|
+
console.error(chalk5.red("Value must be a non-negative number (days)"));
|
|
38237
|
+
process.exit(1);
|
|
38238
|
+
}
|
|
38163
38239
|
const { detectProjectRoot: detectProjectRoot2 } = await Promise.resolve().then(() => (init_path_resolver(), path_resolver_exports));
|
|
38164
38240
|
const projectDir = await detectProjectRoot2(process.cwd());
|
|
38165
38241
|
const workspaceManager = new WorkspaceManager(projectDir);
|
|
38166
38242
|
if (!argv.confirm) {
|
|
38167
38243
|
console.log(chalk5.yellow(`
|
|
38168
|
-
\u26A0 This will remove temporary files older than ${
|
|
38244
|
+
\u26A0 This will remove temporary files older than ${olderThan} days`));
|
|
38169
38245
|
console.log(chalk5.gray("Run with --confirm to proceed\n"));
|
|
38170
38246
|
process.exit(0);
|
|
38171
38247
|
}
|
|
38172
|
-
const removed = await workspaceManager.cleanupTmp(
|
|
38248
|
+
const removed = await workspaceManager.cleanupTmp(olderThan);
|
|
38173
38249
|
console.log(chalk5.green.bold(`
|
|
38174
38250
|
\u2713 Cleanup complete
|
|
38175
38251
|
`));
|
|
@@ -39444,7 +39520,7 @@ var resumeCommand = {
|
|
|
39444
39520
|
if (router) {
|
|
39445
39521
|
router.destroy();
|
|
39446
39522
|
}
|
|
39447
|
-
await new Promise((
|
|
39523
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
39448
39524
|
console.log(chalk5.green.bold("\u2705 Complete\n"));
|
|
39449
39525
|
process.exit(0);
|
|
39450
39526
|
} catch (error) {
|
|
@@ -39464,7 +39540,7 @@ var resumeCommand = {
|
|
|
39464
39540
|
if (router) {
|
|
39465
39541
|
router.destroy();
|
|
39466
39542
|
}
|
|
39467
|
-
await new Promise((
|
|
39543
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
39468
39544
|
} catch (cleanupError) {
|
|
39469
39545
|
const errMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
39470
39546
|
logger.debug("Cleanup error ignored", { error: errMsg });
|
|
@@ -41755,7 +41831,7 @@ var doctorCommand = {
|
|
|
41755
41831
|
}
|
|
41756
41832
|
}
|
|
41757
41833
|
async function checkCLIVersion() {
|
|
41758
|
-
return new Promise((
|
|
41834
|
+
return new Promise((resolve13) => {
|
|
41759
41835
|
const child = spawn("gemini", ["--version"], {
|
|
41760
41836
|
stdio: ["ignore", "pipe", "pipe"]
|
|
41761
41837
|
});
|
|
@@ -41769,14 +41845,14 @@ var doctorCommand = {
|
|
|
41769
41845
|
});
|
|
41770
41846
|
child.on("close", (code) => {
|
|
41771
41847
|
if (code === 0 && stdout.trim()) {
|
|
41772
|
-
|
|
41848
|
+
resolve13({
|
|
41773
41849
|
name: "CLI Version",
|
|
41774
41850
|
status: "pass",
|
|
41775
41851
|
message: "Gemini CLI version detected",
|
|
41776
41852
|
details: stdout.trim()
|
|
41777
41853
|
});
|
|
41778
41854
|
} else {
|
|
41779
|
-
|
|
41855
|
+
resolve13({
|
|
41780
41856
|
name: "CLI Version",
|
|
41781
41857
|
status: "warn",
|
|
41782
41858
|
message: "Could not detect version",
|
|
@@ -41786,7 +41862,7 @@ var doctorCommand = {
|
|
|
41786
41862
|
});
|
|
41787
41863
|
setTimeout(() => {
|
|
41788
41864
|
child.kill();
|
|
41789
|
-
|
|
41865
|
+
resolve13({
|
|
41790
41866
|
name: "CLI Version",
|
|
41791
41867
|
status: "fail",
|
|
41792
41868
|
message: "Version check timed out"
|
|
@@ -43283,22 +43359,30 @@ var DagGenerator = class {
|
|
|
43283
43359
|
}
|
|
43284
43360
|
/**
|
|
43285
43361
|
* Calculate maximum depth of DAG (longest path)
|
|
43362
|
+
* BUG FIX: Added cycle detection with visiting set to prevent infinite recursion
|
|
43286
43363
|
*/
|
|
43287
43364
|
calculateMaxDepth(dag) {
|
|
43288
43365
|
const depths = /* @__PURE__ */ new Map();
|
|
43366
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
43289
43367
|
const calculateDepth = (nodeId) => {
|
|
43290
43368
|
if (depths.has(nodeId)) {
|
|
43291
43369
|
return depths.get(nodeId);
|
|
43292
43370
|
}
|
|
43371
|
+
if (visiting.has(nodeId)) {
|
|
43372
|
+
return 0;
|
|
43373
|
+
}
|
|
43374
|
+
visiting.add(nodeId);
|
|
43293
43375
|
const node = dag.nodes.find((n) => n.id === nodeId);
|
|
43294
43376
|
if (!node || !node.dependencies || node.dependencies.length === 0) {
|
|
43295
43377
|
depths.set(nodeId, 1);
|
|
43378
|
+
visiting.delete(nodeId);
|
|
43296
43379
|
return 1;
|
|
43297
43380
|
}
|
|
43298
43381
|
const depthValues = node.dependencies.map((dep) => calculateDepth(dep));
|
|
43299
43382
|
const maxDepDep = depthValues.length > 0 ? Math.max(...depthValues) : 0;
|
|
43300
43383
|
const depth = maxDepDep + 1;
|
|
43301
43384
|
depths.set(nodeId, depth);
|
|
43385
|
+
visiting.delete(nodeId);
|
|
43302
43386
|
return depth;
|
|
43303
43387
|
};
|
|
43304
43388
|
let maxDepth = 0;
|
|
@@ -44297,11 +44381,23 @@ var genCommand = {
|
|
|
44297
44381
|
process.exit(1);
|
|
44298
44382
|
}
|
|
44299
44383
|
specFile = resolve(process.cwd(), specFile);
|
|
44300
|
-
const
|
|
44301
|
-
const
|
|
44384
|
+
const dangerousUnixPaths = ["/etc", "/sys", "/proc", "/dev", "/root", "/boot"];
|
|
44385
|
+
const isDangerousUnixPath = dangerousUnixPaths.some(
|
|
44302
44386
|
(dangerous) => specFile.startsWith(dangerous + "/") || specFile === dangerous
|
|
44303
44387
|
);
|
|
44304
|
-
|
|
44388
|
+
const specFileLower = specFile.toLowerCase();
|
|
44389
|
+
const dangerousWindowsPaths = [
|
|
44390
|
+
"c:\\windows",
|
|
44391
|
+
"c:\\program files",
|
|
44392
|
+
"c:\\program files (x86)",
|
|
44393
|
+
"c:\\programdata",
|
|
44394
|
+
"c:\\users\\public",
|
|
44395
|
+
"c:\\system32"
|
|
44396
|
+
];
|
|
44397
|
+
const isDangerousWindowsPath = dangerousWindowsPaths.some(
|
|
44398
|
+
(dangerous) => specFileLower.startsWith(dangerous + "\\") || specFileLower === dangerous
|
|
44399
|
+
);
|
|
44400
|
+
if (isDangerousUnixPath || isDangerousWindowsPath) {
|
|
44305
44401
|
console.error(chalk5.red(`\u2717 Error: Access to system directory '${specFile}' is not allowed`));
|
|
44306
44402
|
console.error(chalk5.gray("Spec files should be in your project directory"));
|
|
44307
44403
|
process.exit(1);
|
|
@@ -46458,7 +46554,7 @@ async function findProcesses(processName, verbose) {
|
|
|
46458
46554
|
}
|
|
46459
46555
|
async function killProcess(pid, verbose) {
|
|
46460
46556
|
try {
|
|
46461
|
-
await new Promise((
|
|
46557
|
+
await new Promise((resolve13, reject) => {
|
|
46462
46558
|
const proc = spawn("kill", ["-TERM", String(pid)], {
|
|
46463
46559
|
stdio: "pipe",
|
|
46464
46560
|
shell: false
|
|
@@ -46466,23 +46562,23 @@ async function killProcess(pid, verbose) {
|
|
|
46466
46562
|
});
|
|
46467
46563
|
proc.on("close", (code) => {
|
|
46468
46564
|
if (code === 0) {
|
|
46469
|
-
|
|
46565
|
+
resolve13();
|
|
46470
46566
|
} else {
|
|
46471
46567
|
reject(new Error(`kill -TERM failed with code ${code}`));
|
|
46472
46568
|
}
|
|
46473
46569
|
});
|
|
46474
46570
|
proc.on("error", reject);
|
|
46475
46571
|
});
|
|
46476
|
-
await new Promise((
|
|
46572
|
+
await new Promise((resolve13) => setTimeout(resolve13, 1e3));
|
|
46477
46573
|
try {
|
|
46478
|
-
await new Promise((
|
|
46574
|
+
await new Promise((resolve13, reject) => {
|
|
46479
46575
|
const proc = spawn("ps", ["-p", String(pid)], {
|
|
46480
46576
|
stdio: "pipe",
|
|
46481
46577
|
shell: false
|
|
46482
46578
|
});
|
|
46483
46579
|
proc.on("close", (code) => {
|
|
46484
46580
|
if (code === 0) {
|
|
46485
|
-
|
|
46581
|
+
resolve13();
|
|
46486
46582
|
} else {
|
|
46487
46583
|
reject(new Error("Process not running"));
|
|
46488
46584
|
}
|
|
@@ -46492,14 +46588,14 @@ async function killProcess(pid, verbose) {
|
|
|
46492
46588
|
if (verbose) {
|
|
46493
46589
|
logger.debug(`Process ${pid} didn't respond to SIGTERM, using SIGKILL`);
|
|
46494
46590
|
}
|
|
46495
|
-
await new Promise((
|
|
46591
|
+
await new Promise((resolve13, reject) => {
|
|
46496
46592
|
const proc = spawn("kill", ["-KILL", String(pid)], {
|
|
46497
46593
|
stdio: "pipe",
|
|
46498
46594
|
shell: false
|
|
46499
46595
|
});
|
|
46500
46596
|
proc.on("close", (code) => {
|
|
46501
46597
|
if (code === 0) {
|
|
46502
|
-
|
|
46598
|
+
resolve13();
|
|
46503
46599
|
} else {
|
|
46504
46600
|
reject(new Error(`kill -KILL failed with code ${code}`));
|
|
46505
46601
|
}
|
|
@@ -48077,7 +48173,7 @@ async function handleKill(argv) {
|
|
|
48077
48173
|
`);
|
|
48078
48174
|
console.log(chalk5.yellow("This will immediately disable the feature for ALL users."));
|
|
48079
48175
|
console.log(chalk5.gray("Press Ctrl+C to cancel, or wait 5 seconds to confirm...\n"));
|
|
48080
|
-
await new Promise((
|
|
48176
|
+
await new Promise((resolve13) => setTimeout(resolve13, 5e3));
|
|
48081
48177
|
try {
|
|
48082
48178
|
await flagManager.killSwitch(flagName, reason);
|
|
48083
48179
|
console.log(chalk5.red("\u2713 Kill switch activated"));
|