archondev 2.19.2 → 2.19.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/{bug-IJCK43FK.js → bug-NZHQ6QZF.js} +1 -1
- package/dist/{chunk-QTBRLNZQ.js → chunk-3UOMLERV.js} +1 -1
- package/dist/{chunk-M6GNIN64.js → chunk-6XLWTTGJ.js} +2 -1
- package/dist/{chunk-YA562WHL.js → chunk-C4HVI2NJ.js} +1 -1
- package/dist/{chunk-OREGEFTF.js → chunk-HQBF3VTN.js} +12 -2
- package/dist/{chunk-ACFMKTDL.js → chunk-IKMCIWK3.js} +250 -3
- package/dist/{chunk-CTWVQ6F3.js → chunk-K3XN7PN6.js} +116 -31
- package/dist/{chunk-DCIIYVJW.js → chunk-XKYRHJA5.js} +36 -2
- package/dist/{chunk-KG35EHZY.js → chunk-YGDLWQBK.js} +58 -13
- package/dist/{code-review-ODLXGXNZ.js → code-review-GJVBZPZA.js} +1 -1
- package/dist/{execute-ZTJGSRBW.js → execute-JAHXFYXL.js} +2 -2
- package/dist/index.js +54 -34
- package/dist/{list-REPLUXJF.js → list-Q4HLHQJI.js} +2 -2
- package/dist/{parallel-23VQYK7H.js → parallel-QLKYSZZ3.js} +2 -2
- package/dist/{plan-HCYXLSSD.js → plan-7M27X3OD.js} +1 -1
- package/dist/{preferences-OAOZCZGR.js → preferences-SFXRVXT3.js} +6 -3
- package/dist/{review-F6DHAGDF.js → review-BXESOS5R.js} +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,7 @@ pnpm exec tsx scripts/init-governance-db.ts
|
|
|
77
77
|
| `archon credits` | View credit balance |
|
|
78
78
|
| `archon credits add` | Purchase credits |
|
|
79
79
|
| `archon credits budget` | Set monthly budget and alerts |
|
|
80
|
+
| `archon usage` | Usage by period and model (BYOK/Credits) |
|
|
80
81
|
| `archon keys add <provider>` | Add your own API key — BYOK (Bring Your Own Key) |
|
|
81
82
|
| `archon keys list` | Show configured API keys by provider |
|
|
82
83
|
| `archon preferences` | Interactive settings menu (billing, models, keys, usage) |
|
|
@@ -117,6 +118,8 @@ pnpm exec tsx scripts/init-governance-db.ts
|
|
|
117
118
|
|
|
118
119
|
**Notes:**
|
|
119
120
|
- Credits tier shows your balance and per‑model usage on startup; use `archon credits` for full details and history.
|
|
121
|
+
- Content-only requests (stories, outlines, lessons, visuals) use lightweight planning to avoid blocking.
|
|
122
|
+
- BYOK shows per‑model usage and cost by today/week/month/year in `archon preferences` → “View usage details.”
|
|
120
123
|
- You can paste multi‑line requests into interactive prompts; Archon captures them as a single response.
|
|
121
124
|
|
|
122
125
|
**Tip:** Use `archon plan --edit` to adjust title and acceptance criteria before planning.
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
analyzeProject,
|
|
5
5
|
featuresToTasks,
|
|
6
6
|
readArchitectureContext
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-YGDLWQBK.js";
|
|
8
8
|
|
|
9
9
|
// src/cli/review.ts
|
|
10
10
|
import chalk from "chalk";
|
|
@@ -593,6 +593,7 @@ async function reviewRun(options) {
|
|
|
593
593
|
spinner.stop();
|
|
594
594
|
console.log(chalk.green(`Starting AI Review`));
|
|
595
595
|
console.log(chalk.dim(`Pending tasks: ${stats.pending}`));
|
|
596
|
+
console.log(chalk.dim("Workflow: Stage 1 spec compliance \u2192 Stage 2 code quality"));
|
|
596
597
|
if (limit) {
|
|
597
598
|
console.log(chalk.dim(`Limit: ${limit}`));
|
|
598
599
|
}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
UsageRecorder,
|
|
8
8
|
loadAtom
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-IKMCIWK3.js";
|
|
10
10
|
import {
|
|
11
11
|
transitionAtom
|
|
12
12
|
} from "./chunk-PCTP3LKJ.js";
|
|
@@ -4793,7 +4793,7 @@ function createPrompt() {
|
|
|
4793
4793
|
}
|
|
4794
4794
|
async function execute(atomId, options) {
|
|
4795
4795
|
if (options.parallel && options.parallel.length > 0) {
|
|
4796
|
-
const { parallelExecute } = await import("./parallel-
|
|
4796
|
+
const { parallelExecute } = await import("./parallel-QLKYSZZ3.js");
|
|
4797
4797
|
const allAtomIds = [atomId, ...options.parallel];
|
|
4798
4798
|
await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
|
|
4799
4799
|
return;
|
|
@@ -4894,6 +4894,16 @@ Repository: ${repoUrl}`));
|
|
|
4894
4894
|
console.log(chalk2.dim(`Run "archon plan" to create a plan first.`));
|
|
4895
4895
|
process.exit(1);
|
|
4896
4896
|
}
|
|
4897
|
+
const atomContext = atom.context;
|
|
4898
|
+
const designApproved = atomContext?.["designApproved"] === true;
|
|
4899
|
+
if (!designApproved) {
|
|
4900
|
+
console.log(chalk2.yellow("\n[!] This atom does not record explicit design approval metadata."));
|
|
4901
|
+
const proceed = await prompt.ask("Proceed with execution anyway? (y/N): ");
|
|
4902
|
+
if (proceed.trim().toLowerCase() !== "y") {
|
|
4903
|
+
console.log(chalk2.dim("Execution cancelled. Re-run planning and approve design first."));
|
|
4904
|
+
return;
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4897
4907
|
const archPath = join4(cwd, "ARCHITECTURE.md");
|
|
4898
4908
|
if (!existsSync9(archPath)) {
|
|
4899
4909
|
console.error(chalk2.red("ARCHITECTURE.md not found."));
|
|
@@ -851,6 +851,24 @@ async function plan(description, options) {
|
|
|
851
851
|
requirements.length = 0;
|
|
852
852
|
}
|
|
853
853
|
}
|
|
854
|
+
const classification = classifyTaskIntent({
|
|
855
|
+
description,
|
|
856
|
+
requirements,
|
|
857
|
+
references,
|
|
858
|
+
deliverableTarget: deliverableTarget ?? void 0
|
|
859
|
+
});
|
|
860
|
+
const isContentOnlyTask = classification.kind === "content";
|
|
861
|
+
const designApproved = await promptForDesignApproval(prompt, {
|
|
862
|
+
description,
|
|
863
|
+
requirements,
|
|
864
|
+
references,
|
|
865
|
+
deliverableTarget: deliverableTarget ?? void 0,
|
|
866
|
+
classification
|
|
867
|
+
});
|
|
868
|
+
if (!designApproved) {
|
|
869
|
+
console.log(chalk.yellow("\nDesign not approved. Planning cancelled."));
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
854
872
|
console.log(chalk.dim("Creating atom from description..."));
|
|
855
873
|
const atomInput = parseAtomDescription(description, options, requirements);
|
|
856
874
|
const atom = createAtom(atomInput, {
|
|
@@ -858,7 +876,9 @@ async function plan(description, options) {
|
|
|
858
876
|
fileSummaries,
|
|
859
877
|
missingFiles,
|
|
860
878
|
requirements,
|
|
861
|
-
deliverableTarget
|
|
879
|
+
deliverableTarget,
|
|
880
|
+
designApproved,
|
|
881
|
+
designApprovalTimestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
862
882
|
});
|
|
863
883
|
const validation = validateAtom(atom);
|
|
864
884
|
if (!validation.valid) {
|
|
@@ -872,6 +892,26 @@ async function plan(description, options) {
|
|
|
872
892
|
Atom created: ${atom.externalId}`));
|
|
873
893
|
console.log(chalk.dim(`Title: ${atom.title}`));
|
|
874
894
|
console.log(chalk.dim(`Acceptance Criteria: ${atom.acceptanceCriteria.length} items`));
|
|
895
|
+
if (isContentOnlyTask) {
|
|
896
|
+
console.log(chalk.blue("\nContent task detected. Creating a lightweight plan (no adversarial loop)."));
|
|
897
|
+
atom.plan = buildContentPlan({
|
|
898
|
+
description,
|
|
899
|
+
requirements,
|
|
900
|
+
referencedFiles: references,
|
|
901
|
+
deliverableTarget,
|
|
902
|
+
missingFiles
|
|
903
|
+
});
|
|
904
|
+
atom.status = "READY";
|
|
905
|
+
await saveAtom(atom);
|
|
906
|
+
console.log(chalk.green(`
|
|
907
|
+
\u2705 Atom saved: ${atom.externalId}`));
|
|
908
|
+
console.log(chalk.dim(`Status: ${atom.status}`));
|
|
909
|
+
console.log(chalk.dim(`
|
|
910
|
+
Next steps:`));
|
|
911
|
+
console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
912
|
+
console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
875
915
|
let apiKey = process.env["ANTHROPIC_API_KEY"];
|
|
876
916
|
if (!apiKey) {
|
|
877
917
|
const keyManager = new KeyManager();
|
|
@@ -926,15 +966,65 @@ Atom saved: ${atom.externalId}`));
|
|
|
926
966
|
}
|
|
927
967
|
}
|
|
928
968
|
}
|
|
969
|
+
const shouldAutoFallback = shouldFallbackToContentPlan({
|
|
970
|
+
classification,
|
|
971
|
+
description,
|
|
972
|
+
issues: planResult.iterations.flatMap(
|
|
973
|
+
(iteration) => iteration.validation.passed ? [] : iteration.validation.issues.map((issue) => issue.message)
|
|
974
|
+
)
|
|
975
|
+
});
|
|
976
|
+
if (shouldAutoFallback) {
|
|
977
|
+
console.log(chalk.blue("\nTask looks content-focused. Switching to lightweight plan."));
|
|
978
|
+
atom.plan = buildContentPlan({
|
|
979
|
+
description,
|
|
980
|
+
requirements,
|
|
981
|
+
referencedFiles: references,
|
|
982
|
+
deliverableTarget,
|
|
983
|
+
missingFiles
|
|
984
|
+
});
|
|
985
|
+
atom.status = "READY";
|
|
986
|
+
await saveAtom(atom);
|
|
987
|
+
console.log(chalk.green(`
|
|
988
|
+
\u2705 Atom saved: ${atom.externalId}`));
|
|
989
|
+
console.log(chalk.dim(`Status: ${atom.status}`));
|
|
990
|
+
console.log(chalk.dim(`
|
|
991
|
+
Next steps:`));
|
|
992
|
+
console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
993
|
+
console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
929
996
|
const answer2 = await prompt.ask("\nSave as draft anyway? (y/N): ");
|
|
930
|
-
|
|
997
|
+
const normalized = answer2.toLowerCase();
|
|
998
|
+
if (normalized.includes("wrong") || normalized.includes("content") || normalized.includes("not a code")) {
|
|
999
|
+
console.log(chalk.blue("\nReclassifying as content task and creating a lightweight plan."));
|
|
1000
|
+
atom.plan = buildContentPlan({
|
|
1001
|
+
description,
|
|
1002
|
+
requirements,
|
|
1003
|
+
referencedFiles: references,
|
|
1004
|
+
deliverableTarget,
|
|
1005
|
+
missingFiles
|
|
1006
|
+
});
|
|
1007
|
+
atom.status = "READY";
|
|
1008
|
+
await saveAtom(atom);
|
|
1009
|
+
console.log(chalk.green(`
|
|
1010
|
+
\u2705 Atom saved: ${atom.externalId}`));
|
|
1011
|
+
console.log(chalk.dim(`Status: ${atom.status}`));
|
|
1012
|
+
console.log(chalk.dim(`
|
|
1013
|
+
Next steps:`));
|
|
1014
|
+
console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
|
|
1015
|
+
console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
if (normalized !== "y") {
|
|
931
1019
|
console.log(chalk.dim("Atom discarded."));
|
|
932
1020
|
return;
|
|
933
1021
|
}
|
|
934
1022
|
}
|
|
935
1023
|
if (planResult.finalPlan) {
|
|
1024
|
+
const enrichedPlan = enforcePlanStructure(planResult.finalPlan, requirements);
|
|
1025
|
+
planResult.finalPlan = enrichedPlan;
|
|
936
1026
|
console.log(chalk.green("\n\u2705 Plan approved!"));
|
|
937
|
-
displayPlan(
|
|
1027
|
+
displayPlan(enrichedPlan);
|
|
938
1028
|
} else {
|
|
939
1029
|
console.log(chalk.yellow("\nNo approved plan available."));
|
|
940
1030
|
}
|
|
@@ -1029,6 +1119,163 @@ function extractNumberedRequirements(description) {
|
|
|
1029
1119
|
}
|
|
1030
1120
|
return requirements;
|
|
1031
1121
|
}
|
|
1122
|
+
function extractNumberedSteps(description) {
|
|
1123
|
+
const steps = [];
|
|
1124
|
+
const lines = description.split("\n");
|
|
1125
|
+
for (const line of lines) {
|
|
1126
|
+
const match = line.match(/^\s*(\d+)[\).]\s+(.+)$/);
|
|
1127
|
+
if (match && match[2]) {
|
|
1128
|
+
steps.push(match[2].trim());
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return steps;
|
|
1132
|
+
}
|
|
1133
|
+
async function promptForDesignApproval(prompt, input) {
|
|
1134
|
+
console.log(chalk.blue("\nDesign Approval Gate"));
|
|
1135
|
+
console.log(chalk.dim("\u2500".repeat(40)));
|
|
1136
|
+
console.log(chalk.dim(`Task type: ${input.classification.kind} (${input.classification.confidence} confidence)`));
|
|
1137
|
+
console.log(chalk.dim(`Title: ${deriveTitle(input.description)}`));
|
|
1138
|
+
if (input.requirements.length > 0) {
|
|
1139
|
+
console.log(chalk.dim("\nRequirements summary:"));
|
|
1140
|
+
for (const req of input.requirements.slice(0, 6)) {
|
|
1141
|
+
console.log(chalk.dim(` - ${req}`));
|
|
1142
|
+
}
|
|
1143
|
+
if (input.requirements.length > 6) {
|
|
1144
|
+
console.log(chalk.dim(` - ... and ${input.requirements.length - 6} more`));
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
if (input.references.length > 0) {
|
|
1148
|
+
console.log(chalk.dim("\nReferenced inputs:"));
|
|
1149
|
+
for (const ref of input.references.slice(0, 8)) {
|
|
1150
|
+
console.log(chalk.dim(` - ${ref}`));
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
if (input.deliverableTarget) {
|
|
1154
|
+
console.log(chalk.dim(`
|
|
1155
|
+
Deliverable target: ${input.deliverableTarget}`));
|
|
1156
|
+
}
|
|
1157
|
+
console.log(chalk.dim("\nI will generate a step-by-step implementation plan from this design."));
|
|
1158
|
+
const approval = await prompt.ask("Approve design and proceed to planning? (Y/n): ");
|
|
1159
|
+
return approval.trim().toLowerCase() !== "n";
|
|
1160
|
+
}
|
|
1161
|
+
function enforcePlanStructure(plan2, requirements) {
|
|
1162
|
+
const normalizedSteps = plan2.steps.map((step, index) => {
|
|
1163
|
+
const trimmed = step.trim();
|
|
1164
|
+
if (/^step\s+\d+/i.test(trimmed)) {
|
|
1165
|
+
return trimmed;
|
|
1166
|
+
}
|
|
1167
|
+
return `Step ${index + 1}: ${trimmed}`;
|
|
1168
|
+
});
|
|
1169
|
+
const hasVerificationStep = normalizedSteps.some(
|
|
1170
|
+
(step) => /(verify|test|lint|build|validate|check)/i.test(step)
|
|
1171
|
+
);
|
|
1172
|
+
const hasAcceptanceStep = normalizedSteps.some(
|
|
1173
|
+
(step) => /(acceptance criteria|acceptance check|confirm criteria)/i.test(step)
|
|
1174
|
+
);
|
|
1175
|
+
if (!hasVerificationStep) {
|
|
1176
|
+
normalizedSteps.push("Step " + (normalizedSteps.length + 1) + ": Run verification commands (build/test/lint as applicable).");
|
|
1177
|
+
}
|
|
1178
|
+
if (!hasAcceptanceStep) {
|
|
1179
|
+
normalizedSteps.push(
|
|
1180
|
+
"Step " + (normalizedSteps.length + 1) + ": Confirm all acceptance criteria are satisfied before execution completion."
|
|
1181
|
+
);
|
|
1182
|
+
}
|
|
1183
|
+
const normalizedRisks = [...plan2.risks];
|
|
1184
|
+
if (!normalizedRisks.some((risk) => /scope/i.test(risk))) {
|
|
1185
|
+
normalizedRisks.push("Scope drift risk: avoid adding unrequested behavior.");
|
|
1186
|
+
}
|
|
1187
|
+
if (requirements.length > 0 && !normalizedRisks.some((risk) => /acceptance/i.test(risk))) {
|
|
1188
|
+
normalizedRisks.push("Acceptance mismatch risk: validate changes directly against requested criteria.");
|
|
1189
|
+
}
|
|
1190
|
+
return {
|
|
1191
|
+
...plan2,
|
|
1192
|
+
steps: normalizedSteps,
|
|
1193
|
+
risks: normalizedRisks
|
|
1194
|
+
};
|
|
1195
|
+
}
|
|
1196
|
+
function classifyTaskIntent(input) {
|
|
1197
|
+
const text = `${input.description}
|
|
1198
|
+
${input.requirements.join("\n")}`.toLowerCase();
|
|
1199
|
+
const signals = [];
|
|
1200
|
+
let contentScore = 0;
|
|
1201
|
+
let codeScore = 0;
|
|
1202
|
+
const contentCues = [
|
|
1203
|
+
/story|storytelling|storyboard|capsule|lesson|outline|narrative|plot|arc|character|conflict/,
|
|
1204
|
+
/illustration|visual|image|diagram|slides?|deck/,
|
|
1205
|
+
/write|draft|summarize|summarise|rewrite|edit|revise|polish/,
|
|
1206
|
+
/teach|teaching|curriculum|learning objectives?|lesson plan/
|
|
1207
|
+
];
|
|
1208
|
+
const codeCues = [
|
|
1209
|
+
/api|endpoint|server|backend|frontend|cli|database|schema|migration/,
|
|
1210
|
+
/typescript|javascript|python|go|rust|java|c\+\+|react|node/,
|
|
1211
|
+
/implement|refactor|compile|build|deploy|test|lint|ci/
|
|
1212
|
+
];
|
|
1213
|
+
for (const cue of contentCues) {
|
|
1214
|
+
if (cue.test(text)) {
|
|
1215
|
+
contentScore += 2;
|
|
1216
|
+
signals.push(`content:${cue.source}`);
|
|
1217
|
+
}
|
|
1218
|
+
}
|
|
1219
|
+
for (const cue of codeCues) {
|
|
1220
|
+
if (cue.test(text)) {
|
|
1221
|
+
codeScore += 2;
|
|
1222
|
+
signals.push(`code:${cue.source}`);
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
const references = [...input.references];
|
|
1226
|
+
if (input.deliverableTarget) references.push(input.deliverableTarget);
|
|
1227
|
+
const contentRefs = references.filter((ref) => /\.(md|markdown|txt|rtf|pdf|png|jpg|jpeg|gif|svg|webp)$/i.test(ref));
|
|
1228
|
+
const codeRefs = references.filter((ref) => /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|cpp|c|h|sql|json|yml|yaml)$/i.test(ref));
|
|
1229
|
+
if (contentRefs.length > 0 && codeRefs.length === 0) {
|
|
1230
|
+
contentScore += 2;
|
|
1231
|
+
signals.push("content:refs");
|
|
1232
|
+
}
|
|
1233
|
+
if (codeRefs.length > 0) {
|
|
1234
|
+
codeScore += 2;
|
|
1235
|
+
signals.push("code:refs");
|
|
1236
|
+
}
|
|
1237
|
+
let kind = "mixed";
|
|
1238
|
+
let confidence = "low";
|
|
1239
|
+
if (contentScore >= 4 && contentScore >= codeScore + 2) {
|
|
1240
|
+
kind = "content";
|
|
1241
|
+
confidence = contentScore >= 6 ? "high" : "medium";
|
|
1242
|
+
} else if (codeScore >= 4 && codeScore >= contentScore + 2) {
|
|
1243
|
+
kind = "code";
|
|
1244
|
+
confidence = codeScore >= 6 ? "high" : "medium";
|
|
1245
|
+
}
|
|
1246
|
+
return { kind, confidence, contentScore, codeScore, signals };
|
|
1247
|
+
}
|
|
1248
|
+
function shouldFallbackToContentPlan(input) {
|
|
1249
|
+
if (input.classification.kind === "content") return true;
|
|
1250
|
+
const text = input.description.toLowerCase();
|
|
1251
|
+
const issueText = input.issues.join(" ").toLowerCase();
|
|
1252
|
+
const contentLike = /story|storytelling|capsule|lesson|outline|storyboard|illustration|visual|image/.test(text);
|
|
1253
|
+
const engineeringBlockers = /api|pipeline|module|interfaces|schema|database|timeout|rate limit|retry|cache|rollback|tests?/.test(issueText);
|
|
1254
|
+
if (contentLike && engineeringBlockers && input.classification.contentScore >= input.classification.codeScore) {
|
|
1255
|
+
return true;
|
|
1256
|
+
}
|
|
1257
|
+
return false;
|
|
1258
|
+
}
|
|
1259
|
+
function buildContentPlan(input) {
|
|
1260
|
+
const stepsFromNumbering = extractNumberedSteps(input.description);
|
|
1261
|
+
const stepsFromRequirements = input.requirements.map((req) => `Create: ${req}`);
|
|
1262
|
+
const steps = stepsFromNumbering.length > 0 ? stepsFromNumbering : stepsFromRequirements.length > 0 ? stepsFromRequirements : ["Draft a clear outline", "Write the content", "Review and refine", "Finalize deliverable"];
|
|
1263
|
+
const files = /* @__PURE__ */ new Set();
|
|
1264
|
+
input.referencedFiles.forEach((f) => files.add(f));
|
|
1265
|
+
if (input.deliverableTarget) files.add(input.deliverableTarget);
|
|
1266
|
+
const risks = [];
|
|
1267
|
+
if (input.missingFiles.length > 0) {
|
|
1268
|
+
risks.push(`Missing inputs: ${input.missingFiles.join(", ")}`);
|
|
1269
|
+
}
|
|
1270
|
+
risks.push("Source material may be incomplete; validate against lesson content.");
|
|
1271
|
+
return {
|
|
1272
|
+
steps,
|
|
1273
|
+
files_to_modify: Array.from(files),
|
|
1274
|
+
dependencies: [],
|
|
1275
|
+
risks,
|
|
1276
|
+
estimated_complexity: steps.length > 6 ? "MEDIUM" : "LOW"
|
|
1277
|
+
};
|
|
1278
|
+
}
|
|
1032
1279
|
function extractReferencedFiles(description) {
|
|
1033
1280
|
const references = /* @__PURE__ */ new Set();
|
|
1034
1281
|
const barePattern = /\b[\w./-]+\.(md|txt|json|yaml|yml|png|jpg|jpeg|gif|svg|pdf)\b/gi;
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAuthedSupabaseClient
|
|
3
|
+
} from "./chunk-Q3GIFHIQ.js";
|
|
1
4
|
import {
|
|
2
5
|
findModel,
|
|
3
6
|
getAllActiveModels,
|
|
@@ -15,6 +18,10 @@ import {
|
|
|
15
18
|
import {
|
|
16
19
|
login
|
|
17
20
|
} from "./chunk-F4OUCZPN.js";
|
|
21
|
+
import {
|
|
22
|
+
SUPABASE_ANON_KEY,
|
|
23
|
+
SUPABASE_URL
|
|
24
|
+
} from "./chunk-M4LGRTLC.js";
|
|
18
25
|
import {
|
|
19
26
|
getApiUrl,
|
|
20
27
|
getAuthToken,
|
|
@@ -783,7 +790,7 @@ async function interactiveSettings() {
|
|
|
783
790
|
await interactiveSettings();
|
|
784
791
|
break;
|
|
785
792
|
case "4":
|
|
786
|
-
await
|
|
793
|
+
await showUsageDetails();
|
|
787
794
|
await interactiveSettings();
|
|
788
795
|
break;
|
|
789
796
|
case "5":
|
|
@@ -1083,11 +1090,12 @@ async function manageApiKeys() {
|
|
|
1083
1090
|
await addKey(provider);
|
|
1084
1091
|
}
|
|
1085
1092
|
}
|
|
1086
|
-
async function
|
|
1093
|
+
async function showUsageDetails() {
|
|
1087
1094
|
console.log(chalk.bold("\n-- Usage Details --\n"));
|
|
1088
1095
|
const spinner = ora("Loading usage data...").start();
|
|
1089
1096
|
const config = await loadConfig();
|
|
1090
1097
|
const authToken = getAuthToken(config);
|
|
1098
|
+
const authId = config.userId;
|
|
1091
1099
|
if (!authToken) {
|
|
1092
1100
|
spinner.fail("Not logged in");
|
|
1093
1101
|
return;
|
|
@@ -1103,36 +1111,112 @@ async function viewUsageDetails() {
|
|
|
1103
1111
|
return;
|
|
1104
1112
|
}
|
|
1105
1113
|
const data = await response.json();
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
|
|
1111
|
-
console.log(` Output: ${formatTokens(data.totalOutputTokens)} tokens`);
|
|
1112
|
-
console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
|
|
1113
|
-
console.log();
|
|
1114
|
-
console.log(chalk.blue("Cost:"));
|
|
1115
|
-
console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
|
|
1116
|
-
if (data.tier === "CREDITS") {
|
|
1117
|
-
const withFee = data.totalBaseCost * 1.1;
|
|
1118
|
-
console.log(` With 10% Fee: ${formatCost(withFee)}`);
|
|
1119
|
-
} else if (data.tier === "BYOK") {
|
|
1120
|
-
console.log(chalk.dim(" (Paid directly to your provider)"));
|
|
1121
|
-
}
|
|
1122
|
-
if (data.byModel && Object.keys(data.byModel).length > 0) {
|
|
1123
|
-
console.log();
|
|
1124
|
-
console.log(chalk.blue("By Model:"));
|
|
1125
|
-
for (const [model, stats] of Object.entries(data.byModel)) {
|
|
1126
|
-
const modelInfo = findModel(model);
|
|
1127
|
-
const name = modelInfo?.name ?? model;
|
|
1128
|
-
console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
|
|
1114
|
+
if (data.tier === "BYOK") {
|
|
1115
|
+
if (!authId) {
|
|
1116
|
+
console.log(chalk.yellow("Unable to resolve user ID for usage details."));
|
|
1117
|
+
return;
|
|
1129
1118
|
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1119
|
+
const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
|
|
1120
|
+
const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
|
|
1121
|
+
if (profileError || !profileRow?.id) {
|
|
1122
|
+
console.log(chalk.yellow("Unable to resolve profile for usage details."));
|
|
1123
|
+
return;
|
|
1124
|
+
}
|
|
1125
|
+
const profileId = profileRow.id;
|
|
1126
|
+
const now = /* @__PURE__ */ new Date();
|
|
1127
|
+
const yearStart = new Date(now.getFullYear(), 0, 1);
|
|
1128
|
+
const { data: usageRows, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", profileId).gte("created_at", yearStart.toISOString()).lte("created_at", now.toISOString());
|
|
1129
|
+
if (error || !usageRows) {
|
|
1130
|
+
console.log(chalk.yellow("Unable to fetch BYOK usage data."));
|
|
1131
|
+
return;
|
|
1132
|
+
}
|
|
1133
|
+
const rows = usageRows;
|
|
1134
|
+
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
1135
|
+
const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay());
|
|
1136
|
+
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
|
1137
|
+
const periods = [
|
|
1138
|
+
{ label: "Today", start: startOfToday, end: now },
|
|
1139
|
+
{ label: "Week to Date (Sun\u2013Sat)", start: startOfWeek, end: now },
|
|
1140
|
+
{ label: "Month to Date", start: startOfMonth, end: now },
|
|
1141
|
+
{ label: "Year to Date", start: yearStart, end: now }
|
|
1142
|
+
];
|
|
1143
|
+
const aggregate = (start, end) => {
|
|
1144
|
+
let totalInputTokens = 0;
|
|
1145
|
+
let totalOutputTokens = 0;
|
|
1146
|
+
let totalCost = 0;
|
|
1147
|
+
const byModelMap = /* @__PURE__ */ new Map();
|
|
1148
|
+
for (const row of rows) {
|
|
1149
|
+
const ts = new Date(row.created_at);
|
|
1150
|
+
if (ts < start || ts > end) continue;
|
|
1151
|
+
totalInputTokens += row.input_tokens;
|
|
1152
|
+
totalOutputTokens += row.output_tokens;
|
|
1153
|
+
totalCost += row.base_cost;
|
|
1154
|
+
const existing = byModelMap.get(row.model);
|
|
1155
|
+
if (existing) {
|
|
1156
|
+
existing.inputTokens += row.input_tokens;
|
|
1157
|
+
existing.outputTokens += row.output_tokens;
|
|
1158
|
+
existing.cost += row.base_cost;
|
|
1159
|
+
} else {
|
|
1160
|
+
byModelMap.set(row.model, {
|
|
1161
|
+
inputTokens: row.input_tokens,
|
|
1162
|
+
outputTokens: row.output_tokens,
|
|
1163
|
+
cost: row.base_cost
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
|
|
1168
|
+
return { totalInputTokens, totalOutputTokens, totalCost, byModel };
|
|
1169
|
+
};
|
|
1170
|
+
console.log(chalk.blue("BYOK Usage (local time):"));
|
|
1171
|
+
for (const period of periods) {
|
|
1172
|
+
const summary = aggregate(period.start, period.end);
|
|
1173
|
+
console.log();
|
|
1174
|
+
console.log(chalk.bold(`${period.label}:`));
|
|
1175
|
+
console.log(` ${period.start.toLocaleDateString()} \u2192 ${period.end.toLocaleDateString()}`);
|
|
1176
|
+
console.log(` Tokens: ${formatTokens(summary.totalInputTokens + summary.totalOutputTokens)} (in ${formatTokens(summary.totalInputTokens)} / out ${formatTokens(summary.totalOutputTokens)})`);
|
|
1177
|
+
console.log(` Cost: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
|
|
1178
|
+
if (summary.byModel.length > 0) {
|
|
1179
|
+
console.log(chalk.dim(" By Model:"));
|
|
1180
|
+
for (const model of summary.byModel) {
|
|
1181
|
+
const modelInfo = findModel(model.model);
|
|
1182
|
+
const name = modelInfo?.name ?? model.model;
|
|
1183
|
+
const tokenTotal = model.inputTokens + model.outputTokens;
|
|
1184
|
+
console.log(` ${name}: ${formatTokens(tokenTotal)} tokens (${formatCost(model.cost)})`);
|
|
1185
|
+
}
|
|
1186
|
+
} else {
|
|
1187
|
+
console.log(chalk.dim(" No usage recorded."));
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
} else {
|
|
1191
|
+
console.log(chalk.blue("Current Billing Period:"));
|
|
1192
|
+
console.log(` ${data.periodStart} to ${data.periodEnd}`);
|
|
1193
|
+
console.log();
|
|
1194
|
+
console.log(chalk.blue("Token Usage:"));
|
|
1195
|
+
console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
|
|
1196
|
+
console.log(` Output: ${formatTokens(data.totalOutputTokens)} tokens`);
|
|
1197
|
+
console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
|
|
1132
1198
|
console.log();
|
|
1133
|
-
console.log(chalk.blue("
|
|
1134
|
-
|
|
1135
|
-
|
|
1199
|
+
console.log(chalk.blue("Cost:"));
|
|
1200
|
+
console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
|
|
1201
|
+
if (data.tier === "CREDITS") {
|
|
1202
|
+
const withFee = data.totalBaseCost * 1.1;
|
|
1203
|
+
console.log(` With 10% Fee: ${formatCost(withFee)}`);
|
|
1204
|
+
}
|
|
1205
|
+
if (data.byModel && data.byModel.length > 0) {
|
|
1206
|
+
console.log();
|
|
1207
|
+
console.log(chalk.blue("By Model:"));
|
|
1208
|
+
for (const stats of data.byModel) {
|
|
1209
|
+
const modelInfo = findModel(stats.model);
|
|
1210
|
+
const name = modelInfo?.name ?? stats.model;
|
|
1211
|
+
console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
if (data.byOperation && data.byOperation.length > 0) {
|
|
1215
|
+
console.log();
|
|
1216
|
+
console.log(chalk.blue("By Operation:"));
|
|
1217
|
+
for (const stats of data.byOperation) {
|
|
1218
|
+
console.log(` ${stats.operation}: ${formatTokens(stats.tokenCount)} tokens (${formatCost(stats.cost)})`);
|
|
1219
|
+
}
|
|
1136
1220
|
}
|
|
1137
1221
|
}
|
|
1138
1222
|
} catch {
|
|
@@ -1151,5 +1235,6 @@ export {
|
|
|
1151
1235
|
setPreference,
|
|
1152
1236
|
resetPreferences,
|
|
1153
1237
|
listModels,
|
|
1154
|
-
interactiveSettings
|
|
1238
|
+
interactiveSettings,
|
|
1239
|
+
showUsageDetails
|
|
1155
1240
|
};
|
|
@@ -452,6 +452,24 @@ async function bugReport(title, options) {
|
|
|
452
452
|
}
|
|
453
453
|
const expectedBehavior = await prompt.ask(chalk.cyan("Expected behavior: "));
|
|
454
454
|
const actualBehavior = await prompt.ask(chalk.cyan("Actual behavior: "));
|
|
455
|
+
const observedEvidence = await prompt.ask(
|
|
456
|
+
chalk.cyan("Observed evidence (logs/errors/metrics): ")
|
|
457
|
+
);
|
|
458
|
+
const reproducedInput = await prompt.ask(
|
|
459
|
+
chalk.cyan("Can you reproduce this consistently? (y/N): ")
|
|
460
|
+
);
|
|
461
|
+
const reproducedConsistently = reproducedInput.trim().toLowerCase() === "y";
|
|
462
|
+
const rootCauseHypothesis = await prompt.ask(
|
|
463
|
+
chalk.cyan("Root cause hypothesis (where/why failing): ")
|
|
464
|
+
);
|
|
465
|
+
if (!reproducedConsistently) {
|
|
466
|
+
console.log(chalk.yellow("\n[!] Root-cause-first workflow recommends reproducible steps before fixing."));
|
|
467
|
+
const continueChoice = await prompt.ask("Continue creating bug anyway? (y/N): ");
|
|
468
|
+
if (continueChoice.trim().toLowerCase() !== "y") {
|
|
469
|
+
console.log(chalk.dim("Bug report cancelled."));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
455
473
|
let severity = null;
|
|
456
474
|
while (!severity) {
|
|
457
475
|
const severityInput = await prompt.ask(chalk.cyan("Severity (LOW/MEDIUM/HIGH/CRITICAL): "));
|
|
@@ -514,6 +532,7 @@ async function bugReport(title, options) {
|
|
|
514
532
|
console.log(chalk.blue("\n\u{1F4E6} Creating fix atom..."));
|
|
515
533
|
const acceptanceCriteria = [
|
|
516
534
|
`Bug ${bug.id} is fixed`,
|
|
535
|
+
"Root cause evidence and hypothesis are documented before implementation",
|
|
517
536
|
"Regression test added to prevent recurrence",
|
|
518
537
|
"Typecheck passes",
|
|
519
538
|
"All tests pass"
|
|
@@ -523,7 +542,17 @@ async function bugReport(title, options) {
|
|
|
523
542
|
}
|
|
524
543
|
const atom = createAtom({
|
|
525
544
|
title: `Fix ${bug.id}: ${bug.title}`,
|
|
526
|
-
description: buildAtomDescription(
|
|
545
|
+
description: buildAtomDescription(
|
|
546
|
+
bug.id,
|
|
547
|
+
bug.description,
|
|
548
|
+
bug.actualBehavior,
|
|
549
|
+
rcaResult,
|
|
550
|
+
{
|
|
551
|
+
observedEvidence,
|
|
552
|
+
rootCauseHypothesis,
|
|
553
|
+
reproducedConsistently
|
|
554
|
+
}
|
|
555
|
+
),
|
|
527
556
|
goals: [`Fix bug ${bug.id}`],
|
|
528
557
|
acceptanceCriteria,
|
|
529
558
|
ownershipPaths: rcaResult?.affectedFiles ?? triageResult.relatedFiles,
|
|
@@ -561,7 +590,7 @@ function formatSeverity(severity) {
|
|
|
561
590
|
return chalk.green(severity);
|
|
562
591
|
}
|
|
563
592
|
}
|
|
564
|
-
function buildAtomDescription(bugId, description, actualBehavior, rcaResult) {
|
|
593
|
+
function buildAtomDescription(bugId, description, actualBehavior, rcaResult, investigation) {
|
|
565
594
|
const parts = [
|
|
566
595
|
`Fix for ${bugId}`,
|
|
567
596
|
"",
|
|
@@ -575,6 +604,11 @@ function buildAtomDescription(bugId, description, actualBehavior, rcaResult) {
|
|
|
575
604
|
parts.push("");
|
|
576
605
|
parts.push(`**Suggested Fix:** ${rcaResult.suggestedFix}`);
|
|
577
606
|
}
|
|
607
|
+
parts.push("");
|
|
608
|
+
parts.push("**Root-Cause Investigation (Required Before Code Changes):**");
|
|
609
|
+
parts.push(`- Reproduced consistently: ${investigation.reproducedConsistently ? "yes" : "no"}`);
|
|
610
|
+
parts.push(`- Observed evidence: ${investigation.observedEvidence || "not provided"}`);
|
|
611
|
+
parts.push(`- Root cause hypothesis: ${investigation.rootCauseHypothesis || "not provided"}`);
|
|
578
612
|
return parts.join("\n");
|
|
579
613
|
}
|
|
580
614
|
async function generateRCA(bugId, title, description, actualBehavior, affectedComponents) {
|
|
@@ -523,6 +523,9 @@ var ReviewerAgent = class {
|
|
|
523
523
|
* Review a task by analyzing its associated files
|
|
524
524
|
*/
|
|
525
525
|
async reviewTask(task, context) {
|
|
526
|
+
return this.reviewTaskByStage(task, context, "quality");
|
|
527
|
+
}
|
|
528
|
+
async reviewTaskByStage(task, context, stage) {
|
|
526
529
|
const fileContents = await this.loadFilesForReview(task, context);
|
|
527
530
|
if (fileContents.length === 0) {
|
|
528
531
|
return {
|
|
@@ -538,7 +541,7 @@ var ReviewerAgent = class {
|
|
|
538
541
|
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, baseCost: 0, markedUpCost: 0 }
|
|
539
542
|
};
|
|
540
543
|
}
|
|
541
|
-
const userMessage = this.buildPrompt(task, fileContents, context);
|
|
544
|
+
const userMessage = this.buildPrompt(task, fileContents, context, stage);
|
|
542
545
|
const response = await this.client.chat(SYSTEM_PROMPT, userMessage, {
|
|
543
546
|
temperature: 0.3,
|
|
544
547
|
maxTokens: 4096
|
|
@@ -569,7 +572,7 @@ var ReviewerAgent = class {
|
|
|
569
572
|
/**
|
|
570
573
|
* Build the review prompt
|
|
571
574
|
*/
|
|
572
|
-
buildPrompt(task, files, context) {
|
|
575
|
+
buildPrompt(task, files, context, stage) {
|
|
573
576
|
const parts = [];
|
|
574
577
|
parts.push("# Review Task");
|
|
575
578
|
parts.push(`**Feature:** ${task.featureName}`);
|
|
@@ -625,8 +628,16 @@ var ReviewerAgent = class {
|
|
|
625
628
|
}
|
|
626
629
|
parts.push("# Instructions");
|
|
627
630
|
parts.push("");
|
|
628
|
-
|
|
629
|
-
|
|
631
|
+
if (stage === "spec") {
|
|
632
|
+
parts.push("Stage 1: SPEC COMPLIANCE REVIEW.");
|
|
633
|
+
parts.push("Focus strictly on whether implementation matches requested behavior and acceptance criteria.");
|
|
634
|
+
parts.push("Flag missing requirements, incorrect behavior, and unrequested scope additions.");
|
|
635
|
+
parts.push("Do not focus on style/performance unless it breaks requirements.");
|
|
636
|
+
} else {
|
|
637
|
+
parts.push("Stage 2: CODE QUALITY REVIEW (only after spec compliance).");
|
|
638
|
+
parts.push("Focus on correctness, security, maintainability, architecture boundaries, and test quality.");
|
|
639
|
+
parts.push("Do not re-open already-passed spec scope unless there is clear mismatch.");
|
|
640
|
+
}
|
|
630
641
|
parts.push("Output your review as valid JSON.");
|
|
631
642
|
return parts.join("\n");
|
|
632
643
|
}
|
|
@@ -801,14 +812,39 @@ var ReviewService = class {
|
|
|
801
812
|
architectureContent: this.architectureContent ?? void 0,
|
|
802
813
|
maxFilesToRead: this.config.maxFilesPerTask ?? 10
|
|
803
814
|
};
|
|
804
|
-
const
|
|
815
|
+
const specResult = await this.agent.reviewTaskByStage(task, context, "spec");
|
|
816
|
+
if (!specResult.passesReview) {
|
|
817
|
+
const specUpdate = {
|
|
818
|
+
status: "needs_fix",
|
|
819
|
+
passesReview: false,
|
|
820
|
+
issuesFound: specResult.issues,
|
|
821
|
+
fixPriority: specResult.fixPriority,
|
|
822
|
+
fixPlan: specResult.fixPlan ?? "Resolve spec compliance issues before quality review.",
|
|
823
|
+
architectureImpact: specResult.architectureImpact ?? void 0,
|
|
824
|
+
reviewedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
825
|
+
reviewedBy: "ai-reviewer-spec"
|
|
826
|
+
};
|
|
827
|
+
this.db.updateTask(task.id, specUpdate);
|
|
828
|
+
if (this.config.onTaskComplete) {
|
|
829
|
+
const updatedTask = this.db.getTask(task.id);
|
|
830
|
+
if (updatedTask) {
|
|
831
|
+
this.config.onTaskComplete(updatedTask, specResult);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return specResult;
|
|
835
|
+
}
|
|
836
|
+
const qualityResult = await this.agent.reviewTaskByStage(task, context, "quality");
|
|
837
|
+
const mergedResult = {
|
|
838
|
+
...qualityResult,
|
|
839
|
+
usage: mergeUsage(specResult.usage, qualityResult.usage)
|
|
840
|
+
};
|
|
805
841
|
const update = {
|
|
806
|
-
status:
|
|
807
|
-
passesReview:
|
|
808
|
-
issuesFound:
|
|
809
|
-
fixPriority:
|
|
810
|
-
fixPlan:
|
|
811
|
-
architectureImpact:
|
|
842
|
+
status: mergedResult.passesReview ? "completed" : "needs_fix",
|
|
843
|
+
passesReview: mergedResult.passesReview,
|
|
844
|
+
issuesFound: mergedResult.issues,
|
|
845
|
+
fixPriority: mergedResult.fixPriority,
|
|
846
|
+
fixPlan: mergedResult.fixPlan ?? void 0,
|
|
847
|
+
architectureImpact: mergedResult.architectureImpact ?? void 0,
|
|
812
848
|
reviewedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
813
849
|
reviewedBy: "ai-reviewer"
|
|
814
850
|
};
|
|
@@ -816,12 +852,21 @@ var ReviewService = class {
|
|
|
816
852
|
if (this.config.onTaskComplete) {
|
|
817
853
|
const updatedTask = this.db.getTask(task.id);
|
|
818
854
|
if (updatedTask) {
|
|
819
|
-
this.config.onTaskComplete(updatedTask,
|
|
855
|
+
this.config.onTaskComplete(updatedTask, mergedResult);
|
|
820
856
|
}
|
|
821
857
|
}
|
|
822
|
-
return
|
|
858
|
+
return mergedResult;
|
|
823
859
|
}
|
|
824
860
|
};
|
|
861
|
+
function mergeUsage(a, b) {
|
|
862
|
+
return {
|
|
863
|
+
inputTokens: a.inputTokens + b.inputTokens,
|
|
864
|
+
outputTokens: a.outputTokens + b.outputTokens,
|
|
865
|
+
totalTokens: a.totalTokens + b.totalTokens,
|
|
866
|
+
baseCost: a.baseCost + b.baseCost,
|
|
867
|
+
markedUpCost: a.markedUpCost + b.markedUpCost
|
|
868
|
+
};
|
|
869
|
+
}
|
|
825
870
|
|
|
826
871
|
export {
|
|
827
872
|
ReviewDatabase,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
execute
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HQBF3VTN.js";
|
|
4
4
|
import "./chunk-EBHHIUCB.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-IKMCIWK3.js";
|
|
6
6
|
import "./chunk-PCTP3LKJ.js";
|
|
7
7
|
import "./chunk-PJRQI5UN.js";
|
|
8
8
|
import "./chunk-EIEU3IIY.js";
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
} from "./chunk-O3B6BE5D.js";
|
|
8
8
|
import {
|
|
9
9
|
bugReport
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-XKYRHJA5.js";
|
|
11
11
|
import {
|
|
12
12
|
reviewAnalyze,
|
|
13
13
|
reviewExport,
|
|
@@ -19,15 +19,16 @@ import {
|
|
|
19
19
|
reviewShow,
|
|
20
20
|
reviewStatus,
|
|
21
21
|
reviewUpdate
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
} from "./chunk-6XLWTTGJ.js";
|
|
23
|
+
import "./chunk-YGDLWQBK.js";
|
|
24
24
|
import {
|
|
25
25
|
resetPreferences,
|
|
26
26
|
setExecutionPreference,
|
|
27
27
|
setPreference,
|
|
28
28
|
showExecutionPreferences,
|
|
29
|
-
showPreferences
|
|
30
|
-
|
|
29
|
+
showPreferences,
|
|
30
|
+
showUsageDetails
|
|
31
|
+
} from "./chunk-K3XN7PN6.js";
|
|
31
32
|
import {
|
|
32
33
|
a11yBadge,
|
|
33
34
|
a11yCheck,
|
|
@@ -46,13 +47,13 @@ import {
|
|
|
46
47
|
parallelRunWaves,
|
|
47
48
|
parallelSchedule,
|
|
48
49
|
parallelStatus
|
|
49
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-3UOMLERV.js";
|
|
50
51
|
import {
|
|
51
52
|
DependencyParser,
|
|
52
53
|
EnvironmentConfigLoader,
|
|
53
54
|
EnvironmentValidator,
|
|
54
55
|
execute
|
|
55
|
-
} from "./chunk-
|
|
56
|
+
} from "./chunk-HQBF3VTN.js";
|
|
56
57
|
import {
|
|
57
58
|
cloudCancel,
|
|
58
59
|
cloudLogs,
|
|
@@ -60,12 +61,12 @@ import {
|
|
|
60
61
|
} from "./chunk-EBHHIUCB.js";
|
|
61
62
|
import {
|
|
62
63
|
list
|
|
63
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-C4HVI2NJ.js";
|
|
64
65
|
import {
|
|
65
66
|
listLocalAtoms,
|
|
66
67
|
loadAtom,
|
|
67
68
|
plan
|
|
68
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-IKMCIWK3.js";
|
|
69
70
|
import "./chunk-PCTP3LKJ.js";
|
|
70
71
|
import "./chunk-PJRQI5UN.js";
|
|
71
72
|
import {
|
|
@@ -3184,7 +3185,7 @@ async function handleNewProject(cwd, _state) {
|
|
|
3184
3185
|
}
|
|
3185
3186
|
if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
|
|
3186
3187
|
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
3187
|
-
const { plan: plan2 } = await import("./plan-
|
|
3188
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3188
3189
|
await plan2(initialResponse, {});
|
|
3189
3190
|
return;
|
|
3190
3191
|
}
|
|
@@ -3208,7 +3209,7 @@ async function handleNewProject(cwd, _state) {
|
|
|
3208
3209
|
break;
|
|
3209
3210
|
case "2":
|
|
3210
3211
|
console.log(chalk6.dim("\n> Creating a task for this...\n"));
|
|
3211
|
-
const { plan: plan2 } = await import("./plan-
|
|
3212
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3212
3213
|
await plan2(initialResponse, {});
|
|
3213
3214
|
break;
|
|
3214
3215
|
case "3":
|
|
@@ -3238,7 +3239,7 @@ async function showNewProjectMenu(cwd) {
|
|
|
3238
3239
|
case "3": {
|
|
3239
3240
|
const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
|
|
3240
3241
|
if (description.trim()) {
|
|
3241
|
-
const { plan: plan2 } = await import("./plan-
|
|
3242
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3242
3243
|
await plan2(description, {});
|
|
3243
3244
|
}
|
|
3244
3245
|
break;
|
|
@@ -3304,7 +3305,7 @@ async function runExploreFlow(cwd) {
|
|
|
3304
3305
|
case "1": {
|
|
3305
3306
|
const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
|
|
3306
3307
|
if (description.trim()) {
|
|
3307
|
-
const { plan: plan2 } = await import("./plan-
|
|
3308
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3308
3309
|
await plan2(description, {});
|
|
3309
3310
|
}
|
|
3310
3311
|
break;
|
|
@@ -3566,7 +3567,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3566
3567
|
if (continueChoice) {
|
|
3567
3568
|
const description = await promptWithCommands("Describe what you want to build first", { allowMultiline: true });
|
|
3568
3569
|
if (description.trim()) {
|
|
3569
|
-
const { plan: plan2 } = await import("./plan-
|
|
3570
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3570
3571
|
await plan2(description, {});
|
|
3571
3572
|
}
|
|
3572
3573
|
}
|
|
@@ -3620,7 +3621,7 @@ async function handleAdaptExisting(cwd, state) {
|
|
|
3620
3621
|
}
|
|
3621
3622
|
if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
|
|
3622
3623
|
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
3623
|
-
const { plan: plan2 } = await import("./plan-
|
|
3624
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3624
3625
|
await plan2(response, {});
|
|
3625
3626
|
return;
|
|
3626
3627
|
}
|
|
@@ -3651,7 +3652,7 @@ async function showAdaptExistingMenu(cwd, state) {
|
|
|
3651
3652
|
case "2": {
|
|
3652
3653
|
const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
|
|
3653
3654
|
if (description.trim()) {
|
|
3654
|
-
const { plan: plan2 } = await import("./plan-
|
|
3655
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3655
3656
|
await plan2(description, {});
|
|
3656
3657
|
}
|
|
3657
3658
|
break;
|
|
@@ -3703,7 +3704,7 @@ async function analyzeAndAdapt(cwd) {
|
|
|
3703
3704
|
async function codeReviewFirst(cwd) {
|
|
3704
3705
|
console.log(chalk6.blue("\n-- Code Review Mode --\n"));
|
|
3705
3706
|
console.log(chalk6.dim("I'll analyze your code for issues without making any changes.\n"));
|
|
3706
|
-
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-
|
|
3707
|
+
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-BXESOS5R.js");
|
|
3707
3708
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
3708
3709
|
if (!existsSync6(reviewDbPath)) {
|
|
3709
3710
|
await reviewInit2();
|
|
@@ -3799,10 +3800,26 @@ async function showMainMenu() {
|
|
|
3799
3800
|
}
|
|
3800
3801
|
console.log(chalk6.dim(' (Type "upgrade" or "help" anytime)'));
|
|
3801
3802
|
console.log();
|
|
3802
|
-
const selected = await promptWithCommands("Enter choice");
|
|
3803
|
+
const selected = await promptWithCommands("Enter choice", { allowMultiline: true });
|
|
3803
3804
|
const choice = choices.find((c) => c.key === selected.toLowerCase());
|
|
3804
3805
|
if (choice) {
|
|
3805
3806
|
await choice.action();
|
|
3807
|
+
} else if (selected.trim()) {
|
|
3808
|
+
const freeform = selected.trim();
|
|
3809
|
+
const intent = detectUserIntent(freeform);
|
|
3810
|
+
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3811
|
+
console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
|
|
3812
|
+
await runExploreFlow(cwd);
|
|
3813
|
+
return;
|
|
3814
|
+
}
|
|
3815
|
+
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
3816
|
+
console.log(chalk6.dim("\n> Let me understand your project better...\n"));
|
|
3817
|
+
await runConversationalInterview(cwd, freeform);
|
|
3818
|
+
return;
|
|
3819
|
+
}
|
|
3820
|
+
console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
|
|
3821
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3822
|
+
await plan2(freeform, {});
|
|
3806
3823
|
} else {
|
|
3807
3824
|
console.log(chalk6.yellow("Invalid choice. Please try again."));
|
|
3808
3825
|
await showMainMenu();
|
|
@@ -3810,7 +3827,7 @@ async function showMainMenu() {
|
|
|
3810
3827
|
}
|
|
3811
3828
|
async function showReviewProgress(cwd) {
|
|
3812
3829
|
try {
|
|
3813
|
-
const { ReviewDatabase } = await import("./code-review-
|
|
3830
|
+
const { ReviewDatabase } = await import("./code-review-GJVBZPZA.js");
|
|
3814
3831
|
const db = new ReviewDatabase(cwd);
|
|
3815
3832
|
db.open();
|
|
3816
3833
|
const stats = db.getStats();
|
|
@@ -3827,20 +3844,20 @@ async function showReviewProgress(cwd) {
|
|
|
3827
3844
|
}
|
|
3828
3845
|
}
|
|
3829
3846
|
async function planTask() {
|
|
3830
|
-
const { plan: plan2 } = await import("./plan-
|
|
3847
|
+
const { plan: plan2 } = await import("./plan-7M27X3OD.js");
|
|
3831
3848
|
const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
|
|
3832
3849
|
if (description.trim()) {
|
|
3833
3850
|
await plan2(description, {});
|
|
3834
3851
|
}
|
|
3835
3852
|
}
|
|
3836
3853
|
async function listAtoms() {
|
|
3837
|
-
const { list: list2 } = await import("./list-
|
|
3854
|
+
const { list: list2 } = await import("./list-Q4HLHQJI.js");
|
|
3838
3855
|
await list2({});
|
|
3839
3856
|
}
|
|
3840
3857
|
async function executeNext() {
|
|
3841
|
-
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-
|
|
3858
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-7M27X3OD.js");
|
|
3842
3859
|
const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
|
|
3843
|
-
const { loadExecutionPreferences } = await import("./preferences-
|
|
3860
|
+
const { loadExecutionPreferences } = await import("./preferences-SFXRVXT3.js");
|
|
3844
3861
|
const cwd = process.cwd();
|
|
3845
3862
|
const atoms = await listLocalAtoms2();
|
|
3846
3863
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
@@ -3909,11 +3926,11 @@ async function executeNext() {
|
|
|
3909
3926
|
}
|
|
3910
3927
|
}
|
|
3911
3928
|
if (selectedMode === "parallel-cloud") {
|
|
3912
|
-
const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-
|
|
3929
|
+
const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-QLKYSZZ3.js");
|
|
3913
3930
|
await parallelExecuteCloud2(runIds);
|
|
3914
3931
|
return;
|
|
3915
3932
|
}
|
|
3916
|
-
const { parallelExecute } = await import("./parallel-
|
|
3933
|
+
const { parallelExecute } = await import("./parallel-QLKYSZZ3.js");
|
|
3917
3934
|
await parallelExecute(runIds);
|
|
3918
3935
|
return;
|
|
3919
3936
|
}
|
|
@@ -3921,14 +3938,14 @@ async function executeNext() {
|
|
|
3921
3938
|
const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
|
|
3922
3939
|
const targetId = atomId.trim() || pendingAtoms[0]?.id;
|
|
3923
3940
|
if (targetId) {
|
|
3924
|
-
const { execute: execute2 } = await import("./execute-
|
|
3941
|
+
const { execute: execute2 } = await import("./execute-JAHXFYXL.js");
|
|
3925
3942
|
await execute2(targetId, {});
|
|
3926
3943
|
} else {
|
|
3927
3944
|
console.log(chalk6.yellow("No atom to execute."));
|
|
3928
3945
|
}
|
|
3929
3946
|
}
|
|
3930
3947
|
async function reportBug() {
|
|
3931
|
-
const { bugReport: bugReport2 } = await import("./bug-
|
|
3948
|
+
const { bugReport: bugReport2 } = await import("./bug-NZHQ6QZF.js");
|
|
3932
3949
|
const title = await prompt("Bug title");
|
|
3933
3950
|
if (title.trim()) {
|
|
3934
3951
|
await bugReport2(title, {});
|
|
@@ -3939,7 +3956,7 @@ async function viewStatus() {
|
|
|
3939
3956
|
await status2();
|
|
3940
3957
|
}
|
|
3941
3958
|
async function settingsMenu() {
|
|
3942
|
-
const { interactiveSettings } = await import("./preferences-
|
|
3959
|
+
const { interactiveSettings } = await import("./preferences-SFXRVXT3.js");
|
|
3943
3960
|
await interactiveSettings();
|
|
3944
3961
|
await showMainMenu();
|
|
3945
3962
|
}
|
|
@@ -3948,7 +3965,7 @@ async function reviewCode() {
|
|
|
3948
3965
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
3949
3966
|
if (!existsSync6(reviewDbPath)) {
|
|
3950
3967
|
console.log(chalk6.dim("Code review not initialized. Starting setup...\n"));
|
|
3951
|
-
const { reviewInit: reviewInit2 } = await import("./review-
|
|
3968
|
+
const { reviewInit: reviewInit2 } = await import("./review-BXESOS5R.js");
|
|
3952
3969
|
await reviewInit2();
|
|
3953
3970
|
console.log();
|
|
3954
3971
|
}
|
|
@@ -3963,27 +3980,27 @@ async function reviewCode() {
|
|
|
3963
3980
|
const choice = await prompt("Enter choice");
|
|
3964
3981
|
switch (choice.toLowerCase()) {
|
|
3965
3982
|
case "1": {
|
|
3966
|
-
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-
|
|
3983
|
+
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-BXESOS5R.js");
|
|
3967
3984
|
await reviewAnalyze2();
|
|
3968
3985
|
break;
|
|
3969
3986
|
}
|
|
3970
3987
|
case "2": {
|
|
3971
|
-
const { reviewStatus: reviewStatus2 } = await import("./review-
|
|
3988
|
+
const { reviewStatus: reviewStatus2 } = await import("./review-BXESOS5R.js");
|
|
3972
3989
|
await reviewStatus2();
|
|
3973
3990
|
break;
|
|
3974
3991
|
}
|
|
3975
3992
|
case "3": {
|
|
3976
|
-
const { reviewNext: reviewNext2 } = await import("./review-
|
|
3993
|
+
const { reviewNext: reviewNext2 } = await import("./review-BXESOS5R.js");
|
|
3977
3994
|
await reviewNext2();
|
|
3978
3995
|
break;
|
|
3979
3996
|
}
|
|
3980
3997
|
case "4": {
|
|
3981
|
-
const { reviewList: reviewList2 } = await import("./review-
|
|
3998
|
+
const { reviewList: reviewList2 } = await import("./review-BXESOS5R.js");
|
|
3982
3999
|
await reviewList2({});
|
|
3983
4000
|
break;
|
|
3984
4001
|
}
|
|
3985
4002
|
case "5": {
|
|
3986
|
-
const { reviewRun: reviewRun2 } = await import("./review-
|
|
4003
|
+
const { reviewRun: reviewRun2 } = await import("./review-BXESOS5R.js");
|
|
3987
4004
|
await reviewRun2({ all: true });
|
|
3988
4005
|
break;
|
|
3989
4006
|
}
|
|
@@ -8243,6 +8260,9 @@ creditsCommand.command("audit").description("Show billing audit log (immutable r
|
|
|
8243
8260
|
creditsCommand.action(async () => {
|
|
8244
8261
|
await showCredits();
|
|
8245
8262
|
});
|
|
8263
|
+
program.command("usage").description("Show usage by period and model").action(async () => {
|
|
8264
|
+
await showUsageDetails();
|
|
8265
|
+
});
|
|
8246
8266
|
var preferencesCommand = program.command("preferences").description("Manage default model preferences");
|
|
8247
8267
|
preferencesCommand.command("set <key> <model>").description("Set a model preference (fast-model, thinking-model, primary-adversarial, secondary-adversarial)").action(async (key, model) => {
|
|
8248
8268
|
await setPreference(key, model);
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
parallelRunWaves,
|
|
7
7
|
parallelSchedule,
|
|
8
8
|
parallelStatus
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3UOMLERV.js";
|
|
10
10
|
import "./chunk-EBHHIUCB.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-IKMCIWK3.js";
|
|
12
12
|
import "./chunk-PCTP3LKJ.js";
|
|
13
13
|
import "./chunk-PJRQI5UN.js";
|
|
14
14
|
import "./chunk-EIEU3IIY.js";
|
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
setExecutionPreference,
|
|
7
7
|
setPreference,
|
|
8
8
|
showExecutionPreferences,
|
|
9
|
-
showPreferences
|
|
10
|
-
|
|
9
|
+
showPreferences,
|
|
10
|
+
showUsageDetails
|
|
11
|
+
} from "./chunk-K3XN7PN6.js";
|
|
12
|
+
import "./chunk-Q3GIFHIQ.js";
|
|
11
13
|
import "./chunk-UFR2LX6G.js";
|
|
12
14
|
import "./chunk-TFSHS7EN.js";
|
|
13
15
|
import "./chunk-RDG5BUED.js";
|
|
@@ -24,5 +26,6 @@ export {
|
|
|
24
26
|
setExecutionPreference,
|
|
25
27
|
setPreference,
|
|
26
28
|
showExecutionPreferences,
|
|
27
|
-
showPreferences
|
|
29
|
+
showPreferences,
|
|
30
|
+
showUsageDetails
|
|
28
31
|
};
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
reviewShow,
|
|
10
10
|
reviewStatus,
|
|
11
11
|
reviewUpdate
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-6XLWTTGJ.js";
|
|
13
|
+
import "./chunk-YGDLWQBK.js";
|
|
14
14
|
import "./chunk-EIEU3IIY.js";
|
|
15
15
|
import "./chunk-UFR2LX6G.js";
|
|
16
16
|
import "./chunk-4VNS5WPM.js";
|