stitchkit 0.36.1 → 0.37.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 (81) hide show
  1. package/README.md +4 -2
  2. package/dist/browser/http.d.ts +2 -2
  3. package/dist/browser/http.d.ts.map +1 -1
  4. package/dist/cli.js +3 -3
  5. package/dist/contract/define.d.ts +28 -2
  6. package/dist/contract/define.d.ts.map +1 -1
  7. package/dist/contract/errors.d.ts.map +1 -1
  8. package/dist/contract/index.js +1 -1
  9. package/dist/{index-dvrn81q4.js → index-4pvtq6h2.js} +83 -34
  10. package/dist/{index-0ed3bx43.js → index-frfyw9fa.js} +2 -2
  11. package/dist/{index-pmftwk2a.js → index-g3jrbd0z.js} +26 -0
  12. package/dist/{index-82gncajj.js → index-s6yhmg1k.js} +555 -337
  13. package/dist/{index-bx49hskg.js → index-xq45akyd.js} +1 -1
  14. package/dist/index.js +1 -1
  15. package/dist/node.d.ts +1 -1
  16. package/dist/node.d.ts.map +1 -1
  17. package/dist/node.js +7 -3
  18. package/dist/observability/index.js +3 -3
  19. package/dist/server/bun.d.ts +32 -0
  20. package/dist/server/bun.d.ts.map +1 -0
  21. package/dist/server/context.d.ts +1 -1
  22. package/dist/server/context.d.ts.map +1 -1
  23. package/dist/server/create.d.ts +2 -3
  24. package/dist/server/create.d.ts.map +1 -1
  25. package/dist/server/implement.d.ts.map +1 -1
  26. package/dist/server/index.d.ts +3 -2
  27. package/dist/server/index.d.ts.map +1 -1
  28. package/dist/server/index.js +25 -5
  29. package/dist/server/logger.d.ts +5 -5
  30. package/dist/server/logger.d.ts.map +1 -1
  31. package/dist/server/logging.d.ts +4 -1
  32. package/dist/server/logging.d.ts.map +1 -1
  33. package/dist/server/middleware/auth.d.ts +2 -2
  34. package/dist/server/middleware/auth.d.ts.map +1 -1
  35. package/dist/server/request-body.d.ts +4 -0
  36. package/dist/server/request-body.d.ts.map +1 -0
  37. package/dist/server/router.d.ts +3 -3
  38. package/dist/server/router.d.ts.map +1 -1
  39. package/dist/server/socket-io-config.d.ts +20 -0
  40. package/dist/server/socket-io-config.d.ts.map +1 -0
  41. package/dist/server/socket-io-node.d.ts +14 -0
  42. package/dist/server/socket-io-node.d.ts.map +1 -0
  43. package/dist/server/socket-io.d.ts +5 -32
  44. package/dist/server/socket-io.d.ts.map +1 -1
  45. package/dist/server/types.d.ts +54 -49
  46. package/dist/server/types.d.ts.map +1 -1
  47. package/dist/tools/agent.d.ts.map +1 -1
  48. package/dist/tools/execute.d.ts +46 -16
  49. package/dist/tools/execute.d.ts.map +1 -1
  50. package/dist/tools/flatten-join.d.ts +8 -0
  51. package/dist/tools/flatten-join.d.ts.map +1 -0
  52. package/dist/tools/flatten.d.ts +7 -44
  53. package/dist/tools/flatten.d.ts.map +1 -1
  54. package/dist/tools/json-schema.d.ts +1 -1
  55. package/dist/tools/json-schema.d.ts.map +1 -1
  56. package/dist/tools/manifest.d.ts.map +1 -1
  57. package/dist/tools/mcp-handler.d.ts +7 -13
  58. package/dist/tools/mcp-handler.d.ts.map +1 -1
  59. package/dist/tools/mcp.d.ts +61 -24
  60. package/dist/tools/mcp.d.ts.map +1 -1
  61. package/dist/tools/mount.d.ts +9 -6
  62. package/dist/tools/mount.d.ts.map +1 -1
  63. package/dist/tools/names.d.ts +1 -1
  64. package/dist/tools/native-mcp.d.ts +57 -0
  65. package/dist/tools/native-mcp.d.ts.map +1 -0
  66. package/dist/tools/portable-formats.d.ts +15 -0
  67. package/dist/tools/portable-formats.d.ts.map +1 -0
  68. package/dist/tools/presentation.d.ts +15 -0
  69. package/dist/tools/presentation.d.ts.map +1 -0
  70. package/dist/tools/remote.d.ts.map +1 -1
  71. package/dist/tools/schema.d.ts +3 -8
  72. package/dist/tools/schema.d.ts.map +1 -1
  73. package/dist/tools/tool-logger.d.ts.map +1 -1
  74. package/dist/tools/view-file.d.ts +5 -3
  75. package/dist/tools/view-file.d.ts.map +1 -1
  76. package/dist/tools.d.ts +7 -4
  77. package/dist/tools.d.ts.map +1 -1
  78. package/dist/tools.js +357 -95
  79. package/llms-full.txt +371 -77
  80. package/package.json +14 -11
  81. /package/dist/{index-17rdjw68.js → index-e497hxcy.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  jsonSchemaFields,
3
3
  toJsonSchema
4
- } from "./index-0ed3bx43.js";
4
+ } from "./index-frfyw9fa.js";
5
5
  import {
6
6
  isWithinDir
7
7
  } from "./index-x3fcszf8.js";
@@ -14,7 +14,7 @@ import {
14
14
  runWithRequestContext,
15
15
  safeJsonParse,
16
16
  validateHandlerOutput
17
- } from "./index-17rdjw68.js";
17
+ } from "./index-e497hxcy.js";
18
18
 
19
19
  // src/tools/coerce.ts
20
20
  import { z } from "zod";
@@ -77,8 +77,325 @@ function coerceJsonArgs(args, schema) {
77
77
  return isRecord(coerced) ? coerced : args;
78
78
  }
79
79
 
80
+ // src/tools/flatten-join.ts
81
+ var ANNOTATION_KEYS = new Set(["$schema", "default", "description", "examples", "title"]);
82
+ var TYPE_KEYWORDS = {
83
+ array: [
84
+ "contains",
85
+ "items",
86
+ "maxContains",
87
+ "maxItems",
88
+ "minContains",
89
+ "minItems",
90
+ "prefixItems",
91
+ "uniqueItems"
92
+ ],
93
+ integer: ["exclusiveMaximum", "exclusiveMinimum", "maximum", "minimum", "multipleOf"],
94
+ number: ["exclusiveMaximum", "exclusiveMinimum", "maximum", "minimum", "multipleOf"],
95
+ object: [
96
+ "additionalProperties",
97
+ "dependentRequired",
98
+ "dependentSchemas",
99
+ "maxProperties",
100
+ "minProperties",
101
+ "patternProperties",
102
+ "properties",
103
+ "propertyNames",
104
+ "required"
105
+ ],
106
+ string: [
107
+ "contentEncoding",
108
+ "contentMediaType",
109
+ "format",
110
+ "maxLength",
111
+ "minLength",
112
+ "pattern"
113
+ ]
114
+ };
115
+ function nullableProjection(schema) {
116
+ if (!Array.isArray(schema.anyOf) || schema.anyOf.length !== 2)
117
+ return schema;
118
+ const branches = schema.anyOf.filter(isRecord);
119
+ if (branches.length !== 2)
120
+ return schema;
121
+ const nullBranch = branches.find((branch) => branch.type === "null");
122
+ const value = branches.find((branch) => typeof branch.type === "string" && branch.type !== "null");
123
+ if (!nullBranch || !value || Object.keys(nullBranch).some((key) => key !== "type")) {
124
+ return schema;
125
+ }
126
+ const type = value.type;
127
+ if (typeof type !== "string")
128
+ return schema;
129
+ const projected = { type: [type, "null"] };
130
+ for (const key of [...ANNOTATION_KEYS, ...TYPE_KEYWORDS[type] ?? []]) {
131
+ if (value[key] !== undefined)
132
+ projected[key] = value[key];
133
+ else if (schema[key] !== undefined)
134
+ projected[key] = schema[key];
135
+ }
136
+ if (value.const !== undefined)
137
+ projected.enum = [value.const, null];
138
+ else if (Array.isArray(value.enum))
139
+ projected.enum = [...value.enum, null];
140
+ return projected;
141
+ }
142
+ function withoutAnnotations(schema) {
143
+ const result = {};
144
+ for (const [key, value] of Object.entries(schema)) {
145
+ if (!ANNOTATION_KEYS.has(key))
146
+ result[key] = value;
147
+ }
148
+ return result;
149
+ }
150
+ function stableJson(value) {
151
+ if (Array.isArray(value))
152
+ return `[${value.map(stableJson).join(",")}]`;
153
+ if (!isRecord(value))
154
+ return JSON.stringify(value) ?? "undefined";
155
+ return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
156
+ }
157
+ function stringValues(schema) {
158
+ if (typeof schema.const === "string")
159
+ return [schema.const];
160
+ if (!Array.isArray(schema.enum))
161
+ return null;
162
+ const values = schema.enum.filter((value) => typeof value === "string");
163
+ return values.length === schema.enum.length ? values : null;
164
+ }
165
+ function typeNames(schema) {
166
+ if (typeof schema.type === "string")
167
+ return [schema.type];
168
+ if (Array.isArray(schema.type)) {
169
+ const values2 = schema.type.filter((value) => typeof value === "string");
170
+ if (values2.length === schema.type.length)
171
+ return values2;
172
+ }
173
+ const values = stringValues(schema);
174
+ if (values)
175
+ return ["string"];
176
+ if (typeof schema.const === "number")
177
+ return ["number"];
178
+ if (typeof schema.const === "boolean")
179
+ return ["boolean"];
180
+ return null;
181
+ }
182
+ function typeSchema(type, nullable) {
183
+ const schema = { type: nullable ? [type, "null"] : type };
184
+ if (type === "array")
185
+ schema.items = {};
186
+ if (type === "object")
187
+ schema.additionalProperties = {};
188
+ return schema;
189
+ }
190
+ function commonBaseType(schemas) {
191
+ const names = schemas.map(typeNames);
192
+ if (names.some((value) => value === null))
193
+ return {};
194
+ let nullable = false;
195
+ const bases = new Set;
196
+ for (const branch of names) {
197
+ if (!branch)
198
+ return {};
199
+ for (const name of branch) {
200
+ if (name === "null")
201
+ nullable = true;
202
+ else
203
+ bases.add(name);
204
+ }
205
+ }
206
+ if (bases.size === 1) {
207
+ const [only] = bases;
208
+ return only ? typeSchema(only, nullable) : {};
209
+ }
210
+ if ([...bases].every((name) => name === "integer" || name === "number")) {
211
+ return typeSchema("number", nullable);
212
+ }
213
+ return {};
214
+ }
215
+ function mergePropertySchemas(properties) {
216
+ const schemas = properties.map((property) => nullableProjection(property.schema));
217
+ const structural = schemas.map(withoutAnnotations);
218
+ const [first] = structural;
219
+ let merged;
220
+ if (first && structural.every((schema) => stableJson(schema) === stableJson(first))) {
221
+ merged = structuredClone(first);
222
+ } else {
223
+ const values = schemas.map(stringValues);
224
+ const allStrings = values.every((value) => value !== null);
225
+ merged = allStrings ? { type: "string", enum: [...new Set(values.flatMap((value) => value ?? []))] } : commonBaseType(schemas);
226
+ }
227
+ const descriptions = [
228
+ ...new Set(schemas.map((schema) => schema.description).filter((value) => typeof value === "string"))
229
+ ];
230
+ if (descriptions.length === 1)
231
+ merged.description = descriptions[0];
232
+ return merged;
233
+ }
234
+
80
235
  // src/tools/flatten.ts
