stitchkit 0.98.0 → 0.99.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 (32) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -3
  3. package/dist/entrypoints/agent-runtime/harness.js +4 -4
  4. package/dist/entrypoints/agent-runtime/sandbox.js +3 -3
  5. package/dist/entrypoints/agent-runtime.js +7 -7
  6. package/dist/entrypoints/application.js +1 -1
  7. package/dist/entrypoints/cli.js +6 -6
  8. package/dist/entrypoints/live.js +1 -1
  9. package/dist/entrypoints/testing.js +1 -1
  10. package/dist/entrypoints/tools/connections.js +2 -2
  11. package/dist/entrypoints/tools/invoker.js +4 -4
  12. package/dist/entrypoints/tools.js +8 -8
  13. package/dist/{index-np4m8hd3.js → index-0r0fbk7z.js} +9 -7
  14. package/dist/{index-p9sh0xx4.js → index-5p2m7we1.js} +3 -3
  15. package/dist/{index-55hkhm67.js → index-8qt2m66q.js} +1 -1
  16. package/dist/{index-hmp4800j.js → index-9t3dffv2.js} +3 -3
  17. package/dist/{index-khtgb21r.js → index-bm5rx7n6.js} +2 -2
  18. package/dist/{index-xw3s75nj.js → index-d8m8zpd8.js} +1 -1
  19. package/dist/{index-het2he5g.js → index-e4hkgm5t.js} +1 -1
  20. package/dist/{index-nts4a2br.js → index-jhx828hc.js} +1 -1
  21. package/dist/{index-f1nb70ae.js → index-r066jx76.js} +4 -4
  22. package/dist/{index-863ea9jb.js → index-sh3s86na.js} +3 -3
  23. package/dist/{index-wdkt63w3.js → index-wt743f7f.js} +17 -4
  24. package/dist/live/watch-delta.d.ts.map +1 -1
  25. package/dist/tools/schema/flatten-join.d.ts.map +1 -1
  26. package/llms/stitchkit.txt +3 -3
  27. package/llms/tools.txt +9 -8
  28. package/llms/{upgrading-0.72.0-0.98.0.txt → upgrading-0.72.0-0.99.0.txt} +32 -3
  29. package/llms/upgrading.txt +1 -1
  30. package/llms-full.txt +41 -11
  31. package/llms.txt +2 -2
  32. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -15,6 +15,36 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.99.0] — 2026-09-27
19
+
20
+ ### ⚠️ Breaking changes
21
+
22
+ - `stitchkit/tools` — `flattenUnionInput` preserves object properties and typed
23
+ array items when discriminated-union variants share a field with different
24
+ structures. Flat mode no longer guarantees the absence of nested `anyOf`.
25
+ Before: a collided object/array field was `{ type: ['object', 'array'] }`.
26
+ After: `{ anyOf: [{ type: 'object', properties: ... }, { type: 'array', items: ... }] }`.
27
+ The containing union stays an object and the original contract still validates
28
+ execution. Schema consumers must traverse these nested alternatives; no
29
+ contract changes or global flatten opt-out are needed. This avoids provider
30
+ rejection of array schemas with missing `items`. See
31
+ [ADR 0205](docs/decisions/0205-flat-tool-collisions-retain-structural-alternatives.md).
32
+
33
+ **Who must act:** users of `flattenUnionInput: true` whose schema walkers,
34
+ snapshots or provider restrictions assume no nested `anyOf`. Other consumers
35
+ only update the dependency; runtime input validation is unchanged.
36
+
37
+ ## [0.98.2] — 2026-09-27
38
+
39
+ ### Fixed
40
+
41
+ - `stitchkit/live` — prepending to a watched array preserves future copy bases,
42
+ so a sliding window sends the new head plus one copy run instead of rewriting
43
+ the window. Duplicate lookup advances through each signature bucket once;
44
+ full-value fallback and the delta wire format are unchanged.
45
+ - Package-scoped release commits now produce the same validated publication
46
+ artifacts as release trains; a green CI run no longer omits their npm tarball.
47
+
18
48
  ## [0.98.0] — 2026-09-26
19
49
 
20
50
  ### ⚠️ Breaking changes
@@ -3,11 +3,11 @@ import {
3
3
  AgentCodingToolLimitsSchema,
4
4
  AgentCodingToolPathAuthorizationSchema,
5
5
  createAgentCodingTools
6
- } from "../../index-het2he5g.js";
6
+ } from "../../index-e4hkgm5t.js";
7
7
  import"../../index-px2gm2jp.js";
8
8
  import"../../index-qmy6zq75.js";
9
- import"../../index-xw3s75nj.js";
10
- import"../../index-np4m8hd3.js";
9
+ import"../../index-d8m8zpd8.js";
10
+ import"../../index-0r0fbk7z.js";
11
11
  import"../../index-eqqvgdb3.js";
12
12
  import"../../index-znfs20ss.js";
13
13
  import"../../index-p5r7qpdd.js";
@@ -6,7 +6,7 @@ import {
6
6
  composeAgentPrompt,
7
7
  createAgentRuntime,
8
8
  createAgentRuntimeEventSink
9
- } from "../../index-nts4a2br.js";
9
+ } from "../../index-jhx828hc.js";
10
10
  import"../../index-83bdg97s.js";
11
11
  import"../../index-y64k3s0h.js";
12
12
  import {
@@ -19,15 +19,15 @@ import {
19
19
  import"../../index-gxrt5h6v.js";
20
20
  import"../../index-gtj3zc53.js";
21
21
  import"../../index-79z7m7dt.js";
22
- import"../../index-55hkhm67.js";
22
+ import"../../index-8qt2m66q.js";
23
23
  import"../../index-zfrhfn82.js";
24
24
  import"../../index-35mh5bhj.js";
25
25
  import"../../index-zcgf3gqf.js";
26
26
  import"../../index-1zbbzgfh.js";
27
27
  import {
28
28
  defineRuntimeTool
29
- } from "../../index-xw3s75nj.js";
30
- import"../../index-np4m8hd3.js";
29
+ } from "../../index-d8m8zpd8.js";
30
+ import"../../index-0r0fbk7z.js";
31
31
  import"../../index-eqqvgdb3.js";
32
32
  import"../../index-znfs20ss.js";
33
33
  import"../../index-p5r7qpdd.js";
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  createAgentCodingTools
3
- } from "../../index-het2he5g.js";
3
+ } from "../../index-e4hkgm5t.js";
4
4
  import"../../index-px2gm2jp.js";
5
5
  import {
6
6
  codingRefusal,
7
7
  missingSandboxRestrictions,
8
8
  probeAgentProcessSandbox
9
9
  } from "../../index-qmy6zq75.js";
10
- import"../../index-xw3s75nj.js";
11
- import"../../index-np4m8hd3.js";
10
+ import"../../index-d8m8zpd8.js";
11
+ import"../../index-0r0fbk7z.js";
12
12
  import"../../index-eqqvgdb3.js";
13
13
  import"../../index-znfs20ss.js";
14
14
  import"../../index-p5r7qpdd.js";
@@ -24,7 +24,7 @@ import {
24
24
  renderAgentStateSlots,
25
25
  repairedSearchCall,
26
26
  selectAgentHistory
27
- } from "../index-nts4a2br.js";
27
+ } from "../index-jhx828hc.js";
28
28
  import"../index-83bdg97s.js";
29
29
  import {
30
30
  AgentAdmissionEventSchema,
@@ -164,7 +164,7 @@ import {
164
164
  import {
165
165
  buildToolManifest,
166
166
  mountAgent
167
- } from "../index-863ea9jb.js";
167
+ } from "../index-sh3s86na.js";
168
168
  import {
169
169
  DURABILITY_STEP_EVENT_KIND,
170
170
  ParkAbortedError,
@@ -173,9 +173,9 @@ import {
173
173
  StepResultDecodeError,
174
174
  StepResultNotSerializableError
175
175
  } from "../index-79z7m7dt.js";
176
- import"../index-hmp4800j.js";
177
- import"../index-khtgb21r.js";
178
- import"../index-55hkhm67.js";
176
+ import"../index-9t3dffv2.js";
177
+ import"../index-bm5rx7n6.js";
178
+ import"../index-8qt2m66q.js";
179
179
  import"../index-zfrhfn82.js";
180
180
  import"../index-35mh5bhj.js";
181
181
  import {
@@ -186,8 +186,8 @@ import"../index-1zbbzgfh.js";
186
186
  import {
187
187
  defineRuntimeTool,
188
188
  executableAgentRuntimeTools
189
- } from "../index-xw3s75nj.js";
190
- import"../index-np4m8hd3.js";
189
+ } from "../index-d8m8zpd8.js";
190
+ import"../index-0r0fbk7z.js";
191
191
  import"../index-eqqvgdb3.js";
192
192
  import"../index-znfs20ss.js";
193
193
  import"../index-p5r7qpdd.js";
@@ -73,7 +73,7 @@ import {
73
73
  deltaWins,
74
74
  diff,
75
75
  watchKeyString
76
- } from "../index-wdkt63w3.js";
76
+ } from "../index-wt743f7f.js";
77
77
  import"../index-1j8pm5t0.js";
78
78
  import {
79
79
  BoundedChannelPolicySchema,
@@ -18,22 +18,22 @@ import {
18
18
  readCapped,
19
19
  renderCliView,
20
20
  routeCliArgv
21
- } from "../index-f1nb70ae.js";
21
+ } from "../index-r066jx76.js";
22
22
  import"../index-sbdmyz75.js";
23
- import"../index-hmp4800j.js";
23
+ import"../index-9t3dffv2.js";
24
24
  import {
25
25
  argumentsDigest
26
26
  } from "../index-0b1ess5e.js";
27
- import"../index-khtgb21r.js";
28
- import"../index-55hkhm67.js";
27
+ import"../index-bm5rx7n6.js";
28
+ import"../index-8qt2m66q.js";
29
29
  import"../index-zfrhfn82.js";
30
30
  import"../index-35mh5bhj.js";
31
31
  import"../index-zcgf3gqf.js";
32
32
  import {
33
33
  coerceJsonArgs
34
34
  } from "../index-1zbbzgfh.js";
35
- import"../index-xw3s75nj.js";
36
- import"../index-np4m8hd3.js";
35
+ import"../index-d8m8zpd8.js";
36
+ import"../index-0r0fbk7z.js";
37
37
  import"../index-eqqvgdb3.js";
38
38
  import"../index-znfs20ss.js";
39
39
  import"../index-p5r7qpdd.js";
@@ -14,7 +14,7 @@ import {
14
14
  diff,
15
15
  watchContract,
16
16
  watchKeyString
17
- } from "../index-wdkt63w3.js";
17
+ } from "../index-wt743f7f.js";
18
18
  import"../index-1j8pm5t0.js";
19
19
  import"../index-d9pk3td4.js";
20
20
  import {
@@ -34,7 +34,7 @@ import {
34
34
  prepareProjectedMcpTools,
35
35
  projectToolSurface,
36
36
  staticInputRounds
37
- } from "../index-np4m8hd3.js";
37
+ } from "../index-0r0fbk7z.js";
38
38
  import {
39
39
  toJsonSchema
40
40
  } from "../index-eqqvgdb3.js";
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  defineRuntimeTool
3
- } from "../../index-xw3s75nj.js";
3
+ } from "../../index-d8m8zpd8.js";
4
4
  import {
5
5
  declaresDraft07,
6
6
  withDefsDialect
7
- } from "../../index-np4m8hd3.js";
7
+ } from "../../index-0r0fbk7z.js";
8
8
  import"../../index-eqqvgdb3.js";
9
9
  import"../../index-znfs20ss.js";
10
10
  import"../../index-p5r7qpdd.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createToolInvoker
3
- } from "../../index-p9sh0xx4.js";
4
- import"../../index-khtgb21r.js";
5
- import"../../index-55hkhm67.js";
3
+ } from "../../index-5p2m7we1.js";
4
+ import"../../index-bm5rx7n6.js";
5
+ import"../../index-8qt2m66q.js";
6
6
  import"../../index-zfrhfn82.js";
7
7
  import"../../index-35mh5bhj.js";
8
8
  import"../../index-zcgf3gqf.js";
9
9
  import"../../index-1zbbzgfh.js";
10
- import"../../index-np4m8hd3.js";
10
+ import"../../index-0r0fbk7z.js";
11
11
  import"../../index-eqqvgdb3.js";
12
12
  import"../../index-znfs20ss.js";
13
13
  import"../../index-p5r7qpdd.js";
@@ -23,7 +23,7 @@ import {
23
23
  buildToolManifest,
24
24
  describeToolCatalog,
25
25
  mountAgent
26
- } from "../index-863ea9jb.js";
26
+ } from "../index-sh3s86na.js";
27
27
  import {
28
28
  AgentToolError,
29
29
  EffectUnresolvedError,
@@ -52,7 +52,7 @@ import {
52
52
  } from "../index-m9zn6cpq.js";
53
53
  import {
54
54
  createToolInvoker
55
- } from "../index-p9sh0xx4.js";
55
+ } from "../index-5p2m7we1.js";
56
56
  import {
57
57
  WaitTimeoutError,
58
58
  createCli,
@@ -60,11 +60,11 @@ import {
60
60
  fetchPinnedDocument,
61
61
  readCapped,
62
62
  runWaitOperation
63
- } from "../index-f1nb70ae.js";
63
+ } from "../index-r066jx76.js";
64
64
  import"../index-sbdmyz75.js";
65
65
  import {
66
66
  collectToolSurface
67
- } from "../index-hmp4800j.js";
67
+ } from "../index-9t3dffv2.js";
68
68
  import {
69
69
  argumentsDigest
70
70
  } from "../index-0b1ess5e.js";
@@ -72,13 +72,13 @@ import {
72
72
  collectTools,
73
73
  createToolRunner,
74
74
  formatToolError
75
- } from "../index-khtgb21r.js";
75
+ } from "../index-bm5rx7n6.js";
76
76
  import {
77
77
  ToolExecutionControlError,
78
78
  isToolExecutionControlError,
79
79
  parseToolCallArguments,
80
80
  toolResultFromError
81
- } from "../index-55hkhm67.js";
81
+ } from "../index-8qt2m66q.js";
82
82
  import {
83
83
  getRequestContext,
84
84
  getTraceId,
@@ -94,7 +94,7 @@ import {
94
94
  import {
95
95
  createRuntimeToolFactory,
96
96
  defineRuntimeTool
97
- } from "../index-xw3s75nj.js";
97
+ } from "../index-d8m8zpd8.js";
98
98
  import {
99
99
  PORTABLE_JSON_SCHEMA_FORMATS,
100
100
  assertToolName,
@@ -108,7 +108,7 @@ import {
108
108
  toolSurfaceOutputSchema,
109
109
  validateMcpRoundPolicy,
110
110
  validateResolvedInputRounds
111
- } from "../index-np4m8hd3.js";
111
+ } from "../index-0r0fbk7z.js";
112
112
  import {
113
113
  toJsonSchema
114
114
  } from "../index-eqqvgdb3.js";
@@ -271,12 +271,7 @@ function typeNames(schema) {
271
271
  return combinedBranchTypes(schema);
272
272
  }
273
273
  function typeSchema(type, nullable) {
274
- const schema = { type: nullable ? [type, "null"] : type };
275
- if (type === "array")
276
- schema.items = {};
277
- if (type === "object")
278
- schema.additionalProperties = {};
279
- return schema;
274
+ return { type: nullable ? [type, "null"] : type };
280
275
  }
281
276
  function commonBaseType(schemas) {
282
277
  const names = schemas.map(typeNames);
@@ -296,6 +291,13 @@ function commonBaseType(schemas) {
296
291
  }
297
292
  if (bases.size === 0)
298
293
  return nullable ? { type: "null" } : {};
294
+ if (bases.has("array") || bases.has("object")) {
295
+ const alternatives = new Map;
296
+ for (const schema of schemas)
297
+ alternatives.set(serializeCanonicalJson(schema), schema);
298
+ const ordered = [...alternatives].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([, schema]) => schema);
299
+ return { anyOf: structuredClone(ordered) };
300
+ }
299
301
  if (bases.size === 1) {
300
302
  const [only] = bases;
301
303
  return only ? typeSchema(only, nullable) : {};
@@ -316,7 +318,7 @@ function mergePropertySchemas(properties) {
316
318
  } else {
317
319
  const values = schemas.map(stringValues);
318
320
  const allStrings = values.every((value) => value !== null);
319
- merged = allStrings ? { type: "string", enum: [...new Set(values.flatMap((value) => value ?? []))] } : commonBaseType(schemas);
321
+ merged = allStrings ? { type: "string", enum: [...new Set(values.flatMap((value) => value ?? []))] } : commonBaseType(structural);
320
322
  }
321
323
  const descriptions = [
322
324
  ...new Set(schemas.map((schema) => schema.description).filter((value) => typeof value === "string"))
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  collectTools,
3
3
  createToolRunner
4
- } from "./index-khtgb21r.js";
4
+ } from "./index-bm5rx7n6.js";
5
5
  import {
6
6
  toolErrorFromResult
7
- } from "./index-55hkhm67.js";
7
+ } from "./index-8qt2m66q.js";
8
8
  import {
9
9
  assertUniqueToolName
10
- } from "./index-np4m8hd3.js";
10
+ } from "./index-0r0fbk7z.js";
11
11
  import {
12
12
  AppError
13
13
  } from "./index-2vtcmrj9.js";
@@ -9,7 +9,7 @@ import {
9
9
  applyToolViewDefaults,
10
10
  objectShapeKeys,
11
11
  projectToolView
12
- } from "./index-np4m8hd3.js";
12
+ } from "./index-0r0fbk7z.js";
13
13
  import {
14
14
  normalizeError,
15
15
  validateDeclaredOutput
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  contractToolMountable
3
- } from "./index-khtgb21r.js";
3
+ } from "./index-bm5rx7n6.js";
4
4
  import {
5
5
  runtimeToolMountable
6
- } from "./index-xw3s75nj.js";
6
+ } from "./index-d8m8zpd8.js";
7
7
  import {
8
8
  projectToolSurface
9
- } from "./index-np4m8hd3.js";
9
+ } from "./index-0r0fbk7z.js";
10
10
 
11
11
  // src/tools/surface.ts
12
12
  function collectToolSurface({
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  executeToolMethod,
3
3
  toolErrorFromResult
4
- } from "./index-55hkhm67.js";
4
+ } from "./index-8qt2m66q.js";
5
5
  import {
6
6
  assertToolExtensionCompatible,
7
7
  mergeSchemas,
8
8
  projectToolSurface,
9
9
  rebuildObject
10
- } from "./index-np4m8hd3.js";
10
+ } from "./index-0r0fbk7z.js";
11
11
  import {
12
12
  isRetryableStatus
13
13
  } from "./index-2vtcmrj9.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  projectRuntimeTool
3
- } from "./index-np4m8hd3.js";
3
+ } from "./index-0r0fbk7z.js";
4
4
 
5
5
  // src/tools/runtime-tool.ts
6
6
  function defineRuntimeTool(definition) {
@@ -22,7 +22,7 @@ import {
22
22
  } from "./index-qmy6zq75.js";
23
23
  import {
24
24
  defineRuntimeTool
25
- } from "./index-xw3s75nj.js";
25
+ } from "./index-d8m8zpd8.js";
26
26
  import {
27
27
  conflict,
28
28
  forbidden
@@ -37,7 +37,7 @@ import {
37
37
  import {
38
38
  ToolExecutionControlError,
39
39
  isToolExecutionControlError
40
- } from "./index-55hkhm67.js";
40
+ } from "./index-8qt2m66q.js";
41
41
  import {
42
42
  isRecord,
43
43
  transportResult
@@ -3,15 +3,15 @@ import {
3
3
  } from "./index-sbdmyz75.js";
4
4
  import {
5
5
  collectToolSurface
6
- } from "./index-hmp4800j.js";
6
+ } from "./index-9t3dffv2.js";
7
7
  import {
8
8
  createToolRunner,
9
9
  formatToolError
10
- } from "./index-khtgb21r.js";
10
+ } from "./index-bm5rx7n6.js";
11
11
  import {
12
12
  toolErrorFromResult,
13
13
  toolResultFromError
14
- } from "./index-55hkhm67.js";
14
+ } from "./index-8qt2m66q.js";
15
15
  import {
16
16
  coerceJsonArgs
17
17
  } from "./index-1zbbzgfh.js";
@@ -19,7 +19,7 @@ import {
19
19
  assertUniqueToolName,
20
20
  buildToolPresentationSchema,
21
21
  objectShapeKeys
22
- } from "./index-np4m8hd3.js";
22
+ } from "./index-0r0fbk7z.js";
23
23
  import {
24
24
  jsonSchemaFields
25
25
  } from "./index-eqqvgdb3.js";
@@ -4,16 +4,16 @@ import {
4
4
  } from "./index-79z7m7dt.js";
5
5
  import {
6
6
  collectToolSurface
7
- } from "./index-hmp4800j.js";
7
+ } from "./index-9t3dffv2.js";
8
8
  import {
9
9
  createToolRunner,
10
10
  formatToolError
11
- } from "./index-khtgb21r.js";
11
+ } from "./index-bm5rx7n6.js";
12
12
  import {
13
13
  isToolExecutionControlError,
14
14
  toolCauseFromResult,
15
15
  toolResultFromError
16
- } from "./index-55hkhm67.js";
16
+ } from "./index-8qt2m66q.js";
17
17
  import {
18
18
  isRecord
19
19
  } from "./index-hffjpmq9.js";
@@ -69,6 +69,10 @@ function objectDiff(previous, next) {
69
69
  }
70
70
  function arrayDiff(previous, next) {
71
71
  const previousSignatures = previous.map(signature);
72
+ const nextSignatures = next.map(signature);
73
+ const remaining = new Map;
74
+ for (const value of nextSignatures)
75
+ remaining.set(value, (remaining.get(value) ?? 0) + 1);
72
76
  const positions = new Map;
73
77
  previousSignatures.forEach((value, index) => {
74
78
  const bucket = positions.get(value);
@@ -77,6 +81,7 @@ function arrayDiff(previous, next) {
77
81
  else
78
82
  positions.set(value, [index]);
79
83
  });
84
+ const offsets = new Map;
80
85
  const taken = new Set;
81
86
  const ops = [];
82
87
  let cursor = 0;
@@ -87,8 +92,9 @@ function arrayDiff(previous, next) {
87
92
  ops[ops.length - 1] = { o: "copy", from: last.from, count: last.count + 1 };
88
93
  return true;
89
94
  };
90
- for (const element of next) {
91
- const wanted = signature(element);
95
+ for (const [index, wanted] of nextSignatures.entries()) {
96
+ const element = next[index];
97
+ remaining.set(wanted, (remaining.get(wanted) ?? 0) - 1);
92
98
  const last = ops.at(-1);
93
99
  const continuation = last?.o === "copy" ? last.from + last.count : undefined;
94
100
  if (continuation !== undefined && continuation < previous.length && previousSignatures[continuation] === wanted && !taken.has(continuation)) {
@@ -98,7 +104,13 @@ function arrayDiff(previous, next) {
98
104
  continue;
99
105
  }
100
106
  const bucket = positions.get(wanted);
101
- const found = bucket?.find((index) => !taken.has(index));
107
+ let offset = offsets.get(wanted) ?? 0;
108
+ let found = bucket?.[offset];
109
+ while (found !== undefined && taken.has(found)) {
110
+ offset += 1;
111
+ found = bucket?.[offset];
112
+ }
113
+ offsets.set(wanted, found === undefined ? offset : offset + 1);
102
114
  if (found !== undefined) {
103
115
  taken.add(found);
104
116
  if (!extend(found))
@@ -106,7 +118,8 @@ function arrayDiff(previous, next) {
106
118
  cursor = found + 1;
107
119
  continue;
108
120
  }
109
- const counterpart = cursor < previous.length && !taken.has(cursor) ? cursor : undefined;
121
+ const candidate = previousSignatures[cursor];
122
+ const counterpart = candidate !== undefined && !taken.has(cursor) && !remaining.get(candidate) ? cursor : undefined;
110
123
  const nested = counterpart === undefined ? undefined : diff(previous[counterpart], element);
111
124
  if (counterpart !== undefined && nested !== undefined) {
112
125
  taken.add(counterpart);
@@ -1 +1 @@
1
- {"version":3,"file":"watch-delta.d.ts","sourceRoot":"","sources":["../../src/live/watch-delta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6DAA6D;AAC7D,MAAM,MAAM,YAAY;AACtB,wEAAwE;AACtE;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACvE,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAA;CAAE;AACxE,4DAA4D;GAC1D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/C,yCAAyC;AACzC,MAAM,MAAM,UAAU;AACpB,gEAAgE;AAC9D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C;IACE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,GACD;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAUzB,CAAC;AAE3B,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAc3B,CAAC;AAa7B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAK7E;AAwGD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAqCnE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE"}
1
+ {"version":3,"file":"watch-delta.d.ts","sourceRoot":"","sources":["../../src/live/watch-delta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,6DAA6D;AAC7D,MAAM,MAAM,YAAY;AACtB,wEAAwE;AACtE;IAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACvE,+DAA+D;GAC7D;IAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAA;CAAE;AACxE,4DAA4D;GAC1D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAE/C,yCAAyC;AACzC,MAAM,MAAM,UAAU;AACpB,gEAAgE;AAC9D;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1C;IACE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACpD,wCAAwC;IACxC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,GACD;IAAE,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,CAAC;AAEjE,eAAO,MAAM,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAUzB,CAAC;AAE3B,eAAO,MAAM,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY,CAc3B,CAAC;AAa7B;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAK7E;AA2HD;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAqCnE;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAEpE"}
@@ -1 +1 @@
1
- {"version":3,"file":"flatten-join.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/flatten-join.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAsED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,EAAE,GAAG,IAAI,CAK5E;AA+HD,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,sBAAsB,CA4B1F"}
1
+ {"version":3,"file":"flatten-join.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/flatten-join.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAsED,oFAAoF;AACpF,wBAAgB,YAAY,CAAC,MAAM,EAAE,sBAAsB,GAAG,MAAM,EAAE,GAAG,IAAI,CAK5E;AAuID,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,eAAe,EAAE,GAAG,sBAAsB,CA4B1F"}
@@ -77,11 +77,11 @@ own, recorded as an ADR.
77
77
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
78
78
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
79
79
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
80
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 43 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
80
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 44 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
81
81
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
82
82
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
83
83
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
84
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 43 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
84
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 44 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
85
85
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
86
86
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
87
87
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -91,7 +91,7 @@ own, recorded as an ADR.
91
91
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
92
92
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
93
93
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
94
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 9 of the 43 minors since 0.56.2, most recently 0.96.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
94
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 9 of the 44 minors since 0.56.2, most recently 0.96.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
95
95
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
96
96
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
97
97
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
package/llms/tools.txt CHANGED
@@ -722,14 +722,15 @@ as one thing. Where they agree, that is what you get; where they disagree — a
722
722
  `.refine()` only one of them carries, two different bounds on the same number, an
723
723
  enum against a free string — the *constraint* is dropped and the **type** is not.
724
724
  A field that is a number in every variant is advertised as a number, not as a
725
- bare description. When the kinds genuinely differ, the flat projection keeps
726
- every provable kind in a deterministic JSON Schema type array — for example
727
- `type: ['string', 'array']` — while dropping constraints that are not sound for
728
- all branches. Nested `oneOf` / `anyOf` values still contribute their provable
729
- base kinds without reintroducing union keywords. Only a branch whose kind is
725
+ bare description. Scalar collisions keep every provable kind in a deterministic
726
+ JSON Schema type array. If any alternative is an object or array, the property
727
+ retains distinct structural alternatives in `anyOf`: object properties, typed
728
+ array items, bounds and nullable values remain available to the model. The
729
+ containing discriminated union still becomes one object; flat mode does not
730
+ promise to remove every nested union keyword. Only a branch whose kind is
730
731
  actually unknowable, such as a free-form schema or unresolved reference, leaves
731
732
  the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md)
732
- and [0065](../decisions/0065-flat-collisions-preserve-every-known-kind.md)
733
+ and [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md).
733
734
 
734
735
  It is **deep** because the projection walks the generated JSON Schema document,
735
736
  including objects, arrays, tuples and schema-definition nodes. Structurally
@@ -738,8 +739,8 @@ Plain unions and unions hidden behind unresolved external references remain
738
739
  unions because Stitchkit cannot soundly invent a discriminator.
739
740
 
740
741
  Use the default `flattenUnionInput: false` when the model must see the exact
741
- relationship between a discriminator and each branch. The flat type array is a
742
- sound set of possible JSON kinds, not a reconstruction of those correlations.
742
+ relationship between a discriminator and each branch. Joined property schemas
743
+ describe allowed values without reconstructing those correlations.
743
744
 
744
745
  The flattened form is **lossy but never executable**. Per-variant refinements
745
746
  and incompatible constraints are widened in the presentation document; the
@@ -1,14 +1,43 @@
1
- # Upgrading 0.72.0 → 0.98.0 — stitchkit docs slice
1
+ # Upgrading 0.72.0 → 0.99.0 — stitchkit docs slice
2
2
 
3
3
  > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
4
  > `llms.txt` in this package.
5
5
 
6
- Contains: Guide: Upgrading, 0.72.0 → 0.98.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.72.0 → 0.99.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.72.0 → 0.98.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.72.0 → 0.99.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.99.0
13
+
14
+ ### structural alternatives in flattened tool schemas
15
+
16
+ **Who must act:** applications using `flattenUnionInput: true` with schema
17
+ walkers, snapshots or provider restrictions that assume there is no nested
18
+ `anyOf`. Applications without that assumption need only update the dependency.
19
+
20
+ Colliding object/array fields retain their complete structural alternatives:
21
+
22
+ ```ts
23
+ // Before: loses both field vocabulary and array items.
24
+ { type: ['object', 'array'] }
25
+ // After: structural alternatives live inside the property schema.
26
+ { anyOf: [
27
+ { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
28
+ { type: 'array', items: {
29
+ type: 'object', properties: { id: { type: 'string' } }, required: ['id'],
30
+ } },
31
+ ] }
32
+ ```
33
+
34
+ Traverse each nested alternative when inspecting schemas and regenerate schema
35
+ snapshots. Verify the actual manifest with the chosen provider. Keep flatten
36
+ enabled when a top-level discriminated union needs to be advertised as an
37
+ object; do not erase `items` or introduce consumer-specific schema patches.
38
+ The root object, discriminator enum, requiredness hints and strict runtime
39
+ contract validation are unchanged. See ADR 0205.
40
+
12
41
  ## Released migration: 0.98.0
13
42
 
14
43
  ### automatic stdin availability
@@ -11,7 +11,7 @@ Contains: Guide: Upgrading, general (docs/guide/upgrading.md)
11
11
 
12
12
  Load this slice, then every range slice between your installed version and the target:
13
13
 
14
- - 0.72.0 → 0.98.0: `llms/upgrading-0.72.0-0.98.0.txt`
14
+ - 0.72.0 → 0.99.0: `llms/upgrading-0.72.0-0.99.0.txt`
15
15
  - 0.59.0 → 0.71.0: `llms/upgrading-0.59.0-0.71.0.txt`
16
16
  - 0.37.0 → 0.58.0: `llms/upgrading-0.37.0-0.58.0.txt`
17
17
 
package/llms-full.txt CHANGED
@@ -68,11 +68,11 @@ own, recorded as an ADR.
68
68
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
69
69
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
70
70
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
71
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 43 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
71
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 44 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
72
72
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, plus the managed-resource conformance kit |
73
73
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
74
74
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
75
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 43 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
75
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 22 of the 44 minors since 0.56.2, most recently 0.97.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
76
76
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
77
77
  | `stitchkit/agent-runtime/testing` | tests on Bun or Node | evolving | credential-free replay, scripted provider faults, deterministic race controls and the agent-store conformance kit |
78
78
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -82,7 +82,7 @@ own, recorded as an ADR.
82
82
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
83
83
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
84
84
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
85
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 9 of the 43 minors since 0.56.2, most recently 0.96.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
85
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 9 of the 44 minors since 0.56.2, most recently 0.96.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
86
86
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
87
87
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
88
88
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -3959,14 +3959,15 @@ as one thing. Where they agree, that is what you get; where they disagree — a
3959
3959
  `.refine()` only one of them carries, two different bounds on the same number, an
3960
3960
  enum against a free string — the *constraint* is dropped and the **type** is not.
3961
3961
  A field that is a number in every variant is advertised as a number, not as a
3962
- bare description. When the kinds genuinely differ, the flat projection keeps
3963
- every provable kind in a deterministic JSON Schema type array — for example
3964
- `type: ['string', 'array']` — while dropping constraints that are not sound for
3965
- all branches. Nested `oneOf` / `anyOf` values still contribute their provable
3966
- base kinds without reintroducing union keywords. Only a branch whose kind is
3962
+ bare description. Scalar collisions keep every provable kind in a deterministic
3963
+ JSON Schema type array. If any alternative is an object or array, the property
3964
+ retains distinct structural alternatives in `anyOf`: object properties, typed
3965
+ array items, bounds and nullable values remain available to the model. The
3966
+ containing discriminated union still becomes one object; flat mode does not
3967
+ promise to remove every nested union keyword. Only a branch whose kind is
3967
3968
  actually unknowable, such as a free-form schema or unresolved reference, leaves
3968
3969
  the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md)
3969
- and [0065](../decisions/0065-flat-collisions-preserve-every-known-kind.md)
3970
+ and [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md).
3970
3971
 
3971
3972
  It is **deep** because the projection walks the generated JSON Schema document,
3972
3973
  including objects, arrays, tuples and schema-definition nodes. Structurally
@@ -3975,8 +3976,8 @@ Plain unions and unions hidden behind unresolved external references remain
3975
3976
  unions because Stitchkit cannot soundly invent a discriminator.
3976
3977
 
3977
3978
  Use the default `flattenUnionInput: false` when the model must see the exact
3978
- relationship between a discriminator and each branch. The flat type array is a
3979
- sound set of possible JSON kinds, not a reconstruction of those correlations.
3979
+ relationship between a discriminator and each branch. Joined property schemas
3980
+ describe allowed values without reconstructing those correlations.
3980
3981
 
3981
3982
  The flattened form is **lossy but never executable**. Per-variant refinements
3982
3983
  and incompatible constraints are widened in the presentation document; the
@@ -13034,6 +13035,35 @@ analytics policy belong to the application.
13034
13035
 
13035
13036
  # Upgrading stitchkit
13036
13037
 
13038
+ ## Released migration: 0.99.0
13039
+
13040
+ ### structural alternatives in flattened tool schemas
13041
+
13042
+ **Who must act:** applications using `flattenUnionInput: true` with schema
13043
+ walkers, snapshots or provider restrictions that assume there is no nested
13044
+ `anyOf`. Applications without that assumption need only update the dependency.
13045
+
13046
+ Colliding object/array fields retain their complete structural alternatives:
13047
+
13048
+ ```ts
13049
+ // Before: loses both field vocabulary and array items.
13050
+ { type: ['object', 'array'] }
13051
+ // After: structural alternatives live inside the property schema.
13052
+ { anyOf: [
13053
+ { type: 'object', properties: { id: { type: 'string' } }, required: ['id'] },
13054
+ { type: 'array', items: {
13055
+ type: 'object', properties: { id: { type: 'string' } }, required: ['id'],
13056
+ } },
13057
+ ] }
13058
+ ```
13059
+
13060
+ Traverse each nested alternative when inspecting schemas and regenerate schema
13061
+ snapshots. Verify the actual manifest with the chosen provider. Keep flatten
13062
+ enabled when a top-level discriminated union needs to be advertised as an
13063
+ object; do not erase `items` or introduce consumer-specific schema patches.
13064
+ The root object, discriminator enum, requiredness hints and strict runtime
13065
+ contract validation are unchanged. See ADR 0205.
13066
+
13037
13067
  ## Released migration: 0.98.0
13038
13068
 
13039
13069
  ### automatic stdin availability
package/llms.txt CHANGED
@@ -12,7 +12,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
12
12
  - **stitchkit**: [llms/stitchkit.txt](llms/stitchkit.txt) 15.6 KB → [llms/stitchkit.2.txt](llms/stitchkit.2.txt) 35.0 KB → [llms/stitchkit.3.txt](llms/stitchkit.3.txt) 14.2 KB
13
13
  - **stitchkit/live**: [llms/live.txt](llms/live.txt) 21.2 KB
14
14
  - **stitchkit/react**: [llms/react.txt](llms/react.txt) 8.6 KB
15
- - **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 44.9 KB → [llms/tools.2.txt](llms/tools.2.txt) 26.3 KB → [llms/tools.3.txt](llms/tools.3.txt) 25.4 KB
15
+ - **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 45.0 KB → [llms/tools.2.txt](llms/tools.2.txt) 26.3 KB → [llms/tools.3.txt](llms/tools.3.txt) 25.4 KB
16
16
  - **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
17
17
  - **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
18
18
  - **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.1 KB
@@ -52,7 +52,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
52
52
 
53
53
  ## Upgrading slices
54
54
  - **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 10.3 KB
55
- - **Upgrading 0.72.0 → 0.98.0**: [llms/upgrading-0.72.0-0.98.0.txt](llms/upgrading-0.72.0-0.98.0.txt) 44.8 KB
55
+ - **Upgrading 0.72.0 → 0.99.0**: [llms/upgrading-0.72.0-0.99.0.txt](llms/upgrading-0.72.0-0.99.0.txt) 46.0 KB
56
56
  - **Upgrading 0.59.0 → 0.71.0**: [llms/upgrading-0.59.0-0.71.0.txt](llms/upgrading-0.59.0-0.71.0.txt) 45.6 KB
57
57
  - **Upgrading 0.37.0 → 0.58.0**: [llms/upgrading-0.37.0-0.58.0.txt](llms/upgrading-0.37.0-0.58.0.txt) 40.0 KB
58
58
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.98.0",
3
+ "version": "0.99.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",