@0xmaxma/claude-gateway 2.0.9 → 2.0.10
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/README.md +1 -1
- package/config.template.json +5 -3
- package/dist/agent/runner.d.ts +7 -0
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +44 -2
- package/dist/agent/runner.js.map +1 -1
- package/dist/agent/skill-learning/reviewer.d.ts.map +1 -1
- package/dist/agent/skill-learning/reviewer.js +1 -2
- package/dist/agent/skill-learning/reviewer.js.map +1 -1
- package/dist/api/capabilities.d.ts +53 -0
- package/dist/api/capabilities.d.ts.map +1 -0
- package/dist/api/capabilities.js +66 -0
- package/dist/api/capabilities.js.map +1 -0
- package/dist/api/gateway-router.d.ts.map +1 -1
- package/dist/api/gateway-router.js +8 -12
- package/dist/api/gateway-router.js.map +1 -1
- package/dist/api/gateway-version.d.ts +9 -0
- package/dist/api/gateway-version.d.ts.map +1 -0
- package/dist/api/gateway-version.js +57 -0
- package/dist/api/gateway-version.js.map +1 -0
- package/dist/build-provenance.json +4 -4
- package/dist/orchestration/agent-tool-schemas.js +2 -2
- package/dist/orchestration/agent-tool-schemas.js.map +1 -1
- package/dist/orchestration/bridge.d.ts.map +1 -1
- package/dist/orchestration/bridge.js +53 -2
- package/dist/orchestration/bridge.js.map +1 -1
- package/dist/orchestration/capabilities.d.ts +1 -1
- package/dist/orchestration/capabilities.d.ts.map +1 -1
- package/dist/orchestration/capabilities.js +9 -15
- package/dist/orchestration/capabilities.js.map +1 -1
- package/dist/orchestration/cli-skills.d.ts +1 -1
- package/dist/orchestration/cli-skills.d.ts.map +1 -1
- package/dist/orchestration/cli-skills.js +14 -9
- package/dist/orchestration/cli-skills.js.map +1 -1
- package/dist/orchestration/container-tool-schemas.js +2 -2
- package/dist/orchestration/container-tool-schemas.js.map +1 -1
- package/dist/orchestration/process-activity.d.ts +4 -2
- package/dist/orchestration/process-activity.d.ts.map +1 -1
- package/dist/orchestration/process-activity.js +31 -42
- package/dist/orchestration/process-activity.js.map +1 -1
- package/dist/orchestration/process-platform.d.ts +75 -0
- package/dist/orchestration/process-platform.d.ts.map +1 -0
- package/dist/orchestration/process-platform.js +400 -0
- package/dist/orchestration/process-platform.js.map +1 -0
- package/dist/orchestration/process-supervisor.d.ts +31 -7
- package/dist/orchestration/process-supervisor.d.ts.map +1 -1
- package/dist/orchestration/process-supervisor.js +89 -61
- package/dist/orchestration/process-supervisor.js.map +1 -1
- package/dist/orchestration/process-turn.d.ts.map +1 -1
- package/dist/orchestration/process-turn.js +32 -5
- package/dist/orchestration/process-turn.js.map +1 -1
- package/dist/orchestration/progress-review.d.ts +1 -1
- package/dist/orchestration/progress-review.d.ts.map +1 -1
- package/dist/orchestration/progress-review.js +5 -1
- package/dist/orchestration/progress-review.js.map +1 -1
- package/dist/orchestration/report-fidelity.d.ts +31 -0
- package/dist/orchestration/report-fidelity.d.ts.map +1 -0
- package/dist/orchestration/report-fidelity.js +34 -0
- package/dist/orchestration/report-fidelity.js.map +1 -0
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +21 -6
- package/dist/orchestration/runtime.js.map +1 -1
- package/dist/orchestration/speech.d.ts +1 -1
- package/dist/orchestration/speech.d.ts.map +1 -1
- package/dist/orchestration/speech.js +1 -1
- package/dist/orchestration/task-questions.js +2 -2
- package/dist/orchestration/task-questions.js.map +1 -1
- package/dist/orchestration/tasks/driver.d.ts.map +1 -1
- package/dist/orchestration/tasks/driver.js +4 -3
- package/dist/orchestration/tasks/driver.js.map +1 -1
- package/dist/orchestration/tasks/failure.d.ts +6 -0
- package/dist/orchestration/tasks/failure.d.ts.map +1 -1
- package/dist/orchestration/tasks/failure.js +26 -2
- package/dist/orchestration/tasks/failure.js.map +1 -1
- package/dist/orchestration/tasks/scheduler.d.ts +1 -1
- package/dist/orchestration/tasks/scheduler.d.ts.map +1 -1
- package/dist/orchestration/tasks/scheduler.js +3 -1
- package/dist/orchestration/tasks/scheduler.js.map +1 -1
- package/dist/orchestration/tasks/service.js +1 -1
- package/dist/orchestration/tasks/service.js.map +1 -1
- package/dist/orchestration/types.d.ts +8 -0
- package/dist/orchestration/types.d.ts.map +1 -1
- package/dist/orchestration/types.js.map +1 -1
- package/dist/safemode/native.d.ts.map +1 -1
- package/dist/safemode/native.js +8 -3
- package/dist/safemode/native.js.map +1 -1
- package/dist/session/claude-bin.d.ts +29 -0
- package/dist/session/claude-bin.d.ts.map +1 -1
- package/dist/session/claude-bin.js +63 -12
- package/dist/session/claude-bin.js.map +1 -1
- package/dist/session/codex-process.d.ts +4 -0
- package/dist/session/codex-process.d.ts.map +1 -1
- package/dist/session/codex-process.js +7 -2
- package/dist/session/codex-process.js.map +1 -1
- package/dist/session/compactor.d.ts.map +1 -1
- package/dist/session/compactor.js +1 -2
- package/dist/session/compactor.js.map +1 -1
- package/dist/session/process.d.ts +6 -0
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +38 -8
- package/dist/session/process.js.map +1 -1
- package/dist/session/runtime-profile.d.ts +13 -0
- package/dist/session/runtime-profile.d.ts.map +1 -1
- package/dist/session/runtime-profile.js +23 -0
- package/dist/session/runtime-profile.js.map +1 -1
- package/dist/session/worker-extensions.d.ts.map +1 -1
- package/dist/session/worker-extensions.js +2 -2
- package/dist/session/worker-extensions.js.map +1 -1
- package/dist/shell/claude-pty-shell.js +5 -4
- package/dist/shell/claude-pty-shell.js.map +1 -1
- package/dist/utils/paths.d.ts +8 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +11 -0
- package/dist/utils/paths.js.map +1 -1
- package/mcp/tools/telegram/receiver-server.ts +4 -2
- package/package.json +2 -2
|
@@ -1,68 +1,57 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ProcessActivitySampler = void 0;
|
|
4
|
-
const
|
|
4
|
+
const process_platform_1 = require("./process-platform");
|
|
5
5
|
/** Read counters only, never argv/env/output. A process identity is PID + start time.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* On POSIX, descendants in new process groups are included while still linked to
|
|
7
|
+
* the root; detached/reparented children outside the original group cannot be
|
|
8
|
+
* proven here. A platform with its own `tree` (Windows) decides ownership itself. */
|
|
8
9
|
class ProcessActivitySampler {
|
|
9
10
|
constructor(pid, enabled = true) {
|
|
10
11
|
this.pid = pid;
|
|
11
12
|
this.enabled = enabled;
|
|
13
|
+
this.known = new Map();
|
|
12
14
|
}
|
|
13
15
|
async sample() {
|
|
14
16
|
const unavailable = { observedAt: Date.now(), available: false };
|
|
15
17
|
const pid = this.pid();
|
|
16
|
-
|
|
18
|
+
const platform = (0, process_platform_1.processPlatform)();
|
|
19
|
+
if (!this.enabled || !platform || !pid || pid <= 0)
|
|
17
20
|
return unavailable;
|
|
18
21
|
try {
|
|
19
|
-
const members =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
for (const entry of entries) {
|
|
23
|
-
if (!/^\d+$/.test(entry))
|
|
24
|
-
continue;
|
|
25
|
-
try {
|
|
26
|
-
const stat = await (0, promises_1.readFile)(`/proc/${entry}/stat`, 'utf8');
|
|
27
|
-
const f = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/);
|
|
28
|
-
members.set(Number(entry), { pid: Number(entry), parent: Number(f[1]), group: Number(f[2]), state: f[0], start: f[19], cpu: Number(f[11]) + Number(f[12]) });
|
|
29
|
-
}
|
|
30
|
-
catch { /* Processes may exit while being sampled. */ }
|
|
31
|
-
}
|
|
22
|
+
const members = await platform.snapshot();
|
|
23
|
+
if (!members)
|
|
24
|
+
return unavailable;
|
|
32
25
|
const root = members.get(pid);
|
|
33
|
-
if (!root || ['Z', 'X'].includes(root.state) || (this.rootStart && this.rootStart !== root.start))
|
|
26
|
+
if (!root || ['Z', 'X'].includes(root.state[0]) || (this.rootStart && this.rootStart !== root.start))
|
|
34
27
|
return unavailable;
|
|
35
28
|
this.rootStart = root.start;
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
29
|
+
let owned = new Set([pid]);
|
|
30
|
+
if (platform.tree) {
|
|
31
|
+
const tree = platform.tree(members, pid, this.known);
|
|
32
|
+
if (!tree)
|
|
33
|
+
return unavailable;
|
|
34
|
+
this.known = tree;
|
|
35
|
+
owned = new Set(tree.keys());
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
let changed = true;
|
|
39
|
+
while (changed) {
|
|
40
|
+
changed = false;
|
|
41
|
+
for (const m of members.values())
|
|
42
|
+
if (!owned.has(m.pid) && (owned.has(m.parent) || (root.group === pid && m.group === pid))) {
|
|
43
|
+
owned.add(m.pid);
|
|
44
|
+
changed = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
45
47
|
}
|
|
46
48
|
const current = new Map();
|
|
47
49
|
for (const id of owned) {
|
|
48
50
|
const m = members.get(id);
|
|
49
|
-
if (['Z', 'X'].includes(m.state))
|
|
51
|
+
if (['Z', 'X'].includes(m.state[0]))
|
|
50
52
|
continue;
|
|
51
|
-
|
|
52
|
-
const io = await (0, promises_1.readFile)(`/proc/${id}/io`, 'utf8');
|
|
53
|
-
// Logical I/O includes pipes/cache, so piped test output is visible.
|
|
54
|
-
m.read = Number(/^rchar:\s+(\d+)/m.exec(io)?.[1]);
|
|
55
|
-
m.write = Number(/^wchar:\s+(\d+)/m.exec(io)?.[1]);
|
|
56
|
-
}
|
|
57
|
-
catch { /* CPU/membership remain usable without I/O permission. */ }
|
|
58
|
-
try {
|
|
59
|
-
const stat = await (0, promises_1.readFile)(`/proc/${id}/stat`, 'utf8');
|
|
60
|
-
if (stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/)[19] !== m.start)
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
53
|
+
if (platform.refine && !await platform.refine(m))
|
|
64
54
|
continue;
|
|
65
|
-
}
|
|
66
55
|
current.set(`${id}:${m.start}`, m);
|
|
67
56
|
}
|
|
68
57
|
const result = { observedAt: Date.now(), available: true, processCount: current.size, ioAvailable: [...current.values()].every(m => Number.isFinite(m.read) && Number.isFinite(m.write)) };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-activity.js","sourceRoot":"","sources":["../../src/orchestration/process-activity.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"process-activity.js","sourceRoot":"","sources":["../../src/orchestration/process-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/** One process as seen by a platform snapshot. `start` is an opaque per-boot
|
|
2
|
+
* start identity (Linux start ticks, macOS lstart, Windows creation FILETIME);
|
|
3
|
+
* `cpu` is user+system time in 10ms ticks. */
|
|
4
|
+
export interface ProcessRecord {
|
|
5
|
+
pid: number;
|
|
6
|
+
parent: number;
|
|
7
|
+
group: number;
|
|
8
|
+
state: string;
|
|
9
|
+
start: string;
|
|
10
|
+
cpu: number;
|
|
11
|
+
read?: number;
|
|
12
|
+
write?: number;
|
|
13
|
+
command?: string;
|
|
14
|
+
}
|
|
15
|
+
export type Fingerprint = {
|
|
16
|
+
bootId: string;
|
|
17
|
+
startTicks: string;
|
|
18
|
+
};
|
|
19
|
+
/** Everything the orchestration supervisor needs from the OS. A "group" is the
|
|
20
|
+
* set of processes the gateway may prove stopped: the POSIX process group led by
|
|
21
|
+
* a detached worker, or on Windows the process tree rooted at the worker. */
|
|
22
|
+
export interface ProcessPlatform {
|
|
23
|
+
/** Spawn the worker with `detached` so it leads its own process group. */
|
|
24
|
+
readonly detachWorkers: boolean;
|
|
25
|
+
readonly termGraceMs: number;
|
|
26
|
+
readonly pollMs: number;
|
|
27
|
+
readonly killSettleMs: number;
|
|
28
|
+
/** Live, non-zombie members; undefined when membership cannot be proven. */
|
|
29
|
+
groupMembers(group: number, rootStart?: string): Promise<number[] | undefined>;
|
|
30
|
+
/** False only when the signal could not be delivered for a reason other than "already gone".
|
|
31
|
+
* `rootStart` pins the root identity the caller owns (Windows; POSIX ignores it). */
|
|
32
|
+
signalGroup(group: number, signal: 'SIGTERM' | 'SIGKILL', rootStart?: string): Promise<boolean>;
|
|
33
|
+
/** Kernel identity that rejects PID reuse; the pid must still lead its group. */
|
|
34
|
+
fingerprint(pid: number): Promise<Fingerprint | undefined>;
|
|
35
|
+
/** This boot's identity, as used in `Fingerprint.bootId`; undefined when unreadable. */
|
|
36
|
+
bootId(): Promise<string | undefined>;
|
|
37
|
+
/** Counters for every visible process; undefined when unavailable. */
|
|
38
|
+
snapshot(): Promise<Map<number, ProcessRecord> | undefined>;
|
|
39
|
+
/** Processes owned by the worker rooted at `root`, when ownership is not the
|
|
40
|
+
* POSIX parent/process-group link. `known` maps pid->start of members owned
|
|
41
|
+
* at the previous sample, so orphaned descendants stay owned. */
|
|
42
|
+
tree?(snapshot: Map<number, ProcessRecord>, root: number, known: Map<number, string>): Map<number, string> | undefined;
|
|
43
|
+
/** Linux enriches owned members with I/O counters and re-checks start identity. */
|
|
44
|
+
refine?(member: ProcessRecord): Promise<boolean>;
|
|
45
|
+
/** Record a just-spawned root's identity while its handle is held (`alive`), so
|
|
46
|
+
* a later stop can anchor orphans and refuse a reused PID. Resolves to the
|
|
47
|
+
* recorded start, or undefined when none could be recorded. */
|
|
48
|
+
adopt?(pid: number, alive: () => boolean): Promise<string | undefined>;
|
|
49
|
+
}
|
|
50
|
+
/** `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe` from the first of SystemRoot
|
|
51
|
+
* and windir that is a plain absolute drive path; otherwise the bare name, resolved through PATH. */
|
|
52
|
+
export declare function windowsPowerShell(systemRoot?: string | undefined, windir?: string | undefined): string;
|
|
53
|
+
export declare const linuxPlatform: ProcessPlatform;
|
|
54
|
+
/** BSD ps `time` is [[dd-]hh:]mm:ss.cc of user+system CPU. */
|
|
55
|
+
export declare function parsePsCpuTicks(value: string): number;
|
|
56
|
+
/** `ps -o pid=,ppid=,pgid=,stat=,time=,lstart=[,comm=]`. lstart is always five
|
|
57
|
+
* fields ("Mon Sep 28 10:00:01 2026"); an optional comm (may hold spaces) follows. */
|
|
58
|
+
export declare function parseDarwinPs(output: string): Map<number, ProcessRecord>;
|
|
59
|
+
export declare const darwinPlatform: ProcessPlatform;
|
|
60
|
+
export declare function parseWindowsSnapshot(output: string): Map<number, ProcessRecord>;
|
|
61
|
+
/** Members of the tree rooted at `root`. `known` holds pid->start of members owned
|
|
62
|
+
* at the previous snapshot, so a grandchild orphaned by an exited intermediate is
|
|
63
|
+
* still owned. Undefined when nothing is proven: the root PID now belongs to a
|
|
64
|
+
* different process (its original tree may still have orphans that cannot be told
|
|
65
|
+
* apart), or the root is gone and no start identity anchors its orphans. */
|
|
66
|
+
export declare function windowsTree(snapshot: Map<number, ProcessRecord>, root: number, known?: Map<number, string>, rootStart?: string): Map<number, string> | undefined;
|
|
67
|
+
export declare function windowsPlatform(powershell?: string): ProcessPlatform;
|
|
68
|
+
/** The supervisor for this host, or undefined where orchestration cannot prove process lifetime. */
|
|
69
|
+
export declare function processPlatform(): ProcessPlatform | undefined;
|
|
70
|
+
/** Windows caps a whole command line at 32767 characters. An OS property, not a
|
|
71
|
+
* supervisor one, so it holds even where no supervisor is selected. */
|
|
72
|
+
export declare function commandLineLimited(): boolean;
|
|
73
|
+
/** Test hook: substitute a platform (e.g. a mocked Windows supervisor on Linux CI). */
|
|
74
|
+
export declare function setProcessPlatform(platform: ProcessPlatform | null | undefined): void;
|
|
75
|
+
//# sourceMappingURL=process-platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-platform.d.ts","sourceRoot":"","sources":["../../src/orchestration/process-platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.darwinPlatform = exports.linuxPlatform = void 0;
|
|
4
|
+
exports.windowsPowerShell = windowsPowerShell;
|
|
5
|
+
exports.parsePsCpuTicks = parsePsCpuTicks;
|
|
6
|
+
exports.parseDarwinPs = parseDarwinPs;
|
|
7
|
+
exports.parseWindowsSnapshot = parseWindowsSnapshot;
|
|
8
|
+
exports.windowsTree = windowsTree;
|
|
9
|
+
exports.windowsPlatform = windowsPlatform;
|
|
10
|
+
exports.processPlatform = processPlatform;
|
|
11
|
+
exports.commandLineLimited = commandLineLimited;
|
|
12
|
+
exports.setProcessPlatform = setProcessPlatform;
|
|
13
|
+
const child_process_1 = require("child_process");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const promises_1 = require("fs/promises");
|
|
16
|
+
const gone = (error) => ['ENOENT', 'ESRCH'].includes(error.code ?? '');
|
|
17
|
+
function signalPosixGroup(group, signal) {
|
|
18
|
+
try {
|
|
19
|
+
process.kill(-group, signal);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error.code !== 'ESRCH')
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
// Absolute paths, so a PATH entry cannot substitute the tool whose output decides what gets killed.
|
|
28
|
+
const PS_BIN = '/bin/ps', SYSCTL_BIN = '/usr/sbin/sysctl';
|
|
29
|
+
/** `%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe` from the first of SystemRoot
|
|
30
|
+
* and windir that is a plain absolute drive path; otherwise the bare name, resolved through PATH. */
|
|
31
|
+
function windowsPowerShell(systemRoot = process.env.SystemRoot, windir = process.env.windir) {
|
|
32
|
+
const root = [systemRoot, windir].find(value => value && /^[A-Za-z]:\\[^"*?<>|]*$/.test(value));
|
|
33
|
+
return root ? `${root.replace(/\\+$/, '')}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe` : 'powershell.exe';
|
|
34
|
+
}
|
|
35
|
+
function run(file, args, timeout = 10000) {
|
|
36
|
+
return new Promise(resolve => {
|
|
37
|
+
(0, child_process_1.execFile)(file, args, { encoding: 'utf8', timeout, windowsHide: true, maxBuffer: 32 * 1024 * 1024, env: { ...process.env, LC_ALL: 'C' } }, (error, stdout) => resolve(error ? undefined : stdout));
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
exports.linuxPlatform = {
|
|
41
|
+
detachWorkers: true, termGraceMs: 2000, pollMs: 25, killSettleMs: 50,
|
|
42
|
+
async groupMembers(group) {
|
|
43
|
+
const members = [];
|
|
44
|
+
try {
|
|
45
|
+
for (const entry of (0, fs_1.readdirSync)('/proc')) {
|
|
46
|
+
if (!/^\d+$/.test(entry))
|
|
47
|
+
continue;
|
|
48
|
+
try {
|
|
49
|
+
const stat = (0, fs_1.readFileSync)(`/proc/${entry}/stat`, 'utf8');
|
|
50
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
|
|
51
|
+
if (Number(fields[2]) === group && fields[0] !== 'Z' && fields[0] !== 'X')
|
|
52
|
+
members.push(Number(entry));
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
if (!gone(error))
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return members;
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
async signalGroup(group, signal) { return signalPosixGroup(group, signal); },
|
|
66
|
+
async fingerprint(pid) {
|
|
67
|
+
try {
|
|
68
|
+
const stat = (0, fs_1.readFileSync)(`/proc/${pid}/stat`, 'utf8');
|
|
69
|
+
const fields = stat.slice(stat.lastIndexOf(')') + 2).split(' ');
|
|
70
|
+
if (Number(fields[2]) !== pid)
|
|
71
|
+
return undefined;
|
|
72
|
+
return { bootId: (0, fs_1.readFileSync)('/proc/sys/kernel/random/boot_id', 'utf8').trim(), startTicks: fields[19] };
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
async bootId() {
|
|
79
|
+
try {
|
|
80
|
+
return (0, fs_1.readFileSync)('/proc/sys/kernel/random/boot_id', 'utf8').trim() || undefined;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
async snapshot() {
|
|
87
|
+
const members = new Map();
|
|
88
|
+
const entries = await (0, promises_1.readdir)('/proc');
|
|
89
|
+
// Sequential stat reads bound open files and memory on busy shared hosts.
|
|
90
|
+
for (const entry of entries) {
|
|
91
|
+
if (!/^\d+$/.test(entry))
|
|
92
|
+
continue;
|
|
93
|
+
try {
|
|
94
|
+
const stat = await (0, promises_1.readFile)(`/proc/${entry}/stat`, 'utf8');
|
|
95
|
+
const f = stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/);
|
|
96
|
+
members.set(Number(entry), { pid: Number(entry), parent: Number(f[1]), group: Number(f[2]), state: f[0], start: f[19], cpu: Number(f[11]) + Number(f[12]) });
|
|
97
|
+
}
|
|
98
|
+
catch { /* Processes may exit while being sampled. */ }
|
|
99
|
+
}
|
|
100
|
+
return members;
|
|
101
|
+
},
|
|
102
|
+
async refine(m) {
|
|
103
|
+
try {
|
|
104
|
+
const io = await (0, promises_1.readFile)(`/proc/${m.pid}/io`, 'utf8');
|
|
105
|
+
// Logical I/O includes pipes/cache, so piped test output is visible.
|
|
106
|
+
m.read = Number(/^rchar:\s+(\d+)/m.exec(io)?.[1]);
|
|
107
|
+
m.write = Number(/^wchar:\s+(\d+)/m.exec(io)?.[1]);
|
|
108
|
+
}
|
|
109
|
+
catch { /* CPU/membership remain usable without I/O permission. */ }
|
|
110
|
+
try {
|
|
111
|
+
const stat = await (0, promises_1.readFile)(`/proc/${m.pid}/stat`, 'utf8');
|
|
112
|
+
return stat.slice(stat.lastIndexOf(')') + 2).trim().split(/\s+/)[19] === m.start;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
/** BSD ps `time` is [[dd-]hh:]mm:ss.cc of user+system CPU. */
|
|
120
|
+
function parsePsCpuTicks(value) {
|
|
121
|
+
const [days, clock] = value.includes('-') ? value.split('-') : ['0', value];
|
|
122
|
+
const seconds = clock.split(':').reduce((total, part) => total * 60 + Number(part), 0) + Number(days) * 86400;
|
|
123
|
+
return Number.isFinite(seconds) ? Math.round(seconds * 100) : 0;
|
|
124
|
+
}
|
|
125
|
+
/** `ps -o pid=,ppid=,pgid=,stat=,time=,lstart=[,comm=]`. lstart is always five
|
|
126
|
+
* fields ("Mon Sep 28 10:00:01 2026"); an optional comm (may hold spaces) follows. */
|
|
127
|
+
function parseDarwinPs(output) {
|
|
128
|
+
const members = new Map();
|
|
129
|
+
for (const line of output.split('\n')) {
|
|
130
|
+
const match = /^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+\s+\S+\s+\d+\s+[\d:]+\s+\d+)(?:\s+(.*?))?\s*$/.exec(line);
|
|
131
|
+
if (!match)
|
|
132
|
+
continue;
|
|
133
|
+
const pid = Number(match[1]);
|
|
134
|
+
members.set(pid, { pid, parent: Number(match[2]), group: Number(match[3]), state: match[4], start: match[6].replace(/\s+/g, ' '), cpu: parsePsCpuTicks(match[5]),
|
|
135
|
+
...(match[7] ? { command: match[7] } : {}) });
|
|
136
|
+
}
|
|
137
|
+
return members;
|
|
138
|
+
}
|
|
139
|
+
const PS_COLUMNS = 'pid=,ppid=,pgid=,stat=,time=,lstart=';
|
|
140
|
+
exports.darwinPlatform = {
|
|
141
|
+
detachWorkers: true, termGraceMs: 2000, pollMs: 50, killSettleMs: 50,
|
|
142
|
+
async groupMembers(group) {
|
|
143
|
+
const output = await run(PS_BIN, ['-A', '-o', 'pid=,pgid=,stat=']);
|
|
144
|
+
if (output === undefined)
|
|
145
|
+
return undefined;
|
|
146
|
+
const members = [];
|
|
147
|
+
for (const line of output.split('\n')) {
|
|
148
|
+
const [pid, pgid, state] = line.trim().split(/\s+/);
|
|
149
|
+
if (Number(pgid) === group && state && state[0] !== 'Z')
|
|
150
|
+
members.push(Number(pid));
|
|
151
|
+
}
|
|
152
|
+
return members;
|
|
153
|
+
},
|
|
154
|
+
async signalGroup(group, signal) { return signalPosixGroup(group, signal); },
|
|
155
|
+
async fingerprint(pid) {
|
|
156
|
+
// ps exits 1 for an unknown pid; that is "no identity", not an error.
|
|
157
|
+
const [output, bootId] = await Promise.all([run(PS_BIN, ['-p', String(pid), '-o', `${PS_COLUMNS},comm=`]), exports.darwinPlatform.bootId()]);
|
|
158
|
+
const record = output === undefined ? undefined : parseDarwinPs(output).get(pid);
|
|
159
|
+
if (!record?.command || record.group !== pid || record.state[0] === 'Z' || !bootId)
|
|
160
|
+
return undefined;
|
|
161
|
+
// ps offers no start time finer than lstart's 1s, so a PID reused within the
|
|
162
|
+
// same second would match on start alone; the executable (and the group-leader
|
|
163
|
+
// check above) must match too. Only this per-attempt call pays for comm.
|
|
164
|
+
return { bootId, startTicks: `${record.start}|${record.command}` };
|
|
165
|
+
},
|
|
166
|
+
async bootId() { return (await run(SYSCTL_BIN, ['-n', 'kern.bootsessionuuid']))?.trim() || undefined; },
|
|
167
|
+
async snapshot() {
|
|
168
|
+
const output = await run(PS_BIN, ['-A', '-o', PS_COLUMNS]);
|
|
169
|
+
return output === undefined ? undefined : parseDarwinPs(output);
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
/** Windows has no process groups and no reparenting: a child keeps the PID of
|
|
173
|
+
* its dead parent. A tree edge is trusted only when the child was created no
|
|
174
|
+
* earlier than that parent, which rejects edges to a reused parent PID. */
|
|
175
|
+
// Plain .NET WMI (System.Management), never a cmdlet: resolving a cmdlet such as
|
|
176
|
+
// Get-CimInstance makes PowerShell run module discovery, which without a warm
|
|
177
|
+
// module-analysis cache (e.g. under the minimal env a desktop app gives its
|
|
178
|
+
// sidecar) takes 20-70s and outlives the timeout, so no stop could be proven.
|
|
179
|
+
const WIN_WMI = "$ErrorActionPreference='Stop';$null=[Reflection.Assembly]::Load('System.Management, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a');";
|
|
180
|
+
const winQuery = (wql, row) => `${WIN_WMI}foreach($p in [Management.ManagementObjectSearcher]::new('${wql}').Get()){${row}}`;
|
|
181
|
+
const winTime = (field) => `[Management.ManagementDateTimeConverter]::ToDateTime($p['${field}']).ToFileTimeUtc()`;
|
|
182
|
+
const WIN_SNAPSHOT = winQuery('SELECT ProcessId,ParentProcessId,CreationDate,KernelModeTime,UserModeTime,ReadTransferCount,WriteTransferCount FROM Win32_Process', `if($p['CreationDate']){'{0} {1} {2} {3} {4} {5}' -f $p['ProcessId'],$p['ParentProcessId'],${winTime('CreationDate')},([uint64]$p['KernelModeTime']+[uint64]$p['UserModeTime']),$p['ReadTransferCount'],$p['WriteTransferCount']}`);
|
|
183
|
+
// LastBootUpTime is the boot identity. It does not follow wall-clock changes
|
|
184
|
+
// (checked on a Windows runner: a +/-3h Set-Date left it identical to the 100ns),
|
|
185
|
+
// so it is compared exactly.
|
|
186
|
+
const WIN_BOOT = winQuery('SELECT LastBootUpTime FROM Win32_OperatingSystem', winTime('LastBootUpTime'));
|
|
187
|
+
function parseWindowsSnapshot(output) {
|
|
188
|
+
const members = new Map();
|
|
189
|
+
for (const line of output.split(/\r?\n/)) {
|
|
190
|
+
const match = /^(\d+) (\d+) (\d+) (\d+) (\d*) (\d*)$/.exec(line.trim());
|
|
191
|
+
if (!match)
|
|
192
|
+
continue;
|
|
193
|
+
const pid = Number(match[1]);
|
|
194
|
+
// 100ns units -> 10ms ticks, matching Linux USER_HZ accounting.
|
|
195
|
+
members.set(pid, { pid, parent: Number(match[2]), group: 0, state: 'R', start: match[3], cpu: Math.floor(Number(match[4]) / 100000),
|
|
196
|
+
...(match[5] ? { read: Number(match[5]) } : {}), ...(match[6] ? { write: Number(match[6]) } : {}) });
|
|
197
|
+
}
|
|
198
|
+
return members;
|
|
199
|
+
}
|
|
200
|
+
const filetime = (value) => /^\d+$/.test(value) ? BigInt(value) : undefined;
|
|
201
|
+
const notBefore = (child, parent) => filetime(parent) !== undefined && filetime(child) >= filetime(parent);
|
|
202
|
+
/** Members of the tree rooted at `root`. `known` holds pid->start of members owned
|
|
203
|
+
* at the previous snapshot, so a grandchild orphaned by an exited intermediate is
|
|
204
|
+
* still owned. Undefined when nothing is proven: the root PID now belongs to a
|
|
205
|
+
* different process (its original tree may still have orphans that cannot be told
|
|
206
|
+
* apart), or the root is gone and no start identity anchors its orphans. */
|
|
207
|
+
function windowsTree(snapshot, root, known = new Map(), rootStart) {
|
|
208
|
+
const expected = known.get(root) ?? rootStart;
|
|
209
|
+
const lineage = new Map(known);
|
|
210
|
+
if (expected !== undefined)
|
|
211
|
+
lineage.set(root, expected);
|
|
212
|
+
const owned = new Map();
|
|
213
|
+
const current = snapshot.get(root);
|
|
214
|
+
if (current && expected !== undefined && current.start !== expected)
|
|
215
|
+
return undefined;
|
|
216
|
+
if (!current && expected === undefined)
|
|
217
|
+
return undefined;
|
|
218
|
+
if (current) {
|
|
219
|
+
owned.set(root, current.start);
|
|
220
|
+
lineage.set(root, current.start);
|
|
221
|
+
}
|
|
222
|
+
let changed = true;
|
|
223
|
+
while (changed) {
|
|
224
|
+
changed = false;
|
|
225
|
+
for (const m of snapshot.values()) {
|
|
226
|
+
if (owned.has(m.pid) || m.pid === m.parent)
|
|
227
|
+
continue;
|
|
228
|
+
// A live parent must itself be owned; a dead one is trusted from lineage.
|
|
229
|
+
// Residual gap: if a member dies, an unrelated process reuses its PID, starts
|
|
230
|
+
// a child and dies too, all between two snapshots, that child passes the
|
|
231
|
+
// creation-time check against the member's recorded start. Closing it needs
|
|
232
|
+
// each member's exit time, which WMI does not report; the lineage is kept
|
|
233
|
+
// for one snapshot only, so the window is one poll interval.
|
|
234
|
+
const parentStart = snapshot.has(m.parent) ? owned.get(m.parent) : lineage.get(m.parent);
|
|
235
|
+
if (known.get(m.pid) === m.start || (parentStart !== undefined && notBefore(m.start, parentStart))) {
|
|
236
|
+
owned.set(m.pid, m.start);
|
|
237
|
+
changed = true;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return owned;
|
|
242
|
+
}
|
|
243
|
+
const bounded = (map, key, value) => {
|
|
244
|
+
map.delete(key);
|
|
245
|
+
map.set(key, value);
|
|
246
|
+
for (const oldest of map.keys()) {
|
|
247
|
+
if (map.size <= 256)
|
|
248
|
+
break;
|
|
249
|
+
map.delete(oldest);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
function windowsPlatform(powershell = windowsPowerShell()) {
|
|
253
|
+
// Latest root identity per PID: its start (`spawned` when recorded while the
|
|
254
|
+
// child handle was held), or null when the root exited before it could be
|
|
255
|
+
// recorded (a live process at that PID is then someone else).
|
|
256
|
+
// Use refreshes an entry's place in the 256-entry budget, so a long-running
|
|
257
|
+
// worker is not evicted by later spawns.
|
|
258
|
+
const roots = new Map();
|
|
259
|
+
// Roots whose tree was proven empty move here, on their own budget: they no
|
|
260
|
+
// longer displace live roots, yet a stop retried after the PID is reused is
|
|
261
|
+
// still refused rather than adopting the new process.
|
|
262
|
+
const retired = new Map();
|
|
263
|
+
const recordedRoot = (pid) => {
|
|
264
|
+
const live = roots.get(pid);
|
|
265
|
+
if (live)
|
|
266
|
+
bounded(roots, pid, live);
|
|
267
|
+
return live ?? retired.get(pid);
|
|
268
|
+
};
|
|
269
|
+
// Lineage per root identity (pid:start), replaced by every snapshot: a dead
|
|
270
|
+
// member is trusted as a parent only in the first snapshot that misses it, so
|
|
271
|
+
// an entry never outlives its PID into a later reuse. Dropped once the tree is
|
|
272
|
+
// proven empty; the root entry is retired, never dropped, so the PID is never
|
|
273
|
+
// re-adopted blindly.
|
|
274
|
+
const lineages = new Map();
|
|
275
|
+
const ps = (script) => run(powershell, ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', script], 30000);
|
|
276
|
+
const snapshot = async () => { const output = await ps(WIN_SNAPSHOT); return output === undefined ? undefined : parseWindowsSnapshot(output); };
|
|
277
|
+
// The boot time cannot change while this process runs, so one query serves
|
|
278
|
+
// every fingerprint; a failed query is retried on the next call.
|
|
279
|
+
let bootQuery;
|
|
280
|
+
const bootTime = () => {
|
|
281
|
+
const pending = bootQuery ?? (bootQuery = ps(WIN_BOOT).then(output => output?.trim() || undefined));
|
|
282
|
+
void pending.then(value => { if (value === undefined && bootQuery === pending)
|
|
283
|
+
bootQuery = undefined; });
|
|
284
|
+
return pending;
|
|
285
|
+
};
|
|
286
|
+
const tree = async (group, rootStart) => {
|
|
287
|
+
const entry = recordedRoot(group);
|
|
288
|
+
const recorded = await entry;
|
|
289
|
+
const processes = await snapshot();
|
|
290
|
+
if (!processes || (rootStart === undefined && recorded === null))
|
|
291
|
+
return undefined;
|
|
292
|
+
// An unrecorded root is adopted only while it is alive; a dead one proves nothing.
|
|
293
|
+
const start = rootStart ?? recorded?.start ?? processes.get(group)?.start;
|
|
294
|
+
if (start === undefined)
|
|
295
|
+
return undefined;
|
|
296
|
+
const key = `${group}:${start}`;
|
|
297
|
+
const owned = windowsTree(processes, group, lineages.get(key), start);
|
|
298
|
+
if (!owned)
|
|
299
|
+
return undefined;
|
|
300
|
+
if (owned.size)
|
|
301
|
+
bounded(lineages, key, owned);
|
|
302
|
+
else
|
|
303
|
+
lineages.delete(key);
|
|
304
|
+
// Only for the recorded identity, and unless a new root was recorded at this PID meanwhile.
|
|
305
|
+
if (roots.get(group) === entry && (recorded === undefined || recorded?.start === start)) {
|
|
306
|
+
const root = recorded === undefined ? Promise.resolve({ start, spawned: false }) : entry;
|
|
307
|
+
if (owned.size)
|
|
308
|
+
bounded(roots, group, root);
|
|
309
|
+
else {
|
|
310
|
+
roots.delete(group);
|
|
311
|
+
bounded(retired, group, root);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return owned;
|
|
315
|
+
};
|
|
316
|
+
return {
|
|
317
|
+
// Each poll is a PowerShell WMI snapshot (0.4-4s), so poll far less often than POSIX.
|
|
318
|
+
detachWorkers: false, termGraceMs: 2000, pollMs: 500, killSettleMs: 500,
|
|
319
|
+
async groupMembers(group, rootStart) { const owned = await tree(group, rootStart); return owned && [...owned.keys()]; },
|
|
320
|
+
// Console processes cannot be asked to exit politely, so both signals terminate
|
|
321
|
+
// every creation-time-verified member individually. Never taskkill /T: it
|
|
322
|
+
// follows bare parent PIDs, which Windows keeps after the parent dies.
|
|
323
|
+
// Termination is by PID, right after the snapshot that verified each creation
|
|
324
|
+
// time; a PID that exits and is reused in that gap (milliseconds) cannot be
|
|
325
|
+
// re-checked without another snapshot. Only a job object, assigned at spawn,
|
|
326
|
+
// would close that window.
|
|
327
|
+
async signalGroup(group, _signal, rootStart) {
|
|
328
|
+
const owned = await tree(group, rootStart);
|
|
329
|
+
if (!owned)
|
|
330
|
+
return false;
|
|
331
|
+
for (const pid of owned.keys()) {
|
|
332
|
+
try {
|
|
333
|
+
process.kill(pid, 'SIGKILL');
|
|
334
|
+
}
|
|
335
|
+
catch (error) {
|
|
336
|
+
if (!gone(error))
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return true;
|
|
341
|
+
},
|
|
342
|
+
async fingerprint(pid) {
|
|
343
|
+
const recorded = await recordedRoot(pid);
|
|
344
|
+
if (recorded === null)
|
|
345
|
+
return undefined;
|
|
346
|
+
// Recorded at spawn while the handle was held: that start is our worker's,
|
|
347
|
+
// even if the PID has been reused since, and needs no fresh snapshot.
|
|
348
|
+
if (recorded?.spawned) {
|
|
349
|
+
const boot = await bootTime();
|
|
350
|
+
return boot ? { bootId: boot, startTicks: recorded.start } : undefined;
|
|
351
|
+
}
|
|
352
|
+
const [processes, boot] = await Promise.all([snapshot(), bootTime()]);
|
|
353
|
+
const record = processes?.get(pid);
|
|
354
|
+
if (!record || !boot || (recorded && record.start !== recorded.start))
|
|
355
|
+
return undefined;
|
|
356
|
+
return { bootId: boot, startTicks: record.start };
|
|
357
|
+
},
|
|
358
|
+
bootId: bootTime,
|
|
359
|
+
snapshot,
|
|
360
|
+
tree(processes, root, known) {
|
|
361
|
+
const owned = windowsTree(processes, root, known);
|
|
362
|
+
// The activity sampler's fresher view also serves a later stop of an
|
|
363
|
+
// adopted root, without another snapshot.
|
|
364
|
+
const key = `${root}:${owned?.get(root)}`;
|
|
365
|
+
if (owned && lineages.has(key)) {
|
|
366
|
+
bounded(lineages, key, owned);
|
|
367
|
+
recordedRoot(root);
|
|
368
|
+
}
|
|
369
|
+
return owned;
|
|
370
|
+
},
|
|
371
|
+
adopt(pid, alive) {
|
|
372
|
+
const root = snapshot().then((processes) => {
|
|
373
|
+
if (!processes)
|
|
374
|
+
return undefined;
|
|
375
|
+
const start = processes.get(pid)?.start;
|
|
376
|
+
if (start === undefined || !alive())
|
|
377
|
+
return null;
|
|
378
|
+
// A new root at a reused PID starts a fresh lineage.
|
|
379
|
+
bounded(lineages, `${pid}:${start}`, new Map([[pid, start]]));
|
|
380
|
+
return { start, spawned: true };
|
|
381
|
+
});
|
|
382
|
+
bounded(roots, pid, root);
|
|
383
|
+
retired.delete(pid);
|
|
384
|
+
return root.then(recorded => recorded?.start);
|
|
385
|
+
},
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
let selected;
|
|
389
|
+
/** The supervisor for this host, or undefined where orchestration cannot prove process lifetime. */
|
|
390
|
+
function processPlatform() {
|
|
391
|
+
if (selected === undefined)
|
|
392
|
+
selected = process.platform === 'linux' ? exports.linuxPlatform : process.platform === 'darwin' ? exports.darwinPlatform : process.platform === 'win32' ? windowsPlatform() : null;
|
|
393
|
+
return selected ?? undefined;
|
|
394
|
+
}
|
|
395
|
+
/** Windows caps a whole command line at 32767 characters. An OS property, not a
|
|
396
|
+
* supervisor one, so it holds even where no supervisor is selected. */
|
|
397
|
+
function commandLineLimited() { return process.platform === 'win32'; }
|
|
398
|
+
/** Test hook: substitute a platform (e.g. a mocked Windows supervisor on Linux CI). */
|
|
399
|
+
function setProcessPlatform(platform) { selected = platform; }
|
|
400
|
+
//# sourceMappingURL=process-platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-platform.js","sourceRoot":"","sources":["../../src/orchestration/process-platform.ts"],"names":[],"mappings":"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"}
|