81
- import { z as z3 } from "zod";
236
+ function rebuild(value) {
237
+ if (Array.isArray(value))
238
+ return value.map(rebuild);
239
+ if (!isRecord(value))
240
+ return value;
241
+ const node = {};
242
+ for (const [key, child] of Object.entries(value))
243
+ node[key] = rebuild(child);
244
+ return flattenNode(node);
245
+ }
246
+ function stringValues2(schema) {
247
+ if (typeof schema.const === "string")
248
+ return [schema.const];
249
+ if (!Array.isArray(schema.enum))
250
+ return null;
251
+ const values = schema.enum.filter((value) => typeof value === "string");
252
+ return values.length === schema.enum.length ? values : null;
253
+ }
254
+ function objectVariants(node) {
255
+ if (!Array.isArray(node.oneOf) || node.oneOf.length < 2)
256
+ return null;
257
+ const variants = node.oneOf.filter(isRecord);
258
+ if (variants.length !== node.oneOf.length)
259
+ return null;
260
+ if (variants.some((variant) => variant.type !== "object" || !isRecord(variant.properties))) {
261
+ return null;
262
+ }
263
+ return variants;
264
+ }
265
+ function findDiscriminator(variants) {
266
+ const [first] = variants;
267
+ if (!first || !isRecord(first.properties))
268
+ return null;
269
+ for (const key of Object.keys(first.properties).sort()) {
270
+ const values = [];
271
+ const seen = new Set;
272
+ let valid = true;
273
+ for (const variant of variants) {
274
+ if (!requiredKeys(variant).has(key)) {
275
+ valid = false;
276
+ break;
277
+ }
278
+ const properties = variant.properties;
279
+ const field = isRecord(properties) ? properties[key] : undefined;
280
+ const branchValues = isRecord(field) ? stringValues2(field) : null;
281
+ if (!branchValues || branchValues.length === 0) {
282
+ valid = false;
283
+ break;
284
+ }
285
+ for (const value of branchValues) {
286
+ if (seen.has(value)) {
287
+ valid = false;
288
+ break;
289
+ }
290
+ seen.add(value);
291
+ }
292
+ if (!valid)
293
+ break;
294
+ values.push(branchValues);
295
+ }
296
+ if (valid)
297
+ return { key, values };
298
+ }
299
+ return null;
300
+ }
301
+ function requiredKeys(variant) {
302
+ if (!Array.isArray(variant.required))
303
+ return new Set;
304
+ return new Set(variant.required.filter((key) => typeof key === "string"));
305
+ }
306
+ function appendHint(schema, hint) {
307
+ const description = typeof schema.description === "string" ? schema.description : undefined;
308
+ return { ...schema, description: description ? `${description} ${hint}` : hint };
309
+ }
310
+ function flattenNode(node) {
311
+ const variants = objectVariants(node);
312
+ if (!variants)
313
+ return node;
314
+ const discriminator = findDiscriminator(variants);
315
+ if (!discriminator)
316
+ return node;
317
+ const perKey = new Map;
318
+ for (let index = 0;index < variants.length; index++) {
319
+ const variant = variants[index];
320
+ if (!variant)
321
+ continue;
322
+ const labels = discriminator.values[index] ?? [];
323
+ const required2 = requiredKeys(variant);
324
+ if (!isRecord(variant.properties))
325
+ continue;
326
+ for (const [key, rawSchema] of Object.entries(variant.properties)) {
327
+ if (key === discriminator.key || !isRecord(rawSchema))
328
+ continue;
329
+ const entries = perKey.get(key) ?? [];
330
+ entries.push({ schema: rawSchema, labels, required: required2.has(key) });
331
+ perKey.set(key, entries);
332
+ }
333
+ }
334
+ const discriminatorProperties = [];
335
+ for (let index = 0;index < variants.length; index++) {
336
+ const variant = variants[index];
337
+ if (!variant || !isRecord(variant.properties))
338
+ continue;
339
+ const schema = variant.properties[discriminator.key];
340
+ if (!isRecord(schema))
341
+ continue;
342
+ discriminatorProperties.push({
343
+ schema,
344
+ labels: discriminator.values[index] ?? [],
345
+ required: true
346
+ });
347
+ }
348
+ const properties = {
349
+ [discriminator.key]: mergePropertySchemas(discriminatorProperties)
350
+ };
351
+ const required = [discriminator.key];
352
+ for (const [key, entries] of perKey) {
353
+ let merged = mergePropertySchemas(entries);
354
+ const requiredEverywhere = entries.length === variants.length && entries.every((entry) => entry.required);
355
+ if (requiredEverywhere) {
356
+ required.push(key);
357
+ } else {
358
+ const requiredLabels = entries.filter((entry) => entry.required).flatMap((entry) => entry.labels);
359
+ const presentLabels = entries.flatMap((entry) => entry.labels);
360
+ const labels = requiredLabels.length > 0 ? requiredLabels : presentLabels;
361
+ const verb = requiredLabels.length > 0 ? "Required" : "Available";
362
+ merged = appendHint(merged, `${verb} if ${discriminator.key} = ${[...new Set(labels)].join(" | ")}`);
363
+ }
364
+ properties[key] = merged;
365
+ }
366
+ const result = {};
367
+ for (const [key, value] of Object.entries(node)) {
368
+ if (key !== "oneOf" && key !== "anyOf" && key !== "properties" && key !== "required") {
369
+ result[key] = value;
370
+ }
371
+ }
372
+ result.type = "object";
373
+ result.properties = properties;
374
+ result.required = required;
375
+ result.additionalProperties = variants.every((variant) => variant.additionalProperties === false) ? false : {};
376
+ return result;
377
+ }
378
+ function flattenToolJsonSchema(schema) {
379
+ const result = rebuild(schema);
380
+ return isRecord(result) ? result : {};
381
+ }
382
+ function freezeToolJsonSchema(schema) {
383
+ for (const value of Object.values(schema))
384
+ freezeJsonValue(value);
385
+ return Object.freeze(schema);
386
+ }
387
+ function freezeJsonValue(value) {
388
+ if (Array.isArray(value)) {
389
+ for (const item of value)
390
+ freezeJsonValue(item);
391
+ Object.freeze(value);
392
+ } else if (isRecord(value)) {
393
+ freezeToolJsonSchema(value);
394
+ }
395
+ }
396
+
397
+ // src/tools/mount.ts
398
+ import { z as z4 } from "zod";
82
399
 
83
400
  // src/tools/schema.ts
84
401
  import { z as z2 } from "zod";
@@ -131,300 +448,6 @@ function mergeSchemas(paramsSchema, inputSchema) {
131
448
  return paramsObject ? z2.intersection(paramsObject, inputSchema) : inputSchema;
132
449
  }
133
450
 
