@molecule/app-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +115 -0
  2. package/README.md +2645 -0
  3. package/dist/agent-identity.d.ts +40 -0
  4. package/dist/agent-identity.d.ts.map +1 -0
  5. package/dist/agent-identity.js +31 -0
  6. package/dist/agent-identity.js.map +1 -0
  7. package/dist/contexts.d.ts +69 -0
  8. package/dist/contexts.d.ts.map +1 -0
  9. package/dist/contexts.js +70 -0
  10. package/dist/contexts.js.map +1 -0
  11. package/dist/hooks/index.d.ts +32 -0
  12. package/dist/hooks/index.d.ts.map +1 -0
  13. package/dist/hooks/index.js +32 -0
  14. package/dist/hooks/index.js.map +1 -0
  15. package/dist/hooks/useAIModels.d.ts +48 -0
  16. package/dist/hooks/useAIModels.d.ts.map +1 -0
  17. package/dist/hooks/useAIModels.js +145 -0
  18. package/dist/hooks/useAIModels.js.map +1 -0
  19. package/dist/hooks/useAsyncState.d.ts +41 -0
  20. package/dist/hooks/useAsyncState.d.ts.map +1 -0
  21. package/dist/hooks/useAsyncState.js +77 -0
  22. package/dist/hooks/useAsyncState.js.map +1 -0
  23. package/dist/hooks/useAuth.d.ts +43 -0
  24. package/dist/hooks/useAuth.d.ts.map +1 -0
  25. package/dist/hooks/useAuth.js +106 -0
  26. package/dist/hooks/useAuth.js.map +1 -0
  27. package/dist/hooks/useCapacitorApp.d.ts +35 -0
  28. package/dist/hooks/useCapacitorApp.d.ts.map +1 -0
  29. package/dist/hooks/useCapacitorApp.js +61 -0
  30. package/dist/hooks/useCapacitorApp.js.map +1 -0
  31. package/dist/hooks/useChangePassword.d.ts +34 -0
  32. package/dist/hooks/useChangePassword.d.ts.map +1 -0
  33. package/dist/hooks/useChangePassword.js +37 -0
  34. package/dist/hooks/useChangePassword.js.map +1 -0
  35. package/dist/hooks/useChat.d.ts +30 -0
  36. package/dist/hooks/useChat.d.ts.map +1 -0
  37. package/dist/hooks/useChat.js +1510 -0
  38. package/dist/hooks/useChat.js.map +1 -0
  39. package/dist/hooks/useDevice.d.ts +39 -0
  40. package/dist/hooks/useDevice.d.ts.map +1 -0
  41. package/dist/hooks/useDevice.js +41 -0
  42. package/dist/hooks/useDevice.js.map +1 -0
  43. package/dist/hooks/useEditor.d.ts +20 -0
  44. package/dist/hooks/useEditor.d.ts.map +1 -0
  45. package/dist/hooks/useEditor.js +98 -0
  46. package/dist/hooks/useEditor.js.map +1 -0
  47. package/dist/hooks/useForm.d.ts +87 -0
  48. package/dist/hooks/useForm.d.ts.map +1 -0
  49. package/dist/hooks/useForm.js +148 -0
  50. package/dist/hooks/useForm.js.map +1 -0
  51. package/dist/hooks/useHttp.d.ts +103 -0
  52. package/dist/hooks/useHttp.d.ts.map +1 -0
  53. package/dist/hooks/useHttp.js +161 -0
  54. package/dist/hooks/useHttp.js.map +1 -0
  55. package/dist/hooks/useLogger.d.ts +68 -0
  56. package/dist/hooks/useLogger.d.ts.map +1 -0
  57. package/dist/hooks/useLogger.js +95 -0
  58. package/dist/hooks/useLogger.js.map +1 -0
  59. package/dist/hooks/useLogin.d.ts +35 -0
  60. package/dist/hooks/useLogin.d.ts.map +1 -0
  61. package/dist/hooks/useLogin.js +37 -0
  62. package/dist/hooks/useLogin.js.map +1 -0
  63. package/dist/hooks/useOAuth.d.ts +83 -0
  64. package/dist/hooks/useOAuth.d.ts.map +1 -0
  65. package/dist/hooks/useOAuth.js +348 -0
  66. package/dist/hooks/useOAuth.js.map +1 -0
  67. package/dist/hooks/usePasswordReset.d.ts +43 -0
  68. package/dist/hooks/usePasswordReset.d.ts.map +1 -0
  69. package/dist/hooks/usePasswordReset.js +50 -0
  70. package/dist/hooks/usePasswordReset.js.map +1 -0
  71. package/dist/hooks/usePlatform.d.ts +38 -0
  72. package/dist/hooks/usePlatform.d.ts.map +1 -0
  73. package/dist/hooks/usePlatform.js +40 -0
  74. package/dist/hooks/usePlatform.js.map +1 -0
  75. package/dist/hooks/usePreview.d.ts +20 -0
  76. package/dist/hooks/usePreview.d.ts.map +1 -0
  77. package/dist/hooks/usePreview.js +62 -0
  78. package/dist/hooks/usePreview.js.map +1 -0
  79. package/dist/hooks/usePromise.d.ts +39 -0
  80. package/dist/hooks/usePromise.d.ts.map +1 -0
  81. package/dist/hooks/usePromise.js +92 -0
  82. package/dist/hooks/usePromise.js.map +1 -0
  83. package/dist/hooks/usePush.d.ts +50 -0
  84. package/dist/hooks/usePush.d.ts.map +1 -0
  85. package/dist/hooks/usePush.js +89 -0
  86. package/dist/hooks/usePush.js.map +1 -0
  87. package/dist/hooks/useRouter.d.ts +65 -0
  88. package/dist/hooks/useRouter.d.ts.map +1 -0
  89. package/dist/hooks/useRouter.js +120 -0
  90. package/dist/hooks/useRouter.js.map +1 -0
  91. package/dist/hooks/useSignup.d.ts +35 -0
  92. package/dist/hooks/useSignup.d.ts.map +1 -0
  93. package/dist/hooks/useSignup.js +37 -0
  94. package/dist/hooks/useSignup.js.map +1 -0
  95. package/dist/hooks/useStorage.d.ts +72 -0
  96. package/dist/hooks/useStorage.d.ts.map +1 -0
  97. package/dist/hooks/useStorage.js +144 -0
  98. package/dist/hooks/useStorage.js.map +1 -0
  99. package/dist/hooks/useStore.d.ts +51 -0
  100. package/dist/hooks/useStore.d.ts.map +1 -0
  101. package/dist/hooks/useStore.js +86 -0
  102. package/dist/hooks/useStore.js.map +1 -0
  103. package/dist/hooks/useTheme.d.ts +50 -0
  104. package/dist/hooks/useTheme.d.ts.map +1 -0
  105. package/dist/hooks/useTheme.js +135 -0
  106. package/dist/hooks/useTheme.js.map +1 -0
  107. package/dist/hooks/useTranslation.d.ts +69 -0
  108. package/dist/hooks/useTranslation.d.ts.map +1 -0
  109. package/dist/hooks/useTranslation.js +131 -0
  110. package/dist/hooks/useTranslation.js.map +1 -0
  111. package/dist/hooks/useVersion.d.ts +41 -0
  112. package/dist/hooks/useVersion.d.ts.map +1 -0
  113. package/dist/hooks/useVersion.js +73 -0
  114. package/dist/hooks/useVersion.js.map +1 -0
  115. package/dist/hooks/useWorkspace.d.ts +18 -0
  116. package/dist/hooks/useWorkspace.d.ts.map +1 -0
  117. package/dist/hooks/useWorkspace.js +67 -0
  118. package/dist/hooks/useWorkspace.js.map +1 -0
  119. package/dist/index.d.ts +80 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +80 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/providers.d.ts +189 -0
  124. package/dist/providers.d.ts.map +1 -0
  125. package/dist/providers.js +248 -0
  126. package/dist/providers.js.map +1 -0
  127. package/dist/types.d.ts +381 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +7 -0
  130. package/dist/types.js.map +1 -0
  131. package/package.json +82 -0
package/README.md ADDED
@@ -0,0 +1,2645 @@
1
+ <!--
2
+ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
+ Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
+ Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
+ To change this document, edit the module-level JSDoc in src/index.ts.
6
+ Generated: 2026-08-04T00:40:53.219Z
7
+ -->
8
+
9
+ # @molecule/app-react
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
+ React framework bindings for the Molecule app stack.
16
+
17
+ Provides React hooks, contexts, and provider components for all molecule
18
+ core interfaces (auth, i18n, theme, routing, state, http, storage, logger,
19
+ chat, workspace, editor, preview), so framework-agnostic providers plug
20
+ into React idioms.
21
+
22
+ ## Quick Start
23
+
24
+ ```tsx
25
+ import { MoleculeProvider, useAuth, useTheme, useTranslation } from '@molecule/app-react'
26
+ import { provider as stateProvider } from '@molecule/app-state-zustand'
27
+ import { provider as themeProvider } from '@molecule/app-theme-css-variables'
28
+ import { provider as i18nProvider } from '@molecule/app-i18n-react-i18next'
29
+ import { createJWTAuthClient } from '@molecule/app-auth'
30
+
31
+ const authClient = createJWTAuthClient({ baseURL: '/api' })
32
+
33
+ function Dashboard() {
34
+ const { user, isAuthenticated, logout } = useAuth<{ name?: string }>()
35
+ const { t } = useTranslation()
36
+ const { theme, toggleTheme } = useTheme()
37
+
38
+ if (!isAuthenticated) {
39
+ return <p>{t('auth.required', undefined, { defaultValue: 'Please log in.' })}</p>
40
+ }
41
+ return (
42
+ <div style={{ background: theme.colors.background }}>
43
+ <h1>{t('greeting.welcome', { name: user?.name }, { defaultValue: 'Welcome, {{name}}!' })}</h1>
44
+ <button onClick={toggleTheme}>
45
+ {t('theme.toggle', undefined, { defaultValue: 'Toggle theme' })}
46
+ </button>
47
+ <button onClick={() => logout()}>
48
+ {t('auth.logout', undefined, { defaultValue: 'Log out' })}
49
+ </button>
50
+ </div>
51
+ )
52
+ }
53
+
54
+ function App() {
55
+ return (
56
+ <MoleculeProvider
57
+ state={stateProvider}
58
+ auth={authClient}
59
+ theme={themeProvider}
60
+ i18n={i18nProvider}
61
+ >
62
+ <Dashboard />
63
+ </MoleculeProvider>
64
+ )
65
+ }
66
+ ```
67
+
68
+ ## Type
69
+
70
+ `framework`
71
+
72
+ ## Installation
73
+
74
+ ```bash
75
+ npm install @molecule/app-react @molecule/app-ai-chat @molecule/app-ai-models @molecule/app-auth @molecule/app-code-editor @molecule/app-device @molecule/app-forms @molecule/app-http @molecule/app-i18n @molecule/app-ide @molecule/app-live-preview @molecule/app-logger @molecule/app-platform @molecule/app-push @molecule/app-routing @molecule/app-state @molecule/app-storage @molecule/app-theme @molecule/app-ui @molecule/app-utilities @molecule/app-version react
76
+ npm install -D @types/react
77
+ ```
78
+
79
+ ## API
80
+
81
+ ### Interfaces
82
+
83
+ #### `AgentIdentity`
84
+
85
+ Display identity for the AI coding agent and the host product, used to
86
+ interpolate the `{{agentName}}` / `{{productName}}` tokens in shared chat/IDE
87
+ copy. A consuming app sets these to its own agent + product brand names; the
88
+ shared packages fall back to {@link DEFAULT_AGENT_IDENTITY} when it does not.
89
+
90
+ ```typescript
91
+ interface AgentIdentity {
92
+ /** Display name of the AI coding agent. Defaults to {@link DEFAULT_AGENT_NAME}. */
93
+ agentName: string
94
+ /** Display name of the host product / IDE. Defaults to {@link DEFAULT_PRODUCT_NAME}. */
95
+ productName: string
96
+ }
97
+ ```
98
+
99
+ #### `AuthClient`
100
+
101
+ Auth client interface that all auth bond packages must implement.
102
+ Provides login/logout/register flows, token management, profile
103
+ updates, and auth state subscription.
104
+
105
+ ```typescript
106
+ interface AuthClient<T = UserProfile> {
107
+ /**
108
+ * Returns the current authentication state snapshot.
109
+ */
110
+ getState(): AuthState<T>
111
+ /**
112
+ * Returns whether the user is currently authenticated.
113
+ */
114
+ isAuthenticated(): boolean
115
+ /**
116
+ * Gets the current user.
117
+ */
118
+ getUser(): T | null
119
+ /**
120
+ * Updates the cached user object (state + persistent storage) without
121
+ * hitting the network. Intended for local refreshes after a per-app
122
+ * mutation (e.g., the user just PATCHed their own profile and the
123
+ * server returned the canonical row). Does NOT change tokens.
124
+ */
125
+ setUser(user: T | null): void
126
+ /**
127
+ * Gets the current access token.
128
+ */
129
+ getAccessToken(): string | null
130
+ /**
131
+ * Stores the access token in the configured token storage adapter (in-memory
132
+ * by default). Use this to seed the token after an out-of-band exchange (e.g.
133
+ * the OAuth code→token redirect) instead of writing to `localStorage` directly,
134
+ * which would violate the in-memory-default storage contract and make the bearer
135
+ * token JS-readable (XSS-exfiltratable). Pass `null` to clear it.
136
+ */
137
+ setAccessToken(token: string | null): void
138
+ /**
139
+ * Gets the refresh token.
140
+ */
141
+ getRefreshToken(): string | null
142
+ /**
143
+ * Logs in with credentials.
144
+ */
145
+ login(credentials: LoginCredentials): Promise<AuthResult<T>>
146
+ /**
147
+ * Logs out the current user.
148
+ */
149
+ logout(): Promise<void>
150
+ /**
151
+ * Registers a new user.
152
+ */
153
+ register(data: RegisterData): Promise<AuthResult<T>>
154
+ /**
155
+ * Refreshes the access token.
156
+ */
157
+ refresh(): Promise<AuthResult<T>>
158
+ /**
159
+ * Requests a password reset.
160
+ */
161
+ requestPasswordReset(data: PasswordResetRequest): Promise<void>
162
+ /**
163
+ * Confirms a password reset.
164
+ */
165
+ confirmPasswordReset(data: PasswordResetConfirm): Promise<void>
166
+ /**
167
+ * Updates the current user's profile.
168
+ */
169
+ updateProfile(data: Partial<T>): Promise<T>
170
+ /**
171
+ * Changes the current user's password.
172
+ */
173
+ changePassword(oldPassword: string, newPassword: string): Promise<void>
174
+ /**
175
+ * Initializes auth state (e.g., from stored tokens).
176
+ */
177
+ initialize(): Promise<void>
178
+ /**
179
+ * Subscribes to auth state changes.
180
+ */
181
+ subscribe(callback: (state: AuthState<T>) => void): () => void
182
+ /**
183
+ * Subscribes to auth state changes (alias for subscribe).
184
+ */
185
+ onAuthChange(callback: (state: AuthState<T>) => void): () => void
186
+ /**
187
+ * Gets the current access token (alias for getAccessToken).
188
+ */
189
+ getToken?(): string | null
190
+ /**
191
+ * Adds an auth event listener.
192
+ */
193
+ addEventListener(listener: AuthEventListener): () => void
194
+ /**
195
+ * Destroys the auth client.
196
+ */
197
+ destroy(): void
198
+ }
199
+ ```
200
+
201
+ #### `AuthProviderProps`
202
+
203
+ Props for auth provider component.
204
+
205
+ ```typescript
206
+ interface AuthProviderProps<T = unknown> extends ProviderProps {
207
+ client: AuthClient<T>
208
+ }
209
+ ```
210
+
211
+ #### `AuthState`
212
+
213
+ Reactive authentication state snapshot (initialized, authenticated, user, loading, and error).
214
+
215
+ ```typescript
216
+ interface AuthState<T = UserProfile> {
217
+ /**
218
+ * Whether auth state has been initialized.
219
+ */
220
+ initialized: boolean
221
+ /**
222
+ * Whether the user is authenticated.
223
+ */
224
+ authenticated: boolean
225
+ /**
226
+ * Current user (if authenticated).
227
+ */
228
+ user: T | null
229
+ /**
230
+ * Whether an auth operation is in progress.
231
+ */
232
+ loading: boolean
233
+ /**
234
+ * Last auth error (if any).
235
+ */
236
+ error: string | null
237
+ }
238
+ ```
239
+
240
+ #### `ChatProviderProps`
241
+
242
+ Props for the ChatProvider React component.
243
+
244
+ ```typescript
245
+ interface ChatProviderProps extends ProviderProps {
246
+ provider: ChatProvider
247
+ }
248
+ ```
249
+
250
+ #### `EditorProviderProps`
251
+
252
+ Props for editor provider component.
253
+
254
+ ```typescript
255
+ interface EditorProviderProps extends ProviderProps {
256
+ provider: EditorProvider
257
+ }
258
+ ```
259
+
260
+ #### `FormController`
261
+
262
+ Form controller interface.
263
+
264
+ All form providers must implement this interface.
265
+
266
+ ```typescript
267
+ interface FormController<T extends Record<string, unknown> = Record<string, unknown>> {
268
+ /**
269
+ * Gets the current form state.
270
+ */
271
+ getState(): FormState<T>
272
+ /**
273
+ * Gets the value of a specific field.
274
+ */
275
+ getValue(name: string): unknown
276
+ getValue<K extends keyof T>(name: K): T[K]
277
+ /**
278
+ * Gets all form values.
279
+ */
280
+ getValues(): T
281
+ /**
282
+ * Sets the value of a specific field.
283
+ */
284
+ setValue(
285
+ name: string,
286
+ value: unknown,
287
+ options?: {
288
+ shouldValidate?: boolean
289
+ shouldDirty?: boolean
290
+ shouldTouch?: boolean
291
+ },
292
+ ): void
293
+ /**
294
+ * Sets multiple values at once.
295
+ */
296
+ setValues(
297
+ values: Partial<T>,
298
+ options?: {
299
+ shouldValidate?: boolean
300
+ },
301
+ ): void
302
+ /**
303
+ * Gets the error for a specific field.
304
+ */
305
+ getError(name: string): string | undefined
306
+ /**
307
+ * Sets the error for a specific field.
308
+ */
309
+ setError(name: string, error: string | undefined): void
310
+ /**
311
+ * Clears the error for a specific field.
312
+ */
313
+ clearError<K extends keyof T>(name: K): void
314
+ /**
315
+ * Clears all errors.
316
+ */
317
+ clearErrors(): void
318
+ /**
319
+ * Gets the field state for a specific field.
320
+ */
321
+ getFieldState<K extends keyof T>(name: K): FieldState<T[K]>
322
+ /**
323
+ * Registers a field for form management.
324
+ */
325
+ register(nameOrOptions: string | RegisterOptions, options?: RegisterOptions): FieldRegistration
326
+ /**
327
+ * Unregisters a field.
328
+ */
329
+ unregister(name: string): void
330
+ /**
331
+ * Validates a specific field.
332
+ */
333
+ validateField<K extends keyof T>(name: K): Promise<boolean>
334
+ /**
335
+ * Validates all fields.
336
+ */
337
+ validate(): Promise<boolean>
338
+ /**
339
+ * Resets the form to initial values.
340
+ */
341
+ reset(values?: Partial<T>): void
342
+ /**
343
+ * Handles form submission.
344
+ */
345
+ handleSubmit(
346
+ onSubmit: (values: T) => void | Promise<void>,
347
+ onError?: (errors: Partial<Record<keyof T, string>>) => void,
348
+ ): (event?: { preventDefault?: () => void }) => Promise<void>
349
+ /**
350
+ * Sets focus to a field.
351
+ */
352
+ setFocus(name: keyof T): void
353
+ /**
354
+ * Subscribes to form state changes.
355
+ */
356
+ subscribe(callback: (state: FormState<T>) => void): () => void
357
+ /**
358
+ * Destroys the form controller.
359
+ */
360
+ destroy(): void
361
+ }
362
+ ```
363
+
364
+ #### `FormOptions`
365
+
366
+ Form creation options.
367
+
368
+ ```typescript
369
+ interface FormOptions<T extends Record<string, unknown>> {
370
+ /**
371
+ * Default values.
372
+ */
373
+ defaultValues?: Partial<T>
374
+ /**
375
+ * Validation mode.
376
+ */
377
+ mode?: 'onSubmit' | 'onChange' | 'onBlur' | 'all'
378
+ /**
379
+ * Revalidation mode.
380
+ */
381
+ reValidateMode?: 'onChange' | 'onBlur' | 'onSubmit'
382
+ /**
383
+ * Whether to focus the first error field on submit.
384
+ */
385
+ shouldFocusError?: boolean
386
+ /**
387
+ * Form-level validation function.
388
+ */
389
+ validate?: (
390
+ values: T,
391
+ ) => Partial<Record<keyof T, string>> | Promise<Partial<Record<keyof T, string>>>
392
+ }
393
+ ```
394
+
395
+ #### `HttpClient`
396
+
397
+ HTTP client interface.
398
+
399
+ All HTTP providers must implement this interface.
400
+
401
+ ```typescript
402
+ interface HttpClient {
403
+ /**
404
+ * Base URL for all requests.
405
+ */
406
+ baseURL: string
407
+ /**
408
+ * Default headers for all requests.
409
+ */
410
+ defaultHeaders: Record<string, string>
411
+ /**
412
+ * Makes a generic HTTP request.
413
+ */
414
+ request<T = unknown>(config: FullRequestConfig): Promise<HttpResponse<T>>
415
+ /**
416
+ * Makes a GET request.
417
+ */
418
+ get<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
419
+ /**
420
+ * Makes a POST request.
421
+ */
422
+ post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
423
+ /**
424
+ * Makes a PUT request.
425
+ */
426
+ put<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
427
+ /**
428
+ * Makes a PATCH request.
429
+ */
430
+ patch<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<HttpResponse<T>>
431
+ /**
432
+ * Makes a DELETE request.
433
+ */
434
+ delete<T = unknown>(url: string, config?: RequestConfig): Promise<HttpResponse<T>>
435
+ /**
436
+ * Adds a request interceptor.
437
+ * Returns a function to remove the interceptor.
438
+ */
439
+ addRequestInterceptor(interceptor: RequestInterceptor): () => void
440
+ /**
441
+ * Adds a response interceptor.
442
+ * Returns a function to remove the interceptor.
443
+ */
444
+ addResponseInterceptor(interceptor: ResponseInterceptor): () => void
445
+ /**
446
+ * Adds an error interceptor.
447
+ * Returns a function to remove the interceptor.
448
+ */
449
+ addErrorInterceptor(interceptor: ErrorInterceptor): () => void
450
+ /**
451
+ * Sets the authorization token.
452
+ */
453
+ setAuthToken(token: string | null): void
454
+ /**
455
+ * Returns the current authorization token, or `null` if not set.
456
+ */
457
+ getAuthToken(): string | null
458
+ /**
459
+ * Registers a handler for authentication errors (401).
460
+ *
461
+ * @returns An unsubscribe function.
462
+ */
463
+ onAuthError(handler: () => void): () => void
464
+ }
465
+ ```
466
+
467
+ #### `HttpProviderProps`
468
+
469
+ Props for http provider component.
470
+
471
+ ```typescript
472
+ interface HttpProviderProps extends ProviderProps {
473
+ client: HttpClient
474
+ }
475
+ ```
476
+
477
+ #### `I18nProviderProps`
478
+
479
+ Props for i18n provider component.
480
+
481
+ ```typescript
482
+ interface I18nProviderProps extends ProviderProps {
483
+ provider: I18nProvider
484
+ }
485
+ ```
486
+
487
+ #### `LoggerProviderProps`
488
+
489
+ Props for logger provider component.
490
+
491
+ ```typescript
492
+ interface LoggerProviderProps extends ProviderProps {
493
+ provider: LoggerProvider
494
+ }
495
+ ```
496
+
497
+ #### `MoleculeProviderProps`
498
+
499
+ Properties for molecule provider.
500
+
501
+ ```typescript
502
+ interface MoleculeProviderProps extends ProviderProps {
503
+ state?: StateProvider
504
+ auth?: AuthClient<unknown>
505
+ theme?: ThemeProvider
506
+ router?: Router
507
+ i18n?: I18nProvider
508
+ http?: HttpClient
509
+ storage?: StorageProvider
510
+ logger?: LoggerProvider
511
+ chat?: ChatProvider
512
+ workspace?: WorkspaceProvider
513
+ editor?: EditorProvider
514
+ preview?: PreviewProvider
515
+ }
516
+ ```
517
+
518
+ #### `PreviewProviderProps`
519
+
520
+ Props for preview provider component.
521
+
522
+ ```typescript
523
+ interface PreviewProviderProps extends ProviderProps {
524
+ provider: PreviewProvider
525
+ }
526
+ ```
527
+
528
+ #### `ProviderProps`
529
+
530
+ Props for provider components.
531
+
532
+ ```typescript
533
+ interface ProviderProps {
534
+ children: ReactNode
535
+ }
536
+ ```
537
+
538
+ #### `Router`
539
+
540
+ Client-side router providing navigation, guards, route matching, and history control.
541
+
542
+ All routing providers must implement this interface.
543
+
544
+ ```typescript
545
+ interface Router {
546
+ /**
547
+ * Returns the current route location (pathname, search, hash, state).
548
+ */
549
+ getLocation(): RouteLocation
550
+ /**
551
+ * Gets the current route params.
552
+ */
553
+ getParams<T extends RouteParams = RouteParams>(): T
554
+ /**
555
+ * Gets the current query params.
556
+ */
557
+ getQuery(): QueryParams
558
+ /**
559
+ * Gets a specific query parameter.
560
+ */
561
+ getQueryParam(key: string): string | undefined
562
+ /**
563
+ * Gets the current hash.
564
+ */
565
+ getHash(): string
566
+ /**
567
+ * Navigates to a path.
568
+ */
569
+ navigate(path: string, options?: NavigateOptions): void
570
+ /**
571
+ * Navigates to a named route.
572
+ */
573
+ navigateTo(
574
+ name: string,
575
+ params?: RouteParams,
576
+ query?: QueryParams,
577
+ options?: NavigateOptions,
578
+ ): void
579
+ /**
580
+ * Goes back in history.
581
+ */
582
+ back(): void
583
+ /**
584
+ * Goes forward in history.
585
+ */
586
+ forward(): void
587
+ /**
588
+ * Goes to a specific point in history.
589
+ */
590
+ go(delta: number): void
591
+ /**
592
+ * Updates the current query params.
593
+ */
594
+ setQuery(params: QueryParams, options?: NavigateOptions): void
595
+ /**
596
+ * Updates a specific query parameter.
597
+ */
598
+ setQueryParam(key: string, value: string | undefined, options?: NavigateOptions): void
599
+ /**
600
+ * Updates the current hash.
601
+ */
602
+ setHash(hash: string, options?: NavigateOptions): void
603
+ /**
604
+ * Checks if a path matches the current location.
605
+ *
606
+ * @returns `true` if the path matches the current route.
607
+ */
608
+ isActive(path: string, exact?: boolean): boolean
609
+ /**
610
+ * Matches a path pattern against a pathname.
611
+ */
612
+ matchPath<Params extends RouteParams = RouteParams>(
613
+ pattern: string,
614
+ pathname: string,
615
+ ): RouteMatch<Params> | null
616
+ /**
617
+ * Generates a URL from a named route.
618
+ */
619
+ generatePath(name: string, params?: RouteParams, query?: QueryParams): string
620
+ /**
621
+ * Subscribes to route changes.
622
+ */
623
+ subscribe(listener: RouteChangeListener): () => void
624
+ /**
625
+ * Adds a navigation guard.
626
+ */
627
+ addGuard(guard: NavigationGuard): () => void
628
+ /**
629
+ * Registers route definitions.
630
+ */
631
+ registerRoutes(routes: RouteDefinition[]): void
632
+ /**
633
+ * Gets all registered routes.
634
+ */
635
+ getRoutes(): RouteDefinition[]
636
+ /**
637
+ * Destroys the router.
638
+ */
639
+ destroy(): void
640
+ }
641
+ ```
642
+
643
+ #### `RouterConfig`
644
+
645
+ Configuration options for creating a router instance.
646
+
647
+ ```typescript
648
+ interface RouterConfig {
649
+ /**
650
+ * Router mode.
651
+ */
652
+ mode?: 'history' | 'hash' | 'memory'
653
+ /**
654
+ * Base path.
655
+ */
656
+ basePath?: string
657
+ /**
658
+ * Initial routes.
659
+ */
660
+ routes?: RouteDefinition[]
661
+ }
662
+ ```
663
+
664
+ #### `RouterProviderProps`
665
+
666
+ Props for router provider component.
667
+
668
+ ```typescript
669
+ interface RouterProviderProps extends ProviderProps {
670
+ router: Router
671
+ }
672
+ ```
673
+
674
+ #### `SendMessageOptions`
675
+
676
+ Options for {@link UseChatResult.sendMessage}.
677
+
678
+ ```typescript
679
+ interface SendMessageOptions {
680
+ /**
681
+ * Skip the optimistic local user-message bubble. The text is still sent to
682
+ * the server. Used for ask_user responses: the answer is folded into the
683
+ * ask_user tool card (a checkmark on the chosen option, or the custom text
684
+ * shown in-card) rather than echoed as a separate message below it.
685
+ */
686
+ suppressUserMessage?: boolean
687
+ /**
688
+ * Mark this send as issued automatically on the user's behalf (e.g. an
689
+ * auto-fix prompt). The optimistic local bubble and the persisted message are
690
+ * flagged `automatic` so the chat renders it in the distinct auto-sent style
691
+ * (agent avatar + accent border) instead of looking like the user typed it.
692
+ */
693
+ automatic?: boolean
694
+ /**
695
+ * Mark this send as the answer to the pending `ask_user` question. The most
696
+ * recent unanswered `ask_user` tool call in the store is resolved in place —
697
+ * its `output` is set to this answer — so the chosen option stays checked
698
+ * across remounts (e.g. the discovery→IDE transition) instead of relying on
699
+ * ephemeral component state that the answer's selection would otherwise lose.
700
+ * Distinct from {@link suppressUserMessage} (which the post-boot kickoff also
701
+ * sets) so resolving never misfires on a non-ask_user suppressed send.
702
+ */
703
+ askUserAnswer?: boolean
704
+ /**
705
+ * Mark an {@link automatic} send as directly requested by the user (e.g. the
706
+ * editor's "Fix with AI" action, the broken-preview overlay's "Fix with AI"
707
+ * button) rather than dispatched autonomously by the platform. A user Stop
708
+ * suppresses autonomous automatic sends until the user re-engages; a
709
+ * user-initiated one IS that re-engagement — it clears the stop and sends.
710
+ */
711
+ userInitiated?: boolean
712
+ }
713
+ ```
714
+
715
+ #### `StateProviderProps`
716
+
717
+ Props for state provider component.
718
+
719
+ ```typescript
720
+ interface StateProviderProps extends ProviderProps {
721
+ provider: StateProvider
722
+ }
723
+ ```
724
+
725
+ #### `StorageProviderProps`
726
+
727
+ Props for storage provider component.
728
+
729
+ ```typescript
730
+ interface StorageProviderProps extends ProviderProps {
731
+ provider: StorageProvider
732
+ }
733
+ ```
734
+
735
+ #### `Store`
736
+
737
+ Reactive state container with getState, setState, subscribe, and destroy.
738
+
739
+ All state management providers must implement this interface.
740
+
741
+ ```typescript
742
+ interface Store<T> {
743
+ /**
744
+ * Gets the current state.
745
+ */
746
+ getState(): T
747
+ /**
748
+ * Sets the state (partial or via updater function).
749
+ */
750
+ setState(partial: Partial<T> | ((state: T) => Partial<T>)): void
751
+ /**
752
+ * Subscribes to state changes.
753
+ * Returns an unsubscribe function.
754
+ */
755
+ subscribe(listener: StateListener<T>): () => void
756
+ /**
757
+ * Destroys the store and cleans up subscriptions.
758
+ */
759
+ destroy(): void
760
+ }
761
+ ```
762
+
763
+ #### `StoreConfig`
764
+
765
+ Configuration for creating a store (initial state, optional name, and middleware chain).
766
+
767
+ ```typescript
768
+ interface StoreConfig<T> {
769
+ /**
770
+ * Initial state value.
771
+ */
772
+ initialState: T
773
+ /**
774
+ * Optional name for debugging.
775
+ */
776
+ name?: string
777
+ /**
778
+ * Optional middleware functions.
779
+ */
780
+ middleware?: StoreMiddleware<T>[]
781
+ }
782
+ ```
783
+
784
+ #### `Theme`
785
+
786
+ Complete theme definition.
787
+
788
+ ```typescript
789
+ interface Theme {
790
+ name: string
791
+ mode: 'light' | 'dark'
792
+ colors: ThemeColors
793
+ breakpoints: ThemeBreakpoints
794
+ spacing: ThemeSpacing
795
+ typography: ThemeTypography
796
+ borderRadius: ThemeBorderRadius
797
+ shadows: ThemeShadows
798
+ transitions: ThemeTransitions
799
+ zIndex: ThemeZIndex
800
+ }
801
+ ```
802
+
803
+ #### `ThemeProviderProps`
804
+
805
+ Props for theme provider component.
806
+
807
+ ```typescript
808
+ interface ThemeProviderProps extends ProviderProps {
809
+ provider: ThemeProvider
810
+ initialTheme?: string
811
+ }
812
+ ```
813
+
814
+ #### `UseAIModelsResult`
815
+
816
+ Result returned by `useAIModels`.
817
+
818
+ ```typescript
819
+ interface UseAIModelsResult {
820
+ /** Available models, or an empty array while loading. */
821
+ models: AppModelDefinition[]
822
+ /**
823
+ * Per-mode server default model ids for the requester's tier, or `undefined`
824
+ * while loading or on servers that don't provide them.
825
+ */
826
+ defaults: AppModeModelDefaults | undefined
827
+ /** The single model marked `freeTier: true`, or `undefined`. */
828
+ freeTierModel: AppModelDefinition | undefined
829
+ /** `true` while the initial fetch is in flight. */
830
+ loading: boolean
831
+ /** Error from the initial fetch, or `null`. */
832
+ error: Error | null
833
+ }
834
+ ```
835
+
836
+ #### `UseAuthOptions`
837
+
838
+ Hook options for useAuth.
839
+
840
+ ```typescript
841
+ interface UseAuthOptions {
842
+ /**
843
+ * Whether to automatically refresh the token on mount.
844
+ */
845
+ autoRefresh?: boolean
846
+ }
847
+ ```
848
+
849
+ #### `UseAuthResult`
850
+
851
+ Hook result for useAuth.
852
+
853
+ ```typescript
854
+ interface UseAuthResult<T = unknown> {
855
+ state: AuthState<T>
856
+ login: AuthClient<T>['login']
857
+ logout: AuthClient<T>['logout']
858
+ register: AuthClient<T>['register']
859
+ refresh: AuthClient<T>['refresh']
860
+ setUser: AuthClient<T>['setUser']
861
+ isAuthenticated: boolean
862
+ isLoading: boolean
863
+ user: T | null
864
+ }
865
+ ```
866
+
867
+ #### `UseChangePasswordReturn`
868
+
869
+ Return type for useChangePassword hook.
870
+
871
+ ```typescript
872
+ interface UseChangePasswordReturn {
873
+ status: UsePromiseState<void>['status']
874
+ error: UsePromiseState<void>['error']
875
+ changePassword: (oldPassword: string, newPassword: string) => Promise<void>
876
+ reset: () => void
877
+ }
878
+ ```
879
+
880
+ #### `UseChatOptions`
881
+
882
+ Hook options for useChat.
883
+
884
+ ```typescript
885
+ interface UseChatOptions {
886
+ /** Chat endpoint (e.g., '/projects/123/chat'). */
887
+ endpoint: string
888
+ /** Project ID for context. */
889
+ projectId?: string
890
+ /**
891
+ * Display name of the AI coding agent, interpolated into user-facing chat
892
+ * copy (e.g. the stalled-stream notice). The host passes its own agent brand
893
+ * name; defaults to the neutral `DEFAULT_AGENT_NAME` so the shared hook never
894
+ * names a specific product.
895
+ */
896
+ agentName?: string
897
+ /** Load history on mount. */
898
+ loadOnMount?: boolean
899
+ /** Called when a file is created or modified by a tool call (path + new content). */
900
+ onFileChange?: (path: string, content: string) => void
901
+ /** Called when the AI switches between plan and execute modes. */
902
+ onModeChange?: (mode: 'plan' | 'execute') => void
903
+ /** Called when the backend assigns or confirms a conversation ID. */
904
+ onConversationId?: (id: string) => void
905
+ /** Called for every streaming event — useful for notifications, sounds, etc. */
906
+ onStreamEvent?: (event: ChatStreamEvent) => void
907
+ }
908
+ ```
909
+
910
+ #### `UseChatResult`
911
+
912
+ Hook result for useChat.
913
+
914
+ ```typescript
915
+ interface UseChatResult {
916
+ messages: ChatMessage[]
917
+ isLoading: boolean
918
+ /**
919
+ * True while a backend turn for this conversation streams WITHOUT this client
920
+ * owning the request — a turn started in another tab, by a teammate, or any
921
+ * server-side continuation. Detected from pushed (broadcast) chat events and
922
+ * confirmed/cleared against the server's `streaming` history flag, so the Stop
923
+ * control can stay visible and functional whenever ANY backend turn is live —
924
+ * not only for sends this hook instance made.
925
+ */
926
+ isRemoteStreaming: boolean
927
+ /**
928
+ * Tell the hook a pushed (broadcast) chat event arrived for this conversation.
929
+ * The host (ChatPanel) calls this from its push-channel handler; the hook then
930
+ * confirms against the server's `streaming` flag and, while a remote turn is
931
+ * live, keeps `isRemoteStreaming` true until the server reports it finished.
932
+ */
933
+ noteRemoteStreamEvent: () => void
934
+ error: string | null
935
+ /** Metadata about a limit-related error (for contextual upgrade CTAs). */
936
+ errorMeta: { limitType?: string; requiresSignup?: boolean } | null
937
+ /** Current agent mode — plan (read-only research) or execute (full access). */
938
+ mode: 'plan' | 'execute'
939
+ /**
940
+ * Whether the conversation runs at the provider's fast/priority speed tier
941
+ * (server-persisted per conversation; hydrated from the history load's
942
+ * `fastMode` meta field, when the server provides one). Only meaningful for
943
+ * models that support a fast tier — the server ignores it otherwise.
944
+ */
945
+ fastMode: boolean
946
+ /**
947
+ * Transient label for a background phase (e.g. the post-response verification
948
+ * pass — "Type-checking the API", "Linting"), set by `status` stream events.
949
+ * The UI shows it in place of the spinner's generic rotating messages; `null`
950
+ * when no such phase is active.
951
+ */
952
+ streamingStatus: string | null
953
+ /**
954
+ * Active 5XX backoff-retry countdown, or `null` when none is pending. After a
955
+ * backend server error (HTTP 5XX) the hook does NOT surface a terminal error —
956
+ * it shows this cancelable countdown and, when it elapses, auto-resumes the
957
+ * turn where the user left off (`resume:true`). `secondsRemaining` ticks down
958
+ * once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
959
+ * limit/quota, and signup-required errors never auto-retry.
960
+ */
961
+ retryCountdown: { secondsRemaining: number; attempt: number } | null
962
+ /** Update the local mode state (for instant mode toggle without an AI turn). */
963
+ setMode: (mode: 'plan' | 'execute') => void
964
+ /** Update the local fast-mode state (for instant toggle without an AI turn). */
965
+ setFastMode: (fastMode: boolean) => void
966
+ sendMessage: (
967
+ message: string,
968
+ attachments?: ChatAttachment[],
969
+ options?: SendMessageOptions,
970
+ ) => Promise<void>
971
+ abort: () => void
972
+ /**
973
+ * Cancel a pending 5XX auto-retry. Clears the countdown and surfaces the
974
+ * original error (via `error`) so the user sees why the turn failed.
975
+ */
976
+ cancelRetry: () => void
977
+ clearHistory: () => Promise<void>
978
+ /** Edit the content of a queued (not yet sent) message. */
979
+ editQueuedMessage: (msgId: string, newContent: string) => void
980
+ /** Remove a queued (not yet sent) message from the queue. */
981
+ deleteQueuedMessage: (msgId: string) => void
982
+ /** Remove queued auto-fix messages whose content references the given file path. */
983
+ clearQueuedForFile: (filePath: string) => void
984
+ /**
985
+ * Append an inline transcript card (model / mode / skills / custom notice) as a
986
+ * `role:'system'` card-message in the ONE message store. Used by the host (ChatPanel)
987
+ * to render a TEAMMATE's broadcast `card` event live — this client's OWN cards arrive
988
+ * through the stream and are appended internally. De-duped by the server-assigned id.
989
+ */
990
+ appendCardMessage: (
991
+ id: string,
992
+ timestamp: number,
993
+ card: NonNullable<ChatMessage['cardEvent']>,
994
+ ) => void
995
+ }
996
+ ```
997
+
998
+ #### `UseDeviceResult`
999
+
1000
+ Hook return type.
1001
+
1002
+ ```typescript
1003
+ interface UseDeviceResult {
1004
+ deviceInfo: DeviceInfo
1005
+ screenInfo: ScreenInfo
1006
+ hardwareInfo: HardwareInfo
1007
+ featureSupport: FeatureSupport
1008
+ supports: (feature: keyof FeatureSupport) => boolean
1009
+ isOnline: () => boolean
1010
+ isStandalone: () => boolean
1011
+ language: string
1012
+ languages: string[]
1013
+ }
1014
+ ```
1015
+
1016
+ #### `UseEditorResult`
1017
+
1018
+ Hook result for useEditor.
1019
+
1020
+ ```typescript
1021
+ interface UseEditorResult {
1022
+ tabs: EditorTab[]
1023
+ activeFile: string | null
1024
+ openFile: (file: EditorFile) => void
1025
+ closeFile: (path: string) => void
1026
+ getContent: () => string | null
1027
+ setContent: (path: string, content: string) => void
1028
+ setActiveTab: (path: string) => void
1029
+ mount: EditorProvider['mount']
1030
+ dispose: () => void
1031
+ focus: () => void
1032
+ openDiff: (file: DiffFile) => void
1033
+ closeDiff: () => void
1034
+ pinTab: (path: string) => void
1035
+ addExtraLib: (content: string, filePath: string) => void
1036
+ onFixWithAI: (callback: (request: FixWithAIRequest) => void) => () => void
1037
+ }
1038
+ ```
1039
+
1040
+ #### `UseFormOptions`
1041
+
1042
+ Options for useForm hook.
1043
+
1044
+ ```typescript
1045
+ interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
1046
+ /**
1047
+ * Form provider's createForm function.
1048
+ */
1049
+ createForm: (options: FormOptions<T>) => FormController<T>
1050
+ }
1051
+ ```
1052
+
1053
+ #### `UseFormResult`
1054
+
1055
+ Result of useForm hook.
1056
+
1057
+ ```typescript
1058
+ interface UseFormResult<T extends Record<string, unknown>> {
1059
+ // State
1060
+ formState: FormState<T>
1061
+ isValid: boolean
1062
+ isDirty: boolean
1063
+ isSubmitting: boolean
1064
+
1065
+ // Field methods
1066
+ register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
1067
+ getValue: <K extends keyof T>(name: K) => T[K]
1068
+ setValue: <K extends keyof T>(name: K, value: T[K]) => void
1069
+ getError: (name: keyof T) => string | undefined
1070
+ setError: (name: keyof T, error: string | undefined) => void
1071
+ clearErrors: () => void
1072
+
1073
+ // Form methods
1074
+ handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (event?: React.FormEvent) => void
1075
+ reset: (values?: Partial<T>) => void
1076
+ validate: () => Promise<boolean>
1077
+ }
1078
+ ```
1079
+
1080
+ #### `UseHttpOptions`
1081
+
1082
+ Options for useHttp hook.
1083
+
1084
+ ```typescript
1085
+ interface UseHttpOptions<T> extends RequestConfig {
1086
+ /**
1087
+ * Whether to execute the request immediately on mount.
1088
+ */
1089
+ immediate?: boolean
1090
+ /**
1091
+ * Callback when request succeeds.
1092
+ */
1093
+ onSuccess?: (data: T) => void
1094
+ /**
1095
+ * Callback when request fails.
1096
+ */
1097
+ onError?: (error: Error) => void
1098
+ }
1099
+ ```
1100
+
1101
+ #### `UseHttpResult`
1102
+
1103
+ Result of useHttp hook.
1104
+
1105
+ ```typescript
1106
+ interface UseHttpResult<T> extends UseHttpState<T> {
1107
+ execute: () => Promise<T | null>
1108
+ reset: () => void
1109
+ }
1110
+ ```
1111
+
1112
+ #### `UseHttpState`
1113
+
1114
+ State for async HTTP operations.
1115
+
1116
+ ```typescript
1117
+ interface UseHttpState<T> {
1118
+ data: T | null
1119
+ loading: boolean
1120
+ error: Error | null
1121
+ }
1122
+ ```
1123
+
1124
+ #### `UseLoginReturn`
1125
+
1126
+ Return type for useLogin hook.
1127
+
1128
+ ```typescript
1129
+ interface UseLoginReturn<T = unknown> {
1130
+ status: UsePromiseState<AuthResult<T>>['status']
1131
+ value: UsePromiseState<AuthResult<T>>['value']
1132
+ error: UsePromiseState<AuthResult<T>>['error']
1133
+ login: (credentials: LoginCredentials) => Promise<AuthResult<T>>
1134
+ reset: () => void
1135
+ }
1136
+ ```
1137
+
1138
+ #### `UseOAuthReturn`
1139
+
1140
+ Return type for useOAuth hook.
1141
+
1142
+ ```typescript
1143
+ interface UseOAuthReturn {
1144
+ providers: string[]
1145
+ getOAuthUrl: (provider: string) => string
1146
+ /** Full-page redirect to the provider (default). The opener page navigates away. */
1147
+ redirect: (provider: string) => void
1148
+ /**
1149
+ * Open the provider in a popup so the opener page does NOT navigate. On success
1150
+ * the session is established in the opener in place and `config.onSuccess` fires;
1151
+ * on failure `config.onError` fires. Falls back to a full-page {@link redirect}
1152
+ * when the popup is blocked.
1153
+ */
1154
+ loginViaPopup: (provider: string) => void
1155
+ }
1156
+ ```
1157
+
1158
+ #### `UsePasswordResetReturn`
1159
+
1160
+ Return type for usePasswordReset hook.
1161
+
1162
+ ```typescript
1163
+ interface UsePasswordResetReturn {
1164
+ requestStatus: UsePromiseState<void>['status']
1165
+ requestError: UsePromiseState<void>['error']
1166
+ confirmStatus: UsePromiseState<void>['status']
1167
+ confirmError: UsePromiseState<void>['error']
1168
+ requestReset: (data: PasswordResetRequest) => Promise<void>
1169
+ confirmReset: (data: PasswordResetConfirm) => Promise<void>
1170
+ reset: () => void
1171
+ }
1172
+ ```
1173
+
1174
+ #### `UsePlatformResult`
1175
+
1176
+ Hook return type.
1177
+
1178
+ ```typescript
1179
+ interface UsePlatformResult {
1180
+ platform: Platform
1181
+ isNative: boolean
1182
+ isMobile: boolean
1183
+ isDesktop: boolean
1184
+ isWeb: boolean
1185
+ isDevelopment: boolean
1186
+ isProduction: boolean
1187
+ isPlatform: (...platforms: Platform[]) => boolean
1188
+ }
1189
+ ```
1190
+
1191
+ #### `UsePreviewResult`
1192
+
1193
+ Hook result for usePreview.
1194
+
1195
+ ```typescript
1196
+ interface UsePreviewResult {
1197
+ state: PreviewState
1198
+ setUrl: (url: string) => void
1199
+ refresh: () => void
1200
+ setDevice: (device: DeviceFrame) => void
1201
+ openExternal: () => void
1202
+ /**
1203
+ * Records a navigation the running preview reported via its `molecule:navigate`
1204
+ * message — updates the displayed current location without reloading the iframe.
1205
+ * Pass `isReplace` when the preview REPLACED its current history entry (a
1206
+ * `replaceState` redirect/canonicalization) so the forward stack is preserved
1207
+ * instead of truncated (a `pushState`, the default, truncates forward).
1208
+ */
1209
+ recordNavigation: (url: string, isReplace?: boolean) => void
1210
+ /** Navigates the preview to the previous navigation-history entry (Back). */
1211
+ back: () => void
1212
+ /** Navigates the preview to the next navigation-history entry (Forward). */
1213
+ forward: () => void
1214
+ }
1215
+ ```
1216
+
1217
+ #### `UsePromiseState`
1218
+
1219
+ Extended promise state with actions.
1220
+
1221
+ ```typescript
1222
+ interface UsePromiseState<T> {
1223
+ status: PromiseStatus
1224
+ value: T | null
1225
+ error: Error | null
1226
+ cancel: (message?: string) => void
1227
+ reset: () => void
1228
+ }
1229
+ ```
1230
+
1231
+ #### `UsePushOptions`
1232
+
1233
+ Options for the usePush hook (e.g. check permission on mount).
1234
+
1235
+ ```typescript
1236
+ interface UsePushOptions {
1237
+ /**
1238
+ * Whether to check permission status on mount.
1239
+ */
1240
+ checkOnMount?: boolean
1241
+ }
1242
+ ```
1243
+
1244
+ #### `UsePushResult`
1245
+
1246
+ Hook return type.
1247
+
1248
+ ```typescript
1249
+ interface UsePushResult {
1250
+ permission: PermissionStatus | null
1251
+ token: PushToken | null
1252
+ checkPermission: () => Promise<PermissionStatus>
1253
+ requestPermission: () => Promise<PermissionStatus>
1254
+ register: (options?: PushRegisterOptions) => Promise<PushToken>
1255
+ unregister: () => Promise<void>
1256
+ onNotificationReceived: (listener: NotificationReceivedListener) => () => void
1257
+ onNotificationAction: (listener: NotificationActionListener) => () => void
1258
+ onTokenChange: (listener: TokenChangeListener) => () => void
1259
+ setBadge: (count: number) => Promise<void>
1260
+ clearBadge: () => Promise<void>
1261
+ }
1262
+ ```
1263
+
1264
+ #### `UseRouterResult`
1265
+
1266
+ Hook result for useRouter.
1267
+
1268
+ ```typescript
1269
+ interface UseRouterResult {
1270
+ location: Router['getLocation'] extends () => infer R ? R : never
1271
+ params: Record<string, string>
1272
+ query: QueryParams
1273
+ navigate: Router['navigate']
1274
+ navigateTo: Router['navigateTo']
1275
+ back: Router['back']
1276
+ forward: Router['forward']
1277
+ isActive: Router['isActive']
1278
+ }
1279
+ ```
1280
+
1281
+ #### `UseSignupReturn`
1282
+
1283
+ Return type for useSignup hook.
1284
+
1285
+ ```typescript
1286
+ interface UseSignupReturn<T = unknown> {
1287
+ status: UsePromiseState<AuthResult<T>>['status']
1288
+ value: UsePromiseState<AuthResult<T>>['value']
1289
+ error: UsePromiseState<AuthResult<T>>['error']
1290
+ signup: (data: RegisterData) => Promise<AuthResult<T>>
1291
+ reset: () => void
1292
+ }
1293
+ ```
1294
+
1295
+ #### `UseStorageValueOptions`
1296
+
1297
+ Options for useStorageValue hook.
1298
+
1299
+ ```typescript
1300
+ interface UseStorageValueOptions<T> {
1301
+ /**
1302
+ * Default value if key doesn't exist.
1303
+ */
1304
+ defaultValue?: T
1305
+ /**
1306
+ * Whether to sync across tabs/windows (if supported by storage provider).
1307
+ */
1308
+ sync?: boolean
1309
+ }
1310
+ ```
1311
+
1312
+ #### `UseStorageValueResult`
1313
+
1314
+ Result of useStorageValue hook.
1315
+
1316
+ ```typescript
1317
+ interface UseStorageValueResult<T> {
1318
+ value: T | undefined
1319
+ setValue: (value: T) => Promise<void>
1320
+ removeValue: () => Promise<void>
1321
+ loading: boolean
1322
+ error: Error | null
1323
+ }
1324
+ ```
1325
+
1326
+ #### `UseStoreOptions`
1327
+
1328
+ Hook options for useStore.
1329
+
1330
+ ```typescript
1331
+ interface UseStoreOptions<T, S> {
1332
+ selector?: (state: T) => S
1333
+ equalityFn?: (a: S, b: S) => boolean
1334
+ }
1335
+ ```
1336
+
1337
+ #### `UseThemeResult`
1338
+
1339
+ Hook result for useTheme.
1340
+
1341
+ ```typescript
1342
+ interface UseThemeResult {
1343
+ theme: Theme
1344
+ themeName: string
1345
+ setTheme: (name: string) => void
1346
+ toggleTheme: () => void
1347
+ mode: 'light' | 'dark'
1348
+ }
1349
+ ```
1350
+
1351
+ #### `UseTranslationResult`
1352
+
1353
+ Hook result for useTranslation.
1354
+
1355
+ ```typescript
1356
+ interface UseTranslationResult {
1357
+ t: I18nProvider['t']
1358
+ locale: string
1359
+ setLocale: I18nProvider['setLocale']
1360
+ locales: ReturnType<I18nProvider['getLocales']>
1361
+ formatNumber: I18nProvider['formatNumber']
1362
+ formatDate: I18nProvider['formatDate']
1363
+ direction: 'ltr' | 'rtl'
1364
+ }
1365
+ ```
1366
+
1367
+ #### `UseVersionResult`
1368
+
1369
+ Hook return type.
1370
+
1371
+ ```typescript
1372
+ interface UseVersionResult {
1373
+ state: VersionState
1374
+ isUpdateAvailable: boolean
1375
+ isChecking: boolean
1376
+ isServiceWorkerWaiting: boolean
1377
+ newVersion: string | undefined
1378
+ checkForUpdates: () => Promise<boolean>
1379
+ applyUpdate: (options?: { force?: boolean }) => void
1380
+ dismissUpdate: () => void
1381
+ startPeriodicChecks: (options?: UpdateCheckOptions) => void
1382
+ stopPeriodicChecks: () => void
1383
+ }
1384
+ ```
1385
+
1386
+ #### `UseWorkspaceResult`
1387
+
1388
+ Hook result for useWorkspace.
1389
+
1390
+ ```typescript
1391
+ interface UseWorkspaceResult {
1392
+ layout: WorkspaceLayout
1393
+ activePanel: PanelId | null
1394
+ collapsedPanels: Set<PanelId>
1395
+ togglePanel: (panelId: PanelId) => void
1396
+ resizePanel: (panelId: PanelId, size: number) => void
1397
+ setActivePanel: (panelId: PanelId) => void
1398
+ resetLayout: () => void
1399
+ }
1400
+ ```
1401
+
1402
+ #### `WorkspaceProviderProps`
1403
+
1404
+ Props for workspace provider component.
1405
+
1406
+ ```typescript
1407
+ interface WorkspaceProviderProps extends ProviderProps {
1408
+ provider: WorkspaceProvider
1409
+ }
1410
+ ```
1411
+
1412
+ ### Types
1413
+
1414
+ #### `AsyncExtendState`
1415
+
1416
+ Async-capable extendState function for partial updates.
1417
+
1418
+ ```typescript
1419
+ type AsyncExtendState<T> = (
1420
+ partial: Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
1421
+ ) => void
1422
+ ```
1423
+
1424
+ #### `AsyncSetState`
1425
+
1426
+ Async-capable setState function.
1427
+
1428
+ ```typescript
1429
+ type AsyncSetState<T> = (value: T | ((prev: T) => T) | Promise<T | ((prev: T) => T)>) => void
1430
+ ```
1431
+
1432
+ #### `UseCapacitorAppResult`
1433
+
1434
+ Hook return type.
1435
+
1436
+ ```typescript
1437
+ type UseCapacitorAppResult = CapacitorAppState & {
1438
+ initialize: () => Promise<void>
1439
+ }
1440
+ ```
1441
+
1442
+ ### Functions
1443
+
1444
+ #### `AuthProvider(props)`
1445
+
1446
+ Provider for authentication.
1447
+
1448
+ ```typescript
1449
+ function AuthProvider({
1450
+ client,
1451
+ children,
1452
+ }: AuthProviderProps<T>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1453
+ ```
1454
+
1455
+ - `props` — Component props (see {@link AuthProviderProps}).
1456
+
1457
+ **Returns:** The rendered auth provider element.
1458
+
1459
+ #### `ChatProvider(props)`
1460
+
1461
+ Provider for AI chat.
1462
+
1463
+ ```typescript
1464
+ function ChatProvider({
1465
+ provider,
1466
+ children,
1467
+ }: ChatProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1468
+ ```
1469
+
1470
+ - `props` — Component props (see {@link ChatProviderProps}).
1471
+
1472
+ **Returns:** The rendered chat provider element.
1473
+
1474
+ #### `EditorProvider(props)`
1475
+
1476
+ Provider for code editor.
1477
+
1478
+ ```typescript
1479
+ function EditorProvider({
1480
+ provider,
1481
+ children,
1482
+ }: EditorProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1483
+ ```
1484
+
1485
+ - `props` — Component props (see {@link EditorProviderProps}).
1486
+
1487
+ **Returns:** The rendered editor provider element.
1488
+
1489
+ #### `HttpProvider(props)`
1490
+
1491
+ Provider for HTTP client.
1492
+
1493
+ ```typescript
1494
+ function HttpProvider({
1495
+ client,
1496
+ children,
1497
+ }: HttpProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1498
+ ```
1499
+
1500
+ - `props` — Component props (see {@link HttpProviderProps}).
1501
+
1502
+ **Returns:** The rendered HTTP provider element.
1503
+
1504
+ #### `I18nProvider(props)`
1505
+
1506
+ Provider for internationalization.
1507
+
1508
+ ```typescript
1509
+ function I18nProvider({
1510
+ provider,
1511
+ children,
1512
+ }: I18nProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1513
+ ```
1514
+
1515
+ - `props` — Component props (see {@link I18nProviderProps}).
1516
+
1517
+ **Returns:** The rendered i18n provider element.
1518
+
1519
+ #### `LoggerProvider(props)`
1520
+
1521
+ Provider for logging.
1522
+
1523
+ ```typescript
1524
+ function LoggerProvider({
1525
+ provider,
1526
+ children,
1527
+ }: LoggerProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1528
+ ```
1529
+
1530
+ - `props` — Component props (see {@link LoggerProviderProps}).
1531
+
1532
+ **Returns:** The rendered logger provider element.
1533
+
1534
+ #### `MoleculeProvider(props)`
1535
+
1536
+ Combined provider for all molecule services.
1537
+
1538
+ Provides a convenient way to wrap your app with all molecule providers at once.
1539
+ Only providers that are passed will be included.
1540
+
1541
+ ```typescript
1542
+ function MoleculeProvider({
1543
+ children,
1544
+ state,
1545
+ auth,
1546
+ theme,
1547
+ router,
1548
+ i18n,
1549
+ http,
1550
+ storage,
1551
+ logger,
1552
+ chat,
1553
+ workspace,
1554
+ editor,
1555
+ preview,
1556
+ }: MoleculeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1557
+ ```
1558
+
1559
+ - `props` — Component props (see {@link MoleculeProviderProps}) — each service is optional, and ONLY the services passed are provided to the tree.
1560
+
1561
+ **Returns:** The rendered combined provider element.
1562
+
1563
+ #### `PreviewProvider(props)`
1564
+
1565
+ Provider for live preview.
1566
+
1567
+ ```typescript
1568
+ function PreviewProvider({
1569
+ provider,
1570
+ children,
1571
+ }: PreviewProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1572
+ ```
1573
+
1574
+ - `props` — Component props (see {@link PreviewProviderProps}).
1575
+
1576
+ **Returns:** The rendered preview provider element.
1577
+
1578
+ #### `resetAIModelsCache()`
1579
+
1580
+ Test-only: drops every cached model list so the next `useAIModels` call
1581
+ refetches. Exposed for unit tests; do not call from production code.
1582
+
1583
+ ```typescript
1584
+ function resetAIModelsCache(): void
1585
+ ```
1586
+
1587
+ #### `resetChatStoresForTests()`
1588
+
1589
+ Test-only: clear all conversation stores. The store is module-level (it must
1590
+ outlive component mounts), so it persists across test cases — reset it in a
1591
+ `beforeEach` the same way tests clear `sessionStorage`.
1592
+
1593
+ ```typescript
1594
+ function resetChatStoresForTests(): void
1595
+ ```
1596
+
1597
+ #### `RouterProvider(props)`
1598
+
1599
+ Provider for routing.
1600
+
1601
+ ```typescript
1602
+ function RouterProvider({
1603
+ router,
1604
+ children,
1605
+ }: RouterProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1606
+ ```
1607
+
1608
+ - `props` — Component props (see {@link RouterProviderProps}).
1609
+
1610
+ **Returns:** The rendered router provider element.
1611
+
1612
+ #### `StateProvider(props)`
1613
+
1614
+ Provider for state management.
1615
+
1616
+ ```typescript
1617
+ function StateProvider({
1618
+ provider,
1619
+ children,
1620
+ }: StateProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1621
+ ```
1622
+
1623
+ - `props` — Component props (see {@link StateProviderProps}).
1624
+
1625
+ **Returns:** The rendered state provider element.
1626
+
1627
+ #### `StorageProvider(props)`
1628
+
1629
+ Provider for storage.
1630
+
1631
+ ```typescript
1632
+ function StorageProvider({
1633
+ provider,
1634
+ children,
1635
+ }: StorageProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1636
+ ```
1637
+
1638
+ - `props` — Component props (see {@link StorageProviderProps}).
1639
+
1640
+ **Returns:** The rendered storage provider element.
1641
+
1642
+ #### `ThemeProvider(props)`
1643
+
1644
+ Provider for theming.
1645
+
1646
+ ```typescript
1647
+ function ThemeProvider({
1648
+ provider,
1649
+ children,
1650
+ }: ThemeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1651
+ ```
1652
+
1653
+ - `props` — Component props (see {@link ThemeProviderProps}).
1654
+
1655
+ **Returns:** The rendered theme provider element.
1656
+
1657
+ #### `useAIModels(projectId)`
1658
+
1659
+ Subscribes to the cached AI model catalog. The first mount of a scope
1660
+ triggers a single `GET /ai/models` fetch; subsequent mounts return the
1661
+ cached result.
1662
+
1663
+ ```typescript
1664
+ function useAIModels(projectId?: string): UseAIModelsResult
1665
+ ```
1666
+
1667
+ - `projectId` — Optional project scope: includes that project's custom ("bring your own AI") models on servers that support them.
1668
+
1669
+ **Returns:** Models, free-tier model, loading flag, and error.
1670
+
1671
+ #### `useAsyncState(initialState)`
1672
+
1673
+ Hook like useState but accepts Promises and supports partial state extension.
1674
+
1675
+ ```typescript
1676
+ function useAsyncState(initialState: T): [T, AsyncSetState<T>, AsyncExtendState<T>]
1677
+ ```
1678
+
1679
+ - `initialState` — Initial state value
1680
+
1681
+ **Returns:** Tuple of [state, asyncSetState, asyncExtendState]
1682
+
1683
+ #### `useAuth(options)`
1684
+
1685
+ Hook for authentication state and actions.
1686
+
1687
+ ```typescript
1688
+ function useAuth(options?: UseAuthOptions): UseAuthResult<T>
1689
+ ```
1690
+
1691
+ - `options` — Hook options
1692
+
1693
+ **Returns:** Auth state and action methods
1694
+
1695
+ #### `useAuthClient()`
1696
+
1697
+ Hook to access the auth client from context.
1698
+
1699
+ ```typescript
1700
+ function useAuthClient(): AuthClient<T>
1701
+ ```
1702
+
1703
+ **Returns:** The auth client from context
1704
+
1705
+ #### `useCapacitorApp(options)`
1706
+
1707
+ Hook for Capacitor app initialization and state management.
1708
+
1709
+ Creates a `CapacitorApp` coordinator on mount, subscribes to state changes,
1710
+ and auto-initializes. Cleans up listeners on unmount via `destroy()`.
1711
+
1712
+ ```typescript
1713
+ function useCapacitorApp(options?: CapacitorAppOptions): UseCapacitorAppResult
1714
+ ```
1715
+
1716
+ - `options` — Capacitor app configuration options
1717
+
1718
+ **Returns:** Current app state and an `initialize` function for manual re-initialization
1719
+
1720
+ #### `useChangePassword()`
1721
+
1722
+ Hook for changing password with async state tracking.
1723
+
1724
+ ```typescript
1725
+ function useChangePassword(): UseChangePasswordReturn
1726
+ ```
1727
+
1728
+ **Returns:** Change password state and action
1729
+
1730
+ #### `useChat(options)`
1731
+
1732
+ Hook for AI chat with streaming support.
1733
+
1734
+ Manages message state, sends messages to the backend, and handles
1735
+ SSE streaming responses.
1736
+
1737
+ ```typescript
1738
+ function useChat(options: UseChatOptions): UseChatResult
1739
+ ```
1740
+
1741
+ - `options` — Chat configuration including endpoint URL, project ID, and whether to load history on mount.
1742
+
1743
+ **Returns:** Chat state and controls: messages, isLoading, error, sendMessage, abort, and clearHistory.
1744
+
1745
+ #### `useChatProvider()`
1746
+
1747
+ Access the chat provider from context.
1748
+
1749
+ ```typescript
1750
+ function useChatProvider(): ChatProvider
1751
+ ```
1752
+
1753
+ **Returns:** The ChatProvider instance from the nearest ChatContext.
1754
+
1755
+ #### `useChildLogger(parentName, context)`
1756
+
1757
+ Hook to create a child logger with additional context.
1758
+
1759
+ ```typescript
1760
+ function useChildLogger(parentName: string, context: Record<string, unknown>): Logger
1761
+ ```
1762
+
1763
+ - `parentName` — Parent logger name
1764
+ - `context` — Additional context to include in logs
1765
+
1766
+ **Returns:** Child logger instance
1767
+
1768
+ #### `useCurrentTheme()`
1769
+
1770
+ Hook to get just the current theme object.
1771
+
1772
+ ```typescript
1773
+ function useCurrentTheme(): Theme
1774
+ ```
1775
+
1776
+ **Returns:** The current theme
1777
+
1778
+ #### `useDelete(url, options)`
1779
+
1780
+ Hook for DELETE requests.
1781
+
1782
+ ```typescript
1783
+ function useDelete(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1784
+ ```
1785
+
1786
+ - `url` — Request URL of the resource to delete.
1787
+ - `options` — HTTP request options including callbacks.
1788
+
1789
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1790
+
1791
+ #### `useDevice()`
1792
+
1793
+ Hook for device information.
1794
+
1795
+ Uses module-level `getProvider()` — device info is a singleton, not context-provided.
1796
+ Device info is static and doesn't change at runtime, so this uses `useMemo`.
1797
+
1798
+ ```typescript
1799
+ function useDevice(): UseDeviceResult
1800
+ ```
1801
+
1802
+ **Returns:** Device information and utility methods
1803
+
1804
+ #### `useDirection()`
1805
+
1806
+ Hook to get the text direction.
1807
+
1808
+ ```typescript
1809
+ function useDirection(): 'ltr' | 'rtl'
1810
+ ```
1811
+
1812
+ **Returns:** The text direction ('ltr' or 'rtl')
1813
+
1814
+ #### `useEditor()`
1815
+
1816
+ Hook for code editor management.
1817
+
1818
+ ```typescript
1819
+ function useEditor(): UseEditorResult
1820
+ ```
1821
+
1822
+ **Returns:** Editor state and controls: tabs, activeFile, openFile, closeFile, getContent, setContent, setActiveTab, mount, dispose, and focus.
1823
+
1824
+ #### `useEditorProvider()`
1825
+
1826
+ Access the editor provider from context.
1827
+
1828
+ ```typescript
1829
+ function useEditorProvider(): EditorProvider
1830
+ ```
1831
+
1832
+ **Returns:** The EditorProvider instance from the nearest EditorContext.
1833
+
1834
+ #### `useFieldState(form, name)`
1835
+
1836
+ Hook to get field-level state.
1837
+
1838
+ ```typescript
1839
+ function useFieldState(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>
1840
+ ```
1841
+
1842
+ - `form` — Form controller
1843
+ - `name` — Field name
1844
+
1845
+ **Returns:** Field state (value, error, touched, dirty, valid)
1846
+
1847
+ #### `useForm(options)`
1848
+
1849
+ Hook for form state management.
1850
+
1851
+ ```typescript
1852
+ function useForm(options: UseFormOptions<T>): UseFormResult<T>
1853
+ ```
1854
+
1855
+ - `options` — Form options including createForm from a forms provider
1856
+
1857
+ **Returns:** Form state and methods
1858
+
1859
+ #### `useGet(url, options)`
1860
+
1861
+ Hook for GET requests.
1862
+
1863
+ ```typescript
1864
+ function useGet(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1865
+ ```
1866
+
1867
+ - `url` — Request URL to fetch from.
1868
+ - `options` — HTTP request options including callbacks and request config.
1869
+
1870
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1871
+
1872
+ #### `useHttp(method, url, options)`
1873
+
1874
+ Hook for making HTTP requests with state management.
1875
+
1876
+ ```typescript
1877
+ function useHttp(
1878
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
1879
+ url: string,
1880
+ options?: UseHttpOptions<T>,
1881
+ ): UseHttpResult<T>
1882
+ ```
1883
+
1884
+ - `method` — HTTP method
1885
+ - `url` — Request URL
1886
+ - `options` — Request options
1887
+
1888
+ **Returns:** Request state and execute function
1889
+
1890
+ #### `useHttpClient()`
1891
+
1892
+ Hook to access the HTTP client from context.
1893
+
1894
+ ```typescript
1895
+ function useHttpClient(): HttpClient
1896
+ ```
1897
+
1898
+ **Returns:** The HTTP client from context
1899
+
1900
+ #### `useI18nError(error)`
1901
+
1902
+ Translates an error at render time so the displayed message updates automatically
1903
+ when the locale changes.
1904
+
1905
+ **Always use this hook to display errors in React components** — accessing
1906
+ `error.message` directly bypasses re-translation and leaves stale text after a
1907
+ locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
1908
+ its key is translated using the current locale. For plain `Error` instances,
1909
+ `error.message` is returned unchanged.
1910
+
1911
+ ```typescript
1912
+ function useI18nError(error: Error | null | undefined): string | null
1913
+ ```
1914
+
1915
+ - `error` — The error to translate, or `null`/`undefined`.
1916
+
1917
+ **Returns:** The translated error string, or `null` if no error.
1918
+
1919
+ #### `useI18nProvider()`
1920
+
1921
+ Hook to access the i18n provider from context.
1922
+
1923
+ ```typescript
1924
+ function useI18nProvider(): I18nProvider
1925
+ ```
1926
+
1927
+ **Returns:** The i18n provider from context
1928
+
1929
+ #### `useIsActive(path, exact)`
1930
+
1931
+ Hook to check if a path is active.
1932
+
1933
+ ```typescript
1934
+ function useIsActive(path: string, exact?: boolean): boolean
1935
+ ```
1936
+
1937
+ - `path` — The path to check
1938
+ - `exact` — Whether to match exactly (default: false)
1939
+
1940
+ **Returns:** Whether the path is active
1941
+
1942
+ #### `useIsAuthenticated()`
1943
+
1944
+ Hook to check if user is authenticated.
1945
+
1946
+ ```typescript
1947
+ function useIsAuthenticated(): boolean
1948
+ ```
1949
+
1950
+ **Returns:** Whether the user is authenticated
1951
+
1952
+ #### `useLocale()`
1953
+
1954
+ Hook to get the current locale.
1955
+
1956
+ ```typescript
1957
+ function useLocale(): string
1958
+ ```
1959
+
1960
+ **Returns:** The current locale code
1961
+
1962
+ #### `useLocation()`
1963
+
1964
+ Hook to get the current location.
1965
+
1966
+ ```typescript
1967
+ function useLocation(): RouteLocation
1968
+ ```
1969
+
1970
+ **Returns:** The current route location
1971
+
1972
+ #### `useLogger(name, config)`
1973
+
1974
+ Hook to get a logger instance.
1975
+
1976
+ ```typescript
1977
+ function useLogger(name: string, config?: Partial<LoggerConfig>): Logger
1978
+ ```
1979
+
1980
+ - `name` — Logger name (usually component or module name)
1981
+ - `config` — Optional logger configuration
1982
+
1983
+ **Returns:** Logger instance
1984
+
1985
+ #### `useLoggerProvider()`
1986
+
1987
+ Hook to access the logger provider from context.
1988
+
1989
+ ```typescript
1990
+ function useLoggerProvider(): LoggerProvider
1991
+ ```
1992
+
1993
+ **Returns:** The logger provider from context
1994
+
1995
+ #### `useLogin()`
1996
+
1997
+ Hook for login with async state tracking.
1998
+
1999
+ ```typescript
2000
+ function useLogin(): UseLoginReturn<T>
2001
+ ```
2002
+
2003
+ **Returns:** Login state and action
2004
+
2005
+ #### `useNavigate()`
2006
+
2007
+ Hook to get the navigate function.
2008
+
2009
+ ```typescript
2010
+ function useNavigate(): (path: string, options?: NavigateOptions) => void
2011
+ ```
2012
+
2013
+ **Returns:** The navigate function
2014
+
2015
+ #### `useOAuth(config)`
2016
+
2017
+ Hook for OAuth authentication.
2018
+
2019
+ Reads OAuth configuration from the provided config and provides
2020
+ helpers to build OAuth URLs and start a login (full-page or popup).
2021
+ Automatically handles OAuth callbacks by detecting `code` and `state`
2022
+ URL parameters and exchanging them for a session — and, when the callback is
2023
+ running inside a popup we opened, relaying the result to the opener instead.
2024
+
2025
+ ```typescript
2026
+ function useOAuth(config?: {
2027
+ baseURL?: string
2028
+ oauthProviders?: string[]
2029
+ oauthEndpoint?: string
2030
+ loginEndpoint?: string
2031
+ onSuccess?: () => void
2032
+ onError?: (error: string) => void
2033
+ }): UseOAuthReturn
2034
+ ```
2035
+
2036
+ - `config` — Optional OAuth configuration override.
2037
+ - `config.baseURL` — Base URL for the API server (e.g. "https://api.example.com").
2038
+ - `config.oauthProviders` — List of supported OAuth provider names (e.g. ["google", "github"]).
2039
+ - `config.oauthEndpoint` — Path prefix for OAuth routes (defaults to "/oauth").
2040
+ - `config.loginEndpoint` — Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
2041
+ - `config.onSuccess` — Callback after successful OAuth login.
2042
+ - `config.onError` — Callback on OAuth login failure.
2043
+
2044
+ **Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
2045
+
2046
+ #### `useParams()`
2047
+
2048
+ Hook to get route parameters.
2049
+
2050
+ ```typescript
2051
+ function useParams(): T
2052
+ ```
2053
+
2054
+ **Returns:** The current route parameters
2055
+
2056
+ #### `usePasswordReset()`
2057
+
2058
+ Hook for password reset flow with async state tracking.
2059
+
2060
+ Provides separate tracking for the request and confirm steps.
2061
+
2062
+ ```typescript
2063
+ function usePasswordReset(): UsePasswordResetReturn
2064
+ ```
2065
+
2066
+ **Returns:** Password reset state and actions
2067
+
2068
+ #### `usePatch(url, options)`
2069
+
2070
+ Hook for PATCH requests.
2071
+
2072
+ ```typescript
2073
+ function usePatch(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2074
+ ```
2075
+
2076
+ - `url` — Request URL to send the PATCH request to.
2077
+ - `options` — HTTP request options including partial body data and callbacks.
2078
+
2079
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
2080
+
2081
+ #### `usePlatform()`
2082
+
2083
+ Hook for platform detection.
2084
+
2085
+ Uses module-level functions — platform is a singleton, not context-provided.
2086
+ Platform info is static and doesn't change at runtime, so this uses `useMemo`.
2087
+
2088
+ ```typescript
2089
+ function usePlatform(): UsePlatformResult
2090
+ ```
2091
+
2092
+ **Returns:** Platform information and utility methods
2093
+
2094
+ #### `usePost(url, options)`
2095
+
2096
+ Hook for POST requests.
2097
+
2098
+ ```typescript
2099
+ function usePost(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2100
+ ```
2101
+
2102
+ - `url` — Request URL to post to.
2103
+ - `options` — HTTP request options including body data and callbacks.
2104
+
2105
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
2106
+
2107
+ #### `usePreview()`
2108
+
2109
+ Hook for live preview management.
2110
+
2111
+ ```typescript
2112
+ function usePreview(): UsePreviewResult
2113
+ ```
2114
+
2115
+ **Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
2116
+
2117
+ #### `usePreviewProvider()`
2118
+
2119
+ Access the preview provider from context.
2120
+
2121
+ ```typescript
2122
+ function usePreviewProvider(): PreviewProvider
2123
+ ```
2124
+
2125
+ **Returns:** The PreviewProvider instance from the nearest PreviewContext.
2126
+
2127
+ #### `usePromise(asyncFn)`
2128
+
2129
+ Hook that wraps an async function with state tracking.
2130
+
2131
+ ```typescript
2132
+ function usePromise(
2133
+ asyncFn: T,
2134
+ ): [
2135
+ UsePromiseState<Awaited<ReturnType<T>>>,
2136
+ (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>,
2137
+ ]
2138
+ ```
2139
+
2140
+ - `asyncFn` — The async function to wrap
2141
+
2142
+ **Returns:** Tuple of [state, wrappedFunction]
2143
+
2144
+ #### `usePush(options)`
2145
+
2146
+ Hook for push notification state and actions.
2147
+
2148
+ Uses module-level `getProvider()` — push is a singleton, not context-provided.
2149
+
2150
+ ```typescript
2151
+ function usePush(options?: UsePushOptions): UsePushResult
2152
+ ```
2153
+
2154
+ - `options` — Hook options
2155
+
2156
+ **Returns:** Push notification state and action methods
2157
+
2158
+ #### `usePut(url, options)`
2159
+
2160
+ Hook for PUT requests.
2161
+
2162
+ ```typescript
2163
+ function usePut(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2164
+ ```
2165
+
2166
+ - `url` — Request URL to send the PUT request to.
2167
+ - `options` — HTTP request options including body data and callbacks.
2168
+
2169
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
2170
+
2171
+ #### `useQuery()`
2172
+
2173
+ Hook to get query parameters.
2174
+
2175
+ ```typescript
2176
+ function useQuery(): T
2177
+ ```
2178
+
2179
+ **Returns:** The current query parameters
2180
+
2181
+ #### `useRootLogger()`
2182
+
2183
+ Hook to get the root logger.
2184
+
2185
+ ```typescript
2186
+ function useRootLogger(): Logger
2187
+ ```
2188
+
2189
+ **Returns:** Root logger instance
2190
+
2191
+ #### `useRouter()`
2192
+
2193
+ Hook for routing state and actions.
2194
+
2195
+ ```typescript
2196
+ function useRouter(): UseRouterResult
2197
+ ```
2198
+
2199
+ **Returns:** Router state and navigation methods
2200
+
2201
+ #### `useRouterInstance()`
2202
+
2203
+ Hook to access the router from context.
2204
+
2205
+ ```typescript
2206
+ function useRouterInstance(): Router
2207
+ ```
2208
+
2209
+ **Returns:** The router from context
2210
+
2211
+ #### `useSetStore(store)`
2212
+
2213
+ Hook to get the store's setState function.
2214
+
2215
+ ```typescript
2216
+ function useSetStore(store: Store<T>): (partial: Partial<T> | ((state: T) => Partial<T>)) => void
2217
+ ```
2218
+
2219
+ - `store` — The store to get setState from
2220
+
2221
+ **Returns:** The setState function
2222
+
2223
+ #### `useSignup()`
2224
+
2225
+ Hook for user registration with async state tracking.
2226
+
2227
+ ```typescript
2228
+ function useSignup(): UseSignupReturn<T>
2229
+ ```
2230
+
2231
+ **Returns:** Signup state and action
2232
+
2233
+ #### `useStateProvider()`
2234
+
2235
+ Hook to access the state provider from context.
2236
+
2237
+ ```typescript
2238
+ function useStateProvider(): StateProvider
2239
+ ```
2240
+
2241
+ **Returns:** The state provider from context
2242
+
2243
+ #### `useStorage()`
2244
+
2245
+ Hook for simple storage operations without React state sync.
2246
+
2247
+ ```typescript
2248
+ function useStorage(): {
2249
+ get: <T>(key: string) => Promise<T | null>
2250
+ set: <T>(key: string, value: T) => Promise<void>
2251
+ remove: (key: string) => Promise<void>
2252
+ clear: () => Promise<void>
2253
+ keys: () => Promise<string[]>
2254
+ }
2255
+ ```
2256
+
2257
+ **Returns:** Storage operation methods
2258
+
2259
+ #### `useStorageProvider()`
2260
+
2261
+ Hook to access the storage provider from context.
2262
+
2263
+ ```typescript
2264
+ function useStorageProvider(): StorageProvider
2265
+ ```
2266
+
2267
+ **Returns:** The storage provider from context
2268
+
2269
+ #### `useStorageValue(key, options)`
2270
+
2271
+ Hook to manage a single storage value with React state sync.
2272
+
2273
+ ```typescript
2274
+ function useStorageValue(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>
2275
+ ```
2276
+
2277
+ - `key` — Storage key
2278
+ - `options` — Hook options
2279
+
2280
+ **Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
2281
+
2282
+ #### `useStore(store, options)`
2283
+
2284
+ Hook to subscribe to a store with optional selector and equality function.
2285
+
2286
+ ```typescript
2287
+ function useStore(store: Store<T>, options?: UseStoreOptions<T, S>): S
2288
+ ```
2289
+
2290
+ - `store` — The store to subscribe to
2291
+ - `options` — Hook options (selector, equalityFn)
2292
+
2293
+ **Returns:** The selected state
2294
+
2295
+ #### `useStoreAction(store, action)`
2296
+
2297
+ Hook to create a bound action for a store.
2298
+
2299
+ ```typescript
2300
+ function useStoreAction(
2301
+ store: Store<T>,
2302
+ action: (setState: Store<T>['setState'], getState: Store<T>['getState']) => (...args: Args) => R,
2303
+ ): (...args: Args) => R
2304
+ ```
2305
+
2306
+ - `store` — The store to bind to
2307
+ - `action` — The action function that receives setState and getState
2308
+
2309
+ **Returns:** A bound action function
2310
+
2311
+ #### `useT()`
2312
+
2313
+ Hook to get just the translation function.
2314
+
2315
+ ```typescript
2316
+ function useT(): (
2317
+ key: string,
2318
+ values?: InterpolationValues,
2319
+ options?: { defaultValue?: string; count?: number },
2320
+ ) => string
2321
+ ```
2322
+
2323
+ **Returns:** The translation function
2324
+
2325
+ #### `useTheme()`
2326
+
2327
+ Hook for theme state and actions.
2328
+
2329
+ ```typescript
2330
+ function useTheme(): UseThemeResult
2331
+ ```
2332
+
2333
+ **Returns:** Theme state and actions
2334
+
2335
+ #### `useThemeColors()`
2336
+
2337
+ Hook to get theme colors.
2338
+
2339
+ ```typescript
2340
+ function useThemeColors(): ThemeColors
2341
+ ```
2342
+
2343
+ **Returns:** The current theme colors
2344
+
2345
+ #### `useThemeMode()`
2346
+
2347
+ Hook to get just the theme mode (light/dark).
2348
+
2349
+ ```typescript
2350
+ function useThemeMode(): 'light' | 'dark'
2351
+ ```
2352
+
2353
+ **Returns:** The current theme mode
2354
+
2355
+ #### `useThemeProvider()`
2356
+
2357
+ Hook to access the theme provider from context.
2358
+
2359
+ ```typescript
2360
+ function useThemeProvider(): ThemeProvider
2361
+ ```
2362
+
2363
+ **Returns:** The theme provider from context
2364
+
2365
+ #### `useTranslation()`
2366
+
2367
+ Hook for internationalization.
2368
+
2369
+ ```typescript
2370
+ function useTranslation(): UseTranslationResult
2371
+ ```
2372
+
2373
+ **Returns:** Translation function and locale management
2374
+
2375
+ #### `useUser()`
2376
+
2377
+ Hook to get just the authenticated user.
2378
+
2379
+ ```typescript
2380
+ function useUser(): T | null
2381
+ ```
2382
+
2383
+ **Returns:** The authenticated user or null
2384
+
2385
+ #### `useVersion()`
2386
+
2387
+ Hook for version state and update actions.
2388
+
2389
+ Uses module-level `getProvider()` — version is a singleton, not context-provided.
2390
+
2391
+ ```typescript
2392
+ function useVersion(): UseVersionResult
2393
+ ```
2394
+
2395
+ **Returns:** Version state and action methods
2396
+
2397
+ #### `useWatch(form, name)`
2398
+
2399
+ Hook to watch a specific field value.
2400
+
2401
+ ```typescript
2402
+ function useWatch(form: FormController<T>, name: K): T[K]
2403
+ ```
2404
+
2405
+ - `form` — Form controller
2406
+ - `name` — Field name to watch
2407
+
2408
+ **Returns:** Current field value
2409
+
2410
+ #### `useWorkspace()`
2411
+
2412
+ Hook for IDE workspace layout management.
2413
+
2414
+ ```typescript
2415
+ function useWorkspace(): UseWorkspaceResult
2416
+ ```
2417
+
2418
+ **Returns:** The workspace state and management methods.
2419
+
2420
+ #### `useWorkspaceProvider()`
2421
+
2422
+ Access the workspace provider from context.
2423
+
2424
+ ```typescript
2425
+ function useWorkspaceProvider(): WorkspaceProvider
2426
+ ```
2427
+
2428
+ **Returns:** The result.
2429
+
2430
+ #### `WorkspaceProvider(props)`
2431
+
2432
+ Provider for IDE workspace.
2433
+
2434
+ ```typescript
2435
+ function WorkspaceProvider({
2436
+ provider,
2437
+ children,
2438
+ }: WorkspaceProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2439
+ ```
2440
+
2441
+ - `props` — Component props (see {@link WorkspaceProviderProps}).
2442
+
2443
+ **Returns:** The rendered workspace provider element.
2444
+
2445
+ ### Constants
2446
+
2447
+ #### `AuthContext`
2448
+
2449
+ Context for authentication client.
2450
+
2451
+ ```typescript
2452
+ const AuthContext: Context<AuthClient<unknown> | null>
2453
+ ```
2454
+
2455
+ #### `ChatContext`
2456
+
2457
+ Context for AI chat provider.
2458
+
2459
+ ```typescript
2460
+ const ChatContext: Context<ChatProvider | null>
2461
+ ```
2462
+
2463
+ #### `DEFAULT_AGENT_IDENTITY`
2464
+
2465
+ The neutral default identity ({@link DEFAULT_AGENT_NAME} +
2466
+ {@link DEFAULT_PRODUCT_NAME}) the shared packages use until a consuming app
2467
+ passes its own.
2468
+
2469
+ ```typescript
2470
+ const DEFAULT_AGENT_IDENTITY: AgentIdentity
2471
+ ```
2472
+
2473
+ #### `DEFAULT_AGENT_NAME`
2474
+
2475
+ Neutral, product-agnostic agent name used when the host supplies none.
2476
+
2477
+ ```typescript
2478
+ const DEFAULT_AGENT_NAME: 'the assistant'
2479
+ ```
2480
+
2481
+ #### `DEFAULT_PRODUCT_NAME`
2482
+
2483
+ Neutral, product-agnostic product/IDE name used when the host supplies none.
2484
+
2485
+ ```typescript
2486
+ const DEFAULT_PRODUCT_NAME: 'the IDE'
2487
+ ```
2488
+
2489
+ #### `EditorContext`
2490
+
2491
+ Context for code editor provider.
2492
+
2493
+ ```typescript
2494
+ const EditorContext: Context<EditorProvider | null>
2495
+ ```
2496
+
2497
+ #### `HttpContext`
2498
+
2499
+ Context for HTTP client.
2500
+
2501
+ ```typescript
2502
+ const HttpContext: Context<HttpClient | null>
2503
+ ```
2504
+
2505
+ #### `I18nContext`
2506
+
2507
+ Context for internationalization provider.
2508
+
2509
+ ```typescript
2510
+ const I18nContext: Context<I18nProvider | null>
2511
+ ```
2512
+
2513
+ #### `LoggerContext`
2514
+
2515
+ Context for logger provider.
2516
+
2517
+ ```typescript
2518
+ const LoggerContext: Context<LoggerProvider | null>
2519
+ ```
2520
+
2521
+ #### `PreviewContext`
2522
+
2523
+ Context for live preview provider.
2524
+
2525
+ ```typescript
2526
+ const PreviewContext: Context<PreviewProvider | null>
2527
+ ```
2528
+
2529
+ #### `RouterContext`
2530
+
2531
+ Context for router.
2532
+
2533
+ ```typescript
2534
+ const RouterContext: Context<Router | null>
2535
+ ```
2536
+
2537
+ #### `StateContext`
2538
+
2539
+ Context for state management provider.
2540
+
2541
+ ```typescript
2542
+ const StateContext: Context<StateProvider | null>
2543
+ ```
2544
+
2545
+ #### `StorageContext`
2546
+
2547
+ Context for storage provider.
2548
+
2549
+ ```typescript
2550
+ const StorageContext: Context<StorageProvider | null>
2551
+ ```
2552
+
2553
+ #### `ThemeContext`
2554
+
2555
+ Context for theme provider.
2556
+
2557
+ ```typescript
2558
+ const ThemeContext: Context<ThemeProvider | null>
2559
+ ```
2560
+
2561
+ #### `WorkspaceContext`
2562
+
2563
+ Context for IDE workspace provider.
2564
+
2565
+ ```typescript
2566
+ const WorkspaceContext: Context<WorkspaceProvider | null>
2567
+ ```
2568
+
2569
+ ## Injection Notes
2570
+
2571
+ ### Requirements
2572
+
2573
+ Peer dependencies:
2574
+
2575
+ - `@molecule/app-auth` ^1.0.0
2576
+ - `@molecule/app-ai-models` ^1.0.0
2577
+ - `@molecule/app-forms` ^1.0.0
2578
+ - `@molecule/app-utilities` ^1.0.0
2579
+ - `@molecule/app-http` ^1.0.0
2580
+ - `@molecule/app-i18n` ^1.0.0
2581
+ - `@molecule/app-logger` ^1.0.0
2582
+ - `@molecule/app-routing` ^1.0.0
2583
+ - `@molecule/app-state` ^1.0.0
2584
+ - `@molecule/app-storage` ^1.0.0
2585
+ - `@molecule/app-theme` ^1.0.0
2586
+ - `@molecule/app-ui` ^1.0.0
2587
+ - `@molecule/app-version` ^1.0.0
2588
+ - `@molecule/app-device` ^1.0.0
2589
+ - `@molecule/app-platform` ^1.0.0
2590
+ - `@molecule/app-push` ^1.0.0
2591
+ - `@molecule/app-ai-chat` ^1.0.0
2592
+ - `@molecule/app-ide` ^1.0.0
2593
+ - `@molecule/app-code-editor` ^1.0.0
2594
+ - `@molecule/app-live-preview` ^1.0.0
2595
+ - `react` ^18.0.0 || ^19.0.0
2596
+
2597
+ ### Runtime Dependencies
2598
+
2599
+ - `@molecule/app-ai-chat`
2600
+ - `@molecule/app-ai-models`
2601
+ - `@molecule/app-auth`
2602
+ - `@molecule/app-code-editor`
2603
+ - `@molecule/app-device`
2604
+ - `@molecule/app-forms`
2605
+ - `@molecule/app-http`
2606
+ - `@molecule/app-i18n`
2607
+ - `@molecule/app-ide`
2608
+ - `@molecule/app-live-preview`
2609
+ - `@molecule/app-logger`
2610
+ - `@molecule/app-platform`
2611
+ - `@molecule/app-push`
2612
+ - `@molecule/app-routing`
2613
+ - `@molecule/app-state`
2614
+ - `@molecule/app-storage`
2615
+ - `@molecule/app-theme`
2616
+ - `@molecule/app-ui`
2617
+ - `@molecule/app-utilities`
2618
+ - `@molecule/app-version`
2619
+ - `react`
2620
+
2621
+ - **Every hook throws when its provider is not mounted.** `MoleculeProvider` wires ONLY the
2622
+ services you pass as props — it is a convenience wrapper, not a default registry. The map:
2623
+ `useAuth`→`auth`, `useTranslation`/`useT`→`i18n`, `useTheme`→`theme`, `useRouter`→`router`,
2624
+ `useStore`→`state`, `useHttp`→`http`, `useStorage`→`storage`, `useLogger`→`logger`,
2625
+ `useChat`→`chat`, `useWorkspace`→`workspace`, `useEditor`→`editor`, `usePreview`→`preview`.
2626
+ "useXProvider must be used within an XProvider" means the matching prop (or individual
2627
+ provider component) is missing ABOVE the component that calls the hook — fix the wiring,
2628
+ never wrap the hook in try/catch.
2629
+ - **Locale-reactive text requires the hook.** Inside components always read `t` from
2630
+ `useTranslation()` (or `useT()`); it re-renders on `onLocaleChange` — even when
2631
+ `addTranslations()` only adds keys for the current locale. Calling the raw `t()` import from
2632
+ `@molecule/app-i18n` in render works once but leaves stale text after a locale switch.
2633
+ - **Exactly one React copy.** In workspace/symlinked dev setups a second React instance makes
2634
+ every hook fail ("Invalid hook call", or the provider errors above with the provider
2635
+ mounted). Scaffolded Vite configs ship
2636
+ `resolve.dedupe: ['react', 'react-dom', 'react-router', 'react-router']` — keep it, and
2637
+ add any new hook-bearing peer library there too.
2638
+ - `RouterProvider` carries a molecule `Router` (e.g. `createReactRouter()` from
2639
+ `@molecule/app-routing-react-router`). react-router's own `<BrowserRouter>` context is
2640
+ separate — components that render react-router `<Link>` (several in
2641
+ `@molecule/app-ui-react`) need it in addition to the molecule providers.
2642
+
2643
+ ## Translations
2644
+
2645
+ Translation strings are provided by `@molecule/app-locales-react`.