@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/mcp/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, extname as extname$1, basename, resolve,
|
|
3
|
+
import path4__default, { dirname, join, extname as extname$1, basename, resolve, relative, sep, isAbsolute, parse, delimiter } from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import { mkdir, appendFile, readFile, readdir, writeFile, rename, unlink, copyFile, access, stat, realpath } from 'fs/promises';
|
|
6
6
|
import { existsSync, readFileSync, promises, mkdirSync, createWriteStream, writeFileSync, unlinkSync, constants } from 'fs';
|
|
@@ -690,7 +690,7 @@ var init_process_manager = __esm({
|
|
|
690
690
|
if (child.killed || child.exitCode !== null) {
|
|
691
691
|
continue;
|
|
692
692
|
}
|
|
693
|
-
killPromises.push(new Promise((
|
|
693
|
+
killPromises.push(new Promise((resolve5) => {
|
|
694
694
|
let mainTimeoutId = null;
|
|
695
695
|
let fallbackTimeoutId = null;
|
|
696
696
|
let resolved = false;
|
|
@@ -705,7 +705,7 @@ var init_process_manager = __esm({
|
|
|
705
705
|
}
|
|
706
706
|
if (!resolved) {
|
|
707
707
|
resolved = true;
|
|
708
|
-
|
|
708
|
+
resolve5();
|
|
709
709
|
}
|
|
710
710
|
};
|
|
711
711
|
child.once("exit", () => {
|
|
@@ -730,8 +730,8 @@ var init_process_manager = __esm({
|
|
|
730
730
|
try {
|
|
731
731
|
await Promise.race([
|
|
732
732
|
Promise.all(killPromises),
|
|
733
|
-
new Promise((
|
|
734
|
-
finalTimeoutId = setTimeout(
|
|
733
|
+
new Promise((resolve5) => {
|
|
734
|
+
finalTimeoutId = setTimeout(resolve5, timeout);
|
|
735
735
|
})
|
|
736
736
|
]);
|
|
737
737
|
} finally {
|
|
@@ -2320,7 +2320,8 @@ var init_base_provider = __esm({
|
|
|
2320
2320
|
try {
|
|
2321
2321
|
const cliCommand = this.getCLICommand();
|
|
2322
2322
|
const cliArgs = await this.getCLIArgs();
|
|
2323
|
-
const
|
|
2323
|
+
const escapedArgs = cliArgs.map((arg) => this.escapeShellArg(arg));
|
|
2324
|
+
const argsString = escapedArgs.length > 0 ? escapedArgs.join(" ") + " " : "";
|
|
2324
2325
|
const escapedPrompt = this.escapeShellArg(prompt);
|
|
2325
2326
|
const fullCommand = `${cliCommand} ${argsString}${escapedPrompt}`;
|
|
2326
2327
|
const commandLength = fullCommand.length;
|
|
@@ -2363,7 +2364,7 @@ var init_base_provider = __esm({
|
|
|
2363
2364
|
* @returns Promise resolving to stdout and stderr
|
|
2364
2365
|
*/
|
|
2365
2366
|
async executeWithSpawn(command, cliCommand) {
|
|
2366
|
-
return new Promise((
|
|
2367
|
+
return new Promise((resolve5, reject) => {
|
|
2367
2368
|
const child = spawn(command, [], {
|
|
2368
2369
|
shell: true,
|
|
2369
2370
|
// Auto-detects: cmd.exe on Windows, /bin/sh on Unix
|
|
@@ -2462,11 +2463,16 @@ var init_base_provider = __esm({
|
|
|
2462
2463
|
if (stderr) {
|
|
2463
2464
|
logger.debug(`${cliCommand} CLI stderr output`, { stderr: stderr.trim() });
|
|
2464
2465
|
}
|
|
2465
|
-
if (code === 0 || code === null) {
|
|
2466
|
+
if ((code === 0 || code === null) && !signal) {
|
|
2466
2467
|
if (progressParser) {
|
|
2467
2468
|
progressParser.succeed(`${cliCommand} completed successfully`);
|
|
2468
2469
|
}
|
|
2469
|
-
|
|
2470
|
+
resolve5({ stdout, stderr });
|
|
2471
|
+
} else if (signal) {
|
|
2472
|
+
if (progressParser) {
|
|
2473
|
+
progressParser.fail(`${cliCommand} killed by signal ${signal}`);
|
|
2474
|
+
}
|
|
2475
|
+
reject(new Error(`${cliCommand} CLI killed by signal ${signal}. stderr: ${stderr || "none"}`));
|
|
2470
2476
|
} else {
|
|
2471
2477
|
if (progressParser) {
|
|
2472
2478
|
progressParser.fail(`${cliCommand} failed with code ${code}`);
|
|
@@ -2516,7 +2522,7 @@ var init_base_provider = __esm({
|
|
|
2516
2522
|
* @returns Promise resolving to stdout and stderr
|
|
2517
2523
|
*/
|
|
2518
2524
|
async executeWithStdin(cliCommand, cliArgs, prompt) {
|
|
2519
|
-
return new Promise((
|
|
2525
|
+
return new Promise((resolve5, reject) => {
|
|
2520
2526
|
const commandArgs = cliArgs ? cliArgs.split(" ").filter(Boolean) : [];
|
|
2521
2527
|
logger.debug(`Executing ${cliCommand} CLI with stdin`, {
|
|
2522
2528
|
command: cliCommand,
|
|
@@ -2629,7 +2635,7 @@ var init_base_provider = __esm({
|
|
|
2629
2635
|
if (progressParser) {
|
|
2630
2636
|
progressParser.succeed(`${cliCommand} completed successfully`);
|
|
2631
2637
|
}
|
|
2632
|
-
|
|
2638
|
+
resolve5({ stdout, stderr });
|
|
2633
2639
|
} else {
|
|
2634
2640
|
if (progressParser) {
|
|
2635
2641
|
progressParser.fail(`${cliCommand} failed with code ${code}`);
|
|
@@ -2752,6 +2758,10 @@ ${fullPrompt}
|
|
|
2752
2758
|
errors: responseValidation.error.issues,
|
|
2753
2759
|
response
|
|
2754
2760
|
});
|
|
2761
|
+
throw new ProviderError(
|
|
2762
|
+
`Provider returned invalid response structure: ${responseValidation.error.issues.map((i) => i.message).join(", ")}`,
|
|
2763
|
+
"E1305" /* PROVIDER_EXEC_ERROR */
|
|
2764
|
+
);
|
|
2755
2765
|
}
|
|
2756
2766
|
return response;
|
|
2757
2767
|
} catch (error) {
|
|
@@ -3381,7 +3391,7 @@ var init_cli_wrapper = __esm({
|
|
|
3381
3391
|
* Spawn codex process
|
|
3382
3392
|
*/
|
|
3383
3393
|
async spawnProcess(args2, prompt, timeout) {
|
|
3384
|
-
return new Promise((
|
|
3394
|
+
return new Promise((resolve5, reject) => {
|
|
3385
3395
|
let stdout = "";
|
|
3386
3396
|
let stderr = "";
|
|
3387
3397
|
let hasTimedOut = false;
|
|
@@ -3438,7 +3448,7 @@ var init_cli_wrapper = __esm({
|
|
|
3438
3448
|
return;
|
|
3439
3449
|
}
|
|
3440
3450
|
if (code === 0) {
|
|
3441
|
-
|
|
3451
|
+
resolve5({ stdout, stderr, exitCode: code });
|
|
3442
3452
|
} else {
|
|
3443
3453
|
reject(
|
|
3444
3454
|
new CodexError(
|
|
@@ -3471,7 +3481,7 @@ var init_cli_wrapper = __esm({
|
|
|
3471
3481
|
* Spawn codex process with streaming support
|
|
3472
3482
|
*/
|
|
3473
3483
|
async spawnProcessWithStreaming(args2, prompt, timeout, renderer) {
|
|
3474
|
-
return new Promise((
|
|
3484
|
+
return new Promise((resolve5, reject) => {
|
|
3475
3485
|
let stdout = "";
|
|
3476
3486
|
let stderr = "";
|
|
3477
3487
|
let hasTimedOut = false;
|
|
@@ -3541,7 +3551,7 @@ var init_cli_wrapper = __esm({
|
|
|
3541
3551
|
if (renderer) {
|
|
3542
3552
|
renderer.succeed("Execution complete");
|
|
3543
3553
|
}
|
|
3544
|
-
|
|
3554
|
+
resolve5({ stdout, stderr, exitCode: code });
|
|
3545
3555
|
} else {
|
|
3546
3556
|
if (renderer) {
|
|
3547
3557
|
renderer.fail(`Process exited with code ${code}`);
|
|
@@ -5219,7 +5229,7 @@ var PRECOMPILED_CONFIG = {
|
|
|
5219
5229
|
"enableFreeTierPrioritization": true,
|
|
5220
5230
|
"enableWorkloadAwareRouting": true
|
|
5221
5231
|
},
|
|
5222
|
-
"version": "11.2.
|
|
5232
|
+
"version": "11.2.6"
|
|
5223
5233
|
};
|
|
5224
5234
|
|
|
5225
5235
|
// src/core/config-schemas.ts
|
|
@@ -8289,23 +8299,29 @@ var Router = class {
|
|
|
8289
8299
|
const isCircuitOpen = this.circuitBreaker.isOpen(provider.name);
|
|
8290
8300
|
healthMultipliers.set(provider.name, isCircuitOpen ? 0.5 : 1);
|
|
8291
8301
|
}
|
|
8292
|
-
|
|
8293
|
-
|
|
8294
|
-
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8299
|
-
|
|
8300
|
-
|
|
8301
|
-
|
|
8302
|
-
|
|
8303
|
-
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8302
|
+
try {
|
|
8303
|
+
const scores = await getProviderMetricsTracker().getAllScores(
|
|
8304
|
+
providerNames,
|
|
8305
|
+
strategyManager.getWeights(),
|
|
8306
|
+
healthMultipliers
|
|
8307
|
+
);
|
|
8308
|
+
if (scores.length > 0) {
|
|
8309
|
+
const scoreMap = new Map(scores.map((s) => [s.provider, s.totalScore]));
|
|
8310
|
+
const originalOrder = providersToTry.map((p) => p.name);
|
|
8311
|
+
providersToTry = [...providersToTry].sort((a, b) => {
|
|
8312
|
+
const scoreA = scoreMap.get(a.name) ?? 0;
|
|
8313
|
+
const scoreB = scoreMap.get(b.name) ?? 0;
|
|
8314
|
+
return scoreB - scoreA;
|
|
8315
|
+
});
|
|
8316
|
+
logger.debug("Provider order after multi-factor routing", {
|
|
8317
|
+
original: originalOrder,
|
|
8318
|
+
reordered: providersToTry.map((p) => p.name),
|
|
8319
|
+
scores: Object.fromEntries(scoreMap)
|
|
8320
|
+
});
|
|
8321
|
+
}
|
|
8322
|
+
} catch (scoringError) {
|
|
8323
|
+
logger.warn("Multi-factor scoring failed, using priority order", {
|
|
8324
|
+
error: scoringError.message
|
|
8309
8325
|
});
|
|
8310
8326
|
}
|
|
8311
8327
|
}
|
|
@@ -10183,8 +10199,11 @@ var MemoryManager = class _MemoryManager {
|
|
|
10183
10199
|
}
|
|
10184
10200
|
const tempPath = `${this.config.dbPath}.restore.tmp`;
|
|
10185
10201
|
const srcDb = new Database2(srcPath, { readonly: true });
|
|
10186
|
-
|
|
10187
|
-
|
|
10202
|
+
try {
|
|
10203
|
+
await srcDb.backup(tempPath);
|
|
10204
|
+
} finally {
|
|
10205
|
+
srcDb.close();
|
|
10206
|
+
}
|
|
10188
10207
|
try {
|
|
10189
10208
|
const tempDb = new Database2(tempPath, { readonly: true });
|
|
10190
10209
|
tempDb.prepare("SELECT COUNT(*) FROM memory_entries").get();
|
|
@@ -12940,7 +12959,7 @@ var __filename2 = fileURLToPath(import.meta.url);
|
|
|
12940
12959
|
var __dirname3 = dirname(__filename2);
|
|
12941
12960
|
function getPackageRoot() {
|
|
12942
12961
|
const currentDir = __dirname3;
|
|
12943
|
-
if (currentDir.includes("/dist")) {
|
|
12962
|
+
if (currentDir.includes(`${sep}dist`) || currentDir.includes("/dist")) {
|
|
12944
12963
|
return join(currentDir, "..");
|
|
12945
12964
|
} else {
|
|
12946
12965
|
return join(currentDir, "../..");
|
|
@@ -13633,7 +13652,7 @@ var __filename3 = fileURLToPath(import.meta.url);
|
|
|
13633
13652
|
var __dirname4 = dirname(__filename3);
|
|
13634
13653
|
function getPackageRoot2() {
|
|
13635
13654
|
const currentDir = __dirname4;
|
|
13636
|
-
if (currentDir.includes("/dist")) {
|
|
13655
|
+
if (currentDir.includes(`${sep}dist`) || currentDir.includes("/dist")) {
|
|
13637
13656
|
return join(currentDir, "..");
|
|
13638
13657
|
} else {
|
|
13639
13658
|
return join(currentDir, "../..");
|
|
@@ -13933,6 +13952,7 @@ var TeamManager = class {
|
|
|
13933
13952
|
// src/core/conversation-context-store.ts
|
|
13934
13953
|
init_esm_shims();
|
|
13935
13954
|
init_logger();
|
|
13955
|
+
var VALID_ID_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
|
|
13936
13956
|
var ConversationContextStore = class {
|
|
13937
13957
|
storePath;
|
|
13938
13958
|
maxEntries;
|
|
@@ -13942,6 +13962,33 @@ var ConversationContextStore = class {
|
|
|
13942
13962
|
this.maxEntries = options.maxEntries ?? 100;
|
|
13943
13963
|
this.ttlMs = options.ttlMs ?? 24 * 60 * 60 * 1e3;
|
|
13944
13964
|
}
|
|
13965
|
+
/**
|
|
13966
|
+
* Validate and sanitize context ID to prevent path traversal attacks
|
|
13967
|
+
*
|
|
13968
|
+
* SECURITY: This is critical to prevent path traversal vulnerabilities.
|
|
13969
|
+
* A malicious ID like "../../.ssh/id_rsa" could read/write/delete files
|
|
13970
|
+
* outside the context store directory.
|
|
13971
|
+
*
|
|
13972
|
+
* @param id - Context ID to validate
|
|
13973
|
+
* @returns Sanitized file path within storePath
|
|
13974
|
+
* @throws Error if ID is invalid or path escapes storePath
|
|
13975
|
+
*/
|
|
13976
|
+
validateAndResolvePath(id) {
|
|
13977
|
+
if (!VALID_ID_PATTERN.test(id)) {
|
|
13978
|
+
throw new Error(
|
|
13979
|
+
`Invalid context ID: "${id}". IDs must be 1-64 characters, alphanumeric with underscores/hyphens only.`
|
|
13980
|
+
);
|
|
13981
|
+
}
|
|
13982
|
+
const filePath = join(this.storePath, `${id}.json`);
|
|
13983
|
+
const resolvedPath = resolve(filePath);
|
|
13984
|
+
const resolvedStorePath = resolve(this.storePath);
|
|
13985
|
+
const relativePath = relative(resolvedStorePath, resolvedPath);
|
|
13986
|
+
if (relativePath.startsWith("..") || relativePath.includes("/..") || relativePath.includes("\\..")) {
|
|
13987
|
+
logger.error("[ContextStore] Path traversal attempt blocked", { id, resolvedPath });
|
|
13988
|
+
throw new Error(`Security violation: context ID "${id}" would escape store directory`);
|
|
13989
|
+
}
|
|
13990
|
+
return resolvedPath;
|
|
13991
|
+
}
|
|
13945
13992
|
/**
|
|
13946
13993
|
* Initialize store (create directory if needed)
|
|
13947
13994
|
*/
|
|
@@ -13959,7 +14006,7 @@ var ConversationContextStore = class {
|
|
|
13959
14006
|
*/
|
|
13960
14007
|
async save(context) {
|
|
13961
14008
|
await this.initialize();
|
|
13962
|
-
const filePath =
|
|
14009
|
+
const filePath = this.validateAndResolvePath(context.id);
|
|
13963
14010
|
const data = JSON.stringify(context, null, 2);
|
|
13964
14011
|
try {
|
|
13965
14012
|
await writeFile(filePath, data, "utf-8");
|
|
@@ -13978,7 +14025,7 @@ var ConversationContextStore = class {
|
|
|
13978
14025
|
* Get conversation context by ID
|
|
13979
14026
|
*/
|
|
13980
14027
|
async get(id) {
|
|
13981
|
-
const filePath =
|
|
14028
|
+
const filePath = this.validateAndResolvePath(id);
|
|
13982
14029
|
try {
|
|
13983
14030
|
const data = await readFile(filePath, "utf-8");
|
|
13984
14031
|
const context = JSON.parse(data);
|
|
@@ -14032,7 +14079,7 @@ var ConversationContextStore = class {
|
|
|
14032
14079
|
* Delete context entry
|
|
14033
14080
|
*/
|
|
14034
14081
|
async delete(id) {
|
|
14035
|
-
const filePath =
|
|
14082
|
+
const filePath = this.validateAndResolvePath(id);
|
|
14036
14083
|
try {
|
|
14037
14084
|
await unlink(filePath);
|
|
14038
14085
|
logger.info("[ContextStore] Context deleted", { id });
|
|
@@ -16466,7 +16513,7 @@ ${context.task}`;
|
|
|
16466
16513
|
* @param signal - Optional AbortSignal to cancel the sleep
|
|
16467
16514
|
*/
|
|
16468
16515
|
sleep(ms, signal) {
|
|
16469
|
-
return new Promise((
|
|
16516
|
+
return new Promise((resolve5, reject) => {
|
|
16470
16517
|
if (signal?.aborted) {
|
|
16471
16518
|
reject(new Error("Sleep cancelled"));
|
|
16472
16519
|
return;
|
|
@@ -16476,7 +16523,7 @@ ${context.task}`;
|
|
|
16476
16523
|
if (abortHandler && signal) {
|
|
16477
16524
|
signal.removeEventListener("abort", abortHandler);
|
|
16478
16525
|
}
|
|
16479
|
-
|
|
16526
|
+
resolve5();
|
|
16480
16527
|
}, ms);
|
|
16481
16528
|
if (signal) {
|
|
16482
16529
|
abortHandler = () => {
|
|
@@ -17894,10 +17941,10 @@ var McpClient = class extends EventEmitter {
|
|
|
17894
17941
|
return;
|
|
17895
17942
|
}
|
|
17896
17943
|
if (this.state.status === "connecting") {
|
|
17897
|
-
return new Promise((
|
|
17944
|
+
return new Promise((resolve5, reject) => {
|
|
17898
17945
|
const onConnected = () => {
|
|
17899
17946
|
this.off("error", onError);
|
|
17900
|
-
|
|
17947
|
+
resolve5();
|
|
17901
17948
|
};
|
|
17902
17949
|
const onError = (err) => {
|
|
17903
17950
|
this.off("connected", onConnected);
|
|
@@ -18064,14 +18111,14 @@ var McpClient = class extends EventEmitter {
|
|
|
18064
18111
|
method,
|
|
18065
18112
|
params
|
|
18066
18113
|
};
|
|
18067
|
-
return new Promise((
|
|
18114
|
+
return new Promise((resolve5, reject) => {
|
|
18068
18115
|
const timeoutMs = timeout ?? this.config.timeout;
|
|
18069
18116
|
const timeoutHandle = setTimeout(() => {
|
|
18070
18117
|
this.pendingRequests.delete(id);
|
|
18071
18118
|
reject(new Error(`Request timed out after ${timeoutMs}ms: ${method}`));
|
|
18072
18119
|
}, timeoutMs);
|
|
18073
18120
|
this.pendingRequests.set(id, {
|
|
18074
|
-
resolve:
|
|
18121
|
+
resolve: resolve5,
|
|
18075
18122
|
reject,
|
|
18076
18123
|
timeout: timeoutHandle
|
|
18077
18124
|
});
|
|
@@ -18529,15 +18576,15 @@ var McpClientPool = class extends EventEmitter {
|
|
|
18529
18576
|
}
|
|
18530
18577
|
}
|
|
18531
18578
|
async waitForConnection(provider, pool) {
|
|
18532
|
-
return new Promise((
|
|
18579
|
+
return new Promise((resolve5, reject) => {
|
|
18533
18580
|
const timeout = setTimeout(() => {
|
|
18534
|
-
const index = pool.waitQueue.findIndex((w) => w.resolve ===
|
|
18581
|
+
const index = pool.waitQueue.findIndex((w) => w.resolve === resolve5);
|
|
18535
18582
|
if (index !== -1) {
|
|
18536
18583
|
pool.waitQueue.splice(index, 1);
|
|
18537
18584
|
}
|
|
18538
18585
|
reject(new ConnectionTimeoutError(provider, this.config.acquireTimeoutMs));
|
|
18539
18586
|
}, this.config.acquireTimeoutMs);
|
|
18540
|
-
pool.waitQueue.push({ resolve:
|
|
18587
|
+
pool.waitQueue.push({ resolve: resolve5, reject, timeout });
|
|
18541
18588
|
logger.debug("[MCP Pool] Waiting for connection", {
|
|
18542
18589
|
provider,
|
|
18543
18590
|
queuePosition: pool.waitQueue.length
|
|
@@ -20014,6 +20061,8 @@ var McpServer = class _McpServer {
|
|
|
20014
20061
|
initializationPromise = null;
|
|
20015
20062
|
initializationMutex = new Mutex();
|
|
20016
20063
|
// BUG FIX (v9.0.1): Prevent concurrent initialization
|
|
20064
|
+
stdinMutex = new Mutex();
|
|
20065
|
+
// BUG FIX: Prevent race conditions in stdin message processing
|
|
20017
20066
|
version;
|
|
20018
20067
|
ajv;
|
|
20019
20068
|
compiledValidators = /* @__PURE__ */ new Map();
|
|
@@ -20389,7 +20438,15 @@ var McpServer = class _McpServer {
|
|
|
20389
20438
|
* v10.5.0: Capture clientInfo for Smart Routing
|
|
20390
20439
|
*/
|
|
20391
20440
|
async handleInitialize(request, id) {
|
|
20392
|
-
const clientInfo = request.params
|
|
20441
|
+
const clientInfo = request.params?.clientInfo;
|
|
20442
|
+
if (!clientInfo || typeof clientInfo.name !== "string" || typeof clientInfo.version !== "string") {
|
|
20443
|
+
logger.warn("[MCP Server] Invalid initialize request: missing or invalid clientInfo", {
|
|
20444
|
+
hasParams: !!request.params,
|
|
20445
|
+
hasClientInfo: !!clientInfo,
|
|
20446
|
+
clientInfo
|
|
20447
|
+
});
|
|
20448
|
+
return this.createErrorResponse(id, -32600 /* InvalidRequest */, "Invalid initialize request: clientInfo with name and version is required");
|
|
20449
|
+
}
|
|
20393
20450
|
logger.info("[MCP Server] Initialize request received (fast handshake mode)", { clientInfo });
|
|
20394
20451
|
this.session = {
|
|
20395
20452
|
clientInfo: {
|
|
@@ -20515,67 +20572,77 @@ ${json}`;
|
|
|
20515
20572
|
logger.info("[MCP Server] Starting stdio JSON-RPC server...");
|
|
20516
20573
|
let buffer = "";
|
|
20517
20574
|
let contentLength = null;
|
|
20518
|
-
process.stdin.on("data",
|
|
20519
|
-
|
|
20520
|
-
|
|
20521
|
-
|
|
20522
|
-
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20528
|
-
|
|
20529
|
-
|
|
20530
|
-
|
|
20531
|
-
iterations
|
|
20532
|
-
|
|
20533
|
-
|
|
20534
|
-
|
|
20535
|
-
|
|
20536
|
-
|
|
20537
|
-
|
|
20538
|
-
const
|
|
20539
|
-
|
|
20540
|
-
|
|
20541
|
-
|
|
20542
|
-
|
|
20543
|
-
|
|
20544
|
-
|
|
20545
|
-
|
|
20575
|
+
process.stdin.on("data", (chunk) => {
|
|
20576
|
+
void this.stdinMutex.runExclusive(async () => {
|
|
20577
|
+
buffer += chunk.toString("utf-8");
|
|
20578
|
+
if (buffer.length > STDIO_MAX_BUFFER_SIZE) {
|
|
20579
|
+
logger.error("[MCP Server] Buffer size exceeded maximum", {
|
|
20580
|
+
bufferSize: buffer.length,
|
|
20581
|
+
maxSize: STDIO_MAX_BUFFER_SIZE
|
|
20582
|
+
});
|
|
20583
|
+
buffer = "";
|
|
20584
|
+
contentLength = null;
|
|
20585
|
+
return;
|
|
20586
|
+
}
|
|
20587
|
+
let iterations = 0;
|
|
20588
|
+
while (iterations < STDIO_MAX_ITERATIONS) {
|
|
20589
|
+
iterations++;
|
|
20590
|
+
if (contentLength === null) {
|
|
20591
|
+
const delimiter2 = buffer.includes("\r\n\r\n") ? "\r\n\r\n" : buffer.includes("\n\n") ? "\n\n" : null;
|
|
20592
|
+
if (!delimiter2) break;
|
|
20593
|
+
const headerEndIndex = buffer.indexOf(delimiter2);
|
|
20594
|
+
const headerBlock = buffer.slice(0, headerEndIndex);
|
|
20595
|
+
for (const line of headerBlock.split(delimiter2 === "\r\n\r\n" ? "\r\n" : "\n")) {
|
|
20596
|
+
const [key, value] = line.split(":", 2).map((s) => s.trim());
|
|
20597
|
+
if (key && key.toLowerCase() === "content-length" && value) {
|
|
20598
|
+
contentLength = parseInt(value, 10);
|
|
20599
|
+
if (isNaN(contentLength) || contentLength <= 0 || contentLength > STDIO_MAX_MESSAGE_SIZE) {
|
|
20600
|
+
logger.error("[MCP Server] Invalid Content-Length", { contentLength });
|
|
20601
|
+
this.writeResponse({
|
|
20602
|
+
jsonrpc: "2.0",
|
|
20603
|
+
id: null,
|
|
20604
|
+
error: {
|
|
20605
|
+
code: -32600 /* InvalidRequest */,
|
|
20606
|
+
message: `Invalid Content-Length: ${contentLength}`
|
|
20607
|
+
}
|
|
20608
|
+
});
|
|
20609
|
+
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
20610
|
+
contentLength = null;
|
|
20611
|
+
continue;
|
|
20612
|
+
}
|
|
20546
20613
|
}
|
|
20547
20614
|
}
|
|
20548
|
-
|
|
20549
|
-
|
|
20550
|
-
|
|
20615
|
+
if (contentLength === null) {
|
|
20616
|
+
logger.error("[MCP Server] No Content-Length header found");
|
|
20617
|
+
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
20618
|
+
continue;
|
|
20619
|
+
}
|
|
20551
20620
|
buffer = buffer.slice(headerEndIndex + delimiter2.length);
|
|
20552
|
-
continue;
|
|
20553
20621
|
}
|
|
20554
|
-
|
|
20555
|
-
|
|
20556
|
-
|
|
20557
|
-
|
|
20558
|
-
|
|
20559
|
-
|
|
20560
|
-
|
|
20561
|
-
|
|
20562
|
-
|
|
20563
|
-
|
|
20564
|
-
|
|
20565
|
-
|
|
20566
|
-
|
|
20622
|
+
if (Buffer.byteLength(buffer, "utf-8") < contentLength) break;
|
|
20623
|
+
const messageBuffer = Buffer.from(buffer, "utf-8");
|
|
20624
|
+
const jsonMessage = messageBuffer.slice(0, contentLength).toString("utf-8");
|
|
20625
|
+
buffer = messageBuffer.slice(contentLength).toString("utf-8");
|
|
20626
|
+
contentLength = null;
|
|
20627
|
+
try {
|
|
20628
|
+
const request = JSON.parse(jsonMessage);
|
|
20629
|
+
logger.debug("[MCP Server] Request received", { method: request.method, id: request.id });
|
|
20630
|
+
const response = await this.handleRequest(request);
|
|
20631
|
+
if (request.id !== void 0 && request.id !== null) {
|
|
20632
|
+
this.writeResponse(response);
|
|
20633
|
+
}
|
|
20634
|
+
} catch (error) {
|
|
20635
|
+
logger.error("[MCP Server] Failed to parse or handle request", { jsonMessage, error });
|
|
20636
|
+
this.writeResponse({ jsonrpc: "2.0", id: null, error: { code: -32700 /* ParseError */, message: "Parse error: Invalid JSON" } });
|
|
20567
20637
|
}
|
|
20568
|
-
} catch (error) {
|
|
20569
|
-
logger.error("[MCP Server] Failed to parse or handle request", { jsonMessage, error });
|
|
20570
|
-
this.writeResponse({ jsonrpc: "2.0", id: null, error: { code: -32700 /* ParseError */, message: "Parse error: Invalid JSON" } });
|
|
20571
20638
|
}
|
|
20572
|
-
|
|
20573
|
-
|
|
20574
|
-
|
|
20575
|
-
|
|
20576
|
-
|
|
20577
|
-
}
|
|
20578
|
-
}
|
|
20639
|
+
if (iterations >= STDIO_MAX_ITERATIONS) {
|
|
20640
|
+
logger.warn("[MCP Server] Maximum iterations reached in message processing", {
|
|
20641
|
+
iterations,
|
|
20642
|
+
bufferSize: buffer.length
|
|
20643
|
+
});
|
|
20644
|
+
}
|
|
20645
|
+
});
|
|
20579
20646
|
});
|
|
20580
20647
|
const shutdown = (reason) => {
|
|
20581
20648
|
logger.info(`[MCP Server] ${reason}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defai.digital/automatosx",
|
|
3
|
-
"version": "11.2.
|
|
3
|
+
"version": "11.2.6",
|
|
4
4
|
"description": "Provider-agnostic AI orchestration platform with 20+ specialized agents, persistent memory, and multi-provider routing for Claude Code, Gemini CLI, Codex CLI, and ax-cli",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|