@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.
Files changed (36) hide show
  1. package/dist/components/Footer.cjs +0 -31
  2. package/dist/components/Footer.d.ts.map +1 -1
  3. package/dist/components/Footer.js +0 -31
  4. package/dist/components/Footer.test.cjs +0 -44
  5. package/dist/components/Footer.test.js +0 -44
  6. package/dist/components/overlays/InsufficientCreditsOverlay.cjs +4 -19
  7. package/dist/components/overlays/InsufficientCreditsOverlay.d.ts +0 -2
  8. package/dist/components/overlays/InsufficientCreditsOverlay.d.ts.map +1 -1
  9. package/dist/components/overlays/InsufficientCreditsOverlay.js +4 -19
  10. package/dist/components/overlays/LoginOverlay.cjs +61 -25
  11. package/dist/components/overlays/LoginOverlay.d.ts +3 -1
  12. package/dist/components/overlays/LoginOverlay.d.ts.map +1 -1
  13. package/dist/components/overlays/LoginOverlay.js +66 -26
  14. package/dist/components/overlays/LogoutOverlay.cjs +17 -8
  15. package/dist/components/overlays/LogoutOverlay.d.ts +0 -1
  16. package/dist/components/overlays/LogoutOverlay.d.ts.map +1 -1
  17. package/dist/components/overlays/LogoutOverlay.js +31 -10
  18. package/dist/components/overlays/custom-model-wizard/provider-config.cjs +4 -4
  19. package/dist/components/overlays/custom-model-wizard/provider-config.js +4 -4
  20. package/dist/containers/OverlayContainer.cjs +40 -30
  21. package/dist/containers/OverlayContainer.d.ts.map +1 -1
  22. package/dist/containers/OverlayContainer.js +40 -30
  23. package/dist/host/index.cjs +49 -22
  24. package/dist/host/index.d.ts +72 -18
  25. package/dist/host/index.d.ts.map +1 -1
  26. package/dist/host/index.js +42 -18
  27. package/dist/host/index.test.cjs +35 -21
  28. package/dist/host/index.test.js +40 -22
  29. package/dist/index.d.cts +52 -13
  30. package/dist/services/processStream.cjs +2 -2
  31. package/dist/services/processStream.js +2 -2
  32. package/dist/services/processStream.test.cjs +1 -1
  33. package/dist/services/processStream.test.js +1 -1
  34. package/dist/utils/llm-provider-display.cjs +1 -1
  35. package/dist/utils/llm-provider-display.js +1 -1
  36. package/package.json +5 -5
@@ -22,18 +22,21 @@ __export(host_exports, {
22
22
  buildDextoBillingUrl: () => buildDextoBillingUrl,
23
23
  canUseDextoProvider: () => canUseDextoProvider,
24
24
  captureAnalytics: () => captureAnalytics,
25
- currentSignIn: () => currentSignIn,
26
- dextoCreditBalance: () => dextoCreditBalance,
25
+ ensureDextoApiKeyForAuthToken: () => ensureDextoApiKeyForAuthToken,
27
26
  getProviderDisplayName: () => getProviderDisplayName,
28
27
  getProviderInstructions: () => getProviderInstructions,
29
28
  getTuiRuntimeServices: () => getTuiRuntimeServices,
30
29
  isUsingDextoCredits: () => isUsingDextoCredits,
31
30
  isValidApiKeyFormat: () => isValidApiKeyFormat,
31
+ loadAuth: () => loadAuth,
32
32
  openDextoBillingPage: () => openDextoBillingPage,
33
+ performDeviceCodeLogin: () => performDeviceCodeLogin,
34
+ persistDeviceApiKeyLoginResult: () => persistDeviceApiKeyLoginResult,
33
35
  registerGracefulShutdown: () => registerGracefulShutdown,
36
+ removeAuth: () => removeAuth,
37
+ removeDextoApiKeyFromEnv: () => removeDextoApiKeyFromEnv,
34
38
  setTuiRuntimeServices: () => setTuiRuntimeServices,
35
- signIn: () => signIn,
36
- signOut: () => signOut
39
+ storeAuth: () => storeAuth
37
40
  });
38
41
  module.exports = __toCommonJS(host_exports);
39
42
  let runtimeServices = {};
@@ -66,26 +69,47 @@ function isValidApiKeyFormat(apiKey, provider) {
66
69
  function getProviderInstructions(provider) {
67
70
  return runtimeServices.getProviderInstructions?.(provider) ?? null;
68
71
  }
69
- async function currentSignIn() {
70
- if (!runtimeServices.currentSignIn) {
71
- throw missingHostMethod("currentSignIn");
72
+ async function performDeviceCodeLogin(options) {
73
+ if (!runtimeServices.performDeviceCodeLogin) {
74
+ throw missingHostMethod("performDeviceCodeLogin");
72
75
  }
73
- return runtimeServices.currentSignIn();
76
+ return runtimeServices.performDeviceCodeLogin(options);
74
77
  }
75
- async function signIn(options) {
76
- if (!runtimeServices.signIn) {
77
- throw missingHostMethod("signIn");
78
+ async function persistDeviceApiKeyLoginResult(result) {
79
+ if (!runtimeServices.persistDeviceApiKeyLoginResult) {
80
+ throw missingHostMethod("persistDeviceApiKeyLoginResult");
78
81
  }
79
- return runtimeServices.signIn(options);
82
+ return runtimeServices.persistDeviceApiKeyLoginResult(result);
80
83
  }
81
- async function dextoCreditBalance() {
82
- return await runtimeServices.dextoCreditBalance?.() ?? null;
84
+ async function ensureDextoApiKeyForAuthToken(authToken, options) {
85
+ if (!runtimeServices.ensureDextoApiKeyForAuthToken) {
86
+ throw missingHostMethod("ensureDextoApiKeyForAuthToken");
87
+ }
88
+ return runtimeServices.ensureDextoApiKeyForAuthToken(authToken, options);
89
+ }
90
+ async function loadAuth() {
91
+ if (!runtimeServices.loadAuth) {
92
+ throw missingHostMethod("loadAuth");
93
+ }
94
+ return runtimeServices.loadAuth();
95
+ }
96
+ async function storeAuth(config) {
97
+ if (!runtimeServices.storeAuth) {
98
+ throw missingHostMethod("storeAuth");
99
+ }
100
+ await runtimeServices.storeAuth(config);
101
+ }
102
+ async function removeAuth() {
103
+ if (!runtimeServices.removeAuth) {
104
+ throw missingHostMethod("removeAuth");
105
+ }
106
+ await runtimeServices.removeAuth();
83
107
  }
84
- async function signOut() {
85
- if (!runtimeServices.signOut) {
86
- throw missingHostMethod("signOut");
108
+ async function removeDextoApiKeyFromEnv(options) {
109
+ if (!runtimeServices.removeDextoApiKeyFromEnv) {
110
+ throw missingHostMethod("removeDextoApiKeyFromEnv");
87
111
  }
88
- return runtimeServices.signOut();
112
+ return runtimeServices.removeDextoApiKeyFromEnv(options);
89
113
  }
90
114
  async function isUsingDextoCredits() {
91
115
  if (!runtimeServices.isUsingDextoCredits) {
@@ -117,16 +141,19 @@ async function openDextoBillingPage(options) {
117
141
  buildDextoBillingUrl,
118
142
  canUseDextoProvider,
119
143
  captureAnalytics,
120
- currentSignIn,
121
- dextoCreditBalance,
144
+ ensureDextoApiKeyForAuthToken,
122
145
  getProviderDisplayName,
123
146
  getProviderInstructions,
124
147
  getTuiRuntimeServices,
125
148
  isUsingDextoCredits,
126
149
  isValidApiKeyFormat,
150
+ loadAuth,
127
151
  openDextoBillingPage,
152
+ performDeviceCodeLogin,
153
+ persistDeviceApiKeyLoginResult,
128
154
  registerGracefulShutdown,
155
+ removeAuth,
156
+ removeDextoApiKeyFromEnv,
129
157
  setTuiRuntimeServices,
130
- signIn,
131
- signOut
158
+ storeAuth
132
159
  });
@@ -3,11 +3,38 @@ import type { TuiAgentBackend } from '../agent-backend.js';
3
3
  export interface TuiShutdownHandle {
4
4
  stop?: (() => Promise<void>) | undefined;
5
5
  }
6
- export interface TuiSignInOptions {
7
- /** Aborts the sign-in, such as when the person presses Esc. */
8
- signal: AbortSignal;
9
- /** What to show while signing in: the link, or the code to check. */
10
- onNote: (text: string) => void;
6
+ export interface TuiAuthConfig {
7
+ token?: string | undefined;
8
+ refreshToken?: string | undefined;
9
+ userId?: string | undefined;
10
+ email?: string | undefined;
11
+ expiresAt?: number | undefined;
12
+ createdAt: number;
13
+ dextoApiKey?: string | undefined;
14
+ dextoKeyId?: string | undefined;
15
+ dextoApiKeySource?: 'provisioned' | 'user-supplied' | undefined;
16
+ }
17
+ export interface TuiDeviceApiKeyLoginResult {
18
+ dextoApiKey: string;
19
+ dextoKeyId: string;
20
+ dextoKeyDisplay: string;
21
+ }
22
+ export interface TuiDeviceLoginPrompt {
23
+ userCode: string;
24
+ verificationUrl: string;
25
+ verificationUrlComplete: string | null;
26
+ expiresIn: number;
27
+ }
28
+ export type TuiDextoApiKeyProvisionStatusLevel = 'info' | 'success' | 'warning' | 'error';
29
+ export interface TuiDextoApiKeyProvisionStatus {
30
+ level: TuiDextoApiKeyProvisionStatusLevel;
31
+ message: string;
32
+ }
33
+ export interface TuiPersistedLoginResult {
34
+ email?: string | undefined;
35
+ userId?: string | undefined;
36
+ keyId?: string | undefined;
37
+ hasDextoApiKey: boolean;
11
38
  }
12
39
  export interface TuiRuntimeServices {
13
40
  registerGracefulShutdown?: (getAgent: () => TuiShutdownHandle, options: {
@@ -22,14 +49,26 @@ export interface TuiRuntimeServices {
22
49
  content: string;
23
50
  url?: string | undefined;
24
51
  } | null;
25
- /** Who the current profile acts as, in a few words, or null when signed out. */
26
- currentSignIn?: () => Promise<string | null>;
27
- /** Signs the current profile in to Dexto, resolving with what to say once signed in. */
28
- signIn?: (options: TuiSignInOptions) => Promise<string>;
29
- /** Ends the current profile's sign-in, resolving with what to say. */
30
- signOut?: () => Promise<string>;
31
- /** The organization's Dexto credit balance in USD; null when signed out. */
32
- dextoCreditBalance?: () => Promise<number | null>;
52
+ performDeviceCodeLogin?: (options?: {
53
+ signal?: AbortSignal | undefined;
54
+ onPrompt?: ((prompt: TuiDeviceLoginPrompt) => void) | undefined;
55
+ }) => Promise<TuiDeviceApiKeyLoginResult>;
56
+ persistDeviceApiKeyLoginResult?: (result: TuiDeviceApiKeyLoginResult) => Promise<TuiPersistedLoginResult>;
57
+ ensureDextoApiKeyForAuthToken?: (authToken: string, options?: {
58
+ onStatus?: ((status: TuiDextoApiKeyProvisionStatus) => void) | undefined;
59
+ }) => Promise<{
60
+ dextoApiKey: string;
61
+ keyId: string | null;
62
+ } | null>;
63
+ loadAuth?: () => Promise<TuiAuthConfig | null>;
64
+ storeAuth?: (config: TuiAuthConfig) => Promise<void>;
65
+ removeAuth?: () => Promise<void>;
66
+ removeDextoApiKeyFromEnv?: (options?: {
67
+ expectedValue?: string;
68
+ }) => Promise<{
69
+ removed: boolean;
70
+ targetEnvPath: string;
71
+ }>;
33
72
  isUsingDextoCredits?: () => Promise<boolean>;
34
73
  canUseDextoProvider?: () => Promise<boolean>;
35
74
  buildDextoBillingUrl?: (options: {
@@ -53,11 +92,26 @@ export declare function getProviderInstructions(provider: LLMProvider): {
53
92
  content: string;
54
93
  url?: string | undefined;
55
94
  } | null;
56
- export declare function currentSignIn(): Promise<string | null>;
57
- export declare function signIn(options: TuiSignInOptions): Promise<string>;
58
- /** The Dexto credit balance, or null when the host can't say. */
59
- export declare function dextoCreditBalance(): Promise<number | null>;
60
- export declare function signOut(): Promise<string>;
95
+ export declare function performDeviceCodeLogin(options?: {
96
+ signal?: AbortSignal | undefined;
97
+ onPrompt?: ((prompt: TuiDeviceLoginPrompt) => void) | undefined;
98
+ }): Promise<TuiDeviceApiKeyLoginResult>;
99
+ export declare function persistDeviceApiKeyLoginResult(result: TuiDeviceApiKeyLoginResult): Promise<TuiPersistedLoginResult>;
100
+ export declare function ensureDextoApiKeyForAuthToken(authToken: string, options?: {
101
+ onStatus?: ((status: TuiDextoApiKeyProvisionStatus) => void) | undefined;
102
+ }): Promise<{
103
+ dextoApiKey: string;
104
+ keyId: string | null;
105
+ } | null>;
106
+ export declare function loadAuth(): Promise<TuiAuthConfig | null>;
107
+ export declare function storeAuth(config: TuiAuthConfig): Promise<void>;
108
+ export declare function removeAuth(): Promise<void>;
109
+ export declare function removeDextoApiKeyFromEnv(options?: {
110
+ expectedValue?: string;
111
+ }): Promise<{
112
+ removed: boolean;
113
+ targetEnvPath: string;
114
+ }>;
61
115
  export declare function isUsingDextoCredits(): Promise<boolean>;
62
116
  export declare function canUseDextoProvider(): Promise<boolean>;
63
117
  export declare function buildDextoBillingUrl(options: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host/index.ts"],"names":[],"mappings":"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"}
@@ -28,26 +28,47 @@ function isValidApiKeyFormat(apiKey, provider) {
28
28
  function getProviderInstructions(provider) {
29
29
  return runtimeServices.getProviderInstructions?.(provider) ?? null;
30
30
  }
31
- async function currentSignIn() {
32
- if (!runtimeServices.currentSignIn) {
33
- throw missingHostMethod("currentSignIn");
31
+ async function performDeviceCodeLogin(options) {
32
+ if (!runtimeServices.performDeviceCodeLogin) {
33
+ throw missingHostMethod("performDeviceCodeLogin");
34
34
  }
35
- return runtimeServices.currentSignIn();
35
+ return runtimeServices.performDeviceCodeLogin(options);
36
36
  }
37
- async function signIn(options) {
38
- if (!runtimeServices.signIn) {
39
- throw missingHostMethod("signIn");
37
+ async function persistDeviceApiKeyLoginResult(result) {
38
+ if (!runtimeServices.persistDeviceApiKeyLoginResult) {
39
+ throw missingHostMethod("persistDeviceApiKeyLoginResult");
40
40
  }
41
- return runtimeServices.signIn(options);
41
+ return runtimeServices.persistDeviceApiKeyLoginResult(result);
42
42
  }
43
- async function dextoCreditBalance() {
44
- return await runtimeServices.dextoCreditBalance?.() ?? null;
43
+ async function ensureDextoApiKeyForAuthToken(authToken, options) {
44
+ if (!runtimeServices.ensureDextoApiKeyForAuthToken) {
45
+ throw missingHostMethod("ensureDextoApiKeyForAuthToken");
46
+ }
47
+ return runtimeServices.ensureDextoApiKeyForAuthToken(authToken, options);
48
+ }
49
+ async function loadAuth() {
50
+ if (!runtimeServices.loadAuth) {
51
+ throw missingHostMethod("loadAuth");
52
+ }
53
+ return runtimeServices.loadAuth();
54
+ }
55
+ async function storeAuth(config) {
56
+ if (!runtimeServices.storeAuth) {
57
+ throw missingHostMethod("storeAuth");
58
+ }
59
+ await runtimeServices.storeAuth(config);
60
+ }
61
+ async function removeAuth() {
62
+ if (!runtimeServices.removeAuth) {
63
+ throw missingHostMethod("removeAuth");
64
+ }
65
+ await runtimeServices.removeAuth();
45
66
  }
46
- async function signOut() {
47
- if (!runtimeServices.signOut) {
48
- throw missingHostMethod("signOut");
67
+ async function removeDextoApiKeyFromEnv(options) {
68
+ if (!runtimeServices.removeDextoApiKeyFromEnv) {
69
+ throw missingHostMethod("removeDextoApiKeyFromEnv");
49
70
  }
50
- return runtimeServices.signOut();
71
+ return runtimeServices.removeDextoApiKeyFromEnv(options);
51
72
  }
52
73
  async function isUsingDextoCredits() {
53
74
  if (!runtimeServices.isUsingDextoCredits) {
@@ -78,16 +99,19 @@ export {
78
99
  buildDextoBillingUrl,
79
100
  canUseDextoProvider,
80
101
  captureAnalytics,
81
- currentSignIn,
82
- dextoCreditBalance,
102
+ ensureDextoApiKeyForAuthToken,
83
103
  getProviderDisplayName,
84
104
  getProviderInstructions,
85
105
  getTuiRuntimeServices,
86
106
  isUsingDextoCredits,
87
107
  isValidApiKeyFormat,
108
+ loadAuth,
88
109
  openDextoBillingPage,
110
+ performDeviceCodeLogin,
111
+ persistDeviceApiKeyLoginResult,
89
112
  registerGracefulShutdown,
113
+ removeAuth,
114
+ removeDextoApiKeyFromEnv,
90
115
  setTuiRuntimeServices,
91
- signIn,
92
- signOut
116
+ storeAuth
93
117
  };
@@ -1,33 +1,47 @@
1
1
  "use strict";
2
2
  var import_vitest = require("vitest");
3
3
  var import_index = require("./index.js");
4
- (0, import_vitest.describe)("TUI sign-in runtime services", () => {
4
+ (0, import_vitest.describe)("TUI auth runtime services", () => {
5
5
  (0, import_vitest.afterEach)(() => {
6
6
  (0, import_index.setTuiRuntimeServices)({});
7
7
  });
8
- (0, import_vitest.it)("signs in, says who, and signs out through the host", async () => {
9
- const signal = new AbortController().signal;
10
- const onNote = import_vitest.vi.fn();
11
- const hostSignIn = import_vitest.vi.fn().mockResolvedValue("Signed in as ada@example.com in Acme.");
8
+ (0, import_vitest.it)("uses host-provided API-key device login and persistence services", async () => {
9
+ const prompt = import_vitest.vi.fn();
10
+ const perform = import_vitest.vi.fn().mockResolvedValue({
11
+ dextoApiKey: "dxt_full_key",
12
+ dextoKeyDisplay: "dxt_abc...",
13
+ dextoKeyId: "key-id"
14
+ });
15
+ const persist = import_vitest.vi.fn().mockResolvedValue({
16
+ keyId: "key-id",
17
+ hasDextoApiKey: true
18
+ });
12
19
  (0, import_index.setTuiRuntimeServices)({
13
- currentSignIn: async () => "ada@example.com in Acme",
14
- signIn: hostSignIn,
15
- signOut: async () => "Logged out."
20
+ performDeviceCodeLogin: perform,
21
+ persistDeviceApiKeyLoginResult: persist
22
+ });
23
+ const loginResult = await (0, import_index.performDeviceCodeLogin)({
24
+ onPrompt: prompt
25
+ });
26
+ const persisted = await (0, import_index.persistDeviceApiKeyLoginResult)(loginResult);
27
+ (0, import_vitest.expect)(perform).toHaveBeenCalledWith({ onPrompt: prompt });
28
+ (0, import_vitest.expect)(persist).toHaveBeenCalledWith({
29
+ dextoApiKey: "dxt_full_key",
30
+ dextoKeyDisplay: "dxt_abc...",
31
+ dextoKeyId: "key-id"
32
+ });
33
+ (0, import_vitest.expect)(persisted).toEqual({
34
+ keyId: "key-id",
35
+ hasDextoApiKey: true
16
36
  });
17
- (0, import_vitest.expect)(await (0, import_index.currentSignIn)()).toBe("ada@example.com in Acme");
18
- (0, import_vitest.expect)(await (0, import_index.signIn)({ signal, onNote })).toBe("Signed in as ada@example.com in Acme.");
19
- (0, import_vitest.expect)(hostSignIn).toHaveBeenCalledWith({ signal, onNote });
20
- (0, import_vitest.expect)(await (0, import_index.signOut)()).toBe("Logged out.");
21
37
  });
22
- (0, import_vitest.it)("fails fast when the host provides no sign-in", async () => {
23
- await (0, import_vitest.expect)((0, import_index.currentSignIn)()).rejects.toThrow(
24
- "TUI runtime services missing required method: currentSignIn"
25
- );
38
+ (0, import_vitest.it)("fails fast when API-key device login persistence is not provided by the host", async () => {
26
39
  await (0, import_vitest.expect)(
27
- (0, import_index.signIn)({ signal: new AbortController().signal, onNote: () => void 0 })
28
- ).rejects.toThrow("TUI runtime services missing required method: signIn");
29
- await (0, import_vitest.expect)((0, import_index.signOut)()).rejects.toThrow(
30
- "TUI runtime services missing required method: signOut"
31
- );
40
+ (0, import_index.persistDeviceApiKeyLoginResult)({
41
+ dextoApiKey: "dxt_full_key",
42
+ dextoKeyDisplay: "dxt_abc...",
43
+ dextoKeyId: "key-id"
44
+ })
45
+ ).rejects.toThrow("TUI runtime services missing required method");
32
46
  });
33
47
  });
@@ -1,32 +1,50 @@
1
1
  import { afterEach, describe, expect, it, vi } from "vitest";
2
- import { currentSignIn, setTuiRuntimeServices, signIn, signOut } from "./index.js";
3
- describe("TUI sign-in runtime services", () => {
2
+ import {
3
+ performDeviceCodeLogin,
4
+ persistDeviceApiKeyLoginResult,
5
+ setTuiRuntimeServices
6
+ } from "./index.js";
7
+ describe("TUI auth runtime services", () => {
4
8
  afterEach(() => {
5
9
  setTuiRuntimeServices({});
6
10
  });
7
- it("signs in, says who, and signs out through the host", async () => {
8
- const signal = new AbortController().signal;
9
- const onNote = vi.fn();
10
- const hostSignIn = vi.fn().mockResolvedValue("Signed in as ada@example.com in Acme.");
11
+ it("uses host-provided API-key device login and persistence services", async () => {
12
+ const prompt = vi.fn();
13
+ const perform = vi.fn().mockResolvedValue({
14
+ dextoApiKey: "dxt_full_key",
15
+ dextoKeyDisplay: "dxt_abc...",
16
+ dextoKeyId: "key-id"
17
+ });
18
+ const persist = vi.fn().mockResolvedValue({
19
+ keyId: "key-id",
20
+ hasDextoApiKey: true
21
+ });
11
22
  setTuiRuntimeServices({
12
- currentSignIn: async () => "ada@example.com in Acme",
13
- signIn: hostSignIn,
14
- signOut: async () => "Logged out."
23
+ performDeviceCodeLogin: perform,
24
+ persistDeviceApiKeyLoginResult: persist
25
+ });
26
+ const loginResult = await performDeviceCodeLogin({
27
+ onPrompt: prompt
28
+ });
29
+ const persisted = await persistDeviceApiKeyLoginResult(loginResult);
30
+ expect(perform).toHaveBeenCalledWith({ onPrompt: prompt });
31
+ expect(persist).toHaveBeenCalledWith({
32
+ dextoApiKey: "dxt_full_key",
33
+ dextoKeyDisplay: "dxt_abc...",
34
+ dextoKeyId: "key-id"
35
+ });
36
+ expect(persisted).toEqual({
37
+ keyId: "key-id",
38
+ hasDextoApiKey: true
15
39
  });
16
- expect(await currentSignIn()).toBe("ada@example.com in Acme");
17
- expect(await signIn({ signal, onNote })).toBe("Signed in as ada@example.com in Acme.");
18
- expect(hostSignIn).toHaveBeenCalledWith({ signal, onNote });
19
- expect(await signOut()).toBe("Logged out.");
20
40
  });
21
- it("fails fast when the host provides no sign-in", async () => {
22
- await expect(currentSignIn()).rejects.toThrow(
23
- "TUI runtime services missing required method: currentSignIn"
24
- );
41
+ it("fails fast when API-key device login persistence is not provided by the host", async () => {
25
42
  await expect(
26
- signIn({ signal: new AbortController().signal, onNote: () => void 0 })
27
- ).rejects.toThrow("TUI runtime services missing required method: signIn");
28
- await expect(signOut()).rejects.toThrow(
29
- "TUI runtime services missing required method: signOut"
30
- );
43
+ persistDeviceApiKeyLoginResult({
44
+ dextoApiKey: "dxt_full_key",
45
+ dextoKeyDisplay: "dxt_abc...",
46
+ dextoKeyId: "key-id"
47
+ })
48
+ ).rejects.toThrow("TUI runtime services missing required method");
31
49
  });
32
50
  });
package/dist/index.d.cts CHANGED
@@ -362,11 +362,38 @@ declare function startInkCliRefactored(agent: TuiAgentBackend, initialSessionId:
362
362
  interface TuiShutdownHandle {
363
363
  stop?: (() => Promise<void>) | undefined;
364
364
  }
365
- interface TuiSignInOptions {
366
- /** Aborts the sign-in, such as when the person presses Esc. */
367
- signal: AbortSignal;
368
- /** What to show while signing in: the link, or the code to check. */
369
- onNote: (text: string) => void;
365
+ interface TuiAuthConfig {
366
+ token?: string | undefined;
367
+ refreshToken?: string | undefined;
368
+ userId?: string | undefined;
369
+ email?: string | undefined;
370
+ expiresAt?: number | undefined;
371
+ createdAt: number;
372
+ dextoApiKey?: string | undefined;
373
+ dextoKeyId?: string | undefined;
374
+ dextoApiKeySource?: 'provisioned' | 'user-supplied' | undefined;
375
+ }
376
+ interface TuiDeviceApiKeyLoginResult {
377
+ dextoApiKey: string;
378
+ dextoKeyId: string;
379
+ dextoKeyDisplay: string;
380
+ }
381
+ interface TuiDeviceLoginPrompt {
382
+ userCode: string;
383
+ verificationUrl: string;
384
+ verificationUrlComplete: string | null;
385
+ expiresIn: number;
386
+ }
387
+ type TuiDextoApiKeyProvisionStatusLevel = 'info' | 'success' | 'warning' | 'error';
388
+ interface TuiDextoApiKeyProvisionStatus {
389
+ level: TuiDextoApiKeyProvisionStatusLevel;
390
+ message: string;
391
+ }
392
+ interface TuiPersistedLoginResult {
393
+ email?: string | undefined;
394
+ userId?: string | undefined;
395
+ keyId?: string | undefined;
396
+ hasDextoApiKey: boolean;
370
397
  }
371
398
  interface TuiRuntimeServices {
372
399
  registerGracefulShutdown?: (getAgent: () => TuiShutdownHandle, options: {
@@ -381,14 +408,26 @@ interface TuiRuntimeServices {
381
408
  content: string;
382
409
  url?: string | undefined;
383
410
  } | null;
384
- /** Who the current profile acts as, in a few words, or null when signed out. */
385
- currentSignIn?: () => Promise<string | null>;
386
- /** Signs the current profile in to Dexto, resolving with what to say once signed in. */
387
- signIn?: (options: TuiSignInOptions) => Promise<string>;
388
- /** Ends the current profile's sign-in, resolving with what to say. */
389
- signOut?: () => Promise<string>;
390
- /** The organization's Dexto credit balance in USD; null when signed out. */
391
- dextoCreditBalance?: () => Promise<number | null>;
411
+ performDeviceCodeLogin?: (options?: {
412
+ signal?: AbortSignal | undefined;
413
+ onPrompt?: ((prompt: TuiDeviceLoginPrompt) => void) | undefined;
414
+ }) => Promise<TuiDeviceApiKeyLoginResult>;
415
+ persistDeviceApiKeyLoginResult?: (result: TuiDeviceApiKeyLoginResult) => Promise<TuiPersistedLoginResult>;
416
+ ensureDextoApiKeyForAuthToken?: (authToken: string, options?: {
417
+ onStatus?: ((status: TuiDextoApiKeyProvisionStatus) => void) | undefined;
418
+ }) => Promise<{
419
+ dextoApiKey: string;
420
+ keyId: string | null;
421
+ } | null>;
422
+ loadAuth?: () => Promise<TuiAuthConfig | null>;
423
+ storeAuth?: (config: TuiAuthConfig) => Promise<void>;
424
+ removeAuth?: () => Promise<void>;
425
+ removeDextoApiKeyFromEnv?: (options?: {
426
+ expectedValue?: string;
427
+ }) => Promise<{
428
+ removed: boolean;
429
+ targetEnvPath: string;
430
+ }>;
392
431
  isUsingDextoCredits?: () => Promise<boolean>;
393
432
  canUseDextoProvider?: () => Promise<boolean>;
394
433
  buildDextoBillingUrl?: (options: {
@@ -81,9 +81,9 @@ function extractInsufficientCreditsBalance(error) {
81
81
  }
82
82
  function buildInsufficientCreditsContent(balance) {
83
83
  if (balance === null) {
84
- return "Out of Dexto credits.\nUse the billing prompt to top up and retry your request.";
84
+ return "Out of Dexto Nova credits.\nUse the billing prompt to top up and retry your request.";
85
85
  }
86
- return `Out of Dexto credits. Current balance: $${balance.toFixed(2)}.
86
+ return `Out of Dexto Nova credits. Current balance: $${balance.toFixed(2)}.
87
87
  Use the billing prompt to top up and retry your request.`;
88
88
  }
89
89
  function hasMeaningfulTokenUsageForAnalytics(tokenUsage, estimatedCost) {
@@ -48,9 +48,9 @@ function extractInsufficientCreditsBalance(error) {
48
48
  }
49
49
  function buildInsufficientCreditsContent(balance) {
50
50
  if (balance === null) {
51
- return "Out of Dexto credits.\nUse the billing prompt to top up and retry your request.";
51
+ return "Out of Dexto Nova credits.\nUse the billing prompt to top up and retry your request.";
52
52
  }
53
- return `Out of Dexto credits. Current balance: $${balance.toFixed(2)}.
53
+ return `Out of Dexto Nova credits. Current balance: $${balance.toFixed(2)}.
54
54
  Use the billing prompt to top up and retry your request.`;
55
55
  }
56
56
  function hasMeaningfulTokenUsageForAnalytics(tokenUsage, estimatedCost) {
@@ -504,7 +504,7 @@ function createSetters({
504
504
  (0, import_vitest.expect)(ui.insufficientCredits).toEqual({ balanceUsd: 0 });
505
505
  (0, import_vitest.expect)(ui.isProcessing).toBe(false);
506
506
  const latestMessage = getMessages().at(-1);
507
- (0, import_vitest.expect)(latestMessage?.content).toContain("Out of Dexto credits");
507
+ (0, import_vitest.expect)(latestMessage?.content).toContain("Out of Dexto Nova credits");
508
508
  (0, import_vitest.expect)(latestMessage?.content).not.toContain("Error:");
509
509
  });
510
510
  (0, import_vitest.it)("captures analytics cost fields for priced llm responses", async () => {
@@ -503,7 +503,7 @@ describe("processStream (reasoning)", () => {
503
503
  expect(ui.insufficientCredits).toEqual({ balanceUsd: 0 });
504
504
  expect(ui.isProcessing).toBe(false);
505
505
  const latestMessage = getMessages().at(-1);
506
- expect(latestMessage?.content).toContain("Out of Dexto credits");
506
+ expect(latestMessage?.content).toContain("Out of Dexto Nova credits");
507
507
  expect(latestMessage?.content).not.toContain("Error:");
508
508
  });
509
509
  it("captures analytics cost fields for priced llm responses", async () => {
@@ -39,7 +39,7 @@ const LLM_PROVIDER_DISPLAY_NAMES = {
39
39
  bedrock: "Bedrock",
40
40
  local: "Local",
41
41
  ollama: "Ollama",
42
- "dexto-nova": "Dexto"
42
+ "dexto-nova": "Dexto Nova"
43
43
  };
44
44
  function getLLMProviderDisplayName(provider, baseURL) {
45
45
  if (provider === "openai-compatible") {
@@ -16,7 +16,7 @@ const LLM_PROVIDER_DISPLAY_NAMES = {
16
16
  bedrock: "Bedrock",
17
17
  local: "Local",
18
18
  ollama: "Ollama",
19
- "dexto-nova": "Dexto"
19
+ "dexto-nova": "Dexto Nova"
20
20
  };
21
21
  function getLLMProviderDisplayName(provider, baseURL) {
22
22
  if (provider === "openai-compatible") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexto/tui",
3
- "version": "1.15.0-beta.0",
3
+ "version": "1.15.0",
4
4
  "description": "Interactive terminal UI for Dexto CLI",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,10 +28,10 @@
28
28
  "string-width": "^8.1.0",
29
29
  "strip-ansi": "^7.1.2",
30
30
  "wrap-ansi": "^9.0.2",
31
- "@dexto/core": "1.14.4",
32
- "@dexto/llm": "1.14.4",
33
- "@dexto/registry": "1.14.4",
34
- "@dexto/agent-management": "1.15.0-beta.0"
31
+ "@dexto/core": "1.15.0",
32
+ "@dexto/agent-management": "1.15.0",
33
+ "@dexto/registry": "1.15.0",
34
+ "@dexto/llm": "1.15.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/react": "^19.0.0",