@moxt-ai/mobius 0.0.336 → 0.0.338
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/dist/cli.js +1407 -1283
- package/dist/cli.js.map +4 -4
- package/dist/daemon/upgrades/upgrade.d.ts.map +1 -1
- package/dist/daemon/upgrades/upgrade.js +25 -2
- package/dist/daemon/upgrades/upgrade.js.map +1 -1
- package/dist/runtime.js +1091 -1021
- package/dist/runtime.js.map +4 -4
- package/dist/session/turn/runtime-turn-activity.d.ts +12 -1
- package/dist/session/turn/runtime-turn-activity.d.ts.map +1 -1
- package/dist/session/turn/runtime-turn-activity.js +52 -26
- package/dist/session/turn/runtime-turn-activity.js.map +1 -1
- package/dist/util/filesystem/private-path.js +6 -324
- package/dist/util/filesystem/private-path.js.map +4 -4
- package/dist/util/platform/contracts.d.ts +0 -26
- package/dist/util/platform/contracts.d.ts.map +1 -1
- package/dist/util/platform/index.d.ts.map +1 -1
- package/dist/util/platform/index.js +1 -4
- package/dist/util/platform/index.js.map +1 -1
- package/dist/util/platform/linux.d.ts.map +1 -1
- package/dist/util/platform/linux.js +1 -117
- package/dist/util/platform/linux.js.map +1 -1
- package/dist/util/platform/macos.d.ts.map +1 -1
- package/dist/util/platform/macos.js +1 -4
- package/dist/util/platform/macos.js.map +1 -1
- package/dist/util/platform/posix.d.ts +0 -21
- package/dist/util/platform/posix.d.ts.map +1 -1
- package/dist/util/platform/posix.js +1 -104
- package/dist/util/platform/posix.js.map +1 -1
- package/dist/util/platform/windows.d.ts.map +1 -1
- package/dist/util/platform/windows.js +1 -107
- package/dist/util/platform/windows.js.map +1 -1
- package/dist/util/process/executable.d.ts +2 -2
- package/dist/util/process/executable.d.ts.map +1 -1
- package/dist/util/process/executable.js +31 -222
- package/dist/util/process/executable.js.map +4 -4
- package/dist/util/process/platform/contracts.d.ts +29 -0
- package/dist/util/process/platform/contracts.d.ts.map +1 -0
- package/dist/util/process/platform/contracts.js +2 -0
- package/dist/util/process/platform/contracts.js.map +1 -0
- package/dist/util/process/platform/index.d.ts +3 -0
- package/dist/util/process/platform/index.d.ts.map +1 -0
- package/dist/util/process/platform/index.js +20 -0
- package/dist/util/process/platform/index.js.map +1 -0
- package/dist/util/process/platform/linux.d.ts +3 -0
- package/dist/util/process/platform/linux.d.ts.map +1 -0
- package/dist/util/process/platform/linux.js +122 -0
- package/dist/util/process/platform/linux.js.map +1 -0
- package/dist/util/process/platform/macos.d.ts +3 -0
- package/dist/util/process/platform/macos.d.ts.map +1 -0
- package/dist/util/process/platform/macos.js +8 -0
- package/dist/util/process/platform/macos.js.map +1 -0
- package/dist/util/process/platform/posix.d.ts +25 -0
- package/dist/util/process/platform/posix.d.ts.map +1 -0
- package/dist/util/process/platform/posix.js +107 -0
- package/dist/util/process/platform/posix.js.map +1 -0
- package/dist/util/process/platform/windows.d.ts +3 -0
- package/dist/util/process/platform/windows.d.ts.map +1 -0
- package/dist/util/process/platform/windows.js +114 -0
- package/dist/util/process/platform/windows.js.map +1 -0
- package/package.json +2 -2
|
@@ -4,9 +4,20 @@ export declare class RuntimeTurnActivity {
|
|
|
4
4
|
#private;
|
|
5
5
|
readonly acceptsPrompts: () => boolean;
|
|
6
6
|
readonly count: () => number;
|
|
7
|
+
readonly describe: () => {
|
|
8
|
+
readonly turns: number;
|
|
9
|
+
readonly backgroundSources: number;
|
|
10
|
+
};
|
|
7
11
|
readonly setBackgroundActivity: (source: object, active: boolean) => void;
|
|
8
12
|
readonly start: (turn: ActiveRuntimeTurn) => void;
|
|
9
13
|
readonly finish: (turn: ActiveRuntimeTurn) => void;
|
|
10
|
-
readonly
|
|
14
|
+
readonly whenIdle: (signal: AbortSignal) => Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Close admission only after the Runtime has had no work for `quietMilliseconds`.
|
|
17
|
+
* The moment a reply finishes is when a user is most likely to continue, so idle
|
|
18
|
+
* alone is not an upgrade window. Checking and reserving happen synchronously, so
|
|
19
|
+
* no prompt can be admitted between them.
|
|
20
|
+
*/
|
|
21
|
+
readonly reserveIfQuiet: (quietMilliseconds: number) => Disposable | null;
|
|
11
22
|
}
|
|
12
23
|
//# sourceMappingURL=runtime-turn-activity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-turn-activity.d.ts","sourceRoot":"","sources":["../../../src/session/turn/runtime-turn-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"runtime-turn-activity.d.ts","sourceRoot":"","sources":["../../../src/session/turn/runtime-turn-activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,iGAAiG;AACjG,qBAAa,mBAAmB;;IAQ5B,QAAQ,CAAC,cAAc,QAAO,OAAO,CAAoB;IAEzD,QAAQ,CAAC,KAAK,QAAO,MAAM,CAAoD;IAE/E,QAAQ,CAAC,QAAQ,QAAO;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,CAGnF;IAEH,QAAQ,CAAC,qBAAqB,WAAY,MAAM,UAAU,OAAO,KAAG,IAAI,CAWtE;IAEF,QAAQ,CAAC,KAAK,SAAU,iBAAiB,KAAG,IAAI,CAG9C;IAEF,QAAQ,CAAC,MAAM,SAAU,iBAAiB,KAAG,IAAI,CAG/C;IAYF,QAAQ,CAAC,QAAQ,WAAY,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC,CAiBtD;IAEF;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,sBAAuB,MAAM,KAAG,UAAU,GAAG,IAAI,CAatE;CACL"}
|
|
@@ -2,57 +2,83 @@
|
|
|
2
2
|
export class RuntimeTurnActivity {
|
|
3
3
|
#turns = new Set();
|
|
4
4
|
#backgroundSources = new Set();
|
|
5
|
-
#
|
|
6
|
-
|
|
5
|
+
#idleWaiters = new Set();
|
|
6
|
+
// When work last started or stopped; the quiet period is measured from here.
|
|
7
|
+
#changedAt = Date.now();
|
|
8
|
+
#reserved = false;
|
|
9
|
+
acceptsPrompts = () => !this.#reserved;
|
|
7
10
|
count = () => this.#turns.size + this.#backgroundSources.size;
|
|
11
|
+
describe = () => ({
|
|
12
|
+
turns: this.#turns.size,
|
|
13
|
+
backgroundSources: this.#backgroundSources.size,
|
|
14
|
+
});
|
|
8
15
|
setBackgroundActivity = (source, active) => {
|
|
16
|
+
// Agents repeat unchanged reports; only a transition counts as activity.
|
|
17
|
+
if (active === this.#backgroundSources.has(source)) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
9
20
|
if (active) {
|
|
10
21
|
this.#backgroundSources.add(source);
|
|
11
22
|
}
|
|
12
23
|
else {
|
|
13
24
|
this.#backgroundSources.delete(source);
|
|
14
25
|
}
|
|
15
|
-
this.#
|
|
26
|
+
this.#changed();
|
|
16
27
|
};
|
|
17
|
-
#reserveIfIdle() {
|
|
18
|
-
if (this.count() === 0 && this.#admission.kind === "waiting") {
|
|
19
|
-
this.#admission.reserve();
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
28
|
start = (turn) => {
|
|
23
29
|
this.#turns.add(turn);
|
|
30
|
+
this.#changed();
|
|
24
31
|
};
|
|
25
32
|
finish = (turn) => {
|
|
26
33
|
this.#turns.delete(turn);
|
|
27
|
-
|
|
28
|
-
this.#reserveIfIdle();
|
|
34
|
+
this.#changed();
|
|
29
35
|
};
|
|
30
|
-
|
|
36
|
+
#changed() {
|
|
37
|
+
this.#changedAt = Date.now();
|
|
38
|
+
if (this.count() === 0) {
|
|
39
|
+
for (const resolve of this.#idleWaiters) {
|
|
40
|
+
resolve();
|
|
41
|
+
}
|
|
42
|
+
this.#idleWaiters.clear();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
whenIdle = (signal) => {
|
|
31
46
|
signal.throwIfAborted();
|
|
32
|
-
if (this
|
|
33
|
-
|
|
47
|
+
if (this.count() === 0) {
|
|
48
|
+
return Promise.resolve();
|
|
34
49
|
}
|
|
35
50
|
return new Promise((resolve, reject) => {
|
|
36
51
|
const abort = () => {
|
|
37
|
-
this.#
|
|
38
|
-
signal.removeEventListener("abort", abort);
|
|
52
|
+
this.#idleWaiters.delete(idle);
|
|
39
53
|
reject(signal.reason);
|
|
40
54
|
};
|
|
41
|
-
const
|
|
42
|
-
this.#admission = { kind: "reserved" };
|
|
55
|
+
const idle = () => {
|
|
43
56
|
signal.removeEventListener("abort", abort);
|
|
44
|
-
resolve(
|
|
45
|
-
[Symbol.dispose]: () => {
|
|
46
|
-
this.#admission = { kind: "open" };
|
|
47
|
-
},
|
|
48
|
-
});
|
|
57
|
+
resolve();
|
|
49
58
|
};
|
|
50
|
-
this.#
|
|
59
|
+
this.#idleWaiters.add(idle);
|
|
51
60
|
signal.addEventListener("abort", abort, { once: true });
|
|
52
|
-
if (this.count() === 0) {
|
|
53
|
-
reserve();
|
|
54
|
-
}
|
|
55
61
|
});
|
|
56
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Close admission only after the Runtime has had no work for `quietMilliseconds`.
|
|
65
|
+
* The moment a reply finishes is when a user is most likely to continue, so idle
|
|
66
|
+
* alone is not an upgrade window. Checking and reserving happen synchronously, so
|
|
67
|
+
* no prompt can be admitted between them.
|
|
68
|
+
*/
|
|
69
|
+
reserveIfQuiet = (quietMilliseconds) => {
|
|
70
|
+
if (this.#reserved) {
|
|
71
|
+
throw new Error("A daemon upgrade already owns admission");
|
|
72
|
+
}
|
|
73
|
+
if (this.count() > 0 || Date.now() - this.#changedAt < quietMilliseconds) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
this.#reserved = true;
|
|
77
|
+
return {
|
|
78
|
+
[Symbol.dispose]: () => {
|
|
79
|
+
this.#reserved = false;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
};
|
|
57
83
|
}
|
|
58
84
|
//# sourceMappingURL=runtime-turn-activity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-turn-activity.js","sourceRoot":"","sources":["../../../src/session/turn/runtime-turn-activity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime-turn-activity.js","sourceRoot":"","sources":["../../../src/session/turn/runtime-turn-activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,14 +2,10 @@
|
|
|
2
2
|
import { lstat as lstat2 } from "node:fs/promises";
|
|
3
3
|
|
|
4
4
|
// src/util/platform/linux.ts
|
|
5
|
-
import { constants as constants2, readdirSync, readFileSync } from "node:fs";
|
|
6
|
-
import { access as access2, readdir, readFile, realpath as realpath2, stat } from "node:fs/promises";
|
|
7
5
|
import { isAbsolute, join as join2 } from "node:path";
|
|
8
6
|
|
|
9
7
|
// src/util/platform/posix.ts
|
|
10
|
-
import {
|
|
11
|
-
import { constants } from "node:fs";
|
|
12
|
-
import { access, chmod, lstat, realpath, unlink } from "node:fs/promises";
|
|
8
|
+
import { chmod, lstat, unlink } from "node:fs/promises";
|
|
13
9
|
import { tmpdir } from "node:os";
|
|
14
10
|
import { join } from "node:path";
|
|
15
11
|
|
|
@@ -23,85 +19,6 @@ var LocalPathError = class extends Error {
|
|
|
23
19
|
};
|
|
24
20
|
|
|
25
21
|
// src/util/platform/posix.ts
|
|
26
|
-
var PROCESS_TABLE_TIMEOUT_MILLISECONDS = 1e3;
|
|
27
|
-
var PROCESS_TABLE_OUTPUT_LIMIT_BYTES = 1024 * 1024;
|
|
28
|
-
function parseProcessTable(output) {
|
|
29
|
-
const entries = [];
|
|
30
|
-
for (const line of output.split("\n")) {
|
|
31
|
-
const groups = /^\s*(?<pid>\d+)\s+(?<ppid>\d+)\s+(?<pgid>\d+)\s*$/.exec(line)?.groups;
|
|
32
|
-
if (groups === void 0) {
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
const processId = Number(groups["pid"]);
|
|
36
|
-
const parentProcessId = Number(groups["ppid"]);
|
|
37
|
-
const processGroupId = Number(groups["pgid"]);
|
|
38
|
-
if (!Number.isSafeInteger(processId) || processId <= 0 || !Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
entries.push({ parentProcessId, processGroupId, processId });
|
|
42
|
-
}
|
|
43
|
-
return entries;
|
|
44
|
-
}
|
|
45
|
-
function readProcessTableWithPs(executable) {
|
|
46
|
-
return new Promise((resolveTable) => {
|
|
47
|
-
execFile(
|
|
48
|
-
executable,
|
|
49
|
-
["-axo", "pid=,ppid=,pgid="],
|
|
50
|
-
{
|
|
51
|
-
encoding: "utf8",
|
|
52
|
-
maxBuffer: PROCESS_TABLE_OUTPUT_LIMIT_BYTES,
|
|
53
|
-
signal: AbortSignal.timeout(PROCESS_TABLE_TIMEOUT_MILLISECONDS),
|
|
54
|
-
timeout: PROCESS_TABLE_TIMEOUT_MILLISECONDS
|
|
55
|
-
},
|
|
56
|
-
(error, stdout) => {
|
|
57
|
-
resolveTable(error === null ? parseProcessTable(stdout) : []);
|
|
58
|
-
}
|
|
59
|
-
);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
function processExists(processId) {
|
|
63
|
-
try {
|
|
64
|
-
process.kill(processId, 0);
|
|
65
|
-
return true;
|
|
66
|
-
} catch {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function signalCapturedProcesses(processes, rootProcessId, signal) {
|
|
71
|
-
const processIds = new Set(processes.map((identity) => identity.processId));
|
|
72
|
-
const signalledGroups = /* @__PURE__ */ new Set();
|
|
73
|
-
for (const identity of processes) {
|
|
74
|
-
const isRootProcessGroup = identity.processGroupId === rootProcessId;
|
|
75
|
-
if (!isRootProcessGroup && !processIds.has(identity.processGroupId) || signalledGroups.has(identity.processGroupId)) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
try {
|
|
79
|
-
process.kill(-identity.processGroupId, signal);
|
|
80
|
-
signalledGroups.add(identity.processGroupId);
|
|
81
|
-
} catch {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
for (const identity of processes) {
|
|
85
|
-
if (identity.processId === rootProcessId || identity.processGroupId === rootProcessId || signalledGroups.has(identity.processGroupId)) {
|
|
86
|
-
continue;
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
process.kill(identity.processId, signal);
|
|
90
|
-
} catch {
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function terminateProcess(child, signal) {
|
|
95
|
-
if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
try {
|
|
99
|
-
process.kill(-child.pid, signal);
|
|
100
|
-
return;
|
|
101
|
-
} catch {
|
|
102
|
-
}
|
|
103
|
-
child.kill(signal);
|
|
104
|
-
}
|
|
105
22
|
async function removeControlSocket(path) {
|
|
106
23
|
try {
|
|
107
24
|
await unlink(path);
|
|
@@ -118,18 +35,6 @@ var posixOperations = {
|
|
|
118
35
|
await chmod(path, 384);
|
|
119
36
|
},
|
|
120
37
|
removeControlSocket,
|
|
121
|
-
pathDelimiter: ":",
|
|
122
|
-
environmentValue: (environment, name) => environment[name],
|
|
123
|
-
executableExtensions: () => [""],
|
|
124
|
-
resolveExecutableTarget: async (path) => {
|
|
125
|
-
const target = await realpath(path);
|
|
126
|
-
await access(target, constants.X_OK);
|
|
127
|
-
return target;
|
|
128
|
-
},
|
|
129
|
-
executableLaunch: (command, args) => ({ command, arguments: args }),
|
|
130
|
-
spawnOptions: { detached: true, windowsHide: true },
|
|
131
|
-
signalCapturedProcesses,
|
|
132
|
-
terminateProcess,
|
|
133
38
|
validatePathPermissions: async (path, directory, privateAccess, signal) => {
|
|
134
39
|
signal.throwIfAborted();
|
|
135
40
|
const metadata = await lstat(path);
|
|
@@ -144,110 +49,8 @@ var posixOperations = {
|
|
|
144
49
|
};
|
|
145
50
|
|
|
146
51
|
// src/util/platform/linux.ts
|
|
147
|
-
function appendLinuxProcessTableEntry(entries, processId, encoded) {
|
|
148
|
-
const closingParenthesis = encoded.lastIndexOf(")");
|
|
149
|
-
if (!encoded.startsWith(`${processId.toString()} (`) || closingParenthesis < 0) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
const fields = encoded.slice(closingParenthesis + 1).trim().split(/\s+/);
|
|
153
|
-
const parentProcessId = Number(fields[1]);
|
|
154
|
-
const processGroupId = Number(fields[2]);
|
|
155
|
-
if (!Number.isSafeInteger(parentProcessId) || parentProcessId < 0 || !Number.isSafeInteger(processGroupId) || processGroupId <= 0) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
entries.push({ parentProcessId, processGroupId, processId });
|
|
159
|
-
}
|
|
160
|
-
async function readLinuxProcessTable() {
|
|
161
|
-
const entries = [];
|
|
162
|
-
try {
|
|
163
|
-
const directories = await readdir("/proc", { withFileTypes: true });
|
|
164
|
-
for (const directory of directories) {
|
|
165
|
-
if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
const processId = Number(directory.name);
|
|
169
|
-
if (!Number.isSafeInteger(processId) || processId <= 0) {
|
|
170
|
-
continue;
|
|
171
|
-
}
|
|
172
|
-
try {
|
|
173
|
-
appendLinuxProcessTableEntry(
|
|
174
|
-
entries,
|
|
175
|
-
processId,
|
|
176
|
-
await readFile(join2("/proc", directory.name, "stat"), "utf8")
|
|
177
|
-
);
|
|
178
|
-
} catch {
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
} catch {
|
|
182
|
-
}
|
|
183
|
-
return entries;
|
|
184
|
-
}
|
|
185
|
-
function readLinuxProcessTableSynchronously() {
|
|
186
|
-
const entries = [];
|
|
187
|
-
try {
|
|
188
|
-
const directories = readdirSync("/proc", { withFileTypes: true });
|
|
189
|
-
for (const directory of directories) {
|
|
190
|
-
if (!directory.isDirectory() || !/^\d+$/.test(directory.name)) {
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
const processId = Number(directory.name);
|
|
194
|
-
if (!Number.isSafeInteger(processId) || processId <= 0) {
|
|
195
|
-
continue;
|
|
196
|
-
}
|
|
197
|
-
try {
|
|
198
|
-
appendLinuxProcessTableEntry(
|
|
199
|
-
entries,
|
|
200
|
-
processId,
|
|
201
|
-
readFileSync(join2("/proc", directory.name, "stat"), "utf8")
|
|
202
|
-
);
|
|
203
|
-
} catch {
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
} catch {
|
|
207
|
-
}
|
|
208
|
-
return entries;
|
|
209
|
-
}
|
|
210
|
-
async function readLinuxProcessTableWithFallback() {
|
|
211
|
-
const procfsEntries = await readLinuxProcessTable();
|
|
212
|
-
if (procfsEntries.length > 0) {
|
|
213
|
-
return procfsEntries;
|
|
214
|
-
}
|
|
215
|
-
for (const candidate of ["/usr/bin/ps", "/bin/ps", "/run/current-system/sw/bin/ps"]) {
|
|
216
|
-
try {
|
|
217
|
-
const resolvedPath = await realpath2(candidate);
|
|
218
|
-
if (!(await stat(resolvedPath)).isFile()) {
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
await access2(resolvedPath, constants2.X_OK);
|
|
222
|
-
} catch {
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
const entries = await readProcessTableWithPs(candidate);
|
|
226
|
-
if (entries.length > 0) {
|
|
227
|
-
return entries;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
return [];
|
|
231
|
-
}
|
|
232
|
-
function processExists2(processId) {
|
|
233
|
-
try {
|
|
234
|
-
const encoded = readFileSync(join2("/proc", processId.toString(), "stat"), "utf8");
|
|
235
|
-
const closingParenthesis = encoded.lastIndexOf(")");
|
|
236
|
-
if (closingParenthesis >= 0) {
|
|
237
|
-
const processState = encoded.slice(closingParenthesis + 1).trimStart().charAt(0);
|
|
238
|
-
if (processState === "Z" || processState === "X") {
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
} catch {
|
|
243
|
-
}
|
|
244
|
-
return processExists(processId);
|
|
245
|
-
}
|
|
246
52
|
var linuxPlatform = {
|
|
247
53
|
...posixOperations,
|
|
248
|
-
readProcessTable: readLinuxProcessTableWithFallback,
|
|
249
|
-
readProcessTableSynchronously: readLinuxProcessTableSynchronously,
|
|
250
|
-
processExists: processExists2,
|
|
251
54
|
claudeCodeExecutablePaths: (environment) => {
|
|
252
55
|
const homeDirectory = environment["HOME"];
|
|
253
56
|
return homeDirectory !== void 0 && isAbsolute(homeDirectory) ? [join2(homeDirectory, ".local", "bin", "claude")] : [];
|
|
@@ -258,11 +61,11 @@ var linuxPlatform = {
|
|
|
258
61
|
import { isAbsolute as isAbsolute2, join as join4 } from "node:path";
|
|
259
62
|
|
|
260
63
|
// src/util/platform/claude-desktop.ts
|
|
261
|
-
import { readdirSync
|
|
64
|
+
import { readdirSync } from "node:fs";
|
|
262
65
|
import { join as join3 } from "node:path";
|
|
263
66
|
function installedDirectories(directory) {
|
|
264
67
|
try {
|
|
265
|
-
return
|
|
68
|
+
return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
266
69
|
} catch (cause) {
|
|
267
70
|
if (cause instanceof Error && "code" in cause && (cause.code === "ENOENT" || cause.code === "ENOTDIR" || cause.code === "EACCES")) {
|
|
268
71
|
return [];
|
|
@@ -293,9 +96,6 @@ function claudeDesktopExecutablePaths(roots, executablePaths) {
|
|
|
293
96
|
// src/util/platform/macos.ts
|
|
294
97
|
var macosPlatform = {
|
|
295
98
|
...posixOperations,
|
|
296
|
-
readProcessTable: () => readProcessTableWithPs("/bin/ps"),
|
|
297
|
-
readProcessTableSynchronously: () => [],
|
|
298
|
-
processExists,
|
|
299
99
|
claudeCodeExecutablePaths: (environment) => {
|
|
300
100
|
const paths = ["/opt/homebrew/bin/claude", "/usr/local/bin/claude"];
|
|
301
101
|
const homeDirectory = environment["HOME"];
|
|
@@ -313,23 +113,10 @@ var macosPlatform = {
|
|
|
313
113
|
};
|
|
314
114
|
|
|
315
115
|
// src/util/platform/windows.ts
|
|
316
|
-
import { execFile
|
|
317
|
-
import {
|
|
318
|
-
import { dirname, extname, isAbsolute as isAbsolute3, join as join5, resolve } from "node:path";
|
|
116
|
+
import { execFile } from "node:child_process";
|
|
117
|
+
import { isAbsolute as isAbsolute3, join as join5 } from "node:path";
|
|
319
118
|
import { promisify } from "node:util";
|
|
320
|
-
|
|
321
|
-
// src/util/process/process-error.ts
|
|
322
|
-
var ProcessExecutionError = class extends Error {
|
|
323
|
-
code;
|
|
324
|
-
constructor(code, message, options = {}) {
|
|
325
|
-
super(message, options);
|
|
326
|
-
this.code = code;
|
|
327
|
-
this.name = "ProcessExecutionError";
|
|
328
|
-
}
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
// src/util/platform/windows.ts
|
|
332
|
-
var execute = promisify(execFile2);
|
|
119
|
+
var execute = promisify(execFile);
|
|
333
120
|
function environmentValue(environment, name) {
|
|
334
121
|
return Object.entries(environment).find(([key]) => key.toUpperCase() === name.toUpperCase())?.[1];
|
|
335
122
|
}
|
|
@@ -350,97 +137,6 @@ function desktopClaudeExecutablePaths(environment) {
|
|
|
350
137
|
}
|
|
351
138
|
return claudeDesktopExecutablePaths(roots, [["claude.exe"]]);
|
|
352
139
|
}
|
|
353
|
-
function executableExtensions(executableName, environment) {
|
|
354
|
-
if (/\.[a-zA-Z0-9]+$/.test(executableName)) {
|
|
355
|
-
return [""];
|
|
356
|
-
}
|
|
357
|
-
const configured = environmentValue(environment, "PATHEXT") ?? ".COM;.EXE;.BAT;.CMD";
|
|
358
|
-
const extensions = configured.split(";").map((extension) => extension.trim()).filter((extension) => extension.length > 0).map((extension) => extension.startsWith(".") ? extension : `.${extension}`);
|
|
359
|
-
return extensions.length > 0 ? extensions : [".EXE"];
|
|
360
|
-
}
|
|
361
|
-
async function resolveExecutableTarget(path) {
|
|
362
|
-
let resolvedPath;
|
|
363
|
-
try {
|
|
364
|
-
resolvedPath = await realpath3(extname(path) === "" ? `${path}.cmd` : path);
|
|
365
|
-
} catch (cause) {
|
|
366
|
-
if (extname(path) !== "" || !(cause instanceof Error) || !("code" in cause) || cause.code !== "ENOENT") {
|
|
367
|
-
throw cause;
|
|
368
|
-
}
|
|
369
|
-
resolvedPath = await realpath3(path);
|
|
370
|
-
}
|
|
371
|
-
if (extname(resolvedPath).toLowerCase() === ".cmd") {
|
|
372
|
-
const shim = await readFile2(resolvedPath, "utf8");
|
|
373
|
-
if (shim.includes('SET "NPM_CLI_JS=%~dp0\\node_modules\\npm\\bin\\npm-cli.js"') && shim.includes('"%NODE_EXE%" "%NPM_CLI_JS%" %*')) {
|
|
374
|
-
return await realpath3(resolve(dirname(resolvedPath), "node_modules/npm/bin/npm-cli.js"));
|
|
375
|
-
}
|
|
376
|
-
const script = /"%_prog%"\s+"%dp0%[\\/]([^"\r\n]+\.(?:js|mjs|cjs))"\s+%\*/iu.exec(shim)?.[1];
|
|
377
|
-
if (script !== void 0 && shim.includes("SET dp0=%~dp0")) {
|
|
378
|
-
resolvedPath = await realpath3(resolve(dirname(resolvedPath), script));
|
|
379
|
-
} else {
|
|
380
|
-
const pnpmScript = /^\s*node\s+"%~dp0[\\/]([^"\r\n]+\.(?:js|mjs|cjs))"\s+%\*\s*$/imu.exec(shim)?.[1];
|
|
381
|
-
if (pnpmScript === void 0 || !shim.includes("@SETLOCAL")) {
|
|
382
|
-
throw new ProcessExecutionError(
|
|
383
|
-
"process_unsupported_script",
|
|
384
|
-
"Use a native executable or a verified Node entrypoint"
|
|
385
|
-
);
|
|
386
|
-
}
|
|
387
|
-
resolvedPath = await realpath3(resolve(dirname(resolvedPath), pnpmScript));
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
return resolvedPath;
|
|
391
|
-
}
|
|
392
|
-
function executableLaunch(command, args) {
|
|
393
|
-
if (/\.(?:js|mjs|cjs)$/iu.test(command)) {
|
|
394
|
-
return { command: process.execPath, arguments: [command, ...args] };
|
|
395
|
-
}
|
|
396
|
-
if (/\.(?:cmd|bat)$/iu.test(command)) {
|
|
397
|
-
throw new ProcessExecutionError(
|
|
398
|
-
"process_unsupported_script",
|
|
399
|
-
"Use a native executable or a verified Node entrypoint"
|
|
400
|
-
);
|
|
401
|
-
}
|
|
402
|
-
return { command, arguments: args };
|
|
403
|
-
}
|
|
404
|
-
function readProcessTable() {
|
|
405
|
-
const systemRoot = environmentValue(process.env, "SystemRoot");
|
|
406
|
-
if (systemRoot === void 0) {
|
|
407
|
-
return Promise.resolve([]);
|
|
408
|
-
}
|
|
409
|
-
return new Promise((resolveTable) => {
|
|
410
|
-
execFile2(
|
|
411
|
-
join5(systemRoot, "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
|
|
412
|
-
[
|
|
413
|
-
"-NoLogo",
|
|
414
|
-
"-NoProfile",
|
|
415
|
-
"-NonInteractive",
|
|
416
|
-
"-Command",
|
|
417
|
-
"Get-CimInstance Win32_Process | ForEach-Object { '{0} {1} {0}' -f $_.ProcessId, $_.ParentProcessId }"
|
|
418
|
-
],
|
|
419
|
-
{
|
|
420
|
-
encoding: "utf8",
|
|
421
|
-
windowsHide: true,
|
|
422
|
-
timeout: 1e4,
|
|
423
|
-
signal: AbortSignal.timeout(1e4),
|
|
424
|
-
maxBuffer: 1024 * 1024
|
|
425
|
-
},
|
|
426
|
-
(error, stdout) => resolveTable(error === null ? parseProcessTable(stdout) : [])
|
|
427
|
-
);
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
function signalCapturedProcesses2(processes, _rootProcessId, signal) {
|
|
431
|
-
for (const identity of [...processes].reverse()) {
|
|
432
|
-
try {
|
|
433
|
-
process.kill(identity.processId, signal);
|
|
434
|
-
} catch {
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
function terminateProcess2(child, signal) {
|
|
439
|
-
if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
child.kill(signal);
|
|
443
|
-
}
|
|
444
140
|
var windowsPermissions = `
|
|
445
141
|
$ErrorActionPreference = 'Stop'
|
|
446
142
|
$ProgressPreference = 'SilentlyContinue'
|
|
@@ -506,18 +202,7 @@ var windowsPlatform = {
|
|
|
506
202
|
},
|
|
507
203
|
removeControlSocket: async () => {
|
|
508
204
|
},
|
|
509
|
-
pathDelimiter: ";",
|
|
510
|
-
environmentValue,
|
|
511
|
-
executableExtensions,
|
|
512
|
-
resolveExecutableTarget,
|
|
513
|
-
executableLaunch,
|
|
514
|
-
spawnOptions: { detached: false, windowsHide: true },
|
|
515
|
-
signalCapturedProcesses: signalCapturedProcesses2,
|
|
516
|
-
terminateProcess: terminateProcess2,
|
|
517
205
|
validatePathPermissions,
|
|
518
|
-
readProcessTable,
|
|
519
|
-
readProcessTableSynchronously: () => [],
|
|
520
|
-
processExists,
|
|
521
206
|
claudeCodeExecutablePaths: (environment) => {
|
|
522
207
|
const paths = [];
|
|
523
208
|
const userProfile = environmentValue(environment, "USERPROFILE");
|
|
@@ -536,9 +221,6 @@ var windowsPlatform = {
|
|
|
536
221
|
// src/util/platform/index.ts
|
|
537
222
|
var fallbackPlatform = {
|
|
538
223
|
...posixOperations,
|
|
539
|
-
readProcessTable: () => readProcessTableWithPs("/usr/bin/ps"),
|
|
540
|
-
readProcessTableSynchronously: () => [],
|
|
541
|
-
processExists,
|
|
542
224
|
claudeCodeExecutablePaths: () => []
|
|
543
225
|
};
|
|
544
226
|
var platforms = /* @__PURE__ */ new Map([
|