archondev 2.19.33 → 2.19.36

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.
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadAtom
3
- } from "./chunk-Z6RH6DFP.js";
3
+ } from "./chunk-LGWUWEEJ.js";
4
4
 
5
5
  // src/cli/show.ts
6
6
  import chalk from "chalk";
@@ -7,7 +7,7 @@ import {
7
7
  UsageRecorder,
8
8
  handleInsufficientCreditsRecovery,
9
9
  loadAtom
10
- } from "./chunk-Z6RH6DFP.js";
10
+ } from "./chunk-LGWUWEEJ.js";
11
11
  import {
12
12
  transitionAtom
13
13
  } from "./chunk-WGLVDEZC.js";
@@ -4794,6 +4794,46 @@ 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 beforeIds = new Set(before.map((entry) => entry.externalId));
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 replacement = after.filter((entry) => !beforeIds.has(entry.externalId) && entry.status === "READY").sort((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
+ })[0];
4829
+ if (!replacement) {
4830
+ return false;
4831
+ }
4832
+ console.log(chalk2.dim(`Auto-recovery: retrying with ${replacement.externalId}...
4833
+ `));
4834
+ await execute(replacement.externalId, { ...options, autoRecoverAttempted: true, nonTerminating: true });
4835
+ return true;
4836
+ }
4797
4837
  function createPrompt() {
4798
4838
  const rl = createInterface({
4799
4839
  input: process.stdin,
@@ -4815,7 +4855,7 @@ async function execute(atomId, options) {
4815
4855
  process.exit(1);
4816
4856
  };
4817
4857
  if (options.parallel && options.parallel.length > 0) {
4818
- const { parallelExecute } = await import("./parallel-3EZP3X6S.js");
4858
+ const { parallelExecute } = await import("./parallel-N74S3MFF.js");
4819
4859
  const allAtomIds = [atomId, ...options.parallel];
4820
4860
  await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
4821
4861
  return;
@@ -5033,11 +5073,15 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
5033
5073
  console.log(chalk2.yellow("\n\u26A0\uFE0F Execution paused by governance guidance"));
5034
5074
  console.log(chalk2.dim("No changes were committed. Update the plan/path scope, then continue."));
5035
5075
  const violations = extractGovernanceViolations(executionResult.errorMessage);
5076
+ const pathScopeBlocked = violations.some((violation) => violation.toLowerCase().includes("outside the allowed paths"));
5036
5077
  if (violations.length > 0) {
5037
5078
  console.log(chalk2.yellow("\nGovernance guidance:"));
5038
5079
  for (const violation of violations) {
5039
5080
  console.log(chalk2.dim(` - ${violation}`));
5040
5081
  }
5082
+ if (pathScopeBlocked) {
5083
+ console.log(chalk2.dim('\nTry in chat: "adjust this atom to allowed paths", then "continue".'));
5084
+ }
5041
5085
  } else {
5042
5086
  console.log(chalk2.yellow(executionResult.errorMessage ?? "Architecture constraints were not satisfied."));
5043
5087
  }
@@ -5064,7 +5108,23 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
5064
5108
  errorMessage: executionResult.errorMessage
5065
5109
  });
5066
5110
  if (isGovernanceViolation(executionResult.errorMessage)) {
5067
- printExecuteNextActions(atom.externalId, false);
5111
+ const pathScopeViolation = isPathScopeGovernanceViolation(executionResult.errorMessage);
5112
+ if (pathScopeViolation) {
5113
+ const recovered = await attemptPathScopeAutoRecovery(
5114
+ atom,
5115
+ cwd,
5116
+ parseResult.schema,
5117
+ options
5118
+ );
5119
+ if (recovered) {
5120
+ return;
5121
+ }
5122
+ }
5123
+ printExecuteNextActions(
5124
+ atom.externalId,
5125
+ false,
5126
+ pathScopeViolation ? "governance_path" : "generic"
5127
+ );
5068
5128
  return;
5069
5129
  }
5070
5130
  return fail();
@@ -5179,12 +5239,18 @@ Running quality gates for ${targetEnvName}...`));
5179
5239
  prompt.close();
5180
5240
  }
5181
5241
  }
5182
- function printExecuteNextActions(atomExternalId, success) {
5242
+ function printExecuteNextActions(atomExternalId, success, context = "generic") {
5183
5243
  console.log();
5184
5244
  console.log(chalk2.bold("Next best action:"));
5185
5245
  if (success) {
5186
5246
  console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon list")} to select your next atom.`));
