squadrant 0.25.0 → 0.25.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -135,13 +135,8 @@ function getDefaultConfig() {
135
135
  captain: "auto",
136
136
  crew: "auto"
137
137
  },
138
- models: {
139
- command: "opus",
140
- captain: "opus",
141
- crew: "sonnet",
142
- exploration: "haiku",
143
- review: "opus"
144
- },
138
+ // #874: no `models` here — it's deprecated (superseded by `roles`), so a
139
+ // fresh init wrote a key the drift check immediately flagged.
145
140
  roles: {
146
141
  command: { agent: "claude", model: "opus" },
147
142
  captain: { agent: "claude", model: "opus" },
@@ -3359,6 +3354,10 @@ function sanitizePathForPlist(path40) {
3359
3354
  continue;
3360
3355
  if (p.includes("/.claude/plugins/"))
3361
3356
  continue;
3357
+ if (p.includes("/.cmuxterm/cmux-cli-shims/"))
3358
+ continue;
3359
+ if (p.includes("/fnm_multishells/"))
3360
+ continue;
3362
3361
  if (seen.has(p))
3363
3362
  continue;
3364
3363
  seen.add(p);
@@ -3386,18 +3385,7 @@ function resolveAgentBinDirs() {
3386
3385
  });
3387
3386
  }
3388
3387
  function buildDaemonPath(shellPath) {
3389
- const agentDirs = resolveAgentBinDirs();
3390
- const sanitized = sanitizePathForPlist(shellPath);
3391
- if (agentDirs.length === 0)
3392
- return sanitized;
3393
- const parts = [...agentDirs, ...sanitized.split(":")];
3394
- const seen = /* @__PURE__ */ new Set();
3395
- return parts.filter((p) => {
3396
- if (!p || seen.has(p))
3397
- return false;
3398
- seen.add(p);
3399
- return true;
3400
- }).join(":");
3388
+ return sanitizePathForPlist([...resolveAgentBinDirs(), shellPath].join(":"));
3401
3389
  }
3402
3390
  function renderPlist(nodeBin, daemonEntry, pathEnv = "") {
3403
3391
  const logPath2 = join8(homedir5(), ".config", "squadrant", "squadrantd.log");
@@ -14346,14 +14334,14 @@ var init_runtimes = __esm({
14346
14334
  });
14347
14335
 
14348
14336
  // packages/workspaces/dist/notifiers/cmux.js
14349
- import { execFile as execFileCb, execSync as execSync7 } from "child_process";
14337
+ import { execFile as execFileCb, execFileSync as execFileSync7 } from "child_process";
14350
14338
  import { promisify as promisify2 } from "util";
14351
14339
  function createCmuxNotifier(_scope) {
14352
14340
  return {
14353
14341
  name: "cmux",
14354
14342
  async probe() {
14355
14343
  try {
14356
- execSync7("squadrant runtime status --command", { encoding: "utf-8", stdio: "pipe" });
14344
+ execFileSync7(resolveCmuxBin(), ["capabilities"], { encoding: "utf-8", stdio: "pipe", timeout: CMUX_TIMEOUT });
14357
14345
  return { installed: true, reachable: true };
14358
14346
  } catch (err) {
14359
14347
  const code = err.code;
@@ -14371,6 +14359,7 @@ function createCmuxNotifier(_scope) {
14371
14359
  var execFile3;
14372
14360
  var init_cmux2 = __esm({
14373
14361
  "packages/workspaces/dist/notifiers/cmux.js"() {
14362
+ init_dist();
14374
14363
  init_cmux();
14375
14364
  execFile3 = promisify2(execFileCb);
14376
14365
  }
@@ -14678,9 +14667,9 @@ var init_events_bridge = __esm({
14678
14667
  });
14679
14668
 
14680
14669
  // packages/workspaces/dist/cmux-daemon/store-fingerprint.js
14681
- import { execFileSync as execFileSync7 } from "child_process";
14670
+ import { execFileSync as execFileSync8 } from "child_process";
14682
14671
  function defaultExecPs(pid) {
14683
- return execFileSync7("ps", ["-o", "command=", "-p", String(pid)], {
14672
+ return execFileSync8("ps", ["-o", "command=", "-p", String(pid)], {
14684
14673
  encoding: "utf-8",
14685
14674
  stdio: ["ignore", "pipe", "ignore"]
14686
14675
  });
@@ -14890,12 +14879,13 @@ function defaultReadFile(path40) {
14890
14879
  return void 0;
14891
14880
  }
14892
14881
  }
14893
- function defaultWatchDir(dir, cb) {
14882
+ function defaultWatchDir(dir, cb, onError) {
14894
14883
  const w = watch(dir, (_event, filename) => {
14895
14884
  if (typeof filename === "string" && filename.endsWith("-hook-sessions.json")) {
14896
14885
  cb();
14897
14886
  }
14898
14887
  });
14888
+ w.on("error", onError);
14899
14889
  return () => w.close();
14900
14890
  }
14901
14891
  var CmuxStoreSource;
@@ -14907,6 +14897,7 @@ var init_cmux_store_source = __esm({
14907
14897
  debounceMs;
14908
14898
  lockRetryMs;
14909
14899
  maxLockRetries;
14900
+ rewatchMs;
14910
14901
  isPidAlive;
14911
14902
  listFiles;
14912
14903
  readFile;
@@ -14918,6 +14909,7 @@ var init_cmux_store_source = __esm({
14918
14909
  deps;
14919
14910
  stopWatcher;
14920
14911
  debounceTimer;
14912
+ rewatchTimer;
14921
14913
  /** filename → pending lock-retry timer (one per locked file). */
14922
14914
  lockRetryTimers = /* @__PURE__ */ new Map();
14923
14915
  /** filename → re-scan attempts used in the current lock episode. */
@@ -14931,6 +14923,7 @@ var init_cmux_store_source = __esm({
14931
14923
  this.debounceMs = opts.debounceMs ?? 50;
14932
14924
  this.lockRetryMs = opts.lockRetryMs ?? 50;
14933
14925
  this.maxLockRetries = opts.maxLockRetries ?? 3;
14926
+ this.rewatchMs = opts.rewatchMs ?? 5e3;
14934
14927
  this.isPidAlive = opts.isPidAlive ?? defaultIsPidAlive2;
14935
14928
  this.listFiles = opts.listFiles ?? defaultListFiles;
14936
14929
  this.readFile = opts.readFile ?? defaultReadFile;
@@ -14946,18 +14939,17 @@ var init_cmux_store_source = __esm({
14946
14939
  this.active = true;
14947
14940
  this.lastError = null;
14948
14941
  this.scan();
14949
- try {
14950
- this.stopWatcher = this.watchDir(this.stateDir, () => this.scheduleDebounced());
14951
- } catch (e) {
14952
- this.lastError = e.message;
14953
- this.log(`cmux-store: failed to watch ${this.stateDir}: ${e.message}`);
14954
- }
14942
+ this.armWatcher();
14955
14943
  }
14956
14944
  stop() {
14957
14945
  if (this.debounceTimer !== void 0) {
14958
14946
  this.cancelTimer(this.debounceTimer);
14959
14947
  this.debounceTimer = void 0;
14960
14948
  }
14949
+ if (this.rewatchTimer !== void 0) {
14950
+ this.cancelTimer(this.rewatchTimer);
14951
+ this.rewatchTimer = void 0;
14952
+ }
14961
14953
  for (const timer of this.lockRetryTimers.values()) {
14962
14954
  this.cancelTimer(timer);
14963
14955
  }
@@ -14978,6 +14970,36 @@ var init_cmux_store_source = __esm({
14978
14970
  return { active: this.active, error: this.lastError };
14979
14971
  }
14980
14972
  // ── private ─────────────────────────────────────────────────────────────────
14973
+ /** Watch for subsequent changes, debounced. */
14974
+ armWatcher() {
14975
+ try {
14976
+ this.stopWatcher = this.watchDir(this.stateDir, () => this.scheduleDebounced(), (err) => this.onWatchError(err));
14977
+ } catch (e) {
14978
+ this.lastError = e.message;
14979
+ this.log(`cmux-store: failed to watch ${this.stateDir}: ${e.message}`);
14980
+ }
14981
+ }
14982
+ /**
14983
+ * The watcher failed after starting (macOS: a refused FSEventStreamStart()
14984
+ * surfaces as EMFILE). Drop it and re-arm later instead of letting the error
14985
+ * escape as an uncaughtException that kills the daemon.
14986
+ */
14987
+ onWatchError(err) {
14988
+ this.lastError = err.message;
14989
+ this.log(`cmux-store: watcher error on ${this.stateDir}: ${err.message} \u2014 re-arming in ${this.rewatchMs}ms`);
14990
+ this.stopWatcher?.();
14991
+ this.stopWatcher = void 0;
14992
+ if (!this.active || this.rewatchTimer !== void 0)
14993
+ return;
14994
+ this.rewatchTimer = this.scheduleTimer(() => {
14995
+ this.rewatchTimer = void 0;
14996
+ if (!this.active)
14997
+ return;
14998
+ this.lastError = null;
14999
+ this.scan();
15000
+ this.armWatcher();
15001
+ }, this.rewatchMs);
15002
+ }
14981
15003
  scheduleDebounced() {
14982
15004
  if (this.debounceTimer !== void 0) {
14983
15005
  this.cancelTimer(this.debounceTimer);
@@ -15079,8 +15101,35 @@ var init_cmux_store_source = __esm({
15079
15101
  import { join as join25 } from "path";
15080
15102
  import { homedir as homedir13 } from "os";
15081
15103
  import { mkdirSync as mkdirSync8, readFileSync as readFileSync18, writeFileSync as writeFileSync11 } from "fs";
15082
- function hookCommandFor(eventName, sub, hookCmd) {
15083
- return eventName === "PermissionRequest" ? `${GATE_HOOK_CMD} claude ${sub}` : `${hookCmd} claude ${sub}`;
15104
+ function hookCommandFor(eventName, sub, hookCmd, gateCmd) {
15105
+ return eventName === "PermissionRequest" ? `${gateCmd} claude ${sub}` : `${hookCmd} claude ${sub}`;
15106
+ }
15107
+ function isSquadrantOwnedCommand(command, sub) {
15108
+ if (typeof command !== "string")
15109
+ return false;
15110
+ const m = command.match(/^(.*) (?:hooks|gate) claude (\S+)$/);
15111
+ if (!m || m[2] !== sub)
15112
+ return false;
15113
+ const prefix = m[1];
15114
+ return prefix === DEFAULT_CLI_CMD || /squadrant\/dist\/index\.js'?$/.test(prefix);
15115
+ }
15116
+ function removeStaleOwnedHandlers(entries, sub, keep) {
15117
+ let removed = false;
15118
+ for (let i = entries.length - 1; i >= 0; i--) {
15119
+ const entry = entries[i];
15120
+ if (!Array.isArray(entry?.hooks))
15121
+ continue;
15122
+ const before = entry.hooks.length;
15123
+ entry.hooks = entry.hooks.filter((h) => {
15124
+ const cmd = h?.command;
15125
+ return cmd === keep || !isSquadrantOwnedCommand(cmd, sub);
15126
+ });
15127
+ if (entry.hooks.length !== before)
15128
+ removed = true;
15129
+ if (entry.hooks.length === 0)
15130
+ entries.splice(i, 1);
15131
+ }
15132
+ return removed;
15084
15133
  }
15085
15134
  function removeCommandHandlers(entries, command) {
15086
15135
  let removed = false;
@@ -15140,7 +15189,9 @@ function removeForeignGateHandlers(entries) {
15140
15189
  }
15141
15190
  function installClaudeHooks(opts = {}) {
15142
15191
  const settingsPath = opts.settingsPath ?? join25(homedir13(), ".claude", "settings.json");
15143
- const hookCmd = opts.hookCmd ?? DEFAULT_HOOK_CMD;
15192
+ const cliCmd = opts.cliCmd ?? DEFAULT_CLI_CMD;
15193
+ const hookCmd = opts.hookCmd ?? `${cliCmd} hooks`;
15194
+ const gateCmd = `${cliCmd} gate`;
15144
15195
  const readFile7 = opts.readFile ?? defaultReadFile2;
15145
15196
  const writeFile6 = opts.writeFile ?? defaultWriteFile;
15146
15197
  const log = opts.log ?? (() => {
@@ -15162,12 +15213,13 @@ function installClaudeHooks(opts = {}) {
15162
15213
  let changed = false;
15163
15214
  const repaired = [];
15164
15215
  const migrated = [];
15216
+ const repointed = [];
15165
15217
  for (const [eventName, sub, matcher] of CLAUDE_HOOK_EVENTS) {
15166
15218
  if (!Array.isArray(hooks[eventName])) {
15167
15219
  hooks[eventName] = [];
15168
15220
  }
15169
15221
  const entries = hooks[eventName];
15170
- const command = hookCommandFor(eventName, sub, hookCmd);
15222
+ const command = hookCommandFor(eventName, sub, hookCmd, gateCmd);
15171
15223
  const hookMatcher = matcher ?? "";
15172
15224
  if (eventName === "PermissionRequest") {
15173
15225
  const legacy = `${hookCmd} claude ${sub}`;
@@ -15193,11 +15245,14 @@ function installClaudeHooks(opts = {}) {
15193
15245
  }
15194
15246
  }
15195
15247
  }
15248
+ const wasRepointed = removeStaleOwnedHandlers(entries, sub, command);
15249
+ if (wasRepointed)
15250
+ changed = true;
15196
15251
  const alreadyPresent = entries.some((m) => Array.isArray(m.hooks) && m.hooks.some((h) => typeof h.command === "string" && h.command === command));
15197
15252
  if (!alreadyPresent) {
15198
15253
  entries.push({ matcher: hookMatcher, hooks: [{ type: "command", command, timeout: 10 }] });
15199
15254
  changed = true;
15200
- repaired.push(`${eventName}/${sub}`);
15255
+ (wasRepointed ? repointed : repaired).push(`${eventName}/${sub}`);
15201
15256
  }
15202
15257
  }
15203
15258
  if (repaired.length > 0 && hadExistingSettings) {
@@ -15206,6 +15261,9 @@ function installClaudeHooks(opts = {}) {
15206
15261
  if (migrated.length > 0) {
15207
15262
  log(`native-hook: migrated ${migrated.length} PermissionRequest hook(s) to the U7 permission gate in ${settingsPath} [${migrated.join(", ")}]`);
15208
15263
  }
15264
+ if (repointed.length > 0) {
15265
+ log(`native-hook: repointed ${repointed.length} squadrant hook(s) to ${cliCmd} in ${settingsPath} [${repointed.join(", ")}]`);
15266
+ }
15209
15267
  if (opts.claudeEnv && Object.keys(opts.claudeEnv).length > 0) {
15210
15268
  if (typeof settings.env !== "object" || settings.env === null || Array.isArray(settings.env)) {
15211
15269
  settings.env = {};
@@ -15320,7 +15378,7 @@ function defaultWriteFile(path40, content) {
15320
15378
  mkdirSync8(path40.replace(/\/[^/]+$/, ""), { recursive: true });
15321
15379
  writeFileSync11(path40, content, "utf-8");
15322
15380
  }
15323
- var CLAUDE_HOOK_EVENTS, DEFAULT_HOOK_CMD, GATE_HOOK_CMD, FOREIGN_AUTO_GATE_MARKER, SUBAGENT_MODEL_KEY, SMALL_FAST_MODEL_KEY, NativeHookSource;
15381
+ var CLAUDE_HOOK_EVENTS, DEFAULT_CLI_CMD, FOREIGN_AUTO_GATE_MARKER, SUBAGENT_MODEL_KEY, SMALL_FAST_MODEL_KEY, NativeHookSource;
15324
15382
  var init_native_hook_source = __esm({
15325
15383
  "packages/workspaces/dist/native-hooks/native-hook-source.js"() {
15326
15384
  CLAUDE_HOOK_EVENTS = [
@@ -15338,8 +15396,7 @@ var init_native_hook_source = __esm({
15338
15396
  // this at all; without it the watchdog reports a plain stall (wrong story).
15339
15397
  ["StopFailure", "stop-failure"]
15340
15398
  ];
15341
- DEFAULT_HOOK_CMD = "squadrant hooks";
15342
- GATE_HOOK_CMD = "squadrant gate";
15399
+ DEFAULT_CLI_CMD = "squadrant";
15343
15400
  FOREIGN_AUTO_GATE_MARKER = "auto-gate-managed";
15344
15401
  SUBAGENT_MODEL_KEY = "CLAUDE_CODE_SUBAGENT_MODEL";
15345
15402
  SMALL_FAST_MODEL_KEY = "ANTHROPIC_SMALL_FAST_MODEL";
@@ -15853,7 +15910,7 @@ init_dist();
15853
15910
  init_dist();
15854
15911
  init_dist4();
15855
15912
  import { Command } from "commander";
15856
- import { execSync as execSync8 } from "child_process";
15913
+ import { execSync as execSync7 } from "child_process";
15857
15914
  import fs20 from "fs";
15858
15915
  import { stat } from "fs/promises";
15859
15916
  import path23 from "path";
@@ -15936,7 +15993,7 @@ function printServiceHealth(rows, now = Date.now()) {
15936
15993
  init_dist3();
15937
15994
  function commandExists(cmd) {
15938
15995
  try {
15939
- execSync8(`which ${cmd}`, { stdio: "ignore" });
15996
+ execSync7(`which ${cmd}`, { stdio: "ignore" });
15940
15997
  return true;
15941
15998
  } catch {
15942
15999
  return false;
@@ -15944,7 +16001,7 @@ function commandExists(cmd) {
15944
16001
  }
15945
16002
  function claudeVersionOk() {
15946
16003
  try {
15947
- const version = execSync8("claude --version", { encoding: "utf-8" }).trim();
16004
+ const version = execSync7("claude --version", { encoding: "utf-8" }).trim();
15948
16005
  const match = version.match(/(\d+)\.(\d+)\.(\d+)/);
15949
16006
  if (!match) return false;
15950
16007
  const [major, minor, patch] = match.slice(1).map(Number);
@@ -15986,7 +16043,7 @@ function nodeVersionOk() {
15986
16043
  }
15987
16044
  function tryGetVersion(cmd) {
15988
16045
  try {
15989
- return execSync8(`${cmd} --version`, { encoding: "utf-8" }).trim();
16046
+ return execSync7(`${cmd} --version`, { encoding: "utf-8" }).trim();
15990
16047
  } catch {
15991
16048
  return "";
15992
16049
  }
@@ -16023,7 +16080,7 @@ function readPackageVersion(packageJsonPath) {
16023
16080
  }
16024
16081
  function tryGetGlobalRoot(cmd, args) {
16025
16082
  try {
16026
- return execSync8(`${cmd} ${args.join(" ")}`, { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim() || void 0;
16083
+ return execSync7(`${cmd} ${args.join(" ")}`, { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim() || void 0;
16027
16084
  } catch {
16028
16085
  return void 0;
16029
16086
  }
@@ -16461,7 +16518,7 @@ function writePerCrewOpencodeConfig(o) {
16461
16518
  }
16462
16519
 
16463
16520
  // packages/cli/src/lib/claude-auth.ts
16464
- import { execSync as execSync9 } from "child_process";
16521
+ import { execSync as execSync8 } from "child_process";
16465
16522
  function parseClaudeAuthStatus(raw) {
16466
16523
  let parsed;
16467
16524
  try {
@@ -16479,7 +16536,7 @@ function parseClaudeAuthStatus(raw) {
16479
16536
  };
16480
16537
  }
16481
16538
  function detectClaudeAuth(probe = {}) {
16482
- const run = probe.run ?? (() => execSync9("claude auth status", {
16539
+ const run = probe.run ?? (() => execSync8("claude auth status", {
16483
16540
  encoding: "utf8",
16484
16541
  stdio: ["ignore", "pipe", "ignore"],
16485
16542
  timeout: 1e4
@@ -16959,7 +17016,7 @@ init_dist4();
16959
17016
  init_dist3();
16960
17017
  init_dist();
16961
17018
  import { Command as Command5 } from "commander";
16962
- import { execSync as execSync10 } from "child_process";
17019
+ import { execSync as execSync9 } from "child_process";
16963
17020
  import path26 from "path";
16964
17021
  import os15 from "os";
16965
17022
  import chalk7 from "chalk";
@@ -16970,7 +17027,7 @@ var TASK_PROMPTS = {
16970
17027
  "wiki-aggregate": "Run a wiki aggregation pass using the squadrant:command-ops skill. Scan each spoke wiki index, identify shared knowledge worth promoting, write hub wiki pages, and exit when done."
16971
17028
  };
16972
17029
  function detectCurrentWorkspace() {
16973
- const out = execSync10(`"${resolveCmuxBin()}" current-workspace`, { encoding: "utf-8" }).trim();
17030
+ const out = execSync9(`"${resolveCmuxBin()}" current-workspace`, { encoding: "utf-8" }).trim();
16974
17031
  const match = out.match(/workspace:\d+/);
16975
17032
  if (!match) {
16976
17033
  throw new Error("Could not detect current cmux workspace. Run `squadrant command` from inside a cmux workspace.");
@@ -17037,7 +17094,7 @@ init_dist3();
17037
17094
  import { Command as Command9 } from "commander";
17038
17095
  import { createConnection as createConnection4 } from "net";
17039
17096
  import { randomUUID as randomUUID5 } from "crypto";
17040
- import { execFileSync as execFileSync8 } from "child_process";
17097
+ import { execFileSync as execFileSync9 } from "child_process";
17041
17098
  import { homedir as homedir15 } from "os";
17042
17099
  import { join as join27 } from "path";
17043
17100
  import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync13 } from "fs";
@@ -17541,10 +17598,10 @@ function resolveApproveTarget(tasks, crew) {
17541
17598
  return matches.reduce((a, b) => (b.createdAt ?? 0) > (a.createdAt ?? 0) ? b : a);
17542
17599
  }
17543
17600
  function defaultPushBranch(cwd, branch) {
17544
- execFileSync8("git", ["-C", cwd, "push", "-u", "origin", branch], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
17601
+ execFileSync9("git", ["-C", cwd, "push", "-u", "origin", branch], { encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
17545
17602
  }
17546
17603
  function defaultCreatePr(cwd, o) {
17547
- return execFileSync8(
17604
+ return execFileSync9(
17548
17605
  "gh",
17549
17606
  ["pr", "create", "--base", o.base, "--head", o.branch, "--title", o.title, "--body", o.body],
17550
17607
  { cwd, encoding: "utf-8" }
@@ -17552,7 +17609,7 @@ function defaultCreatePr(cwd, o) {
17552
17609
  }
17553
17610
  function defaultGetCommitSubject(cwd) {
17554
17611
  try {
17555
- return execFileSync8("git", ["-C", cwd, "log", "-1", "--format=%s"], {
17612
+ return execFileSync9("git", ["-C", cwd, "log", "-1", "--format=%s"], {
17556
17613
  encoding: "utf-8",
17557
17614
  stdio: ["ignore", "pipe", "pipe"]
17558
17615
  }).trim();
@@ -18092,7 +18149,7 @@ init_dist();
18092
18149
  init_dist4();
18093
18150
  import { Command as Command11 } from "commander";
18094
18151
  import chalk11 from "chalk";
18095
- import { execFileSync as execFileSync9 } from "child_process";
18152
+ import { execFileSync as execFileSync10 } from "child_process";
18096
18153
  import readline2 from "readline";
18097
18154
  function resolveDiffTarget(tasks, crew, projectPath) {
18098
18155
  const matches = tasks.filter((t) => t.name === crew);
@@ -18163,14 +18220,14 @@ function promptLine2(question) {
18163
18220
  }
18164
18221
  function getPrDiff(projectPath, pr) {
18165
18222
  try {
18166
- return execFileSync9("gh", ["pr", "diff", pr], { cwd: projectPath, encoding: "utf-8" });
18223
+ return execFileSync10("gh", ["pr", "diff", pr], { cwd: projectPath, encoding: "utf-8" });
18167
18224
  } catch (e) {
18168
18225
  throw new Error(`Could not fetch PR #${pr} diff (gh pr diff failed): ${e.message}`);
18169
18226
  }
18170
18227
  }
18171
18228
  function getRefsDiff(projectPath, base, head) {
18172
18229
  try {
18173
- return execFileSync9("git", ["-C", projectPath, "diff", `${base}...${head}`], { encoding: "utf-8" });
18230
+ return execFileSync10("git", ["-C", projectPath, "diff", `${base}...${head}`], { encoding: "utf-8" });
18174
18231
  } catch (e) {
18175
18232
  throw new Error(`Could not diff ${base}...${head}: ${e.message}`);
18176
18233
  }
@@ -18191,7 +18248,7 @@ async function openCrewDiff(project, proj, crew, opts, runtime, workspaceId) {
18191
18248
  let opened = 0;
18192
18249
  for (const source of sources) {
18193
18250
  const statArgs = source === "staged" ? ["diff", "--stat", "--cached"] : ["diff", "--stat"];
18194
- const stat2 = execFileSync9("git", ["-C", target.cwd, ...statArgs], { encoding: "utf-8" }).trim();
18251
+ const stat2 = execFileSync10("git", ["-C", target.cwd, ...statArgs], { encoding: "utf-8" }).trim();
18195
18252
  if (!stat2) continue;
18196
18253
  await runtime.showDiff({
18197
18254
  workspaceId,
@@ -18212,7 +18269,7 @@ async function openCrewDiff(project, proj, crew, opts, runtime, workspaceId) {
18212
18269
  }
18213
18270
  return;
18214
18271
  }
18215
- const diffStat = execFileSync9(
18272
+ const diffStat = execFileSync10(
18216
18273
  "git",
18217
18274
  ["-C", target.cwd, "diff", "--stat", `${base}...HEAD`],
18218
18275
  { encoding: "utf-8" }
@@ -18261,7 +18318,7 @@ async function runDiff(project, crewArg, opts) {
18261
18318
  const base = resolveWorktreeBase(proj.path);
18262
18319
  const stats = buildCrewDiffStats(tasks, proj.path, base, (cwd, b) => {
18263
18320
  try {
18264
- return execFileSync9("git", ["-C", cwd, "diff", "--stat", `${b}...HEAD`], { encoding: "utf-8" });
18321
+ return execFileSync10("git", ["-C", cwd, "diff", "--stat", `${b}...HEAD`], { encoding: "utf-8" });
18265
18322
  } catch {
18266
18323
  return "";
18267
18324
  }
@@ -18432,7 +18489,7 @@ sideCommand.command("close").description("Close a side-session (closes its tab)"
18432
18489
  init_dist();
18433
18490
  init_dist4();
18434
18491
  import { Command as Command13 } from "commander";
18435
- import { execSync as execSync11 } from "child_process";
18492
+ import { execSync as execSync10 } from "child_process";
18436
18493
  import chalk14 from "chalk";
18437
18494
 
18438
18495
  // packages/web/dist/read-status.js
@@ -19853,7 +19910,7 @@ async function startWebServer(opts) {
19853
19910
  init_dist();
19854
19911
  var SOCK3 = DAEMON_SOCK_PATH;
19855
19912
  function detectCurrentWorkspace2() {
19856
- const out = execSync11(`"${resolveCmuxBin()}" current-workspace`, { encoding: "utf-8" }).trim();
19913
+ const out = execSync10(`"${resolveCmuxBin()}" current-workspace`, { encoding: "utf-8" }).trim();
19857
19914
  const match = out.match(/workspace:\d+/);
19858
19915
  if (!match) {
19859
19916
  throw new Error("Could not detect current cmux workspace. Run `squadrant dashboard --pane` from inside a cmux workspace.");
@@ -19936,7 +19993,7 @@ init_dist3();
19936
19993
  init_dist4();
19937
19994
  init_dist2();
19938
19995
  import { Command as Command14 } from "commander";
19939
- import { execSync as execSync12, execFileSync as execFileSync10 } from "child_process";
19996
+ import { execSync as execSync11, execFileSync as execFileSync11 } from "child_process";
19940
19997
  import fs25 from "fs";
19941
19998
  import path29 from "path";
19942
19999
  import os17 from "os";
@@ -20054,7 +20111,7 @@ function pickResumeSessionId(record, agentName, fresh = false) {
20054
20111
  }
20055
20112
  function isOpencodeCaptainDir(dir) {
20056
20113
  try {
20057
- execFileSync10("git", ["-C", dir, "rev-parse", "--verify", "HEAD"], { stdio: "ignore" });
20114
+ execFileSync11("git", ["-C", dir, "rev-parse", "--verify", "HEAD"], { stdio: "ignore" });
20058
20115
  return true;
20059
20116
  } catch {
20060
20117
  return false;
@@ -20068,7 +20125,7 @@ function resolveAnthropicRefusal(role, workspaceName, agentName, model, readOpen
20068
20125
  function ensureCmuxReady(headless) {
20069
20126
  if (headless || isInsideCmux()) return;
20070
20127
  console.log(chalk15.yellow("\n Not running inside cmux. Opening cmux app...\n"));
20071
- execSync12(`open "${CMUX_APP}"`, { stdio: "inherit" });
20128
+ execSync11(`open "${CMUX_APP}"`, { stdio: "inherit" });
20072
20129
  console.log(chalk15.bold(" Run `squadrant launch` from inside a cmux workspace.\n"));
20073
20130
  process.exit(0);
20074
20131
  }
@@ -20489,7 +20546,7 @@ import fs26 from "fs";
20489
20546
  import os18 from "os";
20490
20547
  import path30 from "path";
20491
20548
  import { fileURLToPath as fileURLToPath3 } from "url";
20492
- import { execSync as execSync13 } from "child_process";
20549
+ import { execSync as execSync12 } from "child_process";
20493
20550
  import chalk17 from "chalk";
20494
20551
  var REPO_URL = "https://github.com/tu11aa/squadrant";
20495
20552
  function readPkgVersion() {
@@ -20548,7 +20605,7 @@ var feedbackCommand = new Command16("feedback").description("Open a pre-filled G
20548
20605
  console.log(chalk17.dim(` URL: ${issueUrl.substring(0, 80)}...
20549
20606
  `));
20550
20607
  try {
20551
- execSync13(`open "${issueUrl}"`, { stdio: "ignore" });
20608
+ execSync12(`open "${issueUrl}"`, { stdio: "ignore" });
20552
20609
  console.log(chalk17.green(" \u2714 Browser opened\n"));
20553
20610
  } catch {
20554
20611
  console.log(chalk17.yellow(" \u26A0 Could not open browser automatically."));
@@ -21303,7 +21360,7 @@ function readPkgVersion2() {
21303
21360
 
21304
21361
  // packages/cli/src/commands/heal.ts
21305
21362
  init_dist();
21306
- import { execFileSync as execFileSync11 } from "child_process";
21363
+ import { execFileSync as execFileSync12 } from "child_process";
21307
21364
  import { join as join31 } from "path";
21308
21365
  import { homedir as homedir17 } from "os";
21309
21366
  import { Command as Command24 } from "commander";
@@ -21512,7 +21569,7 @@ async function runHealCaptain(projects, deps) {
21512
21569
  }
21513
21570
  function kickstartDaemonForHealCaptain() {
21514
21571
  const uid = process.getuid?.() ?? 0;
21515
- execFileSync11("launchctl", ["kickstart", "-k", `gui/${uid}/${LABEL}`], { stdio: "ignore" });
21572
+ execFileSync12("launchctl", ["kickstart", "-k", `gui/${uid}/${LABEL}`], { stdio: "ignore" });
21516
21573
  }
21517
21574
  var healCommand = new Command24("heal").description("Targeted, idempotent remediation for squadrant components (daemon, health)").addHelpText("after", "\nDeferred: 'squadrant heal crew <id>' (re-attach) \u2014 see issue #100.").addCommand(
21518
21575
  new Command24("status").description("Dry-run: print unhealthy components and the exact heal command for each").option("-p, --project <project>", "scope to one project").option("--json", "output machine-readable JSON (exit 0=healthy, 1=error, 2=unhealthy)").action(async (opts) => {
@@ -21577,7 +21634,7 @@ import chalk26 from "chalk";
21577
21634
  init_dist();
21578
21635
  init_dist2();
21579
21636
  import { Command as Command25 } from "commander";
21580
- import { execSync as execSync14 } from "child_process";
21637
+ import { execSync as execSync13 } from "child_process";
21581
21638
  import chalk25 from "chalk";
21582
21639
  async function runDispatch(toProject, task, opts) {
21583
21640
  const fromProject = resolveCurrentProject(loadConfig());
@@ -21593,7 +21650,7 @@ async function runDispatch(toProject, task, opts) {
21593
21650
  warmupTimeoutMs: opts.warmupTimeout,
21594
21651
  bootCaptain: async (project) => {
21595
21652
  try {
21596
- execSync14(`squadrant launch ${project}`, { stdio: "ignore", timeout: 15e3 });
21653
+ execSync13(`squadrant launch ${project}`, { stdio: "ignore", timeout: 15e3 });
21597
21654
  } catch {
21598
21655
  throw new Error(`failed to launch captain for '${project}' \u2014 is squadrant installed?`);
21599
21656
  }
@@ -23158,7 +23215,7 @@ import os20 from "os";
23158
23215
 
23159
23216
  // packages/cli/src/lib/handoff-live-repo.ts
23160
23217
  init_dist();
23161
- import { execFileSync as execFileSync12 } from "child_process";
23218
+ import { execFileSync as execFileSync13 } from "child_process";
23162
23219
  import fs33 from "fs";
23163
23220
  import path36 from "path";
23164
23221
 
@@ -23237,7 +23294,7 @@ var OPEN_PR_LIMIT = 20;
23237
23294
  var RELEASE_BRANCH = "main";
23238
23295
  var defaultCommandRunner = {
23239
23296
  run(cmd, args, cwd) {
23240
- return execFileSync12(cmd, args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
23297
+ return execFileSync13(cmd, args, { cwd, encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] });
23241
23298
  }
23242
23299
  };
23243
23300
  function tryRun2(runner, cmd, args, cwd) {