@defai.digital/automatosx 11.3.1 → 11.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mcp/index.js CHANGED
@@ -3,6 +3,7 @@ import * as path4 from 'path';
3
3
  import path4__default, { dirname, join, extname as extname$1, basename, resolve, relative, isAbsolute, sep, 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
+ import * as fs3 from 'fs';
6
7
  import { existsSync, readFileSync, promises, mkdirSync, createWriteStream, writeFileSync, unlinkSync, constants } from 'fs';
7
8
  import Database2 from 'better-sqlite3';
8
9
  import { glob } from 'glob';
@@ -23,9 +24,7 @@ import { randomUUID } from 'crypto';
23
24
  import yaml from 'yaml';
24
25
 
25
26
  var __defProp = Object.defineProperty;
26
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
27
27
  var __getOwnPropNames = Object.getOwnPropertyNames;
28
- var __hasOwnProp = Object.prototype.hasOwnProperty;
29
28
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
30
29
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
31
30
  }) : x)(function(x) {
@@ -39,15 +38,6 @@ var __export = (target, all) => {
39
38
  for (var name in all)
40
39
  __defProp(target, name, { get: all[name], enumerable: true });
41
40
  };
42
- var __copyProps = (to, from, except, desc) => {
43
- if (from && typeof from === "object" || typeof from === "function") {
44
- for (let key of __getOwnPropNames(from))
45
- if (!__hasOwnProp.call(to, key) && key !== except)
46
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
47
- }
48
- return to;
49
- };
50
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
51
41
  var init_esm_shims = __esm({
52
42
  "node_modules/tsup/assets/esm_shims.js"() {
53
43
  }
@@ -328,16 +318,16 @@ var init_errors = __esm({
328
318
  constructor(message, code = "E1001" /* CONFIG_INVALID */, suggestions = [], context) {
329
319
  super(message, code, suggestions, context);
330
320
  }
331
- static notFound(path5) {
321
+ static notFound(path6) {
332
322
  return new _ConfigError(
333
- `Configuration file not found: ${path5}`,
323
+ `Configuration file not found: ${path6}`,
334
324
  "E1000" /* CONFIG_NOT_FOUND */,
335
325
  [
336
326
  'Run "automatosx setup" to create a new configuration',
337
327
  "Specify a custom config path with --config option",
338
328
  "Check that you are in a valid AutomatosX project directory"
339
329
  ],
340
- { path: path5 }
330
+ { path: path6 }
341
331
  );
342
332
  }
343
333
  static invalid(reason, context) {
@@ -352,7 +342,7 @@ var init_errors = __esm({
352
342
  context
353
343
  );
354
344
  }
355
- static parseError(error, path5) {
345
+ static parseError(error, path6) {
356
346
  return new _ConfigError(
357
347
  `Failed to parse configuration: ${error.message}`,
358
348
  "E1002" /* CONFIG_PARSE_ERROR */,
@@ -361,7 +351,7 @@ var init_errors = __esm({
361
351
  "Use a JSON validator to find syntax errors",
362
352
  'Reset to default with "automatosx setup --force"'
363
353
  ],
364
- { path: path5, originalError: error.message }
354
+ { path: path6, originalError: error.message }
365
355
  );
366
356
  }
367
357
  };
@@ -1174,11 +1164,11 @@ var init_workspace_indexer = __esm({
1174
1164
  /**
1175
1165
  * Detect file type and language
1176
1166
  */
1177
- detectTypeAndLanguage(path5, ext) {
1178
- if (path5.match(/package\.json|tsconfig\.json|\.config\.(js|ts|json|yaml|yml)|\.eslintrc|\.prettierrc/)) {
1167
+ detectTypeAndLanguage(path6, ext) {
1168
+ if (path6.match(/package\.json|tsconfig\.json|\.config\.(js|ts|json|yaml|yml)|\.eslintrc|\.prettierrc/)) {
1179
1169
  return { type: "config", language: "json" };
1180
1170
  }
1181
- if (path5.match(/\.(test|spec)\.(ts|js|tsx|jsx)$/) || path5.includes("__tests__")) {
1171
+ if (path6.match(/\.(test|spec)\.(ts|js|tsx|jsx)$/) || path6.includes("__tests__")) {
1182
1172
  const lang = LANGUAGE_MAP[ext];
1183
1173
  return { type: "test", language: lang };
1184
1174
  }
@@ -1195,15 +1185,15 @@ var init_workspace_indexer = __esm({
1195
1185
  *
1196
1186
  * Higher score = more likely to be relevant
1197
1187
  */
1198
- calculateImportance(path5, type, size) {
1188
+ calculateImportance(path6, type, size) {
1199
1189
  let score = 0.5;
1200
- if (path5.match(/^(index|main|app)\.(ts|js|tsx|jsx)$/)) score = 1;
1201
- if (path5.match(/^src\/(index|main|app)\.(ts|js|tsx|jsx)$/)) score = 0.95;
1202
- if (path5.match(/^src\/cli\/(index|main)\.(ts|js)$/)) score = 0.9;
1190
+ if (path6.match(/^(index|main|app)\.(ts|js|tsx|jsx)$/)) score = 1;
1191
+ if (path6.match(/^src\/(index|main|app)\.(ts|js|tsx|jsx)$/)) score = 0.95;
1192
+ if (path6.match(/^src\/cli\/(index|main)\.(ts|js)$/)) score = 0.9;
1203
1193
  if (type === "config") score = 0.85;
1204
- if (path5.includes("/core/")) score += 0.15;
1205
- if (path5.includes("/types/")) score += 0.1;
1206
- if (path5.includes("/utils/")) score += 0.05;
1194
+ if (path6.includes("/core/")) score += 0.15;
1195
+ if (path6.includes("/types/")) score += 0.1;
1196
+ if (path6.includes("/utils/")) score += 0.05;
1207
1197
  if (type === "test") score = Math.max(0.3, score - 0.3);
1208
1198
  if (type === "doc") score = Math.max(0.4, score - 0.2);
1209
1199
  if (size > 1e4) score += 0.05;
@@ -1679,10 +1669,10 @@ function findOnPathUnix(cmdBase) {
1679
1669
  try {
1680
1670
  const which = spawnSync("which", [cmdBase], { timeout: 3e3 });
1681
1671
  if (which.status === 0) {
1682
- const path5 = which.stdout.toString().trim();
1683
- if (path5) {
1684
- logger.debug("Found via which", { cmdBase, path: path5 });
1685
- return { found: true, path: path5 };
1672
+ const path6 = which.stdout.toString().trim();
1673
+ if (path6) {
1674
+ logger.debug("Found via which", { cmdBase, path: path6 });
1675
+ return { found: true, path: path6 };
1686
1676
  }
1687
1677
  }
1688
1678
  } catch (error) {
@@ -1981,15 +1971,6 @@ var init_streaming_progress_parser = __esm({
1981
1971
  });
1982
1972
 
1983
1973
  // src/providers/error-patterns.ts
1984
- var error_patterns_exports = {};
1985
- __export(error_patterns_exports, {
1986
- GENERIC_ERROR_PATTERNS: () => GENERIC_ERROR_PATTERNS,
1987
- PROVIDER_ERROR_PATTERNS: () => PROVIDER_ERROR_PATTERNS,
1988
- getProviderErrorPatterns: () => getProviderErrorPatterns,
1989
- isLimitError: () => isLimitError,
1990
- isQuotaError: () => isQuotaError,
1991
- isRateLimitError: () => isRateLimitError
1992
- });
1993
1974
  function isQuotaError(error, providerName) {
1994
1975
  const patterns = PROVIDER_ERROR_PATTERNS[providerName] || GENERIC_ERROR_PATTERNS;
1995
1976
  const message = (error?.message || "").toLowerCase();
@@ -2031,9 +2012,6 @@ function isRateLimitError(error, providerName) {
2031
2012
  function isLimitError(error, providerName) {
2032
2013
  return isQuotaError(error, providerName) || isRateLimitError(error, providerName);
2033
2014
  }
2034
- function getProviderErrorPatterns(providerName) {
2035
- return PROVIDER_ERROR_PATTERNS[providerName] || GENERIC_ERROR_PATTERNS;
2036
- }
2037
2015
  var PROVIDER_ERROR_PATTERNS, GENERIC_ERROR_PATTERNS;
2038
2016
  var init_error_patterns = __esm({
2039
2017
  "src/providers/error-patterns.ts"() {
@@ -2254,6 +2232,7 @@ var init_base_provider = __esm({
2254
2232
  init_provider_schemas();
2255
2233
  init_streaming_progress_parser();
2256
2234
  init_verbosity_manager();
2235
+ init_error_patterns();
2257
2236
  BaseProvider = class _BaseProvider {
2258
2237
  /**
2259
2238
  * Whitelist of allowed provider names for security
@@ -2286,6 +2265,10 @@ var init_base_provider = __esm({
2286
2265
  NO_UPDATE_NOTIFIER: "1",
2287
2266
  DEBIAN_FRONTEND: "noninteractive"
2288
2267
  };
2268
+ /** Default CLI execution timeout in milliseconds */
2269
+ static DEFAULT_TIMEOUT_MS = 12e4;
2270
+ /** Time to wait after SIGTERM before escalating to SIGKILL */
2271
+ static SIGKILL_ESCALATION_MS = 5e3;
2289
2272
  config;
2290
2273
  logger = logger;
2291
2274
  health;
@@ -2343,7 +2326,7 @@ var init_base_provider = __esm({
2343
2326
  useStdin,
2344
2327
  streaming: process.env.AUTOMATOSX_SHOW_PROVIDER_OUTPUT === "true"
2345
2328
  });
2346
- const result = useStdin ? await this.executeWithStdin(cliCommand, argsString.trim(), prompt) : await this.executeWithSpawn(fullCommand, cliCommand);
2329
+ const result = useStdin ? await this.executeWithStdin(cliCommand, cliArgs, prompt) : await this.executeWithSpawn(fullCommand, cliCommand);
2347
2330
  if (!result.stdout) {
2348
2331
  throw new Error(`${cliCommand} CLI returned empty output. stderr: ${result.stderr || "none"}`);
2349
2332
  }
@@ -2365,8 +2348,8 @@ var init_base_provider = __esm({
2365
2348
  /**
2366
2349
  * Execute command using spawn() with streaming support (v8.4.18)
2367
2350
  *
2368
- * Replaces execWithCleanup to support real-time line-by-line output streaming.
2369
- * Maintains all timeout and cleanup behaviors from execWithCleanup.
2351
+ * Supports real-time line-by-line output streaming with proper timeout
2352
+ * and cleanup behaviors (SIGTERM → SIGKILL escalation pattern).
2370
2353
  *
2371
2354
  * @param command - Full command string to execute
2372
2355
  * @param cliCommand - CLI command name (for logging)
@@ -2377,7 +2360,7 @@ var init_base_provider = __esm({
2377
2360
  const child = spawn(command, [], {
2378
2361
  shell: true,
2379
2362
  // Auto-detects: cmd.exe on Windows, /bin/sh on Unix
2380
- timeout: this.config.timeout || 12e4,
2363
+ timeout: this.config.timeout || _BaseProvider.DEFAULT_TIMEOUT_MS,
2381
2364
  env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
2382
2365
  });
2383
2366
  let stdout = "";
@@ -2488,7 +2471,7 @@ var init_base_provider = __esm({
2488
2471
  });
2489
2472
  reject(new Error(`Failed to spawn ${cliCommand} CLI: ${error.message}`));
2490
2473
  });
2491
- const timeout = this.config.timeout || 12e4;
2474
+ const timeout = this.config.timeout || _BaseProvider.DEFAULT_TIMEOUT_MS;
2492
2475
  timeoutId = setTimeout(() => {
2493
2476
  if (child.pid && !child.killed) {
2494
2477
  logger.warn("Killing child process due to timeout", {
@@ -2502,7 +2485,7 @@ var init_base_provider = __esm({
2502
2485
  logger.warn("Force killing child process", { pid: child.pid });
2503
2486
  child.kill("SIGKILL");
2504
2487
  }
2505
- }, 5e3);
2488
+ }, _BaseProvider.SIGKILL_ESCALATION_MS);
2506
2489
  }
2507
2490
  }, timeout);
2508
2491
  });
@@ -2520,14 +2503,13 @@ var init_base_provider = __esm({
2520
2503
  */
2521
2504
  async executeWithStdin(cliCommand, cliArgs, prompt) {
2522
2505
  return new Promise((resolve5, reject) => {
2523
- const commandArgs = cliArgs ? cliArgs.split(" ").filter(Boolean) : [];
2524
2506
  logger.debug(`Executing ${cliCommand} CLI with stdin`, {
2525
2507
  command: cliCommand,
2526
- args: commandArgs,
2508
+ args: cliArgs,
2527
2509
  promptLength: prompt.length
2528
2510
  });
2529
- const child = spawn(cliCommand, commandArgs, {
2530
- timeout: this.config.timeout || 12e4,
2511
+ const child = spawn(cliCommand, cliArgs, {
2512
+ timeout: this.config.timeout || _BaseProvider.DEFAULT_TIMEOUT_MS,
2531
2513
  env: { ...process.env, ..._BaseProvider.NON_INTERACTIVE_ENV }
2532
2514
  });
2533
2515
  let stdout = "";
@@ -2663,7 +2645,7 @@ var init_base_provider = __esm({
2663
2645
  });
2664
2646
  reject(new Error(`Failed to spawn ${cliCommand} CLI: ${error.message}`));
2665
2647
  });
2666
- const timeout = this.config.timeout || 12e4;
2648
+ const timeout = this.config.timeout || _BaseProvider.DEFAULT_TIMEOUT_MS;
2667
2649
  timeoutId = setTimeout(() => {
2668
2650
  if (child.pid && !child.killed) {
2669
2651
  logger.warn("Killing child process due to timeout", {
@@ -2677,7 +2659,7 @@ var init_base_provider = __esm({
2677
2659
  logger.warn("Force killing child process", { pid: child.pid });
2678
2660
  child.kill("SIGKILL");
2679
2661
  }
2680
- }, 5e3);
2662
+ }, _BaseProvider.SIGKILL_ESCALATION_MS);
2681
2663
  }
2682
2664
  }, timeout);
2683
2665
  });
@@ -2743,9 +2725,7 @@ var init_base_provider = __esm({
2743
2725
  ${request.prompt}`;
2744
2726
  }
2745
2727
  if (process.env.AUTOMATOSX_DEBUG_PROMPT === "true") {
2746
- const fs3 = await import('fs');
2747
- const path5 = await import('path');
2748
- const debugPath = path5.join(process.cwd(), "automatosx/tmp/debug-prompt.txt");
2728
+ const debugPath = path4.join(process.cwd(), "automatosx/tmp/debug-prompt.txt");
2749
2729
  fs3.writeFileSync(debugPath, `=== FULL PROMPT SENT TO ${this.getCLICommand()} ===
2750
2730
 
2751
2731
  ${fullPrompt}
@@ -2869,26 +2849,16 @@ ${fullPrompt}
2869
2849
  * @returns true if this is a rate limit or quota error
2870
2850
  */
2871
2851
  detectRateLimitError(error) {
2872
- const { isLimitError: isLimitError2 } = (init_error_patterns(), __toCommonJS(error_patterns_exports));
2873
- try {
2874
- const isLimited = isLimitError2(error, this.config.name);
2875
- if (isLimited) {
2876
- this.logger.debug("Rate limit error detected", {
2877
- provider: this.config.name,
2878
- message: error?.message,
2879
- code: error?.code,
2880
- status: error?.status || error?.statusCode
2881
- });
2882
- }
2883
- return isLimited;
2884
- } catch (detectionError) {
2885
- this.logger.warn("Rate limit detection failed, using fallback", {
2852
+ const isLimited = isLimitError(error, this.config.name);
2853
+ if (isLimited) {
2854
+ this.logger.debug("Rate limit error detected", {
2886
2855
  provider: this.config.name,
2887
- error: detectionError
2856
+ message: error?.message,
2857
+ code: error?.code,
2858
+ status: error?.status || error?.statusCode
2888
2859
  });
2889
- const message = (error?.message || "").toLowerCase();
2890
- return message.includes("rate limit") || message.includes("quota") || message.includes("resource_exhausted") || message.includes("too many requests");
2891
2860
  }
2861
+ return isLimited;
2892
2862
  }
2893
2863
  /**
2894
2864
  * Escape shell command arguments to prevent injection
@@ -4578,11 +4548,11 @@ var VALIDATION_LIMITS = {
4578
4548
  MAX_PORT: 65535
4579
4549
  // Maximum port number
4580
4550
  };
4581
- function isValidRelativePath(path5) {
4582
- if (!path5 || typeof path5 !== "string") {
4551
+ function isValidRelativePath(path6) {
4552
+ if (!path6 || typeof path6 !== "string") {
4583
4553
  return false;
4584
4554
  }
4585
- const normalizedPath = path5.replace(/\\/g, "/");
4555
+ const normalizedPath = path6.replace(/\\/g, "/");
4586
4556
  if (normalizedPath.startsWith("/")) {
4587
4557
  return false;
4588
4558
  }
@@ -5212,11 +5182,16 @@ var PRECOMPILED_CONFIG = {
5212
5182
  },
5213
5183
  "advanced": {
5214
5184
  "embedding": {
5185
+ "model": "text-embedding-3-small",
5215
5186
  "timeout": 3e4,
5216
5187
  "retryDelay": 1e3,
5217
5188
  "dimensions": 1536,
5218
5189
  "maxRetries": 3
5219
5190
  },
5191
+ "projectContext": {
5192
+ "maxSizeBytes": 102400,
5193
+ "cacheTtlMs": 3e5
5194
+ },
5220
5195
  "security": {
5221
5196
  "enablePathValidation": true,
5222
5197
  "allowedExtensions": [
@@ -5272,7 +5247,23 @@ var PRECOMPILED_CONFIG = {
5272
5247
  "enableFreeTierPrioritization": true,
5273
5248
  "enableWorkloadAwareRouting": true
5274
5249
  },
5275
- "version": "11.3.1"
5250
+ "axCliSdk": {
5251
+ "maxToolRounds": 400,
5252
+ "checkpoint": {
5253
+ "maxCheckpoints": 10,
5254
+ "flushTimeoutMs": 5e3
5255
+ },
5256
+ "subagent": {
5257
+ "maxParallel": 4,
5258
+ "timeoutMs": 3e5,
5259
+ "maxToolRounds": 100
5260
+ },
5261
+ "instructions": {
5262
+ "cacheTtlMs": 3e5,
5263
+ "maxContextLength": 32e3
5264
+ }
5265
+ },
5266
+ "version": "11.3.2"
5276
5267
  };
5277
5268
 
5278
5269
  // src/core/config/schemas.ts
@@ -5299,7 +5290,7 @@ var safeNameSchema = z.string().min(1).max(VALIDATION_LIMITS.MAX_NAME_LENGTH).re
5299
5290
  "Name must be alphanumeric with dash/underscore only"
5300
5291
  ).describe("Safe identifier name");
5301
5292
  var relativePathSchema = z.string().min(1).refine(
5302
- (path5) => !path5.includes("..") && !path5.startsWith("/"),
5293
+ (path6) => !path6.includes("..") && !path6.startsWith("/"),
5303
5294
  "Path must be relative (no ../, no absolute paths)"
5304
5295
  ).describe("Relative path within project");
5305
5296
  var fileExtensionSchema = z.string().regex(
@@ -5639,16 +5630,16 @@ async function loadConfigUncached(projectDir) {
5639
5630
  });
5640
5631
  return config;
5641
5632
  }
5642
- async function loadConfigFile(path5) {
5633
+ async function loadConfigFile(path6) {
5643
5634
  try {
5644
- const content = await readFile(path5, "utf-8");
5635
+ const content = await readFile(path6, "utf-8");
5645
5636
  if (content.length > VALIDATION_LIMITS.MAX_CONFIG_FILE_SIZE) {
5646
5637
  throw ConfigError.parseError(
5647
5638
  new Error(`Config file too large (max ${VALIDATION_LIMITS.MAX_CONFIG_FILE_SIZE / 1024}KB, got ${Math.ceil(content.length / 1024)}KB)`),
5648
- path5
5639
+ path6
5649
5640
  );
5650
5641
  }
5651
- const ext = extname(path5).toLowerCase();
5642
+ const ext = extname(path6).toLowerCase();
5652
5643
  let userConfig;
5653
5644
  try {
5654
5645
  if (ext === ".yaml" || ext === ".yml") {
@@ -5657,7 +5648,7 @@ async function loadConfigFile(path5) {
5657
5648
  userConfig = JSON.parse(content);
5658
5649
  }
5659
5650
  } catch (parseError) {
5660
- throw ConfigError.parseError(parseError, path5);
5651
+ throw ConfigError.parseError(parseError, path6);
5661
5652
  }
5662
5653
  const config = mergeConfig(DEFAULT_CONFIG, userConfig);
5663
5654
  if (config.execution && userConfig.execution?.maxConcurrentAgents === void 0) {
@@ -5673,35 +5664,35 @@ async function loadConfigFile(path5) {
5673
5664
  if (validationErrors.length > 0) {
5674
5665
  throw ConfigError.invalid(
5675
5666
  validationErrors.join("; "),
5676
- { path: path5, errors: validationErrors }
5667
+ { path: path6, errors: validationErrors }
5677
5668
  );
5678
5669
  }
5679
- logger.info("Config loaded successfully", { path: normalizePath(path5), format: ext });
5670
+ logger.info("Config loaded successfully", { path: normalizePath(path6), format: ext });
5680
5671
  return config;
5681
5672
  } catch (error) {
5682
5673
  if (error instanceof ConfigError) {
5683
5674
  throw error;
5684
5675
  }
5685
5676
  if (error.code === "ENOENT") {
5686
- throw ConfigError.notFound(path5);
5677
+ throw ConfigError.notFound(path6);
5687
5678
  }
5688
5679
  if (error.code === "EACCES") {
5689
5680
  throw new ConfigError(
5690
- `Permission denied reading config: ${path5}`,
5681
+ `Permission denied reading config: ${path6}`,
5691
5682
  "E1002" /* CONFIG_PARSE_ERROR */,
5692
5683
  [
5693
5684
  "Check file permissions",
5694
5685
  "Run with appropriate user privileges",
5695
5686
  "Verify the file is accessible"
5696
5687
  ],
5697
- { path: path5, error: error.message }
5688
+ { path: path6, error: error.message }
5698
5689
  );
5699
5690
  }
5700
5691
  throw new ConfigError(
5701
5692
  `Failed to load config: ${error.message}`,
5702
5693
  "E1002" /* CONFIG_PARSE_ERROR */,
5703
5694
  ["Check file format and permissions"],
5704
- { path: path5, originalError: error.message }
5695
+ { path: path6, originalError: error.message }
5705
5696
  );
5706
5697
  }
5707
5698
  }
@@ -5717,8 +5708,8 @@ function validateConfigWithZod(config) {
5717
5708
  return ["Configuration validation failed with unknown error structure"];
5718
5709
  }
5719
5710
  return result.error.issues.map((err) => {
5720
- const path5 = err.path.join(".");
5721
- return `${path5}: ${err.message}`;
5711
+ const path6 = err.path.join(".");
5712
+ return `${path6}: ${err.message}`;
5722
5713
  });
5723
5714
  }
5724
5715
  function validateConfig(config) {
@@ -6128,8 +6119,8 @@ var PathError = class extends Error {
6128
6119
  };
6129
6120
 
6130
6121
  // src/shared/validation/path-resolver.ts
6131
- function isWindowsPath(path5) {
6132
- return /^[a-zA-Z]:[/\\]/.test(path5);
6122
+ function isWindowsPath(path6) {
6123
+ return /^[a-zA-Z]:[/\\]/.test(path6);
6133
6124
  }
6134
6125
  async function detectProjectRoot(startDir = process.cwd()) {
6135
6126
  if (process.env.AUTOMATOSX_PROJECT_ROOT) {
@@ -6229,8 +6220,8 @@ var PathResolver = class {
6229
6220
  /**
6230
6221
  * Validate path is within allowed base directory
6231
6222
  */
6232
- validatePath(path5, baseDir) {
6233
- const normalized = normalizePath(resolvePath(path5));
6223
+ validatePath(path6, baseDir) {
6224
+ const normalized = normalizePath(resolvePath(path6));
6234
6225
  const base = normalizePath(resolvePath(baseDir));
6235
6226
  const separator = "/";
6236
6227
  const pathWithSep = normalized + separator;
@@ -6240,15 +6231,15 @@ var PathResolver = class {
6240
6231
  /**
6241
6232
  * Check if path is within allowed boundaries
6242
6233
  */
6243
- isPathAllowed(path5) {
6244
- const boundary = this.checkBoundaries(path5);
6234
+ isPathAllowed(path6) {
6235
+ const boundary = this.checkBoundaries(path6);
6245
6236
  return boundary === "agent_workspace" || boundary === "user_project";
6246
6237
  }
6247
6238
  /**
6248
6239
  * Check which boundary a path belongs to
6249
6240
  */
6250
- checkBoundaries(path5) {
6251
- const normalized = resolvePath(path5);
6241
+ checkBoundaries(path6) {
6242
+ const normalized = resolvePath(path6);
6252
6243
  if (this.validatePath(normalized, this.config.agentWorkspace)) {
6253
6244
  return "agent_workspace";
6254
6245
  }
@@ -6266,15 +6257,15 @@ var PathResolver = class {
6266
6257
  /**
6267
6258
  * Get relative path from project root
6268
6259
  */
6269
- getRelativeToProject(path5) {
6270
- const normalized = resolvePath(path5);
6260
+ getRelativeToProject(path6) {
6261
+ const normalized = resolvePath(path6);
6271
6262
  return normalizePath(getRelativePath(this.config.projectDir, normalized));
6272
6263
  }
6273
6264
  /**
6274
6265
  * Get relative path from working directory
6275
6266
  */
6276
- getRelativeToWorking(path5) {
6277
- const normalized = resolvePath(path5);
6267
+ getRelativeToWorking(path6) {
6268
+ const normalized = resolvePath(path6);
6278
6269
  return normalizePath(getRelativePath(this.config.workingDir, normalized));
6279
6270
  }
6280
6271
  /**
@@ -6293,11 +6284,11 @@ var PathResolver = class {
6293
6284
  * Validate path is within project boundaries
6294
6285
  * @throws PathError if outside project
6295
6286
  */
6296
- validateInProject(path5) {
6297
- const boundary = this.checkBoundaries(path5);
6287
+ validateInProject(path6) {
6288
+ const boundary = this.checkBoundaries(path6);
6298
6289
  if (boundary === "outside_boundaries" || boundary === "system_restricted") {
6299
6290
  throw new PathError("Path outside project directory", {
6300
- path: path5,
6291
+ path: path6,
6301
6292
  projectDir: this.config.projectDir,
6302
6293
  boundary
6303
6294
  });
@@ -8164,18 +8155,18 @@ var ProviderSessionManager = class {
8164
8155
  };
8165
8156
  var providerSessionInstances = /* @__PURE__ */ new Map();
8166
8157
  async function getProviderSession(workspacePath) {
8167
- let path5;
8158
+ let path6;
8168
8159
  {
8169
8160
  if (process.env.NODE_ENV === "test" || process.env.VITEST) {
8170
- path5 = process.cwd();
8161
+ path6 = process.cwd();
8171
8162
  } else {
8172
- path5 = await detectProjectRoot();
8163
+ path6 = await detectProjectRoot();
8173
8164
  }
8174
8165
  }
8175
- if (!providerSessionInstances.has(path5)) {
8176
- providerSessionInstances.set(path5, new ProviderSessionManager(path5));
8166
+ if (!providerSessionInstances.has(path6)) {
8167
+ providerSessionInstances.set(path6, new ProviderSessionManager(path6));
8177
8168
  }
8178
- return providerSessionInstances.get(path5);
8169
+ return providerSessionInstances.get(path6);
8179
8170
  }
8180
8171
 
8181
8172
  // src/core/router/router.ts
@@ -9944,6 +9935,9 @@ var MemoryManager = class _MemoryManager {
9944
9935
  if (!Number.isInteger(offsetValue) || offsetValue < 0) {
9945
9936
  throw new Error(`Invalid offset value: ${options.offset}. Must be a non-negative integer.`);
9946
9937
  }
9938
+ if (!limitClause) {
9939
+ limitClause = "LIMIT -1";
9940
+ }
9947
9941
  offsetClause = `OFFSET ${offsetValue}`;
9948
9942
  }
9949
9943
  const sql = `
@@ -10297,6 +10291,13 @@ var MemoryManager = class _MemoryManager {
10297
10291
  await this.initialize();
10298
10292
  logger.info("Database restored successfully (atomic operation)", { srcPath: normalizePath(srcPath) });
10299
10293
  } catch (error) {
10294
+ try {
10295
+ DatabaseFactory.close(this.db);
10296
+ } finally {
10297
+ this.initialized = false;
10298
+ this.entryCount = 0;
10299
+ this.statements = {};
10300
+ }
10300
10301
  throw new MemoryError(
10301
10302
  `Failed to restore database: ${error.message}`,
10302
10303
  "DATABASE_ERROR",
@@ -10846,6 +10847,10 @@ var SessionManager = class _SessionManager {
10846
10847
  MAX_TASKS_PER_SESSION = 1e3;
10847
10848
  /** UUID v4 validation regex (static for performance) */
10848
10849
  static UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
10850
+ /** Tracks whether manager has been destroyed to prevent late saves */
10851
+ destroyed = false;
10852
+ /** Last persistence error (reported during flush) */
10853
+ lastSaveError;
10849
10854
  /**
10850
10855
  * Validate session ID format (must be valid UUID v4)
10851
10856
  *
@@ -11440,6 +11445,7 @@ var SessionManager = class _SessionManager {
11440
11445
  * ```
11441
11446
  */
11442
11447
  async destroy() {
11448
+ this.destroyed = true;
11443
11449
  if (this.saveTimeout) {
11444
11450
  clearTimeout(this.saveTimeout);
11445
11451
  this.saveTimeout = void 0;
@@ -11450,9 +11456,12 @@ var SessionManager = class _SessionManager {
11450
11456
  logger.error("Error flushing save during destroy", {
11451
11457
  error: error.message
11452
11458
  });
11459
+ this.lastSaveError = void 0;
11453
11460
  }
11461
+ const sessionCount = this.activeSessions.size;
11462
+ this.activeSessions.clear();
11454
11463
  logger.debug("SessionManager destroyed", {
11455
- sessions: this.activeSessions.size
11464
+ sessions: sessionCount
11456
11465
  });
11457
11466
  }
11458
11467
  /**
@@ -11477,11 +11486,21 @@ var SessionManager = class _SessionManager {
11477
11486
  this.pendingSave = void 0;
11478
11487
  });
11479
11488
  await this.pendingSave;
11489
+ if (this.lastSaveError) {
11490
+ const err = this.lastSaveError;
11491
+ this.lastSaveError = void 0;
11492
+ throw err;
11493
+ }
11480
11494
  return;
11481
11495
  }
11482
11496
  if (this.pendingSave) {
11483
11497
  try {
11484
11498
  await this.pendingSave;
11499
+ if (this.lastSaveError) {
11500
+ const err = this.lastSaveError;
11501
+ this.lastSaveError = void 0;
11502
+ throw err;
11503
+ }
11485
11504
  } catch (err) {
11486
11505
  throw err;
11487
11506
  }
@@ -11646,7 +11665,7 @@ var SessionManager = class _SessionManager {
11646
11665
  * @private
11647
11666
  */
11648
11667
  saveToFile() {
11649
- if (!this.persistencePath) {
11668
+ if (!this.persistencePath || this.destroyed) {
11650
11669
  return;
11651
11670
  }
11652
11671
  if (this.saveTimeout) {
@@ -11659,18 +11678,18 @@ var SessionManager = class _SessionManager {
11659
11678
  }
11660
11679
  this.saveNeeded = false;
11661
11680
  const executeNextSave = async () => {
11662
- await this.doSave();
11681
+ try {
11682
+ await this.doSave();
11683
+ this.lastSaveError = void 0;
11684
+ } catch (err) {
11685
+ this.lastSaveError = err;
11686
+ }
11663
11687
  if (this.saveNeeded) {
11664
11688
  this.saveNeeded = false;
11665
11689
  return executeNextSave();
11666
11690
  }
11667
11691
  };
11668
- this.pendingSave = executeNextSave().catch((err) => {
11669
- logger.error("Debounced save failed", {
11670
- error: err.message
11671
- });
11672
- throw err;
11673
- }).finally(() => {
11692
+ this.pendingSave = executeNextSave().finally(() => {
11674
11693
  this.pendingSave = void 0;
11675
11694
  });
11676
11695
  }, 100);
@@ -15081,9 +15100,9 @@ var DependencyGraphBuilder = class {
15081
15100
  detectCycles(graph) {
15082
15101
  const visiting = /* @__PURE__ */ new Set();
15083
15102
  const visited = /* @__PURE__ */ new Set();
15084
- const visit = (nodeName, path5) => {
15103
+ const visit = (nodeName, path6) => {
15085
15104
  if (visiting.has(nodeName)) {
15086
- throw new Error(`Circular dependency detected: ${[...path5, nodeName].join(" \u2192 ")}`);
15105
+ throw new Error(`Circular dependency detected: ${[...path6, nodeName].join(" \u2192 ")}`);
15087
15106
  }
15088
15107
  if (visited.has(nodeName)) {
15089
15108
  return;
@@ -15098,7 +15117,7 @@ var DependencyGraphBuilder = class {
15098
15117
  }
15099
15118
  visiting.add(nodeName);
15100
15119
  for (const dependency of node.dependencies) {
15101
- visit(dependency, [...path5, nodeName]);
15120
+ visit(dependency, [...path6, nodeName]);
15102
15121
  }
15103
15122
  visiting.delete(nodeName);
15104
15123
  visited.add(nodeName);
@@ -16831,59 +16850,59 @@ var DANGEROUS_PATH_PATTERNS = [
16831
16850
  // Common data drive (Windows, alt format)
16832
16851
  ];
16833
16852
  var SUSPICIOUS_PATH_CHARS = /[<>:|"]/;
16834
- function validatePathParameter(path5, paramName, projectRoot = process.cwd()) {
16835
- if (!path5 || path5.trim() === "") {
16853
+ function validatePathParameter(path6, paramName, projectRoot = process.cwd()) {
16854
+ if (!path6 || path6.trim() === "") {
16836
16855
  throw new ValidationError(
16837
16856
  `Invalid ${paramName}: path cannot be empty`,
16838
16857
  -32602 /* InvalidParams */,
16839
- { path: path5, paramName }
16858
+ { path: path6, paramName }
16840
16859
  );
16841
16860
  }
16842
16861
  for (const pattern of DANGEROUS_PATH_PATTERNS) {
16843
- if (path5.includes(pattern)) {
16862
+ if (path6.includes(pattern)) {
16844
16863
  throw new ValidationError(
16845
16864
  `Invalid ${paramName}: path contains dangerous pattern "${pattern}"`,
16846
16865
  -32602 /* InvalidParams */,
16847
- { path: path5, paramName, pattern }
16866
+ { path: path6, paramName, pattern }
16848
16867
  );
16849
16868
  }
16850
16869
  }
16851
- if (isAbsolute(path5)) {
16870
+ if (isAbsolute(path6)) {
16852
16871
  throw new ValidationError(
16853
16872
  `Invalid ${paramName}: absolute paths are not allowed`,
16854
16873
  -32602 /* InvalidParams */,
16855
- { path: path5, paramName }
16874
+ { path: path6, paramName }
16856
16875
  );
16857
16876
  }
16858
16877
  try {
16859
- const resolvedPath = resolve(projectRoot, path5);
16878
+ const resolvedPath = resolve(projectRoot, path6);
16860
16879
  const normalizedRoot = resolve(projectRoot);
16861
16880
  if (!resolvedPath.startsWith(normalizedRoot + sep) && resolvedPath !== normalizedRoot) {
16862
16881
  throw new ValidationError(
16863
16882
  `Invalid ${paramName}: path escapes project boundary`,
16864
16883
  -32602 /* InvalidParams */,
16865
- { path: path5, paramName, projectRoot, resolvedPath }
16884
+ { path: path6, paramName, projectRoot, resolvedPath }
16866
16885
  );
16867
16886
  }
16868
16887
  } catch (error) {
16869
16888
  throw new ValidationError(
16870
16889
  `Invalid ${paramName}: path resolution failed`,
16871
16890
  -32602 /* InvalidParams */,
16872
- { path: path5, paramName, error: String(error) }
16891
+ { path: path6, paramName, error: String(error) }
16873
16892
  );
16874
16893
  }
16875
- if (path5.includes("\0")) {
16894
+ if (path6.includes("\0")) {
16876
16895
  throw new ValidationError(
16877
16896
  `Invalid ${paramName}: path contains null byte`,
16878
16897
  -32602 /* InvalidParams */,
16879
- { path: path5, paramName }
16898
+ { path: path6, paramName }
16880
16899
  );
16881
16900
  }
16882
- if (SUSPICIOUS_PATH_CHARS.test(path5)) {
16901
+ if (SUSPICIOUS_PATH_CHARS.test(path6)) {
16883
16902
  throw new ValidationError(
16884
16903
  `Invalid ${paramName}: path contains invalid characters`,
16885
16904
  -32602 /* InvalidParams */,
16886
- { path: path5, paramName }
16905
+ { path: path6, paramName }
16887
16906
  );
16888
16907
  }
16889
16908
  }
@@ -17579,8 +17598,8 @@ function createMemoryExportHandler(deps) {
17579
17598
  return async (input) => {
17580
17599
  logger.info("[MCP] memory_export called", { input });
17581
17600
  try {
17582
- const { path: path5 } = input;
17583
- const absolutePath = resolveExportPath(deps.pathResolver, path5);
17601
+ const { path: path6 } = input;
17602
+ const absolutePath = resolveExportPath(deps.pathResolver, path6);
17584
17603
  const exported = await deps.memoryManager.exportToJSON(absolutePath);
17585
17604
  const result = {
17586
17605
  success: true,
@@ -17616,8 +17635,8 @@ function createMemoryImportHandler(deps) {
17616
17635
  return async (input) => {
17617
17636
  logger.info("[MCP] memory_import called", { input });
17618
17637
  try {
17619
- const { path: path5 } = input;
17620
- const absolutePath = resolveImportPath(deps.pathResolver, path5);
17638
+ const { path: path6 } = input;
17639
+ const absolutePath = resolveImportPath(deps.pathResolver, path6);
17621
17640
  const imported = await deps.memoryManager.importFromJSON(absolutePath);
17622
17641
  const result = {
17623
17642
  success: true,
@@ -18192,7 +18211,18 @@ var McpClient = class extends EventEmitter {
18192
18211
  timeout: timeoutHandle
18193
18212
  });
18194
18213
  const message = JSON.stringify(request) + "\n";
18195
- this.process.stdin.write(message);
18214
+ try {
18215
+ this.process.stdin.write(message);
18216
+ } catch (error) {
18217
+ const pending = this.pendingRequests.get(id);
18218
+ if (pending) {
18219
+ clearTimeout(pending.timeout);
18220
+ this.pendingRequests.delete(id);
18221
+ }
18222
+ const err = error instanceof Error ? error : new Error(String(error));
18223
+ reject(err);
18224
+ return;
18225
+ }
18196
18226
  logger.debug("[MCP Client] Sent request", {
18197
18227
  id,
18198
18228
  method,