@molecule/app-react-native 1.0.2 → 1.0.3

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 (3) hide show
  1. package/LICENSE +111 -24
  2. package/README.md +1541 -1360
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -3,15 +3,11 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-09-15T13:40:29.572Z
6
+ Generated: 2026-10-19T22:40:47.803Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-react-native
10
10
 
11
- > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
- > It is written to be read by coding agents as much as by people, and is generated from this
13
- > package's source — edit `src/index.ts` JSDoc, not this file.
14
-
15
11
  React Native framework bindings for molecule.dev.
16
12
 
17
13
  Re-exports every hook and provider from `@molecule/app-react` (they are pure
@@ -19,6 +15,10 @@ React — no DOM dependency) and adds RN-specific hooks: `useAppState`
19
15
  (foreground/background), `useBackHandler` (Android back button),
20
16
  `useKeyboardHeight`, and `useSafeArea`.
21
17
 
18
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
19
+ > It is written to be read by coding agents as much as by people, and is generated from this
20
+ > package's source — edit `src/index.ts` JSDoc, not this file.
21
+
22
22
  ## Quick Start
23
23
 
24
24
  ```tsx
@@ -64,140 +64,17 @@ npm install @molecule/app-react-native @molecule/app-keyboard @molecule/app-life
64
64
 
65
65
  ### Interfaces
66
66
 
67
- #### `AgentIdentity`
68
-
69
- Display identity for the AI coding agent and the host product, used to
70
- interpolate the `{{agentName}}` / `{{productName}}` tokens in shared chat/IDE
71
- copy. A consuming app sets these to its own agent + product brand names; the
72
- shared packages fall back to {@link DEFAULT_AGENT_IDENTITY} when it does not.
73
-
74
- ```typescript
75
- interface AgentIdentity {
76
- /** Display name of the AI coding agent. Defaults to {@link DEFAULT_AGENT_NAME}. */
77
- agentName: string
78
- /** Display name of the host product / IDE. Defaults to {@link DEFAULT_PRODUCT_NAME}. */
79
- productName: string
80
- }
81
- ```
82
-
83
- #### `AuthClient`
84
-
85
- Auth client interface that all auth bond packages must implement.
86
- Provides login/logout/register flows, token management, profile
87
- updates, and auth state subscription.
88
-
89
- ```typescript
90
- interface AuthClient<T = UserProfile> {
91
- /**
92
- * Returns the current authentication state snapshot.
93
- */
94
- getState(): AuthState<T>
95
- /**
96
- * Returns whether the user is currently authenticated.
97
- */
98
- isAuthenticated(): boolean
99
- /**
100
- * Gets the current user.
101
- */
102
- getUser(): T | null
103
- /**
104
- * Updates the cached user object (state + persistent storage) without
105
- * hitting the network. Intended for local refreshes after a per-app
106
- * mutation (e.g., the user just PATCHed their own profile and the
107
- * server returned the canonical row). Does NOT change tokens.
108
- */
109
- setUser(user: T | null): void
110
- /**
111
- * Gets the current access token.
112
- */
113
- getAccessToken(): string | null
114
- /**
115
- * Stores the access token in the configured token storage adapter (in-memory
116
- * by default). Use this to seed the token after an out-of-band exchange (e.g.
117
- * the OAuth code→token redirect) instead of writing to `localStorage` directly,
118
- * which would violate the in-memory-default storage contract and make the bearer
119
- * token JS-readable (XSS-exfiltratable). Pass `null` to clear it.
120
- */
121
- setAccessToken(token: string | null): void
122
- /**
123
- * Gets the refresh token.
124
- */
125
- getRefreshToken(): string | null
126
- /**
127
- * Logs in with credentials.
128
- */
129
- login(credentials: LoginCredentials): Promise<AuthResult<T>>
130
- /**
131
- * Logs out the current user.
132
- */
133
- logout(): Promise<void>
134
- /**
135
- * Registers a new user.
136
- */
137
- register(data: RegisterData): Promise<AuthResult<T>>
138
- /**
139
- * Refreshes the access token.
140
- */
141
- refresh(): Promise<AuthResult<T>>
142
- /**
143
- * Requests a password reset.
144
- */
145
- requestPasswordReset(data: PasswordResetRequest): Promise<void>
146
- /**
147
- * Confirms a password reset.
148
- */
149
- confirmPasswordReset(data: PasswordResetConfirm): Promise<void>
150
- /**
151
- * Updates the current user's profile.
152
- */
153
- updateProfile(data: Partial<T>): Promise<T>
154
- /**
155
- * Changes the current user's password.
156
- */
157
- changePassword(oldPassword: string, newPassword: string): Promise<void>
158
- /**
159
- * Initializes auth state (e.g., from stored tokens).
160
- */
161
- initialize(): Promise<void>
162
- /**
163
- * Subscribes to auth state changes.
164
- */
165
- subscribe(callback: (state: AuthState<T>) => void): () => void
166
- /**
167
- * Subscribes to auth state changes (alias for subscribe).
168
- */
169
- onAuthChange(callback: (state: AuthState<T>) => void): () => void
170
- /**
171
- * Gets the current access token (alias for getAccessToken).
172
- */
173
- getToken?(): string | null
174
- /**
175
- * Adds an auth event listener.
176
- */
177
- addEventListener(listener: AuthEventListener): () => void
178
- /**
179
- * Destroys the auth client.
180
- */
181
- destroy(): void
182
- }
183
- ```
184
-
185
- #### `AuthProviderProps`
186
-
187
- Props for auth provider component.
188
-
189
- ```typescript
190
- interface AuthProviderProps<T = unknown> extends ProviderProps {
191
- client: AuthClient<T>
192
- }
193
- ```
194
-
195
67
  #### `AuthState`
196
68
 
197
69
  Reactive authentication state snapshot (initialized, authenticated, user, loading, and error).
198
70
 
199
71
  ```typescript
200
72
  interface AuthState<T = UserProfile> {
73
+ /**
74
+ * The session's state as one value — render from this instead of combining
75
+ * `initialized`/`authenticated`/`loading`. See {@link AuthStatus}.
76
+ */
77
+ status: AuthStatus
201
78
  /**
202
79
  * Whether auth state has been initialized.
203
80
  */
@@ -221,24 +98,176 @@ interface AuthState<T = UserProfile> {
221
98
  }
222
99
  ```
223
100
 
224
- #### `ChatProviderProps`
225
-
226
- Props for the ChatProvider React component.
227
-
228
- ```typescript
229
- interface ChatProviderProps extends ProviderProps {
230
- provider: ChatProvider
231
- }
232
- ```
233
-
234
- #### `EditorProviderProps`
101
+ #### `AuthClient`
235
102
 
236
- Props for editor provider component.
103
+ Auth client interface that all auth bond packages must implement.
104
+ Provides login/logout/register flows, token management, profile
105
+ updates, and auth state subscription.
237
106
 
238
107
  ```typescript
239
- interface EditorProviderProps extends ProviderProps {
240
- provider: EditorProvider
241
- }
108
+ interface AuthClient<T = UserProfile, TRegister extends Record<string, unknown> = Record<never, never>> {
109
+ /**
110
+ * Returns the current authentication state snapshot.
111
+ *
112
+ * READING the state starts the client's one session restore when nobody has called
113
+ * {@link initialize} yet — lazily and exactly once, sharing the promise an explicit
114
+ * `initialize()` returns. A hook (`useAuth()`), a subscriber, `isAuthenticated()` and
115
+ * `getUser()` are reads too, so a client whose entry file dropped the template's
116
+ * `authClient.initialize()` line still restores instead of reporting `'loading'`
117
+ * forever.
118
+ */
119
+ getState(): AuthState<T>;
120
+ /**
121
+ * Returns whether the user is currently authenticated.
122
+ */
123
+ isAuthenticated(): boolean;
124
+ /**
125
+ * Gets the current user.
126
+ */
127
+ getUser(): T | null;
128
+ /**
129
+ * Updates the cached user object (state + persistent storage) without
130
+ * hitting the network. Intended for local refreshes after a per-app
131
+ * mutation (e.g., the user just PATCHed their own profile and the
132
+ * server returned the canonical row). Does NOT change tokens.
133
+ *
134
+ * This does not sign the client in: `authenticated` and `status` are
135
+ * unchanged, so an anonymous client stays anonymous. Use
136
+ * {@link login} / {@link register} for a credential exchange, or
137
+ * {@link setSession} when the token was issued outside the client.
138
+ */
139
+ setUser(user: T | null): void;
140
+ /**
141
+ * Gets the current access token.
142
+ */
143
+ getAccessToken(): string | null;
144
+ /**
145
+ * Stores the access token in the configured token storage adapter (in a
146
+ * browser, Web Storage; `'memory'` where no browser store exists). Use this
147
+ * to seed the token after an out-of-band exchange (e.g. the OAuth
148
+ * code→token redirect) instead of writing to `localStorage` directly,
149
+ * which would violate the storage contract and make a stored bearer token
150
+ * JS-readable (XSS-exfiltratable). Pass `null` to clear it.
151
+ *
152
+ * This changes token storage only; it does not sign the client in
153
+ * (`authenticated` and `status` are unchanged). Use {@link login} /
154
+ * {@link register} for a credential exchange, or call {@link setSession}
155
+ * with the token and the user to establish an already-issued session.
156
+ */
157
+ setAccessToken(token: string | null): void;
158
+ /**
159
+ * Adopts a session an out-of-band exchange already established: stores the
160
+ * access token (and the refresh token when given), caches the user, and
161
+ * sets the COMPLETE state — `initialized`, `authenticated`, `status:
162
+ * 'authenticated'`, no error — in one update, with one subscriber
163
+ * notification. Every hook reading the shared client sees the user as
164
+ * signed in immediately.
165
+ *
166
+ * This is the way to seed an OAuth/custom sign-in. Calling
167
+ * {@link setAccessToken} and {@link setUser} instead does NOT sign the
168
+ * client in.
169
+ */
170
+ setSession(session: AuthSessionSeed<T>): void;
171
+ /**
172
+ * Gets the refresh token.
173
+ */
174
+ getRefreshToken(): string | null;
175
+ /**
176
+ * Logs in with credentials.
177
+ */
178
+ login(credentials: LoginCredentials): Promise<AuthResult<T>>;
179
+ /**
180
+ * Logs out the current user.
181
+ */
182
+ logout(): Promise<void>;
183
+ /**
184
+ * Registers a new user. Accepts the base fields plus the app's own fields
185
+ * (`TRegister`) at the top level — see {@link RegisterData}.
186
+ */
187
+ register(data: RegisterData<TRegister>): Promise<AuthResult<T>>;
188
+ /**
189
+ * Refreshes the access token.
190
+ */
191
+ refresh(): Promise<AuthResult<T>>;
192
+ /**
193
+ * Requests a password reset.
194
+ */
195
+ requestPasswordReset(data: PasswordResetRequest): Promise<void>;
196
+ /**
197
+ * Confirms a password reset.
198
+ */
199
+ confirmPasswordReset(data: PasswordResetConfirm): Promise<void>;
200
+ /**
201
+ * Updates the current user's profile.
202
+ */
203
+ updateProfile(data: Partial<T>): Promise<T>;
204
+ /**
205
+ * Changes the current user's password.
206
+ */
207
+ changePassword(oldPassword: string, newPassword: string): Promise<void>;
208
+ /**
209
+ * Initializes auth state (e.g., from stored tokens).
210
+ *
211
+ * LAZY and IDEMPOTENT: the first read of the state ({@link getState},
212
+ * {@link subscribe}, `useAuth()`) starts this same restore when nobody has called
213
+ * `initialize()`, and every later call shares the one promise instead of sending a
214
+ * second request. An app that keeps the template's explicit call behaves exactly as
215
+ * before; an app that loses that line still restores its session.
216
+ *
217
+ * With a stored token AND a stored user it marks the session `'authenticated'`
218
+ * SYNCHRONOUSLY — before its first `await` — so the first render is the
219
+ * signed-in UI and no page waits on a verification round trip. Any check
220
+ * (a refresh, the cookie-restore probe) settles behind that render, and only an
221
+ * explicit 401/403 ends the session; a network/5xx/404 failure keeps it and
222
+ * reports `'unavailable'`. With no stored user the client stays `'loading'`
223
+ * until the cookie restore decides.
224
+ *
225
+ * Do not put this call (or a `/me` request of your own) in front of the first
226
+ * render, and do not render a loading screen over a session it just restored:
227
+ * `whenRestored()` already resolves as soon as the restore has settled, and the
228
+ * HTTP gate built on it holds requests for exactly that window.
229
+ */
230
+ initialize(): Promise<void>;
231
+ /**
232
+ * Re-checks a restored session against the server, in the background — the
233
+ * boot-time validation an app with a stored token needs when a revoked or
234
+ * expired token must sign the user out. Call it AFTER the first render
235
+ * (`initialize()` restores synchronously from storage; this costs one request).
236
+ *
237
+ * - The server confirms the user: the session is refreshed and {@link AuthState.status}
238
+ * stays `'authenticated'`.
239
+ * - The server answers 401 or 403: the token is dead — the stored session is
240
+ * cleared and the status becomes `'unauthenticated'`.
241
+ * - The server cannot confirm the session — a network failure, a 5xx, or a 404
242
+ * from a misconfigured {@link AuthClientConfig.currentUserEndpoint}: the
243
+ * session (token AND user) is KEPT and the status becomes `'unavailable'`, so
244
+ * the app can retry instead of signing the user out over a bad connection or a
245
+ * route that does not exist. The 404 error names `currentUserEndpoint`.
246
+ *
247
+ * Do not hand-write this beside the client: a parallel token/user store for a
248
+ * "validating"/"unavailable" flag is the race this method removes.
249
+ *
250
+ * Optional: a provider with no restorable session has nothing to validate.
251
+ */
252
+ validateSession?(): Promise<void>;
253
+ /**
254
+ * Resolves when the session restore started by `initialize()` has settled — the point
255
+ * after which the client knows whether this visitor is signed in.
256
+ *
257
+ * Resolves IMMEDIATELY when no restore is in flight: before `initialize()` is ever
258
+ * called, and after it has finished. A restore that failed resolves too (it settled the
259
+ * question), so an HTTP client can await this before every request without risking one
260
+ * held forever. That is what makes the fetch-before-restore race impossible: a page that
261
+ * fetches viewer-dependent data on mount waits here instead of going out anonymously
262
+ * (see `setAuthGate` in `@molecule/app-http`).
263
+ *
264
+ * Optional: a provider that restores no session has nothing to wait for. Without it, an
265
+ * HTTP client bonded to that provider sends first-paint requests unauthenticated.
266
+ *
267
+ * A provider whose restore sends a request THROUGH the gated HTTP client must send that
268
+ * request with `skipAuthGate: true` (`RequestConfig` in `@molecule/app-http`): the gate
269
+ * waits on this promise, so holding the restore's own request makes the gate wait on
270
+ // … truncated — the full declaration is in node_modules/@molecule/app-react-native/dist
242
271
  ```
243
272
 
244
273
  #### `FormController`
@@ -393,7 +422,8 @@ interface HttpClient {
393
422
  */
394
423
  defaultHeaders: Record<string, string>
395
424
  /**
396
- * Makes a generic HTTP request.
425
+ * Makes a generic HTTP request. `data` is a field of THIS config object — the same body
426
+ * `post(url, data, config)` takes as its second argument.
397
427
  */
398
428
  request<T = unknown>(config: FullRequestConfig): Promise<HttpResponse<T>>
399
429
  /**
@@ -401,15 +431,19 @@ interface HttpClient {
401
431
  */
402
432
  get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
403
433
  /**
404
- * Makes a POST request.
434
+ * Makes a POST request. `data` is the request BODY, not a config object: the wire body is
435
+ * `data` itself, so `post(url, { data: body })` sends `{"data":body}` — pass `body` directly.
436
+ * A config (headers, params) is the THIRD argument.
405
437
  */
406
438
  post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
407
439
  /**
408
- * Makes a PUT request.
440
+ * Makes a PUT request. `data` is the request BODY (second argument) — never `{ data: body }`,
441
+ * which sends `{"data":body}`; a config is the THIRD argument.
409
442
  */
410
443
  put<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
411
444
  /**
412
- * Makes a PATCH request.
445
+ * Makes a PATCH request. `data` is the request BODY (second argument) — never `{ data: body }`,
446
+ * which sends `{"data":body}`; a config is the THIRD argument.
413
447
  */
414
448
  patch<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
415
449
  /**
@@ -448,77 +482,6 @@ interface HttpClient {
448
482
  }
449
483
  ```
450
484
 
451
- #### `HttpProviderProps`
452
-
453
- Props for http provider component.
454
-
455
- ```typescript
456
- interface HttpProviderProps extends ProviderProps {
457
- client: HttpClient
458
- }
459
- ```
460
-
461
- #### `I18nProviderProps`
462
-
463
- Props for i18n provider component.
464
-
465
- ```typescript
466
- interface I18nProviderProps extends ProviderProps {
467
- provider: I18nProvider
468
- }
469
- ```
470
-
471
- #### `LoggerProviderProps`
472
-
473
- Props for logger provider component.
474
-
475
- ```typescript
476
- interface LoggerProviderProps extends ProviderProps {
477
- provider: LoggerProvider
478
- }
479
- ```
480
-
481
- #### `MoleculeProviderProps`
482
-
483
- Properties for molecule provider.
484
-
485
- ```typescript
486
- interface MoleculeProviderProps extends ProviderProps {
487
- state?: StateProvider
488
- auth?: AuthClient<unknown>
489
- theme?: ThemeProvider
490
- router?: Router
491
- i18n?: I18nProvider
492
- http?: HttpClient
493
- storage?: StorageProvider
494
- logger?: LoggerProvider
495
- chat?: ChatProvider
496
- workspace?: WorkspaceProvider
497
- editor?: EditorProvider
498
- preview?: PreviewProvider
499
- }
500
- ```
501
-
502
- #### `PreviewProviderProps`
503
-
504
- Props for preview provider component.
505
-
506
- ```typescript
507
- interface PreviewProviderProps extends ProviderProps {
508
- provider: PreviewProvider
509
- }
510
- ```
511
-
512
- #### `ProviderProps`
513
-
514
- Props for provider components.
515
-
516
- ```typescript
517
- interface ProviderProps {
518
- children: ReactNode
519
- }
520
- ```
521
-
522
485
  #### `Router`
523
486
 
524
487
  Client-side router providing navigation, guards, route matching, and history control.
@@ -645,163 +608,124 @@ interface RouterConfig {
645
608
  }
646
609
  ```
647
610
 
648
- #### `RouterProviderProps`
611
+ #### `StoreConfig`
649
612
 
650
- Props for router provider component.
613
+ Configuration for creating a store (initial state, optional name, and middleware chain).
651
614
 
652
615
  ```typescript
653
- interface RouterProviderProps extends ProviderProps {
654
- router: Router
616
+ interface StoreConfig<T> {
617
+ /**
618
+ * Initial state value.
619
+ */
620
+ initialState: T
621
+ /**
622
+ * Optional name for debugging.
623
+ */
624
+ name?: string
625
+ /**
626
+ * Optional middleware functions.
627
+ */
628
+ middleware?: StoreMiddleware<T>[]
655
629
  }
656
630
  ```
657
631
 
658
- #### `SendMessageOptions`
632
+ #### `Store`
659
633
 
660
- Options for {@link UseChatResult.sendMessage}.
634
+ Reactive state container with getState, setState, subscribe, and destroy.
635
+
636
+ All state management providers must implement this interface.
661
637
 
662
638
  ```typescript
663
- interface SendMessageOptions {
664
- /**
665
- * Skip the optimistic local user-message bubble. The text is still sent to
666
- * the server. Used for ask_user responses: the answer is folded into the
667
- * ask_user tool card (a checkmark on the chosen option, or the custom text
668
- * shown in-card) rather than echoed as a separate message below it.
669
- */
670
- suppressUserMessage?: boolean
639
+ interface Store<T> {
671
640
  /**
672
- * Mark this send as issued automatically on the user's behalf (e.g. an
673
- * auto-fix prompt). The optimistic local bubble and the persisted message are
674
- * flagged `automatic` so the chat renders it in the distinct auto-sent style
675
- * (agent avatar + accent border) instead of looking like the user typed it.
641
+ * Gets the current state.
676
642
  */
677
- automatic?: boolean
643
+ getState(): T
678
644
  /**
679
- * Mark this send as the answer to the pending `ask_user` question. The most
680
- * recent unanswered `ask_user` tool call in the store is resolved in place —
681
- * its `output` is set to this answer — so the chosen option stays checked
682
- * across remounts (e.g. the discovery→IDE transition) instead of relying on
683
- * ephemeral component state that the answer's selection would otherwise lose.
684
- * Distinct from {@link suppressUserMessage} (which the post-boot kickoff also
685
- * sets) so resolving never misfires on a non-ask_user suppressed send.
645
+ * Sets the state (partial or via updater function).
686
646
  */
687
- askUserAnswer?: boolean
647
+ setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
688
648
  /**
689
- * Mark an {@link automatic} send as directly requested by the user (e.g. the
690
- * editor's "Fix with AI" action, the broken-preview overlay's "Fix with AI"
691
- * button) rather than dispatched autonomously by the platform. A user Stop
692
- * suppresses autonomous automatic sends until the user re-engages; a
693
- * user-initiated one IS that re-engagement — it clears the stop and sends.
649
+ * Subscribes to state changes.
650
+ * Returns an unsubscribe function.
694
651
  */
695
- userInitiated?: boolean
652
+ subscribe(listener: StateListener<T>): () => void
696
653
  /**
697
- * Send on the SIDE CHANNEL: a human-to-human message (e.g. a team note) the
698
- * server intercepts before running any agent turn. When the provider supports
699
- * `sendSideMessage`, the send goes out IMMEDIATELY on an independent request —
700
- * it never queues behind an active turn, never takes over the streaming
701
- * state, and never tears down remote-turn tracking (a viewer's note while
702
- * watching a teammate's turn must not stop the watching). Falls back to the
703
- * normal send path on providers without side-channel support.
654
+ * Destroys the store and cleans up subscriptions.
704
655
  */
705
- sideChannel?: boolean
656
+ destroy(): void
706
657
  }
707
658
  ```
708
659
 
709
- #### `StateProviderProps`
660
+ #### `Theme`
710
661
 
711
- Props for state provider component.
662
+ Complete theme definition.
712
663
 
713
664
  ```typescript
714
- interface StateProviderProps extends ProviderProps {
715
- provider: StateProvider
716
- }
717
- ```
718
-
719
- #### `StorageProviderProps`
720
-
721
- Props for storage provider component.
722
-
723
- ```typescript
724
- interface StorageProviderProps extends ProviderProps {
725
- provider: StorageProvider
665
+ interface Theme {
666
+ name: string
667
+ mode: 'light' | 'dark'
668
+ colors: ThemeColors
669
+ breakpoints: ThemeBreakpoints
670
+ spacing: ThemeSpacing
671
+ typography: ThemeTypography
672
+ borderRadius: ThemeBorderRadius
673
+ shadows: ThemeShadows
674
+ transitions: ThemeTransitions
675
+ zIndex: ThemeZIndex
726
676
  }
727
677
  ```
728
678
 
729
- #### `Store`
730
-
731
- Reactive state container with getState, setState, subscribe, and destroy.
679
+ #### `UseBackHandlerOptions`
732
680
 
733
- All state management providers must implement this interface.
681
+ Options for the useBackHandler hook.
734
682
 
735
683
  ```typescript
736
- interface Store<T> {
737
- /**
738
- * Gets the current state.
739
- */
740
- getState(): T
741
- /**
742
- * Sets the state (partial or via updater function).
743
- */
744
- setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
745
- /**
746
- * Subscribes to state changes.
747
- * Returns an unsubscribe function.
748
- */
749
- subscribe(listener: StateListener<T>): () => void
750
- /**
751
- * Destroys the store and cleans up subscriptions.
752
- */
753
- destroy(): void
684
+ interface UseBackHandlerOptions {
685
+ /** Whether the handler is enabled. Defaults to true. */
686
+ enabled?: boolean
754
687
  }
755
688
  ```
756
689
 
757
- #### `StoreConfig`
690
+ #### `UseAppStateResult`
758
691
 
759
- Configuration for creating a store (initial state, optional name, and middleware chain).
692
+ Result from the useAppState hook.
760
693
 
761
694
  ```typescript
762
- interface StoreConfig<T> {
763
- /**
764
- * Initial state value.
765
- */
766
- initialState: T
767
- /**
768
- * Optional name for debugging.
769
- */
770
- name?: string
771
- /**
772
- * Optional middleware functions.
773
- */
774
- middleware?: StoreMiddleware<T>[]
695
+ interface UseAppStateResult {
696
+ /** Current app state: 'active' | 'background' | 'inactive' */
697
+ appState: string
698
+ /** Whether the app is in the foreground */
699
+ isActive: boolean
775
700
  }
776
701
  ```
777
702
 
778
- #### `Theme`
703
+ #### `UseKeyboardHeightResult`
779
704
 
780
- Complete theme definition.
705
+ Result from the useKeyboardHeight hook.
781
706
 
782
707
  ```typescript
783
- interface Theme {
784
- name: string
785
- mode: 'light' | 'dark'
786
- colors: ThemeColors
787
- breakpoints: ThemeBreakpoints
788
- spacing: ThemeSpacing
789
- typography: ThemeTypography
790
- borderRadius: ThemeBorderRadius
791
- shadows: ThemeShadows
792
- transitions: ThemeTransitions
793
- zIndex: ThemeZIndex
708
+ interface UseKeyboardHeightResult {
709
+ /** Current keyboard height in points (0 when hidden) */
710
+ keyboardHeight: number
711
+ /** Whether the keyboard is currently visible */
712
+ isKeyboardVisible: boolean
794
713
  }
795
714
  ```
796
715
 
797
- #### `ThemeProviderProps`
716
+ #### `AgentIdentity`
798
717
 
799
- Props for theme provider component.
718
+ Display identity for the AI coding agent and the host product, used to
719
+ interpolate the `{{agentName}}` / `{{productName}}` tokens in shared chat/IDE
720
+ copy. A consuming app sets these to its own agent + product brand names; the
721
+ shared packages fall back to {@link DEFAULT_AGENT_IDENTITY} when it does not.
800
722
 
801
723
  ```typescript
802
- interface ThemeProviderProps extends ProviderProps {
803
- provider: ThemeProvider
804
- initialTheme?: string
724
+ interface AgentIdentity {
725
+ /** Display name of the AI coding agent. Defaults to {@link DEFAULT_AGENT_NAME}. */
726
+ agentName: string
727
+ /** Display name of the host product / IDE. Defaults to {@link DEFAULT_PRODUCT_NAME}. */
728
+ productName: string
805
729
  }
806
730
  ```
807
731
 
@@ -827,384 +751,119 @@ interface UseAIModelsResult {
827
751
  }
828
752
  ```
829
753
 
830
- #### `UseAppStateResult`
754
+ #### `UseChangePasswordReturn`
831
755
 
832
- Result from the useAppState hook.
756
+ Return type for useChangePassword hook.
833
757
 
834
758
  ```typescript
835
- interface UseAppStateResult {
836
- /** Current app state: 'active' | 'background' | 'inactive' */
837
- appState: string
838
- /** Whether the app is in the foreground */
839
- isActive: boolean
759
+ interface UseChangePasswordReturn {
760
+ status: UsePromiseState<void>['status']
761
+ error: UsePromiseState<void>['error']
762
+ changePassword: (oldPassword: string, newPassword: string) => Promise<void>
763
+ reset: () => void
840
764
  }
841
765
  ```
842
766
 
843
- #### `UseAuthOptions`
767
+ #### `UseDeviceResult`
844
768
 
845
- Hook options for useAuth.
769
+ Hook return type.
846
770
 
847
771
  ```typescript
848
- interface UseAuthOptions {
772
+ interface UseDeviceResult {
773
+ deviceInfo: DeviceInfo
774
+ screenInfo: ScreenInfo
775
+ hardwareInfo: HardwareInfo
776
+ featureSupport: FeatureSupport
777
+ supports: (feature: keyof FeatureSupport) => boolean
778
+ isOnline: () => boolean
779
+ isStandalone: () => boolean
780
+ language: string
781
+ languages: string[]
782
+ }
783
+ ```
784
+
785
+ #### `UseFormOptions`
786
+
787
+ Options for useForm hook.
788
+
789
+ ```typescript
790
+ interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
849
791
  /**
850
- * Whether to automatically refresh the token on mount.
792
+ * Form provider's createForm function.
851
793
  */
852
- autoRefresh?: boolean
794
+ createForm: (options: FormOptions<T>) => FormController<T>
853
795
  }
854
796
  ```
855
797
 
856
- #### `UseAuthResult`
798
+ #### `UseFormResult`
857
799
 
858
- Hook result for useAuth.
800
+ Result of useForm hook.
859
801
 
860
802
  ```typescript
861
- interface UseAuthResult<T = unknown> {
862
- state: AuthState<T>
863
- login: AuthClient<T>['login']
864
- logout: AuthClient<T>['logout']
865
- register: AuthClient<T>['register']
866
- refresh: AuthClient<T>['refresh']
867
- setUser: AuthClient<T>['setUser']
868
- isAuthenticated: boolean
869
- isLoading: boolean
870
- user: T | null
803
+ interface UseFormResult<T extends Record<string, unknown>> {
804
+ formState: FormState<T>
805
+ isValid: boolean
806
+ isDirty: boolean
807
+ isSubmitting: boolean
808
+ register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
809
+ getValue: <K extends keyof T>(name: K) => T[K]
810
+ setValue: <K extends keyof T>(name: K, value: T[K]) => void
811
+ getError: (name: keyof T) => string | undefined
812
+ setError: (name: keyof T, error: string | undefined) => void
813
+ clearErrors: () => void
814
+ handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (event?: React.FormEvent) => void
815
+ reset: (values?: Partial<T>) => void
816
+ validate: () => Promise<boolean>
871
817
  }
872
818
  ```
873
819
 
874
- #### `UseBackHandlerOptions`
820
+ #### `UseHttpState`
875
821
 
876
- Options for the useBackHandler hook.
822
+ State for async HTTP operations.
877
823
 
878
824
  ```typescript
879
- interface UseBackHandlerOptions {
880
- /** Whether the handler is enabled. Defaults to true. */
881
- enabled?: boolean
825
+ interface UseHttpState<T> {
826
+ data: T | null
827
+ loading: boolean
828
+ error: Error | null
882
829
  }
883
830
  ```
884
831
 
885
- #### `UseChangePasswordReturn`
832
+ #### `UseHttpResult`
886
833
 
887
- Return type for useChangePassword hook.
834
+ Result of useHttp hook.
888
835
 
889
836
  ```typescript
890
- interface UseChangePasswordReturn {
891
- status: UsePromiseState<void>['status']
892
- error: UsePromiseState<void>['error']
893
- changePassword: (oldPassword: string, newPassword: string) => Promise<void>
837
+ interface UseHttpResult<T> extends UseHttpState<T> {
838
+ execute: () => Promise<T | null>
894
839
  reset: () => void
895
840
  }
896
841
  ```
897
842
 
898
- #### `UseChatOptions`
843
+ #### `UseHttpOptions`
899
844
 
900
- Hook options for useChat.
845
+ Options for useHttp hook.
901
846
 
902
847
  ```typescript
903
- interface UseChatOptions {
904
- /** Chat endpoint (e.g., '/projects/123/chat'). */
905
- endpoint: string
906
- /** Project ID for context. */
907
- projectId?: string
848
+ interface UseHttpOptions<T> extends RequestConfig {
908
849
  /**
909
- * Display name of the AI coding agent, interpolated into user-facing chat
910
- * copy (e.g. the stalled-stream notice). The host passes its own agent brand
911
- * name; defaults to the neutral `DEFAULT_AGENT_NAME` so the shared hook never
912
- * names a specific product.
850
+ * Whether to execute the request immediately on mount.
913
851
  */
914
- agentName?: string
915
- /** Load history on mount. */
916
- loadOnMount?: boolean
852
+ immediate?: boolean
917
853
  /**
918
- * This client may only WATCH the conversation (e.g. a read-only project
919
- * viewer): the hook never issues chat POSTs on its behalf — no resume
920
- * request after a reload, no auto-retries. A live turn is followed through
921
- * the remote-watch path instead: pushed broadcast frames (applyRemoteEvent)
922
- * render it in real time and the history reconcile poll backstops gaps, with
923
- * `isRemoteStreaming` driving the activity indicator.
854
+ * Callback when request succeeds.
924
855
  */
925
- readOnly?: boolean
926
- /** Called when a file is created or modified by a tool call (path + new content). */
927
- onFileChange?: (path: string, content: string) => void
928
- /** Called when the AI switches between plan and execute modes. */
929
- onModeChange?: (mode: 'plan' | 'execute') => void
930
- /** Called when the backend assigns or confirms a conversation ID. */
931
- onConversationId?: (id: string) => void
932
- /** Called for every streaming event — useful for notifications, sounds, etc. */
933
- onStreamEvent?: (event: ChatStreamEvent) => void
856
+ onSuccess?: (data: T) => void
857
+ /**
858
+ * Callback when request fails.
859
+ */
860
+ onError?: (error: Error) => void
934
861
  }
935
862
  ```
936
863
 
937
- #### `UseChatResult`
864
+ #### `UseLoginReturn`
938
865
 
939
- Hook result for useChat.
940
-
941
- ```typescript
942
- interface UseChatResult {
943
- messages: ChatMessage[]
944
- isLoading: boolean
945
- /**
946
- * True while a backend turn for this conversation streams WITHOUT this client
947
- * owning the request — a turn started in another tab, by a teammate, or any
948
- * server-side continuation. Detected from pushed (broadcast) chat events and
949
- * confirmed/cleared against the server's `streaming` history flag, so the Stop
950
- * control can stay visible and functional whenever ANY backend turn is live —
951
- * not only for sends this hook instance made.
952
- */
953
- isRemoteStreaming: boolean
954
- /**
955
- * Tell the hook a pushed (broadcast) chat event arrived for this conversation.
956
- * The host (ChatPanel) calls this from its push-channel handler; the hook then
957
- * confirms against the server's `streaming` flag and, while a remote turn is
958
- * live, keeps `isRemoteStreaming` true until the server reports it finished.
959
- */
960
- noteRemoteStreamEvent: () => void
961
- error: string | null
962
- /**
963
- * Metadata about a limit-related error, for a contextual call-to-action.
964
- * `limitType` names the RULE the backend enforced; `billingAction` names the
965
- * REMEDY it resolved (e.g. `add_funds`, `add_payment_method`,
966
- * `raise_spend_cap`, `upgrade`, `none`) and is what the button should be
967
- * built from — the same limit needs a different button per account.
968
- * `upgradeTier` is the plan an upgrade would move to, explicitly `null` when
969
- * there is no higher tier. The backend owns these vocabularies, so the
970
- * action/tier are plain strings here.
971
- */
972
- errorMeta: {
973
- limitType?: string
974
- requiresSignup?: boolean
975
- billingAction?: string
976
- upgradeTier?: string | null
977
- } | null
978
- /** Current agent mode — plan (read-only research) or execute (full access). */
979
- mode: 'plan' | 'execute'
980
- /**
981
- * Whether the conversation runs at the provider's fast/priority speed tier
982
- * (server-persisted per conversation; hydrated from the history load's
983
- * `fastMode` meta field, when the server provides one). Only meaningful for
984
- * models that support a fast tier — the server ignores it otherwise.
985
- */
986
- fastMode: boolean
987
- /**
988
- * Transient label for a background phase (e.g. the post-response verification
989
- * pass — "Type-checking the API", "Linting"), set by `status` stream events.
990
- * The UI shows it in place of the spinner's generic rotating messages; `null`
991
- * when no such phase is active.
992
- */
993
- streamingStatus: string | null
994
- /**
995
- * Active 5XX backoff-retry countdown, or `null` when none is pending. After a
996
- * backend server error (HTTP 5XX) the hook does NOT surface a terminal error —
997
- * it shows this cancelable countdown and, when it elapses, auto-resumes the
998
- * turn where the user left off (`resume:true`). `secondsRemaining` ticks down
999
- * once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
1000
- * limit/quota, and signup-required errors never auto-retry.
1001
- */
1002
- retryCountdown: {
1003
- secondsRemaining: number
1004
- attempt: number
1005
- } | null
1006
- /** Update the local mode state (for instant mode toggle without an AI turn). */
1007
- setMode: (mode: 'plan' | 'execute') => void
1008
- /** Update the local fast-mode state (for instant toggle without an AI turn). */
1009
- setFastMode: (fastMode: boolean) => void
1010
- sendMessage: (
1011
- message: string,
1012
- attachments?: ChatAttachment[],
1013
- options?: SendMessageOptions,
1014
- ) => Promise<void>
1015
- abort: () => void
1016
- /**
1017
- * Cancel a pending 5XX auto-retry. Clears the countdown and surfaces the
1018
- * original error (via `error`) so the user sees why the turn failed.
1019
- */
1020
- cancelRetry: () => void
1021
- clearHistory: () => Promise<void>
1022
- /** Edit the content of a queued (not yet sent) message. */
1023
- editQueuedMessage: (msgId: string, newContent: string) => void
1024
- /** Remove a queued (not yet sent) message from the queue. */
1025
- deleteQueuedMessage: (msgId: string) => void
1026
- /** Remove queued auto-fix messages whose content references the given file path. */
1027
- clearQueuedForFile: (filePath: string) => void
1028
- /**
1029
- * Append an inline transcript card (model / mode / skills / custom notice) as a
1030
- * `role:'system'` card-message in the ONE message store. Used by the host (ChatPanel)
1031
- * to render a TEAMMATE's broadcast `card` event live — this client's OWN cards arrive
1032
- * through the stream and are appended internally. De-duped by the server-assigned id.
1033
- */
1034
- appendCardMessage: (
1035
- id: string,
1036
- timestamp: number,
1037
- card: NonNullable<ChatMessage['cardEvent']>,
1038
- ) => void
1039
- /**
1040
- * Append a COMPLETE, non-streaming chat message (a `message` stream event — e.g.
1041
- * a teammate's human-only team note) to the ONE message store. Used by the host
1042
- * (ChatPanel) to render a TEAMMATE's broadcast `message` event live — this
1043
- * client's OWN `message` events arrive through the stream and are appended
1044
- * internally. De-duped by the server-assigned message id.
1045
- */
1046
- appendCompleteMessage: (message: ChatMessage) => void
1047
- /**
1048
- * Ingest ONE pushed (broadcast) stream frame from a turn running elsewhere —
1049
- * a teammate's send, another tab, a server-side continuation — into the ONE
1050
- * message store, through the same content applier as an own SSE stream: text/
1051
- * thinking deltas, tool events, verification, cards, complete messages, done.
1052
- * The host (ChatPanel) calls this from its push-channel handler for every
1053
- * broadcast frame of the OPEN conversation. Own echoes are dropped while a
1054
- * local send is in flight (the SSE stream is authoritative for the sender);
1055
- * complete id-carrying items (cards, team notes) always apply, de-duped.
1056
- */
1057
- applyRemoteEvent: (event: ChatStreamEvent) => void
1058
- /**
1059
- * Reload history and converge the local view on the server transcript (and
1060
- * re-enter a still-streaming turn). The page-lifecycle events run this
1061
- * automatically; the host should ALSO call it whenever its chat push channel
1062
- * (re)connects — a broadcast sent while that socket was down (a teammate's
1063
- * team note against a backgrounded tab or a slept laptop) is otherwise lost
1064
- * until the next lifecycle event happens to fire. Cheap when nothing changed:
1065
- * an identical transcript is never re-applied.
1066
- */
1067
- reconcileHistory: () => Promise<void>
1068
- }
1069
- ```
1070
-
1071
- #### `UseDeviceResult`
1072
-
1073
- Hook return type.
1074
-
1075
- ```typescript
1076
- interface UseDeviceResult {
1077
- deviceInfo: DeviceInfo
1078
- screenInfo: ScreenInfo
1079
- hardwareInfo: HardwareInfo
1080
- featureSupport: FeatureSupport
1081
- supports: (feature: keyof FeatureSupport) => boolean
1082
- isOnline: () => boolean
1083
- isStandalone: () => boolean
1084
- language: string
1085
- languages: string[]
1086
- }
1087
- ```
1088
-
1089
- #### `UseEditorResult`
1090
-
1091
- Hook result for useEditor.
1092
-
1093
- ```typescript
1094
- interface UseEditorResult {
1095
- tabs: EditorTab[]
1096
- activeFile: string | null
1097
- openFile: (file: EditorFile) => void
1098
- closeFile: (path: string) => void
1099
- getContent: () => string | null
1100
- setContent: (path: string, content: string) => void
1101
- setActiveTab: (path: string) => void
1102
- mount: EditorProvider['mount']
1103
- dispose: () => void
1104
- focus: () => void
1105
- openDiff: (file: DiffFile) => void
1106
- closeDiff: () => void
1107
- pinTab: (path: string) => void
1108
- addExtraLib: (content: string, filePath: string) => void
1109
- onFixWithAI: (callback: (request: FixWithAIRequest) => void) => () => void
1110
- }
1111
- ```
1112
-
1113
- #### `UseFormOptions`
1114
-
1115
- Options for useForm hook.
1116
-
1117
- ```typescript
1118
- interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
1119
- /**
1120
- * Form provider's createForm function.
1121
- */
1122
- createForm: (options: FormOptions<T>) => FormController<T>
1123
- }
1124
- ```
1125
-
1126
- #### `UseFormResult`
1127
-
1128
- Result of useForm hook.
1129
-
1130
- ```typescript
1131
- interface UseFormResult<T extends Record<string, unknown>> {
1132
- formState: FormState<T>
1133
- isValid: boolean
1134
- isDirty: boolean
1135
- isSubmitting: boolean
1136
- register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
1137
- getValue: <K extends keyof T>(name: K) => T[K]
1138
- setValue: <K extends keyof T>(name: K, value: T[K]) => void
1139
- getError: (name: keyof T) => string | undefined
1140
- setError: (name: keyof T, error: string | undefined) => void
1141
- clearErrors: () => void
1142
- handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (event?: React.FormEvent) => void
1143
- reset: (values?: Partial<T>) => void
1144
- validate: () => Promise<boolean>
1145
- }
1146
- ```
1147
-
1148
- #### `UseHttpOptions`
1149
-
1150
- Options for useHttp hook.
1151
-
1152
- ```typescript
1153
- interface UseHttpOptions<T> extends RequestConfig {
1154
- /**
1155
- * Whether to execute the request immediately on mount.
1156
- */
1157
- immediate?: boolean
1158
- /**
1159
- * Callback when request succeeds.
1160
- */
1161
- onSuccess?: (data: T) => void
1162
- /**
1163
- * Callback when request fails.
1164
- */
1165
- onError?: (error: Error) => void
1166
- }
1167
- ```
1168
-
1169
- #### `UseHttpResult`
1170
-
1171
- Result of useHttp hook.
1172
-
1173
- ```typescript
1174
- interface UseHttpResult<T> extends UseHttpState<T> {
1175
- execute: () => Promise<T | null>
1176
- reset: () => void
1177
- }
1178
- ```
1179
-
1180
- #### `UseHttpState`
1181
-
1182
- State for async HTTP operations.
1183
-
1184
- ```typescript
1185
- interface UseHttpState<T> {
1186
- data: T | null
1187
- loading: boolean
1188
- error: Error | null
1189
- }
1190
- ```
1191
-
1192
- #### `UseKeyboardHeightResult`
1193
-
1194
- Result from the useKeyboardHeight hook.
1195
-
1196
- ```typescript
1197
- interface UseKeyboardHeightResult {
1198
- /** Current keyboard height in points (0 when hidden) */
1199
- keyboardHeight: number
1200
- /** Whether the keyboard is currently visible */
1201
- isKeyboardVisible: boolean
1202
- }
1203
- ```
1204
-
1205
- #### `UseLoginReturn`
1206
-
1207
- Return type for useLogin hook.
866
+ Return type for useLogin hook.
1208
867
 
1209
868
  ```typescript
1210
869
  interface UseLoginReturn<T = unknown> {
@@ -1269,35 +928,9 @@ interface UsePlatformResult {
1269
928
  }
1270
929
  ```
1271
930
 
1272
- #### `UsePreviewResult`
931
+ #### `UsePromiseState`
1273
932
 
1274
- Hook result for usePreview.
1275
-
1276
- ```typescript
1277
- interface UsePreviewResult {
1278
- state: PreviewState
1279
- setUrl: (url: string) => void
1280
- refresh: () => void
1281
- setDevice: (device: DeviceFrame) => void
1282
- openExternal: () => void
1283
- /**
1284
- * Records a navigation the running preview reported via its `molecule:navigate`
1285
- * message — updates the displayed current location without reloading the iframe.
1286
- * Pass `isReplace` when the preview REPLACED its current history entry (a
1287
- * `replaceState` redirect/canonicalization) so the forward stack is preserved
1288
- * instead of truncated (a `pushState`, the default, truncates forward).
1289
- */
1290
- recordNavigation: (url: string, isReplace?: boolean) => void
1291
- /** Navigates the preview to the previous navigation-history entry (Back). */
1292
- back: () => void
1293
- /** Navigates the preview to the next navigation-history entry (Forward). */
1294
- forward: () => void
1295
- }
1296
- ```
1297
-
1298
- #### `UsePromiseState`
1299
-
1300
- Extended promise state with actions.
933
+ Extended promise state with actions.
1301
934
 
1302
935
  ```typescript
1303
936
  interface UsePromiseState<T> {
@@ -1309,19 +942,6 @@ interface UsePromiseState<T> {
1309
942
  }
1310
943
  ```
1311
944
 
1312
- #### `UsePushOptions`
1313
-
1314
- Options for the usePush hook (e.g. check permission on mount).
1315
-
1316
- ```typescript
1317
- interface UsePushOptions {
1318
- /**
1319
- * Whether to check permission status on mount.
1320
- */
1321
- checkOnMount?: boolean
1322
- }
1323
- ```
1324
-
1325
945
  #### `UsePushResult`
1326
946
 
1327
947
  Hook return type.
@@ -1342,20 +962,16 @@ interface UsePushResult {
1342
962
  }
1343
963
  ```
1344
964
 
1345
- #### `UseRouterResult`
965
+ #### `UsePushOptions`
1346
966
 
1347
- Hook result for useRouter.
967
+ Options for the usePush hook (e.g. check permission on mount).
1348
968
 
1349
969
  ```typescript
1350
- interface UseRouterResult {
1351
- location: Router['getLocation'] extends () => infer R ? R : never
1352
- params: Record<string, string>
1353
- query: QueryParams
1354
- navigate: Router['navigate']
1355
- navigateTo: Router['navigateTo']
1356
- back: Router['back']
1357
- forward: Router['forward']
1358
- isActive: Router['isActive']
970
+ interface UsePushOptions {
971
+ /**
972
+ * Whether to check permission status on mount.
973
+ */
974
+ checkOnMount?: boolean
1359
975
  }
1360
976
  ```
1361
977
 
@@ -1404,47 +1020,6 @@ interface UseStorageValueResult<T> {
1404
1020
  }
1405
1021
  ```
1406
1022
 
1407
- #### `UseStoreOptions`
1408
-
1409
- Hook options for useStore.
1410
-
1411
- ```typescript
1412
- interface UseStoreOptions<T, S> {
1413
- selector?: (state: T) => S
1414
- equalityFn?: (a: S, b: S) => boolean
1415
- }
1416
- ```
1417
-
1418
- #### `UseThemeResult`
1419
-
1420
- Hook result for useTheme.
1421
-
1422
- ```typescript
1423
- interface UseThemeResult {
1424
- theme: Theme
1425
- themeName: string
1426
- setTheme: (name: string) => void
1427
- toggleTheme: () => void
1428
- mode: 'light' | 'dark'
1429
- }
1430
- ```
1431
-
1432
- #### `UseTranslationResult`
1433
-
1434
- Hook result for useTranslation.
1435
-
1436
- ```typescript
1437
- interface UseTranslationResult {
1438
- t: I18nProvider['t']
1439
- locale: string
1440
- setLocale: I18nProvider['setLocale']
1441
- locales: ReturnType<I18nProvider['getLocales']>
1442
- formatNumber: I18nProvider['formatNumber']
1443
- formatDate: I18nProvider['formatDate']
1444
- direction: 'ltr' | 'rtl'
1445
- }
1446
- ```
1447
-
1448
1023
  #### `UseVerifyPaymentReturnOptions`
1449
1024
 
1450
1025
  Options for {@link useVerifyPaymentReturn}.
@@ -1515,6 +1090,502 @@ interface UseVersionResult {
1515
1090
  }
1516
1091
  ```
1517
1092
 
1093
+ #### `ProviderProps`
1094
+
1095
+ Props for provider components.
1096
+
1097
+ ```typescript
1098
+ interface ProviderProps {
1099
+ children: ReactNode
1100
+ }
1101
+ ```
1102
+
1103
+ #### `StateProviderProps`
1104
+
1105
+ Props for state provider component.
1106
+
1107
+ ```typescript
1108
+ interface StateProviderProps extends ProviderProps {
1109
+ provider: StateProvider
1110
+ }
1111
+ ```
1112
+
1113
+ #### `AuthProviderProps`
1114
+
1115
+ Props for auth provider component.
1116
+
1117
+ ```typescript
1118
+ interface AuthProviderProps<T = unknown> extends ProviderProps {
1119
+ client: AuthClient<T>
1120
+ }
1121
+ ```
1122
+
1123
+ #### `ThemeProviderProps`
1124
+
1125
+ Props for theme provider component.
1126
+
1127
+ ```typescript
1128
+ interface ThemeProviderProps extends ProviderProps {
1129
+ provider: ThemeProvider
1130
+ initialTheme?: string
1131
+ }
1132
+ ```
1133
+
1134
+ #### `RouterProviderProps`
1135
+
1136
+ Props for router provider component.
1137
+
1138
+ ```typescript
1139
+ interface RouterProviderProps extends ProviderProps {
1140
+ router: Router
1141
+ }
1142
+ ```
1143
+
1144
+ #### `I18nProviderProps`
1145
+
1146
+ Props for i18n provider component.
1147
+
1148
+ ```typescript
1149
+ interface I18nProviderProps extends ProviderProps {
1150
+ provider: I18nProvider
1151
+ }
1152
+ ```
1153
+
1154
+ #### `HttpProviderProps`
1155
+
1156
+ Props for http provider component.
1157
+
1158
+ ```typescript
1159
+ interface HttpProviderProps extends ProviderProps {
1160
+ client: HttpClient
1161
+ }
1162
+ ```
1163
+
1164
+ #### `StorageProviderProps`
1165
+
1166
+ Props for storage provider component.
1167
+
1168
+ ```typescript
1169
+ interface StorageProviderProps extends ProviderProps {
1170
+ provider: StorageProvider
1171
+ }
1172
+ ```
1173
+
1174
+ #### `LoggerProviderProps`
1175
+
1176
+ Props for logger provider component.
1177
+
1178
+ ```typescript
1179
+ interface LoggerProviderProps extends ProviderProps {
1180
+ provider: LoggerProvider
1181
+ }
1182
+ ```
1183
+
1184
+ #### `ChatProviderProps`
1185
+
1186
+ Props for the ChatProvider React component.
1187
+
1188
+ ```typescript
1189
+ interface ChatProviderProps extends ProviderProps {
1190
+ provider: ChatProvider
1191
+ }
1192
+ ```
1193
+
1194
+ #### `WorkspaceProviderProps`
1195
+
1196
+ Props for workspace provider component.
1197
+
1198
+ ```typescript
1199
+ interface WorkspaceProviderProps extends ProviderProps {
1200
+ provider: WorkspaceProvider
1201
+ }
1202
+ ```
1203
+
1204
+ #### `EditorProviderProps`
1205
+
1206
+ Props for editor provider component.
1207
+
1208
+ ```typescript
1209
+ interface EditorProviderProps extends ProviderProps {
1210
+ provider: EditorProvider
1211
+ }
1212
+ ```
1213
+
1214
+ #### `PreviewProviderProps`
1215
+
1216
+ Props for preview provider component.
1217
+
1218
+ ```typescript
1219
+ interface PreviewProviderProps extends ProviderProps {
1220
+ provider: PreviewProvider
1221
+ }
1222
+ ```
1223
+
1224
+ #### `MoleculeProviderProps`
1225
+
1226
+ Properties for molecule provider.
1227
+
1228
+ ```typescript
1229
+ interface MoleculeProviderProps extends ProviderProps {
1230
+ state?: StateProvider
1231
+ auth?: AuthClient<unknown>
1232
+ theme?: ThemeProvider
1233
+ router?: Router
1234
+ i18n?: I18nProvider
1235
+ http?: HttpClient
1236
+ storage?: StorageProvider
1237
+ logger?: LoggerProvider
1238
+ chat?: ChatProvider
1239
+ workspace?: WorkspaceProvider
1240
+ editor?: EditorProvider
1241
+ preview?: PreviewProvider
1242
+ }
1243
+ ```
1244
+
1245
+ #### `UseStoreOptions`
1246
+
1247
+ Hook options for useStore.
1248
+
1249
+ ```typescript
1250
+ interface UseStoreOptions<T, S> {
1251
+ selector?: (state: T) => S
1252
+ equalityFn?: (a: S, b: S) => boolean
1253
+ }
1254
+ ```
1255
+
1256
+ #### `UseAuthOptions`
1257
+
1258
+ Hook options for useAuth.
1259
+
1260
+ ```typescript
1261
+ interface UseAuthOptions {
1262
+ /**
1263
+ * Whether to automatically refresh the token on mount.
1264
+ */
1265
+ autoRefresh?: boolean
1266
+ }
1267
+ ```
1268
+
1269
+ #### `UseAuthResult`
1270
+
1271
+ Hook result for useAuth.
1272
+
1273
+ ```typescript
1274
+ interface UseAuthResult<T = unknown> {
1275
+ /**
1276
+ * The session state as one value — render from this instead of combining
1277
+ * `initialized`/`authenticated`/`loading`. A stored token AND user make it
1278
+ * `'authenticated'` on the first render; only `'loading'` means "no decision
1279
+ * yet", so a route guard waits on that and nothing else.
1280
+ */
1281
+ status: AuthState<T>['status']
1282
+ state: AuthState<T>
1283
+ login: AuthClient<T>['login']
1284
+ logout: AuthClient<T>['logout']
1285
+ register: AuthClient<T>['register']
1286
+ refresh: AuthClient<T>['refresh']
1287
+ setUser: AuthClient<T>['setUser']
1288
+ /**
1289
+ * Adopt a session an exchange outside the client already established (an
1290
+ * OAuth code→token redirect, the app's own sign-in endpoint) in ONE update:
1291
+ * the token and user are stored and the hook's consumers see the client as
1292
+ * `authenticated` immediately.
1293
+ *
1294
+ * `setUser` alone does NOT sign the client in, and `setAccessToken` changes
1295
+ * storage only — using those two for a caller-issued session leaves every
1296
+ * `authenticated` read signed out (xr-molecule-flash-m178).
1297
+ */
1298
+ setSession: AuthClient<T>['setSession']
1299
+ isAuthenticated: boolean
1300
+ isLoading: boolean
1301
+ user: T | null
1302
+ }
1303
+ ```
1304
+
1305
+ #### `UseThemeResult`
1306
+
1307
+ Hook result for useTheme.
1308
+
1309
+ ```typescript
1310
+ interface UseThemeResult {
1311
+ theme: Theme
1312
+ themeName: string
1313
+ setTheme: (name: string) => void
1314
+ toggleTheme: () => void
1315
+ mode: 'light' | 'dark'
1316
+ }
1317
+ ```
1318
+
1319
+ #### `UseRouterResult`
1320
+
1321
+ Hook result for useRouter.
1322
+
1323
+ ```typescript
1324
+ interface UseRouterResult {
1325
+ location: Router['getLocation'] extends () => infer R ? R : never
1326
+ params: Record<string, string>
1327
+ query: QueryParams
1328
+ navigate: Router['navigate']
1329
+ navigateTo: Router['navigateTo']
1330
+ back: Router['back']
1331
+ forward: Router['forward']
1332
+ isActive: Router['isActive']
1333
+ }
1334
+ ```
1335
+
1336
+ #### `UseTranslationResult`
1337
+
1338
+ Hook result for useTranslation.
1339
+
1340
+ ```typescript
1341
+ interface UseTranslationResult {
1342
+ t: I18nProvider['t']
1343
+ locale: string
1344
+ setLocale: I18nProvider['setLocale']
1345
+ locales: ReturnType<I18nProvider['getLocales']>
1346
+ formatNumber: I18nProvider['formatNumber']
1347
+ formatDate: I18nProvider['formatDate']
1348
+ direction: 'ltr' | 'rtl'
1349
+ }
1350
+ ```
1351
+
1352
+ #### `UseChatOptions`
1353
+
1354
+ Hook options for useChat.
1355
+
1356
+ ```typescript
1357
+ interface UseChatOptions {
1358
+ /** Chat endpoint (e.g., '/projects/123/chat'). */
1359
+ endpoint: string
1360
+ /** Project ID for context. */
1361
+ projectId?: string
1362
+ /**
1363
+ * Display name of the AI coding agent, interpolated into user-facing chat
1364
+ * copy (e.g. the stalled-stream notice). The host passes its own agent brand
1365
+ * name; defaults to the neutral `DEFAULT_AGENT_NAME` so the shared hook never
1366
+ * names a specific product.
1367
+ */
1368
+ agentName?: string
1369
+ /** Load history on mount. */
1370
+ loadOnMount?: boolean
1371
+ /**
1372
+ * This client may only WATCH the conversation (e.g. a read-only project
1373
+ * viewer): the hook never issues chat POSTs on its behalf — no resume
1374
+ * request after a reload, no auto-retries. A live turn is followed through
1375
+ * the remote-watch path instead: pushed broadcast frames (applyRemoteEvent)
1376
+ * render it in real time and the history reconcile poll backstops gaps, with
1377
+ * `isRemoteStreaming` driving the activity indicator.
1378
+ */
1379
+ readOnly?: boolean
1380
+ /** Called when a file is created or modified by a tool call (path + new content). */
1381
+ onFileChange?: (path: string, content: string) => void
1382
+ /** Called when the AI switches between plan and execute modes. */
1383
+ onModeChange?: (mode: 'plan' | 'execute') => void
1384
+ /** Called when the backend assigns or confirms a conversation ID. */
1385
+ onConversationId?: (id: string) => void
1386
+ /** Called for every streaming event — useful for notifications, sounds, etc. */
1387
+ onStreamEvent?: (event: ChatStreamEvent) => void
1388
+ }
1389
+ ```
1390
+
1391
+ #### `SendMessageOptions`
1392
+
1393
+ Options for {@link UseChatResult.sendMessage}.
1394
+
1395
+ ```typescript
1396
+ interface SendMessageOptions {
1397
+ /**
1398
+ * Skip the optimistic local user-message bubble. The text is still sent to
1399
+ * the server. Used for ask_user responses: the answer is folded into the
1400
+ * ask_user tool card (a checkmark on the chosen option, or the custom text
1401
+ * shown in-card) rather than echoed as a separate message below it.
1402
+ */
1403
+ suppressUserMessage?: boolean
1404
+ /**
1405
+ * Mark this send as issued automatically on the user's behalf (e.g. an
1406
+ * auto-fix prompt). The optimistic local bubble and the persisted message are
1407
+ * flagged `automatic` so the chat renders it in the distinct auto-sent style
1408
+ * (agent avatar + accent border) instead of looking like the user typed it.
1409
+ */
1410
+ automatic?: boolean
1411
+ /**
1412
+ * Mark this send as the answer to the pending `ask_user` question. The most
1413
+ * recent unanswered `ask_user` tool call in the store is resolved in place —
1414
+ * its `output` is set to this answer — so the chosen option stays checked
1415
+ * across remounts (e.g. the discovery→IDE transition) instead of relying on
1416
+ * ephemeral component state that the answer's selection would otherwise lose.
1417
+ * Distinct from {@link suppressUserMessage} (which the post-boot kickoff also
1418
+ * sets) so resolving never misfires on a non-ask_user suppressed send.
1419
+ */
1420
+ askUserAnswer?: boolean
1421
+ /**
1422
+ * Mark an {@link automatic} send as directly requested by the user (e.g. the
1423
+ * editor's "Fix with AI" action, the broken-preview overlay's "Fix with AI"
1424
+ * button) rather than dispatched autonomously by the platform. A user Stop
1425
+ * suppresses autonomous automatic sends until the user re-engages; a
1426
+ * user-initiated one IS that re-engagement — it clears the stop and sends.
1427
+ */
1428
+ userInitiated?: boolean
1429
+ /**
1430
+ * Send on the SIDE CHANNEL: a human-to-human message (e.g. a team note) the
1431
+ * server intercepts before running any agent turn. When the provider supports
1432
+ * `sendSideMessage`, the send goes out IMMEDIATELY on an independent request —
1433
+ * it never queues behind an active turn, never takes over the streaming
1434
+ * state, and never tears down remote-turn tracking (a viewer's note while
1435
+ * watching a teammate's turn must not stop the watching). Falls back to the
1436
+ * normal send path on providers without side-channel support.
1437
+ */
1438
+ sideChannel?: boolean
1439
+ /**
1440
+ * Mark this send as composed through voice dictation — the mic button's
1441
+ * transcript was still present in the composer at submit. The optimistic
1442
+ * bubble and the persisted message are flagged `viaDictation` so the chat
1443
+ * renders a mic badge on the message, live and after a reload.
1444
+ */
1445
+ viaDictation?: boolean
1446
+ }
1447
+ ```
1448
+
1449
+ #### `UseChatResult`
1450
+
1451
+ Hook result for useChat.
1452
+
1453
+ ```typescript
1454
+ interface UseChatResult {
1455
+ messages: ChatMessage[]
1456
+ isLoading: boolean
1457
+ /**
1458
+ * True while a backend turn for this conversation streams WITHOUT this client
1459
+ * owning the request — a turn started in another tab, by a teammate, or any
1460
+ * server-side continuation. Detected from pushed (broadcast) chat events and
1461
+ * confirmed/cleared against the server's `streaming` history flag, so the Stop
1462
+ * control can stay visible and functional whenever ANY backend turn is live —
1463
+ * not only for sends this hook instance made.
1464
+ */
1465
+ isRemoteStreaming: boolean
1466
+ /**
1467
+ * Tell the hook a pushed (broadcast) chat event arrived for this conversation.
1468
+ * The host (ChatPanel) calls this from its push-channel handler; the hook then
1469
+ * confirms against the server's `streaming` flag and, while a remote turn is
1470
+ * live, keeps `isRemoteStreaming` true until the server reports it finished.
1471
+ */
1472
+ noteRemoteStreamEvent: () => void
1473
+ error: string | null
1474
+ /**
1475
+ * Metadata about a limit-related error, for a contextual call-to-action.
1476
+ * `limitType` names the RULE the backend enforced; `billingAction` names the
1477
+ * REMEDY it resolved (e.g. `add_funds`, `add_payment_method`,
1478
+ * `raise_spend_cap`, `upgrade`, `none`) and is what the button should be
1479
+ * built from — the same limit needs a different button per account.
1480
+ * `upgradeTier` is the plan an upgrade would move to, explicitly `null` when
1481
+ * there is no higher tier. The backend owns these vocabularies, so the
1482
+ * action/tier are plain strings here.
1483
+ */
1484
+ errorMeta: {
1485
+ limitType?: string
1486
+ requiresSignup?: boolean
1487
+ billingAction?: string
1488
+ upgradeTier?: string | null
1489
+ } | null
1490
+ /** Current agent mode — plan (read-only research) or execute (full access). */
1491
+ mode: 'plan' | 'execute'
1492
+ /**
1493
+ * Whether the conversation runs at the provider's fast/priority speed tier
1494
+ * (server-persisted per conversation; hydrated from the history load's
1495
+ * `fastMode` meta field, when the server provides one). Only meaningful for
1496
+ * models that support a fast tier — the server ignores it otherwise.
1497
+ */
1498
+ fastMode: boolean
1499
+ /**
1500
+ * Transient label for a background phase (e.g. the post-response verification
1501
+ * pass — "Type-checking the API", "Linting"), set by `status` stream events.
1502
+ * The UI shows it in place of the spinner's generic rotating messages; `null`
1503
+ * when no such phase is active.
1504
+ */
1505
+ streamingStatus: string | null
1506
+ /**
1507
+ * Commands the executor detached with `run_in_background`, newest last. Each
1508
+ * appears here the moment it starts and is replaced in place when it finishes,
1509
+ * so the UI can show work that outlives the tool call that started it.
1510
+ */
1511
+ backgroundTasks: BackgroundTaskState[]
1512
+ /**
1513
+ * Active 5XX backoff-retry countdown, or `null` when none is pending. After a
1514
+ * backend server error (HTTP 5XX) the hook does NOT surface a terminal error —
1515
+ * it shows this cancelable countdown and, when it elapses, auto-resumes the
1516
+ * turn where the user left off (`resume:true`). `secondsRemaining` ticks down
1517
+ * once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
1518
+ * limit/quota, and signup-required errors never auto-retry.
1519
+ */
1520
+ retryCountdown: {
1521
+ secondsRemaining: number
1522
+ attempt: number
1523
+ } | null
1524
+ /** Update the local mode state (for instant mode toggle without an AI turn). */
1525
+ setMode: (mode: 'plan' | 'execute') => void
1526
+ /** Update the local fast-mode state (for instant toggle without an AI turn). */
1527
+ setFastMode: (fastMode: boolean) => void
1528
+ sendMessage: (
1529
+ message: string,
1530
+ attachments?: ChatAttachment[],
1531
+ options?: SendMessageOptions,
1532
+ ) => Promise<void>
1533
+ abort: () => void
1534
+ /**
1535
+ * Cancel a pending 5XX auto-retry. Clears the countdown and surfaces the
1536
+ * original error (via `error`) so the user sees why the turn failed.
1537
+ */
1538
+ cancelRetry: () => void
1539
+ clearHistory: () => Promise<void>
1540
+ /** Edit the content of a queued (not yet sent) message. */
1541
+ editQueuedMessage: (msgId: string, newContent: string) => void
1542
+ /** Remove a queued (not yet sent) message from the queue. */
1543
+ deleteQueuedMessage: (msgId: string) => void
1544
+ /** Remove queued auto-fix messages whose content references the given file path. */
1545
+ clearQueuedForFile: (filePath: string) => void
1546
+ /**
1547
+ * Append an inline transcript card (model / mode / skills / custom notice) as a
1548
+ * `role:'system'` card-message in the ONE message store. Used by the host (ChatPanel)
1549
+ * to render a TEAMMATE's broadcast `card` event live — this client's OWN cards arrive
1550
+ * through the stream and are appended internally. De-duped by the server-assigned id.
1551
+ */
1552
+ appendCardMessage: (
1553
+ id: string,
1554
+ timestamp: number,
1555
+ card: NonNullable<ChatMessage['cardEvent']>,
1556
+ ) => void
1557
+ /**
1558
+ * Append a COMPLETE, non-streaming chat message (a `message` stream event — e.g.
1559
+ * a teammate's human-only team note) to the ONE message store. Used by the host
1560
+ * (ChatPanel) to render a TEAMMATE's broadcast `message` event live — this
1561
+ * client's OWN `message` events arrive through the stream and are appended
1562
+ * internally. De-duped by the server-assigned message id.
1563
+ */
1564
+ appendCompleteMessage: (message: ChatMessage) => void
1565
+ /**
1566
+ * Ingest ONE pushed (broadcast) stream frame from a turn running elsewhere —
1567
+ * a teammate's send, another tab, a server-side continuation — into the ONE
1568
+ * message store, through the same content applier as an own SSE stream: text/
1569
+ * thinking deltas, tool events, verification, cards, complete messages, done.
1570
+ * The host (ChatPanel) calls this from its push-channel handler for every
1571
+ * broadcast frame of the OPEN conversation. Own echoes are dropped while a
1572
+ * local send is in flight (the SSE stream is authoritative for the sender);
1573
+ * complete id-carrying items (cards, team notes) always apply, de-duped.
1574
+ */
1575
+ applyRemoteEvent: (event: ChatStreamEvent) => void
1576
+ /**
1577
+ * Reload history and converge the local view on the server transcript (and
1578
+ * re-enter a still-streaming turn). The page-lifecycle events run this
1579
+ * automatically; the host should ALSO call it whenever its chat push channel
1580
+ * (re)connects — a broadcast sent while that socket was down (a teammate's
1581
+ * team note against a backgrounded tab or a slept laptop) is otherwise lost
1582
+ * until the next lifecycle event happens to fire. Cheap when nothing changed:
1583
+ * an identical transcript is never re-applied.
1584
+ */
1585
+ reconcileHistory: () => Promise<void>
1586
+ }
1587
+ ```
1588
+
1518
1589
  #### `UseWorkspaceResult`
1519
1590
 
1520
1591
  Hook result for useWorkspace.
@@ -1531,28 +1602,58 @@ interface UseWorkspaceResult {
1531
1602
  }
1532
1603
  ```
1533
1604
 
1534
- #### `WorkspaceProviderProps`
1605
+ #### `UseEditorResult`
1535
1606
 
1536
- Props for workspace provider component.
1607
+ Hook result for useEditor.
1537
1608
 
1538
1609
  ```typescript
1539
- interface WorkspaceProviderProps extends ProviderProps {
1540
- provider: WorkspaceProvider
1610
+ interface UseEditorResult {
1611
+ tabs: EditorTab[]
1612
+ activeFile: string | null
1613
+ openFile: (file: EditorFile) => void
1614
+ closeFile: (path: string) => void
1615
+ getContent: () => string | null
1616
+ setContent: (path: string, content: string) => void
1617
+ setActiveTab: (path: string) => void
1618
+ mount: EditorProvider['mount']
1619
+ dispose: () => void
1620
+ focus: () => void
1621
+ openDiff: (file: DiffFile) => void
1622
+ closeDiff: () => void
1623
+ pinTab: (path: string) => void
1624
+ addExtraLib: (content: string, filePath: string) => void
1625
+ onFixWithAI: (callback: (request: FixWithAIRequest) => void) => () => void
1541
1626
  }
1542
1627
  ```
1543
1628
 
1544
- ### Types
1545
-
1546
- #### `AsyncExtendState`
1629
+ #### `UsePreviewResult`
1547
1630
 
1548
- Async-capable extendState function for partial updates.
1631
+ Hook result for usePreview.
1549
1632
 
1550
1633
  ```typescript
1551
- type AsyncExtendState<T> = (
1552
- partial: Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
1553
- ) => void
1634
+ interface UsePreviewResult {
1635
+ state: PreviewState
1636
+ setUrl: (url: string) => void
1637
+ refresh: () => void
1638
+ setDevice: (device: DeviceFrame) => void
1639
+ openExternal: () => void
1640
+ /**
1641
+ * Records a navigation the running preview reported via its `molecule:navigate`
1642
+ * message — updates the displayed current location without reloading the iframe.
1643
+ * Pass `isReplace` when the preview REPLACED its current history entry (a
1644
+ * `replaceState` redirect/canonicalization) so the forward stack is preserved
1645
+ * instead of truncated (a `pushState`, the default, truncates forward).
1646
+ */
1647
+ recordNavigation: (url: string, isReplace?: boolean) => void
1648
+ /** Navigates the preview to the previous navigation-history entry (Back). */
1649
+ back: () => void
1650
+ /** Navigates the preview to the next navigation-history entry (Forward). */
1651
+ forward: () => void
1652
+ }
1554
1653
  ```
1555
1654
 
1655
+ ### Types
1656
+
1556
1657
  #### `AsyncSetState`
1557
1658
 
1558
1659
  Async-capable setState function.
@@ -1561,6 +1662,18 @@ Async-capable setState function.
1561
1662
  type AsyncSetState<T> = (value: T | ((prev: T) => T) | Promise<T | ((prev: T) => T)>) => void
1562
1663
  ```
1563
1664
 
1665
+ - `value` — The new state value, an updater function receiving previous state, or a Promise resolving to either.
1666
+
1667
+ #### `AsyncExtendState`
1668
+
1669
+ Async-capable extendState function for partial updates.
1670
+
1671
+ ```typescript
1672
+ type AsyncExtendState<T> = (
1673
+ partial: Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
1674
+ ) => void
1675
+ ```
1676
+
1564
1677
  #### `UseCapacitorAppResult`
1565
1678
 
1566
1679
  Hook return type.
@@ -1581,168 +1694,208 @@ type VerifyPaymentReturnStatus = 'idle' | 'verifying' | 'verified' | 'failed'
1581
1694
 
1582
1695
  ### Functions
1583
1696
 
1584
- #### `AuthProvider(props)`
1697
+ #### `useAppState()`
1585
1698
 
1586
- Provider for authentication.
1699
+ Tracks whether the app is in the foreground, background, or inactive.
1700
+
1701
+ Uses React Native's `AppState` API under the hood. Falls back to
1702
+ 'active' on platforms where AppState is unavailable.
1587
1703
 
1588
1704
  ```typescript
1589
- function AuthProvider({
1590
- client,
1591
- children,
1592
- }: AuthProviderProps<T>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1705
+ function useAppState(): UseAppStateResult
1593
1706
  ```
1594
1707
 
1595
- - `props` — Component props (see {@link AuthProviderProps}).
1708
+ **Returns:** Current app state and whether the app is active.
1596
1709
 
1597
- **Returns:** The rendered auth provider element.
1710
+ #### `useBackHandler(handler, options)`
1598
1711
 
1599
- #### `ChatProvider(props)`
1712
+ Registers a handler for the Android hardware back button.
1600
1713
 
1601
- Provider for AI chat.
1714
+ Return `true` from the handler to prevent the default back behavior,
1715
+ or `false` to allow it.
1602
1716
 
1603
1717
  ```typescript
1604
- function ChatProvider({
1605
- provider,
1606
- children,
1607
- }: ChatProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1718
+ function useBackHandler(handler: () => boolean, options?: UseBackHandlerOptions): void
1608
1719
  ```
1609
1720
 
1610
- - `props` — Component props (see {@link ChatProviderProps}).
1721
+ - `handler` — Callback invoked when the hardware back button is pressed.
1722
+ - `options` — Optional configuration.
1611
1723
 
1612
- **Returns:** The rendered chat provider element.
1724
+ #### `useKeyboardHeight()`
1613
1725
 
1614
- #### `EditorProvider(props)`
1726
+ Tracks soft keyboard visibility and height.
1615
1727
 
1616
- Provider for code editor.
1728
+ Uses React Native's `Keyboard` API. Falls back to hidden state
1729
+ on platforms where Keyboard is unavailable.
1617
1730
 
1618
1731
  ```typescript
1619
- function EditorProvider({
1620
- provider,
1621
- children,
1622
- }: EditorProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1732
+ function useKeyboardHeight(): UseKeyboardHeightResult
1623
1733
  ```
1624
1734
 
1625
- - `props` — Component props (see {@link EditorProviderProps}).
1735
+ **Returns:** Current keyboard height and visibility state.
1626
1736
 
1627
- **Returns:** The rendered editor provider element.
1737
+ #### `useSafeArea()`
1628
1738
 
1629
- #### `HttpProvider(props)`
1739
+ Returns the current safe area insets from `react-native-safe-area-context`.
1630
1740
 
1631
- Provider for HTTP client.
1741
+ Must be used within a `SafeAreaProvider`. Falls back to zero insets
1742
+ if the context is unavailable.
1632
1743
 
1633
1744
  ```typescript
1634
- function HttpProvider({
1635
- client,
1636
- children,
1637
- }: HttpProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1745
+ function useSafeArea(): SafeAreaInsets
1638
1746
  ```
1639
1747
 
1640
- - `props` — Component props (see {@link HttpProviderProps}).
1748
+ **Returns:** Safe area insets for the current device.
1641
1749
 
1642
- **Returns:** The rendered HTTP provider element.
1750
+ #### `resetAIModelsCache()`
1643
1751
 
1644
- #### `I18nProvider(props)`
1752
+ Test-only: drops every cached model list so the next `useAIModels` call
1753
+ refetches. Exposed for unit tests; do not call from production code.
1645
1754
 
1646
- Provider for internationalization.
1755
+ ```typescript
1756
+ function resetAIModelsCache(): void
1757
+ ```
1758
+
1759
+ #### `useAIModels(projectId)`
1760
+
1761
+ Subscribes to the cached AI model catalog. The first mount of a scope
1762
+ triggers a single `GET /ai/models` fetch; subsequent mounts return the
1763
+ cached result.
1647
1764
 
1648
1765
  ```typescript
1649
- function I18nProvider({
1650
- provider,
1651
- children,
1652
- }: I18nProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1766
+ function useAIModels(projectId?: string): UseAIModelsResult
1653
1767
  ```
1654
1768
 
1655
- - `props` — Component props (see {@link I18nProviderProps}).
1769
+ - `projectId` — Optional project scope: includes that project's custom ("bring your own AI") models on servers that support them.
1656
1770
 
1657
- **Returns:** The rendered i18n provider element.
1771
+ **Returns:** Models, free-tier model, loading flag, and error.
1658
1772
 
1659
- #### `localOnlyMessages(prev, history)`
1773
+ #### `useAuthClient()`
1660
1774
 
1661
- The messages only the local store holds, given a server history: optimistic
1662
- bubbles and session-local cards, minus the optimistic ECHO of a send the
1663
- server already persisted. A local user message carries a local id
1664
- (`user-N`), the server's copy a server id, so ids never match — content does.
1665
- Without this, the dashboard's first prompt (auto-sent by the workspace,
1666
- then merged back in from history by the remote-stream poll) rendered as two
1667
- identical user bubbles in every new project (2026-09-08).
1775
+ Hook to access the auth client from context.
1668
1776
 
1669
1777
  ```typescript
1670
- function localOnlyMessages(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1778
+ function useAuthClient(): AuthClient<T, Record<never, never>>
1671
1779
  ```
1672
1780
 
1673
- - `prev` — The store's current messages.
1674
- - `history` — The server's history.
1781
+ **Returns:** The auth client from context
1675
1782
 
1676
- **Returns:** The local-only messages to keep after the merged history.
1783
+ #### `useAuth(options)`
1677
1784
 
1678
- #### `LoggerProvider(props)`
1785
+ Hook for authentication state and actions.
1679
1786
 
1680
- Provider for logging.
1787
+ Pass the app's user type — the SAME type used for the auth client and its
1788
+ config (`createJWTAuthClient<MyUser>`, `AuthClientConfig<MyUser>`) — so
1789
+ `user` and `setSession`/`setUser` are typed for the pages:
1790
+ `useAuth<MyUser>()`.
1791
+
1792
+ For a sign-in the app runs itself (an OAuth redirect, a custom endpoint that
1793
+ already issued the token), call `setSession({ accessToken, user })`: it
1794
+ adopts the token and profile atomically and every consumer of this hook sees
1795
+ `status: 'authenticated'` at once. `setUser` alone does not sign in.
1796
+
1797
+ To create an account, use `const { register } = useAuth<MyUser>()` and
1798
+ `await register({ email, password, name })`. Registration returns the auth
1799
+ client's `AuthResult<MyUser>`; there is no separate `useRegister` hook.
1681
1800
 
1682
1801
  ```typescript
1683
- function LoggerProvider({
1684
- provider,
1685
- children,
1686
- }: LoggerProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1802
+ function useAuth(options?: UseAuthOptions): UseAuthResult<T>
1687
1803
  ```
1688
1804
 
1689
- - `props` — Component props (see {@link LoggerProviderProps}).
1805
+ - `options` — Hook options
1690
1806
 
1691
- **Returns:** The rendered logger provider element.
1807
+ **Returns:** Auth state and action methods
1692
1808
 
1693
- #### `MoleculeProvider(props)`
1809
+ #### `useUser()`
1694
1810
 
1695
- Combined provider for all molecule services.
1811
+ Hook to get just the authenticated user.
1696
1812
 
1697
- Provides a convenient way to wrap your app with all molecule providers at once.
1698
- Only providers that are passed will be included.
1813
+ ```typescript
1814
+ function useUser(): T | null
1815
+ ```
1816
+
1817
+ **Returns:** The authenticated user or null
1818
+
1819
+ #### `useIsAuthenticated()`
1820
+
1821
+ Hook to check if user is authenticated.
1699
1822
 
1700
1823
  ```typescript
1701
- function MoleculeProvider({
1702
- children,
1703
- state,
1704
- auth,
1705
- theme,
1706
- router,
1707
- i18n,
1708
- http,
1709
- storage,
1710
- logger,
1711
- chat,
1712
- workspace,
1713
- editor,
1714
- preview,
1715
- }: MoleculeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1824
+ function useIsAuthenticated(): boolean
1716
1825
  ```
1717
1826
 
1718
- - `props` — Component props (see {@link MoleculeProviderProps}) — each service is optional, and ONLY the services passed are provided to the tree.
1827
+ **Returns:** Whether the user is authenticated
1828
+
1829
+ #### `useCapacitorApp(options)`
1830
+
1831
+ Hook for Capacitor app initialization and state management.
1832
+
1833
+ Creates a `CapacitorApp` coordinator on mount, subscribes to state changes,
1834
+ and auto-initializes. Cleans up listeners on unmount via `destroy()`.
1835
+
1836
+ ```typescript
1837
+ function useCapacitorApp(options?: CapacitorAppOptions): UseCapacitorAppResult
1838
+ ```
1839
+
1840
+ - `options` — Capacitor app configuration options
1841
+
1842
+ **Returns:** Current app state and an `initialize` function for manual re-initialization
1843
+
1844
+ #### `useChangePassword()`
1845
+
1846
+ Hook for changing password with async state tracking.
1847
+
1848
+ ```typescript
1849
+ function useChangePassword(): UseChangePasswordReturn
1850
+ ```
1851
+
1852
+ **Returns:** Change password state and action
1719
1853
 
1720
- **Returns:** The rendered combined provider element.
1854
+ #### `convergeHistory(prev, history)`
1721
1855
 
1722
- #### `PreviewProvider(props)`
1856
+ Converge a live store on a fresh server history WITHOUT rewinding anything
1857
+ already on screen. This is the ONE place a server transcript is applied to a
1858
+ local view — the page-lifecycle/push reconcile, the remote-turn poll, the
1859
+ dropped-stream reconcile and the resume poll all go through it, because two
1860
+ paths that almost agree is how a message came to vanish and come back
1861
+ (reported 2026-09-21).
1723
1862
 
1724
- Provider for live preview.
1863
+ Per message id the further-along copy wins ({@link messageProgress}); a TIE
1864
+ keeps the local copy, so an unchanged transcript returns the same object
1865
+ references and a poll neither churns React nor rewinds. Messages only the
1866
+ server has are added in the server's order (filling gaps a watcher missed);
1867
+ messages only the store has ({@link localOnlyMessages} — an answer still
1868
+ carrying its local id, a session-local card, a turn the server has not
1869
+ persisted yet) are kept after them.
1725
1870
 
1726
1871
  ```typescript
1727
- function PreviewProvider({
1728
- provider,
1729
- children,
1730
- }: PreviewProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1872
+ function convergeHistory(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1731
1873
  ```
1732
1874
 
1733
- - `props` — Component props (see {@link PreviewProviderProps}).
1875
+ - `prev` — The store's current messages.
1876
+ - `history` — The messages from the server's history endpoint.
1734
1877
 
1735
- **Returns:** The rendered preview provider element.
1878
+ **Returns:** The converged message list.
1736
1879
 
1737
- #### `resetAIModelsCache()`
1880
+ #### `localOnlyMessages(prev, history)`
1738
1881
 
1739
- Test-only: drops every cached model list so the next `useAIModels` call
1740
- refetches. Exposed for unit tests; do not call from production code.
1882
+ The messages only the local store holds, given a server history: optimistic
1883
+ bubbles and session-local cards, minus the optimistic ECHO of a send the
1884
+ server already persisted. A local user message carries a local id
1885
+ (`user-N`), the server's copy a server id, so ids never match — content does.
1886
+ Without this, the dashboard's first prompt (auto-sent by the workspace,
1887
+ then merged back in from history by the remote-stream poll) rendered as two
1888
+ identical user bubbles in every new project (2026-09-08).
1741
1889
 
1742
1890
  ```typescript
1743
- function resetAIModelsCache(): void
1891
+ function localOnlyMessages(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1744
1892
  ```
1745
1893
 
1894
+ - `prev` — The store's current messages.
1895
+ - `history` — The server's history.
1896
+
1897
+ **Returns:** The local-only messages to keep after the merged history.
1898
+
1746
1899
  #### `resetChatStoresForTests()`
1747
1900
 
1748
1901
  Test-only: clear all conversation stores. The store is module-level (it must
@@ -1753,201 +1906,181 @@ outlive component mounts), so it persists across test cases — reset it in a
1753
1906
  function resetChatStoresForTests(): void
1754
1907
  ```
1755
1908
 
1756
- #### `RouterProvider(props)`
1909
+ #### `useChatProvider()`
1757
1910
 
1758
- Provider for routing.
1911
+ Access the chat provider from context.
1759
1912
 
1760
1913
  ```typescript
1761
- function RouterProvider({
1762
- router,
1763
- children,
1764
- }: RouterProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1914
+ function useChatProvider(): ChatProvider
1765
1915
  ```
1766
1916
 
1767
- - `props` — Component props (see {@link RouterProviderProps}).
1917
+ **Returns:** The ChatProvider instance from the nearest ChatContext.
1768
1918
 
1769
- **Returns:** The rendered router provider element.
1919
+ #### `useChat(options)`
1770
1920
 
1771
- #### `StateProvider(props)`
1921
+ Hook for AI chat with streaming support.
1772
1922
 
1773
- Provider for state management.
1923
+ Manages message state, sends messages to the backend, and handles
1924
+ SSE streaming responses.
1774
1925
 
1775
1926
  ```typescript
1776
- function StateProvider({
1777
- provider,
1778
- children,
1779
- }: StateProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1927
+ function useChat(options: UseChatOptions): UseChatResult
1780
1928
  ```
1781
1929
 
1782
- - `props` — Component props (see {@link StateProviderProps}).
1783
-
1784
- **Returns:** The rendered state provider element.
1785
-
1786
- #### `StorageProvider(props)`
1787
-
1788
- Provider for storage.
1789
-
1790
- ```typescript
1791
- function StorageProvider({
1792
- provider,
1793
- children,
1794
- }: StorageProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1795
- ```
1930
+ - `options` — Chat configuration including endpoint URL, project ID, and whether to load history on mount.
1796
1931
 
1797
- - `props` — Component props (see {@link StorageProviderProps}).
1932
+ **Returns:** Chat state and controls: messages, isLoading, error, sendMessage, abort, and clearHistory.
1798
1933
 
1799
- **Returns:** The rendered storage provider element.
1934
+ #### `useDevice()`
1800
1935
 
1801
- #### `ThemeProvider(props)`
1936
+ Hook for device information.
1802
1937
 
1803
- Provider for theming.
1938
+ Uses module-level `getProvider()` — device info is a singleton, not context-provided.
1939
+ Device info is static and doesn't change at runtime, so this uses `useMemo`.
1804
1940
 
1805
1941
  ```typescript
1806
- function ThemeProvider({
1807
- provider,
1808
- children,
1809
- }: ThemeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1942
+ function useDevice(): UseDeviceResult
1810
1943
  ```
1811
1944
 
1812
- - `props` — Component props (see {@link ThemeProviderProps}).
1813
-
1814
- **Returns:** The rendered theme provider element.
1945
+ **Returns:** Device information and utility methods
1815
1946
 
1816
- #### `useAIModels(projectId)`
1947
+ #### `useEditorProvider()`
1817
1948
 
1818
- Subscribes to the cached AI model catalog. The first mount of a scope
1819
- triggers a single `GET /ai/models` fetch; subsequent mounts return the
1820
- cached result.
1949
+ Access the editor provider from context.
1821
1950
 
1822
1951
  ```typescript
1823
- function useAIModels(projectId?: string): UseAIModelsResult
1952
+ function useEditorProvider(): EditorProvider
1824
1953
  ```
1825
1954
 
1826
- - `projectId` — Optional project scope: includes that project's custom ("bring your own AI") models on servers that support them.
1827
-
1828
- **Returns:** Models, free-tier model, loading flag, and error.
1829
-
1830
- #### `useAppState()`
1955
+ **Returns:** The EditorProvider instance from the nearest EditorContext.
1831
1956
 
1832
- Tracks whether the app is in the foreground, background, or inactive.
1957
+ #### `useEditor()`
1833
1958
 
1834
- Uses React Native's `AppState` API under the hood. Falls back to
1835
- 'active' on platforms where AppState is unavailable.
1959
+ Hook for code editor management.
1836
1960
 
1837
1961
  ```typescript
1838
- function useAppState(): UseAppStateResult
1962
+ function useEditor(): UseEditorResult
1839
1963
  ```
1840
1964
 
1841
- **Returns:** Current app state and whether the app is active.
1965
+ **Returns:** Editor state and controls: tabs, activeFile, openFile, closeFile, getContent, setContent, setActiveTab, mount, dispose, and focus.
1842
1966
 
1843
- #### `useAuth(options)`
1967
+ #### `useForm(options)`
1844
1968
 
1845
- Hook for authentication state and actions.
1969
+ Hook for form state management.
1846
1970
 
1847
1971
  ```typescript
1848
- function useAuth(options?: UseAuthOptions): UseAuthResult<T>
1972
+ function useForm(options: UseFormOptions<T>): UseFormResult<T>
1849
1973
  ```
1850
1974
 
1851
- - `options` — Hook options
1975
+ - `options` — Form options including createForm from a forms provider
1852
1976
 
1853
- **Returns:** Auth state and action methods
1977
+ **Returns:** Form state and methods
1854
1978
 
1855
- #### `useAuthClient()`
1979
+ #### `useWatch(form, name)`
1856
1980
 
1857
- Hook to access the auth client from context.
1981
+ Hook to watch a specific field value.
1858
1982
 
1859
1983
  ```typescript
1860
- function useAuthClient(): AuthClient<T>
1984
+ function useWatch(form: FormController<T>, name: K): T[K]
1861
1985
  ```
1862
1986
 
1863
- **Returns:** The auth client from context
1987
+ - `form` — Form controller
1988
+ - `name` — Field name to watch
1864
1989
 
1865
- #### `useBackHandler(handler, options)`
1990
+ **Returns:** Current field value
1866
1991
 
1867
- Registers a handler for the Android hardware back button.
1992
+ #### `useFieldState(form, name)`
1868
1993
 
1869
- Return `true` from the handler to prevent the default back behavior,
1870
- or `false` to allow it.
1994
+ Hook to get field-level state.
1871
1995
 
1872
1996
  ```typescript
1873
- function useBackHandler(handler: () => boolean, options?: UseBackHandlerOptions): void
1997
+ function useFieldState(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>
1874
1998
  ```
1875
1999
 
1876
- - `handler` — Callback invoked when the hardware back button is pressed.
1877
- - `options` — Optional configuration.
2000
+ - `form` — Form controller
2001
+ - `name` — Field name
1878
2002
 
1879
- #### `useCapacitorApp(options)`
2003
+ **Returns:** Field state (value, error, touched, dirty, valid)
1880
2004
 
1881
- Hook for Capacitor app initialization and state management.
2005
+ #### `useHttpClient()`
1882
2006
 
1883
- Creates a `CapacitorApp` coordinator on mount, subscribes to state changes,
1884
- and auto-initializes. Cleans up listeners on unmount via `destroy()`.
2007
+ Hook to access the HTTP client from context.
1885
2008
 
1886
2009
  ```typescript
1887
- function useCapacitorApp(options?: CapacitorAppOptions): UseCapacitorAppResult
2010
+ function useHttpClient(): HttpClient
1888
2011
  ```
1889
2012
 
1890
- - `options` — Capacitor app configuration options
1891
-
1892
- **Returns:** Current app state and an `initialize` function for manual re-initialization
2013
+ **Returns:** The HTTP client from context
1893
2014
 
1894
- #### `useChangePassword()`
2015
+ #### `useHttp(method, url, options)`
1895
2016
 
1896
- Hook for changing password with async state tracking.
2017
+ Hook for making HTTP requests with state management.
1897
2018
 
1898
2019
  ```typescript
1899
- function useChangePassword(): UseChangePasswordReturn
2020
+ function useHttp(
2021
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
2022
+ url: string,
2023
+ options?: UseHttpOptions<T>,
2024
+ ): UseHttpResult<T>
1900
2025
  ```
1901
2026
 
1902
- **Returns:** Change password state and action
2027
+ - `method` — HTTP method
2028
+ - `url` — Request URL
2029
+ - `options` — Request options
1903
2030
 
1904
- #### `useChat(options)`
2031
+ **Returns:** Request state and execute function
1905
2032
 
1906
- Hook for AI chat with streaming support.
2033
+ #### `useGet(url, options)`
1907
2034
 
1908
- Manages message state, sends messages to the backend, and handles
1909
- SSE streaming responses.
2035
+ Hook for GET requests.
1910
2036
 
1911
2037
  ```typescript
1912
- function useChat(options: UseChatOptions): UseChatResult
2038
+ function useGet(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1913
2039
  ```
1914
2040
 
1915
- - `options` — Chat configuration including endpoint URL, project ID, and whether to load history on mount.
2041
+ - `url` — Request URL to fetch from.
2042
+ - `options` — HTTP request options including callbacks and request config.
1916
2043
 
1917
- **Returns:** Chat state and controls: messages, isLoading, error, sendMessage, abort, and clearHistory.
2044
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1918
2045
 
1919
- #### `useChatProvider()`
2046
+ #### `usePost(url, options)`
1920
2047
 
1921
- Access the chat provider from context.
2048
+ Hook for POST requests.
1922
2049
 
1923
2050
  ```typescript
1924
- function useChatProvider(): ChatProvider
2051
+ function usePost(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1925
2052
  ```
1926
2053
 
1927
- **Returns:** The ChatProvider instance from the nearest ChatContext.
2054
+ - `url` — Request URL to post to.
2055
+ - `options` — HTTP request options including body data and callbacks.
1928
2056
 
1929
- #### `useChildLogger(parentName, context)`
2057
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1930
2058
 
1931
- Hook to create a child logger with additional context.
2059
+ #### `usePut(url, options)`
2060
+
2061
+ Hook for PUT requests.
1932
2062
 
1933
2063
  ```typescript
1934
- function useChildLogger(parentName: string, context: Record<string, unknown>): Logger
2064
+ function usePut(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1935
2065
  ```
1936
2066
 
1937
- - `parentName` — Parent logger name
1938
- - `context` — Additional context to include in logs
2067
+ - `url` — Request URL to send the PUT request to.
2068
+ - `options` — HTTP request options including body data and callbacks.
1939
2069
 
1940
- **Returns:** Child logger instance
2070
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1941
2071
 
1942
- #### `useCurrentTheme()`
2072
+ #### `usePatch(url, options)`
1943
2073
 
1944
- Hook to get just the current theme object.
2074
+ Hook for PATCH requests.
1945
2075
 
1946
2076
  ```typescript
1947
- function useCurrentTheme(): Theme
2077
+ function usePatch(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1948
2078
  ```
1949
2079
 
1950
- **Returns:** The current theme
2080
+ - `url` — Request URL to send the PATCH request to.
2081
+ - `options` — HTTP request options including partial body data and callbacks.
2082
+
2083
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1951
2084
 
1952
2085
  #### `useDelete(url, options)`
1953
2086
 
@@ -1962,189 +2095,175 @@ function useDelete(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1962
2095
 
1963
2096
  **Returns:** Request state (data, loading, error) and controls (execute, reset).
1964
2097
 
1965
- #### `useDevice()`
1966
-
1967
- Hook for device information.
1968
-
1969
- Uses module-level `getProvider()` — device info is a singleton, not context-provided.
1970
- Device info is static and doesn't change at runtime, so this uses `useMemo`.
1971
-
1972
- ```typescript
1973
- function useDevice(): UseDeviceResult
1974
- ```
1975
-
1976
- **Returns:** Device information and utility methods
1977
-
1978
- #### `useDirection()`
2098
+ #### `useLoggerProvider()`
1979
2099
 
1980
- Hook to get the text direction.
2100
+ Hook to access the logger provider from context.
1981
2101
 
1982
2102
  ```typescript
1983
- function useDirection(): 'ltr' | 'rtl'
2103
+ function useLoggerProvider(): LoggerProvider
1984
2104
  ```
1985
2105
 
1986
- **Returns:** The text direction ('ltr' or 'rtl')
2106
+ **Returns:** The logger provider from context
1987
2107
 
1988
- #### `useEditor()`
2108
+ #### `useLogger(name, config)`
1989
2109
 
1990
- Hook for code editor management.
2110
+ Hook to get a logger instance.
1991
2111
 
1992
2112
  ```typescript
1993
- function useEditor(): UseEditorResult
2113
+ function useLogger(name: string, config?: Partial<LoggerConfig>): Logger
1994
2114
  ```
1995
2115
 
1996
- **Returns:** Editor state and controls: tabs, activeFile, openFile, closeFile, getContent, setContent, setActiveTab, mount, dispose, and focus.
1997
-
1998
- #### `useEditorProvider()`
1999
-
2000
- Access the editor provider from context.
2001
-
2002
- ```typescript
2003
- function useEditorProvider(): EditorProvider
2004
- ```
2116
+ - `name` — Logger name (usually component or module name)
2117
+ - `config` — Optional logger configuration
2005
2118
 
2006
- **Returns:** The EditorProvider instance from the nearest EditorContext.
2119
+ **Returns:** Logger instance
2007
2120
 
2008
- #### `useFieldState(form, name)`
2121
+ #### `useRootLogger()`
2009
2122
 
2010
- Hook to get field-level state.
2123
+ Hook to get the root logger.
2011
2124
 
2012
2125
  ```typescript
2013
- function useFieldState(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>
2126
+ function useRootLogger(): Logger
2014
2127
  ```
2015
2128
 
2016
- - `form` — Form controller
2017
- - `name` — Field name
2018
-
2019
- **Returns:** Field state (value, error, touched, dirty, valid)
2129
+ **Returns:** Root logger instance
2020
2130
 
2021
- #### `useForm(options)`
2131
+ #### `useChildLogger(parentName, context)`
2022
2132
 
2023
- Hook for form state management.
2133
+ Hook to create a child logger with additional context.
2024
2134
 
2025
2135
  ```typescript
2026
- function useForm(options: UseFormOptions<T>): UseFormResult<T>
2136
+ function useChildLogger(parentName: string, context: Record<string, unknown>): Logger
2027
2137
  ```
2028
2138
 
2029
- - `options` — Form options including createForm from a forms provider
2139
+ - `parentName` — Parent logger name
2140
+ - `context` — Additional context to include in logs
2030
2141
 
2031
- **Returns:** Form state and methods
2142
+ **Returns:** Child logger instance
2032
2143
 
2033
- #### `useGet(url, options)`
2144
+ #### `useLogin()`
2034
2145
 
2035
- Hook for GET requests.
2146
+ Hook for login with async state tracking.
2147
+ Registration is available through `const { register } = useAuth()`;
2148
+ call `register({ email, password, name })` to create an account. There is
2149
+ no separate `useRegister` hook. Use `usePromise(register)` when the form
2150
+ needs the same pending/error tracking as this login hook.
2036
2151
 
2037
2152
  ```typescript
2038
- function useGet(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2153
+ function useLogin(): UseLoginReturn<T>
2039
2154
  ```
2040
2155
 
2041
- - `url` — Request URL to fetch from.
2042
- - `options` — HTTP request options including callbacks and request config.
2156
+ **Returns:** Login state and action
2043
2157
 
2044
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2158
+ #### `useOAuth(config)`
2045
2159
 
2046
- #### `useHttp(method, url, options)`
2160
+ Hook for OAuth authentication.
2047
2161
 
2048
- Hook for making HTTP requests with state management.
2162
+ Reads OAuth configuration from the provided config and provides
2163
+ helpers to build OAuth URLs and start a login (full-page or popup).
2164
+ Automatically handles OAuth callbacks by detecting `code` and `state`
2165
+ URL parameters and exchanging them for a session — and, when the callback is
2166
+ running inside a popup we opened, relaying the result to the opener instead.
2049
2167
 
2050
2168
  ```typescript
2051
- function useHttp(
2052
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
2053
- url: string,
2054
- options?: UseHttpOptions<T>,
2055
- ): UseHttpResult<T>
2169
+ function useOAuth(config?: {
2170
+ baseURL?: string
2171
+ oauthProviders?: string[]
2172
+ oauthEndpoint?: string
2173
+ loginEndpoint?: string
2174
+ onSuccess?: () => void
2175
+ onError?: (error: string) => void
2176
+ }): UseOAuthReturn
2056
2177
  ```
2057
2178
 
2058
- - `method` — HTTP method
2059
- - `url` — Request URL
2060
- - `options` — Request options
2179
+ - `config` — Optional OAuth configuration override.
2180
+ - `config.baseURL` — Base URL for the API server (e.g. "https://api.example.com").
2181
+ - `config.oauthProviders` — List of supported OAuth provider names (e.g. ["google", "github"]).
2182
+ - `config.oauthEndpoint` — Path prefix for OAuth routes (defaults to "/oauth").
2183
+ - `config.loginEndpoint` — Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
2184
+ - `config.onSuccess` — Callback after successful OAuth login.
2185
+ - `config.onError` — Callback on OAuth login failure.
2061
2186
 
2062
- **Returns:** Request state and execute function
2187
+ **Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
2063
2188
 
2064
- #### `useHttpClient()`
2189
+ #### `usePasswordReset()`
2065
2190
 
2066
- Hook to access the HTTP client from context.
2191
+ Hook for password reset flow with async state tracking.
2192
+
2193
+ Provides separate tracking for the request and confirm steps.
2067
2194
 
2068
2195
  ```typescript
2069
- function useHttpClient(): HttpClient
2196
+ function usePasswordReset(): UsePasswordResetReturn
2070
2197
  ```
2071
2198
 
2072
- **Returns:** The HTTP client from context
2199
+ **Returns:** Password reset state and actions
2073
2200
 
2074
- #### `useI18nError(error)`
2201
+ #### `usePlatform()`
2075
2202
 
2076
- Translates an error at render time so the displayed message updates automatically
2077
- when the locale changes.
2203
+ Hook for platform detection.
2078
2204
 
2079
- **Always use this hook to display errors in React components** — accessing
2080
- `error.message` directly bypasses re-translation and leaves stale text after a
2081
- locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
2082
- its key is translated using the current locale. For plain `Error` instances,
2083
- `error.message` is returned unchanged.
2205
+ Uses module-level functions — platform is a singleton, not context-provided.
2206
+ Platform info is static and doesn't change at runtime, so this uses `useMemo`.
2084
2207
 
2085
2208
  ```typescript
2086
- function useI18nError(error: Error | null | undefined): string | null
2209
+ function usePlatform(): UsePlatformResult
2087
2210
  ```
2088
2211
 
2089
- - `error` — The error to translate, or `null`/`undefined`.
2090
-
2091
- **Returns:** The translated error string, or `null` if no error.
2212
+ **Returns:** Platform information and utility methods
2092
2213
 
2093
- #### `useI18nProvider()`
2214
+ #### `usePreviewProvider()`
2094
2215
 
2095
- Hook to access the i18n provider from context.
2216
+ Access the preview provider from context.
2096
2217
 
2097
2218
  ```typescript
2098
- function useI18nProvider(): I18nProvider
2219
+ function usePreviewProvider(): PreviewProvider
2099
2220
  ```
2100
2221
 
2101
- **Returns:** The i18n provider from context
2222
+ **Returns:** The PreviewProvider instance from the nearest PreviewContext.
2102
2223
 
2103
- #### `useIsActive(path, exact)`
2224
+ #### `usePreview()`
2104
2225
 
2105
- Hook to check if a path is active.
2226
+ Hook for live preview management.
2106
2227
 
2107
2228
  ```typescript
2108
- function useIsActive(path: string, exact?: boolean): boolean
2229
+ function usePreview(): UsePreviewResult
2109
2230
  ```
2110
2231
 
2111
- - `path` — The path to check
2112
- - `exact` — Whether to match exactly (default: false)
2232
+ **Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
2113
2233
 
2114
- **Returns:** Whether the path is active
2234
+ #### `usePush(options)`
2115
2235
 
2116
- #### `useIsAuthenticated()`
2236
+ Hook for push notification state and actions.
2117
2237
 
2118
- Hook to check if user is authenticated.
2238
+ Uses module-level `getProvider()` — push is a singleton, not context-provided.
2119
2239
 
2120
2240
  ```typescript
2121
- function useIsAuthenticated(): boolean
2241
+ function usePush(options?: UsePushOptions): UsePushResult
2122
2242
  ```
2123
2243
 
2124
- **Returns:** Whether the user is authenticated
2244
+ - `options` — Hook options
2125
2245
 
2126
- #### `useKeyboardHeight()`
2246
+ **Returns:** Push notification state and action methods
2127
2247
 
2128
- Tracks soft keyboard visibility and height.
2248
+ #### `useRouterInstance()`
2129
2249
 
2130
- Uses React Native's `Keyboard` API. Falls back to hidden state
2131
- on platforms where Keyboard is unavailable.
2250
+ Hook to access the router from context.
2132
2251
 
2133
2252
  ```typescript
2134
- function useKeyboardHeight(): UseKeyboardHeightResult
2253
+ function useRouterInstance(): Router
2135
2254
  ```
2136
2255
 
2137
- **Returns:** Current keyboard height and visibility state.
2256
+ **Returns:** The router from context
2138
2257
 
2139
- #### `useLocale()`
2258
+ #### `useRouter()`
2140
2259
 
2141
- Hook to get the current locale.
2260
+ Hook for routing state and actions.
2142
2261
 
2143
2262
  ```typescript
2144
- function useLocale(): string
2263
+ function useRouter(): UseRouterResult
2145
2264
  ```
2146
2265
 
2147
- **Returns:** The current locale code
2266
+ **Returns:** Router state and navigation methods
2148
2267
 
2149
2268
  #### `useLocation()`
2150
2269
 
@@ -2156,520 +2275,574 @@ function useLocation(): RouteLocation
2156
2275
 
2157
2276
  **Returns:** The current route location
2158
2277
 
2159
- #### `useLogger(name, config)`
2278
+ #### `useParams()`
2160
2279
 
2161
- Hook to get a logger instance.
2280
+ Hook to get route parameters.
2162
2281
 
2163
2282
  ```typescript
2164
- function useLogger(name: string, config?: Partial<LoggerConfig>): Logger
2283
+ function useParams(): T
2165
2284
  ```
2166
2285
 
2167
- - `name` — Logger name (usually component or module name)
2168
- - `config` — Optional logger configuration
2169
-
2170
- **Returns:** Logger instance
2286
+ **Returns:** The current route parameters
2171
2287
 
2172
- #### `useLoggerProvider()`
2288
+ #### `useQuery()`
2173
2289
 
2174
- Hook to access the logger provider from context.
2290
+ Hook to get query parameters.
2175
2291
 
2176
2292
  ```typescript
2177
- function useLoggerProvider(): LoggerProvider
2293
+ function useQuery(): T
2178
2294
  ```
2179
2295
 
2180
- **Returns:** The logger provider from context
2296
+ **Returns:** The current query parameters
2181
2297
 
2182
- #### `useLogin()`
2298
+ #### `useNavigate()`
2183
2299
 
2184
- Hook for login with async state tracking.
2300
+ Hook to get the navigate function.
2185
2301
 
2186
2302
  ```typescript
2187
- function useLogin(): UseLoginReturn<T>
2303
+ function useNavigate(): (path: string, options?: NavigateOptions) => void
2188
2304
  ```
2189
2305
 
2190
- **Returns:** Login state and action
2306
+ **Returns:** The navigate function
2191
2307
 
2192
- #### `useNavigate()`
2308
+ #### `useIsActive(path, exact)`
2193
2309
 
2194
- Hook to get the navigate function.
2310
+ Hook to check if a path is active.
2195
2311
 
2196
2312
  ```typescript
2197
- function useNavigate(): (path: string, options?: NavigateOptions) => void
2313
+ function useIsActive(path: string, exact?: boolean): boolean
2198
2314
  ```
2199
2315
 
2200
- **Returns:** The navigate function
2316
+ - `path` — The path to check
2317
+ - `exact` — Whether to match exactly (default: false)
2201
2318
 
2202
- #### `useOAuth(config)`
2319
+ **Returns:** Whether the path is active
2203
2320
 
2204
- Hook for OAuth authentication.
2321
+ #### `useSignup()`
2205
2322
 
2206
- Reads OAuth configuration from the provided config and provides
2207
- helpers to build OAuth URLs and start a login (full-page or popup).
2208
- Automatically handles OAuth callbacks by detecting `code` and `state`
2209
- URL parameters and exchanging them for a session — and, when the callback is
2210
- running inside a popup we opened, relaying the result to the opener instead.
2323
+ Hook for user registration with async state tracking.
2211
2324
 
2212
2325
  ```typescript
2213
- function useOAuth(config?: {
2214
- baseURL?: string
2215
- oauthProviders?: string[]
2216
- oauthEndpoint?: string
2217
- loginEndpoint?: string
2218
- onSuccess?: () => void
2219
- onError?: (error: string) => void
2220
- }): UseOAuthReturn
2326
+ function useSignup(): UseSignupReturn<T>
2221
2327
  ```
2222
2328
 
2223
- - `config` — Optional OAuth configuration override.
2224
- - `config.baseURL` — Base URL for the API server (e.g. "https://api.example.com").
2225
- - `config.oauthProviders` — List of supported OAuth provider names (e.g. ["google", "github"]).
2226
- - `config.oauthEndpoint` — Path prefix for OAuth routes (defaults to "/oauth").
2227
- - `config.loginEndpoint` — Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
2228
- - `config.onSuccess` — Callback after successful OAuth login.
2229
- - `config.onError` — Callback on OAuth login failure.
2329
+ **Returns:** Signup state and action
2230
2330
 
2231
- **Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
2331
+ #### `useStorageProvider()`
2232
2332
 
2233
- #### `useParams()`
2333
+ Hook to access the storage provider from context.
2234
2334
 
2235
- Hook to get route parameters.
2335
+ ```typescript
2336
+ function useStorageProvider(): StorageProvider
2337
+ ```
2338
+
2339
+ **Returns:** The storage provider from context
2340
+
2341
+ #### `useStorageValue(key, options)`
2342
+
2343
+ Hook to manage a single storage value with React state sync.
2236
2344
 
2237
2345
  ```typescript
2238
- function useParams(): T
2346
+ function useStorageValue(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>
2239
2347
  ```
2240
2348
 
2241
- **Returns:** The current route parameters
2349
+ - `key` — Storage key
2350
+ - `options` — Hook options
2242
2351
 
2243
- #### `usePasswordReset()`
2352
+ **Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
2244
2353
 
2245
- Hook for password reset flow with async state tracking.
2354
+ #### `useStorage()`
2246
2355
 
2247
- Provides separate tracking for the request and confirm steps.
2356
+ Hook for simple storage operations without React state sync.
2248
2357
 
2249
2358
  ```typescript
2250
- function usePasswordReset(): UsePasswordResetReturn
2359
+ function useStorage(): {
2360
+ get: <T>(key: string) => Promise<T | null>
2361
+ set: <T>(key: string, value: T) => Promise<void>
2362
+ remove: (key: string) => Promise<void>
2363
+ clear: () => Promise<void>
2364
+ keys: () => Promise<string[]>
2365
+ }
2251
2366
  ```
2252
2367
 
2253
- **Returns:** Password reset state and actions
2368
+ **Returns:** Storage operation methods
2254
2369
 
2255
- #### `usePatch(url, options)`
2370
+ #### `useStateProvider()`
2256
2371
 
2257
- Hook for PATCH requests.
2372
+ Hook to access the state provider from context.
2373
+
2374
+ The context comes from `<StateProvider provider={…}>` or from
2375
+ `<MoleculeProvider>` — which supplies the provider bonded under
2376
+ `@molecule/app-state` by default, so a scaffolded app needs no `state` prop.
2377
+
2378
+ Only hooks that read the context call this; `useStore(store)` takes its store
2379
+ as an argument and works with no provider at all.
2258
2380
 
2259
2381
  ```typescript
2260
- function usePatch(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2382
+ function useStateProvider(): StateProvider
2261
2383
  ```
2262
2384
 
2263
- - `url` — Request URL to send the PATCH request to.
2264
- - `options` — HTTP request options including partial body data and callbacks.
2385
+ **Returns:** The state provider from context
2386
+
2387
+ #### `useStore(store, options)`
2388
+
2389
+ Hook to subscribe to a store with optional selector and equality function.
2390
+
2391
+ The store is the argument, so this hook needs NO `StateProvider`: it reads
2392
+ `store.getState()` and subscribes with `store.subscribe()`, and never touches
2393
+ the state context. A store minted outside the `state` bond — the direct
2394
+ `createStoreWithActions()` / `createStore()` a provider package exports — is
2395
+ therefore as valid here as one `@molecule/app-state`'s `createStore()` made.
2396
+
2397
+ ```typescript
2398
+ function useStore(store: Store<T>, options?: UseStoreOptions<T, S>): S
2399
+ ```
2265
2400
 
2266
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2401
+ - `store` — The store to subscribe to
2402
+ - `options` — Hook options (selector, equalityFn)
2267
2403
 
2268
- #### `usePlatform()`
2404
+ **Returns:** The selected state
2269
2405
 
2270
- Hook for platform detection.
2406
+ #### `useSetStore(store)`
2271
2407
 
2272
- Uses module-level functions — platform is a singleton, not context-provided.
2273
- Platform info is static and doesn't change at runtime, so this uses `useMemo`.
2408
+ Hook to get the store's setState function.
2274
2409
 
2275
2410
  ```typescript
2276
- function usePlatform(): UsePlatformResult
2411
+ function useSetStore(store: Store<T>): (partial: Partial<T> | ((state: T) => Partial<T>)) => void
2277
2412
  ```
2278
2413
 
2279
- **Returns:** Platform information and utility methods
2414
+ - `store` — The store to get setState from
2280
2415
 
2281
- #### `usePost(url, options)`
2416
+ **Returns:** The setState function
2282
2417
 
2283
- Hook for POST requests.
2418
+ #### `useStoreAction(store, action)`
2419
+
2420
+ Hook to create a bound action for a store.
2284
2421
 
2285
2422
  ```typescript
2286
- function usePost(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2423
+ function useStoreAction(
2424
+ store: Store<T>,
2425
+ action: (setState: Store<T>['setState'], getState: Store<T>['getState']) => (...args: Args) => R,
2426
+ ): (...args: Args) => R
2287
2427
  ```
2288
2428
 
2289
- - `url` — Request URL to post to.
2290
- - `options` — HTTP request options including body data and callbacks.
2429
+ - `store` — The store to bind to
2430
+ - `action` — The action function that receives setState and getState
2291
2431
 
2292
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2432
+ **Returns:** A bound action function
2293
2433
 
2294
- #### `usePreview()`
2434
+ #### `useThemeProvider()`
2295
2435
 
2296
- Hook for live preview management.
2436
+ Hook to access the theme provider from context.
2297
2437
 
2298
2438
  ```typescript
2299
- function usePreview(): UsePreviewResult
2439
+ function useThemeProvider(): ThemeProvider
2300
2440
  ```
2301
2441
 
2302
- **Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
2442
+ **Returns:** The theme provider from context
2303
2443
 
2304
- #### `usePreviewProvider()`
2444
+ #### `useTheme()`
2305
2445
 
2306
- Access the preview provider from context.
2446
+ Hook for theme state and actions.
2307
2447
 
2308
2448
  ```typescript
2309
- function usePreviewProvider(): PreviewProvider
2449
+ function useTheme(): UseThemeResult
2310
2450
  ```
2311
2451
 
2312
- **Returns:** The PreviewProvider instance from the nearest PreviewContext.
2313
-
2314
- #### `usePush(options)`
2452
+ **Returns:** Theme state and actions
2315
2453
 
2316
- Hook for push notification state and actions.
2454
+ #### `useCurrentTheme()`
2317
2455
 
2318
- Uses module-level `getProvider()` — push is a singleton, not context-provided.
2456
+ Hook to get just the current theme object.
2319
2457
 
2320
2458
  ```typescript
2321
- function usePush(options?: UsePushOptions): UsePushResult
2459
+ function useCurrentTheme(): Theme
2322
2460
  ```
2323
2461
 
2324
- - `options` — Hook options
2325
-
2326
- **Returns:** Push notification state and action methods
2462
+ **Returns:** The current theme
2327
2463
 
2328
- #### `usePut(url, options)`
2464
+ #### `useThemeMode()`
2329
2465
 
2330
- Hook for PUT requests.
2466
+ Hook to get just the theme mode (light/dark).
2331
2467
 
2332
2468
  ```typescript
2333
- function usePut(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2469
+ function useThemeMode(): 'light' | 'dark'
2334
2470
  ```
2335
2471
 
2336
- - `url` — Request URL to send the PUT request to.
2337
- - `options` — HTTP request options including body data and callbacks.
2338
-
2339
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2472
+ **Returns:** The current theme mode
2340
2473
 
2341
- #### `useQuery()`
2474
+ #### `useThemeColors()`
2342
2475
 
2343
- Hook to get query parameters.
2476
+ Hook to get theme colors.
2344
2477
 
2345
2478
  ```typescript
2346
- function useQuery(): T
2479
+ function useThemeColors(): ThemeColors
2347
2480
  ```
2348
2481
 
2349
- **Returns:** The current query parameters
2482
+ **Returns:** The current theme colors
2350
2483
 
2351
- #### `useRootLogger()`
2484
+ #### `useI18nProvider()`
2352
2485
 
2353
- Hook to get the root logger.
2486
+ Hook to access the i18n provider from context.
2354
2487
 
2355
2488
  ```typescript
2356
- function useRootLogger(): Logger
2489
+ function useI18nProvider(): I18nProvider
2357
2490
  ```
2358
2491
 
2359
- **Returns:** Root logger instance
2492
+ **Returns:** The i18n provider from context
2360
2493
 
2361
- #### `useRouter()`
2494
+ #### `useTranslation()`
2362
2495
 
2363
- Hook for routing state and actions.
2496
+ Hook for internationalization.
2364
2497
 
2365
2498
  ```typescript
2366
- function useRouter(): UseRouterResult
2499
+ function useTranslation(): UseTranslationResult
2367
2500
  ```
2368
2501
 
2369
- **Returns:** Router state and navigation methods
2502
+ **Returns:** Translation function and locale management
2370
2503
 
2371
- #### `useRouterInstance()`
2504
+ #### `useT()`
2372
2505
 
2373
- Hook to access the router from context.
2506
+ Hook to get just the translation function.
2374
2507
 
2375
2508
  ```typescript
2376
- function useRouterInstance(): Router
2509
+ function useT(): (
2510
+ key: string,
2511
+ values?: InterpolationValues,
2512
+ options?: { defaultValue?: string; count?: number },
2513
+ ) => string
2377
2514
  ```
2378
2515
 
2379
- **Returns:** The router from context
2380
-
2381
- #### `useSafeArea()`
2516
+ **Returns:** The translation function
2382
2517
 
2383
- Returns the current safe area insets from `react-native-safe-area-context`.
2518
+ #### `useLocale()`
2384
2519
 
2385
- Must be used within a `SafeAreaProvider`. Falls back to zero insets
2386
- if the context is unavailable.
2520
+ Hook to get the current locale.
2387
2521
 
2388
2522
  ```typescript
2389
- function useSafeArea(): SafeAreaInsets
2523
+ function useLocale(): string
2390
2524
  ```
2391
2525
 
2392
- **Returns:** Safe area insets for the current device.
2526
+ **Returns:** The current locale code
2393
2527
 
2394
- #### `useSetStore(store)`
2528
+ #### `useDirection()`
2395
2529
 
2396
- Hook to get the store's setState function.
2530
+ Hook to get the text direction.
2397
2531
 
2398
2532
  ```typescript
2399
- function useSetStore(store: Store<T>): (partial: Partial<T> | ((state: T) => Partial<T>)) => void
2533
+ function useDirection(): 'ltr' | 'rtl'
2400
2534
  ```
2401
2535
 
2402
- - `store` — The store to get setState from
2536
+ **Returns:** The text direction ('ltr' or 'rtl')
2403
2537
 
2404
- **Returns:** The setState function
2538
+ #### `useI18nError(error)`
2405
2539
 
2406
- #### `useSignup()`
2540
+ Translates an error at render time so the displayed message updates automatically
2541
+ when the locale changes.
2407
2542
 
2408
- Hook for user registration with async state tracking.
2543
+ **Always use this hook to display errors in React components** — accessing
2544
+ `error.message` directly bypasses re-translation and leaves stale text after a
2545
+ locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
2546
+ its key is translated using the current locale. For plain `Error` instances,
2547
+ `error.message` is returned unchanged.
2409
2548
 
2410
2549
  ```typescript
2411
- function useSignup(): UseSignupReturn<T>
2550
+ function useI18nError(error: Error | null | undefined): string | null
2412
2551
  ```
2413
2552
 
2414
- **Returns:** Signup state and action
2415
-
2416
- #### `useStateProvider()`
2553
+ - `error` — The error to translate, or `null`/`undefined`.
2417
2554
 
2418
- Hook to access the state provider from context.
2555
+ **Returns:** The translated error string, or `null` if no error.
2419
2556
 
2420
- ```typescript
2421
- function useStateProvider(): StateProvider
2422
- ```
2557
+ #### `useVerifyPaymentReturn(options)`
2423
2558
 
2424
- **Returns:** The state provider from context
2559
+ Reads the payment id a provider put in the return URL and confirms the
2560
+ purchase server-side with `POST /users/:id/verify-payment/:provider`.
2425
2561
 
2426
- #### `useStorage()`
2562
+ **This is why a hosted checkout returns the buyer to the APP and not the
2563
+ API.** Session cookies are host-only on the app's origin, so a top-level
2564
+ redirect from the provider straight to an authenticated API callback on a
2565
+ different host arrives with NO credentials — it answers 401 and the paid plan
2566
+ is never granted. The request this hook makes is a same-origin call from a
2567
+ loaded app page, so the credentials apply. It waits for auth to hydrate
2568
+ first: after the redirect the page is a cold load, and the session is
2569
+ restored from the httpOnly cookie via `GET /users/me`.
2427
2570
 
2428
- Hook for simple storage operations without React state sync.
2571
+ Verification is idempotent server-side (first-claim-wins on the transaction),
2572
+ and this hook additionally runs at most once per transaction id per page.
2573
+ Safe on pages that are also reached normally: with no id in the URL it stays
2574
+ `idle` and issues no request.
2429
2575
 
2430
2576
  ```typescript
2431
- function useStorage(): {
2432
- get: <T>(key: string) => Promise<T | null>
2433
- set: <T>(key: string, value: T) => Promise<void>
2434
- remove: (key: string) => Promise<void>
2435
- clear: () => Promise<void>
2436
- keys: () => Promise<string[]>
2437
- }
2577
+ function useVerifyPaymentReturn(
2578
+ options?: UseVerifyPaymentReturnOptions,
2579
+ ): UseVerifyPaymentReturnResult
2438
2580
  ```
2439
2581
 
2440
- **Returns:** Storage operation methods
2582
+ - `options` — Provider fallback + lifecycle callbacks (see {@link UseVerifyPaymentReturnOptions}).
2441
2583
 
2442
- #### `useStorageProvider()`
2584
+ **Returns:** The verification state (see {@link UseVerifyPaymentReturnResult}).
2443
2585
 
2444
- Hook to access the storage provider from context.
2586
+ #### `useVersion()`
2587
+
2588
+ Hook for version state and update actions.
2589
+
2590
+ Uses module-level `getProvider()` — version is a singleton, not context-provided.
2445
2591
 
2446
2592
  ```typescript
2447
- function useStorageProvider(): StorageProvider
2593
+ function useVersion(): UseVersionResult
2448
2594
  ```
2449
2595
 
2450
- **Returns:** The storage provider from context
2596
+ **Returns:** Version state and action methods
2451
2597
 
2452
- #### `useStorageValue(key, options)`
2598
+ #### `useWorkspaceProvider()`
2453
2599
 
2454
- Hook to manage a single storage value with React state sync.
2600
+ Access the workspace provider from context.
2455
2601
 
2456
2602
  ```typescript
2457
- function useStorageValue(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>
2603
+ function useWorkspaceProvider(): WorkspaceProvider
2458
2604
  ```
2459
2605
 
2460
- - `key` — Storage key
2461
- - `options` — Hook options
2462
-
2463
- **Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
2606
+ **Returns:** The result.
2464
2607
 
2465
- #### `useStore(store, options)`
2608
+ #### `useWorkspace()`
2466
2609
 
2467
- Hook to subscribe to a store with optional selector and equality function.
2610
+ Hook for IDE workspace layout management.
2468
2611
 
2469
2612
  ```typescript
2470
- function useStore(store: Store<T>, options?: UseStoreOptions<T, S>): S
2613
+ function useWorkspace(): UseWorkspaceResult
2471
2614
  ```
2472
2615
 
2473
- - `store` — The store to subscribe to
2474
- - `options` — Hook options (selector, equalityFn)
2475
-
2476
- **Returns:** The selected state
2616
+ **Returns:** The workspace state and management methods.
2477
2617
 
2478
- #### `useStoreAction(store, action)`
2618
+ #### `StateProvider(props)`
2479
2619
 
2480
- Hook to create a bound action for a store.
2620
+ Provider for state management.
2481
2621
 
2482
2622
  ```typescript
2483
- function useStoreAction(
2484
- store: Store<T>,
2485
- action: (setState: Store<T>['setState'], getState: Store<T>['getState']) => (...args: Args) => R,
2486
- ): (...args: Args) => R
2623
+ function StateProvider({
2624
+ provider,
2625
+ children,
2626
+ }: StateProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2487
2627
  ```
2488
2628
 
2489
- - `store` — The store to bind to
2490
- - `action` — The action function that receives setState and getState
2629
+ - `props` — Component props (see {@link StateProviderProps}).
2491
2630
 
2492
- **Returns:** A bound action function
2631
+ **Returns:** The rendered state provider element.
2493
2632
 
2494
- #### `useT()`
2633
+ #### `AuthProvider(props)`
2495
2634
 
2496
- Hook to get just the translation function.
2635
+ Provider for authentication.
2497
2636
 
2498
2637
  ```typescript
2499
- function useT(): (
2500
- key: string,
2501
- values?: InterpolationValues,
2502
- options?: { defaultValue?: string; count?: number },
2503
- ) => string
2638
+ function AuthProvider({
2639
+ client,
2640
+ children,
2641
+ }: AuthProviderProps<T>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2504
2642
  ```
2505
2643
 
2506
- **Returns:** The translation function
2644
+ - `props` — Component props (see {@link AuthProviderProps}).
2507
2645
 
2508
- #### `useTheme()`
2646
+ **Returns:** The rendered auth provider element.
2509
2647
 
2510
- Hook for theme state and actions.
2648
+ #### `ThemeProvider(props)`
2649
+
2650
+ Provider for theming.
2511
2651
 
2512
2652
  ```typescript
2513
- function useTheme(): UseThemeResult
2653
+ function ThemeProvider({
2654
+ provider,
2655
+ children,
2656
+ }: ThemeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2514
2657
  ```
2515
2658
 
2516
- **Returns:** Theme state and actions
2659
+ - `props` — Component props (see {@link ThemeProviderProps}).
2660
+
2661
+ **Returns:** The rendered theme provider element.
2517
2662
 
2518
- #### `useThemeColors()`
2663
+ #### `RouterProvider(props)`
2519
2664
 
2520
- Hook to get theme colors.
2665
+ Provider for routing.
2521
2666
 
2522
2667
  ```typescript
2523
- function useThemeColors(): ThemeColors
2668
+ function RouterProvider({
2669
+ router,
2670
+ children,
2671
+ }: RouterProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2524
2672
  ```
2525
2673
 
2526
- **Returns:** The current theme colors
2674
+ - `props` — Component props (see {@link RouterProviderProps}).
2527
2675
 
2528
- #### `useThemeMode()`
2676
+ **Returns:** The rendered router provider element.
2529
2677
 
2530
- Hook to get just the theme mode (light/dark).
2678
+ #### `I18nProvider(props)`
2679
+
2680
+ Provider for internationalization.
2531
2681
 
2532
2682
  ```typescript
2533
- function useThemeMode(): 'light' | 'dark'
2683
+ function I18nProvider({
2684
+ provider,
2685
+ children,
2686
+ }: I18nProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2534
2687
  ```
2535
2688
 
2536
- **Returns:** The current theme mode
2689
+ - `props` — Component props (see {@link I18nProviderProps}).
2537
2690
 
2538
- #### `useThemeProvider()`
2691
+ **Returns:** The rendered i18n provider element.
2539
2692
 
2540
- Hook to access the theme provider from context.
2693
+ #### `HttpProvider(props)`
2694
+
2695
+ Provider for HTTP client.
2541
2696
 
2542
2697
  ```typescript
2543
- function useThemeProvider(): ThemeProvider
2698
+ function HttpProvider({
2699
+ client,
2700
+ children,
2701
+ }: HttpProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2544
2702
  ```
2545
2703
 
2546
- **Returns:** The theme provider from context
2704
+ - `props` — Component props (see {@link HttpProviderProps}).
2547
2705
 
2548
- #### `useTranslation()`
2706
+ **Returns:** The rendered HTTP provider element.
2549
2707
 
2550
- Hook for internationalization.
2708
+ #### `StorageProvider(props)`
2709
+
2710
+ Provider for storage.
2551
2711
 
2552
2712
  ```typescript
2553
- function useTranslation(): UseTranslationResult
2713
+ function StorageProvider({
2714
+ provider,
2715
+ children,
2716
+ }: StorageProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2554
2717
  ```
2555
2718
 
2556
- **Returns:** Translation function and locale management
2719
+ - `props` — Component props (see {@link StorageProviderProps}).
2557
2720
 
2558
- #### `useUser()`
2721
+ **Returns:** The rendered storage provider element.
2559
2722
 
2560
- Hook to get just the authenticated user.
2723
+ #### `LoggerProvider(props)`
2724
+
2725
+ Provider for logging.
2561
2726
 
2562
2727
  ```typescript
2563
- function useUser(): T | null
2728
+ function LoggerProvider({
2729
+ provider,
2730
+ children,
2731
+ }: LoggerProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2564
2732
  ```
2565
2733
 
2566
- **Returns:** The authenticated user or null
2567
-
2568
- #### `useVerifyPaymentReturn(options)`
2734
+ - `props` — Component props (see {@link LoggerProviderProps}).
2569
2735
 
2570
- Reads the payment id a provider put in the return URL and confirms the
2571
- purchase server-side with `POST /users/:id/verify-payment/:provider`.
2736
+ **Returns:** The rendered logger provider element.
2572
2737
 
2573
- **This is why a hosted checkout returns the buyer to the APP and not the
2574
- API.** Session cookies are host-only on the app's origin, so a top-level
2575
- redirect from the provider straight to an authenticated API callback on a
2576
- different host arrives with NO credentials — it answers 401 and the paid plan
2577
- is never granted. The request this hook makes is a same-origin call from a
2578
- loaded app page, so the credentials apply. It waits for auth to hydrate
2579
- first: after the redirect the page is a cold load, and the session is
2580
- restored from the httpOnly cookie via `GET /users/me`.
2738
+ #### `ChatProvider(props)`
2581
2739
 
2582
- Verification is idempotent server-side (first-claim-wins on the transaction),
2583
- and this hook additionally runs at most once per transaction id per page.
2584
- Safe on pages that are also reached normally: with no id in the URL it stays
2585
- `idle` and issues no request.
2740
+ Provider for AI chat.
2586
2741
 
2587
2742
  ```typescript
2588
- function useVerifyPaymentReturn(
2589
- options?: UseVerifyPaymentReturnOptions,
2590
- ): UseVerifyPaymentReturnResult
2743
+ function ChatProvider({
2744
+ provider,
2745
+ children,
2746
+ }: ChatProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2591
2747
  ```
2592
2748
 
2593
- - `options` — Provider fallback + lifecycle callbacks (see {@link UseVerifyPaymentReturnOptions}).
2594
-
2595
- **Returns:** The verification state (see {@link UseVerifyPaymentReturnResult}).
2749
+ - `props` — Component props (see {@link ChatProviderProps}).
2596
2750
 
2597
- #### `useVersion()`
2751
+ **Returns:** The rendered chat provider element.
2598
2752
 
2599
- Hook for version state and update actions.
2753
+ #### `WorkspaceProvider(props)`
2600
2754
 
2601
- Uses module-level `getProvider()` — version is a singleton, not context-provided.
2755
+ Provider for IDE workspace.
2602
2756
 
2603
2757
  ```typescript
2604
- function useVersion(): UseVersionResult
2758
+ function WorkspaceProvider({
2759
+ provider,
2760
+ children,
2761
+ }: WorkspaceProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2605
2762
  ```
2606
2763
 
2607
- **Returns:** Version state and action methods
2764
+ - `props` — Component props (see {@link WorkspaceProviderProps}).
2608
2765
 
2609
- #### `useWatch(form, name)`
2766
+ **Returns:** The rendered workspace provider element.
2610
2767
 
2611
- Hook to watch a specific field value.
2768
+ #### `EditorProvider(props)`
2769
+
2770
+ Provider for code editor.
2612
2771
 
2613
2772
  ```typescript
2614
- function useWatch(form: FormController<T>, name: K): T[K]
2773
+ function EditorProvider({
2774
+ provider,
2775
+ children,
2776
+ }: EditorProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2615
2777
  ```
2616
2778
 
2617
- - `form` — Form controller
2618
- - `name` — Field name to watch
2779
+ - `props` — Component props (see {@link EditorProviderProps}).
2619
2780
 
2620
- **Returns:** Current field value
2781
+ **Returns:** The rendered editor provider element.
2621
2782
 
2622
- #### `useWorkspace()`
2783
+ #### `PreviewProvider(props)`
2623
2784
 
2624
- Hook for IDE workspace layout management.
2785
+ Provider for live preview.
2625
2786
 
2626
2787
  ```typescript
2627
- function useWorkspace(): UseWorkspaceResult
2788
+ function PreviewProvider({
2789
+ provider,
2790
+ children,
2791
+ }: PreviewProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2628
2792
  ```
2629
2793
 
2630
- **Returns:** The workspace state and management methods.
2631
-
2632
- #### `useWorkspaceProvider()`
2633
-
2634
- Access the workspace provider from context.
2794
+ - `props` — Component props (see {@link PreviewProviderProps}).
2635
2795
 
2636
- ```typescript
2637
- function useWorkspaceProvider(): WorkspaceProvider
2638
- ```
2796
+ **Returns:** The rendered preview provider element.
2639
2797
 
2640
- **Returns:** The result.
2798
+ #### `MoleculeProvider(props)`
2641
2799
 
2642
- #### `WorkspaceProvider(props)`
2800
+ Combined provider for all molecule services.
2643
2801
 
2644
- Provider for IDE workspace.
2802
+ Provides a convenient way to wrap your app with all molecule providers at once.
2803
+ Only providers that are passed will be included — except `state`, which falls
2804
+ back to the state provider bonded under `@molecule/app-state` (set by
2805
+ `setupAllDefaultBonds()` or a state bond) so `useStore()` works without a
2806
+ `state` prop.
2645
2807
 
2646
2808
  ```typescript
2647
- function WorkspaceProvider({
2648
- provider,
2809
+ function MoleculeProvider({
2649
2810
  children,
2650
- }: WorkspaceProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2811
+ state,
2812
+ auth,
2813
+ theme,
2814
+ router,
2815
+ i18n,
2816
+ http,
2817
+ storage,
2818
+ logger,
2819
+ chat,
2820
+ workspace,
2821
+ editor,
2822
+ preview,
2823
+ }: MoleculeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2651
2824
  ```
2652
2825
 
2653
- - `props` — Component props (see {@link WorkspaceProviderProps}).
2826
+ - `props` — Component props (see {@link MoleculeProviderProps}) — each service is optional, and ONLY the services passed are provided to the tree.
2654
2827
 
2655
- **Returns:** The rendered workspace provider element.
2828
+ **Returns:** The rendered combined provider element.
2656
2829
 
2657
2830
  ### Constants
2658
2831
 
2659
- #### `AuthContext`
2832
+ #### `DEFAULT_AGENT_NAME`
2660
2833
 
2661
- Context for authentication client.
2834
+ Neutral, product-agnostic agent name used when the host supplies none.
2662
2835
 
2663
2836
  ```typescript
2664
- const AuthContext: Context<AuthClient<unknown> | null>
2837
+ const DEFAULT_AGENT_NAME: 'the assistant'
2665
2838
  ```
2666
2839
 
2667
- #### `ChatContext`
2840
+ #### `DEFAULT_PRODUCT_NAME`
2668
2841
 
2669
- Context for AI chat provider.
2842
+ Neutral, product-agnostic product/IDE name used when the host supplies none.
2670
2843
 
2671
2844
  ```typescript
2672
- const ChatContext: Context<ChatProvider | null>
2845
+ const DEFAULT_PRODUCT_NAME: 'the IDE'
2673
2846
  ```
2674
2847
 
2675
2848
  #### `DEFAULT_AGENT_IDENTITY`
@@ -2682,36 +2855,36 @@ passes its own.
2682
2855
  const DEFAULT_AGENT_IDENTITY: AgentIdentity
2683
2856
  ```
2684
2857
 
2685
- #### `DEFAULT_AGENT_NAME`
2858
+ #### `StateContext`
2686
2859
 
2687
- Neutral, product-agnostic agent name used when the host supplies none.
2860
+ Context for state management provider.
2688
2861
 
2689
2862
  ```typescript
2690
- const DEFAULT_AGENT_NAME: 'the assistant'
2863
+ const StateContext: Context<StateProvider | null>
2691
2864
  ```
2692
2865
 
2693
- #### `DEFAULT_PRODUCT_NAME`
2866
+ #### `AuthContext`
2694
2867
 
2695
- Neutral, product-agnostic product/IDE name used when the host supplies none.
2868
+ Context for authentication client.
2696
2869
 
2697
2870
  ```typescript
2698
- const DEFAULT_PRODUCT_NAME: 'the IDE'
2871
+ const AuthContext: Context<AuthClient<unknown, Record<never, never>> | null>
2699
2872
  ```
2700
2873
 
2701
- #### `EditorContext`
2874
+ #### `ThemeContext`
2702
2875
 
2703
- Context for code editor provider.
2876
+ Context for theme provider.
2704
2877
 
2705
2878
  ```typescript
2706
- const EditorContext: Context<EditorProvider | null>
2879
+ const ThemeContext: Context<ThemeProvider | null>
2707
2880
  ```
2708
2881
 
2709
- #### `HttpContext`
2882
+ #### `RouterContext`
2710
2883
 
2711
- Context for HTTP client.
2884
+ Context for router.
2712
2885
 
2713
2886
  ```typescript
2714
- const HttpContext: Context<HttpClient | null>
2887
+ const RouterContext: Context<Router | null>
2715
2888
  ```
2716
2889
 
2717
2890
  #### `I18nContext`
@@ -2722,52 +2895,60 @@ Context for internationalization provider.
2722
2895
  const I18nContext: Context<I18nProvider | null>
2723
2896
  ```
2724
2897
 
2725
- #### `LoggerContext`
2898
+ #### `HttpContext`
2726
2899
 
2727
- Context for logger provider.
2900
+ Context for HTTP client.
2728
2901
 
2729
2902
  ```typescript
2730
- const LoggerContext: Context<LoggerProvider | null>
2903
+ const HttpContext: Context<HttpClient | null>
2731
2904
  ```
2732
2905
 
2733
- #### `PreviewContext`
2906
+ #### `StorageContext`
2734
2907
 
2735
- Context for live preview provider.
2908
+ Context for storage provider.
2736
2909
 
2737
2910
  ```typescript
2738
- const PreviewContext: Context<PreviewProvider | null>
2911
+ const StorageContext: Context<StorageProvider | null>
2739
2912
  ```
2740
2913
 
2741
- #### `RouterContext`
2914
+ #### `LoggerContext`
2742
2915
 
2743
- Context for router.
2916
+ Context for logger provider.
2744
2917
 
2745
2918
  ```typescript
2746
- const RouterContext: Context<Router | null>
2919
+ const LoggerContext: Context<LoggerProvider | null>
2747
2920
  ```
2748
2921
 
2749
- #### `StateContext`
2922
+ #### `ChatContext`
2750
2923
 
2751
- Context for state management provider.
2924
+ Context for AI chat provider.
2752
2925
 
2753
2926
  ```typescript
2754
- const StateContext: Context<StateProvider | null>
2927
+ const ChatContext: Context<ChatProvider | null>
2755
2928
  ```
2756
2929
 
2757
- #### `StorageContext`
2930
+ #### `WorkspaceContext`
2758
2931
 
2759
- Context for storage provider.
2932
+ Context for IDE workspace provider.
2760
2933
 
2761
2934
  ```typescript
2762
- const StorageContext: Context<StorageProvider | null>
2935
+ const WorkspaceContext: Context<WorkspaceProvider | null>
2763
2936
  ```
2764
2937
 
2765
- #### `ThemeContext`
2938
+ #### `EditorContext`
2766
2939
 
2767
- Context for theme provider.
2940
+ Context for code editor provider.
2768
2941
 
2769
2942
  ```typescript
2770
- const ThemeContext: Context<ThemeProvider | null>
2943
+ const EditorContext: Context<EditorProvider | null>
2944
+ ```
2945
+
2946
+ #### `PreviewContext`
2947
+
2948
+ Context for live preview provider.
2949
+
2950
+ ```typescript
2951
+ const PreviewContext: Context<PreviewProvider | null>
2771
2952
  ```
2772
2953
 
2773
2954
  #### `useAsyncState`
@@ -2778,6 +2959,10 @@ Hook like useState but accepts Promises and supports partial state extension.
2778
2959
  const useAsyncState: <T>(initialState: T) => [T, AsyncSetState<T>, AsyncExtendState<T>]
2779
2960
  ```
2780
2961
 
2962
+ - `initialState` — Initial state value
2963
+
2964
+ **Returns:** Tuple of [state, asyncSetState, asyncExtendState]
2965
+
2781
2966
  #### `usePromise`
2782
2967
 
2783
2968
  Hook that wraps an async function with state tracking.
@@ -2791,13 +2976,9 @@ const usePromise: <T extends (...args: any[]) => Promise<any>>(
2791
2976
  ]
2792
2977
  ```
2793
2978
 
2794
- #### `WorkspaceContext`
2795
-
2796
- Context for IDE workspace provider.
2979
+ - `asyncFn` — The async function to wrap
2797
2980
 
2798
- ```typescript
2799
- const WorkspaceContext: Context<WorkspaceProvider | null>
2800
- ```
2981
+ **Returns:** Tuple of [state, wrappedFunction]
2801
2982
 
2802
2983
  ## Injection Notes
2803
2984