archondev 2.19.2 → 2.19.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,6 +77,7 @@ pnpm exec tsx scripts/init-governance-db.ts
77
77
  | `archon credits` | View credit balance |
78
78
  | `archon credits add` | Purchase credits |
79
79
  | `archon credits budget` | Set monthly budget and alerts |
80
+ | `archon usage` | Usage by period and model (BYOK/Credits) |
80
81
  | `archon keys add <provider>` | Add your own API key — BYOK (Bring Your Own Key) |
81
82
  | `archon keys list` | Show configured API keys by provider |
82
83
  | `archon preferences` | Interactive settings menu (billing, models, keys, usage) |
@@ -117,6 +118,7 @@ pnpm exec tsx scripts/init-governance-db.ts
117
118
 
118
119
  **Notes:**
119
120
  - Credits tier shows your balance and per‑model usage on startup; use `archon credits` for full details and history.
121
+ - BYOK shows per‑model usage and cost by today/week/month/year in `archon preferences` → “View usage details.”
120
122
  - You can paste multi‑line requests into interactive prompts; Archon captures them as a single response.
121
123
 
122
124
  **Tip:** Use `archon plan --edit` to adjust title and acceptance criteria before planning.
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-ACFMKTDL.js";
9
+ } from "./chunk-4VIBRFVY.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -851,6 +851,13 @@ async function plan(description, options) {
851
851
  requirements.length = 0;
852
852
  }
853
853
  }
854
+ const classification = classifyTaskIntent({
855
+ description,
856
+ requirements,
857
+ references,
858
+ deliverableTarget: deliverableTarget ?? void 0
859
+ });
860
+ const isContentOnlyTask = classification.kind === "content";
854
861
  console.log(chalk.dim("Creating atom from description..."));
855
862
  const atomInput = parseAtomDescription(description, options, requirements);
856
863
  const atom = createAtom(atomInput, {
@@ -872,6 +879,26 @@ async function plan(description, options) {
872
879
  Atom created: ${atom.externalId}`));
873
880
  console.log(chalk.dim(`Title: ${atom.title}`));
874
881
  console.log(chalk.dim(`Acceptance Criteria: ${atom.acceptanceCriteria.length} items`));
882
+ if (isContentOnlyTask) {
883
+ console.log(chalk.blue("\nContent task detected. Creating a lightweight plan (no adversarial loop)."));
884
+ atom.plan = buildContentPlan({
885
+ description,
886
+ requirements,
887
+ referencedFiles: references,
888
+ deliverableTarget,
889
+ missingFiles
890
+ });
891
+ atom.status = "READY";
892
+ await saveAtom(atom);
893
+ console.log(chalk.green(`
894
+ \u2705 Atom saved: ${atom.externalId}`));
895
+ console.log(chalk.dim(`Status: ${atom.status}`));
896
+ console.log(chalk.dim(`
897
+ Next steps:`));
898
+ console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
899
+ console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
900
+ return;
901
+ }
875
902
  let apiKey = process.env["ANTHROPIC_API_KEY"];
876
903
  if (!apiKey) {
877
904
  const keyManager = new KeyManager();
@@ -926,8 +953,56 @@ Atom saved: ${atom.externalId}`));
926
953
  }
927
954
  }
928
955
  }
956
+ const shouldAutoFallback = shouldFallbackToContentPlan({
957
+ classification,
958
+ description,
959
+ issues: planResult.iterations.flatMap(
960
+ (iteration) => iteration.validation.passed ? [] : iteration.validation.issues.map((issue) => issue.message)
961
+ )
962
+ });
963
+ if (shouldAutoFallback) {
964
+ console.log(chalk.blue("\nTask looks content-focused. Switching to lightweight plan."));
965
+ atom.plan = buildContentPlan({
966
+ description,
967
+ requirements,
968
+ referencedFiles: references,
969
+ deliverableTarget,
970
+ missingFiles
971
+ });
972
+ atom.status = "READY";
973
+ await saveAtom(atom);
974
+ console.log(chalk.green(`
975
+ \u2705 Atom saved: ${atom.externalId}`));
976
+ console.log(chalk.dim(`Status: ${atom.status}`));
977
+ console.log(chalk.dim(`
978
+ Next steps:`));
979
+ console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
980
+ console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
981
+ return;
982
+ }
929
983
  const answer2 = await prompt.ask("\nSave as draft anyway? (y/N): ");
