stitchkit 0.111.2 → 0.111.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/application/diagnostic-journal-contract.d.ts +1 -1
  3. package/dist/application/diagnostic-journal-contract.d.ts.map +1 -1
  4. package/dist/entrypoints/agent-runtime/coding-tools.js +3 -3
  5. package/dist/entrypoints/agent-runtime/harness.js +6 -6
  6. package/dist/entrypoints/agent-runtime/sandbox.js +3 -3
  7. package/dist/entrypoints/agent-runtime/sqlite/bun.js +5 -5
  8. package/dist/entrypoints/agent-runtime/sqlite/node.js +5 -5
  9. package/dist/entrypoints/agent-runtime/testing.js +5 -5
  10. package/dist/entrypoints/agent-runtime.js +12 -12
  11. package/dist/entrypoints/application/diagnostic-journal.js +1 -1
  12. package/dist/entrypoints/application/directory-inbox.js +3 -3
  13. package/dist/entrypoints/cli/publish.js +2 -2
  14. package/dist/entrypoints/cli.js +8 -8
  15. package/dist/entrypoints/files.js +2 -2
  16. package/dist/entrypoints/server.js +3 -3
  17. package/dist/entrypoints/telegram.js +1 -1
  18. package/dist/entrypoints/testing.js +1 -1
  19. package/dist/entrypoints/tools/connections.js +6 -4
  20. package/dist/entrypoints/tools/contract.js +2 -2
  21. package/dist/entrypoints/tools/invoker.js +6 -6
  22. package/dist/entrypoints/tools/mcp.js +8 -8
  23. package/dist/entrypoints/tools.js +11 -11
  24. package/dist/{index-mha6b4vk.js → index-02h0dfpr.js} +12 -5
  25. package/dist/{index-0z3kfphz.js → index-38gvr73z.js} +1 -1
  26. package/dist/{index-8jv0trhg.js → index-5as18gs2.js} +1 -1
  27. package/dist/{index-t2bsd0hm.js → index-5v5a9k2n.js} +92 -43
  28. package/dist/{index-c5374vpt.js → index-651xsm48.js} +4 -4
  29. package/dist/{index-w9mqgnz9.js → index-6b3pcq5z.js} +1 -1
  30. package/dist/{index-7c046kxr.js → index-c7h371gr.js} +4 -4
  31. package/dist/{index-mnk5vgdr.js → index-d4cnhfdn.js} +1 -1
  32. package/dist/{index-t5sjh517.js → index-epmnrnth.js} +18 -1
  33. package/dist/{index-636mggad.js → index-ff3agzaf.js} +1 -1
  34. package/dist/{index-7c957abz.js → index-fh2ht88b.js} +1 -1
  35. package/dist/{index-q6crhe1n.js → index-h7accrrv.js} +19 -6
  36. package/dist/{index-0d8m0kee.js → index-hvg9hctd.js} +3 -3
  37. package/dist/{index-nx49x0tw.js → index-hy802jnr.js} +1 -1
  38. package/dist/{index-dd1z5kxb.js → index-jfk93gja.js} +3 -3
  39. package/dist/{index-v2eyj2ws.js → index-jprxv2an.js} +6 -6
  40. package/dist/{index-cykxpxz5.js → index-jy9wq8tp.js} +1 -1
  41. package/dist/{index-ey15wx6j.js → index-n0adphfg.js} +1 -1
  42. package/dist/{index-ghwntn9n.js → index-vqdjym30.js} +2 -2
  43. package/dist/internal/exclusive-lock-owner.d.ts +53 -0
  44. package/dist/internal/exclusive-lock-owner.d.ts.map +1 -0
  45. package/dist/internal/exclusive-lock.d.ts +1 -28
  46. package/dist/internal/exclusive-lock.d.ts.map +1 -1
  47. package/dist/internal/open-descriptors.d.ts +18 -0
  48. package/dist/internal/open-descriptors.d.ts.map +1 -0
  49. package/dist/internal/with-exclusive-lock.d.ts +2 -12
  50. package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
  51. package/dist/tools/connections/runtime.d.ts +1 -1
  52. package/dist/tools/connections/runtime.d.ts.map +1 -1
  53. package/dist/tools/execute-args.d.ts.map +1 -1
  54. package/dist/tools/schema/flatten-join.d.ts.map +1 -1
  55. package/dist/tools/schema/json-schema-origin.d.ts +17 -0
  56. package/dist/tools/schema/json-schema-origin.d.ts.map +1 -1
  57. package/llms/cli.2.txt +10 -0
  58. package/llms/files.txt +1 -1
  59. package/llms/process.txt +10 -0
  60. package/llms/tools-connections.txt +1 -1
  61. package/llms/tools.txt +8 -3
  62. package/llms-full.txt +30 -5
  63. package/llms.txt +5 -5
  64. package/package.json +1 -1
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  ToolExecutionControlError2,
16
16
  isToolExecutionControlError2
17
- } from "./index-mha6b4vk.js";
17
+ } from "./index-02h0dfpr.js";
18
18
  import {
19
19
  agentDurableEventId2
20
20
  } from "./index-mnkk1ffz.js";
@@ -18,11 +18,93 @@ import {
18
18
 
19
19
  // src/internal/exclusive-lock.ts
20
20
  import { randomUUID } from "node:crypto";
21
- import { lstat, open, readdir, unlink } from "node:fs/promises";
22
- import { hostname } from "node:os";
21
+ import { lstat, open as open2, readdir as readdir2, unlink } from "node:fs/promises";
22
+ import { hostname as hostname2 } from "node:os";
23
23
  import { dirname, join } from "node:path";
24
+
25
+ // src/internal/exclusive-lock-owner.ts
26
+ import { hostname } from "node:os";
24
27
  import { z } from "zod";
25
28
 
29
+ // src/internal/open-descriptors.ts
30
+ import { constants, fstatSync } from "node:fs";
31
+ import { open, readdir } from "node:fs/promises";
32
+ var DESCRIPTOR_DIRECTORY = "/dev/fd";
33
+ async function holdsOpenDescriptor(path, file, descriptorDirectory = DESCRIPTOR_DIRECTORY) {
34
+ const probe = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK).catch(() => null);
35
+ if (!probe)
36
+ return null;
37
+ try {
38
+ const opened = await probe.stat();
39
+ if (!opened.isFile() || opened.ino !== file.ino || opened.dev !== file.dev)
40
+ return null;
41
+ let names;
42
+ try {
43
+ names = await readdir(descriptorDirectory);
44
+ } catch {
45
+ return null;
46
+ }
47
+ let listedProbe = false;
48
+ for (const name of names) {
49
+ const descriptor = Number(name);
50
+ if (!Number.isInteger(descriptor) || descriptor < 0)
51
+ continue;
52
+ if (descriptor === probe.fd) {
53
+ listedProbe = true;
54
+ continue;
55
+ }
56
+ try {
57
+ const info = fstatSync(descriptor);
58
+ if (info.ino === file.ino && info.dev === file.dev)
59
+ return true;
60
+ } catch {}
61
+ }
62
+ return listedProbe ? false : null;
63
+ } finally {
64
+ await probe.close();
65
+ }
66
+ }
67
+
68
+ // src/internal/exclusive-lock-owner.ts
69
+ var ExclusiveLockOwnerSchema = z.object({
70
+ pid: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
71
+ host: z.string().min(1),
72
+ acquiredAt: z.string(),
73
+ machine: z.string().min(1).optional().catch(undefined),
74
+ process: ProcessInstanceSchema2.nullable().optional().catch(null)
75
+ });
76
+ function readOwner(text) {
77
+ let parsed;
78
+ try {
79
+ parsed = JSON.parse(text);
80
+ } catch {
81
+ return { owner: undefined, ownerless: true };
82
+ }
83
+ const owner = ExclusiveLockOwnerSchema.safeParse(parsed);
84
+ if (owner.success)
85
+ return { owner: owner.data, ownerless: false };
86
+ const ownerlike = isRecord(parsed) && ["pid", "token", "host", "machine", "process", "acquiredAt"].some((key) => Object.hasOwn(parsed, key));
87
+ return { owner: undefined, ownerless: !ownerlike };
88
+ }
89
+ function attribute(owner, identity) {
90
+ if (identity !== null && owner.machine !== undefined) {
91
+ return owner.machine === identity ? "this-machine" : "another-machine";
92
+ }
93
+ return owner.host === hostname() ? "this-machine" : "unattributable";
94
+ }
95
+ async function diagnose(lock, declaredIdentity) {
96
+ const owner = lock?.owner;
97
+ if (!lock || !owner)
98
+ return { attribution: "unattributable", liveness: "not-probed", owner: null };
99
+ const attribution = attribute(owner, await machineIdentity(declaredIdentity));
100
+ if (attribution !== "this-machine")
101
+ return { attribution, liveness: "not-probed", owner };
102
+ const evidence = await probeProcessOwner2(owner.pid, owner.process);
103
+ if (evidence.identity === "matched" && owner.pid === process.pid && await holdsOpenDescriptor(lock.path, lock) === false)
104
+ return { attribution, liveness: "gone", identity: "descriptor-closed", owner };
105
+ return { attribution, ...evidence, owner };
106
+ }
107
+
26
108
  // src/internal/exclusive-lock-read.ts
27
109
  var OWNER_RECORD_BYTES = 16 * 1024;
28
110
 
@@ -60,49 +142,15 @@ async function readLockRecord(path, {
60
142
  }
61
143
 
62
144
  // src/internal/exclusive-lock.ts
63
- var ExclusiveLockOwnerSchema = z.object({
64
- pid: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
65
- host: z.string().min(1),
66
- acquiredAt: z.string(),
67
- machine: z.string().min(1).optional().catch(undefined),
68
- process: ProcessInstanceSchema2.nullable().optional().catch(null)
69
- });
70
145
  function isCode(error, code) {
71
146
  return isRecord(error) && error.code === code;
72
147
  }
73
- function readOwner(text) {
74
- let parsed;
75
- try {
76
- parsed = JSON.parse(text);
77
- } catch {
78
- return { owner: undefined, ownerless: true };
79
- }
80
- const owner = ExclusiveLockOwnerSchema.safeParse(parsed);
81
- if (owner.success)
82
- return { owner: owner.data, ownerless: false };
83
- const ownerlike = isRecord(parsed) && ["pid", "token", "host", "machine", "process", "acquiredAt"].some((key) => Object.hasOwn(parsed, key));
84
- return { owner: undefined, ownerless: !ownerlike };
85
- }
86
- function attribute(owner, identity) {
87
- if (identity !== null && owner.machine !== undefined) {
88
- return owner.machine === identity ? "this-machine" : "another-machine";
89
- }
90
- return owner.host === hostname() ? "this-machine" : "unattributable";
91
- }
92
- async function diagnose(owner, declaredIdentity) {
93
- if (!owner)
94
- return { attribution: "unattributable", liveness: "not-probed", owner: null };
95
- const attribution = attribute(owner, await machineIdentity(declaredIdentity));
96
- if (attribution !== "this-machine")
97
- return { attribution, liveness: "not-probed", owner };
98
- return { attribution, ...await probeProcessOwner2(owner.pid, owner.process), owner };
99
- }
100
148
  var MAX_RECLAIM_DEPTH = 16;
101
149
  var STALE_GUARD_GRACE_MS = 5000;
102
150
  var STAGED_NAME = /^\.lock-[0-9a-f-]{36}\.tmp$/;
103
151
  async function stagedSibling(path, ino, dev) {
104
152
  const directory = dirname(path);
105
- for (const name of await readdir(directory)) {
153
+ for (const name of await readdir2(directory)) {
106
154
  if (!STAGED_NAME.test(name))
107
155
  continue;
108
156
  const candidate = join(directory, name);
@@ -130,6 +178,7 @@ async function readLockFile(path, onFailure, signal) {
130
178
  record = await readLockRecord(path, { signal, singleLink: false });
131
179
  }
132
180
  return {
181
+ path,
133
182
  ...readOwner(record.text),
134
183
  ino: record.info.ino,
135
184
  dev: record.info.dev,
@@ -143,14 +192,14 @@ async function readLockFile(path, onFailure, signal) {
143
192
  }
144
193
  }
145
194
  async function sweepStagedLocks(directory, machine, signal) {
146
- for (const name of await readdir(directory).catch(() => [])) {
195
+ for (const name of await readdir2(directory).catch(() => [])) {
147
196
  if (!STAGED_NAME.test(name))
148
197
  continue;
149
198
  const candidate = join(directory, name);
150
199
  const state = await readLockFile(candidate, undefined, signal);
151
200
  if (!state?.owner)
152
201
  continue;
153
- if ((await diagnose(state.owner, machine)).liveness !== "gone")
202
+ if ((await diagnose(state, machine)).liveness !== "gone")
154
203
  continue;
155
204
  await unlinkIfSame(candidate, state.ino, state.dev, state.stagedName === undefined ? 1 : 2);
156
205
  }
@@ -172,14 +221,14 @@ async function createOwned(path, options, reclaimed) {
172
221
  const owner = {
173
222
  pid: process.pid,
174
223
  process: instance,
175
- host: hostname(),
224
+ host: hostname2(),
176
225
  acquiredAt: new Date().toISOString(),
177
226
  ...identity !== null && { machine: identity }
178
227
  };
179
228
  const ownedRecord = `${JSON.stringify(owner)}
180
229
  `;
181
230
  const staged = join(dirname(path), `.lock-${randomUUID()}.tmp`);
182
- const handle = await open(staged, "wx", options.mode);
231
+ const handle = await open2(staged, "wx", options.mode);
183
232
  let ino;
184
233
  let dev;
185
234
  let published = false;
@@ -271,7 +320,7 @@ async function reclaimUnderGuard(path, options, depth) {
271
320
  if (readFailure !== undefined)
272
321
  return { refused: true, cause: readFailure };
273
322
  if (state) {
274
- const diagnosis = await diagnose(state.owner, options.machineIdentity);
323
+ const diagnosis = await diagnose(state, options.machineIdentity);
275
324
  if (options.signal?.aborted)
276
325
  return { refused: true };
277
326
  if (!reclaimable(state, diagnosis, options.ownerlessGraceMs))
@@ -308,7 +357,7 @@ async function attemptExclusiveLock(path, options, depth = 0) {
308
357
  readFailure = cause;
309
358
  }, options.signal);
310
359
  const diagnosis = {
311
- ...await diagnose(state?.owner, options.machineIdentity),
360
+ ...await diagnose(state, options.machineIdentity),
312
361
  ...readFailure !== undefined && { cause: readFailure }
313
362
  };
314
363
  if (options.signal?.aborted)
@@ -8,17 +8,17 @@ import {
8
8
  validateResolvedInputRounds,
9
9
  presentationMetadata,
10
10
  prepareProjectedMcpTools
11
- } from "./index-q6crhe1n.js";
11
+ } from "./index-h7accrrv.js";
12
12
  import {
13
13
  parseToolCallArguments,
14
14
  toolResultFromError,
15
15
  observed
16
- } from "./index-mha6b4vk.js";
16
+ } from "./index-02h0dfpr.js";
17
17
  import {
18
18
  collectTools2,
19
19
  createToolRunner,
20
20
  formatToolError
21
- } from "./index-ghwntn9n.js";
21
+ } from "./index-vqdjym30.js";
22
22
  import {
23
23
  DEFAULT_CORS_ALLOW_HEADERS2,
24
24
  DEFAULT_PROCESS_SIGNALS,
@@ -31,7 +31,7 @@ import {
31
31
  } from "./index-e6c2spsd.js";
32
32
  import {
33
33
  collectToolSurface
34
- } from "./index-0d8m0kee.js";
34
+ } from "./index-hvg9hctd.js";
35
35
  import {
36
36
  runWithRequestContext2,
37
37
  getRequestContext2
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  attemptExclusiveLock
3
- } from "./index-t2bsd0hm.js";
3
+ } from "./index-5v5a9k2n.js";
4
4
  import {
5
5
  sleep
6
6
  } from "./index-eemvahkc.js";
@@ -2,21 +2,21 @@ import {
2
2
  toolResultFromError,
3
3
  toolCauseFromResult,
4
4
  isToolExecutionControlError2
5
- } from "./index-mha6b4vk.js";
5
+ } from "./index-02h0dfpr.js";
6
6
  import {
7
7
  createToolRunner,
8
8
  formatToolError
9
- } from "./index-ghwntn9n.js";
9
+ } from "./index-vqdjym30.js";
10
10
  import {
11
11
  AgentToolError2,
12
12
  resolveToolDurability
13
13
  } from "./index-56yx8dxp.js";
14
14
  import {
15
15
  collectToolSurface
16
- } from "./index-0d8m0kee.js";
16
+ } from "./index-hvg9hctd.js";
17
17
  import {
18
18
  agentPresenterOf
19
- } from "./index-636mggad.js";
19
+ } from "./index-ff3agzaf.js";
20
20
  import {
21
21
  isRecord
22
22
  } from "./index-9jfdm5tg.js";
@@ -17,7 +17,7 @@ import {
17
17
  replaceMessage,
18
18
  ArchiveSpillSchema,
19
19
  createAgentRuntimeStore2
20
- } from "./index-0z3kfphz.js";
20
+ } from "./index-38gvr73z.js";
21
21
 
22
22
  // src/agent-runtime/store-memory.ts
23
23
  import { z as z2 } from "zod";
@@ -82,6 +82,23 @@ function markJsonSchemaObjectGuards(schema) {
82
82
  };
83
83
  visit(schema);
84
84
  }
85
+ var REMOTE_UNION_VERDICT = Symbol.for("stitchkit.tools.json-schema-remote-union-verdict.v1");
86
+ function markRemoteUnionVerdict(schema) {
87
+ Reflect.defineProperty(schema, REMOTE_UNION_VERDICT, {
88
+ configurable: false,
89
+ enumerable: false,
90
+ value: true,
91
+ writable: false
92
+ });
93
+ }
94
+ function localVerdict(schema, error) {
95
+ if (Reflect.get(schema, REMOTE_UNION_VERDICT) !== true)
96
+ return error;
97
+ const local = error.issues.filter((issue) => issue.code !== "invalid_union");
98
+ if (local.length === 0)
99
+ return null;
100
+ return local.length === error.issues.length ? error : new z.ZodError(local);
101
+ }
85
102
  function jsonSchemaObjectCoercionMembers(schema) {
86
103
  if (Reflect.get(schema, JSON_SCHEMA_OBJECT_GUARD) !== true)
87
104
  return;
@@ -97,4 +114,4 @@ function jsonSchemaObjectCoercionMembers(schema) {
97
114
  return;
98
115
  }
99
116
 
100
- export { markJsonSchemaObjectGuards, jsonSchemaObjectCoercionMembers };
117
+ export { markJsonSchemaObjectGuards, markRemoteUnionVerdict, localVerdict, jsonSchemaObjectCoercionMembers };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  projectRuntimeTool
3
- } from "./index-q6crhe1n.js";
3
+ } from "./index-h7accrrv.js";
4
4
  import {
5
5
  isRecord
6
6
  } from "./index-9jfdm5tg.js";
@@ -19,7 +19,7 @@ import {
19
19
  appendEventIn,
20
20
  ArchiveProjectionSchema,
21
21
  createAgentRuntimeStore2
22
- } from "./index-0z3kfphz.js";
22
+ } from "./index-38gvr73z.js";
23
23
  import {
24
24
  AgentConversationPageSchema2,
25
25
  AgentConversationMessagePageSchema2
@@ -273,7 +273,8 @@ function typeNames(schema) {
273
273
  function typeSchema(type, nullable) {
274
274
  return { type: nullable ? [type, "null"] : type };
275
275
  }
276
- function commonBaseType(schemas) {
276
+ function commonBaseType(variants, discriminator) {
277
+ const schemas = variants.map(({ schema }) => schema);
277
278
  const names = schemas.map(typeNames);
278
279
  if (names.some((value) => value === null))
279
280
  return {};
@@ -293,10 +294,19 @@ function commonBaseType(schemas) {
293
294
  return nullable ? { type: "null" } : {};
294
295
  if (bases.has("array") || bases.has("object")) {
295
296
  const alternatives = new Map;
296
- for (const schema of schemas)
297
- alternatives.set(serializeCanonicalJson(schema), schema);
298
- const ordered = [...alternatives].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([, schema]) => schema);
299
- return { anyOf: structuredClone(ordered) };
297
+ for (const { schema, labels } of variants) {
298
+ const key = serializeCanonicalJson(schema);
299
+ const known = alternatives.get(key);
300
+ if (known)
301
+ known.labels.push(...labels);
302
+ else
303
+ alternatives.set(key, { schema, labels: [...labels] });
304
+ }
305
+ const ordered = [...alternatives].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([, { schema, labels }]) => ({
306
+ ...structuredClone(schema),
307
+ description: `When ${discriminator} = ${[...new Set(labels)].join(" | ")}.`
308
+ }));
309
+ return { anyOf: ordered };
300
310
  }
301
311
  if (bases.size === 1) {
302
312
  const [only] = bases;
@@ -337,7 +347,10 @@ function mergePropertySchemas(properties, discriminator) {
337
347
  } else {
338
348
  const values = schemas.map(stringValues);
339
349
  const allStrings = values.every((value) => value !== null);
340
- merged = allStrings ? { type: "string", enum: [...new Set(values.flatMap((value) => value ?? []))] } : commonBaseType(structural);
350
+ merged = allStrings ? { type: "string", enum: [...new Set(values.flatMap((value) => value ?? []))] } : commonBaseType(structural.map((schema, index) => ({
351
+ schema,
352
+ labels: properties[index]?.labels ?? []
353
+ })), discriminator);
341
354
  }
342
355
  const description = describeVariants(properties.map((property, index) => ({
343
356
  ...property,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  projectToolSurface
3
- } from "./index-q6crhe1n.js";
3
+ } from "./index-h7accrrv.js";
4
4
  import {
5
5
  contractToolMountable
6
- } from "./index-ghwntn9n.js";
6
+ } from "./index-vqdjym30.js";
7
7
  import {
8
8
  runtimeToolMountable
9
- } from "./index-636mggad.js";
9
+ } from "./index-ff3agzaf.js";
10
10
 
11
11
  // src/tools/surface.ts
12
12
  function collectToolSurface({
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  withExclusiveLock2
3
- } from "./index-w9mqgnz9.js";
3
+ } from "./index-6b3pcq5z.js";
4
4
  import {
5
5
  readBoundedFile
6
6
  } from "./index-m616f0yz.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  assertUniqueToolName
3
- } from "./index-q6crhe1n.js";
3
+ } from "./index-h7accrrv.js";
4
4
  import {
5
5
  toolErrorFromResult
6
- } from "./index-mha6b4vk.js";
6
+ } from "./index-02h0dfpr.js";
7
7
  import {
8
8
  collectTools2,
9
9
  createToolRunner
10
- } from "./index-ghwntn9n.js";
10
+ } from "./index-vqdjym30.js";
11
11
  import {
12
12
  AppError2
13
13
  } from "./index-j9gxbztg.js";
@@ -3,10 +3,10 @@ import {
3
3
  } from "./index-fynr93w4.js";
4
4
  import {
5
5
  jsonSchemaObjectCoercionMembers
6
- } from "./index-t5sjh517.js";
6
+ } from "./index-epmnrnth.js";
7
7
  import {
8
8
  coerceJsonArgs2
9
- } from "./index-cykxpxz5.js";
9
+ } from "./index-jy9wq8tp.js";
10
10
  import {
11
11
  jsonSchemaFields
12
12
  } from "./index-ct75c3at.js";
@@ -14,15 +14,15 @@ import {
14
14
  objectShapeKeys,
15
15
  assertUniqueToolName,
16
16
  buildToolPresentationSchema
17
- } from "./index-q6crhe1n.js";
17
+ } from "./index-h7accrrv.js";
18
18
  import {
19
19
  toolResultFromError,
20
20
  toolErrorFromResult
21
- } from "./index-mha6b4vk.js";
21
+ } from "./index-02h0dfpr.js";
22
22
  import {
23
23
  createToolRunner,
24
24
  formatToolError
25
- } from "./index-ghwntn9n.js";
25
+ } from "./index-vqdjym30.js";
26
26
  import {
27
27
  fetchGuarded,
28
28
  readCapped
@@ -35,7 +35,7 @@ import {
35
35
  } from "./index-eemvahkc.js";
36
36
  import {
37
37
  collectToolSurface
38
- } from "./index-0d8m0kee.js";
38
+ } from "./index-hvg9hctd.js";
39
39
  import {
40
40
  isUnsafeKey,
41
41
  safeJsonParse
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  jsonSchemaObjectCoercionMembers
3
- } from "./index-t5sjh517.js";
3
+ } from "./index-epmnrnth.js";
4
4
  import {
5
5
  safeJsonParse
6
6
  } from "./index-zsarb5xp.js";
@@ -27,7 +27,7 @@ import {
27
27
  } from "./index-j4zh647a.js";
28
28
  import {
29
29
  defineRuntimeTool2
30
- } from "./index-636mggad.js";
30
+ } from "./index-ff3agzaf.js";
31
31
  import {
32
32
  AppError2,
33
33
  forbidden2,
@@ -3,11 +3,11 @@ import {
3
3
  mergeSchemas,
4
4
  assertToolExtensionCompatible,
5
5
  projectToolSurface
6
- } from "./index-q6crhe1n.js";
6
+ } from "./index-h7accrrv.js";
7
7
  import {
8
8
  toolErrorFromResult,
9
9
  executeToolMethod
10
- } from "./index-mha6b4vk.js";
10
+ } from "./index-02h0dfpr.js";
11
11
  import {
12
12
  isRetryableStatus2
13
13
  } from "./index-j9gxbztg.js";
@@ -0,0 +1,53 @@
1
+ import { z } from 'zod';
2
+ import { type FileIdentity } from './open-descriptors.js';
3
+ import { type ProcessOwnerEvidence } from './process-instance.js';
4
+ /** Who holds a lock, as its file records it. */
5
+ declare const ExclusiveLockOwnerSchema: z.ZodObject<{
6
+ pid: z.ZodNumber;
7
+ host: z.ZodString;
8
+ acquiredAt: z.ZodString;
9
+ machine: z.ZodCatch<z.ZodOptional<z.ZodString>>;
10
+ process: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
11
+ platform: z.ZodEnum<{
12
+ darwin: "darwin";
13
+ linux: "linux";
14
+ }>;
15
+ bootId: z.ZodString;
16
+ namespace: z.ZodString;
17
+ startId: z.ZodString;
18
+ }, z.core.$strict>>>>;
19
+ }, z.core.$strip>;
20
+ export type ExclusiveLockOwner = z.infer<typeof ExclusiveLockOwnerSchema>;
21
+ /** Why a present lock was or was not taken. */
22
+ export interface ExclusiveLockDiagnosis {
23
+ readonly attribution: 'this-machine' | 'another-machine' | 'unattributable';
24
+ readonly liveness: 'alive' | 'gone' | 'not-probed';
25
+ /**
26
+ * The process evidence, plus `descriptor-closed`: the record names this very process, and no
27
+ * descriptor of this process is open on the lock — an earlier image of the PID left it.
28
+ */
29
+ readonly identity?: ProcessOwnerEvidence['identity'] | 'descriptor-closed';
30
+ readonly owner: ExclusiveLockOwner | null;
31
+ readonly cause?: unknown;
32
+ }
33
+ export declare function readOwner(text: string): {
34
+ owner: ExclusiveLockOwner | undefined;
35
+ ownerless: boolean;
36
+ };
37
+ /** A lock file as read: its recorded owner, if readable, and the file it was read from. */
38
+ export interface RecordedLock extends FileIdentity {
39
+ readonly path: string;
40
+ readonly owner: ExclusiveLockOwner | undefined;
41
+ }
42
+ /**
43
+ * Judge the recorded owner of a lock file that was read, or of none when it was not.
44
+ *
45
+ * A record that names this process with matching kernel identity is held only while a descriptor
46
+ * of this process is open on the file: a holder keeps the descriptor it created the lock with
47
+ * until it releases, in every version that records a process identity. A process image replaced
48
+ * in place keeps its PID and start time but not that descriptor, so the lock it left is gone —
49
+ * judged alive, it would stay held until the PID changed.
50
+ */
51
+ export declare function diagnose(lock: RecordedLock | undefined, declaredIdentity: string | undefined): Promise<ExclusiveLockDiagnosis>;
52
+ export {};
53
+ //# sourceMappingURL=exclusive-lock-owner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclusive-lock-owner.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock-owner.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AAE5E,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,oBAAoB,CAAC;AAG5B,gDAAgD;AAChD,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,+CAA+C;AAC/C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IACnD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,GAAG,mBAAmB,CAAC;IAC3E,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IACvC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACtC,SAAS,EAAE,OAAO,CAAC;CACpB,CAkBA;AAoBD,2FAA2F;AAC3F,MAAM,WAAW,YAAa,SAAQ,YAAY;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAChD;AAED;;;;;;;;GAQG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,YAAY,GAAG,SAAS,EAC9B,gBAAgB,EAAE,MAAM,GAAG,SAAS,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAcjC"}
@@ -1,30 +1,4 @@
1
- import { z } from 'zod';
2
- import { type ProcessOwnerEvidence } from './process-instance.js';
3
- /** Who holds a lock, as its file records it. */
4
- declare const ExclusiveLockOwnerSchema: z.ZodObject<{
5
- pid: z.ZodNumber;
6
- host: z.ZodString;
7
- acquiredAt: z.ZodString;
8
- machine: z.ZodCatch<z.ZodOptional<z.ZodString>>;
9
- process: z.ZodCatch<z.ZodOptional<z.ZodNullable<z.ZodObject<{
10
- platform: z.ZodEnum<{
11
- darwin: "darwin";
12
- linux: "linux";
13
- }>;
14
- bootId: z.ZodString;
15
- namespace: z.ZodString;
16
- startId: z.ZodString;
17
- }, z.core.$strict>>>>;
18
- }, z.core.$strip>;
19
- export type ExclusiveLockOwner = z.infer<typeof ExclusiveLockOwnerSchema>;
20
- /** Why a present lock was not taken. */
21
- export interface ExclusiveLockDiagnosis {
22
- readonly attribution: 'this-machine' | 'another-machine' | 'unattributable';
23
- readonly liveness: 'alive' | 'gone' | 'not-probed';
24
- readonly identity?: ProcessOwnerEvidence['identity'];
25
- readonly owner: ExclusiveLockOwner | null;
26
- readonly cause?: unknown;
27
- }
1
+ import { type ExclusiveLockDiagnosis, type ExclusiveLockOwner } from './exclusive-lock-owner.js';
28
2
  /** A lock this process holds. */
29
3
  export interface HeldExclusiveLock {
30
4
  readonly path: string;
@@ -64,5 +38,4 @@ export type ExclusiveLockAttempt = {
64
38
  export declare function attemptExclusiveLock(path: string, options: ExclusiveLockAttemptOptions, depth?: number): Promise<ExclusiveLockAttempt>;
65
39
  /** Read the owner a present lock records, for a refusal that has to name it. */
66
40
  export declare function readExclusiveLockOwner(path: string): Promise<ExclusiveLockOwner | null>;
67
- export {};
68
41
  //# sourceMappingURL=exclusive-lock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,oBAAoB,CAAC;AAG5B,gDAAgD;AAChD,QAAA,MAAM,wBAAwB;;;;;;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E,wCAAwC;AACxC,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,cAAc,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;IAC5E,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,iCAAiC;AACjC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,uFAAuF;IACvF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GACpC;IACE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;CAC7C,CAAC;AA8VN;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,EACpC,KAAK,SAAI,GACR,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,gFAAgF;AAChF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC"}
1
+ {"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"AA6BA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EAGxB,MAAM,wBAAwB,CAAC;AAMhC,iCAAiC;AACjC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,uFAAuF;IACvF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;CAAE,GACpC;IACE,kDAAkD;IAClD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,sBAAsB,CAAC;CAC7C,CAAC;AAwSN;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,EACpC,KAAK,SAAI,GACR,OAAO,CAAC,oBAAoB,CAAC,CAgC/B;AAED,gFAAgF;AAChF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC"}
@@ -0,0 +1,18 @@
1
+ /** The file a descriptor must refer to, as `stat` identifies it. */
2
+ export interface FileIdentity {
3
+ readonly ino: number;
4
+ readonly dev: number;
5
+ }
6
+ /**
7
+ * `true` when another descriptor of this process refers to the file at `path` — still the file
8
+ * `file` names — `false` when none does, and `null` when that cannot be told: the file is gone or
9
+ * replaced, or the listing is not proven complete. Unknown never proves that a holder is gone.
10
+ *
11
+ * The listing proves itself: the probe opens the file, and the answer counts only when the
12
+ * listing contains that fresh descriptor. A platform that lists a fixed few descriptors (a BSD
13
+ * `/dev/fd` without fdescfs lists 0–2) answers `null`, not a false "nobody holds it".
14
+ */
15
+ export declare function holdsOpenDescriptor(path: string, file: FileIdentity,
16
+ /** @internal A fixture listing; the real one is always this process's own. */
17
+ descriptorDirectory?: string): Promise<boolean | null>;
18
+ //# sourceMappingURL=open-descriptors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-descriptors.d.ts","sourceRoot":"","sources":["../../src/internal/open-descriptors.ts"],"names":[],"mappings":"AAkBA,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,YAAY;AAClB,8EAA8E;AAC9E,mBAAmB,SAAuB,GACzC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAkCzB"}
@@ -1,15 +1,5 @@
1
- /**
2
- * Run work under an exclusive lock between processes, waiting for it within a
3
- * deadline and a cancellation signal.
4
- *
5
- * The waiting is what the journal never needed and every other caller does: a
6
- * registry, a cursor or a mailbox is held for milliseconds, so a second process
7
- * should wait its turn rather than fail. It waits within a bound, stops the
8
- * moment its signal aborts — during the wait, not after it — and a refusal names
9
- * the resource and whoever holds it, so "timed out" is never the whole message.
10
- */
11
- import { type ExclusiveLockOwner } from './exclusive-lock.js';
12
- export type { ExclusiveLockOwner } from './exclusive-lock.js';
1
+ import type { ExclusiveLockOwner } from './exclusive-lock-owner.js';
2
+ export type { ExclusiveLockOwner } from './exclusive-lock-owner.js';
13
3
  /** Options of {@link withExclusiveLock}. */
14
4
  export interface ExclusiveLockOptions {
15
5
  /** What the lock guards, named in a refusal. Defaults to the lock path. */