archondev 2.19.4 → 2.19.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-3UOMLERV.js → chunk-KDWIKBM2.js} +1 -1
- package/dist/{chunk-K3XN7PN6.js → chunk-MIT5Z5V7.js} +243 -86
- package/dist/{chunk-IKMCIWK3.js → chunk-OTODLPY4.js} +177 -104
- package/dist/{chunk-C4HVI2NJ.js → chunk-W6TYXCZA.js} +1 -1
- package/dist/{chunk-HQBF3VTN.js → chunk-X5ZZCJBQ.js} +52 -11
- package/dist/{execute-JAHXFYXL.js → execute-DBNVIJ3P.js} +3 -2
- package/dist/index.js +332 -91
- package/dist/{list-Q4HLHQJI.js → list-SKRHIZ5T.js} +3 -2
- package/dist/{parallel-QLKYSZZ3.js → parallel-KRBYFJ4O.js} +3 -2
- package/dist/{plan-7M27X3OD.js → plan-7SCZH7EA.js} +2 -1
- package/dist/{preferences-SFXRVXT3.js → preferences-4V4C7MVD.js} +3 -1
- package/package.json +1 -1
|
@@ -22,13 +22,17 @@ import {
|
|
|
22
22
|
SUPABASE_ANON_KEY,
|
|
23
23
|
SUPABASE_URL
|
|
24
24
|
} from "./chunk-M4LGRTLC.js";
|
|
25
|
+
import {
|
|
26
|
+
handleTierSetup,
|
|
27
|
+
updateUserTier
|
|
28
|
+
} from "./chunk-GBYW3YAY.js";
|
|
25
29
|
import {
|
|
26
30
|
isAuthenticated,
|
|
27
31
|
loadConfig
|
|
28
32
|
} from "./chunk-SVU7MLG6.js";
|
|
29
33
|
|
|
30
34
|
// src/cli/plan.ts
|
|
31
|
-
import
|
|
35
|
+
import chalk2 from "chalk";
|
|
32
36
|
import { existsSync } from "fs";
|
|
33
37
|
import { readFile, writeFile, mkdir, stat } from "fs/promises";
|
|
34
38
|
import { join } from "path";
|
|
@@ -767,6 +771,50 @@ var TrackedAdversarialPlanner = class {
|
|
|
767
771
|
}
|
|
768
772
|
};
|
|
769
773
|
|
|
774
|
+
// src/cli/credits-recovery.ts
|
|
775
|
+
import chalk from "chalk";
|
|
776
|
+
import readline from "readline";
|
|
777
|
+
function prompt(question) {
|
|
778
|
+
return new Promise((resolve) => {
|
|
779
|
+
const rl = readline.createInterface({
|
|
780
|
+
input: process.stdin,
|
|
781
|
+
output: process.stdout
|
|
782
|
+
});
|
|
783
|
+
rl.question(`${chalk.cyan("?")} ${question}: `, (answer) => {
|
|
784
|
+
rl.close();
|
|
785
|
+
resolve(answer.trim());
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
async function handleInsufficientCreditsRecovery(input) {
|
|
790
|
+
console.log(chalk.red("\n\u274C Insufficient credits"));
|
|
791
|
+
console.log(chalk.dim(`Your balance: $${(input.balanceCents / 100).toFixed(2)}`));
|
|
792
|
+
console.log(chalk.dim(`Estimated ${input.operationLabel} cost: $${(input.estimatedCostCents / 100).toFixed(2)}`));
|
|
793
|
+
console.log();
|
|
794
|
+
console.log(chalk.bold("Choose next step:"));
|
|
795
|
+
console.log(` ${chalk.cyan("1")}) Add credits now (open checkout)`);
|
|
796
|
+
console.log(` ${chalk.cyan("2")}) Switch to BYOK and add API key now`);
|
|
797
|
+
console.log(` ${chalk.cyan("3")}) Cancel`);
|
|
798
|
+
console.log();
|
|
799
|
+
const choice = await prompt("Enter choice (1-3)");
|
|
800
|
+
if (choice === "1") {
|
|
801
|
+
await handleTierSetup("CREDITS");
|
|
802
|
+
return "retry";
|
|
803
|
+
}
|
|
804
|
+
if (choice === "2") {
|
|
805
|
+
const switchResult = await updateUserTier("BYOK");
|
|
806
|
+
if (!switchResult.success) {
|
|
807
|
+
console.log(chalk.red(switchResult.error ?? "Failed to switch to BYOK."));
|
|
808
|
+
return "abort";
|
|
809
|
+
}
|
|
810
|
+
console.log(chalk.green("\u2713 Switched to BYOK."));
|
|
811
|
+
await handleTierSetup("BYOK");
|
|
812
|
+
return "retry";
|
|
813
|
+
}
|
|
814
|
+
console.log(chalk.dim("Operation cancelled."));
|
|
815
|
+
return "abort";
|
|
816
|
+
}
|
|
817
|
+
|
|
770
818
|
// src/cli/plan.ts
|
|
771
819
|
var ATOMS_DIR = ".archon/atoms";
|
|
772
820
|
function createPrompt() {
|
|
@@ -782,24 +830,24 @@ function createPrompt() {
|
|
|
782
830
|
};
|
|
783
831
|
}
|
|
784
832
|
async function plan(description, options) {
|
|
785
|
-
const
|
|
833
|
+
const prompt2 = createPrompt();
|
|
786
834
|
try {
|
|
787
835
|
if (!await isAuthenticated()) {
|
|
788
|
-
console.log(
|
|
789
|
-
console.log(
|
|
836
|
+
console.log(chalk2.yellow('Not authenticated. Run "archon login" first.'));
|
|
837
|
+
console.log(chalk2.dim("For local development, you can continue without authentication."));
|
|
790
838
|
}
|
|
791
839
|
const archPath = join(process.cwd(), "ARCHITECTURE.md");
|
|
792
840
|
if (!existsSync(archPath)) {
|
|
793
|
-
console.error(
|
|
841
|
+
console.error(chalk2.red('ARCHITECTURE.md not found. Run "archon init" first.'));
|
|
794
842
|
process.exit(1);
|
|
795
843
|
}
|
|
796
|
-
console.log(
|
|
844
|
+
console.log(chalk2.dim("Parsing ARCHITECTURE.md..."));
|
|
797
845
|
const parser = new ArchitectureParser(archPath);
|
|
798
846
|
const parseResult = await parser.parse();
|
|
799
847
|
if (!parseResult.success || !parseResult.schema) {
|
|
800
|
-
console.error(
|
|
848
|
+
console.error(chalk2.red("Failed to parse ARCHITECTURE.md:"));
|
|
801
849
|
for (const error of parseResult.errors) {
|
|
802
|
-
console.error(
|
|
850
|
+
console.error(chalk2.red(` - ${error.message}`));
|
|
803
851
|
}
|
|
804
852
|
process.exit(1);
|
|
805
853
|
}
|
|
@@ -807,24 +855,24 @@ async function plan(description, options) {
|
|
|
807
855
|
const references = extractReferencedFiles(description);
|
|
808
856
|
const { foundFiles, missingFiles, fileSummaries } = await loadReferencedFileSummaries(references);
|
|
809
857
|
if (references.length > 0) {
|
|
810
|
-
console.log(
|
|
858
|
+
console.log(chalk2.dim("\nReferenced inputs detected:"));
|
|
811
859
|
for (const ref of references) {
|
|
812
|
-
const status = foundFiles.includes(ref) ?
|
|
860
|
+
const status = foundFiles.includes(ref) ? chalk2.green("\u2713") : chalk2.yellow("!");
|
|
813
861
|
console.log(` ${status} ${ref}`);
|
|
814
862
|
}
|
|
815
863
|
if (missingFiles.length > 0) {
|
|
816
|
-
console.log(
|
|
864
|
+
console.log(chalk2.yellow("\nMissing referenced files:"));
|
|
817
865
|
for (const missing of missingFiles) {
|
|
818
|
-
console.log(
|
|
866
|
+
console.log(chalk2.yellow(` - ${missing}`));
|
|
819
867
|
}
|
|
820
|
-
console.log(
|
|
821
|
-
console.log(
|
|
822
|
-
console.log(
|
|
823
|
-
console.log(
|
|
824
|
-
const proceedChoice = await
|
|
868
|
+
console.log(chalk2.dim("\nHow would you like to proceed?"));
|
|
869
|
+
console.log(chalk2.dim(" 1) Cancel planning and add the missing files"));
|
|
870
|
+
console.log(chalk2.dim(" 2) Continue and mark missing files as required"));
|
|
871
|
+
console.log(chalk2.dim(" 3) Continue with default placeholders"));
|
|
872
|
+
const proceedChoice = await prompt2.ask("Choose 1/2/3 (default: 1): ");
|
|
825
873
|
const choice = proceedChoice.trim() || "1";
|
|
826
874
|
if (choice === "1") {
|
|
827
|
-
console.log(
|
|
875
|
+
console.log(chalk2.dim("Planning cancelled."));
|
|
828
876
|
return;
|
|
829
877
|
}
|
|
830
878
|
if (choice === "2") {
|
|
@@ -836,7 +884,7 @@ async function plan(description, options) {
|
|
|
836
884
|
}
|
|
837
885
|
}
|
|
838
886
|
const deliverableTarget = await promptForDeliverableTarget(
|
|
839
|
-
|
|
887
|
+
prompt2,
|
|
840
888
|
requirements,
|
|
841
889
|
references
|
|
842
890
|
);
|
|
@@ -844,9 +892,9 @@ async function plan(description, options) {
|
|
|
844
892
|
requirements.push(`Deliverables saved to: ${deliverableTarget}`);
|
|
845
893
|
}
|
|
846
894
|
if (requirements.length > 0) {
|
|
847
|
-
console.log(
|
|
895
|
+
console.log(chalk2.dim("\nDetected requirements:"));
|
|
848
896
|
requirements.forEach((req, i) => console.log(` ${i + 1}. ${req}`));
|
|
849
|
-
const confirm = await
|
|
897
|
+
const confirm = await prompt2.ask("\nUse these as acceptance criteria? (Y/n): ");
|
|
850
898
|
if (confirm.toLowerCase() === "n") {
|
|
851
899
|
requirements.length = 0;
|
|
852
900
|
}
|
|
@@ -858,7 +906,7 @@ async function plan(description, options) {
|
|
|
858
906
|
deliverableTarget: deliverableTarget ?? void 0
|
|
859
907
|
});
|
|
860
908
|
const isContentOnlyTask = classification.kind === "content";
|
|
861
|
-
const designApproved = await promptForDesignApproval(
|
|
909
|
+
const designApproved = await promptForDesignApproval(prompt2, {
|
|
862
910
|
description,
|
|
863
911
|
requirements,
|
|
864
912
|
references,
|
|
@@ -866,10 +914,10 @@ async function plan(description, options) {
|
|
|
866
914
|
classification
|
|
867
915
|
});
|
|
868
916
|
if (!designApproved) {
|
|
869
|
-
console.log(
|
|
917
|
+
console.log(chalk2.yellow("\nDesign not approved. Planning cancelled."));
|
|
870
918
|
return;
|
|
871
919
|
}
|
|
872
|
-
console.log(
|
|
920
|
+
console.log(chalk2.dim("Creating atom from description..."));
|
|
873
921
|
const atomInput = parseAtomDescription(description, options, requirements);
|
|
874
922
|
const atom = createAtom(atomInput, {
|
|
875
923
|
referencedFiles: references,
|
|
@@ -882,18 +930,18 @@ async function plan(description, options) {
|
|
|
882
930
|
});
|
|
883
931
|
const validation = validateAtom(atom);
|
|
884
932
|
if (!validation.valid) {
|
|
885
|
-
console.error(
|
|
933
|
+
console.error(chalk2.red("Invalid atom:"));
|
|
886
934
|
for (const error of validation.errors) {
|
|
887
|
-
console.error(
|
|
935
|
+
console.error(chalk2.red(` - ${error.field}: ${error.message}`));
|
|
888
936
|
}
|
|
889
937
|
process.exit(1);
|
|
890
938
|
}
|
|
891
|
-
console.log(
|
|
939
|
+
console.log(chalk2.blue(`
|
|
892
940
|
Atom created: ${atom.externalId}`));
|
|
893
|
-
console.log(
|
|
894
|
-
console.log(
|
|
941
|
+
console.log(chalk2.dim(`Title: ${atom.title}`));
|
|
942
|
+
console.log(chalk2.dim(`Acceptance Criteria: ${atom.acceptanceCriteria.length} items`));
|
|
895
943
|
if (isContentOnlyTask) {
|
|
896
|
-
console.log(
|
|
944
|
+
console.log(chalk2.blue("\nContent task detected. Creating a lightweight plan (no adversarial loop)."));
|
|
897
945
|
atom.plan = buildContentPlan({
|
|
898
946
|
description,
|
|
899
947
|
requirements,
|
|
@@ -903,13 +951,13 @@ Atom created: ${atom.externalId}`));
|
|
|
903
951
|
});
|
|
904
952
|
atom.status = "READY";
|
|
905
953
|
await saveAtom(atom);
|
|
906
|
-
console.log(
|
|
954
|
+
console.log(chalk2.green(`
|
|
907
955
|
\u2705 Atom saved: ${atom.externalId}`));
|
|
908
|
-
console.log(
|
|
909
|
-
console.log(
|
|
956
|
+
console.log(chalk2.dim(`Status: ${atom.status}`));
|
|
957
|
+
console.log(chalk2.dim(`
|
|
910
958
|
Next steps:`));
|
|
911
|
-
console.log(
|
|
912
|
-
console.log(
|
|
959
|
+
console.log(chalk2.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
960
|
+
console.log(chalk2.dim(` - View: archon show ${atom.externalId}`));
|
|
913
961
|
return;
|
|
914
962
|
}
|
|
915
963
|
let apiKey = process.env["ANTHROPIC_API_KEY"];
|
|
@@ -921,16 +969,16 @@ Next steps:`));
|
|
|
921
969
|
}
|
|
922
970
|
}
|
|
923
971
|
if (!apiKey) {
|
|
924
|
-
console.log(
|
|
925
|
-
console.log(
|
|
972
|
+
console.log(chalk2.yellow("\nNo API key configured. Skipping adversarial planning."));
|
|
973
|
+
console.log(chalk2.dim('Set ANTHROPIC_API_KEY or use "archon keys add anthropic"'));
|
|
926
974
|
await saveAtom(atom);
|
|
927
|
-
console.log(
|
|
975
|
+
console.log(chalk2.green(`
|
|
928
976
|
Atom saved: ${atom.externalId}`));
|
|
929
|
-
console.log(
|
|
977
|
+
console.log(chalk2.dim(`Next: Configure API key and run "archon plan ${atom.externalId} --continue"`));
|
|
930
978
|
return;
|
|
931
979
|
}
|
|
932
|
-
console.log(
|
|
933
|
-
console.log(
|
|
980
|
+
console.log(chalk2.blue("\nStarting adversarial planning..."));
|
|
981
|
+
console.log(chalk2.dim("Architect will generate a plan, Sentinel will validate it.\n"));
|
|
934
982
|
const config = await loadConfig();
|
|
935
983
|
let billingContext;
|
|
936
984
|
if (config.userId && config.accessToken) {
|
|
@@ -945,24 +993,36 @@ Atom saved: ${atom.externalId}`));
|
|
|
945
993
|
}
|
|
946
994
|
const planner = billingContext ? new TrackedAdversarialPlanner({ apiKey, billing: billingContext }) : new AdversarialPlanner({ apiKey });
|
|
947
995
|
if (billingContext && planner instanceof TrackedAdversarialPlanner) {
|
|
948
|
-
|
|
996
|
+
let balanceCheck = await planner.checkBalance();
|
|
997
|
+
if (balanceCheck.tier === "CREDITS") {
|
|
998
|
+
console.log(chalk2.dim(`Estimated planning cost: $${(balanceCheck.estimatedCostCents / 100).toFixed(2)} | Balance: $${(balanceCheck.balance / 100).toFixed(2)}`));
|
|
999
|
+
}
|
|
949
1000
|
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
1001
|
+
const recovery = await handleInsufficientCreditsRecovery({
|
|
1002
|
+
balanceCents: balanceCheck.balance,
|
|
1003
|
+
estimatedCostCents: balanceCheck.estimatedCostCents,
|
|
1004
|
+
operationLabel: "planning"
|
|
1005
|
+
});
|
|
1006
|
+
if (recovery === "abort") {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
balanceCheck = await planner.checkBalance();
|
|
1010
|
+
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
1011
|
+
console.log(chalk2.red("\nStill insufficient credits after recovery action."));
|
|
1012
|
+
console.log(chalk2.dim("Please add more credits with: archon credits add"));
|
|
1013
|
+
printPlanNextActions(atom.externalId, false);
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
956
1016
|
}
|
|
957
1017
|
}
|
|
958
1018
|
const planResult = await planner.planAtom(atom, parseResult.schema);
|
|
959
1019
|
if (!planResult.approved) {
|
|
960
|
-
console.log(
|
|
961
|
-
console.log(
|
|
1020
|
+
console.log(chalk2.red("\n\u274C Plan not approved after maximum iterations."));
|
|
1021
|
+
console.log(chalk2.yellow("Issues found:"));
|
|
962
1022
|
for (const iteration of planResult.iterations) {
|
|
963
1023
|
if (!iteration.validation.passed) {
|
|
964
1024
|
for (const issue of iteration.validation.issues) {
|
|
965
|
-
console.log(
|
|
1025
|
+
console.log(chalk2.yellow(` - [${issue.severity}] ${issue.message}`));
|
|
966
1026
|
}
|
|
967
1027
|
}
|
|
968
1028
|
}
|
|
@@ -974,7 +1034,7 @@ Atom saved: ${atom.externalId}`));
|
|
|
974
1034
|
)
|
|
975
1035
|
});
|
|
976
1036
|
if (shouldAutoFallback) {
|
|
977
|
-
console.log(
|
|
1037
|
+
console.log(chalk2.blue("\nTask looks content-focused. Switching to lightweight plan."));
|
|
978
1038
|
atom.plan = buildContentPlan({
|
|
979
1039
|
description,
|
|
980
1040
|
requirements,
|
|
@@ -984,19 +1044,19 @@ Atom saved: ${atom.externalId}`));
|
|
|
984
1044
|
});
|
|
985
1045
|
atom.status = "READY";
|
|
986
1046
|
await saveAtom(atom);
|
|
987
|
-
console.log(
|
|
1047
|
+
console.log(chalk2.green(`
|
|
988
1048
|
\u2705 Atom saved: ${atom.externalId}`));
|
|
989
|
-
console.log(
|
|
990
|
-
console.log(
|
|
1049
|
+
console.log(chalk2.dim(`Status: ${atom.status}`));
|
|
1050
|
+
console.log(chalk2.dim(`
|
|
991
1051
|
Next steps:`));
|
|
992
|
-
console.log(
|
|
993
|
-
console.log(
|
|
1052
|
+
console.log(chalk2.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
1053
|
+
console.log(chalk2.dim(` - View: archon show ${atom.externalId}`));
|
|
994
1054
|
return;
|
|
995
1055
|
}
|
|
996
|
-
const answer2 = await
|
|
1056
|
+
const answer2 = await prompt2.ask("\nSave as draft anyway? (y/N): ");
|
|
997
1057
|
const normalized = answer2.toLowerCase();
|
|
998
1058
|
if (normalized.includes("wrong") || normalized.includes("content") || normalized.includes("not a code")) {
|
|
999
|
-
console.log(
|
|
1059
|
+
console.log(chalk2.blue("\nReclassifying as content task and creating a lightweight plan."));
|
|
1000
1060
|
atom.plan = buildContentPlan({
|
|
1001
1061
|
description,
|
|
1002
1062
|
requirements,
|
|
@@ -1006,61 +1066,73 @@ Next steps:`));
|
|
|
1006
1066
|
});
|
|
1007
1067
|
atom.status = "READY";
|
|
1008
1068
|
await saveAtom(atom);
|
|
1009
|
-
console.log(
|
|
1069
|
+
console.log(chalk2.green(`
|
|
1010
1070
|
\u2705 Atom saved: ${atom.externalId}`));
|
|
1011
|
-
console.log(
|
|
1012
|
-
console.log(
|
|
1071
|
+
console.log(chalk2.dim(`Status: ${atom.status}`));
|
|
1072
|
+
console.log(chalk2.dim(`
|
|
1013
1073
|
Next steps:`));
|
|
1014
|
-
console.log(
|
|
1015
|
-
console.log(
|
|
1074
|
+
console.log(chalk2.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
1075
|
+
console.log(chalk2.dim(` - View: archon show ${atom.externalId}`));
|
|
1016
1076
|
return;
|
|
1017
1077
|
}
|
|
1018
1078
|
if (normalized !== "y") {
|
|
1019
|
-
console.log(
|
|
1079
|
+
console.log(chalk2.dim("Atom discarded."));
|
|
1020
1080
|
return;
|
|
1021
1081
|
}
|
|
1022
1082
|
}
|
|
1023
1083
|
if (planResult.finalPlan) {
|
|
1024
1084
|
const enrichedPlan = enforcePlanStructure(planResult.finalPlan, requirements);
|
|
1025
1085
|
planResult.finalPlan = enrichedPlan;
|
|
1026
|
-
console.log(
|
|
1086
|
+
console.log(chalk2.green("\n\u2705 Plan approved!"));
|
|
1027
1087
|
displayPlan(enrichedPlan);
|
|
1028
1088
|
} else {
|
|
1029
|
-
console.log(
|
|
1089
|
+
console.log(chalk2.yellow("\nNo approved plan available."));
|
|
1030
1090
|
}
|
|
1031
|
-
console.log(
|
|
1091
|
+
console.log(chalk2.dim(`
|
|
1032
1092
|
Token usage: ${planResult.totalUsage.inputTokens} input, ${planResult.totalUsage.outputTokens} output`));
|
|
1033
1093
|
if (planner instanceof TrackedAdversarialPlanner) {
|
|
1034
1094
|
const trackedResult = planResult;
|
|
1035
1095
|
if (trackedResult.totalCostCents && trackedResult.totalCostCents > 0) {
|
|
1036
|
-
console.log(
|
|
1096
|
+
console.log(chalk2.dim(`Credits used: $${(trackedResult.totalCostCents / 100).toFixed(4)}`));
|
|
1037
1097
|
if (trackedResult.remainingBalance !== void 0) {
|
|
1038
|
-
console.log(
|
|
1098
|
+
console.log(chalk2.dim(`Remaining balance: $${(trackedResult.remainingBalance / 100).toFixed(2)}`));
|
|
1039
1099
|
}
|
|
1040
1100
|
}
|
|
1041
1101
|
}
|
|
1042
|
-
const answer = await
|
|
1102
|
+
const answer = await prompt2.ask("\nApprove this plan? (y/N/e for edit): ");
|
|
1043
1103
|
if (answer.toLowerCase() === "e") {
|
|
1044
|
-
console.log(
|
|
1104
|
+
console.log(chalk2.yellow("Edit mode not yet implemented. Saving as draft."));
|
|
1045
1105
|
atom.status = "DRAFT";
|
|
1046
1106
|
} else if (answer.toLowerCase() !== "y") {
|
|
1047
|
-
console.log(
|
|
1107
|
+
console.log(chalk2.dim("Atom discarded."));
|
|
1048
1108
|
return;
|
|
1049
1109
|
} else {
|
|
1050
1110
|
atom.plan = planResult.finalPlan;
|
|
1051
1111
|
atom.status = "READY";
|
|
1052
1112
|
}
|
|
1053
1113
|
await saveAtom(atom);
|
|
1054
|
-
console.log(
|
|
1114
|
+
console.log(chalk2.green(`
|
|
1055
1115
|
\u2705 Atom saved: ${atom.externalId}`));
|
|
1056
|
-
console.log(
|
|
1057
|
-
console.log(
|
|
1116
|
+
console.log(chalk2.dim(`Status: ${atom.status}`));
|
|
1117
|
+
console.log(chalk2.dim(`
|
|
1058
1118
|
Next steps:`));
|
|
1059
|
-
console.log(
|
|
1060
|
-
console.log(
|
|
1119
|
+
console.log(chalk2.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
1120
|
+
console.log(chalk2.dim(` - View: archon show ${atom.externalId}`));
|
|
1121
|
+
printPlanNextActions(atom.externalId, true);
|
|
1061
1122
|
} finally {
|
|
1062
|
-
|
|
1123
|
+
prompt2.close();
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
function printPlanNextActions(atomExternalId, success) {
|
|
1127
|
+
console.log();
|
|
1128
|
+
console.log(chalk2.bold("Next best action:"));
|
|
1129
|
+
if (success) {
|
|
1130
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon execute ${atomExternalId}`)} to move this atom forward.`));
|
|
1131
|
+
} else {
|
|
1132
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon credits add")} or switch to ${chalk2.cyan("BYOK")} to continue planning.`));
|
|
1063
1133
|
}
|
|
1134
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect acceptance criteria.`));
|
|
1135
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon preferences")} to tune model routing/cost.`));
|
|
1064
1136
|
}
|
|
1065
1137
|
function parseAtomDescription(description, options, extractedCriteria = []) {
|
|
1066
1138
|
const title = deriveTitle(description);
|
|
@@ -1130,32 +1202,32 @@ function extractNumberedSteps(description) {
|
|
|
1130
1202
|
}
|
|
1131
1203
|
return steps;
|
|
1132
1204
|
}
|
|
1133
|
-
async function promptForDesignApproval(
|
|
1134
|
-
console.log(
|
|
1135
|
-
console.log(
|
|
1136
|
-
console.log(
|
|
1137
|
-
console.log(
|
|
1205
|
+
async function promptForDesignApproval(prompt2, input) {
|
|
1206
|
+
console.log(chalk2.blue("\nDesign Approval Gate"));
|
|
1207
|
+
console.log(chalk2.dim("\u2500".repeat(40)));
|
|
1208
|
+
console.log(chalk2.dim(`Task type: ${input.classification.kind} (${input.classification.confidence} confidence)`));
|
|
1209
|
+
console.log(chalk2.dim(`Title: ${deriveTitle(input.description)}`));
|
|
1138
1210
|
if (input.requirements.length > 0) {
|
|
1139
|
-
console.log(
|
|
1211
|
+
console.log(chalk2.dim("\nRequirements summary:"));
|
|
1140
1212
|
for (const req of input.requirements.slice(0, 6)) {
|
|
1141
|
-
console.log(
|
|
1213
|
+
console.log(chalk2.dim(` - ${req}`));
|
|
1142
1214
|
}
|
|
1143
1215
|
if (input.requirements.length > 6) {
|
|
1144
|
-
console.log(
|
|
1216
|
+
console.log(chalk2.dim(` - ... and ${input.requirements.length - 6} more`));
|
|
1145
1217
|
}
|
|
1146
1218
|
}
|
|
1147
1219
|
if (input.references.length > 0) {
|
|
1148
|
-
console.log(
|
|
1220
|
+
console.log(chalk2.dim("\nReferenced inputs:"));
|
|
1149
1221
|
for (const ref of input.references.slice(0, 8)) {
|
|
1150
|
-
console.log(
|
|
1222
|
+
console.log(chalk2.dim(` - ${ref}`));
|
|
1151
1223
|
}
|
|
1152
1224
|
}
|
|
1153
1225
|
if (input.deliverableTarget) {
|
|
1154
|
-
console.log(
|
|
1226
|
+
console.log(chalk2.dim(`
|
|
1155
1227
|
Deliverable target: ${input.deliverableTarget}`));
|
|
1156
1228
|
}
|
|
1157
|
-
console.log(
|
|
1158
|
-
const approval = await
|
|
1229
|
+
console.log(chalk2.dim("\nI will generate a step-by-step implementation plan from this design."));
|
|
1230
|
+
const approval = await prompt2.ask("Approve design and proceed to planning? (Y/n): ");
|
|
1159
1231
|
return approval.trim().toLowerCase() !== "n";
|
|
1160
1232
|
}
|
|
1161
1233
|
function enforcePlanStructure(plan2, requirements) {
|
|
@@ -1337,17 +1409,17 @@ async function loadReferencedFileSummaries(references) {
|
|
|
1337
1409
|
}
|
|
1338
1410
|
return { foundFiles, missingFiles, fileSummaries };
|
|
1339
1411
|
}
|
|
1340
|
-
async function promptForDeliverableTarget(
|
|
1412
|
+
async function promptForDeliverableTarget(prompt2, requirements, references) {
|
|
1341
1413
|
const mentionsResearch = requirements.some((req) => req.toLowerCase().includes("research"));
|
|
1342
1414
|
const defaultTarget = references.find((ref) => ref.toLowerCase().endsWith(".md"));
|
|
1343
1415
|
if (!mentionsResearch && !defaultTarget) {
|
|
1344
1416
|
return null;
|
|
1345
1417
|
}
|
|
1346
|
-
console.log(
|
|
1418
|
+
console.log(chalk2.dim("\nWhere should the deliverables be written?"));
|
|
1347
1419
|
if (defaultTarget) {
|
|
1348
|
-
console.log(
|
|
1420
|
+
console.log(chalk2.dim(`Press Enter to use ${defaultTarget}`));
|
|
1349
1421
|
}
|
|
1350
|
-
const answer = await
|
|
1422
|
+
const answer = await prompt2.ask("Target file or folder (leave blank to skip): ");
|
|
1351
1423
|
const trimmed = answer.trim();
|
|
1352
1424
|
if (trimmed.length === 0) {
|
|
1353
1425
|
return defaultTarget ?? null;
|
|
@@ -1366,29 +1438,29 @@ async function resolveProfileId(authId, accessToken) {
|
|
|
1366
1438
|
}
|
|
1367
1439
|
}
|
|
1368
1440
|
function displayPlan(plan2) {
|
|
1369
|
-
console.log(
|
|
1370
|
-
console.log(
|
|
1371
|
-
console.log(
|
|
1441
|
+
console.log(chalk2.bold("\n\u{1F4DD} Implementation Plan"));
|
|
1442
|
+
console.log(chalk2.dim("\u2500".repeat(40)));
|
|
1443
|
+
console.log(chalk2.bold("\nSteps:"));
|
|
1372
1444
|
plan2.steps.forEach((step, i) => {
|
|
1373
1445
|
console.log(` ${i + 1}. ${step}`);
|
|
1374
1446
|
});
|
|
1375
|
-
console.log(
|
|
1447
|
+
console.log(chalk2.bold("\nFiles to modify:"));
|
|
1376
1448
|
for (const file of plan2.files_to_modify) {
|
|
1377
1449
|
console.log(` - ${file}`);
|
|
1378
1450
|
}
|
|
1379
1451
|
if (plan2.dependencies.length > 0) {
|
|
1380
|
-
console.log(
|
|
1452
|
+
console.log(chalk2.bold("\nDependencies:"));
|
|
1381
1453
|
for (const dep of plan2.dependencies) {
|
|
1382
1454
|
console.log(` - ${dep}`);
|
|
1383
1455
|
}
|
|
1384
1456
|
}
|
|
1385
1457
|
if (plan2.risks.length > 0) {
|
|
1386
|
-
console.log(
|
|
1458
|
+
console.log(chalk2.bold("\nRisks:"));
|
|
1387
1459
|
for (const risk of plan2.risks) {
|
|
1388
|
-
console.log(
|
|
1460
|
+
console.log(chalk2.yellow(` [!] ${risk}`));
|
|
1389
1461
|
}
|
|
1390
1462
|
}
|
|
1391
|
-
console.log(
|
|
1463
|
+
console.log(chalk2.bold("\nComplexity:"), plan2.estimated_complexity);
|
|
1392
1464
|
}
|
|
1393
1465
|
async function saveAtom(atom) {
|
|
1394
1466
|
const atomsDir = join(process.cwd(), ATOMS_DIR);
|
|
@@ -1427,6 +1499,7 @@ async function listLocalAtoms() {
|
|
|
1427
1499
|
|
|
1428
1500
|
export {
|
|
1429
1501
|
UsageRecorder,
|
|
1502
|
+
handleInsufficientCreditsRecovery,
|
|
1430
1503
|
plan,
|
|
1431
1504
|
parseAtomDescription,
|
|
1432
1505
|
loadAtom,
|
|
@@ -5,8 +5,9 @@ import {
|
|
|
5
5
|
} from "./chunk-EBHHIUCB.js";
|
|
6
6
|
import {
|
|
7
7
|
UsageRecorder,
|
|
8
|
+
handleInsufficientCreditsRecovery,
|
|
8
9
|
loadAtom
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-OTODLPY4.js";
|
|
10
11
|
import {
|
|
11
12
|
transitionAtom
|
|
12
13
|
} from "./chunk-PCTP3LKJ.js";
|
|
@@ -20,6 +21,9 @@ import {
|
|
|
20
21
|
import {
|
|
21
22
|
ArchitectureParser
|
|
22
23
|
} from "./chunk-5EVHUDQX.js";
|
|
24
|
+
import {
|
|
25
|
+
KeyManager
|
|
26
|
+
} from "./chunk-RDG5BUED.js";
|
|
23
27
|
import {
|
|
24
28
|
SUPABASE_ANON_KEY,
|
|
25
29
|
SUPABASE_URL
|
|
@@ -4793,7 +4797,7 @@ function createPrompt() {
|
|
|
4793
4797
|
}
|
|
4794
4798
|
async function execute(atomId, options) {
|
|
4795
4799
|
if (options.parallel && options.parallel.length > 0) {
|
|
4796
|
-
const { parallelExecute } = await import("./parallel-
|
|
4800
|
+
const { parallelExecute } = await import("./parallel-KRBYFJ4O.js");
|
|
4797
4801
|
const allAtomIds = [atomId, ...options.parallel];
|
|
4798
4802
|
await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
|
|
4799
4803
|
return;
|
|
@@ -4808,7 +4812,12 @@ async function execute(atomId, options) {
|
|
|
4808
4812
|
console.log(chalk2.red("\n\u274C Cloud execution requires Credits tier"));
|
|
4809
4813
|
console.log(chalk2.dim("BYOK and Free tiers run locally only."));
|
|
4810
4814
|
console.log(chalk2.dim("Upgrade with: archon upgrade"));
|
|
4811
|
-
|
|
4815
|
+
const upgradeNow = await prompt.ask("Switch tier now? (y/N): ");
|
|
4816
|
+
if (upgradeNow.trim().toLowerCase() === "y") {
|
|
4817
|
+
const { showUpgradeMenu } = await import("./tier-selection-XFBM4SZ4.js");
|
|
4818
|
+
await showUpgradeMenu();
|
|
4819
|
+
}
|
|
4820
|
+
return;
|
|
4812
4821
|
}
|
|
4813
4822
|
const projectName = basename(cwd);
|
|
4814
4823
|
console.log(chalk2.dim(`Queueing cloud execution for ${atomId}...`));
|
|
@@ -4967,16 +4976,36 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
|
|
|
4967
4976
|
}
|
|
4968
4977
|
const roleOverrides = await loadRoleOverrides(cwd);
|
|
4969
4978
|
const executorConfig = roleOverrides?.executor?.model ? { model: roleOverrides.executor.model } : void 0;
|
|
4970
|
-
|
|
4979
|
+
let apiKey = process.env["ANTHROPIC_API_KEY"];
|
|
4980
|
+
if (!apiKey) {
|
|
4981
|
+
const keyManager = new KeyManager();
|
|
4982
|
+
const storedKey = await keyManager.getKey("anthropic");
|
|
4983
|
+
if (storedKey) {
|
|
4984
|
+
apiKey = storedKey;
|
|
4985
|
+
}
|
|
4986
|
+
}
|
|
4987
|
+
const executor = billingContext ? new TrackedExecutorAgent({ billing: billingContext, clientConfig: executorConfig, apiKey }) : new ExecutorAgent(executorConfig, apiKey);
|
|
4971
4988
|
if (billingContext && executor instanceof TrackedExecutorAgent) {
|
|
4972
|
-
|
|
4989
|
+
let balanceCheck = await executor.checkBalance();
|
|
4990
|
+
if (balanceCheck.tier === "CREDITS") {
|
|
4991
|
+
console.log(chalk2.dim(`Estimated execution cost: $${(balanceCheck.estimatedCostCents / 100).toFixed(2)} | Balance: $${(balanceCheck.balance / 100).toFixed(2)}`));
|
|
4992
|
+
}
|
|
4973
4993
|
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4994
|
+
const recovery = await handleInsufficientCreditsRecovery({
|
|
4995
|
+
balanceCents: balanceCheck.balance,
|
|
4996
|
+
estimatedCostCents: balanceCheck.estimatedCostCents,
|
|
4997
|
+
operationLabel: "execution"
|
|
4998
|
+
});
|
|
4999
|
+
if (recovery === "abort") {
|
|
5000
|
+
return;
|
|
5001
|
+
}
|
|
5002
|
+
balanceCheck = await executor.checkBalance();
|
|
5003
|
+
if (!balanceCheck.sufficient && balanceCheck.tier === "CREDITS") {
|
|
5004
|
+
console.log(chalk2.red("\nStill insufficient credits after recovery action."));
|
|
5005
|
+
console.log(chalk2.dim("Please add more credits with: archon credits add"));
|
|
5006
|
+
printExecuteNextActions(atom.externalId, false);
|
|
5007
|
+
return;
|
|
5008
|
+
}
|
|
4980
5009
|
}
|
|
4981
5010
|
}
|
|
4982
5011
|
const executionResult = await executor.executeAtom(atom, atom.plan, parseResult.schema, cwd);
|
|
@@ -5104,10 +5133,22 @@ Running quality gates for ${targetEnvName}...`));
|
|
|
5104
5133
|
console.log(chalk2.dim(`Atom: ${atom.externalId}`));
|
|
5105
5134
|
console.log(chalk2.dim(`Status: ${atom.status}`));
|
|
5106
5135
|
console.log(chalk2.dim(`Files changed: ${filesChanged.length}`));
|
|
5136
|
+
printExecuteNextActions(atom.externalId, true);
|
|
5107
5137
|
} finally {
|
|
5108
5138
|
prompt.close();
|
|
5109
5139
|
}
|
|
5110
5140
|
}
|
|
5141
|
+
function printExecuteNextActions(atomExternalId, success) {
|
|
5142
|
+
console.log();
|
|
5143
|
+
console.log(chalk2.bold("Next best action:"));
|
|
5144
|
+
if (success) {
|
|
5145
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon list")} to select your next atom.`));
|
|
5146
|
+
} else {
|
|
5147
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan(`archon show ${atomExternalId}`)} to inspect this atom.`));
|
|
5148
|
+
}
|
|
5149
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon credits")} to verify balance/tier.`));
|
|
5150
|
+
console.log(chalk2.dim(` \u2022 Run ${chalk2.cyan("archon preferences")} to tune model routing.`));
|
|
5151
|
+
}
|
|
5111
5152
|
async function saveAtom(atom) {
|
|
5112
5153
|
const atomsDir = join4(process.cwd(), ATOMS_DIR);
|
|
5113
5154
|
const atomFile = join4(atomsDir, `${atom.externalId}.json`);
|