stitchkit 0.111.1 → 0.111.3

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 (70) hide show
  1. package/CHANGELOG.md +17 -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/process.d.ts +1 -0
  17. package/dist/entrypoints/process.d.ts.map +1 -1
  18. package/dist/entrypoints/process.js +76 -1
  19. package/dist/entrypoints/server.js +3 -3
  20. package/dist/entrypoints/telegram.js +1 -1
  21. package/dist/entrypoints/testing.js +1 -1
  22. package/dist/entrypoints/tools/connections.js +6 -4
  23. package/dist/entrypoints/tools/contract.js +2 -2
  24. package/dist/entrypoints/tools/invoker.js +6 -6
  25. package/dist/entrypoints/tools/mcp.js +8 -8
  26. package/dist/entrypoints/tools.js +11 -11
  27. package/dist/{index-mha6b4vk.js → index-02h0dfpr.js} +12 -5
  28. package/dist/{index-0z3kfphz.js → index-38gvr73z.js} +1 -1
  29. package/dist/{index-8jv0trhg.js → index-5as18gs2.js} +1 -1
  30. package/dist/{index-t2bsd0hm.js → index-5v5a9k2n.js} +92 -43
  31. package/dist/{index-c5374vpt.js → index-651xsm48.js} +4 -4
  32. package/dist/{index-w9mqgnz9.js → index-6b3pcq5z.js} +1 -1
  33. package/dist/{index-7c046kxr.js → index-c7h371gr.js} +4 -4
  34. package/dist/{index-mnk5vgdr.js → index-d4cnhfdn.js} +1 -1
  35. package/dist/{index-t5sjh517.js → index-epmnrnth.js} +18 -1
  36. package/dist/{index-636mggad.js → index-ff3agzaf.js} +1 -1
  37. package/dist/{index-7c957abz.js → index-fh2ht88b.js} +1 -1
  38. package/dist/{index-q6crhe1n.js → index-h7accrrv.js} +19 -6
  39. package/dist/{index-0d8m0kee.js → index-hvg9hctd.js} +3 -3
  40. package/dist/{index-nx49x0tw.js → index-hy802jnr.js} +1 -1
  41. package/dist/{index-dd1z5kxb.js → index-jfk93gja.js} +3 -3
  42. package/dist/{index-v2eyj2ws.js → index-jprxv2an.js} +6 -6
  43. package/dist/{index-cykxpxz5.js → index-jy9wq8tp.js} +1 -1
  44. package/dist/{index-ey15wx6j.js → index-n0adphfg.js} +1 -1
  45. package/dist/{index-ghwntn9n.js → index-vqdjym30.js} +2 -2
  46. package/dist/internal/exclusive-lock-owner.d.ts +53 -0
  47. package/dist/internal/exclusive-lock-owner.d.ts.map +1 -0
  48. package/dist/internal/exclusive-lock.d.ts +1 -28
  49. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  50. package/dist/internal/open-descriptors.d.ts +18 -0
  51. package/dist/internal/open-descriptors.d.ts.map +1 -0
  52. package/dist/internal/with-exclusive-lock.d.ts +2 -12
  53. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  54. package/dist/process/stream.d.ts +27 -0
  55. package/dist/process/stream.d.ts.map +1 -0
  56. package/dist/tools/connections/runtime.d.ts +1 -1
  57. package/dist/tools/connections/runtime.d.ts.map +1 -1
  58. package/dist/tools/execute-args.d.ts.map +1 -1
  59. package/dist/tools/schema/flatten-join.d.ts.map +1 -1
  60. package/dist/tools/schema/json-schema-origin.d.ts +17 -0
  61. package/dist/tools/schema/json-schema-origin.d.ts.map +1 -1
  62. package/llms/cli.2.txt +10 -0
  63. package/llms/files.txt +1 -1
  64. package/llms/process.2.txt +32 -0
  65. package/llms/process.txt +36 -23
  66. package/llms/tools-connections.txt +1 -1
  67. package/llms/tools.txt +8 -3
  68. package/llms-full.txt +54 -5
  69. package/llms.txt +5 -5
  70. package/package.json +1 -1
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ import { type FileIdentity } from './open-descriptors.js';
3
+ import { type ProcessOwnerEvidence } from './process-instance.js';
4
+ /** Who holds a lock, as its file records it. */
5
+ declare const ExclusiveLockOwnerSchema: z.ZodObject<{
6
+ pid: z.ZodNumber;
7
+ host: z.ZodString;
8
+ acquiredAt: z.ZodString;
9
+ machine: z.ZodCatch<z.ZodOptional<z.ZodString>>;
10
+ process: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
11
+ platform: z.ZodEnum<{
12
+ darwin: "darwin";
13
+ linux: "linux";
14
+ }>;
15
+ bootId: z.ZodString;
16
+ namespace: z.ZodString;
17
+ startId: z.ZodString;
18
+ }, z.core.$strict>>>>;
19
+ }, z.core.$strip>;
20
+ export type ExclusiveLockOwner = z.infer<typeof ExclusiveLockOwnerSchema>;
21
+ /** Why a present lock was or was not taken. */
22
+ export interface ExclusiveLockDiagnosis {
23
+ readonly attribution: 'this-machine' | 'another-machine' | 'unattributable';
24
+ readonly liveness: 'alive' | 'gone' | 'not-probed';
25
+ /**
26
+ * The process evidence, plus `descriptor-closed`: the record names this very process, and no
27
+ * descriptor of this process is open on the lock — an earlier image of the PID left it.
28
+ */
29
+ readonly identity?: ProcessOwnerEvidence['identity'] | 'descriptor-closed';
30
+ readonly owner: ExclusiveLockOwner | null;
31
+ readonly cause?: unknown;
32
+ }
33
+ export declare function readOwner(text: string): {
34
+ owner: ExclusiveLockOwner | undefined;
35
+ ownerless: boolean;
36
+ };
37
+ /** A lock file as read: its recorded owner, if readable, and the file it was read from. */
38
+ export interface RecordedLock extends FileIdentity {
39
+ readonly path: string;
40
+ readonly owner: ExclusiveLockOwner | undefined;
41
+ }
42
+ /**
43
+ * Judge the recorded owner of a lock file that was read, or of none when it was not.
44
+ *
45
+ * A record that names this process with matching kernel identity is held only while a descriptor
46
+ * of this process is open on the file: a holder keeps the descriptor it created the lock with
47
+ * until it releases, in every version that records a process identity. A process image replaced
48
+ * in place keeps its PID and start time but not that descriptor, so the lock it left is gone —
49
+ * judged alive, it would stay held until the PID changed.
50
+ */
51
+ export declare function diagnose(lock: RecordedLock | undefined, declaredIdentity: string | undefined): Promise<ExclusiveLockDiagnosis>;
52
+ export {};
53
+ //# sourceMappingURL=exclusive-lock-owner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusive-lock-owner.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock-owner.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,oBAAoB,CAAC;AAG5B,gDAAgD;AAChD,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IACnD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,GAAG,mBAAmB,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IACvC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,OAAO,CAAC;CACpB,CAkBA;AAoBD,2FAA2F;AAC3F,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAChD;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAcjC"}
@@ -1,30 +1,4 @@
1
- import { z } from 'zod';
2
- import { type ProcessOwnerEvidence } from './process-instance.js';
3
- /** Who holds a lock, as its file records it. */
4
- declare const ExclusiveLockOwnerSchema: z.ZodObject<{
5
- pid: z.ZodNumber;
6
- host: z.ZodString;
7
- acquiredAt: z.ZodString;
8
- machine: z.ZodCatch<z.ZodOptional<z.ZodString>>;
9
- process: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
10
- platform: z.ZodEnum<{
11
- darwin: "darwin";
12
- linux: "linux";
13
- }>;
14
- bootId: z.ZodString;
15
- namespace: z.ZodString;
16
- startId: z.ZodString;
17
- }, z.core.$strict>>>>;
18
- }, z.core.$strip>;
19
- export type ExclusiveLockOwner = z.infer<typeof ExclusiveLockOwnerSchema>;
20
- /** Why a present lock was not taken. */
21
- export interface ExclusiveLockDiagnosis {
22
- readonly attribution: 'this-machine' | 'another-machine' | 'unattributable';
23
- readonly liveness: 'alive' | 'gone' | 'not-probed';
24
- readonly identity?: ProcessOwnerEvidence['identity'];
25
- readonly owner: ExclusiveLockOwner | null;
26
- readonly cause?: unknown;
27
- }
1
+ import { type ExclusiveLockDiagnosis, type ExclusiveLockOwner } from './exclusive-lock-owner.js';
28
2
  /** A lock this process holds. */
29
3
  export interface HeldExclusiveLock {
30
4
  readonly path: string;
@@ -64,5 +38,4 @@ export type ExclusiveLockAttempt = {
64
38
  export declare function attemptExclusiveLock(path: string, options: ExclusiveLockAttemptOptions, depth?: number): Promise<ExclusiveLockAttempt>;
65
39
  /** Read the owner a present lock records, for a refusal that has to name it. */
66
40
  export declare function readExclusiveLockOwner(path: string): Promise<ExclusiveLockOwner | null>;
67
- export {};
68
41
  //# sourceMappingURL=exclusive-lock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,oBAAoB,CAAC;AAG5B,gDAAgD;AAChD,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,iCAAiC;AACjC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,uFAAuF;IACvF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GACpC;IACE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;CAC7C,CAAC;AA8VN;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,EACpC,KAAK,SAAI,GACR,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,gFAAgF;AAChF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC"}
1
+ {"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"AA6BA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAGxB,MAAM,wBAAwB,CAAC;AAMhC,iCAAiC;AACjC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,uFAAuF;IACvF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GACpC;IACE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;CAC7C,CAAC;AAwSN;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,EACpC,KAAK,SAAI,GACR,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,gFAAgF;AAChF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC"}
@@ -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"}
@@ -0,0 +1,27 @@
1
+ import type { NativeCommandOptions, NativeCommandResult } from './contract.js';
2
+ /** Options the stream owns: its readers are the capture, the sink and the pipes. */
3
+ export type NativeCommandStreamOptions = Omit<NativeCommandOptions, 'capture' | 'onOutput' | 'stdio'>;
4
+ /** A started command whose output is read as it appears. */
5
+ export interface NativeCommandStream {
6
+ /** The leader's stdout; closes once the command finished and every byte was queued. */
7
+ readonly stdout: ReadableStream<Uint8Array>;
8
+ readonly stderr: ReadableStream<Uint8Array>;
9
+ /**
10
+ * Settles like `runNativeCommand` once the command ended and both streams were read to the end
11
+ * or cancelled: a stream nobody reads holds the child back, and with it this result. Its
12
+ * `stdout` and `stderr` are empty, the streams hold the bytes.
13
+ */
14
+ readonly result: Promise<NativeCommandResult>;
15
+ /** Stops the command with its stop policy and resolves once its resources are proven closed. */
16
+ stop(): Promise<void>;
17
+ }
18
+ /**
19
+ * Starts one command directly (no shell) like `runNativeCommand`, with the same group ownership,
20
+ * stop policy and bounds, and hands its output over as `ReadableStream`s instead of buffering it
21
+ * for the end. A slow reader slows the child (pipe backpressure); a cancelled stream drops what
22
+ * follows without stopping the command. When the command fails or is stopped, both streams error and
23
+ * the bytes still queued are dropped. A stream nobody reads holds the child back
24
+ * once it queued 1 MiB, so read large outputs concurrently or cancel the stream.
25
+ */
26
+ export declare function streamNativeCommand(input: NativeCommandStreamOptions): NativeCommandStream;
27
+ //# sourceMappingURL=stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../src/process/stream.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAE5E,oFAAoF;AACpF,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,oBAAoB,EACpB,SAAS,GAAG,UAAU,GAAG,OAAO,CACjC,CAAC;AAEF,4DAA4D;AAC5D,MAAM,WAAW,mBAAmB;IAClC,uFAAuF;IACvF,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,gGAAgG;IAChG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,0BAA0B,GAAG,mBAAmB,CA0B1F"}
@@ -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
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()` |
@@ -0,0 +1,32 @@
1
+ # stitchkit/process — stitchkit docs slice, part 2 of 2
2
+
3
+ > Generated from the `docs/` tree by `bun run gen:llms`. The index of all slices is
4
+ > `llms.txt` in this package.
5
+
6
+ Parts of this slice:
7
+ - `llms/process.txt`: Guide: Native IO (docs/guide/native-io.md)
8
+ - `llms/process.2.txt`: API reference: `stitchkit/process` (docs/api/reference.md)
9
+
10
+ ==============================================================================
11
+ # API reference: `stitchkit/process` (docs/api/reference.md)
12
+ ==============================================================================
13
+
14
+ ## `stitchkit/process`
15
+
16
+ Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/native-io.md).
17
+
18
+ | Export | Kind | Purpose |
19
+ |---|---|---|
20
+ | `runNativeCommand` | function | caller-lifetime streaming or explicitly bounded binary capture |
21
+ | `streamNativeCommand` | function | starts a command under the same group ownership, stop policy and bounds as `runNativeCommand` and returns `stdout` / `stderr` as `ReadableStream<Uint8Array>`, `result` and `stop()`; a slow reader slows the child, a cancelled stream drops its bytes, a failed command errors both streams |
22
+ | `NativeCommandStream` | type | what `streamNativeCommand` returns: `stdout`, `stderr`, `result` (its buffers are empty) and `stop()` |
23
+ | `NativeCommandStreamOptions` | type | `NativeCommandOptions` without `capture`, `onOutput` and `stdio`, which the streams own |
24
+ | `NativeCommandOptions` | type | executable/args, env policy, signal/deadline, bytes sink, finite cleanup limits, the `stop` policy and `descendants` (`'terminate-after-leader'`, the default: stop the group after the leader exits, or `'leave'`); `stdio` (`'pipe'`, or `'inherit'` for the caller's descriptors, refusing the pipe-only options) and `group` (`'own'`, or `'caller'`: joins the caller's process group, stops only the leader, refuses `descendants`, `ownerLoss` and a group stop); `ownerLoss: 'terminate'` (optional Linux/Darwin Bun/Node guard: kernel channel EOF after abrupt caller death KILLs its owned group, unsupported platforms refuse); `onLeaderStarted({ pid })` (once after the group leader exists; the package guard's PID under `ownerLoss`), `drainTimeoutMs` (bound on the pipes staying open after the leader exited, `COMMAND_CLEANUP`); an unknown key is refused by name, a removed one (`killGraceMs`) with its replacement |
25
+ | `NativeCommandStopPolicy` | type | how a cancelled command stops: `target` `'group'` (signal every member) or `'leader'` (signal only the leader; its exit ends the grace), `signal` (default `SIGTERM`), `graceMs` (at most one hour) before KILL to the group, and `killOn`, an `AbortSignal` that skips the grace; default `{ target: 'group', signal: 'SIGTERM', graceMs: 100 }` |
26
+ | `NativeCommandResult` | type | observed nullable exit code/signal, `descendantsStopped` (members left in the group after the leader exited were stopped) and captured stdout/stderr bytes |
27
+ | `NativeCommandError` | class | COMMAND_LIMIT with machine reason `deadline` or `output-budget`; COMMAND_UNAVAILABLE / COMMAND_CLEANUP have no limit reason; COMMAND_CLEANUP means the command's resources were not proven closed, either past `cleanupTimeoutMs` after a stop or past `drainTimeoutMs` after the leader exited, and `cause` holds that bound's failure. Preserves internal cause and existing constructor; caller-created limits without supplied reason remain unclassified |
28
+
29
+ | `NativeCommandSettlement` | type | `exit` (the leader ended on its own), `stopped` (the command was stopped and the leader's exit after the stop observed: the stop's `cause` with `exitCode`/`signal`) or `error` (no exit observed), including synchronous native launch failure; `onLeaderSettled` runs once before drain, bounded by cleanupTimeoutMs, with a cancellable settlement signal; schema/pre-abort refusal creates no settlement obligation |
30
+ | `observeProcessInstance` / `ProcessInstanceObservation` | function / type | Linux/Darwin lifetime observation; observed identity or unavailable with its original cause, never guessed absence |
31
+ | `ProcessInstanceSchema` / `ProcessInstance` | schema / type | platform, boot ID, namespace and process start identity from the shared native reader |
32
+ | `probeProcessOwner` / `ProcessOwnerEvidence` | function / type | compare lifetimes on one caller-established machine; matched, boot change, reused PID, gone, legacy or unavailable with cause |
package/llms/process.txt CHANGED
@@ -1,9 +1,12 @@
1
- # stitchkit/process — stitchkit docs slice
1
+ # stitchkit/process — stitchkit docs slice, part 1 of 2
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
+ > Continues in `llms/process.2.txt`.
5
6
 
6
- Contains: Guide: Native IO (docs/guide/native-io.md) · API reference: `stitchkit/process` (docs/api/reference.md)
7
+ Parts of this slice:
8
+ - `llms/process.txt`: Guide: Native IO (docs/guide/native-io.md)
9
+ - `llms/process.2.txt`: API reference: `stitchkit/process` (docs/api/reference.md)
7
10
 
8
11
  ==============================================================================
9
12
  # Guide: Native IO (docs/guide/native-io.md)
@@ -147,6 +150,27 @@ await runNativeCommand({
147
150
  })
148
151
  ```
149
152
 
153
+ To read output as it appears, use `streamNativeCommand`: the same owner, group ownership, `stop`
154
+ policy and bounds, with the output as `ReadableStream<Uint8Array>`.
155
+
156
+ ```ts
157
+ import { streamNativeCommand } from 'stitchkit/process'
158
+
159
+ const lifetime = new AbortController()
160
+ const command = streamNativeCommand({
161
+ executable: '/usr/bin/tail', args: ['-f', '/var/log/app.log'], signal: lifetime.signal,
162
+ })
163
+ void command.stderr.cancel() // not interested: dropped, the command keeps running
164
+ for await (const bytes of command.stdout) handle(bytes) // a slow reader slows the child
165
+ await command.result // settles like `runNativeCommand`; `stop()` ends the group and waits for it
166
+ ```
167
+
168
+ The streams own `capture`, `onOutput` and `stdio`; passing one is refused. Each stream queues up to 1 MiB, so
169
+ a small output can be read in any order, even after `result`; past that an unread stream fills its pipe
170
+ and holds the command, and its `result`, until the signal or `timeoutMs`, so read large outputs
171
+ concurrently or cancel the stream you ignore. Cancelling a stream drops its later bytes and leaves the command running. When the
172
+ command fails or is stopped, both streams error and the bytes still queued are dropped.
173
+
150
174
  A command needs a caller `signal` or a finite `timeoutMs` (1 to 2147483647 ms, the native timer
151
175
  range; a larger value is refused, never turned into 1 ms). Streaming runs for the caller's lifetime,
152
176
  with no hidden 60-second timeout or 1 MiB output limit. `capture` defaults to false; `true` requires
@@ -456,6 +480,16 @@ unlink. Recovery depth is capped at 16; a deeper stale chain refuses recovery wi
456
480
  the bounded `LOCK_TIMEOUT`. Live owners, unknown process-lifetime evidence and unsafe records are never
457
481
  reclaimed. Concurrent writers cannot bypass a guard while a prior unlink is paused.
458
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
+
459
493
  ## Libraries with a Zod-only runtime
460
494
 
461
495
  Public leaves keep optional peers out of their import closure. Installing `stitchkit` still
@@ -698,24 +732,3 @@ A sandbox admission slot is released once a direct command's pipes have closed a
698
732
  A `COMMAND_CLEANUP` outcome means the death of its group was not proven, so the slot stays
699
733
  occupied, `stop` keeps rejecting with the cleanup error, and the sandbox session is recreated to
700
734
  recover.
701
-
702
- ==============================================================================
703
- # API reference: `stitchkit/process` (docs/api/reference.md)
704
- ==============================================================================
705
-
706
- ## `stitchkit/process`
707
-
708
- Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/native-io.md).
709
-
710
- | Export | Kind | Purpose |
711
- |---|---|---|
712
- | `runNativeCommand` | function | caller-lifetime streaming or explicitly bounded binary capture |
713
- | `NativeCommandOptions` | type | executable/args, env policy, signal/deadline, bytes sink, finite cleanup limits, the `stop` policy and `descendants` (`'terminate-after-leader'`, the default: stop the group after the leader exits, or `'leave'`); `stdio` (`'pipe'`, or `'inherit'` for the caller's descriptors, refusing the pipe-only options) and `group` (`'own'`, or `'caller'`: joins the caller's process group, stops only the leader, refuses `descendants`, `ownerLoss` and a group stop); `ownerLoss: 'terminate'` (optional Linux/Darwin Bun/Node guard: kernel channel EOF after abrupt caller death KILLs its owned group, unsupported platforms refuse); `onLeaderStarted({ pid })` (once after the group leader exists; the package guard's PID under `ownerLoss`), `drainTimeoutMs` (bound on the pipes staying open after the leader exited, `COMMAND_CLEANUP`); an unknown key is refused by name, a removed one (`killGraceMs`) with its replacement |
714
- | `NativeCommandStopPolicy` | type | how a cancelled command stops: `target` `'group'` (signal every member) or `'leader'` (signal only the leader; its exit ends the grace), `signal` (default `SIGTERM`), `graceMs` (at most one hour) before KILL to the group, and `killOn`, an `AbortSignal` that skips the grace; default `{ target: 'group', signal: 'SIGTERM', graceMs: 100 }` |
715
- | `NativeCommandResult` | type | observed nullable exit code/signal, `descendantsStopped` (members left in the group after the leader exited were stopped) and captured stdout/stderr bytes |
716
- | `NativeCommandError` | class | COMMAND_LIMIT with machine reason `deadline` or `output-budget`; COMMAND_UNAVAILABLE / COMMAND_CLEANUP have no limit reason; COMMAND_CLEANUP means the command's resources were not proven closed, either past `cleanupTimeoutMs` after a stop or past `drainTimeoutMs` after the leader exited, and `cause` holds that bound's failure. Preserves internal cause and existing constructor; caller-created limits without supplied reason remain unclassified |
717
-
718
- | `NativeCommandSettlement` | type | `exit` (the leader ended on its own), `stopped` (the command was stopped and the leader's exit after the stop observed: the stop's `cause` with `exitCode`/`signal`) or `error` (no exit observed), including synchronous native launch failure; `onLeaderSettled` runs once before drain, bounded by cleanupTimeoutMs, with a cancellable settlement signal; schema/pre-abort refusal creates no settlement obligation |
719
- | `observeProcessInstance` / `ProcessInstanceObservation` | function / type | Linux/Darwin lifetime observation; observed identity or unavailable with its original cause, never guessed absence |
720
- | `ProcessInstanceSchema` / `ProcessInstance` | schema / type | platform, boot ID, namespace and process start identity from the shared native reader |
721
- | `probeProcessOwner` / `ProcessOwnerEvidence` | function / type | compare lifetimes on one caller-established machine; matched, boot change, reused PID, gone, legacy or unavailable with cause |
@@ -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
package/llms-full.txt CHANGED
@@ -4428,12 +4428,17 @@ A field that is a number in every variant is advertised as a number, not as a
4428
4428
  bare description. Scalar collisions keep every provable kind in a deterministic
4429
4429
  JSON Schema type array. If any alternative is an object or array, the property
4430
4430
  retains distinct structural alternatives in `anyOf`: object properties, typed
4431
- array items, bounds and nullable values remain available to the model. The
4431
+ array items, bounds and nullable values remain available to the model. Each
4432
+ alternative is described by the discriminator values that select it
4433
+ (`When type = image.`, or `When type = photo | video.` for a shape two values share),
4434
+ so the model can pair a shape with its value; the order of the alternatives is
4435
+ canonical, not the order of the variants. The
4432
4436
  containing discriminated union still becomes one object; flat mode does not
4433
4437
  promise to remove every nested union keyword. Only a branch whose kind is
4434
4438
  actually unknowable, such as a free-form schema or unresolved reference, leaves
4435
- the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md)
4436
- and [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md).
4439
+ the collision unconstrained. → ADRs [0044](../decisions/0044-a-collided-field-keeps-its-type.md),
4440
+ [0205](../decisions/0205-flat-tool-collisions-retain-structural-alternatives.md)
4441
+ and [0267](../decisions/0267-a-flat-alternative-names-the-values-that-select-it.md).
4437
4442
 
4438
4443
  It is **deep** because the projection walks the generated JSON Schema document,
4439
4444
  including objects, arrays, tuples and schema-definition nodes. Structurally
@@ -8586,6 +8591,27 @@ await runNativeCommand({
8586
8591
  })
8587
8592
  ```
8588
8593
 
8594
+ To read output as it appears, use `streamNativeCommand`: the same owner, group ownership, `stop`
8595
+ policy and bounds, with the output as `ReadableStream<Uint8Array>`.
8596
+
8597
+ ```ts
8598
+ import { streamNativeCommand } from 'stitchkit/process'
8599
+
8600
+ const lifetime = new AbortController()
8601
+ const command = streamNativeCommand({
8602
+ executable: '/usr/bin/tail', args: ['-f', '/var/log/app.log'], signal: lifetime.signal,
8603
+ })
8604
+ void command.stderr.cancel() // not interested: dropped, the command keeps running
8605
+ for await (const bytes of command.stdout) handle(bytes) // a slow reader slows the child
8606
+ await command.result // settles like `runNativeCommand`; `stop()` ends the group and waits for it
8607
+ ```
8608
+
8609
+ The streams own `capture`, `onOutput` and `stdio`; passing one is refused. Each stream queues up to 1 MiB, so
8610
+ a small output can be read in any order, even after `result`; past that an unread stream fills its pipe
8611
+ and holds the command, and its `result`, until the signal or `timeoutMs`, so read large outputs
8612
+ concurrently or cancel the stream you ignore. Cancelling a stream drops its later bytes and leaves the command running. When the
8613
+ command fails or is stopped, both streams error and the bytes still queued are dropped.
8614
+
8589
8615
  A command needs a caller `signal` or a finite `timeoutMs` (1 to 2147483647 ms, the native timer
8590
8616
  range; a larger value is refused, never turned into 1 ms). Streaming runs for the caller's lifetime,
8591
8617
  with no hidden 60-second timeout or 1 MiB output limit. `capture` defaults to false; `true` requires
@@ -8895,6 +8921,16 @@ unlink. Recovery depth is capped at 16; a deeper stale chain refuses recovery wi
8895
8921
  the bounded `LOCK_TIMEOUT`. Live owners, unknown process-lifetime evidence and unsafe records are never
8896
8922
  reclaimed. Concurrent writers cannot bypass a guard while a prior unlink is paused.
8897
8923
 
8924
+ A record that names this very process is held only while a descriptor of this process is open
8925
+ on the lock: the holder keeps the one it created the lock with until it releases. A process image
8926
+ replaced in place — `execve`, which is how `bun --watch` restarts — keeps its PID and kernel start
8927
+ time, so its record still matches, but not that descriptor, and the new image takes the lock over
8928
+ at once instead of waiting for the PID to change. Worker threads and a second copy of the package
8929
+ in the same process share the descriptor table, so a hold any of them takes is never displaced.
8930
+ The check counts only when `/dev/fd` lists the descriptor it opens itself; a listing it cannot
8931
+ prove complete means "unknown", which never reclaims. A replaced image of another process is
8932
+ still judged alive.
8933
+
8898
8934
  ## Libraries with a Zod-only runtime
8899
8935
 
8900
8936
  Public leaves keep optional peers out of their import closure. Installing `stitchkit` still
@@ -10750,6 +10786,16 @@ One unconvertible schema does not take the connection down. The tool
10750
10786
  is skipped and **named** (`onSkippedTool`, or a stderr line by default), so a
10751
10787
  surface of two hundred tools is not lost to one.
10752
10788
 
10789
+ **A discovered schema is checked locally, except for its unions.** The arguments are
10790
+ coerced and parsed against the schema the server advertised, so a missing field or a
10791
+ wrong scalar is refused before anything is sent. A union in that schema is not judged
10792
+ here: a server's presentation may join a discriminated union into one object whose
10793
+ shared field is an unlabelled `anyOf` (a stitchkit server with `flattenUnionInput`
10794
+ does), and judged against that, a wrong value could only be refused with every branch
10795
+ listed. The value goes to the server, which holds the original schema, and its refusal
10796
+ names the one wrong field — `blocks.0.data.artifactId: expected string` rather than
10797
+ `No union branch matched — branch 1 … and 6 more branches`.
10798
+
10753
10799
  MCP connection limits follow the operation phase. `initialize`, the initialized
10754
10800
  notification, `tools/list` and legacy endpoint discovery use `limits.discovery`;
10755
10801
  `tools/call` uses `limits.call`. A mounted call's handshake still uses discovery
@@ -22883,7 +22929,7 @@ and approval path.
22883
22929
  | `ConnectionPhase` / `ConnectionOperation` / `ConnectionFailureContext` | _type_ | closed operation/phase vocabulary and measured read context for existing typed connection errors |
22884
22930
  | `ConnectionTimeoutError` / `ConnectionResponseTooLargeError` | class | bounded operation refusal, with phase, operation and finite observed bytes; safe tool projection retains the raw cause locally |
22885
22931
  | `defineOpenApiConnection` | function | declare one OpenAPI document (object, JSON text or JSON URL) as a tool surface |
22886
- | `mountConnections` | function | discover every connection and return readonly `RuntimeToolDefinition`s for `mountAgent` |
22932
+ | `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) |
22887
22933
  | `ConnectionAuthorizationRequiredError` | class | typed reauthorization signal raised on `401` with credentials resolved again on the next call |
22888
22934
  | `ConnectionBudgetExceededError` | class | the mount would expose more foreign tools than its declared budget |
22889
22935
  | `ConnectionRequestError` | class | any non-`2xx` connection response other than the reauthorization signal |
@@ -22992,7 +23038,7 @@ available from `stitchkit/contract`.
22992
23038
  | `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 |
22993
23039
  | `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)) |
22994
23040
  | `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 |
22995
- | `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 |
23041
+ | `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 |
22996
23042
  | `ExclusiveLockError` | class | `LOCK_TIMEOUT` naming the resource and its holder, or `LOCK_ABORTED` with the signal's reason |
22997
23043
  | `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) |
22998
23044
  | `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()` |
@@ -23566,6 +23612,9 @@ Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/nativ
23566
23612
  | Export | Kind | Purpose |
23567
23613
  |---|---|---|
23568
23614
  | `runNativeCommand` | function | caller-lifetime streaming or explicitly bounded binary capture |
23615
+ | `streamNativeCommand` | function | starts a command under the same group ownership, stop policy and bounds as `runNativeCommand` and returns `stdout` / `stderr` as `ReadableStream<Uint8Array>`, `result` and `stop()`; a slow reader slows the child, a cancelled stream drops its bytes, a failed command errors both streams |
23616
+ | `NativeCommandStream` | type | what `streamNativeCommand` returns: `stdout`, `stderr`, `result` (its buffers are empty) and `stop()` |
23617
+ | `NativeCommandStreamOptions` | type | `NativeCommandOptions` without `capture`, `onOutput` and `stdio`, which the streams own |
23569
23618
  | `NativeCommandOptions` | type | executable/args, env policy, signal/deadline, bytes sink, finite cleanup limits, the `stop` policy and `descendants` (`'terminate-after-leader'`, the default: stop the group after the leader exits, or `'leave'`); `stdio` (`'pipe'`, or `'inherit'` for the caller's descriptors, refusing the pipe-only options) and `group` (`'own'`, or `'caller'`: joins the caller's process group, stops only the leader, refuses `descendants`, `ownerLoss` and a group stop); `ownerLoss: 'terminate'` (optional Linux/Darwin Bun/Node guard: kernel channel EOF after abrupt caller death KILLs its owned group, unsupported platforms refuse); `onLeaderStarted({ pid })` (once after the group leader exists; the package guard's PID under `ownerLoss`), `drainTimeoutMs` (bound on the pipes staying open after the leader exited, `COMMAND_CLEANUP`); an unknown key is refused by name, a removed one (`killGraceMs`) with its replacement |
23570
23619
  | `NativeCommandStopPolicy` | type | how a cancelled command stops: `target` `'group'` (signal every member) or `'leader'` (signal only the leader; its exit ends the grace), `signal` (default `SIGTERM`), `graceMs` (at most one hour) before KILL to the group, and `killOn`, an `AbortSignal` that skips the grace; default `{ target: 'group', signal: 'SIGTERM', graceMs: 100 }` |
23571
23620
  | `NativeCommandResult` | type | observed nullable exit code/signal, `descendantsStopped` (members left in the group after the leader exited were stopped) and captured stdout/stderr bytes |
package/llms.txt CHANGED
@@ -13,12 +13,12 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
13
13
  - **stitchkit/live**: [llms/live.txt](llms/live.txt) 21.2 KB
14
14
  - **stitchkit/react**: [llms/react.txt](llms/react.txt) 8.6 KB
15
15
  - **stitchkit/react/keyboard**: [llms/react-keyboard.txt](llms/react-keyboard.txt) 9.2 KB
16
- - **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 46.4 KB → [llms/tools.2.txt](llms/tools.2.txt) 30.4 KB → [llms/tools.3.txt](llms/tools.3.txt) 26.3 KB
16
+ - **stitchkit/tools**: [llms/tools.txt](llms/tools.txt) 46.7 KB → [llms/tools.2.txt](llms/tools.2.txt) 30.4 KB → [llms/tools.3.txt](llms/tools.3.txt) 26.3 KB
17
17
  - **stitchkit/tools/mcp**: [llms/tools-mcp.txt](llms/tools-mcp.txt) 1.8 KB
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
- - **stitchkit/tools/connections**: [llms/tools-connections.txt](llms/tools-connections.txt) 3.7 KB
21
- - **stitchkit/cli**: [llms/cli.txt](llms/cli.txt) 44.6 KB → [llms/cli.2.txt](llms/cli.2.txt) 20.6 KB
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
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
@@ -41,7 +41,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
41
41
  - **stitchkit/application/schemas**: [llms/application-schemas.txt](llms/application-schemas.txt) 1.8 KB
42
42
  - **stitchkit/testing**: [llms/testing.txt](llms/testing.txt) 33.6 KB
43
43
  - **stitchkit/agent-runtime/sandbox**: [llms/agent-runtime-sandbox.txt](llms/agent-runtime-sandbox.txt) 8.3 KB
44
- - **stitchkit/files**: [llms/files.txt](llms/files.txt) 5.5 KB
44
+ - **stitchkit/files**: [llms/files.txt](llms/files.txt) 5.7 KB
45
45
  - **stitchkit/telegram**: [llms/telegram.txt](llms/telegram.txt) 36.6 KB
46
46
  - **stitchkit/telegram/html**: [llms/telegram-html.txt](llms/telegram-html.txt) 2.7 KB
47
47
  - **stitchkit/telegram/screens**: [llms/telegram-screens.txt](llms/telegram-screens.txt) 21.2 KB
@@ -56,7 +56,7 @@ Load the slice for each entrypoint your code imports — `import … from 'stitc
56
56
  - **stitchkit/node**: [llms/node.txt](llms/node.txt) 3.1 KB
57
57
  - **stitchkit/agent-runtime/react**: [llms/agent-runtime-react.txt](llms/agent-runtime-react.txt) 1.0 KB
58
58
  - **stitchkit/agent-runtime/realtime**: [llms/agent-runtime-realtime.txt](llms/agent-runtime-realtime.txt) 2.6 KB
59
- - **stitchkit/process**: [llms/process.txt](llms/process.txt) 45.8 KB
59
+ - **stitchkit/process**: [llms/process.txt](llms/process.txt) 44.4 KB → [llms/process.2.txt](llms/process.2.txt) 4.3 KB
60
60
  - **stitchkit/process/owner-loss**: [llms/process-owner-loss.txt](llms/process-owner-loss.txt) 0.9 KB
61
61
  - **stitchkit/files/packaging**: [llms/files-packaging.txt](llms/files-packaging.txt) 3.5 KB
62
62
  - **stitchkit/http**: [llms/http.txt](llms/http.txt) 0.9 KB