stitchkit 0.111.3 → 0.112.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/CHANGELOG.md CHANGED
@@ -15,6 +15,15 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.112.0] - 2026-10-24
19
+
20
+ ### ⚠️ Breaking changes
21
+
22
+ **Who must act:** scripts that combine named array options with bare positional arguments without an explicit `positionals` policy must name the scalar fields or declare their destinations. Flag-only calls and explicitly declared positional policies need no migration.
23
+
24
+ - `stitchkit/cli` — **array options require named arguments or an explicit positional policy.** Without a declared `positionals` policy, a named array option together with any bare positional is now a usage error before dispatch. Schema-order inference could mistake the array's remaining elements for unrelated optional fields and execute a different call. Before: `app resolve --references alpha.md beta.md gamma.md` could assign `beta.md` and `gamma.md` to other fields. After: `app resolve --references alpha.md --references beta.md --references gamma.md`, or `app resolve --references:='["alpha.md","beta.md","gamma.md"]'`. Name scalar fields with flags too, or declare their exact positional policy. Command help describes one element per option; only a declared trailing positional array is variadic. See [ADR 0268](docs/decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md) and the [migration](docs/guide/upgrading.md).
25
+ **Affects:** `stitchkit/cli` createCli, parseCliArgs
26
+
18
27
  ## [0.111.3] - 2026-10-20
19
28
 
20
29
  ### Fixed
@@ -16,7 +16,7 @@ import {
16
16
  renderCliView2,
17
17
  pollUntilDone2,
18
18
  createCli2
19
- } from "../index-jprxv2an.js";
19
+ } from "../index-bd7spznx.js";
20
20
  import"../index-fynr93w4.js";
21
21
  import"../index-ct75c3at.js";
22
22
  import"../index-h7accrrv.js";
@@ -74,7 +74,7 @@ import {
74
74
  WaitTimeoutError,
75
75
  runWaitOperation,
76
76
  createCli2
77
- } from "../index-jprxv2an.js";
77
+ } from "../index-bd7spznx.js";
78
78
  import {
79
79
  ManagedFilePathSchema2,
80
80
  ManagedFileRefSchema2
@@ -1102,6 +1102,12 @@ function resolveCliView(flags, ascending) {
1102
1102
  // src/tools/cli/args.ts
1103
1103
  function buildToolArgs(tokens, fields, fieldFor, declaredPositionals, allowUnknown) {
1104
1104
  const { flags, jsonFields, literalBooleanFlags, positionals } = tokens;
1105
+ if (declaredPositionals === undefined && positionals.length > 0) {
1106
+ const arrayFlag = [...flags.keys()].find((key) => fieldFor(key)?.kind === "array");
1107
+ if (arrayFlag !== undefined) {
1108
+ throw new CliArgumentError2(`--${arrayFlag} cannot be combined with automatic positional arguments. Repeat --${arrayFlag} for each element or use --${arrayFlag}:=JSON; name other fields with flags, or declare a positional policy.`);
1109
+ }
1110
+ }
1105
1111
  const toolArgs = {};
1106
1112
  const fillable = declaredPositionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...declaredPositionals];
1107
1113
  const variadicTail = declaredPositionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
@@ -1660,7 +1666,7 @@ function typeLabel(schema) {
1660
1666
  if (Array.isArray(schema.enum))
1661
1667
  return schema.enum.join("|");
1662
1668
  if (schema.type === "array")
1663
- return "value…";
1669
+ return "value";
1664
1670
  if (typeof schema.type === "string")
1665
1671
  return schema.type;
1666
1672
  return "value";
@@ -1822,6 +1828,13 @@ function renderCommandHelp(name, command, descriptor, applicationOptions = []) {
1822
1828
  if (flag !== undefined) {
1823
1829
  lines.push("", `A boolean flag is on alone or takes true/false: --${flag}, --${flag} false, --no-${flag}`);
1824
1830
  }
1831
+ const arrays = [...kinds].filter(([, info]) => info.kind === "array");
1832
+ for (const [field] of arrays) {
1833
+ lines.push("", `Repeat --${field} <value> for each element, or assign the whole array with --${field}:=JSON.`);
1834
+ }
1835
+ if (arrays.length > 0 && descriptor.positionals === undefined) {
1836
+ lines.push("Array options cannot be combined with automatic positional arguments; name other fields with flags.");
1837
+ }
1825
1838
  lines.push("", ...jsonValueHelp(fields), "");
1826
1839
  }
1827
1840
  const applicationLines = applicationOptionLines(applicationOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,aAAa,CAAC;AAMjE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;AA6GD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAC7B,MAAM,GAAE;IACN,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,GACL,aAAa,CAsBf;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,GAC9B,qBAAqB,CAyDvB"}
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,aAAa,CAAC;AAMjE,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,IAAI,EAAE,OAAO,CAAC;IACd,iEAAiE;IACjE,IAAI,EAAE,OAAO,CAAC;IACd,8DAA8D;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,OAAO,CAAC;IAChB,qDAAqD;IACrD,IAAI,EAAE,OAAO,CAAC;IACd,0FAA0F;IAC1F,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,+BAA+B;IAC/B,OAAO,EAAE,aAAa,CAAC;CACxB;AAwHD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,EAC7B,MAAM,GAAE;IACN,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,GACL,aAAa,CAsBf;AAED,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,0EAA0E;IAC1E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AASD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,SAAS,GAC9B,qBAAqB,CAyDvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAkIvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAsCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,CA6DR"}
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/help.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,eAAe,EAAoB,MAAM,+BAA+B,CAAC;AAEvF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAkIvD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,EAC7C,MAAM,EAAE,MAAM,GACb,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CASrC;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,MAAM,CAsCT;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,GAAE,SAAS,eAAe,EAAO,GAClD,MAAM,CAyER"}
package/llms/cli.2.txt CHANGED
@@ -281,7 +281,7 @@ SDK nor the `ai` peer.
281
281
  |--------|------|---------|
282
282
  | `createCli` | function | build and run a CLI from contracts — [guide](../guide/cli.md) |
283
283
  | `defineCliCommand` | function | define one Zod-typed CLI-only executable command with optional validated-result presentation/exit policy |
284
- | `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical (advanced) |
284
+ | `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical; named array options together with bare positionals require an explicit `positionals` policy (advanced) |
285
285
  | `routeCliArgv` | function | select the command out of argv without duplicating the global-option grammar (advanced) |
286
286
  | `extractCliGlobalOptions` | function | lift the application's own global options out of argv before routing (advanced) |
287
287
  | `coerceJsonArgs` | function | the second half of `parseCliArgs` — parse array/object values a consumer sends itself, including discovered MCP object guards restored from JSON Schema, without the `stitchkit/tools` barrel |
package/llms/cli.txt CHANGED
@@ -247,6 +247,15 @@ string, the schema says what it should be:
247
247
  | `z.record(z.string(), z.unknown())` | `--data '{"code":"007"}'` or `--data.code=007` → `"007"` |
248
248
  | `.optional()` / `.default()` | not required |
249
249
 
250
+ An array option takes **one value per occurrence**, never a bare list after the flag.
251
+ Repeat it (`--tag a --tag b`) or assign the whole array (`--tag:='["a","b"]'`).
252
+ Without an explicit command `positionals` policy, combining any named array option
253
+ with bare positionals is refused before dispatch: schema-order inference could otherwise
254
+ assign the remaining array elements to unrelated fields. This includes short aliases,
255
+ dotted array leaves, whole-array JSON and tokens after `--`, regardless of token order.
256
+ Name the scalar fields too, or declare their exact positional destinations. An explicitly
257
+ declared trailing positional array is the variadic form described below.
258
+
250
259
  Use the inline `:=` form to assign a whole JSON value without scalar coercion:
251
260
 
252
261
  ```bash
@@ -522,7 +531,7 @@ Declared aliases render beside their canonical options, for example
522
531
 
523
532
  The argument table and `Application options:` show bounds from their JSON Schema,
524
533
  for example `<integer> [>=1, <=50]`, `<string> [length >=1, length <=12]`, and
525
- `<value…> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
534
+ `<value> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
526
535
  and `<=` include the endpoint; a zero limit is displayed too. Only limits the
527
536
  schema declares are shown: the safe-integer range every `z.int()` carries is the
528
537
  type, not a bound, so a bare integer prints `<integer>`, `.min(1)` prints `>=1` and
@@ -85,12 +85,12 @@ own, recorded as an ADR.
85
85
  | `stitchkit/geo` | server (Bun or Node) | evolving | managed GeoIP reader generations, last-known-good reload and the optional MaxMind adapter |
86
86
  | `stitchkit/oauth` | browser **and** server | evolving | provider-neutral Authorization Code + PKCE request and one-shot callback transaction mechanics |
87
87
  | `stitchkit/google` | server (Bun or Node) | evolving | optional Google code exchange and verified OIDC identity adapter |
88
- | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 56 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
88
+ | `stitchkit/observability` | server | stable<br>_redefined in 2 of the 57 minors since 0.56.2, most recently 0.92.0_ | request/tool event projections — `createObservability`, trace context, sanitisation |
89
89
  | `stitchkit/testing` | tests on Bun or Node | stable | in-process generated clients over a real Fetch handler, the managed-resource conformance kit and manual time for schedules and retries |
90
90
  | `stitchkit/declaration` | browser + build and deployment tooling (Bun or Node) | evolving | `ProjectDeclarationSchema` — the one machine-readable statement a repository makes about itself |
91
91
  | `stitchkit/react` | browser + server rendering | stable | `createCursorQuery`, `createCacheBridge`, QueryClient and `ApiError` retry policy |
92
92
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
93
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 56 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
93
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
94
94
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
95
95
  | `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 |
96
96
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -102,7 +102,7 @@ own, recorded as an ADR.
102
102
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
103
103
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
104
104
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
105
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 56 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
105
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
106
106
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
107
107
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
108
108
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -1,14 +1,45 @@
1
- # Upgrading 0.101.0 → 0.111.0 — stitchkit docs slice
1
+ # Upgrading 0.103.0 → 0.112.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.101.0 → 0.111.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.101.0 → 0.111.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.103.0 → 0.112.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.112.0
13
+
14
+ **Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
15
+
16
+ An array flag consumes one value. Automatic schema-order positionals cannot distinguish additional array elements from values intended for unrelated fields, so the combination is refused before any handler or stdin read. The rule is independent of token order, includes aliases, dotted array leaves and whole-array JSON, and `--` does not bypass it. See [ADR 0268](../decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md).
17
+
18
+ ```sh
19
+ # before: the last two words could populate unrelated fields
20
+ app resolve --references alpha.md beta.md gamma.md
21
+ # after: repeat the option or assign the whole array
22
+ app resolve --references alpha.md --references beta.md --references gamma.md
23
+ app resolve --references:='["alpha.md","beta.md","gamma.md"]'
24
+
25
+ # before: even an intended scalar positional has an implicit destination
26
+ app resolve project-one --references alpha.md
27
+ # after: name it
28
+ app resolve --projectId project-one --references alpha.md
29
+ ```
30
+
31
+ Applications that intend positional syntax declare its destinations on the available command:
32
+
33
+ ```ts
34
+ createCli({ ...config, positionals: { resolve: ['projectId'] } })
35
+ // app resolve project-one --references alpha.md
36
+
37
+ createCli({ ...config, positionals: { resolve: ['references'] } })
38
+ // app resolve alpha.md beta.md gamma.md
39
+ ```
40
+
41
+ A declared trailing array accepts all remaining positional elements. Giving that same field both a flag and positional elements remains an error. An empty policy accepts flags only. Policies still target exact available command names: a partial dynamic catalogue needs no policy for an unavailable command to enforce this admission rule.
42
+
12
43
  ## Released migration: 0.111.0
13
44
 
14
45
  **Who must act:** applications whose raw routes call `parseBody` on JSON larger than 1 MiB, and applications whose OAuth clients send `/register` or `/token` bodies larger than 64 KiB.
@@ -874,63 +905,3 @@ For archive inspection, replace ad hoc line parsing with `readDiagnosticJournal`
874
905
  from the same filesystem leaf. Handle its `frame | anomaly` stream explicitly;
875
906
  missing files, permissions and unsafe paths still throw. See the
876
907
  [journal guide](application-kernel.md#bounded-local-diagnostic-journal).
877
-
878
- ## Released migration: 0.102.0
879
-
880
- ### `view_file` receives an array, not an array encoded as text
881
-
882
- **Who must act:** callers sending `paths` as a JSON-encoded array string, or
883
- matching the former media-extension refusal for that input. Managed MCP,
884
- Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
885
- reports an input-validation error. Correct single paths and arrays need no change.
886
-
887
- ```ts
888
- // Before
889
- { paths: '["image.png"]' }
890
- // After
891
- { paths: ['image.png'] }
892
- // One file may also be a string
893
- { paths: 'image.png' }
894
- ```
895
-
896
- The same rule applies to an array element containing another encoded array.
897
- Do not change generic string-union coercion: path strings remain strings.
898
- A legitimate filename such as `[preview].PNG` is still accepted. Local
899
- unsupported-extension errors now include the caller's path and extension;
900
- match the error code rather than the former generic message.
901
-
902
- ## Released migration: 0.101.0
903
-
904
- ### `TelegramInitDataUser` is `TelegramUser`
905
-
906
- **Who must act:** code that names the type `TelegramInitDataUser` from
907
- `stitchkit/telegram`. The record is the same; its name now says it is any
908
- Telegram user, since `parseTelegramUser(ctx.from)` returns it for a Bot API user
909
- too.
910
-
911
- ```ts
912
- // Before
913
- import type { TelegramInitDataUser } from 'stitchkit/telegram'
914
- function ensureAccount(user: TelegramInitDataUser) {}
915
- // After
916
- import type { TelegramUser } from 'stitchkit/telegram'
917
- function ensureAccount(user: TelegramUser) {}
918
- ```
919
-
920
- ### `TELEGRAM_BOT_TOKEN_PATTERN` matches the secret half only
921
-
922
- **Who must act:** code that uses `TELEGRAM_BOT_TOKEN_PATTERN` to find or cut a
923
- whole token. It now matches what follows `<bot id>:`, so a masking replace keeps
924
- the bot's id — `123456:[redacted]`. Masking needs nothing any more: `redact` and
925
- every logger on it mask bot tokens by shape; remove the pattern from
926
- `sensitiveUrlPatterns`, and use `redactTelegramBotToken(text)` for a string of
927
- your own.
928
-
929
- ```ts
930
- // Before
931
- createJsonLogger({ sensitiveUrlPatterns: [TELEGRAM_BOT_TOKEN_PATTERN] })
932
- text.replace(new RegExp(TELEGRAM_BOT_TOKEN_PATTERN.source, 'g'), '[redacted]')
933
- // After
934
- createJsonLogger({})
935
- redactTelegramBotToken(text)
936
- ```
@@ -1,14 +1,75 @@
1
- # Upgrading 0.61.0 → 0.73.0 — stitchkit docs slice
1
+ # Upgrading 0.61.0 → 0.74.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.61.0 → 0.73.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.61.0 → 0.73.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.61.0 → 0.74.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.74.0
13
+
14
+ One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
15
+ planning the request, before anything was sent. A server refusal is unchanged.
16
+
17
+ ### If you match on the text of a client-side refusal
18
+
19
+ A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
20
+ invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
21
+ arrive as an `ApiError` in the same shape a server validation failure uses.
22
+
23
+ ```ts
24
+ // before
25
+ catch (e) {
26
+ if (/Missing path param/.test(e.message)) …
27
+ }
28
+
29
+ // after
30
+ catch (e) {
31
+ if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
32
+ }
33
+ // e.details.issues[0].path === 'id'
34
+ ```
35
+
36
+ `status` is what separates the two worlds, and it is not new — `0` has always meant *this never
37
+ reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
38
+
39
+ | | `code` | `status` |
40
+ |---|---|---|
41
+ | the client refused your arguments | `VALIDATION_ERROR` | `0` |
42
+ | the server refused your arguments | `VALIDATION_ERROR` | `400` |
43
+
44
+ `details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
45
+ and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
46
+ `stitchkit/server`.
47
+
48
+ ### If you are on `createHttpClient` and your call site relied on a synchronous throw
49
+
50
+ This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
51
+ **synchronously** on the Ky-backed client — before the call returned a promise — so
52
+ `api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
53
+ client rejected normally. They now reject on both.
54
+
55
+ ```ts
56
+ // before, on createHttpClient only
57
+ try {
58
+ api.upload({}) // threw here
59
+ } catch (e) { … }
60
+
61
+ // after, on both transports
62
+ await api.upload({}).catch(handler)
63
+ ```
64
+
65
+ A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
66
+ longer catches anything — which was already true on the other transport.
67
+
68
+ Not a migration, but worth knowing: a missing multipart file used to be reported as
69
+ `UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
70
+ where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
71
+ validation stays on the server.
72
+
12
73
  ## Released migration: 0.73.0
13
74
 
14
75
  Two breaking changes. Nothing you send to a server changed, and only one of these
@@ -1,14 +1,74 @@
1
- # Upgrading 0.74.0 → 0.100.0 — stitchkit docs slice
1
+ # Upgrading 0.75.0 → 0.102.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.74.0 → 0.100.0 (docs/guide/upgrading.md)
6
+ Contains: Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
7
7
 
8
8
  ==============================================================================
9
- # Guide: Upgrading, 0.74.0 → 0.100.0 (docs/guide/upgrading.md)
9
+ # Guide: Upgrading, 0.75.0 → 0.102.0 (docs/guide/upgrading.md)
10
10
  ==============================================================================
11
11
 
12
+ ## Released migration: 0.102.0
13
+
14
+ ### `view_file` receives an array, not an array encoded as text
15
+
16
+ **Who must act:** callers sending `paths` as a JSON-encoded array string, or
17
+ matching the former media-extension refusal for that input. Managed MCP,
18
+ Agent and CLI surfaces now reject it as `VALIDATION_ERROR` before IO; raw MCP
19
+ reports an input-validation error. Correct single paths and arrays need no change.
20
+
21
+ ```ts
22
+ // Before
23
+ { paths: '["image.png"]' }
24
+ // After
25
+ { paths: ['image.png'] }
26
+ // One file may also be a string
27
+ { paths: 'image.png' }
28
+ ```
29
+
30
+ The same rule applies to an array element containing another encoded array.
31
+ Do not change generic string-union coercion: path strings remain strings.
32
+ A legitimate filename such as `[preview].PNG` is still accepted. Local
33
+ unsupported-extension errors now include the caller's path and extension;
34
+ match the error code rather than the former generic message.
35
+
36
+ ## Released migration: 0.101.0
37
+
38
+ ### `TelegramInitDataUser` is `TelegramUser`
39
+
40
+ **Who must act:** code that names the type `TelegramInitDataUser` from
41
+ `stitchkit/telegram`. The record is the same; its name now says it is any
42
+ Telegram user, since `parseTelegramUser(ctx.from)` returns it for a Bot API user
43
+ too.
44
+
45
+ ```ts
46
+ // Before
47
+ import type { TelegramInitDataUser } from 'stitchkit/telegram'
48
+ function ensureAccount(user: TelegramInitDataUser) {}
49
+ // After
50
+ import type { TelegramUser } from 'stitchkit/telegram'
51
+ function ensureAccount(user: TelegramUser) {}
52
+ ```
53
+
54
+ ### `TELEGRAM_BOT_TOKEN_PATTERN` matches the secret half only
55
+
56
+ **Who must act:** code that uses `TELEGRAM_BOT_TOKEN_PATTERN` to find or cut a
57
+ whole token. It now matches what follows `<bot id>:`, so a masking replace keeps
58
+ the bot's id — `123456:[redacted]`. Masking needs nothing any more: `redact` and
59
+ every logger on it mask bot tokens by shape; remove the pattern from
60
+ `sensitiveUrlPatterns`, and use `redactTelegramBotToken(text)` for a string of
61
+ your own.
62
+
63
+ ```ts
64
+ // Before
65
+ createJsonLogger({ sensitiveUrlPatterns: [TELEGRAM_BOT_TOKEN_PATTERN] })
66
+ text.replace(new RegExp(TELEGRAM_BOT_TOKEN_PATTERN.source, 'g'), '[redacted]')
67
+ // After
68
+ createJsonLogger({})
69
+ redactTelegramBotToken(text)
70
+ ```
71
+
12
72
  ## Released migration: 0.100.0
13
73
 
14
74
  ### watch capacity and session/live/delivery adoption
@@ -1026,64 +1086,3 @@ schema.
1026
1086
  `stitchkit/live`, the watch hub, the keyspace and the trust fence are all
1027
1087
  additive. Adopt them when you want them; the guide is
1028
1088
  [Live data](./live.md).
1029
-
1030
- ## Released migration: 0.74.0
1031
-
1032
- One change, and it only reaches you if you catch a refusal the **client** raised — one it made while
1033
- planning the request, before anything was sent. A server refusal is unchanged.
1034
-
1035
- ### If you match on the text of a client-side refusal
1036
-
1037
- A missing path param, a missing scoped prefix key, a non-flat field in a `GET` input, a missing or
1038
- invalid multipart file: each used to arrive as a plain `Error` carrying only a sentence. They now
1039
- arrive as an `ApiError` in the same shape a server validation failure uses.
1040
-
1041
- ```ts
1042
- // before
1043
- catch (e) {
1044
- if (/Missing path param/.test(e.message)) …
1045
- }
1046
-
1047
- // after
1048
- catch (e) {
1049
- if (e.code === 'VALIDATION_ERROR' && e.status === 0) … // refused here, nothing was sent
1050
- }
1051
- // e.details.issues[0].path === 'id'
1052
- ```
1053
-
1054
- `status` is what separates the two worlds, and it is not new — `0` has always meant *this never
1055
- reached the server*, as `REQUEST_ABORTED` and `REQUEST_TIMEOUT` already used it:
1056
-
1057
- | | `code` | `status` |
1058
- |---|---|---|
1059
- | the client refused your arguments | `VALIDATION_ERROR` | `0` |
1060
- | the server refused your arguments | `VALIDATION_ERROR` | `400` |
1061
-
1062
- `details.issues` is the same `{ path, code, message }` array on both, so one rendering serves both —
1063
- and `zodIssues` / `ZodIssueSummary` are now importable from `stitchkit` itself, not only from
1064
- `stitchkit/server`.
1065
-
1066
- ### If you are on `createHttpClient` and your call site relied on a synchronous throw
1067
-
1068
- This is the sharp one, because it is invisible in a diff. Those refusals used to be thrown
1069
- **synchronously** on the Ky-backed client — before the call returned a promise — so
1070
- `api.upload({}).catch(handler)` never reached the handler, while the same mistake on the bare-fetch
1071
- client rejected normally. They now reject on both.
1072
-
1073
- ```ts
1074
- // before, on createHttpClient only
1075
- try {
1076
- api.upload({}) // threw here
1077
- } catch (e) { … }
1078
-
1079
- // after, on both transports
1080
- await api.upload({}).catch(handler)
1081
- ```
1082
-
1083
- A `try/catch` around an `await`ed call keeps working. A `try/catch` around an un-awaited call no
1084
- longer catches anything — which was already true on the other transport.
1085
-
1086
- Not a migration, but worth knowing: a missing multipart file used to be reported as
1087
- `UNKNOWN_ERROR`, the code that means *this client cannot tell you what happened*, on the one refusal
1088
- where it is certain nothing was sent. → ADR 0148 carries the reasoning, including why argument
1089
- validation stays on the server.
@@ -11,9 +11,9 @@ 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.101.0 → 0.111.0: `llms/upgrading-0.101.0-0.111.0.txt`
15
- - 0.74.0 → 0.100.0: `llms/upgrading-0.74.0-0.100.0.txt`
16
- - 0.61.0 → 0.73.0: `llms/upgrading-0.61.0-0.73.0.txt`
14
+ - 0.103.0 → 0.112.0: `llms/upgrading-0.103.0-0.112.0.txt`
15
+ - 0.75.0 → 0.102.0: `llms/upgrading-0.75.0-0.102.0.txt`
16
+ - 0.61.0 → 0.74.0: `llms/upgrading-0.61.0-0.74.0.txt`
17
17
  - 0.44.0 → 0.60.0: `llms/upgrading-0.44.0-0.60.0.txt`
18
18
  - 0.37.0 → 0.37.0: `llms/upgrading-0.37.0.txt`
19
19
 
package/llms-full.txt CHANGED
@@ -77,12 +77,12 @@ 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 56 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 57 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, the managed-resource conformance kit and manual time for schedules and retries |
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
84
  | `stitchkit/react/keyboard` | browser | evolving | which part of a screen gets a key — ordered layers, one Escape per level, list zones with real focus; see [keyboard guide](keyboard.md) |
85
- | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 56 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
85
+ | `stitchkit/agent-runtime` | server | evolving<br>_redefined in 23 of the 57 minors since 0.56.2, most recently 0.105.0_ | optional durable conversation/run loop, history, models, prompts, fencing and events |
86
86
  | `stitchkit/agent-runtime/sandbox` | server | evolving | optional Linux Bubblewrap sessions, durable workspaces and a host HTTP credential gateway; see [sandbox guide](sandbox.md) |
87
87
  | `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 |
88
88
  | `stitchkit/agent-runtime/harness` | server | evolving | resource-aware process-local facade over the canonical Agent runtime; supervision stays outside |
@@ -94,7 +94,7 @@ own, recorded as an ADR.
94
94
  | `stitchkit/agent-runtime/sqlite/bun` | server (Bun) | evolving | durable built-in SQLite store for the agent runtime |
95
95
  | `stitchkit/agent-runtime/sqlite/node` | server (Node ≥ 22.5) | evolving | durable built-in SQLite store for the agent runtime |
96
96
  | `stitchkit-tui` | terminal (Bun) | evolving | optional official OpenTUI host over a caller-composed headless runtime |
97
- | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 56 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
97
+ | `stitchkit/application` | browser + server | evolving<br>_redefined in 14 of the 57 minors since 0.56.2, most recently 0.110.0_ | managed resource graph, readiness, admission, schedules, subtree restart and bounded shutdown |
98
98
  | `stitchkit/application/grammy` | server | evolving | a grammY bot as application resources — configuration, then polling with updates admitted by batch — and the webhook adapter |
99
99
  | `stitchkit/application/opentelemetry` | server | evolving | maps application snapshots onto an injected OpenTelemetry `Meter` |
100
100
  | `stitchkit/application/schemas` | browser + server | evolving | the application's snapshot, health and shutdown schemas alone, without the kernel |
@@ -9941,6 +9941,15 @@ string, the schema says what it should be:
9941
9941
  | `z.record(z.string(), z.unknown())` | `--data '{"code":"007"}'` or `--data.code=007` → `"007"` |
9942
9942
  | `.optional()` / `.default()` | not required |
9943
9943
 
9944
+ An array option takes **one value per occurrence**, never a bare list after the flag.
9945
+ Repeat it (`--tag a --tag b`) or assign the whole array (`--tag:='["a","b"]'`).
9946
+ Without an explicit command `positionals` policy, combining any named array option
9947
+ with bare positionals is refused before dispatch: schema-order inference could otherwise
9948
+ assign the remaining array elements to unrelated fields. This includes short aliases,
9949
+ dotted array leaves, whole-array JSON and tokens after `--`, regardless of token order.
9950
+ Name the scalar fields too, or declare their exact positional destinations. An explicitly
9951
+ declared trailing positional array is the variadic form described below.
9952
+
9944
9953
  Use the inline `:=` form to assign a whole JSON value without scalar coercion:
9945
9954
 
9946
9955
  ```bash
@@ -10216,7 +10225,7 @@ Declared aliases render beside their canonical options, for example
10216
10225
 
10217
10226
  The argument table and `Application options:` show bounds from their JSON Schema,
10218
10227
  for example `<integer> [>=1, <=50]`, `<string> [length >=1, length <=12]`, and
10219
- `<value…> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
10228
+ `<value> [items >=2, items <=4]`. Numeric `>` and `<` are exclusive, while `>=`
10220
10229
  and `<=` include the endpoint; a zero limit is displayed too. Only limits the
10221
10230
  schema declares are shown: the safe-integer range every `z.int()` carries is the
10222
10231
  type, not a bound, so a bare integer prints `<integer>`, `.min(1)` prints `>=1` and
@@ -16193,6 +16202,37 @@ analytics policy belong to the application.
16193
16202
 
16194
16203
  # Upgrading stitchkit
16195
16204
 
16205
+ ## Released migration: 0.112.0
16206
+
16207
+ **Who must act:** scripts using an array option together with bare positional arguments without a declared `positionals` policy, including calls to `parseCliArgs`.
16208
+
16209
+ An array flag consumes one value. Automatic schema-order positionals cannot distinguish additional array elements from values intended for unrelated fields, so the combination is refused before any handler or stdin read. The rule is independent of token order, includes aliases, dotted array leaves and whole-array JSON, and `--` does not bypass it. See [ADR 0268](../decisions/0268-named-cli-arrays-require-explicit-positional-destinations.md).
16210
+
16211
+ ```sh
16212
+ # before: the last two words could populate unrelated fields
16213
+ app resolve --references alpha.md beta.md gamma.md
16214
+ # after: repeat the option or assign the whole array
16215
+ app resolve --references alpha.md --references beta.md --references gamma.md
16216
+ app resolve --references:='["alpha.md","beta.md","gamma.md"]'
16217
+
16218
+ # before: even an intended scalar positional has an implicit destination
16219
+ app resolve project-one --references alpha.md
16220
+ # after: name it
16221
+ app resolve --projectId project-one --references alpha.md
16222
+ ```
16223
+
16224
+ Applications that intend positional syntax declare its destinations on the available command:
16225
+
16226
+ ```ts
16227
+ createCli({ ...config, positionals: { resolve: ['projectId'] } })
16228
+ // app resolve project-one --references alpha.md
16229
+
16230
+ createCli({ ...config, positionals: { resolve: ['references'] } })
16231
+ // app resolve alpha.md beta.md gamma.md
16232
+ ```
16233
+
16234
+ A declared trailing array accepts all remaining positional elements. Giving that same field both a flag and positional elements remains an error. An empty policy accepts flags only. Policies still target exact available command names: a partial dynamic catalogue needs no policy for an unavailable command to enforce this admission rule.
16235
+
16196
16236
  ## Released migration: 0.111.0
16197
16237
 
16198
16238
  **Who must act:** applications whose raw routes call `parseBody` on JSON larger than 1 MiB, and applications whose OAuth clients send `/register` or `/token` bodies larger than 64 KiB.
@@ -23410,7 +23450,7 @@ SDK nor the `ai` peer.
23410
23450
  |--------|------|---------|
23411
23451
  | `createCli` | function | build and run a CLI from contracts — [guide](../guide/cli.md) |
23412
23452
  | `defineCliCommand` | function | define one Zod-typed CLI-only executable command with optional validated-result presentation/exit policy |
23413
- | `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical (advanced) |
23453
+ | `parseCliArgs` | function | argv → typed tool args against a schema; inline `--field:=JSON` assigns a whole JSON value, including null, while ordinary string flags remain lexical; named array options together with bare positionals require an explicit `positionals` policy (advanced) |
23414
23454
  | `routeCliArgv` | function | select the command out of argv without duplicating the global-option grammar (advanced) |
23415
23455
  | `extractCliGlobalOptions` | function | lift the application's own global options out of argv before routing (advanced) |
23416
23456
  | `coerceJsonArgs` | function | the second half of `parseCliArgs` — parse array/object values a consumer sends itself, including discovered MCP object guards restored from JSON Schema, without the `stitchkit/tools` barrel |
package/llms.txt CHANGED
@@ -18,7 +18,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
18
18
  - **stitchkit/tools/contract**: [llms/tools-contract.txt](llms/tools-contract.txt) 0.2 KB
19
19
  - **stitchkit/tools/invoker**: [llms/tools-invoker.txt](llms/tools-invoker.txt) 0.2 KB
20
20
  - **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.8 KB
21
- - **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 44.6 KB → [llms/cli.2.txt](llms/cli.2.txt) 21.3 KB
21
+ - **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 45.3 KB → [llms/cli.2.txt](llms/cli.2.txt) 21.4 KB
22
22
  - **stitchkit/cli/publish**: [llms/cli-publish.txt](llms/cli-publish.txt) 1.5 KB
23
23
  - **stitchkit/remote**: [llms/remote.txt](llms/remote.txt) 1.0 KB
24
24
  - **stitchkit/contract**: [llms/contract.txt](llms/contract.txt) 31.9 KB
@@ -64,9 +64,9 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
64
64
 
65
65
  ## Upgrading slices
66
66
  - **Upgrading — how to move across versions**: [llms/upgrading.txt](llms/upgrading.txt) 12.7 KB
67
- - **Upgrading 0.101.0 → 0.111.0**: [llms/upgrading-0.101.0-0.111.0.txt](llms/upgrading-0.101.0-0.111.0.txt) 46.9 KB
68
- - **Upgrading 0.74.0 → 0.100.0**: [llms/upgrading-0.74.0-0.100.0.txt](llms/upgrading-0.74.0-0.100.0.txt) 45.1 KB
69
- - **Upgrading 0.61.0 → 0.73.0**: [llms/upgrading-0.61.0-0.73.0.txt](llms/upgrading-0.61.0-0.73.0.txt) 41.2 KB
67
+ - **Upgrading 0.103.0 → 0.112.0**: [llms/upgrading-0.103.0-0.112.0.txt](llms/upgrading-0.103.0-0.112.0.txt) 46.6 KB
68
+ - **Upgrading 0.75.0 → 0.102.0**: [llms/upgrading-0.75.0-0.102.0.txt](llms/upgrading-0.75.0-0.102.0.txt) 44.8 KB
69
+ - **Upgrading 0.61.0 → 0.74.0**: [llms/upgrading-0.61.0-0.74.0.txt](llms/upgrading-0.61.0-0.74.0.txt) 43.5 KB
70
70
  - **Upgrading 0.44.0 → 0.60.0**: [llms/upgrading-0.44.0-0.60.0.txt](llms/upgrading-0.44.0-0.60.0.txt) 43.9 KB
71
71
  - **Upgrading 0.37.0 → 0.37.0**: [llms/upgrading-0.37.0.txt](llms/upgrading-0.37.0.txt) 6.2 KB
72
72
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stitchkit",
3
- "version": "0.111.3",
3
+ "version": "0.112.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",