archondev 2.19.34 → 2.19.37
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.
|
@@ -4794,6 +4794,56 @@ function extractGovernanceViolations(errorMessage) {
|
|
|
4794
4794
|
if (!errorMessage.startsWith(prefix)) return [];
|
|
4795
4795
|
return errorMessage.slice(prefix.length).split(",").map((item) => item.trim()).filter(Boolean);
|
|
4796
4796
|
}
|
|
4797
|
+
function isPathScopeGovernanceViolation(errorMessage) {
|
|
4798
|
+
return extractGovernanceViolations(errorMessage).some((violation) => violation.toLowerCase().includes("outside the allowed paths"));
|
|
4799
|
+
}
|
|
4800
|
+
function collectAllowedPathsFromArchitecture(schema) {
|
|
4801
|
+
const paths = (schema.components ?? []).flatMap((component) => component.paths ?? []).filter((path) => typeof path === "string" && path.trim().length > 0);
|
|
4802
|
+
return Array.from(new Set(paths));
|
|
4803
|
+
}
|
|
4804
|
+
async function attemptPathScopeAutoRecovery(atom, cwd, parseSchema, options) {
|
|
4805
|
+
if (!options.nonTerminating || options.autoRecoverAttempted) {
|
|
4806
|
+
return false;
|
|
4807
|
+
}
|
|
4808
|
+
const allowedPaths = collectAllowedPathsFromArchitecture(parseSchema);
|
|
4809
|
+
if (allowedPaths.length === 0) {
|
|
4810
|
+
return false;
|
|
4811
|
+
}
|
|
4812
|
+
const { listLocalAtoms, plan } = await import("./plan-S5EULQKJ.js");
|
|
4813
|
+
const before = await listLocalAtoms();
|
|
4814
|
+
const recoveryStartedAt = Date.now();
|
|
4815
|
+
const recoverySource = atom.description ?? atom.title;
|
|
4816
|
+
const scopedRequest = `${recoverySource}
|
|
4817
|
+
|
|
4818
|
+
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"));
|
|
4822
|
+
await plan(scopedRequest, { conversational: true });
|
|
4823
|
+
const after = await listLocalAtoms();
|
|
4824
|
+
const byMostRecent = (a, b) => {
|
|
4825
|
+
const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
|
|
4826
|
+
const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
|
|
4827
|
+
return bTime - aTime;
|
|
4828
|
+
};
|
|
4829
|
+
let replacement = after.filter((entry) => {
|
|
4830
|
+
if (entry.status !== "READY") return false;
|
|
4831
|
+
if (entry.externalId === atom.externalId) return false;
|
|
4832
|
+
const updatedAt = new Date(String(entry.updatedAt ?? entry.createdAt ?? "")).getTime() || 0;
|
|
4833
|
+
return updatedAt >= recoveryStartedAt - 2e3;
|
|
4834
|
+
}).sort(byMostRecent)[0];
|
|
4835
|
+
if (!replacement) {
|
|
4836
|
+
replacement = after.filter((entry) => entry.status === "READY" && entry.externalId !== atom.externalId).sort(byMostRecent)[0];
|
|
4837
|
+
}
|
|
4838
|
+
if (!replacement) {
|
|
4839
|
+
console.log(chalk2.yellow("Auto-recovery could not find a replacement READY atom to retry."));
|
|
4840
|
+
return false;
|
|
4841
|
+
}
|
|
4842
|
+
console.log(chalk2.dim(`Auto-recovery: retrying with ${replacement.externalId}...
|
|
4843
|
+
`));
|
|
4844
|
+
await execute(replacement.externalId, { ...options, autoRecoverAttempted: true, nonTerminating: true });
|
|
4845
|
+
return true;
|
|
4846
|
+
}
|
|
4797
4847
|
function createPrompt() {
|
|
4798
4848
|
const rl = createInterface({
|
|
4799
4849
|
input: process.stdin,
|
|
@@ -5068,7 +5118,23 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
5068
5118
|
errorMessage: executionResult.errorMessage
|
|
5069
5119
|
});
|
|
5070
5120
|
if (isGovernanceViolation(executionResult.errorMessage)) {
|
|
5071
|
-
|
|
5121
|
+
const pathScopeViolation = isPathScopeGovernanceViolation(executionResult.errorMessage);
|
|
5122
|
+
if (pathScopeViolation) {
|
|
5123
|
+
const recovered = await attemptPathScopeAutoRecovery(
|
|
5124
|
+
atom,
|
|
5125
|
+
cwd,
|
|
5126
|
+
parseResult.schema,
|
|
5127
|
+
options
|
|
5128
|
+
);
|
|
5129
|
+
if (recovered) {
|
|
5130
|
+
return;
|
|
5131
|
+
}
|
|
5132
|
+
}
|
|
5133
|
+
printExecuteNextActions(
|
|
5134
|
+
atom.externalId,
|
|
5135
|
+
false,
|
|
5136
|
+
pathScopeViolation ? "governance_path" : "generic"
|
|
5137
|
+
);
|
|
5072
5138
|
return;
|
|
5073
5139
|
}
|
|
5074
5140
|
return fail();
|
|
@@ -5183,12 +5249,18 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5183
5249
|
prompt.close();
|
|
5184
5250
|
}
|
|
5185
5251
|
}
|
|
5186
|
-
function printExecuteNextActions(atomExternalId, success) {
|
|
5252
|
+
function printExecuteNextActions(atomExternalId, success, context = "generic") {
|
|
5187
5253
|
console.log();
|
|
5188
5254
|
console.log(chalk2.bold("Next best action:"));
|
|
5189
5255
|
if (success) {
|
|
5190
5256
|
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon list")} to select your next atom.`));
|
|
5191
5257
|
} else {
|
|
5258
|
+
if (context === "governance_path") {
|
|
5259
|
+
console.log(chalk2.dim(` \u2022 In chat, say ${chalk2.cyan('"adjust this atom to allowed paths"')} to re-scope automatically.`));
|
|
5260
|
+
console.log(chalk2.dim(` \u2022 Then say ${chalk2.cyan('"continue"')} to execute the re-scoped atom.`));
|
|
5261
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect the blocked atom.`));
|
|
5262
|
+
return;
|
|
5263
|
+
}
|
|
5192
5264
|
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect this atom.`));
|
|
5193
5265
|
}
|
|
5194
5266
|
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon credits")} to verify balance/tier.`));
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
EnvironmentConfigLoader,
|
|
57
57
|
EnvironmentValidator,
|
|
58
58
|
execute
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-KZP4GK6K.js";
|
|
60
60
|
import {
|
|
61
61
|
cloudCancel,
|
|
62
62
|
cloudLogs,
|
|
@@ -3683,7 +3683,7 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3683
3683
|
pendingAnalysisToAtomRequest = null;
|
|
3684
3684
|
console.log(chalk5.dim("\n> Great. Creating a governed task from the approved analysis plan.\n"));
|
|
3685
3685
|
const { plan: plan3 } = await import("./plan-S5EULQKJ.js");
|
|
3686
|
-
await plan3(request, { conversational: true });
|
|
3686
|
+
await plan3(await withAllowedPathScope(cwd, request), { conversational: true });
|
|
3687
3687
|
console.log(chalk5.dim("\n> Starting implementation now...\n"));
|
|
3688
3688
|
await continueWithCurrentTask(cwd);
|
|
3689
3689
|
return true;
|
|
@@ -3724,7 +3724,7 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3724
3724
|
}
|
|
3725
3725
|
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3726
3726
|
const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
|
|
3727
|
-
await plan2(input, { conversational: true });
|
|
3727
|
+
await plan2(await withAllowedPathScope(cwd, input), { conversational: true });
|
|
3728
3728
|
if (shouldAutoExecuteAfterPlanning(input)) {
|
|
3729
3729
|
await continueWithCurrentTask(cwd);
|
|
3730
3730
|
return true;
|
|
@@ -3886,7 +3886,7 @@ async function applyApprovedProposal(cwd) {
|
|
|
3886
3886
|
}
|
|
3887
3887
|
console.log(chalk5.dim("\n> Great. I will create the task from your approved request.\n"));
|
|
3888
3888
|
const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
|
|
3889
|
-
await plan2(approvedRequest, { conversational: true });
|
|
3889
|
+
await plan2(await withAllowedPathScope(cwd, approvedRequest), { conversational: true });
|
|
3890
3890
|
if (shouldAutoExecuteAfterPlanning(approvedRequest)) {
|
|
3891
3891
|
await continueWithCurrentTask(cwd);
|
|
3892
3892
|
return;
|
|
@@ -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-
|
|
4064
|
+
const { execute: execute2 } = await import("./execute-HXE6WQFQ.js");
|
|
4065
4065
|
await execute2(nextAtom.externalId, { nonTerminating: true });
|
|
4066
4066
|
}
|
|
4067
4067
|
async function replanLatestBlockedAtom(cwd) {
|
|
@@ -4172,7 +4172,7 @@ async function handleFreeformJourneyInput(cwd, input) {
|
|
|
4172
4172
|
if (state.hasArchitecture) {
|
|
4173
4173
|
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
4174
4174
|
const { plan: plan3 } = await import("./plan-S5EULQKJ.js");
|
|
4175
|
-
await plan3(freeform, { conversational: true });
|
|
4175
|
+
await plan3(await withAllowedPathScope(cwd, freeform), { conversational: true });
|
|
4176
4176
|
return true;
|
|
4177
4177
|
}
|
|
4178
4178
|
console.log(chalk5.dim("\n> Let me understand your project better...\n"));
|
|
@@ -4181,7 +4181,7 @@ async function handleFreeformJourneyInput(cwd, input) {
|
|
|
4181
4181
|
}
|
|
4182
4182
|
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
4183
4183
|
const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
|
|
4184
|
-
await plan2(freeform, { conversational: true });
|
|
4184
|
+
await plan2(await withAllowedPathScope(cwd, freeform), { conversational: true });
|
|
4185
4185
|
return true;
|
|
4186
4186
|
}
|
|
4187
4187
|
function extractActionableFollowUpFromExplore(input) {
|
|
@@ -4240,7 +4240,7 @@ async function handlePostExploreAction(cwd, request, options = {}) {
|
|
|
4240
4240
|
console.log(chalk5.dim("> Got it! Creating a task for this...\n"));
|
|
4241
4241
|
}
|
|
4242
4242
|
const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
|
|
4243
|
-
await plan2(request, { conversational: true });
|
|
4243
|
+
await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
|
|
4244
4244
|
if (options.agentMode) {
|
|
4245
4245
|
if (shouldAutoExecuteAfterPlanning(sourceInput)) {
|
|
4246
4246
|
await continueWithCurrentTask(cwd);
|
|
@@ -4250,6 +4250,17 @@ async function handlePostExploreAction(cwd, request, options = {}) {
|
|
|
4250
4250
|
console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
|
|
4251
4251
|
}
|
|
4252
4252
|
}
|
|
4253
|
+
async function withAllowedPathScope(cwd, request) {
|
|
4254
|
+
const allowedPaths = await listArchitecturePaths(cwd);
|
|
4255
|
+
if (allowedPaths.length === 0) {
|
|
4256
|
+
return request;
|
|
4257
|
+
}
|
|
4258
|
+
return `${request}
|
|
4259
|
+
|
|
4260
|
+
Constraints:
|
|
4261
|
+
- Only modify files within these allowed architecture paths: ${allowedPaths.join(", ")}
|
|
4262
|
+
- If required files are outside this scope, propose the minimum architecture path update first.`;
|
|
4263
|
+
}
|
|
4253
4264
|
async function planTask() {
|
|
4254
4265
|
const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
|
|
4255
4266
|
const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
|
|
@@ -4345,7 +4356,7 @@ async function executeNext() {
|
|
|
4345
4356
|
const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
|
|
4346
4357
|
const targetId = atomId.trim() || pendingAtoms[0]?.id;
|
|
4347
4358
|
if (targetId) {
|
|
4348
|
-
const { execute: execute2 } = await import("./execute-
|
|
4359
|
+
const { execute: execute2 } = await import("./execute-HXE6WQFQ.js");
|
|
4349
4360
|
await execute2(targetId, {});
|
|
4350
4361
|
} else {
|
|
4351
4362
|
console.log(chalk5.yellow("No atom to execute."));
|