@aspectlylabs/mikka 0.0.1 → 0.0.3

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/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((resolve9) => {
2212
- this.waiter = resolve9;
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
- (resolve9) => {
2283
+ (resolve10) => {
2284
2284
  child.once("error", (error) => {
2285
2285
  stderr += `
2286
2286
  ${error.message}`;
2287
- resolve9({ code: null, signal: null });
2287
+ resolve10({ code: null, signal: null });
2288
2288
  });
2289
- child.once("exit", (code, signal) => resolve9({ 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((resolve9) => {
2307
- timer = setTimeout(resolve9, graceMs);
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, label, ms = 12e4) {
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(`${label}: the CLI exited (${signal ?? code})`);
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(`${label}: no answer after ${ms / 1e3} s`)),
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((resolve9, reject) => {
2388
+ return new Promise((resolve10, reject) => {
2389
2389
  this.stream.write(
2390
2390
  `${JSON.stringify(message)}
2391
2391
  `,
2392
- (error) => error ? reject(error) : resolve9()
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.1",
2829
+ version: "0.0.3",
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: "4d1f09bda63e1b86a6cf08c4c7f4dc159b2938a2"
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((resolve9, reject) => {
5422
- resolveEnd = resolve9;
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 join25 } from "node:path";
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((resolve9) => {
5732
- settle = resolve9;
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((resolve9, reject) => {
6013
+ await new Promise((resolve10, reject) => {
6006
6014
  server.once("error", reject);
6007
- server.listen(socket, resolve9);
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((resolve9) => server.close(() => resolve9()));
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((resolve9) => {
6185
- this.waiter = resolve9;
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((resolve9) => {
6200
- timer = setTimeout(() => resolve9(true), CONTINUE_SILENCE_MS);
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((resolve9) => spoke = resolve9);
6341
+ const spoken = new Promise((resolve10) => spoke = resolve10);
6334
6342
  let finished = () => void 0;
6335
- const gone = new Promise((resolve9) => finished = resolve9);
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, label) => untilReady(child, step, `codex ${label}`);
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, label) => untilReady(child, step, `cursor ${label}`);
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
- (resolve9) => abort.signal.addEventListener("abort", resolve9, { once: true })
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 join16 } from "node:path";
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 join16(dataDir, "daemon.pid");
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((resolve9) => {
8842
+ return new Promise((resolve10) => {
8803
8843
  const socket = createConnection(socketPath);
8804
8844
  const done = (alive) => {
8805
8845
  socket.destroy();
8806
- resolve9(alive);
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((resolve9) => file.end(resolve9));
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 join17 } from "node:path";
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 join17(this.dir, `${assertSafeId("run id", runId)}.jsonl`);
8990
+ return join18(this.dir, `${assertSafeId("run id", runId)}.jsonl`);
8951
8991
  }
8952
8992
  ackFile(runId) {
8953
- return join17(this.dir, `${assertSafeId("run id", runId)}.ack.json`);
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 homedir6 } from "node:os";
9138
- import { join as join19 } from "node:path";
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 label = "Subscription";
9364
+ let label2 = "Subscription";
9325
9365
  if (subscriptionType === "team" || subscriptionType === "" && tier.includes("team")) {
9326
- label = hasMax ? "Team Premium" : "Team";
9366
+ label2 = hasMax ? "Team Premium" : "Team";
9327
9367
  } else if (subscriptionType === "enterprise" || subscriptionType === "" && tier.includes("enterprise")) {
9328
- label = hasMax ? "Enterprise Premium" : "Enterprise";
9368
+ label2 = hasMax ? "Enterprise Premium" : "Enterprise";
9329
9369
  } else if (subscriptionType === "max" || hasMax) {
9330
- label = hasMax20 ? "Max 20x" : "Max 5x";
9370
+ label2 = hasMax20 ? "Max 20x" : "Max 5x";
9331
9371
  } else if (subscriptionType === "pro" || tier.includes("pro")) {
9332
- label = "Pro";
9372
+ label2 = "Pro";
9333
9373
  }
9334
- return cleanText(label);
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 join18 } from "node:path";
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 join18(
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 join18(
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 join18(home, ".config", "Cursor", "User", "globalStorage", "state.vscdb");
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 join19(home, ".claude", ".credentials.json");
9874
+ return join20(home, ".claude", ".credentials.json");
9835
9875
  }
9836
9876
  function codexAuthPath(home) {
9837
- return join19(home, ".codex", "auth.json");
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 ?? homedir6();
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((resolve9, reject) => {
10072
+ await new Promise((resolve10, reject) => {
10033
10073
  server.once("error", reject);
10034
- server.listen(socketPath, () => resolve9());
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((resolve9) => {
10099
- if (!this.server) return resolve9();
10100
- this.server.close(() => resolve9());
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, label] of needles) if (out.includes(needle)) out = out.split(needle).join(label);
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 join21, resolve as resolve7 } from "node:path";
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 join20 } from "node:path";
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(join20(tmpdir2(), "mikka-checkpoint-"));
10367
- const file = join20(dir, "checkpoint.patch");
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((resolve9) => {
10617
- const timer = setTimeout(resolve9, waitSeconds * 1e3);
10618
- signal?.addEventListener("abort", () => resolve9(), { once: true });
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
- resolve9();
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((resolve9) => {
11069
+ const grace = new Promise((resolve10) => {
11030
11070
  timer = setTimeout(
11031
- resolve9,
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((resolve9) => {
11224
- timer = setTimeout(resolve9, 6e4);
11263
+ new Promise((resolve10) => {
11264
+ timer = setTimeout(resolve10, 6e4);
11225
11265
  })
11226
11266
  ]).finally(() => clearTimeout(timer));
11227
11267
  }
@@ -11531,7 +11571,7 @@ var RunSupervisor = class {
11531
11571
  mailbox
11532
11572
  };
11533
11573
  const resuming = entry.sessionId !== null && adapter.capabilities.supportsResume;
11534
- const inEarlierWorktree = continued !== null || entry.worktree !== null && resolve7(entry.worktree) !== resolve7(this.deps.worktrees.pathFor(runId));
11574
+ const inEarlierWorktree = continued !== null || entry.worktree !== null && resolve8(entry.worktree) !== resolve8(this.deps.worktrees.pathFor(runId));
11535
11575
  const continueSession = !resuming && assignment.resumeSessionId && assignment.continuesRunId && inEarlierWorktree && adapter.capabilities.supportsResume ? {
11536
11576
  sessionId: assignment.resumeSessionId,
11537
11577
  runId: assignment.continuesRunId,
@@ -11578,7 +11618,7 @@ var RunSupervisor = class {
11578
11618
  if (!this.deps.adapterStateDir || assignment.harness === "mock" || !session.sessionId || resuming && session.sessionId !== entry.sessionId || assignment.requireSessionResume && session.sessionId !== assignment.resumeSessionId)
11579
11619
  throw new Error("Skill mount requires the actual original harness session");
11580
11620
  verifySkillAssignment(assignment);
11581
- const file = join21(
11621
+ const file = join22(
11582
11622
  runPaths(this.deps.adapterStateDir, runId).runDir,
11583
11623
  SKILLS_DIR,
11584
11624
  skillSlug(assignment.skills[0].name),
@@ -11756,10 +11796,10 @@ function trackParts(open2, chunk) {
11756
11796
  }
11757
11797
  var ABORTED = /* @__PURE__ */ Symbol("aborted");
11758
11798
  function abortPromise(signal) {
11759
- return new Promise((resolve9) => {
11760
- if (signal.aborted) resolve9(ABORTED);
11799
+ return new Promise((resolve10) => {
11800
+ if (signal.aborted) resolve10(ABORTED);
11761
11801
  else
11762
- signal.addEventListener("abort", () => resolve9(ABORTED), { once: true });
11802
+ signal.addEventListener("abort", () => resolve10(ABORTED), { once: true });
11763
11803
  });
11764
11804
  }
11765
11805
  function pickAgentReport(agent) {
@@ -11777,18 +11817,21 @@ function pickAgentReport(agent) {
11777
11817
  const question = runQuestion.safeParse(agent.question);
11778
11818
  if (question.success) picked.question = question.data;
11779
11819
  if (agent.plan) picked.plan = agent.plan;
11820
+ if (typeof agent.previewDatabaseBranch === "string" && agent.previewDatabaseBranch.trim())
11821
+ picked.previewDatabaseBranch = agent.previewDatabaseBranch.trim().slice(0, 500);
11780
11822
  if (Array.isArray(agent.criteria)) {
11781
11823
  const criteria = [];
11782
11824
  for (const entry of agent.criteria) {
11783
11825
  if (criteria.length >= MAX_REPORTED_CRITERIA) break;
11784
11826
  if (!entry || typeof entry !== "object") continue;
11785
- const { criterionId, passed, evidence } = entry;
11827
+ const { criterionId, passed, evidence, command, exitCode } = entry;
11786
11828
  if (typeof criterionId !== "string" || !UUID_RE.test(criterionId))
11787
11829
  continue;
11788
11830
  if (typeof passed !== "boolean") continue;
11789
11831
  criteria.push({
11790
11832
  criterionId,
11791
11833
  passed,
11834
+ ...typeof command === "string" && command.trim() ? { command: command.trim().slice(0, 2e3), ...exitCode === null || typeof exitCode === "number" && Number.isSafeInteger(exitCode) ? { exitCode } : {} } : {},
11792
11835
  ...typeof evidence === "string" ? { evidence: evidence.slice(0, 1e4) } : {}
11793
11836
  });
11794
11837
  }
@@ -11848,7 +11891,7 @@ var SessionRejectedError = class extends DaemonError {
11848
11891
  // src/repositories.ts
11849
11892
  import { createHash as createHash4, randomUUID as randomUUID6 } from "node:crypto";
11850
11893
  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 dirname9, join as join22, resolve as resolve8 } from "node:path";
11894
+ import { dirname as dirname10, join as join23, resolve as resolve9 } from "node:path";
11852
11895
  import { setTimeout as delay2 } from "node:timers/promises";
11853
11896
  import { execa as execa12 } from "execa";
11854
11897
  import lockfile2 from "proper-lockfile";
@@ -11863,8 +11906,8 @@ var RepositoryCache = class {
11863
11906
  retainResources;
11864
11907
  pathFor(remoteUrl) {
11865
11908
  const { key: key2 } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
11866
- const path = resolve8(this.root, "v2", createHash4("sha256").update(key2).digest("hex"));
11867
- if (!isInside(resolve8(this.root), path) || path === resolve8(this.root)) throw new Error("Invalid repository cache path");
11909
+ const path = resolve9(this.root, "v2", createHash4("sha256").update(key2).digest("hex"));
11910
+ if (!isInside(resolve9(this.root), path) || path === resolve9(this.root)) throw new Error("Invalid repository cache path");
11868
11911
  return path;
11869
11912
  }
11870
11913
  /** Serialize clone/fetch against the same cache, including other processes. */
@@ -11872,7 +11915,7 @@ var RepositoryCache = class {
11872
11915
  signal?.throwIfAborted();
11873
11916
  const { remoteUrl: remote } = normalizeRepository(remoteUrl, { allowFile: this.allowFile });
11874
11917
  const path = this.pathFor(remote);
11875
- this.ensureParents(dirname9(path));
11918
+ this.ensureParents(dirname10(path));
11876
11919
  const release = await this.lock(path, signal);
11877
11920
  try {
11878
11921
  signal?.throwIfAborted();
@@ -11916,28 +11959,28 @@ var RepositoryCache = class {
11916
11959
  paths() {
11917
11960
  const visit = (path) => {
11918
11961
  if (!existsSync4(path) || lstatSync7(path).isSymbolicLink()) return [];
11919
- if (existsSync4(join22(path, ".git"))) {
11962
+ if (existsSync4(join23(path, ".git"))) {
11920
11963
  this.assertClone(path);
11921
11964
  return [path];
11922
11965
  }
11923
- return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(join22(path, entry.name)) : []);
11966
+ return readdirSync5(path, { withFileTypes: true }).flatMap((entry) => entry.isDirectory() && !entry.name.endsWith(".lock") && !entry.name.includes(".clone-") ? visit(join23(path, entry.name)) : []);
11924
11967
  };
11925
- return visit(resolve8(this.root));
11968
+ return visit(resolve9(this.root));
11926
11969
  }
11927
11970
  ensureParents(path) {
11928
11971
  mkdirSync13(this.root, { recursive: true, mode: 448 });
11929
11972
  if (lstatSync7(this.root).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
11930
11973
  const root = realpathSync9(this.root);
11931
- let current = resolve8(this.root);
11974
+ let current = resolve9(this.root);
11932
11975
  for (const part of path.slice(current.length + 1).split("/").filter(Boolean)) {
11933
- current = join22(current, part);
11976
+ current = join23(current, part);
11934
11977
  if (existsSync4(current) && lstatSync7(current).isSymbolicLink()) throw new Error("Repository cache contains a symlink");
11935
11978
  mkdirSync13(current, { recursive: true, mode: 448 });
11936
11979
  if (!isInside(root, realpathSync9(current))) throw new Error("Repository cache escapes its directory");
11937
11980
  }
11938
11981
  }
11939
11982
  assertClone(path) {
11940
- if (lstatSync7(path).isSymbolicLink() || !lstatSync7(join22(path, ".git")).isDirectory() || lstatSync7(join22(path, ".git")).isSymbolicLink()) throw new Error("Repository cache is not a standard clone");
11983
+ 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
11984
  if (!isInside(realpathSync9(this.root), realpathSync9(path))) throw new Error("Repository cache escapes its directory");
11942
11985
  }
11943
11986
  async lock(path, signal) {
@@ -11967,17 +12010,17 @@ import {
11967
12010
  rmSync as rmSync15
11968
12011
  } from "node:fs";
11969
12012
  import { createRequire } from "node:module";
11970
- import { delimiter, dirname as dirname10, join as join24 } from "node:path";
12013
+ import { delimiter, dirname as dirname11, join as join25 } from "node:path";
11971
12014
  import { fileURLToPath as fileURLToPath2 } from "node:url";
11972
12015
  import { promisify as promisify4 } from "node:util";
11973
12016
 
11974
12017
  // src/agents/public-egress.ts
11975
12018
  import { lookup } from "node:dns/promises";
11976
- import { chmod, mkdtemp, rm } from "node:fs/promises";
12019
+ import { chmod, mkdtemp, rm as rm2 } from "node:fs/promises";
11977
12020
  import { createServer as createServer3, request as httpRequest } from "node:http";
11978
12021
  import { connect, isIP as isIP3 } from "node:net";
11979
12022
  import { tmpdir as tmpdir3 } from "node:os";
11980
- import { join as join23 } from "node:path";
12023
+ import { join as join24 } from "node:path";
11981
12024
 
11982
12025
  // ../../lib/search/url-policy.ts
11983
12026
  import { BlockList, isIP as isIP2 } from "node:net";
@@ -12046,9 +12089,9 @@ function endToEndHeaders(input) {
12046
12089
  }
12047
12090
  async function startPublicEgress(options) {
12048
12091
  options.signal.throwIfAborted();
12049
- const directory = await mkdtemp(join23(tmpdir3(), "mikka-egress-"));
12092
+ const directory = await mkdtemp(join24(tmpdir3(), "mikka-egress-"));
12050
12093
  await chmod(directory, 448);
12051
- const socketPath = join23(directory, "egress.sock");
12094
+ const socketPath = join24(directory, "egress.sock");
12052
12095
  const lifetime = new AbortController();
12053
12096
  const signal = AbortSignal.any([options.signal, lifetime.signal]);
12054
12097
  const sockets = /* @__PURE__ */ new Set();
@@ -12153,9 +12196,9 @@ async function startPublicEgress(options) {
12153
12196
  if (closing) return closing;
12154
12197
  lifetime.abort();
12155
12198
  for (const socket of sockets) socket.destroy();
12156
- closing = new Promise((resolve9, reject) => server.close((error) => {
12199
+ closing = new Promise((resolve10, reject) => server.close((error) => {
12157
12200
  options.signal.removeEventListener("abort", onAbort);
12158
- void rm(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve9(), reject);
12201
+ void rm2(directory, { recursive: true, force: true }).then(() => error && error.code !== "ERR_SERVER_NOT_RUNNING" ? reject(error) : resolve10(), reject);
12159
12202
  }));
12160
12203
  return closing;
12161
12204
  };
@@ -12164,11 +12207,11 @@ async function startPublicEgress(options) {
12164
12207
  };
12165
12208
  options.signal.addEventListener("abort", onAbort, { once: true });
12166
12209
  try {
12167
- await new Promise((resolve9, reject) => {
12210
+ await new Promise((resolve10, reject) => {
12168
12211
  server.once("error", reject);
12169
12212
  server.listen(socketPath, () => {
12170
12213
  server.removeListener("error", reject);
12171
- resolve9();
12214
+ resolve10();
12172
12215
  });
12173
12216
  });
12174
12217
  await chmod(socketPath, 384);
@@ -12205,7 +12248,7 @@ async function createHostedBotRunner(host) {
12205
12248
  }).catch(() => {
12206
12249
  throw unavailable2();
12207
12250
  });
12208
- const resources = join24(host.stateDir, "native-resources");
12251
+ const resources = join25(host.stateDir, "native-resources");
12209
12252
  mkdirSync14(resources, { recursive: true, mode: 448 });
12210
12253
  const removeResource = async (file, record) => {
12211
12254
  if (!/^mikka-native-(?:verify-)?[a-f0-9-]{36}$/.test(record.name) || !/^[a-f0-9-]{36}$/.test(record.nonce))
@@ -12226,7 +12269,7 @@ async function createHostedBotRunner(host) {
12226
12269
  if (record.state === "created" && /No such (?:container|object)/i.test(
12227
12270
  String(error.stderr)
12228
12271
  )) {
12229
- if (record.assets?.startsWith(join24(host.stateDir, "native-verify-git-")))
12272
+ if (record.assets?.startsWith(join25(host.stateDir, "native-verify-git-")))
12230
12273
  rmSync15(record.assets, { recursive: true, force: true });
12231
12274
  rmSync15(file, { force: true });
12232
12275
  return;
@@ -12237,13 +12280,13 @@ async function createHostedBotRunner(host) {
12237
12280
  if (labels?.["com.mikka.native.resource"] !== record.nonce || record.id && record.id !== id3)
12238
12281
  throw unavailable2();
12239
12282
  await exec2("docker", ["rm", "-f", id3], { env: bareEnv, timeout: 3e4 });
12240
- if (record.assets?.startsWith(join24(host.stateDir, "native-verify-git-")))
12283
+ if (record.assets?.startsWith(join25(host.stateDir, "native-verify-git-")))
12241
12284
  rmSync15(record.assets, { recursive: true, force: true });
12242
12285
  rmSync15(file, { force: true });
12243
12286
  };
12244
12287
  for (const name of readdirSync6(resources))
12245
12288
  if (name.endsWith(".json")) {
12246
- const file = join24(resources, name);
12289
+ const file = join25(resources, name);
12247
12290
  const record = readJson(file);
12248
12291
  if (!record) throw unavailable2();
12249
12292
  await removeResource(file, record);
@@ -12254,8 +12297,8 @@ async function createHostedBotRunner(host) {
12254
12297
  const bundled = createRequire(
12255
12298
  require2.resolve("@anthropic-ai/claude-agent-sdk")
12256
12299
  );
12257
- claude ??= join24(
12258
- dirname10(
12300
+ claude ??= join25(
12301
+ dirname11(
12259
12302
  bundled.resolve(
12260
12303
  "@anthropic-ai/claude-agent-sdk-linux-x64/package.json"
12261
12304
  )
@@ -12264,7 +12307,7 @@ async function createHostedBotRunner(host) {
12264
12307
  );
12265
12308
  } catch {
12266
12309
  }
12267
- const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter).map((dir) => join24(dir, "codex")).find((path) => existsSync5(path));
12310
+ const codex = host.binaries?.codex ?? (process.env.PATH ?? "").split(delimiter).map((dir) => join25(dir, "codex")).find((path) => existsSync5(path));
12268
12311
  const binaries = { codex, claude_code: claude };
12269
12312
  for (const kind of ["codex", "claude_code"])
12270
12313
  if (binaries[kind]) {
@@ -12278,12 +12321,12 @@ async function createHostedBotRunner(host) {
12278
12321
  if (!binaries.codex && !binaries.claude_code) throw unavailable2();
12279
12322
  const command = async (worktree, script, readOnly, timeoutMs, signal) => {
12280
12323
  const name = `mikka-native-verify-${randomUUID7()}`;
12281
- const file = join24(resources, name + ".json");
12324
+ const file = join25(resources, name + ".json");
12282
12325
  const resource = { name, nonce: randomUUID7(), state: "creating" };
12283
12326
  const timing = { createMs: 0, runMs: 0 };
12284
12327
  let phase = "create";
12285
12328
  let began = performance.now();
12286
- const gitCopy = mkdtempSync6(join24(host.stateDir, "native-verify-git-"));
12329
+ const gitCopy = mkdtempSync6(join25(host.stateDir, "native-verify-git-"));
12287
12330
  resource.assets = gitCopy;
12288
12331
  try {
12289
12332
  const cwd = realpathSync10(worktree);
@@ -12299,7 +12342,7 @@ async function createHostedBotRunner(host) {
12299
12342
  "--no-checkout",
12300
12343
  "--",
12301
12344
  cwd,
12302
- join24(gitCopy, "repo")
12345
+ join25(gitCopy, "repo")
12303
12346
  ],
12304
12347
  {
12305
12348
  env: {
@@ -12314,8 +12357,8 @@ async function createHostedBotRunner(host) {
12314
12357
  maxBuffer: 1024 * 1024
12315
12358
  }
12316
12359
  );
12317
- const safeGit = join24(gitCopy, "repo", ".git");
12318
- const protectedGit = lstatSync8(join24(cwd, ".git")).isFile() ? join24(cwd, ".git") : safeGit;
12360
+ const safeGit = join25(gitCopy, "repo", ".git");
12361
+ const protectedGit = lstatSync8(join25(cwd, ".git")).isFile() ? join25(cwd, ".git") : safeGit;
12319
12362
  writeJsonAtomic(file, resource);
12320
12363
  const created = await exec2(
12321
12364
  "docker",
@@ -12419,7 +12462,7 @@ async function createHostedBotRunner(host) {
12419
12462
  throw unavailable2();
12420
12463
  const name = `mikka-native-${randomUUID7()}`;
12421
12464
  const nonce = randomUUID7();
12422
- const resourceFile = join24(resources, name + ".json");
12465
+ const resourceFile = join25(resources, name + ".json");
12423
12466
  const resource = { name, nonce, state: "creating" };
12424
12467
  const lifetime = new AbortController();
12425
12468
  let closed = false;
@@ -12492,8 +12535,8 @@ async function createHostedBotRunner(host) {
12492
12535
  };
12493
12536
  const paths = runPaths(host.stateDir, assignment.runId);
12494
12537
  mkdirSync14(paths.runDir, { recursive: true, mode: 448 });
12495
- const shadow = join24(paths.runDir, "runtime-git");
12496
- const emptyHome = join24(paths.runDir, "git-bootstrap-home");
12538
+ const shadow = join25(paths.runDir, "runtime-git");
12539
+ const emptyHome = join25(paths.runDir, "git-bootstrap-home");
12497
12540
  mkdirSync14(emptyHome, { recursive: true, mode: 448 });
12498
12541
  if (!existsSync5(shadow))
12499
12542
  await exec2(
@@ -12524,9 +12567,9 @@ async function createHostedBotRunner(host) {
12524
12567
  }
12525
12568
  );
12526
12569
  await live();
12527
- if (!lstatSync8(shadow).isDirectory() || !lstatSync8(join24(shadow, ".git")).isDirectory() || !realpathSync10(shadow).startsWith(realpathSync10(paths.runDir) + "/"))
12570
+ if (!lstatSync8(shadow).isDirectory() || !lstatSync8(join25(shadow, ".git")).isDirectory() || !realpathSync10(shadow).startsWith(realpathSync10(paths.runDir) + "/"))
12528
12571
  throw unavailable2();
12529
- const ledger = join24(
12572
+ const ledger = join25(
12530
12573
  host.stateDir,
12531
12574
  "native-ledgers",
12532
12575
  assignment.runId + ".json"
@@ -12545,13 +12588,13 @@ async function createHostedBotRunner(host) {
12545
12588
  const previous = readJson(ledger);
12546
12589
  if (existsSync5(ledger) && (!previous || JSON.stringify(previous.scope) !== JSON.stringify(scope) || typeof previous.sessionId !== "string"))
12547
12590
  throw unavailable2();
12548
- mkdirSync14(dirname10(ledger), { recursive: true, mode: 448 });
12591
+ mkdirSync14(dirname11(ledger), { recursive: true, mode: 448 });
12549
12592
  const record = async (sessionId) => {
12550
12593
  assertOpen();
12551
12594
  writeJsonAtomic(ledger, { scope, sessionId });
12552
12595
  };
12553
12596
  brokerStarting = createNativeSubscriptionBroker({
12554
- root: join24(host.stateDir, "native-brokers"),
12597
+ root: join25(host.stateDir, "native-brokers"),
12555
12598
  revision,
12556
12599
  check,
12557
12600
  worker: {
@@ -12592,7 +12635,7 @@ async function createHostedBotRunner(host) {
12592
12635
  }
12593
12636
  const cwd = realpathSync10(options.cwd);
12594
12637
  const runDir = realpathSync10(paths.runDir);
12595
- const protectedGit = lstatSync8(join24(cwd, ".git")).isFile() ? join24(cwd, ".git") : join24(shadow, ".git");
12638
+ const protectedGit = lstatSync8(join25(cwd, ".git")).isFile() ? join25(cwd, ".git") : join25(shadow, ".git");
12596
12639
  if (!lstatSync8(runDir).isDirectory() || !runDir.startsWith(realpathSync10(host.stateDir) + "/runs/")) {
12597
12640
  await close();
12598
12641
  throw unavailable2();
@@ -12645,7 +12688,7 @@ async function createHostedBotRunner(host) {
12645
12688
  "-v",
12646
12689
  `${MCP_SERVER_SCRIPT}:${MCP_SERVER_SCRIPT}:ro`,
12647
12690
  "-v",
12648
- `${join24(dirname10(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:${join24(dirname10(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:ro`,
12691
+ `${join25(dirname11(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:${join25(dirname11(MCP_SERVER_SCRIPT), "capture-copy.mjs")}:ro`,
12649
12692
  "-v",
12650
12693
  `${readyBroker.socket}:/run/mikka-native.sock:ro`,
12651
12694
  ...computerGrant ? [
@@ -12688,13 +12731,13 @@ async function createHostedBotRunner(host) {
12688
12731
  }
12689
12732
  const spawnHosted = (config) => {
12690
12733
  assertOpen();
12691
- const home = join24(runDir, "runtime-home");
12734
+ const home = join25(runDir, "runtime-home");
12692
12735
  mkdirSync14(home, { recursive: true, mode: 448 });
12693
12736
  const env = {
12694
12737
  ...config.env,
12695
12738
  HOME: kind === "claude_code" ? config.env.HOME ?? home : home,
12696
12739
  PATH: "/usr/local/bin:/usr/bin:/bin",
12697
- GIT_DIR: join24(shadow, ".git"),
12740
+ GIT_DIR: join25(shadow, ".git"),
12698
12741
  GIT_WORK_TREE: cwd,
12699
12742
  GIT_CONFIG_GLOBAL: "/dev/null",
12700
12743
  GIT_CONFIG_SYSTEM: "/dev/null",
@@ -12727,9 +12770,9 @@ async function createHostedBotRunner(host) {
12727
12770
  signal: new AbortController().signal
12728
12771
  });
12729
12772
  child.stderr?.resume();
12730
- const exited = new Promise((resolve9) => {
12731
- child.once("exit", (code, signal) => resolve9({ code, signal }));
12732
- child.once("error", () => resolve9({ code: null, signal: null }));
12773
+ const exited = new Promise((resolve10) => {
12774
+ child.once("exit", (code, signal) => resolve10({ code, signal }));
12775
+ child.once("error", () => resolve10({ code: null, signal: null }));
12733
12776
  });
12734
12777
  return {
12735
12778
  process: child,
@@ -12988,9 +13031,9 @@ async function executeDriver(driver, input, display, leaseGuard, assertLive = ()
12988
13031
  )
12989
13032
  )
12990
13033
  );
12991
- const request = (method, params) => new Promise((resolve9, reject) => {
13034
+ const request = (method, params) => new Promise((resolve10, reject) => {
12992
13035
  const n = ++id3;
12993
- pending.set(n, { resolve: resolve9, reject });
13036
+ pending.set(n, { resolve: resolve10, reject });
12994
13037
  child.stdin.write(
12995
13038
  JSON.stringify({ jsonrpc: "2.0", id: n, method, params }) + "\n"
12996
13039
  );
@@ -13091,10 +13134,10 @@ var ComputerBroker = class {
13091
13134
  })();
13092
13135
  });
13093
13136
  });
13094
- await new Promise((resolve9, reject) => {
13137
+ await new Promise((resolve10, reject) => {
13095
13138
  this.server.once("error", reject);
13096
- if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 }, resolve9);
13097
- else this.server.listen(this.socketPath, resolve9);
13139
+ if (this.transport === "tcp") this.server.listen({ host: "127.0.0.1", port: 0 }, resolve10);
13140
+ else this.server.listen(this.socketPath, resolve10);
13098
13141
  });
13099
13142
  if (this.transport === "tcp") this.socketPath = `tcp://127.0.0.1:${this.server.address().port}`;
13100
13143
  else chmodSync3(this.socketPath, 384);
@@ -13125,7 +13168,7 @@ var ComputerBroker = class {
13125
13168
  expiresAt: this.now() + this.ttl
13126
13169
  };
13127
13170
  const digest = createHash6("sha256").update(JSON.stringify(request)).digest("hex");
13128
- return new Promise((resolve9, reject) => {
13171
+ return new Promise((resolve10, reject) => {
13129
13172
  const timer = setTimeout(() => {
13130
13173
  this.pending.delete(request.id);
13131
13174
  signal?.removeEventListener("abort", cancel);
@@ -13142,7 +13185,7 @@ var ComputerBroker = class {
13142
13185
  assertLive,
13143
13186
  cleanup: () => signal?.removeEventListener("abort", cancel),
13144
13187
  request: { ...request, digest },
13145
- resolve: resolve9,
13188
+ resolve: resolve10,
13146
13189
  reject,
13147
13190
  timer
13148
13191
  });
@@ -13219,7 +13262,7 @@ var ComputerBroker = class {
13219
13262
  async close() {
13220
13263
  this.suspend();
13221
13264
  for (const socket of this.sockets) socket.destroy();
13222
- if (this.server?.listening) await new Promise((resolve9) => this.server.close(resolve9));
13265
+ if (this.server?.listening) await new Promise((resolve10) => this.server.close(resolve10));
13223
13266
  }
13224
13267
  };
13225
13268
 
@@ -13288,11 +13331,11 @@ async function pollWebComputerReviews(broker, deviceId, link, signal, intervalMs
13288
13331
  } catch {
13289
13332
  }
13290
13333
  if (signal.aborted) break;
13291
- await new Promise((resolve9) => {
13334
+ await new Promise((resolve10) => {
13292
13335
  const done = () => {
13293
13336
  clearTimeout(timer);
13294
13337
  signal.removeEventListener("abort", done);
13295
- resolve9();
13338
+ resolve10();
13296
13339
  };
13297
13340
  const timer = setTimeout(done, intervalMs);
13298
13341
  signal.addEventListener("abort", done, { once: true });
@@ -13401,7 +13444,7 @@ var Daemon = class {
13401
13444
  if (this.options.credential)
13402
13445
  this.saveDevice({ credential: this.options.credential });
13403
13446
  this.journal = new RunJournal(paths.journal);
13404
- this.captureUploader = new CaptureUploader((runId) => join25(runPaths(paths.adapterState, runId).runDir, CAPTURES_DIR), this.options.link, this.log, join25(paths.dataDir, "capture-pending"));
13447
+ this.captureUploader = new CaptureUploader((runId) => join26(runPaths(paths.adapterState, runId).runDir, CAPTURES_DIR), this.options.link, this.log, join26(paths.dataDir, "capture-pending"));
13405
13448
  this.outbox = new Outbox(
13406
13449
  paths.outbox,
13407
13450
  this.options.link,
@@ -13418,7 +13461,7 @@ var Daemon = class {
13418
13461
  if (this.localComputerDriver && this.options.link.syncComputerReviews && this.options.link.localComputerAuthority) {
13419
13462
  this.localComputerBroker = new ComputerBroker({
13420
13463
  driver: this.localComputerDriver,
13421
- socketPath: join25(paths.dataDir, "local-computer.sock"),
13464
+ socketPath: join26(paths.dataDir, "local-computer.sock"),
13422
13465
  transport: "tcp",
13423
13466
  permitted: (runId) => {
13424
13467
  const assignment = this.journal.get(runId)?.assignment;
@@ -13460,7 +13503,7 @@ var Daemon = class {
13460
13503
  };
13461
13504
  this.cloudComputerBroker = new ComputerBroker({
13462
13505
  driver,
13463
- socketPath: join25(paths.dataDir, "computer.sock"),
13506
+ socketPath: join26(paths.dataDir, "computer.sock"),
13464
13507
  permitted: (runId) => {
13465
13508
  const entry = this.journal.get(runId);
13466
13509
  return Boolean(!this.stopped && this.registered && entry?.assignment.computer && this.supervisor?.computerRunAllowed(runId));
@@ -13729,12 +13772,12 @@ var Daemon = class {
13729
13772
  }
13730
13773
  /** Waits `ms`, or less if the daemon stops or the device registers. */
13731
13774
  pauseCommands(ms, signal) {
13732
- return new Promise((resolve9) => {
13775
+ return new Promise((resolve10) => {
13733
13776
  const done = () => {
13734
13777
  clearTimeout(timer);
13735
13778
  signal.removeEventListener("abort", done);
13736
13779
  this.wakeCommands = null;
13737
- resolve9();
13780
+ resolve10();
13738
13781
  };
13739
13782
  const timer = setTimeout(done, ms);
13740
13783
  signal.addEventListener("abort", done, { once: true });
@@ -13835,11 +13878,11 @@ var Daemon = class {
13835
13878
  return runVerify(sandbox, {
13836
13879
  command,
13837
13880
  worktree: realpathSync11(worktree),
13838
- tmpRoot: join25(this.paths.adapterState, "verify", runId),
13881
+ tmpRoot: join26(this.paths.adapterState, "verify", runId),
13839
13882
  privateDir: paths.privateDir,
13840
13883
  pidFile: paths.pidFile.replace(/\.pgid$/, ".verify.pgid"),
13841
13884
  networkAllow: repo.networkAllow,
13842
- env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE: join25(paths.runDir, "handoff.json") },
13885
+ env: { ...buildChildEnv(), MIKKA_HANDOFF_FILE: join26(paths.runDir, "handoff.json") },
13843
13886
  timeoutMs,
13844
13887
  signal,
13845
13888
  readOnly
@@ -13961,7 +14004,7 @@ var Daemon = class {
13961
14004
  }
13962
14005
  const deviceId = this.device.deviceId;
13963
14006
  const quotas = this.quota?.snapshot().quotas;
13964
- const { leases, revoked, cloudCredential, deviceCommands } = await link.heartbeat(deviceId, {
14007
+ const heartbeat = {
13965
14008
  completedDeviceCommands: this.device.completedDeviceCommands,
13966
14009
  failedDeviceCommands: this.device.failedDeviceCommands,
13967
14010
  harnesses: this.harnesses,
@@ -13969,7 +14012,8 @@ var Daemon = class {
13969
14012
  runs: this.supervisor.heartbeatRuns(),
13970
14013
  worktreeDiskBytes: await this.worktrees.diskUsage(),
13971
14014
  ...quotas ? { quotas } : {}
13972
- });
14015
+ };
14016
+ const { leases, revoked, cloudCredential, deviceCommands } = await link.heartbeat(deviceId, heartbeat);
13973
14017
  this.supervisor.renewLeases(leases);
13974
14018
  if (revoked) this.supervisor.revokeLeases(revoked);
13975
14019
  if (this.options.cloudComputer && cloudCredential && this.device.credential === credential) {
@@ -13978,6 +14022,26 @@ var Daemon = class {
13978
14022
  this.registered = false;
13979
14023
  }
13980
14024
  const command = deviceCommands?.[0];
14025
+ if (command?.kind === "uninstall") {
14026
+ this.draining = true;
14027
+ if (this.supervisor.heartbeatRuns().length === 0) {
14028
+ this.saveDevice({ completedDeviceCommands: [command.id], failedDeviceCommands: [] });
14029
+ try {
14030
+ await link.heartbeat(deviceId, { ...heartbeat, runs: [], completedDeviceCommands: [command.id], failedDeviceCommands: [] });
14031
+ } catch {
14032
+ this.log.warn("Could not confirm uninstall receipt");
14033
+ }
14034
+ setImmediate(() => {
14035
+ void this.stop().then(() => uninstallService(() => {
14036
+ this.saveDevice({ credential: void 0 });
14037
+ rmSync16(this.paths.secret, { force: true });
14038
+ })).catch(() => {
14039
+ this.options.onDrained?.();
14040
+ });
14041
+ });
14042
+ }
14043
+ return;
14044
+ }
13981
14045
  if (command && !this.device.completedDeviceCommands?.includes(command.id) && !this.device.failedDeviceCommands?.some((failure) => failure.id === command.id)) {
13982
14046
  if (command.kind === "redetect" || this.supervisor.heartbeatRuns().length === 0) {
13983
14047
  try {
@@ -14273,7 +14337,7 @@ var Daemon = class {
14273
14337
  if (!job || controller.signal.aborted) return;
14274
14338
  await runNativeCoordinatorJob(job, {
14275
14339
  deviceId,
14276
- stateDir: join25(this.paths.dataDir, "coordinator"),
14340
+ stateDir: join26(this.paths.dataDir, "coordinator"),
14277
14341
  link,
14278
14342
  signal: controller.signal,
14279
14343
  sandbox,