archondev 2.18.4 → 2.18.7

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.
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  bugReport
3
- } from "./chunk-VF2OTDMS.js";
3
+ } from "./chunk-2BCITFWP.js";
4
4
  import "./chunk-5CFGPXQ3.js";
5
- import "./chunk-2NSWZDP7.js";
5
+ import "./chunk-5BYCJAFM.js";
6
6
  import "./chunk-HJARQDQR.js";
7
7
  import "./chunk-UFR2LX6G.js";
8
8
  import "./chunk-SVU7MLG6.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5CFGPXQ3.js";
4
4
  import {
5
5
  ArchitectAgent
6
- } from "./chunk-2NSWZDP7.js";
6
+ } from "./chunk-5BYCJAFM.js";
7
7
  import {
8
8
  loadConfig
9
9
  } from "./chunk-SVU7MLG6.js";
@@ -83,6 +83,37 @@ var ArchitectAgent = class {
83
83
  parts.push("**Acceptance Criteria:**");
84
84
  atom.acceptanceCriteria.forEach((ac, i) => parts.push(`${i + 1}. ${ac}`));
85
85
  parts.push("");
86
+ const contextMeta = atom.context;
87
+ const referencedFiles = contextMeta?.["referencedFiles"] ?? [];
88
+ const missingFiles = contextMeta?.["missingFiles"] ?? [];
89
+ const requirements = contextMeta?.["requirements"] ?? [];
90
+ const fileSummaries = contextMeta?.["fileSummaries"] ?? [];
91
+ if (referencedFiles.length > 0 || requirements.length > 0) {
92
+ parts.push("# Referenced Inputs");
93
+ if (requirements.length > 0) {
94
+ parts.push("**User Requirements:**");
95
+ requirements.forEach((req, i) => parts.push(`${i + 1}. ${req}`));
96
+ parts.push("");
97
+ }
98
+ if (referencedFiles.length > 0) {
99
+ parts.push("**Referenced Files:**");
100
+ referencedFiles.forEach((ref) => parts.push(`- ${ref}`));
101
+ parts.push("");
102
+ }
103
+ if (missingFiles.length > 0) {
104
+ parts.push("**Missing Files (note and plan around gaps):**");
105
+ missingFiles.forEach((ref) => parts.push(`- ${ref}`));
106
+ parts.push("");
107
+ }
108
+ if (fileSummaries.length > 0) {
109
+ parts.push("**File Summaries (use these, do not invent):**");
110
+ for (const summary of fileSummaries) {
111
+ parts.push(`- ${summary.path}`);
112
+ parts.push(summary.summary);
113
+ parts.push("");
114
+ }
115
+ }
116
+ }
86
117
  if (atom.ownershipPaths.length > 0) {
87
118
  parts.push("**Ownership Paths (files this atom can modify):**");
88
119
  atom.ownershipPaths.forEach((p) => parts.push(`- ${p}`));
@@ -1,3 +1,6 @@
1
+ import {
2
+ createAuthedSupabaseClient
3
+ } from "./chunk-Q3GIFHIQ.js";
1
4
  import {
2
5
  SUPABASE_ANON_KEY,
3
6
  SUPABASE_URL
@@ -7,14 +10,6 @@ import {
7
10
  loadConfig
8
11
  } from "./chunk-SVU7MLG6.js";
9
12
 
10
- // src/core/supabase/client.ts
11
- import { createClient } from "@supabase/supabase-js";
12
- function createAuthedSupabaseClient(supabaseUrl, supabaseAnonKey, accessToken) {
13
- return createClient(supabaseUrl, supabaseAnonKey, {
14
- global: { headers: { Authorization: `Bearer ${accessToken}` } }
15
- });
16
- }
17
-
18
13
  // src/cli/cloud.ts
19
14
  import chalk from "chalk";
20
15
  function getClient(accessToken) {
@@ -182,7 +177,6 @@ function getStatusIcon(status) {
182
177
  }
183
178
 
184
179
  export {
185
- createAuthedSupabaseClient,
186
180
  cloudStatus,
187
181
  cloudCancel,
188
182
  cloudLogs,
@@ -1,17 +1,20 @@
1
- import {
2
- ArchitectureParser
3
- } from "./chunk-5EVHUDQX.js";
4
1
  import {
5
2
  createAtom,
6
3
  validateAtom
7
4
  } from "./chunk-5CFGPXQ3.js";
8
5
  import {
9
6
  ArchitectAgent
10
- } from "./chunk-2NSWZDP7.js";
7
+ } from "./chunk-5BYCJAFM.js";
11
8
  import {
12
9
  AnthropicClient,
13
10
  getDefaultModel
14
11
  } from "./chunk-HJARQDQR.js";
12
+ import {
13
+ createAuthedSupabaseClient
14
+ } from "./chunk-Q3GIFHIQ.js";
15
+ import {
16
+ ArchitectureParser
17
+ } from "./chunk-5EVHUDQX.js";
15
18
  import {
16
19
  KeyManager
17
20
  } from "./chunk-RDG5BUED.js";
@@ -27,10 +30,9 @@ import {
27
30
  // src/cli/plan.ts
28
31
  import chalk from "chalk";
29
32
  import { existsSync } from "fs";
30
- import { readFile, writeFile, mkdir } from "fs/promises";
33
+ import { readFile, writeFile, mkdir, stat } from "fs/promises";
31
34
  import { join } from "path";
32
35
  import { createInterface } from "readline";
33
- import { createClient } from "@supabase/supabase-js";
34
36
 
35
37
  // src/agents/sentinel.ts
36
38
  var SYSTEM_PROMPT = `You are the Sentinel, a paranoid and skeptical code reviewer responsible for finding issues in implementation plans.
@@ -125,6 +127,37 @@ var SentinelAgent = class {
125
127
  parts.push("**Acceptance Criteria:**");
126
128
  atom.acceptanceCriteria.forEach((ac, i) => parts.push(`${i + 1}. ${ac}`));
127
129
  parts.push("");
130
+ const contextMeta = atom.context;
131
+ const referencedFiles = contextMeta?.["referencedFiles"] ?? [];
132
+ const missingFiles = contextMeta?.["missingFiles"] ?? [];
133
+ const requirements = contextMeta?.["requirements"] ?? [];
134
+ const fileSummaries = contextMeta?.["fileSummaries"] ?? [];
135
+ if (referencedFiles.length > 0 || requirements.length > 0) {
136
+ parts.push("# Referenced Inputs");
137
+ if (requirements.length > 0) {
138
+ parts.push("**User Requirements:**");
139
+ requirements.forEach((req, i) => parts.push(`${i + 1}. ${req}`));
140
+ parts.push("");
141
+ }
142
+ if (referencedFiles.length > 0) {
143
+ parts.push("**Referenced Files:**");
144
+ referencedFiles.forEach((ref) => parts.push(`- ${ref}`));
145
+ parts.push("");
146
+ }
147
+ if (missingFiles.length > 0) {
148
+ parts.push("**Missing Files (plan must acknowledge gaps):**");
149
+ missingFiles.forEach((ref) => parts.push(`- ${ref}`));
150
+ parts.push("");
151
+ }
152
+ if (fileSummaries.length > 0) {
153
+ parts.push("**File Summaries:**");
154
+ for (const summary of fileSummaries) {
155
+ parts.push(`- ${summary.path}`);
156
+ parts.push(summary.summary);
157
+ parts.push("");
158
+ }
159
+ }
160
+ }
128
161
  parts.push("# Implementation Plan to Validate");
129
162
  parts.push("");
130
163
  parts.push("**Steps:**");
@@ -770,9 +803,63 @@ async function plan(description, options) {
770
803
  }
771
804
  process.exit(1);
772
805
  }
806
+ const requirements = extractNumberedRequirements(description);
807
+ const references = extractReferencedFiles(description);
808
+ const { foundFiles, missingFiles, fileSummaries } = await loadReferencedFileSummaries(references);
809
+ if (references.length > 0) {
810
+ console.log(chalk.dim("\nReferenced inputs detected:"));
811
+ for (const ref of references) {
812
+ const status = foundFiles.includes(ref) ? chalk.green("\u2713") : chalk.yellow("!");
813
+ console.log(` ${status} ${ref}`);
814
+ }
815
+ if (missingFiles.length > 0) {
816
+ console.log(chalk.yellow("\nMissing referenced files:"));
817
+ for (const missing of missingFiles) {
818
+ console.log(chalk.yellow(` - ${missing}`));
819
+ }
820
+ console.log(chalk.dim("\nHow would you like to proceed?"));
821
+ console.log(chalk.dim(" 1) Cancel planning and add the missing files"));
822
+ console.log(chalk.dim(" 2) Continue and mark missing files as required"));
823
+ console.log(chalk.dim(" 3) Continue with default placeholders"));
824
+ const proceedChoice = await prompt.ask("Choose 1/2/3 (default: 1): ");
825
+ const choice = proceedChoice.trim() || "1";
826
+ if (choice === "1") {
827
+ console.log(chalk.dim("Planning cancelled."));
828
+ return;
829
+ }
830
+ if (choice === "2") {
831
+ missingFiles.forEach((file) => requirements.push(`Missing input required: ${file}`));
832
+ }
833
+ if (choice === "3") {
834
+ missingFiles.forEach((file) => requirements.push(`Use default placeholder for missing input: ${file}`));
835
+ }
836
+ }
837
+ }
838
+ const deliverableTarget = await promptForDeliverableTarget(
839
+ prompt,
840
+ requirements,
841
+ references
842
+ );
843
+ if (deliverableTarget) {
844
+ requirements.push(`Deliverables saved to: ${deliverableTarget}`);
845
+ }
846
+ if (requirements.length > 0) {
847
+ console.log(chalk.dim("\nDetected requirements:"));
848
+ requirements.forEach((req, i) => console.log(` ${i + 1}. ${req}`));
849
+ const confirm = await prompt.ask("\nUse these as acceptance criteria? (Y/n): ");
850
+ if (confirm.toLowerCase() === "n") {
851
+ requirements.length = 0;
852
+ }
853
+ }
773
854
  console.log(chalk.dim("Creating atom from description..."));
774
- const atomInput = parseAtomDescription(description, options);
775
- const atom = createAtom(atomInput);
855
+ const atomInput = parseAtomDescription(description, options, requirements);
856
+ const atom = createAtom(atomInput, {
857
+ referencedFiles: references,
858
+ fileSummaries,
859
+ missingFiles,
860
+ requirements,
861
+ deliverableTarget
862
+ });
776
863
  const validation = validateAtom(atom);
777
864
  if (!validation.valid) {
778
865
  console.error(chalk.red("Invalid atom:"));
@@ -806,12 +893,15 @@ Atom saved: ${atom.externalId}`));
806
893
  console.log(chalk.dim("Architect will generate a plan, Sentinel will validate it.\n"));
807
894
  const config = await loadConfig();
808
895
  let billingContext;
809
- if (config.userId) {
810
- const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);
811
- billingContext = {
812
- userId: config.userId,
813
- supabase
814
- };
896
+ if (config.userId && config.accessToken) {
897
+ const profileId = await resolveProfileId(config.userId, config.accessToken);
898
+ if (profileId) {
899
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, config.accessToken);
900
+ billingContext = {
901
+ userId: profileId,
902
+ supabase
903
+ };
904
+ }
815
905
  }
816
906
  const planner = billingContext ? new TrackedAdversarialPlanner({ apiKey, billing: billingContext }) : new AdversarialPlanner({ apiKey });
817
907
  if (billingContext && planner instanceof TrackedAdversarialPlanner) {
@@ -882,13 +972,16 @@ Next steps:`));
882
972
  prompt.close();
883
973
  }
884
974
  }
885
- function parseAtomDescription(description, options) {
975
+ function parseAtomDescription(description, options, extractedCriteria = []) {
976
+ const title = deriveTitle(description);
886
977
  const parts = description.split(" - ");
887
- const title = parts[0]?.trim() ?? description;
888
978
  let acceptanceCriteria = [];
889
979
  if (parts.length > 1) {
890
980
  acceptanceCriteria = (parts[1] ?? "").split(",").map((ac) => ac.trim());
891
981
  }
982
+ if (acceptanceCriteria.length === 0 && extractedCriteria.length > 0) {
983
+ acceptanceCriteria = [...extractedCriteria];
984
+ }
892
985
  if (acceptanceCriteria.length === 0) {
893
986
  acceptanceCriteria = ["Feature implemented as described", "Typecheck passes", "Tests pass"];
894
987
  }
@@ -901,6 +994,129 @@ function parseAtomDescription(description, options) {
901
994
  tags
902
995
  };
903
996
  }
997
+ function deriveTitle(description) {
998
+ const dashIndex = description.indexOf(" - ");
999
+ if (dashIndex > 0) {
1000
+ return description.slice(0, dashIndex).trim();
1001
+ }
1002
+ const bracketIndex = description.indexOf("[1]");
1003
+ if (bracketIndex > 0) {
1004
+ return description.slice(0, bracketIndex).trim();
1005
+ }
1006
+ const line = description.split("\n")[0] ?? description;
1007
+ const trimmed = line.trim();
1008
+ return trimmed.length > 0 ? trimmed : description.trim();
1009
+ }
1010
+ function extractNumberedRequirements(description) {
1011
+ const requirements = [];
1012
+ const bracketPattern = /\[\s*(\d+)\s*\]\s*([^\[]+)/g;
1013
+ let match;
1014
+ while ((match = bracketPattern.exec(description)) !== null) {
1015
+ const text = match[2]?.trim();
1016
+ if (text) {
1017
+ requirements.push(text.replace(/\s+/g, " "));
1018
+ }
1019
+ }
1020
+ if (requirements.length > 0) {
1021
+ return requirements;
1022
+ }
1023
+ const lines = description.split("\n");
1024
+ for (const line of lines) {
1025
+ const listMatch = line.match(/^\s*\d+[\)\.]\s*(.+)$/);
1026
+ if (listMatch?.[1]) {
1027
+ requirements.push(listMatch[1].trim());
1028
+ }
1029
+ }
1030
+ return requirements;
1031
+ }
1032
+ function extractReferencedFiles(description) {
1033
+ const references = /* @__PURE__ */ new Set();
1034
+ const barePattern = /\b[\w./-]+\.(md|txt|json|yaml|yml|png|jpg|jpeg|gif|svg|pdf)\b/gi;
1035
+ const quotedPattern = /"([^"]+\.(?:md|txt|json|yaml|yml|png|jpg|jpeg|gif|svg|pdf))"/gi;
1036
+ let match;
1037
+ while ((match = quotedPattern.exec(description)) !== null) {
1038
+ if (match[1]) {
1039
+ references.add(match[1]);
1040
+ }
1041
+ }
1042
+ while ((match = barePattern.exec(description)) !== null) {
1043
+ if (match[0]) {
1044
+ references.add(match[0].replace(/["'`,]/g, "").trim());
1045
+ }
1046
+ }
1047
+ return Array.from(references).filter((ref) => ref.length > 0);
1048
+ }
1049
+ async function loadReferencedFileSummaries(references) {
1050
+ const foundFiles = [];
1051
+ const missingFiles = [];
1052
+ const fileSummaries = [];
1053
+ for (const ref of references) {
1054
+ const normalized = ref.replace(/^\.?\//, "");
1055
+ const absolute = join(process.cwd(), normalized);
1056
+ if (!existsSync(absolute)) {
1057
+ missingFiles.push(ref);
1058
+ continue;
1059
+ }
1060
+ foundFiles.push(ref);
1061
+ const isImage = /\.(png|jpg|jpeg|gif|svg)$/i.test(ref);
1062
+ if (isImage) {
1063
+ try {
1064
+ const fileStat = await stat(absolute);
1065
+ fileSummaries.push({
1066
+ path: ref,
1067
+ summary: `Image file (${fileStat.size} bytes). Use as visual style reference.`
1068
+ });
1069
+ } catch {
1070
+ fileSummaries.push({
1071
+ path: ref,
1072
+ summary: "Image file present. Use as visual style reference."
1073
+ });
1074
+ }
1075
+ continue;
1076
+ }
1077
+ try {
1078
+ const content = await readFile(absolute, "utf-8");
1079
+ const snippet = content.slice(0, 2e3);
1080
+ fileSummaries.push({
1081
+ path: ref,
1082
+ summary: snippet + (content.length > 2e3 ? "\n... [truncated]" : "")
1083
+ });
1084
+ } catch {
1085
+ fileSummaries.push({
1086
+ path: ref,
1087
+ summary: "File exists but could not be read."
1088
+ });
1089
+ }
1090
+ }
1091
+ return { foundFiles, missingFiles, fileSummaries };
1092
+ }
1093
+ async function promptForDeliverableTarget(prompt, requirements, references) {
1094
+ const mentionsResearch = requirements.some((req) => req.toLowerCase().includes("research"));
1095
+ const defaultTarget = references.find((ref) => ref.toLowerCase().endsWith(".md"));
1096
+ if (!mentionsResearch && !defaultTarget) {
1097
+ return null;
1098
+ }
1099
+ console.log(chalk.dim("\nWhere should the deliverables be written?"));
1100
+ if (defaultTarget) {
1101
+ console.log(chalk.dim(`Press Enter to use ${defaultTarget}`));
1102
+ }
1103
+ const answer = await prompt.ask("Target file or folder (leave blank to skip): ");
1104
+ const trimmed = answer.trim();
1105
+ if (trimmed.length === 0) {
1106
+ return defaultTarget ?? null;
1107
+ }
1108
+ return trimmed;
1109
+ }
1110
+ async function resolveProfileId(authId, accessToken) {
1111
+ try {
1112
+ const supabase = createAuthedSupabaseClient(SUPABASE_URL, SUPABASE_ANON_KEY, accessToken);
1113
+ const { data, error } = await supabase.from("user_profiles").select("id").eq("auth_id", authId).single();
1114
+ if (error || !data?.id) return null;
1115
+ return data.id;
1116
+ } catch {
1117
+ return null;
1118
+ }
1119
+ }
904
1120
  function displayPlan(plan2) {
905
1121
  console.log(chalk.bold("\n\u{1F4DD} Implementation Plan"));
906
1122
  console.log(chalk.dim("\u2500".repeat(40)));
@@ -2,11 +2,11 @@ import {
2
2
  getGitBranch,
3
3
  getGitRemoteUrl,
4
4
  queueCloudExecution
5
- } from "./chunk-Z65525NP.js";
5
+ } from "./chunk-EBHHIUCB.js";
6
6
  import {
7
7
  listLocalAtoms,
8
8
  loadAtom
9
- } from "./chunk-3PZ7WU5I.js";
9
+ } from "./chunk-ESSNYHC7.js";
10
10
  import {
11
11
  loadConfig
12
12
  } from "./chunk-SVU7MLG6.js";
