squadrant 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -744,6 +744,7 @@ var init_update_check = __esm({
744
744
 
745
745
  // packages/shared/dist/lib/git-worktree.js
746
746
  import { execFileSync as execFileSync2 } from "child_process";
747
+ import fs4 from "fs";
747
748
  import path4 from "path";
748
749
  function worktreePath(repoRoot, worktreeDir, project, name) {
749
750
  return path4.resolve(repoRoot, worktreeDir, `${project}-${name}`);
@@ -751,6 +752,18 @@ function worktreePath(repoRoot, worktreeDir, project, name) {
751
752
  function crewBranch(name) {
752
753
  return `crew/${name}`;
753
754
  }
755
+ function ensureSpotlightExcluded(repoRoot, worktreeDir) {
756
+ if (process.platform !== "darwin")
757
+ return;
758
+ try {
759
+ const dir = path4.resolve(repoRoot, worktreeDir);
760
+ fs4.mkdirSync(dir, { recursive: true });
761
+ const marker = path4.join(dir, ".metadata_never_index");
762
+ if (!fs4.existsSync(marker))
763
+ fs4.writeFileSync(marker, "");
764
+ } catch {
765
+ }
766
+ }
754
767
  function resolveWorktreeBase(repoRoot, fallback = "develop") {
755
768
  try {
756
769
  const ref = execFileSync2("git", ["-C", repoRoot, "symbolic-ref", "refs/remotes/origin/HEAD"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
@@ -763,6 +776,7 @@ function resolveWorktreeBase(repoRoot, fallback = "develop") {
763
776
  return fallback;
764
777
  }
765
778
  function addWorktree(spec) {
779
+ ensureSpotlightExcluded(spec.repoRoot, spec.worktreeDir);
766
780
  const originalBranch = crewBranch(spec.name);
767
781
  let targetName = spec.name;
768
782
  let targetBranch = originalBranch;
@@ -798,8 +812,25 @@ function addWorktree(spec) {
798
812
  }
799
813
  const wt = worktreePath(spec.repoRoot, spec.worktreeDir, spec.project, targetName);
800
814
  execFileSync2("git", ["-C", spec.repoRoot, "worktree", "add", wt, "-b", targetBranch, spec.base], { stdio: "pipe" });
815
+ installWorktreeDependencies(wt);
801
816
  return wt;
802
817
  }
818
+ function installWorktreeDependencies(wt) {
819
+ if (!fs4.existsSync(path4.join(wt, "package.json")))
820
+ return;
821
+ if (fs4.existsSync(path4.join(wt, "pnpm-lock.yaml"))) {
822
+ execFileSync2("pnpm", ["-C", wt, "install", "--frozen-lockfile"], { stdio: "pipe" });
823
+ } else if (fs4.existsSync(path4.join(wt, "yarn.lock"))) {
824
+ execFileSync2("yarn", ["install", "--frozen-lockfile"], { cwd: wt, stdio: "pipe" });
825
+ } else if (fs4.existsSync(path4.join(wt, "package-lock.json"))) {
826
+ execFileSync2("npm", ["ci"], { cwd: wt, stdio: "pipe" });
827
+ } else if (fs4.existsSync(path4.join(wt, "bun.lockb"))) {
828
+ execFileSync2("bun", ["install", "--frozen-lockfile"], { cwd: wt, stdio: "pipe" });
829
+ } else {
830
+ process.stderr.write(`worktree ${wt}: package.json present but no lockfile \u2014 dependencies not installed; local typechecks/tests may resolve against the main checkout instead of this worktree.
831
+ `);
832
+ }
833
+ }
803
834
  function removeWorktree(repoRoot, wtPath) {
804
835
  try {
805
836
  execFileSync2("git", ["-C", repoRoot, "worktree", "remove", wtPath], { stdio: "pipe" });
@@ -813,7 +844,7 @@ var init_git_worktree = __esm({
813
844
  });
814
845
 
815
846
  // packages/shared/dist/lib/resolve-text-input.js
816
- import fs4 from "fs";
847
+ import fs5 from "fs";
817
848
  async function readAllStdin() {
818
849
  const chunks = [];
819
850
  for await (const chunk of process.stdin) {
@@ -825,7 +856,7 @@ function flagName(label) {
825
856
  return label === "task" ? "--task-file" : "--message-file";
826
857
  }
827
858
  async function resolveTextInput(opts, deps) {
828
- const readFile6 = deps?.readFile ?? ((p) => fs4.readFileSync(p, "utf8"));
859
+ const readFile6 = deps?.readFile ?? ((p) => fs5.readFileSync(p, "utf8"));
829
860
  const readStdin3 = deps?.readStdin ?? readAllStdin;
830
861
  if (opts.filePath) {
831
862
  if (opts.filePath === "-") {
@@ -853,19 +884,19 @@ var init_resolve_text_input = __esm({
853
884
  });
854
885
 
855
886
  // packages/shared/dist/lib/runtime-sync.js
856
- import fs5 from "fs";
887
+ import fs6 from "fs";
857
888
  import path5 from "path";
858
889
  function copyIfDifferent(src, dest) {
859
- if (fs5.existsSync(dest)) {
860
- if (fs5.readFileSync(src).equals(fs5.readFileSync(dest)))
890
+ if (fs6.existsSync(dest)) {
891
+ if (fs6.readFileSync(src).equals(fs6.readFileSync(dest)))
861
892
  return false;
862
893
  }
863
- fs5.copyFileSync(src, dest);
894
+ fs6.copyFileSync(src, dest);
864
895
  return true;
865
896
  }
866
897
  function mirrorDir(src, dest) {
867
- fs5.mkdirSync(dest, { recursive: true });
868
- const srcEntries = fs5.readdirSync(src, { withFileTypes: true });
898
+ fs6.mkdirSync(dest, { recursive: true });
899
+ const srcEntries = fs6.readdirSync(src, { withFileTypes: true });
869
900
  const srcNames = new Set(srcEntries.map((e) => e.name));
870
901
  for (const entry of srcEntries) {
871
902
  const srcPath = path5.join(src, entry.name);
@@ -876,25 +907,25 @@ function mirrorDir(src, dest) {
876
907
  copyIfDifferent(srcPath, destPath);
877
908
  }
878
909
  }
879
- for (const entry of fs5.readdirSync(dest, { withFileTypes: true })) {
910
+ for (const entry of fs6.readdirSync(dest, { withFileTypes: true })) {
880
911
  if (!srcNames.has(entry.name)) {
881
- fs5.rmSync(path5.join(dest, entry.name), { recursive: true, force: true });
912
+ fs6.rmSync(path5.join(dest, entry.name), { recursive: true, force: true });
882
913
  }
883
914
  }
884
915
  }
885
916
  function mirrorFlat(src, dest, match, chmod) {
886
- fs5.mkdirSync(dest, { recursive: true });
887
- const matched = fs5.readdirSync(src, { withFileTypes: true }).filter((e) => e.isFile() && match.test(e.name)).map((e) => e.name);
917
+ fs6.mkdirSync(dest, { recursive: true });
918
+ const matched = fs6.readdirSync(src, { withFileTypes: true }).filter((e) => e.isFile() && match.test(e.name)).map((e) => e.name);
888
919
  const matchedSet = new Set(matched);
889
920
  for (const name of matched) {
890
921
  const destPath = path5.join(dest, name);
891
922
  const copied = copyIfDifferent(path5.join(src, name), destPath);
892
923
  if (copied && chmod !== void 0)
893
- fs5.chmodSync(destPath, chmod);
924
+ fs6.chmodSync(destPath, chmod);
894
925
  }
895
- for (const entry of fs5.readdirSync(dest, { withFileTypes: true })) {
926
+ for (const entry of fs6.readdirSync(dest, { withFileTypes: true })) {
896
927
  if (!matchedSet.has(entry.name)) {
897
- fs5.rmSync(path5.join(dest, entry.name), { recursive: true, force: true });
928
+ fs6.rmSync(path5.join(dest, entry.name), { recursive: true, force: true });
898
929
  }
899
930
  }
900
931
  }
@@ -903,7 +934,7 @@ function ensureRuntimeSynced(opts) {
903
934
  for (const t of targets) {
904
935
  const srcDir = path5.join(opts.sourceRoot, t.srcRel);
905
936
  try {
906
- if (!fs5.existsSync(srcDir))
937
+ if (!fs6.existsSync(srcDir))
907
938
  continue;
908
939
  const destDir = path5.join(opts.runtimeRoot, t.name);
909
940
  if (t.mode === "tree") {
@@ -969,7 +1000,7 @@ var init_tool_compat = __esm({
969
1000
  });
970
1001
 
971
1002
  // packages/shared/dist/lib/canonical-source.js
972
- import fs6 from "fs";
1003
+ import fs7 from "fs";
973
1004
  import path6 from "path";
974
1005
  function parseSkill(raw) {
975
1006
  const match = raw.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
@@ -1011,7 +1042,7 @@ async function readSkills(driver, skillsDir) {
1011
1042
  function readRoleTemplates(opts) {
1012
1043
  if (!opts.pkgRoot)
1013
1044
  return "";
1014
- const reader = opts.readFile ?? ((p) => fs6.readFileSync(p, "utf-8"));
1045
+ const reader = opts.readFile ?? ((p) => fs7.readFileSync(p, "utf-8"));
1015
1046
  const sections = [];
1016
1047
  for (const { file, heading } of ROLE_TEMPLATES) {
1017
1048
  const full = path6.join(opts.pkgRoot, "templates", file);
@@ -1051,7 +1082,7 @@ var init_canonical_source = __esm({
1051
1082
 
1052
1083
  // packages/shared/dist/lib/daily-logs.js
1053
1084
  import { execSync } from "child_process";
1054
- import fs7 from "fs";
1085
+ import fs8 from "fs";
1055
1086
  import path7 from "path";
1056
1087
  import matter from "gray-matter";
1057
1088
  function iso(d) {
@@ -1104,7 +1135,7 @@ function getGitCommits(projectPath, dateStr) {
1104
1135
  }
1105
1136
  function getGitCommitsInRange(projectPath, since, until) {
1106
1137
  const resolved = resolveHome(projectPath);
1107
- if (!fs7.existsSync(path7.join(resolved, ".git")))
1138
+ if (!fs8.existsSync(path7.join(resolved, ".git")))
1108
1139
  return [];
1109
1140
  const untilArg = until ? ` --until="${until}"` : "";
1110
1141
  try {
@@ -1118,7 +1149,7 @@ function getGitCommitsInRange(projectPath, since, until) {
1118
1149
  }
1119
1150
  function getMergedPRsInRange(projectPath, since, until) {
1120
1151
  const resolved = resolveHome(projectPath);
1121
- if (!fs7.existsSync(path7.join(resolved, ".git")))
1152
+ if (!fs8.existsSync(path7.join(resolved, ".git")))
1122
1153
  return [];
1123
1154
  const untilArg = until ? ` --until="${until}"` : "";
1124
1155
  try {
@@ -1830,7 +1861,7 @@ var init_reduce = __esm({
1830
1861
  });
1831
1862
 
1832
1863
  // packages/core/dist/mailbox.js
1833
- import { promises as fs8 } from "fs";
1864
+ import { promises as fs9 } from "fs";
1834
1865
  import { join as join5 } from "path";
1835
1866
  import { randomUUID } from "crypto";
1836
1867
  function inboxDir(stateRoot) {
@@ -1847,7 +1878,7 @@ async function listRotatedOldestFirst(stateRoot, project) {
1847
1878
  const dir = inboxDir(stateRoot);
1848
1879
  let entries;
1849
1880
  try {
1850
- entries = await fs8.readdir(dir);
1881
+ entries = await fs9.readdir(dir);
1851
1882
  } catch {
1852
1883
  return [];
1853
1884
  }
@@ -1856,7 +1887,7 @@ async function listRotatedOldestFirst(stateRoot, project) {
1856
1887
  }
1857
1888
  async function readMaxSeqFromFile(file) {
1858
1889
  try {
1859
- const buf = await fs8.readFile(file, "utf-8");
1890
+ const buf = await fs9.readFile(file, "utf-8");
1860
1891
  if (!buf.trim())
1861
1892
  return 0;
1862
1893
  const lines = buf.trim().split("\n");
@@ -1897,12 +1928,12 @@ function withProjectLock(project, fn) {
1897
1928
  function appendEntry(stateRoot, project, build) {
1898
1929
  return withProjectLock(project, async () => {
1899
1930
  const dir = inboxDir(stateRoot);
1900
- await fs8.mkdir(dir, { recursive: true });
1931
+ await fs9.mkdir(dir, { recursive: true });
1901
1932
  const file = logPath(stateRoot, project);
1902
1933
  const lastSeq = await readMaxSeq(stateRoot, project);
1903
1934
  const seq = lastSeq + 1;
1904
1935
  const entry = build(seq);
1905
- await fs8.appendFile(file, JSON.stringify(entry) + "\n", { encoding: "utf-8" });
1936
+ await fs9.appendFile(file, JSON.stringify(entry) + "\n", { encoding: "utf-8" });
1906
1937
  return seq;
1907
1938
  });
1908
1939
  }
@@ -1933,7 +1964,7 @@ function cursorPath(stateRoot, project, subscriber) {
1933
1964
  async function readCursor(opts) {
1934
1965
  let buf;
1935
1966
  try {
1936
- buf = await fs8.readFile(cursorPath(opts.stateRoot, opts.project, opts.subscriber), "utf-8");
1967
+ buf = await fs9.readFile(cursorPath(opts.stateRoot, opts.project, opts.subscriber), "utf-8");
1937
1968
  } catch (e) {
1938
1969
  if (e.code === "ENOENT")
1939
1970
  return null;
@@ -1948,7 +1979,7 @@ async function readCursor(opts) {
1948
1979
  }
1949
1980
  }
1950
1981
  async function writeCursor(opts) {
1951
- await fs8.mkdir(inboxDir(opts.stateRoot), { recursive: true });
1982
+ await fs9.mkdir(inboxDir(opts.stateRoot), { recursive: true });
1952
1983
  const dest = cursorPath(opts.stateRoot, opts.project, opts.subscriber);
1953
1984
  const tmp = `${dest}.${process.pid}.${randomUUID()}.tmp`;
1954
1985
  const data = {
@@ -1956,7 +1987,7 @@ async function writeCursor(opts) {
1956
1987
  subscriber: opts.subscriber,
1957
1988
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1958
1989
  };
1959
- const handle = await fs8.open(tmp, "w");
1990
+ const handle = await fs9.open(tmp, "w");
1960
1991
  try {
1961
1992
  await handle.writeFile(JSON.stringify(data), { encoding: "utf-8" });
1962
1993
  await handle.sync();
@@ -1964,9 +1995,9 @@ async function writeCursor(opts) {
1964
1995
  await handle.close();
1965
1996
  }
1966
1997
  try {
1967
- await fs8.rename(tmp, dest);
1998
+ await fs9.rename(tmp, dest);
1968
1999
  } catch (e) {
1969
- await fs8.unlink(tmp).catch(() => {
2000
+ await fs9.unlink(tmp).catch(() => {
1970
2001
  });
1971
2002
  throw e;
1972
2003
  }
@@ -1977,7 +2008,7 @@ async function* readFromCursor(opts) {
1977
2008
  for (const file of files) {
1978
2009
  let buf;
1979
2010
  try {
1980
- buf = await fs8.readFile(file, "utf-8");
2011
+ buf = await fs9.readFile(file, "utf-8");
1981
2012
  } catch (e) {
1982
2013
  if (e.code === "ENOENT")
1983
2014
  continue;
@@ -2003,7 +2034,7 @@ async function mailboxStats(stateRoot, project) {
2003
2034
  let sizeBytes = 0;
2004
2035
  for (const f of [file, ...rotated]) {
2005
2036
  try {
2006
- sizeBytes += (await fs8.stat(f)).size;
2037
+ sizeBytes += (await fs9.stat(f)).size;
2007
2038
  } catch (e) {
2008
2039
  if (e.code !== "ENOENT")
2009
2040
  throw e;
@@ -2019,7 +2050,7 @@ async function mailboxStats(stateRoot, project) {
2019
2050
  }
2020
2051
  async function oldestEntryAgeMs(file) {
2021
2052
  try {
2022
- const buf = await fs8.readFile(file, "utf-8");
2053
+ const buf = await fs9.readFile(file, "utf-8");
2023
2054
  const firstLine2 = buf.split("\n").find((l) => l.trim());
2024
2055
  if (!firstLine2)
2025
2056
  return 0;
@@ -2034,7 +2065,7 @@ async function rotateIfNeeded(opts) {
2034
2065
  const file = logPath(opts.stateRoot, opts.project);
2035
2066
  let size = 0;
2036
2067
  try {
2037
- size = (await fs8.stat(file)).size;
2068
+ size = (await fs9.stat(file)).size;
2038
2069
  } catch (e) {
2039
2070
  if (e.code === "ENOENT")
2040
2071
  return { rotated: false };
@@ -2050,22 +2081,22 @@ async function rotateIfNeeded(opts) {
2050
2081
  const dst = `${file}.${n + 1}`;
2051
2082
  if (n + 1 > opts.keepCount) {
2052
2083
  try {
2053
- await fs8.unlink(src);
2084
+ await fs9.unlink(src);
2054
2085
  } catch (e) {
2055
2086
  if (e.code !== "ENOENT")
2056
2087
  throw e;
2057
2088
  }
2058
2089
  } else {
2059
2090
  try {
2060
- await fs8.rename(src, dst);
2091
+ await fs9.rename(src, dst);
2061
2092
  } catch (e) {
2062
2093
  if (e.code !== "ENOENT")
2063
2094
  throw e;
2064
2095
  }
2065
2096
  }
2066
2097
  }
2067
- await fs8.rename(file, `${file}.1`);
2068
- await fs8.writeFile(file, "", { encoding: "utf-8" });
2098
+ await fs9.rename(file, `${file}.1`);
2099
+ await fs9.writeFile(file, "", { encoding: "utf-8" });
2069
2100
  return { rotated: true, from: file, to: `${file}.1` };
2070
2101
  });
2071
2102
  }
@@ -3994,35 +4025,35 @@ var init_start = __esm({
3994
4025
 
3995
4026
  // packages/core/dist/session-freshness.js
3996
4027
  import crypto from "crypto";
3997
- import fs9 from "fs";
4028
+ import fs10 from "fs";
3998
4029
  import path8 from "path";
3999
4030
  function loadSessions(sessionsPath) {
4000
4031
  try {
4001
- return JSON.parse(fs9.readFileSync(sessionsPath, "utf-8"));
4032
+ return JSON.parse(fs10.readFileSync(sessionsPath, "utf-8"));
4002
4033
  } catch {
4003
4034
  return { workspaces: {} };
4004
4035
  }
4005
4036
  }
4006
4037
  function saveSessions(sessionsPath, sessions) {
4007
4038
  const dir = path8.dirname(sessionsPath);
4008
- fs9.mkdirSync(dir, { recursive: true });
4009
- fs9.writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2) + "\n");
4039
+ fs10.mkdirSync(dir, { recursive: true });
4040
+ fs10.writeFileSync(sessionsPath, JSON.stringify(sessions, null, 2) + "\n");
4010
4041
  }
4011
4042
  function computeTemplateHash(role, templatesDir) {
4012
4043
  const hash = crypto.createHash("sha256");
4013
4044
  const roleFile = path8.join(templatesDir, `${role}.claude.md`);
4014
4045
  const legacyRoleFile = path8.join(templatesDir, `${role}.CLAUDE.md`);
4015
- if (fs9.existsSync(roleFile)) {
4016
- hash.update(fs9.readFileSync(roleFile, "utf-8"));
4017
- } else if (fs9.existsSync(legacyRoleFile)) {
4018
- hash.update(fs9.readFileSync(legacyRoleFile, "utf-8"));
4046
+ if (fs10.existsSync(roleFile)) {
4047
+ hash.update(fs10.readFileSync(roleFile, "utf-8"));
4048
+ } else if (fs10.existsSync(legacyRoleFile)) {
4049
+ hash.update(fs10.readFileSync(legacyRoleFile, "utf-8"));
4019
4050
  }
4020
4051
  const pluginSkillsDir = path8.join(templatesDir, "..", "plugin", "skills");
4021
- if (fs9.existsSync(pluginSkillsDir)) {
4022
- for (const skill of fs9.readdirSync(pluginSkillsDir).sort()) {
4052
+ if (fs10.existsSync(pluginSkillsDir)) {
4053
+ for (const skill of fs10.readdirSync(pluginSkillsDir).sort()) {
4023
4054
  const skillFile = path8.join(pluginSkillsDir, skill, "SKILL.md");
4024
- if (fs9.existsSync(skillFile)) {
4025
- hash.update(fs9.readFileSync(skillFile, "utf-8"));
4055
+ if (fs10.existsSync(skillFile)) {
4056
+ hash.update(fs10.readFileSync(skillFile, "utf-8"));
4026
4057
  }
4027
4058
  }
4028
4059
  }
@@ -4086,6 +4117,9 @@ function shellQuote(p) {
4086
4117
  function titleFor(project, name) {
4087
4118
  return `\u{1F527} ${project}:${name}`;
4088
4119
  }
4120
+ function niceCrewCommand(cmd) {
4121
+ return `nice -n ${CREW_NICE_LEVEL} ${cmd}`;
4122
+ }
4089
4123
  function isCrewTitle(project, title) {
4090
4124
  return title.startsWith(`\u{1F527} ${project}:`);
4091
4125
  }
@@ -4104,8 +4138,10 @@ function nextAutoName(existingTitles, project) {
4104
4138
  i++;
4105
4139
  return `crew-${i}`;
4106
4140
  }
4141
+ var CREW_NICE_LEVEL;
4107
4142
  var init_crew_protocol = __esm({
4108
4143
  "packages/core/dist/crew-protocol.js"() {
4144
+ CREW_NICE_LEVEL = 10;
4109
4145
  }
4110
4146
  });
4111
4147
 
@@ -4431,7 +4467,7 @@ var init_format = __esm({
4431
4467
  });
4432
4468
 
4433
4469
  // packages/core/dist/telegram/state.js
4434
- import fs10 from "fs";
4470
+ import fs11 from "fs";
4435
4471
  import path9 from "path";
4436
4472
  function statePath(stateRoot) {
4437
4473
  return path9.join(stateRoot, "telegram-state.json");
@@ -4441,7 +4477,7 @@ function topicKey(project, scope = "project") {
4441
4477
  }
4442
4478
  function loadState(stateRoot) {
4443
4479
  try {
4444
- const raw = fs10.readFileSync(statePath(stateRoot), "utf-8");
4480
+ const raw = fs11.readFileSync(statePath(stateRoot), "utf-8");
4445
4481
  const data = JSON.parse(raw);
4446
4482
  const result = {
4447
4483
  offset: typeof data.offset === "number" ? data.offset : 0,
@@ -4456,8 +4492,8 @@ function loadState(stateRoot) {
4456
4492
  }
4457
4493
  }
4458
4494
  function saveState(stateRoot, s) {
4459
- fs10.mkdirSync(stateRoot, { recursive: true });
4460
- fs10.writeFileSync(statePath(stateRoot), JSON.stringify(s, null, 2) + "\n");
4495
+ fs11.mkdirSync(stateRoot, { recursive: true });
4496
+ fs11.writeFileSync(statePath(stateRoot), JSON.stringify(s, null, 2) + "\n");
4461
4497
  }
4462
4498
  function setTopic(stateRoot, project, topicId, scope = "project") {
4463
4499
  const s = loadState(stateRoot);
@@ -5063,7 +5099,7 @@ var init_restart_daemon = __esm({
5063
5099
  });
5064
5100
 
5065
5101
  // packages/core/dist/telegram/setup.js
5066
- import fs11 from "fs";
5102
+ import fs12 from "fs";
5067
5103
  function resolveSetupGroup(existingSupergroupId, opts) {
5068
5104
  if (existingSupergroupId !== void 0 && !opts.redetect)
5069
5105
  return "reuse";
@@ -5114,7 +5150,7 @@ function writeTelegramConfig(configPath, opts) {
5114
5150
  let config;
5115
5151
  let raw = null;
5116
5152
  try {
5117
- raw = fs11.readFileSync(configPath, "utf-8");
5153
+ raw = fs12.readFileSync(configPath, "utf-8");
5118
5154
  } catch (err) {
5119
5155
  if (err.code !== "ENOENT") {
5120
5156
  throw new Error(`refusing to overwrite unreadable config at ${configPath}: ${String(err)}`);
@@ -5142,7 +5178,7 @@ function writeTelegramConfig(configPath, opts) {
5142
5178
  if (remoteControl !== void 0)
5143
5179
  next.remoteControl = remoteControl;
5144
5180
  config.telegram = next;
5145
- fs11.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
5181
+ fs12.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
5146
5182
  }
5147
5183
  var init_setup = __esm({
5148
5184
  "packages/core/dist/telegram/setup.js"() {
@@ -5470,7 +5506,7 @@ var init_launch_workspace = __esm({
5470
5506
  });
5471
5507
 
5472
5508
  // packages/core/dist/side-session.js
5473
- import fs12 from "fs";
5509
+ import fs13 from "fs";
5474
5510
  function sideTitleFor(project, name) {
5475
5511
  return `\u{1F5D2} ${project}:${name}`;
5476
5512
  }
@@ -5572,7 +5608,7 @@ async function runSideClose(runtime, workspaceId, project, name, projPath, workt
5572
5608
  await runtime.closePane(pane);
5573
5609
  if (projPath) {
5574
5610
  const wtPath = worktreePath(projPath, worktreeDir, project, name);
5575
- if (fs12.existsSync(wtPath)) {
5611
+ if (fs13.existsSync(wtPath)) {
5576
5612
  try {
5577
5613
  removeWorktree(projPath, wtPath);
5578
5614
  } catch (e) {
@@ -5592,7 +5628,7 @@ var init_side_session = __esm({
5592
5628
  });
5593
5629
 
5594
5630
  // packages/core/dist/crew-spawn.js
5595
- import fs13 from "fs";
5631
+ import fs14 from "fs";
5596
5632
  import os5 from "os";
5597
5633
  import path11 from "path";
5598
5634
  async function listCrewPanes(runtime, workspaceId, project) {
@@ -5660,7 +5696,7 @@ async function runCrewSpawn(input, config, deps) {
5660
5696
  if (input.taskFile && input.taskFile !== "-" && !input.shared) {
5661
5697
  const absTaskFile = path11.resolve(input.taskFile);
5662
5698
  const basename = path11.basename(absTaskFile);
5663
- fs13.copyFileSync(absTaskFile, path11.join(spawnCwd, basename));
5699
+ fs14.copyFileSync(absTaskFile, path11.join(spawnCwd, basename));
5664
5700
  firstTurnTask = `Read ./${basename} to get your task brief, then execute it.`;
5665
5701
  }
5666
5702
  const route = !input.agentExplicit && !input.model ? resolveCrewRoute(input.task, config) : null;
@@ -5674,7 +5710,7 @@ async function runCrewSpawn(input, config, deps) {
5674
5710
  }
5675
5711
  if (agentName === "codex") {
5676
5712
  const codexRoleFile = path11.join(TEMPLATES_DIR, `crew.${agent.templateSuffix}.md`);
5677
- const roleInstructions = fs13.existsSync(codexRoleFile) ? fs13.readFileSync(codexRoleFile, "utf8") : void 0;
5713
+ const roleInstructions = fs14.existsSync(codexRoleFile) ? fs14.readFileSync(codexRoleFile, "utf8") : void 0;
5678
5714
  return runCodexInteractiveSpawn({
5679
5715
  project: input.project,
5680
5716
  task: input.task,
@@ -5725,7 +5761,7 @@ async function runCrewSpawn(input, config, deps) {
5725
5761
  const title2 = titleFor(input.project, name);
5726
5762
  const pane2 = await deps.runtime.newPane({ workspaceId: captain.id, direction: direction2, title: title2 });
5727
5763
  const envPrefix = `SQUADRANT_CREW_TASK_ID=${rec.id} SQUADRANT_CREW_PROJECT=${input.project}`;
5728
- await deps.runtime.sendToPane(pane2, `cd ${shellQuote(spawnCwd)} && ${envPrefix} ${cliCommand2}`);
5764
+ await deps.runtime.sendToPane(pane2, `cd ${shellQuote(spawnCwd)} && ${envPrefix} ${niceCrewCommand(cliCommand2)}`);
5729
5765
  const preLaunchScreen = await deps.runtime.readPaneScreen(pane2) ?? "";
5730
5766
  const claudeResult = await deps.sendFirstTurn(pane2, `${firstTurnTask}
5731
5767
 
@@ -5773,7 +5809,7 @@ ${buildCompletionProtocol(rec.id, input.project)}`, preLaunchScreen);
5773
5809
  const title2 = titleFor(input.project, name);
5774
5810
  const pane2 = await deps.runtime.newPane({ workspaceId: captain.id, direction: direction2, title: title2 });
5775
5811
  const envPrefix = `SQUADRANT_CREW_TASK_ID=${rec.id} SQUADRANT_CREW_PROJECT=${input.project}`;
5776
- await deps.runtime.sendToPane(pane2, `cd ${shellQuote(spawnCwd)} && ${envPrefix} OPENCODE_CONFIG=${opencodeConfigPath} ${cliCommand2}`);
5812
+ await deps.runtime.sendToPane(pane2, `cd ${shellQuote(spawnCwd)} && ${envPrefix} OPENCODE_CONFIG=${opencodeConfigPath} ${niceCrewCommand(cliCommand2)}`);
5777
5813
  const preLaunchScreen = await deps.runtime.readPaneScreen(pane2) ?? "";
5778
5814
  const opencodeResult = await deps.sendFirstTurn(pane2, `${firstTurnTask}
5779
5815
 
@@ -5808,7 +5844,7 @@ ${buildCompletionProtocol(rec.id, input.project)}`, preLaunchScreen, {
5808
5844
  const direction = input.direction ?? "tab";
5809
5845
  const title = titleFor(input.project, name);
5810
5846
  const pane = await deps.runtime.newPane({ workspaceId: captain.id, direction, title });
5811
- await deps.runtime.sendToPane(pane, cliCommand);
5847
+ await deps.runtime.sendToPane(pane, niceCrewCommand(cliCommand));
5812
5848
  if (interactive) {
5813
5849
  const preLaunchScreen = await deps.runtime.readPaneScreen(pane) ?? "";
5814
5850
  const genericResult = await deps.sendFirstTurn(pane, firstTurnTask, preLaunchScreen);
@@ -6040,6 +6076,7 @@ __export(dist_exports2, {
6040
6076
  maskToken: () => maskToken,
6041
6077
  nameFromTitle: () => nameFromTitle,
6042
6078
  nextAutoName: () => nextAutoName,
6079
+ niceCrewCommand: () => niceCrewCommand,
6043
6080
  notifyToggle: () => notifyToggle,
6044
6081
  parseCommand: () => parseCommand,
6045
6082
  parseNotifyPref: () => parseNotifyPref,
@@ -6745,7 +6782,7 @@ var init_notifiers = __esm({
6745
6782
  });
6746
6783
 
6747
6784
  // packages/workspaces/dist/workspaces/obsidian.js
6748
- import fs14 from "fs/promises";
6785
+ import fs15 from "fs/promises";
6749
6786
  import { existsSync as existsSync9 } from "fs";
6750
6787
  import path12 from "path";
6751
6788
  function resolveInRoot(root, relative) {
@@ -6770,16 +6807,16 @@ function createObsidianDriver(scope) {
6770
6807
  };
6771
6808
  },
6772
6809
  async read(rel) {
6773
- return fs14.readFile(resolveInRoot(root, rel), "utf-8");
6810
+ return fs15.readFile(resolveInRoot(root, rel), "utf-8");
6774
6811
  },
6775
6812
  async write(rel, content) {
6776
6813
  const abs = resolveInRoot(root, rel);
6777
- await fs14.mkdir(path12.dirname(abs), { recursive: true });
6778
- await fs14.writeFile(abs, content);
6814
+ await fs15.mkdir(path12.dirname(abs), { recursive: true });
6815
+ await fs15.writeFile(abs, content);
6779
6816
  },
6780
6817
  async exists(rel) {
6781
6818
  try {
6782
- await fs14.access(resolveInRoot(root, rel));
6819
+ await fs15.access(resolveInRoot(root, rel));
6783
6820
  return true;
6784
6821
  } catch {
6785
6822
  return false;
@@ -6787,13 +6824,13 @@ function createObsidianDriver(scope) {
6787
6824
  },
6788
6825
  async list(rel) {
6789
6826
  try {
6790
- return await fs14.readdir(resolveInRoot(root, rel));
6827
+ return await fs15.readdir(resolveInRoot(root, rel));
6791
6828
  } catch {
6792
6829
  return [];
6793
6830
  }
6794
6831
  },
6795
6832
  async mkdir(rel) {
6796
- await fs14.mkdir(resolveInRoot(root, rel), { recursive: true });
6833
+ await fs15.mkdir(resolveInRoot(root, rel), { recursive: true });
6797
6834
  }
6798
6835
  };
6799
6836
  }
@@ -8018,7 +8055,7 @@ var init_registry4 = __esm({
8018
8055
  });
8019
8056
 
8020
8057
  // packages/agents/dist/drivers/launch-cmd.js
8021
- import fs15 from "fs";
8058
+ import fs16 from "fs";
8022
8059
  import path13 from "path";
8023
8060
  function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model, templatesDir) {
8024
8061
  const driver = registry.getDriver(agentName);
@@ -8037,12 +8074,12 @@ function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model,
8037
8074
  if (templatesDir) {
8038
8075
  const roleFile2 = path13.join(templatesDir, `${role}.claude.md`);
8039
8076
  const legacyRoleFile = path13.join(templatesDir, `${role}.CLAUDE.md`);
8040
- const actualRoleFile = fs15.existsSync(roleFile2) ? roleFile2 : fs15.existsSync(legacyRoleFile) ? legacyRoleFile : null;
8077
+ const actualRoleFile = fs16.existsSync(roleFile2) ? roleFile2 : fs16.existsSync(legacyRoleFile) ? legacyRoleFile : null;
8041
8078
  if (actualRoleFile) {
8042
8079
  cmd += ` --append-system-prompt-file ${actualRoleFile}`;
8043
8080
  }
8044
8081
  const pluginDir = path13.join(templatesDir, "..", "plugin");
8045
- if (fs15.existsSync(pluginDir)) {
8082
+ if (fs16.existsSync(pluginDir)) {
8046
8083
  cmd += ` --plugin-dir ${pluginDir}`;
8047
8084
  }
8048
8085
  }
@@ -8055,7 +8092,7 @@ function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model,
8055
8092
  role,
8056
8093
  model,
8057
8094
  autoApprove: true,
8058
- promptFile: roleFile && fs15.existsSync(roleFile) ? roleFile : void 0
8095
+ promptFile: roleFile && fs16.existsSync(roleFile) ? roleFile : void 0
8059
8096
  });
8060
8097
  }
8061
8098
  var init_launch_cmd = __esm({
@@ -9819,7 +9856,7 @@ init_dist();
9819
9856
  init_dist3();
9820
9857
  import { Command } from "commander";
9821
9858
  import { execSync as execSync8 } from "child_process";
9822
- import fs16 from "fs";
9859
+ import fs17 from "fs";
9823
9860
  import { stat } from "fs/promises";
9824
9861
  import path18 from "path";
9825
9862
  import chalk3 from "chalk";
@@ -9924,7 +9961,7 @@ function settingsHaveAgentTeams() {
9924
9961
  try {
9925
9962
  const home = process.env.HOME || "";
9926
9963
  const settings = JSON.parse(
9927
- fs16.readFileSync(`${home}/.claude/settings.json`, "utf-8")
9964
+ fs17.readFileSync(`${home}/.claude/settings.json`, "utf-8")
9928
9965
  );
9929
9966
  return settings?.env?.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1";
9930
9967
  } catch {
@@ -9935,7 +9972,7 @@ function pluginInstalled(pluginKey) {
9935
9972
  try {
9936
9973
  const home = process.env.HOME || "";
9937
9974
  const plugins = JSON.parse(
9938
- fs16.readFileSync(
9975
+ fs17.readFileSync(
9939
9976
  `${home}/.claude/plugins/installed_plugins.json`,
9940
9977
  "utf-8"
9941
9978
  )
@@ -9980,7 +10017,7 @@ var doctorCommand = new Command("doctor").description("Check system health and p
9980
10017
  ));
9981
10018
  results.push(check(
9982
10019
  "Obsidian installed",
9983
- commandExists("obsidian") || fs16.existsSync("/Applications/Obsidian.app"),
10020
+ commandExists("obsidian") || fs17.existsSync("/Applications/Obsidian.app"),
9984
10021
  "Install from: https://obsidian.md"
9985
10022
  ));
9986
10023
  results.push(check(
@@ -10087,7 +10124,7 @@ var doctorCommand = new Command("doctor").description("Check system health and p
10087
10124
  results.push(
10088
10125
  check(
10089
10126
  "Squadrant config exists",
10090
- fs16.existsSync(
10127
+ fs17.existsSync(
10091
10128
  process.env.SQUADRANT_CONFIG || `${process.env.HOME}/.config/squadrant/config.json`
10092
10129
  ),
10093
10130
  "Run: squadrant init"
@@ -10161,7 +10198,7 @@ init_dist();
10161
10198
  init_dist3();
10162
10199
  init_dist();
10163
10200
  import { Command as Command2 } from "commander";
10164
- import fs17 from "fs";
10201
+ import fs18 from "fs";
10165
10202
  import path19 from "path";
10166
10203
  import os10 from "os";
10167
10204
  import readline from "readline";
@@ -10318,20 +10355,20 @@ init_dist4();
10318
10355
  function findPackageRoot() {
10319
10356
  let dir = path19.dirname(new URL(import.meta.url).pathname);
10320
10357
  while (dir !== "/") {
10321
- if (fs17.existsSync(path19.join(dir, "package.json"))) return dir;
10358
+ if (fs18.existsSync(path19.join(dir, "package.json"))) return dir;
10322
10359
  dir = path19.dirname(dir);
10323
10360
  }
10324
10361
  return process.cwd();
10325
10362
  }
10326
10363
  function copyDirRecursive(src, dest) {
10327
- fs17.mkdirSync(dest, { recursive: true });
10328
- for (const entry of fs17.readdirSync(src, { withFileTypes: true })) {
10364
+ fs18.mkdirSync(dest, { recursive: true });
10365
+ for (const entry of fs18.readdirSync(src, { withFileTypes: true })) {
10329
10366
  const srcPath = path19.join(src, entry.name);
10330
10367
  const destPath = path19.join(dest, entry.name);
10331
10368
  if (entry.isDirectory()) {
10332
10369
  copyDirRecursive(srcPath, destPath);
10333
10370
  } else {
10334
- fs17.copyFileSync(srcPath, destPath);
10371
+ fs18.copyFileSync(srcPath, destPath);
10335
10372
  }
10336
10373
  }
10337
10374
  }
@@ -10377,8 +10414,8 @@ var initCommand = new Command2("init").description("Guided first-time setup: hub
10377
10414
  }
10378
10415
  const wsRegistry = new WorkspaceRegistry({ obsidian: createObsidianDriver });
10379
10416
  try {
10380
- if (fs17.existsSync(DEFAULT_CONFIG_PATH)) {
10381
- const existing = JSON.parse(fs17.readFileSync(DEFAULT_CONFIG_PATH, "utf-8"));
10417
+ if (fs18.existsSync(DEFAULT_CONFIG_PATH)) {
10418
+ const existing = JSON.parse(fs18.readFileSync(DEFAULT_CONFIG_PATH, "utf-8"));
10382
10419
  wsRegistry.get(existing.workspace ?? "obsidian");
10383
10420
  }
10384
10421
  } catch (err) {
@@ -10386,7 +10423,7 @@ var initCommand = new Command2("init").description("Guided first-time setup: hub
10386
10423
  return;
10387
10424
  }
10388
10425
  stepHeader(1, 5, "Hub vault");
10389
- if (fs17.existsSync(DEFAULT_CONFIG_PATH)) {
10426
+ if (fs18.existsSync(DEFAULT_CONFIG_PATH)) {
10390
10427
  console.log(chalk4.yellow(" \u26A0 Config already exists, skipping creation"));
10391
10428
  } else {
10392
10429
  const config = getDefaultConfig();
@@ -10395,36 +10432,36 @@ var initCommand = new Command2("init").description("Guided first-time setup: hub
10395
10432
  console.log(chalk4.green(` \u2714 Config created at ${DEFAULT_CONFIG_PATH}`));
10396
10433
  }
10397
10434
  const hubTemplate = path19.join(pkgRoot, "obsidian", "hub");
10398
- if (fs17.existsSync(hubPath)) {
10435
+ if (fs18.existsSync(hubPath)) {
10399
10436
  console.log(chalk4.yellow(` \u26A0 Hub vault already exists at ${hubPath}`));
10400
- } else if (fs17.existsSync(hubTemplate)) {
10437
+ } else if (fs18.existsSync(hubTemplate)) {
10401
10438
  copyDirRecursive(hubTemplate, hubPath);
10402
10439
  console.log(chalk4.green(` \u2714 Hub vault scaffolded at ${hubPath}`));
10403
10440
  } else {
10404
- fs17.mkdirSync(hubPath, { recursive: true });
10441
+ fs18.mkdirSync(hubPath, { recursive: true });
10405
10442
  console.log(chalk4.yellow(` \u26A0 Hub template not found; created empty directory at ${hubPath}`));
10406
10443
  }
10407
10444
  const hubDashboardSrc = path19.join(pkgRoot, "obsidian", "hub", "dashboard.md");
10408
10445
  const hubDashboardDest = path19.join(hubPath, "dashboard.md");
10409
- if (fs17.existsSync(hubDashboardSrc)) {
10410
- fs17.copyFileSync(hubDashboardSrc, hubDashboardDest);
10446
+ if (fs18.existsSync(hubDashboardSrc)) {
10447
+ fs18.copyFileSync(hubDashboardSrc, hubDashboardDest);
10411
10448
  console.log(chalk4.green(` \u2714 Dashboard refreshed`));
10412
10449
  }
10413
- fs17.mkdirSync(path19.join(hubPath, "projects"), { recursive: true });
10450
+ fs18.mkdirSync(path19.join(hubPath, "projects"), { recursive: true });
10414
10451
  ensureRuntimeSynced({ sourceRoot: pkgRoot, runtimeRoot: configDir });
10415
10452
  console.log(chalk4.green(` \u2714 Runtime assets synced to ${configDir}`));
10416
10453
  stepHeader(2, 5, "Agent + projection setup");
10417
10454
  const settingsPath = path19.join(os10.homedir(), ".claude", "settings.json");
10418
10455
  try {
10419
10456
  let settings = {};
10420
- if (fs17.existsSync(settingsPath)) {
10421
- settings = JSON.parse(fs17.readFileSync(settingsPath, "utf-8"));
10457
+ if (fs18.existsSync(settingsPath)) {
10458
+ settings = JSON.parse(fs18.readFileSync(settingsPath, "utf-8"));
10422
10459
  }
10423
10460
  const env = settings.env || {};
10424
10461
  if (env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS !== "1") {
10425
10462
  settings.env = { ...env, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" };
10426
- fs17.mkdirSync(path19.dirname(settingsPath), { recursive: true });
10427
- fs17.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
10463
+ fs18.mkdirSync(path19.dirname(settingsPath), { recursive: true });
10464
+ fs18.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
10428
10465
  console.log(chalk4.green(" \u2714 Agent Teams enabled in ~/.claude/settings.json"));
10429
10466
  } else {
10430
10467
  console.log(chalk4.green(" \u2714 Agent Teams already enabled"));
@@ -10504,7 +10541,7 @@ var initCommand = new Command2("init").description("Guided first-time setup: hub
10504
10541
  init_dist();
10505
10542
  init_dist2();
10506
10543
  import { Command as Command3 } from "commander";
10507
- import fs18 from "fs";
10544
+ import fs19 from "fs";
10508
10545
  import path20 from "path";
10509
10546
  import chalk5 from "chalk";
10510
10547
  function restartAfterProjectsAdd(opts) {
@@ -10519,20 +10556,20 @@ function restartAfterProjectsAdd(opts) {
10519
10556
  function findPackageRoot2() {
10520
10557
  let dir = path20.dirname(new URL(import.meta.url).pathname);
10521
10558
  while (dir !== "/") {
10522
- if (fs18.existsSync(path20.join(dir, "package.json"))) return dir;
10559
+ if (fs19.existsSync(path20.join(dir, "package.json"))) return dir;
10523
10560
  dir = path20.dirname(dir);
10524
10561
  }
10525
10562
  return process.cwd();
10526
10563
  }
10527
10564
  function copyDirRecursive2(src, dest) {
10528
- fs18.mkdirSync(dest, { recursive: true });
10529
- for (const entry of fs18.readdirSync(src, { withFileTypes: true })) {
10565
+ fs19.mkdirSync(dest, { recursive: true });
10566
+ for (const entry of fs19.readdirSync(src, { withFileTypes: true })) {
10530
10567
  const srcPath = path20.join(src, entry.name);
10531
10568
  const destPath = path20.join(dest, entry.name);
10532
10569
  if (entry.isDirectory()) {
10533
10570
  copyDirRecursive2(srcPath, destPath);
10534
10571
  } else {
10535
- fs18.copyFileSync(srcPath, destPath);
10572
+ fs19.copyFileSync(srcPath, destPath);
10536
10573
  }
10537
10574
  }
10538
10575
  }
@@ -10568,7 +10605,7 @@ var addCmd = new Command3("add").description("Register a project").argument("<na
10568
10605
  process.exit(1);
10569
10606
  }
10570
10607
  const resolvedPath = resolveHome(projectPath);
10571
- if (!fs18.existsSync(path20.join(resolvedPath, ".git"))) {
10608
+ if (!fs19.existsSync(path20.join(resolvedPath, ".git"))) {
10572
10609
  console.log(chalk5.yellow(`
10573
10610
  \u26A0 No .git found at ${resolvedPath}. Make sure this is the project root, not a parent directory.
10574
10611
  `));
@@ -10637,19 +10674,19 @@ var addCmd = new Command3("add").description("Register a project").argument("<na
10637
10674
  restartAfterProjectsAdd({ noRestart: opts.restart === false });
10638
10675
  const pkgRoot = findPackageRoot2();
10639
10676
  const spokeTemplate = path20.join(pkgRoot, "obsidian", "spoke");
10640
- if (fs18.existsSync(spokeVault)) {
10677
+ if (fs19.existsSync(spokeVault)) {
10641
10678
  console.log(chalk5.yellow(` \u26A0 Spoke vault already exists at ${spokeVault}, skipping scaffold`));
10642
- } else if (fs18.existsSync(spokeTemplate)) {
10679
+ } else if (fs19.existsSync(spokeTemplate)) {
10643
10680
  copyDirRecursive2(spokeTemplate, spokeVault);
10644
10681
  const statusPath = path20.join(spokeVault, "status.md");
10645
- if (fs18.existsSync(statusPath)) {
10646
- const content = fs18.readFileSync(statusPath, "utf-8");
10682
+ if (fs19.existsSync(statusPath)) {
10683
+ const content = fs19.readFileSync(statusPath, "utf-8");
10647
10684
  const updated = content.replace(/^project: unnamed/m, `project: ${name}`);
10648
- fs18.writeFileSync(statusPath, updated);
10685
+ fs19.writeFileSync(statusPath, updated);
10649
10686
  }
10650
10687
  console.log(chalk5.green(` \u2714 Spoke vault scaffolded at ${spokeVault}`));
10651
10688
  } else {
10652
- fs18.mkdirSync(spokeVault, { recursive: true });
10689
+ fs19.mkdirSync(spokeVault, { recursive: true });
10653
10690
  console.log(chalk5.yellow(` \u26A0 Spoke template not found; created empty dir at ${spokeVault}`));
10654
10691
  }
10655
10692
  console.log("");
@@ -11506,7 +11543,7 @@ init_dist3();
11506
11543
  init_dist();
11507
11544
  init_dist2();
11508
11545
  import { Command as Command10 } from "commander";
11509
- import fs19 from "fs";
11546
+ import fs20 from "fs";
11510
11547
  import path22 from "path";
11511
11548
  import os12 from "os";
11512
11549
  import chalk10 from "chalk";
@@ -11542,7 +11579,7 @@ async function runSideSpawn2(input) {
11542
11579
  prompt: input.topic,
11543
11580
  workdir: spawnCwd,
11544
11581
  role: "side",
11545
- promptFile: fs19.existsSync(promptFile) ? promptFile : void 0,
11582
+ promptFile: fs20.existsSync(promptFile) ? promptFile : void 0,
11546
11583
  interactive: true,
11547
11584
  permissionMode: config.defaults.permissions?.crew ?? "auto",
11548
11585
  ...sideModel ? { model: sideModel } : {}
@@ -11806,7 +11843,7 @@ function renderDashboard(rows, opts) {
11806
11843
 
11807
11844
  // packages/web/dist/sync-hub.js
11808
11845
  init_dist();
11809
- import fs20 from "fs";
11846
+ import fs21 from "fs";
11810
11847
  import path23 from "path";
11811
11848
  function buildMirrorMarkdown(s) {
11812
11849
  const fenced = "```";
@@ -11833,8 +11870,8 @@ function buildMirrorMarkdown(s) {
11833
11870
  function syncHub(deps) {
11834
11871
  if (!deps.config.hubVault)
11835
11872
  return [];
11836
- const writeFile5 = deps.writeFile ?? ((p, c) => fs20.writeFileSync(p, c));
11837
- const mkdir5 = deps.mkdir ?? ((p) => fs20.mkdirSync(p, { recursive: true }));
11873
+ const writeFile5 = deps.writeFile ?? ((p, c) => fs21.writeFileSync(p, c));
11874
+ const mkdir5 = deps.mkdir ?? ((p) => fs21.mkdirSync(p, { recursive: true }));
11838
11875
  const projectsDir = path23.join(resolveHome(deps.config.hubVault), "projects");
11839
11876
  mkdir5(projectsDir);
11840
11877
  const out = [];
@@ -12966,7 +13003,7 @@ init_dist3();
12966
13003
  init_dist2();
12967
13004
  import { Command as Command12 } from "commander";
12968
13005
  import { execSync as execSync11 } from "child_process";
12969
- import fs21 from "fs";
13006
+ import fs22 from "fs";
12970
13007
  import path24 from "path";
12971
13008
  import os13 from "os";
12972
13009
  import chalk13 from "chalk";
@@ -13119,12 +13156,12 @@ var launchCommand = new Command12("launch").description(
13119
13156
  }
13120
13157
  if (opts.all) {
13121
13158
  const hubPath = resolveHome(config.hubVault);
13122
- fs21.mkdirSync(hubPath, { recursive: true });
13159
+ fs22.mkdirSync(hubPath, { recursive: true });
13123
13160
  console.log(chalk13.bold("\nLaunching all captain workspaces\n"));
13124
13161
  for (const [name, proj] of Object.entries(config.projects)) {
13125
13162
  const projPath = resolveHome(proj.path);
13126
13163
  const spokePath = resolveHome(proj.spokeVault);
13127
- if (!fs21.existsSync(spokePath)) {
13164
+ if (!fs22.existsSync(spokePath)) {
13128
13165
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(name, config);
13129
13166
  await ensureSpokeLayout(spokeDriver);
13130
13167
  console.log(chalk13.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -13162,7 +13199,7 @@ Launching ${selected.length} captain workspace(s) in parallel
13162
13199
  const proj = config.projects[name];
13163
13200
  const projPath = resolveHome(proj.path);
13164
13201
  const spokePath = resolveHome(proj.spokeVault);
13165
- if (!fs21.existsSync(spokePath)) {
13202
+ if (!fs22.existsSync(spokePath)) {
13166
13203
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(name, config);
13167
13204
  await ensureSpokeLayout(spokeDriver);
13168
13205
  console.log(chalk13.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -13186,7 +13223,7 @@ Launching ${selected.length} captain workspace(s) in parallel
13186
13223
  const proj = config.projects[project];
13187
13224
  const projPath = resolveHome(proj.path);
13188
13225
  const spokePath = resolveHome(proj.spokeVault);
13189
- if (!fs21.existsSync(spokePath)) {
13226
+ if (!fs22.existsSync(spokePath)) {
13190
13227
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(project, config);
13191
13228
  await ensureSpokeLayout(spokeDriver);
13192
13229
  console.log(chalk13.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -13322,7 +13359,7 @@ Shutting down captain workspace for '${project}'...
13322
13359
  // packages/cli/src/commands/feedback.ts
13323
13360
  init_dist();
13324
13361
  import { Command as Command14 } from "commander";
13325
- import fs22 from "fs";
13362
+ import fs23 from "fs";
13326
13363
  import os14 from "os";
13327
13364
  import path25 from "path";
13328
13365
  import { fileURLToPath as fileURLToPath3 } from "url";
@@ -13332,14 +13369,14 @@ var REPO_URL = "https://github.com/tu11aa/squadrant";
13332
13369
  function readPkgVersion() {
13333
13370
  try {
13334
13371
  const pkgPath = path25.join(path25.dirname(fileURLToPath3(import.meta.url)), "..", "package.json");
13335
- return JSON.parse(fs22.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
13372
+ return JSON.parse(fs23.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
13336
13373
  } catch {
13337
13374
  return "unknown";
13338
13375
  }
13339
13376
  }
13340
13377
  function readMetrics(metricsPath) {
13341
13378
  try {
13342
- return JSON.parse(fs22.readFileSync(metricsPath, "utf-8"));
13379
+ return JSON.parse(fs23.readFileSync(metricsPath, "utf-8"));
13343
13380
  } catch {
13344
13381
  return {};
13345
13382
  }
@@ -13399,7 +13436,7 @@ init_dist();
13399
13436
  init_dist();
13400
13437
  init_dist3();
13401
13438
  import { Command as Command15 } from "commander";
13402
- import fs23 from "fs";
13439
+ import fs24 from "fs";
13403
13440
  import path26 from "path";
13404
13441
  import chalk16 from "chalk";
13405
13442
  import matter3 from "gray-matter";
@@ -13411,9 +13448,9 @@ async function getProjectStandup(name, project, dateStr, registry, config) {
13411
13448
  const spokeVault = resolveHome(project.spokeVault);
13412
13449
  const statusFile = path26.join(spokeVault, "status.md");
13413
13450
  let status = {};
13414
- if (fs23.existsSync(statusFile)) {
13451
+ if (fs24.existsSync(statusFile)) {
13415
13452
  try {
13416
- status = matter3(fs23.readFileSync(statusFile, "utf-8")).data;
13453
+ status = matter3(fs24.readFileSync(statusFile, "utf-8")).data;
13417
13454
  } catch {
13418
13455
  }
13419
13456
  }
@@ -13531,15 +13568,15 @@ init_dist();
13531
13568
  init_dist();
13532
13569
  init_dist3();
13533
13570
  import { Command as Command16 } from "commander";
13534
- import fs24 from "fs";
13571
+ import fs25 from "fs";
13535
13572
  import path27 from "path";
13536
13573
  import chalk17 from "chalk";
13537
13574
  import matter4 from "gray-matter";
13538
13575
  function readStatus(spokeVault) {
13539
13576
  const statusFile = path27.join(spokeVault, "status.md");
13540
- if (!fs24.existsSync(statusFile)) return {};
13577
+ if (!fs25.existsSync(statusFile)) return {};
13541
13578
  try {
13542
- return matter4(fs24.readFileSync(statusFile, "utf-8")).data;
13579
+ return matter4(fs25.readFileSync(statusFile, "utf-8")).data;
13543
13580
  } catch {
13544
13581
  return {};
13545
13582
  }
@@ -13956,7 +13993,7 @@ init_dist3();
13956
13993
  init_dist();
13957
13994
  import { Command as Command20 } from "commander";
13958
13995
  import chalk21 from "chalk";
13959
- import fs25 from "fs";
13996
+ import fs26 from "fs";
13960
13997
  import path28 from "path";
13961
13998
  import { fileURLToPath as fileURLToPath4 } from "url";
13962
13999
  function parseScope(v) {
@@ -13968,7 +14005,7 @@ function parseScope(v) {
13968
14005
  function findPackageRoot3() {
13969
14006
  let dir = path28.dirname(fileURLToPath4(import.meta.url));
13970
14007
  while (dir !== "/" && dir !== "") {
13971
- if (fs25.existsSync(path28.join(dir, "package.json"))) return dir;
14008
+ if (fs26.existsSync(path28.join(dir, "package.json"))) return dir;
13972
14009
  dir = path28.dirname(dir);
13973
14010
  }
13974
14011
  return process.cwd();
@@ -14164,12 +14201,12 @@ init_dist();
14164
14201
  init_dist();
14165
14202
  init_dist2();
14166
14203
  import { Command as Command22 } from "commander";
14167
- import fs26 from "fs";
14204
+ import fs27 from "fs";
14168
14205
  import { fileURLToPath as fileURLToPath5 } from "url";
14169
14206
  import { dirname as dirname6, join as join25 } from "path";
14170
14207
  import chalk22 from "chalk";
14171
14208
  function runConfigCheck(opts) {
14172
- const raw = JSON.parse(fs26.readFileSync(opts.configPath, "utf-8"));
14209
+ const raw = JSON.parse(fs27.readFileSync(opts.configPath, "utf-8"));
14173
14210
  const def = getDefaultConfig();
14174
14211
  const items = detectDrift(raw, def);
14175
14212
  let working = raw;
@@ -14186,7 +14223,7 @@ function runConfigCheck(opts) {
14186
14223
  stamped = true;
14187
14224
  }
14188
14225
  if (opts.fix || opts.accept || stamped) {
14189
- fs26.writeFileSync(opts.configPath, JSON.stringify(working, null, 2) + "\n");
14226
+ fs27.writeFileSync(opts.configPath, JSON.stringify(working, null, 2) + "\n");
14190
14227
  }
14191
14228
  return { items, applied, remaining, stamped };
14192
14229
  }
@@ -14257,7 +14294,7 @@ function printItems(items) {
14257
14294
  var configCommand = new Command22("config").description("Inspect and reconcile squadrant config");
14258
14295
  configCommand.command("check").description("Detect config drift vs the current default schema").option("--fix", "Apply the safe tier (add missing, remove deprecated)", false).option("--accept", "Stamp the current version without changing config (dismiss advisories)", false).option("--json", "Output drift items as JSON", false).action((opts) => {
14259
14296
  const pkgVersion = readPkgVersion2();
14260
- if (!fs26.existsSync(DEFAULT_CONFIG_PATH)) {
14297
+ if (!fs27.existsSync(DEFAULT_CONFIG_PATH)) {
14261
14298
  console.log(chalk22.yellow("No config found \u2014 run `squadrant init` first."));
14262
14299
  return;
14263
14300
  }
@@ -14303,7 +14340,7 @@ configCommand.command("set").description("Write a config value by dotted key (e.
14303
14340
  });
14304
14341
  function readPkgVersion2() {
14305
14342
  const pkgPath = join25(dirname6(fileURLToPath5(import.meta.url)), "..", "package.json");
14306
- return JSON.parse(fs26.readFileSync(pkgPath, "utf-8")).version;
14343
+ return JSON.parse(fs27.readFileSync(pkgPath, "utf-8")).version;
14307
14344
  }
14308
14345
 
14309
14346
  // packages/cli/src/commands/heal.ts
@@ -14543,7 +14580,7 @@ var cmuxCommand = new Command27("cmux").description("cmux integration helpers").
14543
14580
  // packages/cli/src/commands/effort.ts
14544
14581
  init_dist();
14545
14582
  init_dist2();
14546
- import fs27 from "fs";
14583
+ import fs28 from "fs";
14547
14584
  import path29 from "path";
14548
14585
  import { Command as Command28 } from "commander";
14549
14586
  import chalk28 from "chalk";
@@ -14571,7 +14608,7 @@ function runEffortSet(value, configPath = DEFAULT_CONFIG_PATH) {
14571
14608
  }
14572
14609
  function canonical(p) {
14573
14610
  try {
14574
- return fs27.realpathSync(p);
14611
+ return fs28.realpathSync(p);
14575
14612
  } catch {
14576
14613
  return path29.resolve(p);
14577
14614
  }