archondev 2.19.42 → 2.19.44
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
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
showExecutionPreferences,
|
|
39
39
|
showPreferences,
|
|
40
40
|
showUsageDetails
|
|
41
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-SAM5CXO4.js";
|
|
42
42
|
import {
|
|
43
43
|
init,
|
|
44
44
|
isInitialized
|
|
@@ -118,7 +118,7 @@ import "./chunk-4VNS5WPM.js";
|
|
|
118
118
|
|
|
119
119
|
// src/cli/index.ts
|
|
120
120
|
import { Command as Command3 } from "commander";
|
|
121
|
-
import
|
|
121
|
+
import chalk18 from "chalk";
|
|
122
122
|
import "dotenv/config";
|
|
123
123
|
|
|
124
124
|
// src/cli/terminal-compat.ts
|
|
@@ -200,7 +200,7 @@ async function saveAtomEnvironmentState(atomId, cwd, state) {
|
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
// src/cli/start.ts
|
|
203
|
-
import
|
|
203
|
+
import chalk6 from "chalk";
|
|
204
204
|
import readline from "readline";
|
|
205
205
|
import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync3, appendFileSync } from "fs";
|
|
206
206
|
import { join as join6, relative } from "path";
|
|
@@ -769,8 +769,91 @@ async function runAutoCleanupCheck(cwd) {
|
|
|
769
769
|
return needsAttention;
|
|
770
770
|
}
|
|
771
771
|
|
|
772
|
-
// src/cli/
|
|
772
|
+
// src/cli/policy.ts
|
|
773
773
|
import chalk3 from "chalk";
|
|
774
|
+
var DEFAULT_POLICY = {
|
|
775
|
+
approval: "approve_this_task",
|
|
776
|
+
sentinel: "plan_batch_only",
|
|
777
|
+
routing: "balanced"
|
|
778
|
+
};
|
|
779
|
+
async function loadRuntimePolicy() {
|
|
780
|
+
const config = await loadConfig();
|
|
781
|
+
return {
|
|
782
|
+
approval: config.approvalPolicy ?? DEFAULT_POLICY.approval,
|
|
783
|
+
sentinel: config.sentinelPolicy ?? DEFAULT_POLICY.sentinel,
|
|
784
|
+
routing: config.routingProfile ?? DEFAULT_POLICY.routing
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
async function setRuntimePolicy(update) {
|
|
788
|
+
const config = await loadConfig();
|
|
789
|
+
const next = {
|
|
790
|
+
approval: update.approval ?? config.approvalPolicy ?? DEFAULT_POLICY.approval,
|
|
791
|
+
sentinel: update.sentinel ?? config.sentinelPolicy ?? DEFAULT_POLICY.sentinel,
|
|
792
|
+
routing: update.routing ?? config.routingProfile ?? DEFAULT_POLICY.routing
|
|
793
|
+
};
|
|
794
|
+
await saveConfig({
|
|
795
|
+
...config,
|
|
796
|
+
approvalPolicy: next.approval,
|
|
797
|
+
sentinelPolicy: next.sentinel,
|
|
798
|
+
routingProfile: next.routing
|
|
799
|
+
});
|
|
800
|
+
return next;
|
|
801
|
+
}
|
|
802
|
+
async function showPolicy() {
|
|
803
|
+
const policy = await loadRuntimePolicy();
|
|
804
|
+
console.log(chalk3.green("Runtime Policy:"));
|
|
805
|
+
console.log();
|
|
806
|
+
console.log(` ${chalk3.blue("Approval:")} ${policy.approval}`);
|
|
807
|
+
console.log(` ${chalk3.blue("Sentinel:")} ${policy.sentinel}`);
|
|
808
|
+
console.log(` ${chalk3.blue("Routing:")} ${policy.routing}`);
|
|
809
|
+
}
|
|
810
|
+
async function setPolicy(scope, value) {
|
|
811
|
+
if (scope === "approval") {
|
|
812
|
+
const allowed = [
|
|
813
|
+
"ask_every_time",
|
|
814
|
+
"approve_this_task",
|
|
815
|
+
"approve_this_session",
|
|
816
|
+
"always_approve_safe_ops",
|
|
817
|
+
"full_autopilot"
|
|
818
|
+
];
|
|
819
|
+
if (!allowed.includes(value)) {
|
|
820
|
+
console.error(chalk3.red(`Invalid approval policy: ${value}`));
|
|
821
|
+
console.log(chalk3.dim(`Valid values: ${allowed.join(", ")}`));
|
|
822
|
+
process.exit(1);
|
|
823
|
+
}
|
|
824
|
+
await setRuntimePolicy({ approval: value });
|
|
825
|
+
console.log(chalk3.green(`\u2713 approval policy set to ${value}`));
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
if (scope === "sentinel") {
|
|
829
|
+
const allowed = ["every_atom", "plan_batch_only", "manual_only"];
|
|
830
|
+
if (!allowed.includes(value)) {
|
|
831
|
+
console.error(chalk3.red(`Invalid sentinel policy: ${value}`));
|
|
832
|
+
console.log(chalk3.dim(`Valid values: ${allowed.join(", ")}`));
|
|
833
|
+
process.exit(1);
|
|
834
|
+
}
|
|
835
|
+
await setRuntimePolicy({ sentinel: value });
|
|
836
|
+
console.log(chalk3.green(`\u2713 sentinel policy set to ${value}`));
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
if (scope === "routing") {
|
|
840
|
+
const allowed = ["cheap", "balanced", "max_quality"];
|
|
841
|
+
if (!allowed.includes(value)) {
|
|
842
|
+
console.error(chalk3.red(`Invalid routing profile: ${value}`));
|
|
843
|
+
console.log(chalk3.dim(`Valid values: ${allowed.join(", ")}`));
|
|
844
|
+
process.exit(1);
|
|
845
|
+
}
|
|
846
|
+
await setRuntimePolicy({ routing: value });
|
|
847
|
+
console.log(chalk3.green(`\u2713 routing profile set to ${value}`));
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
console.error(chalk3.red(`Invalid policy scope: ${scope}`));
|
|
851
|
+
console.log(chalk3.dim("Valid scopes: approval, sentinel, routing"));
|
|
852
|
+
process.exit(1);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
// src/cli/update-check.ts
|
|
856
|
+
import chalk4 from "chalk";
|
|
774
857
|
import { readFileSync, existsSync as existsSync4 } from "fs";
|
|
775
858
|
import { join as join4, dirname as dirname3 } from "path";
|
|
776
859
|
import { fileURLToPath } from "url";
|
|
@@ -862,10 +945,10 @@ async function checkForUpdates() {
|
|
|
862
945
|
function displayUpdateBanner(result) {
|
|
863
946
|
if (!result.hasUpdate) return;
|
|
864
947
|
console.log();
|
|
865
|
-
console.log(
|
|
866
|
-
console.log(
|
|
867
|
-
console.log(
|
|
868
|
-
console.log(
|
|
948
|
+
console.log(chalk4.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
949
|
+
console.log(chalk4.yellow("\u2502") + chalk4.bold(" Update available! ") + chalk4.dim(`${result.currentVersion} \u2192 `) + chalk4.green(result.latestVersion) + chalk4.yellow(" \u2502"));
|
|
950
|
+
console.log(chalk4.yellow("\u2502") + chalk4.dim(` Run: ${result.updateCommand}`) + chalk4.yellow(" \u2502"));
|
|
951
|
+
console.log(chalk4.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
869
952
|
console.log();
|
|
870
953
|
}
|
|
871
954
|
function startBackgroundUpdateCheck() {
|
|
@@ -873,7 +956,7 @@ function startBackgroundUpdateCheck() {
|
|
|
873
956
|
}
|
|
874
957
|
|
|
875
958
|
// src/cli/logo.ts
|
|
876
|
-
import
|
|
959
|
+
import chalk5 from "chalk";
|
|
877
960
|
var ARCHON_LOGO_MINI = `
|
|
878
961
|
\u2584\u2588\u2580\u2588\u2584
|
|
879
962
|
\u2588\u2588\u2580\u2588\u2580\u2588\u2588
|
|
@@ -898,10 +981,10 @@ function displayBrandedHeader() {
|
|
|
898
981
|
return;
|
|
899
982
|
}
|
|
900
983
|
console.log();
|
|
901
|
-
console.log(
|
|
902
|
-
console.log(
|
|
903
|
-
console.log(
|
|
904
|
-
console.log(
|
|
984
|
+
console.log(chalk5.hex("#374F4E")(ARCHON_LOGO_MINI));
|
|
985
|
+
console.log(chalk5.bold.hex("#374F4E")(" ArchonDev"));
|
|
986
|
+
console.log(chalk5.hex("#AA8552")(" AI-Powered Development Governance"));
|
|
987
|
+
console.log(chalk5.hex("#374F4E")("\u2500".repeat(40)));
|
|
905
988
|
console.log();
|
|
906
989
|
}
|
|
907
990
|
|
|
@@ -2620,6 +2703,9 @@ var pendingProposalMode = "atom";
|
|
|
2620
2703
|
var pendingAnalysisToAtomRequest = null;
|
|
2621
2704
|
var pendingAnalysisReviewedFiles = [];
|
|
2622
2705
|
var pendingAnalysisCapsuleCount = null;
|
|
2706
|
+
function shouldAutoRunOnApproval(policy) {
|
|
2707
|
+
return policy !== "ask_every_time";
|
|
2708
|
+
}
|
|
2623
2709
|
function uiText(rich, plain) {
|
|
2624
2710
|
return isTerminalSafeMode() ? plain : rich;
|
|
2625
2711
|
}
|
|
@@ -2633,21 +2719,21 @@ async function start(options = {}) {
|
|
|
2633
2719
|
let config = await loadConfig();
|
|
2634
2720
|
let token = getAuthToken(config);
|
|
2635
2721
|
if (!token) {
|
|
2636
|
-
console.log(
|
|
2637
|
-
console.log(
|
|
2722
|
+
console.log(chalk6.bold("Welcome to ArchonDev!\n"));
|
|
2723
|
+
console.log(chalk6.dim("Let's get you set up. First, we need to create your account.\n"));
|
|
2638
2724
|
await login();
|
|
2639
2725
|
console.log();
|
|
2640
2726
|
config = await loadConfig();
|
|
2641
2727
|
token = getAuthToken(config);
|
|
2642
2728
|
if (!token) {
|
|
2643
|
-
console.log(
|
|
2729
|
+
console.log(chalk6.yellow("Login is required to continue. Run `archon` again when ready."));
|
|
2644
2730
|
return;
|
|
2645
2731
|
}
|
|
2646
2732
|
}
|
|
2647
2733
|
if (!config.tier || config.tier === "FREE") {
|
|
2648
2734
|
const isFirstRun = !existsSync6(join6(cwd, ".archon")) && resolveArchitecturePath(cwd).path === null;
|
|
2649
2735
|
if (isFirstRun && !config.tierConfirmed) {
|
|
2650
|
-
console.log(
|
|
2736
|
+
console.log(chalk6.bold("How would you like to use ArchonDev?\n"));
|
|
2651
2737
|
const selection = await promptTierSelection();
|
|
2652
2738
|
if (selection && !selection.skipped) {
|
|
2653
2739
|
const updateResult2 = await updateUserTier(selection.tier);
|
|
@@ -2655,7 +2741,7 @@ async function start(options = {}) {
|
|
|
2655
2741
|
config.tier = selection.tier;
|
|
2656
2742
|
config.tierConfirmed = true;
|
|
2657
2743
|
await saveConfig(config);
|
|
2658
|
-
console.log(
|
|
2744
|
+
console.log(chalk6.green(`
|
|
2659
2745
|
\u2713 Tier set to ${formatTierName(selection.tier)}
|
|
2660
2746
|
`));
|
|
2661
2747
|
await handleTierSetup(selection.tier);
|
|
@@ -2663,28 +2749,32 @@ async function start(options = {}) {
|
|
|
2663
2749
|
} else {
|
|
2664
2750
|
config.tierConfirmed = true;
|
|
2665
2751
|
await saveConfig(config);
|
|
2666
|
-
console.log(
|
|
2752
|
+
console.log(chalk6.dim("Using Free tier. You can upgrade anytime with `archon upgrade`\n"));
|
|
2667
2753
|
}
|
|
2668
2754
|
}
|
|
2669
2755
|
}
|
|
2670
2756
|
if (config.email) {
|
|
2671
|
-
console.log(
|
|
2757
|
+
console.log(chalk6.dim(`Logged in as: ${config.email}`));
|
|
2672
2758
|
}
|
|
2673
2759
|
const currentTier = config.tier || "FREE";
|
|
2674
2760
|
const tierDisplay = formatTierName(currentTier);
|
|
2675
|
-
|
|
2761
|
+
const runtimePolicy = await loadRuntimePolicy();
|
|
2762
|
+
console.log(chalk6.dim(`Tier: `) + tierDisplay);
|
|
2676
2763
|
const startupChatModel = await resolveStartupChatModel(currentTier, config.accessToken, config.userId);
|
|
2677
2764
|
if (currentTier !== "FREE") {
|
|
2678
|
-
console.log(
|
|
2679
|
-
console.log(
|
|
2765
|
+
console.log(chalk6.dim(`Chat model: ${formatChatModelDisplay(startupChatModel)}`));
|
|
2766
|
+
console.log(chalk6.dim("Change model: archon preferences"));
|
|
2680
2767
|
}
|
|
2768
|
+
console.log(chalk6.dim(`Approval policy: ${runtimePolicy.approval}`));
|
|
2769
|
+
console.log(chalk6.dim(`Sentinel policy: ${runtimePolicy.sentinel}`));
|
|
2770
|
+
console.log(chalk6.dim(`Routing profile: ${runtimePolicy.routing}`));
|
|
2681
2771
|
if (currentTier === "FREE") {
|
|
2682
2772
|
console.log();
|
|
2683
|
-
console.log(
|
|
2684
|
-
console.log(
|
|
2685
|
-
console.log(
|
|
2686
|
-
console.log(
|
|
2687
|
-
console.log(
|
|
2773
|
+
console.log(chalk6.yellow("\u26A0\uFE0F FREE TIER: Limited usage. Upgrade options:"));
|
|
2774
|
+
console.log(chalk6.dim(" \u2022 ") + chalk6.bold("BYOK (FREE)") + chalk6.dim(" - Unlimited usage with your own API keys"));
|
|
2775
|
+
console.log(chalk6.dim(" \u2022 ") + chalk6.bold("Managed Plan") + chalk6.dim(" - Just 10% fee on AI costs, zero setup"));
|
|
2776
|
+
console.log(chalk6.cyan("\u2192 Run ") + chalk6.bold("'archon upgrade'") + chalk6.cyan(" to unlock unlimited access"));
|
|
2777
|
+
console.log(chalk6.dim("\u2192 Model preferences: archon preferences"));
|
|
2688
2778
|
}
|
|
2689
2779
|
if (currentTier === "CREDITS" && config.accessToken) {
|
|
2690
2780
|
try {
|
|
@@ -2706,41 +2796,41 @@ async function start(options = {}) {
|
|
|
2706
2796
|
}
|
|
2707
2797
|
if (usageStats) {
|
|
2708
2798
|
console.log();
|
|
2709
|
-
console.log(
|
|
2710
|
-
console.log(
|
|
2711
|
-
const balanceColor = usageStats.balance < 1 ?
|
|
2799
|
+
console.log(chalk6.bold(uiText("\u{1F4B0} Credits Balance", "Credits Balance")));
|
|
2800
|
+
console.log(chalk6.dim(uiSeparator()));
|
|
2801
|
+
const balanceColor = usageStats.balance < 1 ? chalk6.red : usageStats.balance < 5 ? chalk6.yellow : chalk6.green;
|
|
2712
2802
|
console.log(` Balance: ${balanceColor(`$${usageStats.balance.toFixed(2)}`)}`);
|
|
2713
2803
|
if (usageStats.periodStart) {
|
|
2714
2804
|
const periodDate = new Date(usageStats.periodStart);
|
|
2715
2805
|
const formatted = isNaN(periodDate.getTime()) ? usageStats.periodStart : periodDate.toLocaleDateString();
|
|
2716
2806
|
const label = usageStats.periodSource === "credit_purchase" ? `Since last top-up (${formatted})` : usageStats.periodSource === "month" ? `Since ${formatted}` : `Period start: ${formatted}`;
|
|
2717
|
-
console.log(
|
|
2807
|
+
console.log(chalk6.dim(` ${label}`));
|
|
2718
2808
|
}
|
|
2719
2809
|
if (usageStats.usedThisPeriod > 0) {
|
|
2720
|
-
console.log(` Used since last top-up: ${
|
|
2810
|
+
console.log(` Used since last top-up: ${chalk6.dim(`$${usageStats.usedThisPeriod.toFixed(2)}`)}`);
|
|
2721
2811
|
} else {
|
|
2722
|
-
console.log(
|
|
2812
|
+
console.log(chalk6.dim(" No usage recorded since last top-up."));
|
|
2723
2813
|
}
|
|
2724
2814
|
console.log();
|
|
2725
|
-
console.log(
|
|
2815
|
+
console.log(chalk6.dim(" Model Usage:"));
|
|
2726
2816
|
if (usageStats.byModel && usageStats.byModel.length > 0) {
|
|
2727
2817
|
for (const model of usageStats.byModel) {
|
|
2728
2818
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2729
|
-
console.log(
|
|
2819
|
+
console.log(chalk6.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2730
2820
|
}
|
|
2731
2821
|
} else {
|
|
2732
|
-
console.log(
|
|
2822
|
+
console.log(chalk6.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2733
2823
|
}
|
|
2734
|
-
console.log(
|
|
2824
|
+
console.log(chalk6.dim(uiSeparator()));
|
|
2735
2825
|
if (usageStatsUnavailable) {
|
|
2736
|
-
console.log(
|
|
2826
|
+
console.log(chalk6.dim("Usage details may be delayed. Run `archon credits` to refresh."));
|
|
2737
2827
|
}
|
|
2738
2828
|
if (usageStats.balance < 5) {
|
|
2739
|
-
console.log(
|
|
2829
|
+
console.log(chalk6.yellow(`\u26A0\uFE0F Low balance! Add credits: `) + chalk6.bold(`archon credits add`));
|
|
2740
2830
|
} else {
|
|
2741
|
-
console.log(
|
|
2831
|
+
console.log(chalk6.dim(`Add credits: archon credits add`));
|
|
2742
2832
|
}
|
|
2743
|
-
console.log(
|
|
2833
|
+
console.log(chalk6.dim(`View details: archon credits | Switch tier: archon upgrade | Models: archon preferences`));
|
|
2744
2834
|
if (usageStats.balance <= 0) {
|
|
2745
2835
|
const topUpNow = await promptYesNo("Balance is $0. Add credits now?", true);
|
|
2746
2836
|
if (topUpNow) {
|
|
@@ -2764,39 +2854,39 @@ async function start(options = {}) {
|
|
|
2764
2854
|
};
|
|
2765
2855
|
}
|
|
2766
2856
|
console.log();
|
|
2767
|
-
console.log(
|
|
2768
|
-
console.log(
|
|
2857
|
+
console.log(chalk6.bold(uiText("\u{1F4CA} BYOK Usage", "BYOK Usage")));
|
|
2858
|
+
console.log(chalk6.dim(uiSeparator()));
|
|
2769
2859
|
if (usageStats.periodStart) {
|
|
2770
2860
|
const periodStart = new Date(usageStats.periodStart);
|
|
2771
2861
|
const periodEnd = usageStats.periodEnd ? new Date(usageStats.periodEnd) : null;
|
|
2772
2862
|
const formattedStart = isNaN(periodStart.getTime()) ? usageStats.periodStart : periodStart.toLocaleDateString();
|
|
2773
2863
|
const formattedEnd = periodEnd && !isNaN(periodEnd.getTime()) ? periodEnd.toLocaleDateString() : void 0;
|
|
2774
2864
|
if (formattedEnd) {
|
|
2775
|
-
console.log(
|
|
2865
|
+
console.log(chalk6.dim(` Period: ${formattedStart} \u2192 ${formattedEnd}`));
|
|
2776
2866
|
} else {
|
|
2777
|
-
console.log(
|
|
2867
|
+
console.log(chalk6.dim(` Period start: ${formattedStart}`));
|
|
2778
2868
|
}
|
|
2779
2869
|
} else {
|
|
2780
|
-
console.log(
|
|
2870
|
+
console.log(chalk6.dim(" Period: Current month to date"));
|
|
2781
2871
|
}
|
|
2782
2872
|
const totalTokens = usageStats.totalInputTokens + usageStats.totalOutputTokens;
|
|
2783
|
-
console.log(` Tokens: ${
|
|
2784
|
-
console.log(` Estimated provider spend: ${
|
|
2873
|
+
console.log(` Tokens: ${chalk6.dim(totalTokens.toLocaleString())}`);
|
|
2874
|
+
console.log(` Estimated provider spend: ${chalk6.dim(`$${usageStats.totalBaseCost.toFixed(4)}`)}`);
|
|
2785
2875
|
console.log();
|
|
2786
|
-
console.log(
|
|
2876
|
+
console.log(chalk6.dim(" Model Usage:"));
|
|
2787
2877
|
if (usageStats.byModel.length > 0) {
|
|
2788
2878
|
for (const model of usageStats.byModel) {
|
|
2789
2879
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2790
|
-
console.log(
|
|
2880
|
+
console.log(chalk6.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2791
2881
|
}
|
|
2792
2882
|
} else {
|
|
2793
|
-
console.log(
|
|
2883
|
+
console.log(chalk6.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2794
2884
|
}
|
|
2795
|
-
console.log(
|
|
2885
|
+
console.log(chalk6.dim(uiSeparator()));
|
|
2796
2886
|
if (usageStatsUnavailable) {
|
|
2797
|
-
console.log(
|
|
2887
|
+
console.log(chalk6.dim("Usage details may be delayed. Run `archon usage` to refresh."));
|
|
2798
2888
|
}
|
|
2799
|
-
console.log(
|
|
2889
|
+
console.log(chalk6.dim("View details: archon usage | Models: archon preferences | Switch tier: archon upgrade"));
|
|
2800
2890
|
} catch {
|
|
2801
2891
|
}
|
|
2802
2892
|
}
|
|
@@ -2805,11 +2895,11 @@ async function start(options = {}) {
|
|
|
2805
2895
|
const hasKeys = await keyManager.hasAnyKey();
|
|
2806
2896
|
if (!hasKeys) {
|
|
2807
2897
|
console.log();
|
|
2808
|
-
console.log(
|
|
2809
|
-
console.log(
|
|
2810
|
-
console.log(` ${
|
|
2811
|
-
console.log(` ${
|
|
2812
|
-
console.log(` ${
|
|
2898
|
+
console.log(chalk6.yellow("\u26A0\uFE0F BYOK MODE: No API keys configured!"));
|
|
2899
|
+
console.log(chalk6.dim("You need at least one API key to use ArchonDev with BYOK.\n"));
|
|
2900
|
+
console.log(` ${chalk6.cyan("1")}) Add an API key now`);
|
|
2901
|
+
console.log(` ${chalk6.cyan("2")}) Switch to Managed Plan (no keys needed)`);
|
|
2902
|
+
console.log(` ${chalk6.cyan("3")}) Continue on Free tier`);
|
|
2813
2903
|
console.log();
|
|
2814
2904
|
const choice = await promptWithCommands("What would you like to do?", { allowMultiline: true });
|
|
2815
2905
|
switch (choice) {
|
|
@@ -2823,7 +2913,7 @@ async function start(options = {}) {
|
|
|
2823
2913
|
if (result.success) {
|
|
2824
2914
|
config.tier = "CREDITS";
|
|
2825
2915
|
await saveConfig(config);
|
|
2826
|
-
console.log(
|
|
2916
|
+
console.log(chalk6.green("\u2713 Switched to Managed Plan"));
|
|
2827
2917
|
const { handleTierSetup: setupCredits } = await import("./tier-selection-XFBM4SZ4.js");
|
|
2828
2918
|
await setupCredits("CREDITS");
|
|
2829
2919
|
}
|
|
@@ -2834,11 +2924,11 @@ async function start(options = {}) {
|
|
|
2834
2924
|
if (downgradeResult.success) {
|
|
2835
2925
|
config.tier = "FREE";
|
|
2836
2926
|
await saveConfig(config);
|
|
2837
|
-
console.log(
|
|
2927
|
+
console.log(chalk6.dim("Switched to Free tier."));
|
|
2838
2928
|
}
|
|
2839
2929
|
break;
|
|
2840
2930
|
default:
|
|
2841
|
-
console.log(
|
|
2931
|
+
console.log(chalk6.dim("Continuing without keys. Some features may not work."));
|
|
2842
2932
|
}
|
|
2843
2933
|
}
|
|
2844
2934
|
}
|
|
@@ -2849,7 +2939,7 @@ async function start(options = {}) {
|
|
|
2849
2939
|
}
|
|
2850
2940
|
const projectState = detectProjectState(cwd);
|
|
2851
2941
|
if (!projectState.hasArchitecture) {
|
|
2852
|
-
console.log(
|
|
2942
|
+
console.log(chalk6.dim("No project initialized in this folder.\n"));
|
|
2853
2943
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
2854
2944
|
await init2({ analyze: true, git: true });
|
|
2855
2945
|
console.log();
|
|
@@ -2863,20 +2953,20 @@ async function start(options = {}) {
|
|
|
2863
2953
|
const contextManager = new ContextManager();
|
|
2864
2954
|
const pendingAtomsData = await contextManager.getPendingAtomsData(cwd);
|
|
2865
2955
|
if (pendingAtomsData && pendingAtomsData.atoms.length > 0) {
|
|
2866
|
-
console.log(
|
|
2956
|
+
console.log(chalk6.yellow("[!] Previous session had pending atoms:\n"));
|
|
2867
2957
|
for (const atomId of pendingAtomsData.atoms) {
|
|
2868
|
-
console.log(
|
|
2958
|
+
console.log(chalk6.dim(` \u2022 ${atomId}`));
|
|
2869
2959
|
}
|
|
2870
2960
|
console.log();
|
|
2871
2961
|
const resume = await promptYesNo("Resume with these atoms?", true);
|
|
2872
2962
|
if (resume) {
|
|
2873
|
-
console.log(
|
|
2963
|
+
console.log(chalk6.green("\n\u2713 Resuming with pending atoms...\n"));
|
|
2874
2964
|
await contextManager.clearPendingAtoms(cwd);
|
|
2875
2965
|
} else {
|
|
2876
2966
|
const clear = await promptYesNo("Clear pending atoms?", false);
|
|
2877
2967
|
if (clear) {
|
|
2878
2968
|
await contextManager.clearPendingAtoms(cwd);
|
|
2879
|
-
console.log(
|
|
2969
|
+
console.log(chalk6.dim("Cleared pending atoms.\n"));
|
|
2880
2970
|
}
|
|
2881
2971
|
}
|
|
2882
2972
|
}
|
|
@@ -3043,18 +3133,18 @@ async function fetchCreditsUsageStatsFromSupabase(accessToken, authId) {
|
|
|
3043
3133
|
}
|
|
3044
3134
|
}
|
|
3045
3135
|
function displayGovernanceStatus(status2) {
|
|
3046
|
-
console.log(
|
|
3136
|
+
console.log(chalk6.dim("Governance Status:"));
|
|
3047
3137
|
if (status2.hasArchitecture) {
|
|
3048
|
-
console.log(
|
|
3138
|
+
console.log(chalk6.green(" \u2713") + ` ARCHITECTURE.md (${status2.posture} posture)`);
|
|
3049
3139
|
if (status2.invariantsCount > 0) {
|
|
3050
|
-
console.log(
|
|
3140
|
+
console.log(chalk6.green(" \u2713") + ` ${status2.invariantsCount} invariants`);
|
|
3051
3141
|
}
|
|
3052
3142
|
if (status2.protectedPathsCount > 0) {
|
|
3053
|
-
console.log(
|
|
3143
|
+
console.log(chalk6.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths`);
|
|
3054
3144
|
}
|
|
3055
3145
|
}
|
|
3056
3146
|
if (status2.pendingAtomsCount > 0) {
|
|
3057
|
-
console.log(
|
|
3147
|
+
console.log(chalk6.cyan(` \u2192 ${status2.pendingAtomsCount} atoms pending`));
|
|
3058
3148
|
}
|
|
3059
3149
|
console.log();
|
|
3060
3150
|
}
|
|
@@ -3186,11 +3276,11 @@ async function gatherGovernanceStatus(cwd) {
|
|
|
3186
3276
|
return status2;
|
|
3187
3277
|
}
|
|
3188
3278
|
async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
3189
|
-
console.log(
|
|
3279
|
+
console.log(chalk6.blue("-- Analyzing Project --\n"));
|
|
3190
3280
|
const projectInfo = await gatherProjectInfo(cwd);
|
|
3191
|
-
console.log(
|
|
3281
|
+
console.log(chalk6.bold(uiText("\u{1F4C1} Project Overview\n", "Project Overview\n")));
|
|
3192
3282
|
if (projectInfo.name) {
|
|
3193
|
-
console.log(` Name: ${
|
|
3283
|
+
console.log(` Name: ${chalk6.cyan(projectInfo.name)}`);
|
|
3194
3284
|
}
|
|
3195
3285
|
if (projectInfo.language) {
|
|
3196
3286
|
console.log(` Language: ${projectInfo.language}`);
|
|
@@ -3202,35 +3292,35 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3202
3292
|
console.log(` Package Manager: ${projectInfo.packageManager}`);
|
|
3203
3293
|
}
|
|
3204
3294
|
console.log();
|
|
3205
|
-
console.log(
|
|
3206
|
-
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") :
|
|
3295
|
+
console.log(chalk6.bold(uiText("\u{1F4CA} Structure\n", "Structure\n")));
|
|
3296
|
+
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") : chalk6.dim("none detected")}`);
|
|
3207
3297
|
console.log(` Source files: ${projectInfo.sourceFileCount}`);
|
|
3208
3298
|
if (projectInfo.testFileCount > 0) {
|
|
3209
3299
|
console.log(` Test files: ${projectInfo.testFileCount}`);
|
|
3210
3300
|
}
|
|
3211
3301
|
console.log();
|
|
3212
|
-
console.log(
|
|
3302
|
+
console.log(chalk6.bold(uiText("\u{1F3DB}\uFE0F Governance\n", "Governance\n")));
|
|
3213
3303
|
if (projectInfo.hasArchitecture) {
|
|
3214
|
-
console.log(` ${
|
|
3304
|
+
console.log(` ${chalk6.green("\u2713")} ARCHITECTURE.md (${projectInfo.posture || "unknown"} posture)`);
|
|
3215
3305
|
if (projectInfo.invariantsCount > 0) {
|
|
3216
|
-
console.log(` ${
|
|
3306
|
+
console.log(` ${chalk6.green("\u2713")} ${projectInfo.invariantsCount} invariants defined`);
|
|
3217
3307
|
}
|
|
3218
3308
|
if (projectInfo.protectedPathsCount > 0) {
|
|
3219
|
-
console.log(` ${
|
|
3309
|
+
console.log(` ${chalk6.green("\u2713")} ${projectInfo.protectedPathsCount} protected paths`);
|
|
3220
3310
|
}
|
|
3221
3311
|
} else {
|
|
3222
|
-
console.log(` ${
|
|
3312
|
+
console.log(` ${chalk6.yellow("\u25CB")} No ARCHITECTURE.md yet`);
|
|
3223
3313
|
}
|
|
3224
3314
|
if (projectInfo.hasProgress) {
|
|
3225
|
-
console.log(` ${
|
|
3315
|
+
console.log(` ${chalk6.green("\u2713")} progress.txt exists`);
|
|
3226
3316
|
}
|
|
3227
3317
|
console.log();
|
|
3228
|
-
console.log(
|
|
3318
|
+
console.log(chalk6.green("\u2713 Analysis complete! I'm ready to work on this project.\n"));
|
|
3229
3319
|
const originalFollowUp = (followUpInput ?? "").trim();
|
|
3230
3320
|
const actionableFollowUp = extractActionableFollowUpFromExplore(originalFollowUp);
|
|
3231
3321
|
if (actionableFollowUp || containsActionIntent(originalFollowUp)) {
|
|
3232
3322
|
const request = actionableFollowUp ?? originalFollowUp;
|
|
3233
|
-
console.log(
|
|
3323
|
+
console.log(chalk6.dim("I finished the project scan. Continuing with your requested task...\n"));
|
|
3234
3324
|
await handlePostExploreAction(cwd, request, {
|
|
3235
3325
|
agentMode: options.agentMode,
|
|
3236
3326
|
originalInput: originalFollowUp
|
|
@@ -3238,17 +3328,17 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3238
3328
|
return;
|
|
3239
3329
|
}
|
|
3240
3330
|
if (options.agentMode) {
|
|
3241
|
-
console.log(
|
|
3331
|
+
console.log(chalk6.dim("Tell me the next thing you want to do.\n"));
|
|
3242
3332
|
return;
|
|
3243
3333
|
}
|
|
3244
|
-
console.log(
|
|
3245
|
-
console.log(
|
|
3246
|
-
console.log(` ${
|
|
3247
|
-
console.log(` ${
|
|
3334
|
+
console.log(chalk6.bold("What would you like to do next?\n"));
|
|
3335
|
+
console.log(chalk6.dim("You can describe it naturally, or use shortcuts:\n"));
|
|
3336
|
+
console.log(` ${chalk6.cyan("1")}) ${chalk6.bold("Plan a task")} \u2014 Tell me what to implement, fix, or change`);
|
|
3337
|
+
console.log(` ${chalk6.cyan("2")}) ${chalk6.bold("Review code")} \u2014 Run AI-powered code review`);
|
|
3248
3338
|
if (!projectInfo.hasArchitecture) {
|
|
3249
|
-
console.log(` ${
|
|
3339
|
+
console.log(` ${chalk6.cyan("3")}) ${chalk6.bold("Set up governance")} \u2014 Generate ARCHITECTURE.md from this analysis`);
|
|
3250
3340
|
}
|
|
3251
|
-
console.log(` ${
|
|
3341
|
+
console.log(` ${chalk6.cyan("q")}) ${chalk6.dim("Quit")}`);
|
|
3252
3342
|
console.log();
|
|
3253
3343
|
const choice = await promptWithCommands("Enter choice");
|
|
3254
3344
|
switch (choice.toLowerCase()) {
|
|
@@ -3281,7 +3371,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3281
3371
|
return;
|
|
3282
3372
|
}
|
|
3283
3373
|
}
|
|
3284
|
-
console.log(
|
|
3374
|
+
console.log(chalk6.yellow("I did not catch that. Tell me what you want to do next."));
|
|
3285
3375
|
await showMainMenu();
|
|
3286
3376
|
}
|
|
3287
3377
|
}
|
|
@@ -3384,7 +3474,7 @@ async function runConversationalInterview(cwd, initialMessage) {
|
|
|
3384
3474
|
if (agent && agent.isAvailable()) {
|
|
3385
3475
|
await runAIInterview(cwd, initialMessage, agent);
|
|
3386
3476
|
} else {
|
|
3387
|
-
console.log(
|
|
3477
|
+
console.log(chalk6.dim("(Using simple setup - add API keys with `archon keys add` for AI-powered interview)\n"));
|
|
3388
3478
|
await runSimpleInterview(cwd, initialMessage);
|
|
3389
3479
|
}
|
|
3390
3480
|
}
|
|
@@ -3394,11 +3484,11 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3394
3484
|
try {
|
|
3395
3485
|
let turn = await agent.startInterview(initialMessage);
|
|
3396
3486
|
while (!turn.isComplete && turnCount < MAX_TURNS) {
|
|
3397
|
-
console.log(
|
|
3487
|
+
console.log(chalk6.blue("\u2192 ") + turn.question);
|
|
3398
3488
|
console.log();
|
|
3399
3489
|
const response = await prompt("");
|
|
3400
3490
|
if (wantsToSkip(response)) {
|
|
3401
|
-
console.log(
|
|
3491
|
+
console.log(chalk6.dim("\n> Using defaults for remaining questions.\n"));
|
|
3402
3492
|
break;
|
|
3403
3493
|
}
|
|
3404
3494
|
turn = await agent.continueInterview(response);
|
|
@@ -3410,12 +3500,12 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3410
3500
|
}
|
|
3411
3501
|
const usage = agent.getUsage();
|
|
3412
3502
|
if (usage.totalTokens > 0) {
|
|
3413
|
-
console.log(
|
|
3503
|
+
console.log(chalk6.dim(`
|
|
3414
3504
|
(Interview used ${usage.totalTokens} tokens, $${usage.baseCost.toFixed(4)})`));
|
|
3415
3505
|
}
|
|
3416
3506
|
await finishInterview(cwd, state, initialMessage);
|
|
3417
3507
|
} catch (error) {
|
|
3418
|
-
console.log(
|
|
3508
|
+
console.log(chalk6.yellow("\n[!] AI interview unavailable, using simple setup.\n"));
|
|
3419
3509
|
await runSimpleInterview(cwd, initialMessage);
|
|
3420
3510
|
}
|
|
3421
3511
|
}
|
|
@@ -3428,9 +3518,9 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3428
3518
|
});
|
|
3429
3519
|
const known = getKnownInfo(state);
|
|
3430
3520
|
if (known.length > 0) {
|
|
3431
|
-
console.log(
|
|
3521
|
+
console.log(chalk6.dim("From what you said, I got:"));
|
|
3432
3522
|
for (const info of known) {
|
|
3433
|
-
console.log(
|
|
3523
|
+
console.log(chalk6.dim(` \u2022 ${info}`));
|
|
3434
3524
|
}
|
|
3435
3525
|
console.log();
|
|
3436
3526
|
}
|
|
@@ -3452,7 +3542,7 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3452
3542
|
await finishInterview(cwd, state, initialMessage);
|
|
3453
3543
|
}
|
|
3454
3544
|
async function finishInterview(cwd, state, initialTaskHint) {
|
|
3455
|
-
console.log(
|
|
3545
|
+
console.log(chalk6.blue("\n-- Recording Project Details --\n"));
|
|
3456
3546
|
const posture = state.posture === "enterprise" ? "enterprise" : state.posture === "prototype" ? "prototype" : "production";
|
|
3457
3547
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3458
3548
|
const progressEntry = `
|
|
@@ -3484,22 +3574,22 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3484
3574
|
writeFileSync2(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
|
|
3485
3575
|
}
|
|
3486
3576
|
appendFileSync(progressPath, progressEntry);
|
|
3487
|
-
console.log(
|
|
3577
|
+
console.log(chalk6.green("\n\u2713 Project details recorded!\n"));
|
|
3488
3578
|
const finalKnown = getKnownInfo(state);
|
|
3489
3579
|
if (finalKnown.length > 0) {
|
|
3490
|
-
console.log(
|
|
3580
|
+
console.log(chalk6.dim("Project configured with:"));
|
|
3491
3581
|
for (const info of finalKnown) {
|
|
3492
|
-
console.log(
|
|
3582
|
+
console.log(chalk6.dim(` \u2022 ${info}`));
|
|
3493
3583
|
}
|
|
3494
3584
|
console.log();
|
|
3495
3585
|
}
|
|
3496
|
-
console.log(
|
|
3497
|
-
console.log(` 1. ${
|
|
3498
|
-
console.log(` 2. ${
|
|
3586
|
+
console.log(chalk6.bold("Next steps:"));
|
|
3587
|
+
console.log(` 1. ${chalk6.cyan("Review")} ARCHITECTURE.md and customize if needed`);
|
|
3588
|
+
console.log(` 2. ${chalk6.cyan("Run")} ${chalk6.dim('archon plan "your first task"')} to create an atom`);
|
|
3499
3589
|
console.log();
|
|
3500
3590
|
const hintedTask = initialTaskHint?.trim() ?? "";
|
|
3501
3591
|
if (hintedTask) {
|
|
3502
|
-
console.log(
|
|
3592
|
+
console.log(chalk6.dim("Using your request above as the first task.\n"));
|
|
3503
3593
|
const { plan: plan2 } = await import("./plan-I3P6U2ZM.js");
|
|
3504
3594
|
await plan2(hintedTask, { conversational: true });
|
|
3505
3595
|
return;
|
|
@@ -3517,7 +3607,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3517
3607
|
const hinted = initialTaskHint?.trim() ?? "";
|
|
3518
3608
|
if (hinted) {
|
|
3519
3609
|
description = hinted;
|
|
3520
|
-
console.log(
|
|
3610
|
+
console.log(chalk6.dim("\nUsing your request above as the first task.\n"));
|
|
3521
3611
|
} else {
|
|
3522
3612
|
description = await promptWithCommands("Describe what you want to build first", { allowMultiline: true });
|
|
3523
3613
|
}
|
|
@@ -3603,7 +3693,7 @@ function inferLanguageFromProjectFiles(cwd) {
|
|
|
3603
3693
|
return best?.language;
|
|
3604
3694
|
}
|
|
3605
3695
|
async function analyzeAndAdapt(cwd) {
|
|
3606
|
-
console.log(
|
|
3696
|
+
console.log(chalk6.blue("\n-- Analyzing Project --\n"));
|
|
3607
3697
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
3608
3698
|
await init2({ analyze: true, git: true });
|
|
3609
3699
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -3625,12 +3715,12 @@ async function analyzeAndAdapt(cwd) {
|
|
|
3625
3715
|
- .archon/config.yaml - Build commands configured
|
|
3626
3716
|
- progress.txt - This file
|
|
3627
3717
|
`);
|
|
3628
|
-
console.log(
|
|
3718
|
+
console.log(chalk6.green("\n\u2713 Governance files adapted!\n"));
|
|
3629
3719
|
await showMainMenu();
|
|
3630
3720
|
}
|
|
3631
3721
|
async function codeReviewFirst(cwd) {
|
|
3632
|
-
console.log(
|
|
3633
|
-
console.log(
|
|
3722
|
+
console.log(chalk6.blue("\n-- Code Review Mode --\n"));
|
|
3723
|
+
console.log(chalk6.dim("I'll analyze your code for issues without making any changes.\n"));
|
|
3634
3724
|
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-7BBVCF7H.js");
|
|
3635
3725
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
3636
3726
|
if (!existsSync6(reviewDbPath)) {
|
|
@@ -3641,22 +3731,22 @@ async function codeReviewFirst(cwd) {
|
|
|
3641
3731
|
if (runReview) {
|
|
3642
3732
|
await reviewRun2({ all: true });
|
|
3643
3733
|
}
|
|
3644
|
-
console.log(
|
|
3734
|
+
console.log(chalk6.dim("\nAfter reviewing, you can run ") + chalk6.cyan("archon") + chalk6.dim(" again to set up governance.\n"));
|
|
3645
3735
|
}
|
|
3646
3736
|
async function runAgentMode(cwd, state) {
|
|
3647
3737
|
if (state.scenario === "CONTINUE_SESSION") {
|
|
3648
|
-
console.log(
|
|
3738
|
+
console.log(chalk6.bold("Welcome back!\n"));
|
|
3649
3739
|
if (state.lastProgressEntry) {
|
|
3650
|
-
console.log(
|
|
3651
|
-
console.log(
|
|
3740
|
+
console.log(chalk6.dim("Last activity:"));
|
|
3741
|
+
console.log(chalk6.dim(" " + state.lastProgressEntry.split("\n")[0]));
|
|
3652
3742
|
console.log();
|
|
3653
3743
|
}
|
|
3654
3744
|
} else if (state.scenario === "NEW_PROJECT") {
|
|
3655
|
-
console.log(
|
|
3656
|
-
console.log(
|
|
3745
|
+
console.log(chalk6.bold("Starting in chat mode.\n"));
|
|
3746
|
+
console.log(chalk6.dim("Tell me what you want to build. I will apply governance checks in the background.\n"));
|
|
3657
3747
|
} else {
|
|
3658
|
-
console.log(
|
|
3659
|
-
console.log(
|
|
3748
|
+
console.log(chalk6.bold("Ready in chat mode.\n"));
|
|
3749
|
+
console.log(chalk6.dim("Tell me what you want to do. Use /workflow for the classic menu.\n"));
|
|
3660
3750
|
}
|
|
3661
3751
|
while (true) {
|
|
3662
3752
|
const response = await promptWithCommands(
|
|
@@ -3673,7 +3763,7 @@ async function runAgentMode(cwd, state) {
|
|
|
3673
3763
|
}
|
|
3674
3764
|
const handled = await handleAgentConversationInput(cwd, trimmed);
|
|
3675
3765
|
if (!handled) {
|
|
3676
|
-
console.log(
|
|
3766
|
+
console.log(chalk6.yellow("I did not catch that. Describe your goal in one sentence."));
|
|
3677
3767
|
}
|
|
3678
3768
|
}
|
|
3679
3769
|
}
|
|
@@ -3688,11 +3778,27 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3688
3778
|
const capsuleCount = pendingAnalysisCapsuleCount ?? 1;
|
|
3689
3779
|
pendingAnalysisCapsuleCount = null;
|
|
3690
3780
|
const enrichedRequest = enrichApprovedAnalysisRequest(request, reviewedFiles, capsuleCount);
|
|
3691
|
-
console.log(
|
|
3692
|
-
const
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3781
|
+
console.log(chalk6.dim("\n> Great. Creating a governed task from the approved analysis plan.\n"));
|
|
3782
|
+
const createdAtomIds = await createTaskFromRequest(cwd, enrichedRequest);
|
|
3783
|
+
const policy = await loadRuntimePolicy();
|
|
3784
|
+
if (shouldAutoRunOnApproval(policy.approval)) {
|
|
3785
|
+
console.log(chalk6.dim("\n> Starting implementation now...\n"));
|
|
3786
|
+
await continueWithCurrentTask(cwd, {
|
|
3787
|
+
runAllReady: true,
|
|
3788
|
+
onlyAtomIds: createdAtomIds
|
|
3789
|
+
});
|
|
3790
|
+
} else {
|
|
3791
|
+
const executeNow = await promptYesNo("Plan approved. Execute this task now?", true);
|
|
3792
|
+
if (executeNow) {
|
|
3793
|
+
await continueWithCurrentTask(cwd, {
|
|
3794
|
+
runAllReady: true,
|
|
3795
|
+
onlyAtomIds: createdAtomIds
|
|
3796
|
+
});
|
|
3797
|
+
} else {
|
|
3798
|
+
await showLatestPlannedAtom(cwd);
|
|
3799
|
+
console.log(chalk6.dim('\nReply "continue" when you want execution to start.'));
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3696
3802
|
return true;
|
|
3697
3803
|
}
|
|
3698
3804
|
if (pendingProposalRequest && isPlanApprovalDirective(normalized)) {
|
|
@@ -3725,11 +3831,11 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3725
3831
|
}
|
|
3726
3832
|
const intent = detectUserIntent(input);
|
|
3727
3833
|
if (isReadOnlyExploreRequest(input) || intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3728
|
-
console.log(
|
|
3834
|
+
console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
|
|
3729
3835
|
await runExploreFlow(cwd, input, { agentMode: true });
|
|
3730
3836
|
return true;
|
|
3731
3837
|
}
|
|
3732
|
-
console.log(
|
|
3838
|
+
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
3733
3839
|
const { plan: plan2 } = await import("./plan-I3P6U2ZM.js");
|
|
3734
3840
|
await plan2(await withAllowedPathScope(cwd, input), { conversational: true });
|
|
3735
3841
|
if (shouldAutoExecuteAfterPlanning(input)) {
|
|
@@ -3737,7 +3843,7 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3737
3843
|
return true;
|
|
3738
3844
|
}
|
|
3739
3845
|
await showLatestPlannedAtom(cwd);
|
|
3740
|
-
console.log(
|
|
3846
|
+
console.log(chalk6.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
|
|
3741
3847
|
return true;
|
|
3742
3848
|
}
|
|
3743
3849
|
function isReadOnlyExploreRequest(input) {
|
|
@@ -3765,22 +3871,22 @@ function wantsProposalBeforeExecution(input) {
|
|
|
3765
3871
|
async function showProposalForApproval(input) {
|
|
3766
3872
|
pendingProposalRequest = input.trim();
|
|
3767
3873
|
pendingProposalMode = shouldDoAnalysisBeforeAtom(input) ? "analysis" : "atom";
|
|
3768
|
-
console.log(
|
|
3769
|
-
console.log(
|
|
3770
|
-
console.log(
|
|
3771
|
-
console.log(
|
|
3772
|
-
console.log(
|
|
3773
|
-
console.log(
|
|
3874
|
+
console.log(chalk6.dim("\n> Understood. I will not create atoms yet.\n"));
|
|
3875
|
+
console.log(chalk6.bold("Proposed plan (for your approval):"));
|
|
3876
|
+
console.log(chalk6.dim(" 1. Review project files and locate the capsule markdown/source for day 1."));
|
|
3877
|
+
console.log(chalk6.dim(" 2. Evaluate day-1 content boundaries and recommend one capsule vs multiple capsules with rationale."));
|
|
3878
|
+
console.log(chalk6.dim(" 3. Draft a user-friendly capsule structure for day 1."));
|
|
3879
|
+
console.log(chalk6.dim(" 4. Present implementation plan and wait for your approval before creating atoms or executing."));
|
|
3774
3880
|
if (input.trim()) {
|
|
3775
3881
|
console.log();
|
|
3776
|
-
console.log(
|
|
3882
|
+
console.log(chalk6.dim('Reply "approve plan" to proceed, or tell me what to adjust in this plan.'));
|
|
3777
3883
|
}
|
|
3778
3884
|
}
|
|
3779
3885
|
async function showLatestPlannedAtom(cwd) {
|
|
3780
3886
|
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-I3P6U2ZM.js");
|
|
3781
3887
|
const atoms = await listLocalAtoms2();
|
|
3782
3888
|
if (atoms.length === 0) {
|
|
3783
|
-
console.log(
|
|
3889
|
+
console.log(chalk6.yellow("No atoms found yet. Tell me what to plan."));
|
|
3784
3890
|
return;
|
|
3785
3891
|
}
|
|
3786
3892
|
const latest = atoms.slice().sort((a, b) => {
|
|
@@ -3789,10 +3895,10 @@ async function showLatestPlannedAtom(cwd) {
|
|
|
3789
3895
|
return bTime - aTime;
|
|
3790
3896
|
})[0];
|
|
3791
3897
|
if (!latest) {
|
|
3792
|
-
console.log(
|
|
3898
|
+
console.log(chalk6.yellow("No atoms found yet. Tell me what to plan."));
|
|
3793
3899
|
return;
|
|
3794
3900
|
}
|
|
3795
|
-
console.log(
|
|
3901
|
+
console.log(chalk6.dim(`
|
|
3796
3902
|
Showing latest planned atom (${latest.externalId})...
|
|
3797
3903
|
`));
|
|
3798
3904
|
const { show: show2 } = await import("./show-7HL5NIA7.js");
|
|
@@ -3891,14 +3997,51 @@ async function applyApprovedProposal(cwd) {
|
|
|
3891
3997
|
await provideAnalysisFirstPlan(cwd, approvedRequest);
|
|
3892
3998
|
return;
|
|
3893
3999
|
}
|
|
3894
|
-
console.log(
|
|
3895
|
-
const
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
4000
|
+
console.log(chalk6.dim("\n> Great. I will create the task from your approved request.\n"));
|
|
4001
|
+
const createdAtomIds = await createTaskFromRequest(cwd, approvedRequest);
|
|
4002
|
+
const policy = await loadRuntimePolicy();
|
|
4003
|
+
if (shouldAutoRunOnApproval(policy.approval)) {
|
|
4004
|
+
console.log(chalk6.dim("\n> Approval received. Starting unattended execution for all READY atoms...\n"));
|
|
4005
|
+
await continueWithCurrentTask(cwd, {
|
|
4006
|
+
runAllReady: true,
|
|
4007
|
+
onlyAtomIds: createdAtomIds
|
|
4008
|
+
});
|
|
4009
|
+
return;
|
|
4010
|
+
}
|
|
4011
|
+
const executeNow = await promptYesNo("Plan approved. Execute this task now?", true);
|
|
4012
|
+
if (executeNow) {
|
|
4013
|
+
await continueWithCurrentTask(cwd, {
|
|
4014
|
+
runAllReady: true,
|
|
4015
|
+
onlyAtomIds: createdAtomIds
|
|
4016
|
+
});
|
|
4017
|
+
return;
|
|
4018
|
+
}
|
|
4019
|
+
await showLatestPlannedAtom(cwd);
|
|
4020
|
+
console.log(chalk6.dim('\nReply "continue" when you want execution to start.'));
|
|
4021
|
+
}
|
|
4022
|
+
async function createTaskFromRequest(cwd, request) {
|
|
4023
|
+
const { plan: plan2, listLocalAtoms: listLocalAtoms2 } = await import("./plan-I3P6U2ZM.js");
|
|
4024
|
+
const before = await listLocalAtoms2();
|
|
4025
|
+
const beforeIds = new Set(before.map((atom) => atom.externalId));
|
|
4026
|
+
await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
|
|
4027
|
+
const after = await listLocalAtoms2();
|
|
4028
|
+
const created = after.filter((atom) => atom.status === "READY" && !beforeIds.has(atom.externalId)).sort((a, b) => {
|
|
4029
|
+
const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
|
|
4030
|
+
const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
|
|
4031
|
+
return bTime - aTime;
|
|
4032
|
+
}).map((atom) => atom.externalId);
|
|
4033
|
+
if (created.length === 0) {
|
|
4034
|
+
const latestReady = after.filter((atom) => atom.status === "READY").sort((a, b) => {
|
|
4035
|
+
const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
|
|
4036
|
+
const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
|
|
4037
|
+
return bTime - aTime;
|
|
4038
|
+
})[0];
|
|
4039
|
+
return latestReady ? [latestReady.externalId] : [];
|
|
4040
|
+
}
|
|
4041
|
+
return created;
|
|
3899
4042
|
}
|
|
3900
4043
|
async function provideAnalysisFirstPlan(cwd, request) {
|
|
3901
|
-
console.log(
|
|
4044
|
+
console.log(chalk6.dim("\n> I analyzed your request and generated a recommendation + sample draft first.\n"));
|
|
3902
4045
|
const markdownFiles = collectMarkdownFiles(cwd);
|
|
3903
4046
|
const dayOneCandidates = markdownFiles.filter((file) => isDayOnePath(file));
|
|
3904
4047
|
const capsuleCandidates = markdownFiles.filter((file) => /capsule/i.test(file));
|
|
@@ -3907,43 +4050,43 @@ async function provideAnalysisFirstPlan(cwd, request) {
|
|
|
3907
4050
|
const stats = computeContentStats(cwd, reviewedFiles);
|
|
3908
4051
|
const recommendSplit = stats.totalWords > 900 || stats.totalHeadings >= 6;
|
|
3909
4052
|
const capsuleCount = recommendSplit ? 2 : 1;
|
|
3910
|
-
console.log(
|
|
4053
|
+
console.log(chalk6.bold("Analysis summary (no atoms created):"));
|
|
3911
4054
|
if (reviewedFiles.length === 0) {
|
|
3912
|
-
console.log(
|
|
3913
|
-
console.log(
|
|
4055
|
+
console.log(chalk6.dim(" - I did not find obvious day-1 capsule markdown files automatically."));
|
|
4056
|
+
console.log(chalk6.dim(" - Share the target file path and I will evaluate it directly."));
|
|
3914
4057
|
} else {
|
|
3915
|
-
console.log(
|
|
4058
|
+
console.log(chalk6.dim(" Files reviewed:"));
|
|
3916
4059
|
for (const file of reviewedFiles) {
|
|
3917
|
-
console.log(
|
|
4060
|
+
console.log(chalk6.dim(` - ${file}`));
|
|
3918
4061
|
}
|
|
3919
|
-
console.log(
|
|
4062
|
+
console.log(chalk6.dim(` Content signals: ~${stats.totalWords} words, ${stats.totalHeadings} section headings.`));
|
|
3920
4063
|
}
|
|
3921
4064
|
console.log();
|
|
3922
|
-
console.log(
|
|
4065
|
+
console.log(chalk6.bold("Recommendation:"));
|
|
3923
4066
|
if (reviewedFiles.length === 0) {
|
|
3924
|
-
console.log(
|
|
4067
|
+
console.log(chalk6.dim(" I need the exact day-1 capsule file path to make a reliable one-vs-many capsule recommendation."));
|
|
3925
4068
|
} else if (recommendSplit) {
|
|
3926
|
-
console.log(
|
|
4069
|
+
console.log(chalk6.dim(` Split day 1 into ${capsuleCount} capsules for clarity and lower cognitive load.`));
|
|
3927
4070
|
} else {
|
|
3928
|
-
console.log(
|
|
4071
|
+
console.log(chalk6.dim(" Keep day 1 as one capsule to preserve continuity and reduce context switching."));
|
|
3929
4072
|
}
|
|
3930
4073
|
console.log();
|
|
3931
|
-
console.log(
|
|
3932
|
-
console.log(
|
|
3933
|
-
console.log(
|
|
3934
|
-
console.log(
|
|
3935
|
-
console.log(
|
|
4074
|
+
console.log(chalk6.bold("Implementation plan (proposed):"));
|
|
4075
|
+
console.log(chalk6.dim(" 1. Confirm target source file(s) for day 1 content."));
|
|
4076
|
+
console.log(chalk6.dim(` 2. Define capsule boundaries and titles (${capsuleCount} capsule${capsuleCount > 1 ? "s" : ""}).`));
|
|
4077
|
+
console.log(chalk6.dim(" 3. Draft capsule markdown(s) with consistent template and learning objective per capsule."));
|
|
4078
|
+
console.log(chalk6.dim(" 4. Add index/manifest links and quick validation checks for user flow."));
|
|
3936
4079
|
const sampleDraft = buildSampleCapsuleDraft(cwd, reviewedFiles, capsuleCount);
|
|
3937
4080
|
if (sampleDraft) {
|
|
3938
4081
|
console.log();
|
|
3939
|
-
console.log(
|
|
4082
|
+
console.log(chalk6.bold("Sample output for day 1 (draft):"));
|
|
3940
4083
|
console.log(sampleDraft);
|
|
3941
4084
|
}
|
|
3942
4085
|
pendingAnalysisToAtomRequest = request;
|
|
3943
4086
|
pendingAnalysisReviewedFiles = reviewedFiles;
|
|
3944
4087
|
pendingAnalysisCapsuleCount = capsuleCount;
|
|
3945
4088
|
console.log();
|
|
3946
|
-
console.log(
|
|
4089
|
+
console.log(chalk6.dim('Reply with "yes", "go ahead", or "create atom" when you want me to implement this in governed mode.'));
|
|
3947
4090
|
}
|
|
3948
4091
|
function enrichApprovedAnalysisRequest(request, reviewedFiles, capsuleCount) {
|
|
3949
4092
|
const normalizedFiles = reviewedFiles.map((file) => file.trim()).filter((file) => file.length > 0);
|
|
@@ -4022,27 +4165,27 @@ function buildSampleCapsuleDraft(cwd, files, capsuleCount) {
|
|
|
4022
4165
|
const practice = paragraphs[2] ?? "Give one guided prompt so the learner can apply the idea immediately.";
|
|
4023
4166
|
if (capsuleCount <= 1) {
|
|
4024
4167
|
return [
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4168
|
+
chalk6.dim(" ---"),
|
|
4169
|
+
chalk6.dim(` title: "${heading} - Core Capsule"`),
|
|
4170
|
+
chalk6.dim(' type: "lesson_capsule"'),
|
|
4171
|
+
chalk6.dim(" day: 1"),
|
|
4172
|
+
chalk6.dim(" ---"),
|
|
4173
|
+
chalk6.dim(" ## Objective"),
|
|
4174
|
+
chalk6.dim(` ${objective}`),
|
|
4175
|
+
chalk6.dim(" ## Core Concept"),
|
|
4176
|
+
chalk6.dim(` ${concept}`),
|
|
4177
|
+
chalk6.dim(" ## Practice"),
|
|
4178
|
+
chalk6.dim(` ${practice}`)
|
|
4036
4179
|
].join("\n");
|
|
4037
4180
|
}
|
|
4038
4181
|
return [
|
|
4039
|
-
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4182
|
+
chalk6.dim(" Capsule 1: Foundation"),
|
|
4183
|
+
chalk6.dim(` - Objective: ${objective}`),
|
|
4184
|
+
chalk6.dim(` - Core Concept: ${concept}`),
|
|
4185
|
+
chalk6.dim(""),
|
|
4186
|
+
chalk6.dim(" Capsule 2: Application"),
|
|
4187
|
+
chalk6.dim(` - Guided Practice: ${practice}`),
|
|
4188
|
+
chalk6.dim(" - Reflection Prompt: What changed in your understanding after this exercise?")
|
|
4046
4189
|
].join("\n");
|
|
4047
4190
|
}
|
|
4048
4191
|
async function continueWithCurrentTask(cwd, options = {}) {
|
|
@@ -4054,50 +4197,53 @@ async function continueWithCurrentTask(cwd, options = {}) {
|
|
|
4054
4197
|
};
|
|
4055
4198
|
const { execute: execute2 } = await import("./execute-AQWHZKDH.js");
|
|
4056
4199
|
const runAllReady = options.runAllReady === true;
|
|
4200
|
+
const scopeIds = options.onlyAtomIds ? new Set(options.onlyAtomIds) : null;
|
|
4057
4201
|
const attempted = /* @__PURE__ */ new Set();
|
|
4058
4202
|
let queueStarted = false;
|
|
4059
4203
|
while (true) {
|
|
4060
4204
|
const atoms = await listLocalAtoms2();
|
|
4061
|
-
const readyAtoms = atoms.filter((a) => a.status === "READY").sort(byMostRecent);
|
|
4205
|
+
const readyAtoms = atoms.filter((a) => a.status === "READY" && (!scopeIds || scopeIds.has(a.externalId))).sort(byMostRecent);
|
|
4062
4206
|
if (readyAtoms.length === 0) {
|
|
4063
4207
|
const inProgressAtoms = atoms.filter((a) => a.status === "IN_PROGRESS").sort(byMostRecent);
|
|
4064
4208
|
if (inProgressAtoms.length > 0) {
|
|
4065
4209
|
const current = inProgressAtoms[0];
|
|
4066
|
-
console.log(
|
|
4067
|
-
console.log(
|
|
4210
|
+
console.log(chalk6.yellow(`No READY atoms found. Current in-progress atom: ${current?.externalId}.`));
|
|
4211
|
+
console.log(chalk6.dim("Use `archon show <atom-id>` to inspect status, or plan a new task."));
|
|
4068
4212
|
return;
|
|
4069
4213
|
}
|
|
4070
4214
|
const blockedByPath = atoms.filter((a) => a.status === "BLOCKED").sort(byMostRecent).find((a) => (a.errorMessage ?? "").toLowerCase().includes("outside the allowed paths"));
|
|
4071
4215
|
if (blockedByPath) {
|
|
4072
|
-
console.log(
|
|
4073
|
-
console.log(
|
|
4216
|
+
console.log(chalk6.yellow(`No READY atoms found. Latest blocked atom: ${blockedByPath.externalId}.`));
|
|
4217
|
+
console.log(chalk6.dim('This atom is blocked by governance path scope. Tell me: "adjust this atom to allowed paths".'));
|
|
4074
4218
|
return;
|
|
4075
4219
|
}
|
|
4076
4220
|
if (queueStarted && runAllReady) {
|
|
4077
|
-
console.log(
|
|
4221
|
+
console.log(chalk6.green("\nQueue execution complete. No READY atoms remain."));
|
|
4222
|
+
} else if (scopeIds && scopeIds.size > 0) {
|
|
4223
|
+
console.log(chalk6.yellow("No READY atoms found for this approved task scope."));
|
|
4078
4224
|
} else {
|
|
4079
|
-
console.log(
|
|
4225
|
+
console.log(chalk6.yellow("No pending atoms found. Tell me what to plan next."));
|
|
4080
4226
|
}
|
|
4081
4227
|
return;
|
|
4082
4228
|
}
|
|
4083
4229
|
const nextAtom = readyAtoms[0];
|
|
4084
4230
|
if (!nextAtom) {
|
|
4085
|
-
console.log(
|
|
4231
|
+
console.log(chalk6.yellow("No pending atoms found. Tell me what to plan next."));
|
|
4086
4232
|
return;
|
|
4087
4233
|
}
|
|
4088
4234
|
if (runAllReady && attempted.has(nextAtom.externalId)) {
|
|
4089
|
-
console.log(
|
|
4090
|
-
console.log(
|
|
4235
|
+
console.log(chalk6.yellow(`Stopping queue execution: ${nextAtom.externalId} is still READY after an execution attempt.`));
|
|
4236
|
+
console.log(chalk6.dim("Inspect with `archon show <atom-id>` before continuing."));
|
|
4091
4237
|
return;
|
|
4092
4238
|
}
|
|
4093
4239
|
attempted.add(nextAtom.externalId);
|
|
4094
4240
|
queueStarted = true;
|
|
4095
4241
|
if (runAllReady) {
|
|
4096
|
-
console.log(
|
|
4242
|
+
console.log(chalk6.dim(`
|
|
4097
4243
|
Queue execution: running ${nextAtom.externalId}...
|
|
4098
4244
|
`));
|
|
4099
4245
|
} else {
|
|
4100
|
-
console.log(
|
|
4246
|
+
console.log(chalk6.dim(`
|
|
4101
4247
|
Continuing with ${nextAtom.externalId}...
|
|
4102
4248
|
`));
|
|
4103
4249
|
}
|
|
@@ -4112,8 +4258,8 @@ Continuing with ${nextAtom.externalId}...
|
|
|
4112
4258
|
const executedAtom = refreshed.find((a) => a.externalId === nextAtom.externalId);
|
|
4113
4259
|
const status2 = executedAtom?.status ?? "UNKNOWN";
|
|
4114
4260
|
if (status2 !== "DONE") {
|
|
4115
|
-
console.log(
|
|
4116
|
-
console.log(
|
|
4261
|
+
console.log(chalk6.yellow(`Queue execution paused at ${nextAtom.externalId} (status: ${status2}).`));
|
|
4262
|
+
console.log(chalk6.dim('Resolve this atom, then run "continue" to resume the queue.'));
|
|
4117
4263
|
return;
|
|
4118
4264
|
}
|
|
4119
4265
|
}
|
|
@@ -4127,19 +4273,19 @@ async function replanLatestBlockedAtom(cwd) {
|
|
|
4127
4273
|
return bTime - aTime;
|
|
4128
4274
|
})[0];
|
|
4129
4275
|
if (!blocked) {
|
|
4130
|
-
console.log(
|
|
4276
|
+
console.log(chalk6.yellow("No blocked atom with path-scope guidance found."));
|
|
4131
4277
|
return;
|
|
4132
4278
|
}
|
|
4133
4279
|
const allowedPaths = await listArchitecturePaths(cwd);
|
|
4134
4280
|
const scope = allowedPaths.length > 0 ? allowedPaths.join(", ") : "existing architecture component paths";
|
|
4135
|
-
console.log(
|
|
4281
|
+
console.log(chalk6.dim("\n> Re-planning the blocked task with explicit allowed-path constraints...\n"));
|
|
4136
4282
|
await plan2(`${blocked.title}
|
|
4137
4283
|
|
|
4138
4284
|
Constraints:
|
|
4139
4285
|
- Only modify files within these allowed architecture paths: ${scope}
|
|
4140
4286
|
- If required files are outside scope, first propose the minimum ARCHITECTURE.md path update needed.`, { conversational: true });
|
|
4141
4287
|
await showLatestPlannedAtom(cwd);
|
|
4142
|
-
console.log(
|
|
4288
|
+
console.log(chalk6.dim('\nReply "continue" to execute this re-scoped atom.'));
|
|
4143
4289
|
}
|
|
4144
4290
|
async function listArchitecturePaths(cwd) {
|
|
4145
4291
|
try {
|
|
@@ -4156,14 +4302,14 @@ async function showMainMenu() {
|
|
|
4156
4302
|
const cwd = process.cwd();
|
|
4157
4303
|
while (true) {
|
|
4158
4304
|
const state = detectProjectState(cwd);
|
|
4159
|
-
console.log(
|
|
4305
|
+
console.log(chalk6.bold("What would you like to do?\n"));
|
|
4160
4306
|
if (state.isWebProject) {
|
|
4161
4307
|
const { loadWebChecks, formatWebCheckStatus } = await import("./web-checks-4BSYXWDF.js");
|
|
4162
4308
|
const prefs = await loadWebChecks(cwd);
|
|
4163
|
-
console.log(
|
|
4164
|
-
console.log(
|
|
4165
|
-
console.log(
|
|
4166
|
-
console.log(
|
|
4309
|
+
console.log(chalk6.dim("Web checks status:"));
|
|
4310
|
+
console.log(chalk6.dim(` A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
4311
|
+
console.log(chalk6.dim(` SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
4312
|
+
console.log(chalk6.dim(` GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
4167
4313
|
console.log();
|
|
4168
4314
|
}
|
|
4169
4315
|
const choices = [
|
|
@@ -4184,9 +4330,9 @@ async function showMainMenu() {
|
|
|
4184
4330
|
{ key: "q", label: "Quit", action: async () => process.exit(0) }
|
|
4185
4331
|
];
|
|
4186
4332
|
for (const choice2 of choices) {
|
|
4187
|
-
console.log(` ${
|
|
4333
|
+
console.log(` ${chalk6.cyan(choice2.key)}) ${choice2.label}`);
|
|
4188
4334
|
}
|
|
4189
|
-
console.log(
|
|
4335
|
+
console.log(chalk6.dim(' (Type "/" for quick commands, or "upgrade"/"help" anytime)'));
|
|
4190
4336
|
console.log();
|
|
4191
4337
|
const selected = await promptWithCommands("Tell me what you want to do (or enter a shortcut)", { allowMultiline: true });
|
|
4192
4338
|
const choice = choices.find((c) => c.key === selected.toLowerCase());
|
|
@@ -4197,11 +4343,11 @@ async function showMainMenu() {
|
|
|
4197
4343
|
if (selected.trim()) {
|
|
4198
4344
|
const handled = await handleFreeformJourneyInput(cwd, selected.trim());
|
|
4199
4345
|
if (!handled) {
|
|
4200
|
-
console.log(
|
|
4346
|
+
console.log(chalk6.yellow("I did not catch that. Try describing your goal in one sentence."));
|
|
4201
4347
|
}
|
|
4202
4348
|
continue;
|
|
4203
4349
|
}
|
|
4204
|
-
console.log(
|
|
4350
|
+
console.log(chalk6.yellow("Invalid choice. Please try again."));
|
|
4205
4351
|
}
|
|
4206
4352
|
}
|
|
4207
4353
|
async function handleFreeformJourneyInput(cwd, input) {
|
|
@@ -4217,23 +4363,23 @@ async function handleFreeformJourneyInput(cwd, input) {
|
|
|
4217
4363
|
}
|
|
4218
4364
|
const intent = detectUserIntent(freeform);
|
|
4219
4365
|
if (isReadOnlyExploreRequest(freeform) || intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
4220
|
-
console.log(
|
|
4366
|
+
console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
|
|
4221
4367
|
await runExploreFlow(cwd, freeform);
|
|
4222
4368
|
return true;
|
|
4223
4369
|
}
|
|
4224
4370
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
4225
4371
|
const state = detectProjectState(cwd);
|
|
4226
4372
|
if (state.hasArchitecture) {
|
|
4227
|
-
console.log(
|
|
4373
|
+
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
4228
4374
|
const { plan: plan3 } = await import("./plan-I3P6U2ZM.js");
|
|
4229
4375
|
await plan3(await withAllowedPathScope(cwd, freeform), { conversational: true });
|
|
4230
4376
|
return true;
|
|
4231
4377
|
}
|
|
4232
|
-
console.log(
|
|
4378
|
+
console.log(chalk6.dim("\n> Let me understand your project better...\n"));
|
|
4233
4379
|
await runConversationalInterview(cwd, freeform);
|
|
4234
4380
|
return true;
|
|
4235
4381
|
}
|
|
4236
|
-
console.log(
|
|
4382
|
+
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
4237
4383
|
const { plan: plan2 } = await import("./plan-I3P6U2ZM.js");
|
|
4238
4384
|
await plan2(await withAllowedPathScope(cwd, freeform), { conversational: true });
|
|
4239
4385
|
return true;
|
|
@@ -4284,14 +4430,14 @@ async function handlePostExploreAction(cwd, request, options = {}) {
|
|
|
4284
4430
|
}
|
|
4285
4431
|
const intent = detectUserIntent(request);
|
|
4286
4432
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
4287
|
-
console.log(
|
|
4433
|
+
console.log(chalk6.dim("> Let me understand your project better...\n"));
|
|
4288
4434
|
await runConversationalInterview(cwd, request);
|
|
4289
4435
|
return;
|
|
4290
4436
|
}
|
|
4291
4437
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
4292
|
-
console.log(
|
|
4438
|
+
console.log(chalk6.dim("> I can go deeper. Creating a concrete task from your request...\n"));
|
|
4293
4439
|
} else {
|
|
4294
|
-
console.log(
|
|
4440
|
+
console.log(chalk6.dim("> Got it! Creating a task for this...\n"));
|
|
4295
4441
|
}
|
|
4296
4442
|
const { plan: plan2 } = await import("./plan-I3P6U2ZM.js");
|
|
4297
4443
|
await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
|
|
@@ -4301,7 +4447,7 @@ async function handlePostExploreAction(cwd, request, options = {}) {
|
|
|
4301
4447
|
return;
|
|
4302
4448
|
}
|
|
4303
4449
|
await showLatestPlannedAtom(cwd);
|
|
4304
|
-
console.log(
|
|
4450
|
+
console.log(chalk6.dim('\nReply "execute atom" when you want implementation to start, or tell me what to change.'));
|
|
4305
4451
|
}
|
|
4306
4452
|
}
|
|
4307
4453
|
async function withAllowedPathScope(cwd, request) {
|
|
@@ -4330,13 +4476,13 @@ async function listAtoms() {
|
|
|
4330
4476
|
async function executeNext() {
|
|
4331
4477
|
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-I3P6U2ZM.js");
|
|
4332
4478
|
const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
|
|
4333
|
-
const { loadExecutionPreferences } = await import("./preferences-
|
|
4479
|
+
const { loadExecutionPreferences } = await import("./preferences-MTGN2VZK.js");
|
|
4334
4480
|
const cwd = process.cwd();
|
|
4335
4481
|
const atoms = await listLocalAtoms2();
|
|
4336
4482
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
4337
4483
|
const readyAtoms = atoms.filter((a) => a.status === "READY");
|
|
4338
4484
|
if (pendingAtoms.length === 0) {
|
|
4339
|
-
console.log(
|
|
4485
|
+
console.log(chalk6.yellow('No pending atoms. Use "archon plan" to create one.'));
|
|
4340
4486
|
return;
|
|
4341
4487
|
}
|
|
4342
4488
|
if (pendingAtoms.length > 1) {
|
|
@@ -4344,20 +4490,20 @@ async function executeNext() {
|
|
|
4344
4490
|
const prefs = await loadExecutionPreferences(cwd);
|
|
4345
4491
|
const config = await loadConfig();
|
|
4346
4492
|
const canUseCloud = (config.tier ?? "FREE") === "CREDITS";
|
|
4347
|
-
console.log(
|
|
4348
|
-
console.log(` ${
|
|
4349
|
-
console.log(` ${
|
|
4350
|
-
console.log(` ${
|
|
4351
|
-
console.log(` ${
|
|
4493
|
+
console.log(chalk6.blue("\n-- Project Analysis --\n"));
|
|
4494
|
+
console.log(` ${chalk6.bold("Atoms:")} ${analysis.atomCount}`);
|
|
4495
|
+
console.log(` ${chalk6.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
|
|
4496
|
+
console.log(` ${chalk6.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
|
|
4497
|
+
console.log(` ${chalk6.bold("Suggested:")} ${analysis.suggestedMode} - ${getModeDescription(analysis.suggestedMode)}`);
|
|
4352
4498
|
console.log();
|
|
4353
4499
|
let selectedMode = "sequential";
|
|
4354
4500
|
if (canUseCloud && prefs.cloudMode === "always" && analysis.suggestedMode === "parallel-cloud") {
|
|
4355
4501
|
selectedMode = "parallel-cloud";
|
|
4356
|
-
console.log(
|
|
4502
|
+
console.log(chalk6.green(`
|
|
4357
4503
|
\u2713 Auto-selected parallel cloud execution (preference: always)`));
|
|
4358
4504
|
} else if (prefs.parallelMode === "always" && analysis.suggestedMode !== "sequential") {
|
|
4359
4505
|
selectedMode = "parallel-local";
|
|
4360
|
-
console.log(
|
|
4506
|
+
console.log(chalk6.green(`
|
|
4361
4507
|
\u2713 Auto-selected parallel local execution (preference: always)`));
|
|
4362
4508
|
} else if (prefs.parallelMode === "ask" || canUseCloud && prefs.cloudMode === "ask") {
|
|
4363
4509
|
const options = [
|
|
@@ -4373,18 +4519,18 @@ async function executeNext() {
|
|
|
4373
4519
|
}
|
|
4374
4520
|
if (selectedMode !== "sequential") {
|
|
4375
4521
|
if (readyAtoms.length === 0) {
|
|
4376
|
-
console.log(
|
|
4522
|
+
console.log(chalk6.yellow("No READY atoms available for parallel execution."));
|
|
4377
4523
|
return;
|
|
4378
4524
|
}
|
|
4379
|
-
console.log(
|
|
4525
|
+
console.log(chalk6.dim("\nPending atoms:"));
|
|
4380
4526
|
for (const atom of readyAtoms) {
|
|
4381
|
-
console.log(
|
|
4527
|
+
console.log(chalk6.dim(` - ${atom.id}: ${atom.title}`));
|
|
4382
4528
|
}
|
|
4383
4529
|
console.log();
|
|
4384
4530
|
const raw = await prompt("Enter atom IDs to run in parallel (comma-separated, or press Enter for all)");
|
|
4385
4531
|
const selectedIds = raw.trim() ? raw.split(",").map((s) => s.trim()).filter(Boolean) : readyAtoms.map((a) => a.id);
|
|
4386
4532
|
if (selectedIds.length === 0) {
|
|
4387
|
-
console.log(
|
|
4533
|
+
console.log(chalk6.yellow("No atoms selected."));
|
|
4388
4534
|
return;
|
|
4389
4535
|
}
|
|
4390
4536
|
let runIds = selectedIds;
|
|
@@ -4395,7 +4541,7 @@ async function executeNext() {
|
|
|
4395
4541
|
);
|
|
4396
4542
|
if (!override) {
|
|
4397
4543
|
runIds = selectedIds.slice(0, prefs.maxParallelAgents);
|
|
4398
|
-
console.log(
|
|
4544
|
+
console.log(chalk6.dim(`Running first ${runIds.length} atoms.`));
|
|
4399
4545
|
}
|
|
4400
4546
|
}
|
|
4401
4547
|
if (selectedMode === "parallel-cloud") {
|
|
@@ -4414,7 +4560,7 @@ async function executeNext() {
|
|
|
4414
4560
|
const { execute: execute2 } = await import("./execute-AQWHZKDH.js");
|
|
4415
4561
|
await execute2(targetId, {});
|
|
4416
4562
|
} else {
|
|
4417
|
-
console.log(
|
|
4563
|
+
console.log(chalk6.yellow("No atom to execute."));
|
|
4418
4564
|
}
|
|
4419
4565
|
}
|
|
4420
4566
|
async function reportBug() {
|
|
@@ -4429,26 +4575,26 @@ async function viewStatus() {
|
|
|
4429
4575
|
await status2();
|
|
4430
4576
|
}
|
|
4431
4577
|
async function settingsMenu() {
|
|
4432
|
-
const { interactiveSettings } = await import("./preferences-
|
|
4578
|
+
const { interactiveSettings } = await import("./preferences-MTGN2VZK.js");
|
|
4433
4579
|
await interactiveSettings();
|
|
4434
4580
|
}
|
|
4435
4581
|
async function reviewCode() {
|
|
4436
4582
|
const cwd = process.cwd();
|
|
4437
4583
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
4438
4584
|
if (!existsSync6(reviewDbPath)) {
|
|
4439
|
-
console.log(
|
|
4585
|
+
console.log(chalk6.dim("Code review not initialized. Starting setup...\n"));
|
|
4440
4586
|
const { reviewInit: reviewInit2 } = await import("./review-7BBVCF7H.js");
|
|
4441
4587
|
await reviewInit2();
|
|
4442
4588
|
console.log();
|
|
4443
4589
|
}
|
|
4444
|
-
console.log(
|
|
4445
|
-
console.log(
|
|
4446
|
-
console.log(` ${
|
|
4447
|
-
console.log(` ${
|
|
4448
|
-
console.log(` ${
|
|
4449
|
-
console.log(` ${
|
|
4450
|
-
console.log(` ${
|
|
4451
|
-
console.log(` ${
|
|
4590
|
+
console.log(chalk6.bold("\nCode Review Options:\n"));
|
|
4591
|
+
console.log(chalk6.dim("You can type naturally (recommended) or use a shortcut:\n"));
|
|
4592
|
+
console.log(` ${chalk6.cyan("1")}) Analyze project`);
|
|
4593
|
+
console.log(` ${chalk6.cyan("2")}) Show review status`);
|
|
4594
|
+
console.log(` ${chalk6.cyan("3")}) Review next file`);
|
|
4595
|
+
console.log(` ${chalk6.cyan("4")}) List all tasks`);
|
|
4596
|
+
console.log(` ${chalk6.cyan("5")}) Run AI review on all pending`);
|
|
4597
|
+
console.log(` ${chalk6.cyan("b")}) Back to main menu`);
|
|
4452
4598
|
console.log();
|
|
4453
4599
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4454
4600
|
const choice = resolveReviewChoice(raw);
|
|
@@ -4487,7 +4633,7 @@ async function reviewCode() {
|
|
|
4487
4633
|
return;
|
|
4488
4634
|
}
|
|
4489
4635
|
}
|
|
4490
|
-
console.log(
|
|
4636
|
+
console.log(chalk6.yellow("I did not catch that. Tell me what review action you want."));
|
|
4491
4637
|
}
|
|
4492
4638
|
await reviewCode();
|
|
4493
4639
|
}
|
|
@@ -4515,13 +4661,13 @@ async function handleInSessionCommand(input) {
|
|
|
4515
4661
|
}
|
|
4516
4662
|
if (normalized === "help" || normalized === "?" || normalized === "archon help") {
|
|
4517
4663
|
console.log();
|
|
4518
|
-
console.log(
|
|
4519
|
-
console.log(
|
|
4520
|
-
console.log(
|
|
4521
|
-
console.log(
|
|
4522
|
-
console.log(
|
|
4523
|
-
console.log(
|
|
4524
|
-
console.log(
|
|
4664
|
+
console.log(chalk6.bold("Available commands (type anytime):"));
|
|
4665
|
+
console.log(chalk6.dim(" upgrade \u2014 Switch to BYOK or Managed plan"));
|
|
4666
|
+
console.log(chalk6.dim(" status \u2014 Show login and tier status"));
|
|
4667
|
+
console.log(chalk6.dim(" keys \u2014 Manage API keys (BYOK tier)"));
|
|
4668
|
+
console.log(chalk6.dim(" /workflow \u2014 Open classic workflow menu"));
|
|
4669
|
+
console.log(chalk6.dim(" quit / q \u2014 Exit ArchonDev"));
|
|
4670
|
+
console.log(chalk6.dim(" skip \u2014 Skip current question"));
|
|
4525
4671
|
console.log();
|
|
4526
4672
|
return true;
|
|
4527
4673
|
}
|
|
@@ -4531,23 +4677,23 @@ async function handleInSessionCommand(input) {
|
|
|
4531
4677
|
return true;
|
|
4532
4678
|
}
|
|
4533
4679
|
if (normalized === "quit" || normalized === "exit" || normalized === "q") {
|
|
4534
|
-
console.log(
|
|
4680
|
+
console.log(chalk6.dim("Goodbye!"));
|
|
4535
4681
|
process.exit(0);
|
|
4536
4682
|
}
|
|
4537
4683
|
return false;
|
|
4538
4684
|
}
|
|
4539
4685
|
function showSlashCommandMenu() {
|
|
4540
4686
|
console.log();
|
|
4541
|
-
console.log(
|
|
4542
|
-
console.log(
|
|
4543
|
-
console.log(
|
|
4544
|
-
console.log(
|
|
4545
|
-
console.log(
|
|
4546
|
-
console.log(
|
|
4547
|
-
console.log(
|
|
4548
|
-
console.log(
|
|
4549
|
-
console.log(
|
|
4550
|
-
console.log(
|
|
4687
|
+
console.log(chalk6.bold("Quick Commands"));
|
|
4688
|
+
console.log(chalk6.dim(" /plan <task> Create a plan from a one-line task"));
|
|
4689
|
+
console.log(chalk6.dim(" /list List atoms"));
|
|
4690
|
+
console.log(chalk6.dim(" /execute Execute next atom"));
|
|
4691
|
+
console.log(chalk6.dim(" /review Open code review menu"));
|
|
4692
|
+
console.log(chalk6.dim(" /status Show account/status"));
|
|
4693
|
+
console.log(chalk6.dim(" /settings Open settings & preferences"));
|
|
4694
|
+
console.log(chalk6.dim(" /upgrade Open tier upgrade menu"));
|
|
4695
|
+
console.log(chalk6.dim(" /workflow Open classic workflow menu"));
|
|
4696
|
+
console.log(chalk6.dim(" /quit Exit ArchonDev"));
|
|
4551
4697
|
console.log();
|
|
4552
4698
|
}
|
|
4553
4699
|
async function handleSlashCommand(input) {
|
|
@@ -4596,7 +4742,7 @@ async function handleSlashCommand(input) {
|
|
|
4596
4742
|
return true;
|
|
4597
4743
|
case "/quit":
|
|
4598
4744
|
case "/exit":
|
|
4599
|
-
console.log(
|
|
4745
|
+
console.log(chalk6.dim("Goodbye!"));
|
|
4600
4746
|
process.exit(0);
|
|
4601
4747
|
}
|
|
4602
4748
|
return false;
|
|
@@ -4604,7 +4750,7 @@ async function handleSlashCommand(input) {
|
|
|
4604
4750
|
function prompt(question) {
|
|
4605
4751
|
return new Promise((resolve) => {
|
|
4606
4752
|
const safeMode = isTerminalSafeMode();
|
|
4607
|
-
const promptPrefix = safeMode ? ">" :
|
|
4753
|
+
const promptPrefix = safeMode ? ">" : chalk6.cyan("?");
|
|
4608
4754
|
const rl = readline.createInterface({
|
|
4609
4755
|
input: process.stdin,
|
|
4610
4756
|
output: process.stdout,
|
|
@@ -4619,7 +4765,7 @@ function prompt(question) {
|
|
|
4619
4765
|
function promptMultiline(question) {
|
|
4620
4766
|
return new Promise((resolve) => {
|
|
4621
4767
|
const safeMode = isTerminalSafeMode();
|
|
4622
|
-
const promptPrefix = safeMode ? ">" :
|
|
4768
|
+
const promptPrefix = safeMode ? ">" : chalk6.cyan("?");
|
|
4623
4769
|
const rl = readline.createInterface({
|
|
4624
4770
|
input: process.stdin,
|
|
4625
4771
|
output: process.stdout,
|
|
@@ -4655,14 +4801,14 @@ async function promptWithCommands(question, options = {}) {
|
|
|
4655
4801
|
if (!handled) {
|
|
4656
4802
|
return answer;
|
|
4657
4803
|
}
|
|
4658
|
-
console.log(
|
|
4804
|
+
console.log(chalk6.dim("(Returning to previous question...)\n"));
|
|
4659
4805
|
}
|
|
4660
4806
|
}
|
|
4661
4807
|
async function runWebChecksSuite() {
|
|
4662
4808
|
const { a11yCheck: a11yCheck2 } = await import("./a11y-O35BAA25.js");
|
|
4663
4809
|
const { seoCheck } = await import("./seo-PMI42KRZ.js");
|
|
4664
4810
|
const { geoAudit } = await import("./geo-KXVALNSF.js");
|
|
4665
|
-
console.log(
|
|
4811
|
+
console.log(chalk6.blue("\nRunning web checks (A11y, SEO, GEO)...\n"));
|
|
4666
4812
|
await a11yCheck2({});
|
|
4667
4813
|
await seoCheck({});
|
|
4668
4814
|
await geoAudit();
|
|
@@ -4671,19 +4817,19 @@ async function showWebChecksMenu() {
|
|
|
4671
4817
|
const cwd = process.cwd();
|
|
4672
4818
|
const { loadWebChecks, formatWebCheckStatus, setWebPromptMode } = await import("./web-checks-4BSYXWDF.js");
|
|
4673
4819
|
const prefs = await loadWebChecks(cwd);
|
|
4674
|
-
console.log(
|
|
4675
|
-
console.log(
|
|
4676
|
-
console.log(
|
|
4677
|
-
console.log(
|
|
4820
|
+
console.log(chalk6.bold("\nWeb Checks (SEO / GEO / A11y)\n"));
|
|
4821
|
+
console.log(chalk6.dim(`A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
4822
|
+
console.log(chalk6.dim(`SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
4823
|
+
console.log(chalk6.dim(`GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
4678
4824
|
console.log();
|
|
4679
|
-
console.log(` ${
|
|
4680
|
-
console.log(` ${
|
|
4681
|
-
console.log(` ${
|
|
4682
|
-
console.log(` ${
|
|
4683
|
-
console.log(` ${
|
|
4684
|
-
console.log(` ${
|
|
4685
|
-
console.log(` ${
|
|
4686
|
-
console.log(` ${
|
|
4825
|
+
console.log(` ${chalk6.cyan("1")}) Run all checks`);
|
|
4826
|
+
console.log(` ${chalk6.cyan("2")}) Run accessibility check`);
|
|
4827
|
+
console.log(` ${chalk6.cyan("3")}) Run SEO check`);
|
|
4828
|
+
console.log(` ${chalk6.cyan("4")}) Run GEO audit`);
|
|
4829
|
+
console.log(` ${chalk6.cyan("5")}) Generate GEO identity`);
|
|
4830
|
+
console.log(` ${chalk6.cyan("6")}) Generate GEO schema`);
|
|
4831
|
+
console.log(` ${chalk6.cyan("7")}) Set prompt mode (ask/always/never)`);
|
|
4832
|
+
console.log(` ${chalk6.cyan("b")}) Back to main menu`);
|
|
4687
4833
|
console.log();
|
|
4688
4834
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4689
4835
|
const choice = resolveWebChecksChoice(raw);
|
|
@@ -4718,9 +4864,9 @@ async function showWebChecksMenu() {
|
|
|
4718
4864
|
}
|
|
4719
4865
|
case "7": {
|
|
4720
4866
|
console.log();
|
|
4721
|
-
console.log(` ${
|
|
4722
|
-
console.log(` ${
|
|
4723
|
-
console.log(` ${
|
|
4867
|
+
console.log(` ${chalk6.cyan("1")}) Ask each session`);
|
|
4868
|
+
console.log(` ${chalk6.cyan("2")}) Always run automatically`);
|
|
4869
|
+
console.log(` ${chalk6.cyan("3")}) Never prompt`);
|
|
4724
4870
|
console.log();
|
|
4725
4871
|
const modeChoiceRaw = await promptWithCommands("Set mode (ask / always / never)");
|
|
4726
4872
|
const modeChoice = resolvePromptModeChoice(modeChoiceRaw);
|
|
@@ -4736,7 +4882,7 @@ async function showWebChecksMenu() {
|
|
|
4736
4882
|
return;
|
|
4737
4883
|
}
|
|
4738
4884
|
}
|
|
4739
|
-
console.log(
|
|
4885
|
+
console.log(chalk6.yellow("I did not catch that. Tell me which web check you want."));
|
|
4740
4886
|
}
|
|
4741
4887
|
if (choice.toLowerCase() !== "b") {
|
|
4742
4888
|
await showWebChecksMenu();
|
|
@@ -4752,11 +4898,11 @@ async function maybePromptWebChecks(cwd, projectState) {
|
|
|
4752
4898
|
return;
|
|
4753
4899
|
}
|
|
4754
4900
|
if (prefs.promptMode === "always") {
|
|
4755
|
-
console.log(
|
|
4901
|
+
console.log(chalk6.blue("\nWeb project detected. Running web checks automatically...\n"));
|
|
4756
4902
|
await runWebChecksSuite();
|
|
4757
4903
|
return;
|
|
4758
4904
|
}
|
|
4759
|
-
console.log(
|
|
4905
|
+
console.log(chalk6.blue("\nWeb project detected."));
|
|
4760
4906
|
const choice = await promptChoice("Run web checks now?", [
|
|
4761
4907
|
{ key: "1", label: "Run all checks (A11y + SEO + GEO)" },
|
|
4762
4908
|
{ key: "2", label: "Choose checks" },
|
|
@@ -4778,7 +4924,7 @@ function promptYesNo(question, defaultValue) {
|
|
|
4778
4924
|
output: process.stdout
|
|
4779
4925
|
});
|
|
4780
4926
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
4781
|
-
rl.question(`${
|
|
4927
|
+
rl.question(`${chalk6.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
4782
4928
|
rl.close();
|
|
4783
4929
|
if (answer.trim() === "") {
|
|
4784
4930
|
resolve(defaultValue);
|
|
@@ -4790,15 +4936,15 @@ function promptYesNo(question, defaultValue) {
|
|
|
4790
4936
|
}
|
|
4791
4937
|
function promptChoice(question, options, defaultKey) {
|
|
4792
4938
|
return new Promise((resolve) => {
|
|
4793
|
-
console.log(`${
|
|
4939
|
+
console.log(`${chalk6.cyan("?")} ${question}`);
|
|
4794
4940
|
for (const opt of options) {
|
|
4795
|
-
console.log(` ${
|
|
4941
|
+
console.log(` ${chalk6.dim(opt.key)}) ${opt.label}`);
|
|
4796
4942
|
}
|
|
4797
4943
|
const rl = readline.createInterface({
|
|
4798
4944
|
input: process.stdin,
|
|
4799
4945
|
output: process.stdout
|
|
4800
4946
|
});
|
|
4801
|
-
rl.question(` ${
|
|
4947
|
+
rl.question(` ${chalk6.dim("Enter choice or describe what you want")}: `, (answer) => {
|
|
4802
4948
|
rl.close();
|
|
4803
4949
|
const trimmed = answer.trim();
|
|
4804
4950
|
if (trimmed) {
|
|
@@ -4861,7 +5007,7 @@ function resolvePromptModeChoice(input) {
|
|
|
4861
5007
|
}
|
|
4862
5008
|
|
|
4863
5009
|
// src/cli/credits.ts
|
|
4864
|
-
import
|
|
5010
|
+
import chalk7 from "chalk";
|
|
4865
5011
|
import ora from "ora";
|
|
4866
5012
|
import open from "open";
|
|
4867
5013
|
import readline2 from "readline";
|
|
@@ -4907,20 +5053,20 @@ async function showCredits() {
|
|
|
4907
5053
|
const profile = data;
|
|
4908
5054
|
spinner.stop();
|
|
4909
5055
|
console.log();
|
|
4910
|
-
console.log(
|
|
5056
|
+
console.log(chalk7.bold("\u{1F4B0} Credit Balance"));
|
|
4911
5057
|
console.log();
|
|
4912
5058
|
const balance = (profile.credit_balance_cents || 0) / 100;
|
|
4913
5059
|
console.log(` Tier: ${formatTier(profile.tier)}`);
|
|
4914
|
-
console.log(` Balance: ${
|
|
5060
|
+
console.log(` Balance: ${chalk7.green(`$${balance.toFixed(2)}`)}`);
|
|
4915
5061
|
if (profile.tier === "FREE") {
|
|
4916
5062
|
console.log(` Atoms: ${profile.atoms_used_this_month}/10,000 this month`);
|
|
4917
5063
|
console.log();
|
|
4918
|
-
console.log(
|
|
5064
|
+
console.log(chalk7.dim(" Upgrade to Credits tier: archon credits add"));
|
|
4919
5065
|
printCreditsNextAction("FREE");
|
|
4920
5066
|
} else if (profile.tier === "CREDITS") {
|
|
4921
5067
|
console.log();
|
|
4922
|
-
console.log(
|
|
4923
|
-
console.log(
|
|
5068
|
+
console.log(chalk7.dim(" Add more credits: archon credits add"));
|
|
5069
|
+
console.log(chalk7.dim(" Detailed usage by model: archon usage"));
|
|
4924
5070
|
printCreditsNextAction("CREDITS");
|
|
4925
5071
|
if (balance < 5) {
|
|
4926
5072
|
const addNow = await promptYesNo2("Balance is low. Add credits now?", false);
|
|
@@ -4930,8 +5076,8 @@ async function showCredits() {
|
|
|
4930
5076
|
}
|
|
4931
5077
|
} else if (profile.tier === "BYOK") {
|
|
4932
5078
|
console.log();
|
|
4933
|
-
console.log(
|
|
4934
|
-
console.log(
|
|
5079
|
+
console.log(chalk7.dim(" Using your own API keys - no credit charges"));
|
|
5080
|
+
console.log(chalk7.dim(" Estimated spend by model: archon usage"));
|
|
4935
5081
|
printCreditsNextAction("BYOK");
|
|
4936
5082
|
}
|
|
4937
5083
|
console.log();
|
|
@@ -4978,35 +5124,35 @@ async function addCredits(options = {}) {
|
|
|
4978
5124
|
}
|
|
4979
5125
|
spinner.succeed("Checkout ready");
|
|
4980
5126
|
console.log();
|
|
4981
|
-
console.log(
|
|
5127
|
+
console.log(chalk7.bold("\u{1F6D2} Add Credits"));
|
|
4982
5128
|
console.log();
|
|
4983
|
-
console.log(` Amount: ${
|
|
5129
|
+
console.log(` Amount: ${chalk7.green(`$${amountDollars.toFixed(2)}`)}`);
|
|
4984
5130
|
console.log();
|
|
4985
5131
|
console.log(" Opening checkout in browser...");
|
|
4986
5132
|
console.log();
|
|
4987
|
-
console.log(
|
|
5133
|
+
console.log(chalk7.dim(` Or visit: ${checkoutUrl}`));
|
|
4988
5134
|
console.log();
|
|
4989
5135
|
try {
|
|
4990
5136
|
await open(checkoutUrl);
|
|
4991
5137
|
} catch {
|
|
4992
|
-
console.log(
|
|
5138
|
+
console.log(chalk7.yellow(" Could not open browser. Please visit the URL above."));
|
|
4993
5139
|
}
|
|
4994
|
-
console.log(
|
|
4995
|
-
console.log(
|
|
4996
|
-
console.log(
|
|
5140
|
+
console.log(chalk7.bold("\nNext best action:"));
|
|
5141
|
+
console.log(chalk7.dim(` \u2022 Complete payment in browser, then run ${chalk7.cyan("archon credits")} to verify balance.`));
|
|
5142
|
+
console.log(chalk7.dim(` \u2022 Continue work with ${chalk7.cyan('archon plan "..."')} or ${chalk7.cyan("archon execute <ATOM-ID>")}.`));
|
|
4997
5143
|
} catch (err2) {
|
|
4998
5144
|
spinner.fail("Error preparing checkout");
|
|
4999
5145
|
console.error(err2);
|
|
5000
5146
|
}
|
|
5001
5147
|
}
|
|
5002
5148
|
function printCreditsNextAction(tier) {
|
|
5003
|
-
console.log(
|
|
5149
|
+
console.log(chalk7.bold(" Next best action:"));
|
|
5004
5150
|
if (tier === "CREDITS") {
|
|
5005
|
-
console.log(
|
|
5151
|
+
console.log(chalk7.dim(` \u2022 Keep at least $5 balance to avoid interruptions during plan/execute.`));
|
|
5006
5152
|
} else if (tier === "BYOK") {
|
|
5007
|
-
console.log(
|
|
5153
|
+
console.log(chalk7.dim(` \u2022 Manage provider keys with ${chalk7.cyan("archon keys add/list/remove")}.`));
|
|
5008
5154
|
} else {
|
|
5009
|
-
console.log(
|
|
5155
|
+
console.log(chalk7.dim(` \u2022 Upgrade to BYOK or Credits with ${chalk7.cyan("archon upgrade")}.`));
|
|
5010
5156
|
}
|
|
5011
5157
|
}
|
|
5012
5158
|
function promptYesNo2(question, defaultValue) {
|
|
@@ -5016,7 +5162,7 @@ function promptYesNo2(question, defaultValue) {
|
|
|
5016
5162
|
output: process.stdout
|
|
5017
5163
|
});
|
|
5018
5164
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
5019
|
-
rl.question(`${
|
|
5165
|
+
rl.question(`${chalk7.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
5020
5166
|
rl.close();
|
|
5021
5167
|
if (answer.trim() === "") {
|
|
5022
5168
|
resolve(defaultValue);
|
|
@@ -5050,15 +5196,15 @@ async function showHistory(options = {}) {
|
|
|
5050
5196
|
const usage = data;
|
|
5051
5197
|
spinner.stop();
|
|
5052
5198
|
console.log();
|
|
5053
|
-
console.log(
|
|
5199
|
+
console.log(chalk7.bold("Usage History"));
|
|
5054
5200
|
console.log();
|
|
5055
5201
|
if (!usage || usage.length === 0) {
|
|
5056
|
-
console.log(
|
|
5202
|
+
console.log(chalk7.dim(" No usage recorded yet."));
|
|
5057
5203
|
console.log();
|
|
5058
5204
|
return;
|
|
5059
5205
|
}
|
|
5060
|
-
console.log(
|
|
5061
|
-
console.log(
|
|
5206
|
+
console.log(chalk7.dim(" Model Tokens Cost Date"));
|
|
5207
|
+
console.log(chalk7.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"));
|
|
5062
5208
|
for (const row of usage) {
|
|
5063
5209
|
const model = row.model.padEnd(30).slice(0, 30);
|
|
5064
5210
|
const tokens = (row.input_tokens + row.output_tokens).toString().padStart(8);
|
|
@@ -5068,9 +5214,9 @@ async function showHistory(options = {}) {
|
|
|
5068
5214
|
}
|
|
5069
5215
|
const totalCost = usage.reduce((sum, r) => sum + r.base_cost, 0);
|
|
5070
5216
|
const totalTokens = usage.reduce((sum, r) => sum + r.input_tokens + r.output_tokens, 0);
|
|
5071
|
-
console.log(
|
|
5217
|
+
console.log(chalk7.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"));
|
|
5072
5218
|
console.log(
|
|
5073
|
-
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${
|
|
5219
|
+
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${chalk7.green(`$${totalCost.toFixed(4)}`.padStart(10))}`
|
|
5074
5220
|
);
|
|
5075
5221
|
console.log();
|
|
5076
5222
|
} catch (err2) {
|
|
@@ -5136,24 +5282,24 @@ async function manageBudget(options = {}) {
|
|
|
5136
5282
|
}
|
|
5137
5283
|
spinner.stop();
|
|
5138
5284
|
console.log();
|
|
5139
|
-
console.log(
|
|
5285
|
+
console.log(chalk7.bold("Monthly Budget"));
|
|
5140
5286
|
console.log();
|
|
5141
5287
|
if (profile.monthly_budget_cents === null) {
|
|
5142
|
-
console.log(` Budget: ${
|
|
5288
|
+
console.log(` Budget: ${chalk7.dim("No limit set")}`);
|
|
5143
5289
|
} else {
|
|
5144
5290
|
const budget = profile.monthly_budget_cents / 100;
|
|
5145
5291
|
const spend = (profile.monthly_spend_cents || 0) / 100;
|
|
5146
5292
|
const remaining = budget - spend;
|
|
5147
5293
|
const percent = budget > 0 ? Math.round(spend / budget * 100) : 0;
|
|
5148
|
-
console.log(` Budget: ${
|
|
5294
|
+
console.log(` Budget: ${chalk7.green(`$${budget.toFixed(2)}`)} / month`);
|
|
5149
5295
|
console.log(` Spent: $${spend.toFixed(2)} (${percent}%)`);
|
|
5150
|
-
console.log(` Remaining: ${remaining >= 0 ?
|
|
5296
|
+
console.log(` Remaining: ${remaining >= 0 ? chalk7.green(`$${remaining.toFixed(2)}`) : chalk7.red(`-$${Math.abs(remaining).toFixed(2)}`)}`);
|
|
5151
5297
|
}
|
|
5152
5298
|
console.log(` Alert at: ${profile.budget_alert_threshold_percent}% of budget`);
|
|
5153
5299
|
console.log();
|
|
5154
|
-
console.log(
|
|
5155
|
-
console.log(
|
|
5156
|
-
console.log(
|
|
5300
|
+
console.log(chalk7.dim(" Set budget: archon credits budget --set 50"));
|
|
5301
|
+
console.log(chalk7.dim(" Clear budget: archon credits budget --clear"));
|
|
5302
|
+
console.log(chalk7.dim(" Set alert: archon credits budget --alert 80"));
|
|
5157
5303
|
console.log();
|
|
5158
5304
|
} catch (err2) {
|
|
5159
5305
|
spinner.fail("Error managing budget");
|
|
@@ -5215,12 +5361,12 @@ async function manageAutoRecharge(options = {}) {
|
|
|
5215
5361
|
}
|
|
5216
5362
|
spinner.stop();
|
|
5217
5363
|
console.log();
|
|
5218
|
-
console.log(
|
|
5364
|
+
console.log(chalk7.bold("\u{1F504} Auto-Recharge"));
|
|
5219
5365
|
console.log();
|
|
5220
5366
|
if (!profile.auto_recharge_enabled) {
|
|
5221
|
-
console.log(` Status: ${
|
|
5367
|
+
console.log(` Status: ${chalk7.dim("Disabled")}`);
|
|
5222
5368
|
} else {
|
|
5223
|
-
console.log(` Status: ${
|
|
5369
|
+
console.log(` Status: ${chalk7.green("Enabled")}`);
|
|
5224
5370
|
if (profile.auto_recharge_threshold_cents !== null) {
|
|
5225
5371
|
console.log(` When: Balance drops below $${(profile.auto_recharge_threshold_cents / 100).toFixed(2)}`);
|
|
5226
5372
|
}
|
|
@@ -5228,10 +5374,10 @@ async function manageAutoRecharge(options = {}) {
|
|
|
5228
5374
|
console.log(` Amount: $${(profile.auto_recharge_amount_cents / 100).toFixed(2)}`);
|
|
5229
5375
|
}
|
|
5230
5376
|
}
|
|
5231
|
-
console.log(` Payment: ${profile.stripe_payment_method_id ?
|
|
5377
|
+
console.log(` Payment: ${profile.stripe_payment_method_id ? chalk7.green("Card saved") : chalk7.dim("No card saved")}`);
|
|
5232
5378
|
console.log();
|
|
5233
|
-
console.log(
|
|
5234
|
-
console.log(
|
|
5379
|
+
console.log(chalk7.dim(" Enable: archon credits auto-recharge --enable --threshold 5 --amount 20"));
|
|
5380
|
+
console.log(chalk7.dim(" Disable: archon credits auto-recharge --disable"));
|
|
5235
5381
|
console.log();
|
|
5236
5382
|
} catch (err2) {
|
|
5237
5383
|
spinner.fail("Error managing auto-recharge");
|
|
@@ -5261,21 +5407,21 @@ async function showAuditHistory(options = {}) {
|
|
|
5261
5407
|
});
|
|
5262
5408
|
if (error) {
|
|
5263
5409
|
spinner.fail("Could not fetch audit history");
|
|
5264
|
-
console.error(
|
|
5410
|
+
console.error(chalk7.dim(error.message));
|
|
5265
5411
|
return;
|
|
5266
5412
|
}
|
|
5267
5413
|
const history = data;
|
|
5268
5414
|
spinner.stop();
|
|
5269
5415
|
console.log();
|
|
5270
|
-
console.log(
|
|
5416
|
+
console.log(chalk7.bold("\u{1F4CB} Billing Audit History"));
|
|
5271
5417
|
console.log();
|
|
5272
5418
|
if (!history || history.length === 0) {
|
|
5273
|
-
console.log(
|
|
5419
|
+
console.log(chalk7.dim(" No billing events recorded yet."));
|
|
5274
5420
|
console.log();
|
|
5275
5421
|
return;
|
|
5276
5422
|
}
|
|
5277
|
-
console.log(
|
|
5278
|
-
console.log(
|
|
5423
|
+
console.log(chalk7.dim(" Event Amount Balance Date"));
|
|
5424
|
+
console.log(chalk7.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"));
|
|
5279
5425
|
for (const row of history) {
|
|
5280
5426
|
const eventType = formatEventType(row.event_type).padEnd(22);
|
|
5281
5427
|
const amount = row.amount_cents !== null ? formatAmount(row.event_type, row.amount_cents).padStart(10) : " -";
|
|
@@ -5283,10 +5429,10 @@ async function showAuditHistory(options = {}) {
|
|
|
5283
5429
|
const date = new Date(row.created_at).toLocaleDateString();
|
|
5284
5430
|
console.log(` ${eventType} ${amount} ${balance} ${date}`);
|
|
5285
5431
|
}
|
|
5286
|
-
console.log(
|
|
5432
|
+
console.log(chalk7.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"));
|
|
5287
5433
|
console.log();
|
|
5288
|
-
console.log(
|
|
5289
|
-
console.log(
|
|
5434
|
+
console.log(chalk7.dim(` Showing ${history.length} most recent events`));
|
|
5435
|
+
console.log(chalk7.dim(" Use --limit N to show more"));
|
|
5290
5436
|
console.log();
|
|
5291
5437
|
} catch (err2) {
|
|
5292
5438
|
spinner.fail("Error fetching audit history");
|
|
@@ -5296,19 +5442,19 @@ async function showAuditHistory(options = {}) {
|
|
|
5296
5442
|
function formatEventType(eventType) {
|
|
5297
5443
|
switch (eventType) {
|
|
5298
5444
|
case "CREDITS_PURCHASED":
|
|
5299
|
-
return
|
|
5445
|
+
return chalk7.green("+ Purchase");
|
|
5300
5446
|
case "CREDITS_DEDUCTED":
|
|
5301
|
-
return
|
|
5447
|
+
return chalk7.red("- Usage");
|
|
5302
5448
|
case "CREDITS_REFUNDED":
|
|
5303
|
-
return
|
|
5449
|
+
return chalk7.cyan("+ Refund");
|
|
5304
5450
|
case "BALANCE_ADJUSTED":
|
|
5305
|
-
return
|
|
5451
|
+
return chalk7.yellow("\xB1 Adjustment");
|
|
5306
5452
|
case "BUDGET_CHANGED":
|
|
5307
|
-
return
|
|
5453
|
+
return chalk7.blue("\u25C9 Budget");
|
|
5308
5454
|
case "TIER_CHANGED":
|
|
5309
|
-
return
|
|
5455
|
+
return chalk7.magenta("\u25C9 Tier");
|
|
5310
5456
|
case "USAGE_RECORDED":
|
|
5311
|
-
return
|
|
5457
|
+
return chalk7.dim("\u25C9 Usage");
|
|
5312
5458
|
default:
|
|
5313
5459
|
return eventType;
|
|
5314
5460
|
}
|
|
@@ -5316,20 +5462,20 @@ function formatEventType(eventType) {
|
|
|
5316
5462
|
function formatAmount(eventType, cents) {
|
|
5317
5463
|
const dollars = (cents / 100).toFixed(2);
|
|
5318
5464
|
if (eventType === "CREDITS_PURCHASED" || eventType === "CREDITS_REFUNDED") {
|
|
5319
|
-
return
|
|
5465
|
+
return chalk7.green(`+$${dollars}`);
|
|
5320
5466
|
} else if (eventType === "CREDITS_DEDUCTED") {
|
|
5321
|
-
return
|
|
5467
|
+
return chalk7.red(`-$${dollars}`);
|
|
5322
5468
|
}
|
|
5323
5469
|
return `$${dollars}`;
|
|
5324
5470
|
}
|
|
5325
5471
|
function formatTier(tier) {
|
|
5326
5472
|
switch (tier) {
|
|
5327
5473
|
case "FREE":
|
|
5328
|
-
return
|
|
5474
|
+
return chalk7.blue("Free (10k atoms/month)");
|
|
5329
5475
|
case "CREDITS":
|
|
5330
|
-
return
|
|
5476
|
+
return chalk7.green("Credits (Pay-as-you-go)");
|
|
5331
5477
|
case "BYOK":
|
|
5332
|
-
return
|
|
5478
|
+
return chalk7.magenta("BYOK (Bring Your Own Key)");
|
|
5333
5479
|
default:
|
|
5334
5480
|
return tier;
|
|
5335
5481
|
}
|
|
@@ -5606,7 +5752,7 @@ async function watch() {
|
|
|
5606
5752
|
|
|
5607
5753
|
// src/cli/deps.ts
|
|
5608
5754
|
import { Command } from "commander";
|
|
5609
|
-
import
|
|
5755
|
+
import chalk8 from "chalk";
|
|
5610
5756
|
import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
5611
5757
|
import { existsSync as existsSync8 } from "fs";
|
|
5612
5758
|
var DEPENDENCIES_FILENAME = "DEPENDENCIES.md";
|
|
@@ -5624,30 +5770,30 @@ Examples:
|
|
|
5624
5770
|
deps.command("list").description("List all dependency rules").option("-v, --verbose", "Show detailed information").action(async (options) => {
|
|
5625
5771
|
const parser = new DependencyParser();
|
|
5626
5772
|
if (!parser.exists()) {
|
|
5627
|
-
console.log(
|
|
5628
|
-
console.log(
|
|
5773
|
+
console.log(chalk8.yellow("No DEPENDENCIES.md found."));
|
|
5774
|
+
console.log(chalk8.dim("Create one with: archon deps add --source <path> --dependent <path>"));
|
|
5629
5775
|
return;
|
|
5630
5776
|
}
|
|
5631
5777
|
const result = await parser.parse();
|
|
5632
5778
|
if (!result.success) {
|
|
5633
|
-
console.log(
|
|
5779
|
+
console.log(chalk8.red(`Parse error: ${result.error}`));
|
|
5634
5780
|
return;
|
|
5635
5781
|
}
|
|
5636
5782
|
const rules = result.document?.rules ?? [];
|
|
5637
5783
|
if (rules.length === 0) {
|
|
5638
|
-
console.log(
|
|
5784
|
+
console.log(chalk8.dim("No dependency rules defined."));
|
|
5639
5785
|
return;
|
|
5640
5786
|
}
|
|
5641
|
-
console.log(
|
|
5787
|
+
console.log(chalk8.bold(`
|
|
5642
5788
|
\u{1F4E6} Dependency Rules (${rules.length})
|
|
5643
5789
|
`));
|
|
5644
5790
|
for (const rule of rules) {
|
|
5645
|
-
const severityColor = rule.severity === "BLOCKER" ?
|
|
5646
|
-
console.log(`${severityColor(`[${rule.severity}]`)} ${
|
|
5647
|
-
console.log(` Source: ${
|
|
5648
|
-
console.log(` Dependents: ${rule.dependents.map((d) =>
|
|
5791
|
+
const severityColor = rule.severity === "BLOCKER" ? chalk8.red : rule.severity === "WARNING" ? chalk8.yellow : chalk8.blue;
|
|
5792
|
+
console.log(`${severityColor(`[${rule.severity}]`)} ${chalk8.bold(rule.id)}`);
|
|
5793
|
+
console.log(` Source: ${chalk8.cyan(rule.source)}`);
|
|
5794
|
+
console.log(` Dependents: ${rule.dependents.map((d) => chalk8.dim(d)).join(", ")}`);
|
|
5649
5795
|
if (rule.reason && options.verbose) {
|
|
5650
|
-
console.log(` Reason: ${
|
|
5796
|
+
console.log(` Reason: ${chalk8.dim(rule.reason)}`);
|
|
5651
5797
|
}
|
|
5652
5798
|
if (rule.mustTest && options.verbose) {
|
|
5653
5799
|
console.log(` Must test: ${rule.mustTest.join(", ")}`);
|
|
@@ -5659,29 +5805,29 @@ Examples:
|
|
|
5659
5805
|
const files = options.files.split(",").map((f) => f.trim());
|
|
5660
5806
|
const parser = new DependencyParser();
|
|
5661
5807
|
if (!parser.exists()) {
|
|
5662
|
-
console.log(
|
|
5808
|
+
console.log(chalk8.dim("No DEPENDENCIES.md found. No dependency checks performed."));
|
|
5663
5809
|
process.exit(0);
|
|
5664
5810
|
}
|
|
5665
5811
|
const result = await parser.checkFiles(files);
|
|
5666
5812
|
if (result.impacts.length === 0) {
|
|
5667
|
-
console.log(
|
|
5813
|
+
console.log(chalk8.green("\u2705 No downstream dependency impacts found."));
|
|
5668
5814
|
process.exit(0);
|
|
5669
5815
|
}
|
|
5670
|
-
console.log(
|
|
5816
|
+
console.log(chalk8.yellow(`
|
|
5671
5817
|
[!] Found ${result.impacts.length} dependency impact(s):
|
|
5672
5818
|
`));
|
|
5673
5819
|
for (const impact of result.impacts) {
|
|
5674
|
-
const severityColor = impact.rule.severity === "BLOCKER" ?
|
|
5820
|
+
const severityColor = impact.rule.severity === "BLOCKER" ? chalk8.red : impact.rule.severity === "WARNING" ? chalk8.yellow : chalk8.blue;
|
|
5675
5821
|
console.log(severityColor(`[${impact.rule.severity}] ${impact.rule.id}`));
|
|
5676
|
-
console.log(` Changing: ${
|
|
5822
|
+
console.log(` Changing: ${chalk8.cyan(impact.matchedSource)}`);
|
|
5677
5823
|
console.log(` May impact: ${impact.affectedDependents.join(", ")}`);
|
|
5678
5824
|
if (impact.rule.reason) {
|
|
5679
|
-
console.log(` Reason: ${
|
|
5825
|
+
console.log(` Reason: ${chalk8.dim(impact.rule.reason)}`);
|
|
5680
5826
|
}
|
|
5681
5827
|
console.log("");
|
|
5682
5828
|
}
|
|
5683
5829
|
if (result.hasBlockers) {
|
|
5684
|
-
console.log(
|
|
5830
|
+
console.log(chalk8.red("\u274C BLOCKER-level impacts found. Review before proceeding."));
|
|
5685
5831
|
process.exit(1);
|
|
5686
5832
|
}
|
|
5687
5833
|
process.exit(0);
|
|
@@ -5723,7 +5869,7 @@ Examples:
|
|
|
5723
5869
|
(r) => r.source === source && r.dependents.includes(dependent)
|
|
5724
5870
|
);
|
|
5725
5871
|
if (existingRule) {
|
|
5726
|
-
console.log(
|
|
5872
|
+
console.log(chalk8.yellow(`Rule already exists: ${existingRule.id}`));
|
|
5727
5873
|
return;
|
|
5728
5874
|
}
|
|
5729
5875
|
const newRule = {
|
|
@@ -5737,20 +5883,20 @@ Examples:
|
|
|
5737
5883
|
const yaml2 = generateYamlFrontmatter(existingRules);
|
|
5738
5884
|
await writeFile4(DEPENDENCIES_FILENAME, `---
|
|
5739
5885
|
${yaml2}---${markdownBody}`, "utf-8");
|
|
5740
|
-
console.log(
|
|
5741
|
-
console.log(` Source: ${
|
|
5742
|
-
console.log(` Dependent: ${
|
|
5886
|
+
console.log(chalk8.green(`\u2705 Added dependency rule: ${nextId}`));
|
|
5887
|
+
console.log(` Source: ${chalk8.cyan(source)}`);
|
|
5888
|
+
console.log(` Dependent: ${chalk8.dim(dependent)}`);
|
|
5743
5889
|
});
|
|
5744
5890
|
deps.command("graph").description("Generate Mermaid diagram of dependencies").option("--output <file>", "Write to file instead of stdout").action(async (options) => {
|
|
5745
5891
|
const parser = new DependencyParser();
|
|
5746
5892
|
if (!parser.exists()) {
|
|
5747
|
-
console.log(
|
|
5893
|
+
console.log(chalk8.yellow("No DEPENDENCIES.md found."));
|
|
5748
5894
|
return;
|
|
5749
5895
|
}
|
|
5750
5896
|
const mermaid = await parser.generateGraph();
|
|
5751
5897
|
if (options.output) {
|
|
5752
5898
|
await writeFile4(options.output, mermaid, "utf-8");
|
|
5753
|
-
console.log(
|
|
5899
|
+
console.log(chalk8.green(`\u2705 Graph written to ${options.output}`));
|
|
5754
5900
|
} else {
|
|
5755
5901
|
console.log("\n```mermaid");
|
|
5756
5902
|
console.log(mermaid);
|
|
@@ -5759,7 +5905,7 @@ ${yaml2}---${markdownBody}`, "utf-8");
|
|
|
5759
5905
|
});
|
|
5760
5906
|
deps.command("init").description("Create a starter DEPENDENCIES.md file").action(async () => {
|
|
5761
5907
|
if (existsSync8(DEPENDENCIES_FILENAME)) {
|
|
5762
|
-
console.log(
|
|
5908
|
+
console.log(chalk8.yellow("DEPENDENCIES.md already exists."));
|
|
5763
5909
|
return;
|
|
5764
5910
|
}
|
|
5765
5911
|
const template = `---
|
|
@@ -5806,8 +5952,8 @@ rules:
|
|
|
5806
5952
|
*Powered by [ArchonDev](https://archondev.io)*
|
|
5807
5953
|
`;
|
|
5808
5954
|
await writeFile4(DEPENDENCIES_FILENAME, template, "utf-8");
|
|
5809
|
-
console.log(
|
|
5810
|
-
console.log(
|
|
5955
|
+
console.log(chalk8.green("\u2705 Created DEPENDENCIES.md"));
|
|
5956
|
+
console.log(chalk8.dim("Add your first rule with: archon deps add --source <path> --dependent <path>"));
|
|
5811
5957
|
});
|
|
5812
5958
|
return deps;
|
|
5813
5959
|
}
|
|
@@ -5844,7 +5990,7 @@ function generateYamlFrontmatter(rules) {
|
|
|
5844
5990
|
}
|
|
5845
5991
|
|
|
5846
5992
|
// src/cli/session.ts
|
|
5847
|
-
import
|
|
5993
|
+
import chalk9 from "chalk";
|
|
5848
5994
|
import ora2 from "ora";
|
|
5849
5995
|
import os from "os";
|
|
5850
5996
|
import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -5940,13 +6086,13 @@ async function saveSession(name) {
|
|
|
5940
6086
|
spinner.fail(`Failed to save session: ${error.message}`);
|
|
5941
6087
|
return;
|
|
5942
6088
|
}
|
|
5943
|
-
spinner.succeed(
|
|
6089
|
+
spinner.succeed(chalk9.green("Session saved!"));
|
|
5944
6090
|
console.log();
|
|
5945
|
-
console.log(` ID: ${
|
|
6091
|
+
console.log(` ID: ${chalk9.cyan(session.id)}`);
|
|
5946
6092
|
console.log(` Project: ${session.project_name}`);
|
|
5947
6093
|
console.log(` Device: ${session.last_device}`);
|
|
5948
6094
|
console.log();
|
|
5949
|
-
console.log(
|
|
6095
|
+
console.log(chalk9.dim(" Resume on another device: archon session resume " + session.id));
|
|
5950
6096
|
console.log();
|
|
5951
6097
|
} catch (err2) {
|
|
5952
6098
|
spinner.fail("Error saving session");
|
|
@@ -5974,23 +6120,23 @@ async function listSessions() {
|
|
|
5974
6120
|
}
|
|
5975
6121
|
spinner.stop();
|
|
5976
6122
|
if (!sessions || sessions.length === 0) {
|
|
5977
|
-
console.log(
|
|
5978
|
-
console.log(
|
|
6123
|
+
console.log(chalk9.yellow("\nNo saved sessions found.\n"));
|
|
6124
|
+
console.log(chalk9.dim(" Save a session: archon session save [name]\n"));
|
|
5979
6125
|
return;
|
|
5980
6126
|
}
|
|
5981
6127
|
console.log();
|
|
5982
|
-
console.log(
|
|
6128
|
+
console.log(chalk9.bold("\u{1F4C2} Saved Sessions"));
|
|
5983
6129
|
console.log();
|
|
5984
6130
|
for (const session of sessions) {
|
|
5985
6131
|
const date = new Date(session.updated_at).toLocaleDateString();
|
|
5986
|
-
const atomInfo = session.current_atom_id ?
|
|
6132
|
+
const atomInfo = session.current_atom_id ? chalk9.dim(` (atom: ${session.current_atom_id})`) : "";
|
|
5987
6133
|
console.log(
|
|
5988
|
-
` ${
|
|
6134
|
+
` ${chalk9.cyan(session.id.slice(0, 8))} ${session.project_name}${atomInfo}`
|
|
5989
6135
|
);
|
|
5990
|
-
console.log(
|
|
6136
|
+
console.log(chalk9.dim(` ${date} from ${session.last_device || "unknown device"}`));
|
|
5991
6137
|
console.log();
|
|
5992
6138
|
}
|
|
5993
|
-
console.log(
|
|
6139
|
+
console.log(chalk9.dim(" Resume: archon session resume <id>\n"));
|
|
5994
6140
|
} catch (err2) {
|
|
5995
6141
|
spinner.fail("Error fetching sessions");
|
|
5996
6142
|
console.error(err2);
|
|
@@ -6034,13 +6180,13 @@ async function resumeSession(sessionId) {
|
|
|
6034
6180
|
await writeFile5(archPath, session.architecture_snapshot);
|
|
6035
6181
|
}
|
|
6036
6182
|
await supabase.from("sessions").update({ last_device: getDeviceName(), updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", session.id);
|
|
6037
|
-
spinner.succeed(
|
|
6183
|
+
spinner.succeed(chalk9.green("Session resumed!"));
|
|
6038
6184
|
console.log();
|
|
6039
6185
|
console.log(` Project: ${session.project_name}`);
|
|
6040
6186
|
console.log(` Current Atom: ${session.current_atom_id || "none"}`);
|
|
6041
6187
|
console.log(` Pending: ${session.pending_atoms.length} atoms`);
|
|
6042
6188
|
console.log();
|
|
6043
|
-
console.log(
|
|
6189
|
+
console.log(chalk9.dim(" Continue working: archon start"));
|
|
6044
6190
|
console.log();
|
|
6045
6191
|
} catch (err2) {
|
|
6046
6192
|
spinner.fail("Error resuming session");
|
|
@@ -6083,7 +6229,7 @@ async function syncSession() {
|
|
|
6083
6229
|
spinner.fail(`Failed to sync: ${error.message}`);
|
|
6084
6230
|
return;
|
|
6085
6231
|
}
|
|
6086
|
-
spinner.succeed(
|
|
6232
|
+
spinner.succeed(chalk9.green("Session synced to cloud"));
|
|
6087
6233
|
} catch (err2) {
|
|
6088
6234
|
spinner.fail("Error syncing session");
|
|
6089
6235
|
console.error(err2);
|
|
@@ -6091,7 +6237,7 @@ async function syncSession() {
|
|
|
6091
6237
|
}
|
|
6092
6238
|
|
|
6093
6239
|
// src/cli/deploy.ts
|
|
6094
|
-
import
|
|
6240
|
+
import chalk10 from "chalk";
|
|
6095
6241
|
import { existsSync as existsSync10 } from "fs";
|
|
6096
6242
|
import { join as join9 } from "path";
|
|
6097
6243
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -6106,46 +6252,46 @@ function detectPlatform(cwd) {
|
|
|
6106
6252
|
}
|
|
6107
6253
|
async function deploy(options) {
|
|
6108
6254
|
const cwd = process.cwd();
|
|
6109
|
-
console.log(
|
|
6255
|
+
console.log(chalk10.blue("Running pre-deploy checks..."));
|
|
6110
6256
|
const platform = options.platform ?? detectPlatform(cwd);
|
|
6111
|
-
console.log(
|
|
6257
|
+
console.log(chalk10.dim(`Detected platform: ${platform}`));
|
|
6112
6258
|
if (options.dryRun) {
|
|
6113
|
-
console.log(
|
|
6259
|
+
console.log(chalk10.dim("Dry run mode - would deploy to:"), platform);
|
|
6114
6260
|
return;
|
|
6115
6261
|
}
|
|
6116
6262
|
switch (platform) {
|
|
6117
6263
|
case "fly":
|
|
6118
|
-
console.log(
|
|
6264
|
+
console.log(chalk10.blue("Deploying to Fly.io..."));
|
|
6119
6265
|
execSync3("fly deploy", { cwd, stdio: "inherit" });
|
|
6120
6266
|
break;
|
|
6121
6267
|
case "vercel": {
|
|
6122
|
-
console.log(
|
|
6268
|
+
console.log(chalk10.blue("Deploying to Vercel..."));
|
|
6123
6269
|
const cmd = options.preview ? "vercel" : "vercel --prod";
|
|
6124
6270
|
execSync3(cmd, { cwd, stdio: "inherit" });
|
|
6125
6271
|
break;
|
|
6126
6272
|
}
|
|
6127
6273
|
case "netlify": {
|
|
6128
|
-
console.log(
|
|
6274
|
+
console.log(chalk10.blue("Deploying to Netlify..."));
|
|
6129
6275
|
const netlifyCmd = options.preview ? "netlify deploy" : "netlify deploy --prod";
|
|
6130
6276
|
execSync3(netlifyCmd, { cwd, stdio: "inherit" });
|
|
6131
6277
|
break;
|
|
6132
6278
|
}
|
|
6133
6279
|
case "railway":
|
|
6134
|
-
console.log(
|
|
6280
|
+
console.log(chalk10.blue("Deploying to Railway..."));
|
|
6135
6281
|
execSync3("railway up", { cwd, stdio: "inherit" });
|
|
6136
6282
|
break;
|
|
6137
6283
|
case "render":
|
|
6138
|
-
console.log(
|
|
6139
|
-
console.log(
|
|
6284
|
+
console.log(chalk10.blue("Deploying to Render..."));
|
|
6285
|
+
console.log(chalk10.yellow("Render deploys via git push. Push to your connected branch."));
|
|
6140
6286
|
break;
|
|
6141
6287
|
default:
|
|
6142
|
-
console.log(
|
|
6143
|
-
console.log(
|
|
6288
|
+
console.log(chalk10.yellow("Platform not detected. Please specify with --platform"));
|
|
6289
|
+
console.log(chalk10.dim("Supported: fly, vercel, netlify, railway, render"));
|
|
6144
6290
|
}
|
|
6145
6291
|
}
|
|
6146
6292
|
|
|
6147
6293
|
// src/cli/index-cmd.ts
|
|
6148
|
-
import
|
|
6294
|
+
import chalk11 from "chalk";
|
|
6149
6295
|
|
|
6150
6296
|
// src/core/indexing/local.ts
|
|
6151
6297
|
import { existsSync as existsSync11, mkdirSync } from "fs";
|
|
@@ -6559,14 +6705,14 @@ async function getCloudIndexer(cwd) {
|
|
|
6559
6705
|
const config = await loadConfig();
|
|
6560
6706
|
const authToken = getAuthToken(config);
|
|
6561
6707
|
if (!authToken) {
|
|
6562
|
-
console.error(
|
|
6708
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6563
6709
|
return null;
|
|
6564
6710
|
}
|
|
6565
6711
|
const openaiKey = process.env["OPENAI_API_KEY"];
|
|
6566
6712
|
if (!openaiKey) {
|
|
6567
|
-
console.error(
|
|
6568
|
-
console.log(
|
|
6569
|
-
console.log(
|
|
6713
|
+
console.error(chalk11.red("OPENAI_API_KEY environment variable not set."));
|
|
6714
|
+
console.log(chalk11.dim("Cloud indexing requires an OpenAI API key for embeddings."));
|
|
6715
|
+
console.log(chalk11.dim("Set it with: export OPENAI_API_KEY=sk-..."));
|
|
6570
6716
|
return null;
|
|
6571
6717
|
}
|
|
6572
6718
|
const projectId = basename(cwd);
|
|
@@ -6583,12 +6729,12 @@ async function getCloudIndexer(cwd) {
|
|
|
6583
6729
|
});
|
|
6584
6730
|
const { data: { user } } = await client.auth.getUser();
|
|
6585
6731
|
if (!user) {
|
|
6586
|
-
console.error(
|
|
6732
|
+
console.error(chalk11.red("Failed to get user. Try logging in again."));
|
|
6587
6733
|
return null;
|
|
6588
6734
|
}
|
|
6589
6735
|
const { data: profile } = await client.from("user_profiles").select("id").eq("auth_id", user.id).single();
|
|
6590
6736
|
if (!profile) {
|
|
6591
|
-
console.error(
|
|
6737
|
+
console.error(chalk11.red("User profile not found."));
|
|
6592
6738
|
return null;
|
|
6593
6739
|
}
|
|
6594
6740
|
indexer.setUserId(profile.id);
|
|
@@ -6597,21 +6743,21 @@ async function getCloudIndexer(cwd) {
|
|
|
6597
6743
|
async function indexInit(options) {
|
|
6598
6744
|
const cwd = process.cwd();
|
|
6599
6745
|
if (options.cloud) {
|
|
6600
|
-
console.log(
|
|
6746
|
+
console.log(chalk11.blue("Initializing cloud semantic index..."));
|
|
6601
6747
|
const indexer = await getCloudIndexer(cwd);
|
|
6602
6748
|
if (!indexer) return;
|
|
6603
6749
|
try {
|
|
6604
6750
|
const status2 = await indexer.getStatus();
|
|
6605
|
-
console.log(
|
|
6606
|
-
console.log(
|
|
6607
|
-
console.log(
|
|
6751
|
+
console.log(chalk11.green("\u2713 Cloud indexing configured"));
|
|
6752
|
+
console.log(chalk11.green(`\u2713 Project ID: ${status2.projectId}`));
|
|
6753
|
+
console.log(chalk11.dim("\nRun `archon index update --cloud` to index your codebase."));
|
|
6608
6754
|
} catch (error) {
|
|
6609
|
-
console.error(
|
|
6755
|
+
console.error(chalk11.red(`Failed to initialize cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6610
6756
|
process.exit(1);
|
|
6611
6757
|
}
|
|
6612
6758
|
return;
|
|
6613
6759
|
}
|
|
6614
|
-
console.log(
|
|
6760
|
+
console.log(chalk11.blue("Initializing local semantic index..."));
|
|
6615
6761
|
try {
|
|
6616
6762
|
const indexer = new LocalIndexer();
|
|
6617
6763
|
await indexer.init(cwd);
|
|
@@ -6619,18 +6765,18 @@ async function indexInit(options) {
|
|
|
6619
6765
|
if (!response.ok) {
|
|
6620
6766
|
throw new Error("Ollama not responding");
|
|
6621
6767
|
}
|
|
6622
|
-
console.log(
|
|
6623
|
-
console.log(
|
|
6624
|
-
console.log(
|
|
6768
|
+
console.log(chalk11.green("\u2713 Ollama connection verified"));
|
|
6769
|
+
console.log(chalk11.green("\u2713 Index database created at .archon/index.db"));
|
|
6770
|
+
console.log(chalk11.dim("\nRun `archon index update` to index your codebase."));
|
|
6625
6771
|
indexer.close();
|
|
6626
6772
|
} catch (error) {
|
|
6627
6773
|
if (error instanceof Error && error.message.includes("Ollama")) {
|
|
6628
|
-
console.log(
|
|
6629
|
-
console.log(
|
|
6630
|
-
console.log(
|
|
6631
|
-
console.log(
|
|
6774
|
+
console.log(chalk11.red("\n\u2717 Ollama is not running"));
|
|
6775
|
+
console.log(chalk11.dim("Start Ollama with: ollama serve"));
|
|
6776
|
+
console.log(chalk11.dim("Then pull the embedding model: ollama pull nomic-embed-text"));
|
|
6777
|
+
console.log(chalk11.dim("\nOr use cloud indexing: archon index init --cloud"));
|
|
6632
6778
|
} else {
|
|
6633
|
-
console.error(
|
|
6779
|
+
console.error(chalk11.red(`Failed to initialize index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6634
6780
|
}
|
|
6635
6781
|
process.exit(1);
|
|
6636
6782
|
}
|
|
@@ -6638,7 +6784,7 @@ async function indexInit(options) {
|
|
|
6638
6784
|
async function indexUpdate(options) {
|
|
6639
6785
|
const cwd = process.cwd();
|
|
6640
6786
|
if (options?.cloud) {
|
|
6641
|
-
console.log(
|
|
6787
|
+
console.log(chalk11.blue("Updating cloud semantic index..."));
|
|
6642
6788
|
const indexer = await getCloudIndexer(cwd);
|
|
6643
6789
|
if (!indexer) return;
|
|
6644
6790
|
try {
|
|
@@ -6646,15 +6792,15 @@ async function indexUpdate(options) {
|
|
|
6646
6792
|
cwd,
|
|
6647
6793
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6648
6794
|
});
|
|
6649
|
-
console.log(
|
|
6650
|
-
console.log(
|
|
6795
|
+
console.log(chalk11.dim(`Found ${files.length} files to index...`));
|
|
6796
|
+
console.log(chalk11.dim("This may take a few minutes and will use OpenAI API credits.\n"));
|
|
6651
6797
|
let totalChunks = 0;
|
|
6652
6798
|
let indexedFiles = 0;
|
|
6653
6799
|
let skippedFiles = 0;
|
|
6654
6800
|
for (let i = 0; i < files.length; i++) {
|
|
6655
6801
|
const file = files[i];
|
|
6656
6802
|
if (!file) continue;
|
|
6657
|
-
process.stdout.write(`\r${
|
|
6803
|
+
process.stdout.write(`\r${chalk11.dim(`[${i + 1}/${files.length}] ${file.slice(0, 45).padEnd(45)}`)}`);
|
|
6658
6804
|
try {
|
|
6659
6805
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6660
6806
|
if (chunks > 0) {
|
|
@@ -6665,21 +6811,21 @@ async function indexUpdate(options) {
|
|
|
6665
6811
|
}
|
|
6666
6812
|
} catch (error) {
|
|
6667
6813
|
console.log(`
|
|
6668
|
-
${
|
|
6814
|
+
${chalk11.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message : "Unknown error"}`)}`);
|
|
6669
6815
|
}
|
|
6670
6816
|
}
|
|
6671
6817
|
console.log("\r" + " ".repeat(70));
|
|
6672
|
-
console.log(
|
|
6818
|
+
console.log(chalk11.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6673
6819
|
if (skippedFiles > 0) {
|
|
6674
|
-
console.log(
|
|
6820
|
+
console.log(chalk11.dim(` Skipped ${skippedFiles} unchanged files`));
|
|
6675
6821
|
}
|
|
6676
6822
|
} catch (error) {
|
|
6677
|
-
console.error(
|
|
6823
|
+
console.error(chalk11.red(`Failed to update cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6678
6824
|
process.exit(1);
|
|
6679
6825
|
}
|
|
6680
6826
|
return;
|
|
6681
6827
|
}
|
|
6682
|
-
console.log(
|
|
6828
|
+
console.log(chalk11.blue("Updating local semantic index..."));
|
|
6683
6829
|
try {
|
|
6684
6830
|
const indexer = new LocalIndexer();
|
|
6685
6831
|
await indexer.init(cwd);
|
|
@@ -6687,12 +6833,12 @@ ${chalk10.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6687
6833
|
cwd,
|
|
6688
6834
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6689
6835
|
});
|
|
6690
|
-
console.log(
|
|
6836
|
+
console.log(chalk11.dim(`Found ${files.length} files to index...`));
|
|
6691
6837
|
let totalChunks = 0;
|
|
6692
6838
|
let indexedFiles = 0;
|
|
6693
6839
|
for (const file of files) {
|
|
6694
6840
|
if (!file) continue;
|
|
6695
|
-
process.stdout.write(`\r${
|
|
6841
|
+
process.stdout.write(`\r${chalk11.dim(`Indexing: ${file.slice(0, 50).padEnd(50)}`)}`);
|
|
6696
6842
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6697
6843
|
if (chunks > 0) {
|
|
6698
6844
|
totalChunks += chunks;
|
|
@@ -6700,10 +6846,10 @@ ${chalk10.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6700
6846
|
}
|
|
6701
6847
|
}
|
|
6702
6848
|
console.log("\r" + " ".repeat(60));
|
|
6703
|
-
console.log(
|
|
6849
|
+
console.log(chalk11.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6704
6850
|
indexer.close();
|
|
6705
6851
|
} catch (error) {
|
|
6706
|
-
console.error(
|
|
6852
|
+
console.error(chalk11.red(`Failed to update index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6707
6853
|
process.exit(1);
|
|
6708
6854
|
}
|
|
6709
6855
|
}
|
|
@@ -6713,25 +6859,25 @@ async function indexSearch(query, options) {
|
|
|
6713
6859
|
const indexer = await getCloudIndexer(cwd);
|
|
6714
6860
|
if (!indexer) return;
|
|
6715
6861
|
try {
|
|
6716
|
-
console.log(
|
|
6862
|
+
console.log(chalk11.dim("Searching cloud index..."));
|
|
6717
6863
|
const results = await indexer.search(query, 10);
|
|
6718
6864
|
if (results.length === 0) {
|
|
6719
|
-
console.log(
|
|
6720
|
-
console.log(
|
|
6865
|
+
console.log(chalk11.yellow("\nNo results found."));
|
|
6866
|
+
console.log(chalk11.dim("Try running `archon index update --cloud` first."));
|
|
6721
6867
|
} else {
|
|
6722
|
-
console.log(
|
|
6868
|
+
console.log(chalk11.blue(`
|
|
6723
6869
|
Top ${results.length} results for: "${query}"
|
|
6724
6870
|
`));
|
|
6725
6871
|
for (const result of results) {
|
|
6726
6872
|
const score = (result.score * 100).toFixed(1);
|
|
6727
|
-
console.log(
|
|
6873
|
+
console.log(chalk11.green(`[${score}%] ${result.file}`));
|
|
6728
6874
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6729
|
-
console.log(
|
|
6875
|
+
console.log(chalk11.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6730
6876
|
console.log();
|
|
6731
6877
|
}
|
|
6732
6878
|
}
|
|
6733
6879
|
} catch (error) {
|
|
6734
|
-
console.error(
|
|
6880
|
+
console.error(chalk11.red(`Cloud search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6735
6881
|
process.exit(1);
|
|
6736
6882
|
}
|
|
6737
6883
|
return;
|
|
@@ -6741,23 +6887,23 @@ Top ${results.length} results for: "${query}"
|
|
|
6741
6887
|
await indexer.init(cwd);
|
|
6742
6888
|
const results = await indexer.search(query, 10);
|
|
6743
6889
|
if (results.length === 0) {
|
|
6744
|
-
console.log(
|
|
6745
|
-
console.log(
|
|
6890
|
+
console.log(chalk11.yellow("No results found."));
|
|
6891
|
+
console.log(chalk11.dim("Try running `archon index update` first."));
|
|
6746
6892
|
} else {
|
|
6747
|
-
console.log(
|
|
6893
|
+
console.log(chalk11.blue(`
|
|
6748
6894
|
Top ${results.length} results for: "${query}"
|
|
6749
6895
|
`));
|
|
6750
6896
|
for (const result of results) {
|
|
6751
6897
|
const score = (result.score * 100).toFixed(1);
|
|
6752
|
-
console.log(
|
|
6898
|
+
console.log(chalk11.green(`[${score}%] ${result.file}`));
|
|
6753
6899
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6754
|
-
console.log(
|
|
6900
|
+
console.log(chalk11.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6755
6901
|
console.log();
|
|
6756
6902
|
}
|
|
6757
6903
|
}
|
|
6758
6904
|
indexer.close();
|
|
6759
6905
|
} catch (error) {
|
|
6760
|
-
console.error(
|
|
6906
|
+
console.error(chalk11.red(`Search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6761
6907
|
process.exit(1);
|
|
6762
6908
|
}
|
|
6763
6909
|
}
|
|
@@ -6768,17 +6914,17 @@ async function indexStatus(options) {
|
|
|
6768
6914
|
if (!indexer) return;
|
|
6769
6915
|
try {
|
|
6770
6916
|
const status2 = await indexer.getStatus();
|
|
6771
|
-
console.log(
|
|
6772
|
-
console.log(` Project ID: ${
|
|
6773
|
-
console.log(` Files indexed: ${
|
|
6774
|
-
console.log(` Total chunks: ${
|
|
6775
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6917
|
+
console.log(chalk11.blue("\nCloud Semantic Index Status\n"));
|
|
6918
|
+
console.log(` Project ID: ${chalk11.green(status2.projectId)}`);
|
|
6919
|
+
console.log(` Files indexed: ${chalk11.green(status2.fileCount)}`);
|
|
6920
|
+
console.log(` Total chunks: ${chalk11.green(status2.chunkCount)}`);
|
|
6921
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk11.dim(status2.lastUpdated) : chalk11.yellow("Never")}`);
|
|
6776
6922
|
if (status2.jobStatus) {
|
|
6777
|
-
console.log(` Job status: ${
|
|
6923
|
+
console.log(` Job status: ${chalk11.dim(status2.jobStatus)}`);
|
|
6778
6924
|
}
|
|
6779
|
-
console.log(` Storage: ${
|
|
6925
|
+
console.log(` Storage: ${chalk11.dim("Supabase pgvector")}`);
|
|
6780
6926
|
} catch (error) {
|
|
6781
|
-
console.error(
|
|
6927
|
+
console.error(chalk11.red(`Failed to get cloud status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6782
6928
|
process.exit(1);
|
|
6783
6929
|
}
|
|
6784
6930
|
return;
|
|
@@ -6787,14 +6933,14 @@ async function indexStatus(options) {
|
|
|
6787
6933
|
const indexer = new LocalIndexer();
|
|
6788
6934
|
await indexer.init(cwd);
|
|
6789
6935
|
const status2 = await indexer.getStatus();
|
|
6790
|
-
console.log(
|
|
6791
|
-
console.log(` Files indexed: ${
|
|
6792
|
-
console.log(` Total chunks: ${
|
|
6793
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6794
|
-
console.log(` Database: ${
|
|
6936
|
+
console.log(chalk11.blue("\nLocal Semantic Index Status\n"));
|
|
6937
|
+
console.log(` Files indexed: ${chalk11.green(status2.fileCount)}`);
|
|
6938
|
+
console.log(` Total chunks: ${chalk11.green(status2.chunkCount)}`);
|
|
6939
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk11.dim(status2.lastUpdated) : chalk11.yellow("Never")}`);
|
|
6940
|
+
console.log(` Database: ${chalk11.dim(join12(cwd, ".archon/index.db"))}`);
|
|
6795
6941
|
indexer.close();
|
|
6796
6942
|
} catch (error) {
|
|
6797
|
-
console.error(
|
|
6943
|
+
console.error(chalk11.red(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6798
6944
|
process.exit(1);
|
|
6799
6945
|
}
|
|
6800
6946
|
}
|
|
@@ -6804,30 +6950,30 @@ async function indexClear(options) {
|
|
|
6804
6950
|
const indexer = await getCloudIndexer(cwd);
|
|
6805
6951
|
if (!indexer) return;
|
|
6806
6952
|
try {
|
|
6807
|
-
console.log(
|
|
6953
|
+
console.log(chalk11.yellow("Clearing cloud index..."));
|
|
6808
6954
|
await indexer.clearProject();
|
|
6809
|
-
console.log(
|
|
6955
|
+
console.log(chalk11.green("\u2713 Cloud index cleared"));
|
|
6810
6956
|
} catch (error) {
|
|
6811
|
-
console.error(
|
|
6957
|
+
console.error(chalk11.red(`Failed to clear cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6812
6958
|
process.exit(1);
|
|
6813
6959
|
}
|
|
6814
6960
|
return;
|
|
6815
6961
|
}
|
|
6816
|
-
console.log(
|
|
6962
|
+
console.log(chalk11.yellow("To clear local index, delete .archon/index.db"));
|
|
6817
6963
|
}
|
|
6818
6964
|
|
|
6819
6965
|
// src/cli/github.ts
|
|
6820
|
-
import
|
|
6966
|
+
import chalk12 from "chalk";
|
|
6821
6967
|
import open2 from "open";
|
|
6822
6968
|
var API_URL2 = process.env["ARCHONDEV_API_URL"] ?? "https://archondev-api.fly.dev";
|
|
6823
6969
|
async function githubConnect() {
|
|
6824
6970
|
const config = await loadConfig();
|
|
6825
6971
|
const authToken = getAuthToken(config);
|
|
6826
6972
|
if (!authToken) {
|
|
6827
|
-
console.error(
|
|
6973
|
+
console.error(chalk12.red('Not authenticated. Run "archon login" first.'));
|
|
6828
6974
|
process.exit(1);
|
|
6829
6975
|
}
|
|
6830
|
-
console.log(
|
|
6976
|
+
console.log(chalk12.dim("Starting GitHub connection..."));
|
|
6831
6977
|
try {
|
|
6832
6978
|
const response = await fetch(`${API_URL2}/api/github/connect`, {
|
|
6833
6979
|
headers: {
|
|
@@ -6836,18 +6982,18 @@ async function githubConnect() {
|
|
|
6836
6982
|
});
|
|
6837
6983
|
if (!response.ok) {
|
|
6838
6984
|
const error = await response.json();
|
|
6839
|
-
console.error(
|
|
6985
|
+
console.error(chalk12.red(error.error ?? "Failed to start GitHub connection"));
|
|
6840
6986
|
process.exit(1);
|
|
6841
6987
|
}
|
|
6842
6988
|
const data = await response.json();
|
|
6843
|
-
console.log(
|
|
6844
|
-
console.log(
|
|
6845
|
-
console.log(
|
|
6989
|
+
console.log(chalk12.dim("\nOpening browser for GitHub authorization..."));
|
|
6990
|
+
console.log(chalk12.dim("If browser does not open, visit:"));
|
|
6991
|
+
console.log(chalk12.blue(data.url));
|
|
6846
6992
|
await open2(data.url);
|
|
6847
|
-
console.log(
|
|
6848
|
-
console.log(
|
|
6993
|
+
console.log(chalk12.dim("\nComplete the authorization in your browser."));
|
|
6994
|
+
console.log(chalk12.dim('Then run "archon github status" to verify connection.'));
|
|
6849
6995
|
} catch (error) {
|
|
6850
|
-
console.error(
|
|
6996
|
+
console.error(chalk12.red(error instanceof Error ? error.message : "Failed to connect"));
|
|
6851
6997
|
process.exit(1);
|
|
6852
6998
|
}
|
|
6853
6999
|
}
|
|
@@ -6855,7 +7001,7 @@ async function githubStatus() {
|
|
|
6855
7001
|
const config = await loadConfig();
|
|
6856
7002
|
const authToken = getAuthToken(config);
|
|
6857
7003
|
if (!authToken) {
|
|
6858
|
-
console.error(
|
|
7004
|
+
console.error(chalk12.red('Not authenticated. Run "archon login" first.'));
|
|
6859
7005
|
process.exit(1);
|
|
6860
7006
|
}
|
|
6861
7007
|
try {
|
|
@@ -6866,20 +7012,20 @@ async function githubStatus() {
|
|
|
6866
7012
|
});
|
|
6867
7013
|
if (!response.ok) {
|
|
6868
7014
|
const error = await response.json();
|
|
6869
|
-
console.error(
|
|
7015
|
+
console.error(chalk12.red(error.error ?? "Failed to get GitHub status"));
|
|
6870
7016
|
process.exit(1);
|
|
6871
7017
|
}
|
|
6872
7018
|
const data = await response.json();
|
|
6873
7019
|
if (data.connected) {
|
|
6874
|
-
console.log(
|
|
6875
|
-
console.log(
|
|
6876
|
-
console.log(
|
|
7020
|
+
console.log(chalk12.green("\u2713 GitHub connected"));
|
|
7021
|
+
console.log(chalk12.dim(` Username: ${data.username}`));
|
|
7022
|
+
console.log(chalk12.dim(` Connected: ${data.connectedAt ? new Date(data.connectedAt).toLocaleDateString() : "Unknown"}`));
|
|
6877
7023
|
} else {
|
|
6878
|
-
console.log(
|
|
6879
|
-
console.log(
|
|
7024
|
+
console.log(chalk12.yellow("GitHub not connected"));
|
|
7025
|
+
console.log(chalk12.dim('Run "archon github connect" to connect your GitHub account.'));
|
|
6880
7026
|
}
|
|
6881
7027
|
} catch (error) {
|
|
6882
|
-
console.error(
|
|
7028
|
+
console.error(chalk12.red(error instanceof Error ? error.message : "Failed to get status"));
|
|
6883
7029
|
process.exit(1);
|
|
6884
7030
|
}
|
|
6885
7031
|
}
|
|
@@ -6887,7 +7033,7 @@ async function githubDisconnect() {
|
|
|
6887
7033
|
const config = await loadConfig();
|
|
6888
7034
|
const authToken = getAuthToken(config);
|
|
6889
7035
|
if (!authToken) {
|
|
6890
|
-
console.error(
|
|
7036
|
+
console.error(chalk12.red('Not authenticated. Run "archon login" first.'));
|
|
6891
7037
|
process.exit(1);
|
|
6892
7038
|
}
|
|
6893
7039
|
try {
|
|
@@ -6899,18 +7045,18 @@ async function githubDisconnect() {
|
|
|
6899
7045
|
});
|
|
6900
7046
|
if (!response.ok) {
|
|
6901
7047
|
const error = await response.json();
|
|
6902
|
-
console.error(
|
|
7048
|
+
console.error(chalk12.red(error.error ?? "Failed to disconnect GitHub"));
|
|
6903
7049
|
process.exit(1);
|
|
6904
7050
|
}
|
|
6905
|
-
console.log(
|
|
7051
|
+
console.log(chalk12.green("\u2713 GitHub disconnected"));
|
|
6906
7052
|
} catch (error) {
|
|
6907
|
-
console.error(
|
|
7053
|
+
console.error(chalk12.red(error instanceof Error ? error.message : "Failed to disconnect"));
|
|
6908
7054
|
process.exit(1);
|
|
6909
7055
|
}
|
|
6910
7056
|
}
|
|
6911
7057
|
|
|
6912
7058
|
// src/cli/interview.ts
|
|
6913
|
-
import
|
|
7059
|
+
import chalk13 from "chalk";
|
|
6914
7060
|
import readline3 from "readline";
|
|
6915
7061
|
import ora3 from "ora";
|
|
6916
7062
|
import { existsSync as existsSync13, readFileSync as readFileSync5, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
@@ -6928,23 +7074,23 @@ async function interview(options = {}) {
|
|
|
6928
7074
|
if (!existsSync13(archonDir)) {
|
|
6929
7075
|
mkdirSync2(archonDir, { recursive: true });
|
|
6930
7076
|
}
|
|
6931
|
-
console.log(
|
|
6932
|
-
console.log(
|
|
7077
|
+
console.log(chalk13.bold("\n\u{1F3AF} ArchonDev Project Interview"));
|
|
7078
|
+
console.log(chalk13.dim("Let's define what you're building.\n"));
|
|
6933
7079
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6934
7080
|
const draftPath = getDraftPath(cwd);
|
|
6935
7081
|
if (existsSync13(constitutionPath)) {
|
|
6936
7082
|
const existing = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
6937
7083
|
if (existing.state === "FROZEN") {
|
|
6938
|
-
console.log(
|
|
6939
|
-
console.log(
|
|
6940
|
-
console.log(
|
|
7084
|
+
console.log(chalk13.yellow("[!] A frozen Constitution already exists."));
|
|
7085
|
+
console.log(chalk13.dim(` Project: ${existing.branding.projectName}`));
|
|
7086
|
+
console.log(chalk13.dim(` Frozen: ${existing.frozenAt?.toISOString()}`));
|
|
6941
7087
|
console.log();
|
|
6942
7088
|
const action = await prompt2("Start a new interview (overwrite) or view existing? (new/view)");
|
|
6943
7089
|
if (action.toLowerCase() === "view") {
|
|
6944
7090
|
console.log("\n" + summarizeConstitution(existing));
|
|
6945
7091
|
return;
|
|
6946
7092
|
} else if (action.toLowerCase() !== "new") {
|
|
6947
|
-
console.log(
|
|
7093
|
+
console.log(chalk13.dim("Cancelled."));
|
|
6948
7094
|
return;
|
|
6949
7095
|
}
|
|
6950
7096
|
}
|
|
@@ -6953,8 +7099,8 @@ async function interview(options = {}) {
|
|
|
6953
7099
|
let startPhase = 1;
|
|
6954
7100
|
if (existsSync13(draftPath) && options.resume !== false) {
|
|
6955
7101
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
6956
|
-
console.log(
|
|
6957
|
-
console.log(
|
|
7102
|
+
console.log(chalk13.blue("[i] Found draft from previous session."));
|
|
7103
|
+
console.log(chalk13.dim(` Project: ${draft.branding.projectName || "(unnamed)"}`));
|
|
6958
7104
|
console.log();
|
|
6959
7105
|
const resumeChoice = await prompt2("Resume draft or start fresh? (resume/fresh)");
|
|
6960
7106
|
if (resumeChoice.toLowerCase() === "resume") {
|
|
@@ -6966,7 +7112,7 @@ async function interview(options = {}) {
|
|
|
6966
7112
|
break;
|
|
6967
7113
|
}
|
|
6968
7114
|
}
|
|
6969
|
-
console.log(
|
|
7115
|
+
console.log(chalk13.green(`
|
|
6970
7116
|
\u2713 Resuming at Phase ${startPhase}: ${INTERVIEW_PHASES[startPhase]?.name}
|
|
6971
7117
|
`));
|
|
6972
7118
|
} else {
|
|
@@ -6977,19 +7123,19 @@ async function interview(options = {}) {
|
|
|
6977
7123
|
}
|
|
6978
7124
|
if (options.phase && options.phase >= 1 && options.phase <= 5) {
|
|
6979
7125
|
startPhase = options.phase;
|
|
6980
|
-
console.log(
|
|
7126
|
+
console.log(chalk13.dim(`Starting at Phase ${startPhase}...
|
|
6981
7127
|
`));
|
|
6982
7128
|
}
|
|
6983
|
-
console.log(
|
|
6984
|
-
console.log(
|
|
6985
|
-
console.log(
|
|
7129
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
7130
|
+
console.log(chalk13.dim(formatProgressBar(startPhase)));
|
|
7131
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
6986
7132
|
console.log();
|
|
6987
7133
|
let currentPhase = startPhase;
|
|
6988
7134
|
while (currentPhase <= 5) {
|
|
6989
7135
|
const result = await runPhase(currentPhase, constitution, cwd);
|
|
6990
7136
|
if (result.action === "exit") {
|
|
6991
7137
|
saveDraft(cwd, constitution);
|
|
6992
|
-
console.log(
|
|
7138
|
+
console.log(chalk13.dim("\nDraft saved. Run `archon interview` to resume.\n"));
|
|
6993
7139
|
return;
|
|
6994
7140
|
}
|
|
6995
7141
|
if (result.action === "back" && currentPhase > 1) {
|
|
@@ -7004,9 +7150,9 @@ async function interview(options = {}) {
|
|
|
7004
7150
|
if (next) {
|
|
7005
7151
|
currentPhase = next;
|
|
7006
7152
|
console.log();
|
|
7007
|
-
console.log(
|
|
7008
|
-
console.log(
|
|
7009
|
-
console.log(
|
|
7153
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
7154
|
+
console.log(chalk13.dim(formatProgressBar(currentPhase)));
|
|
7155
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
7010
7156
|
console.log();
|
|
7011
7157
|
} else {
|
|
7012
7158
|
break;
|
|
@@ -7014,9 +7160,9 @@ async function interview(options = {}) {
|
|
|
7014
7160
|
}
|
|
7015
7161
|
const validationResult = validateConstitution(constitution);
|
|
7016
7162
|
if (!validationResult.valid) {
|
|
7017
|
-
console.log(
|
|
7163
|
+
console.log(chalk13.red("\n[!] Constitution has validation errors:\n"));
|
|
7018
7164
|
for (const error of validationResult.errors) {
|
|
7019
|
-
console.log(
|
|
7165
|
+
console.log(chalk13.red(` \u2022 ${error}`));
|
|
7020
7166
|
}
|
|
7021
7167
|
console.log();
|
|
7022
7168
|
const fix = await promptYesNo3("Would you like to go back and fix these?", true);
|
|
@@ -7026,9 +7172,9 @@ async function interview(options = {}) {
|
|
|
7026
7172
|
}
|
|
7027
7173
|
}
|
|
7028
7174
|
if (validationResult.warnings.length > 0) {
|
|
7029
|
-
console.log(
|
|
7175
|
+
console.log(chalk13.yellow("\n[!] Warnings:\n"));
|
|
7030
7176
|
for (const warning of validationResult.warnings) {
|
|
7031
|
-
console.log(
|
|
7177
|
+
console.log(chalk13.yellow(` \u2022 ${warning}`));
|
|
7032
7178
|
}
|
|
7033
7179
|
console.log();
|
|
7034
7180
|
}
|
|
@@ -7038,21 +7184,21 @@ async function interview(options = {}) {
|
|
|
7038
7184
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
7039
7185
|
const challengeResult = analyzeForChallenges(constitution);
|
|
7040
7186
|
if (challengeResult.shouldChallenge) {
|
|
7041
|
-
console.log(
|
|
7042
|
-
console.log(
|
|
7187
|
+
console.log(chalk13.bold("\n\u{1F3AF} Challenge Mode\n"));
|
|
7188
|
+
console.log(chalk13.dim("Let me share some observations about your project scope...\n"));
|
|
7043
7189
|
for (const challenge of challengeResult.challenges) {
|
|
7044
7190
|
const prompt3 = generateChallengePrompt(challenge);
|
|
7045
|
-
const icon = challenge.severity === "critical" ?
|
|
7046
|
-
console.log(`${icon} ${
|
|
7047
|
-
console.log(
|
|
7191
|
+
const icon = challenge.severity === "critical" ? chalk13.red("\u25CF") : chalk13.yellow("\u25CF");
|
|
7192
|
+
console.log(`${icon} ${chalk13.bold(challenge.title)}`);
|
|
7193
|
+
console.log(chalk13.dim(` ${prompt3}`));
|
|
7048
7194
|
console.log();
|
|
7049
7195
|
}
|
|
7050
|
-
console.log(
|
|
7196
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
7051
7197
|
console.log(summarizeChallenges(challengeResult));
|
|
7052
|
-
console.log(
|
|
7198
|
+
console.log(chalk13.dim("\u2500".repeat(40)));
|
|
7053
7199
|
console.log();
|
|
7054
7200
|
if (challengeResult.featuresToDefer.length > 0) {
|
|
7055
|
-
console.log(
|
|
7201
|
+
console.log(chalk13.bold("Suggested Features to Defer to Post-MVP:\n"));
|
|
7056
7202
|
for (const feature of challengeResult.featuresToDefer) {
|
|
7057
7203
|
console.log(` \u2022 ${feature.name}`);
|
|
7058
7204
|
}
|
|
@@ -7067,39 +7213,39 @@ async function interview(options = {}) {
|
|
|
7067
7213
|
constitution.complexity = calculateComplexity(constitution);
|
|
7068
7214
|
constitution.estimatedBuildHours = estimateBuildHours(constitution.complexity);
|
|
7069
7215
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
7070
|
-
console.log(
|
|
7071
|
-
console.log(
|
|
7072
|
-
console.log(
|
|
7216
|
+
console.log(chalk13.green("\n\u2713 Features deferred. Updated estimates:"));
|
|
7217
|
+
console.log(chalk13.dim(` Complexity: ${constitution.complexity.tier}`));
|
|
7218
|
+
console.log(chalk13.dim(` Build time: ~${Math.round(constitution.estimatedBuildHours)} hours`));
|
|
7073
7219
|
console.log();
|
|
7074
7220
|
saveDraft(cwd, constitution);
|
|
7075
7221
|
}
|
|
7076
7222
|
}
|
|
7077
7223
|
const criticalCount = challengeResult.challenges.filter((c) => c.severity === "critical").length;
|
|
7078
7224
|
if (criticalCount > 0) {
|
|
7079
|
-
console.log(
|
|
7225
|
+
console.log(chalk13.red(`
|
|
7080
7226
|
\u26A0\uFE0F ${criticalCount} critical issue(s) detected.`));
|
|
7081
7227
|
const proceed = await promptYesNo3("Proceed anyway?", false);
|
|
7082
7228
|
if (!proceed) {
|
|
7083
7229
|
saveDraft(cwd, constitution);
|
|
7084
|
-
console.log(
|
|
7230
|
+
console.log(chalk13.dim("\nDraft saved. Address the issues and run `archon interview` again.\n"));
|
|
7085
7231
|
return;
|
|
7086
7232
|
}
|
|
7087
7233
|
}
|
|
7088
7234
|
} else {
|
|
7089
|
-
console.log(
|
|
7235
|
+
console.log(chalk13.green("\n\u2713 Scope looks reasonable! No major concerns detected.\n"));
|
|
7090
7236
|
}
|
|
7091
|
-
console.log(
|
|
7237
|
+
console.log(chalk13.bold("\n\u{1F4CB} Constitution Summary\n"));
|
|
7092
7238
|
console.log(summarizeConstitution(constitution));
|
|
7093
7239
|
console.log();
|
|
7094
7240
|
if (options.dryRun) {
|
|
7095
|
-
console.log(
|
|
7241
|
+
console.log(chalk13.dim("(Dry run mode - not freezing Constitution)"));
|
|
7096
7242
|
saveDraft(cwd, constitution);
|
|
7097
7243
|
return;
|
|
7098
7244
|
}
|
|
7099
7245
|
const confirmFreeze = await promptYesNo3("Freeze this Constitution and start building?", true);
|
|
7100
7246
|
if (!confirmFreeze) {
|
|
7101
7247
|
saveDraft(cwd, constitution);
|
|
7102
|
-
console.log(
|
|
7248
|
+
console.log(chalk13.dim("\nDraft saved. Run `archon interview` to continue.\n"));
|
|
7103
7249
|
return;
|
|
7104
7250
|
}
|
|
7105
7251
|
const spinner = ora3("Freezing Constitution...").start();
|
|
@@ -7110,15 +7256,15 @@ async function interview(options = {}) {
|
|
|
7110
7256
|
const { unlinkSync } = await import("fs");
|
|
7111
7257
|
unlinkSync(draftPath);
|
|
7112
7258
|
}
|
|
7113
|
-
spinner.succeed(
|
|
7259
|
+
spinner.succeed(chalk13.green("Constitution frozen!"));
|
|
7114
7260
|
console.log();
|
|
7115
|
-
console.log(
|
|
7116
|
-
console.log(
|
|
7261
|
+
console.log(chalk13.dim(`Hash: ${frozen.hash?.substring(0, 32)}...`));
|
|
7262
|
+
console.log(chalk13.dim(`Saved: ${constitutionPath}`));
|
|
7117
7263
|
console.log();
|
|
7118
|
-
console.log(
|
|
7119
|
-
console.log(` ${
|
|
7120
|
-
console.log(` ${
|
|
7121
|
-
console.log(` ${
|
|
7264
|
+
console.log(chalk13.bold("Next Steps:\n"));
|
|
7265
|
+
console.log(` ${chalk13.cyan("1.")} Run ${chalk13.bold("archon generate")} to create atoms from this Constitution`);
|
|
7266
|
+
console.log(` ${chalk13.cyan("2.")} Run ${chalk13.bold("archon list")} to see generated atoms`);
|
|
7267
|
+
console.log(` ${chalk13.cyan("3.")} Run ${chalk13.bold("archon execute <atom-id>")} to start building`);
|
|
7122
7268
|
console.log();
|
|
7123
7269
|
} catch (err2) {
|
|
7124
7270
|
spinner.fail("Failed to freeze Constitution");
|
|
@@ -7127,18 +7273,18 @@ async function interview(options = {}) {
|
|
|
7127
7273
|
}
|
|
7128
7274
|
async function runPhase(phase, constitution, cwd) {
|
|
7129
7275
|
const phaseInfo = INTERVIEW_PHASES[phase];
|
|
7130
|
-
console.log(
|
|
7131
|
-
console.log(
|
|
7276
|
+
console.log(chalk13.bold(`Phase ${phase}: ${phaseInfo.name}`));
|
|
7277
|
+
console.log(chalk13.dim(phaseInfo.description));
|
|
7132
7278
|
console.log();
|
|
7133
7279
|
const skippable = getSkippableQuestions(phase, constitution);
|
|
7134
7280
|
let updatedConstitution = { ...constitution };
|
|
7135
7281
|
for (const question of phaseInfo.questions) {
|
|
7136
7282
|
if (skippable.includes(question.id)) {
|
|
7137
|
-
console.log(
|
|
7283
|
+
console.log(chalk13.dim(`[\u2713] ${question.prompt.split("?")[0]}... (already answered)`));
|
|
7138
7284
|
continue;
|
|
7139
7285
|
}
|
|
7140
7286
|
if (phase === 5 && question.id === "review_summary") {
|
|
7141
|
-
console.log(
|
|
7287
|
+
console.log(chalk13.bold("\n\u{1F4CB} Current State:\n"));
|
|
7142
7288
|
console.log(summarizeConstitution(updatedConstitution));
|
|
7143
7289
|
console.log();
|
|
7144
7290
|
}
|
|
@@ -7155,14 +7301,14 @@ async function runPhase(phase, constitution, cwd) {
|
|
|
7155
7301
|
if (question.validator) {
|
|
7156
7302
|
const validation = question.validator(answer);
|
|
7157
7303
|
if (!validation.valid) {
|
|
7158
|
-
console.log(
|
|
7304
|
+
console.log(chalk13.red(` ${validation.error}`));
|
|
7159
7305
|
continue;
|
|
7160
7306
|
}
|
|
7161
7307
|
}
|
|
7162
7308
|
const extracted = question.extractor(answer, updatedConstitution);
|
|
7163
7309
|
updatedConstitution = { ...updatedConstitution, ...extracted };
|
|
7164
7310
|
if (question.followUp && answer.length > 10) {
|
|
7165
|
-
console.log(
|
|
7311
|
+
console.log(chalk13.dim(` ${question.followUp}`));
|
|
7166
7312
|
}
|
|
7167
7313
|
}
|
|
7168
7314
|
return { action: "next", constitution: updatedConstitution };
|
|
@@ -7172,7 +7318,7 @@ function saveDraft(cwd, constitution) {
|
|
|
7172
7318
|
writeFileSync(draftPath, serializeConstitution(constitution));
|
|
7173
7319
|
}
|
|
7174
7320
|
async function promptQuestion(question) {
|
|
7175
|
-
const prefix = question.required ?
|
|
7321
|
+
const prefix = question.required ? chalk13.red("*") : " ";
|
|
7176
7322
|
return prompt2(`${prefix} ${question.prompt}`);
|
|
7177
7323
|
}
|
|
7178
7324
|
function prompt2(question) {
|
|
@@ -7181,7 +7327,7 @@ function prompt2(question) {
|
|
|
7181
7327
|
input: process.stdin,
|
|
7182
7328
|
output: process.stdout
|
|
7183
7329
|
});
|
|
7184
|
-
rl.question(`${
|
|
7330
|
+
rl.question(`${chalk13.cyan("?")} ${question}
|
|
7185
7331
|
> `, (answer) => {
|
|
7186
7332
|
rl.close();
|
|
7187
7333
|
resolve(answer.trim());
|
|
@@ -7195,7 +7341,7 @@ function promptYesNo3(question, defaultValue) {
|
|
|
7195
7341
|
output: process.stdout
|
|
7196
7342
|
});
|
|
7197
7343
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7198
|
-
rl.question(`${
|
|
7344
|
+
rl.question(`${chalk13.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7199
7345
|
rl.close();
|
|
7200
7346
|
if (answer.trim() === "") {
|
|
7201
7347
|
resolve(defaultValue);
|
|
@@ -7214,10 +7360,10 @@ async function showConstitution() {
|
|
|
7214
7360
|
console.log(summarizeConstitution(constitution));
|
|
7215
7361
|
} else if (existsSync13(draftPath)) {
|
|
7216
7362
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
7217
|
-
console.log(
|
|
7363
|
+
console.log(chalk13.yellow("[DRAFT]"));
|
|
7218
7364
|
console.log(summarizeConstitution(draft));
|
|
7219
7365
|
} else {
|
|
7220
|
-
console.log(
|
|
7366
|
+
console.log(chalk13.dim("No Constitution found. Run `archon interview` to create one."));
|
|
7221
7367
|
}
|
|
7222
7368
|
}
|
|
7223
7369
|
async function validateConstitutionCommand() {
|
|
@@ -7226,23 +7372,23 @@ async function validateConstitutionCommand() {
|
|
|
7226
7372
|
const draftPath = getDraftPath(cwd);
|
|
7227
7373
|
const path2 = existsSync13(constitutionPath) ? constitutionPath : draftPath;
|
|
7228
7374
|
if (!existsSync13(path2)) {
|
|
7229
|
-
console.log(
|
|
7375
|
+
console.log(chalk13.dim("No Constitution found. Run `archon interview` to create one."));
|
|
7230
7376
|
return;
|
|
7231
7377
|
}
|
|
7232
7378
|
const constitution = deserializeConstitution(readFileSync5(path2, "utf-8"));
|
|
7233
7379
|
const result = validateConstitution(constitution);
|
|
7234
7380
|
if (result.valid) {
|
|
7235
|
-
console.log(
|
|
7381
|
+
console.log(chalk13.green("\u2713 Constitution is valid"));
|
|
7236
7382
|
} else {
|
|
7237
|
-
console.log(
|
|
7383
|
+
console.log(chalk13.red("\u2717 Constitution has errors:"));
|
|
7238
7384
|
for (const error of result.errors) {
|
|
7239
|
-
console.log(
|
|
7385
|
+
console.log(chalk13.red(` \u2022 ${error}`));
|
|
7240
7386
|
}
|
|
7241
7387
|
}
|
|
7242
7388
|
if (result.warnings.length > 0) {
|
|
7243
|
-
console.log(
|
|
7389
|
+
console.log(chalk13.yellow("\nWarnings:"));
|
|
7244
7390
|
for (const warning of result.warnings) {
|
|
7245
|
-
console.log(
|
|
7391
|
+
console.log(chalk13.yellow(` \u2022 ${warning}`));
|
|
7246
7392
|
}
|
|
7247
7393
|
}
|
|
7248
7394
|
}
|
|
@@ -7250,7 +7396,7 @@ async function exportConstitution(format) {
|
|
|
7250
7396
|
const cwd = process.cwd();
|
|
7251
7397
|
const constitutionPath = getConstitutionPath(cwd);
|
|
7252
7398
|
if (!existsSync13(constitutionPath)) {
|
|
7253
|
-
console.log(
|
|
7399
|
+
console.log(chalk13.dim("No frozen Constitution found."));
|
|
7254
7400
|
return;
|
|
7255
7401
|
}
|
|
7256
7402
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
@@ -7263,26 +7409,26 @@ async function exportConstitution(format) {
|
|
|
7263
7409
|
console.log(summarizeConstitution(constitution));
|
|
7264
7410
|
break;
|
|
7265
7411
|
default:
|
|
7266
|
-
console.log(
|
|
7412
|
+
console.log(chalk13.red(`Unknown format: ${format}. Use 'json' or 'markdown'.`));
|
|
7267
7413
|
}
|
|
7268
7414
|
}
|
|
7269
7415
|
async function generateAtoms(options = {}) {
|
|
7270
7416
|
const cwd = process.cwd();
|
|
7271
7417
|
const constitutionPath = getConstitutionPath(cwd);
|
|
7272
7418
|
if (!existsSync13(constitutionPath)) {
|
|
7273
|
-
console.log(
|
|
7274
|
-
console.log(
|
|
7419
|
+
console.log(chalk13.red("No frozen Constitution found."));
|
|
7420
|
+
console.log(chalk13.dim("Run `archon interview` to create one first."));
|
|
7275
7421
|
return;
|
|
7276
7422
|
}
|
|
7277
7423
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
7278
7424
|
if (constitution.state !== "FROZEN") {
|
|
7279
|
-
console.log(
|
|
7280
|
-
console.log(
|
|
7425
|
+
console.log(chalk13.yellow("Constitution is not frozen yet."));
|
|
7426
|
+
console.log(chalk13.dim("Complete the interview and freeze before generating atoms."));
|
|
7281
7427
|
return;
|
|
7282
7428
|
}
|
|
7283
|
-
console.log(
|
|
7284
|
-
console.log(
|
|
7285
|
-
console.log(
|
|
7429
|
+
console.log(chalk13.bold("\n\u{1F527} Generating Atoms from Constitution\n"));
|
|
7430
|
+
console.log(chalk13.dim(`Project: ${constitution.branding.projectName}`));
|
|
7431
|
+
console.log(chalk13.dim(`Hash: ${constitution.hash?.substring(0, 16)}...`));
|
|
7286
7432
|
console.log();
|
|
7287
7433
|
const spinner = ora3("Generating atoms...").start();
|
|
7288
7434
|
const result = generateAtomsFromConstitution(constitution, {
|
|
@@ -7295,7 +7441,7 @@ async function generateAtoms(options = {}) {
|
|
|
7295
7441
|
console.log(summarizeGeneration(result));
|
|
7296
7442
|
console.log();
|
|
7297
7443
|
if (options.dryRun) {
|
|
7298
|
-
console.log(
|
|
7444
|
+
console.log(chalk13.dim("(Dry run - not writing prd.json)"));
|
|
7299
7445
|
return;
|
|
7300
7446
|
}
|
|
7301
7447
|
const prdPath = options.output ?? join13(cwd, "prd.json");
|
|
@@ -7303,23 +7449,23 @@ async function generateAtoms(options = {}) {
|
|
|
7303
7449
|
if (existsSync13(prdPath)) {
|
|
7304
7450
|
const overwrite = await promptYesNo3("prd.json already exists. Overwrite?", false);
|
|
7305
7451
|
if (!overwrite) {
|
|
7306
|
-
console.log(
|
|
7452
|
+
console.log(chalk13.dim("Cancelled. Existing prd.json preserved."));
|
|
7307
7453
|
return;
|
|
7308
7454
|
}
|
|
7309
7455
|
}
|
|
7310
7456
|
writeFileSync(prdPath, JSON.stringify(prdContent, null, 2));
|
|
7311
|
-
console.log(
|
|
7457
|
+
console.log(chalk13.green(`
|
|
7312
7458
|
\u2713 Written to ${prdPath}`));
|
|
7313
7459
|
console.log();
|
|
7314
|
-
console.log(
|
|
7315
|
-
console.log(` ${
|
|
7316
|
-
console.log(` ${
|
|
7317
|
-
console.log(` ${
|
|
7460
|
+
console.log(chalk13.bold("Next Steps:\n"));
|
|
7461
|
+
console.log(` ${chalk13.cyan("1.")} Run ${chalk13.bold("archon list")} to see all atoms`);
|
|
7462
|
+
console.log(` ${chalk13.cyan("2.")} Run ${chalk13.bold("archon execute ATOM-001")} to start building`);
|
|
7463
|
+
console.log(` ${chalk13.cyan("3.")} Run ${chalk13.bold("archon watch")} to monitor progress`);
|
|
7318
7464
|
console.log();
|
|
7319
7465
|
}
|
|
7320
7466
|
|
|
7321
7467
|
// src/cli/eject.ts
|
|
7322
|
-
import
|
|
7468
|
+
import chalk14 from "chalk";
|
|
7323
7469
|
import { existsSync as existsSync14, rmSync } from "fs";
|
|
7324
7470
|
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
7325
7471
|
import { join as join14 } from "path";
|
|
@@ -7336,70 +7482,70 @@ var METADATA_FILES = [
|
|
|
7336
7482
|
];
|
|
7337
7483
|
async function eject(options = {}) {
|
|
7338
7484
|
const cwd = process.cwd();
|
|
7339
|
-
console.log(
|
|
7485
|
+
console.log(chalk14.blue("\n\u{1F680} ArchonDev Eject\n"));
|
|
7340
7486
|
const archonDir = join14(cwd, ".archon");
|
|
7341
7487
|
if (!existsSync14(archonDir)) {
|
|
7342
|
-
console.log(
|
|
7488
|
+
console.log(chalk14.yellow("This does not appear to be an ArchonDev project (.archon/ not found)."));
|
|
7343
7489
|
return;
|
|
7344
7490
|
}
|
|
7345
|
-
console.log(
|
|
7491
|
+
console.log(chalk14.dim("The following will be removed/modified:\n"));
|
|
7346
7492
|
const filesToRemove = [];
|
|
7347
7493
|
for (const file of ARCHON_FILES) {
|
|
7348
7494
|
const filePath = join14(cwd, file);
|
|
7349
7495
|
if (existsSync14(filePath)) {
|
|
7350
7496
|
filesToRemove.push(file);
|
|
7351
|
-
console.log(
|
|
7497
|
+
console.log(chalk14.red(` \u2717 ${file}`));
|
|
7352
7498
|
}
|
|
7353
7499
|
}
|
|
7354
7500
|
const archMd = join14(cwd, "ARCHITECTURE.md");
|
|
7355
7501
|
if (existsSync14(archMd) && !options.keepArchitecture) {
|
|
7356
|
-
console.log(
|
|
7502
|
+
console.log(chalk14.yellow(` ? ARCHITECTURE.md (will be kept by default)`));
|
|
7357
7503
|
}
|
|
7358
7504
|
console.log();
|
|
7359
|
-
console.log(
|
|
7505
|
+
console.log(chalk14.dim("Files to be modified:"));
|
|
7360
7506
|
for (const file of METADATA_FILES) {
|
|
7361
7507
|
const filePath = join14(cwd, file);
|
|
7362
7508
|
if (existsSync14(filePath)) {
|
|
7363
|
-
console.log(
|
|
7509
|
+
console.log(chalk14.yellow(` \u25CF ${file}`));
|
|
7364
7510
|
}
|
|
7365
7511
|
}
|
|
7366
7512
|
console.log();
|
|
7367
7513
|
if (!options.force) {
|
|
7368
7514
|
const confirmed = await promptYesNo4("This will permanently remove ArchonDev from your project. Continue?", false);
|
|
7369
7515
|
if (!confirmed) {
|
|
7370
|
-
console.log(
|
|
7516
|
+
console.log(chalk14.dim("Eject cancelled."));
|
|
7371
7517
|
return;
|
|
7372
7518
|
}
|
|
7373
7519
|
}
|
|
7374
7520
|
console.log();
|
|
7375
7521
|
const result = await performEject(cwd, options);
|
|
7376
7522
|
if (result.success) {
|
|
7377
|
-
console.log(
|
|
7523
|
+
console.log(chalk14.green("\n\u2705 Eject complete!\n"));
|
|
7378
7524
|
if (result.filesRemoved.length > 0) {
|
|
7379
|
-
console.log(
|
|
7525
|
+
console.log(chalk14.dim("Removed:"));
|
|
7380
7526
|
for (const file of result.filesRemoved) {
|
|
7381
|
-
console.log(
|
|
7527
|
+
console.log(chalk14.dim(` - ${file}`));
|
|
7382
7528
|
}
|
|
7383
7529
|
}
|
|
7384
7530
|
if (result.filesModified.length > 0) {
|
|
7385
|
-
console.log(
|
|
7531
|
+
console.log(chalk14.dim("\nModified:"));
|
|
7386
7532
|
for (const file of result.filesModified) {
|
|
7387
|
-
console.log(
|
|
7533
|
+
console.log(chalk14.dim(` - ${file}`));
|
|
7388
7534
|
}
|
|
7389
7535
|
}
|
|
7390
7536
|
if (result.warnings.length > 0) {
|
|
7391
|
-
console.log(
|
|
7537
|
+
console.log(chalk14.yellow("\nWarnings:"));
|
|
7392
7538
|
for (const warning of result.warnings) {
|
|
7393
|
-
console.log(
|
|
7539
|
+
console.log(chalk14.yellow(` \u26A0\uFE0F ${warning}`));
|
|
7394
7540
|
}
|
|
7395
7541
|
}
|
|
7396
7542
|
console.log();
|
|
7397
|
-
console.log(
|
|
7398
|
-
console.log(
|
|
7543
|
+
console.log(chalk14.blue("Your project is now a standard repository."));
|
|
7544
|
+
console.log(chalk14.dim("Thank you for using ArchonDev!"));
|
|
7399
7545
|
} else {
|
|
7400
|
-
console.log(
|
|
7546
|
+
console.log(chalk14.red("\n\u274C Eject failed."));
|
|
7401
7547
|
for (const warning of result.warnings) {
|
|
7402
|
-
console.log(
|
|
7548
|
+
console.log(chalk14.red(` ${warning}`));
|
|
7403
7549
|
}
|
|
7404
7550
|
}
|
|
7405
7551
|
}
|
|
@@ -7506,17 +7652,17 @@ async function performEject(cwd, options) {
|
|
|
7506
7652
|
}
|
|
7507
7653
|
async function ejectDryRun() {
|
|
7508
7654
|
const cwd = process.cwd();
|
|
7509
|
-
console.log(
|
|
7655
|
+
console.log(chalk14.blue("\n\u{1F50D} Eject Dry Run\n"));
|
|
7510
7656
|
const archonDir = join14(cwd, ".archon");
|
|
7511
7657
|
if (!existsSync14(archonDir)) {
|
|
7512
|
-
console.log(
|
|
7658
|
+
console.log(chalk14.yellow("This does not appear to be an ArchonDev project."));
|
|
7513
7659
|
return;
|
|
7514
7660
|
}
|
|
7515
7661
|
console.log("The following would be removed:\n");
|
|
7516
7662
|
for (const file of ARCHON_FILES) {
|
|
7517
7663
|
const filePath = join14(cwd, file);
|
|
7518
7664
|
if (existsSync14(filePath)) {
|
|
7519
|
-
console.log(
|
|
7665
|
+
console.log(chalk14.red(` \u2717 ${file}`));
|
|
7520
7666
|
}
|
|
7521
7667
|
}
|
|
7522
7668
|
console.log();
|
|
@@ -7524,11 +7670,11 @@ async function ejectDryRun() {
|
|
|
7524
7670
|
for (const file of METADATA_FILES) {
|
|
7525
7671
|
const filePath = join14(cwd, file);
|
|
7526
7672
|
if (existsSync14(filePath)) {
|
|
7527
|
-
console.log(
|
|
7673
|
+
console.log(chalk14.yellow(` \u25CF ${file}`));
|
|
7528
7674
|
}
|
|
7529
7675
|
}
|
|
7530
7676
|
console.log();
|
|
7531
|
-
console.log(
|
|
7677
|
+
console.log(chalk14.dim('Run "archon eject" to proceed.'));
|
|
7532
7678
|
}
|
|
7533
7679
|
function promptYesNo4(question, defaultValue) {
|
|
7534
7680
|
return new Promise((resolve) => {
|
|
@@ -7537,7 +7683,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7537
7683
|
output: process.stdout
|
|
7538
7684
|
});
|
|
7539
7685
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7540
|
-
rl.question(`${
|
|
7686
|
+
rl.question(`${chalk14.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7541
7687
|
rl.close();
|
|
7542
7688
|
if (answer.trim() === "") {
|
|
7543
7689
|
resolve(defaultValue);
|
|
@@ -7549,7 +7695,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7549
7695
|
}
|
|
7550
7696
|
|
|
7551
7697
|
// src/cli/revert.ts
|
|
7552
|
-
import
|
|
7698
|
+
import chalk15 from "chalk";
|
|
7553
7699
|
import { execSync as execSync4 } from "child_process";
|
|
7554
7700
|
import { existsSync as existsSync15 } from "fs";
|
|
7555
7701
|
import { readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
@@ -7594,35 +7740,35 @@ async function findAtomCommits(limit = 50) {
|
|
|
7594
7740
|
}
|
|
7595
7741
|
return commits;
|
|
7596
7742
|
} catch (error) {
|
|
7597
|
-
console.error(
|
|
7743
|
+
console.error(chalk15.red("Failed to read git history:"), error instanceof Error ? error.message : "Unknown error");
|
|
7598
7744
|
return [];
|
|
7599
7745
|
}
|
|
7600
7746
|
}
|
|
7601
7747
|
async function historyCommand(options) {
|
|
7602
7748
|
const limit = options.limit ?? 20;
|
|
7603
|
-
console.log(
|
|
7749
|
+
console.log(chalk15.blue("\n\u{1F4DC} Atom Execution History\n"));
|
|
7604
7750
|
const commits = await findAtomCommits(limit);
|
|
7605
7751
|
if (commits.length === 0) {
|
|
7606
|
-
console.log(
|
|
7607
|
-
console.log(
|
|
7752
|
+
console.log(chalk15.dim("No atom commits found in git history."));
|
|
7753
|
+
console.log(chalk15.dim('Atom commits are created when you run "archon execute <atom-id>".'));
|
|
7608
7754
|
return;
|
|
7609
7755
|
}
|
|
7610
|
-
console.log(
|
|
7756
|
+
console.log(chalk15.dim(`Showing ${commits.length} atom commit(s):
|
|
7611
7757
|
`));
|
|
7612
7758
|
for (const commit of commits) {
|
|
7613
7759
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7614
7760
|
const filesLabel = commit.filesChanged === 1 ? "file" : "files";
|
|
7615
|
-
console.log(`${
|
|
7616
|
-
console.log(
|
|
7617
|
-
console.log(
|
|
7761
|
+
console.log(`${chalk15.yellow(shortHash)} ${chalk15.cyan(commit.atomId)}`);
|
|
7762
|
+
console.log(chalk15.dim(` ${commit.message}`));
|
|
7763
|
+
console.log(chalk15.dim(` ${commit.date} | ${commit.filesChanged} ${filesLabel} changed`));
|
|
7618
7764
|
console.log();
|
|
7619
7765
|
}
|
|
7620
|
-
console.log(
|
|
7621
|
-
console.log(
|
|
7766
|
+
console.log(chalk15.dim("To revert an atom: archon revert <atom-id>"));
|
|
7767
|
+
console.log(chalk15.dim("Or by commit hash: archon revert --commit <hash>"));
|
|
7622
7768
|
}
|
|
7623
7769
|
async function revertCommand(atomIdOrHash, options = {}) {
|
|
7624
7770
|
const cwd = process.cwd();
|
|
7625
|
-
console.log(
|
|
7771
|
+
console.log(chalk15.blue("\n\u23EA Atom Revert\n"));
|
|
7626
7772
|
let commit;
|
|
7627
7773
|
if (atomIdOrHash.match(/^[a-f0-9]{7,40}$/i)) {
|
|
7628
7774
|
const commits = await findAtomCommits(100);
|
|
@@ -7632,54 +7778,54 @@ async function revertCommand(atomIdOrHash, options = {}) {
|
|
|
7632
7778
|
commit = commits.find((c) => c.atomId.toLowerCase() === atomIdOrHash.toLowerCase());
|
|
7633
7779
|
}
|
|
7634
7780
|
if (!commit) {
|
|
7635
|
-
console.log(
|
|
7636
|
-
console.log(
|
|
7781
|
+
console.log(chalk15.red(`No atom commit found for: ${atomIdOrHash}`));
|
|
7782
|
+
console.log(chalk15.dim('Run "archon history" to see available atom commits.'));
|
|
7637
7783
|
return;
|
|
7638
7784
|
}
|
|
7639
|
-
console.log(`Atom: ${
|
|
7640
|
-
console.log(`Commit: ${
|
|
7785
|
+
console.log(`Atom: ${chalk15.cyan(commit.atomId)}`);
|
|
7786
|
+
console.log(`Commit: ${chalk15.yellow(commit.commitHash.substring(0, 7))}`);
|
|
7641
7787
|
console.log(`Message: ${commit.message}`);
|
|
7642
7788
|
console.log(`Date: ${commit.date}`);
|
|
7643
7789
|
console.log(`Files changed: ${commit.filesChanged}`);
|
|
7644
7790
|
console.log();
|
|
7645
7791
|
try {
|
|
7646
|
-
console.log(
|
|
7792
|
+
console.log(chalk15.dim("Changes to be reverted:"));
|
|
7647
7793
|
const diffStat = execSync4(
|
|
7648
7794
|
`git diff --stat ${commit.commitHash}^..${commit.commitHash}`,
|
|
7649
7795
|
{ cwd, encoding: "utf-8" }
|
|
7650
7796
|
);
|
|
7651
|
-
console.log(
|
|
7797
|
+
console.log(chalk15.dim(diffStat));
|
|
7652
7798
|
} catch {
|
|
7653
7799
|
}
|
|
7654
7800
|
if (!options.force) {
|
|
7655
7801
|
const confirmed = await promptYesNo5("Revert this atom commit?", false);
|
|
7656
7802
|
if (!confirmed) {
|
|
7657
|
-
console.log(
|
|
7803
|
+
console.log(chalk15.dim("Revert cancelled."));
|
|
7658
7804
|
return;
|
|
7659
7805
|
}
|
|
7660
7806
|
}
|
|
7661
7807
|
try {
|
|
7662
7808
|
const revertArgs = options.noCommit ? "--no-commit" : "";
|
|
7663
7809
|
execSync4(`git revert ${revertArgs} ${commit.commitHash}`, { cwd, stdio: "pipe" });
|
|
7664
|
-
console.log(
|
|
7810
|
+
console.log(chalk15.green(`
|
|
7665
7811
|
\u2705 Successfully reverted ${commit.atomId}`));
|
|
7666
7812
|
if (options.noCommit) {
|
|
7667
|
-
console.log(
|
|
7668
|
-
console.log(
|
|
7813
|
+
console.log(chalk15.dim("Changes are staged but not committed."));
|
|
7814
|
+
console.log(chalk15.dim('Run "git commit" to finalize the revert.'));
|
|
7669
7815
|
} else {
|
|
7670
|
-
console.log(
|
|
7816
|
+
console.log(chalk15.dim("A new commit has been created to undo the changes."));
|
|
7671
7817
|
}
|
|
7672
7818
|
await updateAtomStatus(commit.atomId, "REVERTED");
|
|
7673
7819
|
} catch (error) {
|
|
7674
7820
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
7675
7821
|
if (errorMsg.includes("conflict")) {
|
|
7676
|
-
console.log(
|
|
7677
|
-
console.log(
|
|
7678
|
-
console.log(
|
|
7679
|
-
console.log(
|
|
7822
|
+
console.log(chalk15.yellow("\n\u26A0\uFE0F Merge conflict detected during revert."));
|
|
7823
|
+
console.log(chalk15.dim("Resolve conflicts manually, then:"));
|
|
7824
|
+
console.log(chalk15.dim(" git add ."));
|
|
7825
|
+
console.log(chalk15.dim(" git revert --continue"));
|
|
7680
7826
|
} else {
|
|
7681
|
-
console.log(
|
|
7682
|
-
console.log(
|
|
7827
|
+
console.log(chalk15.red("\n\u274C Revert failed:"), errorMsg);
|
|
7828
|
+
console.log(chalk15.dim("You may need to resolve this manually."));
|
|
7683
7829
|
}
|
|
7684
7830
|
}
|
|
7685
7831
|
}
|
|
@@ -7698,10 +7844,10 @@ async function updateAtomStatus(atomId, status2) {
|
|
|
7698
7844
|
}
|
|
7699
7845
|
}
|
|
7700
7846
|
async function revertableAtoms() {
|
|
7701
|
-
console.log(
|
|
7847
|
+
console.log(chalk15.blue("\n\u{1F504} Revertable Atoms\n"));
|
|
7702
7848
|
const commits = await findAtomCommits(30);
|
|
7703
7849
|
if (commits.length === 0) {
|
|
7704
|
-
console.log(
|
|
7850
|
+
console.log(chalk15.dim("No atom commits found."));
|
|
7705
7851
|
return;
|
|
7706
7852
|
}
|
|
7707
7853
|
const atomMap = /* @__PURE__ */ new Map();
|
|
@@ -7710,14 +7856,14 @@ async function revertableAtoms() {
|
|
|
7710
7856
|
atomMap.set(commit.atomId, commit);
|
|
7711
7857
|
}
|
|
7712
7858
|
}
|
|
7713
|
-
console.log(
|
|
7859
|
+
console.log(chalk15.dim(`Found ${atomMap.size} unique atom(s) in history:
|
|
7714
7860
|
`));
|
|
7715
7861
|
for (const [atomId, commit] of atomMap) {
|
|
7716
7862
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7717
|
-
console.log(` ${
|
|
7863
|
+
console.log(` ${chalk15.cyan(atomId)} ${chalk15.dim(`(${shortHash})`)} - ${commit.message.substring(0, 50)}`);
|
|
7718
7864
|
}
|
|
7719
7865
|
console.log();
|
|
7720
|
-
console.log(
|
|
7866
|
+
console.log(chalk15.dim("To revert: archon revert <atom-id>"));
|
|
7721
7867
|
}
|
|
7722
7868
|
function promptYesNo5(question, defaultValue) {
|
|
7723
7869
|
return new Promise((resolve) => {
|
|
@@ -7726,7 +7872,7 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7726
7872
|
output: process.stdout
|
|
7727
7873
|
});
|
|
7728
7874
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7729
|
-
rl.question(`${
|
|
7875
|
+
rl.question(`${chalk15.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7730
7876
|
rl.close();
|
|
7731
7877
|
if (answer.trim() === "") {
|
|
7732
7878
|
resolve(defaultValue);
|
|
@@ -7738,17 +7884,17 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7738
7884
|
}
|
|
7739
7885
|
|
|
7740
7886
|
// src/cli/models-sync.ts
|
|
7741
|
-
import
|
|
7887
|
+
import chalk16 from "chalk";
|
|
7742
7888
|
async function modelsSync(options) {
|
|
7743
7889
|
const supabaseUrl = process.env["SUPABASE_URL"];
|
|
7744
7890
|
const supabaseKey = process.env["SUPABASE_SERVICE_ROLE_KEY"] || process.env["SUPABASE_ANON_KEY"];
|
|
7745
7891
|
if (!supabaseUrl) {
|
|
7746
|
-
console.log(
|
|
7747
|
-
console.log(
|
|
7748
|
-
console.log(
|
|
7892
|
+
console.log(chalk16.red("SUPABASE_URL not set. Cannot trigger remote sync."));
|
|
7893
|
+
console.log(chalk16.dim("Run the pricing check locally instead:"));
|
|
7894
|
+
console.log(chalk16.dim(" npx tsx scripts/update-model-pricing.ts --check"));
|
|
7749
7895
|
return;
|
|
7750
7896
|
}
|
|
7751
|
-
console.log(
|
|
7897
|
+
console.log(chalk16.blue("\n\u{1F504} Triggering model registry sync...\n"));
|
|
7752
7898
|
try {
|
|
7753
7899
|
const functionUrl = `${supabaseUrl}/functions/v1/model-registry-sync`;
|
|
7754
7900
|
const response = await fetch(functionUrl, {
|
|
@@ -7760,83 +7906,83 @@ async function modelsSync(options) {
|
|
|
7760
7906
|
});
|
|
7761
7907
|
if (!response.ok) {
|
|
7762
7908
|
const errorText = await response.text();
|
|
7763
|
-
console.log(
|
|
7909
|
+
console.log(chalk16.red(`Sync failed: ${response.status} - ${errorText}`));
|
|
7764
7910
|
return;
|
|
7765
7911
|
}
|
|
7766
7912
|
const result = await response.json();
|
|
7767
|
-
console.log(
|
|
7913
|
+
console.log(chalk16.bold("Sync Results:"));
|
|
7768
7914
|
console.log(` Providers checked: ${result.providersChecked.join(", ")}`);
|
|
7769
7915
|
console.log(` Duration: ${result.durationMs}ms`);
|
|
7770
7916
|
console.log();
|
|
7771
|
-
console.log(
|
|
7917
|
+
console.log(chalk16.bold("Parse Confidence:"));
|
|
7772
7918
|
for (const [provider, score] of Object.entries(result.confidenceScores)) {
|
|
7773
7919
|
const pct = (score * 100).toFixed(0);
|
|
7774
|
-
const color = score >= 0.8 ?
|
|
7920
|
+
const color = score >= 0.8 ? chalk16.green : score >= 0.5 ? chalk16.yellow : chalk16.red;
|
|
7775
7921
|
console.log(` ${provider}: ${color(pct + "%")}`);
|
|
7776
7922
|
}
|
|
7777
7923
|
console.log();
|
|
7778
7924
|
if (result.diffs.length === 0) {
|
|
7779
|
-
console.log(
|
|
7925
|
+
console.log(chalk16.green("\u2705 All model pricing is up to date. No changes detected."));
|
|
7780
7926
|
} else {
|
|
7781
7927
|
const pricingChanges = result.diffs.filter((d) => d.type === "PRICING_CHANGE");
|
|
7782
7928
|
const newModels = result.diffs.filter((d) => d.type === "NEW_MODEL");
|
|
7783
7929
|
if (pricingChanges.length > 0) {
|
|
7784
|
-
console.log(
|
|
7930
|
+
console.log(chalk16.yellow(`\u{1F4B0} Pricing Changes (${pricingChanges.length}):`));
|
|
7785
7931
|
for (const d of pricingChanges) {
|
|
7786
|
-
console.log(` ${d.provider}/${
|
|
7787
|
-
console.log(` Old: ${
|
|
7788
|
-
console.log(` New: ${
|
|
7932
|
+
console.log(` ${d.provider}/${chalk16.bold(d.modelId)}`);
|
|
7933
|
+
console.log(` Old: ${chalk16.red(d.oldValue ?? "unknown")}`);
|
|
7934
|
+
console.log(` New: ${chalk16.green(d.newValue ?? "unknown")}`);
|
|
7789
7935
|
}
|
|
7790
7936
|
console.log();
|
|
7791
7937
|
}
|
|
7792
7938
|
if (newModels.length > 0) {
|
|
7793
|
-
console.log(
|
|
7939
|
+
console.log(chalk16.cyan(`\u{1F195} New Models (${newModels.length}):`));
|
|
7794
7940
|
for (const d of newModels) {
|
|
7795
|
-
console.log(` ${d.provider}/${
|
|
7941
|
+
console.log(` ${d.provider}/${chalk16.bold(d.modelId)}: ${d.details}`);
|
|
7796
7942
|
}
|
|
7797
7943
|
console.log();
|
|
7798
7944
|
}
|
|
7799
|
-
console.log(
|
|
7945
|
+
console.log(chalk16.bold(`Applied: ${result.modelsUpdated} updated, ${result.modelsAdded} added`));
|
|
7800
7946
|
}
|
|
7801
7947
|
if (result.parseErrors.length > 0) {
|
|
7802
7948
|
console.log();
|
|
7803
|
-
console.log(
|
|
7949
|
+
console.log(chalk16.red(`\u26A0\uFE0F Warnings/Errors (${result.parseErrors.length}):`));
|
|
7804
7950
|
for (const err2 of result.parseErrors) {
|
|
7805
|
-
console.log(
|
|
7951
|
+
console.log(chalk16.red(` - ${err2}`));
|
|
7806
7952
|
}
|
|
7807
7953
|
}
|
|
7808
7954
|
console.log();
|
|
7809
7955
|
} catch (err2) {
|
|
7810
|
-
console.log(
|
|
7956
|
+
console.log(chalk16.red(`Failed to run sync: ${err2}`));
|
|
7811
7957
|
}
|
|
7812
7958
|
}
|
|
7813
7959
|
async function modelsList() {
|
|
7814
7960
|
const { getAllActiveModels, getModelCost, isFreeModel } = await import("./models-D4NV2MVH.js");
|
|
7815
7961
|
const models = getAllActiveModels();
|
|
7816
|
-
console.log(
|
|
7962
|
+
console.log(chalk16.bold("\n\u{1F4CB} Model Registry\n"));
|
|
7817
7963
|
let currentProvider = "";
|
|
7818
7964
|
for (const model of models) {
|
|
7819
7965
|
if (model.provider !== currentProvider) {
|
|
7820
7966
|
currentProvider = model.provider;
|
|
7821
|
-
console.log(
|
|
7967
|
+
console.log(chalk16.bold.blue(`
|
|
7822
7968
|
${currentProvider.toUpperCase()}`));
|
|
7823
|
-
console.log(
|
|
7969
|
+
console.log(chalk16.dim(" \u2500".repeat(40)));
|
|
7824
7970
|
}
|
|
7825
7971
|
const cost = getModelCost(model.modelId);
|
|
7826
7972
|
const free = isFreeModel(model.modelId);
|
|
7827
|
-
const tier = free ?
|
|
7828
|
-
const category = model.category === "thinking" ?
|
|
7973
|
+
const tier = free ? chalk16.green(" [FREE]") : "";
|
|
7974
|
+
const category = model.category === "thinking" ? chalk16.magenta("thinking") : chalk16.cyan("fast");
|
|
7829
7975
|
const inputPrice = cost ? `$${(cost.costPer1kInput * 1e3).toFixed(2)}/1M` : "?";
|
|
7830
7976
|
const outputPrice = cost ? `$${(cost.costPer1kOutput * 1e3).toFixed(2)}/1M` : "?";
|
|
7831
|
-
console.log(` ${
|
|
7832
|
-
console.log(
|
|
7977
|
+
console.log(` ${chalk16.bold(model.modelId)}${tier}`);
|
|
7978
|
+
console.log(chalk16.dim(` ${category} | Input: ${inputPrice} | Output: ${outputPrice}`));
|
|
7833
7979
|
}
|
|
7834
7980
|
console.log();
|
|
7835
7981
|
}
|
|
7836
7982
|
|
|
7837
7983
|
// src/cli/governance.ts
|
|
7838
7984
|
import { Command as Command2 } from "commander";
|
|
7839
|
-
import
|
|
7985
|
+
import chalk17 from "chalk";
|
|
7840
7986
|
import { existsSync as existsSync19, readFileSync as readFileSync7 } from "fs";
|
|
7841
7987
|
import { readFile as readFile12 } from "fs/promises";
|
|
7842
7988
|
import { join as join19 } from "path";
|
|
@@ -8656,9 +8802,9 @@ function parseContextMeta(content) {
|
|
|
8656
8802
|
function renderStatusCounts(counts) {
|
|
8657
8803
|
const total = Object.values(counts).reduce((sum, value) => sum + value, 0);
|
|
8658
8804
|
if (total === 0) return;
|
|
8659
|
-
console.log(
|
|
8805
|
+
console.log(chalk17.dim(` Tasks: ${total} total`));
|
|
8660
8806
|
console.log(
|
|
8661
|
-
|
|
8807
|
+
chalk17.dim(
|
|
8662
8808
|
` pending: ${counts.pending} | in_progress: ${counts.in_progress} | verification: ${counts.verification} | done: ${counts.done}`
|
|
8663
8809
|
)
|
|
8664
8810
|
);
|
|
@@ -8674,22 +8820,22 @@ function createGovernanceCommand() {
|
|
|
8674
8820
|
const cwd = process.cwd();
|
|
8675
8821
|
const store = new GovernanceStore(cwd);
|
|
8676
8822
|
store.ensureStructure();
|
|
8677
|
-
console.log(
|
|
8823
|
+
console.log(chalk17.bold("\nGovernance Status\n"));
|
|
8678
8824
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8679
8825
|
if (archInfo.path) {
|
|
8680
8826
|
const parser = new ArchitectureParser(archInfo.path);
|
|
8681
8827
|
const parsed = await parser.parse();
|
|
8682
8828
|
if (parsed.success && parsed.schema) {
|
|
8683
8829
|
const posture = parsed.schema.qualityLevel?.posture ?? "unknown";
|
|
8684
|
-
console.log(
|
|
8685
|
-
console.log(
|
|
8686
|
-
console.log(
|
|
8687
|
-
console.log(
|
|
8830
|
+
console.log(chalk17.green(" \u2713") + ` Architecture (${archInfo.source})`);
|
|
8831
|
+
console.log(chalk17.dim(` posture: ${posture}`));
|
|
8832
|
+
console.log(chalk17.dim(` invariants: ${parsed.schema.invariants.length}`));
|
|
8833
|
+
console.log(chalk17.dim(` protected paths: ${parsed.schema.protectedPaths.length}`));
|
|
8688
8834
|
} else {
|
|
8689
|
-
console.log(
|
|
8835
|
+
console.log(chalk17.yellow(" ! Architecture present but failed to parse"));
|
|
8690
8836
|
}
|
|
8691
8837
|
} else {
|
|
8692
|
-
console.log(
|
|
8838
|
+
console.log(chalk17.yellow(" \u25CB No architecture file found"));
|
|
8693
8839
|
}
|
|
8694
8840
|
const tasksPath = join19(cwd, ACTIVE_TASKS_PATH2);
|
|
8695
8841
|
if (existsSync19(tasksPath)) {
|
|
@@ -8699,33 +8845,33 @@ function createGovernanceCommand() {
|
|
|
8699
8845
|
if (tasks2) {
|
|
8700
8846
|
renderStatusCounts(countTaskStatuses(tasks2));
|
|
8701
8847
|
} else {
|
|
8702
|
-
console.log(
|
|
8848
|
+
console.log(chalk17.yellow(" ! tasks.json present but invalid"));
|
|
8703
8849
|
}
|
|
8704
8850
|
} catch {
|
|
8705
|
-
console.log(
|
|
8851
|
+
console.log(chalk17.yellow(" ! tasks.json present but unreadable"));
|
|
8706
8852
|
}
|
|
8707
8853
|
}
|
|
8708
8854
|
const contextPath = join19(cwd, CURRENT_CONTEXT_PATH);
|
|
8709
8855
|
if (existsSync19(contextPath)) {
|
|
8710
8856
|
const content = readFileSync7(contextPath, "utf-8");
|
|
8711
8857
|
const meta = parseContextMeta(content);
|
|
8712
|
-
console.log(
|
|
8858
|
+
console.log(chalk17.dim(` Handoff: ${meta.timestamp ?? "present"}`));
|
|
8713
8859
|
if (meta.reason) {
|
|
8714
|
-
console.log(
|
|
8860
|
+
console.log(chalk17.dim(` reason: ${meta.reason}`));
|
|
8715
8861
|
}
|
|
8716
8862
|
}
|
|
8717
8863
|
const handoffHistoryPath = join19(cwd, HANDOFF_HISTORY_PATH);
|
|
8718
8864
|
if (existsSync19(handoffHistoryPath)) {
|
|
8719
8865
|
const count = lineCount(readFileSync7(handoffHistoryPath, "utf-8"));
|
|
8720
8866
|
if (count > 0) {
|
|
8721
|
-
console.log(
|
|
8867
|
+
console.log(chalk17.dim(` Handoff entries: ${count}`));
|
|
8722
8868
|
}
|
|
8723
8869
|
}
|
|
8724
8870
|
const completedPath = join19(cwd, COMPLETED_TASKS_PATH);
|
|
8725
8871
|
if (existsSync19(completedPath)) {
|
|
8726
8872
|
const count = lineCount(readFileSync7(completedPath, "utf-8"));
|
|
8727
8873
|
if (count > 0) {
|
|
8728
|
-
console.log(
|
|
8874
|
+
console.log(chalk17.dim(` Completed tasks archived: ${count}`));
|
|
8729
8875
|
}
|
|
8730
8876
|
}
|
|
8731
8877
|
console.log("");
|
|
@@ -8736,7 +8882,7 @@ function createGovernanceCommand() {
|
|
|
8736
8882
|
const store = new GovernanceStore(cwd);
|
|
8737
8883
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8738
8884
|
if (!archInfo.path) {
|
|
8739
|
-
console.log(
|
|
8885
|
+
console.log(chalk17.yellow("No architecture file found."));
|
|
8740
8886
|
return;
|
|
8741
8887
|
}
|
|
8742
8888
|
if (options.raw) {
|
|
@@ -8747,11 +8893,11 @@ function createGovernanceCommand() {
|
|
|
8747
8893
|
if (archInfo.source === "agd") {
|
|
8748
8894
|
const result = await store.readArchitecture();
|
|
8749
8895
|
if (!result.ok) {
|
|
8750
|
-
console.log(
|
|
8896
|
+
console.log(chalk17.red(`Failed to read architecture: ${result.error}`));
|
|
8751
8897
|
return;
|
|
8752
8898
|
}
|
|
8753
8899
|
if (!result.value) {
|
|
8754
|
-
console.log(
|
|
8900
|
+
console.log(chalk17.yellow("Architecture file is empty."));
|
|
8755
8901
|
return;
|
|
8756
8902
|
}
|
|
8757
8903
|
console.log(result.value);
|
|
@@ -8761,7 +8907,7 @@ function createGovernanceCommand() {
|
|
|
8761
8907
|
const legacyParsed = matter4(legacyRaw);
|
|
8762
8908
|
const legacyContent = legacyParsed.content.trim();
|
|
8763
8909
|
if (!legacyContent) {
|
|
8764
|
-
console.log(
|
|
8910
|
+
console.log(chalk17.yellow("Architecture file is empty."));
|
|
8765
8911
|
return;
|
|
8766
8912
|
}
|
|
8767
8913
|
console.log(legacyContent);
|
|
@@ -8770,32 +8916,32 @@ function createGovernanceCommand() {
|
|
|
8770
8916
|
const cwd = process.cwd();
|
|
8771
8917
|
const filePath = options.file;
|
|
8772
8918
|
if (!existsSync19(filePath)) {
|
|
8773
|
-
console.log(
|
|
8919
|
+
console.log(chalk17.red(`File not found: ${filePath}`));
|
|
8774
8920
|
process.exit(1);
|
|
8775
8921
|
}
|
|
8776
8922
|
const content = await readFile12(filePath, "utf-8");
|
|
8777
8923
|
const store = new GovernanceStore(cwd);
|
|
8778
8924
|
const result = await store.updateArchitecture(content, options.reason, options.by);
|
|
8779
8925
|
if (!result.ok) {
|
|
8780
|
-
console.log(
|
|
8926
|
+
console.log(chalk17.red(`Failed to update architecture: ${result.error}`));
|
|
8781
8927
|
process.exit(1);
|
|
8782
8928
|
}
|
|
8783
|
-
console.log(
|
|
8929
|
+
console.log(chalk17.green("\u2713 Architecture updated"));
|
|
8784
8930
|
});
|
|
8785
8931
|
const tasks = governance.command("task").description("Update tasks in governance store");
|
|
8786
8932
|
tasks.command("update <taskId>").description("Update task status and notes").requiredOption("-s, --status <status>", "Status: pending, in_progress, verification, done").option("-n, --notes <text>", "Optional notes").action(async (taskId, options) => {
|
|
8787
8933
|
const status2 = options.status;
|
|
8788
8934
|
if (!isTaskStatus(status2)) {
|
|
8789
|
-
console.log(
|
|
8935
|
+
console.log(chalk17.red(`Invalid status: ${options.status}`));
|
|
8790
8936
|
process.exit(1);
|
|
8791
8937
|
}
|
|
8792
8938
|
const store = new GovernanceStore(process.cwd());
|
|
8793
8939
|
const result = await store.updateTask(taskId, status2, options.notes);
|
|
8794
8940
|
if (!result.ok) {
|
|
8795
|
-
console.log(
|
|
8941
|
+
console.log(chalk17.red(`Failed to update task: ${result.error}`));
|
|
8796
8942
|
process.exit(1);
|
|
8797
8943
|
}
|
|
8798
|
-
console.log(
|
|
8944
|
+
console.log(chalk17.green(`\u2713 Task ${taskId} updated to ${status2}`));
|
|
8799
8945
|
});
|
|
8800
8946
|
governance.command("handoff").description("Log a handoff entry and update current context").requiredOption("-r, --reason <text>", "Reason for handoff").requiredOption("-s, --summary <text>", "Summary (single paragraph)").requiredOption("-n, --next <actions...>", "Next actions (space-separated)").option("-f, --from <agent>", "Agent or source name").option("-t, --timestamp <iso>", "Timestamp override (ISO 8601)").action(async (options) => {
|
|
8801
8947
|
const store = new GovernanceStore(process.cwd());
|
|
@@ -8808,10 +8954,10 @@ function createGovernanceCommand() {
|
|
|
8808
8954
|
};
|
|
8809
8955
|
const result = await store.logHandoff(entry);
|
|
8810
8956
|
if (!result.ok) {
|
|
8811
|
-
console.log(
|
|
8957
|
+
console.log(chalk17.red(`Failed to log handoff: ${result.error}`));
|
|
8812
8958
|
process.exit(1);
|
|
8813
8959
|
}
|
|
8814
|
-
console.log(
|
|
8960
|
+
console.log(chalk17.green("\u2713 Handoff logged"));
|
|
8815
8961
|
});
|
|
8816
8962
|
governance.command("migrate").description("Migrate legacy governance files into AGD structure").option("--remove-legacy", "Archive legacy files after migration").option("--dry-run", "Show what would change without writing files").option("-b, --by <name>", "Updated by label for architecture migration").action(async (options) => {
|
|
8817
8963
|
const result = await migrateLegacyGovernance({
|
|
@@ -8820,23 +8966,23 @@ function createGovernanceCommand() {
|
|
|
8820
8966
|
dryRun: options.dryRun,
|
|
8821
8967
|
updatedBy: options.by
|
|
8822
8968
|
});
|
|
8823
|
-
console.log(
|
|
8969
|
+
console.log(chalk17.bold("\nMigration Summary"));
|
|
8824
8970
|
console.log(
|
|
8825
|
-
result.migratedArchitecture ?
|
|
8971
|
+
result.migratedArchitecture ? chalk17.green(" \u2713 Architecture migrated") : chalk17.dim(" \u25CB Architecture migration skipped")
|
|
8826
8972
|
);
|
|
8827
8973
|
console.log(
|
|
8828
|
-
result.migratedTasks ?
|
|
8974
|
+
result.migratedTasks ? chalk17.green(" \u2713 Tasks migrated") : chalk17.dim(" \u25CB Tasks migration skipped")
|
|
8829
8975
|
);
|
|
8830
8976
|
if (result.archivedLegacyFiles.length > 0) {
|
|
8831
|
-
console.log(
|
|
8977
|
+
console.log(chalk17.dim(" Archived legacy files:"));
|
|
8832
8978
|
for (const file of result.archivedLegacyFiles) {
|
|
8833
|
-
console.log(
|
|
8979
|
+
console.log(chalk17.dim(` - ${file}`));
|
|
8834
8980
|
}
|
|
8835
8981
|
}
|
|
8836
8982
|
if (result.warnings.length > 0) {
|
|
8837
|
-
console.log(
|
|
8983
|
+
console.log(chalk17.yellow("\nWarnings:"));
|
|
8838
8984
|
for (const warning of result.warnings) {
|
|
8839
|
-
console.log(
|
|
8985
|
+
console.log(chalk17.yellow(` - ${warning}`));
|
|
8840
8986
|
}
|
|
8841
8987
|
}
|
|
8842
8988
|
console.log("");
|
|
@@ -8847,7 +8993,7 @@ function createGovernanceCommand() {
|
|
|
8847
8993
|
view.init(cwd);
|
|
8848
8994
|
await view.loadFromDisk(cwd);
|
|
8849
8995
|
view.close();
|
|
8850
|
-
console.log(
|
|
8996
|
+
console.log(chalk17.green("\u2713 Governance SQLite DB initialized"));
|
|
8851
8997
|
});
|
|
8852
8998
|
return governance;
|
|
8853
8999
|
}
|
|
@@ -8859,7 +9005,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8859
9005
|
const cwd = process.cwd();
|
|
8860
9006
|
const wasInitialized = isInitialized(cwd);
|
|
8861
9007
|
if (!wasInitialized) {
|
|
8862
|
-
console.log(
|
|
9008
|
+
console.log(chalk18.blue("\nArchonDev is not initialized in this folder.\n"));
|
|
8863
9009
|
await init({ analyze: true, git: true });
|
|
8864
9010
|
}
|
|
8865
9011
|
await start({ skipGovernanceBanner: !wasInitialized });
|
|
@@ -8867,7 +9013,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8867
9013
|
program.command("login").description("Authenticate with ArchonDev").option("-p, --provider <provider>", "OAuth provider (github or google)", "github").action(async (options) => {
|
|
8868
9014
|
const provider = options.provider;
|
|
8869
9015
|
if (provider !== "github" && provider !== "google") {
|
|
8870
|
-
console.error(
|
|
9016
|
+
console.error(chalk18.red('Invalid provider. Use "github" or "google"'));
|
|
8871
9017
|
process.exit(1);
|
|
8872
9018
|
}
|
|
8873
9019
|
await login(provider);
|
|
@@ -8966,6 +9112,13 @@ preferencesCommand.command("execution-set <key> <value>").description("Set execu
|
|
|
8966
9112
|
preferencesCommand.action(async () => {
|
|
8967
9113
|
await showPreferences();
|
|
8968
9114
|
});
|
|
9115
|
+
var policyCommand = program.command("policy").description("Manage runtime policy (approval, sentinel, routing profile)");
|
|
9116
|
+
policyCommand.command("set <scope> <value>").description("Set policy value: scope in [approval|sentinel|routing]").action(async (scope, value) => {
|
|
9117
|
+
await setPolicy(scope, value);
|
|
9118
|
+
});
|
|
9119
|
+
policyCommand.action(async () => {
|
|
9120
|
+
await showPolicy();
|
|
9121
|
+
});
|
|
8969
9122
|
program.command("watch").description("Live TUI dashboard showing atoms, credits, and activity").action(async () => {
|
|
8970
9123
|
await watch();
|
|
8971
9124
|
});
|
|
@@ -9065,7 +9218,7 @@ cleanupCmd.command("check").description("Analyze workspace for bloat and mainten
|
|
|
9065
9218
|
cleanupCmd.command("run").description("Execute cleanup (archive old entries, remove stale files)").action(cleanupRun);
|
|
9066
9219
|
cleanupCmd.command("auto").description("Enable/disable automatic cleanup checks").argument("[action]", "enable, disable, or status", "status").action(async (action) => {
|
|
9067
9220
|
if (action !== "enable" && action !== "disable" && action !== "status") {
|
|
9068
|
-
console.error(
|
|
9221
|
+
console.error(chalk18.red("Invalid action. Use: enable, disable, or status"));
|
|
9069
9222
|
process.exit(1);
|
|
9070
9223
|
}
|
|
9071
9224
|
await cleanupAuto(action);
|