930
- if (answer2.toLowerCase() !== "y") {
984
+ const normalized = answer2.toLowerCase();
985
+ if (normalized.includes("wrong") || normalized.includes("content") || normalized.includes("not a code")) {
986
+ console.log(chalk.blue("\nReclassifying as content task and creating a lightweight plan."));
987
+ atom.plan = buildContentPlan({
988
+ description,
989
+ requirements,
990
+ referencedFiles: references,
991
+ deliverableTarget,
992
+ missingFiles
993
+ });
994
+ atom.status = "READY";
995
+ await saveAtom(atom);
996
+ console.log(chalk.green(`
997
+ \u2705 Atom saved: ${atom.externalId}`));
998
+ console.log(chalk.dim(`Status: ${atom.status}`));
999
+ console.log(chalk.dim(`
1000
+ Next steps:`));
1001
+ console.log(chalk.dim(` - Execute: archon execute ${atom.externalId}`));
1002
+ console.log(chalk.dim(` - View: archon show ${atom.externalId}`));
1003
+ return;
1004
+ }
1005
+ if (normalized !== "y") {
931
1006
  console.log(chalk.dim("Atom discarded."));
932
1007
  return;
933
1008
  }
@@ -1029,6 +1104,100 @@ function extractNumberedRequirements(description) {
1029
1104
  }
1030
1105
  return requirements;
1031
1106
  }
