@bodhiapp/bodhi-js 0.0.1

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 (47) hide show
  1. package/README.md +26 -0
  2. package/dist/bodhi-browser-ext/src/types/bodhiext.d.ts +202 -0
  3. package/dist/bodhi-browser-ext/src/types/common.d.ts +36 -0
  4. package/dist/bodhi-browser-ext/src/types/index.d.ts +6 -0
  5. package/dist/bodhi-browser-ext/src/types/protocol.d.ts +223 -0
  6. package/dist/bodhi-js-sdk/core/src/direct-client-base.d.ts +129 -0
  7. package/dist/bodhi-js-sdk/core/src/errors.d.ts +23 -0
  8. package/dist/bodhi-js-sdk/core/src/facade-client-base.d.ts +130 -0
  9. package/dist/bodhi-js-sdk/core/src/index.d.ts +19 -0
  10. package/dist/bodhi-js-sdk/core/src/interface.d.ts +228 -0
  11. package/dist/bodhi-js-sdk/core/src/logger.d.ts +13 -0
  12. package/dist/bodhi-js-sdk/core/src/oauth.d.ts +45 -0
  13. package/dist/bodhi-js-sdk/core/src/onboarding/config.d.ts +10 -0
  14. package/dist/bodhi-js-sdk/core/src/onboarding/index.d.ts +5 -0
  15. package/dist/bodhi-js-sdk/core/src/onboarding/modal.d.ts +80 -0
  16. package/dist/bodhi-js-sdk/core/src/onboarding/protocol-utils.d.ts +33 -0
  17. package/dist/bodhi-js-sdk/core/src/platform.d.ts +11 -0
  18. package/dist/bodhi-js-sdk/core/src/storage.d.ts +81 -0
  19. package/dist/bodhi-js-sdk/core/src/types/api.d.ts +34 -0
  20. package/dist/bodhi-js-sdk/core/src/types/callback.d.ts +23 -0
  21. package/dist/bodhi-js-sdk/core/src/types/client-state.d.ts +191 -0
  22. package/dist/bodhi-js-sdk/core/src/types/config.d.ts +26 -0
  23. package/dist/bodhi-js-sdk/core/src/types/html.d.ts +9 -0
  24. package/dist/bodhi-js-sdk/core/src/types/index.d.ts +15 -0
  25. package/dist/bodhi-js-sdk/core/src/types/platform.d.ts +16 -0
  26. package/dist/bodhi-js-sdk/core/src/types/user-info.d.ts +59 -0
  27. package/dist/bodhi-js-sdk/web/src/constants.d.ts +9 -0
  28. package/dist/bodhi-js-sdk/web/src/direct-client.d.ts +24 -0
  29. package/dist/bodhi-js-sdk/web/src/ext-client.d.ts +151 -0
  30. package/dist/bodhi-js-sdk/web/src/facade-client.d.ts +43 -0
  31. package/dist/bodhi-js-sdk/web/src/index.d.ts +5 -0
  32. package/dist/bodhi-js-sdk/web/src/interface.d.ts +4 -0
  33. package/dist/bodhi-web.cjs.js +749 -0
  34. package/dist/bodhi-web.cjs.js.map +1 -0
  35. package/dist/bodhi-web.esm.d.ts +1 -0
  36. package/dist/bodhi-web.esm.js +749 -0
  37. package/dist/bodhi-web.esm.js.map +1 -0
  38. package/dist/setup-modal/src/types/extension.d.ts +24 -0
  39. package/dist/setup-modal/src/types/index.d.ts +20 -0
  40. package/dist/setup-modal/src/types/lna.d.ts +56 -0
  41. package/dist/setup-modal/src/types/message-types.d.ts +169 -0
  42. package/dist/setup-modal/src/types/platform.d.ts +32 -0
  43. package/dist/setup-modal/src/types/protocol.d.ts +71 -0
  44. package/dist/setup-modal/src/types/server.d.ts +63 -0
  45. package/dist/setup-modal/src/types/state.d.ts +43 -0
  46. package/dist/setup-modal/src/types/type-guards.d.ts +27 -0
  47. package/package.json +54 -0
@@ -0,0 +1,34 @@
1
+ import { ApiResponse, OperationErrorResponse } from '../../../../bodhi-browser-ext/src/types';
2
+ import { OpenAiApiError } from '@bodhiapp/ts-client';
3
+
4
+ /**
5
+ * Public API result type - discriminated union without protocol fields
6
+ *
7
+ * This is the return type for sendApiRequest() and similar methods.
8
+ * Unlike ApiResponseMessage<T> (which includes type and requestId for internal routing),
9
+ * this is the clean public interface without protocol overhead.
10
+ *
11
+ * Usage:
12
+ * if ('error' in result) → { error: OperationErrorResponse } (network/extension error)
13
+ * if ('body' in result) → ApiResponse<T> (HTTP completed - check status for success/error)
14
+ */
15
+ export type ApiResponseResult<T> = ApiResponse<T> | {
16
+ error: OperationErrorResponse;
17
+ };
18
+ /**
19
+ * Type guard for operation error response
20
+ */
21
+ export declare function isApiResultOperationError<T>(result: ApiResponseResult<T>): result is {
22
+ error: OperationErrorResponse;
23
+ };
24
+ /**
25
+ * Type guard for API response (success or HTTP error)
26
+ */
27
+ export declare function isApiResultSuccess<T>(result: ApiResponseResult<T>): result is ApiResponse<T> & {
28
+ body: T;
29
+ status: number;
30
+ };
31
+ export declare function isApiResultError<T>(result: ApiResponseResult<T>): result is ApiResponse<OpenAiApiError> & {
32
+ body: OpenAiApiError;
33
+ status: number;
34
+ };
@@ -0,0 +1,23 @@
1
+ import { ClientState } from './client-state';
2
+ import { AuthState } from './user-info';
3
+
4
+ /**
5
+ * Discriminated union for state changes.
6
+ * Allows single callback to handle both client state and auth state changes.
7
+ */
8
+ export type ClientStateChange = {
9
+ type: 'client-state';
10
+ state: ClientState;
11
+ };
12
+ export type AuthStateChange = {
13
+ type: 'auth-state';
14
+ state: AuthState;
15
+ };
16
+ export type StateChange = ClientStateChange | AuthStateChange;
17
+ /**
18
+ * Callback invoked when client state or auth state changes.
19
+ * Defaults to no-op if not provided.
20
+ */
21
+ export type StateChangeCallback = (change: StateChange) => void;
22
+ /** No-op callback for clients created without listener */
23
+ export declare const NOOP_STATE_CALLBACK: StateChangeCallback;
@@ -0,0 +1,191 @@
1
+ import { OperationErrorResponse } from '../../../../bodhi-browser-ext/src/types';
2
+
3
+ /**
4
+ * Serialized direct client state for persistence
5
+ * Stores minimal state needed to restore direct connection
6
+ */
7
+ export type SerializedDirectState = {
8
+ url?: string;
9
+ };
10
+ /**
11
+ * Connection mode - how the client communicates with the local server
12
+ *
13
+ * - 'direct': Direct HTTP fetch to local server (requires LNA permission in web context,
14
+ * but extension already has network access)
15
+ * - 'extension': Communication via extension (chrome.runtime or window.bodhiext)
16
+ */
17
+ export type ConnectionMode = 'direct' | 'extension';
18
+ /**
19
+ * Hardcoded error messages for server states
20
+ */
21
+ export declare const SERVER_ERROR_CODES: {
22
+ readonly NOT_REACHABLE: {
23
+ readonly message: "server is not reachable on given url";
24
+ readonly type: "network_error";
25
+ };
26
+ readonly SERVER_NOT_READY: {
27
+ readonly message: "server is not in ready state, configure to complete setup";
28
+ readonly type: "extension_error";
29
+ };
30
+ };
31
+ export declare const BACKEND_SERVER_NOT_REACHABLE: BackendServerNotReachableState;
32
+ /**
33
+ * Server is ready - no error field
34
+ */
35
+ export interface BackendServerReadyState {
36
+ status: 'ready';
37
+ version: string;
38
+ }
39
+ /**
40
+ * Server is reachable but needs configuration - has error details
41
+ * error code: 'server-not-ready'
42
+ */
43
+ export interface BackendServerNotReadyState {
44
+ status: 'setup' | 'resource-admin' | 'error';
45
+ version: string;
46
+ error: OperationErrorResponse;
47
+ }
48
+ /**
49
+ * Server is not reachable - network/connection failure
50
+ * error code: 'not-reachable'
51
+ */
52
+ export interface BackendServerNotReachableState {
53
+ status: 'not-reachable';
54
+ error: OperationErrorResponse;
55
+ }
56
+ /**
57
+ * Backend server state from /bodhi/v1/info endpoint
58
+ * Discriminated union with definite fields per state
59
+ * Different from setup-modal's ServerState which includes UI states
60
+ */
61
+ export type BackendServerState = BackendServerReadyState | BackendServerNotReadyState | BackendServerNotReachableState;
62
+ /**
63
+ * State indicating extension is ready but server state is pending
64
+ */
65
+ export interface PendingExtensionReadyState {
66
+ status: 'pending-extension-ready';
67
+ }
68
+ export declare const PENDING_EXTENSION_READY: PendingExtensionReadyState;
69
+ /**
70
+ * State indicating direct connection not yet established
71
+ */
72
+ export interface BackendServerNotConnectedState {
73
+ status: 'not-connected';
74
+ }
75
+ export declare const BACKEND_SERVER_NOT_CONNECTED: BackendServerNotConnectedState;
76
+ /**
77
+ * Raw response from /bodhi/v1/info endpoint
78
+ */
79
+ export interface ServerInfoResponse {
80
+ status: 'setup' | 'ready' | 'resource-admin' | 'error';
81
+ version?: string;
82
+ error?: OperationErrorResponse;
83
+ }
84
+ export declare function isServerReady(state: BackendServerState): state is BackendServerReadyState;
85
+ export declare function backendServerNotReady(status: 'setup' | 'resource-admin' | 'error', version?: string, error?: OperationErrorResponse): BackendServerNotReadyState;
86
+ /**
87
+ * ClientState - Unified state for extension or direct connectivity
88
+ * Discriminated union with type field: 'extension' | 'direct'
89
+ */
90
+ export type ClientState = ExtensionState | DirectState;
91
+ /**
92
+ * Serialized client state for localStorage persistence
93
+ * Nested structure storing each client's state separately
94
+ * Server state is transient and not persisted
95
+ */
96
+ export type SerializedExtensionState = Record<string, unknown>;
97
+ export interface SerializedClientState {
98
+ connectionMode: ConnectionMode | null;
99
+ direct: SerializedDirectState;
100
+ extension: SerializedExtensionState;
101
+ }
102
+ /**
103
+ * Parameters for client initialization
104
+ * Unified interface with priority handling:
105
+ * - Explicit params (serverUrl, timeoutMs) take priority over savedState
106
+ * - selectedConnection: true → initialize client (get handle/set url), server stays 'not-initialized'
107
+ * - testConnection: true → also test backend server connectivity and update server state
108
+ */
109
+ export interface InitParams {
110
+ savedState?: Record<string, unknown>;
111
+ selectedConnection?: boolean;
112
+ testConnection?: boolean;
113
+ serverUrl?: string;
114
+ timeoutMs?: number;
115
+ intervalMs?: number;
116
+ }
117
+ export declare function isExtensionState(state: ClientState): state is ExtensionState;
118
+ export declare function isDirectState(state: ClientState): state is DirectState;
119
+ export interface DirectStateNotInitialized {
120
+ type: 'direct';
121
+ server: BackendServerNotConnectedState;
122
+ }
123
+ export interface DirectStateInitialized {
124
+ type: 'direct';
125
+ url: string;
126
+ server: BackendServerNotConnectedState | BackendServerState;
127
+ }
128
+ export interface DirectStateReady {
129
+ type: 'direct';
130
+ url: string;
131
+ server: BackendServerReadyState;
132
+ }
133
+ export interface DirectStateNotReachable {
134
+ type: 'direct';
135
+ url: string;
136
+ server: BackendServerNotReachableState;
137
+ }
138
+ export interface DirectStateNotReady {
139
+ type: 'direct';
140
+ url: string;
141
+ server: BackendServerNotReadyState;
142
+ }
143
+ export type DirectState = DirectStateNotInitialized | DirectStateInitialized | DirectStateReady | DirectStateNotReachable | DirectStateNotReady;
144
+ export declare function isDirectServerReady(state: DirectState): state is DirectStateReady;
145
+ export declare function isDirectClientReady(state: DirectState): state is DirectStateInitialized | DirectStateReady | DirectStateNotReachable | DirectStateNotReady;
146
+ export declare const DIRECT_STATE_NOT_INITIALIZED: DirectStateNotInitialized;
147
+ export declare function createDirectStateReady(url: string, version?: string): DirectStateReady;
148
+ export declare function createDirectStateNotReachable(url: string): DirectStateNotReachable;
149
+ export declare function createDirectStateNotReady(url: string, server: BackendServerNotReadyState): DirectStateNotReady;
150
+ export declare const EXTENSION_STATE_NOT_INITIALIZED: ExtensionState;
151
+ export declare const EXTENSION_STATE_NOT_FOUND: ExtensionState;
152
+ export interface ExtensionStateNotInitialized {
153
+ type: 'extension';
154
+ extension: 'not-initialized';
155
+ server: PendingExtensionReadyState;
156
+ }
157
+ export interface ExtensionStateNotFound {
158
+ type: 'extension';
159
+ extension: 'not-found';
160
+ server: PendingExtensionReadyState;
161
+ }
162
+ export interface ExtensionStateReady {
163
+ type: 'extension';
164
+ extension: 'ready';
165
+ extensionId: string;
166
+ server: PendingExtensionReadyState | BackendServerState;
167
+ }
168
+ export type ExtensionState = ExtensionStateNotInitialized | ExtensionStateNotFound | ExtensionStateReady;
169
+ export declare function isExtensionServerReady(state: ExtensionState): state is ExtensionStateReady;
170
+ export declare function isExtensionClientReady(state: ExtensionState): state is ExtensionStateReady;
171
+ export declare function createExtensionStateNotInitialized(): ExtensionStateNotInitialized;
172
+ export declare function createExtensionStateNotFound(): ExtensionStateNotFound;
173
+ /**
174
+ * Check if client is ready (has handle/url) - does NOT require server ready
175
+ * Use this for auth checks and reload state checks
176
+ */
177
+ export declare function isClientReady(state: ClientState): boolean;
178
+ /**
179
+ * Get backend server state from client state
180
+ */
181
+ export declare function getBackendServerState(state: ClientState): BackendServerState | PendingExtensionReadyState | BackendServerNotConnectedState;
182
+ /**
183
+ * Safely get extension ID from client state
184
+ * @returns Extension ID if state is ExtensionStateReady, undefined otherwise
185
+ */
186
+ export declare function getExtensionId(state: ClientState): string | undefined;
187
+ /**
188
+ * Safely get server URL from client state
189
+ * @returns Server URL if state is DirectState with URL, undefined otherwise
190
+ */
191
+ export declare function getServerUrl(state: ClientState): string | undefined;
@@ -0,0 +1,26 @@
1
+ import { UserScope } from './user-info';
2
+
3
+ /**
4
+ * Log levels for client logging
5
+ */
6
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
7
+ /**
8
+ * Extension discovery result
9
+ */
10
+ export interface DiscoveryResult {
11
+ success: boolean;
12
+ extensionId?: string;
13
+ error?: string;
14
+ }
15
+ /**
16
+ * Client configuration
17
+ */
18
+ export interface ClientConfig {
19
+ authServerUrl?: string;
20
+ userScope?: UserScope;
21
+ extensionId?: string;
22
+ logLevel?: LogLevel;
23
+ discoveryAttempts?: number;
24
+ discoveryAttemptWaitMs?: number;
25
+ discoveryAttemptTimeout?: number;
26
+ }
@@ -0,0 +1,9 @@
1
+ declare module '*.html' {
2
+ const content: string;
3
+ export default content;
4
+ }
5
+
6
+ declare module '*.html?raw' {
7
+ const content: string;
8
+ export default content;
9
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared types used by both ext2ext and web2ext clients
3
+ */
4
+ export { isApiResultError, isApiResultOperationError, isApiResultSuccess } from './api';
5
+ export type { ApiResponseResult } from './api';
6
+ export { createApiError, createOperationError } from '../errors';
7
+ export { BACKEND_SERVER_NOT_CONNECTED, BACKEND_SERVER_NOT_REACHABLE, backendServerNotReady, createDirectStateNotReachable, createDirectStateNotReady, createDirectStateReady, createExtensionStateNotFound, createExtensionStateNotInitialized, DIRECT_STATE_NOT_INITIALIZED, EXTENSION_STATE_NOT_FOUND, EXTENSION_STATE_NOT_INITIALIZED, getBackendServerState, getExtensionId, getServerUrl, isClientReady, isDirectClientReady, isDirectServerReady, isDirectState, isExtensionClientReady, isExtensionServerReady, isExtensionState, isServerReady, PENDING_EXTENSION_READY, SERVER_ERROR_CODES, } from './client-state';
8
+ export type { BackendServerNotConnectedState, BackendServerNotReachableState, BackendServerNotReadyState, BackendServerReadyState, BackendServerState, ClientState, ConnectionMode, DirectState, DirectStateNotInitialized, DirectStateNotReachable, DirectStateNotReady, DirectStateReady, ExtensionState, ExtensionStateNotFound, ExtensionStateNotInitialized, ExtensionStateReady, InitParams, PendingExtensionReadyState, SerializedClientState, SerializedDirectState, SerializedExtensionState, ServerInfoResponse, } from './client-state';
9
+ export { AUTH_CLIENT_NOT_INITIALIZED as AUTH_EXT_NOT_INITIALIZED, isAuthError, isAuthLoggedIn, isAuthLoggedOut, } from './user-info';
10
+ export type { AuthLoggedIn, AuthLoggedOut, AuthState, Tokens, UserInfo, UserScope, } from './user-info';
11
+ export type { ClientConfig, DiscoveryResult, LogLevel } from './config';
12
+ export type { BrowserInfo, OSInfo } from './platform';
13
+ export { NOOP_STATE_CALLBACK } from './callback';
14
+ export type { AuthStateChange, ClientStateChange, StateChange, StateChangeCallback, } from './callback';
15
+ export { buildError, buildEvent, buildResponse, handleRequest } from '../onboarding/protocol-utils';
@@ -0,0 +1,16 @@
1
+ import { BrowserType, OSType } from '../../../../setup-modal/src/types';
2
+
3
+ /**
4
+ * Browser detection result
5
+ */
6
+ export interface BrowserInfo {
7
+ name: string;
8
+ type: BrowserType;
9
+ }
10
+ /**
11
+ * Operating system detection result
12
+ */
13
+ export interface OSInfo {
14
+ name: string;
15
+ type: OSType;
16
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * User and authentication related types
3
+ */
4
+ /**
5
+ * User scope types for regular and power users
6
+ */
7
+ export type UserScope = 'scope_user_user' | 'scope_user_power_user';
8
+ /**
9
+ * User information from OAuth
10
+ */
11
+ export interface UserInfo {
12
+ sub: string;
13
+ email: string;
14
+ name: string;
15
+ given_name: string;
16
+ family_name: string;
17
+ preferred_username: string;
18
+ }
19
+ /**
20
+ * OAuth tokens
21
+ */
22
+ export interface Tokens {
23
+ accessToken: string;
24
+ refreshToken?: string;
25
+ idToken?: string;
26
+ expiresIn: number;
27
+ }
28
+ /**
29
+ * Authentication state when user is logged in
30
+ */
31
+ export interface AuthLoggedIn {
32
+ isLoggedIn: true;
33
+ userInfo: UserInfo;
34
+ accessToken: string;
35
+ }
36
+ /**
37
+ * Authentication state when user is logged out
38
+ */
39
+ export interface AuthLoggedOut {
40
+ isLoggedIn: false;
41
+ }
42
+ /**
43
+ * Authentication state when there is an error
44
+ */
45
+ export interface AuthError {
46
+ isLoggedIn: false;
47
+ error: {
48
+ message: string;
49
+ code: string;
50
+ };
51
+ }
52
+ export declare const AUTH_CLIENT_NOT_INITIALIZED: AuthError;
53
+ export declare function isAuthError(state: unknown): state is AuthError;
54
+ export declare function isAuthLoggedOut(state: unknown): state is AuthLoggedOut;
55
+ export declare function isAuthLoggedIn(state: unknown): state is AuthLoggedIn;
56
+ /**
57
+ * Authentication state (discriminated union)
58
+ */
59
+ export type AuthState = AuthLoggedIn | AuthLoggedOut | AuthError;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Constants for web2ext communication
3
+ */
4
+ export declare const POLL_INTERVAL = 500;
5
+ export declare const POLL_TIMEOUT = 5000;
6
+ /**
7
+ * LocalStorage keys for OAuth tokens and PKCE flow (namespaced with 'bodhi:web' prefix)
8
+ */
9
+ export declare const STORAGE_KEYS: import('../../core/src/index.ts').StorageKeys;
@@ -0,0 +1,24 @@
1
+ import { DirectClientBase, AuthLoggedIn, AuthLoggedOut, DirectClientBaseConfig, StateChangeCallback } from '../../core/src/index.ts';
2
+
3
+ /**
4
+ * Configuration for DirectWebClient
5
+ */
6
+ export interface DirectWebClientConfig extends DirectClientBaseConfig {
7
+ redirectUri: string;
8
+ }
9
+ /**
10
+ * DirectWebClient - Web mode implementation using browser redirect OAuth
11
+ */
12
+ export declare class DirectWebClient extends DirectClientBase {
13
+ private redirectUri;
14
+ constructor(config: DirectWebClientConfig, onStateChange?: StateChangeCallback);
15
+ login(): Promise<AuthLoggedIn>;
16
+ handleOAuthCallback(code: string, state: string): Promise<AuthLoggedIn>;
17
+ logout(): Promise<AuthLoggedOut>;
18
+ protected requestResourceAccess(): Promise<string>;
19
+ protected exchangeCodeForTokens(code: string): Promise<void>;
20
+ protected _storageGet(key: string): Promise<string | null>;
21
+ protected _storageSet(items: Record<string, string | number>): Promise<void>;
22
+ protected _storageRemove(keys: string[]): Promise<void>;
23
+ protected _getRedirectUri(): string;
24
+ }
@@ -0,0 +1,151 @@
1
+ import { ApiResponseResult, AuthLoggedIn, AuthLoggedOut, AuthState, BackendServerState, ClientState, ExtensionState, IExtensionClient, InitParams, StateChangeCallback } from '../../core/src/index.ts';
2
+ import { CreateChatCompletionStreamResponse } from '@bodhiapp/ts-client';
3
+ import { WebClientConfig } from './facade-client';
4
+
5
+ export type SerializedWebExtensionState = {
6
+ extensionId?: string;
7
+ };
8
+ /**
9
+ * WindowBodhiextClient - web mode extension client using window.bodhiext
10
+ *
11
+ * Communicates with bodhi-browser-ext via window.bodhiext API
12
+ *
13
+ * Implements IExtensionClient interface with state callback for state changes
14
+ * Additionally provides handleOAuthCallback for web-specific OAuth flow
15
+ *
16
+ */
17
+ export declare class WindowBodhiextClient implements IExtensionClient {
18
+ private state;
19
+ private logger;
20
+ private bodhiext;
21
+ private authClientId;
22
+ private config;
23
+ private authEndpoints;
24
+ private onStateChange;
25
+ private refreshPromise;
26
+ constructor(authClientId: string, config: WebClientConfig, onStateChange?: StateChangeCallback);
27
+ /**
28
+ * Set client state and notify callback
29
+ */
30
+ private setState;
31
+ /**
32
+ * Set auth state and notify callback
33
+ */
34
+ private setAuthState;
35
+ /**
36
+ * Set or update the state change callback
37
+ */
38
+ setStateCallback(callback: StateChangeCallback): void;
39
+ /**
40
+ * Ensure bodhiext is available, attempting to acquire it if not already set
41
+ * @throws Error if client not initialized
42
+ */
43
+ private ensureBodhiext;
44
+ /**
45
+ * Send extension request via window.bodhiext.sendExtRequest
46
+ */
47
+ sendExtRequest<TParams = void, TRes = unknown>(action: string, params?: TParams): Promise<TRes>;
48
+ /**
49
+ * Send API message via window.bodhiext.sendApiRequest
50
+ * Converts ApiResponse to ApiResponseResult
51
+ */
52
+ sendApiRequest<TReq = void, TRes = unknown>(method: string, endpoint: string, body?: TReq, headers?: Record<string, string>, authenticated?: boolean): Promise<ApiResponseResult<TRes>>;
53
+ /**
54
+ * Get current client state
55
+ */
56
+ getState(): ClientState;
57
+ isClientInitialized(): boolean;
58
+ isServerReady(): boolean;
59
+ /**
60
+ * Initialize extension discovery with optional timeout
61
+ * Returns ExtensionState with extension and server status
62
+ *
63
+ * Note: Web mode uses stateless discovery (always polls for window.bodhiext)
64
+ * No extensionId storage/restoration needed - window.bodhiext handle is ephemeral
65
+ */
66
+ init(params?: InitParams): Promise<ExtensionState>;
67
+ /**
68
+ * Request resource access scope from backend
69
+ * Required for authenticated API access
70
+ */
71
+ private requestResourceAccess;
72
+ /**
73
+ * Login via browser redirect OAuth2 + PKCE flow
74
+ * @returns AuthLoggedIn (though in practice, this redirects and never returns)
75
+ */
76
+ login(): Promise<AuthLoggedIn>;
77
+ /**
78
+ * Handle OAuth callback with authorization code
79
+ * Should be called from callback page with extracted URL params
80
+ * @returns AuthLoggedIn with login state and user info
81
+ */
82
+ handleOAuthCallback(code: string, state: string): Promise<AuthLoggedIn>;
83
+ /**
84
+ * Exchange authorization code for tokens
85
+ */
86
+ private exchangeCodeForTokens;
87
+ /**
88
+ * Logout user and revoke tokens
89
+ * @returns AuthLoggedOut with logged out state
90
+ */
91
+ logout(): Promise<AuthLoggedOut>;
92
+ /**
93
+ * Get current authentication state
94
+ */
95
+ getAuthState(): Promise<AuthState>;
96
+ /**
97
+ * Get current access token
98
+ * Returns null if not logged in or token expired
99
+ */
100
+ protected _getAccessTokenRaw(): Promise<string | null>;
101
+ /**
102
+ * Try to refresh access token using refresh token
103
+ * Race condition prevention: Returns existing promise if refresh already in progress
104
+ */
105
+ private _tryRefreshToken;
106
+ /**
107
+ * Perform the actual token refresh
108
+ */
109
+ private _doRefreshToken;
110
+ /**
111
+ * Store refreshed tokens
112
+ */
113
+ private _storeRefreshedTokens;
114
+ /**
115
+ * Ping API
116
+ */
117
+ pingApi(): Promise<ApiResponseResult<{
118
+ message: string;
119
+ }>>;
120
+ /**
121
+ * Fetch models
122
+ */
123
+ fetchModels(): Promise<ApiResponseResult<{
124
+ data: Array<{
125
+ id: string;
126
+ object: string;
127
+ }>;
128
+ }>>;
129
+ /**
130
+ * Get backend server state
131
+ * Calls /bodhi/v1/info and returns structured server state
132
+ */
133
+ getServerState(): Promise<BackendServerState>;
134
+ /**
135
+ * Generic streaming via window.bodhiext.sendStreamRequest
136
+ * Wraps ReadableStream as AsyncGenerator
137
+ */
138
+ stream<TReq = unknown, TRes = unknown>(method: string, endpoint: string, body?: TReq, headers?: Record<string, string>, authenticated?: boolean): AsyncGenerator<TRes>;
139
+ /**
140
+ * Chat streaming
141
+ */
142
+ streamChat(model: string, prompt: string, authenticated?: boolean): AsyncGenerator<CreateChatCompletionStreamResponse>;
143
+ /**
144
+ * Serialize web extension client state (all transient, nothing to persist)
145
+ */
146
+ serialize(): SerializedWebExtensionState;
147
+ /**
148
+ * Debug dump of WindowBodhiextClient internal state
149
+ */
150
+ debug(): Promise<Record<string, unknown>>;
151
+ }
@@ -0,0 +1,43 @@
1
+ import { BaseFacadeClient, Logger, AuthLoggedIn, IWebUIClient, LogLevel, StateChange, StateChangeCallback, UserScope } from '../../core/src/index.ts';
2
+ import { DirectWebClient } from './direct-client';
3
+ import { WindowBodhiextClient } from './ext-client';
4
+
5
+ /**
6
+ * Configuration for WebClient OAuth
7
+ */
8
+ export interface WebClientConfig {
9
+ authServerUrl: string;
10
+ redirectUri: string;
11
+ userScope: UserScope;
12
+ logLevel: LogLevel;
13
+ initParams?: {
14
+ extension?: {
15
+ timeoutMs?: number;
16
+ intervalMs?: number;
17
+ };
18
+ };
19
+ }
20
+ /**
21
+ * WebUIClient - Public facade for web mode
22
+ *
23
+ * Automatically switches between DirectClient and InternalWebUIClient
24
+ * based on stored user preferences.
25
+ */
26
+ export declare class WebUIClient extends BaseFacadeClient<WebClientConfig, WindowBodhiextClient, DirectWebClient> implements IWebUIClient {
27
+ constructor(authClientId: string, config: {
28
+ redirectUri: string;
29
+ authServerUrl?: string;
30
+ userScope?: UserScope;
31
+ logLevel?: LogLevel;
32
+ initParams?: {
33
+ extension?: {
34
+ timeoutMs?: number;
35
+ intervalMs?: number;
36
+ };
37
+ };
38
+ }, onStateChange?: StateChangeCallback, storagePrefix?: string);
39
+ protected createLogger(config: WebClientConfig): Logger;
40
+ protected createExtClient(config: WebClientConfig, onStateChange: (change: StateChange) => void): WindowBodhiextClient;
41
+ protected createDirectClient(authClientId: string, config: WebClientConfig, onStateChange: (change: StateChange) => void): DirectWebClient;
42
+ handleOAuthCallback(code: string, state: string): Promise<AuthLoggedIn>;
43
+ }
@@ -0,0 +1,5 @@
1
+ import { SerializedWebExtensionState } from './ext-client';
2
+ import { IWebUIClient } from './interface';
3
+
4
+ export { WebUIClient } from './facade-client';
5
+ export type { IWebUIClient, SerializedWebExtensionState };
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Re-export IWebUIClient from core (internal monorepo package)
3
+ */
4
+ export type { IWebUIClient } from '../../core/src/index.ts';