5187
5247
  } else {
5248
+ if (context === "governance_path") {
5249
+ console.log(chalk2.dim(` \u2022 In chat, say ${chalk2.cyan('"adjust this atom to allowed paths"')} to re-scope automatically.`));
5250
+ console.log(chalk2.dim(` \u2022 Then say ${chalk2.cyan('"continue"')} to execute the re-scoped atom.`));
5251
+ console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect the blocked atom.`));
5252
+ return;
5253
+ }
5188
5254
  console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect this atom.`));
5189
5255
  }
5190
5256
  console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon credits")} to verify balance/tier.`));
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-Z6RH6DFP.js";
9
+ } from "./chunk-LGWUWEEJ.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -1272,16 +1272,27 @@ function parseAtomDescription(description, options, extractedCriteria = []) {
1272
1272
  }
1273
1273
  function deriveTitle(description) {
1274
1274
  const dashIndex = description.indexOf(" - ");
1275
- if (dashIndex > 0) {
1276
- return description.slice(0, dashIndex).trim();
1277
- }
1275
+ let titleCandidate = dashIndex > 0 ? description.slice(0, dashIndex).trim() : (description.split("\n")[0] ?? description).trim() || description.trim();
1278
1276
  const bracketIndex = description.indexOf("[1]");
1279
- if (bracketIndex > 0) {
1280
- return description.slice(0, bracketIndex).trim();
1277
+ if (bracketIndex > 0 && bracketIndex < titleCandidate.length) {
1278
+ titleCandidate = description.slice(0, bracketIndex).trim();
1279
+ }
1280
+ titleCandidate = titleCandidate.replace(/^\s*(please|can you|could you)\s+/i, "").replace(/^\s*i (want|would like|need) you to\s+/i, "").replace(/^\s*i (want|would like|need) to\s+/i, "");
1281
+ const sentenceBreak = titleCandidate.search(/[.!?]/);
1282
+ if (sentenceBreak > 0) {
1283
+ titleCandidate = titleCandidate.slice(0, sentenceBreak).trim();
1284
+ }
1285
+ if (titleCandidate.length > 110) {
1286
+ const andBreak = titleCandidate.search(/\band\b/i);
1287
+ if (andBreak > 24) {
1288
+ titleCandidate = titleCandidate.slice(0, andBreak).trim();
1289
+ }
1290
+ }
1291
+ titleCandidate = titleCandidate.replace(/\s+/g, " ").trim();
1292
+ if (titleCandidate.length > 96) {
1293
+ titleCandidate = `${titleCandidate.slice(0, 93).trimEnd()}...`;
1281
1294
  }
1282
- const line = description.split("\n")[0] ?? description;
1283
- const trimmed = line.trim();
1284
- return trimmed.length > 0 ? trimmed : description.trim();
1295
+ return titleCandidate.length > 0 ? titleCandidate : "Task";
1285
1296
  }
1286
1297
  function extractNumberedRequirements(description) {
1287
1298
  const requirements = [];
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listLocalAtoms
3
- } from "./chunk-Z6RH6DFP.js";
3
+ } from "./chunk-LGWUWEEJ.js";
4
4
 
5
5
  // src/cli/list.ts
6
6
  import chalk from "chalk";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-UVW75BHP.js";
3
+ } from "./chunk-B5OHK54H.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
- import "./chunk-Z6RH6DFP.js";
5
+ import "./chunk-LGWUWEEJ.js";
6
6
  import "./chunk-WGLVDEZC.js";
7
7
  import "./chunk-3MZOEZUH.js";
8
8
  import "./chunk-F7R3QKHP.js";
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-6URKZ7NB.js";
14
14
  import {
15
15
  show
16
- } from "./chunk-LRNXR7DL.js";
16
+ } from "./chunk-4C6XR7WP.js";
17
17
  import {
18
18
  bugReport
19
19
  } from "./chunk-AHK2ITJX.js";
@@ -50,13 +50,13 @@ import {
50
50
  parallelRunWaves,
51
51
  parallelSchedule,
52
52
  parallelStatus
53
- } from "./chunk-MRCIJKWD.js";
53
+ } from "./chunk-CFEX6EWG.js";
54
54
  import {
55
55
  DependencyParser,
56
56
  EnvironmentConfigLoader,
57
57
  EnvironmentValidator,
58
58
  execute
59
- } from "./chunk-UVW75BHP.js";
59
+ } from "./chunk-B5OHK54H.js";
60
60
  import {
61
61
  cloudCancel,
62
62
  cloudLogs,
@@ -64,12 +64,12 @@ import {
64
64
  } from "./chunk-EBHHIUCB.js";
65
65
  import {
66
66
  list
67
- } from "./chunk-6ADNSWJ3.js";
67
+ } from "./chunk-Y2QXZ2UR.js";
68
68
  import {
69
69
  listLocalAtoms,
70
70
  loadAtom,
71
71
  plan
72
- } from "./chunk-Z6RH6DFP.js";
72
+ } from "./chunk-LGWUWEEJ.js";
73
73
  import "./chunk-WGLVDEZC.js";
74
74
  import "./chunk-3MZOEZUH.js";
75
75
  import {
@@ -3253,7 +3253,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
3253
3253
  case "1": {
3254
3254
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3255
3255
  if (description.trim()) {
3256
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3256
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
3257
3257
  await plan2(description, { conversational: true });
3258
3258
  }
3259
3259
  await showMainMenu();
@@ -3498,7 +3498,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3498
3498
  const hintedTask = initialTaskHint?.trim() ?? "";
3499
3499
  if (hintedTask) {
3500
3500
  console.log(chalk5.dim("Using your request above as the first task.\n"));
3501
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3501
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
3502
3502
  await plan2(hintedTask, { conversational: true });
3503
3503
  return;
3504
3504
  }
@@ -3523,7 +3523,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3523
3523
  description = continueAnswer.trim();
3524
3524
  }
3525
3525
  if (description.trim()) {
3526
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3526
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
3527
3527
  await plan2(description, { conversational: true });
3528
3528
  }
3529
3529
  }
@@ -3682,10 +3682,10 @@ async function handleAgentConversationInput(cwd, input) {
3682
3682
  const request = pendingAnalysisToAtomRequest;
3683
3683
  pendingAnalysisToAtomRequest = null;
3684
3684
  console.log(chalk5.dim("\n> Great. Creating a governed task from the approved analysis plan.\n"));
3685
- const { plan: plan3 } = await import("./plan-RHDFDSZE.js");
3686
- await plan3(request, { conversational: true });
3687
- await showLatestPlannedAtom(cwd);
3688
- console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
3685
+ const { plan: plan3 } = await import("./plan-S5EULQKJ.js");
3686
+ await plan3(await withAllowedPathScope(cwd, request), { conversational: true });
3687
+ console.log(chalk5.dim("\n> Starting implementation now...\n"));
3688
+ await continueWithCurrentTask(cwd);
3689
3689
  return true;
3690
3690
  }
3691
3691
  if (pendingProposalRequest && isPlanApprovalDirective(normalized)) {
@@ -3696,6 +3696,14 @@ async function handleAgentConversationInput(cwd, input) {
3696
3696
  await continueWithCurrentTask(cwd);
3697
3697
  return true;
3698
3698
  }
3699
+ if (isContinuationDirective(normalized)) {
3700
+ await continueWithCurrentTask(cwd);
3701
+ return true;
3702
+ }
3703
+ if (isRescopeBlockedDirective(normalized)) {
3704
+ await replanLatestBlockedAtom(cwd);
3705
+ return true;
3706
+ }
3699
3707
  if (isReferenceToPreviousRequest(normalized)) {
3700
3708
  await showLatestPlannedAtom(cwd);
3701
3709
  return true;
@@ -3715,8 +3723,8 @@ async function handleAgentConversationInput(cwd, input) {
3715
3723
  return true;
3716
3724
  }
3717
3725
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
3718
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3719
- await plan2(input, { conversational: true });
3726
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
3727
+ await plan2(await withAllowedPathScope(cwd, input), { conversational: true });
3720
3728
  if (shouldAutoExecuteAfterPlanning(input)) {
3721
3729
  await continueWithCurrentTask(cwd);
3722
3730
  return true;
@@ -3762,7 +3770,7 @@ async function showProposalForApproval(input) {
3762
3770
  }
3763
3771
  }
3764
3772
  async function showLatestPlannedAtom(cwd) {
3765
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
3773
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-S5EULQKJ.js");
3766
3774
  const atoms = await listLocalAtoms2();
3767
3775
  if (atoms.length === 0) {
3768
3776
  console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
@@ -3780,9 +3788,13 @@ async function showLatestPlannedAtom(cwd) {
3780
3788
  console.log(chalk5.dim(`
3781
3789
  Showing latest planned atom (${latest.externalId})...
3782
3790
  `));
3783
- const { show: show2 } = await import("./show-7A3FACN6.js");
3791
+ const { show: show2 } = await import("./show-DYDXCREZ.js");
3784
3792
  await show2(latest.externalId);
3785
3793
  }
3794
+ function isContinuationDirective(input) {
3795
+ const normalized = normalizeDirectiveInput(input);
3796
+ return normalized === "continue" || normalized === "go on" || normalized === "go ahead" || normalized === "next" || normalized === "proceed" || normalized === "do it" || normalized === "keep going" || normalized === "move forward";
3797
+ }
3786
3798
  function isPlanApprovalDirective(input) {
3787
3799
  const normalized = normalizeDirectiveInput(input);
3788
3800
  if (!normalized) return false;
@@ -3851,6 +3863,10 @@ function isCreateAtomDirective(input) {
3851
3863
  if (directCreate.has(normalized)) return true;
3852
3864
  return /\b(create|save|make|turn)\b/.test(normalized) && /\b(atom|task|plan|this|it)\b/.test(normalized);
3853
3865
  }
3866
+ function isRescopeBlockedDirective(input) {
3867
+ const normalized = normalizeDirectiveInput(input);
3868
+ return /\b(adjust|rescope|re scope|re-scope)\b/.test(normalized) && /\b(allowed paths|path scope|governance path|governance)\b/.test(normalized);
3869
+ }
3854
3870
  function normalizeDirectiveInput(input) {
3855
3871
  return input.trim().toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
3856
3872
  }
@@ -3869,8 +3885,8 @@ async function applyApprovedProposal(cwd) {
3869
3885
  return;
3870
3886
  }
3871
3887
  console.log(chalk5.dim("\n> Great. I will create the task from your approved request.\n"));
3872
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3873
- await plan2(approvedRequest, { conversational: true });
3888
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
3889
+ await plan2(await withAllowedPathScope(cwd, approvedRequest), { conversational: true });
3874
3890
  if (shouldAutoExecuteAfterPlanning(approvedRequest)) {
3875
3891
  await continueWithCurrentTask(cwd);
3876
3892
  return;
@@ -4012,17 +4028,28 @@ function buildSampleCapsuleDraft(cwd, files, capsuleCount) {
4012
4028
  ].join("\n");
4013
4029
  }
4014
4030
  async function continueWithCurrentTask(cwd) {
4015
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
4031
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-S5EULQKJ.js");
4016
4032
  const atoms = await listLocalAtoms2();
4017
- const readyAtoms = atoms.filter((a) => a.status === "READY").sort((a, b) => a.externalId.localeCompare(b.externalId));
4033
+ const byMostRecent = (a, b) => {
4034
+ const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
4035
+ const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
4036
+ return bTime - aTime;
4037
+ };
4038
+ const readyAtoms = atoms.filter((a) => a.status === "READY").sort(byMostRecent);
4018
4039
  if (readyAtoms.length === 0) {
4019
- const inProgressAtoms = atoms.filter((a) => a.status === "IN_PROGRESS").sort((a, b) => a.externalId.localeCompare(b.externalId));
4040
+ const inProgressAtoms = atoms.filter((a) => a.status === "IN_PROGRESS").sort(byMostRecent);
4020
4041
  if (inProgressAtoms.length > 0) {
4021
4042
  const current = inProgressAtoms[0];
4022
4043
  console.log(chalk5.yellow(`No READY atoms found. Current in-progress atom: ${current?.externalId}.`));
4023
4044
  console.log(chalk5.dim("Use `archon show <atom-id>` to inspect status, or plan a new task."));
4024
4045
  return;
4025
4046
  }
4047
+ const blockedByPath = atoms.filter((a) => a.status === "BLOCKED").sort(byMostRecent).find((a) => (a.errorMessage ?? "").toLowerCase().includes("outside the allowed paths"));
4048
+ if (blockedByPath) {
4049
+ console.log(chalk5.yellow(`No READY atoms found. Latest blocked atom: ${blockedByPath.externalId}.`));
4050
+ console.log(chalk5.dim('This atom is blocked by governance path scope. Tell me: "adjust this atom to allowed paths".'));
4051
+ return;
4052
+ }
4026
4053
  console.log(chalk5.yellow("No pending atoms found. Tell me what to plan next."));
4027
4054
  return;
4028
4055
  }
@@ -4034,9 +4061,43 @@ async function continueWithCurrentTask(cwd) {
4034
4061
  console.log(chalk5.dim(`
4035
4062
  Continuing with ${nextAtom.externalId}...
4036
4063
  `));
4037
- const { execute: execute2 } = await import("./execute-VOZIDAAG.js");
4064
+ const { execute: execute2 } = await import("./execute-QCEAXLVH.js");
4038
4065
  await execute2(nextAtom.externalId, { nonTerminating: true });
4039
4066
  }
4067
+ async function replanLatestBlockedAtom(cwd) {
4068
+ const { listLocalAtoms: listLocalAtoms2, plan: plan2 } = await import("./plan-S5EULQKJ.js");
4069
+ const atoms = await listLocalAtoms2();
4070
+ const blocked = atoms.filter((a) => a.status === "BLOCKED" && (a.errorMessage ?? "").toLowerCase().includes("outside the allowed paths")).sort((a, b) => {
4071
+ const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
4072
+ const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
4073
+ return bTime - aTime;
4074
+ })[0];
4075
+ if (!blocked) {
4076
+ console.log(chalk5.yellow("No blocked atom with path-scope guidance found."));
4077
+ return;
4078
+ }
4079
+ const allowedPaths = await listArchitecturePaths(cwd);
4080
+ const scope = allowedPaths.length > 0 ? allowedPaths.join(", ") : "existing architecture component paths";
4081
+ console.log(chalk5.dim("\n> Re-planning the blocked task with explicit allowed-path constraints...\n"));
4082
+ await plan2(`${blocked.title}
4083
+
4084
+ Constraints:
4085
+ - Only modify files within these allowed architecture paths: ${scope}
4086
+ - If required files are outside scope, first propose the minimum ARCHITECTURE.md path update needed.`, { conversational: true });
4087
+ await showLatestPlannedAtom(cwd);
4088
+ console.log(chalk5.dim('\nReply "continue" to execute this re-scoped atom.'));
4089
+ }
4090
+ async function listArchitecturePaths(cwd) {
4091
+ try {
4092
+ const parser = new ArchitectureParser(join6(cwd, "ARCHITECTURE.md"));
4093
+ const parsed = await parser.parse();
4094
+ const components = parsed.success ? parsed.schema?.components ?? [] : [];
4095
+ const paths = components.flatMap((component) => component.paths ?? []).filter((path2) => typeof path2 === "string" && path2.trim().length > 0);
4096
+ return Array.from(new Set(paths));
4097
+ } catch {
4098
+ return [];
4099
+ }
4100
+ }
4040
4101
  async function showMainMenu() {
4041
4102
  const cwd = process.cwd();
4042
4103
  while (true) {
@@ -4092,6 +4153,14 @@ async function showMainMenu() {
4092
4153
  async function handleFreeformJourneyInput(cwd, input) {
4093
4154
  const freeform = input.trim();
4094
4155
  if (!freeform) return false;
4156
+ if (isExecutionDirective(freeform) || isContinuationDirective(freeform)) {
4157
+ await continueWithCurrentTask(cwd);
4158
+ return true;
4159
+ }
4160
+ if (isRescopeBlockedDirective(freeform)) {
4161
+ await replanLatestBlockedAtom(cwd);
4162
+ return true;
4163
+ }
4095
4164
  const intent = detectUserIntent(freeform);
4096
4165
  if (isReadOnlyExploreRequest(freeform) || intent.mode === "explore" && intent.confidence >= 0.7) {
4097
4166
  console.log(chalk5.dim("\n> Got it! Analyzing the project...\n"));
@@ -4102,8 +4171,8 @@ async function handleFreeformJourneyInput(cwd, input) {
4102
4171
  const state = detectProjectState(cwd);
4103
4172
  if (state.hasArchitecture) {
4104
4173
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
4105
- const { plan: plan3 } = await import("./plan-RHDFDSZE.js");
4106
- await plan3(freeform, { conversational: true });
4174
+ const { plan: plan3 } = await import("./plan-S5EULQKJ.js");
4175
+ await plan3(await withAllowedPathScope(cwd, freeform), { conversational: true });
4107
4176
  return true;
4108
4177
  }
4109
4178
  console.log(chalk5.dim("\n> Let me understand your project better...\n"));
@@ -4111,8 +4180,8 @@ async function handleFreeformJourneyInput(cwd, input) {
4111
4180
  return true;
4112
4181
  }
4113
4182
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
4114
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
4115
- await plan2(freeform, { conversational: true });
4183
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
4184
+ await plan2(await withAllowedPathScope(cwd, freeform), { conversational: true });
4116
4185
  return true;
4117
4186
  }
4118
4187
  function extractActionableFollowUpFromExplore(input) {
@@ -4170,8 +4239,8 @@ async function handlePostExploreAction(cwd, request, options = {}) {
4170
4239
  } else {
4171
4240
  console.log(chalk5.dim("> Got it! Creating a task for this...\n"));
4172
4241
  }
4173
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
4174
- await plan2(request, { conversational: true });
4242
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
4243
+ await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
4175
4244
  if (options.agentMode) {
4176
4245
  if (shouldAutoExecuteAfterPlanning(sourceInput)) {
4177
4246
  await continueWithCurrentTask(cwd);
@@ -4181,19 +4250,30 @@ async function handlePostExploreAction(cwd, request, options = {}) {
4181
4250
  console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
4182
4251
  }
4183
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
+ }
4184
4264
  async function planTask() {
4185
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
4265
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
4186
4266
  const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
4187
4267
  if (description.trim()) {
4188
4268
  await plan2(description, { conversational: true });
4189
4269
  }
4190
4270
  }
4191
4271
  async function listAtoms() {
4192
- const { list: list2 } = await import("./list-JC7IMC5M.js");
4272
+ const { list: list2 } = await import("./list-WW6WUNBG.js");
4193
4273
  await list2({});
4194
4274
  }
4195
4275
  async function executeNext() {
4196
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
4276
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-S5EULQKJ.js");
4197
4277
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
4198
4278
  const { loadExecutionPreferences } = await import("./preferences-AGIZD5E5.js");
4199
4279
  const cwd = process.cwd();
@@ -4264,11 +4344,11 @@ async function executeNext() {
4264
4344
  }
4265
4345
  }
4266
4346
  if (selectedMode === "parallel-cloud") {
4267
- const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-3EZP3X6S.js");
4347
+ const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-N74S3MFF.js");
4268
4348
  await parallelExecuteCloud2(runIds);
4269
4349
  return;
4270
4350
  }
4271
- const { parallelExecute } = await import("./parallel-3EZP3X6S.js");
4351
+ const { parallelExecute } = await import("./parallel-N74S3MFF.js");
4272
4352
  await parallelExecute(runIds);
4273
4353
  return;
4274
4354
  }
@@ -4276,7 +4356,7 @@ async function executeNext() {
4276
4356
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
4277
4357
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
4278
4358
  if (targetId) {
4279
- const { execute: execute2 } = await import("./execute-VOZIDAAG.js");
4359
+ const { execute: execute2 } = await import("./execute-QCEAXLVH.js");
4280
4360
  await execute2(targetId, {});
4281
4361
  } else {
4282
4362
  console.log(chalk5.yellow("No atom to execute."));
@@ -4425,7 +4505,7 @@ async function handleSlashCommand(input) {
4425
4505
  const arg = parts.slice(1).join(" ").trim();
4426
4506
  switch (command) {
4427
4507
  case "/plan": {
4428
- const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
4508
+ const { plan: plan2 } = await import("./plan-S5EULQKJ.js");
4429
4509
  if (arg) {
4430
4510
  await plan2(arg, { conversational: true });
4431
4511
  } else {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  list
3
- } from "./chunk-6ADNSWJ3.js";
4
- import "./chunk-Z6RH6DFP.js";
3
+ } from "./chunk-Y2QXZ2UR.js";
4
+ import "./chunk-LGWUWEEJ.js";
5
5
  import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
@@ -6,9 +6,9 @@ import {
6
6
  parallelRunWaves,
7
7
  parallelSchedule,
8
8
  parallelStatus
9
- } from "./chunk-MRCIJKWD.js";
9
+ } from "./chunk-CFEX6EWG.js";
10
10
  import "./chunk-EBHHIUCB.js";
11
- import "./chunk-Z6RH6DFP.js";
11
+ import "./chunk-LGWUWEEJ.js";
12
12
  import "./chunk-WGLVDEZC.js";
13
13
  import "./chunk-3MZOEZUH.js";
14
14
  import "./chunk-F7R3QKHP.js";
@@ -3,7 +3,7 @@ import {
3
3
  loadAtom,
4
4
  parseAtomDescription,
5
5
  plan
6
- } from "./chunk-Z6RH6DFP.js";
6
+ } from "./chunk-LGWUWEEJ.js";
7
7
  import "./chunk-WGLVDEZC.js";
8
8
  import "./chunk-3MZOEZUH.js";
9
9
  import "./chunk-F7R3QKHP.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  show
3
- } from "./chunk-LRNXR7DL.js";
4
- import "./chunk-Z6RH6DFP.js";
3
+ } from "./chunk-4C6XR7WP.js";
4
+ import "./chunk-LGWUWEEJ.js";
5
5
  import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.33",
3
+ "version": "2.19.36",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {