@aspectlylabs/mikka 0.0.1 → 0.0.4
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 +20 -4
- package/cli.js +101 -15
- package/client.js +10 -4
- package/http-link.js +32 -8
- package/login.js +10 -4
- package/main.js +218 -146
- package/mikka-mcp.mjs +4 -0
- package/mikka.js +101 -15
- package/package.json +2 -1
- package/paths.js +3 -2
package/main.js
CHANGED
|
@@ -2208,8 +2208,8 @@ var EventQueue = class {
|
|
|
2208
2208
|
if (next.type === "exit") return;
|
|
2209
2209
|
continue;
|
|
2210
2210
|
}
|
|
2211
|
-
await new Promise((
|
|
2212
|
-
this.waiter =
|
|
2211
|
+
await new Promise((resolve10) => {
|
|
2212
|
+
this.waiter = resolve10;
|
|
2213
2213
|
});
|
|
2214
2214
|
}
|
|
2215
2215
|
}
|
|
@@ -2280,13 +2280,13 @@ async function spawnCli(sandbox, argv, options) {
|
|
|
2280
2280
|
stderr = (stderr + data).slice(-STDERR_TAIL * 4);
|
|
2281
2281
|
});
|
|
2282
2282
|
const exited = new Promise(
|
|
2283
|
-
(
|
|
2283
|
+
(resolve10) => {
|
|
2284
2284
|
child.once("error", (error) => {
|
|
2285
2285
|
stderr += `
|
|
2286
2286
|
${error.message}`;
|
|
2287
|
-
|
|
2287
|
+
resolve10({ code: null, signal: null });
|
|
2288
2288
|
});
|
|
2289
|
-
child.once("exit", (code, signal) =>
|
|
2289
|
+
child.once("exit", (code, signal) => resolve10({ code, signal }));
|
|
2290
2290
|
}
|
|
2291
2291
|
).finally(() => {
|
|
2292
2292
|
signalGroup(pgid, "SIGKILL");
|
|
@@ -2303,8 +2303,8 @@ ${error.message}`;
|
|
|
2303
2303
|
let timer;
|
|
2304
2304
|
await Promise.race([
|
|
2305
2305
|
exited,
|
|
2306
|
-
new Promise((
|
|
2307
|
-
timer = setTimeout(
|
|
2306
|
+
new Promise((resolve10) => {
|
|
2307
|
+
timer = setTimeout(resolve10, graceMs);
|
|
2308
2308
|
})
|
|
2309
2309
|
]);
|
|
2310
2310
|
clearTimeout(timer);
|
|
@@ -2313,17 +2313,17 @@ ${error.message}`;
|
|
|
2313
2313
|
}
|
|
2314
2314
|
};
|
|
2315
2315
|
}
|
|
2316
|
-
async function untilReady(child, step,
|
|
2316
|
+
async function untilReady(child, step, label2, ms = 12e4) {
|
|
2317
2317
|
let timer;
|
|
2318
2318
|
try {
|
|
2319
2319
|
return await Promise.race([
|
|
2320
2320
|
step,
|
|
2321
2321
|
child.exited.then(({ code, signal }) => {
|
|
2322
|
-
throw new Error(`${
|
|
2322
|
+
throw new Error(`${label2}: the CLI exited (${signal ?? code})`);
|
|
2323
2323
|
}),
|
|
2324
2324
|
new Promise((_, reject) => {
|
|
2325
2325
|
timer = setTimeout(
|
|
2326
|
-
() => reject(new Error(`${
|
|
2326
|
+
() => reject(new Error(`${label2}: no answer after ${ms / 1e3} s`)),
|
|
2327
2327
|
ms
|
|
2328
2328
|
);
|
|
2329
2329
|
})
|
|
@@ -2385,11 +2385,11 @@ var JsonlWriter = class extends AbstractMessageWriter {
|
|
|
2385
2385
|
}
|
|
2386
2386
|
stream;
|
|
2387
2387
|
write(message) {
|
|
2388
|
-
return new Promise((
|
|
2388
|
+
return new Promise((resolve10, reject) => {
|
|
2389
2389
|
this.stream.write(
|
|
2390
2390
|
`${JSON.stringify(message)}
|
|
2391
2391
|
`,
|
|
2392
|
-
(error) => error ? reject(error) :
|
|
2392
|
+
(error) => error ? reject(error) : resolve10()
|
|
2393
2393
|
);
|
|
2394
2394
|
});
|
|
2395
2395
|
}
|
|
@@ -2625,13 +2625,18 @@ var runReport = z2.object({
|
|
|
2625
2625
|
sha: z2.string().regex(/^[a-f0-9]{40}$/),
|
|
2626
2626
|
readOnly: z2.literal(true)
|
|
2627
2627
|
}).optional(),
|
|
2628
|
+
/** Preview branch created or used by the producing run; descriptive metadata only. */
|
|
2629
|
+
previewDatabaseBranch: z2.string().trim().min(1).max(500).optional(),
|
|
2628
2630
|
/** Acceptance criteria the agent checked, with evidence. */
|
|
2629
2631
|
criteria: z2.array(
|
|
2630
2632
|
z2.object({
|
|
2631
2633
|
criterionId: z2.uuid().optional(),
|
|
2632
2634
|
text: z2.string().max(2e3).optional(),
|
|
2633
2635
|
passed: z2.boolean(),
|
|
2634
|
-
evidence: z2.string().max(1e4).optional()
|
|
2636
|
+
evidence: z2.string().max(1e4).optional(),
|
|
2637
|
+
/** Agent-reported criterion check; the daemon-owned verify remains authoritative. */
|
|
2638
|
+
command: z2.string().trim().min(1).max(2e3).optional(),
|
|
2639
|
+
exitCode: z2.number().int().nullable().optional()
|
|
2635
2640
|
})
|
|
2636
2641
|
).max(200).optional(),
|
|
2637
2642
|
/**
|
|
@@ -2821,7 +2826,7 @@ import { join as join2 } from "node:path";
|
|
|
2821
2826
|
// package.json
|
|
2822
2827
|
var package_default = {
|
|
2823
2828
|
name: "@mikka/daemon",
|
|
2824
|
-
version: "0.0.
|
|
2829
|
+
version: "0.0.4",
|
|
2825
2830
|
description: "Local Mikka daemon: runs agents through the user's own CLIs",
|
|
2826
2831
|
type: "module",
|
|
2827
2832
|
private: true,
|
|
@@ -2878,7 +2883,8 @@ var package_default = {
|
|
|
2878
2883
|
},
|
|
2879
2884
|
engines: {
|
|
2880
2885
|
node: ">=24"
|
|
2881
|
-
}
|
|
2886
|
+
},
|
|
2887
|
+
gitHead: "4c5f80747928d60ea3e03ed6a3de5ca2dc2216df"
|
|
2882
2888
|
};
|
|
2883
2889
|
|
|
2884
2890
|
// src/paths.ts
|
|
@@ -3837,7 +3843,7 @@ var heartbeatRunSchema = z14.object({
|
|
|
3837
3843
|
/** Last tool call, turn boundary or file change (not raw output). */
|
|
3838
3844
|
lastProgressAt: isoTime
|
|
3839
3845
|
});
|
|
3840
|
-
var deviceManagementCommand = z14.object({ id: z14.uuid(), kind: z14.enum(["redetect", "restart", "update"]) });
|
|
3846
|
+
var deviceManagementCommand = z14.object({ id: z14.uuid(), kind: z14.enum(["redetect", "restart", "update", "uninstall"]) });
|
|
3841
3847
|
var deviceHeartbeatSchema = z14.object({
|
|
3842
3848
|
completedDeviceCommands: z14.array(z14.uuid()).max(100).optional(),
|
|
3843
3849
|
failedDeviceCommands: z14.array(z14.object({ id: z14.uuid(), error: z14.string().max(500) })).max(100).optional(),
|
|
@@ -5157,6 +5163,7 @@ var RunContext = class {
|
|
|
5157
5163
|
nextStep: file.nextStep ?? null,
|
|
5158
5164
|
...file.blockedOn ? { blockedOn: file.blockedOn } : {},
|
|
5159
5165
|
...plan ? { plan } : {},
|
|
5166
|
+
...typeof file.previewDatabaseBranch === "string" ? { previewDatabaseBranch: file.previewDatabaseBranch } : {},
|
|
5160
5167
|
...Array.isArray(file.criteria) ? { criteria: file.criteria } : {},
|
|
5161
5168
|
...runQuestion.safeParse(file.question).success ? { question: runQuestion.parse(file.question) } : {}
|
|
5162
5169
|
};
|
|
@@ -5418,8 +5425,8 @@ async function runCodexCoordinator(input, host) {
|
|
|
5418
5425
|
const messages = /* @__PURE__ */ new Map();
|
|
5419
5426
|
let resolveEnd;
|
|
5420
5427
|
let rejectEnd;
|
|
5421
|
-
const ended = new Promise((
|
|
5422
|
-
resolveEnd =
|
|
5428
|
+
const ended = new Promise((resolve10, reject) => {
|
|
5429
|
+
resolveEnd = resolve10;
|
|
5423
5430
|
rejectEnd = reject;
|
|
5424
5431
|
});
|
|
5425
5432
|
void ended.catch(() => void 0);
|
|
@@ -5599,10 +5606,11 @@ import {
|
|
|
5599
5606
|
existsSync as existsSync6,
|
|
5600
5607
|
mkdirSync as mkdirSync15,
|
|
5601
5608
|
readFileSync as readFileSync11,
|
|
5609
|
+
rmSync as rmSync16,
|
|
5602
5610
|
realpathSync as realpathSync11
|
|
5603
5611
|
} from "node:fs";
|
|
5604
5612
|
import { arch, hostname, platform as platform2 } from "node:os";
|
|
5605
|
-
import { join as
|
|
5613
|
+
import { join as join26 } from "node:path";
|
|
5606
5614
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
5607
5615
|
|
|
5608
5616
|
// src/adapters/claude.ts
|
|
@@ -5728,8 +5736,8 @@ function spawnRunSandbox(options) {
|
|
|
5728
5736
|
let outcome;
|
|
5729
5737
|
let hardStop;
|
|
5730
5738
|
let settle;
|
|
5731
|
-
const exited = new Promise((
|
|
5732
|
-
settle =
|
|
5739
|
+
const exited = new Promise((resolve10) => {
|
|
5740
|
+
settle = resolve10;
|
|
5733
5741
|
});
|
|
5734
5742
|
function send(message) {
|
|
5735
5743
|
if (!child.connected || gone) return;
|
|
@@ -6002,9 +6010,9 @@ async function createNativeSubscriptionBroker(host) {
|
|
|
6002
6010
|
}
|
|
6003
6011
|
});
|
|
6004
6012
|
try {
|
|
6005
|
-
await new Promise((
|
|
6013
|
+
await new Promise((resolve10, reject) => {
|
|
6006
6014
|
server.once("error", reject);
|
|
6007
|
-
server.listen(socket,
|
|
6015
|
+
server.listen(socket, resolve10);
|
|
6008
6016
|
});
|
|
6009
6017
|
chmodSync(socket, 384);
|
|
6010
6018
|
} catch {
|
|
@@ -6017,7 +6025,7 @@ async function createNativeSubscriptionBroker(host) {
|
|
|
6017
6025
|
halted = true;
|
|
6018
6026
|
for (const abort of pending) abort.abort();
|
|
6019
6027
|
server.closeAllConnections();
|
|
6020
|
-
await new Promise((
|
|
6028
|
+
await new Promise((resolve10) => server.close(() => resolve10()));
|
|
6021
6029
|
rmSync6(dir, { recursive: true, force: true });
|
|
6022
6030
|
}
|
|
6023
6031
|
};
|
|
@@ -6181,8 +6189,8 @@ var PromptQueue = class {
|
|
|
6181
6189
|
continue;
|
|
6182
6190
|
}
|
|
6183
6191
|
if (this.closed) return;
|
|
6184
|
-
await new Promise((
|
|
6185
|
-
this.waiter =
|
|
6192
|
+
await new Promise((resolve10) => {
|
|
6193
|
+
this.waiter = resolve10;
|
|
6186
6194
|
});
|
|
6187
6195
|
}
|
|
6188
6196
|
}
|
|
@@ -6196,8 +6204,8 @@ async function untilSpoken(spoken) {
|
|
|
6196
6204
|
try {
|
|
6197
6205
|
return await Promise.race([
|
|
6198
6206
|
spoken,
|
|
6199
|
-
new Promise((
|
|
6200
|
-
timer = setTimeout(() =>
|
|
6207
|
+
new Promise((resolve10) => {
|
|
6208
|
+
timer = setTimeout(() => resolve10(true), CONTINUE_SILENCE_MS);
|
|
6201
6209
|
})
|
|
6202
6210
|
]);
|
|
6203
6211
|
} finally {
|
|
@@ -6330,9 +6338,9 @@ var ClaudeAdapter = class {
|
|
|
6330
6338
|
let stderr = "";
|
|
6331
6339
|
const stderrTail = () => stderr.slice(-STDERR_TAIL2).trim() || "no output";
|
|
6332
6340
|
let spoke = () => void 0;
|
|
6333
|
-
const spoken = new Promise((
|
|
6341
|
+
const spoken = new Promise((resolve10) => spoke = resolve10);
|
|
6334
6342
|
let finished = () => void 0;
|
|
6335
|
-
const gone = new Promise((
|
|
6343
|
+
const gone = new Promise((resolve10) => finished = resolve10);
|
|
6336
6344
|
if (externalAuth && this.options.onHostedSession) {
|
|
6337
6345
|
try {
|
|
6338
6346
|
await this.options.onHostedSession(sessionId);
|
|
@@ -7033,7 +7041,7 @@ var CodexAdapter = class {
|
|
|
7033
7041
|
error: externalAuth ? SUBSCRIPTION_EXECUTION_ERROR2 : `codex app-server exited (${signal ?? code}): ${child.stderrTail() || "no output"}`
|
|
7034
7042
|
});
|
|
7035
7043
|
});
|
|
7036
|
-
const ready = (step,
|
|
7044
|
+
const ready = (step, label2) => untilReady(child, step, `codex ${label2}`);
|
|
7037
7045
|
try {
|
|
7038
7046
|
const initialized = await ready(
|
|
7039
7047
|
rpc.sendRequest("initialize", {
|
|
@@ -7452,7 +7460,7 @@ var CursorAdapter = class {
|
|
|
7452
7460
|
env: Object.entries(computerMcp.env).map(([name, value]) => ({ name, value }))
|
|
7453
7461
|
}] : []
|
|
7454
7462
|
];
|
|
7455
|
-
const ready = (step,
|
|
7463
|
+
const ready = (step, label2) => untilReady(child, step, `cursor ${label2}`);
|
|
7456
7464
|
try {
|
|
7457
7465
|
await ready(
|
|
7458
7466
|
conn.initialize({
|
|
@@ -7669,7 +7677,7 @@ var MockAdapter = class {
|
|
|
7669
7677
|
if (line.hang) {
|
|
7670
7678
|
if (!abort.signal.aborted) {
|
|
7671
7679
|
await new Promise(
|
|
7672
|
-
(
|
|
7680
|
+
(resolve10) => abort.signal.addEventListener("abort", resolve10, { once: true })
|
|
7673
7681
|
);
|
|
7674
7682
|
}
|
|
7675
7683
|
yield { type: "exit", outcome: "cancelled" };
|
|
@@ -8593,7 +8601,11 @@ async function verifyExpectedOrigin(path, expected) {
|
|
|
8593
8601
|
// src/service.ts
|
|
8594
8602
|
import { execFile as execFile2 } from "node:child_process";
|
|
8595
8603
|
import { promisify as promisify2 } from "node:util";
|
|
8604
|
+
import { mkdir, writeFile, rm } from "node:fs/promises";
|
|
8605
|
+
import { homedir as homedir6 } from "node:os";
|
|
8606
|
+
import { dirname as dirname9, join as join16, resolve as resolve7 } from "node:path";
|
|
8596
8607
|
var exec = promisify2(execFile2);
|
|
8608
|
+
var label = "com.aspectlylabs.mikka.daemon";
|
|
8597
8609
|
async function restartService(update, beforeRestart, dependencies = {
|
|
8598
8610
|
manager: process.env.MIKKA_SERVICE,
|
|
8599
8611
|
update: async () => {
|
|
@@ -8609,6 +8621,34 @@ async function restartService(update, beforeRestart, dependencies = {
|
|
|
8609
8621
|
beforeRestart();
|
|
8610
8622
|
dependencies.restart();
|
|
8611
8623
|
}
|
|
8624
|
+
async function uninstallService(clearCredential, dependencies = {
|
|
8625
|
+
manager: process.env.MIKKA_SERVICE,
|
|
8626
|
+
home: homedir6(),
|
|
8627
|
+
uid: process.getuid?.() ?? 0,
|
|
8628
|
+
run: async (program, args) => {
|
|
8629
|
+
await exec(program, args, { timeout: 1e4 });
|
|
8630
|
+
},
|
|
8631
|
+
exit: () => {
|
|
8632
|
+
process.exit(0);
|
|
8633
|
+
}
|
|
8634
|
+
}) {
|
|
8635
|
+
try {
|
|
8636
|
+
if (dependencies.manager === "systemd") {
|
|
8637
|
+
await dependencies.run("systemctl", ["--user", "disable", "mikka-daemon.service"]);
|
|
8638
|
+
await rm(join16(dependencies.home, ".config/systemd/user/mikka-daemon.service"), { force: true });
|
|
8639
|
+
await dependencies.run("systemctl", ["--user", "daemon-reload"]);
|
|
8640
|
+
} else if (dependencies.manager === "launchd") {
|
|
8641
|
+
await rm(join16(dependencies.home, "Library/LaunchAgents", `${label}.plist`), { force: true });
|
|
8642
|
+
}
|
|
8643
|
+
} finally {
|
|
8644
|
+
clearCredential();
|
|
8645
|
+
try {
|
|
8646
|
+
if (dependencies.manager === "launchd") await dependencies.run("launchctl", ["bootout", `gui/${dependencies.uid}/${label}`]);
|
|
8647
|
+
} finally {
|
|
8648
|
+
dependencies.exit();
|
|
8649
|
+
}
|
|
8650
|
+
}
|
|
8651
|
+
}
|
|
8612
8652
|
|
|
8613
8653
|
// src/device-type.ts
|
|
8614
8654
|
import { readdir as readdir3, readFile } from "node:fs/promises";
|
|
@@ -8765,7 +8805,7 @@ async function detectHarnesses() {
|
|
|
8765
8805
|
// src/lock.ts
|
|
8766
8806
|
import { mkdirSync as mkdirSync11, readFileSync as readFileSync9, rmSync as rmSync10 } from "node:fs";
|
|
8767
8807
|
import { createConnection } from "node:net";
|
|
8768
|
-
import { join as
|
|
8808
|
+
import { join as join17 } from "node:path";
|
|
8769
8809
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
8770
8810
|
import lockfile from "proper-lockfile";
|
|
8771
8811
|
var DaemonAlreadyRunningError = class extends Error {
|
|
@@ -8780,7 +8820,7 @@ var LOCK_STALE_MS = 5 * 6e4;
|
|
|
8780
8820
|
var LOCK_UPDATE_MS = 3e4;
|
|
8781
8821
|
var LOCK_TAKEOVER_MS = 6e3;
|
|
8782
8822
|
function pidFile(dataDir) {
|
|
8783
|
-
return
|
|
8823
|
+
return join17(dataDir, "daemon.pid");
|
|
8784
8824
|
}
|
|
8785
8825
|
function holderPid(dataDir) {
|
|
8786
8826
|
try {
|
|
@@ -8799,11 +8839,11 @@ function processAlive(pid) {
|
|
|
8799
8839
|
}
|
|
8800
8840
|
}
|
|
8801
8841
|
function socketAnswers(socketPath) {
|
|
8802
|
-
return new Promise((
|
|
8842
|
+
return new Promise((resolve10) => {
|
|
8803
8843
|
const socket = createConnection(socketPath);
|
|
8804
8844
|
const done = (alive) => {
|
|
8805
8845
|
socket.destroy();
|
|
8806
|
-
|
|
8846
|
+
resolve10(alive);
|
|
8807
8847
|
};
|
|
8808
8848
|
socket.once("connect", () => done(true));
|
|
8809
8849
|
socket.once("error", () => done(false));
|
|
@@ -8912,7 +8952,7 @@ function closeLogger(logger) {
|
|
|
8912
8952
|
const file = files.get(logger);
|
|
8913
8953
|
if (!file) return Promise.resolve();
|
|
8914
8954
|
files.delete(logger);
|
|
8915
|
-
return new Promise((
|
|
8955
|
+
return new Promise((resolve10) => file.end(resolve10));
|
|
8916
8956
|
}
|
|
8917
8957
|
|
|
8918
8958
|
// src/outbox.ts
|
|
@@ -8924,7 +8964,7 @@ import {
|
|
|
8924
8964
|
rmSync as rmSync11,
|
|
8925
8965
|
truncateSync
|
|
8926
8966
|
} from "node:fs";
|
|
8927
|
-
import { join as
|
|
8967
|
+
import { join as join18 } from "node:path";
|
|
8928
8968
|
var Outbox = class {
|
|
8929
8969
|
constructor(dir, link, log, retryMs = 1e3, onUndeliverable = () => void 0, retainResources = false) {
|
|
8930
8970
|
this.dir = dir;
|
|
@@ -8947,10 +8987,10 @@ var Outbox = class {
|
|
|
8947
8987
|
/** Runs whose file was checked for a torn tail since this process started. */
|
|
8948
8988
|
repaired = /* @__PURE__ */ new Set();
|
|
8949
8989
|
file(runId) {
|
|
8950
|
-
return
|
|
8990
|
+
return join18(this.dir, `${assertSafeId("run id", runId)}.jsonl`);
|
|
8951
8991
|
}
|
|
8952
8992
|
ackFile(runId) {
|
|
8953
|
-
return
|
|
8993
|
+
return join18(this.dir, `${assertSafeId("run id", runId)}.ack.json`);
|
|
8954
8994
|
}
|
|
8955
8995
|
parse(runId) {
|
|
8956
8996
|
let data;
|
|
@@ -9134,8 +9174,8 @@ var Outbox = class {
|
|
|
9134
9174
|
};
|
|
9135
9175
|
|
|
9136
9176
|
// src/quota/local-credentials.ts
|
|
9137
|
-
import { homedir as
|
|
9138
|
-
import { join as
|
|
9177
|
+
import { homedir as homedir7 } from "node:os";
|
|
9178
|
+
import { join as join20 } from "node:path";
|
|
9139
9179
|
|
|
9140
9180
|
// src/quota/files.ts
|
|
9141
9181
|
import { execFile as execFile3 } from "node:child_process";
|
|
@@ -9321,17 +9361,17 @@ function claudePlanLabel(credential) {
|
|
|
9321
9361
|
const tier = credential.rateLimitTier?.toLowerCase() ?? "";
|
|
9322
9362
|
const hasMax20 = tier.includes("max_20x") || tier.includes("max20x") || tier.includes("max-20x");
|
|
9323
9363
|
const hasMax = tier.includes("max");
|
|
9324
|
-
let
|
|
9364
|
+
let label2 = "Subscription";
|
|
9325
9365
|
if (subscriptionType === "team" || subscriptionType === "" && tier.includes("team")) {
|
|
9326
|
-
|
|
9366
|
+
label2 = hasMax ? "Team Premium" : "Team";
|
|
9327
9367
|
} else if (subscriptionType === "enterprise" || subscriptionType === "" && tier.includes("enterprise")) {
|
|
9328
|
-
|
|
9368
|
+
label2 = hasMax ? "Enterprise Premium" : "Enterprise";
|
|
9329
9369
|
} else if (subscriptionType === "max" || hasMax) {
|
|
9330
|
-
|
|
9370
|
+
label2 = hasMax20 ? "Max 20x" : "Max 5x";
|
|
9331
9371
|
} else if (subscriptionType === "pro" || tier.includes("pro")) {
|
|
9332
|
-
|
|
9372
|
+
label2 = "Pro";
|
|
9333
9373
|
}
|
|
9334
|
-
return cleanText(
|
|
9374
|
+
return cleanText(label2);
|
|
9335
9375
|
}
|
|
9336
9376
|
function windowFrom(kind, value, model) {
|
|
9337
9377
|
if (!value || typeof value !== "object") return null;
|
|
@@ -9633,12 +9673,12 @@ async function readCodexQuota(options) {
|
|
|
9633
9673
|
|
|
9634
9674
|
// src/quota/cursor.ts
|
|
9635
9675
|
import { lstat as lstat3 } from "node:fs/promises";
|
|
9636
|
-
import { join as
|
|
9676
|
+
import { join as join19 } from "node:path";
|
|
9637
9677
|
var ENDPOINT3 = "https://cursor.com/api/usage-summary";
|
|
9638
9678
|
var ACCESS_TOKEN_KEY = "cursorAuth/accessToken";
|
|
9639
9679
|
function cursorDatabasePath(platform3, home) {
|
|
9640
9680
|
if (platform3 === "darwin") {
|
|
9641
|
-
return
|
|
9681
|
+
return join19(
|
|
9642
9682
|
home,
|
|
9643
9683
|
"Library",
|
|
9644
9684
|
"Application Support",
|
|
@@ -9649,7 +9689,7 @@ function cursorDatabasePath(platform3, home) {
|
|
|
9649
9689
|
);
|
|
9650
9690
|
}
|
|
9651
9691
|
if (platform3 === "win32") {
|
|
9652
|
-
return
|
|
9692
|
+
return join19(
|
|
9653
9693
|
home,
|
|
9654
9694
|
"AppData",
|
|
9655
9695
|
"Roaming",
|
|
@@ -9659,7 +9699,7 @@ function cursorDatabasePath(platform3, home) {
|
|
|
9659
9699
|
"state.vscdb"
|
|
9660
9700
|
);
|
|
9661
9701
|
}
|
|
9662
|
-
return
|
|
9702
|
+
return join19(home, ".config", "Cursor", "User", "globalStorage", "state.vscdb");
|
|
9663
9703
|
}
|
|
9664
9704
|
var CURSOR_PLANS = {
|
|
9665
9705
|
pro: "Pro",
|
|
@@ -9831,10 +9871,10 @@ async function readCursorQuota(options) {
|
|
|
9831
9871
|
// src/quota/local-credentials.ts
|
|
9832
9872
|
var KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
9833
9873
|
function claudeCredentialPath(home) {
|
|
9834
|
-
return
|
|
9874
|
+
return join20(home, ".claude", ".credentials.json");
|
|
9835
9875
|
}
|
|
9836
9876
|
function codexAuthPath(home) {
|
|
9837
|
-
return
|
|
9877
|
+
return join20(home, ".codex", "auth.json");
|
|
9838
9878
|
}
|
|
9839
9879
|
function unknown2(vendor, observedAt) {
|
|
9840
9880
|
return {
|
|
@@ -9853,7 +9893,7 @@ var LocalCredentialsSource = class {
|
|
|
9853
9893
|
options;
|
|
9854
9894
|
id = "local_credentials";
|
|
9855
9895
|
async read(signal) {
|
|
9856
|
-
const home = this.options.home ??
|
|
9896
|
+
const home = this.options.home ?? homedir7();
|
|
9857
9897
|
const platform3 = this.options.platform ?? process.platform;
|
|
9858
9898
|
const fetchImpl = this.options.fetch ?? globalThis.fetch;
|
|
9859
9899
|
const now = this.options.now ?? Date.now;
|
|
@@ -10029,9 +10069,9 @@ var RpcServer = class {
|
|
|
10029
10069
|
const { socketPath } = this.options;
|
|
10030
10070
|
rmSync12(socketPath, { force: true });
|
|
10031
10071
|
const server = createServer2((socket) => this.accept(socket));
|
|
10032
|
-
await new Promise((
|
|
10072
|
+
await new Promise((resolve10, reject) => {
|
|
10033
10073
|
server.once("error", reject);
|
|
10034
|
-
server.listen(socketPath, () =>
|
|
10074
|
+
server.listen(socketPath, () => resolve10());
|
|
10035
10075
|
});
|
|
10036
10076
|
chmodSync2(socketPath, 384);
|
|
10037
10077
|
this.server = server;
|
|
@@ -10095,9 +10135,9 @@ var RpcServer = class {
|
|
|
10095
10135
|
}
|
|
10096
10136
|
async close() {
|
|
10097
10137
|
for (const socket of this.sockets) socket.destroy();
|
|
10098
|
-
await new Promise((
|
|
10099
|
-
if (!this.server) return
|
|
10100
|
-
this.server.close(() =>
|
|
10138
|
+
await new Promise((resolve10) => {
|
|
10139
|
+
if (!this.server) return resolve10();
|
|
10140
|
+
this.server.close(() => resolve10());
|
|
10101
10141
|
});
|
|
10102
10142
|
this.server = null;
|
|
10103
10143
|
rmSync12(this.options.socketPath, { force: true });
|
|
@@ -10225,7 +10265,7 @@ function createRunMasker(secrets) {
|
|
|
10225
10265
|
let pending = /* @__PURE__ */ new Map();
|
|
10226
10266
|
const text3 = (value) => {
|
|
10227
10267
|
let out = value;
|
|
10228
|
-
for (const [needle,
|
|
10268
|
+
for (const [needle, label2] of needles) if (out.includes(needle)) out = out.split(needle).join(label2);
|
|
10229
10269
|
return out;
|
|
10230
10270
|
};
|
|
10231
10271
|
const holdback = (value) => {
|
|
@@ -10323,13 +10363,13 @@ function createRunMasker(secrets) {
|
|
|
10323
10363
|
|
|
10324
10364
|
// src/runs/supervisor.ts
|
|
10325
10365
|
import { createHash as createHash3, randomUUID as randomUUID5 } from "node:crypto";
|
|
10326
|
-
import { join as
|
|
10366
|
+
import { join as join22, resolve as resolve8 } from "node:path";
|
|
10327
10367
|
import { execa as execa11 } from "execa";
|
|
10328
10368
|
|
|
10329
10369
|
// src/agents/checkpoint.ts
|
|
10330
10370
|
import { mkdtempSync as mkdtempSync5, rmSync as rmSync13, writeFileSync as writeFileSync6 } from "node:fs";
|
|
10331
10371
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
10332
|
-
import { join as
|
|
10372
|
+
import { join as join21 } from "node:path";
|
|
10333
10373
|
import { gunzipSync as gunzipSync2, gzipSync as gzipSync2 } from "node:zlib";
|
|
10334
10374
|
import { execa as execa10 } from "execa";
|
|
10335
10375
|
async function headCommit(repoPath, worktree) {
|
|
@@ -10363,8 +10403,8 @@ async function takeCheckpoint(options) {
|
|
|
10363
10403
|
}
|
|
10364
10404
|
async function applyCheckpoint(options) {
|
|
10365
10405
|
const git2 = await pinnedGit(options.repoPath, options.worktree);
|
|
10366
|
-
const dir = mkdtempSync5(
|
|
10367
|
-
const file =
|
|
10406
|
+
const dir = mkdtempSync5(join21(tmpdir2(), "mikka-checkpoint-"));
|
|
10407
|
+
const file = join21(dir, "checkpoint.patch");
|
|
10368
10408
|
try {
|
|
10369
10409
|
writeFileSync6(
|
|
10370
10410
|
file,
|
|
@@ -10613,12 +10653,12 @@ var MemoryServer = class {
|
|
|
10613
10653
|
this.check();
|
|
10614
10654
|
let pending = this.pendingCommands(deviceId, skip);
|
|
10615
10655
|
if (pending.length === 0 && waitSeconds > 0 && !signal?.aborted) {
|
|
10616
|
-
await new Promise((
|
|
10617
|
-
const timer = setTimeout(
|
|
10618
|
-
signal?.addEventListener("abort", () =>
|
|
10656
|
+
await new Promise((resolve10) => {
|
|
10657
|
+
const timer = setTimeout(resolve10, waitSeconds * 1e3);
|
|
10658
|
+
signal?.addEventListener("abort", () => resolve10(), { once: true });
|
|
10619
10659
|
this.wakeCommands.push(() => {
|
|
10620
10660
|
clearTimeout(timer);
|
|
10621
|
-
|
|
10661
|
+
resolve10();
|
|
10622
10662
|
});
|
|
10623
10663
|
});
|
|
10624
10664
|
this.check();
|
|
@@ -11026,9 +11066,9 @@ var RunSupervisor = class {
|
|
|
11026
11066
|
run2.abort.abort();
|
|
11027
11067
|
}
|
|
11028
11068
|
let timer;
|
|
11029
|
-
const grace = new Promise((
|
|
11069
|
+
const grace = new Promise((resolve10) => {
|
|
11030
11070
|
timer = setTimeout(
|
|
11031
|
-
|
|
11071
|
+
resolve10,
|
|
11032
11072
|
this.deps.stopGraceMs ?? DEFAULT_STOP_GRACE_MS
|
|
11033
11073
|
);
|
|
11034
11074
|
});
|
|
@@ -11220,8 +11260,8 @@ var RunSupervisor = class {
|
|
|
11220
11260
|
let timer;
|
|
11221
11261
|
await Promise.race([
|
|
11222
11262
|
this.deps.captures.flush(runId),
|
|
11223
|
-
new Promise((
|
|
11224
|
-
timer = setTimeout(
|
|
11263
|
+
new Promise((resolve10) => {
|
|
11264
|
+
timer = setTimeout(resolve10, 6e4);
|
|
11225
11265
|
})
|
|
11226
11266
|
]).finally(() => clearTimeout(timer));
|
|
11227
11267
|
}
|
|
@@ -11474,7 +11514,7 @@ var RunSupervisor = class {
|
|
|
11474
11514
|
const current = this.deps.journal.get(runId);
|
|
11475
11515
|
assertMailboxRunAuthority({ held: this.active.get(runId) === run2, state: current?.state, stopped: this.stopping || run2.cancelRequested || run2.abort.signal.aborted, lease });
|
|
11476
11516
|
};
|
|
11477
|
-
|
|
11517
|
+
let mailbox = await this.deps.prepareRunMailbox?.(assignment, run2.abort.signal, checkMailbox);
|
|
11478
11518
|
run2.mailbox = mailbox;
|
|
11479
11519
|
if (this.stopping) return;
|
|
11480
11520
|
if (run2.cancelRequested) {
|
|
@@ -11484,6 +11524,14 @@ var RunSupervisor = class {
|
|
|
11484
11524
|
if (mailbox) checkMailbox();
|
|
11485
11525
|
const toolApproval = await this.deps.prepareRunToolApproval?.(assignment, run2.abort.signal, checkMailbox, worktree);
|
|
11486
11526
|
run2.toolApproval = toolApproval;
|
|
11527
|
+
if (mailbox && toolApproval) {
|
|
11528
|
+
const original = mailbox;
|
|
11529
|
+
mailbox = { tools: original.tools, close: () => original.close(), request: async (body, signal) => {
|
|
11530
|
+
if (!await toolApproval.checkLive()) throw new Error("Run tool approval unavailable");
|
|
11531
|
+
return original.request(body, signal);
|
|
11532
|
+
} };
|
|
11533
|
+
run2.mailbox = mailbox;
|
|
11534
|
+
}
|
|
11487
11535
|
if (this.stopping) {
|
|
11488
11536
|
toolApproval?.revoke();
|
|
11489
11537
|
return;
|
|
@@ -11531,7 +11579,7 @@ var RunSupervisor = class {
|
|
|
11531
11579
|
mailbox
|
|
11532
11580
|
};
|
|
11533
11581
|
const resuming = entry.sessionId !== null && adapter.capabilities.supportsResume;
|
|
11534
|
-
const inEarlierWorktree = continued !== null || entry.worktree !== null &&
|
|
11582
|
+
const inEarlierWorktree = continued !== null || entry.worktree !== null && resolve8(entry.worktree) !== resolve8(this.deps.worktrees.pathFor(runId));
|
|
11535
11583
|
const continueSession = !resuming && assignment.resumeSessionId && assignment.continuesRunId && inEarlierWorktree && adapter.capabilities.supportsResume ? {
|
|
11536
11584
|
sessionId: assignment.resumeSessionId,
|
|
11537
11585
|
runId: assignment.continuesRunId,
|
|
@@ -11578,7 +11626,7 @@ var RunSupervisor = class {
|
|
|
11578
11626
|
if (!this.deps.adapterStateDir || assignment.harness === "mock" || !session.sessionId || resuming && session.sessionId !== entry.sessionId || assignment.requireSessionResume && session.sessionId !== assignment.resumeSessionId)
|
|
11579
11627
|
throw new Error("Skill mount requires the actual original harness session");
|
|
11580
11628
|
verifySkillAssignment(assignment);
|
|
11581
|
-
const file =
|
|
11629
|
+
const file = join22(
|
|
11582
11630
|
runPaths(this.deps.adapterStateDir, runId).runDir,
|
|
11583
11631
|
SKILLS_DIR,
|
|
11584
11632
|
skillSlug(assignment.skills[0].name),
|
|
@@ -11756,10 +11804,10 @@ function trackParts(open2, chunk) {
|
|
|
11756
11804
|
}
|
|
11757
11805
|
var ABORTED = /* @__PURE__ */ Symbol("aborted");
|
|
11758
11806
|
function abortPromise(signal) {
|
|
11759
|
-
return new Promise((
|
|
11760
|
-
if (signal.aborted)
|
|
11807
|
+
return new Promise((resolve10) => {
|
|
11808
|
+
if (signal.aborted) resolve10(ABORTED);
|
|
11761
11809
|
else
|
|
11762
|
-
signal.addEventListener("abort", () =>
|
|
11810
|
+
signal.addEventListener("abort", () => resolve10(ABORTED), { once: true });
|
|
11763
11811
|
});
|
|
11764
11812
|
}
|
|
11765
11813
|
function pickAgentReport(agent) {
|
|
@@ -11777,18 +11825,21 @@ function pickAgentReport(agent) {
|
|
|
11777
11825
|
const question = runQuestion.safeParse(agent.question);
|
|
11778
11826
|
if (question.success) picked.question = question.data;
|
|
11779
11827
|
if (agent.plan) picked.plan = agent.plan;
|
|
11828
|
+
if (typeof agent.previewDatabaseBranch === "string" && agent.previewDatabaseBranch.trim())
|
|
11829
|
+
picked.previewDatabaseBranch = agent.previewDatabaseBranch.trim().slice(0, 500);
|
|
11780
11830
|
if (Array.isArray(agent.criteria)) {
|
|
11781
11831
|
const criteria = [];
|
|
11782
11832
|
for (const entry of agent.criteria) {
|
|
11783
11833
|
if (criteria.length >= MAX_REPORTED_CRITERIA) break;
|
|
11784
11834
|
if (!entry || typeof entry !== "object") continue;
|
|
11785
|
-
const { criterionId, passed, evidence } = entry;
|
|
11835
|
+
const { criterionId, passed, evidence, command, exitCode } = entry;
|
|
11786
11836
|
if (typeof criterionId !== "string" || !UUID_RE.test(criterionId))
|
|
11787
11837
|
continue;
|
|
11788
11838
|
if (typeof passed !== "boolean") continue;
|
|
11789
11839
|
criteria.push({
|
|
11790
11840
|
criterionId,
|
|
11791
11841
|
passed,
|
|
11842
|
+
...typeof command === "string" && command.trim() ? { command: command.trim().slice(0, 2e3), ...exitCode === null || typeof exitCode === "number" && Number.isSafeInteger(exitCode) ? { exitCode } : {} } : {},
|
|
11792
11843
|
...typeof evidence === "string" ? { evidence: evidence.slice(0, 1e4) } : {}
|
|
11793
11844
|
});
|
|
11794
11845
|
}
|
|
@@ -11848,7 +11899,7 @@ var SessionRejectedError = class extends DaemonError {
|
|
|
11848
11899
|
// src/repositories.ts
|
|
11849
11900
|
import { createHash as createHash4, randomUUID as randomUUID6 } from "node:crypto";
|
|
11850
11901
|
import { existsSync as existsSync4, lstatSync as lstatSync7, mkdirSync as mkdirSync13, readdirSync as readdirSync5, realpathSync as realpathSync9, renameSync as renameSync2, rmSync as rmSync14 } from "node:fs";
|
|
11851
|
-
import { dirname as
|
|
11902
|
+
import { dirname as dirname10, join as join23, resolve as resolve9 } from "node:path";
|
|
11852
11903
|
import { setTimeout as delay2 } from "node:timers/promises";
|
|
11853
11904
|
import { execa as execa12 } from "execa";
|
|
11854
11905
|
import lockfile2 from "proper-lockfile";
|
|
@@ -11863,8 +11914,8 @@ var RepositoryCache = class {
|
|
|
11863
11914
|
retainResources;
|
|
11864
11915
|
pathFor(remoteUrl) {
|
|
11865
11916
|
const { key: key2 } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
|
|
11866
|
-
const path =
|
|
11867
|
-
if (!isInside(
|
|
11917
|
+
const path = resolve9(this.root, "v2", createHash4("sha256").update(key2).digest("hex"));
|
|
11918
|
+
if (!isInside(resolve9(this.root), path) || path === resolve9(this.root)) throw new Error("Invalid repository cache path");
|
|
11868
11919
|
return path;
|
|
11869
11920
|
}
|
|
11870
11921
|
/** Serialize clone/fetch against the same cache, including other processes. */
|
|
@@ -11872,7 +11923,7 @@ var RepositoryCache = class {
|
|
|
11872
11923
|
signal?.throwIfAborted();
|
|
11873
11924
|
const { remoteUrl: remote } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
|
|
11874
11925
|
const path = this.pathFor(remote);
|
|
11875
|
-
this.ensureParents(
|
|
11926
|
+
this.ensureParents(dirname10(path));
|
|
11876
11927
|
const release = await this.lock(path, signal);
|
|
11877
11928
|
try {
|
|
11878
11929
|
signal?.throwIfAborted();
|
|
@@ -11916,28 +11967,28 @@ var RepositoryCache = class {
|
|
|
11916
11967
|
paths() {
|
|
11917
11968
|
const visit = (path) => {
|
|
11918
11969
|
if (!existsSync4(path) || lstatSync7(path).isSymbolicLink()) return [];
|
|
11919
|
-
if (existsSync4(
|
|
11970
|
+
if (existsSync4(join23(path, ".git"))) {
|
|
11920
11971
|
this.assertClone(path);
|
|
11921
11972
|
return [path];
|
|
11922
11973
|
}
|
|
11923
|
-
return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(
|
|
11974
|
+
return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(join23(path, entry.name)) : []);
|
|
11924
11975
|
};
|
|
11925
|
-
return visit(
|
|
11976
|
+
return visit(resolve9(this.root));
|
|
11926
11977
|
}
|
|
11927
11978
|
ensureParents(path) {
|
|
11928
11979
|
mkdirSync13(this.root, { recursive: true, mode: 448 });
|
|
11929
11980
|
if (lstatSync7(this.root).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
|
|
11930
11981
|
const root = realpathSync9(this.root);
|
|
11931
|
-
let current =
|
|
11982
|
+
let current = resolve9(this.root);
|
|
11932
11983
|
for (const part of path.slice(current.length + 1).split("/").filter(Boolean)) {
|
|
11933
|
-
current =
|
|
11984
|
+
current = join23(current, part);
|
|
11934
11985
|
if (existsSync4(current) && lstatSync7(current).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
|
|
11935
11986
|
mkdirSync13(current, { recursive: true, mode: 448 });
|
|
11936
11987
|
if (!isInside(root, realpathSync9(current))) throw new Error("Repository cache escapes its directory");
|
|
11937
11988
|
}
|
|
11938
11989
|
}
|
|
11939
11990
|
assertClone(path) {
|
|
11940
|
-
if (lstatSync7(path).isSymbolicLink() || !lstatSync7(
|
|
11991
|
+
if (lstatSync7(path).isSymbolicLink() || !lstatSync7(join23(path, ".git")).isDirectory() || lstatSync7(join23(path, ".git")).isSymbolicLink()) throw new Error("Repository cache is not a standard clone");
|
|
11941
11992
|
if (!isInside(realpathSync9(this.root), realpathSync9(path))) throw new Error("Repository cache escapes its directory");
|
|
11942
11993
|
}
|
|
11943
11994
|
async lock(path, signal) {
|
|
@@ -11967,17 +12018,17 @@ import {
|
|
|
11967
12018
|
rmSync as rmSync15
|
|
11968
12019
|
} from "node:fs";
|
|
11969
12020
|
import { createRequire } from "node:module";
|
|
11970
|
-
import { delimiter, dirname as
|
|
12021
|
+
import { delimiter, dirname as dirname11, join as join25 } from "node:path";
|
|
11971
12022
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
11972
12023
|
import { promisify as promisify4 } from "node:util";
|
|
11973
12024
|
|
|
11974
12025
|
// src/agents/public-egress.ts
|
|
11975
12026
|
import { lookup } from "node:dns/promises";
|
|
11976
|
-
import { chmod, mkdtemp, rm } from "node:fs/promises";
|
|
12027
|
+
import { chmod, mkdtemp, rm as rm2 } from "node:fs/promises";
|
|
11977
12028
|
import { createServer as createServer3, request as httpRequest } from "node:http";
|
|
11978
12029
|
import { connect, isIP as isIP3 } from "node:net";
|
|
11979
12030
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
11980
|
-
import { join as
|
|
12031
|
+
import { join as join24 } from "node:path";
|
|
11981
12032
|
|
|
11982
12033
|
// ../../lib/search/url-policy.ts
|
|
11983
12034
|
import { BlockList, isIP as isIP2 } from "node:net";
|
|
@@ -12046,9 +12097,9 @@ function endToEndHeaders(input) {
|
|
|
12046
12097
|
}
|
|
12047
12098
|
async function startPublicEgress(options) {
|
|
12048
12099
|
options.signal.throwIfAborted();
|
|
12049
|
-
const directory = await mkdtemp(
|
|
12100
|
+
const directory = await mkdtemp(join24(tmpdir3(), "mikka-egress-"));
|
|
12050
12101
|
await chmod(directory, 448);
|
|
12051
|
-
const socketPath =
|
|
12102
|
+
const socketPath = join24(directory, "egress.sock");
|
|
12052
12103
|
const lifetime = new AbortController();
|
|
12053
12104
|
const signal = AbortSignal.any([options.signal, lifetime.signal]);
|
|
12054
12105
|
const sockets = /* @__PURE__ */ new Set();
|
|
@@ -12153,9 +12204,9 @@ async function startPublicEgress(options) {
|
|
|
12153
12204
|
if (closing) return closing;
|
|
12154
12205
|
lifetime.abort();
|
|
12155
12206
|
for (const socket of sockets) socket.destroy();
|
|
12156
|
-
closing = new Promise((
|
|
12207
|
+
closing = new Promise((resolve10, reject) => server.close((error) => {
|
|
12157
12208
|
options.signal.removeEventListener("abort", onAbort);
|
|
12158
|
-
void
|
|
12209
|
+
void rm2(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve10(), reject);
|
|
12159
12210
|
}));
|
|
12160
12211
|
return closing;
|
|
12161
12212
|
};
|
|
@@ -12164,11 +12215,11 @@ async function startPublicEgress(options) {
|
|
|
12164
12215
|
};
|
|
12165
12216
|
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
12166
12217
|
try {
|
|
12167
|
-
await new Promise((
|
|
12218
|
+
await new Promise((resolve10, reject) => {
|
|
12168
12219
|
server.once("error", reject);
|
|
12169
12220
|
server.listen(socketPath, () => {
|
|
12170
12221
|
server.removeListener("error", reject);
|
|
12171
|
-
|
|
12222
|
+
resolve10();
|
|
12172
12223
|
});
|
|
12173
12224
|
});
|
|
12174
12225
|
await chmod(socketPath, 384);
|
|
@@ -12205,7 +12256,7 @@ async function createHostedBotRunner(host) {
|
|
|
12205
12256
|
}).catch(() => {
|
|
12206
12257
|
throw unavailable2();
|
|
12207
12258
|
});
|
|
12208
|
-
const resources =
|
|
12259
|
+
const resources = join25(host.stateDir, "native-resources");
|
|
12209
12260
|
mkdirSync14(resources, { recursive: true, mode: 448 });
|
|
12210
12261
|
const removeResource = async (file, record) => {
|
|
12211
12262
|
if (!/^mikka-native-(?:verify-)?[a-f0-9-]{36}$/.test(record.name) || !/^[a-f0-9-]{36}$/.test(record.nonce))
|
|
@@ -12226,7 +12277,7 @@ async function createHostedBotRunner(host) {
|
|
|
12226
12277
|
if (record.state === "created" && /No such (?:container|object)/i.test(
|
|
12227
12278
|
String(error.stderr)
|
|
12228
12279
|
)) {
|
|
12229
|
-
if (record.assets?.startsWith(
|
|
12280
|
+
if (record.assets?.startsWith(join25(host.stateDir, "native-verify-git-")))
|
|
12230
12281
|
rmSync15(record.assets, { recursive: true, force: true });
|
|
12231
12282
|
rmSync15(file, { force: true });
|
|
12232
12283
|
return;
|
|
@@ -12237,13 +12288,13 @@ async function createHostedBotRunner(host) {
|
|
|
12237
12288
|
if (labels?.["com.mikka.native.resource"] !== record.nonce || record.id && record.id !== id3)
|
|
12238
12289
|
throw unavailable2();
|
|
12239
12290
|
await exec2("docker", ["rm", "-f", id3], { env: bareEnv, timeout: 3e4 });
|
|
12240
|
-
if (record.assets?.startsWith(
|
|
12291
|
+
if (record.assets?.startsWith(join25(host.stateDir, "native-verify-git-")))
|
|
12241
12292
|
rmSync15(record.assets, { recursive: true, force: true });
|
|
12242
12293
|
rmSync15(file, { force: true });
|
|
12243
12294
|
};
|
|
12244
12295
|
for (const name of readdirSync6(resources))
|
|
12245
12296
|
if (name.endsWith(".json")) {
|
|
12246
|
-
const file =
|
|
12297
|
+
const file = join25(resources, name);
|
|
12247
12298
|
const record = readJson(file);
|
|
12248
12299
|
if (!record) throw unavailable2();
|
|
12249
12300
|
await removeResource(file, record);
|
|
@@ -12254,8 +12305,8 @@ async function createHostedBotRunner(host) {
|
|
|
12254
12305
|
const bundled = createRequire(
|
|
12255
12306
|
require2.resolve("@anthropic-ai/claude-agent-sdk")
|
|
12256
12307
|
);
|
|
12257
|
-
claude ??=
|
|
12258
|
-
|
|
12308
|
+
claude ??= join25(
|
|
12309
|
+
dirname11(
|
|
12259
12310
|
bundled.resolve(
|
|
12260
12311
|
"@anthropic-ai/claude-agent-sdk-linux-x64/package.json"
|
|
12261
12312
|
)
|
|
@@ -12264,7 +12315,7 @@ async function createHostedBotRunner(host) {
|
|
|
12264
12315
|
);
|
|
12265
12316
|
} catch {
|
|
12266
12317
|
}
|
|
12267
|
-
const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter).map((dir) =>
|
|
12318
|
+
const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter).map((dir) => join25(dir, "codex")).find((path) => existsSync5(path));
|
|
12268
12319
|
const binaries = { codex, claude_code: claude };
|
|
12269
12320
|
for (const kind of ["codex", "claude_code"])
|
|
12270
12321
|
if (binaries[kind]) {
|
|
@@ -12278,12 +12329,12 @@ async function createHostedBotRunner(host) {
|
|
|
12278
12329
|
if (!binaries.codex && !binaries.claude_code) throw unavailable2();
|
|
12279
12330
|
const command = async (worktree, script, readOnly, timeoutMs, signal) => {
|
|
12280
12331
|
const name = `mikka-native-verify-${randomUUID7()}`;
|
|
12281
|
-
const file =
|
|
12332
|
+
const file = join25(resources, name + ".json");
|
|
12282
12333
|
const resource = { name, nonce: randomUUID7(), state: "creating" };
|
|
12283
12334
|
const timing = { createMs: 0, runMs: 0 };
|
|
12284
12335
|
let phase = "create";
|
|
12285
12336
|
let began = performance.now();
|
|
12286
|
-
const gitCopy = mkdtempSync6(
|
|
12337
|
+
const gitCopy = mkdtempSync6(join25(host.stateDir, "native-verify-git-"));
|
|
12287
12338
|
resource.assets = gitCopy;
|
|
12288
12339
|
try {
|
|
12289
12340
|
const cwd = realpathSync10(worktree);
|
|
@@ -12299,7 +12350,7 @@ async function createHostedBotRunner(host) {
|
|
|
12299
12350
|
"--no-checkout",
|
|
12300
12351
|
"--",
|
|
12301
12352
|
cwd,
|
|
12302
|
-
|
|
12353
|
+
join25(gitCopy, "repo")
|
|
12303
12354
|
],
|
|
12304
12355
|
{
|
|
12305
12356
|
env: {
|
|
@@ -12314,8 +12365,8 @@ async function createHostedBotRunner(host) {
|
|
|
12314
12365
|
maxBuffer: 1024 * 1024
|
|
12315
12366
|
}
|
|
12316
12367
|
);
|
|
12317
|
-
const safeGit =
|
|
12318
|
-
const protectedGit = lstatSync8(
|
|
12368
|
+
const safeGit = join25(gitCopy, "repo", ".git");
|
|
12369
|
+
const protectedGit = lstatSync8(join25(cwd, ".git")).isFile() ? join25(cwd, ".git") : safeGit;
|
|
12319
12370
|
writeJsonAtomic(file, resource);
|
|
12320
12371
|
const created = await exec2(
|
|
12321
12372
|
"docker",
|
|
@@ -12419,7 +12470,7 @@ async function createHostedBotRunner(host) {
|
|
|
12419
12470
|
throw unavailable2();
|
|
12420
12471
|
const name = `mikka-native-${randomUUID7()}`;
|
|
12421
12472
|
const nonce = randomUUID7();
|
|
12422
|
-
const resourceFile =
|
|
12473
|
+
const resourceFile = join25(resources, name + ".json");
|
|
12423
12474
|
const resource = { name, nonce, state: "creating" };
|
|
12424
12475
|
const lifetime = new AbortController();
|
|
12425
12476
|
let closed = false;
|
|
@@ -12492,8 +12543,8 @@ async function createHostedBotRunner(host) {
|
|
|
12492
12543
|
};
|
|
12493
12544
|
const paths = runPaths(host.stateDir, assignment.runId);
|
|
12494
12545
|
mkdirSync14(paths.runDir, { recursive: true, mode: 448 });
|
|
12495
|
-
const shadow =
|
|
12496
|
-
const emptyHome =
|
|
12546
|
+
const shadow = join25(paths.runDir, "runtime-git");
|
|
12547
|
+
const emptyHome = join25(paths.runDir, "git-bootstrap-home");
|
|
12497
12548
|
mkdirSync14(emptyHome, { recursive: true, mode: 448 });
|
|
12498
12549
|
if (!existsSync5(shadow))
|
|
12499
12550
|
await exec2(
|
|
@@ -12524,9 +12575,9 @@ async function createHostedBotRunner(host) {
|
|
|
12524
12575
|
}
|
|
12525
12576
|
);
|
|
12526
12577
|
await live();
|
|
12527
|
-
if (!lstatSync8(shadow).isDirectory() || !lstatSync8(
|
|
12578
|
+
if (!lstatSync8(shadow).isDirectory() || !lstatSync8(join25(shadow, ".git")).isDirectory() || !realpathSync10(shadow).startsWith(realpathSync10(paths.runDir) + "/"))
|
|
12528
12579
|
throw unavailable2();
|
|
12529
|
-
const ledger =
|
|
12580
|
+
const ledger = join25(
|
|
12530
12581
|
host.stateDir,
|
|
12531
12582
|
"native-ledgers",
|
|
12532
12583
|
assignment.runId + ".json"
|
|
@@ -12545,13 +12596,13 @@ async function createHostedBotRunner(host) {
|
|
|
12545
12596
|
const previous = readJson(ledger);
|
|
12546
12597
|
if (existsSync5(ledger) && (!previous || JSON.stringify(previous.scope) !== JSON.stringify(scope) || typeof previous.sessionId !== "string"))
|
|
12547
12598
|
throw unavailable2();
|
|
12548
|
-
mkdirSync14(
|
|
12599
|
+
mkdirSync14(dirname11(ledger), { recursive: true, mode: 448 });
|
|
12549
12600
|
const record = async (sessionId) => {
|
|
12550
12601
|
assertOpen();
|
|
12551
12602
|
writeJsonAtomic(ledger, { scope, sessionId });
|
|
12552
12603
|
};
|
|
12553
12604
|
brokerStarting = createNativeSubscriptionBroker({
|
|
12554
|
-
root:
|
|
12605
|
+
root: join25(host.stateDir, "native-brokers"),
|
|
12555
12606
|
revision,
|
|
12556
12607
|
check,
|
|
12557
12608
|
worker: {
|
|
@@ -12592,7 +12643,7 @@ async function createHostedBotRunner(host) {
|
|
|
12592
12643
|
}
|
|
12593
12644
|
const cwd = realpathSync10(options.cwd);
|
|
12594
12645
|
const runDir = realpathSync10(paths.runDir);
|
|
12595
|
-
const protectedGit = lstatSync8(
|
|
12646
|
+
const protectedGit = lstatSync8(join25(cwd, ".git")).isFile() ? join25(cwd, ".git") : join25(shadow, ".git");
|
|
12596
12647
|
if (!lstatSync8(runDir).isDirectory() || !runDir.startsWith(realpathSync10(host.stateDir) + "/runs/")) {
|
|
12597
12648
|
await close();
|
|
12598
12649
|
throw unavailable2();
|
|
@@ -12645,7 +12696,7 @@ async function createHostedBotRunner(host) {
|
|
|
12645
12696
|
"-v",
|
|
12646
12697
|
`${MCP_SERVER_SCRIPT}:${MCP_SERVER_SCRIPT}:ro`,
|
|
12647
12698
|
"-v",
|
|
12648
|
-
`${
|
|
12699
|
+
`${join25(dirname11(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:${join25(dirname11(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:ro`,
|
|
12649
12700
|
"-v",
|
|
12650
12701
|
`${readyBroker.socket}:/run/mikka-native.sock:ro`,
|
|
12651
12702
|
...computerGrant ? [
|
|
@@ -12688,13 +12739,13 @@ async function createHostedBotRunner(host) {
|
|
|
12688
12739
|
}
|
|
12689
12740
|
const spawnHosted = (config) => {
|
|
12690
12741
|
assertOpen();
|
|
12691
|
-
const home =
|
|
12742
|
+
const home = join25(runDir, "runtime-home");
|
|
12692
12743
|
mkdirSync14(home, { recursive: true, mode: 448 });
|
|
12693
12744
|
const env = {
|
|
12694
12745
|
...config.env,
|
|
12695
12746
|
HOME: kind === "claude_code" ? config.env.HOME ?? home : home,
|
|
12696
12747
|
PATH: "/usr/local/bin:/usr/bin:/bin",
|
|
12697
|
-
GIT_DIR:
|
|
12748
|
+
GIT_DIR: join25(shadow, ".git"),
|
|
12698
12749
|
GIT_WORK_TREE: cwd,
|
|
12699
12750
|
GIT_CONFIG_GLOBAL: "/dev/null",
|
|
12700
12751
|
GIT_CONFIG_SYSTEM: "/dev/null",
|
|
@@ -12727,9 +12778,9 @@ async function createHostedBotRunner(host) {
|
|
|
12727
12778
|
signal: new AbortController().signal
|
|
12728
12779
|
});
|
|
12729
12780
|
child.stderr?.resume();
|
|
12730
|
-
const exited = new Promise((
|
|
12731
|
-
child.once("exit", (code, signal) =>
|
|
12732
|
-
child.once("error", () =>
|
|
12781
|
+
const exited = new Promise((resolve10) => {
|
|
12782
|
+
child.once("exit", (code, signal) => resolve10({ code, signal }));
|
|
12783
|
+
child.once("error", () => resolve10({ code: null, signal: null }));
|
|
12733
12784
|
});
|
|
12734
12785
|
return {
|
|
12735
12786
|
process: child,
|
|
@@ -12988,9 +13039,9 @@ async function executeDriver(driver, input, display, leaseGuard, assertLive = ()
|
|
|
12988
13039
|
)
|
|
12989
13040
|
)
|
|
12990
13041
|
);
|
|
12991
|
-
const request = (method, params) => new Promise((
|
|
13042
|
+
const request = (method, params) => new Promise((resolve10, reject) => {
|
|
12992
13043
|
const n = ++id3;
|
|
12993
|
-
pending.set(n, { resolve:
|
|
13044
|
+
pending.set(n, { resolve: resolve10, reject });
|
|
12994
13045
|
child.stdin.write(
|
|
12995
13046
|
JSON.stringify({ jsonrpc: "2.0", id: n, method, params }) + "\n"
|
|
12996
13047
|
);
|
|
@@ -13091,10 +13142,10 @@ var ComputerBroker = class {
|
|
|
13091
13142
|
})();
|
|
13092
13143
|
});
|
|
13093
13144
|
});
|
|
13094
|
-
await new Promise((
|
|
13145
|
+
await new Promise((resolve10, reject) => {
|
|
13095
13146
|
this.server.once("error", reject);
|
|
13096
|
-
if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 },
|
|
13097
|
-
else this.server.listen(this.socketPath,
|
|
13147
|
+
if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 }, resolve10);
|
|
13148
|
+
else this.server.listen(this.socketPath, resolve10);
|
|
13098
13149
|
});
|
|
13099
13150
|
if (this.transport === "tcp") this.socketPath = `tcp://127.0.0.1:${this.server.address().port}`;
|
|
13100
13151
|
else chmodSync3(this.socketPath, 384);
|
|
@@ -13125,7 +13176,7 @@ var ComputerBroker = class {
|
|
|
13125
13176
|
expiresAt: this.now() + this.ttl
|
|
13126
13177
|
};
|
|
13127
13178
|
const digest = createHash6("sha256").update(JSON.stringify(request)).digest("hex");
|
|
13128
|
-
return new Promise((
|
|
13179
|
+
return new Promise((resolve10, reject) => {
|
|
13129
13180
|
const timer = setTimeout(() => {
|
|
13130
13181
|
this.pending.delete(request.id);
|
|
13131
13182
|
signal?.removeEventListener("abort", cancel);
|
|
@@ -13142,7 +13193,7 @@ var ComputerBroker = class {
|
|
|
13142
13193
|
assertLive,
|
|
13143
13194
|
cleanup: () => signal?.removeEventListener("abort", cancel),
|
|
13144
13195
|
request: { ...request, digest },
|
|
13145
|
-
resolve:
|
|
13196
|
+
resolve: resolve10,
|
|
13146
13197
|
reject,
|
|
13147
13198
|
timer
|
|
13148
13199
|
});
|
|
@@ -13219,7 +13270,7 @@ var ComputerBroker = class {
|
|
|
13219
13270
|
async close() {
|
|
13220
13271
|
this.suspend();
|
|
13221
13272
|
for (const socket of this.sockets) socket.destroy();
|
|
13222
|
-
if (this.server?.listening) await new Promise((
|
|
13273
|
+
if (this.server?.listening) await new Promise((resolve10) => this.server.close(resolve10));
|
|
13223
13274
|
}
|
|
13224
13275
|
};
|
|
13225
13276
|
|
|
@@ -13288,11 +13339,11 @@ async function pollWebComputerReviews(broker, deviceId, link, signal, intervalMs
|
|
|
13288
13339
|
} catch {
|
|
13289
13340
|
}
|
|
13290
13341
|
if (signal.aborted) break;
|
|
13291
|
-
await new Promise((
|
|
13342
|
+
await new Promise((resolve10) => {
|
|
13292
13343
|
const done = () => {
|
|
13293
13344
|
clearTimeout(timer);
|
|
13294
13345
|
signal.removeEventListener("abort", done);
|
|
13295
|
-
|
|
13346
|
+
resolve10();
|
|
13296
13347
|
};
|
|
13297
13348
|
const timer = setTimeout(done, intervalMs);
|
|
13298
13349
|
signal.addEventListener("abort", done, { once: true });
|
|
@@ -13401,7 +13452,7 @@ var Daemon = class {
|
|
|
13401
13452
|
if (this.options.credential)
|
|
13402
13453
|
this.saveDevice({ credential: this.options.credential });
|
|
13403
13454
|
this.journal = new RunJournal(paths.journal);
|
|
13404
|
-
this.captureUploader = new CaptureUploader((runId) =>
|
|
13455
|
+
this.captureUploader = new CaptureUploader((runId) => join26(runPaths(paths.adapterState, runId).runDir, CAPTURES_DIR), this.options.link, this.log, join26(paths.dataDir, "capture-pending"));
|
|
13405
13456
|
this.outbox = new Outbox(
|
|
13406
13457
|
paths.outbox,
|
|
13407
13458
|
this.options.link,
|
|
@@ -13418,7 +13469,7 @@ var Daemon = class {
|
|
|
13418
13469
|
if (this.localComputerDriver && this.options.link.syncComputerReviews && this.options.link.localComputerAuthority) {
|
|
13419
13470
|
this.localComputerBroker = new ComputerBroker({
|
|
13420
13471
|
driver: this.localComputerDriver,
|
|
13421
|
-
socketPath:
|
|
13472
|
+
socketPath: join26(paths.dataDir, "local-computer.sock"),
|
|
13422
13473
|
transport: "tcp",
|
|
13423
13474
|
permitted: (runId) => {
|
|
13424
13475
|
const assignment = this.journal.get(runId)?.assignment;
|
|
@@ -13460,7 +13511,7 @@ var Daemon = class {
|
|
|
13460
13511
|
};
|
|
13461
13512
|
this.cloudComputerBroker = new ComputerBroker({
|
|
13462
13513
|
driver,
|
|
13463
|
-
socketPath:
|
|
13514
|
+
socketPath: join26(paths.dataDir, "computer.sock"),
|
|
13464
13515
|
permitted: (runId) => {
|
|
13465
13516
|
const entry = this.journal.get(runId);
|
|
13466
13517
|
return Boolean(!this.stopped && this.registered && entry?.assignment.computer && this.supervisor?.computerRunAllowed(runId));
|
|
@@ -13729,12 +13780,12 @@ var Daemon = class {
|
|
|
13729
13780
|
}
|
|
13730
13781
|
/** Waits `ms`, or less if the daemon stops or the device registers. */
|
|
13731
13782
|
pauseCommands(ms, signal) {
|
|
13732
|
-
return new Promise((
|
|
13783
|
+
return new Promise((resolve10) => {
|
|
13733
13784
|
const done = () => {
|
|
13734
13785
|
clearTimeout(timer);
|
|
13735
13786
|
signal.removeEventListener("abort", done);
|
|
13736
13787
|
this.wakeCommands = null;
|
|
13737
|
-
|
|
13788
|
+
resolve10();
|
|
13738
13789
|
};
|
|
13739
13790
|
const timer = setTimeout(done, ms);
|
|
13740
13791
|
signal.addEventListener("abort", done, { once: true });
|
|
@@ -13835,11 +13886,11 @@ var Daemon = class {
|
|
|
13835
13886
|
return runVerify(sandbox, {
|
|
13836
13887
|
command,
|
|
13837
13888
|
worktree: realpathSync11(worktree),
|
|
13838
|
-
tmpRoot:
|
|
13889
|
+
tmpRoot: join26(this.paths.adapterState, "verify", runId),
|
|
13839
13890
|
privateDir: paths.privateDir,
|
|
13840
13891
|
pidFile: paths.pidFile.replace(/\.pgid$/, ".verify.pgid"),
|
|
13841
13892
|
networkAllow: repo.networkAllow,
|
|
13842
|
-
env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE:
|
|
13893
|
+
env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE: join26(paths.runDir, "handoff.json") },
|
|
13843
13894
|
timeoutMs,
|
|
13844
13895
|
signal,
|
|
13845
13896
|
readOnly
|
|
@@ -13961,7 +14012,7 @@ var Daemon = class {
|
|
|
13961
14012
|
}
|
|
13962
14013
|
const deviceId = this.device.deviceId;
|
|
13963
14014
|
const quotas = this.quota?.snapshot().quotas;
|
|
13964
|
-
const
|
|
14015
|
+
const heartbeat = {
|
|
13965
14016
|
completedDeviceCommands: this.device.completedDeviceCommands,
|
|
13966
14017
|
failedDeviceCommands: this.device.failedDeviceCommands,
|
|
13967
14018
|
harnesses: this.harnesses,
|
|
@@ -13969,7 +14020,8 @@ var Daemon = class {
|
|
|
13969
14020
|
runs: this.supervisor.heartbeatRuns(),
|
|
13970
14021
|
worktreeDiskBytes: await this.worktrees.diskUsage(),
|
|
13971
14022
|
...quotas ? { quotas } : {}
|
|
13972
|
-
}
|
|
14023
|
+
};
|
|
14024
|
+
const { leases, revoked, cloudCredential, deviceCommands } = await link.heartbeat(deviceId, heartbeat);
|
|
13973
14025
|
this.supervisor.renewLeases(leases);
|
|
13974
14026
|
if (revoked) this.supervisor.revokeLeases(revoked);
|
|
13975
14027
|
if (this.options.cloudComputer && cloudCredential && this.device.credential === credential) {
|
|
@@ -13978,6 +14030,26 @@ var Daemon = class {
|
|
|
13978
14030
|
this.registered = false;
|
|
13979
14031
|
}
|
|
13980
14032
|
const command = deviceCommands?.[0];
|
|
14033
|
+
if (command?.kind === "uninstall") {
|
|
14034
|
+
this.draining = true;
|
|
14035
|
+
if (this.supervisor.heartbeatRuns().length === 0) {
|
|
14036
|
+
this.saveDevice({ completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14037
|
+
try {
|
|
14038
|
+
await link.heartbeat(deviceId, { ...heartbeat, runs: [], completedDeviceCommands: [command.id], failedDeviceCommands: [] });
|
|
14039
|
+
} catch {
|
|
14040
|
+
this.log.warn("Could not confirm uninstall receipt");
|
|
14041
|
+
}
|
|
14042
|
+
setImmediate(() => {
|
|
14043
|
+
void this.stop().then(() => uninstallService(() => {
|
|
14044
|
+
this.saveDevice({ credential: void 0 });
|
|
14045
|
+
rmSync16(this.paths.secret, { force: true });
|
|
14046
|
+
})).catch(() => {
|
|
14047
|
+
this.options.onDrained?.();
|
|
14048
|
+
});
|
|
14049
|
+
});
|
|
14050
|
+
}
|
|
14051
|
+
return;
|
|
14052
|
+
}
|
|
13981
14053
|
if (command && !this.device.completedDeviceCommands?.includes(command.id) && !this.device.failedDeviceCommands?.some((failure) => failure.id === command.id)) {
|
|
13982
14054
|
if (command.kind === "redetect" || this.supervisor.heartbeatRuns().length === 0) {
|
|
13983
14055
|
try {
|
|
@@ -14273,7 +14345,7 @@ var Daemon = class {
|
|
|
14273
14345
|
if (!job || controller.signal.aborted) return;
|
|
14274
14346
|
await runNativeCoordinatorJob(job, {
|
|
14275
14347
|
deviceId,
|
|
14276
|
-
stateDir:
|
|
14348
|
+
stateDir: join26(this.paths.dataDir, "coordinator"),
|
|
14277
14349
|
link,
|
|
14278
14350
|
signal: controller.signal,
|
|
14279
14351
|
sandbox,
|