archondev 2.19.20 → 2.19.23
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/bug-QYKFP77X.js +12 -0
- package/dist/{chunk-YGDLWQBK.js → chunk-2LAC2IW3.js} +1 -1
- package/dist/{chunk-PJRQI5UN.js → chunk-3MZOEZUH.js} +1 -1
- package/dist/{chunk-O3B6BE5D.js → chunk-6URKZ7NB.js} +1 -1
- package/dist/{chunk-XKYRHJA5.js → chunk-77S6ZEVT.js} +2 -2
- package/dist/{chunk-UFR2LX6G.js → chunk-7C6JELBL.js} +25 -16
- package/dist/{chunk-PCTP3LKJ.js → chunk-DFDEEMQU.js} +1 -1
- package/dist/{chunk-6XLWTTGJ.js → chunk-DRWP34CI.js} +1 -1
- package/dist/{chunk-EIEU3IIY.js → chunk-F7R3QKHP.js} +6 -6
- package/dist/{chunk-PSUBO3TR.js → chunk-I2ORQAMH.js} +5 -5
- package/dist/{chunk-LWNFP7BL.js → chunk-JOID4CDJ.js} +6 -6
- package/dist/{chunk-MIT5Z5V7.js → chunk-KOD52FHX.js} +7 -7
- package/dist/{chunk-RWNRCLN5.js → chunk-QIGRZP5P.js} +1 -1
- package/dist/chunk-RS3FR4UB.js +169 -0
- package/dist/{chunk-6KE53F2W.js → chunk-WQIXCLK4.js} +1 -1
- package/dist/{code-review-GJVBZPZA.js → code-review-JUMR2TQM.js} +3 -3
- package/dist/{execute-3IUO33KY.js → execute-SGRPEDGM.js} +6 -6
- package/dist/{geo-HRG7M7YX.js → geo-KXVALNSF.js} +4 -4
- package/dist/index.js +795 -854
- package/dist/{interviewer-BWM5SNOE.js → interviewer-FACOJSBN.js} +2 -2
- package/dist/{list-P5H2N6WT.js → list-2PHO34IY.js} +6 -6
- package/dist/{models-UTFGCHAY.js → models-D4NV2MVH.js} +1 -1
- package/dist/{parallel-DBPSYNE4.js → parallel-RCMUYXE2.js} +6 -6
- package/dist/{plan-W4WQY7BR.js → plan-PJI6MCS3.js} +5 -5
- package/dist/{preferences-4V4C7MVD.js → preferences-AGIZD5E5.js} +2 -2
- package/dist/{review-BXESOS5R.js → review-7BBVCF7H.js} +4 -4
- package/dist/show-N7E3I6EF.js +19 -0
- package/package.json +2 -1
- package/dist/bug-NZHQ6QZF.js +0 -12
package/dist/index.js
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
a11yBadge,
|
|
4
|
+
a11yCheck,
|
|
5
|
+
a11yFix,
|
|
6
|
+
a11yPreDeploy
|
|
7
|
+
} from "./chunk-FWLLGLD5.js";
|
|
2
8
|
import {
|
|
3
9
|
createSeoCommand
|
|
4
10
|
} from "./chunk-JF7JCK6H.js";
|
|
5
11
|
import {
|
|
6
12
|
createGeoCommand
|
|
7
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-6URKZ7NB.js";
|
|
14
|
+
import {
|
|
15
|
+
show
|
|
16
|
+
} from "./chunk-RS3FR4UB.js";
|
|
8
17
|
import {
|
|
9
18
|
bugReport
|
|
10
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-77S6ZEVT.js";
|
|
11
20
|
import {
|
|
12
21
|
reviewAnalyze,
|
|
13
22
|
reviewExport,
|
|
@@ -19,8 +28,9 @@ import {
|
|
|
19
28
|
reviewShow,
|
|
20
29
|
reviewStatus,
|
|
21
30
|
reviewUpdate
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import "./chunk-
|
|
31
|
+
} from "./chunk-DRWP34CI.js";
|
|
32
|
+
import "./chunk-2LAC2IW3.js";
|
|
33
|
+
import "./chunk-3ASILTFB.js";
|
|
24
34
|
import {
|
|
25
35
|
resetPreferences,
|
|
26
36
|
setExecutionPreference,
|
|
@@ -28,14 +38,7 @@ import {
|
|
|
28
38
|
showExecutionPreferences,
|
|
29
39
|
showPreferences,
|
|
30
40
|
showUsageDetails
|
|
31
|
-
} from "./chunk-
|
|
32
|
-
import {
|
|
33
|
-
a11yBadge,
|
|
34
|
-
a11yCheck,
|
|
35
|
-
a11yFix,
|
|
36
|
-
a11yPreDeploy
|
|
37
|
-
} from "./chunk-FWLLGLD5.js";
|
|
38
|
-
import "./chunk-3ASILTFB.js";
|
|
41
|
+
} from "./chunk-KOD52FHX.js";
|
|
39
42
|
import {
|
|
40
43
|
init,
|
|
41
44
|
isInitialized
|
|
@@ -47,13 +50,13 @@ import {
|
|
|
47
50
|
parallelRunWaves,
|
|
48
51
|
parallelSchedule,
|
|
49
52
|
parallelStatus
|
|
50
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-QIGRZP5P.js";
|
|
51
54
|
import {
|
|
52
55
|
DependencyParser,
|
|
53
56
|
EnvironmentConfigLoader,
|
|
54
57
|
EnvironmentValidator,
|
|
55
58
|
execute
|
|
56
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-JOID4CDJ.js";
|
|
57
60
|
import {
|
|
58
61
|
cloudCancel,
|
|
59
62
|
cloudLogs,
|
|
@@ -61,26 +64,28 @@ import {
|
|
|
61
64
|
} from "./chunk-EBHHIUCB.js";
|
|
62
65
|
import {
|
|
63
66
|
list
|
|
64
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-WQIXCLK4.js";
|
|
65
68
|
import {
|
|
66
69
|
listLocalAtoms,
|
|
67
70
|
loadAtom,
|
|
68
71
|
plan
|
|
69
|
-
} from "./chunk-
|
|
70
|
-
import "./chunk-
|
|
71
|
-
import "./chunk-
|
|
72
|
+
} from "./chunk-I2ORQAMH.js";
|
|
73
|
+
import "./chunk-DFDEEMQU.js";
|
|
74
|
+
import "./chunk-3MZOEZUH.js";
|
|
72
75
|
import {
|
|
73
76
|
err,
|
|
74
77
|
ok,
|
|
75
78
|
sleep
|
|
76
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-F7R3QKHP.js";
|
|
77
80
|
import {
|
|
78
81
|
createAuthedSupabaseClient
|
|
79
82
|
} from "./chunk-Q3GIFHIQ.js";
|
|
80
83
|
import {
|
|
81
84
|
ArchitectureParser
|
|
82
85
|
} from "./chunk-5EVHUDQX.js";
|
|
83
|
-
import
|
|
86
|
+
import {
|
|
87
|
+
findModel
|
|
88
|
+
} from "./chunk-7C6JELBL.js";
|
|
84
89
|
import {
|
|
85
90
|
addKey,
|
|
86
91
|
listKeys,
|
|
@@ -113,7 +118,7 @@ import "./chunk-4VNS5WPM.js";
|
|
|
113
118
|
|
|
114
119
|
// src/cli/index.ts
|
|
115
120
|
import { Command as Command3 } from "commander";
|
|
116
|
-
import
|
|
121
|
+
import chalk17 from "chalk";
|
|
117
122
|
import "dotenv/config";
|
|
118
123
|
|
|
119
124
|
// src/cli/terminal-compat.ts
|
|
@@ -194,170 +199,8 @@ async function saveAtomEnvironmentState(atomId, cwd, state) {
|
|
|
194
199
|
await writeFile(stateFile, JSON.stringify(state, null, 2));
|
|
195
200
|
}
|
|
196
201
|
|
|
197
|
-
// src/cli/show.ts
|
|
198
|
-
import chalk2 from "chalk";
|
|
199
|
-
var STATUS_COLORS = {
|
|
200
|
-
DRAFT: chalk2.gray,
|
|
201
|
-
READY: chalk2.blue,
|
|
202
|
-
IN_PROGRESS: chalk2.yellow,
|
|
203
|
-
TESTING: chalk2.cyan,
|
|
204
|
-
DONE: chalk2.green,
|
|
205
|
-
FAILED: chalk2.red,
|
|
206
|
-
BLOCKED: chalk2.magenta
|
|
207
|
-
};
|
|
208
|
-
async function show(atomId) {
|
|
209
|
-
const atom = await loadAtom(atomId);
|
|
210
|
-
if (!atom) {
|
|
211
|
-
console.error(chalk2.red(`Atom ${atomId} not found.`));
|
|
212
|
-
console.log(chalk2.dim('Use "archon list" to see available atoms.'));
|
|
213
|
-
process.exit(1);
|
|
214
|
-
}
|
|
215
|
-
const colorFn = STATUS_COLORS[atom.status] ?? chalk2.white;
|
|
216
|
-
console.log("");
|
|
217
|
-
console.log(chalk2.bold(`Atom: ${atom.externalId}`));
|
|
218
|
-
console.log(chalk2.dim("\u2550".repeat(60)));
|
|
219
|
-
console.log("");
|
|
220
|
-
console.log(chalk2.bold("Title:"), atom.title);
|
|
221
|
-
if (atom.description) {
|
|
222
|
-
console.log(chalk2.bold("Description:"), atom.description);
|
|
223
|
-
}
|
|
224
|
-
console.log(chalk2.bold("Status:"), colorFn(atom.status));
|
|
225
|
-
console.log(chalk2.bold("Priority:"), atom.priority);
|
|
226
|
-
console.log(chalk2.bold("Created:"), formatDateTime(atom.createdAt));
|
|
227
|
-
console.log(chalk2.bold("Updated:"), formatDateTime(atom.updatedAt));
|
|
228
|
-
if (atom.goals && atom.goals.length > 0) {
|
|
229
|
-
console.log("");
|
|
230
|
-
console.log(chalk2.bold("Goals:"));
|
|
231
|
-
for (const goal of atom.goals) {
|
|
232
|
-
console.log(` \u2022 ${goal}`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (atom.acceptanceCriteria && atom.acceptanceCriteria.length > 0) {
|
|
236
|
-
console.log("");
|
|
237
|
-
console.log(chalk2.bold("Acceptance Criteria:"));
|
|
238
|
-
for (let i = 0; i < atom.acceptanceCriteria.length; i++) {
|
|
239
|
-
console.log(` ${i + 1}. ${atom.acceptanceCriteria[i]}`);
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
if (atom.tags && atom.tags.length > 0) {
|
|
243
|
-
console.log("");
|
|
244
|
-
console.log(chalk2.bold("Tags:"), atom.tags.join(", "));
|
|
245
|
-
}
|
|
246
|
-
if (atom.plan) {
|
|
247
|
-
console.log("");
|
|
248
|
-
console.log(chalk2.bold("Implementation Plan:"));
|
|
249
|
-
console.log(chalk2.dim("\u2500".repeat(40)));
|
|
250
|
-
console.log(chalk2.bold("Steps:"));
|
|
251
|
-
for (let i = 0; i < atom.plan.steps.length; i++) {
|
|
252
|
-
console.log(` ${i + 1}. ${atom.plan.steps[i]}`);
|
|
253
|
-
}
|
|
254
|
-
if (atom.plan.files_to_modify.length > 0) {
|
|
255
|
-
console.log("");
|
|
256
|
-
console.log(chalk2.bold("Files to modify:"));
|
|
257
|
-
for (const file of atom.plan.files_to_modify) {
|
|
258
|
-
console.log(` \u2022 ${file}`);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (atom.plan.dependencies.length > 0) {
|
|
262
|
-
console.log("");
|
|
263
|
-
console.log(chalk2.bold("Dependencies:"));
|
|
264
|
-
for (const dep of atom.plan.dependencies) {
|
|
265
|
-
console.log(` \u2022 ${dep}`);
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
if (atom.plan.risks.length > 0) {
|
|
269
|
-
console.log("");
|
|
270
|
-
console.log(chalk2.bold("Risks:"));
|
|
271
|
-
for (const risk of atom.plan.risks) {
|
|
272
|
-
console.log(chalk2.yellow(` [!] ${risk}`));
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
console.log("");
|
|
276
|
-
console.log(chalk2.bold("Estimated Complexity:"), atom.plan.estimated_complexity);
|
|
277
|
-
}
|
|
278
|
-
if (atom.status === "FAILED" && atom.errorMessage) {
|
|
279
|
-
console.log("");
|
|
280
|
-
console.log(chalk2.bold("Error:"));
|
|
281
|
-
console.log(chalk2.red(` ${atom.errorMessage}`));
|
|
282
|
-
}
|
|
283
|
-
if (atom.retryCount > 0) {
|
|
284
|
-
console.log("");
|
|
285
|
-
console.log(chalk2.bold("Retry Count:"), chalk2.yellow(String(atom.retryCount)));
|
|
286
|
-
}
|
|
287
|
-
if (atom.ownershipPaths && atom.ownershipPaths.length > 0) {
|
|
288
|
-
console.log("");
|
|
289
|
-
console.log(chalk2.bold("Ownership Paths:"));
|
|
290
|
-
for (const path2 of atom.ownershipPaths) {
|
|
291
|
-
console.log(` \u2022 ${path2}`);
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
if (atom.diffContract) {
|
|
295
|
-
console.log("");
|
|
296
|
-
console.log(chalk2.bold("Diff Contract:"));
|
|
297
|
-
if (atom.diffContract.allowed_paths.length > 0) {
|
|
298
|
-
console.log(chalk2.dim(" Allowed paths:"));
|
|
299
|
-
for (const path2 of atom.diffContract.allowed_paths) {
|
|
300
|
-
console.log(` \u2713 ${path2}`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (atom.diffContract.forbidden_paths.length > 0) {
|
|
304
|
-
console.log(chalk2.dim(" Forbidden paths:"));
|
|
305
|
-
for (const path2 of atom.diffContract.forbidden_paths) {
|
|
306
|
-
console.log(chalk2.red(` \u2717 ${path2}`));
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
if (atom.context && Object.keys(atom.context).length > 0) {
|
|
311
|
-
console.log("");
|
|
312
|
-
console.log(chalk2.bold("Context:"));
|
|
313
|
-
if (atom.context.relevantFiles && atom.context.relevantFiles.length > 0) {
|
|
314
|
-
console.log(chalk2.dim(" Relevant files:"));
|
|
315
|
-
for (const file of atom.context.relevantFiles) {
|
|
316
|
-
console.log(` \u2022 ${file}`);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (atom.context.recentLearnings && atom.context.recentLearnings.length > 0) {
|
|
320
|
-
console.log(chalk2.dim(" Recent learnings:"));
|
|
321
|
-
for (const learning of atom.context.recentLearnings) {
|
|
322
|
-
console.log(` \u2022 ${learning}`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
console.log("");
|
|
327
|
-
console.log(chalk2.dim("\u2500".repeat(60)));
|
|
328
|
-
console.log(chalk2.bold("Next Steps:"));
|
|
329
|
-
switch (atom.status) {
|
|
330
|
-
case "DRAFT":
|
|
331
|
-
console.log(chalk2.dim(` Run "archon plan ${atom.externalId} --continue" to finalize the plan`));
|
|
332
|
-
break;
|
|
333
|
-
case "READY":
|
|
334
|
-
console.log(chalk2.dim(` Run "archon execute ${atom.externalId}" to implement`));
|
|
335
|
-
break;
|
|
336
|
-
case "IN_PROGRESS":
|
|
337
|
-
console.log(chalk2.dim(" Execution is in progress..."));
|
|
338
|
-
break;
|
|
339
|
-
case "TESTING":
|
|
340
|
-
console.log(chalk2.dim(" Waiting for quality gates to complete..."));
|
|
341
|
-
break;
|
|
342
|
-
case "DONE":
|
|
343
|
-
console.log(chalk2.green(" \u2713 Atom completed successfully!"));
|
|
344
|
-
break;
|
|
345
|
-
case "FAILED":
|
|
346
|
-
console.log(chalk2.dim(` Review the error and run "archon execute ${atom.externalId}" to retry`));
|
|
347
|
-
break;
|
|
348
|
-
case "BLOCKED":
|
|
349
|
-
console.log(chalk2.dim(" This atom is blocked. Manual intervention required."));
|
|
350
|
-
break;
|
|
351
|
-
}
|
|
352
|
-
console.log("");
|
|
353
|
-
}
|
|
354
|
-
function formatDateTime(date) {
|
|
355
|
-
const d = typeof date === "string" ? new Date(date) : date;
|
|
356
|
-
return d.toLocaleString();
|
|
357
|
-
}
|
|
358
|
-
|
|
359
202
|
// src/cli/start.ts
|
|
360
|
-
import
|
|
203
|
+
import chalk5 from "chalk";
|
|
361
204
|
import readline from "readline";
|
|
362
205
|
import { existsSync as existsSync6, readFileSync as readFileSync3, readdirSync as readdirSync3, appendFileSync } from "fs";
|
|
363
206
|
import { join as join6 } from "path";
|
|
@@ -464,7 +307,7 @@ var ContextManager = class _ContextManager {
|
|
|
464
307
|
};
|
|
465
308
|
|
|
466
309
|
// src/cli/cleanup.ts
|
|
467
|
-
import
|
|
310
|
+
import chalk2 from "chalk";
|
|
468
311
|
import { existsSync as existsSync3, readdirSync, statSync } from "fs";
|
|
469
312
|
import { readFile as readFile3, writeFile as writeFile3, mkdir as mkdir2, unlink, readdir, stat } from "fs/promises";
|
|
470
313
|
import { join as join3 } from "path";
|
|
@@ -643,7 +486,7 @@ async function cleanupCheck() {
|
|
|
643
486
|
const config = await loadCleanupConfig(cwd);
|
|
644
487
|
const progressMaxKb = config?.progressMaxKb ?? DEFAULT_THRESHOLDS.progressMaxKb;
|
|
645
488
|
const archonDirMaxMb = config?.archonDirMaxMb ?? DEFAULT_THRESHOLDS.archonDirMaxMb;
|
|
646
|
-
console.log(
|
|
489
|
+
console.log(chalk2.blue("\n\u{1F50D} Analyzing workspace for maintenance needs...\n"));
|
|
647
490
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
648
491
|
if (existsSync3(progressPath)) {
|
|
649
492
|
const size = statSync(progressPath).size;
|
|
@@ -716,12 +559,12 @@ async function cleanupCheck() {
|
|
|
716
559
|
});
|
|
717
560
|
}
|
|
718
561
|
}
|
|
719
|
-
console.log(
|
|
562
|
+
console.log(chalk2.bold("Workspace Analysis Summary\n"));
|
|
720
563
|
console.log("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
|
|
721
564
|
console.log("\u2502 Item \u2502 Size \u2502 Status \u2502");
|
|
722
565
|
console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
|
|
723
566
|
for (const result of results) {
|
|
724
|
-
const statusIcon = result.status === "critical" ?
|
|
567
|
+
const statusIcon = result.status === "critical" ? chalk2.red("\u2717") : result.status === "warn" ? chalk2.yellow("!") : chalk2.green("\u2713");
|
|
725
568
|
const name = result.name.padEnd(23);
|
|
726
569
|
const size = result.sizeFormatted.padEnd(14);
|
|
727
570
|
console.log(`\u2502 ${name} \u2502 ${size} \u2502 ${statusIcon} \u2502`);
|
|
@@ -730,13 +573,13 @@ async function cleanupCheck() {
|
|
|
730
573
|
console.log();
|
|
731
574
|
const recommendations = results.filter((r) => r.recommendation && r.status !== "ok");
|
|
732
575
|
if (recommendations.length > 0) {
|
|
733
|
-
console.log(
|
|
576
|
+
console.log(chalk2.yellow("Recommendations:\n"));
|
|
734
577
|
for (const rec of recommendations) {
|
|
735
|
-
console.log(` ${
|
|
578
|
+
console.log(` ${chalk2.dim("\u2022")} ${rec.name}: ${rec.recommendation}`);
|
|
736
579
|
}
|
|
737
580
|
console.log();
|
|
738
581
|
} else {
|
|
739
|
-
console.log(
|
|
582
|
+
console.log(chalk2.green("\u2713 Workspace is in good shape!\n"));
|
|
740
583
|
}
|
|
741
584
|
}
|
|
742
585
|
async function cleanupRun() {
|
|
@@ -747,7 +590,7 @@ async function cleanupRun() {
|
|
|
747
590
|
const progressArchiveDays = config?.progressArchiveDays ?? DEFAULT_THRESHOLDS.progressArchiveDays;
|
|
748
591
|
const cacheRetentionDays = config?.cacheRetentionDays ?? DEFAULT_THRESHOLDS.cacheRetentionDays;
|
|
749
592
|
const cloudLogRetentionDays = config?.cloudLogRetentionDays ?? DEFAULT_THRESHOLDS.cloudLogRetentionDays;
|
|
750
|
-
console.log(
|
|
593
|
+
console.log(chalk2.blue("\n\u{1F9F9} Running workspace cleanup...\n"));
|
|
751
594
|
const progressPath = join3(cwd, PROGRESS_FILE);
|
|
752
595
|
if (existsSync3(progressPath)) {
|
|
753
596
|
const content = await readFile3(progressPath, "utf-8");
|
|
@@ -793,7 +636,7 @@ async function cleanupRun() {
|
|
|
793
636
|
spaceSavedFormatted: "N/A"
|
|
794
637
|
});
|
|
795
638
|
} catch {
|
|
796
|
-
console.log(
|
|
639
|
+
console.log(chalk2.yellow(` Could not remove worktree: ${worktree}`));
|
|
797
640
|
}
|
|
798
641
|
}
|
|
799
642
|
const cachePath = join3(cwd, CACHE_DIR);
|
|
@@ -839,18 +682,18 @@ async function cleanupRun() {
|
|
|
839
682
|
}
|
|
840
683
|
}
|
|
841
684
|
if (results.length === 0) {
|
|
842
|
-
console.log(
|
|
685
|
+
console.log(chalk2.green("\u2713 Nothing to clean up!\n"));
|
|
843
686
|
return;
|
|
844
687
|
}
|
|
845
|
-
console.log(
|
|
688
|
+
console.log(chalk2.bold("Cleanup Results\n"));
|
|
846
689
|
for (const result of results) {
|
|
847
|
-
console.log(` ${
|
|
690
|
+
console.log(` ${chalk2.green("\u2713")} ${result.name}: ${result.action}`);
|
|
848
691
|
if (result.spaceSaved > 0) {
|
|
849
|
-
console.log(
|
|
692
|
+
console.log(chalk2.dim(` Space saved: ${result.spaceSavedFormatted}`));
|
|
850
693
|
}
|
|
851
694
|
}
|
|
852
695
|
console.log();
|
|
853
|
-
console.log(
|
|
696
|
+
console.log(chalk2.green(`\u2713 Total space saved: ${formatBytes(totalSaved)}
|
|
854
697
|
`));
|
|
855
698
|
}
|
|
856
699
|
async function cleanupAuto(action) {
|
|
@@ -858,20 +701,20 @@ async function cleanupAuto(action) {
|
|
|
858
701
|
const config = await loadCleanupConfig(cwd);
|
|
859
702
|
if (action === "status") {
|
|
860
703
|
const enabled = config?.autoEnabled ?? false;
|
|
861
|
-
console.log(
|
|
704
|
+
console.log(chalk2.blue("\n\u{1F527} Auto Cleanup Settings\n"));
|
|
862
705
|
console.log(
|
|
863
|
-
` Status: ${enabled ?
|
|
706
|
+
` Status: ${enabled ? chalk2.green("Enabled") : chalk2.dim("Disabled")}`
|
|
864
707
|
);
|
|
865
708
|
console.log(
|
|
866
|
-
|
|
709
|
+
chalk2.dim(
|
|
867
710
|
` Progress archive threshold: ${config?.progressArchiveDays ?? 30} days`
|
|
868
711
|
)
|
|
869
712
|
);
|
|
870
713
|
console.log(
|
|
871
|
-
|
|
714
|
+
chalk2.dim(` Cache retention: ${config?.cacheRetentionDays ?? 7} days`)
|
|
872
715
|
);
|
|
873
716
|
console.log(
|
|
874
|
-
|
|
717
|
+
chalk2.dim(
|
|
875
718
|
` Cloud log retention: ${config?.cloudLogRetentionDays ?? 30} days`
|
|
876
719
|
)
|
|
877
720
|
);
|
|
@@ -886,14 +729,14 @@ async function cleanupAuto(action) {
|
|
|
886
729
|
};
|
|
887
730
|
await saveCleanupConfig(cwd, newConfig);
|
|
888
731
|
if (action === "enable") {
|
|
889
|
-
console.log(
|
|
732
|
+
console.log(chalk2.green("\n\u2713 Auto cleanup enabled"));
|
|
890
733
|
console.log(
|
|
891
|
-
|
|
734
|
+
chalk2.dim(
|
|
892
735
|
' Cleanup check will run on "archon start" and warn if action needed\n'
|
|
893
736
|
)
|
|
894
737
|
);
|
|
895
738
|
} else {
|
|
896
|
-
console.log(
|
|
739
|
+
console.log(chalk2.green("\n\u2713 Auto cleanup disabled\n"));
|
|
897
740
|
}
|
|
898
741
|
}
|
|
899
742
|
async function shouldRunAutoCleanup(cwd) {
|
|
@@ -927,7 +770,7 @@ async function runAutoCleanupCheck(cwd) {
|
|
|
927
770
|
}
|
|
928
771
|
|
|
929
772
|
// src/cli/update-check.ts
|
|
930
|
-
import
|
|
773
|
+
import chalk3 from "chalk";
|
|
931
774
|
import { readFileSync, existsSync as existsSync4 } from "fs";
|
|
932
775
|
import { join as join4, dirname as dirname3 } from "path";
|
|
933
776
|
import { fileURLToPath } from "url";
|
|
@@ -1019,10 +862,10 @@ async function checkForUpdates() {
|
|
|
1019
862
|
function displayUpdateBanner(result) {
|
|
1020
863
|
if (!result.hasUpdate) return;
|
|
1021
864
|
console.log();
|
|
1022
|
-
console.log(
|
|
1023
|
-
console.log(
|
|
1024
|
-
console.log(
|
|
1025
|
-
console.log(
|
|
865
|
+
console.log(chalk3.yellow("\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
866
|
+
console.log(chalk3.yellow("\u2502") + chalk3.bold(" Update available! ") + chalk3.dim(`${result.currentVersion} \u2192 `) + chalk3.green(result.latestVersion) + chalk3.yellow(" \u2502"));
|
|
867
|
+
console.log(chalk3.yellow("\u2502") + chalk3.dim(` Run: ${result.updateCommand}`) + chalk3.yellow(" \u2502"));
|
|
868
|
+
console.log(chalk3.yellow("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
1026
869
|
console.log();
|
|
1027
870
|
}
|
|
1028
871
|
function startBackgroundUpdateCheck() {
|
|
@@ -1030,16 +873,24 @@ function startBackgroundUpdateCheck() {
|
|
|
1030
873
|
}
|
|
1031
874
|
|
|
1032
875
|
// src/cli/logo.ts
|
|
1033
|
-
import
|
|
876
|
+
import chalk4 from "chalk";
|
|
1034
877
|
var ARCHON_LOGO_MINI = `
|
|
1035
878
|
\u2584\u2588\u2580\u2588\u2584
|
|
1036
879
|
\u2588\u2588\u2580\u2588\u2580\u2588\u2588
|
|
1037
880
|
\u2588\u2591\u2591\u2588\u2591\u2591\u2588
|
|
1038
881
|
\u2588\u2588\u2588\u2588\u2588\u2588
|
|
1039
882
|
`;
|
|
883
|
+
var ARCHON_LOGO_SAFE = `
|
|
884
|
+
/\\
|
|
885
|
+
/__\\
|
|
886
|
+
/ /\\ \\
|
|
887
|
+
/ / \\ \\
|
|
888
|
+
\\/____\\/
|
|
889
|
+
`;
|
|
1040
890
|
function displayBrandedHeader() {
|
|
1041
891
|
if (process.env["ARCHON_TERMINAL_SAFE_MODE"] === "1") {
|
|
1042
892
|
console.log();
|
|
893
|
+
console.log(ARCHON_LOGO_SAFE);
|
|
1043
894
|
console.log("ArchonDev");
|
|
1044
895
|
console.log("AI-Powered Development Governance");
|
|
1045
896
|
console.log("----------------------------------------");
|
|
@@ -1047,10 +898,10 @@ function displayBrandedHeader() {
|
|
|
1047
898
|
return;
|
|
1048
899
|
}
|
|
1049
900
|
console.log();
|
|
1050
|
-
console.log(
|
|
1051
|
-
console.log(
|
|
1052
|
-
console.log(
|
|
1053
|
-
console.log(
|
|
901
|
+
console.log(chalk4.hex("#374F4E")(ARCHON_LOGO_MINI));
|
|
902
|
+
console.log(chalk4.bold.hex("#374F4E")(" ArchonDev"));
|
|
903
|
+
console.log(chalk4.hex("#AA8552")(" AI-Powered Development Governance"));
|
|
904
|
+
console.log(chalk4.hex("#374F4E")("\u2500".repeat(40)));
|
|
1054
905
|
console.log();
|
|
1055
906
|
}
|
|
1056
907
|
|
|
@@ -2763,6 +2614,13 @@ function detectWebProject(cwd) {
|
|
|
2763
2614
|
}
|
|
2764
2615
|
|
|
2765
2616
|
// src/cli/start.ts
|
|
2617
|
+
var PAID_TIER_DEFAULT_CHAT_MODEL = "gemini-3.1-pro-preview";
|
|
2618
|
+
function uiText(rich, plain) {
|
|
2619
|
+
return isTerminalSafeMode() ? plain : rich;
|
|
2620
|
+
}
|
|
2621
|
+
function uiSeparator() {
|
|
2622
|
+
return isTerminalSafeMode() ? "-".repeat(40) : "\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501";
|
|
2623
|
+
}
|
|
2766
2624
|
async function start(options = {}) {
|
|
2767
2625
|
const cwd = process.cwd();
|
|
2768
2626
|
displayBrandedHeader();
|
|
@@ -2770,21 +2628,21 @@ async function start(options = {}) {
|
|
|
2770
2628
|
let config = await loadConfig();
|
|
2771
2629
|
let token = getAuthToken(config);
|
|
2772
2630
|
if (!token) {
|
|
2773
|
-
console.log(
|
|
2774
|
-
console.log(
|
|
2631
|
+
console.log(chalk5.bold("Welcome to ArchonDev!\n"));
|
|
2632
|
+
console.log(chalk5.dim("Let's get you set up. First, we need to create your account.\n"));
|
|
2775
2633
|
await login();
|
|
2776
2634
|
console.log();
|
|
2777
2635
|
config = await loadConfig();
|
|
2778
2636
|
token = getAuthToken(config);
|
|
2779
2637
|
if (!token) {
|
|
2780
|
-
console.log(
|
|
2638
|
+
console.log(chalk5.yellow("Login is required to continue. Run `archon` again when ready."));
|
|
2781
2639
|
return;
|
|
2782
2640
|
}
|
|
2783
2641
|
}
|
|
2784
2642
|
if (!config.tier || config.tier === "FREE") {
|
|
2785
2643
|
const isFirstRun = !existsSync6(join6(cwd, ".archon")) && resolveArchitecturePath(cwd).path === null;
|
|
2786
2644
|
if (isFirstRun && !config.tierConfirmed) {
|
|
2787
|
-
console.log(
|
|
2645
|
+
console.log(chalk5.bold("How would you like to use ArchonDev?\n"));
|
|
2788
2646
|
const selection = await promptTierSelection();
|
|
2789
2647
|
if (selection && !selection.skipped) {
|
|
2790
2648
|
const updateResult2 = await updateUserTier(selection.tier);
|
|
@@ -2792,7 +2650,7 @@ async function start(options = {}) {
|
|
|
2792
2650
|
config.tier = selection.tier;
|
|
2793
2651
|
config.tierConfirmed = true;
|
|
2794
2652
|
await saveConfig(config);
|
|
2795
|
-
console.log(
|
|
2653
|
+
console.log(chalk5.green(`
|
|
2796
2654
|
\u2713 Tier set to ${formatTierName(selection.tier)}
|
|
2797
2655
|
`));
|
|
2798
2656
|
await handleTierSetup(selection.tier);
|
|
@@ -2800,23 +2658,28 @@ async function start(options = {}) {
|
|
|
2800
2658
|
} else {
|
|
2801
2659
|
config.tierConfirmed = true;
|
|
2802
2660
|
await saveConfig(config);
|
|
2803
|
-
console.log(
|
|
2661
|
+
console.log(chalk5.dim("Using Free tier. You can upgrade anytime with `archon upgrade`\n"));
|
|
2804
2662
|
}
|
|
2805
2663
|
}
|
|
2806
2664
|
}
|
|
2807
2665
|
if (config.email) {
|
|
2808
|
-
console.log(
|
|
2666
|
+
console.log(chalk5.dim(`Logged in as: ${config.email}`));
|
|
2809
2667
|
}
|
|
2810
2668
|
const currentTier = config.tier || "FREE";
|
|
2811
2669
|
const tierDisplay = formatTierName(currentTier);
|
|
2812
|
-
console.log(
|
|
2670
|
+
console.log(chalk5.dim(`Tier: `) + tierDisplay);
|
|
2671
|
+
const startupChatModel = await resolveStartupChatModel(currentTier, config.accessToken, config.userId);
|
|
2672
|
+
if (currentTier !== "FREE") {
|
|
2673
|
+
console.log(chalk5.dim(`Chat model: ${formatChatModelDisplay(startupChatModel)}`));
|
|
2674
|
+
console.log(chalk5.dim("Change model: archon preferences"));
|
|
2675
|
+
}
|
|
2813
2676
|
if (currentTier === "FREE") {
|
|
2814
2677
|
console.log();
|
|
2815
|
-
console.log(
|
|
2816
|
-
console.log(
|
|
2817
|
-
console.log(
|
|
2818
|
-
console.log(
|
|
2819
|
-
console.log(
|
|
2678
|
+
console.log(chalk5.yellow("\u26A0\uFE0F FREE TIER: Limited usage. Upgrade options:"));
|
|
2679
|
+
console.log(chalk5.dim(" \u2022 ") + chalk5.bold("BYOK (FREE)") + chalk5.dim(" - Unlimited usage with your own API keys"));
|
|
2680
|
+
console.log(chalk5.dim(" \u2022 ") + chalk5.bold("Managed Plan") + chalk5.dim(" - Just 10% fee on AI costs, zero setup"));
|
|
2681
|
+
console.log(chalk5.cyan("\u2192 Run ") + chalk5.bold("'archon upgrade'") + chalk5.cyan(" to unlock unlimited access"));
|
|
2682
|
+
console.log(chalk5.dim("\u2192 Model preferences: archon preferences"));
|
|
2820
2683
|
}
|
|
2821
2684
|
if (currentTier === "CREDITS" && config.accessToken) {
|
|
2822
2685
|
try {
|
|
@@ -2838,41 +2701,41 @@ async function start(options = {}) {
|
|
|
2838
2701
|
}
|
|
2839
2702
|
if (usageStats) {
|
|
2840
2703
|
console.log();
|
|
2841
|
-
console.log(
|
|
2842
|
-
console.log(
|
|
2843
|
-
const balanceColor = usageStats.balance < 1 ?
|
|
2704
|
+
console.log(chalk5.bold(uiText("\u{1F4B0} Credits Balance", "Credits Balance")));
|
|
2705
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2706
|
+
const balanceColor = usageStats.balance < 1 ? chalk5.red : usageStats.balance < 5 ? chalk5.yellow : chalk5.green;
|
|
2844
2707
|
console.log(` Balance: ${balanceColor(`$${usageStats.balance.toFixed(2)}`)}`);
|
|
2845
2708
|
if (usageStats.periodStart) {
|
|
2846
2709
|
const periodDate = new Date(usageStats.periodStart);
|
|
2847
2710
|
const formatted = isNaN(periodDate.getTime()) ? usageStats.periodStart : periodDate.toLocaleDateString();
|
|
2848
2711
|
const label = usageStats.periodSource === "credit_purchase" ? `Since last top-up (${formatted})` : usageStats.periodSource === "month" ? `Since ${formatted}` : `Period start: ${formatted}`;
|
|
2849
|
-
console.log(
|
|
2712
|
+
console.log(chalk5.dim(` ${label}`));
|
|
2850
2713
|
}
|
|
2851
2714
|
if (usageStats.usedThisPeriod > 0) {
|
|
2852
|
-
console.log(` Used since last top-up: ${
|
|
2715
|
+
console.log(` Used since last top-up: ${chalk5.dim(`$${usageStats.usedThisPeriod.toFixed(2)}`)}`);
|
|
2853
2716
|
} else {
|
|
2854
|
-
console.log(
|
|
2717
|
+
console.log(chalk5.dim(" No usage recorded since last top-up."));
|
|
2855
2718
|
}
|
|
2856
2719
|
console.log();
|
|
2857
|
-
console.log(
|
|
2720
|
+
console.log(chalk5.dim(" Model Usage:"));
|
|
2858
2721
|
if (usageStats.byModel && usageStats.byModel.length > 0) {
|
|
2859
2722
|
for (const model of usageStats.byModel) {
|
|
2860
2723
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2861
|
-
console.log(
|
|
2724
|
+
console.log(chalk5.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2862
2725
|
}
|
|
2863
2726
|
} else {
|
|
2864
|
-
console.log(
|
|
2727
|
+
console.log(chalk5.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2865
2728
|
}
|
|
2866
|
-
console.log(
|
|
2729
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2867
2730
|
if (usageStatsUnavailable) {
|
|
2868
|
-
console.log(
|
|
2731
|
+
console.log(chalk5.dim("Usage details may be delayed. Run `archon credits` to refresh."));
|
|
2869
2732
|
}
|
|
2870
2733
|
if (usageStats.balance < 5) {
|
|
2871
|
-
console.log(
|
|
2734
|
+
console.log(chalk5.yellow(`\u26A0\uFE0F Low balance! Add credits: `) + chalk5.bold(`archon credits add`));
|
|
2872
2735
|
} else {
|
|
2873
|
-
console.log(
|
|
2736
|
+
console.log(chalk5.dim(`Add credits: archon credits add`));
|
|
2874
2737
|
}
|
|
2875
|
-
console.log(
|
|
2738
|
+
console.log(chalk5.dim(`View details: archon credits | Switch tier: archon upgrade | Models: archon preferences`));
|
|
2876
2739
|
if (usageStats.balance <= 0) {
|
|
2877
2740
|
const topUpNow = await promptYesNo("Balance is $0. Add credits now?", true);
|
|
2878
2741
|
if (topUpNow) {
|
|
@@ -2896,39 +2759,39 @@ async function start(options = {}) {
|
|
|
2896
2759
|
};
|
|
2897
2760
|
}
|
|
2898
2761
|
console.log();
|
|
2899
|
-
console.log(
|
|
2900
|
-
console.log(
|
|
2762
|
+
console.log(chalk5.bold(uiText("\u{1F4CA} BYOK Usage", "BYOK Usage")));
|
|
2763
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2901
2764
|
if (usageStats.periodStart) {
|
|
2902
2765
|
const periodStart = new Date(usageStats.periodStart);
|
|
2903
2766
|
const periodEnd = usageStats.periodEnd ? new Date(usageStats.periodEnd) : null;
|
|
2904
2767
|
const formattedStart = isNaN(periodStart.getTime()) ? usageStats.periodStart : periodStart.toLocaleDateString();
|
|
2905
2768
|
const formattedEnd = periodEnd && !isNaN(periodEnd.getTime()) ? periodEnd.toLocaleDateString() : void 0;
|
|
2906
2769
|
if (formattedEnd) {
|
|
2907
|
-
console.log(
|
|
2770
|
+
console.log(chalk5.dim(` Period: ${formattedStart} \u2192 ${formattedEnd}`));
|
|
2908
2771
|
} else {
|
|
2909
|
-
console.log(
|
|
2772
|
+
console.log(chalk5.dim(` Period start: ${formattedStart}`));
|
|
2910
2773
|
}
|
|
2911
2774
|
} else {
|
|
2912
|
-
console.log(
|
|
2775
|
+
console.log(chalk5.dim(" Period: Current month to date"));
|
|
2913
2776
|
}
|
|
2914
2777
|
const totalTokens = usageStats.totalInputTokens + usageStats.totalOutputTokens;
|
|
2915
|
-
console.log(` Tokens: ${
|
|
2916
|
-
console.log(` Estimated provider spend: ${
|
|
2778
|
+
console.log(` Tokens: ${chalk5.dim(totalTokens.toLocaleString())}`);
|
|
2779
|
+
console.log(` Estimated provider spend: ${chalk5.dim(`$${usageStats.totalBaseCost.toFixed(4)}`)}`);
|
|
2917
2780
|
console.log();
|
|
2918
|
-
console.log(
|
|
2781
|
+
console.log(chalk5.dim(" Model Usage:"));
|
|
2919
2782
|
if (usageStats.byModel.length > 0) {
|
|
2920
2783
|
for (const model of usageStats.byModel) {
|
|
2921
2784
|
const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
|
|
2922
|
-
console.log(
|
|
2785
|
+
console.log(chalk5.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
|
|
2923
2786
|
}
|
|
2924
2787
|
} else {
|
|
2925
|
-
console.log(
|
|
2788
|
+
console.log(chalk5.dim(` ${"No usage yet".padEnd(34)} $0.0000`));
|
|
2926
2789
|
}
|
|
2927
|
-
console.log(
|
|
2790
|
+
console.log(chalk5.dim(uiSeparator()));
|
|
2928
2791
|
if (usageStatsUnavailable) {
|
|
2929
|
-
console.log(
|
|
2792
|
+
console.log(chalk5.dim("Usage details may be delayed. Run `archon usage` to refresh."));
|
|
2930
2793
|
}
|
|
2931
|
-
console.log(
|
|
2794
|
+
console.log(chalk5.dim("View details: archon usage | Models: archon preferences | Switch tier: archon upgrade"));
|
|
2932
2795
|
} catch {
|
|
2933
2796
|
}
|
|
2934
2797
|
}
|
|
@@ -2937,11 +2800,11 @@ async function start(options = {}) {
|
|
|
2937
2800
|
const hasKeys = await keyManager.hasAnyKey();
|
|
2938
2801
|
if (!hasKeys) {
|
|
2939
2802
|
console.log();
|
|
2940
|
-
console.log(
|
|
2941
|
-
console.log(
|
|
2942
|
-
console.log(` ${
|
|
2943
|
-
console.log(` ${
|
|
2944
|
-
console.log(` ${
|
|
2803
|
+
console.log(chalk5.yellow("\u26A0\uFE0F BYOK MODE: No API keys configured!"));
|
|
2804
|
+
console.log(chalk5.dim("You need at least one API key to use ArchonDev with BYOK.\n"));
|
|
2805
|
+
console.log(` ${chalk5.cyan("1")}) Add an API key now`);
|
|
2806
|
+
console.log(` ${chalk5.cyan("2")}) Switch to Managed Plan (no keys needed)`);
|
|
2807
|
+
console.log(` ${chalk5.cyan("3")}) Continue on Free tier`);
|
|
2945
2808
|
console.log();
|
|
2946
2809
|
const choice = await promptWithCommands("What would you like to do?", { allowMultiline: true });
|
|
2947
2810
|
switch (choice) {
|
|
@@ -2955,7 +2818,7 @@ async function start(options = {}) {
|
|
|
2955
2818
|
if (result.success) {
|
|
2956
2819
|
config.tier = "CREDITS";
|
|
2957
2820
|
await saveConfig(config);
|
|
2958
|
-
console.log(
|
|
2821
|
+
console.log(chalk5.green("\u2713 Switched to Managed Plan"));
|
|
2959
2822
|
const { handleTierSetup: setupCredits } = await import("./tier-selection-XFBM4SZ4.js");
|
|
2960
2823
|
await setupCredits("CREDITS");
|
|
2961
2824
|
}
|
|
@@ -2966,11 +2829,11 @@ async function start(options = {}) {
|
|
|
2966
2829
|
if (downgradeResult.success) {
|
|
2967
2830
|
config.tier = "FREE";
|
|
2968
2831
|
await saveConfig(config);
|
|
2969
|
-
console.log(
|
|
2832
|
+
console.log(chalk5.dim("Switched to Free tier."));
|
|
2970
2833
|
}
|
|
2971
2834
|
break;
|
|
2972
2835
|
default:
|
|
2973
|
-
console.log(
|
|
2836
|
+
console.log(chalk5.dim("Continuing without keys. Some features may not work."));
|
|
2974
2837
|
}
|
|
2975
2838
|
}
|
|
2976
2839
|
}
|
|
@@ -2981,7 +2844,7 @@ async function start(options = {}) {
|
|
|
2981
2844
|
}
|
|
2982
2845
|
const projectState = detectProjectState(cwd);
|
|
2983
2846
|
if (!projectState.hasArchitecture) {
|
|
2984
|
-
console.log(
|
|
2847
|
+
console.log(chalk5.dim("No project initialized in this folder.\n"));
|
|
2985
2848
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
2986
2849
|
await init2({ analyze: true, git: true });
|
|
2987
2850
|
console.log();
|
|
@@ -2995,20 +2858,20 @@ async function start(options = {}) {
|
|
|
2995
2858
|
const contextManager = new ContextManager();
|
|
2996
2859
|
const pendingAtomsData = await contextManager.getPendingAtomsData(cwd);
|
|
2997
2860
|
if (pendingAtomsData && pendingAtomsData.atoms.length > 0) {
|
|
2998
|
-
console.log(
|
|
2861
|
+
console.log(chalk5.yellow("[!] Previous session had pending atoms:\n"));
|
|
2999
2862
|
for (const atomId of pendingAtomsData.atoms) {
|
|
3000
|
-
console.log(
|
|
2863
|
+
console.log(chalk5.dim(` \u2022 ${atomId}`));
|
|
3001
2864
|
}
|
|
3002
2865
|
console.log();
|
|
3003
2866
|
const resume = await promptYesNo("Resume with these atoms?", true);
|
|
3004
2867
|
if (resume) {
|
|
3005
|
-
console.log(
|
|
2868
|
+
console.log(chalk5.green("\n\u2713 Resuming with pending atoms...\n"));
|
|
3006
2869
|
await contextManager.clearPendingAtoms(cwd);
|
|
3007
2870
|
} else {
|
|
3008
2871
|
const clear = await promptYesNo("Clear pending atoms?", false);
|
|
3009
2872
|
if (clear) {
|
|
3010
2873
|
await contextManager.clearPendingAtoms(cwd);
|
|
3011
|
-
console.log(
|
|
2874
|
+
console.log(chalk5.dim("Cleared pending atoms.\n"));
|
|
3012
2875
|
}
|
|
3013
2876
|
}
|
|
3014
2877
|
}
|
|
@@ -3029,6 +2892,44 @@ function formatTierName(tier) {
|
|
|
3029
2892
|
return tier;
|
|
3030
2893
|
}
|
|
3031
2894
|
}
|
|
2895
|
+
function getTierDefaultChatModel(tier) {
|
|
2896
|
+
switch (tier) {
|
|
2897
|
+
case "BYOK":
|
|
2898
|
+
case "CREDITS":
|
|
2899
|
+
case "CLAUDE_SUBSCRIPTION":
|
|
2900
|
+
return PAID_TIER_DEFAULT_CHAT_MODEL;
|
|
2901
|
+
case "FREE":
|
|
2902
|
+
default:
|
|
2903
|
+
return "gpt-5-nano";
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
function formatChatModelDisplay(modelId) {
|
|
2907
|
+
if (modelId === PAID_TIER_DEFAULT_CHAT_MODEL) {
|
|
2908
|
+
return "Gemini 3.1 Pro (gemini-3.1-pro-preview)";
|
|
2909
|
+
}
|
|
2910
|
+
const model = findModel(modelId);
|
|
2911
|
+
return `${model?.name ?? modelId} (${modelId})`;
|
|
2912
|
+
}
|
|
2913
|
+
async function resolveStartupChatModel(tier, accessToken, existingAuthId) {
|
|
2914
|
+
const fallbackModel = getTierDefaultChatModel(tier);
|
|
2915
|
+
if (!accessToken || tier === "FREE") {
|
|
2916
|
+
return fallbackModel;
|
|
2917
|
+
}
|
|
2918
|
+
const authId = await resolveAuthIdFromToken(accessToken, existingAuthId);
|
|
2919
|
+
if (!authId) {
|
|
2920
|
+
return fallbackModel;
|
|
2921
|
+
}
|
|
2922
|
+
try {
|
|
2923
|
+
const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-XDIWFFPN.js");
|
|
2924
|
+
const { createAuthedSupabaseClient: createAuthedSupabaseClient2 } = await import("./client-PHW2C2HB.js");
|
|
2925
|
+
const supabase = createAuthedSupabaseClient2(SUPABASE_URL2, SUPABASE_ANON_KEY2, accessToken);
|
|
2926
|
+
const { data: rawProfile } = await supabase.from("user_profiles").select("pref_reasoning_model").eq("auth_id", authId).single();
|
|
2927
|
+
const profile = rawProfile;
|
|
2928
|
+
return profile?.pref_reasoning_model ?? fallbackModel;
|
|
2929
|
+
} catch {
|
|
2930
|
+
return fallbackModel;
|
|
2931
|
+
}
|
|
2932
|
+
}
|
|
3032
2933
|
async function resolveAuthIdFromToken(accessToken, existingAuthId) {
|
|
3033
2934
|
if (existingAuthId) return existingAuthId;
|
|
3034
2935
|
try {
|
|
@@ -3137,18 +3038,18 @@ async function fetchCreditsUsageStatsFromSupabase(accessToken, authId) {
|
|
|
3137
3038
|
}
|
|
3138
3039
|
}
|
|
3139
3040
|
function displayGovernanceStatus(status2) {
|
|
3140
|
-
console.log(
|
|
3041
|
+
console.log(chalk5.dim("Governance Status:"));
|
|
3141
3042
|
if (status2.hasArchitecture) {
|
|
3142
|
-
console.log(
|
|
3043
|
+
console.log(chalk5.green(" \u2713") + ` ARCHITECTURE.md (${status2.posture} posture)`);
|
|
3143
3044
|
if (status2.invariantsCount > 0) {
|
|
3144
|
-
console.log(
|
|
3045
|
+
console.log(chalk5.green(" \u2713") + ` ${status2.invariantsCount} invariants`);
|
|
3145
3046
|
}
|
|
3146
3047
|
if (status2.protectedPathsCount > 0) {
|
|
3147
|
-
console.log(
|
|
3048
|
+
console.log(chalk5.green(" \u2713") + ` ${status2.protectedPathsCount} protected paths`);
|
|
3148
3049
|
}
|
|
3149
3050
|
}
|
|
3150
3051
|
if (status2.pendingAtomsCount > 0) {
|
|
3151
|
-
console.log(
|
|
3052
|
+
console.log(chalk5.cyan(` \u2192 ${status2.pendingAtomsCount} atoms pending`));
|
|
3152
3053
|
}
|
|
3153
3054
|
console.log();
|
|
3154
3055
|
}
|
|
@@ -3280,11 +3181,11 @@ async function gatherGovernanceStatus(cwd) {
|
|
|
3280
3181
|
return status2;
|
|
3281
3182
|
}
|
|
3282
3183
|
async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
3283
|
-
console.log(
|
|
3184
|
+
console.log(chalk5.blue("-- Analyzing Project --\n"));
|
|
3284
3185
|
const projectInfo = await gatherProjectInfo(cwd);
|
|
3285
|
-
console.log(
|
|
3186
|
+
console.log(chalk5.bold(uiText("\u{1F4C1} Project Overview\n", "Project Overview\n")));
|
|
3286
3187
|
if (projectInfo.name) {
|
|
3287
|
-
console.log(` Name: ${
|
|
3188
|
+
console.log(` Name: ${chalk5.cyan(projectInfo.name)}`);
|
|
3288
3189
|
}
|
|
3289
3190
|
if (projectInfo.language) {
|
|
3290
3191
|
console.log(` Language: ${projectInfo.language}`);
|
|
@@ -3296,57 +3197,57 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3296
3197
|
console.log(` Package Manager: ${projectInfo.packageManager}`);
|
|
3297
3198
|
}
|
|
3298
3199
|
console.log();
|
|
3299
|
-
console.log(
|
|
3300
|
-
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") :
|
|
3200
|
+
console.log(chalk5.bold(uiText("\u{1F4CA} Structure\n", "Structure\n")));
|
|
3201
|
+
console.log(` Source directories: ${projectInfo.sourceDirs.length > 0 ? projectInfo.sourceDirs.join(", ") : chalk5.dim("none detected")}`);
|
|
3301
3202
|
console.log(` Source files: ${projectInfo.sourceFileCount}`);
|
|
3302
3203
|
if (projectInfo.testFileCount > 0) {
|
|
3303
3204
|
console.log(` Test files: ${projectInfo.testFileCount}`);
|
|
3304
3205
|
}
|
|
3305
3206
|
console.log();
|
|
3306
|
-
console.log(
|
|
3207
|
+
console.log(chalk5.bold(uiText("\u{1F3DB}\uFE0F Governance\n", "Governance\n")));
|
|
3307
3208
|
if (projectInfo.hasArchitecture) {
|
|
3308
|
-
console.log(` ${
|
|
3209
|
+
console.log(` ${chalk5.green("\u2713")} ARCHITECTURE.md (${projectInfo.posture || "unknown"} posture)`);
|
|
3309
3210
|
if (projectInfo.invariantsCount > 0) {
|
|
3310
|
-
console.log(` ${
|
|
3211
|
+
console.log(` ${chalk5.green("\u2713")} ${projectInfo.invariantsCount} invariants defined`);
|
|
3311
3212
|
}
|
|
3312
3213
|
if (projectInfo.protectedPathsCount > 0) {
|
|
3313
|
-
console.log(` ${
|
|
3214
|
+
console.log(` ${chalk5.green("\u2713")} ${projectInfo.protectedPathsCount} protected paths`);
|
|
3314
3215
|
}
|
|
3315
3216
|
} else {
|
|
3316
|
-
console.log(` ${
|
|
3217
|
+
console.log(` ${chalk5.yellow("\u25CB")} No ARCHITECTURE.md yet`);
|
|
3317
3218
|
}
|
|
3318
3219
|
if (projectInfo.hasProgress) {
|
|
3319
|
-
console.log(` ${
|
|
3220
|
+
console.log(` ${chalk5.green("\u2713")} progress.txt exists`);
|
|
3320
3221
|
}
|
|
3321
3222
|
console.log();
|
|
3322
|
-
console.log(
|
|
3223
|
+
console.log(chalk5.green("\u2713 Analysis complete! I'm ready to work on this project.\n"));
|
|
3323
3224
|
const originalFollowUp = (followUpInput ?? "").trim();
|
|
3324
3225
|
const actionableFollowUp = extractActionableFollowUpFromExplore(originalFollowUp);
|
|
3325
3226
|
if (actionableFollowUp || containsActionIntent(originalFollowUp)) {
|
|
3326
3227
|
const request = actionableFollowUp ?? originalFollowUp;
|
|
3327
|
-
console.log(
|
|
3228
|
+
console.log(chalk5.dim("I finished the project scan. Continuing with your requested task...\n"));
|
|
3328
3229
|
await handlePostExploreAction(cwd, request);
|
|
3329
3230
|
return;
|
|
3330
3231
|
}
|
|
3331
3232
|
if (options.agentMode) {
|
|
3332
|
-
console.log(
|
|
3233
|
+
console.log(chalk5.dim("Tell me the next thing you want to do.\n"));
|
|
3333
3234
|
return;
|
|
3334
3235
|
}
|
|
3335
|
-
console.log(
|
|
3336
|
-
console.log(
|
|
3337
|
-
console.log(` ${
|
|
3338
|
-
console.log(` ${
|
|
3236
|
+
console.log(chalk5.bold("What would you like to do next?\n"));
|
|
3237
|
+
console.log(chalk5.dim("You can describe it naturally, or use shortcuts:\n"));
|
|
3238
|
+
console.log(` ${chalk5.cyan("1")}) ${chalk5.bold("Plan a task")} \u2014 Tell me what to implement, fix, or change`);
|
|
3239
|
+
console.log(` ${chalk5.cyan("2")}) ${chalk5.bold("Review code")} \u2014 Run AI-powered code review`);
|
|
3339
3240
|
if (!projectInfo.hasArchitecture) {
|
|
3340
|
-
console.log(` ${
|
|
3241
|
+
console.log(` ${chalk5.cyan("3")}) ${chalk5.bold("Set up governance")} \u2014 Generate ARCHITECTURE.md from this analysis`);
|
|
3341
3242
|
}
|
|
3342
|
-
console.log(` ${
|
|
3243
|
+
console.log(` ${chalk5.cyan("q")}) ${chalk5.dim("Quit")}`);
|
|
3343
3244
|
console.log();
|
|
3344
3245
|
const choice = await promptWithCommands("Enter choice");
|
|
3345
3246
|
switch (choice.toLowerCase()) {
|
|
3346
3247
|
case "1": {
|
|
3347
3248
|
const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
|
|
3348
3249
|
if (description.trim()) {
|
|
3349
|
-
const { plan: plan2 } = await import("./plan-
|
|
3250
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3350
3251
|
await plan2(description, { conversational: true });
|
|
3351
3252
|
}
|
|
3352
3253
|
await showMainMenu();
|
|
@@ -3372,7 +3273,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
|
|
|
3372
3273
|
return;
|
|
3373
3274
|
}
|
|
3374
3275
|
}
|
|
3375
|
-
console.log(
|
|
3276
|
+
console.log(chalk5.yellow("I did not catch that. Tell me what you want to do next."));
|
|
3376
3277
|
await showMainMenu();
|
|
3377
3278
|
}
|
|
3378
3279
|
}
|
|
@@ -3470,12 +3371,12 @@ async function gatherProjectInfo(cwd) {
|
|
|
3470
3371
|
return info;
|
|
3471
3372
|
}
|
|
3472
3373
|
async function runConversationalInterview(cwd, initialMessage) {
|
|
3473
|
-
const { InterviewerAgent, createInterviewerAgent } = await import("./interviewer-
|
|
3374
|
+
const { InterviewerAgent, createInterviewerAgent } = await import("./interviewer-FACOJSBN.js");
|
|
3474
3375
|
const agent = await createInterviewerAgent();
|
|
3475
3376
|
if (agent && agent.isAvailable()) {
|
|
3476
3377
|
await runAIInterview(cwd, initialMessage, agent);
|
|
3477
3378
|
} else {
|
|
3478
|
-
console.log(
|
|
3379
|
+
console.log(chalk5.dim("(Using simple setup - add API keys with `archon keys add` for AI-powered interview)\n"));
|
|
3479
3380
|
await runSimpleInterview(cwd, initialMessage);
|
|
3480
3381
|
}
|
|
3481
3382
|
}
|
|
@@ -3485,11 +3386,11 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3485
3386
|
try {
|
|
3486
3387
|
let turn = await agent.startInterview(initialMessage);
|
|
3487
3388
|
while (!turn.isComplete && turnCount < MAX_TURNS) {
|
|
3488
|
-
console.log(
|
|
3389
|
+
console.log(chalk5.blue("\u2192 ") + turn.question);
|
|
3489
3390
|
console.log();
|
|
3490
3391
|
const response = await prompt("");
|
|
3491
3392
|
if (wantsToSkip(response)) {
|
|
3492
|
-
console.log(
|
|
3393
|
+
console.log(chalk5.dim("\n> Using defaults for remaining questions.\n"));
|
|
3493
3394
|
break;
|
|
3494
3395
|
}
|
|
3495
3396
|
turn = await agent.continueInterview(response);
|
|
@@ -3501,12 +3402,12 @@ async function runAIInterview(cwd, initialMessage, agent) {
|
|
|
3501
3402
|
}
|
|
3502
3403
|
const usage = agent.getUsage();
|
|
3503
3404
|
if (usage.totalTokens > 0) {
|
|
3504
|
-
console.log(
|
|
3405
|
+
console.log(chalk5.dim(`
|
|
3505
3406
|
(Interview used ${usage.totalTokens} tokens, $${usage.baseCost.toFixed(4)})`));
|
|
3506
3407
|
}
|
|
3507
3408
|
await finishInterview(cwd, state, initialMessage);
|
|
3508
3409
|
} catch (error) {
|
|
3509
|
-
console.log(
|
|
3410
|
+
console.log(chalk5.yellow("\n[!] AI interview unavailable, using simple setup.\n"));
|
|
3510
3411
|
await runSimpleInterview(cwd, initialMessage);
|
|
3511
3412
|
}
|
|
3512
3413
|
}
|
|
@@ -3519,9 +3420,9 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3519
3420
|
});
|
|
3520
3421
|
const known = getKnownInfo(state);
|
|
3521
3422
|
if (known.length > 0) {
|
|
3522
|
-
console.log(
|
|
3423
|
+
console.log(chalk5.dim("From what you said, I got:"));
|
|
3523
3424
|
for (const info of known) {
|
|
3524
|
-
console.log(
|
|
3425
|
+
console.log(chalk5.dim(` \u2022 ${info}`));
|
|
3525
3426
|
}
|
|
3526
3427
|
console.log();
|
|
3527
3428
|
}
|
|
@@ -3543,7 +3444,7 @@ async function runSimpleInterview(cwd, initialMessage) {
|
|
|
3543
3444
|
await finishInterview(cwd, state, initialMessage);
|
|
3544
3445
|
}
|
|
3545
3446
|
async function finishInterview(cwd, state, initialTaskHint) {
|
|
3546
|
-
console.log(
|
|
3447
|
+
console.log(chalk5.blue("\n-- Recording Project Details --\n"));
|
|
3547
3448
|
const posture = state.posture === "enterprise" ? "enterprise" : state.posture === "prototype" ? "prototype" : "production";
|
|
3548
3449
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
3549
3450
|
const progressEntry = `
|
|
@@ -3575,23 +3476,23 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3575
3476
|
writeFileSync2(progressPath, "# ArchonDev Progress Log\n\nThis file tracks learnings and decisions across sessions.\n");
|
|
3576
3477
|
}
|
|
3577
3478
|
appendFileSync(progressPath, progressEntry);
|
|
3578
|
-
console.log(
|
|
3479
|
+
console.log(chalk5.green("\n\u2713 Project details recorded!\n"));
|
|
3579
3480
|
const finalKnown = getKnownInfo(state);
|
|
3580
3481
|
if (finalKnown.length > 0) {
|
|
3581
|
-
console.log(
|
|
3482
|
+
console.log(chalk5.dim("Project configured with:"));
|
|
3582
3483
|
for (const info of finalKnown) {
|
|
3583
|
-
console.log(
|
|
3484
|
+
console.log(chalk5.dim(` \u2022 ${info}`));
|
|
3584
3485
|
}
|
|
3585
3486
|
console.log();
|
|
3586
3487
|
}
|
|
3587
|
-
console.log(
|
|
3588
|
-
console.log(` 1. ${
|
|
3589
|
-
console.log(` 2. ${
|
|
3488
|
+
console.log(chalk5.bold("Next steps:"));
|
|
3489
|
+
console.log(` 1. ${chalk5.cyan("Review")} ARCHITECTURE.md and customize if needed`);
|
|
3490
|
+
console.log(` 2. ${chalk5.cyan("Run")} ${chalk5.dim('archon plan "your first task"')} to create an atom`);
|
|
3590
3491
|
console.log();
|
|
3591
3492
|
const hintedTask = initialTaskHint?.trim() ?? "";
|
|
3592
3493
|
if (hintedTask) {
|
|
3593
|
-
console.log(
|
|
3594
|
-
const { plan: plan2 } = await import("./plan-
|
|
3494
|
+
console.log(chalk5.dim("Using your request above as the first task.\n"));
|
|
3495
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3595
3496
|
await plan2(hintedTask, { conversational: true });
|
|
3596
3497
|
return;
|
|
3597
3498
|
}
|
|
@@ -3608,7 +3509,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3608
3509
|
const hinted = initialTaskHint?.trim() ?? "";
|
|
3609
3510
|
if (hinted) {
|
|
3610
3511
|
description = hinted;
|
|
3611
|
-
console.log(
|
|
3512
|
+
console.log(chalk5.dim("\nUsing your request above as the first task.\n"));
|
|
3612
3513
|
} else {
|
|
3613
3514
|
description = await promptWithCommands("Describe what you want to build first", { allowMultiline: true });
|
|
3614
3515
|
}
|
|
@@ -3616,7 +3517,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
|
|
|
3616
3517
|
description = continueAnswer.trim();
|
|
3617
3518
|
}
|
|
3618
3519
|
if (description.trim()) {
|
|
3619
|
-
const { plan: plan2 } = await import("./plan-
|
|
3520
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3620
3521
|
await plan2(description, { conversational: true });
|
|
3621
3522
|
}
|
|
3622
3523
|
}
|
|
@@ -3694,7 +3595,7 @@ function inferLanguageFromProjectFiles(cwd) {
|
|
|
3694
3595
|
return best?.language;
|
|
3695
3596
|
}
|
|
3696
3597
|
async function analyzeAndAdapt(cwd) {
|
|
3697
|
-
console.log(
|
|
3598
|
+
console.log(chalk5.blue("\n-- Analyzing Project --\n"));
|
|
3698
3599
|
const { init: init2 } = await import("./init-FINETS3Q.js");
|
|
3699
3600
|
await init2({ analyze: true, git: true });
|
|
3700
3601
|
const today = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
@@ -3716,13 +3617,13 @@ async function analyzeAndAdapt(cwd) {
|
|
|
3716
3617
|
- .archon/config.yaml - Build commands configured
|
|
3717
3618
|
- progress.txt - This file
|
|
3718
3619
|
`);
|
|
3719
|
-
console.log(
|
|
3620
|
+
console.log(chalk5.green("\n\u2713 Governance files adapted!\n"));
|
|
3720
3621
|
await showMainMenu();
|
|
3721
3622
|
}
|
|
3722
3623
|
async function codeReviewFirst(cwd) {
|
|
3723
|
-
console.log(
|
|
3724
|
-
console.log(
|
|
3725
|
-
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-
|
|
3624
|
+
console.log(chalk5.blue("\n-- Code Review Mode --\n"));
|
|
3625
|
+
console.log(chalk5.dim("I'll analyze your code for issues without making any changes.\n"));
|
|
3626
|
+
const { reviewInit: reviewInit2, reviewAnalyze: reviewAnalyze2, reviewRun: reviewRun2 } = await import("./review-7BBVCF7H.js");
|
|
3726
3627
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
3727
3628
|
if (!existsSync6(reviewDbPath)) {
|
|
3728
3629
|
await reviewInit2();
|
|
@@ -3732,22 +3633,22 @@ async function codeReviewFirst(cwd) {
|
|
|
3732
3633
|
if (runReview) {
|
|
3733
3634
|
await reviewRun2({ all: true });
|
|
3734
3635
|
}
|
|
3735
|
-
console.log(
|
|
3636
|
+
console.log(chalk5.dim("\nAfter reviewing, you can run ") + chalk5.cyan("archon") + chalk5.dim(" again to set up governance.\n"));
|
|
3736
3637
|
}
|
|
3737
3638
|
async function runAgentMode(cwd, state) {
|
|
3738
3639
|
if (state.scenario === "CONTINUE_SESSION") {
|
|
3739
|
-
console.log(
|
|
3640
|
+
console.log(chalk5.bold("Welcome back!\n"));
|
|
3740
3641
|
if (state.lastProgressEntry) {
|
|
3741
|
-
console.log(
|
|
3742
|
-
console.log(
|
|
3642
|
+
console.log(chalk5.dim("Last activity:"));
|
|
3643
|
+
console.log(chalk5.dim(" " + state.lastProgressEntry.split("\n")[0]));
|
|
3743
3644
|
console.log();
|
|
3744
3645
|
}
|
|
3745
3646
|
} else if (state.scenario === "NEW_PROJECT") {
|
|
3746
|
-
console.log(
|
|
3747
|
-
console.log(
|
|
3647
|
+
console.log(chalk5.bold("Starting in chat mode.\n"));
|
|
3648
|
+
console.log(chalk5.dim("Tell me what you want to build. I will apply governance checks in the background.\n"));
|
|
3748
3649
|
} else {
|
|
3749
|
-
console.log(
|
|
3750
|
-
console.log(
|
|
3650
|
+
console.log(chalk5.bold("Ready in chat mode.\n"));
|
|
3651
|
+
console.log(chalk5.dim("Tell me what you want to do. Use /workflow for the classic menu.\n"));
|
|
3751
3652
|
}
|
|
3752
3653
|
while (true) {
|
|
3753
3654
|
const response = await promptWithCommands(
|
|
@@ -3764,7 +3665,7 @@ async function runAgentMode(cwd, state) {
|
|
|
3764
3665
|
}
|
|
3765
3666
|
const handled = await handleAgentConversationInput(cwd, trimmed);
|
|
3766
3667
|
if (!handled) {
|
|
3767
|
-
console.log(
|
|
3668
|
+
console.log(chalk5.yellow("I did not catch that. Describe your goal in one sentence."));
|
|
3768
3669
|
}
|
|
3769
3670
|
}
|
|
3770
3671
|
}
|
|
@@ -3775,52 +3676,92 @@ async function handleAgentConversationInput(cwd, input) {
|
|
|
3775
3676
|
await continueWithCurrentTask(cwd);
|
|
3776
3677
|
return true;
|
|
3777
3678
|
}
|
|
3679
|
+
if (isReferenceToPreviousRequest(normalized)) {
|
|
3680
|
+
await showLatestPlannedAtom(cwd);
|
|
3681
|
+
return true;
|
|
3682
|
+
}
|
|
3778
3683
|
const intent = detectUserIntent(input);
|
|
3779
3684
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3780
|
-
console.log(
|
|
3685
|
+
console.log(chalk5.dim("\n> Got it! Analyzing the project...\n"));
|
|
3781
3686
|
await runExploreFlow(cwd, input, { agentMode: true });
|
|
3782
3687
|
return true;
|
|
3783
3688
|
}
|
|
3784
|
-
console.log(
|
|
3785
|
-
const { plan: plan2 } = await import("./plan-
|
|
3689
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3690
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3786
3691
|
await plan2(input, { conversational: true });
|
|
3692
|
+
if (shouldStopAfterPlanning(input)) {
|
|
3693
|
+
await showLatestPlannedAtom(cwd);
|
|
3694
|
+
return true;
|
|
3695
|
+
}
|
|
3696
|
+
await continueWithCurrentTask(cwd);
|
|
3787
3697
|
return true;
|
|
3788
3698
|
}
|
|
3699
|
+
function isReferenceToPreviousRequest(input) {
|
|
3700
|
+
const normalized = input.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
|
|
3701
|
+
if (!normalized) return false;
|
|
3702
|
+
return normalized === "that" || normalized === "that one" || normalized === "same thing" || normalized === "same request" || normalized.includes("what i wrote already") || normalized.includes("what i already wrote") || normalized.includes("same as above") || normalized.includes("as above") || normalized.includes("same as earlier") || normalized.includes("use what i wrote");
|
|
3703
|
+
}
|
|
3704
|
+
function shouldStopAfterPlanning(input) {
|
|
3705
|
+
const normalized = input.toLowerCase();
|
|
3706
|
+
return normalized.includes("plan before") || normalized.includes("before continuing") || normalized.includes("before we continue") || normalized.includes("show me your plan") || normalized.includes("give me your plan") || normalized.includes("come up with a plan") || normalized.includes("do not start yet");
|
|
3707
|
+
}
|
|
3708
|
+
async function showLatestPlannedAtom(cwd) {
|
|
3709
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
|
|
3710
|
+
const atoms = await listLocalAtoms2();
|
|
3711
|
+
if (atoms.length === 0) {
|
|
3712
|
+
console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
|
|
3713
|
+
return;
|
|
3714
|
+
}
|
|
3715
|
+
const latest = atoms.slice().sort((a, b) => {
|
|
3716
|
+
const aTime = new Date(String(a.updatedAt)).getTime();
|
|
3717
|
+
const bTime = new Date(String(b.updatedAt)).getTime();
|
|
3718
|
+
return bTime - aTime;
|
|
3719
|
+
})[0];
|
|
3720
|
+
if (!latest) {
|
|
3721
|
+
console.log(chalk5.yellow("No atoms found yet. Tell me what to plan."));
|
|
3722
|
+
return;
|
|
3723
|
+
}
|
|
3724
|
+
console.log(chalk5.dim(`
|
|
3725
|
+
Showing latest planned atom (${latest.externalId})...
|
|
3726
|
+
`));
|
|
3727
|
+
const { show: show2 } = await import("./show-N7E3I6EF.js");
|
|
3728
|
+
await show2(latest.externalId);
|
|
3729
|
+
}
|
|
3789
3730
|
function isContinuationDirective(input) {
|
|
3790
3731
|
const normalized = input.trim().toLowerCase();
|
|
3791
3732
|
return normalized === "continue" || normalized === "continue." || normalized === "go on" || normalized === "go ahead" || normalized === "next" || normalized === "proceed" || normalized === "do it";
|
|
3792
3733
|
}
|
|
3793
3734
|
async function continueWithCurrentTask(cwd) {
|
|
3794
|
-
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-
|
|
3735
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
|
|
3795
3736
|
const atoms = await listLocalAtoms2();
|
|
3796
3737
|
const pending = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS").sort((a, b) => a.externalId.localeCompare(b.externalId));
|
|
3797
3738
|
if (pending.length === 0) {
|
|
3798
|
-
console.log(
|
|
3739
|
+
console.log(chalk5.yellow("No pending atoms found. Tell me what to plan next."));
|
|
3799
3740
|
return;
|
|
3800
3741
|
}
|
|
3801
3742
|
const nextAtom = pending[0];
|
|
3802
3743
|
if (!nextAtom) {
|
|
3803
|
-
console.log(
|
|
3744
|
+
console.log(chalk5.yellow("No pending atoms found. Tell me what to plan next."));
|
|
3804
3745
|
return;
|
|
3805
3746
|
}
|
|
3806
|
-
console.log(
|
|
3747
|
+
console.log(chalk5.dim(`
|
|
3807
3748
|
Continuing with ${nextAtom.externalId}...
|
|
3808
3749
|
`));
|
|
3809
|
-
const { execute: execute2 } = await import("./execute-
|
|
3750
|
+
const { execute: execute2 } = await import("./execute-SGRPEDGM.js");
|
|
3810
3751
|
await execute2(nextAtom.externalId, {});
|
|
3811
3752
|
}
|
|
3812
3753
|
async function showMainMenu() {
|
|
3813
3754
|
const cwd = process.cwd();
|
|
3814
3755
|
while (true) {
|
|
3815
3756
|
const state = detectProjectState(cwd);
|
|
3816
|
-
console.log(
|
|
3757
|
+
console.log(chalk5.bold("What would you like to do?\n"));
|
|
3817
3758
|
if (state.isWebProject) {
|
|
3818
3759
|
const { loadWebChecks, formatWebCheckStatus } = await import("./web-checks-4BSYXWDF.js");
|
|
3819
3760
|
const prefs = await loadWebChecks(cwd);
|
|
3820
|
-
console.log(
|
|
3821
|
-
console.log(
|
|
3822
|
-
console.log(
|
|
3823
|
-
console.log(
|
|
3761
|
+
console.log(chalk5.dim("Web checks status:"));
|
|
3762
|
+
console.log(chalk5.dim(` A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
3763
|
+
console.log(chalk5.dim(` SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
3764
|
+
console.log(chalk5.dim(` GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
3824
3765
|
console.log();
|
|
3825
3766
|
}
|
|
3826
3767
|
const choices = [
|
|
@@ -3841,9 +3782,9 @@ async function showMainMenu() {
|
|
|
3841
3782
|
{ key: "q", label: "Quit", action: async () => process.exit(0) }
|
|
3842
3783
|
];
|
|
3843
3784
|
for (const choice2 of choices) {
|
|
3844
|
-
console.log(` ${
|
|
3785
|
+
console.log(` ${chalk5.cyan(choice2.key)}) ${choice2.label}`);
|
|
3845
3786
|
}
|
|
3846
|
-
console.log(
|
|
3787
|
+
console.log(chalk5.dim(' (Type "/" for quick commands, or "upgrade"/"help" anytime)'));
|
|
3847
3788
|
console.log();
|
|
3848
3789
|
const selected = await promptWithCommands("Tell me what you want to do (or enter a shortcut)", { allowMultiline: true });
|
|
3849
3790
|
const choice = choices.find((c) => c.key === selected.toLowerCase());
|
|
@@ -3854,11 +3795,11 @@ async function showMainMenu() {
|
|
|
3854
3795
|
if (selected.trim()) {
|
|
3855
3796
|
const handled = await handleFreeformJourneyInput(cwd, selected.trim());
|
|
3856
3797
|
if (!handled) {
|
|
3857
|
-
console.log(
|
|
3798
|
+
console.log(chalk5.yellow("I did not catch that. Try describing your goal in one sentence."));
|
|
3858
3799
|
}
|
|
3859
3800
|
continue;
|
|
3860
3801
|
}
|
|
3861
|
-
console.log(
|
|
3802
|
+
console.log(chalk5.yellow("Invalid choice. Please try again."));
|
|
3862
3803
|
}
|
|
3863
3804
|
}
|
|
3864
3805
|
async function handleFreeformJourneyInput(cwd, input) {
|
|
@@ -3866,24 +3807,24 @@ async function handleFreeformJourneyInput(cwd, input) {
|
|
|
3866
3807
|
if (!freeform) return false;
|
|
3867
3808
|
const intent = detectUserIntent(freeform);
|
|
3868
3809
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3869
|
-
console.log(
|
|
3810
|
+
console.log(chalk5.dim("\n> Got it! Analyzing the project...\n"));
|
|
3870
3811
|
await runExploreFlow(cwd, freeform);
|
|
3871
3812
|
return true;
|
|
3872
3813
|
}
|
|
3873
3814
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
3874
3815
|
const state = detectProjectState(cwd);
|
|
3875
3816
|
if (state.hasArchitecture) {
|
|
3876
|
-
console.log(
|
|
3877
|
-
const { plan: plan3 } = await import("./plan-
|
|
3817
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3818
|
+
const { plan: plan3 } = await import("./plan-PJI6MCS3.js");
|
|
3878
3819
|
await plan3(freeform, { conversational: true });
|
|
3879
3820
|
return true;
|
|
3880
3821
|
}
|
|
3881
|
-
console.log(
|
|
3822
|
+
console.log(chalk5.dim("\n> Let me understand your project better...\n"));
|
|
3882
3823
|
await runConversationalInterview(cwd, freeform);
|
|
3883
3824
|
return true;
|
|
3884
3825
|
}
|
|
3885
|
-
console.log(
|
|
3886
|
-
const { plan: plan2 } = await import("./plan-
|
|
3826
|
+
console.log(chalk5.dim("\n> Got it! Creating a task for this...\n"));
|
|
3827
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3887
3828
|
await plan2(freeform, { conversational: true });
|
|
3888
3829
|
return true;
|
|
3889
3830
|
}
|
|
@@ -3924,39 +3865,39 @@ function containsActionIntent(input) {
|
|
|
3924
3865
|
async function handlePostExploreAction(cwd, request) {
|
|
3925
3866
|
const intent = detectUserIntent(request);
|
|
3926
3867
|
if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
|
|
3927
|
-
console.log(
|
|
3868
|
+
console.log(chalk5.dim("> Let me understand your project better...\n"));
|
|
3928
3869
|
await runConversationalInterview(cwd, request);
|
|
3929
3870
|
return;
|
|
3930
3871
|
}
|
|
3931
3872
|
if (intent.mode === "explore" && intent.confidence >= 0.7) {
|
|
3932
|
-
console.log(
|
|
3873
|
+
console.log(chalk5.dim("> I can go deeper. Creating a concrete task from your request...\n"));
|
|
3933
3874
|
} else {
|
|
3934
|
-
console.log(
|
|
3875
|
+
console.log(chalk5.dim("> Got it! Creating a task for this...\n"));
|
|
3935
3876
|
}
|
|
3936
|
-
const { plan: plan2 } = await import("./plan-
|
|
3877
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3937
3878
|
await plan2(request, { conversational: true });
|
|
3938
3879
|
}
|
|
3939
3880
|
async function planTask() {
|
|
3940
|
-
const { plan: plan2 } = await import("./plan-
|
|
3881
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
3941
3882
|
const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
|
|
3942
3883
|
if (description.trim()) {
|
|
3943
3884
|
await plan2(description, { conversational: true });
|
|
3944
3885
|
}
|
|
3945
3886
|
}
|
|
3946
3887
|
async function listAtoms() {
|
|
3947
|
-
const { list: list2 } = await import("./list-
|
|
3888
|
+
const { list: list2 } = await import("./list-2PHO34IY.js");
|
|
3948
3889
|
await list2({});
|
|
3949
3890
|
}
|
|
3950
3891
|
async function executeNext() {
|
|
3951
|
-
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-
|
|
3892
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-PJI6MCS3.js");
|
|
3952
3893
|
const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
|
|
3953
|
-
const { loadExecutionPreferences } = await import("./preferences-
|
|
3894
|
+
const { loadExecutionPreferences } = await import("./preferences-AGIZD5E5.js");
|
|
3954
3895
|
const cwd = process.cwd();
|
|
3955
3896
|
const atoms = await listLocalAtoms2();
|
|
3956
3897
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
3957
3898
|
const readyAtoms = atoms.filter((a) => a.status === "READY");
|
|
3958
3899
|
if (pendingAtoms.length === 0) {
|
|
3959
|
-
console.log(
|
|
3900
|
+
console.log(chalk5.yellow('No pending atoms. Use "archon plan" to create one.'));
|
|
3960
3901
|
return;
|
|
3961
3902
|
}
|
|
3962
3903
|
if (pendingAtoms.length > 1) {
|
|
@@ -3964,20 +3905,20 @@ async function executeNext() {
|
|
|
3964
3905
|
const prefs = await loadExecutionPreferences(cwd);
|
|
3965
3906
|
const config = await loadConfig();
|
|
3966
3907
|
const canUseCloud = (config.tier ?? "FREE") === "CREDITS";
|
|
3967
|
-
console.log(
|
|
3968
|
-
console.log(` ${
|
|
3969
|
-
console.log(` ${
|
|
3970
|
-
console.log(` ${
|
|
3971
|
-
console.log(` ${
|
|
3908
|
+
console.log(chalk5.blue("\n-- Project Analysis --\n"));
|
|
3909
|
+
console.log(` ${chalk5.bold("Atoms:")} ${analysis.atomCount}`);
|
|
3910
|
+
console.log(` ${chalk5.bold("Estimated:")} ${analysis.estimatedMinutes} minutes`);
|
|
3911
|
+
console.log(` ${chalk5.bold("Complexity:")} ${analysis.complexity} - ${getComplexityDescription(analysis.complexity)}`);
|
|
3912
|
+
console.log(` ${chalk5.bold("Suggested:")} ${analysis.suggestedMode} - ${getModeDescription(analysis.suggestedMode)}`);
|
|
3972
3913
|
console.log();
|
|
3973
3914
|
let selectedMode = "sequential";
|
|
3974
3915
|
if (canUseCloud && prefs.cloudMode === "always" && analysis.suggestedMode === "parallel-cloud") {
|
|
3975
3916
|
selectedMode = "parallel-cloud";
|
|
3976
|
-
console.log(
|
|
3917
|
+
console.log(chalk5.green(`
|
|
3977
3918
|
\u2713 Auto-selected parallel cloud execution (preference: always)`));
|
|
3978
3919
|
} else if (prefs.parallelMode === "always" && analysis.suggestedMode !== "sequential") {
|
|
3979
3920
|
selectedMode = "parallel-local";
|
|
3980
|
-
console.log(
|
|
3921
|
+
console.log(chalk5.green(`
|
|
3981
3922
|
\u2713 Auto-selected parallel local execution (preference: always)`));
|
|
3982
3923
|
} else if (prefs.parallelMode === "ask" || canUseCloud && prefs.cloudMode === "ask") {
|
|
3983
3924
|
const options = [
|
|
@@ -3993,18 +3934,18 @@ async function executeNext() {
|
|
|
3993
3934
|
}
|
|
3994
3935
|
if (selectedMode !== "sequential") {
|
|
3995
3936
|
if (readyAtoms.length === 0) {
|
|
3996
|
-
console.log(
|
|
3937
|
+
console.log(chalk5.yellow("No READY atoms available for parallel execution."));
|
|
3997
3938
|
return;
|
|
3998
3939
|
}
|
|
3999
|
-
console.log(
|
|
3940
|
+
console.log(chalk5.dim("\nPending atoms:"));
|
|
4000
3941
|
for (const atom of readyAtoms) {
|
|
4001
|
-
console.log(
|
|
3942
|
+
console.log(chalk5.dim(` - ${atom.id}: ${atom.title}`));
|
|
4002
3943
|
}
|
|
4003
3944
|
console.log();
|
|
4004
3945
|
const raw = await prompt("Enter atom IDs to run in parallel (comma-separated, or press Enter for all)");
|
|
4005
3946
|
const selectedIds = raw.trim() ? raw.split(",").map((s) => s.trim()).filter(Boolean) : readyAtoms.map((a) => a.id);
|
|
4006
3947
|
if (selectedIds.length === 0) {
|
|
4007
|
-
console.log(
|
|
3948
|
+
console.log(chalk5.yellow("No atoms selected."));
|
|
4008
3949
|
return;
|
|
4009
3950
|
}
|
|
4010
3951
|
let runIds = selectedIds;
|
|
@@ -4015,15 +3956,15 @@ async function executeNext() {
|
|
|
4015
3956
|
);
|
|
4016
3957
|
if (!override) {
|
|
4017
3958
|
runIds = selectedIds.slice(0, prefs.maxParallelAgents);
|
|
4018
|
-
console.log(
|
|
3959
|
+
console.log(chalk5.dim(`Running first ${runIds.length} atoms.`));
|
|
4019
3960
|
}
|
|
4020
3961
|
}
|
|
4021
3962
|
if (selectedMode === "parallel-cloud") {
|
|
4022
|
-
const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-
|
|
3963
|
+
const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-RCMUYXE2.js");
|
|
4023
3964
|
await parallelExecuteCloud2(runIds);
|
|
4024
3965
|
return;
|
|
4025
3966
|
}
|
|
4026
|
-
const { parallelExecute } = await import("./parallel-
|
|
3967
|
+
const { parallelExecute } = await import("./parallel-RCMUYXE2.js");
|
|
4027
3968
|
await parallelExecute(runIds);
|
|
4028
3969
|
return;
|
|
4029
3970
|
}
|
|
@@ -4031,14 +3972,14 @@ async function executeNext() {
|
|
|
4031
3972
|
const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
|
|
4032
3973
|
const targetId = atomId.trim() || pendingAtoms[0]?.id;
|
|
4033
3974
|
if (targetId) {
|
|
4034
|
-
const { execute: execute2 } = await import("./execute-
|
|
3975
|
+
const { execute: execute2 } = await import("./execute-SGRPEDGM.js");
|
|
4035
3976
|
await execute2(targetId, {});
|
|
4036
3977
|
} else {
|
|
4037
|
-
console.log(
|
|
3978
|
+
console.log(chalk5.yellow("No atom to execute."));
|
|
4038
3979
|
}
|
|
4039
3980
|
}
|
|
4040
3981
|
async function reportBug() {
|
|
4041
|
-
const { bugReport: bugReport2 } = await import("./bug-
|
|
3982
|
+
const { bugReport: bugReport2 } = await import("./bug-QYKFP77X.js");
|
|
4042
3983
|
const title = await prompt("Bug title");
|
|
4043
3984
|
if (title.trim()) {
|
|
4044
3985
|
await bugReport2(title, {});
|
|
@@ -4049,52 +3990,52 @@ async function viewStatus() {
|
|
|
4049
3990
|
await status2();
|
|
4050
3991
|
}
|
|
4051
3992
|
async function settingsMenu() {
|
|
4052
|
-
const { interactiveSettings } = await import("./preferences-
|
|
3993
|
+
const { interactiveSettings } = await import("./preferences-AGIZD5E5.js");
|
|
4053
3994
|
await interactiveSettings();
|
|
4054
3995
|
}
|
|
4055
3996
|
async function reviewCode() {
|
|
4056
3997
|
const cwd = process.cwd();
|
|
4057
3998
|
const reviewDbPath = join6(cwd, "docs", "code-review", "review-tasks.db");
|
|
4058
3999
|
if (!existsSync6(reviewDbPath)) {
|
|
4059
|
-
console.log(
|
|
4060
|
-
const { reviewInit: reviewInit2 } = await import("./review-
|
|
4000
|
+
console.log(chalk5.dim("Code review not initialized. Starting setup...\n"));
|
|
4001
|
+
const { reviewInit: reviewInit2 } = await import("./review-7BBVCF7H.js");
|
|
4061
4002
|
await reviewInit2();
|
|
4062
4003
|
console.log();
|
|
4063
4004
|
}
|
|
4064
|
-
console.log(
|
|
4065
|
-
console.log(
|
|
4066
|
-
console.log(` ${
|
|
4067
|
-
console.log(` ${
|
|
4068
|
-
console.log(` ${
|
|
4069
|
-
console.log(` ${
|
|
4070
|
-
console.log(` ${
|
|
4071
|
-
console.log(` ${
|
|
4005
|
+
console.log(chalk5.bold("\nCode Review Options:\n"));
|
|
4006
|
+
console.log(chalk5.dim("You can type naturally (recommended) or use a shortcut:\n"));
|
|
4007
|
+
console.log(` ${chalk5.cyan("1")}) Analyze project`);
|
|
4008
|
+
console.log(` ${chalk5.cyan("2")}) Show review status`);
|
|
4009
|
+
console.log(` ${chalk5.cyan("3")}) Review next file`);
|
|
4010
|
+
console.log(` ${chalk5.cyan("4")}) List all tasks`);
|
|
4011
|
+
console.log(` ${chalk5.cyan("5")}) Run AI review on all pending`);
|
|
4012
|
+
console.log(` ${chalk5.cyan("b")}) Back to main menu`);
|
|
4072
4013
|
console.log();
|
|
4073
4014
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4074
4015
|
const choice = resolveReviewChoice(raw);
|
|
4075
4016
|
switch (choice) {
|
|
4076
4017
|
case "1": {
|
|
4077
|
-
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-
|
|
4018
|
+
const { reviewAnalyze: reviewAnalyze2 } = await import("./review-7BBVCF7H.js");
|
|
4078
4019
|
await reviewAnalyze2();
|
|
4079
4020
|
break;
|
|
4080
4021
|
}
|
|
4081
4022
|
case "2": {
|
|
4082
|
-
const { reviewStatus: reviewStatus2 } = await import("./review-
|
|
4023
|
+
const { reviewStatus: reviewStatus2 } = await import("./review-7BBVCF7H.js");
|
|
4083
4024
|
await reviewStatus2();
|
|
4084
4025
|
break;
|
|
4085
4026
|
}
|
|
4086
4027
|
case "3": {
|
|
4087
|
-
const { reviewNext: reviewNext2 } = await import("./review-
|
|
4028
|
+
const { reviewNext: reviewNext2 } = await import("./review-7BBVCF7H.js");
|
|
4088
4029
|
await reviewNext2();
|
|
4089
4030
|
break;
|
|
4090
4031
|
}
|
|
4091
4032
|
case "4": {
|
|
4092
|
-
const { reviewList: reviewList2 } = await import("./review-
|
|
4033
|
+
const { reviewList: reviewList2 } = await import("./review-7BBVCF7H.js");
|
|
4093
4034
|
await reviewList2({});
|
|
4094
4035
|
break;
|
|
4095
4036
|
}
|
|
4096
4037
|
case "5": {
|
|
4097
|
-
const { reviewRun: reviewRun2 } = await import("./review-
|
|
4038
|
+
const { reviewRun: reviewRun2 } = await import("./review-7BBVCF7H.js");
|
|
4098
4039
|
await reviewRun2({ all: true });
|
|
4099
4040
|
break;
|
|
4100
4041
|
}
|
|
@@ -4107,7 +4048,7 @@ async function reviewCode() {
|
|
|
4107
4048
|
return;
|
|
4108
4049
|
}
|
|
4109
4050
|
}
|
|
4110
|
-
console.log(
|
|
4051
|
+
console.log(chalk5.yellow("I did not catch that. Tell me what review action you want."));
|
|
4111
4052
|
}
|
|
4112
4053
|
await reviewCode();
|
|
4113
4054
|
}
|
|
@@ -4135,13 +4076,13 @@ async function handleInSessionCommand(input) {
|
|
|
4135
4076
|
}
|
|
4136
4077
|
if (normalized === "help" || normalized === "?" || normalized === "archon help") {
|
|
4137
4078
|
console.log();
|
|
4138
|
-
console.log(
|
|
4139
|
-
console.log(
|
|
4140
|
-
console.log(
|
|
4141
|
-
console.log(
|
|
4142
|
-
console.log(
|
|
4143
|
-
console.log(
|
|
4144
|
-
console.log(
|
|
4079
|
+
console.log(chalk5.bold("Available commands (type anytime):"));
|
|
4080
|
+
console.log(chalk5.dim(" upgrade \u2014 Switch to BYOK or Managed plan"));
|
|
4081
|
+
console.log(chalk5.dim(" status \u2014 Show login and tier status"));
|
|
4082
|
+
console.log(chalk5.dim(" keys \u2014 Manage API keys (BYOK tier)"));
|
|
4083
|
+
console.log(chalk5.dim(" /workflow \u2014 Open classic workflow menu"));
|
|
4084
|
+
console.log(chalk5.dim(" quit / q \u2014 Exit ArchonDev"));
|
|
4085
|
+
console.log(chalk5.dim(" skip \u2014 Skip current question"));
|
|
4145
4086
|
console.log();
|
|
4146
4087
|
return true;
|
|
4147
4088
|
}
|
|
@@ -4151,23 +4092,23 @@ async function handleInSessionCommand(input) {
|
|
|
4151
4092
|
return true;
|
|
4152
4093
|
}
|
|
4153
4094
|
if (normalized === "quit" || normalized === "exit" || normalized === "q") {
|
|
4154
|
-
console.log(
|
|
4095
|
+
console.log(chalk5.dim("Goodbye!"));
|
|
4155
4096
|
process.exit(0);
|
|
4156
4097
|
}
|
|
4157
4098
|
return false;
|
|
4158
4099
|
}
|
|
4159
4100
|
function showSlashCommandMenu() {
|
|
4160
4101
|
console.log();
|
|
4161
|
-
console.log(
|
|
4162
|
-
console.log(
|
|
4163
|
-
console.log(
|
|
4164
|
-
console.log(
|
|
4165
|
-
console.log(
|
|
4166
|
-
console.log(
|
|
4167
|
-
console.log(
|
|
4168
|
-
console.log(
|
|
4169
|
-
console.log(
|
|
4170
|
-
console.log(
|
|
4102
|
+
console.log(chalk5.bold("Quick Commands"));
|
|
4103
|
+
console.log(chalk5.dim(" /plan <task> Create a plan from a one-line task"));
|
|
4104
|
+
console.log(chalk5.dim(" /list List atoms"));
|
|
4105
|
+
console.log(chalk5.dim(" /execute Execute next atom"));
|
|
4106
|
+
console.log(chalk5.dim(" /review Open code review menu"));
|
|
4107
|
+
console.log(chalk5.dim(" /status Show account/status"));
|
|
4108
|
+
console.log(chalk5.dim(" /settings Open settings & preferences"));
|
|
4109
|
+
console.log(chalk5.dim(" /upgrade Open tier upgrade menu"));
|
|
4110
|
+
console.log(chalk5.dim(" /workflow Open classic workflow menu"));
|
|
4111
|
+
console.log(chalk5.dim(" /quit Exit ArchonDev"));
|
|
4171
4112
|
console.log();
|
|
4172
4113
|
}
|
|
4173
4114
|
async function handleSlashCommand(input) {
|
|
@@ -4180,7 +4121,7 @@ async function handleSlashCommand(input) {
|
|
|
4180
4121
|
const arg = parts.slice(1).join(" ").trim();
|
|
4181
4122
|
switch (command) {
|
|
4182
4123
|
case "/plan": {
|
|
4183
|
-
const { plan: plan2 } = await import("./plan-
|
|
4124
|
+
const { plan: plan2 } = await import("./plan-PJI6MCS3.js");
|
|
4184
4125
|
if (arg) {
|
|
4185
4126
|
await plan2(arg, { conversational: true });
|
|
4186
4127
|
} else {
|
|
@@ -4216,7 +4157,7 @@ async function handleSlashCommand(input) {
|
|
|
4216
4157
|
return true;
|
|
4217
4158
|
case "/quit":
|
|
4218
4159
|
case "/exit":
|
|
4219
|
-
console.log(
|
|
4160
|
+
console.log(chalk5.dim("Goodbye!"));
|
|
4220
4161
|
process.exit(0);
|
|
4221
4162
|
}
|
|
4222
4163
|
return false;
|
|
@@ -4227,7 +4168,7 @@ function prompt(question) {
|
|
|
4227
4168
|
input: process.stdin,
|
|
4228
4169
|
output: process.stdout
|
|
4229
4170
|
});
|
|
4230
|
-
rl.question(`${
|
|
4171
|
+
rl.question(`${chalk5.cyan("?")} ${question}: `, (answer) => {
|
|
4231
4172
|
rl.close();
|
|
4232
4173
|
resolve(answer);
|
|
4233
4174
|
});
|
|
@@ -4254,7 +4195,7 @@ function promptMultiline(question) {
|
|
|
4254
4195
|
rl.on("close", () => {
|
|
4255
4196
|
resolve(lines.join("\n").trimEnd());
|
|
4256
4197
|
});
|
|
4257
|
-
rl.setPrompt(`${
|
|
4198
|
+
rl.setPrompt(`${chalk5.cyan("?")} ${question} (multi-line: end with a single '.' line or Ctrl+D): `);
|
|
4258
4199
|
rl.prompt();
|
|
4259
4200
|
});
|
|
4260
4201
|
}
|
|
@@ -4269,14 +4210,14 @@ async function promptWithCommands(question, options = {}) {
|
|
|
4269
4210
|
if (!handled) {
|
|
4270
4211
|
return answer;
|
|
4271
4212
|
}
|
|
4272
|
-
console.log(
|
|
4213
|
+
console.log(chalk5.dim("(Returning to previous question...)\n"));
|
|
4273
4214
|
}
|
|
4274
4215
|
}
|
|
4275
4216
|
async function runWebChecksSuite() {
|
|
4276
4217
|
const { a11yCheck: a11yCheck2 } = await import("./a11y-O35BAA25.js");
|
|
4277
4218
|
const { seoCheck } = await import("./seo-PMI42KRZ.js");
|
|
4278
|
-
const { geoAudit } = await import("./geo-
|
|
4279
|
-
console.log(
|
|
4219
|
+
const { geoAudit } = await import("./geo-KXVALNSF.js");
|
|
4220
|
+
console.log(chalk5.blue("\nRunning web checks (A11y, SEO, GEO)...\n"));
|
|
4280
4221
|
await a11yCheck2({});
|
|
4281
4222
|
await seoCheck({});
|
|
4282
4223
|
await geoAudit();
|
|
@@ -4285,19 +4226,19 @@ async function showWebChecksMenu() {
|
|
|
4285
4226
|
const cwd = process.cwd();
|
|
4286
4227
|
const { loadWebChecks, formatWebCheckStatus, setWebPromptMode } = await import("./web-checks-4BSYXWDF.js");
|
|
4287
4228
|
const prefs = await loadWebChecks(cwd);
|
|
4288
|
-
console.log(
|
|
4289
|
-
console.log(
|
|
4290
|
-
console.log(
|
|
4291
|
-
console.log(
|
|
4229
|
+
console.log(chalk5.bold("\nWeb Checks (SEO / GEO / A11y)\n"));
|
|
4230
|
+
console.log(chalk5.dim(`A11y: ${formatWebCheckStatus(prefs.lastRun?.a11y)}`));
|
|
4231
|
+
console.log(chalk5.dim(`SEO: ${formatWebCheckStatus(prefs.lastRun?.seo)}`));
|
|
4232
|
+
console.log(chalk5.dim(`GEO: ${formatWebCheckStatus(prefs.lastRun?.geo)}`));
|
|
4292
4233
|
console.log();
|
|
4293
|
-
console.log(` ${
|
|
4294
|
-
console.log(` ${
|
|
4295
|
-
console.log(` ${
|
|
4296
|
-
console.log(` ${
|
|
4297
|
-
console.log(` ${
|
|
4298
|
-
console.log(` ${
|
|
4299
|
-
console.log(` ${
|
|
4300
|
-
console.log(` ${
|
|
4234
|
+
console.log(` ${chalk5.cyan("1")}) Run all checks`);
|
|
4235
|
+
console.log(` ${chalk5.cyan("2")}) Run accessibility check`);
|
|
4236
|
+
console.log(` ${chalk5.cyan("3")}) Run SEO check`);
|
|
4237
|
+
console.log(` ${chalk5.cyan("4")}) Run GEO audit`);
|
|
4238
|
+
console.log(` ${chalk5.cyan("5")}) Generate GEO identity`);
|
|
4239
|
+
console.log(` ${chalk5.cyan("6")}) Generate GEO schema`);
|
|
4240
|
+
console.log(` ${chalk5.cyan("7")}) Set prompt mode (ask/always/never)`);
|
|
4241
|
+
console.log(` ${chalk5.cyan("b")}) Back to main menu`);
|
|
4301
4242
|
console.log();
|
|
4302
4243
|
const raw = await promptWithCommands("What do you want to do?", { allowMultiline: true });
|
|
4303
4244
|
const choice = resolveWebChecksChoice(raw);
|
|
@@ -4316,25 +4257,25 @@ async function showWebChecksMenu() {
|
|
|
4316
4257
|
break;
|
|
4317
4258
|
}
|
|
4318
4259
|
case "4": {
|
|
4319
|
-
const { geoAudit } = await import("./geo-
|
|
4260
|
+
const { geoAudit } = await import("./geo-KXVALNSF.js");
|
|
4320
4261
|
await geoAudit();
|
|
4321
4262
|
break;
|
|
4322
4263
|
}
|
|
4323
4264
|
case "5": {
|
|
4324
|
-
const { geoIdentity } = await import("./geo-
|
|
4265
|
+
const { geoIdentity } = await import("./geo-KXVALNSF.js");
|
|
4325
4266
|
await geoIdentity();
|
|
4326
4267
|
break;
|
|
4327
4268
|
}
|
|
4328
4269
|
case "6": {
|
|
4329
|
-
const { geoSchema } = await import("./geo-
|
|
4270
|
+
const { geoSchema } = await import("./geo-KXVALNSF.js");
|
|
4330
4271
|
await geoSchema({});
|
|
4331
4272
|
break;
|
|
4332
4273
|
}
|
|
4333
4274
|
case "7": {
|
|
4334
4275
|
console.log();
|
|
4335
|
-
console.log(` ${
|
|
4336
|
-
console.log(` ${
|
|
4337
|
-
console.log(` ${
|
|
4276
|
+
console.log(` ${chalk5.cyan("1")}) Ask each session`);
|
|
4277
|
+
console.log(` ${chalk5.cyan("2")}) Always run automatically`);
|
|
4278
|
+
console.log(` ${chalk5.cyan("3")}) Never prompt`);
|
|
4338
4279
|
console.log();
|
|
4339
4280
|
const modeChoiceRaw = await promptWithCommands("Set mode (ask / always / never)");
|
|
4340
4281
|
const modeChoice = resolvePromptModeChoice(modeChoiceRaw);
|
|
@@ -4350,7 +4291,7 @@ async function showWebChecksMenu() {
|
|
|
4350
4291
|
return;
|
|
4351
4292
|
}
|
|
4352
4293
|
}
|
|
4353
|
-
console.log(
|
|
4294
|
+
console.log(chalk5.yellow("I did not catch that. Tell me which web check you want."));
|
|
4354
4295
|
}
|
|
4355
4296
|
if (choice.toLowerCase() !== "b") {
|
|
4356
4297
|
await showWebChecksMenu();
|
|
@@ -4366,11 +4307,11 @@ async function maybePromptWebChecks(cwd, projectState) {
|
|
|
4366
4307
|
return;
|
|
4367
4308
|
}
|
|
4368
4309
|
if (prefs.promptMode === "always") {
|
|
4369
|
-
console.log(
|
|
4310
|
+
console.log(chalk5.blue("\nWeb project detected. Running web checks automatically...\n"));
|
|
4370
4311
|
await runWebChecksSuite();
|
|
4371
4312
|
return;
|
|
4372
4313
|
}
|
|
4373
|
-
console.log(
|
|
4314
|
+
console.log(chalk5.blue("\nWeb project detected."));
|
|
4374
4315
|
const choice = await promptChoice("Run web checks now?", [
|
|
4375
4316
|
{ key: "1", label: "Run all checks (A11y + SEO + GEO)" },
|
|
4376
4317
|
{ key: "2", label: "Choose checks" },
|
|
@@ -4392,7 +4333,7 @@ function promptYesNo(question, defaultValue) {
|
|
|
4392
4333
|
output: process.stdout
|
|
4393
4334
|
});
|
|
4394
4335
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
4395
|
-
rl.question(`${
|
|
4336
|
+
rl.question(`${chalk5.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
4396
4337
|
rl.close();
|
|
4397
4338
|
if (answer.trim() === "") {
|
|
4398
4339
|
resolve(defaultValue);
|
|
@@ -4404,15 +4345,15 @@ function promptYesNo(question, defaultValue) {
|
|
|
4404
4345
|
}
|
|
4405
4346
|
function promptChoice(question, options, defaultKey) {
|
|
4406
4347
|
return new Promise((resolve) => {
|
|
4407
|
-
console.log(`${
|
|
4348
|
+
console.log(`${chalk5.cyan("?")} ${question}`);
|
|
4408
4349
|
for (const opt of options) {
|
|
4409
|
-
console.log(` ${
|
|
4350
|
+
console.log(` ${chalk5.dim(opt.key)}) ${opt.label}`);
|
|
4410
4351
|
}
|
|
4411
4352
|
const rl = readline.createInterface({
|
|
4412
4353
|
input: process.stdin,
|
|
4413
4354
|
output: process.stdout
|
|
4414
4355
|
});
|
|
4415
|
-
rl.question(` ${
|
|
4356
|
+
rl.question(` ${chalk5.dim("Enter choice or describe what you want")}: `, (answer) => {
|
|
4416
4357
|
rl.close();
|
|
4417
4358
|
const trimmed = answer.trim();
|
|
4418
4359
|
if (trimmed) {
|
|
@@ -4475,7 +4416,7 @@ function resolvePromptModeChoice(input) {
|
|
|
4475
4416
|
}
|
|
4476
4417
|
|
|
4477
4418
|
// src/cli/credits.ts
|
|
4478
|
-
import
|
|
4419
|
+
import chalk6 from "chalk";
|
|
4479
4420
|
import ora from "ora";
|
|
4480
4421
|
import open from "open";
|
|
4481
4422
|
import readline2 from "readline";
|
|
@@ -4521,20 +4462,20 @@ async function showCredits() {
|
|
|
4521
4462
|
const profile = data;
|
|
4522
4463
|
spinner.stop();
|
|
4523
4464
|
console.log();
|
|
4524
|
-
console.log(
|
|
4465
|
+
console.log(chalk6.bold("\u{1F4B0} Credit Balance"));
|
|
4525
4466
|
console.log();
|
|
4526
4467
|
const balance = (profile.credit_balance_cents || 0) / 100;
|
|
4527
4468
|
console.log(` Tier: ${formatTier(profile.tier)}`);
|
|
4528
|
-
console.log(` Balance: ${
|
|
4469
|
+
console.log(` Balance: ${chalk6.green(`$${balance.toFixed(2)}`)}`);
|
|
4529
4470
|
if (profile.tier === "FREE") {
|
|
4530
4471
|
console.log(` Atoms: ${profile.atoms_used_this_month}/10,000 this month`);
|
|
4531
4472
|
console.log();
|
|
4532
|
-
console.log(
|
|
4473
|
+
console.log(chalk6.dim(" Upgrade to Credits tier: archon credits add"));
|
|
4533
4474
|
printCreditsNextAction("FREE");
|
|
4534
4475
|
} else if (profile.tier === "CREDITS") {
|
|
4535
4476
|
console.log();
|
|
4536
|
-
console.log(
|
|
4537
|
-
console.log(
|
|
4477
|
+
console.log(chalk6.dim(" Add more credits: archon credits add"));
|
|
4478
|
+
console.log(chalk6.dim(" Detailed usage by model: archon usage"));
|
|
4538
4479
|
printCreditsNextAction("CREDITS");
|
|
4539
4480
|
if (balance < 5) {
|
|
4540
4481
|
const addNow = await promptYesNo2("Balance is low. Add credits now?", false);
|
|
@@ -4544,8 +4485,8 @@ async function showCredits() {
|
|
|
4544
4485
|
}
|
|
4545
4486
|
} else if (profile.tier === "BYOK") {
|
|
4546
4487
|
console.log();
|
|
4547
|
-
console.log(
|
|
4548
|
-
console.log(
|
|
4488
|
+
console.log(chalk6.dim(" Using your own API keys - no credit charges"));
|
|
4489
|
+
console.log(chalk6.dim(" Estimated spend by model: archon usage"));
|
|
4549
4490
|
printCreditsNextAction("BYOK");
|
|
4550
4491
|
}
|
|
4551
4492
|
console.log();
|
|
@@ -4592,35 +4533,35 @@ async function addCredits(options = {}) {
|
|
|
4592
4533
|
}
|
|
4593
4534
|
spinner.succeed("Checkout ready");
|
|
4594
4535
|
console.log();
|
|
4595
|
-
console.log(
|
|
4536
|
+
console.log(chalk6.bold("\u{1F6D2} Add Credits"));
|
|
4596
4537
|
console.log();
|
|
4597
|
-
console.log(` Amount: ${
|
|
4538
|
+
console.log(` Amount: ${chalk6.green(`$${amountDollars.toFixed(2)}`)}`);
|
|
4598
4539
|
console.log();
|
|
4599
4540
|
console.log(" Opening checkout in browser...");
|
|
4600
4541
|
console.log();
|
|
4601
|
-
console.log(
|
|
4542
|
+
console.log(chalk6.dim(` Or visit: ${checkoutUrl}`));
|
|
4602
4543
|
console.log();
|
|
4603
4544
|
try {
|
|
4604
4545
|
await open(checkoutUrl);
|
|
4605
4546
|
} catch {
|
|
4606
|
-
console.log(
|
|
4547
|
+
console.log(chalk6.yellow(" Could not open browser. Please visit the URL above."));
|
|
4607
4548
|
}
|
|
4608
|
-
console.log(
|
|
4609
|
-
console.log(
|
|
4610
|
-
console.log(
|
|
4549
|
+
console.log(chalk6.bold("\nNext best action:"));
|
|
4550
|
+
console.log(chalk6.dim(` \u2022 Complete payment in browser, then run ${chalk6.cyan("archon credits")} to verify balance.`));
|
|
4551
|
+
console.log(chalk6.dim(` \u2022 Continue work with ${chalk6.cyan('archon plan "..."')} or ${chalk6.cyan("archon execute <ATOM-ID>")}.`));
|
|
4611
4552
|
} catch (err2) {
|
|
4612
4553
|
spinner.fail("Error preparing checkout");
|
|
4613
4554
|
console.error(err2);
|
|
4614
4555
|
}
|
|
4615
4556
|
}
|
|
4616
4557
|
function printCreditsNextAction(tier) {
|
|
4617
|
-
console.log(
|
|
4558
|
+
console.log(chalk6.bold(" Next best action:"));
|
|
4618
4559
|
if (tier === "CREDITS") {
|
|
4619
|
-
console.log(
|
|
4560
|
+
console.log(chalk6.dim(` \u2022 Keep at least $5 balance to avoid interruptions during plan/execute.`));
|
|
4620
4561
|
} else if (tier === "BYOK") {
|
|
4621
|
-
console.log(
|
|
4562
|
+
console.log(chalk6.dim(` \u2022 Manage provider keys with ${chalk6.cyan("archon keys add/list/remove")}.`));
|
|
4622
4563
|
} else {
|
|
4623
|
-
console.log(
|
|
4564
|
+
console.log(chalk6.dim(` \u2022 Upgrade to BYOK or Credits with ${chalk6.cyan("archon upgrade")}.`));
|
|
4624
4565
|
}
|
|
4625
4566
|
}
|
|
4626
4567
|
function promptYesNo2(question, defaultValue) {
|
|
@@ -4630,7 +4571,7 @@ function promptYesNo2(question, defaultValue) {
|
|
|
4630
4571
|
output: process.stdout
|
|
4631
4572
|
});
|
|
4632
4573
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
4633
|
-
rl.question(`${
|
|
4574
|
+
rl.question(`${chalk6.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
4634
4575
|
rl.close();
|
|
4635
4576
|
if (answer.trim() === "") {
|
|
4636
4577
|
resolve(defaultValue);
|
|
@@ -4664,15 +4605,15 @@ async function showHistory(options = {}) {
|
|
|
4664
4605
|
const usage = data;
|
|
4665
4606
|
spinner.stop();
|
|
4666
4607
|
console.log();
|
|
4667
|
-
console.log(
|
|
4608
|
+
console.log(chalk6.bold("Usage History"));
|
|
4668
4609
|
console.log();
|
|
4669
4610
|
if (!usage || usage.length === 0) {
|
|
4670
|
-
console.log(
|
|
4611
|
+
console.log(chalk6.dim(" No usage recorded yet."));
|
|
4671
4612
|
console.log();
|
|
4672
4613
|
return;
|
|
4673
4614
|
}
|
|
4674
|
-
console.log(
|
|
4675
|
-
console.log(
|
|
4615
|
+
console.log(chalk6.dim(" Model Tokens Cost Date"));
|
|
4616
|
+
console.log(chalk6.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4676
4617
|
for (const row of usage) {
|
|
4677
4618
|
const model = row.model.padEnd(30).slice(0, 30);
|
|
4678
4619
|
const tokens = (row.input_tokens + row.output_tokens).toString().padStart(8);
|
|
@@ -4682,9 +4623,9 @@ async function showHistory(options = {}) {
|
|
|
4682
4623
|
}
|
|
4683
4624
|
const totalCost = usage.reduce((sum, r) => sum + r.base_cost, 0);
|
|
4684
4625
|
const totalTokens = usage.reduce((sum, r) => sum + r.input_tokens + r.output_tokens, 0);
|
|
4685
|
-
console.log(
|
|
4626
|
+
console.log(chalk6.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4686
4627
|
console.log(
|
|
4687
|
-
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${
|
|
4628
|
+
` ${"Total".padEnd(30)} ${totalTokens.toString().padStart(8)} ${chalk6.green(`$${totalCost.toFixed(4)}`.padStart(10))}`
|
|
4688
4629
|
);
|
|
4689
4630
|
console.log();
|
|
4690
4631
|
} catch (err2) {
|
|
@@ -4750,24 +4691,24 @@ async function manageBudget(options = {}) {
|
|
|
4750
4691
|
}
|
|
4751
4692
|
spinner.stop();
|
|
4752
4693
|
console.log();
|
|
4753
|
-
console.log(
|
|
4694
|
+
console.log(chalk6.bold("Monthly Budget"));
|
|
4754
4695
|
console.log();
|
|
4755
4696
|
if (profile.monthly_budget_cents === null) {
|
|
4756
|
-
console.log(` Budget: ${
|
|
4697
|
+
console.log(` Budget: ${chalk6.dim("No limit set")}`);
|
|
4757
4698
|
} else {
|
|
4758
4699
|
const budget = profile.monthly_budget_cents / 100;
|
|
4759
4700
|
const spend = (profile.monthly_spend_cents || 0) / 100;
|
|
4760
4701
|
const remaining = budget - spend;
|
|
4761
4702
|
const percent = budget > 0 ? Math.round(spend / budget * 100) : 0;
|
|
4762
|
-
console.log(` Budget: ${
|
|
4703
|
+
console.log(` Budget: ${chalk6.green(`$${budget.toFixed(2)}`)} / month`);
|
|
4763
4704
|
console.log(` Spent: $${spend.toFixed(2)} (${percent}%)`);
|
|
4764
|
-
console.log(` Remaining: ${remaining >= 0 ?
|
|
4705
|
+
console.log(` Remaining: ${remaining >= 0 ? chalk6.green(`$${remaining.toFixed(2)}`) : chalk6.red(`-$${Math.abs(remaining).toFixed(2)}`)}`);
|
|
4765
4706
|
}
|
|
4766
4707
|
console.log(` Alert at: ${profile.budget_alert_threshold_percent}% of budget`);
|
|
4767
4708
|
console.log();
|
|
4768
|
-
console.log(
|
|
4769
|
-
console.log(
|
|
4770
|
-
console.log(
|
|
4709
|
+
console.log(chalk6.dim(" Set budget: archon credits budget --set 50"));
|
|
4710
|
+
console.log(chalk6.dim(" Clear budget: archon credits budget --clear"));
|
|
4711
|
+
console.log(chalk6.dim(" Set alert: archon credits budget --alert 80"));
|
|
4771
4712
|
console.log();
|
|
4772
4713
|
} catch (err2) {
|
|
4773
4714
|
spinner.fail("Error managing budget");
|
|
@@ -4829,12 +4770,12 @@ async function manageAutoRecharge(options = {}) {
|
|
|
4829
4770
|
}
|
|
4830
4771
|
spinner.stop();
|
|
4831
4772
|
console.log();
|
|
4832
|
-
console.log(
|
|
4773
|
+
console.log(chalk6.bold("\u{1F504} Auto-Recharge"));
|
|
4833
4774
|
console.log();
|
|
4834
4775
|
if (!profile.auto_recharge_enabled) {
|
|
4835
|
-
console.log(` Status: ${
|
|
4776
|
+
console.log(` Status: ${chalk6.dim("Disabled")}`);
|
|
4836
4777
|
} else {
|
|
4837
|
-
console.log(` Status: ${
|
|
4778
|
+
console.log(` Status: ${chalk6.green("Enabled")}`);
|
|
4838
4779
|
if (profile.auto_recharge_threshold_cents !== null) {
|
|
4839
4780
|
console.log(` When: Balance drops below $${(profile.auto_recharge_threshold_cents / 100).toFixed(2)}`);
|
|
4840
4781
|
}
|
|
@@ -4842,10 +4783,10 @@ async function manageAutoRecharge(options = {}) {
|
|
|
4842
4783
|
console.log(` Amount: $${(profile.auto_recharge_amount_cents / 100).toFixed(2)}`);
|
|
4843
4784
|
}
|
|
4844
4785
|
}
|
|
4845
|
-
console.log(` Payment: ${profile.stripe_payment_method_id ?
|
|
4786
|
+
console.log(` Payment: ${profile.stripe_payment_method_id ? chalk6.green("Card saved") : chalk6.dim("No card saved")}`);
|
|
4846
4787
|
console.log();
|
|
4847
|
-
console.log(
|
|
4848
|
-
console.log(
|
|
4788
|
+
console.log(chalk6.dim(" Enable: archon credits auto-recharge --enable --threshold 5 --amount 20"));
|
|
4789
|
+
console.log(chalk6.dim(" Disable: archon credits auto-recharge --disable"));
|
|
4849
4790
|
console.log();
|
|
4850
4791
|
} catch (err2) {
|
|
4851
4792
|
spinner.fail("Error managing auto-recharge");
|
|
@@ -4875,21 +4816,21 @@ async function showAuditHistory(options = {}) {
|
|
|
4875
4816
|
});
|
|
4876
4817
|
if (error) {
|
|
4877
4818
|
spinner.fail("Could not fetch audit history");
|
|
4878
|
-
console.error(
|
|
4819
|
+
console.error(chalk6.dim(error.message));
|
|
4879
4820
|
return;
|
|
4880
4821
|
}
|
|
4881
4822
|
const history = data;
|
|
4882
4823
|
spinner.stop();
|
|
4883
4824
|
console.log();
|
|
4884
|
-
console.log(
|
|
4825
|
+
console.log(chalk6.bold("\u{1F4CB} Billing Audit History"));
|
|
4885
4826
|
console.log();
|
|
4886
4827
|
if (!history || history.length === 0) {
|
|
4887
|
-
console.log(
|
|
4828
|
+
console.log(chalk6.dim(" No billing events recorded yet."));
|
|
4888
4829
|
console.log();
|
|
4889
4830
|
return;
|
|
4890
4831
|
}
|
|
4891
|
-
console.log(
|
|
4892
|
-
console.log(
|
|
4832
|
+
console.log(chalk6.dim(" Event Amount Balance Date"));
|
|
4833
|
+
console.log(chalk6.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4893
4834
|
for (const row of history) {
|
|
4894
4835
|
const eventType = formatEventType(row.event_type).padEnd(22);
|
|
4895
4836
|
const amount = row.amount_cents !== null ? formatAmount(row.event_type, row.amount_cents).padStart(10) : " -";
|
|
@@ -4897,10 +4838,10 @@ async function showAuditHistory(options = {}) {
|
|
|
4897
4838
|
const date = new Date(row.created_at).toLocaleDateString();
|
|
4898
4839
|
console.log(` ${eventType} ${amount} ${balance} ${date}`);
|
|
4899
4840
|
}
|
|
4900
|
-
console.log(
|
|
4841
|
+
console.log(chalk6.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
4901
4842
|
console.log();
|
|
4902
|
-
console.log(
|
|
4903
|
-
console.log(
|
|
4843
|
+
console.log(chalk6.dim(` Showing ${history.length} most recent events`));
|
|
4844
|
+
console.log(chalk6.dim(" Use --limit N to show more"));
|
|
4904
4845
|
console.log();
|
|
4905
4846
|
} catch (err2) {
|
|
4906
4847
|
spinner.fail("Error fetching audit history");
|
|
@@ -4910,19 +4851,19 @@ async function showAuditHistory(options = {}) {
|
|
|
4910
4851
|
function formatEventType(eventType) {
|
|
4911
4852
|
switch (eventType) {
|
|
4912
4853
|
case "CREDITS_PURCHASED":
|
|
4913
|
-
return
|
|
4854
|
+
return chalk6.green("+ Purchase");
|
|
4914
4855
|
case "CREDITS_DEDUCTED":
|
|
4915
|
-
return
|
|
4856
|
+
return chalk6.red("- Usage");
|
|
4916
4857
|
case "CREDITS_REFUNDED":
|
|
4917
|
-
return
|
|
4858
|
+
return chalk6.cyan("+ Refund");
|
|
4918
4859
|
case "BALANCE_ADJUSTED":
|
|
4919
|
-
return
|
|
4860
|
+
return chalk6.yellow("\xB1 Adjustment");
|
|
4920
4861
|
case "BUDGET_CHANGED":
|
|
4921
|
-
return
|
|
4862
|
+
return chalk6.blue("\u25C9 Budget");
|
|
4922
4863
|
case "TIER_CHANGED":
|
|
4923
|
-
return
|
|
4864
|
+
return chalk6.magenta("\u25C9 Tier");
|
|
4924
4865
|
case "USAGE_RECORDED":
|
|
4925
|
-
return
|
|
4866
|
+
return chalk6.dim("\u25C9 Usage");
|
|
4926
4867
|
default:
|
|
4927
4868
|
return eventType;
|
|
4928
4869
|
}
|
|
@@ -4930,20 +4871,20 @@ function formatEventType(eventType) {
|
|
|
4930
4871
|
function formatAmount(eventType, cents) {
|
|
4931
4872
|
const dollars = (cents / 100).toFixed(2);
|
|
4932
4873
|
if (eventType === "CREDITS_PURCHASED" || eventType === "CREDITS_REFUNDED") {
|
|
4933
|
-
return
|
|
4874
|
+
return chalk6.green(`+$${dollars}`);
|
|
4934
4875
|
} else if (eventType === "CREDITS_DEDUCTED") {
|
|
4935
|
-
return
|
|
4876
|
+
return chalk6.red(`-$${dollars}`);
|
|
4936
4877
|
}
|
|
4937
4878
|
return `$${dollars}`;
|
|
4938
4879
|
}
|
|
4939
4880
|
function formatTier(tier) {
|
|
4940
4881
|
switch (tier) {
|
|
4941
4882
|
case "FREE":
|
|
4942
|
-
return
|
|
4883
|
+
return chalk6.blue("Free (10k atoms/month)");
|
|
4943
4884
|
case "CREDITS":
|
|
4944
|
-
return
|
|
4885
|
+
return chalk6.green("Credits (Pay-as-you-go)");
|
|
4945
4886
|
case "BYOK":
|
|
4946
|
-
return
|
|
4887
|
+
return chalk6.magenta("BYOK (Bring Your Own Key)");
|
|
4947
4888
|
default:
|
|
4948
4889
|
return tier;
|
|
4949
4890
|
}
|
|
@@ -4956,7 +4897,7 @@ import Spinner from "ink-spinner";
|
|
|
4956
4897
|
import * as fs from "fs";
|
|
4957
4898
|
import * as path from "path";
|
|
4958
4899
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4959
|
-
var
|
|
4900
|
+
var STATUS_COLORS = {
|
|
4960
4901
|
DRAFT: "gray",
|
|
4961
4902
|
READY: "blue",
|
|
4962
4903
|
IN_PROGRESS: "yellow",
|
|
@@ -5039,7 +4980,7 @@ function AtomList({ atoms }) {
|
|
|
5039
4980
|
] }),
|
|
5040
4981
|
atoms.slice(0, 15).map((atom) => /* @__PURE__ */ jsxs(Box, { paddingX: 1, children: [
|
|
5041
4982
|
/* @__PURE__ */ jsx(Box, { width: 12, children: /* @__PURE__ */ jsx(Text, { children: atom.id.slice(0, 10) }) }),
|
|
5042
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color:
|
|
4983
|
+
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color: STATUS_COLORS[atom.status], children: [
|
|
5043
4984
|
STATUS_ICONS[atom.status],
|
|
5044
4985
|
" ",
|
|
5045
4986
|
atom.status.slice(0, 7)
|
|
@@ -5100,7 +5041,7 @@ function RecentActivity({ atoms }) {
|
|
|
5100
5041
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, children: "Recent Activity" }) }),
|
|
5101
5042
|
recentAtoms.map((atom) => /* @__PURE__ */ jsxs(Box, { marginBottom: 0, children: [
|
|
5102
5043
|
/* @__PURE__ */ jsx(Box, { width: 20, children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: formatTime(new Date(atom.updatedAt)) }) }),
|
|
5103
|
-
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color:
|
|
5044
|
+
/* @__PURE__ */ jsx(Box, { width: 10, children: /* @__PURE__ */ jsxs(Text, { color: STATUS_COLORS[atom.status], children: [
|
|
5104
5045
|
STATUS_ICONS[atom.status],
|
|
5105
5046
|
" ",
|
|
5106
5047
|
atom.status.slice(0, 7)
|
|
@@ -5220,7 +5161,7 @@ async function watch() {
|
|
|
5220
5161
|
|
|
5221
5162
|
// src/cli/deps.ts
|
|
5222
5163
|
import { Command } from "commander";
|
|
5223
|
-
import
|
|
5164
|
+
import chalk7 from "chalk";
|
|
5224
5165
|
import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
5225
5166
|
import { existsSync as existsSync8 } from "fs";
|
|
5226
5167
|
var DEPENDENCIES_FILENAME = "DEPENDENCIES.md";
|
|
@@ -5238,30 +5179,30 @@ Examples:
|
|
|
5238
5179
|
deps.command("list").description("List all dependency rules").option("-v, --verbose", "Show detailed information").action(async (options) => {
|
|
5239
5180
|
const parser = new DependencyParser();
|
|
5240
5181
|
if (!parser.exists()) {
|
|
5241
|
-
console.log(
|
|
5242
|
-
console.log(
|
|
5182
|
+
console.log(chalk7.yellow("No DEPENDENCIES.md found."));
|
|
5183
|
+
console.log(chalk7.dim("Create one with: archon deps add --source <path> --dependent <path>"));
|
|
5243
5184
|
return;
|
|
5244
5185
|
}
|
|
5245
5186
|
const result = await parser.parse();
|
|
5246
5187
|
if (!result.success) {
|
|
5247
|
-
console.log(
|
|
5188
|
+
console.log(chalk7.red(`Parse error: ${result.error}`));
|
|
5248
5189
|
return;
|
|
5249
5190
|
}
|
|
5250
5191
|
const rules = result.document?.rules ?? [];
|
|
5251
5192
|
if (rules.length === 0) {
|
|
5252
|
-
console.log(
|
|
5193
|
+
console.log(chalk7.dim("No dependency rules defined."));
|
|
5253
5194
|
return;
|
|
5254
5195
|
}
|
|
5255
|
-
console.log(
|
|
5196
|
+
console.log(chalk7.bold(`
|
|
5256
5197
|
\u{1F4E6} Dependency Rules (${rules.length})
|
|
5257
5198
|
`));
|
|
5258
5199
|
for (const rule of rules) {
|
|
5259
|
-
const severityColor = rule.severity === "BLOCKER" ?
|
|
5260
|
-
console.log(`${severityColor(`[${rule.severity}]`)} ${
|
|
5261
|
-
console.log(` Source: ${
|
|
5262
|
-
console.log(` Dependents: ${rule.dependents.map((d) =>
|
|
5200
|
+
const severityColor = rule.severity === "BLOCKER" ? chalk7.red : rule.severity === "WARNING" ? chalk7.yellow : chalk7.blue;
|
|
5201
|
+
console.log(`${severityColor(`[${rule.severity}]`)} ${chalk7.bold(rule.id)}`);
|
|
5202
|
+
console.log(` Source: ${chalk7.cyan(rule.source)}`);
|
|
5203
|
+
console.log(` Dependents: ${rule.dependents.map((d) => chalk7.dim(d)).join(", ")}`);
|
|
5263
5204
|
if (rule.reason && options.verbose) {
|
|
5264
|
-
console.log(` Reason: ${
|
|
5205
|
+
console.log(` Reason: ${chalk7.dim(rule.reason)}`);
|
|
5265
5206
|
}
|
|
5266
5207
|
if (rule.mustTest && options.verbose) {
|
|
5267
5208
|
console.log(` Must test: ${rule.mustTest.join(", ")}`);
|
|
@@ -5273,29 +5214,29 @@ Examples:
|
|
|
5273
5214
|
const files = options.files.split(",").map((f) => f.trim());
|
|
5274
5215
|
const parser = new DependencyParser();
|
|
5275
5216
|
if (!parser.exists()) {
|
|
5276
|
-
console.log(
|
|
5217
|
+
console.log(chalk7.dim("No DEPENDENCIES.md found. No dependency checks performed."));
|
|
5277
5218
|
process.exit(0);
|
|
5278
5219
|
}
|
|
5279
5220
|
const result = await parser.checkFiles(files);
|
|
5280
5221
|
if (result.impacts.length === 0) {
|
|
5281
|
-
console.log(
|
|
5222
|
+
console.log(chalk7.green("\u2705 No downstream dependency impacts found."));
|
|
5282
5223
|
process.exit(0);
|
|
5283
5224
|
}
|
|
5284
|
-
console.log(
|
|
5225
|
+
console.log(chalk7.yellow(`
|
|
5285
5226
|
[!] Found ${result.impacts.length} dependency impact(s):
|
|
5286
5227
|
`));
|
|
5287
5228
|
for (const impact of result.impacts) {
|
|
5288
|
-
const severityColor = impact.rule.severity === "BLOCKER" ?
|
|
5229
|
+
const severityColor = impact.rule.severity === "BLOCKER" ? chalk7.red : impact.rule.severity === "WARNING" ? chalk7.yellow : chalk7.blue;
|
|
5289
5230
|
console.log(severityColor(`[${impact.rule.severity}] ${impact.rule.id}`));
|
|
5290
|
-
console.log(` Changing: ${
|
|
5231
|
+
console.log(` Changing: ${chalk7.cyan(impact.matchedSource)}`);
|
|
5291
5232
|
console.log(` May impact: ${impact.affectedDependents.join(", ")}`);
|
|
5292
5233
|
if (impact.rule.reason) {
|
|
5293
|
-
console.log(` Reason: ${
|
|
5234
|
+
console.log(` Reason: ${chalk7.dim(impact.rule.reason)}`);
|
|
5294
5235
|
}
|
|
5295
5236
|
console.log("");
|
|
5296
5237
|
}
|
|
5297
5238
|
if (result.hasBlockers) {
|
|
5298
|
-
console.log(
|
|
5239
|
+
console.log(chalk7.red("\u274C BLOCKER-level impacts found. Review before proceeding."));
|
|
5299
5240
|
process.exit(1);
|
|
5300
5241
|
}
|
|
5301
5242
|
process.exit(0);
|
|
@@ -5337,7 +5278,7 @@ Examples:
|
|
|
5337
5278
|
(r) => r.source === source && r.dependents.includes(dependent)
|
|
5338
5279
|
);
|
|
5339
5280
|
if (existingRule) {
|
|
5340
|
-
console.log(
|
|
5281
|
+
console.log(chalk7.yellow(`Rule already exists: ${existingRule.id}`));
|
|
5341
5282
|
return;
|
|
5342
5283
|
}
|
|
5343
5284
|
const newRule = {
|
|
@@ -5351,20 +5292,20 @@ Examples:
|
|
|
5351
5292
|
const yaml2 = generateYamlFrontmatter(existingRules);
|
|
5352
5293
|
await writeFile4(DEPENDENCIES_FILENAME, `---
|
|
5353
5294
|
${yaml2}---${markdownBody}`, "utf-8");
|
|
5354
|
-
console.log(
|
|
5355
|
-
console.log(` Source: ${
|
|
5356
|
-
console.log(` Dependent: ${
|
|
5295
|
+
console.log(chalk7.green(`\u2705 Added dependency rule: ${nextId}`));
|
|
5296
|
+
console.log(` Source: ${chalk7.cyan(source)}`);
|
|
5297
|
+
console.log(` Dependent: ${chalk7.dim(dependent)}`);
|
|
5357
5298
|
});
|
|
5358
5299
|
deps.command("graph").description("Generate Mermaid diagram of dependencies").option("--output <file>", "Write to file instead of stdout").action(async (options) => {
|
|
5359
5300
|
const parser = new DependencyParser();
|
|
5360
5301
|
if (!parser.exists()) {
|
|
5361
|
-
console.log(
|
|
5302
|
+
console.log(chalk7.yellow("No DEPENDENCIES.md found."));
|
|
5362
5303
|
return;
|
|
5363
5304
|
}
|
|
5364
5305
|
const mermaid = await parser.generateGraph();
|
|
5365
5306
|
if (options.output) {
|
|
5366
5307
|
await writeFile4(options.output, mermaid, "utf-8");
|
|
5367
|
-
console.log(
|
|
5308
|
+
console.log(chalk7.green(`\u2705 Graph written to ${options.output}`));
|
|
5368
5309
|
} else {
|
|
5369
5310
|
console.log("\n```mermaid");
|
|
5370
5311
|
console.log(mermaid);
|
|
@@ -5373,7 +5314,7 @@ ${yaml2}---${markdownBody}`, "utf-8");
|
|
|
5373
5314
|
});
|
|
5374
5315
|
deps.command("init").description("Create a starter DEPENDENCIES.md file").action(async () => {
|
|
5375
5316
|
if (existsSync8(DEPENDENCIES_FILENAME)) {
|
|
5376
|
-
console.log(
|
|
5317
|
+
console.log(chalk7.yellow("DEPENDENCIES.md already exists."));
|
|
5377
5318
|
return;
|
|
5378
5319
|
}
|
|
5379
5320
|
const template = `---
|
|
@@ -5420,8 +5361,8 @@ rules:
|
|
|
5420
5361
|
*Powered by [ArchonDev](https://archondev.io)*
|
|
5421
5362
|
`;
|
|
5422
5363
|
await writeFile4(DEPENDENCIES_FILENAME, template, "utf-8");
|
|
5423
|
-
console.log(
|
|
5424
|
-
console.log(
|
|
5364
|
+
console.log(chalk7.green("\u2705 Created DEPENDENCIES.md"));
|
|
5365
|
+
console.log(chalk7.dim("Add your first rule with: archon deps add --source <path> --dependent <path>"));
|
|
5425
5366
|
});
|
|
5426
5367
|
return deps;
|
|
5427
5368
|
}
|
|
@@ -5458,7 +5399,7 @@ function generateYamlFrontmatter(rules) {
|
|
|
5458
5399
|
}
|
|
5459
5400
|
|
|
5460
5401
|
// src/cli/session.ts
|
|
5461
|
-
import
|
|
5402
|
+
import chalk8 from "chalk";
|
|
5462
5403
|
import ora2 from "ora";
|
|
5463
5404
|
import os from "os";
|
|
5464
5405
|
import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
|
|
@@ -5554,13 +5495,13 @@ async function saveSession(name) {
|
|
|
5554
5495
|
spinner.fail(`Failed to save session: ${error.message}`);
|
|
5555
5496
|
return;
|
|
5556
5497
|
}
|
|
5557
|
-
spinner.succeed(
|
|
5498
|
+
spinner.succeed(chalk8.green("Session saved!"));
|
|
5558
5499
|
console.log();
|
|
5559
|
-
console.log(` ID: ${
|
|
5500
|
+
console.log(` ID: ${chalk8.cyan(session.id)}`);
|
|
5560
5501
|
console.log(` Project: ${session.project_name}`);
|
|
5561
5502
|
console.log(` Device: ${session.last_device}`);
|
|
5562
5503
|
console.log();
|
|
5563
|
-
console.log(
|
|
5504
|
+
console.log(chalk8.dim(" Resume on another device: archon session resume " + session.id));
|
|
5564
5505
|
console.log();
|
|
5565
5506
|
} catch (err2) {
|
|
5566
5507
|
spinner.fail("Error saving session");
|
|
@@ -5588,23 +5529,23 @@ async function listSessions() {
|
|
|
5588
5529
|
}
|
|
5589
5530
|
spinner.stop();
|
|
5590
5531
|
if (!sessions || sessions.length === 0) {
|
|
5591
|
-
console.log(
|
|
5592
|
-
console.log(
|
|
5532
|
+
console.log(chalk8.yellow("\nNo saved sessions found.\n"));
|
|
5533
|
+
console.log(chalk8.dim(" Save a session: archon session save [name]\n"));
|
|
5593
5534
|
return;
|
|
5594
5535
|
}
|
|
5595
5536
|
console.log();
|
|
5596
|
-
console.log(
|
|
5537
|
+
console.log(chalk8.bold("\u{1F4C2} Saved Sessions"));
|
|
5597
5538
|
console.log();
|
|
5598
5539
|
for (const session of sessions) {
|
|
5599
5540
|
const date = new Date(session.updated_at).toLocaleDateString();
|
|
5600
|
-
const atomInfo = session.current_atom_id ?
|
|
5541
|
+
const atomInfo = session.current_atom_id ? chalk8.dim(` (atom: ${session.current_atom_id})`) : "";
|
|
5601
5542
|
console.log(
|
|
5602
|
-
` ${
|
|
5543
|
+
` ${chalk8.cyan(session.id.slice(0, 8))} ${session.project_name}${atomInfo}`
|
|
5603
5544
|
);
|
|
5604
|
-
console.log(
|
|
5545
|
+
console.log(chalk8.dim(` ${date} from ${session.last_device || "unknown device"}`));
|
|
5605
5546
|
console.log();
|
|
5606
5547
|
}
|
|
5607
|
-
console.log(
|
|
5548
|
+
console.log(chalk8.dim(" Resume: archon session resume <id>\n"));
|
|
5608
5549
|
} catch (err2) {
|
|
5609
5550
|
spinner.fail("Error fetching sessions");
|
|
5610
5551
|
console.error(err2);
|
|
@@ -5648,13 +5589,13 @@ async function resumeSession(sessionId) {
|
|
|
5648
5589
|
await writeFile5(archPath, session.architecture_snapshot);
|
|
5649
5590
|
}
|
|
5650
5591
|
await supabase.from("sessions").update({ last_device: getDeviceName(), updated_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", session.id);
|
|
5651
|
-
spinner.succeed(
|
|
5592
|
+
spinner.succeed(chalk8.green("Session resumed!"));
|
|
5652
5593
|
console.log();
|
|
5653
5594
|
console.log(` Project: ${session.project_name}`);
|
|
5654
5595
|
console.log(` Current Atom: ${session.current_atom_id || "none"}`);
|
|
5655
5596
|
console.log(` Pending: ${session.pending_atoms.length} atoms`);
|
|
5656
5597
|
console.log();
|
|
5657
|
-
console.log(
|
|
5598
|
+
console.log(chalk8.dim(" Continue working: archon start"));
|
|
5658
5599
|
console.log();
|
|
5659
5600
|
} catch (err2) {
|
|
5660
5601
|
spinner.fail("Error resuming session");
|
|
@@ -5697,7 +5638,7 @@ async function syncSession() {
|
|
|
5697
5638
|
spinner.fail(`Failed to sync: ${error.message}`);
|
|
5698
5639
|
return;
|
|
5699
5640
|
}
|
|
5700
|
-
spinner.succeed(
|
|
5641
|
+
spinner.succeed(chalk8.green("Session synced to cloud"));
|
|
5701
5642
|
} catch (err2) {
|
|
5702
5643
|
spinner.fail("Error syncing session");
|
|
5703
5644
|
console.error(err2);
|
|
@@ -5705,7 +5646,7 @@ async function syncSession() {
|
|
|
5705
5646
|
}
|
|
5706
5647
|
|
|
5707
5648
|
// src/cli/deploy.ts
|
|
5708
|
-
import
|
|
5649
|
+
import chalk9 from "chalk";
|
|
5709
5650
|
import { existsSync as existsSync10 } from "fs";
|
|
5710
5651
|
import { join as join9 } from "path";
|
|
5711
5652
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -5720,46 +5661,46 @@ function detectPlatform(cwd) {
|
|
|
5720
5661
|
}
|
|
5721
5662
|
async function deploy(options) {
|
|
5722
5663
|
const cwd = process.cwd();
|
|
5723
|
-
console.log(
|
|
5664
|
+
console.log(chalk9.blue("Running pre-deploy checks..."));
|
|
5724
5665
|
const platform = options.platform ?? detectPlatform(cwd);
|
|
5725
|
-
console.log(
|
|
5666
|
+
console.log(chalk9.dim(`Detected platform: ${platform}`));
|
|
5726
5667
|
if (options.dryRun) {
|
|
5727
|
-
console.log(
|
|
5668
|
+
console.log(chalk9.dim("Dry run mode - would deploy to:"), platform);
|
|
5728
5669
|
return;
|
|
5729
5670
|
}
|
|
5730
5671
|
switch (platform) {
|
|
5731
5672
|
case "fly":
|
|
5732
|
-
console.log(
|
|
5673
|
+
console.log(chalk9.blue("Deploying to Fly.io..."));
|
|
5733
5674
|
execSync3("fly deploy", { cwd, stdio: "inherit" });
|
|
5734
5675
|
break;
|
|
5735
5676
|
case "vercel": {
|
|
5736
|
-
console.log(
|
|
5677
|
+
console.log(chalk9.blue("Deploying to Vercel..."));
|
|
5737
5678
|
const cmd = options.preview ? "vercel" : "vercel --prod";
|
|
5738
5679
|
execSync3(cmd, { cwd, stdio: "inherit" });
|
|
5739
5680
|
break;
|
|
5740
5681
|
}
|
|
5741
5682
|
case "netlify": {
|
|
5742
|
-
console.log(
|
|
5683
|
+
console.log(chalk9.blue("Deploying to Netlify..."));
|
|
5743
5684
|
const netlifyCmd = options.preview ? "netlify deploy" : "netlify deploy --prod";
|
|
5744
5685
|
execSync3(netlifyCmd, { cwd, stdio: "inherit" });
|
|
5745
5686
|
break;
|
|
5746
5687
|
}
|
|
5747
5688
|
case "railway":
|
|
5748
|
-
console.log(
|
|
5689
|
+
console.log(chalk9.blue("Deploying to Railway..."));
|
|
5749
5690
|
execSync3("railway up", { cwd, stdio: "inherit" });
|
|
5750
5691
|
break;
|
|
5751
5692
|
case "render":
|
|
5752
|
-
console.log(
|
|
5753
|
-
console.log(
|
|
5693
|
+
console.log(chalk9.blue("Deploying to Render..."));
|
|
5694
|
+
console.log(chalk9.yellow("Render deploys via git push. Push to your connected branch."));
|
|
5754
5695
|
break;
|
|
5755
5696
|
default:
|
|
5756
|
-
console.log(
|
|
5757
|
-
console.log(
|
|
5697
|
+
console.log(chalk9.yellow("Platform not detected. Please specify with --platform"));
|
|
5698
|
+
console.log(chalk9.dim("Supported: fly, vercel, netlify, railway, render"));
|
|
5758
5699
|
}
|
|
5759
5700
|
}
|
|
5760
5701
|
|
|
5761
5702
|
// src/cli/index-cmd.ts
|
|
5762
|
-
import
|
|
5703
|
+
import chalk10 from "chalk";
|
|
5763
5704
|
|
|
5764
5705
|
// src/core/indexing/local.ts
|
|
5765
5706
|
import { existsSync as existsSync11, mkdirSync } from "fs";
|
|
@@ -6173,14 +6114,14 @@ async function getCloudIndexer(cwd) {
|
|
|
6173
6114
|
const config = await loadConfig();
|
|
6174
6115
|
const authToken = getAuthToken(config);
|
|
6175
6116
|
if (!authToken) {
|
|
6176
|
-
console.error(
|
|
6117
|
+
console.error(chalk10.red('Not authenticated. Run "archon login" first.'));
|
|
6177
6118
|
return null;
|
|
6178
6119
|
}
|
|
6179
6120
|
const openaiKey = process.env["OPENAI_API_KEY"];
|
|
6180
6121
|
if (!openaiKey) {
|
|
6181
|
-
console.error(
|
|
6182
|
-
console.log(
|
|
6183
|
-
console.log(
|
|
6122
|
+
console.error(chalk10.red("OPENAI_API_KEY environment variable not set."));
|
|
6123
|
+
console.log(chalk10.dim("Cloud indexing requires an OpenAI API key for embeddings."));
|
|
6124
|
+
console.log(chalk10.dim("Set it with: export OPENAI_API_KEY=sk-..."));
|
|
6184
6125
|
return null;
|
|
6185
6126
|
}
|
|
6186
6127
|
const projectId = basename(cwd);
|
|
@@ -6197,12 +6138,12 @@ async function getCloudIndexer(cwd) {
|
|
|
6197
6138
|
});
|
|
6198
6139
|
const { data: { user } } = await client.auth.getUser();
|
|
6199
6140
|
if (!user) {
|
|
6200
|
-
console.error(
|
|
6141
|
+
console.error(chalk10.red("Failed to get user. Try logging in again."));
|
|
6201
6142
|
return null;
|
|
6202
6143
|
}
|
|
6203
6144
|
const { data: profile } = await client.from("user_profiles").select("id").eq("auth_id", user.id).single();
|
|
6204
6145
|
if (!profile) {
|
|
6205
|
-
console.error(
|
|
6146
|
+
console.error(chalk10.red("User profile not found."));
|
|
6206
6147
|
return null;
|
|
6207
6148
|
}
|
|
6208
6149
|
indexer.setUserId(profile.id);
|
|
@@ -6211,21 +6152,21 @@ async function getCloudIndexer(cwd) {
|
|
|
6211
6152
|
async function indexInit(options) {
|
|
6212
6153
|
const cwd = process.cwd();
|
|
6213
6154
|
if (options.cloud) {
|
|
6214
|
-
console.log(
|
|
6155
|
+
console.log(chalk10.blue("Initializing cloud semantic index..."));
|
|
6215
6156
|
const indexer = await getCloudIndexer(cwd);
|
|
6216
6157
|
if (!indexer) return;
|
|
6217
6158
|
try {
|
|
6218
6159
|
const status2 = await indexer.getStatus();
|
|
6219
|
-
console.log(
|
|
6220
|
-
console.log(
|
|
6221
|
-
console.log(
|
|
6160
|
+
console.log(chalk10.green("\u2713 Cloud indexing configured"));
|
|
6161
|
+
console.log(chalk10.green(`\u2713 Project ID: ${status2.projectId}`));
|
|
6162
|
+
console.log(chalk10.dim("\nRun `archon index update --cloud` to index your codebase."));
|
|
6222
6163
|
} catch (error) {
|
|
6223
|
-
console.error(
|
|
6164
|
+
console.error(chalk10.red(`Failed to initialize cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6224
6165
|
process.exit(1);
|
|
6225
6166
|
}
|
|
6226
6167
|
return;
|
|
6227
6168
|
}
|
|
6228
|
-
console.log(
|
|
6169
|
+
console.log(chalk10.blue("Initializing local semantic index..."));
|
|
6229
6170
|
try {
|
|
6230
6171
|
const indexer = new LocalIndexer();
|
|
6231
6172
|
await indexer.init(cwd);
|
|
@@ -6233,18 +6174,18 @@ async function indexInit(options) {
|
|
|
6233
6174
|
if (!response.ok) {
|
|
6234
6175
|
throw new Error("Ollama not responding");
|
|
6235
6176
|
}
|
|
6236
|
-
console.log(
|
|
6237
|
-
console.log(
|
|
6238
|
-
console.log(
|
|
6177
|
+
console.log(chalk10.green("\u2713 Ollama connection verified"));
|
|
6178
|
+
console.log(chalk10.green("\u2713 Index database created at .archon/index.db"));
|
|
6179
|
+
console.log(chalk10.dim("\nRun `archon index update` to index your codebase."));
|
|
6239
6180
|
indexer.close();
|
|
6240
6181
|
} catch (error) {
|
|
6241
6182
|
if (error instanceof Error && error.message.includes("Ollama")) {
|
|
6242
|
-
console.log(
|
|
6243
|
-
console.log(
|
|
6244
|
-
console.log(
|
|
6245
|
-
console.log(
|
|
6183
|
+
console.log(chalk10.red("\n\u2717 Ollama is not running"));
|
|
6184
|
+
console.log(chalk10.dim("Start Ollama with: ollama serve"));
|
|
6185
|
+
console.log(chalk10.dim("Then pull the embedding model: ollama pull nomic-embed-text"));
|
|
6186
|
+
console.log(chalk10.dim("\nOr use cloud indexing: archon index init --cloud"));
|
|
6246
6187
|
} else {
|
|
6247
|
-
console.error(
|
|
6188
|
+
console.error(chalk10.red(`Failed to initialize index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6248
6189
|
}
|
|
6249
6190
|
process.exit(1);
|
|
6250
6191
|
}
|
|
@@ -6252,7 +6193,7 @@ async function indexInit(options) {
|
|
|
6252
6193
|
async function indexUpdate(options) {
|
|
6253
6194
|
const cwd = process.cwd();
|
|
6254
6195
|
if (options?.cloud) {
|
|
6255
|
-
console.log(
|
|
6196
|
+
console.log(chalk10.blue("Updating cloud semantic index..."));
|
|
6256
6197
|
const indexer = await getCloudIndexer(cwd);
|
|
6257
6198
|
if (!indexer) return;
|
|
6258
6199
|
try {
|
|
@@ -6260,15 +6201,15 @@ async function indexUpdate(options) {
|
|
|
6260
6201
|
cwd,
|
|
6261
6202
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6262
6203
|
});
|
|
6263
|
-
console.log(
|
|
6264
|
-
console.log(
|
|
6204
|
+
console.log(chalk10.dim(`Found ${files.length} files to index...`));
|
|
6205
|
+
console.log(chalk10.dim("This may take a few minutes and will use OpenAI API credits.\n"));
|
|
6265
6206
|
let totalChunks = 0;
|
|
6266
6207
|
let indexedFiles = 0;
|
|
6267
6208
|
let skippedFiles = 0;
|
|
6268
6209
|
for (let i = 0; i < files.length; i++) {
|
|
6269
6210
|
const file = files[i];
|
|
6270
6211
|
if (!file) continue;
|
|
6271
|
-
process.stdout.write(`\r${
|
|
6212
|
+
process.stdout.write(`\r${chalk10.dim(`[${i + 1}/${files.length}] ${file.slice(0, 45).padEnd(45)}`)}`);
|
|
6272
6213
|
try {
|
|
6273
6214
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6274
6215
|
if (chunks > 0) {
|
|
@@ -6279,21 +6220,21 @@ async function indexUpdate(options) {
|
|
|
6279
6220
|
}
|
|
6280
6221
|
} catch (error) {
|
|
6281
6222
|
console.log(`
|
|
6282
|
-
${
|
|
6223
|
+
${chalk10.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message : "Unknown error"}`)}`);
|
|
6283
6224
|
}
|
|
6284
6225
|
}
|
|
6285
6226
|
console.log("\r" + " ".repeat(70));
|
|
6286
|
-
console.log(
|
|
6227
|
+
console.log(chalk10.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6287
6228
|
if (skippedFiles > 0) {
|
|
6288
|
-
console.log(
|
|
6229
|
+
console.log(chalk10.dim(` Skipped ${skippedFiles} unchanged files`));
|
|
6289
6230
|
}
|
|
6290
6231
|
} catch (error) {
|
|
6291
|
-
console.error(
|
|
6232
|
+
console.error(chalk10.red(`Failed to update cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6292
6233
|
process.exit(1);
|
|
6293
6234
|
}
|
|
6294
6235
|
return;
|
|
6295
6236
|
}
|
|
6296
|
-
console.log(
|
|
6237
|
+
console.log(chalk10.blue("Updating local semantic index..."));
|
|
6297
6238
|
try {
|
|
6298
6239
|
const indexer = new LocalIndexer();
|
|
6299
6240
|
await indexer.init(cwd);
|
|
@@ -6301,12 +6242,12 @@ ${chalk11.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6301
6242
|
cwd,
|
|
6302
6243
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**", "**/build/**", "**/coverage/**"]
|
|
6303
6244
|
});
|
|
6304
|
-
console.log(
|
|
6245
|
+
console.log(chalk10.dim(`Found ${files.length} files to index...`));
|
|
6305
6246
|
let totalChunks = 0;
|
|
6306
6247
|
let indexedFiles = 0;
|
|
6307
6248
|
for (const file of files) {
|
|
6308
6249
|
if (!file) continue;
|
|
6309
|
-
process.stdout.write(`\r${
|
|
6250
|
+
process.stdout.write(`\r${chalk10.dim(`Indexing: ${file.slice(0, 50).padEnd(50)}`)}`);
|
|
6310
6251
|
const chunks = await indexer.indexFile(cwd, file);
|
|
6311
6252
|
if (chunks > 0) {
|
|
6312
6253
|
totalChunks += chunks;
|
|
@@ -6314,10 +6255,10 @@ ${chalk11.yellow(`[!] Skipped ${file}: ${error instanceof Error ? error.message
|
|
|
6314
6255
|
}
|
|
6315
6256
|
}
|
|
6316
6257
|
console.log("\r" + " ".repeat(60));
|
|
6317
|
-
console.log(
|
|
6258
|
+
console.log(chalk10.green(`\u2713 Indexed ${indexedFiles} files (${totalChunks} chunks)`));
|
|
6318
6259
|
indexer.close();
|
|
6319
6260
|
} catch (error) {
|
|
6320
|
-
console.error(
|
|
6261
|
+
console.error(chalk10.red(`Failed to update index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6321
6262
|
process.exit(1);
|
|
6322
6263
|
}
|
|
6323
6264
|
}
|
|
@@ -6327,25 +6268,25 @@ async function indexSearch(query, options) {
|
|
|
6327
6268
|
const indexer = await getCloudIndexer(cwd);
|
|
6328
6269
|
if (!indexer) return;
|
|
6329
6270
|
try {
|
|
6330
|
-
console.log(
|
|
6271
|
+
console.log(chalk10.dim("Searching cloud index..."));
|
|
6331
6272
|
const results = await indexer.search(query, 10);
|
|
6332
6273
|
if (results.length === 0) {
|
|
6333
|
-
console.log(
|
|
6334
|
-
console.log(
|
|
6274
|
+
console.log(chalk10.yellow("\nNo results found."));
|
|
6275
|
+
console.log(chalk10.dim("Try running `archon index update --cloud` first."));
|
|
6335
6276
|
} else {
|
|
6336
|
-
console.log(
|
|
6277
|
+
console.log(chalk10.blue(`
|
|
6337
6278
|
Top ${results.length} results for: "${query}"
|
|
6338
6279
|
`));
|
|
6339
6280
|
for (const result of results) {
|
|
6340
6281
|
const score = (result.score * 100).toFixed(1);
|
|
6341
|
-
console.log(
|
|
6282
|
+
console.log(chalk10.green(`[${score}%] ${result.file}`));
|
|
6342
6283
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6343
|
-
console.log(
|
|
6284
|
+
console.log(chalk10.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6344
6285
|
console.log();
|
|
6345
6286
|
}
|
|
6346
6287
|
}
|
|
6347
6288
|
} catch (error) {
|
|
6348
|
-
console.error(
|
|
6289
|
+
console.error(chalk10.red(`Cloud search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6349
6290
|
process.exit(1);
|
|
6350
6291
|
}
|
|
6351
6292
|
return;
|
|
@@ -6355,23 +6296,23 @@ Top ${results.length} results for: "${query}"
|
|
|
6355
6296
|
await indexer.init(cwd);
|
|
6356
6297
|
const results = await indexer.search(query, 10);
|
|
6357
6298
|
if (results.length === 0) {
|
|
6358
|
-
console.log(
|
|
6359
|
-
console.log(
|
|
6299
|
+
console.log(chalk10.yellow("No results found."));
|
|
6300
|
+
console.log(chalk10.dim("Try running `archon index update` first."));
|
|
6360
6301
|
} else {
|
|
6361
|
-
console.log(
|
|
6302
|
+
console.log(chalk10.blue(`
|
|
6362
6303
|
Top ${results.length} results for: "${query}"
|
|
6363
6304
|
`));
|
|
6364
6305
|
for (const result of results) {
|
|
6365
6306
|
const score = (result.score * 100).toFixed(1);
|
|
6366
|
-
console.log(
|
|
6307
|
+
console.log(chalk10.green(`[${score}%] ${result.file}`));
|
|
6367
6308
|
const preview = result.text.slice(0, 200).replace(/\n/g, " ").trim();
|
|
6368
|
-
console.log(
|
|
6309
|
+
console.log(chalk10.dim(` ${preview}${result.text.length > 200 ? "..." : ""}`));
|
|
6369
6310
|
console.log();
|
|
6370
6311
|
}
|
|
6371
6312
|
}
|
|
6372
6313
|
indexer.close();
|
|
6373
6314
|
} catch (error) {
|
|
6374
|
-
console.error(
|
|
6315
|
+
console.error(chalk10.red(`Search failed: ${error instanceof Error ? error.message : String(error)}`));
|
|
6375
6316
|
process.exit(1);
|
|
6376
6317
|
}
|
|
6377
6318
|
}
|
|
@@ -6382,17 +6323,17 @@ async function indexStatus(options) {
|
|
|
6382
6323
|
if (!indexer) return;
|
|
6383
6324
|
try {
|
|
6384
6325
|
const status2 = await indexer.getStatus();
|
|
6385
|
-
console.log(
|
|
6386
|
-
console.log(` Project ID: ${
|
|
6387
|
-
console.log(` Files indexed: ${
|
|
6388
|
-
console.log(` Total chunks: ${
|
|
6389
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6326
|
+
console.log(chalk10.blue("\nCloud Semantic Index Status\n"));
|
|
6327
|
+
console.log(` Project ID: ${chalk10.green(status2.projectId)}`);
|
|
6328
|
+
console.log(` Files indexed: ${chalk10.green(status2.fileCount)}`);
|
|
6329
|
+
console.log(` Total chunks: ${chalk10.green(status2.chunkCount)}`);
|
|
6330
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk10.dim(status2.lastUpdated) : chalk10.yellow("Never")}`);
|
|
6390
6331
|
if (status2.jobStatus) {
|
|
6391
|
-
console.log(` Job status: ${
|
|
6332
|
+
console.log(` Job status: ${chalk10.dim(status2.jobStatus)}`);
|
|
6392
6333
|
}
|
|
6393
|
-
console.log(` Storage: ${
|
|
6334
|
+
console.log(` Storage: ${chalk10.dim("Supabase pgvector")}`);
|
|
6394
6335
|
} catch (error) {
|
|
6395
|
-
console.error(
|
|
6336
|
+
console.error(chalk10.red(`Failed to get cloud status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6396
6337
|
process.exit(1);
|
|
6397
6338
|
}
|
|
6398
6339
|
return;
|
|
@@ -6401,14 +6342,14 @@ async function indexStatus(options) {
|
|
|
6401
6342
|
const indexer = new LocalIndexer();
|
|
6402
6343
|
await indexer.init(cwd);
|
|
6403
6344
|
const status2 = await indexer.getStatus();
|
|
6404
|
-
console.log(
|
|
6405
|
-
console.log(` Files indexed: ${
|
|
6406
|
-
console.log(` Total chunks: ${
|
|
6407
|
-
console.log(` Last updated: ${status2.lastUpdated ?
|
|
6408
|
-
console.log(` Database: ${
|
|
6345
|
+
console.log(chalk10.blue("\nLocal Semantic Index Status\n"));
|
|
6346
|
+
console.log(` Files indexed: ${chalk10.green(status2.fileCount)}`);
|
|
6347
|
+
console.log(` Total chunks: ${chalk10.green(status2.chunkCount)}`);
|
|
6348
|
+
console.log(` Last updated: ${status2.lastUpdated ? chalk10.dim(status2.lastUpdated) : chalk10.yellow("Never")}`);
|
|
6349
|
+
console.log(` Database: ${chalk10.dim(join12(cwd, ".archon/index.db"))}`);
|
|
6409
6350
|
indexer.close();
|
|
6410
6351
|
} catch (error) {
|
|
6411
|
-
console.error(
|
|
6352
|
+
console.error(chalk10.red(`Failed to get status: ${error instanceof Error ? error.message : String(error)}`));
|
|
6412
6353
|
process.exit(1);
|
|
6413
6354
|
}
|
|
6414
6355
|
}
|
|
@@ -6418,30 +6359,30 @@ async function indexClear(options) {
|
|
|
6418
6359
|
const indexer = await getCloudIndexer(cwd);
|
|
6419
6360
|
if (!indexer) return;
|
|
6420
6361
|
try {
|
|
6421
|
-
console.log(
|
|
6362
|
+
console.log(chalk10.yellow("Clearing cloud index..."));
|
|
6422
6363
|
await indexer.clearProject();
|
|
6423
|
-
console.log(
|
|
6364
|
+
console.log(chalk10.green("\u2713 Cloud index cleared"));
|
|
6424
6365
|
} catch (error) {
|
|
6425
|
-
console.error(
|
|
6366
|
+
console.error(chalk10.red(`Failed to clear cloud index: ${error instanceof Error ? error.message : String(error)}`));
|
|
6426
6367
|
process.exit(1);
|
|
6427
6368
|
}
|
|
6428
6369
|
return;
|
|
6429
6370
|
}
|
|
6430
|
-
console.log(
|
|
6371
|
+
console.log(chalk10.yellow("To clear local index, delete .archon/index.db"));
|
|
6431
6372
|
}
|
|
6432
6373
|
|
|
6433
6374
|
// src/cli/github.ts
|
|
6434
|
-
import
|
|
6375
|
+
import chalk11 from "chalk";
|
|
6435
6376
|
import open2 from "open";
|
|
6436
6377
|
var API_URL2 = process.env["ARCHONDEV_API_URL"] ?? "https://archondev-api.fly.dev";
|
|
6437
6378
|
async function githubConnect() {
|
|
6438
6379
|
const config = await loadConfig();
|
|
6439
6380
|
const authToken = getAuthToken(config);
|
|
6440
6381
|
if (!authToken) {
|
|
6441
|
-
console.error(
|
|
6382
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6442
6383
|
process.exit(1);
|
|
6443
6384
|
}
|
|
6444
|
-
console.log(
|
|
6385
|
+
console.log(chalk11.dim("Starting GitHub connection..."));
|
|
6445
6386
|
try {
|
|
6446
6387
|
const response = await fetch(`${API_URL2}/api/github/connect`, {
|
|
6447
6388
|
headers: {
|
|
@@ -6450,18 +6391,18 @@ async function githubConnect() {
|
|
|
6450
6391
|
});
|
|
6451
6392
|
if (!response.ok) {
|
|
6452
6393
|
const error = await response.json();
|
|
6453
|
-
console.error(
|
|
6394
|
+
console.error(chalk11.red(error.error ?? "Failed to start GitHub connection"));
|
|
6454
6395
|
process.exit(1);
|
|
6455
6396
|
}
|
|
6456
6397
|
const data = await response.json();
|
|
6457
|
-
console.log(
|
|
6458
|
-
console.log(
|
|
6459
|
-
console.log(
|
|
6398
|
+
console.log(chalk11.dim("\nOpening browser for GitHub authorization..."));
|
|
6399
|
+
console.log(chalk11.dim("If browser does not open, visit:"));
|
|
6400
|
+
console.log(chalk11.blue(data.url));
|
|
6460
6401
|
await open2(data.url);
|
|
6461
|
-
console.log(
|
|
6462
|
-
console.log(
|
|
6402
|
+
console.log(chalk11.dim("\nComplete the authorization in your browser."));
|
|
6403
|
+
console.log(chalk11.dim('Then run "archon github status" to verify connection.'));
|
|
6463
6404
|
} catch (error) {
|
|
6464
|
-
console.error(
|
|
6405
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to connect"));
|
|
6465
6406
|
process.exit(1);
|
|
6466
6407
|
}
|
|
6467
6408
|
}
|
|
@@ -6469,7 +6410,7 @@ async function githubStatus() {
|
|
|
6469
6410
|
const config = await loadConfig();
|
|
6470
6411
|
const authToken = getAuthToken(config);
|
|
6471
6412
|
if (!authToken) {
|
|
6472
|
-
console.error(
|
|
6413
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6473
6414
|
process.exit(1);
|
|
6474
6415
|
}
|
|
6475
6416
|
try {
|
|
@@ -6480,20 +6421,20 @@ async function githubStatus() {
|
|
|
6480
6421
|
});
|
|
6481
6422
|
if (!response.ok) {
|
|
6482
6423
|
const error = await response.json();
|
|
6483
|
-
console.error(
|
|
6424
|
+
console.error(chalk11.red(error.error ?? "Failed to get GitHub status"));
|
|
6484
6425
|
process.exit(1);
|
|
6485
6426
|
}
|
|
6486
6427
|
const data = await response.json();
|
|
6487
6428
|
if (data.connected) {
|
|
6488
|
-
console.log(
|
|
6489
|
-
console.log(
|
|
6490
|
-
console.log(
|
|
6429
|
+
console.log(chalk11.green("\u2713 GitHub connected"));
|
|
6430
|
+
console.log(chalk11.dim(` Username: ${data.username}`));
|
|
6431
|
+
console.log(chalk11.dim(` Connected: ${data.connectedAt ? new Date(data.connectedAt).toLocaleDateString() : "Unknown"}`));
|
|
6491
6432
|
} else {
|
|
6492
|
-
console.log(
|
|
6493
|
-
console.log(
|
|
6433
|
+
console.log(chalk11.yellow("GitHub not connected"));
|
|
6434
|
+
console.log(chalk11.dim('Run "archon github connect" to connect your GitHub account.'));
|
|
6494
6435
|
}
|
|
6495
6436
|
} catch (error) {
|
|
6496
|
-
console.error(
|
|
6437
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to get status"));
|
|
6497
6438
|
process.exit(1);
|
|
6498
6439
|
}
|
|
6499
6440
|
}
|
|
@@ -6501,7 +6442,7 @@ async function githubDisconnect() {
|
|
|
6501
6442
|
const config = await loadConfig();
|
|
6502
6443
|
const authToken = getAuthToken(config);
|
|
6503
6444
|
if (!authToken) {
|
|
6504
|
-
console.error(
|
|
6445
|
+
console.error(chalk11.red('Not authenticated. Run "archon login" first.'));
|
|
6505
6446
|
process.exit(1);
|
|
6506
6447
|
}
|
|
6507
6448
|
try {
|
|
@@ -6513,18 +6454,18 @@ async function githubDisconnect() {
|
|
|
6513
6454
|
});
|
|
6514
6455
|
if (!response.ok) {
|
|
6515
6456
|
const error = await response.json();
|
|
6516
|
-
console.error(
|
|
6457
|
+
console.error(chalk11.red(error.error ?? "Failed to disconnect GitHub"));
|
|
6517
6458
|
process.exit(1);
|
|
6518
6459
|
}
|
|
6519
|
-
console.log(
|
|
6460
|
+
console.log(chalk11.green("\u2713 GitHub disconnected"));
|
|
6520
6461
|
} catch (error) {
|
|
6521
|
-
console.error(
|
|
6462
|
+
console.error(chalk11.red(error instanceof Error ? error.message : "Failed to disconnect"));
|
|
6522
6463
|
process.exit(1);
|
|
6523
6464
|
}
|
|
6524
6465
|
}
|
|
6525
6466
|
|
|
6526
6467
|
// src/cli/interview.ts
|
|
6527
|
-
import
|
|
6468
|
+
import chalk12 from "chalk";
|
|
6528
6469
|
import readline3 from "readline";
|
|
6529
6470
|
import ora3 from "ora";
|
|
6530
6471
|
import { existsSync as existsSync13, readFileSync as readFileSync5, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
@@ -6542,23 +6483,23 @@ async function interview(options = {}) {
|
|
|
6542
6483
|
if (!existsSync13(archonDir)) {
|
|
6543
6484
|
mkdirSync2(archonDir, { recursive: true });
|
|
6544
6485
|
}
|
|
6545
|
-
console.log(
|
|
6546
|
-
console.log(
|
|
6486
|
+
console.log(chalk12.bold("\n\u{1F3AF} ArchonDev Project Interview"));
|
|
6487
|
+
console.log(chalk12.dim("Let's define what you're building.\n"));
|
|
6547
6488
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6548
6489
|
const draftPath = getDraftPath(cwd);
|
|
6549
6490
|
if (existsSync13(constitutionPath)) {
|
|
6550
6491
|
const existing = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
6551
6492
|
if (existing.state === "FROZEN") {
|
|
6552
|
-
console.log(
|
|
6553
|
-
console.log(
|
|
6554
|
-
console.log(
|
|
6493
|
+
console.log(chalk12.yellow("[!] A frozen Constitution already exists."));
|
|
6494
|
+
console.log(chalk12.dim(` Project: ${existing.branding.projectName}`));
|
|
6495
|
+
console.log(chalk12.dim(` Frozen: ${existing.frozenAt?.toISOString()}`));
|
|
6555
6496
|
console.log();
|
|
6556
6497
|
const action = await prompt2("Start a new interview (overwrite) or view existing? (new/view)");
|
|
6557
6498
|
if (action.toLowerCase() === "view") {
|
|
6558
6499
|
console.log("\n" + summarizeConstitution(existing));
|
|
6559
6500
|
return;
|
|
6560
6501
|
} else if (action.toLowerCase() !== "new") {
|
|
6561
|
-
console.log(
|
|
6502
|
+
console.log(chalk12.dim("Cancelled."));
|
|
6562
6503
|
return;
|
|
6563
6504
|
}
|
|
6564
6505
|
}
|
|
@@ -6567,8 +6508,8 @@ async function interview(options = {}) {
|
|
|
6567
6508
|
let startPhase = 1;
|
|
6568
6509
|
if (existsSync13(draftPath) && options.resume !== false) {
|
|
6569
6510
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
6570
|
-
console.log(
|
|
6571
|
-
console.log(
|
|
6511
|
+
console.log(chalk12.blue("[i] Found draft from previous session."));
|
|
6512
|
+
console.log(chalk12.dim(` Project: ${draft.branding.projectName || "(unnamed)"}`));
|
|
6572
6513
|
console.log();
|
|
6573
6514
|
const resumeChoice = await prompt2("Resume draft or start fresh? (resume/fresh)");
|
|
6574
6515
|
if (resumeChoice.toLowerCase() === "resume") {
|
|
@@ -6580,7 +6521,7 @@ async function interview(options = {}) {
|
|
|
6580
6521
|
break;
|
|
6581
6522
|
}
|
|
6582
6523
|
}
|
|
6583
|
-
console.log(
|
|
6524
|
+
console.log(chalk12.green(`
|
|
6584
6525
|
\u2713 Resuming at Phase ${startPhase}: ${INTERVIEW_PHASES[startPhase]?.name}
|
|
6585
6526
|
`));
|
|
6586
6527
|
} else {
|
|
@@ -6591,19 +6532,19 @@ async function interview(options = {}) {
|
|
|
6591
6532
|
}
|
|
6592
6533
|
if (options.phase && options.phase >= 1 && options.phase <= 5) {
|
|
6593
6534
|
startPhase = options.phase;
|
|
6594
|
-
console.log(
|
|
6535
|
+
console.log(chalk12.dim(`Starting at Phase ${startPhase}...
|
|
6595
6536
|
`));
|
|
6596
6537
|
}
|
|
6597
|
-
console.log(
|
|
6598
|
-
console.log(
|
|
6599
|
-
console.log(
|
|
6538
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6539
|
+
console.log(chalk12.dim(formatProgressBar(startPhase)));
|
|
6540
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6600
6541
|
console.log();
|
|
6601
6542
|
let currentPhase = startPhase;
|
|
6602
6543
|
while (currentPhase <= 5) {
|
|
6603
6544
|
const result = await runPhase(currentPhase, constitution, cwd);
|
|
6604
6545
|
if (result.action === "exit") {
|
|
6605
6546
|
saveDraft(cwd, constitution);
|
|
6606
|
-
console.log(
|
|
6547
|
+
console.log(chalk12.dim("\nDraft saved. Run `archon interview` to resume.\n"));
|
|
6607
6548
|
return;
|
|
6608
6549
|
}
|
|
6609
6550
|
if (result.action === "back" && currentPhase > 1) {
|
|
@@ -6618,9 +6559,9 @@ async function interview(options = {}) {
|
|
|
6618
6559
|
if (next) {
|
|
6619
6560
|
currentPhase = next;
|
|
6620
6561
|
console.log();
|
|
6621
|
-
console.log(
|
|
6622
|
-
console.log(
|
|
6623
|
-
console.log(
|
|
6562
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6563
|
+
console.log(chalk12.dim(formatProgressBar(currentPhase)));
|
|
6564
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6624
6565
|
console.log();
|
|
6625
6566
|
} else {
|
|
6626
6567
|
break;
|
|
@@ -6628,9 +6569,9 @@ async function interview(options = {}) {
|
|
|
6628
6569
|
}
|
|
6629
6570
|
const validationResult = validateConstitution(constitution);
|
|
6630
6571
|
if (!validationResult.valid) {
|
|
6631
|
-
console.log(
|
|
6572
|
+
console.log(chalk12.red("\n[!] Constitution has validation errors:\n"));
|
|
6632
6573
|
for (const error of validationResult.errors) {
|
|
6633
|
-
console.log(
|
|
6574
|
+
console.log(chalk12.red(` \u2022 ${error}`));
|
|
6634
6575
|
}
|
|
6635
6576
|
console.log();
|
|
6636
6577
|
const fix = await promptYesNo3("Would you like to go back and fix these?", true);
|
|
@@ -6640,9 +6581,9 @@ async function interview(options = {}) {
|
|
|
6640
6581
|
}
|
|
6641
6582
|
}
|
|
6642
6583
|
if (validationResult.warnings.length > 0) {
|
|
6643
|
-
console.log(
|
|
6584
|
+
console.log(chalk12.yellow("\n[!] Warnings:\n"));
|
|
6644
6585
|
for (const warning of validationResult.warnings) {
|
|
6645
|
-
console.log(
|
|
6586
|
+
console.log(chalk12.yellow(` \u2022 ${warning}`));
|
|
6646
6587
|
}
|
|
6647
6588
|
console.log();
|
|
6648
6589
|
}
|
|
@@ -6652,21 +6593,21 @@ async function interview(options = {}) {
|
|
|
6652
6593
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
6653
6594
|
const challengeResult = analyzeForChallenges(constitution);
|
|
6654
6595
|
if (challengeResult.shouldChallenge) {
|
|
6655
|
-
console.log(
|
|
6656
|
-
console.log(
|
|
6596
|
+
console.log(chalk12.bold("\n\u{1F3AF} Challenge Mode\n"));
|
|
6597
|
+
console.log(chalk12.dim("Let me share some observations about your project scope...\n"));
|
|
6657
6598
|
for (const challenge of challengeResult.challenges) {
|
|
6658
6599
|
const prompt3 = generateChallengePrompt(challenge);
|
|
6659
|
-
const icon = challenge.severity === "critical" ?
|
|
6660
|
-
console.log(`${icon} ${
|
|
6661
|
-
console.log(
|
|
6600
|
+
const icon = challenge.severity === "critical" ? chalk12.red("\u25CF") : chalk12.yellow("\u25CF");
|
|
6601
|
+
console.log(`${icon} ${chalk12.bold(challenge.title)}`);
|
|
6602
|
+
console.log(chalk12.dim(` ${prompt3}`));
|
|
6662
6603
|
console.log();
|
|
6663
6604
|
}
|
|
6664
|
-
console.log(
|
|
6605
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6665
6606
|
console.log(summarizeChallenges(challengeResult));
|
|
6666
|
-
console.log(
|
|
6607
|
+
console.log(chalk12.dim("\u2500".repeat(40)));
|
|
6667
6608
|
console.log();
|
|
6668
6609
|
if (challengeResult.featuresToDefer.length > 0) {
|
|
6669
|
-
console.log(
|
|
6610
|
+
console.log(chalk12.bold("Suggested Features to Defer to Post-MVP:\n"));
|
|
6670
6611
|
for (const feature of challengeResult.featuresToDefer) {
|
|
6671
6612
|
console.log(` \u2022 ${feature.name}`);
|
|
6672
6613
|
}
|
|
@@ -6681,39 +6622,39 @@ async function interview(options = {}) {
|
|
|
6681
6622
|
constitution.complexity = calculateComplexity(constitution);
|
|
6682
6623
|
constitution.estimatedBuildHours = estimateBuildHours(constitution.complexity);
|
|
6683
6624
|
constitution.costs = estimateCosts(constitution, config.tier || "FREE");
|
|
6684
|
-
console.log(
|
|
6685
|
-
console.log(
|
|
6686
|
-
console.log(
|
|
6625
|
+
console.log(chalk12.green("\n\u2713 Features deferred. Updated estimates:"));
|
|
6626
|
+
console.log(chalk12.dim(` Complexity: ${constitution.complexity.tier}`));
|
|
6627
|
+
console.log(chalk12.dim(` Build time: ~${Math.round(constitution.estimatedBuildHours)} hours`));
|
|
6687
6628
|
console.log();
|
|
6688
6629
|
saveDraft(cwd, constitution);
|
|
6689
6630
|
}
|
|
6690
6631
|
}
|
|
6691
6632
|
const criticalCount = challengeResult.challenges.filter((c) => c.severity === "critical").length;
|
|
6692
6633
|
if (criticalCount > 0) {
|
|
6693
|
-
console.log(
|
|
6634
|
+
console.log(chalk12.red(`
|
|
6694
6635
|
\u26A0\uFE0F ${criticalCount} critical issue(s) detected.`));
|
|
6695
6636
|
const proceed = await promptYesNo3("Proceed anyway?", false);
|
|
6696
6637
|
if (!proceed) {
|
|
6697
6638
|
saveDraft(cwd, constitution);
|
|
6698
|
-
console.log(
|
|
6639
|
+
console.log(chalk12.dim("\nDraft saved. Address the issues and run `archon interview` again.\n"));
|
|
6699
6640
|
return;
|
|
6700
6641
|
}
|
|
6701
6642
|
}
|
|
6702
6643
|
} else {
|
|
6703
|
-
console.log(
|
|
6644
|
+
console.log(chalk12.green("\n\u2713 Scope looks reasonable! No major concerns detected.\n"));
|
|
6704
6645
|
}
|
|
6705
|
-
console.log(
|
|
6646
|
+
console.log(chalk12.bold("\n\u{1F4CB} Constitution Summary\n"));
|
|
6706
6647
|
console.log(summarizeConstitution(constitution));
|
|
6707
6648
|
console.log();
|
|
6708
6649
|
if (options.dryRun) {
|
|
6709
|
-
console.log(
|
|
6650
|
+
console.log(chalk12.dim("(Dry run mode - not freezing Constitution)"));
|
|
6710
6651
|
saveDraft(cwd, constitution);
|
|
6711
6652
|
return;
|
|
6712
6653
|
}
|
|
6713
6654
|
const confirmFreeze = await promptYesNo3("Freeze this Constitution and start building?", true);
|
|
6714
6655
|
if (!confirmFreeze) {
|
|
6715
6656
|
saveDraft(cwd, constitution);
|
|
6716
|
-
console.log(
|
|
6657
|
+
console.log(chalk12.dim("\nDraft saved. Run `archon interview` to continue.\n"));
|
|
6717
6658
|
return;
|
|
6718
6659
|
}
|
|
6719
6660
|
const spinner = ora3("Freezing Constitution...").start();
|
|
@@ -6724,15 +6665,15 @@ async function interview(options = {}) {
|
|
|
6724
6665
|
const { unlinkSync } = await import("fs");
|
|
6725
6666
|
unlinkSync(draftPath);
|
|
6726
6667
|
}
|
|
6727
|
-
spinner.succeed(
|
|
6668
|
+
spinner.succeed(chalk12.green("Constitution frozen!"));
|
|
6728
6669
|
console.log();
|
|
6729
|
-
console.log(
|
|
6730
|
-
console.log(
|
|
6670
|
+
console.log(chalk12.dim(`Hash: ${frozen.hash?.substring(0, 32)}...`));
|
|
6671
|
+
console.log(chalk12.dim(`Saved: ${constitutionPath}`));
|
|
6731
6672
|
console.log();
|
|
6732
|
-
console.log(
|
|
6733
|
-
console.log(` ${
|
|
6734
|
-
console.log(` ${
|
|
6735
|
-
console.log(` ${
|
|
6673
|
+
console.log(chalk12.bold("Next Steps:\n"));
|
|
6674
|
+
console.log(` ${chalk12.cyan("1.")} Run ${chalk12.bold("archon generate")} to create atoms from this Constitution`);
|
|
6675
|
+
console.log(` ${chalk12.cyan("2.")} Run ${chalk12.bold("archon list")} to see generated atoms`);
|
|
6676
|
+
console.log(` ${chalk12.cyan("3.")} Run ${chalk12.bold("archon execute <atom-id>")} to start building`);
|
|
6736
6677
|
console.log();
|
|
6737
6678
|
} catch (err2) {
|
|
6738
6679
|
spinner.fail("Failed to freeze Constitution");
|
|
@@ -6741,18 +6682,18 @@ async function interview(options = {}) {
|
|
|
6741
6682
|
}
|
|
6742
6683
|
async function runPhase(phase, constitution, cwd) {
|
|
6743
6684
|
const phaseInfo = INTERVIEW_PHASES[phase];
|
|
6744
|
-
console.log(
|
|
6745
|
-
console.log(
|
|
6685
|
+
console.log(chalk12.bold(`Phase ${phase}: ${phaseInfo.name}`));
|
|
6686
|
+
console.log(chalk12.dim(phaseInfo.description));
|
|
6746
6687
|
console.log();
|
|
6747
6688
|
const skippable = getSkippableQuestions(phase, constitution);
|
|
6748
6689
|
let updatedConstitution = { ...constitution };
|
|
6749
6690
|
for (const question of phaseInfo.questions) {
|
|
6750
6691
|
if (skippable.includes(question.id)) {
|
|
6751
|
-
console.log(
|
|
6692
|
+
console.log(chalk12.dim(`[\u2713] ${question.prompt.split("?")[0]}... (already answered)`));
|
|
6752
6693
|
continue;
|
|
6753
6694
|
}
|
|
6754
6695
|
if (phase === 5 && question.id === "review_summary") {
|
|
6755
|
-
console.log(
|
|
6696
|
+
console.log(chalk12.bold("\n\u{1F4CB} Current State:\n"));
|
|
6756
6697
|
console.log(summarizeConstitution(updatedConstitution));
|
|
6757
6698
|
console.log();
|
|
6758
6699
|
}
|
|
@@ -6769,14 +6710,14 @@ async function runPhase(phase, constitution, cwd) {
|
|
|
6769
6710
|
if (question.validator) {
|
|
6770
6711
|
const validation = question.validator(answer);
|
|
6771
6712
|
if (!validation.valid) {
|
|
6772
|
-
console.log(
|
|
6713
|
+
console.log(chalk12.red(` ${validation.error}`));
|
|
6773
6714
|
continue;
|
|
6774
6715
|
}
|
|
6775
6716
|
}
|
|
6776
6717
|
const extracted = question.extractor(answer, updatedConstitution);
|
|
6777
6718
|
updatedConstitution = { ...updatedConstitution, ...extracted };
|
|
6778
6719
|
if (question.followUp && answer.length > 10) {
|
|
6779
|
-
console.log(
|
|
6720
|
+
console.log(chalk12.dim(` ${question.followUp}`));
|
|
6780
6721
|
}
|
|
6781
6722
|
}
|
|
6782
6723
|
return { action: "next", constitution: updatedConstitution };
|
|
@@ -6786,7 +6727,7 @@ function saveDraft(cwd, constitution) {
|
|
|
6786
6727
|
writeFileSync(draftPath, serializeConstitution(constitution));
|
|
6787
6728
|
}
|
|
6788
6729
|
async function promptQuestion(question) {
|
|
6789
|
-
const prefix = question.required ?
|
|
6730
|
+
const prefix = question.required ? chalk12.red("*") : " ";
|
|
6790
6731
|
return prompt2(`${prefix} ${question.prompt}`);
|
|
6791
6732
|
}
|
|
6792
6733
|
function prompt2(question) {
|
|
@@ -6795,7 +6736,7 @@ function prompt2(question) {
|
|
|
6795
6736
|
input: process.stdin,
|
|
6796
6737
|
output: process.stdout
|
|
6797
6738
|
});
|
|
6798
|
-
rl.question(`${
|
|
6739
|
+
rl.question(`${chalk12.cyan("?")} ${question}
|
|
6799
6740
|
> `, (answer) => {
|
|
6800
6741
|
rl.close();
|
|
6801
6742
|
resolve(answer.trim());
|
|
@@ -6809,7 +6750,7 @@ function promptYesNo3(question, defaultValue) {
|
|
|
6809
6750
|
output: process.stdout
|
|
6810
6751
|
});
|
|
6811
6752
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
6812
|
-
rl.question(`${
|
|
6753
|
+
rl.question(`${chalk12.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
6813
6754
|
rl.close();
|
|
6814
6755
|
if (answer.trim() === "") {
|
|
6815
6756
|
resolve(defaultValue);
|
|
@@ -6828,10 +6769,10 @@ async function showConstitution() {
|
|
|
6828
6769
|
console.log(summarizeConstitution(constitution));
|
|
6829
6770
|
} else if (existsSync13(draftPath)) {
|
|
6830
6771
|
const draft = deserializeConstitution(readFileSync5(draftPath, "utf-8"));
|
|
6831
|
-
console.log(
|
|
6772
|
+
console.log(chalk12.yellow("[DRAFT]"));
|
|
6832
6773
|
console.log(summarizeConstitution(draft));
|
|
6833
6774
|
} else {
|
|
6834
|
-
console.log(
|
|
6775
|
+
console.log(chalk12.dim("No Constitution found. Run `archon interview` to create one."));
|
|
6835
6776
|
}
|
|
6836
6777
|
}
|
|
6837
6778
|
async function validateConstitutionCommand() {
|
|
@@ -6840,23 +6781,23 @@ async function validateConstitutionCommand() {
|
|
|
6840
6781
|
const draftPath = getDraftPath(cwd);
|
|
6841
6782
|
const path2 = existsSync13(constitutionPath) ? constitutionPath : draftPath;
|
|
6842
6783
|
if (!existsSync13(path2)) {
|
|
6843
|
-
console.log(
|
|
6784
|
+
console.log(chalk12.dim("No Constitution found. Run `archon interview` to create one."));
|
|
6844
6785
|
return;
|
|
6845
6786
|
}
|
|
6846
6787
|
const constitution = deserializeConstitution(readFileSync5(path2, "utf-8"));
|
|
6847
6788
|
const result = validateConstitution(constitution);
|
|
6848
6789
|
if (result.valid) {
|
|
6849
|
-
console.log(
|
|
6790
|
+
console.log(chalk12.green("\u2713 Constitution is valid"));
|
|
6850
6791
|
} else {
|
|
6851
|
-
console.log(
|
|
6792
|
+
console.log(chalk12.red("\u2717 Constitution has errors:"));
|
|
6852
6793
|
for (const error of result.errors) {
|
|
6853
|
-
console.log(
|
|
6794
|
+
console.log(chalk12.red(` \u2022 ${error}`));
|
|
6854
6795
|
}
|
|
6855
6796
|
}
|
|
6856
6797
|
if (result.warnings.length > 0) {
|
|
6857
|
-
console.log(
|
|
6798
|
+
console.log(chalk12.yellow("\nWarnings:"));
|
|
6858
6799
|
for (const warning of result.warnings) {
|
|
6859
|
-
console.log(
|
|
6800
|
+
console.log(chalk12.yellow(` \u2022 ${warning}`));
|
|
6860
6801
|
}
|
|
6861
6802
|
}
|
|
6862
6803
|
}
|
|
@@ -6864,7 +6805,7 @@ async function exportConstitution(format) {
|
|
|
6864
6805
|
const cwd = process.cwd();
|
|
6865
6806
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6866
6807
|
if (!existsSync13(constitutionPath)) {
|
|
6867
|
-
console.log(
|
|
6808
|
+
console.log(chalk12.dim("No frozen Constitution found."));
|
|
6868
6809
|
return;
|
|
6869
6810
|
}
|
|
6870
6811
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
@@ -6877,26 +6818,26 @@ async function exportConstitution(format) {
|
|
|
6877
6818
|
console.log(summarizeConstitution(constitution));
|
|
6878
6819
|
break;
|
|
6879
6820
|
default:
|
|
6880
|
-
console.log(
|
|
6821
|
+
console.log(chalk12.red(`Unknown format: ${format}. Use 'json' or 'markdown'.`));
|
|
6881
6822
|
}
|
|
6882
6823
|
}
|
|
6883
6824
|
async function generateAtoms(options = {}) {
|
|
6884
6825
|
const cwd = process.cwd();
|
|
6885
6826
|
const constitutionPath = getConstitutionPath(cwd);
|
|
6886
6827
|
if (!existsSync13(constitutionPath)) {
|
|
6887
|
-
console.log(
|
|
6888
|
-
console.log(
|
|
6828
|
+
console.log(chalk12.red("No frozen Constitution found."));
|
|
6829
|
+
console.log(chalk12.dim("Run `archon interview` to create one first."));
|
|
6889
6830
|
return;
|
|
6890
6831
|
}
|
|
6891
6832
|
const constitution = deserializeConstitution(readFileSync5(constitutionPath, "utf-8"));
|
|
6892
6833
|
if (constitution.state !== "FROZEN") {
|
|
6893
|
-
console.log(
|
|
6894
|
-
console.log(
|
|
6834
|
+
console.log(chalk12.yellow("Constitution is not frozen yet."));
|
|
6835
|
+
console.log(chalk12.dim("Complete the interview and freeze before generating atoms."));
|
|
6895
6836
|
return;
|
|
6896
6837
|
}
|
|
6897
|
-
console.log(
|
|
6898
|
-
console.log(
|
|
6899
|
-
console.log(
|
|
6838
|
+
console.log(chalk12.bold("\n\u{1F527} Generating Atoms from Constitution\n"));
|
|
6839
|
+
console.log(chalk12.dim(`Project: ${constitution.branding.projectName}`));
|
|
6840
|
+
console.log(chalk12.dim(`Hash: ${constitution.hash?.substring(0, 16)}...`));
|
|
6900
6841
|
console.log();
|
|
6901
6842
|
const spinner = ora3("Generating atoms...").start();
|
|
6902
6843
|
const result = generateAtomsFromConstitution(constitution, {
|
|
@@ -6909,7 +6850,7 @@ async function generateAtoms(options = {}) {
|
|
|
6909
6850
|
console.log(summarizeGeneration(result));
|
|
6910
6851
|
console.log();
|
|
6911
6852
|
if (options.dryRun) {
|
|
6912
|
-
console.log(
|
|
6853
|
+
console.log(chalk12.dim("(Dry run - not writing prd.json)"));
|
|
6913
6854
|
return;
|
|
6914
6855
|
}
|
|
6915
6856
|
const prdPath = options.output ?? join13(cwd, "prd.json");
|
|
@@ -6917,23 +6858,23 @@ async function generateAtoms(options = {}) {
|
|
|
6917
6858
|
if (existsSync13(prdPath)) {
|
|
6918
6859
|
const overwrite = await promptYesNo3("prd.json already exists. Overwrite?", false);
|
|
6919
6860
|
if (!overwrite) {
|
|
6920
|
-
console.log(
|
|
6861
|
+
console.log(chalk12.dim("Cancelled. Existing prd.json preserved."));
|
|
6921
6862
|
return;
|
|
6922
6863
|
}
|
|
6923
6864
|
}
|
|
6924
6865
|
writeFileSync(prdPath, JSON.stringify(prdContent, null, 2));
|
|
6925
|
-
console.log(
|
|
6866
|
+
console.log(chalk12.green(`
|
|
6926
6867
|
\u2713 Written to ${prdPath}`));
|
|
6927
6868
|
console.log();
|
|
6928
|
-
console.log(
|
|
6929
|
-
console.log(` ${
|
|
6930
|
-
console.log(` ${
|
|
6931
|
-
console.log(` ${
|
|
6869
|
+
console.log(chalk12.bold("Next Steps:\n"));
|
|
6870
|
+
console.log(` ${chalk12.cyan("1.")} Run ${chalk12.bold("archon list")} to see all atoms`);
|
|
6871
|
+
console.log(` ${chalk12.cyan("2.")} Run ${chalk12.bold("archon execute ATOM-001")} to start building`);
|
|
6872
|
+
console.log(` ${chalk12.cyan("3.")} Run ${chalk12.bold("archon watch")} to monitor progress`);
|
|
6932
6873
|
console.log();
|
|
6933
6874
|
}
|
|
6934
6875
|
|
|
6935
6876
|
// src/cli/eject.ts
|
|
6936
|
-
import
|
|
6877
|
+
import chalk13 from "chalk";
|
|
6937
6878
|
import { existsSync as existsSync14, rmSync } from "fs";
|
|
6938
6879
|
import { readFile as readFile8, writeFile as writeFile6 } from "fs/promises";
|
|
6939
6880
|
import { join as join14 } from "path";
|
|
@@ -6950,70 +6891,70 @@ var METADATA_FILES = [
|
|
|
6950
6891
|
];
|
|
6951
6892
|
async function eject(options = {}) {
|
|
6952
6893
|
const cwd = process.cwd();
|
|
6953
|
-
console.log(
|
|
6894
|
+
console.log(chalk13.blue("\n\u{1F680} ArchonDev Eject\n"));
|
|
6954
6895
|
const archonDir = join14(cwd, ".archon");
|
|
6955
6896
|
if (!existsSync14(archonDir)) {
|
|
6956
|
-
console.log(
|
|
6897
|
+
console.log(chalk13.yellow("This does not appear to be an ArchonDev project (.archon/ not found)."));
|
|
6957
6898
|
return;
|
|
6958
6899
|
}
|
|
6959
|
-
console.log(
|
|
6900
|
+
console.log(chalk13.dim("The following will be removed/modified:\n"));
|
|
6960
6901
|
const filesToRemove = [];
|
|
6961
6902
|
for (const file of ARCHON_FILES) {
|
|
6962
6903
|
const filePath = join14(cwd, file);
|
|
6963
6904
|
if (existsSync14(filePath)) {
|
|
6964
6905
|
filesToRemove.push(file);
|
|
6965
|
-
console.log(
|
|
6906
|
+
console.log(chalk13.red(` \u2717 ${file}`));
|
|
6966
6907
|
}
|
|
6967
6908
|
}
|
|
6968
6909
|
const archMd = join14(cwd, "ARCHITECTURE.md");
|
|
6969
6910
|
if (existsSync14(archMd) && !options.keepArchitecture) {
|
|
6970
|
-
console.log(
|
|
6911
|
+
console.log(chalk13.yellow(` ? ARCHITECTURE.md (will be kept by default)`));
|
|
6971
6912
|
}
|
|
6972
6913
|
console.log();
|
|
6973
|
-
console.log(
|
|
6914
|
+
console.log(chalk13.dim("Files to be modified:"));
|
|
6974
6915
|
for (const file of METADATA_FILES) {
|
|
6975
6916
|
const filePath = join14(cwd, file);
|
|
6976
6917
|
if (existsSync14(filePath)) {
|
|
6977
|
-
console.log(
|
|
6918
|
+
console.log(chalk13.yellow(` \u25CF ${file}`));
|
|
6978
6919
|
}
|
|
6979
6920
|
}
|
|
6980
6921
|
console.log();
|
|
6981
6922
|
if (!options.force) {
|
|
6982
6923
|
const confirmed = await promptYesNo4("This will permanently remove ArchonDev from your project. Continue?", false);
|
|
6983
6924
|
if (!confirmed) {
|
|
6984
|
-
console.log(
|
|
6925
|
+
console.log(chalk13.dim("Eject cancelled."));
|
|
6985
6926
|
return;
|
|
6986
6927
|
}
|
|
6987
6928
|
}
|
|
6988
6929
|
console.log();
|
|
6989
6930
|
const result = await performEject(cwd, options);
|
|
6990
6931
|
if (result.success) {
|
|
6991
|
-
console.log(
|
|
6932
|
+
console.log(chalk13.green("\n\u2705 Eject complete!\n"));
|
|
6992
6933
|
if (result.filesRemoved.length > 0) {
|
|
6993
|
-
console.log(
|
|
6934
|
+
console.log(chalk13.dim("Removed:"));
|
|
6994
6935
|
for (const file of result.filesRemoved) {
|
|
6995
|
-
console.log(
|
|
6936
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
6996
6937
|
}
|
|
6997
6938
|
}
|
|
6998
6939
|
if (result.filesModified.length > 0) {
|
|
6999
|
-
console.log(
|
|
6940
|
+
console.log(chalk13.dim("\nModified:"));
|
|
7000
6941
|
for (const file of result.filesModified) {
|
|
7001
|
-
console.log(
|
|
6942
|
+
console.log(chalk13.dim(` - ${file}`));
|
|
7002
6943
|
}
|
|
7003
6944
|
}
|
|
7004
6945
|
if (result.warnings.length > 0) {
|
|
7005
|
-
console.log(
|
|
6946
|
+
console.log(chalk13.yellow("\nWarnings:"));
|
|
7006
6947
|
for (const warning of result.warnings) {
|
|
7007
|
-
console.log(
|
|
6948
|
+
console.log(chalk13.yellow(` \u26A0\uFE0F ${warning}`));
|
|
7008
6949
|
}
|
|
7009
6950
|
}
|
|
7010
6951
|
console.log();
|
|
7011
|
-
console.log(
|
|
7012
|
-
console.log(
|
|
6952
|
+
console.log(chalk13.blue("Your project is now a standard repository."));
|
|
6953
|
+
console.log(chalk13.dim("Thank you for using ArchonDev!"));
|
|
7013
6954
|
} else {
|
|
7014
|
-
console.log(
|
|
6955
|
+
console.log(chalk13.red("\n\u274C Eject failed."));
|
|
7015
6956
|
for (const warning of result.warnings) {
|
|
7016
|
-
console.log(
|
|
6957
|
+
console.log(chalk13.red(` ${warning}`));
|
|
7017
6958
|
}
|
|
7018
6959
|
}
|
|
7019
6960
|
}
|
|
@@ -7120,17 +7061,17 @@ async function performEject(cwd, options) {
|
|
|
7120
7061
|
}
|
|
7121
7062
|
async function ejectDryRun() {
|
|
7122
7063
|
const cwd = process.cwd();
|
|
7123
|
-
console.log(
|
|
7064
|
+
console.log(chalk13.blue("\n\u{1F50D} Eject Dry Run\n"));
|
|
7124
7065
|
const archonDir = join14(cwd, ".archon");
|
|
7125
7066
|
if (!existsSync14(archonDir)) {
|
|
7126
|
-
console.log(
|
|
7067
|
+
console.log(chalk13.yellow("This does not appear to be an ArchonDev project."));
|
|
7127
7068
|
return;
|
|
7128
7069
|
}
|
|
7129
7070
|
console.log("The following would be removed:\n");
|
|
7130
7071
|
for (const file of ARCHON_FILES) {
|
|
7131
7072
|
const filePath = join14(cwd, file);
|
|
7132
7073
|
if (existsSync14(filePath)) {
|
|
7133
|
-
console.log(
|
|
7074
|
+
console.log(chalk13.red(` \u2717 ${file}`));
|
|
7134
7075
|
}
|
|
7135
7076
|
}
|
|
7136
7077
|
console.log();
|
|
@@ -7138,11 +7079,11 @@ async function ejectDryRun() {
|
|
|
7138
7079
|
for (const file of METADATA_FILES) {
|
|
7139
7080
|
const filePath = join14(cwd, file);
|
|
7140
7081
|
if (existsSync14(filePath)) {
|
|
7141
|
-
console.log(
|
|
7082
|
+
console.log(chalk13.yellow(` \u25CF ${file}`));
|
|
7142
7083
|
}
|
|
7143
7084
|
}
|
|
7144
7085
|
console.log();
|
|
7145
|
-
console.log(
|
|
7086
|
+
console.log(chalk13.dim('Run "archon eject" to proceed.'));
|
|
7146
7087
|
}
|
|
7147
7088
|
function promptYesNo4(question, defaultValue) {
|
|
7148
7089
|
return new Promise((resolve) => {
|
|
@@ -7151,7 +7092,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7151
7092
|
output: process.stdout
|
|
7152
7093
|
});
|
|
7153
7094
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7154
|
-
rl.question(`${
|
|
7095
|
+
rl.question(`${chalk13.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7155
7096
|
rl.close();
|
|
7156
7097
|
if (answer.trim() === "") {
|
|
7157
7098
|
resolve(defaultValue);
|
|
@@ -7163,7 +7104,7 @@ function promptYesNo4(question, defaultValue) {
|
|
|
7163
7104
|
}
|
|
7164
7105
|
|
|
7165
7106
|
// src/cli/revert.ts
|
|
7166
|
-
import
|
|
7107
|
+
import chalk14 from "chalk";
|
|
7167
7108
|
import { execSync as execSync4 } from "child_process";
|
|
7168
7109
|
import { existsSync as existsSync15 } from "fs";
|
|
7169
7110
|
import { readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
@@ -7208,35 +7149,35 @@ async function findAtomCommits(limit = 50) {
|
|
|
7208
7149
|
}
|
|
7209
7150
|
return commits;
|
|
7210
7151
|
} catch (error) {
|
|
7211
|
-
console.error(
|
|
7152
|
+
console.error(chalk14.red("Failed to read git history:"), error instanceof Error ? error.message : "Unknown error");
|
|
7212
7153
|
return [];
|
|
7213
7154
|
}
|
|
7214
7155
|
}
|
|
7215
7156
|
async function historyCommand(options) {
|
|
7216
7157
|
const limit = options.limit ?? 20;
|
|
7217
|
-
console.log(
|
|
7158
|
+
console.log(chalk14.blue("\n\u{1F4DC} Atom Execution History\n"));
|
|
7218
7159
|
const commits = await findAtomCommits(limit);
|
|
7219
7160
|
if (commits.length === 0) {
|
|
7220
|
-
console.log(
|
|
7221
|
-
console.log(
|
|
7161
|
+
console.log(chalk14.dim("No atom commits found in git history."));
|
|
7162
|
+
console.log(chalk14.dim('Atom commits are created when you run "archon execute <atom-id>".'));
|
|
7222
7163
|
return;
|
|
7223
7164
|
}
|
|
7224
|
-
console.log(
|
|
7165
|
+
console.log(chalk14.dim(`Showing ${commits.length} atom commit(s):
|
|
7225
7166
|
`));
|
|
7226
7167
|
for (const commit of commits) {
|
|
7227
7168
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7228
7169
|
const filesLabel = commit.filesChanged === 1 ? "file" : "files";
|
|
7229
|
-
console.log(`${
|
|
7230
|
-
console.log(
|
|
7231
|
-
console.log(
|
|
7170
|
+
console.log(`${chalk14.yellow(shortHash)} ${chalk14.cyan(commit.atomId)}`);
|
|
7171
|
+
console.log(chalk14.dim(` ${commit.message}`));
|
|
7172
|
+
console.log(chalk14.dim(` ${commit.date} | ${commit.filesChanged} ${filesLabel} changed`));
|
|
7232
7173
|
console.log();
|
|
7233
7174
|
}
|
|
7234
|
-
console.log(
|
|
7235
|
-
console.log(
|
|
7175
|
+
console.log(chalk14.dim("To revert an atom: archon revert <atom-id>"));
|
|
7176
|
+
console.log(chalk14.dim("Or by commit hash: archon revert --commit <hash>"));
|
|
7236
7177
|
}
|
|
7237
7178
|
async function revertCommand(atomIdOrHash, options = {}) {
|
|
7238
7179
|
const cwd = process.cwd();
|
|
7239
|
-
console.log(
|
|
7180
|
+
console.log(chalk14.blue("\n\u23EA Atom Revert\n"));
|
|
7240
7181
|
let commit;
|
|
7241
7182
|
if (atomIdOrHash.match(/^[a-f0-9]{7,40}$/i)) {
|
|
7242
7183
|
const commits = await findAtomCommits(100);
|
|
@@ -7246,54 +7187,54 @@ async function revertCommand(atomIdOrHash, options = {}) {
|
|
|
7246
7187
|
commit = commits.find((c) => c.atomId.toLowerCase() === atomIdOrHash.toLowerCase());
|
|
7247
7188
|
}
|
|
7248
7189
|
if (!commit) {
|
|
7249
|
-
console.log(
|
|
7250
|
-
console.log(
|
|
7190
|
+
console.log(chalk14.red(`No atom commit found for: ${atomIdOrHash}`));
|
|
7191
|
+
console.log(chalk14.dim('Run "archon history" to see available atom commits.'));
|
|
7251
7192
|
return;
|
|
7252
7193
|
}
|
|
7253
|
-
console.log(`Atom: ${
|
|
7254
|
-
console.log(`Commit: ${
|
|
7194
|
+
console.log(`Atom: ${chalk14.cyan(commit.atomId)}`);
|
|
7195
|
+
console.log(`Commit: ${chalk14.yellow(commit.commitHash.substring(0, 7))}`);
|
|
7255
7196
|
console.log(`Message: ${commit.message}`);
|
|
7256
7197
|
console.log(`Date: ${commit.date}`);
|
|
7257
7198
|
console.log(`Files changed: ${commit.filesChanged}`);
|
|
7258
7199
|
console.log();
|
|
7259
7200
|
try {
|
|
7260
|
-
console.log(
|
|
7201
|
+
console.log(chalk14.dim("Changes to be reverted:"));
|
|
7261
7202
|
const diffStat = execSync4(
|
|
7262
7203
|
`git diff --stat ${commit.commitHash}^..${commit.commitHash}`,
|
|
7263
7204
|
{ cwd, encoding: "utf-8" }
|
|
7264
7205
|
);
|
|
7265
|
-
console.log(
|
|
7206
|
+
console.log(chalk14.dim(diffStat));
|
|
7266
7207
|
} catch {
|
|
7267
7208
|
}
|
|
7268
7209
|
if (!options.force) {
|
|
7269
7210
|
const confirmed = await promptYesNo5("Revert this atom commit?", false);
|
|
7270
7211
|
if (!confirmed) {
|
|
7271
|
-
console.log(
|
|
7212
|
+
console.log(chalk14.dim("Revert cancelled."));
|
|
7272
7213
|
return;
|
|
7273
7214
|
}
|
|
7274
7215
|
}
|
|
7275
7216
|
try {
|
|
7276
7217
|
const revertArgs = options.noCommit ? "--no-commit" : "";
|
|
7277
7218
|
execSync4(`git revert ${revertArgs} ${commit.commitHash}`, { cwd, stdio: "pipe" });
|
|
7278
|
-
console.log(
|
|
7219
|
+
console.log(chalk14.green(`
|
|
7279
7220
|
\u2705 Successfully reverted ${commit.atomId}`));
|
|
7280
7221
|
if (options.noCommit) {
|
|
7281
|
-
console.log(
|
|
7282
|
-
console.log(
|
|
7222
|
+
console.log(chalk14.dim("Changes are staged but not committed."));
|
|
7223
|
+
console.log(chalk14.dim('Run "git commit" to finalize the revert.'));
|
|
7283
7224
|
} else {
|
|
7284
|
-
console.log(
|
|
7225
|
+
console.log(chalk14.dim("A new commit has been created to undo the changes."));
|
|
7285
7226
|
}
|
|
7286
7227
|
await updateAtomStatus(commit.atomId, "REVERTED");
|
|
7287
7228
|
} catch (error) {
|
|
7288
7229
|
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
|
7289
7230
|
if (errorMsg.includes("conflict")) {
|
|
7290
|
-
console.log(
|
|
7291
|
-
console.log(
|
|
7292
|
-
console.log(
|
|
7293
|
-
console.log(
|
|
7231
|
+
console.log(chalk14.yellow("\n\u26A0\uFE0F Merge conflict detected during revert."));
|
|
7232
|
+
console.log(chalk14.dim("Resolve conflicts manually, then:"));
|
|
7233
|
+
console.log(chalk14.dim(" git add ."));
|
|
7234
|
+
console.log(chalk14.dim(" git revert --continue"));
|
|
7294
7235
|
} else {
|
|
7295
|
-
console.log(
|
|
7296
|
-
console.log(
|
|
7236
|
+
console.log(chalk14.red("\n\u274C Revert failed:"), errorMsg);
|
|
7237
|
+
console.log(chalk14.dim("You may need to resolve this manually."));
|
|
7297
7238
|
}
|
|
7298
7239
|
}
|
|
7299
7240
|
}
|
|
@@ -7312,10 +7253,10 @@ async function updateAtomStatus(atomId, status2) {
|
|
|
7312
7253
|
}
|
|
7313
7254
|
}
|
|
7314
7255
|
async function revertableAtoms() {
|
|
7315
|
-
console.log(
|
|
7256
|
+
console.log(chalk14.blue("\n\u{1F504} Revertable Atoms\n"));
|
|
7316
7257
|
const commits = await findAtomCommits(30);
|
|
7317
7258
|
if (commits.length === 0) {
|
|
7318
|
-
console.log(
|
|
7259
|
+
console.log(chalk14.dim("No atom commits found."));
|
|
7319
7260
|
return;
|
|
7320
7261
|
}
|
|
7321
7262
|
const atomMap = /* @__PURE__ */ new Map();
|
|
@@ -7324,14 +7265,14 @@ async function revertableAtoms() {
|
|
|
7324
7265
|
atomMap.set(commit.atomId, commit);
|
|
7325
7266
|
}
|
|
7326
7267
|
}
|
|
7327
|
-
console.log(
|
|
7268
|
+
console.log(chalk14.dim(`Found ${atomMap.size} unique atom(s) in history:
|
|
7328
7269
|
`));
|
|
7329
7270
|
for (const [atomId, commit] of atomMap) {
|
|
7330
7271
|
const shortHash = commit.commitHash.substring(0, 7);
|
|
7331
|
-
console.log(` ${
|
|
7272
|
+
console.log(` ${chalk14.cyan(atomId)} ${chalk14.dim(`(${shortHash})`)} - ${commit.message.substring(0, 50)}`);
|
|
7332
7273
|
}
|
|
7333
7274
|
console.log();
|
|
7334
|
-
console.log(
|
|
7275
|
+
console.log(chalk14.dim("To revert: archon revert <atom-id>"));
|
|
7335
7276
|
}
|
|
7336
7277
|
function promptYesNo5(question, defaultValue) {
|
|
7337
7278
|
return new Promise((resolve) => {
|
|
@@ -7340,7 +7281,7 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7340
7281
|
output: process.stdout
|
|
7341
7282
|
});
|
|
7342
7283
|
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
7343
|
-
rl.question(`${
|
|
7284
|
+
rl.question(`${chalk14.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
7344
7285
|
rl.close();
|
|
7345
7286
|
if (answer.trim() === "") {
|
|
7346
7287
|
resolve(defaultValue);
|
|
@@ -7352,17 +7293,17 @@ function promptYesNo5(question, defaultValue) {
|
|
|
7352
7293
|
}
|
|
7353
7294
|
|
|
7354
7295
|
// src/cli/models-sync.ts
|
|
7355
|
-
import
|
|
7296
|
+
import chalk15 from "chalk";
|
|
7356
7297
|
async function modelsSync(options) {
|
|
7357
7298
|
const supabaseUrl = process.env["SUPABASE_URL"];
|
|
7358
7299
|
const supabaseKey = process.env["SUPABASE_SERVICE_ROLE_KEY"] || process.env["SUPABASE_ANON_KEY"];
|
|
7359
7300
|
if (!supabaseUrl) {
|
|
7360
|
-
console.log(
|
|
7361
|
-
console.log(
|
|
7362
|
-
console.log(
|
|
7301
|
+
console.log(chalk15.red("SUPABASE_URL not set. Cannot trigger remote sync."));
|
|
7302
|
+
console.log(chalk15.dim("Run the pricing check locally instead:"));
|
|
7303
|
+
console.log(chalk15.dim(" npx tsx scripts/update-model-pricing.ts --check"));
|
|
7363
7304
|
return;
|
|
7364
7305
|
}
|
|
7365
|
-
console.log(
|
|
7306
|
+
console.log(chalk15.blue("\n\u{1F504} Triggering model registry sync...\n"));
|
|
7366
7307
|
try {
|
|
7367
7308
|
const functionUrl = `${supabaseUrl}/functions/v1/model-registry-sync`;
|
|
7368
7309
|
const response = await fetch(functionUrl, {
|
|
@@ -7374,83 +7315,83 @@ async function modelsSync(options) {
|
|
|
7374
7315
|
});
|
|
7375
7316
|
if (!response.ok) {
|
|
7376
7317
|
const errorText = await response.text();
|
|
7377
|
-
console.log(
|
|
7318
|
+
console.log(chalk15.red(`Sync failed: ${response.status} - ${errorText}`));
|
|
7378
7319
|
return;
|
|
7379
7320
|
}
|
|
7380
7321
|
const result = await response.json();
|
|
7381
|
-
console.log(
|
|
7322
|
+
console.log(chalk15.bold("Sync Results:"));
|
|
7382
7323
|
console.log(` Providers checked: ${result.providersChecked.join(", ")}`);
|
|
7383
7324
|
console.log(` Duration: ${result.durationMs}ms`);
|
|
7384
7325
|
console.log();
|
|
7385
|
-
console.log(
|
|
7326
|
+
console.log(chalk15.bold("Parse Confidence:"));
|
|
7386
7327
|
for (const [provider, score] of Object.entries(result.confidenceScores)) {
|
|
7387
7328
|
const pct = (score * 100).toFixed(0);
|
|
7388
|
-
const color = score >= 0.8 ?
|
|
7329
|
+
const color = score >= 0.8 ? chalk15.green : score >= 0.5 ? chalk15.yellow : chalk15.red;
|
|
7389
7330
|
console.log(` ${provider}: ${color(pct + "%")}`);
|
|
7390
7331
|
}
|
|
7391
7332
|
console.log();
|
|
7392
7333
|
if (result.diffs.length === 0) {
|
|
7393
|
-
console.log(
|
|
7334
|
+
console.log(chalk15.green("\u2705 All model pricing is up to date. No changes detected."));
|
|
7394
7335
|
} else {
|
|
7395
7336
|
const pricingChanges = result.diffs.filter((d) => d.type === "PRICING_CHANGE");
|
|
7396
7337
|
const newModels = result.diffs.filter((d) => d.type === "NEW_MODEL");
|
|
7397
7338
|
if (pricingChanges.length > 0) {
|
|
7398
|
-
console.log(
|
|
7339
|
+
console.log(chalk15.yellow(`\u{1F4B0} Pricing Changes (${pricingChanges.length}):`));
|
|
7399
7340
|
for (const d of pricingChanges) {
|
|
7400
|
-
console.log(` ${d.provider}/${
|
|
7401
|
-
console.log(` Old: ${
|
|
7402
|
-
console.log(` New: ${
|
|
7341
|
+
console.log(` ${d.provider}/${chalk15.bold(d.modelId)}`);
|
|
7342
|
+
console.log(` Old: ${chalk15.red(d.oldValue ?? "unknown")}`);
|
|
7343
|
+
console.log(` New: ${chalk15.green(d.newValue ?? "unknown")}`);
|
|
7403
7344
|
}
|
|
7404
7345
|
console.log();
|
|
7405
7346
|
}
|
|
7406
7347
|
if (newModels.length > 0) {
|
|
7407
|
-
console.log(
|
|
7348
|
+
console.log(chalk15.cyan(`\u{1F195} New Models (${newModels.length}):`));
|
|
7408
7349
|
for (const d of newModels) {
|
|
7409
|
-
console.log(` ${d.provider}/${
|
|
7350
|
+
console.log(` ${d.provider}/${chalk15.bold(d.modelId)}: ${d.details}`);
|
|
7410
7351
|
}
|
|
7411
7352
|
console.log();
|
|
7412
7353
|
}
|
|
7413
|
-
console.log(
|
|
7354
|
+
console.log(chalk15.bold(`Applied: ${result.modelsUpdated} updated, ${result.modelsAdded} added`));
|
|
7414
7355
|
}
|
|
7415
7356
|
if (result.parseErrors.length > 0) {
|
|
7416
7357
|
console.log();
|
|
7417
|
-
console.log(
|
|
7358
|
+
console.log(chalk15.red(`\u26A0\uFE0F Warnings/Errors (${result.parseErrors.length}):`));
|
|
7418
7359
|
for (const err2 of result.parseErrors) {
|
|
7419
|
-
console.log(
|
|
7360
|
+
console.log(chalk15.red(` - ${err2}`));
|
|
7420
7361
|
}
|
|
7421
7362
|
}
|
|
7422
7363
|
console.log();
|
|
7423
7364
|
} catch (err2) {
|
|
7424
|
-
console.log(
|
|
7365
|
+
console.log(chalk15.red(`Failed to run sync: ${err2}`));
|
|
7425
7366
|
}
|
|
7426
7367
|
}
|
|
7427
7368
|
async function modelsList() {
|
|
7428
|
-
const { getAllActiveModels, getModelCost, isFreeModel } = await import("./models-
|
|
7369
|
+
const { getAllActiveModels, getModelCost, isFreeModel } = await import("./models-D4NV2MVH.js");
|
|
7429
7370
|
const models = getAllActiveModels();
|
|
7430
|
-
console.log(
|
|
7371
|
+
console.log(chalk15.bold("\n\u{1F4CB} Model Registry\n"));
|
|
7431
7372
|
let currentProvider = "";
|
|
7432
7373
|
for (const model of models) {
|
|
7433
7374
|
if (model.provider !== currentProvider) {
|
|
7434
7375
|
currentProvider = model.provider;
|
|
7435
|
-
console.log(
|
|
7376
|
+
console.log(chalk15.bold.blue(`
|
|
7436
7377
|
${currentProvider.toUpperCase()}`));
|
|
7437
|
-
console.log(
|
|
7378
|
+
console.log(chalk15.dim(" \u2500".repeat(40)));
|
|
7438
7379
|
}
|
|
7439
7380
|
const cost = getModelCost(model.modelId);
|
|
7440
7381
|
const free = isFreeModel(model.modelId);
|
|
7441
|
-
const tier = free ?
|
|
7442
|
-
const category = model.category === "thinking" ?
|
|
7382
|
+
const tier = free ? chalk15.green(" [FREE]") : "";
|
|
7383
|
+
const category = model.category === "thinking" ? chalk15.magenta("thinking") : chalk15.cyan("fast");
|
|
7443
7384
|
const inputPrice = cost ? `$${(cost.costPer1kInput * 1e3).toFixed(2)}/1M` : "?";
|
|
7444
7385
|
const outputPrice = cost ? `$${(cost.costPer1kOutput * 1e3).toFixed(2)}/1M` : "?";
|
|
7445
|
-
console.log(` ${
|
|
7446
|
-
console.log(
|
|
7386
|
+
console.log(` ${chalk15.bold(model.modelId)}${tier}`);
|
|
7387
|
+
console.log(chalk15.dim(` ${category} | Input: ${inputPrice} | Output: ${outputPrice}`));
|
|
7447
7388
|
}
|
|
7448
7389
|
console.log();
|
|
7449
7390
|
}
|
|
7450
7391
|
|
|
7451
7392
|
// src/cli/governance.ts
|
|
7452
7393
|
import { Command as Command2 } from "commander";
|
|
7453
|
-
import
|
|
7394
|
+
import chalk16 from "chalk";
|
|
7454
7395
|
import { existsSync as existsSync19, readFileSync as readFileSync7 } from "fs";
|
|
7455
7396
|
import { readFile as readFile12 } from "fs/promises";
|
|
7456
7397
|
import { join as join19 } from "path";
|
|
@@ -8270,9 +8211,9 @@ function parseContextMeta(content) {
|
|
|
8270
8211
|
function renderStatusCounts(counts) {
|
|
8271
8212
|
const total = Object.values(counts).reduce((sum, value) => sum + value, 0);
|
|
8272
8213
|
if (total === 0) return;
|
|
8273
|
-
console.log(
|
|
8214
|
+
console.log(chalk16.dim(` Tasks: ${total} total`));
|
|
8274
8215
|
console.log(
|
|
8275
|
-
|
|
8216
|
+
chalk16.dim(
|
|
8276
8217
|
` pending: ${counts.pending} | in_progress: ${counts.in_progress} | verification: ${counts.verification} | done: ${counts.done}`
|
|
8277
8218
|
)
|
|
8278
8219
|
);
|
|
@@ -8288,22 +8229,22 @@ function createGovernanceCommand() {
|
|
|
8288
8229
|
const cwd = process.cwd();
|
|
8289
8230
|
const store = new GovernanceStore(cwd);
|
|
8290
8231
|
store.ensureStructure();
|
|
8291
|
-
console.log(
|
|
8232
|
+
console.log(chalk16.bold("\nGovernance Status\n"));
|
|
8292
8233
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8293
8234
|
if (archInfo.path) {
|
|
8294
8235
|
const parser = new ArchitectureParser(archInfo.path);
|
|
8295
8236
|
const parsed = await parser.parse();
|
|
8296
8237
|
if (parsed.success && parsed.schema) {
|
|
8297
8238
|
const posture = parsed.schema.qualityLevel?.posture ?? "unknown";
|
|
8298
|
-
console.log(
|
|
8299
|
-
console.log(
|
|
8300
|
-
console.log(
|
|
8301
|
-
console.log(
|
|
8239
|
+
console.log(chalk16.green(" \u2713") + ` Architecture (${archInfo.source})`);
|
|
8240
|
+
console.log(chalk16.dim(` posture: ${posture}`));
|
|
8241
|
+
console.log(chalk16.dim(` invariants: ${parsed.schema.invariants.length}`));
|
|
8242
|
+
console.log(chalk16.dim(` protected paths: ${parsed.schema.protectedPaths.length}`));
|
|
8302
8243
|
} else {
|
|
8303
|
-
console.log(
|
|
8244
|
+
console.log(chalk16.yellow(" ! Architecture present but failed to parse"));
|
|
8304
8245
|
}
|
|
8305
8246
|
} else {
|
|
8306
|
-
console.log(
|
|
8247
|
+
console.log(chalk16.yellow(" \u25CB No architecture file found"));
|
|
8307
8248
|
}
|
|
8308
8249
|
const tasksPath = join19(cwd, ACTIVE_TASKS_PATH2);
|
|
8309
8250
|
if (existsSync19(tasksPath)) {
|
|
@@ -8313,33 +8254,33 @@ function createGovernanceCommand() {
|
|
|
8313
8254
|
if (tasks2) {
|
|
8314
8255
|
renderStatusCounts(countTaskStatuses(tasks2));
|
|
8315
8256
|
} else {
|
|
8316
|
-
console.log(
|
|
8257
|
+
console.log(chalk16.yellow(" ! tasks.json present but invalid"));
|
|
8317
8258
|
}
|
|
8318
8259
|
} catch {
|
|
8319
|
-
console.log(
|
|
8260
|
+
console.log(chalk16.yellow(" ! tasks.json present but unreadable"));
|
|
8320
8261
|
}
|
|
8321
8262
|
}
|
|
8322
8263
|
const contextPath = join19(cwd, CURRENT_CONTEXT_PATH);
|
|
8323
8264
|
if (existsSync19(contextPath)) {
|
|
8324
8265
|
const content = readFileSync7(contextPath, "utf-8");
|
|
8325
8266
|
const meta = parseContextMeta(content);
|
|
8326
|
-
console.log(
|
|
8267
|
+
console.log(chalk16.dim(` Handoff: ${meta.timestamp ?? "present"}`));
|
|
8327
8268
|
if (meta.reason) {
|
|
8328
|
-
console.log(
|
|
8269
|
+
console.log(chalk16.dim(` reason: ${meta.reason}`));
|
|
8329
8270
|
}
|
|
8330
8271
|
}
|
|
8331
8272
|
const handoffHistoryPath = join19(cwd, HANDOFF_HISTORY_PATH);
|
|
8332
8273
|
if (existsSync19(handoffHistoryPath)) {
|
|
8333
8274
|
const count = lineCount(readFileSync7(handoffHistoryPath, "utf-8"));
|
|
8334
8275
|
if (count > 0) {
|
|
8335
|
-
console.log(
|
|
8276
|
+
console.log(chalk16.dim(` Handoff entries: ${count}`));
|
|
8336
8277
|
}
|
|
8337
8278
|
}
|
|
8338
8279
|
const completedPath = join19(cwd, COMPLETED_TASKS_PATH);
|
|
8339
8280
|
if (existsSync19(completedPath)) {
|
|
8340
8281
|
const count = lineCount(readFileSync7(completedPath, "utf-8"));
|
|
8341
8282
|
if (count > 0) {
|
|
8342
|
-
console.log(
|
|
8283
|
+
console.log(chalk16.dim(` Completed tasks archived: ${count}`));
|
|
8343
8284
|
}
|
|
8344
8285
|
}
|
|
8345
8286
|
console.log("");
|
|
@@ -8350,7 +8291,7 @@ function createGovernanceCommand() {
|
|
|
8350
8291
|
const store = new GovernanceStore(cwd);
|
|
8351
8292
|
const archInfo = resolveArchitecturePath2(cwd);
|
|
8352
8293
|
if (!archInfo.path) {
|
|
8353
|
-
console.log(
|
|
8294
|
+
console.log(chalk16.yellow("No architecture file found."));
|
|
8354
8295
|
return;
|
|
8355
8296
|
}
|
|
8356
8297
|
if (options.raw) {
|
|
@@ -8361,11 +8302,11 @@ function createGovernanceCommand() {
|
|
|
8361
8302
|
if (archInfo.source === "agd") {
|
|
8362
8303
|
const result = await store.readArchitecture();
|
|
8363
8304
|
if (!result.ok) {
|
|
8364
|
-
console.log(
|
|
8305
|
+
console.log(chalk16.red(`Failed to read architecture: ${result.error}`));
|
|
8365
8306
|
return;
|
|
8366
8307
|
}
|
|
8367
8308
|
if (!result.value) {
|
|
8368
|
-
console.log(
|
|
8309
|
+
console.log(chalk16.yellow("Architecture file is empty."));
|
|
8369
8310
|
return;
|
|
8370
8311
|
}
|
|
8371
8312
|
console.log(result.value);
|
|
@@ -8375,7 +8316,7 @@ function createGovernanceCommand() {
|
|
|
8375
8316
|
const legacyParsed = matter4(legacyRaw);
|
|
8376
8317
|
const legacyContent = legacyParsed.content.trim();
|
|
8377
8318
|
if (!legacyContent) {
|
|
8378
|
-
console.log(
|
|
8319
|
+
console.log(chalk16.yellow("Architecture file is empty."));
|
|
8379
8320
|
return;
|
|
8380
8321
|
}
|
|
8381
8322
|
console.log(legacyContent);
|
|
@@ -8384,32 +8325,32 @@ function createGovernanceCommand() {
|
|
|
8384
8325
|
const cwd = process.cwd();
|
|
8385
8326
|
const filePath = options.file;
|
|
8386
8327
|
if (!existsSync19(filePath)) {
|
|
8387
|
-
console.log(
|
|
8328
|
+
console.log(chalk16.red(`File not found: ${filePath}`));
|
|
8388
8329
|
process.exit(1);
|
|
8389
8330
|
}
|
|
8390
8331
|
const content = await readFile12(filePath, "utf-8");
|
|
8391
8332
|
const store = new GovernanceStore(cwd);
|
|
8392
8333
|
const result = await store.updateArchitecture(content, options.reason, options.by);
|
|
8393
8334
|
if (!result.ok) {
|
|
8394
|
-
console.log(
|
|
8335
|
+
console.log(chalk16.red(`Failed to update architecture: ${result.error}`));
|
|
8395
8336
|
process.exit(1);
|
|
8396
8337
|
}
|
|
8397
|
-
console.log(
|
|
8338
|
+
console.log(chalk16.green("\u2713 Architecture updated"));
|
|
8398
8339
|
});
|
|
8399
8340
|
const tasks = governance.command("task").description("Update tasks in governance store");
|
|
8400
8341
|
tasks.command("update <taskId>").description("Update task status and notes").requiredOption("-s, --status <status>", "Status: pending, in_progress, verification, done").option("-n, --notes <text>", "Optional notes").action(async (taskId, options) => {
|
|
8401
8342
|
const status2 = options.status;
|
|
8402
8343
|
if (!isTaskStatus(status2)) {
|
|
8403
|
-
console.log(
|
|
8344
|
+
console.log(chalk16.red(`Invalid status: ${options.status}`));
|
|
8404
8345
|
process.exit(1);
|
|
8405
8346
|
}
|
|
8406
8347
|
const store = new GovernanceStore(process.cwd());
|
|
8407
8348
|
const result = await store.updateTask(taskId, status2, options.notes);
|
|
8408
8349
|
if (!result.ok) {
|
|
8409
|
-
console.log(
|
|
8350
|
+
console.log(chalk16.red(`Failed to update task: ${result.error}`));
|
|
8410
8351
|
process.exit(1);
|
|
8411
8352
|
}
|
|
8412
|
-
console.log(
|
|
8353
|
+
console.log(chalk16.green(`\u2713 Task ${taskId} updated to ${status2}`));
|
|
8413
8354
|
});
|
|
8414
8355
|
governance.command("handoff").description("Log a handoff entry and update current context").requiredOption("-r, --reason <text>", "Reason for handoff").requiredOption("-s, --summary <text>", "Summary (single paragraph)").requiredOption("-n, --next <actions...>", "Next actions (space-separated)").option("-f, --from <agent>", "Agent or source name").option("-t, --timestamp <iso>", "Timestamp override (ISO 8601)").action(async (options) => {
|
|
8415
8356
|
const store = new GovernanceStore(process.cwd());
|
|
@@ -8422,10 +8363,10 @@ function createGovernanceCommand() {
|
|
|
8422
8363
|
};
|
|
8423
8364
|
const result = await store.logHandoff(entry);
|
|
8424
8365
|
if (!result.ok) {
|
|
8425
|
-
console.log(
|
|
8366
|
+
console.log(chalk16.red(`Failed to log handoff: ${result.error}`));
|
|
8426
8367
|
process.exit(1);
|
|
8427
8368
|
}
|
|
8428
|
-
console.log(
|
|
8369
|
+
console.log(chalk16.green("\u2713 Handoff logged"));
|
|
8429
8370
|
});
|
|
8430
8371
|
governance.command("migrate").description("Migrate legacy governance files into AGD structure").option("--remove-legacy", "Archive legacy files after migration").option("--dry-run", "Show what would change without writing files").option("-b, --by <name>", "Updated by label for architecture migration").action(async (options) => {
|
|
8431
8372
|
const result = await migrateLegacyGovernance({
|
|
@@ -8434,23 +8375,23 @@ function createGovernanceCommand() {
|
|
|
8434
8375
|
dryRun: options.dryRun,
|
|
8435
8376
|
updatedBy: options.by
|
|
8436
8377
|
});
|
|
8437
|
-
console.log(
|
|
8378
|
+
console.log(chalk16.bold("\nMigration Summary"));
|
|
8438
8379
|
console.log(
|
|
8439
|
-
result.migratedArchitecture ?
|
|
8380
|
+
result.migratedArchitecture ? chalk16.green(" \u2713 Architecture migrated") : chalk16.dim(" \u25CB Architecture migration skipped")
|
|
8440
8381
|
);
|
|
8441
8382
|
console.log(
|
|
8442
|
-
result.migratedTasks ?
|
|
8383
|
+
result.migratedTasks ? chalk16.green(" \u2713 Tasks migrated") : chalk16.dim(" \u25CB Tasks migration skipped")
|
|
8443
8384
|
);
|
|
8444
8385
|
if (result.archivedLegacyFiles.length > 0) {
|
|
8445
|
-
console.log(
|
|
8386
|
+
console.log(chalk16.dim(" Archived legacy files:"));
|
|
8446
8387
|
for (const file of result.archivedLegacyFiles) {
|
|
8447
|
-
console.log(
|
|
8388
|
+
console.log(chalk16.dim(` - ${file}`));
|
|
8448
8389
|
}
|
|
8449
8390
|
}
|
|
8450
8391
|
if (result.warnings.length > 0) {
|
|
8451
|
-
console.log(
|
|
8392
|
+
console.log(chalk16.yellow("\nWarnings:"));
|
|
8452
8393
|
for (const warning of result.warnings) {
|
|
8453
|
-
console.log(
|
|
8394
|
+
console.log(chalk16.yellow(` - ${warning}`));
|
|
8454
8395
|
}
|
|
8455
8396
|
}
|
|
8456
8397
|
console.log("");
|
|
@@ -8461,7 +8402,7 @@ function createGovernanceCommand() {
|
|
|
8461
8402
|
view.init(cwd);
|
|
8462
8403
|
await view.loadFromDisk(cwd);
|
|
8463
8404
|
view.close();
|
|
8464
|
-
console.log(
|
|
8405
|
+
console.log(chalk16.green("\u2713 Governance SQLite DB initialized"));
|
|
8465
8406
|
});
|
|
8466
8407
|
return governance;
|
|
8467
8408
|
}
|
|
@@ -8473,7 +8414,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8473
8414
|
const cwd = process.cwd();
|
|
8474
8415
|
const wasInitialized = isInitialized(cwd);
|
|
8475
8416
|
if (!wasInitialized) {
|
|
8476
|
-
console.log(
|
|
8417
|
+
console.log(chalk17.blue("\nArchonDev is not initialized in this folder.\n"));
|
|
8477
8418
|
await init({ analyze: true, git: true });
|
|
8478
8419
|
}
|
|
8479
8420
|
await start({ skipGovernanceBanner: !wasInitialized });
|
|
@@ -8481,7 +8422,7 @@ program.name("archon").description("Local-first AI-powered development governanc
|
|
|
8481
8422
|
program.command("login").description("Authenticate with ArchonDev").option("-p, --provider <provider>", "OAuth provider (github or google)", "github").action(async (options) => {
|
|
8482
8423
|
const provider = options.provider;
|
|
8483
8424
|
if (provider !== "github" && provider !== "google") {
|
|
8484
|
-
console.error(
|
|
8425
|
+
console.error(chalk17.red('Invalid provider. Use "github" or "google"'));
|
|
8485
8426
|
process.exit(1);
|
|
8486
8427
|
}
|
|
8487
8428
|
await login(provider);
|
|
@@ -8679,7 +8620,7 @@ cleanupCmd.command("check").description("Analyze workspace for bloat and mainten
|
|
|
8679
8620
|
cleanupCmd.command("run").description("Execute cleanup (archive old entries, remove stale files)").action(cleanupRun);
|
|
8680
8621
|
cleanupCmd.command("auto").description("Enable/disable automatic cleanup checks").argument("[action]", "enable, disable, or status", "status").action(async (action) => {
|
|
8681
8622
|
if (action !== "enable" && action !== "disable" && action !== "status") {
|
|
8682
|
-
console.error(
|
|
8623
|
+
console.error(chalk17.red("Invalid action. Use: enable, disable, or status"));
|
|
8683
8624
|
process.exit(1);
|
|
8684
8625
|
}
|
|
8685
8626
|
await cleanupAuto(action);
|