archondev 2.1.6 → 2.2.0
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 +2 -0
- package/dist/{auth-COINREKK.js → auth-R6G5RDJE.js} +3 -2
- package/dist/{bug-K4V357B2.js → bug-IT4C6HIG.js} +2 -2
- package/dist/{chunk-UI4UQ24R.js → chunk-2BPIPDFV.js} +32 -6
- package/dist/{chunk-RCW22YNI.js → chunk-5HVYNCLT.js} +4 -4
- package/dist/{chunk-TEY4GCMH.js → chunk-7FJ4ATJE.js} +1 -1
- package/dist/{chunk-SSSEOM25.js → chunk-BBAUT4M5.js} +1 -1
- package/dist/chunk-C5TDNTNC.js +265 -0
- package/dist/{chunk-KF6MFAB4.js → chunk-GLBVZOBA.js} +1 -1
- package/dist/{chunk-3NPZQOK2.js → chunk-HGO4UUAC.js} +4 -4
- package/dist/{chunk-TSSFMB6E.js → chunk-OI4K3RYO.js} +1 -1
- package/dist/{chunk-F3RLDQTQ.js → chunk-XP7PNLXG.js} +4 -4
- package/dist/{chunk-IVY5AHPS.js → chunk-Y7DQ5XTU.js} +46 -2
- package/dist/{config-FTSBI4XE.js → config-SU5Y6MKO.js} +3 -1
- package/dist/{execute-5ZSLSWPZ.js → execute-6D6USH33.js} +4 -4
- package/dist/index.js +37 -32
- package/dist/{keys-IHYIP43K.js → keys-76UFD2QR.js} +2 -2
- package/dist/{list-LEFAISNL.js → list-XZ42CNFC.js} +4 -4
- package/dist/{parallel-5WJAXTYL.js → parallel-IC6FLPSK.js} +4 -4
- package/dist/{plan-W2UXAR6E.js → plan-TVTKS655.js} +3 -3
- package/dist/{preferences-3Z4OCNTT.js → preferences-VY6WPI6V.js} +4 -3
- package/dist/tier-selection-JYMYBIRV.js +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,8 @@ Copy governance files into any project. Works with your existing AI tools: **Cur
|
|
|
53
53
|
|---------|-------------|
|
|
54
54
|
| `archon` | Interactive mode — just run and follow prompts |
|
|
55
55
|
| `archon init` | Initialize in your project |
|
|
56
|
+
| `archon login` | Authenticate with ArchonDev (tier selection on first login) |
|
|
57
|
+
| `archon pricing` | View and switch pricing tiers (Free, BYOK, Credits) |
|
|
56
58
|
| `archon plan <description>` | Create a work item with AI planning (extracts and confirms multi-item requests) |
|
|
57
59
|
| `archon execute <atom-id>` | Execute with quality gates |
|
|
58
60
|
| `archon list` | List all work items |
|
|
@@ -2,9 +2,10 @@ import {
|
|
|
2
2
|
login,
|
|
3
3
|
logout,
|
|
4
4
|
status
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2BPIPDFV.js";
|
|
6
|
+
import "./chunk-C5TDNTNC.js";
|
|
6
7
|
import "./chunk-M4LGRTLC.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
8
9
|
import "./chunk-QGM4M3NI.js";
|
|
9
10
|
export {
|
|
10
11
|
login,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
bugReport
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GLBVZOBA.js";
|
|
4
4
|
import "./chunk-5IQKC2TD.js";
|
|
5
5
|
import "./chunk-A7QU6JC6.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
7
7
|
import "./chunk-QGM4M3NI.js";
|
|
8
8
|
export {
|
|
9
9
|
bugReport
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleTierSetup,
|
|
3
|
+
promptTierSelection,
|
|
4
|
+
updateUserTier
|
|
5
|
+
} from "./chunk-C5TDNTNC.js";
|
|
1
6
|
import {
|
|
2
7
|
SUPABASE_ANON_KEY,
|
|
3
8
|
SUPABASE_URL
|
|
@@ -6,7 +11,7 @@ import {
|
|
|
6
11
|
clearConfig,
|
|
7
12
|
loadConfig,
|
|
8
13
|
saveConfig
|
|
9
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
10
15
|
|
|
11
16
|
// src/cli/auth.ts
|
|
12
17
|
import { createClient } from "@supabase/supabase-js";
|
|
@@ -54,11 +59,15 @@ async function login(provider = "github") {
|
|
|
54
59
|
}
|
|
55
60
|
if (sessionData.session) {
|
|
56
61
|
let userTier = "FREE";
|
|
62
|
+
let isFirstTimeUser = true;
|
|
57
63
|
try {
|
|
58
|
-
const { data: profileData } = await supabase.from("user_profiles").select("tier").eq("auth_id", sessionData.user.id).single();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
const { data: profileData, error: profileError } = await supabase.from("user_profiles").select("tier").eq("auth_id", sessionData.user.id).single();
|
|
65
|
+
if (!profileError && profileData) {
|
|
66
|
+
const profile = profileData;
|
|
67
|
+
if (profile?.tier) {
|
|
68
|
+
userTier = profile.tier;
|
|
69
|
+
isFirstTimeUser = false;
|
|
70
|
+
}
|
|
62
71
|
}
|
|
63
72
|
} catch {
|
|
64
73
|
}
|
|
@@ -71,7 +80,24 @@ async function login(provider = "github") {
|
|
|
71
80
|
expiresAt: new Date(sessionData.session.expires_at ?? Date.now() + 36e5).toISOString()
|
|
72
81
|
});
|
|
73
82
|
spinner.succeed(chalk.green(`Logged in as ${sessionData.user.email}`));
|
|
74
|
-
|
|
83
|
+
if (isFirstTimeUser) {
|
|
84
|
+
const selection = await promptTierSelection();
|
|
85
|
+
if (selection && !selection.skipped) {
|
|
86
|
+
const updateResult = await updateUserTier(selection.tier);
|
|
87
|
+
if (updateResult.success) {
|
|
88
|
+
userTier = selection.tier;
|
|
89
|
+
console.log(chalk.green(`
|
|
90
|
+
\u2713 Tier set to ${formatTier(userTier)}`));
|
|
91
|
+
await handleTierSetup(selection.tier);
|
|
92
|
+
}
|
|
93
|
+
} else if (selection?.skipped) {
|
|
94
|
+
userTier = "FREE";
|
|
95
|
+
}
|
|
96
|
+
const config = await loadConfig();
|
|
97
|
+
await saveConfig({ ...config, tier: userTier });
|
|
98
|
+
} else {
|
|
99
|
+
console.log(chalk.dim(`Tier: ${formatTier(userTier)}`));
|
|
100
|
+
}
|
|
75
101
|
}
|
|
76
102
|
}
|
|
77
103
|
} catch (error) {
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
createAtom,
|
|
4
4
|
validateAtom
|
|
5
5
|
} from "./chunk-5IQKC2TD.js";
|
|
6
|
+
import {
|
|
7
|
+
KeyManager
|
|
8
|
+
} from "./chunk-SMR7JQK6.js";
|
|
6
9
|
import {
|
|
7
10
|
AnthropicClient,
|
|
8
11
|
getDefaultModel
|
|
9
12
|
} from "./chunk-A7QU6JC6.js";
|
|
10
|
-
import {
|
|
11
|
-
KeyManager
|
|
12
|
-
} from "./chunk-SMR7JQK6.js";
|
|
13
13
|
import {
|
|
14
14
|
isAuthenticated
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
16
16
|
import {
|
|
17
17
|
ArchitectureParser
|
|
18
18
|
} from "./chunk-5EVHUDQX.js";
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import {
|
|
2
|
+
API_URL
|
|
3
|
+
} from "./chunk-M4LGRTLC.js";
|
|
4
|
+
import {
|
|
5
|
+
getApiUrl,
|
|
6
|
+
loadConfig,
|
|
7
|
+
saveConfig
|
|
8
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
9
|
+
|
|
10
|
+
// src/cli/tier-selection.ts
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import readline from "readline";
|
|
13
|
+
import ora from "ora";
|
|
14
|
+
import open from "open";
|
|
15
|
+
var TIER_INFO = {
|
|
16
|
+
FREE: {
|
|
17
|
+
name: "Free",
|
|
18
|
+
tagline: "Get started at no cost",
|
|
19
|
+
description: "Use ultra-cheap AI models (GPT-5-nano, Gemini Flash-Lite)",
|
|
20
|
+
limits: "Limited to $1/day, $5/month in AI usage",
|
|
21
|
+
models: "Basic models only",
|
|
22
|
+
cost: "$0"
|
|
23
|
+
},
|
|
24
|
+
BYOK: {
|
|
25
|
+
name: "BYOK (Bring Your Own Key)",
|
|
26
|
+
tagline: "Use your own API keys",
|
|
27
|
+
description: "Connect your Anthropic, OpenAI, or Google API keys",
|
|
28
|
+
limits: "Unlimited usage (you pay providers directly)",
|
|
29
|
+
models: "All models available",
|
|
30
|
+
cost: "$0 to ArchonDev"
|
|
31
|
+
},
|
|
32
|
+
CREDITS: {
|
|
33
|
+
name: "Credits",
|
|
34
|
+
tagline: "Pay-as-you-go with all models",
|
|
35
|
+
description: "We handle API access. Pay only for what you use.",
|
|
36
|
+
limits: "Unlimited usage",
|
|
37
|
+
models: "All models available (Claude, GPT-4, Gemini Pro, etc.)",
|
|
38
|
+
cost: "10% service fee on AI costs"
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
async function promptTierSelection() {
|
|
42
|
+
console.log();
|
|
43
|
+
console.log(chalk.bold("\u{1F389} Welcome to ArchonDev!"));
|
|
44
|
+
console.log();
|
|
45
|
+
console.log(chalk.dim("Choose how you want to use AI models:"));
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(` ${chalk.cyan("1")}) ${chalk.bold(TIER_INFO.FREE.name)}`);
|
|
48
|
+
console.log(chalk.dim(` ${TIER_INFO.FREE.description}`));
|
|
49
|
+
console.log(chalk.dim(` ${TIER_INFO.FREE.limits}`));
|
|
50
|
+
console.log();
|
|
51
|
+
console.log(` ${chalk.cyan("2")}) ${chalk.bold(TIER_INFO.BYOK.name)}`);
|
|
52
|
+
console.log(chalk.dim(` ${TIER_INFO.BYOK.description}`));
|
|
53
|
+
console.log(chalk.green(` \u2713 ${TIER_INFO.BYOK.models}`));
|
|
54
|
+
console.log();
|
|
55
|
+
console.log(` ${chalk.cyan("3")}) ${chalk.bold(TIER_INFO.CREDITS.name)}`);
|
|
56
|
+
console.log(chalk.dim(` ${TIER_INFO.CREDITS.description}`));
|
|
57
|
+
console.log(chalk.green(` \u2713 ${TIER_INFO.CREDITS.models}`));
|
|
58
|
+
console.log(chalk.dim(` ${TIER_INFO.CREDITS.cost}`));
|
|
59
|
+
console.log();
|
|
60
|
+
console.log(` ${chalk.dim("s")}) ${chalk.dim("Skip for now (defaults to Free)")}`);
|
|
61
|
+
console.log();
|
|
62
|
+
const choice = await prompt("Enter choice (1-3 or s)");
|
|
63
|
+
switch (choice.toLowerCase()) {
|
|
64
|
+
case "1":
|
|
65
|
+
return { tier: "FREE", skipped: false };
|
|
66
|
+
case "2":
|
|
67
|
+
return { tier: "BYOK", skipped: false };
|
|
68
|
+
case "3":
|
|
69
|
+
return { tier: "CREDITS", skipped: false };
|
|
70
|
+
case "s":
|
|
71
|
+
case "skip":
|
|
72
|
+
case "":
|
|
73
|
+
console.log(chalk.dim("\nDefaulting to Free tier. You can change this anytime with `archon pricing`"));
|
|
74
|
+
return { tier: "FREE", skipped: true };
|
|
75
|
+
default:
|
|
76
|
+
console.log(chalk.yellow("Invalid choice. Defaulting to Free tier."));
|
|
77
|
+
return { tier: "FREE", skipped: true };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function handleTierSetup(tier) {
|
|
81
|
+
const result = {};
|
|
82
|
+
if (tier === "CREDITS") {
|
|
83
|
+
const addCredits = await promptYesNo(
|
|
84
|
+
"Would you like to add credits now? (minimum $5)",
|
|
85
|
+
true
|
|
86
|
+
);
|
|
87
|
+
if (addCredits) {
|
|
88
|
+
const checkoutUrl = await createCheckoutSession(500);
|
|
89
|
+
if (checkoutUrl) {
|
|
90
|
+
result.checkoutUrl = checkoutUrl;
|
|
91
|
+
console.log();
|
|
92
|
+
console.log(chalk.green("Opening checkout in browser..."));
|
|
93
|
+
try {
|
|
94
|
+
await open(checkoutUrl);
|
|
95
|
+
} catch {
|
|
96
|
+
console.log(chalk.dim(`Visit: ${checkoutUrl}`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
console.log(chalk.dim("\nYou can add credits later with `archon credits add`"));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (tier === "BYOK") {
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(chalk.blue("Next step: Add your API keys"));
|
|
106
|
+
console.log(chalk.dim("Run one of these commands:"));
|
|
107
|
+
console.log(chalk.dim(" archon keys add anthropic"));
|
|
108
|
+
console.log(chalk.dim(" archon keys add openai"));
|
|
109
|
+
console.log(chalk.dim(" archon keys add google"));
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
async function createCheckoutSession(amountCents) {
|
|
114
|
+
const spinner = ora("Preparing checkout...").start();
|
|
115
|
+
try {
|
|
116
|
+
const config = await loadConfig();
|
|
117
|
+
if (!config.accessToken || !config.userId) {
|
|
118
|
+
spinner.fail("Not logged in");
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const response = await fetch(`${API_URL}/api/checkout`, {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: {
|
|
124
|
+
"Content-Type": "application/json",
|
|
125
|
+
"Authorization": `Bearer ${config.accessToken}`
|
|
126
|
+
},
|
|
127
|
+
body: JSON.stringify({
|
|
128
|
+
userId: config.userId,
|
|
129
|
+
amountCents
|
|
130
|
+
})
|
|
131
|
+
});
|
|
132
|
+
const result = await response.json();
|
|
133
|
+
if (!response.ok || !result.success) {
|
|
134
|
+
spinner.fail(result.error?.error || "Failed to create checkout");
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
spinner.succeed("Checkout ready");
|
|
138
|
+
return result.data?.checkoutUrl || null;
|
|
139
|
+
} catch (err) {
|
|
140
|
+
spinner.fail("Error creating checkout");
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function showTierSwitchMenu() {
|
|
145
|
+
const config = await loadConfig();
|
|
146
|
+
const currentTier = config.tier || "FREE";
|
|
147
|
+
console.log();
|
|
148
|
+
console.log(chalk.bold("Pricing & Billing"));
|
|
149
|
+
console.log();
|
|
150
|
+
console.log(`Current tier: ${formatTierDisplay(currentTier)}`);
|
|
151
|
+
console.log();
|
|
152
|
+
console.log(chalk.dim("Choose a pricing model:\n"));
|
|
153
|
+
const tiers = [
|
|
154
|
+
{ key: "1", tier: "FREE", info: TIER_INFO.FREE },
|
|
155
|
+
{ key: "2", tier: "BYOK", info: TIER_INFO.BYOK },
|
|
156
|
+
{ key: "3", tier: "CREDITS", info: TIER_INFO.CREDITS }
|
|
157
|
+
];
|
|
158
|
+
for (const { key, tier, info } of tiers) {
|
|
159
|
+
const isCurrent = tier === currentTier;
|
|
160
|
+
const marker = isCurrent ? chalk.green("\u25CF ") : "\u25CB ";
|
|
161
|
+
console.log(` ${chalk.cyan(key)}) ${marker}${chalk.bold(info.name)}`);
|
|
162
|
+
console.log(chalk.dim(` ${info.description}`));
|
|
163
|
+
if (tier !== "FREE") {
|
|
164
|
+
console.log(chalk.green(` \u2713 ${info.models}`));
|
|
165
|
+
}
|
|
166
|
+
console.log();
|
|
167
|
+
}
|
|
168
|
+
console.log(` ${chalk.dim("b")}) Back`);
|
|
169
|
+
console.log();
|
|
170
|
+
const choice = await prompt("Enter choice");
|
|
171
|
+
if (choice.toLowerCase() === "b" || choice === "") {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const selected = tiers.find((t) => t.key === choice);
|
|
175
|
+
if (!selected) {
|
|
176
|
+
console.log(chalk.yellow("Invalid choice."));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
if (selected.tier === currentTier) {
|
|
180
|
+
console.log(chalk.dim("Already using this pricing model."));
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const spinner = ora(`Switching to ${selected.info.name}...`).start();
|
|
184
|
+
const result = await updateUserTier(selected.tier);
|
|
185
|
+
if (result.success) {
|
|
186
|
+
spinner.succeed(chalk.green(`Switched to ${selected.info.name}`));
|
|
187
|
+
await handleTierSetup(selected.tier);
|
|
188
|
+
} else {
|
|
189
|
+
spinner.fail(chalk.red(result.error || "Failed to update tier"));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function updateUserTier(tier) {
|
|
193
|
+
try {
|
|
194
|
+
const config = await loadConfig();
|
|
195
|
+
if (!config.accessToken) {
|
|
196
|
+
return { success: false, error: "Not logged in" };
|
|
197
|
+
}
|
|
198
|
+
const apiUrl = getApiUrl(config);
|
|
199
|
+
const response = await fetch(`${apiUrl}/api/preferences`, {
|
|
200
|
+
method: "PATCH",
|
|
201
|
+
headers: {
|
|
202
|
+
"Authorization": `Bearer ${config.accessToken}`,
|
|
203
|
+
"Content-Type": "application/json"
|
|
204
|
+
},
|
|
205
|
+
body: JSON.stringify({ tier })
|
|
206
|
+
});
|
|
207
|
+
if (!response.ok) {
|
|
208
|
+
const text = await response.text();
|
|
209
|
+
return { success: false, error: text };
|
|
210
|
+
}
|
|
211
|
+
await saveConfig({ ...config, tier });
|
|
212
|
+
return { success: true };
|
|
213
|
+
} catch (err) {
|
|
214
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
215
|
+
return { success: false, error: message };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function formatTierDisplay(tier) {
|
|
219
|
+
switch (tier) {
|
|
220
|
+
case "FREE":
|
|
221
|
+
return chalk.gray("Free");
|
|
222
|
+
case "CREDITS":
|
|
223
|
+
return chalk.green("Credits (Pay-as-you-go)");
|
|
224
|
+
case "BYOK":
|
|
225
|
+
return chalk.blue("BYOK (Bring Your Own Key)");
|
|
226
|
+
default:
|
|
227
|
+
return tier;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function prompt(question) {
|
|
231
|
+
return new Promise((resolve) => {
|
|
232
|
+
const rl = readline.createInterface({
|
|
233
|
+
input: process.stdin,
|
|
234
|
+
output: process.stdout
|
|
235
|
+
});
|
|
236
|
+
rl.question(`${chalk.cyan("?")} ${question}: `, (answer) => {
|
|
237
|
+
rl.close();
|
|
238
|
+
resolve(answer.trim());
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function promptYesNo(question, defaultValue) {
|
|
243
|
+
return new Promise((resolve) => {
|
|
244
|
+
const rl = readline.createInterface({
|
|
245
|
+
input: process.stdin,
|
|
246
|
+
output: process.stdout
|
|
247
|
+
});
|
|
248
|
+
const hint = defaultValue ? "(Y/n)" : "(y/N)";
|
|
249
|
+
rl.question(`${chalk.cyan("?")} ${question} ${hint}: `, (answer) => {
|
|
250
|
+
rl.close();
|
|
251
|
+
if (answer.trim() === "") {
|
|
252
|
+
resolve(defaultValue);
|
|
253
|
+
} else {
|
|
254
|
+
resolve(answer.toLowerCase().startsWith("y"));
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export {
|
|
261
|
+
promptTierSelection,
|
|
262
|
+
handleTierSetup,
|
|
263
|
+
showTierSwitchMenu,
|
|
264
|
+
updateUserTier
|
|
265
|
+
};
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-M4LGRTLC.js";
|
|
5
5
|
import {
|
|
6
6
|
loadAtom
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-5HVYNCLT.js";
|
|
8
8
|
import {
|
|
9
9
|
transitionAtom
|
|
10
10
|
} from "./chunk-5IQKC2TD.js";
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
import {
|
|
16
16
|
getAuthToken,
|
|
17
17
|
loadConfig
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
19
19
|
import {
|
|
20
20
|
ArchitectureParser
|
|
21
21
|
} from "./chunk-5EVHUDQX.js";
|
|
@@ -4815,7 +4815,7 @@ function createPrompt() {
|
|
|
4815
4815
|
}
|
|
4816
4816
|
async function execute(atomId, options) {
|
|
4817
4817
|
if (options.parallel && options.parallel.length > 0) {
|
|
4818
|
-
const { parallelExecute } = await import("./parallel-
|
|
4818
|
+
const { parallelExecute } = await import("./parallel-IC6FLPSK.js");
|
|
4819
4819
|
const allAtomIds = [atomId, ...options.parallel];
|
|
4820
4820
|
await parallelExecute(allAtomIds);
|
|
4821
4821
|
return;
|
|
@@ -5114,7 +5114,7 @@ async function watchCloudExecution(executionId) {
|
|
|
5114
5114
|
const pollInterval = 5e3;
|
|
5115
5115
|
let lastLogCount = 0;
|
|
5116
5116
|
const poll = async () => {
|
|
5117
|
-
const { loadConfig: loadConfig2, getAuthToken: getAuthToken2 } = await import("./config-
|
|
5117
|
+
const { loadConfig: loadConfig2, getAuthToken: getAuthToken2 } = await import("./config-SU5Y6MKO.js");
|
|
5118
5118
|
const { createClient: createClient2 } = await import("@supabase/supabase-js");
|
|
5119
5119
|
const { SUPABASE_URL: SUPABASE_URL2, SUPABASE_ANON_KEY: SUPABASE_ANON_KEY2 } = await import("./constants-AHP5F7HW.js");
|
|
5120
5120
|
const config = await loadConfig2();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
login
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-2BPIPDFV.js";
|
|
4
4
|
import {
|
|
5
5
|
keyManager
|
|
6
6
|
} from "./chunk-SMR7JQK6.js";
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getApiUrl,
|
|
9
9
|
getAuthToken,
|
|
10
10
|
loadConfig
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
12
12
|
|
|
13
13
|
// src/cli/preferences.ts
|
|
14
14
|
import chalk from "chalk";
|
|
@@ -782,7 +782,7 @@ async function manageApiKeys() {
|
|
|
782
782
|
if (removeIndex >= 0 && removeIndex < providers.length) {
|
|
783
783
|
const providerToRemove = providers[removeIndex];
|
|
784
784
|
if (providerToRemove) {
|
|
785
|
-
const { removeKey } = await import("./keys-
|
|
785
|
+
const { removeKey } = await import("./keys-76UFD2QR.js");
|
|
786
786
|
await removeKey(providerToRemove);
|
|
787
787
|
}
|
|
788
788
|
}
|
|
@@ -790,7 +790,7 @@ async function manageApiKeys() {
|
|
|
790
790
|
}
|
|
791
791
|
const provider = providerMap[choice];
|
|
792
792
|
if (provider) {
|
|
793
|
-
const { addKey } = await import("./keys-
|
|
793
|
+
const { addKey } = await import("./keys-76UFD2QR.js");
|
|
794
794
|
await addKey(provider);
|
|
795
795
|
}
|
|
796
796
|
}
|
|
@@ -3,8 +3,11 @@ import { homedir } from "os";
|
|
|
3
3
|
import { join } from "path";
|
|
4
4
|
import { readFile, writeFile, mkdir, chmod, unlink } from "fs/promises";
|
|
5
5
|
import { existsSync } from "fs";
|
|
6
|
+
import { createClient } from "@supabase/supabase-js";
|
|
6
7
|
var CONFIG_DIR = join(homedir(), ".archon");
|
|
7
8
|
var CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
9
|
+
var SUPABASE_URL = "https://yjdkcepktrbabmzhcmrt.supabase.co";
|
|
10
|
+
var SUPABASE_ANON_KEY = "sb_publishable_XSGLVPfLZx-HA2uL6xsGCQ_KjAx2TIa";
|
|
8
11
|
function getAuthToken(config) {
|
|
9
12
|
return config.accessToken;
|
|
10
13
|
}
|
|
@@ -45,12 +48,52 @@ async function isAuthenticated() {
|
|
|
45
48
|
}
|
|
46
49
|
if (config.expiresAt) {
|
|
47
50
|
const expiresAt = new Date(config.expiresAt);
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
const now = /* @__PURE__ */ new Date();
|
|
52
|
+
const fiveMinutesFromNow = new Date(now.getTime() + 5 * 60 * 1e3);
|
|
53
|
+
if (expiresAt < fiveMinutesFromNow) {
|
|
54
|
+
if (config.refreshToken) {
|
|
55
|
+
const refreshed = await refreshSession(config);
|
|
56
|
+
return refreshed;
|
|
57
|
+
}
|
|
58
|
+
if (expiresAt < now) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
50
61
|
}
|
|
51
62
|
}
|
|
52
63
|
return true;
|
|
53
64
|
}
|
|
65
|
+
async function refreshSession(config) {
|
|
66
|
+
if (!config.refreshToken) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
|
|
71
|
+
auth: { flowType: "pkce" }
|
|
72
|
+
});
|
|
73
|
+
const { data, error } = await supabase.auth.refreshSession({
|
|
74
|
+
refresh_token: config.refreshToken
|
|
75
|
+
});
|
|
76
|
+
if (error || !data.session) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
await saveConfig({
|
|
80
|
+
...config,
|
|
81
|
+
accessToken: data.session.access_token,
|
|
82
|
+
refreshToken: data.session.refresh_token,
|
|
83
|
+
expiresAt: new Date(data.session.expires_at ?? Date.now() + 36e5).toISOString()
|
|
84
|
+
});
|
|
85
|
+
return true;
|
|
86
|
+
} catch {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function ensureValidSession() {
|
|
91
|
+
const isAuth = await isAuthenticated();
|
|
92
|
+
if (!isAuth) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return await loadConfig();
|
|
96
|
+
}
|
|
54
97
|
async function getCurrentUser() {
|
|
55
98
|
const config = await loadConfig();
|
|
56
99
|
if (!config.accessToken || !config.email) {
|
|
@@ -70,5 +113,6 @@ export {
|
|
|
70
113
|
saveConfig,
|
|
71
114
|
clearConfig,
|
|
72
115
|
isAuthenticated,
|
|
116
|
+
ensureValidSession,
|
|
73
117
|
getCurrentUser
|
|
74
118
|
};
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
clearConfig,
|
|
3
|
+
ensureValidSession,
|
|
3
4
|
getApiUrl,
|
|
4
5
|
getAuthToken,
|
|
5
6
|
getCurrentUser,
|
|
6
7
|
isAuthenticated,
|
|
7
8
|
loadConfig,
|
|
8
9
|
saveConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
10
11
|
import "./chunk-QGM4M3NI.js";
|
|
11
12
|
export {
|
|
12
13
|
clearConfig,
|
|
14
|
+
ensureValidSession,
|
|
13
15
|
getApiUrl,
|
|
14
16
|
getAuthToken,
|
|
15
17
|
getCurrentUser,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
execute
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HGO4UUAC.js";
|
|
4
4
|
import "./chunk-M4LGRTLC.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-5HVYNCLT.js";
|
|
6
6
|
import "./chunk-5IQKC2TD.js";
|
|
7
|
-
import "./chunk-A7QU6JC6.js";
|
|
8
7
|
import "./chunk-SMR7JQK6.js";
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-A7QU6JC6.js";
|
|
9
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
10
10
|
import "./chunk-5EVHUDQX.js";
|
|
11
11
|
import "./chunk-QGM4M3NI.js";
|
|
12
12
|
export {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
listModels,
|
|
4
|
+
resetPreferences,
|
|
5
|
+
setExecutionPreference,
|
|
6
|
+
setPreference,
|
|
7
|
+
showExecutionPreferences,
|
|
8
|
+
showPreferences
|
|
9
|
+
} from "./chunk-XP7PNLXG.js";
|
|
10
|
+
import {
|
|
11
|
+
parallelClean,
|
|
12
|
+
parallelMerge,
|
|
13
|
+
parallelStatus
|
|
14
|
+
} from "./chunk-OI4K3RYO.js";
|
|
2
15
|
import {
|
|
3
16
|
DependencyParser,
|
|
4
17
|
EnvironmentConfigLoader,
|
|
@@ -7,19 +20,19 @@ import {
|
|
|
7
20
|
cloudLogs,
|
|
8
21
|
cloudStatus,
|
|
9
22
|
execute
|
|
10
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-HGO4UUAC.js";
|
|
11
24
|
import {
|
|
12
25
|
list
|
|
13
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-7FJ4ATJE.js";
|
|
14
27
|
import {
|
|
15
28
|
bugReport
|
|
16
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-GLBVZOBA.js";
|
|
17
30
|
import {
|
|
18
31
|
addKey,
|
|
19
32
|
listKeys,
|
|
20
33
|
removeKey,
|
|
21
34
|
setPrimaryKey
|
|
22
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-BBAUT4M5.js";
|
|
23
36
|
import {
|
|
24
37
|
reviewAnalyze,
|
|
25
38
|
reviewExport,
|
|
@@ -33,19 +46,12 @@ import {
|
|
|
33
46
|
reviewUpdate
|
|
34
47
|
} from "./chunk-QSYKKPFF.js";
|
|
35
48
|
import "./chunk-VKM3HAHW.js";
|
|
36
|
-
import {
|
|
37
|
-
listModels,
|
|
38
|
-
resetPreferences,
|
|
39
|
-
setExecutionPreference,
|
|
40
|
-
setPreference,
|
|
41
|
-
showExecutionPreferences,
|
|
42
|
-
showPreferences
|
|
43
|
-
} from "./chunk-F3RLDQTQ.js";
|
|
44
49
|
import {
|
|
45
50
|
login,
|
|
46
51
|
logout,
|
|
47
52
|
status
|
|
48
|
-
} from "./chunk-
|
|
53
|
+
} from "./chunk-2BPIPDFV.js";
|
|
54
|
+
import "./chunk-C5TDNTNC.js";
|
|
49
55
|
import {
|
|
50
56
|
API_URL,
|
|
51
57
|
SUPABASE_ANON_KEY,
|
|
@@ -55,25 +61,20 @@ import {
|
|
|
55
61
|
init,
|
|
56
62
|
isInitialized
|
|
57
63
|
} from "./chunk-P666JE3G.js";
|
|
58
|
-
import {
|
|
59
|
-
parallelClean,
|
|
60
|
-
parallelMerge,
|
|
61
|
-
parallelStatus
|
|
62
|
-
} from "./chunk-TSSFMB6E.js";
|
|
63
64
|
import {
|
|
64
65
|
listLocalAtoms,
|
|
65
66
|
loadAtom,
|
|
66
67
|
plan
|
|
67
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-5HVYNCLT.js";
|
|
68
69
|
import {
|
|
69
70
|
ArchitectAgent
|
|
70
71
|
} from "./chunk-5IQKC2TD.js";
|
|
71
|
-
import "./chunk-A7QU6JC6.js";
|
|
72
72
|
import "./chunk-SMR7JQK6.js";
|
|
73
|
+
import "./chunk-A7QU6JC6.js";
|
|
73
74
|
import {
|
|
74
75
|
getAuthToken,
|
|
75
76
|
loadConfig
|
|
76
|
-
} from "./chunk-
|
|
77
|
+
} from "./chunk-Y7DQ5XTU.js";
|
|
77
78
|
import {
|
|
78
79
|
ArchitectureParser
|
|
79
80
|
} from "./chunk-5EVHUDQX.js";
|
|
@@ -1168,7 +1169,7 @@ ${noNoPatterns ? `- **Forbidden patterns:** ${noNoPatterns}` : "- No forbidden p
|
|
|
1168
1169
|
if (continueChoice) {
|
|
1169
1170
|
const description = await prompt("Describe what you want to build first");
|
|
1170
1171
|
if (description.trim()) {
|
|
1171
|
-
const { plan: plan2 } = await import("./plan-
|
|
1172
|
+
const { plan: plan2 } = await import("./plan-TVTKS655.js");
|
|
1172
1173
|
await plan2(description, {});
|
|
1173
1174
|
}
|
|
1174
1175
|
}
|
|
@@ -1389,20 +1390,20 @@ async function showReviewProgress(cwd) {
|
|
|
1389
1390
|
}
|
|
1390
1391
|
}
|
|
1391
1392
|
async function planTask() {
|
|
1392
|
-
const { plan: plan2 } = await import("./plan-
|
|
1393
|
+
const { plan: plan2 } = await import("./plan-TVTKS655.js");
|
|
1393
1394
|
const description = await prompt("Describe what you want to build");
|
|
1394
1395
|
if (description.trim()) {
|
|
1395
1396
|
await plan2(description, {});
|
|
1396
1397
|
}
|
|
1397
1398
|
}
|
|
1398
1399
|
async function listAtoms() {
|
|
1399
|
-
const { list: list2 } = await import("./list-
|
|
1400
|
+
const { list: list2 } = await import("./list-XZ42CNFC.js");
|
|
1400
1401
|
await list2({});
|
|
1401
1402
|
}
|
|
1402
1403
|
async function executeNext() {
|
|
1403
|
-
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-
|
|
1404
|
+
const { listLocalAtoms: listLocalAtoms2 } = await import("./plan-TVTKS655.js");
|
|
1404
1405
|
const { analyzeProject, getComplexityDescription, getModeDescription } = await import("./orchestration-X6LHSHBJ.js");
|
|
1405
|
-
const { loadExecutionPreferences } = await import("./preferences-
|
|
1406
|
+
const { loadExecutionPreferences } = await import("./preferences-VY6WPI6V.js");
|
|
1406
1407
|
const cwd = process.cwd();
|
|
1407
1408
|
const atoms = await listLocalAtoms2();
|
|
1408
1409
|
const pendingAtoms = atoms.filter((a) => a.status === "READY" || a.status === "IN_PROGRESS");
|
|
@@ -1435,25 +1436,25 @@ async function executeNext() {
|
|
|
1435
1436
|
const atomId = await prompt("Enter atom ID to execute (or press Enter for first pending)");
|
|
1436
1437
|
const targetId = atomId.trim() || pendingAtoms[0]?.id;
|
|
1437
1438
|
if (targetId) {
|
|
1438
|
-
const { execute: execute2 } = await import("./execute-
|
|
1439
|
+
const { execute: execute2 } = await import("./execute-6D6USH33.js");
|
|
1439
1440
|
await execute2(targetId, {});
|
|
1440
1441
|
} else {
|
|
1441
1442
|
console.log(chalk4.yellow("No atom to execute."));
|
|
1442
1443
|
}
|
|
1443
1444
|
}
|
|
1444
1445
|
async function reportBug() {
|
|
1445
|
-
const { bugReport: bugReport2 } = await import("./bug-
|
|
1446
|
+
const { bugReport: bugReport2 } = await import("./bug-IT4C6HIG.js");
|
|
1446
1447
|
const title = await prompt("Bug title");
|
|
1447
1448
|
if (title.trim()) {
|
|
1448
1449
|
await bugReport2(title, {});
|
|
1449
1450
|
}
|
|
1450
1451
|
}
|
|
1451
1452
|
async function viewStatus() {
|
|
1452
|
-
const { status: status2 } = await import("./auth-
|
|
1453
|
+
const { status: status2 } = await import("./auth-R6G5RDJE.js");
|
|
1453
1454
|
await status2();
|
|
1454
1455
|
}
|
|
1455
1456
|
async function settingsMenu() {
|
|
1456
|
-
const { interactiveSettings } = await import("./preferences-
|
|
1457
|
+
const { interactiveSettings } = await import("./preferences-VY6WPI6V.js");
|
|
1457
1458
|
await interactiveSettings();
|
|
1458
1459
|
await showMainMenu();
|
|
1459
1460
|
}
|
|
@@ -1612,7 +1613,7 @@ async function addCredits(options = {}) {
|
|
|
1612
1613
|
spinner.fail("Not logged in. Run: archon login");
|
|
1613
1614
|
return;
|
|
1614
1615
|
}
|
|
1615
|
-
const amountDollars = options.amount ? parseFloat(options.amount) :
|
|
1616
|
+
const amountDollars = options.amount ? parseFloat(options.amount) : 5;
|
|
1616
1617
|
if (isNaN(amountDollars) || amountDollars < 5) {
|
|
1617
1618
|
spinner.fail("Minimum purchase is $5.00");
|
|
1618
1619
|
return;
|
|
@@ -4773,6 +4774,10 @@ program.command("logout").description("Clear stored authentication").action(asyn
|
|
|
4773
4774
|
program.command("status").description("Show current user and project status").action(async () => {
|
|
4774
4775
|
await status();
|
|
4775
4776
|
});
|
|
4777
|
+
program.command("pricing").description("View and switch pricing tiers (Free, BYOK, Credits)").action(async () => {
|
|
4778
|
+
const { showTierSwitchMenu } = await import("./tier-selection-JYMYBIRV.js");
|
|
4779
|
+
await showTierSwitchMenu();
|
|
4780
|
+
});
|
|
4776
4781
|
program.command("init").description("Initialize ArchonDev in current project").option("--analyze", "Run enhanced analysis of codebase").option("--no-git", "Skip git initialization").action(async (options) => {
|
|
4777
4782
|
await init(options);
|
|
4778
4783
|
});
|
|
@@ -4816,7 +4821,7 @@ var creditsCommand = program.command("credits").description("Manage credit balan
|
|
|
4816
4821
|
creditsCommand.command("show").description("Show current credit balance").action(async () => {
|
|
4817
4822
|
await showCredits();
|
|
4818
4823
|
});
|
|
4819
|
-
creditsCommand.command("add").description("Add credits via Stripe checkout").option("-a, --amount <dollars>", "Amount in dollars (min $5)", "
|
|
4824
|
+
creditsCommand.command("add").description("Add credits via Stripe checkout").option("-a, --amount <dollars>", "Amount in dollars (min $5)", "5").action(async (options) => {
|
|
4820
4825
|
await addCredits(options);
|
|
4821
4826
|
});
|
|
4822
4827
|
creditsCommand.command("history").description("Show recent token usage").option("-l, --limit <count>", "Number of records to show", "20").action(async (options) => {
|
|
@@ -3,9 +3,9 @@ import {
|
|
|
3
3
|
listKeys,
|
|
4
4
|
removeKey,
|
|
5
5
|
setPrimaryKey
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BBAUT4M5.js";
|
|
7
7
|
import "./chunk-SMR7JQK6.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
9
9
|
import "./chunk-QGM4M3NI.js";
|
|
10
10
|
export {
|
|
11
11
|
addKey,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
list
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-7FJ4ATJE.js";
|
|
4
|
+
import "./chunk-5HVYNCLT.js";
|
|
5
5
|
import "./chunk-5IQKC2TD.js";
|
|
6
|
-
import "./chunk-A7QU6JC6.js";
|
|
7
6
|
import "./chunk-SMR7JQK6.js";
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-A7QU6JC6.js";
|
|
8
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
9
9
|
import "./chunk-5EVHUDQX.js";
|
|
10
10
|
import "./chunk-QGM4M3NI.js";
|
|
11
11
|
export {
|
|
@@ -3,12 +3,12 @@ import {
|
|
|
3
3
|
parallelExecute,
|
|
4
4
|
parallelMerge,
|
|
5
5
|
parallelStatus
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-OI4K3RYO.js";
|
|
7
|
+
import "./chunk-5HVYNCLT.js";
|
|
8
8
|
import "./chunk-5IQKC2TD.js";
|
|
9
|
-
import "./chunk-A7QU6JC6.js";
|
|
10
9
|
import "./chunk-SMR7JQK6.js";
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-A7QU6JC6.js";
|
|
11
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
12
12
|
import "./chunk-5EVHUDQX.js";
|
|
13
13
|
import "./chunk-QGM4M3NI.js";
|
|
14
14
|
export {
|
|
@@ -2,11 +2,11 @@ import {
|
|
|
2
2
|
listLocalAtoms,
|
|
3
3
|
loadAtom,
|
|
4
4
|
plan
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5HVYNCLT.js";
|
|
6
6
|
import "./chunk-5IQKC2TD.js";
|
|
7
|
-
import "./chunk-A7QU6JC6.js";
|
|
8
7
|
import "./chunk-SMR7JQK6.js";
|
|
9
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-A7QU6JC6.js";
|
|
9
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
10
10
|
import "./chunk-5EVHUDQX.js";
|
|
11
11
|
import "./chunk-QGM4M3NI.js";
|
|
12
12
|
export {
|
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
setPreference,
|
|
8
8
|
showExecutionPreferences,
|
|
9
9
|
showPreferences
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
} from "./chunk-XP7PNLXG.js";
|
|
11
|
+
import "./chunk-2BPIPDFV.js";
|
|
12
|
+
import "./chunk-C5TDNTNC.js";
|
|
12
13
|
import "./chunk-M4LGRTLC.js";
|
|
13
14
|
import "./chunk-SMR7JQK6.js";
|
|
14
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
15
16
|
import "./chunk-QGM4M3NI.js";
|
|
16
17
|
export {
|
|
17
18
|
interactiveSettings,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleTierSetup,
|
|
3
|
+
promptTierSelection,
|
|
4
|
+
showTierSwitchMenu,
|
|
5
|
+
updateUserTier
|
|
6
|
+
} from "./chunk-C5TDNTNC.js";
|
|
7
|
+
import "./chunk-M4LGRTLC.js";
|
|
8
|
+
import "./chunk-Y7DQ5XTU.js";
|
|
9
|
+
import "./chunk-QGM4M3NI.js";
|
|
10
|
+
export {
|
|
11
|
+
handleTierSetup,
|
|
12
|
+
promptTierSelection,
|
|
13
|
+
showTierSwitchMenu,
|
|
14
|
+
updateUserTier
|
|
15
|
+
};
|