stitchkit 0.118.0 → 0.119.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.
Files changed (151) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/dist/browser/http.d.ts.map +1 -1
  3. package/dist/contract/client-types.d.ts +6 -3
  4. package/dist/contract/client-types.d.ts.map +1 -1
  5. package/dist/contract/define-validation.d.ts.map +1 -1
  6. package/dist/contract/define.d.ts +18 -12
  7. package/dist/contract/define.d.ts.map +1 -1
  8. package/dist/contract/endpoint-capabilities.d.ts +28 -0
  9. package/dist/contract/endpoint-capabilities.d.ts.map +1 -0
  10. package/dist/contract/factory.d.ts +49 -19
  11. package/dist/contract/factory.d.ts.map +1 -1
  12. package/dist/contract/tool-view.d.ts +1 -1
  13. package/dist/contract/tool-view.d.ts.map +1 -1
  14. package/dist/contract/transports.d.ts +5 -0
  15. package/dist/contract/transports.d.ts.map +1 -0
  16. package/dist/entrypoints/agent-runtime/coding-tools.js +6 -5
  17. package/dist/entrypoints/agent-runtime/harness.js +6 -5
  18. package/dist/entrypoints/agent-runtime/sandbox.js +6 -5
  19. package/dist/entrypoints/agent-runtime/sqlite/bun.js +9 -8
  20. package/dist/entrypoints/agent-runtime/sqlite/node.js +9 -8
  21. package/dist/entrypoints/agent-runtime/testing.js +9 -8
  22. package/dist/entrypoints/agent-runtime.js +14 -13
  23. package/dist/entrypoints/application/diagnostic-journal.js +3 -3
  24. package/dist/entrypoints/application/directory-inbox.js +4 -4
  25. package/dist/entrypoints/application/opentelemetry.js +1 -1
  26. package/dist/entrypoints/application.js +5 -5
  27. package/dist/entrypoints/cli/publish.js +4 -4
  28. package/dist/entrypoints/cli.js +8 -7
  29. package/dist/entrypoints/contract.d.ts +1 -1
  30. package/dist/entrypoints/contract.d.ts.map +1 -1
  31. package/dist/entrypoints/contract.js +6 -4
  32. package/dist/entrypoints/files.js +3 -3
  33. package/dist/entrypoints/geo/contract.d.ts +7 -0
  34. package/dist/entrypoints/geo/contract.d.ts.map +1 -0
  35. package/dist/entrypoints/geo/contract.js +6 -0
  36. package/dist/entrypoints/geo.js +60 -23
  37. package/dist/entrypoints/http.js +2 -2
  38. package/dist/entrypoints/index.js +8 -6
  39. package/dist/entrypoints/live.js +1 -1
  40. package/dist/entrypoints/node.js +7 -6
  41. package/dist/entrypoints/primitives.js +1 -1
  42. package/dist/entrypoints/process/owner-loss.js +1 -1
  43. package/dist/entrypoints/process.js +3 -3
  44. package/dist/entrypoints/react.js +1 -1
  45. package/dist/entrypoints/remote.js +4 -3
  46. package/dist/entrypoints/server.d.ts +1 -1
  47. package/dist/entrypoints/server.d.ts.map +1 -1
  48. package/dist/entrypoints/server.js +42 -27
  49. package/dist/entrypoints/telegram.js +2 -2
  50. package/dist/entrypoints/testing.js +7 -6
  51. package/dist/entrypoints/tools/connections.js +3 -2
  52. package/dist/entrypoints/tools/contract.js +1 -1
  53. package/dist/entrypoints/tools/invoker.js +5 -4
  54. package/dist/entrypoints/tools/mcp.js +7 -6
  55. package/dist/entrypoints/tools.js +17 -15
  56. package/dist/entrypoints/tracking/contract.js +5 -3
  57. package/dist/entrypoints/tracking/performance.js +3 -3
  58. package/dist/entrypoints/tracking.d.ts +1 -1
  59. package/dist/entrypoints/tracking.d.ts.map +1 -1
  60. package/dist/entrypoints/tracking.js +63 -83
  61. package/dist/entrypoints/xlsx.js +1 -1
  62. package/dist/geo/index.d.ts +2 -1
  63. package/dist/geo/index.d.ts.map +1 -1
  64. package/dist/geo/record.d.ts +8 -0
  65. package/dist/geo/record.d.ts.map +1 -0
  66. package/dist/geo/resolver.d.ts +1 -3
  67. package/dist/geo/resolver.d.ts.map +1 -1
  68. package/dist/geo/schema.d.ts +44 -0
  69. package/dist/geo/schema.d.ts.map +1 -0
  70. package/dist/geo/types.d.ts +2 -13
  71. package/dist/geo/types.d.ts.map +1 -1
  72. package/dist/{index-n5sv4z0w.js → index-1k18qzqa.js} +13 -15
  73. package/dist/{index-tsngj2b5.js → index-2dfvv1jg.js} +206 -206
  74. package/dist/{index-d9hq291n.js → index-4jpykzvw.js} +70 -81
  75. package/dist/{index-ghtpfz4z.js → index-57gqaq8b.js} +2 -2
  76. package/dist/index-69t14s4a.js +39 -0
  77. package/dist/{index-6p3frkv5.js → index-6a69xzrx.js} +4 -4
  78. package/dist/{index-dky0dcmf.js → index-72r9k0av.js} +6 -2
  79. package/dist/{index-vv1sch8a.js → index-8vzh5wpv.js} +13 -8
  80. package/dist/{index-xx1j310k.js → index-8yxgcyt6.js} +171 -169
  81. package/dist/{index-p6apg0jg.js → index-9frf01t9.js} +16 -9
  82. package/dist/{index-q0th8q0z.js → index-9mjrnqxs.js} +1 -3
  83. package/dist/{index-ega3yz4c.js → index-aqwg2dm5.js} +1 -1
  84. package/dist/{index-073nw9qr.js → index-ba7are04.js} +524 -522
  85. package/dist/{index-095ya5hm.js → index-bbvc59gw.js} +13 -11
  86. package/dist/{index-txg1npmg.js → index-cyxp8rbf.js} +1 -1
  87. package/dist/index-d3xdyjt6.js +38 -0
  88. package/dist/{index-n8z3rvzw.js → index-f4njz9j0.js} +3 -5
  89. package/dist/{index-90p34rts.js → index-fcqj44mb.js} +3 -1
  90. package/dist/{index-86nbfysb.js → index-ff39f9dr.js} +3 -3
  91. package/dist/{index-75ns2ybj.js → index-fqd4yqwd.js} +1 -1
  92. package/dist/{index-nqxrm176.js → index-g444vfz2.js} +1 -1
  93. package/dist/{index-vwhrnp67.js → index-kz9734jc.js} +3 -3
  94. package/dist/{index-dr3t5n1v.js → index-nn9qvkww.js} +46 -46
  95. package/dist/{index-qezhmp51.js → index-nz06qw5a.js} +3 -1
  96. package/dist/{index-1bx1xv1k.js → index-pfvde2fz.js} +5 -2
  97. package/dist/{index-s80awwsw.js → index-qch1vcaa.js} +3 -1
  98. package/dist/{index-cycp3r3e.js → index-rxcgp4b9.js} +2 -2
  99. package/dist/{index-w7jq3fz9.js → index-s0qjs6ee.js} +1198 -1196
  100. package/dist/{index-p0rf7sq9.js → index-s20s2mad.js} +209 -209
  101. package/dist/{index-v6vb5qx8.js → index-s3yxw6kt.js} +1 -1
  102. package/dist/{index-cqmqyjax.js → index-sa99p98w.js} +1 -1
  103. package/dist/{index-0gxvns6s.js → index-sba3e6m4.js} +1 -0
  104. package/dist/{index-f24bdt13.js → index-v1swr26p.js} +3 -1
  105. package/dist/{index-rhzkndr5.js → index-x4p3kw1p.js} +533 -530
  106. package/dist/{index-hdjmdwsj.js → index-x8d9fdeg.js} +513 -507
  107. package/dist/{index-htxh46ej.js → index-ycqhyars.js} +2 -2
  108. package/dist/{index-9bwcthxw.js → index-yj6saztf.js} +31 -13
  109. package/dist/{index-tdpmfks8.js → index-ynrf908v.js} +1 -1
  110. package/dist/{index-f6m4c545.js → index-zrdcmg6j.js} +4 -6
  111. package/dist/process/bun-child.d.ts +3 -2
  112. package/dist/process/bun-child.d.ts.map +1 -1
  113. package/dist/server/contract-method.d.ts.map +1 -1
  114. package/dist/server/file.d.ts +12 -6
  115. package/dist/server/file.d.ts.map +1 -1
  116. package/dist/tools/internal/surface-projector.d.ts.map +1 -1
  117. package/dist/tools/operations/async-operation-canonical-types.d.ts +1 -1
  118. package/dist/tracking/attribution.d.ts +21 -25
  119. package/dist/tracking/attribution.d.ts.map +1 -1
  120. package/dist/tracking/client-visit.d.ts +5 -7
  121. package/dist/tracking/client-visit.d.ts.map +1 -1
  122. package/dist/tracking/client.d.ts +2 -2
  123. package/dist/tracking/client.d.ts.map +1 -1
  124. package/dist/tracking/contract.d.ts +1 -1
  125. package/dist/tracking/host.d.ts +0 -1
  126. package/dist/tracking/host.d.ts.map +1 -1
  127. package/dist/tracking/privacy.d.ts +6 -0
  128. package/dist/tracking/privacy.d.ts.map +1 -1
  129. package/dist/tracking/schemas.d.ts +2 -2
  130. package/dist/tracking/schemas.d.ts.map +1 -1
  131. package/llms/contract.txt +46 -24
  132. package/llms/geo-contract.txt +23 -0
  133. package/llms/geo.txt +40 -4
  134. package/llms/server.2.txt +19 -6
  135. package/llms/server.5.txt +2 -1
  136. package/llms/stitchkit.txt +4 -3
  137. package/llms/testing.txt +3 -3
  138. package/llms/tools.2.txt +2 -2
  139. package/llms/tools.3.txt +1 -1
  140. package/llms/tracking-contract.txt +1 -1
  141. package/llms/tracking.txt +27 -5
  142. package/llms/{upgrading-0.105.0-0.118.0.txt → upgrading-0.106.0-0.119.0.txt} +121 -410
  143. package/llms/upgrading-0.37.0-0.53.0.txt +969 -0
  144. package/llms/{upgrading-0.44.0-0.62.0.txt → upgrading-0.55.0-0.68.0.txt} +509 -528
  145. package/llms/{upgrading-0.63.0-0.83.0.txt → upgrading-0.69.0-0.95.0.txt} +506 -509
  146. package/llms/{upgrading-0.84.0-0.104.0.txt → upgrading-0.96.0-0.105.0.txt} +410 -506
  147. package/llms/upgrading.txt +5 -5
  148. package/llms-full.txt +271 -48
  149. package/llms.txt +11 -10
  150. package/package.json +23 -19
  151. package/llms/upgrading-0.37.0-0.44.0.txt +0 -444
@@ -13,7 +13,7 @@ import {
13
13
  uploadProgressRoute,
14
14
  withUploadProgress,
15
15
  parseApiErrorBody
16
- } from "./index-p6apg0jg.js";
16
+ } from "./index-9frf01t9.js";
17
17
  import {
18
18
  inputIsQuery
19
19
  } from "./index-xhzq2qvj.js";
@@ -33,211 +33,6 @@ import {
33
33
  mapObject
34
34
  } from "./index-9jfdm5tg.js";
35
35
 
36
- // src/internal/bounded-lines.ts
37
- var DEFAULT_STREAM_LINE_BYTES = 1024 * 1024;
38
-
39
- class StreamLineLimitError2 extends RangeError {
40
- limitBytes;
41
- lineBytes;
42
- name = "StreamLineLimitError";
43
- constructor(limitBytes, lineBytes) {
44
- super(`Stream line exceeds the ${limitBytes} byte limit (${lineBytes} bytes so far)`);
45
- this.limitBytes = limitBytes;
46
- this.lineBytes = lineBytes;
47
- }
48
- }
49
-
50
- class StreamTruncatedLineError2 extends SyntaxError {
51
- lineBytes;
52
- name = "StreamTruncatedLineError";
53
- constructor(lineBytes) {
54
- super(`Stream ended with an unterminated final line (${lineBytes} bytes)`);
55
- this.lineBytes = lineBytes;
56
- }
57
- }
58
- function lineLimit(value) {
59
- const resolved = value ?? DEFAULT_STREAM_LINE_BYTES;
60
- assertPositiveSafeInteger("maxLineBytes", resolved);
61
- return resolved;
62
- }
63
- function createLineSplitter(maxLineBytes, requireFinalNewline = false) {
64
- const limit = lineLimit(maxLineBytes);
65
- const decoder = new TextDecoder("utf-8", { fatal: true });
66
- let parts = [];
67
- let pendingBytes = 0;
68
- let ended = false;
69
- let failed = false;
70
- const drop = () => {
71
- parts = [];
72
- pendingBytes = 0;
73
- };
74
- const retain = (bytes) => {
75
- if (bytes.byteLength === 0)
76
- return;
77
- pendingBytes += bytes.byteLength;
78
- if (pendingBytes > limit) {
79
- const seen = pendingBytes;
80
- drop();
81
- throw new StreamLineLimitError2(limit, seen);
82
- }
83
- parts.push(new Uint8Array(bytes));
84
- };
85
- const take = () => {
86
- const line = new Uint8Array(pendingBytes);
87
- let at = 0;
88
- for (const part of parts) {
89
- line.set(part, at);
90
- at += part.byteLength;
91
- }
92
- drop();
93
- return decoder.decode(line);
94
- };
95
- function* lines(chunk) {
96
- if (ended)
97
- throw new Error("Line decoder received bytes after end()");
98
- if (failed)
99
- throw new Error("Line decoder stopped at an earlier error; read the source again");
100
- try {
101
- let start = 0;
102
- for (let index = chunk.indexOf(10);index !== -1; index = chunk.indexOf(10, start)) {
103
- retain(chunk.subarray(start, index));
104
- yield take();
105
- start = index + 1;
106
- }
107
- retain(chunk.subarray(start));
108
- } catch (error) {
109
- failed = true;
110
- throw error;
111
- }
112
- }
113
- return {
114
- lines,
115
- push: (chunk) => [...lines(chunk)],
116
- end() {
117
- ended = true;
118
- if (pendingBytes === 0)
119
- return [];
120
- if (requireFinalNewline) {
121
- const seen = pendingBytes;
122
- drop();
123
- throw new StreamTruncatedLineError2(seen);
124
- }
125
- return [take()];
126
- }
127
- };
128
- }
129
- function createBoundedLineDecoder(maxLineBytes, requireFinalNewline = false) {
130
- const { push, end } = createLineSplitter(maxLineBytes, requireFinalNewline);
131
- return { push, end };
132
- }
133
- async function* readBoundedUtf8Lines(source, maxLineBytes, requireFinalNewline = false, signal) {
134
- const splitter = createLineSplitter(maxLineBytes, requireFinalNewline);
135
- for await (const chunk of chunksOf(source, signal)) {
136
- for (const line of splitter.lines(chunk)) {
137
- signal?.throwIfAborted();
138
- yield line;
139
- }
140
- }
141
- for (const line of splitter.end()) {
142
- signal?.throwIfAborted();
143
- yield line;
144
- }
145
- }
146
-
147
- // src/browser/stream.ts
148
- function ndjsonLine(rawLine) {
149
- return (rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine).trim();
150
- }
151
- function parseFailure(raw, error, onParseError) {
152
- const failure = error instanceof Error ? error : new Error(String(error));
153
- if (!onParseError)
154
- throw failure;
155
- onParseError(raw, failure);
156
- }
157
- async function* parseNDJSON2(source, options) {
158
- let reporting = false;
159
- try {
160
- for await (const rawLine of readBoundedUtf8Lines(source, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, options?.finalLine === "require-newline", options?.signal)) {
161
- const line = ndjsonLine(rawLine);
162
- if (line === "")
163
- continue;
164
- let value;
165
- try {
166
- value = JSON.parse(line);
167
- } catch (error) {
168
- reporting = true;
169
- parseFailure(line, error, options?.onParseError);
170
- reporting = false;
171
- continue;
172
- }
173
- yield value;
174
- }
175
- } catch (error) {
176
- if (reporting || options?.signal?.aborted)
177
- throw error;
178
- parseFailure("", error, options?.onParseError);
179
- }
180
- }
181
- function createNDJSONDecoder2(options) {
182
- const lines = createBoundedLineDecoder(options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, options?.finalLine === "require-newline");
183
- let failed = false;
184
- const values = (rawLines) => {
185
- const parsed = [];
186
- for (const rawLine of rawLines) {
187
- const line = ndjsonLine(rawLine);
188
- if (line === "")
189
- continue;
190
- try {
191
- parsed.push(JSON.parse(line));
192
- } catch (error) {
193
- parseFailure(line, error, options?.onParseError);
194
- }
195
- }
196
- return parsed;
197
- };
198
- const guarded = (step) => {
199
- if (failed)
200
- throw new Error("NDJSON decoder stopped at an earlier error; read the source again");
201
- try {
202
- return values(step());
203
- } catch (error) {
204
- failed = true;
205
- throw error;
206
- }
207
- };
208
- return {
209
- push: (chunk) => guarded(() => lines.push(chunk)),
210
- end: () => guarded(() => lines.end())
211
- };
212
- }
213
- async function* parseSSE2(source, options) {
214
- let reporting = false;
215
- try {
216
- for await (const rawLine of readBoundedUtf8Lines(source, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, false, options?.signal)) {
217
- const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
218
- if (!line.startsWith("data:"))
219
- continue;
220
- const data = line.slice(5).replace(/^ /, "");
221
- if (data === "[DONE]")
222
- return;
223
- let value;
224
- try {
225
- value = JSON.parse(data);
226
- } catch (error) {
227
- reporting = true;
228
- parseFailure(data, error, options?.onParseError);
229
- reporting = false;
230
- continue;
231
- }
232
- yield value;
233
- }
234
- } catch (error) {
235
- if (reporting || options?.signal?.aborted)
236
- throw error;
237
- parseFailure("", error, options?.onParseError);
238
- }
239
- }
240
-
241
36
  // src/browser/client-arguments.ts
242
37
  function endpointHasArguments(endpoint) {
243
38
  return Boolean(endpoint.params || endpoint.input || endpoint.multipart);
@@ -464,6 +259,211 @@ function joinClientBaseUrl(baseUrl, relativeUrl) {
464
259
  return `${base}${path}`;
465
260
  }
466
261
 
262
+ // src/internal/bounded-lines.ts
263
+ var DEFAULT_STREAM_LINE_BYTES = 1024 * 1024;
264
+
265
+ class StreamLineLimitError2 extends RangeError {
266
+ limitBytes;
267
+ lineBytes;
268
+ name = "StreamLineLimitError";
269
+ constructor(limitBytes, lineBytes) {
270
+ super(`Stream line exceeds the ${limitBytes} byte limit (${lineBytes} bytes so far)`);
271
+ this.limitBytes = limitBytes;
272
+ this.lineBytes = lineBytes;
273
+ }
274
+ }
275
+
276
+ class StreamTruncatedLineError2 extends SyntaxError {
277
+ lineBytes;
278
+ name = "StreamTruncatedLineError";
279
+ constructor(lineBytes) {
280
+ super(`Stream ended with an unterminated final line (${lineBytes} bytes)`);
281
+ this.lineBytes = lineBytes;
282
+ }
283
+ }
284
+ function lineLimit(value) {
285
+ const resolved = value ?? DEFAULT_STREAM_LINE_BYTES;
286
+ assertPositiveSafeInteger("maxLineBytes", resolved);
287
+ return resolved;
288
+ }
289
+ function createLineSplitter(maxLineBytes, requireFinalNewline = false) {
290
+ const limit = lineLimit(maxLineBytes);
291
+ const decoder = new TextDecoder("utf-8", { fatal: true });
292
+ let parts = [];
293
+ let pendingBytes = 0;
294
+ let ended = false;
295
+ let failed = false;
296
+ const drop = () => {
297
+ parts = [];
298
+ pendingBytes = 0;
299
+ };
300
+ const retain = (bytes) => {
301
+ if (bytes.byteLength === 0)
302
+ return;
303
+ pendingBytes += bytes.byteLength;
304
+ if (pendingBytes > limit) {
305
+ const seen = pendingBytes;
306
+ drop();
307
+ throw new StreamLineLimitError2(limit, seen);
308
+ }
309
+ parts.push(new Uint8Array(bytes));
310
+ };
311
+ const take = () => {
312
+ const line = new Uint8Array(pendingBytes);
313
+ let at = 0;
314
+ for (const part of parts) {
315
+ line.set(part, at);
316
+ at += part.byteLength;
317
+ }
318
+ drop();
319
+ return decoder.decode(line);
320
+ };
321
+ function* lines(chunk) {
322
+ if (ended)
323
+ throw new Error("Line decoder received bytes after end()");
324
+ if (failed)
325
+ throw new Error("Line decoder stopped at an earlier error; read the source again");
326
+ try {
327
+ let start = 0;
328
+ for (let index = chunk.indexOf(10);index !== -1; index = chunk.indexOf(10, start)) {
329
+ retain(chunk.subarray(start, index));
330
+ yield take();
331
+ start = index + 1;
332
+ }
333
+ retain(chunk.subarray(start));
334
+ } catch (error) {
335
+ failed = true;
336
+ throw error;
337
+ }
338
+ }
339
+ return {
340
+ lines,
341
+ push: (chunk) => [...lines(chunk)],
342
+ end() {
343
+ ended = true;
344
+ if (pendingBytes === 0)
345
+ return [];
346
+ if (requireFinalNewline) {
347
+ const seen = pendingBytes;
348
+ drop();
349
+ throw new StreamTruncatedLineError2(seen);
350
+ }
351
+ return [take()];
352
+ }
353
+ };
354
+ }
355
+ function createBoundedLineDecoder(maxLineBytes, requireFinalNewline = false) {
356
+ const { push, end } = createLineSplitter(maxLineBytes, requireFinalNewline);
357
+ return { push, end };
358
+ }
359
+ async function* readBoundedUtf8Lines(source, maxLineBytes, requireFinalNewline = false, signal) {
360
+ const splitter = createLineSplitter(maxLineBytes, requireFinalNewline);
361
+ for await (const chunk of chunksOf(source, signal)) {
362
+ for (const line of splitter.lines(chunk)) {
363
+ signal?.throwIfAborted();
364
+ yield line;
365
+ }
366
+ }
367
+ for (const line of splitter.end()) {
368
+ signal?.throwIfAborted();
369
+ yield line;
370
+ }
371
+ }
372
+
373
+ // src/browser/stream.ts
374
+ function ndjsonLine(rawLine) {
375
+ return (rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine).trim();
376
+ }
377
+ function parseFailure(raw, error, onParseError) {
378
+ const failure = error instanceof Error ? error : new Error(String(error));
379
+ if (!onParseError)
380
+ throw failure;
381
+ onParseError(raw, failure);
382
+ }
383
+ async function* parseNDJSON2(source, options) {
384
+ let reporting = false;
385
+ try {
386
+ for await (const rawLine of readBoundedUtf8Lines(source, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, options?.finalLine === "require-newline", options?.signal)) {
387
+ const line = ndjsonLine(rawLine);
388
+ if (line === "")
389
+ continue;
390
+ let value;
391
+ try {
392
+ value = JSON.parse(line);
393
+ } catch (error) {
394
+ reporting = true;
395
+ parseFailure(line, error, options?.onParseError);
396
+ reporting = false;
397
+ continue;
398
+ }
399
+ yield value;
400
+ }
401
+ } catch (error) {
402
+ if (reporting || options?.signal?.aborted)
403
+ throw error;
404
+ parseFailure("", error, options?.onParseError);
405
+ }
406
+ }
407
+ function createNDJSONDecoder2(options) {
408
+ const lines = createBoundedLineDecoder(options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, options?.finalLine === "require-newline");
409
+ let failed = false;
410
+ const values = (rawLines) => {
411
+ const parsed = [];
412
+ for (const rawLine of rawLines) {
413
+ const line = ndjsonLine(rawLine);
414
+ if (line === "")
415
+ continue;
416
+ try {
417
+ parsed.push(JSON.parse(line));
418
+ } catch (error) {
419
+ parseFailure(line, error, options?.onParseError);
420
+ }
421
+ }
422
+ return parsed;
423
+ };
424
+ const guarded = (step) => {
425
+ if (failed)
426
+ throw new Error("NDJSON decoder stopped at an earlier error; read the source again");
427
+ try {
428
+ return values(step());
429
+ } catch (error) {
430
+ failed = true;
431
+ throw error;
432
+ }
433
+ };
434
+ return {
435
+ push: (chunk) => guarded(() => lines.push(chunk)),
436
+ end: () => guarded(() => lines.end())
437
+ };
438
+ }
439
+ async function* parseSSE2(source, options) {
440
+ let reporting = false;
441
+ try {
442
+ for await (const rawLine of readBoundedUtf8Lines(source, options?.maxLineBytes ?? DEFAULT_STREAM_LINE_BYTES, false, options?.signal)) {
443
+ const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
444
+ if (!line.startsWith("data:"))
445
+ continue;
446
+ const data = line.slice(5).replace(/^ /, "");
447
+ if (data === "[DONE]")
448
+ return;
449
+ let value;
450
+ try {
451
+ value = JSON.parse(data);
452
+ } catch (error) {
453
+ reporting = true;
454
+ parseFailure(data, error, options?.onParseError);
455
+ reporting = false;
456
+ continue;
457
+ }
458
+ yield value;
459
+ }
460
+ } catch (error) {
461
+ if (reporting || options?.signal?.aborted)
462
+ throw error;
463
+ parseFailure("", error, options?.onParseError);
464
+ }
465
+ }
466
+
467
467
  // src/browser/contract-stream.ts
468
468
  function sourceFor(response, descriptor) {
469
469
  const options = {
@@ -1,6 +1,11 @@
1
1
  import {
2
2
  resolveRouteParamsSchema
3
3
  } from "./index-m38ej7e5.js";
4
+ import {
5
+ TOOL_TRANSPORTS2,
6
+ isHttpOnlyEndpoint,
7
+ assertEndpointExposure
8
+ } from "./index-69t14s4a.js";
4
9
  import {
5
10
  isUnsafeKey
6
11
  } from "./index-zsarb5xp.js";
@@ -11,71 +16,10 @@ import {
11
16
  isRecord
12
17
  } from "./index-9jfdm5tg.js";
13
18
 
14
- // src/contract/tool-view.ts
15
- import { z } from "zod";
16
- var DECLARED_TOOL_VIEW = Symbol.for("stitchkit.toolView");
17
- function withToolView2(endpoint, view) {
18
- const declared = { ...view, [DECLARED_TOOL_VIEW]: true };
19
- return { ...endpoint, tool: { ...endpoint.tool, view: declared } };
20
- }
21
- function objectKeys(schema) {
22
- return schema instanceof z.ZodObject ? new Set(Object.keys(schema.shape)) : new Set;
23
- }
24
- function assertToolView(prefix, key, ep) {
25
- const where = `Contract "${prefix}": endpoint "${key}" tool.view`;
26
- const tool = Reflect.get(ep, "tool");
27
- const view = isRecord(tool) ? tool.view : undefined;
28
- if (!isRecord(view))
29
- throw new Error(`${where} must be an object`);
30
- if (Reflect.get(view, DECLARED_TOOL_VIEW) !== true) {
31
- throw new Error(`${where} must be declared with withToolView, which types its project`);
32
- }
33
- if (ep.rawResponse || ep.rawBody || ep.multipart || "responseMeta" in ep || "stream" in ep) {
34
- throw new Error(`${where} is only for a JSON tool endpoint — this one is HTTP-only by kind`);
35
- }
36
- if (!ep.output) {
37
- throw new Error(`${where} needs the endpoint's full output — the view is derived from it`);
38
- }
39
- const output = view.output;
40
- const project = view.project;
41
- if (output !== undefined && !(output instanceof z.ZodType)) {
42
- throw new Error(`${where}.output must be a Zod schema`);
43
- }
44
- if (project !== undefined && typeof project !== "function") {
45
- throw new Error(`${where}.project must be a function`);
46
- }
47
- const defaults = view.defaults;
48
- if (defaults !== undefined && !isRecord(defaults)) {
49
- throw new Error(`${where}.defaults must be an object`);
50
- }
51
- const entries = defaults === undefined ? [] : Object.entries(defaults);
52
- if (output === undefined && project === undefined && entries.length === 0) {
53
- throw new Error(`${where} declares no defaults, output or project — it would change nothing`);
54
- }
55
- if (entries.length === 0)
56
- return;
57
- if (!(ep.input instanceof z.ZodObject)) {
58
- throw new Error(`${where}.defaults needs an object input schema to name keys of`);
59
- }
60
- const inputKeys = objectKeys(ep.input);
61
- const paramKeys = objectKeys(ep.params);
62
- for (const [name, value] of entries) {
63
- if (paramKeys.has(name)) {
64
- throw new Error(`${where}.defaults.${name} is a path param — a route segment has no default`);
65
- }
66
- if (!inputKeys.has(name)) {
67
- throw new Error(`${where}.defaults.${name} is not a key of the endpoint's input`);
68
- }
69
- const field = ep.input.shape[name];
70
- if (field === undefined || !z.safeParse(field, value).success) {
71
- throw new Error(`${where}.defaults.${name} is not a valid value for that input key`);
72
- }
73
- }
74
- }
75
-
76
19
  // src/contract/define-validation.ts
77
20
  function assertMultipartEndpoint(prefix, key, ep) {
78
21
  const where = `Contract "${prefix}": multipart endpoint "${key}"`;
22
+ assertNoToolOptions(where, ep);
79
23
  if (ep.method !== "POST" && ep.method !== "PUT" && ep.method !== "PATCH") {
80
24
  throw new Error(`${where} must use POST, PUT or PATCH`);
81
25
  }
@@ -113,10 +57,6 @@ function assertRawEndpoint(prefix, key, ep) {
113
57
  if (ep.output)
114
58
  throw new Error(`${where} cannot declare an output schema`);
115
59
  assertNoToolOptions(where, ep);
116
- const nonHttp = (ep.expose ?? []).filter((t) => t !== "HTTP");
117
- if (nonHttp.length > 0) {
118
- throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
119
- }
120
60
  }
121
61
  function assertStreamingResponseEndpoint(prefix, key, ep) {
122
62
  const where = `Contract "${prefix}": streaming endpoint "${key}"`;
@@ -153,10 +93,6 @@ function assertStreamingResponseEndpoint(prefix, key, ep) {
153
93
  if (ep.multipart)
154
94
  throw new Error(`${where} cannot be multipart`);
155
95
  assertNoToolOptions(where, ep);
156
- const nonHttp = (ep.expose ?? []).filter((transport) => transport !== "HTTP");
157
- if (nonHttp.length > 0) {
158
- throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
159
- }
160
96
  }
161
97
  var UNGROUPED_TOOL_OPTIONS = {
162
98
  toolName: "tool.name",
@@ -214,10 +150,6 @@ function assertRawBodyEndpoint(prefix, key, ep) {
214
150
  throw new Error(`${where} must use POST, PUT or PATCH`);
215
151
  }
216
152
  assertNoToolOptions(where, ep);
217
- const nonHttp = (ep.expose ?? []).filter((transport) => transport !== "HTTP");
218
- if (nonHttp.length > 0) {
219
- throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
220
- }
221
153
  }
222
154
  function assertSafelistedBodyEndpoint(prefix, key, ep) {
223
155
  const where = `Contract "${prefix}": safelistedBody endpoint "${key}"`;
@@ -245,15 +177,71 @@ function assertResponseMetaEndpoint(prefix, key, ep) {
245
177
  if (ep.rawResponse)
246
178
  throw new Error(`${where} cannot also be a rawResponse endpoint`);
247
179
  assertNoToolOptions(where, ep);
248
- const nonHttp = (ep.expose ?? []).filter((transport) => transport !== "HTTP");
249
- if (nonHttp.length > 0) {
250
- throw new Error(`${where} is HTTP-only — remove ${nonHttp.join(", ")} from expose`);
180
+ }
181
+
182
+ // src/contract/tool-view.ts
183
+ import { z } from "zod";
184
+ var DECLARED_TOOL_VIEW = Symbol.for("stitchkit.toolView");
185
+ function withToolView2(endpoint, view) {
186
+ const declared = { ...view, [DECLARED_TOOL_VIEW]: true };
187
+ return { ...endpoint, tool: { ...endpoint.tool, view: declared } };
188
+ }
189
+ function objectKeys(schema) {
190
+ return schema instanceof z.ZodObject ? new Set(Object.keys(schema.shape)) : new Set;
191
+ }
192
+ function assertToolView(prefix, key, ep) {
193
+ const where = `Contract "${prefix}": endpoint "${key}" tool.view`;
194
+ const tool = Reflect.get(ep, "tool");
195
+ const view = isRecord(tool) ? tool.view : undefined;
196
+ if (!isRecord(view))
197
+ throw new Error(`${where} must be an object`);
198
+ if (Reflect.get(view, DECLARED_TOOL_VIEW) !== true) {
199
+ throw new Error(`${where} must be declared with withToolView, which types its project`);
200
+ }
201
+ if (isHttpOnlyEndpoint(ep)) {
202
+ throw new Error(`${where} is only for a JSON tool endpoint — this one is HTTP-only by kind`);
203
+ }
204
+ if (!ep.output) {
205
+ throw new Error(`${where} needs the endpoint's full output — the view is derived from it`);
206
+ }
207
+ const output = view.output;
208
+ const project = view.project;
209
+ if (output !== undefined && !(output instanceof z.ZodType)) {
210
+ throw new Error(`${where}.output must be a Zod schema`);
211
+ }
212
+ if (project !== undefined && typeof project !== "function") {
213
+ throw new Error(`${where}.project must be a function`);
214
+ }
215
+ const defaults = view.defaults;
216
+ if (defaults !== undefined && !isRecord(defaults)) {
217
+ throw new Error(`${where}.defaults must be an object`);
218
+ }
219
+ const entries = defaults === undefined ? [] : Object.entries(defaults);
220
+ if (output === undefined && project === undefined && entries.length === 0) {
221
+ throw new Error(`${where} declares no defaults, output or project — it would change nothing`);
222
+ }
223
+ if (entries.length === 0)
224
+ return;
225
+ if (!(ep.input instanceof z.ZodObject)) {
226
+ throw new Error(`${where}.defaults needs an object input schema to name keys of`);
227
+ }
228
+ const inputKeys = objectKeys(ep.input);
229
+ const paramKeys = objectKeys(ep.params);
230
+ for (const [name, value] of entries) {
231
+ if (paramKeys.has(name)) {
232
+ throw new Error(`${where}.defaults.${name} is a path param — a route segment has no default`);
233
+ }
234
+ if (!inputKeys.has(name)) {
235
+ throw new Error(`${where}.defaults.${name} is not a key of the endpoint's input`);
236
+ }
237
+ const field = ep.input.shape[name];
238
+ if (field === undefined || !z.safeParse(field, value).success) {
239
+ throw new Error(`${where}.defaults.${name} is not a valid value for that input key`);
240
+ }
251
241
  }
252
242
  }
253
243
 
254
244
  // src/contract/define.ts
255
- var ALL_TRANSPORTS2 = ["HTTP", "MCP", "AGENT", "CLI"];
256
- var TOOL_TRANSPORTS2 = ["MCP", "AGENT", "CLI"];
257
245
  function defineContract2(meta, endpoints) {
258
246
  const materializedEndpoints = {};
259
247
  for (const [key, endpoint] of Object.entries(endpoints)) {
@@ -262,6 +250,7 @@ function defineContract2(meta, endpoints) {
262
250
  }
263
251
  const toolTransports = new Map;
264
252
  for (const [key, ep] of Object.entries(materializedEndpoints)) {
253
+ assertEndpointExposure(meta.prefix, key, ep);
265
254
  if (ep.desc.trim() === "") {
266
255
  throw new Error(`Contract "${meta.prefix}": endpoint "${key}" has an empty desc`);
267
256
  }
@@ -289,7 +278,7 @@ function defineContract2(meta, endpoints) {
289
278
  }
290
279
  const transports = new Set(ep.expose ? ep.expose.filter((t) => t !== "HTTP") : ["MCP", "AGENT"]);
291
280
  if (transports.size === 0) {
292
- throw new Error(`Contract "${meta.prefix}": endpoint "${key}" sets tool options but is not exposed on any tool transport (${TOOL_TRANSPORTS2.join(" / ")}) — a contract factory with toolExposure 'explicit' makes an omitted expose HTTP-only`);
281
+ throw new Error(`Contract "${meta.prefix}": endpoint "${key}" sets tool options but is not exposed on any tool transport (${TOOL_TRANSPORTS2.join(" / ")}) — add a tool transport to expose or the factory default`);
293
282
  }
294
283
  if (tool.view !== undefined)
295
284
  assertToolView(meta.prefix, key, ep);
@@ -310,4 +299,4 @@ function defineContract2(meta, endpoints) {
310
299
  return { meta, endpoints: materializedEndpoints };
311
300
  }
312
301
 
313
- export { withToolView2, ALL_TRANSPORTS2, TOOL_TRANSPORTS2, defineContract2 };
302
+ export { withToolView2, defineContract2 };
@@ -8,7 +8,7 @@ import {
8
8
  AgentSeedReceiptSchema2,
9
9
  AgentHistoryMutationSchema2,
10
10
  isActiveRunState
11
- } from "./index-xx1j310k.js";
11
+ } from "./index-8yxgcyt6.js";
12
12
  import {
13
13
  AgentRecordIdSchema2,
14
14
  AgentMessageSchema2
@@ -17,7 +17,7 @@ import {
17
17
  replaceMessage,
18
18
  ArchiveSpillSchema,
19
19
  createAgentRuntimeStore2
20
- } from "./index-cycp3r3e.js";
20
+ } from "./index-rxcgp4b9.js";
21
21
 
22
22
  // src/agent-runtime/store-memory.ts
23
23
  import { z as z2 } from "zod";
@@ -0,0 +1,39 @@
1
+ // src/contract/endpoint-capabilities.ts
2
+ import { z } from "zod";
3
+
4
+ // src/contract/transports.ts
5
+ var ALL_TRANSPORTS2 = ["HTTP", "MCP", "AGENT", "CLI"];
6
+ var TOOL_TRANSPORTS2 = ["MCP", "AGENT", "CLI"];
7
+
8
+ // src/contract/endpoint-capabilities.ts
9
+ var HTTP_ONLY_FEATURES = [
10
+ "rawResponse",
11
+ "rawBody",
12
+ "responseMeta",
13
+ "multipart",
14
+ "stream"
15
+ ];
16
+ var HTTP_ONLY_EXPOSURE = Object.freeze(["HTTP"]);
17
+ var ExposureSchema = z.array(z.enum(ALL_TRANSPORTS2)).refine((transports) => new Set(transports).size === transports.length, {
18
+ message: "Each transport appears at most once"
19
+ }).readonly();
20
+ function isHttpOnlyEndpoint(endpoint) {
21
+ return endpoint.method === "HEAD" || HTTP_ONLY_FEATURES.some((feature) => Boolean(endpoint[feature]));
22
+ }
23
+ function assertEndpointExposure(prefix, key, endpoint) {
24
+ if (endpoint.expose === undefined)
25
+ return;
26
+ const exposure = ExposureSchema.safeParse(endpoint.expose);
27
+ const where = `Contract "${prefix}": endpoint "${key}"`;
28
+ if (!exposure.success) {
29
+ throw new Error(`${where} expose must be an array of distinct transports: ${ALL_TRANSPORTS2.join(" / ")}`);
30
+ }
31
+ if (isHttpOnlyEndpoint(endpoint)) {
32
+ const unsupported = exposure.data.filter((transport) => transport !== "HTTP");
33
+ if (unsupported.length > 0) {
34
+ throw new Error(`${where} is HTTP-only — remove ${unsupported.join(", ")} from expose`);
35
+ }
36
+ }
37
+ }
38
+
39
+ export { ALL_TRANSPORTS2, TOOL_TRANSPORTS2, HTTP_ONLY_EXPOSURE, ExposureSchema, isHttpOnlyEndpoint, assertEndpointExposure };