theokit 0.12.0 → 0.12.1

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 (42) hide show
  1. package/dist/adapters/web-shim.d.ts +67 -0
  2. package/dist/adapters/ws-shim.d.ts +55 -0
  3. package/dist/agent-events-DosDXkSV.d.ts +94 -0
  4. package/dist/audit-log-BQWM5YLG.d.ts +60 -0
  5. package/dist/boot/index.d.ts +39 -0
  6. package/dist/client/index.d.ts +362 -0
  7. package/dist/csrf-BBrEZSBW.d.ts +107 -0
  8. package/dist/csrf-readiness-store-CjIoub3U.d.ts +43 -0
  9. package/dist/define-websocket-CdK94O-D.d.ts +64 -0
  10. package/dist/devtools/entry.d.ts +5 -0
  11. package/dist/error-envelope-BsNzzAV5.d.ts +62 -0
  12. package/dist/health-route-C0hk64_U.d.ts +57 -0
  13. package/dist/index-B40qUSrQ.d.ts +575 -0
  14. package/dist/index.d.ts +361 -0
  15. package/dist/job-backend-CgC8Xf33.d.ts +68 -0
  16. package/dist/match-CfbEFRG4.d.ts +26 -0
  17. package/dist/plugin-runner-BGBkzgi0.d.ts +95 -0
  18. package/dist/plugin-types-DNJGxr4Z.d.ts +79 -0
  19. package/dist/rate-limit-BdNDZ3vt.d.ts +58 -0
  20. package/dist/rate-limit-store-BEJnhWdw.d.ts +72 -0
  21. package/dist/react-query/index.d.ts +33 -0
  22. package/dist/schema-BpH6ivDY.d.ts +74 -0
  23. package/dist/server/agent/index.d.ts +229 -0
  24. package/dist/server/auth/index.d.ts +419 -0
  25. package/dist/server/cost/index.d.ts +177 -0
  26. package/dist/server/cron/index.d.ts +208 -0
  27. package/dist/server/define/index.d.ts +313 -0
  28. package/dist/server/http/index.d.ts +11 -0
  29. package/dist/server/index.d.ts +848 -0
  30. package/dist/server/jobs/index.d.ts +348 -0
  31. package/dist/server/observability/index.d.ts +324 -0
  32. package/dist/server/plugins/index.d.ts +17 -0
  33. package/dist/server/rate-limit/index.d.ts +105 -0
  34. package/dist/server/realtime/index.d.ts +15 -0
  35. package/dist/server/scan/index.d.ts +106 -0
  36. package/dist/server/security/index.d.ts +193 -0
  37. package/dist/server/storage/index.d.ts +22 -0
  38. package/dist/server/webhook/index.d.ts +148 -0
  39. package/dist/storage-manager-C4jsO0Tp.d.ts +89 -0
  40. package/dist/storage-types-DsDTCPbp.d.ts +96 -0
  41. package/dist/vite-plugin/index.d.ts +115 -0
  42. package/package.json +4 -4
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Web-to-Node bridge used by adapters whose runtimes provide a `Request`
3
+ * (Web Standard) but where TheoKit's `executeRoute` expects a Node-style
4
+ * IncomingMessage/ServerResponse pair.
5
+ *
6
+ * Used by adapters that target Node-compatible runtimes (Bun, Netlify
7
+ * Functions, AWS Lambda Node). Cloudflare uses an inline version of the same
8
+ * pattern — long-term it should consolidate here too.
9
+ *
10
+ * NOT used by Deno Deploy: Deno's stdlib does not have `Buffer`/`node:http`
11
+ * by default and forcing the shim there bloats the bundle. Deno wiring is
12
+ * tracked separately and will likely require executeRoute to accept Web
13
+ * Standard Request directly.
14
+ */
15
+ interface ShimRequest {
16
+ method: string;
17
+ url: string;
18
+ headers: Record<string, string>;
19
+ socket: {
20
+ remoteAddress: string;
21
+ };
22
+ on: (event: 'data' | 'end' | 'error', cb: (chunk?: unknown) => void) => unknown;
23
+ }
24
+ interface ShimResponse {
25
+ statusCode: number;
26
+ headersSent: boolean;
27
+ writableEnded: boolean;
28
+ writeHead: (status: number, headers?: Record<string, string>) => void;
29
+ setHeader: (key: string, value: string) => void;
30
+ getHeader: (key: string) => string | undefined;
31
+ write: (chunk: Uint8Array | string) => boolean;
32
+ end: (body?: Uint8Array | string) => void;
33
+ }
34
+ interface ShimContext {
35
+ req: ShimRequest;
36
+ res: ShimResponse;
37
+ /** Resolves to a Web Standard Response once `res.end()` is called. */
38
+ toResponse: () => Promise<Response>;
39
+ }
40
+ interface CreateWebShimOptions {
41
+ /**
42
+ * CR-018 fix: how to resolve the client IP from forwarded headers.
43
+ *
44
+ * - `'platform'` (default for `cf-connecting-ip`): trust runtime-injected
45
+ * headers only (`cf-connecting-ip` on Cloudflare, `x-real-ip` on
46
+ * Netlify/Vercel when the platform writes it). Ignores
47
+ * `x-forwarded-for` because clients can spoof it.
48
+ * - `'trusted-proxy'`: read the **rightmost** entry of `x-forwarded-for`.
49
+ * Only safe when the request literally went through a trusted proxy
50
+ * that strips client-set headers and appends the real client IP last.
51
+ * - `'none'`: skip all forwarded-header lookups and report
52
+ * `'0.0.0.0'`. Force this when the adapter has no reliable way to
53
+ * identify the client (rate-limiters then must use a different key).
54
+ *
55
+ * Default: `'platform'`.
56
+ */
57
+ trustedProxy?: 'platform' | 'trusted-proxy' | 'none';
58
+ }
59
+ /**
60
+ * Build Node-style req/res objects around a Web Standard Request.
61
+ * `toResponse()` returns a Promise that resolves when `res.end()` has been
62
+ * invoked, materializing a Web Standard Response with the accumulated body
63
+ * + headers + status.
64
+ */
65
+ declare function createWebShim(request: Request, options?: CreateWebShimOptions): ShimContext;
66
+
67
+ export { type CreateWebShimOptions, type ShimContext, type ShimRequest, type ShimResponse, createWebShim };
@@ -0,0 +1,55 @@
1
+ /**
2
+ * T3.1 — WebSocket cross-runtime bridges.
3
+ *
4
+ * Exports 4 bridges (Node `ws` package, Bun.serve, Deno.upgradeWebSocket,
5
+ * Cloudflare WebSocketPair) that adapt each runtime's native WebSocket API
6
+ * to a common `WebSocketLike` interface that user handlers (`defineWebSocket`)
7
+ * can consume uniformly.
8
+ */
9
+ interface WebSocketLike {
10
+ send(data: string | Uint8Array | ArrayBuffer): void;
11
+ close(code?: number, reason?: string): void;
12
+ on(event: 'message' | 'close' | 'error', cb: (data?: unknown) => void): void;
13
+ }
14
+ interface WsHandler {
15
+ onOpen?: (ws: WebSocketLike) => void;
16
+ onMessage?: (ws: WebSocketLike, data: unknown) => void;
17
+ onClose?: (ws: WebSocketLike, code?: number, reason?: string) => void;
18
+ onError?: (ws: WebSocketLike, err: unknown) => void;
19
+ }
20
+ interface NodeWsLike {
21
+ on(event: string, cb: (arg?: unknown) => void): unknown;
22
+ send(data: unknown): void;
23
+ close(code?: number, reason?: string): void;
24
+ }
25
+ declare function createNodeWsBridge(handler: WsHandler): {
26
+ attach(nativeWs: NodeWsLike): WebSocketLike;
27
+ };
28
+ interface BunWsContext {
29
+ send(data: unknown): void;
30
+ close(code?: number, reason?: string): void;
31
+ }
32
+ interface BunWebSocketConfig {
33
+ open: (ws: BunWsContext) => void;
34
+ message: (ws: BunWsContext, message: unknown) => void;
35
+ close: (ws: BunWsContext, code?: number, reason?: string) => void;
36
+ }
37
+ declare function createBunWsBridge(handler: WsHandler): BunWebSocketConfig;
38
+ interface DenoLike {
39
+ upgradeWebSocket(req: Request): {
40
+ response: Response;
41
+ socket: {
42
+ send(data: unknown): void;
43
+ close(code?: number, reason?: string): void;
44
+ addEventListener(event: string, cb: (e: unknown) => void): void;
45
+ };
46
+ };
47
+ }
48
+ declare function createDenoWsBridge(handler: WsHandler, denoNs: DenoLike): {
49
+ handle(request: Request): Response;
50
+ };
51
+ declare function createCloudflareWsBridge(handler: WsHandler): {
52
+ handle(request: Request): Response;
53
+ };
54
+
55
+ export { type BunWebSocketConfig, type WebSocketLike, type WsHandler, createBunWsBridge, createCloudflareWsBridge, createDenoWsBridge, createNodeWsBridge };
@@ -0,0 +1,94 @@
1
+ /**
2
+ * core/contracts/agent-events.ts
3
+ *
4
+ * Canonical home for the AgentEvent wire-format contract (T2.2 of
5
+ * architecture-cleanup plan; ADR-0001 v3 invariant #3 exception).
6
+ *
7
+ * Server emits via SSE; client consumes. Discriminated union by `type`.
8
+ * Both `server/agent/*` and `client/*` import from here.
9
+ *
10
+ * Per ADR-0001 v3: `cache → core/contracts`, `client → core/contracts`,
11
+ * `devtools → core/contracts` are LEGAL direct imports (this is the
12
+ * documented exception to the `no-cross-module-deep-import` rule).
13
+ */
14
+ /**
15
+ * Discriminated union for AgentRunError codes (Phase 1 — Production-Readiness #3).
16
+ *
17
+ * Mirrors `@theokit/sdk`'s `AgentRunErrorCode` without hard-importing the SDK
18
+ * type (D2 decoupling). EC-7 forward-compat: `(string & {})` fallback preserves
19
+ * autocompletion for the known codes while accepting future codes the SDK may
20
+ * introduce — autocomplete works AND TS doesn't reject unknown codes.
21
+ */
22
+ type AgentRunErrorCode = 'auth' | 'rate_limit' | 'quota_exceeded' | 'invalid_model' | 'invalid_request' | 'invalid_input' | 'context_too_large' | 'safety_blocked' | 'provider_unreachable' | 'tool_runtime_error' | 'aborted' | 'unknown' | (string & {});
23
+ interface AgentMessageEvent {
24
+ type: 'message';
25
+ content: string;
26
+ /** Optional id for client-side dedup / animation keys. */
27
+ id?: string;
28
+ }
29
+ interface AgentToolCallEvent {
30
+ type: 'tool_call';
31
+ name: string;
32
+ args: Record<string, unknown>;
33
+ id?: string;
34
+ }
35
+ interface AgentToolResultEvent {
36
+ type: 'tool_result';
37
+ name: string;
38
+ data: unknown;
39
+ id?: string;
40
+ }
41
+ /**
42
+ * Error event emitted via SSE.
43
+ *
44
+ * Phase 1 — Production-Readiness #3:
45
+ * New optional fields `code/provider/retriable/retryAfterMs` discriminate
46
+ * error classes for client-side handling (auth → sign-in CTA; rate_limit →
47
+ * countdown; quota_exceeded → upsell; etc.).
48
+ *
49
+ * Backward compat (D4): all new fields are optional. Existing clients that
50
+ * read only `event.message` keep working unchanged. New clients can safely
51
+ * `switch (event.code)` — `undefined` (legacy server) is a valid case.
52
+ *
53
+ * EC-15 (DOCUMENT): `message` is *trusted* to not contain secrets. SDK's
54
+ * `AgentRunError.message` is propagated verbatim. The SDK's `providerError`
55
+ * is NEVER serialized into this event — quarantined to prevent leakage.
56
+ */
57
+ interface AgentErrorEvent {
58
+ type: 'error';
59
+ message: string;
60
+ id?: string;
61
+ /** Discriminated error class — see AgentRunErrorCode. */
62
+ code?: AgentRunErrorCode;
63
+ /** Provider id (e.g., 'openai', 'anthropic', 'openrouter'). */
64
+ provider?: string;
65
+ /** Whether the SAME request can be retried as-is. */
66
+ retriable?: boolean;
67
+ /** Hint from provider's Retry-After header (milliseconds). Zero is valid (immediate retry). */
68
+ retryAfterMs?: number;
69
+ }
70
+ /**
71
+ * Extended thinking / reasoning event.
72
+ *
73
+ * Carries the model's reasoning text (when the model supports extended
74
+ * thinking). Mirrors the `@theokit/agents` stream-layer `ThinkingEvent`
75
+ * (`packages/agents/src/bridge/agent-stream-events.ts`) so the two layers
76
+ * agree on the wire form; defined here (not imported) to keep `core/contracts`
77
+ * free of a dependency on `@theokit/agents` (G1 dependency direction).
78
+ *
79
+ * Consumers that switch only on the other variants are unaffected (additive);
80
+ * a consumer that wants to surface reasoning opts in by handling `'thinking'`.
81
+ */
82
+ interface AgentThinkingEvent {
83
+ type: 'thinking';
84
+ content: string;
85
+ /** Optional id for client-side dedup / animation keys. */
86
+ id?: string;
87
+ }
88
+ /**
89
+ * Runtime AgentEvent — discriminated union of the 5 variants emitted by
90
+ * agent endpoints. Server produces; client consumes.
91
+ */
92
+ type AgentEvent = AgentMessageEvent | AgentToolCallEvent | AgentToolResultEvent | AgentErrorEvent | AgentThinkingEvent;
93
+
94
+ export type { AgentEvent as A, AgentErrorEvent as a, AgentMessageEvent as b, AgentThinkingEvent as c, AgentToolCallEvent as d, AgentToolResultEvent as e, AgentRunErrorCode as f };
@@ -0,0 +1,60 @@
1
+ /**
2
+ * T4.1 — Audit logging interface + default JSON stdout sink.
3
+ *
4
+ * Per ADR D4: define the interface; ship a zero-dep default; reserve
5
+ * adapter shapes for Postgres, File, OpenTelemetry, Sentry as follow-up
6
+ * packages. Persistence has heavy deps (`pg`, `better-sqlite3`); we
7
+ * keep core dep-free and let users opt in.
8
+ *
9
+ * Compatibility:
10
+ * - Node / Bun / Deno / Vercel — console.log is sync, captured.
11
+ * - Edge runtimes (CF Workers, Vercel Edge) — console.log is captured
12
+ * but may be rate-limited by the platform. For high-volume edge audit,
13
+ * implement a custom sink writing to a queue / HTTP endpoint.
14
+ */
15
+ interface AuditEvent {
16
+ /** Domain-qualified verb. Convention: `<domain>.<verb>` (e.g. csrf.warn, session.rotated). */
17
+ action: string;
18
+ /** Who triggered the event. Anonymous = no auth at time of event. */
19
+ actor?: {
20
+ type: 'user' | 'system' | 'anonymous';
21
+ id?: string;
22
+ };
23
+ /** What was operated on (optional). */
24
+ resource?: {
25
+ type: string;
26
+ id?: string;
27
+ };
28
+ /** Arbitrary event-specific metadata. JSON-serializable. */
29
+ metadata?: Record<string, unknown>;
30
+ /** ISO 8601 timestamp. If absent, sink fills in `new Date().toISOString()`. */
31
+ timestamp?: string;
32
+ /** Optional trace id (populated by middleware from `x-trace-id`). */
33
+ traceId?: string;
34
+ }
35
+ interface AuditLogger {
36
+ log(event: AuditEvent): void | Promise<void>;
37
+ }
38
+ /**
39
+ * Default sink: one JSON line per event to stdout. Sync. Never throws.
40
+ *
41
+ * EC: circular refs / BigInt values fall back to a placeholder line so
42
+ * the event is still observable (action + traceId) without crashing the
43
+ * request lifecycle.
44
+ */
45
+ declare class JsonStdoutSink implements AuditLogger {
46
+ log(event: AuditEvent): void;
47
+ }
48
+ /**
49
+ * No-op logger. Returned when `config.audit` is unset. Zero overhead;
50
+ * framework wiring sites null-check before calling.
51
+ */
52
+ declare function createNoOpLogger(): AuditLogger;
53
+ /**
54
+ * T4.2 — Safe-emit wrapper. Used by framework wiring sites (csrf.ts,
55
+ * rate-limit.ts, session.ts) so a logger throw NEVER propagates into
56
+ * the request handler.
57
+ */
58
+ declare function safeAudit(logger: AuditLogger | undefined, event: AuditEvent): void;
59
+
60
+ export { type AuditLogger as A, JsonStdoutSink as J, type AuditEvent as a, createNoOpLogger as c, safeAudit as s };
@@ -0,0 +1,39 @@
1
+ import { R as ReservedRoutes } from '../health-route-C0hk64_U.js';
2
+
3
+ /**
4
+ * M7-3 — `theokit/boot`: programmatic boot surface for the convention server.
5
+ *
6
+ * The programmatic surface is a Web `fetch` handler (the universal "fetch
7
+ * handler is the entry point" contract — see the hono reference in
8
+ * knowledge-base/discoveries/blueprints/m7-http-dual-surface-blueprint.md
9
+ * "Coverage Corner 4"). It composes M7-1 (typed 404 envelope) + M7-2 (reserved
10
+ * health/ready routes) and binds NO socket, so embedders + integration tests
11
+ * can fire requests in-process via `app.fetch(new Request(...))`.
12
+ *
13
+ * The CLI's `startDevServer`/`startCommand` (Vite/SSR machinery) intentionally
14
+ * stay in the `cli` module — `boot` must not depend on `cli` (architecture DAG:
15
+ * nothing depends on `cli`). The fetch handler IS the portable boot surface.
16
+ *
17
+ * @public
18
+ */
19
+
20
+ /** Options for {@link createConventionFetchHandler}. */
21
+ interface ConventionFetchHandlerOptions {
22
+ /** Reserved health/ready routes (M7-2). Liveness defaults to 200 even when omitted. */
23
+ readonly reservedRoutes?: ReservedRoutes;
24
+ }
25
+ /** A socketless convention-server handle. */
26
+ interface ConventionFetchHandle {
27
+ /** Serve a single request in-process (no socket). Reserved routes first, else a typed 404. */
28
+ fetch(request: Request): Promise<Response>;
29
+ /** Idempotent teardown. The in-process handler holds no socket, so this is a safe no-op. */
30
+ close(): Promise<void>;
31
+ }
32
+ /**
33
+ * Build an in-process convention-server `fetch` handler. Reserved `/__theo/*`
34
+ * routes (health/ready) are served first; any other path yields a typed
35
+ * `NOT_FOUND` envelope (404) via the same translator the wire boundary uses.
36
+ */
37
+ declare function createConventionFetchHandler(options?: ConventionFetchHandlerOptions): ConventionFetchHandle;
38
+
39
+ export { type ConventionFetchHandle, type ConventionFetchHandlerOptions, createConventionFetchHandler };
@@ -0,0 +1,362 @@
1
+ import { z } from 'zod';
2
+ import { T as TheoErrorEnvelope } from '../error-envelope-BsNzzAV5.js';
3
+ export { FetchOptionsLike, Fetcher, QueryKey, UseTheoQueryConfig, buildUseTheoQueryConfig, stableQueryKey } from '../react-query/index.js';
4
+ import { A as AgentEvent, a as AgentErrorEvent } from '../agent-events-DosDXkSV.js';
5
+ export { b as AgentMessageEvent, c as AgentThinkingEvent, d as AgentToolCallEvent, e as AgentToolResultEvent } from '../agent-events-DosDXkSV.js';
6
+ import * as react from 'react';
7
+ import { LinkProps as LinkProps$1 } from 'react-router';
8
+
9
+ /** Infer the response type from a route's handler return */
10
+ type InferResponse<T> = T extends {
11
+ handler: (...args: never[]) => infer R;
12
+ } ? Awaited<R> : unknown;
13
+ /** Extract the query Zod schema type, handling optional properties */
14
+ type ExtractQuery<T> = T extends {
15
+ query?: infer Q;
16
+ } ? (Q extends z.ZodType ? Q : never) : never;
17
+ /** Extract the body Zod schema type, handling optional properties */
18
+ type ExtractBody<T> = T extends {
19
+ body?: infer B;
20
+ } ? (B extends z.ZodType ? B : never) : never;
21
+ /** Infer query type from a route's query Zod schema */
22
+ type InferQuery<T> = [ExtractQuery<T>] extends [never] ? undefined : ExtractQuery<T> extends z.ZodUndefined ? undefined : z.infer<ExtractQuery<T>>;
23
+ /** Infer body type from a route's body Zod schema */
24
+ type InferBody<T> = [ExtractBody<T>] extends [never] ? undefined : ExtractBody<T> extends z.ZodUndefined ? undefined : z.infer<ExtractBody<T>>;
25
+ /** Build the options type based on what schemas the route has */
26
+ type TheoFetchOptions<T> = Omit<RequestInit, 'body' | 'method'> & (InferQuery<T> extends undefined ? {
27
+ query?: never;
28
+ } : {
29
+ query: InferQuery<T>;
30
+ }) & (InferBody<T> extends undefined ? {
31
+ body?: never;
32
+ } : {
33
+ body: InferBody<T>;
34
+ });
35
+ declare class TheoFetchError extends Error {
36
+ status: number;
37
+ code?: string;
38
+ issues?: unknown[];
39
+ /**
40
+ * G5 T2.1 — canonical envelope view of the server-side error. Use this in
41
+ * consumer code that wants to switch on a typed TheoErrorCode instead of
42
+ * coupling to the legacy `.status` / `.code` flat fields.
43
+ */
44
+ readonly envelope: TheoErrorEnvelope;
45
+ constructor(status: number, body?: unknown);
46
+ }
47
+ declare function theoFetch<T>(url: string, options?: TheoFetchOptions<T>): Promise<InferResponse<T>>;
48
+
49
+ /**
50
+ * Phase 3 of G1 (g1-client-codegen-plan.md):
51
+ *
52
+ * `createAppClient(baseUrl?, fetchImpl?)` returns a Proxy that walks property
53
+ * access (`client.posts.id.get(...)`) into a `theoFetch` invocation against
54
+ * `{baseUrl}/posts/{params.id}` with method `GET`.
55
+ *
56
+ * Type safety is delivered by the `.d.ts` file emitted in Phase 2 — this
57
+ * runtime is structurally untyped. Power users may use `theoFetch` directly
58
+ * when they need to escape the Proxy facade.
59
+ *
60
+ * Edge cases absorbed:
61
+ * - EC-1 (thenable trap): `then` / `catch` / `finally` / `toJSON` / `Symbol.*`
62
+ * return `undefined` so that accidental `await client.posts` resolves to a
63
+ * plain Proxy value (it is NOT thenable) instead of looping.
64
+ * - EC-7 (abort signal): `opts.signal` is spread through to the underlying
65
+ * fetchImpl unchanged — verified in unit tests.
66
+ *
67
+ * Bundle target: ≤ 2KB gzipped.
68
+ */
69
+
70
+ type FetchImpl = typeof theoFetch;
71
+ interface CreateAppClientOptions {
72
+ /** Base URL for the API. Defaults to `/api`. */
73
+ baseUrl?: string;
74
+ /** Test-only fetch override. Production callers should not pass this. */
75
+ fetchImpl?: FetchImpl;
76
+ }
77
+ declare function createAppClient<TAppClient = unknown>(baseUrlOrOptions?: string | CreateAppClientOptions, legacyFetchImpl?: FetchImpl): TAppClient;
78
+
79
+ /**
80
+ * T5.1 — client-side microtask batching.
81
+ *
82
+ * Collects all `dispatch` calls within the same microtask and sends them as a
83
+ * single HTTP POST to the configured transport. Each caller's promise resolves
84
+ * with its own result; one failed item does not break the others (per-item
85
+ * error isolation).
86
+ *
87
+ * Designed as a transport-agnostic primitive so unit tests do not require
88
+ * network access. The default transport (fetch to `/api/__theo_batch__`)
89
+ * lives alongside this module but is created by the consumer (e.g., theoFetch).
90
+ */
91
+ interface BatchRequest {
92
+ path: string;
93
+ method: string;
94
+ query?: Record<string, unknown>;
95
+ body?: unknown;
96
+ headers?: Record<string, string>;
97
+ }
98
+ type BatchResponse = {
99
+ index: number;
100
+ data: unknown;
101
+ } | {
102
+ index: number;
103
+ error: {
104
+ message: string;
105
+ code?: string;
106
+ };
107
+ };
108
+ type BatchTransport = (requests: BatchRequest[]) => Promise<BatchResponse[]>;
109
+ interface BatcherOptions {
110
+ transport: BatchTransport;
111
+ /** Maximum batch size before flushing into multiple parallel batches. */
112
+ max?: number;
113
+ }
114
+ interface Batcher {
115
+ dispatch(req: BatchRequest): Promise<unknown>;
116
+ }
117
+ declare function createBatcher(options: BatcherOptions): Batcher;
118
+
119
+ /**
120
+ * Accumulated assistant text (M5-1): the concatenation of every `message`
121
+ * event's `content`. Pure. Assumes append/delta semantics — a server that
122
+ * emits full-snapshot messages should read `events` directly.
123
+ */
124
+ declare function deriveLiveText(events: readonly AgentEvent[]): string;
125
+ /**
126
+ * The current error (M5-1): the last `error` event, or `undefined`. Surfaces
127
+ * the full `AgentErrorEvent` (with `code`/`retriable`) so the UI can branch.
128
+ * Pure.
129
+ */
130
+ declare function deriveError(events: readonly AgentEvent[]): AgentErrorEvent | undefined;
131
+ /**
132
+ * T5.2 — useAgentStream
133
+ *
134
+ * React hook to consume an agent endpoint defined with `defineAgentEndpoint`.
135
+ *
136
+ * Transport (ADR D7, EC-3): fetch + ReadableStream — NOT EventSource.
137
+ * EventSource is GET-only; agent endpoints need POST + body.
138
+ *
139
+ * Returns:
140
+ * events — array of AgentEvents accumulated so far
141
+ * send — call with a payload to (re)open a stream
142
+ * status — 'idle' | 'streaming' | 'done' | 'error'
143
+ * abort — manually cancel an in-flight stream
144
+ *
145
+ * Cleanup (EC-8): on unmount, the current AbortController fires .abort(),
146
+ * which propagates to the underlying fetch and the ReadableStream reader.
147
+ * Safe under React.StrictMode double-mount.
148
+ */
149
+ type AgentStreamStatus = 'idle' | 'streaming' | 'done' | 'error';
150
+ interface UseAgentStreamReturn<TBody = unknown> {
151
+ events: AgentEvent[];
152
+ status: AgentStreamStatus;
153
+ /** Accumulated assistant text — concatenation of all `message` contents (M5-1). */
154
+ liveText: string;
155
+ /** The last `error` event, or `undefined` (M5-1). */
156
+ error: AgentErrorEvent | undefined;
157
+ send: (body: TBody) => void;
158
+ abort: () => void;
159
+ reset: () => void;
160
+ }
161
+ interface UseAgentStreamOptions {
162
+ /** Extra headers (e.g., auth). */
163
+ headers?: Record<string, string>;
164
+ /** Override fetch (rare — primarily for tests). */
165
+ fetch?: typeof fetch;
166
+ }
167
+ declare function useAgentStream<TBody = unknown>(path: string, options?: UseAgentStreamOptions): UseAgentStreamReturn<TBody>;
168
+
169
+ /**
170
+ * A correlated, UI-facing view of one tool invocation (M5-2).
171
+ *
172
+ * `foldAgentToolCards` correlates a `tool_call` with its `tool_result` (by
173
+ * `id`, falling back to FIFO-by-name) into a single card so consumers stop
174
+ * hand-rolling `switch(event.type)`.
175
+ */
176
+ interface AgentToolCard {
177
+ /** Correlation id (the event `id`, or a synthesized `tool-<index>`). */
178
+ id: string;
179
+ name: string;
180
+ args: Record<string, unknown>;
181
+ status: 'running' | 'success' | 'error';
182
+ /** The `tool_result.data` payload, once the result arrives. */
183
+ result?: unknown;
184
+ }
185
+ /**
186
+ * Classifies a `tool_result.data` payload as success/error. Injectable so the
187
+ * correlator is decoupled from any specific tool-result envelope shape.
188
+ */
189
+ type ToolEnvelopeResolver = (data: unknown) => {
190
+ error: boolean;
191
+ };
192
+ interface FoldAgentToolCardsOptions {
193
+ /** Override the default envelope classifier. */
194
+ resolveEnvelope?: ToolEnvelopeResolver;
195
+ }
196
+ /**
197
+ * Default envelope resolver: an object (or a JSON STRING parsing to an object)
198
+ * with `ok === false` is an error; everything else is success (conservative).
199
+ * sdk-tools handlers return a JSON STRING, so string parsing is intentional.
200
+ */
201
+ declare function defaultResolveEnvelope(data: unknown): {
202
+ error: boolean;
203
+ };
204
+ /**
205
+ * Fold an `AgentEvent[]` into correlated {@link AgentToolCard}s (M5-2). Pure.
206
+ *
207
+ * Correlation: a `tool_result` matches its `tool_call` by `id` when both carry
208
+ * one; otherwise it matches the oldest still-`running` card with the same
209
+ * `name` (FIFO). An unmatched `tool_result` becomes its own finished card.
210
+ * A `tool_call` with no result stays `running`. The error status comes from
211
+ * `options.resolveEnvelope` (default {@link defaultResolveEnvelope}).
212
+ */
213
+ declare function foldAgentToolCards(events: readonly AgentEvent[], options?: FoldAgentToolCardsOptions): AgentToolCard[];
214
+
215
+ /** {@link useAgentToolCards} return — the stream result plus correlated tool cards. */
216
+ interface UseAgentToolCardsReturn<TBody = unknown> extends UseAgentStreamReturn<TBody> {
217
+ /** Correlated tool cards folded from the stream events (M5-2). */
218
+ toolCards: AgentToolCard[];
219
+ }
220
+ /**
221
+ * `useAgentStream` + correlated tool cards (M5-2). Composes the stream hook with
222
+ * the pure {@link foldAgentToolCards} reducer; pass `resolveEnvelope` to classify
223
+ * tool-result payloads (default flags `{ ok: false }` envelopes as errors).
224
+ */
225
+ declare function useAgentToolCards<TBody = unknown>(path: string, options?: UseAgentStreamOptions & FoldAgentToolCardsOptions): UseAgentToolCardsReturn<TBody>;
226
+
227
+ /**
228
+ * T5.2 — Pure SSE consumer used by useAgentStream.
229
+ *
230
+ * Split out from the React hook so the wire behavior can be tested
231
+ * without a DOM. The hook is glue: useState + useEffect + this primitive.
232
+ *
233
+ * Transport (ADR D7, EC-3): fetch + ReadableStream — NOT EventSource.
234
+ * EventSource is GET-only and cannot carry a body. Agent endpoints need
235
+ * POST + JSON body, so we use fetch + manual SSE chunk parsing.
236
+ */
237
+ interface ConsumeOptions<TBody = unknown> {
238
+ /** Request body — JSON-serialized into the POST. */
239
+ body: TBody;
240
+ /** Called once per SSE event parsed off the stream. */
241
+ onEvent: (event: AgentEvent) => void;
242
+ /** Optional fetch override (tests). */
243
+ fetch?: typeof fetch;
244
+ /** Optional abort signal — passed through to fetch. */
245
+ signal?: AbortSignal;
246
+ /** Extra headers (e.g., auth). */
247
+ headers?: Record<string, string>;
248
+ }
249
+ /**
250
+ * Parse a single SSE line of the form `data: <json>`.
251
+ * Returns null for non-data lines, comments, or malformed JSON.
252
+ */
253
+ declare function parseSSEChunk(line: string): AgentEvent | null;
254
+ /**
255
+ * POSTs to `path` with `body`, reads the SSE response, and invokes
256
+ * `onEvent` for each parsed AgentEvent. Resolves when the server
257
+ * closes the stream or the signal aborts.
258
+ *
259
+ * T1.1 — Attaches `X-Theo-Action: '1'` so 0.3.0 strict CSRF mode accepts
260
+ * the request. The user can override (or suppress) by passing the header
261
+ * in `options.headers` — spread order ensures their value wins.
262
+ */
263
+ declare function consumeAgentStream<TBody = unknown>(path: string, options: ConsumeOptions<TBody>): Promise<void>;
264
+
265
+ type PrefetchBehavior = 'none' | 'intent' | 'viewport';
266
+ interface LinkProps extends LinkProps$1 {
267
+ /** Prefetch strategy. Default: 'intent' (on hover + focus). */
268
+ prefetch?: PrefetchBehavior;
269
+ }
270
+ /**
271
+ * TheoKit Link — drop-in replacement for react-router Link with prefetch.
272
+ *
273
+ * @example
274
+ * ```tsx
275
+ * import { Link } from 'theokit/client'
276
+ *
277
+ * <Link to="/contacts">Contacts</Link>
278
+ * <Link to="/dashboard" prefetch="viewport">Dashboard</Link>
279
+ * <Link to="/settings" prefetch="none">Settings</Link>
280
+ * ```
281
+ */
282
+ declare function Link({ prefetch, to, onMouseEnter, onFocus, ...rest }: LinkProps): react.JSX.Element;
283
+
284
+ /**
285
+ * <Metadata> — SEO-ready head tags from a single component.
286
+ *
287
+ * Uses React 19's native <title>/<meta>/<link> hoisting to <head>.
288
+ * No build-time extraction needed — works in SSR and client.
289
+ *
290
+ * @example
291
+ * ```tsx
292
+ * import { Metadata } from 'theokit/client'
293
+ *
294
+ * export default function ContactsPage() {
295
+ * return (
296
+ * <>
297
+ * <Metadata
298
+ * title="Contacts | My CRM"
299
+ * description="Manage your contacts"
300
+ * ogImage="/og/contacts.png"
301
+ * canonical="https://mycrm.com/contacts"
302
+ * />
303
+ * <h1>Contacts</h1>
304
+ * </>
305
+ * )
306
+ * }
307
+ * ```
308
+ */
309
+ interface MetadataProps {
310
+ title?: string;
311
+ description?: string;
312
+ canonical?: string;
313
+ ogTitle?: string;
314
+ ogDescription?: string;
315
+ ogImage?: string;
316
+ ogType?: string;
317
+ ogUrl?: string;
318
+ twitterCard?: 'summary' | 'summary_large_image';
319
+ /** Custom meta tags rendered as children */
320
+ children?: React.ReactNode;
321
+ }
322
+ declare function Metadata(props: MetadataProps): react.JSX.Element;
323
+
324
+ /**
325
+ * <Image> — optimized image component with lazy loading.
326
+ *
327
+ * Renders a standard <img> with:
328
+ * - loading="lazy" by default (eager with priority={true})
329
+ * - decoding="async" for non-blocking decode
330
+ * - width/height for CLS prevention
331
+ * - srcSet/sizes forwarded for responsive images
332
+ *
333
+ * No CDN, no Sharp, no build-time optimization — pure HTML attributes
334
+ * that deliver 80% of the performance value at zero complexity.
335
+ *
336
+ * @example
337
+ * ```tsx
338
+ * import { Image } from 'theokit/client'
339
+ *
340
+ * <Image src="/team.jpg" alt="Team photo" width={800} height={600} />
341
+ * <Image src="/hero.jpg" alt="Hero" priority />
342
+ * <Image
343
+ * src="/product.jpg"
344
+ * alt="Product"
345
+ * width={400}
346
+ * height={300}
347
+ * srcSet="/product-400.jpg 400w, /product-800.jpg 800w"
348
+ * sizes="(max-width: 768px) 100vw, 400px"
349
+ * />
350
+ * ```
351
+ */
352
+ interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
353
+ /** Image source URL (required). */
354
+ src: string;
355
+ /** Alt text for accessibility (required). */
356
+ alt: string;
357
+ /** If true, loading="eager" — use for above-the-fold images. */
358
+ priority?: boolean;
359
+ }
360
+ declare function Image({ priority, loading, decoding, ...props }: ImageProps): react.JSX.Element;
361
+
362
+ export { AgentErrorEvent, AgentEvent, type AgentStreamStatus, type AgentToolCard, type BatchRequest, type BatchResponse, type BatchTransport, type Batcher, type BatcherOptions, type ConsumeOptions, type CreateAppClientOptions, type FoldAgentToolCardsOptions, Image, type ImageProps, type InferBody, type InferQuery, type InferResponse, Link, type LinkProps, Metadata, type MetadataProps, type PrefetchBehavior, TheoFetchError, type TheoFetchOptions, type ToolEnvelopeResolver, type UseAgentStreamOptions, type UseAgentStreamReturn, type UseAgentToolCardsReturn, consumeAgentStream, createAppClient, createBatcher, defaultResolveEnvelope, deriveError, deriveLiveText, foldAgentToolCards, parseSSEChunk, theoFetch, useAgentStream, useAgentToolCards };