archondev 2.19.5 → 2.19.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -792,7 +792,7 @@ async function interactiveSettings() {
792
792
  await interactiveSettings();
793
793
  break;
794
794
  case "4":
795
- await showUsageDetails();
795
+ await showUsageDetails({ pauseForInput: true });
796
796
  await interactiveSettings();
797
797
  break;
798
798
  case "5":
@@ -1188,7 +1188,91 @@ var __preferencesChoiceHelpers = {
1188
1188
  resolveProviderIndexChoice,
1189
1189
  resolveModelChoice
1190
1190
  };
1191
- async function showUsageDetails() {
1191
+ function formatLocalDateTime(value) {
1192
+ const date = new Date(value);
1193
+ if (isNaN(date.getTime())) {
1194
+ return value;
1195
+ }
1196
+ return date.toLocaleString();
1197
+ }
1198
+ function formatUsagePeriodLabel(periodSource) {
1199
+ if (periodSource === "credit_purchase") return "Since last top-up";
1200
+ if (periodSource === "month") return "Current month to date";
1201
+ return "Current billing period";
1202
+ }
1203
+ function sumModelCost(byModel) {
1204
+ return (byModel ?? []).reduce((sum, row) => sum + row.cost, 0);
1205
+ }
1206
+ function renderModelBreakdown(rows, options = {}) {
1207
+ const indent = options.indent ?? " ";
1208
+ if (rows.length === 0) {
1209
+ console.log(chalk.dim(`${indent}No usage recorded.`));
1210
+ return;
1211
+ }
1212
+ const total = rows.reduce((sum, row) => sum + row.cost, 0);
1213
+ const sorted = [...rows].sort((a, b) => b.cost - a.cost);
1214
+ for (const row of sorted) {
1215
+ const modelInfo = findModel(row.model);
1216
+ const name = modelInfo?.name ?? row.model;
1217
+ const tokenTotal = row.inputTokens + row.outputTokens;
1218
+ const share = total > 0 ? (row.cost / total * 100).toFixed(1) : "0.0";
1219
+ const note = options.costNote ? ` ${chalk.dim(options.costNote)}` : "";
1220
+ console.log(`${indent}${name}: ${formatTokens(tokenTotal)} tokens | ${formatCost(row.cost)} (${share}%)${note}`);
1221
+ }
1222
+ }
1223
+ async function resolveAuthAndProfileIds(authToken, fallbackAuthId) {
1224
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1225
+ let authId = fallbackAuthId ?? null;
1226
+ if (!authId) {
1227
+ const { data, error } = await supabase.auth.getUser();
1228
+ if (error || !data.user?.id) {
1229
+ return { authId: null, profileId: null };
1230
+ }
1231
+ authId = data.user.id;
1232
+ }
1233
+ const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1234
+ if (profileError || !profileRow?.id) {
1235
+ return { authId, profileId: null };
1236
+ }
1237
+ return { authId, profileId: profileRow.id };
1238
+ }
1239
+ async function fetchUsageRows(authToken, profileId, startIso, endIso) {
1240
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1241
+ const { data, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", profileId).gte("created_at", startIso).lte("created_at", endIso);
1242
+ if (error || !data) {
1243
+ return null;
1244
+ }
1245
+ return data;
1246
+ }
1247
+ function aggregateUsageRows(rows, start, end) {
1248
+ let totalInputTokens = 0;
1249
+ let totalOutputTokens = 0;
1250
+ let totalCost = 0;
1251
+ const byModelMap = /* @__PURE__ */ new Map();
1252
+ for (const row of rows) {
1253
+ const ts = new Date(row.created_at);
1254
+ if (ts < start || ts > end) continue;
1255
+ totalInputTokens += row.input_tokens;
1256
+ totalOutputTokens += row.output_tokens;
1257
+ totalCost += row.base_cost;
1258
+ const existing = byModelMap.get(row.model);
1259
+ if (existing) {
1260
+ existing.inputTokens += row.input_tokens;
1261
+ existing.outputTokens += row.output_tokens;
1262
+ existing.cost += row.base_cost;
1263
+ } else {
1264
+ byModelMap.set(row.model, {
1265
+ inputTokens: row.input_tokens,
1266
+ outputTokens: row.output_tokens,
1267
+ cost: row.base_cost
1268
+ });
1269
+ }
1270
+ }
1271
+ const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
1272
+ return { totalInputTokens, totalOutputTokens, totalCost, byModel };
1273
+ }
1274
+ async function showUsageDetails(options = {}) {
1275
+ const { pauseForInput = false } = options;
1192
1276
  console.log(chalk.bold("\n-- Usage Details --\n"));
1193
1277
  const spinner = ora("Loading usage data...").start();
1194
1278
  const config = await loadConfig();
@@ -1210,84 +1294,49 @@ async function showUsageDetails() {
1210
1294
  }
1211
1295
  const data = await response.json();
1212
1296
  if (data.tier === "BYOK") {
1213
- if (!authId) {
1297
+ const ids = await resolveAuthAndProfileIds(authToken, authId);
1298
+ if (!ids.authId || !ids.profileId) {
1214
1299
  console.log(chalk.yellow("Unable to resolve user ID for usage details."));
1215
1300
  return;
1216
1301
  }
1217
- const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, authToken);
1218
- const { data: profileRow, error: profileError } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1219
- if (profileError || !profileRow?.id) {
1220
- console.log(chalk.yellow("Unable to resolve profile for usage details."));
1221
- return;
1222
- }
1223
- const profileId = profileRow.id;
1224
1302
  const now = /* @__PURE__ */ new Date();
1225
1303
  const yearStart = new Date(now.getFullYear(), 0, 1);
1226
- 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());
1227
- if (error || !usageRows) {
1304
+ const usageRows = await fetchUsageRows(authToken, ids.profileId, yearStart.toISOString(), now.toISOString());
1305
+ if (!usageRows) {
1228
1306
  console.log(chalk.yellow("Unable to fetch BYOK usage data."));
1229
1307
  return;
1230
1308
  }
1231
- const rows = usageRows;
1232
1309
  const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
1233
- const startOfWeek = new Date(now.getFullYear(), now.getMonth(), now.getDate() - now.getDay());
1234
- const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1310
+ const startOf24h = new Date(now.getTime() - 24 * 60 * 60 * 1e3);
1311
+ const startOf7d = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1e3);
1312
+ const startOf30d = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1e3);
1235
1313
  const periods = [
1236
1314
  { label: "Today", start: startOfToday, end: now },
1237
- { label: "Week to Date (Sun\u2013Sat)", start: startOfWeek, end: now },
1238
- { label: "Month to Date", start: startOfMonth, end: now },
1315
+ { label: "Last 24 Hours", start: startOf24h, end: now },
1316
+ { label: "Last 7 Days", start: startOf7d, end: now },
1317
+ { label: "Last 30 Days", start: startOf30d, end: now },
1239
1318
  { label: "Year to Date", start: yearStart, end: now }
1240
1319
  ];
1241
- const aggregate = (start, end) => {
1242
- let totalInputTokens = 0;
1243
- let totalOutputTokens = 0;
1244
- let totalCost = 0;
1245
- const byModelMap = /* @__PURE__ */ new Map();
1246
- for (const row of rows) {
1247
- const ts = new Date(row.created_at);
1248
- if (ts < start || ts > end) continue;
1249
- totalInputTokens += row.input_tokens;
1250
- totalOutputTokens += row.output_tokens;
1251
- totalCost += row.base_cost;
1252
- const existing = byModelMap.get(row.model);
1253
- if (existing) {
1254
- existing.inputTokens += row.input_tokens;
1255
- existing.outputTokens += row.output_tokens;
1256
- existing.cost += row.base_cost;
1257
- } else {
1258
- byModelMap.set(row.model, {
1259
- inputTokens: row.input_tokens,
1260
- outputTokens: row.output_tokens,
1261
- cost: row.base_cost
1262
- });
1263
- }
1264
- }
1265
- const byModel = Array.from(byModelMap.entries()).map(([model, stats]) => ({ model, ...stats })).sort((a, b) => b.cost - a.cost);
1266
- return { totalInputTokens, totalOutputTokens, totalCost, byModel };
1267
- };
1268
1320
  console.log(chalk.blue("BYOK Usage (local time):"));
1321
+ console.log(chalk.dim("Estimated provider spend by model (you are billed directly by provider)."));
1269
1322
  for (const period of periods) {
1270
- const summary = aggregate(period.start, period.end);
1323
+ const summary = aggregateUsageRows(usageRows, period.start, period.end);
1271
1324
  console.log();
1272
1325
  console.log(chalk.bold(`${period.label}:`));
1273
1326
  console.log(` ${period.start.toLocaleDateString()} \u2192 ${period.end.toLocaleDateString()}`);
1274
1327
  console.log(` Tokens: ${formatTokens(summary.totalInputTokens + summary.totalOutputTokens)} (in ${formatTokens(summary.totalInputTokens)} / out ${formatTokens(summary.totalOutputTokens)})`);
1275
- console.log(` Cost: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
1276
- if (summary.byModel.length > 0) {
1277
- console.log(chalk.dim(" By Model:"));
1278
- for (const model of summary.byModel) {
1279
- const modelInfo = findModel(model.model);
1280
- const name = modelInfo?.name ?? model.model;
1281
- const tokenTotal = model.inputTokens + model.outputTokens;
1282
- console.log(` ${name}: ${formatTokens(tokenTotal)} tokens (${formatCost(model.cost)})`);
1283
- }
1284
- } else {
1285
- console.log(chalk.dim(" No usage recorded."));
1286
- }
1328
+ console.log(` Estimated Spend: ${formatCost(summary.totalCost)} ${chalk.dim("(paid directly to provider)")}`);
1329
+ console.log(chalk.dim(" By Model:"));
1330
+ renderModelBreakdown(summary.byModel, { indent: " " });
1287
1331
  }
1288
1332
  } else {
1289
- console.log(chalk.blue("Current Billing Period:"));
1290
- console.log(` ${data.periodStart} to ${data.periodEnd}`);
1333
+ const periodLabel = formatUsagePeriodLabel(data.periodSource);
1334
+ const byModel = [...data.byModel ?? []].sort((a, b) => b.cost - a.cost);
1335
+ const modelBilledTotal = sumModelCost(byModel);
1336
+ const modelBaseTotal = data.totalBaseCost;
1337
+ const modelFeeTotal = Math.max(0, modelBilledTotal - modelBaseTotal);
1338
+ console.log(chalk.blue(`${periodLabel}:`));
1339
+ console.log(` ${formatLocalDateTime(data.periodStart)} \u2192 ${formatLocalDateTime(data.periodEnd)}`);
1291
1340
  console.log();
1292
1341
  console.log(chalk.blue("Token Usage:"));
1293
1342
  console.log(` Input: ${formatTokens(data.totalInputTokens)} tokens`);
@@ -1295,24 +1344,29 @@ async function showUsageDetails() {
1295
1344
  console.log(` Total: ${formatTokens(data.totalInputTokens + data.totalOutputTokens)} tokens`);
1296
1345
  console.log();
1297
1346
  console.log(chalk.blue("Cost:"));
1298
- console.log(` Base Cost: ${formatCost(data.totalBaseCost)}`);
1299
1347
  if (data.tier === "CREDITS") {
1300
- const withFee = data.totalBaseCost * 1.1;
1301
- console.log(` With 10% Fee: ${formatCost(withFee)}`);
1348
+ console.log(` Base Model Cost: ${formatCost(modelBaseTotal)}`);
1349
+ console.log(` Platform Fee: ${formatCost(modelFeeTotal)}`);
1350
+ console.log(` Credits Deducted:${formatCost(modelBilledTotal)}`);
1351
+ } else {
1352
+ console.log(` Estimated Cost: ${formatCost(modelBaseTotal)}`);
1302
1353
  }
1303
- if (data.byModel && data.byModel.length > 0) {
1354
+ if (byModel.length > 0) {
1304
1355
  console.log();
1305
1356
  console.log(chalk.blue("By Model:"));
1306
- for (const stats of data.byModel) {
1307
- const modelInfo = findModel(stats.model);
1308
- const name = modelInfo?.name ?? stats.model;
1309
- console.log(` ${name}: ${formatTokens(stats.inputTokens + stats.outputTokens)} tokens (${formatCost(stats.cost)})`);
1310
- }
1357
+ renderModelBreakdown(
1358
+ byModel.map((row) => ({
1359
+ model: row.model,
1360
+ inputTokens: row.inputTokens,
1361
+ outputTokens: row.outputTokens,
1362
+ cost: row.cost
1363
+ }))
1364
+ );
1311
1365
  }
1312
1366
  if (data.byOperation && data.byOperation.length > 0) {
1313
1367
  console.log();
1314
1368
  console.log(chalk.blue("By Operation:"));
1315
- for (const stats of data.byOperation) {
1369
+ for (const stats of [...data.byOperation].sort((a, b) => b.cost - a.cost)) {
1316
1370
  console.log(` ${stats.operation}: ${formatTokens(stats.tokenCount)} tokens (${formatCost(stats.cost)})`);
1317
1371
  }
1318
1372
  }
@@ -1321,8 +1375,12 @@ async function showUsageDetails() {
1321
1375
  spinner.stop();
1322
1376
  console.log(chalk.yellow("Error fetching usage data."));
1323
1377
  }
1324
- console.log();
1325
- await prompt("Press Enter to continue");
1378
+ if (pauseForInput) {
1379
+ console.log();
1380
+ await prompt("Press Enter to continue");
1381
+ } else {
1382
+ console.log();
1383
+ }
1326
1384
  }
1327
1385
 
1328
1386
  export {
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  showExecutionPreferences,
29
29
  showPreferences,
30
30
  showUsageDetails
31
- } from "./chunk-KETUHDUE.js";
31
+ } from "./chunk-MIT5Z5V7.js";
32
32
  import {
33
33
  a11yBadge,
34
34
  a11yCheck,
@@ -3187,7 +3187,7 @@ async function handleNewProject(cwd, _state) {
3187
3187
  }
3188
3188
  if (intent.mode === "explore" && intent.confidence >= 0.7) {
3189
3189
  console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
3190
- await runExploreFlow(cwd);
3190
+ await runExploreFlow(cwd, initialResponse);
3191
3191
  return;
3192
3192
  }
3193
3193
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
@@ -3274,7 +3274,7 @@ async function showNewProjectMenu(cwd) {
3274
3274
  await showNewProjectMenu(cwd);
3275
3275
  }
3276
3276
  }
3277
- async function runExploreFlow(cwd) {
3277
+ async function runExploreFlow(cwd, followUpInput) {
3278
3278
  console.log(chalk6.blue("-- Analyzing Project --\n"));
3279
3279
  const projectInfo = await gatherProjectInfo(cwd);
3280
3280
  console.log(chalk6.bold("\u{1F4C1} Project Overview\n"));
@@ -3315,6 +3315,13 @@ async function runExploreFlow(cwd) {
3315
3315
  }
3316
3316
  console.log();
3317
3317
  console.log(chalk6.green("\u2713 Analysis complete! I'm ready to work on this project.\n"));
3318
+ const actionableFollowUp = extractActionableFollowUpFromExplore(followUpInput ?? "");
3319
+ if (actionableFollowUp) {
3320
+ console.log(chalk6.dim("I finished the project scan. Continuing with your requested task...\n"));
3321
+ await handlePostExploreAction(cwd, actionableFollowUp);
3322
+ await showMainMenu();
3323
+ return;
3324
+ }
3318
3325
  console.log(chalk6.bold("What would you like to do next?\n"));
3319
3326
  console.log(chalk6.dim("You can describe it naturally, or use shortcuts:\n"));
3320
3327
  console.log(` ${chalk6.cyan("1")}) ${chalk6.bold("Plan a task")} \u2014 Tell me what to implement, fix, or change`);
@@ -3332,22 +3339,26 @@ async function runExploreFlow(cwd) {
3332
3339
  const { plan: plan2 } = await import("./plan-7SCZH7EA.js");
3333
3340
  await plan2(description, {});
3334
3341
  }
3335
- break;
3342
+ await showMainMenu();
3343
+ return;
3336
3344
  }
3337
3345
  case "2":
3338
3346
  await codeReviewFirst(cwd);
3339
- break;
3347
+ await showMainMenu();
3348
+ return;
3340
3349
  case "3":
3341
3350
  if (!projectInfo.hasArchitecture) {
3342
3351
  await analyzeAndAdapt(cwd);
3343
3352
  }
3344
- break;
3353
+ await showMainMenu();
3354
+ return;
3345
3355
  case "q":
3346
3356
  process.exit(0);
3347
3357
  default:
3348
3358
  if (choice.trim()) {
3349
3359
  const handled = await handleFreeformJourneyInput(cwd, choice);
3350
3360
  if (handled) {
3361
+ await showMainMenu();
3351
3362
  return;
3352
3363
  }
3353
3364
  }
@@ -3649,7 +3660,7 @@ async function handleAdaptExisting(cwd, state) {
3649
3660
  const intent = detectUserIntent(response);
3650
3661
  if (intent.mode === "explore" && intent.confidence >= 0.7) {
3651
3662
  console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
3652
- await runExploreFlow(cwd);
3663
+ await runExploreFlow(cwd, response);
3653
3664
  return;
3654
3665
  }
3655
3666
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
@@ -3874,7 +3885,7 @@ async function handleFreeformJourneyInput(cwd, input) {
3874
3885
  const intent = detectUserIntent(freeform);
3875
3886
  if (intent.mode === "explore" && intent.confidence >= 0.7) {
3876
3887
  console.log(chalk6.dim("\n> Got it! Analyzing the project...\n"));
3877
- await runExploreFlow(cwd);
3888
+ await runExploreFlow(cwd, freeform);
3878
3889
  return true;
3879
3890
  }
3880
3891
  if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
@@ -3887,6 +3898,42 @@ async function handleFreeformJourneyInput(cwd, input) {
3887
3898
  await plan2(freeform, {});
3888
3899
  return true;
3889
3900
  }
3901
+ function extractActionableFollowUpFromExplore(input) {
3902
+ const trimmed = input.trim();
3903
+ if (!trimmed) return null;
3904
+ const normalized = trimmed.toLowerCase();
3905
+ const hasExploreSignal = /(analyz|review|explore|scan|inspect|understand|get familiar)/.test(normalized);
3906
+ const hasActionSignal = /(how (can|could|do i)|create|build|generate|make|produce|plan|implement|write)/.test(normalized);
3907
+ if (!hasExploreSignal || !hasActionSignal) {
3908
+ return null;
3909
+ }
3910
+ const transitions = [" and then ", " then ", " and "];
3911
+ for (const token of transitions) {
3912
+ const idx = normalized.indexOf(token);
3913
+ if (idx !== -1) {
3914
+ const candidate = trimmed.slice(idx + token.length).trim();
3915
+ if (candidate.length > 10) {
3916
+ return candidate;
3917
+ }
3918
+ }
3919
+ }
3920
+ return trimmed;
3921
+ }
3922
+ async function handlePostExploreAction(cwd, request) {
3923
+ const intent = detectUserIntent(request);
3924
+ if (intent.mode === "app_builder" && intent.confidence >= 0.7) {
3925
+ console.log(chalk6.dim("> Let me understand your project better...\n"));
3926
+ await runConversationalInterview(cwd, request);
3927
+ return;
3928
+ }
3929
+ if (intent.mode === "explore" && intent.confidence >= 0.7) {
3930
+ console.log(chalk6.dim("> I can go deeper. Creating a concrete task from your request...\n"));
3931
+ } else {
3932
+ console.log(chalk6.dim("> Got it! Creating a task for this...\n"));
3933
+ }
3934
+ const { plan: plan2 } = await import("./plan-7SCZH7EA.js");
3935
+ await plan2(request, {});
3936
+ }
3890
3937
  async function showReviewProgress(cwd) {
3891
3938
  try {
3892
3939
  const { ReviewDatabase } = await import("./code-review-GJVBZPZA.js");
@@ -3919,7 +3966,7 @@ async function listAtoms() {
3919
3966
  async function executeNext() {
3920
3967
  const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-7SCZH7EA.js");
3921
3968
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
3922
- const { loadExecutionPreferences } = await import("./preferences-YOSAIHGM.js");
3969
+ const { loadExecutionPreferences } = await import("./preferences-4V4C7MVD.js");
3923
3970
  const cwd = process.cwd();
3924
3971
  const atoms = await listLocalAtoms2();
3925
3972
  const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
@@ -4018,7 +4065,7 @@ async function viewStatus() {
4018
4065
  await status2();
4019
4066
  }
4020
4067
  async function settingsMenu() {
4021
- const { interactiveSettings } = await import("./preferences-YOSAIHGM.js");
4068
+ const { interactiveSettings } = await import("./preferences-4V4C7MVD.js");
4022
4069
  await interactiveSettings();
4023
4070
  await showMainMenu();
4024
4071
  }
@@ -4376,16 +4423,38 @@ import readline2 from "readline";
4376
4423
  function getSupabaseClient(accessToken) {
4377
4424
  return createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, accessToken);
4378
4425
  }
4426
+ async function resolveAuthAndProfileIds(accessToken, fallbackAuthId) {
4427
+ const supabase = getSupabaseClient(accessToken);
4428
+ let authId = fallbackAuthId ?? null;
4429
+ if (!authId) {
4430
+ const { data, error } = await supabase.auth.getUser();
4431
+ if (error || !data.user?.id) {
4432
+ return { authId: null, profileId: null };
4433
+ }
4434
+ authId = data.user.id;
4435
+ }
4436
+ const { data: profile } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
4437
+ return {
4438
+ authId,
4439
+ profileId: profile?.id ?? null
4440
+ };
4441
+ }
4379
4442
  async function showCredits() {
4380
4443
  const spinner = ora("Fetching credit balance...").start();
4381
4444
  try {
4382
4445
  const config = await loadConfig();
4383
- if (!config.accessToken || !config.userId) {
4446
+ const authToken = getAuthToken(config);
4447
+ if (!authToken) {
4384
4448
  spinner.fail("Not logged in. Run: archon login");
4385
4449
  return;
4386
4450
  }
4387
- const supabase = getSupabaseClient(config.accessToken);
4388
- const { data, error } = await supabase.from("user_profiles").select("tier, credit_balance_cents, atoms_used_this_month").eq("auth_id", config.userId).single();
4451
+ const supabase = getSupabaseClient(authToken);
4452
+ const ids = await resolveAuthAndProfileIds(authToken, config.userId);
4453
+ if (!ids.authId) {
4454
+ spinner.fail("Could not resolve account. Run: archon login");
4455
+ return;
4456
+ }
4457
+ const { data, error } = await supabase.from("user_profiles").select("tier, credit_balance_cents, atoms_used_this_month").eq("auth_id", ids.authId).single();
4389
4458
  if (error || !data) {
4390
4459
  spinner.fail("Could not fetch profile");
4391
4460
  return;
@@ -4406,6 +4475,7 @@ async function showCredits() {
4406
4475
  } else if (profile.tier === "CREDITS") {
4407
4476
  console.log();
4408
4477
  console.log(chalk7.dim(" Add more credits: archon credits add"));
4478
+ console.log(chalk7.dim(" Detailed usage by model: archon usage"));
4409
4479
  printCreditsNextAction("CREDITS");
4410
4480
  if (balance < 5) {
4411
4481
  const addNow = await promptYesNo2("Balance is low. Add credits now?", false);
@@ -4416,6 +4486,7 @@ async function showCredits() {
4416
4486
  } else if (profile.tier === "BYOK") {
4417
4487
  console.log();
4418
4488
  console.log(chalk7.dim(" Using your own API keys - no credit charges"));
4489
+ console.log(chalk7.dim(" Estimated spend by model: archon usage"));
4419
4490
  printCreditsNextAction("BYOK");
4420
4491
  }
4421
4492
  console.log();
@@ -4514,13 +4585,19 @@ async function showHistory(options = {}) {
4514
4585
  const spinner = ora("Fetching usage history...").start();
4515
4586
  try {
4516
4587
  const config = await loadConfig();
4517
- if (!config.accessToken || !config.userId) {
4588
+ const authToken = getAuthToken(config);
4589
+ if (!authToken) {
4518
4590
  spinner.fail("Not logged in. Run: archon login");
4519
4591
  return;
4520
4592
  }
4521
- const supabase = getSupabaseClient(config.accessToken);
4593
+ const supabase = getSupabaseClient(authToken);
4594
+ const ids = await resolveAuthAndProfileIds(authToken, config.userId);
4595
+ if (!ids.profileId) {
4596
+ spinner.fail("Could not resolve profile for usage history");
4597
+ return;
4598
+ }
4522
4599
  const limit = options.limit ? parseInt(options.limit, 10) : 20;
4523
- const { data, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", config.userId).order("created_at", { ascending: false }).limit(limit);
4600
+ const { data, error } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, created_at").eq("user_id", ids.profileId).order("created_at", { ascending: false }).limit(limit);
4524
4601
  if (error) {
4525
4602
  spinner.fail("Could not fetch usage");
4526
4603
  return;
@@ -9,7 +9,7 @@ import {
9
9
  showExecutionPreferences,
10
10
  showPreferences,
11
11
  showUsageDetails
12
- } from "./chunk-KETUHDUE.js";
12
+ } from "./chunk-MIT5Z5V7.js";
13
13
  import "./chunk-Q3GIFHIQ.js";
14
14
  import "./chunk-UFR2LX6G.js";
15
15
  import "./chunk-TFSHS7EN.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.5",
3
+ "version": "2.19.6",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {