zelari-code 2.44.0 → 2.45.1

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.
@@ -807,7 +807,7 @@ async function openBrowser(url2) {
807
807
  return { bin: "xdg-open", args: [url2] };
808
808
  }
809
809
  })();
810
- return new Promise((resolve10, reject) => {
810
+ return new Promise((resolve11, reject) => {
811
811
  try {
812
812
  const child = spawn19(cmd.bin, cmd.args, {
813
813
  stdio: "ignore",
@@ -816,9 +816,9 @@ async function openBrowser(url2) {
816
816
  child.on("error", (err) => reject(err));
817
817
  child.on("spawn", () => {
818
818
  child.unref();
819
- resolve10();
819
+ resolve11();
820
820
  });
821
- setTimeout(() => resolve10(), 100);
821
+ setTimeout(() => resolve11(), 100);
822
822
  } catch (err) {
823
823
  reject(err);
824
824
  }
@@ -867,7 +867,7 @@ async function waitForLoopbackCallback(options) {
867
867
  const host = options.host ?? "127.0.0.1";
868
868
  const timeoutMs2 = options.timeoutMs ?? 3e5;
869
869
  const expectedPath = options.path.startsWith("/") ? options.path : `/${options.path}`;
870
- return new Promise((resolve10, reject) => {
870
+ return new Promise((resolve11, reject) => {
871
871
  let settled = false;
872
872
  const server = createServer((req, res) => {
873
873
  const url2 = new URL(req.url ?? "/", `http://${host}`);
@@ -896,7 +896,7 @@ async function waitForLoopbackCallback(options) {
896
896
  clearTimeout(timer);
897
897
  server.close(() => {
898
898
  if (err) reject(err);
899
- else resolve10(value ?? {});
899
+ else resolve11(value ?? {});
900
900
  });
901
901
  };
902
902
  server.on("error", (err) => finish2(void 0, err));
@@ -19086,7 +19086,7 @@ function createBashTool(spawnSeam) {
19086
19086
  timeoutMs: 6e4,
19087
19087
  inputSchema: BashArgsSchema,
19088
19088
  execute: async (args, ctx) => {
19089
- return new Promise((resolve10) => {
19089
+ return new Promise((resolve11) => {
19090
19090
  const start = Date.now();
19091
19091
  const cwd = args.cwd ?? ctx.cwd;
19092
19092
  const resolved = resolveShell();
@@ -19113,7 +19113,7 @@ function createBashTool(spawnSeam) {
19113
19113
  if (spawnSeam) {
19114
19114
  const seamResult = spawnSeam({ program, argv, cwd, env, signal: ctx.signal });
19115
19115
  if (seamResult.outcome !== "spawned") {
19116
- resolve10(typedErr(seamResult.reason));
19116
+ resolve11(typedErr(seamResult.reason));
19117
19117
  return;
19118
19118
  }
19119
19119
  child = seamResult.child;
@@ -19140,14 +19140,14 @@ function createBashTool(spawnSeam) {
19140
19140
  });
19141
19141
  const timer = setTimeout(() => {
19142
19142
  child.kill("SIGTERM");
19143
- resolve10(typedErr(`Bash command timed out after ${args.timeoutMs}ms. If it was waiting for interactive input: stdin is closed \u2014 pass non-interactive flags or create the files directly instead of retrying.`));
19143
+ resolve11(typedErr(`Bash command timed out after ${args.timeoutMs}ms. If it was waiting for interactive input: stdin is closed \u2014 pass non-interactive flags or create the files directly instead of retrying.`));
19144
19144
  }, args.timeoutMs);
19145
19145
  child.on("close", (code) => {
19146
19146
  clearTimeout(timer);
19147
19147
  const cappedStdout = stdout.slice(0, maxBuffer);
19148
19148
  const cappedStderr = stderr.slice(0, maxBuffer);
19149
19149
  const interactive = INTERACTIVE_CANCEL_RE.test(cappedStdout) || INTERACTIVE_CANCEL_RE.test(cappedStderr);
19150
- resolve10(typedOk({
19150
+ resolve11(typedOk({
19151
19151
  stdout: cappedStdout,
19152
19152
  stderr: cappedStderr,
19153
19153
  exitCode: code ?? -1,
@@ -19159,7 +19159,7 @@ function createBashTool(spawnSeam) {
19159
19159
  });
19160
19160
  child.on("error", (err) => {
19161
19161
  clearTimeout(timer);
19162
- resolve10(typedErr(err.message));
19162
+ resolve11(typedErr(err.message));
19163
19163
  });
19164
19164
  });
19165
19165
  }
@@ -22296,7 +22296,7 @@ var init_nodeProviders = __esm({
22296
22296
  const isWindows = process.platform === "win32";
22297
22297
  const file2 = isWindows ? "cmd.exe" : "/bin/sh";
22298
22298
  const args = isWindows ? ["/d", "/s", "/c", command] : ["-c", command];
22299
- return await new Promise((resolve10) => {
22299
+ return await new Promise((resolve11) => {
22300
22300
  const child = spawn2(file2, args, {
22301
22301
  cwd,
22302
22302
  shell: false,
@@ -22329,7 +22329,7 @@ var init_nodeProviders = __esm({
22329
22329
  });
22330
22330
  child.on("error", (err) => {
22331
22331
  clearTimeout(timer);
22332
- resolve10({
22332
+ resolve11({
22333
22333
  exitCode: null,
22334
22334
  stdout,
22335
22335
  stderr: `${stderr}${err.message}`,
@@ -22339,7 +22339,7 @@ var init_nodeProviders = __esm({
22339
22339
  });
22340
22340
  child.on("close", (code) => {
22341
22341
  clearTimeout(timer);
22342
- resolve10({ exitCode: code, stdout, stderr, durationMs: Date.now() - started, timedOut });
22342
+ resolve11({ exitCode: code, stdout, stderr, durationMs: Date.now() - started, timedOut });
22343
22343
  });
22344
22344
  });
22345
22345
  }
@@ -22417,7 +22417,7 @@ import path16 from "node:path";
22417
22417
  import crypto2 from "node:crypto";
22418
22418
  import { spawn as spawn3 } from "node:child_process";
22419
22419
  async function git(cwd, args) {
22420
- return await new Promise((resolve10, reject) => {
22420
+ return await new Promise((resolve11, reject) => {
22421
22421
  const child = spawn3("git", args, { cwd, shell: false });
22422
22422
  let stdout = "";
22423
22423
  let stderr = "";
@@ -22426,7 +22426,7 @@ async function git(cwd, args) {
22426
22426
  child.on("error", (err) => reject(err));
22427
22427
  child.on("close", (code) => {
22428
22428
  if (code === 0)
22429
- resolve10(stdout);
22429
+ resolve11(stdout);
22430
22430
  else
22431
22431
  reject(new Error(`git ${args.join(" ")} failed (${code}): ${stderr.trim()}`));
22432
22432
  });
@@ -30565,8 +30565,8 @@ function wrapLegacyStream(legacyStream, params, _messages, _tools) {
30565
30565
  }
30566
30566
  if (done)
30567
30567
  break;
30568
- await new Promise((resolve10) => {
30569
- resolveNext = resolve10;
30568
+ await new Promise((resolve11) => {
30569
+ resolveNext = resolve11;
30570
30570
  });
30571
30571
  }
30572
30572
  await promise2;
@@ -30699,11 +30699,11 @@ var init_sessionJsonl = __esm({
30699
30699
  */
30700
30700
  scheduleFlush() {
30701
30701
  if (this.pending.length > 0 && !this.flushDeferred) {
30702
- let resolve10;
30702
+ let resolve11;
30703
30703
  const promise2 = new Promise((r) => {
30704
- resolve10 = r;
30704
+ resolve11 = r;
30705
30705
  });
30706
- this.flushDeferred = { promise: promise2, resolve: resolve10 };
30706
+ this.flushDeferred = { promise: promise2, resolve: resolve11 };
30707
30707
  }
30708
30708
  if (this.flushTimer === null && this.pending.length > 0) {
30709
30709
  this.flushTimer = setTimeout(() => {
@@ -31010,7 +31010,7 @@ var init_lifecycleHookRunner = __esm({
31010
31010
  }
31011
31011
  /** Spawn `command`, write JSON payload to stdin, read stdout until close. */
31012
31012
  execCommand(command, payload, timeoutMs2, cwd) {
31013
- return new Promise((resolve10, reject) => {
31013
+ return new Promise((resolve11, reject) => {
31014
31014
  const argv = splitHookCommandLine(command);
31015
31015
  if (argv.length === 0) {
31016
31016
  reject(new Error("empty hook command"));
@@ -31044,7 +31044,7 @@ var init_lifecycleHookRunner = __esm({
31044
31044
  reject(new Error(`exited ${code}: ${stderr.trim().slice(0, 200)}`));
31045
31045
  return;
31046
31046
  }
31047
- resolve10(stdout);
31047
+ resolve11(stdout);
31048
31048
  });
31049
31049
  child.stdin?.on("error", () => {
31050
31050
  });
@@ -38898,7 +38898,7 @@ var CORE_VERSION;
38898
38898
  var init_version = __esm({
38899
38899
  "packages/core/dist/version.js"() {
38900
38900
  "use strict";
38901
- CORE_VERSION = "2.44.0";
38901
+ CORE_VERSION = "2.45.1";
38902
38902
  }
38903
38903
  });
38904
38904
 
@@ -40116,15 +40116,48 @@ __export(updater_exports, {
40116
40116
  fetchLatestVersion: () => fetchLatestVersion,
40117
40117
  getCurrentVersion: () => getCurrentVersion,
40118
40118
  looksLikeBrokenShim: () => looksLikeBrokenShim,
40119
+ nonGlobalUpdateAdvisory: () => nonGlobalUpdateAdvisory,
40119
40120
  performUpdate: () => performUpdate,
40120
40121
  registryUrlForTag: () => registryUrlForTag,
40121
- resolveBundledNpmCli: () => resolveBundledNpmCli
40122
+ resolveBundledNpmCli: () => resolveBundledNpmCli,
40123
+ resolveInstallKind: () => resolveInstallKind
40122
40124
  });
40123
40125
  import { createRequire } from "node:module";
40124
- import { spawn as spawn6 } from "node:child_process";
40126
+ import { execSync, spawn as spawn6 } from "node:child_process";
40125
40127
  import { existsSync as existsSync14 } from "node:fs";
40128
+ import os2 from "node:os";
40126
40129
  import path32 from "node:path";
40127
40130
  import { fileURLToPath } from "node:url";
40131
+ function getGlobalPrefix() {
40132
+ try {
40133
+ const out = execSync("npm prefix -g", {
40134
+ encoding: "utf8",
40135
+ stdio: ["ignore", "pipe", "ignore"]
40136
+ }).trim();
40137
+ return out || null;
40138
+ } catch {
40139
+ return null;
40140
+ }
40141
+ }
40142
+ function normalizeForMatch2(p3) {
40143
+ return path32.resolve(p3).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
40144
+ }
40145
+ function resolveInstallKind(npmPrefix = getGlobalPrefix(), packageRoot2 = PKG_ROOT) {
40146
+ const root = normalizeForMatch2(packageRoot2);
40147
+ const tmp = normalizeForMatch2(os2.tmpdir());
40148
+ const inTmp = tmp !== "" && (root === tmp || root.startsWith(`${tmp}/`));
40149
+ if (root.split("/").includes("_npx") || inTmp) return "npx";
40150
+ if (!npmPrefix) return "unknown";
40151
+ const prefix = normalizeForMatch2(npmPrefix);
40152
+ if (root === prefix || root.startsWith(`${prefix}/`)) return "global";
40153
+ return "local";
40154
+ }
40155
+ function nonGlobalUpdateAdvisory(kind2) {
40156
+ const where = kind2 === "npx" ? "was started via npx (from npm's cache)" : "is a local/source install";
40157
+ return `[update] this zelari-code ${where}, not a global install \u2014 self-update is disabled.
40158
+ update with: npx zelari-code@latest (always fetches the latest)
40159
+ or install persistently: npm install -g zelari-code (enables /update)`;
40160
+ }
40128
40161
  function resolveBundledNpmCli(execPath = process.execPath) {
40129
40162
  const dir = path32.dirname(execPath);
40130
40163
  const candidates = [
@@ -40218,7 +40251,16 @@ async function checkForUpdate(fetcher = fetch, registryUrl) {
40218
40251
  updateAvailable: cmp < 0
40219
40252
  };
40220
40253
  }
40221
- async function performUpdate(packageName = "zelari-code", executor = spawn6, resolveNpmCli = resolveBundledNpmCli, channel) {
40254
+ async function performUpdate(packageName = "zelari-code", executor = spawn6, resolveNpmCli = resolveBundledNpmCli, channel, installKind = resolveInstallKind()) {
40255
+ if (installKind === "npx" || installKind === "local") {
40256
+ return {
40257
+ ok: false,
40258
+ output: nonGlobalUpdateAdvisory(installKind),
40259
+ error: "self-update skipped: non-global install",
40260
+ exitCode: null,
40261
+ installKind
40262
+ };
40263
+ }
40222
40264
  const tag = channel ?? distTagForVersion(getCurrentVersion());
40223
40265
  const args = ["install", "-g", `${packageName}@${tag}`];
40224
40266
  const primary = await runNpm(executor, args, "shim");
@@ -40235,7 +40277,7 @@ ${fallback.output}`
40235
40277
  return primary;
40236
40278
  }
40237
40279
  function runNpm(executor, args, mode, npmCliPath) {
40238
- return new Promise((resolve10) => {
40280
+ return new Promise((resolve11) => {
40239
40281
  let stdout = "";
40240
40282
  let stderr = "";
40241
40283
  const stdio = ["ignore", "pipe", "pipe"];
@@ -40247,7 +40289,7 @@ function runNpm(executor, args, mode, npmCliPath) {
40247
40289
  stderr += chunk.toString();
40248
40290
  });
40249
40291
  child.on("error", (err) => {
40250
- resolve10({
40292
+ resolve11({
40251
40293
  ok: false,
40252
40294
  output: stdout + stderr,
40253
40295
  error: err.message,
@@ -40256,7 +40298,7 @@ function runNpm(executor, args, mode, npmCliPath) {
40256
40298
  });
40257
40299
  child.on("close", (code) => {
40258
40300
  const ok = code === 0;
40259
- resolve10({
40301
+ resolve11({
40260
40302
  ok,
40261
40303
  output: stdout + stderr,
40262
40304
  error: ok ? void 0 : `npm exited with code ${code}`,
@@ -40265,13 +40307,14 @@ function runNpm(executor, args, mode, npmCliPath) {
40265
40307
  });
40266
40308
  });
40267
40309
  }
40268
- var require2, __dirname2, REGISTRY_URL;
40310
+ var require2, __dirname2, PKG_ROOT, REGISTRY_URL;
40269
40311
  var init_updater = __esm({
40270
40312
  "src/cli/updater.ts"() {
40271
40313
  "use strict";
40272
40314
  init_cmdline();
40273
40315
  require2 = createRequire(import.meta.url);
40274
40316
  __dirname2 = path32.dirname(fileURLToPath(import.meta.url));
40317
+ PKG_ROOT = path32.resolve(__dirname2, "..", "..");
40275
40318
  REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
40276
40319
  }
40277
40320
  });
@@ -42278,8 +42321,8 @@ var init_storage = __esm({
42278
42321
  const prev2 = this.chains.get(key) ?? Promise.resolve();
42279
42322
  let release = () => {
42280
42323
  };
42281
- const next = new Promise((resolve10) => {
42282
- release = resolve10;
42324
+ const next = new Promise((resolve11) => {
42325
+ release = resolve11;
42283
42326
  });
42284
42327
  const chained = prev2.then(() => next);
42285
42328
  this.chains.set(key, chained);
@@ -43075,14 +43118,14 @@ var init_engine2 = __esm({
43075
43118
  parse: parseRuffJson
43076
43119
  }
43077
43120
  ];
43078
- defaultRunner = (cmd, args, opts) => new Promise((resolve10) => {
43121
+ defaultRunner = (cmd, args, opts) => new Promise((resolve11) => {
43079
43122
  let stdout = "";
43080
43123
  let stderr = "";
43081
43124
  let settled = false;
43082
43125
  const done = (r) => {
43083
43126
  if (settled) return;
43084
43127
  settled = true;
43085
- resolve10(r);
43128
+ resolve11(r);
43086
43129
  };
43087
43130
  let child;
43088
43131
  try {
@@ -44137,7 +44180,7 @@ async function readChecks(cwd) {
44137
44180
  }
44138
44181
  }
44139
44182
  function runShell(command, cwd, timeoutMs2, signal) {
44140
- return new Promise((resolve10) => {
44183
+ return new Promise((resolve11) => {
44141
44184
  const isWin = process.platform === "win32";
44142
44185
  const child = spawn8(isWin ? "cmd.exe" : "/bin/sh", isWin ? ["/c", command] : ["-c", command], {
44143
44186
  cwd,
@@ -44151,7 +44194,7 @@ function runShell(command, cwd, timeoutMs2, signal) {
44151
44194
  const finish2 = (exitCode) => {
44152
44195
  if (settled) return;
44153
44196
  settled = true;
44154
- resolve10({ exitCode, stdout, stderr });
44197
+ resolve11({ exitCode, stdout, stderr });
44155
44198
  };
44156
44199
  const timer = setTimeout(() => {
44157
44200
  try {
@@ -46862,8 +46905,8 @@ ${upstream}` : node.prompt,
46862
46905
  if (ms <= 0) return promise2;
46863
46906
  let timer;
46864
46907
  const TIMED_OUT = Symbol("timeout");
46865
- const timeout = new Promise((resolve10) => {
46866
- timer = setTimeout(() => resolve10(TIMED_OUT), ms);
46908
+ const timeout = new Promise((resolve11) => {
46909
+ timer = setTimeout(() => resolve11(TIMED_OUT), ms);
46867
46910
  });
46868
46911
  const raced = await Promise.race([promise2, timeout]).finally(() => {
46869
46912
  if (timer) clearTimeout(timer);
@@ -46872,8 +46915,8 @@ ${upstream}` : node.prompt,
46872
46915
  controller?.abort();
46873
46916
  const graceMs = this.cancelGraceMs ?? resolveCancelGraceMs();
46874
46917
  let graceTimer;
46875
- const grace = new Promise((resolve10) => {
46876
- graceTimer = setTimeout(() => resolve10(TIMED_OUT), graceMs);
46918
+ const grace = new Promise((resolve11) => {
46919
+ graceTimer = setTimeout(() => resolve11(TIMED_OUT), graceMs);
46877
46920
  });
46878
46921
  const settled = await Promise.race([promise2, grace]).finally(() => {
46879
46922
  if (graceTimer) clearTimeout(graceTimer);
@@ -47640,13 +47683,13 @@ ${findings || "(the reviewer reported FAIL without detail)"}`;
47640
47683
  async function runAutoVerifyAfterGeneral(opts) {
47641
47684
  const g = globalThis;
47642
47685
  g.__zelariGeneralVerifyDebt = { description: opts.original.description };
47643
- const emitVerifyPhase = (detail2, ok) => {
47686
+ const emitVerifyPhase = (detail2, ok, terminal) => {
47644
47687
  const agentId = opts.general.agentId;
47645
47688
  if (agentId) {
47646
47689
  opts.deps.onTentacleEvent?.({
47647
47690
  type: "agent_status",
47648
47691
  agentId,
47649
- status: "running",
47692
+ status: terminal ?? "running",
47650
47693
  message: detail2,
47651
47694
  id: randomUUID4(),
47652
47695
  sessionId: opts.sessionId,
@@ -47714,6 +47757,7 @@ async function runAutoVerifyAfterGeneral(opts) {
47714
47757
  detail: detail2,
47715
47758
  ok: false
47716
47759
  });
47760
+ emitVerifyPhase(`rework round ${round2} failed`, false, "failed");
47717
47761
  return `
47718
47762
 
47719
47763
  [kraken:auto-verify] verify FAIL \u2014 rework round ${round2} failed to run (${rework.error}). Work stays UNVERIFIED; strict done will close this turn blocked.`;
@@ -47725,14 +47769,15 @@ async function runAutoVerifyAfterGeneral(opts) {
47725
47769
  }
47726
47770
  if (verdict === "pass") {
47727
47771
  g.__zelariGeneralVerifyDebt = null;
47728
- emitVerifyPhase("verify PASS", true);
47772
+ emitVerifyPhase("verify PASS", true, "completed");
47729
47773
  return `
47730
47774
 
47731
47775
  [kraken:auto-verify] verify PASS \u2014 general\u21D2verify obligation satisfied.`;
47732
47776
  }
47733
47777
  emitVerifyPhase(
47734
47778
  verdict === "fail" ? "verify FAIL" : verify.ok ? "verify unknown" : "verify failed",
47735
- verdict === "fail" || !verify.ok ? false : void 0
47779
+ verdict === "fail" || !verify.ok ? false : void 0,
47780
+ "failed"
47736
47781
  );
47737
47782
  const detail = verdict === "fail" ? `verify FAIL unresolved (rework budget spent): ${findings || "no findings reported"}` : verify.ok ? "verify produced no parseable VERDICT \u2014 unverified" : `verify tentacle failed: ${verify.error}`;
47738
47783
  g.__zelariGeneralVerifyDebt = { description: opts.original.description, detail };
@@ -50772,13 +50817,13 @@ async function scanTsbuildinfo(root) {
50772
50817
  return found;
50773
50818
  }
50774
50819
  async function gitStatusPorcelain(root) {
50775
- return new Promise((resolve10) => {
50820
+ return new Promise((resolve11) => {
50776
50821
  const child = spawn9("git", ["status", "--porcelain"], { cwd: root, shell: false });
50777
50822
  let out = "";
50778
50823
  child.stdout.on("data", (d) => out += d.toString());
50779
50824
  child.stderr.on("data", (d) => out += d.toString());
50780
- child.on("error", () => resolve10("<git-unavailable>"));
50781
- child.on("close", (code) => resolve10(code === 0 ? out : `<git-exit-${code ?? "none"}>`));
50825
+ child.on("error", () => resolve11("<git-unavailable>"));
50826
+ child.on("close", (code) => resolve11(code === 0 ? out : `<git-exit-${code ?? "none"}>`));
50782
50827
  });
50783
50828
  }
50784
50829
  async function fingerprintWorkspace(root) {
@@ -50826,7 +50871,7 @@ var init_inspectTypecheckSafety = __esm({
50826
50871
  import { spawn as spawn10 } from "node:child_process";
50827
50872
  import { createHash as createHash14 } from "node:crypto";
50828
50873
  import { existsSync as existsSync30, promises as fs23 } from "node:fs";
50829
- import os2 from "node:os";
50874
+ import os3 from "node:os";
50830
50875
  import path52 from "node:path";
50831
50876
  function resolveNodeModuleBin(start, rel2) {
50832
50877
  let dir = path52.resolve(start);
@@ -50912,7 +50957,7 @@ function buildInspectCommand(op, ctx) {
50912
50957
  case "typecheck": {
50913
50958
  const project = path52.resolve(ctx.cwd, op.project ?? "tsconfig.json");
50914
50959
  const hash3 = createHash14("sha256").update(project).digest("hex").slice(0, 16);
50915
- const tsBuildInfoFile = path52.join(os2.tmpdir(), "zelari-inspect", `${hash3}.tsbuildinfo`);
50960
+ const tsBuildInfoFile = path52.join(os3.tmpdir(), "zelari-inspect", `${hash3}.tsbuildinfo`);
50916
50961
  return {
50917
50962
  ok: true,
50918
50963
  command: process.execPath,
@@ -50936,12 +50981,12 @@ function buildInspectCommand(op, ctx) {
50936
50981
  }
50937
50982
  }
50938
50983
  function runSpawn(command, argv, opts) {
50939
- return new Promise((resolve10) => {
50984
+ return new Promise((resolve11) => {
50940
50985
  let child;
50941
50986
  try {
50942
50987
  child = spawn10(command, argv, { cwd: opts.cwd, shell: false });
50943
50988
  } catch (err) {
50944
- resolve10({ code: null, stdout: "", stderr: String(err), timedOut: false, spawnError: String(err) });
50989
+ resolve11({ code: null, stdout: "", stderr: String(err), timedOut: false, spawnError: String(err) });
50945
50990
  return;
50946
50991
  }
50947
50992
  let stdout = "";
@@ -50963,14 +51008,14 @@ function runSpawn(command, argv, opts) {
50963
51008
  if (settled) return;
50964
51009
  settled = true;
50965
51010
  clearTimeout(timer);
50966
- resolve10({ code: null, stdout, stderr, timedOut, spawnError: err.message });
51011
+ resolve11({ code: null, stdout, stderr, timedOut, spawnError: err.message });
50967
51012
  });
50968
51013
  child.on("close", (code) => {
50969
51014
  if (settled) return;
50970
51015
  settled = true;
50971
51016
  clearTimeout(timer);
50972
51017
  opts.signal?.removeEventListener("abort", onAbort);
50973
- resolve10({ code, stdout, stderr, timedOut });
51018
+ resolve11({ code, stdout, stderr, timedOut });
50974
51019
  });
50975
51020
  });
50976
51021
  }
@@ -51255,7 +51300,7 @@ function createExecProcessTool(root, opts = {}) {
51255
51300
  const msg = err instanceof SandboxViolationError ? err.message : String(err);
51256
51301
  return typedErr(`[sandbox] ${msg}`);
51257
51302
  }
51258
- return new Promise((resolve10) => {
51303
+ return new Promise((resolve11) => {
51259
51304
  const start = Date.now();
51260
51305
  const spec = { ...baseSpec, network: opts.resolveNetwork?.(input) ?? baseSpec.network };
51261
51306
  const res = spawnJailed(spec, {
@@ -51267,11 +51312,11 @@ function createExecProcessTool(root, opts = {}) {
51267
51312
  envExtras: { CI: process.env.CI ?? "1" }
51268
51313
  });
51269
51314
  if (res.outcome === "denied") {
51270
- resolve10(typedErr(res.reason));
51315
+ resolve11(typedErr(res.reason));
51271
51316
  return;
51272
51317
  }
51273
51318
  if (res.outcome === "failed") {
51274
- resolve10(typedErr(`exec_process could not launch ${input.program}: ${res.reason}`));
51319
+ resolve11(typedErr(`exec_process could not launch ${input.program}: ${res.reason}`));
51275
51320
  return;
51276
51321
  }
51277
51322
  const meta3 = res.notice ? { status: "complete", warnings: [`os-jail: ${res.notice}`] } : void 0;
@@ -51287,7 +51332,7 @@ function createExecProcessTool(root, opts = {}) {
51287
51332
  const timeoutMs2 = typeof input.timeoutMs === "number" && input.timeoutMs > 0 ? input.timeoutMs : 3e4;
51288
51333
  const timer = setTimeout(() => {
51289
51334
  child.kill("SIGTERM");
51290
- resolve10(
51335
+ resolve11(
51291
51336
  typedErr(
51292
51337
  `exec_process timed out after ${timeoutMs2}ms running: ${[input.program, ...argv].join(" ")}`
51293
51338
  )
@@ -51295,11 +51340,11 @@ function createExecProcessTool(root, opts = {}) {
51295
51340
  }, timeoutMs2);
51296
51341
  child.on("error", (err) => {
51297
51342
  clearTimeout(timer);
51298
- resolve10(typedErr(`exec_process could not launch ${input.program}: ${err.message}`));
51343
+ resolve11(typedErr(`exec_process could not launch ${input.program}: ${err.message}`));
51299
51344
  });
51300
51345
  child.on("close", (code) => {
51301
51346
  clearTimeout(timer);
51302
- resolve10(
51347
+ resolve11(
51303
51348
  typedOk(
51304
51349
  {
51305
51350
  exitCode: code ?? -1,
@@ -51828,12 +51873,12 @@ var init_client = __esm({
51828
51873
  if (this.closed) return Promise.reject(new Error("LSP transport is closed"));
51829
51874
  const id3 = this.nextId++;
51830
51875
  const msg = { jsonrpc: "2.0", id: id3, method, ...params !== void 0 ? { params } : {} };
51831
- return new Promise((resolve10, reject) => {
51876
+ return new Promise((resolve11, reject) => {
51832
51877
  const timer = setTimeout(() => {
51833
51878
  this.pending.delete(id3);
51834
51879
  reject(new Error(`LSP request "${method}" timed out after ${this.timeoutMs}ms`));
51835
51880
  }, this.timeoutMs);
51836
- this.pending.set(id3, { resolve: resolve10, reject, timer });
51881
+ this.pending.set(id3, { resolve: resolve11, reject, timer });
51837
51882
  this.transport.send(encodeMessage(msg));
51838
51883
  });
51839
51884
  }
@@ -52110,8 +52155,8 @@ var init_manager = __esm({
52110
52155
  if (cached2 !== void 0) return cached2;
52111
52156
  let resolveInit;
52112
52157
  let rejectInit;
52113
- const initialized = new Promise((resolve10, reject) => {
52114
- resolveInit = resolve10;
52158
+ const initialized = new Promise((resolve11, reject) => {
52159
+ resolveInit = resolve11;
52115
52160
  rejectInit = reject;
52116
52161
  });
52117
52162
  let entry = null;
@@ -52636,14 +52681,14 @@ function resolveStreamTimeouts(capabilities) {
52636
52681
  };
52637
52682
  }
52638
52683
  function abortableSleep(ms, signal) {
52639
- return new Promise((resolve10) => {
52640
- if (signal?.aborted) return resolve10();
52641
- const t = setTimeout(resolve10, ms);
52684
+ return new Promise((resolve11) => {
52685
+ if (signal?.aborted) return resolve11();
52686
+ const t = setTimeout(resolve11, ms);
52642
52687
  signal?.addEventListener(
52643
52688
  "abort",
52644
52689
  () => {
52645
52690
  clearTimeout(t);
52646
- resolve10();
52691
+ resolve11();
52647
52692
  },
52648
52693
  { once: true }
52649
52694
  );
@@ -53517,8 +53562,8 @@ async function runBrowserCheck(options, loader) {
53517
53562
  const failedRequests = [];
53518
53563
  const evaluateResults = [];
53519
53564
  const base2 = { ok: false, consoleErrors, pageErrors, failedRequests };
53520
- const resolve10 = loader ?? (() => loadPlaywright(options.cwd ?? process.cwd()));
53521
- const pw = await resolve10();
53565
+ const resolve11 = loader ?? (() => loadPlaywright(options.cwd ?? process.cwd()));
53566
+ const pw = await resolve11();
53522
53567
  if (!pw) {
53523
53568
  return {
53524
53569
  ...base2,
@@ -53681,7 +53726,7 @@ var init_driver = __esm({
53681
53726
 
53682
53727
  // src/cli/browser/tools.ts
53683
53728
  import path58 from "node:path";
53684
- import os3 from "node:os";
53729
+ import os4 from "node:os";
53685
53730
  import { readFile as readFile8 } from "node:fs/promises";
53686
53731
  async function loadImageBlock(filePath) {
53687
53732
  try {
@@ -53708,7 +53753,7 @@ function createBrowserTool(deps = {}) {
53708
53753
  }),
53709
53754
  execute: async (args, ctx) => {
53710
53755
  const a = args;
53711
- const dir = deps.screenshotDir ?? os3.tmpdir();
53756
+ const dir = deps.screenshotDir ?? os4.tmpdir();
53712
53757
  const screenshotPath = a.screenshot === false ? void 0 : path58.join(dir, `zelari-browser-${Date.now()}.png`);
53713
53758
  const result = await runBrowserCheck(
53714
53759
  {
@@ -54111,9 +54156,9 @@ exec node "$(dirname "$0")/askpass.cjs"
54111
54156
  return sh;
54112
54157
  }
54113
54158
  function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
54114
- return new Promise((resolve10) => {
54159
+ return new Promise((resolve11) => {
54115
54160
  if (target.auth === "password" && !getSshPassword(target.id)) {
54116
- resolve10({
54161
+ resolve11({
54117
54162
  code: 1,
54118
54163
  stdout: "",
54119
54164
  stderr: "No password stored for this target \u2014 edit target and set password"
@@ -54145,7 +54190,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
54145
54190
  });
54146
54191
  const timer = setTimeout(() => {
54147
54192
  child.kill("SIGTERM");
54148
- resolve10({
54193
+ resolve11({
54149
54194
  code: 124,
54150
54195
  stdout,
54151
54196
  stderr: stderr + "\n[ssh] timeout"
@@ -54153,7 +54198,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
54153
54198
  }, timeoutMs2);
54154
54199
  child.on("error", (err) => {
54155
54200
  clearTimeout(timer);
54156
- resolve10({
54201
+ resolve11({
54157
54202
  code: 127,
54158
54203
  stdout,
54159
54204
  stderr: err.message.includes("ENOENT") ? "ssh not found on PATH \u2014 install OpenSSH client" : err.message
@@ -54161,7 +54206,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
54161
54206
  });
54162
54207
  child.on("close", (code) => {
54163
54208
  clearTimeout(timer);
54164
- resolve10({ code: code ?? 1, stdout, stderr });
54209
+ resolve11({ code: code ?? 1, stdout, stderr });
54165
54210
  });
54166
54211
  });
54167
54212
  }
@@ -54938,14 +54983,14 @@ function backoffDelay2(attempt, retryAfterHeader) {
54938
54983
  return Math.min(BACKOFF_BASE_MS2 * 2 ** attempt, BACKOFF_CAP_MS2);
54939
54984
  }
54940
54985
  function abortableSleep2(ms, signal) {
54941
- return new Promise((resolve10) => {
54942
- if (signal?.aborted) return resolve10();
54943
- const t = setTimeout(resolve10, ms);
54986
+ return new Promise((resolve11) => {
54987
+ if (signal?.aborted) return resolve11();
54988
+ const t = setTimeout(resolve11, ms);
54944
54989
  signal?.addEventListener(
54945
54990
  "abort",
54946
54991
  () => {
54947
54992
  clearTimeout(t);
54948
- resolve10();
54993
+ resolve11();
54949
54994
  },
54950
54995
  { once: true }
54951
54996
  );
@@ -57035,6 +57080,9 @@ function wrapWithPermissions(original, policy, onAsk, agentLayers, precedence =
57035
57080
  }
57036
57081
  const claimHit = claims && claims.effect !== void 0 ? claims.matchedRules.find((x) => x.effect === claims.effect) : void 0;
57037
57082
  const rulePrefix = contractRule ? `[contract] rule '${contractRule.match}'${contractRule.reason ? ` \u2014 ${contractRule.reason}` : ""}` : rule ? `[policy] rule '${rule.match}'${rule.reason ? ` \u2014 ${rule.reason}` : ""}` : claimHit ? `[policy] claim '${claimHit.match}'${claimHit.reason ? ` \u2014 ${claimHit.reason}` : ""}` : "";
57083
+ if (action === "ask" && activePermissionPreset() === "yolo") {
57084
+ action = "allow";
57085
+ }
57038
57086
  if (action === "deny") {
57039
57087
  return typedErr(`[permission] ${rulePrefix || decision.reason}`);
57040
57088
  }
@@ -57565,12 +57613,12 @@ var init_metrics3 = __esm({
57565
57613
  }
57566
57614
  /** Append a single record synchronously (file I/O). */
57567
57615
  append(rec) {
57568
- return new Promise((resolve10, reject) => {
57616
+ return new Promise((resolve11, reject) => {
57569
57617
  try {
57570
57618
  this.maybeRotate();
57571
57619
  const line = JSON.stringify(rec) + "\n";
57572
57620
  appendFileSync3(this.file, line, { encoding: "utf-8" });
57573
- resolve10();
57621
+ resolve11();
57574
57622
  } catch (err) {
57575
57623
  reject(err);
57576
57624
  }
@@ -58955,8 +59003,8 @@ var init_sqliteRpc = __esm({
58955
59003
  const worker = this.worker;
58956
59004
  if (!worker) return Promise.reject(new Error("SQLite worker is not open."));
58957
59005
  const id3 = this.nextId++;
58958
- return new Promise((resolve10, reject) => {
58959
- this.pending.set(id3, { resolve: resolve10, reject });
59006
+ return new Promise((resolve11, reject) => {
59007
+ this.pending.set(id3, { resolve: resolve11, reject });
58960
59008
  worker.postMessage({ id: id3, operation, args });
58961
59009
  });
58962
59010
  }
@@ -58967,7 +59015,7 @@ var init_sqliteRpc = __esm({
58967
59015
  return await this.request(operation, args);
58968
59016
  } catch (error51) {
58969
59017
  if (!isBusy(error51) || attempt >= 3) throw error51;
58970
- await new Promise((resolve10) => setTimeout(resolve10, 25 * 2 ** attempt));
59018
+ await new Promise((resolve11) => setTimeout(resolve11, 25 * 2 ** attempt));
58971
59019
  attempt += 1;
58972
59020
  }
58973
59021
  }
@@ -61886,13 +61934,13 @@ __export(claudeProvider_exports, {
61886
61934
  });
61887
61935
  import { spawn as spawn13 } from "node:child_process";
61888
61936
  function waitForExit(child, timeoutMs2 = 2e3) {
61889
- return new Promise((resolve10) => {
61890
- if (child.exitCode != null) return resolve10(child.exitCode);
61891
- const timer = setTimeout(() => resolve10(child.exitCode ?? null), timeoutMs2);
61937
+ return new Promise((resolve11) => {
61938
+ if (child.exitCode != null) return resolve11(child.exitCode);
61939
+ const timer = setTimeout(() => resolve11(child.exitCode ?? null), timeoutMs2);
61892
61940
  timer.unref?.();
61893
61941
  child.once("exit", (code) => {
61894
61942
  clearTimeout(timer);
61895
- resolve10(code ?? null);
61943
+ resolve11(code ?? null);
61896
61944
  });
61897
61945
  });
61898
61946
  }
@@ -63807,7 +63855,7 @@ var init_mcpClient = __esm({
63807
63855
  if (!transport && !child)
63808
63856
  return Promise.reject(new Error(`[mcp:${this.serverName}] not started`));
63809
63857
  const id3 = this.nextId++;
63810
- return new Promise((resolve10, reject) => {
63858
+ return new Promise((resolve11, reject) => {
63811
63859
  const timer = setTimeout(() => {
63812
63860
  this.pending.delete(id3);
63813
63861
  reject(
@@ -63816,7 +63864,7 @@ var init_mcpClient = __esm({
63816
63864
  )
63817
63865
  );
63818
63866
  }, timeoutMs2);
63819
- this.pending.set(id3, { resolve: resolve10, reject, timer });
63867
+ this.pending.set(id3, { resolve: resolve11, reject, timer });
63820
63868
  if (transport) {
63821
63869
  void transport.send({ id: id3, method, params }, timeoutMs2);
63822
63870
  } else {
@@ -67002,12 +67050,12 @@ function startPermissionBroker(socketPath, handlers, opts) {
67002
67050
  });
67003
67051
  }
67004
67052
  }
67005
- return new Promise((resolve10, reject) => {
67053
+ return new Promise((resolve11, reject) => {
67006
67054
  const onError = (err) => reject(err);
67007
67055
  server.once("error", onError);
67008
67056
  server.listen(path104, () => {
67009
67057
  server.removeListener("error", onError);
67010
- resolve10({
67058
+ resolve11({
67011
67059
  socketPath: path104,
67012
67060
  stop: () => new Promise((res) => {
67013
67061
  for (const s of sockets) s.destroy();
@@ -67035,7 +67083,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
67035
67083
  const path104 = safeSocketPath(socketPath);
67036
67084
  const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
67037
67085
  const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
67038
- return new Promise((resolve10, reject) => {
67086
+ return new Promise((resolve11, reject) => {
67039
67087
  const socket = connect(path104);
67040
67088
  let buffer = "";
67041
67089
  let settled = false;
@@ -67088,7 +67136,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
67088
67136
  }
67089
67137
  if (msg?.t === "answer" && msg.id === ask.id) {
67090
67138
  const { t: _t, id: _id, ...answer } = msg;
67091
- settle(() => resolve10(answer));
67139
+ settle(() => resolve11(answer));
67092
67140
  return;
67093
67141
  }
67094
67142
  }
@@ -67867,7 +67915,7 @@ __export(prereqChecks_exports, {
67867
67915
  isWslBashPath: () => isWslBashPath2,
67868
67916
  runPrereqChecks: () => runPrereqChecks
67869
67917
  });
67870
- import { execSync, spawnSync as spawnSync2 } from "node:child_process";
67918
+ import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
67871
67919
  import { existsSync as existsSync54 } from "node:fs";
67872
67920
  import { dirname as dirname13 } from "node:path";
67873
67921
  function isWslBashPath2(p3) {
@@ -68027,7 +68075,7 @@ function probeTool(tool) {
68027
68075
  }
68028
68076
  } else if (process.platform === "win32") {
68029
68077
  try {
68030
- stdout = execSync(`${tool} --version`, {
68078
+ stdout = execSync2(`${tool} --version`, {
68031
68079
  encoding: "utf8",
68032
68080
  stdio: ["ignore", "pipe", "ignore"],
68033
68081
  env
@@ -68036,7 +68084,7 @@ function probeTool(tool) {
68036
68084
  }
68037
68085
  } else {
68038
68086
  try {
68039
- stdout = execSync(`${tool} --version`, {
68087
+ stdout = execSync2(`${tool} --version`, {
68040
68088
  encoding: "utf8",
68041
68089
  stdio: ["ignore", "pipe", "ignore"],
68042
68090
  env
@@ -68161,7 +68209,7 @@ function checkAgentBash() {
68161
68209
  }
68162
68210
  function checkMainNode() {
68163
68211
  try {
68164
- const raw = execSync("node --version", {
68212
+ const raw = execSync2("node --version", {
68165
68213
  encoding: "utf8",
68166
68214
  stdio: ["ignore", "pipe", "ignore"]
68167
68215
  }).trim();
@@ -68221,7 +68269,7 @@ var MIN_NODE_MAJOR, STANDARD_BASH_PATHS2, POWERSHELL_EXES2, STANDARD_POWERSHELL_
68221
68269
  var init_prereqChecks = __esm({
68222
68270
  "src/cli/utils/prereqChecks.ts"() {
68223
68271
  "use strict";
68224
- MIN_NODE_MAJOR = 24;
68272
+ MIN_NODE_MAJOR = 20;
68225
68273
  STANDARD_BASH_PATHS2 = [
68226
68274
  "C:\\Program Files\\Git\\bin\\bash.exe",
68227
68275
  "C:\\Program Files\\Git\\usr\\bin\\bash.exe",
@@ -74136,8 +74184,8 @@ async function startMemoryMcpServer(options) {
74136
74184
  let stopped = false;
74137
74185
  let finalizePromise;
74138
74186
  let resolveClosed = () => void 0;
74139
- const closed = new Promise((resolve10) => {
74140
- resolveClosed = resolve10;
74187
+ const closed = new Promise((resolve11) => {
74188
+ resolveClosed = resolve11;
74141
74189
  });
74142
74190
  const adapter = new MemoryMcpAdapter({
74143
74191
  service,
@@ -74284,8 +74332,8 @@ function startPermissionMcpServer(opts) {
74284
74332
  });
74285
74333
  let closedResolve = () => {
74286
74334
  };
74287
- const closed = new Promise((resolve10) => {
74288
- closedResolve = resolve10;
74335
+ const closed = new Promise((resolve11) => {
74336
+ closedResolve = resolve11;
74289
74337
  });
74290
74338
  let stopped = false;
74291
74339
  const send = (obj) => {
@@ -74541,9 +74589,10 @@ import {
74541
74589
  existsSync as existsSync61,
74542
74590
  mkdirSync as mkdirSync24,
74543
74591
  readFileSync as readFileSync45,
74592
+ statSync as statSync10,
74544
74593
  writeFileSync as writeFileSync26
74545
74594
  } from "node:fs";
74546
- import { join as join48 } from "node:path";
74595
+ import { join as join48, resolve as resolve9 } from "node:path";
74547
74596
  import { createHash as createHash26, randomBytes as randomBytes7, timingSafeEqual } from "node:crypto";
74548
74597
  function getZelariHome() {
74549
74598
  return zelariHome();
@@ -74632,6 +74681,30 @@ function slugFromPath(p3) {
74632
74681
  const base2 = p3.replace(/[/\\]+$/, "").split(/[/\\]/).pop() || "project";
74633
74682
  return base2.toLowerCase().replace(/[^a-z0-9-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48) || "project";
74634
74683
  }
74684
+ function resolveFsDirectory(rawPath) {
74685
+ const trimmed = rawPath.trim();
74686
+ if (!trimmed) return { ok: false, error: "cwd is required" };
74687
+ const norm = trimmed.replace(/\\/g, "/");
74688
+ const absolute = /^([a-zA-Z]:\/|\/)/.test(norm);
74689
+ if (!absolute || norm.split("/").includes("..")) {
74690
+ return {
74691
+ ok: false,
74692
+ error: `cwd must be an absolute path without '..': ${trimmed}`
74693
+ };
74694
+ }
74695
+ let stat8;
74696
+ try {
74697
+ stat8 = statSync10(trimmed);
74698
+ } catch {
74699
+ return { ok: false, error: `path not found: ${trimmed}` };
74700
+ }
74701
+ if (!stat8.isDirectory()) {
74702
+ return { ok: false, error: `not a directory: ${trimmed}` };
74703
+ }
74704
+ const abs = resolve9(trimmed);
74705
+ const slug = slugFromPath(abs);
74706
+ return { ok: true, project: { id: slug, name: slug, path: abs } };
74707
+ }
74635
74708
  function mergeProjects(cfg, extraPaths) {
74636
74709
  const byId = /* @__PURE__ */ new Map();
74637
74710
  for (const p3 of cfg.projects) {
@@ -74653,24 +74726,24 @@ function mergeProjects(cfg, extraPaths) {
74653
74726
  }
74654
74727
  return [...byId.values()];
74655
74728
  }
74656
- function resolveProjectPath(projects, cwdOrId) {
74657
- if (!projects.length) {
74729
+ function resolveProjectPath(projects, cwdOrId, opts = {}) {
74730
+ const key = String(cwdOrId ?? "").trim();
74731
+ if (!projects.length && !(opts.fullFs && key)) {
74658
74732
  return {
74659
74733
  ok: false,
74660
74734
  error: "No projects configured. Pass --project <path> or edit ~/.zelari-code/companion.json"
74661
74735
  };
74662
74736
  }
74663
- if (!cwdOrId || !String(cwdOrId).trim()) {
74664
- return { ok: true, project: projects[0] };
74737
+ if (!key) {
74738
+ return { ok: true, project: projects[0], trusted: true };
74665
74739
  }
74666
- const key = String(cwdOrId).trim();
74667
74740
  const byId = projects.find((p3) => p3.id === key || p3.name === key);
74668
- if (byId) return { ok: true, project: byId };
74741
+ if (byId) return { ok: true, project: byId, trusted: true };
74669
74742
  const norm = key.replace(/\\/g, "/").toLowerCase();
74670
74743
  const byPath = projects.find(
74671
74744
  (p3) => p3.path.replace(/\\/g, "/").toLowerCase() === norm
74672
74745
  );
74673
- if (byPath) return { ok: true, project: byPath };
74746
+ if (byPath) return { ok: true, project: byPath, trusted: true };
74674
74747
  const under = projects.find((p3) => {
74675
74748
  const root = p3.path.replace(/\\/g, "/").toLowerCase().replace(/\/$/, "");
74676
74749
  return norm === root || norm.startsWith(root + "/");
@@ -74678,14 +74751,31 @@ function resolveProjectPath(projects, cwdOrId) {
74678
74751
  if (under) {
74679
74752
  return {
74680
74753
  ok: true,
74681
- project: { ...under, path: key }
74754
+ project: { ...under, path: key },
74755
+ trusted: true
74682
74756
  };
74683
74757
  }
74758
+ if (opts.fullFs) {
74759
+ const dir = resolveFsDirectory(key);
74760
+ if (dir.ok) return { ok: true, project: dir.project, trusted: false };
74761
+ return { ok: false, error: dir.error };
74762
+ }
74684
74763
  return {
74685
74764
  ok: false,
74686
74765
  error: `cwd/project not in allowlist: ${key}. Allowed: ${projects.map((p3) => p3.id).join(", ")}`
74687
74766
  };
74688
74767
  }
74768
+ function isUnderRoots(rawPath, projects) {
74769
+ const norm = rawPath.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
74770
+ if (!norm || norm.split("/").includes("..")) return { ok: false };
74771
+ for (const p3 of projects) {
74772
+ const root = p3.path.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
74773
+ if (norm === root || norm.startsWith(root + "/")) {
74774
+ return { ok: true, root: p3, normalized: norm };
74775
+ }
74776
+ }
74777
+ return { ok: false };
74778
+ }
74689
74779
  var DEFAULT_COMPANION_PORT, DEFAULT_COMPANION_BIND;
74690
74780
  var init_config = __esm({
74691
74781
  "src/cli/companion/config.ts"() {
@@ -74735,12 +74825,12 @@ function createServePermissionBridge(write, timeoutMs2 = 12e4) {
74735
74825
  onPermissionAsk(payload) {
74736
74826
  const requestId = `perm-${Date.now()}-${++seq}`;
74737
74827
  const categories = payload.categories && payload.categories.length > 0 ? payload.categories : payload.category ? payload.category.split(",").map((c) => c.trim()).filter(Boolean) : [];
74738
- return new Promise((resolve10) => {
74828
+ return new Promise((resolve11) => {
74739
74829
  const timer = setTimeout(() => {
74740
74830
  settle(requestId, "deny", true);
74741
74831
  }, timeoutMs2);
74742
74832
  const sessionId2 = getCurrentHarnessSessionId();
74743
- pending.set(requestId, { resolve: resolve10, timer, payload, sessionId: sessionId2 });
74833
+ pending.set(requestId, { resolve: resolve11, timer, payload, sessionId: sessionId2 });
74744
74834
  write(
74745
74835
  JSON.stringify({
74746
74836
  type: "permission.request",
@@ -74865,12 +74955,12 @@ function createServeAskUserBridge(write, timeoutMs2 = askUserTimeoutMs()) {
74865
74955
  const choices = req.choices.map((c) => c.trim()).filter(Boolean);
74866
74956
  if (choices.length < 2) return Promise.resolve(null);
74867
74957
  const requestId = `ask-${Date.now()}-${++seq}`;
74868
- return new Promise((resolve10) => {
74958
+ return new Promise((resolve11) => {
74869
74959
  const timer = setTimeout(() => {
74870
74960
  settle(requestId, null, true);
74871
74961
  }, timeoutMs2);
74872
74962
  const sessionId2 = getCurrentHarnessSessionId();
74873
- pending.set(requestId, { resolve: resolve10, timer, sessionId: sessionId2 });
74963
+ pending.set(requestId, { resolve: resolve11, timer, sessionId: sessionId2 });
74874
74964
  write(
74875
74965
  JSON.stringify({
74876
74966
  type: "ask_user.request",
@@ -75374,8 +75464,8 @@ var init_harnessClient = __esm({
75374
75464
  );
75375
75465
  }
75376
75466
  const id3 = this.nextId++;
75377
- return new Promise((resolve10, reject) => {
75378
- this.pending.set(id3, { resolve: resolve10, reject });
75467
+ return new Promise((resolve11, reject) => {
75468
+ this.pending.set(id3, { resolve: resolve11, reject });
75379
75469
  this.transport.write(JSON.stringify({ id: id3, method, params }));
75380
75470
  });
75381
75471
  }
@@ -75401,6 +75491,18 @@ var init_harnessClient = __esm({
75401
75491
  if (reason !== void 0) params["reason"] = reason;
75402
75492
  return await this.request("session.cancel", params);
75403
75493
  }
75494
+ /** t63: settle a permission.request (allow/deny/always-tool/always-category). */
75495
+ async permissionRespond(requestId, decision, sessionId2) {
75496
+ const params = { requestId, decision };
75497
+ if (sessionId2 !== void 0) params["sessionId"] = sessionId2;
75498
+ return await this.request("permission.respond", params);
75499
+ }
75500
+ /** t63: settle an ask_user.request (null = dismiss). */
75501
+ async askUserRespond(requestId, answer, sessionId2) {
75502
+ const params = { requestId, answer };
75503
+ if (sessionId2 !== void 0) params["sessionId"] = sessionId2;
75504
+ return await this.request("ask_user.respond", params);
75505
+ }
75404
75506
  async disposeSession(sessionId2) {
75405
75507
  await this.request("session.dispose", { sessionId: sessionId2 });
75406
75508
  }
@@ -75430,6 +75532,9 @@ import { tmpdir as tmpdir4 } from "node:os";
75430
75532
  function harnessServerMode() {
75431
75533
  return process.env[HARNESS_SERVER_ENV] === "1";
75432
75534
  }
75535
+ function isPermissionRequestEvent(ev) {
75536
+ return typeof ev === "object" && ev !== null && ev.type === "permission.request";
75537
+ }
75433
75538
  var HARNESS_SERVER_ENV, RunManager;
75434
75539
  var init_runManager = __esm({
75435
75540
  "src/cli/companion/runManager.ts"() {
@@ -75487,6 +75592,13 @@ var init_runManager = __esm({
75487
75592
  }
75488
75593
  emit(ev) {
75489
75594
  if (!this.active) return;
75595
+ if (this.active.permissionPreset === "yolo" && isPermissionRequestEvent(ev)) {
75596
+ const requestId = ev.requestId;
75597
+ if (typeof requestId === "string" && requestId.trim()) {
75598
+ void this.permissionRespond(this.active.run.id, requestId, "allow");
75599
+ return;
75600
+ }
75601
+ }
75490
75602
  this.active.run.events.push(ev);
75491
75603
  if (this.active.run.events.length > 5e3) {
75492
75604
  this.active.run.events.splice(0, this.active.run.events.length - 4e3);
@@ -75498,7 +75610,7 @@ var init_runManager = __esm({
75498
75610
  }
75499
75611
  }
75500
75612
  }
75501
- start(args) {
75613
+ start(args, gate) {
75502
75614
  if (this.active) {
75503
75615
  return {
75504
75616
  ok: false,
@@ -75520,9 +75632,79 @@ var init_runManager = __esm({
75520
75632
  createdAt: Date.now(),
75521
75633
  events: []
75522
75634
  };
75635
+ if (gate?.awaitingTrust) {
75636
+ run.status = "awaiting_trust";
75637
+ this.active = {
75638
+ run,
75639
+ listeners: /* @__PURE__ */ new Set(),
75640
+ trustArgs: args,
75641
+ trustMode: this.clientMode ? "harness" : "spawn",
75642
+ permissionPreset: args.permissionPreset
75643
+ };
75644
+ this.emit({
75645
+ type: "trust.pending",
75646
+ runId: id3,
75647
+ path: args.cwd,
75648
+ message: `[companion] run ${id3} awaiting desktop trust approval for ${args.cwd}`
75649
+ });
75650
+ return { ok: true, run, awaitingTrust: true };
75651
+ }
75523
75652
  if (this.clientMode) {
75524
75653
  return this.startViaHarness(run, args, mode, phase2);
75525
75654
  }
75655
+ return this.launchSpawn(run, args);
75656
+ }
75657
+ /**
75658
+ * t66: desktop approved the parked run — launch it now, preserving the
75659
+ * listeners (phone SSE) attached while it was awaiting trust.
75660
+ */
75661
+ releaseTrust() {
75662
+ const a = this.active;
75663
+ if (!a || a.run.status !== "awaiting_trust" || !a.trustArgs) {
75664
+ return { ok: false, error: "no run awaiting trust" };
75665
+ }
75666
+ const args = a.trustArgs;
75667
+ a.run.status = "running";
75668
+ this.emit({ type: "trust.settled", runId: a.run.id, approved: true });
75669
+ if (a.trustMode === "harness") {
75670
+ return this.startViaHarness(a.run, args, a.run.mode, a.run.phase);
75671
+ }
75672
+ return this.launchSpawn(a.run, args);
75673
+ }
75674
+ /** t66: desktop denied the parked run — fail it, fail-closed. */
75675
+ denyTrust(reason) {
75676
+ const a = this.active;
75677
+ if (!a || a.run.status !== "awaiting_trust") {
75678
+ return { ok: false, error: "no run awaiting trust" };
75679
+ }
75680
+ a.run.status = "error";
75681
+ a.run.error = reason;
75682
+ a.run.finishedAt = Date.now();
75683
+ this.emit({ type: "trust.settled", runId: a.run.id, approved: false });
75684
+ this.emit({
75685
+ type: "error",
75686
+ severity: "fatal",
75687
+ message: reason,
75688
+ code: "trust_denied"
75689
+ });
75690
+ this.emit({
75691
+ type: "run_finished",
75692
+ runId: a.run.id,
75693
+ status: "error",
75694
+ exitCode: null
75695
+ });
75696
+ this.finishActive();
75697
+ return { ok: true };
75698
+ }
75699
+ /** t66: current awaiting_trust run (if any) for GET /v1/trust/pending. */
75700
+ pendingTrust() {
75701
+ const a = this.active;
75702
+ if (!a || a.run.status !== "awaiting_trust") return null;
75703
+ return { runId: a.run.id, path: a.run.cwd };
75704
+ }
75705
+ /** t66: spawn-path launch, extracted from start() so releaseTrust can
75706
+ * launch a parked run. Preserves parked listeners (same run id). */
75707
+ launchSpawn(run, args) {
75526
75708
  const cliEntry = process.argv[1];
75527
75709
  if (!cliEntry) {
75528
75710
  return { ok: false, error: "Cannot resolve CLI entry (process.argv[1])" };
@@ -75531,13 +75713,13 @@ var init_runManager = __esm({
75531
75713
  cliEntry,
75532
75714
  "--headless",
75533
75715
  "--task",
75534
- prompt,
75716
+ run.prompt,
75535
75717
  "--output",
75536
75718
  "json",
75537
75719
  "--mode",
75538
- mode === "council" || mode === "zelari" ? mode : "kraken",
75720
+ run.mode === "council" || run.mode === "zelari" ? run.mode : "kraken",
75539
75721
  "--phase",
75540
- phase2 === "plan" ? "plan" : "build"
75722
+ run.phase === "plan" ? "plan" : "build"
75541
75723
  ];
75542
75724
  if (args.provider?.trim()) {
75543
75725
  argv.push("--provider", args.provider.trim());
@@ -75545,9 +75727,14 @@ var init_runManager = __esm({
75545
75727
  if (args.model?.trim()) {
75546
75728
  argv.push("--model", args.model.trim());
75547
75729
  }
75730
+ if (args.strictDone === true) argv.push("--strict-done");
75731
+ else if (args.strictDone === false) argv.push("--no-strict-done");
75732
+ if (args.permissionPreset) {
75733
+ argv.push("--permissions", args.permissionPreset);
75734
+ }
75548
75735
  let historyFile;
75549
75736
  if (args.history && Array.isArray(args.history) && args.history.length > 0) {
75550
- historyFile = join49(tmpdir4(), `zelari-companion-hist-${id3}.json`);
75737
+ historyFile = join49(tmpdir4(), `zelari-companion-hist-${run.id}.json`);
75551
75738
  try {
75552
75739
  writeFileSync27(historyFile, JSON.stringify(args.history), "utf8");
75553
75740
  argv.push("--history-file", historyFile);
@@ -75561,15 +75748,26 @@ var init_runManager = __esm({
75561
75748
  ...process.env,
75562
75749
  ZELARI_SKIP_PREFLIGHT: "1",
75563
75750
  ANATHEMA_DEV: "1",
75564
- FORCE_COLOR: "0"
75751
+ FORCE_COLOR: "0",
75752
+ // t65: belt-and-suspenders — the long-lived headless child reads the
75753
+ // preset straight from env even if it never re-parses --permissions;
75754
+ // mirrors main.ts's --permissions → ZELARI_PERMISSION_PRESET promotion.
75755
+ ...args.permissionPreset ? { ZELARI_PERMISSION_PRESET: args.permissionPreset } : {}
75565
75756
  },
75566
75757
  stdio: ["ignore", "pipe", "pipe"],
75567
75758
  windowsHide: true
75568
75759
  });
75569
- this.active = { run, child, listeners: /* @__PURE__ */ new Set(), historyFile };
75760
+ const parked = this.active?.run.id === run.id ? this.active : null;
75761
+ this.active = {
75762
+ run,
75763
+ child,
75764
+ listeners: parked?.listeners ?? /* @__PURE__ */ new Set(),
75765
+ historyFile,
75766
+ permissionPreset: args.permissionPreset
75767
+ };
75570
75768
  this.emit({
75571
75769
  type: "log",
75572
- message: `[companion] run ${id3} started mode=${mode} phase=${phase2} cwd=${args.cwd}`
75770
+ message: `[companion] run ${run.id} started mode=${run.mode} phase=${run.phase} cwd=${args.cwd}`
75573
75771
  });
75574
75772
  if (child.stdout) {
75575
75773
  const rl = createInterface4({ input: child.stdout });
@@ -75616,7 +75814,7 @@ var init_runManager = __esm({
75616
75814
  }
75617
75815
  this.emit({
75618
75816
  type: "run_finished",
75619
- runId: id3,
75817
+ runId: run.id,
75620
75818
  status: run.status,
75621
75819
  exitCode: code
75622
75820
  });
@@ -75631,7 +75829,12 @@ var init_runManager = __esm({
75631
75829
  * reports through the usual run status + emit path.
75632
75830
  */
75633
75831
  startViaHarness(run, args, mode, phase2) {
75634
- this.active = { run, listeners: /* @__PURE__ */ new Set() };
75832
+ const parked = this.active?.run.id === run.id ? this.active : null;
75833
+ this.active = {
75834
+ run,
75835
+ listeners: parked?.listeners ?? /* @__PURE__ */ new Set(),
75836
+ permissionPreset: args.permissionPreset
75837
+ };
75635
75838
  this.emit({
75636
75839
  type: "log",
75637
75840
  message: `[companion] run ${run.id} started mode=${mode} phase=${phase2} cwd=${args.cwd}`
@@ -75679,6 +75882,9 @@ var init_runManager = __esm({
75679
75882
  if (Array.isArray(args.history) && args.history.length > 0) {
75680
75883
  turnInput["history"] = args.history;
75681
75884
  }
75885
+ if (args.permissionPreset) turnInput["permissionPreset"] = args.permissionPreset;
75886
+ if (args.strictDone !== void 0) turnInput["strictDone"] = args.strictDone;
75887
+ if (args.verifyPack !== void 0) turnInput["verifyPack"] = args.verifyPack;
75682
75888
  const result = await client.runTurn(sessionId2, turnInput);
75683
75889
  const stillOwner = this.active?.run.id === run.id;
75684
75890
  if (stillOwner && run.status === "running") {
@@ -75779,6 +75985,51 @@ var init_runManager = __esm({
75779
75985
  return { ok: false, error: err instanceof Error ? err.message : String(err) };
75780
75986
  }
75781
75987
  }
75988
+ /** t63: settle a permission.request on the active client-mode run. */
75989
+ async permissionRespond(runId, requestId, decision) {
75990
+ if (!this.active) return { ok: false, error: "No active run" };
75991
+ if (runId && this.active.run.id !== runId) {
75992
+ return { ok: false, error: `Run ${runId} is not active` };
75993
+ }
75994
+ const id3 = requestId?.trim();
75995
+ if (!id3) return { ok: false, error: "requestId is required" };
75996
+ if (!this.active.harnessSessionId || !this.harnessClient) {
75997
+ return {
75998
+ ok: false,
75999
+ error: `permission respond requires harness server mode (${HARNESS_SERVER_ENV}=1)`
76000
+ };
76001
+ }
76002
+ try {
76003
+ const result = await this.harnessClient.permissionRespond(id3, decision);
76004
+ return { ok: true, result };
76005
+ } catch (err) {
76006
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
76007
+ }
76008
+ }
76009
+ /** t63: settle an ask_user.request (answer null = dismiss). */
76010
+ async askUserRespond(runId, requestId, answer) {
76011
+ if (!this.active) return { ok: false, error: "No active run" };
76012
+ if (runId && this.active.run.id !== runId) {
76013
+ return { ok: false, error: `Run ${runId} is not active` };
76014
+ }
76015
+ const id3 = requestId?.trim();
76016
+ if (!id3) return { ok: false, error: "requestId is required" };
76017
+ if (answer != null && typeof answer !== "string") {
76018
+ return { ok: false, error: "answer must be a string or null" };
76019
+ }
76020
+ if (!this.active.harnessSessionId || !this.harnessClient) {
76021
+ return {
76022
+ ok: false,
76023
+ error: `ask respond requires harness server mode (${HARNESS_SERVER_ENV}=1)`
76024
+ };
76025
+ }
76026
+ try {
76027
+ const result = await this.harnessClient.askUserRespond(id3, answer);
76028
+ return { ok: true, result };
76029
+ } catch (err) {
76030
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
76031
+ }
76032
+ }
75782
76033
  cancel(runId) {
75783
76034
  if (!this.active) {
75784
76035
  return { ok: false, error: "No active run" };
@@ -75870,8 +76121,8 @@ __export(serve_exports, {
75870
76121
  runCompanionServe: () => runCompanionServe
75871
76122
  });
75872
76123
  import { createServer as createServer3 } from "node:http";
75873
- import { existsSync as existsSync62 } from "node:fs";
75874
- import { resolve as resolve9 } from "node:path";
76124
+ import { existsSync as existsSync62, readdirSync as readdirSync13 } from "node:fs";
76125
+ import { join as join50, resolve as resolve10 } from "node:path";
75875
76126
  function readBody(req, max = 2e6) {
75876
76127
  return new Promise((resolveBody, reject) => {
75877
76128
  const chunks = [];
@@ -75918,7 +76169,7 @@ async function runCompanionServe(opts = {}) {
75918
76169
  const { token, created } = loadOrCreateToken(opts.token);
75919
76170
  let projects = mergeProjects(fileCfg, opts.projects ?? []);
75920
76171
  projects = projects.filter((p3) => {
75921
- const abs = resolve9(p3.path);
76172
+ const abs = resolve10(p3.path);
75922
76173
  if (!existsSync62(abs)) {
75923
76174
  process.stderr.write(
75924
76175
  `[zelari-code serve] skip missing project path: ${p3.path}
@@ -75938,7 +76189,7 @@ async function runCompanionServe(opts = {}) {
75938
76189
  });
75939
76190
  }
75940
76191
  if (projects.length === 0) {
75941
- const cwd = resolve9(process.cwd());
76192
+ const cwd = resolve10(process.cwd());
75942
76193
  projects = [
75943
76194
  {
75944
76195
  id: "default",
@@ -75954,6 +76205,7 @@ async function runCompanionServe(opts = {}) {
75954
76205
  );
75955
76206
  }
75956
76207
  const runs = new RunManager();
76208
+ const fsFull = (opts.fsMode ?? "full") === "full";
75957
76209
  const allowedOrigins = [
75958
76210
  ...loopbackOrigins(port),
75959
76211
  ...parseAllowedOrigins(process.env[COMPANION_ALLOWED_ORIGINS_ENV])
@@ -75995,6 +76247,65 @@ async function runCompanionServe(opts = {}) {
75995
76247
  sendJson2(res, 200, { ok: true, ...snap });
75996
76248
  return;
75997
76249
  }
76250
+ if (req.method === "GET" && path104 === "/v1/fs") {
76251
+ const listFsRootsInline = () => {
76252
+ if (process.platform === "win32") {
76253
+ const roots = [];
76254
+ for (let code = 65; code <= 90; code++) {
76255
+ const letter = String.fromCharCode(code);
76256
+ const drive = `${letter}:\\`;
76257
+ if (existsSync62(drive)) {
76258
+ roots.push({
76259
+ id: `fs-${letter.toLowerCase()}`,
76260
+ name: drive,
76261
+ path: drive
76262
+ });
76263
+ }
76264
+ }
76265
+ return roots;
76266
+ }
76267
+ return [{ id: "fs-root", name: "/", path: "/" }];
76268
+ };
76269
+ const rawParam = url2.searchParams.get("path")?.trim() ?? "";
76270
+ if (!rawParam) {
76271
+ sendJson2(res, 200, {
76272
+ ok: true,
76273
+ roots: fsFull ? listFsRootsInline() : projects,
76274
+ entries: []
76275
+ });
76276
+ return;
76277
+ }
76278
+ const norm = rawParam.replace(/\\/g, "/").replace(/\/+$/, "");
76279
+ const absolute = /^([a-zA-Z]:\/|\/)/.test(norm);
76280
+ const allowed = fsFull && absolute && !norm.split("/").includes("..") ? true : isUnderRoots(rawParam, projects).ok;
76281
+ if (!allowed) {
76282
+ sendJson2(res, 403, { ok: false, error: "path outside allowed roots" });
76283
+ return;
76284
+ }
76285
+ if (!existsSync62(rawParam)) {
76286
+ sendJson2(res, 404, { ok: false, error: "path not found" });
76287
+ return;
76288
+ }
76289
+ const dirs = readdirSync13(rawParam, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).sort((a, b) => a.name.localeCompare(b.name));
76290
+ const slash = norm.lastIndexOf("/");
76291
+ let parent = slash > 0 ? norm.slice(0, slash) : null;
76292
+ const rootHit = isUnderRoots(rawParam, projects);
76293
+ if (rootHit.ok) {
76294
+ const rootNorm = rootHit.root.path.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
76295
+ if (rootHit.normalized === rootNorm) parent = null;
76296
+ }
76297
+ sendJson2(res, 200, {
76298
+ ok: true,
76299
+ path: rawParam,
76300
+ parent,
76301
+ entries: dirs.map((d) => ({
76302
+ name: d.name,
76303
+ path: join50(rawParam, d.name),
76304
+ dir: true
76305
+ }))
76306
+ });
76307
+ return;
76308
+ }
75998
76309
  if (req.method === "GET" && path104 === "/v1/projects") {
75999
76310
  sendJson2(res, 200, {
76000
76311
  ok: true,
@@ -76037,27 +76348,37 @@ async function runCompanionServe(opts = {}) {
76037
76348
  const mode = String(body.mode ?? "kraken");
76038
76349
  const phase2 = String(body.phase ?? "build");
76039
76350
  const cwdArg = body.cwd != null ? String(body.cwd) : body.projectId != null ? String(body.projectId) : null;
76040
- const resolved = resolveProjectPath(projects, cwdArg);
76351
+ const resolved = resolveProjectPath(projects, cwdArg, { fullFs: fsFull });
76041
76352
  if (!resolved.ok) {
76042
76353
  sendJson2(res, 400, { ok: false, error: resolved.error });
76043
76354
  return;
76044
76355
  }
76045
76356
  const history2 = Array.isArray(body.history) ? body.history : void 0;
76046
- const result = runs.start({
76357
+ const presetRaw = typeof body.permissionPreset === "string" ? body.permissionPreset.trim().toLowerCase() : "";
76358
+ const permissionPreset = ["standard", "strict", "yolo"].includes(presetRaw) ? presetRaw : void 0;
76359
+ const strictDone = typeof body.strictDone === "boolean" ? body.strictDone : void 0;
76360
+ const verifyPack = typeof body.verifyPack === "boolean" ? body.verifyPack : void 0;
76361
+ const startArgs = {
76047
76362
  prompt,
76048
76363
  mode,
76049
76364
  phase: phase2,
76050
76365
  cwd: resolved.project.path,
76051
76366
  provider: body.provider != null ? String(body.provider) : void 0,
76052
76367
  model: body.model != null ? String(body.model) : void 0,
76053
- history: history2
76054
- });
76368
+ history: history2,
76369
+ permissionPreset,
76370
+ strictDone,
76371
+ verifyPack
76372
+ };
76373
+ const gate = fsFull && !resolved.trusted ? { awaitingTrust: true } : void 0;
76374
+ const result = runs.start(startArgs, gate);
76055
76375
  if (!result.ok) {
76056
76376
  sendJson2(res, 409, { ok: false, error: result.error });
76057
76377
  return;
76058
76378
  }
76059
76379
  sendJson2(res, 201, {
76060
76380
  ok: true,
76381
+ awaitingTrust: gate ? true : void 0,
76061
76382
  run: {
76062
76383
  id: result.run.id,
76063
76384
  status: result.run.status,
@@ -76068,10 +76389,57 @@ async function runCompanionServe(opts = {}) {
76068
76389
  },
76069
76390
  eventsUrl: `/v1/runs/${result.run.id}/events`,
76070
76391
  cancelUrl: `/v1/runs/${result.run.id}/cancel`,
76071
- steerUrl: `/v1/runs/${result.run.id}/steer`
76392
+ steerUrl: `/v1/runs/${result.run.id}/steer`,
76393
+ permissionUrl: `/v1/runs/${result.run.id}/permission`,
76394
+ askUrl: `/v1/runs/${result.run.id}/ask`
76072
76395
  });
76073
76396
  return;
76074
76397
  }
76398
+ if (req.method === "POST" && path104 === "/v1/trust") {
76399
+ const raw = await readBody(req);
76400
+ let body = {};
76401
+ try {
76402
+ body = raw ? JSON.parse(raw) : {};
76403
+ } catch {
76404
+ sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
76405
+ return;
76406
+ }
76407
+ const runId = typeof body.runId === "string" ? body.runId.trim() : "";
76408
+ if (!runId) {
76409
+ sendJson2(res, 400, { ok: false, error: "runId is required" });
76410
+ return;
76411
+ }
76412
+ const current = runs.pendingTrust();
76413
+ if (!current || current.runId !== runId) {
76414
+ sendJson2(res, 409, { ok: false, error: "no such awaiting_trust run" });
76415
+ return;
76416
+ }
76417
+ if (body.approve === true) {
76418
+ projects = mergeProjects({ ...fileCfg, projects }, [current.path]);
76419
+ try {
76420
+ saveCompanionConfig({ ...fileCfg, bind, port, projects });
76421
+ } catch {
76422
+ }
76423
+ const released = runs.releaseTrust();
76424
+ if (!released.ok) {
76425
+ sendJson2(res, 409, { ok: false, error: released.error });
76426
+ return;
76427
+ }
76428
+ sendJson2(res, 200, { ok: true, approved: runId, path: current.path });
76429
+ return;
76430
+ }
76431
+ const denied = runs.denyTrust("Trust negato sul desktop");
76432
+ if (!denied.ok) {
76433
+ sendJson2(res, 409, { ok: false, error: denied.error });
76434
+ return;
76435
+ }
76436
+ sendJson2(res, 200, { ok: true, denied: runId });
76437
+ return;
76438
+ }
76439
+ if (req.method === "GET" && path104 === "/v1/trust/pending") {
76440
+ sendJson2(res, 200, { ok: true, pending: runs.pendingTrust() });
76441
+ return;
76442
+ }
76075
76443
  const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path104);
76076
76444
  if (req.method === "GET" && eventsMatch) {
76077
76445
  const runId = eventsMatch[1];
@@ -76099,7 +76467,7 @@ async function runCompanionServe(opts = {}) {
76099
76467
  }
76100
76468
  };
76101
76469
  const unsub = runs.subscribe(runId, writeEv);
76102
- if (run.status !== "running" && run.status !== "queued") {
76470
+ if (run.status !== "running" && run.status !== "queued" && run.status !== "awaiting_trust") {
76103
76471
  writeEv({
76104
76472
  type: "run_finished",
76105
76473
  runId,
@@ -76125,7 +76493,7 @@ async function runCompanionServe(opts = {}) {
76125
76493
  req.on("close", onClose);
76126
76494
  const check2 = setInterval(() => {
76127
76495
  const r = runs.getRun(runId);
76128
- if (!r || r.status !== "running" && r.status !== "queued") {
76496
+ if (!r || r.status !== "running" && r.status !== "queued" && r.status !== "awaiting_trust") {
76129
76497
  clearInterval(check2);
76130
76498
  clearInterval(heartbeat);
76131
76499
  unsub();
@@ -76172,6 +76540,53 @@ async function runCompanionServe(opts = {}) {
76172
76540
  sendJson2(res, 200, { ok: true, steered: runId, result: result.result });
76173
76541
  return;
76174
76542
  }
76543
+ const askMatch = /^\/v1\/runs\/([^/]+)\/(permission|ask)$/.exec(path104);
76544
+ if (req.method === "POST" && askMatch) {
76545
+ const runId = askMatch[1];
76546
+ const kind2 = askMatch[2];
76547
+ const raw = await readBody(req);
76548
+ let body = {};
76549
+ try {
76550
+ body = raw ? JSON.parse(raw) : {};
76551
+ } catch {
76552
+ sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
76553
+ return;
76554
+ }
76555
+ const requestId = typeof body.requestId === "string" ? body.requestId.trim() : "";
76556
+ if (!requestId) {
76557
+ sendJson2(res, 400, { ok: false, error: "requestId is required" });
76558
+ return;
76559
+ }
76560
+ if (kind2 === "permission") {
76561
+ const decision = typeof body.decision === "string" ? body.decision.trim() : "";
76562
+ if (!["allow", "deny", "always-tool", "always-category"].includes(decision)) {
76563
+ sendJson2(res, 400, {
76564
+ ok: false,
76565
+ error: "decision must be allow|deny|always-tool|always-category"
76566
+ });
76567
+ return;
76568
+ }
76569
+ const result2 = await runs.permissionRespond(runId, requestId, decision);
76570
+ if (!result2.ok) {
76571
+ sendJson2(res, 404, { ok: false, error: result2.error });
76572
+ return;
76573
+ }
76574
+ sendJson2(res, 200, { ok: true, runId, requestId, result: result2.result });
76575
+ return;
76576
+ }
76577
+ const answer = body.answer == null ? null : typeof body.answer === "string" ? body.answer : void 0;
76578
+ if (answer === void 0) {
76579
+ sendJson2(res, 400, { ok: false, error: "answer must be a string or null" });
76580
+ return;
76581
+ }
76582
+ const result = await runs.askUserRespond(runId, requestId, answer);
76583
+ if (!result.ok) {
76584
+ sendJson2(res, 404, { ok: false, error: result.error });
76585
+ return;
76586
+ }
76587
+ sendJson2(res, 200, { ok: true, runId, requestId, result: result.result });
76588
+ return;
76589
+ }
76175
76590
  sendJson2(res, 404, { ok: false, error: "not found" });
76176
76591
  } catch (err) {
76177
76592
  sendJson2(res, 500, {
@@ -76247,12 +76662,14 @@ function parseServeFlags(argv) {
76247
76662
  }
76248
76663
  const portRaw = get("--port");
76249
76664
  const port = portRaw ? Number.parseInt(portRaw, 10) : void 0;
76665
+ const fsRaw = get("--fs");
76250
76666
  return {
76251
76667
  bind: get("--bind"),
76252
76668
  port: Number.isFinite(port) ? port : void 0,
76253
76669
  token: get("--token"),
76254
76670
  projects,
76255
- persistProjects: argv.includes("--save-projects")
76671
+ persistProjects: argv.includes("--save-projects"),
76672
+ fsMode: fsRaw === "allowlist" ? "allowlist" : fsRaw === "full" ? "full" : void 0
76256
76673
  };
76257
76674
  }
76258
76675
  var init_serve = __esm({
@@ -76313,8 +76730,8 @@ __export(doctor_exports, {
76313
76730
  firstBlockingRed: () => firstBlockingRed,
76314
76731
  runDoctor: () => runDoctor
76315
76732
  });
76316
- import { execSync as execSync2 } from "node:child_process";
76317
- import { existsSync as existsSync63, readFileSync as readFileSync46, readlinkSync, statSync as statSync10 } from "node:fs";
76733
+ import { execSync as execSync3 } from "node:child_process";
76734
+ import { existsSync as existsSync63, readFileSync as readFileSync46, readlinkSync, statSync as statSync11 } from "node:fs";
76318
76735
  import { createRequire as createRequire3 } from "node:module";
76319
76736
  import { fileURLToPath as fileURLToPath3 } from "node:url";
76320
76737
  import path100 from "node:path";
@@ -76337,7 +76754,7 @@ function findPackageRoot(start) {
76337
76754
  }
76338
76755
  function tryExec(cmd) {
76339
76756
  try {
76340
- return execSync2(cmd, {
76757
+ return execSync3(cmd, {
76341
76758
  encoding: "utf8",
76342
76759
  stdio: ["ignore", "pipe", "ignore"]
76343
76760
  }).trim();
@@ -76353,7 +76770,7 @@ function readPackageJson4() {
76353
76770
  return null;
76354
76771
  }
76355
76772
  }
76356
- function getGlobalPrefix() {
76773
+ function getGlobalPrefix2() {
76357
76774
  const fromNpm = tryExec("npm prefix -g");
76358
76775
  if (fromNpm) return fromNpm;
76359
76776
  return (process.env.npm_config_prefix || process.env.NPM_CONFIG_PREFIX || "").trim();
@@ -76362,7 +76779,7 @@ function isSourceCheckout() {
76362
76779
  return existsSync63(path100.join(packageRoot, "src", "cli", "main.ts")) && existsSync63(path100.join(packageRoot, "apps", "desktop", "package.json"));
76363
76780
  }
76364
76781
  function checkShim(pkgName) {
76365
- const prefix = getGlobalPrefix();
76782
+ const prefix = getGlobalPrefix2();
76366
76783
  if (!prefix) {
76367
76784
  return WARN("npm global prefix not detectable (run inside an npm context)");
76368
76785
  }
@@ -76378,13 +76795,21 @@ function checkShim(pkgName) {
76378
76795
  optional: npm install -g ${pkgName}@latest --force`
76379
76796
  );
76380
76797
  }
76798
+ const installKind = resolveInstallKind();
76799
+ if (installKind === "npx" || installKind === "local") {
76800
+ return WARN(
76801
+ `non-global install (${installKind}) \u2014 no global shim at ${shimPath}
76802
+ PATH/shim expectations do not apply to an npx or local run
76803
+ for a persistent install: npm install -g ${pkgName}@latest`
76804
+ );
76805
+ }
76381
76806
  return FAIL(
76382
76807
  `shim not found at ${shimPath}
76383
76808
  fix: npm install -g ${pkgName}@latest --force`
76384
76809
  );
76385
76810
  }
76386
76811
  try {
76387
- const st = statSync10(shimPath);
76812
+ const st = statSync11(shimPath);
76388
76813
  if (isWin) {
76389
76814
  const content = readFileSync46(shimPath, "utf8");
76390
76815
  if (content.includes(`${pkgName}\\bin\\`) || content.includes(`${pkgName}/bin/`)) {
@@ -76455,7 +76880,7 @@ function checkBundle() {
76455
76880
  );
76456
76881
  }
76457
76882
  try {
76458
- const st = statSync10(bundle);
76883
+ const st = statSync11(bundle);
76459
76884
  return OK(`bundle OK (${(st.size / 1024 / 1024).toFixed(2)} MB)`);
76460
76885
  } catch (err) {
76461
76886
  return FAIL(
@@ -76485,7 +76910,7 @@ function checkRuntimeDeps() {
76485
76910
  );
76486
76911
  }
76487
76912
  function checkPath() {
76488
- const prefix = getGlobalPrefix();
76913
+ const prefix = getGlobalPrefix2();
76489
76914
  if (!prefix) return WARN("npm global prefix not detectable");
76490
76915
  const pathSep = process.platform === "win32" ? ";" : ":";
76491
76916
  const pathDirs = (process.env.PATH || "").split(pathSep);
@@ -76703,7 +77128,7 @@ async function runDoctor() {
76703
77128
  console.log(`zelari-code doctor (v${pkg?.version ?? "unknown"})`);
76704
77129
  console.log("platform:", process.platform, process.arch);
76705
77130
  console.log("node: ", process.version);
76706
- console.log("prefix: ", getGlobalPrefix() || "(unknown)");
77131
+ console.log("prefix: ", getGlobalPrefix2() || "(unknown)");
76707
77132
  console.log("root: ", packageRoot);
76708
77133
  console.log("");
76709
77134
  let criticalFails = 0;
@@ -76744,6 +77169,7 @@ var init_doctor = __esm({
76744
77169
  init_prereqChecks();
76745
77170
  init_metrics3();
76746
77171
  init_contextGrowthSummary();
77172
+ init_updater();
76747
77173
  require3 = createRequire3(import.meta.url);
76748
77174
  __dirname3 = path100.dirname(fileURLToPath3(import.meta.url));
76749
77175
  packageRoot = findPackageRoot(__dirname3);
@@ -76771,7 +77197,7 @@ __export(fixPath_exports, {
76771
77197
  repairWindowsUserPath: () => repairWindowsUserPath
76772
77198
  });
76773
77199
  import { spawnSync as spawnSync3 } from "node:child_process";
76774
- function getGlobalPrefix2() {
77200
+ function getGlobalPrefix3() {
76775
77201
  try {
76776
77202
  const fromNpm = spawnSync3("npm", ["prefix", "-g"], {
76777
77203
  encoding: "utf8",
@@ -76796,7 +77222,7 @@ function powershell(script) {
76796
77222
  }
76797
77223
  }
76798
77224
  function repairWindowsUserPath() {
76799
- const prefix = getGlobalPrefix2();
77225
+ const prefix = getGlobalPrefix3();
76800
77226
  if (!prefix) {
76801
77227
  return {
76802
77228
  ok: false,
@@ -77206,7 +77632,7 @@ __export(inspect_exports, {
77206
77632
  runInspect: () => runInspect
77207
77633
  });
77208
77634
  import path103 from "node:path";
77209
- import { existsSync as existsSync66, readFileSync as readFileSync48, readdirSync as readdirSync13 } from "node:fs";
77635
+ import { existsSync as existsSync66, readFileSync as readFileSync48, readdirSync as readdirSync14 } from "node:fs";
77210
77636
  async function collectInspectReport(cwd = process.cwd()) {
77211
77637
  ensureBuiltinSkillsLoadedSync();
77212
77638
  const snap = listSkillsSnapshot(cwd);
@@ -77275,7 +77701,7 @@ async function collectInspectReport(cwd = process.cwd()) {
77275
77701
  }
77276
77702
  function listJsonFiles(dir) {
77277
77703
  try {
77278
- return readdirSync13(dir).filter((f) => f.endsWith(".json")).sort();
77704
+ return readdirSync14(dir).filter((f) => f.endsWith(".json")).sort();
77279
77705
  } catch {
77280
77706
  return [];
77281
77707
  }
@@ -77742,12 +78168,12 @@ function mergeChanges(unstaged, staged, untrackedPaths) {
77742
78168
  return [...byPath.values()].sort((a, b) => churn(b) - churn(a));
77743
78169
  }
77744
78170
  function runGit(args, cwd) {
77745
- return new Promise((resolve10, reject) => {
78171
+ return new Promise((resolve11, reject) => {
77746
78172
  execFile(
77747
78173
  "git",
77748
78174
  args,
77749
78175
  { cwd, timeout: 5e3, windowsHide: true, maxBuffer: 4 * 1024 * 1024 },
77750
- (err, stdout) => err ? reject(err) : resolve10(stdout)
78176
+ (err, stdout) => err ? reject(err) : resolve11(stdout)
77751
78177
  );
77752
78178
  });
77753
78179
  }
@@ -80326,7 +80752,7 @@ init_toolPermissions();
80326
80752
  init_askUserTimeout();
80327
80753
  function createPermissionAskHandler(opts) {
80328
80754
  const { setPicker: setPicker2, appendSystem: appendSystem2 } = opts;
80329
- return (req) => new Promise((resolve10) => {
80755
+ return (req) => new Promise((resolve11) => {
80330
80756
  const cats = req.categories;
80331
80757
  const catLabel = cats.length === 1 ? cats[0] : cats.join("+") || "action";
80332
80758
  const title = `Allow tool "${req.toolName}"?`;
@@ -80352,7 +80778,7 @@ ${detail}${note}${claimsBlock}
80352
80778
  cancelAskTimeout();
80353
80779
  setPicker2(null);
80354
80780
  if (note2) appendSystem2?.(note2, Date.now());
80355
- resolve10(ok);
80781
+ resolve11(ok);
80356
80782
  };
80357
80783
  cancelAskTimeout = armPickerTimeout(
80358
80784
  () => finish2(
@@ -80551,10 +80977,10 @@ function useChatTurn(params) {
80551
80977
  }
80552
80978
  } catch {
80553
80979
  }
80554
- const onAskUser = setPicker2 ? (req) => new Promise((resolve10) => {
80980
+ const onAskUser = setPicker2 ? (req) => new Promise((resolve11) => {
80555
80981
  const choices = req.choices ?? [];
80556
80982
  if (choices.length < 2) {
80557
- resolve10(null);
80983
+ resolve11(null);
80558
80984
  return;
80559
80985
  }
80560
80986
  setLastClarification({
@@ -80578,7 +81004,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
80578
81004
  settled = true;
80579
81005
  cancelAskTimeout();
80580
81006
  setPicker2(null);
80581
- resolve10(value);
81007
+ resolve11(value);
80582
81008
  };
80583
81009
  cancelAskTimeout = armPickerTimeout(
80584
81010
  () => {
@@ -81524,10 +81950,10 @@ async function dispatchCouncilPromptImpl(text, deps, overrides = {}) {
81524
81950
  const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
81525
81951
  const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
81526
81952
  const workPhase = getPhase();
81527
- const onAskUserCouncil = setPicker2 ? (req) => new Promise((resolve10) => {
81953
+ const onAskUserCouncil = setPicker2 ? (req) => new Promise((resolve11) => {
81528
81954
  const choices = req.choices ?? [];
81529
81955
  if (choices.length < 2) {
81530
- resolve10(null);
81956
+ resolve11(null);
81531
81957
  return;
81532
81958
  }
81533
81959
  setLastClarification({
@@ -81551,7 +81977,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
81551
81977
  settled = true;
81552
81978
  cancelAskTimeout();
81553
81979
  setPicker2(null);
81554
- resolve10(value);
81980
+ resolve11(value);
81555
81981
  };
81556
81982
  cancelAskTimeout = armPickerTimeout(
81557
81983
  () => {
@@ -81733,10 +82159,10 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
81733
82159
  appendSystem(setMessages, message, Date.now());
81734
82160
  },
81735
82161
  // v1.8.0: pause council when a member asks a structured question.
81736
- onClarification: setPicker2 ? (req) => new Promise((resolve10) => {
82162
+ onClarification: setPicker2 ? (req) => new Promise((resolve11) => {
81737
82163
  const choices = req.choices ?? [];
81738
82164
  if (choices.length < 2) {
81739
- resolve10(null);
82165
+ resolve11(null);
81740
82166
  return;
81741
82167
  }
81742
82168
  setLastClarification({
@@ -81757,7 +82183,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
81757
82183
  if (settled) return;
81758
82184
  settled = true;
81759
82185
  setPicker2(null);
81760
- resolve10(value);
82186
+ resolve11(value);
81761
82187
  };
81762
82188
  setPicker2({
81763
82189
  kind: "clarification",
@@ -82415,10 +82841,10 @@ function usePermissionBroker(opts) {
82415
82841
  setPicker: setPicker2,
82416
82842
  appendSystem: (msg, at) => appendSystem(setMessages, msg, at ?? Date.now())
82417
82843
  });
82418
- const onQuestion = (req) => new Promise((resolve10) => {
82844
+ const onQuestion = (req) => new Promise((resolve11) => {
82419
82845
  const choices = (req.choices ?? []).map((c) => String(c).trim()).filter((c) => c.length > 0);
82420
82846
  if (choices.length < 2) {
82421
- resolve10(null);
82847
+ resolve11(null);
82422
82848
  return;
82423
82849
  }
82424
82850
  let settled = false;
@@ -82428,7 +82854,7 @@ function usePermissionBroker(opts) {
82428
82854
  settled = true;
82429
82855
  cancelWaitTimeout?.();
82430
82856
  setPicker2(null);
82431
- resolve10(value);
82857
+ resolve11(value);
82432
82858
  };
82433
82859
  const waitTimeoutMs = askUserTimeoutMs();
82434
82860
  cancelWaitTimeout = armPickerTimeout(() => {
@@ -84682,7 +85108,8 @@ async function handleUpdateCheck(ctx) {
84682
85108
  appendSystem(
84683
85109
  ctx.setMessages,
84684
85110
  `[update] \u{1F195} zelari-code ${info.latestVersion} available (current: ${info.currentVersion})
84685
- Run \`/update --yes\` to install. You'll need to restart manually after.`
85111
+ Run \`/update --yes\` to install (global installs only).
85112
+ On npx/local installs, update with \`npx zelari-code@latest\` \u2014 you'll need to restart manually after.`
84686
85113
  );
84687
85114
  } else {
84688
85115
  appendSystem(
@@ -84699,7 +85126,18 @@ async function handleUpdateCheck(ctx) {
84699
85126
  }
84700
85127
  async function handleUpdatePerform(ctx) {
84701
85128
  try {
84702
- const { performUpdate: performUpdate2, distTagForVersion: distTagForVersion2, getCurrentVersion: getCurrentVersion2 } = await Promise.resolve().then(() => (init_updater(), updater_exports));
85129
+ const {
85130
+ performUpdate: performUpdate2,
85131
+ resolveInstallKind: resolveInstallKind2,
85132
+ nonGlobalUpdateAdvisory: nonGlobalUpdateAdvisory2,
85133
+ distTagForVersion: distTagForVersion2,
85134
+ getCurrentVersion: getCurrentVersion2
85135
+ } = await Promise.resolve().then(() => (init_updater(), updater_exports));
85136
+ const kind2 = resolveInstallKind2();
85137
+ if (kind2 === "npx" || kind2 === "local") {
85138
+ appendSystem(ctx.setMessages, nonGlobalUpdateAdvisory2(kind2));
85139
+ return;
85140
+ }
84703
85141
  const tag = distTagForVersion2(getCurrentVersion2());
84704
85142
  appendSystem(
84705
85143
  ctx.setMessages,
@@ -84806,7 +85244,7 @@ ${browsers.output}` : "") + (browsers.ok ? "" : `
84806
85244
  return result;
84807
85245
  }
84808
85246
  function runPlaywrightInstallChromium(cwd, executor) {
84809
- return new Promise((resolve10) => {
85247
+ return new Promise((resolve11) => {
84810
85248
  let stdout = "";
84811
85249
  let stderr = "";
84812
85250
  const stdio = ["ignore", "pipe", "pipe"];
@@ -84819,7 +85257,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
84819
85257
  stderr += chunk.toString();
84820
85258
  });
84821
85259
  child.on("error", (err) => {
84822
- resolve10({
85260
+ resolve11({
84823
85261
  ok: false,
84824
85262
  output: stdout + stderr,
84825
85263
  error: err.message,
@@ -84828,7 +85266,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
84828
85266
  });
84829
85267
  child.on("close", (code) => {
84830
85268
  const ok = code === 0;
84831
- resolve10({
85269
+ resolve11({
84832
85270
  ok,
84833
85271
  output: stdout + stderr,
84834
85272
  exitCode: code,
@@ -84838,7 +85276,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
84838
85276
  });
84839
85277
  }
84840
85278
  function runNpm2(executor, args, cwd, mode, npmCliPath) {
84841
- return new Promise((resolve10) => {
85279
+ return new Promise((resolve11) => {
84842
85280
  let stdout = "";
84843
85281
  let stderr = "";
84844
85282
  const stdio = ["ignore", "pipe", "pipe"];
@@ -84850,7 +85288,7 @@ function runNpm2(executor, args, cwd, mode, npmCliPath) {
84850
85288
  stderr += chunk.toString();
84851
85289
  });
84852
85290
  child.on("error", (err) => {
84853
- resolve10({
85291
+ resolve11({
84854
85292
  ok: false,
84855
85293
  output: stdout + stderr,
84856
85294
  error: err.message,
@@ -84859,7 +85297,7 @@ function runNpm2(executor, args, cwd, mode, npmCliPath) {
84859
85297
  });
84860
85298
  child.on("close", (code) => {
84861
85299
  const ok = code === 0;
84862
- resolve10({
85300
+ resolve11({
84863
85301
  ok,
84864
85302
  output: stdout + stderr,
84865
85303
  exitCode: code,
@@ -87323,7 +87761,7 @@ function runPreflight() {
87323
87761
  }
87324
87762
  async function backgroundUpdateCheck() {
87325
87763
  if (process.env.ANATHEMA_DEV === "1") return;
87326
- await new Promise((resolve10) => setTimeout(resolve10, 3e3));
87764
+ await new Promise((resolve11) => setTimeout(resolve11, 3e3));
87327
87765
  try {
87328
87766
  const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_updater(), updater_exports));
87329
87767
  const info = await checkForUpdate2();
@@ -88124,7 +88562,7 @@ function main() {
88124
88562
  closeMcpClients2();
88125
88563
  } catch {
88126
88564
  }
88127
- await new Promise((resolve10) => setImmediate(resolve10));
88565
+ await new Promise((resolve11) => setImmediate(resolve11));
88128
88566
  process.exit(code);
88129
88567
  }).catch(async (err) => {
88130
88568
  console.error(