stitchkit 0.103.9 → 0.103.11

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 +21 -0
  2. package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
  3. package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
  4. package/dist/entrypoints/agent-runtime/coding-tools.js +2 -1
  5. package/dist/entrypoints/agent-runtime/sandbox.js +28 -14
  6. package/dist/entrypoints/application/diagnostic-journal.js +2 -1
  7. package/dist/entrypoints/files.js +14 -4
  8. package/dist/entrypoints/process.d.ts +2 -1
  9. package/dist/entrypoints/process.d.ts.map +1 -1
  10. package/dist/entrypoints/process.js +9 -2
  11. package/dist/index-32jkwkdm.js +565 -0
  12. package/dist/{index-a4ajxwmb.js → index-g4jxe7ve.js} +113 -131
  13. package/dist/index-nybn2err.js +213 -0
  14. package/dist/index-ttf0y7b8.js +246 -0
  15. package/dist/internal/exclusive-lock-read.d.ts +20 -0
  16. package/dist/internal/exclusive-lock-read.d.ts.map +1 -0
  17. package/dist/internal/exclusive-lock.d.ts +3 -1
  18. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  19. package/dist/internal/process-instance.d.ts +46 -9
  20. package/dist/internal/process-instance.d.ts.map +1 -1
  21. package/dist/internal/with-exclusive-lock.d.ts +4 -3
  22. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  23. package/dist/process/command-owner.d.ts +7 -2
  24. package/dist/process/command-owner.d.ts.map +1 -1
  25. package/dist/process/contract.d.ts +22 -1
  26. package/dist/process/contract.d.ts.map +1 -1
  27. package/dist/process/group.d.ts +6 -1
  28. package/dist/process/group.d.ts.map +1 -1
  29. package/dist/process/launch.d.ts +65 -0
  30. package/dist/process/launch.d.ts.map +1 -0
  31. package/dist/process/leader-settlement.d.ts +6 -0
  32. package/dist/process/leader-settlement.d.ts.map +1 -0
  33. package/dist/process/start-failure.d.ts +7 -0
  34. package/dist/process/start-failure.d.ts.map +1 -0
  35. package/llms/agent-runtime.txt +7 -1
  36. package/llms/files.txt +1 -1
  37. package/llms/process.txt +115 -2
  38. package/llms-full.txt +123 -4
  39. package/llms.txt +3 -3
  40. package/native/darwin-arm64.node +0 -0
  41. package/native/darwin-x64.node +0 -0
  42. package/package.json +2 -2
  43. package/dist/index-7kxw1awn.js +0 -328
  44. package/dist/index-eeqmg7qm.js +0 -202
package/CHANGELOG.md CHANGED
@@ -15,6 +15,27 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.103.11] - 2026-10-02
19
+
20
+ ### Added
21
+
22
+ - `stitchkit/process`: native command limit errors expose a typed `reason` (`deadline` or `output-budget`) independent of their message; existing codes, causes, cancellation and cleanup guarantees are preserved.
23
+
24
+ ### Fixed
25
+
26
+ - `stitchkit/files`: cancellation after acquiring an exclusive lock refuses the callback and releases ownership. Lock and reclaim-guard records use bounded descriptor reads and refuse FIFO, nonregular, linked, oversized or changing records.
27
+ - `stitchkit/process`: synchronous native launch failures settle external resources once before rejecting, with bounded cleanup and the original syscall cause.
28
+ - `stitchkit/agent-runtime`: coding commands share the native execution owner while retaining forced descendant cleanup, structural sandbox launchers, bounded artifacts and UTF-8 previews.
29
+ - Local gate evidence is saved only for stable inputs, including content changed and restored during a run. PostgreSQL fingerprint probes have finite budgets and distinguish URI connection overrides; unknown external inputs cannot authorize heavy memo reuse. Heavy concurrency accounts for visible cgroup memory limits.
30
+
31
+ ## [0.103.10] - 2026-10-01
32
+
33
+ ### Added
34
+
35
+ - `stitchkit/process`: `onLeaderSettled` observes launcher exit before inherited-pipe drain and settles resource scopes once on terminal failure; callbacks have bounded cancellation and preserve initial causes. Public process identity observation/probing preserves unavailable evidence and its cause from the existing Linux/Darwin owner.
36
+ - `stitchkit/files`: `ownerlessGraceMs: null` explicitly refuses age-based reclaim of unknown locks and guards; exact requested lock permissions survive restrictive umask, and failed descriptor setup cannot remove a replacement inode.
37
+ - Document and qualify neutral library bundling from public imports and published declarations with Zod as its only runtime peer; full-kernel install remains a build-time choice.
38
+
18
39
  ## [0.103.9] - 2026-10-01
19
40
 
20
41
  ### Added
@@ -1 +1 @@
1
- {"version":3,"file":"coding-shell-process.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/coding-shell-process.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,qBAAqB,EAAqB,MAAM,wBAAwB,CAAC;AAEvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAuCrD,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,CAAC,EAAE,MAAM,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;;;;;;;;;;;;;;;GAsKA"}
1
+ {"version":3,"file":"coding-shell-process.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/coding-shell-process.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,qBAAqB,EAAqB,MAAM,wBAAwB,CAAC;AAEvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAuCrD,wBAAsB,cAAc,CAAC,KAAK,EAAE;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,KAAK,CAAC,EAAE,MAAM,UAAU,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;CACrE;;;;;;;;;;;;;;;GAkKA"}
@@ -1 +1 @@
1
- {"version":3,"file":"sandbox-process-owner.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/sandbox-process-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,8BAA8B,EAAS,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM;;mBAOrD,8BAA8B;;iBAerC,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;EA0B7D"}
1
+ {"version":3,"file":"sandbox-process-owner.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/sandbox-process-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,8BAA8B,EAAS,MAAM,oBAAoB,CAAC;AAIhF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM;;mBAOrD,8BAA8B;;iBA6BrC,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;EAkC7D"}
@@ -7,7 +7,8 @@ import {
7
7
  AgentCodingToolAuthorizationSchema2,
8
8
  AgentCodingToolPathAuthorizationSchema2,
9
9
  createAgentCodingTools2
10
- } from "../../index-a4ajxwmb.js";
10
+ } from "../../index-g4jxe7ve.js";
11
+ import"../../index-32jkwkdm.js";
11
12
  import"../../index-ahvsksw5.js";
12
13
  import"../../index-tgzhq07n.js";
13
14
  export {
@@ -9,11 +9,12 @@ import"../../index-x87j7csh.js";
9
9
  import"../../index-b2bz0kdm.js";
10
10
  import {
11
11
  createAgentCodingTools2
12
- } from "../../index-a4ajxwmb.js";
12
+ } from "../../index-g4jxe7ve.js";
13
13
  import {
14
14
  NativeCommandError2,
15
+ nativeCommandOwner,
15
16
  startNativeCommand
16
- } from "../../index-eeqmg7qm.js";
17
+ } from "../../index-32jkwkdm.js";
17
18
  import"../../index-tgzhq07n.js";
18
19
 
19
20
  // src/agent-runtime/sandbox-bubblewrap.ts
@@ -548,12 +549,25 @@ function sandboxProcessOwner(assertActive, maximum) {
548
549
  throw new SandboxError("SANDBOX_BUSY", "Sandbox command concurrency limit reached");
549
550
  };
550
551
  const track = (child) => {
551
- const closed = new Promise((resolve) => {
552
+ const closed = new Promise((resolve, reject) => {
552
553
  child.once("close", () => {
553
- children.delete(child);
554
- resolve();
554
+ const settled = nativeCommandOwner(child)?.result ?? Promise.resolve();
555
+ settled.then(() => {
556
+ children.delete(child);
557
+ resolve();
558
+ }, (error) => {
559
+ if (error instanceof NativeCommandError2 && error.code === "COMMAND_CLEANUP")
560
+ reject(error);
561
+ else {
562
+ children.delete(child);
563
+ resolve();
564
+ }
565
+ });
555
566
  });
556
567
  });
568
+ closed.catch(() => {
569
+ return;
570
+ });
557
571
  children.set(child, closed);
558
572
  };
559
573
  return {
@@ -576,16 +590,16 @@ function sandboxProcessOwner(assertActive, maximum) {
576
590
  },
577
591
  async stop() {
578
592
  const pending = [...children];
579
- for (const [child] of pending) {
580
- if (child.pid === undefined)
581
- continue;
582
- try {
583
- process.kill(-child.pid, "SIGKILL");
584
- } catch (error) {
585
- if (!(error instanceof Error && ("code" in error) && error.code === "ESRCH"))
586
- throw error;
593
+ await Promise.all(pending.map(([child]) => {
594
+ let owner = nativeCommandOwner(child);
595
+ if (!owner) {
596
+ const adopted = startNativeCommand({ executable: "host-owned-command", signal: new AbortController().signal }, undefined, { launch: () => child, group: process.platform !== "win32", force: true });
597
+ owner = nativeCommandOwner(child);
598
+ if (!owner)
599
+ return adopted.stop();
587
600
  }
588
- }
601
+ return owner.terminate();
602
+ }));
589
603
  await Promise.all(pending.map(([, closed]) => closed));
590
604
  }
591
605
  };
@@ -16,7 +16,8 @@ import {
16
16
  } from "../../index-w0eqdhyd.js";
17
17
  import {
18
18
  attemptExclusiveLock
19
- } from "../../index-7kxw1awn.js";
19
+ } from "../../index-ttf0y7b8.js";
20
+ import"../../index-nybn2err.js";
20
21
  import {
21
22
  isRecord
22
23
  } from "../../index-9jfdm5tg.js";
@@ -11,7 +11,8 @@ import {
11
11
  } from "../index-n53mswt3.js";
12
12
  import {
13
13
  attemptExclusiveLock
14
- } from "../index-7kxw1awn.js";
14
+ } from "../index-ttf0y7b8.js";
15
+ import"../index-nybn2err.js";
15
16
  import {
16
17
  writeFileAtomic2,
17
18
  writeFileAtomicSync2
@@ -300,7 +301,10 @@ function pause(ms, signal) {
300
301
  async function withExclusiveLock(path, run, options = {}) {
301
302
  const label = options.label ?? path;
302
303
  const timeoutMs = nonNegative("timeoutMs", options.timeoutMs, DEFAULT_TIMEOUT_MS);
303
- const ownerlessGraceMs = nonNegative("ownerlessGraceMs", options.ownerlessGraceMs, DEFAULT_OWNERLESS_GRACE_MS);
304
+ const ownerlessGraceMs = options.ownerlessGraceMs === null ? null : nonNegative("ownerlessGraceMs", options.ownerlessGraceMs, DEFAULT_OWNERLESS_GRACE_MS);
305
+ const mode = options.mode ?? 384;
306
+ if (!Number.isInteger(mode) || mode < 0 || mode > 511)
307
+ throw new RangeError("[stitchkit] withExclusiveLock: mode must be permission bits from 0000 to 0777");
304
308
  const { signal } = options;
305
309
  const deadline = performance.now() + timeoutMs;
306
310
  let delay = FIRST_RETRY_MS;
@@ -309,8 +313,9 @@ async function withExclusiveLock(path, run, options = {}) {
309
313
  throw new ExclusiveLockError("LOCK_ABORTED", label, null, `[stitchkit] waiting for the lock on "${label}" was cancelled`, { cause: signal.reason });
310
314
  }
311
315
  const attempt = await attemptExclusiveLock(path, {
312
- mode: options.mode ?? 384,
316
+ mode,
313
317
  reclaim: true,
318
+ signal,
314
319
  ownerlessGraceMs,
315
320
  ...options.machineIdentity !== undefined && {
316
321
  machineIdentity: options.machineIdentity
@@ -320,6 +325,9 @@ async function withExclusiveLock(path, run, options = {}) {
320
325
  const { held } = attempt;
321
326
  let result;
322
327
  try {
328
+ if (signal?.aborted) {
329
+ throw new ExclusiveLockError("LOCK_ABORTED", label, null, `[stitchkit] waiting for the lock on "${label}" was cancelled`, { cause: signal.reason });
330
+ }
323
331
  result = await run({ path: held.path, owner: held.owner, reclaimed: held.reclaimed });
324
332
  } catch (error) {
325
333
  await held.release().catch(() => {
@@ -330,10 +338,12 @@ async function withExclusiveLock(path, run, options = {}) {
330
338
  await held.release();
331
339
  return result;
332
340
  }
341
+ if (signal?.aborted)
342
+ continue;
333
343
  const remaining = deadline - performance.now();
334
344
  if (remaining <= 0) {
335
345
  const holder = attempt.diagnosis?.owner ?? null;
336
- throw new ExclusiveLockError("LOCK_TIMEOUT", label, holder, `[stitchkit] the lock on "${label}" is held by ${describeHolder(holder)}${describeEvidence(attempt.diagnosis)}; gave up after ${timeoutMs} ms`, { cause: attempt.error });
346
+ throw new ExclusiveLockError("LOCK_TIMEOUT", label, holder, `[stitchkit] the lock on "${label}" is held by ${describeHolder(holder)}${describeEvidence(attempt.diagnosis)}; gave up after ${timeoutMs} ms`, { cause: attempt.diagnosis?.cause ?? attempt.error });
337
347
  }
338
348
  await pause(Math.min(delay * (0.5 + Math.random() / 2), remaining), signal);
339
349
  delay = Math.min(delay * 2, MAX_RETRY_MS);
@@ -1,4 +1,5 @@
1
1
  /** POSIX Node/Bun finite native commands, independent of the agent runtime. */
2
+ export { observeProcessInstance, type ProcessInstance, type ProcessInstanceObservation, ProcessInstanceSchema, type ProcessOwnerEvidence, probeProcessOwner, } from '../internal/process-instance.js';
2
3
  export { runNativeCommand } from '../process/command.js';
3
- export { NativeCommandError, type NativeCommandOptions, type NativeCommandResult, } from '../process/contract.js';
4
+ export { NativeCommandError, type NativeCommandOptions, type NativeCommandResult, type NativeCommandSettlement, } from '../process/contract.js';
4
5
  //# sourceMappingURL=process.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/entrypoints/process.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/entrypoints/process.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAE/E,OAAO,EACL,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,0BAA0B,EAC/B,qBAAqB,EACrB,KAAK,oBAAoB,EACzB,iBAAiB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,kBAAkB,EAClB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,GAC7B,MAAM,qBAAqB,CAAC"}
@@ -1,13 +1,20 @@
1
+ import {
2
+ ProcessInstanceSchema2,
3
+ observeProcessInstance2,
4
+ probeProcessOwner2
5
+ } from "../index-nybn2err.js";
1
6
  import {
2
7
  NativeCommandError2,
3
8
  startNativeCommand
4
- } from "../index-eeqmg7qm.js";
5
-
9
+ } from "../index-32jkwkdm.js";
6
10
  // src/process/command.ts
7
11
  function runNativeCommand(input) {
8
12
  return startNativeCommand(input).result;
9
13
  }
10
14
  export {
11
15
  NativeCommandError2 as NativeCommandError,
16
+ ProcessInstanceSchema2 as ProcessInstanceSchema,
17
+ observeProcessInstance2 as observeProcessInstance,
18
+ probeProcessOwner2 as probeProcessOwner,
12
19
  runNativeCommand
13
20
  };