@@ -1,16 +1,12 @@
1
1
  import {
2
- createAuthedSupabaseClient,
3
2
  getGitBranch,
4
3
  getGitRemoteUrl,
5
4
  queueCloudExecution
6
- } from "./chunk-Z65525NP.js";
5
+ } from "./chunk-EBHHIUCB.js";
7
6
  import {
8
7
  UsageRecorder,
9
8
  loadAtom
10
- } from "./chunk-3PZ7WU5I.js";
11
- import {
12
- ArchitectureParser
13
- } from "./chunk-5EVHUDQX.js";
9
+ } from "./chunk-ESSNYHC7.js";
14
10
  import {
15
11
  transitionAtom
16
12
  } from "./chunk-5CFGPXQ3.js";
@@ -18,6 +14,12 @@ import {
18
14
  AnthropicClient,
19
15
  getDefaultModel
20
16
  } from "./chunk-HJARQDQR.js";
17
+ import {
18
+ createAuthedSupabaseClient
19
+ } from "./chunk-Q3GIFHIQ.js";
20
+ import {
21
+ ArchitectureParser
22
+ } from "./chunk-5EVHUDQX.js";
21
23
  import {
22
24
  SUPABASE_ANON_KEY,
23
25
  SUPABASE_URL
@@ -4791,7 +4793,7 @@ function createPrompt() {
4791
4793
  }
4792
4794
  async function execute(atomId, options) {
4793
4795
  if (options.parallel && options.parallel.length > 0) {
4794
- const { parallelExecute } = await import("./parallel-27ZWSW6B.js");
4796
+ const { parallelExecute } = await import("./parallel-U3COBCHB.js");
4795
4797
  const allAtomIds = [atomId, ...options.parallel];
4796
4798
  await parallelExecute(allAtomIds, { skipGates: options.skipGates === true });
4797
4799
  return;
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-3ASILTFB.js";
4
4
  import {
5
5
  ArchitectAgent
6
- } from "./chunk-2NSWZDP7.js";
6
+ } from "./chunk-5BYCJAFM.js";
7
7
  import {
8
8
  loadConfig
9
9
  } from "./chunk-SVU7MLG6.js";
@@ -0,0 +1,23 @@
1
+ // src/core/supabase/client.ts
2
+ import { createClient } from "@supabase/supabase-js";
3
+ function createAnonSupabaseClient(supabaseUrl, supabaseAnonKey) {
4
+ return createClient(supabaseUrl, supabaseAnonKey);
5
+ }
6
+ function createPkceSupabaseClient(supabaseUrl, supabaseAnonKey) {
7
+ return createClient(supabaseUrl, supabaseAnonKey, {
8
+ auth: {
9
+ flowType: "pkce"
10
+ }
11
+ });
12
+ }
13
+ function createAuthedSupabaseClient(supabaseUrl, supabaseAnonKey, accessToken) {
14
+ return createClient(supabaseUrl, supabaseAnonKey, {
15
+ global: { headers: { Authorization: `Bearer ${accessToken}` } }
16
+ });
17
+ }
18
+
19
+ export {
20
+ createAnonSupabaseClient,
21
+ createPkceSupabaseClient,
22
+ createAuthedSupabaseClient
23
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listLocalAtoms
3
- } from "./chunk-3PZ7WU5I.js";
3
+ } from "./chunk-ESSNYHC7.js";
4
4
 
5
5
  // src/cli/list.ts
6
6
  import chalk from "chalk";
@@ -0,0 +1,11 @@
1
+ import {
2
+ createAnonSupabaseClient,
3
+ createAuthedSupabaseClient,
4
+ createPkceSupabaseClient
5
+ } from "./chunk-Q3GIFHIQ.js";
6
+ import "./chunk-4VNS5WPM.js";
7
+ export {
8
+ createAnonSupabaseClient,
9
+ createAuthedSupabaseClient,
10
+ createPkceSupabaseClient
11
+ };
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  execute
3
- } from "./chunk-3WJIZGHN.js";
4
- import "./chunk-Z65525NP.js";
5
- import "./chunk-3PZ7WU5I.js";
6
- import "./chunk-5EVHUDQX.js";
3
+ } from "./chunk-MRRA3QDP.js";
4
+ import "./chunk-EBHHIUCB.js";
5
+ import "./chunk-ESSNYHC7.js";
7
6
  import "./chunk-5CFGPXQ3.js";