134
- // src/tools/flatten.ts
135
- function flattenDiscriminatedUnion(union) {
136
- const discriminator = union.def.discriminator;
137
- const allDiscValues = [];
138
- const perKey = new Map;
139
- for (const opt of union.def.options) {
140
- if (!(opt instanceof z3.ZodObject)) {
141
- throw new Error(`flattenDiscriminatedUnion: variant for discriminator '${discriminator}' is not a ZodObject`);
142
- }
143
- const discValues = stringLiteralOrEnumValues(opt.shape[discriminator]);
144
- if (discValues === null) {
145
- throw new Error(`flattenDiscriminatedUnion: discriminator '${discriminator}' must be a string z.literal() or z.enum()`);
146
- }
147
- allDiscValues.push(...discValues);
148
- const label = discValues.join(" | ");
149
- for (const [key, field] of Object.entries(opt.shape)) {
150
- if (key === discriminator)
151
- continue;
152
- const entry = perKey.get(key) ?? { schemas: [], variants: [] };
153
- entry.schemas.push(unwrapField(field));
154
- entry.variants.push(label);
155
- perKey.set(key, entry);
156
- }
157
- }
158
- const uniqDisc = [...new Set(allDiscValues)];
159
- const [firstLiteral, ...restLiterals] = uniqDisc;
160
- if (firstLiteral === undefined) {
161
- throw new Error("flattenDiscriminatedUnion: union has no options");
162
- }
163
- const shape = {
164
- [discriminator]: z3.enum([firstLiteral, ...restLiterals])
165
- };
166
- for (const [key, entry] of perKey) {
167
- const advertised = mergeCollidingFields(entry.schemas);
168
- const hint = `Required if ${discriminator} = ${[...new Set(entry.variants)].join(" | ")}`;
169
- shape[key] = z3.optional(advertised).describe(hint);
170
- }
171
- return withKeyPolicy(z3.object(shape), mergeVariantKeyPolicies(union.def.options));
172
- }
173
- function mergeVariantKeyPolicies(options) {
174
- let strict = 0;
175
- let counted = 0;
176
- for (const option of options) {
177
- const policy = option instanceof z3.ZodObject ? keyPolicyOf(option) : undefined;
178
- if (policy !== undefined && !(policy instanceof z3.ZodNever))
179
- return z3.unknown();
180
- counted++;
181
- if (policy instanceof z3.ZodNever)
182
- strict++;
183
- }
184
- if (counted === 0 || strict === 0)
185
- return;
186
- return strict === counted ? z3.never() : z3.unknown();
187
- }
188
- function unwrapField(field) {
189
- if (field instanceof z3.ZodOptional || field instanceof z3.ZodDefault) {
190
- return unwrapField(field.unwrap());
191
- }
192
- return field;
193
- }
194
- function preserveDescription(from, to) {
195
- return from.description === undefined ? to : to.describe(from.description);
196
- }
197
- function stringLiteralOrEnumValues(field) {
198
- let raw = null;
199
- if (field instanceof z3.ZodLiteral)
200
- raw = field.def.values;
201
- else if (field instanceof z3.ZodEnum)
202
- raw = field.options;
203
- if (raw === null)
204
- return null;
205
- const strings = raw.filter((v) => typeof v === "string");
206
- return strings.length === raw.length ? strings : null;
207
- }
208
- function isFlattenableDU(union) {
209
- const disc = union.def.discriminator;
210
- if (union.def.options.length === 0)
211
- return false;
212
- for (const opt of union.def.options) {
213
- if (!(opt instanceof z3.ZodObject))
214
- return false;
215
- if (stringLiteralOrEnumValues(opt.shape[disc]) === null)
216
- return false;
217
- }
218
- return true;
219
- }
220
- function stripAnnotations(node) {
221
- if (Array.isArray(node)) {
222
- for (const item of node)
223
- stripAnnotations(item);
224
- return;
225
- }
226
- if (typeof node === "object" && node !== null) {
227
- Reflect.deleteProperty(node, "description");
228
- Reflect.deleteProperty(node, "default");
229
- Reflect.deleteProperty(node, "$schema");
230
- for (const value of Object.values(node))
231
- stripAnnotations(value);
232
- }
233
- }
234
- function hasInvisibleConstraint(schema) {
235
- if (!(schema instanceof z3.ZodType))
236
- return false;
237
- const def = schema.def;
238
- if (isRecord(def) && def.type !== "unknown" && def.type !== "any") {
239
- if (normalizedJson(schema) === "{}")
240
- return true;
241
- }
242
- if (schema instanceof z3.ZodCatch)
243
- return true;
244
- if (isRecord(def) && def.coerce === true)
245
- return true;
246
- if (isRecord(def) && Array.isArray(def.checks)) {
247
- for (const check of def.checks) {
248
- if (isInvisibleCheck(check))
249
- return true;
250
- }
251
- }
252
- if (schema instanceof z3.ZodOptional || schema instanceof z3.ZodNullable || schema instanceof z3.ZodDefault) {
253
- return hasInvisibleConstraint(schema.unwrap());
254
- }
255
- if (schema instanceof z3.ZodPipe)
256
- return true;
257
- if (schema instanceof z3.ZodObject) {
258
- return Object.values(schema.shape).some(hasInvisibleConstraint);
259
- }
260
- if (schema instanceof z3.ZodArray)
261
- return hasInvisibleConstraint(schema.element);
262
- if (schema instanceof z3.ZodUnion)
263
- return schema.def.options.some(hasInvisibleConstraint);
264
- if (schema instanceof z3.ZodRecord)
265
- return hasInvisibleConstraint(schema.valueType);
266
- if (schema instanceof z3.ZodIntersection) {
267
- return hasInvisibleConstraint(schema.def.left) || hasInvisibleConstraint(schema.def.right);
268
- }
269
- return false;
270
- }
271
- var INVISIBLE_CHECK_KINDS = new Set(["custom", "overwrite"]);
272
- function acceptsMoreThanItsType(schema) {
273
- if (!(schema instanceof z3.ZodType))
274
- return false;
275
- if (schema instanceof z3.ZodCatch)
276
- return true;
277
- if (isRecord(schema.def) && schema.def.coerce === true)
278
- return true;
279
- if (schema instanceof z3.ZodOptional || schema instanceof z3.ZodNullable || schema instanceof z3.ZodDefault) {
280
- return acceptsMoreThanItsType(schema.unwrap());
281
- }
282
- if (schema instanceof z3.ZodPipe)
283
- return acceptsMoreThanItsType(schema.def.in);
284
- return false;
285
- }
286
- function isInvisibleCheck(check) {
287
- if (!isRecord(check))
288
- return false;
289
- const inner = check._zod;
290
- const def = isRecord(inner) ? inner.def : undefined;
291
- const kind = isRecord(def) ? def.check : undefined;
292
- return typeof kind === "string" && INVISIBLE_CHECK_KINDS.has(kind);
293
- }
294
- function projectToBaseType(schema) {
295
- if (!(schema instanceof z3.ZodType))
296
- return z3.unknown();
297
- if (schema instanceof z3.ZodNullable) {
298
- return z3.nullable(projectToBaseType(schema.unwrap()));
299
- }
300
- if (schema instanceof z3.ZodOptional || schema instanceof z3.ZodDefault) {
301
- return projectToBaseType(schema.unwrap());
302
- }
303
- if (schema instanceof z3.ZodPipe)
304
- return projectToBaseType(schema.def.in);
305
- if (schema instanceof z3.ZodCatch)
306
- return z3.unknown();
307
- const coerces = isRecord(schema.def) && schema.def.coerce === true;
308
- if (schema instanceof z3.ZodNumber)
309
- return coerces ? z3.coerce.number() : z3.number();
310
- if (schema instanceof z3.ZodString)
311
- return coerces ? z3.coerce.string() : z3.string();
312
- if (schema instanceof z3.ZodBoolean && coerces)
313
- return z3.coerce.boolean();
314
- if (schema instanceof z3.ZodEnum || schema instanceof z3.ZodLiteral) {
315
- return stringLiteralOrEnumValues(schema) === null ? z3.unknown() : z3.string();
316
- }
317
- if (schema instanceof z3.ZodBoolean)
318
- return z3.boolean();
319
- if (schema instanceof z3.ZodArray)
320
- return z3.array(z3.unknown());
321
- if (schema instanceof z3.ZodObject)
322
- return z3.looseObject({});
323
- return z3.unknown();
324
- }
325
- function normalizedJson(schema) {
326
- if (!(schema instanceof z3.ZodType))
327
- return "{}";
328
- const json = toJsonSchema(schema, "input", "any");
329
- stripAnnotations(json);
330
- return JSON.stringify(json);
331
- }
332
- function mergeCollidingFields(schemas) {
333
- const distinct = new Map;
334
- for (const schema of schemas) {
335
- const key = normalizedJson(schema);
336
- if (!distinct.has(key))
337
- distinct.set(key, schema);
338
- }
339
- const values = [...distinct.values()];
340
- const only = values[0];
341
- if (values.length <= 1) {
342
- if (only === undefined)
343
- return z3.unknown();
344
- if (schemas.length <= 1)
345
- return only;
346
- const hazards2 = schemas.map(acceptsMoreThanItsType);
347
- if (hazards2.some(Boolean) && !hazards2.every(Boolean))
348
- return z3.unknown();
349
- if (schemas.some(hasInvisibleConstraint)) {
350
- if (normalizedJson(only) === "{}")
351
- return only;
352
- return projectToBaseType(only);
353
- }
354
- return only;
355
- }
356
- const merged = [];
357
- let allEnum = true;
358
- for (const schema of values) {
359
- const vals = stringLiteralOrEnumValues(schema);
360
- if (vals === null) {
361
- allEnum = false;
362
- break;
363
- }
364
- merged.push(...vals);
365
- }
366
- if (allEnum) {
367
- const uniq = [...new Set(merged)];
368
- const [first2, ...rest] = uniq;
369
- if (first2 !== undefined)
370
- return z3.enum([first2, ...rest]);
371
- }
372
- const hazards = schemas.map(acceptsMoreThanItsType);
373
- if (hazards.some(Boolean) && !hazards.every(Boolean))
374
- return z3.unknown();
375
- const projected = values.map(projectToBaseType);
376
- const first = projected[0];
377
- if (first !== undefined) {
378
- const shape = normalizedJson(first);
379
- if (shape !== "{}" && projected.every((p) => normalizedJson(p) === shape))
380
- return first;
381
- }
382
- return z3.unknown();
383
- }
384
- function flattenUnionsDeep(schema) {
385
- if (!(schema instanceof z3.ZodType))
386
- return z3.unknown();
387
- if (schema instanceof z3.ZodDiscriminatedUnion) {
388
- if (!isFlattenableDU(schema))
389
- return schema;
390
- return preserveDescription(schema, flattenUnionsDeep(flattenDiscriminatedUnion(schema)));
391
- }
392
- if (schema instanceof z3.ZodObject) {
393
- const shape = {};
394
- for (const [key, field] of Object.entries(schema.shape)) {
395
- shape[key] = flattenUnionsDeep(field);
396
- }
397
- return preserveDescription(schema, rebuildObject(schema, shape));
398
- }
399
- if (schema instanceof z3.ZodArray) {
400
- return preserveDescription(schema, z3.array(flattenUnionsDeep(schema.element)));
401
- }
402
- if (schema instanceof z3.ZodUnion) {
403
- const opts = schema.def.options.map((option) => flattenUnionsDeep(option));
404
- const [a, b, ...rest] = opts;
405
- return a && b ? preserveDescription(schema, z3.union([a, b, ...rest])) : schema;
406
- }
407
- if (schema instanceof z3.ZodRecord) {
408
- return preserveDescription(schema, z3.record(schema.keyType, flattenUnionsDeep(schema.valueType)));
409
- }
410
- if (schema instanceof z3.ZodOptional) {
411
- return preserveDescription(schema, z3.optional(flattenUnionsDeep(schema.unwrap())));
412
- }
413
- if (schema instanceof z3.ZodNullable) {
414
- return preserveDescription(schema, z3.nullable(flattenUnionsDeep(schema.unwrap())));
415
- }
416
- if (schema instanceof z3.ZodDefault) {
417
- return preserveDescription(schema, flattenUnionsDeep(schema.unwrap()).default(schema.def.defaultValue));
418
- }
419
- if (schema instanceof z3.ZodIntersection) {
420
- return preserveDescription(schema, z3.intersection(flattenUnionsDeep(schema.def.left), flattenUnionsDeep(schema.def.right)));
421
- }
422
- return schema;
423
- }
424
-
425
- // src/tools/mount.ts
426
- import { z as z4 } from "zod";
427
-
428
451
  // src/tools/execute.ts
