@defai.digital/automatosx 6.5.11 → 6.5.12

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.
Files changed (2) hide show
  1. package/dist/index.js +109 -43
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1879,16 +1879,18 @@ var init_cli_provider_detector = __esm({
1879
1879
 
1880
1880
  // src/utils/environment.ts
1881
1881
  function isClaudeCodeEnvironment() {
1882
+ const parentProcess = (process.env._ || "").toLowerCase();
1883
+ const comSpec = (process.env.ComSpec || "").toLowerCase();
1882
1884
  return Boolean(
1883
1885
  // Explicit Claude Code indicators
1884
1886
  process.env.CLAUDE_CODE === "true" || process.env.CLAUDE_DESKTOP === "true" || process.env.MCP_SERVER === "true" || // Check parent process name (Unix/Windows)
1885
- process.env._?.toLowerCase().includes("claude") || process.env.ComSpec?.toLowerCase().includes("claude") || // Check if MCP tools are being used
1886
- process.env.ANTHROPIC_API_KEY !== void 0
1887
+ parentProcess.includes("claude") || comSpec.includes("claude")
1887
1888
  );
1888
1889
  }
1889
1890
  function isCursorEnvironment() {
1891
+ const parentProcess = (process.env._ || "").toLowerCase();
1890
1892
  return Boolean(
1891
- process.env.CURSOR === "true" || process.env.CURSOR_IDE === "true" || process.env._?.toLowerCase().includes("cursor")
1893
+ process.env.CURSOR === "true" || process.env.CURSOR_IDE === "true" || parentProcess.includes("cursor")
1892
1894
  );
1893
1895
  }
1894
1896
  function isVSCodeCopilotEnvironment() {
@@ -3036,6 +3038,8 @@ var init_base_provider = __esm({
3036
3038
  resolved = true;
3037
3039
  cleanup();
3038
3040
  resolve12(value);
3041
+ } else {
3042
+ cleanup();
3039
3043
  }
3040
3044
  };
3041
3045
  let sanitizedCommand;
@@ -3267,6 +3271,10 @@ var init_base_provider = __esm({
3267
3271
  const latency = Date.now() - startTime;
3268
3272
  this.updateMetrics(response, latency);
3269
3273
  this.health.consecutiveFailures = 0;
3274
+ if (this.circuitBreakerRecoveryTimeout) {
3275
+ clearTimeout(this.circuitBreakerRecoveryTimeout);
3276
+ this.circuitBreakerRecoveryTimeout = null;
3277
+ }
3270
3278
  try {
3271
3279
  const cost = await this.calculateCostFromTokens(
3272
3280
  response.tokensUsed,
@@ -9210,39 +9218,47 @@ function validateConfig(config) {
9210
9218
  errors.push(`Execution: defaultTimeout must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms (1 hour max)`);
9211
9219
  }
9212
9220
  }
9213
- if (!isPositiveInteger(config.execution.retry.maxAttempts)) {
9214
- errors.push("Execution: retry.maxAttempts must be a positive integer");
9215
- } else if (config.execution.retry.maxAttempts > 10) {
9216
- errors.push("Execution: retry.maxAttempts must be <= 10 (reasonable retry limit)");
9217
- }
9218
- if (!isNonNegativeInteger(config.execution.retry.initialDelay)) {
9219
- errors.push("Execution: retry.initialDelay must be a non-negative integer");
9220
- } else if (config.execution.retry.initialDelay > VALIDATION_LIMITS.MAX_TIMEOUT) {
9221
- errors.push(`Execution: retry.initialDelay must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9222
- }
9223
- if (!isPositiveInteger(config.execution.retry.maxDelay)) {
9224
- errors.push("Execution: retry.maxDelay must be a positive integer");
9221
+ if (!config.execution.retry || typeof config.execution.retry !== "object") {
9222
+ errors.push("Execution: retry configuration block is required");
9225
9223
  } else {
9226
- if (config.execution.retry.maxDelay < config.execution.retry.initialDelay) {
9227
- errors.push("Execution: retry.maxDelay must be >= initialDelay");
9224
+ if (!isPositiveInteger(config.execution.retry.maxAttempts)) {
9225
+ errors.push("Execution: retry.maxAttempts must be a positive integer");
9226
+ } else if (config.execution.retry.maxAttempts > 10) {
9227
+ errors.push("Execution: retry.maxAttempts must be <= 10 (reasonable retry limit)");
9228
+ }
9229
+ if (!isNonNegativeInteger(config.execution.retry.initialDelay)) {
9230
+ errors.push("Execution: retry.initialDelay must be a non-negative integer");
9231
+ } else if (config.execution.retry.initialDelay > VALIDATION_LIMITS.MAX_TIMEOUT) {
9232
+ errors.push(`Execution: retry.initialDelay must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9233
+ }
9234
+ if (!isPositiveInteger(config.execution.retry.maxDelay)) {
9235
+ errors.push("Execution: retry.maxDelay must be a positive integer");
9236
+ } else {
9237
+ if (config.execution.retry.maxDelay < config.execution.retry.initialDelay) {
9238
+ errors.push("Execution: retry.maxDelay must be >= initialDelay");
9239
+ }
9240
+ if (config.execution.retry.maxDelay > VALIDATION_LIMITS.MAX_TIMEOUT) {
9241
+ errors.push(`Execution: retry.maxDelay must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9242
+ }
9228
9243
  }
9229
- if (config.execution.retry.maxDelay > VALIDATION_LIMITS.MAX_TIMEOUT) {
9230
- errors.push(`Execution: retry.maxDelay must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9244
+ if (typeof config.execution.retry.backoffFactor !== "number" || config.execution.retry.backoffFactor < VALIDATION_LIMITS.MIN_BACKOFF_FACTOR) {
9245
+ errors.push(`Execution: retry.backoffFactor must be >= ${VALIDATION_LIMITS.MIN_BACKOFF_FACTOR}`);
9246
+ } else if (config.execution.retry.backoffFactor > VALIDATION_LIMITS.MAX_BACKOFF_FACTOR) {
9247
+ errors.push(`Execution: retry.backoffFactor must be <= ${VALIDATION_LIMITS.MAX_BACKOFF_FACTOR}`);
9231
9248
  }
9232
9249
  }
9233
- if (typeof config.execution.retry.backoffFactor !== "number" || config.execution.retry.backoffFactor < VALIDATION_LIMITS.MIN_BACKOFF_FACTOR) {
9234
- errors.push(`Execution: retry.backoffFactor must be >= ${VALIDATION_LIMITS.MIN_BACKOFF_FACTOR}`);
9235
- } else if (config.execution.retry.backoffFactor > VALIDATION_LIMITS.MAX_BACKOFF_FACTOR) {
9236
- errors.push(`Execution: retry.backoffFactor must be <= ${VALIDATION_LIMITS.MAX_BACKOFF_FACTOR}`);
9237
- }
9238
- if (!isPositiveInteger(config.execution.provider.maxWaitMs)) {
9239
- errors.push("Execution: provider.maxWaitMs must be a positive integer");
9250
+ if (!config.execution.provider || typeof config.execution.provider !== "object") {
9251
+ errors.push("Execution: provider configuration block is required");
9240
9252
  } else {
9241
- if (config.execution.provider.maxWaitMs < VALIDATION_LIMITS.MIN_TIMEOUT) {
9242
- errors.push(`Execution: provider.maxWaitMs must be >= ${VALIDATION_LIMITS.MIN_TIMEOUT}ms`);
9243
- }
9244
- if (config.execution.provider.maxWaitMs > VALIDATION_LIMITS.MAX_TIMEOUT) {
9245
- errors.push(`Execution: provider.maxWaitMs must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9253
+ if (!isPositiveInteger(config.execution.provider.maxWaitMs)) {
9254
+ errors.push("Execution: provider.maxWaitMs must be a positive integer");
9255
+ } else {
9256
+ if (config.execution.provider.maxWaitMs < VALIDATION_LIMITS.MIN_TIMEOUT) {
9257
+ errors.push(`Execution: provider.maxWaitMs must be >= ${VALIDATION_LIMITS.MIN_TIMEOUT}ms`);
9258
+ }
9259
+ if (config.execution.provider.maxWaitMs > VALIDATION_LIMITS.MAX_TIMEOUT) {
9260
+ errors.push(`Execution: provider.maxWaitMs must be <= ${VALIDATION_LIMITS.MAX_TIMEOUT}ms`);
9261
+ }
9246
9262
  }
9247
9263
  }
9248
9264
  if (config.execution.maxConcurrentAgents !== void 0) {
@@ -9993,6 +10009,12 @@ function validateProvider(name, provider) {
9993
10009
  message: "priority must be a number",
9994
10010
  value: provider.priority
9995
10011
  });
10012
+ } else if (!Number.isInteger(provider.priority)) {
10013
+ errors.push({
10014
+ path: `${basePath}.priority`,
10015
+ message: "priority must be an integer (no fractional values)",
10016
+ value: provider.priority
10017
+ });
9996
10018
  } else if (provider.priority < 1) {
9997
10019
  errors.push({
9998
10020
  path: `${basePath}.priority`,
@@ -10006,6 +10028,12 @@ function validateProvider(name, provider) {
10006
10028
  message: "timeout must be a number",
10007
10029
  value: provider.timeout
10008
10030
  });
10031
+ } else if (!Number.isInteger(provider.timeout)) {
10032
+ errors.push({
10033
+ path: `${basePath}.timeout`,
10034
+ message: "timeout must be an integer (no fractional values)",
10035
+ value: provider.timeout
10036
+ });
10009
10037
  } else if (provider.timeout < 1e3) {
10010
10038
  errors.push({
10011
10039
  path: `${basePath}.timeout`,
@@ -13957,6 +13985,10 @@ var RouterTraceLogger = class {
13957
13985
  enabled;
13958
13986
  autoFlush;
13959
13987
  streamInitializing = false;
13988
+ // FIXED (v6.5.12 Bug #123): Store event handler references for cleanup
13989
+ exitHandler = () => this.close();
13990
+ sigintHandler = () => this.close();
13991
+ sigtermHandler = () => this.close();
13960
13992
  constructor(options) {
13961
13993
  this.traceFile = join(options.workspacePath, ".automatosx/logs/router.trace.jsonl");
13962
13994
  this.enabled = options.enabled ?? true;
@@ -13967,9 +13999,9 @@ var RouterTraceLogger = class {
13967
13999
  mkdirSync(logDir, { recursive: true });
13968
14000
  }
13969
14001
  }
13970
- process.on("exit", () => this.close());
13971
- process.on("SIGINT", () => this.close());
13972
- process.on("SIGTERM", () => this.close());
14002
+ process.on("exit", this.exitHandler);
14003
+ process.on("SIGINT", this.sigintHandler);
14004
+ process.on("SIGTERM", this.sigtermHandler);
13973
14005
  }
13974
14006
  /**
13975
14007
  * Log a trace event
@@ -14151,8 +14183,15 @@ var RouterTraceLogger = class {
14151
14183
  }
14152
14184
  /**
14153
14185
  * Flush and close the trace file
14186
+ *
14187
+ * FIXED (v6.5.12 Bug #123): Remove process event listeners to prevent memory leak
14188
+ * Without cleanup, each RouterTraceLogger instance leaves 3 event listeners attached
14189
+ * to the process object, preventing garbage collection.
14154
14190
  */
14155
14191
  close() {
14192
+ process.removeListener("exit", this.exitHandler);
14193
+ process.removeListener("SIGINT", this.sigintHandler);
14194
+ process.removeListener("SIGTERM", this.sigtermHandler);
14156
14195
  if (this.stream) {
14157
14196
  this.stream.end();
14158
14197
  this.stream = void 0;
@@ -15172,7 +15211,7 @@ var Router = class {
15172
15211
  const reason = request.spec?.policy ? "policy-based selection" : "priority-based selection";
15173
15212
  const specContext = request.spec ? {
15174
15213
  specId: request.spec.metadata?.id,
15175
- taskId: request.spec.taskId
15214
+ taskId: request.spec?.taskId
15176
15215
  } : void 0;
15177
15216
  this.tracer.logSelection(candidateNames, provider.name, reason, void 0, specContext);
15178
15217
  }
@@ -15888,6 +15927,7 @@ var MemoryManager = class _MemoryManager {
15888
15927
  accessCount: 0
15889
15928
  };
15890
15929
  } catch (error) {
15930
+ if (error instanceof MemoryError) throw error;
15891
15931
  throw new MemoryError(
15892
15932
  `Failed to add memory entry: ${error.message}`,
15893
15933
  "DATABASE_ERROR"
@@ -17209,16 +17249,17 @@ var SessionManager = class _SessionManager {
17209
17249
  if (session.metadata.tasks.length > this.MAX_TASKS_PER_SESSION) {
17210
17250
  const completedTasks = session.metadata.tasks.filter((t) => t.status === "completed" || t.status === "failed");
17211
17251
  const runningTasks = session.metadata.tasks.filter((t) => t.status === "running" || t.status === "pending");
17212
- const tasksToKeep = this.MAX_TASKS_PER_SESSION - runningTasks.length;
17252
+ const oldTaskCount = session.metadata.tasks.length;
17253
+ const tasksToKeep = Math.max(0, this.MAX_TASKS_PER_SESSION - runningTasks.length);
17213
17254
  const recentCompleted = completedTasks.sort((a, b) => {
17214
17255
  const aTime = a.completedAt || a.startedAt;
17215
17256
  const bTime = b.completedAt || b.startedAt;
17216
17257
  return bTime.localeCompare(aTime);
17217
- }).slice(0, Math.max(0, tasksToKeep));
17258
+ }).slice(0, tasksToKeep);
17218
17259
  session.metadata.tasks = [...runningTasks, ...recentCompleted];
17219
17260
  logger.debug("Cleaned up old tasks", {
17220
17261
  sessionId,
17221
- removed: session.metadata.tasks.length - (runningTasks.length + recentCompleted.length),
17262
+ removed: oldTaskCount - session.metadata.tasks.length,
17222
17263
  remaining: session.metadata.tasks.length
17223
17264
  });
17224
17265
  }
@@ -17655,6 +17696,11 @@ var SessionManager = class _SessionManager {
17655
17696
  throw renameError;
17656
17697
  }
17657
17698
  } catch (error) {
17699
+ const tempPath = `${this.persistencePath}.tmp`;
17700
+ try {
17701
+ await unlink(tempPath);
17702
+ } catch (unlinkError) {
17703
+ }
17658
17704
  logger.error("Failed to save sessions to persistence", {
17659
17705
  path: normalizePath(this.persistencePath),
17660
17706
  error: error.message
@@ -19747,13 +19793,15 @@ var DelegationParser = class {
19747
19793
  const lastNewline = before.lastIndexOf("\n");
19748
19794
  if (lastDoubleQuote > lastNewline) {
19749
19795
  const closingDoubleQuote = after.indexOf('"');
19750
- if (closingDoubleQuote !== -1 && closingDoubleQuote < after.indexOf("\n\n")) {
19796
+ const blankLinePos = after.indexOf("\n\n");
19797
+ if (closingDoubleQuote !== -1 && (blankLinePos === -1 || closingDoubleQuote < blankLinePos)) {
19751
19798
  return true;
19752
19799
  }
19753
19800
  }
19754
19801
  if (lastSingleQuote > lastNewline) {
19755
19802
  const closingSingleQuote = after.indexOf("'");
19756
- if (closingSingleQuote !== -1 && closingSingleQuote < after.indexOf("\n\n")) {
19803
+ const blankLinePos = after.indexOf("\n\n");
19804
+ if (closingSingleQuote !== -1 && (blankLinePos === -1 || closingSingleQuote < blankLinePos)) {
19757
19805
  return true;
19758
19806
  }
19759
19807
  }
@@ -19792,9 +19840,11 @@ var DelegationParser = class {
19792
19840
  if (testCodePatterns.test(before) || testCodePatterns.test(after)) {
19793
19841
  return true;
19794
19842
  }
19795
- const combinedContext = before.slice(-100) + after.slice(0, 100);
19843
+ const beforeSlice = before.length > 0 ? before.slice(-Math.min(100, before.length)) : "";
19844
+ const afterSlice = after.length > 0 ? after.slice(0, Math.min(100, after.length)) : "";
19845
+ const combinedContext = beforeSlice + afterSlice;
19796
19846
  const stringLiteralPattern = /['"`][^'"`]{0,100}@[a-zA-Z0-9-_]+[^'"`]{0,100}['"`]/;
19797
- if (stringLiteralPattern.test(combinedContext)) {
19847
+ if (combinedContext.length > 0 && stringLiteralPattern.test(combinedContext)) {
19798
19848
  return true;
19799
19849
  }
19800
19850
  return false;
@@ -25004,6 +25054,21 @@ var ProgressChannel = class {
25004
25054
  this.processing = false;
25005
25055
  }
25006
25056
  }
25057
+ /**
25058
+ * Cleanup channel and clear pending timers
25059
+ *
25060
+ * FIXED (v6.5.12 Bug #122): Added cleanup method to prevent timer leaks
25061
+ * Clears pending timeout and removes all listeners to allow proper garbage collection.
25062
+ */
25063
+ destroy() {
25064
+ if (this.processQueueTimeout) {
25065
+ clearTimeout(this.processQueueTimeout);
25066
+ this.processQueueTimeout = void 0;
25067
+ }
25068
+ this.listeners.clear();
25069
+ this.eventQueue = [];
25070
+ this.processing = false;
25071
+ }
25007
25072
  };
25008
25073
 
25009
25074
  // src/cli/renderers/progress-renderer.ts
@@ -27881,7 +27946,8 @@ async function getLatestVersion() {
27881
27946
  return stdout.trim();
27882
27947
  }
27883
27948
  function isNewer(a, b) {
27884
- const parseVersion = (v) => v.split(".").map(Number);
27949
+ const stripPrerelease = (v) => v.split("-")[0] || v;
27950
+ const parseVersion = (v) => stripPrerelease(v).split(".").map(Number);
27885
27951
  const [aMajor = 0, aMinor = 0, aPatch = 0] = parseVersion(a);
27886
27952
  const [bMajor = 0, bMinor = 0, bPatch = 0] = parseVersion(b);
27887
27953
  if (aMajor !== bMajor) return aMajor > bMajor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defai.digital/automatosx",
3
- "version": "6.5.11",
3
+ "version": "6.5.12",
4
4
  "description": "AI Agent Orchestration Platform",
5
5
  "type": "module",
6
6
  "publishConfig": {