8
- import "./chunk-2NSWZDP7.js";
7
+ import "./chunk-5BYCJAFM.js";
9
8
  import "./chunk-HJARQDQR.js";
9
+ import "./chunk-Q3GIFHIQ.js";
10
+ import "./chunk-5EVHUDQX.js";
10
11
  import "./chunk-UFR2LX6G.js";
11
12
  import "./chunk-TFSHS7EN.js";
12
13
  import "./chunk-RDG5BUED.js";
@@ -4,9 +4,9 @@ import {
4
4
  geoFaq,
5
5
  geoIdentity,
6
6
  geoSchema
7
- } from "./chunk-UD45ZLV3.js";
7
+ } from "./chunk-OAHFRSDS.js";
8
8
  import "./chunk-3ASILTFB.js";
9
- import "./chunk-2NSWZDP7.js";
9
+ import "./chunk-5BYCJAFM.js";
10
10
  import "./chunk-HJARQDQR.js";
11
11
  import "./chunk-UFR2LX6G.js";
12
12
  import "./chunk-SVU7MLG6.js";
package/dist/index.js CHANGED
@@ -1,7 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ createSeoCommand
4
+ } from "./chunk-JF7JCK6H.js";
2
5
  import {
3
6
  createGeoCommand
4
- } from "./chunk-UD45ZLV3.js";
7
+ } from "./chunk-OAHFRSDS.js";
8
+ import {
9
+ bugReport
10
+ } from "./chunk-2BCITFWP.js";
5
11
  import {
6
12
  reviewAnalyze,
7
13
  reviewExport,
@@ -28,9 +34,6 @@ import {
28
34
  a11yFix,
29
35
  a11yPreDeploy
30
36
  } from "./chunk-FWLLGLD5.js";
31
- import {
32
- createSeoCommand
33
- } from "./chunk-JF7JCK6H.js";
34
37
  import "./chunk-3ASILTFB.js";
35
38
  import {
36
39
  init,
@@ -43,36 +46,35 @@ import {
43
46
  parallelRunWaves,
44
47
  parallelSchedule,
45
48
  parallelStatus
46
- } from "./chunk-DYYWJ5MO.js";
49
+ } from "./chunk-ICSHS6BW.js";
47
50
  import {
48
51
  DependencyParser,
49
52
  EnvironmentConfigLoader,
50
53
  EnvironmentValidator,
51
54
  execute
52
- } from "./chunk-3WJIZGHN.js";
55
+ } from "./chunk-MRRA3QDP.js";
53
56
  import {
54
57
  cloudCancel,
55
58
  cloudLogs,
56
- cloudStatus,
57
- createAuthedSupabaseClient
58
- } from "./chunk-Z65525NP.js";
59
+ cloudStatus
60
+ } from "./chunk-EBHHIUCB.js";
59
61
  import {
60
62
  list
61
- } from "./chunk-NJF6MRTR.js";
63
+ } from "./chunk-YFCC6QEY.js";
62
64
  import {
63
65
  listLocalAtoms,
64
66
  loadAtom,
65
67
  plan
66
- } from "./chunk-3PZ7WU5I.js";
68
+ } from "./chunk-ESSNYHC7.js";
69
+ import "./chunk-5CFGPXQ3.js";
70
+ import "./chunk-5BYCJAFM.js";
71
+ import "./chunk-HJARQDQR.js";
72
+ import {
73
+ createAuthedSupabaseClient
74
+ } from "./chunk-Q3GIFHIQ.js";
67
75
  import {
68
76
  ArchitectureParser
69
77
  } from "./chunk-5EVHUDQX.js";
70
- import {
71
- bugReport
72
- } from "./chunk-VF2OTDMS.js";
73
- import "./chunk-5CFGPXQ3.js";
74
- import "./chunk-2NSWZDP7.js";
75
- import "./chunk-HJARQDQR.js";
76
78
  import "./chunk-UFR2LX6G.js";
77
79
  import {
78
80
  addKey,
@@ -2769,26 +2771,30 @@ async function start(options = {}) {
2769
2771
  }
2770
2772
  if (currentTier === "CREDITS" && config.accessToken) {
2771
2773
  try {
2772
- const usageStats = await fetchCreditsUsageStats(config.accessToken);
2774
+ const usageStats = config.userId ? await fetchCreditsUsageStats(config.accessToken, config.userId) : null;
2773
2775
  if (usageStats) {
2774
2776
  console.log();
2775
2777
  console.log(chalk6.bold("\u{1F4B0} Credits Balance"));
2776
2778
  console.log(chalk6.dim("\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"));
2777
2779
  const balanceColor = usageStats.balance < 1 ? chalk6.red : usageStats.balance < 5 ? chalk6.yellow : chalk6.green;
2778
2780
  console.log(` Balance: ${balanceColor(`$${usageStats.balance.toFixed(2)}`)}`);
2781
+ if (usageStats.periodStart) {
2782
+ const periodDate = new Date(usageStats.periodStart);
2783
+ const formatted = isNaN(periodDate.getTime()) ? usageStats.periodStart : periodDate.toLocaleDateString();
2784
+ const label = usageStats.periodSource === "credit_purchase" ? `Since last top-up (${formatted})` : usageStats.periodSource === "month" ? `Since ${formatted}` : `Period start: ${formatted}`;
2785
+ console.log(chalk6.dim(` ${label}`));
2786
+ }
2779
2787
  if (usageStats.usedThisPeriod > 0) {
2780
- console.log(` Used this period: ${chalk6.dim(`$${usageStats.usedThisPeriod.toFixed(2)}`)}`);
2788
+ console.log(` Used since last top-up: ${chalk6.dim(`$${usageStats.usedThisPeriod.toFixed(2)}`)}`);
2789
+ } else {
2790
+ console.log(chalk6.dim(" No usage recorded since last top-up."));
2781
2791
  }
2782
2792
  if (usageStats.byModel && usageStats.byModel.length > 0) {
2783
2793
  console.log();
2784
2794
  console.log(chalk6.dim(" Model Usage:"));
2785
- const topModels = usageStats.byModel.slice(0, 3);
2786
- for (const model of topModels) {
2787
- const modelName = model.model.length > 25 ? model.model.slice(0, 22) + "..." : model.model;
2788
- console.log(chalk6.dim(` ${modelName.padEnd(26)} $${model.cost.toFixed(4)}`));
2789
- }
2790
- if (usageStats.byModel.length > 3) {
2791
- console.log(chalk6.dim(` ... and ${usageStats.byModel.length - 3} more (run 'archon credits history')`));
2795
+ for (const model of usageStats.byModel) {
2796
+ const modelName = model.model.length > 32 ? model.model.slice(0, 29) + "..." : model.model;
2797
+ console.log(chalk6.dim(` ${modelName.padEnd(34)} $${model.cost.toFixed(4)}`));
2792
2798
  }
2793
2799
  }
2794
2800
  console.log(chalk6.dim("\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"));
@@ -2909,7 +2915,7 @@ function formatTierName(tier) {
2909
2915
  return tier;
2910
2916
  }
2911
2917
  }
2912
- async function fetchCreditsUsageStats(accessToken) {
2918
+ async function fetchCreditsUsageStats(accessToken, authId) {
2913
2919
  try {
2914
2920
  const { API_URL: API_URL3 } = await import("./constants-XDIWFFPN.js");
2915
2921
  const response = await fetch(`${API_URL3}/api/usage`, {
@@ -2917,14 +2923,51 @@ async function fetchCreditsUsageStats(accessToken) {
2917
2923
  "Authorization": `Bearer ${accessToken}`
2918
2924
  }
2919
2925
  });
2920
- if (!response.ok) {
2926
+ if (response.ok) {
2927
+ const data = await response.json();
2928
+ return {
2929
+ balance: data.remainingCredits ?? 0,
2930
+ usedThisPeriod: data.totalBaseCost ?? 0,
2931
+ byModel: data.byModel ?? [],
2932
+ periodStart: data.periodStart,
2933
+ periodSource: data.periodSource,
2934
+ lastCreditPurchaseAt: data.lastCreditPurchaseAt ?? null
2935
+ };
2936
+ }
2937
+ } catch {
2938
+ }
2939
+ return fetchCreditsUsageStatsFromSupabase(accessToken, authId);
2940
+ }
2941
+ async function fetchCreditsUsageStatsFromSupabase(accessToken, authId) {
2942
+ try {
2943
+ const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-XDIWFFPN.js");
2944
+ const { createAuthedSupabaseClient: createAuthedSupabaseClient2 } = await import("./client-PHW2C2HB.js");
2945
+ const supabase = createAuthedSupabaseClient2(SUPABASE_URL2, SUPABASE_ANON_KEY2, accessToken);
2946
+ const { data: profile, error: profileError } = await supabase.from("user_profiles").select("id, credit_balance_cents").eq("auth_id", authId).single();
2947
+ if (profileError || !profile?.id) {
2921
2948
  return null;
2922
2949
  }
2923
- const data = await response.json();
2950
+ const { data: lastPurchase } = await supabase.from("credit_purchases").select("created_at").eq("user_id", profile.id).eq("status", "completed").order("created_at", { ascending: false }).limit(1).maybeSingle();
2951
+ const now = /* @__PURE__ */ new Date();
2952
+ const defaultStart = new Date(now.getFullYear(), now.getMonth(), 1).toISOString();
2953
+ const periodStart = lastPurchase?.created_at ?? defaultStart;
2954
+ const periodSource = lastPurchase?.created_at ? "credit_purchase" : "month";
2955
+ const { data: usageRows } = await supabase.from("token_usage").select("model, marked_up_cost, total_cents, created_at").eq("user_id", profile.id).gte("created_at", periodStart);
2956
+ const byModelMap = /* @__PURE__ */ new Map();
2957
+ let usedThisPeriod = 0;
2958
+ for (const row of usageRows ?? []) {
2959
+ const cost = typeof row.marked_up_cost === "number" ? row.marked_up_cost : typeof row.total_cents === "number" ? row.total_cents / 100 : 0;
2960
+ usedThisPeriod += cost;
2961
+ byModelMap.set(row.model, (byModelMap.get(row.model) ?? 0) + cost);
2962
+ }
2963
+ const byModel = Array.from(byModelMap.entries()).map(([model, cost]) => ({ model, cost })).sort((a, b) => b.cost - a.cost);
2924
2964
  return {
2925
- balance: data.remainingCredits ?? 0,
2926
- usedThisPeriod: data.totalBaseCost ?? 0,
2927
- byModel: data.byModel ?? []
2965
+ balance: (profile.credit_balance_cents ?? 0) / 100,
2966
+ usedThisPeriod,
2967
+ byModel,
2968
+ periodStart,
2969
+ periodSource,
2970
+ lastCreditPurchaseAt: lastPurchase?.created_at ?? null
2928
2971
  };
2929
2972
  } catch {
2930
2973
  return null;
@@ -3084,7 +3127,7 @@ async function handleNewProject(cwd, _state) {
3084
3127
  }
3085
3128
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
3086
3129
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3087
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3130
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3088
3131
  await plan2(initialResponse, {});
3089
3132
  return;
3090
3133
  }
@@ -3108,7 +3151,7 @@ async function handleNewProject(cwd, _state) {
3108
3151
  break;
3109
3152
  case "2":
3110
3153
  console.log(chalk6.dim("\n> Creating a task for this...\n"));
3111
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3154
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3112
3155
  await plan2(initialResponse, {});
3113
3156
  break;
3114
3157
  case "3":
@@ -3138,7 +3181,7 @@ async function showNewProjectMenu(cwd) {
3138
3181
  case "3": {
3139
3182
  const description = await prompt("Describe what you want to do");
3140
3183
  if (description.trim()) {
3141
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3184
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3142
3185
  await plan2(description, {});
3143
3186
  }
3144
3187
  break;
@@ -3204,7 +3247,7 @@ async function runExploreFlow(cwd) {
3204
3247
  case "1": {
3205
3248
  const description = await prompt("Describe what you want to do");
3206
3249
  if (description.trim()) {
3207
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3250
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3208
3251
  await plan2(description, {});
3209
3252
  }
3210
3253
  break;
@@ -3463,7 +3506,7 @@ ${state.forbiddenPatterns?.length ? `- **Forbidden patterns:** ${state.forbidden
3463
3506
  if (continueChoice) {
3464
3507
  const description = await prompt("Describe what you want to build first");
3465
3508
  if (description.trim()) {
3466
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3509
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3467
3510
  await plan2(description, {});
3468
3511
  }
3469
3512
  }
@@ -3517,7 +3560,7 @@ async function handleAdaptExisting(cwd, state) {
3517
3560
  }
3518
3561
  if (intent.mode === "ad_hoc" && intent.confidence >= 0.7) {
3519
3562
  console.log(chalk6.dim("\n> Got it! Creating a task for this...\n"));
3520
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3563
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3521
3564
  await plan2(response, {});
3522
3565
  return;
3523
3566
  }
@@ -3548,7 +3591,7 @@ async function showAdaptExistingMenu(cwd, state) {
3548
3591
  case "2": {
3549
3592
  const description = await prompt("Describe what you want to do");
3550
3593
  if (description.trim()) {
3551
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3594
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3552
3595
  await plan2(description, {});
3553
3596
  }
3554
3597
  break;
@@ -3716,18 +3759,18 @@ async function showReviewProgress(cwd) {
3716
3759
  }
3717
3760
  }
3718
3761
  async function planTask() {
3719
- const { plan: plan2 } = await import("./plan-XALA4SLH.js");
3762
+ const { plan: plan2 } = await import("./plan-4RIHWWZG.js");
3720
3763
  const description = await prompt("Describe what you want to build");
3721
3764
  if (description.trim()) {
3722
3765
  await plan2(description, {});
3723
3766
  }
3724
3767
  }
3725
3768
  async function listAtoms() {
3726
- const { list: list2 } = await import("./list-CNKAH354.js");
3769
+ const { list: list2 } = await import("./list-BJCKDRG4.js");
3727
3770
  await list2({});
3728
3771
  }
3729
3772
  async function executeNext() {
3730
- const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-XALA4SLH.js");
3773
+ const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-4RIHWWZG.js");
3731
3774
  const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-HIF3KP25.js");
3732
3775
  const { loadExecutionPreferences } = await import("./preferences-I6WETXOI.js");
3733
3776
  const cwd = process.cwd();
@@ -3798,11 +3841,11 @@ async function executeNext() {
3798
3841
  }
3799
3842
  }
3800
3843
  if (selectedMode === "parallel-cloud") {
3801
- const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-27ZWSW6B.js");
3844
+ const { parallelExecuteCloud: parallelExecuteCloud2 } = await import("./parallel-U3COBCHB.js");
3802
3845
  await parallelExecuteCloud2(runIds);
3803
3846
  return;
3804
3847
  }
3805
- const { parallelExecute } = await import("./parallel-27ZWSW6B.js");
3848
+ const { parallelExecute } = await import("./parallel-U3COBCHB.js");
3806
3849
  await parallelExecute(runIds);
3807
3850
  return;
3808
3851
  }
@@ -3810,14 +3853,14 @@ async function executeNext() {
3810
3853
  const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
3811
3854
  const targetId = atomId.trim() || pendingAtoms[0]?.id;
3812
3855
  if (targetId) {
3813
- const { execute: execute2 } = await import("./execute-2RL7NTHZ.js");
3856
+ const { execute: execute2 } = await import("./execute-OTW55P2Q.js");
3814
3857
  await execute2(targetId, {});
3815
3858
  } else {
3816
3859
  console.log(chalk6.yellow("No atom to execute."));
3817
3860
  }
3818
3861
  }
3819
3862
  async function reportBug() {
3820
- const { bugReport: bugReport2 } = await import("./bug-5WRBCFRT.js");
3863
+ const { bugReport: bugReport2 } = await import("./bug-DCFTT2AF.js");
3821
3864
  const title = await prompt("Bug title");
3822
3865
  if (title.trim()) {
3823
3866
  await bugReport2(title, {});
@@ -3943,7 +3986,7 @@ async function promptWithCommands(question) {
3943
3986
  async function runWebChecksSuite() {
3944
3987
  const { a11yCheck: a11yCheck2 } = await import("./a11y-O35BAA25.js");
3945
3988
  const { seoCheck } = await import("./seo-PMI42KRZ.js");
3946
- const { geoAudit } = await import("./geo-KV4IRGKN.js");
3989
+ const { geoAudit } = await import("./geo-GEWH777F.js");
3947
3990
  console.log(chalk6.blue("\nRunning web checks (A11y, SEO, GEO)...\n"));
3948
3991
  await a11yCheck2({});
3949
3992
  await seoCheck({});
@@ -3983,17 +4026,17 @@ async function showWebChecksMenu() {
3983
4026
  break;
3984
4027
  }
3985
4028
  case "4": {
3986
- const { geoAudit } = await import("./geo-KV4IRGKN.js");
4029
+ const { geoAudit } = await import("./geo-GEWH777F.js");
3987
4030
  await geoAudit();
3988
4031
  break;
3989
4032
  }
3990
4033
  case "5": {
3991
- const { geoIdentity } = await import("./geo-KV4IRGKN.js");
4034
+ const { geoIdentity } = await import("./geo-GEWH777F.js");
3992
4035
  await geoIdentity();
3993
4036
  break;
3994
4037
  }
3995
4038
  case "6": {
3996
- const { geoSchema } = await import("./geo-KV4IRGKN.js");
4039
+ const { geoSchema } = await import("./geo-GEWH777F.js");
3997
4040
  await geoSchema({});
3998
4041
  break;
3999
4042
  }
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  list
3
- } from "./chunk-NJF6MRTR.js";
4
- import "./chunk-3PZ7WU5I.js";
5
- import "./chunk-5EVHUDQX.js";
3
+ } from "./chunk-YFCC6QEY.js";
4
+ import "./chunk-ESSNYHC7.js";
6
5
  import "./chunk-5CFGPXQ3.js";
7
- import "./chunk-2NSWZDP7.js";
6
+ import "./chunk-5BYCJAFM.js";
8
7
  import "./chunk-HJARQDQR.js";
8
+ import "./chunk-Q3GIFHIQ.js";
9
+ import "./chunk-5EVHUDQX.js";
9
10
  import "./chunk-UFR2LX6G.js";
10
11
  import "./chunk-TFSHS7EN.js";
11
12
  import "./chunk-RDG5BUED.js";
@@ -6,13 +6,14 @@ import {
6
6
  parallelRunWaves,
7
7
  parallelSchedule,
8
8
  parallelStatus
9
- } from "./chunk-DYYWJ5MO.js";
10
- import "./chunk-Z65525NP.js";
11
- import "./chunk-3PZ7WU5I.js";
12
- import "./chunk-5EVHUDQX.js";
9
+ } from "./chunk-ICSHS6BW.js";
10
+ import "./chunk-EBHHIUCB.js";
11
+ import "./chunk-ESSNYHC7.js";
13
12
  import "./chunk-5CFGPXQ3.js";
14
- import "./chunk-2NSWZDP7.js";
13
+ import "./chunk-5BYCJAFM.js";
15
14
  import "./chunk-HJARQDQR.js";
15
+ import "./chunk-Q3GIFHIQ.js";
16
+ import "./chunk-5EVHUDQX.js";
16
17
  import "./chunk-UFR2LX6G.js";
17
18
  import "./chunk-TFSHS7EN.js";
18
19
  import "./chunk-RDG5BUED.js";
@@ -3,11 +3,12 @@ import {
3
3
  loadAtom,
4
4
  parseAtomDescription,
5
5
  plan
6
- } from "./chunk-3PZ7WU5I.js";
7
- import "./chunk-5EVHUDQX.js";
6
+ } from "./chunk-ESSNYHC7.js";
8
7
  import "./chunk-5CFGPXQ3.js";
9
- import "./chunk-2NSWZDP7.js";
8
+ import "./chunk-5BYCJAFM.js";
10
9
  import "./chunk-HJARQDQR.js";
10
+ import "./chunk-Q3GIFHIQ.js";
11
+ import "./chunk-5EVHUDQX.js";
11
12
  import "./chunk-UFR2LX6G.js";
12
13
  import "./chunk-TFSHS7EN.js";
13
14
  import "./chunk-RDG5BUED.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archondev",
3
- "version": "2.18.4",
3
+ "version": "2.18.7",
4
4
  "description": "Local-first AI-powered development governance system",
5
5
  "main": "dist/index.js",
6
6
  "bin": {