429
452
  function toolResultFromError(err) {
430
453
  const appErr = normalizeError(err);
@@ -435,8 +458,8 @@ function toolResultFromError(err) {
435
458
  ...appErr.hint && { hint: appErr.hint }
436
459
  };
437
460
  }
438
- async function executeToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson = false, onOutputStrip) {
439
- return inToolCallContext({ source: context.source, toolName, method }, () => runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip));
461
+ async function executeToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson = false, onOutputStrip, extension) {
462
+ return inToolCallContext({ source: context.source, toolName, method }, () => runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip, extension));
440
463
  }
441
464
  function inToolCallContext(call, body) {
442
465
  const parent = getRequestContext();
@@ -454,23 +477,93 @@ function inToolCallContext(call, body) {
454
477
  action: call.method.key
455
478
  }, body);
456
479
  }
457
- async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip) {
480
+ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycle, coerceJson, onOutputStrip, extension) {
458
481
  const startedAt = Date.now();
482
+ let hookContext = context;
459
483
  const finish = async (result, thrown) => {
460
- await hooks?.afterToolCall?.(toolName, rawArgs, result, Date.now() - startedAt, context, method, thrown);
484
+ await hooks?.afterToolCall?.({
485
+ toolName,
486
+ args: rawArgs,
487
+ result,
488
+ durationMs: Date.now() - startedAt,
489
+ context: hookContext,
490
+ endpoint: method,
491
+ ...thrown !== undefined && { error: thrown }
492
+ });
461
493
  return result;
462
494
  };
463
- if (hooks?.beforeToolCall) {
495
+ let beforeRan = false;
496
+ const runBefore = async () => {
497
+ if (beforeRan || !hooks?.beforeToolCall)
498
+ return null;
499
+ beforeRan = true;
464
500
  try {
465
- await hooks.beforeToolCall(toolName, rawArgs, context, method);
501
+ await hooks.beforeToolCall({
502
+ toolName,
503
+ args: rawArgs,
504
+ context: hookContext,
505
+ endpoint: method
506
+ });
507
+ return null;
466
508
  } catch (err) {
467
509
  return finish(toolResultFromError(err));
468
510
  }
511
+ };
512
+ const finishThrown = async (err) => {
513
+ const beforeFailure2 = await runBefore();
514
+ if (beforeFailure2)
515
+ return beforeFailure2;
516
+ if (hooks?.onToolError) {
517
+ try {
518
+ await hooks.onToolError({
519
+ toolName,
520
+ error: err,
521
+ context: hookContext,
522
+ endpoint: method
523
+ });
524
+ } catch (hookErr) {
525
+ console.error("[stitchkit] onToolError hook failed:", hookErr);
526
+ }
527
+ }
528
+ return finish(toolResultFromError(err), err);
529
+ };
530
+ let callArgs = rawArgs;
531
+ let callContext = context;
532
+ if (extension) {
533
+ const extensionKeys = new Set(Object.keys(extension.schema.shape));
534
+ const extensionArgs = Object.fromEntries(Object.entries(rawArgs).filter(([key]) => extensionKeys.has(key)));
535
+ let parsed;
536
+ try {
537
+ parsed = extension.schema.safeParse(extensionArgs);
538
+ } catch (err) {
539
+ return finishThrown(err);
540
+ }
541
+ if (!parsed.success) {
542
+ const beforeFailure2 = await runBefore();
543
+ if (beforeFailure2)
544
+ return beforeFailure2;
545
+ return finish({
546
+ ok: false,
547
+ code: "VALIDATION_ERROR",
548
+ details: { message: `Invalid tool extension: ${formatZodError(parsed.error)}` }
549
+ });
550
+ }
551
+ try {
552
+ const resolved = await extension.resolve({ ...rawArgs, ...parsed.data });
553
+ callContext = { ...context, ...resolved, source: context.source };
554
+ hookContext = callContext;
555
+ callArgs = Object.fromEntries(Object.entries(rawArgs).filter(([key]) => !extensionKeys.has(key)));
556
+ } catch (err) {
557
+ return finishThrown(err);
558
+ }
469
559
  }
560
+ const beforeFailure = await runBefore();
561
+ if (beforeFailure)
562
+ return beforeFailure;
470
563
  const paramKeys = new Set(objectShapeKeys(method.paramsSchema));
471
564
  let paramArgs = {};
472
565
  let inputArgs = {};
473
- for (const [key, value] of Object.entries(rawArgs)) {
566
+ for (const [key, value] of Object.entries(callArgs)) {
474
567
  if (isUnsafeKey(key))
475
568
  continue;
476
569
  if (paramKeys.has(key))
@@ -484,7 +577,12 @@ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycl
484
577
  }
485
578
  let params;
486
579
  if (method.paramsSchema) {
487
- const result = method.paramsSchema.safeParse(paramArgs);
580
+ let result;
581
+ try {
582
+ result = method.paramsSchema.safeParse(paramArgs);
583
+ } catch (err) {
584
+ return finishThrown(err);
585
+ }
488
586
  if (!result.success) {
489
587
  return finish({
490
588
  ok: false,
@@ -496,7 +594,12 @@ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycl
496
594
  }
497
595
  let input;
498
596
  if (method.inputSchema) {
499
- const result = method.inputSchema.safeParse(inputArgs);
597
+ let result;
598
+ try {
599
+ result = method.inputSchema.safeParse(inputArgs);
600
+ } catch (err) {
601
+ return finishThrown(err);
602
+ }
500
603
  if (!result.success) {
501
604
  return finish({
502
605
  ok: false,
@@ -507,7 +610,12 @@ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycl
507
610
  input = result.data;
508
611
  }
509
612
  try {
510
- const ctx = { ...context, params, input, source: context.source };
613
+ const ctx = {
614
+ ...callContext,
615
+ params,
616
+ input,
617
+ source: context.source
618
+ };
511
619
  if (lifecycle?.beforeHandle) {
512
620
  await lifecycle.beforeHandle(ctx, method);
513
621
  }
@@ -531,14 +639,7 @@ async function runToolMethod(method, toolName, rawArgs, context, hooks, lifecycl
531
639
  const output = (data === undefined || data === null) && !method.outputSchema ? { status: "ok" } : data;
532
640
  return finish({ ok: true, data: output });
533
641
  } catch (err) {
534
- if (hooks?.onToolError) {
535
- try {
536
- await hooks.onToolError(toolName, err, context, method);
537
- } catch (hookErr) {
538
- console.error("[stitchkit] onToolError hook failed:", hookErr);
539
- }
540
- }
541
- return finish(toolResultFromError(err), err);
642
+ return finishThrown(err);
542
643
  }
543
644
  }
544
645
 
@@ -607,6 +708,121 @@ function assertUniqueToolName(name, taken, surface) {
607
708
  }
608
709
  }
609
710
 
711
+ // src/tools/presentation.ts
712
+ import { z as z3 } from "zod";
713
+ function withoutDialect(schema) {
714
+ const result = {};
715
+ for (const [key, value] of Object.entries(schema)) {
716
+ if (key !== "$schema")
717
+ result[key] = value;
718
+ }
719
+ return result;
720
+ }
721
+ function hasLocalReference(value) {
722
+ if (Array.isArray(value))
723
+ return value.some(hasLocalReference);
724
+ if (!isRecord(value))
725
+ return false;
726
+ if (typeof value.$ref === "string" && value.$ref.startsWith("#"))
727
+ return true;
728
+ return Object.values(value).some(hasLocalReference);
729
+ }
730
+ function rewriteLocalReferences(value, namespace) {
731
+ if (Array.isArray(value)) {
732
+ return value.map((child) => rewriteLocalReferences(child, namespace));
733
+ }
734
+ if (!isRecord(value))
735
+ return value;
736
+ const rewritten = {};
737
+ for (const [key, child] of Object.entries(value)) {
738
+ rewritten[key] = key === "$ref" && typeof child === "string" && child.startsWith("#") ? `#/definitions/${namespace}${child.slice(1)}` : rewriteLocalReferences(child, namespace);
739
+ }
740
+ return rewritten;
741
+ }
742
+ function namespaceLocalReferences(schema, namespace) {
743
+ if (!schema || !hasLocalReference(schema))
744
+ return schema;
745
+ const rewritten = rewriteLocalReferences(schema, namespace);
746
+ if (!isRecord(rewritten))
747
+ return schema;
748
+ return { ...rewritten, definitions: { [namespace]: rewritten } };
749
+ }
750
+ function objectProperties(schema) {
751
+ return schema.type === "object" && isRecord(schema.properties) ? schema.properties : null;
752
+ }
753
+ function requiredKeys2(schema) {
754
+ return Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === "string") : [];
755
+ }
756
+ function mergeObjectSchemas(left, right, rightOwnsUnknownKeys) {
757
+ const leftProperties = objectProperties(left);
758
+ const rightProperties = objectProperties(right);
759
+ if (!leftProperties || !rightProperties)
760
+ return { allOf: [left, right] };
761
+ const conflicts = Object.keys(leftProperties).filter((key) => (key in rightProperties));
762
+ if (conflicts.length > 0) {
763
+ throw new Error(`Schema merge conflict: ${conflicts.join(", ")} appear in both params and input`);
764
+ }
765
+ const merged = {
766
+ type: "object",
767
+ properties: { ...leftProperties, ...rightProperties },
768
+ required: [...new Set([...requiredKeys2(left), ...requiredKeys2(right)])]
769
+ };
770
+ const leftDefinitions = isRecord(left.definitions) ? left.definitions : {};
771
+ const rightDefinitions = isRecord(right.definitions) ? right.definitions : {};
772
+ const definitions = { ...leftDefinitions, ...rightDefinitions };
773
+ if (Object.keys(definitions).length > 0)
774
+ merged.definitions = definitions;
775
+ const unknownKeys = rightOwnsUnknownKeys ? right.additionalProperties : left.additionalProperties;
776
+ if (unknownKeys !== undefined)
777
+ merged.additionalProperties = unknownKeys;
778
+ return merged;
779
+ }
780
+ function schemaFromZod(schema, unrepresentable, flatten) {
781
+ if (!schema)
782
+ return;
783
+ const json = toJsonSchema(schema, "input", unrepresentable, "draft-07");
784
+ return flatten ? flattenToolJsonSchema(json) : json;
785
+ }
786
+ function buildToolPresentationSchema(config) {
787
+ const unrepresentable = config.unrepresentable ?? "any";
788
+ const flatten = config.flattenUnionInput ?? false;
789
+ const params = namespaceLocalReferences(schemaFromZod(config.paramsSchema, unrepresentable, flatten), "params");
790
+ const input = namespaceLocalReferences(schemaFromZod(config.inputSchema, unrepresentable, flatten), "input");
791
+ let presentation;
792
+ if (params && input) {
793
+ presentation = mergeObjectSchemas(withoutDialect(params), withoutDialect(input), true);
794
+ } else if (input) {
795
+ presentation = input;
796
+ } else if (params) {
797
+ presentation = params;
798
+ } else {
799
+ presentation = {
800
+ $schema: "http://json-schema.org/draft-07/schema#",
801
+ type: "object",
802
+ properties: {}
803
+ };
804
+ }
805
+ if (config.extendSchema) {
806
+ const extra = namespaceLocalReferences(schemaFromZod(z3.object(config.extendSchema), unrepresentable, flatten), "extend");
807
+ if (extra) {
808
+ presentation = mergeObjectSchemas(withoutDialect(extra), withoutDialect(presentation), true);
809
+ }
810
+ }
811
+ if (presentation.$schema === undefined) {
812
+ presentation = {
813
+ $schema: "http://json-schema.org/draft-07/schema#",
814
+ ...presentation
815
+ };
816
+ }
817
+ return freezeToolJsonSchema(presentation);
818
+ }
819
+ function isObjectPresentationSchema(schema) {
820
+ return schema.type === "object" && isRecord(schema.properties);
821
+ }
822
+ function presentationMetadata(schema) {
823
+ return withoutDialect(schema);
824
+ }
825
+
610
826
  // src/tools/mount.ts
611
827
  function applyExtend(base, extra) {
612
828
  if (base instanceof z4.ZodObject) {
@@ -630,6 +846,8 @@ function collectTools(service, transport, config = {}) {
630
846
  }
631
847
  if (method.multipart)
632
848
  continue;
849
+ if (method.rawBody)
850
+ continue;
633
851
  if (method.rawResponse)
634
852
  continue;
635
853
  const name = method.toolName ?? toToolName(service.name, methodName);
@@ -639,24 +857,28 @@ function collectTools(service, transport, config = {}) {
639
857
  }
640
858
  assertToolName(name, service.name, methodName);
641
859
  }
642
- const baseSchema = flattenUnionInput ? mergeSchemas(method.paramsSchema ? flattenUnionsDeep(method.paramsSchema) : undefined, method.inputSchema ? flattenUnionsDeep(method.inputSchema) : undefined) : mergeSchemas(method.paramsSchema, method.inputSchema);
643
860
  const shouldExtend = !!extend && (!extend.filter || extend.filter(service, method));
644
- const schema = shouldExtend && extend ? applyExtend(baseSchema, extend.schema) : baseSchema;
645
- tools.push({ method, name, schema, shouldExtend });
861
+ const baseArgumentSchema = mergeSchemas(method.paramsSchema, method.inputSchema);
862
+ const argumentSchema = shouldExtend && extend ? applyExtend(baseArgumentSchema, extend.schema) : baseArgumentSchema;
863
+ const presentationSchema = buildToolPresentationSchema({
864
+ paramsSchema: method.paramsSchema,
865
+ inputSchema: method.inputSchema,
866
+ extendSchema: shouldExtend ? extend?.schema : undefined,
867
+ flattenUnionInput,
868
+ unrepresentable: "any"
869
+ });
870
+ tools.push({ method, name, argumentSchema, presentationSchema, shouldExtend });
646
871
  }
647
872
  return tools;
648
873
  }
649
874
  function createToolRunner(config) {
650
- const extendKeys = config.extend ? new Set(Object.keys(config.extend.schema)) : null;
651
- return async (tool, rawArgs) => inToolCallContext({ source: config.source, toolName: tool.name, method: tool.method }, () => runOneToolCall(tool, rawArgs));
652
- async function runOneToolCall(tool, rawArgs) {
653
- let extraContext = {};
654
- if (tool.shouldExtend && config.extend) {
655
- extraContext = await config.extend.resolve(rawArgs);
656
- }
657
- const cleanArgs = tool.shouldExtend && extendKeys ? Object.fromEntries(Object.entries(rawArgs).filter(([key]) => !extendKeys.has(key))) : rawArgs;
658
- return executeToolMethod(tool.method, tool.name, cleanArgs, { ...config.context, ...extraContext, source: config.source }, config.hooks, config.lifecycle, config.coerceJsonArgs ?? true, config.onOutputStrip ? (paths) => config.onOutputStrip?.(tool.name, paths) : undefined);
659
- }
875
+ const extension = config.extend ? {
876
+ schema: z4.object(config.extend.schema),
877
+ resolve: config.extend.resolve
878
+ } : undefined;
879
+ return async function runOneToolCall(tool, rawArgs) {
880
+ return executeToolMethod(tool.method, tool.name, rawArgs, { ...config.context, source: config.source }, config.hooks, config.lifecycle, config.coerceJsonArgs ?? true, config.onOutputStrip ? (paths) => config.onOutputStrip?.(tool.name, paths) : undefined, tool.shouldExtend ? extension : undefined);
881
+ };
660
882
  }
661
883
  function formatToolError(result, toolName, errorHint) {
662
884
  const err = { error: result.code };
@@ -1227,7 +1449,7 @@ function renderCommandHelp(name, command, tool) {
1227
1449
  const lines = [tool.method.desc, "", `Usage: ${name} ${command} [args] [--flags]`, ""];
1228
1450
  let fields = [];
1229
1451
  try {
1230
- fields = jsonSchemaFields(toJsonSchema(tool.schema, "input"));
1452
+ fields = jsonSchemaFields(tool.presentationSchema);
1231
1453
  } catch {
1232
1454
  lines.push("(arguments: pass a JSON object — this command has a complex schema)", "");
1233
1455
  }
@@ -1307,7 +1529,7 @@ async function createCli(config) {
1307
1529
  `);
1308
1530
  return exit(1);
1309
1531
  }
1310
- const { toolArgs, options } = parseCliArgs(commandArgv, tool.schema);
1532
+ const { toolArgs, options } = parseCliArgs(commandArgv, tool.argumentSchema);
1311
1533
  if (options.help) {
1312
1534
  stdout(renderCommandHelp(config.name, command, tool));
1313
1535
  return exit(0);
@@ -1321,7 +1543,7 @@ async function createCli(config) {
1321
1543
  }
1322
1544
  const passthroughField = config.passthrough?.[command];
1323
1545
  if (passthroughField) {
1324
- collectPassthrough(toolArgs, passthroughField, objectShapeKeys(tool.schema));
1546
+ collectPassthrough(toolArgs, passthroughField, objectShapeKeys(tool.argumentSchema));
1325
1547
  }
1326
1548
  if (options.dryRun) {
1327
1549
  stdout(`${JSON.stringify({ command, args: toolArgs }, null, 2)}
@@ -1367,11 +1589,7 @@ async function createCli(config) {
1367
1589
  return exit(exitCode);
1368
1590
  }
1369
1591
  function safeInputSchema(tool) {
1370
- try {
1371
- return toJsonSchema(tool.schema, "input");
1372
- } catch {
1373
- return {};
1374
- }
1592
+ return tool.presentationSchema;
1375
1593
  }
1376
1594
 
1377
- export { coerceJsonArgs, toolResultFromError, flattenDiscriminatedUnion, flattenUnionsDeep, assertToolName, assertUniqueToolName, collectTools, createToolRunner, formatToolError, fetchGuarded, readCapped, writeDownload, parseCliArgs, DEFAULT_EXIT_CODES, emitResult, pollUntil, pollUntilDone, createCli };
1595
+ export { coerceJsonArgs, toolResultFromError, executeToolMethod, assertToolName, assertUniqueToolName, flattenToolJsonSchema, buildToolPresentationSchema, isObjectPresentationSchema, presentationMetadata, collectTools, createToolRunner, formatToolError, fetchGuarded, readCapped, writeDownload, parseCliArgs, DEFAULT_EXIT_CODES, emitResult, pollUntil, pollUntilDone, createCli };