@dexto/tui 1.15.0-beta.0 → 1.15.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/dist/components/Footer.cjs +0 -31
- package/dist/components/Footer.d.ts.map +1 -1
- package/dist/components/Footer.js +0 -31
- package/dist/components/Footer.test.cjs +0 -44
- package/dist/components/Footer.test.js +0 -44
- package/dist/components/overlays/InsufficientCreditsOverlay.cjs +4 -19
- package/dist/components/overlays/InsufficientCreditsOverlay.d.ts +0 -2
- package/dist/components/overlays/InsufficientCreditsOverlay.d.ts.map +1 -1
- package/dist/components/overlays/InsufficientCreditsOverlay.js +4 -19
- package/dist/components/overlays/LoginOverlay.cjs +61 -25
- package/dist/components/overlays/LoginOverlay.d.ts +3 -1
- package/dist/components/overlays/LoginOverlay.d.ts.map +1 -1
- package/dist/components/overlays/LoginOverlay.js +66 -26
- package/dist/components/overlays/LogoutOverlay.cjs +17 -8
- package/dist/components/overlays/LogoutOverlay.d.ts +0 -1
- package/dist/components/overlays/LogoutOverlay.d.ts.map +1 -1
- package/dist/components/overlays/LogoutOverlay.js +31 -10
- package/dist/components/overlays/custom-model-wizard/provider-config.cjs +4 -4
- package/dist/components/overlays/custom-model-wizard/provider-config.js +4 -4
- package/dist/containers/OverlayContainer.cjs +40 -30
- package/dist/containers/OverlayContainer.d.ts.map +1 -1
- package/dist/containers/OverlayContainer.js +40 -30
- package/dist/host/index.cjs +49 -22
- package/dist/host/index.d.ts +72 -18
- package/dist/host/index.d.ts.map +1 -1
- package/dist/host/index.js +42 -18
- package/dist/host/index.test.cjs +35 -21
- package/dist/host/index.test.js +40 -22
- package/dist/index.d.cts +52 -13
- package/dist/services/processStream.cjs +2 -2
- package/dist/services/processStream.js +2 -2
- package/dist/services/processStream.test.cjs +1 -1
- package/dist/services/processStream.test.js +1 -1
- package/dist/utils/llm-provider-display.cjs +1 -1
- package/dist/utils/llm-provider-display.js +1 -1
- package/package.json +5 -5
|
@@ -8,12 +8,17 @@ import {
|
|
|
8
8
|
useState
|
|
9
9
|
} from "react";
|
|
10
10
|
import { Box, Text } from "ink";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
loadAuth,
|
|
13
|
+
performDeviceCodeLogin,
|
|
14
|
+
persistDeviceApiKeyLoginResult
|
|
15
|
+
} from "../../host/index.js";
|
|
12
16
|
const LoginOverlay = forwardRef(function LoginOverlay2({ isVisible, onDone }, ref) {
|
|
13
17
|
const [step, setStep] = useState("checking");
|
|
14
18
|
const [existingUser, setExistingUser] = useState(null);
|
|
15
|
-
const [
|
|
16
|
-
const [
|
|
19
|
+
const [authUrl, setAuthUrl] = useState(null);
|
|
20
|
+
const [devicePrompt, setDevicePrompt] = useState(null);
|
|
21
|
+
const [status, setStatus] = useState("Preparing login...");
|
|
17
22
|
const [error, setError] = useState(null);
|
|
18
23
|
const abortControllerRef = useRef(null);
|
|
19
24
|
const isActiveRef = useRef(false);
|
|
@@ -25,24 +30,47 @@ const LoginOverlay = forwardRef(function LoginOverlay2({ isVisible, onDone }, re
|
|
|
25
30
|
abortControllerRef.current?.abort(new Error("Authentication cancelled"));
|
|
26
31
|
abortControllerRef.current = null;
|
|
27
32
|
}, []);
|
|
33
|
+
const runDeviceLogin = useCallback(
|
|
34
|
+
async (abortController) => {
|
|
35
|
+
setStep("starting");
|
|
36
|
+
safeSetStatus("Starting device code login...");
|
|
37
|
+
setAuthUrl(null);
|
|
38
|
+
setDevicePrompt(null);
|
|
39
|
+
return performDeviceCodeLogin({
|
|
40
|
+
signal: abortController.signal,
|
|
41
|
+
onPrompt: (prompt) => {
|
|
42
|
+
if (!isActiveRef.current || abortController.signal.aborted) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
setDevicePrompt(prompt);
|
|
46
|
+
setAuthUrl(prompt.verificationUrlComplete ?? prompt.verificationUrl);
|
|
47
|
+
setStep("waiting");
|
|
48
|
+
safeSetStatus("Open the URL below and approve login.");
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
[safeSetStatus]
|
|
53
|
+
);
|
|
28
54
|
const startLogin = useCallback(async () => {
|
|
29
55
|
cancelInFlight();
|
|
30
56
|
setError(null);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
safeSetStatus("Signing in...");
|
|
57
|
+
setAuthUrl(null);
|
|
58
|
+
setDevicePrompt(null);
|
|
34
59
|
const abortController = new AbortController();
|
|
35
60
|
abortControllerRef.current = abortController;
|
|
36
61
|
try {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
});
|
|
62
|
+
const result = await runDeviceLogin(abortController);
|
|
63
|
+
if (!result || !isActiveRef.current || abortController.signal.aborted) return;
|
|
64
|
+
setStep("finalizing");
|
|
65
|
+
safeSetStatus("Finalizing login...");
|
|
66
|
+
const persisted = await persistDeviceApiKeyLoginResult(result);
|
|
44
67
|
if (!isActiveRef.current || abortController.signal.aborted) return;
|
|
45
|
-
onDone({
|
|
68
|
+
onDone({
|
|
69
|
+
outcome: "success",
|
|
70
|
+
email: persisted.email,
|
|
71
|
+
keyId: persisted.keyId,
|
|
72
|
+
hasDextoApiKey: persisted.hasDextoApiKey
|
|
73
|
+
});
|
|
46
74
|
} catch (err) {
|
|
47
75
|
if (abortController.signal.aborted) {
|
|
48
76
|
return;
|
|
@@ -50,27 +78,28 @@ const LoginOverlay = forwardRef(function LoginOverlay2({ isVisible, onDone }, re
|
|
|
50
78
|
setStep("error");
|
|
51
79
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
52
80
|
setError(errorMessage);
|
|
53
|
-
safeSetStatus("
|
|
81
|
+
safeSetStatus("Login failed");
|
|
54
82
|
} finally {
|
|
55
83
|
abortControllerRef.current = null;
|
|
56
84
|
}
|
|
57
|
-
}, [cancelInFlight, onDone, safeSetStatus]);
|
|
85
|
+
}, [cancelInFlight, onDone, runDeviceLogin, safeSetStatus]);
|
|
58
86
|
useEffect(() => {
|
|
59
87
|
if (!isVisible) return;
|
|
60
88
|
isActiveRef.current = true;
|
|
61
89
|
setStep("checking");
|
|
62
90
|
setExistingUser(null);
|
|
63
|
-
|
|
64
|
-
|
|
91
|
+
setAuthUrl(null);
|
|
92
|
+
setDevicePrompt(null);
|
|
93
|
+
setStatus("Preparing login...");
|
|
65
94
|
setError(null);
|
|
66
95
|
void (async () => {
|
|
67
96
|
try {
|
|
68
|
-
const
|
|
97
|
+
const auth = await loadAuth();
|
|
69
98
|
if (!isActiveRef.current) return;
|
|
70
|
-
if (
|
|
71
|
-
setExistingUser(
|
|
99
|
+
if (auth) {
|
|
100
|
+
setExistingUser(auth.email || auth.userId || "user");
|
|
72
101
|
setStep("already-authenticated");
|
|
73
|
-
setStatus("You are already
|
|
102
|
+
setStatus("You are already logged in");
|
|
74
103
|
return;
|
|
75
104
|
}
|
|
76
105
|
await startLogin();
|
|
@@ -110,7 +139,7 @@ const LoginOverlay = forwardRef(function LoginOverlay2({ isVisible, onDone }, re
|
|
|
110
139
|
[cancelInFlight, isVisible, onDone, startLogin, step]
|
|
111
140
|
);
|
|
112
141
|
if (!isVisible) return null;
|
|
113
|
-
const hint = step === "already-authenticated" ? "Enter to
|
|
142
|
+
const hint = step === "already-authenticated" ? "Enter to login again \u2022 Esc to close" : step === "error" ? "Enter to retry \u2022 Esc to close" : "Esc to cancel";
|
|
114
143
|
return /* @__PURE__ */ jsxs(
|
|
115
144
|
Box,
|
|
116
145
|
{
|
|
@@ -120,16 +149,27 @@ const LoginOverlay = forwardRef(function LoginOverlay2({ isVisible, onDone }, re
|
|
|
120
149
|
paddingX: 1,
|
|
121
150
|
marginTop: 1,
|
|
122
151
|
children: [
|
|
123
|
-
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "
|
|
152
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Login to Dexto" }) }),
|
|
124
153
|
existingUser && step === "already-authenticated" && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
125
|
-
"
|
|
154
|
+
"\u2705 Already logged in as: ",
|
|
126
155
|
existingUser
|
|
127
156
|
] }) }),
|
|
128
157
|
/* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
129
158
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "Status: " }),
|
|
130
159
|
/* @__PURE__ */ jsx(Text, { children: status })
|
|
131
160
|
] }),
|
|
132
|
-
|
|
161
|
+
devicePrompt && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
162
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "Open this URL on any device:" }),
|
|
163
|
+
/* @__PURE__ */ jsx(Text, { color: "yellowBright", children: devicePrompt.verificationUrlComplete ?? devicePrompt.verificationUrl }),
|
|
164
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
165
|
+
"Code: ",
|
|
166
|
+
devicePrompt.userCode
|
|
167
|
+
] })
|
|
168
|
+
] }),
|
|
169
|
+
authUrl && !devicePrompt && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
170
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", children: "If your browser didn't open, use this URL:" }),
|
|
171
|
+
/* @__PURE__ */ jsx(Text, { color: "yellowBright", children: authUrl })
|
|
172
|
+
] }),
|
|
133
173
|
error && /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ jsxs(Text, { color: "red", children: [
|
|
134
174
|
"Error: ",
|
|
135
175
|
error
|
|
@@ -30,12 +30,20 @@ const LogoutOverlay = (0, import_react.forwardRef)(function LogoutOverlay2({ isV
|
|
|
30
30
|
const [userLabel, setUserLabel] = (0, import_react.useState)(null);
|
|
31
31
|
const [usingDextoCredits, setUsingDextoCredits] = (0, import_react.useState)(false);
|
|
32
32
|
const [error, setError] = (0, import_react.useState)(null);
|
|
33
|
+
const provisionedApiKeyRef = (0, import_react.useRef)(null);
|
|
33
34
|
const performLogout = (0, import_react.useCallback)(async () => {
|
|
34
35
|
setError(null);
|
|
35
36
|
setStep("logging-out");
|
|
36
37
|
try {
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const auth = await (0, import_host.loadAuth)();
|
|
39
|
+
if (auth?.dextoApiKey && auth.dextoApiKeySource === "provisioned") {
|
|
40
|
+
provisionedApiKeyRef.current = auth.dextoApiKey;
|
|
41
|
+
}
|
|
42
|
+
await (0, import_host.removeAuth)();
|
|
43
|
+
if (provisionedApiKeyRef.current) {
|
|
44
|
+
await (0, import_host.removeDextoApiKeyFromEnv)({ expectedValue: provisionedApiKeyRef.current });
|
|
45
|
+
}
|
|
46
|
+
onDone({ outcome: "success", wasUsingDextoCredits: usingDextoCredits });
|
|
39
47
|
} catch (err) {
|
|
40
48
|
setStep("error");
|
|
41
49
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -44,23 +52,24 @@ const LogoutOverlay = (0, import_react.forwardRef)(function LogoutOverlay2({ isV
|
|
|
44
52
|
(0, import_react.useEffect)(() => {
|
|
45
53
|
if (!isVisible) return;
|
|
46
54
|
let cancelled = false;
|
|
55
|
+
provisionedApiKeyRef.current = null;
|
|
47
56
|
setStep("checking");
|
|
48
57
|
setUserLabel(null);
|
|
49
58
|
setUsingDextoCredits(false);
|
|
50
59
|
setError(null);
|
|
51
60
|
void (async () => {
|
|
52
61
|
try {
|
|
53
|
-
const
|
|
62
|
+
const auth = await (0, import_host.loadAuth)();
|
|
54
63
|
if (cancelled) return;
|
|
55
|
-
if (
|
|
64
|
+
if (!auth) {
|
|
56
65
|
setStep("not-authenticated");
|
|
57
66
|
return;
|
|
58
67
|
}
|
|
59
|
-
setUserLabel(
|
|
68
|
+
setUserLabel(auth.email || auth.userId || "user");
|
|
60
69
|
} catch {
|
|
61
70
|
if (!cancelled) {
|
|
62
71
|
setStep("error");
|
|
63
|
-
setError("Failed to
|
|
72
|
+
setError("Failed to load authentication state");
|
|
64
73
|
}
|
|
65
74
|
return;
|
|
66
75
|
}
|
|
@@ -108,12 +117,12 @@ const LogoutOverlay = (0, import_react.forwardRef)(function LogoutOverlay2({ isV
|
|
|
108
117
|
marginTop: 1,
|
|
109
118
|
children: [
|
|
110
119
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { bold: true, color: "cyan", children: "Logout" }) }),
|
|
111
|
-
step === "not-authenticated" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "yellow", children: "Not
|
|
120
|
+
step === "not-authenticated" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "yellow", children: "\u2139\uFE0F Not currently logged in" }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { marginBottom: 1, children: [
|
|
112
121
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: "Account: " }),
|
|
113
122
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: userLabel ?? "..." })
|
|
114
123
|
] }),
|
|
115
124
|
usingDextoCredits && step !== "not-authenticated" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
116
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "yellow", children: "\u26A0\uFE0F You are configured to use Dexto
|
|
125
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "yellow", children: "\u26A0\uFE0F You are configured to use Dexto Nova credits (provider: Dexto Nova)." }),
|
|
117
126
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", dimColor: true, children: "After logout, you will need to run `/login` to authenticate again, or `dexto setup` to configure a different provider." })
|
|
118
127
|
] }),
|
|
119
128
|
step === "logging-out" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { color: "gray", children: "Logging out..." }) }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LogoutOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/LogoutOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"LogoutOverlay.d.ts","sourceRoot":"","sources":["../../../src/components/overlays/LogoutOverlay.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,qCAAqC,CAAC;AAQ/D,MAAM,MAAM,oBAAoB,GAC1B;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,oBAAoB,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,GACxB;IAAE,OAAO,EAAE,QAAQ,CAAA;CAAE,CAAC;AAE5B,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,mBAAmB;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAID,QAAA,MAAM,aAAa,gGAwKjB,CAAC;AAEH,eAAe,aAAa,CAAC"}
|
|
@@ -1,18 +1,38 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
forwardRef,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useImperativeHandle,
|
|
7
|
+
useRef,
|
|
8
|
+
useState
|
|
9
|
+
} from "react";
|
|
3
10
|
import { Box, Text } from "ink";
|
|
4
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
loadAuth,
|
|
13
|
+
removeAuth,
|
|
14
|
+
removeDextoApiKeyFromEnv,
|
|
15
|
+
isUsingDextoCredits
|
|
16
|
+
} from "../../host/index.js";
|
|
5
17
|
const LogoutOverlay = forwardRef(function LogoutOverlay2({ isVisible, onDone }, ref) {
|
|
6
18
|
const [step, setStep] = useState("checking");
|
|
7
19
|
const [userLabel, setUserLabel] = useState(null);
|
|
8
20
|
const [usingDextoCredits, setUsingDextoCredits] = useState(false);
|
|
9
21
|
const [error, setError] = useState(null);
|
|
22
|
+
const provisionedApiKeyRef = useRef(null);
|
|
10
23
|
const performLogout = useCallback(async () => {
|
|
11
24
|
setError(null);
|
|
12
25
|
setStep("logging-out");
|
|
13
26
|
try {
|
|
14
|
-
const
|
|
15
|
-
|
|
27
|
+
const auth = await loadAuth();
|
|
28
|
+
if (auth?.dextoApiKey && auth.dextoApiKeySource === "provisioned") {
|
|
29
|
+
provisionedApiKeyRef.current = auth.dextoApiKey;
|
|
30
|
+
}
|
|
31
|
+
await removeAuth();
|
|
32
|
+
if (provisionedApiKeyRef.current) {
|
|
33
|
+
await removeDextoApiKeyFromEnv({ expectedValue: provisionedApiKeyRef.current });
|
|
34
|
+
}
|
|
35
|
+
onDone({ outcome: "success", wasUsingDextoCredits: usingDextoCredits });
|
|
16
36
|
} catch (err) {
|
|
17
37
|
setStep("error");
|
|
18
38
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -21,23 +41,24 @@ const LogoutOverlay = forwardRef(function LogoutOverlay2({ isVisible, onDone },
|
|
|
21
41
|
useEffect(() => {
|
|
22
42
|
if (!isVisible) return;
|
|
23
43
|
let cancelled = false;
|
|
44
|
+
provisionedApiKeyRef.current = null;
|
|
24
45
|
setStep("checking");
|
|
25
46
|
setUserLabel(null);
|
|
26
47
|
setUsingDextoCredits(false);
|
|
27
48
|
setError(null);
|
|
28
49
|
void (async () => {
|
|
29
50
|
try {
|
|
30
|
-
const
|
|
51
|
+
const auth = await loadAuth();
|
|
31
52
|
if (cancelled) return;
|
|
32
|
-
if (
|
|
53
|
+
if (!auth) {
|
|
33
54
|
setStep("not-authenticated");
|
|
34
55
|
return;
|
|
35
56
|
}
|
|
36
|
-
setUserLabel(
|
|
57
|
+
setUserLabel(auth.email || auth.userId || "user");
|
|
37
58
|
} catch {
|
|
38
59
|
if (!cancelled) {
|
|
39
60
|
setStep("error");
|
|
40
|
-
setError("Failed to
|
|
61
|
+
setError("Failed to load authentication state");
|
|
41
62
|
}
|
|
42
63
|
return;
|
|
43
64
|
}
|
|
@@ -85,12 +106,12 @@ const LogoutOverlay = forwardRef(function LogoutOverlay2({ isVisible, onDone },
|
|
|
85
106
|
marginTop: 1,
|
|
86
107
|
children: [
|
|
87
108
|
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "Logout" }) }),
|
|
88
|
-
step === "not-authenticated" ? /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "Not
|
|
109
|
+
step === "not-authenticated" ? /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u2139\uFE0F Not currently logged in" }) }) : /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
|
|
89
110
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "Account: " }),
|
|
90
111
|
/* @__PURE__ */ jsx(Text, { children: userLabel ?? "..." })
|
|
91
112
|
] }),
|
|
92
113
|
usingDextoCredits && step !== "not-authenticated" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
93
|
-
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u26A0\uFE0F You are configured to use Dexto
|
|
114
|
+
/* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u26A0\uFE0F You are configured to use Dexto Nova credits (provider: Dexto Nova)." }),
|
|
94
115
|
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: "After logout, you will need to run `/login` to authenticate again, or `dexto setup` to configure a different provider." })
|
|
95
116
|
] }),
|
|
96
117
|
step === "logging-out" && /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "gray", children: "Logging out..." }) }),
|
|
@@ -446,7 +446,7 @@ const PROVIDER_CONFIGS = {
|
|
|
446
446
|
}
|
|
447
447
|
},
|
|
448
448
|
"dexto-nova": {
|
|
449
|
-
displayName: "Dexto",
|
|
449
|
+
displayName: "Dexto Nova",
|
|
450
450
|
description: "Access 100+ models with Nova credits",
|
|
451
451
|
steps: [
|
|
452
452
|
{
|
|
@@ -493,14 +493,14 @@ const PROVIDER_CONFIGS = {
|
|
|
493
493
|
}
|
|
494
494
|
}
|
|
495
495
|
if (status === "invalid") {
|
|
496
|
-
return `Model '${modelId}' not found. Dexto uses OpenRouter model IDs - check https://openrouter.ai/models`;
|
|
496
|
+
return `Model '${modelId}' not found. Dexto Nova uses OpenRouter model IDs - check https://openrouter.ai/models`;
|
|
497
497
|
}
|
|
498
498
|
return null;
|
|
499
499
|
}
|
|
500
500
|
},
|
|
501
501
|
setupInfo: {
|
|
502
|
-
title: "Dexto
|
|
503
|
-
description: "Add OpenRouter-format models that use your Dexto credits. Requires
|
|
502
|
+
title: "Dexto Nova Setup",
|
|
503
|
+
description: "Add OpenRouter-format models that use your Dexto Nova credits. Requires login: run `/login` first.",
|
|
504
504
|
docsUrl: "https://openrouter.ai/models"
|
|
505
505
|
}
|
|
506
506
|
}
|
|
@@ -411,7 +411,7 @@ const PROVIDER_CONFIGS = {
|
|
|
411
411
|
}
|
|
412
412
|
},
|
|
413
413
|
"dexto-nova": {
|
|
414
|
-
displayName: "Dexto",
|
|
414
|
+
displayName: "Dexto Nova",
|
|
415
415
|
description: "Access 100+ models with Nova credits",
|
|
416
416
|
steps: [
|
|
417
417
|
{
|
|
@@ -458,14 +458,14 @@ const PROVIDER_CONFIGS = {
|
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
if (status === "invalid") {
|
|
461
|
-
return `Model '${modelId}' not found. Dexto uses OpenRouter model IDs - check https://openrouter.ai/models`;
|
|
461
|
+
return `Model '${modelId}' not found. Dexto Nova uses OpenRouter model IDs - check https://openrouter.ai/models`;
|
|
462
462
|
}
|
|
463
463
|
return null;
|
|
464
464
|
}
|
|
465
465
|
},
|
|
466
466
|
setupInfo: {
|
|
467
|
-
title: "Dexto
|
|
468
|
-
description: "Add OpenRouter-format models that use your Dexto credits. Requires
|
|
467
|
+
title: "Dexto Nova Setup",
|
|
468
|
+
description: "Add OpenRouter-format models that use your Dexto Nova credits. Requires login: run `/login` first.",
|
|
469
469
|
docsUrl: "https://openrouter.ai/models"
|
|
470
470
|
}
|
|
471
471
|
}
|
|
@@ -85,6 +85,7 @@ var import_idGenerator = require("../utils/idGenerator.js");
|
|
|
85
85
|
var import_host = require("../host/index.js");
|
|
86
86
|
var import_FocusOverlayFrame = require("../components/shared/FocusOverlayFrame.js");
|
|
87
87
|
var import_overlayPresentation = require("../utils/overlayPresentation.js");
|
|
88
|
+
var import_dexto_auth_refresh = require("../utils/dexto-auth-refresh.js");
|
|
88
89
|
function isLLMProvider(value) {
|
|
89
90
|
if (typeof value !== "string") return false;
|
|
90
91
|
for (const provider of import_llm.LLM_PROVIDERS) {
|
|
@@ -385,7 +386,7 @@ const OverlayContainer = (0, import_react.forwardRef)(
|
|
|
385
386
|
{
|
|
386
387
|
id: (0, import_idGenerator.generateMessageId)("system"),
|
|
387
388
|
role: "system",
|
|
388
|
-
content: "
|
|
389
|
+
content: "Cannot switch to Dexto Nova model - authentication required. Run /login to authenticate.",
|
|
389
390
|
timestamp: /* @__PURE__ */ new Date()
|
|
390
391
|
}
|
|
391
392
|
]);
|
|
@@ -397,7 +398,7 @@ const OverlayContainer = (0, import_react.forwardRef)(
|
|
|
397
398
|
{
|
|
398
399
|
id: (0, import_idGenerator.generateMessageId)("error"),
|
|
399
400
|
role: "system",
|
|
400
|
-
content: `Failed to
|
|
401
|
+
content: `Failed to verify Dexto Nova auth: ${error instanceof Error ? error.message : String(error)}`,
|
|
401
402
|
timestamp: /* @__PURE__ */ new Date()
|
|
402
403
|
}
|
|
403
404
|
]);
|
|
@@ -660,13 +661,6 @@ const OverlayContainer = (0, import_react.forwardRef)(
|
|
|
660
661
|
insufficientCredits: null
|
|
661
662
|
}));
|
|
662
663
|
}, [setUi]);
|
|
663
|
-
const handleInsufficientCreditsChooseOwnModel = (0, import_react.useCallback)(() => {
|
|
664
|
-
setUi((prev) => ({
|
|
665
|
-
...prev,
|
|
666
|
-
activeOverlay: "model-selector",
|
|
667
|
-
insufficientCredits: null
|
|
668
|
-
}));
|
|
669
|
-
}, [setUi]);
|
|
670
664
|
const handleInsufficientCreditsResolved = (0, import_react.useCallback)(() => {
|
|
671
665
|
setUi((prev) => ({
|
|
672
666
|
...prev,
|
|
@@ -1136,33 +1130,50 @@ ${result.context}`,
|
|
|
1136
1130
|
}, [setUi]);
|
|
1137
1131
|
const handleLoginDone = (0, import_react.useCallback)(
|
|
1138
1132
|
(outcome) => {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1133
|
+
void (async () => {
|
|
1134
|
+
handleClose();
|
|
1135
|
+
if (outcome.outcome === "closed") {
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
if (outcome.outcome === "cancelled") {
|
|
1139
|
+
setMessages((prev) => [
|
|
1140
|
+
...prev,
|
|
1141
|
+
{
|
|
1142
|
+
id: (0, import_idGenerator.generateMessageId)("system"),
|
|
1143
|
+
role: "system",
|
|
1144
|
+
content: "Login cancelled.",
|
|
1145
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1146
|
+
}
|
|
1147
|
+
]);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
let refreshWarning = null;
|
|
1151
|
+
if (outcome.hasDextoApiKey) {
|
|
1152
|
+
try {
|
|
1153
|
+
await (0, import_dexto_auth_refresh.refreshDextoNovaAuthAfterLogin)(agent, session.id || void 0);
|
|
1154
|
+
} catch (error) {
|
|
1155
|
+
refreshWarning = `Logged in, but failed to refresh the active Dexto Nova session: ${error instanceof Error ? error.message : String(error)}`;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
const userLabel = outcome.email ? ` as ${outcome.email}` : "";
|
|
1159
|
+
const keyLine = outcome.hasDextoApiKey ? `\u{1F511} DEXTO_API_KEY ready${outcome.keyId ? ` (Key ID: ${outcome.keyId})` : ""}` : "\u26A0\uFE0F Failed to provision DEXTO_API_KEY (you can still use your own API keys)";
|
|
1160
|
+
const content = [
|
|
1161
|
+
`\u2705 Logged in${userLabel}`,
|
|
1162
|
+
keyLine,
|
|
1163
|
+
...refreshWarning ? [`\u26A0\uFE0F ${refreshWarning}`] : []
|
|
1164
|
+
].join("\n");
|
|
1144
1165
|
setMessages((prev) => [
|
|
1145
1166
|
...prev,
|
|
1146
1167
|
{
|
|
1147
1168
|
id: (0, import_idGenerator.generateMessageId)("system"),
|
|
1148
1169
|
role: "system",
|
|
1149
|
-
content
|
|
1170
|
+
content,
|
|
1150
1171
|
timestamp: /* @__PURE__ */ new Date()
|
|
1151
1172
|
}
|
|
1152
1173
|
]);
|
|
1153
|
-
|
|
1154
|
-
}
|
|
1155
|
-
setMessages((prev) => [
|
|
1156
|
-
...prev,
|
|
1157
|
-
{
|
|
1158
|
-
id: (0, import_idGenerator.generateMessageId)("system"),
|
|
1159
|
-
role: "system",
|
|
1160
|
-
content: outcome.summary,
|
|
1161
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1162
|
-
}
|
|
1163
|
-
]);
|
|
1174
|
+
})();
|
|
1164
1175
|
},
|
|
1165
|
-
[handleClose, setMessages]
|
|
1176
|
+
[agent, handleClose, session.id, setMessages]
|
|
1166
1177
|
);
|
|
1167
1178
|
const handleLogoutDone = (0, import_react.useCallback)(
|
|
1168
1179
|
(outcome) => {
|
|
@@ -1188,7 +1199,7 @@ ${result.context}`,
|
|
|
1188
1199
|
{
|
|
1189
1200
|
id: (0, import_idGenerator.generateMessageId)("system"),
|
|
1190
1201
|
role: "system",
|
|
1191
|
-
content:
|
|
1202
|
+
content: `\u2705 Successfully logged out${warning}`,
|
|
1192
1203
|
timestamp: /* @__PURE__ */ new Date()
|
|
1193
1204
|
}
|
|
1194
1205
|
]);
|
|
@@ -2485,8 +2496,7 @@ Use /${data.name} to run it.`,
|
|
|
2485
2496
|
isVisible: true,
|
|
2486
2497
|
initialBalanceUsd: ui.insufficientCredits.balanceUsd,
|
|
2487
2498
|
onResolved: handleInsufficientCreditsResolved,
|
|
2488
|
-
onClose: handleInsufficientCreditsClose
|
|
2489
|
-
onChooseOwnModel: handleInsufficientCreditsChooseOwnModel
|
|
2499
|
+
onClose: handleInsufficientCreditsClose
|
|
2490
2500
|
}
|
|
2491
2501
|
) }),
|
|
2492
2502
|
ui.activeOverlay === "login" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../src/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAuGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuC3D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../src/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAuGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuC3D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAuC3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,eAAe,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,mDAAmD;IACnD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGA6/F5B,CAAC"}
|
|
@@ -67,6 +67,7 @@ import { generateMessageId } from "../utils/idGenerator.js";
|
|
|
67
67
|
import { canUseDextoProvider, captureAnalytics } from "../host/index.js";
|
|
68
68
|
import { FocusOverlayFrame } from "../components/shared/FocusOverlayFrame.js";
|
|
69
69
|
import { shouldHideCliChrome } from "../utils/overlayPresentation.js";
|
|
70
|
+
import { refreshDextoNovaAuthAfterLogin } from "../utils/dexto-auth-refresh.js";
|
|
70
71
|
function isLLMProvider(value) {
|
|
71
72
|
if (typeof value !== "string") return false;
|
|
72
73
|
for (const provider of LLM_PROVIDERS) {
|
|
@@ -367,7 +368,7 @@ const OverlayContainer = forwardRef(
|
|
|
367
368
|
{
|
|
368
369
|
id: generateMessageId("system"),
|
|
369
370
|
role: "system",
|
|
370
|
-
content: "
|
|
371
|
+
content: "Cannot switch to Dexto Nova model - authentication required. Run /login to authenticate.",
|
|
371
372
|
timestamp: /* @__PURE__ */ new Date()
|
|
372
373
|
}
|
|
373
374
|
]);
|
|
@@ -379,7 +380,7 @@ const OverlayContainer = forwardRef(
|
|
|
379
380
|
{
|
|
380
381
|
id: generateMessageId("error"),
|
|
381
382
|
role: "system",
|
|
382
|
-
content: `Failed to
|
|
383
|
+
content: `Failed to verify Dexto Nova auth: ${error instanceof Error ? error.message : String(error)}`,
|
|
383
384
|
timestamp: /* @__PURE__ */ new Date()
|
|
384
385
|
}
|
|
385
386
|
]);
|
|
@@ -642,13 +643,6 @@ const OverlayContainer = forwardRef(
|
|
|
642
643
|
insufficientCredits: null
|
|
643
644
|
}));
|
|
644
645
|
}, [setUi]);
|
|
645
|
-
const handleInsufficientCreditsChooseOwnModel = useCallback(() => {
|
|
646
|
-
setUi((prev) => ({
|
|
647
|
-
...prev,
|
|
648
|
-
activeOverlay: "model-selector",
|
|
649
|
-
insufficientCredits: null
|
|
650
|
-
}));
|
|
651
|
-
}, [setUi]);
|
|
652
646
|
const handleInsufficientCreditsResolved = useCallback(() => {
|
|
653
647
|
setUi((prev) => ({
|
|
654
648
|
...prev,
|
|
@@ -1118,33 +1112,50 @@ ${result.context}`,
|
|
|
1118
1112
|
}, [setUi]);
|
|
1119
1113
|
const handleLoginDone = useCallback(
|
|
1120
1114
|
(outcome) => {
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1115
|
+
void (async () => {
|
|
1116
|
+
handleClose();
|
|
1117
|
+
if (outcome.outcome === "closed") {
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
if (outcome.outcome === "cancelled") {
|
|
1121
|
+
setMessages((prev) => [
|
|
1122
|
+
...prev,
|
|
1123
|
+
{
|
|
1124
|
+
id: generateMessageId("system"),
|
|
1125
|
+
role: "system",
|
|
1126
|
+
content: "Login cancelled.",
|
|
1127
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1128
|
+
}
|
|
1129
|
+
]);
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
let refreshWarning = null;
|
|
1133
|
+
if (outcome.hasDextoApiKey) {
|
|
1134
|
+
try {
|
|
1135
|
+
await refreshDextoNovaAuthAfterLogin(agent, session.id || void 0);
|
|
1136
|
+
} catch (error) {
|
|
1137
|
+
refreshWarning = `Logged in, but failed to refresh the active Dexto Nova session: ${error instanceof Error ? error.message : String(error)}`;
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
const userLabel = outcome.email ? ` as ${outcome.email}` : "";
|
|
1141
|
+
const keyLine = outcome.hasDextoApiKey ? `\u{1F511} DEXTO_API_KEY ready${outcome.keyId ? ` (Key ID: ${outcome.keyId})` : ""}` : "\u26A0\uFE0F Failed to provision DEXTO_API_KEY (you can still use your own API keys)";
|
|
1142
|
+
const content = [
|
|
1143
|
+
`\u2705 Logged in${userLabel}`,
|
|
1144
|
+
keyLine,
|
|
1145
|
+
...refreshWarning ? [`\u26A0\uFE0F ${refreshWarning}`] : []
|
|
1146
|
+
].join("\n");
|
|
1126
1147
|
setMessages((prev) => [
|
|
1127
1148
|
...prev,
|
|
1128
1149
|
{
|
|
1129
1150
|
id: generateMessageId("system"),
|
|
1130
1151
|
role: "system",
|
|
1131
|
-
content
|
|
1152
|
+
content,
|
|
1132
1153
|
timestamp: /* @__PURE__ */ new Date()
|
|
1133
1154
|
}
|
|
1134
1155
|
]);
|
|
1135
|
-
|
|
1136
|
-
}
|
|
1137
|
-
setMessages((prev) => [
|
|
1138
|
-
...prev,
|
|
1139
|
-
{
|
|
1140
|
-
id: generateMessageId("system"),
|
|
1141
|
-
role: "system",
|
|
1142
|
-
content: outcome.summary,
|
|
1143
|
-
timestamp: /* @__PURE__ */ new Date()
|
|
1144
|
-
}
|
|
1145
|
-
]);
|
|
1156
|
+
})();
|
|
1146
1157
|
},
|
|
1147
|
-
[handleClose, setMessages]
|
|
1158
|
+
[agent, handleClose, session.id, setMessages]
|
|
1148
1159
|
);
|
|
1149
1160
|
const handleLogoutDone = useCallback(
|
|
1150
1161
|
(outcome) => {
|
|
@@ -1170,7 +1181,7 @@ ${result.context}`,
|
|
|
1170
1181
|
{
|
|
1171
1182
|
id: generateMessageId("system"),
|
|
1172
1183
|
role: "system",
|
|
1173
|
-
content:
|
|
1184
|
+
content: `\u2705 Successfully logged out${warning}`,
|
|
1174
1185
|
timestamp: /* @__PURE__ */ new Date()
|
|
1175
1186
|
}
|
|
1176
1187
|
]);
|
|
@@ -2467,8 +2478,7 @@ Use /${data.name} to run it.`,
|
|
|
2467
2478
|
isVisible: true,
|
|
2468
2479
|
initialBalanceUsd: ui.insufficientCredits.balanceUsd,
|
|
2469
2480
|
onResolved: handleInsufficientCreditsResolved,
|
|
2470
|
-
onClose: handleInsufficientCreditsClose
|
|
2471
|
-
onChooseOwnModel: handleInsufficientCreditsChooseOwnModel
|
|
2481
|
+
onClose: handleInsufficientCreditsClose
|
|
2472
2482
|
}
|
|
2473
2483
|
) }),
|
|
2474
2484
|
ui.activeOverlay === "login" && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
|