archondev 2.19.20 → 2.19.22
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/dist/chunk-3XEHZYXJ.js +169 -0
- package/dist/index.js +696 -809
- package/dist/show-CXJPLCXD.js +19 -0
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
a11yBadge,
|
|
4
|
+
a11yCheck,
|
|
5
|
+
a11yFix,
|
|
6
|
+
a11yPreDeploy
|
|
7
|
+
} from "./chunk-FWLLGLD5.js";
|
|
2
8
|
import {
|
|
3
9
|
createSeoCommand
|
|
4
10
|
} from "./chunk-JF7JCK6H.js";
|
|
5
11
|
import {
|
|
6
12
|
createGeoCommand
|
|
7
13
|
} from "./chunk-O3B6BE5D.js";
|
|
14
|
+
import {
|
|
15
|
+
show
|
|
16
|
+
} from "./chunk-3XEHZYXJ.js";
|
|
8
17
|
import {
|
|
9
18
|
bugReport
|
|
10
19
|
} from "./chunk-XKYRHJA5.js";
|
|
@@ -21,6 +30,7 @@ import {
|
|
|
21
30
|
reviewUpdate
|
|
22
31
|
} from "./chunk-6XLWTTGJ.js";
|
|
23
32
|
import "./chunk-YGDLWQBK.js";
|
|
33
|
+
import "./chunk-3ASILTFB.js";
|
|
24
34
|
import {
|
|
25
35
|
resetPreferences,
|
|
26
36
|
setExecutionPreference,
|
|
@@ -29,13 +39,6 @@ import {
|
|
|
29
39
|
showPreferences,
|
|
30
40
|
showUsageDetails
|
|
31
41
|
} from "./chunk-MIT5Z5V7.js";
|
|
32
|
-
import {
|
|
33
|
-
a11yBadge,
|
|
34
|
-
a11yCheck,
|
|
35
|
-
a11yFix,
|
|
36
|
-
a11yPreDeploy
|
|
37
|
-
} from "./chunk-FWLLGLD5.js";
|
|
38
|
-
import "./chunk-3ASILTFB.js";
|
|
39
42
|
import {
|
|
40
43
|
init,
|
|
41
44
|
isInitialized
|
|
@@ -113,7 +116,7 @@ import "./chunk-4VNS5WPM.js";
|
|
|
113
116
|
|
|
114
117
|
// src/cli/index.ts
|
|
115
118
|
import { Command as Command3 } from "commander";
|
|
116
|
-
import
|
|
119
|
+
import chalk17 from "chalk";
|
|
117
120
|
import "dotenv/config";
|
|
118
121
|
|
|
119
122
|
// src/cli/terminal-compat.ts
|
|
@@ -194,170 +197,8 @@ async function saveAtomEnvironmentState(atomId, cwd, state) {
|
|
|
194
197
|
await writeFile(stateFile, JSON.stringify(state, null, 2));
|
|
195
198
|
}
|
|
196
199
|
|
|
197
|
-
// src/cli/show.ts
|
|
198
|
-
import chalk2 from "chalk";
|
|
199
|
-
var STATUS_COLORS = {
|
|
200
|
-
DRAFT: chalk2.gray,
|
|
201
|
-
READY: chalk2.blue,
|
|
202
|
-
IN_PROGRESS: chalk2.yellow,
|
|
203
|
-
TESTING: chalk2.cyan,
|
|
204
|
-
DONE: chalk2.green,
|
|
205
|
-
FAILED: chalk2.red,
|
|
206
|
-
BLOCKED: chalk2.magenta
|
|
207
|
-
};
|
|
208
|
-
async function show(atomId) {
|
|
209
|
-
const atom = await loadAtom(atomId);
|
|
210
|
-
if (!atom) {
|
|
211
|
-
console.error(chalk2.red(`Atom ${atomId} not found.`));
|
|
212
|
-
console.log(chalk2.dim('Use "archon list" to see available atoms.'));
|
|
213
|
-
process.exit(1);
|
|
214
|
-
}
|
|
215
|
-
const colorFn = STATUS_COLORS[atom.status] ?? chalk2.white;
|
|
216
|
-
console.log("");
|
|
217
|
-
console.log(chalk2.bold(`Atom: ${atom.externalId}`));
|
|
218
|
-
console.log(chalk2.dim("\u2550".repeat(60)));
|
|
219
|
-
console.log("");
|
|
220
|
-
console.log(chalk2.bold("Title:"), atom.title);
|
|
221
|
-
if (atom.description) {
|
|
222
|
-
console.log(chalk2.bold("Description:"), atom.description);
|
|
223
|
-
}
|
|
224
|
-
console.log(chalk2.bold("Status:"), colorFn(atom.status));
|
|
225
|
-
console.log(chalk2.bold("Priority:"), atom.priority);
|
|
226
|
-
console.log(chalk2.bold("Created:"), formatDateTime(atom.createdAt));
|
|
227
|
-
console.log(chalk2.bold("Updated:"), formatDateTime(atom.updatedAt));
|
|
228
|
-
if (atom.goals && atom.goals.length > 0) {
|
|
229
|
-
console.log("");
|
|
230
|
-
console.log(chalk2.bold("Goals:"));
|
|
231
|
-
for (const goal of atom.goals) {
|
|
232
|
-
console.log(` \u2022 ${goal}`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (atom.acceptanceCriteria && atom.acceptanceCriteria.length > 0) {
|
|
236
|
-
console.log("");
|
|
237
|
-
console.log(chalk2.bold("Acceptance Criteria:"));
|
|
238
|
-
for (let i = 0; i < atom.acceptanceCriteria.length; i++) {
|
|
239
|
-
console.log(` ${i + 1}. ${atom.acceptanceCriteria[i]}`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
if (atom.tags && atom.tags.length > 0) {
|
|
243
|
-
console.log("");
|
|
244
|
-
console.log(chalk2.bold("Tags:"), atom.tags.join(", "));
|
|
245
|
-
}
|
|
246
|
-
if (atom.plan) {
|
|
247
|
-
console.log("");
|
|
248
|
-
console.log(chalk2.bold("Implementation Plan:"));
|
|
249
|
-
console.log(chalk2.dim("\u2500".repeat(40)));
|
|
250
|
-
console.log(chalk2.bold("Steps:"));
|
|
251
|
-
for (let i = 0; i < atom.plan.steps.length; i++) {
|
|
252
|
-
console.log(` ${i + 1}. ${atom.plan.steps[i]}`);
|
|
253
|
-
}
|
|
254
|
-
if (atom.plan.files_to_modify.length > 0) {
|
|
255
|
-
console.log("");
|
|
256
|
-
console.log(chalk2.bold("Files to modify:"));
|
|
257
|
-
for (const file of atom.plan.files_to_modify) {
|
|
258
|
-
console.log(` \u2022 ${file}`);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (atom.plan.dependencies.length > 0) {
|
|
262
|
-
console.log("");
|
|
263
|
-
console.log(chalk2.bold("Dependencies:"));
|
|
264
|
-
for (const dep of atom.plan.dependencies) {
|
|
265
|
-
console.log(` \u2022 ${dep}`);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
if (atom.plan.risks.length > 0) {
|
|
269
|
-
console.log("");
|
|
270
|
-
console.log(chalk2.bold("Risks:"));
|
|
271
|
-
for (const risk of atom.plan.risks) {
|
|
272
|
-
console.log(chalk2.yellow(` [!] ${risk}`));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
console.log("");
|
|
276
|
-
console.log(chalk2.bold("Estimated Complexity:"), atom.plan.estimated_complexity);
|
|
277
|
-
}
|
|
278
|
-
if (atom.status === "FAILED" && atom.errorMessage) {
|
|
279
|
-
console.log("");
|
|
280
|
-
console.log(chalk2.bold("Error:"));
|
|
281
|
-
console.log(chalk2.red(` ${atom.errorMessage}`));
|
|
282
|
-
}
|
|
283
|
-
if (atom.retryCount > 0) {
|
|
284
|
-
console.log("");
|
|
285
|
-
console.log(chalk2.bold("Retry Count:"), chalk2.yellow(String(atom.retryCount)));
|
|
286
|
-
}
|
|
287
|
-
if (atom.ownershipPaths && atom.ownershipPaths.length > 0) {
|
|
288
|
-
console.log("");
|
|
289
|
-
console.log(chalk2.bold("Ownership Paths:"));
|
|
290
|
-
for (const path2 of atom.ownershipPaths) {
|
|
291
|
-
console.log(` \u2022 ${path2}`);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
if (atom.diffContract) {
|
|
295
|
-
console.log("");
|
|
296
|
-
console.log(chalk2.bold("Diff Contract:"));
|
|
297
|
-
if (atom.diffContract.allowed_paths.length > 0) {
|
|
298
|
-
console.log(chalk2.dim(" Allowed paths:"));
|
|
299
|
-
for (const path2 of atom.diffContract.allowed_paths) {
|
|
300
|
-
console.log(` \u2713 ${path2}`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (atom.diffContract.forbidden_paths.length > 0) {
|
|
304
|
-
console.log(chalk2.dim(" Forbidden paths:"));
|
|
305
|
-
for (const path2 of atom.diffContract.forbidden_paths) {
|
|
306
|
-
console.log(chalk2.red(` \u2717 ${path2}`));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
if (atom.context && Object.keys(atom.context).length > 0) {
|
|
311
|
-
console.log("");
|
|
312
|
-
console.log(chalk2.bold("Context:"));
|
|
313
|
-
if (atom.context.relevantFiles && atom.context.relevantFiles.length > 0) {
|
|
314
|
-
console.log(chalk2.dim(" Relevant files:"));
|
|
315
|
-
for (const file of atom.context.relevantFiles) {
|
|
316
|
-
console.log(` \u2022 ${file}`);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (atom.context.recentLearnings && atom.context.recentLearnings.length > 0) {
|
|
320
|
-
console.log(chalk2.dim(" Recent learnings:"));
|
|
321
|
-
for (const learning of atom.context.recentLearnings) {
|
|
322
|
-
console.log(` \u2022 ${learning}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
console.log("");
|
|
327
|
-
console.log(chalk2.dim("\u2500".repeat(60)));
|
|
328
|
-
console.log(chalk2.bold("Next Steps:"));
|
|
329
|
-
switch (atom.status) {
|
|
330
|
-
case "DRAFT":
|
|
331
|
-
console.log(chalk2.dim(` Run "archon plan ${atom.externalId} --continue" to finalize the plan`));
|
|
332
|
-
break;
|
|
333
|
-
case "READY":
|
|
334
|
-
console.log(chalk2.dim(` Run "archon execute ${atom.externalId}" to implement`));
|
|
335
|
-
break;
|
|
336
|
-
case "IN_PROGRESS":
|
|
337
|
-
console.log(chalk2.dim(" Execution is in progress..."));
|
|
338
|
-
break;
|
|
339
|
-
case "TESTING":
|
|
340
|
-
console.log(chalk2.dim(" Waiting for quality gates to complete..."));
|
|
341
|
-
break;
|
|
342
|
-
case "DONE":
|
|
343
|
-
console.log(chalk2.green(" \u2713 Atom completed successfully!"));
|
|
344
|
-
break;
|
|
345
|
-
case "FAILED":
|
|
346
|
-
console.log(chalk2.dim(` Review the error and run "archon execute ${atom.externalId}" to retry`));
|
|
347
|
-
break;
|
|
348
|
-
case "BLOCKED":
|
|
349
|
-
console.log(chalk2.dim(" This atom is blocked. Manual intervention required."));
|
|
350
|
-
break;
|
|
351
|
-
}
|
|
352
|
-
console.log("");
|
|
353
|
-
}
|
|
354
|
-
function formatDateTime(date) {
|
|
355
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
356
|
-
return d.toLocaleString();
|
|
357
|
-
}
|
|
358
|
-
|
|
359
200
|
// src/cli/start.ts
|
|
360
|
-
import
|
|
201
|
+
import chalk5 from "chalk";
|
|
361
202
|
import readline from "readline";
|
|
362
203
|
import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync3, appendFileSync } from "fs";
|
|
363
204
|
import { join as join6 } from "path";
|
|
@@ -464,7 +305,7 @@ var ContextManager = class _ContextManager {
|
|
|
464
305
|
};
|
|
465
306
|
|
|
466
307
|
// src/cli/cleanup.ts
|
|
467
|
-
import
|
|
308
|
+
import chalk2 from "chalk";
|
|
468
309
|
import { existsSync as existsSync3, readdirSync, statSync } from "fs";
|
|
469
310
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir2, unlink, readdir, stat } from "fs/promises";
|
|
470
311
|
import { join as join3 } from "path";
|
|
@@ -643,7 +484,7 @@ async function cleanupCheck() {
|
|
|
643
484
|
const config = await loadCleanupConfig(cwd);
|
|
644
485
|
const progressMaxKb = config?.progressMaxKb ?? DEFAULT_THRESHOLDS.progressMaxKb;
|
|
645
486
|
const archonDirMaxMb = config?.archonDirMaxMb ?? DEFAULT_THRESHOLDS.archonDirMaxMb;
|
|
646
|
-
console.log(
|
|
487
|
+
console.log(chalk2.blue("\n\u{1F50D} Analyzing workspace for maintenance needs...\n"));
|
|
647
488
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
648
489
|
if (existsSync3(progressPath)) {
|
|
649
490
|
const size = statSync(progressPath).size;
|
|
@@ -716,12 +557,12 @@ async function cleanupCheck() {
|
|
|
716
557
|
});
|
|
717
558
|
}
|
|
718
559
|
}
|
|
719
|
-
console.log(
|
|
560
|
+
console.log(chalk2.bold("Workspace Analysis Summary\n"));
|
|
720
561
|
console.log("\u250C\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\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
721
562
|
console.log("\u2502 Item \u2502 Size \u2502 Status \u2502");
|
|
722
563
|
console.log("\u251C\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\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
|
|
723
564
|
for (const result of results) {
|
|
724
|
-
const statusIcon = result.status === "critical" ?
|
|
565
|
+
const statusIcon = result.status === "critical" ? chalk2.red("\u2717") : result.status === "warn" ? chalk2.yellow("!") : chalk2.green("\u2713");
|
|
725
566
|
const name = result.name.padEnd(23);
|
|
726
567
|
const size = result.sizeFormatted.padEnd(14);
|
|
727
568
|
console.log(`\u2502 ${name} \u2502 ${size} \u2502 ${statusIcon} \u2502`);
|
|
@@ -730,13 +571,13 @@ async function cleanupCheck() {
|
|
|
730
571
|
console.log();
|
|
731
572
|
const recommendations = results.filter((r) => r.recommendation && r.status !== "ok");
|
|
732
573
|
if (recommendations.length > 0) {
|
|
733
|
-
console.log(
|
|
574
|
+
console.log(chalk2.yellow("Recommendations:\n"));
|
|
734
575
|
for (const rec of recommendations) {
|
|
735
|
-
console.log(` ${
|
|
576
|
+
console.log(` ${chalk2.dim("\u2022")} ${rec.name}: ${rec.recommendation}`);
|
|
736
577
|
}
|
|
737
578
|
console.log();
|
|
738
579
|
} else {
|
|
739
|
-
console.log(
|
|
580
|
+
console.log(chalk2.green("\u2713 Workspace is in good shape!\n"));
|
|
740
581
|
}
|
|
741
582
|
}
|
|
742
583
|
async function cleanupRun() {
|
|
@@ -747,7 +588,7 @@ async function cleanupRun() {
|
|
|
747
588
|
const progressArchiveDays = config?.progressArchiveDays ?? DEFAULT_THRESHOLDS.progressArchiveDays;
|
|
748
589
|
const cacheRetentionDays = config?.cacheRetentionDays ?? DEFAULT_THRESHOLDS.cacheRetentionDays;
|
|
749
590
|
const cloudLogRetentionDays = config?.cloudLogRetentionDays ?? DEFAULT_THRESHOLDS.cloudLogRetentionDays;
|
|
750
|
-
console.log(
|
|
591
|
+
console.log(chalk2.blue("\n\u{1F9F9} Running workspace cleanup...\n"));
|
|
751
592
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
752
593
|
if (existsSync3(progressPath)) {
|
|
753
594
|
const content = await readFile3(progressPath, "utf-8");
|
|
@@ -793,7 +634,7 @@ async function cleanupRun() {
|
|
|
793
634
|
spaceSavedFormatted: "N/A"
|
|
794
635
|
});
|
|
795
636
|
} catch {
|
|
796
|
-
console.log(
|
|
637
|
+
console.log(chalk2.yellow(` Could not remove worktree: ${worktree}`));
|
|
797
638
|
}
|
|
798
639
|
}
|
|
799
640
|
const cachePath = join3(cwd, CACHE_DIR);
|
|
@@ -839,18 +680,18 @@ async function cleanupRun() {
|
|
|
839
680
|
}
|
|
840
681
|
}
|
|
841
682
|
if (results.length === 0) {
|
|
842
|
-
console.log(
|
|
683
|
+
console.log(chalk2.green("\u2713 Nothing to clean up!\n"));
|
|
843
684
|
return;
|
|
844
685
|
}
|
|
845
|
-
console.log(
|
|
686
|
+
console.log(chalk2.bold("Cleanup Results\n"));
|
|
846
687
|
for (const result of results) {
|
|
847
|
-
console.log(` ${
|
|
688
|
+
console.log(` ${chalk2.green("\u2713")} ${result.name}: ${result.action}`);
|
|
848
689
|
if (result.spaceSaved > 0) {
|
|
849
|
-
console.log(
|
|
690
|
+
console.log(chalk2.dim(` Space saved: ${result.spaceSavedFormatted}`));
|
|
850
691
|
}
|
|
851
692
|
}
|
|
852
693
|
console.log();
|
|
853
|
-
console.log(
|
|
694
|
+
console.log(chalk2.green(`\u2713 Total space saved: ${formatBytes(totalSaved)}
|
|
854
695
|
`));
|
|
855
696
|
}
|
|
856
697
|
async function cleanupAuto(action) {
|
|
@@ -858,20 +699,20 @@ async function cleanupAuto(action) {
|
|
|
858
699
|
const config = await loadCleanupConfig(cwd);
|
|
859
700
|
if (action === "status") {
|
|
860
701
|
const enabled = config?.autoEnabled ?? false;
|
|
861
|
-
console.log(
|
|
702
|
+
console.log(chalk2.blue("\n\u{1F527} Auto Cleanup Settings\n"));
|
|
862
703
|
console.log(
|
|
863
|
-
` Status: ${enabled ?
|
|
704
|
+
` Status: ${enabled ? chalk2.green("Enabled") : chalk2.dim("Disabled")}`
|
|
864
705
|
);
|
|
865
706
|
console.log(
|
|
866
|
-
|
|
707
|
+
chalk2.dim(
|
|
867
708
|
` Progress archive threshold: ${config?.progressArchiveDays ?? 30} days`
|
|
868
709
|
)
|
|
869
710
|
);
|
|
870
711
|
console.log(
|
|
871
|
-
|
|
712
|
+
chalk2.dim(` Cache retention: ${config?.cacheRetentionDays ?? 7} days`)
|
|
872
713
|
);
|
|
873
714
|
console.log(
|
|
874
|
-
|
|
715
|
+
chalk2.dim(
|
|
875
716
|
` Cloud log retention: ${config?.cloudLogRetentionDays ?? 30} days`
|
|
876
717
|
)
|
|
877
718
|
);
|
|
@@ -886,14 +727,14 @@ async function cleanupAuto(action) {
|
|
|
886
727
|
};
|
|
887
728
|
await saveCleanupConfig(cwd, newConfig);
|
|
888
729
|
if (action === "enable") {
|
|
889
|
-
console.log(
|
|
730
|
+
console.log(chalk2.green("\n\u2713 Auto cleanup enabled"));
|
|
890
731
|
console.log(
|
|
891
|
-
|
|
732
|
+
chalk2.dim(
|
|
892
733
|
' Cleanup check will run on "archon start" and warn if action needed\n'
|
|
893
734
|
)
|
|
894
735
|
);
|
|
895
736
|
} else {
|
|
896
|
-
console.log(
|
|
737
|
+
console.log(chalk2.green("\n\u2713 Auto cleanup disabled\n"));
|
|
897
738
|
}
|
|
898
739
|
}
|
|
899
740
|
async function shouldRunAutoCleanup(cwd) {
|
|
@@ -927,7 +768,7 @@ async function runAutoCleanupCheck(cwd) {
|
|
|
927
768
|
}
|
|
928
769
|
|
|
929
770
|
// src/cli/update-check.ts
|
|
930
|
-
import
|
|
771
|
+
import chalk3 from "chalk";
|
|
931
772
|
import { readFileSync, existsSync as existsSync4 } from "fs";
|
|
932
773
|
import { join as join4, dirname as dirname3 } from "path";
|
|
933
774
|
import { fileURLToPath } from "url";
|
|
@@ -1019,10 +860,10 @@ async function checkForUpdates() {
|
|
|
1019
860
|
function displayUpdateBanner(result) {
|
|
1020
861
|
if (!result.hasUpdate) return;
|
|
1021
862
|
console.log();
|
|
1022
|
-
console.log(
|
|
1023
|
-
console.log(
|
|
1024
|
-
console.log(
|
|
1025
|
-
console.log(
|
|
863
|
+
console.log(chalk3.yellow("\u250C\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
864
|
+
console.log(chalk3.yellow("\u2502") + chalk3.bold(" Update available! ") + chalk3.dim(`${result.currentVersion} \u2192 `) + chalk3.green(result.latestVersion) + chalk3.yellow(" \u2502"));
|
|
865
|
+
console.log(chalk3.yellow("\u2502") + chalk3.dim(` Run: ${result.updateCommand}`) + chalk3.yellow(" \u2502"));
|
|
866
|
+
console.log(chalk3.yellow("\u2514\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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
1026
867
|
console.log();
|
|
1027
868
|
}
|
|
1028
869
|
function startBackgroundUpdateCheck() {
|
|
@@ -1030,7 +871,7 @@ function startBackgroundUpdateCheck() {
|
|
|
1030
871
|
}
|
|
1031
872
|
|
|
1032
873
|
// src/cli/logo.ts
|
|
1033
|
-
import
|
|
874
|
+
import chalk4 from "chalk";
|
|
1034
875
|
var ARCHON_LOGO_MINI = `
|
|
1035
876
|
\u2584\u2588\u2580\u2588\u2584
|
|
1036
877
|
\u2588\u2588\u2580\u2588\u2580\u2588\u2588
|
|
@@ -1047,10 +888,10 @@ function displayBrandedHeader() {
|
|
|
1047
888
|
return;
|
|
1048
889
|
}
|
|
1049
890
|
console.log();
|
|
1050
|
-
console.log(
|
|
1051
|
-
console.log(
|
|
1052
|
-
console.log(
|
|
1053
|
-
console.log(
|
|
891
|
+
console.log(chalk4.hex("#374F4E")(ARCHON_LOGO_MINI));
|
|
892
|
+
console.log(chalk4.bold.hex("#374F4E")(" ArchonDev"));
|
|
893
|
+
console.log(chalk4.hex("#AA8552")(" AI-Powered Development Governance"));
|
|
894
|
+
console.log(chalk4.hex("#374F4E")("\u2500".repeat(40)));
|
|
1054
895
|
console.log();
|
|
1055
896
|
}
|
|
1056
897
|
|
|
@@ -2763,6 +2604,12 @@ function detectWebProject(cwd) {
|
|
|
2763
2604
|
}
|
|
2764
2605
|
|
|
2765
2606
|
// src/cli/start.ts
|
|
2607
|
+
function uiText(rich, plain) {
|
|
2608
|
+
return isTerminalSafeMode() ? plain : rich;
|
|
2609
|
+
}
|
|
2610
|
+
function uiSeparator() {
|
|
2611
|
+
return isTerminalSafeMode() ? "-".repeat(40) : "\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";
|
|
2612
|
+
}
|
|
2766
2613
|
async function start(options = {}) {
|
|
2767
2614
|
const cwd = process.cwd();
|
|
2768
2615
|
displayBrandedHeader();
|
|
@@ -2770,21 +2617,21 @@ async function start(options = {}) {
|
|
|
2770
2617
|
let config = await loadConfig();
|
|
2771
2618
|
let token = getAuthToken(config);
|
|
2772
2619
|
if (!token) {
|
|
2773
|
-
console.log(
|
|
2774
|
-
console.log(
|
|
2620
|
+
console.log(chalk5.bold("Welcome to ArchonDev!\n"));
|
|
2621
|
+
console.log(chalk5.dim("Let's get you set up. First, we need to create your account.\n"));
|
|
2775
2622
|
await login();
|
|
2776
2623
|
console.log();
|
|
2777
2624
|
config = await loadConfig();
|
|
2778
2625
|
token = getAuthToken(config);
|
|
2779
2626
|
if (!token) {
|
|
2780
|
-
console.log(
|
|
2627
|
+
console.log(chalk5.yellow("Login is required to continue. Run `archon` again when ready."));
|
|
2781
2628
|
return;
|
|
2782
2629
|
}
|
|
2783
2630
|
}
|
|
2784
2631
|
if (!config.tier || config.tier === "FREE") {
|
|
2785
2632
|
const isFirstRun = !existsSync6(join6(cwd, ".archon")) && resolveArchitecturePath(cwd).path === null;
|
|
2786
2633
|
if (isFirstRun && !config.tierConfirmed) {
|
|
2787
|
-
console.log(
|
|
2634
|
+
console.log(chalk5.bold("How would you like to use ArchonDev?\n"));
|
|
2788
2635
|
const selection = await promptTierSelection();
|
|
2789
2636
|
if (selection && !selection.skipped) {
|
|
2790
2637
|
const updateResult2 = await updateUserTier(selection.tier);
|
|
@@ -2792,7 +2639,7 @@ async function start(options = {}) {
|
|
|
2792
2639
|
config.tier = selection.tier;
|
|
2793
2640
|
config.tierConfirmed = true;
|
|
2794
2641
|
await saveConfig(config);
|
|
2795
|
-
console.log(
|
|
2642
|
+
console.log(chalk5.green(`
|
|
2796
2643
|
\u2713 Tier set to ${formatTierName(selection.tier)}
|
|
2797
2644
|
`));
|
|
2798
2645
|
await handleTierSetup(selection.tier);
|
|
@@ -2800,23 +2647,23 @@ async function start(options = {}) {
|
|
|
2800
2647
|
} else {
|
|
2801
2648
|
config.tierConfirmed = true;
|
|
2802
2649
|
await saveConfig(config);
|
|
2803
|
-
console.log(
|
|
2650
|
+
console.log(chalk5.dim("Using Free tier. You can upgrade anytime with `archon upgrade`\n"));
|
|
2804
2651
|
}
|
|
2805
2652
|
}
|
|
2806
2653
|
}
|
|
2807
2654
|
if (config.email) {
|
|
2808
|
-
console.log(
|
|
2655
|
+
console.log(chalk5.dim(`Logged in as: ${config.email}`));
|
|
2809
2656
|
}
|
|
2810
2657
|
const currentTier = config.tier || "FREE";
|
|
2811
2658
|
const tierDisplay = formatTierName(currentTier);
|
|
2812
|
-
console.log(
|
|
2659
|
+
console.log(chalk5.dim(`Tier: `) + tierDisplay);
|
|
2813
2660
|
if (currentTier === "FREE") {
|
|
2814
2661
|
console.log();
|
|
2815
|
-
console.log(
|
|
2816
|
-
console.log(
|
|
2817
|
-
console.log(
|
|
2818
|
-
console.log(
|
|
2819
|
-
console.log(
|
|
2662
|
+
console.log(chalk5.yellow("\u26A0\uFE0F FREE TIER: Limited usage. Upgrade options:"));
|
|
2663
|
+
console.log(chalk5.dim(" \u2022 ") + chalk5.bold("BYOK (FREE)") + chalk5.dim(" - Unlimited usage with your own API keys"));
|
|
2664
|
+
console.log(chalk5.dim(" \u2022 ") + chalk5.bold("Managed Plan") + chalk5.dim(" - Just 10% fee on AI costs, zero setup"));
|
|
2665
|
+
console.log(chalk5.cyan("\u2192 Run ") + chalk5.bold("'archon upgrade'") + chalk5.cyan(" to unlock unlimited access"));
|
|
2666
|
+
console.log(chalk5.dim("\u2192 Model preferences: archon preferences"));
|
|
2820
2667
|
}
|
|
2821
2668
|
if (currentTier === "CREDITS" && config.accessToken) {
|
|
2822
2669
|
try {
|
|
@@ -2838,41 +2685,41 @@ async function start(options = {}) {
|
|
|
2838
2685
|
}
|
|
2839
2686
|
if (usageStats) {
|
|
2840
2687
|
console.log();
|
|
2841
|
-
console.log(
|
|
2842
|
-
console.log(
|
|
2843
|
-
const balanceColor = usageStats.balance < 1 ?
|
|
2688
|
+
console.log(chalk5.bold(uiText("\u{1F4B0} Credits Balance", "Credits Balance")));
|
|
2689
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2690
|
+
const balanceColor = usageStats.balance < 1 ? chalk5.red : usageStats.balance < 5 ? chalk5.yellow : chalk5.green;
|
|
2844
2691
|
console.log(` Balance: ${balanceColor(`$${usageStats.balance.toFixed(2)}`)}`);
|
|
2845
2692
|
if (usageStats.periodStart) {
|
|
2846
2693
|
const periodDate = new Date(usageStats.periodStart);
|
|
2847
2694
|
const formatted = isNaN(periodDate.getTime()) ? usageStats.periodStart : periodDate.toLocaleDateString();
|
|
2848
2695
|
const label = usageStats.periodSource === "credit_purchase" ? `Since last top-up (${formatted})` : usageStats.periodSource === "month" ? `Since ${formatted}` : `Period start: ${formatted}`;
|
|
2849
|
-
console.log(
|
|
2696
|
+
console.log(chalk5.dim(` ${label}`));
|
|
2850
2697
|
}
|
|
2851
2698
|
if (usageStats.usedThisPeriod > 0) {
|
|
2852
|
-
console.log(` Used since last top-up: ${
|
|
2699
|
+
console.log(` Used since last top-up: ${chalk5.dim(`$${usageStats.usedThisPeriod.toFixed(2)}`)}`);
|
|
2853
2700
|
} else {
|
|
2854
|
-
console.log(
|
|
2701
|
+
console.log(chalk5.dim(" No usage recorded since last top-up."));
|
|
2855
2702
|
}
|
|
2856
2703
|
console.log();
|
|
2857
|
-
console.log(
|
|
2704
|
+
console.log(chalk5.dim(" Model Usage:"));
|
|
2858
2705
|
if (usageStats.byModel && usageStats.byModel.length > 0) {
|
|
2859
2706
|
for (const model of usageStats.byModel) {
|
|
2860
2707
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2861
|
-
console.log(
|
|
2708
|
+
console.log(chalk5.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2862
2709
|
}
|
|
2863
2710
|
} else {
|
|
2864
|
-
console.log(
|
|
2711
|
+
console.log(chalk5.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2865
2712
|
}
|
|
2866
|
-
console.log(
|
|
2713
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2867
2714
|
if (usageStatsUnavailable) {
|
|
2868
|
-
console.log(
|
|
2715
|
+
console.log(chalk5.dim("Usage details may be delayed. Run `archon credits` to refresh."));
|
|
2869
2716
|
}
|
|
2870
2717
|
if (usageStats.balance < 5) {
|
|
2871
|
-
console.log(
|
|
2718
|
+
console.log(chalk5.yellow(`\u26A0\uFE0F Low balance! Add credits: `) + chalk5.bold(`archon credits add`));
|
|
2872
2719
|
} else {
|
|
2873
|
-
console.log(
|
|
2720
|
+
console.log(chalk5.dim(`Add credits: archon credits add`));
|
|
2874
2721
|
}
|
|
2875
|
-
console.log(
|
|
2722
|
+
console.log(chalk5.dim(`View details: archon credits | Switch tier: archon upgrade | Models: archon preferences`));
|
|
2876
2723
|
if (usageStats.balance <= 0) {
|
|
2877
2724
|
const topUpNow = await promptYesNo("Balance is $0. Add credits now?", true);
|
|
2878
2725
|
if (topUpNow) {
|
|
@@ -2896,39 +2743,39 @@ async function start(options = {}) {
|
|
|
2896
2743
|
};
|
|
2897
2744
|
}
|
|
2898
2745
|
console.log();
|
|
2899
|
-
console.log(
|
|
2900
|
-
console.log(
|
|
2746
|
+
console.log(chalk5.bold(uiText("\u{1F4CA} BYOK Usage", "BYOK Usage")));
|
|
2747
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2901
2748
|
if (usageStats.periodStart) {
|
|
2902
2749
|
const periodStart = new Date(usageStats.periodStart);
|
|
2903
2750
|
const periodEnd = usageStats.periodEnd ? new Date(usageStats.periodEnd) : null;
|
|
2904
2751
|
const formattedStart = isNaN(periodStart.getTime()) ? usageStats.periodStart : periodStart.toLocaleDateString();
|
|
2905
2752
|
const formattedEnd = periodEnd && !isNaN(periodEnd.getTime()) ? periodEnd.toLocaleDateString() : void 0;
|
|
2906
2753
|
if (formattedEnd) {
|
|
2907
|
-
console.log(
|
|
2754
|
+
console.log(chalk5.dim(` Period: ${formattedStart} \u2192 ${formattedEnd}`));
|
|
2908
2755
|
} else {
|
|
2909
|
-
console.log(
|
|
2756
|
+
console.log(chalk5.dim(` Period start: ${formattedStart}`));
|
|
2910
2757
|
}
|
|
2911
2758
|
} else {
|
|
2912
|
-
console.log(
|
|
2759
|
+
console.log(chalk5.dim(" Period: Current month to date"));
|
|
2913
2760
|
}
|
|
2914
2761
|
const totalTokens = usageStats.totalInputTokens + usageStats.totalOutputTokens;
|
|
2915
|
-
console.log(` Tokens: ${
|
|
2916
|
-
console.log(` Estimated provider spend: ${
|
|
2762
|
+
console.log(` Tokens: ${chalk5.dim(totalTokens.toLocaleString())}`);
|
|
2763
|
+
console.log(` Estimated provider spend: ${chalk5.dim(`$${usageStats.totalBaseCost.toFixed(4)}`)}`);
|
|
2917
2764
|
console.log();
|
|
2918
|
-
console.log(
|
|
2765
|
+
console.log(chalk5.dim(" Model Usage:"));
|
|
2919
2766
|
if (usageStats.byModel.length > 0) {
|
|
2920
2767
|
for (const model of usageStats.byModel) {
|
|
2921
2768
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2922
|
-
console.log(
|
|
2769
|
+
console.log(chalk5.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2923
2770
|
}
|
|
2924
2771
|
} else {
|
|
2925
|
-
console.log(
|
|
2772
|
+
console.log(chalk5.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2926
2773
|
}
|
|
2927
|
-
console.log(
|
|
2774
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2928
2775
|
if (usageStatsUnavailable) {
|
|
2929
|
-
console.log(
|
|
2776
|
+
console.log(chalk5.dim("Usage details may be delayed. Run `archon usage` to refresh."));
|
|
2930
2777
|
}
|
|
2931
|
-
console.log(
|
|
2778
|
+
console.log(chalk5.dim("View details: archon usage | Models: archon preferences | Switch tier: archon upgrade"));
|
|
2932
2779
|
} catch {
|
|
2933
2780
|
}
|
|
2934
2781
|
}
|
|
@@ -2937,11 +2784,11 @@ async function start(options = {}) {
|
|
|
2937
2784
|
const hasKeys = await keyManager.hasAnyKey();
|
|
2938
2785
|
if (!hasKeys) {
|
|
2939
2786
|
console.log();
|
|
2940
|
-
console.log(
|
|
2941
|
-
console.log(
|
|
2942
|
-
console.log(` ${
|
|
2943
|
-
console.log(` ${
|
|
2944
|
-
console.log(` ${
|
|
2787
|
+
console.log(chalk5.yellow("\u26A0\uFE0F BYOK MODE: No API keys configured!"));
|
|
2788
|
+
console.log(chalk5.dim("You need at least one API key to use ArchonDev with BYOK.\n"));
|
|
2789
|
+
console.log(` ${chalk5.cyan("1")}) Add an API key now`);
|
|
2790
|
+
console.log(` ${chalk5.cyan("2")}) Switch to Managed Plan (no keys needed)`);
|
|
2791
|
+
console.log(` ${chalk5.cyan("3")}) Continue on Free tier`);
|
|
2945
2792
|
console.log();
|
|
2946
2793
|
const choice = await promptWithCommands("What would you like to do?", { allowMultiline: true });
|
|
2947
2794
|
switch (choice) {
|
|
@@ -2955,7 +2802,7 @@ async function start(options = {}) {
|
|
|
2955
2802
|
if (result.success) {
|
|
2956
2803
|
config.tier = "CREDITS";
|
|
2957
2804
|
await saveConfig(config);
|
|
2958
|
-
console.log(
|
|
2805
|
+
console.log(chalk5.green("\u2713 Switched to Managed Plan"));
|
|
2959
2806
|
const { handleTierSetup: setupCredits } = await import("./tier-selection-XFBM4SZ4.js");
|
|
2960
2807
|
await setupCredits("CREDITS");
|
|
2961
2808
|
}
|
|
@@ -2966,11 +2813,11 @@ async function start(options = {}) {
|
|
|
2966
2813
|
if (downgradeResult.success) {
|
|
2967
2814
|
config.tier = "FREE";
|
|
2968
2815
|
await saveConfig(config);
|
|
2969
|
-
console.log(
|
|
2816
|
+
console.log(chalk5.dim("Switched to Free tier."));
|
|
2970
2817
|
}
|
|
2971
2818
|
break;
|
|
2972
2819
|
default:
|
|
2973
|
-
console.log(
|
|
2820
|
+
console.log(chalk5.dim("Continuing without keys. Some features may not work."));
|
|
2974
2821
|
}
|
|
2975
2822
|
}
|
|
2976
2823
|
}
|
|
@@ -2981,7 +2828,7 @@ async function start(options = {}) {
|
|
|
2981
2828
|
}
|
|
2982
2829
|
const projectState = detectProjectState(cwd);
|
|
2983
2830
|
if (!projectState.hasArchitecture) {
|
|
2984
|
-
console.log(
|
|
2831
|
+
console.log(chalk5.dim("No project initialized in this folder.\n"));
|
|
2985
2832
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
2986
2833
|
await init2({ analyze: true, git: true });
|
|
2987
2834
|
console.log();
|
|
@@ -2995,20 +2842,20 @@ async function start(options = {}) {
|
|
|
2995
2842
|
const contextManager = new ContextManager();
|
|
2996
2843
|
const pendingAtomsData = await contextManager.getPendingAtomsData(cwd);
|
|
2997
2844
|
if (pendingAtomsData && pendingAtomsData.atoms.length > 0) {
|
|
2998
|
-
console.log(
|
|
2845
|
+
console.log(chalk5.yellow("[!] Previous session had pending atoms:\n"));
|
|
2999
2846
|
for (const atomId of pendingAtomsData.atoms) {
|
|
3000
|
-
console.log(
|
|
2847
|
+
console.log(chalk5.dim(` \u2022 ${atomId}`));
|
|
3001
2848
|
}
|
|
3002
2849
|
console.log();
|
|
3003
2850
|
const resume = await promptYesNo("Resume with these atoms?", true);
|
|
3004
2851
|
if (resume) {
|
|
3005
|
-
console.log(
|
|
2852
|
+
console.log(chalk5.green("\n\u2713 Resuming with pending atoms...\n"));
|
|
3006
2853
|
await contextManager.clearPendingAtoms(cwd);
|
|
3007
2854
|
} else {
|
|
3008
2855
|
const clear = await promptYesNo("Clear pending atoms?", false);
|
|
3009
2856
|
if (clear) {
|
|
3010
2857
|
await contextManager.clearPendingAtoms(cwd);
|
|
3011
|
-
console.log(
|
|
2858
|
+
console.log(chalk5.dim("Cleared pending atoms.\n"));
|
|
3012
2859
|
}
|
|
3013
2860
|
}
|
|
3014
2861
|
}
|
|
@@ -3137,18 +2984,18 @@ async function fetchCreditsUsageStatsFromSupabase(accessToken, authId) {
|
|
|
3137
2984
|
}
|
|
3138
2985
|
}
|
|
3139
2986
|
function displayGovernanceStatus(status2) {
|
|
3140
|
-
console.log(
|
|
2987
|
+
console.log(chalk5.dim("Governance Status:"));
|
|
3141
2988
|
if (status2.hasArchitecture) {
|
|
3142
|
-
console.log(
|
|
2989
|
+
console.log(chalk5.green(" \u2713") + ` ARCHITECTURE.md (${status2.posture} posture)`);
|
|
3143
2990
|
if (status2.invariantsCount > 0) {
|
|
3144
|
-
console.log(
|
|
2991
|
+
console.log(chalk5.green(" \u2713") + ` ${status2.invariantsCount} invariants`);
|
|
3145
2992
|
}
|
|
3146
2993
|
if (status2.protectedPathsCount > 0) {
|
|
3147
|
-
console.log(
|
|
2994
|
+
console.log(chalk5.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths`);
|
|
3148
2995
|
}
|
|
3149
2996
|
}
|
|
3150
2997
|
if (status2.pendingAtomsCount > 0) {
|
|
3151
|
-
console.log(
|
|
2998
|
+
console.log(chalk5.cyan(` \u2192 ${status2.pendingAtomsCount} atoms pending`));
|
|
3152
2999
|
}
|
|
3153
3000
|
console.log();
|
|
3154
3001
|
}
|
|
@@ -3280,11 +3127,11 @@ async function gatherGovernanceStatus(cwd) {
|
|
|
3280
3127
|
return status2;
|
|
3281
3128
|
}
|
|
3282
3129
|
async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
3283
|
-
console.log(
|
|
3130
|
+
console.log(chalk5.blue("-- Analyzing Project --\n"));
|
|
3284
3131
|
const projectInfo = await gatherProjectInfo(cwd);
|
|
3285
|
-
console.log(
|
|
3132
|
+
console.log(chalk5.bold(uiText("\u{1F4C1} Project Overview\n", "Project Overview\n")));
|
|
3286
3133
|
if (projectInfo.name) {
|
|
3287
|
-
console.log(` Name: ${
|
|
3134
|
+
console.log(` Name: ${chalk5.cyan(projectInfo.name)}`);
|
|
3288
3135
|
}
|
|
3289
3136
|
if (projectInfo.language) {
|
|
3290
3137
|
console.log(` Language: ${projectInfo.language}`);
|
|
@@ -3296,50 +3143,50 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3296
3143
|
console.log(` Package Manager: ${projectInfo.packageManager}`);
|
|
3297
3144
|
}
|
|
3298
3145
|
console.log();
|
|
3299
|
-
console.log(
|
|
3300
|
-
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") :
|
|
3146
|
+
console.log(chalk5.bold(uiText("\u{1F4CA} Structure\n", "Structure\n")));
|
|
3147
|
+
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") : chalk5.dim("none detected")}`);
|
|
3301
3148
|
console.log(` Source files: ${projectInfo.sourceFileCount}`);
|
|
3302
3149
|
if (projectInfo.testFileCount > 0) {
|
|
3303
3150
|
console.log(` Test files: ${projectInfo.testFileCount}`);
|
|
3304
3151
|
}
|
|
3305
3152
|
console.log();
|
|
3306
|
-
console.log(
|
|
3153
|
+
console.log(chalk5.bold(uiText("\u{1F3DB}\uFE0F Governance\n", "Governance\n")));
|
|
3307
3154
|
if (projectInfo.hasArchitecture) {
|
|
3308
|
-
console.log(` ${
|
|
3155
|
+
console.log(` ${chalk5.green("\u2713")} ARCHITECTURE.md (${projectInfo.posture || "unknown"} posture)`);
|
|
3309
3156
|
if (projectInfo.invariantsCount > 0) {
|
|
3310
|
-
console.log(` ${
|
|
3157
|
+
console.log(` ${chalk5.green("\u2713")} ${projectInfo.invariantsCount} invariants defined`);
|
|
3311
3158
|
}
|
|
3312
3159
|
if (projectInfo.protectedPathsCount > 0) {
|
|
3313
|
-
console.log(` ${
|
|
3160
|
+
console.log(` ${chalk5.green("\u2713")} ${projectInfo.protectedPathsCount} protected paths`);
|
|
3314
3161
|
}
|
|
3315
3162
|
} else {
|
|
3316
|
-
console.log(` ${
|
|
3163
|
+
console.log(` ${chalk5.yellow("\u25CB")} No ARCHITECTURE.md yet`);
|
|
3317
3164
|
}
|
|
3318
3165
|
if (projectInfo.hasProgress) {
|
|
3319
|
-
console.log(` ${
|
|
3166
|
+
console.log(` ${chalk5.green("\u2713")} progress.txt exists`);
|
|
3320
3167
|
}
|
|
3321
3168
|
console.log();
|
|
3322
|
-
console.log(
|
|
3169
|
+
console.log(chalk5.green("\u2713 Analysis complete! I'm ready to work on this project.\n"));
|
|
3323
3170
|
const originalFollowUp = (followUpInput ?? "").trim();
|
|
3324
3171
|
const actionableFollowUp = extractActionableFollowUpFromExplore(originalFollowUp);
|
|
3325
3172
|
if (actionableFollowUp || containsActionIntent(originalFollowUp)) {
|
|
3326
3173
|
const request = actionableFollowUp ?? originalFollowUp;
|
|
3327
|
-
console.log(
|
|
3174
|
+
console.log(chalk5.dim("I finished the project scan. Continuing with your requested task...\n"));
|
|
3328
3175
|
await handlePostExploreAction(cwd, request);
|
|
3329
3176
|
return;
|
|
3330
3177
|
}
|
|
3331
3178
|
if (options.agentMode) {
|
|
3332
|
-
console.log(
|
|
3179
|
+
console.log(chalk5.dim("Tell me the next thing you want to do.\n"));
|
|
3333
3180
|
return;
|
|
3334
3181
|
}
|
|
3335
|
-
console.log(
|
|
3336
|
-
console.log(
|
|
3337
|
-
console.log(` ${
|
|
3338
|
-
console.log(` ${
|
|
3182
|
+
console.log(chalk5.bold("What would you like to do next?\n"));
|
|
3183
|
+
console.log(chalk5.dim("You can describe it naturally, or use shortcuts:\n"));
|
|
3184
|
+
console.log(` ${chalk5.cyan("1")}) ${chalk5.bold("Plan a task")} \u2014 Tell me what to implement, fix, or change`);
|
|
3185
|
+
console.log(` ${chalk5.cyan("2")}) ${chalk5.bold("Review code")} \u2014 Run AI-powered code review`);
|
|
3339
3186
|
if (!projectInfo.hasArchitecture) {
|
|
3340
|
-
console.log(` ${
|
|
3187
|
+
console.log(` ${chalk5.cyan("3")}) ${chalk5.bold("Set up governance")} \u2014 Generate ARCHITECTURE.md from this analysis`);
|
|
3341
3188
|
}
|
|
3342
|
-
console.log(` ${
|
|
3189
|
+
console.log(` ${chalk5.cyan("q")}) ${chalk5.dim("Quit")}`);
|
|
3343
3190
|
console.log();
|
|
3344
3191
|
const choice = await promptWithCommands("Enter choice");
|
|
3345
3192
|
switch (choice.toLowerCase()) {
|
|
@@ -3372,7 +3219,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3372
3219
|
return;
|
|
3373
3220
|
}
|
|
3374
3221
|
}
|
|
3375
|
-
console.log(
|
|
3222
|
+
console.log(chalk5.yellow("I did not catch that. Tell me what you want to do next."));
|
|
3376
3223
|
await showMainMenu();
|
|
3377
3224
|
}
|
|
3378
3225
|
}
|
|
@@ -3475,7 +3322,7 @@ async function runConversationalInterview(cwd, initialMessage) {
|
|
|
3475
3322
|
if (agent && agent.isAvailable()) {
|
|
3476
3323
|
await runAIInterview(cwd, initialMessage, agent);
|
|
3477
3324
|
} else {
|
|
3478
|
-
console.log(
|
|
3325
|
+
console.log(chalk5.dim("(Using simple setup - add API keys with `archon keys add` for AI-powered interview)\n"));
|
|
3479
3326
|
await runSimpleInterview(cwd, initialMessage);
|
|
3480
3327
|
}
|
|
3481
3328
|
}
|
|
@@ -3485,11 +3332,11 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3485
3332
|
try {
|
|
3486
3333
|
let turn = await agent.startInterview(initialMessage);
|
|
3487
3334
|
while (!turn.isComplete && turnCount < MAX_TURNS) {
|
|
3488
|
-
console.log(
|
|
3335
|
+
console.log(chalk5.blue("\u2192 ") + turn.question);
|
|
3489
3336
|
console.log();
|
|
3490
3337
|
const response = await prompt("");
|
|
3491
3338
|
if (wantsToSkip(response)) {
|
|
3492
|
-
console.log(
|
|
3339
|
+
console.log(chalk5.dim("\n> Using defaults for remaining questions.\n"));
|
|
3493
3340
|
break;
|
|
3494
3341
|
}
|
|
3495
3342
|
turn = await agent.continueInterview(response);
|
|
@@ -3501,12 +3348,12 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3501
3348
|
}
|
|
3502
3349
|
const usage = agent.getUsage();
|
|
3503
3350
|
if (usage.totalTokens > 0) {
|
|
3504
|
-
console.log(
|
|
3351
|
+
console.log(chalk5.dim(`
|
|
3505
3352
|
(Interview used ${usage.totalTokens} tokens, $${usage.baseCost.toFixed(4)})`));
|
|
3506
3353
|
}
|
|
3507
3354
|
await finishInterview(cwd, state, initialMessage);
|
|
3508
3355
|
} catch (error) {
|
|
3509
|
-
console.log(
|
|
3356
|
+
console.log(chalk5.yellow("\n[!] AI interview unavailable, using simple setup.\n"));
|
|
3510
3357
|
await runSimpleInterview(cwd, initialMessage);
|
|
3511
3358
|
}
|
|
3512
3359
|
}
|
|
@@ -3519,9 +3366,9 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3519
3366
|
});
|
|
3520
3367
|
const known = getKnownInfo(state);
|
|
3521
3368
|
if (known.length > 0) {
|
|
3522
|
-
console.log(
|
|
3369
|
+
console.log(chalk5.dim("From what you said, I got:"));
|
|
3523
3370
|
for (const info of known) {
|
|
3524
|
-
console.log(
|
|
3371
|
+
console.log(chalk5.dim(` \u2022 ${info}`));
|
|
3525
3372
|
}
|
|
3526
3373
|
console.log();
|
|
3527
3374
|
}
|
|
@@ -3543,7 +3390,7 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3543
3390
|
await finishInterview(cwd, state, initialMessage);
|
|
3544
3391
|
}
|
|
3545
3392
|
async function finishInterview(cwd, state, initialTaskHint) {
|
|
3546
|
-
console.log(
|
|
3393
|
+
console.log(chalk5.blue("\n-- Recording Project Details --\n"));
|
|
3547
3394
|
const posture = state.posture === "enterprise" ? "enterprise" : state.posture === "prototype" ? "prototype" : "production";
|
|
3548
3395
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3549
3396
|
const progressEntry = `
|
|
@@ -3575,22 +3422,22 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3575
3422
|
writeFileSync2(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
|
|
3576
3423
|
}
|
|
3577
3424
|
appendFileSync(progressPath, progressEntry);
|
|
3578
|
-
console.log(
|
|
3425
|
+
console.log(chalk5.green("\n\u2713 Project details recorded!\n"));
|
|
3579
3426
|
const finalKnown = getKnownInfo(state);
|
|
3580
3427
|
if (finalKnown.length > 0) {
|
|
3581
|
-
console.log(
|
|
3428
|
+
console.log(chalk5.dim("Project configured with:"));
|
|
3582
3429
|
for (const info of finalKnown) {
|
|
3583
|
-
console.log(
|
|
3430
|
+
console.log(chalk5.dim(` \u2022 ${info}`));
|
|
3584
3431
|
}
|
|
3585
3432
|
console.log();
|
|
3586
3433
|
}
|
|
3587
|
-
console.log(
|
|
3588
|
-
console.log(` 1. ${
|
|
3589
|
-
console.log(` 2. ${
|
|
3434
|
+
console.log(chalk5.bold("Next steps:"));
|
|
3435
|
+
console.log(` 1. ${chalk5.cyan("Review")} ARCHITECTURE.md and customize if needed`);
|
|
3436
|
+
console.log(` 2. ${chalk5.cyan("Run")} ${chalk5.dim('archon plan "your first task"')} to create an atom`);
|
|
3590
3437
|
console.log();
|
|
3591
3438
|
const hintedTask = initialTaskHint?.trim() ?? "";
|
|
3592
3439
|
if (hintedTask) {
|
|
3593
|
-
console.log(
|
|
3440
|
+
console.log(chalk5.dim("Using your request above as the first task.\n"));
|
|
3594
3441
|
const { plan: plan2 } = await import("./plan-W4WQY7BR.js");
|
|
3595
3442
|
await plan2(hintedTask, { conversational: true });
|
|
3596
3443
|
return;
|
|
@@ -3608,7 +3455,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3608
3455
|
const hinted = initialTaskHint?.trim() ?? "";
|
|
3609
3456
|
if (hinted) {
|
|
3610
3457
|
description = hinted;
|
|
3611
|
-
console.log(
|
|
3458
|
+
console.log(chalk5.dim("\nUsing your request above as the first task.\n"));
|
|
3612
3459
|
} else {
|
|
3613
3460
|
description = await promptWithCommands("Describe what you want to build first", { allowMultiline: true });
|
|
3614
3461
|
}
|
|
@@ -3694,7 +3541,7 @@ function inferLanguageFromProjectFiles(cwd) {
|
|
|
3694
3541
|
return best?.language;
|
|
3695
3542
|
}
|
|
3696
3543
|
async function analyzeAndAdapt(cwd) {
|
|
3697
|
-
console.log(
|
|
3544
|
+
console.log(chalk5.blue("\n-- Analyzing Project --\n"));
|
|
3698
3545
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
3699
3546
|
await init2({ analyze: true, git: true });
|
|
3700
3547
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -3716,12 +3563,12 @@ async function analyzeAndAdapt(cwd) {
|
|
|
3716
3563
|
- .archon/config.yaml - Build commands configured
|
|
3717
3564
|
- progress.txt - This file
|
|
3718
3565
|
`);
|
|
3719
|
-
console.log(
|
|
3566
|
+
console.log(chalk5.green("\n\u2713 Governance files adapted!\n"));
|
|
3720
3567
|
await showMainMenu();
|
|
3721
3568
|
}
|
|
3722
3569
|
async function codeReviewFirst(cwd) {
|
|
3723
|
-
console.log(
|
|
3724
|
-
console.log(
|
|
3570
|
+
console.log(chalk5.blue("\n-- Code Review Mode --\n"));
|
|
3571
|
+
console.log(chalk5.dim("I'll analyze your code for issues without making any changes.\n"));
|
|
3725
3572
|
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-BXESOS5R.js");
|
|
3726
3573
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
3727
3574
|
if (!existsSync6(reviewDbPath)) {
|
|
@@ -3732,22 +3579,22 @@ async function codeReviewFirst(cwd) {
|
|
|
3732
3579
|
if (runReview) {
|
|
3733
3580
|
await reviewRun2({ all: true });
|
|
3734
3581
|
}
|
|
3735
|
-
console.log(
|
|
3582
|
+
console.log(chalk5.dim("\nAfter reviewing, you can run ") + chalk5.cyan("archon") + chalk5.dim(" again to set up governance.\n"));
|
|
3736
3583
|
}
|
|
3737
3584
|
async function runAgentMode(cwd, state) {
|
|
3738
3585
|
if (state.scenario === "CONTINUE_SESSION") {
|
|
3739
|
-
console.log(
|
|
3586
|
+
console.log(chalk5.bold("Welcome back!\n"));
|
|
3740
3587
|
if (state.lastProgressEntry) {
|
|
3741
|
-
console.log(
|
|
3742
|
-
console.log(
|
|
3588
|
+
console.log(chalk5.dim("Last activity:"));
|
|
3589
|
+
console.log(chalk5.dim(" " + state.lastProgressEntry.split("\n")[0]));
|
|
3743
3590
|
console.log();
|
|
3744
3591
|
}
|
|
3745
3592
|
} else if (state.scenario === "NEW_PROJECT") {
|
|
3746
|
-
console.log(
|
|
3747
|
-
console.log(
|
|
3593
|
+
console.log(chalk5.bold("Starting in chat mode.\n"));
|
|
3594
|
+
console.log(chalk5.dim("Tell me what you want to build. I will apply governance checks in the background.\n"));
|
|
3748
3595
|
} else {
|
|
3749
|
-
console.log(
|
|
3750
|
-
console.log(
|
|
3596
|
+
console.log(chalk5.bold("Ready in chat mode.\n"));
|
|
3597
|
+
console.log(chalk5.dim("Tell me what you want to do. Use /workflow for the classic menu.\n"));
|
|
3751
3598
|
}
|
|
3752
3599
|
while (true) {
|
|
3753
3600
|
const response = await promptWithCommands(
|
|
@@ -3764,7 +3611,7 @@ async function runAgentMode(cwd, state) {
|
|
|
3764
3611
|
}
|
|
3765
3612
|
const handled = await handleAgentConversationInput(cwd, trimmed);
|
|
3766
3613
|
if (!handled) {
|
|
3767
|
-
console.log(
|
|
3614
|
+
console.log(chalk5.yellow("I did not catch that. Describe your goal in one sentence."));
|
|
3768
3615
|
}
|
|
3769
3616
|
}
|
|
3770
3617
|
}
|
|
@@ -3775,17 +3622,57 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3775
3622
|
await continueWithCurrentTask(cwd);
|
|
3776
3623
|
return true;
|
|
3777
3624
|
}
|
|
3625
|
+
if (isReferenceToPreviousRequest(normalized)) {
|
|
3626
|
+
await showLatestPlannedAtom(cwd);
|
|
3627
|
+
return true;
|
|
3628
|
+
}
|
|
3778
3629
|
const intent = detectUserIntent(input);
|
|
3779
3630
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3780
|
-
console.log(
|
|
3631
|
+
console.log(chalk5.dim("\n> Got it! Analyzing the project...\n"));
|
|
3781
3632
|
await runExploreFlow(cwd, input, { agentMode: true });
|
|
3782
3633
|
return true;
|
|
3783
3634
|
}
|
|
3784
|
-
console.log(
|
|
3635
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3785
3636
|
const { plan: plan2 } = await import("./plan-W4WQY7BR.js");
|
|
3786
3637
|
await plan2(input, { conversational: true });
|
|
3638
|
+
if (shouldStopAfterPlanning(input)) {
|
|
3639
|
+
await showLatestPlannedAtom(cwd);
|
|
3640
|
+
return true;
|
|
3641
|
+
}
|
|
3642
|
+
await continueWithCurrentTask(cwd);
|
|
3787
3643
|
return true;
|
|
3788
3644
|
}
|
|
3645
|
+
function isReferenceToPreviousRequest(input) {
|
|
3646
|
+
const normalized = input.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
3647
|
+
if (!normalized) return false;
|
|
3648
|
+
return normalized === "that" || normalized === "that one" || normalized === "same thing" || normalized === "same request" || normalized.includes("what i wrote already") || normalized.includes("what i already wrote") || normalized.includes("same as above") || normalized.includes("as above") || normalized.includes("same as earlier") || normalized.includes("use what i wrote");
|
|
3649
|
+
}
|
|
3650
|
+
function shouldStopAfterPlanning(input) {
|
|
3651
|
+
const normalized = input.toLowerCase();
|
|
3652
|
+
return normalized.includes("plan before") || normalized.includes("before continuing") || normalized.includes("before we continue") || normalized.includes("show me your plan") || normalized.includes("give me your plan") || normalized.includes("come up with a plan") || normalized.includes("do not start yet");
|
|
3653
|
+
}
|
|
3654
|
+
async function showLatestPlannedAtom(cwd) {
|
|
3655
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-W4WQY7BR.js");
|
|
3656
|
+
const atoms = await listLocalAtoms2();
|
|
3657
|
+
if (atoms.length === 0) {
|
|
3658
|
+
console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
|
|
3659
|
+
return;
|
|
3660
|
+
}
|
|
3661
|
+
const latest = atoms.slice().sort((a, b) => {
|
|
3662
|
+
const aTime = new Date(String(a.updatedAt)).getTime();
|
|
3663
|
+
const bTime = new Date(String(b.updatedAt)).getTime();
|
|
3664
|
+
return bTime - aTime;
|
|
3665
|
+
})[0];
|
|
3666
|
+
if (!latest) {
|
|
3667
|
+
console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3670
|
+
console.log(chalk5.dim(`
|
|
3671
|
+
Showing latest planned atom (${latest.externalId})...
|
|
3672
|
+
`));
|
|
3673
|
+
const { show: show2 } = await import("./show-CXJPLCXD.js");
|
|
3674
|
+
await show2(latest.externalId);
|
|
3675
|
+
}
|
|
3789
3676
|
function isContinuationDirective(input) {
|
|
3790
3677
|
const normalized = input.trim().toLowerCase();
|
|
3791
3678
|
return normalized === "continue" || normalized === "continue." || normalized === "go on" || normalized === "go ahead" || normalized === "next" || normalized === "proceed" || normalized === "do it";
|
|
@@ -3795,15 +3682,15 @@ async function continueWithCurrentTask(cwd) {
|
|
|
3795
3682
|
const atoms = await listLocalAtoms2();
|
|
3796
3683
|
const pending = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS").sort((a, b) => a.externalId.localeCompare(b.externalId));
|
|
3797
3684
|
if (pending.length === 0) {
|
|
3798
|
-
console.log(
|
|
3685
|
+
console.log(chalk5.yellow("No pending atoms found. Tell me what to plan next."));
|
|
3799
3686
|
return;
|
|
3800
3687
|
}
|
|
3801
3688
|
const nextAtom = pending[0];
|
|
3802
3689
|
if (!nextAtom) {
|
|
3803
|
-
console.log(
|
|
3690
|
+
console.log(chalk5.yellow("No pending atoms found. Tell me what to plan next."));
|
|
3804
3691
|
return;
|
|
3805
3692
|
}
|
|
3806
|
-
console.log(
|
|
3693
|
+
console.log(chalk5.dim(`
|
|
3807
3694
|
Continuing with ${nextAtom.externalId}...
|
|
3808
3695
|
`));
|
|
3809
3696
|
const { execute: execute2 } = await import("./execute-3IUO33KY.js");
|
|
@@ -3813,14 +3700,14 @@ async function showMainMenu() {
|
|
|
3813
3700
|
const cwd = process.cwd();
|
|
3814
3701
|
while (true) {
|
|
3815
3702
|
const state = detectProjectState(cwd);
|
|
3816
|
-
console.log(
|
|
3703
|
+
console.log(chalk5.bold("What would you like to do?\n"));
|
|
3817
3704
|
if (state.isWebProject) {
|
|
3818
3705
|
const { loadWebChecks, formatWebCheckStatus } = await import("./web-checks-4BSYXWDF.js");
|
|
3819
3706
|
const prefs = await loadWebChecks(cwd);
|
|
3820
|
-
console.log(
|
|
3821
|
-
console.log(
|
|
3822
|
-
console.log(
|
|
3823
|
-
console.log(
|
|
3707
|
+
console.log(chalk5.dim("Web checks status:"));
|
|
3708
|
+
console.log(chalk5.dim(` A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
3709
|
+
console.log(chalk5.dim(` SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
3710
|
+
console.log(chalk5.dim(` GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
3824
3711
|
console.log();
|
|
3825
3712
|
}
|
|
3826
3713
|
const choices = [
|
|
@@ -3841,9 +3728,9 @@ async function showMainMenu() {
|
|
|
3841
3728
|
{ key: "q", label: "Quit", action: async () => process.exit(0) }
|
|
3842
3729
|
];
|
|
3843
3730
|
for (const choice2 of choices) {
|
|
3844
|
-
console.log(` ${
|
|
3731
|
+
console.log(` ${chalk5.cyan(choice2.key)}) ${choice2.label}`);
|
|
3845
3732
|
}
|
|
3846
|
-
console.log(
|
|
3733
|
+
console.log(chalk5.dim(' (Type "/" for quick commands, or "upgrade"/"help" anytime)'));
|
|
3847
3734
|
console.log();
|
|
3848
3735
|
const selected = await promptWithCommands("Tell me what you want to do (or enter a shortcut)", { allowMultiline: true });
|
|
3849
3736
|
const choice = choices.find((c) => c.key === selected.toLowerCase());
|
|
@@ -3854,11 +3741,11 @@ async function showMainMenu() {
|
|
|
3854
3741
|
if (selected.trim()) {
|
|
3855
3742
|
const handled = await handleFreeformJourneyInput(cwd, selected.trim());
|
|
3856
3743
|
if (!handled) {
|
|
3857
|
-
console.log(
|
|
3744
|
+
console.log(chalk5.yellow("I did not catch that. Try describing your goal in one sentence."));
|
|
3858
3745
|
}
|
|
3859
3746
|
continue;
|
|
3860
3747
|
}
|
|
3861
|
-
console.log(
|
|
3748
|
+
console.log(chalk5.yellow("Invalid choice. Please try again."));
|
|
3862
3749
|
}
|
|
3863
3750
|
}
|
|
3864
3751
|
async function handleFreeformJourneyInput(cwd, input) {
|
|
@@ -3866,23 +3753,23 @@ async function handleFreeformJourneyInput(cwd, input) {
|
|
|
3866
3753
|
if (!freeform) return false;
|
|
3867
3754
|
const intent = detectUserIntent(freeform);
|
|
3868
3755
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3869
|
-
console.log(
|
|
3756
|
+
console.log(chalk5.dim("\n> Got it! Analyzing the project...\n"));
|
|
3870
3757
|
await runExploreFlow(cwd, freeform);
|
|
3871
3758
|
return true;
|
|
3872
3759
|
}
|
|
3873
3760
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
3874
3761
|
const state = detectProjectState(cwd);
|
|
3875
3762
|
if (state.hasArchitecture) {
|
|
3876
|
-
console.log(
|
|
3763
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3877
3764
|
const { plan: plan3 } = await import("./plan-W4WQY7BR.js");
|
|
3878
3765
|
await plan3(freeform, { conversational: true });
|
|
3879
3766
|
return true;
|
|
3880
3767
|
}
|
|
3881
|
-
console.log(
|
|
3768
|
+
console.log(chalk5.dim("\n> Let me understand your project better...\n"));
|
|
3882
3769
|
await runConversationalInterview(cwd, freeform);
|
|
3883
3770
|
return true;
|
|
3884
3771
|
}
|
|
3885
|
-
console.log(
|
|
3772
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3886
3773
|
const { plan: plan2 } = await import("./plan-W4WQY7BR.js");
|
|
3887
3774
|
await plan2(freeform, { conversational: true });
|
|
3888
3775
|
return true;
|
|
@@ -3924,14 +3811,14 @@ function containsActionIntent(input) {
|
|
|
3924
3811
|
async function handlePostExploreAction(cwd, request) {
|
|
3925
3812
|
const intent = detectUserIntent(request);
|
|
3926
3813
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
3927
|
-
console.log(
|
|
3814
|
+
console.log(chalk5.dim("> Let me understand your project better...\n"));
|
|
3928
3815
|
await runConversationalInterview(cwd, request);
|
|
3929
3816
|
return;
|
|
3930
3817
|
}
|
|
3931
3818
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3932
|
-
console.log(
|
|
3819
|
+
console.log(chalk5.dim("> I can go deeper. Creating a concrete task from your request...\n"));
|
|
3933
3820
|
} else {
|
|
3934
|
-
console.log(
|
|
3821
|
+
console.log(chalk5.dim("> Got it! Creating a task for this...\n"));
|
|
3935
3822
|
}
|
|
3936
3823
|
const { plan: plan2 } = await import("./plan-W4WQY7BR.js");
|
|
3937
3824
|
await plan2(request, { conversational: true });
|
|
@@ -3956,7 +3843,7 @@ async function executeNext() {
|
|
|
3956
3843
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
3957
3844
|
const readyAtoms = atoms.filter((a) => a.status === "READY");
|
|
3958
3845
|
if (pendingAtoms.length === 0) {
|
|
3959
|
-
console.log(
|
|
3846
|
+
console.log(chalk5.yellow('No pending atoms. Use "archon plan" to create one.'));
|
|
3960
3847
|
return;
|
|
3961
3848
|
}
|
|
3962
3849
|
if (pendingAtoms.length > 1) {
|
|
@@ -3964,20 +3851,20 @@ async function executeNext() {
|
|
|
3964
3851
|
const prefs = await loadExecutionPreferences(cwd);
|
|
3965
3852
|
const config = await loadConfig();
|
|
3966
3853
|
const canUseCloud = (config.tier ?? "FREE") === "CREDITS";
|
|
3967
|
-
console.log(
|
|
3968
|
-
console.log(` ${
|
|
3969
|
-
console.log(` ${
|
|
3970
|
-
console.log(` ${
|
|
3971
|
-
console.log(` ${
|
|
3854
|
+
console.log(chalk5.blue("\n-- Project Analysis --\n"));
|
|
3855
|
+
console.log(` ${chalk5.bold("Atoms:")} ${analysis.atomCount}`);
|
|
3856
|
+
console.log(` ${chalk5.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
|
|
3857
|
+
console.log(` ${chalk5.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
|
|
3858
|
+
console.log(` ${chalk5.bold("Suggested:")} ${analysis.suggestedMode} - ${getModeDescription(analysis.suggestedMode)}`);
|
|
3972
3859
|
console.log();
|
|
3973
3860
|
let selectedMode = "sequential";
|
|
3974
3861
|
if (canUseCloud && prefs.cloudMode === "always" && analysis.suggestedMode === "parallel-cloud") {
|
|
3975
3862
|
selectedMode = "parallel-cloud";
|
|
3976
|
-
console.log(
|
|
3863
|
+
console.log(chalk5.green(`
|
|
3977
3864
|
\u2713 Auto-selected parallel cloud execution (preference: always)`));
|
|
3978
3865
|
} else if (prefs.parallelMode === "always" && analysis.suggestedMode !== "sequential") {
|
|
3979
3866
|
selectedMode = "parallel-local";
|
|
3980
|
-
console.log(
|
|
3867
|
+
console.log(chalk5.green(`
|
|
3981
3868
|
\u2713 Auto-selected parallel local execution (preference: always)`));
|
|
3982
3869
|
} else if (prefs.parallelMode === "ask" || canUseCloud && prefs.cloudMode === "ask") {
|
|
3983
3870
|
const options = [
|
|
@@ -3993,18 +3880,18 @@ async function executeNext() {
|
|
|
3993
3880
|
}
|
|
3994
3881
|
if (selectedMode !== "sequential") {
|
|
3995
3882
|
if (readyAtoms.length === 0) {
|
|
3996
|
-
console.log(
|
|
3883
|
+
console.log(chalk5.yellow("No READY atoms available for parallel execution."));
|
|
3997
3884
|
return;
|
|
3998
3885
|
}
|
|
3999
|
-
console.log(
|
|
3886
|
+
console.log(chalk5.dim("\nPending atoms:"));
|
|
4000
3887
|
for (const atom of readyAtoms) {
|
|
4001
|
-
console.log(
|
|
3888
|
+
console.log(chalk5.dim(` - ${atom.id}: ${atom.title}`));
|
|
4002
3889
|
}
|
|
4003
3890
|
console.log();
|
|
4004
3891
|
const raw = await prompt("Enter atom IDs to run in parallel (comma-separated, or press Enter for all)");
|
|
4005
3892
|
const selectedIds = raw.trim() ? raw.split(",").map((s) => s.trim()).filter(Boolean) : readyAtoms.map((a) => a.id);
|
|
4006
3893
|
if (selectedIds.length === 0) {
|
|
4007
|
-
console.log(
|
|
3894
|
+
console.log(chalk5.yellow("No atoms selected."));
|
|
4008
3895
|
return;
|
|
4009
3896
|
}
|
|
4010
3897
|
let runIds = selectedIds;
|
|
@@ -4015,7 +3902,7 @@ async function executeNext() {
|
|
|
4015
3902
|
);
|
|
4016
3903
|
if (!override) {
|
|
4017
3904
|
runIds = selectedIds.slice(0, prefs.maxParallelAgents);
|
|
4018
|
-
console.log(
|
|
3905
|
+
console.log(chalk5.dim(`Running first ${runIds.length} atoms.`));
|
|
4019
3906
|
}
|
|
4020
3907
|
}
|
|
4021
3908
|
if (selectedMode === "parallel-cloud") {
|
|
@@ -4034,7 +3921,7 @@ async function executeNext() {
|
|
|
4034
3921
|
const { execute: execute2 } = await import("./execute-3IUO33KY.js");
|
|
4035
3922
|
await execute2(targetId, {});
|
|
4036
3923
|
} else {
|
|
4037
|
-
console.log(
|
|
3924
|
+
console.log(chalk5.yellow("No atom to execute."));
|
|
4038
3925
|
}
|
|
4039
3926
|
}
|
|
4040
3927
|
async function reportBug() {
|
|
@@ -4056,19 +3943,19 @@ async function reviewCode() {
|
|
|
4056
3943
|
const cwd = process.cwd();
|
|
4057
3944
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
4058
3945
|
if (!existsSync6(reviewDbPath)) {
|
|
4059
|
-
console.log(
|
|
3946
|
+
console.log(chalk5.dim("Code review not initialized. Starting setup...\n"));
|
|
4060
3947
|
const { reviewInit: reviewInit2 } = await import("./review-BXESOS5R.js");
|
|
4061
3948
|
await reviewInit2();
|
|
4062
3949
|
console.log();
|
|
4063
3950
|
}
|
|
4064
|
-
console.log(
|
|
4065
|
-
console.log(
|
|
4066
|
-
console.log(` ${
|
|
4067
|
-
console.log(` ${
|
|
4068
|
-
console.log(` ${
|
|
4069
|
-
console.log(` ${
|
|
4070
|
-
console.log(` ${
|
|
4071
|
-
console.log(` ${
|
|
3951
|
+
console.log(chalk5.bold("\nCode Review Options:\n"));
|
|
3952
|
+
console.log(chalk5.dim("You can type naturally (recommended) or use a shortcut:\n"));
|
|
3953
|
+
console.log(` ${chalk5.cyan("1")}) Analyze project`);
|
|
3954
|
+
console.log(` ${chalk5.cyan("2")}) Show review status`);
|
|
3955
|
+
console.log(` ${chalk5.cyan("3")}) Review next file`);
|
|
3956
|
+
console.log(` ${chalk5.cyan("4")}) List all tasks`);
|
|
3957
|
+
console.log(` ${chalk5.cyan("5")}) Run AI review on all pending`);
|
|
3958
|
+
console.log(` ${chalk5.cyan("b")}) Back to main menu`);
|
|
4072
3959
|
console.log();
|
|
4073
3960
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4074
3961
|
const choice = resolveReviewChoice(raw);
|
|
@@ -4107,7 +3994,7 @@ async function reviewCode() {
|
|
|
4107
3994
|
return;
|
|
4108
3995
|
}
|
|
4109
3996
|
}
|
|
4110
|
-
console.log(
|
|
3997
|
+
console.log(chalk5.yellow("I did not catch that. Tell me what review action you want."));
|
|
4111
3998
|
}
|
|
4112
3999
|
await reviewCode();
|
|
4113
4000
|
}
|
|
@@ -4135,13 +4022,13 @@ async function handleInSessionCommand(input) {
|
|
|
4135
4022
|
}
|
|
4136
4023
|
if (normalized === "help" || normalized === "?" || normalized === "archon help") {
|
|
4137
4024
|
console.log();
|
|
4138
|
-
console.log(
|
|
4139
|
-
console.log(
|
|
4140
|
-
console.log(
|
|
4141
|
-
console.log(
|
|
4142
|
-
console.log(
|
|
4143
|
-
console.log(
|
|
4144
|
-
console.log(
|
|
4025
|
+
console.log(chalk5.bold("Available commands (type anytime):"));
|
|
4026
|
+
console.log(chalk5.dim(" upgrade \u2014 Switch to BYOK or Managed plan"));
|
|
4027
|
+
console.log(chalk5.dim(" status \u2014 Show login and tier status"));
|
|
4028
|
+
console.log(chalk5.dim(" keys \u2014 Manage API keys (BYOK tier)"));
|
|
4029
|
+
console.log(chalk5.dim(" /workflow \u2014 Open classic workflow menu"));
|
|
4030
|
+
console.log(chalk5.dim(" quit / q \u2014 Exit ArchonDev"));
|
|
4031
|
+
console.log(chalk5.dim(" skip \u2014 Skip current question"));
|
|
4145
4032
|
console.log();
|
|
4146
4033
|
return true;
|
|
4147
4034
|
}
|
|
@@ -4151,23 +4038,23 @@ async function handleInSessionCommand(input) {
|
|
|
4151
4038
|
return true;
|
|
4152
4039
|
}
|
|
4153
4040
|
if (normalized === "quit" || normalized === "exit" || normalized === "q") {
|
|
4154
|
-
console.log(
|
|
4041
|
+
console.log(chalk5.dim("Goodbye!"));
|
|
4155
4042
|
process.exit(0);
|
|
4156
4043
|
}
|
|
4157
4044
|
return false;
|
|
4158
4045
|
}
|
|
4159
4046
|
function showSlashCommandMenu() {
|
|
4160
4047
|
console.log();
|
|
4161
|
-
console.log(
|
|
4162
|
-
console.log(
|
|
4163
|
-
console.log(
|
|
4164
|
-
console.log(
|
|
4165
|
-
console.log(
|
|
4166
|
-
console.log(
|
|
4167
|
-
console.log(
|
|
4168
|
-
console.log(
|
|
4169
|
-
console.log(
|
|
4170
|
-
console.log(
|
|
4048
|
+
console.log(chalk5.bold("Quick Commands"));
|
|
4049
|
+
console.log(chalk5.dim(" /plan <task> Create a plan from a one-line task"));
|
|
4050
|
+
console.log(chalk5.dim(" /list List atoms"));
|
|
4051
|
+
console.log(chalk5.dim(" /execute Execute next atom"));
|
|
4052
|
+
console.log(chalk5.dim(" /review Open code review menu"));
|
|
4053
|
+
console.log(chalk5.dim(" /status Show account/status"));
|
|
4054
|
+
console.log(chalk5.dim(" /settings Open settings & preferences"));
|
|
4055
|
+
console.log(chalk5.dim(" /upgrade Open tier upgrade menu"));
|
|
4056
|
+
console.log(chalk5.dim(" /workflow Open classic workflow menu"));
|
|
4057
|
+
console.log(chalk5.dim(" /quit Exit ArchonDev"));
|
|
4171
4058
|
console.log();
|
|
4172
4059
|
}
|
|
4173
4060
|
async function handleSlashCommand(input) {
|
|
@@ -4216,7 +4103,7 @@ async function handleSlashCommand(input) {
|
|
|
4216
4103
|
return true;
|
|
4217
4104
|
case "/quit":
|
|
4218
4105
|
case "/exit":
|
|
4219
|
-
console.log(
|
|
4106
|
+
console.log(chalk5.dim("Goodbye!"));
|
|
4220
4107
|
process.exit(0);
|
|
4221
4108
|
}
|
|
4222
4109
|
return false;
|
|
@@ -4227,7 +4114,7 @@ function prompt(question) {
|
|
|
4227
4114
|
input: process.stdin,
|
|
4228
4115
|
output: process.stdout
|
|
4229
4116
|
});
|
|
4230
|
-
rl.question(`${
|
|
4117
|
+
rl.question(`${chalk5.cyan("?")} ${question}: `, (answer) => {
|
|
4231
4118
|
rl.close();
|
|
4232
4119
|
resolve(answer);
|
|
4233
4120
|
});
|
|
@@ -4254,7 +4141,7 @@ function promptMultiline(question) {
|
|
|
4254
4141
|
rl.on("close", () => {
|
|
4255
4142
|
resolve(lines.join("\n").trimEnd());
|
|
4256
4143
|
});
|
|
4257
|
-
rl.setPrompt(`${
|
|
4144
|
+
rl.setPrompt(`${chalk5.cyan("?")} ${question} (multi-line: end with a single '.' line or Ctrl+D): `);
|
|
4258
4145
|
rl.prompt();
|
|
4259
4146
|
});
|
|
4260
4147
|
}
|
|
@@ -4269,14 +4156,14 @@ async function promptWithCommands(question, options = {}) {
|
|
|
4269
4156
|
if (!handled) {
|
|
4270
4157
|
return answer;
|
|
4271
4158
|
}
|
|
4272
|
-
console.log(
|
|
4159
|
+
console.log(chalk5.dim("(Returning to previous question...)\n"));
|
|
4273
4160
|
}
|
|
4274
4161
|
}
|
|
4275
4162
|
async function runWebChecksSuite() {
|
|
4276
4163
|
const { a11yCheck: a11yCheck2 } = await import("./a11y-O35BAA25.js");
|
|
4277
4164
|
const { seoCheck } = await import("./seo-PMI42KRZ.js");
|
|
4278
4165
|
const { geoAudit } = await import("./geo-HRG7M7YX.js");
|
|
4279
|
-
console.log(
|
|
4166
|
+
console.log(chalk5.blue("\nRunning web checks (A11y, SEO, GEO)...\n"));
|
|
4280
4167
|
await a11yCheck2({});
|
|
4281
4168
|
await seoCheck({});
|
|
4282
4169
|
await geoAudit();
|
|
@@ -4285,19 +4172,19 @@ async function showWebChecksMenu() {
|
|
|
4285
4172
|
const cwd = process.cwd();
|
|
4286
4173
|
const { loadWebChecks, formatWebCheckStatus, setWebPromptMode } = await import("./web-checks-4BSYXWDF.js");
|
|
4287
4174
|
const prefs = await loadWebChecks(cwd);
|
|
4288
|
-
console.log(
|
|
4289
|
-
console.log(
|
|
4290
|
-
console.log(
|
|
4291
|
-
console.log(
|
|
4175
|
+
console.log(chalk5.bold("\nWeb Checks (SEO / GEO / A11y)\n"));
|
|
4176
|
+
console.log(chalk5.dim(`A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
4177
|
+
console.log(chalk5.dim(`SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
4178
|
+
console.log(chalk5.dim(`GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
4292
4179
|
console.log();
|
|
4293
|
-
console.log(` ${
|
|
4294
|
-
console.log(` ${
|
|
4295
|
-
console.log(` ${
|
|
4296
|
-
console.log(` ${
|
|
4297
|
-
console.log(` ${
|
|
4298
|
-
console.log(` ${
|
|
4299
|
-
console.log(` ${
|
|
4300
|
-
console.log(` ${
|
|
4180
|
+
console.log(` ${chalk5.cyan("1")}) Run all checks`);
|
|
4181
|
+
console.log(` ${chalk5.cyan("2")}) Run accessibility check`);
|
|
4182
|
+
console.log(` ${chalk5.cyan("3")}) Run SEO check`);
|
|
4183
|
+
console.log(` ${chalk5.cyan("4")}) Run GEO audit`);
|
|
4184
|
+
console.log(` ${chalk5.cyan("5")}) Generate GEO identity`);
|
|
4185
|
+
console.log(` ${chalk5.cyan("6")}) Generate GEO schema`);
|
|
4186
|
+
console.log(` ${chalk5.cyan("7")}) Set prompt mode (ask/always/never)`);
|
|
4187
|
+
console.log(` ${chalk5.cyan("b")}) Back to main menu`);
|
|
4301
4188
|
console.log();
|
|
4302
4189
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4303
4190
|
const choice = resolveWebChecksChoice(raw);
|
|
@@ -4332,9 +4219,9 @@ async function showWebChecksMenu() {
|
|
|
4332
4219
|
}
|
|
4333
4220
|
case "7": {
|
|
4334
4221
|
console.log();
|
|
4335
|
-
console.log(` ${
|
|
4336
|
-
console.log(` ${
|
|
4337
|
-
console.log(` ${
|
|
4222
|
+
console.log(` ${chalk5.cyan("1")}) Ask each session`);
|
|
4223
|
+
console.log(` ${chalk5.cyan("2")}) Always run automatically`);
|
|
4224
|
+
console.log(` ${chalk5.cyan("3")}) Never prompt`);
|
|
4338
4225
|
console.log();
|
|
4339
4226
|
const modeChoiceRaw = await promptWithCommands("Set mode (ask / always / never)");
|
|
4340
4227
|
const modeChoice = resolvePromptModeChoice(modeChoiceRaw);
|
|
@@ -4350,7 +4237,7 @@ async function showWebChecksMenu() {
|
|
|
4350
4237
|
return;
|
|
4351
4238
|
}
|
|
4352
4239
|
}
|
|
4353
|
-
console.log(
|
|
4240
|
+
console.log(chalk5.yellow("I did not catch that. Tell me which web check you want."));
|
|
4354
4241
|
}
|
|
4355
4242
|
if (choice.toLowerCase() !== "b") {
|
|
4356
4243
|
await showWebChecksMenu();
|
|
@@ -4366,11 +4253,11 @@ async function maybePromptWebChecks(cwd, projectState) {
|
|
|
4366
4253
|
return;
|
|
4367
4254
|
}
|
|
4368
4255
|
if (prefs.promptMode === "always") {
|
|
4369
|
-
console.log(
|
|
4256
|
+
console.log(chalk5.blue("\nWeb project detected. Running web checks automatically...\n"));
|
|
4370
4257
|
await runWebChecksSuite();
|
|
4371
4258
|
return;
|
|
4372
4259
|
}
|
|
4373
|
-
console.log(
|
|
4260
|
+
console.log(chalk5.blue("\nWeb project detected."));
|
|
4374
4261
|
const choice = await promptChoice("Run web checks now?", [
|
|
4375
4262
|
{ key: "1", label: "Run all checks (A11y + SEO + GEO)" },
|
|
4376
4263
|
{ key: "2", label: "Choose checks" },
|
|
@@ -4392,7 +4279,7 @@ function promptYesNo(question, defaultValue) {
|
|
|
4392
4279
|
output: process.stdout
|
|
4393
4280
|
});
|
|
4394
4281
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
4395
|
-
rl.question(`${
|
|
4282
|
+
rl.question(`${chalk5.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
4396
4283
|
rl.close();
|
|
4397
4284
|
if (answer.trim() === "") {
|
|
4398
4285
|
resolve(defaultValue);
|
|
@@ -4404,15 +4291,15 @@ function promptYesNo(question, defaultValue) {
|
|
|
4404
4291
|
}
|
|
4405
4292
|
function promptChoice(question, options, defaultKey) {
|
|
4406
4293
|
return new Promise((resolve) => {
|
|
4407
|
-
console.log(`${
|
|
4294
|
+
console.log(`${chalk5.cyan("?")} ${question}`);
|
|
4408
4295
|
for (const opt of options) {
|
|
4409
|
-
console.log(` ${
|
|
4296
|
+
console.log(` ${chalk5.dim(opt.key)}) ${opt.label}`);
|
|
4410
4297
|
}
|
|
4411
4298
|
const rl = readline.createInterface({
|
|
4412
4299
|
input: process.stdin,
|
|
4413
4300
|
output: process.stdout
|
|
4414
4301
|
});
|
|
4415
|
-
rl.question(` ${
|
|
4302
|
+
rl.question(` ${chalk5.dim("Enter choice or describe what you want")}: `, (answer) => {
|
|
4416
4303
|
rl.close();
|
|
4417
4304
|
const trimmed = answer.trim();
|
|
4418
4305
|
if (trimmed) {
|
|
@@ -4475,7 +4362,7 @@ function resolvePromptModeChoice(input) {
|
|
|
4475
4362
|
}
|
|
4476
4363
|
|
|
4477
4364
|
// src/cli/credits.ts
|
|
4478
|
-
import
|
|
4365
|
+
import chalk6 from "chalk";
|
|
4479
4366
|
import ora from "ora";
|
|
4480
4367
|
import open from "open";
|
|
4481
4368
|
import readline2 from "readline";
|
|
@@ -4521,20 +4408,20 @@ async function showCredits() {
|
|
|
4521
4408
|
const profile = data;
|
|
4522
4409
|
spinner.stop();
|
|
4523
4410
|
console.log();
|
|
4524
|
-
console.log(
|
|
4411
|
+
console.log(chalk6.bold("\u{1F4B0} Credit Balance"));
|
|
4525
4412
|
console.log();
|
|
4526
4413
|
const balance = (profile.credit_balance_cents || 0) / 100;
|
|
4527
4414
|
console.log(` Tier: ${formatTier(profile.tier)}`);
|
|
4528
|
-
console.log(` Balance: ${
|
|
4415
|
+
console.log(` Balance: ${chalk6.green(`$${balance.toFixed(2)}`)}`);
|
|
4529
4416
|
if (profile.tier === "FREE") {
|
|
4530
4417
|
console.log(` Atoms: ${profile.atoms_used_this_month}/10,000 this month`);
|
|
4531
4418
|
console.log();
|
|
4532
|
-
console.log(
|
|
4419
|
+
console.log(chalk6.dim(" Upgrade to Credits tier: archon credits add"));
|
|
4533
4420
|
printCreditsNextAction("FREE");
|
|
4534
4421
|
} else if (profile.tier === "CREDITS") {
|
|
4535
4422
|
console.log();
|
|
4536
|
-
console.log(
|
|
4537
|
-
console.log(
|
|
4423
|
+
console.log(chalk6.dim(" Add more credits: archon credits add"));
|
|
4424
|
+
console.log(chalk6.dim(" Detailed usage by model: archon usage"));
|
|
4538
4425
|
printCreditsNextAction("CREDITS");
|
|
4539
4426
|
if (balance < 5) {
|
|
4540
4427
|
const addNow = await promptYesNo2("Balance is low. Add credits now?", false);
|
|
@@ -4544,8 +4431,8 @@ async function showCredits() {
|
|
|
4544
4431
|
}
|
|
4545
4432
|
} else if (profile.tier === "BYOK") {
|
|
4546
4433
|
console.log();
|
|
4547
|
-
console.log(
|
|
4548
|
-
console.log(
|
|
4434
|
+
console.log(chalk6.dim(" Using your own API keys - no credit charges"));
|
|
4435
|
+
console.log(chalk6.dim(" Estimated spend by model: archon usage"));
|
|
4549
4436
|
printCreditsNextAction("BYOK");
|
|
4550
4437
|
}
|
|
4551
4438
|
console.log();
|
|
@@ -4592,35 +4479,35 @@ async function addCredits(options = {}) {
|
|
|
4592
4479
|
}
|
|
4593
4480
|
spinner.succeed("Checkout ready");
|
|
4594
4481
|
console.log();
|
|
4595
|
-
console.log(
|
|
4482
|
+
console.log(chalk6.bold("\u{1F6D2} Add Credits"));
|
|
4596
4483
|
console.log();
|
|
4597
|
-
console.log(` Amount: ${
|
|
4484
|
+
console.log(` Amount: ${chalk6.green(`$${amountDollars.toFixed(2)}`)}`);
|
|
4598
4485
|
console.log();
|
|
4599
4486
|
console.log(" Opening checkout in browser...");
|
|
4600
4487
|
console.log();
|
|
4601
|
-
console.log(
|
|
4488
|
+
console.log(chalk6.dim(` Or visit: ${checkoutUrl}`));
|
|
4602
4489
|
console.log();
|
|
4603
4490
|
try {
|
|
4604
4491
|
await open(checkoutUrl);
|
|
4605
4492
|
} catch {
|
|
4606
|
-
console.log(
|
|
4493
|
+
console.log(chalk6.yellow(" Could not open browser. Please visit the URL above."));
|
|
4607
4494
|
}
|
|
4608
|
-
console.log(
|
|
4609
|
-
console.log(
|
|
4610
|
-
console.log(
|
|
4495
|
+
console.log(chalk6.bold("\nNext best action:"));
|
|
4496
|
+
console.log(chalk6.dim(` \u2022 Complete payment in browser, then run ${chalk6.cyan("archon credits")} to verify balance.`));
|
|
4497
|
+
console.log(chalk6.dim(` \u2022 Continue work with ${chalk6.cyan('archon plan "..."')} or ${chalk6.cyan("archon execute <ATOM-ID>")}.`));
|
|
4611
4498
|
} catch (err2) {
|
|
4612
4499
|
spinner.fail("Error preparing checkout");
|
|
4613
4500
|
console.error(err2);
|
|
4614
4501
|
}
|
|
4615
4502
|
}
|
|
4616
4503
|
function printCreditsNextAction(tier) {
|
|
4617
|
-
console.log(
|
|
4504
|
+
console.log(chalk6.bold(" Next best action:"));
|
|
4618
4505
|
if (tier === "CREDITS") {
|
|
4619
|
-
console.log(
|
|
4506
|
+
console.log(chalk6.dim(` \u2022 Keep at least $5 balance to avoid interruptions during plan/execute.`));
|
|
4620
4507
|
} else if (tier === "BYOK") {
|
|
4621
|
-
console.log(
|
|
4508
|
+
console.log(chalk6.dim(` \u2022 Manage provider keys with ${chalk6.cyan("archon keys add/list/remove")}.`));
|
|
4622
4509
|
} else {
|
|
4623
|
-
console.log(
|
|
4510
|
+
console.log(chalk6.dim(` \u2022 Upgrade to BYOK or Credits with ${chalk6.cyan("archon upgrade")}.`));
|
|
4624
4511
|
}
|
|
4625
4512
|
}
|
|
4626
4513
|
function promptYesNo2(question, defaultValue) {
|
|
@@ -4630,7 +4517,7 @@ function promptYesNo2(question, defaultValue) {
|
|
|
4630
4517
|
output: process.stdout
|
|
4631
4518
|
});
|
|
4632
4519
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
4633
|
-
rl.question(`${
|
|
4520
|
+
rl.question(`${chalk6.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
4634
4521
|
rl.close();
|
|
4635
4522
|
if (answer.trim() === "") {
|
|
4636
4523
|
resolve(defaultValue);
|
|
@@ -4664,15 +4551,15 @@ async function showHistory(options = {}) {
|
|
|
4664
4551
|
const usage = data;
|
|
4665
4552
|
spinner.stop();
|
|
4666
4553
|
console.log();
|
|
4667
|
-
console.log(
|
|
4554
|
+
console.log(chalk6.bold("Usage History"));
|
|
4668
4555
|
console.log();
|
|
4669
4556
|
if (!usage || usage.length === 0) {
|
|
4670
|
-
console.log(
|
|
4557
|
+
console.log(chalk6.dim(" No usage recorded yet."));
|
|
4671
4558
|
console.log();
|
|
4672
4559
|
return;
|
|
4673
4560
|
}
|
|
4674
|
-
console.log(
|
|
4675
|
-
console.log(
|
|
4561
|
+
console.log(chalk6.dim(" Model Tokens Cost Date"));
|
|
4562
|
+
console.log(chalk6.dim(" \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\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"));
|
|
4676
4563
|
for (const row of usage) {
|
|
4677
4564
|
const model = row.model.padEnd(30).slice(0, 30);
|
|
4678
4565
|
const tokens = (row.input_tokens + row.output_tokens).toString().padStart(8);
|
|
@@ -4682,9 +4569,9 @@ async function showHistory(options = {}) {
|
|
|
4682
4569
|
}
|
|
4683
4570
|
const totalCost = usage.reduce((sum, r) => sum + r.base_cost, 0);
|
|
4684
4571
|
const totalTokens = usage.reduce((sum, r) => sum + r.input_tokens + r.output_tokens, 0);
|
|
4685
|
-
console.log(
|
|
4572
|
+
console.log(chalk6.dim(" \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\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"));
|
|
4686
4573
|
console.log(
|
|
4687
|
-
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${
|
|
4574
|
+
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${chalk6.green(`$${totalCost.toFixed(4)}`.padStart(10))}`
|
|
4688
4575
|
);
|
|
4689
4576
|
console.log();
|
|
4690
4577
|
} catch (err2) {
|
|
@@ -4750,24 +4637,24 @@ async function manageBudget(options = {}) {
|
|
|
4750
4637
|
}
|
|
4751
4638
|
spinner.stop();
|
|
4752
4639
|
console.log();
|
|
4753
|
-
console.log(
|
|
4640
|
+
console.log(chalk6.bold("Monthly Budget"));
|
|
4754
4641
|
console.log();
|
|
4755
4642
|
if (profile.monthly_budget_cents === null) {
|
|
4756
|
-
console.log(` Budget: ${
|
|
4643
|
+
console.log(` Budget: ${chalk6.dim("No limit set")}`);
|
|
4757
4644
|
} else {
|
|
4758
4645
|
const budget = profile.monthly_budget_cents / 100;
|
|
4759
4646
|
const spend = (profile.monthly_spend_cents || 0) / 100;
|
|
4760
4647
|
const remaining = budget - spend;
|
|
4761
4648
|
const percent = budget > 0 ? Math.round(spend / budget * 100) : 0;
|
|
4762
|
-
console.log(` Budget: ${
|
|
4649
|
+
console.log(` Budget: ${chalk6.green(`$${budget.toFixed(2)}`)} / month`);
|
|
4763
4650
|
console.log(` Spent: $${spend.toFixed(2)} (${percent}%)`);
|
|
4764
|
-
console.log(` Remaining: ${remaining >= 0 ?
|
|
4651
|
+
console.log(` Remaining: ${remaining >= 0 ? chalk6.green(`$${remaining.toFixed(2)}`) : chalk6.red(`-$${Math.abs(remaining).toFixed(2)}`)}`);
|
|
4765
4652
|
}
|
|
4766
4653
|
console.log(` Alert at: ${profile.budget_alert_threshold_percent}% of budget`);
|
|
4767
4654
|
console.log();
|
|
4768
|
-
console.log(
|
|
4769
|
-
console.log(
|
|
4770
|
-
console.log(
|
|
4655
|
+
console.log(chalk6.dim(" Set budget: archon credits budget --set 50"));
|
|
4656
|
+
console.log(chalk6.dim(" Clear budget: archon credits budget --clear"));
|
|
4657
|
+
console.log(chalk6.dim(" Set alert: archon credits budget --alert 80"));
|
|
4771
4658
|
console.log();
|
|
4772
4659
|
} catch (err2) {
|
|
4773
4660
|
spinner.fail("Error managing budget");
|
|
@@ -4829,12 +4716,12 @@ async function manageAutoRecharge(options = {}) {
|
|
|
4829
4716
|
}
|
|
4830
4717
|
spinner.stop();
|
|
4831
4718
|
console.log();
|
|
4832
|
-
console.log(
|
|
4719
|
+
console.log(chalk6.bold("\u{1F504} Auto-Recharge"));
|
|
4833
4720
|
console.log();
|
|
4834
4721
|
if (!profile.auto_recharge_enabled) {
|
|
4835
|
-
console.log(` Status: ${
|
|
4722
|
+
console.log(` Status: ${chalk6.dim("Disabled")}`);
|
|
4836
4723
|
} else {
|
|
4837
|
-
console.log(` Status: ${
|
|
4724
|
+
console.log(` Status: ${chalk6.green("Enabled")}`);
|
|
4838
4725
|
if (profile.auto_recharge_threshold_cents !== null) {
|
|
4839
4726
|
console.log(` When: Balance drops below $${(profile.auto_recharge_threshold_cents / 100).toFixed(2)}`);
|
|
4840
4727
|
}
|
|
@@ -4842,10 +4729,10 @@ async function manageAutoRecharge(options = {}) {
|
|
|
4842
4729
|
console.log(` Amount: $${(profile.auto_recharge_amount_cents / 100).toFixed(2)}`);
|
|
4843
4730
|
}
|
|
4844
4731
|
}
|
|
4845
|
-
console.log(` Payment: ${profile.stripe_payment_method_id ?
|
|
4732
|
+
console.log(` Payment: ${profile.stripe_payment_method_id ? chalk6.green("Card saved") : chalk6.dim("No card saved")}`);
|
|
4846
4733
|
console.log();
|
|
4847
|
-
console.log(
|
|
4848
|
-
console.log(
|
|
4734
|
+
console.log(chalk6.dim(" Enable: archon credits auto-recharge --enable --threshold 5 --amount 20"));
|
|
4735
|
+
console.log(chalk6.dim(" Disable: archon credits auto-recharge --disable"));
|
|
4849
4736
|
console.log();
|
|
4850
4737
|
} catch (err2) {
|
|
4851
4738
|
spinner.fail("Error managing auto-recharge");
|
|
@@ -4875,21 +4762,21 @@ async function showAuditHistory(options = {}) {
|
|
|
4875
4762
|
});
|
|
4876
4763
|
if (error) {
|
|
4877
4764
|
spinner.fail("Could not fetch audit history");
|
|
4878
|
-
console.error(
|
|
4765
|
+
console.error(chalk6.dim(error.message));
|
|
4879
4766
|
return;
|
|
4880
4767
|
}
|
|
4881
4768
|
const history = data;
|
|
4882
4769
|
spinner.stop();
|
|
4883
4770
|
console.log();
|
|
4884
|
-
console.log(
|
|
4771
|
+
console.log(chalk6.bold("\u{1F4CB} Billing Audit History"));
|
|
4885
4772
|
console.log();
|
|
4886
4773
|
if (!history || history.length === 0) {
|
|
4887
|
-
console.log(
|
|
4774
|
+
console.log(chalk6.dim(" No billing events recorded yet."));
|
|
4888
4775
|
console.log();
|
|
4889
4776
|
return;
|
|
4890
4777
|
}
|
|
4891
|
-
console.log(
|
|
4892
|
-
console.log(
|
|
4778
|
+
console.log(chalk6.dim(" Event Amount Balance Date"));
|
|
4779
|
+
console.log(chalk6.dim(" \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\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"));
|
|
4893
4780
|
for (const row of history) {
|
|
4894
4781
|
const eventType = formatEventType(row.event_type).padEnd(22);
|
|
4895
4782
|
const amount = row.amount_cents !== null ? formatAmount(row.event_type, row.amount_cents).padStart(10) : " -";
|
|
@@ -4897,10 +4784,10 @@ async function showAuditHistory(options = {}) {
|
|
|
4897
4784
|
const date = new Date(row.created_at).toLocaleDateString();
|
|
4898
4785
|
console.log(` ${eventType} ${amount} ${balance} ${date}`);
|
|
4899
4786
|
}
|
|
4900
|
-
console.log(
|
|
4787
|
+
console.log(chalk6.dim(" \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\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"));
|
|
4901
4788
|
console.log();
|
|
4902
|
-
console.log(
|
|
4903
|
-
console.log(
|
|
4789
|
+
console.log(chalk6.dim(` Showing ${history.length} most recent events`));
|
|
4790
|
+
console.log(chalk6.dim(" Use --limit N to show more"));
|
|
4904
4791
|
console.log();
|
|
4905
4792
|
} catch (err2) {
|
|
4906
4793
|
spinner.fail("Error fetching audit history");
|
|
@@ -4910,19 +4797,19 @@ async function showAuditHistory(options = {}) {
|
|
|
4910
4797
|
function formatEventType(eventType) {
|
|
4911
4798
|
switch (eventType) {
|
|
4912
4799
|
case "CREDITS_PURCHASED":
|
|
4913
|
-
return
|
|
4800
|
+
return chalk6.green("+ Purchase");
|
|
4914
4801
|
case "CREDITS_DEDUCTED":
|
|
4915
|
-
return
|
|
4802
|
+
return chalk6.red("- Usage");
|
|
4916
4803
|
case "CREDITS_REFUNDED":
|
|
4917
|
-
return
|
|
4804
|
+
return chalk6.cyan("+ Refund");
|
|
4918
4805
|
case "BALANCE_ADJUSTED":
|
|
4919
|
-
return
|
|
4806
|
+
return chalk6.yellow("\xB1 Adjustment");
|
|
4920
4807
|
case "BUDGET_CHANGED":
|
|
4921
|
-
return
|
|
4808
|
+
return chalk6.blue("\u25C9 Budget");
|
|
4922
4809
|
case "TIER_CHANGED":
|
|
4923
|
-
return
|
|
4810
|
+
return chalk6.magenta("\u25C9 Tier");
|
|
4924
4811
|
case "USAGE_RECORDED":
|
|
4925
|
-
return
|
|
4812
|
+
return chalk6.dim("\u25C9 Usage");
|
|
4926
4813
|
default:
|
|
4927
4814
|
return eventType;
|
|
4928
4815
|
}
|
|
@@ -4930,20 +4817,20 @@ function formatEventType(eventType) {
|
|
|
4930
4817
|
function formatAmount(eventType, cents) {
|
|
4931
4818
|
const dollars = (cents / 100).toFixed(2);
|
|
4932
4819
|
if (eventType === "CREDITS_PURCHASED" || eventType === "CREDITS_REFUNDED") {
|
|
4933
|
-
return
|
|
4820
|
+
return chalk6.green(`+$${dollars}`);
|
|
4934
4821
|
} else if (eventType === "CREDITS_DEDUCTED") {
|
|
4935
|
-
return
|
|
4822
|
+
return chalk6.red(`-$${dollars}`);
|
|
4936
4823
|
}
|
|
4937
4824
|
return `$${dollars}`;
|
|
4938
4825
|
}
|
|
4939
4826
|
function formatTier(tier) {
|
|
4940
4827
|
switch (tier) {
|
|
4941
4828
|
case "FREE":
|
|
4942
|
-
return
|
|
4829
|
+
return chalk6.blue("Free (10k atoms/month)");
|
|
4943
4830
|
case "CREDITS":
|
|
4944
|
-
return
|
|
4831
|
+
return chalk6.green("Credits (Pay-as-you-go)");
|
|
4945
4832
|
case "BYOK":
|
|
4946
|
-
return
|
|
4833
|
+
return chalk6.magenta("BYOK (Bring Your Own Key)");
|
|
4947
4834
|
default:
|
|
4948
4835
|
return tier;
|
|
4949
4836
|
}
|
|
@@ -4956,7 +4843,7 @@ import Spinner from "ink-spinner";
|
|
|
4956
4843
|
import * as fs from "fs";
|
|
4957
4844
|
import * as path from "path";
|
|
4958
4845
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4959
|
-
var
|
|
4846
|
+
var STATUS_COLORS = {
|
|
4960
4847
|
DRAFT: "gray",
|
|
4961
4848
|
READY: "blue",
|
|
4962
4849
|
IN_PROGRESS: "yellow",
|
|
@@ -5039,7 +4926,7 @@ function AtomList({ atoms }) {
|
|
|
5039
4926
|
] }),
|
|
5040
4927
|
atoms.slice(0, 15).map((atom) => /* @__PURE__ */ jsxs(Box, { paddingX: 1, children: [
|
|
5041
4928
|
/* @__PURE__ */ jsx(Box, { width: 12, children: /* @__PURE__ */ jsx(Text, { children: atom.id.slice(0, 10) }) }),
|
|
5042
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color:
|
|
4929
|
+
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color: STATUS_COLORS[atom.status], children: [
|
|
5043
4930
|
STATUS_ICONS[atom.status],
|
|
5044
4931
|
" ",
|
|
5045
4932
|
atom.status.slice(0, 7)
|
|
@@ -5100,7 +4987,7 @@ function RecentActivity({ atoms }) {
|
|
|
5100
4987
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Recent Activity" }) }),
|
|
5101
4988
|
recentAtoms.map((atom) => /* @__PURE__ */ jsxs(Box, { marginBottom: 0, children: [
|
|
5102
4989
|
/* @__PURE__ */ jsx(Box, { width: 20, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: formatTime(new Date(atom.updatedAt)) }) }),
|
|
5103
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color:
|
|
4990
|
+
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color: STATUS_COLORS[atom.status], children: [
|
|
5104
4991
|
STATUS_ICONS[atom.status],
|
|
5105
4992
|
" ",
|
|
5106
4993
|
atom.status.slice(0, 7)
|
|
@@ -5220,7 +5107,7 @@ async function watch() {
|
|
|
5220
5107
|
|
|
5221
5108
|
// src/cli/deps.ts
|
|
5222
5109
|
import { Command } from "commander";
|
|
5223
|
-
import
|
|
5110
|
+
import chalk7 from "chalk";
|
|
5224
5111
|
import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
5225
5112
|
import { existsSync as existsSync8 } from "fs";
|
|
5226
5113
|
var DEPENDENCIES_FILENAME = "DEPENDENCIES.md";
|
|
@@ -5238,30 +5125,30 @@ Examples:
|
|
|
5238
5125
|
deps.command("list").description("List all dependency rules").option("-v, --verbose", "Show detailed information").action(async (options) => {
|
|
5239
5126
|
const parser = new DependencyParser();
|
|
5240
5127
|
if (!parser.exists()) {
|
|
5241
|
-
console.log(
|
|
5242
|
-
console.log(
|
|
5128
|
+
console.log(chalk7.yellow("No DEPENDENCIES.md found."));
|
|
5129
|
+
console.log(chalk7.dim("Create one with: archon deps add --source <path> --dependent <path>"));
|
|
5243
5130
|
return;
|
|
5244
5131
|
}
|
|
5245
5132
|
const result = await parser.parse();
|
|
5246
5133
|
if (!result.success) {
|
|
5247
|
-
console.log(
|
|
5134
|
+
console.log(chalk7.red(`Parse error: ${result.error}`));
|
|
5248
5135
|
return;
|
|
5249
5136
|
}
|
|
5250
5137
|
const rules = result.document?.rules ?? [];
|
|
5251
5138
|
if (rules.length === 0) {
|
|
5252
|
-
console.log(
|
|
5139
|
+
console.log(chalk7.dim("No dependency rules defined."));
|
|
5253
5140
|
return;
|
|
5254
5141
|
}
|
|
5255
|
-
console.log(
|
|
5142
|
+
console.log(chalk7.bold(`
|
|
5256
5143
|
\u{1F4E6} Dependency Rules (${rules.length})
|
|
5257
5144
|
`));
|
|
5258
5145
|
for (const rule of rules) {
|
|
5259
|
-
const severityColor = rule.severity === "BLOCKER" ?
|
|
5260
|
-
console.log(`${severityColor(`[${rule.severity}]`)} ${
|
|
5261
|
-
console.log(` Source: ${
|
|
5262
|
-
console.log(` Dependents: ${rule.dependents.map((d) =>
|
|
5146
|
+
const severityColor = rule.severity === "BLOCKER" ? chalk7.red : rule.severity === "WARNING" ? chalk7.yellow : chalk7.blue;
|
|
5147
|
+
console.log(`${severityColor(`[${rule.severity}]`)} ${chalk7.bold(rule.id)}`);
|
|
5148
|
+
console.log(` Source: ${chalk7.cyan(rule.source)}`);
|
|
5149
|
+
console.log(` Dependents: ${rule.dependents.map((d) => chalk7.dim(d)).join(", ")}`);
|
|
5263
5150
|
if (rule.reason && options.verbose) {
|
|
5264
|
-
console.log(` Reason: ${
|
|
5151
|
+
console.log(` Reason: ${chalk7.dim(rule.reason)}`);
|
|
5265
5152
|
}
|
|
5266
5153
|
if (rule.mustTest && options.verbose) {
|
|
5267
5154
|
console.log(` Must test: ${rule.mustTest.join(", ")}`);
|
|
@@ -5273,29 +5160,29 @@ Examples:
|
|
|
5273
5160
|
const files = options.files.split(",").map((f) => f.trim());
|
|
5274
5161
|
const parser = new DependencyParser();
|
|
5275
5162
|
if (!parser.exists()) {
|
|
5276
|
-
console.log(
|
|
5163
|
+
console.log(chalk7.dim("No DEPENDENCIES.md found. No dependency checks performed."));
|
|
5277
5164
|
process.exit(0);
|
|
5278
5165
|
}
|
|
5279
5166
|
const result = await parser.checkFiles(files);
|
|
5280
5167
|
if (result.impacts.length === 0) {
|
|
5281
|
-
console.log(
|
|
5168
|
+
console.log(chalk7.green("\u2705 No downstream dependency impacts found."));
|
|
5282
5169
|
process.exit(0);
|
|
5283
5170
|
}
|
|
5284
|
-
console.log(
|
|
5171
|
+
console.log(chalk7.yellow(`
|
|
5285
5172
|
[!] Found ${result.impacts.length} dependency impact(s):
|
|
5286
5173
|
`));
|
|
5287
5174
|
for (const impact of result.impacts) {
|
|
5288
|
-
const severityColor = impact.rule.severity === "BLOCKER" ?
|
|
5175
|
+
const severityColor = impact.rule.severity === "BLOCKER" ? chalk7.red : impact.rule.severity === "WARNING" ? chalk7.yellow : chalk7.blue;
|
|
5289
5176
|
console.log(severityColor(`[${impact.rule.severity}] ${impact.rule.id}`));
|
|
5290
|
-
console.log(` Changing: ${
|
|
5177
|
+
console.log(` Changing: ${chalk7.cyan(impact.matchedSource)}`);
|
|
5291
5178
|
console.log(` May impact: ${impact.affectedDependents.join(", ")}`);
|
|
5292
5179
|
if (impact.rule.reason) {
|
|
5293
|
-
console.log(` Reason: ${
|
|
5180
|
+
console.log(` Reason: ${chalk7.dim(impact.rule.reason)}`);
|
|
5294
5181
|
}
|
|
5295
5182
|
console.log("");
|
|
5296
5183
|
}
|
|
5297
5184
|
if (result.hasBlockers) {
|
|
5298
|
-
console.log(
|
|
5185
|
+
console.log(chalk7.red("\u274C BLOCKER-level impacts found. Review before proceeding."));
|
|
5299
5186
|
process.exit(1);
|
|
5300
5187
|
}
|
|
5301
5188
|
process.exit(0);
|
|
@@ -5337,7 +5224,7 @@ Examples:
|
|
|
5337
5224
|
(r) => r.source === source && r.dependents.includes(dependent)
|
|
5338
5225
|
);
|
|
5339
5226
|
if (existingRule) {
|
|
5340
|
-
console.log(
|
|
5227
|
+
console.log(chalk7.yellow(`Rule already exists: ${existingRule.id}`));
|
|
5341
5228
|
return;
|
|
5342
5229
|
}
|
|
5343
5230
|
const newRule = {
|
|
@@ -5351,20 +5238,20 @@ Examples:
|
|
|
5351
5238
|
const yaml2 = generateYamlFrontmatter(existingRules);
|
|
5352
5239
|
await writeFile4(DEPENDENCIES_FILENAME, `---
|
|
5353
5240
|
${yaml2}---${markdownBody}`, "utf-8");
|
|
5354
|
-
console.log(
|
|
5355
|
-
console.log(` Source: ${
|
|
5356
|
-
console.log(` Dependent: ${
|
|
5241
|
+
console.log(chalk7.green(`\u2705 Added dependency rule: ${nextId}`));
|
|
5242
|
+
console.log(` Source: ${chalk7.cyan(source)}`);
|
|
5243
|
+
console.log(` Dependent: ${chalk7.dim(dependent)}`);
|
|
5357
5244
|
});
|
|
5358
5245
|
deps.command("graph").description("Generate Mermaid diagram of dependencies").option("--output <file>", "Write to file instead of stdout").action(async (options) => {
|
|
5359
5246
|
const parser = new DependencyParser();
|
|
5360
5247
|
if (!parser.exists()) {
|
|
5361
|
-
console.log(
|
|
5248
|
+
console.log(chalk7.yellow("No DEPENDENCIES.md found."));
|
|
5362
5249
|
return;
|
|
5363
5250
|
}
|
|
5364
5251
|
const mermaid = await parser.generateGraph();
|
|
5365
5252
|
if (options.output) {
|
|
5366
5253
|
await writeFile4(options.output, mermaid, "utf-8");
|
|
5367
|
-
console.log(
|
|
5254
|
+
console.log(chalk7.green(`\u2705 Graph written to ${options.output}`));
|
|
5368
5255
|
} else {
|
|
5369
5256
|
console.log("\n```mermaid");
|
|
5370
5257
|
console.log(mermaid);
|
|
@@ -5373,7 +5260,7 @@ ${yaml2}---${markdownBody}`, "utf-8");
|
|
|
5373
5260
|
});
|
|
5374
5261
|
deps.command("init").description("Create a starter DEPENDENCIES.md file").action(async () => {
|
|
5375
5262
|
if (existsSync8(DEPENDENCIES_FILENAME)) {
|
|
5376
|
-
console.log(
|
|
5263
|
+
console.log(chalk7.yellow("DEPENDENCIES.md already exists."));
|
|
5377
5264
|
return;
|
|
5378
5265
|
}
|
|
5379
5266
|
const template = `---
|
|
@@ -5420,8 +5307,8 @@ rules:
|
|
|
5420
5307
|
*Powered by [ArchonDev](https://archondev.io)*
|
|
5421
5308
|
`;
|
|
5422
5309
|
await writeFile4(DEPENDENCIES_FILENAME, template, "utf-8");
|
|
5423
|
-
console.log(
|
|
5424
|
-
console.log(
|
|
5310
|
+
console.log(chalk7.green("\u2705 Created DEPENDENCIES.md"));
|
|
5311
|
+
console.log(chalk7.dim("Add your first rule with: archon deps add --source <path> --dependent <path>"));
|
|
5425
5312
|
});
|
|
5426
5313
|
return deps;
|
|
5427
5314
|
}
|
|
@@ -5458,7 +5345,7 @@ function generateYamlFrontmatter(rules) {
|
|
|
5458
5345
|
}
|
|
5459
5346
|
|
|
5460
5347
|
// src/cli/session.ts
|
|
5461
|
-
import
|
|
5348
|
+
import chalk8 from "chalk";
|
|
5462
5349
|
import ora2 from "ora";
|
|
5463
5350
|
import os from "os";
|
|
5464
5351
|
import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -5554,13 +5441,13 @@ async function saveSession(name) {
|
|
|
5554
5441
|
spinner.fail(`Failed to save session: ${error.message}`);
|
|
5555
5442
|
return;
|
|
5556
5443
|
}
|
|
5557
|
-
spinner.succeed(
|
|
5444
|
+
spinner.succeed(chalk8.green("Session saved!"));
|
|
5558
5445
|
console.log();
|
|
5559
|
-
console.log(` ID: ${
|
|
5446
|
+
console.log(` ID: ${chalk8.cyan(session.id)}`);
|
|
5560
5447
|
console.log(` Project: ${session.project_name}`);
|
|
5561
5448
|
console.log(` Device: ${session.last_device}`);
|
|
5562
5449
|
console.log();
|
|
5563
|
-
console.log(
|
|
5450
|
+
console.log(chalk8.dim(" Resume on another device: archon session resume " + session.id));
|
|
5564
5451
|
console.log();
|
|
5565
5452
|
} catch (err2) {
|
|
5566
5453
|
spinner.fail("Error saving session");
|
|
@@ -5588,23 +5475,23 @@ async function listSessions() {
|
|
|
5588
5475
|
}
|
|
5589
5476
|
spinner.stop();
|
|
5590
5477
|
if (!sessions || sessions.length === 0) {
|
|
5591
|
-
console.log(
|
|
5592
|
-
console.log(
|
|
5478
|
+
console.log(chalk8.yellow("\nNo saved sessions found.\n"));
|
|
5479
|
+
console.log(chalk8.dim(" Save a session: archon session save [name]\n"));
|
|
5593
5480
|
return;
|
|
5594
5481
|
}
|
|
5595
5482
|
console.log();
|
|
5596
|
-
console.log(
|
|
5483
|
+
console.log(chalk8.bold("\u{1F4C2} Saved Sessions"));
|
|
5597
5484
|
console.log();
|
|
5598
5485
|
for (const session of sessions) {
|
|
5599
5486
|
const date = new Date(session.updated_at).toLocaleDateString();
|
|
5600
|
-
const atomInfo = session.current_atom_id ?
|
|
5487
|
+
const atomInfo = session.current_atom_id ? chalk8.dim(` (atom: ${session.current_atom_id})`) : "";
|
|
5601
5488
|
console.log(
|
|
5602
|
-
` ${
|
|
5489
|
+
` ${chalk8.cyan(session.id.slice(0, 8))} ${session.project_name}${atomInfo}`
|
|
5603
5490
|
);
|
|
5604
|
-
console.log(
|
|
5491
|
+
console.log(chalk8.dim(` ${date} from ${session.last_device || "unknown device"}`));
|
|
5605
5492
|
console.log();
|
|
5606
5493
|
}
|
|
5607
|
-
console.log(
|
|
5494
|
+
console.log(chalk8.dim(" Resume: archon session resume <id>\n"));
|
|
5608
5495
|
} catch (err2) {
|
|
5609
5496
|
spinner.fail("Error fetching sessions");
|
|
5610
5497
|
console.error(err2);
|
|
@@ -5648,13 +5535,13 @@ async function resumeSession(sessionId) {
|
|
|
5648
5535
|
await writeFile5(archPath, session.architecture_snapshot);
|
|
5649
5536
|
}
|
|
5650
5537
|
await supabase.from("sessions").update({ last_device: getDeviceName(), updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", session.id);
|
|
5651
|
-
spinner.succeed(
|
|
5538
|
+
spinner.succeed(chalk8.green("Session resumed!"));
|
|
5652
5539
|
console.log();
|
|
5653
5540
|
console.log(` Project: ${session.project_name}`);
|
|
5654
5541
|
console.log(` Current Atom: ${session.current_atom_id || "none"}`);
|
|
5655
5542
|
console.log(` Pending: ${session.pending_atoms.length} atoms`);
|
|
5656
5543
|
console.log();
|
|
5657
|
-
console.log(
|
|
5544
|
+
console.log(chalk8.dim(" Continue working: archon start"));
|
|
5658
5545
|
console.log();
|
|
5659
5546
|
} catch (err2) {
|
|
5660
5547
|
spinner.fail("Error resuming session");
|
|
@@ -5697,7 +5584,7 @@ async function syncSession() {
|
|
|
5697
5584
|
spinner.fail(`Failed to sync: ${error.message}`);
|
|
5698
5585
|
return;
|
|
5699
5586
|
}
|
|
5700
|
-
spinner.succeed(
|
|
5587
|
+
spinner.succeed(chalk8.green("Session synced to cloud"));
|
|
5701
5588
|
} catch (err2) {
|
|
5702
5589
|
spinner.fail("Error syncing session");
|
|
5703
5590
|
console.error(err2);
|
|
@@ -5705,7 +5592,7 @@ async function syncSession() {
|
|
|
5705
5592
|
}
|
|
5706
5593
|
|
|
5707
5594
|
// src/cli/deploy.ts
|
|
5708
|
-
import
|
|
5595
|
+
import chalk9 from "chalk";
|
|
5709
5596
|
import { existsSync as existsSync10 } from "fs";
|
|
5710
5597
|
import { join as join9 } from "path";
|
|
5711
5598
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -5720,46 +5607,46 @@ function detectPlatform(cwd) {
|
|
|
5720
5607
|
}
|
|
5721
5608
|
async function deploy(options) {
|
|
5722
5609
|
const cwd = process.cwd();
|
|
5723
|
-
console.log(
|
|
5610
|
+
console.log(chalk9.blue("Running pre-deploy checks..."));
|
|
5724
5611
|
const platform = options.platform ?? detectPlatform(cwd);
|
|
5725
|
-
console.log(
|
|
5612
|
+
console.log(chalk9.dim(`Detected platform: ${platform}`));
|
|
5726
5613
|
if (options.dryRun) {
|
|
5727
|
-
console.log(
|
|
5614
|
+
console.log(chalk9.dim("Dry run mode - would deploy to:"), platform);
|
|
5728
5615
|
return;
|
|
5729
5616
|
}
|
|
5730
5617
|
switch (platform) {
|
|
5731
5618
|
case "fly":
|
|
5732
|
-
console.log(
|
|
5619
|
+
console.log(chalk9.blue("Deploying to Fly.io..."));
|
|
5733
5620
|
execSync3("fly deploy", { cwd, stdio: "inherit" });
|
|
5734
5621
|
break;
|
|
5735
5622
|
case "vercel": {
|
|
5736
|
-
console.log(
|
|
5623
|
+
console.log(chalk9.blue("Deploying to Vercel..."));
|
|
5737
5624
|
const cmd = options.preview ? "vercel" : "vercel --prod";
|
|
5738
5625
|
execSync3(cmd, { cwd, stdio: "inherit" });
|
|
5739
5626
|
break;
|
|
5740
5627
|
}
|
|
5741
5628
|
case "netlify": {
|
|
5742
|
-
console.log(
|
|
5629
|
+
console.log(chalk9.blue("Deploying to Netlify..."));
|
|
5743
5630
|
const netlifyCmd = options.preview ? "netlify deploy" : "netlify deploy --prod";
|
|
5744
5631
|
execSync3(netlifyCmd, { cwd, stdio: "inherit" });
|
|
5745
5632
|
break;
|
|
5746
5633
|
}
|
|
5747
5634
|
case "railway":
|
|
5748
|
-
console.log(
|
|
5635
|
+
console.log(chalk9.blue("Deploying to Railway..."));
|
|
5749
5636
|
execSync3("railway up", { cwd, stdio: "inherit" });
|
|
5750
5637
|
break;
|
|
5751
5638
|
case "render":
|
|
5752
|
-
console.log(
|
|
5753
|
-
console.log(
|
|
5639
|
+
console.log(chalk9.blue("Deploying to Render..."));
|
|
5640
|
+
console.log(chalk9.yellow("Render deploys via git push. Push to your connected branch."));
|
|
5754
5641
|
break;
|
|
5755
5642
|
default:
|
|
5756
|
-
console.log(
|
|
5757
|
-
console.log(
|
|
5643
|
+
console.log(chalk9.yellow("Platform not detected. Please specify with --platform"));
|
|
5644
|
+
console.log(chalk9.dim("Supported: fly, vercel, netlify, railway, render"));
|
|
5758
5645
|
}
|
|
5759
5646
|
}
|
|
5760
5647
|
|
|
5761
5648
|
// src/cli/index-cmd.ts
|
|
5762
|
-
import
|
|
5649
|
+
import chalk10 from "chalk";
|
|
5763
5650
|
|
|
5764
5651
|
// src/core/indexing/local.ts
|
|
5765
5652
|
import { existsSync as existsSync11, mkdirSync } from "fs";
|
|
@@ -6173,14 +6060,14 @@ async function getCloudIndexer(cwd) {
|
|
|
6173
6060
|
const config = await loadConfig();
|
|
6174
6061
|
const authToken = getAuthToken(config);
|
|
6175
6062
|
if (!authToken) {
|
|
6176
|
-
console.error(
|
|
6063
|
+
console.error(chalk10.red('Not authenticated. Run "archon login" first.'));
|
|
6177
6064
|
return null;
|
|
6178
6065
|
}
|
|
6179
6066
|
const openaiKey = process.env["OPENAI_API_KEY"];
|
|
6180
6067
|
if (!openaiKey) {
|
|
6181
|
-
console.error(
|
|
6182
|
-
console.log(
|
|
6183
|
-
console.log(
|
|
6068
|
+
console.error(chalk10.red("OPENAI_API_KEY environment variable not set."));
|
|
6069
|
+
console.log(chalk10.dim("Cloud indexing requires an OpenAI API key for embeddings."));
|
|
6070
|
+
console.log(chalk10.dim("Set it with: export OPENAI_API_KEY=sk-..."));
|
|
6184
6071
|
return null;
|
|
6185
6072
|
}
|
|
6186
6073
|
const projectId = basename(cwd);
|
|
@@ -6197,12 +6084,12 @@ async function getCloudIndexer(cwd) {
|
|
|
6197
6084
|
});
|
|
6198
6085
|
const { data: { user } } = await client.auth.getUser();
|
|
6199
6086
|
if (!user) {
|
|
6200
|
-
console.error(
|
|
6087
|
+
console.error(chalk10.red("Failed to get user. Try logging in again."));
|
|
6201
6088
|
return null;
|
|
6202
6089
|
}
|
|
6203
6090
|
const { data: profile } = await client.from("user_profiles").select("id").eq("auth_id", user.id).single();
|
|
6204
6091
|
if (!profile) {
|
|
6205
|
-
console.error(
|
|
6092
|
+
console.error(chalk10.red("User profile not found."));
|
|
6206
6093
|
return null;
|
|
6207
6094
|
}
|
|
6208
6095
|
indexer.setUserId(profile.id);
|
|
@@ -6211,21 +6098,21 @@ async function getCloudIndexer(cwd) {
|
|
|
6211
6098
|
async function indexInit(options) {
|
|
6212
6099
|
const cwd = process.cwd();
|
|
6213
6100
|
if (options.cloud) {
|
|
6214
|
-
console.log(
|
|
6101
|
+
console.log(chalk10.blue("Initializing cloud semantic index..."));
|
|
6215
6102
|
const indexer = await getCloudIndexer(cwd);
|
|
6216
6103
|
if (!indexer) return;
|
|
6217
6104
|
try {
|
|
6218
6105
|
const status2 = await indexer.getStatus();
|
|
6219
|
-
console.log(
|
|
6220
|
-
console.log(
|
|
6221
|
-
console.log(
|
|
6106
|
+
console.log(chalk10.green("\u2713 Cloud indexing configured"));
|
|
6107
|
+
console.log(chalk10.green(`\u2713 Project ID: ${status2.projectId}`));
|
|
6108
|
+
console.log(chalk10.dim("\nRun `archon index update --cloud` to index your codebase."));
|
|
6222
6109
|
} catch (error) {
|
|
6223
|
-
console.error(
|
|
6110
|
+
console.error(chalk10.red(`Failed to initialize cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6224
6111
|
process.exit(1);
|
|
6225
6112
|
}
|
|
6226
6113
|
return;
|
|
6227
6114
|
}
|
|
6228
|
-
console.log(
|
|
6115
|
+
console.log(chalk10.blue("Initializing local semantic index..."));
|
|
6229
6116
|
try {
|
|
6230
6117
|
const indexer = new LocalIndexer();
|
|
6231
6118
|
await indexer.init(cwd);
|
|
@@ -6233,18 +6120,18 @@ async function indexInit(options) {
|
|
|
6233
6120
|
if (!response.ok) {
|
|
6234
6121
|
throw new Error("Ollama not responding");
|
|
6235
6122
|
}
|
|
6236
|
-
console.log(
|
|
6237
|
-
console.log(
|
|
6238
|
-
console.log(
|
|
6123
|
+
console.log(chalk10.green("\u2713 Ollama connection verified"));
|
|
6124
|
+
console.log(chalk10.green("\u2713 Index database created at .archon/index.db"));
|
|
6125
|
+
console.log(chalk10.dim("\nRun `archon index update` to index your codebase."));
|
|
6239
6126
|
indexer.close();
|
|
6240
6127
|
} catch (error) {
|
|
6241
6128
|
if (error instanceof Error && error.message.includes("Ollama")) {
|
|
6242
|
-
console.log(
|
|
6243
|
-
console.log(
|
|
6244
|
-
console.log(
|
|
6245
|
-
console.log(
|
|
6129
|
+
console.log(chalk10.red("\n\u2717 Ollama is not running"));
|
|
6130
|
+
console.log(chalk10.dim("Start Ollama with: ollama serve"));
|
|
6131
|
+
console.log(chalk10.dim("Then pull the embedding model: ollama pull nomic-embed-text"));
|
|
6132
|
+
console.log(chalk10.dim("\nOr use cloud indexing: archon index init --cloud"));
|
|
6246
6133
|
} else {
|
|
6247
|
-
console.error(
|
|
6134
|
+
console.error(chalk10.red(`Failed to initialize index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6248
6135
|
}
|
|
6249
6136
|
process.exit(1);
|
|
6250
6137
|
}
|
|
@@ -6252,7 +6139,7 @@ async function indexInit(options) {
|
|
|
6252
6139
|
async function indexUpdate(options) {
|
|
6253
6140
|
const cwd = process.cwd();
|
|
6254
6141
|
if (options?.cloud) {
|
|
6255
|
-
console.log(
|
|
6142
|
+
console.log(chalk10.blue("Updating cloud semantic index..."));
|
|
6256
6143
|
const indexer = await getCloudIndexer(cwd);
|
|
6257
6144
|
if (!indexer) return;
|
|
6258
6145
|
try {
|
|
@@ -6260,15 +6147,15 @@ async function indexUpdate(options) {
|
|
|
6260
6147
|
cwd,
|
|
6261
6148
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6262
6149
|
});
|
|
6263
|
-
console.log(
|
|
6264
|
-
console.log(
|
|
6150
|
+
console.log(chalk10.dim(`Found ${files.length} files to index...`));
|
|
6151
|
+
console.log(chalk10.dim("This may take a few minutes and will use OpenAI API credits.\n"));
|
|
6265
6152
|
let totalChunks = 0;
|
|
6266
6153
|
let indexedFiles = 0;
|
|
6267
6154
|
let skippedFiles = 0;
|
|
6268
6155
|
for (let i = 0; i < files.length; i++) {
|
|
6269
6156
|
const file = files[i];
|
|
6270
6157
|
if (!file) continue;
|
|
6271
|
-
process.stdout.write(`\r${
|
|
6158
|
+
process.stdout.write(`\r${chalk10.dim(`[${i + 1}/${files.length}] ${file.slice(0, 45).padEnd(45)}`)}`);
|
|
6272
6159
|
try {
|
|
6273
6160
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6274
6161
|
if (chunks > 0) {
|
|
@@ -6279,21 +6166,21 @@ async function indexUpdate(options) {
|
|
|
6279
6166
|
}
|
|
6280
6167
|
} catch (error) {
|
|
6281
6168
|
console.log(`
|
|
6282
|
-
${
|
|
6169
|
+
${chalk10.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message : "Unknown error"}`)}`);
|
|
6283
6170
|
}
|
|
6284
6171
|
}
|
|
6285
6172
|
console.log("\r" + " ".repeat(70));
|
|
6286
|
-
console.log(
|
|
6173
|
+
console.log(chalk10.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6287
6174
|
if (skippedFiles > 0) {
|
|
6288
|
-
console.log(
|
|
6175
|
+
console.log(chalk10.dim(` Skipped ${skippedFiles} unchanged files`));
|
|
6289
6176
|
}
|
|
6290
6177
|
} catch (error) {
|
|
6291
|
-
console.error(
|
|
6178
|
+
console.error(chalk10.red(`Failed to update cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6292
6179
|
process.exit(1);
|
|
6293
6180
|
}
|
|
6294
6181
|
return;
|
|
6295
6182
|
}
|
|
6296
|
-
console.log(
|
|
6183
|
+
console.log(chalk10.blue("Updating local semantic index..."));
|
|
6297
6184
|
try {
|
|
6298
6185
|
const indexer = new LocalIndexer();
|
|
6299
6186
|
await indexer.init(cwd);
|
|
@@ -6301,12 +6188,12 @@ ${chalk11.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6301
6188
|
cwd,
|
|
6302
6189
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6303
6190
|
});
|
|
6304
|
-
console.log(
|
|
6191
|
+
console.log(chalk10.dim(`Found ${files.length} files to index...`));
|
|
6305
6192
|
let totalChunks = 0;
|
|
6306
6193
|
let indexedFiles = 0;
|
|
6307
6194
|
for (const file of files) {
|
|
6308
6195
|
if (!file) continue;
|
|
6309
|
-
process.stdout.write(`\r${
|
|
6196
|
+
process.stdout.write(`\r${chalk10.dim(`Indexing: ${file.slice(0, 50).padEnd(50)}`)}`);
|
|
6310
6197
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6311
6198
|
if (chunks > 0) {
|
|
6312
6199
|
totalChunks += chunks;
|
|
@@ -6314,10 +6201,10 @@ ${chalk11.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6314
6201
|
}
|
|
6315
6202
|
}
|
|
6316
6203
|
console.log("\r" + " ".repeat(60));
|
|
6317
|
-
console.log(
|
|
6204
|
+
console.log(chalk10.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6318
6205
|
indexer.close();
|
|
6319
6206
|
} catch (error) {
|
|
6320
|
-
console.error(
|
|
6207
|
+
console.error(chalk10.red(`Failed to update index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6321
6208
|
process.exit(1);
|
|
6322
6209
|
}
|
|
6323
6210
|
}
|
|
@@ -6327,25 +6214,25 @@ async function indexSearch(query, options) {
|
|
|
6327
6214
|
const indexer = await getCloudIndexer(cwd);
|
|
6328
6215
|
if (!indexer) return;
|
|
6329
6216
|
try {
|
|
6330
|
-
console.log(
|
|
6217
|
+
console.log(chalk10.dim("Searching cloud index..."));
|
|
6331
6218
|
const results = await indexer.search(query, 10);
|
|
6332
6219
|
if (results.length === 0) {
|
|
6333
|
-
console.log(
|
|
6334
|
-
console.log(
|
|
6220
|
+
console.log(chalk10.yellow("\nNo results found."));
|
|
6221
|
+
console.log(chalk10.dim("Try running `archon index update --cloud` first."));
|
|
6335
6222
|
} else {
|
|
6336
|
-
console.log(
|
|
6223
|
+
console.log(chalk10.blue(`
|
|
6337
6224
|
Top ${results.length} results for: "${query}"
|
|
6338
6225
|
`));
|
|
6339
6226
|
for (const result of results) {
|
|
6340
6227
|
const score = (result.score * 100).toFixed(1);
|
|
6341
|
-
console.log(
|
|
6228
|
+
console.log(chalk10.green(`[${score}%] ${result.file}`));
|
|
6342
6229
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6343
|
-
console.log(
|
|
6230
|
+
console.log(chalk10.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6344
6231
|
console.log();
|
|
6345
6232
|
}
|
|
6346
6233
|
}
|
|
6347
6234
|
} catch (error) {
|
|
6348
|
-
console.error(
|
|
6235
|
+
console.error(chalk10.red(`Cloud search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6349
6236
|
process.exit(1);
|
|
6350
6237
|
}
|
|
6351
6238
|
return;
|
|
@@ -6355,23 +6242,23 @@ Top ${results.length} results for: "${query}"
|
|
|
6355
6242
|
await indexer.init(cwd);
|
|
6356
6243
|
const results = await indexer.search(query, 10);
|
|
6357
6244
|
if (results.length === 0) {
|
|
6358
|
-
console.log(
|
|
6359
|
-
console.log(
|
|
6245
|
+
console.log(chalk10.yellow("No results found."));
|
|
6246
|
+
console.log(chalk10.dim("Try running `archon index update` first."));
|
|
6360
6247
|
} else {
|
|
6361
|
-
console.log(
|
|
6248
|
+
console.log(chalk10.blue(`
|
|
6362
6249
|
Top ${results.length} results for: "${query}"
|
|
6363
6250
|
`));
|
|
6364
6251
|
for (const result of results) {
|
|
6365
6252
|
const score = (result.score * 100).toFixed(1);
|
|
6366
|
-
console.log(
|
|
6253
|
+
console.log(chalk10.green(`[${score}%] ${result.file}`));
|
|
6367
6254
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6368
|
-
console.log(
|
|
6255
|
+
console.log(chalk10.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6369
6256
|
console.log();
|
|
6370
6257
|
}
|
|
6371
6258
|
}
|
|
6372
6259
|
indexer.close();
|
|
6373
6260
|
} catch (error) {
|
|
6374
|
-
console.error(
|
|
6261
|
+
console.error(chalk10.red(`Search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6375
6262
|
process.exit(1);
|
|
6376
6263
|
}
|
|
6377
6264
|
}
|
|
@@ -6382,17 +6269,17 @@ async function indexStatus(options) {
|
|
|
6382
6269
|
if (!indexer) return;
|
|
6383
6270
|
try {
|
|
6384
6271
|
const status2 = await indexer.getStatus();
|
|
6385
|
-
console.log(
|
|
6386
|
-
console.log(` Project ID: ${
|
|
6387
|
-
console.log(` Files indexed: ${
|
|
6388
|
-
console.log(` Total chunks: ${
|
|
6389
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6272
|
+
console.log(chalk10.blue("\nCloud Semantic Index Status\n"));
|
|
6273
|
+
console.log(` Project ID: ${chalk10.green(status2.projectId)}`);
|
|
6274
|
+
console.log(` Files indexed: ${chalk10.green(status2.fileCount)}`);
|
|
6275
|
+
console.log(` Total chunks: ${chalk10.green(status2.chunkCount)}`);
|
|
6276
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk10.dim(status2.lastUpdated) : chalk10.yellow("Never")}`);
|
|
6390
6277
|
if (status2.jobStatus) {
|
|
6391
|
-
console.log(` Job status: ${
|
|
6278
|
+
console.log(` Job status: ${chalk10.dim(status2.jobStatus)}`);
|
|
6392
6279
|
}
|
|
6393
|
-
console.log(` Storage: ${
|
|
6280
|
+
console.log(` Storage: ${chalk10.dim("Supabase pgvector")}`);
|
|
6394
6281
|
} catch (error) {
|
|
6395
|
-
console.error(
|
|
6282
|
+
console.error(chalk10.red(`Failed to get cloud status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6396
6283
|
process.exit(1);
|
|
6397
6284
|
}
|
|
6398
6285
|
return;
|
|
@@ -6401,14 +6288,14 @@ async function indexStatus(options) {
|
|
|
6401
6288
|
const indexer = new LocalIndexer();
|
|
6402
6289
|
await indexer.init(cwd);
|
|
6403
6290
|
const status2 = await indexer.getStatus();
|
|
6404
|
-
console.log(
|
|
6405
|
-
console.log(` Files indexed: ${
|
|
6406
|
-
console.log(` Total chunks: ${
|
|
6407
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6408
|
-
console.log(` Database: ${
|
|
6291
|
+
console.log(chalk10.blue("\nLocal Semantic Index Status\n"));
|
|
6292
|
+
console.log(` Files indexed: ${chalk10.green(status2.fileCount)}`);
|
|
6293
|
+
console.log(` Total chunks: ${chalk10.green(status2.chunkCount)}`);
|
|
6294
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk10.dim(status2.lastUpdated) : chalk10.yellow("Never")}`);
|
|
6295
|
+
console.log(` Database: ${chalk10.dim(join12(cwd, ".archon/index.db"))}`);
|
|
6409
6296
|
indexer.close();
|
|
6410
6297
|
} catch (error) {
|
|
6411
|
-
console.error(
|
|
6298
|
+
console.error(chalk10.red(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6412
6299
|
process.exit(1);
|
|
6413
6300
|
}
|
|
6414
6301
|
}
|
|
@@ -6418,30 +6305,30 @@ async function indexClear(options) {
|
|
|
6418
6305
|
const indexer = await getCloudIndexer(cwd);
|
|
6419
6306
|
if (!indexer) return;
|
|
6420
6307
|
try {
|
|
6421
|
-
console.log(
|
|
6308
|
+
console.log(chalk10.yellow("Clearing cloud index..."));
|
|
6422
6309
|
await indexer.clearProject();
|
|
6423
|
-
console.log(
|
|
6310
|
+
console.log(chalk10.green("\u2713 Cloud index cleared"));
|
|
6424
6311
|
} catch (error) {
|
|
6425
|
-
console.error(
|
|
6312
|
+
console.error(chalk10.red(`Failed to clear cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6426
6313
|
process.exit(1);
|
|
6427
6314
|
}
|
|
6428
6315
|
return;
|
|
6429
6316
|
}
|
|
6430
|
-
console.log(
|
|
6317
|
+
console.log(chalk10.yellow("To clear local index, delete .archon/index.db"));
|
|
6431
6318
|
}
|
|
6432
6319
|
|
|
6433
6320
|
// src/cli/github.ts
|
|
6434
|
-
import
|
|
6321
|
+
import chalk11 from "chalk";
|
|
6435
6322
|
import open2 from "open";
|
|
6436
6323
|
var API_URL2 = process.env["ARCHONDEV_API_URL"] ?? "https://archondev-api.fly.dev";
|
|
6437
6324
|
async function githubConnect() {
|
|
6438
6325
|
const config = await loadConfig();
|
|
6439
6326
|
const authToken = getAuthToken(config);
|
|
6440
6327
|
if (!authToken) {
|
|
6441
|
-
console.error(
|
|
6328
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6442
6329
|
process.exit(1);
|
|
6443
6330
|
}
|
|
6444
|
-
console.log(
|
|
6331
|
+
console.log(chalk11.dim("Starting GitHub connection..."));
|
|
6445
6332
|
try {
|
|
6446
6333
|
const response = await fetch(`${API_URL2}/api/github/connect`, {
|
|
6447
6334
|
headers: {
|
|
@@ -6450,18 +6337,18 @@ async function githubConnect() {
|
|
|
6450
6337
|
});
|
|
6451
6338
|
if (!response.ok) {
|
|
6452
6339
|
const error = await response.json();
|
|
6453
|
-
console.error(
|
|
6340
|
+
console.error(chalk11.red(error.error ?? "Failed to start GitHub connection"));
|
|
6454
6341
|
process.exit(1);
|
|
6455
6342
|
}
|
|
6456
6343
|
const data = await response.json();
|
|
6457
|
-
console.log(
|
|
6458
|
-
console.log(
|
|
6459
|
-
console.log(
|
|
6344
|
+
console.log(chalk11.dim("\nOpening browser for GitHub authorization..."));
|
|
6345
|
+
console.log(chalk11.dim("If browser does not open, visit:"));
|
|
6346
|
+
console.log(chalk11.blue(data.url));
|
|
6460
6347
|
await open2(data.url);
|
|
6461
|
-
console.log(
|
|
6462
|
-
console.log(
|
|
6348
|
+
console.log(chalk11.dim("\nComplete the authorization in your browser."));
|
|
6349
|
+
console.log(chalk11.dim('Then run "archon github status" to verify connection.'));
|
|
6463
6350
|
} catch (error) {
|
|
6464
|
-
console.error(
|
|
6351
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to connect"));
|
|
6465
6352
|
process.exit(1);
|
|
6466
6353
|
}
|
|
6467
6354
|
}
|
|
@@ -6469,7 +6356,7 @@ async function githubStatus() {
|
|
|
6469
6356
|
const config = await loadConfig();
|
|
6470
6357
|
const authToken = getAuthToken(config);
|
|
6471
6358
|
if (!authToken) {
|
|
6472
|
-
console.error(
|
|
6359
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6473
6360
|
process.exit(1);
|
|
6474
6361
|
}
|
|
6475
6362
|
try {
|
|
@@ -6480,20 +6367,20 @@ async function githubStatus() {
|
|
|
6480
6367
|
});
|
|
6481
6368
|
if (!response.ok) {
|
|
6482
6369
|
const error = await response.json();
|
|
6483
|
-
console.error(
|
|
6370
|
+
console.error(chalk11.red(error.error ?? "Failed to get GitHub status"));
|
|
6484
6371
|
process.exit(1);
|
|
6485
6372
|
}
|
|
6486
6373
|
const data = await response.json();
|
|
6487
6374
|
if (data.connected) {
|
|
6488
|
-
console.log(
|
|
6489
|
-
console.log(
|
|
6490
|
-
console.log(
|
|
6375
|
+
console.log(chalk11.green("\u2713 GitHub connected"));
|
|
6376
|
+
console.log(chalk11.dim(` Username: ${data.username}`));
|
|
6377
|
+
console.log(chalk11.dim(` Connected: ${data.connectedAt ? new Date(data.connectedAt).toLocaleDateString() : "Unknown"}`));
|
|
6491
6378
|
} else {
|
|
6492
|
-
console.log(
|
|
6493
|
-
console.log(
|
|
6379
|
+
console.log(chalk11.yellow("GitHub not connected"));
|
|
6380
|
+
console.log(chalk11.dim('Run "archon github connect" to connect your GitHub account.'));
|
|
6494
6381
|
}
|
|
6495
6382
|
} catch (error) {
|
|
6496
|
-
console.error(
|
|
6383
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to get status"));
|
|
6497
6384
|
process.exit(1);
|
|
6498
6385
|
}
|
|
6499
6386
|
}
|
|
@@ -6501,7 +6388,7 @@ async function githubDisconnect() {
|
|
|
6501
6388
|
const config = await loadConfig();
|
|
6502
6389
|
const authToken = getAuthToken(config);
|
|
6503
6390
|
if (!authToken) {
|
|
6504
|
-
console.error(
|
|
6391
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6505
6392
|
process.exit(1);
|
|
6506
6393
|
}
|
|
6507
6394
|
try {
|
|
@@ -6513,18 +6400,18 @@ async function githubDisconnect() {
|
|
|
6513
6400
|
});
|
|
6514
6401
|
if (!response.ok) {
|
|
6515
6402
|
const error = await response.json();
|
|
6516
|
-
console.error(
|
|
6403
|
+
console.error(chalk11.red(error.error ?? "Failed to disconnect GitHub"));
|
|
6517
6404
|
process.exit(1);
|
|
6518
6405
|
}
|
|
6519
|
-
console.log(
|
|
6406
|
+
console.log(chalk11.green("\u2713 GitHub disconnected"));
|
|
6520
6407
|
} catch (error) {
|
|
6521
|
-
console.error(
|
|
6408
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to disconnect"));
|
|
6522
6409
|
process.exit(1);
|
|
6523
6410
|
}
|
|
6524
6411
|
}
|
|
6525
6412
|
|
|
6526
6413
|
// src/cli/interview.ts
|
|
6527
|
-
import
|
|
6414
|
+
import chalk12 from "chalk";
|
|
6528
6415
|
import readline3 from "readline";
|
|
6529
6416
|
import ora3 from "ora";
|
|
6530
6417
|
import { existsSync as existsSync13, readFileSync as readFileSync5, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
@@ -6542,23 +6429,23 @@ async function interview(options = {}) {
|
|
|
6542
6429
|
if (!existsSync13(archonDir)) {
|
|
6543
6430
|
mkdirSync2(archonDir, { recursive: true });
|
|
6544
6431
|
}
|
|
6545
|
-
console.log(
|
|
6546
|
-
console.log(
|
|
6432
|
+
console.log(chalk12.bold("\n\u{1F3AF} ArchonDev Project Interview"));
|
|
6433
|
+
console.log(chalk12.dim("Let's define what you're building.\n"));
|
|
6547
6434
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6548
6435
|
const draftPath = getDraftPath(cwd);
|
|
6549
6436
|
if (existsSync13(constitutionPath)) {
|
|
6550
6437
|
const existing = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
6551
6438
|
if (existing.state === "FROZEN") {
|
|
6552
|
-
console.log(
|
|
6553
|
-
console.log(
|
|
6554
|
-
console.log(
|
|
6439
|
+
console.log(chalk12.yellow("[!] A frozen Constitution already exists."));
|
|
6440
|
+
console.log(chalk12.dim(` Project: ${existing.branding.projectName}`));
|
|
6441
|
+
console.log(chalk12.dim(` Frozen: ${existing.frozenAt?.toISOString()}`));
|
|
6555
6442
|
console.log();
|
|
6556
6443
|
const action = await prompt2("Start a new interview (overwrite) or view existing? (new/view)");
|
|
6557
6444
|
if (action.toLowerCase() === "view") {
|
|
6558
6445
|
console.log("\n" + summarizeConstitution(existing));
|
|
6559
6446
|
return;
|
|
6560
6447
|
} else if (action.toLowerCase() !== "new") {
|
|
6561
|
-
console.log(
|
|
6448
|
+
console.log(chalk12.dim("Cancelled."));
|
|
6562
6449
|
return;
|
|
6563
6450
|
}
|
|
6564
6451
|
}
|
|
@@ -6567,8 +6454,8 @@ async function interview(options = {}) {
|
|
|
6567
6454
|
let startPhase = 1;
|
|
6568
6455
|
if (existsSync13(draftPath) && options.resume !== false) {
|
|
6569
6456
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
6570
|
-
console.log(
|
|
6571
|
-
console.log(
|
|
6457
|
+
console.log(chalk12.blue("[i] Found draft from previous session."));
|
|
6458
|
+
console.log(chalk12.dim(` Project: ${draft.branding.projectName || "(unnamed)"}`));
|
|
6572
6459
|
console.log();
|
|
6573
6460
|
const resumeChoice = await prompt2("Resume draft or start fresh? (resume/fresh)");
|
|
6574
6461
|
if (resumeChoice.toLowerCase() === "resume") {
|
|
@@ -6580,7 +6467,7 @@ async function interview(options = {}) {
|
|
|
6580
6467
|
break;
|
|
6581
6468
|
}
|
|
6582
6469
|
}
|
|
6583
|
-
console.log(
|
|
6470
|
+
console.log(chalk12.green(`
|
|
6584
6471
|
\u2713 Resuming at Phase ${startPhase}: ${INTERVIEW_PHASES[startPhase]?.name}
|
|
6585
6472
|
`));
|
|
6586
6473
|
} else {
|
|
@@ -6591,19 +6478,19 @@ async function interview(options = {}) {
|
|
|
6591
6478
|
}
|
|
6592
6479
|
if (options.phase && options.phase >= 1 && options.phase <= 5) {
|
|
6593
6480
|
startPhase = options.phase;
|
|
6594
|
-
console.log(
|
|
6481
|
+
console.log(chalk12.dim(`Starting at Phase ${startPhase}...
|
|
6595
6482
|
`));
|
|
6596
6483
|
}
|
|
6597
|
-
console.log(
|
|
6598
|
-
console.log(
|
|
6599
|
-
console.log(
|
|
6484
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6485
|
+
console.log(chalk12.dim(formatProgressBar(startPhase)));
|
|
6486
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6600
6487
|
console.log();
|
|
6601
6488
|
let currentPhase = startPhase;
|
|
6602
6489
|
while (currentPhase <= 5) {
|
|
6603
6490
|
const result = await runPhase(currentPhase, constitution, cwd);
|
|
6604
6491
|
if (result.action === "exit") {
|
|
6605
6492
|
saveDraft(cwd, constitution);
|
|
6606
|
-
console.log(
|
|
6493
|
+
console.log(chalk12.dim("\nDraft saved. Run `archon interview` to resume.\n"));
|
|
6607
6494
|
return;
|
|
6608
6495
|
}
|
|
6609
6496
|
if (result.action === "back" && currentPhase > 1) {
|
|
@@ -6618,9 +6505,9 @@ async function interview(options = {}) {
|
|
|
6618
6505
|
if (next) {
|
|
6619
6506
|
currentPhase = next;
|
|
6620
6507
|
console.log();
|
|
6621
|
-
console.log(
|
|
6622
|
-
console.log(
|
|
6623
|
-
console.log(
|
|
6508
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6509
|
+
console.log(chalk12.dim(formatProgressBar(currentPhase)));
|
|
6510
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6624
6511
|
console.log();
|
|
6625
6512
|
} else {
|
|
6626
6513
|
break;
|
|
@@ -6628,9 +6515,9 @@ async function interview(options = {}) {
|
|
|
6628
6515
|
}
|
|
6629
6516
|
const validationResult = validateConstitution(constitution);
|
|
6630
6517
|
if (!validationResult.valid) {
|
|
6631
|
-
console.log(
|
|
6518
|
+
console.log(chalk12.red("\n[!] Constitution has validation errors:\n"));
|
|
6632
6519
|
for (const error of validationResult.errors) {
|
|
6633
|
-
console.log(
|
|
6520
|
+
console.log(chalk12.red(` \u2022 ${error}`));
|
|
6634
6521
|
}
|
|
6635
6522
|
console.log();
|
|
6636
6523
|
const fix = await promptYesNo3("Would you like to go back and fix these?", true);
|
|
@@ -6640,9 +6527,9 @@ async function interview(options = {}) {
|
|
|
6640
6527
|
}
|
|
6641
6528
|
}
|
|
6642
6529
|
if (validationResult.warnings.length > 0) {
|
|
6643
|
-
console.log(
|
|
6530
|
+
console.log(chalk12.yellow("\n[!] Warnings:\n"));
|
|
6644
6531
|
for (const warning of validationResult.warnings) {
|
|
6645
|
-
console.log(
|
|
6532
|
+
console.log(chalk12.yellow(` \u2022 ${warning}`));
|
|
6646
6533
|
}
|
|
6647
6534
|
console.log();
|
|
6648
6535
|
}
|
|
@@ -6652,21 +6539,21 @@ async function interview(options = {}) {
|
|
|
6652
6539
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
6653
6540
|
const challengeResult = analyzeForChallenges(constitution);
|
|
6654
6541
|
if (challengeResult.shouldChallenge) {
|
|
6655
|
-
console.log(
|
|
6656
|
-
console.log(
|
|
6542
|
+
console.log(chalk12.bold("\n\u{1F3AF} Challenge Mode\n"));
|
|
6543
|
+
console.log(chalk12.dim("Let me share some observations about your project scope...\n"));
|
|
6657
6544
|
for (const challenge of challengeResult.challenges) {
|
|
6658
6545
|
const prompt3 = generateChallengePrompt(challenge);
|
|
6659
|
-
const icon = challenge.severity === "critical" ?
|
|
6660
|
-
console.log(`${icon} ${
|
|
6661
|
-
console.log(
|
|
6546
|
+
const icon = challenge.severity === "critical" ? chalk12.red("\u25CF") : chalk12.yellow("\u25CF");
|
|
6547
|
+
console.log(`${icon} ${chalk12.bold(challenge.title)}`);
|
|
6548
|
+
console.log(chalk12.dim(` ${prompt3}`));
|
|
6662
6549
|
console.log();
|
|
6663
6550
|
}
|
|
6664
|
-
console.log(
|
|
6551
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6665
6552
|
console.log(summarizeChallenges(challengeResult));
|
|
6666
|
-
console.log(
|
|
6553
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6667
6554
|
console.log();
|
|
6668
6555
|
if (challengeResult.featuresToDefer.length > 0) {
|
|
6669
|
-
console.log(
|
|
6556
|
+
console.log(chalk12.bold("Suggested Features to Defer to Post-MVP:\n"));
|
|
6670
6557
|
for (const feature of challengeResult.featuresToDefer) {
|
|
6671
6558
|
console.log(` \u2022 ${feature.name}`);
|
|
6672
6559
|
}
|
|
@@ -6681,39 +6568,39 @@ async function interview(options = {}) {
|
|
|
6681
6568
|
constitution.complexity = calculateComplexity(constitution);
|
|
6682
6569
|
constitution.estimatedBuildHours = estimateBuildHours(constitution.complexity);
|
|
6683
6570
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
6684
|
-
console.log(
|
|
6685
|
-
console.log(
|
|
6686
|
-
console.log(
|
|
6571
|
+
console.log(chalk12.green("\n\u2713 Features deferred. Updated estimates:"));
|
|
6572
|
+
console.log(chalk12.dim(` Complexity: ${constitution.complexity.tier}`));
|
|
6573
|
+
console.log(chalk12.dim(` Build time: ~${Math.round(constitution.estimatedBuildHours)} hours`));
|
|
6687
6574
|
console.log();
|
|
6688
6575
|
saveDraft(cwd, constitution);
|
|
6689
6576
|
}
|
|
6690
6577
|
}
|
|
6691
6578
|
const criticalCount = challengeResult.challenges.filter((c) => c.severity === "critical").length;
|
|
6692
6579
|
if (criticalCount > 0) {
|
|
6693
|
-
console.log(
|
|
6580
|
+
console.log(chalk12.red(`
|
|
6694
6581
|
\u26A0\uFE0F ${criticalCount} critical issue(s) detected.`));
|
|
6695
6582
|
const proceed = await promptYesNo3("Proceed anyway?", false);
|
|
6696
6583
|
if (!proceed) {
|
|
6697
6584
|
saveDraft(cwd, constitution);
|
|
6698
|
-
console.log(
|
|
6585
|
+
console.log(chalk12.dim("\nDraft saved. Address the issues and run `archon interview` again.\n"));
|
|
6699
6586
|
return;
|
|
6700
6587
|
}
|
|
6701
6588
|
}
|
|
6702
6589
|
} else {
|
|
6703
|
-
console.log(
|
|
6590
|
+
console.log(chalk12.green("\n\u2713 Scope looks reasonable! No major concerns detected.\n"));
|
|
6704
6591
|
}
|
|
6705
|
-
console.log(
|
|
6592
|
+
console.log(chalk12.bold("\n\u{1F4CB} Constitution Summary\n"));
|
|
6706
6593
|
console.log(summarizeConstitution(constitution));
|
|
6707
6594
|
console.log();
|
|
6708
6595
|
if (options.dryRun) {
|
|
6709
|
-
console.log(
|
|
6596
|
+
console.log(chalk12.dim("(Dry run mode - not freezing Constitution)"));
|
|
6710
6597
|
saveDraft(cwd, constitution);
|
|
6711
6598
|
return;
|
|
6712
6599
|
}
|
|
6713
6600
|
const confirmFreeze = await promptYesNo3("Freeze this Constitution and start building?", true);
|
|
6714
6601
|
if (!confirmFreeze) {
|
|
6715
6602
|
saveDraft(cwd, constitution);
|
|
6716
|
-
console.log(
|
|
6603
|
+
console.log(chalk12.dim("\nDraft saved. Run `archon interview` to continue.\n"));
|
|
6717
6604
|
return;
|
|
6718
6605
|
}
|
|
6719
6606
|
const spinner = ora3("Freezing Constitution...").start();
|
|
@@ -6724,15 +6611,15 @@ async function interview(options = {}) {
|
|
|
6724
6611
|
const { unlinkSync } = await import("fs");
|
|
6725
6612
|
unlinkSync(draftPath);
|
|
6726
6613
|
}
|
|
6727
|
-
spinner.succeed(
|
|
6614
|
+
spinner.succeed(chalk12.green("Constitution frozen!"));
|
|
6728
6615
|
console.log();
|
|
6729
|
-
console.log(
|
|
6730
|
-
console.log(
|
|
6616
|
+
console.log(chalk12.dim(`Hash: ${frozen.hash?.substring(0, 32)}...`));
|
|
6617
|
+
console.log(chalk12.dim(`Saved: ${constitutionPath}`));
|
|
6731
6618
|
console.log();
|
|
6732
|
-
console.log(
|
|
6733
|
-
console.log(` ${
|
|
6734
|
-
console.log(` ${
|
|
6735
|
-
console.log(` ${
|
|
6619
|
+
console.log(chalk12.bold("Next Steps:\n"));
|
|
6620
|
+
console.log(` ${chalk12.cyan("1.")} Run ${chalk12.bold("archon generate")} to create atoms from this Constitution`);
|
|
6621
|
+
console.log(` ${chalk12.cyan("2.")} Run ${chalk12.bold("archon list")} to see generated atoms`);
|
|
6622
|
+
console.log(` ${chalk12.cyan("3.")} Run ${chalk12.bold("archon execute <atom-id>")} to start building`);
|
|
6736
6623
|
console.log();
|
|
6737
6624
|
} catch (err2) {
|
|
6738
6625
|
spinner.fail("Failed to freeze Constitution");
|
|
@@ -6741,18 +6628,18 @@ async function interview(options = {}) {
|
|
|
6741
6628
|
}
|
|
6742
6629
|
async function runPhase(phase, constitution, cwd) {
|
|
6743
6630
|
const phaseInfo = INTERVIEW_PHASES[phase];
|
|
6744
|
-
console.log(
|
|
6745
|
-
console.log(
|
|
6631
|
+
console.log(chalk12.bold(`Phase ${phase}: ${phaseInfo.name}`));
|
|
6632
|
+
console.log(chalk12.dim(phaseInfo.description));
|
|
6746
6633
|
console.log();
|
|
6747
6634
|
const skippable = getSkippableQuestions(phase, constitution);
|
|
6748
6635
|
let updatedConstitution = { ...constitution };
|
|
6749
6636
|
for (const question of phaseInfo.questions) {
|
|
6750
6637
|
if (skippable.includes(question.id)) {
|
|
6751
|
-
console.log(
|
|
6638
|
+
console.log(chalk12.dim(`[\u2713] ${question.prompt.split("?")[0]}... (already answered)`));
|
|
6752
6639
|
continue;
|
|
6753
6640
|
}
|
|
6754
6641
|
if (phase === 5 && question.id === "review_summary") {
|
|
6755
|
-
console.log(
|
|
6642
|
+
console.log(chalk12.bold("\n\u{1F4CB} Current State:\n"));
|
|
6756
6643
|
console.log(summarizeConstitution(updatedConstitution));
|
|
6757
6644
|
console.log();
|
|
6758
6645
|
}
|
|
@@ -6769,14 +6656,14 @@ async function runPhase(phase, constitution, cwd) {
|
|
|
6769
6656
|
if (question.validator) {
|
|
6770
6657
|
const validation = question.validator(answer);
|
|
6771
6658
|
if (!validation.valid) {
|
|
6772
|
-
console.log(
|
|
6659
|
+
console.log(chalk12.red(` ${validation.error}`));
|
|
6773
6660
|
continue;
|
|
6774
6661
|
}
|
|
6775
6662
|
}
|
|
6776
6663
|
const extracted = question.extractor(answer, updatedConstitution);
|
|
6777
6664
|
updatedConstitution = { ...updatedConstitution, ...extracted };
|
|
6778
6665
|
if (question.followUp && answer.length > 10) {
|
|
6779
|
-
console.log(
|
|
6666
|
+
console.log(chalk12.dim(` ${question.followUp}`));
|
|
6780
6667
|
}
|
|
6781
6668
|
}
|
|
6782
6669
|
return { action: "next", constitution: updatedConstitution };
|
|
@@ -6786,7 +6673,7 @@ function saveDraft(cwd, constitution) {
|
|
|
6786
6673
|
writeFileSync(draftPath, serializeConstitution(constitution));
|
|
6787
6674
|
}
|
|
6788
6675
|
async function promptQuestion(question) {
|
|
6789
|
-
const prefix = question.required ?
|
|
6676
|
+
const prefix = question.required ? chalk12.red("*") : " ";
|
|
6790
6677
|
return prompt2(`${prefix} ${question.prompt}`);
|
|
6791
6678
|
}
|
|
6792
6679
|
function prompt2(question) {
|
|
@@ -6795,7 +6682,7 @@ function prompt2(question) {
|
|
|
6795
6682
|
input: process.stdin,
|
|
6796
6683
|
output: process.stdout
|
|
6797
6684
|
});
|
|
6798
|
-
rl.question(`${
|
|
6685
|
+
rl.question(`${chalk12.cyan("?")} ${question}
|
|
6799
6686
|
> `, (answer) => {
|
|
6800
6687
|
rl.close();
|
|
6801
6688
|
resolve(answer.trim());
|
|
@@ -6809,7 +6696,7 @@ function promptYesNo3(question, defaultValue) {
|
|
|
6809
6696
|
output: process.stdout
|
|
6810
6697
|
});
|
|
6811
6698
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
6812
|
-
rl.question(`${
|
|
6699
|
+
rl.question(`${chalk12.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
6813
6700
|
rl.close();
|
|
6814
6701
|
if (answer.trim() === "") {
|
|
6815
6702
|
resolve(defaultValue);
|
|
@@ -6828,10 +6715,10 @@ async function showConstitution() {
|
|
|
6828
6715
|
console.log(summarizeConstitution(constitution));
|
|
6829
6716
|
} else if (existsSync13(draftPath)) {
|
|
6830
6717
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
6831
|
-
console.log(
|
|
6718
|
+
console.log(chalk12.yellow("[DRAFT]"));
|
|
6832
6719
|
console.log(summarizeConstitution(draft));
|
|
6833
6720
|
} else {
|
|
6834
|
-
console.log(
|
|
6721
|
+
console.log(chalk12.dim("No Constitution found. Run `archon interview` to create one."));
|
|
6835
6722
|
}
|
|
6836
6723
|
}
|
|
6837
6724
|
async function validateConstitutionCommand() {
|
|
@@ -6840,23 +6727,23 @@ async function validateConstitutionCommand() {
|
|
|
6840
6727
|
const draftPath = getDraftPath(cwd);
|
|
6841
6728
|
const path2 = existsSync13(constitutionPath) ? constitutionPath : draftPath;
|
|
6842
6729
|
if (!existsSync13(path2)) {
|
|
6843
|
-
console.log(
|
|
6730
|
+
console.log(chalk12.dim("No Constitution found. Run `archon interview` to create one."));
|
|
6844
6731
|
return;
|
|
6845
6732
|
}
|
|
6846
6733
|
const constitution = deserializeConstitution(readFileSync5(path2, "utf-8"));
|
|
6847
6734
|
const result = validateConstitution(constitution);
|
|
6848
6735
|
if (result.valid) {
|
|
6849
|
-
console.log(
|
|
6736
|
+
console.log(chalk12.green("\u2713 Constitution is valid"));
|
|
6850
6737
|
} else {
|
|
6851
|
-
console.log(
|
|
6738
|
+
console.log(chalk12.red("\u2717 Constitution has errors:"));
|
|
6852
6739
|
for (const error of result.errors) {
|
|
6853
|
-
console.log(
|
|
6740
|
+
console.log(chalk12.red(` \u2022 ${error}`));
|
|
6854
6741
|
}
|
|
6855
6742
|
}
|
|
6856
6743
|
if (result.warnings.length > 0) {
|
|
6857
|
-
console.log(
|
|
6744
|
+
console.log(chalk12.yellow("\nWarnings:"));
|
|
6858
6745
|
for (const warning of result.warnings) {
|
|
6859
|
-
console.log(
|
|
6746
|
+
console.log(chalk12.yellow(` \u2022 ${warning}`));
|
|
6860
6747
|
}
|
|
6861
6748
|
}
|
|
6862
6749
|
}
|
|
@@ -6864,7 +6751,7 @@ async function exportConstitution(format) {
|
|
|
6864
6751
|
const cwd = process.cwd();
|
|
6865
6752
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6866
6753
|
if (!existsSync13(constitutionPath)) {
|
|
6867
|
-
console.log(
|
|
6754
|
+
console.log(chalk12.dim("No frozen Constitution found."));
|
|
6868
6755
|
return;
|
|
6869
6756
|
}
|
|
6870
6757
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
@@ -6877,26 +6764,26 @@ async function exportConstitution(format) {
|
|
|
6877
6764
|
console.log(summarizeConstitution(constitution));
|
|
6878
6765
|
break;
|
|
6879
6766
|
default:
|
|
6880
|
-
console.log(
|
|
6767
|
+
console.log(chalk12.red(`Unknown format: ${format}. Use 'json' or 'markdown'.`));
|
|
6881
6768
|
}
|
|
6882
6769
|
}
|
|
6883
6770
|
async function generateAtoms(options = {}) {
|
|
6884
6771
|
const cwd = process.cwd();
|
|
6885
6772
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6886
6773
|
if (!existsSync13(constitutionPath)) {
|
|
6887
|
-
console.log(
|
|
6888
|
-
console.log(
|
|
6774
|
+
console.log(chalk12.red("No frozen Constitution found."));
|
|
6775
|
+
console.log(chalk12.dim("Run `archon interview` to create one first."));
|
|
6889
6776
|
return;
|
|
6890
6777
|
}
|
|
6891
6778
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
6892
6779
|
if (constitution.state !== "FROZEN") {
|
|
6893
|
-
console.log(
|
|
6894
|
-
console.log(
|
|
6780
|
+
console.log(chalk12.yellow("Constitution is not frozen yet."));
|
|
6781
|
+
console.log(chalk12.dim("Complete the interview and freeze before generating atoms."));
|
|
6895
6782
|
return;
|
|
6896
6783
|
}
|
|
6897
|
-
console.log(
|
|
6898
|
-
console.log(
|
|
6899
|
-
console.log(
|
|
6784
|
+
console.log(chalk12.bold("\n\u{1F527} Generating Atoms from Constitution\n"));
|
|
6785
|
+
console.log(chalk12.dim(`Project: ${constitution.branding.projectName}`));
|
|
6786
|
+
console.log(chalk12.dim(`Hash: ${constitution.hash?.substring(0, 16)}...`));
|
|
6900
6787
|
console.log();
|
|
6901
6788
|
const spinner = ora3("Generating atoms...").start();
|
|
6902
6789
|
const result = generateAtomsFromConstitution(constitution, {
|
|
@@ -6909,7 +6796,7 @@ async function generateAtoms(options = {}) {
|
|
|
6909
6796
|
console.log(summarizeGeneration(result));
|
|
6910
6797
|
console.log();
|
|
6911
6798
|
if (options.dryRun) {
|
|
6912
|
-
console.log(
|
|
6799
|
+
console.log(chalk12.dim("(Dry run - not writing prd.json)"));
|
|
6913
6800
|
return;
|
|
6914
6801
|
}
|
|
6915
6802
|
const prdPath = options.output ?? join13(cwd, "prd.json");
|
|
@@ -6917,23 +6804,23 @@ async function generateAtoms(options = {}) {
|
|
|
6917
6804
|
if (existsSync13(prdPath)) {
|
|
6918
6805
|
const overwrite = await promptYesNo3("prd.json already exists. Overwrite?", false);
|
|
6919
6806
|
if (!overwrite) {
|
|
6920
|
-
console.log(
|
|
6807
|
+
console.log(chalk12.dim("Cancelled. Existing prd.json preserved."));
|
|
6921
6808
|
return;
|
|
6922
6809
|
}
|
|
6923
6810
|
}
|
|
6924
6811
|
writeFileSync(prdPath, JSON.stringify(prdContent, null, 2));
|
|
6925
|
-
console.log(
|
|
6812
|
+
console.log(chalk12.green(`
|
|
6926
6813
|
\u2713 Written to ${prdPath}`));
|
|
6927
6814
|
console.log();
|
|
6928
|
-
console.log(
|
|
6929
|
-
console.log(` ${
|
|
6930
|
-
console.log(` ${
|
|
6931
|
-
console.log(` ${
|
|
6815
|
+
console.log(chalk12.bold("Next Steps:\n"));
|
|
6816
|
+
console.log(` ${chalk12.cyan("1.")} Run ${chalk12.bold("archon list")} to see all atoms`);
|
|
6817
|
+
console.log(` ${chalk12.cyan("2.")} Run ${chalk12.bold("archon execute ATOM-001")} to start building`);
|
|
6818
|
+
console.log(` ${chalk12.cyan("3.")} Run ${chalk12.bold("archon watch")} to monitor progress`);
|
|
6932
6819
|
console.log();
|
|
6933
6820
|
}
|
|
6934
6821
|
|
|
6935
6822
|
// src/cli/eject.ts
|
|
6936
|
-
import
|
|
6823
|
+
import chalk13 from "chalk";
|
|
6937
6824
|
import { existsSync as existsSync14, rmSync } from "fs";
|
|
6938
6825
|
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
6939
6826
|
import { join as join14 } from "path";
|
|
@@ -6950,70 +6837,70 @@ var METADATA_FILES = [
|
|
|
6950
6837
|
];
|
|
6951
6838
|
async function eject(options = {}) {
|
|
6952
6839
|
const cwd = process.cwd();
|
|
6953
|
-
console.log(
|
|
6840
|
+
console.log(chalk13.blue("\n\u{1F680} ArchonDev Eject\n"));
|
|
6954
6841
|
const archonDir = join14(cwd, ".archon");
|
|
6955
6842
|
if (!existsSync14(archonDir)) {
|
|
6956
|
-
console.log(
|
|
6843
|
+
console.log(chalk13.yellow("This does not appear to be an ArchonDev project (.archon/ not found)."));
|
|
6957
6844
|
return;
|
|
6958
6845
|
}
|
|
6959
|
-
console.log(
|
|
6846
|
+
console.log(chalk13.dim("The following will be removed/modified:\n"));
|
|
6960
6847
|
const filesToRemove = [];
|
|
6961
6848
|
for (const file of ARCHON_FILES) {
|
|
6962
6849
|
const filePath = join14(cwd, file);
|
|
6963
6850
|
if (existsSync14(filePath)) {
|
|
6964
6851
|
filesToRemove.push(file);
|
|
6965
|
-
console.log(
|
|
6852
|
+
console.log(chalk13.red(` \u2717 ${file}`));
|
|
6966
6853
|
}
|
|
6967
6854
|
}
|
|
6968
6855
|
const archMd = join14(cwd, "ARCHITECTURE.md");
|
|
6969
6856
|
if (existsSync14(archMd) && !options.keepArchitecture) {
|
|
6970
|
-
console.log(
|
|
6857
|
+
console.log(chalk13.yellow(` ? ARCHITECTURE.md (will be kept by default)`));
|
|
6971
6858
|
}
|
|
6972
6859
|
console.log();
|
|
6973
|
-
console.log(
|
|
6860
|
+
console.log(chalk13.dim("Files to be modified:"));
|
|
6974
6861
|
for (const file of METADATA_FILES) {
|
|
6975
6862
|
const filePath = join14(cwd, file);
|
|
6976
6863
|
if (existsSync14(filePath)) {
|
|
6977
|
-
console.log(
|
|
6864
|
+
console.log(chalk13.yellow(` \u25CF ${file}`));
|
|
6978
6865
|
}
|
|
6979
6866
|
}
|
|
6980
6867
|
console.log();
|
|
6981
6868
|
if (!options.force) {
|
|
6982
6869
|
const confirmed = await promptYesNo4("This will permanently remove ArchonDev from your project. Continue?", false);
|
|
6983
6870
|
if (!confirmed) {
|
|
6984
|
-
console.log(
|
|
6871
|
+
console.log(chalk13.dim("Eject cancelled."));
|
|
6985
6872
|
return;
|
|
6986
6873
|
}
|
|
6987
6874
|
}
|
|
6988
6875
|
console.log();
|
|
6989
6876
|
const result = await performEject(cwd, options);
|
|
6990
6877
|
if (result.success) {
|
|
6991
|
-
console.log(
|
|
6878
|
+
console.log(chalk13.green("\n\u2705 Eject complete!\n"));
|
|
6992
6879
|
if (result.filesRemoved.length > 0) {
|
|
6993
|
-
console.log(
|
|
6880
|
+
console.log(chalk13.dim("Removed:"));
|
|
6994
6881
|
for (const file of result.filesRemoved) {
|
|
6995
|
-
console.log(
|
|
6882
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
6996
6883
|
}
|
|
6997
6884
|
}
|
|
6998
6885
|
if (result.filesModified.length > 0) {
|
|
6999
|
-
console.log(
|
|
6886
|
+
console.log(chalk13.dim("\nModified:"));
|
|
7000
6887
|
for (const file of result.filesModified) {
|
|
7001
|
-
console.log(
|
|
6888
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
7002
6889
|
}
|
|
7003
6890
|
}
|
|
7004
6891
|
if (result.warnings.length > 0) {
|
|
7005
|
-
console.log(
|
|
6892
|
+
console.log(chalk13.yellow("\nWarnings:"));
|
|
7006
6893
|
for (const warning of result.warnings) {
|
|
7007
|
-
console.log(
|
|
6894
|
+
console.log(chalk13.yellow(` \u26A0\uFE0F ${warning}`));
|
|
7008
6895
|
}
|
|
7009
6896
|
}
|
|
7010
6897
|
console.log();
|
|
7011
|
-
console.log(
|
|
7012
|
-
console.log(
|
|
6898
|
+
console.log(chalk13.blue("Your project is now a standard repository."));
|
|
6899
|
+
console.log(chalk13.dim("Thank you for using ArchonDev!"));
|
|
7013
6900
|
} else {
|
|
7014
|
-
console.log(
|
|
6901
|
+
console.log(chalk13.red("\n\u274C Eject failed."));
|
|
7015
6902
|
for (const warning of result.warnings) {
|
|
7016
|
-
console.log(
|
|
6903
|
+
console.log(chalk13.red(` ${warning}`));
|
|
7017
6904
|
}
|
|
7018
6905
|
}
|
|
7019
6906
|
}
|
|
@@ -7120,17 +7007,17 @@ async function performEject(cwd, options) {
|
|
|
7120
7007
|
}
|
|
7121
7008
|
async function ejectDryRun() {
|
|
7122
7009
|
const cwd = process.cwd();
|
|
7123
|
-
console.log(
|
|
7010
|
+
console.log(chalk13.blue("\n\u{1F50D} Eject Dry Run\n"));
|
|
7124
7011
|
const archonDir = join14(cwd, ".archon");
|
|
7125
7012
|
if (!existsSync14(archonDir)) {
|
|
7126
|
-
console.log(
|
|
7013
|
+
console.log(chalk13.yellow("This does not appear to be an ArchonDev project."));
|
|
7127
7014
|
return;
|
|
7128
7015
|
}
|
|
7129
7016
|
console.log("The following would be removed:\n");
|
|
7130
7017
|
for (const file of ARCHON_FILES) {
|
|
7131
7018
|
const filePath = join14(cwd, file);
|
|
7132
7019
|
if (existsSync14(filePath)) {
|
|
7133
|
-
console.log(
|
|
7020
|
+
console.log(chalk13.red(` \u2717 ${file}`));
|
|
7134
7021
|
}
|
|
7135
7022
|
}
|
|
7136
7023
|
console.log();
|
|
@@ -7138,11 +7025,11 @@ async function ejectDryRun() {
|
|
|
7138
7025
|
for (const file of METADATA_FILES) {
|
|
7139
7026
|
const filePath = join14(cwd, file);
|
|
7140
7027
|
if (existsSync14(filePath)) {
|
|
7141
|
-
console.log(
|
|
7028
|
+
console.log(chalk13.yellow(` \u25CF ${file}`));
|
|
7142
7029
|
}
|
|
7143
7030
|
}
|
|
7144
7031
|
console.log();
|
|
7145
|
-
console.log(
|
|
7032
|
+
console.log(chalk13.dim('Run "archon eject" to proceed.'));
|
|
7146
7033
|
}
|
|
7147
7034
|
function promptYesNo4(question, defaultValue) {
|
|
7148
7035
|
return new Promise((resolve) => {
|
|
@@ -7151,7 +7038,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7151
7038
|
output: process.stdout
|
|
7152
7039
|
});
|
|
7153
7040
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7154
|
-
rl.question(`${
|
|
7041
|
+
rl.question(`${chalk13.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7155
7042
|
rl.close();
|
|
7156
7043
|
if (answer.trim() === "") {
|
|
7157
7044
|
resolve(defaultValue);
|
|
@@ -7163,7 +7050,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7163
7050
|
}
|
|
7164
7051
|
|
|
7165
7052
|
// src/cli/revert.ts
|
|
7166
|
-
import
|
|
7053
|
+
import chalk14 from "chalk";
|
|
7167
7054
|
import { execSync as execSync4 } from "child_process";
|
|
7168
7055
|
import { existsSync as existsSync15 } from "fs";
|
|
7169
7056
|
import { readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
@@ -7208,35 +7095,35 @@ async function findAtomCommits(limit = 50) {
|
|
|
7208
7095
|
}
|
|
7209
7096
|
return commits;
|
|
7210
7097
|
} catch (error) {
|
|
7211
|
-
console.error(
|
|
7098
|
+
console.error(chalk14.red("Failed to read git history:"), error instanceof Error ? error.message : "Unknown error");
|
|
7212
7099
|
return [];
|
|
7213
7100
|
}
|
|
7214
7101
|
}
|
|
7215
7102
|
async function historyCommand(options) {
|
|
7216
7103
|
const limit = options.limit ?? 20;
|
|
7217
|
-
console.log(
|
|
7104
|
+
console.log(chalk14.blue("\n\u{1F4DC} Atom Execution History\n"));
|
|
7218
7105
|
const commits = await findAtomCommits(limit);
|
|
7219
7106
|
if (commits.length === 0) {
|
|
7220
|
-
console.log(
|
|
7221
|
-
console.log(
|
|
7107
|
+
console.log(chalk14.dim("No atom commits found in git history."));
|
|
7108
|
+
console.log(chalk14.dim('Atom commits are created when you run "archon execute <atom-id>".'));
|
|
7222
7109
|
return;
|
|
7223
7110
|
}
|
|
7224
|
-
console.log(
|
|
7111
|
+
console.log(chalk14.dim(`Showing ${commits.length} atom commit(s):
|
|
7225
7112
|
`));
|
|
7226
7113
|
for (const commit of commits) {
|
|
7227
7114
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7228
7115
|
const filesLabel = commit.filesChanged === 1 ? "file" : "files";
|
|
7229
|
-
console.log(`${
|
|
7230
|
-
console.log(
|
|
7231
|
-
console.log(
|
|
7116
|
+
console.log(`${chalk14.yellow(shortHash)} ${chalk14.cyan(commit.atomId)}`);
|
|
7117
|
+
console.log(chalk14.dim(` ${commit.message}`));
|
|
7118
|
+
console.log(chalk14.dim(` ${commit.date} | ${commit.filesChanged} ${filesLabel} changed`));
|
|
7232
7119
|
console.log();
|
|
7233
7120
|
}
|
|
7234
|
-
console.log(
|
|
7235
|
-
console.log(
|
|
7121
|
+
console.log(chalk14.dim("To revert an atom: archon revert <atom-id>"));
|
|
7122
|
+
console.log(chalk14.dim("Or by commit hash: archon revert --commit <hash>"));
|
|
7236
7123
|
}
|
|
7237
7124
|
async function revertCommand(atomIdOrHash, options = {}) {
|
|
7238
7125
|
const cwd = process.cwd();
|
|
7239
|
-
console.log(
|
|
7126
|
+
console.log(chalk14.blue("\n\u23EA Atom Revert\n"));
|
|
7240
7127
|
let commit;
|
|
7241
7128
|
if (atomIdOrHash.match(/^[a-f0-9]{7,40}$/i)) {
|
|
7242
7129
|
const commits = await findAtomCommits(100);
|
|
@@ -7246,54 +7133,54 @@ async function revertCommand(atomIdOrHash, options = {}) {
|
|
|
7246
7133
|
commit = commits.find((c) => c.atomId.toLowerCase() === atomIdOrHash.toLowerCase());
|
|
7247
7134
|
}
|
|
7248
7135
|
if (!commit) {
|
|
7249
|
-
console.log(
|
|
7250
|
-
console.log(
|
|
7136
|
+
console.log(chalk14.red(`No atom commit found for: ${atomIdOrHash}`));
|
|
7137
|
+
console.log(chalk14.dim('Run "archon history" to see available atom commits.'));
|
|
7251
7138
|
return;
|
|
7252
7139
|
}
|
|
7253
|
-
console.log(`Atom: ${
|
|
7254
|
-
console.log(`Commit: ${
|
|
7140
|
+
console.log(`Atom: ${chalk14.cyan(commit.atomId)}`);
|
|
7141
|
+
console.log(`Commit: ${chalk14.yellow(commit.commitHash.substring(0, 7))}`);
|
|
7255
7142
|
console.log(`Message: ${commit.message}`);
|
|
7256
7143
|
console.log(`Date: ${commit.date}`);
|
|
7257
7144
|
console.log(`Files changed: ${commit.filesChanged}`);
|
|
7258
7145
|
console.log();
|
|
7259
7146
|
try {
|
|
7260
|
-
console.log(
|
|
7147
|
+
console.log(chalk14.dim("Changes to be reverted:"));
|
|
7261
7148
|
const diffStat = execSync4(
|
|
7262
7149
|
`git diff --stat ${commit.commitHash}^..${commit.commitHash}`,
|
|
7263
7150
|
{ cwd, encoding: "utf-8" }
|
|
7264
7151
|
);
|
|
7265
|
-
console.log(
|
|
7152
|
+
console.log(chalk14.dim(diffStat));
|
|
7266
7153
|
} catch {
|
|
7267
7154
|
}
|
|
7268
7155
|
if (!options.force) {
|
|
7269
7156
|
const confirmed = await promptYesNo5("Revert this atom commit?", false);
|
|
7270
7157
|
if (!confirmed) {
|
|
7271
|
-
console.log(
|
|
7158
|
+
console.log(chalk14.dim("Revert cancelled."));
|
|
7272
7159
|
return;
|
|
7273
7160
|
}
|
|
7274
7161
|
}
|
|
7275
7162
|
try {
|
|
7276
7163
|
const revertArgs = options.noCommit ? "--no-commit" : "";
|
|
7277
7164
|
execSync4(`git revert ${revertArgs} ${commit.commitHash}`, { cwd, stdio: "pipe" });
|
|
7278
|
-
console.log(
|
|
7165
|
+
console.log(chalk14.green(`
|
|
7279
7166
|
\u2705 Successfully reverted ${commit.atomId}`));
|
|
7280
7167
|
if (options.noCommit) {
|
|
7281
|
-
console.log(
|
|
7282
|
-
console.log(
|
|
7168
|
+
console.log(chalk14.dim("Changes are staged but not committed."));
|
|
7169
|
+
console.log(chalk14.dim('Run "git commit" to finalize the revert.'));
|
|
7283
7170
|
} else {
|
|
7284
|
-
console.log(
|
|
7171
|
+
console.log(chalk14.dim("A new commit has been created to undo the changes."));
|
|
7285
7172
|
}
|
|
7286
7173
|
await updateAtomStatus(commit.atomId, "REVERTED");
|
|
7287
7174
|
} catch (error) {
|
|
7288
7175
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
7289
7176
|
if (errorMsg.includes("conflict")) {
|
|
7290
|
-
console.log(
|
|
7291
|
-
console.log(
|
|
7292
|
-
console.log(
|
|
7293
|
-
console.log(
|
|
7177
|
+
console.log(chalk14.yellow("\n\u26A0\uFE0F Merge conflict detected during revert."));
|
|
7178
|
+
console.log(chalk14.dim("Resolve conflicts manually, then:"));
|
|
7179
|
+
console.log(chalk14.dim(" git add ."));
|
|
7180
|
+
console.log(chalk14.dim(" git revert --continue"));
|
|
7294
7181
|
} else {
|
|
7295
|
-
console.log(
|
|
7296
|
-
console.log(
|
|
7182
|
+
console.log(chalk14.red("\n\u274C Revert failed:"), errorMsg);
|
|
7183
|
+
console.log(chalk14.dim("You may need to resolve this manually."));
|
|
7297
7184
|
}
|
|
7298
7185
|
}
|
|
7299
7186
|
}
|
|
@@ -7312,10 +7199,10 @@ async function updateAtomStatus(atomId, status2) {
|
|
|
7312
7199
|
}
|
|
7313
7200
|
}
|
|
7314
7201
|
async function revertableAtoms() {
|
|
7315
|
-
console.log(
|
|
7202
|
+
console.log(chalk14.blue("\n\u{1F504} Revertable Atoms\n"));
|
|
7316
7203
|
const commits = await findAtomCommits(30);
|
|
7317
7204
|
if (commits.length === 0) {
|
|
7318
|
-
console.log(
|
|
7205
|
+
console.log(chalk14.dim("No atom commits found."));
|
|
7319
7206
|
return;
|
|
7320
7207
|
}
|
|
7321
7208
|
const atomMap = /* @__PURE__ */ new Map();
|
|
@@ -7324,14 +7211,14 @@ async function revertableAtoms() {
|
|
|
7324
7211
|
atomMap.set(commit.atomId, commit);
|
|
7325
7212
|
}
|
|
7326
7213
|
}
|
|
7327
|
-
console.log(
|
|
7214
|
+
console.log(chalk14.dim(`Found ${atomMap.size} unique atom(s) in history:
|
|
7328
7215
|
`));
|
|
7329
7216
|
for (const [atomId, commit] of atomMap) {
|
|
7330
7217
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7331
|
-
console.log(` ${
|
|
7218
|
+
console.log(` ${chalk14.cyan(atomId)} ${chalk14.dim(`(${shortHash})`)} - ${commit.message.substring(0, 50)}`);
|
|
7332
7219
|
}
|
|
7333
7220
|
console.log();
|
|
7334
|
-
console.log(
|
|
7221
|
+
console.log(chalk14.dim("To revert: archon revert <atom-id>"));
|
|
7335
7222
|
}
|
|
7336
7223
|
function promptYesNo5(question, defaultValue) {
|
|
7337
7224
|
return new Promise((resolve) => {
|
|
@@ -7340,7 +7227,7 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7340
7227
|
output: process.stdout
|
|
7341
7228
|
});
|
|
7342
7229
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7343
|
-
rl.question(`${
|
|
7230
|
+
rl.question(`${chalk14.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7344
7231
|
rl.close();
|
|
7345
7232
|
if (answer.trim() === "") {
|
|
7346
7233
|
resolve(defaultValue);
|
|
@@ -7352,17 +7239,17 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7352
7239
|
}
|
|
7353
7240
|
|
|
7354
7241
|
// src/cli/models-sync.ts
|
|
7355
|
-
import
|
|
7242
|
+
import chalk15 from "chalk";
|
|
7356
7243
|
async function modelsSync(options) {
|
|
7357
7244
|
const supabaseUrl = process.env["SUPABASE_URL"];
|
|
7358
7245
|
const supabaseKey = process.env["SUPABASE_SERVICE_ROLE_KEY"] || process.env["SUPABASE_ANON_KEY"];
|
|
7359
7246
|
if (!supabaseUrl) {
|
|
7360
|
-
console.log(
|
|
7361
|
-
console.log(
|
|
7362
|
-
console.log(
|
|
7247
|
+
console.log(chalk15.red("SUPABASE_URL not set. Cannot trigger remote sync."));
|
|
7248
|
+
console.log(chalk15.dim("Run the pricing check locally instead:"));
|
|
7249
|
+
console.log(chalk15.dim(" npx tsx scripts/update-model-pricing.ts --check"));
|
|
7363
7250
|
return;
|
|
7364
7251
|
}
|
|
7365
|
-
console.log(
|
|
7252
|
+
console.log(chalk15.blue("\n\u{1F504} Triggering model registry sync...\n"));
|
|
7366
7253
|
try {
|
|
7367
7254
|
const functionUrl = `${supabaseUrl}/functions/v1/model-registry-sync`;
|
|
7368
7255
|
const response = await fetch(functionUrl, {
|
|
@@ -7374,83 +7261,83 @@ async function modelsSync(options) {
|
|
|
7374
7261
|
});
|
|
7375
7262
|
if (!response.ok) {
|
|
7376
7263
|
const errorText = await response.text();
|
|
7377
|
-
console.log(
|
|
7264
|
+
console.log(chalk15.red(`Sync failed: ${response.status} - ${errorText}`));
|
|
7378
7265
|
return;
|
|
7379
7266
|
}
|
|
7380
7267
|
const result = await response.json();
|
|
7381
|
-
console.log(
|
|
7268
|
+
console.log(chalk15.bold("Sync Results:"));
|
|
7382
7269
|
console.log(` Providers checked: ${result.providersChecked.join(", ")}`);
|
|
7383
7270
|
console.log(` Duration: ${result.durationMs}ms`);
|
|
7384
7271
|
console.log();
|
|
7385
|
-
console.log(
|
|
7272
|
+
console.log(chalk15.bold("Parse Confidence:"));
|
|
7386
7273
|
for (const [provider, score] of Object.entries(result.confidenceScores)) {
|
|
7387
7274
|
const pct = (score * 100).toFixed(0);
|
|
7388
|
-
const color = score >= 0.8 ?
|
|
7275
|
+
const color = score >= 0.8 ? chalk15.green : score >= 0.5 ? chalk15.yellow : chalk15.red;
|
|
7389
7276
|
console.log(` ${provider}: ${color(pct + "%")}`);
|
|
7390
7277
|
}
|
|
7391
7278
|
console.log();
|
|
7392
7279
|
if (result.diffs.length === 0) {
|
|
7393
|
-
console.log(
|
|
7280
|
+
console.log(chalk15.green("\u2705 All model pricing is up to date. No changes detected."));
|
|
7394
7281
|
} else {
|
|
7395
7282
|
const pricingChanges = result.diffs.filter((d) => d.type === "PRICING_CHANGE");
|
|
7396
7283
|
const newModels = result.diffs.filter((d) => d.type === "NEW_MODEL");
|
|
7397
7284
|
if (pricingChanges.length > 0) {
|
|
7398
|
-
console.log(
|
|
7285
|
+
console.log(chalk15.yellow(`\u{1F4B0} Pricing Changes (${pricingChanges.length}):`));
|
|
7399
7286
|
for (const d of pricingChanges) {
|
|
7400
|
-
console.log(` ${d.provider}/${
|
|
7401
|
-
console.log(` Old: ${
|
|
7402
|
-
console.log(` New: ${
|
|
7287
|
+
console.log(` ${d.provider}/${chalk15.bold(d.modelId)}`);
|
|
7288
|
+
console.log(` Old: ${chalk15.red(d.oldValue ?? "unknown")}`);
|
|
7289
|
+
console.log(` New: ${chalk15.green(d.newValue ?? "unknown")}`);
|
|
7403
7290
|
}
|
|
7404
7291
|
console.log();
|
|
7405
7292
|
}
|
|
7406
7293
|
if (newModels.length > 0) {
|
|
7407
|
-
console.log(
|
|
7294
|
+
console.log(chalk15.cyan(`\u{1F195} New Models (${newModels.length}):`));
|
|
7408
7295
|
for (const d of newModels) {
|
|
7409
|
-
console.log(` ${d.provider}/${
|
|
7296
|
+
console.log(` ${d.provider}/${chalk15.bold(d.modelId)}: ${d.details}`);
|
|
7410
7297
|
}
|
|
7411
7298
|
console.log();
|
|
7412
7299
|
}
|
|
7413
|
-
console.log(
|
|
7300
|
+
console.log(chalk15.bold(`Applied: ${result.modelsUpdated} updated, ${result.modelsAdded} added`));
|
|
7414
7301
|
}
|
|
7415
7302
|
if (result.parseErrors.length > 0) {
|
|
7416
7303
|
console.log();
|
|
7417
|
-
console.log(
|
|
7304
|
+
console.log(chalk15.red(`\u26A0\uFE0F Warnings/Errors (${result.parseErrors.length}):`));
|
|
7418
7305
|
for (const err2 of result.parseErrors) {
|
|
7419
|
-
console.log(
|
|
7306
|
+
console.log(chalk15.red(` - ${err2}`));
|
|
7420
7307
|
}
|
|
7421
7308
|
}
|
|
7422
7309
|
console.log();
|
|
7423
7310
|
} catch (err2) {
|
|
7424
|
-
console.log(
|
|
7311
|
+
console.log(chalk15.red(`Failed to run sync: ${err2}`));
|
|
7425
7312
|
}
|
|
7426
7313
|
}
|
|
7427
7314
|
async function modelsList() {
|
|
7428
7315
|
const { getAllActiveModels, getModelCost, isFreeModel } = await import("./models-UTFGCHAY.js");
|
|
7429
7316
|
const models = getAllActiveModels();
|
|
7430
|
-
console.log(
|
|
7317
|
+
console.log(chalk15.bold("\n\u{1F4CB} Model Registry\n"));
|
|
7431
7318
|
let currentProvider = "";
|
|
7432
7319
|
for (const model of models) {
|
|
7433
7320
|
if (model.provider !== currentProvider) {
|
|
7434
7321
|
currentProvider = model.provider;
|
|
7435
|
-
console.log(
|
|
7322
|
+
console.log(chalk15.bold.blue(`
|
|
7436
7323
|
${currentProvider.toUpperCase()}`));
|
|
7437
|
-
console.log(
|
|
7324
|
+
console.log(chalk15.dim(" \u2500".repeat(40)));
|
|
7438
7325
|
}
|
|
7439
7326
|
const cost = getModelCost(model.modelId);
|
|
7440
7327
|
const free = isFreeModel(model.modelId);
|
|
7441
|
-
const tier = free ?
|
|
7442
|
-
const category = model.category === "thinking" ?
|
|
7328
|
+
const tier = free ? chalk15.green(" [FREE]") : "";
|
|
7329
|
+
const category = model.category === "thinking" ? chalk15.magenta("thinking") : chalk15.cyan("fast");
|
|
7443
7330
|
const inputPrice = cost ? `$${(cost.costPer1kInput * 1e3).toFixed(2)}/1M` : "?";
|
|
7444
7331
|
const outputPrice = cost ? `$${(cost.costPer1kOutput * 1e3).toFixed(2)}/1M` : "?";
|
|
7445
|
-
console.log(` ${
|
|
7446
|
-
console.log(
|
|
7332
|
+
console.log(` ${chalk15.bold(model.modelId)}${tier}`);
|
|
7333
|
+
console.log(chalk15.dim(` ${category} | Input: ${inputPrice} | Output: ${outputPrice}`));
|
|
7447
7334
|
}
|
|
7448
7335
|
console.log();
|
|
7449
7336
|
}
|
|
7450
7337
|
|
|
7451
7338
|
// src/cli/governance.ts
|
|
7452
7339
|
import { Command as Command2 } from "commander";
|
|
7453
|
-
import
|
|
7340
|
+
import chalk16 from "chalk";
|
|
7454
7341
|
import { existsSync as existsSync19, readFileSync as readFileSync7 } from "fs";
|
|
7455
7342
|
import { readFile as readFile12 } from "fs/promises";
|
|
7456
7343
|
import { join as join19 } from "path";
|
|
@@ -8270,9 +8157,9 @@ function parseContextMeta(content) {
|
|
|
8270
8157
|
function renderStatusCounts(counts) {
|
|
8271
8158
|
const total = Object.values(counts).reduce((sum, value) => sum + value, 0);
|
|
8272
8159
|
if (total === 0) return;
|
|
8273
|
-
console.log(
|
|
8160
|
+
console.log(chalk16.dim(` Tasks: ${total} total`));
|
|
8274
8161
|
console.log(
|
|
8275
|
-
|
|
8162
|
+
chalk16.dim(
|
|
8276
8163
|
` pending: ${counts.pending} | in_progress: ${counts.in_progress} | verification: ${counts.verification} | done: ${counts.done}`
|
|
8277
8164
|
)
|
|
8278
8165
|
);
|
|
@@ -8288,22 +8175,22 @@ function createGovernanceCommand() {
|
|
|
8288
8175
|
const cwd = process.cwd();
|
|
8289
8176
|
const store = new GovernanceStore(cwd);
|
|
8290
8177
|
store.ensureStructure();
|
|
8291
|
-
console.log(
|
|
8178
|
+
console.log(chalk16.bold("\nGovernance Status\n"));
|
|
8292
8179
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8293
8180
|
if (archInfo.path) {
|
|
8294
8181
|
const parser = new ArchitectureParser(archInfo.path);
|
|
8295
8182
|
const parsed = await parser.parse();
|
|
8296
8183
|
if (parsed.success && parsed.schema) {
|
|
8297
8184
|
const posture = parsed.schema.qualityLevel?.posture ?? "unknown";
|
|
8298
|
-
console.log(
|
|
8299
|
-
console.log(
|
|
8300
|
-
console.log(
|
|
8301
|
-
console.log(
|
|
8185
|
+
console.log(chalk16.green(" \u2713") + ` Architecture (${archInfo.source})`);
|
|
8186
|
+
console.log(chalk16.dim(` posture: ${posture}`));
|
|
8187
|
+
console.log(chalk16.dim(` invariants: ${parsed.schema.invariants.length}`));
|
|
8188
|
+
console.log(chalk16.dim(` protected paths: ${parsed.schema.protectedPaths.length}`));
|
|
8302
8189
|
} else {
|
|
8303
|
-
console.log(
|
|
8190
|
+
console.log(chalk16.yellow(" ! Architecture present but failed to parse"));
|
|
8304
8191
|
}
|
|
8305
8192
|
} else {
|
|
8306
|
-
console.log(
|
|
8193
|
+
console.log(chalk16.yellow(" \u25CB No architecture file found"));
|
|
8307
8194
|
}
|
|
8308
8195
|
const tasksPath = join19(cwd, ACTIVE_TASKS_PATH2);
|
|
8309
8196
|
if (existsSync19(tasksPath)) {
|
|
@@ -8313,33 +8200,33 @@ function createGovernanceCommand() {
|
|
|
8313
8200
|
if (tasks2) {
|
|
8314
8201
|
renderStatusCounts(countTaskStatuses(tasks2));
|
|
8315
8202
|
} else {
|
|
8316
|
-
console.log(
|
|
8203
|
+
console.log(chalk16.yellow(" ! tasks.json present but invalid"));
|
|
8317
8204
|
}
|
|
8318
8205
|
} catch {
|
|
8319
|
-
console.log(
|
|
8206
|
+
console.log(chalk16.yellow(" ! tasks.json present but unreadable"));
|
|
8320
8207
|
}
|
|
8321
8208
|
}
|
|
8322
8209
|
const contextPath = join19(cwd, CURRENT_CONTEXT_PATH);
|
|
8323
8210
|
if (existsSync19(contextPath)) {
|
|
8324
8211
|
const content = readFileSync7(contextPath, "utf-8");
|
|
8325
8212
|
const meta = parseContextMeta(content);
|
|
8326
|
-
console.log(
|
|
8213
|
+
console.log(chalk16.dim(` Handoff: ${meta.timestamp ?? "present"}`));
|
|
8327
8214
|
if (meta.reason) {
|
|
8328
|
-
console.log(
|
|
8215
|
+
console.log(chalk16.dim(` reason: ${meta.reason}`));
|
|
8329
8216
|
}
|
|
8330
8217
|
}
|
|
8331
8218
|
const handoffHistoryPath = join19(cwd, HANDOFF_HISTORY_PATH);
|
|
8332
8219
|
if (existsSync19(handoffHistoryPath)) {
|
|
8333
8220
|
const count = lineCount(readFileSync7(handoffHistoryPath, "utf-8"));
|
|
8334
8221
|
if (count > 0) {
|
|
8335
|
-
console.log(
|
|
8222
|
+
console.log(chalk16.dim(` Handoff entries: ${count}`));
|
|
8336
8223
|
}
|
|
8337
8224
|
}
|
|
8338
8225
|
const completedPath = join19(cwd, COMPLETED_TASKS_PATH);
|
|
8339
8226
|
if (existsSync19(completedPath)) {
|
|
8340
8227
|
const count = lineCount(readFileSync7(completedPath, "utf-8"));
|
|
8341
8228
|
if (count > 0) {
|
|
8342
|
-
console.log(
|
|
8229
|
+
console.log(chalk16.dim(` Completed tasks archived: ${count}`));
|
|
8343
8230
|
}
|
|
8344
8231
|
}
|
|
8345
8232
|
console.log("");
|
|
@@ -8350,7 +8237,7 @@ function createGovernanceCommand() {
|
|
|
8350
8237
|
const store = new GovernanceStore(cwd);
|
|
8351
8238
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8352
8239
|
if (!archInfo.path) {
|
|
8353
|
-
console.log(
|
|
8240
|
+
console.log(chalk16.yellow("No architecture file found."));
|
|
8354
8241
|
return;
|
|
8355
8242
|
}
|
|
8356
8243
|
if (options.raw) {
|
|
@@ -8361,11 +8248,11 @@ function createGovernanceCommand() {
|
|
|
8361
8248
|
if (archInfo.source === "agd") {
|
|
8362
8249
|
const result = await store.readArchitecture();
|
|
8363
8250
|
if (!result.ok) {
|
|
8364
|
-
console.log(
|
|
8251
|
+
console.log(chalk16.red(`Failed to read architecture: ${result.error}`));
|
|
8365
8252
|
return;
|
|
8366
8253
|
}
|
|
8367
8254
|
if (!result.value) {
|
|
8368
|
-
console.log(
|
|
8255
|
+
console.log(chalk16.yellow("Architecture file is empty."));
|
|
8369
8256
|
return;
|
|
8370
8257
|
}
|
|
8371
8258
|
console.log(result.value);
|
|
@@ -8375,7 +8262,7 @@ function createGovernanceCommand() {
|
|
|
8375
8262
|
const legacyParsed = matter4(legacyRaw);
|
|
8376
8263
|
const legacyContent = legacyParsed.content.trim();
|
|
8377
8264
|
if (!legacyContent) {
|
|
8378
|
-
console.log(
|
|
8265
|
+
console.log(chalk16.yellow("Architecture file is empty."));
|
|
8379
8266
|
return;
|
|
8380
8267
|
}
|
|
8381
8268
|
console.log(legacyContent);
|
|
@@ -8384,32 +8271,32 @@ function createGovernanceCommand() {
|
|
|
8384
8271
|
const cwd = process.cwd();
|
|
8385
8272
|
const filePath = options.file;
|
|
8386
8273
|
if (!existsSync19(filePath)) {
|
|
8387
|
-
console.log(
|
|
8274
|
+
console.log(chalk16.red(`File not found: ${filePath}`));
|
|
8388
8275
|
process.exit(1);
|
|
8389
8276
|
}
|
|
8390
8277
|
const content = await readFile12(filePath, "utf-8");
|
|
8391
8278
|
const store = new GovernanceStore(cwd);
|
|
8392
8279
|
const result = await store.updateArchitecture(content, options.reason, options.by);
|
|
8393
8280
|
if (!result.ok) {
|
|
8394
|
-
console.log(
|
|
8281
|
+
console.log(chalk16.red(`Failed to update architecture: ${result.error}`));
|
|
8395
8282
|
process.exit(1);
|
|
8396
8283
|
}
|
|
8397
|
-
console.log(
|
|
8284
|
+
console.log(chalk16.green("\u2713 Architecture updated"));
|
|
8398
8285
|
});
|
|
8399
8286
|
const tasks = governance.command("task").description("Update tasks in governance store");
|
|
8400
8287
|
tasks.command("update <taskId>").description("Update task status and notes").requiredOption("-s, --status <status>", "Status: pending, in_progress, verification, done").option("-n, --notes <text>", "Optional notes").action(async (taskId, options) => {
|
|
8401
8288
|
const status2 = options.status;
|
|
8402
8289
|
if (!isTaskStatus(status2)) {
|
|
8403
|
-
console.log(
|
|
8290
|
+
console.log(chalk16.red(`Invalid status: ${options.status}`));
|
|
8404
8291
|
process.exit(1);
|
|
8405
8292
|
}
|
|
8406
8293
|
const store = new GovernanceStore(process.cwd());
|
|
8407
8294
|
const result = await store.updateTask(taskId, status2, options.notes);
|
|
8408
8295
|
if (!result.ok) {
|
|
8409
|
-
console.log(
|
|
8296
|
+
console.log(chalk16.red(`Failed to update task: ${result.error}`));
|
|
8410
8297
|
process.exit(1);
|
|
8411
8298
|
}
|
|
8412
|
-
console.log(
|
|
8299
|
+
console.log(chalk16.green(`\u2713 Task ${taskId} updated to ${status2}`));
|
|
8413
8300
|
});
|
|
8414
8301
|
governance.command("handoff").description("Log a handoff entry and update current context").requiredOption("-r, --reason <text>", "Reason for handoff").requiredOption("-s, --summary <text>", "Summary (single paragraph)").requiredOption("-n, --next <actions...>", "Next actions (space-separated)").option("-f, --from <agent>", "Agent or source name").option("-t, --timestamp <iso>", "Timestamp override (ISO 8601)").action(async (options) => {
|
|
8415
8302
|
const store = new GovernanceStore(process.cwd());
|
|
@@ -8422,10 +8309,10 @@ function createGovernanceCommand() {
|
|
|
8422
8309
|
};
|
|
8423
8310
|
const result = await store.logHandoff(entry);
|
|
8424
8311
|
if (!result.ok) {
|
|
8425
|
-
console.log(
|
|
8312
|
+
console.log(chalk16.red(`Failed to log handoff: ${result.error}`));
|
|
8426
8313
|
process.exit(1);
|
|
8427
8314
|
}
|
|
8428
|
-
console.log(
|
|
8315
|
+
console.log(chalk16.green("\u2713 Handoff logged"));
|
|
8429
8316
|
});
|
|
8430
8317
|
governance.command("migrate").description("Migrate legacy governance files into AGD structure").option("--remove-legacy", "Archive legacy files after migration").option("--dry-run", "Show what would change without writing files").option("-b, --by <name>", "Updated by label for architecture migration").action(async (options) => {
|
|
8431
8318
|
const result = await migrateLegacyGovernance({
|
|
@@ -8434,23 +8321,23 @@ function createGovernanceCommand() {
|
|
|
8434
8321
|
dryRun: options.dryRun,
|
|
8435
8322
|
updatedBy: options.by
|
|
8436
8323
|
});
|
|
8437
|
-
console.log(
|
|
8324
|
+
console.log(chalk16.bold("\nMigration Summary"));
|
|
8438
8325
|
console.log(
|
|
8439
|
-
result.migratedArchitecture ?
|
|
8326
|
+
result.migratedArchitecture ? chalk16.green(" \u2713 Architecture migrated") : chalk16.dim(" \u25CB Architecture migration skipped")
|
|
8440
8327
|
);
|
|
8441
8328
|
console.log(
|
|
8442
|
-
result.migratedTasks ?
|
|
8329
|
+
result.migratedTasks ? chalk16.green(" \u2713 Tasks migrated") : chalk16.dim(" \u25CB Tasks migration skipped")
|
|
8443
8330
|
);
|
|
8444
8331
|
if (result.archivedLegacyFiles.length > 0) {
|
|
8445
|
-
console.log(
|
|
8332
|
+
console.log(chalk16.dim(" Archived legacy files:"));
|
|
8446
8333
|
for (const file of result.archivedLegacyFiles) {
|
|
8447
|
-
console.log(
|
|
8334
|
+
console.log(chalk16.dim(` - ${file}`));
|
|
8448
8335
|
}
|
|
8449
8336
|
}
|
|
8450
8337
|
if (result.warnings.length > 0) {
|
|
8451
|
-
console.log(
|
|
8338
|
+
console.log(chalk16.yellow("\nWarnings:"));
|
|
8452
8339
|
for (const warning of result.warnings) {
|
|
8453
|
-
console.log(
|
|
8340
|
+
console.log(chalk16.yellow(` - ${warning}`));
|
|
8454
8341
|
}
|
|
8455
8342
|
}
|
|
8456
8343
|
console.log("");
|
|
@@ -8461,7 +8348,7 @@ function createGovernanceCommand() {
|
|
|
8461
8348
|
view.init(cwd);
|
|
8462
8349
|
await view.loadFromDisk(cwd);
|
|
8463
8350
|
view.close();
|
|
8464
|
-
console.log(
|
|
8351
|
+
console.log(chalk16.green("\u2713 Governance SQLite DB initialized"));
|
|
8465
8352
|
});
|
|
8466
8353
|
return governance;
|
|
8467
8354
|
}
|
|
@@ -8473,7 +8360,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8473
8360
|
const cwd = process.cwd();
|
|
8474
8361
|
const wasInitialized = isInitialized(cwd);
|
|
8475
8362
|
if (!wasInitialized) {
|
|
8476
|
-
console.log(
|
|
8363
|
+
console.log(chalk17.blue("\nArchonDev is not initialized in this folder.\n"));
|
|
8477
8364
|
await init({ analyze: true, git: true });
|
|
8478
8365
|
}
|
|
8479
8366
|
await start({ skipGovernanceBanner: !wasInitialized });
|
|
@@ -8481,7 +8368,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8481
8368
|
program.command("login").description("Authenticate with ArchonDev").option("-p, --provider <provider>", "OAuth provider (github or google)", "github").action(async (options) => {
|
|
8482
8369
|
const provider = options.provider;
|
|
8483
8370
|
if (provider !== "github" && provider !== "google") {
|
|
8484
|
-
console.error(
|
|
8371
|
+
console.error(chalk17.red('Invalid provider. Use "github" or "google"'));
|
|
8485
8372
|
process.exit(1);
|
|
8486
8373
|
}
|
|
8487
8374
|
await login(provider);
|
|
@@ -8679,7 +8566,7 @@ cleanupCmd.command("check").description("Analyze workspace for bloat and mainten
|
|
|
8679
8566
|
cleanupCmd.command("run").description("Execute cleanup (archive old entries, remove stale files)").action(cleanupRun);
|
|
8680
8567
|
cleanupCmd.command("auto").description("Enable/disable automatic cleanup checks").argument("[action]", "enable, disable, or status", "status").action(async (action) => {
|
|
8681
8568
|
if (action !== "enable" && action !== "disable" && action !== "status") {
|
|
8682
|
-
console.error(
|
|
8569
|
+
console.error(chalk17.red("Invalid action. Use: enable, disable, or status"));
|
|
8683
8570
|
process.exit(1);
|
|
8684
8571
|
}
|
|
8685
8572
|
await cleanupAuto(action);
|