archondev 2.19.36 → 2.19.38

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.
@@ -4802,7 +4802,8 @@ function collectAllowedPathsFromArchitecture(schema) {
4802
4802
  return Array.from(new Set(paths));
4803
4803
  }
4804
4804
  async function attemptPathScopeAutoRecovery(atom, cwd, parseSchema, options) {
4805
- if (!options.nonTerminating || options.autoRecoverAttempted) {
4805
+ const recoveryDepth = options.autoRecoverDepth ?? 0;
4806
+ if (!options.nonTerminating || recoveryDepth >= 2) {
4806
4807
  return false;
4807
4808
  }
4808
4809
  const allowedPaths = collectAllowedPathsFromArchitecture(parseSchema);
@@ -4811,27 +4812,49 @@ async function attemptPathScopeAutoRecovery(atom, cwd, parseSchema, options) {
4811
4812
  }
4812
4813
  const { listLocalAtoms, plan } = await import("./plan-S5EULQKJ.js");
4813
4814
  const before = await listLocalAtoms();
4814
- const beforeIds = new Set(before.map((entry) => entry.externalId));
4815
+ const recoveryStartedAt = Date.now();
4815
4816
  const recoverySource = atom.description ?? atom.title;
4816
- const scopedRequest = `${recoverySource}
4817
+ const normalizedAllowedPaths = allowedPaths.map((path) => path.trim()).filter(Boolean);
4818
+ const forcedBasePath = normalizedAllowedPaths.map((path) => path.replace(/\/\*\*$/, "").replace(/\*.*$/, "")).find((path) => path.length > 0 && path !== ".");
4819
+ const strictScopeLine = normalizedAllowedPaths.join(", ");
4820
+ const scopedRequest = recoveryDepth === 0 ? `${recoverySource}
4817
4821
 
4818
4822
  Constraints:
4819
- - Only modify files within these allowed architecture paths: ${allowedPaths.join(", ")}
4820
- - If required files are outside scope, first propose the minimum architecture path update needed.`;
4821
- console.log(chalk2.dim("\nAuto-recovery: re-planning with allowed-path scope constraints...\n"));
4823
+ - Only modify files within these allowed architecture paths: ${strictScopeLine}
4824
+ - Before implementation, choose exact target file paths and ensure every path matches the allowed scope.
4825
+ - If required files are outside scope, first propose the minimum architecture path update needed.` : `${recoverySource}
4826
+
4827
+ Hard Constraints:
4828
+ - EVERY output file path MUST start with: ${forcedBasePath ?? normalizedAllowedPaths[0]}
4829
+ - Do not create files outside this base path.
4830
+ - If this cannot satisfy the task, return a minimal architecture path update proposal instead of writing out-of-scope files.`;
4831
+ const phaseLabel = recoveryDepth === 0 ? "scope-constrained retry" : "forced-base-path retry";
4832
+ console.log(chalk2.dim(`
4833
+ Auto-recovery: re-planning with ${phaseLabel}...
4834
+ `));
4822
4835
  await plan(scopedRequest, { conversational: true });
4823
4836
  const after = await listLocalAtoms();
4824
- const replacement = after.filter((entry) => !beforeIds.has(entry.externalId) && entry.status === "READY").sort((a, b) => {
4837
+ const byMostRecent = (a, b) => {
4825
4838
  const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
4826
4839
  const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
4827
4840
  return bTime - aTime;
4828
- })[0];
4841
+ };
4842
+ let replacement = after.filter((entry) => {
4843
+ if (entry.status !== "READY") return false;
4844
+ if (entry.externalId === atom.externalId) return false;
4845
+ const updatedAt = new Date(String(entry.updatedAt ?? entry.createdAt ?? "")).getTime() || 0;
4846
+ return updatedAt >= recoveryStartedAt - 2e3;
4847
+ }).sort(byMostRecent)[0];
4848
+ if (!replacement) {
4849
+ replacement = after.filter((entry) => entry.status === "READY" && entry.externalId !== atom.externalId).sort(byMostRecent)[0];
4850
+ }
4829
4851
  if (!replacement) {
4852
+ console.log(chalk2.yellow("Auto-recovery could not find a replacement READY atom to retry."));
4830
4853
  return false;
4831
4854
  }
4832
4855
  console.log(chalk2.dim(`Auto-recovery: retrying with ${replacement.externalId}...
4833
4856
  `));
4834
- await execute(replacement.externalId, { ...options, autoRecoverAttempted: true, nonTerminating: true });
4857
+ await execute(replacement.externalId, { ...options, autoRecoverDepth: recoveryDepth + 1, nonTerminating: true });
4835
4858
  return true;
4836
4859
  }
4837
4860
  function createPrompt() {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-B5OHK54H.js";
3
+ } from "./chunk-6RDZF7BB.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
5
  import "./chunk-LGWUWEEJ.js";
6
6
  import "./chunk-WGLVDEZC.js";
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ import {
56
56
  EnvironmentConfigLoader,
57
57
  EnvironmentValidator,
58
58
  execute
59
- } from "./chunk-B5OHK54H.js";
59
+ } from "./chunk-6RDZF7BB.js";
60
60
  import {
61
61
  cloudCancel,
62
62
  cloudLogs,
@@ -4061,7 +4061,7 @@ async function continueWithCurrentTask(cwd) {
4061
4061
  console.log(chalk5.dim(`
4062
4062
  Continuing with ${nextAtom.externalId}...
4063
4063
  `));
4064
- const { execute: execute2 } = await import("./execute-QCEAXLVH.js");
4064
+ const { execute: execute2 } = await import("./execute-I7YHYKPQ.js");
4065
4065
  await execute2(nextAtom.externalId, { nonTerminating: true });
4066
4066
  }
4067
4067
  async function replanLatestBlockedAtom(cwd) {
@@ -4259,6 +4259,7 @@ async function withAllowedPathScope(cwd, request) {
4259
4259
 
4260
4260
  Constraints:
4261
4261
  - Only modify files within these allowed architecture paths: ${allowedPaths.join(", ")}
4262
+ - Before writing code/content, choose exact output file paths and ensure each one stays inside allowed scope.
4262
4263
  - If required files are outside this scope, propose the minimum architecture path update first.`;
4263
4264
  }
4264
4265
  async function planTask() {
@@ -4356,7 +4357,7 @@ async function executeNext() {
4356
4357
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
4357
4358
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
4358
4359
  if (targetId) {
4359
- const { execute: execute2 } = await import("./execute-QCEAXLVH.js");
4360
+ const { execute: execute2 } = await import("./execute-I7YHYKPQ.js");
4360
4361
  await execute2(targetId, {});
4361
4362
  } else {
4362
4363
  console.log(chalk5.yellow("No atom to execute."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.36",
3
+ "version": "2.19.38",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {