archondev 2.19.28 → 2.19.30

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/README.md CHANGED
@@ -121,6 +121,8 @@ pnpm exec tsx scripts/init-governance-db.ts
121
121
  - Content-only requests (stories, outlines, lessons, visuals) use lightweight planning to avoid blocking.
122
122
  - BYOK shows per‑model usage and cost by today/week/month/year in `archon preferences` → “View usage details.”
123
123
  - You can paste multi‑line requests into interactive prompts; Archon captures them as a single response.
124
+ - Proposal approvals like `approve plan` now bind to the pending proposal context in chat mode.
125
+ - Governance boundary/path checks in execute now steer with actionable guidance and set atoms to `BLOCKED` rather than hard failing.
124
126
 
125
127
  **Tip:** Use `archon plan --edit` to adjust title and acceptance criteria before planning.
126
128
  **Web Checks:** If Archon detects a web project, it prompts to run A11y/SEO/GEO checks and stores your preference in `.archon/config.yaml`.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  bugReport
3
- } from "./chunk-77S6ZEVT.js";
4
- import "./chunk-DFDEEMQU.js";
3
+ } from "./chunk-AHK2ITJX.js";
4
+ import "./chunk-WGLVDEZC.js";
5
5
  import "./chunk-3MZOEZUH.js";
6
6
  import "./chunk-F7R3QKHP.js";
7
7
  import "./chunk-7C6JELBL.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listLocalAtoms
3
- } from "./chunk-I2ORQAMH.js";
3
+ } from "./chunk-Z6RH6DFP.js";
4
4
 
5
5
  // src/cli/list.ts
6
6
  import chalk from "chalk";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createAtom
3
- } from "./chunk-DFDEEMQU.js";
3
+ } from "./chunk-WGLVDEZC.js";
4
4
  import {
5
5
  ArchitectAgent
6
6
  } from "./chunk-3MZOEZUH.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadAtom
3
- } from "./chunk-I2ORQAMH.js";
3
+ } from "./chunk-Z6RH6DFP.js";
4
4
 
5
5
  // src/cli/show.ts
6
6
  import chalk from "chalk";
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-I2ORQAMH.js";
9
+ } from "./chunk-Z6RH6DFP.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -7,10 +7,10 @@ import {
7
7
  UsageRecorder,
8
8
  handleInsufficientCreditsRecovery,
9
9
  loadAtom
10
- } from "./chunk-I2ORQAMH.js";
10
+ } from "./chunk-Z6RH6DFP.js";
11
11
  import {
12
12
  transitionAtom
13
- } from "./chunk-DFDEEMQU.js";
13
+ } from "./chunk-WGLVDEZC.js";
14
14
  import {
15
15
  AnthropicClient,
16
16
  getDefaultModel
@@ -4783,6 +4783,17 @@ var EnvironmentValidator = class {
4783
4783
 
4784
4784
  // src/cli/execute.ts
4785
4785
  var ATOMS_DIR = ".archon/atoms";
4786
+ function isGovernanceViolation(errorMessage) {
4787
+ if (!errorMessage) return false;
4788
+ const normalized = errorMessage.toLowerCase();
4789
+ return normalized.includes("architecture violations:") || normalized.includes("outside the allowed paths") || normalized.includes("is protected");
4790
+ }
4791
+ function extractGovernanceViolations(errorMessage) {
4792
+ if (!errorMessage) return [];
4793
+ const prefix = "Architecture violations:";
4794
+ if (!errorMessage.startsWith(prefix)) return [];
4795
+ return errorMessage.slice(prefix.length).split(",").map((item) => item.trim()).filter(Boolean);
4796
+ }
4786
4797
  function createPrompt() {
4787
4798
  const rl = createInterface({
4788
4799
  input: process.stdin,
@@ -4804,7 +4815,7 @@ async function execute(atomId, options) {
4804
4815
  process.exit(1);
4805
4816
  };
4806
4817
  if (options.parallel && options.parallel.length > 0) {
4807
- const { parallelExecute } = await import("./parallel-RCMUYXE2.js");
4818
+ const { parallelExecute } = await import("./parallel-3EZP3X6S.js");
4808
4819
  const allAtomIds = [atomId, ...options.parallel];
4809
4820
  await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
4810
4821
  return;
@@ -5018,13 +5029,32 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
5018
5029
  const executionResult = await executor.executeAtom(atom, atom.plan, parseResult.schema, cwd);
5019
5030
  const filesChanged = executionResult.diffs.map((d) => d.path);
5020
5031
  if (!executionResult.success) {
5021
- console.log(chalk2.red("\n\u274C Execution failed"));
5022
- console.log(chalk2.red(executionResult.errorMessage ?? "Unknown error"));
5032
+ if (isGovernanceViolation(executionResult.errorMessage)) {
5033
+ console.log(chalk2.yellow("\n\u26A0\uFE0F Execution paused by governance guidance"));
5034
+ console.log(chalk2.dim("No changes were committed. Update the plan/path scope, then continue."));
5035
+ const violations = extractGovernanceViolations(executionResult.errorMessage);
5036
+ if (violations.length > 0) {
5037
+ console.log(chalk2.yellow("\nGovernance guidance:"));
5038
+ for (const violation of violations) {
5039
+ console.log(chalk2.dim(` - ${violation}`));
5040
+ }
5041
+ } else {
5042
+ console.log(chalk2.yellow(executionResult.errorMessage ?? "Architecture constraints were not satisfied."));
5043
+ }
5044
+ } else {
5045
+ console.log(chalk2.red("\n\u274C Execution failed"));
5046
+ console.log(chalk2.red(executionResult.errorMessage ?? "Unknown error"));
5047
+ }
5023
5048
  if (executionResult.rollbackPerformed) {
5024
5049
  console.log(chalk2.yellow("Changes have been rolled back."));
5025
5050
  }
5026
- atom = transitionAtom(atom, "FAILED");
5027
- atom.errorMessage = executionResult.errorMessage ?? "Execution failed";
5051
+ if (isGovernanceViolation(executionResult.errorMessage)) {
5052
+ atom = transitionAtom(atom, "BLOCKED");
5053
+ atom.errorMessage = executionResult.errorMessage ?? "Governance guidance requires adjustments before execution.";
5054
+ } else {
5055
+ atom = transitionAtom(atom, "FAILED");
5056
+ atom.errorMessage = executionResult.errorMessage ?? "Execution failed";
5057
+ }
5028
5058
  await saveAtom(atom);
5029
5059
  await captureLearnings(atom, {
5030
5060
  atomId: atom.id,
@@ -5033,6 +5063,10 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
5033
5063
  success: false,
5034
5064
  errorMessage: executionResult.errorMessage
5035
5065
  });
5066
+ if (isGovernanceViolation(executionResult.errorMessage)) {
5067
+ printExecuteNextActions(atom.externalId, false);
5068
+ return;
5069
+ }
5036
5070
  return fail();
5037
5071
  }
5038
5072
  console.log(chalk2.green("\u2713 Plan executed successfully"));
@@ -6,8 +6,8 @@ import {
6
6
  var ATOM_TRANSITIONS = {
7
7
  DRAFT: ["READY"],
8
8
  READY: ["IN_PROGRESS", "BLOCKED"],
9
- IN_PROGRESS: ["TESTING", "FAILED"],
10
- TESTING: ["DONE", "FAILED"],
9
+ IN_PROGRESS: ["TESTING", "FAILED", "BLOCKED"],
10
+ TESTING: ["DONE", "FAILED", "BLOCKED"],
11
11
  DONE: [],
12
12
  // Terminal state
13
13
  FAILED: ["IN_PROGRESS", "BLOCKED"],
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createAtom,
3
3
  validateAtom
4
- } from "./chunk-DFDEEMQU.js";
4
+ } from "./chunk-WGLVDEZC.js";
5
5
  import {
6
6
  ArchitectAgent
7
7
  } from "./chunk-3MZOEZUH.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-VMQKFKX3.js";
3
+ } from "./chunk-UVW75BHP.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
- import "./chunk-I2ORQAMH.js";
6
- import "./chunk-DFDEEMQU.js";
5
+ import "./chunk-Z6RH6DFP.js";
6
+ import "./chunk-WGLVDEZC.js";
7
7
  import "./chunk-3MZOEZUH.js";
8
8
  import "./chunk-F7R3QKHP.js";
9
9
  import "./chunk-Q3GIFHIQ.js";
package/dist/index.js CHANGED
@@ -13,10 +13,10 @@ import {
13
13
  } from "./chunk-6URKZ7NB.js";
14
14
  import {
15
15
  show
16
- } from "./chunk-RS3FR4UB.js";
16
+ } from "./chunk-LRNXR7DL.js";
17
17
  import {
18
18
  bugReport
19
- } from "./chunk-77S6ZEVT.js";
19
+ } from "./chunk-AHK2ITJX.js";
20
20
  import {
21
21
  reviewAnalyze,
22
22
  reviewExport,
@@ -50,13 +50,13 @@ import {
50
50
  parallelRunWaves,
51
51
  parallelSchedule,
52
52
  parallelStatus
53
- } from "./chunk-QIGRZP5P.js";
53
+ } from "./chunk-MRCIJKWD.js";
54
54
  import {
55
55
  DependencyParser,
56
56
  EnvironmentConfigLoader,
57
57
  EnvironmentValidator,
58
58
  execute
59
- } from "./chunk-VMQKFKX3.js";
59
+ } from "./chunk-UVW75BHP.js";
60
60
  import {
61
61
  cloudCancel,
62
62
  cloudLogs,
@@ -64,13 +64,13 @@ import {
64
64
  } from "./chunk-EBHHIUCB.js";
65
65
  import {
66
66
  list
67
- } from "./chunk-WQIXCLK4.js";
67
+ } from "./chunk-6ADNSWJ3.js";
68
68
  import {
69
69
  listLocalAtoms,
70
70
  loadAtom,
71
71
  plan
72
- } from "./chunk-I2ORQAMH.js";
73
- import "./chunk-DFDEEMQU.js";
72
+ } from "./chunk-Z6RH6DFP.js";
73
+ import "./chunk-WGLVDEZC.js";
74
74
  import "./chunk-3MZOEZUH.js";
75
75
  import {
76
76
  err,
@@ -203,7 +203,7 @@ async function saveAtomEnvironmentState(atomId, cwd, state) {
203
203
  import chalk5 from "chalk";
204
204
  import readline from "readline";
205
205
  import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync3, appendFileSync } from "fs";
206
- import { join as join6 } from "path";
206
+ import { join as join6, relative } from "path";
207
207
 
208
208
  // src/core/context/manager.ts
209
209
  import { existsSync as existsSync2 } from "fs";
@@ -2616,6 +2616,8 @@ function detectWebProject(cwd) {
2616
2616
  // src/cli/start.ts
2617
2617
  var PAID_TIER_DEFAULT_CHAT_MODEL = "gemini-3.1-pro-preview";
2618
2618
  var pendingProposalRequest = null;
2619
+ var pendingProposalMode = "atom";
2620
+ var pendingAnalysisToAtomRequest = null;
2619
2621
  function uiText(rich, plain) {
2620
2622
  return isTerminalSafeMode() ? plain : rich;
2621
2623
  }
@@ -3251,7 +3253,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
3251
3253
  case "1": {
3252
3254
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3253
3255
  if (description.trim()) {
3254
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3256
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3255
3257
  await plan2(description, { conversational: true });
3256
3258
  }
3257
3259
  await showMainMenu();
@@ -3496,7 +3498,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3496
3498
  const hintedTask = initialTaskHint?.trim() ?? "";
3497
3499
  if (hintedTask) {
3498
3500
  console.log(chalk5.dim("Using your request above as the first task.\n"));
3499
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3501
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3500
3502
  await plan2(hintedTask, { conversational: true });
3501
3503
  return;
3502
3504
  }
@@ -3521,7 +3523,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3521
3523
  description = continueAnswer.trim();
3522
3524
  }
3523
3525
  if (description.trim()) {
3524
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3526
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3525
3527
  await plan2(description, { conversational: true });
3526
3528
  }
3527
3529
  }
@@ -3676,11 +3678,21 @@ async function runAgentMode(cwd, state) {
3676
3678
  async function handleAgentConversationInput(cwd, input) {
3677
3679
  const normalized = input.trim().toLowerCase();
3678
3680
  if (!normalized) return false;
3681
+ if (pendingAnalysisToAtomRequest && isCreateAtomDirective(normalized)) {
3682
+ const request = pendingAnalysisToAtomRequest;
3683
+ pendingAnalysisToAtomRequest = null;
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.'));
3689
+ return true;
3690
+ }
3679
3691
  if (pendingProposalRequest && isPlanApprovalDirective(normalized)) {
3680
3692
  await applyApprovedProposal(cwd);
3681
3693
  return true;
3682
3694
  }
3683
- if (isContinuationDirective(normalized)) {
3695
+ if (isExecutionDirective(normalized)) {
3684
3696
  await continueWithCurrentTask(cwd);
3685
3697
  return true;
3686
3698
  }
@@ -3699,14 +3711,14 @@ async function handleAgentConversationInput(cwd, input) {
3699
3711
  return true;
3700
3712
  }
3701
3713
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
3702
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3714
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3703
3715
  await plan2(input, { conversational: true });
3704
3716
  if (shouldAutoExecuteAfterPlanning(input)) {
3705
3717
  await continueWithCurrentTask(cwd);
3706
3718
  return true;
3707
3719
  }
3708
3720
  await showLatestPlannedAtom(cwd);
3709
- console.log(chalk5.dim('\nReply "continue" when you approve this plan, or tell me what to change.'));
3721
+ console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
3710
3722
  return true;
3711
3723
  }
3712
3724
  function isReadOnlyExploreRequest(input) {
@@ -3733,6 +3745,7 @@ function wantsProposalBeforeExecution(input) {
3733
3745
  }
3734
3746
  async function showProposalForApproval(input) {
3735
3747
  pendingProposalRequest = input.trim();
3748
+ pendingProposalMode = shouldDoAnalysisBeforeAtom(input) ? "analysis" : "atom";
3736
3749
  console.log(chalk5.dim("\n> Understood. I will not create atoms yet.\n"));
3737
3750
  console.log(chalk5.bold("Proposed plan (for your approval):"));
3738
3751
  console.log(chalk5.dim(" 1. Review project files and locate the capsule markdown/source for day 1."));
@@ -3745,7 +3758,7 @@ async function showProposalForApproval(input) {
3745
3758
  }
3746
3759
  }
3747
3760
  async function showLatestPlannedAtom(cwd) {
3748
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
3761
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
3749
3762
  const atoms = await listLocalAtoms2();
3750
3763
  if (atoms.length === 0) {
3751
3764
  console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
@@ -3763,33 +3776,129 @@ async function showLatestPlannedAtom(cwd) {
3763
3776
  console.log(chalk5.dim(`
3764
3777
  Showing latest planned atom (${latest.externalId})...
3765
3778
  `));
3766
- const { show: show2 } = await import("./show-N7E3I6EF.js");
3779
+ const { show: show2 } = await import("./show-7A3FACN6.js");
3767
3780
  await show2(latest.externalId);
3768
3781
  }
3769
- function isContinuationDirective(input) {
3782
+ function isPlanApprovalDirective(input) {
3770
3783
  const normalized = input.trim().toLowerCase();
3771
- return normalized === "continue" || normalized === "continue." || normalized === "go on" || normalized === "go ahead" || normalized === "next" || normalized === "proceed" || normalized === "do it";
3784
+ return normalized === "approve" || normalized === "approve plan" || normalized === "approved" || normalized === "yes" || normalized === "yes, proceed" || normalized === "proceed";
3772
3785
  }
3773
- function isPlanApprovalDirective(input) {
3786
+ function isExecutionDirective(input) {
3774
3787
  const normalized = input.trim().toLowerCase();
3775
- return normalized === "approve" || normalized === "approve plan" || normalized === "approved" || normalized === "yes" || normalized === "yes, proceed" || normalized === "proceed" || normalized === "continue" || normalized === "continue.";
3788
+ return normalized === "execute" || normalized === "execute atom" || normalized === "run atom" || normalized === "run it now" || normalized === "implement now" || normalized === "start execution" || normalized === "go ahead and execute";
3789
+ }
3790
+ function isCreateAtomDirective(input) {
3791
+ const normalized = input.trim().toLowerCase();
3792
+ return normalized === "create atom" || normalized === "make atom" || normalized === "save as atom" || normalized === "turn this into a task" || normalized === "create task";
3793
+ }
3794
+ function shouldDoAnalysisBeforeAtom(input) {
3795
+ const normalized = input.toLowerCase();
3796
+ const hasAnalysisIntent = /\b(review|analy[sz]e|inspect|read)\b/.test(normalized) && /\b(files?|folder|project|markdown|lesson|capsule)\b/.test(normalized);
3797
+ const asksForPlan = /\b(let me know|what your plan is|plan is|how to implement|before creating|before you implement)\b/.test(normalized);
3798
+ return hasAnalysisIntent && asksForPlan;
3776
3799
  }
3777
3800
  async function applyApprovedProposal(cwd) {
3778
3801
  const approvedRequest = pendingProposalRequest;
3779
3802
  if (!approvedRequest) return;
3780
3803
  pendingProposalRequest = null;
3804
+ if (pendingProposalMode === "analysis") {
3805
+ await provideAnalysisFirstPlan(cwd, approvedRequest);
3806
+ return;
3807
+ }
3781
3808
  console.log(chalk5.dim("\n> Great. I will create the task from your approved request.\n"));
3782
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3809
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3783
3810
  await plan2(approvedRequest, { conversational: true });
3784
3811
  if (shouldAutoExecuteAfterPlanning(approvedRequest)) {
3785
3812
  await continueWithCurrentTask(cwd);
3786
3813
  return;
3787
3814
  }
3788
3815
  await showLatestPlannedAtom(cwd);
3789
- console.log(chalk5.dim('\nReply "continue" when you approve this plan, or tell me what to change.'));
3816
+ console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
3817
+ }
3818
+ async function provideAnalysisFirstPlan(cwd, request) {
3819
+ console.log(chalk5.dim("\n> Great. I will analyze first and return a concrete recommendation before creating atoms.\n"));
3820
+ const markdownFiles = collectMarkdownFiles(cwd);
3821
+ const dayOneCandidates = markdownFiles.filter((file) => /(day[-_ ]?0?1|lesson[-_ ]?0?1|first)/i.test(file));
3822
+ const capsuleCandidates = markdownFiles.filter((file) => /capsule/i.test(file));
3823
+ const primaryCandidates = dayOneCandidates.length > 0 ? dayOneCandidates : capsuleCandidates;
3824
+ const reviewedFiles = primaryCandidates.slice(0, 8);
3825
+ const stats = computeContentStats(cwd, reviewedFiles);
3826
+ const recommendSplit = stats.totalWords > 900 || stats.totalHeadings >= 6;
3827
+ const capsuleCount = recommendSplit ? 2 : 1;
3828
+ console.log(chalk5.bold("Analysis summary (no atoms created):"));
3829
+ if (reviewedFiles.length === 0) {
3830
+ console.log(chalk5.dim(" - I did not find obvious day-1 capsule markdown files automatically."));
3831
+ console.log(chalk5.dim(" - Share the target file path and I will evaluate it directly."));
3832
+ } else {
3833
+ console.log(chalk5.dim(" Files reviewed:"));
3834
+ for (const file of reviewedFiles) {
3835
+ console.log(chalk5.dim(` - ${file}`));
3836
+ }
3837
+ console.log(chalk5.dim(` Content signals: ~${stats.totalWords} words, ${stats.totalHeadings} section headings.`));
3838
+ }
3839
+ console.log();
3840
+ console.log(chalk5.bold("Recommendation:"));
3841
+ if (reviewedFiles.length === 0) {
3842
+ console.log(chalk5.dim(" I need the exact day-1 capsule file path to make a reliable one-vs-many capsule recommendation."));
3843
+ } else if (recommendSplit) {
3844
+ console.log(chalk5.dim(` Split day 1 into ${capsuleCount} capsules for clarity and lower cognitive load.`));
3845
+ } else {
3846
+ console.log(chalk5.dim(" Keep day 1 as one capsule to preserve continuity and reduce context switching."));
3847
+ }
3848
+ console.log();
3849
+ console.log(chalk5.bold("Implementation plan (proposed):"));
3850
+ console.log(chalk5.dim(" 1. Confirm target source file(s) for day 1 content."));
3851
+ console.log(chalk5.dim(` 2. Define capsule boundaries and titles (${capsuleCount} capsule${capsuleCount > 1 ? "s" : ""}).`));
3852
+ console.log(chalk5.dim(" 3. Draft capsule markdown(s) with consistent template and learning objective per capsule."));
3853
+ console.log(chalk5.dim(" 4. Add index/manifest links and quick validation checks for user flow."));
3854
+ pendingAnalysisToAtomRequest = request;
3855
+ console.log();
3856
+ console.log(chalk5.dim('Reply "create atom" to save this as a governed task, or tell me what to adjust first.'));
3857
+ }
3858
+ function collectMarkdownFiles(cwd) {
3859
+ const results = [];
3860
+ const queue = ["."];
3861
+ const skipDirs = /* @__PURE__ */ new Set([".git", "node_modules", ".archon", "dist", "build", ".next", ".turbo"]);
3862
+ while (queue.length > 0 && results.length < 200) {
3863
+ const current = queue.shift();
3864
+ if (!current) break;
3865
+ const abs = join6(cwd, current);
3866
+ let entries;
3867
+ try {
3868
+ entries = readdirSync3(abs, { withFileTypes: true });
3869
+ } catch {
3870
+ continue;
3871
+ }
3872
+ for (const entry of entries) {
3873
+ const rel = current === "." ? entry.name : join6(current, entry.name);
3874
+ if (entry.isDirectory()) {
3875
+ if (!skipDirs.has(entry.name)) {
3876
+ queue.push(rel);
3877
+ }
3878
+ continue;
3879
+ }
3880
+ if (entry.isFile() && entry.name.toLowerCase().endsWith(".md")) {
3881
+ results.push(relative(cwd, join6(cwd, rel)).replace(/\\/g, "/"));
3882
+ }
3883
+ }
3884
+ }
3885
+ return results;
3886
+ }
3887
+ function computeContentStats(cwd, files) {
3888
+ let totalWords = 0;
3889
+ let totalHeadings = 0;
3890
+ for (const relPath of files) {
3891
+ try {
3892
+ const content = readFileSync3(join6(cwd, relPath), "utf-8");
3893
+ totalWords += content.split(/\s+/).filter(Boolean).length;
3894
+ totalHeadings += content.split("\n").filter((line) => line.trim().startsWith("#")).length;
3895
+ } catch {
3896
+ }
3897
+ }
3898
+ return { totalWords, totalHeadings };
3790
3899
  }
3791
3900
  async function continueWithCurrentTask(cwd) {
3792
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
3901
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
3793
3902
  const atoms = await listLocalAtoms2();
3794
3903
  const pending = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS").sort((a, b) => a.externalId.localeCompare(b.externalId));
3795
3904
  if (pending.length === 0) {
@@ -3804,7 +3913,7 @@ async function continueWithCurrentTask(cwd) {
3804
3913
  console.log(chalk5.dim(`
3805
3914
  Continuing with ${nextAtom.externalId}...
3806
3915
  `));
3807
- const { execute: execute2 } = await import("./execute-WIOXRN5H.js");
3916
+ const { execute: execute2 } = await import("./execute-VOZIDAAG.js");
3808
3917
  await execute2(nextAtom.externalId, { nonTerminating: true });
3809
3918
  }
3810
3919
  async function showMainMenu() {
@@ -3872,7 +3981,7 @@ async function handleFreeformJourneyInput(cwd, input) {
3872
3981
  const state = detectProjectState(cwd);
3873
3982
  if (state.hasArchitecture) {
3874
3983
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
3875
- const { plan: plan3 } = await import("./plan-PJI6MCS3.js");
3984
+ const { plan: plan3 } = await import("./plan-RHDFDSZE.js");
3876
3985
  await plan3(freeform, { conversational: true });
3877
3986
  return true;
3878
3987
  }
@@ -3881,7 +3990,7 @@ async function handleFreeformJourneyInput(cwd, input) {
3881
3990
  return true;
3882
3991
  }
3883
3992
  console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
3884
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
3993
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3885
3994
  await plan2(freeform, { conversational: true });
3886
3995
  return true;
3887
3996
  }
@@ -3936,7 +4045,7 @@ async function handlePostExploreAction(cwd, request, options = {}) {
3936
4045
  } else {
3937
4046
  console.log(chalk5.dim("> Got it! Creating a task for this...\n"));
3938
4047
  }
3939
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
4048
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3940
4049
  await plan2(request, { conversational: true });
3941
4050
  if (options.agentMode) {
3942
4051
  if (shouldAutoExecuteAfterPlanning(sourceInput)) {
@@ -3944,22 +4053,22 @@ async function handlePostExploreAction(cwd, request, options = {}) {
3944
4053
  return;
3945
4054
  }
3946
4055
  await showLatestPlannedAtom(cwd);
3947
- console.log(chalk5.dim('\nReply "continue" when you approve this plan, or tell me what to change.'));
4056
+ console.log(chalk5.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
3948
4057
  }
3949
4058
  }
3950
4059
  async function planTask() {
3951
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
4060
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
3952
4061
  const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
3953
4062
  if (description.trim()) {
3954
4063
  await plan2(description, { conversational: true });
3955
4064
  }
3956
4065
  }
3957
4066
  async function listAtoms() {
3958
- const { list: list2 } = await import("./list-2PHO34IY.js");
4067
+ const { list: list2 } = await import("./list-JC7IMC5M.js");
3959
4068
  await list2({});
3960
4069
  }
3961
4070
  async function executeNext() {
3962
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
4071
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-RHDFDSZE.js");
3963
4072
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
3964
4073
  const { loadExecutionPreferences } = await import("./preferences-AGIZD5E5.js");
3965
4074
  const cwd = process.cwd();
@@ -4030,11 +4139,11 @@ async function executeNext() {
4030
4139
  }
4031
4140
  }
4032
4141
  if (selectedMode === "parallel-cloud") {
4033
- const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-RCMUYXE2.js");
4142
+ const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-3EZP3X6S.js");
4034
4143
  await parallelExecuteCloud2(runIds);
4035
4144
  return;
4036
4145
  }
4037
- const { parallelExecute } = await import("./parallel-RCMUYXE2.js");
4146
+ const { parallelExecute } = await import("./parallel-3EZP3X6S.js");
4038
4147
  await parallelExecute(runIds);
4039
4148
  return;
4040
4149
  }
@@ -4042,14 +4151,14 @@ async function executeNext() {
4042
4151
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
4043
4152
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
4044
4153
  if (targetId) {
4045
- const { execute: execute2 } = await import("./execute-WIOXRN5H.js");
4154
+ const { execute: execute2 } = await import("./execute-VOZIDAAG.js");
4046
4155
  await execute2(targetId, {});
4047
4156
  } else {
4048
4157
  console.log(chalk5.yellow("No atom to execute."));
4049
4158
  }
4050
4159
  }
4051
4160
  async function reportBug() {
4052
- const { bugReport: bugReport2 } = await import("./bug-QYKFP77X.js");
4161
+ const { bugReport: bugReport2 } = await import("./bug-CQKGCVCM.js");
4053
4162
  const title = await prompt("Bug title");
4054
4163
  if (title.trim()) {
4055
4164
  await bugReport2(title, {});
@@ -4191,7 +4300,7 @@ async function handleSlashCommand(input) {
4191
4300
  const arg = parts.slice(1).join(" ").trim();
4192
4301
  switch (command) {
4193
4302
  case "/plan": {
4194
- const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
4303
+ const { plan: plan2 } = await import("./plan-RHDFDSZE.js");
4195
4304
  if (arg) {
4196
4305
  await plan2(arg, { conversational: true });
4197
4306
  } else {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  list
3
- } from "./chunk-WQIXCLK4.js";
4
- import "./chunk-I2ORQAMH.js";
5
- import "./chunk-DFDEEMQU.js";
3
+ } from "./chunk-6ADNSWJ3.js";
4
+ import "./chunk-Z6RH6DFP.js";
5
+ import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
8
8
  import "./chunk-Q3GIFHIQ.js";
@@ -6,10 +6,10 @@ import {
6
6
  parallelRunWaves,
7
7
  parallelSchedule,
8
8
  parallelStatus
9
- } from "./chunk-QIGRZP5P.js";
9
+ } from "./chunk-MRCIJKWD.js";
10
10
  import "./chunk-EBHHIUCB.js";
11
- import "./chunk-I2ORQAMH.js";
12
- import "./chunk-DFDEEMQU.js";
11
+ import "./chunk-Z6RH6DFP.js";
12
+ import "./chunk-WGLVDEZC.js";
13
13
  import "./chunk-3MZOEZUH.js";
14
14
  import "./chunk-F7R3QKHP.js";
15
15
  import "./chunk-Q3GIFHIQ.js";
@@ -3,8 +3,8 @@ import {
3
3
  loadAtom,
4
4
  parseAtomDescription,
5
5
  plan
6
- } from "./chunk-I2ORQAMH.js";
7
- import "./chunk-DFDEEMQU.js";
6
+ } from "./chunk-Z6RH6DFP.js";
7
+ import "./chunk-WGLVDEZC.js";
8
8
  import "./chunk-3MZOEZUH.js";
9
9
  import "./chunk-F7R3QKHP.js";
10
10
  import "./chunk-Q3GIFHIQ.js";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  show
3
- } from "./chunk-RS3FR4UB.js";
4
- import "./chunk-I2ORQAMH.js";
5
- import "./chunk-DFDEEMQU.js";
3
+ } from "./chunk-LRNXR7DL.js";
4
+ import "./chunk-Z6RH6DFP.js";
5
+ import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
8
8
  import "./chunk-Q3GIFHIQ.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.28",
3
+ "version": "2.19.30",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {