@lunora/react 1.0.0-alpha.27 → 1.0.0-alpha.29

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.
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ import { ReactNode, ReactElement } from 'react';
2
2
  import { LunoraClient, OptimisticUpdate, User, FunctionReference, ClientQueryRef, ConnectionStatus, ArgsOf, ReturnOf, HttpStreamRef, HttpStreamArgsOf, HttpStreamChunkOf, MutatorHandle, Preloaded } from '@lunora/client';
3
3
  export { type ArgsOf, type ClientQueryRef, type FunctionReference, type HttpStreamArgsOf, type HttpStreamChunkOf, type HttpStreamRef, type LunoraClient, type LunoraErrorCode, type MutatorHandle, type MutatorTransaction, type OptimisticLocalStore, type OptimisticUpdate, type Preloaded, type ReturnOf, type User, createClientQuery, getErrorCode, getRetryAfterMs, isConflictError, isForbiddenError, isRateLimitedError, isUnauthorizedError } from '@lunora/client';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
- export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-D4okOpO8.mjs";
5
+ export { type L as LunoraQueryOptions, l as lunoraQueryOptions } from "./packem_shared/query-options.d-CdgGQ9s4.mjs";
6
6
  import { PaginationStatus } from '@lunora/client/pagination';
7
7
  export type { PaginationResult, PaginationStatus } from '@lunora/client/pagination';
8
8
  import { RateLimitStatus, RateLimitConfig } from '@lunora/ratelimit';
@@ -10,73 +10,63 @@ interface AuthGateProps {
10
10
  children: ReactNode;
11
11
  }
12
12
  /** Renders `children` only once a token is set on the client (after hydration). */
13
- declare const Authenticated: ({
14
- children
15
- }: AuthGateProps) => ReactNode;
13
+ declare const Authenticated: ({ children }: AuthGateProps) => ReactNode;
16
14
  /** Renders `children` only when auth has settled and no token is set. */
17
- declare const Unauthenticated: ({
18
- children
19
- }: AuthGateProps) => ReactNode;
15
+ declare const Unauthenticated: ({ children }: AuthGateProps) => ReactNode;
20
16
  /** Renders `children` while auth is still settling (before hydration completes). */
21
- declare const AuthLoading: ({
22
- children
23
- }: AuthGateProps) => ReactNode;
17
+ declare const AuthLoading: ({ children }: AuthGateProps) => ReactNode;
24
18
  /**
25
- * Resolved auth-gate state. `isLoading` covers the window before the client has
26
- * hydrated — the server render and the first hydration render both report
27
- * loading, so the markup agrees and no signed-out UI flashes in.
28
- */
19
+ * Resolved auth-gate state. `isLoading` covers the window before the client has
20
+ * hydrated — the server render and the first hydration render both report
21
+ * loading, so the markup agrees and no signed-out UI flashes in.
22
+ */
29
23
  interface AuthState {
30
24
  isAuthenticated: boolean;
31
25
  isLoading: boolean;
32
26
  }
33
27
  /**
34
- * Three-state auth status for gating UI. Reports `isLoading` until the client
35
- * has hydrated, then `isAuthenticated` tracks whether a token is set on the
36
- * shared client.
37
- *
38
- * Lunora auth is token-based and resolves synchronously once the token is
39
- * known, so the loading window is hydration rather than a server round-trip —
40
- * use it (via {@link AuthState}) to render a fallback while it settles.
41
- */
28
+ * Three-state auth status for gating UI. Reports `isLoading` until the client
29
+ * has hydrated, then `isAuthenticated` tracks whether a token is set on the
30
+ * shared client.
31
+ *
32
+ * Lunora auth is token-based and resolves synchronously once the token is
33
+ * known, so the loading window is hydration rather than a server round-trip —
34
+ * use it (via {@link AuthState}) to render a fallback while it settles.
35
+ */
42
36
  declare const useAuthState: () => AuthState;
43
37
  interface LunoraProviderProps {
44
38
  children: ReactNode;
45
39
  client: LunoraClient;
46
40
  /**
47
- * Bring-your-own QueryClient. When omitted, the provider creates one with
48
- * defaults tuned for Lunora's push-driven model: `staleTime: Infinity` (the
49
- * WS subscription is the only invalidation signal), `retry: 0` (failures
50
- * route through the offline queue on the client), and `gcTime: 5min` (keep
51
- * results around for a short return-to-view window).
52
- *
53
- * If a parent `<QueryClientProvider>` is already mounted, the provider
54
- * uses *that* client and does NOT install an inner one (so apps with their
55
- * own setup don't double-wrap).
56
- */
41
+ * Bring-your-own QueryClient. When omitted, the provider creates one with
42
+ * defaults tuned for Lunora's push-driven model: `staleTime: Infinity` (the
43
+ * WS subscription is the only invalidation signal), `retry: 0` (failures
44
+ * route through the offline queue on the client), and `gcTime: 5min` (keep
45
+ * results around for a short return-to-view window).
46
+ *
47
+ * If a parent `<QueryClientProvider>` is already mounted, the provider
48
+ * uses *that* client and does NOT install an inner one (so apps with their
49
+ * own setup don't double-wrap).
50
+ */
57
51
  queryClient?: QueryClient;
58
52
  }
59
53
  /**
60
- * Provides both the {@link LunoraClient} and a TanStack `QueryClient` to the
61
- * tree. The detection logic for a parent QueryClientProvider keeps this safe to
62
- * drop into an app that already runs TanStack Query for its own purposes.
63
- */
64
- declare const LunoraProvider: ({
65
- children,
66
- client,
67
- queryClient
68
- }: LunoraProviderProps) => ReactElement;
54
+ * Provides both the {@link LunoraClient} and a TanStack `QueryClient` to the
55
+ * tree. The detection logic for a parent QueryClientProvider keeps this safe to
56
+ * drop into an app that already runs TanStack Query for its own purposes.
57
+ */
58
+ declare const LunoraProvider: ({ children, client, queryClient }: LunoraProviderProps) => ReactElement;
69
59
  /**
70
- * Read the {@link LunoraClient} from the nearest `<LunoraProvider>`. Kept
71
- * colocated with the provider for back-compat.
72
- */
60
+ * Read the {@link LunoraClient} from the nearest `<LunoraProvider>`. Kept
61
+ * colocated with the provider for back-compat.
62
+ */
73
63
  declare const useLunora: () => LunoraClient;
74
64
  /**
75
- * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
76
- * (rather than imported) so this React entry never pulls in the server-only
77
- * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
78
- * sync with `packages/payment/src/types.ts`.
79
- */
65
+ * Client-safe mirror of `@lunora/payment`'s `Subscription`. Re-declared here
66
+ * (rather than imported) so this React entry never pulls in the server-only
67
+ * `@lunora/payment` module graph — the kit stays React + DOM only. Keep this in
68
+ * sync with `packages/payment/src/types.ts`.
69
+ */
80
70
  interface Subscription {
81
71
  readonly cancelAtPeriodEnd: boolean;
82
72
  readonly createdAt: number;
@@ -104,24 +94,24 @@ interface UseCheckoutResult {
104
94
  pending: boolean;
105
95
  }
106
96
  /**
107
- * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
108
- * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
109
- * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
110
- * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
111
- * `pending`, surfaces any `error`, and on success navigates via
112
- * `location.assign(url)`.
113
- *
114
- * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
115
- * that returns a URL, then redirect) while staying agnostic of the app's
116
- * function names.
117
- */
97
+ * Decoupled redirect-on-resolve primitive shared by `CheckoutButton` and
98
+ * `CustomerPortalButton`. The app passes a `trigger` thunk that calls its own
99
+ * Lunora action (the one wrapping `LunoraPayment.createCheckout` /
100
+ * `createPortalSession`) and resolves `{ url }`; this hook awaits it, flips
101
+ * `pending`, surfaces any `error`, and on success navigates via
102
+ * `location.assign(url)`.
103
+ *
104
+ * Mirrors Convex's `CheckoutLink` / `CustomerPortalLink` flow (trigger an action
105
+ * that returns a URL, then redirect) while staying agnostic of the app's
106
+ * function names.
107
+ */
118
108
  declare const useCheckout: (trigger: RedirectTrigger) => UseCheckoutResult;
119
109
  /**
120
- * Presentational props shared by the redirect buttons. Kept to a curated set
121
- * (rather than spreading arbitrary button attributes) so the component stays
122
- * within the repo's `react/jsx-props-no-spreading` rule while covering the
123
- * common styling / accessibility hooks.
124
- */
110
+ * Presentational props shared by the redirect buttons. Kept to a curated set
111
+ * (rather than spreading arbitrary button attributes) so the component stays
112
+ * within the repo's `react/jsx-props-no-spreading` rule while covering the
113
+ * common styling / accessibility hooks.
114
+ */
125
115
  interface RedirectButtonOwnProps {
126
116
  /** Accessible label when the visible `children` are icon-only. */
127
117
  "aria-label"?: string;
@@ -142,33 +132,27 @@ interface CustomerPortalButtonProps extends RedirectButtonOwnProps {
142
132
  onPortal: RedirectTrigger;
143
133
  }
144
134
  /**
145
- * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
146
- * that calls the app's checkout action) and redirects to the returned URL,
147
- * disabling itself while the request is in flight.
148
- */
149
- declare const CheckoutButton: ({
150
- onCheckout,
151
- ...rest
152
- }: CheckoutButtonProps) => ReactNode;
135
+ * Button that starts a hosted checkout. On click it awaits `onCheckout` (a thunk
136
+ * that calls the app's checkout action) and redirects to the returned URL,
137
+ * disabling itself while the request is in flight.
138
+ */
139
+ declare const CheckoutButton: ({ onCheckout, ...rest }: CheckoutButtonProps) => ReactNode;
153
140
  /**
154
- * Button that opens the provider's customer portal. On click it awaits
155
- * `onPortal` (a thunk that calls the app's portal action) and redirects to the
156
- * returned URL, disabling itself while the request is in flight.
157
- */
158
- declare const CustomerPortalButton: ({
159
- onPortal,
160
- ...rest
161
- }: CustomerPortalButtonProps) => ReactNode;
141
+ * Button that opens the provider's customer portal. On click it awaits
142
+ * `onPortal` (a thunk that calls the app's portal action) and redirects to the
143
+ * returned URL, disabling itself while the request is in flight.
144
+ */
145
+ declare const CustomerPortalButton: ({ onPortal, ...rest }: CustomerPortalButtonProps) => ReactNode;
162
146
  interface UseQueryOptions {
163
147
  shardKey?: string;
164
148
  }
165
149
  interface UseMutationCallOptions<TCurrent = unknown, TValue = unknown, TArgs = unknown> {
166
150
  optimistic?: (current: TCurrent | undefined) => TValue;
167
151
  /**
168
- * Convex-parity multi-query optimistic update forwarded to
169
- * `client.mutation`. Patches many subscribed queries at once via an
170
- * `OptimisticLocalStore`, rolled back atomically on failure.
171
- */
152
+ * Convex-parity multi-query optimistic update forwarded to
153
+ * `client.mutation`. Patches many subscribed queries at once via an
154
+ * `OptimisticLocalStore`, rolled back atomically on failure.
155
+ */
172
156
  optimisticUpdate?: OptimisticUpdate<TArgs>;
173
157
  shardKey?: string;
174
158
  }
@@ -214,19 +198,19 @@ interface UseAuthResult {
214
198
  user: User | null;
215
199
  }
216
200
  /**
217
- * The lifecycle status stored on an agent thread. Client-safe mirror of
218
- * `@lunora/agent`'s `AgentThreadStatus` — re-declared here (rather than imported)
219
- * so this React entry never pulls in the server-only `@lunora/agent` module
220
- * graph (the kit stays React + DOM only). Keep in sync with
221
- * `packages/agent/src/types.ts`.
222
- */
201
+ * The lifecycle status stored on an agent thread. Client-safe mirror of
202
+ * `@lunora/agent`'s `AgentThreadStatus` — re-declared here (rather than imported)
203
+ * so this React entry never pulls in the server-only `@lunora/agent` module
204
+ * graph (the kit stays React + DOM only). Keep in sync with
205
+ * `packages/agent/src/types.ts`.
206
+ */
223
207
  type AgentThreadStatus = "awaiting_input" | "cancelled" | "error" | "idle" | "running";
224
208
  /**
225
- * The live thread record surfaced by the `agents:agentThread` query. A structural
226
- * subset of the persisted thread row — every field beyond `status` is optional so
227
- * the shape stays forgiving as the server schema grows. Keep in sync with the
228
- * `agent_threads` table in `packages/agent/src/component.ts`.
229
- */
209
+ * The live thread record surfaced by the `agents:agentThread` query. A structural
210
+ * subset of the persisted thread row — every field beyond `status` is optional so
211
+ * the shape stays forgiving as the server schema grows. Keep in sync with the
212
+ * `agent_threads` table in `packages/agent/src/component.ts`.
213
+ */
230
214
  interface AgentThreadRecord {
231
215
  createdAt?: number;
232
216
  /** The failure message when `status === "error"`. */
@@ -241,10 +225,10 @@ interface AgentThreadRecord {
241
225
  updatedAt?: number;
242
226
  }
243
227
  /**
244
- * The `agents.agentThread` reference the hook subscribes to for live thread state
245
- * (status + the in-flight `instanceId`). A structural subset of the generated
246
- * `api.agents` surface, so the whole generated `api` object is assignable.
247
- */
228
+ * The `agents.agentThread` reference the hook subscribes to for live thread state
229
+ * (status + the in-flight `instanceId`). A structural subset of the generated
230
+ * `api.agents` surface, so the whole generated `api` object is assignable.
231
+ */
248
232
  interface UseAgentApi {
249
233
  agents: {
250
234
  agentThread: FunctionReference<"query", {
@@ -256,17 +240,17 @@ interface UseAgentOptions {
256
240
  /** The generated `api` — its `agents.agentThread` query drives live thread state. */
257
241
  api: UseAgentApi;
258
242
  /**
259
- * Optional app mutation over the agent's cancel path
260
- * (`ctx.agents.&lt;name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
261
- * When omitted (or no run is in flight) {@link UseAgentResult.cancel} is a
262
- * no-op.
263
- */
243
+ * Optional app mutation over the agent's cancel path
244
+ * (`ctx.agents.&lt;name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
245
+ * When omitted (or no run is in flight) {@link UseAgentResult.cancel} is a
246
+ * no-op.
247
+ */
264
248
  cancel?: FunctionReference<"mutation">;
265
249
  /**
266
- * The app mutation that starts (or continues) a run — a thin wrapper over
267
- * `ctx.agents.&lt;name>.run(...)`. Called with `{ threadKey, input }` merged with
268
- * {@link UseAgentOptions.runArgs} and the per-call args.
269
- */
250
+ * The app mutation that starts (or continues) a run — a thin wrapper over
251
+ * `ctx.agents.&lt;name>.run(...)`. Called with `{ threadKey, input }` merged with
252
+ * {@link UseAgentOptions.runArgs} and the per-call args.
253
+ */
270
254
  run: FunctionReference<"mutation">;
271
255
  /** Extra args merged into every `run` call (e.g. an `owner` or `title`). */
272
256
  runArgs?: Record<string, unknown>;
@@ -275,9 +259,9 @@ interface UseAgentOptions {
275
259
  }
276
260
  interface UseAgentResult {
277
261
  /**
278
- * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
279
- * no-op when no `cancel` mutation was supplied or no run is in flight.
280
- */
262
+ * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
263
+ * no-op when no `cancel` mutation was supplied or no run is in flight.
264
+ */
281
265
  cancel: () => Promise<void>;
282
266
  /** `true` while a `run` invocation is in flight. */
283
267
  pending: boolean;
@@ -289,31 +273,31 @@ interface UseAgentResult {
289
273
  thread: AgentThreadRecord | undefined;
290
274
  }
291
275
  /**
292
- * A thin agent handle: live thread `status` plus `run` / `cancel`, without the
293
- * chat message surface. Composes `useSubscription(api.agents.agentThread)` for
294
- * live state and `useMutation` for the run/cancel writes. For the full
295
- * conversation surface (durable history + streaming + approvals) use
296
- * `useAgentChat`.
297
- *
298
- * `run` and `cancel` stay generic over the app-defined mutations that wrap
299
- * `ctx.agents.&lt;name>.run` / `.cancel`, so the hook hard-codes no function names
300
- * beyond the `agents:*` surface.
301
- */
276
+ * A thin agent handle: live thread `status` plus `run` / `cancel`, without the
277
+ * chat message surface. Composes `useSubscription(api.agents.agentThread)` for
278
+ * live state and `useMutation` for the run/cancel writes. For the full
279
+ * conversation surface (durable history + streaming + approvals) use
280
+ * `useAgentChat`.
281
+ *
282
+ * `run` and `cancel` stay generic over the app-defined mutations that wrap
283
+ * `ctx.agents.&lt;name>.run` / `.cancel`, so the hook hard-codes no function names
284
+ * beyond the `agents:*` surface.
285
+ */
302
286
  declare const useAgent: (options: UseAgentOptions) => UseAgentResult;
303
287
  /**
304
- * One persisted (or optimistic) thread message, as `agents:agentMessages`
305
- * surfaces it. Client-safe mirror of `@lunora/agent`'s `AgentMessageRow` —
306
- * re-declared here (rather than imported) so this React entry never pulls in the
307
- * server-only `@lunora/agent` module graph. Keep in sync with the `agent_messages`
308
- * table in `packages/agent/src/component.ts`.
309
- */
288
+ * One persisted (or optimistic) thread message, as `agents:agentMessages`
289
+ * surfaces it. Client-safe mirror of `@lunora/agent`'s `AgentMessageRow` —
290
+ * re-declared here (rather than imported) so this React entry never pulls in the
291
+ * server-only `@lunora/agent` module graph. Keep in sync with the `agent_messages`
292
+ * table in `packages/agent/src/component.ts`.
293
+ */
310
294
  interface AgentChatMessage {
311
295
  content: string;
312
296
  createdAt?: number;
313
297
  /**
314
- * `true` for a client-side optimistic user message not yet acknowledged by
315
- * the server. Cleared once the durable history carries the matching user turn.
316
- */
298
+ * `true` for a client-side optimistic user message not yet acknowledged by
299
+ * the server. Cleared once the durable history carries the matching user turn.
300
+ */
317
301
  optimistic?: boolean;
318
302
  role: "assistant" | "system" | "tool" | "user";
319
303
  seq: number;
@@ -328,11 +312,11 @@ interface AgentChatMessage {
328
312
  toolName?: string;
329
313
  }
330
314
  /**
331
- * A live token delta streamed while a turn is generating. Client-safe mirror of
332
- * `@lunora/agent`'s `AgentTokenDelta`. Ephemeral — deltas feed
333
- * {@link UseAgentChatResult.streamingText} live and are never replayed; the
334
- * persisted assistant message stays the single source of truth.
335
- */
315
+ * A live token delta streamed while a turn is generating. Client-safe mirror of
316
+ * `@lunora/agent`'s `AgentTokenDelta`. Ephemeral — deltas feed
317
+ * {@link UseAgentChatResult.streamingText} live and are never replayed; the
318
+ * persisted assistant message stays the single source of truth.
319
+ */
336
320
  interface AgentTokenDelta {
337
321
  /** Discriminates the token arm of {@link AgentLiveEvent}; unset on the wire (token is the default). */
338
322
  kind?: "token";
@@ -344,10 +328,10 @@ interface AgentTokenDelta {
344
328
  turn: number;
345
329
  }
346
330
  /**
347
- * A live tool-progress event streamed via `ctx.reportProgress(...)`. Client-safe
348
- * mirror of `@lunora/agent`'s `AgentProgressEvent`. Ephemeral and `toolCallId`-keyed;
349
- * surfaced by `useAgentToolEvents`, ignored by {@link UseAgentChatResult.streamingText}.
350
- */
331
+ * A live tool-progress event streamed via `ctx.reportProgress(...)`. Client-safe
332
+ * mirror of `@lunora/agent`'s `AgentProgressEvent`. Ephemeral and `toolCallId`-keyed;
333
+ * surfaced by `useAgentToolEvents`, ignored by {@link UseAgentChatResult.streamingText}.
334
+ */
351
335
  interface AgentProgressEvent {
352
336
  /** The arbitrary, JSON-serializable payload the tool reported. */
353
337
  data: unknown;
@@ -359,11 +343,11 @@ interface AgentProgressEvent {
359
343
  toolCallId: string;
360
344
  }
361
345
  /**
362
- * A single event on the agent's live-only channel — a streamed token delta or a
363
- * tool progress event. Client-safe mirror of `@lunora/agent`'s `AgentLiveEvent`.
364
- * Discriminate on `kind` (`"progress"` for the progress arm; token deltas leave
365
- * it unset).
366
- */
346
+ * A single event on the agent's live-only channel — a streamed token delta or a
347
+ * tool progress event. Client-safe mirror of `@lunora/agent`'s `AgentLiveEvent`.
348
+ * Discriminate on `kind` (`"progress"` for the progress arm; token deltas leave
349
+ * it unset).
350
+ */
367
351
  type AgentLiveEvent = AgentProgressEvent | AgentTokenDelta;
368
352
  /** The `agents:agentMessages` reference — live durable thread history. */
369
353
  type AgentMessagesReference$1 = FunctionReference<"query", {
@@ -385,17 +369,17 @@ type AgentThreadReference = FunctionReference<"query", {
385
369
  key: string;
386
370
  }, Record<string, unknown> | undefined>;
387
371
  /**
388
- * An app stream reference that tees the agent's in-flight live events, keyed by
389
- * thread. Carries token deltas and — since `ctx.reportProgress` rides the same
390
- * sink — tool progress events; this hook consumes only the token arm.
391
- */
372
+ * An app stream reference that tees the agent's in-flight live events, keyed by
373
+ * thread. Carries token deltas and — since `ctx.reportProgress` rides the same
374
+ * sink — tool progress events; this hook consumes only the token arm.
375
+ */
392
376
  type AgentTokenStreamReference = FunctionReference<"stream", {
393
377
  key: string;
394
378
  }, AgentLiveEvent>;
395
379
  /**
396
- * The `agents.*` reference surface the chat hook reads. A structural subset of
397
- * the generated `api.agents`, so the whole generated `api` object is assignable.
398
- */
380
+ * The `agents.*` reference surface the chat hook reads. A structural subset of
381
+ * the generated `api.agents`, so the whole generated `api` object is assignable.
382
+ */
399
383
  interface UseAgentChatApi {
400
384
  agents: {
401
385
  agentMessages: AgentMessagesReference$1;
@@ -407,27 +391,27 @@ interface UseAgentChatOptions {
407
391
  /** The generated `api` — its `agents.*` surface provides history, thread state, and approval resolution. */
408
392
  api: UseAgentChatApi;
409
393
  /**
410
- * Optional app mutation over the agent's cancel path
411
- * (`ctx.agents.&lt;name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
412
- * When omitted (or no run is in flight) {@link UseAgentChatResult.cancel} is a
413
- * no-op.
414
- */
394
+ * Optional app mutation over the agent's cancel path
395
+ * (`ctx.agents.&lt;name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
396
+ * When omitted (or no run is in flight) {@link UseAgentChatResult.cancel} is a
397
+ * no-op.
398
+ */
415
399
  cancel?: FunctionReference<"mutation">;
416
400
  /** History depth forwarded to `agents:agentMessages`. */
417
401
  limit?: number;
418
402
  /**
419
- * The app mutation that starts (or continues) a run — a thin wrapper over
420
- * `ctx.agents.&lt;name>.run(...)`. Called with `{ threadKey, input }` merged with
421
- * {@link UseAgentChatOptions.sendArgs} and the per-call args.
422
- */
403
+ * The app mutation that starts (or continues) a run — a thin wrapper over
404
+ * `ctx.agents.&lt;name>.run(...)`. Called with `{ threadKey, input }` merged with
405
+ * {@link UseAgentChatOptions.sendArgs} and the per-call args.
406
+ */
423
407
  send: FunctionReference<"mutation">;
424
408
  /** Extra args merged into every `send` call (e.g. an `owner` or `title`). */
425
409
  sendArgs?: Record<string, unknown>;
426
410
  /**
427
- * Optional live token-delta stream — an app stream function that tees the
428
- * agent's in-flight deltas. When omitted {@link UseAgentChatResult.streamingText}
429
- * stays empty and the UI updates message-by-message from durable history.
430
- */
411
+ * Optional live token-delta stream — an app stream function that tees the
412
+ * agent's in-flight deltas. When omitted {@link UseAgentChatResult.streamingText}
413
+ * stays empty and the UI updates message-by-message from durable history.
414
+ */
431
415
  stream?: AgentTokenStreamReference;
432
416
  /** The thread to observe and continue. */
433
417
  threadKey: string;
@@ -436,9 +420,9 @@ interface UseAgentChatResult {
436
420
  /** Approve a paused human-in-the-loop tool call (optionally with a note). */
437
421
  approve: (toolCallId: string, note?: string) => Promise<void>;
438
422
  /**
439
- * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
440
- * no-op when no `cancel` mutation was supplied or no run is in flight.
441
- */
423
+ * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
424
+ * no-op when no `cancel` mutation was supplied or no run is in flight.
425
+ */
442
426
  cancel: () => Promise<void>;
443
427
  /** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
444
428
  messages: ReadonlyArray<AgentChatMessage>;
@@ -452,33 +436,33 @@ interface UseAgentChatResult {
452
436
  streamingText: string;
453
437
  }
454
438
  /**
455
- * A first-class agent chat surface: live durable history + in-flight token
456
- * streaming + the send / approve / reject / cancel writes, keyed by `threadKey`.
457
- *
458
- * It composes the existing primitives rather than adding transport:
459
- * `useSubscription(api.agents.agentMessages)` for durable history,
460
- * `useSubscription(api.agents.agentThread)` for live status + the in-flight
461
- * `instanceId`, {@link useStream} over an app token stream for in-flight deltas,
462
- * and `useMutation` for the writes (`api.agents.agentResolveApproval` for
463
- * approvals; app-defined wrappers for `send`/`cancel`). Only the `agents:*`
464
- * surface is hard-coded — `send`/`cancel`/`stream` stay generic references.
465
- *
466
- * A `send` optimistically appends the user turn so it renders immediately; the
467
- * optimistic row clears once the durable history carries the acknowledged turn.
468
- * `streamingText` is live-only: it holds the current turn's streamed text and
469
- * empties as soon as that turn's assistant message lands in `messages` (the
470
- * persisted message is the source of truth), consistent with the loop's
471
- * replay-safe, live-only delta design.
472
- */
439
+ * A first-class agent chat surface: live durable history + in-flight token
440
+ * streaming + the send / approve / reject / cancel writes, keyed by `threadKey`.
441
+ *
442
+ * It composes the existing primitives rather than adding transport:
443
+ * `useSubscription(api.agents.agentMessages)` for durable history,
444
+ * `useSubscription(api.agents.agentThread)` for live status + the in-flight
445
+ * `instanceId`, {@link useStream} over an app token stream for in-flight deltas,
446
+ * and `useMutation` for the writes (`api.agents.agentResolveApproval` for
447
+ * approvals; app-defined wrappers for `send`/`cancel`). Only the `agents:*`
448
+ * surface is hard-coded — `send`/`cancel`/`stream` stay generic references.
449
+ *
450
+ * A `send` optimistically appends the user turn so it renders immediately; the
451
+ * optimistic row clears once the durable history carries the acknowledged turn.
452
+ * `streamingText` is live-only: it holds the current turn's streamed text and
453
+ * empties as soon as that turn's assistant message lands in `messages` (the
454
+ * persisted message is the source of truth), consistent with the loop's
455
+ * replay-safe, live-only delta design.
456
+ */
473
457
  declare const useAgentChat: (options: UseAgentChatOptions) => UseAgentChatResult;
474
458
  /**
475
- * The `agents.agentState` reference the hook subscribes to for the thread's live
476
- * synced state. A structural subset of the generated `api.agents` surface (like
477
- * `UseAgentApi` for `agentThread`), so the whole generated `api` object is
478
- * assignable. Client-safe: no `@lunora/agent` import — the per-agent state type
479
- * is mirrored by the hook's generic `T`, since codegen pins the reference return
480
- * as an optional record (it never evaluates agent config).
481
- */
459
+ * The `agents.agentState` reference the hook subscribes to for the thread's live
460
+ * synced state. A structural subset of the generated `api.agents` surface (like
461
+ * `UseAgentApi` for `agentThread`), so the whole generated `api` object is
462
+ * assignable. Client-safe: no `@lunora/agent` import — the per-agent state type
463
+ * is mirrored by the hook's generic `T`, since codegen pins the reference return
464
+ * as an optional record (it never evaluates agent config).
465
+ */
482
466
  interface UseAgentStateApi {
483
467
  agents: {
484
468
  agentState: FunctionReference<"query", {
@@ -499,20 +483,20 @@ interface UseAgentStateResult<T> {
499
483
  state: T | undefined;
500
484
  }
501
485
  /**
502
- * Subscribe to an agent thread's synced state — the `setState`-style value a
503
- * tool writes with `ctx.setState(...)`, seeded by `defineAgent({ initialState })`.
504
- * A thin wrapper over `useSubscription(api.agents.agentState, { key })`: the
505
- * server pushes a fresh frame whenever the state changes (the dedicated query's
506
- * per-socket JSON memo suppresses no-op pushes on unrelated thread writes), so
507
- * `state` updates only on a real `setState`.
508
- *
509
- * Generic over the app's state shape (`useAgentState` with a `SupportState` type
510
- * argument, itself a record) — the reference is typed as an optional record
511
- * because codegen cannot see the per-agent state type; the generic casts to `T`.
512
- * The `extends` bound (not a bare unbounded type parameter) is required: this
513
- * `.ts` file is parsed JSX-aware by the bundler, where an unbounded type-param
514
- * arrow is ambiguous with a JSX element.
515
- */
486
+ * Subscribe to an agent thread's synced state — the `setState`-style value a
487
+ * tool writes with `ctx.setState(...)`, seeded by `defineAgent({ initialState })`.
488
+ * A thin wrapper over `useSubscription(api.agents.agentState, { key })`: the
489
+ * server pushes a fresh frame whenever the state changes (the dedicated query's
490
+ * per-socket JSON memo suppresses no-op pushes on unrelated thread writes), so
491
+ * `state` updates only on a real `setState`.
492
+ *
493
+ * Generic over the app's state shape (`useAgentState` with a `SupportState` type
494
+ * argument, itself a record) — the reference is typed as an optional record
495
+ * because codegen cannot see the per-agent state type; the generic casts to `T`.
496
+ * The `extends` bound (not a bare unbounded type parameter) is required: this
497
+ * `.ts` file is parsed JSX-aware by the bundler, where an unbounded type-param
498
+ * arrow is ambiguous with a JSX element.
499
+ */
516
500
  declare const useAgentState: <T extends Record<string, unknown> = Record<string, unknown>>(options: UseAgentStateOptions) => UseAgentStateResult<T>;
517
501
  /** The `agents:agentMessages` reference — live durable thread history. */
518
502
  type AgentMessagesReference = FunctionReference<"query", {
@@ -520,18 +504,18 @@ type AgentMessagesReference = FunctionReference<"query", {
520
504
  limit?: number;
521
505
  }, ReadonlyArray<Record<string, unknown>>>;
522
506
  /**
523
- * An app stream reference that tees the agent's in-flight live events, keyed by
524
- * thread. Carries token deltas and tool progress events; this hook consumes only
525
- * the progress arm (`kind === "progress"`).
526
- */
507
+ * An app stream reference that tees the agent's in-flight live events, keyed by
508
+ * thread. Carries token deltas and tool progress events; this hook consumes only
509
+ * the progress arm (`kind === "progress"`).
510
+ */
527
511
  type AgentLiveStreamReference = FunctionReference<"stream", {
528
512
  key: string;
529
513
  }, AgentLiveEvent>;
530
514
  /**
531
- * The `agents.*` reference surface the tool-events hook reads. A structural
532
- * subset of the generated `api.agents`, so the whole generated `api` object is
533
- * assignable.
534
- */
515
+ * The `agents.*` reference surface the tool-events hook reads. A structural
516
+ * subset of the generated `api.agents`, so the whole generated `api` object is
517
+ * assignable.
518
+ */
535
519
  interface UseAgentToolEventsApi {
536
520
  agents: {
537
521
  agentMessages: AgentMessagesReference;
@@ -543,21 +527,21 @@ interface UseAgentToolEventsOptions {
543
527
  /** History depth forwarded to `agents:agentMessages`. */
544
528
  limit?: number;
545
529
  /**
546
- * Optional live event stream — the same app stream function `useAgentChat`
547
- * uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
548
- * thread are surfaced as `{ type: "progress" }` entries; when omitted only the
549
- * durable lifecycle (call / result / awaiting-approval) is returned.
550
- */
530
+ * Optional live event stream — the same app stream function `useAgentChat`
531
+ * uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
532
+ * thread are surfaced as `{ type: "progress" }` entries; when omitted only the
533
+ * durable lifecycle (call / result / awaiting-approval) is returned.
534
+ */
551
535
  stream?: AgentLiveStreamReference;
552
536
  /** The thread whose tool activity to observe. */
553
537
  threadKey: string;
554
538
  }
555
539
  /**
556
- * A single tool-lifecycle event for a thread. The durable arms
557
- * (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
558
- * and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
559
- * stream and has no `seq`. Discriminate on `type`.
560
- */
540
+ * A single tool-lifecycle event for a thread. The durable arms
541
+ * (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
542
+ * and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
543
+ * stream and has no `seq`. Discriminate on `type`.
544
+ */
561
545
  type AgentToolEvent = {
562
546
  data: unknown;
563
547
  toolCallId: string;
@@ -583,69 +567,69 @@ type AgentToolEvent = {
583
567
  };
584
568
  interface UseAgentToolEventsResult {
585
569
  /**
586
- * The thread's tool events: the durable lifecycle (oldest first, by `seq`)
587
- * followed by any in-flight ephemeral progress events. Rebuilt each render
588
- * from the live subscription + stream — treat as derived, not identity-stable.
589
- */
570
+ * The thread's tool events: the durable lifecycle (oldest first, by `seq`)
571
+ * followed by any in-flight ephemeral progress events. Rebuilt each render
572
+ * from the live subscription + stream — treat as derived, not identity-stable.
573
+ */
590
574
  events: ReadonlyArray<AgentToolEvent>;
591
575
  }
592
576
  /**
593
- * A focused view of a thread's tool activity: tool calls, their results,
594
- * human-in-the-loop approval pauses, and live `ctx.reportProgress(...)` events —
595
- * without the full chat message surface. Composes the existing primitives:
596
- * `useSubscription(api.agents.agentMessages)` for the durable lifecycle and
597
- * {@link useStream} over the optional app event stream for ephemeral progress.
598
- *
599
- * Progress events are live-only (the durable path never emits them): they ride
600
- * the same sink as token deltas and are surfaced here, correlated to their tool
601
- * call by `toolCallId`. For the conversational surface (messages + streaming
602
- * text + approvals) use `useAgentChat`; this hook is the tool-observability slice.
603
- */
577
+ * A focused view of a thread's tool activity: tool calls, their results,
578
+ * human-in-the-loop approval pauses, and live `ctx.reportProgress(...)` events —
579
+ * without the full chat message surface. Composes the existing primitives:
580
+ * `useSubscription(api.agents.agentMessages)` for the durable lifecycle and
581
+ * {@link useStream} over the optional app event stream for ephemeral progress.
582
+ *
583
+ * Progress events are live-only (the durable path never emits them): they ride
584
+ * the same sink as token deltas and are surfaced here, correlated to their tool
585
+ * call by `toolCallId`. For the conversational surface (messages + streaming
586
+ * text + approvals) use `useAgentChat`; this hook is the tool-observability slice.
587
+ */
604
588
  declare const useAgentToolEvents: (options: UseAgentToolEventsOptions) => UseAgentToolEventsResult;
605
589
  /**
606
- * Token + identity plumbing. The token lives on the shared `LunoraClient`;
607
- * `setToken(jwt)` after a sign-in makes subsequent RPC calls carry the
608
- * `Authorization` header. `user` is resolved from better-auth's `get-session`
609
- * endpoint via `client.getCurrentUser()` — fetched on mount and refetched
610
- * whenever the token changes (`onAuthTokenChange`), and `null` when signed out.
611
- *
612
- * Multiple `useAuth` instances stay in sync: both `token` and `user` are read
613
- * through `useSyncExternalStore` over the shared client (and a per-client
614
- * identity store), so a `setToken` from one component re-renders every mounted
615
- * hook with the freshly-resolved user.
616
- */
590
+ * Token + identity plumbing. The token lives on the shared `LunoraClient`;
591
+ * `setToken(jwt)` after a sign-in makes subsequent RPC calls carry the
592
+ * `Authorization` header. `user` is resolved from better-auth's `get-session`
593
+ * endpoint via `client.getCurrentUser()` — fetched on mount and refetched
594
+ * whenever the token changes (`onAuthTokenChange`), and `null` when signed out.
595
+ *
596
+ * Multiple `useAuth` instances stay in sync: both `token` and `user` are read
597
+ * through `useSyncExternalStore` over the shared client (and a per-client
598
+ * identity store), so a `setToken` from one component re-renders every mounted
599
+ * hook with the freshly-resolved user.
600
+ */
617
601
  declare const useAuth: () => UseAuthResult;
618
602
  type Setter<T> = (value: T) => void;
619
603
  /**
620
- * Subscribe to a local-only {@link ClientQueryRef} and re-render when its
621
- * value changes. Unlike `useQuery`, this never touches the network — the
622
- * value lives in a reactive store on the `LunoraClient` instance and is shared
623
- * across every consumer of the same ref.
624
- *
625
- * The initial render reads the store synchronously (via
626
- * `useSyncExternalStore`), so there is never an "undefined flash" — the value
627
- * is either the one most recently set or `ref.defaultValue`.
628
- *
629
- * Returns a `[value, setter]` tuple, matching the `useState` convention.
630
- * @example
631
- * ```tsx
632
- * import { useClientQuery, createClientQuery } from "@lunora/react";
633
- *
634
- * const sidebarOpen = createClientQuery("sidebarOpen", true);
635
- *
636
- * function Sidebar() {
637
- * const [open, setOpen] = useClientQuery(sidebarOpen);
638
- * return <aside data-open={open}>…</aside>;
639
- * }
640
- * ```
641
- */
604
+ * Subscribe to a local-only {@link ClientQueryRef} and re-render when its
605
+ * value changes. Unlike `useQuery`, this never touches the network — the
606
+ * value lives in a reactive store on the `LunoraClient` instance and is shared
607
+ * across every consumer of the same ref.
608
+ *
609
+ * The initial render reads the store synchronously (via
610
+ * `useSyncExternalStore`), so there is never an "undefined flash" — the value
611
+ * is either the one most recently set or `ref.defaultValue`.
612
+ *
613
+ * Returns a `[value, setter]` tuple, matching the `useState` convention.
614
+ * @example
615
+ * ```tsx
616
+ * import { useClientQuery, createClientQuery } from "@lunora/react";
617
+ *
618
+ * const sidebarOpen = createClientQuery("sidebarOpen", true);
619
+ *
620
+ * function Sidebar() {
621
+ * const [open, setOpen] = useClientQuery(sidebarOpen);
622
+ * return <aside data-open={open}>…</aside>;
623
+ * }
624
+ * ```
625
+ */
642
626
  declare const useClientQuery: <T extends unknown>(ref: ClientQueryRef<T>) => [T, Setter<T>];
643
627
  /**
644
- * Reactive view of the client's aggregate live-socket status across all shard
645
- * connections. Re-renders on every transition (`idle` → `connecting` →
646
- * `connected` → `offline`). Use it to drive a connection indicator so an
647
- * operator can tell a healthy live channel from a silently-dropped socket.
648
- */
628
+ * Reactive view of the client's aggregate live-socket status across all shard
629
+ * connections. Re-renders on every transition (`idle` → `connecting` →
630
+ * `connected` → `offline`). Use it to drive a connection indicator so an
631
+ * operator can tell a healthy live channel from a silently-dropped socket.
632
+ */
649
633
  declare const useConnectionStatus: () => ConnectionStatus;
650
634
  /** A targeting context merged on top of the app's default (`defineFlags({ identify })`). */
651
635
  type FlagContext = Record<string, unknown>;
@@ -654,30 +638,30 @@ type FlagValue = boolean | number | string | {
654
638
  [key: string]: unknown;
655
639
  } | unknown[] | null;
656
640
  /**
657
- * Subscribe to a single feature flag, live over Lunora's WebSocket.
658
- *
659
- * Returns `defaultValue` until the first evaluation lands, then the server's
660
- * resolved value — re-pushed whenever the provider re-evaluates (e.g. a flag is
661
- * toggled in Cloudflare Flagship). The flag's kind is inferred from
662
- * `defaultValue`'s runtime type, so `useFlag("dark", false)` reads a boolean and
663
- * `useFlag("hero", "control")` a string. `context` supplies a per-call targeting
664
- * context merged on top of the app's default `identify` targeting key.
665
- *
666
- * Evaluation runs through whatever OpenFeature provider the app wired in
667
- * `lunora/flags.ts`; the read never throws — a provider error resolves the
668
- * default (the same fail-open contract as server-side `ctx.flags`).
669
- */
641
+ * Subscribe to a single feature flag, live over Lunora's WebSocket.
642
+ *
643
+ * Returns `defaultValue` until the first evaluation lands, then the server's
644
+ * resolved value — re-pushed whenever the provider re-evaluates (e.g. a flag is
645
+ * toggled in Cloudflare Flagship). The flag's kind is inferred from
646
+ * `defaultValue`'s runtime type, so `useFlag("dark", false)` reads a boolean and
647
+ * `useFlag("hero", "control")` a string. `context` supplies a per-call targeting
648
+ * context merged on top of the app's default `identify` targeting key.
649
+ *
650
+ * Evaluation runs through whatever OpenFeature provider the app wired in
651
+ * `lunora/flags.ts`; the read never throws — a provider error resolves the
652
+ * default (the same fail-open contract as server-side `ctx.flags`).
653
+ */
670
654
  declare const useFlag: <T extends FlagValue>(key: string, defaultValue: T, context?: FlagContext) => T;
671
655
  /**
672
- * Subscribe to several feature flags at once, live over Lunora's WebSocket.
673
- *
674
- * Pass a record of `key → defaultValue`; each flag's kind is inferred from its
675
- * default, and the result is the same-shaped record with resolved values (the
676
- * defaults until each evaluation lands). A single `context` applies to every
677
- * flag. This is the batched form of {@link useFlag} — one effect manages one
678
- * subscription per key, so it stays rules-of-hooks-safe even as the flag set
679
- * changes between renders.
680
- */
656
+ * Subscribe to several feature flags at once, live over Lunora's WebSocket.
657
+ *
658
+ * Pass a record of `key → defaultValue`; each flag's kind is inferred from its
659
+ * default, and the result is the same-shaped record with resolved values (the
660
+ * defaults until each evaluation lands). A single `context` applies to every
661
+ * flag. This is the batched form of {@link useFlag} — one effect manages one
662
+ * subscription per key, so it stays rules-of-hooks-safe even as the flag set
663
+ * changes between renders.
664
+ */
681
665
  declare const useFlags: <T extends Record<string, FlagValue>>(flags: T, context?: FlagContext) => T;
682
666
  /** The lifecycle of a stream the hook is observing. */
683
667
  type UseStreamStatus = "complete" | "error" | "idle" | "streaming";
@@ -695,19 +679,19 @@ interface UseStreamOptions {
695
679
  shardKey?: string;
696
680
  }
697
681
  /**
698
- * Subscribe to a streaming query. Returns the chunks pushed so far plus a
699
- * lifecycle status and a cancel function. Changing `fn` or the serialized
700
- * `args` resets the stream — the previous iterator is cancelled and a fresh
701
- * one opens with empty `chunks`.
702
- *
703
- * Pass `"skip"` for `args` to keep the hook mounted without opening a stream
704
- * (mirrors `useQuery` / `useSubscription`).
705
- */
682
+ * Subscribe to a streaming query. Returns the chunks pushed so far plus a
683
+ * lifecycle status and a cancel function. Changing `fn` or the serialized
684
+ * `args` resets the stream — the previous iterator is cancelled and a fresh
685
+ * one opens with empty `chunks`.
686
+ *
687
+ * Pass `"skip"` for `args` to keep the hook mounted without opening a stream
688
+ * (mirrors `useQuery` / `useSubscription`).
689
+ */
706
690
  declare const useStream: <F extends FunctionReference<"stream">>(function_: F, args: "skip" | ArgsOf<F>, options?: UseStreamOptions) => UseStreamResult<ReturnOf<F>>;
707
691
  /**
708
- * Result shape returned by {@link useHttpStream}.
709
- * @experimental Part of the HTTP-SSE stream surface.
710
- */
692
+ * Result shape returned by {@link useHttpStream}.
693
+ * @experimental Part of the HTTP-SSE stream surface.
694
+ */
711
695
  interface UseHttpStreamResult<T> {
712
696
  /** Force-cancel the stream (aborts the fetch) and resolve the iterator. Safe to call multiple times. */
713
697
  cancel: () => void;
@@ -717,26 +701,26 @@ interface UseHttpStreamResult<T> {
717
701
  status: UseStreamStatus;
718
702
  }
719
703
  /**
720
- * Options accepted by {@link useHttpStream}.
721
- * @experimental Part of the HTTP-SSE stream surface.
722
- */
704
+ * Options accepted by {@link useHttpStream}.
705
+ * @experimental Part of the HTTP-SSE stream surface.
706
+ */
723
707
  interface UseHttpStreamOptions {
724
708
  /** Forwarded to `client.httpStream()` — caps the in-flight chunk buffer. */
725
709
  maxBuffer?: number;
726
710
  }
727
711
  /**
728
- * Consume an **HTTP-SSE route stream** (`httpRoute.&lt;verb>(path).stream()`) via
729
- * `client.httpStream`. Distinct from `useStream`, which consumes the WS
730
- * procedure stream (`kind: "stream"`). Returns the chunks received so far plus
731
- * a lifecycle status and a cancel function. Changing the route or the
732
- * serialized `args` resets the stream — the previous fetch is aborted (the
733
- * server sees `request.signal`) and a fresh one opens with empty `chunks`.
734
- * Unmount also aborts.
735
- *
736
- * Pass `"skip"` for `args` to keep the hook mounted without opening a stream
737
- * (mirrors `useQuery` / `useStream`).
738
- * @experimental Reconnect/POST-body/wire-fidelity design questions are still open, so the shape may change.
739
- */
712
+ * Consume an **HTTP-SSE route stream** (`httpRoute.&lt;verb>(path).stream()`) via
713
+ * `client.httpStream`. Distinct from `useStream`, which consumes the WS
714
+ * procedure stream (`kind: "stream"`). Returns the chunks received so far plus
715
+ * a lifecycle status and a cancel function. Changing the route or the
716
+ * serialized `args` resets the stream — the previous fetch is aborted (the
717
+ * server sees `request.signal`) and a fresh one opens with empty `chunks`.
718
+ * Unmount also aborts.
719
+ *
720
+ * Pass `"skip"` for `args` to keep the hook mounted without opening a stream
721
+ * (mirrors `useQuery` / `useStream`).
722
+ * @experimental Reconnect/POST-body/wire-fidelity design questions are still open, so the shape may change.
723
+ */
740
724
  declare const useHttpStream: <Ref extends HttpStreamRef>(route: Ref, args: "skip" | HttpStreamArgsOf<Ref>, options?: UseHttpStreamOptions) => UseHttpStreamResult<HttpStreamChunkOf<Ref>>;
741
725
  /** The args a paginated query exposes minus the framework-supplied page cursor. */
742
726
  type PaginatedArgs<F> = Omit<ArgsOf<F>, "paginationOpts">;
@@ -745,44 +729,44 @@ type PageItemOf<F> = ReturnOf<F> extends {
745
729
  page: (infer T)[];
746
730
  } ? T : unknown;
747
731
  /**
748
- * Subscribe to a reactively-paginated query and grow the feed page by page.
749
- *
750
- * The query function must accept a `paginationOpts: { numItems, cursor,
751
- * endCursor }` arg and return a `PaginationResult` (the shape
752
- * `ctx.db.query(...).paginate` yields). Pages are tracked as an ordered list of
753
- * stable boundary cursors: each loaded page is a live subscription over a
754
- * FIXED `(lower, upper]` range whose upper bound is the next page's lower bound.
755
- * Because boundaries are shared stable cursors, inserting or deleting a row in
756
- * the middle of the list grows/shrinks the affected page in place without
757
- * duplicating or skipping rows across page boundaries — the bug the legacy
758
- * "first N after the previous page's last row" model suffered under live edits.
759
- *
760
- * `loadMore` appends the next page off the open-ended tail's `continueCursor`;
761
- * it is a no-op unless `status === "CanLoadMore"`. Background split/join
762
- * maintenance keeps page sizes near `initialNumItems` as edits accumulate (see
763
- * `use-paginated-core.ts`).
764
- *
765
- * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
766
- * feed to its first page. The public return shape (`results` / `status` /
767
- * `loadMore`) is unchanged from the legacy keyset implementation.
768
- */
732
+ * Subscribe to a reactively-paginated query and grow the feed page by page.
733
+ *
734
+ * The query function must accept a `paginationOpts: { numItems, cursor,
735
+ * endCursor }` arg and return a `PaginationResult` (the shape
736
+ * `ctx.db.query(...).paginate` yields). Pages are tracked as an ordered list of
737
+ * stable boundary cursors: each loaded page is a live subscription over a
738
+ * FIXED `(lower, upper]` range whose upper bound is the next page's lower bound.
739
+ * Because boundaries are shared stable cursors, inserting or deleting a row in
740
+ * the middle of the list grows/shrinks the affected page in place without
741
+ * duplicating or skipping rows across page boundaries — the bug the legacy
742
+ * "first N after the previous page's last row" model suffered under live edits.
743
+ *
744
+ * `loadMore` appends the next page off the open-ended tail's `continueCursor`;
745
+ * it is a no-op unless `status === "CanLoadMore"`. Background split/join
746
+ * maintenance keeps page sizes near `initialNumItems` as edits accumulate (see
747
+ * `use-paginated-core.ts`).
748
+ *
749
+ * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
750
+ * feed to its first page. The public return shape (`results` / `status` /
751
+ * `loadMore`) is unchanged from the legacy keyset implementation.
752
+ */
769
753
  declare const usePaginatedQuery: <F extends FunctionReference>(function_: F, args: "skip" | PaginatedArgs<F>, options: UsePaginatedQueryOptions) => UsePaginatedQueryResult<PageItemOf<F>>;
770
754
  /**
771
- * Subscribe to a reactively-paginated query and expose its pages discretely.
772
- *
773
- * Shares `usePaginatedQuery`'s reactive-pagination engine — pages are fixed
774
- * `(lower, upper]` cursor ranges with shared stable boundaries, so a row
775
- * inserted or deleted mid-list grows/shrinks the affected page without
776
- * duplicating or skipping rows across boundaries — but keeps each page as its
777
- * own inner array rather than flattening them, and adds the
778
- * TanStack-Query-style `fetchNextPage` / `hasNextPage` / `isFetchingNextPage`
779
- * shape. `fetchNextPage` appends the next page off the open-ended tail's
780
- * `continueCursor`; it is a no-op unless `status === "CanLoadMore"`.
781
- *
782
- * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
783
- * feed to its first page. The public return shape is unchanged from the legacy
784
- * keyset implementation.
785
- */
755
+ * Subscribe to a reactively-paginated query and expose its pages discretely.
756
+ *
757
+ * Shares `usePaginatedQuery`'s reactive-pagination engine — pages are fixed
758
+ * `(lower, upper]` cursor ranges with shared stable boundaries, so a row
759
+ * inserted or deleted mid-list grows/shrinks the affected page without
760
+ * duplicating or skipping rows across boundaries — but keeps each page as its
761
+ * own inner array rather than flattening them, and adds the
762
+ * TanStack-Query-style `fetchNextPage` / `hasNextPage` / `isFetchingNextPage`
763
+ * shape. `fetchNextPage` appends the next page off the open-ended tail's
764
+ * `continueCursor`; it is a no-op unless `status === "CanLoadMore"`.
765
+ *
766
+ * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
767
+ * feed to its first page. The public return shape is unchanged from the legacy
768
+ * keyset implementation.
769
+ */
786
770
  declare const useInfiniteQuery: <F extends FunctionReference>(function_: F, args: "skip" | PaginatedArgs<F>, options: UseInfiniteQueryOptions) => UseInfiniteQueryResult<PageItemOf<F>>;
787
771
  type CallOptions<F extends FunctionReference> = UseMutationCallOptions<unknown, unknown, ArgsOf<F>>;
788
772
  interface MutationHook<F extends FunctionReference> {
@@ -798,34 +782,34 @@ interface MutationHook<F extends FunctionReference> {
798
782
  /** Clear the latest `data`/`error` back to idle. */
799
783
  reset: () => void;
800
784
  /**
801
- * Bind a Convex-parity multi-query optimistic update to this mutation.
802
- * Returns a `{ mutate, pending, … }` whose `mutate` forwards `update` as the
803
- * `optimisticUpdate` for every call — unless a per-call `optimisticUpdate`
804
- * is supplied in the call options, which overrides the bound one.
805
- */
785
+ * Bind a Convex-parity multi-query optimistic update to this mutation.
786
+ * Returns a `{ mutate, pending, … }` whose `mutate` forwards `update` as the
787
+ * `optimisticUpdate` for every call — unless a per-call `optimisticUpdate`
788
+ * is supplied in the call options, which overrides the bound one.
789
+ */
806
790
  withOptimisticUpdate: (update: OptimisticUpdate<ArgsOf<F>>) => MutationHook<F>;
807
791
  }
808
792
  /**
809
- * Returns `{ mutate, pending, data, error, reset, withOptimisticUpdate }` for the
810
- * given mutation reference. Prefer destructuring at the call site so the React
811
- * linter can track dependencies on each field independently.
812
- *
813
- * Built on TanStack Query's mutation cache (the same cache the query hooks use),
814
- * so it composes with Query Devtools and exposes the latest call's `data`/`error`
815
- * plus `reset()`. `mutate` maps to `mutateAsync`, so it stays an awaitable that
816
- * rejects on failure (rather than TanStack's fire-and-forget `mutate`).
817
- *
818
- * `pending` is ref-counted across overlapping invocations of THIS hook instance
819
- * (driven by the mutation's `onMutate`/`onSettled` lifecycle), so it flips back to
820
- * `false` only once every concurrent call has settled — and a sibling component
821
- * mutating the same function never affects it (TanStack's own `isPending` tracks
822
- * just the latest invocation).
823
- *
824
- * Optimistic updates stay client-owned: the `optimistic` / `optimisticUpdate`
825
- * call options pass straight through to `client.mutation`, which applies and
826
- * rolls them back against the Lunora subscription cache (Convex parity) — not
827
- * through TanStack's `onMutate`.
828
- */
793
+ * Returns `{ mutate, pending, data, error, reset, withOptimisticUpdate }` for the
794
+ * given mutation reference. Prefer destructuring at the call site so the React
795
+ * linter can track dependencies on each field independently.
796
+ *
797
+ * Built on TanStack Query's mutation cache (the same cache the query hooks use),
798
+ * so it composes with Query Devtools and exposes the latest call's `data`/`error`
799
+ * plus `reset()`. `mutate` maps to `mutateAsync`, so it stays an awaitable that
800
+ * rejects on failure (rather than TanStack's fire-and-forget `mutate`).
801
+ *
802
+ * `pending` is ref-counted across overlapping invocations of THIS hook instance
803
+ * (driven by the mutation's `onMutate`/`onSettled` lifecycle), so it flips back to
804
+ * `false` only once every concurrent call has settled — and a sibling component
805
+ * mutating the same function never affects it (TanStack's own `isPending` tracks
806
+ * just the latest invocation).
807
+ *
808
+ * Optimistic updates stay client-owned: the `optimistic` / `optimisticUpdate`
809
+ * call options pass straight through to `client.mutation`, which applies and
810
+ * rolls them back against the Lunora subscription cache (Convex parity) — not
811
+ * through TanStack's `onMutate`.
812
+ */
829
813
  declare const useMutation: <F extends FunctionReference>(function_: F) => MutationHook<F>;
830
814
  interface MutatorHook<TArgs> {
831
815
  /** The latest invocation's error, or `undefined`. */
@@ -840,86 +824,86 @@ interface MutatorHook<TArgs> {
840
824
  reset: () => void;
841
825
  }
842
826
  /**
843
- * Ergonomic `{ mutate, pending, error, isError, reset }` wrapper over a bound
844
- * custom-mutator handle from `@lunora/db`'s `bindMutators`. The optimistic
845
- * overlay and server-authoritative push are owned by the bound handle (and
846
- * TanStack DB's optimistic-transaction layer rebases pending overlays on every
847
- * sync tick) — this hook only surfaces React state for the in-flight/error
848
- * lifecycle. Reads stay on the existing `useLiveQuery`; no new query hook is
849
- * needed.
850
- *
851
- * `pending` is ref-counted across overlapping invocations of THIS hook instance,
852
- * so it clears only once every concurrent call has settled.
853
- */
827
+ * Ergonomic `{ mutate, pending, error, isError, reset }` wrapper over a bound
828
+ * custom-mutator handle from `@lunora/db`'s `bindMutators`. The optimistic
829
+ * overlay and server-authoritative push are owned by the bound handle (and
830
+ * TanStack DB's optimistic-transaction layer rebases pending overlays on every
831
+ * sync tick) — this hook only surfaces React state for the in-flight/error
832
+ * lifecycle. Reads stay on the existing `useLiveQuery`; no new query hook is
833
+ * needed.
834
+ *
835
+ * `pending` is ref-counted across overlapping invocations of THIS hook instance,
836
+ * so it clears only once every concurrent call has settled.
837
+ */
854
838
  declare const useMutator: <TArgs = Record<string, unknown>>(handle: MutatorHandle<TArgs>) => MutatorHook<TArgs>;
855
839
  /**
856
- * Hydrate a query from a {@link Preloaded} token produced by `preloadQuery`
857
- * during SSR, then keep it live.
858
- *
859
- * The first render returns the preloaded value (TanStack's `initialData`),
860
- * so the server markup and the initial client markup match — no hydration
861
- * mismatch, no loading flash. After mount, a WS subscription attaches so
862
- * later server pushes update the value just like `useQuery`.
863
- *
864
- * The {@link Preloaded} token's `value` seeds `initialData`; we don't need a
865
- * full dehydrate/hydrate dance because the consumer hands us the resolved
866
- * value directly. Apps that want to share a pre-populated QueryClient across
867
- * many preloaded queries can pass their own `queryClient` to `LunoraProvider`
868
- * and hydrate it themselves via TanStack's `hydrate(qc, dehydratedState)`.
869
- */
840
+ * Hydrate a query from a {@link Preloaded} token produced by `preloadQuery`
841
+ * during SSR, then keep it live.
842
+ *
843
+ * The first render returns the preloaded value (TanStack's `initialData`),
844
+ * so the server markup and the initial client markup match — no hydration
845
+ * mismatch, no loading flash. After mount, a WS subscription attaches so
846
+ * later server pushes update the value just like `useQuery`.
847
+ *
848
+ * The {@link Preloaded} token's `value` seeds `initialData`; we don't need a
849
+ * full dehydrate/hydrate dance because the consumer hands us the resolved
850
+ * value directly. Apps that want to share a pre-populated QueryClient across
851
+ * many preloaded queries can pass their own `queryClient` to `LunoraProvider`
852
+ * and hydrate it themselves via TanStack's `hydrate(qc, dehydratedState)`.
853
+ */
870
854
  declare const usePreloadedQuery: <T>(preloaded: Preloaded<T>) => T;
871
855
  /**
872
- * The PLAN4 §1 framework-neutral name for the preloaded-hydration handoff:
873
- * `hydratePreloaded(preloaded)` seeds the SSR value on the first paint, then
874
- * attaches a live WS subscription on mount. It is a thin alias of
875
- * {@link usePreloadedQuery} so the React adapter exposes the same
876
- * `hydratePreloaded` primitive every other adapter (Solid, Svelte, Vue) will,
877
- * while existing callers of `usePreloadedQuery` keep working unchanged.
878
- *
879
- * It carries React's Rules-of-Hooks contract (it calls hooks internally), so
880
- * call it like a hook — at the top level of a component, unconditionally.
881
- */
856
+ * The PLAN4 §1 framework-neutral name for the preloaded-hydration handoff:
857
+ * `hydratePreloaded(preloaded)` seeds the SSR value on the first paint, then
858
+ * attaches a live WS subscription on mount. It is a thin alias of
859
+ * {@link usePreloadedQuery} so the React adapter exposes the same
860
+ * `hydratePreloaded` primitive every other adapter (Solid, Svelte, Vue) will,
861
+ * while existing callers of `usePreloadedQuery` keep working unchanged.
862
+ *
863
+ * It carries React's Rules-of-Hooks contract (it calls hooks internally), so
864
+ * call it like a hook — at the top level of a component, unconditionally.
865
+ */
882
866
  declare const hydratePreloaded: <T>(preloaded: Preloaded<T>) => T;
883
867
  /**
884
- * `usePresence` — collaborative-awareness hook, the client half of the
885
- * `@lunora/server` `definePresence` preset (Convex `@convex-dev/presence`
886
- * parity).
887
- *
888
- * It drives the two presence functions the server component ships:
889
- *
890
- * - **heartbeat** (a mutation): called on mount, on a fixed interval, and again
891
- * whenever the tab becomes visible, to upsert the caller's presence row and
892
- * refresh its `lastSeen`. On unmount the interval is cleared. Each heartbeat
893
- * carries the latest `data` from a ref, so `setData` takes effect on the next
894
- * tick without re-subscribing or resetting the timer.
895
- * - **listPresent** (a query): subscribed to over the live-query WS, so the
896
- * present-list updates reactively. Because the server patches a single row per
897
- * heartbeat, the client's **per-row subscription delta merge** applies just that
898
- * row to the cached list instead of re-sending every member — the list stays
899
- * cheap even with many participants heart-beating.
900
- *
901
- * `sessionId` defaults to a stable per-mount id (one row per tab); pass your own
902
- * to dedupe across tabs by user. TTL/expiry is server-side: a member that stops
903
- * heart-beating drops out of `listPresent` once `lastSeen` ages past the TTL, so
904
- * the hook needs no client-side reaping.
905
- *
906
- * The two `FunctionReference`s come from your generated `api` (e.g.
907
- * `api.presence.heartbeat` / `api.presence.listPresent`) — passed in so the hook
908
- * stays decoupled from any specific app schema.
909
- */
868
+ * `usePresence` — collaborative-awareness hook, the client half of the
869
+ * `@lunora/server` `definePresence` preset (Convex `@convex-dev/presence`
870
+ * parity).
871
+ *
872
+ * It drives the two presence functions the server component ships:
873
+ *
874
+ * - **heartbeat** (a mutation): called on mount, on a fixed interval, and again
875
+ * whenever the tab becomes visible, to upsert the caller's presence row and
876
+ * refresh its `lastSeen`. On unmount the interval is cleared. Each heartbeat
877
+ * carries the latest `data` from a ref, so `setData` takes effect on the next
878
+ * tick without re-subscribing or resetting the timer.
879
+ * - **listPresent** (a query): subscribed to over the live-query WS, so the
880
+ * present-list updates reactively. Because the server patches a single row per
881
+ * heartbeat, the client's **per-row subscription delta merge** applies just that
882
+ * row to the cached list instead of re-sending every member — the list stays
883
+ * cheap even with many participants heart-beating.
884
+ *
885
+ * `sessionId` defaults to a stable per-mount id (one row per tab); pass your own
886
+ * to dedupe across tabs by user. TTL/expiry is server-side: a member that stops
887
+ * heart-beating drops out of `listPresent` once `lastSeen` ages past the TTL, so
888
+ * the hook needs no client-side reaping.
889
+ *
890
+ * The two `FunctionReference`s come from your generated `api` (e.g.
891
+ * `api.presence.heartbeat` / `api.presence.listPresent`) — passed in so the hook
892
+ * stays decoupled from any specific app schema.
893
+ */
910
894
  /**
911
- * A heartbeat mutation reference: takes `{ roomId, sessionId, data? }` (the shape
912
- * `definePresence().functions.heartbeat` registers).
913
- */
895
+ * A heartbeat mutation reference: takes `{ roomId, sessionId, data? }` (the shape
896
+ * `definePresence().functions.heartbeat` registers).
897
+ */
914
898
  type HeartbeatReference = FunctionReference<"mutation", {
915
899
  data?: Record<string, unknown>;
916
900
  roomId: string;
917
901
  sessionId: string;
918
902
  }>;
919
903
  /**
920
- * A listPresent query reference: takes `{ roomId }` and returns the array of
921
- * present members.
922
- */
904
+ * A listPresent query reference: takes `{ roomId }` and returns the array of
905
+ * present members.
906
+ */
923
907
  type ListPresentReference = FunctionReference<"query", {
924
908
  roomId: string;
925
909
  }>;
@@ -933,9 +917,9 @@ interface UsePresenceOptions<H extends HeartbeatReference, L extends ListPresent
933
917
  /** The `api.*` reference for the presence listPresent query. */
934
918
  listPresent: L;
935
919
  /**
936
- * Stable id for this presence row. Defaults to a fresh per-mount id (one row
937
- * per tab). Pass a user/connection id to control deduping.
938
- */
920
+ * Stable id for this presence row. Defaults to a fresh per-mount id (one row
921
+ * per tab). Pass a user/connection id to control deduping.
922
+ */
939
923
  sessionId?: string;
940
924
  /** Forwarded to the heartbeat mutation / listPresent subscription when sharding by room. */
941
925
  shardKey?: string;
@@ -950,31 +934,31 @@ interface UsePresenceResult<L extends ListPresentReference> {
950
934
  }
951
935
  declare const usePresence: <H extends HeartbeatReference, L extends ListPresentReference>(roomId: string, options: UsePresenceOptions<H, L>) => UsePresenceResult<L>;
952
936
  /**
953
- * Subscribe to a server query.
954
- *
955
- * Returns `undefined` until the first response lands. Pass `"skip"` for
956
- * `args` to short-circuit the query (no network call, no subscription).
957
- *
958
- * When the `LunoraClient` was created with `hydrateOnStart: true` and a
959
- * `queryCache` adapter, the first **enabled** render waits for the durable
960
- * read cache to finish loading. If a cached value exists for this query it
961
- * is fed as `initialData` so the user sees it immediately — no undefined
962
- * flash before the socket round-trip.
963
- *
964
- * Internally this routes through TanStack Query: the queryKey is
965
- * `["lunora", fn.__lunoraRef, args, shardKey]` (TanStack hashes structurally
966
- * so an args object built in a different key order still dedupes). The
967
- * subscription registry shares a single WS subscription across every consumer
968
- * of the same queryKey; pushes call `queryClient.setQueryData(...)`.
969
- */
937
+ * Subscribe to a server query.
938
+ *
939
+ * Returns `undefined` until the first response lands. Pass `"skip"` for
940
+ * `args` to short-circuit the query (no network call, no subscription).
941
+ *
942
+ * When the `LunoraClient` was created with `hydrateOnStart: true` and a
943
+ * `queryCache` adapter, the first **enabled** render waits for the durable
944
+ * read cache to finish loading. If a cached value exists for this query it
945
+ * is fed as `initialData` so the user sees it immediately — no undefined
946
+ * flash before the socket round-trip.
947
+ *
948
+ * Internally this routes through TanStack Query: the queryKey is
949
+ * `["lunora", fn.__lunoraRef, args, shardKey]` (TanStack hashes structurally
950
+ * so an args object built in a different key order still dedupes). The
951
+ * subscription registry shares a single WS subscription across every consumer
952
+ * of the same queryKey; pushes call `queryClient.setQueryData(...)`.
953
+ */
970
954
  declare const useQuery: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip", options?: UseQueryOptions) => ReturnOf<F> | undefined;
971
955
  interface UseRateLimitOptions {
972
956
  /** Clock injection for tests. Defaults to `Date.now`. */
973
957
  now?: () => number;
974
958
  /**
975
- * Re-render cadence in milliseconds while throttled, so `retryAfter` ticks
976
- * down and `disabled` flips back automatically. Defaults to `1000`.
977
- */
959
+ * Re-render cadence in milliseconds while throttled, so `retryAfter` ticks
960
+ * down and `disabled` flips back automatically. Defaults to `1000`.
961
+ */
978
962
  tickMs?: number;
979
963
  }
980
964
  interface UseRateLimitResult {
@@ -992,35 +976,35 @@ interface UseRateLimitResult {
992
976
  retryAfter: number;
993
977
  }
994
978
  /**
995
- * Client-side mirror of a rate limit for instant UX — disable a button or show
996
- * a countdown without a round-trip. It runs the same token-bucket / fixed-window
997
- * math as `@lunora/ratelimit` on the server, so the prediction agrees with the
998
- * authoritative check; the server remains the source of truth.
999
- *
1000
- * `config` is read on every render; pass a stable reference (module constant or
1001
- * `useMemo`) so the `consume`/`check` callbacks keep a steady identity.
1002
- */
979
+ * Client-side mirror of a rate limit for instant UX — disable a button or show
980
+ * a countdown without a round-trip. It runs the same token-bucket / fixed-window
981
+ * math as `@lunora/ratelimit` on the server, so the prediction agrees with the
982
+ * authoritative check; the server remains the source of truth.
983
+ *
984
+ * `config` is read on every render; pass a stable reference (module constant or
985
+ * `useMemo`) so the `consume`/`check` callbacks keep a steady identity.
986
+ */
1003
987
  declare const useRateLimit: (config: RateLimitConfig, options?: UseRateLimitOptions) => UseRateLimitResult;
1004
988
  /**
1005
- * Subscribe to a real-time stream from the server. Unlike `useQuery`, this
1006
- * hook does not issue an initial HTTP fetch — it only delivers values that
1007
- * the server pushes over the WS.
1008
- */
989
+ * Subscribe to a real-time stream from the server. Unlike `useQuery`, this
990
+ * hook does not issue an initial HTTP fetch — it only delivers values that
991
+ * the server pushes over the WS.
992
+ */
1009
993
  declare const useSubscription: <F extends FunctionReference>(function_: F, args: ArgsOf<F> | "skip", options?: UseQueryOptions) => UseSubscriptionResult<ReturnOf<F>>;
1010
994
  /**
1011
- * Browser Web Audio subsystems for `useVoiceAgent` — the default microphone
1012
- * capture and speaker playback implementations injected into the hook via its
1013
- * `createMicrophone` / `createSpeaker` seams. Kept in a sibling module so the
1014
- * heavy Web Audio graph (and its structural DOM typings) stays isolated from the
1015
- * hook's transport + React-state logic and remains mockable in a non-browser
1016
- * test env.
1017
- */
995
+ * Browser Web Audio subsystems for `useVoiceAgent` — the default microphone
996
+ * capture and speaker playback implementations injected into the hook via its
997
+ * `createMicrophone` / `createSpeaker` seams. Kept in a sibling module so the
998
+ * heavy Web Audio graph (and its structural DOM typings) stays isolated from the
999
+ * hook's transport + React-state logic and remains mockable in a non-browser
1000
+ * test env.
1001
+ */
1018
1002
  /**
1019
- * The negotiated audio format the voice DO streams back. Mirrors
1020
- * `@lunora/agent`'s `VoiceServerFrame` `ready.audioFormat` — re-declared (not
1021
- * imported) so this React package never pulls in the server-only `@lunora/agent`
1022
- * module graph.
1023
- */
1003
+ * The negotiated audio format the voice DO streams back. Mirrors
1004
+ * `@lunora/agent`'s `VoiceServerFrame` `ready.audioFormat` — re-declared (not
1005
+ * imported) so this React package never pulls in the server-only `@lunora/agent`
1006
+ * module graph.
1007
+ */
1024
1008
  type VoiceAudioFormat = "mp3" | "wav";
1025
1009
  /** Captures microphone audio and reports level / turn boundaries back to the hook. */
1026
1010
  interface VoiceMicrophone {
@@ -1064,15 +1048,10 @@ type CreateSpeaker = (config: {
1064
1048
  audioFormat: VoiceAudioFormat;
1065
1049
  }) => VoiceSpeaker;
1066
1050
  /**
1067
- * The default browser microphone: `getUserMedia` a Web Audio `ScriptProcessor`
1068
- * that tees 16 kHz PCM frames, tracks input RMS, auto-commits an utterance after
1069
- * a silence gap, and flags a barge-in while the agent is speaking.
1070
- */
1071
- /**
1072
- * The `agents.&lt;name>Voice` reference codegen emits for a voice-enabled agent — a
1073
- * live, WS-backed session keyed by `threadKey`. A structural subset of the
1074
- * generated member, so passing `api.agents.&lt;name>Voice` type-checks.
1075
- */
1051
+ * The `agents.&lt;name>Voice` reference codegen emits for a voice-enabled agent — a
1052
+ * live, WS-backed session keyed by `threadKey`. A structural subset of the
1053
+ * generated member, so passing `api.agents.&lt;name>Voice` type-checks.
1054
+ */
1076
1055
  type VoiceReference = FunctionReference<"stream", {
1077
1056
  threadKey: string;
1078
1057
  }, Record<string, unknown>>;
@@ -1094,10 +1073,10 @@ interface VoiceSocket {
1094
1073
  type CreateSocket = (url: string) => VoiceSocket;
1095
1074
  interface UseVoiceAgentOptions {
1096
1075
  /**
1097
- * Advanced/test seam: build the microphone capture subsystem. Defaults to a
1098
- * `getUserMedia` + Web Audio implementation. Injected wholesale so the Web
1099
- * Audio graph stays isolated (and mockable in a non-browser test env).
1100
- */
1076
+ * Advanced/test seam: build the microphone capture subsystem. Defaults to a
1077
+ * `getUserMedia` + Web Audio implementation. Injected wholesale so the Web
1078
+ * Audio graph stays isolated (and mockable in a non-browser test env).
1079
+ */
1101
1080
  createMicrophone?: CreateMicrophone;
1102
1081
  /** Advanced/test seam: open the transport. Defaults to `new WebSocket(url)`. */
1103
1082
  createSocket?: CreateSocket;
@@ -1141,17 +1120,17 @@ interface UseVoiceAgentResult {
1141
1120
  transcript: string;
1142
1121
  }
1143
1122
  /**
1144
- * A first-class voice-call surface for a voice-enabled agent: it opens a
1145
- * WebSocket to the agent's `VoiceSessionDO`, captures mic audio as 16 kHz PCM,
1146
- * streams the agent's synthesized speech back through the browser's audio output,
1147
- * and mirrors the call lifecycle (`status`, `transcript`, `interimTranscript`,
1148
- * `audioLevel`) to React state. Pass the generated `api.agents.&lt;name>Voice`
1149
- * reference (never a string), matching `useAgentChat`'s reference-passing style.
1150
- *
1151
- * v1 transport is plain binary WebSocket frames with push-to-talk / silence-timer
1152
- * turn detection and client-side RMS barge-in. The heavy Web Audio capture and
1153
- * playback subsystems are injectable (`createMicrophone` / `createSpeaker` /
1154
- * `createSocket`) so the hook is drivable outside a browser.
1155
- */
1123
+ * A first-class voice-call surface for a voice-enabled agent: it opens a
1124
+ * WebSocket to the agent's `VoiceSessionDO`, captures mic audio as 16 kHz PCM,
1125
+ * streams the agent's synthesized speech back through the browser's audio output,
1126
+ * and mirrors the call lifecycle (`status`, `transcript`, `interimTranscript`,
1127
+ * `audioLevel`) to React state. Pass the generated `api.agents.&lt;name>Voice`
1128
+ * reference (never a string), matching `useAgentChat`'s reference-passing style.
1129
+ *
1130
+ * v1 transport is plain binary WebSocket frames with push-to-talk / silence-timer
1131
+ * turn detection and client-side RMS barge-in. The heavy Web Audio capture and
1132
+ * playback subsystems are injectable (`createMicrophone` / `createSpeaker` /
1133
+ * `createSocket`) so the hook is drivable outside a browser.
1134
+ */
1156
1135
  declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
1157
1136
  export { type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, type AuthState, Authenticated, CheckoutButton, type CheckoutButtonProps, CustomerPortalButton, type CustomerPortalButtonProps, type FlagContext, type FlagValue, type HeartbeatReference, type ListPresentReference, LunoraProvider, type LunoraProviderProps, type MutationHook, type MutatorHook, type PageItemOf, type PaginatedArgs, type RedirectTarget, type RedirectTrigger, type Subscription, Unauthenticated, type UseAgentApi, type UseAgentChatApi, type UseAgentChatOptions, type UseAgentChatResult, type UseAgentOptions, type UseAgentResult, type UseAgentStateApi, type UseAgentStateOptions, type UseAgentStateResult, type UseAgentToolEventsApi, type UseAgentToolEventsOptions, type UseAgentToolEventsResult, type UseAuthResult, type UseCheckoutResult, type UseHttpStreamOptions, type UseHttpStreamResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UseMutationCallOptions, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseStreamOptions, type UseStreamResult, type UseStreamStatus, type UseSubscriptionResult, type UseVoiceAgentOptions, type UseVoiceAgentResult, type VoiceAudioFormat, type VoiceReference, type VoiceStatus, hydratePreloaded, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useAuthState, useCheckout, useClientQuery, useConnectionStatus, useFlag, useFlags, useHttpStream, useInfiniteQuery, useLunora, useMutation, useMutator, usePaginatedQuery, usePreloadedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };