stitchkit 0.13.0 → 0.15.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/dist/cli.js CHANGED
@@ -4,9 +4,9 @@ import {
4
4
  emitResult,
5
5
  parseCliArgs,
6
6
  pollUntilDone
7
- } from "./index-91b3n95r.js";
7
+ } from "./index-bb18z3px.js";
8
8
  import"./index-0ed3bx43.js";
9
- import"./index-fq89tdex.js";
9
+ import"./index-ktn76xz0.js";
10
10
  import"./index-tm7dqzxc.js";
11
11
  export {
12
12
  pollUntilDone,
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/contract/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QACL,2CAA2C;QAC3C,IAAI,EAAE,MAAM,CAAC;QACb,8BAA8B;QAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gCAAgC;QAChC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,0BAA0B;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAED;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAEf,IAAI,EAAE,MAAM;aAEZ,MAAM,EAAE,MAAM;aACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;aACjC,IAAI,CAAC,EAAE,MAAM;gBAJb,IAAI,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,MAAM,EACA,MAAM,GAAE,MAAY,EACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA,EACjC,IAAI,CAAC,EAAE,MAAM,YAAA;IAM/B,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ;IAIxC,MAAM,IAAI,aAAa;CAUxB;AAED,qCAAqC;AACrC,wBAAgB,QAAQ,CAAC,OAAO,SAAc,GAAG,KAAK,CAErD;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAEpF;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,OAAO,SAAiB,GAAG,KAAK,CAE5D;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,OAAO,SAAc,GAAG,KAAK,CAEtD;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,OAAO,SAAa,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAEvF;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,OAAO,SAAsB,GAAG,KAAK,CAEhE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;CAUE,CAAC;AAEnC,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAE/D,iEAAiE;AACjE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,eAAe,CAEvE;AAED,+FAA+F;AAC/F,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,KAAK,CAOP"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/contract/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE;QACL,2CAA2C;QAC3C,IAAI,EAAE,MAAM,CAAC;QACb,8BAA8B;QAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,gCAAgC;QAChC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,0BAA0B;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH;AAcD;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;aAEf,IAAI,EAAE,MAAM;aAEZ,MAAM,EAAE,MAAM;aACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;aACjC,IAAI,CAAC,EAAE,MAAM;gBAJb,IAAI,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,MAAM,EACA,MAAM,GAAE,MAAY,EACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA,EACjC,IAAI,CAAC,EAAE,MAAM,YAAA;IAU/B,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ;IAIxC,MAAM,IAAI,aAAa;CAUxB;AAED,qCAAqC;AACrC,wBAAgB,QAAQ,CAAC,OAAO,SAAc,GAAG,KAAK,CAErD;AAED,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAEpF;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,OAAO,SAAiB,GAAG,KAAK,CAE5D;AAED,qCAAqC;AACrC,wBAAgB,SAAS,CAAC,OAAO,SAAc,GAAG,KAAK,CAEtD;AAED,0EAA0E;AAC1E,wBAAgB,QAAQ,CAAC,OAAO,SAAa,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAEvF;AAED,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,OAAO,SAAsB,GAAG,KAAK,CAEhE;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;CAUE,CAAC;AAEnC,mFAAmF;AACnF,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAE/D,iEAAiE;AACjE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,IAAI,eAAe,CAEvE;AAED,+FAA+F;AAC/F,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,KAAK,CAOP"}
@@ -14,7 +14,7 @@ import {
14
14
  paginatedSchema,
15
15
  rateLimited,
16
16
  unauthorized
17
- } from "../index-eq29zkrx.js";
17
+ } from "../index-yzac2zbh.js";
18
18
  export {
19
19
  unauthorized,
20
20
  rateLimited,
@@ -5,7 +5,7 @@ import {
5
5
  isWithinDir,
6
6
  normalizeError,
7
7
  validateHandlerOutput
8
- } from "./index-fq89tdex.js";
8
+ } from "./index-ktn76xz0.js";
9
9
  import {
10
10
  extractIp,
11
11
  getClientInfo,
@@ -7,7 +7,7 @@ import {
7
7
  isWithinDir,
8
8
  normalizeError,
9
9
  validateHandlerOutput
10
- } from "./index-fq89tdex.js";
10
+ } from "./index-ktn76xz0.js";
11
11
  import {
12
12
  isRecord,
13
13
  isUnsafeKey,
@@ -16,85 +16,196 @@ import {
16
16
 
17
17
  // src/tools/coerce.ts
18
18
  import { z } from "zod";
19
- function needsJsonCoercion(field) {
20
- if (field instanceof z.ZodArray || field instanceof z.ZodObject || field instanceof z.ZodRecord) {
19
+ function needsJsonCoercion(schema) {
20
+ if (schema instanceof z.ZodArray || schema instanceof z.ZodObject || schema instanceof z.ZodRecord || schema instanceof z.ZodTuple || schema instanceof z.ZodUnion) {
21
21
  return true;
22
22
  }
23
- if (field instanceof z.ZodOptional || field instanceof z.ZodNullable || field instanceof z.ZodDefault) {
24
- return needsJsonCoercion(field.unwrap());
23
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable || schema instanceof z.ZodDefault) {
24
+ return needsJsonCoercion(schema.unwrap());
25
25
  }
26
26
  return false;
27
27
  }
28
- function coerceJsonArgs(args, schema) {
29
- if (!(schema instanceof z.ZodObject))
30
- return args;
31
- const shape = schema.shape;
32
- const out = {};
33
- for (const [key, value] of Object.entries(args)) {
34
- const field = shape[key];
35
- if (field && needsJsonCoercion(field) && typeof value === "string") {
36
- try {
37
- out[key] = safeJsonParse(value);
38
- continue;
39
- } catch {}
28
+ function matchingVariant(union, value) {
29
+ const disc = union.def.discriminator;
30
+ const tag = value[disc];
31
+ for (const option of union.def.options) {
32
+ if (!(option instanceof z.ZodObject))
33
+ continue;
34
+ const field = option.shape[disc];
35
+ if (field instanceof z.ZodLiteral && field.def.values.some((v) => v === tag))
36
+ return option;
37
+ if (field instanceof z.ZodEnum && field.options.some((v) => v === tag))
38
+ return option;
39
+ }
40
+ return;
41
+ }
42
+ function coerceValue(value, schema) {
43
+ if (!schema)
44
+ return value;
45
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable || schema instanceof z.ZodDefault) {
46
+ return coerceValue(value, schema.unwrap());
47
+ }
48
+ let current = value;
49
+ if (typeof current === "string" && needsJsonCoercion(schema)) {
50
+ try {
51
+ current = safeJsonParse(current);
52
+ } catch {
53
+ return value;
40
54
  }
41
- out[key] = value;
42
55
  }
43
- return out;
56
+ if (schema instanceof z.ZodObject && isRecord(current)) {
57
+ const shape = schema.shape;
58
+ const out = {};
59
+ for (const [key, item] of Object.entries(current)) {
60
+ out[key] = coerceValue(item, shape[key]);
61
+ }
62
+ return out;
63
+ }
64
+ if (schema instanceof z.ZodArray && Array.isArray(current)) {
65
+ return current.map((item) => coerceValue(item, schema.element));
66
+ }
67
+ if (schema instanceof z.ZodDiscriminatedUnion && isRecord(current)) {
68
+ const variant = matchingVariant(schema, current);
69
+ return variant ? coerceValue(current, variant) : current;
70
+ }
71
+ return current;
72
+ }
73
+ function coerceJsonArgs(args, schema) {
74
+ const coerced = coerceValue(args, schema);
75
+ return isRecord(coerced) ? coerced : args;
44
76
  }
45
77
 
46
78
  // src/tools/flatten.ts
47
79
  import { z as z2 } from "zod";
48
80
  function flattenDiscriminatedUnion(union) {
49
81
  const discriminator = union.def.discriminator;
50
- const literalValues = [];
51
- const fieldToVariants = new Map;
52
- const fieldSchemas = {};
82
+ const allDiscValues = [];
83
+ const perKey = new Map;
53
84
  for (const opt of union.def.options) {
54
85
  if (!(opt instanceof z2.ZodObject)) {
55
86
  throw new Error(`flattenDiscriminatedUnion: variant for discriminator '${discriminator}' is not a ZodObject`);
56
87
  }
57
- const discField = opt.shape[discriminator];
58
- if (!(discField instanceof z2.ZodLiteral)) {
59
- throw new Error(`flattenDiscriminatedUnion: discriminator field '${discriminator}' must be z.literal()`);
88
+ const discValues = stringLiteralOrEnumValues(opt.shape[discriminator]);
89
+ if (discValues === null) {
90
+ throw new Error(`flattenDiscriminatedUnion: discriminator '${discriminator}' must be a string z.literal() or z.enum()`);
60
91
  }
61
- const [literalValue] = discField.def.values;
62
- if (typeof literalValue !== "string") {
63
- throw new Error("flattenDiscriminatedUnion: discriminator literal must be a string");
64
- }
65
- literalValues.push(literalValue);
92
+ allDiscValues.push(...discValues);
93
+ const label = discValues.join(" | ");
66
94
  for (const [key, field] of Object.entries(opt.shape)) {
67
95
  if (key === discriminator)
68
96
  continue;
69
- const variants = fieldToVariants.get(key) ?? [];
70
- variants.push(literalValue);
71
- fieldToVariants.set(key, variants);
72
- if (!(key in fieldSchemas)) {
73
- fieldSchemas[key] = field instanceof z2.ZodOptional ? field : z2.optional(field);
74
- }
97
+ const entry = perKey.get(key) ?? { schemas: [], variants: [] };
98
+ entry.schemas.push(field instanceof z2.ZodOptional ? field.unwrap() : field);
99
+ entry.variants.push(label);
100
+ perKey.set(key, entry);
75
101
  }
76
102
  }
77
- const [firstLiteral, ...restLiterals] = literalValues;
78
- if (!firstLiteral) {
103
+ const uniqDisc = [...new Set(allDiscValues)];
104
+ const [firstLiteral, ...restLiterals] = uniqDisc;
105
+ if (firstLiteral === undefined) {
79
106
  throw new Error("flattenDiscriminatedUnion: union has no options");
80
107
  }
81
108
  const shape = {
82
109
  [discriminator]: z2.enum([firstLiteral, ...restLiterals])
83
110
  };
84
- for (const [key, field] of Object.entries(fieldSchemas)) {
85
- const variants = fieldToVariants.get(key) ?? [];
86
- const hint = `Required if ${discriminator} = ${variants.join(" | ")}`;
87
- shape[key] = field.describe(hint);
111
+ for (const [key, entry] of perKey) {
112
+ const advertised = mergeCollidingFields(entry.schemas);
113
+ const hint = `Required if ${discriminator} = ${[...new Set(entry.variants)].join(" | ")}`;
114
+ shape[key] = z2.optional(advertised).describe(hint);
88
115
  }
89
116
  return z2.object(shape);
90
117
  }
91
118
  function preserveDescription(from, to) {
92
119
  return from.description === undefined ? to : to.describe(from.description);
93
120
  }
121
+ function stringLiteralOrEnumValues(field) {
122
+ let raw = null;
123
+ if (field instanceof z2.ZodLiteral)
124
+ raw = field.def.values;
125
+ else if (field instanceof z2.ZodEnum)
126
+ raw = field.options;
127
+ if (raw === null)
128
+ return null;
129
+ const strings = raw.filter((v) => typeof v === "string");
130
+ return strings.length === raw.length ? strings : null;
131
+ }
132
+ function isFlattenableDU(union) {
133
+ const disc = union.def.discriminator;
134
+ if (union.def.options.length === 0)
135
+ return false;
136
+ for (const opt of union.def.options) {
137
+ if (!(opt instanceof z2.ZodObject))
138
+ return false;
139
+ if (stringLiteralOrEnumValues(opt.shape[disc]) === null)
140
+ return false;
141
+ }
142
+ return true;
143
+ }
144
+ function stripAnnotations(node) {
145
+ if (Array.isArray(node)) {
146
+ for (const item of node)
147
+ stripAnnotations(item);
148
+ return;
149
+ }
150
+ if (typeof node === "object" && node !== null) {
151
+ Reflect.deleteProperty(node, "description");
152
+ Reflect.deleteProperty(node, "default");
153
+ Reflect.deleteProperty(node, "$schema");
154
+ for (const value of Object.values(node))
155
+ stripAnnotations(value);
156
+ }
157
+ }
158
+ function hasChecks(schema) {
159
+ if (!(schema instanceof z2.ZodType))
160
+ return false;
161
+ const def = schema.def;
162
+ return isRecord(def) && Array.isArray(def.checks) && def.checks.length > 0;
163
+ }
164
+ function normalizedJson(schema) {
165
+ if (!(schema instanceof z2.ZodType))
166
+ return "{}";
167
+ const json = toJsonSchema(schema, "input", "any");
168
+ stripAnnotations(json);
169
+ return JSON.stringify(json);
170
+ }
171
+ function mergeCollidingFields(schemas) {
172
+ const distinct = new Map;
173
+ for (const schema of schemas) {
174
+ const key = normalizedJson(schema);
175
+ if (!distinct.has(key))
176
+ distinct.set(key, schema);
177
+ }
178
+ const values = [...distinct.values()];
179
+ const only = values[0];
180
+ if (values.length <= 1) {
181
+ if (only === undefined)
182
+ return z2.unknown();
183
+ return schemas.length > 1 && hasChecks(only) ? z2.unknown() : only;
184
+ }
185
+ const merged = [];
186
+ let allEnum = true;
187
+ for (const schema of values) {
188
+ const vals = stringLiteralOrEnumValues(schema);
189
+ if (vals === null) {
190
+ allEnum = false;
191
+ break;
192
+ }
193
+ merged.push(...vals);
194
+ }
195
+ if (allEnum) {
196
+ const uniq = [...new Set(merged)];
197
+ const [first, ...rest] = uniq;
198
+ if (first !== undefined)
199
+ return z2.enum([first, ...rest]);
200
+ }
201
+ return z2.unknown();
202
+ }
94
203
  function flattenUnionsDeep(schema) {
95
204
  if (!(schema instanceof z2.ZodType))
96
205
  return z2.unknown();
97
206
  if (schema instanceof z2.ZodDiscriminatedUnion) {
207
+ if (!isFlattenableDU(schema))
208
+ return schema;
98
209
  return preserveDescription(schema, flattenUnionsDeep(flattenDiscriminatedUnion(schema)));
99
210
  }
100
211
  if (schema instanceof z2.ZodObject) {
@@ -107,6 +218,14 @@ function flattenUnionsDeep(schema) {
107
218
  if (schema instanceof z2.ZodArray) {
108
219
  return preserveDescription(schema, z2.array(flattenUnionsDeep(schema.element)));
109
220
  }
221
+ if (schema instanceof z2.ZodUnion) {
222
+ const opts = schema.def.options.map((option) => flattenUnionsDeep(option));
223
+ const [a, b, ...rest] = opts;
224
+ return a && b ? preserveDescription(schema, z2.union([a, b, ...rest])) : schema;
225
+ }
226
+ if (schema instanceof z2.ZodRecord) {
227
+ return preserveDescription(schema, z2.record(schema.keyType, flattenUnionsDeep(schema.valueType)));
228
+ }
110
229
  if (schema instanceof z2.ZodOptional) {
111
230
  return preserveDescription(schema, z2.optional(flattenUnionsDeep(schema.unwrap())));
112
231
  }
@@ -301,10 +420,7 @@ function collectTools(service, transport, config = {}) {
301
420
  if (method.multipart)
302
421
  continue;
303
422
  const name = method.toolName ?? toToolName(service.name, methodName);
304
- let baseSchema = mergeSchemas(method.paramsSchema, method.inputSchema);
305
- if (flattenUnionInput) {
306
- baseSchema = flattenUnionsDeep(baseSchema);
307
- }
423
+ const baseSchema = flattenUnionInput ? mergeSchemas(method.paramsSchema ? flattenUnionsDeep(method.paramsSchema) : undefined, method.inputSchema ? flattenUnionsDeep(method.inputSchema) : undefined) : mergeSchemas(method.paramsSchema, method.inputSchema);
308
424
  const shouldExtend = !!extend && (!extend.filter || extend.filter(service, method));
309
425
  const schema = shouldExtend && extend ? applyExtend(baseSchema, extend.schema) : baseSchema;
310
426
  tools.push({ method, name, schema, shouldExtend });
@@ -1,4 +1,6 @@
1
1
  // src/contract/errors.ts
2
+ var APP_ERROR_BRAND = Symbol.for("stitchkit.AppError");
3
+
2
4
  class AppError extends Error {
3
5
  code;
4
6
  status;
@@ -11,9 +13,10 @@ class AppError extends Error {
11
13
  this.details = details;
12
14
  this.hint = hint;
13
15
  this.name = "AppError";
16
+ Object.defineProperty(this, APP_ERROR_BRAND, { value: true });
14
17
  }
15
18
  static is(err) {
16
- return err instanceof AppError;
19
+ return typeof err === "object" && err !== null && APP_ERROR_BRAND in err;
17
20
  }
18
21
  toJSON() {
19
22
  return {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  forbidden,
3
3
  unauthorized
4
- } from "./index-fq89tdex.js";
4
+ } from "./index-ktn76xz0.js";
5
5
  import {
6
6
  isRecord,
7
7
  isUnsafeKey,
@@ -27,6 +27,8 @@ function defineContract(meta, endpoints) {
27
27
  return { meta, endpoints };
28
28
  }
29
29
  // src/contract/errors.ts
30
+ var APP_ERROR_BRAND = Symbol.for("stitchkit.AppError");
31
+
30
32
  class AppError extends Error {
31
33
  code;
32
34
  status;
@@ -39,9 +41,10 @@ class AppError extends Error {
39
41
  this.details = details;
40
42
  this.hint = hint;
41
43
  this.name = "AppError";
44
+ Object.defineProperty(this, APP_ERROR_BRAND, { value: true });
42
45
  }
43
46
  static is(err) {
44
- return err instanceof AppError;
47
+ return typeof err === "object" && err !== null && APP_ERROR_BRAND in err;
45
48
  }
46
49
  toJSON() {
47
50
  return {
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  paginatedSchema,
15
15
  rateLimited,
16
16
  unauthorized
17
- } from "./index-eq29zkrx.js";
17
+ } from "./index-yzac2zbh.js";
18
18
 
19
19
  // src/internal/http-input.ts
20
20
  function inputIsQuery(method) {
package/dist/node.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createImplement,
4
4
  createSocketIOServer,
5
5
  implement
6
- } from "./index-kb7wxdq0.js";
6
+ } from "./index-6k6y7wat.js";
7
7
  import {
8
8
  AppError,
9
9
  appError,
@@ -13,7 +13,7 @@ import {
13
13
  notFound,
14
14
  rateLimited,
15
15
  unauthorized
16
- } from "./index-fq89tdex.js";
16
+ } from "./index-ktn76xz0.js";
17
17
  import"./index-fwqnkc90.js";
18
18
  import"./index-tm7dqzxc.js";
19
19
  // src/server/node.ts
@@ -12,7 +12,7 @@ import {
12
12
  socketIoLane,
13
13
  staticRoute,
14
14
  webSocketLane
15
- } from "../index-kb7wxdq0.js";
15
+ } from "../index-6k6y7wat.js";
16
16
  import {
17
17
  createAuthHook,
18
18
  createBearerResolver,
@@ -25,7 +25,7 @@ import {
25
25
  signJwt,
26
26
  verifyJwt,
27
27
  verifyPkce
28
- } from "../index-msmy8ydw.js";
28
+ } from "../index-yv93m4yr.js";
29
29
  import {
30
30
  jsonSchemaFields,
31
31
  toJsonSchema
@@ -42,7 +42,7 @@ import {
42
42
  notFound,
43
43
  rateLimited,
44
44
  unauthorized
45
- } from "../index-fq89tdex.js";
45
+ } from "../index-ktn76xz0.js";
46
46
  import {
47
47
  extractIp,
48
48
  generateTraceId,
@@ -3,10 +3,10 @@ import { z } from 'zod';
3
3
  * Coerce JSON-stringified array/object arguments — an LLM sometimes
4
4
  * double-serializes a nested value (sends `"[1,2]"` instead of `[1,2]`).
5
5
  *
6
- * Only fields the schema declares as an array/object are touched, and only
7
- * when the incoming value is a string. The transform operates on the
8
- * **arguments**, never the schema so the advertised tool schema stays
9
- * exactly the contract schema (correct types, correct `required`).
6
+ * Operates recursively against the schema (object fields, array items, and the
7
+ * matching variant of a discriminated union) so a stringified value at any depth
8
+ * is repaired, not just a top-level field. The transform touches the **arguments**
9
+ * only the advertised tool schema stays exactly the contract schema.
10
10
  */
11
11
  export declare function coerceJsonArgs(args: Record<string, unknown>, schema: z.ZodType | undefined): Record<string, unknown>;
12
12
  //# sourceMappingURL=coerce.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../src/tools/coerce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAsBxB;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB"}
1
+ {"version":3,"file":"coerce.d.ts","sourceRoot":"","sources":["../../src/tools/coerce.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoFxB;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB"}
@@ -1,31 +1,37 @@
1
1
  import { z } from 'zod';
2
2
  /**
3
- * Flatten a `ZodDiscriminatedUnion` into a single `ZodObject` for LLM
4
- * transports that cannot represent `oneOf` (MCP).
3
+ * Flatten a `ZodDiscriminatedUnion` into a single `ZodObject` for LLM transports
4
+ * that cannot represent `oneOf` (MCP / weaker models).
5
5
  *
6
- * The discriminator becomes a `z.enum(...)` of all variant values; fields
7
- * from each variant become optional with a `.describe()` hint indicating
8
- * which variant requires them.
6
+ * The discriminator becomes a `z.enum(...)` of **all** variant values; each
7
+ * variant's fields become optional with a `.describe()` hint naming the variants
8
+ * that require them. When two variants declare the **same key with different
9
+ * shapes**, the advertised field is widened so it accepts every variant's value —
10
+ * never narrowed to one (which would make the losing variant unsatisfiable):
9
11
  *
10
- * **Lossy:** per-variant field requiredness is replaced with optional +
11
- * description hint. The original union remains the validation schema in
12
- * `executeToolMethod` this is the advertised schema only.
12
+ * - identical across variants kept as-is.
13
+ * - all string literal/enum merged into one widened `z.enum`.
14
+ * - otherwise (object vs array, differing object shapes) → `z.unknown()` (accepts
15
+ * anything; the `.describe()` carries the per-variant shape).
16
+ *
17
+ * This keeps the advertised schema free of `oneOf` / `anyOf` at any depth (→ ADR
18
+ * 0033) **and** a superset of the original union, so a model can always produce a
19
+ * value that passes both the transport SDK and validation.
20
+ *
21
+ * **Lossy and advertised-only:** the original union remains the validation schema
22
+ * in `executeToolMethod`. `.strict()` / `.catchall()` / object-level refinements
23
+ * on variants are dropped from the *advertised* hint (validation still enforces
24
+ * them — see ADR 0033 on the strict-variant caveat).
13
25
  */
14
26
  export declare function flattenDiscriminatedUnion(union: z.ZodDiscriminatedUnion): z.ZodObject<z.ZodRawShape>;
15
27
  /**
16
- * Recursively flatten **every** `ZodDiscriminatedUnion` in a schema — at the top
17
- * level and nested inside object fields, array items and `optional` / `nullable`
18
- * / `default` / intersection wrappers — so the advertised JSON Schema carries no
19
- * `oneOf` / `anyOf` at any depth. `flattenDiscriminatedUnion` alone is shallow
20
- * (it copies a variant's fields verbatim), so a nested union — e.g.
21
- * `content.parts[]` being an array of a discriminated union would otherwise
22
- * still reach the transport as `oneOf`, which weaker models mishandle.
23
- *
24
- * Like the single-level flatten this is **lossy and advertised-only**: the
25
- * original schemas remain the validation schemas in `executeToolMethod`. Schemas
26
- * a transform cannot safely rebuild (refined / piped / lazy / plain non-
27
- * discriminated unions) are left untouched — a discriminated union behind one of
28
- * those keeps its `oneOf`.
28
+ * Recursively flatten **every** flattenable `ZodDiscriminatedUnion` in a schema —
29
+ * top level and nested inside object fields, array items, plain unions, records,
30
+ * and `optional` / `nullable` / `default` / intersection wrappers — so the
31
+ * advertised JSON Schema carries no `oneOf` / `anyOf` at any depth. A union that
32
+ * cannot be flattened (non-string discriminator, non-object variant) is left
33
+ * untouched rather than crashing the mount (→ ADR 0033). Advertised-only; the
34
+ * original schemas remain the validation schemas.
29
35
  */
30
36
  export declare function flattenUnionsDeep(schema: z.core.$ZodType): z.ZodType;
31
37
  //# sourceMappingURL=flatten.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../src/tools/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,CAAC,CAAC,qBAAqB,GAC7B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAkD5B;AAOD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,CAwCpE"}
1
+ {"version":3,"file":"flatten.d.ts","sourceRoot":"","sources":["../../src/tools/flatten.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,CAAC,CAAC,qBAAqB,GAC7B,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CA6C5B;AA4GD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,CAkDpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,oBAAoB,EAAsB,MAAM,OAAO,CAAC;AACtF,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,kBAAkB,CAAC;AAqEvF,MAAM,WAAW,gBAAgB,CAAC,KAAK,CAAE,SAAQ,oBAAoB,CAAC,KAAK,CAAC;IAC1E,uEAAuE;IACvE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC7D;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAoBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC9B,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAkHrC"}
1
+ {"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../../src/tools/mcp-handler.ts"],"names":[],"mappings":"AASA,OAAO,EAAkB,KAAK,oBAAoB,EAAsB,MAAM,OAAO,CAAC;AACtF,OAAO,EAAE,KAAK,uBAAuB,EAAyB,MAAM,kBAAkB,CAAC;AAqEvF,MAAM,WAAW,gBAAgB,CAAC,KAAK,CAAE,SAAQ,oBAAoB,CAAC,KAAK,CAAC;IAC1E,uEAAuE;IACvE,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IAC7D;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAoBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EACpC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,GAC9B,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAqHrC"}
@@ -43,7 +43,10 @@ export interface McpMountConfig {
43
43
  * callable on its own (a startup assertion, a test) to fail a deploy before
44
44
  * the first request.
45
45
  */
46
- export declare function validateMcpSchemas(services: ServiceDef[], onIncompatibleSchema?: IncompatibleSchemaPolicy, logger?: StitchLogger): void;
46
+ export declare function validateMcpSchemas(services: ServiceDef[], onIncompatibleSchema?: IncompatibleSchemaPolicy, logger?: StitchLogger, options?: {
47
+ extend?: ToolExtend;
48
+ flattenUnionInput?: boolean;
49
+ }): void;
47
50
  export declare function mountMcp(mcpServer: McpServer, services: ServiceDef | ServiceDef[], config?: McpMountConfig): void;
48
51
  /**
49
52
  * Transport-neutral build config for an MCP server — everything needed to turn
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/tools/mcp.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/tools/mount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAKnB;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAElE,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,qEAAqE;IACrE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC;CAC9D;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;CACvB;AAkBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,SAAS,EACpB,MAAM,GAAE,kBAAuB,GAC9B,aAAa,EAAE,CA+BjB;AAED,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,MAAM,EAAE,eAAe,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,qCAAqC;IACrC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,gEAAgE;IAChE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnE,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GACvB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAsBhF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,EAC1C,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GACjE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../src/tools/mount.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,UAAU,EAChB,MAAM,WAAW,CAAC;AAKnB;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU,CACzB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAElE,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAClC,qEAAqE;IACrE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC;CAC9D;AAED,2DAA2D;AAC3D,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,sFAAsF;IACtF,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC;IAClB,mDAAmD;IACnD,YAAY,EAAE,OAAO,CAAC;CACvB;AAkBD,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,SAAS,EACpB,MAAM,GAAE,kBAAuB,GAC9B,aAAa,EAAE,CAkCjB;AAED,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,MAAM,EAAE,eAAe,CAAC;IACxB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,qCAAqC;IACrC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,gEAAgE;IAChE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnE,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,gBAAgB,GACvB,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAsBhF;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE;IAAE,EAAE,EAAE,KAAK,CAAA;CAAE,CAAC,EAC1C,QAAQ,CAAC,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GACjE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAazB"}
package/dist/tools.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  inputIsQuery,
3
3
  signJwt,
4
4
  verifyPkce
5
- } from "./index-msmy8ydw.js";
5
+ } from "./index-yv93m4yr.js";
6
6
  import {
7
7
  coerceJsonArgs,
8
8
  collectTools,
@@ -15,14 +15,14 @@ import {
15
15
  pollUntil,
16
16
  readCapped,
17
17
  toolResultFromError
18
- } from "./index-91b3n95r.js";
18
+ } from "./index-bb18z3px.js";
19
19
  import {
20
20
  toJsonSchema
21
21
  } from "./index-0ed3bx43.js";
22
22
  import {
23
23
  AppError,
24
24
  isWithinDir
25
- } from "./index-fq89tdex.js";
25
+ } from "./index-ktn76xz0.js";
26
26
  import {
27
27
  isRecord,
28
28
  typedEntries
@@ -183,11 +183,11 @@ function prepareMcpTool(mountable, policy, logger, failures, seen) {
183
183
  }
184
184
  return { outputSchema: resolved.schema, outputMode: resolved.mode };
185
185
  }
186
- function validateMcpSchemas(services, onIncompatibleSchema = "throw", logger) {
186
+ function validateMcpSchemas(services, onIncompatibleSchema = "throw", logger, options) {
187
187
  const seen = new Set;
188
188
  const failures = [];
189
189
  for (const service of services) {
190
- for (const mountable of collectTools(service, "MCP", undefined)) {
190
+ for (const mountable of collectTools(service, "MCP", options)) {
191
191
  prepareMcpTool(mountable, onIncompatibleSchema, logger, failures, seen);
192
192
  }
193
193
  }
@@ -367,7 +367,10 @@ function jsonRpcError(code, message, status, headers) {
367
367
  }
368
368
  function createMcpHandler(config) {
369
369
  if (Array.isArray(config.services)) {
370
- validateMcpSchemas(config.services, config.onIncompatibleSchema, config.logger);
370
+ validateMcpSchemas(config.services, config.onIncompatibleSchema, config.logger, {
371
+ extend: config.extend,
372
+ flattenUnionInput: config.flattenUnionInput
373
+ });
371
374
  }
372
375
  const unauthorized = () => {
373
376
  const headers = config.protectedResource ? { "WWW-Authenticate": wwwAuthenticateHeader(config.protectedResource.resource) } : undefined;
package/llms-full.txt CHANGED
@@ -2142,6 +2142,12 @@ if (ctx.input.title.length > 200) badRequest('Title too long', { max: 200 })
2142
2142
  Each helper has a `never` return type — TypeScript knows execution stops, so the
2143
2143
  code after it is correctly narrowed.
2144
2144
 
2145
+ You can subclass `AppError` for a domain error model (`class FeatureLocked extends
2146
+ AppError`). `AppError.is(err)` identifies any instance — a direct one, a subclass,
2147
+ even a copy from another bundle chunk or realm — by a global brand rather than
2148
+ `instanceof`, so a domain error keeps its `code` / `details` / `hint` on every
2149
+ transport (HTTP, MCP, agent). → ADR 0032.
2150
+
2145
2151
  ### The error envelope
2146
2152
 
2147
2153
  `AppError.toJSON()` renders the public envelope every transport returns:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Contract-first backend framework — one defineContract() into an HTTP API, MCP tools, AI-agent tools and a typed client. Bun and Node.",
5
5
  "keywords": [
6
6
  "bun",