archondev 2.19.49 → 2.19.50

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.
@@ -5071,11 +5071,17 @@ ${conflictReport.blockerCount} blocking conflict(s) found.`));
5071
5071
  const config = await loadConfig();
5072
5072
  let billingContext;
5073
5073
  if (config.userId && config.accessToken) {
5074
+ const profileId = await resolveProfileId(config.userId, config.accessToken);
5075
+ if (!profileId) {
5076
+ console.log(chalk2.dim("Billing context unavailable: could not resolve profile ID. Usage tracking skipped for this execution."));
5077
+ }
5074
5078
  const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, config.accessToken);
5075
- billingContext = {
5076
- userId: config.userId,
5077
- supabase
5078
- };
5079
+ if (profileId) {
5080
+ billingContext = {
5081
+ userId: profileId,
5082
+ supabase
5083
+ };
5084
+ }
5079
5085
  }
5080
5086
  const roleOverrides = await loadRoleOverrides(cwd);
5081
5087
  const executorConfig = roleOverrides?.executor?.model ? { model: roleOverrides.executor.model } : void 0;
@@ -5284,6 +5290,19 @@ Running quality gates for ${targetEnvName}...`));
5284
5290
  prompt.close();
5285
5291
  }
5286
5292
  }
5293
+ async function resolveProfileId(authId, accessToken) {
5294
+ try {
5295
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, accessToken);
5296
+ const { data: rawData, error } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
5297
+ const data = rawData;
5298
+ if (error || !data?.id) {
5299
+ return null;
5300
+ }
5301
+ return data.id;
5302
+ } catch {
5303
+ return null;
5304
+ }
5305
+ }
5287
5306
  function printExecuteNextActions(atomExternalId, success, context = "generic") {
5288
5307
  console.log();
5289
5308
  console.log(chalk2.bold("Next best action:"));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-O22UMAM5.js";
3
+ } from "./chunk-TXUHANIN.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
5
  import "./chunk-RH64CSQU.js";
6
6
  import "./chunk-WGLVDEZC.js";
