stitchkit 0.54.0 → 0.55.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/README.md +4 -1
- package/dist/browser/socket-io.d.ts +11 -1
- package/dist/browser/socket-io.d.ts.map +1 -1
- package/dist/cli.js +14 -9
- package/dist/contract/file-ref.d.ts +13 -0
- package/dist/contract/file-ref.d.ts.map +1 -0
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.d.ts.map +1 -1
- package/dist/contract/index.js +21 -17
- package/dist/files/boundary.d.ts +52 -0
- package/dist/files/boundary.d.ts.map +1 -0
- package/dist/files.d.ts +3 -0
- package/dist/files.d.ts.map +1 -0
- package/dist/files.js +16 -0
- package/dist/{index-7vb44hy8.js → index-0gv7k0ra.js} +127 -92
- package/dist/index-1bx83sw4.js +4 -0
- package/dist/index-1k16zv57.js +269 -0
- package/dist/index-6k1937bx.js +20 -0
- package/dist/{index-bmnhqtya.js → index-7eq9va6e.js} +1 -4
- package/dist/{index-yxpe3phd.js → index-cby4ar3v.js} +1 -18
- package/dist/index-h60df7rj.js +110 -0
- package/dist/{index-yez419px.js → index-js7yexng.js} +19 -6
- package/dist/index-k4dftwf7.js +66 -0
- package/dist/{index-z7761jk2.js → index-npye5kt7.js} +16 -22
- package/dist/{index-b15rtha1.js → index-pzc32v75.js} +61 -3
- package/dist/{index-e1es808r.js → index-qh4xevf5.js} +1 -1
- package/dist/{index-gvha32jh.js → index-qx84bqzk.js} +2 -2
- package/dist/{index-pfqjb5xy.js → index-rgd18hx3.js} +23 -5
- package/dist/index-sbdmyz75.js +18 -0
- package/dist/{index-173tvqcp.js → index-v4bbq3p4.js} +9 -114
- package/dist/index.js +162 -35
- package/dist/node.js +30 -27
- package/dist/observability/index.js +28 -25
- package/dist/react.js +2 -2
- package/dist/realtime/contract.d.ts +9 -0
- package/dist/realtime/contract.d.ts.map +1 -1
- package/dist/realtime/index.d.ts +2 -1
- package/dist/realtime/index.d.ts.map +1 -1
- package/dist/realtime/request.d.ts +21 -0
- package/dist/realtime/request.d.ts.map +1 -0
- package/dist/realtime/socket.d.ts +3 -0
- package/dist/realtime/socket.d.ts.map +1 -1
- package/dist/remote.d.ts +9 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +79 -0
- package/dist/server/context-contribution.d.ts +10 -0
- package/dist/server/context-contribution.d.ts.map +1 -0
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +133 -88
- package/dist/server/lifecycle.d.ts +4 -0
- package/dist/server/lifecycle.d.ts.map +1 -0
- package/dist/server/middleware/auth.d.ts +35 -7
- package/dist/server/middleware/auth.d.ts.map +1 -1
- package/dist/server/types.d.ts +1 -1
- package/dist/server/types.d.ts.map +1 -1
- package/dist/testing/surface-conformance.d.ts +47 -0
- package/dist/testing/surface-conformance.d.ts.map +1 -0
- package/dist/testing/surface-manifest.d.ts +156 -0
- package/dist/testing/surface-manifest.d.ts.map +1 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +366 -3
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/async-operation.d.ts +168 -0
- package/dist/tools/async-operation.d.ts.map +1 -0
- package/dist/tools/cli-args.d.ts +1 -1
- package/dist/tools/cli-args.d.ts.map +1 -1
- package/dist/tools/cli-format.d.ts +2 -2
- package/dist/tools/cli-format.d.ts.map +1 -1
- package/dist/tools/cli-wait.d.ts +11 -2
- package/dist/tools/cli-wait.d.ts.map +1 -1
- package/dist/tools/cli.d.ts +2 -0
- package/dist/tools/cli.d.ts.map +1 -1
- package/dist/tools/define-download-tool.d.ts +6 -5
- package/dist/tools/define-download-tool.d.ts.map +1 -1
- package/dist/tools/define-upload-tool.d.ts +3 -1
- package/dist/tools/define-upload-tool.d.ts.map +1 -1
- package/dist/tools/define-wait-tool.d.ts +1 -1
- package/dist/tools/define-wait-tool.d.ts.map +1 -1
- package/dist/tools/download-core.d.ts +5 -10
- package/dist/tools/download-core.d.ts.map +1 -1
- package/dist/tools/lifecycle.d.ts +4 -0
- package/dist/tools/lifecycle.d.ts.map +1 -0
- package/dist/tools/mount-download.d.ts +5 -4
- package/dist/tools/mount-download.d.ts.map +1 -1
- package/dist/tools/mount-upload.d.ts +4 -2
- package/dist/tools/mount-upload.d.ts.map +1 -1
- package/dist/tools/upload-core.d.ts +3 -2
- package/dist/tools/upload-core.d.ts.map +1 -1
- package/dist/tools/view-file.d.ts +4 -3
- package/dist/tools/view-file.d.ts.map +1 -1
- package/dist/tools/wait-core.d.ts +6 -1
- package/dist/tools/wait-core.d.ts.map +1 -1
- package/dist/tools.d.ts +3 -2
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +385 -244
- package/llms-full.txt +417 -27
- package/package.json +10 -2
package/llms-full.txt
CHANGED
|
@@ -33,7 +33,7 @@ realtime, `@tanstack/react-query` + `react-query-kit` for React). See
|
|
|
33
33
|
|
|
34
34
|
## Entrypoints
|
|
35
35
|
|
|
36
|
-
stitchkit ships
|
|
36
|
+
stitchkit ships eleven entrypoints. Each is import-safe for one environment —
|
|
37
37
|
keeping server-only code (`Bun.serve`, the MCP SDK) out of browser bundles.
|
|
38
38
|
|
|
39
39
|
| Import | Use in | Holds |
|
|
@@ -44,12 +44,15 @@ keeping server-only code (`Bun.serve`, the MCP SDK) out of browser bundles.
|
|
|
44
44
|
| `stitchkit/node` | server (Node ≥ 22) | `serveNode` + the runtime-agnostic core — the Node mirror of `/server` |
|
|
45
45
|
| `stitchkit/tools` | server | `createMcpHandler`, `mountMcp`, `mountAgent`, the OAuth provider, native tools |
|
|
46
46
|
| `stitchkit/cli` | server | `createCli` — the CLI transport, light (no MCP SDK / `ai`) |
|
|
47
|
+
| `stitchkit/remote` | browser **and** server | peer-free `implementRemote` for thin HTTP proxy processes |
|
|
48
|
+
| `stitchkit/files` | server (Bun or Node) | peer-free managed local-file boundary |
|
|
47
49
|
| `stitchkit/observability` | server | request/tool event projections — `createObservability`, trace context, sanitisation |
|
|
48
50
|
| `stitchkit/testing` | tests on Bun or Node | in-process generated clients over a real Fetch handler, without a TCP port |
|
|
49
51
|
| `stitchkit/react` | browser | `createCursorQuery`, `createCacheBridge` |
|
|
50
52
|
|
|
51
53
|
Rule of thumb: browser code imports `stitchkit` and `stitchkit/react`; server
|
|
52
|
-
code adds `stitchkit/server` (or `stitchkit/node` on Node) and
|
|
54
|
+
code adds `stitchkit/server` (or `stitchkit/node` on Node) and opts into
|
|
55
|
+
`stitchkit/tools`, `stitchkit/remote` or `stitchkit/files` by capability.
|
|
53
56
|
The full export list of each is in the [API reference](../api/reference.md).
|
|
54
57
|
|
|
55
58
|
## Project layout
|
|
@@ -2777,7 +2780,8 @@ through the contract's typed client:
|
|
|
2777
2780
|
|
|
2778
2781
|
```ts
|
|
2779
2782
|
import { createHttpClient } from 'stitchkit'
|
|
2780
|
-
import {
|
|
2783
|
+
import { implementRemote } from 'stitchkit/remote'
|
|
2784
|
+
import { createStdioMcpServer } from 'stitchkit/tools'
|
|
2781
2785
|
|
|
2782
2786
|
const http = createHttpClient({
|
|
2783
2787
|
baseUrl: 'https://api.example.com',
|
|
@@ -3017,8 +3021,11 @@ import {
|
|
|
3017
3021
|
defineViewFileTool,
|
|
3018
3022
|
defineWaitTool,
|
|
3019
3023
|
} from 'stitchkit/tools'
|
|
3024
|
+
import { createManagedFileBoundary } from 'stitchkit/files'
|
|
3020
3025
|
import { z } from 'zod'
|
|
3021
3026
|
|
|
3027
|
+
const files = await createManagedFileBoundary({ root: '/srv/job-media' })
|
|
3028
|
+
|
|
3022
3029
|
const waitForJob = defineWaitTool({
|
|
3023
3030
|
name: 'wait_for_job',
|
|
3024
3031
|
description: 'Wait for a job to finish',
|
|
@@ -3035,10 +3042,10 @@ const downloadResult = defineDownloadTool({
|
|
|
3035
3042
|
name: 'download_result',
|
|
3036
3043
|
description: 'Download a completed result',
|
|
3037
3044
|
identity: { serviceName: 'jobs', action: 'downloadResult', scope: 'user' },
|
|
3038
|
-
input: z.object({ id: z.string()
|
|
3045
|
+
input: z.object({ id: z.string() }),
|
|
3039
3046
|
resolveUrl: ({ id }) => resolveResultUrl(id),
|
|
3040
|
-
|
|
3041
|
-
|
|
3047
|
+
files,
|
|
3048
|
+
pathFromInput: ({ id }) => `results/${id}.bin`,
|
|
3042
3049
|
})
|
|
3043
3050
|
|
|
3044
3051
|
const uploadInput = defineUploadTool({
|
|
@@ -3046,16 +3053,17 @@ const uploadInput = defineUploadTool({
|
|
|
3046
3053
|
description: 'Upload a local input file',
|
|
3047
3054
|
identity: { serviceName: 'jobs', action: 'uploadInput', scope: 'user' },
|
|
3048
3055
|
output: z.object({ url: z.url() }),
|
|
3049
|
-
|
|
3056
|
+
files,
|
|
3057
|
+
upload: (source, context) => uploadBytes(source.bytes, context.signal),
|
|
3050
3058
|
})
|
|
3051
3059
|
|
|
3052
3060
|
const viewResult = defineViewFileTool({
|
|
3053
3061
|
name: 'view_result',
|
|
3054
3062
|
description: 'Inspect generated media',
|
|
3055
3063
|
identity: { serviceName: 'jobs', action: 'viewResult', scope: 'user' },
|
|
3056
|
-
// Local files are disabled when
|
|
3064
|
+
// Local files are disabled when files is omitted. URL fetches retain SSRF
|
|
3057
3065
|
// protection; use allowPrivateHosts only for an explicitly trusted network.
|
|
3058
|
-
|
|
3066
|
+
files,
|
|
3059
3067
|
})
|
|
3060
3068
|
|
|
3061
3069
|
const runtimeTools = [waitForJob, downloadResult, uploadInput, viewResult]
|
|
@@ -3078,6 +3086,100 @@ same neutral mechanics but do not gain lifecycle or hooks. The raw view-file
|
|
|
3078
3086
|
adapter preserves its content-only MCP envelope while using the same bounded
|
|
3079
3087
|
batch operation.
|
|
3080
3088
|
|
|
3089
|
+
### Async-operation protocol
|
|
3090
|
+
|
|
3091
|
+
For a complete long-running operation, define the linked runtime-only surface
|
|
3092
|
+
once. Stitchkit owns transport names, validation and wait mechanics; the
|
|
3093
|
+
application still owns storage, execution, retries and domain states:
|
|
3094
|
+
|
|
3095
|
+
```ts
|
|
3096
|
+
import {
|
|
3097
|
+
createAsyncOperationSnapshotSchema,
|
|
3098
|
+
defineAsyncOperation,
|
|
3099
|
+
} from 'stitchkit/tools'
|
|
3100
|
+
|
|
3101
|
+
const id = z.object({ id: z.string() })
|
|
3102
|
+
const state = z.object({
|
|
3103
|
+
phase: z.enum(['pending', 'running', 'succeeded']),
|
|
3104
|
+
value: z.string().optional(),
|
|
3105
|
+
})
|
|
3106
|
+
const snapshot = createAsyncOperationSnapshotSchema({
|
|
3107
|
+
failure: z.object({ code: z.string() }),
|
|
3108
|
+
progress: z.object({ current: z.number(), total: z.number() }),
|
|
3109
|
+
})
|
|
3110
|
+
|
|
3111
|
+
const exportOperation = defineAsyncOperation({
|
|
3112
|
+
mode: 'runtime-only',
|
|
3113
|
+
name: 'export',
|
|
3114
|
+
description: 'Export project data',
|
|
3115
|
+
identity: { serviceName: 'exports', action: 'export', scope: 'user' },
|
|
3116
|
+
startInput: z.object({ projectId: z.string() }),
|
|
3117
|
+
id,
|
|
3118
|
+
state,
|
|
3119
|
+
snapshot,
|
|
3120
|
+
start: ({ projectId }) => enqueueExport(projectId),
|
|
3121
|
+
authorize: ({ id }, capability, ctx) => authorizeExport(id, capability, ctx),
|
|
3122
|
+
inspect: ({ id }, ctx) => readExport(id, ctx.signal),
|
|
3123
|
+
classify: (job) => ({ phase: job.phase }),
|
|
3124
|
+
result: {
|
|
3125
|
+
output: z.object({ value: z.string() }),
|
|
3126
|
+
handler: (job) => ({ value: job.value ?? '' }),
|
|
3127
|
+
},
|
|
3128
|
+
})
|
|
3129
|
+
|
|
3130
|
+
const runtimeTools = exportOperation.runtimeTools
|
|
3131
|
+
```
|
|
3132
|
+
|
|
3133
|
+
Every follow-up repeats `authorize`; an opaque id is never authority. Aborting
|
|
3134
|
+
`wait` only stops waiting and never calls optional domain `cancel`. A
|
|
3135
|
+
contract-backed operation uses `bindContractAsyncOperation` with literal methods
|
|
3136
|
+
from a dedicated existing contract, so it creates no second HTTP router or
|
|
3137
|
+
duplicate schemas. Capability keys are narrowed by schema-compatible TypeScript
|
|
3138
|
+
input/output types. At runtime, the binder additionally requires the exact same
|
|
3139
|
+
id and snapshot Zod instances; declare each once and reuse it:
|
|
3140
|
+
|
|
3141
|
+
```ts
|
|
3142
|
+
import { defineContract } from 'stitchkit/contract'
|
|
3143
|
+
import { bindContractAsyncOperation } from 'stitchkit/tools'
|
|
3144
|
+
import { z } from 'zod'
|
|
3145
|
+
|
|
3146
|
+
const operationId = z.object({ id: z.string() })
|
|
3147
|
+
const operationSnapshot = z.object({
|
|
3148
|
+
phase: z.enum(['pending', 'running', 'succeeded', 'failed', 'cancelled']),
|
|
3149
|
+
})
|
|
3150
|
+
|
|
3151
|
+
const operations = defineContract(
|
|
3152
|
+
{ prefix: 'exports' },
|
|
3153
|
+
{
|
|
3154
|
+
start: {
|
|
3155
|
+
method: 'POST', path: '/', desc: 'Start export',
|
|
3156
|
+
input: z.object({ projectId: z.string() }), output: operationId,
|
|
3157
|
+
},
|
|
3158
|
+
status: {
|
|
3159
|
+
method: 'POST', path: '/status', desc: 'Read export status',
|
|
3160
|
+
input: operationId, output: operationSnapshot,
|
|
3161
|
+
},
|
|
3162
|
+
wait: {
|
|
3163
|
+
method: 'POST', path: '/wait', desc: 'Wait for export',
|
|
3164
|
+
input: operationId, output: operationSnapshot,
|
|
3165
|
+
},
|
|
3166
|
+
},
|
|
3167
|
+
)
|
|
3168
|
+
|
|
3169
|
+
const operationHandlers = {
|
|
3170
|
+
start: () => ({ id: 'example' }),
|
|
3171
|
+
status: (): z.output<typeof operationSnapshot> => ({ phase: 'pending' }),
|
|
3172
|
+
wait: (): z.output<typeof operationSnapshot> => ({ phase: 'succeeded' }),
|
|
3173
|
+
}
|
|
3174
|
+
|
|
3175
|
+
const bound = bindContractAsyncOperation({
|
|
3176
|
+
mode: 'contract-backed',
|
|
3177
|
+
contract: operations,
|
|
3178
|
+
capabilities: { start: 'start', status: 'status', wait: 'wait' },
|
|
3179
|
+
handlers: operationHandlers,
|
|
3180
|
+
})
|
|
3181
|
+
```
|
|
3182
|
+
|
|
3081
3183
|
### Explicit raw SDK registration
|
|
3082
3184
|
|
|
3083
3185
|
`rawTools` is deliberately named as an escape hatch. A tool registered there
|
|
@@ -3093,7 +3195,7 @@ const handleMcp = createMcpHandler({
|
|
|
3093
3195
|
serverInfo: { name: 'my-app', version: '1.0.0' },
|
|
3094
3196
|
auth,
|
|
3095
3197
|
services: [service],
|
|
3096
|
-
rawTools: (server) => mountViewFile(server, {
|
|
3198
|
+
rawTools: (server) => mountViewFile(server, { files }),
|
|
3097
3199
|
})
|
|
3098
3200
|
```
|
|
3099
3201
|
|
|
@@ -3234,6 +3336,12 @@ await createCli({
|
|
|
3234
3336
|
})
|
|
3235
3337
|
```
|
|
3236
3338
|
|
|
3339
|
+
`createCli({ signal })` and its wait loop honor an explicit caller
|
|
3340
|
+
`AbortSignal`. Stitchkit does not install a process-global SIGINT handler for
|
|
3341
|
+
ordinary CLI programs: if desired, the application binds SIGINT to an
|
|
3342
|
+
`AbortController` and passes its signal. Aborting wait stops polling only; it
|
|
3343
|
+
does not cancel the underlying job.
|
|
3344
|
+
|
|
3237
3345
|
```json
|
|
3238
3346
|
// package.json
|
|
3239
3347
|
{ "bin": { "myapp": "./dist/cli.js" } }
|
|
@@ -3347,7 +3455,7 @@ same Zod schema an HTTP or MCP call does.
|
|
|
3347
3455
|
|
|
3348
3456
|
| Flag | Effect |
|
|
3349
3457
|
| --------------------- | ---------------------------------------------------------- |
|
|
3350
|
-
| `--json` |
|
|
3458
|
+
| `--json` | Compact success/error JSON records for scripts |
|
|
3351
3459
|
| `--wait` | Block-poll an async result to a terminal state |
|
|
3352
3460
|
| `--wait-timeout <s>` | Override the `--wait` timeout |
|
|
3353
3461
|
| `--output-dir <dir>` | Download result media into a directory |
|
|
@@ -3355,10 +3463,18 @@ same Zod schema an HTTP or MCP call does.
|
|
|
3355
3463
|
| `--dry-run` | Print the resolved call without executing |
|
|
3356
3464
|
| `--help`, `-h` | Usage — top-level or per-command flag table |
|
|
3357
3465
|
|
|
3358
|
-
stdout carries the result; errors and progress go to stderr
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3466
|
+
stdout carries the result; structured errors and progress go to stderr. With
|
|
3467
|
+
`--json`, a success or structured failure is exactly one compact,
|
|
3468
|
+
newline-terminated JSON record on its respective stream; progress and CLI usage
|
|
3469
|
+
diagnostics remain ordinary stderr text. This keeps stdout pipeable and
|
|
3470
|
+
`2>/dev/null` clean. The process exit code carries the error class (`0` ok,
|
|
3471
|
+
`VALIDATION_ERROR → 1`, `UNAUTHORIZED → 2`, `FORBIDDEN → 3`, `NOT_FOUND → 4`,
|
|
3472
|
+
…) — override per app with `exitCodes`.
|
|
3473
|
+
|
|
3474
|
+
Per-command help derives the positional form from the same schema order as the
|
|
3475
|
+
argv parser. For example, a required `action` and optional `profile` render as
|
|
3476
|
+
`Usage: myapp skill <action> [profile] [--flags]`; the argument table also shows
|
|
3477
|
+
`<action> | --action` and `[profile] | --profile`. Boolean fields remain flags.
|
|
3362
3478
|
|
|
3363
3479
|
## `--wait` — background-friendly generation
|
|
3364
3480
|
|
|
@@ -3375,12 +3491,19 @@ await createCli({
|
|
|
3375
3491
|
generate: {
|
|
3376
3492
|
tool: 'get_generation',
|
|
3377
3493
|
poll: (r) => (isRecord(r) && typeof r.id === 'string' ? { id: r.id } : null),
|
|
3378
|
-
done: (r) => isRecord(r) &&
|
|
3494
|
+
done: (r) => isRecord(r) && ['COMPLETED', 'FAILED'].includes(String(r.status)),
|
|
3495
|
+
failed: (r) => isRecord(r) && r.status === 'FAILED',
|
|
3379
3496
|
},
|
|
3380
3497
|
},
|
|
3381
3498
|
})
|
|
3382
3499
|
```
|
|
3383
3500
|
|
|
3501
|
+
`failed` is optional. When it matches either the initial result or a later poll,
|
|
3502
|
+
polling stops and the CLI emits `WAIT_FAILED` on stderr with a non-zero exit;
|
|
3503
|
+
the terminal payload is retained under `details.result`. `failed` is checked
|
|
3504
|
+
before `done`, so overlapping predicates fail closed. A failed poll tool call
|
|
3505
|
+
keeps its own error code, and an elapsed deadline remains `TIMEOUT`.
|
|
3506
|
+
|
|
3384
3507
|
```bash
|
|
3385
3508
|
# foreground
|
|
3386
3509
|
myapp generate "a fox" --wait --output-dir ./out
|
|
@@ -3486,6 +3609,57 @@ runtime. A malformed inbound tuple never reaches the application handler;
|
|
|
3486
3609
|
invalid outbound data throws before Socket.IO publishes it. Rejections call the
|
|
3487
3610
|
optional `onRejected` hook with event, direction, phase and the Zod error.
|
|
3488
3611
|
|
|
3612
|
+
### Protocol generations
|
|
3613
|
+
|
|
3614
|
+
For a distributed producer/consumer pair, put a literal generation first in the
|
|
3615
|
+
first payload object. Zod validates object fields in declaration order, so an
|
|
3616
|
+
incompatible peer is identified before the rest of its payload is interpreted:
|
|
3617
|
+
|
|
3618
|
+
```ts
|
|
3619
|
+
const ReplicationMessage = z.object({
|
|
3620
|
+
v: z.literal(2),
|
|
3621
|
+
item: ReplicatedItem,
|
|
3622
|
+
})
|
|
3623
|
+
|
|
3624
|
+
const realtimeContract = defineRealtimeContract({
|
|
3625
|
+
serverToClient: {
|
|
3626
|
+
replicated: { args: z.tuple([ReplicationMessage]) },
|
|
3627
|
+
},
|
|
3628
|
+
clientToServer: {},
|
|
3629
|
+
})
|
|
3630
|
+
```
|
|
3631
|
+
|
|
3632
|
+
The original `z.ZodError` is retained as `RealtimeRejectedEvent.error.cause`.
|
|
3633
|
+
Because event arguments are a tuple, the first payload's `v` path is
|
|
3634
|
+
`[0, 'v']` (not `['v']`):
|
|
3635
|
+
|
|
3636
|
+
```ts
|
|
3637
|
+
import type { RealtimeRejectedEvent } from 'stitchkit'
|
|
3638
|
+
import { z } from 'zod'
|
|
3639
|
+
|
|
3640
|
+
function isProtocolGenerationMismatch(rejected: RealtimeRejectedEvent): boolean {
|
|
3641
|
+
const cause = rejected.error.cause
|
|
3642
|
+
if (!(cause instanceof z.ZodError)) return false
|
|
3643
|
+
const first = cause.issues[0]
|
|
3644
|
+
return first?.code === 'invalid_value'
|
|
3645
|
+
&& first.path.length === 2
|
|
3646
|
+
&& first.path[0] === 0
|
|
3647
|
+
&& first.path[1] === 'v'
|
|
3648
|
+
}
|
|
3649
|
+
|
|
3650
|
+
const socket = createRealtimeClient(realtimeContract, {
|
|
3651
|
+
url,
|
|
3652
|
+
onRejected: (rejected) => {
|
|
3653
|
+
if (isProtocolGenerationMismatch(rejected)) schedulePeerUpgrade()
|
|
3654
|
+
else reportMalformedRealtimePayload(rejected)
|
|
3655
|
+
},
|
|
3656
|
+
})
|
|
3657
|
+
```
|
|
3658
|
+
|
|
3659
|
+
A generation mismatch means “upgrade the peer”; another schema rejection means
|
|
3660
|
+
“fix the producer or payload”. This stays an application convention, not a core
|
|
3661
|
+
API: only the application knows which field denotes protocol compatibility.
|
|
3662
|
+
|
|
3489
3663
|
## Server — `createSocketIOServer`
|
|
3490
3664
|
|
|
3491
3665
|
```ts
|
|
@@ -3584,6 +3758,35 @@ socket.on('note:created', (note) => { /* typed note */ })
|
|
|
3584
3758
|
socket.emit('room:join', 'general', ({ joined }) => { /* typed + validated */ })
|
|
3585
3759
|
```
|
|
3586
3760
|
|
|
3761
|
+
### Request-response over realtime
|
|
3762
|
+
|
|
3763
|
+
For an event with an `ack` schema, `request()` is the Promise form of the same
|
|
3764
|
+
native Socket.IO acknowledgement. Arguments and the resolved value are inferred
|
|
3765
|
+
from the contract and validated on both sides:
|
|
3766
|
+
|
|
3767
|
+
```ts
|
|
3768
|
+
const result = await socket.request(
|
|
3769
|
+
'room:join',
|
|
3770
|
+
'general',
|
|
3771
|
+
{ timeoutMs: 5_000 },
|
|
3772
|
+
)
|
|
3773
|
+
// result: { joined: boolean }
|
|
3774
|
+
```
|
|
3775
|
+
|
|
3776
|
+
An event without `ack` cannot be passed to `request()` by type. A disconnected
|
|
3777
|
+
client rejects immediately with `RealtimeRequestDisconnectedError`; an in-flight
|
|
3778
|
+
disconnect uses the same error; an elapsed native acknowledgement timeout uses
|
|
3779
|
+
`RealtimeRequestTimeoutError`. These are distinct stable classes and codes, so
|
|
3780
|
+
never parse Socket.IO error text. An invalid acknowledgement still fires the
|
|
3781
|
+
existing `onRejected` hook with phase `acknowledgement`, then rejects with
|
|
3782
|
+
`RealtimeRequestInvalidAcknowledgementError`.
|
|
3783
|
+
|
|
3784
|
+
`timeoutMs` must be finite and greater than zero. Use acknowledgements only for
|
|
3785
|
+
bounded request-response work. A job that runs for minutes, progress streaming,
|
|
3786
|
+
or resumable delivery should use separate correlated events or the async
|
|
3787
|
+
operation protocol; keeping one acknowledgement open is not a durable RPC/job
|
|
3788
|
+
transport.
|
|
3789
|
+
|
|
3587
3790
|
## Low-level transport
|
|
3588
3791
|
|
|
3589
3792
|
`createSocketIOClient` remains the low-level Socket.IO transport wrapper for
|
|
@@ -4068,10 +4271,11 @@ The value of each `rules` entry, keyed by scope:
|
|
|
4068
4271
|
|
|
4069
4272
|
- **`'public'`** — always passes; the identity is attached if present.
|
|
4070
4273
|
- **`'authenticated'`** — any resolved identity passes; no identity ⇒ 401.
|
|
4071
|
-
- **a function** `(identity, ctx) => boolean |
|
|
4274
|
+
- **a function** `(identity, ctx) => boolean | contribution`, sync or async — a custom
|
|
4072
4275
|
check. It receives request metadata and validated path params, so a
|
|
4073
4276
|
resource-scoped rule can do a DB lookup. It cannot read `input` or files: the
|
|
4074
|
-
body has deliberately not been consumed yet.
|
|
4277
|
+
body has deliberately not been consumed yet. `false` denies, `true` passes,
|
|
4278
|
+
and a returned plain object passes and contributes inferred handler fields.
|
|
4075
4279
|
|
|
4076
4280
|
#### Resource-scoped rule — reading a path/prefix param
|
|
4077
4281
|
|
|
@@ -4101,6 +4305,30 @@ identity *and* any derived values (role, parent-id) on `ctx` for handlers. Read
|
|
|
4101
4305
|
them back as `ctx.tenantRole` (typed `unknown` — narrow at the read site). The
|
|
4102
4306
|
endpoints under the group declare `scope: 'tenant'`.
|
|
4103
4307
|
|
|
4308
|
+
When the async authorization lookup already produced handler data, return it
|
|
4309
|
+
instead of repeating the lookup in `inject` and a handwritten scope map:
|
|
4310
|
+
|
|
4311
|
+
```ts
|
|
4312
|
+
const auth = createAuthHook({
|
|
4313
|
+
resolve: sessionResolver,
|
|
4314
|
+
rules: {
|
|
4315
|
+
project: async (user, ctx) => {
|
|
4316
|
+
const membership = await findMembership(user.id, String(ctx.projectId))
|
|
4317
|
+
return membership
|
|
4318
|
+
? { userId: user.id, projectId: membership.projectId, role: membership.role }
|
|
4319
|
+
: false
|
|
4320
|
+
},
|
|
4321
|
+
},
|
|
4322
|
+
})
|
|
4323
|
+
|
|
4324
|
+
const implementFor = createScopedImplement<AuthScopes<typeof auth>>()
|
|
4325
|
+
```
|
|
4326
|
+
|
|
4327
|
+
Contributions are merged only after full validation. Runtime-owned context keys,
|
|
4328
|
+
arrays, class instances, accessors, symbols, unsafe prototypes and partial proxy
|
|
4329
|
+
reads fail without mutating context. `false | object` contributes required
|
|
4330
|
+
fields; `true | object` correctly makes them optional.
|
|
4331
|
+
|
|
4104
4332
|
### `AuthHookConfig`
|
|
4105
4333
|
|
|
4106
4334
|
| Field | Purpose |
|
|
@@ -4968,6 +5196,25 @@ observe. (This is also why it lives on `ToolCallHooks` rather than being an
|
|
|
4968
5196
|
`Response`, which a tool call has no use for, and a whole `createServer` hooks
|
|
4969
5197
|
object must stay assignable to `ToolLifecycle`.)
|
|
4970
5198
|
|
|
5199
|
+
### Compose lifecycle policy explicitly
|
|
5200
|
+
|
|
5201
|
+
When auth, a feature policy and audit identity are independent modules, compose
|
|
5202
|
+
their existing hooks instead of forwarding each phase by hand:
|
|
5203
|
+
|
|
5204
|
+
```ts
|
|
5205
|
+
import { composeLifecycleHooks } from 'stitchkit/server'
|
|
5206
|
+
import { composeToolLifecycle } from 'stitchkit/tools'
|
|
5207
|
+
|
|
5208
|
+
const httpLifecycle = composeLifecycleHooks(authLifecycle, featurePolicy, auditIdentity)
|
|
5209
|
+
const toolLifecycle = composeToolLifecycle(authHook, featureToolPolicy, auditToolIdentity)
|
|
5210
|
+
```
|
|
5211
|
+
|
|
5212
|
+
Phases run left to right. `onRequest` stops on the first `Response`; `onError`
|
|
5213
|
+
falls through until a hook handles it; after transforms feed the current value
|
|
5214
|
+
forward and preserve it when a hook returns `undefined`. Throws remain owned by
|
|
5215
|
+
the existing outer error boundary, and the original context/signal identity is
|
|
5216
|
+
never replaced.
|
|
5217
|
+
|
|
4971
5218
|
**Do not reach for `setRequestError` here.** It writes to the *request* context,
|
|
4972
5219
|
which the built-in **tool** row does not read: a tool event takes
|
|
4973
5220
|
`errorCode` / `errorMessage` / `errorDetail` from the `ToolResult`, and only
|
|
@@ -5083,6 +5330,38 @@ contract registry. Both helpers are Fetch-only: they construct ordinary
|
|
|
5083
5330
|
absolute `Request` objects and call `createHandler` directly, so Bun and Node
|
|
5084
5331
|
exercise the same framework pipeline.
|
|
5085
5332
|
|
|
5333
|
+
### Transport conformance
|
|
5334
|
+
|
|
5335
|
+
`buildSurfaceManifest` snapshots actual HTTP topology, MCP/Agent/CLI names,
|
|
5336
|
+
CLI-only commands, extensions and canonical schema digests. Compare real runner
|
|
5337
|
+
discovery with `assertSurfaceDiscovery`, then use `runSurfaceProbes` only for
|
|
5338
|
+
the transports you explicitly provide:
|
|
5339
|
+
|
|
5340
|
+
```ts
|
|
5341
|
+
import {
|
|
5342
|
+
assertSurfaceDiscovery,
|
|
5343
|
+
buildSurfaceManifest,
|
|
5344
|
+
runSurfaceProbes,
|
|
5345
|
+
} from 'stitchkit/testing'
|
|
5346
|
+
|
|
5347
|
+
const manifest = buildSurfaceManifest({ services, runtimeTools, cliCommands })
|
|
5348
|
+
assertSurfaceDiscovery(manifest, {
|
|
5349
|
+
openApi,
|
|
5350
|
+
MCP: (await mcpClient.listTools()).tools.map((tool) => tool.name),
|
|
5351
|
+
AGENT: Object.keys(agentTools),
|
|
5352
|
+
CLI: cliHelpNames,
|
|
5353
|
+
})
|
|
5354
|
+
|
|
5355
|
+
await runSurfaceProbes({
|
|
5356
|
+
probes,
|
|
5357
|
+
drivers: { HTTP: httpDriver, MCP: mcpDriver, AGENT: agentDriver, CLI: cliDriver },
|
|
5358
|
+
})
|
|
5359
|
+
```
|
|
5360
|
+
|
|
5361
|
+
The kit never starts a server or invents credentials. Each probe declares its
|
|
5362
|
+
expected normalized outcome and has bounded timeout, setup/teardown and an
|
|
5363
|
+
AbortSignal. A missing driver is unsupported, not silently marked conformant.
|
|
5364
|
+
|
|
5086
5365
|
### Test handlers with raw Requests
|
|
5087
5366
|
|
|
5088
5367
|
`createHandler` is the router as a plain `(req) => Promise<Response>` function —
|
|
@@ -5642,6 +5921,45 @@ current one *up to* your target, and apply each snippet.
|
|
|
5642
5921
|
runtime): bootstrap the server, one HTTP request, and any feature you rely on
|
|
5643
5922
|
(Socket.IO connect, an MCP tool call, a multipart upload, …).
|
|
5644
5923
|
|
|
5924
|
+
## Unreleased migration: peer-free `implementRemote`
|
|
5925
|
+
|
|
5926
|
+
`implementRemote` now has one canonical, optional-peer-free owner. This keeps
|
|
5927
|
+
MCP SDK and AI SDK modules out of CLI bundles that only proxy HTTP calls:
|
|
5928
|
+
|
|
5929
|
+
```ts
|
|
5930
|
+
// before
|
|
5931
|
+
import { implementRemote } from 'stitchkit/tools'
|
|
5932
|
+
// after
|
|
5933
|
+
import { implementRemote } from 'stitchkit/remote'
|
|
5934
|
+
```
|
|
5935
|
+
|
|
5936
|
+
## Unreleased migration: managed file boundary and strict auth returns
|
|
5937
|
+
|
|
5938
|
+
Create one boundary during application bootstrap and pass the capability, never
|
|
5939
|
+
a per-call directory or host path:
|
|
5940
|
+
|
|
5941
|
+
```ts
|
|
5942
|
+
import { createManagedFileBoundary } from 'stitchkit/files'
|
|
5943
|
+
|
|
5944
|
+
const files = await createManagedFileBoundary({ root: '/srv/app-files' })
|
|
5945
|
+
|
|
5946
|
+
// before
|
|
5947
|
+
defineDownloadTool({ defaultDir: '/srv/app-files', resolveUrl, ...common })
|
|
5948
|
+
defineUploadTool({ upload: (path) => provider.uploadFile(path), ...common })
|
|
5949
|
+
defineViewFileTool({ baseDir: '/srv/app-files', ...common })
|
|
5950
|
+
|
|
5951
|
+
// after
|
|
5952
|
+
defineDownloadTool({ files, resolveUrl, ...common })
|
|
5953
|
+
defineUploadTool({ files, upload: ({ bytes }) => provider.upload(bytes), ...common })
|
|
5954
|
+
defineViewFileTool({ files, ...common })
|
|
5955
|
+
```
|
|
5956
|
+
|
|
5957
|
+
Downloaded `path` is now relative to the boundary and MIME metadata is named
|
|
5958
|
+
`mediaType`. Update raw `mountDownload`/`mountUpload`/`mountViewFile` configs the
|
|
5959
|
+
same way. Auth predicates must explicitly return `true`, `false`, or a plain
|
|
5960
|
+
object of context fields; replace accidental `undefined` fallthroughs with the
|
|
5961
|
+
intended boolean.
|
|
5962
|
+
|
|
5645
5963
|
## Released migration: 0.53.0
|
|
5646
5964
|
|
|
5647
5965
|
### Realtime `emit` returns `boolean` instead of `void`
|
|
@@ -6611,11 +6929,18 @@ The browser-and-server entrypoint. Re-exports everything from
|
|
|
6611
6929
|
| `createRealtimeClient` | function | inferred, runtime-validated Socket.IO client — [guide](../guide/realtime.md#client--createrealtimeclient) |
|
|
6612
6930
|
| `createRetainedTopics` | function | retained last-value store for sticky events — [guide](../guide/realtime.md#sticky-events) |
|
|
6613
6931
|
| `parseSSE` | function | parse an SSE `Response` into an async generator — [guide](../guide/client.md#sse) |
|
|
6614
|
-
| `SocketIOClient` | _type_ |
|
|
6932
|
+
| `SocketIOClient` | _type_ | low-level client handle; `emit` reports disconnected drops and `emitWithAck` exposes the native Promise primitive used by validated `request()` |
|
|
6615
6933
|
| `SocketIOClientConfig` | _type_ | config for `createSocketIOClient` (incl. `retain`, `onConnectError`, `onDroppedEmit`) |
|
|
6616
6934
|
| `SocketEventMap` | _type_ | the shape of an event map |
|
|
6617
6935
|
| `RealtimeClient` | _type_ | validated client inferred from a realtime contract |
|
|
6618
6936
|
| `RealtimeClientOptions` | _type_ | transport options and the rejected-event hook for `createRealtimeClient` |
|
|
6937
|
+
| `RealtimeAcknowledgedEvent` | _type_ | event-name union restricted to definitions with an `ack` schema |
|
|
6938
|
+
| `RealtimeAcknowledgement` | _type_ | validated acknowledgement output inferred from an event definition |
|
|
6939
|
+
| `RealtimeRequestArguments` | _type_ | request arguments inferred from an acknowledged event tuple |
|
|
6940
|
+
| `RealtimeRequestOptions` | _type_ | finite positive native acknowledgement `timeoutMs` |
|
|
6941
|
+
| `RealtimeRequestTimeoutError` | class | stable `REALTIME_REQUEST_TIMEOUT` rejection |
|
|
6942
|
+
| `RealtimeRequestDisconnectedError` | class | stable `REALTIME_REQUEST_DISCONNECTED` rejection, including an immediate disconnected call |
|
|
6943
|
+
| `RealtimeRequestInvalidAcknowledgementError` | class | invalid ack was reported through `onRejected` and the request rejected |
|
|
6619
6944
|
| `RealtimeContract` | _type_ | shared server-to-client and client-to-server event registries |
|
|
6620
6945
|
| `RealtimeEventRegistry` | _type_ | string-keyed registry of event definitions |
|
|
6621
6946
|
| `RealtimeEventDefinition` | _type_ | one tuple-shaped event and optional acknowledgement schema |
|
|
@@ -6796,6 +7121,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
6796
7121
|
| `OperationIdentity` | _type_ | path-free service/action/scope/method identity shared by contract and native tool operations |
|
|
6797
7122
|
| `Handlers` | _type_ | the typed handler map `implement` expects |
|
|
6798
7123
|
| `LifecycleHooks` | _type_ | `onRequest` / pre-body `authorize` / `beforeHandle` / `afterHandle` / `onError` |
|
|
7124
|
+
| `composeLifecycleHooks` | function | compose HTTP lifecycle phases in declaration order with short-circuit/fallthrough semantics |
|
|
6799
7125
|
| `AuthorizationContext` | _type_ | HTTP pre-body context with validated params, `input: undefined` and no files |
|
|
6800
7126
|
| `RouteGroup` | _type_ | a prefixed group of services with its own hooks |
|
|
6801
7127
|
| `RawRoute` | _type_ | a non-contract `Request → Response` route with a concrete `BunServer` context |
|
|
@@ -6827,6 +7153,7 @@ Also re-exports the error helpers from `stitchkit/contract`.
|
|
|
6827
7153
|
| `AuthHook` | _type_ | the hook `createAuthHook` returns |
|
|
6828
7154
|
| `AuthHookConfig` | _type_ | config for `createAuthHook` |
|
|
6829
7155
|
| `AuthRule` | _type_ | `'public' \| 'authenticated' \| predicate` |
|
|
7156
|
+
| `AuthRuleContribution` | _type_ | plain context fields a sync/async rule may contribute after authorizing |
|
|
6830
7157
|
| `ScopedAuthRule` | _type_ | a rule plus its typed context contribution — `{ rule, inject? }` |
|
|
6831
7158
|
| `AuthRules` | _type_ | the `rules` map: bare rules or scoped rules |
|
|
6832
7159
|
| `RuleScopes` | _type_ | scope→context map derived from a `rules` object; `'public'` fields become optional |
|
|
@@ -6995,6 +7322,18 @@ audit event. See the [Observability guide](../guide/observability.md).
|
|
|
6995
7322
|
|
|
6996
7323
|
---
|
|
6997
7324
|
|
|
7325
|
+
## `stitchkit/remote`
|
|
7326
|
+
|
|
7327
|
+
Peer-free remote implementation boundary. Importing it does not load the MCP
|
|
7328
|
+
SDK, `ai`, or other optional tool peers, so it is safe in a thin CLI bundle.
|
|
7329
|
+
|
|
7330
|
+
| Export | Kind | Summary |
|
|
7331
|
+
|--------|------|---------|
|
|
7332
|
+
| `implementRemote` | function | bind a contract to a remote HTTP API — [guide](../guide/mcp-and-agents.md#proxying-a-remote-api--implementremote) |
|
|
7333
|
+
| `ImplementRemoteOptions` | _type_ | optional argument-rewrite hook for `implementRemote` |
|
|
7334
|
+
|
|
7335
|
+
---
|
|
7336
|
+
|
|
6998
7337
|
## `stitchkit/tools`
|
|
6999
7338
|
|
|
7000
7339
|
Server-only. Turns contracts into MCP and AI-agent tools. MCP server surfaces
|
|
@@ -7014,7 +7353,6 @@ payload.
|
|
|
7014
7353
|
| `bindStdioProcessSignals` | function | explicitly bind OS signals to one close-only stdio handle — [guide](../guide/testing-and-deployment.md#stdio-process-signals) |
|
|
7015
7354
|
| `buildMcpServer` | function | build an `McpServer` from contract/runtime surfaces; no-auth configs omit the second argument |
|
|
7016
7355
|
| `mountMcp` | function | add contract tools to an existing `McpServer` — [guide](../guide/mcp-and-agents.md#mountmcp) |
|
|
7017
|
-
| `implementRemote` | function | bind a contract to a remote HTTP API — [guide](../guide/mcp-and-agents.md#proxying-a-remote-api--implementremote) |
|
|
7018
7356
|
| `mountAgent` | function | a Vercel AI SDK `ToolSet` from a service — [guide](../guide/mcp-and-agents.md#ai-agents--mountagent) |
|
|
7019
7357
|
| `defineRuntimeTool` | function | define one validated pathless operation for explicit MCP, Agent and/or CLI surfaces — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
|
|
7020
7358
|
| `createRuntimeToolFactory` | function | bind shared identity and Zod-validated per-call context for runtime tools — [guide](../guide/mcp-and-agents.md#pathless-runtime-tools-and-multimodal-results) |
|
|
@@ -7046,7 +7384,6 @@ payload.
|
|
|
7046
7384
|
| `McpSurfaceDefinition` | _type_ | one immutable `{ services, runtimeTools }` MCP surface |
|
|
7047
7385
|
| `McpSurfaceRegistry` | _type_ | finite keyed surface registry for eager preparation |
|
|
7048
7386
|
| `StdioAuthConfig` | _type_ | startup identity composed into `StdioMcpServerConfig` |
|
|
7049
|
-
| `ImplementRemoteOptions` | _type_ | options for `implementRemote` |
|
|
7050
7387
|
| `McpMountConfig` | _type_ | config for `mountMcp` |
|
|
7051
7388
|
| `McpSchemaValidationConfig` | _type_ | shared `{ policy, requireTypedProperties, allowUntyped, requirePortableFormats, allowFormats }` profile |
|
|
7052
7389
|
| `ValidateMcpSchemasConfig` | _type_ | standalone validation profile plus `services`, `extend`, flattening and logger |
|
|
@@ -7102,7 +7439,7 @@ payload.
|
|
|
7102
7439
|
| `ToolInvocationOptions` | _type_ | per-call source, context, lifecycle, hooks and output-strip reporter |
|
|
7103
7440
|
| `ToolInvokerTransport` | _type_ | invoker exposure policy: `MCP \| AGENT \| CLI` |
|
|
7104
7441
|
| `ToolCallContext` | _type_ | the context every tool hook receives — `{ source, mcp? }` plus whatever the mount's `context` added |
|
|
7105
|
-
| `ViewFileOptions` | _type_ | shared URL/
|
|
7442
|
+
| `ViewFileOptions` | _type_ | shared URL/managed-file-boundary policy for `defineViewFileTool`, `mountViewFile` and `resolveMedia` |
|
|
7106
7443
|
| `ViewFileOutput` | _type_ | neutral managed batch result with multimodal `content` and per-item `errors` |
|
|
7107
7444
|
| `ViewFileInputSchema` | constant | fixed one-or-many media path/URL input schema |
|
|
7108
7445
|
| `ViewFileOutputSchema` | constant | Zod schema for the neutral managed view-file batch result |
|
|
@@ -7138,9 +7475,25 @@ runtime-tool runner, plus deliberate raw MCP adapters over the same mechanics.
|
|
|
7138
7475
|
| `ManagedNativeToolConfig` | _type_ | shared name, description, identity, exposure and annotations for managed native factories |
|
|
7139
7476
|
| `NativeToolIdentity` | _type_ | pathless service/action/scope/meta identity; semantic method is factory-owned |
|
|
7140
7477
|
| `ManagedWaitRender` | _type_ | optional managed wait terminal text and failure classification |
|
|
7141
|
-
| `DownloadResultSchema` | constant | Zod schema for a saved download's path, byte size and MIME type |
|
|
7142
|
-
| `DownloadResult` | _type_ | validated output of `defineDownloadTool` |
|
|
7143
7478
|
| `UploadToolInputSchema` | constant | fixed `{ path: string }` input schema for `defineUploadTool` |
|
|
7479
|
+
| `defineAsyncOperation` | function | runtime-only start/status/wait plus configured cancel/result/artifacts definitions |
|
|
7480
|
+
| `bindContractAsyncOperation` | function | bind literal methods from an existing contract without creating another HTTP surface |
|
|
7481
|
+
| `createAsyncOperationSnapshotSchema` | function | canonical pending/running/succeeded/failed/cancelled Zod snapshot |
|
|
7482
|
+
| `AsyncOperationCancelResultSchema` | constant | validated accepted/already_terminal/rejected cancellation result |
|
|
7483
|
+
| `AsyncOperationCancelResult` | _type_ | validated cancel capability result |
|
|
7484
|
+
| `AsyncOperationCancelCapability` | _type_ | optional typed domain cancellation callback |
|
|
7485
|
+
| `AsyncOperationCapability` | _type_ | generated capability-name union |
|
|
7486
|
+
| `AsyncOperationStartDefinition` / `AsyncOperationFollowDefinition` | _type_ | generated runtime definition types |
|
|
7487
|
+
| `AsyncOperationIdentity` | _type_ | shared service/action/scope/meta identity for an operation |
|
|
7488
|
+
| `AsyncOperationOutputCapability` | _type_ | optional result/artifact schema plus handler |
|
|
7489
|
+
| `RuntimeAsyncOperationConfig` | _type_ | runtime-only descriptor configuration |
|
|
7490
|
+
| `RuntimeAsyncOperation` | _type_ | inferred generated definitions and schemas |
|
|
7491
|
+
| `ContractAsyncOperationConfig` | _type_ | literal contract method binding and handlers |
|
|
7492
|
+
| `ContractAsyncOperationKeys` | _type_ | literal method-key union of a bound contract |
|
|
7493
|
+
| `ContractAsyncOperationStartKey` | _type_ | contract keys with a declared output schema, valid for `start` |
|
|
7494
|
+
| `ContractAsyncOperationFollowKey` | _type_ | contract keys whose input schema type matches the selected start output |
|
|
7495
|
+
| `ContractAsyncOperationWaitKey` | _type_ | follow-up keys whose output schema type also matches the selected status output |
|
|
7496
|
+
| `composeToolLifecycle` | function | ordered composition of tool before/after phases |
|
|
7144
7497
|
| `mountDownload` | function | raw MCP "download a URL to disk" adapter (SSRF-guarded, size-capped) |
|
|
7145
7498
|
| `mountUpload` | function | raw MCP "upload a local file" adapter |
|
|
7146
7499
|
| `mountWait` | function | raw MCP generic `--wait`-style polling adapter |
|
|
@@ -7220,6 +7573,43 @@ handler pipeline without opening a TCP port.
|
|
|
7220
7573
|
| `HandlerTestClientConfig` | _type_ | handler, contract, path prefix, scoped config and client request defaults |
|
|
7221
7574
|
| `HandlerTestClientsConfig` | _type_ | batch helper configuration |
|
|
7222
7575
|
| `HandlerTestTransportConfig` | _type_ | shared in-process handler, origin, prefix, client defaults and optional server handle |
|
|
7576
|
+
| `buildSurfaceManifest` | function | deterministic actual HTTP/tool/CLI/extension topology with versioned schema digests |
|
|
7577
|
+
| `assertSurfaceManifestSnapshot` | function | bounded deterministic manifest drift assertion |
|
|
7578
|
+
| `assertSurfaceDiscovery` | function | compare real OpenAPI/MCP/Agent/CLI discovery to a manifest |
|
|
7579
|
+
| `runSurfaceProbes` | function | execute explicit transport drivers with per-probe setup, teardown, timeout and cancellation |
|
|
7580
|
+
| `TransportObservationSchema` | constant | normalized success/validation/domain-error/aborted probe outcome |
|
|
7581
|
+
| `ConformanceTransport` | _type_ | explicit probe transport union |
|
|
7582
|
+
| `RunSurfaceProbesConfig` | _type_ | probes, drivers and diagnostic byte cap |
|
|
7583
|
+
| `SurfaceDiscoveryObservation` | _type_ | real OpenAPI/tool/CLI/extension discovery values |
|
|
7584
|
+
| `SurfaceProbe` / `SurfaceProbeDriver` | _type_ | one bounded scenario and its consumer-supplied runner |
|
|
7585
|
+
| `TransportObservation` | _type_ | validated normalized driver result |
|
|
7586
|
+
| `SurfaceManifest` / `SurfaceManifestConfig` | _type_ | deterministic surface snapshot and its inputs |
|
|
7587
|
+
| `SurfaceManifestOperation` / `SurfaceManifestOperationSchema` | _type_ / schema | one contract or runtime operation row |
|
|
7588
|
+
| `SurfaceManifestExtension` / `SurfaceManifestExtensionSchema` | _type_ / schema | declared transport extension row |
|
|
7589
|
+
| `SurfaceManifestSchema` | schema | complete deterministic manifest schema |
|
|
7590
|
+
| `SurfaceRuntimeToolDefinition` | _type_ | peer-free structural runtime-operation subset accepted by manifests |
|
|
7591
|
+
| `SurfaceSchemaDigestsSchema` | schema | params/input/output/multipart digest object |
|
|
7592
|
+
| `serializeSurfaceValue` | function | canonical versioned serialization used for deterministic digests |
|
|
7593
|
+
|
|
7594
|
+
---
|
|
7595
|
+
|
|
7596
|
+
## `stitchkit/files`
|
|
7597
|
+
|
|
7598
|
+
Peer-free Bun/Node filesystem capability. Browser/contract-safe refs are also
|
|
7599
|
+
available from `stitchkit/contract`.
|
|
7600
|
+
|
|
7601
|
+
| Export | Kind | Summary |
|
|
7602
|
+
|--------|------|---------|
|
|
7603
|
+
| `createManagedFileBoundary` | function | bind one existing application-owned root for capped reads and atomic writes |
|
|
7604
|
+
| `ManagedFileBoundary` | _type_ | non-reopenable `read`/`write` capability over canonical relative paths |
|
|
7605
|
+
| `ManagedFileBoundaryConfig` | _type_ | bound root, finite limits, inspector and cleanup observer |
|
|
7606
|
+
| `ManagedFileRefSchema` / `ManagedFileRef` | schema / _type_ | transport-safe relative path, measured size and optional media metadata |
|
|
7607
|
+
| `ManagedFilePathSchema` / `ManagedFilePath` | schema / _type_ | canonical POSIX relative managed-file path |
|
|
7608
|
+
| `ManagedFileSource` | _type_ | bounded immutable bytes plus validated ref passed to upload callbacks |
|
|
7609
|
+
| `ManagedFileReadOptions` / `ManagedFileWriteOptions` | _type_ | per-operation byte cap, signal and atomic write policy |
|
|
7610
|
+
| `ManagedFileError` / `ManagedFileErrorCode` | class / _type_ | stable caller-safe boundary failures |
|
|
7611
|
+
| `ManagedFileInspector` | _type_ | bounded-prefix content inspection callback that cannot own path or size |
|
|
7612
|
+
| `ManagedFileInspectionInput` / `ManagedFileInspection` | _type_ | inspector input and normalized metadata-only result |
|
|
7223
7613
|
|
|
7224
7614
|
---
|
|
7225
7615
|
|
|
@@ -7258,7 +7648,7 @@ SDK nor the `ai` peer.
|
|
|
7258
7648
|
| `defineCliCommand` | function | define one Zod-typed CLI-only executable command |
|
|
7259
7649
|
| `parseCliArgs` | function | argv → typed tool args against a schema (advanced) |
|
|
7260
7650
|
| `pollUntilDone` | function | the generic `--wait` poller (advanced) |
|
|
7261
|
-
| `emitResult` | function | write a `ToolResult` to stdout/stderr + exit code (advanced) |
|
|
7651
|
+
| `emitResult` | function | write a pretty or compact `ToolResult` record to stdout/stderr + exit code (advanced) |
|
|
7262
7652
|
| `DEFAULT_EXIT_CODES` | const | the default `ToolResult.code` → exit-code map |
|
|
7263
7653
|
| `CliConfig` | _type_ | config for `createCli` |
|
|
7264
7654
|
| `CliSurfaceSource` | _type_ | static service/runtime array or identity-dependent factory |
|
|
@@ -7267,9 +7657,9 @@ SDK nor the `ai` peer.
|
|
|
7267
7657
|
| `CliCommandDefinitionWithOutput` | _type_ | native command with validated declared output |
|
|
7268
7658
|
| `CliCommandDefinitionWithoutOutput` | _type_ | native void command without an output contract |
|
|
7269
7659
|
| `CliCommandContext` | _type_ | parsed input, global options and stdout/stderr writers |
|
|
7270
|
-
| `CliRunOptions` | _type_ | parsed global flags (`--json
|
|
7660
|
+
| `CliRunOptions` | _type_ | parsed global flags (`--json` compacts success/error records, `--wait`, …) |
|
|
7271
7661
|
| `ParsedCliArgs` | _type_ | result of `parseCliArgs` |
|
|
7272
|
-
| `CliWaitConfig` | _type_ | per-command `--wait` polling config |
|
|
7662
|
+
| `CliWaitConfig` | _type_ | per-command `--wait` polling config; optional `failed(result)` maps a terminal domain failure to `WAIT_FAILED` and a non-zero exit |
|
|
7273
7663
|
| `ExitCodeMap` | _type_ | `ToolResult.code` → process exit code |
|
|
7274
7664
|
| `PollParams` | _type_ | params for `pollUntilDone` |
|
|
7275
7665
|
| `CliWriters` | _type_ | stdout/stderr sinks for `emitResult` |
|