@lunora/vue 1.0.0-alpha.9 → 1.0.0-alpha.91

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE.md +6 -0
  2. package/README.md +2 -0
  3. package/dist/index.d.mts +951 -188
  4. package/dist/index.d.ts +951 -188
  5. package/dist/index.mjs +1 -11
  6. package/dist/packem_shared/AuthLoading-nfI43dvD.mjs +1 -0
  7. package/dist/packem_shared/LUNORA_INJECTION_KEY-Bct9tKCj.mjs +1 -0
  8. package/dist/packem_shared/hydratePreloaded-kyzbcRHO.mjs +1 -0
  9. package/dist/packem_shared/is-browser-BEdfLJHK.mjs +1 -0
  10. package/dist/packem_shared/scope-dispose-Mq3k4nvP.mjs +1 -0
  11. package/dist/packem_shared/stable-key-ITGZkfuz.mjs +1 -0
  12. package/dist/packem_shared/subscribeToQuery-DPfbYx11.mjs +1 -0
  13. package/dist/packem_shared/useAction-C4VLsh4M.mjs +1 -0
  14. package/dist/packem_shared/useAgent-Bji8ptsw.mjs +1 -0
  15. package/dist/packem_shared/useAgentChat-C3Q3Wf5w.mjs +1 -0
  16. package/dist/packem_shared/useAgentState-B_LPf5ZX.mjs +1 -0
  17. package/dist/packem_shared/useAgentToolEvents-DYYeyrXW.mjs +1 -0
  18. package/dist/packem_shared/useAuth-DJ9902_4.mjs +1 -0
  19. package/dist/packem_shared/useConnectionStatus-BSFJBnmi.mjs +1 -0
  20. package/dist/packem_shared/useFlag-isqtnhHx.mjs +1 -0
  21. package/dist/packem_shared/useInfiniteQuery-DNrg36Co.mjs +1 -0
  22. package/dist/packem_shared/useMutation-D6PkaNaE.mjs +1 -0
  23. package/dist/packem_shared/useMutator-CO7nXlRf.mjs +1 -0
  24. package/dist/packem_shared/usePresence-D5H9k1UX.mjs +1 -0
  25. package/dist/packem_shared/useRateLimit-zoPsflSG.mjs +1 -0
  26. package/dist/packem_shared/useStream-pSLl_8ix.mjs +1 -0
  27. package/dist/packem_shared/useSubscription-uZqOa1Pu.mjs +1 -0
  28. package/dist/packem_shared/useVoiceAgent-CR6Tyf_3.mjs +1 -0
  29. package/dist/server.mjs +1 -1
  30. package/dist/upload.d.mts +2 -0
  31. package/dist/upload.d.ts +2 -0
  32. package/dist/upload.mjs +1 -0
  33. package/package.json +8 -7
  34. package/dist/packem_shared/AuthLoading-_6-uOycE.mjs +0 -29
  35. package/dist/packem_shared/LUNORA_INJECTION_KEY-DtFXLDQ_.mjs +0 -22
  36. package/dist/packem_shared/hydratePreloaded-rVY68iFv.mjs +0 -14
  37. package/dist/packem_shared/subscribeToQuery-Cv5YL-SI.mjs +0 -51
  38. package/dist/packem_shared/useAuth-C2aEzXXH.mjs +0 -28
  39. package/dist/packem_shared/useConnectionStatus-CDgduQYe.mjs +0 -20
  40. package/dist/packem_shared/useInfiniteQuery-CEfbw7Nw.mjs +0 -199
  41. package/dist/packem_shared/useMutation-DWubV5pv.mjs +0 -29
  42. package/dist/packem_shared/usePresence-BeN5xaZM.mjs +0 -59
  43. package/dist/packem_shared/useRateLimit-DlPWjcX1.mjs +0 -67
  44. package/dist/packem_shared/useSubscription-Ol0AZFUv.mjs +0 -47
  45. package/dist/worker.d.mts +0 -1
  46. package/dist/worker.d.ts +0 -1
  47. package/dist/worker.mjs +0 -1
package/dist/index.d.mts CHANGED
@@ -1,114 +1,593 @@
1
- import { Component, Ref, InjectionKey, App, DeepReadonly, MaybeRefOrGetter, ShallowRef, ComputedRef } from 'vue';
2
- import { Preloaded, LunoraClient, User, ConnectionStatus, FunctionReference, ReturnOf, ArgsOf, MutationCallOptions } from '@lunora/client';
3
- export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, Unsubscribe, User } from '@lunora/client';
1
+ import { Component, Ref, InjectionKey, App, MaybeRefOrGetter, ComputedRef, DeepReadonly, ShallowRef } from 'vue';
2
+ import { Preloaded, LunoraClient, FunctionReference, ArgsOf, ActionCallOptions, ReturnOf, User, ConnectionStatus, MutationCallOptions, MutatorHandle } from '@lunora/client';
3
+ export type { ArgsOf, FunctionReference, LunoraClient, MutationCallOptions, MutatorHandle, MutatorTransaction, OptimisticLocalStore, OptimisticUpdate, Preloaded, ReturnOf, Unsubscribe, User } from '@lunora/client';
4
4
  import { PaginationStatus } from '@lunora/client/pagination';
5
5
  export type { PaginationResult, PaginationStatus } from '@lunora/client/pagination';
6
6
  import { RateLimitStatus, RateLimitConfig } from '@lunora/ratelimit';
7
7
  /**
8
- * Render the default slot only after auth has settled and a token + user are
9
- * both present. Hides the slot on first render and when signed out.
10
- */
8
+ * Render the default slot only after auth has settled and a token + user are
9
+ * both present. Hides the slot on first render and when signed out.
10
+ */
11
11
  declare const Authenticated: Component;
12
12
  /**
13
- * Render the default slot only when auth has settled and no token is present
14
- * (the signed-out state). Hidden while the user is still loading.
15
- */
13
+ * Render the default slot only when auth has settled and no token is present
14
+ * (the signed-out state). Hidden while the user is still loading.
15
+ */
16
16
  declare const Unauthenticated: Component;
17
17
  /**
18
- * Render the default slot while authentication is still in progress — token is
19
- * set but `getCurrentUser()` has not yet resolved.
20
- */
18
+ * Render the default slot while authentication is still in progress — token is
19
+ * set but `getCurrentUser()` has not yet resolved.
20
+ */
21
21
  declare const AuthLoading: Component;
22
22
  /**
23
- * Hydrate a query from a {@link Preloaded} token produced by `preloadQuery`
24
- * during SSR, then keep it live — the Vue half of PLAN4's reactive-loader
25
- * handoff.
26
- *
27
- * The returned `ref` is seeded **synchronously** from `preloaded.value`, so the
28
- * very first read (during hydration) shows the server value: no loading flash,
29
- * no hydration mismatch. After seeding it opens a WebSocket subscription on the
30
- * same `(functionPath, args, shardKey)` the SSR loader used, so every later
31
- * server delta updates the ref exactly like `useQuery`.
32
- *
33
- * The subscription tears down with the surrounding effect scope (component
34
- * unmount or `effectScope().stop()`), inherited from `subscribeToQuery`.
35
- */
23
+ * Hydrate a query from a {@link Preloaded} token produced by `preloadQuery`
24
+ * during SSR, then keep it live — the Vue half of PLAN4's reactive-loader
25
+ * handoff.
26
+ *
27
+ * The returned `ref` is seeded **synchronously** from `preloaded.value`, so the
28
+ * very first read (during hydration) shows the server value: no loading flash,
29
+ * no hydration mismatch. After seeding it opens a WebSocket subscription on the
30
+ * same `(functionPath, args, shardKey)` the SSR loader used, so every later
31
+ * server delta updates the ref exactly like `useQuery`.
32
+ *
33
+ * The subscription tears down with the surrounding effect scope (component
34
+ * unmount or `effectScope().stop()`), inherited from `subscribeToQuery`.
35
+ */
36
36
  declare const hydratePreloaded: <T>(preloaded: Preloaded<T>) => Ref<T | undefined>;
37
37
  /**
38
- * Injection key carrying the {@link LunoraClient} down the component tree.
39
- * Exported so advanced consumers can inject it by hand; most apps use
40
- * {@link createLunora} or {@link provideLunora}.
41
- */
38
+ * Injection key carrying the {@link LunoraClient} down the component tree.
39
+ * Exported so advanced consumers can inject it by hand; most apps use
40
+ * {@link createLunora} or {@link provideLunora}.
41
+ */
42
42
  declare const LUNORA_INJECTION_KEY: InjectionKey<LunoraClient>;
43
43
  /**
44
- * Vue plugin form: `app.use(createLunora(client))`. Mirrors the React
45
- * `LunoraProvider` — establishes the single app-wide client every composable
46
- * resolves through {@link useLunora}.
47
- *
48
- * The client is framework-neutral (`@lunora/client`): it owns the WebSocket
49
- * transport, subscription registry, offline queue, and delta-merge. This plugin
50
- * only wires it into Vue's `provide`/`inject` graph (read it with
51
- * {@link useLunora}); it adds no React, no store, and no extra reactivity layer.
52
- */
44
+ * Vue plugin form: `app.use(createLunora(client))`. Mirrors the React
45
+ * `LunoraProvider` — establishes the single app-wide client every composable
46
+ * resolves through {@link useLunora}.
47
+ *
48
+ * The client is framework-neutral (`@lunora/client`): it owns the WebSocket
49
+ * transport, subscription registry, offline queue, and delta-merge. This plugin
50
+ * only wires it into Vue's `provide`/`inject` graph (read it with
51
+ * {@link useLunora}); it adds no React, no store, and no extra reactivity layer.
52
+ */
53
53
  declare const createLunora: (client: LunoraClient) => {
54
54
  install: (app: App) => void;
55
55
  };
56
56
  /**
57
- * Composition-API form: call inside a parent component's `setup()` to provide
58
- * the client to its subtree. The counterpart to `app.use(createLunora(client))`
59
- * when you'd rather scope the client to a subtree than the whole app. Must run
60
- * synchronously inside `setup()` (Vue's `provide` constraint).
61
- */
57
+ * Composition-API form: call inside a parent component's `setup()` to provide
58
+ * the client to its subtree. The counterpart to `app.use(createLunora(client))`
59
+ * when you'd rather scope the client to a subtree than the whole app. Must run
60
+ * synchronously inside `setup()` (Vue's `provide` constraint).
61
+ */
62
62
  declare const provideLunora: (client: LunoraClient) => void;
63
63
  /**
64
- * Read the {@link LunoraClient} from the nearest provider — the Vue counterpart
65
- * to `@lunora/react`/`@lunora/solid`'s `useLunora`. Throws with a clear message
66
- * when called outside a `createLunora`/`provideLunora` scope so the failure
67
- * points at the missing provider rather than a later `undefined` deref.
68
- */
64
+ * Read the {@link LunoraClient} from the nearest provider — the Vue counterpart
65
+ * to `@lunora/react`/`@lunora/solid`'s `useLunora`. Throws with a clear message
66
+ * when called outside a `createLunora`/`provideLunora` scope so the failure
67
+ * points at the missing provider rather than a later `undefined` deref.
68
+ */
69
69
  declare const useLunora: () => LunoraClient;
70
70
  /** Options shared by the live-query composables. */
71
71
  interface UseQueryOptions {
72
72
  /** Route to a specific shard when the target function is `.shardBy(...)`-partitioned. */
73
73
  shardKey?: string;
74
74
  }
75
+ /**
76
+ * The reactive handle returned by {@link useAction} — the Vue counterpart to
77
+ * React's `useAction`, re-expressed with refs. The surface is identical across
78
+ * the Lunora adapters (`@lunora/solid`, `/svelte`): `data`/`error`/`pending`
79
+ * are refs you read in a template, and `call` is an awaitable that resolves with
80
+ * the server value (or rejects).
81
+ */
82
+ interface ActionHandle<F extends FunctionReference> {
83
+ /** Invoke the action. Resolves with the server value; rejects on failure. */
84
+ call: (args: ArgsOf<F>, options?: ActionCallOptions) => Promise<ReturnOf<F>>;
85
+ /** The latest invocation's resolved value, or `undefined` before the first success. */
86
+ data: Ref<ReturnOf<F> | undefined>;
87
+ /** The latest invocation's error, or `undefined`. */
88
+ error: Ref<Error | undefined>;
89
+ /** `true` while ANY invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
90
+ pending: Ref<boolean>;
91
+ /** Clear the latest `data`/`error` back to idle. */
92
+ reset: () => void;
93
+ }
94
+ /**
95
+ * Returns a reactive {@link ActionHandle} for the given action reference — the
96
+ * Vue equivalent of React's `useAction`.
97
+ *
98
+ * Actions were the one procedure kind with no adapter hook: `useQuery` and
99
+ * `useMutation` shipped in every adapter and nothing covered actions, so each
100
+ * app re-derived the same pending/error wrapper by hand.
101
+ *
102
+ * **Narrower than `useMutation` on purpose:** there are no `optimistic` /
103
+ * `optimisticUpdate` call options. An optimistic update patches the subscription
104
+ * cache on the assumption a write will land; an action is not a write — it runs
105
+ * in the Worker, may call a third party, and has no declared effect on any
106
+ * query. Offering the option would imply a rollback guarantee nothing can
107
+ * honour.
108
+ *
109
+ * `pending` is ref-counted across overlapping invocations of THIS handle, so it
110
+ * flips back to `false` only once every concurrent call has settled. That
111
+ * orchestration is the shared `createCallRunner` from `@lunora/client`; only the
112
+ * refs are adapter-specific.
113
+ *
114
+ * `data`/`error` follow the adapter-wide contract: both track the LATEST
115
+ * invocation (an earlier call settling later cannot clobber a newer one), a
116
+ * success clears `error`, and a failure leaves the previous `data` in place so a
117
+ * transient error does not blank the view. `reset()` clears both; it does not
118
+ * cancel an in-flight call, whose result still lands.
119
+ */
120
+ declare const useAction: <F extends FunctionReference>(function_: F) => ActionHandle<F>;
121
+ /**
122
+ * The lifecycle status stored on an agent thread. Client-safe mirror of
123
+ * `@lunora/agent`'s `AgentThreadStatus` — re-declared here (rather than imported)
124
+ * so this Vue entry never pulls in the server-only `@lunora/agent` module graph
125
+ * (the adapter stays Vue + `@lunora/client` only). Keep in sync with
126
+ * `packages/agent/src/types.ts`.
127
+ */
128
+ type AgentThreadStatus = "awaiting_input" | "cancelled" | "error" | "idle" | "running";
129
+ /**
130
+ * The live thread record surfaced by the `agents:agentThread` query. A structural
131
+ * subset of the persisted thread row — every field beyond `status` is optional so
132
+ * the shape stays forgiving as the server schema grows. Keep in sync with the
133
+ * `agent_threads` table in `packages/agent/src/component.ts`.
134
+ */
135
+ interface AgentThreadRecord {
136
+ createdAt?: number;
137
+ /** The failure message when `status === "error"`. */
138
+ error?: string;
139
+ /** The workflow instance id of the in-flight run — the handle `cancel` targets. */
140
+ instanceId?: string;
141
+ messageCount?: number;
142
+ /** The verified thread owner, when the run was started with one. */
143
+ owner?: string;
144
+ status: AgentThreadStatus;
145
+ title?: string;
146
+ updatedAt?: number;
147
+ }
148
+ /**
149
+ * The `agents.agentThread` reference the composable subscribes to for live thread
150
+ * state (status + the in-flight `instanceId`). A structural subset of the
151
+ * generated `api.agents` surface, so the whole generated `api` object is
152
+ * assignable.
153
+ */
154
+ interface UseAgentApi {
155
+ agents: {
156
+ agentThread: FunctionReference<"query", {
157
+ key: string;
158
+ }, Record<string, unknown> | undefined>;
159
+ };
160
+ }
161
+ interface UseAgentOptions {
162
+ /** The generated `api` — its `agents.agentThread` query drives live thread state. */
163
+ api: UseAgentApi;
164
+ /**
165
+ * Optional app mutation over the agent's cancel path
166
+ * (`ctx.agents.<name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
167
+ * When omitted (or no run is in flight) {@link UseAgentResult.cancel} is a
168
+ * no-op.
169
+ */
170
+ cancel?: FunctionReference<"mutation">;
171
+ /**
172
+ * The app mutation that starts (or continues) a run — a thin wrapper over
173
+ * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
174
+ * {@link UseAgentOptions.runArgs} and the per-call args.
175
+ */
176
+ run: FunctionReference<"mutation">;
177
+ /** Extra args merged into every `run` call (e.g. an `owner` or `title`). */
178
+ runArgs?: Record<string, unknown>;
179
+ /** The thread to observe and drive — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
180
+ threadKey: MaybeRefOrGetter<string>;
181
+ }
182
+ interface UseAgentResult {
183
+ /**
184
+ * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
185
+ * no-op when no `cancel` mutation was supplied or no run is in flight.
186
+ */
187
+ cancel: () => Promise<void>;
188
+ /** `true` while a `run` invocation is in flight. */
189
+ pending: Readonly<Ref<boolean>>;
190
+ /** Start (or continue) a run with a user message; extra args merge over `runArgs`. */
191
+ run: (input: string, args?: Record<string, unknown>) => Promise<void>;
192
+ /** The live thread status, or `undefined` before the thread exists. */
193
+ status: ComputedRef<AgentThreadStatus | undefined>;
194
+ /** The live thread record (status, `instanceId`, …), or `undefined` before it exists. */
195
+ thread: ComputedRef<AgentThreadRecord | undefined>;
196
+ }
197
+ /**
198
+ * A thin agent handle: live thread `status` plus `run` / `cancel`, without the
199
+ * chat message surface. Composes `useSubscription(api.agents.agentThread)` for
200
+ * live state and `useMutation` for the run/cancel writes — the Vue counterpart to
201
+ * React's `useAgent`, re-expressed with refs. For the full conversation surface
202
+ * (durable history + streaming + approvals) use `useAgentChat`.
203
+ *
204
+ * `run` and `cancel` stay generic over the app-defined mutations that wrap
205
+ * `ctx.agents.<name>.run` / `.cancel`, so the composable hard-codes no function
206
+ * names beyond the `agents:*` surface. `threadKey` may be reactive — a changing
207
+ * key re-subscribes to the new thread.
208
+ */
209
+ declare const useAgent: (options: UseAgentOptions) => UseAgentResult;
210
+ /**
211
+ * One persisted (or optimistic) thread message, as `agents:agentMessages`
212
+ * surfaces it. Client-safe mirror of `@lunora/agent`'s `AgentMessageRow` —
213
+ * re-declared here (rather than imported) so this Vue entry never pulls in the
214
+ * server-only `@lunora/agent` module graph. Keep in sync with the
215
+ * `agent_messages` table in `packages/agent/src/component.ts`.
216
+ */
217
+ interface AgentChatMessage {
218
+ content: string;
219
+ createdAt?: number;
220
+ /**
221
+ * `true` for a client-side optimistic user message not yet acknowledged by
222
+ * the server. Cleared once the durable history carries the matching user turn.
223
+ */
224
+ optimistic?: boolean;
225
+ role: "assistant" | "system" | "tool" | "user";
226
+ seq: number;
227
+ /** Approval lifecycle marker on a human-in-the-loop tool message. */
228
+ status?: "approved" | "awaiting_approval" | "rejected";
229
+ toolCallId?: string;
230
+ toolCalls?: ReadonlyArray<{
231
+ id: string;
232
+ input: unknown;
233
+ name: string;
234
+ }>;
235
+ toolName?: string;
236
+ }
237
+ /**
238
+ * A live token delta streamed while a turn is generating. Client-safe mirror of
239
+ * `@lunora/agent`'s `AgentTokenDelta`. Ephemeral — deltas feed
240
+ * {@link UseAgentChatResult.streamingText} live and are never replayed; the
241
+ * persisted assistant message stays the single source of truth.
242
+ */
243
+ interface AgentTokenDelta {
244
+ /** Discriminates the token arm of {@link AgentLiveEvent}; unset on the wire (token is the default). */
245
+ kind?: "token";
246
+ /** The incremental text chunk the model just produced. */
247
+ text: string;
248
+ /** The thread this delta belongs to. */
249
+ threadKey: string;
250
+ /** The zero-based index of the turn producing the delta. */
251
+ turn: number;
252
+ }
253
+ /**
254
+ * A live tool-progress event streamed via `ctx.reportProgress(...)`. Client-safe
255
+ * mirror of `@lunora/agent`'s `AgentProgressEvent`. Ephemeral and `toolCallId`-keyed;
256
+ * surfaced by `useAgentToolEvents`, ignored by {@link UseAgentChatResult.streamingText}.
257
+ */
258
+ interface AgentProgressEvent {
259
+ /** The arbitrary, JSON-serializable payload the tool reported. */
260
+ data: unknown;
261
+ /** Discriminates the progress arm of {@link AgentLiveEvent}. */
262
+ kind: "progress";
263
+ /** The thread this event belongs to. */
264
+ threadKey: string;
265
+ /** The tool call this progress belongs to. */
266
+ toolCallId: string;
267
+ }
268
+ /**
269
+ * A single event on the agent's live-only channel — a streamed token delta or a
270
+ * tool progress event. Client-safe mirror of `@lunora/agent`'s `AgentLiveEvent`.
271
+ * Discriminate on `kind` (`"progress"` for the progress arm; token deltas leave
272
+ * it unset).
273
+ */
274
+ type AgentLiveEvent = AgentProgressEvent | AgentTokenDelta;
275
+ /** The `agents:agentMessages` reference — live durable thread history. */
276
+ type AgentMessagesReference$1 = FunctionReference<"query", {
277
+ key: string;
278
+ limit?: number;
279
+ }, ReadonlyArray<Record<string, unknown>>>;
280
+ /** The `agents:agentResolveApproval` reference — resolves a human-in-the-loop tool approval. */
281
+ type AgentApprovalReference = FunctionReference<"mutation", {
282
+ decision: "approve" | "reject";
283
+ instanceId: string;
284
+ note?: string;
285
+ threadKey: string;
286
+ toolCallId: string;
287
+ }, {
288
+ resolved: boolean;
289
+ }>;
290
+ /** The `agents:agentThread` reference — live thread status + in-flight `instanceId`. */
291
+ type AgentThreadReference = FunctionReference<"query", {
292
+ key: string;
293
+ }, Record<string, unknown> | undefined>;
294
+ /**
295
+ * An app stream reference that tees the agent's in-flight live events, keyed by
296
+ * thread. Carries token deltas and — since `ctx.reportProgress` rides the same
297
+ * sink — tool progress events; this composable consumes only the token arm.
298
+ */
299
+ type AgentTokenStreamReference = FunctionReference<"stream", {
300
+ key: string;
301
+ }, AgentLiveEvent>;
302
+ /**
303
+ * The `agents.*` reference surface the chat composable reads. A structural subset
304
+ * of the generated `api.agents`, so the whole generated `api` object is
305
+ * assignable.
306
+ */
307
+ interface UseAgentChatApi {
308
+ agents: {
309
+ agentMessages: AgentMessagesReference$1;
310
+ agentResolveApproval: AgentApprovalReference;
311
+ agentThread: AgentThreadReference;
312
+ };
313
+ }
314
+ interface UseAgentChatOptions {
315
+ /** The generated `api` — its `agents.*` surface provides history, thread state, and approval resolution. */
316
+ api: UseAgentChatApi;
317
+ /**
318
+ * Optional app mutation over the agent's cancel path
319
+ * (`ctx.agents.<name>.cancel(id)`). Called with `{ instanceId, threadKey }`.
320
+ * When omitted (or no run is in flight) {@link UseAgentChatResult.cancel} is a
321
+ * no-op.
322
+ */
323
+ cancel?: FunctionReference<"mutation">;
324
+ /** History depth forwarded to `agents:agentMessages`. */
325
+ limit?: number;
326
+ /**
327
+ * The app mutation that starts (or continues) a run — a thin wrapper over
328
+ * `ctx.agents.<name>.run(...)`. Called with `{ threadKey, input }` merged with
329
+ * {@link UseAgentChatOptions.sendArgs} and the per-call args.
330
+ */
331
+ send: FunctionReference<"mutation">;
332
+ /** Extra args merged into every `send` call (e.g. an `owner` or `title`). */
333
+ sendArgs?: Record<string, unknown>;
334
+ /**
335
+ * Optional live token-delta stream — an app stream function that tees the
336
+ * agent's in-flight deltas. When omitted {@link UseAgentChatResult.streamingText}
337
+ * stays empty and the UI updates message-by-message from durable history.
338
+ */
339
+ stream?: AgentTokenStreamReference;
340
+ /** The thread to observe and continue — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
341
+ threadKey: MaybeRefOrGetter<string>;
342
+ }
343
+ interface UseAgentChatResult {
344
+ /** Approve a paused human-in-the-loop tool call (optionally with a note). */
345
+ approve: (toolCallId: string, note?: string) => Promise<void>;
346
+ /**
347
+ * Terminate the in-flight run and mark its thread `"cancelled"`. Resolves as a
348
+ * no-op when no `cancel` mutation was supplied or no run is in flight.
349
+ */
350
+ cancel: () => Promise<void>;
351
+ /** Durable thread history (oldest first) plus any un-acknowledged optimistic user turns. */
352
+ messages: ComputedRef<ReadonlyArray<AgentChatMessage>>;
353
+ /** Reject a paused human-in-the-loop tool call (optionally with a reason). */
354
+ reject: (toolCallId: string, note?: string) => Promise<void>;
355
+ /** Start (or continue) a run with a user message; extra args merge over `sendArgs`. Appends an optimistic user turn. */
356
+ send: (input: string, args?: Record<string, unknown>) => Promise<void>;
357
+ /** The live thread status, or `undefined` before the thread exists. */
358
+ status: ComputedRef<AgentThreadStatus | undefined>;
359
+ /** The in-flight turn's streamed text — live-only, empty once the turn persists to `messages`. */
360
+ streamingText: ComputedRef<string>;
361
+ }
362
+ /**
363
+ * A first-class agent chat surface: live durable history + in-flight token
364
+ * streaming + the send / approve / reject / cancel writes, keyed by `threadKey` —
365
+ * the Vue counterpart to React's `useAgentChat`, re-expressed with refs.
366
+ *
367
+ * It composes the existing primitives rather than adding transport:
368
+ * `useSubscription(api.agents.agentMessages)` for durable history,
369
+ * `useSubscription(api.agents.agentThread)` for live status + the in-flight
370
+ * `instanceId`, {@link useStream} over an app token stream for in-flight deltas,
371
+ * and `useMutation` for the writes (`api.agents.agentResolveApproval` for
372
+ * approvals; app-defined wrappers for `send`/`cancel`). Only the `agents:*`
373
+ * surface is hard-coded — `send`/`cancel`/`stream` stay generic references.
374
+ *
375
+ * A `send` optimistically appends the user turn so it renders immediately; the
376
+ * optimistic row clears once the durable history carries the acknowledged turn.
377
+ * `streamingText` is live-only: it holds the current turn's streamed text and
378
+ * empties as soon as that turn's assistant message lands in `messages` (the
379
+ * persisted message is the source of truth), consistent with the loop's
380
+ * replay-safe, live-only delta design.
381
+ */
382
+ declare const useAgentChat: (options: UseAgentChatOptions) => UseAgentChatResult;
383
+ /**
384
+ * The `agents.agentState` reference the composable subscribes to for the thread's
385
+ * live synced state. A structural subset of the generated `api.agents` surface
386
+ * (like `UseAgentApi` for `agentThread`), so the whole generated `api` object is
387
+ * assignable. Client-safe: no `@lunora/agent` import — the per-agent state type is
388
+ * mirrored by the composable's generic `T`, since codegen pins the reference
389
+ * return as an optional record (it never evaluates agent config).
390
+ */
391
+ interface UseAgentStateApi {
392
+ agents: {
393
+ agentState: FunctionReference<"query", {
394
+ key: string;
395
+ }, Record<string, unknown> | undefined>;
396
+ };
397
+ }
398
+ interface UseAgentStateOptions {
399
+ /** The generated `api` — its `agents.agentState` query drives live thread state. */
400
+ api: UseAgentStateApi;
401
+ /** The thread whose synced state to observe — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
402
+ threadKey: MaybeRefOrGetter<string>;
403
+ }
404
+ interface UseAgentStateResult<T> {
405
+ /** The subscription error, if the live channel reported one. */
406
+ error: Ref<Error | undefined>;
407
+ /** The live synced state, or `undefined` before it is seeded/first pushed. */
408
+ state: ComputedRef<T | undefined>;
409
+ }
410
+ /**
411
+ * Subscribe to an agent thread's synced state — the `setState`-style value a tool
412
+ * writes with `ctx.setState(...)`, seeded by `defineAgent({ initialState })`. A
413
+ * thin wrapper over `useSubscription(api.agents.agentState, { key })`: the server
414
+ * pushes a fresh frame whenever the state changes (the dedicated query's
415
+ * per-socket JSON memo suppresses no-op pushes on unrelated thread writes), so
416
+ * `state` updates only on a real `setState`. The Vue counterpart to React's
417
+ * `useAgentState`, re-expressed with refs.
418
+ *
419
+ * Generic over the app's state shape (`useAgentState` with a `SupportState` type
420
+ * argument, itself a record) — the reference is typed as an optional record
421
+ * because codegen cannot see the per-agent state type; the generic casts to `T`.
422
+ * The `extends` bound (not
423
+ * a bare unbounded type parameter) is required: this `.ts` file is parsed
424
+ * JSX-aware by the bundler, where an unbounded type-param arrow is ambiguous with
425
+ * a JSX element.
426
+ */
427
+ declare const useAgentState: <T extends Record<string, unknown> = Record<string, unknown>>(options: UseAgentStateOptions) => UseAgentStateResult<T>;
428
+ /** The `agents:agentMessages` reference — live durable thread history. */
429
+ type AgentMessagesReference = FunctionReference<"query", {
430
+ key: string;
431
+ limit?: number;
432
+ }, ReadonlyArray<Record<string, unknown>>>;
433
+ /**
434
+ * An app stream reference that tees the agent's in-flight live events, keyed by
435
+ * thread. Carries token deltas and tool progress events; this composable consumes
436
+ * only the progress arm (`kind === "progress"`).
437
+ */
438
+ type AgentLiveStreamReference = FunctionReference<"stream", {
439
+ key: string;
440
+ }, AgentLiveEvent>;
441
+ /**
442
+ * The `agents.*` reference surface the tool-events composable reads. A structural
443
+ * subset of the generated `api.agents`, so the whole generated `api` object is
444
+ * assignable.
445
+ */
446
+ interface UseAgentToolEventsApi {
447
+ agents: {
448
+ agentMessages: AgentMessagesReference;
449
+ };
450
+ }
451
+ interface UseAgentToolEventsOptions {
452
+ /** The generated `api` — its `agents.agentMessages` query provides the durable tool lifecycle. */
453
+ api: UseAgentToolEventsApi;
454
+ /** History depth forwarded to `agents:agentMessages`. */
455
+ limit?: number;
456
+ /**
457
+ * Optional live event stream — the same app stream function `useAgentChat`
458
+ * uses. When supplied, ephemeral `ctx.reportProgress(...)` events for the
459
+ * thread are surfaced as `{ type: "progress" }` entries; when omitted only the
460
+ * durable lifecycle (call / result / awaiting-approval) is returned.
461
+ */
462
+ stream?: AgentLiveStreamReference;
463
+ /** The thread whose tool activity to observe — may be a plain value, `ref`, or getter (a reactive source re-subscribes). */
464
+ threadKey: MaybeRefOrGetter<string>;
465
+ }
466
+ /**
467
+ * A single tool-lifecycle event for a thread. The durable arms
468
+ * (`call`/`result`/`awaiting-approval`) are derived from `agents:agentMessages`
469
+ * and carry the persisted `seq`; the ephemeral `progress` arm comes live off the
470
+ * stream and has no `seq`. Discriminate on `type`.
471
+ */
472
+ type AgentToolEvent = {
473
+ data: unknown;
474
+ toolCallId: string;
475
+ type: "progress";
476
+ } | {
477
+ input: unknown;
478
+ seq: number;
479
+ toolCallId: string;
480
+ toolName: string;
481
+ type: "call";
482
+ } | {
483
+ output: string;
484
+ seq: number;
485
+ status?: "approved" | "rejected";
486
+ toolCallId?: string;
487
+ toolName?: string;
488
+ type: "result";
489
+ } | {
490
+ seq: number;
491
+ toolCallId?: string;
492
+ toolName?: string;
493
+ type: "awaiting-approval";
494
+ };
495
+ interface UseAgentToolEventsResult {
496
+ /**
497
+ * The thread's tool events: the durable lifecycle (oldest first, by `seq`)
498
+ * followed by any in-flight ephemeral progress events, recomputed from the live
499
+ * subscription + stream. Treat as derived, not identity-stable.
500
+ */
501
+ events: ComputedRef<ReadonlyArray<AgentToolEvent>>;
502
+ }
503
+ /**
504
+ * A focused view of a thread's tool activity: tool calls, their results,
505
+ * human-in-the-loop approval pauses, and live `ctx.reportProgress(...)` events —
506
+ * without the full chat message surface. The Vue counterpart to React's
507
+ * `useAgentToolEvents`, re-expressed as a `computed`.
508
+ *
509
+ * It composes the existing primitives rather than adding transport:
510
+ * `useSubscription(api.agents.agentMessages)` for the durable lifecycle and
511
+ * {@link useStream} over the optional app event stream for ephemeral progress.
512
+ * Progress events are live-only (the durable path never emits them): they ride
513
+ * the same sink as token deltas and are surfaced here, correlated to their tool
514
+ * call by `toolCallId`. For the conversational surface (messages + streaming text
515
+ * + approvals) use `useAgentChat`; this composable is the tool-observability slice.
516
+ */
517
+ declare const useAgentToolEvents: (options: UseAgentToolEventsOptions) => UseAgentToolEventsResult;
75
518
  interface UseAuthResult {
76
519
  setToken: (token: string | null) => void;
77
520
  token: DeepReadonly<Ref<string | null>>;
78
521
  user: DeepReadonly<Ref<User | null>>;
79
522
  }
80
523
  /**
81
- * Token + identity plumbing for Vue. `token` is a readonly ref tracking the
82
- * client's auth token; `user` is a readonly ref resolved from `getCurrentUser()`
83
- * whenever the token changes. `setToken(jwt)` after sign-in makes subsequent
84
- * RPC calls carry the `Authorization` header.
85
- *
86
- * Multiple `useAuth` instances within the same effect scope share a single
87
- * per-client identity store (from `@lunora/client/auth`) — a `setToken` from
88
- * one component re-renders every watcher with the freshly-resolved user.
89
- */
524
+ * Token + identity plumbing for Vue. `token` is a readonly ref tracking the
525
+ * client's auth token; `user` is a readonly ref resolved from `getCurrentUser()`
526
+ * whenever the token changes. `setToken(jwt)` after sign-in makes subsequent
527
+ * RPC calls carry the `Authorization` header.
528
+ *
529
+ * Multiple `useAuth` instances within the same effect scope share a single
530
+ * per-client identity store (from `@lunora/client/auth`) — a `setToken` from
531
+ * one component re-renders every watcher with the freshly-resolved user.
532
+ */
90
533
  declare const useAuth: () => UseAuthResult;
91
534
  /**
92
- * Reactive view of the client's aggregate live-socket status across all shard
93
- * connections, exposed as a read-only `ref`. The value transitions through
94
- * `idle` → `connecting` → `connected` → `offline` as sockets open and drop —
95
- * use it to drive a connection indicator so an operator can tell a healthy live
96
- * channel from a silently-dropped one. The Vue-idiomatic equivalent of
97
- * `@lunora/react`'s `useConnectionStatus`.
98
- *
99
- * Teardown is wired to the active effect scope (`onScopeDispose`), so the
100
- * status listener is released on component unmount (or `effectScope().stop()`).
101
- * Call inside `setup()` / an active effect scope.
102
- */
535
+ * Reactive view of the client's aggregate live-socket status across all shard
536
+ * connections, exposed as a read-only `ref`. The value transitions through
537
+ * `idle` → `connecting` → `connected` → `offline` as sockets open and drop —
538
+ * use it to drive a connection indicator so an operator can tell a healthy live
539
+ * channel from a silently-dropped one. The Vue-idiomatic equivalent of
540
+ * `@lunora/react`'s `useConnectionStatus`.
541
+ *
542
+ * Teardown is wired to the active effect scope (`onScopeDispose`), so the
543
+ * status listener is released on component unmount (or `effectScope().stop()`).
544
+ * Call inside `setup()` / an active effect scope.
545
+ */
103
546
  declare const useConnectionStatus: () => Readonly<Ref<ConnectionStatus>>;
547
+ /** A targeting context merged on top of the app's default (`defineFlags({ identify })`). */
548
+ type FlagContext = Record<string, unknown>;
549
+ /** The value kinds a flag resolves to — OpenFeature's boolean / number / string / structured (JSON) flags. */
550
+ type FlagValue = boolean | number | string | {
551
+ [key: string]: unknown;
552
+ } | unknown[] | null;
553
+ /**
554
+ * Subscribe to a single feature flag, live over Lunora's WebSocket.
555
+ *
556
+ * The returned `ref` holds `defaultValue` until the first evaluation lands, then
557
+ * the server's resolved value — re-pushed whenever the provider re-evaluates
558
+ * (e.g. a flag is toggled in Cloudflare Flagship). The flag's kind is inferred
559
+ * from `defaultValue`'s runtime type, so `useFlag("dark", false)` reads a boolean
560
+ * and `useFlag("hero", "control")` a string.
561
+ *
562
+ * `key` and `context` may be plain values, `ref`s, or getters: passing a reactive
563
+ * source makes the subscription reactive — when it changes the old subscription
564
+ * is torn down and a fresh one opens. `context` supplies a per-call targeting
565
+ * context merged on top of the app's default `identify` targeting key.
566
+ *
567
+ * Evaluation runs through whatever OpenFeature provider the app wired in
568
+ * `lunora/flags.ts`; the read never throws — a provider error resolves the
569
+ * default (the same fail-open contract as server-side `ctx.flags`). Call inside
570
+ * `setup()` (or any active effect scope); the subscription tears down on unmount.
571
+ */
572
+ declare const useFlag: <T extends FlagValue>(key: MaybeRefOrGetter<string>, defaultValue: T, context?: MaybeRefOrGetter<FlagContext | undefined>) => Readonly<Ref<T>>;
104
573
  /**
105
- * The reactive handle returned by {@link useMutation} — the Vue counterpart to
106
- * React's `useMutation`, re-expressed with refs. The surface is identical across
107
- * the Lunora adapters (`@lunora/solid`, `/svelte`): `data`/`error`/`pending` are
108
- * refs you read in a template, `mutate` is an awaitable that resolves with the
109
- * server value (or rejects). Per-call `optimistic` / `optimisticUpdate` options
110
- * pass straight through to `client.mutation`.
111
- */
574
+ * Subscribe to several feature flags at once, live over Lunora's WebSocket.
575
+ *
576
+ * Pass a record of `key → defaultValue`; each flag's kind is inferred from its
577
+ * default, and the returned `ref` holds the same-shaped record with resolved
578
+ * values (the defaults until each evaluation lands). A single `context` applies
579
+ * to every flag and may be reactive. This is the batched form of {@link useFlag}
580
+ * — one watcher manages one subscription per key.
581
+ */
582
+ declare const useFlags: <T extends Record<string, FlagValue>>(flags: T, context?: MaybeRefOrGetter<FlagContext | undefined>) => Readonly<Ref<T>>;
583
+ /**
584
+ * The reactive handle returned by {@link useMutation} — the Vue counterpart to
585
+ * React's `useMutation`, re-expressed with refs. The surface is identical across
586
+ * the Lunora adapters (`@lunora/solid`, `/svelte`): `data`/`error`/`pending` are
587
+ * refs you read in a template, `mutate` is an awaitable that resolves with the
588
+ * server value (or rejects). Per-call `optimistic` / `optimisticUpdate` options
589
+ * pass straight through to `client.mutation`.
590
+ */
112
591
  interface MutationHandle<F extends FunctionReference> {
113
592
  /** The latest invocation's resolved value, or `undefined` before the first success. */
114
593
  data: Ref<ReturnOf<F> | undefined>;
@@ -122,20 +601,57 @@ interface MutationHandle<F extends FunctionReference> {
122
601
  reset: () => void;
123
602
  }
124
603
  /**
125
- * Returns a reactive {@link MutationHandle} for the given mutation reference —
126
- * the Vue equivalent of React's `useMutation`.
127
- *
128
- * Optimistic updates stay client-owned: the `optimistic` / `optimisticUpdate`
129
- * call options pass straight through to `client.mutation`, which applies and
130
- * rolls them back against the Lunora subscription cache (Convex parity).
131
- *
132
- * `pending` is ref-counted across overlapping invocations of THIS handle, so it
133
- * flips back to `false` only once every concurrent call has settled. The
134
- * ref-counted pending + error-normalize orchestration is the shared
135
- * `createMutationRunner` from `@lunora/client`; only the refs are
136
- * adapter-specific.
137
- */
604
+ * Returns a reactive {@link MutationHandle} for the given mutation reference —
605
+ * the Vue equivalent of React's `useMutation`.
606
+ *
607
+ * Optimistic updates stay client-owned: the `optimistic` / `optimisticUpdate`
608
+ * call options pass straight through to `client.mutation`, which applies and
609
+ * rolls them back against the Lunora subscription cache (Convex parity).
610
+ *
611
+ * `pending` is ref-counted across overlapping invocations of THIS handle, so it
612
+ * flips back to `false` only once every concurrent call has settled. The
613
+ * ref-counted pending + error-normalize orchestration is the shared
614
+ * `createCallRunner` from `@lunora/client`; only the refs are adapter-specific.
615
+ *
616
+ * `data`/`error` follow the adapter-wide contract: both track the LATEST
617
+ * invocation (an earlier call settling later cannot clobber a newer one), a
618
+ * success clears `error`, and a failure leaves the previous `data` in place.
619
+ * `reset()` clears both; it does not cancel an in-flight call.
620
+ */
138
621
  declare const useMutation: <F extends FunctionReference>(function_: F) => MutationHandle<F>;
622
+ /**
623
+ * The reactive handle returned by {@link useMutator} — the Vue counterpart to
624
+ * `@lunora/react`'s `useMutator`, re-expressed with refs. The surface is
625
+ * identical across the Lunora adapters (`@lunora/solid`, `/svelte`):
626
+ * `error`/`isError`/`pending` are refs you read in a template and `mutate` is an
627
+ * awaitable that resolves once the write is persisted (or rejects).
628
+ */
629
+ interface MutatorHook<TArgs> {
630
+ /** The latest invocation's error, or `undefined`. */
631
+ error: Ref<Error | undefined>;
632
+ /** `true` when the latest invocation rejected. */
633
+ isError: ComputedRef<boolean>;
634
+ /** Run the mutator; resolves once the write is persisted, rejects on failure. */
635
+ mutate: (args: TArgs) => Promise<void>;
636
+ /** `true` while ANY invocation from this handle is in flight (ref-counted, so overlapping calls compose). */
637
+ pending: Ref<boolean>;
638
+ /** Clear the latest `error` back to idle. */
639
+ reset: () => void;
640
+ }
641
+ /**
642
+ * Ergonomic `{ mutate, pending, error, isError, reset }` wrapper over a bound
643
+ * custom-mutator handle from `@lunora/db`'s `bindMutators` — the Vue equivalent
644
+ * of `@lunora/react`'s `useMutator`. The optimistic overlay and
645
+ * server-authoritative push are owned by the bound handle (and TanStack DB's
646
+ * optimistic-transaction layer rebases pending overlays on every sync tick);
647
+ * this composable only surfaces reactive state for the in-flight/error
648
+ * lifecycle. Reads stay on the existing TanStack `useLiveQuery`; no new query
649
+ * composable is needed.
650
+ *
651
+ * `pending` is ref-counted across overlapping invocations of THIS handle, so it
652
+ * clears only once every concurrent call has settled.
653
+ */
654
+ declare const useMutator: <TArgs = Record<string, unknown>>(handle: MutatorHandle<TArgs>) => MutatorHook<TArgs>;
139
655
  /** The args a paginated query exposes minus the framework-supplied page cursor. */
140
656
  type PaginatedArgs<F extends FunctionReference> = Omit<ArgsOf<F>, "paginationOpts">;
141
657
  /** The element type of the `page` array a paginated query returns. */
@@ -157,24 +673,24 @@ interface UsePaginatedQueryResult<T> {
157
673
  status: Ref<PaginationStatus>;
158
674
  }
159
675
  /**
160
- * Subscribe to a reactively-paginated query and grow the feed page by page.
161
- *
162
- * The query function must accept a `paginationOpts: { numItems, cursor,
163
- * endCursor }` arg and return a `PaginationResult`. Pages are tracked as an
164
- * ordered list of stable boundary cursors; each loaded page is a live
165
- * subscription over a FIXED `(lower, upper]` range. Inserting or deleting a row
166
- * grows/shrinks the affected page without duplicating or skipping rows across
167
- * boundaries.
168
- *
169
- * `loadMore` appends the next page off the open-ended tail's `continueCursor`;
170
- * it is a no-op unless `status === "CanLoadMore"`. Background split/join
171
- * maintenance keeps page sizes near `initialNumItems` as edits accumulate.
172
- *
173
- * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
174
- * feed to its first page.
175
- *
176
- * Call inside `setup()` (or any active effect scope).
177
- */
676
+ * Subscribe to a reactively-paginated query and grow the feed page by page.
677
+ *
678
+ * The query function must accept a `paginationOpts: { numItems, cursor,
679
+ * endCursor }` arg and return a `PaginationResult`. Pages are tracked as an
680
+ * ordered list of stable boundary cursors; each loaded page is a live
681
+ * subscription over a FIXED `(lower, upper]` range. Inserting or deleting a row
682
+ * grows/shrinks the affected page without duplicating or skipping rows across
683
+ * boundaries.
684
+ *
685
+ * `loadMore` appends the next page off the open-ended tail's `continueCursor`;
686
+ * it is a no-op unless `status === "CanLoadMore"`. Background split/join
687
+ * maintenance keeps page sizes near `initialNumItems` as edits accumulate.
688
+ *
689
+ * Changing `fn`, the base `args`, `initialNumItems`, or `shardKey` resets the
690
+ * feed to its first page.
691
+ *
692
+ * Call inside `setup()` (or any active effect scope).
693
+ */
178
694
  declare const usePaginatedQuery: <F extends FunctionReference>(function_: F, args: MaybeRefOrGetter<"skip" | PaginatedArgs<F>>, options: UsePaginatedQueryOptions) => UsePaginatedQueryResult<PageItemOf<F>>;
179
695
  interface UseInfiniteQueryOptions {
180
696
  /** Page size for the first page (and the default for `fetchNextPage`). */
@@ -195,37 +711,37 @@ interface UseInfiniteQueryResult<T> {
195
711
  status: Ref<PaginationStatus>;
196
712
  }
197
713
  /**
198
- * Subscribe to a reactively-paginated query and expose its pages discretely.
199
- *
200
- * Shares `usePaginatedQuery`'s reactive-pagination engine but keeps each page
201
- * as its own inner array rather than flattening them, and adds the
202
- * TanStack-Query-style `fetchNextPage` / `hasNextPage` / `isFetchingNextPage`
203
- * shape.
204
- *
205
- * Call inside `setup()` (or any active effect scope).
206
- */
714
+ * Subscribe to a reactively-paginated query and expose its pages discretely.
715
+ *
716
+ * Shares `usePaginatedQuery`'s reactive-pagination engine but keeps each page
717
+ * as its own inner array rather than flattening them, and adds the
718
+ * TanStack-Query-style `fetchNextPage` / `hasNextPage` / `isFetchingNextPage`
719
+ * shape.
720
+ *
721
+ * Call inside `setup()` (or any active effect scope).
722
+ */
207
723
  declare const useInfiniteQuery: <F extends FunctionReference>(function_: F, args: MaybeRefOrGetter<"skip" | PaginatedArgs<F>>, options: UseInfiniteQueryOptions) => UseInfiniteQueryResult<PageItemOf<F>>;
208
724
  /**
209
- * `usePresence` — collaborative-awareness composable, the client half of the
210
- * `@lunora/server` `definePresence` preset.
211
- *
212
- * Drives the heartbeat mutation (on mount, interval, and tab re-focus) and
213
- * subscribes to the live `listPresent` query for the given room.
214
- *
215
- * Call inside `setup()` (or any active effect scope).
216
- */
217
- /**
218
- * A heartbeat mutation reference: takes `{ roomId, sessionId, data? }`.
219
- */
725
+ * `usePresence` — collaborative-awareness composable, the client half of the
726
+ * `@lunora/server` `definePresence` preset.
727
+ *
728
+ * Drives the heartbeat mutation (on mount, interval, and tab re-focus) and
729
+ * subscribes to the live `listPresent` query for the given room.
730
+ *
731
+ * Call inside `setup()` (or any active effect scope).
732
+ */
733
+ /**
734
+ * A heartbeat mutation reference: takes `{ roomId, sessionId, data? }`.
735
+ */
220
736
  type HeartbeatReference = FunctionReference<"mutation", {
221
737
  data?: Record<string, unknown>;
222
738
  roomId: string;
223
739
  sessionId: string;
224
740
  }>;
225
741
  /**
226
- * A listPresent query reference: takes `{ roomId }` and returns the array of
227
- * present members.
228
- */
742
+ * A listPresent query reference: takes `{ roomId }` and returns the array of
743
+ * present members.
744
+ */
229
745
  type ListPresentReference = FunctionReference<"query", {
230
746
  roomId: string;
231
747
  }>;
@@ -239,9 +755,9 @@ interface UsePresenceOptions<H extends HeartbeatReference, L extends ListPresent
239
755
  /** The `api.*` reference for the presence listPresent query. */
240
756
  listPresent: L;
241
757
  /**
242
- * Stable id for this presence row. Defaults to a fresh per-mount id.
243
- * Pass a user/connection id to control deduping across tabs.
244
- */
758
+ * Stable id for this presence row. Defaults to a fresh per-mount id.
759
+ * Pass a user/connection id to control deduping across tabs.
760
+ */
245
761
  sessionId?: string;
246
762
  /** Forwarded to the heartbeat mutation / listPresent subscription when sharding by room. */
247
763
  shardKey?: string;
@@ -256,51 +772,51 @@ interface UsePresenceResult<L extends ListPresentReference> {
256
772
  }
257
773
  declare const usePresence: <H extends HeartbeatReference, L extends ListPresentReference>(roomId: string, options: UsePresenceOptions<H, L>) => UsePresenceResult<L>;
258
774
  /**
259
- * Open a live subscription against `client` for FIXED args and stream its values
260
- * into a `ref`. The low-level primitive behind `hydratePreloaded` (whose args
261
- * come from an immutable `Preloaded` token and never change); {@link useQuery}
262
- * handles the reactive-args case separately.
263
- *
264
- * `client.subscribe` already dedupes by `(functionPath, args, shardKey)` and
265
- * replays the last value synchronously, so multiple consumers of the same query
266
- * ride one server-side registration. `seed` sets the ref's value synchronously
267
- * before the subscription attaches, so the first read shows the SSR value with
268
- * no loading flash.
269
- *
270
- * Teardown is wired to the active effect scope (`onScopeDispose`), so it fires
271
- * on component unmount or `effectScope().stop()`. Call it inside `setup()` / an
272
- * effect scope (as `hydratePreloaded` does); outside any scope there is nothing
273
- * to own the subscription, so it would leak until the process exits — the
274
- * `getCurrentScope` guard only avoids throwing, it does not auto-clean.
275
- */
775
+ * Open a live subscription against `client` for FIXED args and stream its values
776
+ * into a `ref`. The low-level primitive behind `hydratePreloaded` (whose args
777
+ * come from an immutable `Preloaded` token and never change); {@link useQuery}
778
+ * handles the reactive-args case separately.
779
+ *
780
+ * `client.subscribe` already dedupes by `(functionPath, args, shardKey)` and
781
+ * replays the last value synchronously, so multiple consumers of the same query
782
+ * ride one server-side registration. `seed` sets the ref's value synchronously
783
+ * before the subscription attaches, so the first read shows the SSR value with
784
+ * no loading flash.
785
+ *
786
+ * Teardown is wired to the active effect scope (`onScopeDispose`), so it fires
787
+ * on component unmount or `effectScope().stop()`. Call it inside `setup()` / an
788
+ * effect scope (as `hydratePreloaded` does); outside any scope there is nothing
789
+ * to own the subscription, so it would leak until the process exits — the
790
+ * `getCurrentScope` guard only avoids throwing, it does not auto-clean.
791
+ */
276
792
  declare const subscribeToQuery: <F extends FunctionReference, T = ReturnOf<F>>(client: LunoraClient, function_: F, args: ArgsOf<F>, options?: {
277
793
  seed?: T;
278
794
  shardKey?: string;
279
795
  }) => Ref<T | undefined>;
280
796
  /**
281
- * Subscribe to a server query and expose its latest value as a `ref`.
282
- *
283
- * The returned ref is `undefined` until the first server response lands, then
284
- * updates on every delta the server pushes — the Vue-idiomatic equivalent of
285
- * React's `useQuery`. `args` may be a plain value, a `ref`, or a getter: passing
286
- * a reactive source makes the subscription reactive — when the args change the
287
- * old subscription is torn down and a fresh one opens for the new args (matching
288
- * `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
289
- * `"skip"`) to short-circuit: no network call, no socket. The subscription tears
290
- * down automatically when the owning component unmounts (or the effect scope
291
- * stops).
292
- *
293
- * Call inside `setup()` (or any active effect scope). For SSR seeding with no
294
- * loading flash, use `hydratePreloaded` instead.
295
- */
797
+ * Subscribe to a server query and expose its latest value as a `ref`.
798
+ *
799
+ * The returned ref is `undefined` until the first server response lands, then
800
+ * updates on every delta the server pushes — the Vue-idiomatic equivalent of
801
+ * React's `useQuery`. `args` may be a plain value, a `ref`, or a getter: passing
802
+ * a reactive source makes the subscription reactive — when the args change the
803
+ * old subscription is torn down and a fresh one opens for the new args (matching
804
+ * `@lunora/react`/`@lunora/solid`). Pass `"skip"` (or a source resolving to
805
+ * `"skip"`) to short-circuit: no network call, no socket. The subscription tears
806
+ * down automatically when the owning component unmounts (or the effect scope
807
+ * stops).
808
+ *
809
+ * Call inside `setup()` (or any active effect scope). For SSR seeding with no
810
+ * loading flash, use `hydratePreloaded` instead.
811
+ */
296
812
  declare const useQuery: <F extends FunctionReference>(function_: F, args: MaybeRefOrGetter<ArgsOf<F> | "skip">, options?: UseQueryOptions) => Ref<ReturnOf<F> | undefined>;
297
813
  interface UseRateLimitOptions {
298
814
  /** Clock injection for tests. Defaults to `Date.now`. */
299
815
  now?: () => number;
300
816
  /**
301
- * Re-render cadence in milliseconds while throttled, so `retryAfter` ticks
302
- * down and `disabled` flips back automatically. Defaults to `1000`.
303
- */
817
+ * Re-render cadence in milliseconds while throttled, so `retryAfter` ticks
818
+ * down and `disabled` flips back automatically. Defaults to `1000`.
819
+ */
304
820
  tickMs?: number;
305
821
  }
306
822
  interface UseRateLimitResult {
@@ -318,31 +834,278 @@ interface UseRateLimitResult {
318
834
  retryAfter: ComputedRef<number>;
319
835
  }
320
836
  /**
321
- * Client-side mirror of a rate limit for instant UX — disable a button or show
322
- * a countdown without a round-trip. It runs the same token-bucket / fixed-window
323
- * math as `@lunora/ratelimit` on the server, so the prediction agrees with the
324
- * authoritative check; the server remains the source of truth.
325
- *
326
- * `config` accepts a plain object, a `ref`, or a getter (`MaybeRefOrGetter`).
327
- * When you pass a ref/getter it is tracked reactively — changing the config
328
- * re-derives `status` (and the `ok` / `disabled` / `retryAfter` views) on the
329
- * fly. A plain object keeps working unchanged; pass a stable reference (module
330
- * constant) so the reactive derived values stay settled.
331
- */
837
+ * Client-side mirror of a rate limit for instant UX — disable a button or show
838
+ * a countdown without a round-trip. It runs the same token-bucket / fixed-window
839
+ * math as `@lunora/ratelimit` on the server, so the prediction agrees with the
840
+ * authoritative check; the server remains the source of truth.
841
+ *
842
+ * `config` accepts a plain object, a `ref`, or a getter (`MaybeRefOrGetter`).
843
+ * When you pass a ref/getter it is tracked reactively — changing the config
844
+ * re-derives `status` (and the `ok` / `disabled` / `retryAfter` views) on the
845
+ * fly. A plain object keeps working unchanged; pass a stable reference (module
846
+ * constant) so the reactive derived values stay settled.
847
+ */
332
848
  declare const useRateLimit: (config: MaybeRefOrGetter<RateLimitConfig>, options?: UseRateLimitOptions) => UseRateLimitResult;
849
+ /** The lifecycle of a stream the composable is observing. */
850
+ type UseStreamStatus = "complete" | "error" | "idle" | "streaming";
851
+ interface UseStreamResult<T> {
852
+ /** Force-cancel the stream and resolve the iterator. Safe to call multiple times. */
853
+ cancel: () => void;
854
+ /** Chunks the server has pushed so far, in arrival order. */
855
+ chunks: Ref<ReadonlyArray<T>>;
856
+ error: Ref<Error | undefined>;
857
+ status: Ref<UseStreamStatus>;
858
+ }
859
+ interface UseStreamOptions {
860
+ /** Forwarded to `client.stream()` — caps the in-flight chunk buffer. */
861
+ maxBuffer?: number;
862
+ shardKey?: string;
863
+ }
864
+ /**
865
+ * Subscribe to a streaming query. Returns the chunks pushed so far plus a
866
+ * lifecycle status and a cancel function, all as refs. Changing the resolved
867
+ * `args` resets the stream — the previous iterator is cancelled and a fresh one
868
+ * opens with empty `chunks`.
869
+ *
870
+ * `args` may be a plain value, `ref`, or getter; resolving it to `"skip"` keeps
871
+ * the composable mounted without opening a stream (mirrors `useSubscription`).
872
+ * The Vue counterpart to React's `useStream`, re-expressed with refs.
873
+ */
874
+ declare const useStream: <F extends FunctionReference<"stream">>(function_: F, args: MaybeRefOrGetter<"skip" | ArgsOf<F>>, options?: UseStreamOptions) => UseStreamResult<ReturnOf<F>>;
333
875
  interface UseSubscriptionResult<T> {
334
876
  data: Ref<T | undefined>;
335
877
  error: Ref<Error | undefined>;
336
878
  }
337
879
  /**
338
- * Subscribe to a reactive server push stream. Returns `{ data, error }` refs
339
- * that update whenever the server emits a new value. Passing `"skip"` as `args`
340
- * (or a ref/getter that resolves to `"skip"`) tears down the subscription
341
- * without unmounting.
342
- *
343
- * Unlike `useQuery`, which tracks the full reactive cache, `useSubscription`
344
- * owns a single lightweight subscription and is suitable for ephemeral,
345
- * high-frequency streams.
346
- */
880
+ * Subscribe to a reactive server push stream. Returns `{ data, error }` refs
881
+ * that update whenever the server emits a new value. Passing `"skip"` as `args`
882
+ * (or a ref/getter that resolves to `"skip"`) tears down the subscription
883
+ * without unmounting.
884
+ *
885
+ * Unlike `useQuery`, which tracks the full reactive cache, `useSubscription`
886
+ * owns a single lightweight subscription and is suitable for ephemeral,
887
+ * high-frequency streams.
888
+ */
347
889
  declare const useSubscription: <F extends FunctionReference>(function_: F, args: MaybeRefOrGetter<ArgsOf<F> | "skip">, options?: UseQueryOptions) => UseSubscriptionResult<ReturnOf<F>>;
348
- export { AuthLoading, Authenticated, type HeartbeatReference, LUNORA_INJECTION_KEY, type ListPresentReference, type MutationHandle, type PageItemOf, type PaginatedArgs, Unauthenticated, type UseAuthResult, type UseInfiniteQueryOptions, type UseInfiniteQueryResult, type UsePaginatedQueryOptions, type UsePaginatedQueryResult, type UsePresenceOptions, type UsePresenceResult, type UseQueryOptions, type UseRateLimitOptions, type UseRateLimitResult, type UseSubscriptionResult, createLunora, hydratePreloaded, provideLunora, subscribeToQuery, useAuth, useConnectionStatus, useInfiniteQuery, useLunora, useMutation, usePaginatedQuery, usePresence, useQuery, useRateLimit, useSubscription };
890
+ /**
891
+ * Browser Web Audio subsystems for `useVoiceAgent` — the default microphone
892
+ * capture and speaker playback implementations injected into the composable via
893
+ * its `createMicrophone` / `createSpeaker` seams. Kept in a sibling module so the
894
+ * heavy Web Audio graph (and its structural DOM typings) stays isolated from the
895
+ * composable's transport + reactive-state logic and remains mockable in a
896
+ * non-browser test env.
897
+ */
898
+ /**
899
+ * The negotiated audio format the voice DO streams back. Mirrors
900
+ * `@lunora/agent`'s `VoiceServerFrame` `ready.audioFormat` — re-declared (not
901
+ * imported) so this Vue package never pulls in the server-only `@lunora/agent`
902
+ * module graph.
903
+ */
904
+ type VoiceAudioFormat = "mp3" | "wav";
905
+ /** Captures microphone audio and reports level / turn boundaries back to the composable. */
906
+ interface VoiceMicrophone {
907
+ /** Mute/unmute the mic without tearing down the capture graph. */
908
+ setMuted: (muted: boolean) => void;
909
+ /** Stop capture and release the media stream + audio graph. */
910
+ stop: () => void;
911
+ }
912
+ /** Plays the server's streamed audio chunks and supports a mid-utterance barge-in. */
913
+ interface VoiceSpeaker {
914
+ /** Queue a decoded audio chunk for gap-minimized playback. */
915
+ enqueue: (audio: Uint8Array) => void;
916
+ /** Drop everything queued and stop the current chunk (barge-in). */
917
+ interrupt: () => void;
918
+ /** Release the playback audio context. */
919
+ stop: () => void;
920
+ }
921
+ /** Config passed to a {@link CreateMicrophone} factory. */
922
+ interface MicrophoneConfig {
923
+ /** The consecutive above-threshold chunk count that counts as a barge-in. */
924
+ interruptChunks: number;
925
+ /** RMS above which the user is considered to be barging in while the agent speaks. */
926
+ interruptThreshold: number;
927
+ /** `true` while `status === "speaking"` — gates barge-in detection. */
928
+ isSpeaking: () => boolean;
929
+ /** One 16 kHz mono 16-bit little-endian PCM frame captured from the mic. */
930
+ onAudio: (pcm: Uint8Array) => void;
931
+ /** A barge-in was detected (RMS spike while the agent is speaking). */
932
+ onInterrupt: () => void;
933
+ /** The current input RMS (0–1), for a level meter. */
934
+ onLevel: (rms: number) => void;
935
+ /** A spoken utterance ended (speech followed by `silenceDurationMs` of silence). */
936
+ onSilence: () => void;
937
+ /** Milliseconds of sub-threshold audio (after speech) that closes an utterance. */
938
+ silenceDurationMs: number;
939
+ /** RMS below which audio counts as silence. */
940
+ silenceThreshold: number;
941
+ }
942
+ type CreateMicrophone = (config: MicrophoneConfig) => Promise<VoiceMicrophone>;
943
+ type CreateSpeaker = (config: {
944
+ audioFormat: VoiceAudioFormat;
945
+ }) => VoiceSpeaker;
946
+ /**
947
+ * The `agents.<name>Voice` reference codegen emits for a voice-enabled agent — a
948
+ * live, WS-backed session keyed by `threadKey`. A structural subset of the
949
+ * generated member, so passing `api.agents.<name>Voice` type-checks.
950
+ */
951
+ type VoiceReference = FunctionReference<"stream", {
952
+ threadKey: string;
953
+ }, Record<string, unknown>>;
954
+ /** The lifecycle of a voice call, mirrored to the UI. */
955
+ type VoiceStatus = "idle" | "listening" | "speaking" | "thinking";
956
+ /** A minimal structural subset of the DOM `WebSocket` the composable drives. */
957
+ interface VoiceSocket {
958
+ binaryType: string;
959
+ close: () => void;
960
+ onclose: ((event: unknown) => void) | null;
961
+ onerror: ((event: unknown) => void) | null;
962
+ onmessage: ((event: {
963
+ data: unknown;
964
+ }) => void) | null;
965
+ onopen: ((event: unknown) => void) | null;
966
+ readonly readyState: number;
967
+ send: (data: ArrayBufferView | ArrayBufferLike | string) => void;
968
+ }
969
+ type CreateSocket = (url: string) => VoiceSocket;
970
+ interface UseVoiceAgentOptions {
971
+ /**
972
+ * Advanced/test seam: build the microphone capture subsystem. Defaults to a
973
+ * `getUserMedia` + Web Audio implementation. Injected wholesale so the Web
974
+ * Audio graph stays isolated (and mockable in a non-browser test env).
975
+ */
976
+ createMicrophone?: CreateMicrophone;
977
+ /** Advanced/test seam: open the transport. Defaults to `new WebSocket(url)`. */
978
+ createSocket?: CreateSocket;
979
+ /** Advanced/test seam: build the audio playback subsystem. Defaults to a Web Audio implementation. */
980
+ createSpeaker?: CreateSpeaker;
981
+ /** Consecutive above-`interruptThreshold` chunks that trigger a barge-in. Default `3`. */
982
+ interruptChunks?: number;
983
+ /** Input RMS above which the user is treated as barging in while the agent speaks. Default `0.15`. */
984
+ interruptThreshold?: number;
985
+ /** Milliseconds of silence (after speech) that auto-commits an utterance. Default `1200`. */
986
+ silenceDurationMs?: number;
987
+ /** Input RMS below which audio counts as silence. Default `0.01`. */
988
+ silenceThreshold?: number;
989
+ /** The thread to converse on — shared with the agent's text turns. May be a plain value, `ref`, or getter (resolved when the call opens). */
990
+ threadKey: MaybeRefOrGetter<string>;
991
+ /** The generated `api.agents.<name>Voice` reference — identifies the voice DO endpoint. */
992
+ voice: VoiceReference;
993
+ }
994
+ interface UseVoiceAgentResult {
995
+ /** The current input RMS (0–1) — drive a mic level meter. */
996
+ audioLevel: Readonly<Ref<number>>;
997
+ /** `true` once the WS `ready` handshake completed. */
998
+ connected: Readonly<Ref<boolean>>;
999
+ /** Tear down the call: close the socket, stop the mic, release audio. Idempotent. */
1000
+ endCall: () => void;
1001
+ /** The last transport/pipeline error, or `undefined`. */
1002
+ error: Readonly<Ref<Error | undefined>>;
1003
+ /** The live assistant text for the in-flight turn (grows via deltas; finalized on done). */
1004
+ interimTranscript: Readonly<Ref<string>>;
1005
+ /** `true` while the mic is muted. */
1006
+ isMuted: Readonly<Ref<boolean>>;
1007
+ /** Send a typed turn (no audio) — a text message spoken back by the agent. */
1008
+ sendText: (text: string) => void;
1009
+ /** Open the mic, connect the socket, and start the conversation. Idempotent while active. */
1010
+ startCall: () => Promise<void>;
1011
+ /** The current call lifecycle. */
1012
+ status: Readonly<Ref<VoiceStatus>>;
1013
+ /** Mute/unmute the microphone. Returns the new muted state. */
1014
+ toggleMute: () => boolean;
1015
+ /** The last finalized user utterance (STT result). */
1016
+ transcript: Readonly<Ref<string>>;
1017
+ }
1018
+ /**
1019
+ * A first-class voice-call surface for a voice-enabled agent: it opens a
1020
+ * WebSocket to the agent's `VoiceSessionDO`, captures mic audio as 16 kHz PCM,
1021
+ * streams the agent's synthesized speech back through the browser's audio output,
1022
+ * and mirrors the call lifecycle (`status`, `transcript`, `interimTranscript`,
1023
+ * `audioLevel`) to Vue refs. Pass the generated `api.agents.<name>Voice`
1024
+ * reference (never a string), matching `useAgentChat`'s reference-passing style.
1025
+ * The Vue counterpart to React's `useVoiceAgent`, re-expressed with refs; the
1026
+ * per-call connection lives in a closure variable (a composable runs once per
1027
+ * component, so no `ref`-of-ref indirection is needed).
1028
+ *
1029
+ * v1 transport is plain binary WebSocket frames with push-to-talk / silence-timer
1030
+ * turn detection and client-side RMS barge-in. The heavy Web Audio capture and
1031
+ * playback subsystems are injectable (`createMicrophone` / `createSpeaker` /
1032
+ * `createSocket`) so the composable is drivable outside a browser.
1033
+ */
1034
+ declare const useVoiceAgent: (options: UseVoiceAgentOptions) => UseVoiceAgentResult;
1035
+ export { type ActionHandle, type AgentChatMessage, type AgentLiveEvent, type AgentProgressEvent, type AgentThreadRecord, type AgentThreadStatus, type AgentTokenDelta, type AgentToolEvent, AuthLoading, Authenticated, type FlagContext, type FlagValue, type HeartbeatReference,
1036
+ /**
1037
+ * `@lunora/vue` — the Vue adapter for Lunora.
1038
+ *
1039
+ * Thin, idiomatic glue over the framework-neutral `@lunora/client` (which owns
1040
+ * the WebSocket transport, subscription registry, offline queue, and
1041
+ * delta-merge — zero React, zero Vue). This package re-expresses that contract
1042
+ * as Vue composables:
1043
+ *
1044
+ * - `createLunora` / `provideLunora` / `useLunora` — provide/inject the client.
1045
+ * - `useQuery` — a live `ref` that opens a WS subscription and updates on deltas (reactive args re-subscribe).
1046
+ * - `useMutation` — an optimistic mutation handle (refs + awaitable `mutate`).
1047
+ * - `hydratePreloaded` — seed a `ref` synchronously from an SSR `Preloaded` token (no loading flash), then attach the live subscription.
1048
+ *
1049
+ * Server-side preload helpers live in the socket-free `@lunora/vue/server`
1050
+ * entry (`createServerClient`, `preloadQuery`). Nuxt's single-worker
1051
+ * composition (Lunora mounted inside Nitro) is `@lunora/nuxt`, not this
1052
+ * package — see [Bring your framework](/docs/frameworks/bring-your-framework).
1053
+ */
1054
+ LUNORA_INJECTION_KEY, type ListPresentReference, type MutationHandle, type MutatorHook, type PageItemOf, type PaginatedArgs, 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 UseInfiniteQueryOptions, type UseInfiniteQueryResult, 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,
1055
+ /**
1056
+ * `@lunora/vue` — the Vue adapter for Lunora.
1057
+ *
1058
+ * Thin, idiomatic glue over the framework-neutral `@lunora/client` (which owns
1059
+ * the WebSocket transport, subscription registry, offline queue, and
1060
+ * delta-merge — zero React, zero Vue). This package re-expresses that contract
1061
+ * as Vue composables:
1062
+ *
1063
+ * - `createLunora` / `provideLunora` / `useLunora` — provide/inject the client.
1064
+ * - `useQuery` — a live `ref` that opens a WS subscription and updates on deltas (reactive args re-subscribe).
1065
+ * - `useMutation` — an optimistic mutation handle (refs + awaitable `mutate`).
1066
+ * - `hydratePreloaded` — seed a `ref` synchronously from an SSR `Preloaded` token (no loading flash), then attach the live subscription.
1067
+ *
1068
+ * Server-side preload helpers live in the socket-free `@lunora/vue/server`
1069
+ * entry (`createServerClient`, `preloadQuery`). Nuxt's single-worker
1070
+ * composition (Lunora mounted inside Nitro) is `@lunora/nuxt`, not this
1071
+ * package — see [Bring your framework](/docs/frameworks/bring-your-framework).
1072
+ */
1073
+ createLunora, hydratePreloaded,
1074
+ /**
1075
+ * `@lunora/vue` — the Vue adapter for Lunora.
1076
+ *
1077
+ * Thin, idiomatic glue over the framework-neutral `@lunora/client` (which owns
1078
+ * the WebSocket transport, subscription registry, offline queue, and
1079
+ * delta-merge — zero React, zero Vue). This package re-expresses that contract
1080
+ * as Vue composables:
1081
+ *
1082
+ * - `createLunora` / `provideLunora` / `useLunora` — provide/inject the client.
1083
+ * - `useQuery` — a live `ref` that opens a WS subscription and updates on deltas (reactive args re-subscribe).
1084
+ * - `useMutation` — an optimistic mutation handle (refs + awaitable `mutate`).
1085
+ * - `hydratePreloaded` — seed a `ref` synchronously from an SSR `Preloaded` token (no loading flash), then attach the live subscription.
1086
+ *
1087
+ * Server-side preload helpers live in the socket-free `@lunora/vue/server`
1088
+ * entry (`createServerClient`, `preloadQuery`). Nuxt's single-worker
1089
+ * composition (Lunora mounted inside Nitro) is `@lunora/nuxt`, not this
1090
+ * package — see [Bring your framework](/docs/frameworks/bring-your-framework).
1091
+ */
1092
+ provideLunora, subscribeToQuery, useAction, useAgent, useAgentChat, useAgentState, useAgentToolEvents, useAuth, useConnectionStatus, useFlag, useFlags, useInfiniteQuery,
1093
+ /**
1094
+ * `@lunora/vue` — the Vue adapter for Lunora.
1095
+ *
1096
+ * Thin, idiomatic glue over the framework-neutral `@lunora/client` (which owns
1097
+ * the WebSocket transport, subscription registry, offline queue, and
1098
+ * delta-merge — zero React, zero Vue). This package re-expresses that contract
1099
+ * as Vue composables:
1100
+ *
1101
+ * - `createLunora` / `provideLunora` / `useLunora` — provide/inject the client.
1102
+ * - `useQuery` — a live `ref` that opens a WS subscription and updates on deltas (reactive args re-subscribe).
1103
+ * - `useMutation` — an optimistic mutation handle (refs + awaitable `mutate`).
1104
+ * - `hydratePreloaded` — seed a `ref` synchronously from an SSR `Preloaded` token (no loading flash), then attach the live subscription.
1105
+ *
1106
+ * Server-side preload helpers live in the socket-free `@lunora/vue/server`
1107
+ * entry (`createServerClient`, `preloadQuery`). Nuxt's single-worker
1108
+ * composition (Lunora mounted inside Nitro) is `@lunora/nuxt`, not this
1109
+ * package — see [Bring your framework](/docs/frameworks/bring-your-framework).
1110
+ */
1111
+ useLunora, useMutation, useMutator, usePaginatedQuery, usePresence, useQuery, useRateLimit, useStream, useSubscription, useVoiceAgent };