1107
+ function extractNumberedSteps(description) {
1108
+ const steps = [];
1109
+ const lines = description.split("\n");
1110
+ for (const line of lines) {
1111
+ const match = line.match(/^\s*(\d+)[\).]\s+(.+)$/);
1112
+ if (match && match[2]) {
1113
+ steps.push(match[2].trim());
1114
+ }
1115
+ }
1116
+ return steps;
1117
+ }
1118
+ function classifyTaskIntent(input) {
1119
+ const text = `${input.description}
1120
+ ${input.requirements.join("\n")}`.toLowerCase();
1121
+ const signals = [];
1122
+ let contentScore = 0;
1123
+ let codeScore = 0;
1124
+ const contentCues = [
1125
+ /story|storytelling|storyboard|capsule|lesson|outline|narrative|plot|arc|character|conflict/,
1126
+ /illustration|visual|image|diagram|slides?|deck/,
1127
+ /write|draft|summarize|summarise|rewrite|edit|revise|polish/,
1128
+ /teach|teaching|curriculum|learning objectives?|lesson plan/
1129
+ ];
1130
+ const codeCues = [
1131
+ /api|endpoint|server|backend|frontend|cli|database|schema|migration/,
1132
+ /typescript|javascript|python|go|rust|java|c\+\+|react|node/,
1133
+ /implement|refactor|compile|build|deploy|test|lint|ci/
1134
+ ];
1135
+ for (const cue of contentCues) {
1136
+ if (cue.test(text)) {
1137
+ contentScore += 2;
1138
+ signals.push(`content:${cue.source}`);
1139
+ }
1140
+ }
1141
+ for (const cue of codeCues) {
1142
+ if (cue.test(text)) {
1143
+ codeScore += 2;
1144
+ signals.push(`code:${cue.source}`);
1145
+ }
1146
+ }
1147
+ const references = [...input.references];
1148
+ if (input.deliverableTarget) references.push(input.deliverableTarget);
1149
+ const contentRefs = references.filter((ref) => /\.(md|markdown|txt|rtf|pdf|png|jpg|jpeg|gif|svg|webp)$/i.test(ref));
1150
+ const codeRefs = references.filter((ref) => /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|kt|cpp|c|h|sql|json|yml|yaml)$/i.test(ref));
1151
+ if (contentRefs.length > 0 && codeRefs.length === 0) {
1152
+ contentScore += 2;
1153
+ signals.push("content:refs");
1154
+ }
1155
+ if (codeRefs.length > 0) {
1156
+ codeScore += 2;
1157
+ signals.push("code:refs");
1158
+ }
1159
+ let kind = "mixed";
1160
+ let confidence = "low";
1161
+ if (contentScore >= 4 && contentScore >= codeScore + 2) {
1162
+ kind = "content";
1163
+ confidence = contentScore >= 6 ? "high" : "medium";
1164
+ } else if (codeScore >= 4 && codeScore >= contentScore + 2) {
1165
+ kind = "code";
1166
+ confidence = codeScore >= 6 ? "high" : "medium";
1167
+ }
1168
+ return { kind, confidence, contentScore, codeScore, signals };
1169
+ }
1170
+ function shouldFallbackToContentPlan(input) {
1171
+ if (input.classification.kind === "content") return true;
1172
+ const text = input.description.toLowerCase();
1173
+ const issueText = input.issues.join(" ").toLowerCase();
1174
+ const contentLike = /story|storytelling|capsule|lesson|outline|storyboard|illustration|visual|image/.test(text);
1175
+ const engineeringBlockers = /api|pipeline|module|interfaces|schema|database|timeout|rate limit|retry|cache|rollback|tests?/.test(issueText);
1176
+ if (contentLike && engineeringBlockers && input.classification.contentScore >= input.classification.codeScore) {
1177
+ return true;
1178
+ }
1179
+ return false;
1180
+ }
1181
+ function buildContentPlan(input) {
1182
+ const stepsFromNumbering = extractNumberedSteps(input.description);
1183
+ const stepsFromRequirements = input.requirements.map((req) => `Create: ${req}`);
1184
+ const steps = stepsFromNumbering.length > 0 ? stepsFromNumbering : stepsFromRequirements.length > 0 ? stepsFromRequirements : ["Draft a clear outline", "Write the content", "Review and refine", "Finalize deliverable"];
1185
+ const files = /* @__PURE__ */ new Set();
1186
+ input.referencedFiles.forEach((f) => files.add(f));
1187
+ if (input.deliverableTarget) files.add(input.deliverableTarget);
1188
+ const risks = [];
1189
+ if (input.missingFiles.length > 0) {
1190
+ risks.push(`Missing inputs: ${input.missingFiles.join(", ")}`);
1191
+ }
1192
+ risks.push("Source material may be incomplete; validate against lesson content.");
1193
+ return {
1194
+ steps,
1195
+ files_to_modify: Array.from(files),
1196
+ dependencies: [],
1197
+ risks,
1198
+ estimated_complexity: steps.length > 6 ? "MEDIUM" : "LOW"
1199
+ };
1200
+ }
1032
1201
  function extractReferencedFiles(description) {
1033
1202
  const references = /* @__PURE__ */ new Set();
1034
1203
  const barePattern = /\b[\w./-]+\.(md|txt|json|yaml|yml|png|jpg|jpeg|gif|svg|pdf)\b/gi;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listLocalAtoms
3
- } from "./chunk-ACFMKTDL.js";
3
+ } from "./chunk-4VIBRFVY.js";
4
4
 
5
5
  // src/cli/list.ts
6
6
  import chalk from "chalk";
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  UsageRecorder,
8
8
  loadAtom
9
- } from "./chunk-ACFMKTDL.js";
9
+ } from "./chunk-4VIBRFVY.js";
10
10
  import {
11
11
  transitionAtom
12
12
  } from "./chunk-PCTP3LKJ.js";
@@ -4793,7 +4793,7 @@ function createPrompt() {
4793
4793
  }
4794
4794
  async function execute(atomId, options) {
4795
4795
  if (options.parallel && options.parallel.length > 0) {
4796
- const { parallelExecute } = await import("./parallel-23VQYK7H.js");
4796
+ const { parallelExecute } = await import("./parallel-5Z2X2FDD.js");
4797
4797
  const allAtomIds = [atomId, ...options.parallel];
4798
4798
  await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
4799
4799
  return;
@@ -1,3 +1,6 @@
1
+ import {
2
+ createAuthedSupabaseClient
3
+ } from "./chunk-Q3GIFHIQ.js";
1
4
  import {
2
5
  findModel,
3
6
  getAllActiveModels,
@@ -15,6 +18,10 @@ import {
15
18
  import {
16
19
  login
17
20
  } from "./chunk-F4OUCZPN.js";
21
+ import {
22
+ SUPABASE_ANON_KEY,
23
+ SUPABASE_URL
24
+ } from "./chunk-M4LGRTLC.js";
18
25
  import {
19
26
  getApiUrl,
20
27
  getAuthToken,
@@ -783,7 +790,7 @@ async function interactiveSettings() {
783
790
  await interactiveSettings();
784
791
  break;
785
792
  case "4":
786
- await viewUsageDetails();
793
+ await showUsageDetails();
787
794
  await interactiveSettings();
788
795
  break;
789
796
  case "5":
@@ -1083,11 +1090,12 @@ async function manageApiKeys() {
1083
1090
  await addKey(provider);
1084
1091
  }
1085
1092
  }
1086
- async function viewUsageDetails() {
1093
+ async function showUsageDetails() {
1087
1094
  console.log(chalk.bold("\n-- Usage Details --\n"));
1088
1095
  const spinner = ora("Loading usage data...").start();
1089
1096
  const config = await loadConfig();
1090
1097
  const authToken = getAuthToken(config);
1098
+ const authId = config.userId;
1091
1099
  if (!authToken) {
1092
1100
  spinner.fail("Not logged in");
1093
1101
  return;
@@ -1103,36 +1111,112 @@ async function viewUsageDetails() {
1103
1111
  return;
1104
1112
  }
1105
1113
  const data = await response.json();
1106
- console.log(chalk.blue("Current Billing Period:"));
1107
- console.log(` ${data.periodStart} to ${data.periodEnd}`);
1108
- console.log();
1109
- console.log(chalk.blue("Token Usage:"));
1110
- console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
1111
- console.log(` Output: ${formatTokens(data.totalOutputTokens)} tokens`);
1112
- console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
1113
- console.log();
1114
- console.log(chalk.blue("Cost:"));
1115
- console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
1116
- if (data.tier === "CREDITS") {
1117
- const withFee = data.totalBaseCost * 1.1;
1118
- console.log(` With 10% Fee: ${formatCost(withFee)}`);
1119
- } else if (data.tier === "BYOK") {
1120
- console.log(chalk.dim(" (Paid directly to your provider)"));
1121
- }
1122
- if (data.byModel && Object.keys(data.byModel).length > 0) {
1123
- console.log();
1124
- console.log(chalk.blue("By Model:"));
1125
- for (const [model, stats] of Object.entries(data.byModel)) {
1126
- const modelInfo = findModel(model);
1127
- const name = modelInfo?.name ?? model;
1128
- console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
1114
+ if (data.tier === "BYOK") {
1115
+ if (!authId) {
1116
+ console.log(chalk.yellow("Unable to resolve user ID for usage details."));
1117
+ return;
1129
1118
  }
1130
- }
1131
- if (data.byOperation && Object.keys(data.byOperation).length > 0) {
1119
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1120
+ const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1121
+ if (profileError || !profileRow?.id) {
1122
+ console.log(chalk.yellow("Unable to resolve profile for usage details."));
1123
+ return;
1124
+ }
1125
+ const profileId = profileRow.id;
1126
+ const now = /* @__PURE__ */ new Date();
1127
+ const yearStart = new Date(now.getFullYear(), 0, 1);
1128
+ const { data: usageRows, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", profileId).gte("created_at", yearStart.toISOString()).lte("created_at", now.toISOString());
1129
+ if (error || !usageRows) {
1130
+ console.log(chalk.yellow("Unable to fetch BYOK usage data."));
1131
+ return;
1132
+ }
1133
+ const rows = usageRows;
1134
+ const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1135
+ const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay());
1136
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1137
+ const periods = [
1138
+ { label: "Today", start: startOfToday, end: now },
1139
+ { label: "Week to Date (Sun\u2013Sat)", start: startOfWeek, end: now },
1140
+ { label: "Month to Date", start: startOfMonth, end: now },
1141
+ { label: "Year to Date", start: yearStart, end: now }
1142
+ ];
1143
+ const aggregate = (start, end) => {
1144
+ let totalInputTokens = 0;
1145
+ let totalOutputTokens = 0;
1146
+ let totalCost = 0;
1147
+ const byModelMap = /* @__PURE__ */ new Map();
1148
+ for (const row of rows) {
1149
+ const ts = new Date(row.created_at);
1150
+ if (ts < start || ts > end) continue;
1151
+ totalInputTokens += row.input_tokens;
1152
+ totalOutputTokens += row.output_tokens;
1153
+ totalCost += row.base_cost;
1154
+ const existing = byModelMap.get(row.model);
1155
+ if (existing) {
1156
+ existing.inputTokens += row.input_tokens;
1157
+ existing.outputTokens += row.output_tokens;
1158
+ existing.cost += row.base_cost;
1159
+ } else {
1160
+ byModelMap.set(row.model, {
1161
+ inputTokens: row.input_tokens,
1162
+ outputTokens: row.output_tokens,
1163
+ cost: row.base_cost
1164
+ });
1165
+ }
1166
+ }
1167
+ const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
1168
+ return { totalInputTokens, totalOutputTokens, totalCost, byModel };
1169
+ };
1170
+ console.log(chalk.blue("BYOK Usage (local time):"));
1171
+ for (const period of periods) {
1172
+ const summary = aggregate(period.start, period.end);
1173
+ console.log();
1174
+ console.log(chalk.bold(`${period.label}:`));
1175
+ console.log(` ${period.start.toLocaleDateString()} \u2192 ${period.end.toLocaleDateString()}`);
1176
+ console.log(` Tokens: ${formatTokens(summary.totalInputTokens + summary.totalOutputTokens)} (in ${formatTokens(summary.totalInputTokens)} / out ${formatTokens(summary.totalOutputTokens)})`);
1177
+ console.log(` Cost: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
1178
+ if (summary.byModel.length > 0) {
1179
+ console.log(chalk.dim(" By Model:"));
1180
+ for (const model of summary.byModel) {
1181
+ const modelInfo = findModel(model.model);
1182
+ const name = modelInfo?.name ?? model.model;
1183
+ const tokenTotal = model.inputTokens + model.outputTokens;
1184
+ console.log(` ${name}: ${formatTokens(tokenTotal)} tokens (${formatCost(model.cost)})`);
1185
+ }
1186
+ } else {
1187
+ console.log(chalk.dim(" No usage recorded."));
1188
+ }
1189
+ }
1190
+ } else {
1191
+ console.log(chalk.blue("Current Billing Period:"));
1192
+ console.log(` ${data.periodStart} to ${data.periodEnd}`);
1193
+ console.log();
1194
+ console.log(chalk.blue("Token Usage:"));
1195
+ console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
1196
+ console.log(` Output: ${formatTokens(data.totalOutputTokens)} tokens`);
1197
+ console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
1132
1198
  console.log();
1133
- console.log(chalk.blue("By Operation:"));
1134
- for (const [op, stats] of Object.entries(data.byOperation)) {
1135
- console.log(` ${op}: ${formatTokens(stats.tokenCount)} tokens (${formatCost(stats.cost)})`);
1199
+ console.log(chalk.blue("Cost:"));
1200
+ console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
1201
+ if (data.tier === "CREDITS") {
1202
+ const withFee = data.totalBaseCost * 1.1;
1203
+ console.log(` With 10% Fee: ${formatCost(withFee)}`);
1204
+ }
1205
+ if (data.byModel && data.byModel.length > 0) {
1206
+ console.log();
1207
+ console.log(chalk.blue("By Model:"));
1208
+ for (const stats of data.byModel) {
1209
+ const modelInfo = findModel(stats.model);
1210
+ const name = modelInfo?.name ?? stats.model;
1211
+ console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
1212
+ }
1213
+ }
1214
+ if (data.byOperation && data.byOperation.length > 0) {
1215
+ console.log();
1216
+ console.log(chalk.blue("By Operation:"));
1217
+ for (const stats of data.byOperation) {
1218
+ console.log(` ${stats.operation}: ${formatTokens(stats.tokenCount)} tokens (${formatCost(stats.cost)})`);
1219
+ }
1136
1220
  }
1137
1221
  }
1138
1222
  } catch {
@@ -1151,5 +1235,6 @@ export {
1151
1235
  setPreference,
1152
1236
  resetPreferences,
1153
1237
  listModels,
1154
- interactiveSettings
1238
+ interactiveSettings,
1239
+ showUsageDetails
1155
1240
  };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-OREGEFTF.js";
3
+ } from "./chunk-F7U5AURY.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
- import "./chunk-ACFMKTDL.js";
5
+ import "./chunk-4VIBRFVY.js";
6
6
  import "./chunk-PCTP3LKJ.js";
7
7
  import "./chunk-PJRQI5UN.js";
8
8
  import "./chunk-EIEU3IIY.js";
package/dist/index.js CHANGED
@@ -26,8 +26,9 @@ import {
26
26
  setExecutionPreference,
27
27
  setPreference,
28
28
  showExecutionPreferences,
29
- showPreferences
30
- } from "./chunk-CTWVQ6F3.js";
29
+ showPreferences,
30
+ showUsageDetails
31
+ } from "./chunk-K3XN7PN6.js";
31
32
  import {
32
33
  a11yBadge,
33
34
  a11yCheck,
@@ -46,13 +47,13 @@ import {
46
47
  parallelRunWaves,
47
48
  parallelSchedule,
48
49
  parallelStatus
49
- } from "./chunk-QTBRLNZQ.js";
50
+ } from "./chunk-4NP2AVJD.js";
50
51
  import {
51
52
  DependencyParser,
52
53
  EnvironmentConfigLoader,
53
54
  EnvironmentValidator,
54
55
  execute
55
- } from "./chunk-OREGEFTF.js";
56
+ } from "./chunk-F7U5AURY.js";
56
57
  import {
57
58
  cloudCancel,
58
59
  cloudLogs,
@@ -60,12 +61,12 @@ import {
60
61
  } from "./chunk-EBHHIUCB.js";
61
62
  import {
62
63
  list
63
- } from "./chunk-YA562WHL.js";
64
+ } from "./chunk-6G4S6B5M.js";
64
65
  import {
65
66
  listLocalAtoms,
66
67
  loadAtom,
67
68
  plan
68
- } from "./chunk-ACFMKTDL.js";
69
+ } from "./chunk-4VIBRFVY.js";
69
70
  import "./chunk-PCTP3LKJ.js";
70
71
  import "./chunk-PJRQI5UN.js";
71
72
  import {
@@ -3184,7 +3185,7 @@ async function handleNewProject(cwd, _state) {
3184
3185
  }
3185
3186
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
3186
3187
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3187
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3188
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3188
3189
  await plan2(initialResponse, {});
3189
3190
  return;
3190
3191
  }
@@ -3208,7 +3209,7 @@ async function handleNewProject(cwd, _state) {
3208
3209
  break;
3209
3210
  case "2":
3210
3211
  console.log(chalk6.dim("\n> Creating a task for this...\n"));
3211
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3212
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3212
3213
  await plan2(initialResponse, {});
3213
3214
  break;
3214
3215
  case "3":
@@ -3238,7 +3239,7 @@ async function showNewProjectMenu(cwd) {
3238
3239
  case "3": {
3239
3240
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3240
3241
  if (description.trim()) {
3241
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3242
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3242
3243
  await plan2(description, {});
3243
3244
  }
3244
3245
  break;
@@ -3304,7 +3305,7 @@ async function runExploreFlow(cwd) {
3304
3305
  case "1": {
3305
3306
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3306
3307
  if (description.trim()) {
3307
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3308
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3308
3309
  await plan2(description, {});
3309
3310
  }
3310
3311
  break;
@@ -3566,7 +3567,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3566
3567
  if (continueChoice) {
3567
3568
  const description = await promptWithCommands("Describe what you want to build first", { allowMultiline: true });
3568
3569
  if (description.trim()) {
3569
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3570
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3570
3571
  await plan2(description, {});
3571
3572
  }
3572
3573
  }
@@ -3620,7 +3621,7 @@ async function handleAdaptExisting(cwd, state) {
3620
3621
  }
3621
3622
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
3622
3623
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3623
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3624
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3624
3625
  await plan2(response, {});
3625
3626
  return;
3626
3627
  }
@@ -3651,7 +3652,7 @@ async function showAdaptExistingMenu(cwd, state) {
3651
3652
  case "2": {
3652
3653
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3653
3654
  if (description.trim()) {
3654
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3655
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3655
3656
  await plan2(description, {});
3656
3657
  }
3657
3658
  break;
@@ -3799,10 +3800,26 @@ async function showMainMenu() {
3799
3800
  }
3800
3801
  console.log(chalk6.dim(' (Type "upgrade" or "help" anytime)'));
3801
3802
  console.log();
3802
- const selected = await promptWithCommands("Enter choice");
3803
+ const selected = await promptWithCommands("Enter choice", { allowMultiline: true });
3803
3804
  const choice = choices.find((c) => c.key === selected.toLowerCase());
3804
3805
  if (choice) {
3805
3806
  await choice.action();
3807
+ } else if (selected.trim()) {
3808
+ const freeform = selected.trim();
3809
+ const intent = detectUserIntent(freeform);
3810
+ if (intent.mode === "explore" && intent.confidence >= 0.7) {
3811
+ console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
3812
+ await runExploreFlow(cwd);
3813
+ return;
3814
+ }
3815
+ if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
3816
+ console.log(chalk6.dim("\n> Let me understand your project better...\n"));
3817
+ await runConversationalInterview(cwd, freeform);
3818
+ return;
3819
+ }
3820
+ console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3821
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3822
+ await plan2(freeform, {});
3806
3823
  } else {
3807
3824
  console.log(chalk6.yellow("Invalid choice. Please try again."));
3808
3825
  await showMainMenu();
@@ -3827,20 +3844,20 @@ async function showReviewProgress(cwd) {
3827
3844
  }
3828
3845
  }
3829
3846
  async function planTask() {
3830
- const { plan: plan2 } = await import("./plan-HCYXLSSD.js");
3847
+ const { plan: plan2 } = await import("./plan-XPUDPLT2.js");
3831
3848
  const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
3832
3849
  if (description.trim()) {
3833
3850
  await plan2(description, {});
3834
3851
  }
3835
3852
  }
3836
3853
  async function listAtoms() {
3837
- const { list: list2 } = await import("./list-REPLUXJF.js");
3854
+ const { list: list2 } = await import("./list-GVC7CI5U.js");
3838
3855
  await list2({});
3839
3856
  }
3840
3857
  async function executeNext() {
3841
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-HCYXLSSD.js");
3858
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-XPUDPLT2.js");
3842
3859
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
3843
- const { loadExecutionPreferences } = await import("./preferences-OAOZCZGR.js");
3860
+ const { loadExecutionPreferences } = await import("./preferences-SFXRVXT3.js");
3844
3861
  const cwd = process.cwd();
3845
3862
  const atoms = await listLocalAtoms2();
3846
3863
  const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
@@ -3909,11 +3926,11 @@ async function executeNext() {
3909
3926
  }
3910
3927
  }
3911
3928
  if (selectedMode === "parallel-cloud") {
3912
- const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-23VQYK7H.js");
3929
+ const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-5Z2X2FDD.js");
3913
3930
  await parallelExecuteCloud2(runIds);
3914
3931
  return;
3915
3932
  }
3916
- const { parallelExecute } = await import("./parallel-23VQYK7H.js");
3933
+ const { parallelExecute } = await import("./parallel-5Z2X2FDD.js");
3917
3934
  await parallelExecute(runIds);
3918
3935
  return;
3919
3936
  }
@@ -3921,7 +3938,7 @@ async function executeNext() {
3921
3938
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
3922
3939
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
3923
3940
  if (targetId) {
3924
- const { execute: execute2 } = await import("./execute-ZTJGSRBW.js");
3941
+ const { execute: execute2 } = await import("./execute-ST5ES4XI.js");
3925
3942
  await execute2(targetId, {});
3926
3943
  } else {
3927
3944
  console.log(chalk6.yellow("No atom to execute."));
@@ -3939,7 +3956,7 @@ async function viewStatus() {
3939
3956
  await status2();
3940
3957
  }
3941
3958
  async function settingsMenu() {
3942
- const { interactiveSettings } = await import("./preferences-OAOZCZGR.js");
3959
+ const { interactiveSettings } = await import("./preferences-SFXRVXT3.js");
3943
3960
  await interactiveSettings();
3944
3961
  await showMainMenu();
3945
3962
  }
@@ -8243,6 +8260,9 @@ creditsCommand.command("audit").description("Show billing audit log (immutable r
8243
8260
  creditsCommand.action(async () => {
8244
8261
  await showCredits();
8245
8262
  });
8263
+ program.command("usage").description("Show usage by period and model").action(async () => {
8264
+ await showUsageDetails();
8265
+ });
8246
8266
  var preferencesCommand = program.command("preferences").description("Manage default model preferences");
8247
8267
  preferencesCommand.command("set <key> <model>").description("Set a model preference (fast-model, thinking-model, primary-adversarial, secondary-adversarial)").action(async (key, model) => {
8248
8268
  await setPreference(key, model);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  list
3
- } from "./chunk-YA562WHL.js";
4
- import "./chunk-ACFMKTDL.js";
3
+ } from "./chunk-6G4S6B5M.js";
4
+ import "./chunk-4VIBRFVY.js";
5
5
  import "./chunk-PCTP3LKJ.js";
6
6
  import "./chunk-PJRQI5UN.js";
7
7
  import "./chunk-EIEU3IIY.js";
@@ -6,9 +6,9 @@ import {
6
6
  parallelRunWaves,
7
7
  parallelSchedule,
8
8
  parallelStatus
9
- } from "./chunk-QTBRLNZQ.js";
9
+ } from "./chunk-4NP2AVJD.js";
10
10
  import "./chunk-EBHHIUCB.js";
11
- import "./chunk-ACFMKTDL.js";
11
+ import "./chunk-4VIBRFVY.js";
12
12
  import "./chunk-PCTP3LKJ.js";
13
13
  import "./chunk-PJRQI5UN.js";
14
14
  import "./chunk-EIEU3IIY.js";
@@ -3,7 +3,7 @@ import {
3
3
  loadAtom,
4
4
  parseAtomDescription,
5
5
  plan
6
- } from "./chunk-ACFMKTDL.js";
6
+ } from "./chunk-4VIBRFVY.js";
7
7
  import "./chunk-PCTP3LKJ.js";
8
8
  import "./chunk-PJRQI5UN.js";
9
9
  import "./chunk-EIEU3IIY.js";
@@ -6,8 +6,10 @@ import {
6
6
  setExecutionPreference,
7
7
  setPreference,
8
8
  showExecutionPreferences,
9
- showPreferences
10
- } from "./chunk-CTWVQ6F3.js";
9
+ showPreferences,
10
+ showUsageDetails
11
+ } from "./chunk-K3XN7PN6.js";
12
+ import "./chunk-Q3GIFHIQ.js";
11
13
  import "./chunk-UFR2LX6G.js";
12
14
  import "./chunk-TFSHS7EN.js";
13
15
  import "./chunk-RDG5BUED.js";
@@ -24,5 +26,6 @@ export {
24
26
  setExecutionPreference,
25
27
  setPreference,
26
28
  showExecutionPreferences,
27
- showPreferences
29
+ showPreferences,
30
+ showUsageDetails
28
31
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.2",
3
+ "version": "2.19.3",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {