@defai.digital/automatosx 11.2.5 → 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 +264 -160
- 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, "../..");
|
|
@@ -13898,7 +13908,7 @@ async function initializeGitRepository(projectDir) {
|
|
|
13898
13908
|
return true;
|
|
13899
13909
|
}
|
|
13900
13910
|
const { spawn: spawn9 } = await import('child_process');
|
|
13901
|
-
await new Promise((
|
|
13911
|
+
await new Promise((resolve13, reject) => {
|
|
13902
13912
|
const child = spawn9("git", ["init"], {
|
|
13903
13913
|
cwd: projectDir,
|
|
13904
13914
|
stdio: "pipe",
|
|
@@ -13914,7 +13924,7 @@ async function initializeGitRepository(projectDir) {
|
|
|
13914
13924
|
reject(new Error(`git init failed with code ${code}: ${stderr}`));
|
|
13915
13925
|
} else {
|
|
13916
13926
|
logger.info("Git repository set up successfully");
|
|
13917
|
-
|
|
13927
|
+
resolve13();
|
|
13918
13928
|
}
|
|
13919
13929
|
});
|
|
13920
13930
|
child.on("error", (error) => {
|
|
@@ -16060,7 +16070,7 @@ var configureCommand = {
|
|
|
16060
16070
|
}
|
|
16061
16071
|
console.log(chalk5.bold.cyan("\n\u2728 AutomatosX Setup Wizard\n"));
|
|
16062
16072
|
console.log(chalk5.dim("This wizard will help you configure the OpenAI integration mode.\n"));
|
|
16063
|
-
const configPath = resolve(process.cwd(), "
|
|
16073
|
+
const configPath = resolve(process.cwd(), "ax.config.json");
|
|
16064
16074
|
const config = await loadConfig(configPath);
|
|
16065
16075
|
if (!config.providers.openai) {
|
|
16066
16076
|
console.log(chalk5.red("\n\u274C OpenAI provider not found in configuration\n"));
|
|
@@ -18229,23 +18239,29 @@ var Router = class {
|
|
|
18229
18239
|
const isCircuitOpen = this.circuitBreaker.isOpen(provider.name);
|
|
18230
18240
|
healthMultipliers.set(provider.name, isCircuitOpen ? 0.5 : 1);
|
|
18231
18241
|
}
|
|
18232
|
-
|
|
18233
|
-
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
|
|
18248
|
-
|
|
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
|
|
18249
18265
|
});
|
|
18250
18266
|
}
|
|
18251
18267
|
}
|
|
@@ -20124,8 +20140,11 @@ var MemoryManager = class _MemoryManager {
|
|
|
20124
20140
|
}
|
|
20125
20141
|
const tempPath = `${this.config.dbPath}.restore.tmp`;
|
|
20126
20142
|
const srcDb = new Database2(srcPath, { readonly: true });
|
|
20127
|
-
|
|
20128
|
-
|
|
20143
|
+
try {
|
|
20144
|
+
await srcDb.backup(tempPath);
|
|
20145
|
+
} finally {
|
|
20146
|
+
srcDb.close();
|
|
20147
|
+
}
|
|
20129
20148
|
try {
|
|
20130
20149
|
const tempDb = new Database2(tempPath, { readonly: true });
|
|
20131
20150
|
tempDb.prepare("SELECT COUNT(*) FROM memory_entries").get();
|
|
@@ -22717,7 +22736,7 @@ var __filename4 = fileURLToPath(import.meta.url);
|
|
|
22717
22736
|
var __dirname5 = dirname(__filename4);
|
|
22718
22737
|
function getPackageRoot3() {
|
|
22719
22738
|
const currentDir = __dirname5;
|
|
22720
|
-
if (currentDir.includes("/dist")) {
|
|
22739
|
+
if (currentDir.includes(`${sep}dist`) || currentDir.includes("/dist")) {
|
|
22721
22740
|
return join(currentDir, "..");
|
|
22722
22741
|
} else {
|
|
22723
22742
|
return join(currentDir, "../..");
|
|
@@ -22848,6 +22867,7 @@ init_path_resolver();
|
|
|
22848
22867
|
// src/core/conversation-context-store.ts
|
|
22849
22868
|
init_esm_shims();
|
|
22850
22869
|
init_logger();
|
|
22870
|
+
var VALID_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
22851
22871
|
var ConversationContextStore = class {
|
|
22852
22872
|
storePath;
|
|
22853
22873
|
maxEntries;
|
|
@@ -22857,6 +22877,33 @@ var ConversationContextStore = class {
|
|
|
22857
22877
|
this.maxEntries = options.maxEntries ?? 100;
|
|
22858
22878
|
this.ttlMs = options.ttlMs ?? 24 * 60 * 60 * 1e3;
|
|
22859
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
|
+
}
|
|
22860
22907
|
/**
|
|
22861
22908
|
* Initialize store (create directory if needed)
|
|
22862
22909
|
*/
|
|
@@ -22874,7 +22921,7 @@ var ConversationContextStore = class {
|
|
|
22874
22921
|
*/
|
|
22875
22922
|
async save(context) {
|
|
22876
22923
|
await this.initialize();
|
|
22877
|
-
const filePath =
|
|
22924
|
+
const filePath = this.validateAndResolvePath(context.id);
|
|
22878
22925
|
const data = JSON.stringify(context, null, 2);
|
|
22879
22926
|
try {
|
|
22880
22927
|
await writeFile(filePath, data, "utf-8");
|
|
@@ -22893,7 +22940,7 @@ var ConversationContextStore = class {
|
|
|
22893
22940
|
* Get conversation context by ID
|
|
22894
22941
|
*/
|
|
22895
22942
|
async get(id) {
|
|
22896
|
-
const filePath =
|
|
22943
|
+
const filePath = this.validateAndResolvePath(id);
|
|
22897
22944
|
try {
|
|
22898
22945
|
const data = await readFile(filePath, "utf-8");
|
|
22899
22946
|
const context = JSON.parse(data);
|
|
@@ -22947,7 +22994,7 @@ var ConversationContextStore = class {
|
|
|
22947
22994
|
* Delete context entry
|
|
22948
22995
|
*/
|
|
22949
22996
|
async delete(id) {
|
|
22950
|
-
const filePath =
|
|
22997
|
+
const filePath = this.validateAndResolvePath(id);
|
|
22951
22998
|
try {
|
|
22952
22999
|
await unlink(filePath);
|
|
22953
23000
|
logger.info("[ContextStore] Context deleted", { id });
|
|
@@ -25331,7 +25378,7 @@ ${context.task}`;
|
|
|
25331
25378
|
* @param signal - Optional AbortSignal to cancel the sleep
|
|
25332
25379
|
*/
|
|
25333
25380
|
sleep(ms, signal) {
|
|
25334
|
-
return new Promise((
|
|
25381
|
+
return new Promise((resolve13, reject) => {
|
|
25335
25382
|
if (signal?.aborted) {
|
|
25336
25383
|
reject(new Error("Sleep cancelled"));
|
|
25337
25384
|
return;
|
|
@@ -25341,7 +25388,7 @@ ${context.task}`;
|
|
|
25341
25388
|
if (abortHandler && signal) {
|
|
25342
25389
|
signal.removeEventListener("abort", abortHandler);
|
|
25343
25390
|
}
|
|
25344
|
-
|
|
25391
|
+
resolve13();
|
|
25345
25392
|
}, ms);
|
|
25346
25393
|
if (signal) {
|
|
25347
25394
|
abortHandler = () => {
|
|
@@ -26759,10 +26806,10 @@ var McpClient = class extends EventEmitter {
|
|
|
26759
26806
|
return;
|
|
26760
26807
|
}
|
|
26761
26808
|
if (this.state.status === "connecting") {
|
|
26762
|
-
return new Promise((
|
|
26809
|
+
return new Promise((resolve13, reject) => {
|
|
26763
26810
|
const onConnected = () => {
|
|
26764
26811
|
this.off("error", onError);
|
|
26765
|
-
|
|
26812
|
+
resolve13();
|
|
26766
26813
|
};
|
|
26767
26814
|
const onError = (err) => {
|
|
26768
26815
|
this.off("connected", onConnected);
|
|
@@ -26929,14 +26976,14 @@ var McpClient = class extends EventEmitter {
|
|
|
26929
26976
|
method,
|
|
26930
26977
|
params
|
|
26931
26978
|
};
|
|
26932
|
-
return new Promise((
|
|
26979
|
+
return new Promise((resolve13, reject) => {
|
|
26933
26980
|
const timeoutMs = timeout ?? this.config.timeout;
|
|
26934
26981
|
const timeoutHandle = setTimeout(() => {
|
|
26935
26982
|
this.pendingRequests.delete(id);
|
|
26936
26983
|
reject(new Error(`Request timed out after ${timeoutMs}ms: ${method}`));
|
|
26937
26984
|
}, timeoutMs);
|
|
26938
26985
|
this.pendingRequests.set(id, {
|
|
26939
|
-
resolve:
|
|
26986
|
+
resolve: resolve13,
|
|
26940
26987
|
reject,
|
|
26941
26988
|
timeout: timeoutHandle
|
|
26942
26989
|
});
|
|
@@ -27394,15 +27441,15 @@ var McpClientPool = class extends EventEmitter {
|
|
|
27394
27441
|
}
|
|
27395
27442
|
}
|
|
27396
27443
|
async waitForConnection(provider, pool) {
|
|
27397
|
-
return new Promise((
|
|
27444
|
+
return new Promise((resolve13, reject) => {
|
|
27398
27445
|
const timeout = setTimeout(() => {
|
|
27399
|
-
const index = pool.waitQueue.findIndex((w) => w.resolve ===
|
|
27446
|
+
const index = pool.waitQueue.findIndex((w) => w.resolve === resolve13);
|
|
27400
27447
|
if (index !== -1) {
|
|
27401
27448
|
pool.waitQueue.splice(index, 1);
|
|
27402
27449
|
}
|
|
27403
27450
|
reject(new ConnectionTimeoutError(provider, this.config.acquireTimeoutMs));
|
|
27404
27451
|
}, this.config.acquireTimeoutMs);
|
|
27405
|
-
pool.waitQueue.push({ resolve:
|
|
27452
|
+
pool.waitQueue.push({ resolve: resolve13, reject, timeout });
|
|
27406
27453
|
logger.debug("[MCP Pool] Waiting for connection", {
|
|
27407
27454
|
provider,
|
|
27408
27455
|
queuePosition: pool.waitQueue.length
|
|
@@ -28879,6 +28926,8 @@ var McpServer = class _McpServer {
|
|
|
28879
28926
|
initializationPromise = null;
|
|
28880
28927
|
initializationMutex = new Mutex();
|
|
28881
28928
|
// BUG FIX (v9.0.1): Prevent concurrent initialization
|
|
28929
|
+
stdinMutex = new Mutex();
|
|
28930
|
+
// BUG FIX: Prevent race conditions in stdin message processing
|
|
28882
28931
|
version;
|
|
28883
28932
|
ajv;
|
|
28884
28933
|
compiledValidators = /* @__PURE__ */ new Map();
|
|
@@ -29254,7 +29303,15 @@ var McpServer = class _McpServer {
|
|
|
29254
29303
|
* v10.5.0: Capture clientInfo for Smart Routing
|
|
29255
29304
|
*/
|
|
29256
29305
|
async handleInitialize(request, id) {
|
|
29257
|
-
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
|
+
}
|
|
29258
29315
|
logger.info("[MCP Server] Initialize request received (fast handshake mode)", { clientInfo });
|
|
29259
29316
|
this.session = {
|
|
29260
29317
|
clientInfo: {
|
|
@@ -29380,67 +29437,77 @@ ${json}`;
|
|
|
29380
29437
|
logger.info("[MCP Server] Starting stdio JSON-RPC server...");
|
|
29381
29438
|
let buffer = "";
|
|
29382
29439
|
let contentLength = null;
|
|
29383
|
-
process.stdin.on("data",
|
|
29384
|
-
|
|
29385
|
-
|
|
29386
|
-
|
|
29387
|
-
|
|
29388
|
-
|
|
29389
|
-
|
|
29390
|
-
|
|
29391
|
-
|
|
29392
|
-
|
|
29393
|
-
|
|
29394
|
-
|
|
29395
|
-
|
|
29396
|
-
iterations
|
|
29397
|
-
|
|
29398
|
-
|
|
29399
|
-
|
|
29400
|
-
|
|
29401
|
-
|
|
29402
|
-
|
|
29403
|
-
const
|
|
29404
|
-
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
|
|
29409
|
-
|
|
29410
|
-
|
|
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
|
+
}
|
|
29411
29478
|
}
|
|
29412
29479
|
}
|
|
29413
|
-
|
|
29414
|
-
|
|
29415
|
-
|
|
29480
|
+
if (contentLength === null) {
|
|
29481
|
+
logger.error("[MCP Server] No Content-Length header found");
|
|
29482
|
+
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
29483
|
+
continue;
|
|
29484
|
+
}
|
|
29416
29485
|
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
29417
|
-
continue;
|
|
29418
29486
|
}
|
|
29419
|
-
|
|
29420
|
-
|
|
29421
|
-
|
|
29422
|
-
|
|
29423
|
-
|
|
29424
|
-
|
|
29425
|
-
|
|
29426
|
-
|
|
29427
|
-
|
|
29428
|
-
|
|
29429
|
-
|
|
29430
|
-
|
|
29431
|
-
|
|
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" } });
|
|
29432
29502
|
}
|
|
29433
|
-
} catch (error) {
|
|
29434
|
-
logger.error("[MCP Server] Failed to parse or handle request", { jsonMessage, error });
|
|
29435
|
-
this.writeResponse({ jsonrpc: "2.0", id: null, error: { code: -32700 /* ParseError */, message: "Parse error: Invalid JSON" } });
|
|
29436
29503
|
}
|
|
29437
|
-
|
|
29438
|
-
|
|
29439
|
-
|
|
29440
|
-
|
|
29441
|
-
|
|
29442
|
-
}
|
|
29443
|
-
}
|
|
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
|
+
});
|
|
29444
29511
|
});
|
|
29445
29512
|
const shutdown = (reason) => {
|
|
29446
29513
|
logger.info(`[MCP Server] ${reason}`);
|
|
@@ -30331,7 +30398,7 @@ var UnifiedMCPManager = class {
|
|
|
30331
30398
|
};
|
|
30332
30399
|
this.setupProcessHandlers(config.name, childProcess, serverProcess);
|
|
30333
30400
|
this.servers.set(config.name, serverProcess);
|
|
30334
|
-
await new Promise((
|
|
30401
|
+
await new Promise((resolve13) => setTimeout(resolve13, 100));
|
|
30335
30402
|
if (childProcess.killed || childProcess.exitCode !== null) {
|
|
30336
30403
|
throw new Error(
|
|
30337
30404
|
`Server process exited immediately with code ${childProcess.exitCode}`
|
|
@@ -30354,6 +30421,14 @@ var UnifiedMCPManager = class {
|
|
|
30354
30421
|
name: config.name,
|
|
30355
30422
|
error: error.message
|
|
30356
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);
|
|
30357
30432
|
throw error;
|
|
30358
30433
|
}
|
|
30359
30434
|
}
|
|
@@ -30434,7 +30509,7 @@ var UnifiedMCPManager = class {
|
|
|
30434
30509
|
async restartServer(serverName) {
|
|
30435
30510
|
logger.info("UnifiedMCPManager: Restarting server", { name: serverName });
|
|
30436
30511
|
await this.stopServer(serverName);
|
|
30437
|
-
await new Promise((
|
|
30512
|
+
await new Promise((resolve13) => setTimeout(resolve13, 1e3));
|
|
30438
30513
|
const serverConfig = this.config.servers.find((s) => s.name === serverName);
|
|
30439
30514
|
if (!serverConfig) {
|
|
30440
30515
|
throw new Error(`Server configuration not found: ${serverName}`);
|
|
@@ -30681,31 +30756,34 @@ var UnifiedMCPManager = class {
|
|
|
30681
30756
|
this.pendingRestarts.set(serverName, restartTimer);
|
|
30682
30757
|
}
|
|
30683
30758
|
});
|
|
30684
|
-
|
|
30685
|
-
|
|
30686
|
-
|
|
30759
|
+
const shouldLog = this.config.logging?.logServerOutput;
|
|
30760
|
+
if (process2.stdout) {
|
|
30761
|
+
process2.stdout.on("data", (data) => {
|
|
30762
|
+
if (shouldLog) {
|
|
30687
30763
|
logger.debug(`MCP[${serverName}] stdout:`, {
|
|
30688
30764
|
data: data.toString().trim()
|
|
30689
30765
|
});
|
|
30690
|
-
}
|
|
30691
|
-
}
|
|
30692
|
-
|
|
30693
|
-
|
|
30766
|
+
}
|
|
30767
|
+
});
|
|
30768
|
+
}
|
|
30769
|
+
if (process2.stderr) {
|
|
30770
|
+
process2.stderr.on("data", (data) => {
|
|
30771
|
+
if (shouldLog) {
|
|
30694
30772
|
logger.debug(`MCP[${serverName}] stderr:`, {
|
|
30695
30773
|
data: data.toString().trim()
|
|
30696
30774
|
});
|
|
30697
|
-
}
|
|
30698
|
-
}
|
|
30775
|
+
}
|
|
30776
|
+
});
|
|
30699
30777
|
}
|
|
30700
30778
|
}
|
|
30701
30779
|
/**
|
|
30702
30780
|
* Wait for process to exit
|
|
30703
30781
|
*/
|
|
30704
30782
|
async waitForExit(process2, timeoutMs) {
|
|
30705
|
-
return new Promise((
|
|
30783
|
+
return new Promise((resolve13, reject) => {
|
|
30706
30784
|
const exitListener = () => {
|
|
30707
30785
|
clearTimeout(timeout);
|
|
30708
|
-
|
|
30786
|
+
resolve13();
|
|
30709
30787
|
};
|
|
30710
30788
|
const timeout = setTimeout(() => {
|
|
30711
30789
|
process2.removeListener("exit", exitListener);
|
|
@@ -31760,8 +31838,8 @@ var deleteCommand = {
|
|
|
31760
31838
|
input: process.stdin,
|
|
31761
31839
|
output: process.stdout
|
|
31762
31840
|
});
|
|
31763
|
-
const answer = await new Promise((
|
|
31764
|
-
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);
|
|
31765
31843
|
});
|
|
31766
31844
|
rl.close();
|
|
31767
31845
|
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
@@ -32721,7 +32799,7 @@ ${this.config.locale === "zh" ? "\u8ACB\u9078\u64C7" : "Select"}${defaultDisplay
|
|
|
32721
32799
|
async promptWithTimeout(prompt, parser, defaultValue) {
|
|
32722
32800
|
const rl = this.getReadline();
|
|
32723
32801
|
const template = this.getTemplate();
|
|
32724
|
-
return new Promise((
|
|
32802
|
+
return new Promise((resolve13) => {
|
|
32725
32803
|
let resolved = false;
|
|
32726
32804
|
let timeoutHandle;
|
|
32727
32805
|
let warningHandle;
|
|
@@ -32735,7 +32813,7 @@ ${this.config.locale === "zh" ? "\u8ACB\u9078\u64C7" : "Select"}${defaultDisplay
|
|
|
32735
32813
|
${template.timedOut}`);
|
|
32736
32814
|
rl.close();
|
|
32737
32815
|
this.rl = null;
|
|
32738
|
-
|
|
32816
|
+
resolve13({
|
|
32739
32817
|
value: defaultValue,
|
|
32740
32818
|
timedOut: true
|
|
32741
32819
|
});
|
|
@@ -32759,7 +32837,7 @@ ${template.timeoutWarning(30)}`);
|
|
|
32759
32837
|
clearTimeout(warningHandle);
|
|
32760
32838
|
}
|
|
32761
32839
|
const value = parser(answer);
|
|
32762
|
-
|
|
32840
|
+
resolve13({
|
|
32763
32841
|
value,
|
|
32764
32842
|
timedOut: false
|
|
32765
32843
|
});
|
|
@@ -33841,9 +33919,9 @@ ${action.modifications}`;
|
|
|
33841
33919
|
)
|
|
33842
33920
|
);
|
|
33843
33921
|
console.log(chalk5.gray(` Waiting ${delay}ms before retry...`));
|
|
33844
|
-
await new Promise((
|
|
33922
|
+
await new Promise((resolve13) => setTimeout(resolve13, delay));
|
|
33845
33923
|
} else {
|
|
33846
|
-
await new Promise((
|
|
33924
|
+
await new Promise((resolve13) => setTimeout(resolve13, delay));
|
|
33847
33925
|
}
|
|
33848
33926
|
}
|
|
33849
33927
|
const executionOptions = {
|
|
@@ -36980,7 +37058,7 @@ Result: ${result.stages.map((s) => s.output).join("\n\n")}`;
|
|
|
36980
37058
|
if (argv.save) {
|
|
36981
37059
|
try {
|
|
36982
37060
|
const savePath = argv.save;
|
|
36983
|
-
const saveDir =
|
|
37061
|
+
const saveDir = dirname(savePath);
|
|
36984
37062
|
await mkdir(saveDir, { recursive: true });
|
|
36985
37063
|
const outputData = formatForSave(result, argv.format || "text", {
|
|
36986
37064
|
agent: resolvedAgentName,
|
|
@@ -37028,7 +37106,7 @@ Response: ${result.response.content}`;
|
|
|
37028
37106
|
if (router) {
|
|
37029
37107
|
router.destroy();
|
|
37030
37108
|
}
|
|
37031
|
-
await new Promise((
|
|
37109
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
37032
37110
|
if (!verbosity.isQuiet()) {
|
|
37033
37111
|
const executionTime = ((Date.now() - executionStartTime) / 1e3).toFixed(1);
|
|
37034
37112
|
if (verbosity.isNormal()) {
|
|
@@ -37095,7 +37173,7 @@ Response: ${result.response.content}`;
|
|
|
37095
37173
|
logger.debug("Context cleanup error", { error: errMsg });
|
|
37096
37174
|
});
|
|
37097
37175
|
}
|
|
37098
|
-
await new Promise((
|
|
37176
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
37099
37177
|
try {
|
|
37100
37178
|
const { processManager: processManager2 } = await Promise.resolve().then(() => (init_process_manager(), process_manager_exports));
|
|
37101
37179
|
await processManager2.shutdown(3e3);
|
|
@@ -37994,10 +38072,10 @@ async function getCurrentVersion() {
|
|
|
37994
38072
|
return result.dependencies["@defai.digital/automatosx"]?.version || "unknown";
|
|
37995
38073
|
} catch (error) {
|
|
37996
38074
|
const { readFile: readFile24 } = await import('fs/promises');
|
|
37997
|
-
const { dirname:
|
|
38075
|
+
const { dirname: dirname17, join: join48 } = await import('path');
|
|
37998
38076
|
const { fileURLToPath: fileURLToPath8 } = await import('url');
|
|
37999
38077
|
const __filename7 = fileURLToPath8(import.meta.url);
|
|
38000
|
-
const __dirname8 =
|
|
38078
|
+
const __dirname8 = dirname17(__filename7);
|
|
38001
38079
|
const pkgPath = join48(__dirname8, "../../../package.json");
|
|
38002
38080
|
const content = await readFile24(pkgPath, "utf-8");
|
|
38003
38081
|
const pkg = JSON.parse(content);
|
|
@@ -38152,16 +38230,22 @@ var cleanupCommand = {
|
|
|
38152
38230
|
},
|
|
38153
38231
|
handler: async (argv) => {
|
|
38154
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
|
+
}
|
|
38155
38239
|
const { detectProjectRoot: detectProjectRoot2 } = await Promise.resolve().then(() => (init_path_resolver(), path_resolver_exports));
|
|
38156
38240
|
const projectDir = await detectProjectRoot2(process.cwd());
|
|
38157
38241
|
const workspaceManager = new WorkspaceManager(projectDir);
|
|
38158
38242
|
if (!argv.confirm) {
|
|
38159
38243
|
console.log(chalk5.yellow(`
|
|
38160
|
-
\u26A0 This will remove temporary files older than ${
|
|
38244
|
+
\u26A0 This will remove temporary files older than ${olderThan} days`));
|
|
38161
38245
|
console.log(chalk5.gray("Run with --confirm to proceed\n"));
|
|
38162
38246
|
process.exit(0);
|
|
38163
38247
|
}
|
|
38164
|
-
const removed = await workspaceManager.cleanupTmp(
|
|
38248
|
+
const removed = await workspaceManager.cleanupTmp(olderThan);
|
|
38165
38249
|
console.log(chalk5.green.bold(`
|
|
38166
38250
|
\u2713 Cleanup complete
|
|
38167
38251
|
`));
|
|
@@ -39436,7 +39520,7 @@ var resumeCommand = {
|
|
|
39436
39520
|
if (router) {
|
|
39437
39521
|
router.destroy();
|
|
39438
39522
|
}
|
|
39439
|
-
await new Promise((
|
|
39523
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
39440
39524
|
console.log(chalk5.green.bold("\u2705 Complete\n"));
|
|
39441
39525
|
process.exit(0);
|
|
39442
39526
|
} catch (error) {
|
|
@@ -39456,7 +39540,7 @@ var resumeCommand = {
|
|
|
39456
39540
|
if (router) {
|
|
39457
39541
|
router.destroy();
|
|
39458
39542
|
}
|
|
39459
|
-
await new Promise((
|
|
39543
|
+
await new Promise((resolve13) => setImmediate(resolve13));
|
|
39460
39544
|
} catch (cleanupError) {
|
|
39461
39545
|
const errMsg = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
39462
39546
|
logger.debug("Cleanup error ignored", { error: errMsg });
|
|
@@ -41747,7 +41831,7 @@ var doctorCommand = {
|
|
|
41747
41831
|
}
|
|
41748
41832
|
}
|
|
41749
41833
|
async function checkCLIVersion() {
|
|
41750
|
-
return new Promise((
|
|
41834
|
+
return new Promise((resolve13) => {
|
|
41751
41835
|
const child = spawn("gemini", ["--version"], {
|
|
41752
41836
|
stdio: ["ignore", "pipe", "pipe"]
|
|
41753
41837
|
});
|
|
@@ -41761,14 +41845,14 @@ var doctorCommand = {
|
|
|
41761
41845
|
});
|
|
41762
41846
|
child.on("close", (code) => {
|
|
41763
41847
|
if (code === 0 && stdout.trim()) {
|
|
41764
|
-
|
|
41848
|
+
resolve13({
|
|
41765
41849
|
name: "CLI Version",
|
|
41766
41850
|
status: "pass",
|
|
41767
41851
|
message: "Gemini CLI version detected",
|
|
41768
41852
|
details: stdout.trim()
|
|
41769
41853
|
});
|
|
41770
41854
|
} else {
|
|
41771
|
-
|
|
41855
|
+
resolve13({
|
|
41772
41856
|
name: "CLI Version",
|
|
41773
41857
|
status: "warn",
|
|
41774
41858
|
message: "Could not detect version",
|
|
@@ -41778,7 +41862,7 @@ var doctorCommand = {
|
|
|
41778
41862
|
});
|
|
41779
41863
|
setTimeout(() => {
|
|
41780
41864
|
child.kill();
|
|
41781
|
-
|
|
41865
|
+
resolve13({
|
|
41782
41866
|
name: "CLI Version",
|
|
41783
41867
|
status: "fail",
|
|
41784
41868
|
message: "Version check timed out"
|
|
@@ -43275,22 +43359,30 @@ var DagGenerator = class {
|
|
|
43275
43359
|
}
|
|
43276
43360
|
/**
|
|
43277
43361
|
* Calculate maximum depth of DAG (longest path)
|
|
43362
|
+
* BUG FIX: Added cycle detection with visiting set to prevent infinite recursion
|
|
43278
43363
|
*/
|
|
43279
43364
|
calculateMaxDepth(dag) {
|
|
43280
43365
|
const depths = /* @__PURE__ */ new Map();
|
|
43366
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
43281
43367
|
const calculateDepth = (nodeId) => {
|
|
43282
43368
|
if (depths.has(nodeId)) {
|
|
43283
43369
|
return depths.get(nodeId);
|
|
43284
43370
|
}
|
|
43371
|
+
if (visiting.has(nodeId)) {
|
|
43372
|
+
return 0;
|
|
43373
|
+
}
|
|
43374
|
+
visiting.add(nodeId);
|
|
43285
43375
|
const node = dag.nodes.find((n) => n.id === nodeId);
|
|
43286
43376
|
if (!node || !node.dependencies || node.dependencies.length === 0) {
|
|
43287
43377
|
depths.set(nodeId, 1);
|
|
43378
|
+
visiting.delete(nodeId);
|
|
43288
43379
|
return 1;
|
|
43289
43380
|
}
|
|
43290
43381
|
const depthValues = node.dependencies.map((dep) => calculateDepth(dep));
|
|
43291
43382
|
const maxDepDep = depthValues.length > 0 ? Math.max(...depthValues) : 0;
|
|
43292
43383
|
const depth = maxDepDep + 1;
|
|
43293
43384
|
depths.set(nodeId, depth);
|
|
43385
|
+
visiting.delete(nodeId);
|
|
43294
43386
|
return depth;
|
|
43295
43387
|
};
|
|
43296
43388
|
let maxDepth = 0;
|
|
@@ -44289,11 +44381,23 @@ var genCommand = {
|
|
|
44289
44381
|
process.exit(1);
|
|
44290
44382
|
}
|
|
44291
44383
|
specFile = resolve(process.cwd(), specFile);
|
|
44292
|
-
const
|
|
44293
|
-
const
|
|
44384
|
+
const dangerousUnixPaths = ["/etc", "/sys", "/proc", "/dev", "/root", "/boot"];
|
|
44385
|
+
const isDangerousUnixPath = dangerousUnixPaths.some(
|
|
44294
44386
|
(dangerous) => specFile.startsWith(dangerous + "/") || specFile === dangerous
|
|
44295
44387
|
);
|
|
44296
|
-
|
|
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) {
|
|
44297
44401
|
console.error(chalk5.red(`\u2717 Error: Access to system directory '${specFile}' is not allowed`));
|
|
44298
44402
|
console.error(chalk5.gray("Spec files should be in your project directory"));
|
|
44299
44403
|
process.exit(1);
|
|
@@ -46450,7 +46554,7 @@ async function findProcesses(processName, verbose) {
|
|
|
46450
46554
|
}
|
|
46451
46555
|
async function killProcess(pid, verbose) {
|
|
46452
46556
|
try {
|
|
46453
|
-
await new Promise((
|
|
46557
|
+
await new Promise((resolve13, reject) => {
|
|
46454
46558
|
const proc = spawn("kill", ["-TERM", String(pid)], {
|
|
46455
46559
|
stdio: "pipe",
|
|
46456
46560
|
shell: false
|
|
@@ -46458,23 +46562,23 @@ async function killProcess(pid, verbose) {
|
|
|
46458
46562
|
});
|
|
46459
46563
|
proc.on("close", (code) => {
|
|
46460
46564
|
if (code === 0) {
|
|
46461
|
-
|
|
46565
|
+
resolve13();
|
|
46462
46566
|
} else {
|
|
46463
46567
|
reject(new Error(`kill -TERM failed with code ${code}`));
|
|
46464
46568
|
}
|
|
46465
46569
|
});
|
|
46466
46570
|
proc.on("error", reject);
|
|
46467
46571
|
});
|
|
46468
|
-
await new Promise((
|
|
46572
|
+
await new Promise((resolve13) => setTimeout(resolve13, 1e3));
|
|
46469
46573
|
try {
|
|
46470
|
-
await new Promise((
|
|
46574
|
+
await new Promise((resolve13, reject) => {
|
|
46471
46575
|
const proc = spawn("ps", ["-p", String(pid)], {
|
|
46472
46576
|
stdio: "pipe",
|
|
46473
46577
|
shell: false
|
|
46474
46578
|
});
|
|
46475
46579
|
proc.on("close", (code) => {
|
|
46476
46580
|
if (code === 0) {
|
|
46477
|
-
|
|
46581
|
+
resolve13();
|
|
46478
46582
|
} else {
|
|
46479
46583
|
reject(new Error("Process not running"));
|
|
46480
46584
|
}
|
|
@@ -46484,14 +46588,14 @@ async function killProcess(pid, verbose) {
|
|
|
46484
46588
|
if (verbose) {
|
|
46485
46589
|
logger.debug(`Process ${pid} didn't respond to SIGTERM, using SIGKILL`);
|
|
46486
46590
|
}
|
|
46487
|
-
await new Promise((
|
|
46591
|
+
await new Promise((resolve13, reject) => {
|
|
46488
46592
|
const proc = spawn("kill", ["-KILL", String(pid)], {
|
|
46489
46593
|
stdio: "pipe",
|
|
46490
46594
|
shell: false
|
|
46491
46595
|
});
|
|
46492
46596
|
proc.on("close", (code) => {
|
|
46493
46597
|
if (code === 0) {
|
|
46494
|
-
|
|
46598
|
+
resolve13();
|
|
46495
46599
|
} else {
|
|
46496
46600
|
reject(new Error(`kill -KILL failed with code ${code}`));
|
|
46497
46601
|
}
|
|
@@ -48069,7 +48173,7 @@ async function handleKill(argv) {
|
|
|
48069
48173
|
`);
|
|
48070
48174
|
console.log(chalk5.yellow("This will immediately disable the feature for ALL users."));
|
|
48071
48175
|
console.log(chalk5.gray("Press Ctrl+C to cancel, or wait 5 seconds to confirm...\n"));
|
|
48072
|
-
await new Promise((
|
|
48176
|
+
await new Promise((resolve13) => setTimeout(resolve13, 5e3));
|
|
48073
48177
|
try {
|
|
48074
48178
|
await flagManager.killSwitch(flagName, reason);
|
|
48075
48179
|
console.log(chalk5.red("\u2713 Kill switch activated"));
|