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.
- package/CHANGELOG.md +21 -0
- package/dist/agent-runtime/coding-shell-process.d.ts.map +1 -1
- package/dist/agent-runtime/sandbox-process-owner.d.ts.map +1 -1
- package/dist/entrypoints/agent-runtime/coding-tools.js +2 -1
- package/dist/entrypoints/agent-runtime/sandbox.js +28 -14
- package/dist/entrypoints/application/diagnostic-journal.js +2 -1
- package/dist/entrypoints/files.js +14 -4
- package/dist/entrypoints/process.d.ts +2 -1
- package/dist/entrypoints/process.d.ts.map +1 -1
- package/dist/entrypoints/process.js +9 -2
- package/dist/index-32jkwkdm.js +565 -0
- package/dist/{index-a4ajxwmb.js → index-g4jxe7ve.js} +113 -131
- package/dist/index-nybn2err.js +213 -0
- package/dist/index-ttf0y7b8.js +246 -0
- package/dist/internal/exclusive-lock-read.d.ts +20 -0
- package/dist/internal/exclusive-lock-read.d.ts.map +1 -0
- package/dist/internal/exclusive-lock.d.ts +3 -1
- package/dist/internal/exclusive-lock.d.ts.map +1 -1
- package/dist/internal/process-instance.d.ts +46 -9
- package/dist/internal/process-instance.d.ts.map +1 -1
- package/dist/internal/with-exclusive-lock.d.ts +4 -3
- package/dist/internal/with-exclusive-lock.d.ts.map +1 -1
- package/dist/process/command-owner.d.ts +7 -2
- package/dist/process/command-owner.d.ts.map +1 -1
- package/dist/process/contract.d.ts +22 -1
- package/dist/process/contract.d.ts.map +1 -1
- package/dist/process/group.d.ts +6 -1
- package/dist/process/group.d.ts.map +1 -1
- package/dist/process/launch.d.ts +65 -0
- package/dist/process/launch.d.ts.map +1 -0
- package/dist/process/leader-settlement.d.ts +6 -0
- package/dist/process/leader-settlement.d.ts.map +1 -0
- package/dist/process/start-failure.d.ts +7 -0
- package/dist/process/start-failure.d.ts.map +1 -0
- package/llms/agent-runtime.txt +7 -1
- package/llms/files.txt +1 -1
- package/llms/process.txt +115 -2
- package/llms-full.txt +123 -4
- package/llms.txt +3 -3
- package/native/darwin-arm64.node +0 -0
- package/native/darwin-x64.node +0 -0
- package/package.json +2 -2
- package/dist/index-7kxw1awn.js +0 -328
- package/dist/index-eeqmg7qm.js +0 -202
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import {
|
|
2
|
+
machineIdentity,
|
|
3
|
+
ProcessInstanceSchema2,
|
|
4
|
+
readProcessInstance,
|
|
5
|
+
probeProcessOwner2
|
|
6
|
+
} from "./index-nybn2err.js";
|
|
7
|
+
import {
|
|
8
|
+
isRecord
|
|
9
|
+
} from "./index-9jfdm5tg.js";
|
|
10
|
+
|
|
11
|
+
// src/internal/exclusive-lock.ts
|
|
12
|
+
import { lstat, open as open2, unlink } from "node:fs/promises";
|
|
13
|
+
import { hostname } from "node:os";
|
|
14
|
+
import { z } from "zod";
|
|
15
|
+
|
|
16
|
+
// src/internal/exclusive-lock-read.ts
|
|
17
|
+
import { constants } from "node:fs";
|
|
18
|
+
import { open } from "node:fs/promises";
|
|
19
|
+
var OWNER_RECORD_BYTES = 16 * 1024;
|
|
20
|
+
|
|
21
|
+
class LockRecordError extends Error {
|
|
22
|
+
code;
|
|
23
|
+
name = "LockRecordError";
|
|
24
|
+
constructor(code, message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.code = code;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function readLockRecord(path, openDescriptor = open, signal) {
|
|
30
|
+
signal?.throwIfAborted();
|
|
31
|
+
if (!constants.O_NOFOLLOW || !constants.O_NONBLOCK) {
|
|
32
|
+
throw new LockRecordError("LOCK_UNSAFE_RECORD", "Safe lock descriptor flags are unavailable");
|
|
33
|
+
}
|
|
34
|
+
const handle = await openDescriptor(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
35
|
+
try {
|
|
36
|
+
signal?.throwIfAborted();
|
|
37
|
+
const before = await handle.stat();
|
|
38
|
+
signal?.throwIfAborted();
|
|
39
|
+
if (!before.isFile() || before.nlink !== 1) {
|
|
40
|
+
throw new LockRecordError("LOCK_UNSAFE_RECORD", "Lock record must be a regular file with one link");
|
|
41
|
+
}
|
|
42
|
+
if (before.size > OWNER_RECORD_BYTES) {
|
|
43
|
+
throw new LockRecordError("LOCK_RECORD_TOO_LARGE", "Lock owner record exceeds its byte cap");
|
|
44
|
+
}
|
|
45
|
+
const bytes = Buffer.alloc(OWNER_RECORD_BYTES + 1);
|
|
46
|
+
let length = 0;
|
|
47
|
+
while (length < bytes.length) {
|
|
48
|
+
signal?.throwIfAborted();
|
|
49
|
+
const read = await handle.read(bytes, length, bytes.length - length, length);
|
|
50
|
+
if (read.bytesRead === 0)
|
|
51
|
+
break;
|
|
52
|
+
length += read.bytesRead;
|
|
53
|
+
}
|
|
54
|
+
if (length > OWNER_RECORD_BYTES) {
|
|
55
|
+
throw new LockRecordError("LOCK_RECORD_TOO_LARGE", "Lock owner record grew beyond its byte cap");
|
|
56
|
+
}
|
|
57
|
+
const after = await handle.stat();
|
|
58
|
+
signal?.throwIfAborted();
|
|
59
|
+
if (before.dev !== after.dev || before.ino !== after.ino || before.size !== after.size || before.mtimeMs !== after.mtimeMs || before.ctimeMs !== after.ctimeMs || before.nlink !== after.nlink || length !== after.size) {
|
|
60
|
+
throw new LockRecordError("LOCK_RECORD_CHANGED", "Lock owner record changed during its read");
|
|
61
|
+
}
|
|
62
|
+
return { text: bytes.subarray(0, length).toString("utf8"), info: after };
|
|
63
|
+
} finally {
|
|
64
|
+
await handle.close();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/internal/exclusive-lock.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 isCode(error, code) {
|
|
77
|
+
return isRecord(error) && error.code === code;
|
|
78
|
+
}
|
|
79
|
+
function readOwner(text) {
|
|
80
|
+
let parsed;
|
|
81
|
+
try {
|
|
82
|
+
parsed = JSON.parse(text);
|
|
83
|
+
} catch {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const owner = ExclusiveLockOwnerSchema.safeParse(parsed);
|
|
87
|
+
return owner.success ? owner.data : undefined;
|
|
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(owner, declaredIdentity) {
|
|
96
|
+
if (!owner)
|
|
97
|
+
return { attribution: "unattributable", liveness: "not-probed", owner: null };
|
|
98
|
+
const attribution = attribute(owner, await machineIdentity(declaredIdentity));
|
|
99
|
+
if (attribution !== "this-machine")
|
|
100
|
+
return { attribution, liveness: "not-probed", owner };
|
|
101
|
+
return { attribution, ...await probeProcessOwner2(owner.pid, owner.process), owner };
|
|
102
|
+
}
|
|
103
|
+
async function readLockFile(path, onFailure, signal) {
|
|
104
|
+
try {
|
|
105
|
+
const record = await readLockRecord(path, undefined, signal);
|
|
106
|
+
return {
|
|
107
|
+
owner: readOwner(record.text),
|
|
108
|
+
ino: record.info.ino,
|
|
109
|
+
dev: record.info.dev,
|
|
110
|
+
mtimeMs: record.info.mtimeMs
|
|
111
|
+
};
|
|
112
|
+
} catch (cause) {
|
|
113
|
+
if (!isCode(cause, "ENOENT"))
|
|
114
|
+
onFailure?.(cause);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async function unlinkIfSame(path, ino, dev) {
|
|
119
|
+
try {
|
|
120
|
+
const current = await lstat(path);
|
|
121
|
+
if (current.ino !== ino || current.dev !== dev || !current.isFile() || current.nlink !== 1)
|
|
122
|
+
return;
|
|
123
|
+
await unlink(path);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (!isCode(error, "ENOENT"))
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function createOwned(path, options, reclaimed) {
|
|
130
|
+
const identity = await machineIdentity(options.machineIdentity);
|
|
131
|
+
const instance = await readProcessInstance(process.pid);
|
|
132
|
+
const handle = await open2(path, "wx", options.mode);
|
|
133
|
+
const owner = {
|
|
134
|
+
pid: process.pid,
|
|
135
|
+
process: instance,
|
|
136
|
+
host: hostname(),
|
|
137
|
+
acquiredAt: new Date().toISOString(),
|
|
138
|
+
...identity !== null && { machine: identity }
|
|
139
|
+
};
|
|
140
|
+
let ino;
|
|
141
|
+
let dev;
|
|
142
|
+
try {
|
|
143
|
+
const info = await handle.stat();
|
|
144
|
+
ino = info.ino;
|
|
145
|
+
dev = info.dev;
|
|
146
|
+
await handle.chmod(options.mode);
|
|
147
|
+
await handle.writeFile(`${JSON.stringify(owner)}
|
|
148
|
+
`, "utf8");
|
|
149
|
+
} catch (error) {
|
|
150
|
+
await handle.close().catch(() => {
|
|
151
|
+
return;
|
|
152
|
+
});
|
|
153
|
+
if (ino !== undefined && dev !== undefined)
|
|
154
|
+
await unlinkIfSame(path, ino, dev).catch(() => {
|
|
155
|
+
return;
|
|
156
|
+
});
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
const ownedInode = ino;
|
|
160
|
+
const ownedDevice = dev;
|
|
161
|
+
let released = false;
|
|
162
|
+
return {
|
|
163
|
+
path,
|
|
164
|
+
owner,
|
|
165
|
+
reclaimed,
|
|
166
|
+
async release() {
|
|
167
|
+
if (released)
|
|
168
|
+
return;
|
|
169
|
+
released = true;
|
|
170
|
+
try {
|
|
171
|
+
await handle.close();
|
|
172
|
+
} finally {
|
|
173
|
+
await unlinkIfSame(path, ownedInode, ownedDevice);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function reclaimable(state, diagnosis, graceMs) {
|
|
179
|
+
if (state.owner)
|
|
180
|
+
return diagnosis.liveness === "gone";
|
|
181
|
+
return typeof graceMs === "number" && Date.now() - state.mtimeMs >= graceMs;
|
|
182
|
+
}
|
|
183
|
+
async function reclaimUnderGuard(path, options) {
|
|
184
|
+
const guardPath = `${path}.reclaim`;
|
|
185
|
+
const acquired = await attemptExclusiveLock(guardPath, {
|
|
186
|
+
...options,
|
|
187
|
+
ownerlessGraceMs: options.ownerlessGraceMs === undefined ? 5000 : options.ownerlessGraceMs
|
|
188
|
+
});
|
|
189
|
+
if (!("held" in acquired))
|
|
190
|
+
return;
|
|
191
|
+
const guard = acquired.held;
|
|
192
|
+
try {
|
|
193
|
+
let unsafe = false;
|
|
194
|
+
const state = await readLockFile(path, () => {
|
|
195
|
+
unsafe = true;
|
|
196
|
+
}, options.signal);
|
|
197
|
+
if (unsafe)
|
|
198
|
+
return "refused";
|
|
199
|
+
if (state) {
|
|
200
|
+
const diagnosis = await diagnose(state.owner, options.machineIdentity);
|
|
201
|
+
if (options.signal?.aborted)
|
|
202
|
+
return "refused";
|
|
203
|
+
if (!reclaimable(state, diagnosis, options.ownerlessGraceMs))
|
|
204
|
+
return "refused";
|
|
205
|
+
await unlinkIfSame(path, state.ino, state.dev);
|
|
206
|
+
}
|
|
207
|
+
return await createOwned(path, options, state !== undefined).catch((error) => {
|
|
208
|
+
if (isCode(error, "EEXIST"))
|
|
209
|
+
return "refused";
|
|
210
|
+
throw error;
|
|
211
|
+
});
|
|
212
|
+
} finally {
|
|
213
|
+
await guard.release().catch(() => {
|
|
214
|
+
return;
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function attemptExclusiveLock(path, options) {
|
|
219
|
+
try {
|
|
220
|
+
return { held: await createOwned(path, options, false) };
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (!isCode(error, "EEXIST"))
|
|
223
|
+
throw error;
|
|
224
|
+
if (!options.reclaim)
|
|
225
|
+
return { error };
|
|
226
|
+
let readFailure;
|
|
227
|
+
const state = await readLockFile(path, (cause) => {
|
|
228
|
+
readFailure = cause;
|
|
229
|
+
}, options.signal);
|
|
230
|
+
const diagnosis = {
|
|
231
|
+
...await diagnose(state?.owner, options.machineIdentity),
|
|
232
|
+
...readFailure !== undefined && { cause: readFailure }
|
|
233
|
+
};
|
|
234
|
+
if (options.signal?.aborted)
|
|
235
|
+
return { error, diagnosis };
|
|
236
|
+
if (!state || !reclaimable(state, diagnosis, options.ownerlessGraceMs)) {
|
|
237
|
+
return { error, diagnosis };
|
|
238
|
+
}
|
|
239
|
+
const reclaimed = await reclaimUnderGuard(path, options);
|
|
240
|
+
if (reclaimed !== undefined && reclaimed !== "refused")
|
|
241
|
+
return { held: reclaimed };
|
|
242
|
+
return { error, diagnosis };
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export { attemptExclusiveLock };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Stats } from 'node:fs';
|
|
2
|
+
interface LockRecordDescriptor {
|
|
3
|
+
stat(): Promise<Stats>;
|
|
4
|
+
read(buffer: Buffer, offset: number, length: number, position: number): Promise<{
|
|
5
|
+
bytesRead: number;
|
|
6
|
+
}>;
|
|
7
|
+
close(): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare class LockRecordError extends Error {
|
|
10
|
+
readonly code: 'LOCK_UNSAFE_RECORD' | 'LOCK_RECORD_CHANGED' | 'LOCK_RECORD_TOO_LARGE';
|
|
11
|
+
name: string;
|
|
12
|
+
constructor(code: 'LOCK_UNSAFE_RECORD' | 'LOCK_RECORD_CHANGED' | 'LOCK_RECORD_TOO_LARGE', message: string);
|
|
13
|
+
}
|
|
14
|
+
/** A descriptor-bound observation, never a pathname stat followed by an unbounded read. */
|
|
15
|
+
export declare function readLockRecord(path: string, openDescriptor?: (path: string, flags: number) => Promise<LockRecordDescriptor>, signal?: AbortSignal): Promise<{
|
|
16
|
+
text: string;
|
|
17
|
+
info: Stats;
|
|
18
|
+
}>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=exclusive-lock-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exclusive-lock-read.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock-read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAMhD,UAAU,oBAAoB;IAC5B,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC;IACvB,IAAI,CACF,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IAGtC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,GAAG,qBAAqB,GAAG,uBAAuB;IAF9E,IAAI,SAAqB;IAClC,YACW,IAAI,EAAE,oBAAoB,GAAG,qBAAqB,GAAG,uBAAuB,EACrF,OAAO,EAAE,MAAM,EAGhB;CACF;AAED,2FAA2F;AAC3F,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,cAAc,GAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAQ,EACrF,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CA8DxC"}
|
|
@@ -23,6 +23,7 @@ export interface ExclusiveLockDiagnosis {
|
|
|
23
23
|
readonly liveness: 'alive' | 'gone' | 'not-probed';
|
|
24
24
|
readonly identity?: ProcessOwnerEvidence['identity'];
|
|
25
25
|
readonly owner: ExclusiveLockOwner | null;
|
|
26
|
+
readonly cause?: unknown;
|
|
26
27
|
}
|
|
27
28
|
/** A lock this process holds. */
|
|
28
29
|
export interface HeldExclusiveLock {
|
|
@@ -34,6 +35,7 @@ export interface HeldExclusiveLock {
|
|
|
34
35
|
release(): Promise<void>;
|
|
35
36
|
}
|
|
36
37
|
export interface ExclusiveLockAttemptOptions {
|
|
38
|
+
readonly signal?: AbortSignal;
|
|
37
39
|
readonly mode: number;
|
|
38
40
|
/** Take a lock whose owner is provably gone. `false` refuses every present lock. */
|
|
39
41
|
readonly reclaim: boolean;
|
|
@@ -42,7 +44,7 @@ export interface ExclusiveLockAttemptOptions {
|
|
|
42
44
|
* How old a lock with no readable owner must be before it is taken. Absent,
|
|
43
45
|
* an ownerless lock is never taken — it may predate owner records.
|
|
44
46
|
*/
|
|
45
|
-
readonly ownerlessGraceMs?: number;
|
|
47
|
+
readonly ownerlessGraceMs?: number | null;
|
|
46
48
|
}
|
|
47
49
|
export type ExclusiveLockAttempt = {
|
|
48
50
|
readonly held: HeldExclusiveLock;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/exclusive-lock.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,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,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;AAkMN;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,oBAAoB,CAAC,CA0B/B;AAED,gFAAgF;AAChF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAEpC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { probeLiveness } from './process-identity.js';
|
|
3
2
|
export declare const ProcessInstanceSchema: z.ZodObject<{
|
|
4
3
|
platform: z.ZodEnum<{
|
|
5
4
|
darwin: "darwin";
|
|
@@ -10,17 +9,55 @@ export declare const ProcessInstanceSchema: z.ZodObject<{
|
|
|
10
9
|
startId: z.ZodString;
|
|
11
10
|
}, z.core.$strict>;
|
|
12
11
|
export type ProcessInstance = z.infer<typeof ProcessInstanceSchema>;
|
|
12
|
+
/** An unavailable observation preserves its native or validation cause; it never proves death. */
|
|
13
|
+
declare const ProcessInstanceObservationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
14
|
+
state: z.ZodLiteral<"observed">;
|
|
15
|
+
instance: z.ZodObject<{
|
|
16
|
+
platform: z.ZodEnum<{
|
|
17
|
+
darwin: "darwin";
|
|
18
|
+
linux: "linux";
|
|
19
|
+
}>;
|
|
20
|
+
bootId: z.ZodString;
|
|
21
|
+
namespace: z.ZodString;
|
|
22
|
+
startId: z.ZodString;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
25
|
+
state: z.ZodLiteral<"unavailable">;
|
|
26
|
+
cause: z.ZodUnknown;
|
|
27
|
+
}, z.core.$strip>], "state">;
|
|
28
|
+
export type ProcessInstanceObservation = z.infer<typeof ProcessInstanceObservationSchema>;
|
|
29
|
+
export declare function observeProcessInstance(pid: number): Promise<ProcessInstanceObservation>;
|
|
13
30
|
/** /proc stat field 22 follows a command name that may itself contain spaces and parentheses. */
|
|
14
31
|
export declare function linuxProcessStart(stat: string, pid: number): string | null;
|
|
15
32
|
/** @internal procRoot permits kernel-format fixtures without changing a real process or boot. */
|
|
16
33
|
export declare function readProcessInstance(pid: number, procRoot?: string): Promise<ProcessInstance | null>;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
34
|
+
/** @internal The fixture root is never a public owner option. */
|
|
35
|
+
export declare function observeProcessInstanceAt(pid: number, procRoot: string): Promise<ProcessInstanceObservation>;
|
|
36
|
+
declare const ProcessOwnerEvidenceSchema: z.ZodObject<{
|
|
37
|
+
liveness: z.ZodEnum<{
|
|
38
|
+
alive: "alive";
|
|
39
|
+
gone: "gone";
|
|
40
|
+
"not-probed": "not-probed";
|
|
41
|
+
}>;
|
|
42
|
+
identity: z.ZodEnum<{
|
|
43
|
+
"different-boot": "different-boot";
|
|
44
|
+
legacy: "legacy";
|
|
45
|
+
matched: "matched";
|
|
46
|
+
"pid-gone": "pid-gone";
|
|
47
|
+
"reused-pid": "reused-pid";
|
|
48
|
+
unavailable: "unavailable";
|
|
49
|
+
}>;
|
|
50
|
+
cause: z.ZodOptional<z.ZodUnknown>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type ProcessOwnerEvidence = z.infer<typeof ProcessOwnerEvidenceSchema>;
|
|
21
53
|
/** Compare identities only inside one machine (the caller establishes that boundary). */
|
|
22
|
-
export declare function probeProcessOwner(pid: number, recorded: ProcessInstance | null | undefined
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
54
|
+
export declare function probeProcessOwner(pid: number, recorded: ProcessInstance | null | undefined): Promise<ProcessOwnerEvidence>;
|
|
55
|
+
interface ProcessOwnerProbes {
|
|
56
|
+
read(pid: number): Promise<ProcessInstance | null>;
|
|
57
|
+
liveness(pid: number): Promise<'alive' | 'gone'>;
|
|
58
|
+
observe?(pid: number): Promise<ProcessInstanceObservation>;
|
|
59
|
+
}
|
|
60
|
+
/** @internal Injection is for kernel-format controls, not a public ownership assertion. */
|
|
61
|
+
export declare function probeProcessOwnerWith(pid: number, recorded: ProcessInstance | null | undefined, probes?: ProcessOwnerProbes): Promise<ProcessOwnerEvidence>;
|
|
62
|
+
export {};
|
|
26
63
|
//# sourceMappingURL=process-instance.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-instance.d.ts","sourceRoot":"","sources":["../../src/internal/process-instance.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"process-instance.d.ts","sourceRoot":"","sources":["../../src/internal/process-instance.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,qBAAqB;;;;;;;;kBAOvB,CAAC;AACZ,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,kGAAkG;AAClG,QAAA,MAAM,gCAAgC;;;;;;;;;;;;;;4BAGpC,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAE1F,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,0BAA0B,CAAC,CAGrC;AAED,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS1E;AAED,iGAAiG;AACjG,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,QAAQ,SAAU,GACjB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAGjC;AAED,iEAAiE;AACjE,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,0BAA0B,CAAC,CAsDrC;AAED,QAAA,MAAM,0BAA0B;;;;;;;;;;;;;;;iBAW9B,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,yFAAyF;AACzF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAC3C,OAAO,CAAC,oBAAoB,CAAC,CAQ/B;AAED,UAAU,kBAAkB;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,CAAC;IACjD,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CAC5D;AAED,2FAA2F;AAC3F,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EAC5C,MAAM,GAAE,kBAA2E,GAClF,OAAO,CAAC,oBAAoB,CAAC,CA2C/B"}
|
|
@@ -18,7 +18,7 @@ export interface ExclusiveLockOptions {
|
|
|
18
18
|
timeoutMs?: number;
|
|
19
19
|
/** Stops the wait; an abort while waiting rejects at once with its reason as the cause. */
|
|
20
20
|
signal?: AbortSignal;
|
|
21
|
-
/**
|
|
21
|
+
/** Exact permission bits, independent of umask. Default `0o600`. Shared readers need a common group and traversable parents. */
|
|
22
22
|
mode?: number;
|
|
23
23
|
/**
|
|
24
24
|
* This machine's identity, for a platform that offers none (`/etc/machine-id`
|
|
@@ -29,9 +29,10 @@ export interface ExclusiveLockOptions {
|
|
|
29
29
|
/**
|
|
30
30
|
* How old a lock with no readable owner must be before it is taken — the one
|
|
31
31
|
* case where time decides, left by a process that died between creating the
|
|
32
|
-
* file and recording itself. Default 5 000
|
|
32
|
+
* file and recording itself. Default 5 000; `null` disables age-based reclaim,
|
|
33
|
+
* including abandoned ownerless reclaim guards.
|
|
33
34
|
*/
|
|
34
|
-
ownerlessGraceMs?: number;
|
|
35
|
+
ownerlessGraceMs?: number | null;
|
|
35
36
|
}
|
|
36
37
|
/** The lock `run` executes under. */
|
|
37
38
|
export interface ExclusiveLock {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/with-exclusive-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,
|
|
1
|
+
{"version":3,"file":"with-exclusive-lock.d.ts","sourceRoot":"","sources":["../../src/internal/with-exclusive-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAGL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAE1B,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,4CAA4C;AAC5C,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gGAAgG;IAChG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gIAAgI;IAChI,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED,qEAAqE;AACrE,qBAAa,kBAAmB,SAAQ,KAAK;IAGzC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,cAAc;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,wFAAwF;IACxF,QAAQ,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IALnC,IAAI,SAAwB;IACrC,YACW,IAAI,EAAE,cAAc,GAAG,cAAc,EACrC,KAAK,EAAE,MAAM;IACtB,wFAAwF;IAC/E,MAAM,EAAE,kBAAkB,GAAG,IAAI,EAC1C,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAG9B;CACF;AAyCD;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC5C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,CAAC,CAAC,CAuEZ"}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
2
2
|
import { type NativeCommandOptions } from './contract.js';
|
|
3
|
+
import { type NativeCommandLaunchDriver } from './launch.js';
|
|
3
4
|
/** One-shot native execution; sandbox policy/admission is composed above this owner. */
|
|
4
|
-
export declare function startNativeCommand(input: NativeCommandOptions, onSpawn?: (child: ChildProcessWithoutNullStreams) => void): {
|
|
5
|
+
export declare function startNativeCommand(input: NativeCommandOptions, onSpawn?: (child: ChildProcessWithoutNullStreams) => void, driver?: NativeCommandLaunchDriver): {
|
|
6
|
+
result: Promise<never>;
|
|
7
|
+
stop(): Promise<void>;
|
|
8
|
+
} | {
|
|
5
9
|
result: Promise<{
|
|
6
10
|
exitCode: number | null;
|
|
7
11
|
signal: string | null;
|
|
8
12
|
stdout: Uint8Array<ArrayBuffer>;
|
|
9
13
|
stderr: Uint8Array<ArrayBuffer>;
|
|
10
14
|
}>;
|
|
15
|
+
terminate(): Promise<void>;
|
|
11
16
|
stop(): Promise<void>;
|
|
12
17
|
};
|
|
13
18
|
//# sourceMappingURL=command-owner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"command-owner.d.ts","sourceRoot":"","sources":["../../src/process/command-owner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AAEzE,OAAO,EAEL,KAAK,oBAAoB,EAG1B,MAAM,YAAY,CAAC;AAOpB,OAAO,EAEL,KAAK,yBAAyB,EAG/B,MAAM,UAAU,CAAC;AAIlB,wFAAwF;AACxF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,oBAAoB,EAC3B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,8BAA8B,KAAK,IAAI,EACzD,MAAM,CAAC,EAAE,yBAAyB;;;;;;;;;;;;EA+LnC"}
|
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
declare const NativeCommandSettlementSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
kind: z.ZodLiteral<"exit">;
|
|
4
|
+
exitCode: z.ZodNullable<z.ZodNumber>;
|
|
5
|
+
signal: z.ZodNullable<z.ZodString>;
|
|
6
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
7
|
+
kind: z.ZodLiteral<"error">;
|
|
8
|
+
cause: z.ZodUnknown;
|
|
9
|
+
}, z.core.$strip>], "kind">;
|
|
10
|
+
export type NativeCommandSettlement = z.infer<typeof NativeCommandSettlementSchema>;
|
|
2
11
|
export declare const NativeCommandOptionsSchema: z.ZodObject<{
|
|
3
12
|
executable: z.ZodString;
|
|
4
13
|
args: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
@@ -15,6 +24,7 @@ export declare const NativeCommandOptionsSchema: z.ZodObject<{
|
|
|
15
24
|
stdin: z.ZodOptional<z.ZodCustom<Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>>>;
|
|
16
25
|
maxStdinBytes: z.ZodDefault<z.ZodNumber>;
|
|
17
26
|
onOutput: z.ZodOptional<z.ZodCustom<(bytes: Uint8Array, channel: 'stdout' | 'stderr', signal: AbortSignal) => void | Promise<void>, (bytes: Uint8Array, channel: 'stdout' | 'stderr', signal: AbortSignal) => void | Promise<void>>>;
|
|
27
|
+
onLeaderSettled: z.ZodOptional<z.ZodCustom<(event: NativeCommandSettlement, signal: AbortSignal) => void | Promise<void>, (event: NativeCommandSettlement, signal: AbortSignal) => void | Promise<void>>>;
|
|
18
28
|
killGraceMs: z.ZodDefault<z.ZodNumber>;
|
|
19
29
|
cleanupTimeoutMs: z.ZodDefault<z.ZodNumber>;
|
|
20
30
|
}, z.core.$strict>;
|
|
@@ -27,9 +37,20 @@ declare const NativeCommandResultSchema: z.ZodObject<{
|
|
|
27
37
|
stderr: z.ZodInstanceOf<Uint8Array<ArrayBuffer>>;
|
|
28
38
|
}, z.core.$strip>;
|
|
29
39
|
export type NativeCommandResult = z.infer<typeof NativeCommandResultSchema>;
|
|
40
|
+
declare const NativeCommandLimitReasonSchema: z.ZodEnum<{
|
|
41
|
+
deadline: "deadline";
|
|
42
|
+
"output-budget": "output-budget";
|
|
43
|
+
}>;
|
|
30
44
|
export declare class NativeCommandError extends Error {
|
|
31
45
|
readonly code: 'COMMAND_LIMIT' | 'COMMAND_UNAVAILABLE' | 'COMMAND_CLEANUP';
|
|
32
|
-
|
|
46
|
+
/** Observed owner limit; absent on non-limit and caller-constructed errors without evidence. */
|
|
47
|
+
readonly reason: z.infer<typeof NativeCommandLimitReasonSchema> | undefined;
|
|
48
|
+
constructor(code: 'COMMAND_LIMIT', message: string, options?: ErrorOptions & {
|
|
49
|
+
reason?: z.infer<typeof NativeCommandLimitReasonSchema>;
|
|
50
|
+
});
|
|
51
|
+
constructor(code: 'COMMAND_LIMIT' | 'COMMAND_UNAVAILABLE' | 'COMMAND_CLEANUP', message: string, options?: ErrorOptions & {
|
|
52
|
+
reason?: never;
|
|
53
|
+
});
|
|
33
54
|
}
|
|
34
55
|
export {};
|
|
35
56
|
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -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;AAExB,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;gDAoBtB,UAAU,WACR,QAAQ,GAAG,QAAQ,UACpB,WAAW,KAChB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;;;
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/process/contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,6BAA6B;;;;;;;2BAOjC,CAAC;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;gDAoBtB,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;;;kBAiBvF,CAAC;AACL,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;;;;;iBAK7B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,QAAA,MAAM,8BAA8B;;;EAAwC,CAAC;AAE7E,qBAAa,kBAAmB,SAAQ,KAAK;aAezB,IAAI,EAAE,eAAe,GAAG,qBAAqB,GAAG,iBAAiB;IAdnF,gGAAgG;IAChG,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;CAeH"}
|
package/dist/process/group.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { NativeCommandError } from './contract.js';
|
|
2
|
+
/** Chain native-sized timers; internal callers retain their declared safe-integer deadline. */
|
|
3
|
+
export declare function createCommandDeadline(timeoutMs: number, reason: unknown): {
|
|
4
|
+
signal: AbortSignal;
|
|
5
|
+
cancel(): void;
|
|
6
|
+
};
|
|
2
7
|
export declare function signalGroup(pid: number | undefined, signal: NodeJS.Signals): void;
|
|
3
|
-
export declare function stopCommandGroup(pid: number | undefined, graceMs: number): Promise<void>;
|
|
8
|
+
export declare function stopCommandGroup(pid: number | undefined, graceMs: number, cleanupTimeoutMs?: number, force?: boolean): Promise<void>;
|
|
4
9
|
export declare function commandCleanupError(cause: unknown): NativeCommandError;
|
|
5
10
|
export declare function waitForCommandClose<T>(closed: Promise<T>, timeoutMs: number): Promise<T>;
|
|
6
11
|
//# sourceMappingURL=group.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/process/group.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAOjF;
|
|
1
|
+
{"version":3,"file":"group.d.ts","sourceRoot":"","sources":["../../src/process/group.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAEhD,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;IAapE,MAAM;IACN,MAAM;EAIT;AAWD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,IAAI,CAOjF;AAiCD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,MAAM,EACf,gBAAgB,SAAO,EACvB,KAAK,UAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAItE;AAED,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAMxF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type ChildProcessWithoutNullStreams } from 'node:child_process';
|
|
2
|
+
import { type ParsedNativeCommandOptions } from './contract.js';
|
|
3
|
+
/** A structural host launcher may supply pipes without importing Node ambient types. */
|
|
4
|
+
export interface NativeCommandLaunchedProcess {
|
|
5
|
+
readonly pid?: number;
|
|
6
|
+
readonly exitCode: number | null;
|
|
7
|
+
readonly signalCode: string | null;
|
|
8
|
+
readonly stdout: NativeCommandLaunchedOutput;
|
|
9
|
+
readonly stderr: NativeCommandLaunchedOutput;
|
|
10
|
+
kill(signal: 'SIGKILL'): boolean;
|
|
11
|
+
on(event: 'error', listener: (error: Error) => void): unknown;
|
|
12
|
+
on(event: 'exit' | 'close', listener: (code: number | null, signal: string | null) => void): unknown;
|
|
13
|
+
}
|
|
14
|
+
interface NativeCommandLaunchedOutput {
|
|
15
|
+
readonly destroyed: boolean;
|
|
16
|
+
on(event: 'data', listener: (chunk: Uint8Array) => void): unknown;
|
|
17
|
+
destroy(): unknown;
|
|
18
|
+
}
|
|
19
|
+
/** Internal transport selection; application policy never enters the public command contract. */
|
|
20
|
+
export interface NativeCommandLaunchDriver {
|
|
21
|
+
launch?: () => NativeCommandLaunchedProcess;
|
|
22
|
+
maxBufferedBytes?: number;
|
|
23
|
+
group?: boolean;
|
|
24
|
+
force?: boolean;
|
|
25
|
+
cleanupTimeoutMs?: number;
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
closeTimeoutMs?: number;
|
|
28
|
+
}
|
|
29
|
+
/** Driver overrides retain the same finite, safe-integer budget admission. */
|
|
30
|
+
export declare function nativeCommandBudgets(options: ParsedNativeCommandOptions, driver: NativeCommandLaunchDriver | undefined): {
|
|
31
|
+
cleanupTimeoutMs: number;
|
|
32
|
+
timeoutMs: number | undefined;
|
|
33
|
+
};
|
|
34
|
+
interface NativeCommandOwner {
|
|
35
|
+
result: Promise<unknown>;
|
|
36
|
+
stop(): Promise<void>;
|
|
37
|
+
terminate(): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
/** A launcher and its admission owner share the execution owner's shutdown barrier. */
|
|
40
|
+
export declare function registerNativeCommandOwner(child: object, owner: NativeCommandOwner): void;
|
|
41
|
+
export declare function nativeCommandOwner(child: object): NativeCommandOwner | undefined;
|
|
42
|
+
/** Install every observation before starting stdin or invoking an admission callback. */
|
|
43
|
+
export declare function launchNativeCommand(options: ParsedNativeCommandOptions, driver: NativeCommandLaunchDriver | undefined, onSpawn: ((child: ChildProcessWithoutNullStreams) => void) | undefined, onFailure: (error: Error) => void, onInputFailure: (error: Error) => void): {
|
|
44
|
+
child: NativeCommandLaunchedProcess;
|
|
45
|
+
stdout: AsyncIterable<Uint8Array<ArrayBufferLike>>;
|
|
46
|
+
stderr: AsyncIterable<Uint8Array<ArrayBufferLike>>;
|
|
47
|
+
leader: Promise<{
|
|
48
|
+
kind: "exit";
|
|
49
|
+
exitCode: number | null;
|
|
50
|
+
signal: string | null;
|
|
51
|
+
} | {
|
|
52
|
+
kind: "error";
|
|
53
|
+
cause: unknown;
|
|
54
|
+
}>;
|
|
55
|
+
closed: Promise<{
|
|
56
|
+
exitCode: number | null;
|
|
57
|
+
signal: string | null;
|
|
58
|
+
}>;
|
|
59
|
+
released: Promise<[boolean, ...boolean[]]>;
|
|
60
|
+
pendingHandles: Set<string>;
|
|
61
|
+
start(): void;
|
|
62
|
+
destroy(): void;
|
|
63
|
+
};
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch.d.ts","sourceRoot":"","sources":["../../src/process/launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,8BAA8B,EAAS,MAAM,oBAAoB,CAAC;AAEhF,OAAO,EAGL,KAAK,0BAA0B,EAChC,MAAM,YAAY,CAAC;AAEpB,wFAAwF;AACxF,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IACjC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAC;IAC9D,EAAE,CACA,KAAK,EAAE,MAAM,GAAG,OAAO,EACvB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAC7D,OAAO,CAAC;CACZ;AAED,UAAU,2BAA2B;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,OAAO,CAAC;IAClE,OAAO,IAAI,OAAO,CAAC;CACpB;AAED,iGAAiG;AACjG,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE,MAAM,4BAA4B,CAAC;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,0BAA0B,EACnC,MAAM,EAAE,yBAAyB,GAAG,SAAS;;;EAY9C;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACzB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAGD,uFAAuF;AACvF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAEzF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEhF;AA4ED,yFAAyF;AACzF,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,0BAA0B,EACnC,MAAM,EAAE,yBAAyB,GAAG,SAAS,EAC7C,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE,8BAA8B,KAAK,IAAI,CAAC,GAAG,SAAS,EACtE,SAAS,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,EACjC,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI;;;;;;;;;;;;;kBAuBC,MAAM,GAAG,IAAI;gBAAU,MAAM,GAAG,IAAI;;;;;;EA0D5E"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { NativeCommandSettlement, ParsedNativeCommandOptions } from './contract.js';
|
|
2
|
+
/** An internal caller may bound drain/close after leader settlement without changing generic drain. */
|
|
3
|
+
export declare function createLeaderCloseDeadline(leader: Promise<NativeCommandSettlement>, timeoutMs: number | undefined, controller: AbortController): () => void;
|
|
4
|
+
/** One bounded external resource settlement, shared by observed exit and terminal failure. */
|
|
5
|
+
export declare function createLeaderSettlement(options: ParsedNativeCommandOptions, signal: AbortSignal): (event: NativeCommandSettlement) => Promise<void>;
|
|
6
|
+
//# sourceMappingURL=leader-settlement.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leader-settlement.d.ts","sourceRoot":"","sources":["../../src/process/leader-settlement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAGtF,uGAAuG;AACvG,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,OAAO,CAAC,uBAAuB,CAAC,EACxC,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,UAAU,EAAE,eAAe,cAmB5B;AAED,8FAA8F;AAC9F,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,0BAA0B,EACnC,MAAM,EAAE,WAAW,WAGJ,uBAAuB,KAAG,OAAO,CAAC,IAAI,CAAC,CAmCvD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type NativeCommandSettlement } from './contract.js';
|
|
2
|
+
/** A failed native admission still owns one bounded external-resource settlement. */
|
|
3
|
+
export declare function failedCommandStart(cause: unknown, settle: (event: NativeCommandSettlement) => Promise<void>): {
|
|
4
|
+
result: Promise<never>;
|
|
5
|
+
stop(): Promise<void>;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=start-failure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-failure.d.ts","sourceRoot":"","sources":["../../src/process/start-failure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAG9E,qFAAqF;AACrF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC;;;EAyB1D"}
|
package/llms/agent-runtime.txt
CHANGED
|
@@ -19,7 +19,7 @@ description: Configure Stitchkit's optional durable history, stream loop, run co
|
|
|
19
19
|
type: architecture
|
|
20
20
|
status: active
|
|
21
21
|
created: 2026-08-22
|
|
22
|
-
updated: 2026-
|
|
22
|
+
updated: 2026-10-02 16:28 +07:00
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
# Agent application runtime
|
|
@@ -376,6 +376,12 @@ second host executable, so Windows kills the direct child, destroys retained pip
|
|
|
376
376
|
deadline and makes no descendant-cleanup claim. A signal already aborted before execution returns
|
|
377
377
|
`cancelled` without spawning.
|
|
378
378
|
|
|
379
|
+
Coding commands compose the shared native execution owner. Artifact retention and UTF-8
|
|
380
|
+
previews remain coding-tool policy; normal leader exit still forcibly stops remaining POSIX
|
|
381
|
+
group members before draining. A structural sandbox launcher uses the same settlement owner
|
|
382
|
+
with a finite output queue. Sandbox shutdown waits for actual owned completion and surfaces
|
|
383
|
+
cleanup refusal rather than treating it as successful teardown.
|
|
384
|
+
|
|
379
385
|
One `createAgentHarnessFileResources` instance represents one immutable discovery generation:
|
|
380
386
|
concurrent and repeated `load()` calls share it, so a direct resource read cannot cross into a
|
|
381
387
|
new catalog unexpectedly. Discovery uses the same descriptor-anchored traversal as coding search;
|