archondev 2.0.0 → 2.1.1

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/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  cloudLogs,
8
8
  cloudStatus,
9
9
  execute
10
- } from "./chunk-3WEJ3DXM.js";
10
+ } from "./chunk-XRWIU3RD.js";
11
11
  import {
12
12
  list
13
13
  } from "./chunk-N73LAU7W.js";
@@ -71,6 +71,7 @@ import {
71
71
  import "./chunk-A7QU6JC6.js";
72
72
  import "./chunk-SMR7JQK6.js";
73
73
  import {
74
+ getAuthToken,
74
75
  loadConfig
75
76
  } from "./chunk-IVY5AHPS.js";
76
77
  import {
@@ -80,7 +81,7 @@ import "./chunk-QGM4M3NI.js";
80
81
 
81
82
  // src/cli/index.ts
82
83
  import { Command as Command4 } from "commander";
83
- import chalk12 from "chalk";
84
+ import chalk14 from "chalk";
84
85
  import "dotenv/config";
85
86
 
86
87
  // src/cli/promote.ts
@@ -299,10 +300,10 @@ function formatDateTime(date) {
299
300
  }
300
301
 
301
302
  // src/cli/start.ts
302
- import chalk3 from "chalk";
303
+ import chalk4 from "chalk";
303
304
  import readline from "readline";
304
- import { existsSync as existsSync3, readFileSync, readdirSync, appendFileSync } from "fs";
305
- import { join as join3 } from "path";
305
+ import { existsSync as existsSync4, readFileSync, readdirSync as readdirSync2, appendFileSync } from "fs";
306
+ import { join as join4 } from "path";
306
307
 
307
308
  // src/core/context/manager.ts
308
309
  import { existsSync as existsSync2 } from "fs";
@@ -399,44 +400,479 @@ var ContextManager = class _ContextManager {
399
400
  async clearPendingAtoms(cwd) {
400
401
  const filePath = join2(cwd, _ContextManager.PENDING_ATOMS_FILE);
401
402
  if (existsSync2(filePath)) {
402
- const { unlink } = await import("fs/promises");
403
- await unlink(filePath);
403
+ const { unlink: unlink2 } = await import("fs/promises");
404
+ await unlink2(filePath);
404
405
  }
405
406
  }
406
407
  };
407
408
 
409
+ // src/cli/cleanup.ts
410
+ import chalk3 from "chalk";
411
+ import { existsSync as existsSync3, readdirSync, statSync } from "fs";
412
+ import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir2, unlink, readdir, stat } from "fs/promises";
413
+ import { join as join3 } from "path";
414
+ import yaml from "yaml";
415
+ import { execSync } from "child_process";
416
+ var CONFIG_PATH = ".archon/config.yaml";
417
+ var PROGRESS_FILE = "progress.txt";
418
+ var ARCHON_DIR = ".archon";
419
+ var CACHE_DIR = ".archon/cache";
420
+ var ARCHIVE_DIR = "docs/archive";
421
+ function formatBytes(bytes) {
422
+ if (bytes === 0) return "0 B";
423
+ const k = 1024;
424
+ const sizes = ["B", "KB", "MB", "GB"];
425
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
426
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
427
+ }
428
+ function getDirSize(dirPath) {
429
+ if (!existsSync3(dirPath)) return 0;
430
+ let totalSize = 0;
431
+ try {
432
+ const files = readdirSync(dirPath, { withFileTypes: true });
433
+ for (const file of files) {
434
+ const filePath = join3(dirPath, file.name);
435
+ if (file.isDirectory()) {
436
+ totalSize += getDirSize(filePath);
437
+ } else {
438
+ try {
439
+ totalSize += statSync(filePath).size;
440
+ } catch {
441
+ }
442
+ }
443
+ }
444
+ } catch {
445
+ }
446
+ return totalSize;
447
+ }
448
+ async function loadCleanupConfig(cwd) {
449
+ const configPath = join3(cwd, CONFIG_PATH);
450
+ if (!existsSync3(configPath)) {
451
+ return void 0;
452
+ }
453
+ try {
454
+ const content = await readFile3(configPath, "utf-8");
455
+ const config = yaml.parse(content);
456
+ return config.cleanup;
457
+ } catch {
458
+ return void 0;
459
+ }
460
+ }
461
+ async function saveCleanupConfig(cwd, cleanup) {
462
+ const configPath = join3(cwd, CONFIG_PATH);
463
+ const archonDir = join3(cwd, ARCHON_DIR);
464
+ if (!existsSync3(archonDir)) {
465
+ await mkdir2(archonDir, { recursive: true });
466
+ }
467
+ let existing = {};
468
+ if (existsSync3(configPath)) {
469
+ try {
470
+ const content = await readFile3(configPath, "utf-8");
471
+ existing = yaml.parse(content);
472
+ } catch {
473
+ }
474
+ }
475
+ existing.cleanup = cleanup;
476
+ await writeFile3(configPath, yaml.stringify(existing), "utf-8");
477
+ }
478
+ function getOrphanedWorktrees(cwd) {
479
+ const orphaned = [];
480
+ try {
481
+ const output = execSync("git worktree list --porcelain", {
482
+ cwd,
483
+ encoding: "utf-8"
484
+ });
485
+ const lines = output.split("\n");
486
+ let currentWorktree = "";
487
+ for (const line of lines) {
488
+ if (line.startsWith("worktree ")) {
489
+ currentWorktree = line.replace("worktree ", "");
490
+ } else if (line.startsWith("branch ")) {
491
+ if (currentWorktree.includes(".archon-worktree") || currentWorktree.includes("archon-parallel")) {
492
+ if (!existsSync3(join3(currentWorktree, ".git"))) {
493
+ orphaned.push(currentWorktree);
494
+ }
495
+ }
496
+ }
497
+ }
498
+ } catch {
499
+ }
500
+ return orphaned;
501
+ }
502
+ async function getStaleFiles(dirPath, maxAgeDays) {
503
+ const staleFiles = [];
504
+ if (!existsSync3(dirPath)) return staleFiles;
505
+ const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1e3;
506
+ try {
507
+ const entries = await readdir(dirPath, { withFileTypes: true });
508
+ for (const entry of entries) {
509
+ const fullPath = join3(dirPath, entry.name);
510
+ if (entry.isFile()) {
511
+ try {
512
+ const stats = await stat(fullPath);
513
+ if (stats.mtimeMs < cutoffTime) {
514
+ staleFiles.push({ path: fullPath, size: stats.size });
515
+ }
516
+ } catch {
517
+ }
518
+ } else if (entry.isDirectory()) {
519
+ const nested = await getStaleFiles(fullPath, maxAgeDays);
520
+ staleFiles.push(...nested);
521
+ }
522
+ }
523
+ } catch {
524
+ }
525
+ return staleFiles;
526
+ }
527
+ async function parseProgressEntries(content) {
528
+ const entries = [];
529
+ const lines = content.split("\n");
530
+ let currentEntry = "";
531
+ let currentDate = null;
532
+ const datePatterns = [
533
+ /^\[(\d{4}-\d{2}-\d{2})/,
534
+ /^## (\d{4}-\d{2}-\d{2})/,
535
+ /^### (\d{4}-\d{2}-\d{2})/,
536
+ /^(\d{4}-\d{2}-\d{2})/
537
+ ];
538
+ for (const line of lines) {
539
+ let dateMatch = null;
540
+ for (const pattern of datePatterns) {
541
+ const match = line.match(pattern);
542
+ if (match?.[1]) {
543
+ dateMatch = match[1];
544
+ break;
545
+ }
546
+ }
547
+ if (dateMatch) {
548
+ if (currentDate && currentEntry.trim()) {
549
+ entries.push({ date: currentDate, content: currentEntry.trim() });
550
+ }
551
+ currentDate = new Date(dateMatch);
552
+ currentEntry = line + "\n";
553
+ } else {
554
+ currentEntry += line + "\n";
555
+ }
556
+ }
557
+ if (currentDate && currentEntry.trim()) {
558
+ entries.push({ date: currentDate, content: currentEntry.trim() });
559
+ }
560
+ return entries;
561
+ }
562
+ async function cleanupCheck() {
563
+ const cwd = process.cwd();
564
+ const results = [];
565
+ console.log(chalk3.blue("\n\u{1F50D} Analyzing workspace for maintenance needs...\n"));
566
+ const progressPath = join3(cwd, PROGRESS_FILE);
567
+ if (existsSync3(progressPath)) {
568
+ const size = statSync(progressPath).size;
569
+ let status2 = "ok";
570
+ let recommendation;
571
+ if (size > 200 * 1024) {
572
+ status2 = "critical";
573
+ recommendation = "Archive old entries with: archon cleanup run";
574
+ } else if (size > 100 * 1024) {
575
+ status2 = "warn";
576
+ recommendation = "Consider archiving entries older than 30 days";
577
+ }
578
+ results.push({
579
+ name: "progress.txt",
580
+ size,
581
+ sizeFormatted: formatBytes(size),
582
+ status: status2,
583
+ recommendation
584
+ });
585
+ }
586
+ const archonPath = join3(cwd, ARCHON_DIR);
587
+ if (existsSync3(archonPath)) {
588
+ const size = getDirSize(archonPath);
589
+ let status2 = "ok";
590
+ let recommendation;
591
+ if (size > 10 * 1024 * 1024) {
592
+ status2 = "warn";
593
+ recommendation = "Clear stale cache files with: archon cleanup run";
594
+ }
595
+ results.push({
596
+ name: ".archon/",
597
+ size,
598
+ sizeFormatted: formatBytes(size),
599
+ status: status2,
600
+ recommendation
601
+ });
602
+ }
603
+ const nodeModulesPath = join3(cwd, "node_modules");
604
+ if (existsSync3(nodeModulesPath)) {
605
+ const size = getDirSize(nodeModulesPath);
606
+ results.push({
607
+ name: "node_modules/",
608
+ size,
609
+ sizeFormatted: formatBytes(size),
610
+ status: "ok",
611
+ recommendation: "Standard npm dependencies (informational)"
612
+ });
613
+ }
614
+ const orphanedWorktrees = getOrphanedWorktrees(cwd);
615
+ if (orphanedWorktrees.length > 0) {
616
+ results.push({
617
+ name: "Orphaned Worktrees",
618
+ size: orphanedWorktrees.length,
619
+ sizeFormatted: `${orphanedWorktrees.length} found`,
620
+ status: "warn",
621
+ recommendation: "Clean up with: archon cleanup run"
622
+ });
623
+ }
624
+ const cachePath = join3(cwd, CACHE_DIR);
625
+ if (existsSync3(cachePath)) {
626
+ const staleCache = await getStaleFiles(cachePath, 7);
627
+ if (staleCache.length > 0) {
628
+ const totalSize = staleCache.reduce((sum, f) => sum + f.size, 0);
629
+ results.push({
630
+ name: "Stale Cache Files",
631
+ size: totalSize,
632
+ sizeFormatted: `${staleCache.length} files (${formatBytes(totalSize)})`,
633
+ status: "warn",
634
+ recommendation: "Clean up with: archon cleanup run"
635
+ });
636
+ }
637
+ }
638
+ console.log(chalk3.bold("Workspace Analysis Summary\n"));
639
+ 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");
640
+ console.log("\u2502 Item \u2502 Size \u2502 Status \u2502");
641
+ 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");
642
+ for (const result of results) {
643
+ const statusIcon = result.status === "critical" ? chalk3.red("\u2717") : result.status === "warn" ? chalk3.yellow("!") : chalk3.green("\u2713");
644
+ const name = result.name.padEnd(23);
645
+ const size = result.sizeFormatted.padEnd(14);
646
+ console.log(`\u2502 ${name} \u2502 ${size} \u2502 ${statusIcon} \u2502`);
647
+ }
648
+ console.log("\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\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518");
649
+ console.log();
650
+ const recommendations = results.filter((r) => r.recommendation && r.status !== "ok");
651
+ if (recommendations.length > 0) {
652
+ console.log(chalk3.yellow("Recommendations:\n"));
653
+ for (const rec of recommendations) {
654
+ console.log(` ${chalk3.dim("\u2022")} ${rec.name}: ${rec.recommendation}`);
655
+ }
656
+ console.log();
657
+ } else {
658
+ console.log(chalk3.green("\u2713 Workspace is in good shape!\n"));
659
+ }
660
+ }
661
+ async function cleanupRun() {
662
+ const cwd = process.cwd();
663
+ const results = [];
664
+ let totalSaved = 0;
665
+ console.log(chalk3.blue("\n\u{1F9F9} Running workspace cleanup...\n"));
666
+ const progressPath = join3(cwd, PROGRESS_FILE);
667
+ if (existsSync3(progressPath)) {
668
+ const content = await readFile3(progressPath, "utf-8");
669
+ const entries = await parseProgressEntries(content);
670
+ const cutoffDate = /* @__PURE__ */ new Date();
671
+ cutoffDate.setDate(cutoffDate.getDate() - 30);
672
+ const oldEntries = entries.filter((e) => e.date < cutoffDate);
673
+ const recentEntries = entries.filter((e) => e.date >= cutoffDate);
674
+ if (oldEntries.length > 0) {
675
+ const archiveDir = join3(cwd, ARCHIVE_DIR);
676
+ if (!existsSync3(archiveDir)) {
677
+ await mkdir2(archiveDir, { recursive: true });
678
+ }
679
+ const archiveFileName = `progress-archive-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.txt`;
680
+ const archivePath = join3(archiveDir, archiveFileName);
681
+ const archiveContent = oldEntries.map((e) => e.content).join("\n\n---\n\n");
682
+ await writeFile3(archivePath, archiveContent, "utf-8");
683
+ const originalSize = statSync(progressPath).size;
684
+ const newContent = recentEntries.map((e) => e.content).join("\n\n");
685
+ await writeFile3(progressPath, newContent, "utf-8");
686
+ const newSize = statSync(progressPath).size;
687
+ const saved = originalSize - newSize;
688
+ results.push({
689
+ name: "progress.txt",
690
+ action: `Archived ${oldEntries.length} entries to ${archiveFileName}`,
691
+ spaceSaved: saved,
692
+ spaceSavedFormatted: formatBytes(saved)
693
+ });
694
+ totalSaved += saved;
695
+ }
696
+ }
697
+ const orphanedWorktrees = getOrphanedWorktrees(cwd);
698
+ for (const worktree of orphanedWorktrees) {
699
+ try {
700
+ execSync(`git worktree remove --force "${worktree}"`, {
701
+ cwd,
702
+ encoding: "utf-8"
703
+ });
704
+ results.push({
705
+ name: "Worktree",
706
+ action: `Removed orphaned worktree: ${worktree}`,
707
+ spaceSaved: 0,
708
+ spaceSavedFormatted: "N/A"
709
+ });
710
+ } catch {
711
+ console.log(chalk3.yellow(` Could not remove worktree: ${worktree}`));
712
+ }
713
+ }
714
+ const cachePath = join3(cwd, CACHE_DIR);
715
+ if (existsSync3(cachePath)) {
716
+ const staleCache = await getStaleFiles(cachePath, 7);
717
+ let cacheSaved = 0;
718
+ for (const file of staleCache) {
719
+ try {
720
+ await unlink(file.path);
721
+ cacheSaved += file.size;
722
+ } catch {
723
+ }
724
+ }
725
+ if (staleCache.length > 0) {
726
+ results.push({
727
+ name: "Cache",
728
+ action: `Removed ${staleCache.length} stale cache files`,
729
+ spaceSaved: cacheSaved,
730
+ spaceSavedFormatted: formatBytes(cacheSaved)
731
+ });
732
+ totalSaved += cacheSaved;
733
+ }
734
+ }
735
+ const cloudLogsPath = join3(cwd, ".archon", "cloud-logs");
736
+ if (existsSync3(cloudLogsPath)) {
737
+ const staleLogs = await getStaleFiles(cloudLogsPath, 30);
738
+ let logsSaved = 0;
739
+ for (const file of staleLogs) {
740
+ try {
741
+ await unlink(file.path);
742
+ logsSaved += file.size;
743
+ } catch {
744
+ }
745
+ }
746
+ if (staleLogs.length > 0) {
747
+ results.push({
748
+ name: "Cloud Logs",
749
+ action: `Removed ${staleLogs.length} stale log files`,
750
+ spaceSaved: logsSaved,
751
+ spaceSavedFormatted: formatBytes(logsSaved)
752
+ });
753
+ totalSaved += logsSaved;
754
+ }
755
+ }
756
+ if (results.length === 0) {
757
+ console.log(chalk3.green("\u2713 Nothing to clean up!\n"));
758
+ return;
759
+ }
760
+ console.log(chalk3.bold("Cleanup Results\n"));
761
+ for (const result of results) {
762
+ console.log(` ${chalk3.green("\u2713")} ${result.name}: ${result.action}`);
763
+ if (result.spaceSaved > 0) {
764
+ console.log(chalk3.dim(` Space saved: ${result.spaceSavedFormatted}`));
765
+ }
766
+ }
767
+ console.log();
768
+ console.log(chalk3.green(`\u2713 Total space saved: ${formatBytes(totalSaved)}
769
+ `));
770
+ }
771
+ async function cleanupAuto(action) {
772
+ const cwd = process.cwd();
773
+ const config = await loadCleanupConfig(cwd);
774
+ if (action === "status") {
775
+ const enabled = config?.autoEnabled ?? false;
776
+ console.log(chalk3.blue("\n\u{1F527} Auto Cleanup Settings\n"));
777
+ console.log(
778
+ ` Status: ${enabled ? chalk3.green("Enabled") : chalk3.dim("Disabled")}`
779
+ );
780
+ console.log(
781
+ chalk3.dim(
782
+ ` Progress archive threshold: ${config?.progressArchiveDays ?? 30} days`
783
+ )
784
+ );
785
+ console.log(
786
+ chalk3.dim(` Cache retention: ${config?.cacheRetentionDays ?? 7} days`)
787
+ );
788
+ console.log(
789
+ chalk3.dim(
790
+ ` Cloud log retention: ${config?.cloudLogRetentionDays ?? 30} days`
791
+ )
792
+ );
793
+ console.log();
794
+ return;
795
+ }
796
+ const newConfig = {
797
+ autoEnabled: action === "enable",
798
+ progressArchiveDays: config?.progressArchiveDays ?? 30,
799
+ cacheRetentionDays: config?.cacheRetentionDays ?? 7,
800
+ cloudLogRetentionDays: config?.cloudLogRetentionDays ?? 30
801
+ };
802
+ await saveCleanupConfig(cwd, newConfig);
803
+ if (action === "enable") {
804
+ console.log(chalk3.green("\n\u2713 Auto cleanup enabled"));
805
+ console.log(
806
+ chalk3.dim(
807
+ ' Cleanup check will run on "archon start" and warn if action needed\n'
808
+ )
809
+ );
810
+ } else {
811
+ console.log(chalk3.green("\n\u2713 Auto cleanup disabled\n"));
812
+ }
813
+ }
814
+ async function shouldRunAutoCleanup(cwd) {
815
+ const config = await loadCleanupConfig(cwd);
816
+ return config?.autoEnabled ?? false;
817
+ }
818
+ async function runAutoCleanupCheck(cwd) {
819
+ const progressPath = join3(cwd, PROGRESS_FILE);
820
+ const archonPath = join3(cwd, ARCHON_DIR);
821
+ let needsAttention = false;
822
+ if (existsSync3(progressPath)) {
823
+ const size = statSync(progressPath).size;
824
+ if (size > 100 * 1024) {
825
+ needsAttention = true;
826
+ }
827
+ }
828
+ if (existsSync3(archonPath)) {
829
+ const size = getDirSize(archonPath);
830
+ if (size > 10 * 1024 * 1024) {
831
+ needsAttention = true;
832
+ }
833
+ }
834
+ const orphaned = getOrphanedWorktrees(cwd);
835
+ if (orphaned.length > 0) {
836
+ needsAttention = true;
837
+ }
838
+ return needsAttention;
839
+ }
840
+
408
841
  // src/cli/start.ts
409
842
  async function start() {
410
843
  const cwd = process.cwd();
411
- console.log(chalk3.blue("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
412
- console.log(chalk3.bold.white(" ArchonDev - AI-Powered Development Governance"));
413
- console.log(chalk3.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
844
+ console.log(chalk4.blue("\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
845
+ console.log(chalk4.bold.white(" ArchonDev - AI-Powered Development Governance"));
846
+ console.log(chalk4.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
414
847
  const contextManager = new ContextManager();
415
848
  const pendingAtomsData = await contextManager.getPendingAtomsData(cwd);
416
849
  if (pendingAtomsData && pendingAtomsData.atoms.length > 0) {
417
- console.log(chalk3.yellow("\u26A1 Previous session had pending atoms:\n"));
850
+ console.log(chalk4.yellow("\u26A1 Previous session had pending atoms:\n"));
418
851
  for (const atomId of pendingAtomsData.atoms) {
419
- console.log(chalk3.dim(` \u2022 ${atomId}`));
852
+ console.log(chalk4.dim(` \u2022 ${atomId}`));
420
853
  }
421
854
  console.log();
422
- console.log(chalk3.dim(` Saved at: ${pendingAtomsData.savedAt}`));
423
- console.log(chalk3.dim(` Context usage was: ${(pendingAtomsData.contextState.usagePercent * 100).toFixed(0)}%`));
855
+ console.log(chalk4.dim(` Saved at: ${pendingAtomsData.savedAt}`));
856
+ console.log(chalk4.dim(` Context usage was: ${(pendingAtomsData.contextState.usagePercent * 100).toFixed(0)}%`));
424
857
  console.log();
425
858
  const resume = await promptYesNo("Resume with these atoms?", true);
426
859
  if (resume) {
427
- console.log(chalk3.green("\n\u2713 Resuming with pending atoms...\n"));
860
+ console.log(chalk4.green("\n\u2713 Resuming with pending atoms...\n"));
428
861
  await contextManager.clearPendingAtoms(cwd);
429
862
  } else {
430
863
  const clear = await promptYesNo("Clear pending atoms?", false);
431
864
  if (clear) {
432
865
  await contextManager.clearPendingAtoms(cwd);
433
- console.log(chalk3.dim("Cleared pending atoms.\n"));
866
+ console.log(chalk4.dim("Cleared pending atoms.\n"));
434
867
  }
435
868
  }
436
869
  }
437
870
  const projectState = detectProjectState(cwd);
438
871
  const governanceStatus = await gatherGovernanceStatus(cwd);
439
872
  displayGovernanceBanner(governanceStatus);
873
+ if (await shouldRunAutoCleanup(cwd)) {
874
+ await runAutoCleanupCheck(cwd);
875
+ }
440
876
  switch (projectState.scenario) {
441
877
  case "NEW_PROJECT":
442
878
  await handleNewProject(cwd, projectState);
@@ -454,14 +890,14 @@ function detectProjectState(cwd) {
454
890
  const sourceExtensions = [".ts", ".tsx", ".js", ".jsx", ".py", ".go", ".rs", ".java", ".rb", ".php"];
455
891
  let hasSourceFiles = false;
456
892
  for (const dir of sourceDirs) {
457
- if (existsSync3(join3(cwd, dir))) {
893
+ if (existsSync4(join4(cwd, dir))) {
458
894
  hasSourceFiles = true;
459
895
  break;
460
896
  }
461
897
  }
462
898
  if (!hasSourceFiles) {
463
899
  try {
464
- const files = readdirSync(cwd);
900
+ const files = readdirSync2(cwd);
465
901
  hasSourceFiles = files.some(
466
902
  (f) => sourceExtensions.some((ext) => f.endsWith(ext))
467
903
  );
@@ -470,16 +906,16 @@ function detectProjectState(cwd) {
470
906
  }
471
907
  const projectMarkers = ["package.json", "Cargo.toml", "pyproject.toml", "go.mod", "pom.xml", "build.gradle"];
472
908
  if (!hasSourceFiles) {
473
- hasSourceFiles = projectMarkers.some((marker) => existsSync3(join3(cwd, marker)));
909
+ hasSourceFiles = projectMarkers.some((marker) => existsSync4(join4(cwd, marker)));
474
910
  }
475
- const hasArchitecture = existsSync3(join3(cwd, "ARCHITECTURE.md"));
476
- const hasProgress = existsSync3(join3(cwd, "progress.txt"));
477
- const hasReviewDb = existsSync3(join3(cwd, "docs", "code-review", "review-tasks.db"));
911
+ const hasArchitecture = existsSync4(join4(cwd, "ARCHITECTURE.md"));
912
+ const hasProgress = existsSync4(join4(cwd, "progress.txt"));
913
+ const hasReviewDb = existsSync4(join4(cwd, "docs", "code-review", "review-tasks.db"));
478
914
  let hasProgressEntries = false;
479
915
  let lastProgressEntry;
480
916
  if (hasProgress) {
481
917
  try {
482
- const progressContent = readFileSync(join3(cwd, "progress.txt"), "utf-8");
918
+ const progressContent = readFileSync(join4(cwd, "progress.txt"), "utf-8");
483
919
  const entries = progressContent.match(/^## \d{4}-\d{2}-\d{2}/gm);
484
920
  hasProgressEntries = entries !== null && entries.length > 0;
485
921
  if (hasProgressEntries) {
@@ -518,8 +954,8 @@ async function gatherGovernanceStatus(cwd) {
518
954
  dependencyRulesCount: 0,
519
955
  pendingAtomsCount: 0
520
956
  };
521
- const archPath = join3(cwd, "ARCHITECTURE.md");
522
- if (existsSync3(archPath)) {
957
+ const archPath = join4(cwd, "ARCHITECTURE.md");
958
+ if (existsSync4(archPath)) {
523
959
  const parser = new ArchitectureParser(archPath);
524
960
  const result = await parser.parse();
525
961
  if (result.success && result.schema) {
@@ -536,8 +972,8 @@ async function gatherGovernanceStatus(cwd) {
536
972
  status2.dependencyRulesCount = depResult.document.rules.length;
537
973
  }
538
974
  }
539
- const progressPath = join3(cwd, "progress.txt");
540
- if (existsSync3(progressPath)) {
975
+ const progressPath = join4(cwd, "progress.txt");
976
+ if (existsSync4(progressPath)) {
541
977
  try {
542
978
  const content = readFileSync(progressPath, "utf-8");
543
979
  const dateMatches = content.match(/^## (\d{4}-\d{2}-\d{2})/gm);
@@ -551,10 +987,10 @@ async function gatherGovernanceStatus(cwd) {
551
987
  } catch {
552
988
  }
553
989
  }
554
- const atomsDir = join3(cwd, ".archon", "atoms");
555
- if (existsSync3(atomsDir)) {
990
+ const atomsDir = join4(cwd, ".archon", "atoms");
991
+ if (existsSync4(atomsDir)) {
556
992
  try {
557
- const files = readdirSync(atomsDir);
993
+ const files = readdirSync2(atomsDir);
558
994
  status2.pendingAtomsCount = files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml")).length;
559
995
  } catch {
560
996
  }
@@ -562,35 +998,35 @@ async function gatherGovernanceStatus(cwd) {
562
998
  return status2;
563
999
  }
564
1000
  function displayGovernanceBanner(status2) {
565
- console.log(chalk3.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
566
- console.log(chalk3.bold.white(" ArchonDev Governance Active"));
567
- console.log(chalk3.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
1001
+ console.log(chalk4.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
1002
+ console.log(chalk4.bold.white(" ArchonDev Governance Active"));
1003
+ console.log(chalk4.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501"));
568
1004
  if (status2.hasArchitecture) {
569
- console.log(chalk3.green(" \u2713") + ` ARCHITECTURE.md loaded (${status2.posture} posture)`);
570
- console.log(chalk3.green(" \u2713") + ` ${status2.invariantsCount} invariants enforced`);
571
- console.log(chalk3.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths defined`);
1005
+ console.log(chalk4.green(" \u2713") + ` ARCHITECTURE.md loaded (${status2.posture} posture)`);
1006
+ console.log(chalk4.green(" \u2713") + ` ${status2.invariantsCount} invariants enforced`);
1007
+ console.log(chalk4.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths defined`);
572
1008
  } else {
573
- console.log(chalk3.yellow(" \u26A0") + " ARCHITECTURE.md not found - run " + chalk3.cyan("archon init"));
1009
+ console.log(chalk4.yellow(" \u26A0") + " ARCHITECTURE.md not found - run " + chalk4.cyan("archon init"));
574
1010
  }
575
- console.log(chalk3.green(" \u2713") + ` ${status2.dependencyRulesCount} dependency rules active`);
1011
+ console.log(chalk4.green(" \u2713") + ` ${status2.dependencyRulesCount} dependency rules active`);
576
1012
  if (status2.lastSessionDate) {
577
- console.log(chalk3.green(" \u2713") + ` Last session: ${status2.lastSessionDate}`);
1013
+ console.log(chalk4.green(" \u2713") + ` Last session: ${status2.lastSessionDate}`);
578
1014
  }
579
1015
  if (status2.pendingAtomsCount > 0) {
580
1016
  console.log();
581
- console.log(chalk3.cyan(` Pending: ${status2.pendingAtomsCount} atoms ready for execution`));
1017
+ console.log(chalk4.cyan(` Pending: ${status2.pendingAtomsCount} atoms ready for execution`));
582
1018
  }
583
- console.log(chalk3.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
1019
+ console.log(chalk4.blue("\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n"));
584
1020
  }
585
1021
  async function handleNewProject(cwd, state) {
586
- console.log(chalk3.yellow("\u{1F389}") + chalk3.bold(" Starting a new project? Great!\n"));
587
- console.log(chalk3.dim("I'll ask you a few quick questions to set things up right."));
588
- console.log(chalk3.dim("Answer as much or as little as you want \u2014 you can always refine later.\n"));
589
- console.log(chalk3.bold("What would you like to do?\n"));
590
- console.log(` ${chalk3.cyan("1")}) ${chalk3.bold("Start interview")} \u2014 I'll ask questions to understand your project`);
591
- console.log(` ${chalk3.cyan("2")}) ${chalk3.bold("Quick start")} \u2014 Just create basic governance files`);
592
- console.log(` ${chalk3.cyan("3")}) ${chalk3.bold("Import from template")} \u2014 Use a predefined project template`);
593
- console.log(` ${chalk3.cyan("q")}) ${chalk3.dim("Quit")}`);
1022
+ console.log(chalk4.yellow("\u{1F389}") + chalk4.bold(" Starting a new project? Great!\n"));
1023
+ console.log(chalk4.dim("I'll ask you a few quick questions to set things up right."));
1024
+ console.log(chalk4.dim("Answer as much or as little as you want \u2014 you can always refine later.\n"));
1025
+ console.log(chalk4.bold("What would you like to do?\n"));
1026
+ console.log(` ${chalk4.cyan("1")}) ${chalk4.bold("Start interview")} \u2014 I'll ask questions to understand your project`);
1027
+ console.log(` ${chalk4.cyan("2")}) ${chalk4.bold("Quick start")} \u2014 Just create basic governance files`);
1028
+ console.log(` ${chalk4.cyan("3")}) ${chalk4.bold("Import from template")} \u2014 Use a predefined project template`);
1029
+ console.log(` ${chalk4.cyan("q")}) ${chalk4.dim("Quit")}`);
594
1030
  console.log();
595
1031
  const choice = await prompt("Enter choice");
596
1032
  switch (choice.toLowerCase()) {
@@ -601,19 +1037,19 @@ async function handleNewProject(cwd, state) {
601
1037
  await quickStart(cwd);
602
1038
  break;
603
1039
  case "3":
604
- console.log(chalk3.yellow("\nTemplates coming soon! Using quick start for now.\n"));
1040
+ console.log(chalk4.yellow("\nTemplates coming soon! Using quick start for now.\n"));
605
1041
  await quickStart(cwd);
606
1042
  break;
607
1043
  case "q":
608
1044
  process.exit(0);
609
1045
  default:
610
- console.log(chalk3.yellow("Invalid choice. Please try again."));
1046
+ console.log(chalk4.yellow("Invalid choice. Please try again."));
611
1047
  await handleNewProject(cwd, state);
612
1048
  }
613
1049
  }
614
1050
  async function runNewProjectInterview(cwd) {
615
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Project Interview \u2501\u2501\u2501\n"));
616
- console.log(chalk3.bold("Phase 1: The Vision\n"));
1051
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Project Interview \u2501\u2501\u2501\n"));
1052
+ console.log(chalk4.bold("Phase 1: The Vision\n"));
617
1053
  const projectName = await prompt("What's the project name?");
618
1054
  const projectDescription = await prompt("In one sentence, what does this project do?");
619
1055
  const audience = await promptChoice("Who is it for?", [
@@ -626,7 +1062,7 @@ async function runNewProjectInterview(cwd) {
626
1062
  { key: "2", label: "\u{1F7E1} Intermediate \u2014 I've done similar work" },
627
1063
  { key: "3", label: "\u{1F534} Learning \u2014 This is new to me" }
628
1064
  ]);
629
- console.log(chalk3.bold("\nPhase 2: Tech Stack\n"));
1065
+ console.log(chalk4.bold("\nPhase 2: Tech Stack\n"));
630
1066
  const language = await promptChoice("Primary language/framework?", [
631
1067
  { key: "1", label: "TypeScript / JavaScript" },
632
1068
  { key: "2", label: "Python" },
@@ -640,10 +1076,10 @@ async function runNewProjectInterview(cwd) {
640
1076
  { key: "3", label: "Full-stack (both)" },
641
1077
  { key: "4", label: "Library/package" }
642
1078
  ]);
643
- console.log(chalk3.bold("\nPhase 3: Preferences ") + chalk3.dim("(press Enter to skip)\n"));
1079
+ console.log(chalk4.bold("\nPhase 3: Preferences ") + chalk4.dim("(press Enter to skip)\n"));
644
1080
  const protectedFiles = await prompt("Any files AI should NEVER modify without asking? (comma-separated)");
645
1081
  const noNoPatterns = await prompt('Anything AI should NEVER do? (e.g., "no console.log")');
646
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Generating Project Files \u2501\u2501\u2501\n"));
1082
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Generating Project Files \u2501\u2501\u2501\n"));
647
1083
  const { init: init2 } = await import("./init-7EWVBX6O.js");
648
1084
  await init2({ analyze: false, git: true });
649
1085
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
@@ -669,16 +1105,16 @@ ${noNoPatterns ? `- **Forbidden patterns:** ${noNoPatterns}` : "- No forbidden p
669
1105
  - .archon/config.yaml
670
1106
  - progress.txt
671
1107
  `;
672
- const progressPath = join3(cwd, "progress.txt");
673
- if (!existsSync3(progressPath)) {
1108
+ const progressPath = join4(cwd, "progress.txt");
1109
+ if (!existsSync4(progressPath)) {
674
1110
  const { writeFileSync } = await import("fs");
675
1111
  writeFileSync(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
676
1112
  }
677
1113
  appendFileSync(progressPath, progressEntry);
678
- console.log(chalk3.green("\n\u2713 Project initialized!\n"));
679
- console.log(chalk3.bold("Next steps:"));
680
- console.log(` 1. ${chalk3.cyan("Review")} ARCHITECTURE.md and customize if needed`);
681
- console.log(` 2. ${chalk3.cyan("Run")} ${chalk3.dim('archon plan "your first task"')} to create an atom`);
1114
+ console.log(chalk4.green("\n\u2713 Project initialized!\n"));
1115
+ console.log(chalk4.bold("Next steps:"));
1116
+ console.log(` 1. ${chalk4.cyan("Review")} ARCHITECTURE.md and customize if needed`);
1117
+ console.log(` 2. ${chalk4.cyan("Run")} ${chalk4.dim('archon plan "your first task"')} to create an atom`);
682
1118
  console.log();
683
1119
  const continueChoice = await promptYesNo("Would you like to plan your first task now?", true);
684
1120
  if (continueChoice) {
@@ -690,12 +1126,12 @@ ${noNoPatterns ? `- **Forbidden patterns:** ${noNoPatterns}` : "- No forbidden p
690
1126
  }
691
1127
  }
692
1128
  async function quickStart(cwd) {
693
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Quick Start \u2501\u2501\u2501\n"));
1129
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Quick Start \u2501\u2501\u2501\n"));
694
1130
  const { init: init2 } = await import("./init-7EWVBX6O.js");
695
1131
  await init2({ analyze: false, git: true });
696
1132
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
697
- const progressPath = join3(cwd, "progress.txt");
698
- if (!existsSync3(progressPath)) {
1133
+ const progressPath = join4(cwd, "progress.txt");
1134
+ if (!existsSync4(progressPath)) {
699
1135
  const { writeFileSync } = await import("fs");
700
1136
  writeFileSync(progressPath, `# ArchonDev Progress Log
701
1137
 
@@ -717,15 +1153,15 @@ This file tracks learnings and decisions across sessions.
717
1153
  await showMainMenu();
718
1154
  }
719
1155
  async function handleAdaptExisting(cwd, state) {
720
- console.log(chalk3.yellow("\u{1F4C1}") + chalk3.bold(" Existing project detected!\n"));
721
- console.log(chalk3.dim("I can analyze your codebase and adapt the governance files to match your structure."));
722
- console.log(chalk3.dim("This helps me understand your architecture without changing any code.\n"));
723
- console.log(chalk3.bold("What would you like to do?\n"));
724
- console.log(` ${chalk3.cyan("1")}) ${chalk3.bold("Analyze and adapt")} \u2014 I'll scan your project and update ARCHITECTURE.md`);
725
- console.log(` ${chalk3.cyan("2")}) ${chalk3.bold("Code review first")} \u2014 Review code for issues before setting up governance`);
726
- console.log(` ${chalk3.cyan("3")}) ${chalk3.bold("Manual setup")} \u2014 Keep template files, customize manually`);
727
- console.log(` ${chalk3.cyan("4")}) ${chalk3.bold("Just start working")} \u2014 Skip setup, use defaults`);
728
- console.log(` ${chalk3.cyan("q")}) ${chalk3.dim("Quit")}`);
1156
+ console.log(chalk4.yellow("\u{1F4C1}") + chalk4.bold(" Existing project detected!\n"));
1157
+ console.log(chalk4.dim("I can analyze your codebase and adapt the governance files to match your structure."));
1158
+ console.log(chalk4.dim("This helps me understand your architecture without changing any code.\n"));
1159
+ console.log(chalk4.bold("What would you like to do?\n"));
1160
+ console.log(` ${chalk4.cyan("1")}) ${chalk4.bold("Analyze and adapt")} \u2014 I'll scan your project and update ARCHITECTURE.md`);
1161
+ console.log(` ${chalk4.cyan("2")}) ${chalk4.bold("Code review first")} \u2014 Review code for issues before setting up governance`);
1162
+ console.log(` ${chalk4.cyan("3")}) ${chalk4.bold("Manual setup")} \u2014 Keep template files, customize manually`);
1163
+ console.log(` ${chalk4.cyan("4")}) ${chalk4.bold("Just start working")} \u2014 Skip setup, use defaults`);
1164
+ console.log(` ${chalk4.cyan("q")}) ${chalk4.dim("Quit")}`);
729
1165
  console.log();
730
1166
  const choice = await prompt("Enter choice");
731
1167
  switch (choice.toLowerCase()) {
@@ -744,17 +1180,17 @@ async function handleAdaptExisting(cwd, state) {
744
1180
  case "q":
745
1181
  process.exit(0);
746
1182
  default:
747
- console.log(chalk3.yellow("Invalid choice. Please try again."));
1183
+ console.log(chalk4.yellow("Invalid choice. Please try again."));
748
1184
  await handleAdaptExisting(cwd, state);
749
1185
  }
750
1186
  }
751
1187
  async function analyzeAndAdapt(cwd) {
752
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Analyzing Project \u2501\u2501\u2501\n"));
1188
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Analyzing Project \u2501\u2501\u2501\n"));
753
1189
  const { init: init2 } = await import("./init-7EWVBX6O.js");
754
1190
  await init2({ analyze: true, git: true });
755
1191
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
756
- const progressPath = join3(cwd, "progress.txt");
757
- if (!existsSync3(progressPath)) {
1192
+ const progressPath = join4(cwd, "progress.txt");
1193
+ if (!existsSync4(progressPath)) {
758
1194
  const { writeFileSync } = await import("fs");
759
1195
  writeFileSync(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
760
1196
  }
@@ -771,15 +1207,15 @@ async function analyzeAndAdapt(cwd) {
771
1207
  - .archon/config.yaml - Build commands configured
772
1208
  - progress.txt - This file
773
1209
  `);
774
- console.log(chalk3.green("\n\u2713 Governance files adapted!\n"));
1210
+ console.log(chalk4.green("\n\u2713 Governance files adapted!\n"));
775
1211
  await showMainMenu();
776
1212
  }
777
1213
  async function codeReviewFirst(cwd) {
778
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Code Review Mode \u2501\u2501\u2501\n"));
779
- console.log(chalk3.dim("I'll analyze your code for issues without making any changes.\n"));
1214
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Code Review Mode \u2501\u2501\u2501\n"));
1215
+ console.log(chalk4.dim("I'll analyze your code for issues without making any changes.\n"));
780
1216
  const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-3R6QXAXQ.js");
781
- const reviewDbPath = join3(cwd, "docs", "code-review", "review-tasks.db");
782
- if (!existsSync3(reviewDbPath)) {
1217
+ const reviewDbPath = join4(cwd, "docs", "code-review", "review-tasks.db");
1218
+ if (!existsSync4(reviewDbPath)) {
783
1219
  await reviewInit2();
784
1220
  }
785
1221
  await reviewAnalyze2();
@@ -787,27 +1223,27 @@ async function codeReviewFirst(cwd) {
787
1223
  if (runReview) {
788
1224
  await reviewRun2({ all: true });
789
1225
  }
790
- console.log(chalk3.dim("\nAfter reviewing, you can run ") + chalk3.cyan("archon") + chalk3.dim(" again to set up governance.\n"));
1226
+ console.log(chalk4.dim("\nAfter reviewing, you can run ") + chalk4.cyan("archon") + chalk4.dim(" again to set up governance.\n"));
791
1227
  }
792
1228
  async function manualSetup(cwd) {
793
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Manual Setup \u2501\u2501\u2501\n"));
794
- console.log(chalk3.dim("Creating template files. You can customize them manually.\n"));
1229
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Manual Setup \u2501\u2501\u2501\n"));
1230
+ console.log(chalk4.dim("Creating template files. You can customize them manually.\n"));
795
1231
  const { init: init2 } = await import("./init-7EWVBX6O.js");
796
1232
  await init2({ analyze: false, git: true });
797
- console.log(chalk3.bold("\nWhat to customize:\n"));
798
- console.log(` ${chalk3.cyan("1. ARCHITECTURE.md")} \u2014 Update components to match your folders`);
799
- console.log(` ${chalk3.cyan("2. .archon/config.yaml")} \u2014 Change build/test/lint commands`);
800
- console.log(` ${chalk3.cyan("3. progress.txt")} \u2014 Add project-specific patterns`);
1233
+ console.log(chalk4.bold("\nWhat to customize:\n"));
1234
+ console.log(` ${chalk4.cyan("1. ARCHITECTURE.md")} \u2014 Update components to match your folders`);
1235
+ console.log(` ${chalk4.cyan("2. .archon/config.yaml")} \u2014 Change build/test/lint commands`);
1236
+ console.log(` ${chalk4.cyan("3. progress.txt")} \u2014 Add project-specific patterns`);
801
1237
  console.log();
802
1238
  await showMainMenu();
803
1239
  }
804
1240
  async function quickAdapt(cwd) {
805
- console.log(chalk3.blue("\n\u26A1 Using defaults \u2014 let's go!\n"));
1241
+ console.log(chalk4.blue("\n\u26A1 Using defaults \u2014 let's go!\n"));
806
1242
  const { init: init2 } = await import("./init-7EWVBX6O.js");
807
1243
  await init2({ analyze: true, git: true });
808
1244
  const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
809
- const progressPath = join3(cwd, "progress.txt");
810
- if (!existsSync3(progressPath)) {
1245
+ const progressPath = join4(cwd, "progress.txt");
1246
+ if (!existsSync4(progressPath)) {
811
1247
  const { writeFileSync } = await import("fs");
812
1248
  writeFileSync(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
813
1249
  }
@@ -821,20 +1257,20 @@ async function quickAdapt(cwd) {
821
1257
  await showMainMenu();
822
1258
  }
823
1259
  async function handleContinueSession(cwd, state) {
824
- console.log(chalk3.green("\u{1F44B}") + chalk3.bold(" Welcome back!\n"));
1260
+ console.log(chalk4.green("\u{1F44B}") + chalk4.bold(" Welcome back!\n"));
825
1261
  if (state.lastProgressEntry) {
826
- console.log(chalk3.dim("Last activity:"));
827
- console.log(chalk3.dim(" " + state.lastProgressEntry.split("\n")[0]));
1262
+ console.log(chalk4.dim("Last activity:"));
1263
+ console.log(chalk4.dim(" " + state.lastProgressEntry.split("\n")[0]));
828
1264
  console.log();
829
1265
  }
830
1266
  const handoff = checkForHandoff(cwd);
831
1267
  if (handoff) {
832
- console.log(chalk3.yellow("\u{1F4CB} Found handoff from last session:\n"));
833
- console.log(chalk3.dim(handoff.nextSteps));
1268
+ console.log(chalk4.yellow("\u{1F4CB} Found handoff from last session:\n"));
1269
+ console.log(chalk4.dim(handoff.nextSteps));
834
1270
  console.log();
835
1271
  const continueHandoff = await promptYesNo("Continue from handoff?", true);
836
1272
  if (continueHandoff) {
837
- console.log(chalk3.dim("\nPicking up where you left off...\n"));
1273
+ console.log(chalk4.dim("\nPicking up where you left off...\n"));
838
1274
  }
839
1275
  }
840
1276
  if (state.hasReviewDb) {
@@ -844,8 +1280,8 @@ async function handleContinueSession(cwd, state) {
844
1280
  }
845
1281
  function checkForHandoff(cwd) {
846
1282
  try {
847
- const progressPath = join3(cwd, "progress.txt");
848
- if (!existsSync3(progressPath)) return null;
1283
+ const progressPath = join4(cwd, "progress.txt");
1284
+ if (!existsSync4(progressPath)) return null;
849
1285
  const content = readFileSync(progressPath, "utf-8");
850
1286
  const handoffMatch = content.match(/## Context Handoff[^\n]*\n([\s\S]*?)(?=\n## |\n*$)/);
851
1287
  if (handoffMatch && handoffMatch[1]) {
@@ -862,7 +1298,7 @@ function checkForHandoff(cwd) {
862
1298
  async function showMainMenu() {
863
1299
  const cwd = process.cwd();
864
1300
  const state = detectProjectState(cwd);
865
- console.log(chalk3.bold("What would you like to do?\n"));
1301
+ console.log(chalk4.bold("What would you like to do?\n"));
866
1302
  const choices = [
867
1303
  { key: "1", label: "Plan a new task", action: () => planTask() },
868
1304
  { key: "2", label: "List atoms", action: () => listAtoms() },
@@ -874,7 +1310,7 @@ async function showMainMenu() {
874
1310
  { key: "q", label: "Quit", action: async () => process.exit(0) }
875
1311
  ];
876
1312
  for (const choice2 of choices) {
877
- console.log(` ${chalk3.cyan(choice2.key)}) ${choice2.label}`);
1313
+ console.log(` ${chalk4.cyan(choice2.key)}) ${choice2.label}`);
878
1314
  }
879
1315
  console.log();
880
1316
  const selected = await prompt("Enter choice");
@@ -882,7 +1318,7 @@ async function showMainMenu() {
882
1318
  if (choice) {
883
1319
  await choice.action();
884
1320
  } else {
885
- console.log(chalk3.yellow("Invalid choice. Please try again."));
1321
+ console.log(chalk4.yellow("Invalid choice. Please try again."));
886
1322
  await showMainMenu();
887
1323
  }
888
1324
  }
@@ -898,7 +1334,7 @@ async function showReviewProgress(cwd) {
898
1334
  const pending = stats.pending + stats.inReview;
899
1335
  const needsFix = stats.needsFix;
900
1336
  console.log(
901
- chalk3.blue("\u{1F4CA} Review Progress:") + chalk3.dim(` ${completed}/${total} completed`) + (needsFix > 0 ? chalk3.red(` (${needsFix} need fixes)`) : "") + (pending > 0 ? chalk3.yellow(` (${pending} pending)`) : "")
1337
+ chalk4.blue("\u{1F4CA} Review Progress:") + chalk4.dim(` ${completed}/${total} completed`) + (needsFix > 0 ? chalk4.red(` (${needsFix} need fixes)`) : "") + (pending > 0 ? chalk4.yellow(` (${pending} pending)`) : "")
902
1338
  );
903
1339
  console.log();
904
1340
  } catch {
@@ -923,38 +1359,38 @@ async function executeNext() {
923
1359
  const atoms = await listLocalAtoms2();
924
1360
  const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
925
1361
  if (pendingAtoms.length === 0) {
926
- console.log(chalk3.yellow('No pending atoms. Use "archon plan" to create one.'));
1362
+ console.log(chalk4.yellow('No pending atoms. Use "archon plan" to create one.'));
927
1363
  return;
928
1364
  }
929
1365
  if (pendingAtoms.length > 1) {
930
1366
  const analysis = analyzeProject(pendingAtoms);
931
1367
  const prefs = await loadExecutionPreferences(cwd);
932
- console.log(chalk3.blue("\n\u2501\u2501\u2501 Project Analysis \u2501\u2501\u2501\n"));
933
- console.log(` ${chalk3.bold("Atoms:")} ${analysis.atomCount}`);
934
- console.log(` ${chalk3.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
935
- console.log(` ${chalk3.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
936
- console.log(` ${chalk3.bold("Suggested:")} ${analysis.suggestedMode} - ${getModeDescription(analysis.suggestedMode)}`);
1368
+ console.log(chalk4.blue("\n\u2501\u2501\u2501 Project Analysis \u2501\u2501\u2501\n"));
1369
+ console.log(` ${chalk4.bold("Atoms:")} ${analysis.atomCount}`);
1370
+ console.log(` ${chalk4.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
1371
+ console.log(` ${chalk4.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
1372
+ console.log(` ${chalk4.bold("Suggested:")} ${analysis.suggestedMode} - ${getModeDescription(analysis.suggestedMode)}`);
937
1373
  console.log();
938
1374
  if (analysis.suggestedMode !== "sequential" && prefs.parallelMode === "ask") {
939
1375
  const useParallel = await promptYesNo(`Use ${analysis.suggestedMode} execution?`, true);
940
1376
  if (useParallel) {
941
- console.log(chalk3.green(`
1377
+ console.log(chalk4.green(`
942
1378
  \u2713 ${analysis.suggestedMode} execution selected`));
943
- console.log(chalk3.dim("(Parallel/cloud execution coming soon - running sequentially for now)\n"));
1379
+ console.log(chalk4.dim("(Parallel/cloud execution coming soon - running sequentially for now)\n"));
944
1380
  }
945
1381
  } else if (prefs.parallelMode === "always" && analysis.suggestedMode !== "sequential") {
946
- console.log(chalk3.green(`
1382
+ console.log(chalk4.green(`
947
1383
  \u2713 Auto-selected ${analysis.suggestedMode} execution (preference: always)`));
948
- console.log(chalk3.dim("(Parallel/cloud execution coming soon - running sequentially for now)\n"));
1384
+ console.log(chalk4.dim("(Parallel/cloud execution coming soon - running sequentially for now)\n"));
949
1385
  }
950
1386
  }
951
1387
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
952
1388
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
953
1389
  if (targetId) {
954
- const { execute: execute2 } = await import("./execute-IMGKMUBS.js");
1390
+ const { execute: execute2 } = await import("./execute-2S2UHTLN.js");
955
1391
  await execute2(targetId, {});
956
1392
  } else {
957
- console.log(chalk3.yellow("No atom to execute."));
1393
+ console.log(chalk4.yellow("No atom to execute."));
958
1394
  }
959
1395
  }
960
1396
  async function reportBug() {
@@ -975,20 +1411,20 @@ async function settingsMenu() {
975
1411
  }
976
1412
  async function reviewCode() {
977
1413
  const cwd = process.cwd();
978
- const reviewDbPath = join3(cwd, "docs", "code-review", "review-tasks.db");
979
- if (!existsSync3(reviewDbPath)) {
980
- console.log(chalk3.dim("Code review not initialized. Starting setup...\n"));
1414
+ const reviewDbPath = join4(cwd, "docs", "code-review", "review-tasks.db");
1415
+ if (!existsSync4(reviewDbPath)) {
1416
+ console.log(chalk4.dim("Code review not initialized. Starting setup...\n"));
981
1417
  const { reviewInit: reviewInit2 } = await import("./review-3R6QXAXQ.js");
982
1418
  await reviewInit2();
983
1419
  console.log();
984
1420
  }
985
- console.log(chalk3.bold("\nCode Review Options:\n"));
986
- console.log(` ${chalk3.cyan("1")}) Analyze project`);
987
- console.log(` ${chalk3.cyan("2")}) Show review status`);
988
- console.log(` ${chalk3.cyan("3")}) Review next file`);
989
- console.log(` ${chalk3.cyan("4")}) List all tasks`);
990
- console.log(` ${chalk3.cyan("5")}) Run AI review on all pending`);
991
- console.log(` ${chalk3.cyan("b")}) Back to main menu`);
1421
+ console.log(chalk4.bold("\nCode Review Options:\n"));
1422
+ console.log(` ${chalk4.cyan("1")}) Analyze project`);
1423
+ console.log(` ${chalk4.cyan("2")}) Show review status`);
1424
+ console.log(` ${chalk4.cyan("3")}) Review next file`);
1425
+ console.log(` ${chalk4.cyan("4")}) List all tasks`);
1426
+ console.log(` ${chalk4.cyan("5")}) Run AI review on all pending`);
1427
+ console.log(` ${chalk4.cyan("b")}) Back to main menu`);
992
1428
  console.log();
993
1429
  const choice = await prompt("Enter choice");
994
1430
  switch (choice.toLowerCase()) {
@@ -1021,7 +1457,7 @@ async function reviewCode() {
1021
1457
  await showMainMenu();
1022
1458
  return;
1023
1459
  default:
1024
- console.log(chalk3.yellow("Invalid choice."));
1460
+ console.log(chalk4.yellow("Invalid choice."));
1025
1461
  }
1026
1462
  await reviewCode();
1027
1463
  }
@@ -1031,7 +1467,7 @@ function prompt(question) {
1031
1467
  input: process.stdin,
1032
1468
  output: process.stdout
1033
1469
  });
1034
- rl.question(`${chalk3.cyan("?")} ${question}: `, (answer) => {
1470
+ rl.question(`${chalk4.cyan("?")} ${question}: `, (answer) => {
1035
1471
  rl.close();
1036
1472
  resolve(answer);
1037
1473
  });
@@ -1044,7 +1480,7 @@ function promptYesNo(question, defaultValue) {
1044
1480
  output: process.stdout
1045
1481
  });
1046
1482
  const hint = defaultValue ? "(Y/n)" : "(y/N)";
1047
- rl.question(`${chalk3.cyan("?")} ${question} ${hint}: `, (answer) => {
1483
+ rl.question(`${chalk4.cyan("?")} ${question} ${hint}: `, (answer) => {
1048
1484
  rl.close();
1049
1485
  if (answer.trim() === "") {
1050
1486
  resolve(defaultValue);
@@ -1056,15 +1492,15 @@ function promptYesNo(question, defaultValue) {
1056
1492
  }
1057
1493
  function promptChoice(question, options) {
1058
1494
  return new Promise((resolve) => {
1059
- console.log(`${chalk3.cyan("?")} ${question}`);
1495
+ console.log(`${chalk4.cyan("?")} ${question}`);
1060
1496
  for (const opt of options) {
1061
- console.log(` ${chalk3.dim(opt.key)}) ${opt.label}`);
1497
+ console.log(` ${chalk4.dim(opt.key)}) ${opt.label}`);
1062
1498
  }
1063
1499
  const rl = readline.createInterface({
1064
1500
  input: process.stdin,
1065
1501
  output: process.stdout
1066
1502
  });
1067
- rl.question(` ${chalk3.dim("Enter choice")}: `, (answer) => {
1503
+ rl.question(` ${chalk4.dim("Enter choice")}: `, (answer) => {
1068
1504
  rl.close();
1069
1505
  resolve(answer.trim() || "1");
1070
1506
  });
@@ -1072,7 +1508,7 @@ function promptChoice(question, options) {
1072
1508
  }
1073
1509
 
1074
1510
  // src/cli/credits.ts
1075
- import chalk4 from "chalk";
1511
+ import chalk5 from "chalk";
1076
1512
  import ora from "ora";
1077
1513
  import open from "open";
1078
1514
  import { createClient } from "@supabase/supabase-js";
@@ -1098,21 +1534,21 @@ async function showCredits() {
1098
1534
  const profile = data;
1099
1535
  spinner.stop();
1100
1536
  console.log();
1101
- console.log(chalk4.bold("\u{1F4B0} Credit Balance"));
1537
+ console.log(chalk5.bold("\u{1F4B0} Credit Balance"));
1102
1538
  console.log();
1103
1539
  const balance = (profile.credit_balance_cents || 0) / 100;
1104
1540
  console.log(` Tier: ${formatTier(profile.tier)}`);
1105
- console.log(` Balance: ${chalk4.green(`$${balance.toFixed(2)}`)}`);
1541
+ console.log(` Balance: ${chalk5.green(`$${balance.toFixed(2)}`)}`);
1106
1542
  if (profile.tier === "FREE") {
1107
1543
  console.log(` Atoms: ${profile.atoms_used_this_month}/10,000 this month`);
1108
1544
  console.log();
1109
- console.log(chalk4.dim(" Upgrade to Credits tier: archon credits add"));
1545
+ console.log(chalk5.dim(" Upgrade to Credits tier: archon credits add"));
1110
1546
  } else if (profile.tier === "CREDITS") {
1111
1547
  console.log();
1112
- console.log(chalk4.dim(" Add more credits: archon credits add"));
1548
+ console.log(chalk5.dim(" Add more credits: archon credits add"));
1113
1549
  } else if (profile.tier === "BYOK") {
1114
1550
  console.log();
1115
- console.log(chalk4.dim(" Using your own API keys - no credit charges"));
1551
+ console.log(chalk5.dim(" Using your own API keys - no credit charges"));
1116
1552
  }
1117
1553
  console.log();
1118
1554
  } catch (err) {
@@ -1158,18 +1594,18 @@ async function addCredits(options = {}) {
1158
1594
  }
1159
1595
  spinner.succeed("Checkout ready");
1160
1596
  console.log();
1161
- console.log(chalk4.bold("\u{1F6D2} Add Credits"));
1597
+ console.log(chalk5.bold("\u{1F6D2} Add Credits"));
1162
1598
  console.log();
1163
- console.log(` Amount: ${chalk4.green(`$${amountDollars.toFixed(2)}`)}`);
1599
+ console.log(` Amount: ${chalk5.green(`$${amountDollars.toFixed(2)}`)}`);
1164
1600
  console.log();
1165
1601
  console.log(" Opening checkout in browser...");
1166
1602
  console.log();
1167
- console.log(chalk4.dim(` Or visit: ${checkoutUrl}`));
1603
+ console.log(chalk5.dim(` Or visit: ${checkoutUrl}`));
1168
1604
  console.log();
1169
1605
  try {
1170
1606
  await open(checkoutUrl);
1171
1607
  } catch {
1172
- console.log(chalk4.yellow(" Could not open browser. Please visit the URL above."));
1608
+ console.log(chalk5.yellow(" Could not open browser. Please visit the URL above."));
1173
1609
  }
1174
1610
  } catch (err) {
1175
1611
  spinner.fail("Error preparing checkout");
@@ -1194,15 +1630,15 @@ async function showHistory(options = {}) {
1194
1630
  const usage = data;
1195
1631
  spinner.stop();
1196
1632
  console.log();
1197
- console.log(chalk4.bold("\u{1F4CA} Usage History"));
1633
+ console.log(chalk5.bold("\u{1F4CA} Usage History"));
1198
1634
  console.log();
1199
1635
  if (!usage || usage.length === 0) {
1200
- console.log(chalk4.dim(" No usage recorded yet."));
1636
+ console.log(chalk5.dim(" No usage recorded yet."));
1201
1637
  console.log();
1202
1638
  return;
1203
1639
  }
1204
- console.log(chalk4.dim(" Model Tokens Cost Date"));
1205
- console.log(chalk4.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"));
1640
+ console.log(chalk5.dim(" Model Tokens Cost Date"));
1641
+ console.log(chalk5.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"));
1206
1642
  for (const row of usage) {
1207
1643
  const model = row.model.padEnd(30).slice(0, 30);
1208
1644
  const tokens = (row.input_tokens + row.output_tokens).toString().padStart(8);
@@ -1212,9 +1648,9 @@ async function showHistory(options = {}) {
1212
1648
  }
1213
1649
  const totalCost = usage.reduce((sum, r) => sum + r.base_cost, 0);
1214
1650
  const totalTokens = usage.reduce((sum, r) => sum + r.input_tokens + r.output_tokens, 0);
1215
- console.log(chalk4.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"));
1651
+ console.log(chalk5.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"));
1216
1652
  console.log(
1217
- ` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${chalk4.green(`$${totalCost.toFixed(4)}`.padStart(10))}`
1653
+ ` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${chalk5.green(`$${totalCost.toFixed(4)}`.padStart(10))}`
1218
1654
  );
1219
1655
  console.log();
1220
1656
  } catch (err) {
@@ -1280,24 +1716,24 @@ async function manageBudget(options = {}) {
1280
1716
  }
1281
1717
  spinner.stop();
1282
1718
  console.log();
1283
- console.log(chalk4.bold("\u{1F4CA} Monthly Budget"));
1719
+ console.log(chalk5.bold("\u{1F4CA} Monthly Budget"));
1284
1720
  console.log();
1285
1721
  if (profile.monthly_budget_cents === null) {
1286
- console.log(` Budget: ${chalk4.dim("No limit set")}`);
1722
+ console.log(` Budget: ${chalk5.dim("No limit set")}`);
1287
1723
  } else {
1288
1724
  const budget = profile.monthly_budget_cents / 100;
1289
1725
  const spend = (profile.monthly_spend_cents || 0) / 100;
1290
1726
  const remaining = budget - spend;
1291
1727
  const percent = budget > 0 ? Math.round(spend / budget * 100) : 0;
1292
- console.log(` Budget: ${chalk4.green(`$${budget.toFixed(2)}`)} / month`);
1728
+ console.log(` Budget: ${chalk5.green(`$${budget.toFixed(2)}`)} / month`);
1293
1729
  console.log(` Spent: $${spend.toFixed(2)} (${percent}%)`);
1294
- console.log(` Remaining: ${remaining >= 0 ? chalk4.green(`$${remaining.toFixed(2)}`) : chalk4.red(`-$${Math.abs(remaining).toFixed(2)}`)}`);
1730
+ console.log(` Remaining: ${remaining >= 0 ? chalk5.green(`$${remaining.toFixed(2)}`) : chalk5.red(`-$${Math.abs(remaining).toFixed(2)}`)}`);
1295
1731
  }
1296
1732
  console.log(` Alert at: ${profile.budget_alert_threshold_percent}% of budget`);
1297
1733
  console.log();
1298
- console.log(chalk4.dim(" Set budget: archon credits budget --set 50"));
1299
- console.log(chalk4.dim(" Clear budget: archon credits budget --clear"));
1300
- console.log(chalk4.dim(" Set alert: archon credits budget --alert 80"));
1734
+ console.log(chalk5.dim(" Set budget: archon credits budget --set 50"));
1735
+ console.log(chalk5.dim(" Clear budget: archon credits budget --clear"));
1736
+ console.log(chalk5.dim(" Set alert: archon credits budget --alert 80"));
1301
1737
  console.log();
1302
1738
  } catch (err) {
1303
1739
  spinner.fail("Error managing budget");
@@ -1359,12 +1795,12 @@ async function manageAutoRecharge(options = {}) {
1359
1795
  }
1360
1796
  spinner.stop();
1361
1797
  console.log();
1362
- console.log(chalk4.bold("\u{1F504} Auto-Recharge"));
1798
+ console.log(chalk5.bold("\u{1F504} Auto-Recharge"));
1363
1799
  console.log();
1364
1800
  if (!profile.auto_recharge_enabled) {
1365
- console.log(` Status: ${chalk4.dim("Disabled")}`);
1801
+ console.log(` Status: ${chalk5.dim("Disabled")}`);
1366
1802
  } else {
1367
- console.log(` Status: ${chalk4.green("Enabled")}`);
1803
+ console.log(` Status: ${chalk5.green("Enabled")}`);
1368
1804
  if (profile.auto_recharge_threshold_cents !== null) {
1369
1805
  console.log(` When: Balance drops below $${(profile.auto_recharge_threshold_cents / 100).toFixed(2)}`);
1370
1806
  }
@@ -1372,10 +1808,10 @@ async function manageAutoRecharge(options = {}) {
1372
1808
  console.log(` Amount: $${(profile.auto_recharge_amount_cents / 100).toFixed(2)}`);
1373
1809
  }
1374
1810
  }
1375
- console.log(` Payment: ${profile.stripe_payment_method_id ? chalk4.green("Card saved") : chalk4.dim("No card saved")}`);
1811
+ console.log(` Payment: ${profile.stripe_payment_method_id ? chalk5.green("Card saved") : chalk5.dim("No card saved")}`);
1376
1812
  console.log();
1377
- console.log(chalk4.dim(" Enable: archon credits auto-recharge --enable --threshold 5 --amount 20"));
1378
- console.log(chalk4.dim(" Disable: archon credits auto-recharge --disable"));
1813
+ console.log(chalk5.dim(" Enable: archon credits auto-recharge --enable --threshold 5 --amount 20"));
1814
+ console.log(chalk5.dim(" Disable: archon credits auto-recharge --disable"));
1379
1815
  console.log();
1380
1816
  } catch (err) {
1381
1817
  spinner.fail("Error managing auto-recharge");
@@ -1385,11 +1821,11 @@ async function manageAutoRecharge(options = {}) {
1385
1821
  function formatTier(tier) {
1386
1822
  switch (tier) {
1387
1823
  case "FREE":
1388
- return chalk4.blue("Free (10k atoms/month)");
1824
+ return chalk5.blue("Free (10k atoms/month)");
1389
1825
  case "CREDITS":
1390
- return chalk4.green("Credits (Pay-as-you-go)");
1826
+ return chalk5.green("Credits (Pay-as-you-go)");
1391
1827
  case "BYOK":
1392
- return chalk4.magenta("BYOK (Bring Your Own Key)");
1828
+ return chalk5.magenta("BYOK (Bring Your Own Key)");
1393
1829
  default:
1394
1830
  return tier;
1395
1831
  }
@@ -1666,9 +2102,9 @@ async function watch() {
1666
2102
 
1667
2103
  // src/cli/deps.ts
1668
2104
  import { Command } from "commander";
1669
- import chalk5 from "chalk";
1670
- import { readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
1671
- import { existsSync as existsSync5 } from "fs";
2105
+ import chalk6 from "chalk";
2106
+ import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
2107
+ import { existsSync as existsSync6 } from "fs";
1672
2108
  var DEPENDENCIES_FILENAME = "DEPENDENCIES.md";
1673
2109
  function createDepsCommand() {
1674
2110
  const deps = new Command("deps").description("Manage file-level dependencies (DEPENDENCIES.md)").addHelpText(
@@ -1684,30 +2120,30 @@ Examples:
1684
2120
  deps.command("list").description("List all dependency rules").option("-v, --verbose", "Show detailed information").action(async (options) => {
1685
2121
  const parser = new DependencyParser();
1686
2122
  if (!parser.exists()) {
1687
- console.log(chalk5.yellow("No DEPENDENCIES.md found."));
1688
- console.log(chalk5.dim("Create one with: archon deps add --source <path> --dependent <path>"));
2123
+ console.log(chalk6.yellow("No DEPENDENCIES.md found."));
2124
+ console.log(chalk6.dim("Create one with: archon deps add --source <path> --dependent <path>"));
1689
2125
  return;
1690
2126
  }
1691
2127
  const result = await parser.parse();
1692
2128
  if (!result.success) {
1693
- console.log(chalk5.red(`Parse error: ${result.error}`));
2129
+ console.log(chalk6.red(`Parse error: ${result.error}`));
1694
2130
  return;
1695
2131
  }
1696
2132
  const rules = result.document?.rules ?? [];
1697
2133
  if (rules.length === 0) {
1698
- console.log(chalk5.dim("No dependency rules defined."));
2134
+ console.log(chalk6.dim("No dependency rules defined."));
1699
2135
  return;
1700
2136
  }
1701
- console.log(chalk5.bold(`
2137
+ console.log(chalk6.bold(`
1702
2138
  \u{1F4E6} Dependency Rules (${rules.length})
1703
2139
  `));
1704
2140
  for (const rule of rules) {
1705
- const severityColor = rule.severity === "BLOCKER" ? chalk5.red : rule.severity === "WARNING" ? chalk5.yellow : chalk5.blue;
1706
- console.log(`${severityColor(`[${rule.severity}]`)} ${chalk5.bold(rule.id)}`);
1707
- console.log(` Source: ${chalk5.cyan(rule.source)}`);
1708
- console.log(` Dependents: ${rule.dependents.map((d) => chalk5.dim(d)).join(", ")}`);
2141
+ const severityColor = rule.severity === "BLOCKER" ? chalk6.red : rule.severity === "WARNING" ? chalk6.yellow : chalk6.blue;
2142
+ console.log(`${severityColor(`[${rule.severity}]`)} ${chalk6.bold(rule.id)}`);
2143
+ console.log(` Source: ${chalk6.cyan(rule.source)}`);
2144
+ console.log(` Dependents: ${rule.dependents.map((d) => chalk6.dim(d)).join(", ")}`);
1709
2145
  if (rule.reason && options.verbose) {
1710
- console.log(` Reason: ${chalk5.dim(rule.reason)}`);
2146
+ console.log(` Reason: ${chalk6.dim(rule.reason)}`);
1711
2147
  }
1712
2148
  if (rule.mustTest && options.verbose) {
1713
2149
  console.log(` Must test: ${rule.mustTest.join(", ")}`);
@@ -1719,29 +2155,29 @@ Examples:
1719
2155
  const files = options.files.split(",").map((f) => f.trim());
1720
2156
  const parser = new DependencyParser();
1721
2157
  if (!parser.exists()) {
1722
- console.log(chalk5.dim("No DEPENDENCIES.md found. No dependency checks performed."));
2158
+ console.log(chalk6.dim("No DEPENDENCIES.md found. No dependency checks performed."));
1723
2159
  process.exit(0);
1724
2160
  }
1725
2161
  const result = await parser.checkFiles(files);
1726
2162
  if (result.impacts.length === 0) {
1727
- console.log(chalk5.green("\u2705 No downstream dependency impacts found."));
2163
+ console.log(chalk6.green("\u2705 No downstream dependency impacts found."));
1728
2164
  process.exit(0);
1729
2165
  }
1730
- console.log(chalk5.yellow(`
2166
+ console.log(chalk6.yellow(`
1731
2167
  \u26A0\uFE0F Found ${result.impacts.length} dependency impact(s):
1732
2168
  `));
1733
2169
  for (const impact of result.impacts) {
1734
- const severityColor = impact.rule.severity === "BLOCKER" ? chalk5.red : impact.rule.severity === "WARNING" ? chalk5.yellow : chalk5.blue;
2170
+ const severityColor = impact.rule.severity === "BLOCKER" ? chalk6.red : impact.rule.severity === "WARNING" ? chalk6.yellow : chalk6.blue;
1735
2171
  console.log(severityColor(`[${impact.rule.severity}] ${impact.rule.id}`));
1736
- console.log(` Changing: ${chalk5.cyan(impact.matchedSource)}`);
2172
+ console.log(` Changing: ${chalk6.cyan(impact.matchedSource)}`);
1737
2173
  console.log(` May impact: ${impact.affectedDependents.join(", ")}`);
1738
2174
  if (impact.rule.reason) {
1739
- console.log(` Reason: ${chalk5.dim(impact.rule.reason)}`);
2175
+ console.log(` Reason: ${chalk6.dim(impact.rule.reason)}`);
1740
2176
  }
1741
2177
  console.log("");
1742
2178
  }
1743
2179
  if (result.hasBlockers) {
1744
- console.log(chalk5.red("\u274C BLOCKER-level impacts found. Review before proceeding."));
2180
+ console.log(chalk6.red("\u274C BLOCKER-level impacts found. Review before proceeding."));
1745
2181
  process.exit(1);
1746
2182
  }
1747
2183
  process.exit(0);
@@ -1755,7 +2191,7 @@ Examples:
1755
2191
  let existingRules = [];
1756
2192
  let markdownBody = "";
1757
2193
  if (parser.exists()) {
1758
- const content = await readFile3(DEPENDENCIES_FILENAME, "utf-8");
2194
+ const content = await readFile4(DEPENDENCIES_FILENAME, "utf-8");
1759
2195
  const result = await parser.parse();
1760
2196
  if (result.success && result.document) {
1761
2197
  existingRules = result.document.rules;
@@ -1783,7 +2219,7 @@ Examples:
1783
2219
  (r) => r.source === source && r.dependents.includes(dependent)
1784
2220
  );
1785
2221
  if (existingRule) {
1786
- console.log(chalk5.yellow(`Rule already exists: ${existingRule.id}`));
2222
+ console.log(chalk6.yellow(`Rule already exists: ${existingRule.id}`));
1787
2223
  return;
1788
2224
  }
1789
2225
  const newRule = {
@@ -1794,23 +2230,23 @@ Examples:
1794
2230
  reason
1795
2231
  };
1796
2232
  existingRules.push(newRule);
1797
- const yaml2 = generateYamlFrontmatter(existingRules);
1798
- await writeFile3(DEPENDENCIES_FILENAME, `---
1799
- ${yaml2}---${markdownBody}`, "utf-8");
1800
- console.log(chalk5.green(`\u2705 Added dependency rule: ${nextId}`));
1801
- console.log(` Source: ${chalk5.cyan(source)}`);
1802
- console.log(` Dependent: ${chalk5.dim(dependent)}`);
2233
+ const yaml3 = generateYamlFrontmatter(existingRules);
2234
+ await writeFile4(DEPENDENCIES_FILENAME, `---
2235
+ ${yaml3}---${markdownBody}`, "utf-8");
2236
+ console.log(chalk6.green(`\u2705 Added dependency rule: ${nextId}`));
2237
+ console.log(` Source: ${chalk6.cyan(source)}`);
2238
+ console.log(` Dependent: ${chalk6.dim(dependent)}`);
1803
2239
  });
1804
2240
  deps.command("graph").description("Generate Mermaid diagram of dependencies").option("--output <file>", "Write to file instead of stdout").action(async (options) => {
1805
2241
  const parser = new DependencyParser();
1806
2242
  if (!parser.exists()) {
1807
- console.log(chalk5.yellow("No DEPENDENCIES.md found."));
2243
+ console.log(chalk6.yellow("No DEPENDENCIES.md found."));
1808
2244
  return;
1809
2245
  }
1810
2246
  const mermaid = await parser.generateGraph();
1811
2247
  if (options.output) {
1812
- await writeFile3(options.output, mermaid, "utf-8");
1813
- console.log(chalk5.green(`\u2705 Graph written to ${options.output}`));
2248
+ await writeFile4(options.output, mermaid, "utf-8");
2249
+ console.log(chalk6.green(`\u2705 Graph written to ${options.output}`));
1814
2250
  } else {
1815
2251
  console.log("\n```mermaid");
1816
2252
  console.log(mermaid);
@@ -1818,8 +2254,8 @@ ${yaml2}---${markdownBody}`, "utf-8");
1818
2254
  }
1819
2255
  });
1820
2256
  deps.command("init").description("Create a starter DEPENDENCIES.md file").action(async () => {
1821
- if (existsSync5(DEPENDENCIES_FILENAME)) {
1822
- console.log(chalk5.yellow("DEPENDENCIES.md already exists."));
2257
+ if (existsSync6(DEPENDENCIES_FILENAME)) {
2258
+ console.log(chalk6.yellow("DEPENDENCIES.md already exists."));
1823
2259
  return;
1824
2260
  }
1825
2261
  const template = `---
@@ -1865,9 +2301,9 @@ rules:
1865
2301
 
1866
2302
  *Powered by [ArchonDev](https://archondev.io)*
1867
2303
  `;
1868
- await writeFile3(DEPENDENCIES_FILENAME, template, "utf-8");
1869
- console.log(chalk5.green("\u2705 Created DEPENDENCIES.md"));
1870
- console.log(chalk5.dim("Add your first rule with: archon deps add --source <path> --dependent <path>"));
2304
+ await writeFile4(DEPENDENCIES_FILENAME, template, "utf-8");
2305
+ console.log(chalk6.green("\u2705 Created DEPENDENCIES.md"));
2306
+ console.log(chalk6.dim("Add your first rule with: archon deps add --source <path> --dependent <path>"));
1871
2307
  });
1872
2308
  return deps;
1873
2309
  }
@@ -1904,10 +2340,10 @@ function generateYamlFrontmatter(rules) {
1904
2340
  }
1905
2341
 
1906
2342
  // src/cli/a11y.ts
1907
- import chalk6 from "chalk";
1908
- import { existsSync as existsSync6 } from "fs";
1909
- import { readFile as readFile4, writeFile as writeFile4, mkdir as mkdir2 } from "fs/promises";
1910
- import { join as join5 } from "path";
2343
+ import chalk7 from "chalk";
2344
+ import { existsSync as existsSync7 } from "fs";
2345
+ import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir3 } from "fs/promises";
2346
+ import { join as join6 } from "path";
1911
2347
  import { createInterface } from "readline";
1912
2348
  import { glob } from "glob";
1913
2349
  var ACCESSIBILITY_CHECKS = {
@@ -1980,7 +2416,7 @@ async function scanForIssues(files) {
1980
2416
  const issues = [];
1981
2417
  for (const file of files) {
1982
2418
  try {
1983
- const content = await readFile4(file, "utf-8");
2419
+ const content = await readFile5(file, "utf-8");
1984
2420
  const lines = content.split("\n");
1985
2421
  for (const [checkId, check] of Object.entries(ACCESSIBILITY_CHECKS)) {
1986
2422
  for (const pattern of check.patterns) {
@@ -2007,8 +2443,8 @@ async function scanForIssues(files) {
2007
2443
  return issues;
2008
2444
  }
2009
2445
  async function a11yCheck(options) {
2010
- console.log(chalk6.blue("\n\u267F Pre-Deploy Accessibility Check\n"));
2011
- console.log(chalk6.dim("Scanning for WCAG 2.2 AA compliance issues...\n"));
2446
+ console.log(chalk7.blue("\n\u267F Pre-Deploy Accessibility Check\n"));
2447
+ console.log(chalk7.dim("Scanning for WCAG 2.2 AA compliance issues...\n"));
2012
2448
  const patterns = [
2013
2449
  "**/*.html",
2014
2450
  "**/*.htm",
@@ -2022,13 +2458,13 @@ async function a11yCheck(options) {
2022
2458
  let allFiles = [];
2023
2459
  for (const pattern of patterns) {
2024
2460
  const files = await glob(pattern, { cwd: process.cwd(), ignore: ignorePatterns });
2025
- allFiles = allFiles.concat(files.map((f) => join5(process.cwd(), f)));
2461
+ allFiles = allFiles.concat(files.map((f) => join6(process.cwd(), f)));
2026
2462
  }
2027
2463
  if (allFiles.length === 0) {
2028
- console.log(chalk6.yellow("No web files found to check."));
2464
+ console.log(chalk7.yellow("No web files found to check."));
2029
2465
  return;
2030
2466
  }
2031
- console.log(chalk6.dim(`Scanning ${allFiles.length} files...
2467
+ console.log(chalk7.dim(`Scanning ${allFiles.length} files...
2032
2468
  `));
2033
2469
  const issues = await scanForIssues(allFiles);
2034
2470
  const report = {
@@ -2038,28 +2474,28 @@ async function a11yCheck(options) {
2038
2474
  issues,
2039
2475
  passed: issues.length === 0
2040
2476
  };
2041
- const archonDir = join5(process.cwd(), ".archon");
2042
- if (!existsSync6(archonDir)) {
2043
- await mkdir2(archonDir, { recursive: true });
2477
+ const archonDir = join6(process.cwd(), ".archon");
2478
+ if (!existsSync7(archonDir)) {
2479
+ await mkdir3(archonDir, { recursive: true });
2044
2480
  }
2045
- await writeFile4(join5(archonDir, "a11y-report.json"), JSON.stringify(report, null, 2));
2481
+ await writeFile5(join6(archonDir, "a11y-report.json"), JSON.stringify(report, null, 2));
2046
2482
  if (issues.length === 0) {
2047
- console.log(chalk6.green("\u2705 Accessibility Audit Passed\n"));
2048
- console.log(chalk6.dim("Your site meets WCAG 2.2 AA requirements based on static analysis."));
2049
- console.log(chalk6.dim("Note: Run manual testing with screen readers for full compliance.\n"));
2483
+ console.log(chalk7.green("\u2705 Accessibility Audit Passed\n"));
2484
+ console.log(chalk7.dim("Your site meets WCAG 2.2 AA requirements based on static analysis."));
2485
+ console.log(chalk7.dim("Note: Run manual testing with screen readers for full compliance.\n"));
2050
2486
  return;
2051
2487
  }
2052
- console.log(chalk6.red(`\u26A0\uFE0F ${issues.length} Accessibility Issues Found
2488
+ console.log(chalk7.red(`\u26A0\uFE0F ${issues.length} Accessibility Issues Found
2053
2489
  `));
2054
2490
  const criticalCount = issues.filter((i) => i.severity === "critical").length;
2055
2491
  const majorCount = issues.filter((i) => i.severity === "major").length;
2056
2492
  const minorCount = issues.filter((i) => i.severity === "minor").length;
2057
- console.log(chalk6.dim("Summary:"));
2058
- if (criticalCount > 0) console.log(chalk6.red(` \u2022 ${criticalCount} critical`));
2059
- if (majorCount > 0) console.log(chalk6.yellow(` \u2022 ${majorCount} major`));
2060
- if (minorCount > 0) console.log(chalk6.dim(` \u2022 ${minorCount} minor`));
2493
+ console.log(chalk7.dim("Summary:"));
2494
+ if (criticalCount > 0) console.log(chalk7.red(` \u2022 ${criticalCount} critical`));
2495
+ if (majorCount > 0) console.log(chalk7.yellow(` \u2022 ${majorCount} major`));
2496
+ if (minorCount > 0) console.log(chalk7.dim(` \u2022 ${minorCount} minor`));
2061
2497
  console.log();
2062
- console.log(chalk6.bold("Issues:\n"));
2498
+ console.log(chalk7.bold("Issues:\n"));
2063
2499
  const issuesByFile = /* @__PURE__ */ new Map();
2064
2500
  for (const issue of issues) {
2065
2501
  const existing = issuesByFile.get(issue.file) || [];
@@ -2067,43 +2503,43 @@ async function a11yCheck(options) {
2067
2503
  issuesByFile.set(issue.file, existing);
2068
2504
  }
2069
2505
  for (const [file, fileIssues] of issuesByFile) {
2070
- console.log(chalk6.cyan(` ${file}`));
2506
+ console.log(chalk7.cyan(` ${file}`));
2071
2507
  for (const issue of fileIssues.slice(0, 5)) {
2072
- const color = issue.severity === "critical" ? chalk6.red : issue.severity === "major" ? chalk6.yellow : chalk6.dim;
2508
+ const color = issue.severity === "critical" ? chalk7.red : issue.severity === "major" ? chalk7.yellow : chalk7.dim;
2073
2509
  console.log(color(` Line ${issue.line}: ${issue.message} (WCAG ${issue.wcag})`));
2074
2510
  }
2075
2511
  if (fileIssues.length > 5) {
2076
- console.log(chalk6.dim(` ... and ${fileIssues.length - 5} more issues`));
2512
+ console.log(chalk7.dim(` ... and ${fileIssues.length - 5} more issues`));
2077
2513
  }
2078
2514
  console.log();
2079
2515
  }
2080
- console.log(chalk6.bold.yellow("\n\u2696\uFE0F Legal Notice\n"));
2081
- console.log(chalk6.dim("Websites that don't meet accessibility standards may violate:"));
2082
- console.log(chalk6.dim(" \u2022 ADA (Americans with Disabilities Act) \u2014 US"));
2083
- console.log(chalk6.dim(" \u2022 EAA (European Accessibility Act) \u2014 EU, effective June 2025"));
2084
- console.log(chalk6.dim(" \u2022 Section 508 \u2014 US federal agencies and contractors"));
2085
- console.log(chalk6.dim(" \u2022 AODA (Accessibility for Ontarians) \u2014 Ontario, Canada"));
2516
+ console.log(chalk7.bold.yellow("\n\u2696\uFE0F Legal Notice\n"));
2517
+ console.log(chalk7.dim("Websites that don't meet accessibility standards may violate:"));
2518
+ console.log(chalk7.dim(" \u2022 ADA (Americans with Disabilities Act) \u2014 US"));
2519
+ console.log(chalk7.dim(" \u2022 EAA (European Accessibility Act) \u2014 EU, effective June 2025"));
2520
+ console.log(chalk7.dim(" \u2022 Section 508 \u2014 US federal agencies and contractors"));
2521
+ console.log(chalk7.dim(" \u2022 AODA (Accessibility for Ontarians) \u2014 Ontario, Canada"));
2086
2522
  console.log();
2087
- console.log(chalk6.dim("Non-compliance can result in lawsuits, fines, and reputational damage."));
2088
- console.log(chalk6.dim("In 2023, over 4,600 ADA web accessibility lawsuits were filed in the US.\n"));
2089
- console.log(chalk6.dim(`Full report saved to: .archon/a11y-report.json`));
2523
+ console.log(chalk7.dim("Non-compliance can result in lawsuits, fines, and reputational damage."));
2524
+ console.log(chalk7.dim("In 2023, over 4,600 ADA web accessibility lawsuits were filed in the US.\n"));
2525
+ console.log(chalk7.dim(`Full report saved to: .archon/a11y-report.json`));
2090
2526
  }
2091
2527
  async function a11yFix(options) {
2092
2528
  const prompt2 = createPrompt();
2093
2529
  try {
2094
- console.log(chalk6.blue("\n\u267F Accessibility Auto-Fix\n"));
2095
- const reportPath = join5(process.cwd(), ".archon/a11y-report.json");
2096
- if (!existsSync6(reportPath)) {
2097
- console.log(chalk6.yellow("No accessibility report found. Running check first...\n"));
2530
+ console.log(chalk7.blue("\n\u267F Accessibility Auto-Fix\n"));
2531
+ const reportPath = join6(process.cwd(), ".archon/a11y-report.json");
2532
+ if (!existsSync7(reportPath)) {
2533
+ console.log(chalk7.yellow("No accessibility report found. Running check first...\n"));
2098
2534
  await a11yCheck({});
2099
2535
  }
2100
- const reportContent = await readFile4(reportPath, "utf-8");
2536
+ const reportContent = await readFile5(reportPath, "utf-8");
2101
2537
  const report = JSON.parse(reportContent);
2102
2538
  if (report.passed || report.issues.length === 0) {
2103
- console.log(chalk6.green("No issues to fix!"));
2539
+ console.log(chalk7.green("No issues to fix!"));
2104
2540
  return;
2105
2541
  }
2106
- console.log(chalk6.dim(`Found ${report.issues.length} issues from last check.
2542
+ console.log(chalk7.dim(`Found ${report.issues.length} issues from last check.
2107
2543
  `));
2108
2544
  const fixablePatterns = [
2109
2545
  {
@@ -2134,19 +2570,19 @@ async function a11yFix(options) {
2134
2570
  for (const pattern of patterns) {
2135
2571
  const files = await glob(pattern, { cwd: process.cwd(), ignore: ignorePatterns });
2136
2572
  for (const file of files) {
2137
- const filePath = join5(process.cwd(), file);
2573
+ const filePath = join6(process.cwd(), file);
2138
2574
  try {
2139
- const content = await readFile4(filePath, "utf-8");
2575
+ const content = await readFile5(filePath, "utf-8");
2140
2576
  if (fix.pattern.test(content)) {
2141
2577
  fix.pattern.lastIndex = 0;
2142
2578
  const matches = content.match(fix.pattern);
2143
2579
  const count = matches?.length || 0;
2144
2580
  if (count > 0) {
2145
- console.log(chalk6.cyan(` ${file}: ${count} fixes (${fix.description})`));
2581
+ console.log(chalk7.cyan(` ${file}: ${count} fixes (${fix.description})`));
2146
2582
  totalFixes += count;
2147
2583
  if (!options.dryRun) {
2148
2584
  const newContent = content.replace(fix.pattern, fix.replacement);
2149
- await writeFile4(filePath, newContent);
2585
+ await writeFile5(filePath, newContent);
2150
2586
  }
2151
2587
  }
2152
2588
  }
@@ -2156,21 +2592,21 @@ async function a11yFix(options) {
2156
2592
  }
2157
2593
  }
2158
2594
  if (totalFixes === 0) {
2159
- console.log(chalk6.dim("No auto-fixable issues found. Some issues require manual fixes."));
2595
+ console.log(chalk7.dim("No auto-fixable issues found. Some issues require manual fixes."));
2160
2596
  } else if (options.dryRun) {
2161
- console.log(chalk6.yellow(`
2597
+ console.log(chalk7.yellow(`
2162
2598
  ${totalFixes} fixes would be applied. Run without --dry-run to apply.`));
2163
2599
  } else {
2164
- console.log(chalk6.green(`
2600
+ console.log(chalk7.green(`
2165
2601
  \u2705 Applied ${totalFixes} fixes.`));
2166
- console.log(chalk6.dim('Run "archon a11y check" to verify fixes.'));
2602
+ console.log(chalk7.dim('Run "archon a11y check" to verify fixes.'));
2167
2603
  }
2168
2604
  } finally {
2169
2605
  prompt2.close();
2170
2606
  }
2171
2607
  }
2172
2608
  async function a11yBadge(options) {
2173
- console.log(chalk6.blue("\n\u267F Accessibility Badge\n"));
2609
+ console.log(chalk7.blue("\n\u267F Accessibility Badge\n"));
2174
2610
  const badgeHtml = `<!-- WCAG 2.2 AA Compliance Badge -->
2175
2611
  <div class="flex items-center gap-2 text-xs text-text-muted dark:text-cream-300">
2176
2612
  <svg class="h-4 w-4" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
@@ -2185,35 +2621,35 @@ async function a11yBadge(options) {
2185
2621
  footerFiles = footerFiles.concat(files);
2186
2622
  }
2187
2623
  if (footerFiles.length === 0) {
2188
- console.log(chalk6.yellow("No footer files found."));
2189
- console.log(chalk6.dim("\nManually add this badge to your footer:\n"));
2624
+ console.log(chalk7.yellow("No footer files found."));
2625
+ console.log(chalk7.dim("\nManually add this badge to your footer:\n"));
2190
2626
  console.log(badgeHtml);
2191
2627
  return;
2192
2628
  }
2193
- console.log(chalk6.dim(`Found ${footerFiles.length} footer file(s):
2629
+ console.log(chalk7.dim(`Found ${footerFiles.length} footer file(s):
2194
2630
  `));
2195
2631
  for (const file of footerFiles) {
2196
- console.log(chalk6.cyan(` ${file}`));
2632
+ console.log(chalk7.cyan(` ${file}`));
2197
2633
  }
2198
2634
  if (options.remove) {
2199
- console.log(chalk6.yellow("\nRemoving accessibility badge..."));
2200
- console.log(chalk6.dim("Badge removal not yet implemented. Manually remove the WCAG badge comment block."));
2635
+ console.log(chalk7.yellow("\nRemoving accessibility badge..."));
2636
+ console.log(chalk7.dim("Badge removal not yet implemented. Manually remove the WCAG badge comment block."));
2201
2637
  } else {
2202
- console.log(chalk6.dim("\nTo add the badge, insert this code before the closing </footer> tag:\n"));
2203
- console.log(chalk6.green(badgeHtml));
2638
+ console.log(chalk7.dim("\nTo add the badge, insert this code before the closing </footer> tag:\n"));
2639
+ console.log(chalk7.green(badgeHtml));
2204
2640
  }
2205
2641
  }
2206
2642
  async function a11yPreDeploy() {
2207
2643
  const prompt2 = createPrompt();
2208
2644
  try {
2209
- console.log(chalk6.blue("\n\u26A0\uFE0F Pre-Deploy Accessibility Check\n"));
2210
- console.log(chalk6.dim("Before deploying a live website, accessibility compliance is required.\n"));
2645
+ console.log(chalk7.blue("\n\u26A0\uFE0F Pre-Deploy Accessibility Check\n"));
2646
+ console.log(chalk7.dim("Before deploying a live website, accessibility compliance is required.\n"));
2211
2647
  await a11yCheck({});
2212
- const reportPath = join5(process.cwd(), ".archon/a11y-report.json");
2213
- if (!existsSync6(reportPath)) {
2648
+ const reportPath = join6(process.cwd(), ".archon/a11y-report.json");
2649
+ if (!existsSync7(reportPath)) {
2214
2650
  return false;
2215
2651
  }
2216
- const reportContent = await readFile4(reportPath, "utf-8");
2652
+ const reportContent = await readFile5(reportPath, "utf-8");
2217
2653
  const report = JSON.parse(reportContent);
2218
2654
  if (report.passed) {
2219
2655
  const addBadge = await prompt2.ask("\nWould you like to add a WCAG 2.2 AA badge to your footer? (y/N): ");
@@ -2222,7 +2658,7 @@ async function a11yPreDeploy() {
2222
2658
  }
2223
2659
  return true;
2224
2660
  }
2225
- console.log(chalk6.bold("\nOptions:\n"));
2661
+ console.log(chalk7.bold("\nOptions:\n"));
2226
2662
  console.log(" 1) Fix issues now (recommended)");
2227
2663
  console.log(" 2) Deploy anyway (not recommended)");
2228
2664
  console.log(" 3) Cancel deployment\n");
@@ -2232,11 +2668,11 @@ async function a11yPreDeploy() {
2232
2668
  await a11yCheck({});
2233
2669
  return true;
2234
2670
  } else if (choice === "2") {
2235
- console.log(chalk6.yellow("\n\u26A0\uFE0F Acknowledged. Proceeding without full accessibility compliance."));
2236
- console.log(chalk6.dim("Consider addressing these issues in a future session.\n"));
2671
+ console.log(chalk7.yellow("\n\u26A0\uFE0F Acknowledged. Proceeding without full accessibility compliance."));
2672
+ console.log(chalk7.dim("Consider addressing these issues in a future session.\n"));
2237
2673
  return true;
2238
2674
  } else {
2239
- console.log(chalk6.dim("\nDeployment cancelled."));
2675
+ console.log(chalk7.dim("\nDeployment cancelled."));
2240
2676
  return false;
2241
2677
  }
2242
2678
  } finally {
@@ -2246,14 +2682,14 @@ async function a11yPreDeploy() {
2246
2682
 
2247
2683
  // src/cli/geo.ts
2248
2684
  import { Command as Command2 } from "commander";
2249
- import chalk7 from "chalk";
2250
- import { readFile as readFile5, writeFile as writeFile5, mkdir as mkdir3 } from "fs/promises";
2251
- import { existsSync as existsSync7 } from "fs";
2252
- import { join as join6 } from "path";
2685
+ import chalk8 from "chalk";
2686
+ import { readFile as readFile6, writeFile as writeFile6, mkdir as mkdir4 } from "fs/promises";
2687
+ import { existsSync as existsSync8 } from "fs";
2688
+ import { join as join7 } from "path";
2253
2689
  import { createInterface as createInterface2 } from "readline";
2254
2690
  import { glob as glob2 } from "glob";
2255
- import * as yaml from "yaml";
2256
- var CONFIG_PATH = ".archon/config.yaml";
2691
+ import * as yaml2 from "yaml";
2692
+ var CONFIG_PATH2 = ".archon/config.yaml";
2257
2693
  function createPrompt2() {
2258
2694
  const rl = createInterface2({
2259
2695
  input: process.stdin,
@@ -2267,33 +2703,33 @@ function createPrompt2() {
2267
2703
  };
2268
2704
  }
2269
2705
  async function loadGeoConfig(cwd) {
2270
- const configPath = join6(cwd, CONFIG_PATH);
2271
- if (!existsSync7(configPath)) {
2706
+ const configPath = join7(cwd, CONFIG_PATH2);
2707
+ if (!existsSync8(configPath)) {
2272
2708
  return {};
2273
2709
  }
2274
2710
  try {
2275
- const content = await readFile5(configPath, "utf-8");
2276
- return yaml.parse(content);
2711
+ const content = await readFile6(configPath, "utf-8");
2712
+ return yaml2.parse(content);
2277
2713
  } catch {
2278
2714
  return {};
2279
2715
  }
2280
2716
  }
2281
2717
  async function saveGeoConfig(cwd, config) {
2282
- const configPath = join6(cwd, CONFIG_PATH);
2283
- const archonDir = join6(cwd, ".archon");
2284
- if (!existsSync7(archonDir)) {
2285
- await mkdir3(archonDir, { recursive: true });
2718
+ const configPath = join7(cwd, CONFIG_PATH2);
2719
+ const archonDir = join7(cwd, ".archon");
2720
+ if (!existsSync8(archonDir)) {
2721
+ await mkdir4(archonDir, { recursive: true });
2286
2722
  }
2287
2723
  let existing = {};
2288
- if (existsSync7(configPath)) {
2724
+ if (existsSync8(configPath)) {
2289
2725
  try {
2290
- const content = await readFile5(configPath, "utf-8");
2291
- existing = yaml.parse(content);
2726
+ const content = await readFile6(configPath, "utf-8");
2727
+ existing = yaml2.parse(content);
2292
2728
  } catch {
2293
2729
  }
2294
2730
  }
2295
2731
  const merged = { ...existing, ...config };
2296
- await writeFile5(configPath, yaml.stringify(merged), "utf-8");
2732
+ await writeFile6(configPath, yaml2.stringify(merged), "utf-8");
2297
2733
  }
2298
2734
  async function readPageContent(patterns) {
2299
2735
  const cwd = process.cwd();
@@ -2302,7 +2738,7 @@ async function readPageContent(patterns) {
2302
2738
  const files = await glob2(pattern, { cwd, ignore: ["**/node_modules/**", "**/dist/**"] });
2303
2739
  for (const file of files.slice(0, 3)) {
2304
2740
  try {
2305
- const fileContent = await readFile5(join6(cwd, file), "utf-8");
2741
+ const fileContent = await readFile6(join7(cwd, file), "utf-8");
2306
2742
  content += `
2307
2743
  --- File: ${file} ---
2308
2744
  ${fileContent.slice(0, 5e3)}
@@ -2370,13 +2806,13 @@ async function geoIdentity() {
2370
2806
  const cwd = process.cwd();
2371
2807
  const prompt2 = createPrompt2();
2372
2808
  try {
2373
- console.log(chalk7.blue("\n\u{1F3AF} GEO Identity Generator\n"));
2809
+ console.log(chalk8.blue("\n\u{1F3AF} GEO Identity Generator\n"));
2374
2810
  const { allowed, tier } = await checkStrongModelAccess();
2375
2811
  if (!allowed) {
2376
- console.log(chalk7.yellow(`\u26A0\uFE0F Your tier (${tier}) uses basic models.`));
2377
- console.log(chalk7.dim("For better results, add credits or use BYOK mode.\n"));
2812
+ console.log(chalk8.yellow(`\u26A0\uFE0F Your tier (${tier}) uses basic models.`));
2813
+ console.log(chalk8.dim("For better results, add credits or use BYOK mode.\n"));
2378
2814
  }
2379
- console.log(chalk7.dim("Reading homepage and about page content...\n"));
2815
+ console.log(chalk8.dim("Reading homepage and about page content...\n"));
2380
2816
  const pageContent = await readPageContent([
2381
2817
  "**/index.html",
2382
2818
  "**/index.{jsx,tsx,astro,svelte,vue}",
@@ -2387,44 +2823,44 @@ async function geoIdentity() {
2387
2823
  "README.md"
2388
2824
  ]);
2389
2825
  if (pageContent === "No content found.") {
2390
- console.log(chalk7.yellow("No homepage or about page content found."));
2391
- console.log(chalk7.dim("Create an index file or README.md first.\n"));
2826
+ console.log(chalk8.yellow("No homepage or about page content found."));
2827
+ console.log(chalk8.dim("Create an index file or README.md first.\n"));
2392
2828
  return;
2393
2829
  }
2394
- console.log(chalk7.dim("Generating identity candidates with AI...\n"));
2830
+ console.log(chalk8.dim("Generating identity candidates with AI...\n"));
2395
2831
  const candidates = await generateIdentityCandidates(pageContent);
2396
- console.log(chalk7.bold("\u{1F4CC} 7-Word Brand Phrases:\n"));
2832
+ console.log(chalk8.bold("\u{1F4CC} 7-Word Brand Phrases:\n"));
2397
2833
  candidates.phrases.forEach((p, i) => {
2398
- console.log(` ${chalk7.cyan(`${i + 1})`)} ${chalk7.bold(p.phrase)}`);
2399
- console.log(` ${chalk7.dim(p.rationale)}
2834
+ console.log(` ${chalk8.cyan(`${i + 1})`)} ${chalk8.bold(p.phrase)}`);
2835
+ console.log(` ${chalk8.dim(p.rationale)}
2400
2836
  `);
2401
2837
  });
2402
2838
  const phraseChoice = await prompt2.ask('Select a phrase (1-3) or "r" to regenerate: ');
2403
2839
  if (phraseChoice.toLowerCase() === "r") {
2404
- console.log(chalk7.dim("\nRegenerating... Run the command again.\n"));
2840
+ console.log(chalk8.dim("\nRegenerating... Run the command again.\n"));
2405
2841
  return;
2406
2842
  }
2407
2843
  const phraseIndex = parseInt(phraseChoice, 10) - 1;
2408
2844
  const selectedPhrase = candidates.phrases[phraseIndex];
2409
2845
  if (isNaN(phraseIndex) || phraseIndex < 0 || phraseIndex >= candidates.phrases.length || !selectedPhrase) {
2410
- console.log(chalk7.red("Invalid selection."));
2846
+ console.log(chalk8.red("Invalid selection."));
2411
2847
  return;
2412
2848
  }
2413
- console.log(chalk7.bold("\n\u{1F4DD} 50-Word Descriptions:\n"));
2849
+ console.log(chalk8.bold("\n\u{1F4DD} 50-Word Descriptions:\n"));
2414
2850
  candidates.descriptions.forEach((d, i) => {
2415
- console.log(` ${chalk7.cyan(`${i + 1})`)} ${d.description}`);
2416
- console.log(` ${chalk7.dim(d.rationale)}
2851
+ console.log(` ${chalk8.cyan(`${i + 1})`)} ${d.description}`);
2852
+ console.log(` ${chalk8.dim(d.rationale)}
2417
2853
  `);
2418
2854
  });
2419
2855
  const descChoice = await prompt2.ask('Select a description (1-3) or "r" to regenerate: ');
2420
2856
  if (descChoice.toLowerCase() === "r") {
2421
- console.log(chalk7.dim("\nRegenerating... Run the command again.\n"));
2857
+ console.log(chalk8.dim("\nRegenerating... Run the command again.\n"));
2422
2858
  return;
2423
2859
  }
2424
2860
  const descIndex = parseInt(descChoice, 10) - 1;
2425
2861
  const selectedDescription = candidates.descriptions[descIndex];
2426
2862
  if (isNaN(descIndex) || descIndex < 0 || descIndex >= candidates.descriptions.length || !selectedDescription) {
2427
- console.log(chalk7.red("Invalid selection."));
2863
+ console.log(chalk8.red("Invalid selection."));
2428
2864
  return;
2429
2865
  }
2430
2866
  const geoConfig = {
@@ -2435,31 +2871,31 @@ async function geoIdentity() {
2435
2871
  }
2436
2872
  };
2437
2873
  await saveGeoConfig(cwd, geoConfig);
2438
- console.log(chalk7.green("\n\u2705 Identity saved!\n"));
2439
- console.log(chalk7.dim(` Phrase: ${selectedPhrase.phrase}`));
2440
- console.log(chalk7.dim(` Description: ${selectedDescription.description.slice(0, 60)}...`));
2874
+ console.log(chalk8.green("\n\u2705 Identity saved!\n"));
2875
+ console.log(chalk8.dim(` Phrase: ${selectedPhrase.phrase}`));
2876
+ console.log(chalk8.dim(` Description: ${selectedDescription.description.slice(0, 60)}...`));
2441
2877
  console.log();
2442
- console.log(chalk7.cyan(`Use 'archon geo schema' to generate JSON-LD.`));
2878
+ console.log(chalk8.cyan(`Use 'archon geo schema' to generate JSON-LD.`));
2443
2879
  } finally {
2444
2880
  prompt2.close();
2445
2881
  }
2446
2882
  }
2447
2883
  async function geoSchema(options) {
2448
2884
  const cwd = process.cwd();
2449
- console.log(chalk7.blue("\n\u{1F4E6} JSON-LD Schema Generator\n"));
2885
+ console.log(chalk8.blue("\n\u{1F4E6} JSON-LD Schema Generator\n"));
2450
2886
  const config = await loadGeoConfig(cwd);
2451
2887
  if (!config.geo?.identityPhrase || !config.geo?.shortDescription) {
2452
- console.log(chalk7.yellow("No identity defined."));
2453
- console.log(chalk7.dim(`Run 'archon geo identity' first.
2888
+ console.log(chalk8.yellow("No identity defined."));
2889
+ console.log(chalk8.dim(`Run 'archon geo identity' first.
2454
2890
  `));
2455
2891
  return;
2456
2892
  }
2457
2893
  const { identityPhrase, shortDescription } = config.geo;
2458
2894
  let orgName = identityPhrase.split(" ").slice(0, 2).join(" ");
2459
2895
  try {
2460
- const pkgPath = join6(cwd, "package.json");
2461
- if (existsSync7(pkgPath)) {
2462
- const pkg = JSON.parse(await readFile5(pkgPath, "utf-8"));
2896
+ const pkgPath = join7(cwd, "package.json");
2897
+ if (existsSync8(pkgPath)) {
2898
+ const pkg = JSON.parse(await readFile6(pkgPath, "utf-8"));
2463
2899
  if (pkg.name) {
2464
2900
  orgName = pkg.name.replace(/-/g, " ").replace(/^\w/, (c) => c.toUpperCase());
2465
2901
  }
@@ -2493,40 +2929,40 @@ async function geoSchema(options) {
2493
2929
  };
2494
2930
  const jsonLd = JSON.stringify(schema, null, 2);
2495
2931
  if (options.output) {
2496
- await writeFile5(options.output, jsonLd, "utf-8");
2497
- console.log(chalk7.green(`\u2705 Schema written to ${options.output}`));
2932
+ await writeFile6(options.output, jsonLd, "utf-8");
2933
+ console.log(chalk8.green(`\u2705 Schema written to ${options.output}`));
2498
2934
  } else {
2499
- console.log(chalk7.bold("Generated JSON-LD:\n"));
2500
- console.log(chalk7.cyan(jsonLd));
2935
+ console.log(chalk8.bold("Generated JSON-LD:\n"));
2936
+ console.log(chalk8.cyan(jsonLd));
2501
2937
  }
2502
2938
  if (options.apply) {
2503
- console.log(chalk7.dim("\nAttempting to insert into homepage <head>...\n"));
2939
+ console.log(chalk8.dim("\nAttempting to insert into homepage <head>...\n"));
2504
2940
  const indexFiles = await glob2("**/index.html", { cwd, ignore: ["**/node_modules/**", "**/dist/**"] });
2505
2941
  if (indexFiles.length === 0) {
2506
- console.log(chalk7.yellow("No index.html found. Manually add to your HTML <head>:"));
2507
- console.log(chalk7.dim(`<script type="application/ld+json">
2942
+ console.log(chalk8.yellow("No index.html found. Manually add to your HTML <head>:"));
2943
+ console.log(chalk8.dim(`<script type="application/ld+json">
2508
2944
  ${jsonLd}
2509
2945
  </script>`));
2510
2946
  return;
2511
2947
  }
2512
2948
  const firstIndexFile = indexFiles[0];
2513
2949
  if (!firstIndexFile) {
2514
- console.log(chalk7.yellow("No index.html found."));
2950
+ console.log(chalk8.yellow("No index.html found."));
2515
2951
  return;
2516
2952
  }
2517
- const indexPath = join6(cwd, firstIndexFile);
2518
- let indexContent = await readFile5(indexPath, "utf-8");
2953
+ const indexPath = join7(cwd, firstIndexFile);
2954
+ let indexContent = await readFile6(indexPath, "utf-8");
2519
2955
  const scriptTag = `<script type="application/ld+json">
2520
2956
  ${jsonLd}
2521
2957
  </script>`;
2522
2958
  if (indexContent.includes("application/ld+json")) {
2523
- console.log(chalk7.yellow("JSON-LD already exists in index.html. Remove it first or update manually."));
2959
+ console.log(chalk8.yellow("JSON-LD already exists in index.html. Remove it first or update manually."));
2524
2960
  return;
2525
2961
  }
2526
2962
  indexContent = indexContent.replace("</head>", `${scriptTag}
2527
2963
  </head>`);
2528
- await writeFile5(indexPath, indexContent, "utf-8");
2529
- console.log(chalk7.green(`\u2705 JSON-LD inserted into ${firstIndexFile}`));
2964
+ await writeFile6(indexPath, indexContent, "utf-8");
2965
+ console.log(chalk8.green(`\u2705 JSON-LD inserted into ${firstIndexFile}`));
2530
2966
  }
2531
2967
  console.log();
2532
2968
  }
@@ -2542,21 +2978,21 @@ Guidelines:
2542
2978
  Output your response as valid JSON.`;
2543
2979
  async function geoFaq(options) {
2544
2980
  const cwd = process.cwd();
2545
- console.log(chalk7.blue("\n\u2753 FAQ Schema Generator\n"));
2981
+ console.log(chalk8.blue("\n\u2753 FAQ Schema Generator\n"));
2546
2982
  const config = await loadGeoConfig(cwd);
2547
2983
  if (!config.geo?.identityPhrase || !config.geo?.shortDescription) {
2548
- console.log(chalk7.yellow("No identity defined."));
2549
- console.log(chalk7.dim(`Run 'archon geo identity' first.
2984
+ console.log(chalk8.yellow("No identity defined."));
2985
+ console.log(chalk8.dim(`Run 'archon geo identity' first.
2550
2986
  `));
2551
2987
  return;
2552
2988
  }
2553
2989
  const { identityPhrase, shortDescription } = config.geo;
2554
2990
  const { allowed, tier } = await checkStrongModelAccess();
2555
2991
  if (!allowed) {
2556
- console.log(chalk7.yellow(`\u26A0\uFE0F Your tier (${tier}) uses basic models.`));
2557
- console.log(chalk7.dim("For better results, add credits or use BYOK mode.\n"));
2992
+ console.log(chalk8.yellow(`\u26A0\uFE0F Your tier (${tier}) uses basic models.`));
2993
+ console.log(chalk8.dim("For better results, add credits or use BYOK mode.\n"));
2558
2994
  }
2559
- console.log(chalk7.dim("Generating FAQ content with AI...\n"));
2995
+ console.log(chalk8.dim("Generating FAQ content with AI...\n"));
2560
2996
  const agent = new ArchitectAgent({ temperature: 0.7 });
2561
2997
  const prompt2 = `Generate FAQ content for a product/service with:
2562
2998
  - Brand phrase: "${identityPhrase}"
@@ -2576,7 +3012,7 @@ Generate 6-8 FAQs as JSON:
2576
3012
  );
2577
3013
  const jsonMatch = response.content.match(/\{[\s\S]*\}/);
2578
3014
  if (!jsonMatch) {
2579
- console.log(chalk7.red("Failed to generate FAQ content."));
3015
+ console.log(chalk8.red("Failed to generate FAQ content."));
2580
3016
  return;
2581
3017
  }
2582
3018
  const parsed = JSON.parse(jsonMatch[0]);
@@ -2594,17 +3030,17 @@ Generate 6-8 FAQs as JSON:
2594
3030
  };
2595
3031
  const jsonLd = JSON.stringify(faqSchema, null, 2);
2596
3032
  if (options.output) {
2597
- await writeFile5(options.output, jsonLd, "utf-8");
2598
- console.log(chalk7.green(`\u2705 FAQ schema written to ${options.output}`));
3033
+ await writeFile6(options.output, jsonLd, "utf-8");
3034
+ console.log(chalk8.green(`\u2705 FAQ schema written to ${options.output}`));
2599
3035
  } else {
2600
- console.log(chalk7.bold("Generated FAQPage JSON-LD:\n"));
2601
- console.log(chalk7.cyan(jsonLd));
3036
+ console.log(chalk8.bold("Generated FAQPage JSON-LD:\n"));
3037
+ console.log(chalk8.cyan(jsonLd));
2602
3038
  }
2603
3039
  console.log();
2604
3040
  }
2605
3041
  async function geoAudit() {
2606
3042
  const cwd = process.cwd();
2607
- console.log(chalk7.blue("\n\u{1F50D} GEO Audit\n"));
3043
+ console.log(chalk8.blue("\n\u{1F50D} GEO Audit\n"));
2608
3044
  const result = {
2609
3045
  identityDefined: false,
2610
3046
  phraseInH1: false,
@@ -2617,75 +3053,75 @@ async function geoAudit() {
2617
3053
  const config = await loadGeoConfig(cwd);
2618
3054
  if (config.geo?.identityPhrase && config.geo?.shortDescription) {
2619
3055
  result.identityDefined = true;
2620
- console.log(chalk7.green("\u2705 Identity defined"));
2621
- console.log(chalk7.dim(` Phrase: ${config.geo.identityPhrase}`));
3056
+ console.log(chalk8.green("\u2705 Identity defined"));
3057
+ console.log(chalk8.dim(` Phrase: ${config.geo.identityPhrase}`));
2622
3058
  } else {
2623
3059
  result.issues.push('Identity not defined. Run "archon geo identity"');
2624
- console.log(chalk7.red("\u274C Identity not defined"));
3060
+ console.log(chalk8.red("\u274C Identity not defined"));
2625
3061
  }
2626
3062
  const htmlFiles = await glob2("**/index.html", { cwd, ignore: ["**/node_modules/**", "**/dist/**"] });
2627
3063
  const firstHtmlFile = htmlFiles[0];
2628
3064
  if (firstHtmlFile && config.geo?.identityPhrase) {
2629
- const indexPath = join6(cwd, firstHtmlFile);
2630
- const content = await readFile5(indexPath, "utf-8");
3065
+ const indexPath = join7(cwd, firstHtmlFile);
3066
+ const content = await readFile6(indexPath, "utf-8");
2631
3067
  const identityPhrase = config.geo.identityPhrase;
2632
3068
  const firstKeyword = identityPhrase.toLowerCase().split(" ")[0] ?? "";
2633
3069
  const h1Match = content.match(/<h1[^>]*>(.*?)<\/h1>/is);
2634
3070
  if (h1Match?.[1] && h1Match[1].toLowerCase().includes(firstKeyword)) {
2635
3071
  result.phraseInH1 = true;
2636
- console.log(chalk7.green("\u2705 Brand keyword in H1"));
3072
+ console.log(chalk8.green("\u2705 Brand keyword in H1"));
2637
3073
  } else {
2638
3074
  result.issues.push("Brand phrase keyword not found in H1");
2639
- console.log(chalk7.yellow("\u26A0\uFE0F Brand keyword not in H1"));
3075
+ console.log(chalk8.yellow("\u26A0\uFE0F Brand keyword not in H1"));
2640
3076
  }
2641
3077
  const metaMatch = content.match(/<meta[^>]*name=["']description["'][^>]*content=["']([^"']*)["']/i);
2642
3078
  if (metaMatch?.[1] && metaMatch[1].toLowerCase().includes(firstKeyword)) {
2643
3079
  result.phraseInMetaDescription = true;
2644
- console.log(chalk7.green("\u2705 Brand keyword in meta description"));
3080
+ console.log(chalk8.green("\u2705 Brand keyword in meta description"));
2645
3081
  } else {
2646
3082
  result.issues.push("Brand phrase keyword not found in meta description");
2647
- console.log(chalk7.yellow("\u26A0\uFE0F Brand keyword not in meta description"));
3083
+ console.log(chalk8.yellow("\u26A0\uFE0F Brand keyword not in meta description"));
2648
3084
  }
2649
3085
  if (content.includes("application/ld+json")) {
2650
3086
  if (content.includes('"@type":"Organization"') || content.includes('"@type": "Organization"')) {
2651
3087
  result.hasOrganizationSchema = true;
2652
- console.log(chalk7.green("\u2705 Organization schema present"));
3088
+ console.log(chalk8.green("\u2705 Organization schema present"));
2653
3089
  } else {
2654
3090
  result.issues.push("Organization schema not found");
2655
- console.log(chalk7.yellow("\u26A0\uFE0F Organization schema missing"));
3091
+ console.log(chalk8.yellow("\u26A0\uFE0F Organization schema missing"));
2656
3092
  }
2657
3093
  if (content.includes('"@type":"Service"') || content.includes('"@type": "Service"')) {
2658
3094
  result.hasServiceSchema = true;
2659
- console.log(chalk7.green("\u2705 Service schema present"));
3095
+ console.log(chalk8.green("\u2705 Service schema present"));
2660
3096
  } else {
2661
3097
  result.issues.push("Service schema not found");
2662
- console.log(chalk7.yellow("\u26A0\uFE0F Service schema missing"));
3098
+ console.log(chalk8.yellow("\u26A0\uFE0F Service schema missing"));
2663
3099
  }
2664
3100
  if (content.includes('"@type":"FAQPage"') || content.includes('"@type": "FAQPage"')) {
2665
3101
  result.hasFAQSchema = true;
2666
- console.log(chalk7.green("\u2705 FAQPage schema present"));
3102
+ console.log(chalk8.green("\u2705 FAQPage schema present"));
2667
3103
  } else {
2668
3104
  result.issues.push("FAQPage schema not found");
2669
- console.log(chalk7.yellow("\u26A0\uFE0F FAQPage schema missing"));
3105
+ console.log(chalk8.yellow("\u26A0\uFE0F FAQPage schema missing"));
2670
3106
  }
2671
3107
  } else {
2672
3108
  result.issues.push("No JSON-LD schemas found");
2673
- console.log(chalk7.red("\u274C No JSON-LD schemas found"));
3109
+ console.log(chalk8.red("\u274C No JSON-LD schemas found"));
2674
3110
  }
2675
3111
  } else if (htmlFiles.length === 0) {
2676
3112
  result.issues.push("No index.html found");
2677
- console.log(chalk7.yellow("\u26A0\uFE0F No index.html found to audit"));
3113
+ console.log(chalk8.yellow("\u26A0\uFE0F No index.html found to audit"));
2678
3114
  }
2679
3115
  console.log();
2680
3116
  const passed = result.issues.length === 0;
2681
3117
  if (passed) {
2682
- console.log(chalk7.green.bold("\u2705 GEO Audit Passed"));
3118
+ console.log(chalk8.green.bold("\u2705 GEO Audit Passed"));
2683
3119
  } else {
2684
- console.log(chalk7.yellow.bold(`\u26A0\uFE0F ${result.issues.length} issue(s) found`));
3120
+ console.log(chalk8.yellow.bold(`\u26A0\uFE0F ${result.issues.length} issue(s) found`));
2685
3121
  console.log();
2686
- console.log(chalk7.bold("Recommendations:"));
3122
+ console.log(chalk8.bold("Recommendations:"));
2687
3123
  result.issues.forEach((issue, i) => {
2688
- console.log(chalk7.dim(` ${i + 1}. ${issue}`));
3124
+ console.log(chalk8.dim(` ${i + 1}. ${issue}`));
2689
3125
  });
2690
3126
  }
2691
3127
  console.log();
@@ -2722,10 +3158,10 @@ Examples:
2722
3158
 
2723
3159
  // src/cli/seo.ts
2724
3160
  import { Command as Command3 } from "commander";
2725
- import chalk8 from "chalk";
2726
- import { readFile as readFile6, writeFile as writeFile6, mkdir as mkdir4 } from "fs/promises";
2727
- import { existsSync as existsSync8 } from "fs";
2728
- import { join as join7 } from "path";
3161
+ import chalk9 from "chalk";
3162
+ import { readFile as readFile7, writeFile as writeFile7, mkdir as mkdir5 } from "fs/promises";
3163
+ import { existsSync as existsSync9 } from "fs";
3164
+ import { join as join8 } from "path";
2729
3165
  import { createInterface as createInterface3 } from "readline";
2730
3166
  import { glob as glob3 } from "glob";
2731
3167
  var SEO_CHECKS = {
@@ -2834,7 +3270,7 @@ async function getWebFiles() {
2834
3270
  let allFiles = [];
2835
3271
  for (const pattern of patterns) {
2836
3272
  const files = await glob3(pattern, { cwd: process.cwd(), ignore: ignorePatterns });
2837
- allFiles = allFiles.concat(files.map((f) => join7(process.cwd(), f)));
3273
+ allFiles = allFiles.concat(files.map((f) => join8(process.cwd(), f)));
2838
3274
  }
2839
3275
  return allFiles;
2840
3276
  }
@@ -2842,7 +3278,7 @@ async function scanForSeoIssues(files) {
2842
3278
  const issues = [];
2843
3279
  for (const file of files) {
2844
3280
  try {
2845
- const content = await readFile6(file, "utf-8");
3281
+ const content = await readFile7(file, "utf-8");
2846
3282
  const relativePath = file.replace(process.cwd() + "/", "");
2847
3283
  for (const [checkId, check] of Object.entries(SEO_CHECKS)) {
2848
3284
  const hasTag = check.regex.test(content);
@@ -2872,19 +3308,19 @@ function findHeadInsertionPoint(content) {
2872
3308
  return null;
2873
3309
  }
2874
3310
  async function seoCheck(options) {
2875
- console.log(chalk8.blue("\n\u{1F50D} SEO Check\n"));
2876
- console.log(chalk8.dim("Scanning for SEO issues...\n"));
3311
+ console.log(chalk9.blue("\n\u{1F50D} SEO Check\n"));
3312
+ console.log(chalk9.dim("Scanning for SEO issues...\n"));
2877
3313
  const files = await getWebFiles();
2878
3314
  if (files.length === 0) {
2879
- console.log(chalk8.yellow("No web files found to check."));
3315
+ console.log(chalk9.yellow("No web files found to check."));
2880
3316
  return;
2881
3317
  }
2882
- console.log(chalk8.dim(`Scanning ${files.length} files...
3318
+ console.log(chalk9.dim(`Scanning ${files.length} files...
2883
3319
  `));
2884
3320
  const issues = await scanForSeoIssues(files);
2885
- const archonDir = join7(process.cwd(), ".archon");
2886
- if (!existsSync8(archonDir)) {
2887
- await mkdir4(archonDir, { recursive: true });
3321
+ const archonDir = join8(process.cwd(), ".archon");
3322
+ if (!existsSync9(archonDir)) {
3323
+ await mkdir5(archonDir, { recursive: true });
2888
3324
  }
2889
3325
  const report = {
2890
3326
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2893,24 +3329,24 @@ async function seoCheck(options) {
2893
3329
  issues,
2894
3330
  passed: issues.length === 0
2895
3331
  };
2896
- await writeFile6(join7(archonDir, "seo-report.json"), JSON.stringify(report, null, 2));
3332
+ await writeFile7(join8(archonDir, "seo-report.json"), JSON.stringify(report, null, 2));
2897
3333
  if (issues.length === 0) {
2898
- console.log(chalk8.green("\u2705 SEO Check Passed\n"));
2899
- console.log(chalk8.dim("All essential meta tags are present."));
3334
+ console.log(chalk9.green("\u2705 SEO Check Passed\n"));
3335
+ console.log(chalk9.dim("All essential meta tags are present."));
2900
3336
  return;
2901
3337
  }
2902
- console.log(chalk8.yellow(`\u26A0\uFE0F ${issues.length} SEO Issues Found
3338
+ console.log(chalk9.yellow(`\u26A0\uFE0F ${issues.length} SEO Issues Found
2903
3339
  `));
2904
3340
  const criticalCount = issues.filter((i) => i.severity === "critical").length;
2905
3341
  const warningCount = issues.filter((i) => i.severity === "warning").length;
2906
3342
  const infoCount = issues.filter((i) => i.severity === "info").length;
2907
- console.log(chalk8.dim("Summary:"));
2908
- if (criticalCount > 0) console.log(chalk8.red(` \u2022 ${criticalCount} critical`));
2909
- if (warningCount > 0) console.log(chalk8.yellow(` \u2022 ${warningCount} warning`));
2910
- if (infoCount > 0) console.log(chalk8.dim(` \u2022 ${infoCount} info`));
3343
+ console.log(chalk9.dim("Summary:"));
3344
+ if (criticalCount > 0) console.log(chalk9.red(` \u2022 ${criticalCount} critical`));
3345
+ if (warningCount > 0) console.log(chalk9.yellow(` \u2022 ${warningCount} warning`));
3346
+ if (infoCount > 0) console.log(chalk9.dim(` \u2022 ${infoCount} info`));
2911
3347
  console.log();
2912
- console.log(chalk8.bold("File | Issue | Recommendation"));
2913
- console.log(chalk8.dim("\u2500".repeat(100)));
3348
+ console.log(chalk9.bold("File | Issue | Recommendation"));
3349
+ console.log(chalk9.dim("\u2500".repeat(100)));
2914
3350
  const issuesByFile = /* @__PURE__ */ new Map();
2915
3351
  for (const issue of issues) {
2916
3352
  const existing = issuesByFile.get(issue.file) || [];
@@ -2920,31 +3356,31 @@ async function seoCheck(options) {
2920
3356
  for (const [file, fileIssues] of issuesByFile) {
2921
3357
  const displayFile = file.length > 30 ? "..." + file.slice(-27) : file.padEnd(30);
2922
3358
  for (const issue of fileIssues.slice(0, options.verbose ? 20 : 5)) {
2923
- const color = issue.severity === "critical" ? chalk8.red : issue.severity === "warning" ? chalk8.yellow : chalk8.dim;
3359
+ const color = issue.severity === "critical" ? chalk9.red : issue.severity === "warning" ? chalk9.yellow : chalk9.dim;
2924
3360
  const displayIssue = issue.issue.padEnd(24).slice(0, 24);
2925
3361
  const displayRec = issue.recommendation.slice(0, 50);
2926
3362
  console.log(color(`${displayFile} | ${displayIssue} | ${displayRec}`));
2927
3363
  }
2928
3364
  if (!options.verbose && fileIssues.length > 5) {
2929
- console.log(chalk8.dim(`${"".padEnd(30)} | ... and ${fileIssues.length - 5} more issues`));
3365
+ console.log(chalk9.dim(`${"".padEnd(30)} | ... and ${fileIssues.length - 5} more issues`));
2930
3366
  }
2931
3367
  }
2932
- console.log(chalk8.dim(`
3368
+ console.log(chalk9.dim(`
2933
3369
  Full report saved to: .archon/seo-report.json`));
2934
3370
  }
2935
3371
  async function seoFix(options) {
2936
3372
  const prompt2 = createPrompt3();
2937
3373
  try {
2938
- console.log(chalk8.blue("\n\u{1F527} SEO Auto-Fix\n"));
2939
- const reportPath = join7(process.cwd(), ".archon/seo-report.json");
2940
- if (!existsSync8(reportPath)) {
2941
- console.log(chalk8.yellow("No SEO report found. Running check first...\n"));
3374
+ console.log(chalk9.blue("\n\u{1F527} SEO Auto-Fix\n"));
3375
+ const reportPath = join8(process.cwd(), ".archon/seo-report.json");
3376
+ if (!existsSync9(reportPath)) {
3377
+ console.log(chalk9.yellow("No SEO report found. Running check first...\n"));
2942
3378
  await seoCheck({});
2943
3379
  }
2944
- const reportContent = await readFile6(reportPath, "utf-8");
3380
+ const reportContent = await readFile7(reportPath, "utf-8");
2945
3381
  const report = JSON.parse(reportContent);
2946
3382
  if (report.passed || report.issues.length === 0) {
2947
- console.log(chalk8.green("No issues to fix!"));
3383
+ console.log(chalk9.green("No issues to fix!"));
2948
3384
  return;
2949
3385
  }
2950
3386
  const issuesByFile = /* @__PURE__ */ new Map();
@@ -2955,16 +3391,16 @@ async function seoFix(options) {
2955
3391
  }
2956
3392
  let totalFixes = 0;
2957
3393
  for (const [file, fileIssues] of issuesByFile) {
2958
- const filePath = join7(process.cwd(), file);
3394
+ const filePath = join8(process.cwd(), file);
2959
3395
  let content;
2960
3396
  try {
2961
- content = await readFile6(filePath, "utf-8");
3397
+ content = await readFile7(filePath, "utf-8");
2962
3398
  } catch {
2963
3399
  continue;
2964
3400
  }
2965
3401
  const insertPoint = findHeadInsertionPoint(content);
2966
3402
  if (!insertPoint) {
2967
- console.log(chalk8.yellow(` ${file}: No <head> tag found, skipping`));
3403
+ console.log(chalk9.yellow(` ${file}: No <head> tag found, skipping`));
2968
3404
  continue;
2969
3405
  }
2970
3406
  const tagsToAdd = [];
@@ -2983,33 +3419,33 @@ async function seoFix(options) {
2983
3419
  }
2984
3420
  if (tagsToAdd.length === 0) continue;
2985
3421
  const newContent = content.slice(0, insertPoint.index) + "\n" + tagsToAdd.map((tag) => insertPoint.indent + tag).join("\n") + content.slice(insertPoint.index);
2986
- console.log(chalk8.cyan(`
3422
+ console.log(chalk9.cyan(`
2987
3423
  ${file}:`));
2988
3424
  for (const tag of tagsToAdd) {
2989
- console.log(chalk8.green(` + ${tag.slice(0, 70)}${tag.length > 70 ? "..." : ""}`));
3425
+ console.log(chalk9.green(` + ${tag.slice(0, 70)}${tag.length > 70 ? "..." : ""}`));
2990
3426
  }
2991
3427
  if (!options.dryRun) {
2992
- const confirm = await prompt2.ask(chalk8.dim(" Apply these changes? (y/N): "));
3428
+ const confirm = await prompt2.ask(chalk9.dim(" Apply these changes? (y/N): "));
2993
3429
  if (confirm.toLowerCase() === "y") {
2994
- await writeFile6(filePath, newContent);
3430
+ await writeFile7(filePath, newContent);
2995
3431
  totalFixes += tagsToAdd.length;
2996
- console.log(chalk8.green(" \u2713 Applied"));
3432
+ console.log(chalk9.green(" \u2713 Applied"));
2997
3433
  } else {
2998
- console.log(chalk8.dim(" Skipped"));
3434
+ console.log(chalk9.dim(" Skipped"));
2999
3435
  }
3000
3436
  } else {
3001
3437
  totalFixes += tagsToAdd.length;
3002
3438
  }
3003
3439
  }
3004
3440
  if (totalFixes === 0) {
3005
- console.log(chalk8.dim("\nNo auto-fixable issues found. Some issues require manual configuration."));
3441
+ console.log(chalk9.dim("\nNo auto-fixable issues found. Some issues require manual configuration."));
3006
3442
  } else if (options.dryRun) {
3007
- console.log(chalk8.yellow(`
3443
+ console.log(chalk9.yellow(`
3008
3444
  ${totalFixes} fixes would be applied. Run without --dry-run to apply.`));
3009
3445
  } else {
3010
- console.log(chalk8.green(`
3446
+ console.log(chalk9.green(`
3011
3447
  \u2705 Applied ${totalFixes} fixes.`));
3012
- console.log(chalk8.dim('Run "archon seo check" to verify fixes.'));
3448
+ console.log(chalk9.dim('Run "archon seo check" to verify fixes.'));
3013
3449
  }
3014
3450
  } finally {
3015
3451
  prompt2.close();
@@ -3018,33 +3454,33 @@ ${totalFixes} fixes would be applied. Run without --dry-run to apply.`));
3018
3454
  async function seoOpenGraph(options) {
3019
3455
  const prompt2 = createPrompt3();
3020
3456
  try {
3021
- console.log(chalk8.blue("\n\u{1F4F1} Add Open Graph Tags\n"));
3457
+ console.log(chalk9.blue("\n\u{1F4F1} Add Open Graph Tags\n"));
3022
3458
  let targetFile;
3023
3459
  if (options.file) {
3024
- targetFile = options.file.startsWith("/") ? options.file : join7(process.cwd(), options.file);
3460
+ targetFile = options.file.startsWith("/") ? options.file : join8(process.cwd(), options.file);
3025
3461
  } else {
3026
3462
  const files = await getWebFiles();
3027
3463
  if (files.length === 0) {
3028
- console.log(chalk8.yellow("No web files found."));
3464
+ console.log(chalk9.yellow("No web files found."));
3029
3465
  return;
3030
3466
  }
3031
- console.log(chalk8.dim("Available files:"));
3467
+ console.log(chalk9.dim("Available files:"));
3032
3468
  files.slice(0, 10).forEach((f, i) => {
3033
3469
  console.log(` ${i + 1}) ${f.replace(process.cwd() + "/", "")}`);
3034
3470
  });
3035
3471
  if (files.length > 10) {
3036
- console.log(chalk8.dim(` ... and ${files.length - 10} more`));
3472
+ console.log(chalk9.dim(` ... and ${files.length - 10} more`));
3037
3473
  }
3038
3474
  const fileChoice = await prompt2.ask("\nEnter file path or number: ");
3039
3475
  const num = parseInt(fileChoice, 10);
3040
3476
  if (num > 0 && num <= files.length) {
3041
3477
  targetFile = files[num - 1] ?? "";
3042
3478
  } else {
3043
- targetFile = fileChoice.startsWith("/") ? fileChoice : join7(process.cwd(), fileChoice);
3479
+ targetFile = fileChoice.startsWith("/") ? fileChoice : join8(process.cwd(), fileChoice);
3044
3480
  }
3045
3481
  }
3046
- if (!existsSync8(targetFile)) {
3047
- console.log(chalk8.red(`File not found: ${targetFile}`));
3482
+ if (!existsSync9(targetFile)) {
3483
+ console.log(chalk9.red(`File not found: ${targetFile}`));
3048
3484
  return;
3049
3485
  }
3050
3486
  const ogTitle = await prompt2.ask("og:title (page title for social): ");
@@ -3058,22 +3494,22 @@ async function seoOpenGraph(options) {
3058
3494
  `<meta property="og:image" content="${ogImage}">`,
3059
3495
  `<meta property="og:url" content="${ogUrl}">`
3060
3496
  ];
3061
- const content = await readFile6(targetFile, "utf-8");
3497
+ const content = await readFile7(targetFile, "utf-8");
3062
3498
  const insertPoint = findHeadInsertionPoint(content);
3063
3499
  if (!insertPoint) {
3064
- console.log(chalk8.yellow("No <head> tag found. Add these tags manually:"));
3065
- tags.forEach((tag) => console.log(chalk8.cyan(` ${tag}`)));
3500
+ console.log(chalk9.yellow("No <head> tag found. Add these tags manually:"));
3501
+ tags.forEach((tag) => console.log(chalk9.cyan(` ${tag}`)));
3066
3502
  return;
3067
3503
  }
3068
- console.log(chalk8.dim("\nTags to add:"));
3069
- tags.forEach((tag) => console.log(chalk8.green(` + ${tag}`)));
3504
+ console.log(chalk9.dim("\nTags to add:"));
3505
+ tags.forEach((tag) => console.log(chalk9.green(` + ${tag}`)));
3070
3506
  const confirm = await prompt2.ask("\nApply changes? (y/N): ");
3071
3507
  if (confirm.toLowerCase() === "y") {
3072
3508
  const newContent = content.slice(0, insertPoint.index) + "\n" + tags.map((tag) => insertPoint.indent + tag).join("\n") + content.slice(insertPoint.index);
3073
- await writeFile6(targetFile, newContent);
3074
- console.log(chalk8.green("\n\u2705 Open Graph tags added."));
3509
+ await writeFile7(targetFile, newContent);
3510
+ console.log(chalk9.green("\n\u2705 Open Graph tags added."));
3075
3511
  } else {
3076
- console.log(chalk8.dim("Cancelled."));
3512
+ console.log(chalk9.dim("Cancelled."));
3077
3513
  }
3078
3514
  } finally {
3079
3515
  prompt2.close();
@@ -3082,36 +3518,36 @@ async function seoOpenGraph(options) {
3082
3518
  async function seoTwitter(options) {
3083
3519
  const prompt2 = createPrompt3();
3084
3520
  try {
3085
- console.log(chalk8.blue("\n\u{1F426} Add Twitter Card Tags\n"));
3521
+ console.log(chalk9.blue("\n\u{1F426} Add Twitter Card Tags\n"));
3086
3522
  let targetFile;
3087
3523
  if (options.file) {
3088
- targetFile = options.file.startsWith("/") ? options.file : join7(process.cwd(), options.file);
3524
+ targetFile = options.file.startsWith("/") ? options.file : join8(process.cwd(), options.file);
3089
3525
  } else {
3090
3526
  const files = await getWebFiles();
3091
3527
  if (files.length === 0) {
3092
- console.log(chalk8.yellow("No web files found."));
3528
+ console.log(chalk9.yellow("No web files found."));
3093
3529
  return;
3094
3530
  }
3095
- console.log(chalk8.dim("Available files:"));
3531
+ console.log(chalk9.dim("Available files:"));
3096
3532
  files.slice(0, 10).forEach((f, i) => {
3097
3533
  console.log(` ${i + 1}) ${f.replace(process.cwd() + "/", "")}`);
3098
3534
  });
3099
3535
  if (files.length > 10) {
3100
- console.log(chalk8.dim(` ... and ${files.length - 10} more`));
3536
+ console.log(chalk9.dim(` ... and ${files.length - 10} more`));
3101
3537
  }
3102
3538
  const fileChoice = await prompt2.ask("\nEnter file path or number: ");
3103
3539
  const num = parseInt(fileChoice, 10);
3104
3540
  if (num > 0 && num <= files.length) {
3105
3541
  targetFile = files[num - 1] ?? "";
3106
3542
  } else {
3107
- targetFile = fileChoice.startsWith("/") ? fileChoice : join7(process.cwd(), fileChoice);
3543
+ targetFile = fileChoice.startsWith("/") ? fileChoice : join8(process.cwd(), fileChoice);
3108
3544
  }
3109
3545
  }
3110
- if (!existsSync8(targetFile)) {
3111
- console.log(chalk8.red(`File not found: ${targetFile}`));
3546
+ if (!existsSync9(targetFile)) {
3547
+ console.log(chalk9.red(`File not found: ${targetFile}`));
3112
3548
  return;
3113
3549
  }
3114
- console.log(chalk8.dim("Card types: summary, summary_large_image, app, player"));
3550
+ console.log(chalk9.dim("Card types: summary, summary_large_image, app, player"));
3115
3551
  const cardType = await prompt2.ask("twitter:card type (default: summary_large_image): ") || "summary_large_image";
3116
3552
  const twitterTitle = await prompt2.ask("twitter:title: ");
3117
3553
  const twitterDescription = await prompt2.ask("twitter:description: ");
@@ -3122,22 +3558,22 @@ async function seoTwitter(options) {
3122
3558
  `<meta name="twitter:description" content="${twitterDescription}">`,
3123
3559
  `<meta name="twitter:image" content="${twitterImage}">`
3124
3560
  ];
3125
- const content = await readFile6(targetFile, "utf-8");
3561
+ const content = await readFile7(targetFile, "utf-8");
3126
3562
  const insertPoint = findHeadInsertionPoint(content);
3127
3563
  if (!insertPoint) {
3128
- console.log(chalk8.yellow("No <head> tag found. Add these tags manually:"));
3129
- tags.forEach((tag) => console.log(chalk8.cyan(` ${tag}`)));
3564
+ console.log(chalk9.yellow("No <head> tag found. Add these tags manually:"));
3565
+ tags.forEach((tag) => console.log(chalk9.cyan(` ${tag}`)));
3130
3566
  return;
3131
3567
  }
3132
- console.log(chalk8.dim("\nTags to add:"));
3133
- tags.forEach((tag) => console.log(chalk8.green(` + ${tag}`)));
3568
+ console.log(chalk9.dim("\nTags to add:"));
3569
+ tags.forEach((tag) => console.log(chalk9.green(` + ${tag}`)));
3134
3570
  const confirm = await prompt2.ask("\nApply changes? (y/N): ");
3135
3571
  if (confirm.toLowerCase() === "y") {
3136
3572
  const newContent = content.slice(0, insertPoint.index) + "\n" + tags.map((tag) => insertPoint.indent + tag).join("\n") + content.slice(insertPoint.index);
3137
- await writeFile6(targetFile, newContent);
3138
- console.log(chalk8.green("\n\u2705 Twitter Card tags added."));
3573
+ await writeFile7(targetFile, newContent);
3574
+ console.log(chalk9.green("\n\u2705 Twitter Card tags added."));
3139
3575
  } else {
3140
- console.log(chalk8.dim("Cancelled."));
3576
+ console.log(chalk9.dim("Cancelled."));
3141
3577
  }
3142
3578
  } finally {
3143
3579
  prompt2.close();
@@ -3161,7 +3597,7 @@ Examples:
3161
3597
  await seoCheck(options);
3162
3598
  process.exit(0);
3163
3599
  } catch (error) {
3164
- console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
3600
+ console.error(chalk9.red("Error:"), error instanceof Error ? error.message : error);
3165
3601
  process.exit(1);
3166
3602
  }
3167
3603
  });
@@ -3170,7 +3606,7 @@ Examples:
3170
3606
  await seoFix(options);
3171
3607
  process.exit(0);
3172
3608
  } catch (error) {
3173
- console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
3609
+ console.error(chalk9.red("Error:"), error instanceof Error ? error.message : error);
3174
3610
  process.exit(1);
3175
3611
  }
3176
3612
  });
@@ -3179,7 +3615,7 @@ Examples:
3179
3615
  await seoOpenGraph(options);
3180
3616
  process.exit(0);
3181
3617
  } catch (error) {
3182
- console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
3618
+ console.error(chalk9.red("Error:"), error instanceof Error ? error.message : error);
3183
3619
  process.exit(1);
3184
3620
  }
3185
3621
  });
@@ -3188,7 +3624,7 @@ Examples:
3188
3624
  await seoTwitter(options);
3189
3625
  process.exit(0);
3190
3626
  } catch (error) {
3191
- console.error(chalk8.red("Error:"), error instanceof Error ? error.message : error);
3627
+ console.error(chalk9.red("Error:"), error instanceof Error ? error.message : error);
3192
3628
  process.exit(1);
3193
3629
  }
3194
3630
  });
@@ -3196,12 +3632,12 @@ Examples:
3196
3632
  }
3197
3633
 
3198
3634
  // src/cli/session.ts
3199
- import chalk9 from "chalk";
3635
+ import chalk10 from "chalk";
3200
3636
  import ora2 from "ora";
3201
3637
  import os from "os";
3202
- import { readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
3203
- import { existsSync as existsSync9 } from "fs";
3204
- import { join as join8 } from "path";
3638
+ import { readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
3639
+ import { existsSync as existsSync10 } from "fs";
3640
+ import { join as join9 } from "path";
3205
3641
  import { createClient as createClient2 } from "@supabase/supabase-js";
3206
3642
  function getSupabaseClient2(accessToken) {
3207
3643
  return createClient2(SUPABASE_URL, SUPABASE_ANON_KEY, {
@@ -3212,45 +3648,45 @@ function getDeviceName() {
3212
3648
  return `${os.hostname()}-${os.platform()}-${os.arch()}`;
3213
3649
  }
3214
3650
  async function getProjectInfo(cwd) {
3215
- const archonConfigPath = join8(cwd, ".archon", "config.yaml");
3216
- const packageJsonPath = join8(cwd, "package.json");
3651
+ const archonConfigPath = join9(cwd, ".archon", "config.yaml");
3652
+ const packageJsonPath = join9(cwd, "package.json");
3217
3653
  let projectName = "Unknown Project";
3218
- if (existsSync9(packageJsonPath)) {
3654
+ if (existsSync10(packageJsonPath)) {
3219
3655
  try {
3220
- const pkg = JSON.parse(await readFile7(packageJsonPath, "utf-8"));
3656
+ const pkg = JSON.parse(await readFile8(packageJsonPath, "utf-8"));
3221
3657
  projectName = pkg.name || projectName;
3222
3658
  } catch {
3223
3659
  }
3224
3660
  }
3225
- if (!existsSync9(archonConfigPath)) {
3661
+ if (!existsSync10(archonConfigPath)) {
3226
3662
  return null;
3227
3663
  }
3228
3664
  return { name: projectName, path: cwd };
3229
3665
  }
3230
3666
  async function getCurrentAtomId(cwd) {
3231
- const stateFile = join8(cwd, ".archon", "state.json");
3232
- if (!existsSync9(stateFile)) return null;
3667
+ const stateFile = join9(cwd, ".archon", "state.json");
3668
+ if (!existsSync10(stateFile)) return null;
3233
3669
  try {
3234
- const state = JSON.parse(await readFile7(stateFile, "utf-8"));
3670
+ const state = JSON.parse(await readFile8(stateFile, "utf-8"));
3235
3671
  return state.currentAtomId || null;
3236
3672
  } catch {
3237
3673
  return null;
3238
3674
  }
3239
3675
  }
3240
3676
  async function getPendingAtoms(cwd) {
3241
- const stateFile = join8(cwd, ".archon", "state.json");
3242
- if (!existsSync9(stateFile)) return [];
3677
+ const stateFile = join9(cwd, ".archon", "state.json");
3678
+ if (!existsSync10(stateFile)) return [];
3243
3679
  try {
3244
- const state = JSON.parse(await readFile7(stateFile, "utf-8"));
3680
+ const state = JSON.parse(await readFile8(stateFile, "utf-8"));
3245
3681
  return state.pendingAtoms || [];
3246
3682
  } catch {
3247
3683
  return [];
3248
3684
  }
3249
3685
  }
3250
3686
  async function getFileContent(path2) {
3251
- if (!existsSync9(path2)) return null;
3687
+ if (!existsSync10(path2)) return null;
3252
3688
  try {
3253
- return await readFile7(path2, "utf-8");
3689
+ return await readFile8(path2, "utf-8");
3254
3690
  } catch {
3255
3691
  return null;
3256
3692
  }
@@ -3277,8 +3713,8 @@ async function saveSession(name) {
3277
3713
  }
3278
3714
  const currentAtomId = await getCurrentAtomId(cwd);
3279
3715
  const pendingAtoms = await getPendingAtoms(cwd);
3280
- const progressSnapshot = await getFileContent(join8(cwd, "progress.txt"));
3281
- const architectureSnapshot = await getFileContent(join8(cwd, "ARCHITECTURE.md"));
3716
+ const progressSnapshot = await getFileContent(join9(cwd, "progress.txt"));
3717
+ const architectureSnapshot = await getFileContent(join9(cwd, "ARCHITECTURE.md"));
3282
3718
  const sessionData = {
3283
3719
  user_id: profile.id,
3284
3720
  project_name: name || projectInfo.name,
@@ -3295,13 +3731,13 @@ async function saveSession(name) {
3295
3731
  spinner.fail(`Failed to save session: ${error.message}`);
3296
3732
  return;
3297
3733
  }
3298
- spinner.succeed(chalk9.green("Session saved!"));
3734
+ spinner.succeed(chalk10.green("Session saved!"));
3299
3735
  console.log();
3300
- console.log(` ID: ${chalk9.cyan(session.id)}`);
3736
+ console.log(` ID: ${chalk10.cyan(session.id)}`);
3301
3737
  console.log(` Project: ${session.project_name}`);
3302
3738
  console.log(` Device: ${session.last_device}`);
3303
3739
  console.log();
3304
- console.log(chalk9.dim(" Resume on another device: archon session resume " + session.id));
3740
+ console.log(chalk10.dim(" Resume on another device: archon session resume " + session.id));
3305
3741
  console.log();
3306
3742
  } catch (err) {
3307
3743
  spinner.fail("Error saving session");
@@ -3329,23 +3765,23 @@ async function listSessions() {
3329
3765
  }
3330
3766
  spinner.stop();
3331
3767
  if (!sessions || sessions.length === 0) {
3332
- console.log(chalk9.yellow("\nNo saved sessions found.\n"));
3333
- console.log(chalk9.dim(" Save a session: archon session save [name]\n"));
3768
+ console.log(chalk10.yellow("\nNo saved sessions found.\n"));
3769
+ console.log(chalk10.dim(" Save a session: archon session save [name]\n"));
3334
3770
  return;
3335
3771
  }
3336
3772
  console.log();
3337
- console.log(chalk9.bold("\u{1F4C2} Saved Sessions"));
3773
+ console.log(chalk10.bold("\u{1F4C2} Saved Sessions"));
3338
3774
  console.log();
3339
3775
  for (const session of sessions) {
3340
3776
  const date = new Date(session.updated_at).toLocaleDateString();
3341
- const atomInfo = session.current_atom_id ? chalk9.dim(` (atom: ${session.current_atom_id})`) : "";
3777
+ const atomInfo = session.current_atom_id ? chalk10.dim(` (atom: ${session.current_atom_id})`) : "";
3342
3778
  console.log(
3343
- ` ${chalk9.cyan(session.id.slice(0, 8))} ${session.project_name}${atomInfo}`
3779
+ ` ${chalk10.cyan(session.id.slice(0, 8))} ${session.project_name}${atomInfo}`
3344
3780
  );
3345
- console.log(chalk9.dim(` ${date} from ${session.last_device || "unknown device"}`));
3781
+ console.log(chalk10.dim(` ${date} from ${session.last_device || "unknown device"}`));
3346
3782
  console.log();
3347
3783
  }
3348
- console.log(chalk9.dim(" Resume: archon session resume <id>\n"));
3784
+ console.log(chalk10.dim(" Resume: archon session resume <id>\n"));
3349
3785
  } catch (err) {
3350
3786
  spinner.fail("Error fetching sessions");
3351
3787
  console.error(err);
@@ -3372,30 +3808,30 @@ async function resumeSession(sessionId) {
3372
3808
  return;
3373
3809
  }
3374
3810
  const session = sessions[0];
3375
- const stateFile = join8(cwd, ".archon", "state.json");
3811
+ const stateFile = join9(cwd, ".archon", "state.json");
3376
3812
  const state = {
3377
3813
  currentAtomId: session.current_atom_id,
3378
3814
  pendingAtoms: session.pending_atoms,
3379
3815
  resumedFrom: session.id,
3380
3816
  resumedAt: (/* @__PURE__ */ new Date()).toISOString()
3381
3817
  };
3382
- await writeFile7(stateFile, JSON.stringify(state, null, 2));
3818
+ await writeFile8(stateFile, JSON.stringify(state, null, 2));
3383
3819
  if (session.progress_snapshot) {
3384
- const progressPath = join8(cwd, "progress.txt");
3385
- await writeFile7(progressPath, session.progress_snapshot);
3820
+ const progressPath = join9(cwd, "progress.txt");
3821
+ await writeFile8(progressPath, session.progress_snapshot);
3386
3822
  }
3387
3823
  if (session.architecture_snapshot) {
3388
- const archPath = join8(cwd, "ARCHITECTURE.md");
3389
- await writeFile7(archPath, session.architecture_snapshot);
3824
+ const archPath = join9(cwd, "ARCHITECTURE.md");
3825
+ await writeFile8(archPath, session.architecture_snapshot);
3390
3826
  }
3391
3827
  await supabase.from("sessions").update({ last_device: getDeviceName(), updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", session.id);
3392
- spinner.succeed(chalk9.green("Session resumed!"));
3828
+ spinner.succeed(chalk10.green("Session resumed!"));
3393
3829
  console.log();
3394
3830
  console.log(` Project: ${session.project_name}`);
3395
3831
  console.log(` Current Atom: ${session.current_atom_id || "none"}`);
3396
3832
  console.log(` Pending: ${session.pending_atoms.length} atoms`);
3397
3833
  console.log();
3398
- console.log(chalk9.dim(" Continue working: archon start"));
3834
+ console.log(chalk10.dim(" Continue working: archon start"));
3399
3835
  console.log();
3400
3836
  } catch (err) {
3401
3837
  spinner.fail("Error resuming session");
@@ -3411,12 +3847,12 @@ async function syncSession() {
3411
3847
  spinner.fail("Not logged in. Run: archon login");
3412
3848
  return;
3413
3849
  }
3414
- const stateFile = join8(cwd, ".archon", "state.json");
3415
- if (!existsSync9(stateFile)) {
3850
+ const stateFile = join9(cwd, ".archon", "state.json");
3851
+ if (!existsSync10(stateFile)) {
3416
3852
  spinner.info("No active session to sync");
3417
3853
  return;
3418
3854
  }
3419
- const state = JSON.parse(await readFile7(stateFile, "utf-8"));
3855
+ const state = JSON.parse(await readFile8(stateFile, "utf-8"));
3420
3856
  if (!state.resumedFrom) {
3421
3857
  spinner.info('Session was not resumed from cloud - use "archon session save" to create one');
3422
3858
  return;
@@ -3424,8 +3860,8 @@ async function syncSession() {
3424
3860
  const supabase = getSupabaseClient2(config.accessToken);
3425
3861
  const currentAtomId = await getCurrentAtomId(cwd);
3426
3862
  const pendingAtoms = await getPendingAtoms(cwd);
3427
- const progressSnapshot = await getFileContent(join8(cwd, "progress.txt"));
3428
- const architectureSnapshot = await getFileContent(join8(cwd, "ARCHITECTURE.md"));
3863
+ const progressSnapshot = await getFileContent(join9(cwd, "progress.txt"));
3864
+ const architectureSnapshot = await getFileContent(join9(cwd, "ARCHITECTURE.md"));
3429
3865
  const { error } = await supabase.from("sessions").update({
3430
3866
  current_atom_id: currentAtomId,
3431
3867
  pending_atoms: pendingAtoms,
@@ -3438,7 +3874,7 @@ async function syncSession() {
3438
3874
  spinner.fail(`Failed to sync: ${error.message}`);
3439
3875
  return;
3440
3876
  }
3441
- spinner.succeed(chalk9.green("Session synced to cloud"));
3877
+ spinner.succeed(chalk10.green("Session synced to cloud"));
3442
3878
  } catch (err) {
3443
3879
  spinner.fail("Error syncing session");
3444
3880
  console.error(err);
@@ -3446,66 +3882,66 @@ async function syncSession() {
3446
3882
  }
3447
3883
 
3448
3884
  // src/cli/deploy.ts
3449
- import chalk10 from "chalk";
3450
- import { existsSync as existsSync10 } from "fs";
3451
- import { join as join9 } from "path";
3452
- import { execSync } from "child_process";
3885
+ import chalk11 from "chalk";
3886
+ import { existsSync as existsSync11 } from "fs";
3887
+ import { join as join10 } from "path";
3888
+ import { execSync as execSync2 } from "child_process";
3453
3889
  function detectPlatform(cwd) {
3454
- if (existsSync10(join9(cwd, "fly.toml"))) return "fly";
3455
- if (existsSync10(join9(cwd, "vercel.json"))) return "vercel";
3456
- if (existsSync10(join9(cwd, "netlify.toml"))) return "netlify";
3457
- if (existsSync10(join9(cwd, "railway.json"))) return "railway";
3458
- if (existsSync10(join9(cwd, "render.yaml"))) return "render";
3459
- if (existsSync10(join9(cwd, "Dockerfile"))) return "fly";
3890
+ if (existsSync11(join10(cwd, "fly.toml"))) return "fly";
3891
+ if (existsSync11(join10(cwd, "vercel.json"))) return "vercel";
3892
+ if (existsSync11(join10(cwd, "netlify.toml"))) return "netlify";
3893
+ if (existsSync11(join10(cwd, "railway.json"))) return "railway";
3894
+ if (existsSync11(join10(cwd, "render.yaml"))) return "render";
3895
+ if (existsSync11(join10(cwd, "Dockerfile"))) return "fly";
3460
3896
  return "unknown";
3461
3897
  }
3462
3898
  async function deploy(options) {
3463
3899
  const cwd = process.cwd();
3464
- console.log(chalk10.blue("Running pre-deploy checks..."));
3900
+ console.log(chalk11.blue("Running pre-deploy checks..."));
3465
3901
  const platform = options.platform ?? detectPlatform(cwd);
3466
- console.log(chalk10.dim(`Detected platform: ${platform}`));
3902
+ console.log(chalk11.dim(`Detected platform: ${platform}`));
3467
3903
  if (options.dryRun) {
3468
- console.log(chalk10.dim("Dry run mode - would deploy to:"), platform);
3904
+ console.log(chalk11.dim("Dry run mode - would deploy to:"), platform);
3469
3905
  return;
3470
3906
  }
3471
3907
  switch (platform) {
3472
3908
  case "fly":
3473
- console.log(chalk10.blue("Deploying to Fly.io..."));
3474
- execSync("fly deploy", { cwd, stdio: "inherit" });
3909
+ console.log(chalk11.blue("Deploying to Fly.io..."));
3910
+ execSync2("fly deploy", { cwd, stdio: "inherit" });
3475
3911
  break;
3476
3912
  case "vercel": {
3477
- console.log(chalk10.blue("Deploying to Vercel..."));
3913
+ console.log(chalk11.blue("Deploying to Vercel..."));
3478
3914
  const cmd = options.preview ? "vercel" : "vercel --prod";
3479
- execSync(cmd, { cwd, stdio: "inherit" });
3915
+ execSync2(cmd, { cwd, stdio: "inherit" });
3480
3916
  break;
3481
3917
  }
3482
3918
  case "netlify": {
3483
- console.log(chalk10.blue("Deploying to Netlify..."));
3919
+ console.log(chalk11.blue("Deploying to Netlify..."));
3484
3920
  const netlifyCmd = options.preview ? "netlify deploy" : "netlify deploy --prod";
3485
- execSync(netlifyCmd, { cwd, stdio: "inherit" });
3921
+ execSync2(netlifyCmd, { cwd, stdio: "inherit" });
3486
3922
  break;
3487
3923
  }
3488
3924
  case "railway":
3489
- console.log(chalk10.blue("Deploying to Railway..."));
3490
- execSync("railway up", { cwd, stdio: "inherit" });
3925
+ console.log(chalk11.blue("Deploying to Railway..."));
3926
+ execSync2("railway up", { cwd, stdio: "inherit" });
3491
3927
  break;
3492
3928
  case "render":
3493
- console.log(chalk10.blue("Deploying to Render..."));
3494
- console.log(chalk10.yellow("Render deploys via git push. Push to your connected branch."));
3929
+ console.log(chalk11.blue("Deploying to Render..."));
3930
+ console.log(chalk11.yellow("Render deploys via git push. Push to your connected branch."));
3495
3931
  break;
3496
3932
  default:
3497
- console.log(chalk10.yellow("Platform not detected. Please specify with --platform"));
3498
- console.log(chalk10.dim("Supported: fly, vercel, netlify, railway, render"));
3933
+ console.log(chalk11.yellow("Platform not detected. Please specify with --platform"));
3934
+ console.log(chalk11.dim("Supported: fly, vercel, netlify, railway, render"));
3499
3935
  }
3500
3936
  }
3501
3937
 
3502
3938
  // src/cli/index-cmd.ts
3503
- import chalk11 from "chalk";
3939
+ import chalk12 from "chalk";
3504
3940
 
3505
3941
  // src/core/indexing/local.ts
3506
- import { existsSync as existsSync11, mkdirSync } from "fs";
3507
- import { readFile as readFile8 } from "fs/promises";
3508
- import { join as join10, extname } from "path";
3942
+ import { existsSync as existsSync12, mkdirSync } from "fs";
3943
+ import { readFile as readFile9 } from "fs/promises";
3944
+ import { join as join11, extname } from "path";
3509
3945
  import Database from "better-sqlite3";
3510
3946
  var CHUNK_SIZE = 1e3;
3511
3947
  var CHUNK_OVERLAP = 200;
@@ -3552,11 +3988,11 @@ var LocalIndexer = class {
3552
3988
  };
3553
3989
  }
3554
3990
  async init(cwd) {
3555
- const archonDir = join10(cwd, ".archon");
3556
- if (!existsSync11(archonDir)) {
3991
+ const archonDir = join11(cwd, ".archon");
3992
+ if (!existsSync12(archonDir)) {
3557
3993
  mkdirSync(archonDir, { recursive: true });
3558
3994
  }
3559
- this.db = new Database(join10(cwd, this.config.dbPath));
3995
+ this.db = new Database(join11(cwd, this.config.dbPath));
3560
3996
  this.db.exec(`
3561
3997
  CREATE TABLE IF NOT EXISTS embeddings (
3562
3998
  id INTEGER PRIMARY KEY,
@@ -3606,11 +4042,11 @@ var LocalIndexer = class {
3606
4042
  if (!this.isIndexableFile(filePath)) {
3607
4043
  return 0;
3608
4044
  }
3609
- const fullPath = join10(cwd, filePath);
3610
- if (!existsSync11(fullPath)) {
4045
+ const fullPath = join11(cwd, filePath);
4046
+ if (!existsSync12(fullPath)) {
3611
4047
  return 0;
3612
4048
  }
3613
- const content = await readFile8(fullPath, "utf-8");
4049
+ const content = await readFile9(fullPath, "utf-8");
3614
4050
  const chunks = this.chunkText(content);
3615
4051
  const deleteStmt = this.db.prepare("DELETE FROM embeddings WHERE file_path = ?");
3616
4052
  deleteStmt.run(filePath);
@@ -3686,16 +4122,287 @@ var LocalIndexer = class {
3686
4122
  }
3687
4123
  };
3688
4124
 
4125
+ // src/core/indexing/cloud.ts
4126
+ import { createClient as createClient3 } from "@supabase/supabase-js";
4127
+ import { readFile as readFile10 } from "fs/promises";
4128
+ import { existsSync as existsSync13 } from "fs";
4129
+ import { join as join12, extname as extname2 } from "path";
4130
+ import { createHash } from "crypto";
4131
+ var CHUNK_SIZE2 = 1e3;
4132
+ var CHUNK_OVERLAP2 = 200;
4133
+ var INDEXABLE_EXTENSIONS2 = /* @__PURE__ */ new Set([
4134
+ ".ts",
4135
+ ".tsx",
4136
+ ".js",
4137
+ ".jsx",
4138
+ ".py",
4139
+ ".rb",
4140
+ ".go",
4141
+ ".rs",
4142
+ ".java",
4143
+ ".c",
4144
+ ".cpp",
4145
+ ".h",
4146
+ ".hpp",
4147
+ ".cs",
4148
+ ".swift",
4149
+ ".kt",
4150
+ ".scala",
4151
+ ".md",
4152
+ ".mdx",
4153
+ ".txt",
4154
+ ".json",
4155
+ ".yaml",
4156
+ ".yml",
4157
+ ".toml",
4158
+ ".html",
4159
+ ".css",
4160
+ ".scss",
4161
+ ".less",
4162
+ ".vue",
4163
+ ".svelte"
4164
+ ]);
4165
+ var CloudIndexer = class {
4166
+ config;
4167
+ client;
4168
+ userId = null;
4169
+ constructor(config) {
4170
+ this.config = config;
4171
+ this.client = createClient3(config.supabaseUrl, config.supabaseKey);
4172
+ }
4173
+ /**
4174
+ * Set the authenticated user ID
4175
+ */
4176
+ setUserId(userId) {
4177
+ this.userId = userId;
4178
+ }
4179
+ /**
4180
+ * Generate embedding using OpenAI API
4181
+ */
4182
+ async embedText(text) {
4183
+ if (this.config.embeddingProvider === "openai") {
4184
+ return this.embedWithOpenAI(text);
4185
+ }
4186
+ throw new Error(`Unsupported embedding provider: ${this.config.embeddingProvider}`);
4187
+ }
4188
+ async embedWithOpenAI(text) {
4189
+ const response = await fetch("https://api.openai.com/v1/embeddings", {
4190
+ method: "POST",
4191
+ headers: {
4192
+ "Authorization": `Bearer ${this.config.embeddingApiKey}`,
4193
+ "Content-Type": "application/json"
4194
+ },
4195
+ body: JSON.stringify({
4196
+ model: "text-embedding-ada-002",
4197
+ input: text.slice(0, 8e3)
4198
+ // Limit input size
4199
+ })
4200
+ });
4201
+ if (!response.ok) {
4202
+ const error = await response.json();
4203
+ throw new Error(`OpenAI embedding failed: ${error.error?.message ?? response.statusText}`);
4204
+ }
4205
+ const data = await response.json();
4206
+ const embedding = data.data[0]?.embedding;
4207
+ if (!embedding) {
4208
+ throw new Error("No embedding returned from OpenAI");
4209
+ }
4210
+ return embedding;
4211
+ }
4212
+ /**
4213
+ * Chunk text into smaller pieces for embedding
4214
+ */
4215
+ chunkText(text, filePath) {
4216
+ const chunks = [];
4217
+ const header = `File: ${filePath}
4218
+
4219
+ `;
4220
+ let start2 = 0;
4221
+ let index = 0;
4222
+ while (start2 < text.length) {
4223
+ const end = Math.min(start2 + CHUNK_SIZE2, text.length);
4224
+ const chunkText = index === 0 ? header + text.slice(start2, end) : text.slice(start2, end);
4225
+ if (chunkText.trim().length > 0) {
4226
+ chunks.push({ text: chunkText, index });
4227
+ index++;
4228
+ }
4229
+ start2 += CHUNK_SIZE2 - CHUNK_OVERLAP2;
4230
+ }
4231
+ return chunks;
4232
+ }
4233
+ /**
4234
+ * Check if file should be indexed
4235
+ */
4236
+ isIndexableFile(filePath) {
4237
+ const ext = extname2(filePath).toLowerCase();
4238
+ return INDEXABLE_EXTENSIONS2.has(ext);
4239
+ }
4240
+ /**
4241
+ * Compute file hash for change detection
4242
+ */
4243
+ async computeFileHash(content) {
4244
+ return createHash("sha256").update(content).digest("hex").slice(0, 16);
4245
+ }
4246
+ /**
4247
+ * Index a single file
4248
+ */
4249
+ async indexFile(cwd, filePath) {
4250
+ if (!this.userId) {
4251
+ throw new Error("User ID not set. Call setUserId() first.");
4252
+ }
4253
+ if (!this.isIndexableFile(filePath)) {
4254
+ return 0;
4255
+ }
4256
+ const fullPath = join12(cwd, filePath);
4257
+ if (!existsSync13(fullPath)) {
4258
+ return 0;
4259
+ }
4260
+ const content = await readFile10(fullPath, "utf-8");
4261
+ const fileHash = await this.computeFileHash(content);
4262
+ const { data: existing } = await this.client.from("code_embeddings").select("file_hash").eq("user_id", this.userId).eq("project_id", this.config.projectId).eq("file_path", filePath).eq("chunk_index", 0).single();
4263
+ if (existing && existing.file_hash === fileHash) {
4264
+ return 0;
4265
+ }
4266
+ await this.client.from("code_embeddings").delete().eq("user_id", this.userId).eq("project_id", this.config.projectId).eq("file_path", filePath);
4267
+ const chunks = this.chunkText(content, filePath);
4268
+ for (const chunk of chunks) {
4269
+ const embedding = await this.embedText(chunk.text);
4270
+ const embeddingStr = `[${embedding.join(",")}]`;
4271
+ await this.client.from("code_embeddings").insert({
4272
+ user_id: this.userId,
4273
+ project_id: this.config.projectId,
4274
+ file_path: filePath,
4275
+ chunk_index: chunk.index,
4276
+ chunk_text: chunk.text,
4277
+ embedding: embeddingStr,
4278
+ file_hash: fileHash
4279
+ });
4280
+ }
4281
+ return chunks.length;
4282
+ }
4283
+ /**
4284
+ * Search for similar code
4285
+ */
4286
+ async search(query, limit = 10) {
4287
+ if (!this.userId) {
4288
+ throw new Error("User ID not set. Call setUserId() first.");
4289
+ }
4290
+ const queryEmbedding = await this.embedText(query);
4291
+ const embeddingStr = `[${queryEmbedding.join(",")}]`;
4292
+ const { data, error } = await this.client.rpc("search_code_embeddings", {
4293
+ p_user_id: this.userId,
4294
+ p_project_id: this.config.projectId,
4295
+ p_query_embedding: embeddingStr,
4296
+ p_limit: limit
4297
+ });
4298
+ if (error) {
4299
+ throw new Error(`Search failed: ${error.message}`);
4300
+ }
4301
+ return (data ?? []).map((row) => ({
4302
+ file: row.file_path,
4303
+ text: row.chunk_text,
4304
+ score: row.similarity
4305
+ }));
4306
+ }
4307
+ /**
4308
+ * Get indexing status for project
4309
+ */
4310
+ async getStatus() {
4311
+ if (!this.userId) {
4312
+ throw new Error("User ID not set. Call setUserId() first.");
4313
+ }
4314
+ const { data: fileCount } = await this.client.from("code_embeddings").select("file_path", { count: "exact", head: true }).eq("user_id", this.userId).eq("project_id", this.config.projectId);
4315
+ const { data: chunkCount } = await this.client.from("code_embeddings").select("id", { count: "exact", head: true }).eq("user_id", this.userId).eq("project_id", this.config.projectId);
4316
+ const { data: lastUpdated } = await this.client.from("code_embeddings").select("updated_at").eq("user_id", this.userId).eq("project_id", this.config.projectId).order("updated_at", { ascending: false }).limit(1).single();
4317
+ const { data: job } = await this.client.from("indexing_jobs").select("status").eq("user_id", this.userId).eq("project_id", this.config.projectId).order("created_at", { ascending: false }).limit(1).single();
4318
+ return {
4319
+ projectId: this.config.projectId,
4320
+ fileCount: fileCount?.count ?? 0,
4321
+ chunkCount: chunkCount?.count ?? 0,
4322
+ lastUpdated: lastUpdated?.updated_at ?? null,
4323
+ jobStatus: job?.status
4324
+ };
4325
+ }
4326
+ /**
4327
+ * Remove all embeddings for this project
4328
+ */
4329
+ async clearProject() {
4330
+ if (!this.userId) {
4331
+ throw new Error("User ID not set. Call setUserId() first.");
4332
+ }
4333
+ await this.client.from("code_embeddings").delete().eq("user_id", this.userId).eq("project_id", this.config.projectId);
4334
+ }
4335
+ /**
4336
+ * Remove a single file from the index
4337
+ */
4338
+ async removeFile(filePath) {
4339
+ if (!this.userId) {
4340
+ throw new Error("User ID not set. Call setUserId() first.");
4341
+ }
4342
+ await this.client.from("code_embeddings").delete().eq("user_id", this.userId).eq("project_id", this.config.projectId).eq("file_path", filePath);
4343
+ }
4344
+ };
4345
+
3689
4346
  // src/cli/index-cmd.ts
3690
4347
  import { glob as glob4 } from "glob";
3691
- import { join as join11 } from "path";
4348
+ import { join as join13, basename } from "path";
4349
+ async function getCloudIndexer(cwd) {
4350
+ const config = await loadConfig();
4351
+ const authToken = getAuthToken(config);
4352
+ if (!authToken) {
4353
+ console.error(chalk12.red('Not authenticated. Run "archon login" first.'));
4354
+ return null;
4355
+ }
4356
+ const openaiKey = process.env["OPENAI_API_KEY"];
4357
+ if (!openaiKey) {
4358
+ console.error(chalk12.red("OPENAI_API_KEY environment variable not set."));
4359
+ console.log(chalk12.dim("Cloud indexing requires an OpenAI API key for embeddings."));
4360
+ console.log(chalk12.dim("Set it with: export OPENAI_API_KEY=sk-..."));
4361
+ return null;
4362
+ }
4363
+ const projectId = basename(cwd);
4364
+ const indexer = new CloudIndexer({
4365
+ supabaseUrl: SUPABASE_URL,
4366
+ supabaseKey: SUPABASE_ANON_KEY,
4367
+ embeddingProvider: "openai",
4368
+ embeddingApiKey: openaiKey,
4369
+ projectId
4370
+ });
4371
+ const { createClient: createClient4 } = await import("@supabase/supabase-js");
4372
+ const client = createClient4(SUPABASE_URL, SUPABASE_ANON_KEY, {
4373
+ global: { headers: { Authorization: `Bearer ${authToken}` } }
4374
+ });
4375
+ const { data: { user } } = await client.auth.getUser();
4376
+ if (!user) {
4377
+ console.error(chalk12.red("Failed to get user. Try logging in again."));
4378
+ return null;
4379
+ }
4380
+ const { data: profile } = await client.from("user_profiles").select("id").eq("auth_id", user.id).single();
4381
+ if (!profile) {
4382
+ console.error(chalk12.red("User profile not found."));
4383
+ return null;
4384
+ }
4385
+ indexer.setUserId(profile.id);
4386
+ return indexer;
4387
+ }
3692
4388
  async function indexInit(options) {
3693
4389
  const cwd = process.cwd();
3694
4390
  if (options.cloud) {
3695
- console.log(chalk11.yellow("Cloud indexing is not yet implemented. Use --local for Ollama-based indexing."));
4391
+ console.log(chalk12.blue("Initializing cloud semantic index..."));
4392
+ const indexer = await getCloudIndexer(cwd);
4393
+ if (!indexer) return;
4394
+ try {
4395
+ const status2 = await indexer.getStatus();
4396
+ console.log(chalk12.green("\u2713 Cloud indexing configured"));
4397
+ console.log(chalk12.green(`\u2713 Project ID: ${status2.projectId}`));
4398
+ console.log(chalk12.dim("\nRun `archon index update --cloud` to index your codebase."));
4399
+ } catch (error) {
4400
+ console.error(chalk12.red(`Failed to initialize cloud index: ${error instanceof Error ? error.message : String(error)}`));
4401
+ process.exit(1);
4402
+ }
3696
4403
  return;
3697
4404
  }
3698
- console.log(chalk11.blue("Initializing local semantic index..."));
4405
+ console.log(chalk12.blue("Initializing local semantic index..."));
3699
4406
  try {
3700
4407
  const indexer = new LocalIndexer();
3701
4408
  await indexer.init(cwd);
@@ -3703,24 +4410,67 @@ async function indexInit(options) {
3703
4410
  if (!response.ok) {
3704
4411
  throw new Error("Ollama not responding");
3705
4412
  }
3706
- console.log(chalk11.green("\u2713 Ollama connection verified"));
3707
- console.log(chalk11.green("\u2713 Index database created at .archon/index.db"));
3708
- console.log(chalk11.dim("\nRun `archon index update` to index your codebase."));
4413
+ console.log(chalk12.green("\u2713 Ollama connection verified"));
4414
+ console.log(chalk12.green("\u2713 Index database created at .archon/index.db"));
4415
+ console.log(chalk12.dim("\nRun `archon index update` to index your codebase."));
3709
4416
  indexer.close();
3710
4417
  } catch (error) {
3711
4418
  if (error instanceof Error && error.message.includes("Ollama")) {
3712
- console.log(chalk11.red("\n\u2717 Ollama is not running"));
3713
- console.log(chalk11.dim("Start Ollama with: ollama serve"));
3714
- console.log(chalk11.dim("Then pull the embedding model: ollama pull nomic-embed-text"));
4419
+ console.log(chalk12.red("\n\u2717 Ollama is not running"));
4420
+ console.log(chalk12.dim("Start Ollama with: ollama serve"));
4421
+ console.log(chalk12.dim("Then pull the embedding model: ollama pull nomic-embed-text"));
4422
+ console.log(chalk12.dim("\nOr use cloud indexing: archon index init --cloud"));
3715
4423
  } else {
3716
- console.error(chalk11.red(`Failed to initialize index: ${error instanceof Error ? error.message : String(error)}`));
4424
+ console.error(chalk12.red(`Failed to initialize index: ${error instanceof Error ? error.message : String(error)}`));
3717
4425
  }
3718
4426
  process.exit(1);
3719
4427
  }
3720
4428
  }
3721
- async function indexUpdate() {
4429
+ async function indexUpdate(options) {
3722
4430
  const cwd = process.cwd();
3723
- console.log(chalk11.blue("Updating semantic index..."));
4431
+ if (options?.cloud) {
4432
+ console.log(chalk12.blue("Updating cloud semantic index..."));
4433
+ const indexer = await getCloudIndexer(cwd);
4434
+ if (!indexer) return;
4435
+ try {
4436
+ const files = await glob4("**/*.{ts,tsx,js,jsx,py,rb,go,rs,java,md,json,yaml,yml}", {
4437
+ cwd,
4438
+ ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
4439
+ });
4440
+ console.log(chalk12.dim(`Found ${files.length} files to index...`));
4441
+ console.log(chalk12.dim("This may take a few minutes and will use OpenAI API credits.\n"));
4442
+ let totalChunks = 0;
4443
+ let indexedFiles = 0;
4444
+ let skippedFiles = 0;
4445
+ for (let i = 0; i < files.length; i++) {
4446
+ const file = files[i];
4447
+ if (!file) continue;
4448
+ process.stdout.write(`\r${chalk12.dim(`[${i + 1}/${files.length}] ${file.slice(0, 45).padEnd(45)}`)}`);
4449
+ try {
4450
+ const chunks = await indexer.indexFile(cwd, file);
4451
+ if (chunks > 0) {
4452
+ totalChunks += chunks;
4453
+ indexedFiles++;
4454
+ } else {
4455
+ skippedFiles++;
4456
+ }
4457
+ } catch (error) {
4458
+ console.log(`
4459
+ ${chalk12.yellow(`\u26A0 Skipped ${file}: ${error instanceof Error ? error.message : "Unknown error"}`)}`);
4460
+ }
4461
+ }
4462
+ console.log("\r" + " ".repeat(70));
4463
+ console.log(chalk12.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
4464
+ if (skippedFiles > 0) {
4465
+ console.log(chalk12.dim(` Skipped ${skippedFiles} unchanged files`));
4466
+ }
4467
+ } catch (error) {
4468
+ console.error(chalk12.red(`Failed to update cloud index: ${error instanceof Error ? error.message : String(error)}`));
4469
+ process.exit(1);
4470
+ }
4471
+ return;
4472
+ }
4473
+ console.log(chalk12.blue("Updating local semantic index..."));
3724
4474
  try {
3725
4475
  const indexer = new LocalIndexer();
3726
4476
  await indexer.init(cwd);
@@ -3728,11 +4478,12 @@ async function indexUpdate() {
3728
4478
  cwd,
3729
4479
  ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
3730
4480
  });
3731
- console.log(chalk11.dim(`Found ${files.length} files to index...`));
4481
+ console.log(chalk12.dim(`Found ${files.length} files to index...`));
3732
4482
  let totalChunks = 0;
3733
4483
  let indexedFiles = 0;
3734
4484
  for (const file of files) {
3735
- process.stdout.write(`\r${chalk11.dim(`Indexing: ${file.slice(0, 50).padEnd(50)}`)}`);
4485
+ if (!file) continue;
4486
+ process.stdout.write(`\r${chalk12.dim(`Indexing: ${file.slice(0, 50).padEnd(50)}`)}`);
3736
4487
  const chunks = await indexer.indexFile(cwd, file);
3737
4488
  if (chunks > 0) {
3738
4489
  totalChunks += chunks;
@@ -3740,54 +4491,211 @@ async function indexUpdate() {
3740
4491
  }
3741
4492
  }
3742
4493
  console.log("\r" + " ".repeat(60));
3743
- console.log(chalk11.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
4494
+ console.log(chalk12.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
3744
4495
  indexer.close();
3745
4496
  } catch (error) {
3746
- console.error(chalk11.red(`Failed to update index: ${error instanceof Error ? error.message : String(error)}`));
4497
+ console.error(chalk12.red(`Failed to update index: ${error instanceof Error ? error.message : String(error)}`));
3747
4498
  process.exit(1);
3748
4499
  }
3749
4500
  }
3750
- async function indexSearch(query) {
4501
+ async function indexSearch(query, options) {
3751
4502
  const cwd = process.cwd();
4503
+ if (options?.cloud) {
4504
+ const indexer = await getCloudIndexer(cwd);
4505
+ if (!indexer) return;
4506
+ try {
4507
+ console.log(chalk12.dim("Searching cloud index..."));
4508
+ const results = await indexer.search(query, 10);
4509
+ if (results.length === 0) {
4510
+ console.log(chalk12.yellow("\nNo results found."));
4511
+ console.log(chalk12.dim("Try running `archon index update --cloud` first."));
4512
+ } else {
4513
+ console.log(chalk12.blue(`
4514
+ Top ${results.length} results for: "${query}"
4515
+ `));
4516
+ for (const result of results) {
4517
+ const score = (result.score * 100).toFixed(1);
4518
+ console.log(chalk12.green(`[${score}%] ${result.file}`));
4519
+ const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
4520
+ console.log(chalk12.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
4521
+ console.log();
4522
+ }
4523
+ }
4524
+ } catch (error) {
4525
+ console.error(chalk12.red(`Cloud search failed: ${error instanceof Error ? error.message : String(error)}`));
4526
+ process.exit(1);
4527
+ }
4528
+ return;
4529
+ }
3752
4530
  try {
3753
4531
  const indexer = new LocalIndexer();
3754
4532
  await indexer.init(cwd);
3755
4533
  const results = await indexer.search(query, 10);
3756
4534
  if (results.length === 0) {
3757
- console.log(chalk11.yellow("No results found."));
3758
- console.log(chalk11.dim("Try running `archon index update` first."));
4535
+ console.log(chalk12.yellow("No results found."));
4536
+ console.log(chalk12.dim("Try running `archon index update` first."));
3759
4537
  } else {
3760
- console.log(chalk11.blue(`
4538
+ console.log(chalk12.blue(`
3761
4539
  Top ${results.length} results for: "${query}"
3762
4540
  `));
3763
4541
  for (const result of results) {
3764
4542
  const score = (result.score * 100).toFixed(1);
3765
- console.log(chalk11.green(`[${score}%] ${result.file}`));
4543
+ console.log(chalk12.green(`[${score}%] ${result.file}`));
3766
4544
  const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
3767
- console.log(chalk11.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
4545
+ console.log(chalk12.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
3768
4546
  console.log();
3769
4547
  }
3770
4548
  }
3771
4549
  indexer.close();
3772
4550
  } catch (error) {
3773
- console.error(chalk11.red(`Search failed: ${error instanceof Error ? error.message : String(error)}`));
4551
+ console.error(chalk12.red(`Search failed: ${error instanceof Error ? error.message : String(error)}`));
3774
4552
  process.exit(1);
3775
4553
  }
3776
4554
  }
3777
- async function indexStatus() {
4555
+ async function indexStatus(options) {
3778
4556
  const cwd = process.cwd();
4557
+ if (options?.cloud) {
4558
+ const indexer = await getCloudIndexer(cwd);
4559
+ if (!indexer) return;
4560
+ try {
4561
+ const status2 = await indexer.getStatus();
4562
+ console.log(chalk12.blue("\nCloud Semantic Index Status\n"));
4563
+ console.log(` Project ID: ${chalk12.green(status2.projectId)}`);
4564
+ console.log(` Files indexed: ${chalk12.green(status2.fileCount)}`);
4565
+ console.log(` Total chunks: ${chalk12.green(status2.chunkCount)}`);
4566
+ console.log(` Last updated: ${status2.lastUpdated ? chalk12.dim(status2.lastUpdated) : chalk12.yellow("Never")}`);
4567
+ if (status2.jobStatus) {
4568
+ console.log(` Job status: ${chalk12.dim(status2.jobStatus)}`);
4569
+ }
4570
+ console.log(` Storage: ${chalk12.dim("Supabase pgvector")}`);
4571
+ } catch (error) {
4572
+ console.error(chalk12.red(`Failed to get cloud status: ${error instanceof Error ? error.message : String(error)}`));
4573
+ process.exit(1);
4574
+ }
4575
+ return;
4576
+ }
3779
4577
  try {
3780
4578
  const indexer = new LocalIndexer();
3781
4579
  await indexer.init(cwd);
3782
4580
  const status2 = await indexer.getStatus();
3783
- console.log(chalk11.blue("\nSemantic Index Status\n"));
3784
- console.log(` Files indexed: ${chalk11.green(status2.fileCount)}`);
3785
- console.log(` Total chunks: ${chalk11.green(status2.chunkCount)}`);
3786
- console.log(` Last updated: ${status2.lastUpdated ? chalk11.dim(status2.lastUpdated) : chalk11.yellow("Never")}`);
3787
- console.log(` Database: ${chalk11.dim(join11(cwd, ".archon/index.db"))}`);
4581
+ console.log(chalk12.blue("\nLocal Semantic Index Status\n"));
4582
+ console.log(` Files indexed: ${chalk12.green(status2.fileCount)}`);
4583
+ console.log(` Total chunks: ${chalk12.green(status2.chunkCount)}`);
4584
+ console.log(` Last updated: ${status2.lastUpdated ? chalk12.dim(status2.lastUpdated) : chalk12.yellow("Never")}`);
4585
+ console.log(` Database: ${chalk12.dim(join13(cwd, ".archon/index.db"))}`);
3788
4586
  indexer.close();
3789
4587
  } catch (error) {
3790
- console.error(chalk11.red(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`));
4588
+ console.error(chalk12.red(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`));
4589
+ process.exit(1);
4590
+ }
4591
+ }
4592
+ async function indexClear(options) {
4593
+ const cwd = process.cwd();
4594
+ if (options?.cloud) {
4595
+ const indexer = await getCloudIndexer(cwd);
4596
+ if (!indexer) return;
4597
+ try {
4598
+ console.log(chalk12.yellow("Clearing cloud index..."));
4599
+ await indexer.clearProject();
4600
+ console.log(chalk12.green("\u2713 Cloud index cleared"));
4601
+ } catch (error) {
4602
+ console.error(chalk12.red(`Failed to clear cloud index: ${error instanceof Error ? error.message : String(error)}`));
4603
+ process.exit(1);
4604
+ }
4605
+ return;
4606
+ }
4607
+ console.log(chalk12.yellow("To clear local index, delete .archon/index.db"));
4608
+ }
4609
+
4610
+ // src/cli/github.ts
4611
+ import chalk13 from "chalk";
4612
+ import open2 from "open";
4613
+ var API_URL2 = process.env["ARCHONDEV_API_URL"] ?? "https://archondev-api.fly.dev";
4614
+ async function githubConnect() {
4615
+ const config = await loadConfig();
4616
+ const authToken = getAuthToken(config);
4617
+ if (!authToken) {
4618
+ console.error(chalk13.red('Not authenticated. Run "archon login" first.'));
4619
+ process.exit(1);
4620
+ }
4621
+ console.log(chalk13.dim("Starting GitHub connection..."));
4622
+ try {
4623
+ const response = await fetch(`${API_URL2}/api/github/connect`, {
4624
+ headers: {
4625
+ "Authorization": `Bearer ${authToken}`
4626
+ }
4627
+ });
4628
+ if (!response.ok) {
4629
+ const error = await response.json();
4630
+ console.error(chalk13.red(error.error ?? "Failed to start GitHub connection"));
4631
+ process.exit(1);
4632
+ }
4633
+ const data = await response.json();
4634
+ console.log(chalk13.dim("\nOpening browser for GitHub authorization..."));
4635
+ console.log(chalk13.dim("If browser does not open, visit:"));
4636
+ console.log(chalk13.blue(data.url));
4637
+ await open2(data.url);
4638
+ console.log(chalk13.dim("\nComplete the authorization in your browser."));
4639
+ console.log(chalk13.dim('Then run "archon github status" to verify connection.'));
4640
+ } catch (error) {
4641
+ console.error(chalk13.red(error instanceof Error ? error.message : "Failed to connect"));
4642
+ process.exit(1);
4643
+ }
4644
+ }
4645
+ async function githubStatus() {
4646
+ const config = await loadConfig();
4647
+ const authToken = getAuthToken(config);
4648
+ if (!authToken) {
4649
+ console.error(chalk13.red('Not authenticated. Run "archon login" first.'));
4650
+ process.exit(1);
4651
+ }
4652
+ try {
4653
+ const response = await fetch(`${API_URL2}/api/github/status`, {
4654
+ headers: {
4655
+ "Authorization": `Bearer ${authToken}`
4656
+ }
4657
+ });
4658
+ if (!response.ok) {
4659
+ const error = await response.json();
4660
+ console.error(chalk13.red(error.error ?? "Failed to get GitHub status"));
4661
+ process.exit(1);
4662
+ }
4663
+ const data = await response.json();
4664
+ if (data.connected) {
4665
+ console.log(chalk13.green("\u2713 GitHub connected"));
4666
+ console.log(chalk13.dim(` Username: ${data.username}`));
4667
+ console.log(chalk13.dim(` Connected: ${data.connectedAt ? new Date(data.connectedAt).toLocaleDateString() : "Unknown"}`));
4668
+ } else {
4669
+ console.log(chalk13.yellow("GitHub not connected"));
4670
+ console.log(chalk13.dim('Run "archon github connect" to connect your GitHub account.'));
4671
+ }
4672
+ } catch (error) {
4673
+ console.error(chalk13.red(error instanceof Error ? error.message : "Failed to get status"));
4674
+ process.exit(1);
4675
+ }
4676
+ }
4677
+ async function githubDisconnect() {
4678
+ const config = await loadConfig();
4679
+ const authToken = getAuthToken(config);
4680
+ if (!authToken) {
4681
+ console.error(chalk13.red('Not authenticated. Run "archon login" first.'));
4682
+ process.exit(1);
4683
+ }
4684
+ try {
4685
+ const response = await fetch(`${API_URL2}/api/github/disconnect`, {
4686
+ method: "DELETE",
4687
+ headers: {
4688
+ "Authorization": `Bearer ${authToken}`
4689
+ }
4690
+ });
4691
+ if (!response.ok) {
4692
+ const error = await response.json();
4693
+ console.error(chalk13.red(error.error ?? "Failed to disconnect GitHub"));
4694
+ process.exit(1);
4695
+ }
4696
+ console.log(chalk13.green("\u2713 GitHub disconnected"));
4697
+ } catch (error) {
4698
+ console.error(chalk13.red(error instanceof Error ? error.message : "Failed to disconnect"));
3791
4699
  process.exit(1);
3792
4700
  }
3793
4701
  }
@@ -3797,7 +4705,7 @@ var program = new Command4();
3797
4705
  program.name("archon").description("Local-first AI-powered development governance").version("1.1.0").action(async () => {
3798
4706
  const cwd = process.cwd();
3799
4707
  if (!isInitialized(cwd)) {
3800
- console.log(chalk12.blue("\nArchonDev is not initialized in this folder.\n"));
4708
+ console.log(chalk14.blue("\nArchonDev is not initialized in this folder.\n"));
3801
4709
  await init({ analyze: true, git: true });
3802
4710
  }
3803
4711
  await start();
@@ -3805,7 +4713,7 @@ program.name("archon").description("Local-first AI-powered development governanc
3805
4713
  program.command("login").description("Authenticate with ArchonDev").option("-p, --provider <provider>", "OAuth provider (github or google)", "github").action(async (options) => {
3806
4714
  const provider = options.provider;
3807
4715
  if (provider !== "github" && provider !== "google") {
3808
- console.error(chalk12.red('Invalid provider. Use "github" or "google"'));
4716
+ console.error(chalk14.red('Invalid provider. Use "github" or "google"'));
3809
4717
  process.exit(1);
3810
4718
  }
3811
4719
  await login(provider);
@@ -3953,11 +4861,12 @@ a11yCommand.action(async () => {
3953
4861
  program.addCommand(createSeoCommand());
3954
4862
  program.addCommand(createGeoCommand());
3955
4863
  program.command("deploy").description("Deploy application (auto-detects platform)").option("-p, --platform <name>", "Specify platform (fly/vercel/netlify/railway/render)").option("--preview", "Deploy to preview/staging environment").option("--dry-run", "Show what would happen without deploying").action(deploy);
3956
- var indexCmd = program.command("index").description("Semantic codebase indexing with local Ollama");
3957
- indexCmd.command("init").description("Initialize semantic index").option("--local", "Use local Ollama for embeddings (default)").option("--cloud", "Use cloud embeddings (coming soon)").action(indexInit);
3958
- indexCmd.command("update").description("Reindex changed files").action(indexUpdate);
3959
- indexCmd.command("search <query>").description("Semantic search across codebase").action(indexSearch);
3960
- indexCmd.command("status").description("Show index statistics").action(indexStatus);
4864
+ var indexCmd = program.command("index").description("Semantic codebase indexing (local Ollama or cloud pgvector)");
4865
+ indexCmd.command("init").description("Initialize semantic index").option("--local", "Use local Ollama for embeddings (default)").option("--cloud", "Use cloud pgvector with OpenAI embeddings").action(indexInit);
4866
+ indexCmd.command("update").description("Reindex changed files").option("--cloud", "Use cloud indexing").action(indexUpdate);
4867
+ indexCmd.command("search <query>").description("Semantic search across codebase").option("--cloud", "Search cloud index").action((query, options) => indexSearch(query, options));
4868
+ indexCmd.command("status").description("Show index statistics").option("--cloud", "Show cloud index status").action(indexStatus);
4869
+ indexCmd.command("clear").description("Clear the semantic index").option("--cloud", "Clear cloud index").action(indexClear);
3961
4870
  indexCmd.action(indexStatus);
3962
4871
  var sessionCmd = program.command("session").description("Cross-device session management");
3963
4872
  sessionCmd.command("save [name]").description("Save current session").action(saveSession);
@@ -3975,4 +4884,20 @@ parallelCmd.command("status").description("Show status of all parallel execution
3975
4884
  parallelCmd.command("merge [atomId]").description("Merge completed worktrees back to main").action(parallelMerge);
3976
4885
  parallelCmd.command("clean").description("Clean up all parallel execution state and worktrees").action(parallelClean);
3977
4886
  parallelCmd.action(parallelStatus);
4887
+ var githubCmd = program.command("github").description("GitHub integration for cloud execution");
4888
+ githubCmd.command("connect").description("Connect your GitHub account for cloud execution").action(githubConnect);
4889
+ githubCmd.command("status").description("Show GitHub connection status").action(githubStatus);
4890
+ githubCmd.command("disconnect").description("Disconnect your GitHub account").action(githubDisconnect);
4891
+ githubCmd.action(githubStatus);
4892
+ var cleanupCmd = program.command("cleanup").description("Workspace maintenance and file cleanup");
4893
+ cleanupCmd.command("check").description("Analyze workspace for bloat and maintenance needs").action(cleanupCheck);
4894
+ cleanupCmd.command("run").description("Execute cleanup (archive old entries, remove stale files)").action(cleanupRun);
4895
+ cleanupCmd.command("auto").description("Enable/disable automatic cleanup checks").argument("[action]", "enable, disable, or status", "status").action(async (action) => {
4896
+ if (action !== "enable" && action !== "disable" && action !== "status") {
4897
+ console.error(chalk14.red("Invalid action. Use: enable, disable, or status"));
4898
+ process.exit(1);
4899
+ }
4900
+ await cleanupAuto(action);
4901
+ });
4902
+ cleanupCmd.action(cleanupCheck);
3978
4903
  program.parse();