package/dist/index.js CHANGED
@@ -56,7 +56,7 @@ import {
56
56
  EnvironmentConfigLoader,
57
57
  EnvironmentValidator,
58
58
  execute
59
- } from "./chunk-O22UMAM5.js";
59
+ } from "./chunk-TXUHANIN.js";
60
60
  import {
61
61
  cloudCancel,
62
62
  cloudLogs,
@@ -2843,7 +2843,15 @@ async function start(options = {}) {
2843
2843
  }
2844
2844
  if (currentTier === "BYOK" && config.accessToken) {
2845
2845
  try {
2846
+ const resolvedAuthId = await resolveAuthIdFromToken(config.accessToken, config.userId);
2846
2847
  let usageStats = await fetchByokUsageStats(config.accessToken);
2848
+ const apiLooksEmpty = !!usageStats && usageStats.totalInputTokens === 0 && usageStats.totalOutputTokens === 0 && usageStats.totalBaseCost === 0 && usageStats.byModel.length === 0;
2849
+ if (!usageStats || apiLooksEmpty && resolvedAuthId) {
2850
+ const supabaseStats = resolvedAuthId ? await fetchByokUsageStatsFromSupabase(config.accessToken, resolvedAuthId) : null;
2851
+ if (supabaseStats) {
2852
+ usageStats = supabaseStats;
2853
+ }
2854
+ }
2847
2855
  const usageStatsUnavailable = !usageStats;
2848
2856
  if (!usageStats) {
2849
2857
  usageStats = {
@@ -3094,6 +3102,48 @@ async function fetchByokUsageStats(accessToken) {
3094
3102
  return null;
3095
3103
  }
3096
3104
  }
3105
+ async function fetchByokUsageStatsFromSupabase(accessToken, authId) {
3106
+ try {
3107
+ const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-XDIWFFPN.js");
3108
+ const { createAuthedSupabaseClient: createAuthedSupabaseClient2 } = await import("./client-PHW2C2HB.js");
3109
+ const supabase = createAuthedSupabaseClient2(SUPABASE_URL2, SUPABASE_ANON_KEY2, accessToken);
3110
+ const { data: rawProfile, error: profileError } = await supabase.from("user_profiles").select("id, current_period_start, current_period_end").eq("auth_id", authId).single();
3111
+ const profile = rawProfile;
3112
+ if (profileError || !profile?.id) {
3113
+ return null;
3114
+ }
3115
+ const now = /* @__PURE__ */ new Date();
3116
+ const defaultStart = new Date(now.getFullYear(), now.getMonth(), 1);
3117
+ const defaultEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0, 23, 59, 59, 999);
3118
+ const periodStart = profile.current_period_start ? new Date(profile.current_period_start) : defaultStart;
3119
+ const periodEnd = profile.current_period_end ? new Date(profile.current_period_end) : defaultEnd;
3120
+ const { data: rawUsageRows } = await supabase.from("token_usage").select("model, input_tokens, output_tokens, base_cost, total_cents, marked_up_cost").eq("user_id", profile.id).gte("created_at", periodStart.toISOString()).lte("created_at", periodEnd.toISOString());
3121
+ const usageRows = rawUsageRows;
3122
+ let totalInputTokens = 0;
3123
+ let totalOutputTokens = 0;
3124
+ let totalBaseCost = 0;
3125
+ const byModelMap = /* @__PURE__ */ new Map();
3126
+ for (const row of usageRows ?? []) {
3127
+ totalInputTokens += row.input_tokens ?? 0;
3128
+ totalOutputTokens += row.output_tokens ?? 0;
3129
+ const baseCost = typeof row.base_cost === "number" ? row.base_cost : typeof row.total_cents === "number" ? row.total_cents / 100 : typeof row.marked_up_cost === "number" ? row.marked_up_cost : 0;
3130
+ totalBaseCost += baseCost;
3131
+ byModelMap.set(row.model, (byModelMap.get(row.model) ?? 0) + baseCost);
3132
+ }
3133
+ const byModel = Array.from(byModelMap.entries()).map(([model, cost]) => ({ model, cost })).sort((a, b) => b.cost - a.cost);
3134
+ return {
3135
+ totalInputTokens,
3136
+ totalOutputTokens,
3137
+ totalBaseCost,
3138
+ byModel,
3139
+ periodStart: periodStart.toISOString(),
3140
+ periodEnd: periodEnd.toISOString(),
3141
+ periodSource: profile.current_period_start ? "profile_period" : "month"
3142
+ };
3143
+ } catch {
3144
+ return null;
3145
+ }
3146
+ }
3097
3147
  async function fetchCreditsUsageStatsFromSupabase(accessToken, authId) {
3098
3148
  try {
3099
3149
  const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-XDIWFFPN.js");
@@ -4224,7 +4274,7 @@ async function continueWithCurrentTask(cwd, options = {}) {
4224
4274
  const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
4225
4275
  return bTime - aTime;
4226
4276
  };
4227
- const { execute: execute2 } = await import("./execute-AQWHZKDH.js");
4277
+ const { execute: execute2 } = await import("./execute-QQ3OPP6H.js");
4228
4278
  const runAllReady = options.runAllReady === true;
4229
4279
  const scopeIds = options.onlyAtomIds ? new Set(options.onlyAtomIds) : null;
4230
4280
  const attempted = /* @__PURE__ */ new Set();
@@ -4639,7 +4689,7 @@ async function executeNext() {
4639
4689
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
4640
4690
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
4641
4691
  if (targetId) {
4642
- const { execute: execute2 } = await import("./execute-AQWHZKDH.js");
4692
+ const { execute: execute2 } = await import("./execute-QQ3OPP6H.js");
4643
4693
  await execute2(targetId, {});
4644
4694
  } else {
4645
4695
  console.log(chalk6.yellow("No atom to execute."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.49",
3
+ "version": "2.19.50",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {