stitchkit 0.111.2 → 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.
Files changed (72) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/application/diagnostic-journal-contract.d.ts +1 -1
  3. package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
  4. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -3
  5. package/dist/entrypoints/agent-runtime/harness.js +6 -6
  6. package/dist/entrypoints/agent-runtime/sandbox.js +3 -3
  7. package/dist/entrypoints/agent-runtime/sqlite/bun.js +5 -5
  8. package/dist/entrypoints/agent-runtime/sqlite/node.js +5 -5
  9. package/dist/entrypoints/agent-runtime/testing.js +5 -5
  10. package/dist/entrypoints/agent-runtime.js +12 -12
  11. package/dist/entrypoints/application/diagnostic-journal.js +1 -1
  12. package/dist/entrypoints/application/directory-inbox.js +3 -3
  13. package/dist/entrypoints/cli/publish.js +2 -2
  14. package/dist/entrypoints/cli.js +8 -8
  15. package/dist/entrypoints/files.js +2 -2
  16. package/dist/entrypoints/server.js +3 -3
  17. package/dist/entrypoints/telegram.js +1 -1
  18. package/dist/entrypoints/testing.js +1 -1
  19. package/dist/entrypoints/tools/connections.js +6 -4
  20. package/dist/entrypoints/tools/contract.js +2 -2
  21. package/dist/entrypoints/tools/invoker.js +6 -6
  22. package/dist/entrypoints/tools/mcp.js +8 -8
  23. package/dist/entrypoints/tools.js +11 -11
  24. package/dist/{index-mha6b4vk.js → index-02h0dfpr.js} +12 -5
  25. package/dist/{index-0z3kfphz.js → index-38gvr73z.js} +1 -1
  26. package/dist/{index-8jv0trhg.js → index-5as18gs2.js} +1 -1
  27. package/dist/{index-t2bsd0hm.js → index-5v5a9k2n.js} +92 -43
  28. package/dist/{index-c5374vpt.js → index-651xsm48.js} +4 -4
  29. package/dist/{index-w9mqgnz9.js → index-6b3pcq5z.js} +1 -1
  30. package/dist/{index-v2eyj2ws.js → index-bd7spznx.js} +20 -7
  31. package/dist/{index-7c046kxr.js → index-c7h371gr.js} +4 -4
  32. package/dist/{index-mnk5vgdr.js → index-d4cnhfdn.js} +1 -1
  33. package/dist/{index-t5sjh517.js → index-epmnrnth.js} +18 -1
  34. package/dist/{index-636mggad.js → index-ff3agzaf.js} +1 -1
  35. package/dist/{index-7c957abz.js → index-fh2ht88b.js} +1 -1
  36. package/dist/{index-q6crhe1n.js → index-h7accrrv.js} +19 -6
  37. package/dist/{index-0d8m0kee.js → index-hvg9hctd.js} +3 -3
  38. package/dist/{index-nx49x0tw.js → index-hy802jnr.js} +1 -1
  39. package/dist/{index-dd1z5kxb.js → index-jfk93gja.js} +3 -3
  40. package/dist/{index-cykxpxz5.js → index-jy9wq8tp.js} +1 -1
  41. package/dist/{index-ey15wx6j.js → index-n0adphfg.js} +1 -1
  42. package/dist/{index-ghwntn9n.js → index-vqdjym30.js} +2 -2
  43. package/dist/internal/exclusive-lock-owner.d.ts +53 -0
  44. package/dist/internal/exclusive-lock-owner.d.ts.map +1 -0
  45. package/dist/internal/exclusive-lock.d.ts +1 -28
  46. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  47. package/dist/internal/open-descriptors.d.ts +18 -0
  48. package/dist/internal/open-descriptors.d.ts.map +1 -0
  49. package/dist/internal/with-exclusive-lock.d.ts +2 -12
  50. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  51. package/dist/tools/cli/args.d.ts.map +1 -1
  52. package/dist/tools/cli/help.d.ts.map +1 -1
  53. package/dist/tools/connections/runtime.d.ts +1 -1
  54. package/dist/tools/connections/runtime.d.ts.map +1 -1
  55. package/dist/tools/execute-args.d.ts.map +1 -1
  56. package/dist/tools/schema/flatten-join.d.ts.map +1 -1
  57. package/dist/tools/schema/json-schema-origin.d.ts +17 -0
  58. package/dist/tools/schema/json-schema-origin.d.ts.map +1 -1
  59. package/llms/cli.2.txt +11 -1
  60. package/llms/cli.txt +10 -1
  61. package/llms/files.txt +1 -1
  62. package/llms/process.txt +10 -0
  63. package/llms/stitchkit.txt +3 -3
  64. package/llms/tools-connections.txt +1 -1
  65. package/llms/tools.txt +8 -3
  66. package/llms/{upgrading-0.101.0-0.111.0.txt → upgrading-0.103.0-0.112.0.txt} +34 -63
  67. package/llms/{upgrading-0.61.0-0.73.0.txt → upgrading-0.61.0-0.74.0.txt} +64 -3
  68. package/llms/{upgrading-0.74.0-0.100.0.txt → upgrading-0.75.0-0.102.0.txt} +63 -64
  69. package/llms/upgrading.txt +3 -3
  70. package/llms-full.txt +75 -10
  71. package/llms.txt +8 -8
  72. package/package.json +1 -1
@@ -0,0 +1,18 @@
1
+ /** The file a descriptor must refer to, as `stat` identifies it. */
2
+ export interface FileIdentity {
3
+ readonly ino: number;
4
+ readonly dev: number;
5
+ }
6
+ /**
7
+ * `true` when another descriptor of this process refers to the file at `path` — still the file
8
+ * `file` names — `false` when none does, and `null` when that cannot be told: the file is gone or
9
+ * replaced, or the listing is not proven complete. Unknown never proves that a holder is gone.
10
+ *
11
+ * The listing proves itself: the probe opens the file, and the answer counts only when the
12
+ * listing contains that fresh descriptor. A platform that lists a fixed few descriptors (a BSD
13
+ * `/dev/fd` without fdescfs lists 0–2) answers `null`, not a false "nobody holds it".
14
+ */
15
+ export declare function holdsOpenDescriptor(path: string, file: FileIdentity,
16
+ /** @internal A fixture listing; the real one is always this process's own. */
17
+ descriptorDirectory?: string): Promise<boolean | null>;
18
+ //# sourceMappingURL=open-descriptors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-descriptors.d.ts","sourceRoot":"","sources":["../../src/internal/open-descriptors.ts"],"names":[],"mappings":"AAkBA,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY;AAClB,8EAA8E;AAC9E,mBAAmB,SAAuB,GACzC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAkCzB"}
@@ -1,15 +1,5 @@
1
- /**
2
- * Run work under an exclusive lock between processes, waiting for it within a
3
- * deadline and a cancellation signal.
4
- *
5
- * The waiting is what the journal never needed and every other caller does: a
6
- * registry, a cursor or a mailbox is held for milliseconds, so a second process
7
- * should wait its turn rather than fail. It waits within a bound, stops the
8
- * moment its signal aborts — during the wait, not after it — and a refusal names
9
- * the resource and whoever holds it, so "timed out" is never the whole message.
10
- */
11
- import { type ExclusiveLockOwner } from './exclusive-lock.js';
12
- export type { ExclusiveLockOwner } from './exclusive-lock.js';
1
+ import type { ExclusiveLockOwner } from './exclusive-lock-owner.js';
2
+ export type { ExclusiveLockOwner } from './exclusive-lock-owner.js';
13
3
  /** Options of {@link withExclusiveLock}. */
14
4
  export interface ExclusiveLockOptions {
15
5
  /** What the lock guards, named in a refusal. Defaults to the lock path. */
@@ -1 +1 @@
1
- {"version":3,"file":"with-exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/with-exclusive-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gIAAgI;IAChI,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,+EAA+E;IAC/E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,qEAAqE;AACrE,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,WAAW;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IALnC,IAAI,SAAwB;IACrC,YACW,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,WAAW,EACnD,KAAK,EAAE,MAAM;IACtB,wFAAwF;IAC/E,MAAM,EAAE,kBAAkB,GAAG,IAAI,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAG9B;CACF;AA2BD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC5C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,CAAC,CAAC,CA2FZ"}
1
+ {"version":3,"file":"with-exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/with-exclusive-lock.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAA0B,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGzF,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gIAAgI;IAChI,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,+EAA+E;IAC/E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,qEAAqE;AACrE,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,WAAW;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IALnC,IAAI,SAAwB;IACrC,YACW,IAAI,EAAE,cAAc,GAAG,cAAc,GAAG,WAAW,EACnD,KAAK,EAAE,MAAM;IACtB,wFAAwF;IAC/E,MAAM,EAAE,kBAAkB,GAAG,IAAI,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAG9B;CACF;AA2BD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC5C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,CAAC,CAAC,CA2FZ"}
@@ -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"}
@@ -21,7 +21,7 @@ export declare function withConnectionToken<T>(params: {
21
21
  * Turn a discovered JSON Schema into a `ZodObject`, falling back to a permissive
22
22
  * object when the external schema is absent or not an object. This is the typed
23
23
  * boundary: the schema crosses from an untrusted foreign document into Zod here
24
- * and nowhere else.
24
+ * and nowhere else. Its unions are left to the remote that owns the schema.
25
25
  */
26
26
  export declare function zodObjectFromJsonSchema(schema: Record<string, unknown> | undefined): ZodObject;
27
27
  /** Normalise a tool name into the characters every provider accepts. */
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/tools/connections/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAK,MAAM,KAAK,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAI7D,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,CAAC,EAAE,cAAc,KACrB,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEtD,UAAU,cAAc;IACtB,QAAQ,IAAI,IAAI,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,MAAM,EAAE;IACN,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,EACD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9C,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,SAAS,CAQX;AAcD,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAElF,6EAA6E;AAC7E,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAIhF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EACzC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACjC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,qBAAqB,EAC/C,SAAS,EAAE,0BAA0B,GACpC,qBAAqB,EAAE,CAczB"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/tools/connections/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAK,MAAM,KAAK,CAAC;AACxC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAO7D,oEAAoE;AACpE,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,CAAC,EAAE,cAAc,KACrB,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAEtD,UAAU,cAAc;IACtB,QAAQ,IAAI,IAAI,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,MAAM,EAAE;IACN,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IACnC,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B,EACD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9C,OAAO,CAAC,CAAC,CAAC,CAUZ;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,SAAS,CASX;AAcD,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,sEAAsE;AACtE,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,0BAA0B,GAAG,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAElF,6EAA6E;AAC7E,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAIhF;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EACzC,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EACjC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,qBAAqB,EAC/C,SAAS,EAAE,0BAA0B,GACpC,qBAAqB,EAAE,CAczB"}
@@ -1 +1 @@
1
- {"version":3,"file":"execute-args.d.ts","sourceRoot":"","sources":["../../src/tools/execute-args.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAKrE,qEAAqE;AACrE,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAErD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,EACE,UAAkB,EAClB,WAAmB,GACpB,GAAE,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,aAAa,CAAM,GAC/D,uBAAuB,CAoEzB"}
1
+ {"version":3,"file":"execute-args.d.ts","sourceRoot":"","sources":["../../src/tools/execute-args.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAMrE,qEAAqE;AACrE,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAErD;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,EACE,UAAkB,EAClB,WAAmB,GACpB,GAAE,IAAI,CAAC,oBAAoB,EAAE,YAAY,GAAG,aAAa,CAAM,GAC/D,uBAAuB,CAuEzB"}
@@ -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;AAqKD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,eAAe,EAAE,EAC7B,aAAa,EAAE,MAAM,GACpB,sBAAsB,CAiCxB"}
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;AAyLD,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,eAAe,EAAE,EAC7B,aAAa,EAAE,MAAM,GACpB,sBAAsB,CAuCxB"}
@@ -5,6 +5,23 @@ import { z } from 'zod';
5
5
  * provenance and never guesses from a transform's public shape or metadata.
6
6
  */
7
7
  export declare function markJsonSchemaObjectGuards(schema: z.core.$ZodType): void;
8
+ /**
9
+ * Record that a schema restored from a foreign document leaves its unions to the remote.
10
+ *
11
+ * A foreign tool schema is the remote's presentation, and a presentation may join a
12
+ * discriminated union into one object whose shared field is an unlabelled `anyOf` (a stitchkit
13
+ * server with `flattenUnionInput` does, ADR 0205). Every value the remote accepts still passes
14
+ * such a union; which branch a value was meant for does not survive. Judged here, a wrong value
15
+ * can only be refused with every branch listed, while the remote, which holds the original
16
+ * schema, names the one field that is wrong.
17
+ */
18
+ export declare function markRemoteUnionVerdict(schema: z.ZodObject): void;
19
+ /**
20
+ * What a local parse refuses of a value the remote judges: everything but its unions. `null` when
21
+ * every refusal was a union's — the value goes to the remote, whose refusal is the answer.
22
+ * A schema that is not a restored foreign one keeps its own verdict whole.
23
+ */
24
+ export declare function localVerdict(schema: z.core.$ZodType, error: z.ZodError): z.ZodError | null;
8
25
  /**
9
26
  * Schemas that can guide coercion at a proven foreign object boundary.
10
27
  * Intersections need both branches: one carries the key guard, while another
@@ -1 +1 @@
1
- {"version":3,"file":"json-schema-origin.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/json-schema-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgCxB;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAiExE;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GACtB,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,CAsBxC"}
1
+ {"version":3,"file":"json-schema-origin.d.ts","sourceRoot":"","sources":["../../../src/tools/schema/json-schema-origin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgCxB;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAiExE;AAID;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAOhE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,GAAG,IAAI,CAK1F;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,GACtB,SAAS,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,SAAS,CAsBxC"}
package/llms/cli.2.txt CHANGED
@@ -149,6 +149,16 @@ One unconvertible schema does not take the connection down. The tool
149
149
  is skipped and **named** (`onSkippedTool`, or a stderr line by default), so a
150
150
  surface of two hundred tools is not lost to one.
151
151
 
152
+ **A discovered schema is checked locally, except for its unions.** The arguments are
153
+ coerced and parsed against the schema the server advertised, so a missing field or a
154
+ wrong scalar is refused before anything is sent. A union in that schema is not judged
155
+ here: a server's presentation may join a discriminated union into one object whose
156
+ shared field is an unlabelled `anyOf` (a stitchkit server with `flattenUnionInput`
157
+ does), and judged against that, a wrong value could only be refused with every branch
158
+ listed. The value goes to the server, which holds the original schema, and its refusal
159
+ names the one wrong field — `blocks.0.data.artifactId: expected string` rather than
160
+ `No union branch matched — branch 1 … and 6 more branches`.
161
+
152
162
  MCP connection limits follow the operation phase. `initialize`, the initialized
153
163
  notification, `tools/list` and legacy endpoint discovery use `limits.discovery`;
154
164
  `tools/call` uses `limits.call`. A mounted call's handshake still uses discovery
@@ -271,7 +281,7 @@ SDK nor the `ai` peer.
271
281
  |--------|------|---------|
272
282
  | `createCli` | function | build and run a CLI from contracts — [guide](../guide/cli.md) |
273
283
  | `defineCliCommand` | function | define one Zod-typed CLI-only executable command with optional validated-result presentation/exit policy |
274
- | `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) |
275
285
  | `routeCliArgv` | function | select the command out of argv without duplicating the global-option grammar (advanced) |
276
286
  | `extractCliGlobalOptions` | function | lift the application's own global options out of argv before routing (advanced) |
277
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
package/llms/files.txt CHANGED
@@ -32,7 +32,7 @@ available from `stitchkit/contract`.
32
32
  | `writeFileAtomic` / `writeFileAtomicSync` / `WriteFileAtomicOptions` | function / _type_ | replace a file atomically: a random staging name created exclusively (never through a planted link), the mode set on the descriptor before the file is visible (default `0o600`, not masked by the umask), `fsync`, rename; a failure leaves the target and no staging file. The asynchronous form keeps the event loop running. A process killed before publication leaves its staging file; sweeping it is the caller's job |
33
33
  | `isAtomicStagingName` | function | true for a staging file name of an atomic write of this library (`.stitchkit-<24 lowercase hex>.tmp`, also used by the managed writer and the chunk spool); the form is a stable contract, and changing it is a breaking change ([ADR 0242](../decisions/0242-atomic-staging-name-is-a-public-contract.md)) |
34
34
  | `sweepAtomicStaging` / `SweepAtomicStagingOptions` | function / _type_ | remove abandoned staging files from one `directory`: only regular files matching `isAtomicStagingName` and older than the required `olderThanMs`, never following a symlink or entering a subdirectory; stops on `signal`; returns the removed names, `[]` for a `directory` that does not exist |
35
- | `withExclusiveLock` / `ExclusiveLockOptions` / `ExclusiveLock` / `ExclusiveLockOwner` | function / _type_ | run work under an exclusive lock between processes — a file recording its owner (pid, host, machine identity, time and nullable kernel process identity); waits up to `timeoutMs` (default 10 s) and stops on `signal`; a dead owner on this machine is taken over, a live, slow or foreign one never is; the lock is published with its owner already recorded (temporary file plus hard link), so a stalled holder is never displaced; a legacy empty lock file is taken by age only when `ownerlessGraceMs` is a number (default `null`: never; an abandoned empty reclaim guard is taken after 5 000 ms unless a value is set); exact `mode` is independent of umask; shared readers need a common group and traversable directories |
35
+ | `withExclusiveLock` / `ExclusiveLockOptions` / `ExclusiveLock` / `ExclusiveLockOwner` | function / _type_ | run work under an exclusive lock between processes — a file recording its owner (pid, host, machine identity, time and nullable kernel process identity); waits up to `timeoutMs` (default 10 s) and stops on `signal`; a dead owner on this machine is taken over, a live, slow or foreign one never is; a lock recorded by this very process is held only while one of its descriptors is open on it, so the lock an earlier image of the same PID left (`bun --watch` restarts in place) is taken over at once; the lock is published with its owner already recorded (temporary file plus hard link), so a stalled holder is never displaced; a legacy empty lock file is taken by age only when `ownerlessGraceMs` is a number (default `null`: never; an abandoned empty reclaim guard is taken after 5 000 ms unless a value is set); exact `mode` is independent of umask; shared readers need a common group and traversable directories |
36
36
  | `ExclusiveLockError` | class | `LOCK_TIMEOUT` naming the resource and its holder, or `LOCK_ABORTED` with the signal's reason |
37
37
  | `createChunkSpool` | function | the server half of a chunked upload: parts on disk under `owner` + client-minted `uploadId`, each with a size+sha256 receipt; idempotent `open` and `put`, the first writer of a part wins across processes, `assemble` in order once every part is in, `sweep` of untouched uploads — [guide](../guide/client.md#chunked-uploads) |
38
38
  | `ChunkSpool` / `ChunkSpoolConfig` / `ChunkSpoolKey` / `ChunkSpoolOpen` / `ChunkSpoolPart` / `ChunkSpoolAssembly` | _type_ | the spool, its directory, part size, file limit, meta schema and age; an upload's key; its declaration; one part; the assembled parts with a concatenating `stream()` |
package/llms/process.txt CHANGED
@@ -480,6 +480,16 @@ unlink. Recovery depth is capped at 16; a deeper stale chain refuses recovery wi
480
480
  the bounded `LOCK_TIMEOUT`. Live owners, unknown process-lifetime evidence and unsafe records are never
481
481
  reclaimed. Concurrent writers cannot bypass a guard while a prior unlink is paused.
482
482
 
483
+ A record that names this very process is held only while a descriptor of this process is open
484
+ on the lock: the holder keeps the one it created the lock with until it releases. A process image
485
+ replaced in place — `execve`, which is how `bun --watch` restarts — keeps its PID and kernel start
486
+ time, so its record still matches, but not that descriptor, and the new image takes the lock over
487
+ at once instead of waiting for the PID to change. Worker threads and a second copy of the package
488
+ in the same process share the descriptor table, so a hold any of them takes is never displaced.
489
+ The check counts only when `/dev/fd` lists the descriptor it opens itself; a listing it cannot
490
+ prove complete means "unknown", which never reclaims. A replaced image of another process is
491
+ still judged alive.
492
+
483
493
  ## Libraries with a Zod-only runtime
484
494
 
485
495
  Public leaves keep optional peers out of their import closure. Installing `stitchkit` still
@@ -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 |
@@ -27,7 +27,7 @@ and approval path.
27
27
  | `ConnectionPhase` / `ConnectionOperation` / `ConnectionFailureContext` | _type_ | closed operation/phase vocabulary and measured read context for existing typed connection errors |
28
28
  | `ConnectionTimeoutError` / `ConnectionResponseTooLargeError` | class | bounded operation refusal, with phase, operation and finite observed bytes; safe tool projection retains the raw cause locally |
29
29
  | `defineOpenApiConnection` | function | declare one OpenAPI document (object, JSON text or JSON URL) as a tool surface |
30
- | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent` |
30
+ | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent`; a call's arguments are parsed against the discovered schema before sending, except its unions, which the server judges (ADR 0266) |
31
31
  | `ConnectionAuthorizationRequiredError` | class | typed reauthorization signal raised on `401` with credentials resolved again on the next call |
32
32
  | `ConnectionBudgetExceededError` | class | the mount would expose more foreign tools than its declared budget |
33
33
  | `ConnectionRequestError` | class | any non-`2xx` connection response other than the reauthorization signal |
package/llms/tools.txt CHANGED
@@ -770,12 +770,17 @@ A field that is a number in every variant is advertised as a number, not as a
770
770
  bare description. Scalar collisions keep every provable kind in a deterministic
771
771
  JSON Schema type array. If any alternative is an object or array, the property
772
772
  retains distinct structural alternatives in `anyOf`: object properties, typed
773
- array items, bounds and nullable values remain available to the model. The
773
+ array items, bounds and nullable values remain available to the model. Each
774
+ alternative is described by the discriminator values that select it
775
+ (`When type = image.`, or `When type = photo | video.` for a shape two values share),
776
+ so the model can pair a shape with its value; the order of the alternatives is
777
+ canonical, not the order of the variants. The
774
778
  containing discriminated union still becomes one object; flat mode does not
775
779
  promise to remove every nested union keyword. Only a branch whose kind is
776
780
  actually unknowable, such as a free-form schema or unresolved reference, leaves
777
- the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md)
778
- and [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md).
781
+ the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md),
782
+ [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md)
783
+ and [0267](../decisions/0267-a-flat-alternative-names-the-values-that-select-it.md).
779
784
 
780
785
  It is **deep** because the projection walks the generated JSON Schema document,
781
786
  including objects, arrays, tuples and schema-definition nodes. Structurally
@@ -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