@molecule/app-react 1.6.2 → 1.6.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 (2) hide show
  1. package/README.md +1321 -1319
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@ 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-10-04T07:07:58.821Z
6
+ Generated: 2026-10-16T00:51:41.781Z
7
7
  -->
8
8
 
9
9
  # @molecule/app-react
@@ -80,19 +80,32 @@ npm install -D @types/react
80
80
 
81
81
  ### Interfaces
82
82
 
83
- #### `AgentIdentity`
83
+ #### `AuthState`
84
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.
85
+ Reactive authentication state snapshot (initialized, authenticated, user, loading, and error).
89
86
 
90
87
  ```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
88
+ interface AuthState<T = UserProfile> {
89
+ /**
90
+ * Whether auth state has been initialized.
91
+ */
92
+ initialized: boolean
93
+ /**
94
+ * Whether the user is authenticated.
95
+ */
96
+ authenticated: boolean
97
+ /**
98
+ * Current user (if authenticated).
99
+ */
100
+ user: T | null
101
+ /**
102
+ * Whether an auth operation is in progress.
103
+ */
104
+ loading: boolean
105
+ /**
106
+ * Last auth error (if any).
107
+ */
108
+ error: string | null
96
109
  }
97
110
  ```
98
111
 
@@ -198,65 +211,6 @@ interface AuthClient<T = UserProfile> {
198
211
  }
199
212
  ```
200
213
 
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
214
  #### `FormController`
261
215
 
262
216
  Form controller interface.
@@ -464,77 +418,6 @@ interface HttpClient {
464
418
  }
465
419
  ```
466
420
 
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
421
  #### `Router`
539
422
 
540
423
  Client-side router providing navigation, guards, route matching, and history control.
@@ -661,91 +544,24 @@ interface RouterConfig {
661
544
  }
662
545
  ```
663
546
 
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`
547
+ #### `StoreConfig`
675
548
 
676
- Options for {@link UseChatResult.sendMessage}.
549
+ Configuration for creating a store (initial state, optional name, and middleware chain).
677
550
 
678
551
  ```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
552
+ interface StoreConfig<T> {
704
553
  /**
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.
554
+ * Initial state value.
710
555
  */
711
- userInitiated?: boolean
556
+ initialState: T
712
557
  /**
713
- * Send on the SIDE CHANNEL: a human-to-human message (e.g. a team note) the
714
- * server intercepts before running any agent turn. When the provider supports
715
- * `sendSideMessage`, the send goes out IMMEDIATELY on an independent request —
716
- * it never queues behind an active turn, never takes over the streaming
717
- * state, and never tears down remote-turn tracking (a viewer's note while
718
- * watching a teammate's turn must not stop the watching). Falls back to the
719
- * normal send path on providers without side-channel support.
558
+ * Optional name for debugging.
720
559
  */
721
- sideChannel?: boolean
560
+ name?: string
722
561
  /**
723
- * Mark this send as composed through voice dictation — the mic button's
724
- * transcript was still present in the composer at submit. The optimistic
725
- * bubble and the persisted message are flagged `viaDictation` so the chat
726
- * renders a mic badge on the message, live and after a reload.
562
+ * Optional middleware functions.
727
563
  */
728
- viaDictation?: boolean
729
- }
730
- ```
731
-
732
- #### `StateProviderProps`
733
-
734
- Props for state provider component.
735
-
736
- ```typescript
737
- interface StateProviderProps extends ProviderProps {
738
- provider: StateProvider
739
- }
740
- ```
741
-
742
- #### `StorageProviderProps`
743
-
744
- Props for storage provider component.
745
-
746
- ```typescript
747
- interface StorageProviderProps extends ProviderProps {
748
- provider: StorageProvider
564
+ middleware?: StoreMiddleware<T>[]
749
565
  }
750
566
  ```
751
567
 
@@ -777,30 +593,9 @@ interface Store<T> {
777
593
  }
778
594
  ```
779
595
 
780
- #### `StoreConfig`
596
+ #### `Theme`
781
597
 
782
- Configuration for creating a store (initial state, optional name, and middleware chain).
783
-
784
- ```typescript
785
- interface StoreConfig<T> {
786
- /**
787
- * Initial state value.
788
- */
789
- initialState: T
790
- /**
791
- * Optional name for debugging.
792
- */
793
- name?: string
794
- /**
795
- * Optional middleware functions.
796
- */
797
- middleware?: StoreMiddleware<T>[]
798
- }
799
- ```
800
-
801
- #### `Theme`
802
-
803
- Complete theme definition.
598
+ Complete theme definition.
804
599
 
805
600
  ```typescript
