@aspectlylabs/mikka 0.0.65 → 0.0.66
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 +19 -0
- package/cli.js +513 -390
- package/client.js +2 -2
- package/http-link.js +2 -2
- package/login.js +2 -2
- package/main.js +280 -182
- package/mikka-release-manifest.json +18 -18
- package/mikka.js +513 -390
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/paths.js +2 -2
- package/sbom.cdx.json +7 -7
package/main.js
CHANGED
|
@@ -2212,8 +2212,8 @@ var EventQueue = class {
|
|
|
2212
2212
|
if (next.type === "exit") return;
|
|
2213
2213
|
continue;
|
|
2214
2214
|
}
|
|
2215
|
-
await new Promise((
|
|
2216
|
-
this.waiter =
|
|
2215
|
+
await new Promise((resolve12) => {
|
|
2216
|
+
this.waiter = resolve12;
|
|
2217
2217
|
});
|
|
2218
2218
|
}
|
|
2219
2219
|
}
|
|
@@ -2284,13 +2284,13 @@ async function spawnCli(sandbox, argv, options) {
|
|
|
2284
2284
|
stderr = (stderr + data).slice(-STDERR_TAIL * 4);
|
|
2285
2285
|
});
|
|
2286
2286
|
const exited = new Promise(
|
|
2287
|
-
(
|
|
2287
|
+
(resolve12) => {
|
|
2288
2288
|
child.once("error", (error) => {
|
|
2289
2289
|
stderr += `
|
|
2290
2290
|
${error.message}`;
|
|
2291
|
-
|
|
2291
|
+
resolve12({ code: null, signal: null });
|
|
2292
2292
|
});
|
|
2293
|
-
child.once("exit", (code, signal) =>
|
|
2293
|
+
child.once("exit", (code, signal) => resolve12({ code, signal }));
|
|
2294
2294
|
}
|
|
2295
2295
|
).finally(() => {
|
|
2296
2296
|
signalGroup(pgid, "SIGKILL");
|
|
@@ -2307,8 +2307,8 @@ ${error.message}`;
|
|
|
2307
2307
|
let timer;
|
|
2308
2308
|
await Promise.race([
|
|
2309
2309
|
exited,
|
|
2310
|
-
new Promise((
|
|
2311
|
-
timer = setTimeout(
|
|
2310
|
+
new Promise((resolve12) => {
|
|
2311
|
+
timer = setTimeout(resolve12, graceMs);
|
|
2312
2312
|
})
|
|
2313
2313
|
]);
|
|
2314
2314
|
clearTimeout(timer);
|
|
@@ -2389,11 +2389,11 @@ var JsonlWriter = class extends AbstractMessageWriter {
|
|
|
2389
2389
|
}
|
|
2390
2390
|
stream;
|
|
2391
2391
|
write(message) {
|
|
2392
|
-
return new Promise((
|
|
2392
|
+
return new Promise((resolve12, reject) => {
|
|
2393
2393
|
this.stream.write(
|
|
2394
2394
|
`${JSON.stringify(message)}
|
|
2395
2395
|
`,
|
|
2396
|
-
(error) => error ? reject(error) :
|
|
2396
|
+
(error) => error ? reject(error) : resolve12()
|
|
2397
2397
|
);
|
|
2398
2398
|
});
|
|
2399
2399
|
}
|
|
@@ -3728,7 +3728,7 @@ import { join as join5 } from "node:path";
|
|
|
3728
3728
|
// package.json
|
|
3729
3729
|
var package_default = {
|
|
3730
3730
|
name: "@mikka/daemon",
|
|
3731
|
-
version: "0.0.
|
|
3731
|
+
version: "0.0.66",
|
|
3732
3732
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
3733
3733
|
type: "module",
|
|
3734
3734
|
private: true,
|
|
@@ -3787,7 +3787,7 @@ var package_default = {
|
|
|
3787
3787
|
engines: {
|
|
3788
3788
|
node: ">=24"
|
|
3789
3789
|
},
|
|
3790
|
-
gitHead: "
|
|
3790
|
+
gitHead: "362a5415cfca1dae687f81b235450908b4412153"
|
|
3791
3791
|
};
|
|
3792
3792
|
|
|
3793
3793
|
// src/paths.ts
|
|
@@ -6181,8 +6181,8 @@ async function runCodexCoordinator(input, host) {
|
|
|
6181
6181
|
const messages = /* @__PURE__ */ new Map();
|
|
6182
6182
|
let resolveEnd;
|
|
6183
6183
|
let rejectEnd;
|
|
6184
|
-
const ended = new Promise((
|
|
6185
|
-
resolveEnd =
|
|
6184
|
+
const ended = new Promise((resolve12, reject) => {
|
|
6185
|
+
resolveEnd = resolve12;
|
|
6186
6186
|
rejectEnd = reject;
|
|
6187
6187
|
});
|
|
6188
6188
|
void ended.catch(() => void 0);
|
|
@@ -6363,10 +6363,10 @@ import {
|
|
|
6363
6363
|
mkdirSync as mkdirSync16,
|
|
6364
6364
|
readFileSync as readFileSync11,
|
|
6365
6365
|
rmSync as rmSync17,
|
|
6366
|
-
realpathSync as
|
|
6366
|
+
realpathSync as realpathSync13
|
|
6367
6367
|
} from "node:fs";
|
|
6368
6368
|
import { arch, hostname, platform as platform2 } from "node:os";
|
|
6369
|
-
import { join as
|
|
6369
|
+
import { join as join28 } from "node:path";
|
|
6370
6370
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6371
6371
|
|
|
6372
6372
|
// src/adapters/claude.ts
|
|
@@ -6492,8 +6492,8 @@ function spawnRunSandbox(options) {
|
|
|
6492
6492
|
let outcome;
|
|
6493
6493
|
let hardStop;
|
|
6494
6494
|
let settle;
|
|
6495
|
-
const exited = new Promise((
|
|
6496
|
-
settle =
|
|
6495
|
+
const exited = new Promise((resolve12) => {
|
|
6496
|
+
settle = resolve12;
|
|
6497
6497
|
});
|
|
6498
6498
|
function send(message) {
|
|
6499
6499
|
if (!child.connected || gone) return;
|
|
@@ -6766,9 +6766,9 @@ async function createNativeSubscriptionBroker(host) {
|
|
|
6766
6766
|
}
|
|
6767
6767
|
});
|
|
6768
6768
|
try {
|
|
6769
|
-
await new Promise((
|
|
6769
|
+
await new Promise((resolve12, reject) => {
|
|
6770
6770
|
server.once("error", reject);
|
|
6771
|
-
server.listen(socket,
|
|
6771
|
+
server.listen(socket, resolve12);
|
|
6772
6772
|
});
|
|
6773
6773
|
chmodSync(socket, 384);
|
|
6774
6774
|
} catch {
|
|
@@ -6781,7 +6781,7 @@ async function createNativeSubscriptionBroker(host) {
|
|
|
6781
6781
|
halted = true;
|
|
6782
6782
|
for (const abort of pending) abort.abort();
|
|
6783
6783
|
server.closeAllConnections();
|
|
6784
|
-
await new Promise((
|
|
6784
|
+
await new Promise((resolve12) => server.close(() => resolve12()));
|
|
6785
6785
|
rmSync9(dir, { recursive: true, force: true });
|
|
6786
6786
|
}
|
|
6787
6787
|
};
|
|
@@ -6945,8 +6945,8 @@ var PromptQueue = class {
|
|
|
6945
6945
|
continue;
|
|
6946
6946
|
}
|
|
6947
6947
|
if (this.closed) return;
|
|
6948
|
-
await new Promise((
|
|
6949
|
-
this.waiter =
|
|
6948
|
+
await new Promise((resolve12) => {
|
|
6949
|
+
this.waiter = resolve12;
|
|
6950
6950
|
});
|
|
6951
6951
|
}
|
|
6952
6952
|
}
|
|
@@ -6960,8 +6960,8 @@ async function untilSpoken(spoken) {
|
|
|
6960
6960
|
try {
|
|
6961
6961
|
return await Promise.race([
|
|
6962
6962
|
spoken,
|
|
6963
|
-
new Promise((
|
|
6964
|
-
timer = setTimeout(() =>
|
|
6963
|
+
new Promise((resolve12) => {
|
|
6964
|
+
timer = setTimeout(() => resolve12(true), CONTINUE_SILENCE_MS);
|
|
6965
6965
|
})
|
|
6966
6966
|
]);
|
|
6967
6967
|
} finally {
|
|
@@ -7098,9 +7098,9 @@ var ClaudeAdapter = class {
|
|
|
7098
7098
|
let stderr = "";
|
|
7099
7099
|
const stderrTail = () => stderr.slice(-STDERR_TAIL2).trim() || "no output";
|
|
7100
7100
|
let spoke = () => void 0;
|
|
7101
|
-
const spoken = new Promise((
|
|
7101
|
+
const spoken = new Promise((resolve12) => spoke = resolve12);
|
|
7102
7102
|
let finished = () => void 0;
|
|
7103
|
-
const gone = new Promise((
|
|
7103
|
+
const gone = new Promise((resolve12) => finished = resolve12);
|
|
7104
7104
|
if (externalAuth && this.options.onHostedSession) {
|
|
7105
7105
|
try {
|
|
7106
7106
|
await this.options.onHostedSession(sessionId);
|
|
@@ -8451,7 +8451,7 @@ var MockAdapter = class {
|
|
|
8451
8451
|
if (line.hang) {
|
|
8452
8452
|
if (!abort.signal.aborted) {
|
|
8453
8453
|
await new Promise(
|
|
8454
|
-
(
|
|
8454
|
+
(resolve12) => abort.signal.addEventListener("abort", resolve12, { once: true })
|
|
8455
8455
|
);
|
|
8456
8456
|
}
|
|
8457
8457
|
yield { type: "exit", outcome: "cancelled" };
|
|
@@ -8815,35 +8815,71 @@ async function verifyExpectedOrigin(path, expected) {
|
|
|
8815
8815
|
}
|
|
8816
8816
|
}
|
|
8817
8817
|
|
|
8818
|
-
// src/
|
|
8818
|
+
// src/auto-update.ts
|
|
8819
8819
|
import { execFile as execFile2 } from "node:child_process";
|
|
8820
|
-
import {
|
|
8821
|
-
import { mkdir, writeFile, rm } from "node:fs/promises";
|
|
8820
|
+
import { realpathSync as realpathSync10 } from "node:fs";
|
|
8822
8821
|
import { homedir as homedir6 } from "node:os";
|
|
8823
8822
|
import { dirname as dirname9, join as join17, resolve as resolve8 } from "node:path";
|
|
8823
|
+
import { promisify as promisify2 } from "node:util";
|
|
8824
8824
|
var exec = promisify2(execFile2);
|
|
8825
|
+
var DAY = 24 * 60 * 60 * 1e3;
|
|
8826
|
+
function newerStableVersion(candidate, current) {
|
|
8827
|
+
const stable = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
8828
|
+
if (typeof candidate !== "string" || !stable.test(candidate) || !stable.test(current)) return false;
|
|
8829
|
+
const a = candidate.split(".").map(BigInt), b = current.split(".").map(BigInt);
|
|
8830
|
+
for (let i = 0; i < 3; i++) if (a[i] !== b[i]) return a[i] > b[i];
|
|
8831
|
+
return false;
|
|
8832
|
+
}
|
|
8833
|
+
async function runServiceNpm(args) {
|
|
8834
|
+
const npm = realpathSync10(join17(dirname9(process.execPath), "npm"));
|
|
8835
|
+
const { stdout } = await exec(process.execPath, [npm, ...args], {
|
|
8836
|
+
cwd: homedir6(),
|
|
8837
|
+
timeout: 3e5,
|
|
8838
|
+
maxBuffer: 1024 * 1024,
|
|
8839
|
+
env: { ...process.env, PATH: `${dirname9(process.execPath)}:${process.env.PATH ?? ""}` }
|
|
8840
|
+
});
|
|
8841
|
+
return stdout.trim();
|
|
8842
|
+
}
|
|
8843
|
+
async function checkLatestVersion(file, current, runtime, now = Date.now()) {
|
|
8844
|
+
const state = readJson(file);
|
|
8845
|
+
if (typeof state?.lastAttemptAt === "number" && now - state.lastAttemptAt < DAY) return;
|
|
8846
|
+
writeJsonAtomic(file, { lastAttemptAt: now });
|
|
8847
|
+
const latest = await runtime.latest();
|
|
8848
|
+
return newerStableVersion(latest, current) ? latest : void 0;
|
|
8849
|
+
}
|
|
8850
|
+
|
|
8851
|
+
// src/service.ts
|
|
8852
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
8853
|
+
import { promisify as promisify3 } from "node:util";
|
|
8854
|
+
import { mkdir, writeFile, rm } from "node:fs/promises";
|
|
8855
|
+
import { homedir as homedir7 } from "node:os";
|
|
8856
|
+
import { dirname as dirname10, join as join18, resolve as resolve9 } from "node:path";
|
|
8857
|
+
var exec2 = promisify3(execFile3);
|
|
8825
8858
|
var label = "com.aspectlylabs.mikka.daemon";
|
|
8826
8859
|
async function restartService(update, beforeRestart, dependencies = {
|
|
8827
8860
|
manager: process.env.MIKKA_SERVICE,
|
|
8828
8861
|
update: async () => {
|
|
8829
|
-
await
|
|
8862
|
+
await runServiceNpm(["install", "--global", "--engine-strict", "@aspectlylabs/mikka"]);
|
|
8830
8863
|
},
|
|
8831
8864
|
restart: () => {
|
|
8832
|
-
setImmediate(() =>
|
|
8865
|
+
setImmediate(() => {
|
|
8866
|
+
if (canRestart()) process.kill(process.pid, "SIGUSR2");
|
|
8867
|
+
});
|
|
8833
8868
|
}
|
|
8834
|
-
}) {
|
|
8869
|
+
}, canRestart = () => true) {
|
|
8835
8870
|
const manager = dependencies.manager;
|
|
8836
8871
|
if (manager !== "systemd" && manager !== "launchd") throw new Error("Daemon is not running as a managed service");
|
|
8837
8872
|
if (update) await dependencies.update();
|
|
8873
|
+
if (!canRestart()) return;
|
|
8838
8874
|
beforeRestart();
|
|
8839
8875
|
dependencies.restart();
|
|
8840
8876
|
}
|
|
8841
8877
|
async function uninstallService(clearCredential, dependencies = {
|
|
8842
8878
|
manager: process.env.MIKKA_SERVICE,
|
|
8843
|
-
home:
|
|
8879
|
+
home: homedir7(),
|
|
8844
8880
|
uid: process.getuid?.() ?? 0,
|
|
8845
8881
|
run: async (program, args) => {
|
|
8846
|
-
await
|
|
8882
|
+
await exec2(program, args, { timeout: 1e4 });
|
|
8847
8883
|
},
|
|
8848
8884
|
exit: () => {
|
|
8849
8885
|
process.exit(0);
|
|
@@ -8852,10 +8888,10 @@ async function uninstallService(clearCredential, dependencies = {
|
|
|
8852
8888
|
try {
|
|
8853
8889
|
if (dependencies.manager === "systemd") {
|
|
8854
8890
|
await dependencies.run("systemctl", ["--user", "disable", "mikka-daemon.service"]);
|
|
8855
|
-
await rm(
|
|
8891
|
+
await rm(join18(dependencies.home, ".config/systemd/user/mikka-daemon.service"), { force: true });
|
|
8856
8892
|
await dependencies.run("systemctl", ["--user", "daemon-reload"]);
|
|
8857
8893
|
} else if (dependencies.manager === "launchd") {
|
|
8858
|
-
await rm(
|
|
8894
|
+
await rm(join18(dependencies.home, "Library/LaunchAgents", `${label}.plist`), { force: true });
|
|
8859
8895
|
}
|
|
8860
8896
|
} finally {
|
|
8861
8897
|
clearCredential();
|
|
@@ -9086,7 +9122,7 @@ async function detectHarnesses() {
|
|
|
9086
9122
|
// src/lock.ts
|
|
9087
9123
|
import { mkdirSync as mkdirSync12, readFileSync as readFileSync9, rmSync as rmSync11 } from "node:fs";
|
|
9088
9124
|
import { createConnection } from "node:net";
|
|
9089
|
-
import { join as
|
|
9125
|
+
import { join as join19 } from "node:path";
|
|
9090
9126
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
9091
9127
|
import lockfile from "proper-lockfile";
|
|
9092
9128
|
var DaemonAlreadyRunningError = class extends Error {
|
|
@@ -9101,7 +9137,7 @@ var LOCK_STALE_MS = 5 * 6e4;
|
|
|
9101
9137
|
var LOCK_UPDATE_MS = 3e4;
|
|
9102
9138
|
var LOCK_TAKEOVER_MS = 6e3;
|
|
9103
9139
|
function pidFile(dataDir) {
|
|
9104
|
-
return
|
|
9140
|
+
return join19(dataDir, "daemon.pid");
|
|
9105
9141
|
}
|
|
9106
9142
|
function holderPid(dataDir) {
|
|
9107
9143
|
try {
|
|
@@ -9120,11 +9156,11 @@ function processAlive(pid) {
|
|
|
9120
9156
|
}
|
|
9121
9157
|
}
|
|
9122
9158
|
function socketAnswers(socketPath) {
|
|
9123
|
-
return new Promise((
|
|
9159
|
+
return new Promise((resolve12) => {
|
|
9124
9160
|
const socket = createConnection(socketPath);
|
|
9125
9161
|
const done = (alive) => {
|
|
9126
9162
|
socket.destroy();
|
|
9127
|
-
|
|
9163
|
+
resolve12(alive);
|
|
9128
9164
|
};
|
|
9129
9165
|
socket.once("connect", () => done(true));
|
|
9130
9166
|
socket.once("error", () => done(false));
|
|
@@ -9233,7 +9269,7 @@ function closeLogger(logger) {
|
|
|
9233
9269
|
const file = files.get(logger);
|
|
9234
9270
|
if (!file) return Promise.resolve();
|
|
9235
9271
|
files.delete(logger);
|
|
9236
|
-
return new Promise((
|
|
9272
|
+
return new Promise((resolve12) => file.end(resolve12));
|
|
9237
9273
|
}
|
|
9238
9274
|
|
|
9239
9275
|
// src/outbox.ts
|
|
@@ -9245,7 +9281,7 @@ import {
|
|
|
9245
9281
|
rmSync as rmSync12,
|
|
9246
9282
|
truncateSync
|
|
9247
9283
|
} from "node:fs";
|
|
9248
|
-
import { join as
|
|
9284
|
+
import { join as join20 } from "node:path";
|
|
9249
9285
|
var Outbox = class {
|
|
9250
9286
|
constructor(dir, link, log, retryMs = 1e3, onUndeliverable = () => void 0, retainResources = false) {
|
|
9251
9287
|
this.dir = dir;
|
|
@@ -9268,10 +9304,10 @@ var Outbox = class {
|
|
|
9268
9304
|
/** Runs whose file was checked for a torn tail since this process started. */
|
|
9269
9305
|
repaired = /* @__PURE__ */ new Set();
|
|
9270
9306
|
file(runId) {
|
|
9271
|
-
return
|
|
9307
|
+
return join20(this.dir, `${assertSafeId("run id", runId)}.jsonl`);
|
|
9272
9308
|
}
|
|
9273
9309
|
ackFile(runId) {
|
|
9274
|
-
return
|
|
9310
|
+
return join20(this.dir, `${assertSafeId("run id", runId)}.ack.json`);
|
|
9275
9311
|
}
|
|
9276
9312
|
parse(runId) {
|
|
9277
9313
|
let data;
|
|
@@ -9455,16 +9491,16 @@ var Outbox = class {
|
|
|
9455
9491
|
};
|
|
9456
9492
|
|
|
9457
9493
|
// src/quota/local-credentials.ts
|
|
9458
|
-
import { homedir as
|
|
9459
|
-
import { join as
|
|
9494
|
+
import { homedir as homedir8 } from "node:os";
|
|
9495
|
+
import { join as join22 } from "node:path";
|
|
9460
9496
|
|
|
9461
9497
|
// src/quota/files.ts
|
|
9462
|
-
import { execFile as
|
|
9498
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
9463
9499
|
import { constants as constants2 } from "node:fs";
|
|
9464
9500
|
import { lstat as lstat2, open } from "node:fs/promises";
|
|
9465
|
-
import { promisify as
|
|
9501
|
+
import { promisify as promisify4 } from "node:util";
|
|
9466
9502
|
var NOFOLLOW = constants2.O_NOFOLLOW ?? 0;
|
|
9467
|
-
var execFileAsync =
|
|
9503
|
+
var execFileAsync = promisify4(execFile4);
|
|
9468
9504
|
var KEYCHAIN_TIMEOUT_MS = 3e4;
|
|
9469
9505
|
var MAX_CREDENTIAL_BYTES = 64 * 1024;
|
|
9470
9506
|
function sanitizeError(error) {
|
|
@@ -9490,8 +9526,8 @@ function classifyKeychainError(error) {
|
|
|
9490
9526
|
function safeAccount(account) {
|
|
9491
9527
|
return /^[A-Za-z0-9._-]{1,64}$/.test(account);
|
|
9492
9528
|
}
|
|
9493
|
-
async function readKeychainPassword(service, accounts = [null],
|
|
9494
|
-
if (process.platform !== "darwin" &&
|
|
9529
|
+
async function readKeychainPassword(service, accounts = [null], exec5 = execFileAsync) {
|
|
9530
|
+
if (process.platform !== "darwin" && exec5 === execFileAsync) {
|
|
9495
9531
|
return { status: "notFound" };
|
|
9496
9532
|
}
|
|
9497
9533
|
let denied = false;
|
|
@@ -9505,7 +9541,7 @@ async function readKeychainPassword(service, accounts = [null], exec4 = execFile
|
|
|
9505
9541
|
"-w"
|
|
9506
9542
|
];
|
|
9507
9543
|
try {
|
|
9508
|
-
const { stdout } = await
|
|
9544
|
+
const { stdout } = await exec5("/usr/bin/security", args, {
|
|
9509
9545
|
timeout: KEYCHAIN_TIMEOUT_MS,
|
|
9510
9546
|
maxBuffer: MAX_CREDENTIAL_BYTES
|
|
9511
9547
|
});
|
|
@@ -9954,12 +9990,12 @@ async function readCodexQuota(options) {
|
|
|
9954
9990
|
|
|
9955
9991
|
// src/quota/cursor.ts
|
|
9956
9992
|
import { lstat as lstat3 } from "node:fs/promises";
|
|
9957
|
-
import { join as
|
|
9993
|
+
import { join as join21 } from "node:path";
|
|
9958
9994
|
var ENDPOINT3 = "https://cursor.com/api/usage-summary";
|
|
9959
9995
|
var ACCESS_TOKEN_KEY = "cursorAuth/accessToken";
|
|
9960
9996
|
function cursorDatabasePath(platform3, home) {
|
|
9961
9997
|
if (platform3 === "darwin") {
|
|
9962
|
-
return
|
|
9998
|
+
return join21(
|
|
9963
9999
|
home,
|
|
9964
10000
|
"Library",
|
|
9965
10001
|
"Application Support",
|
|
@@ -9970,7 +10006,7 @@ function cursorDatabasePath(platform3, home) {
|
|
|
9970
10006
|
);
|
|
9971
10007
|
}
|
|
9972
10008
|
if (platform3 === "win32") {
|
|
9973
|
-
return
|
|
10009
|
+
return join21(
|
|
9974
10010
|
home,
|
|
9975
10011
|
"AppData",
|
|
9976
10012
|
"Roaming",
|
|
@@ -9980,7 +10016,7 @@ function cursorDatabasePath(platform3, home) {
|
|
|
9980
10016
|
"state.vscdb"
|
|
9981
10017
|
);
|
|
9982
10018
|
}
|
|
9983
|
-
return
|
|
10019
|
+
return join21(home, ".config", "Cursor", "User", "globalStorage", "state.vscdb");
|
|
9984
10020
|
}
|
|
9985
10021
|
var CURSOR_PLANS = {
|
|
9986
10022
|
pro: "Pro",
|
|
@@ -10152,10 +10188,10 @@ async function readCursorQuota(options) {
|
|
|
10152
10188
|
// src/quota/local-credentials.ts
|
|
10153
10189
|
var KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
10154
10190
|
function claudeCredentialPath(home) {
|
|
10155
|
-
return
|
|
10191
|
+
return join22(home, ".claude", ".credentials.json");
|
|
10156
10192
|
}
|
|
10157
10193
|
function codexAuthPath(home) {
|
|
10158
|
-
return
|
|
10194
|
+
return join22(home, ".codex", "auth.json");
|
|
10159
10195
|
}
|
|
10160
10196
|
function unknown2(vendor, observedAt) {
|
|
10161
10197
|
return {
|
|
@@ -10174,7 +10210,7 @@ var LocalCredentialsSource = class {
|
|
|
10174
10210
|
options;
|
|
10175
10211
|
id = "local_credentials";
|
|
10176
10212
|
async read(signal) {
|
|
10177
|
-
const home = this.options.home ??
|
|
10213
|
+
const home = this.options.home ?? homedir8();
|
|
10178
10214
|
const platform3 = this.options.platform ?? process.platform;
|
|
10179
10215
|
const fetchImpl = this.options.fetch ?? globalThis.fetch;
|
|
10180
10216
|
const now = this.options.now ?? Date.now;
|
|
@@ -10350,9 +10386,9 @@ var RpcServer = class {
|
|
|
10350
10386
|
const { socketPath } = this.options;
|
|
10351
10387
|
rmSync13(socketPath, { force: true });
|
|
10352
10388
|
const server = createServer2((socket) => this.accept(socket));
|
|
10353
|
-
await new Promise((
|
|
10389
|
+
await new Promise((resolve12, reject) => {
|
|
10354
10390
|
server.once("error", reject);
|
|
10355
|
-
server.listen(socketPath, () =>
|
|
10391
|
+
server.listen(socketPath, () => resolve12());
|
|
10356
10392
|
});
|
|
10357
10393
|
chmodSync2(socketPath, 384);
|
|
10358
10394
|
this.server = server;
|
|
@@ -10416,9 +10452,9 @@ var RpcServer = class {
|
|
|
10416
10452
|
}
|
|
10417
10453
|
async close() {
|
|
10418
10454
|
for (const socket of this.sockets) socket.destroy();
|
|
10419
|
-
await new Promise((
|
|
10420
|
-
if (!this.server) return
|
|
10421
|
-
this.server.close(() =>
|
|
10455
|
+
await new Promise((resolve12) => {
|
|
10456
|
+
if (!this.server) return resolve12();
|
|
10457
|
+
this.server.close(() => resolve12());
|
|
10422
10458
|
});
|
|
10423
10459
|
this.server = null;
|
|
10424
10460
|
rmSync13(this.options.socketPath, { force: true });
|
|
@@ -10644,13 +10680,13 @@ function createRunMasker(secrets) {
|
|
|
10644
10680
|
|
|
10645
10681
|
// src/runs/supervisor.ts
|
|
10646
10682
|
import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
|
|
10647
|
-
import { join as
|
|
10683
|
+
import { join as join24, resolve as resolve10 } from "node:path";
|
|
10648
10684
|
import { execa as execa12 } from "execa";
|
|
10649
10685
|
|
|
10650
10686
|
// src/agents/checkpoint.ts
|
|
10651
10687
|
import { mkdtempSync as mkdtempSync6, rmSync as rmSync14, writeFileSync as writeFileSync7 } from "node:fs";
|
|
10652
10688
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
10653
|
-
import { join as
|
|
10689
|
+
import { join as join23 } from "node:path";
|
|
10654
10690
|
import { gunzipSync as gunzipSync2, gzipSync as gzipSync2 } from "node:zlib";
|
|
10655
10691
|
import { execa as execa11 } from "execa";
|
|
10656
10692
|
var CheckpointRecoveryError = class extends Error {
|
|
@@ -10697,8 +10733,8 @@ async function takeCheckpoint(options) {
|
|
|
10697
10733
|
}
|
|
10698
10734
|
async function applyCheckpoint(options) {
|
|
10699
10735
|
const git2 = await pinnedGit(options.repoPath, options.worktree);
|
|
10700
|
-
const dir = mkdtempSync6(
|
|
10701
|
-
const file =
|
|
10736
|
+
const dir = mkdtempSync6(join23(tmpdir2(), "mikka-checkpoint-"));
|
|
10737
|
+
const file = join23(dir, "checkpoint.patch");
|
|
10702
10738
|
try {
|
|
10703
10739
|
const patch = gunzipSync2(Buffer.from(options.checkpoint.patch, "base64"));
|
|
10704
10740
|
if (!patch.length && options.checkpoint.files === 0) return true;
|
|
@@ -10946,12 +10982,12 @@ var MemoryServer = class {
|
|
|
10946
10982
|
this.check();
|
|
10947
10983
|
let pending = this.pendingCommands(deviceId, skip);
|
|
10948
10984
|
if (pending.length === 0 && waitSeconds > 0 && !signal?.aborted) {
|
|
10949
|
-
await new Promise((
|
|
10950
|
-
const timer = setTimeout(
|
|
10951
|
-
signal?.addEventListener("abort", () =>
|
|
10985
|
+
await new Promise((resolve12) => {
|
|
10986
|
+
const timer = setTimeout(resolve12, waitSeconds * 1e3);
|
|
10987
|
+
signal?.addEventListener("abort", () => resolve12(), { once: true });
|
|
10952
10988
|
this.wakeCommands.push(() => {
|
|
10953
10989
|
clearTimeout(timer);
|
|
10954
|
-
|
|
10990
|
+
resolve12();
|
|
10955
10991
|
});
|
|
10956
10992
|
});
|
|
10957
10993
|
this.check();
|
|
@@ -11359,9 +11395,9 @@ var RunSupervisor = class {
|
|
|
11359
11395
|
run2.abort.abort();
|
|
11360
11396
|
}
|
|
11361
11397
|
let timer;
|
|
11362
|
-
const grace = new Promise((
|
|
11398
|
+
const grace = new Promise((resolve12) => {
|
|
11363
11399
|
timer = setTimeout(
|
|
11364
|
-
|
|
11400
|
+
resolve12,
|
|
11365
11401
|
this.deps.stopGraceMs ?? DEFAULT_STOP_GRACE_MS
|
|
11366
11402
|
);
|
|
11367
11403
|
});
|
|
@@ -11553,8 +11589,8 @@ var RunSupervisor = class {
|
|
|
11553
11589
|
let timer;
|
|
11554
11590
|
await Promise.race([
|
|
11555
11591
|
this.deps.captures.flush(runId),
|
|
11556
|
-
new Promise((
|
|
11557
|
-
timer = setTimeout(
|
|
11592
|
+
new Promise((resolve12) => {
|
|
11593
|
+
timer = setTimeout(resolve12, 6e4);
|
|
11558
11594
|
})
|
|
11559
11595
|
]).finally(() => clearTimeout(timer));
|
|
11560
11596
|
}
|
|
@@ -11888,7 +11924,7 @@ var RunSupervisor = class {
|
|
|
11888
11924
|
mailbox
|
|
11889
11925
|
};
|
|
11890
11926
|
const resuming = entry.sessionId !== null && adapter.capabilities.supportsResume;
|
|
11891
|
-
const inEarlierWorktree = continued !== null || entry.worktree !== null &&
|
|
11927
|
+
const inEarlierWorktree = continued !== null || entry.worktree !== null && resolve10(entry.worktree) !== resolve10(this.deps.worktrees.pathFor(runId));
|
|
11892
11928
|
const continueSession = !resuming && assignment.resumeSessionId && assignment.continuesRunId && inEarlierWorktree && adapter.capabilities.supportsResume ? {
|
|
11893
11929
|
sessionId: assignment.resumeSessionId,
|
|
11894
11930
|
runId: assignment.continuesRunId,
|
|
@@ -11935,7 +11971,7 @@ var RunSupervisor = class {
|
|
|
11935
11971
|
if (!this.deps.adapterStateDir || assignment.harness === "mock" || !session.sessionId || resuming && session.sessionId !== entry.sessionId || assignment.requireSessionResume && session.sessionId !== assignment.resumeSessionId)
|
|
11936
11972
|
throw new Error("Skill mount requires the actual original harness session");
|
|
11937
11973
|
verifySkillAssignment(assignment);
|
|
11938
|
-
const file =
|
|
11974
|
+
const file = join24(
|
|
11939
11975
|
runPaths(this.deps.adapterStateDir, runId).runDir,
|
|
11940
11976
|
SKILLS_DIR,
|
|
11941
11977
|
skillSlug(assignment.skills[0].name),
|
|
@@ -12117,10 +12153,10 @@ function trackParts(open2, chunk) {
|
|
|
12117
12153
|
}
|
|
12118
12154
|
var ABORTED = /* @__PURE__ */ Symbol("aborted");
|
|
12119
12155
|
function abortPromise(signal) {
|
|
12120
|
-
return new Promise((
|
|
12121
|
-
if (signal.aborted)
|
|
12156
|
+
return new Promise((resolve12) => {
|
|
12157
|
+
if (signal.aborted) resolve12(ABORTED);
|
|
12122
12158
|
else
|
|
12123
|
-
signal.addEventListener("abort", () =>
|
|
12159
|
+
signal.addEventListener("abort", () => resolve12(ABORTED), { once: true });
|
|
12124
12160
|
});
|
|
12125
12161
|
}
|
|
12126
12162
|
function pickAgentReport(agent) {
|
|
@@ -12211,8 +12247,8 @@ var SessionRejectedError = class extends DaemonError {
|
|
|
12211
12247
|
|
|
12212
12248
|
// src/repositories.ts
|
|
12213
12249
|
import { createHash as createHash5, randomUUID as randomUUID6 } from "node:crypto";
|
|
12214
|
-
import { existsSync as existsSync5, lstatSync as lstatSync8, mkdirSync as mkdirSync14, readdirSync as readdirSync5, realpathSync as
|
|
12215
|
-
import { dirname as
|
|
12250
|
+
import { existsSync as existsSync5, lstatSync as lstatSync8, mkdirSync as mkdirSync14, readdirSync as readdirSync5, realpathSync as realpathSync11, renameSync as renameSync2, rmSync as rmSync15 } from "node:fs";
|
|
12251
|
+
import { dirname as dirname11, join as join25, resolve as resolve11 } from "node:path";
|
|
12216
12252
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
12217
12253
|
import { execa as execa13 } from "execa";
|
|
12218
12254
|
import lockfile2 from "proper-lockfile";
|
|
@@ -12227,8 +12263,8 @@ var RepositoryCache = class {
|
|
|
12227
12263
|
retainResources;
|
|
12228
12264
|
pathFor(remoteUrl) {
|
|
12229
12265
|
const { key: key2 } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
|
|
12230
|
-
const path =
|
|
12231
|
-
if (!isInside(
|
|
12266
|
+
const path = resolve11(this.root, "v2", createHash5("sha256").update(key2).digest("hex"));
|
|
12267
|
+
if (!isInside(resolve11(this.root), path) || path === resolve11(this.root)) throw new Error("Invalid repository cache path");
|
|
12232
12268
|
return path;
|
|
12233
12269
|
}
|
|
12234
12270
|
/** Serialize clone/fetch against the same cache, including other processes. */
|
|
@@ -12236,7 +12272,7 @@ var RepositoryCache = class {
|
|
|
12236
12272
|
signal?.throwIfAborted();
|
|
12237
12273
|
const { remoteUrl: remote } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
|
|
12238
12274
|
const path = this.pathFor(remote);
|
|
12239
|
-
this.ensureParents(
|
|
12275
|
+
this.ensureParents(dirname11(path));
|
|
12240
12276
|
const release = await this.lock(path, signal);
|
|
12241
12277
|
try {
|
|
12242
12278
|
signal?.throwIfAborted();
|
|
@@ -12280,29 +12316,29 @@ var RepositoryCache = class {
|
|
|
12280
12316
|
paths() {
|
|
12281
12317
|
const visit = (path) => {
|
|
12282
12318
|
if (!existsSync5(path) || lstatSync8(path).isSymbolicLink()) return [];
|
|
12283
|
-
if (existsSync5(
|
|
12319
|
+
if (existsSync5(join25(path, ".git"))) {
|
|
12284
12320
|
this.assertClone(path);
|
|
12285
12321
|
return [path];
|
|
12286
12322
|
}
|
|
12287
|
-
return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(
|
|
12323
|
+
return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(join25(path, entry.name)) : []);
|
|
12288
12324
|
};
|
|
12289
|
-
return visit(
|
|
12325
|
+
return visit(resolve11(this.root));
|
|
12290
12326
|
}
|
|
12291
12327
|
ensureParents(path) {
|
|
12292
12328
|
mkdirSync14(this.root, { recursive: true, mode: 448 });
|
|
12293
12329
|
if (lstatSync8(this.root).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
|
|
12294
|
-
const root =
|
|
12295
|
-
let current =
|
|
12330
|
+
const root = realpathSync11(this.root);
|
|
12331
|
+
let current = resolve11(this.root);
|
|
12296
12332
|
for (const part of path.slice(current.length + 1).split("/").filter(Boolean)) {
|
|
12297
|
-
current =
|
|
12333
|
+
current = join25(current, part);
|
|
12298
12334
|
if (existsSync5(current) && lstatSync8(current).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
|
|
12299
12335
|
mkdirSync14(current, { recursive: true, mode: 448 });
|
|
12300
|
-
if (!isInside(root,
|
|
12336
|
+
if (!isInside(root, realpathSync11(current))) throw new Error("Repository cache escapes its directory");
|
|
12301
12337
|
}
|
|
12302
12338
|
}
|
|
12303
12339
|
assertClone(path) {
|
|
12304
|
-
if (lstatSync8(path).isSymbolicLink() || !lstatSync8(
|
|
12305
|
-
if (!isInside(
|
|
12340
|
+
if (lstatSync8(path).isSymbolicLink() || !lstatSync8(join25(path, ".git")).isDirectory() || lstatSync8(join25(path, ".git")).isSymbolicLink()) throw new Error("Repository cache is not a standard clone");
|
|
12341
|
+
if (!isInside(realpathSync11(this.root), realpathSync11(path))) throw new Error("Repository cache escapes its directory");
|
|
12306
12342
|
}
|
|
12307
12343
|
async lock(path, signal) {
|
|
12308
12344
|
const deadline = Date.now() + 12e4;
|
|
@@ -12319,7 +12355,7 @@ var RepositoryCache = class {
|
|
|
12319
12355
|
};
|
|
12320
12356
|
|
|
12321
12357
|
// src/subscription-hosted-runner.ts
|
|
12322
|
-
import { execFile as
|
|
12358
|
+
import { execFile as execFile5, spawn as spawn4 } from "node:child_process";
|
|
12323
12359
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
12324
12360
|
import {
|
|
12325
12361
|
existsSync as existsSync6,
|
|
@@ -12327,13 +12363,13 @@ import {
|
|
|
12327
12363
|
mkdirSync as mkdirSync15,
|
|
12328
12364
|
mkdtempSync as mkdtempSync7,
|
|
12329
12365
|
readdirSync as readdirSync6,
|
|
12330
|
-
realpathSync as
|
|
12366
|
+
realpathSync as realpathSync12,
|
|
12331
12367
|
rmSync as rmSync16
|
|
12332
12368
|
} from "node:fs";
|
|
12333
12369
|
import { createRequire } from "node:module";
|
|
12334
|
-
import { delimiter as delimiter2, dirname as
|
|
12370
|
+
import { delimiter as delimiter2, dirname as dirname12, join as join27 } from "node:path";
|
|
12335
12371
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
12336
|
-
import { promisify as
|
|
12372
|
+
import { promisify as promisify5 } from "node:util";
|
|
12337
12373
|
|
|
12338
12374
|
// src/agents/public-egress.ts
|
|
12339
12375
|
import { lookup } from "node:dns/promises";
|
|
@@ -12341,7 +12377,7 @@ import { chmod, mkdtemp, rm as rm2 } from "node:fs/promises";
|
|
|
12341
12377
|
import { createServer as createServer3, request as httpRequest } from "node:http";
|
|
12342
12378
|
import { connect, isIP as isIP3 } from "node:net";
|
|
12343
12379
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
12344
|
-
import { join as
|
|
12380
|
+
import { join as join26 } from "node:path";
|
|
12345
12381
|
|
|
12346
12382
|
// ../../lib/search/url-policy.ts
|
|
12347
12383
|
import { BlockList, isIP as isIP2 } from "node:net";
|
|
@@ -12410,9 +12446,9 @@ function endToEndHeaders(input) {
|
|
|
12410
12446
|
}
|
|
12411
12447
|
async function startPublicEgress(options) {
|
|
12412
12448
|
options.signal.throwIfAborted();
|
|
12413
|
-
const directory = await mkdtemp(
|
|
12449
|
+
const directory = await mkdtemp(join26(tmpdir3(), "mikka-egress-"));
|
|
12414
12450
|
await chmod(directory, 448);
|
|
12415
|
-
const socketPath =
|
|
12451
|
+
const socketPath = join26(directory, "egress.sock");
|
|
12416
12452
|
const lifetime = new AbortController();
|
|
12417
12453
|
const signal = AbortSignal.any([options.signal, lifetime.signal]);
|
|
12418
12454
|
const sockets = /* @__PURE__ */ new Set();
|
|
@@ -12517,9 +12553,9 @@ async function startPublicEgress(options) {
|
|
|
12517
12553
|
if (closing) return closing;
|
|
12518
12554
|
lifetime.abort();
|
|
12519
12555
|
for (const socket of sockets) socket.destroy();
|
|
12520
|
-
closing = new Promise((
|
|
12556
|
+
closing = new Promise((resolve12, reject) => server.close((error) => {
|
|
12521
12557
|
options.signal.removeEventListener("abort", onAbort);
|
|
12522
|
-
void rm2(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) :
|
|
12558
|
+
void rm2(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve12(), reject);
|
|
12523
12559
|
}));
|
|
12524
12560
|
return closing;
|
|
12525
12561
|
};
|
|
@@ -12528,11 +12564,11 @@ async function startPublicEgress(options) {
|
|
|
12528
12564
|
};
|
|
12529
12565
|
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
12530
12566
|
try {
|
|
12531
|
-
await new Promise((
|
|
12567
|
+
await new Promise((resolve12, reject) => {
|
|
12532
12568
|
server.once("error", reject);
|
|
12533
12569
|
server.listen(socketPath, () => {
|
|
12534
12570
|
server.removeListener("error", reject);
|
|
12535
|
-
|
|
12571
|
+
resolve12();
|
|
12536
12572
|
});
|
|
12537
12573
|
});
|
|
12538
12574
|
await chmod(socketPath, 384);
|
|
@@ -12545,7 +12581,7 @@ async function startPublicEgress(options) {
|
|
|
12545
12581
|
}
|
|
12546
12582
|
|
|
12547
12583
|
// src/subscription-hosted-runner.ts
|
|
12548
|
-
var
|
|
12584
|
+
var exec3 = promisify5(execFile5);
|
|
12549
12585
|
var image = HOSTED_NATIVE_IMAGE;
|
|
12550
12586
|
var bootstrap = fileURLToPath2(
|
|
12551
12587
|
new URL("./agents/native-container.mjs", import.meta.url)
|
|
@@ -12563,20 +12599,20 @@ async function createHostedBotRunner(host) {
|
|
|
12563
12599
|
throw unavailable2();
|
|
12564
12600
|
if (host.dockerSocket !== void 0 && host.dockerSocket !== "unix:///run/mikka-container/docker.sock") throw unavailable2();
|
|
12565
12601
|
const bareEnv = { PATH: process.env.PATH, LANG: "C.UTF-8", ...host.dockerSocket ? { DOCKER_HOST: host.dockerSocket } : {} };
|
|
12566
|
-
await
|
|
12602
|
+
await exec3("docker", ["image", "inspect", image, "--format", "{{.Id}}"], {
|
|
12567
12603
|
env: bareEnv,
|
|
12568
12604
|
timeout: 1e4
|
|
12569
12605
|
}).catch(() => {
|
|
12570
12606
|
throw unavailable2();
|
|
12571
12607
|
});
|
|
12572
|
-
const resources =
|
|
12608
|
+
const resources = join27(host.stateDir, "native-resources");
|
|
12573
12609
|
mkdirSync15(resources, { recursive: true, mode: 448 });
|
|
12574
12610
|
const removeResource = async (file, record) => {
|
|
12575
12611
|
if (!/^mikka-native-(?:verify-)?[a-f0-9-]{36}$/.test(record.name) || !/^[a-f0-9-]{36}$/.test(record.nonce))
|
|
12576
12612
|
throw unavailable2();
|
|
12577
12613
|
let described;
|
|
12578
12614
|
try {
|
|
12579
|
-
described = await
|
|
12615
|
+
described = await exec3(
|
|
12580
12616
|
"docker",
|
|
12581
12617
|
[
|
|
12582
12618
|
"inspect",
|
|
@@ -12590,7 +12626,7 @@ async function createHostedBotRunner(host) {
|
|
|
12590
12626
|
if (record.state === "created" && /No such (?:container|object)/i.test(
|
|
12591
12627
|
String(error.stderr)
|
|
12592
12628
|
)) {
|
|
12593
|
-
if (record.assets?.startsWith(
|
|
12629
|
+
if (record.assets?.startsWith(join27(host.stateDir, "native-verify-git-")))
|
|
12594
12630
|
rmSync16(record.assets, { recursive: true, force: true });
|
|
12595
12631
|
rmSync16(file, { force: true });
|
|
12596
12632
|
return;
|
|
@@ -12600,14 +12636,14 @@ async function createHostedBotRunner(host) {
|
|
|
12600
12636
|
const [id4, labels] = described.stdout.trim().split("|").map((part) => JSON.parse(part));
|
|
12601
12637
|
if (labels?.["com.mikka.native.resource"] !== record.nonce || record.id && record.id !== id4)
|
|
12602
12638
|
throw unavailable2();
|
|
12603
|
-
await
|
|
12604
|
-
if (record.assets?.startsWith(
|
|
12639
|
+
await exec3("docker", ["rm", "-f", id4], { env: bareEnv, timeout: 3e4 });
|
|
12640
|
+
if (record.assets?.startsWith(join27(host.stateDir, "native-verify-git-")))
|
|
12605
12641
|
rmSync16(record.assets, { recursive: true, force: true });
|
|
12606
12642
|
rmSync16(file, { force: true });
|
|
12607
12643
|
};
|
|
12608
12644
|
for (const name of readdirSync6(resources))
|
|
12609
12645
|
if (name.endsWith(".json")) {
|
|
12610
|
-
const file =
|
|
12646
|
+
const file = join27(resources, name);
|
|
12611
12647
|
const record = readJson(file);
|
|
12612
12648
|
if (!record) throw unavailable2();
|
|
12613
12649
|
await removeResource(file, record);
|
|
@@ -12618,8 +12654,8 @@ async function createHostedBotRunner(host) {
|
|
|
12618
12654
|
const bundled = createRequire(
|
|
12619
12655
|
require2.resolve("@anthropic-ai/claude-agent-sdk")
|
|
12620
12656
|
);
|
|
12621
|
-
claude ??=
|
|
12622
|
-
|
|
12657
|
+
claude ??= join27(
|
|
12658
|
+
dirname12(
|
|
12623
12659
|
bundled.resolve(
|
|
12624
12660
|
"@anthropic-ai/claude-agent-sdk-linux-x64/package.json"
|
|
12625
12661
|
)
|
|
@@ -12628,12 +12664,12 @@ async function createHostedBotRunner(host) {
|
|
|
12628
12664
|
);
|
|
12629
12665
|
} catch {
|
|
12630
12666
|
}
|
|
12631
|
-
const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter2).map((dir) =>
|
|
12667
|
+
const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter2).map((dir) => join27(dir, "codex")).find((path) => existsSync6(path));
|
|
12632
12668
|
const binaries = { codex, claude_code: claude };
|
|
12633
12669
|
for (const kind of ["codex", "claude_code"])
|
|
12634
12670
|
if (binaries[kind]) {
|
|
12635
12671
|
try {
|
|
12636
|
-
binaries[kind] =
|
|
12672
|
+
binaries[kind] = realpathSync12(binaries[kind]);
|
|
12637
12673
|
if (!lstatSync9(binaries[kind]).isFile()) delete binaries[kind];
|
|
12638
12674
|
} catch {
|
|
12639
12675
|
delete binaries[kind];
|
|
@@ -12642,16 +12678,16 @@ async function createHostedBotRunner(host) {
|
|
|
12642
12678
|
if (!binaries.codex && !binaries.claude_code) throw unavailable2();
|
|
12643
12679
|
const command = async (worktree, script, readOnly, timeoutMs, signal) => {
|
|
12644
12680
|
const name = `mikka-native-verify-${randomUUID7()}`;
|
|
12645
|
-
const file =
|
|
12681
|
+
const file = join27(resources, name + ".json");
|
|
12646
12682
|
const resource = { name, nonce: randomUUID7(), state: "creating" };
|
|
12647
12683
|
const timing = { createMs: 0, runMs: 0 };
|
|
12648
12684
|
let phase = "create";
|
|
12649
12685
|
let began = performance.now();
|
|
12650
|
-
const gitCopy = mkdtempSync7(
|
|
12686
|
+
const gitCopy = mkdtempSync7(join27(host.stateDir, "native-verify-git-"));
|
|
12651
12687
|
resource.assets = gitCopy;
|
|
12652
12688
|
try {
|
|
12653
|
-
const cwd =
|
|
12654
|
-
await
|
|
12689
|
+
const cwd = realpathSync12(worktree);
|
|
12690
|
+
await exec3(
|
|
12655
12691
|
"git",
|
|
12656
12692
|
[
|
|
12657
12693
|
"-c",
|
|
@@ -12663,7 +12699,7 @@ async function createHostedBotRunner(host) {
|
|
|
12663
12699
|
"--no-checkout",
|
|
12664
12700
|
"--",
|
|
12665
12701
|
cwd,
|
|
12666
|
-
|
|
12702
|
+
join27(gitCopy, "repo")
|
|
12667
12703
|
],
|
|
12668
12704
|
{
|
|
12669
12705
|
env: {
|
|
@@ -12678,10 +12714,10 @@ async function createHostedBotRunner(host) {
|
|
|
12678
12714
|
maxBuffer: 1024 * 1024
|
|
12679
12715
|
}
|
|
12680
12716
|
);
|
|
12681
|
-
const safeGit =
|
|
12682
|
-
const protectedGit = lstatSync9(
|
|
12717
|
+
const safeGit = join27(gitCopy, "repo", ".git");
|
|
12718
|
+
const protectedGit = lstatSync9(join27(cwd, ".git")).isFile() ? join27(cwd, ".git") : safeGit;
|
|
12683
12719
|
writeJsonAtomic(file, resource);
|
|
12684
|
-
const created = await
|
|
12720
|
+
const created = await exec3(
|
|
12685
12721
|
"docker",
|
|
12686
12722
|
[
|
|
12687
12723
|
"create",
|
|
@@ -12739,7 +12775,7 @@ async function createHostedBotRunner(host) {
|
|
|
12739
12775
|
timing.createMs = Math.round(performance.now() - began);
|
|
12740
12776
|
phase = "run";
|
|
12741
12777
|
began = performance.now();
|
|
12742
|
-
const result = await
|
|
12778
|
+
const result = await exec3("docker", ["start", "-a", resource.id], {
|
|
12743
12779
|
env: bareEnv,
|
|
12744
12780
|
timeout: timeoutMs,
|
|
12745
12781
|
signal,
|
|
@@ -12783,7 +12819,7 @@ async function createHostedBotRunner(host) {
|
|
|
12783
12819
|
throw unavailable2();
|
|
12784
12820
|
const name = `mikka-native-${randomUUID7()}`;
|
|
12785
12821
|
const nonce = randomUUID7();
|
|
12786
|
-
const resourceFile =
|
|
12822
|
+
const resourceFile = join27(resources, name + ".json");
|
|
12787
12823
|
const resource = { name, nonce, state: "creating" };
|
|
12788
12824
|
const lifetime = new AbortController();
|
|
12789
12825
|
let closed = false;
|
|
@@ -12856,11 +12892,11 @@ async function createHostedBotRunner(host) {
|
|
|
12856
12892
|
};
|
|
12857
12893
|
const paths = runPaths(host.stateDir, assignment.runId);
|
|
12858
12894
|
mkdirSync15(paths.runDir, { recursive: true, mode: 448 });
|
|
12859
|
-
const shadow =
|
|
12860
|
-
const emptyHome =
|
|
12895
|
+
const shadow = join27(paths.runDir, "runtime-git");
|
|
12896
|
+
const emptyHome = join27(paths.runDir, "git-bootstrap-home");
|
|
12861
12897
|
mkdirSync15(emptyHome, { recursive: true, mode: 448 });
|
|
12862
12898
|
if (!existsSync6(shadow))
|
|
12863
|
-
await
|
|
12899
|
+
await exec3(
|
|
12864
12900
|
"git",
|
|
12865
12901
|
[
|
|
12866
12902
|
"-c",
|
|
@@ -12871,7 +12907,7 @@ async function createHostedBotRunner(host) {
|
|
|
12871
12907
|
"--no-hardlinks",
|
|
12872
12908
|
"--no-checkout",
|
|
12873
12909
|
"--",
|
|
12874
|
-
|
|
12910
|
+
realpathSync12(options.cwd),
|
|
12875
12911
|
shadow
|
|
12876
12912
|
],
|
|
12877
12913
|
{
|
|
@@ -12888,9 +12924,9 @@ async function createHostedBotRunner(host) {
|
|
|
12888
12924
|
}
|
|
12889
12925
|
);
|
|
12890
12926
|
await live();
|
|
12891
|
-
if (!lstatSync9(shadow).isDirectory() || !lstatSync9(
|
|
12927
|
+
if (!lstatSync9(shadow).isDirectory() || !lstatSync9(join27(shadow, ".git")).isDirectory() || !realpathSync12(shadow).startsWith(realpathSync12(paths.runDir) + "/"))
|
|
12892
12928
|
throw unavailable2();
|
|
12893
|
-
const ledger =
|
|
12929
|
+
const ledger = join27(
|
|
12894
12930
|
host.stateDir,
|
|
12895
12931
|
"native-ledgers",
|
|
12896
12932
|
assignment.runId + ".json"
|
|
@@ -12909,13 +12945,13 @@ async function createHostedBotRunner(host) {
|
|
|
12909
12945
|
const previous = readJson(ledger);
|
|
12910
12946
|
if (existsSync6(ledger) && (!previous || JSON.stringify(previous.scope) !== JSON.stringify(scope) || typeof previous.sessionId !== "string"))
|
|
12911
12947
|
throw unavailable2();
|
|
12912
|
-
mkdirSync15(
|
|
12948
|
+
mkdirSync15(dirname12(ledger), { recursive: true, mode: 448 });
|
|
12913
12949
|
const record = async (sessionId) => {
|
|
12914
12950
|
assertOpen();
|
|
12915
12951
|
writeJsonAtomic(ledger, { scope, sessionId });
|
|
12916
12952
|
};
|
|
12917
12953
|
brokerStarting = createNativeSubscriptionBroker({
|
|
12918
|
-
root:
|
|
12954
|
+
root: join27(host.stateDir, "native-brokers"),
|
|
12919
12955
|
revision,
|
|
12920
12956
|
check,
|
|
12921
12957
|
worker: {
|
|
@@ -12942,7 +12978,7 @@ async function createHostedBotRunner(host) {
|
|
|
12942
12978
|
});
|
|
12943
12979
|
const readyBroker = await brokerStarting;
|
|
12944
12980
|
await live();
|
|
12945
|
-
const githubCli = options.github ? (process.env.PATH ?? "").split(delimiter2).map((dir) =>
|
|
12981
|
+
const githubCli = options.github ? (process.env.PATH ?? "").split(delimiter2).map((dir) => join27(dir, "gh")).find((file) => existsSync6(file)) : void 0;
|
|
12946
12982
|
if (options.github && !githubCli) throw new Error("Install GitHub CLI (gh) in the cloud worker image");
|
|
12947
12983
|
const githubDomains = options.github ? ["github.com", "api.github.com", new URL(options.github.endpoint).host] : [];
|
|
12948
12984
|
const egressMaximum = runDomains(runPolicy(options.policy), [...options.networkAllow ?? [], ...githubDomains]);
|
|
@@ -12957,10 +12993,10 @@ async function createHostedBotRunner(host) {
|
|
|
12957
12993
|
await egressStarting;
|
|
12958
12994
|
await live();
|
|
12959
12995
|
}
|
|
12960
|
-
const cwd =
|
|
12961
|
-
const runDir =
|
|
12962
|
-
const protectedGit = lstatSync9(
|
|
12963
|
-
if (!lstatSync9(runDir).isDirectory() || !runDir.startsWith(
|
|
12996
|
+
const cwd = realpathSync12(options.cwd);
|
|
12997
|
+
const runDir = realpathSync12(paths.runDir);
|
|
12998
|
+
const protectedGit = lstatSync9(join27(cwd, ".git")).isFile() ? join27(cwd, ".git") : join27(shadow, ".git");
|
|
12999
|
+
if (!lstatSync9(runDir).isDirectory() || !runDir.startsWith(realpathSync12(host.stateDir) + "/runs/")) {
|
|
12964
13000
|
await close();
|
|
12965
13001
|
throw unavailable2();
|
|
12966
13002
|
}
|
|
@@ -13013,7 +13049,7 @@ async function createHostedBotRunner(host) {
|
|
|
13013
13049
|
`${MCP_SERVER_SCRIPT}:${MCP_SERVER_SCRIPT}:ro`,
|
|
13014
13050
|
...githubCli ? ["-v", `${githubCli}:/usr/local/bin/mikka-gh:ro`, "-v", `${GITHUB_CREDENTIAL_SCRIPT}:${GITHUB_CREDENTIAL_SCRIPT}:ro`] : [],
|
|
13015
13051
|
"-v",
|
|
13016
|
-
`${
|
|
13052
|
+
`${join27(dirname12(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:${join27(dirname12(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:ro`,
|
|
13017
13053
|
"-v",
|
|
13018
13054
|
`${readyBroker.socket}:/run/mikka-native.sock:ro`,
|
|
13019
13055
|
...computerGrant ? [
|
|
@@ -13039,7 +13075,7 @@ async function createHostedBotRunner(host) {
|
|
|
13039
13075
|
await live();
|
|
13040
13076
|
writeJsonAtomic(resourceFile, resource);
|
|
13041
13077
|
try {
|
|
13042
|
-
creating =
|
|
13078
|
+
creating = exec3("docker", containerArgs, {
|
|
13043
13079
|
env: bareEnv,
|
|
13044
13080
|
timeout: 3e4
|
|
13045
13081
|
}).then((created) => {
|
|
@@ -13056,13 +13092,13 @@ async function createHostedBotRunner(host) {
|
|
|
13056
13092
|
}
|
|
13057
13093
|
const spawnHosted = (config) => {
|
|
13058
13094
|
assertOpen();
|
|
13059
|
-
const home =
|
|
13095
|
+
const home = join27(runDir, "runtime-home");
|
|
13060
13096
|
mkdirSync15(home, { recursive: true, mode: 448 });
|
|
13061
13097
|
const env = {
|
|
13062
13098
|
...config.env,
|
|
13063
13099
|
HOME: kind === "claude_code" ? config.env.HOME ?? home : home,
|
|
13064
|
-
PATH: `${options.github ?
|
|
13065
|
-
GIT_DIR:
|
|
13100
|
+
PATH: `${options.github ? join27(runDir, "github", "bin") + ":" : ""}/usr/local/bin:/usr/bin:/bin`,
|
|
13101
|
+
GIT_DIR: join27(shadow, ".git"),
|
|
13066
13102
|
GIT_WORK_TREE: cwd,
|
|
13067
13103
|
GIT_CONFIG_GLOBAL: "/dev/null",
|
|
13068
13104
|
GIT_CONFIG_SYSTEM: "/dev/null",
|
|
@@ -13081,7 +13117,7 @@ async function createHostedBotRunner(host) {
|
|
|
13081
13117
|
signal: AbortSignal.any([lifetime.signal, ...config.signal ? [config.signal] : []])
|
|
13082
13118
|
});
|
|
13083
13119
|
child.stdin.write(
|
|
13084
|
-
JSON.stringify({ kind, args: config.args, cwd, env: task.env, publicEgress: Boolean(egress), ...options.github ? { githubBin:
|
|
13120
|
+
JSON.stringify({ kind, args: config.args, cwd, env: task.env, publicEgress: Boolean(egress), ...options.github ? { githubBin: join27(runDir, "github", "bin") } : {} }) + "\n"
|
|
13085
13121
|
);
|
|
13086
13122
|
return child;
|
|
13087
13123
|
};
|
|
@@ -13095,9 +13131,9 @@ async function createHostedBotRunner(host) {
|
|
|
13095
13131
|
signal: new AbortController().signal
|
|
13096
13132
|
});
|
|
13097
13133
|
child.stderr?.resume();
|
|
13098
|
-
const exited = new Promise((
|
|
13099
|
-
child.once("exit", (code, signal) =>
|
|
13100
|
-
child.once("error", () =>
|
|
13134
|
+
const exited = new Promise((resolve12) => {
|
|
13135
|
+
child.once("exit", (code, signal) => resolve12({ code, signal }));
|
|
13136
|
+
child.once("error", () => resolve12({ code: null, signal: null }));
|
|
13101
13137
|
});
|
|
13102
13138
|
return {
|
|
13103
13139
|
process: child,
|
|
@@ -13221,19 +13257,19 @@ import { createServer as createServer4 } from "node:net";
|
|
|
13221
13257
|
|
|
13222
13258
|
// src/computer/driver.mjs
|
|
13223
13259
|
import { spawn as spawn5 } from "node:child_process";
|
|
13224
|
-
import { execFile as
|
|
13225
|
-
import { promisify as
|
|
13260
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
13261
|
+
import { promisify as promisify6 } from "node:util";
|
|
13226
13262
|
import { createHash as createHash6 } from "node:crypto";
|
|
13227
13263
|
import { readFile as readFile2, realpath as realpath2 } from "node:fs/promises";
|
|
13228
13264
|
import { createInterface } from "node:readline";
|
|
13229
|
-
var
|
|
13265
|
+
var exec4 = promisify6(execFile6);
|
|
13230
13266
|
async function detectComputerDriver(binary = "cua-driver") {
|
|
13231
13267
|
try {
|
|
13232
|
-
const { stdout: located } = await
|
|
13268
|
+
const { stdout: located } = await exec4("which", [binary], {
|
|
13233
13269
|
timeout: 5e3
|
|
13234
13270
|
});
|
|
13235
13271
|
const path = await realpath2(located.trim());
|
|
13236
|
-
const { stdout } = await
|
|
13272
|
+
const { stdout } = await exec4(path, ["--version"], { timeout: 5e3 });
|
|
13237
13273
|
const version = stdout.trim().split("\n")[0];
|
|
13238
13274
|
if (!/^cua-driver\s+0\.38\.0\b/.test(version)) return null;
|
|
13239
13275
|
return {
|
|
@@ -13357,9 +13393,9 @@ async function executeDriver(driver, input, display, leaseGuard, assertLive = ()
|
|
|
13357
13393
|
)
|
|
13358
13394
|
)
|
|
13359
13395
|
);
|
|
13360
|
-
const request = (method, params) => new Promise((
|
|
13396
|
+
const request = (method, params) => new Promise((resolve12, reject) => {
|
|
13361
13397
|
const n = ++id4;
|
|
13362
|
-
pending.set(n, { resolve:
|
|
13398
|
+
pending.set(n, { resolve: resolve12, reject });
|
|
13363
13399
|
child.stdin.write(
|
|
13364
13400
|
JSON.stringify({ jsonrpc: "2.0", id: n, method, params }) + "\n"
|
|
13365
13401
|
);
|
|
@@ -13460,10 +13496,10 @@ var ComputerBroker = class {
|
|
|
13460
13496
|
})();
|
|
13461
13497
|
});
|
|
13462
13498
|
});
|
|
13463
|
-
await new Promise((
|
|
13499
|
+
await new Promise((resolve12, reject) => {
|
|
13464
13500
|
this.server.once("error", reject);
|
|
13465
|
-
if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 },
|
|
13466
|
-
else this.server.listen(this.socketPath,
|
|
13501
|
+
if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 }, resolve12);
|
|
13502
|
+
else this.server.listen(this.socketPath, resolve12);
|
|
13467
13503
|
});
|
|
13468
13504
|
if (this.transport === "tcp") this.socketPath = `tcp://127.0.0.1:${this.server.address().port}`;
|
|
13469
13505
|
else chmodSync3(this.socketPath, 384);
|
|
@@ -13494,7 +13530,7 @@ var ComputerBroker = class {
|
|
|
13494
13530
|
expiresAt: this.now() + this.ttl
|
|
13495
13531
|
};
|
|
13496
13532
|
const digest2 = createHash7("sha256").update(JSON.stringify(request)).digest("hex");
|
|
13497
|
-
return new Promise((
|
|
13533
|
+
return new Promise((resolve12, reject) => {
|
|
13498
13534
|
const timer = setTimeout(() => {
|
|
13499
13535
|
this.pending.delete(request.id);
|
|
13500
13536
|
signal?.removeEventListener("abort", cancel);
|
|
@@ -13511,7 +13547,7 @@ var ComputerBroker = class {
|
|
|
13511
13547
|
assertLive,
|
|
13512
13548
|
cleanup: () => signal?.removeEventListener("abort", cancel),
|
|
13513
13549
|
request: { ...request, digest: digest2 },
|
|
13514
|
-
resolve:
|
|
13550
|
+
resolve: resolve12,
|
|
13515
13551
|
reject,
|
|
13516
13552
|
timer
|
|
13517
13553
|
});
|
|
@@ -13588,7 +13624,7 @@ var ComputerBroker = class {
|
|
|
13588
13624
|
async close() {
|
|
13589
13625
|
this.suspend();
|
|
13590
13626
|
for (const socket of this.sockets) socket.destroy();
|
|
13591
|
-
if (this.server?.listening) await new Promise((
|
|
13627
|
+
if (this.server?.listening) await new Promise((resolve12) => this.server.close(resolve12));
|
|
13592
13628
|
}
|
|
13593
13629
|
};
|
|
13594
13630
|
|
|
@@ -13657,11 +13693,11 @@ async function pollWebComputerReviews(broker, deviceId, link, signal, intervalMs
|
|
|
13657
13693
|
} catch {
|
|
13658
13694
|
}
|
|
13659
13695
|
if (signal.aborted) break;
|
|
13660
|
-
await new Promise((
|
|
13696
|
+
await new Promise((resolve12) => {
|
|
13661
13697
|
const done = () => {
|
|
13662
13698
|
clearTimeout(timer);
|
|
13663
13699
|
signal.removeEventListener("abort", done);
|
|
13664
|
-
|
|
13700
|
+
resolve12();
|
|
13665
13701
|
};
|
|
13666
13702
|
const timer = setTimeout(done, intervalMs);
|
|
13667
13703
|
signal.addEventListener("abort", done, { once: true });
|
|
@@ -13712,6 +13748,11 @@ var Daemon = class {
|
|
|
13712
13748
|
server = "unregistered";
|
|
13713
13749
|
timer = null;
|
|
13714
13750
|
tick = Promise.resolve();
|
|
13751
|
+
updating = false;
|
|
13752
|
+
claimsInFlight = 0;
|
|
13753
|
+
updateCheck = null;
|
|
13754
|
+
maintenance = null;
|
|
13755
|
+
updateVersion;
|
|
13715
13756
|
draining = false;
|
|
13716
13757
|
stopped = false;
|
|
13717
13758
|
stopPromise = null;
|
|
@@ -13770,7 +13811,7 @@ var Daemon = class {
|
|
|
13770
13811
|
if (this.options.credential)
|
|
13771
13812
|
this.saveDevice({ credential: this.options.credential });
|
|
13772
13813
|
this.journal = new RunJournal(paths.journal);
|
|
13773
|
-
this.captureUploader = new CaptureUploader((runId) =>
|
|
13814
|
+
this.captureUploader = new CaptureUploader((runId) => join28(runPaths(paths.adapterState, runId).runDir, CAPTURES_DIR), this.options.link, this.log, join28(paths.dataDir, "capture-pending"));
|
|
13774
13815
|
this.outbox = new Outbox(
|
|
13775
13816
|
paths.outbox,
|
|
13776
13817
|
this.options.link,
|
|
@@ -13787,7 +13828,7 @@ var Daemon = class {
|
|
|
13787
13828
|
if (this.localComputerDriver && this.options.link.syncComputerReviews && this.options.link.localComputerAuthority) {
|
|
13788
13829
|
this.localComputerBroker = new ComputerBroker({
|
|
13789
13830
|
driver: this.localComputerDriver,
|
|
13790
|
-
socketPath:
|
|
13831
|
+
socketPath: join28(paths.dataDir, "local-computer.sock"),
|
|
13791
13832
|
transport: "tcp",
|
|
13792
13833
|
permitted: (runId) => {
|
|
13793
13834
|
const assignment = this.journal.get(runId)?.assignment;
|
|
@@ -13829,7 +13870,7 @@ var Daemon = class {
|
|
|
13829
13870
|
};
|
|
13830
13871
|
this.cloudComputerBroker = new ComputerBroker({
|
|
13831
13872
|
driver,
|
|
13832
|
-
socketPath:
|
|
13873
|
+
socketPath: join28(paths.dataDir, "computer.sock"),
|
|
13833
13874
|
permitted: (runId) => {
|
|
13834
13875
|
const entry = this.journal.get(runId);
|
|
13835
13876
|
return Boolean(!this.stopped && this.registered && entry?.assignment.computer && this.supervisor?.computerRunAllowed(runId));
|
|
@@ -13952,7 +13993,7 @@ var Daemon = class {
|
|
|
13952
13993
|
worktree,
|
|
13953
13994
|
tree,
|
|
13954
13995
|
github: { ...assignment.github, runToken: assignment.mcp.token, issueId: assignment.issueId },
|
|
13955
|
-
privateDir:
|
|
13996
|
+
privateDir: join28(paths.adapterState, "pids"),
|
|
13956
13997
|
...hosted ? { hosted: true } : {},
|
|
13957
13998
|
env: githubReceiptEnvironment()
|
|
13958
13999
|
}) : publishRun({
|
|
@@ -14130,12 +14171,12 @@ var Daemon = class {
|
|
|
14130
14171
|
/** Waits `ms`, or less if the daemon stops or the device registers. */
|
|
14131
14172
|
pauseCommands(ms, signal) {
|
|
14132
14173
|
if (signal.aborted) return Promise.resolve();
|
|
14133
|
-
return new Promise((
|
|
14174
|
+
return new Promise((resolve12) => {
|
|
14134
14175
|
const done = () => {
|
|
14135
14176
|
clearTimeout(timer);
|
|
14136
14177
|
signal.removeEventListener("abort", done);
|
|
14137
14178
|
this.wakeCommands = null;
|
|
14138
|
-
|
|
14179
|
+
resolve12();
|
|
14139
14180
|
};
|
|
14140
14181
|
const timer = setTimeout(done, ms);
|
|
14141
14182
|
signal.addEventListener("abort", done, { once: true });
|
|
@@ -14235,12 +14276,12 @@ var Daemon = class {
|
|
|
14235
14276
|
const paths = runPaths(this.paths.adapterState, runId);
|
|
14236
14277
|
return runVerify(sandbox, {
|
|
14237
14278
|
command,
|
|
14238
|
-
worktree:
|
|
14239
|
-
tmpRoot:
|
|
14279
|
+
worktree: realpathSync13(worktree),
|
|
14280
|
+
tmpRoot: join28(this.paths.adapterState, "verify", runId),
|
|
14240
14281
|
privateDir: paths.privateDir,
|
|
14241
14282
|
pidFile: paths.pidFile.replace(/\.pgid$/, ".verify.pgid"),
|
|
14242
14283
|
networkAllow: repo.networkAllow,
|
|
14243
|
-
env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE:
|
|
14284
|
+
env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE: join28(paths.runDir, "handoff.json") },
|
|
14244
14285
|
timeoutMs,
|
|
14245
14286
|
signal,
|
|
14246
14287
|
readOnly
|
|
@@ -14352,6 +14393,8 @@ var Daemon = class {
|
|
|
14352
14393
|
return pass;
|
|
14353
14394
|
}
|
|
14354
14395
|
async syncPass() {
|
|
14396
|
+
if (this.stopped) return;
|
|
14397
|
+
this.checkAutoUpdate();
|
|
14355
14398
|
const { link } = this.options;
|
|
14356
14399
|
const { credential, workspaceId } = this.device;
|
|
14357
14400
|
if (!credential) {
|
|
@@ -14403,7 +14446,7 @@ var Daemon = class {
|
|
|
14403
14446
|
return;
|
|
14404
14447
|
}
|
|
14405
14448
|
if (command && !this.device.completedDeviceCommands?.includes(command.id) && !this.device.failedDeviceCommands?.some((failure) => failure.id === command.id)) {
|
|
14406
|
-
if (command.kind === "redetect" || this.
|
|
14449
|
+
if (command.kind === "redetect" || this.maintenanceIdle()) {
|
|
14407
14450
|
try {
|
|
14408
14451
|
if (command.kind === "redetect") {
|
|
14409
14452
|
const detected = await detectHarnesses();
|
|
@@ -14414,8 +14457,13 @@ var Daemon = class {
|
|
|
14414
14457
|
this.saveDevice({ completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14415
14458
|
void this.syncWithServer().catch(() => void 0);
|
|
14416
14459
|
} else {
|
|
14417
|
-
|
|
14418
|
-
|
|
14460
|
+
this.startMaintenance(async () => {
|
|
14461
|
+
await restartService(command.kind === "update", () => {
|
|
14462
|
+
if (this.stopped) throw new Error("Daemon stopped during update");
|
|
14463
|
+
this.saveDevice({ completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14464
|
+
}, void 0, () => !this.stopped);
|
|
14465
|
+
}, () => {
|
|
14466
|
+
this.saveDevice({ completedDeviceCommands: [], failedDeviceCommands: [{ id: command.id, error: "Device command failed; check daemon service logs." }] });
|
|
14419
14467
|
});
|
|
14420
14468
|
}
|
|
14421
14469
|
} catch {
|
|
@@ -14430,7 +14478,7 @@ var Daemon = class {
|
|
|
14430
14478
|
this.server = "online";
|
|
14431
14479
|
await this.outbox.flushAll();
|
|
14432
14480
|
for (const entry of this.journal.all()) if (isTerminalRunState(entry.state)) void this.captureUploader.flush(entry.assignment.runId, true);
|
|
14433
|
-
if (!this.draining) {
|
|
14481
|
+
if (!this.draining && !this.updating && !this.stopped) {
|
|
14434
14482
|
await this.supervisor.resumeAll(true);
|
|
14435
14483
|
this.startCoordinatorPass(deviceId);
|
|
14436
14484
|
for (const runId of await link.pendingRuns(deviceId)) {
|
|
@@ -14468,6 +14516,17 @@ var Daemon = class {
|
|
|
14468
14516
|
this.log.warn("server refused the device session; sign in again");
|
|
14469
14517
|
}
|
|
14470
14518
|
async claimAndStart(runId) {
|
|
14519
|
+
if (this.draining || this.updating || this.stopped) {
|
|
14520
|
+
throw new DaemonError(DAEMON_RPC_ERRORS.draining, "Daemon is draining");
|
|
14521
|
+
}
|
|
14522
|
+
this.claimsInFlight++;
|
|
14523
|
+
try {
|
|
14524
|
+
return await this.claimAndStartInternal(runId);
|
|
14525
|
+
} finally {
|
|
14526
|
+
this.claimsInFlight--;
|
|
14527
|
+
}
|
|
14528
|
+
}
|
|
14529
|
+
async claimAndStartInternal(runId) {
|
|
14471
14530
|
if (this.draining) {
|
|
14472
14531
|
throw new DaemonError(DAEMON_RPC_ERRORS.draining, "Daemon is draining");
|
|
14473
14532
|
}
|
|
@@ -14501,7 +14560,7 @@ var Daemon = class {
|
|
|
14501
14560
|
}
|
|
14502
14561
|
}
|
|
14503
14562
|
if (assignment.computer && (!this.cloudComputerBroker || !assignment.subscriptionBinding || assignment.computer.ownerId !== assignment.subscriptionBinding.ownerId)) throw new Error("Cloud computer runtime unavailable");
|
|
14504
|
-
return this.supervisor.start(assignment);
|
|
14563
|
+
return await this.supervisor.start(assignment);
|
|
14505
14564
|
}
|
|
14506
14565
|
/**
|
|
14507
14566
|
* A run id that could escape the daemon's dirs never reaches the
|
|
@@ -14699,7 +14758,7 @@ var Daemon = class {
|
|
|
14699
14758
|
startCoordinatorPass(deviceId) {
|
|
14700
14759
|
const link = this.options.link;
|
|
14701
14760
|
const sandbox = this.agentSandbox();
|
|
14702
|
-
if (this.nativeCoordinator || !link.claimCoordinator || !sandbox || this.stopped || !this.harnesses.some((info) => info.coordinator)) return;
|
|
14761
|
+
if (this.updating || this.draining || this.nativeCoordinator || !link.claimCoordinator || !sandbox || this.stopped || !this.harnesses.some((info) => info.coordinator)) return;
|
|
14703
14762
|
const controller = new AbortController();
|
|
14704
14763
|
this.nativeAbort = controller;
|
|
14705
14764
|
this.nativeCoordinator = (async () => {
|
|
@@ -14707,7 +14766,7 @@ var Daemon = class {
|
|
|
14707
14766
|
if (!job || controller.signal.aborted) return;
|
|
14708
14767
|
await runNativeCoordinatorJob(job, {
|
|
14709
14768
|
deviceId,
|
|
14710
|
-
stateDir:
|
|
14769
|
+
stateDir: join28(this.paths.dataDir, "coordinator"),
|
|
14711
14770
|
link,
|
|
14712
14771
|
signal: controller.signal,
|
|
14713
14772
|
sandbox,
|
|
@@ -14722,6 +14781,43 @@ var Daemon = class {
|
|
|
14722
14781
|
this.nativeAbort = null;
|
|
14723
14782
|
});
|
|
14724
14783
|
}
|
|
14784
|
+
maintenanceIdle() {
|
|
14785
|
+
return !this.stopped && !this.draining && !this.updating && !this.nativeCoordinator && this.claimsInFlight === 0 && this.supervisor.heartbeatRuns().length === 0;
|
|
14786
|
+
}
|
|
14787
|
+
startMaintenance(work, failed = () => {
|
|
14788
|
+
}) {
|
|
14789
|
+
if (!this.maintenanceIdle()) return;
|
|
14790
|
+
this.updating = true;
|
|
14791
|
+
this.maintenance = work().catch(() => {
|
|
14792
|
+
this.updating = false;
|
|
14793
|
+
failed();
|
|
14794
|
+
this.log.warn("Daemon update or restart failed; check service installation and npm configuration");
|
|
14795
|
+
}).finally(() => {
|
|
14796
|
+
this.maintenance = null;
|
|
14797
|
+
});
|
|
14798
|
+
}
|
|
14799
|
+
checkAutoUpdate() {
|
|
14800
|
+
const runtime = this.options.autoUpdate;
|
|
14801
|
+
if (!runtime || this.draining || this.updating) return;
|
|
14802
|
+
if (this.updateVersion && this.maintenanceIdle()) {
|
|
14803
|
+
const version = this.updateVersion;
|
|
14804
|
+
this.updateVersion = void 0;
|
|
14805
|
+
this.startMaintenance(async () => {
|
|
14806
|
+
await runtime.install(version);
|
|
14807
|
+
if (this.stopped) return;
|
|
14808
|
+
await restartService(false, () => {
|
|
14809
|
+
}, void 0, () => !this.stopped);
|
|
14810
|
+
});
|
|
14811
|
+
} else if (!this.updateCheck && !this.updateVersion) {
|
|
14812
|
+
this.updateCheck = checkLatestVersion(join28(this.paths.dataDir, "auto-update.json"), DAEMON_VERSION, runtime).then((version) => {
|
|
14813
|
+
this.updateVersion = version;
|
|
14814
|
+
}).catch(() => {
|
|
14815
|
+
this.log.warn("Daemon automatic update check failed");
|
|
14816
|
+
}).finally(() => {
|
|
14817
|
+
this.updateCheck = null;
|
|
14818
|
+
});
|
|
14819
|
+
}
|
|
14820
|
+
}
|
|
14725
14821
|
stop() {
|
|
14726
14822
|
return this.stopPromise ??= this.stopInternal();
|
|
14727
14823
|
}
|
|
@@ -14729,6 +14825,8 @@ var Daemon = class {
|
|
|
14729
14825
|
this.stopped = true;
|
|
14730
14826
|
this.localComputerBroker?.suspend();
|
|
14731
14827
|
await this.starting?.catch(() => void 0);
|
|
14828
|
+
await this.updateCheck;
|
|
14829
|
+
await this.maintenance;
|
|
14732
14830
|
this.nativeAbort?.abort();
|
|
14733
14831
|
await this.nativeCoordinator;
|
|
14734
14832
|
if (this.timer) clearTimeout(this.timer);
|