stitchkit 0.108.1 → 0.108.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 (44) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -2
  3. package/dist/entrypoints/agent-runtime/sandbox.js +5 -3
  4. package/dist/entrypoints/cli.js +1 -1
  5. package/dist/entrypoints/contract.js +1 -1
  6. package/dist/entrypoints/index.js +1 -1
  7. package/dist/entrypoints/node.js +1 -1
  8. package/dist/entrypoints/process/owner-loss.d.ts +3 -0
  9. package/dist/entrypoints/process/owner-loss.d.ts.map +1 -0
  10. package/dist/entrypoints/process/owner-loss.js +6 -0
  11. package/dist/entrypoints/process.js +4 -2
  12. package/dist/entrypoints/server.js +1 -1
  13. package/dist/entrypoints/tools.js +1 -1
  14. package/dist/{index-epg514ys.js → index-dasy32c8.js} +76 -328
  15. package/dist/index-dj1aycxw.js +639 -0
  16. package/dist/{index-4qh90tyw.js → index-fgq4w9bf.js} +23 -1
  17. package/dist/{index-e35py42g.js → index-tycmtxky.js} +6 -4
  18. package/dist/process/bun-child.d.ts +10 -0
  19. package/dist/process/bun-child.d.ts.map +1 -1
  20. package/dist/process/command-owner.d.ts.map +1 -1
  21. package/dist/process/contract.d.ts +5 -0
  22. package/dist/process/contract.d.ts.map +1 -1
  23. package/dist/process/launch.d.ts +1 -1
  24. package/dist/process/launch.d.ts.map +1 -1
  25. package/dist/process/owned-child.d.ts +3 -0
  26. package/dist/process/owned-child.d.ts.map +1 -1
  27. package/dist/process/owner-loss-control.d.ts +15 -0
  28. package/dist/process/owner-loss-control.d.ts.map +1 -0
  29. package/dist/process/owner-loss-guard.d.ts +12 -0
  30. package/dist/process/owner-loss-guard.d.ts.map +1 -0
  31. package/dist/process/owner-loss-protocol.d.ts +10 -0
  32. package/dist/process/owner-loss-protocol.d.ts.map +1 -0
  33. package/dist/process/owner-loss-socket.d.ts +4 -0
  34. package/dist/process/owner-loss-socket.d.ts.map +1 -0
  35. package/dist/tools/cli/args-fields.d.ts.map +1 -1
  36. package/llms/cli.2.txt +107 -0
  37. package/llms/cli.txt +8 -107
  38. package/llms/process-owner-loss.txt +18 -0
  39. package/llms/process.txt +43 -10
  40. package/llms/stitchkit.txt +2 -1
  41. package/llms-full.txt +61 -11
  42. package/llms.txt +4 -3
  43. package/package.json +5 -1
  44. /package/dist/{index-q4hjtyye.js → index-qd8x73e8.js} +0 -0
@@ -1,5 +1,6 @@
1
1
  import { EventEmitter } from 'node:events';
2
2
  import { Readable, Writable } from 'node:stream';
3
+ import { type OwnerLossGuardInvocation } from './owner-loss-protocol.js';
3
4
  /** What a spawned command exposes to its owner: the subset of a Node child the package uses. */
4
5
  export interface OwnedChild extends EventEmitter {
5
6
  readonly pid?: number;
@@ -23,6 +24,7 @@ interface BunSpawnInput {
23
24
  cwd?: string;
24
25
  env?: NodeJS.ProcessEnv;
25
26
  group: boolean;
27
+ ownerLoss?: OwnerLossGuardInvocation;
26
28
  }
27
29
  /**
28
30
  * Whether the host is Bun. Bun's `node:child_process` can lose a child's `exit` event under
@@ -34,5 +36,13 @@ export declare function hostIsBun(): boolean;
34
36
  export declare function spawnBunChild(input: BunSpawnInput): OwnedChild;
35
37
  /** `spawnInheritedCommand` for Bun: a command with the caller's stdio. */
36
38
  export declare function spawnBunInheritedChild(input: BunSpawnInput): ObservableChild;
39
+ export interface BunGuardTarget {
40
+ readonly pid: number;
41
+ readonly exitCode: number | null;
42
+ readonly signalCode: string | number | null;
43
+ readonly exited: Promise<unknown>;
44
+ }
45
+ /** Bun-native target observation for the standalone owner-loss guard. */
46
+ export declare function spawnBunGuardTarget(executable: string, args: readonly string[]): BunGuardTarget;
37
47
  export {};
38
48
  //# sourceMappingURL=bun-child.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bun-child.d.ts","sourceRoot":"","sources":["../../src/process/bun-child.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,gGAAgG;AAChG,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAoKD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CA4B9D;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CAmB5E"}
1
+ {"version":3,"file":"bun-child.d.ts","sourceRoot":"","sources":["../../src/process/bun-child.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjD,OAAO,EAAE,KAAK,wBAAwB,EAAyB,MAAM,uBAAuB,CAAC;AAG7F,gGAAgG;AAChG,MAAM,WAAW,UAAW,SAAQ,YAAY;IAC9C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;IAC1B,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAgB,SAAQ,YAAY;IACnD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;CACvC;AAED,UAAU,aAAa;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,wBAAwB,CAAC;CACtC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAqKD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,GAAG,UAAU,CAgD9D;AAED,0EAA0E;AAC1E,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CAsC5E;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CACnC;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,cAAc,CAMhB"}
@@ -1 +1 @@
1
- {"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAEL,KAAK,oBAAoB,EAI1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,UAAU,CAAC;AAOlB,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,yBAAyB;;;;;;;;;;EAkKnC"}
1
+ {"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAEL,KAAK,oBAAoB,EAI1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,UAAU,CAAC;AAQlB,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,EACrC,MAAM,CAAC,EAAE,yBAAyB;;;;;;;;;;EA8KnC"}
@@ -77,6 +77,9 @@ export declare const NativeCommandOptionsSchema: z.ZodPipe<z.ZodObject<{
77
77
  caller: "caller";
78
78
  own: "own";
79
79
  }>>;
80
+ ownerLoss: z.ZodOptional<z.ZodEnum<{
81
+ terminate: "terminate";
82
+ }>>;
80
83
  stdio: z.ZodDefault<z.ZodEnum<{
81
84
  inherit: "inherit";
82
85
  pipe: "pipe";
@@ -121,6 +124,7 @@ export declare const NativeCommandOptionsSchema: z.ZodPipe<z.ZodObject<{
121
124
  }) => void) | undefined;
122
125
  drainTimeoutMs?: number | undefined;
123
126
  group: "caller" | "own";
127
+ ownerLoss?: "terminate" | undefined;
124
128
  stdio: "inherit" | "pipe";
125
129
  cleanupTimeoutMs: number;
126
130
  stop: {
@@ -149,6 +153,7 @@ export declare const NativeCommandOptionsSchema: z.ZodPipe<z.ZodObject<{
149
153
  }) => void) | undefined;
150
154
  drainTimeoutMs?: number | undefined;
151
155
  group: "caller" | "own";
156
+ ownerLoss?: "terminate" | undefined;
152
157
  stdio: "inherit" | "pipe";
153
158
  stop?: {
154
159
  target: "group" | "leader";
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/process/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,6BAA6B;;;;;;;;;;;;2BAajC,CAAC;AACH;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,gGAAgG;AAChG,eAAO,MAAM,yBAAyB,UAAY,CAAC;AAEnD,QAAA,MAAM,6BAA6B;;;;;;;;;;;;;;;kBAOjC,CAAC;AACH;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAiC3F,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;gDAqBpB,UAAU,WACR,QAAQ,GAAG,QAAQ,UACpB,WAAW,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uDAKX,uBAAuB,UAAU,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uDAMrE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmF3C,CAAC;AACN;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,0BAA0B,CAAC,CAAC;AACrF,QAAA,MAAM,yBAAyB;;;;;;iBAU7B,CAAC;AACH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,QAAA,MAAM,8BAA8B;;;EAAwC,CAAC;AAE7E;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAezB,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB;IAdnF,2GAA2G;IAC3G,SAAgB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,GAAG,SAAS,CAAC;IAEnF,YACE,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAA;KAAE,EACpF;IACF,YACE,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB,EACjE,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,KAAK,CAAA;KAAE,EAC3C;CAgBH"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/process/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,QAAA,MAAM,6BAA6B;;;;;;;;;;;;2BAajC,CAAC;AACH;;;;;;GAMG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF;;GAEG;AACH,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,gGAAgG;AAChG,eAAO,MAAM,yBAAyB,UAAY,CAAC;AAEnD,QAAA,MAAM,6BAA6B;;;;;;;;;;;;;;;kBAOjC,CAAC;AACH;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AACpF,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAiC3F,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;gDAqBpB,UAAU,WACR,QAAQ,GAAG,QAAQ,UACpB,WAAW,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uDAKX,uBAAuB,UAAU,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;uDAMrE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4F3C,CAAC;AACN;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC9E,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,0BAA0B,CAAC,CAAC;AACrF,QAAA,MAAM,yBAAyB;;;;;;iBAU7B,CAAC;AACH;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,QAAA,MAAM,8BAA8B;;;EAAwC,CAAC;AAE7E;;;;;;GAMG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAezB,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB;IAdnF,2GAA2G;IAC3G,SAAgB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,GAAG,SAAS,CAAC;IAEnF,YACE,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAA;KAAE,EACpF;IACF,YACE,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB,EACjE,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,YAAY,GAAG;QAAE,MAAM,CAAC,EAAE,KAAK,CAAA;KAAE,EAC3C;CAgBH"}
@@ -56,7 +56,7 @@ export declare function launchNativeCommand({ options, driver, onSpawn, onFailur
56
56
  }): {
57
57
  stdout: AsyncIterable<Uint8Array<ArrayBufferLike>>;
58
58
  stderr: AsyncIterable<Uint8Array<ArrayBufferLike>>;
59
- start(): void;
59
+ start(): Promise<number | undefined>;
60
60
  child: NativeCommandLaunchedProcess;
61
61
  leader: Promise<{
62
62
  kind: "exit";
@@ -1 +1 @@
1
- {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/process/launch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/process/launch.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { type OwnedChild } from './bun-child.js';
2
2
  import type { NativeCommandLaunchedProcess } from './launch.js';
3
+ import { type OwnerLossGuardInvocation } from './owner-loss-protocol.js';
3
4
  /** Only this native spawn can establish group ownership; structural PIDs cannot. */
4
5
  export declare function spawnOwnedCommand(input: {
5
6
  executable: string;
@@ -7,6 +8,7 @@ export declare function spawnOwnedCommand(input: {
7
8
  cwd?: string;
8
9
  env?: NodeJS.ProcessEnv;
9
10
  group: boolean;
11
+ ownerLoss?: OwnerLossGuardInvocation;
10
12
  }): OwnedChild;
11
13
  /** The same ownership rule as {@link spawnOwnedCommand}, for a child that inherits stdio. */
12
14
  export declare function spawnInheritedCommand(input: {
@@ -15,6 +17,7 @@ export declare function spawnInheritedCommand(input: {
15
17
  cwd?: string;
16
18
  env?: NodeJS.ProcessEnv;
17
19
  group: boolean;
20
+ ownerLoss?: OwnerLossGuardInvocation;
18
21
  }): NativeCommandLaunchedProcess;
19
22
  export declare function ownsCommandGroup(child: object): boolean;
20
23
  //# sourceMappingURL=owned-child.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"owned-child.d.ts","sourceRoot":"","sources":["../../src/process/owned-child.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAA+B,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAI1F,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,UAAU,CAIb;AAkED,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;CAChB,GAAG,4BAA4B,CAa/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
1
+ {"version":3,"file":"owned-child.d.ts","sourceRoot":"","sources":["../../src/process/owned-child.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAA+B,4BAA4B,EAAE,MAAM,UAAU,CAAC;AAM1F,OAAO,EAAE,KAAK,wBAAwB,EAAyB,MAAM,uBAAuB,CAAC;AAI7F,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,wBAAwB,CAAC;CACtC,GAAG,UAAU,CAIb;AAsFD,6FAA6F;AAC7F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,wBAAwB,CAAC;CACtC,GAAG,4BAA4B,CAkC/B;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
@@ -0,0 +1,15 @@
1
+ import type { Duplex } from 'node:stream';
2
+ interface GuardedChild {
3
+ readonly pid?: number;
4
+ on(event: 'exit', listener: (code: number | null, signal: string | null) => void): unknown;
5
+ }
6
+ /** Tear down a newly created guard group if its private control channel is unavailable. */
7
+ export declare function abortOwnerLossLaunch(pid: number | undefined): void;
8
+ /** Bind one private inherited control socket to the guard process that owns it. */
9
+ export declare function attachOwnerLossControl(child: GuardedChild, control: Duplex): void;
10
+ /** Preserve the guard registration when an inherited-stdio child gets its transport wrapper. */
11
+ export declare function transferOwnerLossControl(source: object, target: object): void;
12
+ /** Ordinary children are already started; guarded children first prove that their target exists. */
13
+ export declare function awaitCommandStart(child: GuardedChild): Promise<number | undefined>;
14
+ export {};
15
+ //# sourceMappingURL=owner-loss-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-loss-control.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-control.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAe1C,UAAU,YAAY;IACpB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC;CAC5F;AASD,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOlE;AAQD,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAuDjF;AAED,gGAAgG;AAChG,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAG7E;AAED,oGAAoG;AACpG,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAIxF"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Bootstrap the private owner-loss service before an application's own argv dispatcher.
3
+ *
4
+ * Call this once before routing argv in a single-file application that lazy-imports
5
+ * `stitchkit/process`. `false` means the application owns this invocation and may dispatch it;
6
+ * `true` means the package guard owns it and the application must skip its dispatcher. The guard's
7
+ * child and control channel keep the process alive for exactly their own lifetime.
8
+ */
9
+ export declare function bootstrapNativeCommandOwnerLoss(): boolean;
10
+ /** The built or source module that executes the guard protocol when launched directly. */
11
+ export declare function ownerLossGuardEntry(): string;
12
+ //# sourceMappingURL=owner-loss-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-loss-guard.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-guard.ts"],"names":[],"mappings":"AAyLA;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,IAAI,OAAO,CAEzD;AAED,0FAA0F;AAC1F,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,10 @@
1
+ export declare const OWNER_LOSS_GUARD_FLAG = "--stitchkit-owner-loss-guard-v1";
2
+ export interface OwnerLossGuardInvocation {
3
+ readonly entry: string;
4
+ readonly signalTarget: 'group' | 'leader';
5
+ }
6
+ /** The owner-loss guard is certified only on the two POSIX kernels exercised by release CI. */
7
+ export declare function ownerLossAvailable(platform: NodeJS.Platform): boolean;
8
+ /** Replace a direct command with the package-owned guard that becomes its process-group leader. */
9
+ export declare function ownerLossGuardCommand(guard: OwnerLossGuardInvocation, executable: string, args: readonly string[]): [string, ...string[]];
10
+ //# sourceMappingURL=owner-loss-protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-loss-protocol.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-protocol.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAEvE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC3C;AAED,+FAA+F;AAC/F,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,QAAQ,GAAG,OAAO,CAErE;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,wBAAwB,EAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CASvB"}
@@ -0,0 +1,4 @@
1
+ import { type Socket } from 'node:net';
2
+ /** Bun's runtime accepts an inherited socket fd here before its Node types expose the overload. */
3
+ export declare function connectOwnerLossSocket(fd: number): Socket;
4
+ //# sourceMappingURL=owner-loss-socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-loss-socket.d.ts","sourceRoot":"","sources":["../../src/process/owner-loss-socket.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,UAAU,CAAC;AAEhD,mGAAmG;AACnG,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzD"}
@@ -1 +1 @@
1
- {"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,IAAI,CAaN;AA6ED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAI1F;AAKD,4GAA4G;AAC5G;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAI/E;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtE;AA8BD,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKlD;AAuCD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAaT;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,GACb,IAAI,CAsBN"}
1
+ {"version":3,"file":"args-fields.d.ts","sourceRoot":"","sources":["../../../src/tools/cli/args-fields.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,MAAM,GACN,OAAO,GACP,QAAQ,GACR,OAAO,CAAC;AAEZ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,uEAAuE;IACvE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,iFAAiF;IACjF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAC1B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,GAAG,SAAS,GAC1B,IAAI,CAaN;AAwGD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAI1F;AAKD,4GAA4G;AAC5G;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAI/E;AAED,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAGzD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAKtE;AA8BD,qFAAqF;AACrF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAKlD;AAuCD,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,IAAI,EAAE,SAAS,GAAG,SAAS,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAaT;AAED,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EAAE,EACd,KAAK,EAAE,OAAO,GACb,IAAI,CAsBN"}
package/llms/cli.2.txt CHANGED
@@ -11,6 +11,113 @@ Parts of this slice:
11
11
  # Guide: CLI (docs/guide/cli.md) (continued)
12
12
  ==============================================================================
13
13
 
14
+ ## One operation per line — `createCliInvoker`
15
+
16
+ The most common way an agent drives a CLI is not one command: it is a stream —
17
+ a JSON line per operation, an answer per line — and a resumable batch of the
18
+ same. The mechanics contain nothing product-specific, and until now the
19
+ framework left the one piece that cannot be written outside it: running an
20
+ already-parsed call.
21
+
22
+ ```ts
23
+ import { createCliInvoker, defineCliStreamCommand, defineCliBatchCommand } from 'stitchkit/cli'
24
+
25
+ const invoker = await createCliInvoker({ name: 'myapp', services })
26
+
27
+ const outcome = await invoker.invoke('create_item', { title: 'hello', tags: ['a'] })
28
+ // { ok: true, exitCode: 0, data: { … } } — nothing written, nothing exited
29
+ ```
30
+
31
+ `invoke` runs the same pipeline a typed command runs — the same validation, the
32
+ same `lifecycle` gate, the same hooks — and returns the handler's validated
33
+ output with **the exit code the printed path would give**, from the same table.
34
+ `data` is typed `unknown`: the surface is resolved at run time from services and
35
+ runtime tools, so there is no compile-time name to key a result type on. Narrow
36
+ it with the contract's own output schema. That table used to
37
+ live inside the function that prints, so the only way to learn a code was to
38
+ print it.
39
+
40
+ Without this, a stream loop had to re-spawn the binary per line: arguments
41
+ serialised back into `--flag value` strings, nested objects pushed through
42
+ `JSON.stringify` into one argv slot and parsed again on the other side, the
43
+ result read back out of stdout text. Three conversions of data the framework was
44
+ already holding, plus a process start measured at 0.15 s — thirty seconds for a
45
+ two-hundred-line manifest before any work begins. The ban on nesting one stream
46
+ inside another was a consequence of that child process, not a rule anyone wanted.
47
+
48
+ ### Native commands in the stream
49
+
50
+ A native command is in the invoker's surface when — and only when — it declares
51
+ `output`:
52
+
53
+ ```ts
54
+ const describe = defineCliCommand({
55
+ name: 'describe', description: 'Describe the catalogue',
56
+ input: z.object({ model: z.string() }),
57
+ output: z.object({ model: z.string(), ratios: z.array(z.string()) }),
58
+ handler: ({ input }) => ({ model: input.model, ratios: ['1:1', '16:9'] }),
59
+ })
60
+
61
+ await createCliInvoker({ name: 'myapp', services, commands: [describe] })
62
+ // invoke('describe', { model: 'flux' }) → { ok: true, exitCode: 0, data: { … } }
63
+ ```
64
+
65
+ A command that declares `output?: never` prints itself and returns nothing, so
66
+ there is no result to hand back; it answers `NOT_FOUND` and stays on the command
67
+ line, where stdout exists. Your stream command is one of these, which is why a
68
+ stream still cannot invoke itself.
69
+
70
+ On this path `present` is not called — it is stdout formatting, and there is no
71
+ stdout — while `exitCode` is applied through the same function the command line
72
+ uses, so a script branching on the code sees one answer from both. Anything the
73
+ handler writes comes back as `written` rather than interleaving with your own
74
+ output:
75
+
76
+ ```ts
77
+ const outcome = await invoker.invoke('describe', { model: 'flux' })
78
+ outcome.written // { stderr: 'warming the cache\n' } — absent when nothing was written
79
+ ```
80
+
81
+ ### Mounting the loop
82
+
83
+ ```ts
84
+ await createCli({
85
+ name: 'myapp', version, services,
86
+ commands: [
87
+ defineCliStreamCommand({ name: 'jsonl', invoker }),
88
+ defineCliBatchCommand({ name: 'batch', invoker, checkpointPath: '.myapp-batch.json' }),
89
+ ],
90
+ })
91
+ ```
92
+
93
+ They are factories, not framework-owned names. Reserving `jsonl` and `batch`
94
+ would take two names out of a namespace that belongs to the application — one
95
+ that already has a `batch` command would either fail at startup or find its own
96
+ command silently shadowed — so you mount them under whatever you call them, like
97
+ any other command of yours.
98
+
99
+ Each line is `{ id, command, args }`; each answer is the invocation result plus
100
+ that `id`. A line that is not JSON, or has no `id`, is **answered** and the
101
+ stream continues: a stream that goes quiet on one line leaves its consumer
102
+ unable to tell which request it lost. Answers go to stdout, one object per line,
103
+ and nothing else does.
104
+
105
+ ### Resuming a batch
106
+
107
+ The checkpoint records, per id, a digest of the line that produced the recorded
108
+ answer, and is written after **every** line by atomic rename — a checkpoint that
109
+ only survives a clean finish protects against exactly the case that does not
110
+ happen.
111
+
112
+ A re-run replays what already ran. A line whose content changed under the same
113
+ id is **refused**: replaying it would report success for an operation nobody
114
+ ran, and re-running it would repeat a paid call. Both answer a question nobody
115
+ asked.
116
+
117
+ What stays yours: what makes a repeat safe (an idempotency key derived from the
118
+ line id), which operations a batch may contain, and how much of it runs at once.
119
+ That is product knowledge, and the framework has no business guessing it.
120
+
14
121
  ## Commands discovered from a running server
15
122
 
16
123
  A CLI compiled from contracts carries the surface of the build it was compiled
package/llms/cli.txt CHANGED
@@ -238,11 +238,19 @@ string, the schema says what it should be:
238
238
  | `z.string()` | `--name "box"` or a positional |
239
239
  | `z.number()` | `--count 3` → `3` |
240
240
  | `z.boolean()` | `--active` (presence) / `--active false` / `--no-active` |
241
+ | `z.literal(1)` / `z.literal([1, 2])` | `--level 1` → `1` |
242
+ | `z.literal(true)` | `--enabled` / `--no-enabled` |
243
+ | `z.literal('007')` | `--code 007` → `"007"` |
241
244
  | `z.enum([...])` | `--size large` |
242
245
  | `z.array(z.string())`| `--tag a --tag b` → `["a","b"]` |
243
246
  | `z.object({...})` | `--opts '{"k":"v"}'` (JSON) or `--opts.k v` |
244
247
  | `.optional()` / `.default()` | not required |
245
248
 
249
+ Primitive literals use the same coercion through optional, nullable and default wrappers and as
250
+ array elements. A literal set whose members have different primitive types stays lexical because
251
+ argv has no type tag: for `z.literal([7, '007'])`, `--value 007` remains the string `"007"` rather
252
+ than being guessed as the number `7`. The unchanged Zod schema makes the final admission decision.
253
+
246
254
  After a bare boolean flag, the next token is its value when it is exactly
247
255
  `true` or `false` — `--active false` turns it off, as it reads. Any other word
248
256
  there stays a positional, and `--` makes a literal `false` one too. The same
@@ -916,110 +924,3 @@ asset's address comes from the manifest, and the manifest's address belongs to
916
924
  your server. A channel is two documents at two addresses — which of them a build
917
925
  consults is your decision, and `assertCliPublishable` is told about all of them
918
926
  rather than taught the shape of any.
919
-
920
- ## One operation per line — `createCliInvoker`
921
-
922
- The most common way an agent drives a CLI is not one command: it is a stream —
923
- a JSON line per operation, an answer per line — and a resumable batch of the
924
- same. The mechanics contain nothing product-specific, and until now the
925
- framework left the one piece that cannot be written outside it: running an
926
- already-parsed call.
927
-
928
- ```ts
929
- import { createCliInvoker, defineCliStreamCommand, defineCliBatchCommand } from 'stitchkit/cli'
930
-
931
- const invoker = await createCliInvoker({ name: 'myapp', services })
932
-
933
- const outcome = await invoker.invoke('create_item', { title: 'hello', tags: ['a'] })
934
- // { ok: true, exitCode: 0, data: { … } } — nothing written, nothing exited
935
- ```
936
-
937
- `invoke` runs the same pipeline a typed command runs — the same validation, the
938
- same `lifecycle` gate, the same hooks — and returns the handler's validated
939
- output with **the exit code the printed path would give**, from the same table.
940
- `data` is typed `unknown`: the surface is resolved at run time from services and
941
- runtime tools, so there is no compile-time name to key a result type on. Narrow
942
- it with the contract's own output schema. That table used to
943
- live inside the function that prints, so the only way to learn a code was to
944
- print it.
945
-
946
- Without this, a stream loop had to re-spawn the binary per line: arguments
947
- serialised back into `--flag value` strings, nested objects pushed through
948
- `JSON.stringify` into one argv slot and parsed again on the other side, the
949
- result read back out of stdout text. Three conversions of data the framework was
950
- already holding, plus a process start measured at 0.15 s — thirty seconds for a
951
- two-hundred-line manifest before any work begins. The ban on nesting one stream
952
- inside another was a consequence of that child process, not a rule anyone wanted.
953
-
954
- ### Native commands in the stream
955
-
956
- A native command is in the invoker's surface when — and only when — it declares
957
- `output`:
958
-
959
- ```ts
960
- const describe = defineCliCommand({
961
- name: 'describe', description: 'Describe the catalogue',
962
- input: z.object({ model: z.string() }),
963
- output: z.object({ model: z.string(), ratios: z.array(z.string()) }),
964
- handler: ({ input }) => ({ model: input.model, ratios: ['1:1', '16:9'] }),
965
- })
966
-
967
- await createCliInvoker({ name: 'myapp', services, commands: [describe] })
968
- // invoke('describe', { model: 'flux' }) → { ok: true, exitCode: 0, data: { … } }
969
- ```
970
-
971
- A command that declares `output?: never` prints itself and returns nothing, so
972
- there is no result to hand back; it answers `NOT_FOUND` and stays on the command
973
- line, where stdout exists. Your stream command is one of these, which is why a
974
- stream still cannot invoke itself.
975
-
976
- On this path `present` is not called — it is stdout formatting, and there is no
977
- stdout — while `exitCode` is applied through the same function the command line
978
- uses, so a script branching on the code sees one answer from both. Anything the
979
- handler writes comes back as `written` rather than interleaving with your own
980
- output:
981
-
982
- ```ts
983
- const outcome = await invoker.invoke('describe', { model: 'flux' })
984
- outcome.written // { stderr: 'warming the cache\n' } — absent when nothing was written
985
- ```
986
-
987
- ### Mounting the loop
988
-
989
- ```ts
990
- await createCli({
991
- name: 'myapp', version, services,
992
- commands: [
993
- defineCliStreamCommand({ name: 'jsonl', invoker }),
994
- defineCliBatchCommand({ name: 'batch', invoker, checkpointPath: '.myapp-batch.json' }),
995
- ],
996
- })
997
- ```
998
-
999
- They are factories, not framework-owned names. Reserving `jsonl` and `batch`
1000
- would take two names out of a namespace that belongs to the application — one
1001
- that already has a `batch` command would either fail at startup or find its own
1002
- command silently shadowed — so you mount them under whatever you call them, like
1003
- any other command of yours.
1004
-
1005
- Each line is `{ id, command, args }`; each answer is the invocation result plus
1006
- that `id`. A line that is not JSON, or has no `id`, is **answered** and the
1007
- stream continues: a stream that goes quiet on one line leaves its consumer
1008
- unable to tell which request it lost. Answers go to stdout, one object per line,
1009
- and nothing else does.
1010
-
1011
- ### Resuming a batch
1012
-
1013
- The checkpoint records, per id, a digest of the line that produced the recorded
1014
- answer, and is written after **every** line by atomic rename — a checkpoint that
1015
- only survives a clean finish protects against exactly the case that does not
1016
- happen.
1017
-
1018
- A re-run replays what already ran. A line whose content changed under the same
1019
- id is **refused**: replaying it would report success for an operation nobody
1020
- ran, and re-running it would repeat a paid call. Both answer a question nobody
1021
- asked.
1022
-
1023
- What stays yours: what makes a repeat safe (an idempotency key derived from the
1024
- line id), which operations a batch may contain, and how much of it runs at once.
1025
- That is product knowledge, and the framework has no business guessing it.
@@ -0,0 +1,18 @@
1
+ # stitchkit/process/owner-loss — stitchkit docs slice
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
+ Contains: API reference: `stitchkit/process/owner-loss` (docs/api/reference.md)
7
+
8
+ ==============================================================================
9
+ # API reference: `stitchkit/process/owner-loss` (docs/api/reference.md)
10
+ ==============================================================================
11
+
12
+ ## `stitchkit/process/owner-loss`
13
+
14
+ Narrow startup entry for single-file applications that lazy-import `stitchkit/process`.
15
+
16
+ | Export | Kind | Purpose |
17
+ |---|---|---|
18
+ | `bootstrapNativeCommandOwnerLoss` | function | call before application argv routing; returns `true` only when the package guard owns this invocation, so the application skips its dispatcher while preserving a lazy import of the full command runner |
package/llms/process.txt CHANGED
@@ -139,6 +139,7 @@ console.log(captured.exitCode, new TextDecoder().decode(captured.stdout))
139
139
  const lifetime = new AbortController()
140
140
  await runNativeCommand({
141
141
  executable: '/usr/bin/git', args: ['status'], signal: lifetime.signal,
142
+ ownerLoss: 'terminate', // also stop its group if this JavaScript process is SIGKILLed
142
143
  onOutput: async (bytes, channel, outputSignal) => {
143
144
  outputSignal.throwIfAborted()
144
145
  await output.write(bytes, channel, outputSignal) // application-owned bounded sink
@@ -201,6 +202,35 @@ sink cause is kept; a cleanup failure is a `NativeCommandError` with `COMMAND_CL
201
202
  refuses with `COMMAND_UNAVAILABLE`; a descendant that has left the group on its own with `setsid` is
202
203
  outside this capability. This is one-shot execution, not a PTY, a supervisor or a daemon host.
203
204
 
205
+ `ownerLoss: 'terminate'` binds the command group to this JavaScript process even when it cannot run
206
+ cleanup. A package-owned guard becomes the process-group leader, starts the requested executable in
207
+ that group and holds one end of a private inherited kernel channel. The caller holds the other end.
208
+ `SIGKILL`, a crash or any abrupt caller exit closes that end; EOF makes the guard KILL its own group.
209
+ There is no liveness polling and no later PID lookup. Because the guard is still the group leader
210
+ when it signals, its PGID cannot have been reused by a neighbour. The option is available on Linux
211
+ and Darwin under Bun and Node, requires `group: 'own'`, and other platforms refuse it with
212
+ `COMMAND_UNAVAILABLE`. It adds one short-lived process and one descriptor per guarded command, so it
213
+ is opt-in. `onLeaderStarted({ pid })` reports the guard/group leader with this option; output, stdin,
214
+ exit status, deadlines, cancellation and `onLeaderSettled` retain the requested command's behaviour.
215
+
216
+ An unbundled application already launches the package's own guard module. A single-file bundle
217
+ whose application entry also owns argv routing must load the narrow bootstrap before its dispatcher
218
+ and skip dispatch when it claims the private guard invocation. This is especially relevant when the
219
+ full command runner stays behind a dynamic import:
220
+
221
+ ```ts
222
+ import { bootstrapNativeCommandOwnerLoss } from 'stitchkit/process/owner-loss'
223
+
224
+ if (!bootstrapNativeCommandOwnerLoss()) {
225
+ await dispatch(process.argv.slice(2)) // may lazy-import `stitchkit/process`
226
+ }
227
+ ```
228
+
229
+ The bootstrap carries the package-owned guard into the bundle. It returns `false` for application
230
+ argv and `true` only for the private child started by `runNativeCommand`, so the application does
231
+ not read a guard flag or filename. The built file is self-contained; no installed `node_modules`
232
+ is needed beside it.
233
+
204
234
  ### Stopping a command: the `stop` policy
205
235
 
206
236
  A caller abort, the `timeoutMs` deadline, an exceeded output budget and a failing sink all stop the
@@ -235,13 +265,13 @@ dropped, never passed to `onOutput` and never captured, so a leader that writes
235
265
  does not meet a broken pipe. The result rejects with the abort reason once the group is gone and the
236
266
  pipes are closed, so it can take `graceMs` plus `cleanupTimeoutMs` after the abort.
237
267
 
238
- The grace is a timer inside the process that runs the command. If that process exits first, the
239
- timer is gone and the group, which is detached into its own session, keeps running: nothing in this
240
- package can bound it from outside. Abort `killOn` in your shutdown path, so the group is killed
241
- before the process exits, and let the supervisor own the case where the process dies without a
242
- shutdown. Under systemd, keep `KillMode=control-group` (the default) so the stop of the unit
243
- reaches every process in its cgroup, whatever its process group; launchd only kills the job's own
244
- process group, which a command's group is not.
268
+ The grace is a timer inside the process that runs the command. Without `ownerLoss`, if that process
269
+ exits first, the timer is gone and the group, which is detached into its own session, keeps running.
270
+ Abort `killOn` in your shutdown path so a deliberate shutdown kills the group before exit. For an
271
+ abrupt-exit guarantee, choose `ownerLoss: 'terminate'`; for all groups in a service, let the service
272
+ supervisor own the wider boundary. Under systemd, keep `KillMode=control-group` (the default) so the
273
+ stop of the unit reaches every process in its cgroup, whatever its process group; launchd only kills
274
+ the job's own process group, which an unguarded detached command's group is not.
245
275
 
246
276
  ### Stopping a group and its descendants
247
277
 
@@ -302,7 +332,7 @@ becomes `runNativeCommand`; shell policy, command admission, logging, redaction,
302
332
  decoder and the operator sink stay with the application. Long signal-only commands stay streaming;
303
333
  bounded tar or capture commands get their own explicit limits.
304
334
 
305
- A child the caller holds until it exits is the same call. A guardian that forwards its own SIGTERM
335
+ A child the caller holds until it exits is the same call. A host that forwards its own SIGTERM
306
336
  passes an abort signal and `stop: { target: 'leader', signal: 'SIGTERM', graceMs }`. It records the
307
337
  pid in `onLeaderStarted({ pid })`, which runs once right after the leader exists (a throw stops the
308
338
  command with that error), and the leader's exit code and signal in `onLeaderSettled`: `'exit'`
@@ -312,7 +342,9 @@ long the output pipes may stay open after the leader exited: a holder that left
312
342
  `setsid` keeps them open, and without the option the command waits for it until `timeoutMs` or
313
343
  the signal; with it the command ends with `COMMAND_CLEANUP` (a holder inside the group is already
314
344
  stopped by `descendants`). A worker whose whole group must stop on abort is the default
315
- `target: 'group'`. A command that uses the caller's terminal is the next section. Importing one leaf does not make
345
+ `target: 'group'`. Add `ownerLoss: 'terminate'` when the worker must also die after an abrupt host
346
+ loss; in that mode `onLeaderStarted` reports the package guard that leads the same group. A command
347
+ that uses the caller's terminal is the next section. Importing one leaf does not make
316
348
  installing the whole npm package smaller; choose a dependency after measuring packed size and its
317
349
  dependency closure.
318
350
 
@@ -346,6 +378,7 @@ its own, so:
346
378
  because a group signal would reach the caller;
347
379
  - `descendants` does not apply and is refused: what the leader leaves behind belongs to the
348
380
  caller's group, and `descendantsStopped` is always `false`;
381
+ - `ownerLoss` is refused: an owner-loss guard must lead a group that belongs only to the command;
349
382
  - a Ctrl-C reaches the caller too; handle `SIGINT` in the caller when it must outlive the command.
350
383
 
351
384
  The two options are independent: `stdio: 'inherit'` alone keeps colour and `isatty` for a command
@@ -677,7 +710,7 @@ Native POSIX Bun/Node one-shot command execution. See [native IO](../guide/nativ
677
710
  | Export | Kind | Purpose |
678
711
  |---|---|---|
679
712
  | `runNativeCommand` | function | caller-lifetime streaming or explicitly bounded binary capture |
680
- | `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` and a group stop); `onLeaderStarted({ pid })` (once, after the leader exists), `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 |
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 |
681
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 }` |
682
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 |
683
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 |
@@ -69,7 +69,8 @@ own, recorded as an ADR.
69
69
  | `stitchkit/cli` | server | stable | `createCli` / `createCliInvoker` — runtime and strict NodeNext declarations without MCP SDK / `ai` |
70
70
  | `stitchkit/cli/publish` | build and release tooling (Bun or Node, POSIX) | evolving | `publishCli` — commit a verified CLI distribution and move its public manifest last; see [CLI guide](cli.md#publishing-a-complete-version) |
71
71
  | `stitchkit/remote` | browser **and** server | stable | peer-free `implementRemote` for thin HTTP proxy processes |
72
- | `stitchkit/process` | server (Bun or Node, POSIX) | evolving | finite native commands, byte sinks, bounded capture and process-group cancellation |
72
+ | `stitchkit/process` | server (Bun or Node, POSIX) | evolving | finite native commands, byte sinks, bounded capture, process-group cancellation and opt-in Linux/Darwin owner-loss cleanup |
73
+ | `stitchkit/process/owner-loss` | bundled server entry (Bun, POSIX) | evolving | narrow bootstrap that keeps the process runner lazy while carrying its owner-loss guard in a single-file bundle |
73
74
  | `stitchkit/files/packaging` | build time (Bun or Node) | evolving | installed native asset graph, integrity, Bun packaging plugin and the artifact loader check; no runtime install policy |
74
75
  | `stitchkit/files` | server (Bun or Node) | stable | peer-free managed local-file boundary |
75
76
  | `stitchkit/telegram` | server (Bun or Node) | evolving | peer-free Telegram platform primitives — Mini App `initData` verification, send-failure classification, resumable broadcasts, the operator channel with dedupe, a Bot API transport that separates a request that never left from an unknown outcome, local Bot API files, webhook ownership and durable webhook update intake |