806
601
  interface Theme {
@@ -817,14 +612,19 @@ interface Theme {
817
612
  }
818
613
  ```
819
614
 
820
- #### `ThemeProviderProps`
615
+ #### `AgentIdentity`
821
616
 
822
- Props for theme provider component.
617
+ Display identity for the AI coding agent and the host product, used to
618
+ interpolate the `{{agentName}}` / `{{productName}}` tokens in shared chat/IDE
619
+ copy. A consuming app sets these to its own agent + product brand names; the
620
+ shared packages fall back to {@link DEFAULT_AGENT_IDENTITY} when it does not.
823
621
 
824
622
  ```typescript
825
- interface ThemeProviderProps extends ProviderProps {
826
- provider: ThemeProvider
827
- initialTheme?: string
623
+ interface AgentIdentity {
624
+ /** Display name of the AI coding agent. Defaults to {@link DEFAULT_AGENT_NAME}. */
625
+ agentName: string
626
+ /** Display name of the host product / IDE. Defaults to {@link DEFAULT_PRODUCT_NAME}. */
627
+ productName: string
828
628
  }
829
629
  ```
830
630
 
@@ -850,671 +650,831 @@ interface UseAIModelsResult {
850
650
  }
851
651
  ```
852
652
 
853
- #### `UseAuthOptions`
653
+ #### `UseChangePasswordReturn`
854
654
 
855
- Hook options for useAuth.
655
+ Return type for useChangePassword hook.
856
656
 
857
657
  ```typescript
858
- interface UseAuthOptions {
658
+ interface UseChangePasswordReturn {
659
+ status: UsePromiseState<void>['status']
660
+ error: UsePromiseState<void>['error']
661
+ changePassword: (oldPassword: string, newPassword: string) => Promise<void>
662
+ reset: () => void
663
+ }
664
+ ```
665
+
666
+ #### `UseDeviceResult`
667
+
668
+ Hook return type.
669
+
670
+ ```typescript
671
+ interface UseDeviceResult {
672
+ deviceInfo: DeviceInfo
673
+ screenInfo: ScreenInfo
674
+ hardwareInfo: HardwareInfo
675
+ featureSupport: FeatureSupport
676
+ supports: (feature: keyof FeatureSupport) => boolean
677
+ isOnline: () => boolean
678
+ isStandalone: () => boolean
679
+ language: string
680
+ languages: string[]
681
+ }
682
+ ```
683
+
684
+ #### `UseFormOptions`
685
+
686
+ Options for useForm hook.
687
+
688
+ ```typescript
689
+ interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
859
690
  /**
860
- * Whether to automatically refresh the token on mount.
691
+ * Form provider's createForm function.
861
692
  */
862
- autoRefresh?: boolean
693
+ createForm: (options: FormOptions<T>) => FormController<T>
863
694
  }
864
695
  ```
865
696
 
866
- #### `UseAuthResult`
697
+ #### `UseFormResult`
867
698
 
868
- Hook result for useAuth.
699
+ Result of useForm hook.
869
700
 
870
701
  ```typescript
871
- interface UseAuthResult<T = unknown> {
872
- state: AuthState<T>
873
- login: AuthClient<T>['login']
874
- logout: AuthClient<T>['logout']
875
- register: AuthClient<T>['register']
876
- refresh: AuthClient<T>['refresh']
877
- setUser: AuthClient<T>['setUser']
878
- isAuthenticated: boolean
879
- isLoading: boolean
880
- user: T | null
702
+ interface UseFormResult<T extends Record<string, unknown>> {
703
+ // State
704
+ formState: FormState<T>
705
+ isValid: boolean
706
+ isDirty: boolean
707
+ isSubmitting: boolean
708
+
709
+ // Field methods
710
+ register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
711
+ getValue: <K extends keyof T>(name: K) => T[K]
712
+ setValue: <K extends keyof T>(name: K, value: T[K]) => void
713
+ getError: (name: keyof T) => string | undefined
714
+ setError: (name: keyof T, error: string | undefined) => void
715
+ clearErrors: () => void
716
+
717
+ // Form methods
718
+ handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (event?: React.FormEvent) => void
719
+ reset: (values?: Partial<T>) => void
720
+ validate: () => Promise<boolean>
881
721
  }
882
722
  ```
883
723
 
884
- #### `UseChangePasswordReturn`
724
+ #### `UseHttpState`
885
725
 
886
- Return type for useChangePassword hook.
726
+ State for async HTTP operations.
887
727
 
888
728
  ```typescript
889
- interface UseChangePasswordReturn {
890
- status: UsePromiseState<void>['status']
891
- error: UsePromiseState<void>['error']
892
- changePassword: (oldPassword: string, newPassword: string) => Promise<void>
893
- reset: () => void
729
+ interface UseHttpState<T> {
730
+ data: T | null
731
+ loading: boolean
732
+ error: Error | null
894
733
  }
895
734
  ```
896
735
 
897
- #### `UseChatOptions`
736
+ #### `UseHttpResult`
898
737
 
899
- Hook options for useChat.
738
+ Result of useHttp hook.
900
739
 
901
740
  ```typescript
902
- interface UseChatOptions {
903
- /** Chat endpoint (e.g., '/projects/123/chat'). */
904
- endpoint: string
905
- /** Project ID for context. */
906
- projectId?: string
907
- /**
908
- * Display name of the AI coding agent, interpolated into user-facing chat
909
- * copy (e.g. the stalled-stream notice). The host passes its own agent brand
910
- * name; defaults to the neutral `DEFAULT_AGENT_NAME` so the shared hook never
911
- * names a specific product.
912
- */
913
- agentName?: string
914
- /** Load history on mount. */
915
- loadOnMount?: boolean
916
- /**
917
- * This client may only WATCH the conversation (e.g. a read-only project
918
- * viewer): the hook never issues chat POSTs on its behalf — no resume
919
- * request after a reload, no auto-retries. A live turn is followed through
920
- * the remote-watch path instead: pushed broadcast frames (applyRemoteEvent)
921
- * render it in real time and the history reconcile poll backstops gaps, with
922
- * `isRemoteStreaming` driving the activity indicator.
923
- */
924
- readOnly?: boolean
925
- /** Called when a file is created or modified by a tool call (path + new content). */
926
- onFileChange?: (path: string, content: string) => void
927
- /** Called when the AI switches between plan and execute modes. */
928
- onModeChange?: (mode: 'plan' | 'execute') => void
929
- /** Called when the backend assigns or confirms a conversation ID. */
930
- onConversationId?: (id: string) => void
931
- /** Called for every streaming event — useful for notifications, sounds, etc. */
932
- onStreamEvent?: (event: ChatStreamEvent) => void
741
+ interface UseHttpResult<T> extends UseHttpState<T> {
742
+ execute: () => Promise<T | null>
743
+ reset: () => void
933
744
  }
934
745
  ```
935
746
 
936
- #### `UseChatResult`
747
+ #### `UseHttpOptions`
937
748
 
938
- Hook result for useChat.
749
+ Options for useHttp hook.
939
750
 
940
751
  ```typescript
941
- interface UseChatResult {
942
- messages: ChatMessage[]
943
- isLoading: boolean
944
- /**
945
- * True while a backend turn for this conversation streams WITHOUT this client
946
- * owning the request — a turn started in another tab, by a teammate, or any
947
- * server-side continuation. Detected from pushed (broadcast) chat events and
948
- * confirmed/cleared against the server's `streaming` history flag, so the Stop
949
- * control can stay visible and functional whenever ANY backend turn is live —
950
- * not only for sends this hook instance made.
951
- */
952
- isRemoteStreaming: boolean
953
- /**
954
- * Tell the hook a pushed (broadcast) chat event arrived for this conversation.
955
- * The host (ChatPanel) calls this from its push-channel handler; the hook then
956
- * confirms against the server's `streaming` flag and, while a remote turn is
957
- * live, keeps `isRemoteStreaming` true until the server reports it finished.
958
- */
959
- noteRemoteStreamEvent: () => void
960
- error: string | null
752
+ interface UseHttpOptions<T> extends RequestConfig {
961
753
  /**
962
- * Metadata about a limit-related error, for a contextual call-to-action.
963
- * `limitType` names the RULE the backend enforced; `billingAction` names the
964
- * REMEDY it resolved (e.g. `add_funds`, `add_payment_method`,
965
- * `raise_spend_cap`, `upgrade`, `none`) and is what the button should be
966
- * built from — the same limit needs a different button per account.
967
- * `upgradeTier` is the plan an upgrade would move to, explicitly `null` when
968
- * there is no higher tier. The backend owns these vocabularies, so the
969
- * action/tier are plain strings here.
754
+ * Whether to execute the request immediately on mount.
970
755
  */
971
- errorMeta: {
972
- limitType?: string
973
- requiresSignup?: boolean
974
- billingAction?: string
975
- upgradeTier?: string | null
976
- } | null
977
- /** Current agent mode — plan (read-only research) or execute (full access). */
978
- mode: 'plan' | 'execute'
756
+ immediate?: boolean
979
757
  /**
980
- * Whether the conversation runs at the provider's fast/priority speed tier
981
- * (server-persisted per conversation; hydrated from the history load's
982
- * `fastMode` meta field, when the server provides one). Only meaningful for
983
- * models that support a fast tier — the server ignores it otherwise.
758
+ * Callback when request succeeds.
984
759
  */
985
- fastMode: boolean
760
+ onSuccess?: (data: T) => void
986
761
  /**
987
- * Transient label for a background phase (e.g. the post-response verification
988
- * pass — "Type-checking the API", "Linting"), set by `status` stream events.
989
- * The UI shows it in place of the spinner's generic rotating messages; `null`
990
- * when no such phase is active.
762
+ * Callback when request fails.
991
763
  */
992
- streamingStatus: string | null
764
+ onError?: (error: Error) => void
765
+ }
766
+ ```
767
+
768
+ #### `UseLoginReturn`
769
+
770
+ Return type for useLogin hook.
771
+
772
+ ```typescript
773
+ interface UseLoginReturn<T = unknown> {
774
+ status: UsePromiseState<AuthResult<T>>['status']
775
+ value: UsePromiseState<AuthResult<T>>['value']
776
+ error: UsePromiseState<AuthResult<T>>['error']
777
+ login: (credentials: LoginCredentials) => Promise<AuthResult<T>>
778
+ reset: () => void
779
+ }
780
+ ```
781
+
782
+ #### `UseOAuthReturn`
783
+
784
+ Return type for useOAuth hook.
785
+
786
+ ```typescript
787
+ interface UseOAuthReturn {
788
+ providers: string[]
789
+ getOAuthUrl: (provider: string) => string
790
+ /** Full-page redirect to the provider (default). The opener page navigates away. */
791
+ redirect: (provider: string) => void
993
792
  /**
994
- * Commands the executor detached with `run_in_background`, newest last. Each
995
- * appears here the moment it starts and is replaced in place when it finishes,
996
- * so the UI can show work that outlives the tool call that started it.
793
+ * Open the provider in a popup so the opener page does NOT navigate. On success
794
+ * the session is established in the opener in place and `config.onSuccess` fires;
795
+ * on failure `config.onError` fires. Falls back to a full-page {@link redirect}
796
+ * when the popup is blocked.
997
797
  */
998
- backgroundTasks: BackgroundTaskState[]
999
- /**
1000
- * Active 5XX backoff-retry countdown, or `null` when none is pending. After a
1001
- * backend server error (HTTP 5XX) the hook does NOT surface a terminal error —
1002
- * it shows this cancelable countdown and, when it elapses, auto-resumes the
1003
- * turn where the user left off (`resume:true`). `secondsRemaining` ticks down
1004
- * once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
1005
- * limit/quota, and signup-required errors never auto-retry.
1006
- */
1007
- retryCountdown: { secondsRemaining: number; attempt: number } | null
1008
- /** Update the local mode state (for instant mode toggle without an AI turn). */
1009
- setMode: (mode: 'plan' | 'execute') => void
1010
- /** Update the local fast-mode state (for instant toggle without an AI turn). */
1011
- setFastMode: (fastMode: boolean) => void
1012
- sendMessage: (
1013
- message: string,
1014
- attachments?: ChatAttachment[],
1015
- options?: SendMessageOptions,
1016
- ) => Promise<void>
1017
- abort: () => void
1018
- /**
1019
- * Cancel a pending 5XX auto-retry. Clears the countdown and surfaces the
1020
- * original error (via `error`) so the user sees why the turn failed.
1021
- */
1022
- cancelRetry: () => void
1023
- clearHistory: () => Promise<void>
1024
- /** Edit the content of a queued (not yet sent) message. */
1025
- editQueuedMessage: (msgId: string, newContent: string) => void
1026
- /** Remove a queued (not yet sent) message from the queue. */
1027
- deleteQueuedMessage: (msgId: string) => void
1028
- /** Remove queued auto-fix messages whose content references the given file path. */
1029
- clearQueuedForFile: (filePath: string) => void
1030
- /**
1031
- * Append an inline transcript card (model / mode / skills / custom notice) as a
1032
- * `role:'system'` card-message in the ONE message store. Used by the host (ChatPanel)
1033
- * to render a TEAMMATE's broadcast `card` event live — this client's OWN cards arrive
1034
- * through the stream and are appended internally. De-duped by the server-assigned id.
1035
- */
1036
- appendCardMessage: (
1037
- id: string,
1038
- timestamp: number,
1039
- card: NonNullable<ChatMessage['cardEvent']>,
1040
- ) => void
1041
- /**
1042
- * Append a COMPLETE, non-streaming chat message (a `message` stream event — e.g.
1043
- * a teammate's human-only team note) to the ONE message store. Used by the host
1044
- * (ChatPanel) to render a TEAMMATE's broadcast `message` event live — this
1045
- * client's OWN `message` events arrive through the stream and are appended
1046
- * internally. De-duped by the server-assigned message id.
1047
- */
1048
- appendCompleteMessage: (message: ChatMessage) => void
1049
- /**
1050
- * Ingest ONE pushed (broadcast) stream frame from a turn running elsewhere —
1051
- * a teammate's send, another tab, a server-side continuation — into the ONE
1052
- * message store, through the same content applier as an own SSE stream: text/
1053
- * thinking deltas, tool events, verification, cards, complete messages, done.
1054
- * The host (ChatPanel) calls this from its push-channel handler for every
1055
- * broadcast frame of the OPEN conversation. Own echoes are dropped while a
1056
- * local send is in flight (the SSE stream is authoritative for the sender);
1057
- * complete id-carrying items (cards, team notes) always apply, de-duped.
1058
- */
1059
- applyRemoteEvent: (event: ChatStreamEvent) => void
1060
- /**
1061
- * Reload history and converge the local view on the server transcript (and
1062
- * re-enter a still-streaming turn). The page-lifecycle events run this
1063
- * automatically; the host should ALSO call it whenever its chat push channel
1064
- * (re)connects — a broadcast sent while that socket was down (a teammate's
1065
- * team note against a backgrounded tab or a slept laptop) is otherwise lost
1066
- * until the next lifecycle event happens to fire. Cheap when nothing changed:
1067
- * an identical transcript is never re-applied.
1068
- */
1069
- reconcileHistory: () => Promise<void>
798
+ loginViaPopup: (provider: string) => void
1070
799
  }
1071
800
  ```
1072
801
 
1073
- #### `UseDeviceResult`
802
+ #### `UsePasswordResetReturn`
1074
803
 
1075
- Hook return type.
804
+ Return type for usePasswordReset hook.
1076
805
 
1077
806
  ```typescript
1078
- interface UseDeviceResult {
1079
- deviceInfo: DeviceInfo
1080
- screenInfo: ScreenInfo
1081
- hardwareInfo: HardwareInfo
1082
- featureSupport: FeatureSupport
1083
- supports: (feature: keyof FeatureSupport) => boolean
1084
- isOnline: () => boolean
1085
- isStandalone: () => boolean
1086
- language: string
1087
- languages: string[]
807
+ interface UsePasswordResetReturn {
808
+ requestStatus: UsePromiseState<void>['status']
809
+ requestError: UsePromiseState<void>['error']
810
+ confirmStatus: UsePromiseState<void>['status']
811
+ confirmError: UsePromiseState<void>['error']
812
+ requestReset: (data: PasswordResetRequest) => Promise<void>
813
+ confirmReset: (data: PasswordResetConfirm) => Promise<void>
814
+ reset: () => void
1088
815
  }
1089
816
  ```
1090
817
 
1091
- #### `UseEditorResult`
818
+ #### `UsePlatformResult`
1092
819
 
1093
- Hook result for useEditor.
820
+ Hook return type.
1094
821
 
1095
822
  ```typescript
1096
- interface UseEditorResult {
1097
- tabs: EditorTab[]
1098
- activeFile: string | null
1099
- openFile: (file: EditorFile) => void
1100
- closeFile: (path: string) => void
1101
- getContent: () => string | null
1102
- setContent: (path: string, content: string) => void
1103
- setActiveTab: (path: string) => void
1104
- mount: EditorProvider['mount']
1105
- dispose: () => void
1106
- focus: () => void
1107
- openDiff: (file: DiffFile) => void
1108
- closeDiff: () => void
1109
- pinTab: (path: string) => void
1110
- addExtraLib: (content: string, filePath: string) => void
1111
- onFixWithAI: (callback: (request: FixWithAIRequest) => void) => () => void
823
+ interface UsePlatformResult {
824
+ platform: Platform
825
+ isNative: boolean
826
+ isMobile: boolean
827
+ isDesktop: boolean
828
+ isWeb: boolean
829
+ isDevelopment: boolean
830
+ isProduction: boolean
831
+ isPlatform: (...platforms: Platform[]) => boolean
1112
832
  }
1113
833
  ```
1114
834
 
1115
- #### `UseFormOptions`
835
+ #### `UsePromiseState`
1116
836
 
1117
- Options for useForm hook.
837
+ Extended promise state with actions.
1118
838
 
1119
839
  ```typescript
1120
- interface UseFormOptions<T extends Record<string, unknown>> extends FormOptions<T> {
1121
- /**
1122
- * Form provider's createForm function.
1123
- */
1124
- createForm: (options: FormOptions<T>) => FormController<T>
840
+ interface UsePromiseState<T> {
841
+ status: PromiseStatus
842
+ value: T | null
843
+ error: Error | null
844
+ cancel: (message?: string) => void
845
+ reset: () => void
1125
846
  }
1126
847
  ```
1127
848
 
1128
- #### `UseFormResult`
849
+ #### `UsePushResult`
1129
850
 
1130
- Result of useForm hook.
851
+ Hook return type.
1131
852
 
1132
853
  ```typescript
1133
- interface UseFormResult<T extends Record<string, unknown>> {
1134
- // State
1135
- formState: FormState<T>
1136
- isValid: boolean
1137
- isDirty: boolean
1138
- isSubmitting: boolean
1139
-
1140
- // Field methods
1141
- register: (name: keyof T, options?: RegisterOptions) => FieldRegistration
1142
- getValue: <K extends keyof T>(name: K) => T[K]
1143
- setValue: <K extends keyof T>(name: K, value: T[K]) => void
1144
- getError: (name: keyof T) => string | undefined
1145
- setError: (name: keyof T, error: string | undefined) => void
1146
- clearErrors: () => void
1147
-
1148
- // Form methods
1149
- handleSubmit: (onSubmit: (values: T) => void | Promise<void>) => (event?: React.FormEvent) => void
1150
- reset: (values?: Partial<T>) => void
1151
- validate: () => Promise<boolean>
854
+ interface UsePushResult {
855
+ permission: PermissionStatus | null
856
+ token: PushToken | null
857
+ checkPermission: () => Promise<PermissionStatus>
858
+ requestPermission: () => Promise<PermissionStatus>
859
+ register: (options?: PushRegisterOptions) => Promise<PushToken>
860
+ unregister: () => Promise<void>
861
+ onNotificationReceived: (listener: NotificationReceivedListener) => () => void
862
+ onNotificationAction: (listener: NotificationActionListener) => () => void
863
+ onTokenChange: (listener: TokenChangeListener) => () => void
864
+ setBadge: (count: number) => Promise<void>
865
+ clearBadge: () => Promise<void>
1152
866
  }
1153
867
  ```
1154
868
 
1155
- #### `UseHttpOptions`
869
+ #### `UsePushOptions`
1156
870
 
1157
- Options for useHttp hook.
871
+ Options for the usePush hook (e.g. check permission on mount).
1158
872
 
1159
873
  ```typescript
1160
- interface UseHttpOptions<T> extends RequestConfig {
1161
- /**
1162
- * Whether to execute the request immediately on mount.
1163
- */
1164
- immediate?: boolean
1165
- /**
1166
- * Callback when request succeeds.
1167
- */
1168
- onSuccess?: (data: T) => void
874
+ interface UsePushOptions {
1169
875
  /**
1170
- * Callback when request fails.
876
+ * Whether to check permission status on mount.
1171
877
  */
1172
- onError?: (error: Error) => void
878
+ checkOnMount?: boolean
1173
879
  }
1174
880
  ```
1175
881
 
1176
- #### `UseHttpResult`
882
+ #### `UseSignupReturn`
1177
883
 
1178
- Result of useHttp hook.
884
+ Return type for useSignup hook.
1179
885
 
1180
886
  ```typescript
1181
- interface UseHttpResult<T> extends UseHttpState<T> {
1182
- execute: () => Promise<T | null>
887
+ interface UseSignupReturn<T = unknown> {
888
+ status: UsePromiseState<AuthResult<T>>['status']
889
+ value: UsePromiseState<AuthResult<T>>['value']
890
+ error: UsePromiseState<AuthResult<T>>['error']
891
+ signup: (data: RegisterData) => Promise<AuthResult<T>>
1183
892
  reset: () => void
1184
893
  }
1185
894
  ```
1186
895
 
1187
- #### `UseHttpState`
896
+ #### `UseStorageValueOptions`
1188
897
 
1189
- State for async HTTP operations.
898
+ Options for useStorageValue hook.
1190
899
 
1191
900
  ```typescript
1192
- interface UseHttpState<T> {
1193
- data: T | null
1194
- loading: boolean
1195
- error: Error | null
901
+ interface UseStorageValueOptions<T> {
902
+ /**
903
+ * Default value if key doesn't exist.
904
+ */
905
+ defaultValue?: T
906
+ /**
907
+ * Whether to sync across tabs/windows (if supported by storage provider).
908
+ */
909
+ sync?: boolean
1196
910
  }
1197
911
  ```
1198
912
 
1199
- #### `UseLoginReturn`
913
+ #### `UseStorageValueResult`
1200
914
 
1201
- Return type for useLogin hook.
915
+ Result of useStorageValue hook.
1202
916
 
1203
917
  ```typescript
1204
- interface UseLoginReturn<T = unknown> {
1205
- status: UsePromiseState<AuthResult<T>>['status']
1206
- value: UsePromiseState<AuthResult<T>>['value']
1207
- error: UsePromiseState<AuthResult<T>>['error']
1208
- login: (credentials: LoginCredentials) => Promise<AuthResult<T>>
1209
- reset: () => void
918
+ interface UseStorageValueResult<T> {
919
+ value: T | undefined
920
+ setValue: (value: T) => Promise<void>
921
+ removeValue: () => Promise<void>
922
+ loading: boolean
923
+ error: Error | null
1210
924
  }
1211
925
  ```
1212
926
 
1213
- #### `UseOAuthReturn`
927
+ #### `UseVerifyPaymentReturnOptions`
1214
928
 
1215
- Return type for useOAuth hook.
929
+ Options for {@link useVerifyPaymentReturn}.
1216
930
 
1217
931
  ```typescript
1218
- interface UseOAuthReturn {
1219
- providers: string[]
1220
- getOAuthUrl: (provider: string) => string
1221
- /** Full-page redirect to the provider (default). The opener page navigates away. */
1222
- redirect: (provider: string) => void
932
+ interface UseVerifyPaymentReturnOptions {
1223
933
  /**
1224
- * Open the provider in a popup so the opener page does NOT navigate. On success
1225
- * the session is established in the opener in place and `config.onSuccess` fires;
1226
- * on failure `config.onError` fires. Falls back to a full-page {@link redirect}
1227
- * when the popup is blocked.
934
+ * Provider name to verify with, when the return URL carries no `provider`
935
+ * query parameter. Leave unset to verify only what the URL names.
1228
936
  */
1229
- loginViaPopup: (provider: string) => void
1230
- }
1231
- ```
1232
-
1233
- #### `UsePasswordResetReturn`
937
+ provider?: string
1234
938
 
1235
- Return type for usePasswordReset hook.
939
+ /** Set `false` to skip verification entirely (e.g. behind a feature flag). */
940
+ enabled?: boolean
1236
941
 
1237
- ```typescript
1238
- interface UsePasswordResetReturn {
1239
- requestStatus: UsePromiseState<void>['status']
1240
- requestError: UsePromiseState<void>['error']
1241
- confirmStatus: UsePromiseState<void>['status']
1242
- confirmError: UsePromiseState<void>['error']
1243
- requestReset: (data: PasswordResetRequest) => Promise<void>
1244
- confirmReset: (data: PasswordResetConfirm) => Promise<void>
1245
- reset: () => void
942
+ /**
943
+ * Remove the provider's query parameters from the address bar once the
944
+ * purchase is verified, so a reload (or a shared link) cannot replay the
945
+ * verification. Defaults to `true`.
946
+ */
947
+ cleanUrl?: boolean
948
+
949
+ /** Called once, after the purchase verifies. */
950
+ onVerified?: () => void
951
+
952
+ /** Called when verification fails. */
953
+ onError?: (error: Error) => void
1246
954
  }
1247
955
  ```
1248
956
 
1249
- #### `UsePlatformResult`
957
+ #### `UseVerifyPaymentReturnResult`
1250
958
 
1251
- Hook return type.
959
+ State of the post-checkout verification.
1252
960
 
1253
961
  ```typescript
1254
- interface UsePlatformResult {
1255
- platform: Platform
1256
- isNative: boolean
1257
- isMobile: boolean
1258
- isDesktop: boolean
1259
- isWeb: boolean
1260
- isDevelopment: boolean
1261
- isProduction: boolean
1262
- isPlatform: (...platforms: Platform[]) => boolean
962
+ interface UseVerifyPaymentReturnResult {
963
+ /**
964
+ * `idle` when this page load is not a checkout return (no transaction id in
965
+ * the URL) or auth is still hydrating; `verifying` while the API call is in
966
+ * flight; then `verified` or `failed`.
967
+ */
968
+ status: VerifyPaymentReturnStatus
969
+
970
+ /** `true` when the URL identifies a purchase to verify. */
971
+ isReturn: boolean
972
+
973
+ /** The provider named by the URL (or the `provider` option). */
974
+ provider: string | null
975
+
976
+ /** The provider transaction/session id read from the URL. */
977
+ transactionId: string | null
978
+
979
+ /** Why verification failed, when it did. */
980
+ error: Error | null
981
+
982
+ /** Re-run the verification — wire this to a retry button. */
983
+ retry: () => void
1263
984
  }
1264
985
  ```
1265
986
 
1266
- #### `UsePreviewResult`
987
+ #### `UseVersionResult`
1267
988
 
1268
- Hook result for usePreview.
989
+ Hook return type.
1269
990
 
1270
991
  ```typescript
1271
- interface UsePreviewResult {
1272
- state: PreviewState
1273
- setUrl: (url: string) => void
1274
- refresh: () => void
1275
- setDevice: (device: DeviceFrame) => void
1276
- openExternal: () => void
1277
- /**
1278
- * Records a navigation the running preview reported via its `molecule:navigate`
1279
- * message — updates the displayed current location without reloading the iframe.
1280
- * Pass `isReplace` when the preview REPLACED its current history entry (a
1281
- * `replaceState` redirect/canonicalization) so the forward stack is preserved
1282
- * instead of truncated (a `pushState`, the default, truncates forward).
1283
- */
1284
- recordNavigation: (url: string, isReplace?: boolean) => void
1285
- /** Navigates the preview to the previous navigation-history entry (Back). */
1286
- back: () => void
1287
- /** Navigates the preview to the next navigation-history entry (Forward). */
1288
- forward: () => void
992
+ interface UseVersionResult {
993
+ state: VersionState
994
+ isUpdateAvailable: boolean
995
+ isChecking: boolean
996
+ isServiceWorkerWaiting: boolean
997
+ newVersion: string | undefined
998
+ checkForUpdates: () => Promise<boolean>
999
+ applyUpdate: (options?: { force?: boolean }) => void
1000
+ dismissUpdate: () => void
1001
+ startPeriodicChecks: (options?: UpdateCheckOptions) => void
1002
+ stopPeriodicChecks: () => void
1289
1003
  }
1290
1004
  ```
1291
1005
 
1292
- #### `UsePromiseState`
1006
+ #### `ProviderProps`
1293
1007
 
1294
- Extended promise state with actions.
1008
+ Props for provider components.
1295
1009
 
1296
1010
  ```typescript
1297
- interface UsePromiseState<T> {
1298
- status: PromiseStatus
1299
- value: T | null
1300
- error: Error | null
1301
- cancel: (message?: string) => void
1302
- reset: () => void
1011
+ interface ProviderProps {
1012
+ children: ReactNode
1303
1013
  }
1304
1014
  ```
1305
1015
 
1306
- #### `UsePushOptions`
1016
+ #### `StateProviderProps`
1307
1017
 
1308
- Options for the usePush hook (e.g. check permission on mount).
1018
+ Props for state provider component.
1309
1019
 
1310
1020
  ```typescript
1311
- interface UsePushOptions {
1312
- /**
1313
- * Whether to check permission status on mount.
1314
- */
1315
- checkOnMount?: boolean
1021
+ interface StateProviderProps extends ProviderProps {
1022
+ provider: StateProvider
1316
1023
  }
1317
1024
  ```
1318
1025
 
1319
- #### `UsePushResult`
1026
+ #### `AuthProviderProps`
1320
1027
 
1321
- Hook return type.
1028
+ Props for auth provider component.
1322
1029
 
1323
1030
  ```typescript
1324
- interface UsePushResult {
1325
- permission: PermissionStatus | null
1326
- token: PushToken | null
1327
- checkPermission: () => Promise<PermissionStatus>
1328
- requestPermission: () => Promise<PermissionStatus>
1329
- register: (options?: PushRegisterOptions) => Promise<PushToken>
1330
- unregister: () => Promise<void>
1331
- onNotificationReceived: (listener: NotificationReceivedListener) => () => void
1332
- onNotificationAction: (listener: NotificationActionListener) => () => void
1333
- onTokenChange: (listener: TokenChangeListener) => () => void
1334
- setBadge: (count: number) => Promise<void>
1335
- clearBadge: () => Promise<void>
1031
+ interface AuthProviderProps<T = unknown> extends ProviderProps {
1032
+ client: AuthClient<T>
1336
1033
  }
1337
1034
  ```
1338
1035
 
1339
- #### `UseRouterResult`
1036
+ #### `ThemeProviderProps`
1340
1037
 
1341
- Hook result for useRouter.
1038
+ Props for theme provider component.
1342
1039
 
1343
1040
  ```typescript
1344
- interface UseRouterResult {
1345
- location: Router['getLocation'] extends () => infer R ? R : never
1346
- params: Record<string, string>
1347
- query: QueryParams
1348
- navigate: Router['navigate']
1349
- navigateTo: Router['navigateTo']
1350
- back: Router['back']
1351
- forward: Router['forward']
1352
- isActive: Router['isActive']
1041
+ interface ThemeProviderProps extends ProviderProps {
1042
+ provider: ThemeProvider
1043
+ initialTheme?: string
1353
1044
  }
1354
1045
  ```
1355
1046
 
1356
- #### `UseSignupReturn`
1047
+ #### `RouterProviderProps`
1357
1048
 
1358
- Return type for useSignup hook.
1049
+ Props for router provider component.
1359
1050
 
1360
1051
  ```typescript
1361
- interface UseSignupReturn<T = unknown> {
1362
- status: UsePromiseState<AuthResult<T>>['status']
1363
- value: UsePromiseState<AuthResult<T>>['value']
1364
- error: UsePromiseState<AuthResult<T>>['error']
1365
- signup: (data: RegisterData) => Promise<AuthResult<T>>
1366
- reset: () => void
1052
+ interface RouterProviderProps extends ProviderProps {
1053
+ router: Router
1367
1054
  }
1368
1055
  ```
1369
1056
 
1370
- #### `UseStorageValueOptions`
1057
+ #### `I18nProviderProps`
1371
1058
 
1372
- Options for useStorageValue hook.
1059
+ Props for i18n provider component.
1373
1060
 
1374
1061
  ```typescript
1375
- interface UseStorageValueOptions<T> {
1376
- /**
1377
- * Default value if key doesn't exist.
1378
- */
1379
- defaultValue?: T
1380
- /**
1381
- * Whether to sync across tabs/windows (if supported by storage provider).
1382
- */
1383
- sync?: boolean
1062
+ interface I18nProviderProps extends ProviderProps {
1063
+ provider: I18nProvider
1384
1064
  }
1385
1065
  ```
1386
1066
 
1387
- #### `UseStorageValueResult`
1067
+ #### `HttpProviderProps`
1388
1068
 
1389
- Result of useStorageValue hook.
1069
+ Props for http provider component.
1390
1070
 
1391
1071
  ```typescript
1392
- interface UseStorageValueResult<T> {
1393
- value: T | undefined
1394
- setValue: (value: T) => Promise<void>
1395
- removeValue: () => Promise<void>
1396
- loading: boolean
1397
- error: Error | null
1072
+ interface HttpProviderProps extends ProviderProps {
1073
+ client: HttpClient
1398
1074
  }
1399
1075
  ```
1400
1076
 
1401
- #### `UseStoreOptions`
1077
+ #### `StorageProviderProps`
1402
1078
 
1403
- Hook options for useStore.
1079
+ Props for storage provider component.
1404
1080
 
1405
1081
  ```typescript
1406
- interface UseStoreOptions<T, S> {
1407
- selector?: (state: T) => S
1408
- equalityFn?: (a: S, b: S) => boolean
1082
+ interface StorageProviderProps extends ProviderProps {
1083
+ provider: StorageProvider
1409
1084
  }
1410
1085
  ```
1411
1086
 
1412
- #### `UseThemeResult`
1087
+ #### `LoggerProviderProps`
1413
1088
 
1414
- Hook result for useTheme.
1089
+ Props for logger provider component.
1415
1090
 
1416
1091
  ```typescript
1417
- interface UseThemeResult {
1418
- theme: Theme
1419
- themeName: string
1420
- setTheme: (name: string) => void
1421
- toggleTheme: () => void
1422
- mode: 'light' | 'dark'
1092
+ interface LoggerProviderProps extends ProviderProps {
1093
+ provider: LoggerProvider
1423
1094
  }
1424
1095
  ```
1425
1096
 
1426
- #### `UseTranslationResult`
1097
+ #### `ChatProviderProps`
1427
1098
 
1428
- Hook result for useTranslation.
1099
+ Props for the ChatProvider React component.
1429
1100
 
1430
1101
  ```typescript
1431
- interface UseTranslationResult {
1432
- t: I18nProvider['t']
1433
- locale: string
1434
- setLocale: I18nProvider['setLocale']
1435
- locales: ReturnType<I18nProvider['getLocales']>
1436
- formatNumber: I18nProvider['formatNumber']
1437
- formatDate: I18nProvider['formatDate']
1438
- direction: 'ltr' | 'rtl'
1102
+ interface ChatProviderProps extends ProviderProps {
1103
+ provider: ChatProvider
1439
1104
  }
1440
1105
  ```
1441
1106
 
1442
- #### `UseVerifyPaymentReturnOptions`
1107
+ #### `WorkspaceProviderProps`
1443
1108
 
1444
- Options for {@link useVerifyPaymentReturn}.
1109
+ Props for workspace provider component.
1445
1110
 
1446
1111
  ```typescript
1447
- interface UseVerifyPaymentReturnOptions {
1448
- /**
1449
- * Provider name to verify with, when the return URL carries no `provider`
1450
- * query parameter. Leave unset to verify only what the URL names.
1451
- */
1452
- provider?: string
1453
-
1454
- /** Set `false` to skip verification entirely (e.g. behind a feature flag). */
1455
- enabled?: boolean
1112
+ interface WorkspaceProviderProps extends ProviderProps {
1113
+ provider: WorkspaceProvider
1114
+ }
1115
+ ```
1456
1116
 
1457
- /**
1458
- * Remove the provider's query parameters from the address bar once the
1459
- * purchase is verified, so a reload (or a shared link) cannot replay the
1460
- * verification. Defaults to `true`.
1461
- */
1462
- cleanUrl?: boolean
1117
+ #### `EditorProviderProps`
1463
1118
 
1464
- /** Called once, after the purchase verifies. */
1465
- onVerified?: () => void
1119
+ Props for editor provider component.
1466
1120
 
1467
- /** Called when verification fails. */
1468
- onError?: (error: Error) => void
1121
+ ```typescript
1122
+ interface EditorProviderProps extends ProviderProps {
1123
+ provider: EditorProvider
1469
1124
  }
1470
1125
  ```
1471
1126
 
1472
- #### `UseVerifyPaymentReturnResult`
1127
+ #### `PreviewProviderProps`
1473
1128
 
1474
- State of the post-checkout verification.
1129
+ Props for preview provider component.
1475
1130
 
1476
1131
  ```typescript
1477
- interface UseVerifyPaymentReturnResult {
1132
+ interface PreviewProviderProps extends ProviderProps {
1133
+ provider: PreviewProvider
1134
+ }
1135
+ ```
1136
+
1137
+ #### `MoleculeProviderProps`
1138
+
1139
+ Properties for molecule provider.
1140
+
1141
+ ```typescript
1142
+ interface MoleculeProviderProps extends ProviderProps {
1143
+ state?: StateProvider
1144
+ auth?: AuthClient<unknown>
1145
+ theme?: ThemeProvider
1146
+ router?: Router
1147
+ i18n?: I18nProvider
1148
+ http?: HttpClient
1149
+ storage?: StorageProvider
1150
+ logger?: LoggerProvider
1151
+ chat?: ChatProvider
1152
+ workspace?: WorkspaceProvider
1153
+ editor?: EditorProvider
1154
+ preview?: PreviewProvider
1155
+ }
1156
+ ```
1157
+
1158
+ #### `UseStoreOptions`
1159
+
1160
+ Hook options for useStore.
1161
+
1162
+ ```typescript
1163
+ interface UseStoreOptions<T, S> {
1164
+ selector?: (state: T) => S
1165
+ equalityFn?: (a: S, b: S) => boolean
1166
+ }
1167
+ ```
1168
+
1169
+ #### `UseAuthOptions`
1170
+
1171
+ Hook options for useAuth.
1172
+
1173
+ ```typescript
1174
+ interface UseAuthOptions {
1175
+ /**
1176
+ * Whether to automatically refresh the token on mount.
1177
+ */
1178
+ autoRefresh?: boolean
1179
+ }
1180
+ ```
1181
+
1182
+ #### `UseAuthResult`
1183
+
1184
+ Hook result for useAuth.
1185
+
1186
+ ```typescript
1187
+ interface UseAuthResult<T = unknown> {
1188
+ state: AuthState<T>
1189
+ login: AuthClient<T>['login']
1190
+ logout: AuthClient<T>['logout']
1191
+ register: AuthClient<T>['register']
1192
+ refresh: AuthClient<T>['refresh']
1193
+ setUser: AuthClient<T>['setUser']
1194
+ isAuthenticated: boolean
1195
+ isLoading: boolean
1196
+ user: T | null
1197
+ }
1198
+ ```
1199
+
1200
+ #### `UseThemeResult`
1201
+
1202
+ Hook result for useTheme.
1203
+
1204
+ ```typescript
1205
+ interface UseThemeResult {
1206
+ theme: Theme
1207
+ themeName: string
1208
+ setTheme: (name: string) => void
1209
+ toggleTheme: () => void
1210
+ mode: 'light' | 'dark'
1211
+ }
1212
+ ```
1213
+
1214
+ #### `UseRouterResult`
1215
+
1216
+ Hook result for useRouter.
1217
+
1218
+ ```typescript
1219
+ interface UseRouterResult {
1220
+ location: Router['getLocation'] extends () => infer R ? R : never
1221
+ params: Record<string, string>
1222
+ query: QueryParams
1223
+ navigate: Router['navigate']
1224
+ navigateTo: Router['navigateTo']
1225
+ back: Router['back']
1226
+ forward: Router['forward']
1227
+ isActive: Router['isActive']
1228
+ }
1229
+ ```
1230
+
1231
+ #### `UseTranslationResult`
1232
+
1233
+ Hook result for useTranslation.
1234
+
1235
+ ```typescript
1236
+ interface UseTranslationResult {
1237
+ t: I18nProvider['t']
1238
+ locale: string
1239
+ setLocale: I18nProvider['setLocale']
1240
+ locales: ReturnType<I18nProvider['getLocales']>
1241
+ formatNumber: I18nProvider['formatNumber']
1242
+ formatDate: I18nProvider['formatDate']
1243
+ direction: 'ltr' | 'rtl'
1244
+ }
1245
+ ```
1246
+
1247
+ #### `UseChatOptions`
1248
+
1249
+ Hook options for useChat.
1250
+
1251
+ ```typescript
1252
+ interface UseChatOptions {
1253
+ /** Chat endpoint (e.g., '/projects/123/chat'). */
1254
+ endpoint: string
1255
+ /** Project ID for context. */
1256
+ projectId?: string
1257
+ /**
1258
+ * Display name of the AI coding agent, interpolated into user-facing chat
1259
+ * copy (e.g. the stalled-stream notice). The host passes its own agent brand
1260
+ * name; defaults to the neutral `DEFAULT_AGENT_NAME` so the shared hook never
1261
+ * names a specific product.
1262
+ */
1263
+ agentName?: string
1264
+ /** Load history on mount. */
1265
+ loadOnMount?: boolean
1266
+ /**
1267
+ * This client may only WATCH the conversation (e.g. a read-only project
1268
+ * viewer): the hook never issues chat POSTs on its behalf — no resume
1269
+ * request after a reload, no auto-retries. A live turn is followed through
1270
+ * the remote-watch path instead: pushed broadcast frames (applyRemoteEvent)
1271
+ * render it in real time and the history reconcile poll backstops gaps, with
1272
+ * `isRemoteStreaming` driving the activity indicator.
1273
+ */
1274
+ readOnly?: boolean
1275
+ /** Called when a file is created or modified by a tool call (path + new content). */
1276
+ onFileChange?: (path: string, content: string) => void
1277
+ /** Called when the AI switches between plan and execute modes. */
1278
+ onModeChange?: (mode: 'plan' | 'execute') => void
1279
+ /** Called when the backend assigns or confirms a conversation ID. */
1280
+ onConversationId?: (id: string) => void
1281
+ /** Called for every streaming event — useful for notifications, sounds, etc. */
1282
+ onStreamEvent?: (event: ChatStreamEvent) => void
1283
+ }
1284
+ ```
1285
+
1286
+ #### `SendMessageOptions`
1287
+
1288
+ Options for {@link UseChatResult.sendMessage}.
1289
+
1290
+ ```typescript
1291
+ interface SendMessageOptions {
1292
+ /**
1293
+ * Skip the optimistic local user-message bubble. The text is still sent to
1294
+ * the server. Used for ask_user responses: the answer is folded into the
1295
+ * ask_user tool card (a checkmark on the chosen option, or the custom text
1296
+ * shown in-card) rather than echoed as a separate message below it.
1297
+ */
1298
+ suppressUserMessage?: boolean
1299
+ /**
1300
+ * Mark this send as issued automatically on the user's behalf (e.g. an
1301
+ * auto-fix prompt). The optimistic local bubble and the persisted message are
1302
+ * flagged `automatic` so the chat renders it in the distinct auto-sent style
1303
+ * (agent avatar + accent border) instead of looking like the user typed it.
1304
+ */
1305
+ automatic?: boolean
1306
+ /**
1307
+ * Mark this send as the answer to the pending `ask_user` question. The most
1308
+ * recent unanswered `ask_user` tool call in the store is resolved in place —
1309
+ * its `output` is set to this answer — so the chosen option stays checked
1310
+ * across remounts (e.g. the discovery→IDE transition) instead of relying on
1311
+ * ephemeral component state that the answer's selection would otherwise lose.
1312
+ * Distinct from {@link suppressUserMessage} (which the post-boot kickoff also
1313
+ * sets) so resolving never misfires on a non-ask_user suppressed send.
1314
+ */
1315
+ askUserAnswer?: boolean
1316
+ /**
1317
+ * Mark an {@link automatic} send as directly requested by the user (e.g. the
1318
+ * editor's "Fix with AI" action, the broken-preview overlay's "Fix with AI"
1319
+ * button) rather than dispatched autonomously by the platform. A user Stop
1320
+ * suppresses autonomous automatic sends until the user re-engages; a
1321
+ * user-initiated one IS that re-engagement — it clears the stop and sends.
1322
+ */
1323
+ userInitiated?: boolean
1324
+ /**
1325
+ * Send on the SIDE CHANNEL: a human-to-human message (e.g. a team note) the
1326
+ * server intercepts before running any agent turn. When the provider supports
1327
+ * `sendSideMessage`, the send goes out IMMEDIATELY on an independent request —
1328
+ * it never queues behind an active turn, never takes over the streaming
1329
+ * state, and never tears down remote-turn tracking (a viewer's note while
1330
+ * watching a teammate's turn must not stop the watching). Falls back to the
1331
+ * normal send path on providers without side-channel support.
1332
+ */
1333
+ sideChannel?: boolean
1334
+ /**
1335
+ * Mark this send as composed through voice dictation — the mic button's
1336
+ * transcript was still present in the composer at submit. The optimistic
1337
+ * bubble and the persisted message are flagged `viaDictation` so the chat
1338
+ * renders a mic badge on the message, live and after a reload.
1339
+ */
1340
+ viaDictation?: boolean
1341
+ }
1342
+ ```
1343
+
1344
+ #### `UseChatResult`
1345
+
1346
+ Hook result for useChat.
1347
+
1348
+ ```typescript
1349
+ interface UseChatResult {
1350
+ messages: ChatMessage[]
1351
+ isLoading: boolean
1352
+ /**
1353
+ * True while a backend turn for this conversation streams WITHOUT this client
1354
+ * owning the request — a turn started in another tab, by a teammate, or any
1355
+ * server-side continuation. Detected from pushed (broadcast) chat events and
1356
+ * confirmed/cleared against the server's `streaming` history flag, so the Stop
1357
+ * control can stay visible and functional whenever ANY backend turn is live —
1358
+ * not only for sends this hook instance made.
1359
+ */
1360
+ isRemoteStreaming: boolean
1361
+ /**
1362
+ * Tell the hook a pushed (broadcast) chat event arrived for this conversation.
1363
+ * The host (ChatPanel) calls this from its push-channel handler; the hook then
1364
+ * confirms against the server's `streaming` flag and, while a remote turn is
1365
+ * live, keeps `isRemoteStreaming` true until the server reports it finished.
1366
+ */
1367
+ noteRemoteStreamEvent: () => void
1368
+ error: string | null
1369
+ /**
1370
+ * Metadata about a limit-related error, for a contextual call-to-action.
1371
+ * `limitType` names the RULE the backend enforced; `billingAction` names the
1372
+ * REMEDY it resolved (e.g. `add_funds`, `add_payment_method`,
1373
+ * `raise_spend_cap`, `upgrade`, `none`) and is what the button should be
1374
+ * built from — the same limit needs a different button per account.
1375
+ * `upgradeTier` is the plan an upgrade would move to, explicitly `null` when
1376
+ * there is no higher tier. The backend owns these vocabularies, so the
1377
+ * action/tier are plain strings here.
1378
+ */
1379
+ errorMeta: {
1380
+ limitType?: string
1381
+ requiresSignup?: boolean
1382
+ billingAction?: string
1383
+ upgradeTier?: string | null
1384
+ } | null
1385
+ /** Current agent mode — plan (read-only research) or execute (full access). */
1386
+ mode: 'plan' | 'execute'
1387
+ /**
1388
+ * Whether the conversation runs at the provider's fast/priority speed tier
1389
+ * (server-persisted per conversation; hydrated from the history load's
1390
+ * `fastMode` meta field, when the server provides one). Only meaningful for
1391
+ * models that support a fast tier — the server ignores it otherwise.
1392
+ */
1393
+ fastMode: boolean
1394
+ /**
1395
+ * Transient label for a background phase (e.g. the post-response verification
1396
+ * pass — "Type-checking the API", "Linting"), set by `status` stream events.
1397
+ * The UI shows it in place of the spinner's generic rotating messages; `null`
1398
+ * when no such phase is active.
1399
+ */
1400
+ streamingStatus: string | null
1401
+ /**
1402
+ * Commands the executor detached with `run_in_background`, newest last. Each
1403
+ * appears here the moment it starts and is replaced in place when it finishes,
1404
+ * so the UI can show work that outlives the tool call that started it.
1405
+ */
1406
+ backgroundTasks: BackgroundTaskState[]
1407
+ /**
1408
+ * Active 5XX backoff-retry countdown, or `null` when none is pending. After a
1409
+ * backend server error (HTTP 5XX) the hook does NOT surface a terminal error —
1410
+ * it shows this cancelable countdown and, when it elapses, auto-resumes the
1411
+ * turn where the user left off (`resume:true`). `secondsRemaining` ticks down
1412
+ * once per second; `attempt` is the 1-based retry number (capped at 3). 4XX,
1413
+ * limit/quota, and signup-required errors never auto-retry.
1414
+ */
1415
+ retryCountdown: { secondsRemaining: number; attempt: number } | null
1416
+ /** Update the local mode state (for instant mode toggle without an AI turn). */
1417
+ setMode: (mode: 'plan' | 'execute') => void
1418
+ /** Update the local fast-mode state (for instant toggle without an AI turn). */
1419
+ setFastMode: (fastMode: boolean) => void
1420
+ sendMessage: (
1421
+ message: string,
1422
+ attachments?: ChatAttachment[],
1423
+ options?: SendMessageOptions,
1424
+ ) => Promise<void>
1425
+ abort: () => void
1426
+ /**
1427
+ * Cancel a pending 5XX auto-retry. Clears the countdown and surfaces the
1428
+ * original error (via `error`) so the user sees why the turn failed.
1429
+ */
1430
+ cancelRetry: () => void
1431
+ clearHistory: () => Promise<void>
1432
+ /** Edit the content of a queued (not yet sent) message. */
1433
+ editQueuedMessage: (msgId: string, newContent: string) => void
1434
+ /** Remove a queued (not yet sent) message from the queue. */
1435
+ deleteQueuedMessage: (msgId: string) => void
1436
+ /** Remove queued auto-fix messages whose content references the given file path. */
1437
+ clearQueuedForFile: (filePath: string) => void
1438
+ /**
1439
+ * Append an inline transcript card (model / mode / skills / custom notice) as a
1440
+ * `role:'system'` card-message in the ONE message store. Used by the host (ChatPanel)
1441
+ * to render a TEAMMATE's broadcast `card` event live — this client's OWN cards arrive
1442
+ * through the stream and are appended internally. De-duped by the server-assigned id.
1443
+ */
1444
+ appendCardMessage: (
1445
+ id: string,
1446
+ timestamp: number,
1447
+ card: NonNullable<ChatMessage['cardEvent']>,
1448
+ ) => void
1449
+ /**
1450
+ * Append a COMPLETE, non-streaming chat message (a `message` stream event — e.g.
1451
+ * a teammate's human-only team note) to the ONE message store. Used by the host
1452
+ * (ChatPanel) to render a TEAMMATE's broadcast `message` event live — this
1453
+ * client's OWN `message` events arrive through the stream and are appended
1454
+ * internally. De-duped by the server-assigned message id.
1455
+ */
1456
+ appendCompleteMessage: (message: ChatMessage) => void
1457
+ /**
1458
+ * Ingest ONE pushed (broadcast) stream frame from a turn running elsewhere —
1459
+ * a teammate's send, another tab, a server-side continuation — into the ONE
1460
+ * message store, through the same content applier as an own SSE stream: text/
1461
+ * thinking deltas, tool events, verification, cards, complete messages, done.
1462
+ * The host (ChatPanel) calls this from its push-channel handler for every
1463
+ * broadcast frame of the OPEN conversation. Own echoes are dropped while a
1464
+ * local send is in flight (the SSE stream is authoritative for the sender);
1465
+ * complete id-carrying items (cards, team notes) always apply, de-duped.
1466
+ */
1467
+ applyRemoteEvent: (event: ChatStreamEvent) => void
1478
1468
  /**
1479
- * `idle` when this page load is not a checkout return (no transaction id in
1480
- * the URL) or auth is still hydrating; `verifying` while the API call is in
1481
- * flight; then `verified` or `failed`.
1469
+ * Reload history and converge the local view on the server transcript (and
1470
+ * re-enter a still-streaming turn). The page-lifecycle events run this
1471
+ * automatically; the host should ALSO call it whenever its chat push channel
1472
+ * (re)connects — a broadcast sent while that socket was down (a teammate's
1473
+ * team note against a backgrounded tab or a slept laptop) is otherwise lost
1474
+ * until the next lifecycle event happens to fire. Cheap when nothing changed:
1475
+ * an identical transcript is never re-applied.
1482
1476
  */
1483
- status: VerifyPaymentReturnStatus
1484
-
1485
- /** `true` when the URL identifies a purchase to verify. */
1486
- isReturn: boolean
1487
-
1488
- /** The provider named by the URL (or the `provider` option). */
1489
- provider: string | null
1490
-
1491
- /** The provider transaction/session id read from the URL. */
1492
- transactionId: string | null
1493
-
1494
- /** Why verification failed, when it did. */
1495
- error: Error | null
1496
-
1497
- /** Re-run the verification — wire this to a retry button. */
1498
- retry: () => void
1499
- }
1500
- ```
1501
-
1502
- #### `UseVersionResult`
1503
-
1504
- Hook return type.
1505
-
1506
- ```typescript
1507
- interface UseVersionResult {
1508
- state: VersionState
1509
- isUpdateAvailable: boolean
1510
- isChecking: boolean
1511
- isServiceWorkerWaiting: boolean
1512
- newVersion: string | undefined
1513
- checkForUpdates: () => Promise<boolean>
1514
- applyUpdate: (options?: { force?: boolean }) => void
1515
- dismissUpdate: () => void
1516
- startPeriodicChecks: (options?: UpdateCheckOptions) => void
1517
- stopPeriodicChecks: () => void
1477
+ reconcileHistory: () => Promise<void>
1518
1478
  }
1519
1479
  ```
1520
1480
 
@@ -1534,28 +1494,58 @@ interface UseWorkspaceResult {
1534
1494
  }
1535
1495
  ```
1536
1496
 
1537
- #### `WorkspaceProviderProps`
1497
+ #### `UseEditorResult`
1538
1498
 
1539
- Props for workspace provider component.
1499
+ Hook result for useEditor.
1540
1500
 
1541
1501
  ```typescript
1542
- interface WorkspaceProviderProps extends ProviderProps {
1543
- provider: WorkspaceProvider
1502
+ interface UseEditorResult {
1503
+ tabs: EditorTab[]
1504
+ activeFile: string | null
1505
+ openFile: (file: EditorFile) => void
1506
+ closeFile: (path: string) => void
1507
+ getContent: () => string | null
1508
+ setContent: (path: string, content: string) => void
1509
+ setActiveTab: (path: string) => void
1510
+ mount: EditorProvider['mount']
1511
+ dispose: () => void
1512
+ focus: () => void
1513
+ openDiff: (file: DiffFile) => void
1514
+ closeDiff: () => void
1515
+ pinTab: (path: string) => void
1516
+ addExtraLib: (content: string, filePath: string) => void
1517
+ onFixWithAI: (callback: (request: FixWithAIRequest) => void) => () => void
1544
1518
  }
1545
1519
  ```
1546
1520
 
1547
- ### Types
1548
-
1549
- #### `AsyncExtendState`
1521
+ #### `UsePreviewResult`
1550
1522
 
1551
- Async-capable extendState function for partial updates.
1523
+ Hook result for usePreview.
1552
1524
 
1553
1525
  ```typescript
1554
- type AsyncExtendState<T> = (
1555
- partial: Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
1556
- ) => void
1526
+ interface UsePreviewResult {
1527
+ state: PreviewState
1528
+ setUrl: (url: string) => void
1529
+ refresh: () => void
1530
+ setDevice: (device: DeviceFrame) => void
1531
+ openExternal: () => void
1532
+ /**
1533
+ * Records a navigation the running preview reported via its `molecule:navigate`
1534
+ * message — updates the displayed current location without reloading the iframe.
1535
+ * Pass `isReplace` when the preview REPLACED its current history entry (a
1536
+ * `replaceState` redirect/canonicalization) so the forward stack is preserved
1537
+ * instead of truncated (a `pushState`, the default, truncates forward).
1538
+ */
1539
+ recordNavigation: (url: string, isReplace?: boolean) => void
1540
+ /** Navigates the preview to the previous navigation-history entry (Back). */
1541
+ back: () => void
1542
+ /** Navigates the preview to the next navigation-history entry (Forward). */
1543
+ forward: () => void
1544
+ }
1557
1545
  ```
1558
1546
 
1547
+ ### Types
1548
+
1559
1549
  #### `AsyncSetState`
1560
1550
 
1561
1551
  Async-capable setState function.
@@ -1564,6 +1554,18 @@ Async-capable setState function.
1564
1554
  type AsyncSetState<T> = (value: T | ((prev: T) => T) | Promise<T | ((prev: T) => T)>) => void
1565
1555
  ```
1566
1556
 
1557
+ - `value` — The new state value, an updater function receiving previous state, or a Promise resolving to either.
1558
+
1559
+ #### `AsyncExtendState`
1560
+
1561
+ Async-capable extendState function for partial updates.
1562
+
1563
+ ```typescript
1564
+ type AsyncExtendState<T> = (
1565
+ partial: Partial<T> | ((prev: T) => Partial<T>) | Promise<Partial<T> | ((prev: T) => Partial<T>)>,
1566
+ ) => void
1567
+ ```
1568
+
1567
1569
  #### `UseCapacitorAppResult`
1568
1570
 
1569
1571
  Hook return type.
@@ -1584,194 +1586,153 @@ type VerifyPaymentReturnStatus = 'idle' | 'verifying' | 'verified' | 'failed'
1584
1586
 
1585
1587
  ### Functions
1586
1588
 
1587
- #### `AuthProvider(props)`
1589
+ #### `resetAIModelsCache()`
1588
1590
 
1589
- Provider for authentication.
1591
+ Test-only: drops every cached model list so the next `useAIModels` call
1592
+ refetches. Exposed for unit tests; do not call from production code.
1590
1593
 
1591
1594
  ```typescript
1592
- function AuthProvider({
1593
- client,
1594
- children,
1595
- }: AuthProviderProps<T>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1595
+ function resetAIModelsCache(): void
1596
1596
  ```
1597
1597
 
1598
- - `props` — Component props (see {@link AuthProviderProps}).
1599
-
1600
- **Returns:** The rendered auth provider element.
1601
-
1602
- #### `ChatProvider(props)`
1598
+ #### `useAIModels(projectId)`
1603
1599
 
1604
- Provider for AI chat.
1600
+ Subscribes to the cached AI model catalog. The first mount of a scope
1601
+ triggers a single `GET /ai/models` fetch; subsequent mounts return the
1602
+ cached result.
1605
1603
 
1606
1604
  ```typescript
1607
- function ChatProvider({
1608
- provider,
1609
- children,
1610
- }: ChatProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1605
+ function useAIModels(projectId?: string): UseAIModelsResult
1611
1606
  ```
1612
1607
 
1613
- - `props` — Component props (see {@link ChatProviderProps}).
1614
-
1615
- **Returns:** The rendered chat provider element.
1608
+ - `projectId` — Optional project scope: includes that project's custom ("bring your own AI") models on servers that support them.
1616
1609
 
1617
- #### `convergeHistory(prev, history)`
1610
+ **Returns:** Models, free-tier model, loading flag, and error.
1618
1611
 
1619
- Converge a live store on a fresh server history WITHOUT rewinding anything
1620
- already on screen. This is the ONE place a server transcript is applied to a
1621
- local view — the page-lifecycle/push reconcile, the remote-turn poll, the
1622
- dropped-stream reconcile and the resume poll all go through it, because two
1623
- paths that almost agree is how a message came to vanish and come back
1624
- (reported 2026-09-21).
1612
+ #### `useAsyncState(initialState)`
1625
1613
 
1626
- Per message id the further-along copy wins ({@link messageProgress}); a TIE
1627
- keeps the local copy, so an unchanged transcript returns the same object
1628
- references and a poll neither churns React nor rewinds. Messages only the
1629
- server has are added in the server's order (filling gaps a watcher missed);
1630
- messages only the store has ({@link localOnlyMessages} — an answer still
1631
- carrying its local id, a session-local card, a turn the server has not
1632
- persisted yet) are kept after them.
1614
+ Hook like useState but accepts Promises and supports partial state extension.
1633
1615
 
1634
1616
  ```typescript
1635
- function convergeHistory(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1617
+ function useAsyncState(initialState: T): [T, AsyncSetState<T>, AsyncExtendState<T>]
1636
1618
  ```
1637
1619
 
1638
- - `prev` — The store's current messages.
1639
- - `history` — The messages from the server's history endpoint.
1620
+ - `initialState` — Initial state value
1640
1621
 
1641
- **Returns:** The converged message list.
1622
+ **Returns:** Tuple of [state, asyncSetState, asyncExtendState]
1642
1623
 
1643
- #### `EditorProvider(props)`
1624
+ #### `useAuthClient()`
1644
1625
 
1645
- Provider for code editor.
1626
+ Hook to access the auth client from context.
1646
1627
 
1647
1628
  ```typescript
1648
- function EditorProvider({
1649
- provider,
1650
- children,
1651
- }: EditorProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1629
+ function useAuthClient(): AuthClient<T>
1652
1630
  ```
1653
1631
 
1654
- - `props` — Component props (see {@link EditorProviderProps}).
1655
-
1656
- **Returns:** The rendered editor provider element.
1632
+ **Returns:** The auth client from context
1657
1633
 
1658
- #### `HttpProvider(props)`
1634
+ #### `useAuth(options)`
1659
1635
 
1660
- Provider for HTTP client.
1636
+ Hook for authentication state and actions.
1661
1637
 
1662
1638
  ```typescript
1663
- function HttpProvider({
1664
- client,
1665
- children,
1666
- }: HttpProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1639
+ function useAuth(options?: UseAuthOptions): UseAuthResult<T>
1667
1640
  ```
1668
1641
 
1669
- - `props` — Component props (see {@link HttpProviderProps}).
1642
+ - `options` — Hook options
1670
1643
 
1671
- **Returns:** The rendered HTTP provider element.
1644
+ **Returns:** Auth state and action methods
1672
1645
 
1673
- #### `I18nProvider(props)`
1646
+ #### `useUser()`
1674
1647
 
1675
- Provider for internationalization.
1648
+ Hook to get just the authenticated user.
1676
1649
 
1677
1650
  ```typescript
1678
- function I18nProvider({
1679
- provider,
1680
- children,
1681
- }: I18nProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1651
+ function useUser(): T | null
1682
1652
  ```
1683
1653
 
1684
- - `props` — Component props (see {@link I18nProviderProps}).
1685
-
1686
- **Returns:** The rendered i18n provider element.
1654
+ **Returns:** The authenticated user or null
1687
1655
 
1688
- #### `localOnlyMessages(prev, history)`
1656
+ #### `useIsAuthenticated()`
1689
1657
 
1690
- The messages only the local store holds, given a server history: optimistic
1691
- bubbles and session-local cards, minus the optimistic ECHO of a send the
1692
- server already persisted. A local user message carries a local id
1693
- (`user-N`), the server's copy a server id, so ids never match — content does.
1694
- Without this, the dashboard's first prompt (auto-sent by the workspace,
1695
- then merged back in from history by the remote-stream poll) rendered as two
1696
- identical user bubbles in every new project (2026-09-08).
1658
+ Hook to check if user is authenticated.
1697
1659
 
1698
1660
  ```typescript
1699
- function localOnlyMessages(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1661
+ function useIsAuthenticated(): boolean
1700
1662
  ```
1701
1663
 
1702
- - `prev` — The store's current messages.
1703
- - `history` — The server's history.
1664
+ **Returns:** Whether the user is authenticated
1704
1665
 
1705
- **Returns:** The local-only messages to keep after the merged history.
1666
+ #### `useCapacitorApp(options)`
1706
1667
 
1707
- #### `LoggerProvider(props)`
1668
+ Hook for Capacitor app initialization and state management.
1708
1669
 
1709
- Provider for logging.
1670
+ Creates a `CapacitorApp` coordinator on mount, subscribes to state changes,
1671
+ and auto-initializes. Cleans up listeners on unmount via `destroy()`.
1710
1672
 
1711
1673
  ```typescript
1712
- function LoggerProvider({
1713
- provider,
1714
- children,
1715
- }: LoggerProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1674
+ function useCapacitorApp(options?: CapacitorAppOptions): UseCapacitorAppResult
1716
1675
  ```
1717
1676
 
1718
- - `props` — Component props (see {@link LoggerProviderProps}).
1719
-
1720
- **Returns:** The rendered logger provider element.
1677
+ - `options` — Capacitor app configuration options
1721
1678
 
1722
- #### `MoleculeProvider(props)`
1679
+ **Returns:** Current app state and an `initialize` function for manual re-initialization
1723
1680
 
1724
- Combined provider for all molecule services.
1681
+ #### `useChangePassword()`
1725
1682
 
1726
- Provides a convenient way to wrap your app with all molecule providers at once.
1727
- Only providers that are passed will be included.
1683
+ Hook for changing password with async state tracking.
1728
1684
 
1729
1685
  ```typescript
1730
- function MoleculeProvider({
1731
- children,
1732
- state,
1733
- auth,
1734
- theme,
1735
- router,
1736
- i18n,
1737
- http,
1738
- storage,
1739
- logger,
1740
- chat,
1741
- workspace,
1742
- editor,
1743
- preview,
1744
- }: MoleculeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1686
+ function useChangePassword(): UseChangePasswordReturn
1745
1687
  ```
1746
1688
 
1747
- - `props` — Component props (see {@link MoleculeProviderProps}) — each service is optional, and ONLY the services passed are provided to the tree.
1689
+ **Returns:** Change password state and action
1748
1690
 
1749
- **Returns:** The rendered combined provider element.
1691
+ #### `convergeHistory(prev, history)`
1750
1692
 
1751
- #### `PreviewProvider(props)`
1693
+ Converge a live store on a fresh server history WITHOUT rewinding anything
1694
+ already on screen. This is the ONE place a server transcript is applied to a
1695
+ local view — the page-lifecycle/push reconcile, the remote-turn poll, the
1696
+ dropped-stream reconcile and the resume poll all go through it, because two
1697
+ paths that almost agree is how a message came to vanish and come back
1698
+ (reported 2026-09-21).
1752
1699
 
1753
- Provider for live preview.
1700
+ Per message id the further-along copy wins ({@link messageProgress}); a TIE
1701
+ keeps the local copy, so an unchanged transcript returns the same object
1702
+ references and a poll neither churns React nor rewinds. Messages only the
1703
+ server has are added in the server's order (filling gaps a watcher missed);
1704
+ messages only the store has ({@link localOnlyMessages} — an answer still
1705
+ carrying its local id, a session-local card, a turn the server has not
1706
+ persisted yet) are kept after them.
1754
1707
 
1755
1708
  ```typescript
1756
- function PreviewProvider({
1757
- provider,
1758
- children,
1759
- }: PreviewProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1709
+ function convergeHistory(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1760
1710
  ```
1761
1711
 
1762
- - `props` — Component props (see {@link PreviewProviderProps}).
1712
+ - `prev` — The store's current messages.
1713
+ - `history` — The messages from the server's history endpoint.
1763
1714
 
1764
- **Returns:** The rendered preview provider element.
1715
+ **Returns:** The converged message list.
1765
1716
 
1766
- #### `resetAIModelsCache()`
1717
+ #### `localOnlyMessages(prev, history)`
1767
1718
 
1768
- Test-only: drops every cached model list so the next `useAIModels` call
1769
- refetches. Exposed for unit tests; do not call from production code.
1719
+ The messages only the local store holds, given a server history: optimistic
1720
+ bubbles and session-local cards, minus the optimistic ECHO of a send the
1721
+ server already persisted. A local user message carries a local id
1722
+ (`user-N`), the server's copy a server id, so ids never match — content does.
1723
+ Without this, the dashboard's first prompt (auto-sent by the workspace,
1724
+ then merged back in from history by the remote-stream poll) rendered as two
1725
+ identical user bubbles in every new project (2026-09-08).
1770
1726
 
1771
1727
  ```typescript
1772
- function resetAIModelsCache(): void
1728
+ function localOnlyMessages(prev: ChatMessage[], history: ChatMessage[]): ChatMessage[]
1773
1729
  ```
1774
1730
 
1731
+ - `prev` — The store's current messages.
1732
+ - `history` — The server's history.
1733
+
1734
+ **Returns:** The local-only messages to keep after the merged history.
1735
+
1775
1736
  #### `resetChatStoresForTests()`
1776
1737
 
1777
1738
  Test-only: clear all conversation stores. The store is module-level (it must
@@ -1782,186 +1743,181 @@ outlive component mounts), so it persists across test cases — reset it in a
1782
1743
  function resetChatStoresForTests(): void
1783
1744
  ```
1784
1745
 
1785
- #### `RouterProvider(props)`
1746
+ #### `useChatProvider()`
1786
1747
 
1787
- Provider for routing.
1748
+ Access the chat provider from context.
1788
1749
 
1789
1750
  ```typescript
1790
- function RouterProvider({
1791
- router,
1792
- children,
1793
- }: RouterProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1751
+ function useChatProvider(): ChatProvider
1794
1752
  ```
1795
1753
 
1796
- - `props` — Component props (see {@link RouterProviderProps}).
1754
+ **Returns:** The ChatProvider instance from the nearest ChatContext.
1797
1755
 
1798
- **Returns:** The rendered router provider element.
1756
+ #### `useChat(options)`
1799
1757
 
1800
- #### `StateProvider(props)`
1758
+ Hook for AI chat with streaming support.
1801
1759
 
1802
- Provider for state management.
1760
+ Manages message state, sends messages to the backend, and handles
1761
+ SSE streaming responses.
1803
1762
 
1804
1763
  ```typescript
1805
- function StateProvider({
1806
- provider,
1807
- children,
1808
- }: StateProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1764
+ function useChat(options: UseChatOptions): UseChatResult
1809
1765
  ```
1810
1766
 
1811
- - `props` — Component props (see {@link StateProviderProps}).
1767
+ - `options` — Chat configuration including endpoint URL, project ID, and whether to load history on mount.
1812
1768
 
1813
- **Returns:** The rendered state provider element.
1769
+ **Returns:** Chat state and controls: messages, isLoading, error, sendMessage, abort, and clearHistory.
1814
1770
 
1815
- #### `StorageProvider(props)`
1771
+ #### `useDevice()`
1816
1772
 
1817
- Provider for storage.
1773
+ Hook for device information.
1774
+
1775
+ Uses module-level `getProvider()` — device info is a singleton, not context-provided.
1776
+ Device info is static and doesn't change at runtime, so this uses `useMemo`.
1818
1777
 
1819
1778
  ```typescript
1820
- function StorageProvider({
1821
- provider,
1822
- children,
1823
- }: StorageProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1779
+ function useDevice(): UseDeviceResult
1824
1780
  ```
1825
1781
 
1826
- - `props` — Component props (see {@link StorageProviderProps}).
1827
-
1828
- **Returns:** The rendered storage provider element.
1782
+ **Returns:** Device information and utility methods
1829
1783
 
1830
- #### `ThemeProvider(props)`
1784
+ #### `useEditorProvider()`
1831
1785
 
1832
- Provider for theming.
1786
+ Access the editor provider from context.
1833
1787
 
1834
1788
  ```typescript
1835
- function ThemeProvider({
1836
- provider,
1837
- children,
1838
- }: ThemeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
1789
+ function useEditorProvider(): EditorProvider
1839
1790
  ```
1840
1791
 
1841
- - `props` — Component props (see {@link ThemeProviderProps}).
1842
-
1843
- **Returns:** The rendered theme provider element.
1792
+ **Returns:** The EditorProvider instance from the nearest EditorContext.
1844
1793
 
1845
- #### `useAIModels(projectId)`
1794
+ #### `useEditor()`
1846
1795
 
1847
- Subscribes to the cached AI model catalog. The first mount of a scope
1848
- triggers a single `GET /ai/models` fetch; subsequent mounts return the
1849
- cached result.
1796
+ Hook for code editor management.
1850
1797
 
1851
1798
  ```typescript
1852
- function useAIModels(projectId?: string): UseAIModelsResult
1799
+ function useEditor(): UseEditorResult
1853
1800
  ```
1854
1801
 
1855
- - `projectId` — Optional project scope: includes that project's custom ("bring your own AI") models on servers that support them.
1856
-
1857
- **Returns:** Models, free-tier model, loading flag, and error.
1802
+ **Returns:** Editor state and controls: tabs, activeFile, openFile, closeFile, getContent, setContent, setActiveTab, mount, dispose, and focus.
1858
1803
 
1859
- #### `useAsyncState(initialState)`
1804
+ #### `useForm(options)`
1860
1805
 
1861
- Hook like useState but accepts Promises and supports partial state extension.
1806
+ Hook for form state management.
1862
1807
 
1863
1808
  ```typescript
1864
- function useAsyncState(initialState: T): [T, AsyncSetState<T>, AsyncExtendState<T>]
1809
+ function useForm(options: UseFormOptions<T>): UseFormResult<T>
1865
1810
  ```
1866
1811
 
1867
- - `initialState` — Initial state value
1812
+ - `options` — Form options including createForm from a forms provider
1868
1813
 
1869
- **Returns:** Tuple of [state, asyncSetState, asyncExtendState]
1814
+ **Returns:** Form state and methods
1870
1815
 
1871
- #### `useAuth(options)`
1816
+ #### `useWatch(form, name)`
1872
1817
 
1873
- Hook for authentication state and actions.
1818
+ Hook to watch a specific field value.
1874
1819
 
1875
1820
  ```typescript
1876
- function useAuth(options?: UseAuthOptions): UseAuthResult<T>
1821
+ function useWatch(form: FormController<T>, name: K): T[K]
1877
1822
  ```
1878
1823
 
1879
- - `options` — Hook options
1824
+ - `form` — Form controller
1825
+ - `name` — Field name to watch
1880
1826
 
1881
- **Returns:** Auth state and action methods
1827
+ **Returns:** Current field value
1882
1828
 
1883
- #### `useAuthClient()`
1829
+ #### `useFieldState(form, name)`
1884
1830
 
1885
- Hook to access the auth client from context.
1831
+ Hook to get field-level state.
1886
1832
 
1887
1833
  ```typescript
1888
- function useAuthClient(): AuthClient<T>
1834
+ function useFieldState(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>
1889
1835
  ```
1890
1836
 
1891
- **Returns:** The auth client from context
1837
+ - `form` — Form controller
1838
+ - `name` — Field name
1892
1839
 
1893
- #### `useCapacitorApp(options)`
1840
+ **Returns:** Field state (value, error, touched, dirty, valid)
1894
1841
 
1895
- Hook for Capacitor app initialization and state management.
1842
+ #### `useHttpClient()`
1896
1843
 
1897
- Creates a `CapacitorApp` coordinator on mount, subscribes to state changes,
1898
- and auto-initializes. Cleans up listeners on unmount via `destroy()`.
1844
+ Hook to access the HTTP client from context.
1899
1845
 
1900
1846
  ```typescript
1901
- function useCapacitorApp(options?: CapacitorAppOptions): UseCapacitorAppResult
1847
+ function useHttpClient(): HttpClient
1902
1848
  ```
1903
1849
 
1904
- - `options` — Capacitor app configuration options
1905
-
1906
- **Returns:** Current app state and an `initialize` function for manual re-initialization
1850
+ **Returns:** The HTTP client from context
1907
1851
 
1908
- #### `useChangePassword()`
1852
+ #### `useHttp(method, url, options)`
1909
1853
 
1910
- Hook for changing password with async state tracking.
1854
+ Hook for making HTTP requests with state management.
1911
1855
 
1912
1856
  ```typescript
1913
- function useChangePassword(): UseChangePasswordReturn
1857
+ function useHttp(
1858
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
1859
+ url: string,
1860
+ options?: UseHttpOptions<T>,
1861
+ ): UseHttpResult<T>
1914
1862
  ```
1915
1863
 
1916
- **Returns:** Change password state and action
1864
+ - `method` — HTTP method
1865
+ - `url` — Request URL
1866
+ - `options` — Request options
1917
1867
 
1918
- #### `useChat(options)`
1868
+ **Returns:** Request state and execute function
1919
1869
 
1920
- Hook for AI chat with streaming support.
1870
+ #### `useGet(url, options)`
1921
1871
 
1922
- Manages message state, sends messages to the backend, and handles
1923
- SSE streaming responses.
1872
+ Hook for GET requests.
1924
1873
 
1925
1874
  ```typescript
1926
- function useChat(options: UseChatOptions): UseChatResult
1875
+ function useGet(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1927
1876
  ```
1928
1877
 
1929
- - `options` — Chat configuration including endpoint URL, project ID, and whether to load history on mount.
1878
+ - `url` — Request URL to fetch from.
1879
+ - `options` — HTTP request options including callbacks and request config.
1930
1880
 
1931
- **Returns:** Chat state and controls: messages, isLoading, error, sendMessage, abort, and clearHistory.
1881
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1932
1882
 
1933
- #### `useChatProvider()`
1883
+ #### `usePost(url, options)`
1934
1884
 
1935
- Access the chat provider from context.
1885
+ Hook for POST requests.
1936
1886
 
1937
1887
  ```typescript
1938
- function useChatProvider(): ChatProvider
1888
+ function usePost(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1939
1889
  ```
1940
1890
 
1941
- **Returns:** The ChatProvider instance from the nearest ChatContext.
1891
+ - `url` — Request URL to post to.
1892
+ - `options` — HTTP request options including body data and callbacks.
1942
1893
 
1943
- #### `useChildLogger(parentName, context)`
1894
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1944
1895
 
1945
- Hook to create a child logger with additional context.
1896
+ #### `usePut(url, options)`
1897
+
1898
+ Hook for PUT requests.
1946
1899
 
1947
1900
  ```typescript
1948
- function useChildLogger(parentName: string, context: Record<string, unknown>): Logger
1901
+ function usePut(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1949
1902
  ```
1950
1903
 
1951
- - `parentName` — Parent logger name
1952
- - `context` — Additional context to include in logs
1904
+ - `url` — Request URL to send the PUT request to.
1905
+ - `options` — HTTP request options including body data and callbacks.
1953
1906
 
1954
- **Returns:** Child logger instance
1907
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1955
1908
 
1956
- #### `useCurrentTheme()`
1909
+ #### `usePatch(url, options)`
1957
1910
 
1958
- Hook to get just the current theme object.
1911
+ Hook for PATCH requests.
1959
1912
 
1960
1913
  ```typescript
1961
- function useCurrentTheme(): Theme
1914
+ function usePatch(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1962
1915
  ```
1963
1916
 
1964
- **Returns:** The current theme
1917
+ - `url` — Request URL to send the PATCH request to.
1918
+ - `options` — HTTP request options including partial body data and callbacks.
1919
+
1920
+ **Returns:** Request state (data, loading, error) and controls (execute, reset).
1965
1921
 
1966
1922
  #### `useDelete(url, options)`
1967
1923
 
@@ -1976,219 +1932,218 @@ function useDelete(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
1976
1932
 
1977
1933
  **Returns:** Request state (data, loading, error) and controls (execute, reset).
1978
1934
 
1979
- #### `useDevice()`
1980
-
1981
- Hook for device information.
1935
+ #### `useLoggerProvider()`
1982
1936
 
1983
- Uses module-level `getProvider()` — device info is a singleton, not context-provided.
1984
- Device info is static and doesn't change at runtime, so this uses `useMemo`.
1937
+ Hook to access the logger provider from context.
1985
1938
 
1986
1939
  ```typescript
1987
- function useDevice(): UseDeviceResult
1940
+ function useLoggerProvider(): LoggerProvider
1988
1941
  ```
1989
1942
 
1990
- **Returns:** Device information and utility methods
1943
+ **Returns:** The logger provider from context
1991
1944
 
1992
- #### `useDirection()`
1945
+ #### `useLogger(name, config)`
1993
1946
 
1994
- Hook to get the text direction.
1947
+ Hook to get a logger instance.
1995
1948
 
1996
1949
  ```typescript
1997
- function useDirection(): 'ltr' | 'rtl'
1950
+ function useLogger(name: string, config?: Partial<LoggerConfig>): Logger
1998
1951
  ```
1999
1952
 
2000
- **Returns:** The text direction ('ltr' or 'rtl')
2001
-
2002
- #### `useEditor()`
2003
-
2004
- Hook for code editor management.
2005
-
2006
- ```typescript
2007
- function useEditor(): UseEditorResult
2008
- ```
1953
+ - `name` — Logger name (usually component or module name)
1954
+ - `config` — Optional logger configuration
2009
1955
 
2010
- **Returns:** Editor state and controls: tabs, activeFile, openFile, closeFile, getContent, setContent, setActiveTab, mount, dispose, and focus.
1956
+ **Returns:** Logger instance
2011
1957
 
2012
- #### `useEditorProvider()`
1958
+ #### `useRootLogger()`
2013
1959
 
2014
- Access the editor provider from context.
1960
+ Hook to get the root logger.
2015
1961
 
2016
1962
  ```typescript
2017
- function useEditorProvider(): EditorProvider
1963
+ function useRootLogger(): Logger
2018
1964
  ```
2019
1965
 
2020
- **Returns:** The EditorProvider instance from the nearest EditorContext.
1966
+ **Returns:** Root logger instance
2021
1967
 
2022
- #### `useFieldState(form, name)`
1968
+ #### `useChildLogger(parentName, context)`
2023
1969
 
2024
- Hook to get field-level state.
1970
+ Hook to create a child logger with additional context.
2025
1971
 
2026
1972
  ```typescript
2027
- function useFieldState(form: FormController<T>, name: keyof T): FieldState<T[keyof T]>
1973
+ function useChildLogger(parentName: string, context: Record<string, unknown>): Logger
2028
1974
  ```
2029
1975
 
2030
- - `form` — Form controller
2031
- - `name` — Field name
1976
+ - `parentName` — Parent logger name
1977
+ - `context` — Additional context to include in logs
2032
1978
 
2033
- **Returns:** Field state (value, error, touched, dirty, valid)
1979
+ **Returns:** Child logger instance
2034
1980
 
2035
- #### `useForm(options)`
1981
+ #### `useLogin()`
2036
1982
 
2037
- Hook for form state management.
1983
+ Hook for login with async state tracking.
2038
1984
 
2039
1985
  ```typescript
2040
- function useForm(options: UseFormOptions<T>): UseFormResult<T>
1986
+ function useLogin(): UseLoginReturn<T>
2041
1987
  ```
2042
1988
 
2043
- - `options` — Form options including createForm from a forms provider
1989
+ **Returns:** Login state and action
2044
1990
 
2045
- **Returns:** Form state and methods
1991
+ #### `useOAuth(config)`
2046
1992
 
2047
- #### `useGet(url, options)`
1993
+ Hook for OAuth authentication.
2048
1994
 
2049
- Hook for GET requests.
1995
+ Reads OAuth configuration from the provided config and provides
1996
+ helpers to build OAuth URLs and start a login (full-page or popup).
1997
+ Automatically handles OAuth callbacks by detecting `code` and `state`
1998
+ URL parameters and exchanging them for a session — and, when the callback is
1999
+ running inside a popup we opened, relaying the result to the opener instead.
2050
2000
 
2051
2001
  ```typescript
2052
- function useGet(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2002
+ function useOAuth(config?: {
2003
+ baseURL?: string
2004
+ oauthProviders?: string[]
2005
+ oauthEndpoint?: string
2006
+ loginEndpoint?: string
2007
+ onSuccess?: () => void
2008
+ onError?: (error: string) => void
2009
+ }): UseOAuthReturn
2053
2010
  ```
2054
2011
 
2055
- - `url` — Request URL to fetch from.
2056
- - `options` — HTTP request options including callbacks and request config.
2012
+ - `config` — Optional OAuth configuration override.
2013
+ - `config.baseURL` — Base URL for the API server (e.g. "https://api.example.com").
2014
+ - `config.oauthProviders` — List of supported OAuth provider names (e.g. ["google", "github"]).
2015
+ - `config.oauthEndpoint` — Path prefix for OAuth routes (defaults to "/oauth").
2016
+ - `config.loginEndpoint` — Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
2017
+ - `config.onSuccess` — Callback after successful OAuth login.
2018
+ - `config.onError` — Callback on OAuth login failure.
2057
2019
 
2058
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2020
+ **Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
2059
2021
 
2060
- #### `useHttp(method, url, options)`
2022
+ #### `usePasswordReset()`
2061
2023
 
2062
- Hook for making HTTP requests with state management.
2024
+ Hook for password reset flow with async state tracking.
2025
+
2026
+ Provides separate tracking for the request and confirm steps.
2063
2027
 
2064
2028
  ```typescript
2065
- function useHttp(
2066
- method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE',
2067
- url: string,
2068
- options?: UseHttpOptions<T>,
2069
- ): UseHttpResult<T>
2029
+ function usePasswordReset(): UsePasswordResetReturn
2070
2030
  ```
2071
2031
 
2072
- - `method` — HTTP method
2073
- - `url` — Request URL
2074
- - `options` — Request options
2032
+ **Returns:** Password reset state and actions
2075
2033
 
2076
- **Returns:** Request state and execute function
2034
+ #### `usePlatform()`
2077
2035
 
2078
- #### `useHttpClient()`
2036
+ Hook for platform detection.
2079
2037
 
2080
- Hook to access the HTTP client from context.
2038
+ Uses module-level functions — platform is a singleton, not context-provided.
2039
+ Platform info is static and doesn't change at runtime, so this uses `useMemo`.
2081
2040
 
2082
2041
  ```typescript
2083
- function useHttpClient(): HttpClient
2042
+ function usePlatform(): UsePlatformResult
2084
2043
  ```
2085
2044
 
2086
- **Returns:** The HTTP client from context
2087
-
2088
- #### `useI18nError(error)`
2045
+ **Returns:** Platform information and utility methods
2089
2046
 
2090
- Translates an error at render time so the displayed message updates automatically
2091
- when the locale changes.
2047
+ #### `usePreviewProvider()`
2092
2048
 
2093
- **Always use this hook to display errors in React components** — accessing
2094
- `error.message` directly bypasses re-translation and leaves stale text after a
2095
- locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
2096
- its key is translated using the current locale. For plain `Error` instances,
2097
- `error.message` is returned unchanged.
2049
+ Access the preview provider from context.
2098
2050
 
2099
2051
  ```typescript
2100
- function useI18nError(error: Error | null | undefined): string | null
2052
+ function usePreviewProvider(): PreviewProvider
2101
2053
  ```
2102
2054
 
2103
- - `error` — The error to translate, or `null`/`undefined`.
2104
-
2105
- **Returns:** The translated error string, or `null` if no error.
2055
+ **Returns:** The PreviewProvider instance from the nearest PreviewContext.
2106
2056
 
2107
- #### `useI18nProvider()`
2057
+ #### `usePreview()`
2108
2058
 
2109
- Hook to access the i18n provider from context.
2059
+ Hook for live preview management.
2110
2060
 
2111
2061
  ```typescript
2112
- function useI18nProvider(): I18nProvider
2062
+ function usePreview(): UsePreviewResult
2113
2063
  ```
2114
2064
 
2115
- **Returns:** The i18n provider from context
2065
+ **Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
2116
2066
 
2117
- #### `useIsActive(path, exact)`
2067
+ #### `usePromise(asyncFn)`
2118
2068
 
2119
- Hook to check if a path is active.
2069
+ Hook that wraps an async function with state tracking.
2120
2070
 
2121
2071
  ```typescript
2122
- function useIsActive(path: string, exact?: boolean): boolean
2072
+ function usePromise(
2073
+ asyncFn: T,
2074
+ ): [
2075
+ UsePromiseState<Awaited<ReturnType<T>>>,
2076
+ (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>,
2077
+ ]
2123
2078
  ```
2124
2079
 
2125
- - `path` — The path to check
2126
- - `exact` — Whether to match exactly (default: false)
2080
+ - `asyncFn` — The async function to wrap
2127
2081
 
2128
- **Returns:** Whether the path is active
2082
+ **Returns:** Tuple of [state, wrappedFunction]
2129
2083
 
2130
- #### `useIsAuthenticated()`
2084
+ #### `usePush(options)`
2131
2085
 
2132
- Hook to check if user is authenticated.
2086
+ Hook for push notification state and actions.
2087
+
2088
+ Uses module-level `getProvider()` — push is a singleton, not context-provided.
2133
2089
 
2134
2090
  ```typescript
2135
- function useIsAuthenticated(): boolean
2091
+ function usePush(options?: UsePushOptions): UsePushResult
2136
2092
  ```
2137
2093
 
2138
- **Returns:** Whether the user is authenticated
2094
+ - `options` — Hook options
2139
2095
 
2140
- #### `useLocale()`
2096
+ **Returns:** Push notification state and action methods
2141
2097
 
2142
- Hook to get the current locale.
2098
+ #### `useRouterInstance()`
2099
+
2100
+ Hook to access the router from context.
2143
2101
 
2144
2102
  ```typescript
2145
- function useLocale(): string
2103
+ function useRouterInstance(): Router
2146
2104
  ```
2147
2105
 
2148
- **Returns:** The current locale code
2106
+ **Returns:** The router from context
2149
2107
 
2150
- #### `useLocation()`
2108
+ #### `useRouter()`
2151
2109
 
2152
- Hook to get the current location.
2110
+ Hook for routing state and actions.
2153
2111
 
2154
2112
  ```typescript
2155
- function useLocation(): RouteLocation
2113
+ function useRouter(): UseRouterResult
2156
2114
  ```
2157
2115
 
2158
- **Returns:** The current route location
2116
+ **Returns:** Router state and navigation methods
2159
2117
 
2160
- #### `useLogger(name, config)`
2118
+ #### `useLocation()`
2161
2119
 
2162
- Hook to get a logger instance.
2120
+ Hook to get the current location.
2163
2121
 
2164
2122
  ```typescript
2165
- function useLogger(name: string, config?: Partial<LoggerConfig>): Logger
2123
+ function useLocation(): RouteLocation
2166
2124
  ```
2167
2125
 
2168
- - `name` — Logger name (usually component or module name)
2169
- - `config` — Optional logger configuration
2170
-
2171
- **Returns:** Logger instance
2126
+ **Returns:** The current route location
2172
2127
 
2173
- #### `useLoggerProvider()`
2128
+ #### `useParams()`
2174
2129
 
2175
- Hook to access the logger provider from context.
2130
+ Hook to get route parameters.
2176
2131
 
2177
2132
  ```typescript
2178
- function useLoggerProvider(): LoggerProvider
2133
+ function useParams(): T
2179
2134
  ```
2180
2135
 
2181
- **Returns:** The logger provider from context
2136
+ **Returns:** The current route parameters
2182
2137
 
2183
- #### `useLogin()`
2138
+ #### `useQuery()`
2184
2139
 
2185
- Hook for login with async state tracking.
2140
+ Hook to get query parameters.
2186
2141
 
2187
2142
  ```typescript
2188
- function useLogin(): UseLoginReturn<T>
2143
+ function useQuery(): T
2189
2144
  ```
2190
2145
 
2191
- **Returns:** Login state and action
2146
+ **Returns:** The current query parameters
2192
2147
 
2193
2148
  #### `useNavigate()`
2194
2149
 
@@ -2200,481 +2155,528 @@ function useNavigate(): (path: string, options?: NavigateOptions) => void
2200
2155
 
2201
2156
  **Returns:** The navigate function
2202
2157
 
2203
- #### `useOAuth(config)`
2204
-
2205
- Hook for OAuth authentication.
2158
+ #### `useIsActive(path, exact)`
2206
2159
 
2207
- Reads OAuth configuration from the provided config and provides
2208
- helpers to build OAuth URLs and start a login (full-page or popup).
2209
- Automatically handles OAuth callbacks by detecting `code` and `state`
2210
- URL parameters and exchanging them for a session — and, when the callback is
2211
- running inside a popup we opened, relaying the result to the opener instead.
2160
+ Hook to check if a path is active.
2212
2161
 
2213
2162
  ```typescript
2214
- function useOAuth(config?: {
2215
- baseURL?: string
2216
- oauthProviders?: string[]
2217
- oauthEndpoint?: string
2218
- loginEndpoint?: string
2219
- onSuccess?: () => void
2220
- onError?: (error: string) => void
2221
- }): UseOAuthReturn
2163
+ function useIsActive(path: string, exact?: boolean): boolean
2222
2164
  ```
2223
2165
 
2224
- - `config` — Optional OAuth configuration override.
2225
- - `config.baseURL` — Base URL for the API server (e.g. "https://api.example.com").
2226
- - `config.oauthProviders` — List of supported OAuth provider names (e.g. ["google", "github"]).
2227
- - `config.oauthEndpoint` — Path prefix for OAuth routes (defaults to "/oauth").
2228
- - `config.loginEndpoint` — Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
2229
- - `config.onSuccess` — Callback after successful OAuth login.
2230
- - `config.onError` — Callback on OAuth login failure.
2166
+ - `path` — The path to check
2167
+ - `exact` — Whether to match exactly (default: false)
2231
2168
 
2232
- **Returns:** OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
2169
+ **Returns:** Whether the path is active
2233
2170
 
2234
- #### `useParams()`
2171
+ #### `useSignup()`
2235
2172
 
2236
- Hook to get route parameters.
2173
+ Hook for user registration with async state tracking.
2237
2174
 
2238
2175
  ```typescript
2239
- function useParams(): T
2176
+ function useSignup(): UseSignupReturn<T>
2240
2177
  ```
2241
2178
 
2242
- **Returns:** The current route parameters
2243
-
2244
- #### `usePasswordReset()`
2179
+ **Returns:** Signup state and action
2245
2180
 
2246
- Hook for password reset flow with async state tracking.
2181
+ #### `useStorageProvider()`
2247
2182
 
2248
- Provides separate tracking for the request and confirm steps.
2183
+ Hook to access the storage provider from context.
2249
2184
 
2250
2185
  ```typescript
2251
- function usePasswordReset(): UsePasswordResetReturn
2186
+ function useStorageProvider(): StorageProvider
2252
2187
  ```
2253
2188
 
2254
- **Returns:** Password reset state and actions
2189
+ **Returns:** The storage provider from context
2255
2190
 
2256
- #### `usePatch(url, options)`
2191
+ #### `useStorageValue(key, options)`
2257
2192
 
2258
- Hook for PATCH requests.
2193
+ Hook to manage a single storage value with React state sync.
2259
2194
 
2260
2195
  ```typescript
2261
- function usePatch(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2196
+ function useStorageValue(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>
2262
2197
  ```
2263
2198
 
2264
- - `url` — Request URL to send the PATCH request to.
2265
- - `options` — HTTP request options including partial body data and callbacks.
2199
+ - `key` — Storage key
2200
+ - `options` — Hook options
2266
2201
 
2267
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2202
+ **Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
2268
2203
 
2269
- #### `usePlatform()`
2204
+ #### `useStorage()`
2270
2205
 
2271
- Hook for platform detection.
2206
+ Hook for simple storage operations without React state sync.
2272
2207
 
2273
- Uses module-level functions — platform is a singleton, not context-provided.
2274
- Platform info is static and doesn't change at runtime, so this uses `useMemo`.
2208
+ ```typescript
2209
+ function useStorage(): {
2210
+ get: <T>(key: string) => Promise<T | null>
2211
+ set: <T>(key: string, value: T) => Promise<void>
2212
+ remove: (key: string) => Promise<void>
2213
+ clear: () => Promise<void>
2214
+ keys: () => Promise<string[]>
2215
+ }
2216
+ ```
2217
+
2218
+ **Returns:** Storage operation methods
2219
+
2220
+ #### `useStateProvider()`
2221
+
2222
+ Hook to access the state provider from context.
2275
2223
 
2276
2224
  ```typescript
2277
- function usePlatform(): UsePlatformResult
2225
+ function useStateProvider(): StateProvider
2278
2226
  ```
2279
2227
 
2280
- **Returns:** Platform information and utility methods
2228
+ **Returns:** The state provider from context
2281
2229
 
2282
- #### `usePost(url, options)`
2230
+ #### `useStore(store, options)`
2283
2231
 
2284
- Hook for POST requests.
2232
+ Hook to subscribe to a store with optional selector and equality function.
2285
2233
 
2286
2234
  ```typescript
2287
- function usePost(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2235
+ function useStore(store: Store<T>, options?: UseStoreOptions<T, S>): S
2288
2236
  ```
2289
2237
 
2290
- - `url` — Request URL to post to.
2291
- - `options` — HTTP request options including body data and callbacks.
2238
+ - `store` — The store to subscribe to
2239
+ - `options` — Hook options (selector, equalityFn)
2292
2240
 
2293
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2241
+ **Returns:** The selected state
2294
2242
 
2295
- #### `usePreview()`
2243
+ #### `useSetStore(store)`
2296
2244
 
2297
- Hook for live preview management.
2245
+ Hook to get the store's setState function.
2298
2246
 
2299
2247
  ```typescript
2300
- function usePreview(): UsePreviewResult
2248
+ function useSetStore(store: Store<T>): (partial: Partial<T> | ((state: T) => Partial<T>)) => void
2301
2249
  ```
2302
2250
 
2303
- **Returns:** Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
2251
+ - `store` — The store to get setState from
2304
2252
 
2305
- #### `usePreviewProvider()`
2253
+ **Returns:** The setState function
2306
2254
 
2307
- Access the preview provider from context.
2255
+ #### `useStoreAction(store, action)`
2256
+
2257
+ Hook to create a bound action for a store.
2308
2258
 
2309
2259
  ```typescript
2310
- function usePreviewProvider(): PreviewProvider
2260
+ function useStoreAction(
2261
+ store: Store<T>,
2262
+ action: (setState: Store<T>['setState'], getState: Store<T>['getState']) => (...args: Args) => R,
2263
+ ): (...args: Args) => R
2311
2264
  ```
2312
2265
 
2313
- **Returns:** The PreviewProvider instance from the nearest PreviewContext.
2266
+ - `store` — The store to bind to
2267
+ - `action` — The action function that receives setState and getState
2314
2268
 
2315
- #### `usePromise(asyncFn)`
2269
+ **Returns:** A bound action function
2316
2270
 
2317
- Hook that wraps an async function with state tracking.
2271
+ #### `useThemeProvider()`
2272
+
2273
+ Hook to access the theme provider from context.
2318
2274
 
2319
2275
  ```typescript
2320
- function usePromise(
2321
- asyncFn: T,
2322
- ): [
2323
- UsePromiseState<Awaited<ReturnType<T>>>,
2324
- (...args: Parameters<T>) => Promise<Awaited<ReturnType<T>>>,
2325
- ]
2276
+ function useThemeProvider(): ThemeProvider
2326
2277
  ```
2327
2278
 
2328
- - `asyncFn` — The async function to wrap
2329
-
2330
- **Returns:** Tuple of [state, wrappedFunction]
2331
-
2332
- #### `usePush(options)`
2279
+ **Returns:** The theme provider from context
2333
2280
 
2334
- Hook for push notification state and actions.
2281
+ #### `useTheme()`
2335
2282
 
2336
- Uses module-level `getProvider()` — push is a singleton, not context-provided.
2283
+ Hook for theme state and actions.
2337
2284
 
2338
2285
  ```typescript
2339
- function usePush(options?: UsePushOptions): UsePushResult
2286
+ function useTheme(): UseThemeResult
2340
2287
  ```
2341
2288
 
2342
- - `options` — Hook options
2343
-
2344
- **Returns:** Push notification state and action methods
2289
+ **Returns:** Theme state and actions
2345
2290
 
2346
- #### `usePut(url, options)`
2291
+ #### `useCurrentTheme()`
2347
2292
 
2348
- Hook for PUT requests.
2293
+ Hook to get just the current theme object.
2349
2294
 
2350
2295
  ```typescript
2351
- function usePut(url: string, options?: UseHttpOptions<T>): UseHttpResult<T>
2296
+ function useCurrentTheme(): Theme
2352
2297
  ```
2353
2298
 
2354
- - `url` — Request URL to send the PUT request to.
2355
- - `options` — HTTP request options including body data and callbacks.
2356
-
2357
- **Returns:** Request state (data, loading, error) and controls (execute, reset).
2299
+ **Returns:** The current theme
2358
2300
 
2359
- #### `useQuery()`
2301
+ #### `useThemeMode()`
2360
2302
 
2361
- Hook to get query parameters.
2303
+ Hook to get just the theme mode (light/dark).
2362
2304
 
2363
2305
  ```typescript
2364
- function useQuery(): T
2306
+ function useThemeMode(): 'light' | 'dark'
2365
2307
  ```
2366
2308
 
2367
- **Returns:** The current query parameters
2309
+ **Returns:** The current theme mode
2368
2310
 
2369
- #### `useRootLogger()`
2311
+ #### `useThemeColors()`
2370
2312
 
2371
- Hook to get the root logger.
2313
+ Hook to get theme colors.
2372
2314
 
2373
2315
  ```typescript
2374
- function useRootLogger(): Logger
2316
+ function useThemeColors(): ThemeColors
2375
2317
  ```
2376
2318
 
2377
- **Returns:** Root logger instance
2319
+ **Returns:** The current theme colors
2378
2320
 
2379
- #### `useRouter()`
2321
+ #### `useI18nProvider()`
2380
2322
 
2381
- Hook for routing state and actions.
2323
+ Hook to access the i18n provider from context.
2382
2324
 
2383
2325
  ```typescript
2384
- function useRouter(): UseRouterResult
2326
+ function useI18nProvider(): I18nProvider
2385
2327
  ```
2386
2328
 
2387
- **Returns:** Router state and navigation methods
2329
+ **Returns:** The i18n provider from context
2388
2330
 
2389
- #### `useRouterInstance()`
2331
+ #### `useTranslation()`
2390
2332
 
2391
- Hook to access the router from context.
2333
+ Hook for internationalization.
2392
2334
 
2393
2335
  ```typescript
2394
- function useRouterInstance(): Router
2336
+ function useTranslation(): UseTranslationResult
2395
2337
  ```
2396
2338
 
2397
- **Returns:** The router from context
2339
+ **Returns:** Translation function and locale management
2398
2340
 
2399
- #### `useSetStore(store)`
2341
+ #### `useT()`
2400
2342
 
2401
- Hook to get the store's setState function.
2343
+ Hook to get just the translation function.
2402
2344
 
2403
2345
  ```typescript
2404
- function useSetStore(store: Store<T>): (partial: Partial<T> | ((state: T) => Partial<T>)) => void
2346
+ function useT(): (
2347
+ key: string,
2348
+ values?: InterpolationValues,
2349
+ options?: { defaultValue?: string; count?: number },
2350
+ ) => string
2405
2351
  ```
2406
2352
 
2407
- - `store` — The store to get setState from
2408
-
2409
- **Returns:** The setState function
2353
+ **Returns:** The translation function
2410
2354
 
2411
- #### `useSignup()`
2355
+ #### `useLocale()`
2412
2356
 
2413
- Hook for user registration with async state tracking.
2357
+ Hook to get the current locale.
2414
2358
 
2415
2359
  ```typescript
2416
- function useSignup(): UseSignupReturn<T>
2360
+ function useLocale(): string
2417
2361
  ```
2418
2362
 
2419
- **Returns:** Signup state and action
2363
+ **Returns:** The current locale code
2420
2364
 
2421
- #### `useStateProvider()`
2365
+ #### `useDirection()`
2422
2366
 
2423
- Hook to access the state provider from context.
2367
+ Hook to get the text direction.
2424
2368
 
2425
2369
  ```typescript
2426
- function useStateProvider(): StateProvider
2370
+ function useDirection(): 'ltr' | 'rtl'
2427
2371
  ```
2428
2372
 
2429
- **Returns:** The state provider from context
2373
+ **Returns:** The text direction ('ltr' or 'rtl')
2430
2374
 
2431
- #### `useStorage()`
2375
+ #### `useI18nError(error)`
2432
2376
 
2433
- Hook for simple storage operations without React state sync.
2377
+ Translates an error at render time so the displayed message updates automatically
2378
+ when the locale changes.
2379
+
2380
+ **Always use this hook to display errors in React components** — accessing
2381
+ `error.message` directly bypasses re-translation and leaves stale text after a
2382
+ locale switch. If `error` is an `I18nError` (thrown via `throw new I18nError(key)`),
2383
+ its key is translated using the current locale. For plain `Error` instances,
2384
+ `error.message` is returned unchanged.
2434
2385
 
2435
2386
  ```typescript
2436
- function useStorage(): {
2437
- get: <T>(key: string) => Promise<T | null>
2438
- set: <T>(key: string, value: T) => Promise<void>
2439
- remove: (key: string) => Promise<void>
2440
- clear: () => Promise<void>
2441
- keys: () => Promise<string[]>
2442
- }
2387
+ function useI18nError(error: Error | null | undefined): string | null
2443
2388
  ```
2444
2389
 
2445
- **Returns:** Storage operation methods
2390
+ - `error` — The error to translate, or `null`/`undefined`.
2446
2391
 
2447
- #### `useStorageProvider()`
2392
+ **Returns:** The translated error string, or `null` if no error.
2448
2393
 
2449
- Hook to access the storage provider from context.
2394
+ #### `useVerifyPaymentReturn(options)`
2395
+
2396
+ Reads the payment id a provider put in the return URL and confirms the
2397
+ purchase server-side with `POST /users/:id/verify-payment/:provider`.
2398
+
2399
+ **This is why a hosted checkout returns the buyer to the APP and not the
2400
+ API.** Session cookies are host-only on the app's origin, so a top-level
2401
+ redirect from the provider straight to an authenticated API callback on a
2402
+ different host arrives with NO credentials — it answers 401 and the paid plan
2403
+ is never granted. The request this hook makes is a same-origin call from a
2404
+ loaded app page, so the credentials apply. It waits for auth to hydrate
2405
+ first: after the redirect the page is a cold load, and the session is
2406
+ restored from the httpOnly cookie via `GET /users/me`.
2407
+
2408
+ Verification is idempotent server-side (first-claim-wins on the transaction),
2409
+ and this hook additionally runs at most once per transaction id per page.
2410
+ Safe on pages that are also reached normally: with no id in the URL it stays
2411
+ `idle` and issues no request.
2450
2412
 
2451
2413
  ```typescript
2452
- function useStorageProvider(): StorageProvider
2414
+ function useVerifyPaymentReturn(
2415
+ options?: UseVerifyPaymentReturnOptions,
2416
+ ): UseVerifyPaymentReturnResult
2453
2417
  ```
2454
2418
 
2455
- **Returns:** The storage provider from context
2419
+ - `options` — Provider fallback + lifecycle callbacks (see {@link UseVerifyPaymentReturnOptions}).
2456
2420
 
2457
- #### `useStorageValue(key, options)`
2421
+ **Returns:** The verification state (see {@link UseVerifyPaymentReturnResult}).
2458
2422
 
2459
- Hook to manage a single storage value with React state sync.
2423
+ #### `useVersion()`
2424
+
2425
+ Hook for version state and update actions.
2426
+
2427
+ Uses module-level `getProvider()` — version is a singleton, not context-provided.
2460
2428
 
2461
2429
  ```typescript
2462
- function useStorageValue(key: string, options?: UseStorageValueOptions<T>): UseStorageValueResult<T>
2430
+ function useVersion(): UseVersionResult
2463
2431
  ```
2464
2432
 
2465
- - `key` — Storage key
2466
- - `options` — Hook options
2467
-
2468
- **Returns:** Storage value state (value, loading, error) and mutators (setValue, removeValue).
2433
+ **Returns:** Version state and action methods
2469
2434
 
2470
- #### `useStore(store, options)`
2435
+ #### `useWorkspaceProvider()`
2471
2436
 
2472
- Hook to subscribe to a store with optional selector and equality function.
2437
+ Access the workspace provider from context.
2473
2438
 
2474
2439
  ```typescript
2475
- function useStore(store: Store<T>, options?: UseStoreOptions<T, S>): S
2440
+ function useWorkspaceProvider(): WorkspaceProvider
2476
2441
  ```
2477
2442
 
2478
- - `store` — The store to subscribe to
2479
- - `options` — Hook options (selector, equalityFn)
2480
-
2481
- **Returns:** The selected state
2443
+ **Returns:** The result.
2482
2444
 
2483
- #### `useStoreAction(store, action)`
2445
+ #### `useWorkspace()`
2484
2446
 
2485
- Hook to create a bound action for a store.
2447
+ Hook for IDE workspace layout management.
2486
2448
 
2487
2449
  ```typescript
2488
- function useStoreAction(
2489
- store: Store<T>,
2490
- action: (setState: Store<T>['setState'], getState: Store<T>['getState']) => (...args: Args) => R,
2491
- ): (...args: Args) => R
2450
+ function useWorkspace(): UseWorkspaceResult
2492
2451
  ```
2493
2452
 
2494
- - `store` — The store to bind to
2495
- - `action` — The action function that receives setState and getState
2496
-
2497
- **Returns:** A bound action function
2453
+ **Returns:** The workspace state and management methods.
2498
2454
 
2499
- #### `useT()`
2455
+ #### `StateProvider(props)`
2500
2456
 
2501
- Hook to get just the translation function.
2457
+ Provider for state management.
2502
2458
 
2503
2459
  ```typescript
2504
- function useT(): (
2505
- key: string,
2506
- values?: InterpolationValues,
2507
- options?: { defaultValue?: string; count?: number },
2508
- ) => string
2460
+ function StateProvider({
2461
+ provider,
2462
+ children,
2463
+ }: StateProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2509
2464
  ```
2510
2465
 
2511
- **Returns:** The translation function
2466
+ - `props` — Component props (see {@link StateProviderProps}).
2512
2467
 
2513
- #### `useTheme()`
2468
+ **Returns:** The rendered state provider element.
2514
2469
 
2515
- Hook for theme state and actions.
2470
+ #### `AuthProvider(props)`
2471
+
2472
+ Provider for authentication.
2516
2473
 
2517
2474
  ```typescript
2518
- function useTheme(): UseThemeResult
2475
+ function AuthProvider({
2476
+ client,
2477
+ children,
2478
+ }: AuthProviderProps<T>): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2519
2479
  ```
2520
2480
 
2521
- **Returns:** Theme state and actions
2481
+ - `props` — Component props (see {@link AuthProviderProps}).
2482
+
2483
+ **Returns:** The rendered auth provider element.
2522
2484
 
2523
- #### `useThemeColors()`
2485
+ #### `ThemeProvider(props)`
2524
2486
 
2525
- Hook to get theme colors.
2487
+ Provider for theming.
2526
2488
 
2527
2489
  ```typescript
2528
- function useThemeColors(): ThemeColors
2490
+ function ThemeProvider({
2491
+ provider,
2492
+ children,
2493
+ }: ThemeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2529
2494
  ```
2530
2495
 
2531
- **Returns:** The current theme colors
2496
+ - `props` — Component props (see {@link ThemeProviderProps}).
2532
2497
 
2533
- #### `useThemeMode()`
2498
+ **Returns:** The rendered theme provider element.
2534
2499
 
2535
- Hook to get just the theme mode (light/dark).
2500
+ #### `RouterProvider(props)`
2501
+
2502
+ Provider for routing.
2536
2503
 
2537
2504
  ```typescript
2538
- function useThemeMode(): 'light' | 'dark'
2505
+ function RouterProvider({
2506
+ router,
2507
+ children,
2508
+ }: RouterProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2539
2509
  ```
2540
2510
 
2541
- **Returns:** The current theme mode
2511
+ - `props` — Component props (see {@link RouterProviderProps}).
2542
2512
 
2543
- #### `useThemeProvider()`
2513
+ **Returns:** The rendered router provider element.
2544
2514
 
2545
- Hook to access the theme provider from context.
2515
+ #### `I18nProvider(props)`
2516
+
2517
+ Provider for internationalization.
2546
2518
 
2547
2519
  ```typescript
2548
- function useThemeProvider(): ThemeProvider
2520
+ function I18nProvider({
2521
+ provider,
2522
+ children,
2523
+ }: I18nProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2549
2524
  ```
2550
2525
 
2551
- **Returns:** The theme provider from context
2526
+ - `props` — Component props (see {@link I18nProviderProps}).
2552
2527
 
2553
- #### `useTranslation()`
2528
+ **Returns:** The rendered i18n provider element.
2554
2529
 
2555
- Hook for internationalization.
2530
+ #### `HttpProvider(props)`
2531
+
2532
+ Provider for HTTP client.
2556
2533
 
2557
2534
  ```typescript
2558
- function useTranslation(): UseTranslationResult
2535
+ function HttpProvider({
2536
+ client,
2537
+ children,
2538
+ }: HttpProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2559
2539
  ```
2560
2540
 
2561
- **Returns:** Translation function and locale management
2541
+ - `props` — Component props (see {@link HttpProviderProps}).
2562
2542
 
2563
- #### `useUser()`
2543
+ **Returns:** The rendered HTTP provider element.
2564
2544
 
2565
- Hook to get just the authenticated user.
2545
+ #### `StorageProvider(props)`
2546
+
2547
+ Provider for storage.
2566
2548
 
2567
2549
  ```typescript
2568
- function useUser(): T | null
2550
+ function StorageProvider({
2551
+ provider,
2552
+ children,
2553
+ }: StorageProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2569
2554
  ```
2570
2555
 
2571
- **Returns:** The authenticated user or null
2572
-
2573
- #### `useVerifyPaymentReturn(options)`
2556
+ - `props` — Component props (see {@link StorageProviderProps}).
2574
2557
 
2575
- Reads the payment id a provider put in the return URL and confirms the
2576
- purchase server-side with `POST /users/:id/verify-payment/:provider`.
2558
+ **Returns:** The rendered storage provider element.
2577
2559
 
2578
- **This is why a hosted checkout returns the buyer to the APP and not the
2579
- API.** Session cookies are host-only on the app's origin, so a top-level
2580
- redirect from the provider straight to an authenticated API callback on a
2581
- different host arrives with NO credentials — it answers 401 and the paid plan
2582
- is never granted. The request this hook makes is a same-origin call from a
2583
- loaded app page, so the credentials apply. It waits for auth to hydrate
2584
- first: after the redirect the page is a cold load, and the session is
2585
- restored from the httpOnly cookie via `GET /users/me`.
2560
+ #### `LoggerProvider(props)`
2586
2561
 
2587
- Verification is idempotent server-side (first-claim-wins on the transaction),
2588
- and this hook additionally runs at most once per transaction id per page.
2589
- Safe on pages that are also reached normally: with no id in the URL it stays
2590
- `idle` and issues no request.
2562
+ Provider for logging.
2591
2563
 
2592
2564
  ```typescript
2593
- function useVerifyPaymentReturn(
2594
- options?: UseVerifyPaymentReturnOptions,
2595
- ): UseVerifyPaymentReturnResult
2565
+ function LoggerProvider({
2566
+ provider,
2567
+ children,
2568
+ }: LoggerProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2596
2569
  ```
2597
2570
 
2598
- - `options` — Provider fallback + lifecycle callbacks (see {@link UseVerifyPaymentReturnOptions}).
2599
-
2600
- **Returns:** The verification state (see {@link UseVerifyPaymentReturnResult}).
2571
+ - `props` — Component props (see {@link LoggerProviderProps}).
2601
2572
 
2602
- #### `useVersion()`
2573
+ **Returns:** The rendered logger provider element.
2603
2574
 
2604
- Hook for version state and update actions.
2575
+ #### `ChatProvider(props)`
2605
2576
 
2606
- Uses module-level `getProvider()` — version is a singleton, not context-provided.
2577
+ Provider for AI chat.
2607
2578
 
2608
2579
  ```typescript
2609
- function useVersion(): UseVersionResult
2580
+ function ChatProvider({
2581
+ provider,
2582
+ children,
2583
+ }: ChatProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2610
2584
  ```
2611
2585
 
2612
- **Returns:** Version state and action methods
2586
+ - `props` — Component props (see {@link ChatProviderProps}).
2613
2587
 
2614
- #### `useWatch(form, name)`
2588
+ **Returns:** The rendered chat provider element.
2615
2589
 
2616
- Hook to watch a specific field value.
2590
+ #### `WorkspaceProvider(props)`
2591
+
2592
+ Provider for IDE workspace.
2617
2593
 
2618
2594
  ```typescript
2619
- function useWatch(form: FormController<T>, name: K): T[K]
2595
+ function WorkspaceProvider({
2596
+ provider,
2597
+ children,
2598
+ }: WorkspaceProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2620
2599
  ```
2621
2600
 
2622
- - `form` — Form controller
2623
- - `name` — Field name to watch
2601
+ - `props` — Component props (see {@link WorkspaceProviderProps}).
2624
2602
 
2625
- **Returns:** Current field value
2603
+ **Returns:** The rendered workspace provider element.
2626
2604
 
2627
- #### `useWorkspace()`
2605
+ #### `EditorProvider(props)`
2628
2606
 
2629
- Hook for IDE workspace layout management.
2607
+ Provider for code editor.
2630
2608
 
2631
2609
  ```typescript
2632
- function useWorkspace(): UseWorkspaceResult
2610
+ function EditorProvider({
2611
+ provider,
2612
+ children,
2613
+ }: EditorProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2633
2614
  ```
2634
2615
 
2635
- **Returns:** The workspace state and management methods.
2616
+ - `props` — Component props (see {@link EditorProviderProps}).
2636
2617
 
2637
- #### `useWorkspaceProvider()`
2618
+ **Returns:** The rendered editor provider element.
2638
2619
 
2639
- Access the workspace provider from context.
2620
+ #### `PreviewProvider(props)`
2621
+
2622
+ Provider for live preview.
2640
2623
 
2641
2624
  ```typescript
2642
- function useWorkspaceProvider(): WorkspaceProvider
2625
+ function PreviewProvider({
2626
+ provider,
2627
+ children,
2628
+ }: PreviewProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2643
2629
  ```
2644
2630
 
2645
- **Returns:** The result.
2631
+ - `props` — Component props (see {@link PreviewProviderProps}).
2646
2632
 
2647
- #### `WorkspaceProvider(props)`
2633
+ **Returns:** The rendered preview provider element.
2648
2634
 
2649
- Provider for IDE workspace.
2635
+ #### `MoleculeProvider(props)`
2636
+
2637
+ Combined provider for all molecule services.
2638
+
2639
+ Provides a convenient way to wrap your app with all molecule providers at once.
2640
+ Only providers that are passed will be included.
2650
2641
 
2651
2642
  ```typescript
2652
- function WorkspaceProvider({
2653
- provider,
2643
+ function MoleculeProvider({
2654
2644
  children,
2655
- }: WorkspaceProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2645
+ state,
2646
+ auth,
2647
+ theme,
2648
+ router,
2649
+ i18n,
2650
+ http,
2651
+ storage,
2652
+ logger,
2653
+ chat,
2654
+ workspace,
2655
+ editor,
2656
+ preview,
2657
+ }: MoleculeProviderProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
2656
2658
  ```
2657
2659
 
2658
- - `props` — Component props (see {@link WorkspaceProviderProps}).
2660
+ - `props` — Component props (see {@link MoleculeProviderProps}) — each service is optional, and ONLY the services passed are provided to the tree.
2659
2661
 
2660
- **Returns:** The rendered workspace provider element.
2662
+ **Returns:** The rendered combined provider element.
2661
2663
 
2662
2664
  ### Constants
2663
2665
 
2664
- #### `AuthContext`
2666
+ #### `DEFAULT_AGENT_NAME`
2665
2667
 
2666
- Context for authentication client.
2668
+ Neutral, product-agnostic agent name used when the host supplies none.
2667
2669
 
2668
2670
  ```typescript
2669
- const AuthContext: Context<AuthClient<unknown> | null>
2671
+ const DEFAULT_AGENT_NAME: 'the assistant'
2670
2672
  ```
2671
2673
 
2672
- #### `ChatContext`
2674
+ #### `DEFAULT_PRODUCT_NAME`
2673
2675
 
2674
- Context for AI chat provider.
2676
+ Neutral, product-agnostic product/IDE name used when the host supplies none.
2675
2677
 
2676
2678
  ```typescript
2677
- const ChatContext: Context<ChatProvider | null>
2679
+ const DEFAULT_PRODUCT_NAME: 'the IDE'
2678
2680
  ```
2679
2681
 
2680
2682
  #### `DEFAULT_AGENT_IDENTITY`
@@ -2687,36 +2689,36 @@ passes its own.
2687
2689
  const DEFAULT_AGENT_IDENTITY: AgentIdentity
2688
2690
  ```
2689
2691
 
2690
- #### `DEFAULT_AGENT_NAME`
2692
+ #### `StateContext`
2691
2693
 
2692
- Neutral, product-agnostic agent name used when the host supplies none.
2694
+ Context for state management provider.
2693
2695
 
2694
2696
  ```typescript
2695
- const DEFAULT_AGENT_NAME: 'the assistant'
2697
+ const StateContext: Context<StateProvider | null>
2696
2698
  ```
2697
2699
 
2698
- #### `DEFAULT_PRODUCT_NAME`
2700
+ #### `AuthContext`
2699
2701
 
2700
- Neutral, product-agnostic product/IDE name used when the host supplies none.
2702
+ Context for authentication client.
2701
2703
 
2702
2704
  ```typescript
2703
- const DEFAULT_PRODUCT_NAME: 'the IDE'
2705
+ const AuthContext: Context<AuthClient<unknown> | null>
2704
2706
  ```
2705
2707
 
2706
- #### `EditorContext`
2708
+ #### `ThemeContext`
2707
2709
 
2708
- Context for code editor provider.
2710
+ Context for theme provider.
2709
2711
 
2710
2712
  ```typescript
2711
- const EditorContext: Context<EditorProvider | null>
2713
+ const ThemeContext: Context<ThemeProvider | null>
2712
2714
  ```
2713
2715
 
2714
- #### `HttpContext`
2716
+ #### `RouterContext`
2715
2717
 
2716
- Context for HTTP client.
2718
+ Context for router.
2717
2719
 
2718
2720
  ```typescript
2719
- const HttpContext: Context<HttpClient | null>
2721
+ const RouterContext: Context<Router | null>
2720
2722
  ```
2721
2723
 
2722
2724
  #### `I18nContext`
@@ -2727,60 +2729,60 @@ Context for internationalization provider.
2727
2729
  const I18nContext: Context<I18nProvider | null>
2728
2730
  ```
2729
2731
 
2730
- #### `LoggerContext`
2732
+ #### `HttpContext`
2731
2733
 
2732
- Context for logger provider.
2734
+ Context for HTTP client.
2733
2735
 
2734
2736
  ```typescript
2735
- const LoggerContext: Context<LoggerProvider | null>
2737
+ const HttpContext: Context<HttpClient | null>
2736
2738
  ```
2737
2739
 
2738
- #### `PreviewContext`
2740
+ #### `StorageContext`
2739
2741
 
2740
- Context for live preview provider.
2742
+ Context for storage provider.
2741
2743
 
2742
2744
  ```typescript
2743
- const PreviewContext: Context<PreviewProvider | null>
2745
+ const StorageContext: Context<StorageProvider | null>
2744
2746
  ```
2745
2747
 
2746
- #### `RouterContext`
2748
+ #### `LoggerContext`
2747
2749
 
2748
- Context for router.
2750
+ Context for logger provider.
2749
2751
 
2750
2752
  ```typescript
2751
- const RouterContext: Context<Router | null>
2753
+ const LoggerContext: Context<LoggerProvider | null>
2752
2754
  ```
2753
2755
 
2754
- #### `StateContext`
2756
+ #### `ChatContext`
2755
2757
 
2756
- Context for state management provider.
2758
+ Context for AI chat provider.
2757
2759
 
2758
2760
  ```typescript
2759
- const StateContext: Context<StateProvider | null>
2761
+ const ChatContext: Context<ChatProvider | null>
2760
2762
  ```
2761
2763
 
2762
- #### `StorageContext`
2764
+ #### `WorkspaceContext`
2763
2765
 
2764
- Context for storage provider.
2766
+ Context for IDE workspace provider.
2765
2767
 
2766
2768
  ```typescript
2767
- const StorageContext: Context<StorageProvider | null>
2769
+ const WorkspaceContext: Context<WorkspaceProvider | null>
2768
2770
  ```
2769
2771
 
2770
- #### `ThemeContext`
2772
+ #### `EditorContext`
2771
2773
 
2772
- Context for theme provider.
2774
+ Context for code editor provider.
2773
2775
 
2774
2776
  ```typescript
2775
- const ThemeContext: Context<ThemeProvider | null>
2777
+ const EditorContext: Context<EditorProvider | null>
2776
2778
  ```
2777
2779
 
2778
- #### `WorkspaceContext`
2780
+ #### `PreviewContext`
2779
2781
 
2780
- Context for IDE workspace provider.
2782
+ Context for live preview provider.
2781
2783
 
2782
2784
  ```typescript
2783
- const WorkspaceContext: Context<WorkspaceProvider | null>
2785
+ const PreviewContext: Context<PreviewProvider | null>
2784
2786
  ```
2785
2787
 
2786
2788
  ## Injection Notes