archondev 2.1.1 → 2.1.4
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 +25 -2
- package/dist/{bug-COUVQ4X3.js → bug-K4V357B2.js} +1 -1
- package/dist/{chunk-XRWIU3RD.js → chunk-3NPZQOK2.js} +6 -6
- package/dist/{chunk-JDPFHHTO.js → chunk-E2M23XSZ.js} +4 -4
- package/dist/{chunk-62OWYYHV.js → chunk-KF6MFAB4.js} +4 -4
- package/dist/{chunk-XKRAXJN5.js → chunk-P666JE3G.js} +13 -4
- package/dist/{chunk-UDBFDXJI.js → chunk-QSYKKPFF.js} +2 -2
- package/dist/{chunk-UZT2L27M.js → chunk-RCW22YNI.js} +2 -2
- package/dist/{chunk-N73LAU7W.js → chunk-TEY4GCMH.js} +1 -1
- package/dist/{chunk-OY7OJKFD.js → chunk-TSSFMB6E.js} +3 -3
- package/dist/{execute-2S2UHTLN.js → execute-5ZSLSWPZ.js} +2 -2
- package/dist/index.js +120 -86
- package/dist/{init-7EWVBX6O.js → init-6EXMDCWC.js} +1 -1
- package/dist/{list-6LNHTEOA.js → list-LEFAISNL.js} +2 -2
- package/dist/{parallel-N67PD2HF.js → parallel-5WJAXTYL.js} +2 -2
- package/dist/{plan-VRAS6IYQ.js → plan-W2UXAR6E.js} +1 -1
- package/dist/{preferences-ND2AKZYW.js → preferences-ZJ4TX2RC.js} +1 -1
- package/dist/{review-3R6QXAXQ.js → review-QV4TQM2Z.js} +1 -1
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -9,10 +9,10 @@ The complete AI development system. It manages your entire development process s
|
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
# macOS/Linux:
|
|
12
|
-
npm install -g
|
|
12
|
+
npm install -g archondev && archon
|
|
13
13
|
|
|
14
14
|
# Windows PowerShell:
|
|
15
|
-
npm install -g
|
|
15
|
+
npm install -g archondev; archon
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
**What you get:**
|
|
@@ -124,6 +124,29 @@ This works similarly to how Claude Code allows subscription-based access. We're
|
|
|
124
124
|
3. **Changes Are Validated** — Quality gates check code before it's applied
|
|
125
125
|
4. **Learnings Persist** — Insights saved for future sessions
|
|
126
126
|
|
|
127
|
+
## Cloud Execution
|
|
128
|
+
|
|
129
|
+
Run AI agents in the cloud — close your laptop and get a PR when it's done.
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# 1. Authenticate
|
|
133
|
+
archon login
|
|
134
|
+
|
|
135
|
+
# 2. Connect GitHub (one-time setup)
|
|
136
|
+
archon github connect # Opens browser for authorization
|
|
137
|
+
archon github status # Verify connection
|
|
138
|
+
|
|
139
|
+
# 3. Plan locally, execute in cloud
|
|
140
|
+
archon plan "add user settings page"
|
|
141
|
+
archon execute ATOM-001 --cloud
|
|
142
|
+
|
|
143
|
+
# 4. Check progress
|
|
144
|
+
archon cloud status # List all cloud executions
|
|
145
|
+
archon cloud logs <id> # View execution logs
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The cloud worker clones your repo, runs the Executor agent, creates a feature branch, and opens a PR. You can close your terminal after queuing.
|
|
149
|
+
|
|
127
150
|
## Working with Existing Projects
|
|
128
151
|
|
|
129
152
|
Have a project created by another AI agent? ArchonDev can review it first, then govern future changes.
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-M4LGRTLC.js";
|
|
5
5
|
import {
|
|
6
6
|
loadAtom
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-RCW22YNI.js";
|
|
8
8
|
import {
|
|
9
9
|
transitionAtom
|
|
10
10
|
} from "./chunk-5IQKC2TD.js";
|
|
@@ -4815,7 +4815,7 @@ function createPrompt() {
|
|
|
4815
4815
|
}
|
|
4816
4816
|
async function execute(atomId, options) {
|
|
4817
4817
|
if (options.parallel && options.parallel.length > 0) {
|
|
4818
|
-
const { parallelExecute } = await import("./parallel-
|
|
4818
|
+
const { parallelExecute } = await import("./parallel-5WJAXTYL.js");
|
|
4819
4819
|
const allAtomIds = [atomId, ...options.parallel];
|
|
4820
4820
|
await parallelExecute(allAtomIds);
|
|
4821
4821
|
return;
|
|
@@ -4928,9 +4928,9 @@ Repository: ${repoUrl}`));
|
|
|
4928
4928
|
});
|
|
4929
4929
|
if (conflictReport.hasConflicts) {
|
|
4930
4930
|
console.log(chalk3.yellow(`
|
|
4931
|
-
|
|
4931
|
+
[!] ${conflictReport.conflicts.length} conflict(s) detected:`));
|
|
4932
4932
|
for (const conflict of conflictReport.conflicts) {
|
|
4933
|
-
const icon = conflict.severity === "BLOCKER" ? chalk3.red("\u2717") : chalk3.yellow("
|
|
4933
|
+
const icon = conflict.severity === "BLOCKER" ? chalk3.red("\u2717") : chalk3.yellow("[!]");
|
|
4934
4934
|
console.log(` ${icon} [${conflict.type}] ${conflict.message}`);
|
|
4935
4935
|
}
|
|
4936
4936
|
if (conflictReport.blockerCount > 0) {
|
|
@@ -5051,7 +5051,7 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5051
5051
|
if (learningResult.success && learningResult.entriesAdded > 0) {
|
|
5052
5052
|
console.log(chalk3.green("\u2713 Learning captured to progress.txt"));
|
|
5053
5053
|
} else {
|
|
5054
|
-
console.log(chalk3.yellow("
|
|
5054
|
+
console.log(chalk3.yellow("[!] No learnings captured to progress.txt"));
|
|
5055
5055
|
}
|
|
5056
5056
|
}
|
|
5057
5057
|
const agentsMdUpdater = new AgentsMdUpdater(cwd);
|
|
@@ -5059,7 +5059,7 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5059
5059
|
if (verifyLearning) {
|
|
5060
5060
|
const agentsMdCount = agentsMdResult.filesCreated.length + agentsMdResult.filesUpdated.length;
|
|
5061
5061
|
if (agentsMdCount === 0) {
|
|
5062
|
-
console.log(chalk3.yellow("
|
|
5062
|
+
console.log(chalk3.yellow("[!] No AGENTS.md updates (no reusable patterns found)"));
|
|
5063
5063
|
} else {
|
|
5064
5064
|
console.log(chalk3.green(`\u2713 Updated ${agentsMdCount} AGENTS.md file(s)`));
|
|
5065
5065
|
}
|
|
@@ -636,7 +636,7 @@ async function displayCurrentSettings(profile, usage, providers) {
|
|
|
636
636
|
console.log(` Secondary: ${formatModelDisplay(profile.pref_secondary_adversarial, defaults.secondary)}`);
|
|
637
637
|
}
|
|
638
638
|
async function changeBillingMode(currentTier) {
|
|
639
|
-
console.log(chalk.bold("\n
|
|
639
|
+
console.log(chalk.bold("\n-- Billing Mode --\n"));
|
|
640
640
|
console.log(chalk.dim("Choose how you want to pay for AI usage:\n"));
|
|
641
641
|
const byokSelected = currentTier === "BYOK";
|
|
642
642
|
const creditsSelected = currentTier === "CREDITS";
|
|
@@ -673,7 +673,7 @@ async function changeBillingMode(currentTier) {
|
|
|
673
673
|
}
|
|
674
674
|
}
|
|
675
675
|
async function setDefaultModelsMenu(profile, providers) {
|
|
676
|
-
console.log(chalk.bold("\n
|
|
676
|
+
console.log(chalk.bold("\n-- Default Models --\n"));
|
|
677
677
|
const defaults = getDefaultAdversarialModels();
|
|
678
678
|
console.log(` ${chalk.cyan("1")}) Fast Model: ${formatModelDisplay(profile.pref_fast_model, getDefaultModel("fast"))}`);
|
|
679
679
|
console.log(` ${chalk.cyan("2")}) Thinking Model: ${formatModelDisplay(profile.pref_thinking_model, getDefaultModel("thinking"))}`);
|
|
@@ -723,7 +723,7 @@ async function setDefaultModelsMenu(profile, providers) {
|
|
|
723
723
|
}
|
|
724
724
|
}
|
|
725
725
|
async function manageApiKeys() {
|
|
726
|
-
console.log(chalk.bold("\n
|
|
726
|
+
console.log(chalk.bold("\n-- API Keys --\n"));
|
|
727
727
|
const providers = await getUserProviders();
|
|
728
728
|
if (providers.length > 0) {
|
|
729
729
|
console.log(chalk.blue("Configured providers:"));
|
|
@@ -772,7 +772,7 @@ async function manageApiKeys() {
|
|
|
772
772
|
}
|
|
773
773
|
}
|
|
774
774
|
async function viewUsageDetails() {
|
|
775
|
-
console.log(chalk.bold("\n
|
|
775
|
+
console.log(chalk.bold("\n-- Usage Details --\n"));
|
|
776
776
|
const spinner = ora("Loading usage data...").start();
|
|
777
777
|
const config = await loadConfig();
|
|
778
778
|
const authToken = getAuthToken(config);
|
|
@@ -433,7 +433,7 @@ async function bugReport(title, options) {
|
|
|
433
433
|
const prompt = createPrompt();
|
|
434
434
|
const projectPath = process.cwd();
|
|
435
435
|
try {
|
|
436
|
-
console.log(chalk.blue("\
|
|
436
|
+
console.log(chalk.blue("\nBug Report: ") + chalk.bold(title));
|
|
437
437
|
console.log(chalk.dim("\u2500".repeat(40)));
|
|
438
438
|
const description = await prompt.ask(chalk.cyan("Description: "));
|
|
439
439
|
console.log(chalk.cyan("Steps to reproduce (enter each step, empty line to finish):"));
|
|
@@ -501,11 +501,11 @@ async function bugReport(title, options) {
|
|
|
501
501
|
}
|
|
502
502
|
} catch (error) {
|
|
503
503
|
console.log(chalk.yellow(`
|
|
504
|
-
|
|
504
|
+
[!] RCA generation failed: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
505
505
|
console.log(chalk.dim("Continuing without RCA..."));
|
|
506
506
|
}
|
|
507
507
|
} else {
|
|
508
|
-
console.log(chalk.yellow("\n
|
|
508
|
+
console.log(chalk.yellow("\n[!] No API key configured. Skipping RCA."));
|
|
509
509
|
console.log(chalk.dim('Set ANTHROPIC_API_KEY or use "archon keys add anthropic"'));
|
|
510
510
|
}
|
|
511
511
|
}
|
|
@@ -534,7 +534,7 @@ async function bugReport(title, options) {
|
|
|
534
534
|
console.log(chalk.green(`
|
|
535
535
|
\u2705 Atom created: ${atom.externalId}`));
|
|
536
536
|
console.log(chalk.dim(` Linked to: ${bug.id}`));
|
|
537
|
-
console.log(chalk.bold("\
|
|
537
|
+
console.log(chalk.bold("\nSummary"));
|
|
538
538
|
console.log(chalk.dim("\u2500".repeat(40)));
|
|
539
539
|
console.log(`Bug ID: ${chalk.cyan(bug.id)}`);
|
|
540
540
|
console.log(`Atom ID: ${chalk.cyan(atom.externalId)}`);
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
// src/cli/init.ts
|
|
2
2
|
import { readdir, readFile, writeFile, mkdir } from "fs/promises";
|
|
3
|
-
import { existsSync } from "fs";
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
4
|
import { join, extname } from "path";
|
|
5
5
|
import { execSync } from "child_process";
|
|
6
6
|
import chalk from "chalk";
|
|
7
7
|
import ora from "ora";
|
|
8
8
|
import readline from "readline";
|
|
9
9
|
function isInitialized(cwd) {
|
|
10
|
-
const archMdPath = join(cwd, "ARCHITECTURE.md");
|
|
11
10
|
const archonDir = join(cwd, ".archon");
|
|
12
|
-
|
|
11
|
+
if (existsSync(archonDir)) return true;
|
|
12
|
+
const archMdPath = join(cwd, "ARCHITECTURE.md");
|
|
13
|
+
if (existsSync(archMdPath)) {
|
|
14
|
+
try {
|
|
15
|
+
const content = readFileSync(archMdPath, "utf-8");
|
|
16
|
+
return content.startsWith("---") && content.includes("version:") && content.includes("qualityLevel:");
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
13
22
|
}
|
|
14
23
|
var LANGUAGE_EXTENSIONS = {
|
|
15
24
|
".ts": "TypeScript",
|
|
@@ -48,7 +57,7 @@ async function init(options = {}) {
|
|
|
48
57
|
const cwd = process.cwd();
|
|
49
58
|
const archMdPath = join(cwd, "ARCHITECTURE.md");
|
|
50
59
|
const archonDir = join(cwd, ".archon");
|
|
51
|
-
console.log(chalk.blue("\n
|
|
60
|
+
console.log(chalk.blue("\n[INIT] ArchonDev Initialization\n"));
|
|
52
61
|
if (existsSync(archMdPath)) {
|
|
53
62
|
const overwrite = await promptYesNo("ARCHITECTURE.md already exists. Overwrite?", false);
|
|
54
63
|
if (!overwrite) {
|
|
@@ -21,7 +21,7 @@ function formatStatus(status) {
|
|
|
21
21
|
case "completed":
|
|
22
22
|
return chalk.green("\u2713 completed");
|
|
23
23
|
case "needs_fix":
|
|
24
|
-
return chalk.red("
|
|
24
|
+
return chalk.red("[!] needs_fix");
|
|
25
25
|
default:
|
|
26
26
|
return status;
|
|
27
27
|
}
|
|
@@ -448,7 +448,7 @@ async function reviewPlan() {
|
|
|
448
448
|
console.log(` ${task.fixPlan}`);
|
|
449
449
|
}
|
|
450
450
|
if (task.architectureImpact) {
|
|
451
|
-
console.log(chalk.yellow("
|
|
451
|
+
console.log(chalk.yellow(" [!] Architecture Impact:"));
|
|
452
452
|
console.log(` ${task.architectureImpact}`);
|
|
453
453
|
}
|
|
454
454
|
console.log();
|
|
@@ -397,7 +397,7 @@ Atom saved: ${atom.externalId}`));
|
|
|
397
397
|
console.log(chalk.dim(`Next: Configure API key and run "archon plan ${atom.externalId} --continue"`));
|
|
398
398
|
return;
|
|
399
399
|
}
|
|
400
|
-
console.log(chalk.blue("\
|
|
400
|
+
console.log(chalk.blue("\nStarting adversarial planning..."));
|
|
401
401
|
console.log(chalk.dim("Architect will generate a plan, Sentinel will validate it.\n"));
|
|
402
402
|
const planner = new AdversarialPlanner({ apiKey });
|
|
403
403
|
const planResult = await planner.planAtom(atom, parseResult.schema);
|
|
@@ -487,7 +487,7 @@ function displayPlan(plan2) {
|
|
|
487
487
|
if (plan2.risks.length > 0) {
|
|
488
488
|
console.log(chalk.bold("\nRisks:"));
|
|
489
489
|
for (const risk of plan2.risks) {
|
|
490
|
-
console.log(chalk.yellow(`
|
|
490
|
+
console.log(chalk.yellow(` [!] ${risk}`));
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
console.log(chalk.bold("\nComplexity:"), plan2.estimated_complexity);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadAtom
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-RCW22YNI.js";
|
|
4
4
|
|
|
5
5
|
// src/cli/parallel.ts
|
|
6
6
|
import chalk from "chalk";
|
|
@@ -155,7 +155,7 @@ async function parallelExecute(atomIds) {
|
|
|
155
155
|
const completed = state.executions.filter((e) => e.status === "completed").length;
|
|
156
156
|
const failed = state.executions.filter((e) => e.status === "failed").length;
|
|
157
157
|
console.log(chalk.blue(`
|
|
158
|
-
|
|
158
|
+
Parallel execution complete:`));
|
|
159
159
|
console.log(chalk.green(` \u2713 Completed: ${completed}`));
|
|
160
160
|
if (failed > 0) {
|
|
161
161
|
console.log(chalk.red(` \u2717 Failed: ${failed}`));
|
|
@@ -171,7 +171,7 @@ async function parallelStatus() {
|
|
|
171
171
|
console.log(chalk.dim("No parallel executions found."));
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
console.log(chalk.blue("\
|
|
174
|
+
console.log(chalk.blue("\nParallel Execution Status\n"));
|
|
175
175
|
for (const execution of state.executions) {
|
|
176
176
|
const statusIcon = execution.status === "completed" ? chalk.green("\u2713") : execution.status === "failed" ? chalk.red("\u2717") : execution.status === "running" ? chalk.yellow("\u25CF") : chalk.dim("\u25CB");
|
|
177
177
|
console.log(`${statusIcon} ${execution.atomId}`);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
execute
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3NPZQOK2.js";
|
|
4
4
|
import "./chunk-M4LGRTLC.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-RCW22YNI.js";
|
|
6
6
|
import "./chunk-5IQKC2TD.js";
|
|
7
7
|
import "./chunk-A7QU6JC6.js";
|
|
8
8
|
import "./chunk-SMR7JQK6.js";
|
package/dist/index.js
CHANGED
|
@@ -7,13 +7,13 @@ import {
|
|
|
7
7
|
cloudLogs,
|
|
8
8
|
cloudStatus,
|
|
9
9
|
execute
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3NPZQOK2.js";
|
|
11
11
|
import {
|
|
12
12
|
list
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-TEY4GCMH.js";
|
|
14
14
|
import {
|
|
15
15
|
bugReport
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-KF6MFAB4.js";
|
|
17
17
|
import {
|
|
18
18
|
addKey,
|
|
19
19
|
listKeys,
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
reviewShow,
|
|
32
32
|
reviewStatus,
|
|
33
33
|
reviewUpdate
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-QSYKKPFF.js";
|
|
35
35
|
import "./chunk-VKM3HAHW.js";
|
|
36
36
|
import {
|
|
37
37
|
listModels,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
setPreference,
|
|
41
41
|
showExecutionPreferences,
|
|
42
42
|
showPreferences
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-E2M23XSZ.js";
|
|
44
44
|
import {
|
|
45
45
|
login,
|
|
46
46
|
logout,
|
|
@@ -54,17 +54,17 @@ import {
|
|
|
54
54
|
import {
|
|
55
55
|
init,
|
|
56
56
|
isInitialized
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-P666JE3G.js";
|
|
58
58
|
import {
|
|
59
59
|
parallelClean,
|
|
60
60
|
parallelMerge,
|
|
61
61
|
parallelStatus
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-TSSFMB6E.js";
|
|
63
63
|
import {
|
|
64
64
|
listLocalAtoms,
|
|
65
65
|
loadAtom,
|
|
66
66
|
plan
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-RCW22YNI.js";
|
|
68
68
|
import {
|
|
69
69
|
ArchitectAgent
|
|
70
70
|
} from "./chunk-5IQKC2TD.js";
|
|
@@ -212,7 +212,7 @@ async function show(atomId) {
|
|
|
212
212
|
console.log("");
|
|
213
213
|
console.log(chalk2.bold("Risks:"));
|
|
214
214
|
for (const risk of atom.plan.risks) {
|
|
215
|
-
console.log(chalk2.yellow(`
|
|
215
|
+
console.log(chalk2.yellow(` [!] ${risk}`));
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
console.log("");
|
|
@@ -418,6 +418,14 @@ var PROGRESS_FILE = "progress.txt";
|
|
|
418
418
|
var ARCHON_DIR = ".archon";
|
|
419
419
|
var CACHE_DIR = ".archon/cache";
|
|
420
420
|
var ARCHIVE_DIR = "docs/archive";
|
|
421
|
+
var DEFAULT_THRESHOLDS = {
|
|
422
|
+
progressMaxLines: 500,
|
|
423
|
+
progressMaxKb: 100,
|
|
424
|
+
archonDirMaxMb: 10,
|
|
425
|
+
progressArchiveDays: 30,
|
|
426
|
+
cacheRetentionDays: 7,
|
|
427
|
+
cloudLogRetentionDays: 30
|
|
428
|
+
};
|
|
421
429
|
function formatBytes(bytes) {
|
|
422
430
|
if (bytes === 0) return "0 B";
|
|
423
431
|
const k = 1024;
|
|
@@ -446,17 +454,30 @@ function getDirSize(dirPath) {
|
|
|
446
454
|
return totalSize;
|
|
447
455
|
}
|
|
448
456
|
async function loadCleanupConfig(cwd) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
457
|
+
let cleanup = void 0;
|
|
458
|
+
const projectConfigPath = join3(cwd, "archon.config.yaml");
|
|
459
|
+
if (existsSync3(projectConfigPath)) {
|
|
460
|
+
try {
|
|
461
|
+
const content = await readFile3(projectConfigPath, "utf-8");
|
|
462
|
+
const config = yaml.parse(content);
|
|
463
|
+
if (config.cleanup) {
|
|
464
|
+
cleanup = config.cleanup;
|
|
465
|
+
}
|
|
466
|
+
} catch {
|
|
467
|
+
}
|
|
452
468
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
469
|
+
const localConfigPath = join3(cwd, CONFIG_PATH);
|
|
470
|
+
if (existsSync3(localConfigPath)) {
|
|
471
|
+
try {
|
|
472
|
+
const content = await readFile3(localConfigPath, "utf-8");
|
|
473
|
+
const config = yaml.parse(content);
|
|
474
|
+
if (config.cleanup) {
|
|
475
|
+
cleanup = { ...cleanup, ...config.cleanup };
|
|
476
|
+
}
|
|
477
|
+
} catch {
|
|
478
|
+
}
|
|
459
479
|
}
|
|
480
|
+
return cleanup;
|
|
460
481
|
}
|
|
461
482
|
async function saveCleanupConfig(cwd, cleanup) {
|
|
462
483
|
const configPath = join3(cwd, CONFIG_PATH);
|
|
@@ -562,16 +583,19 @@ async function parseProgressEntries(content) {
|
|
|
562
583
|
async function cleanupCheck() {
|
|
563
584
|
const cwd = process.cwd();
|
|
564
585
|
const results = [];
|
|
586
|
+
const config = await loadCleanupConfig(cwd);
|
|
587
|
+
const progressMaxKb = config?.progressMaxKb ?? DEFAULT_THRESHOLDS.progressMaxKb;
|
|
588
|
+
const archonDirMaxMb = config?.archonDirMaxMb ?? DEFAULT_THRESHOLDS.archonDirMaxMb;
|
|
565
589
|
console.log(chalk3.blue("\n\u{1F50D} Analyzing workspace for maintenance needs...\n"));
|
|
566
590
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
567
591
|
if (existsSync3(progressPath)) {
|
|
568
592
|
const size = statSync(progressPath).size;
|
|
569
593
|
let status2 = "ok";
|
|
570
594
|
let recommendation;
|
|
571
|
-
if (size >
|
|
595
|
+
if (size > progressMaxKb * 2 * 1024) {
|
|
572
596
|
status2 = "critical";
|
|
573
597
|
recommendation = "Archive old entries with: archon cleanup run";
|
|
574
|
-
} else if (size >
|
|
598
|
+
} else if (size > progressMaxKb * 1024) {
|
|
575
599
|
status2 = "warn";
|
|
576
600
|
recommendation = "Consider archiving entries older than 30 days";
|
|
577
601
|
}
|
|
@@ -588,7 +612,7 @@ async function cleanupCheck() {
|
|
|
588
612
|
const size = getDirSize(archonPath);
|
|
589
613
|
let status2 = "ok";
|
|
590
614
|
let recommendation;
|
|
591
|
-
if (size >
|
|
615
|
+
if (size > archonDirMaxMb * 1024 * 1024) {
|
|
592
616
|
status2 = "warn";
|
|
593
617
|
recommendation = "Clear stale cache files with: archon cleanup run";
|
|
594
618
|
}
|
|
@@ -662,13 +686,17 @@ async function cleanupRun() {
|
|
|
662
686
|
const cwd = process.cwd();
|
|
663
687
|
const results = [];
|
|
664
688
|
let totalSaved = 0;
|
|
689
|
+
const config = await loadCleanupConfig(cwd);
|
|
690
|
+
const progressArchiveDays = config?.progressArchiveDays ?? DEFAULT_THRESHOLDS.progressArchiveDays;
|
|
691
|
+
const cacheRetentionDays = config?.cacheRetentionDays ?? DEFAULT_THRESHOLDS.cacheRetentionDays;
|
|
692
|
+
const cloudLogRetentionDays = config?.cloudLogRetentionDays ?? DEFAULT_THRESHOLDS.cloudLogRetentionDays;
|
|
665
693
|
console.log(chalk3.blue("\n\u{1F9F9} Running workspace cleanup...\n"));
|
|
666
694
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
667
695
|
if (existsSync3(progressPath)) {
|
|
668
696
|
const content = await readFile3(progressPath, "utf-8");
|
|
669
697
|
const entries = await parseProgressEntries(content);
|
|
670
698
|
const cutoffDate = /* @__PURE__ */ new Date();
|
|
671
|
-
cutoffDate.setDate(cutoffDate.getDate() -
|
|
699
|
+
cutoffDate.setDate(cutoffDate.getDate() - progressArchiveDays);
|
|
672
700
|
const oldEntries = entries.filter((e) => e.date < cutoffDate);
|
|
673
701
|
const recentEntries = entries.filter((e) => e.date >= cutoffDate);
|
|
674
702
|
if (oldEntries.length > 0) {
|
|
@@ -713,7 +741,7 @@ async function cleanupRun() {
|
|
|
713
741
|
}
|
|
714
742
|
const cachePath = join3(cwd, CACHE_DIR);
|
|
715
743
|
if (existsSync3(cachePath)) {
|
|
716
|
-
const staleCache = await getStaleFiles(cachePath,
|
|
744
|
+
const staleCache = await getStaleFiles(cachePath, cacheRetentionDays);
|
|
717
745
|
let cacheSaved = 0;
|
|
718
746
|
for (const file of staleCache) {
|
|
719
747
|
try {
|
|
@@ -734,7 +762,7 @@ async function cleanupRun() {
|
|
|
734
762
|
}
|
|
735
763
|
const cloudLogsPath = join3(cwd, ".archon", "cloud-logs");
|
|
736
764
|
if (existsSync3(cloudLogsPath)) {
|
|
737
|
-
const staleLogs = await getStaleFiles(cloudLogsPath,
|
|
765
|
+
const staleLogs = await getStaleFiles(cloudLogsPath, cloudLogRetentionDays);
|
|
738
766
|
let logsSaved = 0;
|
|
739
767
|
for (const file of staleLogs) {
|
|
740
768
|
try {
|
|
@@ -818,16 +846,19 @@ async function shouldRunAutoCleanup(cwd) {
|
|
|
818
846
|
async function runAutoCleanupCheck(cwd) {
|
|
819
847
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
820
848
|
const archonPath = join3(cwd, ARCHON_DIR);
|
|
849
|
+
const config = await loadCleanupConfig(cwd);
|
|
850
|
+
const progressMaxKb = config?.progressMaxKb ?? DEFAULT_THRESHOLDS.progressMaxKb;
|
|
851
|
+
const archonDirMaxMb = config?.archonDirMaxMb ?? DEFAULT_THRESHOLDS.archonDirMaxMb;
|
|
821
852
|
let needsAttention = false;
|
|
822
853
|
if (existsSync3(progressPath)) {
|
|
823
854
|
const size = statSync(progressPath).size;
|
|
824
|
-
if (size >
|
|
855
|
+
if (size > progressMaxKb * 1024) {
|
|
825
856
|
needsAttention = true;
|
|
826
857
|
}
|
|
827
858
|
}
|
|
828
859
|
if (existsSync3(archonPath)) {
|
|
829
860
|
const size = getDirSize(archonPath);
|
|
830
|
-
if (size >
|
|
861
|
+
if (size > archonDirMaxMb * 1024 * 1024) {
|
|
831
862
|
needsAttention = true;
|
|
832
863
|
}
|
|
833
864
|
}
|
|
@@ -839,15 +870,16 @@ async function runAutoCleanupCheck(cwd) {
|
|
|
839
870
|
}
|
|
840
871
|
|
|
841
872
|
// src/cli/start.ts
|
|
842
|
-
async function start() {
|
|
873
|
+
async function start(options = {}) {
|
|
843
874
|
const cwd = process.cwd();
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
875
|
+
if (!options.skipGovernanceBanner) {
|
|
876
|
+
console.log(chalk4.bold.white("\nArchonDev - AI-Powered Development Governance"));
|
|
877
|
+
console.log(chalk4.blue("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
878
|
+
}
|
|
847
879
|
const contextManager = new ContextManager();
|
|
848
880
|
const pendingAtomsData = await contextManager.getPendingAtomsData(cwd);
|
|
849
881
|
if (pendingAtomsData && pendingAtomsData.atoms.length > 0) {
|
|
850
|
-
console.log(chalk4.yellow("
|
|
882
|
+
console.log(chalk4.yellow("[!] Previous session had pending atoms:\n"));
|
|
851
883
|
for (const atomId of pendingAtomsData.atoms) {
|
|
852
884
|
console.log(chalk4.dim(` \u2022 ${atomId}`));
|
|
853
885
|
}
|
|
@@ -868,8 +900,10 @@ async function start() {
|
|
|
868
900
|
}
|
|
869
901
|
}
|
|
870
902
|
const projectState = detectProjectState(cwd);
|
|
871
|
-
|
|
872
|
-
|
|
903
|
+
if (!options.skipGovernanceBanner) {
|
|
904
|
+
const governanceStatus = await gatherGovernanceStatus(cwd);
|
|
905
|
+
displayGovernanceBanner(governanceStatus);
|
|
906
|
+
}
|
|
873
907
|
if (await shouldRunAutoCleanup(cwd)) {
|
|
874
908
|
await runAutoCleanupCheck(cwd);
|
|
875
909
|
}
|
|
@@ -998,15 +1032,14 @@ async function gatherGovernanceStatus(cwd) {
|
|
|
998
1032
|
return status2;
|
|
999
1033
|
}
|
|
1000
1034
|
function displayGovernanceBanner(status2) {
|
|
1001
|
-
console.log(chalk4.
|
|
1002
|
-
console.log(chalk4.
|
|
1003
|
-
console.log(chalk4.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
|
|
1035
|
+
console.log(chalk4.bold.white("Governance Status"));
|
|
1036
|
+
console.log(chalk4.blue("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
1004
1037
|
if (status2.hasArchitecture) {
|
|
1005
1038
|
console.log(chalk4.green(" \u2713") + ` ARCHITECTURE.md loaded (${status2.posture} posture)`);
|
|
1006
1039
|
console.log(chalk4.green(" \u2713") + ` ${status2.invariantsCount} invariants enforced`);
|
|
1007
1040
|
console.log(chalk4.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths defined`);
|
|
1008
1041
|
} else {
|
|
1009
|
-
console.log(chalk4.yellow("
|
|
1042
|
+
console.log(chalk4.yellow(" [!]") + " ARCHITECTURE.md not found - run " + chalk4.cyan("archon init"));
|
|
1010
1043
|
}
|
|
1011
1044
|
console.log(chalk4.green(" \u2713") + ` ${status2.dependencyRulesCount} dependency rules active`);
|
|
1012
1045
|
if (status2.lastSessionDate) {
|
|
@@ -1016,10 +1049,10 @@ function displayGovernanceBanner(status2) {
|
|
|
1016
1049
|
console.log();
|
|
1017
1050
|
console.log(chalk4.cyan(` Pending: ${status2.pendingAtomsCount} atoms ready for execution`));
|
|
1018
1051
|
}
|
|
1019
|
-
console.log(
|
|
1052
|
+
console.log();
|
|
1020
1053
|
}
|
|
1021
1054
|
async function handleNewProject(cwd, state) {
|
|
1022
|
-
console.log(chalk4.
|
|
1055
|
+
console.log(chalk4.bold("Starting a new project? Great!\n"));
|
|
1023
1056
|
console.log(chalk4.dim("I'll ask you a few quick questions to set things up right."));
|
|
1024
1057
|
console.log(chalk4.dim("Answer as much or as little as you want \u2014 you can always refine later.\n"));
|
|
1025
1058
|
console.log(chalk4.bold("What would you like to do?\n"));
|
|
@@ -1048,7 +1081,7 @@ async function handleNewProject(cwd, state) {
|
|
|
1048
1081
|
}
|
|
1049
1082
|
}
|
|
1050
1083
|
async function runNewProjectInterview(cwd) {
|
|
1051
|
-
console.log(chalk4.blue("\n
|
|
1084
|
+
console.log(chalk4.blue("\n-- Project Interview --\n"));
|
|
1052
1085
|
console.log(chalk4.bold("Phase 1: The Vision\n"));
|
|
1053
1086
|
const projectName = await prompt("What's the project name?");
|
|
1054
1087
|
const projectDescription = await prompt("In one sentence, what does this project do?");
|
|
@@ -1079,8 +1112,8 @@ async function runNewProjectInterview(cwd) {
|
|
|
1079
1112
|
console.log(chalk4.bold("\nPhase 3: Preferences ") + chalk4.dim("(press Enter to skip)\n"));
|
|
1080
1113
|
const protectedFiles = await prompt("Any files AI should NEVER modify without asking? (comma-separated)");
|
|
1081
1114
|
const noNoPatterns = await prompt('Anything AI should NEVER do? (e.g., "no console.log")');
|
|
1082
|
-
console.log(chalk4.blue("\n
|
|
1083
|
-
const { init: init2 } = await import("./init-
|
|
1115
|
+
console.log(chalk4.blue("\n-- Generating Project Files --\n"));
|
|
1116
|
+
const { init: init2 } = await import("./init-6EXMDCWC.js");
|
|
1084
1117
|
await init2({ analyze: false, git: true });
|
|
1085
1118
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1086
1119
|
const progressEntry = `
|
|
@@ -1120,14 +1153,14 @@ ${noNoPatterns ? `- **Forbidden patterns:** ${noNoPatterns}` : "- No forbidden p
|
|
|
1120
1153
|
if (continueChoice) {
|
|
1121
1154
|
const description = await prompt("Describe what you want to build first");
|
|
1122
1155
|
if (description.trim()) {
|
|
1123
|
-
const { plan: plan2 } = await import("./plan-
|
|
1156
|
+
const { plan: plan2 } = await import("./plan-W2UXAR6E.js");
|
|
1124
1157
|
await plan2(description, {});
|
|
1125
1158
|
}
|
|
1126
1159
|
}
|
|
1127
1160
|
}
|
|
1128
1161
|
async function quickStart(cwd) {
|
|
1129
1162
|
console.log(chalk4.blue("\n\u2501\u2501\u2501 Quick Start \u2501\u2501\u2501\n"));
|
|
1130
|
-
const { init: init2 } = await import("./init-
|
|
1163
|
+
const { init: init2 } = await import("./init-6EXMDCWC.js");
|
|
1131
1164
|
await init2({ analyze: false, git: true });
|
|
1132
1165
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1133
1166
|
const progressPath = join4(cwd, "progress.txt");
|
|
@@ -1186,7 +1219,7 @@ async function handleAdaptExisting(cwd, state) {
|
|
|
1186
1219
|
}
|
|
1187
1220
|
async function analyzeAndAdapt(cwd) {
|
|
1188
1221
|
console.log(chalk4.blue("\n\u2501\u2501\u2501 Analyzing Project \u2501\u2501\u2501\n"));
|
|
1189
|
-
const { init: init2 } = await import("./init-
|
|
1222
|
+
const { init: init2 } = await import("./init-6EXMDCWC.js");
|
|
1190
1223
|
await init2({ analyze: true, git: true });
|
|
1191
1224
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1192
1225
|
const progressPath = join4(cwd, "progress.txt");
|
|
@@ -1213,7 +1246,7 @@ async function analyzeAndAdapt(cwd) {
|
|
|
1213
1246
|
async function codeReviewFirst(cwd) {
|
|
1214
1247
|
console.log(chalk4.blue("\n\u2501\u2501\u2501 Code Review Mode \u2501\u2501\u2501\n"));
|
|
1215
1248
|
console.log(chalk4.dim("I'll analyze your code for issues without making any changes.\n"));
|
|
1216
|
-
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-
|
|
1249
|
+
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-QV4TQM2Z.js");
|
|
1217
1250
|
const reviewDbPath = join4(cwd, "docs", "code-review", "review-tasks.db");
|
|
1218
1251
|
if (!existsSync4(reviewDbPath)) {
|
|
1219
1252
|
await reviewInit2();
|
|
@@ -1228,7 +1261,7 @@ async function codeReviewFirst(cwd) {
|
|
|
1228
1261
|
async function manualSetup(cwd) {
|
|
1229
1262
|
console.log(chalk4.blue("\n\u2501\u2501\u2501 Manual Setup \u2501\u2501\u2501\n"));
|
|
1230
1263
|
console.log(chalk4.dim("Creating template files. You can customize them manually.\n"));
|
|
1231
|
-
const { init: init2 } = await import("./init-
|
|
1264
|
+
const { init: init2 } = await import("./init-6EXMDCWC.js");
|
|
1232
1265
|
await init2({ analyze: false, git: true });
|
|
1233
1266
|
console.log(chalk4.bold("\nWhat to customize:\n"));
|
|
1234
1267
|
console.log(` ${chalk4.cyan("1. ARCHITECTURE.md")} \u2014 Update components to match your folders`);
|
|
@@ -1238,8 +1271,8 @@ async function manualSetup(cwd) {
|
|
|
1238
1271
|
await showMainMenu();
|
|
1239
1272
|
}
|
|
1240
1273
|
async function quickAdapt(cwd) {
|
|
1241
|
-
console.log(chalk4.blue("\n
|
|
1242
|
-
const { init: init2 } = await import("./init-
|
|
1274
|
+
console.log(chalk4.blue("\n> Using defaults \u2014 let's go!\n"));
|
|
1275
|
+
const { init: init2 } = await import("./init-6EXMDCWC.js");
|
|
1243
1276
|
await init2({ analyze: true, git: true });
|
|
1244
1277
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
1245
1278
|
const progressPath = join4(cwd, "progress.txt");
|
|
@@ -1257,7 +1290,7 @@ async function quickAdapt(cwd) {
|
|
|
1257
1290
|
await showMainMenu();
|
|
1258
1291
|
}
|
|
1259
1292
|
async function handleContinueSession(cwd, state) {
|
|
1260
|
-
console.log(chalk4.
|
|
1293
|
+
console.log(chalk4.bold("Welcome back!\n"));
|
|
1261
1294
|
if (state.lastProgressEntry) {
|
|
1262
1295
|
console.log(chalk4.dim("Last activity:"));
|
|
1263
1296
|
console.log(chalk4.dim(" " + state.lastProgressEntry.split("\n")[0]));
|
|
@@ -1265,7 +1298,7 @@ async function handleContinueSession(cwd, state) {
|
|
|
1265
1298
|
}
|
|
1266
1299
|
const handoff = checkForHandoff(cwd);
|
|
1267
1300
|
if (handoff) {
|
|
1268
|
-
console.log(chalk4.yellow("
|
|
1301
|
+
console.log(chalk4.yellow("[HANDOFF] Found from last session:\n"));
|
|
1269
1302
|
console.log(chalk4.dim(handoff.nextSteps));
|
|
1270
1303
|
console.log();
|
|
1271
1304
|
const continueHandoff = await promptYesNo("Continue from handoff?", true);
|
|
@@ -1334,27 +1367,27 @@ async function showReviewProgress(cwd) {
|
|
|
1334
1367
|
const pending = stats.pending + stats.inReview;
|
|
1335
1368
|
const needsFix = stats.needsFix;
|
|
1336
1369
|
console.log(
|
|
1337
|
-
chalk4.blue("
|
|
1370
|
+
chalk4.blue("Review Progress:") + chalk4.dim(` ${completed}/${total} completed`) + (needsFix > 0 ? chalk4.red(` (${needsFix} need fixes)`) : "") + (pending > 0 ? chalk4.yellow(` (${pending} pending)`) : "")
|
|
1338
1371
|
);
|
|
1339
1372
|
console.log();
|
|
1340
1373
|
} catch {
|
|
1341
1374
|
}
|
|
1342
1375
|
}
|
|
1343
1376
|
async function planTask() {
|
|
1344
|
-
const { plan: plan2 } = await import("./plan-
|
|
1377
|
+
const { plan: plan2 } = await import("./plan-W2UXAR6E.js");
|
|
1345
1378
|
const description = await prompt("Describe what you want to build");
|
|
1346
1379
|
if (description.trim()) {
|
|
1347
1380
|
await plan2(description, {});
|
|
1348
1381
|
}
|
|
1349
1382
|
}
|
|
1350
1383
|
async function listAtoms() {
|
|
1351
|
-
const { list: list2 } = await import("./list-
|
|
1384
|
+
const { list: list2 } = await import("./list-LEFAISNL.js");
|
|
1352
1385
|
await list2({});
|
|
1353
1386
|
}
|
|
1354
1387
|
async function executeNext() {
|
|
1355
|
-
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-
|
|
1388
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-W2UXAR6E.js");
|
|
1356
1389
|
const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-X6LHSHBJ.js");
|
|
1357
|
-
const { loadExecutionPreferences } = await import("./preferences-
|
|
1390
|
+
const { loadExecutionPreferences } = await import("./preferences-ZJ4TX2RC.js");
|
|
1358
1391
|
const cwd = process.cwd();
|
|
1359
1392
|
const atoms = await listLocalAtoms2();
|
|
1360
1393
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
@@ -1365,7 +1398,7 @@ async function executeNext() {
|
|
|
1365
1398
|
if (pendingAtoms.length > 1) {
|
|
1366
1399
|
const analysis = analyzeProject(pendingAtoms);
|
|
1367
1400
|
const prefs = await loadExecutionPreferences(cwd);
|
|
1368
|
-
console.log(chalk4.blue("\n
|
|
1401
|
+
console.log(chalk4.blue("\n-- Project Analysis --\n"));
|
|
1369
1402
|
console.log(` ${chalk4.bold("Atoms:")} ${analysis.atomCount}`);
|
|
1370
1403
|
console.log(` ${chalk4.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
|
|
1371
1404
|
console.log(` ${chalk4.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
|
|
@@ -1387,14 +1420,14 @@ async function executeNext() {
|
|
|
1387
1420
|
const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
|
|
1388
1421
|
const targetId = atomId.trim() || pendingAtoms[0]?.id;
|
|
1389
1422
|
if (targetId) {
|
|
1390
|
-
const { execute: execute2 } = await import("./execute-
|
|
1423
|
+
const { execute: execute2 } = await import("./execute-5ZSLSWPZ.js");
|
|
1391
1424
|
await execute2(targetId, {});
|
|
1392
1425
|
} else {
|
|
1393
1426
|
console.log(chalk4.yellow("No atom to execute."));
|
|
1394
1427
|
}
|
|
1395
1428
|
}
|
|
1396
1429
|
async function reportBug() {
|
|
1397
|
-
const { bugReport: bugReport2 } = await import("./bug-
|
|
1430
|
+
const { bugReport: bugReport2 } = await import("./bug-K4V357B2.js");
|
|
1398
1431
|
const title = await prompt("Bug title");
|
|
1399
1432
|
if (title.trim()) {
|
|
1400
1433
|
await bugReport2(title, {});
|
|
@@ -1405,7 +1438,7 @@ async function viewStatus() {
|
|
|
1405
1438
|
await status2();
|
|
1406
1439
|
}
|
|
1407
1440
|
async function settingsMenu() {
|
|
1408
|
-
const { interactiveSettings } = await import("./preferences-
|
|
1441
|
+
const { interactiveSettings } = await import("./preferences-ZJ4TX2RC.js");
|
|
1409
1442
|
await interactiveSettings();
|
|
1410
1443
|
await showMainMenu();
|
|
1411
1444
|
}
|
|
@@ -1414,7 +1447,7 @@ async function reviewCode() {
|
|
|
1414
1447
|
const reviewDbPath = join4(cwd, "docs", "code-review", "review-tasks.db");
|
|
1415
1448
|
if (!existsSync4(reviewDbPath)) {
|
|
1416
1449
|
console.log(chalk4.dim("Code review not initialized. Starting setup...\n"));
|
|
1417
|
-
const { reviewInit: reviewInit2 } = await import("./review-
|
|
1450
|
+
const { reviewInit: reviewInit2 } = await import("./review-QV4TQM2Z.js");
|
|
1418
1451
|
await reviewInit2();
|
|
1419
1452
|
console.log();
|
|
1420
1453
|
}
|
|
@@ -1429,27 +1462,27 @@ async function reviewCode() {
|
|
|
1429
1462
|
const choice = await prompt("Enter choice");
|
|
1430
1463
|
switch (choice.toLowerCase()) {
|
|
1431
1464
|
case "1": {
|
|
1432
|
-
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-
|
|
1465
|
+
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-QV4TQM2Z.js");
|
|
1433
1466
|
await reviewAnalyze2();
|
|
1434
1467
|
break;
|
|
1435
1468
|
}
|
|
1436
1469
|
case "2": {
|
|
1437
|
-
const { reviewStatus: reviewStatus2 } = await import("./review-
|
|
1470
|
+
const { reviewStatus: reviewStatus2 } = await import("./review-QV4TQM2Z.js");
|
|
1438
1471
|
await reviewStatus2();
|
|
1439
1472
|
break;
|
|
1440
1473
|
}
|
|
1441
1474
|
case "3": {
|
|
1442
|
-
const { reviewNext: reviewNext2 } = await import("./review-
|
|
1475
|
+
const { reviewNext: reviewNext2 } = await import("./review-QV4TQM2Z.js");
|
|
1443
1476
|
await reviewNext2();
|
|
1444
1477
|
break;
|
|
1445
1478
|
}
|
|
1446
1479
|
case "4": {
|
|
1447
|
-
const { reviewList: reviewList2 } = await import("./review-
|
|
1480
|
+
const { reviewList: reviewList2 } = await import("./review-QV4TQM2Z.js");
|
|
1448
1481
|
await reviewList2({});
|
|
1449
1482
|
break;
|
|
1450
1483
|
}
|
|
1451
1484
|
case "5": {
|
|
1452
|
-
const { reviewRun: reviewRun2 } = await import("./review-
|
|
1485
|
+
const { reviewRun: reviewRun2 } = await import("./review-QV4TQM2Z.js");
|
|
1453
1486
|
await reviewRun2({ all: true });
|
|
1454
1487
|
break;
|
|
1455
1488
|
}
|
|
@@ -1630,7 +1663,7 @@ async function showHistory(options = {}) {
|
|
|
1630
1663
|
const usage = data;
|
|
1631
1664
|
spinner.stop();
|
|
1632
1665
|
console.log();
|
|
1633
|
-
console.log(chalk5.bold("
|
|
1666
|
+
console.log(chalk5.bold("Usage History"));
|
|
1634
1667
|
console.log();
|
|
1635
1668
|
if (!usage || usage.length === 0) {
|
|
1636
1669
|
console.log(chalk5.dim(" No usage recorded yet."));
|
|
@@ -1716,7 +1749,7 @@ async function manageBudget(options = {}) {
|
|
|
1716
1749
|
}
|
|
1717
1750
|
spinner.stop();
|
|
1718
1751
|
console.log();
|
|
1719
|
-
console.log(chalk5.bold("
|
|
1752
|
+
console.log(chalk5.bold("Monthly Budget"));
|
|
1720
1753
|
console.log();
|
|
1721
1754
|
if (profile.monthly_budget_cents === null) {
|
|
1722
1755
|
console.log(` Budget: ${chalk5.dim("No limit set")}`);
|
|
@@ -2164,7 +2197,7 @@ Examples:
|
|
|
2164
2197
|
process.exit(0);
|
|
2165
2198
|
}
|
|
2166
2199
|
console.log(chalk6.yellow(`
|
|
2167
|
-
|
|
2200
|
+
[!] Found ${result.impacts.length} dependency impact(s):
|
|
2168
2201
|
`));
|
|
2169
2202
|
for (const impact of result.impacts) {
|
|
2170
2203
|
const severityColor = impact.rule.severity === "BLOCKER" ? chalk6.red : impact.rule.severity === "WARNING" ? chalk6.yellow : chalk6.blue;
|
|
@@ -2485,7 +2518,7 @@ async function a11yCheck(options) {
|
|
|
2485
2518
|
console.log(chalk7.dim("Note: Run manual testing with screen readers for full compliance.\n"));
|
|
2486
2519
|
return;
|
|
2487
2520
|
}
|
|
2488
|
-
console.log(chalk7.red(
|
|
2521
|
+
console.log(chalk7.red(`[!] ${issues.length} Accessibility Issues Found
|
|
2489
2522
|
`));
|
|
2490
2523
|
const criticalCount = issues.filter((i) => i.severity === "critical").length;
|
|
2491
2524
|
const majorCount = issues.filter((i) => i.severity === "major").length;
|
|
@@ -2513,7 +2546,7 @@ async function a11yCheck(options) {
|
|
|
2513
2546
|
}
|
|
2514
2547
|
console.log();
|
|
2515
2548
|
}
|
|
2516
|
-
console.log(chalk7.bold.yellow("\n
|
|
2549
|
+
console.log(chalk7.bold.yellow("\n[LEGAL] Notice\n"));
|
|
2517
2550
|
console.log(chalk7.dim("Websites that don't meet accessibility standards may violate:"));
|
|
2518
2551
|
console.log(chalk7.dim(" \u2022 ADA (Americans with Disabilities Act) \u2014 US"));
|
|
2519
2552
|
console.log(chalk7.dim(" \u2022 EAA (European Accessibility Act) \u2014 EU, effective June 2025"));
|
|
@@ -2642,7 +2675,7 @@ async function a11yBadge(options) {
|
|
|
2642
2675
|
async function a11yPreDeploy() {
|
|
2643
2676
|
const prompt2 = createPrompt();
|
|
2644
2677
|
try {
|
|
2645
|
-
console.log(chalk7.blue("\n
|
|
2678
|
+
console.log(chalk7.blue("\n[CHECK] Pre-Deploy Accessibility\n"));
|
|
2646
2679
|
console.log(chalk7.dim("Before deploying a live website, accessibility compliance is required.\n"));
|
|
2647
2680
|
await a11yCheck({});
|
|
2648
2681
|
const reportPath = join6(process.cwd(), ".archon/a11y-report.json");
|
|
@@ -2668,7 +2701,7 @@ async function a11yPreDeploy() {
|
|
|
2668
2701
|
await a11yCheck({});
|
|
2669
2702
|
return true;
|
|
2670
2703
|
} else if (choice === "2") {
|
|
2671
|
-
console.log(chalk7.yellow("\n
|
|
2704
|
+
console.log(chalk7.yellow("\n[!] Acknowledged. Proceeding without full accessibility compliance."));
|
|
2672
2705
|
console.log(chalk7.dim("Consider addressing these issues in a future session.\n"));
|
|
2673
2706
|
return true;
|
|
2674
2707
|
} else {
|
|
@@ -2809,7 +2842,7 @@ async function geoIdentity() {
|
|
|
2809
2842
|
console.log(chalk8.blue("\n\u{1F3AF} GEO Identity Generator\n"));
|
|
2810
2843
|
const { allowed, tier } = await checkStrongModelAccess();
|
|
2811
2844
|
if (!allowed) {
|
|
2812
|
-
console.log(chalk8.yellow(
|
|
2845
|
+
console.log(chalk8.yellow(`[!] Your tier (${tier}) uses basic models.`));
|
|
2813
2846
|
console.log(chalk8.dim("For better results, add credits or use BYOK mode.\n"));
|
|
2814
2847
|
}
|
|
2815
2848
|
console.log(chalk8.dim("Reading homepage and about page content...\n"));
|
|
@@ -2989,7 +3022,7 @@ async function geoFaq(options) {
|
|
|
2989
3022
|
const { identityPhrase, shortDescription } = config.geo;
|
|
2990
3023
|
const { allowed, tier } = await checkStrongModelAccess();
|
|
2991
3024
|
if (!allowed) {
|
|
2992
|
-
console.log(chalk8.yellow(
|
|
3025
|
+
console.log(chalk8.yellow(`[!] Your tier (${tier}) uses basic models.`));
|
|
2993
3026
|
console.log(chalk8.dim("For better results, add credits or use BYOK mode.\n"));
|
|
2994
3027
|
}
|
|
2995
3028
|
console.log(chalk8.dim("Generating FAQ content with AI...\n"));
|
|
@@ -3072,7 +3105,7 @@ async function geoAudit() {
|
|
|
3072
3105
|
console.log(chalk8.green("\u2705 Brand keyword in H1"));
|
|
3073
3106
|
} else {
|
|
3074
3107
|
result.issues.push("Brand phrase keyword not found in H1");
|
|
3075
|
-
console.log(chalk8.yellow("
|
|
3108
|
+
console.log(chalk8.yellow("[!] Brand keyword not in H1"));
|
|
3076
3109
|
}
|
|
3077
3110
|
const metaMatch = content.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']*)["']/i);
|
|
3078
3111
|
if (metaMatch?.[1] && metaMatch[1].toLowerCase().includes(firstKeyword)) {
|
|
@@ -3080,7 +3113,7 @@ async function geoAudit() {
|
|
|
3080
3113
|
console.log(chalk8.green("\u2705 Brand keyword in meta description"));
|
|
3081
3114
|
} else {
|
|
3082
3115
|
result.issues.push("Brand phrase keyword not found in meta description");
|
|
3083
|
-
console.log(chalk8.yellow("
|
|
3116
|
+
console.log(chalk8.yellow("[!] Brand keyword not in meta description"));
|
|
3084
3117
|
}
|
|
3085
3118
|
if (content.includes("application/ld+json")) {
|
|
3086
3119
|
if (content.includes('"@type":"Organization"') || content.includes('"@type": "Organization"')) {
|
|
@@ -3088,21 +3121,21 @@ async function geoAudit() {
|
|
|
3088
3121
|
console.log(chalk8.green("\u2705 Organization schema present"));
|
|
3089
3122
|
} else {
|
|
3090
3123
|
result.issues.push("Organization schema not found");
|
|
3091
|
-
console.log(chalk8.yellow("
|
|
3124
|
+
console.log(chalk8.yellow("[!] Organization schema missing"));
|
|
3092
3125
|
}
|
|
3093
3126
|
if (content.includes('"@type":"Service"') || content.includes('"@type": "Service"')) {
|
|
3094
3127
|
result.hasServiceSchema = true;
|
|
3095
3128
|
console.log(chalk8.green("\u2705 Service schema present"));
|
|
3096
3129
|
} else {
|
|
3097
3130
|
result.issues.push("Service schema not found");
|
|
3098
|
-
console.log(chalk8.yellow("
|
|
3131
|
+
console.log(chalk8.yellow("[!] Service schema missing"));
|
|
3099
3132
|
}
|
|
3100
3133
|
if (content.includes('"@type":"FAQPage"') || content.includes('"@type": "FAQPage"')) {
|
|
3101
3134
|
result.hasFAQSchema = true;
|
|
3102
3135
|
console.log(chalk8.green("\u2705 FAQPage schema present"));
|
|
3103
3136
|
} else {
|
|
3104
3137
|
result.issues.push("FAQPage schema not found");
|
|
3105
|
-
console.log(chalk8.yellow("
|
|
3138
|
+
console.log(chalk8.yellow("[!] FAQPage schema missing"));
|
|
3106
3139
|
}
|
|
3107
3140
|
} else {
|
|
3108
3141
|
result.issues.push("No JSON-LD schemas found");
|
|
@@ -3110,14 +3143,14 @@ async function geoAudit() {
|
|
|
3110
3143
|
}
|
|
3111
3144
|
} else if (htmlFiles.length === 0) {
|
|
3112
3145
|
result.issues.push("No index.html found");
|
|
3113
|
-
console.log(chalk8.yellow("
|
|
3146
|
+
console.log(chalk8.yellow("[!] No index.html found to audit"));
|
|
3114
3147
|
}
|
|
3115
3148
|
console.log();
|
|
3116
3149
|
const passed = result.issues.length === 0;
|
|
3117
3150
|
if (passed) {
|
|
3118
3151
|
console.log(chalk8.green.bold("\u2705 GEO Audit Passed"));
|
|
3119
3152
|
} else {
|
|
3120
|
-
console.log(chalk8.yellow.bold(
|
|
3153
|
+
console.log(chalk8.yellow.bold(`[!] ${result.issues.length} issue(s) found`));
|
|
3121
3154
|
console.log();
|
|
3122
3155
|
console.log(chalk8.bold("Recommendations:"));
|
|
3123
3156
|
result.issues.forEach((issue, i) => {
|
|
@@ -3335,7 +3368,7 @@ async function seoCheck(options) {
|
|
|
3335
3368
|
console.log(chalk9.dim("All essential meta tags are present."));
|
|
3336
3369
|
return;
|
|
3337
3370
|
}
|
|
3338
|
-
console.log(chalk9.yellow(
|
|
3371
|
+
console.log(chalk9.yellow(`[!] ${issues.length} SEO Issues Found
|
|
3339
3372
|
`));
|
|
3340
3373
|
const criticalCount = issues.filter((i) => i.severity === "critical").length;
|
|
3341
3374
|
const warningCount = issues.filter((i) => i.severity === "warning").length;
|
|
@@ -4456,7 +4489,7 @@ async function indexUpdate(options) {
|
|
|
4456
4489
|
}
|
|
4457
4490
|
} catch (error) {
|
|
4458
4491
|
console.log(`
|
|
4459
|
-
${chalk12.yellow(
|
|
4492
|
+
${chalk12.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message : "Unknown error"}`)}`);
|
|
4460
4493
|
}
|
|
4461
4494
|
}
|
|
4462
4495
|
console.log("\r" + " ".repeat(70));
|
|
@@ -4704,11 +4737,12 @@ async function githubDisconnect() {
|
|
|
4704
4737
|
var program = new Command4();
|
|
4705
4738
|
program.name("archon").description("Local-first AI-powered development governance").version("1.1.0").action(async () => {
|
|
4706
4739
|
const cwd = process.cwd();
|
|
4707
|
-
|
|
4740
|
+
const wasInitialized = isInitialized(cwd);
|
|
4741
|
+
if (!wasInitialized) {
|
|
4708
4742
|
console.log(chalk14.blue("\nArchonDev is not initialized in this folder.\n"));
|
|
4709
4743
|
await init({ analyze: true, git: true });
|
|
4710
4744
|
}
|
|
4711
|
-
await start();
|
|
4745
|
+
await start({ skipGovernanceBanner: !wasInitialized });
|
|
4712
4746
|
});
|
|
4713
4747
|
program.command("login").description("Authenticate with ArchonDev").option("-p, --provider <provider>", "OAuth provider (github or google)", "github").action(async (options) => {
|
|
4714
4748
|
const provider = options.provider;
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
parallelExecute,
|
|
4
4
|
parallelMerge,
|
|
5
5
|
parallelStatus
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-TSSFMB6E.js";
|
|
7
|
+
import "./chunk-RCW22YNI.js";
|
|
8
8
|
import "./chunk-5IQKC2TD.js";
|
|
9
9
|
import "./chunk-A7QU6JC6.js";
|
|
10
10
|
import "./chunk-SMR7JQK6.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "archondev",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Local-first AI-powered development governance system",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -57,7 +57,6 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@anthropic-ai/sdk": "^0.71.2",
|
|
59
59
|
"@supabase/supabase-js": "^2.90.1",
|
|
60
|
-
"@types/glob": "^9.0.0",
|
|
61
60
|
"@types/node": "^25.0.9",
|
|
62
61
|
"better-sqlite3": "^12.6.2",
|
|
63
62
|
"chalk": "^5.6.2",
|