@workerdeck/core 0.7.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.d.mts CHANGED
@@ -1,8 +1,49 @@
1
- import { Options, Query, SDKMessage, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
1
+ import { McpServerStatus, Options, Query, SDKMessage, SDKUserMessage, SessionMessage } from "@anthropic-ai/claude-agent-sdk";
2
+ import { ApiMessage, CreateSessionRequest, EngineCapabilities, McpServerConfigWire, McpServerStatusInfo, MessageAttachment, ModelOption, PermissionMode, PermissionRequest, ProfileEngine, ProfileInfo, SdkSessionSummary, SessionEvent, SessionEventBody, SessionInfo, SessionStatus, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput } from "@workerdeck/protocol";
2
3
  import { LanguageModel, ModelMessage, Tool, ToolSet } from "ai";
3
4
  import { SandboxEngine, SandboxVfs } from "@workerdeck/sandbox";
4
- import { ApiMessage, CreateSessionRequest, McpServerConfigWire, PermissionMode, PermissionRequest, ProfileEngine, ProfileInfo, SessionEvent, SessionEventBody, SessionInfo, SessionStatus, ToolCallRequestFrame, ToolExecutionBackend, ToolExecutionOutput } from "@workerdeck/protocol";
5
+ import { Readable, Writable } from "node:stream";
5
6
 
7
+ //#region src/attachments.d.ts
8
+ /**
9
+ * An attachment plus its bytes — what the host hands a runner at send time.
10
+ *
11
+ * The split matters: `data` goes into the message the engine sends and nowhere
12
+ * else. What the runner emits into the seq-numbered event log is the
13
+ * {@link MessageAttachment} half, so replay and parking stay cheap (see the
14
+ * protocol's note on why the bytes are not on the wire).
15
+ */
16
+ type AttachmentInput = MessageAttachment & {
17
+ /** Base64, no data-URL prefix. */data: string;
18
+ };
19
+ /**
20
+ * How an attachment reaches the model. Not every file can be handed to a model
21
+ * as itself: images and PDFs have native block types, anything textual can be
22
+ * inlined, and the rest has no representation at all — so uploads of it are
23
+ * refused at the door rather than silently dropped from the message.
24
+ */
25
+ type AttachmentKind = 'image' | 'document' | 'text';
26
+ /** Strips any `; charset=…` parameter and lowercases. */
27
+ declare function normalizeMediaType(mediaType: string): string;
28
+ /** How this media type can be sent, or null if it can't be. */
29
+ declare function attachmentKind(mediaType: string): AttachmentKind | null;
30
+ /** Human-readable list for the 415 an unsupported upload gets. */
31
+ declare const SUPPORTED_ATTACHMENT_TYPES: string;
32
+ /**
33
+ * Anthropic content blocks for a set of attachments, in the given order.
34
+ *
35
+ * Blocks lead the message and the user's text follows: the model reads the
36
+ * picture, then the instruction about it. Text files are inlined in a named
37
+ * envelope rather than as a bare block, so "here is my config" doesn't read as
38
+ * something the user typed.
39
+ *
40
+ * Structurally typed — `packages/core` models Anthropic content the way
41
+ * `packages/protocol` does, and the caller casts into the SDK's own param type.
42
+ */
43
+ declare function attachmentContentBlocks(attachments: readonly AttachmentInput[]): Array<Record<string, unknown>>;
44
+ /** Strip the bytes: the log-safe half of an attachment. */
45
+ declare function attachmentRef(attachment: AttachmentInput): MessageAttachment;
46
+ //#endregion
6
47
  //#region src/tool-executor.d.ts
7
48
  /**
8
49
  * Result of one tool execution, whenever it arrives. `failed` is a normal
@@ -136,8 +177,22 @@ interface Runner {
136
177
  info(): SessionInfo;
137
178
  /** Replay buffered events with seq > afterSeq, then deliver live events. Returns unsubscribe. */
138
179
  subscribe(listener: SessionEventListener, afterSeq?: number): () => void;
139
- /** Queue a user message for the session (starts the next turn when idle). */
140
- sendMessage(text: string): void;
180
+ /** Queue a user message for the session (starts the next turn when idle).
181
+ * `attachments` carry their bytes to the engine and their reference to the
182
+ * event log (see {@link AttachmentInput}). */
183
+ sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
184
+ /** Live MCP server status. Resolves undefined when the engine cannot answer
185
+ * (no MCP surface, or a fake query in tests); omitted entirely by engines that
186
+ * have no MCP at all. */
187
+ mcpServers?(): Promise<McpServerStatusInfo[] | undefined>;
188
+ /** Reconnect one MCP server by name. Throws if it fails. */
189
+ reconnectMcpServer?(name: string): Promise<void>;
190
+ /** Enable or disable one MCP server by name. Throws if it fails. */
191
+ setMcpServerEnabled?(name: string, enabled: boolean): Promise<void>;
192
+ /** Set (or clear, with undefined) the host's display title — `meta.title`, which
193
+ * `info().title` prefers over the derived one. A host-facing edit only: nothing
194
+ * is sent to the engine. */
195
+ setTitle(title: string | undefined): void;
141
196
  /** Resolve a pending permission request. Returns false if the id is unknown (e.g. timed out). */
142
197
  resolvePermission(requestId: string, decision: PermissionDecision): boolean;
143
198
  interrupt(): Promise<void>;
@@ -202,10 +257,23 @@ declare class SessionRunner implements Runner {
202
257
  get apiKeySource(): string | undefined;
203
258
  get pendingApprovals(): PermissionRequest[];
204
259
  info(): SessionInfo;
260
+ /** Host-facing rename: writes `meta.title`, which `#title()` prefers. Clearing
261
+ * it (undefined) restores the derived title. The engine is never told. */
262
+ setTitle(title: string | undefined): void;
205
263
  /** Begin the session. Idempotent; returns the run promise (resolves when the query ends). */
206
264
  start(): Promise<void>;
207
- /** Queue a user message for the session (starts the next turn when idle). */
208
- sendMessage(text: string): void;
265
+ /** Queue a user message for the session (starts the next turn when idle).
266
+ *
267
+ * `attachments` carry their own bytes; they reach the CLI as content blocks and
268
+ * are logged as references. A message may be attachments alone — an empty text
269
+ * block is not valid API input, so the text is only added when there is some. */
270
+ sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
271
+ /** Live MCP server status, straight from the CLI. Undefined when the engine
272
+ * can't answer (an injected fake query in tests) — the caller 501s rather than
273
+ * pretending the session has no servers. */
274
+ mcpServers(): Promise<McpServerStatusInfo[] | undefined>;
275
+ reconnectMcpServer(name: string): Promise<void>;
276
+ setMcpServerEnabled(name: string, enabled: boolean): Promise<void>;
209
277
  /** Resolve a pending permission request. Returns false if the id is unknown (e.g. timed out). */
210
278
  resolvePermission(requestId: string, decision: PermissionDecision): boolean;
211
279
  interrupt(): Promise<void>;
@@ -348,7 +416,7 @@ declare class AiSdkRunner implements Runner {
348
416
  * or an already-closed/parked runner.
349
417
  */
350
418
  park(): RunnerSnapshot | undefined;
351
- sendMessage(text: string): void;
419
+ sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
352
420
  /**
353
421
  * Deliver the result of an external (execute-less) tool call. Appends the
354
422
  * tool-result message and, once no calls remain pending, re-enters the loop.
@@ -383,6 +451,9 @@ declare class AiSdkRunner implements Runner {
383
451
  * deferred executor). Idempotent by executionId.
384
452
  */
385
453
  settleExecution(executionId: string, result: ToolExecutionResult): boolean;
454
+ /** Host-facing rename: writes `meta.title`, which `#title()` prefers. Clearing
455
+ * it (undefined) restores the derived title. The engine is never told. */
456
+ setTitle(title: string | undefined): void;
386
457
  }
387
458
  //#endregion
388
459
  //#region src/claude-auth.d.ts
@@ -837,6 +908,27 @@ declare class InputQueue implements AsyncIterable<SDKUserMessage> {
837
908
  //#endregion
838
909
  //#region src/normalize.d.ts
839
910
  declare function toApiMessage(message: unknown): ApiMessage;
911
+ /**
912
+ * The CLI's MCP status, as `McpServerStatusInfo`.
913
+ *
914
+ * The narrowing is the point: the SDK's config object carries `env` for stdio
915
+ * servers and `headers` for HTTP ones, and both routinely hold API tokens. This
916
+ * is the one place they are dropped, so no client — dashboard, phone, or a host
917
+ * app reading the REST route — can turn "show me my MCP servers" into a
918
+ * credential dump. Only the connection's identity survives.
919
+ */
920
+ declare function mcpStatusInfo(status: McpServerStatus): McpServerStatusInfo;
921
+ /** The half of the SDK's `ModelInfo` this package forwards. Structurally typed so
922
+ * the mapping can be unit-tested without a live query. */
923
+ type SdkModelInfo = {
924
+ value: string;
925
+ resolvedModel?: string;
926
+ displayName: string;
927
+ description?: string; /** Per-model reasoning efforts, when the SDK reports them (0.3.221+). */
928
+ supportedEffortLevels?: string[];
929
+ supportsEffort?: boolean;
930
+ };
931
+ declare function modelOptionsFromSdk(models: readonly SdkModelInfo[]): ModelOption[];
840
932
  /**
841
933
  * Map one SDKMessage to a wire-protocol event body, or null for messages the runner
842
934
  * consumes itself (system_init and session-state changes carry runner state and are
@@ -844,5 +936,532 @@ declare function toApiMessage(message: unknown): ApiMessage;
844
936
  */
845
937
  declare function normalizeSdkMessage(msg: SDKMessage): SessionEventBody | null;
846
938
  //#endregion
847
- export { AiSdkRunner, type AiSdkRunnerConfig, type AiSdkSessionState, type BridgeAnswer, BrowserBridgeExecutor, type BrowserBridgeExecutorOptions, type ClaudeAuthProbe, type ClaudeAuthStatus, type DeferredDispatch, DeferredExecutor, type DeferredExecutorOptions, type EngineSessionOptions, type HistoryFn, type HostFetch, InputQueue, type McpConnection, type ParkedExecution, type PendingEntry, type PendingKind, type PendingOutcome, PendingRequestRegistry, type PendingToolCall, type PermissionDecision, type QueryFn, QuickJsExecutor, type QuickJsExecutorOptions, type RegisterOptions, type Runner, type RunnerSnapshot, type SessionEventListener, SessionRunner, type SessionRunnerConfig, type SettledBy, type ToolCallOutput, type ToolContext, type ToolContextOptions, type ToolDefinition, type ToolExecutionCall, type ToolExecutionDispatch, type ToolExecutionResult, type ToolExecutor, type ToolTrust, type WebFetchDigest, type WebFetchFn, type WebFetchOptions, type WebFetchResult, checkClaudeAuth, connectMcpTools, createEngineSession, createToolContext, createWebFetch, htmlToMarkdown, isHostAllowed, isPrivateAddress, normalizeSdkMessage, resolveBundledClaudeExecutable, toApiMessage, toExecutionResult, withMcpTools };
939
+ //#region src/engines/adapter.d.ts
940
+ /**
941
+ * A probe's verdict on one profile's credentials. 'unknown' means the probe
942
+ * could not run at all — which is NOT evidence of a missing login and must
943
+ * never be surfaced as one (the `checkClaudeAuth` discipline, generalized).
944
+ */
945
+ type EngineAvailability = {
946
+ available: true;
947
+ } | {
948
+ available: false;
949
+ reason: string;
950
+ } | {
951
+ available: 'unknown';
952
+ };
953
+ /**
954
+ * A model catalog shipped with the release — the answer to "what can a create
955
+ * form offer" with no process spawned, correct from a gateway's first request.
956
+ *
957
+ * Never contains a 'default' sentinel row (a choice, not a model — forms add
958
+ * their own "Profile default" row mapping to an unset model). Staleness is
959
+ * bounded by the release cadence: the release checklist re-runs each catalog's
960
+ * extraction procedure (documented in its file header) and diffs.
961
+ */
962
+ type ModelCatalog = {
963
+ models: ModelOption[]; /** Source + date, for the release-checklist refresh. Not served. */
964
+ provenance: string;
965
+ };
966
+ type EngineRunnerRequest = {
967
+ config: SessionRunnerConfig;
968
+ profile?: ProfileInfo;
969
+ /** Rebuild a parked session instead of starting fresh. Engines that cannot
970
+ * rehydrate throw. */
971
+ restore?: RunnerSnapshot;
972
+ };
973
+ /**
974
+ * One engine, as the server consumes it: its capability record, its shipped
975
+ * model catalog, a credential probe, and a runner factory. The claude adapter
976
+ * wraps `SessionRunner` without behaviour change; the codex adapter owns the
977
+ * `codex app-server` integration; the provider adapter is a pseudo-adapter —
978
+ * its runners are built by the host's `createEngineRunner` hook, so its
979
+ * `createRunner` throws and the server routes around it.
980
+ */
981
+ interface EngineAdapter {
982
+ readonly engine: ProfileEngine;
983
+ /** Must deep-equal ENGINE_CAPABILITIES[engine] — asserted by a core test, so
984
+ * the protocol's browser-safe defaults can never drift from the adapter. */
985
+ readonly capabilities: EngineCapabilities;
986
+ readonly catalog: ModelCatalog;
987
+ /**
988
+ * Probe whether `profile`'s credentials are usable under `env` — the full
989
+ * session environment the real assembly path produces, never a delta (codex
990
+ * replaces the child env wholesale, and a delta would strand HOME/PATH and
991
+ * the auth chain with it). Never rejects.
992
+ */
993
+ checkAvailability(profile: ProfileInfo, env: Record<string, string | undefined>): Promise<EngineAvailability>;
994
+ /** Build a Runner. Throwing fails the create (session POST 500s, job fails). */
995
+ createRunner(request: EngineRunnerRequest): Runner | Promise<Runner>;
996
+ /**
997
+ * List the engine's on-disk resumable sessions (`GET /sdk-sessions`) —
998
+ * present exactly when the capability record's `listSessions` is true. Must
999
+ * not require a live session: the codex adapter answers over a short-lived
1000
+ * `thread/list` app-server child it closes before returning; the claude
1001
+ * adapter reads the Agent SDK's store directly. `env` follows the
1002
+ * checkAvailability contract (the profile's complete session environment,
1003
+ * never a delta). `dir` narrows to one project directory; `limit`/`offset`
1004
+ * page the newest-first result.
1005
+ */
1006
+ listSessions?(options: {
1007
+ profile?: ProfileInfo;
1008
+ env: Record<string, string | undefined>;
1009
+ dir?: string;
1010
+ limit?: number;
1011
+ offset?: number;
1012
+ }): Promise<SdkSessionSummary[]>;
1013
+ }
1014
+ /** The in-repo adapter for an engine. An absent `engine` means 'claude'. */
1015
+ declare function getEngineAdapter(engine: ProfileEngine | undefined): EngineAdapter;
1016
+ //#endregion
1017
+ //#region src/engines/claude/adapter.d.ts
1018
+ /**
1019
+ * The Claude engine as an adapter — a thin, behaviourally inert wrapper:
1020
+ * `SessionRunner` unchanged, `checkClaudeAuth` as the probe, the static
1021
+ * catalog for create forms. Exists so catalogs, capabilities and availability
1022
+ * have one shape across engines; the runner itself is exactly what
1023
+ * `registry.prepare()` builds.
1024
+ */
1025
+ declare const claudeAdapter: EngineAdapter;
1026
+ //#endregion
1027
+ //#region src/engines/claude/catalog.d.ts
1028
+ /**
1029
+ * The Claude engine's model catalog — what a create form offers before any
1030
+ * session has run.
1031
+ *
1032
+ * **Refresh procedure** (release checklist): run `supportedModels()` on a
1033
+ * throwaway SDK query (no tokens spent) and re-apply the shaping rules of
1034
+ * `modelOptionsFromSdk` (`src/normalize.ts`) at authoring time: drop the
1035
+ * `default` sentinel row, derive display names from resolved ids where
1036
+ * unambiguous, mark the newest of each family `primary`, sort by family rank.
1037
+ * A unit test replays the raw extraction through `modelOptionsFromSdk` and
1038
+ * asserts these rows match, so the rules cannot drift.
1039
+ *
1040
+ * Two things the live `capabilities` event can never offer:
1041
+ * - rows for **older models** the CLI no longer reports (hand-maintained, the
1042
+ * accepted cost of a static catalog; the CLI silently downgrades an effort a
1043
+ * model doesn't support, so `reasoningEfforts` is omitted on them and the
1044
+ * engine default set applies);
1045
+ * - an answer on a **cold server**. The live event still exists and remains
1046
+ * the in-session truth for the model switcher; this catalog is the
1047
+ * create-form truth.
1048
+ *
1049
+ * `defaultModel` is deliberately NOT here: a claude profile's default is the
1050
+ * operator's CLI config, unknowable statically.
1051
+ */
1052
+ declare const CLAUDE_CATALOG: ModelCatalog;
1053
+ //#endregion
1054
+ //#region src/engines/codex/types.d.ts
1055
+ /**
1056
+ * Structural mirror of the slice of the `codex app-server` JSON-RPC v2 surface
1057
+ * this engine consumes. Local on purpose: no published client for this
1058
+ * protocol exists, the shapes are regenerated from the binary itself
1059
+ * (`codex app-server generate-json-schema --out <dir>`, verified 2026-08-05
1060
+ * against 0.146.0), and every open-ended axis is a plain string so a newer
1061
+ * binary degrades to the unknown-item path instead of a type error.
1062
+ *
1063
+ * Naming note: the v2 surface is camelCase (`aggregatedOutput`, `exitCode`,
1064
+ * `localImage`) where `codex exec`'s JSONL — the retired first transport, and
1065
+ * what OpenAI's own docs mostly show — is snake_case. The two vocabularies
1066
+ * look alike but are not interchangeable.
1067
+ */
1068
+ /** `TokenUsageBreakdown` — one entry of `thread/tokenUsage/updated`. OpenAI
1069
+ * accounting: `inputTokens` INCLUDES the cached share (the relation the
1070
+ * runner's subtraction assumes, asserted in `smoke:codex`). */
1071
+ type AppServerTokenUsage = {
1072
+ inputTokens: number;
1073
+ cachedInputTokens: number; /** Default 0 in the schema; absent in some payloads. */
1074
+ cacheWriteInputTokens?: number;
1075
+ outputTokens: number;
1076
+ reasoningOutputTokens: number;
1077
+ totalTokens: number;
1078
+ };
1079
+ type AppServerAgentMessageItem = {
1080
+ id: string;
1081
+ type: 'agentMessage';
1082
+ text: string;
1083
+ };
1084
+ /** `summary` is what streams by default (`item/reasoning/summaryTextDelta`);
1085
+ * `content` is raw CoT and only populated when the operator's config asks. */
1086
+ type AppServerReasoningItem = {
1087
+ id: string;
1088
+ type: 'reasoning';
1089
+ content?: string[];
1090
+ summary?: string[];
1091
+ };
1092
+ type AppServerCommandExecutionItem = {
1093
+ id: string;
1094
+ type: 'commandExecution';
1095
+ command: string;
1096
+ aggregatedOutput?: string;
1097
+ exitCode?: number | null; /** 'inProgress' | 'completed' | 'failed' | 'declined' — open. */
1098
+ status: string;
1099
+ };
1100
+ /** v2 `kind` is an object (`{type: 'add'|'delete'|'update', move_path?}`) —
1101
+ * the snake_case JSONL's was a bare string; mapped defensively. */
1102
+ type AppServerFileChangeItem = {
1103
+ id: string;
1104
+ type: 'fileChange';
1105
+ changes: Array<{
1106
+ path: string;
1107
+ kind: string | {
1108
+ type: string;
1109
+ };
1110
+ diff?: string;
1111
+ }>;
1112
+ status: string;
1113
+ };
1114
+ type AppServerMcpToolCallItem = {
1115
+ id: string;
1116
+ type: 'mcpToolCall';
1117
+ server: string;
1118
+ tool: string;
1119
+ arguments: unknown;
1120
+ result?: unknown;
1121
+ error?: {
1122
+ message: string;
1123
+ } | null;
1124
+ status: string;
1125
+ };
1126
+ type AppServerWebSearchItem = {
1127
+ id: string;
1128
+ type: 'webSearch';
1129
+ query: string;
1130
+ };
1131
+ /**
1132
+ * A picture the model made with codex's built-in `image_gen` tool.
1133
+ *
1134
+ * `savedPath` is an absolute path on the **host** — by default under
1135
+ * `$CODEX_HOME/generated_images/`, or inside the workspace when the model was
1136
+ * told the asset belongs to the project. It is the only reference we get: the
1137
+ * app-server never sends the bytes, and neither do we (the event log carries
1138
+ * references, never base64 — see the protocol's note on attachments).
1139
+ *
1140
+ * `result` is an undocumented free-form string. Treated as untrusted length:
1141
+ * short values are shown, anything long enough to be an encoded image is not.
1142
+ */
1143
+ type AppServerImageGenerationItem = {
1144
+ id: string;
1145
+ type: 'imageGeneration';
1146
+ status: string;
1147
+ revisedPrompt?: string | null;
1148
+ result: string;
1149
+ savedPath?: string;
1150
+ };
1151
+ /** The model *looked at* an image on disk (`path`, host-absolute). */
1152
+ type AppServerImageViewItem = {
1153
+ id: string;
1154
+ type: 'imageView';
1155
+ path: string;
1156
+ };
1157
+ /** The user's own message, echoed back as an item — dropped (the runner
1158
+ * already emitted its `user_message`). */
1159
+ type AppServerUserMessageItem = {
1160
+ id: string;
1161
+ type: 'userMessage';
1162
+ content?: unknown;
1163
+ };
1164
+ type AppServerItem = AppServerAgentMessageItem | AppServerReasoningItem | AppServerCommandExecutionItem | AppServerFileChangeItem | AppServerMcpToolCallItem | AppServerWebSearchItem | AppServerImageGenerationItem | AppServerImageViewItem | AppServerUserMessageItem;
1165
+ /** The `Turn` object of `turn/started` / `turn/completed`. */
1166
+ type AppServerTurn = {
1167
+ id: string; /** 'inProgress' | 'completed' | 'failed' | 'interrupted' — open. */
1168
+ status: string;
1169
+ error?: {
1170
+ message: string;
1171
+ } | null;
1172
+ };
1173
+ /**
1174
+ * One historical turn as `thread/resume` / `thread/read {includeTurns: true}`
1175
+ * return it: the same `ThreadItem` vocabulary the live `item/completed`
1176
+ * notifications carry (so the live mapping replays it unchanged), plus an
1177
+ * `itemsView` marker ('full' | 'summary' | 'notLoaded') saying how much of
1178
+ * `items` was actually loaded. Measured against 0.146.0: both surfaces return
1179
+ * 'full' items in chronological order.
1180
+ */
1181
+ type AppServerHistoryTurn = {
1182
+ id: string;
1183
+ items?: AppServerItem[];
1184
+ itemsView?: string;
1185
+ status?: string;
1186
+ };
1187
+ /**
1188
+ * One `thread/list` row (the summary Thread shape — its `turns` is always
1189
+ * empty on list responses). Timestamps are epoch **seconds** (the protocol's
1190
+ * summaries want ms). `id` is what `CreateSessionRequest.resume` feeds
1191
+ * `thread/resume`; the row's separate `sessionId` field is not it.
1192
+ */
1193
+ type AppServerThreadSummary = {
1194
+ id: string; /** Operator-set thread name, when one exists. */
1195
+ name?: string | null; /** First user message — the natural summary line. */
1196
+ preview?: string | null;
1197
+ createdAt?: number | null;
1198
+ updatedAt?: number | null;
1199
+ cwd?: string | null; /** Ephemeral threads are never materialized on disk — not resumable. */
1200
+ ephemeral?: boolean;
1201
+ gitInfo?: {
1202
+ branch?: string | null;
1203
+ } | null;
1204
+ };
1205
+ /** `thread/list` result: one page plus an opaque continuation cursor. */
1206
+ type AppServerThreadListResponse = {
1207
+ data?: AppServerThreadSummary[];
1208
+ nextCursor?: string | null;
1209
+ };
1210
+ type AppServerUserInput = {
1211
+ type: 'text';
1212
+ text: string;
1213
+ } | {
1214
+ type: 'localImage';
1215
+ path: string;
1216
+ };
1217
+ /**
1218
+ * One live `codex app-server` child as the runner consumes it. The real
1219
+ * implementation (`process.ts`) spawns the binary and frames JSON-RPC
1220
+ * over its stdio; unit tests inject a scripted one — no process, no
1221
+ * credentials.
1222
+ */
1223
+ type AppServerConnection = {
1224
+ /** Client→server request. Rejects on a JSON-RPC error response, a dead
1225
+ * child, or a closed connection. */
1226
+ request(method: string, params?: unknown): Promise<unknown>; /** Client→server notification (fire and forget). */
1227
+ notify(method: string, params?: unknown): void; /** Server→client notifications. One handler (the runner). */
1228
+ onNotification(handler: (method: string, params: unknown) => void): void;
1229
+ /** Server→client REQUESTS (approvals live here): the handler's resolution is
1230
+ * sent back as the JSON-RPC result; a throw becomes an error response. `id`
1231
+ * is the wire request id — `serverRequest/resolved` names it when codex
1232
+ * settles a request on its own (auto-resolution), so the runner can retire
1233
+ * the matching pending approval instead of leaving a stale card. */
1234
+ onRequest(handler: (method: string, params: unknown, id: string | number) => Promise<unknown>): void;
1235
+ /** Fires once when the child exits or the pipe breaks — NOT on `close()`.
1236
+ * The message carries an exit summary and a stderr tail for diagnostics. */
1237
+ onClose(handler: (message: string) => void): void; /** Tear the child down (session close). Suppresses the onClose callback. */
1238
+ close(): void;
1239
+ };
1240
+ type AppServerConnectOptions = {
1241
+ /** Complete child environment — a provided spawn env replaces process.env,
1242
+ * never merges with it (CODEX_HOME pin already applied). */
1243
+ env: Record<string, string>;
1244
+ };
1245
+ /** The injectable connection factory: `connectAppServer` under the resolved
1246
+ * binary in production, a scripted peer in tests. */
1247
+ type AppServerConnectFn = (options: AppServerConnectOptions) => AppServerConnection;
1248
+ //#endregion
1249
+ //#region src/engines/codex/adapter.d.ts
1250
+ /**
1251
+ * The codex binary sessions will run: the per-platform package installed next
1252
+ * to `@openai/codex`, `vendor/<target-triple>/bin/codex` — the same file the
1253
+ * npm wrapper's own `bin/codex.js` launcher execs. Probing this binary rather
1254
+ * than whatever `codex` is on PATH means the availability answer is about the
1255
+ * executable sessions will actually run. Undefined when it can't be found;
1256
+ * callers degrade to 'unknown'.
1257
+ */
1258
+ declare function resolveBundledCodexExecutable(): string | undefined;
1259
+ /**
1260
+ * CODEX_HOME's threads over ONE short-lived `codex app-server` child: the
1261
+ * runner's own handshake (`experimentalApi` and all — one code path, no
1262
+ * second vocabulary to drift), `thread/list` pages walked by cursor, child
1263
+ * closed before returning. Requires no live session and costs no tokens —
1264
+ * it is how "resume" is offered before anything is running. The `connectFn`
1265
+ * seam exists for the scripted-peer tests; the adapter passes the real
1266
+ * spawn.
1267
+ */
1268
+ declare function listCodexSessions(options: {
1269
+ connectFn: AppServerConnectFn;
1270
+ profile?: ProfileInfo;
1271
+ env: Record<string, string | undefined>;
1272
+ dir?: string;
1273
+ limit?: number;
1274
+ offset?: number;
1275
+ }): Promise<SdkSessionSummary[]>;
1276
+ /**
1277
+ * OpenAI Codex as an engine: the codex CLI binary driven over its `app-server`
1278
+ * JSON-RPC surface — structurally the Claude engine's sibling (a local agent
1279
+ * binary with sessions, sandboxing and resume, resolving its own credentials
1280
+ * from the operator's environment). `@openai/codex` — the npm package that
1281
+ * carries the binary — is an **optional peer**: absent, every codex profile
1282
+ * reports unavailable and createRunner throws the same message, and no
1283
+ * consumer downloads a ~40 MB per-platform binary it never uses.
1284
+ */
1285
+ declare const codexAdapter: EngineAdapter;
1286
+ //#endregion
1287
+ //#region src/engines/codex/catalog.d.ts
1288
+ /**
1289
+ * The Codex engine's model catalog, seeded from the binary's own embedded
1290
+ * presets — `@openai/codex@0.146.0` ships its model table inside the
1291
+ * executable, and that table (not the SDK's stale `ModelReasoningEffort`
1292
+ * union) is the truth about which reasoning efforts each model takes.
1293
+ *
1294
+ * **Refresh procedure** (release checklist): extract the embedded JSON from
1295
+ * the platform binary and diff —
1296
+ *
1297
+ * node -e 'const d=require("fs").readFileSync(process.argv[1]);
1298
+ * const s=d.indexOf(`{\n "models": [`);
1299
+ * let i=s,n=0; do{n+=(d[i]===123)-(d[i]===125);i++}while(n);
1300
+ * const c=JSON.parse(d.slice(s,i));
1301
+ * for(const m of c.models) console.log(m.slug, m.display_name,
1302
+ * m.visibility, m.supported_reasoning_levels.map(l=>l.effort).join(","))'\
1303
+ * "$(node -p 'require.resolve("@openai/codex-darwin-arm64/package.json").replace("package.json","vendor/aarch64-apple-darwin/bin/codex")')"
1304
+ *
1305
+ * Mapping decisions:
1306
+ * - the internal `codex-auto-review` row is dropped (the codex analogue of
1307
+ * dropping the CLI's `default` sentinel);
1308
+ * - `primary` mirrors the binary's own `visibility` field ('list' = shown in
1309
+ * its picker, 'hide' = its "older models"), so both UIs group the way
1310
+ * codex's own picker does;
1311
+ * - `reasoningEfforts` carries `supported_reasoning_levels` verbatim — note
1312
+ * `max`/`ultra` beyond the SDK union; trust the binary, keep strings open.
1313
+ */
1314
+ declare const CODEX_CATALOG: ModelCatalog;
1315
+ //#endregion
1316
+ //#region src/engines/codex/runner.d.ts
1317
+ type CodexRunnerConfig = CreateSessionRequest & {
1318
+ /** The injectable connection factory. The codex adapter passes
1319
+ * `connectAppServer` under the resolved binary; unit tests pass a scripted
1320
+ * peer. Required — this class never spawns anything itself. */
1321
+ connectFn: AppServerConnectFn;
1322
+ /** Base environment for the codex child. Defaults to process.env. Passed to
1323
+ * spawn **complete** — a child env replaces, never merges. */
1324
+ env?: Record<string, string | undefined>; /** CODEX_HOME pin from the profile (auth, config.toml, thread storage). */
1325
+ codexHome?: string;
1326
+ /** Timeout for pending approvals when the request itself doesn't set one.
1327
+ * Default 300000 — the SessionRunner default. */
1328
+ defaultApprovalTimeoutMs?: number;
1329
+ /** With `resume`: replay the thread's prior turns as `replay: true` events
1330
+ * before anything else, so late-attaching clients get a full transcript —
1331
+ * the SessionRunner option, same name, same default (true). */
1332
+ backfillHistory?: boolean;
1333
+ };
1334
+ /**
1335
+ * The Codex engine, over the binary's `app-server` JSON-RPC surface: ONE
1336
+ * `codex app-server` child per *session* (spawned lazily, held across turns),
1337
+ * streaming `item/agentMessage/delta` and the reasoning deltas token-by-token
1338
+ * (`streaming: 'token'`). Follows `SessionRunner`'s event-log/seq/status
1339
+ * discipline with `AiSdkRunner`'s turn-chain (one turn at a time; sendMessage
1340
+ * queues). The first codex transport was `codex exec --experimental-json` (one
1341
+ * child per turn) — retired because its JSONL carries no partial messages, so
1342
+ * a turn could never stream.
1343
+ *
1344
+ * A dead child is a failed *turn*, not a failed session: the thread persists
1345
+ * on disk, the connection is dropped, and the next message spawns a fresh
1346
+ * child that `thread/resume`s the same thread id.
1347
+ */
1348
+ declare class CodexRunner implements Runner {
1349
+ #private;
1350
+ readonly id: string;
1351
+ readonly createdAt: number;
1352
+ constructor(config: CodexRunnerConfig, id?: string);
1353
+ get status(): SessionStatus;
1354
+ get sdkSessionId(): string | undefined;
1355
+ get lastSeq(): number;
1356
+ get pendingApprovals(): PermissionRequest[];
1357
+ info(): SessionInfo;
1358
+ /** Host-facing rename: writes `meta.title`, which `#title()` prefers. Clearing
1359
+ * it (undefined) restores the derived title. The engine is never told. */
1360
+ setTitle(title: string | undefined): void;
1361
+ start(): Promise<void>;
1362
+ sendMessage(text: string, attachments?: readonly AttachmentInput[]): void;
1363
+ /** Resolve a pending approval. Returns false if the id is unknown (e.g.
1364
+ * timed out, or already settled by codex itself). */
1365
+ resolvePermission(requestId: string, decision: PermissionDecision): boolean;
1366
+ interrupt(): Promise<void>;
1367
+ setPermissionMode(mode: PermissionMode): Promise<void>;
1368
+ setModel(model?: string): Promise<void>;
1369
+ fail(message: string): void;
1370
+ close(reason?: 'client' | 'server' | 'error'): void;
1371
+ subscribe(listener: SessionEventListener, afterSeq?: number): () => void;
1372
+ /**
1373
+ * The session's MCP servers, live from the binary.
1374
+ *
1375
+ * Two sources merged, because codex splits them: `mcpServerStatus/list` says
1376
+ * what is configured and what each server exposes (including every tool's
1377
+ * full JSON Schema, which the Agent SDK does not give us), and the
1378
+ * `mcpServer/startupStatus/updated` notifications say which of them are
1379
+ * actually up.
1380
+ *
1381
+ * Answers **before the session has connected**, over a throwaway child, for
1382
+ * the same reason the skill list does: a codex session spawns nothing until
1383
+ * it has work, and a panel that said "no MCP servers configured" until the
1384
+ * first turn would be stating something false about the operator's config.
1385
+ * The request blocks until the servers are enumerated (measured: complete on
1386
+ * the very first call), so there is no half-populated answer to race.
1387
+ *
1388
+ * Resolves undefined only when there is genuinely nothing to say — the
1389
+ * session is closed, or the child could not be spoken to. The route turns
1390
+ * that into a 501.
1391
+ *
1392
+ * **Listing only.** There is no per-server reconnect or toggle on this
1393
+ * transport — hence no `reconnectMcpServer`/`setMcpServerEnabled` here, and
1394
+ * `ENGINE_CAPABILITIES.codex.mcpServerActions: false` so clients render the
1395
+ * panel read-only instead of offering buttons that cannot work.
1396
+ */
1397
+ mcpServers(): Promise<McpServerStatusInfo[] | undefined>;
1398
+ }
1399
+ //#endregion
1400
+ //#region src/engines/codex/process.d.ts
1401
+ /**
1402
+ * Spawn one `codex app-server` child and frame JSON-RPC over its stdio — the
1403
+ * real {@link AppServerConnectFn}. The child's env is passed **complete**
1404
+ * (a provided spawn env replaces process.env, never merges with it), with the
1405
+ * profile's CODEX_HOME pin already applied by the runner.
1406
+ *
1407
+ * No spawn cwd: the working directory is a thread/turn parameter, and a cwd
1408
+ * that doesn't exist should fail the *turn* with codex's own error, not the
1409
+ * spawn.
1410
+ */
1411
+ declare function connectAppServer(options: {
1412
+ executable: string;
1413
+ env: Record<string, string>;
1414
+ }): AppServerConnection;
1415
+ //#endregion
1416
+ //#region src/engines/codex/jsonrpc.d.ts
1417
+ /**
1418
+ * A JSON-RPC error response from the peer, or one we return to it. `code`
1419
+ * follows the JSON-RPC 2.0 reserved ranges (-32601 = method not found).
1420
+ */
1421
+ declare class JsonRpcError extends Error {
1422
+ readonly code: number;
1423
+ constructor(code: number, message: string);
1424
+ }
1425
+ /**
1426
+ * JSON-RPC over a `codex app-server` child's stdio: **newline-delimited JSON**,
1427
+ * one message per line, and — verified against 0.146.0 — an envelope *without*
1428
+ * the `jsonrpc: "2.0"` field (`{id, method, params}` / `{id, result}` /
1429
+ * `{id, error}`; the binary's own schema marks only those required). Server→
1430
+ * client notifications additionally carry a top-level `emittedAtMs`, ignored
1431
+ * here.
1432
+ *
1433
+ * Transport only: no method knowledge, no process ownership. The process
1434
+ * wrapper (`process.ts`) owns the child and calls {@link fail} when it dies so
1435
+ * every in-flight request rejects instead of hanging.
1436
+ */
1437
+ declare class JsonRpcStdioConnection {
1438
+ #private;
1439
+ constructor(options: {
1440
+ input: Readable;
1441
+ output: Writable;
1442
+ });
1443
+ request(method: string, params?: unknown): Promise<unknown>;
1444
+ notify(method: string, params?: unknown): void;
1445
+ onNotification(handler: (method: string, params: unknown) => void): void;
1446
+ onRequest(handler: (method: string, params: unknown, id: string | number) => Promise<unknown>): void;
1447
+ /** Reject everything in flight and refuse new traffic — the child is gone
1448
+ * (or the session is over). Idempotent. */
1449
+ fail(message: string): void;
1450
+ }
1451
+ //#endregion
1452
+ //#region src/engines/provider/adapter.d.ts
1453
+ /**
1454
+ * The model-agnostic provider engine as a pseudo-adapter: capabilities and an
1455
+ * env-var probe live here, but its runners are assembled by the host's
1456
+ * `createEngineRunner` hook (which is where provider credentials are resolved
1457
+ * and model SDKs are imported — neither belongs in this repo's import graph).
1458
+ * The server routes provider creates to the hook; `createRunner` here throws
1459
+ * so a mis-routed call fails loudly instead of quietly building nothing.
1460
+ *
1461
+ * The catalog is empty by the same token: provider model ids are operator-
1462
+ * declared per profile (`provider.models`), not shipped with releases.
1463
+ */
1464
+ declare const providerAdapter: EngineAdapter;
1465
+ //#endregion
1466
+ export { AiSdkRunner, type AiSdkRunnerConfig, type AiSdkSessionState, type AppServerConnectFn, type AppServerConnectOptions, type AppServerConnection, type AppServerHistoryTurn, type AppServerItem, type AppServerThreadListResponse, type AppServerThreadSummary, type AppServerTokenUsage, type AppServerTurn, type AppServerUserInput, type AttachmentInput, type AttachmentKind, type BridgeAnswer, BrowserBridgeExecutor, type BrowserBridgeExecutorOptions, CLAUDE_CATALOG, CODEX_CATALOG, type ClaudeAuthProbe, type ClaudeAuthStatus, CodexRunner, type CodexRunnerConfig, type DeferredDispatch, DeferredExecutor, type DeferredExecutorOptions, type EngineAdapter, type EngineAvailability, type EngineRunnerRequest, type EngineSessionOptions, type HistoryFn, type HostFetch, InputQueue, JsonRpcError, JsonRpcStdioConnection, type McpConnection, type ModelCatalog, type ParkedExecution, type PendingEntry, type PendingKind, type PendingOutcome, PendingRequestRegistry, type PendingToolCall, type PermissionDecision, type QueryFn, QuickJsExecutor, type QuickJsExecutorOptions, type RegisterOptions, type Runner, type RunnerSnapshot, SUPPORTED_ATTACHMENT_TYPES, type SessionEventListener, SessionRunner, type SessionRunnerConfig, type SettledBy, type ToolCallOutput, type ToolContext, type ToolContextOptions, type ToolDefinition, type ToolExecutionCall, type ToolExecutionDispatch, type ToolExecutionResult, type ToolExecutor, type ToolTrust, type WebFetchDigest, type WebFetchFn, type WebFetchOptions, type WebFetchResult, attachmentContentBlocks, attachmentKind, attachmentRef, checkClaudeAuth, claudeAdapter, codexAdapter, connectAppServer, connectMcpTools, createEngineSession, createToolContext, createWebFetch, getEngineAdapter, htmlToMarkdown, isHostAllowed, isPrivateAddress, listCodexSessions, mcpStatusInfo, modelOptionsFromSdk, normalizeMediaType, normalizeSdkMessage, providerAdapter, resolveBundledClaudeExecutable, resolveBundledCodexExecutable, toApiMessage, toExecutionResult, withMcpTools };
848
1467
  //# sourceMappingURL=index.d.mts.map