archondev 3.0.1 → 3.1.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 +27 -32
- package/dist/auth-ZMBA5HYH.js +13 -0
- package/dist/{bug-TFICZ4OP.js → bug-MOMNYU5J.js} +2 -2
- package/dist/{chunk-43IIEFB2.js → chunk-7ELR6RW6.js} +1 -1
- package/dist/{chunk-IG3H7C7R.js → chunk-ARHCVLQW.js} +4 -4
- package/dist/chunk-AWHINKO2.js +244 -0
- package/dist/{chunk-7RXZTPXY.js → chunk-BSG5XY3C.js} +6 -6
- package/dist/{chunk-AJNKSFHL.js → chunk-CI5E4EX3.js} +80 -5
- package/dist/{chunk-4TZOCXAI.js → chunk-ECEWULAA.js} +1 -1
- package/dist/chunk-EF66S6ZQ.js +1189 -0
- package/dist/chunk-EV5QU5KG.js +18 -0
- package/dist/{chunk-45T2VB5R.js → chunk-IZFUFXDN.js} +98 -237
- package/dist/{chunk-YK5Z6U5A.js → chunk-LE5EJ6I4.js} +23 -20
- package/dist/{chunk-PQS3TQB6.js → chunk-LSLQIPLQ.js} +6 -6
- package/dist/chunk-NQBS7L2F.js +55 -0
- package/dist/chunk-RAM67KA6.js +57 -0
- package/dist/{chunk-Q3GIFHIQ.js → client-PPPOHAVY.js} +4 -3
- package/dist/constants-BES4STNW.js +11 -0
- package/dist/{execute-HWUL2M3B.js → execute-WSCLLLY6.js} +4 -4
- package/dist/geo-IRUGSLZS.js +50 -0
- package/dist/index.js +760 -1239
- package/dist/{interviewer-ZGKR7YQQ.js → interviewer-ZUYQ5ZFJ.js} +2 -2
- package/dist/{keys-3PRAVIRC.js → keys-SQUTA4L2.js} +2 -2
- package/dist/{list-7IBMJCCF.js → list-HZM7DNVS.js} +4 -4
- package/dist/{parallel-4PXJA2QD.js → parallel-MWPBKEEN.js} +5 -6
- package/dist/{plan-HBAUG3KD.js → plan-3Z6M4LE6.js} +3 -3
- package/dist/{preferences-VVFGRNPD.js → preferences-OXVXWARL.js} +2 -2
- package/dist/{ship-KHL6NVC2.js → ship-CTZU6RYR.js} +1 -1
- package/dist/{chunk-ONH6Y3CS.js → tier-selection-5KPN2RF2.js} +7 -28
- package/dist/truth-layer-7N32HKCE.js +19 -0
- package/package.json +2 -2
- package/dist/auth-T4C7OQWO.js +0 -14
- package/dist/chunk-57NSGWWD.js +0 -270
- package/dist/chunk-CFJECC3B.js +0 -495
- package/dist/chunk-GGRW4NTA.js +0 -118
- package/dist/chunk-M4LGRTLC.js +0 -10
- package/dist/client-PHW2C2HB.js +0 -11
- package/dist/constants-XDIWFFPN.js +0 -11
- package/dist/geo-BWH5PUBK.js +0 -20
- package/dist/tier-selection-O5AFLKD6.js +0 -18
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnthropicClient
|
|
3
3
|
} from "./chunk-NIIFUBOE.js";
|
|
4
|
-
import "./chunk-7C6JELBL.js";
|
|
5
4
|
import {
|
|
6
5
|
loadConfig
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-NQBS7L2F.js";
|
|
7
|
+
import "./chunk-7C6JELBL.js";
|
|
8
8
|
import "./chunk-4VNS5WPM.js";
|
|
9
9
|
|
|
10
10
|
// src/agents/interviewer.ts
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
listKeys,
|
|
4
4
|
removeKey,
|
|
5
5
|
setPrimaryKey
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ARHCVLQW.js";
|
|
7
|
+
import "./chunk-NQBS7L2F.js";
|
|
7
8
|
import "./chunk-TFSHS7EN.js";
|
|
8
9
|
import "./chunk-RDG5BUED.js";
|
|
9
|
-
import "./chunk-GGRW4NTA.js";
|
|
10
10
|
import "./chunk-4VNS5WPM.js";
|
|
11
11
|
export {
|
|
12
12
|
addKey,
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
list
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-7ELR6RW6.js";
|
|
4
|
+
import "./chunk-BSG5XY3C.js";
|
|
5
5
|
import "./chunk-I3BBA7MB.js";
|
|
6
|
-
import "./chunk-5EVHUDQX.js";
|
|
7
6
|
import "./chunk-IYZN6FPJ.js";
|
|
8
7
|
import "./chunk-D3TVDCJA.js";
|
|
9
8
|
import "./chunk-NIIFUBOE.js";
|
|
9
|
+
import "./chunk-NQBS7L2F.js";
|
|
10
|
+
import "./chunk-5EVHUDQX.js";
|
|
10
11
|
import "./chunk-7C6JELBL.js";
|
|
11
12
|
import "./chunk-TFSHS7EN.js";
|
|
12
13
|
import "./chunk-RDG5BUED.js";
|
|
13
|
-
import "./chunk-GGRW4NTA.js";
|
|
14
14
|
import "./chunk-4VNS5WPM.js";
|
|
15
15
|
export {
|
|
16
16
|
list
|
|
@@ -6,19 +6,18 @@ import {
|
|
|
6
6
|
parallelRunWaves,
|
|
7
7
|
parallelSchedule,
|
|
8
8
|
parallelStatus
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-IZFUFXDN.js";
|
|
10
|
+
import "./chunk-EV5QU5KG.js";
|
|
11
|
+
import "./chunk-BSG5XY3C.js";
|
|
12
12
|
import "./chunk-I3BBA7MB.js";
|
|
13
|
-
import "./chunk-5EVHUDQX.js";
|
|
14
13
|
import "./chunk-IYZN6FPJ.js";
|
|
15
14
|
import "./chunk-D3TVDCJA.js";
|
|
16
15
|
import "./chunk-NIIFUBOE.js";
|
|
16
|
+
import "./chunk-NQBS7L2F.js";
|
|
17
|
+
import "./chunk-5EVHUDQX.js";
|
|
17
18
|
import "./chunk-7C6JELBL.js";
|
|
18
19
|
import "./chunk-TFSHS7EN.js";
|
|
19
20
|
import "./chunk-RDG5BUED.js";
|
|
20
|
-
import "./chunk-M4LGRTLC.js";
|
|
21
|
-
import "./chunk-GGRW4NTA.js";
|
|
22
21
|
import "./chunk-4VNS5WPM.js";
|
|
23
22
|
export {
|
|
24
23
|
parallelClean,
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
loadAtom,
|
|
4
4
|
parseAtomDescription,
|
|
5
5
|
plan
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-BSG5XY3C.js";
|
|
7
7
|
import "./chunk-I3BBA7MB.js";
|
|
8
|
-
import "./chunk-5EVHUDQX.js";
|
|
9
8
|
import "./chunk-IYZN6FPJ.js";
|
|
10
9
|
import "./chunk-D3TVDCJA.js";
|
|
11
10
|
import "./chunk-NIIFUBOE.js";
|
|
11
|
+
import "./chunk-NQBS7L2F.js";
|
|
12
|
+
import "./chunk-5EVHUDQX.js";
|
|
12
13
|
import "./chunk-7C6JELBL.js";
|
|
13
14
|
import "./chunk-TFSHS7EN.js";
|
|
14
15
|
import "./chunk-RDG5BUED.js";
|
|
15
|
-
import "./chunk-GGRW4NTA.js";
|
|
16
16
|
import "./chunk-4VNS5WPM.js";
|
|
17
17
|
export {
|
|
18
18
|
listLocalAtoms,
|
|
@@ -9,12 +9,12 @@ import {
|
|
|
9
9
|
showExecutionPreferences,
|
|
10
10
|
showPreferences,
|
|
11
11
|
showUsageDetails
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-LSLQIPLQ.js";
|
|
13
13
|
import "./chunk-I3BBA7MB.js";
|
|
14
|
+
import "./chunk-NQBS7L2F.js";
|
|
14
15
|
import "./chunk-7C6JELBL.js";
|
|
15
16
|
import "./chunk-TFSHS7EN.js";
|
|
16
17
|
import "./chunk-RDG5BUED.js";
|
|
17
|
-
import "./chunk-GGRW4NTA.js";
|
|
18
18
|
import "./chunk-4VNS5WPM.js";
|
|
19
19
|
export {
|
|
20
20
|
__preferencesChoiceHelpers,
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ensureValidSession,
|
|
3
|
-
getApiUrl,
|
|
4
2
|
loadConfig,
|
|
5
3
|
saveConfig
|
|
6
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NQBS7L2F.js";
|
|
5
|
+
import "./chunk-4VNS5WPM.js";
|
|
7
6
|
|
|
8
7
|
// src/cli/tier-selection.ts
|
|
9
8
|
import chalk from "chalk";
|
|
@@ -48,11 +47,11 @@ async function runGuidedAIConfig() {
|
|
|
48
47
|
while (keepAdding) {
|
|
49
48
|
const provider = await promptProvider();
|
|
50
49
|
if (!provider) break;
|
|
51
|
-
const { addKey } = await import("./keys-
|
|
50
|
+
const { addKey } = await import("./keys-SQUTA4L2.js");
|
|
52
51
|
await addKey(provider, {});
|
|
53
52
|
keepAdding = await promptYesNo("Add another provider key now?", false);
|
|
54
53
|
}
|
|
55
|
-
const { listKeys } = await import("./keys-
|
|
54
|
+
const { listKeys } = await import("./keys-SQUTA4L2.js");
|
|
56
55
|
console.log();
|
|
57
56
|
await listKeys();
|
|
58
57
|
console.log();
|
|
@@ -104,26 +103,7 @@ async function updateUserTier(tier) {
|
|
|
104
103
|
tier: normalizedTier,
|
|
105
104
|
tierConfirmed: true
|
|
106
105
|
});
|
|
107
|
-
|
|
108
|
-
if (!session?.accessToken) {
|
|
109
|
-
return { success: true };
|
|
110
|
-
}
|
|
111
|
-
try {
|
|
112
|
-
const response = await fetch(`${getApiUrl(session)}/api/preferences`, {
|
|
113
|
-
method: "PATCH",
|
|
114
|
-
headers: {
|
|
115
|
-
Authorization: `Bearer ${session.accessToken}`,
|
|
116
|
-
"Content-Type": "application/json"
|
|
117
|
-
},
|
|
118
|
-
body: JSON.stringify({ tier: normalizedTier })
|
|
119
|
-
});
|
|
120
|
-
if (!response.ok) {
|
|
121
|
-
return { success: true };
|
|
122
|
-
}
|
|
123
|
-
return { success: true };
|
|
124
|
-
} catch {
|
|
125
|
-
return { success: true };
|
|
126
|
-
}
|
|
106
|
+
return { success: true };
|
|
127
107
|
}
|
|
128
108
|
function normalizeTier(tier) {
|
|
129
109
|
if (tier === "BYOK") return "BYOK";
|
|
@@ -215,12 +195,11 @@ function promptYesNo(question, defaultValue) {
|
|
|
215
195
|
});
|
|
216
196
|
});
|
|
217
197
|
}
|
|
218
|
-
|
|
219
198
|
export {
|
|
220
|
-
promptTierSelection,
|
|
221
199
|
handleTierSetup,
|
|
200
|
+
promptTierSelection,
|
|
222
201
|
runGuidedAIConfig,
|
|
223
|
-
showUpgradeMenu,
|
|
224
202
|
showTierSwitchMenu,
|
|
203
|
+
showUpgradeMenu,
|
|
225
204
|
updateUserTier
|
|
226
205
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TRUTH_LAYER_TEMPLATE,
|
|
3
|
+
createTruthLayerCommand,
|
|
4
|
+
truthLayerAudit,
|
|
5
|
+
truthLayerInit
|
|
6
|
+
} from "./chunk-AWHINKO2.js";
|
|
7
|
+
import "./chunk-EF66S6ZQ.js";
|
|
8
|
+
import "./chunk-3ASILTFB.js";
|
|
9
|
+
import "./chunk-D3TVDCJA.js";
|
|
10
|
+
import "./chunk-NIIFUBOE.js";
|
|
11
|
+
import "./chunk-NQBS7L2F.js";
|
|
12
|
+
import "./chunk-7C6JELBL.js";
|
|
13
|
+
import "./chunk-4VNS5WPM.js";
|
|
14
|
+
export {
|
|
15
|
+
TRUTH_LAYER_TEMPLATE,
|
|
16
|
+
createTruthLayerCommand,
|
|
17
|
+
truthLayerAudit,
|
|
18
|
+
truthLayerInit
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "archondev",
|
|
3
|
-
"version": "3.0
|
|
4
|
-
"description": "Local-first AI-
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Local-first development governance for AI-assisted code. Architecture-aware, dependency-tracked, BYOK. Includes the two-audience marketing toolkit: truth layer, agent clarity audit, AI-washing risk register, human memory map.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"archon": "dist/index.js",
|
package/dist/auth-T4C7OQWO.js
DELETED
package/dist/chunk-57NSGWWD.js
DELETED
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SUPABASE_ANON_KEY,
|
|
3
|
-
SUPABASE_URL
|
|
4
|
-
} from "./chunk-M4LGRTLC.js";
|
|
5
|
-
import {
|
|
6
|
-
handleTierSetup,
|
|
7
|
-
promptTierSelection,
|
|
8
|
-
updateUserTier
|
|
9
|
-
} from "./chunk-ONH6Y3CS.js";
|
|
10
|
-
import {
|
|
11
|
-
clearConfig,
|
|
12
|
-
loadConfig,
|
|
13
|
-
saveConfig
|
|
14
|
-
} from "./chunk-GGRW4NTA.js";
|
|
15
|
-
|
|
16
|
-
// src/cli/auth.ts
|
|
17
|
-
import { createClient } from "@supabase/supabase-js";
|
|
18
|
-
import { createServer } from "http";
|
|
19
|
-
import { URL } from "url";
|
|
20
|
-
import readline from "readline";
|
|
21
|
-
import open from "open";
|
|
22
|
-
import chalk from "chalk";
|
|
23
|
-
import ora from "ora";
|
|
24
|
-
var CALLBACK_PORT = 54321;
|
|
25
|
-
var CALLBACK_URL = `http://localhost:${CALLBACK_PORT}/callback`;
|
|
26
|
-
function normalizeTier(tier) {
|
|
27
|
-
if (tier === "BYOK") return "BYOK";
|
|
28
|
-
return "FREE";
|
|
29
|
-
}
|
|
30
|
-
function toIsoFromSupabaseExpiry(expiresAt) {
|
|
31
|
-
if (typeof expiresAt === "number" && Number.isFinite(expiresAt)) {
|
|
32
|
-
const millis = expiresAt > 1e12 ? expiresAt : expiresAt * 1e3;
|
|
33
|
-
return new Date(millis).toISOString();
|
|
34
|
-
}
|
|
35
|
-
return new Date(Date.now() + 36e5).toISOString();
|
|
36
|
-
}
|
|
37
|
-
function getAuthClient() {
|
|
38
|
-
return createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {
|
|
39
|
-
auth: {
|
|
40
|
-
flowType: "pkce"
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
async function login(providerOrOptions = "github") {
|
|
45
|
-
const options = typeof providerOrOptions === "string" ? { provider: providerOrOptions } : providerOrOptions;
|
|
46
|
-
const provider = options.provider || "github";
|
|
47
|
-
const skipTierSelection = options.skipTierSelection || false;
|
|
48
|
-
const spinner = ora("Starting authentication...").start();
|
|
49
|
-
try {
|
|
50
|
-
const supabase = getAuthClient();
|
|
51
|
-
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
52
|
-
provider,
|
|
53
|
-
options: {
|
|
54
|
-
redirectTo: CALLBACK_URL,
|
|
55
|
-
skipBrowserRedirect: true
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
if (error) {
|
|
59
|
-
spinner.fail(chalk.red(`Authentication failed: ${error.message}`));
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (!data.url) {
|
|
63
|
-
spinner.fail(chalk.red("Failed to get authentication URL"));
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const authResult = await startCallbackServer(data.url, spinner);
|
|
67
|
-
if (authResult) {
|
|
68
|
-
const { data: sessionData, error: sessionError } = await supabase.auth.exchangeCodeForSession(
|
|
69
|
-
authResult.code
|
|
70
|
-
);
|
|
71
|
-
if (sessionError) {
|
|
72
|
-
spinner.fail(chalk.red(`Failed to complete authentication: ${sessionError.message}`));
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (sessionData.session) {
|
|
76
|
-
let userTier = "FREE";
|
|
77
|
-
let isFirstTimeUser = true;
|
|
78
|
-
try {
|
|
79
|
-
const { data: profileData, error: profileError } = await supabase.from("user_profiles").select("tier").eq("auth_id", sessionData.user.id).single();
|
|
80
|
-
if (!profileError && profileData) {
|
|
81
|
-
const profile = profileData;
|
|
82
|
-
if (profile?.tier) {
|
|
83
|
-
userTier = normalizeTier(profile.tier);
|
|
84
|
-
isFirstTimeUser = false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
} catch {
|
|
88
|
-
}
|
|
89
|
-
await saveConfig({
|
|
90
|
-
accessToken: sessionData.session.access_token,
|
|
91
|
-
refreshToken: sessionData.session.refresh_token,
|
|
92
|
-
userId: sessionData.user.id,
|
|
93
|
-
email: sessionData.user.email ?? "",
|
|
94
|
-
tier: userTier,
|
|
95
|
-
expiresAt: toIsoFromSupabaseExpiry(sessionData.session.expires_at)
|
|
96
|
-
});
|
|
97
|
-
spinner.succeed(chalk.green(`Logged in as ${sessionData.user.email}`));
|
|
98
|
-
if (isFirstTimeUser && !skipTierSelection) {
|
|
99
|
-
const selection = await promptTierSelection();
|
|
100
|
-
if (selection && !selection.skipped) {
|
|
101
|
-
const updateResult = await updateUserTier(selection.tier);
|
|
102
|
-
if (updateResult.success) {
|
|
103
|
-
userTier = selection.tier;
|
|
104
|
-
console.log(chalk.green(`
|
|
105
|
-
\u2713 Tier set to ${formatTier(userTier)}`));
|
|
106
|
-
await handleTierSetup(selection.tier);
|
|
107
|
-
}
|
|
108
|
-
} else if (selection?.skipped) {
|
|
109
|
-
userTier = "FREE";
|
|
110
|
-
}
|
|
111
|
-
const config = await loadConfig();
|
|
112
|
-
await saveConfig({ ...config, tier: userTier });
|
|
113
|
-
} else if (!skipTierSelection) {
|
|
114
|
-
console.log(chalk.dim(`Tier: ${formatTier(userTier)}`));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
} catch (error) {
|
|
119
|
-
spinner.fail(chalk.red(`Authentication error: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
function startCallbackServer(authUrl, spinner) {
|
|
123
|
-
return new Promise((resolve) => {
|
|
124
|
-
let settled = false;
|
|
125
|
-
const timeout = setTimeout(() => {
|
|
126
|
-
if (settled) return;
|
|
127
|
-
settled = true;
|
|
128
|
-
server.close();
|
|
129
|
-
spinner.fail(chalk.red("Authentication timed out"));
|
|
130
|
-
resolve(null);
|
|
131
|
-
}, 5 * 60 * 1e3);
|
|
132
|
-
const finish = (result) => {
|
|
133
|
-
if (settled) return;
|
|
134
|
-
settled = true;
|
|
135
|
-
clearTimeout(timeout);
|
|
136
|
-
resolve(result);
|
|
137
|
-
};
|
|
138
|
-
const server = createServer((req, res) => {
|
|
139
|
-
const url = new URL(req.url ?? "", `http://localhost:${CALLBACK_PORT}`);
|
|
140
|
-
if (url.pathname === "/callback") {
|
|
141
|
-
const code = url.searchParams.get("code");
|
|
142
|
-
if (code) {
|
|
143
|
-
res.writeHead(200, { "Content-Type": "text/html" });
|
|
144
|
-
res.end(`
|
|
145
|
-
<!DOCTYPE html>
|
|
146
|
-
<html>
|
|
147
|
-
<head><title>ArchonDev - Authentication Successful</title></head>
|
|
148
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
149
|
-
<h1>\u2705 Authentication Successful!</h1>
|
|
150
|
-
<p>You can close this window and return to the terminal.</p>
|
|
151
|
-
</body>
|
|
152
|
-
</html>
|
|
153
|
-
`);
|
|
154
|
-
server.close();
|
|
155
|
-
finish({ code });
|
|
156
|
-
} else {
|
|
157
|
-
const error = url.searchParams.get("error_description") ?? "Authentication failed";
|
|
158
|
-
res.writeHead(400, { "Content-Type": "text/html" });
|
|
159
|
-
res.end(`
|
|
160
|
-
<!DOCTYPE html>
|
|
161
|
-
<html>
|
|
162
|
-
<head><title>ArchonDev - Authentication Failed</title></head>
|
|
163
|
-
<body style="font-family: system-ui; text-align: center; padding: 50px;">
|
|
164
|
-
<h1>\u274C Authentication Failed</h1>
|
|
165
|
-
<p>${error}</p>
|
|
166
|
-
</body>
|
|
167
|
-
</html>
|
|
168
|
-
`);
|
|
169
|
-
server.close();
|
|
170
|
-
finish(null);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
server.listen(CALLBACK_PORT, async () => {
|
|
175
|
-
spinner.stop();
|
|
176
|
-
console.log(chalk.cyan("\nPress ENTER to open browser for authentication..."));
|
|
177
|
-
console.log(chalk.dim(`(or copy this URL: ${authUrl})
|
|
178
|
-
`));
|
|
179
|
-
await waitForEnter();
|
|
180
|
-
spinner.start("Opening browser...");
|
|
181
|
-
try {
|
|
182
|
-
await open(authUrl);
|
|
183
|
-
spinner.text = "Waiting for authentication in browser...";
|
|
184
|
-
} catch {
|
|
185
|
-
spinner.stop();
|
|
186
|
-
console.log(chalk.yellow("\nCould not open browser automatically."));
|
|
187
|
-
console.log(chalk.bold("Please open this URL manually:"));
|
|
188
|
-
console.log(chalk.cyan(authUrl));
|
|
189
|
-
console.log();
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
function waitForEnter() {
|
|
195
|
-
return new Promise((resolve) => {
|
|
196
|
-
setTimeout(() => {
|
|
197
|
-
const rl = readline.createInterface({
|
|
198
|
-
input: process.stdin,
|
|
199
|
-
output: process.stdout
|
|
200
|
-
});
|
|
201
|
-
if (process.stdin.readable) {
|
|
202
|
-
process.stdin.resume();
|
|
203
|
-
}
|
|
204
|
-
rl.question("", () => {
|
|
205
|
-
rl.close();
|
|
206
|
-
resolve();
|
|
207
|
-
});
|
|
208
|
-
}, 100);
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
async function logout() {
|
|
212
|
-
const spinner = ora("Logging out...").start();
|
|
213
|
-
try {
|
|
214
|
-
const config = await loadConfig();
|
|
215
|
-
if (config.accessToken) {
|
|
216
|
-
try {
|
|
217
|
-
const supabase = getAuthClient();
|
|
218
|
-
await supabase.auth.signOut();
|
|
219
|
-
} catch {
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
await clearConfig();
|
|
223
|
-
spinner.succeed(chalk.green("Logged out successfully"));
|
|
224
|
-
} catch (error) {
|
|
225
|
-
spinner.fail(chalk.red(`Logout failed: ${error instanceof Error ? error.message : "Unknown error"}`));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
async function status() {
|
|
229
|
-
const config = await loadConfig();
|
|
230
|
-
if (!config.accessToken) {
|
|
231
|
-
console.log(chalk.green("Local-only mode active"));
|
|
232
|
-
console.log(chalk.dim(`AI mode: ${formatTier(config.tier ?? "FREE")}`));
|
|
233
|
-
console.log(chalk.dim("Platform login is optional and only needed for legacy remote features."));
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
if (config.expiresAt) {
|
|
237
|
-
const expiresAt = new Date(config.expiresAt);
|
|
238
|
-
if (expiresAt < /* @__PURE__ */ new Date()) {
|
|
239
|
-
console.log(chalk.yellow("Session expired"));
|
|
240
|
-
console.log(chalk.dim(`AI mode: ${formatTier(config.tier ?? "FREE")}`));
|
|
241
|
-
console.log(chalk.dim("Re-authenticate only if you need legacy remote features."));
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
console.log(chalk.green("\u2713 Optional remote session available"));
|
|
246
|
-
console.log();
|
|
247
|
-
console.log(` ${chalk.dim("Email:")} ${config.email}`);
|
|
248
|
-
console.log(` ${chalk.dim("AI mode:")} ${formatTier(config.tier ?? "FREE")}`);
|
|
249
|
-
console.log(` ${chalk.dim("User:")} ${config.userId}`);
|
|
250
|
-
if (config.expiresAt) {
|
|
251
|
-
const expiresAt = new Date(config.expiresAt);
|
|
252
|
-
const hoursLeft = Math.round((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60));
|
|
253
|
-
console.log(` ${chalk.dim("Session expires in:")} ${hoursLeft} hours`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
function formatTier(tier) {
|
|
257
|
-
switch (tier) {
|
|
258
|
-
case "BYOK":
|
|
259
|
-
return chalk.blue("BYOK (your provider keys)");
|
|
260
|
-
case "FREE":
|
|
261
|
-
default:
|
|
262
|
-
return chalk.gray("Local governance only");
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export {
|
|
267
|
-
login,
|
|
268
|
-
logout,
|
|
269
|
-
status
|
|
270
|
-
};
|