switchroom 0.15.34 → 0.15.36

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.
@@ -23528,8 +23528,8 @@ var init_resolver = __esm(() => {
23528
23528
 
23529
23529
  // src/agents/compose.ts
23530
23530
  import { createHash as createHash3 } from "node:crypto";
23531
- import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync13 } from "node:fs";
23532
- import { join as join10 } from "node:path";
23531
+ import { existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync13, lstatSync as lstatSync4, readlinkSync as readlinkSync5 } from "node:fs";
23532
+ import { join as join10, isAbsolute, dirname as dirname3, resolve as resolve12 } from "node:path";
23533
23533
  function parseMemToMib(s) {
23534
23534
  const m = /^(\d+(?:\.\d+)?)\s*([gmk]?)b?$/i.exec(s.trim());
23535
23535
  if (!m)
@@ -23707,6 +23707,23 @@ function readStrippedCaps(agent) {
23707
23707
  return caps.map(String);
23708
23708
  return [];
23709
23709
  }
23710
+ function conditionalMountPresent(probePath, hostHome, probeHome) {
23711
+ if (existsSync15(probePath))
23712
+ return true;
23713
+ try {
23714
+ if (!lstatSync4(probePath).isSymbolicLink())
23715
+ return false;
23716
+ let target = readlinkSync5(probePath);
23717
+ if (!isAbsolute(target))
23718
+ target = resolve12(dirname3(probePath), target);
23719
+ if (hostHome && probeHome && hostHome !== probeHome && target.startsWith(hostHome + "/")) {
23720
+ target = probeHome + target.slice(hostHome.length);
23721
+ }
23722
+ return existsSync15(target);
23723
+ } catch {
23724
+ return false;
23725
+ }
23726
+ }
23710
23727
  function generateCompose(opts) {
23711
23728
  const { config } = opts;
23712
23729
  assertNoAgentUidCollision(config);
@@ -24079,16 +24096,16 @@ function emitAgentService(lines, a, imageTag, buildMode, buildContext, homePrefi
24079
24096
  lines.push(` - ${homePrefix}/.switchroom/logs/${a.name}:/var/log/switchroom`);
24080
24097
  lines.push(` - ${homePrefix}/.switchroom/agents/${a.name}:${homePrefix}/.switchroom/agents/${a.name}`);
24081
24098
  lines.push(` - ${homePrefix}/.claude/projects/${a.name}:${homePrefix}/.claude/projects/${a.name}`);
24082
- if (existsSync15(`${probeHome}/.switchroom/skills`)) {
24099
+ if (conditionalMountPresent(`${probeHome}/.switchroom/skills`, hostHomeForChecks, probeHome)) {
24083
24100
  lines.push(` - ${homePrefix}/.switchroom/skills:${homePrefix}/.switchroom/skills:ro`);
24084
24101
  }
24085
- if (existsSync15(`${probeHome}/.switchroom/mcp-launchers`)) {
24102
+ if (conditionalMountPresent(`${probeHome}/.switchroom/mcp-launchers`, hostHomeForChecks, probeHome)) {
24086
24103
  lines.push(` - ${homePrefix}/.switchroom/mcp-launchers:${homePrefix}/.switchroom/mcp-launchers:ro`);
24087
24104
  }
24088
- if (existsSync15(`${probeHome}/.switchroom/fleet`)) {
24105
+ if (conditionalMountPresent(`${probeHome}/.switchroom/fleet`, hostHomeForChecks, probeHome)) {
24089
24106
  lines.push(` - ${homePrefix}/.switchroom/fleet:${homePrefix}/.switchroom/fleet:ro`);
24090
24107
  }
24091
- if (existsSync15(`${probeHome}/.switchroom/credentials/${a.name}`)) {
24108
+ if (conditionalMountPresent(`${probeHome}/.switchroom/credentials/${a.name}`, hostHomeForChecks, probeHome)) {
24092
24109
  lines.push(` - ${homePrefix}/.switchroom/credentials/${a.name}:${homePrefix}/.switchroom/credentials:ro`);
24093
24110
  }
24094
24111
  try {
@@ -24098,7 +24115,7 @@ function emitAgentService(lines, a, imageTag, buildMode, buildContext, homePrefi
24098
24115
  mkdirSync11(`${probeHome}/.switchroom/agents/${a.name}/schedule.d`, { recursive: true });
24099
24116
  } catch {}
24100
24117
  lines.push(` - ${homePrefix}/.switchroom/audit/${a.name}:${homePrefix}/.switchroom/audit/${a.name}:rw`);
24101
- if (existsSync15(`${probeHome}/.switchroom-config`)) {
24118
+ if (conditionalMountPresent(`${probeHome}/.switchroom-config`, hostHomeForChecks, probeHome)) {
24102
24119
  try {
24103
24120
  mkdirSync11(`${probeHome}/.switchroom-config/agents/${a.name}/personal-skills`, { recursive: true });
24104
24121
  } catch {}
@@ -24113,8 +24130,9 @@ function emitAgentService(lines, a, imageTag, buildMode, buildContext, homePrefi
24113
24130
  if (existsSync15(`${probeHome}/.switchroom/webkite/config.toml`)) {
24114
24131
  lines.push(` - ${homePrefix}/.switchroom/webkite/config.toml:/state/agent/home/.config/webkite/config.toml:ro`);
24115
24132
  }
24116
- if (bundledSkillsPoolDir && existsSync15(bundledSkillsPoolDir) && !bundledSkillsPoolDir.startsWith(`${hostHomeForChecks}/.switchroom/skills`)) {
24117
- lines.push(` - ${bundledSkillsPoolDir}:${bundledSkillsPoolDir}:ro`);
24133
+ const bundledSkillsBakeDir = probeHome && hostHomeForChecks && probeHome !== hostHomeForChecks && bundledSkillsPoolDir.startsWith(probeHome + "/") ? hostHomeForChecks + bundledSkillsPoolDir.slice(probeHome.length) : bundledSkillsPoolDir;
24134
+ if (bundledSkillsPoolDir && existsSync15(bundledSkillsPoolDir) && !bundledSkillsBakeDir.startsWith(`${hostHomeForChecks}/.switchroom/skills`)) {
24135
+ lines.push(` - ${bundledSkillsBakeDir}:${bundledSkillsBakeDir}:ro`);
24118
24136
  }
24119
24137
  if (switchroomConfigPath) {
24120
24138
  lines.push(` - ${switchroomConfigPath}:/state/config/switchroom.yaml:ro`);
@@ -24227,7 +24245,7 @@ var init_tmux = __esm(() => {
24227
24245
  });
24228
24246
 
24229
24247
  // src/agents/docker-fleet.ts
24230
- import { resolve as resolve12 } from "node:path";
24248
+ import { resolve as resolve13 } from "node:path";
24231
24249
  import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync6 } from "node:fs";
24232
24250
  import { homedir as homedir7 } from "node:os";
24233
24251
  import { execFileSync as execFileSync6 } from "node:child_process";
@@ -24237,11 +24255,11 @@ function resolveSwitchroomHome(explicit) {
24237
24255
  const envHome = process.env.SWITCHROOM_HOME;
24238
24256
  if (envHome && envHome.length > 0)
24239
24257
  return envHome;
24240
- return resolve12(process.env.HOME ?? "", ".switchroom");
24258
+ return resolve13(process.env.HOME ?? "", ".switchroom");
24241
24259
  }
24242
24260
  function bringUpAgentService(opts) {
24243
24261
  const home2 = resolveSwitchroomHome(opts.switchroomHome);
24244
- const composeDir = resolve12(home2, "compose");
24262
+ const composeDir = resolve13(home2, "compose");
24245
24263
  mkdirSync12(composeDir, { recursive: true, mode: 493 });
24246
24264
  let switchroomConfigPath = opts.switchroomConfigPath;
24247
24265
  if (!switchroomConfigPath && !opts.generateComposeContent) {
@@ -24256,7 +24274,7 @@ function bringUpAgentService(opts) {
24256
24274
  homeDir: homedir7(),
24257
24275
  switchroomConfigPath
24258
24276
  });
24259
- const composePath = resolve12(composeDir, "docker-compose.yml");
24277
+ const composePath = resolve13(composeDir, "docker-compose.yml");
24260
24278
  writeFileSync6(composePath, compose, { mode: 384 });
24261
24279
  const dockerBin = opts.dockerBin ?? "docker";
24262
24280
  const stdio = opts.stdio ?? "inherit";
@@ -24375,7 +24393,7 @@ var init_singleton_reconcile = __esm(() => {
24375
24393
  // src/agents/lifecycle.ts
24376
24394
  import { execFileSync as execFileSync8, spawn, spawnSync } from "node:child_process";
24377
24395
  import { existsSync as existsSync17, mkdirSync as mkdirSync13, writeFileSync as writeFileSync7, renameSync as renameSync4, readFileSync as readFileSync15 } from "node:fs";
24378
- import { resolve as resolve13, join as join13 } from "node:path";
24396
+ import { resolve as resolve14, join as join13 } from "node:path";
24379
24397
  import { connect } from "node:net";
24380
24398
  function cleanShutdownMarkerPathForAgent(name) {
24381
24399
  const agentsDir = process.env.SWITCHROOM_AGENTS_DIR ?? resolveStatePath("agents");
@@ -24438,7 +24456,7 @@ function composeFilePath() {
24438
24456
  const override = process.env.SWITCHROOM_COMPOSE_FILE;
24439
24457
  if (override && override.length > 0)
24440
24458
  return override;
24441
- return resolve13(resolveSwitchroomHome(), "compose", "docker-compose.yml");
24459
+ return resolve14(resolveSwitchroomHome(), "compose", "docker-compose.yml");
24442
24460
  }
24443
24461
  function reconcileSingletonImages(log) {
24444
24462
  return reconcileSingletons({ composeFile: composeFilePath(), log });
@@ -24487,7 +24505,7 @@ function restartAgent(name, reason) {
24487
24505
  function gracefulRestartAgent(name) {
24488
24506
  return new Promise((resolvePromise, reject) => {
24489
24507
  const agentsDir = process.env.SWITCHROOM_AGENTS_DIR ?? resolveStatePath("agents");
24490
- const agentDir = resolve13(agentsDir, name);
24508
+ const agentDir = resolve14(agentsDir, name);
24491
24509
  const socketPath = process.env.SWITCHROOM_GATEWAY_SOCKET ?? join13(agentDir, "telegram", "gateway.sock");
24492
24510
  if (!existsSync17(socketPath)) {
24493
24511
  reject(new Error("Gateway socket not found. Is the gateway running?"));
@@ -25131,7 +25149,7 @@ import {
25131
25149
  chmodSync as chmodSync3,
25132
25150
  statSync as statSync13
25133
25151
  } from "node:fs";
25134
- import { join as join17, resolve as resolve15 } from "node:path";
25152
+ import { join as join17, resolve as resolve16 } from "node:path";
25135
25153
  function extractCodeChallenge(url) {
25136
25154
  const match = url.match(/[?&]code_challenge=([A-Za-z0-9_-]+)/);
25137
25155
  return match ? match[1] : null;
@@ -25394,7 +25412,7 @@ function getAllAuthStatuses(config) {
25394
25412
  const agentsDir = resolveAgentsDir(config);
25395
25413
  const statuses = {};
25396
25414
  for (const name of Object.keys(config.agents)) {
25397
- const agentDir = resolve15(agentsDir, name);
25415
+ const agentDir = resolve16(agentsDir, name);
25398
25416
  statuses[name] = getAuthStatus(name, agentDir);
25399
25417
  }
25400
25418
  return statuses;
@@ -26440,7 +26458,7 @@ class AuthBrokerClient {
26440
26458
  return this.socket;
26441
26459
  if (this.connecting)
26442
26460
  return this.connecting;
26443
- this.connecting = new Promise((resolve22, reject) => {
26461
+ this.connecting = new Promise((resolve23, reject) => {
26444
26462
  const sock = new net2.Socket;
26445
26463
  const onError = (err) => {
26446
26464
  sock.removeAllListeners();
@@ -26464,7 +26482,7 @@ class AuthBrokerClient {
26464
26482
  sock.on("error", (err) => this.onSocketError(err));
26465
26483
  sock.on("close", () => this.onSocketClose());
26466
26484
  this.socket = sock;
26467
- resolve22(sock);
26485
+ resolve23(sock);
26468
26486
  });
26469
26487
  sock.connect({ path: this.socketPath });
26470
26488
  });
@@ -26524,7 +26542,7 @@ class AuthBrokerClient {
26524
26542
  const sock = await this.ensureConnected();
26525
26543
  const id = req.id;
26526
26544
  const frame = encodeRequest2(req);
26527
- return new Promise((resolve22, reject) => {
26545
+ return new Promise((resolve23, reject) => {
26528
26546
  const timer = setTimeout(() => {
26529
26547
  this.pending.delete(id);
26530
26548
  reject(new AuthBrokerUnreachableError(`request ${req.op} timed out after ${this.timeoutMs}ms`, this.socketPath));
@@ -26532,7 +26550,7 @@ class AuthBrokerClient {
26532
26550
  this.pending.set(id, {
26533
26551
  resolve: (resp) => {
26534
26552
  if (resp.ok) {
26535
- resolve22(resp.data);
26553
+ resolve23(resp.data);
26536
26554
  } else {
26537
26555
  reject(new AuthBrokerError(resp.error.code, resp.error.message));
26538
26556
  }
@@ -26632,7 +26650,7 @@ import {
26632
26650
  writeFileSync as writeFileSync14
26633
26651
  } from "node:fs";
26634
26652
  import { homedir as homedir11 } from "node:os";
26635
- import { join as join23, resolve as resolve22 } from "node:path";
26653
+ import { join as join23, resolve as resolve23 } from "node:path";
26636
26654
  function accountsRootOverride() {
26637
26655
  const v = process.env.SWITCHROOM_ACCOUNTS_DIR;
26638
26656
  if (v && v.length > 0 && v.startsWith("/"))
@@ -26640,7 +26658,7 @@ function accountsRootOverride() {
26640
26658
  return;
26641
26659
  }
26642
26660
  function accountsRoot(home2 = homedir11()) {
26643
- return accountsRootOverride() ?? resolve22(home2, ".switchroom", "accounts");
26661
+ return accountsRootOverride() ?? resolve23(home2, ".switchroom", "accounts");
26644
26662
  }
26645
26663
  function accountDir(label, home2 = homedir11()) {
26646
26664
  return join23(accountsRoot(home2), label);
@@ -26991,18 +27009,18 @@ async function openBrowser(url, platform = process.platform, spawnImpl = spawn2)
26991
27009
  cmd = "xdg-open";
26992
27010
  args = [url];
26993
27011
  }
26994
- return new Promise((resolve23) => {
27012
+ return new Promise((resolve24) => {
26995
27013
  try {
26996
27014
  const p = spawnImpl(cmd, args, { stdio: "ignore", detached: true });
26997
- p.once("error", () => resolve23(false));
27015
+ p.once("error", () => resolve24(false));
26998
27016
  p.once("spawn", () => {
26999
27017
  try {
27000
27018
  p.unref();
27001
27019
  } catch {}
27002
- resolve23(true);
27020
+ resolve24(true);
27003
27021
  });
27004
27022
  } catch {
27005
- resolve23(false);
27023
+ resolve24(false);
27006
27024
  }
27007
27025
  });
27008
27026
  }
@@ -27014,18 +27032,18 @@ async function runLoopbackOAuth(cfg, opts = {}) {
27014
27032
  const state = crypto2.randomBytes(16).toString("hex");
27015
27033
  let server = null;
27016
27034
  let timer = null;
27017
- const closeServer = () => new Promise((resolve23) => {
27035
+ const closeServer = () => new Promise((resolve24) => {
27018
27036
  if (!server)
27019
- return resolve23();
27037
+ return resolve24();
27020
27038
  const s = server;
27021
27039
  server = null;
27022
- s.close(() => resolve23());
27040
+ s.close(() => resolve24());
27023
27041
  try {
27024
27042
  s.unref();
27025
27043
  } catch {}
27026
27044
  });
27027
27045
  try {
27028
- const { code, redirectUri } = await new Promise((resolve23, reject) => {
27046
+ const { code, redirectUri } = await new Promise((resolve24, reject) => {
27029
27047
  server = http.createServer((req, res) => {
27030
27048
  try {
27031
27049
  const url = new URL(req.url ?? "/", `http://${host}`);
@@ -27054,7 +27072,7 @@ async function runLoopbackOAuth(cfg, opts = {}) {
27054
27072
  }
27055
27073
  renderHtml(res, 200, "Authorization complete", "Authorization complete. You can close this tab and return to the terminal.");
27056
27074
  const hostHeader = req.headers.host ?? `${host}:?`;
27057
- resolve23({
27075
+ resolve24({
27058
27076
  code: gotCode,
27059
27077
  redirectUri: `http://${hostHeader}`
27060
27078
  });
@@ -27465,7 +27483,7 @@ var init_client3 = __esm(() => {
27465
27483
 
27466
27484
  // src/vault/approvals/wait.ts
27467
27485
  function defaultSleep(ms, signal) {
27468
- return new Promise((resolve23, reject) => {
27486
+ return new Promise((resolve24, reject) => {
27469
27487
  if (signal?.aborted) {
27470
27488
  reject(new DOMException("Aborted", "AbortError"));
27471
27489
  return;
@@ -27476,7 +27494,7 @@ function defaultSleep(ms, signal) {
27476
27494
  };
27477
27495
  const timer = setTimeout(() => {
27478
27496
  signal?.removeEventListener("abort", onAbort);
27479
- resolve23();
27497
+ resolve24();
27480
27498
  }, ms);
27481
27499
  signal?.addEventListener("abort", onAbort, { once: true });
27482
27500
  });
@@ -27629,7 +27647,7 @@ function getVaultPath(configPath) {
27629
27647
  }
27630
27648
  }
27631
27649
  function promptHidden(prompt) {
27632
- return new Promise((resolve23, reject) => {
27650
+ return new Promise((resolve24, reject) => {
27633
27651
  const rl = createInterface2({
27634
27652
  input: process.stdin,
27635
27653
  output: process.stdout
@@ -27649,7 +27667,7 @@ function promptHidden(prompt) {
27649
27667
  rl.close();
27650
27668
  process.stdout.write(`
27651
27669
  `);
27652
- resolve23(input);
27670
+ resolve24(input);
27653
27671
  } else if (char === "\x03") {
27654
27672
  stdin.setRawMode(false);
27655
27673
  stdin.removeListener("data", onData);
@@ -27668,20 +27686,20 @@ function promptHidden(prompt) {
27668
27686
  } else {
27669
27687
  rl.question(prompt, (answer) => {
27670
27688
  rl.close();
27671
- resolve23(answer);
27689
+ resolve24(answer);
27672
27690
  });
27673
27691
  }
27674
27692
  });
27675
27693
  }
27676
27694
  function promptLine(prompt) {
27677
- return new Promise((resolve23) => {
27695
+ return new Promise((resolve24) => {
27678
27696
  const rl = createInterface2({
27679
27697
  input: process.stdin,
27680
27698
  output: process.stdout
27681
27699
  });
27682
27700
  rl.question(prompt, (answer) => {
27683
27701
  rl.close();
27684
- resolve23(answer);
27702
+ resolve24(answer);
27685
27703
  });
27686
27704
  });
27687
27705
  }
@@ -28238,18 +28256,18 @@ async function openBrowser2(url, platform = process.platform, spawnImpl = spawn3
28238
28256
  cmd = "xdg-open";
28239
28257
  args = [url];
28240
28258
  }
28241
- return new Promise((resolve23) => {
28259
+ return new Promise((resolve24) => {
28242
28260
  try {
28243
28261
  const p = spawnImpl(cmd, args, { stdio: "ignore", detached: true });
28244
- p.once("error", () => resolve23(false));
28262
+ p.once("error", () => resolve24(false));
28245
28263
  p.once("spawn", () => {
28246
28264
  try {
28247
28265
  p.unref();
28248
28266
  } catch {}
28249
- resolve23(true);
28267
+ resolve24(true);
28250
28268
  });
28251
28269
  } catch {
28252
- resolve23(false);
28270
+ resolve24(false);
28253
28271
  }
28254
28272
  });
28255
28273
  }
@@ -28262,18 +28280,18 @@ async function runLoopbackOAuth2(cfg, opts = {}) {
28262
28280
  const { verifier, challenge } = generatePkcePair();
28263
28281
  let server = null;
28264
28282
  let timer = null;
28265
- const closeServer = () => new Promise((resolve23) => {
28283
+ const closeServer = () => new Promise((resolve24) => {
28266
28284
  if (!server)
28267
- return resolve23();
28285
+ return resolve24();
28268
28286
  const s = server;
28269
28287
  server = null;
28270
- s.close(() => resolve23());
28288
+ s.close(() => resolve24());
28271
28289
  try {
28272
28290
  s.unref();
28273
28291
  } catch {}
28274
28292
  });
28275
28293
  try {
28276
- const { code, redirectUri } = await new Promise((resolve23, reject) => {
28294
+ const { code, redirectUri } = await new Promise((resolve24, reject) => {
28277
28295
  server = http2.createServer((req, res) => {
28278
28296
  try {
28279
28297
  const url = new URL(req.url ?? "/", `http://${host}`);
@@ -28303,7 +28321,7 @@ async function runLoopbackOAuth2(cfg, opts = {}) {
28303
28321
  }
28304
28322
  renderHtml2(res, 200, "Microsoft authorization complete", "You can close this tab and return to the terminal.");
28305
28323
  const hostHeader = req.headers.host ?? `${host}:?`;
28306
- resolve23({
28324
+ resolve24({
28307
28325
  code: gotCode,
28308
28326
  redirectUri: `http://${hostHeader}`
28309
28327
  });
@@ -28460,7 +28478,7 @@ __export(exports_via_claude, {
28460
28478
  });
28461
28479
  import { execFileSync as execFileSync14, spawnSync as spawnSync2 } from "node:child_process";
28462
28480
  import { existsSync as existsSync32, mkdirSync as mkdirSync19, readFileSync as readFileSync27 } from "node:fs";
28463
- import { join as join25, resolve as resolve23 } from "node:path";
28481
+ import { join as join25, resolve as resolve24 } from "node:path";
28464
28482
  function tmuxHasSession(session) {
28465
28483
  const r = spawnSync2("tmux", ["has-session", "-t", session], {
28466
28484
  stdio: ["ignore", "ignore", "ignore"]
@@ -28504,7 +28522,7 @@ async function runViaClaude(opts) {
28504
28522
  const urlTimeout = opts.urlTimeoutMs ?? VIA_CLAUDE_DEFAULTS.urlTimeoutMs;
28505
28523
  const credsTimeout = opts.credentialsTimeoutMs ?? VIA_CLAUDE_DEFAULTS.credentialsTimeoutMs;
28506
28524
  const poll = opts.pollMs ?? VIA_CLAUDE_DEFAULTS.pollMs;
28507
- const configDir = resolve23(opts.configDir);
28525
+ const configDir = resolve24(opts.configDir);
28508
28526
  mkdirSync19(configDir, { recursive: true });
28509
28527
  const credentialsPath2 = join25(configDir, ".credentials.json");
28510
28528
  const capture = opts.capturePane ?? (() => tmuxCapturePane(SESSION));
@@ -29281,7 +29299,7 @@ var init_audit_reader = () => {};
29281
29299
  import { connect as connect2 } from "node:net";
29282
29300
  async function hostdRequest(opts, req) {
29283
29301
  const timeoutMs = opts.timeoutMs ?? 5000;
29284
- return new Promise((resolve27, reject) => {
29302
+ return new Promise((resolve28, reject) => {
29285
29303
  const socket = connect2(opts.socketPath);
29286
29304
  let buf = "";
29287
29305
  let settled = false;
@@ -29327,7 +29345,7 @@ async function hostdRequest(opts, req) {
29327
29345
  settled = true;
29328
29346
  clearTimeout(timer);
29329
29347
  socket.end();
29330
- resolve27(resp);
29348
+ resolve28(resp);
29331
29349
  } catch (err) {
29332
29350
  if (settled)
29333
29351
  return;
@@ -29404,7 +29422,7 @@ import {
29404
29422
  readFileSync as readFileSync48,
29405
29423
  readdirSync as readdirSync19
29406
29424
  } from "node:fs";
29407
- import { dirname as dirname12, join as join48 } from "node:path";
29425
+ import { dirname as dirname13, join as join48 } from "node:path";
29408
29426
  import { execSync as execSync2 } from "node:child_process";
29409
29427
  function locateManifestPath() {
29410
29428
  let dir = import.meta.dirname;
@@ -29412,7 +29430,7 @@ function locateManifestPath() {
29412
29430
  const candidate = join48(dir, "dependencies.json");
29413
29431
  if (existsSync52(candidate))
29414
29432
  return candidate;
29415
- dir = dirname12(dir);
29433
+ dir = dirname13(dir);
29416
29434
  }
29417
29435
  return null;
29418
29436
  }
@@ -30512,7 +30530,7 @@ import {
30512
30530
  existsSync as realExistsSync,
30513
30531
  readFileSync as realReadFileSync
30514
30532
  } from "node:fs";
30515
- import { join as join51, resolve as resolve30 } from "node:path";
30533
+ import { join as join51, resolve as resolve31 } from "node:path";
30516
30534
  import { homedir as homedir29 } from "node:os";
30517
30535
  function resolveDeps(config, deps) {
30518
30536
  let agentsDir = deps.agentsDir;
@@ -30627,7 +30645,7 @@ function checkScaffoldWiring(config, driveAgents, d) {
30627
30645
  ];
30628
30646
  }
30629
30647
  for (const name of driveAgents) {
30630
- const agentDir = resolve30(d.agentsDir, name);
30648
+ const agentDir = resolve31(d.agentsDir, name);
30631
30649
  if (!d.existsSync(agentDir)) {
30632
30650
  results.push({
30633
30651
  name: `drive: ${name} scaffold`,
@@ -30665,7 +30683,7 @@ function checkScaffoldWiring(config, driveAgents, d) {
30665
30683
  let trustOk = false;
30666
30684
  let trustDetail = "no .claude/.claude.json";
30667
30685
  if (trustRead.kind === "ok") {
30668
- const proj = trustRead.data?.projects?.[resolve30(agentDir)];
30686
+ const proj = trustRead.data?.projects?.[resolve31(agentDir)];
30669
30687
  const enabled = proj?.enabledMcpjsonServers;
30670
30688
  if (Array.isArray(enabled) && enabled.includes("gdrive")) {
30671
30689
  trustOk = true;
@@ -30990,7 +31008,7 @@ var init_doctor_webkite = __esm(() => {
30990
31008
 
30991
31009
  // src/cli/doctor-cron-session.ts
30992
31010
  import { statSync as realStatSync } from "node:fs";
30993
- import { resolve as resolve31 } from "node:path";
31011
+ import { resolve as resolve32 } from "node:path";
30994
31012
  function agentRunsCronSession(config, agent) {
30995
31013
  const raw = config.agents[agent];
30996
31014
  if (!raw)
@@ -31006,7 +31024,7 @@ function runCronSessionChecks(config, deps = defaultDeps2) {
31006
31024
  if (!agentRunsCronSession(config, agent))
31007
31025
  continue;
31008
31026
  const name = `cron-session: ${agent}`;
31009
- const alivePath = resolve31(agentsDir, agent, "telegram", ".bridge-alive-cron");
31027
+ const alivePath = resolve32(agentsDir, agent, "telegram", ".bridge-alive-cron");
31010
31028
  let mtimeMs;
31011
31029
  try {
31012
31030
  mtimeMs = deps.statMtimeMs(alivePath);
@@ -31055,7 +31073,7 @@ var init_doctor_cron_session = __esm(() => {
31055
31073
  });
31056
31074
 
31057
31075
  // src/cli/doctor-scaffold-wiring.ts
31058
- import { join as join53, resolve as resolve32 } from "node:path";
31076
+ import { join as join53, resolve as resolve33 } from "node:path";
31059
31077
  function readJson2(d, path4) {
31060
31078
  if (!d.existsSync(path4))
31061
31079
  return { kind: "absent" };
@@ -31089,7 +31107,7 @@ function checkIntegrationScaffoldWiring(args) {
31089
31107
  ];
31090
31108
  }
31091
31109
  for (const name of agents) {
31092
- const agentDir = resolve32(agentsDir, name);
31110
+ const agentDir = resolve33(agentsDir, name);
31093
31111
  if (!deps.existsSync(agentDir)) {
31094
31112
  results.push({
31095
31113
  name: `${label}: ${name} scaffold`,
@@ -31129,7 +31147,7 @@ function checkIntegrationScaffoldWiring(args) {
31129
31147
  let trustDetail = "no .claude/.claude.json";
31130
31148
  if (trustRead.kind === "ok") {
31131
31149
  const projects = trustRead.data?.projects ?? {};
31132
- const proj = projects[resolve32(agentDir)];
31150
+ const proj = projects[resolve33(agentDir)];
31133
31151
  const enabled = proj?.enabledMcpjsonServers;
31134
31152
  if (Array.isArray(enabled) && enabled.includes(mcpKey)) {
31135
31153
  trustOk = true;
@@ -32202,13 +32220,13 @@ import {
32202
32220
  accessSync as accessSync2,
32203
32221
  constants as fsConstants5,
32204
32222
  existsSync as existsSync57,
32205
- lstatSync as lstatSync6,
32223
+ lstatSync as lstatSync7,
32206
32224
  mkdirSync as mkdirSync31,
32207
32225
  readFileSync as readFileSync51,
32208
32226
  readdirSync as readdirSync21,
32209
32227
  statSync as statSync25
32210
32228
  } from "node:fs";
32211
- import { dirname as dirname13, join as join60, resolve as resolve33 } from "node:path";
32229
+ import { dirname as dirname14, join as join60, resolve as resolve34 } from "node:path";
32212
32230
  import { createPublicKey, createPrivateKey } from "node:crypto";
32213
32231
  function findInNvm(bin) {
32214
32232
  const nvmRoot = join60(process.env.HOME ?? "", ".nvm", "versions", "node");
@@ -32529,7 +32547,7 @@ function checkLegacyState() {
32529
32547
  const legacySock = join60(h, ".switchroom", "vault-broker.sock");
32530
32548
  let sockStat = null;
32531
32549
  try {
32532
- sockStat = lstatSync6(legacySock);
32550
+ sockStat = lstatSync7(legacySock);
32533
32551
  } catch {}
32534
32552
  if (sockStat) {
32535
32553
  results.push({
@@ -33121,7 +33139,7 @@ function checkLeakedHomeSwitchroom(agentName, agentDir) {
33121
33139
  const path4 = join60(agentDir, "home", ".switchroom");
33122
33140
  let stats;
33123
33141
  try {
33124
- stats = lstatSync6(path4);
33142
+ stats = lstatSync7(path4);
33125
33143
  } catch (err) {
33126
33144
  if (err.code === "ENOENT") {
33127
33145
  return {
@@ -33222,7 +33240,7 @@ function checkAgents(config, configPath) {
33222
33240
  const statuses = getAllAgentStatuses(config);
33223
33241
  const authStatuses = getAllAuthStatuses(config);
33224
33242
  for (const [name, agentConfig] of Object.entries(config.agents)) {
33225
- const agentDir = resolve33(agentsDir, name);
33243
+ const agentDir = resolve34(agentsDir, name);
33226
33244
  if (!existsSync57(agentDir)) {
33227
33245
  results.push({
33228
33246
  name: `${name}: scaffold`,
@@ -33405,7 +33423,7 @@ function mffAgentName(config) {
33405
33423
  function mffEnvPath(config) {
33406
33424
  const home2 = process.env.HOME ?? "/root";
33407
33425
  const agent = mffAgentName(config);
33408
- return agent ? resolve33(home2, ".switchroom/credentials", agent, "my-family-finance/.env") : resolve33(home2, ".switchroom/credentials/my-family-finance/.env");
33426
+ return agent ? resolve34(home2, ".switchroom/credentials", agent, "my-family-finance/.env") : resolve34(home2, ".switchroom/credentials/my-family-finance/.env");
33409
33427
  }
33410
33428
  function mffEnvState(envPath) {
33411
33429
  if (!existsSync57(envPath))
@@ -33622,7 +33640,7 @@ async function checkMffAuthFlow(envPath = mffEnvPath(), timeoutMs = 8000) {
33622
33640
  detail: "skipped (MFF_API_URL not set)"
33623
33641
  };
33624
33642
  }
33625
- const credDir = dirname13(envPath);
33643
+ const credDir = dirname14(envPath);
33626
33644
  const authScript = join60(credDir, "claude-auth.py");
33627
33645
  if (!existsSync57(authScript)) {
33628
33646
  return {
@@ -33821,14 +33839,14 @@ async function checkManifestDrift(probers) {
33821
33839
  return results;
33822
33840
  }
33823
33841
  function runDockerSection(config) {
33824
- const composePath = resolve33(process.env.HOME ?? "", ".switchroom", "compose", "docker-compose.yml");
33842
+ const composePath = resolve34(process.env.HOME ?? "", ".switchroom", "compose", "docker-compose.yml");
33825
33843
  const active = isDockerMode({ composePath });
33826
33844
  let composeYaml;
33827
33845
  let dockerfileAgent;
33828
33846
  try {
33829
33847
  composeYaml = readFileSync51(composePath, "utf8");
33830
33848
  } catch {}
33831
- const dockerfilePath = resolve33(process.env.HOME ?? "", ".switchroom", "docker", "Dockerfile.agent");
33849
+ const dockerfilePath = resolve34(process.env.HOME ?? "", ".switchroom", "docker", "Dockerfile.agent");
33832
33850
  try {
33833
33851
  dockerfileAgent = readFileSync51(dockerfilePath, "utf8");
33834
33852
  } catch {}
@@ -42201,7 +42219,7 @@ class Protocol {
42201
42219
  return;
42202
42220
  }
42203
42221
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1000;
42204
- await new Promise((resolve50) => setTimeout(resolve50, pollInterval));
42222
+ await new Promise((resolve51) => setTimeout(resolve51, pollInterval));
42205
42223
  options?.signal?.throwIfAborted();
42206
42224
  }
42207
42225
  } catch (error2) {
@@ -42213,7 +42231,7 @@ class Protocol {
42213
42231
  }
42214
42232
  request(request, resultSchema, options) {
42215
42233
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
42216
- return new Promise((resolve50, reject) => {
42234
+ return new Promise((resolve51, reject) => {
42217
42235
  const earlyReject = (error2) => {
42218
42236
  reject(error2);
42219
42237
  };
@@ -42291,7 +42309,7 @@ class Protocol {
42291
42309
  if (!parseResult.success) {
42292
42310
  reject(parseResult.error);
42293
42311
  } else {
42294
- resolve50(parseResult.data);
42312
+ resolve51(parseResult.data);
42295
42313
  }
42296
42314
  } catch (error2) {
42297
42315
  reject(error2);
@@ -42482,12 +42500,12 @@ class Protocol {
42482
42500
  interval = task.pollInterval;
42483
42501
  }
42484
42502
  } catch {}
42485
- return new Promise((resolve50, reject) => {
42503
+ return new Promise((resolve51, reject) => {
42486
42504
  if (signal.aborted) {
42487
42505
  reject(new McpError(ErrorCode2.InvalidRequest, "Request cancelled"));
42488
42506
  return;
42489
42507
  }
42490
- const timeoutId = setTimeout(resolve50, interval);
42508
+ const timeoutId = setTimeout(resolve51, interval);
42491
42509
  signal.addEventListener("abort", () => {
42492
42510
  clearTimeout(timeoutId);
42493
42511
  reject(new McpError(ErrorCode2.InvalidRequest, "Request cancelled"));
@@ -45472,7 +45490,7 @@ var require_compile = __commonJS((exports2) => {
45472
45490
  const schOrFunc = root.refs[ref];
45473
45491
  if (schOrFunc)
45474
45492
  return schOrFunc;
45475
- let _sch = resolve50.call(this, root, ref);
45493
+ let _sch = resolve51.call(this, root, ref);
45476
45494
  if (_sch === undefined) {
45477
45495
  const schema = (_a = root.localRefs) === null || _a === undefined ? undefined : _a[ref];
45478
45496
  const { schemaId } = this.opts;
@@ -45499,7 +45517,7 @@ var require_compile = __commonJS((exports2) => {
45499
45517
  function sameSchemaEnv(s1, s2) {
45500
45518
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
45501
45519
  }
45502
- function resolve50(root, ref) {
45520
+ function resolve51(root, ref) {
45503
45521
  let sch;
45504
45522
  while (typeof (sch = this.refs[ref]) == "string")
45505
45523
  ref = sch;
@@ -46029,7 +46047,7 @@ var require_fast_uri = __commonJS((exports2, module) => {
46029
46047
  }
46030
46048
  return uri;
46031
46049
  }
46032
- function resolve50(baseURI, relativeURI, options) {
46050
+ function resolve51(baseURI, relativeURI, options) {
46033
46051
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
46034
46052
  const resolved = resolveComponent(parse6(baseURI, schemelessOptions), parse6(relativeURI, schemelessOptions), schemelessOptions, true);
46035
46053
  schemelessOptions.skipEscape = true;
@@ -46257,7 +46275,7 @@ var require_fast_uri = __commonJS((exports2, module) => {
46257
46275
  var fastUri = {
46258
46276
  SCHEMES,
46259
46277
  normalize,
46260
- resolve: resolve50,
46278
+ resolve: resolve51,
46261
46279
  resolveComponent,
46262
46280
  equal,
46263
46281
  serialize,
@@ -49640,12 +49658,12 @@ class StdioServerTransport {
49640
49658
  this.onclose?.();
49641
49659
  }
49642
49660
  send(message) {
49643
- return new Promise((resolve50) => {
49661
+ return new Promise((resolve51) => {
49644
49662
  const json = serializeMessage(message);
49645
49663
  if (this._stdout.write(json)) {
49646
- resolve50();
49664
+ resolve51();
49647
49665
  } else {
49648
- this._stdout.once("drain", resolve50);
49666
+ this._stdout.once("drain", resolve51);
49649
49667
  }
49650
49668
  });
49651
49669
  }
@@ -50574,12 +50592,12 @@ var {
50574
50592
  } = import__.default;
50575
50593
 
50576
50594
  // src/build-info.ts
50577
- var VERSION = "0.15.34";
50578
- var COMMIT_SHA = "508eb512";
50595
+ var VERSION = "0.15.36";
50596
+ var COMMIT_SHA = "18736aec";
50579
50597
 
50580
50598
  // src/cli/agent.ts
50581
50599
  init_source();
50582
- import { join as join20, resolve as resolve21 } from "node:path";
50600
+ import { join as join20, resolve as resolve22 } from "node:path";
50583
50601
  import { rmSync as rmSync9, existsSync as existsSync28, readFileSync as readFileSync23, writeFileSync as writeFileSync13 } from "node:fs";
50584
50602
  import { homedir as homedir8 } from "node:os";
50585
50603
 
@@ -54523,7 +54541,7 @@ init_compose();
54523
54541
  import { chownSync as chownSync2 } from "node:fs";
54524
54542
  import { mkdir, readFile, writeFile } from "node:fs/promises";
54525
54543
  import { homedir as homedir6 } from "node:os";
54526
- import { basename as basename4, dirname as dirname3, join as join12 } from "node:path";
54544
+ import { basename as basename4, dirname as dirname4, join as join12 } from "node:path";
54527
54545
 
54528
54546
  // src/config/release-resolve.ts
54529
54547
  function resolveImageTag(release) {
@@ -54544,11 +54562,28 @@ function resolveRelease(opts) {
54544
54562
  return opts.root;
54545
54563
  return;
54546
54564
  }
54565
+ function parseSemverTag(tag) {
54566
+ if (!tag)
54567
+ return null;
54568
+ const m = /^v(\d+)\.(\d+)\.(\d+)$/.exec(tag.trim());
54569
+ return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : null;
54570
+ }
54571
+ function compareReleaseTags(a, b) {
54572
+ const pa = parseSemverTag(a);
54573
+ const pb = parseSemverTag(b);
54574
+ if (!pa || !pb)
54575
+ return null;
54576
+ for (let i = 0;i < 3; i++) {
54577
+ if (pa[i] !== pb[i])
54578
+ return pa[i] < pb[i] ? -1 : 1;
54579
+ }
54580
+ return 0;
54581
+ }
54547
54582
  // src/cli/operator-uid.ts
54548
54583
  import {
54549
54584
  chownSync,
54550
54585
  existsSync as existsSync16,
54551
- lstatSync as lstatSync4,
54586
+ lstatSync as lstatSync5,
54552
54587
  readdirSync as readdirSync7,
54553
54588
  realpathSync as realpathSync3,
54554
54589
  statSync as statSync8
@@ -54584,7 +54619,7 @@ function restoreOperatorOwnership(home2, operatorUid, deps = {}) {
54584
54619
  const exists = deps.exists ?? ((p) => existsSync16(p));
54585
54620
  const isSymlink = deps.isSymlink ?? ((p) => {
54586
54621
  try {
54587
- return lstatSync4(p).isSymbolicLink();
54622
+ return lstatSync5(p).isSymbolicLink();
54588
54623
  } catch {
54589
54624
  return false;
54590
54625
  }
@@ -54676,7 +54711,7 @@ async function writeComposeFile(opts) {
54676
54711
  previous = null;
54677
54712
  }
54678
54713
  const previousImageTag = previous ? AGENT_IMAGE_TAG_RE.exec(previous)?.[1] ?? null : null;
54679
- await mkdir(dirname3(opts.composePath), { recursive: true });
54714
+ await mkdir(dirname4(opts.composePath), { recursive: true });
54680
54715
  await writeFile(opts.composePath, content, { encoding: "utf8", mode: 384 });
54681
54716
  if (operatorUid !== undefined && process.geteuid?.() === 0) {
54682
54717
  try {
@@ -54698,7 +54733,7 @@ init_merge();
54698
54733
 
54699
54734
  // src/agents/in-flight.ts
54700
54735
  import { readdirSync as readdirSync8, statSync as statSync9 } from "node:fs";
54701
- import { resolve as resolve14 } from "node:path";
54736
+ import { resolve as resolve15 } from "node:path";
54702
54737
  var DEFAULT_RECENCY_MS = 30000;
54703
54738
  function safeReaddir(path) {
54704
54739
  try {
@@ -54725,7 +54760,7 @@ function collectJsonl(root, maxDepth = 4) {
54725
54760
  while (stack.length > 0) {
54726
54761
  const { dir, depth } = stack.pop();
54727
54762
  for (const entry of safeReaddir(dir)) {
54728
- const full = resolve14(dir, entry);
54763
+ const full = resolve15(dir, entry);
54729
54764
  let isDir = false;
54730
54765
  try {
54731
54766
  isDir = statSync9(full).isDirectory();
@@ -54753,16 +54788,16 @@ function detectInFlight(opts) {
54753
54788
  lastActivityMs: 0,
54754
54789
  details: []
54755
54790
  };
54756
- const tasksRoot = resolve14(opts.agentDir, ".claude", "tasks");
54791
+ const tasksRoot = resolve15(opts.agentDir, ".claude", "tasks");
54757
54792
  for (const sessionId of safeReaddir(tasksRoot)) {
54758
- const sessionDir = resolve14(tasksRoot, sessionId);
54793
+ const sessionDir = resolve15(tasksRoot, sessionId);
54759
54794
  let sessionHasRecent = false;
54760
54795
  let newestSubject = null;
54761
54796
  let newestMtime = 0;
54762
54797
  for (const entry of safeReaddir(sessionDir)) {
54763
54798
  if (!entry.endsWith(".json"))
54764
54799
  continue;
54765
- const mtime = safeMtimeMs(resolve14(sessionDir, entry));
54800
+ const mtime = safeMtimeMs(resolve15(sessionDir, entry));
54766
54801
  if (mtime > result.lastActivityMs)
54767
54802
  result.lastActivityMs = mtime;
54768
54803
  if (isRecent(mtime, cutoff)) {
@@ -54778,9 +54813,9 @@ function detectInFlight(opts) {
54778
54813
  result.details.push(`session ${sessionId.slice(0, 8)} task ${newestSubject ?? "?"}`);
54779
54814
  }
54780
54815
  }
54781
- const projectsRoot = resolve14(opts.agentDir, ".claude", "projects");
54816
+ const projectsRoot = resolve15(opts.agentDir, ".claude", "projects");
54782
54817
  for (const slug of safeReaddir(projectsRoot)) {
54783
- const slugDir = resolve14(projectsRoot, slug);
54818
+ const slugDir = resolve15(projectsRoot, slug);
54784
54819
  for (const jsonl of collectJsonl(slugDir, 4)) {
54785
54820
  const mtime = safeMtimeMs(jsonl);
54786
54821
  if (mtime > result.lastActivityMs)
@@ -54831,11 +54866,11 @@ async function ask(question, defaultValue) {
54831
54866
  throw new Error(`Non-interactive mode: no default for "${question}"`);
54832
54867
  }
54833
54868
  const rl = createReadlineInterface();
54834
- return new Promise((resolve15) => {
54869
+ return new Promise((resolve16) => {
54835
54870
  const suffix = defaultValue ? ` [${defaultValue}]` : "";
54836
54871
  rl.question(`${question}${suffix}: `, (answer) => {
54837
54872
  rl.close();
54838
- resolve15(answer.trim() || defaultValue || "");
54873
+ resolve16(answer.trim() || defaultValue || "");
54839
54874
  });
54840
54875
  });
54841
54876
  }
@@ -54845,14 +54880,14 @@ async function askYesNo(question, defaultYes = true) {
54845
54880
  }
54846
54881
  const hint = defaultYes ? "[Y/n]" : "[y/N]";
54847
54882
  const rl = createReadlineInterface();
54848
- return new Promise((resolve15) => {
54883
+ return new Promise((resolve16) => {
54849
54884
  rl.question(`${question} ${hint} `, (answer) => {
54850
54885
  rl.close();
54851
54886
  const normalized = answer.trim().toLowerCase();
54852
54887
  if (normalized === "") {
54853
- resolve15(defaultYes);
54888
+ resolve16(defaultYes);
54854
54889
  } else {
54855
- resolve15(normalized === "y" || normalized === "yes");
54890
+ resolve16(normalized === "y" || normalized === "yes");
54856
54891
  }
54857
54892
  });
54858
54893
  });
@@ -54867,14 +54902,14 @@ ${question}`);
54867
54902
  console.log(` ${i + 1}) ${choices[i]}`);
54868
54903
  }
54869
54904
  const rl = createReadlineInterface();
54870
- return new Promise((resolve15) => {
54905
+ return new Promise((resolve16) => {
54871
54906
  rl.question(`Enter choice [1-${choices.length}]: `, (answer) => {
54872
54907
  rl.close();
54873
54908
  const idx = parseInt(answer.trim(), 10) - 1;
54874
54909
  if (idx >= 0 && idx < choices.length) {
54875
- resolve15(choices[idx]);
54910
+ resolve16(choices[idx]);
54876
54911
  } else {
54877
- resolve15(choices[0]);
54912
+ resolve16(choices[0]);
54878
54913
  }
54879
54914
  });
54880
54915
  });
@@ -54885,11 +54920,11 @@ async function waitForAction(message) {
54885
54920
  return;
54886
54921
  }
54887
54922
  const rl = createReadlineInterface();
54888
- return new Promise((resolve15) => {
54923
+ return new Promise((resolve16) => {
54889
54924
  rl.question(`${message}
54890
54925
  Press Enter when ready...`, () => {
54891
54926
  rl.close();
54892
- resolve15();
54927
+ resolve16();
54893
54928
  });
54894
54929
  });
54895
54930
  }
@@ -55772,7 +55807,7 @@ function readCacheTelemetry(agentDir) {
55772
55807
 
55773
55808
  // src/agents/create-orchestrator.ts
55774
55809
  init_loader();
55775
- import { resolve as resolve16 } from "node:path";
55810
+ import { resolve as resolve17 } from "node:path";
55776
55811
  import { existsSync as existsSync23, rmSync as rmSync6 } from "node:fs";
55777
55812
  init_lifecycle();
55778
55813
  init_manager();
@@ -55849,7 +55884,7 @@ async function pollForDmStart(token, timeoutMs = 120000) {
55849
55884
  throw new Error("Timed out waiting for /start DM");
55850
55885
  }
55851
55886
  function sleep(ms) {
55852
- return new Promise((resolve16) => setTimeout(resolve16, ms));
55887
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
55853
55888
  }
55854
55889
 
55855
55890
  // src/agents/create-orchestrator.ts
@@ -55876,8 +55911,8 @@ async function createAgent(opts) {
55876
55911
  const configPath = configPathOpt ?? (() => {
55877
55912
  const cwd = process.cwd();
55878
55913
  const candidates = [
55879
- resolve16(cwd, "switchroom.yaml"),
55880
- resolve16(cwd, "switchroom.yml")
55914
+ resolve17(cwd, "switchroom.yaml"),
55915
+ resolve17(cwd, "switchroom.yml")
55881
55916
  ];
55882
55917
  for (const c of candidates) {
55883
55918
  if (existsSync23(c))
@@ -55920,7 +55955,7 @@ async function createAgent(opts) {
55920
55955
  throw new Error(`Internal: wrote agent "${name}" to yaml but reload didn't pick it up.`);
55921
55956
  }
55922
55957
  const agentsDir = resolveAgentsDir(config);
55923
- const agentDir = resolve16(agentsDir, name);
55958
+ const agentDir = resolve17(agentsDir, name);
55924
55959
  await withRollback(() => {
55925
55960
  scaffoldAgent(name, agentConfig, agentsDir, config.telegram, config, undefined, configPath);
55926
55961
  rollbackStack.push(() => rmSync6(agentDir, { recursive: true, force: true }));
@@ -55941,7 +55976,7 @@ async function completeCreation(name, code, opts = {}) {
55941
55976
  }
55942
55977
  const configPath = opts.configPath ?? (() => {
55943
55978
  const cwd = process.cwd();
55944
- const candidates = [resolve16(cwd, "switchroom.yaml"), resolve16(cwd, "switchroom.yml")];
55979
+ const candidates = [resolve17(cwd, "switchroom.yaml"), resolve17(cwd, "switchroom.yml")];
55945
55980
  for (const c of candidates)
55946
55981
  if (existsSync23(c))
55947
55982
  return c;
@@ -55949,7 +55984,7 @@ async function completeCreation(name, code, opts = {}) {
55949
55984
  })();
55950
55985
  const config = loadConfig(configPath);
55951
55986
  const agentsDir = resolveAgentsDir(config);
55952
- const agentDir = resolve16(agentsDir, name);
55987
+ const agentDir = resolve17(agentsDir, name);
55953
55988
  if (!existsSync23(agentDir)) {
55954
55989
  throw new Error(`Agent dir not found: ${agentDir}. Run createAgent first.`);
55955
55990
  }
@@ -55989,7 +56024,7 @@ async function completeCreation(name, code, opts = {}) {
55989
56024
  }
55990
56025
 
55991
56026
  // src/agents/add-orchestrator.ts
55992
- import { resolve as resolve18, join as join18 } from "node:path";
56027
+ import { resolve as resolve19, join as join18 } from "node:path";
55993
56028
  import { existsSync as existsSync25, rmSync as rmSync7, statSync as statSync15 } from "node:fs";
55994
56029
  import { execFileSync as execFileSync12 } from "node:child_process";
55995
56030
 
@@ -56082,7 +56117,7 @@ function enforceUsername(username, agentSlug, expectedUsername, loose, warn) {
56082
56117
 
56083
56118
  // src/setup/profile-picker.ts
56084
56119
  import { existsSync as existsSync24, readdirSync as readdirSync12, statSync as statSync14 } from "node:fs";
56085
- import { resolve as resolve17 } from "node:path";
56120
+ import { resolve as resolve18 } from "node:path";
56086
56121
  var PROFILE_GLOSSES = {
56087
56122
  default: "minimal baseline \u2014 generic chat helper, no opinion.",
56088
56123
  coding: "developer copilot \u2014 architecture + code-review skills.",
@@ -56090,16 +56125,16 @@ var PROFILE_GLOSSES = {
56090
56125
  "health-coach": "wellness coach \u2014 daily check-ins, weekly reviews."
56091
56126
  };
56092
56127
  var DEFAULT_MAX_ATTEMPTS2 = 3;
56093
- var PROFILES_ROOT2 = resolve17(import.meta.dirname, "../../profiles");
56128
+ var PROFILES_ROOT2 = resolve18(import.meta.dirname, "../../profiles");
56094
56129
  function defaultListProfileSkills(profileName) {
56095
- const skillsDir = resolve17(PROFILES_ROOT2, profileName, "skills");
56130
+ const skillsDir = resolve18(PROFILES_ROOT2, profileName, "skills");
56096
56131
  if (!existsSync24(skillsDir)) {
56097
56132
  return [];
56098
56133
  }
56099
56134
  try {
56100
56135
  return readdirSync12(skillsDir).filter((entry) => {
56101
56136
  try {
56102
- return statSync14(resolve17(skillsDir, entry)).isDirectory();
56137
+ return statSync14(resolve18(skillsDir, entry)).isDirectory();
56103
56138
  } catch {
56104
56139
  return false;
56105
56140
  }
@@ -56378,7 +56413,7 @@ async function addAgent(opts) {
56378
56413
  }
56379
56414
  function runFinalPreflight(inputs) {
56380
56415
  const { name, agentDir, expectedUserId, isUnitActive, configPath } = inputs;
56381
- const unitPath = resolve18(process.env.HOME ?? "/root", ".config/systemd/user", `switchroom-${name}.service`);
56416
+ const unitPath = resolve19(process.env.HOME ?? "/root", ".config/systemd/user", `switchroom-${name}.service`);
56382
56417
  let autoaccept = { ok: false, detail: `unit not found at ${unitPath}` };
56383
56418
  if (existsSync25(unitPath)) {
56384
56419
  const fs2 = __require("node:fs");
@@ -56397,7 +56432,7 @@ function runFinalPreflight(inputs) {
56397
56432
  detail: `systemd unit missing at ${unitPath}. ` + `Fix: switchroom agent reconcile ${name}`
56398
56433
  };
56399
56434
  }
56400
- const envPath = resolve18(agentDir, "telegram", ".env");
56435
+ const envPath = resolve19(agentDir, "telegram", ".env");
56401
56436
  let token = { ok: false, detail: `telegram/.env missing at ${envPath}` };
56402
56437
  if (existsSync25(envPath)) {
56403
56438
  const fs2 = __require("node:fs");
@@ -56425,7 +56460,7 @@ function runFinalPreflight(inputs) {
56425
56460
  detail: `systemctl probe failed: ${err.message}`
56426
56461
  };
56427
56462
  }
56428
- const accessPath = resolve18(agentDir, "telegram", "access.json");
56463
+ const accessPath = resolve19(agentDir, "telegram", "access.json");
56429
56464
  let access;
56430
56465
  if (!existsSync25(accessPath)) {
56431
56466
  access = {
@@ -56452,7 +56487,7 @@ function runFinalPreflight(inputs) {
56452
56487
  };
56453
56488
  }
56454
56489
  }
56455
- const settingsPath = resolve18(agentDir, ".claude", "settings.json");
56490
+ const settingsPath = resolve19(agentDir, ".claude", "settings.json");
56456
56491
  let mcp;
56457
56492
  if (!existsSync25(settingsPath)) {
56458
56493
  mcp = {
@@ -56533,7 +56568,7 @@ function runFinalPreflight(inputs) {
56533
56568
  };
56534
56569
  }
56535
56570
  function pruneBundledSkills(agentDir, keep, scope) {
56536
- const skillsDir = resolve18(agentDir, ".claude", "skills");
56571
+ const skillsDir = resolve19(agentDir, ".claude", "skills");
56537
56572
  if (!existsSync25(skillsDir)) {
56538
56573
  return [];
56539
56574
  }
@@ -56581,7 +56616,7 @@ import { execFileSync as dockerExecFile } from "node:child_process";
56581
56616
  init_loader();
56582
56617
  init_vault();
56583
56618
  init_lifecycle();
56584
- import { resolve as resolve19 } from "node:path";
56619
+ import { resolve as resolve20 } from "node:path";
56585
56620
  import {
56586
56621
  existsSync as existsSync26,
56587
56622
  mkdtempSync as mkdtempSync3,
@@ -56609,7 +56644,7 @@ function defaultDeps() {
56609
56644
  saveVault,
56610
56645
  resolveVaultPath: (config) => resolvePath(config.vault?.path ?? "~/.switchroom/vault.enc"),
56611
56646
  snapshotDir: (src) => {
56612
- const tmp = mkdtempSync3(resolve19(tmpdir2(), "switchroom-rename-snap-"));
56647
+ const tmp = mkdtempSync3(resolve20(tmpdir2(), "switchroom-rename-snap-"));
56613
56648
  cpSync(src, tmp, { recursive: true });
56614
56649
  return tmp;
56615
56650
  },
@@ -56681,8 +56716,8 @@ async function renameAgent(opts, injectedDeps) {
56681
56716
  if (config.agents[newName]) {
56682
56717
  throw new Error(`Agent "${newName}" is already defined in switchroom.yaml. ` + `Choose a different name or remove the existing entry first.`);
56683
56718
  }
56684
- const oldAgentDir = resolve19(agentsDir, oldName);
56685
- const newAgentDir = resolve19(agentsDir, newName);
56719
+ const oldAgentDir = resolve20(agentsDir, oldName);
56720
+ const newAgentDir = resolve20(agentsDir, newName);
56686
56721
  if (!_existsSync(oldAgentDir)) {
56687
56722
  throw new Error(`Agent directory not found: ${oldAgentDir}. ` + `The agent may not have been scaffolded yet.`);
56688
56723
  }
@@ -56819,7 +56854,7 @@ async function renameAgent(opts, injectedDeps) {
56819
56854
  init_source();
56820
56855
  init_helpers();
56821
56856
  init_loader();
56822
- import { resolve as resolve20 } from "node:path";
56857
+ import { resolve as resolve21 } from "node:path";
56823
56858
  function registerAgentPerfCommand(agent) {
56824
56859
  agent.command("perf <name>").description("Show cache-hit telemetry for an agent (cache_read / cache_creation per-turn from the latest session JSONL)").option("--last <n>", "Number of recent assistant turns to analyze", "20").option("--full", "Analyze every turn in the JSONL (overrides --last)").option("--json", "Output as JSON").action(withConfigError(async (name, opts) => {
56825
56860
  const config = getConfig(program2(agent));
@@ -56829,8 +56864,8 @@ function registerAgentPerfCommand(agent) {
56829
56864
  console.error(source_default.red(`Agent "${name}" is not defined in switchroom.yaml`));
56830
56865
  process.exit(1);
56831
56866
  }
56832
- const agentDir = resolve20(agentsDir, name);
56833
- const claudeConfigDir = resolve20(agentDir, ".claude");
56867
+ const agentDir = resolve21(agentsDir, name);
56868
+ const claudeConfigDir = resolve21(agentDir, ".claude");
56834
56869
  const jsonl = findLatestSessionJsonl(claudeConfigDir);
56835
56870
  if (!jsonl) {
56836
56871
  if (opts.json) {
@@ -57031,11 +57066,11 @@ function checkQuarantineRefusal(agentsDir, name) {
57031
57066
  }
57032
57067
  function preflightCheck(name, agentDir, _usesDevChannels) {
57033
57068
  const errors2 = [];
57034
- const startSh = resolve21(agentDir, "start.sh");
57069
+ const startSh = resolve22(agentDir, "start.sh");
57035
57070
  if (!existsSync28(startSh)) {
57036
57071
  errors2.push(`start.sh not found at ${startSh}`);
57037
57072
  }
57038
- const envPath = resolve21(agentDir, "telegram", ".env");
57073
+ const envPath = resolve22(agentDir, "telegram", ".env");
57039
57074
  if (existsSync28(envPath)) {
57040
57075
  const envContent = readFileSync23(envPath, "utf-8");
57041
57076
  if (!envContent.includes("TELEGRAM_BOT_TOKEN=") || envContent.includes("# Set your bot token")) {
@@ -57044,13 +57079,13 @@ function preflightCheck(name, agentDir, _usesDevChannels) {
57044
57079
  } else {
57045
57080
  errors2.push(`telegram/.env not found at ${envPath}`);
57046
57081
  }
57047
- if (!existsSync28(resolve21(agentDir, ".claude", "settings.json"))) {
57082
+ if (!existsSync28(resolve22(agentDir, ".claude", "settings.json"))) {
57048
57083
  errors2.push(`.claude/settings.json not found. Run: switchroom agent reconcile ${name}`);
57049
57084
  }
57050
57085
  return errors2;
57051
57086
  }
57052
57087
  function buildStatusInputs(name, config, agentsDir) {
57053
- const agentDir = resolve21(agentsDir, name);
57088
+ const agentDir = resolve22(agentsDir, name);
57054
57089
  const agentConfig = config.agents[name];
57055
57090
  let hindsightApiUrl = null;
57056
57091
  let hindsightBankId = name;
@@ -57199,7 +57234,7 @@ async function reconcileAndRestartAgent(name, config, agentsDir, configPath, opt
57199
57234
  }
57200
57235
  }
57201
57236
  if (!opts.force) {
57202
- const envPath = resolve21(agentsDir, name, "telegram", ".env");
57237
+ const envPath = resolve22(agentsDir, name, "telegram", ".env");
57203
57238
  if (existsSync28(envPath)) {
57204
57239
  const envContent = readFileSync23(envPath, "utf-8");
57205
57240
  const match = envContent.match(/^TELEGRAM_BOT_TOKEN=(.+)$/m);
@@ -57318,7 +57353,7 @@ function registerAgentCommand(program3) {
57318
57353
  console.error(source_default.red(`Agent "${name}" is not defined in switchroom.yaml`));
57319
57354
  process.exit(1);
57320
57355
  }
57321
- const agentDir = resolve21(agentsDir, name);
57356
+ const agentDir = resolve22(agentsDir, name);
57322
57357
  let hindsightApiUrl = null;
57323
57358
  let hindsightBankId = name;
57324
57359
  if (isHindsightEnabled(config)) {
@@ -57389,7 +57424,7 @@ function registerAgentCommand(program3) {
57389
57424
  Scaffolding agent: ${name}
57390
57425
  `));
57391
57426
  scaffoldAgent(name, agentConfig, agentsDir, config.telegram, config, undefined, getConfigPath(program3));
57392
- const agentDir = resolve21(agentsDir, name);
57427
+ const agentDir = resolve22(agentsDir, name);
57393
57428
  console.log(source_default.green(` Agent "${name}" scaffolded at ${agentDir}`));
57394
57429
  console.log(source_default.gray(`
57395
57430
  Next: switchroom apply (regenerates docker-compose.yml + brings up new agent)
@@ -57408,7 +57443,7 @@ Scaffolding agent: ${name}
57408
57443
  continue;
57409
57444
  }
57410
57445
  if (!opts.force) {
57411
- const agentDir = resolve21(agentsDir, n);
57446
+ const agentDir = resolve22(agentsDir, n);
57412
57447
  const usesDevChannels = config.agents[n].channels?.telegram?.plugin !== "official";
57413
57448
  const errors2 = preflightCheck(n, agentDir, usesDevChannels);
57414
57449
  if (errors2.length > 0) {
@@ -57510,7 +57545,7 @@ Scaffolding agent: ${name}
57510
57545
  sawAbort = true;
57511
57546
  continue;
57512
57547
  }
57513
- const agentDir = resolve21(agentsDir, n);
57548
+ const agentDir = resolve22(agentsDir, n);
57514
57549
  if (!opts.force) {
57515
57550
  const usesDevChannels = config.agents[n].channels?.telegram?.plugin !== "official";
57516
57551
  const errors2 = preflightCheck(n, agentDir, usesDevChannels);
@@ -57696,7 +57731,7 @@ Scaffolding agent: ${name}
57696
57731
  useSwitchroomPlugin: usesSwitchroomTelegramPlugin(agentConfig),
57697
57732
  configPath
57698
57733
  });
57699
- const settingsPath = resolve21(agentsDir, n, ".claude", "settings.json");
57734
+ const settingsPath = resolve22(agentsDir, n, ".claude", "settings.json");
57700
57735
  let actual = {};
57701
57736
  if (existsSync28(settingsPath)) {
57702
57737
  try {
@@ -57941,7 +57976,7 @@ Reconciled ${agentsTouched} agent(s), ${totalChanges} file(s) changed.`));
57941
57976
  agent.command("permissions <name>").description("Show the current permissions.allow list for an agent").action(withConfigError(async (name) => {
57942
57977
  const config = getConfig(program3);
57943
57978
  const agentsDir = resolveAgentsDir(config);
57944
- const settingsPath = resolve21(agentsDir, name, ".claude", "settings.json");
57979
+ const settingsPath = resolve22(agentsDir, name, ".claude", "settings.json");
57945
57980
  if (!existsSync28(settingsPath)) {
57946
57981
  console.error(source_default.red(`Agent "${name}" not found at ${settingsPath}`));
57947
57982
  process.exit(1);
@@ -57971,12 +58006,12 @@ Permissions for ${name}
57971
58006
  agent.command("destroy <name>").description("Remove an agent's directory (run `switchroom apply` after to remove the container)").option("-y, --yes", "Skip confirmation prompt").action(withConfigError(async (name, opts) => {
57972
58007
  const config = getConfig(program3);
57973
58008
  const agentsDir = resolveAgentsDir(config);
57974
- const agentDir = resolve21(agentsDir, name);
58009
+ const agentDir = resolve22(agentsDir, name);
57975
58010
  if (!opts.yes) {
57976
58011
  process.stdout.write(source_default.yellow(`Destroy agent "${name}"? This removes ${agentDir}. (Run \`switchroom apply\` after to take the container down.) [y/N] `));
57977
- const response = await new Promise((resolve22) => {
58012
+ const response = await new Promise((resolve23) => {
57978
58013
  process.stdin.setEncoding("utf-8");
57979
- process.stdin.once("data", (data) => resolve22(data.toString().trim()));
58014
+ process.stdin.once("data", (data) => resolve23(data.toString().trim()));
57980
58015
  });
57981
58016
  if (response.toLowerCase() !== "y") {
57982
58017
  console.log("Aborted.");
@@ -58051,7 +58086,7 @@ Bootstrapping agent: ${name}
58051
58086
  `));
58052
58087
  }
58053
58088
  process.stdout.write(source_default.bold(" Paste the browser code here: "));
58054
- const code = await new Promise((resolve22) => {
58089
+ const code = await new Promise((resolve23) => {
58055
58090
  process.stdin.setEncoding("utf-8");
58056
58091
  let buf = "";
58057
58092
  process.stdin.on("data", (chunk) => {
@@ -58060,7 +58095,7 @@ Bootstrapping agent: ${name}
58060
58095
  `);
58061
58096
  if (newlineIdx !== -1) {
58062
58097
  process.stdin.removeAllListeners("data");
58063
- resolve22(buf.slice(0, newlineIdx).trim());
58098
+ resolve23(buf.slice(0, newlineIdx).trim());
58064
58099
  }
58065
58100
  });
58066
58101
  });
@@ -58188,7 +58223,7 @@ switchroom agent add: ${name}
58188
58223
  composePath = upRes.composePath;
58189
58224
  console.log(source_default.gray(` Wrote compose: ${composePath}`));
58190
58225
  } catch (err) {
58191
- composePath = resolve21(process.env.SWITCHROOM_HOME ?? resolve21(process.env.HOME ?? "", ".switchroom"), "compose", "docker-compose.yml");
58226
+ composePath = resolve22(process.env.SWITCHROOM_HOME ?? resolve22(process.env.HOME ?? "", ".switchroom"), "compose", "docker-compose.yml");
58192
58227
  console.error(source_default.red(` docker compose up failed: ${err.message}`));
58193
58228
  try {
58194
58229
  dockerExecFile("docker", [
@@ -58204,7 +58239,7 @@ switchroom agent add: ${name}
58204
58239
  stopAgent(name);
58205
58240
  } catch {}
58206
58241
  const agentsDirRollback = resolveAgentsDir(cfg);
58207
- const agentDirRollback = resolve21(agentsDirRollback, name);
58242
+ const agentDirRollback = resolve22(agentsDirRollback, name);
58208
58243
  if (existsSync28(agentDirRollback)) {
58209
58244
  rmSync9(agentDirRollback, { recursive: true, force: true });
58210
58245
  console.log(source_default.gray(` Rolled back: removed ${agentDirRollback}`));
@@ -58256,9 +58291,9 @@ Rename agent "${oldName}" \u2192 "${newName}"?
58256
58291
  ` + ` reconcile, and start ${newName}.
58257
58292
  ` + ` Hindsight mode: ${hindsightMode}
58258
58293
  ` + `[y/N] `));
58259
- const answer = await new Promise((resolve22) => {
58294
+ const answer = await new Promise((resolve23) => {
58260
58295
  process.stdin.setEncoding("utf-8");
58261
- process.stdin.once("data", (d) => resolve22(d.toString().trim()));
58296
+ process.stdin.once("data", (d) => resolve23(d.toString().trim()));
58262
58297
  });
58263
58298
  if (answer.toLowerCase() !== "y") {
58264
58299
  console.log("Aborted.");
@@ -58787,7 +58822,7 @@ init_loader();
58787
58822
  init_manager();
58788
58823
  init_helpers();
58789
58824
  import { existsSync as existsSync33, readFileSync as readFileSync28 } from "node:fs";
58790
- import { join as join26, resolve as resolve24 } from "node:path";
58825
+ import { join as join26, resolve as resolve25 } from "node:path";
58791
58826
 
58792
58827
  // src/cli/auth-google.ts
58793
58828
  init_source();
@@ -59356,8 +59391,8 @@ async function readVisibleLine(prompt) {
59356
59391
  output: process.stdout
59357
59392
  });
59358
59393
  try {
59359
- return await new Promise((resolve23) => {
59360
- rl.question(prompt, (answer) => resolve23(answer));
59394
+ return await new Promise((resolve24) => {
59395
+ rl.question(prompt, (answer) => resolve24(answer));
59361
59396
  });
59362
59397
  } finally {
59363
59398
  rl.close();
@@ -59365,7 +59400,7 @@ async function readVisibleLine(prompt) {
59365
59400
  }
59366
59401
  async function readHiddenLine(prompt) {
59367
59402
  const { createInterface: createInterface3 } = await import("node:readline");
59368
- return await new Promise((resolve23, reject) => {
59403
+ return await new Promise((resolve24, reject) => {
59369
59404
  const rl = createInterface3({
59370
59405
  input: process.stdin,
59371
59406
  output: process.stdout
@@ -59385,7 +59420,7 @@ async function readHiddenLine(prompt) {
59385
59420
  rl.close();
59386
59421
  process.stdout.write(`
59387
59422
  `);
59388
- resolve23(input);
59423
+ resolve24(input);
59389
59424
  } else if (char === "\x03") {
59390
59425
  stdin.setRawMode(false);
59391
59426
  stdin.removeListener("data", onData);
@@ -59404,7 +59439,7 @@ async function readHiddenLine(prompt) {
59404
59439
  } else {
59405
59440
  rl.question(prompt, (answer) => {
59406
59441
  rl.close();
59407
- resolve23(answer);
59442
+ resolve24(answer);
59408
59443
  });
59409
59444
  }
59410
59445
  });
@@ -60024,14 +60059,14 @@ async function readHiddenLine2(prompt) {
60024
60059
  input: process.stdin,
60025
60060
  output: process.stdout
60026
60061
  });
60027
- return new Promise((resolve23) => {
60062
+ return new Promise((resolve24) => {
60028
60063
  rl.question(prompt, (answer) => {
60029
60064
  rl.close();
60030
- resolve23(answer);
60065
+ resolve24(answer);
60031
60066
  });
60032
60067
  });
60033
60068
  }
60034
- return new Promise((resolve23, reject) => {
60069
+ return new Promise((resolve24, reject) => {
60035
60070
  const rl = readline.createInterface({
60036
60071
  input: process.stdin,
60037
60072
  output: process.stdout
@@ -60053,7 +60088,7 @@ async function readHiddenLine2(prompt) {
60053
60088
  rl.close();
60054
60089
  stdout.write(`
60055
60090
  `);
60056
- resolve23(line);
60091
+ resolve24(line);
60057
60092
  return;
60058
60093
  }
60059
60094
  if (ch === "" || ch === "\b") {
@@ -60497,7 +60532,7 @@ function printAgentDetail(state, agent) {
60497
60532
  function loadCredentialsFromAgent(agentName) {
60498
60533
  const config = getConfigSafe();
60499
60534
  const agentsDir = resolveAgentsDir(config);
60500
- const agentDir = resolve24(agentsDir, agentName);
60535
+ const agentDir = resolve25(agentsDir, agentName);
60501
60536
  const credsPath = join26(agentDir, ".claude", ".credentials.json");
60502
60537
  if (!existsSync33(credsPath)) {
60503
60538
  console.error(source_default.red(` Agent "${agentName}" has no .claude/.credentials.json \u2014 log it in first.`));
@@ -60570,8 +60605,8 @@ async function loadCredentialsViaClaude(label) {
60570
60605
  output: process.stdout
60571
60606
  });
60572
60607
  try {
60573
- return await new Promise((resolve25) => {
60574
- rl.question(" Paste the code Claude shows you: ", (answer) => resolve25(answer));
60608
+ return await new Promise((resolve26) => {
60609
+ rl.question(" Paste the code Claude shows you: ", (answer) => resolve26(answer));
60575
60610
  });
60576
60611
  } finally {
60577
60612
  rl.close();
@@ -61229,7 +61264,7 @@ init_compose();
61229
61264
  init_vault();
61230
61265
  import * as net3 from "node:net";
61231
61266
  import { mkdirSync as mkdirSync23, chmodSync as chmodSync7, chownSync as chownSync4, existsSync as existsSync37, readFileSync as readFileSync32, readdirSync as readdirSync17, statSync as statSync20, unlinkSync as unlinkSync8, writeFileSync as writeFileSync19, renameSync as renameSync10 } from "node:fs";
61232
- import { dirname as dirname7, resolve as resolve26, basename as basename6 } from "node:path";
61267
+ import { dirname as dirname8, resolve as resolve27, basename as basename6 } from "node:path";
61233
61268
  import * as os4 from "node:os";
61234
61269
  import * as path3 from "node:path";
61235
61270
 
@@ -61240,7 +61275,7 @@ import {
61240
61275
  chmodSync as chmodSync4,
61241
61276
  existsSync as existsSync35,
61242
61277
  fsyncSync as fsyncSync4,
61243
- lstatSync as lstatSync5,
61278
+ lstatSync as lstatSync6,
61244
61279
  mkdirSync as mkdirSync20,
61245
61280
  openSync as openSync6,
61246
61281
  closeSync as closeSync6,
@@ -61251,7 +61286,7 @@ import {
61251
61286
  unlinkSync as unlinkSync7
61252
61287
  } from "node:fs";
61253
61288
  import { createHash as createHash5 } from "node:crypto";
61254
- import { basename as basename5, dirname as dirname4, join as join28 } from "node:path";
61289
+ import { basename as basename5, dirname as dirname5, join as join28 } from "node:path";
61255
61290
  function vaultLayoutPaths(home2) {
61256
61291
  const switchroomRoot = join28(home2, ".switchroom");
61257
61292
  return {
@@ -61394,7 +61429,7 @@ your fleet works after \`switchroom apply\`, then delete it.
61394
61429
  }
61395
61430
  function lstatSyncOrNull(path) {
61396
61431
  try {
61397
- return lstatSync5(path);
61432
+ return lstatSync6(path);
61398
61433
  } catch {
61399
61434
  return null;
61400
61435
  }
@@ -61404,7 +61439,7 @@ function sha256File(path) {
61404
61439
  return createHash5("sha256").update(data).digest("hex");
61405
61440
  }
61406
61441
  function atomicReplaceWithSymlink(target, linkTarget) {
61407
- const tmp = join28(dirname4(target), `.${basename5(target)}.symlink-tmp`);
61442
+ const tmp = join28(dirname5(target), `.${basename5(target)}.symlink-tmp`);
61408
61443
  if (existsSync35(tmp)) {
61409
61444
  try {
61410
61445
  unlinkSync7(tmp);
@@ -61436,7 +61471,7 @@ init_loader();
61436
61471
  // src/vault/auto-unlock.ts
61437
61472
  import { createHmac, randomBytes as randomBytes6, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2 } from "node:crypto";
61438
61473
  import { chmodSync as chmodSync5, existsSync as existsSync36, mkdirSync as mkdirSync21, readFileSync as readFileSync31, writeFileSync as writeFileSync18 } from "node:fs";
61439
- import { dirname as dirname5 } from "node:path";
61474
+ import { dirname as dirname6 } from "node:path";
61440
61475
  var FORMAT_VERSION = 1;
61441
61476
  var SALT_LEN = 16;
61442
61477
  var NONCE_LEN = 12;
@@ -61525,7 +61560,7 @@ function decryptAutoUnlock(blob, machineId) {
61525
61560
  }
61526
61561
  function writeAutoUnlockFile(passphrase, filePath) {
61527
61562
  const blob = encryptAutoUnlock(passphrase);
61528
- mkdirSync21(dirname5(filePath), { recursive: true, mode: 448 });
61563
+ mkdirSync21(dirname6(filePath), { recursive: true, mode: 448 });
61529
61564
  writeFileSync18(filePath, blob, { mode: 384 });
61530
61565
  chmodSync5(filePath, 384);
61531
61566
  }
@@ -61557,7 +61592,7 @@ import * as path from "node:path";
61557
61592
  // src/vault/broker/test-isolation-guard.ts
61558
61593
  import { mkdtempSync as mkdtempSync4 } from "node:fs";
61559
61594
  import { homedir as homedir14, tmpdir as tmpdir3 } from "node:os";
61560
- import { join as join29, resolve as resolve25, sep } from "node:path";
61595
+ import { join as join29, resolve as resolve26, sep } from "node:path";
61561
61596
  function isTestRuntime() {
61562
61597
  return process.env.VITEST !== undefined;
61563
61598
  }
@@ -61565,11 +61600,11 @@ function escapeHatchSet() {
61565
61600
  return process.env.SWITCHROOM_ALLOW_PROD_VAULT_IN_TEST === "1";
61566
61601
  }
61567
61602
  function realSwitchroomHome() {
61568
- return resolve25(homedir14(), ".switchroom");
61603
+ return resolve26(homedir14(), ".switchroom");
61569
61604
  }
61570
61605
  function isUnderRealSwitchroomHome(p) {
61571
61606
  const home2 = realSwitchroomHome();
61572
- const r = resolve25(p);
61607
+ const r = resolve26(p);
61573
61608
  return r === home2 || r.startsWith(home2 + sep);
61574
61609
  }
61575
61610
  var warnedVault = false;
@@ -61704,13 +61739,13 @@ function genSalt(rounds, seed_length, callback) {
61704
61739
  throw Error("Illegal callback: " + typeof callback);
61705
61740
  _async(callback);
61706
61741
  } else
61707
- return new Promise(function(resolve26, reject) {
61742
+ return new Promise(function(resolve27, reject) {
61708
61743
  _async(function(err, res) {
61709
61744
  if (err) {
61710
61745
  reject(err);
61711
61746
  return;
61712
61747
  }
61713
- resolve26(res);
61748
+ resolve27(res);
61714
61749
  });
61715
61750
  });
61716
61751
  }
@@ -61730,13 +61765,13 @@ function hash(password, salt, callback, progressCallback) {
61730
61765
  throw Error("Illegal callback: " + typeof callback);
61731
61766
  _async(callback);
61732
61767
  } else
61733
- return new Promise(function(resolve26, reject) {
61768
+ return new Promise(function(resolve27, reject) {
61734
61769
  _async(function(err, res) {
61735
61770
  if (err) {
61736
61771
  reject(err);
61737
61772
  return;
61738
61773
  }
61739
- resolve26(res);
61774
+ resolve27(res);
61740
61775
  });
61741
61776
  });
61742
61777
  }
@@ -61769,13 +61804,13 @@ function compare(password, hashValue, callback, progressCallback) {
61769
61804
  throw Error("Illegal callback: " + typeof callback);
61770
61805
  _async(callback);
61771
61806
  } else
61772
- return new Promise(function(resolve26, reject) {
61807
+ return new Promise(function(resolve27, reject) {
61773
61808
  _async(function(err, res) {
61774
61809
  if (err) {
61775
61810
  reject(err);
61776
61811
  return;
61777
61812
  }
61778
- resolve26(res);
61813
+ resolve27(res);
61779
61814
  });
61780
61815
  });
61781
61816
  }
@@ -63935,7 +63970,7 @@ class VaultBroker {
63935
63970
  if (process.platform !== "linux" && process.env.SWITCHROOM_BROKER_ALLOW_NON_LINUX !== "1") {
63936
63971
  throw new Error(`vault-broker is Linux-only (running on ${process.platform}). ` + `The broker's ACL relies on cgroup-based systemd unit identification, ` + `which is not available on this platform. ` + `Use 'switchroom vault get --no-broker' for direct vault access. ` + `If you need to run the broker for development on this platform, ` + `set SWITCHROOM_BROKER_ALLOW_NON_LINUX=1 \u2014 but understand that the ` + `broker will accept any same-user caller without per-cron ACL enforcement.`);
63937
63972
  }
63938
- this.socketPath = resolve26(socketPath);
63973
+ this.socketPath = resolve27(socketPath);
63939
63974
  this.unlockSocketPath = unlockSocketFor(this.socketPath);
63940
63975
  this.startedAt = Date.now();
63941
63976
  if (this.testOpts._testConfig) {
@@ -63945,7 +63980,7 @@ class VaultBroker {
63945
63980
  this.config = loadConfig2(configPath);
63946
63981
  }
63947
63982
  if (vaultPath) {
63948
- this.vaultPath = resolve26(vaultPath);
63983
+ this.vaultPath = resolve27(vaultPath);
63949
63984
  } else {
63950
63985
  this.vaultPath = resolvePath(this.config.vault?.path ?? "~/.switchroom/vault.enc");
63951
63986
  }
@@ -63957,7 +63992,7 @@ class VaultBroker {
63957
63992
  this.passphrase = this.testOpts._testPassphrase;
63958
63993
  }
63959
63994
  process.umask(63);
63960
- const parentDir = dirname7(this.socketPath);
63995
+ const parentDir = dirname8(this.socketPath);
63961
63996
  mkdirSync23(parentDir, { recursive: true, mode: 448 });
63962
63997
  try {
63963
63998
  chmodSync7(parentDir, 448);
@@ -64060,7 +64095,7 @@ class VaultBroker {
64060
64095
  return this.secrets;
64061
64096
  }
64062
64097
  bindAgentSocket(socketPath) {
64063
- const abs = resolve26(socketPath);
64098
+ const abs = resolve27(socketPath);
64064
64099
  const agentName = socketPathToAgent(abs);
64065
64100
  if (agentName === null) {
64066
64101
  return Promise.reject(new Error(`bindAgentSocket: socket path '${abs}' does not match the canonical ` + `/run/switchroom/broker/<agent>.sock shape \u2014 refusing to bind without ` + `a verifiable agent identity`));
@@ -64140,7 +64175,7 @@ class VaultBroker {
64140
64175
  });
64141
64176
  }
64142
64177
  _bindDataSocket() {
64143
- return new Promise((resolve27, reject) => {
64178
+ return new Promise((resolve28, reject) => {
64144
64179
  const server = net3.createServer((socket) => {
64145
64180
  this._handleDataConnection(socket);
64146
64181
  });
@@ -64152,7 +64187,7 @@ class VaultBroker {
64152
64187
  chmodSync7(this.socketPath, 384);
64153
64188
  } catch {}
64154
64189
  this.server = server;
64155
- resolve27();
64190
+ resolve28();
64156
64191
  });
64157
64192
  });
64158
64193
  }
@@ -64169,7 +64204,7 @@ class VaultBroker {
64169
64204
  } catch {}
64170
64205
  }
64171
64206
  bindOperatorListener(socketPath, operatorUid) {
64172
- const abs = resolve26(socketPath);
64207
+ const abs = resolve27(socketPath);
64173
64208
  const identity = socketPathToIdentity(abs);
64174
64209
  if (identity?.kind !== "operator") {
64175
64210
  return Promise.reject(new Error(`bindOperatorListener: socket path '${abs}' does not match the canonical ` + `/run/switchroom/broker/operator/sock shape \u2014 refusing to bind`));
@@ -64233,7 +64268,7 @@ class VaultBroker {
64233
64268
  });
64234
64269
  }
64235
64270
  _bindUnlockSocket() {
64236
- return new Promise((resolve27, reject) => {
64271
+ return new Promise((resolve28, reject) => {
64237
64272
  const server = net3.createServer((socket) => {
64238
64273
  this._handleUnlockConnection(socket);
64239
64274
  });
@@ -64245,7 +64280,7 @@ class VaultBroker {
64245
64280
  chmodSync7(this.unlockSocketPath, 384);
64246
64281
  } catch {}
64247
64282
  this.unlockServer = server;
64248
- resolve27();
64283
+ resolve28();
64249
64284
  });
64250
64285
  });
64251
64286
  }
@@ -65430,15 +65465,15 @@ class VaultBroker {
65430
65465
  }
65431
65466
  }
65432
65467
  function detectVaultLayoutDrift(vaultPath) {
65433
- const dir = dirname7(vaultPath);
65468
+ const dir = dirname8(vaultPath);
65434
65469
  if (basename6(dir) !== "vault")
65435
65470
  return;
65436
65471
  if (basename6(vaultPath) !== "vault.enc")
65437
65472
  return;
65438
- const switchroomDir = dirname7(dir);
65473
+ const switchroomDir = dirname8(dir);
65439
65474
  if (basename6(switchroomDir) !== ".switchroom")
65440
65475
  return;
65441
- const home2 = dirname7(switchroomDir);
65476
+ const home2 = dirname8(switchroomDir);
65442
65477
  const result = inspectVaultLayout(home2);
65443
65478
  if (result.kind === "divergent") {
65444
65479
  throw new VaultError(`Vault layout divergence detected at boot: ${result.details.oldPath} and ${result.details.newPath} are both regular files with different content. An older switchroom CLI may have written to the legacy path after migration ran. Run \`switchroom apply\` from the host to surface the recovery recipe (state E refusal with literal \`mv\` commands). See docs/operators/state-e-recovery.md.`);
@@ -65472,11 +65507,11 @@ async function main() {
65472
65507
  if (e.name.startsWith("."))
65473
65508
  continue;
65474
65509
  if ((e.isFile() || e.isSocket()) && e.name.endsWith(".sock")) {
65475
- flat.push(resolve26(perAgentDir, e.name));
65510
+ flat.push(resolve27(perAgentDir, e.name));
65476
65511
  continue;
65477
65512
  }
65478
65513
  if (e.isDirectory()) {
65479
- const candidate = resolve26(perAgentDir, e.name, "sock");
65514
+ const candidate = resolve27(perAgentDir, e.name, "sock");
65480
65515
  if (socketPathToAgent(candidate) !== null) {
65481
65516
  subdirs.push(candidate);
65482
65517
  }
@@ -65658,7 +65693,7 @@ function getAutoUnlockCredPath(configPath) {
65658
65693
  async function promptPassphrase() {
65659
65694
  if (!process.stdin.isTTY) {
65660
65695
  const { createInterface: createInterface3 } = await import("node:readline");
65661
- return new Promise((resolve27, reject) => {
65696
+ return new Promise((resolve28, reject) => {
65662
65697
  const rl = createInterface3({ input: process.stdin, terminal: false });
65663
65698
  let settled = false;
65664
65699
  rl.once("line", (line) => {
@@ -65669,7 +65704,7 @@ async function promptPassphrase() {
65669
65704
  reject(new Error("Empty passphrase \u2014 aborting"));
65670
65705
  return;
65671
65706
  }
65672
- resolve27(passphrase);
65707
+ resolve28(passphrase);
65673
65708
  });
65674
65709
  rl.once("close", () => {
65675
65710
  if (!settled) {
@@ -65678,7 +65713,7 @@ async function promptPassphrase() {
65678
65713
  });
65679
65714
  });
65680
65715
  }
65681
- return new Promise((resolve27, reject) => {
65716
+ return new Promise((resolve28, reject) => {
65682
65717
  process.stdout.write("Vault passphrase: ");
65683
65718
  const stdin = process.stdin;
65684
65719
  stdin.setRawMode(true);
@@ -65698,7 +65733,7 @@ async function promptPassphrase() {
65698
65733
  if (!input) {
65699
65734
  reject(new Error("Empty passphrase \u2014 aborting"));
65700
65735
  } else {
65701
- resolve27(input);
65736
+ resolve28(input);
65702
65737
  }
65703
65738
  } else if (char === "\x03") {
65704
65739
  cleanup();
@@ -66773,7 +66808,7 @@ function getVaultPath4(configPath) {
66773
66808
  }
66774
66809
  }
66775
66810
  function promptLine2(prompt, hidden = false) {
66776
- return new Promise((resolve27, reject) => {
66811
+ return new Promise((resolve28, reject) => {
66777
66812
  const rl = createInterface3({
66778
66813
  input: process.stdin,
66779
66814
  output: process.stderr
@@ -66793,7 +66828,7 @@ function promptLine2(prompt, hidden = false) {
66793
66828
  rl.close();
66794
66829
  process.stderr.write(`
66795
66830
  `);
66796
- resolve27(input);
66831
+ resolve28(input);
66797
66832
  } else if (char === "\x03") {
66798
66833
  stdin.setRawMode(false);
66799
66834
  stdin.removeListener("data", onData);
@@ -66813,17 +66848,17 @@ function promptLine2(prompt, hidden = false) {
66813
66848
  } else {
66814
66849
  rl.question(prompt, (answer) => {
66815
66850
  rl.close();
66816
- resolve27(answer);
66851
+ resolve28(answer);
66817
66852
  });
66818
66853
  }
66819
66854
  });
66820
66855
  }
66821
66856
  function readStdinToEnd() {
66822
- return new Promise((resolve27, reject) => {
66857
+ return new Promise((resolve28, reject) => {
66823
66858
  const chunks = [];
66824
66859
  process.stdin.on("data", (chunk) => chunks.push(chunk));
66825
66860
  process.stdin.on("end", () => {
66826
- resolve27(Buffer.concat(chunks).toString("utf8"));
66861
+ resolve28(Buffer.concat(chunks).toString("utf8"));
66827
66862
  });
66828
66863
  process.stdin.on("error", reject);
66829
66864
  });
@@ -68073,7 +68108,7 @@ function registerDispatchVerb(tg, _program) {
68073
68108
  }));
68074
68109
  }
68075
68110
  function promptHidden2(prompt) {
68076
- return new Promise((resolve27, reject) => {
68111
+ return new Promise((resolve28, reject) => {
68077
68112
  const rl = createInterface4({ input: process.stdin, output: process.stdout });
68078
68113
  if (process.stdin.isTTY) {
68079
68114
  process.stdout.write(prompt);
@@ -68090,7 +68125,7 @@ function promptHidden2(prompt) {
68090
68125
  rl.close();
68091
68126
  process.stdout.write(`
68092
68127
  `);
68093
- resolve27(input);
68128
+ resolve28(input);
68094
68129
  } else if (char === "\x03") {
68095
68130
  stdin.setRawMode(false);
68096
68131
  stdin.removeListener("data", onData);
@@ -68109,7 +68144,7 @@ function promptHidden2(prompt) {
68109
68144
  } else {
68110
68145
  rl.question(prompt, (answer) => {
68111
68146
  rl.close();
68112
- resolve27(answer);
68147
+ resolve28(answer);
68113
68148
  });
68114
68149
  }
68115
68150
  });
@@ -68447,11 +68482,11 @@ var HINDSIGHT_DEFAULT_MEM_RESERVATION = "2g";
68447
68482
  var HINDSIGHT_DEFAULT_PIDS_LIMIT = 1000;
68448
68483
  var HINDSIGHT_DEFAULT_SHM_SIZE = "2g";
68449
68484
  function isPortFree(port) {
68450
- return new Promise((resolve27) => {
68485
+ return new Promise((resolve28) => {
68451
68486
  const server = createServer4();
68452
- server.once("error", () => resolve27(false));
68487
+ server.once("error", () => resolve28(false));
68453
68488
  server.once("listening", () => {
68454
- server.close(() => resolve27(true));
68489
+ server.close(() => resolve28(true));
68455
68490
  });
68456
68491
  server.listen(port, "127.0.0.1");
68457
68492
  });
@@ -68982,7 +69017,7 @@ import {
68982
69017
  writeSync as writeSync6,
68983
69018
  constants as fsConstants3
68984
69019
  } from "node:fs";
68985
- import { resolve as resolve28, extname, join as join47, relative, dirname as dirname10 } from "node:path";
69020
+ import { resolve as resolve29, extname, join as join47, relative, dirname as dirname11 } from "node:path";
68986
69021
  import { homedir as homedir26 } from "node:os";
68987
69022
  import { timingSafeEqual as timingSafeEqual3, randomBytes as randomBytes11 } from "node:crypto";
68988
69023
 
@@ -68992,7 +69027,7 @@ init_manager();
68992
69027
  init_hindsight();
68993
69028
  import { spawnSync as spawnSync5 } from "node:child_process";
68994
69029
  import { existsSync as existsSync47, readFileSync as readFileSync43, statSync as statSync22 } from "node:fs";
68995
- import { resolve as resolve27, join as join44 } from "node:path";
69030
+ import { resolve as resolve28, join as join44 } from "node:path";
68996
69031
 
68997
69032
  // src/web/memory-remediation.ts
68998
69033
  init_hindsight();
@@ -69126,7 +69161,7 @@ init_client();
69126
69161
  import { homedir as homedir23 } from "node:os";
69127
69162
 
69128
69163
  // node_modules/.bun/posthog-node@5.29.2/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
69129
- import { dirname as dirname8, posix, sep as sep2 } from "path";
69164
+ import { dirname as dirname9, posix, sep as sep2 } from "path";
69130
69165
  function createModulerModifier() {
69131
69166
  const getModuleFromFileName = createGetModuleFromFilename();
69132
69167
  return async (frames) => {
@@ -69135,7 +69170,7 @@ function createModulerModifier() {
69135
69170
  return frames;
69136
69171
  };
69137
69172
  }
69138
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname8(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
69173
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname9(process.argv[1]) : process.cwd(), isWindows = sep2 === "\\") {
69139
69174
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
69140
69175
  return (filename) => {
69141
69176
  if (!filename)
@@ -71474,14 +71509,14 @@ async function addSourceContext(frames) {
71474
71509
  return frames;
71475
71510
  }
71476
71511
  function getContextLinesFromFile(path4, ranges, output) {
71477
- return new Promise((resolve27) => {
71512
+ return new Promise((resolve28) => {
71478
71513
  const stream = createReadStream(path4);
71479
71514
  const lineReaded = createInterface5({
71480
71515
  input: stream
71481
71516
  });
71482
71517
  function destroyStreamAndResolve() {
71483
71518
  stream.destroy();
71484
- resolve27();
71519
+ resolve28();
71485
71520
  }
71486
71521
  let lineNumber = 0;
71487
71522
  let currentRangeIndex = 0;
@@ -72721,9 +72756,9 @@ class PostHogBackendClient extends PostHogCoreStateless {
72721
72756
  if (this.disabled || this.optedOut)
72722
72757
  return;
72723
72758
  if (!this._waitUntilCycle) {
72724
- let resolve27;
72759
+ let resolve28;
72725
72760
  const promise = new Promise((r) => {
72726
- resolve27 = r;
72761
+ resolve28 = r;
72727
72762
  });
72728
72763
  try {
72729
72764
  waitUntil(promise);
@@ -72731,7 +72766,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
72731
72766
  return;
72732
72767
  }
72733
72768
  this._waitUntilCycle = {
72734
- resolve: resolve27,
72769
+ resolve: resolve28,
72735
72770
  startedAt: Date.now(),
72736
72771
  timer: undefined
72737
72772
  };
@@ -72757,11 +72792,11 @@ class PostHogBackendClient extends PostHogCoreStateless {
72757
72792
  return cycle?.resolve;
72758
72793
  }
72759
72794
  async resolveWaitUntilFlush() {
72760
- const resolve27 = this._consumeWaitUntilCycle();
72795
+ const resolve28 = this._consumeWaitUntilCycle();
72761
72796
  try {
72762
72797
  await super.flush();
72763
72798
  } catch {} finally {
72764
- resolve27?.();
72799
+ resolve28?.();
72765
72800
  }
72766
72801
  }
72767
72802
  getPersistedProperty(key) {
@@ -72861,15 +72896,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
72861
72896
  return true;
72862
72897
  if (this.featureFlagsPoller === undefined)
72863
72898
  return false;
72864
- return new Promise((resolve27) => {
72899
+ return new Promise((resolve28) => {
72865
72900
  const timeout = setTimeout(() => {
72866
72901
  cleanup();
72867
- resolve27(false);
72902
+ resolve28(false);
72868
72903
  }, timeoutMs);
72869
72904
  const cleanup = this._events.on("localEvaluationFlagsLoaded", (count) => {
72870
72905
  clearTimeout(timeout);
72871
72906
  cleanup();
72872
- resolve27(count > 0);
72907
+ resolve28(count > 0);
72873
72908
  });
72874
72909
  });
72875
72910
  }
@@ -73213,13 +73248,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
73213
73248
  this.context?.enter(data, options);
73214
73249
  }
73215
73250
  async _shutdown(shutdownTimeoutMs) {
73216
- const resolve27 = this._consumeWaitUntilCycle();
73251
+ const resolve28 = this._consumeWaitUntilCycle();
73217
73252
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
73218
73253
  this.errorTracking.shutdown();
73219
73254
  try {
73220
73255
  return await super._shutdown(shutdownTimeoutMs);
73221
73256
  } finally {
73222
- resolve27?.();
73257
+ resolve28?.();
73223
73258
  }
73224
73259
  }
73225
73260
  async _requestRemoteConfigPayload(flagKey) {
@@ -73573,7 +73608,7 @@ import {
73573
73608
  readFileSync as readFileSync41,
73574
73609
  writeFileSync as writeFileSync24
73575
73610
  } from "node:fs";
73576
- import { dirname as dirname9 } from "node:path";
73611
+ import { dirname as dirname10 } from "node:path";
73577
73612
  import { randomUUID as randomUUID3 } from "node:crypto";
73578
73613
  var DEFAULT_KEY = "phc_qKY87cKWZm6ZyCtk7LcRd2cU8Sg42u7Ywhui5stYCegd";
73579
73614
  var DEFAULT_HOST = "https://us.i.posthog.com";
@@ -73601,7 +73636,7 @@ function getDistinctId() {
73601
73636
  const id = randomUUID3();
73602
73637
  cachedDistinctId = id;
73603
73638
  try {
73604
- mkdirSync25(dirname9(path4), { recursive: true });
73639
+ mkdirSync25(dirname10(path4), { recursive: true });
73605
73640
  writeFileSync24(path4, id, "utf-8");
73606
73641
  } catch {}
73607
73642
  return id;
@@ -73657,7 +73692,7 @@ function installGlobalErrorHandlers() {
73657
73692
  const flushWithTimeout = async (error, kind) => {
73658
73693
  await Promise.race([
73659
73694
  captureException(error, { kind }),
73660
- new Promise((resolve27) => setTimeout(resolve27, FLUSH_TIMEOUT_MS))
73695
+ new Promise((resolve28) => setTimeout(resolve28, FLUSH_TIMEOUT_MS))
73661
73696
  ]);
73662
73697
  };
73663
73698
  process.on("uncaughtException", (err) => {
@@ -74266,7 +74301,7 @@ var DASHBOARD_CACHE_TTL = {
74266
74301
  };
74267
74302
  function readLastTurnAt(agentsDir, name) {
74268
74303
  try {
74269
- const db = openTurnsDb(resolve27(agentsDir, name));
74304
+ const db = openTurnsDb(resolve28(agentsDir, name));
74270
74305
  try {
74271
74306
  const turns = listTurnsForAgent(db, { limit: 1 });
74272
74307
  return turns.length > 0 ? turns[0].started_at : null;
@@ -74279,7 +74314,7 @@ function readLastTurnAt(agentsDir, name) {
74279
74314
  }
74280
74315
  function agentBridgeAlive(agentsDir, name, maxAgeMs = 30000, now = Date.now()) {
74281
74316
  try {
74282
- const f = resolve27(agentsDir, name, "telegram", ".bridge-alive");
74317
+ const f = resolve28(agentsDir, name, "telegram", ".bridge-alive");
74283
74318
  return now - statSync22(f).mtimeMs <= maxAgeMs;
74284
74319
  } catch {
74285
74320
  return false;
@@ -74367,7 +74402,7 @@ async function handleGetLogs(name, lines = 50, deps = {}) {
74367
74402
  function handleGetTurns(config, agentName, limit) {
74368
74403
  try {
74369
74404
  const agentsDir = resolveAgentsDir(config);
74370
- const agentDir = resolve27(agentsDir, agentName);
74405
+ const agentDir = resolve28(agentsDir, agentName);
74371
74406
  const db = openTurnsDb(agentDir);
74372
74407
  try {
74373
74408
  const turns = listTurnsForAgent(db, { limit });
@@ -74385,7 +74420,7 @@ function handleGetTurns(config, agentName, limit) {
74385
74420
  function handleGetSubagents(config, agentName, status) {
74386
74421
  try {
74387
74422
  const agentsDir = resolveAgentsDir(config);
74388
- const agentDir = resolve27(agentsDir, agentName);
74423
+ const agentDir = resolve28(agentsDir, agentName);
74389
74424
  const db = openTurnsDb(agentDir);
74390
74425
  try {
74391
74426
  applySubagentsSchema(db);
@@ -74929,7 +74964,7 @@ async function handleGetSchedule(config, deps = {}) {
74929
74964
  const recentByAgent = {};
74930
74965
  const agents = new Set(entries.map((e) => e.agent));
74931
74966
  for (const agent of agents) {
74932
- const rows = readRecentFires(resolve27(agentsDir, agent, "scheduler.jsonl"));
74967
+ const rows = readRecentFires(resolve28(agentsDir, agent, "scheduler.jsonl"));
74933
74968
  if (rows.length > 0)
74934
74969
  recentByAgent[agent] = rows.slice(-10);
74935
74970
  }
@@ -75479,7 +75514,7 @@ function escapeHtml3(s) {
75479
75514
  import net4 from "node:net";
75480
75515
  function forwardToGateway(socketPath, req, opts = {}) {
75481
75516
  const timeoutMs = opts.timeoutMs ?? 5000;
75482
- return new Promise((resolve28) => {
75517
+ return new Promise((resolve29) => {
75483
75518
  let settled = false;
75484
75519
  let buf = "";
75485
75520
  const done = (value) => {
@@ -75489,7 +75524,7 @@ function forwardToGateway(socketPath, req, opts = {}) {
75489
75524
  try {
75490
75525
  conn.destroy();
75491
75526
  } catch {}
75492
- resolve28(value);
75527
+ resolve29(value);
75493
75528
  };
75494
75529
  const conn = net4.createConnection(socketPath);
75495
75530
  conn.setEncoding("utf8");
@@ -75857,7 +75892,7 @@ function resolveWebToken() {
75857
75892
  return existing;
75858
75893
  }
75859
75894
  const token = randomBytes11(32).toString("hex");
75860
- mkdirSync29(dirname10(tokenPath), { recursive: true, mode: 448 });
75895
+ mkdirSync29(dirname11(tokenPath), { recursive: true, mode: 448 });
75861
75896
  try {
75862
75897
  const fd = openSync10(tokenPath, fsConstants3.O_WRONLY | fsConstants3.O_CREAT | fsConstants3.O_EXCL, 384);
75863
75898
  try {
@@ -76114,7 +76149,7 @@ function parseRoute(pathname, method) {
76114
76149
  return null;
76115
76150
  }
76116
76151
  function startWebServer(config, port, hostname = "127.0.0.1", configPath) {
76117
- const uiDirRaw = resolve28(import.meta.dirname, "ui");
76152
+ const uiDirRaw = resolve29(import.meta.dirname, "ui");
76118
76153
  const uiDir = existsSync50(uiDirRaw) ? realpathSync4(uiDirRaw) : uiDirRaw;
76119
76154
  const token = resolveWebToken();
76120
76155
  const freshConfig = () => {
@@ -76391,7 +76426,7 @@ function startWebServer(config, port, hostname = "127.0.0.1", configPath) {
76391
76426
  return new Response("Not Found", { status: 404 });
76392
76427
  }
76393
76428
  const rel = relative(uiDir, realFullPath);
76394
- if (rel.startsWith("..") || resolve28(uiDir, rel) !== realFullPath) {
76429
+ if (rel.startsWith("..") || resolve29(uiDir, rel) !== realFullPath) {
76395
76430
  return new Response("Forbidden", { status: 403 });
76396
76431
  }
76397
76432
  const ext = extname(realFullPath);
@@ -76546,7 +76581,7 @@ Starting Switchroom dashboard...
76546
76581
  init_source();
76547
76582
  init_loader();
76548
76583
  import { existsSync as existsSync51, copyFileSync as copyFileSync8, readFileSync as readFileSync47, writeFileSync as writeFileSync27, mkdirSync as mkdirSync30 } from "node:fs";
76549
- import { resolve as resolve29, dirname as dirname11 } from "node:path";
76584
+ import { resolve as resolve30, dirname as dirname12 } from "node:path";
76550
76585
  init_vault();
76551
76586
  init_manager();
76552
76587
 
@@ -76737,12 +76772,12 @@ async function stepConfigFile(configPath, nonInteractive) {
76737
76772
  console.log(source_default.gray(` Loading ${existingConfig}`));
76738
76773
  const config = loadConfig(existingConfig);
76739
76774
  console.log(source_default.green(` ${STEP_DONE} Config loaded`) + source_default.gray(` (${Object.keys(config.agents).length} agents)`));
76740
- return { config, configPath: resolve29(existingConfig) };
76775
+ return { config, configPath: resolve30(existingConfig) };
76741
76776
  }
76742
76777
  return await copyExampleConfig(nonInteractive);
76743
76778
  }
76744
76779
  async function copyExampleConfig(nonInteractive) {
76745
- const examplesDir = resolve29(import.meta.dirname, "../../examples");
76780
+ const examplesDir = resolve30(import.meta.dirname, "../../examples");
76746
76781
  let choice;
76747
76782
  if (nonInteractive) {
76748
76783
  choice = "switchroom";
@@ -76753,18 +76788,18 @@ async function copyExampleConfig(nonInteractive) {
76753
76788
  ]);
76754
76789
  choice = choice.split(" ")[0];
76755
76790
  }
76756
- const srcFile = resolve29(examplesDir, `${choice}.yaml`);
76791
+ const srcFile = resolve30(examplesDir, `${choice}.yaml`);
76757
76792
  const destFile = resolvePath("~/.switchroom/switchroom.yaml");
76758
76793
  if (!existsSync51(srcFile)) {
76759
76794
  throw new ConfigError(`Example config not found: ${choice}.yaml`);
76760
76795
  }
76761
- mkdirSync30(dirname11(destFile), { recursive: true });
76796
+ mkdirSync30(dirname12(destFile), { recursive: true });
76762
76797
  copyFileSync8(srcFile, destFile);
76763
76798
  console.log(source_default.green(` Copied ${choice}.yaml -> ${destFile}`));
76764
76799
  console.log(source_default.yellow(` Edit ${destFile} to customize, then re-run switchroom setup.`));
76765
76800
  const config = loadConfig(destFile);
76766
76801
  console.log(source_default.green(` ${STEP_DONE} Config loaded`) + source_default.gray(` (${Object.keys(config.agents).length} agents)`));
76767
- return { config, configPath: resolve29(destFile) };
76802
+ return { config, configPath: resolve30(destFile) };
76768
76803
  }
76769
76804
  async function stepBotToken(config, nonInteractive) {
76770
76805
  stepHeader(2, "Bot tokens", STEP_ACTIVE);
@@ -77272,7 +77307,7 @@ async function stepAutoUnlock(config, switchroomConfigPath, nonInteractive) {
77272
77307
  const choice = await askChoice(" Approval posture", [PASSPHRASE_CHOICE, TELEGRAM_ID_CHOICE]);
77273
77308
  if (choice === TELEGRAM_ID_CHOICE) {
77274
77309
  try {
77275
- const yamlPath = existsSync51(resolve29(process.cwd(), "switchroom.yaml")) ? resolve29(process.cwd(), "switchroom.yaml") : resolve29(process.cwd(), "switchroom.yml");
77310
+ const yamlPath = existsSync51(resolve30(process.cwd(), "switchroom.yaml")) ? resolve30(process.cwd(), "switchroom.yaml") : resolve30(process.cwd(), "switchroom.yml");
77276
77311
  if (existsSync51(yamlPath)) {
77277
77312
  const content = readFileSync47(yamlPath, "utf-8");
77278
77313
  const result = insertVaultBrokerApprovalAuth(content, "telegram-id");
@@ -77304,8 +77339,8 @@ async function stepDangerousMode(config, nonInteractive) {
77304
77339
  }
77305
77340
  if (enableDangerous) {
77306
77341
  const configPaths = [
77307
- resolve29(process.cwd(), "switchroom.yaml"),
77308
- resolve29(process.cwd(), "switchroom.yml")
77342
+ resolve30(process.cwd(), "switchroom.yaml"),
77343
+ resolve30(process.cwd(), "switchroom.yml")
77309
77344
  ];
77310
77345
  for (const configPath of configPaths) {
77311
77346
  if (existsSync51(configPath)) {
@@ -77339,7 +77374,7 @@ async function stepOnboardingGuidance(config, nonInteractive) {
77339
77374
  const agentNames = Object.keys(config.agents);
77340
77375
  let allAuthenticated = true;
77341
77376
  for (const name of agentNames) {
77342
- const agentDir = resolve29(agentsDir, name);
77377
+ const agentDir = resolve30(agentsDir, name);
77343
77378
  const status = getAuthStatus(name, agentDir);
77344
77379
  if (status.authenticated) {
77345
77380
  console.log(` ${source_default.green("OK")} ${source_default.bold(name)}` + source_default.gray(` - authenticated (expires: ${status.timeUntilExpiry ?? "unknown"})`));
@@ -77439,7 +77474,7 @@ init_loader();
77439
77474
  init_lifecycle();
77440
77475
  import { cpSync as cpSync2, existsSync as existsSync58, mkdirSync as mkdirSync32, readFileSync as readFileSync52, realpathSync as realpathSync6, rmSync as rmSync12, statSync as statSync26, chownSync as chownSync5 } from "node:fs";
77441
77476
  import { spawnSync as spawnSync9 } from "node:child_process";
77442
- import { join as join61, dirname as dirname14, resolve as resolve34 } from "node:path";
77477
+ import { join as join61, dirname as dirname15, resolve as resolve35 } from "node:path";
77443
77478
  import { homedir as homedir37 } from "node:os";
77444
77479
 
77445
77480
  // src/cli/release-yaml.ts
@@ -77481,7 +77516,7 @@ function defaultPersistPin(configPath) {
77481
77516
  }
77482
77517
  var DEFAULT_COMPOSE_PATH = join61(homedir37(), ".switchroom", "compose", "docker-compose.yml");
77483
77518
  function runningFromSwitchroomCheckout(scriptPath) {
77484
- let dir = dirname14(scriptPath);
77519
+ let dir = dirname15(scriptPath);
77485
77520
  for (let i = 0;i < 12; i++) {
77486
77521
  if (existsSync58(join61(dir, ".git"))) {
77487
77522
  try {
@@ -77490,7 +77525,7 @@ function runningFromSwitchroomCheckout(scriptPath) {
77490
77525
  return true;
77491
77526
  } catch {}
77492
77527
  }
77493
- const parent = dirname14(dir);
77528
+ const parent = dirname15(dir);
77494
77529
  if (parent === dir)
77495
77530
  break;
77496
77531
  dir = parent;
@@ -77644,7 +77679,7 @@ function planUpdate(opts) {
77644
77679
  opts.syncBundledSkillsFn();
77645
77680
  return;
77646
77681
  }
77647
- const source = resolve34(import.meta.dirname, "../../skills");
77682
+ const source = resolve35(import.meta.dirname, "../../skills");
77648
77683
  const dest = join61(homedir37(), ".switchroom", "skills", "_bundled");
77649
77684
  if (!existsSync58(source)) {
77650
77685
  process.stderr.write(`switchroom update: sync-bundled-skills \u2014 CLI bundle has no adjacent skills/ at ${source}; skipping.
@@ -77655,7 +77690,7 @@ function planUpdate(opts) {
77655
77690
  if (existsSync58(dest)) {
77656
77691
  rmSync12(dest, { recursive: true, force: true });
77657
77692
  }
77658
- mkdirSync32(dirname14(dest), { recursive: true });
77693
+ mkdirSync32(dirname15(dest), { recursive: true });
77659
77694
  cpSync2(source, dest, { recursive: true, dereference: false });
77660
77695
  } catch (err) {
77661
77696
  throw new Error(`sync-bundled-skills failed: ${err.message}`);
@@ -77757,7 +77792,7 @@ function defaultStatusProbe(composePath) {
77757
77792
  try {
77758
77793
  cliBuiltAt = new Date(statSync26(scriptPath).mtimeMs).toISOString();
77759
77794
  } catch {}
77760
- let dir = dirname14(scriptPath);
77795
+ let dir = dirname15(scriptPath);
77761
77796
  for (let i = 0;i < 8; i++) {
77762
77797
  const pkgPath = join61(dir, "package.json");
77763
77798
  if (existsSync58(pkgPath)) {
@@ -77770,7 +77805,7 @@ function defaultStatusProbe(composePath) {
77770
77805
  }
77771
77806
  break;
77772
77807
  }
77773
- const parent = dirname14(dir);
77808
+ const parent = dirname15(dir);
77774
77809
  if (parent === dir)
77775
77810
  break;
77776
77811
  dir = parent;
@@ -78193,7 +78228,7 @@ init_source();
78193
78228
  init_helpers();
78194
78229
  init_loader();
78195
78230
  init_lifecycle();
78196
- import { resolve as resolve35 } from "node:path";
78231
+ import { resolve as resolve36 } from "node:path";
78197
78232
 
78198
78233
  // src/cli/version.ts
78199
78234
  init_source();
@@ -78201,7 +78236,7 @@ init_helpers();
78201
78236
  init_lifecycle();
78202
78237
  import { execSync as execSync4 } from "node:child_process";
78203
78238
  import { existsSync as existsSync59, readFileSync as readFileSync54 } from "node:fs";
78204
- import { dirname as dirname15, join as join62 } from "node:path";
78239
+ import { dirname as dirname16, join as join62 } from "node:path";
78205
78240
  function getClaudeCodeVersion() {
78206
78241
  try {
78207
78242
  const out = execSync4("claude --version 2>/dev/null", {
@@ -78260,7 +78295,7 @@ function locateSwitchroomInstallDir() {
78260
78295
  }
78261
78296
  } catch {}
78262
78297
  }
78263
- dir = dirname15(dir);
78298
+ dir = dirname16(dir);
78264
78299
  }
78265
78300
  return null;
78266
78301
  }
@@ -78348,7 +78383,7 @@ function registerRestartCommand(program3) {
78348
78383
  }
78349
78384
  const didRestart = res.restarted || !graceful;
78350
78385
  if (didRestart) {
78351
- const agentDir = resolve35(agentsDir, name);
78386
+ const agentDir = resolve36(agentsDir, name);
78352
78387
  const converged = waitForAuthConverge(name, agentDir);
78353
78388
  if (!converged) {
78354
78389
  console.log(source_default.yellow(` ${name}: agent is up but auth status didn't converge in 30s \u2014 check logs`));
@@ -78429,7 +78464,7 @@ Dependency manifest`));
78429
78464
  // src/cli/handoff.ts
78430
78465
  init_helpers();
78431
78466
  init_loader();
78432
- import { resolve as resolve36 } from "node:path";
78467
+ import { resolve as resolve37 } from "node:path";
78433
78468
  function registerHandoffCommand(program3) {
78434
78469
  program3.command("handoff <agent>", { hidden: true }).description("Build the agent's session handoff sidecars \u2014 a transcript-tail " + "briefing (.handoff.md) and topic line (.handoff-topic). " + "[internal \u2014 used by the Stop hook]").option("--max-turns <n>", "Max turns kept in the handoff transcript tail", String(DEFAULT_MAX_TURNS)).action(withConfigError(async (agentName, opts) => {
78435
78470
  let agentConfig;
@@ -78443,7 +78478,7 @@ function registerHandoffCommand(program3) {
78443
78478
  return;
78444
78479
  }
78445
78480
  const agentsDir = resolveAgentsDir(config);
78446
- agentDir = resolve36(agentsDir, agentName);
78481
+ agentDir = resolve37(agentsDir, agentName);
78447
78482
  } catch (err) {
78448
78483
  if (!(err instanceof ConfigError))
78449
78484
  throw err;
@@ -78458,7 +78493,7 @@ function registerHandoffCommand(program3) {
78458
78493
  `);
78459
78494
  return;
78460
78495
  }
78461
- const claudeConfigDir = resolve36(agentDir, ".claude");
78496
+ const claudeConfigDir = resolve37(agentDir, ".claude");
78462
78497
  const jsonl = findLatestSessionJsonl(claudeConfigDir);
78463
78498
  if (!jsonl) {
78464
78499
  process.stderr.write(`handoff: no session JSONL under ${claudeConfigDir}/projects; skipping
@@ -78967,7 +79002,7 @@ function record(stateDir, input, nowFn = Date.now) {
78967
79002
  return result;
78968
79003
  });
78969
79004
  }
78970
- function resolve37(stateDir, fingerprint, nowFn = Date.now) {
79005
+ function resolve38(stateDir, fingerprint, nowFn = Date.now) {
78971
79006
  if (!existsSync60(join63(stateDir, ISSUES_FILE)))
78972
79007
  return 0;
78973
79008
  return withLock(stateDir, () => {
@@ -79255,11 +79290,11 @@ function registerIssuesCommand(program3) {
79255
79290
  const stateDir = resolveStateDir2(opts);
79256
79291
  let flipped;
79257
79292
  if (opts.source && opts.code) {
79258
- flipped = resolve37(stateDir, computeFingerprint(opts.source, opts.code));
79293
+ flipped = resolve38(stateDir, computeFingerprint(opts.source, opts.code));
79259
79294
  } else if (opts.source && !fingerprint) {
79260
79295
  flipped = resolveAllBySource(stateDir, opts.source);
79261
79296
  } else if (fingerprint) {
79262
- flipped = resolve37(stateDir, fingerprint);
79297
+ flipped = resolve38(stateDir, fingerprint);
79263
79298
  } else {
79264
79299
  process.stderr.write(`issues resolve: need either <fingerprint>, --source, or --source + --code
79265
79300
  `);
@@ -79356,7 +79391,7 @@ function relTime(deltaMs) {
79356
79391
  init_source();
79357
79392
  import { existsSync as existsSync63 } from "node:fs";
79358
79393
  import { homedir as homedir40 } from "node:os";
79359
- import { join as join66, resolve as resolve38 } from "node:path";
79394
+ import { join as join66, resolve as resolve39 } from "node:path";
79360
79395
 
79361
79396
  // src/deps/python.ts
79362
79397
  import { createHash as createHash11 } from "node:crypto";
@@ -79367,7 +79402,7 @@ import {
79367
79402
  rmSync as rmSync13,
79368
79403
  writeFileSync as writeFileSync29
79369
79404
  } from "node:fs";
79370
- import { dirname as dirname16, join as join64 } from "node:path";
79405
+ import { dirname as dirname17, join as join64 } from "node:path";
79371
79406
  import { homedir as homedir38 } from "node:os";
79372
79407
  import { execFileSync as execFileSync19 } from "node:child_process";
79373
79408
 
@@ -79414,7 +79449,7 @@ function ensurePythonEnv(opts) {
79414
79449
  if (existsSync61(venvDir)) {
79415
79450
  rmSync13(venvDir, { recursive: true, force: true });
79416
79451
  }
79417
- mkdirSync34(dirname16(venvDir), { recursive: true });
79452
+ mkdirSync34(dirname17(venvDir), { recursive: true });
79418
79453
  try {
79419
79454
  execFileSync19(hostPython, ["-m", "venv", venvDir], { stdio: "pipe" });
79420
79455
  } catch (err) {
@@ -79455,7 +79490,7 @@ import {
79455
79490
  rmSync as rmSync14,
79456
79491
  writeFileSync as writeFileSync30
79457
79492
  } from "node:fs";
79458
- import { dirname as dirname17, join as join65 } from "node:path";
79493
+ import { dirname as dirname18, join as join65 } from "node:path";
79459
79494
  import { homedir as homedir39 } from "node:os";
79460
79495
  import { execFileSync as execFileSync20 } from "node:child_process";
79461
79496
 
@@ -79482,7 +79517,7 @@ function defaultNodeCacheRoot() {
79482
79517
  return join65(homedir39(), ".switchroom", "deps", "node");
79483
79518
  }
79484
79519
  function hashDepInputs(packageJsonPath) {
79485
- const sourceDir = dirname17(packageJsonPath);
79520
+ const sourceDir = dirname18(packageJsonPath);
79486
79521
  const hasher = createHash12("sha256");
79487
79522
  hasher.update(`package.json
79488
79523
  `);
@@ -79507,7 +79542,7 @@ function ensureNodeEnv(opts) {
79507
79542
  if (!existsSync62(packageJsonPath)) {
79508
79543
  throw new NodeEnvError(`package.json not found: ${packageJsonPath}`);
79509
79544
  }
79510
- const sourceDir = dirname17(packageJsonPath);
79545
+ const sourceDir = dirname18(packageJsonPath);
79511
79546
  const envDir = join65(cacheRoot, skillName);
79512
79547
  const stampPath = join65(envDir, ".package.sha256");
79513
79548
  const nodeModulesDir = join65(envDir, "node_modules");
@@ -79563,7 +79598,7 @@ function ensureNodeEnv(opts) {
79563
79598
 
79564
79599
  // src/cli/deps.ts
79565
79600
  function builtinSkillsRoot() {
79566
- return resolve38(homedir40(), ".switchroom/skills/_bundled");
79601
+ return resolve39(homedir40(), ".switchroom/skills/_bundled");
79567
79602
  }
79568
79603
  function registerDepsCommand(program3) {
79569
79604
  const deps = program3.command("deps").description("Manage cached per-skill dependency environments");
@@ -79642,7 +79677,7 @@ function registerDepsCommand(program3) {
79642
79677
  init_helpers();
79643
79678
  init_loader();
79644
79679
  import { existsSync as existsSync64 } from "node:fs";
79645
- import { resolve as resolve39, sep as sep3 } from "node:path";
79680
+ import { resolve as resolve40, sep as sep3 } from "node:path";
79646
79681
  import { spawnSync as spawnSync11 } from "node:child_process";
79647
79682
 
79648
79683
  // src/agents/workspace.ts
@@ -80348,8 +80383,8 @@ function registerWorkspaceCommand(program3) {
80348
80383
  const dir = resolveAgentWorkspaceDirOrExit(program3, agentName);
80349
80384
  if (!dir)
80350
80385
  return;
80351
- const resolvedWorkspace = resolve39(dir);
80352
- const target = resolve39(resolvedWorkspace, file ?? "AGENTS.md");
80386
+ const resolvedWorkspace = resolve40(dir);
80387
+ const target = resolve40(resolvedWorkspace, file ?? "AGENTS.md");
80353
80388
  if (!isInsideWorkspace(resolvedWorkspace, target)) {
80354
80389
  process.stderr.write(`workspace edit: refusing path traversal outside workspace dir (${target})
80355
80390
  `);
@@ -80417,7 +80452,7 @@ function registerWorkspaceCommand(program3) {
80417
80452
  const dir = resolveAgentWorkspaceDirOrExit(program3, agentName);
80418
80453
  if (!dir)
80419
80454
  return;
80420
- const gitDir = resolve39(dir, ".git");
80455
+ const gitDir = resolve40(dir, ".git");
80421
80456
  if (!existsSync64(gitDir)) {
80422
80457
  process.stdout.write(`Workspace is not a git repository. Re-run \`switchroom agent create ${agentName}\` ` + `or manually \`git init\` in ${dir} to enable versioning.
80423
80458
  `);
@@ -80471,7 +80506,7 @@ function registerWorkspaceCommand(program3) {
80471
80506
  const dir = resolveAgentWorkspaceDirOrExit(program3, agentName);
80472
80507
  if (!dir)
80473
80508
  return;
80474
- const gitDir = resolve39(dir, ".git");
80509
+ const gitDir = resolve40(dir, ".git");
80475
80510
  if (!existsSync64(gitDir)) {
80476
80511
  process.stdout.write(`Workspace is not a git repository.
80477
80512
  `);
@@ -80495,7 +80530,7 @@ function resolveAgentWorkspaceDirOrExit(program3, agentName) {
80495
80530
  return;
80496
80531
  }
80497
80532
  const agentsDir = resolveAgentsDir(config);
80498
- const agentDir = resolve39(agentsDir, agentName);
80533
+ const agentDir = resolve40(agentsDir, agentName);
80499
80534
  const dir = resolveAgentWorkspaceDir(agentDir);
80500
80535
  if (!existsSync64(dir)) {
80501
80536
  process.stderr.write(`workspace: ${dir} does not exist yet. Run \`switchroom setup\` or \`switchroom agent scaffold ${agentName}\` to seed it.
@@ -80534,7 +80569,7 @@ init_helpers();
80534
80569
  init_loader();
80535
80570
  init_merge();
80536
80571
  import { copyFileSync as copyFileSync10, existsSync as existsSync65, readFileSync as readFileSync58, writeFileSync as writeFileSync31 } from "node:fs";
80537
- import { join as join67, resolve as resolve40 } from "node:path";
80572
+ import { join as join67, resolve as resolve41 } from "node:path";
80538
80573
  init_schema();
80539
80574
  function resolveSoulTargetOrExit(program3, agentName) {
80540
80575
  const config = getConfig(program3);
@@ -80547,7 +80582,7 @@ function resolveSoulTargetOrExit(program3, agentName) {
80547
80582
  const profileName = merged.extends ?? DEFAULT_PROFILE;
80548
80583
  const profilePath = getProfilePath(profileName);
80549
80584
  const agentsDir = resolveAgentsDir(config);
80550
- const agentDir = resolve40(agentsDir, agentName);
80585
+ const agentDir = resolve41(agentsDir, agentName);
80551
80586
  const workspaceDir = resolveAgentWorkspaceDir(agentDir);
80552
80587
  if (!existsSync65(workspaceDir)) {
80553
80588
  console.error(`soul: ${workspaceDir} does not exist yet. Run \`switchroom setup\` ` + `or \`switchroom agent scaffold ${agentName}\` to seed it.`);
@@ -80625,7 +80660,7 @@ function registerSoulCommand(program3) {
80625
80660
  init_helpers();
80626
80661
  init_loader();
80627
80662
  import { existsSync as existsSync66, readFileSync as readFileSync59, readdirSync as readdirSync23, statSync as statSync29 } from "node:fs";
80628
- import { resolve as resolve41, join as join68 } from "node:path";
80663
+ import { resolve as resolve42, join as join68 } from "node:path";
80629
80664
  import { createHash as createHash13 } from "node:crypto";
80630
80665
  init_merge();
80631
80666
  init_hindsight();
@@ -80723,7 +80758,7 @@ function registerDebugCommand(program3) {
80723
80758
  process.exit(1);
80724
80759
  }
80725
80760
  const agentsDir = resolveAgentsDir(config);
80726
- const agentDir = resolve41(agentsDir, agentName);
80761
+ const agentDir = resolve42(agentsDir, agentName);
80727
80762
  if (!existsSync66(agentDir)) {
80728
80763
  console.error(`Agent directory not found: ${agentDir}`);
80729
80764
  process.exit(1);
@@ -80900,7 +80935,7 @@ init_source();
80900
80935
  // src/worktree/claim.ts
80901
80936
  import { execFileSync as execFileSync21 } from "node:child_process";
80902
80937
  import { closeSync as closeSync12, mkdirSync as mkdirSync37, openSync as openSync12, existsSync as existsSync68, unlinkSync as unlinkSync13 } from "node:fs";
80903
- import { join as join70, resolve as resolve43 } from "node:path";
80938
+ import { join as join70, resolve as resolve44 } from "node:path";
80904
80939
  import { homedir as homedir42 } from "node:os";
80905
80940
  import { randomBytes as randomBytes13 } from "node:crypto";
80906
80941
 
@@ -80914,10 +80949,10 @@ import {
80914
80949
  existsSync as existsSync67,
80915
80950
  renameSync as renameSync13
80916
80951
  } from "node:fs";
80917
- import { join as join69, resolve as resolve42 } from "node:path";
80952
+ import { join as join69, resolve as resolve43 } from "node:path";
80918
80953
  import { homedir as homedir41 } from "node:os";
80919
80954
  function registryDir() {
80920
- return resolve42(process.env.SWITCHROOM_WORKTREE_DIR ?? join69(homedir41(), ".switchroom", "worktrees"));
80955
+ return resolve43(process.env.SWITCHROOM_WORKTREE_DIR ?? join69(homedir41(), ".switchroom", "worktrees"));
80921
80956
  }
80922
80957
  function recordPath(id) {
80923
80958
  return join69(registryDir(), `${id}.json`);
@@ -80998,7 +81033,7 @@ function acquireRepoLock(repoPath) {
80998
81033
  }
80999
81034
  var DEFAULT_CONCURRENCY = 5;
81000
81035
  function worktreesBaseDir() {
81001
- return resolve43(process.env.SWITCHROOM_WORKTREE_BASE ?? join70(homedir42(), ".switchroom", "worktree-checkouts"));
81036
+ return resolve44(process.env.SWITCHROOM_WORKTREE_BASE ?? join70(homedir42(), ".switchroom", "worktree-checkouts"));
81002
81037
  }
81003
81038
  function shortId() {
81004
81039
  return randomBytes13(4).toString("hex");
@@ -81662,7 +81697,7 @@ function registerDriveMcpLauncherCommand(program3) {
81662
81697
  init_scaffold_integration();
81663
81698
  import { spawn as spawn5 } from "node:child_process";
81664
81699
  import { writeFileSync as writeFileSync34, mkdirSync as mkdirSync39 } from "node:fs";
81665
- import { dirname as dirname18, join as join72 } from "node:path";
81700
+ import { dirname as dirname19, join as join72 } from "node:path";
81666
81701
  var SOFTERIA_TOKEN_ENV = "MS365_MCP_OAUTH_TOKEN";
81667
81702
  var DEFAULT_REFRESH_LEAD_MS = 5 * 60 * 1000;
81668
81703
  var MAX_REFRESH_INTERVAL_MS = 60 * 60 * 1000;
@@ -81687,7 +81722,7 @@ function computeRefreshDelayMs(expiresAt, now, leadMs = DEFAULT_REFRESH_LEAD_MS)
81687
81722
  function writeRefreshHeartbeat(agentName, data) {
81688
81723
  const path7 = heartbeatPath(agentName);
81689
81724
  try {
81690
- mkdirSync39(dirname18(path7), { recursive: true });
81725
+ mkdirSync39(dirname19(path7), { recursive: true });
81691
81726
  writeFileSync34(path7, JSON.stringify(data, null, 2), { mode: 420 });
81692
81727
  } catch {}
81693
81728
  }
@@ -81718,20 +81753,20 @@ function wireStdio(child) {
81718
81753
  async function killChild(child, gracefulMs = 3000) {
81719
81754
  if (child.exitCode !== null || child.signalCode !== null)
81720
81755
  return;
81721
- return new Promise((resolve44) => {
81756
+ return new Promise((resolve45) => {
81722
81757
  let killTimer = null;
81723
81758
  const onExit = () => {
81724
81759
  if (killTimer) {
81725
81760
  clearTimeout(killTimer);
81726
81761
  killTimer = null;
81727
81762
  }
81728
- resolve44();
81763
+ resolve45();
81729
81764
  };
81730
81765
  child.once("exit", onExit);
81731
81766
  try {
81732
81767
  child.kill("SIGTERM");
81733
81768
  } catch {
81734
- resolve44();
81769
+ resolve45();
81735
81770
  return;
81736
81771
  }
81737
81772
  killTimer = setTimeout(() => {
@@ -81845,8 +81880,8 @@ async function runMs365McpLauncher(opts, rt) {
81845
81880
  };
81846
81881
  process.on("SIGINT", onSignal);
81847
81882
  process.on("SIGTERM", onSignal);
81848
- return new Promise((resolve44) => {
81849
- resolveLauncher = resolve44;
81883
+ return new Promise((resolve45) => {
81884
+ resolveLauncher = resolve45;
81850
81885
  });
81851
81886
  }
81852
81887
  function registerM365McpLauncherCommand(program3) {
@@ -81880,7 +81915,7 @@ function registerM365McpLauncherCommand(program3) {
81880
81915
  init_scaffold_integration();
81881
81916
  import { spawn as spawn6 } from "node:child_process";
81882
81917
  import { existsSync as existsSync71, mkdirSync as mkdirSync40, writeFileSync as writeFileSync35 } from "node:fs";
81883
- import { dirname as dirname19 } from "node:path";
81918
+ import { dirname as dirname20 } from "node:path";
81884
81919
  var HEARTBEAT_WRITE_INTERVAL_MS = 30 * 1000;
81885
81920
  var DEFAULT_HEARTBEAT_PATH = "/state/agent/notion-launcher.heartbeat.json";
81886
81921
  var DEFAULT_VAULT_KEY = "notion/integration-token";
@@ -81890,7 +81925,7 @@ function buildNotionMcpArgs(opts) {
81890
81925
  }
81891
81926
  function defaultWriteHeartbeat(path7, contents) {
81892
81927
  try {
81893
- const dir = dirname19(path7);
81928
+ const dir = dirname20(path7);
81894
81929
  if (!existsSync71(dir))
81895
81930
  mkdirSync40(dir, { recursive: true });
81896
81931
  writeFileSync35(path7, contents);
@@ -81948,23 +81983,23 @@ async function runNotionMcpLauncher(opts, runtime) {
81948
81983
  };
81949
81984
  process.on("SIGTERM", () => forward("SIGTERM"));
81950
81985
  process.on("SIGINT", () => forward("SIGINT"));
81951
- const exitCode = await new Promise((resolve44) => {
81986
+ const exitCode = await new Promise((resolve45) => {
81952
81987
  child.once("exit", (code, signal) => {
81953
81988
  clearTimer(heartbeatHandle);
81954
81989
  if (typeof code === "number") {
81955
- resolve44(code);
81990
+ resolve45(code);
81956
81991
  } else if (signal) {
81957
81992
  const sigCode = { SIGTERM: 15, SIGINT: 2, SIGKILL: 9 }[signal] ?? 1;
81958
- resolve44(128 + sigCode);
81993
+ resolve45(128 + sigCode);
81959
81994
  } else {
81960
- resolve44(1);
81995
+ resolve45(1);
81961
81996
  }
81962
81997
  });
81963
81998
  child.once("error", (err) => {
81964
81999
  clearTimer(heartbeatHandle);
81965
82000
  process.stderr.write(`notion-mcp-launcher: child spawn error: ${err.message}
81966
82001
  `);
81967
- resolve44(1);
82002
+ resolve45(1);
81968
82003
  });
81969
82004
  });
81970
82005
  return exitCode;
@@ -83022,7 +83057,7 @@ agents:
83022
83057
 
83023
83058
  // src/cli/apply.ts
83024
83059
  init_resolver();
83025
- import { dirname as dirname22, join as join75, resolve as resolve45 } from "node:path";
83060
+ import { dirname as dirname23, join as join75, resolve as resolve46 } from "node:path";
83026
83061
  import { homedir as homedir44 } from "node:os";
83027
83062
  import { execFileSync as execFileSync24 } from "node:child_process";
83028
83063
  init_vault();
@@ -83219,7 +83254,7 @@ var COMPOSE_PROJECT2 = "switchroom";
83219
83254
  function resolveVaultBindMountDir(homeDir, ctx) {
83220
83255
  const isCustomPath = ctx.migrationKind === "custom-path-skipped";
83221
83256
  if (isCustomPath && ctx.customVaultPath) {
83222
- return dirname22(ctx.customVaultPath);
83257
+ return dirname23(ctx.customVaultPath);
83223
83258
  }
83224
83259
  return join75(homeDir, ".switchroom", "vault");
83225
83260
  }
@@ -83624,7 +83659,7 @@ function copyExampleConfig2(name) {
83624
83659
  if (!/^[a-z0-9_-]+$/.test(name)) {
83625
83660
  throw new Error(`Invalid example name: ${name} (must match /^[a-z0-9_-]+$/)`);
83626
83661
  }
83627
- const dest = resolve45(process.cwd(), "switchroom.yaml");
83662
+ const dest = resolve46(process.cwd(), "switchroom.yaml");
83628
83663
  if (existsSync74(dest)) {
83629
83664
  console.error(source_default.yellow("switchroom.yaml already exists \u2014 skipping example copy"));
83630
83665
  return;
@@ -83635,7 +83670,7 @@ function copyExampleConfig2(name) {
83635
83670
  console.log(source_default.green(`Copied ${name}.yaml -> switchroom.yaml`));
83636
83671
  return;
83637
83672
  }
83638
- const exampleFile = resolve45(import.meta.dirname, `../../examples/${name}.yaml`);
83673
+ const exampleFile = resolve46(import.meta.dirname, `../../examples/${name}.yaml`);
83639
83674
  if (!existsSync74(exampleFile)) {
83640
83675
  throw new Error(`Example config not found: ${name}.yaml (available: ${Object.keys(EMBEDDED_EXAMPLES).join(", ")})`);
83641
83676
  }
@@ -84213,10 +84248,10 @@ import {
84213
84248
  unlinkSync as unlinkSync14,
84214
84249
  writeSync as writeSync8
84215
84250
  } from "node:fs";
84216
- import { join as join77, resolve as resolve46 } from "node:path";
84251
+ import { join as join77, resolve as resolve47 } from "node:path";
84217
84252
  var STAGING_SUBDIR = ".staging";
84218
84253
  function overlayPathsFor(agent, opts = {}) {
84219
- const base = opts.root ? resolve46(opts.root, agent) : resolve46(resolveDualPath(`~/.switchroom/agents/${agent}`));
84254
+ const base = opts.root ? resolve47(opts.root, agent) : resolve47(resolveDualPath(`~/.switchroom/agents/${agent}`));
84220
84255
  const scheduleDir = join77(base, "schedule.d");
84221
84256
  const scheduleStagingDir = join77(scheduleDir, STAGING_SUBDIR);
84222
84257
  const skillsDir = join77(base, "skills.d");
@@ -85459,7 +85494,7 @@ function registerAgentConfigSkillWriteCommands(program3) {
85459
85494
  import {
85460
85495
  closeSync as closeSync15,
85461
85496
  existsSync as existsSync80,
85462
- lstatSync as lstatSync8,
85497
+ lstatSync as lstatSync9,
85463
85498
  mkdirSync as mkdirSync45,
85464
85499
  mkdtempSync as mkdtempSync5,
85465
85500
  openSync as openSync15,
@@ -85472,7 +85507,7 @@ import {
85472
85507
  writeFileSync as writeFileSync39
85473
85508
  } from "node:fs";
85474
85509
  import { tmpdir as tmpdir5, homedir as homedir46 } from "node:os";
85475
- import { dirname as dirname23, join as join80, relative as relative2, resolve as resolve47 } from "node:path";
85510
+ import { dirname as dirname24, join as join80, relative as relative2, resolve as resolve48 } from "node:path";
85476
85511
  import { spawnSync as spawnSync12 } from "node:child_process";
85477
85512
 
85478
85513
  // src/cli/skill-common.ts
@@ -85670,7 +85705,7 @@ function resolveSkillsPoolDir2(override) {
85670
85705
  }
85671
85706
  if (raw === "~")
85672
85707
  return homedir46();
85673
- return resolve47(raw);
85708
+ return resolve48(raw);
85674
85709
  }
85675
85710
  function readStdinSync() {
85676
85711
  const chunks = [];
@@ -85889,7 +85924,7 @@ function writePayload(poolDir, name, files) {
85889
85924
  const target = join80(poolDir, name);
85890
85925
  let targetIsSymlink = false;
85891
85926
  try {
85892
- const st = lstatSync8(target);
85927
+ const st = lstatSync9(target);
85893
85928
  if (st.isSymbolicLink()) {
85894
85929
  targetIsSymlink = true;
85895
85930
  }
@@ -85902,7 +85937,7 @@ function writePayload(poolDir, name, files) {
85902
85937
  try {
85903
85938
  for (const [path8, content] of Object.entries(files)) {
85904
85939
  const full = join80(staging, path8);
85905
- mkdirSync45(dirname23(full), { recursive: true, mode: 493 });
85940
+ mkdirSync45(dirname24(full), { recursive: true, mode: 493 });
85906
85941
  const fd = openSync15(full, "wx");
85907
85942
  try {
85908
85943
  writeFileSync39(fd, content);
@@ -85916,7 +85951,7 @@ function writePayload(poolDir, name, files) {
85916
85951
  }
85917
85952
  let targetExists = false;
85918
85953
  try {
85919
- lstatSync8(target);
85954
+ lstatSync9(target);
85920
85955
  targetExists = true;
85921
85956
  } catch {}
85922
85957
  if (targetExists) {
@@ -85954,7 +85989,7 @@ function registerSkillCommand(program3) {
85954
85989
  if (opts.from === undefined) {
85955
85990
  files = loadFromStdin();
85956
85991
  } else {
85957
- const fromPath = resolve47(opts.from);
85992
+ const fromPath = resolve48(opts.from);
85958
85993
  if (!existsSync80(fromPath)) {
85959
85994
  fail3(`--from path does not exist: ${opts.from}`);
85960
85995
  }
@@ -86011,7 +86046,7 @@ function sumBytes(files) {
86011
86046
  import {
86012
86047
  closeSync as closeSync16,
86013
86048
  existsSync as existsSync81,
86014
- lstatSync as lstatSync9,
86049
+ lstatSync as lstatSync10,
86015
86050
  mkdirSync as mkdirSync46,
86016
86051
  mkdtempSync as mkdtempSync6,
86017
86052
  openSync as openSync16,
@@ -86023,7 +86058,7 @@ import {
86023
86058
  utimesSync,
86024
86059
  writeFileSync as writeFileSync40
86025
86060
  } from "node:fs";
86026
- import { dirname as dirname24, join as join81, relative as relative3, resolve as resolve48 } from "node:path";
86061
+ import { dirname as dirname25, join as join81, relative as relative3, resolve as resolve49 } from "node:path";
86027
86062
  import { homedir as homedir47, tmpdir as tmpdir6 } from "node:os";
86028
86063
  import { spawnSync as spawnSync13 } from "node:child_process";
86029
86064
  init_helpers();
@@ -86034,7 +86069,7 @@ var TRASH_TTL_MS = 24 * 60 * 60 * 1000;
86034
86069
  var PERSONAL_SKILLS_SUBPATH = "personal-skills";
86035
86070
  function resolveConfigSkillsDir(agent) {
86036
86071
  const override = process.env.SWITCHROOM_CONFIG_DIR;
86037
- const candidate = override ? resolve48(override) : join81(homedir47(), ".switchroom-config");
86072
+ const candidate = override ? resolve49(override) : join81(homedir47(), ".switchroom-config");
86038
86073
  if (!existsSync81(candidate))
86039
86074
  return null;
86040
86075
  return join81(candidate, "agents", agent, PERSONAL_SKILLS_SUBPATH);
@@ -86068,7 +86103,7 @@ function mirrorToConfigRepo(agent, name, liveSkillDir) {
86068
86103
  try {
86069
86104
  if (liveSkillDir !== null) {
86070
86105
  try {
86071
- const st = lstatSync9(liveSkillDir);
86106
+ const st = lstatSync10(liveSkillDir);
86072
86107
  if (st.isSymbolicLink()) {
86073
86108
  process.stderr.write(source_default.yellow(`warning: refusing to mirror ${liveSkillDir} \u2014 source is a symlink
86074
86109
  `));
@@ -86129,7 +86164,7 @@ function resolveAgent(opts) {
86129
86164
  }
86130
86165
  function resolveAgentsRoot(opts) {
86131
86166
  if (opts.root)
86132
- return resolve48(opts.root);
86167
+ return resolve49(opts.root);
86133
86168
  return join81(homedir47(), ".switchroom", "agents");
86134
86169
  }
86135
86170
  function personalSkillDir(agentsRoot, agent, name) {
@@ -86159,7 +86194,7 @@ function readStdinSync2() {
86159
86194
  return Buffer.concat(chunks).toString("utf-8");
86160
86195
  }
86161
86196
  function loadFromDir2(dir) {
86162
- const abs = resolve48(dir);
86197
+ const abs = resolve49(dir);
86163
86198
  if (!statSync33(abs).isDirectory()) {
86164
86199
  fail4(`--from path is not a directory: ${dir}`);
86165
86200
  }
@@ -86256,7 +86291,7 @@ function sweepTrash(agentsRoot, agent) {
86256
86291
  function writePersonalSkill(targetDir, files) {
86257
86292
  let targetIsSymlink = false;
86258
86293
  try {
86259
- const st = lstatSync9(targetDir);
86294
+ const st = lstatSync10(targetDir);
86260
86295
  if (st.isSymbolicLink()) {
86261
86296
  targetIsSymlink = true;
86262
86297
  }
@@ -86264,13 +86299,13 @@ function writePersonalSkill(targetDir, files) {
86264
86299
  if (targetIsSymlink) {
86265
86300
  fail4(`refusing to overwrite symlink at ${targetDir}; investigate manually`);
86266
86301
  }
86267
- mkdirSync46(dirname24(targetDir), { recursive: true, mode: 493 });
86268
- const staging = mkdtempSync6(join81(dirname24(targetDir), `.skill-personal-stage-`));
86302
+ mkdirSync46(dirname25(targetDir), { recursive: true, mode: 493 });
86303
+ const staging = mkdtempSync6(join81(dirname25(targetDir), `.skill-personal-stage-`));
86269
86304
  let oldRename = null;
86270
86305
  try {
86271
86306
  for (const [path8, content] of Object.entries(files)) {
86272
86307
  const full = join81(staging, path8);
86273
- mkdirSync46(dirname24(full), { recursive: true, mode: 493 });
86308
+ mkdirSync46(dirname25(full), { recursive: true, mode: 493 });
86274
86309
  const fd = openSync16(full, "wx");
86275
86310
  try {
86276
86311
  writeFileSync40(fd, content);
@@ -86284,7 +86319,7 @@ function writePersonalSkill(targetDir, files) {
86284
86319
  }
86285
86320
  let targetExists = false;
86286
86321
  try {
86287
- lstatSync9(targetDir);
86322
+ lstatSync10(targetDir);
86288
86323
  targetExists = true;
86289
86324
  } catch {}
86290
86325
  if (targetExists) {
@@ -86319,7 +86354,7 @@ function loadValidateWrite(agentsRoot, agent, name, files, ensureNew) {
86319
86354
  const target = personalSkillDir(agentsRoot, agent, name);
86320
86355
  const exists = (() => {
86321
86356
  try {
86322
- lstatSync9(target);
86357
+ lstatSync10(target);
86323
86358
  return true;
86324
86359
  } catch {
86325
86360
  return false;
@@ -86353,7 +86388,7 @@ function loadFiles(opts) {
86353
86388
  if (opts.from === undefined) {
86354
86389
  return loadFromStdin2();
86355
86390
  }
86356
- const p = resolve48(opts.from);
86391
+ const p = resolve49(opts.from);
86357
86392
  if (!existsSync81(p)) {
86358
86393
  fail4(`--from path does not exist: ${opts.from}`);
86359
86394
  }
@@ -86419,7 +86454,7 @@ function resolveCloneSource(source, opts) {
86419
86454
  if (!existsSync81(dir)) {
86420
86455
  fail4(`clone source ${JSON.stringify(source)} not found at ${dir}; ` + `check \`switchroom skill search --tier ${tier}\``, 1);
86421
86456
  }
86422
- const st = lstatSync9(dir);
86457
+ const st = lstatSync10(dir);
86423
86458
  if (st.isSymbolicLink()) {
86424
86459
  fail4(`clone source ${JSON.stringify(source)} is a symlink at ${dir}; ` + `point clone at the canonical pool path instead`);
86425
86460
  }
@@ -86446,7 +86481,7 @@ function readSourceFiles(dir) {
86446
86481
  continue;
86447
86482
  }
86448
86483
  try {
86449
- const st = lstatSync9(full);
86484
+ const st = lstatSync10(full);
86450
86485
  if (st.size > CLONE_MAX_FILE_BYTES) {
86451
86486
  fail4(`clone source has oversized file ${rel} (${st.size} bytes > ${CLONE_MAX_FILE_BYTES}); ` + `refuse to read`, 3);
86452
86487
  }
@@ -86528,7 +86563,7 @@ function removePersonalAction(name, opts) {
86528
86563
  }
86529
86564
  const target = personalSkillDir(agentsRoot, agent, name);
86530
86565
  try {
86531
- const st = lstatSync9(target);
86566
+ const st = lstatSync10(target);
86532
86567
  if (st.isSymbolicLink()) {
86533
86568
  fail4(`refusing to remove symlink at ${target}; investigate manually`);
86534
86569
  }
@@ -86622,18 +86657,18 @@ init_helpers();
86622
86657
  var import_yaml24 = __toESM(require_dist(), 1);
86623
86658
  import { existsSync as existsSync82, readdirSync as readdirSync32, readFileSync as readFileSync70, statSync as statSync34 } from "node:fs";
86624
86659
  import { homedir as homedir48 } from "node:os";
86625
- import { join as join82, resolve as resolve49 } from "node:path";
86660
+ import { join as join82, resolve as resolve50 } from "node:path";
86626
86661
  var PERSONAL_PREFIX2 = "personal-";
86627
86662
  var BUNDLED_SUBDIR = "_bundled";
86628
86663
  var AGENT_NAME_RE3 = /^[a-z][a-z0-9_-]{0,62}$/;
86629
86664
  function defaultAgentsRoot() {
86630
- return resolve49(homedir48(), ".switchroom/agents");
86665
+ return resolve50(homedir48(), ".switchroom/agents");
86631
86666
  }
86632
86667
  function defaultSharedRoot2() {
86633
- return resolve49(homedir48(), ".switchroom/skills");
86668
+ return resolve50(homedir48(), ".switchroom/skills");
86634
86669
  }
86635
86670
  function defaultBundledRoot2() {
86636
- return resolve49(homedir48(), ".switchroom/skills/_bundled");
86671
+ return resolve50(homedir48(), ".switchroom/skills/_bundled");
86637
86672
  }
86638
86673
  function readSkillFrontmatter(skillDir) {
86639
86674
  const mdPath = join82(skillDir, "SKILL.md");
@@ -86916,7 +86951,46 @@ init_helpers();
86916
86951
  import { existsSync as existsSync84, mkdirSync as mkdirSync47, readdirSync as readdirSync33, readFileSync as readFileSync72, writeFileSync as writeFileSync41, statSync as statSync35, copyFileSync as copyFileSync12 } from "node:fs";
86917
86952
  import { homedir as homedir49 } from "node:os";
86918
86953
  import { join as join83 } from "node:path";
86954
+ import { spawnSync as spawnSync16 } from "node:child_process";
86955
+
86956
+ // src/cli/deploy-version-guard.ts
86919
86957
  import { spawnSync as spawnSync15 } from "node:child_process";
86958
+ var defaultRunner2 = (args) => {
86959
+ const r = spawnSync15("docker", args, { encoding: "utf8" });
86960
+ return { ok: r.status === 0, stdout: r.stdout ?? "", stderr: r.stderr ?? "" };
86961
+ };
86962
+ function deployedImageTag(container, run = defaultRunner2) {
86963
+ const r = run(["inspect", "-f", "{{.Config.Image}}", container]);
86964
+ if (!r.ok)
86965
+ return null;
86966
+ const ref = r.stdout.trim();
86967
+ if (!ref)
86968
+ return null;
86969
+ const noDigest = ref.split("@")[0];
86970
+ const colon = noDigest.lastIndexOf(":");
86971
+ if (colon < 0)
86972
+ return null;
86973
+ const tag = noDigest.slice(colon + 1);
86974
+ return tag && !tag.includes("/") ? tag : null;
86975
+ }
86976
+ function checkDowngrade(opts) {
86977
+ const running = deployedImageTag(opts.container, opts.run);
86978
+ if (opts.allowDowngrade)
86979
+ return { skip: false, running };
86980
+ const cmp = compareReleaseTags(opts.targetTag, running);
86981
+ if (cmp !== null && cmp < 0) {
86982
+ return {
86983
+ skip: true,
86984
+ running,
86985
+ message: `Skipping ${opts.container} deploy \u2014 it is already on ${running}, newer than the ` + `requested ${opts.targetTag}.
86986
+ ` + ` Refusing to downgrade: this guards against a concurrent rollout/update ` + `reverting a newer build.
86987
+ ` + ` To force the downgrade, re-run with --allow-downgrade.`
86988
+ };
86989
+ }
86990
+ return { skip: false, running };
86991
+ }
86992
+
86993
+ // src/cli/hostd.ts
86920
86994
  init_audit_reader();
86921
86995
  function resolveHostdImageTag(explicitTag, release) {
86922
86996
  if (explicitTag)
@@ -87054,7 +87128,7 @@ function backupExistingCompose() {
87054
87128
  return bak;
87055
87129
  }
87056
87130
  function runDocker(args) {
87057
- const r = spawnSync15("docker", args, { encoding: "utf8" });
87131
+ const r = spawnSync16("docker", args, { encoding: "utf8" });
87058
87132
  return {
87059
87133
  ok: r.status === 0,
87060
87134
  stdout: r.stdout ?? "",
@@ -87081,6 +87155,15 @@ async function doInstall(opts, program3) {
87081
87155
  const composePath = hostdComposePath();
87082
87156
  mkdirSync47(dir, { recursive: true });
87083
87157
  const imageTag = resolveHostdImageTag(opts.tag, cfg.release);
87158
+ const guard = checkDowngrade({
87159
+ container: "switchroom-hostd",
87160
+ targetTag: imageTag,
87161
+ allowDowngrade: opts.allowDowngrade
87162
+ });
87163
+ if (guard.skip) {
87164
+ console.log(source_default.yellow(` \u23ed ${opts.dryRun ? "[dry-run] " : ""}${guard.message}`));
87165
+ return;
87166
+ }
87084
87167
  const yaml = renderHostdComposeFile({
87085
87168
  hostHome: resolveHostdHostHome(),
87086
87169
  imageTag,
@@ -87190,7 +87273,7 @@ ${down.stderr}`));
87190
87273
  }
87191
87274
  function registerHostdCommand(program3) {
87192
87275
  const hostd = program3.command("hostd").description("Manage switchroom-hostd, the host-control daemon for admin agents (RFC C)");
87193
- hostd.command("install").description("Install or refresh the hostd container (writes ~/.switchroom/hostd/docker-compose.yml + docker compose up -d)").option("--tag <tag>", "Image tag override (default: resolved from release.pin in switchroom.yaml, else latest)").option("--dry-run", "Print the compose file and the docker commands without writing or running anything").action(withConfigError(async (opts) => {
87276
+ hostd.command("install").description("Install or refresh the hostd container (writes ~/.switchroom/hostd/docker-compose.yml + docker compose up -d)").option("--tag <tag>", "Image tag override (default: resolved from release.pin in switchroom.yaml, else latest)").option("--dry-run", "Print the compose file and the docker commands without writing or running anything").option("--allow-downgrade", "Deploy even if the running container is on a newer version (overrides the anti-revert guard)").action(withConfigError(async (opts) => {
87194
87277
  await doInstall(opts, program3);
87195
87278
  }));
87196
87279
  hostd.command("status").description("Show daemon state and bound sockets").action(() => doStatus());
@@ -87247,7 +87330,7 @@ init_helpers();
87247
87330
  import { existsSync as existsSync85, mkdirSync as mkdirSync48, writeFileSync as writeFileSync42, copyFileSync as copyFileSync13 } from "node:fs";
87248
87331
  import { homedir as homedir50 } from "node:os";
87249
87332
  import { join as join84 } from "node:path";
87250
- import { spawnSync as spawnSync16 } from "node:child_process";
87333
+ import { spawnSync as spawnSync17 } from "node:child_process";
87251
87334
  function resolveWebImageTag(explicitTag, release) {
87252
87335
  if (explicitTag)
87253
87336
  return explicitTag;
@@ -87346,7 +87429,7 @@ function backupExistingCompose2() {
87346
87429
  return bak;
87347
87430
  }
87348
87431
  function runDocker2(args) {
87349
- const r = spawnSync16("docker", args, { encoding: "utf8" });
87432
+ const r = spawnSync17("docker", args, { encoding: "utf8" });
87350
87433
  return {
87351
87434
  ok: r.status === 0,
87352
87435
  stdout: r.stdout ?? "",
@@ -87366,6 +87449,15 @@ async function doInstall2(opts, program3) {
87366
87449
  mkdirSync48(dir, { recursive: true });
87367
87450
  const cfg = getConfig(program3);
87368
87451
  const imageTag = resolveWebImageTag(opts.tag, cfg.release);
87452
+ const guard = checkDowngrade({
87453
+ container: "switchroom-web",
87454
+ targetTag: imageTag,
87455
+ allowDowngrade: opts.allowDowngrade
87456
+ });
87457
+ if (guard.skip) {
87458
+ console.log(source_default.yellow(` \u23ed ${opts.dryRun ? "[dry-run] " : ""}${guard.message}`));
87459
+ return;
87460
+ }
87369
87461
  const yaml = renderWebComposeFile({
87370
87462
  hostHome: homedir50(),
87371
87463
  imageTag,
@@ -87456,7 +87548,7 @@ ${down.stderr}`));
87456
87548
  }
87457
87549
  function registerWebdCommand(program3) {
87458
87550
  const webd = program3.command("webd").description("Manage switchroom-web, the dashboard + GitHub-webhook receiver container");
87459
- webd.command("install").description("Install or refresh the web container (writes ~/.switchroom/web/docker-compose.yml + docker compose up -d)").option("--tag <tag>", "Image tag override (default: resolved from release.pin in switchroom.yaml, else latest)").option("--dry-run", "Print the compose file and the docker commands without writing or running anything").action(withConfigError(async (opts) => {
87551
+ webd.command("install").description("Install or refresh the web container (writes ~/.switchroom/web/docker-compose.yml + docker compose up -d)").option("--tag <tag>", "Image tag override (default: resolved from release.pin in switchroom.yaml, else latest)").option("--dry-run", "Print the compose file and the docker commands without writing or running anything").option("--allow-downgrade", "Deploy even if the running container is on a newer version (overrides the anti-revert guard)").action(withConfigError(async (opts) => {
87460
87552
  await doInstall2(opts, program3);
87461
87553
  }));
87462
87554
  webd.command("status").description("Show web-service container state").action(() => doStatus2());