stitchkit 0.103.11 → 0.103.13

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 (64) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/darwin-native.cjs +12 -0
  3. package/darwin-native.d.cts +2 -0
  4. package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
  5. package/dist/agent-runtime/sandbox-process-owner.d.ts +1 -1
  6. package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
  7. package/dist/agent-runtime/store-conformance-support.d.ts +5 -5
  8. package/dist/durability/json.d.ts.map +1 -1
  9. package/dist/entrypoints/agent-runtime/coding-tools.js +4 -2
  10. package/dist/entrypoints/agent-runtime/harness.js +4 -3
  11. package/dist/entrypoints/agent-runtime/sandbox.js +22 -16
  12. package/dist/entrypoints/agent-runtime.js +2 -2
  13. package/dist/entrypoints/application/diagnostic-journal.js +3 -2
  14. package/dist/entrypoints/cli.js +1 -1
  15. package/dist/entrypoints/files.js +3 -2
  16. package/dist/entrypoints/primitives.js +4 -3
  17. package/dist/entrypoints/process.js +3 -2
  18. package/dist/entrypoints/tools.js +2 -2
  19. package/dist/{index-nybn2err.js → index-5csmzesf.js} +1 -1
  20. package/dist/{index-ary5s7k0.js → index-69nvze1q.js} +1 -2
  21. package/dist/{index-ahtnte39.js → index-8zfsgar0.js} +35 -30
  22. package/dist/{index-ttf0y7b8.js → index-9853ymwb.js} +38 -19
  23. package/dist/{index-g4jxe7ve.js → index-db2spkv1.js} +7 -6
  24. package/dist/{index-32jkwkdm.js → index-f330qqyg.js} +253 -165
  25. package/dist/index-fm1c1a08.js +138 -0
  26. package/dist/{index-ej331hah.js → index-gxm9rc97.js} +1 -1
  27. package/dist/index-v5ee8ath.js +88 -0
  28. package/dist/{index-9jb61j5a.js → index-zp4jpkp0.js} +1 -1
  29. package/dist/internal/darwin-binding-error.d.ts +24 -0
  30. package/dist/internal/darwin-binding-error.d.ts.map +1 -0
  31. package/dist/internal/darwin-binding.d.ts.map +1 -1
  32. package/dist/internal/exclusive-lock.d.ts +1 -1
  33. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  34. package/dist/internal/json-data.d.ts +8 -2
  35. package/dist/internal/json-data.d.ts.map +1 -1
  36. package/dist/internal/json-string-size.d.ts +3 -0
  37. package/dist/internal/json-string-size.d.ts.map +1 -0
  38. package/dist/primitives/canonical-json.d.ts.map +1 -1
  39. package/dist/process/cleanup.d.ts +12 -0
  40. package/dist/process/cleanup.d.ts.map +1 -0
  41. package/dist/process/command-lifetime.d.ts +19 -0
  42. package/dist/process/command-lifetime.d.ts.map +1 -0
  43. package/dist/process/command-owner.d.ts +0 -3
  44. package/dist/process/command-owner.d.ts.map +1 -1
  45. package/dist/process/group.d.ts.map +1 -1
  46. package/dist/process/launch.d.ts +15 -6
  47. package/dist/process/launch.d.ts.map +1 -1
  48. package/dist/process/owned-child.d.ts +10 -0
  49. package/dist/process/owned-child.d.ts.map +1 -0
  50. package/dist/process/start-failure.d.ts +2 -5
  51. package/dist/process/start-failure.d.ts.map +1 -1
  52. package/dist/process/transport.d.ts +30 -0
  53. package/dist/process/transport.d.ts.map +1 -0
  54. package/dist/tools/cli/args-fields.d.ts +2 -0
  55. package/dist/tools/cli/args-fields.d.ts.map +1 -1
  56. package/dist/tools/cli/args.d.ts.map +1 -1
  57. package/llms/agent-runtime-sandbox.txt +9 -1
  58. package/llms/cli.txt +10 -0
  59. package/llms/process.txt +62 -8
  60. package/llms-full.txt +81 -9
  61. package/llms.txt +3 -3
  62. package/package.json +6 -1
  63. package/dist/index-c1jmtxa0.js +0 -74
  64. package/dist/index-d4pa2bgs.js +0 -42
package/CHANGELOG.md CHANGED
@@ -15,6 +15,42 @@ additive**; the first breaking change landed in 0.10.0. Grep the file for
15
15
 
16
16
  ## [Unreleased]
17
17
 
18
+ ## [0.103.13] - 2026-10-04
19
+
20
+ ### Fixed
21
+
22
+ - Darwin native process and contained-file backends retain a static addon dependency through
23
+ Node-compatible package builds, minified Bun/Node bundles and Bun standalone executables.
24
+ Bundlers emit native assets automatically; Bun compile embeds the target architecture addon.
25
+ Backend load failures keep their original internal cause and serialize safe stage/code
26
+ diagnostics instead of an empty object. Installed Darwin proofs exercise relocated artifacts,
27
+ exact process ownership, lock recovery, contained-file races and missing/corrupt backends.
28
+
29
+ - `stitchkit/cli`: repeated non-array options are refused before scalar coercion, including
30
+ mixed boolean presence, separate values, inline values, negation and short aliases. The same
31
+ rule covers framework and application globals. For example, `--check=false --check` is an
32
+ argument error instead of silently selecting `false`. Single options, array repetition,
33
+ untyped passthrough lists and command help retain their grammar.
34
+
35
+ ## [0.103.12] - 2026-10-03
36
+
37
+ ### Fixed
38
+
39
+ - `stitchkit/primitives`: bounded canonical JSON serializes one admitted snapshot, preserving
40
+ historical key order and undefined handling while refusing unstable Proxy reads and oversized
41
+ escaped UTF-8 output before unbounded encoding. Durable JSON predicates avoid copying or encoding.
42
+ - `stitchkit/process`: post-spawn launch failures retain cleanup ownership; process-group cleanup
43
+ uses proven ownership and monotonic deadlines. Exclusive-lock stale guards have bounded depth.
44
+ - Direct sandbox launchers retain process-group cleanup through leader settlement.
45
+ - Release tooling requires every selected evidence job and remote exact-SHA push CI before tags;
46
+ CI covers the complete affected tree independently of which packages are published, preserving
47
+ package paths across renames and Unicode or control characters in filenames.
48
+ - Gate reuse includes tracked inputs matched by ignore rules, fingerprints only selected external
49
+ inputs, rechecks them after execution and serializes memo mutations. Memory admission reads exact
50
+ v1/v2 controller paths, including colons and trailing spaces; registry polling
51
+ bounds requests, bodies and waits with one elapsed deadline.
52
+
53
+
18
54
  ## [0.103.11] - 2026-10-02
19
55
 
20
56
  ### Added
@@ -0,0 +1,12 @@
1
+ /** A lazy, statically discoverable addon edge shared by Node and Bun consumers. */
2
+ module.exports = function loadDarwinAddon() {
3
+ // The catch also keeps non-Darwin builds independent of unavailable slices.
4
+ // Bun compile selects its target architecture and embeds that literal addon.
5
+ try {
6
+ if (process.arch === 'arm64') return require('./native/darwin-arm64.node');
7
+ if (process.arch === 'x64') return require('./native/darwin-x64.node');
8
+ throw new Error('Unsupported Darwin addon architecture');
9
+ } catch (cause) {
10
+ throw new Error('Darwin addon loading failed', { cause });
11
+ }
12
+ };
@@ -0,0 +1,2 @@
1
+ declare function loadDarwinAddon(): unknown;
2
+ export = loadDarwinAddon;
@@ -1 +1 @@
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
+ {"version":3,"file":"coding-shell-process.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/coding-shell-process.ts"],"names":[],"mappings":"AAMA,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,4 +1,4 @@
1
- import { type ChildProcessWithoutNullStreams } from 'node:child_process';
1
+ import type { ChildProcessWithoutNullStreams } from 'node:child_process';
2
2
  import type { AgentProcessSandbox } from './sandbox.js';
3
3
  /** All entry paths share one command admission limit and one shutdown barrier. */
4
4
  export declare function sandboxProcessOwner(assertActive: () => void, maximum: number): {
@@ -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;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"}
1
+ {"version":3,"file":"sandbox-process-owner.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/sandbox-process-owner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAKzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,kFAAkF;AAClF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,IAAI,EAAE,OAAO,EAAE,MAAM;;mBAiBrD,8BAA8B;;iBAmCrC,UAAU,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;;EAmB7D"}
@@ -8,6 +8,11 @@ export declare function userMessage(conversationId: string, id: string): {
8
8
  parts: ({
9
9
  type: "text";
10
10
  text: string;
11
+ } | {
12
+ type: "file";
13
+ mediaType: string;
14
+ reference: string;
15
+ filename?: string | undefined;
11
16
  } | {
12
17
  type: "reasoning";
13
18
  text: string;
@@ -16,11 +21,6 @@ export declare function userMessage(conversationId: string, id: string): {
16
21
  provider: string;
17
22
  data: Record<string, import("zod").JSONType>;
18
23
  } | undefined;
19
- } | {
20
- type: "file";
21
- mediaType: string;
22
- reference: string;
23
- filename?: string | undefined;
24
24
  } | {
25
25
  type: "source";
26
26
  sourceId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/durability/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,iBAAiB,qCAS7B,CAAC"}
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/durability/json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,iBAAiB,qCAQ7B,CAAC"}
@@ -7,9 +7,11 @@ import {
7
7
  AgentCodingToolAuthorizationSchema2,
8
8
  AgentCodingToolPathAuthorizationSchema2,
9
9
  createAgentCodingTools2
10
- } from "../../index-g4jxe7ve.js";
11
- import"../../index-32jkwkdm.js";
10
+ } from "../../index-db2spkv1.js";
11
+ import"../../index-v5ee8ath.js";
12
+ import"../../index-f330qqyg.js";
12
13
  import"../../index-ahvsksw5.js";
14
+ import"../../index-gxm9rc97.js";
13
15
  import"../../index-tgzhq07n.js";
14
16
  export {
15
17
  AgentCodingToolAuthorizationSchema2 as AgentCodingToolAuthorizationSchema,
@@ -5,7 +5,7 @@ import"../../index-8kzct1d6.js";
5
5
  import {
6
6
  composeAgentPrompt2,
7
7
  createAgentRuntime2
8
- } from "../../index-9jb61j5a.js";
8
+ } from "../../index-zp4jpkp0.js";
9
9
  import"../../index-h97tqqp1.js";
10
10
  import"../../index-mnkk1ffz.js";
11
11
  import"../../index-n53mswt3.js";
@@ -15,9 +15,10 @@ import"../../index-9pw0a51a.js";
15
15
  import"../../index-ct75c3at.js";
16
16
  import"../../index-x87j7csh.js";
17
17
  import"../../index-m2xqkv55.js";
18
- import"../../index-ary5s7k0.js";
18
+ import"../../index-69nvze1q.js";
19
19
  import"../../index-nggfa2yn.js";
20
20
  import"../../index-r5hsgkz5.js";
21
+ import"../../index-v5ee8ath.js";
21
22
  import"../../index-n5yqxd3d.js";
22
23
  import {
23
24
  createAgentHarnessControlServer2
@@ -25,7 +26,7 @@ import {
25
26
  import"../../index-vgkbcnkc.js";
26
27
  import {
27
28
  walkContainedFiles
28
- } from "../../index-ej331hah.js";
29
+ } from "../../index-gxm9rc97.js";
29
30
  import"../../index-7n68nmc6.js";
30
31
  import {
31
32
  defineRuntimeTool2
@@ -9,12 +9,15 @@ import"../../index-x87j7csh.js";
9
9
  import"../../index-b2bz0kdm.js";
10
10
  import {
11
11
  createAgentCodingTools2
12
- } from "../../index-g4jxe7ve.js";
12
+ } from "../../index-db2spkv1.js";
13
+ import"../../index-v5ee8ath.js";
13
14
  import {
14
15
  NativeCommandError2,
16
+ spawnOwnedCommand,
15
17
  nativeCommandOwner,
16
18
  startNativeCommand
17
- } from "../../index-32jkwkdm.js";
19
+ } from "../../index-f330qqyg.js";
20
+ import"../../index-gxm9rc97.js";
18
21
  import"../../index-tgzhq07n.js";
19
22
 
20
23
  // src/agent-runtime/sandbox-bubblewrap.ts
@@ -540,7 +543,6 @@ function spawnSandboxProcess(executable, args, limits, options = {}, onSpawn) {
540
543
  }
541
544
 
542
545
  // src/agent-runtime/sandbox-process-owner.ts
543
- import { spawn } from "node:child_process";
544
546
  function sandboxProcessOwner(assertActive, maximum) {
545
547
  const children = new Map;
546
548
  const admit = () => {
@@ -548,7 +550,19 @@ function sandboxProcessOwner(assertActive, maximum) {
548
550
  if (children.size >= maximum)
549
551
  throw new SandboxError("SANDBOX_BUSY", "Sandbox command concurrency limit reached");
550
552
  };
553
+ const terminate = (child) => {
554
+ const owner = nativeCommandOwner(child) ?? startNativeCommand({ executable: "host-owned-command", signal: new AbortController().signal }, undefined, { launch: () => child, group: process.platform !== "win32", force: true });
555
+ return owner.terminate();
556
+ };
551
557
  const track = (child) => {
558
+ const settleDirect = () => {
559
+ if (!nativeCommandOwner(child))
560
+ terminate(child).catch(() => {
561
+ return;
562
+ });
563
+ };
564
+ child.once("exit", settleDirect);
565
+ child.once("error", settleDirect);
552
566
  const closed = new Promise((resolve, reject) => {
553
567
  child.once("close", () => {
554
568
  const settled = nativeCommandOwner(child)?.result ?? Promise.resolve();
@@ -578,11 +592,12 @@ function sandboxProcessOwner(assertActive, maximum) {
578
592
  },
579
593
  spawn(input) {
580
594
  admit();
581
- const child = spawn(input.executable, [...input.args], {
595
+ const child = spawnOwnedCommand({
596
+ executable: input.executable,
597
+ args: input.args,
582
598
  cwd: input.cwd,
583
599
  env: input.environment,
584
- detached: true,
585
- stdio: ["pipe", "pipe", "pipe"]
600
+ group: process.platform !== "win32"
586
601
  });
587
602
  child.stdin.end();
588
603
  track(child);
@@ -590,16 +605,7 @@ function sandboxProcessOwner(assertActive, maximum) {
590
605
  },
591
606
  async stop() {
592
607
  const pending = [...children];
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();
600
- }
601
- return owner.terminate();
602
- }));
608
+ await Promise.all(pending.map(([child]) => terminate(child)));
603
609
  await Promise.all(pending.map(([, closed]) => closed));
604
610
  }
605
611
  };
@@ -110,7 +110,7 @@ import {
110
110
  agentGoalStateSlot2,
111
111
  agentTodoStateSlot2,
112
112
  createAgentRuntime2
113
- } from "../index-9jb61j5a.js";
113
+ } from "../index-zp4jpkp0.js";
114
114
  import {
115
115
  AgentConversationSummarySchema2,
116
116
  AgentConversationPageSchema2,
@@ -175,7 +175,7 @@ import {
175
175
  StepAbortedError2,
176
176
  ParkRecordDecodeError2,
177
177
  ParkAbortedError2
178
- } from "../index-ary5s7k0.js";
178
+ } from "../index-69nvze1q.js";
179
179
  import {
180
180
  AgentSandboxRestrictionSchema2,
181
181
  AgentSandboxGradeSchema2,
@@ -16,8 +16,9 @@ import {
16
16
  } from "../../index-w0eqdhyd.js";
17
17
  import {
18
18
  attemptExclusiveLock
19
- } from "../../index-ttf0y7b8.js";
20
- import"../../index-nybn2err.js";
19
+ } from "../../index-9853ymwb.js";
20
+ import"../../index-5csmzesf.js";
21
+ import"../../index-v5ee8ath.js";
21
22
  import {
22
23
  isRecord
23
24
  } from "../../index-9jfdm5tg.js";
@@ -18,7 +18,7 @@ import {
18
18
  renderCliView2,
19
19
  pollUntilDone2,
20
20
  createCli2
21
- } from "../index-ahtnte39.js";
21
+ } from "../index-8zfsgar0.js";
22
22
  import {
23
23
  AppError2
24
24
  } from "../index-n53mswt3.js";
@@ -11,8 +11,9 @@ import {
11
11
  } from "../index-n53mswt3.js";
12
12
  import {
13
13
  attemptExclusiveLock
14
- } from "../index-ttf0y7b8.js";
15
- import"../index-nybn2err.js";
14
+ } from "../index-9853ymwb.js";
15
+ import"../index-5csmzesf.js";
16
+ import"../index-v5ee8ath.js";
16
17
  import {
17
18
  writeFileAtomic2,
18
19
  writeFileAtomicSync2
@@ -3,7 +3,7 @@ import {
3
3
  } from "../index-xqhede6x.js";
4
4
  import {
5
5
  isJsonData
6
- } from "../index-c1jmtxa0.js";
6
+ } from "../index-fm1c1a08.js";
7
7
  import {
8
8
  serializeCanonicalJson
9
9
  } from "../index-zsvzhjtk.js";
@@ -91,9 +91,10 @@ var CanonicalJsonOptionsSchema = z3.strictObject({
91
91
  });
92
92
  function canonicalJson(value, options = {}) {
93
93
  const limits = CanonicalJsonOptionsSchema.parse(options);
94
- if (!isJsonData(value, { ...limits, omitObjectUndefined: true }))
94
+ const snapshot = {};
95
+ if (!isJsonData(value, { ...limits, omitObjectUndefined: true }, snapshot))
95
96
  throw new TypeError("Expected bounded plain JSON: dense arrays, finite numbers, no -0, cycles or accessors");
96
- return serializeCanonicalJson(value);
97
+ return serializeCanonicalJson(snapshot.value);
97
98
  }
98
99
  // src/primitives/deadline.ts
99
100
  import { z as z4 } from "zod";
@@ -1,12 +1,13 @@
1
+ import"../index-v5ee8ath.js";
1
2
  import {
2
3
  ProcessInstanceSchema2,
3
4
  observeProcessInstance2,
4
5
  probeProcessOwner2
5
- } from "../index-nybn2err.js";
6
+ } from "../index-5csmzesf.js";
6
7
  import {
7
8
  NativeCommandError2,
8
9
  startNativeCommand
9
- } from "../index-32jkwkdm.js";
10
+ } from "../index-f330qqyg.js";
10
11
  // src/process/command.ts
11
12
  function runNativeCommand(input) {
12
13
  return startNativeCommand(input).result;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  EffectUnresolvedError2,
3
3
  createLocalStepDurability2
4
- } from "../index-ary5s7k0.js";
4
+ } from "../index-69nvze1q.js";
5
5
  import {
6
6
  AppError2,
7
7
  STITCH_ERROR_STATUS2
@@ -77,7 +77,7 @@ import {
77
77
  WaitTimeoutError,
78
78
  runWaitOperation,
79
79
  createCli2
80
- } from "../index-ahtnte39.js";
80
+ } from "../index-8zfsgar0.js";
81
81
  import {
82
82
  ManagedFilePathSchema2,
83
83
  ManagedFileRefSchema2
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadDarwinBinding
3
- } from "./index-d4pa2bgs.js";
3
+ } from "./index-v5ee8ath.js";
4
4
  import {
5
5
  isRecord
6
6
  } from "./index-9jfdm5tg.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isJsonData
3
- } from "./index-c1jmtxa0.js";
3
+ } from "./index-fm1c1a08.js";
4
4
  import {
5
5
  raceAbort
6
6
  } from "./index-mbnnw3f2.js";
@@ -103,7 +103,6 @@ import { z as z2 } from "zod";
103
103
  var DurableJsonSchema = z2.custom((value) => isJsonData(value, {
104
104
  maxDepth: 100,
105
105
  maxNodes: Number.MAX_SAFE_INTEGER,
106
- maxBytes: Number.MAX_SAFE_INTEGER,
107
106
  omitObjectUndefined: false
108
107
  }), "Expected lossless JSON data (finite numbers, plain objects and dense arrays; no accessors)");
109
108
 
@@ -152,6 +152,18 @@ class CliArgumentError2 extends Error {
152
152
 
153
153
  // src/tools/cli/args-fields.ts
154
154
  import { z } from "zod";
155
+ function appendCliOptionValue(raw, name, value, info) {
156
+ const existing = raw.get(name);
157
+ const repeatable = !name.includes(".") && (info === undefined || info.kind === "array");
158
+ if (existing !== undefined) {
159
+ if (!repeatable) {
160
+ throw new CliArgumentError2(`--${name} was passed ${existing.length + 1} times`);
161
+ }
162
+ existing.push(value);
163
+ } else {
164
+ raw.set(name, [value]);
165
+ }
166
+ }
155
167
  function unwrap(field) {
156
168
  if (field instanceof z.ZodOptional || field instanceof z.ZodNullable || field instanceof z.ZodDefault) {
157
169
  return unwrap(field.unwrap());
@@ -799,16 +811,13 @@ function readCliTokens(argv, fields, config) {
799
811
  help: false
800
812
  };
801
813
  const flags = new Map;
802
- const boolFlags = new Map;
814
+ const literalBooleanFlags = new Set;
815
+ const frameworkFlags = new Map;
803
816
  const viewFlags = new Map;
804
817
  let ascending = false;
805
818
  const positionals = [];
806
819
  const pushFlag = (name, value) => {
807
- const existing = flags.get(name);
808
- if (existing)
809
- existing.push(value);
810
- else
811
- flags.set(name, [value]);
820
+ appendCliOptionValue(flags, name, value, fields.get(name));
812
821
  };
813
822
  let optionsEnded = false;
814
823
  for (let i = 0;i < argv.length; i++) {
@@ -824,6 +833,7 @@ function readCliTokens(argv, fields, config) {
824
833
  continue;
825
834
  }
826
835
  if (tok === "-h") {
836
+ appendCliOptionValue(frameworkFlags, "help", "true", { kind: "boolean" });
827
837
  options.help = true;
828
838
  continue;
829
839
  }
@@ -839,7 +849,10 @@ function readCliTokens(argv, fields, config) {
839
849
  const separate = inline === undefined ? separateBoolValue(argv[i + 1]) : undefined;
840
850
  if (separate !== undefined)
841
851
  i++;
842
- boolFlags.set(field, inline === undefined ? separate ?? true : parseReservedBool(field, inline));
852
+ pushFlag(field, inline ?? String(separate ?? true));
853
+ if (inline !== undefined)
854
+ parseReservedBool(field, inline);
855
+ literalBooleanFlags.add(field);
843
856
  continue;
844
857
  }
845
858
  let value = inline;
@@ -866,6 +879,9 @@ function readCliTokens(argv, fields, config) {
866
879
  const separate = value === undefined ? separateBoolValue(argv[i + 1]) : undefined;
867
880
  if (separate !== undefined)
868
881
  i++;
882
+ appendCliOptionValue(frameworkFlags, name, value ?? String(separate ?? true), {
883
+ kind: "boolean"
884
+ });
869
885
  const enabled = value === undefined ? separate ?? true : parseReservedBool(name, value);
870
886
  if (name === "dry-run")
871
887
  options.dryRun = enabled;
@@ -889,6 +905,7 @@ function readCliTokens(argv, fields, config) {
889
905
  }
890
906
  if (!option.inline)
891
907
  i++;
908
+ appendCliOptionValue(frameworkFlags, name, value, { kind: "string" });
892
909
  if (name === "wait-timeout") {
893
910
  const timeout = Number(value);
894
911
  if (!Number.isFinite(timeout) || timeout <= 0) {
@@ -896,8 +913,6 @@ function readCliTokens(argv, fields, config) {
896
913
  }
897
914
  options.waitTimeout = timeout;
898
915
  } else if (VIEW_OPTIONS.has(name)) {
899
- if (viewFlags.has(name))
900
- throw new CliArgumentError2(`--${name} was given twice`);
901
916
  viewFlags.set(name, value);
902
917
  } else {
903
918
  options.outputDir = value;
@@ -905,7 +920,8 @@ function readCliTokens(argv, fields, config) {
905
920
  continue;
906
921
  }
907
922
  if (value === undefined && name.startsWith("no-") && fields.get(name.slice(3))?.kind === "boolean") {
908
- boolFlags.set(name.slice(3), false);
923
+ pushFlag(name.slice(3), "false");
924
+ literalBooleanFlags.add(name.slice(3));
909
925
  continue;
910
926
  }
911
927
  const unsafeSegment = name.split(".").find(isUnsafeKey);
@@ -922,7 +938,8 @@ function readCliTokens(argv, fields, config) {
922
938
  const separate = separateBoolValue(argv[i + 1]);
923
939
  if (separate !== undefined)
924
940
  i++;
925
- boolFlags.set(name, separate ?? true);
941
+ pushFlag(name, String(separate ?? true));
942
+ literalBooleanFlags.add(name);
926
943
  continue;
927
944
  }
928
945
  const next = argv[i + 1];
@@ -935,10 +952,10 @@ function readCliTokens(argv, fields, config) {
935
952
  }
936
953
  pushFlag(name, value);
937
954
  }
938
- return { options, flags, boolFlags, viewFlags, ascending, positionals };
955
+ return { options, flags, literalBooleanFlags, viewFlags, ascending, positionals };
939
956
  }
940
957
  function buildToolArgs(tokens, fields, declaredPositionals) {
941
- const { flags, boolFlags, positionals } = tokens;
958
+ const { flags, literalBooleanFlags, positionals } = tokens;
942
959
  const toolArgs = {};
943
960
  const fillable = declaredPositionals === undefined ? [...fields.entries()].filter(([, info]) => info.kind !== "boolean").map(([name]) => name) : [...declaredPositionals];
944
961
  const variadicTail = declaredPositionals !== undefined && fields.get(fillable[fillable.length - 1] ?? "")?.kind === "array" ? fillable[fillable.length - 1] : undefined;
@@ -964,14 +981,12 @@ function buildToolArgs(tokens, fields, declaredPositionals) {
964
981
  if (pi < positionals.length) {
965
982
  throw new CliArgumentError2(`Unexpected positional argument "${positionals[pi]}"`);
966
983
  }
967
- for (const [key, value] of boolFlags) {
968
- toolArgs[key] = value;
969
- }
970
984
  const dottedRoots = new Map;
971
985
  for (const key of flags.keys()) {
972
986
  const dot = key.indexOf(".");
973
- if (dot > 0)
987
+ if (dot > 0 && !literalBooleanFlags.has(key)) {
974
988
  dottedRoots.set(key.slice(0, dot), key);
989
+ }
975
990
  }
976
991
  for (const [root, dotted] of dottedRoots) {
977
992
  if (flags.has(root)) {
@@ -979,17 +994,11 @@ function buildToolArgs(tokens, fields, declaredPositionals) {
979
994
  }
980
995
  }
981
996
  for (const [key, values] of flags) {
982
- if (key.includes(".")) {
983
- if (values.length > 1) {
984
- throw new CliArgumentError2(`--${key} was passed ${values.length} times`);
985
- }
997
+ const info = fields.get(key);
998
+ if (key.includes(".") && !literalBooleanFlags.has(key)) {
986
999
  setNested(toolArgs, key.split("."), looseCoerce(values[0] ?? ""));
987
1000
  continue;
988
1001
  }
989
- const info = fields.get(key);
990
- if (values.length > 1 && info !== undefined && info.kind !== "array" && info.kind !== "other") {
991
- throw new CliArgumentError2(`--${key} was passed ${values.length} times`);
992
- }
993
1002
  toolArgs[key] = coerceField(info, values, `--${key}`);
994
1003
  }
995
1004
  return toolArgs;
@@ -1041,11 +1050,7 @@ function extractCliGlobalOptions2(argv, schema) {
1041
1050
  throw new CliArgumentError2(`--${option.name} requires a value`);
1042
1051
  }
1043
1052
  }
1044
- const existing = raw.get(option.name);
1045
- if (existing)
1046
- existing.push(value);
1047
- else
1048
- raw.set(option.name, [value]);
1053
+ appendCliOptionValue(raw, option.name, value, info);
1049
1054
  }
1050
1055
  const args = {};
1051
1056
  for (const [name, values] of raw) {
@@ -3,7 +3,7 @@ import {
3
3
  ProcessInstanceSchema2,
4
4
  readProcessInstance,
5
5
  probeProcessOwner2
6
- } from "./index-nybn2err.js";
6
+ } from "./index-5csmzesf.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./index-9jfdm5tg.js";
@@ -100,6 +100,7 @@ async function diagnose(owner, declaredIdentity) {
100
100
  return { attribution, liveness: "not-probed", owner };
101
101
  return { attribution, ...await probeProcessOwner2(owner.pid, owner.process), owner };
102
102
  }
103
+ var MAX_RECLAIM_DEPTH = 16;
103
104
  async function readLockFile(path, onFailure, signal) {
104
105
  try {
105
106
  const record = await readLockRecord(path, undefined, signal);
@@ -180,33 +181,45 @@ function reclaimable(state, diagnosis, graceMs) {
180
181
  return diagnosis.liveness === "gone";
181
182
  return typeof graceMs === "number" && Date.now() - state.mtimeMs >= graceMs;
182
183
  }
183
- async function reclaimUnderGuard(path, options) {
184
+ async function reclaimUnderGuard(path, options, depth) {
184
185
  const guardPath = `${path}.reclaim`;
185
- const acquired = await attemptExclusiveLock(guardPath, {
186
- ...options,
187
- ownerlessGraceMs: options.ownerlessGraceMs === undefined ? 5000 : options.ownerlessGraceMs
188
- });
186
+ if (depth >= MAX_RECLAIM_DEPTH)
187
+ return {
188
+ refused: true,
189
+ cause: new Error(`Exclusive lock reclaim guard recovery depth exceeds ${MAX_RECLAIM_DEPTH}`)
190
+ };
191
+ let acquired;
192
+ try {
193
+ acquired = await attemptExclusiveLock(guardPath, {
194
+ ...options,
195
+ ownerlessGraceMs: options.ownerlessGraceMs === undefined ? 5000 : options.ownerlessGraceMs
196
+ }, depth + 1);
197
+ } catch (cause) {
198
+ if (!isCode(cause, "ENAMETOOLONG"))
199
+ throw cause;
200
+ return { refused: true, cause };
201
+ }
189
202
  if (!("held" in acquired))
190
- return;
203
+ return { refused: true, cause: acquired.diagnosis?.cause ?? acquired.error };
191
204
  const guard = acquired.held;
192
205
  try {
193
- let unsafe = false;
194
- const state = await readLockFile(path, () => {
195
- unsafe = true;
206
+ let readFailure;
207
+ const state = await readLockFile(path, (cause) => {
208
+ readFailure = cause;
196
209
  }, options.signal);
197
- if (unsafe)
198
- return "refused";
210
+ if (readFailure !== undefined)
211
+ return { refused: true, cause: readFailure };
199
212
  if (state) {
200
213
  const diagnosis = await diagnose(state.owner, options.machineIdentity);
201
214
  if (options.signal?.aborted)
202
- return "refused";
215
+ return { refused: true };
203
216
  if (!reclaimable(state, diagnosis, options.ownerlessGraceMs))
204
- return "refused";
217
+ return { refused: true, cause: diagnosis.cause };
205
218
  await unlinkIfSame(path, state.ino, state.dev);
206
219
  }
207
220
  return await createOwned(path, options, state !== undefined).catch((error) => {
208
221
  if (isCode(error, "EEXIST"))
209
- return "refused";
222
+ return { refused: true, cause: error };
210
223
  throw error;
211
224
  });
212
225
  } finally {
@@ -215,7 +228,7 @@ async function reclaimUnderGuard(path, options) {
215
228
  });
216
229
  }
217
230
  }
218
- async function attemptExclusiveLock(path, options) {
231
+ async function attemptExclusiveLock(path, options, depth = 0) {
219
232
  try {
220
233
  return { held: await createOwned(path, options, false) };
221
234
  } catch (error) {
@@ -236,10 +249,16 @@ async function attemptExclusiveLock(path, options) {
236
249
  if (!state || !reclaimable(state, diagnosis, options.ownerlessGraceMs)) {
237
250
  return { error, diagnosis };
238
251
  }
239
- const reclaimed = await reclaimUnderGuard(path, options);
240
- if (reclaimed !== undefined && reclaimed !== "refused")
252
+ const reclaimed = await reclaimUnderGuard(path, options, depth);
253
+ if (!("refused" in reclaimed))
241
254
  return { held: reclaimed };
242
- return { error, diagnosis };
255
+ return {
256
+ error,
257
+ diagnosis: {
258
+ ...diagnosis,
259
+ ...reclaimed.cause !== undefined && { cause: reclaimed.cause }
260
+ }
261
+ };
243
262
  }
244
263
  }
245
264