archondev 2.19.52 → 2.19.53

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.
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-FKKVJFSW.js";
9
+ } from "./chunk-R4A2C42M.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -15,6 +15,9 @@ import {
15
15
  import {
16
16
  ArchitectureParser
17
17
  } from "./chunk-5EVHUDQX.js";
18
+ import {
19
+ getModelCostWithFallback
20
+ } from "./chunk-7C6JELBL.js";
18
21
  import {
19
22
  KeyManager
20
23
  } from "./chunk-RDG5BUED.js";
@@ -445,6 +448,68 @@ var UsageRecorder = class {
445
448
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
446
449
  return uuidRegex.test(str);
447
450
  }
451
+ calculateBaseCost(model, inputTokens, outputTokens) {
452
+ const pricing = getModelCostWithFallback(model, "conservative_max");
453
+ return inputTokens / 1e3 * pricing.costPer1kInput + outputTokens / 1e3 * pricing.costPer1kOutput;
454
+ }
455
+ async tryRecordUsageWithoutRpc(params, idempotencyKey) {
456
+ try {
457
+ const { data: rawProfile, error: profileError } = await this.supabase.from("user_profiles").select("id, tier, credit_balance_cents").eq("id", params.userId).single();
458
+ const profile = rawProfile;
459
+ if (profileError || !profile?.id || !profile.tier) {
460
+ return null;
461
+ }
462
+ if (profile.tier === "CREDITS") {
463
+ return null;
464
+ }
465
+ const baseCost = this.calculateBaseCost(params.model, params.inputTokens, params.outputTokens);
466
+ const totalCents = profile.tier === "FREE" ? Math.ceil(baseCost * 100) : 0;
467
+ const payload = {
468
+ user_id: params.userId,
469
+ atom_id: params.atomId ?? null,
470
+ execution_id: params.executionId ?? null,
471
+ model: params.model,
472
+ provider: params.provider,
473
+ operation: params.operation,
474
+ input_tokens: params.inputTokens,
475
+ output_tokens: params.outputTokens,
476
+ base_cost: baseCost,
477
+ marked_up_cost: baseCost,
478
+ fee_cents: 0,
479
+ total_cents: totalCents,
480
+ idempotency_key: idempotencyKey
481
+ };
482
+ const { data: rawInsert, error: insertError } = await this.supabase.from("token_usage").insert(payload).select("id").single();
483
+ if (insertError) {
484
+ const pgCode = insertError.code;
485
+ if (pgCode === "23505") {
486
+ const { data: existing } = await this.supabase.from("token_usage").select("id").eq("user_id", params.userId).eq("idempotency_key", idempotencyKey).single();
487
+ const existingId = existing?.id;
488
+ return {
489
+ success: true,
490
+ isDuplicate: true,
491
+ usageId: existingId,
492
+ costCents: totalCents,
493
+ feeCents: 0,
494
+ remainingBalance: profile.credit_balance_cents ?? 0,
495
+ tier: profile.tier
496
+ };
497
+ }
498
+ return null;
499
+ }
500
+ const usageId = rawInsert?.id;
501
+ return {
502
+ success: true,
503
+ usageId,
504
+ costCents: totalCents,
505
+ feeCents: 0,
506
+ remainingBalance: profile.credit_balance_cents ?? 0,
507
+ tier: profile.tier
508
+ };
509
+ } catch {
510
+ return null;
511
+ }
512
+ }
448
513
  /**
449
514
  * Generate idempotency key for a request
450
515
  * Format: {atomId}:{executionId}:{timestamp}:{random}
@@ -591,6 +656,10 @@ var UsageRecorder = class {
591
656
  });
592
657
  if (error) {
593
658
  console.error("[Billing] RPC error:", error.message);
659
+ const fallback = await this.tryRecordUsageWithoutRpc(params, idempotencyKey);
660
+ if (fallback) {
661
+ return fallback;
662
+ }
594
663
  return {
595
664
  success: false,
596
665
  error: "Billing system temporarily unavailable",
@@ -630,6 +699,10 @@ var UsageRecorder = class {
630
699
  };
631
700
  } catch (err) {
632
701
  console.error("[Billing] Exception:", err);
702
+ const fallback = await this.tryRecordUsageWithoutRpc(params, idempotencyKey);
703
+ if (fallback) {
704
+ return fallback;
705
+ }
633
706
  return {
634
707
  success: false,
635
708
  error: "Billing system error. Please try again.",
@@ -7,7 +7,7 @@ import {
7
7
  UsageRecorder,
8
8
  handleInsufficientCreditsRecovery,
9
9
  loadAtom
10
- } from "./chunk-FKKVJFSW.js";
10
+ } from "./chunk-R4A2C42M.js";
11
11
  import {
12
12
  transitionAtom
13
13
  } from "./chunk-WGLVDEZC.js";
@@ -4835,7 +4835,7 @@ async function attemptPathScopeAutoRecovery(atom, cwd, parseSchema, options) {
4835
4835
  if (allowedPaths.length === 0) {
4836
4836
  return false;
4837
4837
  }
4838
- const { listLocalAtoms, plan } = await import("./plan-Y5S5VXMT.js");
4838
+ const { listLocalAtoms, plan } = await import("./plan-V57SS7O6.js");
4839
4839
  const before = await listLocalAtoms();
4840
4840
  const recoveryStartedAt = Date.now();
4841
4841
  const recoverySource = atom.description ?? atom.title;
@@ -4903,7 +4903,7 @@ async function execute(atomId, options) {
4903
4903
  process.exit(1);
4904
4904
  };
4905
4905
  if (options.parallel && options.parallel.length > 0) {
4906
- const { parallelExecute } = await import("./parallel-NGAMZ22X.js");
4906
+ const { parallelExecute } = await import("./parallel-WCUTC4FM.js");
4907
4907
  const allAtomIds = [atomId, ...options.parallel];
4908
4908
  await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
4909
4909
  return;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadAtom
3
- } from "./chunk-FKKVJFSW.js";
3
+ } from "./chunk-R4A2C42M.js";
4
4
 
5
5
  // src/cli/show.ts
6
6
  import chalk from "chalk";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listLocalAtoms
3
- } from "./chunk-FKKVJFSW.js";
3
+ } from "./chunk-R4A2C42M.js";
4
4
 
5
5
  // src/cli/list.ts
6
6
  import chalk from "chalk";
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-53OOWYJM.js";
3
+ } from "./chunk-TG3ELXS3.js";
4
4
  import "./chunk-EBHHIUCB.js";
5
- import "./chunk-FKKVJFSW.js";
5
+ import "./chunk-R4A2C42M.js";
6
6
  import "./chunk-WGLVDEZC.js";
7
7
  import "./chunk-3MZOEZUH.js";
8
8
  import "./chunk-F7R3QKHP.js";
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  } from "./chunk-6URKZ7NB.js";
14
14
  import {
15
15
  show
16
- } from "./chunk-3A46HCAI.js";
16
+ } from "./chunk-TZNB4BPI.js";
17
17
  import {
18
18
  bugReport
19
19
  } from "./chunk-AHK2ITJX.js";
@@ -50,13 +50,13 @@ import {
50
50
  parallelRunWaves,
51
51
  parallelSchedule,
52
52
  parallelStatus
53
- } from "./chunk-PQINPCF7.js";
53
+ } from "./chunk-L3FRKAIO.js";
54
54
  import {
55
55
  DependencyParser,
56
56
  EnvironmentConfigLoader,
57
57
  EnvironmentValidator,
58
58
  execute
59
- } from "./chunk-53OOWYJM.js";
59
+ } from "./chunk-TG3ELXS3.js";
60
60
  import {
61
61
  cloudCancel,
62
62
  cloudLogs,
@@ -64,12 +64,12 @@ import {
64
64
  } from "./chunk-EBHHIUCB.js";
65
65
  import {
66
66
  list
67
- } from "./chunk-UTI3SKKA.js";
67
+ } from "./chunk-XHIVKDU5.js";
68
68
  import {
69
69
  listLocalAtoms,
70
70
  loadAtom,
71
71
  plan
72
- } from "./chunk-FKKVJFSW.js";
72
+ } from "./chunk-R4A2C42M.js";
73
73
  import "./chunk-WGLVDEZC.js";
74
74
  import "./chunk-3MZOEZUH.js";
75
75
  import {
@@ -3394,7 +3394,7 @@ async function runExploreFlow(cwd, followUpInput, options = {}) {
3394
3394
  case "1": {
3395
3395
  const description = await promptWithCommands("Describe what you want to do", { allowMultiline: true });
3396
3396
  if (description.trim()) {
3397
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
3397
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
3398
3398
  await plan2(description, { conversational: true });
3399
3399
  }
3400
3400
  await showMainMenu();
@@ -3639,7 +3639,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3639
3639
  const hintedTask = initialTaskHint?.trim() ?? "";
3640
3640
  if (hintedTask) {
3641
3641
  console.log(chalk6.dim("Using your request above as the first task.\n"));
3642
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
3642
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
3643
3643
  await plan2(hintedTask, { conversational: true });
3644
3644
  return;
3645
3645
  }
@@ -3664,7 +3664,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3664
3664
  description = continueAnswer.trim();
3665
3665
  }
3666
3666
  if (description.trim()) {
3667
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
3667
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
3668
3668
  await plan2(description, { conversational: true });
3669
3669
  }
3670
3670
  }
@@ -3893,7 +3893,7 @@ async function handleAgentConversationInput(cwd, input) {
3893
3893
  return true;
3894
3894
  }
3895
3895
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3896
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
3896
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
3897
3897
  await plan2(await withAllowedPathScope(cwd, input), { conversational: true });
3898
3898
  if (shouldAutoExecuteAfterPlanning(input)) {
3899
3899
  await continueWithCurrentTask(cwd, { runAllReady: true });
@@ -3940,7 +3940,7 @@ async function showProposalForApproval(input) {
3940
3940
  }
3941
3941
  }
3942
3942
  async function showLatestPlannedAtom(cwd) {
3943
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-Y5S5VXMT.js");
3943
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-V57SS7O6.js");
3944
3944
  const atoms = await listLocalAtoms2();
3945
3945
  if (atoms.length === 0) {
3946
3946
  console.log(chalk6.yellow("No atoms found yet. Tell me what to plan."));
@@ -3958,7 +3958,7 @@ async function showLatestPlannedAtom(cwd) {
3958
3958
  console.log(chalk6.dim(`
3959
3959
  Showing latest planned atom (${latest.externalId})...
3960
3960
  `));
3961
- const { show: show2 } = await import("./show-IL6WBDTI.js");
3961
+ const { show: show2 } = await import("./show-QDTDTY4P.js");
3962
3962
  await show2(latest.externalId);
3963
3963
  }
3964
3964
  function isContinuationDirective(input) {
@@ -4091,7 +4091,7 @@ async function applyApprovedProposal(cwd) {
4091
4091
  console.log(chalk6.dim('\nReply "continue" when you want execution to start.'));
4092
4092
  }
4093
4093
  async function createTaskFromRequest(cwd, request) {
4094
- const { plan: plan2, listLocalAtoms: listLocalAtoms2 } = await import("./plan-Y5S5VXMT.js");
4094
+ const { plan: plan2, listLocalAtoms: listLocalAtoms2 } = await import("./plan-V57SS7O6.js");
4095
4095
  const before = await listLocalAtoms2();
4096
4096
  const beforeIds = new Set(before.map((atom) => atom.externalId));
4097
4097
  await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
@@ -4267,13 +4267,13 @@ function buildSampleCapsuleDraft(cwd, files, capsuleCount) {
4267
4267
  ].join("\n");
4268
4268
  }
4269
4269
  async function continueWithCurrentTask(cwd, options = {}) {
4270
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-Y5S5VXMT.js");
4270
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-V57SS7O6.js");
4271
4271
  const byMostRecent = (a, b) => {
4272
4272
  const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
4273
4273
  const bTime = new Date(String(b.updatedAt ?? b.createdAt ?? "")).getTime() || 0;
4274
4274
  return bTime - aTime;
4275
4275
  };
4276
- const { execute: execute2 } = await import("./execute-MQFDA6EX.js");
4276
+ const { execute: execute2 } = await import("./execute-HQ5XANCR.js");
4277
4277
  const runAllReady = options.runAllReady === true;
4278
4278
  const scopeIds = options.onlyAtomIds ? new Set(options.onlyAtomIds) : null;
4279
4279
  const attempted = /* @__PURE__ */ new Set();
@@ -4349,7 +4349,7 @@ Continuing with ${nextAtom.externalId}...
4349
4349
  }
4350
4350
  }
4351
4351
  async function replanLatestBlockedAtom(cwd) {
4352
- const { listLocalAtoms: listLocalAtoms2, plan: plan2 } = await import("./plan-Y5S5VXMT.js");
4352
+ const { listLocalAtoms: listLocalAtoms2, plan: plan2 } = await import("./plan-V57SS7O6.js");
4353
4353
  const atoms = await listLocalAtoms2();
4354
4354
  const blocked = atoms.filter((a) => a.status === "BLOCKED" && (a.errorMessage ?? "").toLowerCase().includes("outside the allowed paths")).sort((a, b) => {
4355
4355
  const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
@@ -4463,7 +4463,7 @@ async function handleFreeformJourneyInput(cwd, input) {
4463
4463
  const state = detectProjectState(cwd);
4464
4464
  if (state.hasArchitecture) {
4465
4465
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
4466
- const { plan: plan3 } = await import("./plan-Y5S5VXMT.js");
4466
+ const { plan: plan3 } = await import("./plan-V57SS7O6.js");
4467
4467
  await plan3(await withAllowedPathScope(cwd, freeform), { conversational: true });
4468
4468
  return true;
4469
4469
  }
@@ -4472,7 +4472,7 @@ async function handleFreeformJourneyInput(cwd, input) {
4472
4472
  return true;
4473
4473
  }
4474
4474
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
4475
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
4475
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
4476
4476
  await plan2(await withAllowedPathScope(cwd, freeform), { conversational: true });
4477
4477
  return true;
4478
4478
  }
@@ -4521,7 +4521,7 @@ function isFileLocationQuestion(input) {
4521
4521
  return true;
4522
4522
  }
4523
4523
  async function answerLatestOutputLocation(cwd) {
4524
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-Y5S5VXMT.js");
4524
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-V57SS7O6.js");
4525
4525
  const atoms = await listLocalAtoms2();
4526
4526
  const latestDone = atoms.filter((atom) => atom.status === "DONE").sort((a, b) => {
4527
4527
  const aTime = new Date(String(a.updatedAt ?? a.createdAt ?? "")).getTime() || 0;
@@ -4570,7 +4570,7 @@ async function handlePostExploreAction(cwd, request, options = {}) {
4570
4570
  } else {
4571
4571
  console.log(chalk6.dim("> Got it! Creating a task for this...\n"));
4572
4572
  }
4573
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
4573
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
4574
4574
  await plan2(await withAllowedPathScope(cwd, request), { conversational: true });
4575
4575
  if (options.agentMode) {
4576
4576
  if (shouldAutoExecuteAfterPlanning(sourceInput)) {
@@ -4594,18 +4594,18 @@ Constraints:
4594
4594
  - If required files are outside this scope, propose the minimum architecture path update first.`;
4595
4595
  }
4596
4596
  async function planTask() {
4597
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
4597
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
4598
4598
  const description = await promptWithCommands("Describe what you want to build", { allowMultiline: true });
4599
4599
  if (description.trim()) {
4600
4600
  await plan2(description, { conversational: true });
4601
4601
  }
4602
4602
  }
4603
4603
  async function listAtoms() {
4604
- const { list: list2 } = await import("./list-T5JXBHBF.js");
4604
+ const { list: list2 } = await import("./list-QKB55FIY.js");
4605
4605
  await list2({});
4606
4606
  }
4607
4607
  async function executeNext() {
4608
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-Y5S5VXMT.js");
4608
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-V57SS7O6.js");
4609
4609
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
4610
4610
  const { loadExecutionPreferences } = await import("./preferences-MTGN2VZK.js");
4611
4611
  const cwd = process.cwd();
@@ -4676,11 +4676,11 @@ async function executeNext() {
4676
4676
  }
4677
4677
  }
4678
4678
  if (selectedMode === "parallel-cloud") {
4679
- const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-NGAMZ22X.js");
4679
+ const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-WCUTC4FM.js");
4680
4680
  await parallelExecuteCloud2(runIds);
4681
4681
  return;
4682
4682
  }
4683
- const { parallelExecute } = await import("./parallel-NGAMZ22X.js");
4683
+ const { parallelExecute } = await import("./parallel-WCUTC4FM.js");
4684
4684
  await parallelExecute(runIds);
4685
4685
  return;
4686
4686
  }
@@ -4688,7 +4688,7 @@ async function executeNext() {
4688
4688
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
4689
4689
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
4690
4690
  if (targetId) {
4691
- const { execute: execute2 } = await import("./execute-MQFDA6EX.js");
4691
+ const { execute: execute2 } = await import("./execute-HQ5XANCR.js");
4692
4692
  await execute2(targetId, {});
4693
4693
  } else {
4694
4694
  console.log(chalk6.yellow("No atom to execute."));
@@ -4837,7 +4837,7 @@ async function handleSlashCommand(input) {
4837
4837
  const arg = parts.slice(1).join(" ").trim();
4838
4838
  switch (command) {
4839
4839
  case "/plan": {
4840
- const { plan: plan2 } = await import("./plan-Y5S5VXMT.js");
4840
+ const { plan: plan2 } = await import("./plan-V57SS7O6.js");
4841
4841
  if (arg) {
4842
4842
  await plan2(arg, { conversational: true });
4843
4843
  } else {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  list
3
- } from "./chunk-UTI3SKKA.js";
4
- import "./chunk-FKKVJFSW.js";
3
+ } from "./chunk-XHIVKDU5.js";
4
+ import "./chunk-R4A2C42M.js";
5
5
  import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
@@ -6,9 +6,9 @@ import {
6
6
  parallelRunWaves,
7
7
  parallelSchedule,
8
8
  parallelStatus
9
- } from "./chunk-PQINPCF7.js";
9
+ } from "./chunk-L3FRKAIO.js";
10
10
  import "./chunk-EBHHIUCB.js";
11
- import "./chunk-FKKVJFSW.js";
11
+ import "./chunk-R4A2C42M.js";
12
12
  import "./chunk-WGLVDEZC.js";
13
13
  import "./chunk-3MZOEZUH.js";
14
14
  import "./chunk-F7R3QKHP.js";
@@ -3,7 +3,7 @@ import {
3
3
  loadAtom,
4
4
  parseAtomDescription,
5
5
  plan
6
- } from "./chunk-FKKVJFSW.js";
6
+ } from "./chunk-R4A2C42M.js";
7
7
  import "./chunk-WGLVDEZC.js";
8
8
  import "./chunk-3MZOEZUH.js";
9
9
  import "./chunk-F7R3QKHP.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  show
3
- } from "./chunk-3A46HCAI.js";
4
- import "./chunk-FKKVJFSW.js";
3
+ } from "./chunk-TZNB4BPI.js";
4
+ import "./chunk-R4A2C42M.js";
5
5
  import "./chunk-WGLVDEZC.js";
6
6
  import "./chunk-3MZOEZUH.js";
7
7
  import "./chunk-F7R3QKHP.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.19.52",
3
+ "version": "2.19.53",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {