squadrant 0.26.1 → 0.26.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
@@ -594,22 +594,22 @@ function defaultCmuxConfigPath() {
594
594
  return join(homedir(), ".config", "cmux", "cmux.json");
595
595
  }
596
596
  function ensureSocketAutomation(opts = {}) {
597
- const path45 = opts.path ?? defaultCmuxConfigPath();
598
- if (!existsSync(path45)) {
599
- mkdirSync(dirname(path45), { recursive: true });
600
- writeFileSync(path45, MINIMAL_TEMPLATE);
601
- return { path: path45, changed: true, alreadySet: false };
597
+ const path46 = opts.path ?? defaultCmuxConfigPath();
598
+ if (!existsSync(path46)) {
599
+ mkdirSync(dirname(path46), { recursive: true });
600
+ writeFileSync(path46, MINIMAL_TEMPLATE);
601
+ return { path: path46, changed: true, alreadySet: false };
602
602
  }
603
- const text = readFileSync(path45, "utf-8");
603
+ const text = readFileSync(path46, "utf-8");
604
604
  const current = parse(text)?.automation?.socketControlMode;
605
605
  if (current === AUTOMATION_MODE) {
606
- return { path: path45, changed: false, alreadySet: true };
606
+ return { path: path46, changed: false, alreadySet: true };
607
607
  }
608
608
  const edits = modify(text, [...SOCKET_CONTROL_MODE_PATH], AUTOMATION_MODE, {
609
609
  formattingOptions: { insertSpaces: true, tabSize: 2 }
610
610
  });
611
- writeFileSync(path45, applyEdits(text, edits));
612
- return { path: path45, changed: true, alreadySet: false };
611
+ writeFileSync(path46, applyEdits(text, edits));
612
+ return { path: path46, changed: true, alreadySet: false };
613
613
  }
614
614
  var SOCKET_CONTROL_MODE_PATH, AUTOMATION_MODE, MINIMAL_TEMPLATE;
615
615
  var init_cmux_config = __esm({
@@ -762,9 +762,9 @@ import { join as join4 } from "path";
762
762
  function defaultStatePath() {
763
763
  return join4(homedir3(), ".config", "squadrant", "state", "cmux-autoconfig.json");
764
764
  }
765
- function readState(path45) {
765
+ function readState(path46) {
766
766
  try {
767
- return JSON.parse(readConfigFileSync(path45));
767
+ return JSON.parse(readConfigFileSync(path46));
768
768
  } catch {
769
769
  return {};
770
770
  }
@@ -925,18 +925,18 @@ function detectDrift(user, def) {
925
925
  }
926
926
  }
927
927
  }
928
- const checkBackend = (path45, backend, agentName) => {
928
+ const checkBackend = (path46, backend, agentName) => {
929
929
  if (backend === void 0)
930
930
  return;
931
931
  if (!isBackendMode(backend)) {
932
- items.push({ path: path45, kind: "invalid", severity: "warn", current: backend, note: "unknown backend; expected native|direct|proxy" });
932
+ items.push({ path: path46, kind: "invalid", severity: "warn", current: backend, note: "unknown backend; expected native|direct|proxy" });
933
933
  return;
934
934
  }
935
935
  if (backend !== "native") {
936
936
  if (agentName !== "claude") {
937
- items.push({ path: path45, kind: "invalid", severity: "warn", current: backend, note: `backend '${backend}' is claude-only (agent '${agentName ?? "?"}')` });
937
+ items.push({ path: path46, kind: "invalid", severity: "warn", current: backend, note: `backend '${backend}' is claude-only (agent '${agentName ?? "?"}')` });
938
938
  } else if (!router) {
939
- items.push({ path: path45, kind: "invalid", severity: "warn", current: backend, note: `backend '${backend}' requires defaults.router` });
939
+ items.push({ path: path46, kind: "invalid", severity: "warn", current: backend, note: `backend '${backend}' requires defaults.router` });
940
940
  }
941
941
  }
942
942
  };
@@ -1124,8 +1124,8 @@ async function notifyIfUpdateAvailable(opts) {
1124
1124
  const statePath2 = opts.statePath ?? UPDATE_CHECK_STATE_PATH;
1125
1125
  const readState2 = opts.readState ?? readUpdateCheckState;
1126
1126
  const writeState = opts.writeState ?? writeUpdateCheckState;
1127
- const write = opts.write ?? ((line) => process.stderr.write(`
1128
- ${line}
1127
+ const write = opts.write ?? ((line2) => process.stderr.write(`
1128
+ ${line2}
1129
1129
  `));
1130
1130
  const outcome = await checkForUpdate({
1131
1131
  currentVersion: opts.currentVersion,
@@ -1480,8 +1480,8 @@ function parseSkill(raw) {
1480
1480
  return null;
1481
1481
  const [, fmBlock, body] = match;
1482
1482
  const fm = {};
1483
- for (const line of fmBlock.split("\n")) {
1484
- const kv = line.match(/^(\w+):\s*(.+)$/);
1483
+ for (const line2 of fmBlock.split("\n")) {
1484
+ const kv = line2.match(/^(\w+):\s*(.+)$/);
1485
1485
  if (kv)
1486
1486
  fm[kv[1]] = kv[2].trim();
1487
1487
  }
@@ -1595,8 +1595,8 @@ async function readDailyLog(workspace, dateStr) {
1595
1595
  const blockerMatch = content.match(/## Blocked\n([\s\S]*?)(?=\n##|$)/);
1596
1596
  if (blockerMatch) {
1597
1597
  const lines = blockerMatch[1].trim().split("\n");
1598
- for (const line of lines) {
1599
- const trimmed = line.replace(/^[-*]\s*/, "").trim();
1598
+ for (const line2 of lines) {
1599
+ const trimmed = line2.replace(/^[-*]\s*/, "").trim();
1600
1600
  if (trimmed && trimmed !== "(none)" && trimmed !== "None") {
1601
1601
  blockers.push(trimmed);
1602
1602
  }
@@ -2702,12 +2702,12 @@ async function* readFromCursor(opts) {
2702
2702
  continue;
2703
2703
  throw e;
2704
2704
  }
2705
- for (const line of buf.split("\n")) {
2706
- if (!line.trim())
2705
+ for (const line2 of buf.split("\n")) {
2706
+ if (!line2.trim())
2707
2707
  continue;
2708
2708
  let entry;
2709
2709
  try {
2710
- entry = JSON.parse(line);
2710
+ entry = JSON.parse(line2);
2711
2711
  } catch {
2712
2712
  continue;
2713
2713
  }
@@ -2809,17 +2809,17 @@ function createDecoder(onParseError) {
2809
2809
  const out = [];
2810
2810
  let idx;
2811
2811
  while ((idx = buf.indexOf("\n")) >= 0) {
2812
- const line = buf.slice(0, idx);
2812
+ const line2 = buf.slice(0, idx);
2813
2813
  buf = buf.slice(idx + 1);
2814
- if (!line.trim())
2814
+ if (!line2.trim())
2815
2815
  continue;
2816
2816
  try {
2817
- const parsed = JSON.parse(line);
2817
+ const parsed = JSON.parse(line2);
2818
2818
  if (typeof parsed === "object" && parsed !== null && parsed.type === "_keepalive")
2819
2819
  continue;
2820
2820
  out.push(parsed);
2821
2821
  } catch {
2822
- onParseError?.(line);
2822
+ onParseError?.(line2);
2823
2823
  }
2824
2824
  }
2825
2825
  return out;
@@ -2979,11 +2979,11 @@ function encodeFrame(f) {
2979
2979
  }
2980
2980
  function decodeFrames(wire) {
2981
2981
  const out = [];
2982
- for (const line of wire.split("\n")) {
2983
- if (!line.trim())
2982
+ for (const line2 of wire.split("\n")) {
2983
+ if (!line2.trim())
2984
2984
  continue;
2985
2985
  try {
2986
- const parsed = JSON.parse(line);
2986
+ const parsed = JSON.parse(line2);
2987
2987
  if (parsed.type === "_keepalive")
2988
2988
  continue;
2989
2989
  out.push(parsed);
@@ -3465,10 +3465,10 @@ function detectForeignInstall(parsed, thisEntry, registeredEntryExists) {
3465
3465
  isUpgrade: isVersionUpgrade(parsed.daemonEntry, thisEntry)
3466
3466
  };
3467
3467
  }
3468
- function sanitizePathForPlist(path45) {
3468
+ function sanitizePathForPlist(path46) {
3469
3469
  const seen = /* @__PURE__ */ new Set();
3470
3470
  const stable = [];
3471
- for (const p of path45.split(":")) {
3471
+ for (const p of path46.split(":")) {
3472
3472
  if (!p)
3473
3473
  continue;
3474
3474
  if (p.includes("/.claude/plugins/"))
@@ -4171,14 +4171,14 @@ function detectTrailingQuestion(text) {
4171
4171
  let inFence = false;
4172
4172
  let lastLine = null;
4173
4173
  for (const raw of text.split(/\r?\n/)) {
4174
- const line = raw.trim();
4175
- if (line.startsWith("```")) {
4174
+ const line2 = raw.trim();
4175
+ if (line2.startsWith("```")) {
4176
4176
  inFence = !inFence;
4177
4177
  continue;
4178
4178
  }
4179
- if (inFence || line === "")
4179
+ if (inFence || line2 === "")
4180
4180
  continue;
4181
- lastLine = line;
4181
+ lastLine = line2;
4182
4182
  }
4183
4183
  if (lastLine && lastLine.endsWith("?"))
4184
4184
  return lastLine;
@@ -4189,9 +4189,9 @@ function isQuotedLine(raw) {
4189
4189
  return QUOTED_PREFIX_RE.test(noAnsi);
4190
4190
  }
4191
4191
  function stripChrome(raw) {
4192
- let line = raw.replace(/\[[0-9;]*m/g, "");
4193
- line = line.replace(/^[\s│┃▏▕|]+/, "").replace(/[\s│┃▏▕|]+$/, "");
4194
- const trimmed = line.trim();
4192
+ let line2 = raw.replace(/\[[0-9;]*m/g, "");
4193
+ line2 = line2.replace(/^[\s│┃▏▕|]+/, "").replace(/[\s│┃▏▕|]+$/, "");
4194
+ const trimmed = line2.trim();
4195
4195
  if (trimmed === "")
4196
4196
  return null;
4197
4197
  if (PURE_CHROME_RE.test(trimmed))
@@ -4852,12 +4852,12 @@ function extractUserIntentFromTranscript(jsonl) {
4852
4852
  return null;
4853
4853
  const lines = jsonl.split(/\r?\n/);
4854
4854
  for (let i = lines.length - 1; i >= 0; i--) {
4855
- const line = lines[i].trim();
4856
- if (!line)
4855
+ const line2 = lines[i].trim();
4856
+ if (!line2)
4857
4857
  continue;
4858
4858
  let entry;
4859
4859
  try {
4860
- entry = JSON.parse(line);
4860
+ entry = JSON.parse(line2);
4861
4861
  } catch {
4862
4862
  continue;
4863
4863
  }
@@ -5306,10 +5306,10 @@ async function reapCrewChildren(taskId, graceMs = 2e3, execFn = nodeExec) {
5306
5306
  execFn("ps auxE", { maxBuffer: 64 * 1024 * 1024 }, (err, out) => err ? reject(err) : resolve4(out));
5307
5307
  });
5308
5308
  const pids = [];
5309
- for (const line of stdout.split("\n").slice(1)) {
5310
- if (!line.includes(marker))
5309
+ for (const line2 of stdout.split("\n").slice(1)) {
5310
+ if (!line2.includes(marker))
5311
5311
  continue;
5312
- const pid = parseInt(line.trim().split(/\s+/)[1], 10);
5312
+ const pid = parseInt(line2.trim().split(/\s+/)[1], 10);
5313
5313
  if (!isNaN(pid) && pid !== process.pid)
5314
5314
  pids.push(pid);
5315
5315
  }
@@ -6004,11 +6004,11 @@ var init_captain_record = __esm({
6004
6004
  // packages/core/dist/opencode-session.js
6005
6005
  import { execFileSync as execFileSync4 } from "child_process";
6006
6006
  async function listSessions(port, fetchImpl = fetch, timeoutMs = 5e3) {
6007
- for (const path45 of ["/session", "/api/session"]) {
6007
+ for (const path46 of ["/session", "/api/session"]) {
6008
6008
  const ac = new AbortController();
6009
6009
  const t = setTimeout(() => ac.abort(), timeoutMs);
6010
6010
  try {
6011
- const res = await fetchImpl(`http://127.0.0.1:${port}${path45}`, { signal: ac.signal });
6011
+ const res = await fetchImpl(`http://127.0.0.1:${port}${path46}`, { signal: ac.signal });
6012
6012
  if (!res.ok)
6013
6013
  continue;
6014
6014
  const rows = await res.json();
@@ -6023,8 +6023,8 @@ async function listSessions(port, fetchImpl = fetch, timeoutMs = 5e3) {
6023
6023
  }
6024
6024
  function parseLiveOpencodeServers(psOutput) {
6025
6025
  const out = [];
6026
- for (const line of psOutput.split("\n")) {
6027
- const m = line.match(/^\s*(\d+)\s+(.+)$/);
6026
+ for (const line2 of psOutput.split("\n")) {
6027
+ const m = line2.match(/^\s*(\d+)\s+(.+)$/);
6028
6028
  if (!m)
6029
6029
  continue;
6030
6030
  const pid = Number(m[1]);
@@ -6050,8 +6050,8 @@ function defaultPsOutput() {
6050
6050
  function defaultCwdOf(pid) {
6051
6051
  try {
6052
6052
  const out = execFileSync4("lsof", ["-a", "-p", String(pid), "-d", "cwd", "-Fn"], { encoding: "utf-8", timeout: 2e3 });
6053
- const line = out.split("\n").find((l) => l.startsWith("n"));
6054
- return line ? line.slice(1) : null;
6053
+ const line2 = out.split("\n").find((l) => l.startsWith("n"));
6054
+ return line2 ? line2.slice(1) : null;
6055
6055
  } catch {
6056
6056
  return null;
6057
6057
  }
@@ -6701,10 +6701,10 @@ function distBuiltAt() {
6701
6701
  return 0;
6702
6702
  }
6703
6703
  }
6704
- function gatherLogStats(path45, now, windowMs) {
6704
+ function gatherLogStats(path46, now, windowMs) {
6705
6705
  let sizeBytes = 0;
6706
6706
  try {
6707
- sizeBytes = statSync3(path45).size;
6707
+ sizeBytes = statSync3(path46).size;
6708
6708
  } catch {
6709
6709
  return { errorCount: 0, sizeBytes: 0, windowMs };
6710
6710
  }
@@ -6715,7 +6715,7 @@ function gatherLogStats(path45, now, windowMs) {
6715
6715
  const len = sizeBytes - start;
6716
6716
  let text = "";
6717
6717
  try {
6718
- const fd = openSync2(path45, "r");
6718
+ const fd = openSync2(path46, "r");
6719
6719
  try {
6720
6720
  const buf = Buffer.alloc(len);
6721
6721
  readSync(fd, buf, 0, len, start);
@@ -6728,10 +6728,10 @@ function gatherLogStats(path45, now, windowMs) {
6728
6728
  }
6729
6729
  const cutoff = now - windowMs;
6730
6730
  let errorCount = 0;
6731
- for (const line of text.split("\n")) {
6732
- if (!/error|failed/i.test(line))
6731
+ for (const line2 of text.split("\n")) {
6732
+ if (!/error|failed/i.test(line2))
6733
6733
  continue;
6734
- const m = line.match(/\d{4}-\d{2}-\d{2}T[\d:.]+Z/);
6734
+ const m = line2.match(/\d{4}-\d{2}-\d{2}T[\d:.]+Z/);
6735
6735
  if (m) {
6736
6736
  const ts = Date.parse(m[0]);
6737
6737
  if (!Number.isNaN(ts) && ts < cutoff)
@@ -8906,10 +8906,10 @@ function scan(bufRef, acc) {
8906
8906
  let saw = false;
8907
8907
  let idx;
8908
8908
  while ((idx = bufRef.value.indexOf("\n")) !== -1) {
8909
- const line = bufRef.value.slice(0, idx).trim();
8909
+ const line2 = bufRef.value.slice(0, idx).trim();
8910
8910
  bufRef.value = bufRef.value.slice(idx + 1);
8911
- if (line.startsWith("data:")) {
8912
- const payload = line.slice(5).trim();
8911
+ if (line2.startsWith("data:")) {
8912
+ const payload = line2.slice(5).trim();
8913
8913
  if (payload && payload !== "[DONE]") {
8914
8914
  try {
8915
8915
  if (absorb(JSON.parse(payload), acc))
@@ -8960,8 +8960,8 @@ var init_stream = __esm({
8960
8960
  // packages/core/dist/router/shim.js
8961
8961
  import { createServer as createServer3 } from "http";
8962
8962
  import { Readable } from "stream";
8963
- function joinUrl(base, path45) {
8964
- return base.replace(/\/+$/, "") + path45;
8963
+ function joinUrl(base, path46) {
8964
+ return base.replace(/\/+$/, "") + path46;
8965
8965
  }
8966
8966
  async function readBody(req) {
8967
8967
  const chunks = [];
@@ -9137,8 +9137,8 @@ function createRouterShim(opts) {
9137
9137
  writeJson(res, 200, { input_tokens: Math.max(1, Math.ceil(text.length / 4)) });
9138
9138
  }
9139
9139
  function handler(req, res) {
9140
- const path45 = pathnameOf(req.url);
9141
- if (req.method === "POST" && path45 === "/v1/messages") {
9140
+ const path46 = pathnameOf(req.url);
9141
+ if (req.method === "POST" && path46 === "/v1/messages") {
9142
9142
  void handleMessages(req, res).catch((err) => {
9143
9143
  log(`router internal error: ${err instanceof Error ? err.message : String(err)}`);
9144
9144
  if (!res.headersSent) {
@@ -9150,18 +9150,18 @@ function createRouterShim(opts) {
9150
9150
  });
9151
9151
  return;
9152
9152
  }
9153
- if (req.method === "POST" && path45 === "/v1/messages/count_tokens") {
9153
+ if (req.method === "POST" && path46 === "/v1/messages/count_tokens") {
9154
9154
  void handleCountTokens(req, res).catch(() => {
9155
9155
  if (!res.headersSent)
9156
9156
  writeJson(res, 502, anthropicError(502, "api_error", "router internal error").body);
9157
9157
  });
9158
9158
  return;
9159
9159
  }
9160
- if (req.method === "GET" && path45 === "/v1/models") {
9160
+ if (req.method === "GET" && path46 === "/v1/models") {
9161
9161
  writeJson(res, 200, modelsList([...advertisedModels]));
9162
9162
  return;
9163
9163
  }
9164
- if (req.method === "GET" && path45 === "/healthz") {
9164
+ if (req.method === "GET" && path46 === "/healthz") {
9165
9165
  writeJson(res, 200, { ready: server?.listening === true, upstreamReachable, lastError });
9166
9166
  return;
9167
9167
  }
@@ -9430,11 +9430,11 @@ async function probeCaptainChannel(project, opts = {}) {
9430
9430
  }
9431
9431
  }
9432
9432
  async function httpReachable(port, fetchImpl, timeoutMs) {
9433
- for (const path45 of ["/session", "/api/session"]) {
9433
+ for (const path46 of ["/session", "/api/session"]) {
9434
9434
  const ac = new AbortController();
9435
9435
  const t = setTimeout(() => ac.abort(), timeoutMs);
9436
9436
  try {
9437
- const res = await fetchImpl(`http://127.0.0.1:${port}${path45}`, { signal: ac.signal });
9437
+ const res = await fetchImpl(`http://127.0.0.1:${port}${path46}`, { signal: ac.signal });
9438
9438
  if (res.ok)
9439
9439
  return true;
9440
9440
  } catch {
@@ -10617,28 +10617,28 @@ function requireSnippet() {
10617
10617
  const maxLineLength = options.maxLength - (options.indent + lineNoLength + 3);
10618
10618
  for (let i = 1; i <= options.linesBefore; i++) {
10619
10619
  if (foundLineNo - i < 0) break;
10620
- const line2 = getLine(
10620
+ const line22 = getLine(
10621
10621
  mark2.buffer,
10622
10622
  lineStarts[foundLineNo - i],
10623
10623
  lineEnds[foundLineNo - i],
10624
10624
  mark2.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]),
10625
10625
  maxLineLength
10626
10626
  );
10627
- result = common2.repeat(" ", options.indent) + padStart((mark2.line - i + 1).toString(), lineNoLength) + " | " + line2.str + "\n" + result;
10627
+ result = common2.repeat(" ", options.indent) + padStart((mark2.line - i + 1).toString(), lineNoLength) + " | " + line22.str + "\n" + result;
10628
10628
  }
10629
- const line = getLine(mark2.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark2.position, maxLineLength);
10630
- result += common2.repeat(" ", options.indent) + padStart((mark2.line + 1).toString(), lineNoLength) + " | " + line.str + "\n";
10631
- result += common2.repeat("-", options.indent + lineNoLength + 3 + line.pos) + "^\n";
10629
+ const line2 = getLine(mark2.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark2.position, maxLineLength);
10630
+ result += common2.repeat(" ", options.indent) + padStart((mark2.line + 1).toString(), lineNoLength) + " | " + line2.str + "\n";
10631
+ result += common2.repeat("-", options.indent + lineNoLength + 3 + line2.pos) + "^\n";
10632
10632
  for (let i = 1; i <= options.linesAfter; i++) {
10633
10633
  if (foundLineNo + i >= lineEnds.length) break;
10634
- const line2 = getLine(
10634
+ const line22 = getLine(
10635
10635
  mark2.buffer,
10636
10636
  lineStarts[foundLineNo + i],
10637
10637
  lineEnds[foundLineNo + i],
10638
10638
  mark2.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]),
10639
10639
  maxLineLength
10640
10640
  );
10641
- result += common2.repeat(" ", options.indent) + padStart((mark2.line + i + 1).toString(), lineNoLength) + " | " + line2.str + "\n";
10641
+ result += common2.repeat(" ", options.indent) + padStart((mark2.line + i + 1).toString(), lineNoLength) + " | " + line22.str + "\n";
10642
10642
  }
10643
10643
  return result.replace(/\n$/, "");
10644
10644
  }
@@ -12925,17 +12925,17 @@ function requireDumper() {
12925
12925
  let result = "";
12926
12926
  const length = string.length;
12927
12927
  while (position < length) {
12928
- let line;
12928
+ let line2;
12929
12929
  const next = string.indexOf("\n", position);
12930
12930
  if (next === -1) {
12931
- line = string.slice(position);
12931
+ line2 = string.slice(position);
12932
12932
  position = length;
12933
12933
  } else {
12934
- line = string.slice(position, next + 1);
12934
+ line2 = string.slice(position, next + 1);
12935
12935
  position = next + 1;
12936
12936
  }
12937
- if (line.length && line !== "\n") result += ind;
12938
- result += line;
12937
+ if (line2.length && line2 !== "\n") result += ind;
12938
+ result += line2;
12939
12939
  }
12940
12940
  return result;
12941
12941
  }
@@ -13120,15 +13120,15 @@ function requireDumper() {
13120
13120
  let match;
13121
13121
  while (match = lineRe.exec(string)) {
13122
13122
  const prefix = match[1];
13123
- const line = match[2];
13124
- moreIndented = line[0] === " ";
13125
- result += prefix + (!prevMoreIndented && !moreIndented && line !== "" ? "\n" : "") + foldLine(line, width);
13123
+ const line2 = match[2];
13124
+ moreIndented = line2[0] === " ";
13125
+ result += prefix + (!prevMoreIndented && !moreIndented && line2 !== "" ? "\n" : "") + foldLine(line2, width);
13126
13126
  prevMoreIndented = moreIndented;
13127
13127
  }
13128
13128
  return result;
13129
13129
  }
13130
- function foldLine(line, width) {
13131
- if (line === "" || line[0] === " ") return line;
13130
+ function foldLine(line2, width) {
13131
+ if (line2 === "" || line2[0] === " ") return line2;
13132
13132
  const breakRe = / [^ ]/g;
13133
13133
  let match;
13134
13134
  let start = 0;
@@ -13136,20 +13136,20 @@ function requireDumper() {
13136
13136
  let curr = 0;
13137
13137
  let next = 0;
13138
13138
  let result = "";
13139
- while (match = breakRe.exec(line)) {
13139
+ while (match = breakRe.exec(line2)) {
13140
13140
  next = match.index;
13141
13141
  if (next - start > width) {
13142
13142
  end = curr > start ? curr : next;
13143
- result += "\n" + line.slice(start, end);
13143
+ result += "\n" + line2.slice(start, end);
13144
13144
  start = end + 1;
13145
13145
  }
13146
13146
  curr = next;
13147
13147
  }
13148
13148
  result += "\n";
13149
- if (line.length - start > width && curr > start) {
13150
- result += line.slice(start, curr) + "\n" + line.slice(curr + 1);
13149
+ if (line2.length - start > width && curr > start) {
13150
+ result += line2.slice(start, curr) + "\n" + line2.slice(curr + 1);
13151
13151
  } else {
13152
- result += line.slice(start);
13152
+ result += line2.slice(start);
13153
13153
  }
13154
13154
  return result.slice(1);
13155
13155
  }
@@ -13558,6 +13558,220 @@ var init_sources = __esm({
13558
13558
  }
13559
13559
  });
13560
13560
 
13561
+ // packages/core/dist/knowledge/inject.js
13562
+ import fs19 from "fs";
13563
+ import path18 from "path";
13564
+ function sessionOrder(a, b) {
13565
+ const proj = (r) => r.layer.startsWith("project:") ? 0 : 1;
13566
+ const mod = (r) => r.modality === "must-not" ? 0 : 1;
13567
+ return proj(a) - proj(b) || mod(a) - mod(b) || a.id.localeCompare(b.id);
13568
+ }
13569
+ function formatSessionContext(kbs, rules, cap = SESSION_RULE_CAP) {
13570
+ const hard = rules.filter((r) => r.status === "active" && (r.modality === "must" || r.modality === "must-not")).sort(sessionOrder);
13571
+ const shown = hard.slice(0, cap);
13572
+ const lines = [
13573
+ `<squadrant-project-rules kb="${kbs.join(",")}">`,
13574
+ `Rules KB: ${kbs.join(", ")}. ${DATA_NOTE}`,
13575
+ ...shown.map(line)
13576
+ ];
13577
+ if (hard.length > shown.length)
13578
+ lines.push(`+${hard.length - shown.length} more: squadrant rules list --brief`);
13579
+ lines.push("Look up rules for a task with `squadrant rules search <terms>` / `squadrant rules show <id>` (rules-ops skill).");
13580
+ lines.push("</squadrant-project-rules>");
13581
+ return { text: lines.join("\n"), ids: shown.map((r) => r.id) };
13582
+ }
13583
+ function cleanPromptQuery(prompt) {
13584
+ const text = prompt.replace(/```[\s\S]*?(```|$)/g, " ").split("\n").filter((l) => l.length <= MAX_LINE_CHARS).join("\n").slice(0, MAX_PROMPT_CHARS).toLowerCase().replace(/https?:\/\/\S+/g, " ");
13585
+ const terms = [];
13586
+ const add = (t) => {
13587
+ if (t.length < 3 && !SHORT_TERMS.has(t) || /^\d+$/.test(t) || STOPWORDS.has(t) || terms.includes(t))
13588
+ return;
13589
+ terms.push(t);
13590
+ };
13591
+ for (const raw of text.split(/[^a-z0-9._-]+/)) {
13592
+ const t = raw.replace(/^[._-]+|[._-]+$/g, "");
13593
+ if (STOPWORDS.has(t))
13594
+ continue;
13595
+ add(t);
13596
+ const parts = t.split(/[._-]+/);
13597
+ if (parts.length > 1 && parts.every((x) => x.length >= 3 && !PREFIXES.has(x)))
13598
+ parts.forEach(add);
13599
+ if (terms.length >= MAX_TERMS)
13600
+ break;
13601
+ }
13602
+ return terms.slice(0, MAX_TERMS).join(" ");
13603
+ }
13604
+ function wholeWordTerms(rule2, terms) {
13605
+ const text = [
13606
+ rule2.id,
13607
+ ...rule2.triggers?.keywords ?? [],
13608
+ ...rule2.triggers?.expanded ?? [],
13609
+ rule2.triggers?.when ?? "",
13610
+ rule2.statement
13611
+ ].join("\n").toLowerCase();
13612
+ return terms.filter((t) => {
13613
+ const base = t.length > 4 ? t.replace(/(es|s)$/, "") : t;
13614
+ return new RegExp(`(^|[^a-z0-9])(?:${escapeRe(t)}|${escapeRe(base)}(?:s|es)?)($|[^a-z0-9])`).test(text);
13615
+ });
13616
+ }
13617
+ function selectPromptHits(hits, query, seen, opts = {}) {
13618
+ const minScore = opts.minScore ?? PROMPT_MIN_SCORE;
13619
+ const terms = query.split(" ").filter(Boolean);
13620
+ return hits.filter((h) => {
13621
+ if (seen.has(h.rule.id))
13622
+ return false;
13623
+ const n = wholeWordTerms(h.rule, terms).length;
13624
+ return n >= 2 && h.score >= minScore || n === 1 && h.score >= PROMPT_SINGLE_TERM_MIN_SCORE;
13625
+ }).slice(0, opts.cap ?? PROMPT_RULE_CAP);
13626
+ }
13627
+ function isSystemPrompt(prompt) {
13628
+ const t = prompt.trimStart();
13629
+ return /^(⚠|🗒|\[stale\b|CREW [A-Z]|Another Claude session sent a message)/u.test(t) || t.includes("<cross-session-message");
13630
+ }
13631
+ function promptText(prompt) {
13632
+ const m = BRIEF_POINTER_RE.exec(prompt.trimStart());
13633
+ if (!m)
13634
+ return prompt;
13635
+ try {
13636
+ return fs19.readFileSync(m[1], "utf8").slice(0, MAX_PROMPT_CHARS * 2);
13637
+ } catch {
13638
+ return prompt;
13639
+ }
13640
+ }
13641
+ function formatPromptContext(hits) {
13642
+ return [
13643
+ '<squadrant-project-rules match="prompt">',
13644
+ `Rules that may apply to this prompt. ${DATA_NOTE}`,
13645
+ ...hits.map((h) => line(h.rule)),
13646
+ "</squadrant-project-rules>"
13647
+ ].join("\n");
13648
+ }
13649
+ function injectStateDir(stateRoot) {
13650
+ return path18.join(stateRoot, "rules-inject");
13651
+ }
13652
+ function readSeenRules(stateRoot, sessionId) {
13653
+ try {
13654
+ const ids = JSON.parse(fs19.readFileSync(sessionFile(stateRoot, sessionId), "utf8"));
13655
+ return new Set(Array.isArray(ids) ? ids.filter((x) => typeof x === "string") : []);
13656
+ } catch {
13657
+ return /* @__PURE__ */ new Set();
13658
+ }
13659
+ }
13660
+ function recordSeenRules(stateRoot, sessionId, ids) {
13661
+ if (!ids.length)
13662
+ return;
13663
+ const seen = readSeenRules(stateRoot, sessionId);
13664
+ for (const id of ids)
13665
+ seen.add(id);
13666
+ fs19.mkdirSync(injectStateDir(stateRoot), { recursive: true });
13667
+ fs19.writeFileSync(sessionFile(stateRoot, sessionId), JSON.stringify([...seen]));
13668
+ }
13669
+ function pruneSeenRules(stateRoot, now = Date.now()) {
13670
+ const dir = injectStateDir(stateRoot);
13671
+ let names;
13672
+ try {
13673
+ names = fs19.readdirSync(dir);
13674
+ } catch {
13675
+ return;
13676
+ }
13677
+ for (const n of names) {
13678
+ const f = path18.join(dir, n);
13679
+ try {
13680
+ if (now - fs19.statSync(f).mtimeMs > SEEN_TTL_MS)
13681
+ fs19.unlinkSync(f);
13682
+ } catch {
13683
+ }
13684
+ }
13685
+ }
13686
+ async function withBudget(fn, budgetMs = INJECT_BUDGET_MS) {
13687
+ const start = Date.now();
13688
+ let timer;
13689
+ try {
13690
+ const timeout = new Promise((resolve4) => {
13691
+ timer = setTimeout(() => resolve4(null), budgetMs);
13692
+ });
13693
+ const out = await Promise.race([Promise.resolve().then(fn), timeout]);
13694
+ return Date.now() - start > budgetMs ? null : out;
13695
+ } catch {
13696
+ return null;
13697
+ } finally {
13698
+ clearTimeout(timer);
13699
+ }
13700
+ }
13701
+ function resolveInjectProject(cfg, cwd, env, project) {
13702
+ const named = project ?? env.SQUADRANT_CREW_PROJECT;
13703
+ if (named)
13704
+ return cfg.projects[named] ? named : null;
13705
+ let best = null;
13706
+ let bestLen = -1;
13707
+ for (const [name, pc] of Object.entries(cfg.projects)) {
13708
+ const root = resolveHome(pc.path);
13709
+ if ((cwd === root || cwd.startsWith(root + path18.sep)) && root.length > bestLen) {
13710
+ best = name;
13711
+ bestLen = root.length;
13712
+ }
13713
+ }
13714
+ return best;
13715
+ }
13716
+ function computeRulesInjection(i) {
13717
+ if (i.env.SQUADRANT_RULES_INJECT === "0")
13718
+ return null;
13719
+ const p = typeof i.payload === "object" && i.payload !== null ? i.payload : {};
13720
+ const cwd = typeof p.cwd === "string" && p.cwd ? p.cwd : i.cwd;
13721
+ const project = resolveInjectProject(i.cfg, cwd, i.env, i.project);
13722
+ if (!project)
13723
+ return null;
13724
+ const kbs = subscribedKbs(i.cfg, project);
13725
+ if (!kbs.length)
13726
+ return null;
13727
+ const sessionId = typeof p.session_id === "string" && p.session_id ? p.session_id : null;
13728
+ if (i.event === "session-start") {
13729
+ const { text, ids } = formatSessionContext(kbs, resolveProjectRules(i.cfg, project).rules);
13730
+ if (sessionId) {
13731
+ pruneSeenRules(i.stateRoot);
13732
+ recordSeenRules(i.stateRoot, sessionId, ids);
13733
+ }
13734
+ return text;
13735
+ }
13736
+ if (typeof p.prompt !== "string" || isSystemPrompt(p.prompt))
13737
+ return null;
13738
+ const query = cleanPromptQuery(promptText(p.prompt));
13739
+ if (!query)
13740
+ return null;
13741
+ const seen = sessionId ? readSeenRules(i.stateRoot, sessionId) : /* @__PURE__ */ new Set();
13742
+ const picked = selectPromptHits(searchRules(resolveProjectRules(i.cfg, project).rules, query), query, seen);
13743
+ if (!picked.length)
13744
+ return null;
13745
+ if (sessionId)
13746
+ recordSeenRules(i.stateRoot, sessionId, picked.map((h) => h.rule.id));
13747
+ return formatPromptContext(picked);
13748
+ }
13749
+ var SESSION_RULE_CAP, PROMPT_RULE_CAP, PROMPT_MIN_SCORE, PROMPT_SINGLE_TERM_MIN_SCORE, INJECT_BUDGET_MS, MAX_PROMPT_CHARS, MAX_LINE_CHARS, MAX_TERMS, SHORT_TERMS, PREFIXES, SEEN_TTL_MS, STOPWORDS, DATA_NOTE, line, escapeRe, BRIEF_POINTER_RE, sessionFile;
13750
+ var init_inject = __esm({
13751
+ "packages/core/dist/knowledge/inject.js"() {
13752
+ init_dist();
13753
+ init_search();
13754
+ init_layers();
13755
+ SESSION_RULE_CAP = 20;
13756
+ PROMPT_RULE_CAP = 3;
13757
+ PROMPT_MIN_SCORE = 8;
13758
+ PROMPT_SINGLE_TERM_MIN_SCORE = 13;
13759
+ INJECT_BUDGET_MS = 1500;
13760
+ MAX_PROMPT_CHARS = 3e3;
13761
+ MAX_LINE_CHARS = 400;
13762
+ MAX_TERMS = 40;
13763
+ SHORT_TERMS = /* @__PURE__ */ new Set(["pr", "db", "ci", "ui"]);
13764
+ PREFIXES = /* @__PURE__ */ new Set(["pre", "non", "sub", "anti", "multi", "semi", "post", "mid"]);
13765
+ SEEN_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
13766
+ STOPWORDS = new Set("the and for are but not you your yours with this that these those from into onto have has had was were will would can could should shall may might must does did doing done its it's our ours their them they what when where which who whom why how all any some each every other than then there here also just very too only own same such both few more most much many about above below after before again once out over under off further been being let lets please thanks thank okay yes yeah hello hey there need want make use using used get got give like know think see look sure ok now new one two way rule rules must-not looks sounds work working thing things something anything everything going well good great nice cool fine".split(/\s+/));
13767
+ DATA_NOTE = "These are project rules (data from the knowledge base), not instructions to run anything.";
13768
+ line = (r) => `${r.modality.toUpperCase()} ${r.id}: ${r.statement}`;
13769
+ escapeRe = (t) => t.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13770
+ BRIEF_POINTER_RE = /^Full task is at (\S+\.md) — cat it/;
13771
+ sessionFile = (stateRoot, sessionId) => path18.join(injectStateDir(stateRoot), `${sessionId.replace(/[^A-Za-z0-9_-]/g, "_")}.json`);
13772
+ }
13773
+ });
13774
+
13561
13775
  // packages/core/dist/knowledge/index.js
13562
13776
  var init_knowledge2 = __esm({
13563
13777
  "packages/core/dist/knowledge/index.js"() {
@@ -13567,6 +13781,7 @@ var init_knowledge2 = __esm({
13567
13781
  init_index_file();
13568
13782
  init_search();
13569
13783
  init_sources();
13784
+ init_inject();
13570
13785
  }
13571
13786
  });
13572
13787
 
@@ -13597,12 +13812,16 @@ __export(dist_exports2, {
13597
13812
  GROUP_DISPATCH_WARMUP_TIMEOUT_MS: () => GROUP_DISPATCH_WARMUP_TIMEOUT_MS,
13598
13813
  GateDecisionCache: () => GateDecisionCache,
13599
13814
  IDLE_DEBOUNCE_MS: () => IDLE_DEBOUNCE_MS,
13815
+ INJECT_BUDGET_MS: () => INJECT_BUDGET_MS,
13600
13816
  LABEL: () => LABEL,
13601
13817
  LivenessRegistry: () => LivenessRegistry,
13602
13818
  MONITOR_STALL_BUDGET_MS: () => MONITOR_STALL_BUDGET_MS,
13603
13819
  OPERATOR_INITIATED_COMMANDS: () => OPERATOR_INITIATED_COMMANDS,
13604
13820
  PANE_IDLE_AFTER_MS: () => PANE_IDLE_AFTER_MS,
13605
13821
  PROBE_QUIET_MS: () => PROBE_QUIET_MS,
13822
+ PROMPT_MIN_SCORE: () => PROMPT_MIN_SCORE,
13823
+ PROMPT_RULE_CAP: () => PROMPT_RULE_CAP,
13824
+ PROMPT_SINGLE_TERM_MIN_SCORE: () => PROMPT_SINGLE_TERM_MIN_SCORE,
13606
13825
  PROPOSED_DIR: () => PROPOSED_DIR,
13607
13826
  PROTOCOL_VERSION: () => PROTOCOL_VERSION,
13608
13827
  READ_ONLY_CREW_SUBCOMMANDS: () => READ_ONLY_CREW_SUBCOMMANDS,
@@ -13610,6 +13829,7 @@ __export(dist_exports2, {
13610
13829
  ROUTER_READY_ATTEMPTS: () => ROUTER_READY_ATTEMPTS,
13611
13830
  ROUTER_READY_DELAY_MS: () => ROUTER_READY_DELAY_MS,
13612
13831
  SERVER_TOOL_TYPE_RE: () => SERVER_TOOL_TYPE_RE,
13832
+ SESSION_RULE_CAP: () => SESSION_RULE_CAP,
13613
13833
  SIDE_SESSION_ENV: () => SIDE_SESSION_ENV,
13614
13834
  SOURCES_TEMPLATE: () => SOURCES_TEMPLATE,
13615
13835
  STALE_THRESHOLD_MS: () => STALE_THRESHOLD_MS,
@@ -13650,9 +13870,11 @@ __export(dist_exports2, {
13650
13870
  classifyCaptainPane: () => classifyCaptainPane,
13651
13871
  classifyHealth: () => classifyHealth,
13652
13872
  claudeEnvShadowsRouter: () => claudeEnvShadowsRouter,
13873
+ cleanPromptQuery: () => cleanPromptQuery,
13653
13874
  clearPending: () => clearPending,
13654
13875
  closeWorkItem: () => closeWorkItem,
13655
13876
  compileIndex: () => compileIndex,
13877
+ computeRulesInjection: () => computeRulesInjection,
13656
13878
  computeTemplateHash: () => computeTemplateHash,
13657
13879
  consumeExitMarker: () => consumeExitMarker,
13658
13880
  createAttach: () => createAttach,
@@ -13726,6 +13948,8 @@ __export(dist_exports2, {
13726
13948
  formatLifecycle: () => formatLifecycle,
13727
13949
  formatMediaReceipt: () => formatMediaReceipt,
13728
13950
  formatPermissionDecision: () => formatPermissionDecision,
13951
+ formatPromptContext: () => formatPromptContext,
13952
+ formatSessionContext: () => formatSessionContext,
13729
13953
  formatUsageLine: () => formatUsageLine,
13730
13954
  formatWatchdogWarning: () => formatWatchdogWarning,
13731
13955
  freshTrace: () => freshTrace,
@@ -13735,6 +13959,7 @@ __export(dist_exports2, {
13735
13959
  hasModalOptionList: () => hasModalOptionList,
13736
13960
  healCmdFor: () => healCmdFor,
13737
13961
  inboundBody: () => inboundBody,
13962
+ injectStateDir: () => injectStateDir,
13738
13963
  isAuthorized: () => isAuthorized,
13739
13964
  isBareSpawn: () => isBareSpawn,
13740
13965
  isCaptainAlive: () => isCaptainAlive,
@@ -13750,6 +13975,7 @@ __export(dist_exports2, {
13750
13975
  isReadOnlyTopLevelCommand: () => isReadOnlyTopLevelCommand,
13751
13976
  isSideTitle: () => isSideTitle,
13752
13977
  isStickyAttention: () => isStickyAttention,
13978
+ isSystemPrompt: () => isSystemPrompt,
13753
13979
  isTurnAccepted: () => isTurnAccepted,
13754
13980
  isVersionUpgrade: () => isVersionUpgrade,
13755
13981
  joinUrl: () => joinUrl,
@@ -13795,6 +14021,7 @@ __export(dist_exports2, {
13795
14021
  programArgsBlock: () => programArgsBlock,
13796
14022
  projectHealth: () => projectHealth,
13797
14023
  projectRulesDir: () => projectRulesDir,
14024
+ pruneSeenRules: () => pruneSeenRules,
13798
14025
  pruneTopics: () => pruneTopics,
13799
14026
  purgeExpiredWorkItems: () => purgeExpiredWorkItems,
13800
14027
  readCaptainAddress: () => readCaptainAddress,
@@ -13802,11 +14029,13 @@ __export(dist_exports2, {
13802
14029
  readFromCursor: () => readFromCursor,
13803
14030
  readIndex: () => readIndex,
13804
14031
  readRunningMarker: () => readRunningMarker,
14032
+ readSeenRules: () => readSeenRules,
13805
14033
  readUserIntent: () => readUserIntent,
13806
14034
  realpathOrSelf: () => realpathOrSelf,
13807
14035
  reapCrewChildren: () => reapCrewChildren,
13808
14036
  reapOrphanedCrews: () => reapOrphanedCrews,
13809
14037
  reconcileLiveness: () => reconcileLiveness,
14038
+ recordSeenRules: () => recordSeenRules,
13810
14039
  recordSession: () => recordSession,
13811
14040
  recoverStall: () => recoverStall,
13812
14041
  reduce: () => reduce,
@@ -13828,6 +14057,7 @@ __export(dist_exports2, {
13828
14057
  resolveGateMode: () => resolveGateMode,
13829
14058
  resolveGatePolicy: () => resolveGatePolicy,
13830
14059
  resolveGateTools: () => resolveGateTools,
14060
+ resolveInjectProject: () => resolveInjectProject,
13831
14061
  resolveProject: () => resolveProject,
13832
14062
  resolveProjectRules: () => resolveProjectRules,
13833
14063
  resolveRouterCredentials: () => resolveRouterCredentials,
@@ -13867,6 +14097,7 @@ __export(dist_exports2, {
13867
14097
  screenHasSplashMarker: () => screenHasSplashMarker,
13868
14098
  screenHash: () => screenHash,
13869
14099
  searchRules: () => searchRules,
14100
+ selectPromptHits: () => selectPromptHits,
13870
14101
  sendRequest: () => sendRequest,
13871
14102
  setLastUserId: () => setLastUserId,
13872
14103
  setNotify: () => setNotify,
@@ -13895,6 +14126,8 @@ __export(dist_exports2, {
13895
14126
  validateKb: () => validateKb,
13896
14127
  waitForCaptainDelivery: () => waitForCaptainDelivery,
13897
14128
  waitForWarmup: () => waitForWarmup,
14129
+ wholeWordTerms: () => wholeWordTerms,
14130
+ withBudget: () => withBudget,
13898
14131
  writeCaptainAddress: () => writeCaptainAddress,
13899
14132
  writeCursor: () => writeCursor,
13900
14133
  writeExitMarker: () => writeExitMarker,
@@ -13958,7 +14191,7 @@ var init_dist2 = __esm({
13958
14191
  });
13959
14192
 
13960
14193
  // packages/agents/dist/claude/registry.js
13961
- import fs19 from "fs";
14194
+ import fs20 from "fs";
13962
14195
  import { join as join17 } from "path";
13963
14196
  import { homedir as homedir7 } from "os";
13964
14197
  function parseRegistryDir(files, readFile7) {
@@ -14003,11 +14236,11 @@ function readClaudeStatus(task) {
14003
14236
  return void 0;
14004
14237
  let files;
14005
14238
  try {
14006
- files = fs19.readdirSync(CLAUDE_SESSIONS_DIR);
14239
+ files = fs20.readdirSync(CLAUDE_SESSIONS_DIR);
14007
14240
  } catch {
14008
14241
  return void 0;
14009
14242
  }
14010
- const entries = parseRegistryDir(files, (name) => fs19.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14243
+ const entries = parseRegistryDir(files, (name) => fs20.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14011
14244
  let entry;
14012
14245
  if (task.messagingSocketPath) {
14013
14246
  entry = entries.find((e) => e.messagingSocketPath === task.messagingSocketPath);
@@ -14022,11 +14255,11 @@ function readClaudeStatus(task) {
14022
14255
  function readClaudeStatusByCwd(cwd) {
14023
14256
  let files;
14024
14257
  try {
14025
- files = fs19.readdirSync(CLAUDE_SESSIONS_DIR);
14258
+ files = fs20.readdirSync(CLAUDE_SESSIONS_DIR);
14026
14259
  } catch {
14027
14260
  return void 0;
14028
14261
  }
14029
- const entries = parseRegistryDir(files, (name) => fs19.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14262
+ const entries = parseRegistryDir(files, (name) => fs20.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14030
14263
  const entry = entries.find((e) => e.cwd === cwd);
14031
14264
  if (!entry)
14032
14265
  return void 0;
@@ -14035,11 +14268,11 @@ function readClaudeStatusByCwd(cwd) {
14035
14268
  function readClaudeStatusBySocketPath(socketPath2) {
14036
14269
  let files;
14037
14270
  try {
14038
- files = fs19.readdirSync(CLAUDE_SESSIONS_DIR);
14271
+ files = fs20.readdirSync(CLAUDE_SESSIONS_DIR);
14039
14272
  } catch {
14040
14273
  return void 0;
14041
14274
  }
14042
- const entries = parseRegistryDir(files, (name) => fs19.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14275
+ const entries = parseRegistryDir(files, (name) => fs20.readFileSync(join17(CLAUDE_SESSIONS_DIR, name), "utf8"));
14043
14276
  const entry = entries.find((e) => e.messagingSocketPath === socketPath2);
14044
14277
  if (!entry)
14045
14278
  return void 0;
@@ -14462,8 +14695,8 @@ var init_registry2 = __esm({
14462
14695
  });
14463
14696
 
14464
14697
  // packages/agents/dist/drivers/launch-cmd.js
14465
- import fs20 from "fs";
14466
- import path18 from "path";
14698
+ import fs21 from "fs";
14699
+ import path19 from "path";
14467
14700
  function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model, templatesDir, messagingSocketPath, sessionName, thinking, captainBoot, settingsPath) {
14468
14701
  const driver = registry.getDriver(agentName);
14469
14702
  if (driver.name === "claude") {
@@ -14490,14 +14723,14 @@ function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model,
14490
14723
  cmd += ` --settings ${settingsPath}`;
14491
14724
  }
14492
14725
  if (templatesDir) {
14493
- const roleFile2 = path18.join(templatesDir, `${role}.claude.md`);
14494
- const legacyRoleFile = path18.join(templatesDir, `${role}.CLAUDE.md`);
14495
- const actualRoleFile = fs20.existsSync(roleFile2) ? roleFile2 : fs20.existsSync(legacyRoleFile) ? legacyRoleFile : null;
14726
+ const roleFile2 = path19.join(templatesDir, `${role}.claude.md`);
14727
+ const legacyRoleFile = path19.join(templatesDir, `${role}.CLAUDE.md`);
14728
+ const actualRoleFile = fs21.existsSync(roleFile2) ? roleFile2 : fs21.existsSync(legacyRoleFile) ? legacyRoleFile : null;
14496
14729
  if (actualRoleFile) {
14497
14730
  cmd += ` --append-system-prompt-file ${actualRoleFile}`;
14498
14731
  }
14499
- const pluginDir = path18.join(templatesDir, "..", "plugin");
14500
- if (fs20.existsSync(pluginDir)) {
14732
+ const pluginDir = path19.join(templatesDir, "..", "plugin");
14733
+ if (fs21.existsSync(pluginDir)) {
14501
14734
  cmd += ` --plugin-dir ${pluginDir}`;
14502
14735
  }
14503
14736
  }
@@ -14506,14 +14739,14 @@ function buildAgentCmd(agentName, registry, role, fresh, permissionMode, model,
14506
14739
  }
14507
14740
  return cmd;
14508
14741
  }
14509
- const roleFile = templatesDir ? path18.join(templatesDir, `${role}.${driver.templateSuffix}.md`) : void 0;
14742
+ const roleFile = templatesDir ? path19.join(templatesDir, `${role}.${driver.templateSuffix}.md`) : void 0;
14510
14743
  return driver.buildCommand({
14511
14744
  prompt: `You are a squadrant ${role}. Read your instructions from ${roleFile ?? role} and begin.`,
14512
14745
  workdir: process.cwd(),
14513
14746
  role,
14514
14747
  model,
14515
14748
  autoApprove: true,
14516
- promptFile: roleFile && fs20.existsSync(roleFile) ? roleFile : void 0,
14749
+ promptFile: roleFile && fs21.existsSync(roleFile) ? roleFile : void 0,
14517
14750
  ...captainBoot && role === "captain" ? {
14518
14751
  interactive: true,
14519
14752
  ...captainBoot.port ? { port: captainBoot.port } : {},
@@ -14543,7 +14776,7 @@ var init_drivers = __esm({
14543
14776
 
14544
14777
  // packages/agents/dist/projection/cursor.js
14545
14778
  import { mkdir, readFile, writeFile } from "fs/promises";
14546
- import path19 from "path";
14779
+ import path20 from "path";
14547
14780
  import os8 from "os";
14548
14781
  function renderMdc(source) {
14549
14782
  const skillSections = source.skills.map((s) => `## Skill: ${s.name}
@@ -14592,7 +14825,7 @@ function createCursorEmitter() {
14592
14825
  if (scope === "user") {
14593
14826
  return [
14594
14827
  {
14595
- path: path19.join(os8.homedir(), ".cursor/rules/squadrant-global.mdc"),
14828
+ path: path20.join(os8.homedir(), ".cursor/rules/squadrant-global.mdc"),
14596
14829
  shared: false,
14597
14830
  format: "mdc"
14598
14831
  }
@@ -14602,7 +14835,7 @@ function createCursorEmitter() {
14602
14835
  return [];
14603
14836
  return [
14604
14837
  {
14605
- path: path19.join(projectRoot, ".cursor/rules/squadrant.mdc"),
14838
+ path: path20.join(projectRoot, ".cursor/rules/squadrant.mdc"),
14606
14839
  shared: false,
14607
14840
  format: "mdc"
14608
14841
  }
@@ -14619,7 +14852,7 @@ function createCursorEmitter() {
14619
14852
  diff: buildDiff(existing, generated)
14620
14853
  };
14621
14854
  }
14622
- await mkdir(path19.dirname(dest.path), { recursive: true });
14855
+ await mkdir(path20.dirname(dest.path), { recursive: true });
14623
14856
  await writeFile(dest.path, generated, "utf-8");
14624
14857
  return {
14625
14858
  written: true,
@@ -14670,7 +14903,7 @@ var init_marker = __esm({
14670
14903
 
14671
14904
  // packages/agents/dist/projection/codex.js
14672
14905
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
14673
- import path20 from "path";
14906
+ import path21 from "path";
14674
14907
  import os9 from "os";
14675
14908
  function renderMarkdown(source) {
14676
14909
  const skillSections = source.skills.map((s) => `## Skill: ${s.name}
@@ -14695,7 +14928,7 @@ function createCodexEmitter() {
14695
14928
  destinations(scope, projectRoot) {
14696
14929
  if (scope === "user") {
14697
14930
  return [{
14698
- path: path20.join(os9.homedir(), ".codex/AGENTS.md"),
14931
+ path: path21.join(os9.homedir(), ".codex/AGENTS.md"),
14699
14932
  shared: true,
14700
14933
  format: "markdown"
14701
14934
  }];
@@ -14703,7 +14936,7 @@ function createCodexEmitter() {
14703
14936
  if (!projectRoot)
14704
14937
  return [];
14705
14938
  return [{
14706
- path: path20.join(projectRoot, "AGENTS.md"),
14939
+ path: path21.join(projectRoot, "AGENTS.md"),
14707
14940
  shared: true,
14708
14941
  format: "markdown"
14709
14942
  }];
@@ -14724,7 +14957,7 @@ ${existing ?? ""}
14724
14957
  ${generated}`
14725
14958
  };
14726
14959
  }
14727
- await mkdir2(path20.dirname(dest.path), { recursive: true });
14960
+ await mkdir2(path21.dirname(dest.path), { recursive: true });
14728
14961
  await writeFile2(dest.path, generated, "utf-8");
14729
14962
  return {
14730
14963
  written: true,
@@ -14742,7 +14975,7 @@ var init_codex2 = __esm({
14742
14975
 
14743
14976
  // packages/agents/dist/projection/gemini.js
14744
14977
  import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
14745
- import path21 from "path";
14978
+ import path22 from "path";
14746
14979
  import os10 from "os";
14747
14980
  function renderMarkdown2(source) {
14748
14981
  const skillSections = source.skills.map((s) => `## Skill: ${s.name}
@@ -14767,7 +15000,7 @@ function createGeminiEmitter() {
14767
15000
  destinations(scope, projectRoot) {
14768
15001
  if (scope === "user") {
14769
15002
  return [{
14770
- path: path21.join(os10.homedir(), ".gemini/GEMINI.md"),
15003
+ path: path22.join(os10.homedir(), ".gemini/GEMINI.md"),
14771
15004
  shared: true,
14772
15005
  format: "markdown"
14773
15006
  }];
@@ -14775,7 +15008,7 @@ function createGeminiEmitter() {
14775
15008
  if (!projectRoot)
14776
15009
  return [];
14777
15010
  return [{
14778
- path: path21.join(projectRoot, "GEMINI.md"),
15011
+ path: path22.join(projectRoot, "GEMINI.md"),
14779
15012
  shared: true,
14780
15013
  format: "markdown"
14781
15014
  }];
@@ -14796,7 +15029,7 @@ ${existing ?? ""}
14796
15029
  ${generated}`
14797
15030
  };
14798
15031
  }
14799
- await mkdir3(path21.dirname(dest.path), { recursive: true });
15032
+ await mkdir3(path22.dirname(dest.path), { recursive: true });
14800
15033
  await writeFile3(dest.path, generated, "utf-8");
14801
15034
  return {
14802
15035
  written: true,
@@ -14814,7 +15047,7 @@ var init_gemini2 = __esm({
14814
15047
 
14815
15048
  // packages/agents/dist/projection/opencode.js
14816
15049
  import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
14817
- import path22 from "path";
15050
+ import path23 from "path";
14818
15051
  import os11 from "os";
14819
15052
  function renderMarkdown3(source) {
14820
15053
  const skillSections = source.skills.map((s) => `## Skill: ${s.name}
@@ -14839,7 +15072,7 @@ function createOpencodeEmitter() {
14839
15072
  destinations(scope, projectRoot) {
14840
15073
  if (scope === "user") {
14841
15074
  return [{
14842
- path: path22.join(os11.homedir(), ".config", "opencode", "AGENTS.md"),
15075
+ path: path23.join(os11.homedir(), ".config", "opencode", "AGENTS.md"),
14843
15076
  shared: true,
14844
15077
  format: "markdown"
14845
15078
  }];
@@ -14847,7 +15080,7 @@ function createOpencodeEmitter() {
14847
15080
  if (!projectRoot)
14848
15081
  return [];
14849
15082
  return [{
14850
- path: path22.join(projectRoot, "AGENTS.md"),
15083
+ path: path23.join(projectRoot, "AGENTS.md"),
14851
15084
  shared: true,
14852
15085
  format: "markdown"
14853
15086
  }];
@@ -14868,7 +15101,7 @@ ${existing ?? ""}
14868
15101
  ${generated}`
14869
15102
  };
14870
15103
  }
14871
- await mkdir4(path22.dirname(dest.path), { recursive: true });
15104
+ await mkdir4(path23.dirname(dest.path), { recursive: true });
14872
15105
  await writeFile4(dest.path, generated, "utf-8");
14873
15106
  return {
14874
15107
  written: true,
@@ -14885,12 +15118,12 @@ var init_opencode2 = __esm({
14885
15118
  });
14886
15119
 
14887
15120
  // packages/agents/dist/projection/opencode-skills.js
14888
- import fs21 from "fs";
15121
+ import fs22 from "fs";
14889
15122
  import os12 from "os";
14890
- import path23 from "path";
15123
+ import path24 from "path";
14891
15124
  function defaultOpencodeSkillsRoot(env = process.env) {
14892
- const configHome = env.XDG_CONFIG_HOME || path23.join(os12.homedir(), ".config");
14893
- return path23.join(configHome, "opencode", "skills");
15125
+ const configHome = env.XDG_CONFIG_HOME || path24.join(os12.homedir(), ".config");
15126
+ return path24.join(configHome, "opencode", "skills");
14894
15127
  }
14895
15128
  function parseSkillName(raw) {
14896
15129
  const fm = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
@@ -14904,62 +15137,62 @@ function parseSkillName(raw) {
14904
15137
  }
14905
15138
  function listSourceSkills(sourceSkillsDir) {
14906
15139
  const out = /* @__PURE__ */ new Map();
14907
- if (!fs21.existsSync(sourceSkillsDir))
15140
+ if (!fs22.existsSync(sourceSkillsDir))
14908
15141
  return out;
14909
- for (const entry of fs21.readdirSync(sourceSkillsDir, { withFileTypes: true })) {
15142
+ for (const entry of fs22.readdirSync(sourceSkillsDir, { withFileTypes: true })) {
14910
15143
  if (!entry.isDirectory())
14911
15144
  continue;
14912
- const skillPath = path23.join(sourceSkillsDir, entry.name, "SKILL.md");
14913
- if (!fs21.existsSync(skillPath))
15145
+ const skillPath = path24.join(sourceSkillsDir, entry.name, "SKILL.md");
15146
+ if (!fs22.existsSync(skillPath))
14914
15147
  continue;
14915
- const name = parseSkillName(fs21.readFileSync(skillPath, "utf-8"));
15148
+ const name = parseSkillName(fs22.readFileSync(skillPath, "utf-8"));
14916
15149
  if (name && SAFE_NAME.test(name))
14917
15150
  out.set(name, skillPath);
14918
15151
  }
14919
15152
  return out;
14920
15153
  }
14921
15154
  function hasMarker(dir) {
14922
- return fs21.existsSync(path23.join(dir, OPENCODE_SKILL_MARKER));
15155
+ return fs22.existsSync(path24.join(dir, OPENCODE_SKILL_MARKER));
14923
15156
  }
14924
15157
  function syncOpencodeSkills(opts) {
14925
15158
  const result = { written: [], unchanged: [], removed: [], skipped: [] };
14926
15159
  const wanted = listSourceSkills(opts.sourceSkillsDir);
14927
- if (wanted.size === 0 && !fs21.existsSync(opts.sourceSkillsDir))
15160
+ if (wanted.size === 0 && !fs22.existsSync(opts.sourceSkillsDir))
14928
15161
  return result;
14929
15162
  if (!opts.dryRun)
14930
- fs21.mkdirSync(opts.skillsRoot, { recursive: true });
15163
+ fs22.mkdirSync(opts.skillsRoot, { recursive: true });
14931
15164
  for (const [name, srcPath] of wanted) {
14932
- const targetDir = path23.join(opts.skillsRoot, name);
14933
- const targetSkill = path23.join(targetDir, "SKILL.md");
15165
+ const targetDir = path24.join(opts.skillsRoot, name);
15166
+ const targetSkill = path24.join(targetDir, "SKILL.md");
14934
15167
  const managed = hasMarker(targetDir);
14935
- if (fs21.existsSync(targetSkill) && !managed) {
15168
+ if (fs22.existsSync(targetSkill) && !managed) {
14936
15169
  result.skipped.push({ name, reason: "foreign-collision" });
14937
15170
  continue;
14938
15171
  }
14939
- const current = fs21.existsSync(targetSkill) ? fs21.readFileSync(targetSkill) : null;
14940
- if (current && current.equals(fs21.readFileSync(srcPath))) {
15172
+ const current = fs22.existsSync(targetSkill) ? fs22.readFileSync(targetSkill) : null;
15173
+ if (current && current.equals(fs22.readFileSync(srcPath))) {
14941
15174
  if (!managed && !opts.dryRun) {
14942
- fs21.writeFileSync(path23.join(targetDir, OPENCODE_SKILL_MARKER), MARKER_BODY);
15175
+ fs22.writeFileSync(path24.join(targetDir, OPENCODE_SKILL_MARKER), MARKER_BODY);
14943
15176
  }
14944
15177
  result.unchanged.push(name);
14945
15178
  continue;
14946
15179
  }
14947
15180
  if (!opts.dryRun) {
14948
- fs21.mkdirSync(targetDir, { recursive: true });
14949
- fs21.copyFileSync(srcPath, targetSkill);
14950
- fs21.writeFileSync(path23.join(targetDir, OPENCODE_SKILL_MARKER), MARKER_BODY);
15181
+ fs22.mkdirSync(targetDir, { recursive: true });
15182
+ fs22.copyFileSync(srcPath, targetSkill);
15183
+ fs22.writeFileSync(path24.join(targetDir, OPENCODE_SKILL_MARKER), MARKER_BODY);
14951
15184
  }
14952
15185
  result.written.push(name);
14953
15186
  }
14954
- if (fs21.existsSync(opts.skillsRoot)) {
14955
- for (const entry of fs21.readdirSync(opts.skillsRoot, { withFileTypes: true })) {
15187
+ if (fs22.existsSync(opts.skillsRoot)) {
15188
+ for (const entry of fs22.readdirSync(opts.skillsRoot, { withFileTypes: true })) {
14956
15189
  if (!entry.isDirectory() || wanted.has(entry.name))
14957
15190
  continue;
14958
- const dir = path23.join(opts.skillsRoot, entry.name);
15191
+ const dir = path24.join(opts.skillsRoot, entry.name);
14959
15192
  if (!hasMarker(dir))
14960
15193
  continue;
14961
15194
  if (!opts.dryRun)
14962
- fs21.rmSync(dir, { recursive: true, force: true });
15195
+ fs22.rmSync(dir, { recursive: true, force: true });
14963
15196
  result.removed.push(entry.name);
14964
15197
  }
14965
15198
  }
@@ -14967,7 +15200,7 @@ function syncOpencodeSkills(opts) {
14967
15200
  }
14968
15201
  function syncShippedOpencodeSkills(opts) {
14969
15202
  return syncOpencodeSkills({
14970
- sourceSkillsDir: path23.join(opts.pkgRoot, "plugin", "skills"),
15203
+ sourceSkillsDir: path24.join(opts.pkgRoot, "plugin", "skills"),
14971
15204
  skillsRoot: opts.skillsRoot ?? defaultOpencodeSkillsRoot(),
14972
15205
  dryRun: opts.dryRun
14973
15206
  });
@@ -14983,7 +15216,7 @@ var init_opencode_skills = __esm({
14983
15216
 
14984
15217
  // packages/agents/dist/projection/claude.js
14985
15218
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
14986
- import path24 from "path";
15219
+ import path25 from "path";
14987
15220
  import os13 from "os";
14988
15221
  function renderMarkdown4(source) {
14989
15222
  const skillSections = source.skills.map((s) => `## Skill: ${s.name}
@@ -15008,7 +15241,7 @@ function createClaudeEmitter() {
15008
15241
  destinations(scope, projectRoot) {
15009
15242
  if (scope === "user") {
15010
15243
  return [{
15011
- path: path24.join(os13.homedir(), ".claude/CLAUDE.md"),
15244
+ path: path25.join(os13.homedir(), ".claude/CLAUDE.md"),
15012
15245
  shared: true,
15013
15246
  format: "markdown"
15014
15247
  }];
@@ -15016,7 +15249,7 @@ function createClaudeEmitter() {
15016
15249
  if (!projectRoot)
15017
15250
  return [];
15018
15251
  return [{
15019
- path: path24.join(projectRoot, "CLAUDE.md"),
15252
+ path: path25.join(projectRoot, "CLAUDE.md"),
15020
15253
  shared: true,
15021
15254
  format: "markdown"
15022
15255
  }];
@@ -15037,7 +15270,7 @@ ${existing ?? ""}
15037
15270
  ${generated}`
15038
15271
  };
15039
15272
  }
15040
- await mkdir5(path24.dirname(dest.path), { recursive: true });
15273
+ await mkdir5(path25.dirname(dest.path), { recursive: true });
15041
15274
  await writeFile5(dest.path, generated, "utf-8");
15042
15275
  return {
15043
15276
  written: true,
@@ -15099,12 +15332,12 @@ function _parseChunk(acc, chunk) {
15099
15332
  const out = [];
15100
15333
  let idx;
15101
15334
  while ((idx = acc.buf.indexOf("\n")) >= 0) {
15102
- const line = acc.buf.slice(0, idx);
15335
+ const line2 = acc.buf.slice(0, idx);
15103
15336
  acc.buf = acc.buf.slice(idx + 1);
15104
- if (!line.trim())
15337
+ if (!line2.trim())
15105
15338
  continue;
15106
15339
  try {
15107
- out.push(JSON.parse(line));
15340
+ out.push(JSON.parse(line2));
15108
15341
  } catch {
15109
15342
  }
15110
15343
  }
@@ -15865,9 +16098,9 @@ var init_sse_bridge = __esm({
15865
16098
  buf += decoder.decode(value, { stream: true });
15866
16099
  let nl;
15867
16100
  while ((nl = buf.indexOf("\n")) >= 0) {
15868
- const line = buf.slice(0, nl);
16101
+ const line2 = buf.slice(0, nl);
15869
16102
  buf = buf.slice(nl + 1);
15870
- this.handleLine(taskId, line);
16103
+ this.handleLine(taskId, line2);
15871
16104
  }
15872
16105
  }
15873
16106
  } finally {
@@ -15878,16 +16111,16 @@ var init_sse_bridge = __esm({
15878
16111
  }
15879
16112
  }
15880
16113
  handleLine(taskId, rawLine) {
15881
- let line = rawLine.trim();
15882
- if (!line)
16114
+ let line2 = rawLine.trim();
16115
+ if (!line2)
15883
16116
  return;
15884
- if (line.startsWith("data:"))
15885
- line = line.slice(5).trim();
15886
- if (!line.startsWith("{"))
16117
+ if (line2.startsWith("data:"))
16118
+ line2 = line2.slice(5).trim();
16119
+ if (!line2.startsWith("{"))
15887
16120
  return;
15888
16121
  let json2;
15889
16122
  try {
15890
- json2 = JSON.parse(line);
16123
+ json2 = JSON.parse(line2);
15891
16124
  } catch {
15892
16125
  return;
15893
16126
  }
@@ -16009,14 +16242,14 @@ function detectTrailingQuestion2(text) {
16009
16242
  let inFence = false;
16010
16243
  let lastLine = null;
16011
16244
  for (const raw of text.split(/\r?\n/)) {
16012
- const line = raw.trim();
16013
- if (line.startsWith("```")) {
16245
+ const line2 = raw.trim();
16246
+ if (line2.startsWith("```")) {
16014
16247
  inFence = !inFence;
16015
16248
  continue;
16016
16249
  }
16017
- if (inFence || line === "")
16250
+ if (inFence || line2 === "")
16018
16251
  continue;
16019
- lastLine = line;
16252
+ lastLine = line2;
16020
16253
  }
16021
16254
  if (lastLine && lastLine.endsWith("?"))
16022
16255
  return lastLine;
@@ -16033,12 +16266,12 @@ function readLastAssistantText(transcriptPath) {
16033
16266
  const raw = readFileSync14(transcriptPath, "utf-8");
16034
16267
  const lines = raw.split(/\r?\n/);
16035
16268
  for (let i = lines.length - 1; i >= 0; i--) {
16036
- const line = lines[i].trim();
16037
- if (!line)
16269
+ const line2 = lines[i].trim();
16270
+ if (!line2)
16038
16271
  continue;
16039
16272
  let entry;
16040
16273
  try {
16041
- entry = JSON.parse(line);
16274
+ entry = JSON.parse(line2);
16042
16275
  } catch {
16043
16276
  continue;
16044
16277
  }
@@ -16072,8 +16305,8 @@ function resolveLastAssistantText(payload) {
16072
16305
  const derived = deriveTranscriptPath(p?.session_id, cwd);
16073
16306
  if (derived)
16074
16307
  candidates.push(derived);
16075
- for (const path45 of candidates) {
16076
- const text = readLastAssistantText(path45);
16308
+ for (const path46 of candidates) {
16309
+ const text = readLastAssistantText(path46);
16077
16310
  if (text != null)
16078
16311
  return text;
16079
16312
  }
@@ -16341,9 +16574,9 @@ function isQuotedLine2(raw) {
16341
16574
  return QUOTED_PREFIX_RE2.test(noAnsi);
16342
16575
  }
16343
16576
  function stripChrome2(raw) {
16344
- let line = raw.replace(/\[[0-9;]*m/g, "");
16345
- line = line.replace(/^[\s│┃▏▕|]+/, "").replace(/[\s│┃▏▕|]+$/, "");
16346
- const trimmed = line.trim();
16577
+ let line2 = raw.replace(/\[[0-9;]*m/g, "");
16578
+ line2 = line2.replace(/^[\s│┃▏▕|]+/, "").replace(/[\s│┃▏▕|]+$/, "");
16579
+ const trimmed = line2.trim();
16347
16580
  if (trimmed === "")
16348
16581
  return null;
16349
16582
  if (PURE_CHROME_RE2.test(trimmed))
@@ -16717,13 +16950,13 @@ function buildUserEnvelope(opts) {
16717
16950
  };
16718
16951
  }
16719
16952
  function writeLine(socketPath2, envelope, deps) {
16720
- const line = `${JSON.stringify(envelope)}
16953
+ const line2 = `${JSON.stringify(envelope)}
16721
16954
  `;
16722
- if (Buffer.byteLength(line, "utf8") > MAX_LINE_BYTES) {
16955
+ if (Buffer.byteLength(line2, "utf8") > MAX_LINE_BYTES) {
16723
16956
  return Promise.resolve({
16724
16957
  ok: false,
16725
16958
  reason: "transport",
16726
- error: `line exceeds the receiver's 1 MiB buffer cap (${Buffer.byteLength(line, "utf8")} bytes)`
16959
+ error: `line exceeds the receiver's 1 MiB buffer cap (${Buffer.byteLength(line2, "utf8")} bytes)`
16727
16960
  });
16728
16961
  }
16729
16962
  return new Promise((resolve4) => {
@@ -16743,7 +16976,7 @@ function writeLine(socketPath2, envelope, deps) {
16743
16976
  done({ ok: false, reason: "transport", error: `timeout after ${deps.timeoutMs ?? DEFAULT_TIMEOUT_MS}ms` });
16744
16977
  }, deps.timeoutMs ?? DEFAULT_TIMEOUT_MS);
16745
16978
  sock.on("connect", () => {
16746
- sock.write(line, () => {
16979
+ sock.write(line2, () => {
16747
16980
  clearTimeout(timer);
16748
16981
  try {
16749
16982
  sock.end();
@@ -16920,20 +17153,20 @@ var init_receipt_listener = __esm({
16920
17153
  buf += chunk;
16921
17154
  let nl;
16922
17155
  while ((nl = buf.indexOf("\n")) !== -1) {
16923
- const line = buf.slice(0, nl);
17156
+ const line2 = buf.slice(0, nl);
16924
17157
  buf = buf.slice(nl + 1);
16925
- this.dispatch(line);
17158
+ this.dispatch(line2);
16926
17159
  }
16927
17160
  });
16928
17161
  conn.on("error", () => {
16929
17162
  });
16930
17163
  }
16931
- dispatch(line) {
16932
- if (!line.trim())
17164
+ dispatch(line2) {
17165
+ if (!line2.trim())
16933
17166
  return;
16934
17167
  let f;
16935
17168
  try {
16936
- f = JSON.parse(line);
17169
+ f = JSON.parse(line2);
16937
17170
  } catch {
16938
17171
  this.deps.log?.(`claude-receipt: discarded non-JSON frame`);
16939
17172
  return;
@@ -16962,22 +17195,22 @@ var init_receipt_listener = __esm({
16962
17195
  });
16963
17196
 
16964
17197
  // packages/agents/dist/claude/api-key-approval.js
16965
- import fs22 from "fs";
17198
+ import fs23 from "fs";
16966
17199
  import os14 from "os";
16967
- import path25 from "path";
17200
+ import path26 from "path";
16968
17201
  function ensureClaudeApiKeyApproved(apiKey, opts = {}) {
16969
17202
  const suffix = apiKey.slice(-20);
16970
17203
  if (!suffix)
16971
17204
  return { changed: false, reason: "empty api key" };
16972
- const file = opts.claudeJsonPath ?? path25.join(os14.homedir(), ".claude.json");
17205
+ const file = opts.claudeJsonPath ?? path26.join(os14.homedir(), ".claude.json");
16973
17206
  const log = opts.log ?? (() => {
16974
17207
  });
16975
- if (!fs22.existsSync(file)) {
17208
+ if (!fs23.existsSync(file)) {
16976
17209
  return { changed: false, reason: "no ~/.claude.json yet \u2014 skipping routed-key pre-approval" };
16977
17210
  }
16978
17211
  let doc;
16979
17212
  try {
16980
- doc = JSON.parse(fs22.readFileSync(file, "utf8"));
17213
+ doc = JSON.parse(fs23.readFileSync(file, "utf8"));
16981
17214
  } catch {
16982
17215
  return {
16983
17216
  changed: false,
@@ -16999,11 +17232,11 @@ function ensureClaudeApiKeyApproved(apiKey, opts = {}) {
16999
17232
  };
17000
17233
  const tmp = `${file}.squadrant-tmp`;
17001
17234
  try {
17002
- fs22.writeFileSync(tmp, JSON.stringify(doc, null, 2) + "\n", { mode: fs22.statSync(file).mode & 511 });
17003
- fs22.renameSync(tmp, file);
17235
+ fs23.writeFileSync(tmp, JSON.stringify(doc, null, 2) + "\n", { mode: fs23.statSync(file).mode & 511 });
17236
+ fs23.renameSync(tmp, file);
17004
17237
  } catch (e) {
17005
17238
  try {
17006
- fs22.unlinkSync(tmp);
17239
+ fs23.unlinkSync(tmp);
17007
17240
  } catch {
17008
17241
  }
17009
17242
  return {
@@ -17112,10 +17345,10 @@ var init_http_channel = __esm({
17112
17345
  return cached;
17113
17346
  const directory = this.directoryFor?.(taskId);
17114
17347
  const createdAfterMs = this.createdAfterFor?.(taskId);
17115
- for (const path45 of ["/session?", "/api/session?"]) {
17348
+ for (const path46 of ["/session?", "/api/session?"]) {
17116
17349
  let res;
17117
17350
  try {
17118
- res = await this.request(`http://127.0.0.1:${port}${path45}`, { method: "GET" });
17351
+ res = await this.request(`http://127.0.0.1:${port}${path46}`, { method: "GET" });
17119
17352
  } catch {
17120
17353
  return void 0;
17121
17354
  }
@@ -17391,13 +17624,13 @@ function parseDraftFromScreen(screen) {
17391
17624
  if (topHR === -1)
17392
17625
  return null;
17393
17626
  const inputLines = lines.slice(topHR + 1, bottomHR);
17394
- for (const line of inputLines) {
17627
+ for (const line2 of inputLines) {
17395
17628
  let extracted;
17396
- const boxMatch = line.match(/│\s*[>❯]\s+(.*?)\s*│/);
17629
+ const boxMatch = line2.match(/│\s*[>❯]\s+(.*?)\s*│/);
17397
17630
  if (boxMatch) {
17398
17631
  extracted = boxMatch[1].trim();
17399
17632
  } else {
17400
- const plainMatch = line.match(/^\s*[>❯]\s*(.*)$/);
17633
+ const plainMatch = line2.match(/^\s*[>❯]\s*(.*)$/);
17401
17634
  if (plainMatch)
17402
17635
  extracted = plainMatch[1].trim();
17403
17636
  }
@@ -17476,8 +17709,8 @@ function parseModalOptions(screen) {
17476
17709
  return null;
17477
17710
  const OPTION_RE3 = /^\s*(❯)?\s*(\d+)\.\s*(.*?)\s*$/;
17478
17711
  const options = [];
17479
- for (const line of lines.slice(topHR + 1, bottomHR)) {
17480
- const m = line.match(OPTION_RE3);
17712
+ for (const line2 of lines.slice(topHR + 1, bottomHR)) {
17713
+ const m = line2.match(OPTION_RE3);
17481
17714
  if (!m)
17482
17715
  continue;
17483
17716
  options.push({ index: Number(m[2]), label: m[3], highlighted: m[1] === "\u276F" });
@@ -17535,8 +17768,8 @@ function readInputBoxRaw(screen, opts) {
17535
17768
  if (topHR === -1)
17536
17769
  return null;
17537
17770
  const parts = [];
17538
- for (const line of lines.slice(topHR + 1, bottomHR)) {
17539
- let s = line.replace(/│/g, " ");
17771
+ for (const line2 of lines.slice(topHR + 1, bottomHR)) {
17772
+ let s = line2.replace(/│/g, " ");
17540
17773
  s = s.replace(/^\s*[>❯]\s?/, "");
17541
17774
  s = s.replace(/\s*[▌█▔▎▏]+\s*$/, "");
17542
17775
  parts.push(s);
@@ -18064,13 +18297,13 @@ var init_notifiers = __esm({
18064
18297
  });
18065
18298
 
18066
18299
  // packages/workspaces/dist/workspaces/obsidian.js
18067
- import fs23 from "fs/promises";
18300
+ import fs24 from "fs/promises";
18068
18301
  import { existsSync as existsSync11 } from "fs";
18069
- import path26 from "path";
18302
+ import path27 from "path";
18070
18303
  function resolveInRoot(root, relative) {
18071
- const joined = path26.resolve(root, relative);
18072
- const normalized2 = path26.resolve(root) + path26.sep;
18073
- if (joined !== path26.resolve(root) && !joined.startsWith(normalized2)) {
18304
+ const joined = path27.resolve(root, relative);
18305
+ const normalized2 = path27.resolve(root) + path27.sep;
18306
+ if (joined !== path27.resolve(root) && !joined.startsWith(normalized2)) {
18074
18307
  throw new Error(`Path '${relative}' escapes workspace root`);
18075
18308
  }
18076
18309
  return joined;
@@ -18089,16 +18322,16 @@ function createObsidianDriver(scope) {
18089
18322
  };
18090
18323
  },
18091
18324
  async read(rel) {
18092
- return fs23.readFile(resolveInRoot(root, rel), "utf-8");
18325
+ return fs24.readFile(resolveInRoot(root, rel), "utf-8");
18093
18326
  },
18094
18327
  async write(rel, content) {
18095
18328
  const abs = resolveInRoot(root, rel);
18096
- await fs23.mkdir(path26.dirname(abs), { recursive: true });
18097
- await fs23.writeFile(abs, content);
18329
+ await fs24.mkdir(path27.dirname(abs), { recursive: true });
18330
+ await fs24.writeFile(abs, content);
18098
18331
  },
18099
18332
  async exists(rel) {
18100
18333
  try {
18101
- await fs23.access(resolveInRoot(root, rel));
18334
+ await fs24.access(resolveInRoot(root, rel));
18102
18335
  return true;
18103
18336
  } catch {
18104
18337
  return false;
@@ -18106,13 +18339,13 @@ function createObsidianDriver(scope) {
18106
18339
  },
18107
18340
  async list(rel) {
18108
18341
  try {
18109
- return await fs23.readdir(resolveInRoot(root, rel));
18342
+ return await fs24.readdir(resolveInRoot(root, rel));
18110
18343
  } catch {
18111
18344
  return [];
18112
18345
  }
18113
18346
  },
18114
18347
  async mkdir(rel) {
18115
- await fs23.mkdir(resolveInRoot(root, rel), { recursive: true });
18348
+ await fs24.mkdir(resolveInRoot(root, rel), { recursive: true });
18116
18349
  }
18117
18350
  };
18118
18351
  }
@@ -18266,18 +18499,18 @@ var init_events_bridge = __esm({
18266
18499
  this.buf += typeof chunk === "string" ? chunk : chunk.toString("utf-8");
18267
18500
  let nl;
18268
18501
  while ((nl = this.buf.indexOf("\n")) >= 0) {
18269
- const line = this.buf.slice(0, nl);
18502
+ const line2 = this.buf.slice(0, nl);
18270
18503
  this.buf = this.buf.slice(nl + 1);
18271
- this.handleLine(line);
18504
+ this.handleLine(line2);
18272
18505
  }
18273
18506
  }
18274
18507
  handleLine(rawLine) {
18275
- const line = rawLine.trim();
18276
- if (!line || line[0] !== "{")
18508
+ const line2 = rawLine.trim();
18509
+ if (!line2 || line2[0] !== "{")
18277
18510
  return;
18278
18511
  let f;
18279
18512
  try {
18280
- f = JSON.parse(line);
18513
+ f = JSON.parse(line2);
18281
18514
  } catch {
18282
18515
  return;
18283
18516
  }
@@ -18526,9 +18759,9 @@ function defaultListFiles(dir) {
18526
18759
  return [];
18527
18760
  }
18528
18761
  }
18529
- function defaultReadFile(path45) {
18762
+ function defaultReadFile(path46) {
18530
18763
  try {
18531
- return readFileSync17(path45, "utf-8");
18764
+ return readFileSync17(path46, "utf-8");
18532
18765
  } catch {
18533
18766
  return void 0;
18534
18767
  }
@@ -19021,16 +19254,16 @@ function extractDetail(sub, payload) {
19021
19254
  }
19022
19255
  return void 0;
19023
19256
  }
19024
- function defaultReadFile2(path45) {
19257
+ function defaultReadFile2(path46) {
19025
19258
  try {
19026
- return readFileSync18(path45, "utf-8");
19259
+ return readFileSync18(path46, "utf-8");
19027
19260
  } catch {
19028
19261
  return void 0;
19029
19262
  }
19030
19263
  }
19031
- function defaultWriteFile(path45, content) {
19032
- mkdirSync8(path45.replace(/\/[^/]+$/, ""), { recursive: true });
19033
- writeFileSync11(path45, content, "utf-8");
19264
+ function defaultWriteFile(path46, content) {
19265
+ mkdirSync8(path46.replace(/\/[^/]+$/, ""), { recursive: true });
19266
+ writeFileSync11(path46, content, "utf-8");
19034
19267
  }
19035
19268
  var CLAUDE_HOOK_EVENTS, DEFAULT_CLI_CMD, FOREIGN_AUTO_GATE_MARKER, SUBAGENT_MODEL_KEY, SMALL_FAST_MODEL_KEY, NativeHookSource;
19036
19269
  var init_native_hook_source = __esm({
@@ -19459,9 +19692,9 @@ async function runRuntimeSend(arg1, arg2, opts, confirmOpts) {
19459
19692
  const resolved = resolveTarget(registry, config, target, !!opts.command);
19460
19693
  await needRef(resolved);
19461
19694
  const finalProject = opts.command ? config.commandName : target;
19462
- const { join: join37, dirname: dirname13 } = await import("path");
19695
+ const { join: join38, dirname: dirname13 } = await import("path");
19463
19696
  const { DEFAULT_CONFIG_PATH: DEFAULT_CONFIG_PATH2 } = await Promise.resolve().then(() => (init_dist(), dist_exports));
19464
- const stateRoot = join37(dirname13(DEFAULT_CONFIG_PATH2), "state");
19697
+ const stateRoot = join38(dirname13(DEFAULT_CONFIG_PATH2), "state");
19465
19698
  const seq2 = await appendCaptainMessage2({
19466
19699
  stateRoot,
19467
19700
  project: finalProject,
@@ -19584,7 +19817,7 @@ init_dist3();
19584
19817
  import { Command as Command40 } from "commander";
19585
19818
  import { existsSync as existsSync14, readFileSync as readFileSync21 } from "fs";
19586
19819
  import { fileURLToPath as fileURLToPath6 } from "url";
19587
- import { dirname as dirname12, join as join36 } from "path";
19820
+ import { dirname as dirname12, join as join37 } from "path";
19588
19821
  import { homedir as homedir21 } from "os";
19589
19822
 
19590
19823
  // packages/cli/src/commands/doctor.ts
@@ -19595,9 +19828,9 @@ init_dist();
19595
19828
  init_dist4();
19596
19829
  import { Command } from "commander";
19597
19830
  import { execSync as execSync7 } from "child_process";
19598
- import fs24 from "fs";
19831
+ import fs25 from "fs";
19599
19832
  import { stat } from "fs/promises";
19600
- import path27 from "path";
19833
+ import path28 from "path";
19601
19834
  import chalk3 from "chalk";
19602
19835
 
19603
19836
  // packages/cli/src/commands/health-view.ts
@@ -19699,7 +19932,7 @@ function settingsHaveAgentTeams() {
19699
19932
  try {
19700
19933
  const home = process.env.HOME || "";
19701
19934
  const settings = JSON.parse(
19702
- fs24.readFileSync(`${home}/.claude/settings.json`, "utf-8")
19935
+ fs25.readFileSync(`${home}/.claude/settings.json`, "utf-8")
19703
19936
  );
19704
19937
  return settings?.env?.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1";
19705
19938
  } catch {
@@ -19710,7 +19943,7 @@ function pluginInstalled(pluginKey) {
19710
19943
  try {
19711
19944
  const home = process.env.HOME || "";
19712
19945
  const plugins = JSON.parse(
19713
- fs24.readFileSync(
19946
+ fs25.readFileSync(
19714
19947
  `${home}/.claude/plugins/installed_plugins.json`,
19715
19948
  "utf-8"
19716
19949
  )
@@ -19734,9 +19967,9 @@ function tryGetVersion(cmd) {
19734
19967
  }
19735
19968
  function candidateGlobalInstalls(roots) {
19736
19969
  const out = [];
19737
- if (roots.npm) out.push({ manager: "npm", packageJsonPath: path27.join(roots.npm, "squadrant", "package.json") });
19738
- if (roots.pnpm) out.push({ manager: "pnpm", packageJsonPath: path27.join(roots.pnpm, "squadrant", "package.json") });
19739
- if (roots.yarn) out.push({ manager: "yarn", packageJsonPath: path27.join(roots.yarn, "node_modules", "squadrant", "package.json") });
19970
+ if (roots.npm) out.push({ manager: "npm", packageJsonPath: path28.join(roots.npm, "squadrant", "package.json") });
19971
+ if (roots.pnpm) out.push({ manager: "pnpm", packageJsonPath: path28.join(roots.pnpm, "squadrant", "package.json") });
19972
+ if (roots.yarn) out.push({ manager: "yarn", packageJsonPath: path28.join(roots.yarn, "node_modules", "squadrant", "package.json") });
19740
19973
  return out;
19741
19974
  }
19742
19975
  function findInstalledSquadrants(candidates, readVersion) {
@@ -19756,7 +19989,7 @@ ${lines.join("\n")}
19756
19989
  }
19757
19990
  function readPackageVersion(packageJsonPath) {
19758
19991
  try {
19759
- const pkg2 = JSON.parse(fs24.readFileSync(packageJsonPath, "utf-8"));
19992
+ const pkg2 = JSON.parse(fs25.readFileSync(packageJsonPath, "utf-8"));
19760
19993
  return typeof pkg2.version === "string" ? pkg2.version : null;
19761
19994
  } catch {
19762
19995
  return null;
@@ -19821,7 +20054,7 @@ var doctorCommand = new Command("doctor").description("Check system health and p
19821
20054
  ));
19822
20055
  checkOptional(
19823
20056
  "Obsidian installed",
19824
- commandExists("obsidian") || fs24.existsSync("/Applications/Obsidian.app"),
20057
+ commandExists("obsidian") || fs25.existsSync("/Applications/Obsidian.app"),
19825
20058
  "viewer for the hub vault; the vault is plain Markdown",
19826
20059
  "Install from: https://obsidian.md"
19827
20060
  );
@@ -19918,7 +20151,7 @@ var doctorCommand = new Command("doctor").description("Check system health and p
19918
20151
  const emitter = projectionRegistry.get(name);
19919
20152
  const [userDest] = emitter.destinations("user");
19920
20153
  if (!userDest) continue;
19921
- const dir = path27.dirname(userDest.path);
20154
+ const dir = path28.dirname(userDest.path);
19922
20155
  let status;
19923
20156
  try {
19924
20157
  await stat(dir);
@@ -19939,7 +20172,7 @@ var doctorCommand = new Command("doctor").description("Check system health and p
19939
20172
  results.push(
19940
20173
  check(
19941
20174
  "Squadrant config exists",
19942
- fs24.existsSync(
20175
+ fs25.existsSync(
19943
20176
  process.env.SQUADRANT_CONFIG || `${process.env.HOME}/.config/squadrant/config.json`
19944
20177
  ),
19945
20178
  "Run: squadrant init"
@@ -20023,8 +20256,8 @@ init_dist();
20023
20256
  init_dist4();
20024
20257
  init_dist();
20025
20258
  import { Command as Command2 } from "commander";
20026
- import fs25 from "fs";
20027
- import path28 from "path";
20259
+ import fs26 from "fs";
20260
+ import path29 from "path";
20028
20261
  import os15 from "os";
20029
20262
  import readline from "readline";
20030
20263
  import chalk4 from "chalk";
@@ -20275,22 +20508,22 @@ function detectClaudeAuth(probe = {}) {
20275
20508
  // packages/cli/src/commands/init.ts
20276
20509
  init_dist3();
20277
20510
  function findPackageRoot() {
20278
- let dir = path28.dirname(new URL(import.meta.url).pathname);
20511
+ let dir = path29.dirname(new URL(import.meta.url).pathname);
20279
20512
  while (dir !== "/") {
20280
- if (fs25.existsSync(path28.join(dir, "package.json"))) return dir;
20281
- dir = path28.dirname(dir);
20513
+ if (fs26.existsSync(path29.join(dir, "package.json"))) return dir;
20514
+ dir = path29.dirname(dir);
20282
20515
  }
20283
20516
  return process.cwd();
20284
20517
  }
20285
20518
  function copyDirRecursive(src, dest) {
20286
- fs25.mkdirSync(dest, { recursive: true });
20287
- for (const entry of fs25.readdirSync(src, { withFileTypes: true })) {
20288
- const srcPath = path28.join(src, entry.name);
20289
- const destPath = path28.join(dest, entry.name);
20519
+ fs26.mkdirSync(dest, { recursive: true });
20520
+ for (const entry of fs26.readdirSync(src, { withFileTypes: true })) {
20521
+ const srcPath = path29.join(src, entry.name);
20522
+ const destPath = path29.join(dest, entry.name);
20290
20523
  if (entry.isDirectory()) {
20291
20524
  copyDirRecursive(srcPath, destPath);
20292
20525
  } else {
20293
- fs25.copyFileSync(srcPath, destPath);
20526
+ fs26.copyFileSync(srcPath, destPath);
20294
20527
  }
20295
20528
  }
20296
20529
  }
@@ -20332,7 +20565,7 @@ function warnIfNoAnthropic(preset, auth) {
20332
20565
  var initCommand = new Command2("init").description("Guided first-time setup: provider, hub vault, agents, plugins, projects (re-run-safe)").option("--hub <path>", "Hub vault path", "~/squadrant-hub").option("--preset <id>", "provider preset: a|b|c (non-interactive; d accepted as a deprecated alias for c)").action(async (opts) => {
20333
20566
  const hubPath = resolveHome(opts.hub);
20334
20567
  const pkgRoot = findPackageRoot();
20335
- const configDir = path28.join(os15.homedir(), ".config", "squadrant");
20568
+ const configDir = path29.join(os15.homedir(), ".config", "squadrant");
20336
20569
  const isTTY = process.stdin.isTTY === true;
20337
20570
  console.log(chalk4.bold("\nSquadrant Init\n"));
20338
20571
  let explicitPreset;
@@ -20370,8 +20603,8 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
20370
20603
  }
20371
20604
  const wsRegistry = new WorkspaceRegistry({ obsidian: createObsidianDriver });
20372
20605
  try {
20373
- if (fs25.existsSync(DEFAULT_CONFIG_PATH)) {
20374
- const existing = JSON.parse(fs25.readFileSync(DEFAULT_CONFIG_PATH, "utf-8"));
20606
+ if (fs26.existsSync(DEFAULT_CONFIG_PATH)) {
20607
+ const existing = JSON.parse(fs26.readFileSync(DEFAULT_CONFIG_PATH, "utf-8"));
20375
20608
  wsRegistry.get(existing.workspace ?? "obsidian");
20376
20609
  }
20377
20610
  } catch (err) {
@@ -20379,7 +20612,7 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
20379
20612
  return;
20380
20613
  }
20381
20614
  stepHeader(1, 5, "Hub vault");
20382
- const configExists = fs25.existsSync(DEFAULT_CONFIG_PATH);
20615
+ const configExists = fs26.existsSync(DEFAULT_CONFIG_PATH);
20383
20616
  let config;
20384
20617
  if (configExists) {
20385
20618
  console.log(chalk4.yellow(" \u26A0 Config already exists, skipping creation"));
@@ -20417,37 +20650,37 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
20417
20650
  saveConfig(config);
20418
20651
  console.log(chalk4.green(` \u2714 Config updated at ${DEFAULT_CONFIG_PATH}`));
20419
20652
  }
20420
- const hubTemplate = path28.join(pkgRoot, "obsidian", "hub");
20421
- if (fs25.existsSync(hubPath)) {
20653
+ const hubTemplate = path29.join(pkgRoot, "obsidian", "hub");
20654
+ if (fs26.existsSync(hubPath)) {
20422
20655
  console.log(chalk4.yellow(` \u26A0 Hub vault already exists at ${hubPath}`));
20423
- } else if (fs25.existsSync(hubTemplate)) {
20656
+ } else if (fs26.existsSync(hubTemplate)) {
20424
20657
  copyDirRecursive(hubTemplate, hubPath);
20425
20658
  console.log(chalk4.green(` \u2714 Hub vault scaffolded at ${hubPath}`));
20426
20659
  } else {
20427
- fs25.mkdirSync(hubPath, { recursive: true });
20660
+ fs26.mkdirSync(hubPath, { recursive: true });
20428
20661
  console.log(chalk4.yellow(` \u26A0 Hub template not found; created empty directory at ${hubPath}`));
20429
20662
  }
20430
- const hubDashboardSrc = path28.join(pkgRoot, "obsidian", "hub", "dashboard.md");
20431
- const hubDashboardDest = path28.join(hubPath, "dashboard.md");
20432
- if (fs25.existsSync(hubDashboardSrc)) {
20433
- fs25.copyFileSync(hubDashboardSrc, hubDashboardDest);
20663
+ const hubDashboardSrc = path29.join(pkgRoot, "obsidian", "hub", "dashboard.md");
20664
+ const hubDashboardDest = path29.join(hubPath, "dashboard.md");
20665
+ if (fs26.existsSync(hubDashboardSrc)) {
20666
+ fs26.copyFileSync(hubDashboardSrc, hubDashboardDest);
20434
20667
  console.log(chalk4.green(` \u2714 Dashboard refreshed`));
20435
20668
  }
20436
- fs25.mkdirSync(path28.join(hubPath, "projects"), { recursive: true });
20669
+ fs26.mkdirSync(path29.join(hubPath, "projects"), { recursive: true });
20437
20670
  ensureRuntimeSynced({ sourceRoot: pkgRoot, runtimeRoot: configDir });
20438
20671
  console.log(chalk4.green(` \u2714 Runtime assets synced to ${configDir}`));
20439
20672
  stepHeader(2, 5, "Agent + projection setup");
20440
- const settingsPath = path28.join(os15.homedir(), ".claude", "settings.json");
20673
+ const settingsPath = path29.join(os15.homedir(), ".claude", "settings.json");
20441
20674
  try {
20442
20675
  let settings = {};
20443
- if (fs25.existsSync(settingsPath)) {
20444
- settings = JSON.parse(fs25.readFileSync(settingsPath, "utf-8"));
20676
+ if (fs26.existsSync(settingsPath)) {
20677
+ settings = JSON.parse(fs26.readFileSync(settingsPath, "utf-8"));
20445
20678
  }
20446
20679
  const env = settings.env || {};
20447
20680
  if (env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS !== "1") {
20448
20681
  settings.env = { ...env, CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1" };
20449
- fs25.mkdirSync(path28.dirname(settingsPath), { recursive: true });
20450
- fs25.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
20682
+ fs26.mkdirSync(path29.dirname(settingsPath), { recursive: true });
20683
+ fs26.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
20451
20684
  console.log(chalk4.green(" \u2714 Agent Teams enabled in ~/.claude/settings.json"));
20452
20685
  } else {
20453
20686
  console.log(chalk4.green(" \u2714 Agent Teams already enabled"));
@@ -20500,7 +20733,7 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
20500
20733
  chalk4.cyan(" Absolute path to your first project (Enter to skip): ")
20501
20734
  );
20502
20735
  if (projectPath) {
20503
- const projectName = path28.basename(projectPath);
20736
+ const projectName = path29.basename(projectPath);
20504
20737
  console.log(chalk4.bold(`
20505
20738
  Run this to register it:`));
20506
20739
  console.log(chalk4.cyan(` squadrant projects add ${projectName} ${projectPath}
@@ -20528,8 +20761,8 @@ var initCommand = new Command2("init").description("Guided first-time setup: pro
20528
20761
  init_dist();
20529
20762
  init_dist2();
20530
20763
  import { Command as Command3 } from "commander";
20531
- import fs26 from "fs";
20532
- import path29 from "path";
20764
+ import fs27 from "fs";
20765
+ import path30 from "path";
20533
20766
  import chalk5 from "chalk";
20534
20767
  function restartAfterProjectsAdd(opts) {
20535
20768
  const doRestart = opts.doRestart ?? restartDaemonIfRunning;
@@ -20541,22 +20774,22 @@ function restartAfterProjectsAdd(opts) {
20541
20774
  }
20542
20775
  }
20543
20776
  function findPackageRoot2() {
20544
- let dir = path29.dirname(new URL(import.meta.url).pathname);
20777
+ let dir = path30.dirname(new URL(import.meta.url).pathname);
20545
20778
  while (dir !== "/") {
20546
- if (fs26.existsSync(path29.join(dir, "package.json"))) return dir;
20547
- dir = path29.dirname(dir);
20779
+ if (fs27.existsSync(path30.join(dir, "package.json"))) return dir;
20780
+ dir = path30.dirname(dir);
20548
20781
  }
20549
20782
  return process.cwd();
20550
20783
  }
20551
20784
  function copyDirRecursive2(src, dest) {
20552
- fs26.mkdirSync(dest, { recursive: true });
20553
- for (const entry of fs26.readdirSync(src, { withFileTypes: true })) {
20554
- const srcPath = path29.join(src, entry.name);
20555
- const destPath = path29.join(dest, entry.name);
20785
+ fs27.mkdirSync(dest, { recursive: true });
20786
+ for (const entry of fs27.readdirSync(src, { withFileTypes: true })) {
20787
+ const srcPath = path30.join(src, entry.name);
20788
+ const destPath = path30.join(dest, entry.name);
20556
20789
  if (entry.isDirectory()) {
20557
20790
  copyDirRecursive2(srcPath, destPath);
20558
20791
  } else {
20559
- fs26.copyFileSync(srcPath, destPath);
20792
+ fs27.copyFileSync(srcPath, destPath);
20560
20793
  }
20561
20794
  }
20562
20795
  }
@@ -20592,7 +20825,7 @@ var addCmd = new Command3("add").description("Register a project").argument("<na
20592
20825
  process.exit(1);
20593
20826
  }
20594
20827
  const resolvedPath = resolveHome(projectPath);
20595
- if (!fs26.existsSync(path29.join(resolvedPath, ".git"))) {
20828
+ if (!fs27.existsSync(path30.join(resolvedPath, ".git"))) {
20596
20829
  console.log(chalk5.yellow(`
20597
20830
  \u26A0 No .git found at ${resolvedPath}. Make sure this is the project root, not a parent directory.
20598
20831
  `));
@@ -20645,7 +20878,7 @@ var addCmd = new Command3("add").description("Register a project").argument("<na
20645
20878
  \u26A0 Group '${group}' already has '${primary[0]}' as primary. Overriding.`));
20646
20879
  }
20647
20880
  }
20648
- const spokeVault = opts.spoke ? resolveHome(opts.spoke) : path29.join(config.hubVault, "spokes", name);
20881
+ const spokeVault = opts.spoke ? resolveHome(opts.spoke) : path30.join(config.hubVault, "spokes", name);
20649
20882
  const project = {
20650
20883
  path: resolvedPath,
20651
20884
  captainName,
@@ -20660,20 +20893,20 @@ var addCmd = new Command3("add").description("Register a project").argument("<na
20660
20893
  \u2714 Project '${name}' registered`));
20661
20894
  restartAfterProjectsAdd({ noRestart: opts.restart === false });
20662
20895
  const pkgRoot = findPackageRoot2();
20663
- const spokeTemplate = path29.join(pkgRoot, "obsidian", "spoke");
20664
- if (fs26.existsSync(spokeVault)) {
20896
+ const spokeTemplate = path30.join(pkgRoot, "obsidian", "spoke");
20897
+ if (fs27.existsSync(spokeVault)) {
20665
20898
  console.log(chalk5.yellow(` \u26A0 Spoke vault already exists at ${spokeVault}, skipping scaffold`));
20666
- } else if (fs26.existsSync(spokeTemplate)) {
20899
+ } else if (fs27.existsSync(spokeTemplate)) {
20667
20900
  copyDirRecursive2(spokeTemplate, spokeVault);
20668
- const statusPath = path29.join(spokeVault, "status.md");
20669
- if (fs26.existsSync(statusPath)) {
20670
- const content = fs26.readFileSync(statusPath, "utf-8");
20901
+ const statusPath = path30.join(spokeVault, "status.md");
20902
+ if (fs27.existsSync(statusPath)) {
20903
+ const content = fs27.readFileSync(statusPath, "utf-8");
20671
20904
  const updated = content.replace(/^project: unnamed/m, `project: ${name}`);
20672
- fs26.writeFileSync(statusPath, updated);
20905
+ fs27.writeFileSync(statusPath, updated);
20673
20906
  }
20674
20907
  console.log(chalk5.green(` \u2714 Spoke vault scaffolded at ${spokeVault}`));
20675
20908
  } else {
20676
- fs26.mkdirSync(spokeVault, { recursive: true });
20909
+ fs27.mkdirSync(spokeVault, { recursive: true });
20677
20910
  console.log(chalk5.yellow(` \u26A0 Spoke template not found; created empty dir at ${spokeVault}`));
20678
20911
  }
20679
20912
  console.log("");
@@ -20742,10 +20975,10 @@ init_dist3();
20742
20975
  init_dist();
20743
20976
  import { Command as Command5 } from "commander";
20744
20977
  import { execSync as execSync9 } from "child_process";
20745
- import path30 from "path";
20978
+ import path31 from "path";
20746
20979
  import os16 from "os";
20747
20980
  import chalk7 from "chalk";
20748
- var TEMPLATES_DIR2 = path30.join(os16.homedir(), ".config", "squadrant", "templates");
20981
+ var TEMPLATES_DIR2 = path31.join(os16.homedir(), ".config", "squadrant", "templates");
20749
20982
  var TASK_PROMPTS = {
20750
20983
  briefing: "Run your daily briefing using the squadrant:command-ops skill. Read all spoke handoffs, yesterday's logs, current status; produce a concise cross-project briefing; save to {hubVault}/daily-logs/YYYY-MM-DD.md; then exit.",
20751
20984
  "learnings-review": "Run a learnings review using the squadrant:command-ops skill. Scan {spokeVault}/learnings across all projects, identify cross-project patterns, propose captured-skill or fix actions, and exit when done.",
@@ -20778,7 +21011,7 @@ async function runCommandSpawn(input) {
20778
21011
  if (!agent) {
20779
21012
  throw new Error(`Unknown agent '${agentName}'. Known: claude, codex, gemini, opencode.`);
20780
21013
  }
20781
- const promptFile = path30.join(TEMPLATES_DIR2, `command.${agent.templateSuffix}.md`);
21014
+ const promptFile = path31.join(TEMPLATES_DIR2, `command.${agent.templateSuffix}.md`);
20782
21015
  const cliCommand = agent.buildCommand({
20783
21016
  prompt,
20784
21017
  workdir: process.cwd(),
@@ -20834,10 +21067,10 @@ function tailLines(text, maxLines = 40, maxBytes = 4096) {
20834
21067
  if (Buffer.byteLength(result, "utf-8") > maxBytes) {
20835
21068
  const truncated = [];
20836
21069
  let bytes = 0;
20837
- for (const line of kept) {
20838
- const lineBytes = Buffer.byteLength(line, "utf-8") + 1;
21070
+ for (const line2 of kept) {
21071
+ const lineBytes = Buffer.byteLength(line2, "utf-8") + 1;
20839
21072
  if (bytes + lineBytes > maxBytes) break;
20840
- truncated.push(line);
21073
+ truncated.push(line2);
20841
21074
  bytes += lineBytes;
20842
21075
  }
20843
21076
  result = truncated.join("\n");
@@ -21687,7 +21920,7 @@ async function runCrewSend2(project, name, message, opts) {
21687
21920
  socketPathFor: (taskId) => tasks.find((t) => t.id === taskId)?.messagingSocketPath,
21688
21921
  sessionIdFor: (taskId) => tasks.find((t) => t.id === taskId)?.sessionId,
21689
21922
  statusFor: (taskId) => readClaudeStatus(tasks.find((t) => t.id === taskId)),
21690
- wire: (p, e) => writeLine(p, e, { connect: (path45) => netConnect(path45) }),
21923
+ wire: (p, e) => writeLine(p, e, { connect: (path46) => netConnect(path46) }),
21691
21924
  receipts,
21692
21925
  newMsgId: () => randomUUID6(),
21693
21926
  sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
@@ -22074,11 +22307,11 @@ init_dist4();
22074
22307
  init_dist();
22075
22308
  init_dist2();
22076
22309
  import { Command as Command12 } from "commander";
22077
- import fs27 from "fs";
22078
- import path31 from "path";
22310
+ import fs28 from "fs";
22311
+ import path32 from "path";
22079
22312
  import os17 from "os";
22080
22313
  import chalk12 from "chalk";
22081
- var TEMPLATES_DIR3 = path31.join(os17.homedir(), ".config", "squadrant", "templates");
22314
+ var TEMPLATES_DIR3 = path32.join(os17.homedir(), ".config", "squadrant", "templates");
22082
22315
  async function runSideSpawn2(input) {
22083
22316
  const config = loadConfig();
22084
22317
  const proj = config.projects[input.project];
@@ -22103,7 +22336,7 @@ async function runSideSpawn2(input) {
22103
22336
  }
22104
22337
  const sideModel = sideRole?.model;
22105
22338
  const sideThinking = sideRole?.thinking;
22106
- const promptFile = path31.join(
22339
+ const promptFile = path32.join(
22107
22340
  TEMPLATES_DIR3,
22108
22341
  `side.${input.role}.${agent.templateSuffix}.md`
22109
22342
  );
@@ -22111,7 +22344,7 @@ async function runSideSpawn2(input) {
22111
22344
  prompt: input.topic,
22112
22345
  workdir: spawnCwd,
22113
22346
  role: "side",
22114
- promptFile: fs27.existsSync(promptFile) ? promptFile : void 0,
22347
+ promptFile: fs28.existsSync(promptFile) ? promptFile : void 0,
22115
22348
  interactive: true,
22116
22349
  permissionMode: config.defaults.permissions?.crew ?? "auto",
22117
22350
  ...sideModel ? { model: sideModel } : {},
@@ -22330,9 +22563,9 @@ function formatAge(lastChecked, now) {
22330
22563
  return "stale";
22331
22564
  }
22332
22565
  function firstLine(s) {
22333
- for (const line of s.split(/\r?\n/)) {
22334
- if (line.trim().length > 0)
22335
- return line.trim();
22566
+ for (const line2 of s.split(/\r?\n/)) {
22567
+ if (line2.trim().length > 0)
22568
+ return line2.trim();
22336
22569
  }
22337
22570
  return "";
22338
22571
  }
@@ -22374,8 +22607,8 @@ function renderDashboard(rows, opts) {
22374
22607
 
22375
22608
  // packages/web/dist/sync-hub.js
22376
22609
  init_dist();
22377
- import fs28 from "fs";
22378
- import path32 from "path";
22610
+ import fs29 from "fs";
22611
+ import path33 from "path";
22379
22612
  function buildMirrorMarkdown(s) {
22380
22613
  const fenced = "```";
22381
22614
  return [
@@ -22401,15 +22634,15 @@ function buildMirrorMarkdown(s) {
22401
22634
  function syncHub(deps) {
22402
22635
  if (!deps.config.hubVault)
22403
22636
  return [];
22404
- const writeFile6 = deps.writeFile ?? ((p, c) => fs28.writeFileSync(p, c));
22405
- const mkdir6 = deps.mkdir ?? ((p) => fs28.mkdirSync(p, { recursive: true }));
22406
- const projectsDir = path32.join(resolveHome(deps.config.hubVault), "projects");
22637
+ const writeFile6 = deps.writeFile ?? ((p, c) => fs29.writeFileSync(p, c));
22638
+ const mkdir6 = deps.mkdir ?? ((p) => fs29.mkdirSync(p, { recursive: true }));
22639
+ const projectsDir = path33.join(resolveHome(deps.config.hubVault), "projects");
22407
22640
  mkdir6(projectsDir);
22408
22641
  const out = [];
22409
22642
  for (const s of deps.statuses) {
22410
22643
  if (s.state === "unknown")
22411
22644
  continue;
22412
- const hubPath = path32.join(projectsDir, `${s.project}.md`);
22645
+ const hubPath = path33.join(projectsDir, `${s.project}.md`);
22413
22646
  try {
22414
22647
  writeFile6(hubPath, buildMirrorMarkdown(s));
22415
22648
  out.push({ project: s.project, hubPath });
@@ -23415,18 +23648,18 @@ function renderHtml(snap, opts = {}) {
23415
23648
  import { closeSync as closeSync3, openSync as openSync3, readSync as readSync2, statSync as statSync4 } from "fs";
23416
23649
  var LOG_TAIL_BYTES = 256 * 1024;
23417
23650
  var LOG_RING_SIZE = 1e3;
23418
- function defaultSize(path45) {
23651
+ function defaultSize(path46) {
23419
23652
  try {
23420
- return statSync4(path45).size;
23653
+ return statSync4(path46).size;
23421
23654
  } catch {
23422
23655
  return 0;
23423
23656
  }
23424
23657
  }
23425
- function defaultRead(path45, start, len) {
23658
+ function defaultRead(path46, start, len) {
23426
23659
  if (len <= 0)
23427
23660
  return "";
23428
23661
  try {
23429
- const fd = openSync3(path45, "r");
23662
+ const fd = openSync3(path46, "r");
23430
23663
  try {
23431
23664
  const buf = Buffer.alloc(len);
23432
23665
  const n = readSync2(fd, buf, 0, len, start);
@@ -23446,8 +23679,8 @@ var LogTailer = class {
23446
23679
  ring = [];
23447
23680
  size;
23448
23681
  read;
23449
- constructor(path45, ringSize = LOG_RING_SIZE, deps = {}) {
23450
- this.path = path45;
23682
+ constructor(path46, ringSize = LOG_RING_SIZE, deps = {}) {
23683
+ this.path = path46;
23451
23684
  this.ringSize = ringSize;
23452
23685
  this.size = deps.size ?? defaultSize;
23453
23686
  this.read = deps.read ?? defaultRead;
@@ -23723,8 +23956,8 @@ init_dist4();
23723
23956
  init_dist2();
23724
23957
  import { Command as Command14 } from "commander";
23725
23958
  import { execSync as execSync11, execFileSync as execFileSync11 } from "child_process";
23726
- import fs29 from "fs";
23727
- import path33 from "path";
23959
+ import fs30 from "fs";
23960
+ import path34 from "path";
23728
23961
  import os18 from "os";
23729
23962
  import chalk15 from "chalk";
23730
23963
 
@@ -23817,8 +24050,8 @@ function resolveLaunchBackend(o) {
23817
24050
  // packages/cli/src/commands/launch.ts
23818
24051
  init_dist2();
23819
24052
  var CMUX_APP = "/Applications/cmux.app";
23820
- var TEMPLATES_DIR4 = path33.join(os18.homedir(), ".config", "squadrant", "templates");
23821
- var SESSIONS_PATH2 = path33.join(os18.homedir(), ".config", "squadrant", "sessions.json");
24053
+ var TEMPLATES_DIR4 = path34.join(os18.homedir(), ".config", "squadrant", "templates");
24054
+ var SESSIONS_PATH2 = path34.join(os18.homedir(), ".config", "squadrant", "sessions.json");
23822
24055
  function shouldWireCaptainChannel(agentName, config) {
23823
24056
  return agentName === "claude" && resolveCaptainChannelMode(config.defaults) !== "off";
23824
24057
  }
@@ -23915,7 +24148,7 @@ var launchCommand = new Command14("launch").description(
23915
24148
  initialPrompt = "Run your startup checklist: use the squadrant:command-ops skill, complete your daily briefing, then report ready.";
23916
24149
  }
23917
24150
  const runtime = projectName ? runtimes.forProject(projectName, config) : runtimes.global(config);
23918
- const stateRoot = path33.join(os18.homedir(), ".config", "squadrant", "state");
24151
+ const stateRoot = path34.join(os18.homedir(), ".config", "squadrant", "state");
23919
24152
  const isOpencodeCaptain = role === "captain" && agentName === "opencode" && !!projectName;
23920
24153
  if (isOpencodeCaptain && !isOpencodeCaptainDir(cwd)) {
23921
24154
  console.error(chalk15.red(`
@@ -24068,12 +24301,12 @@ var launchCommand = new Command14("launch").description(
24068
24301
  }
24069
24302
  if (opts.all) {
24070
24303
  const hubPath = resolveHome(config.hubVault);
24071
- fs29.mkdirSync(hubPath, { recursive: true });
24304
+ fs30.mkdirSync(hubPath, { recursive: true });
24072
24305
  console.log(chalk15.bold("\nLaunching all captain workspaces\n"));
24073
24306
  for (const [name, proj] of Object.entries(config.projects)) {
24074
24307
  const projPath = resolveHome(proj.path);
24075
24308
  const spokePath = resolveHome(proj.spokeVault);
24076
- if (!fs29.existsSync(spokePath)) {
24309
+ if (!fs30.existsSync(spokePath)) {
24077
24310
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(name, config);
24078
24311
  await ensureSpokeLayout(spokeDriver);
24079
24312
  console.log(chalk15.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -24111,7 +24344,7 @@ Launching ${selected.length} captain workspace(s) in parallel
24111
24344
  const proj = config.projects[name];
24112
24345
  const projPath = resolveHome(proj.path);
24113
24346
  const spokePath = resolveHome(proj.spokeVault);
24114
- if (!fs29.existsSync(spokePath)) {
24347
+ if (!fs30.existsSync(spokePath)) {
24115
24348
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(name, config);
24116
24349
  await ensureSpokeLayout(spokeDriver);
24117
24350
  console.log(chalk15.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -24135,7 +24368,7 @@ Launching ${selected.length} captain workspace(s) in parallel
24135
24368
  const proj = config.projects[project];
24136
24369
  const projPath = resolveHome(proj.path);
24137
24370
  const spokePath = resolveHome(proj.spokeVault);
24138
- if (!fs29.existsSync(spokePath)) {
24371
+ if (!fs30.existsSync(spokePath)) {
24139
24372
  const spokeDriver = new WorkspaceRegistry({ obsidian: createObsidianDriver }).forProject(project, config);
24140
24373
  await ensureSpokeLayout(spokeDriver);
24141
24374
  console.log(chalk15.cyan(` \u2714 Created spoke vault at ${spokePath}`));
@@ -24271,24 +24504,24 @@ Shutting down captain workspace for '${project}'...
24271
24504
  // packages/cli/src/commands/feedback.ts
24272
24505
  init_dist();
24273
24506
  import { Command as Command16 } from "commander";
24274
- import fs30 from "fs";
24507
+ import fs31 from "fs";
24275
24508
  import os19 from "os";
24276
- import path34 from "path";
24509
+ import path35 from "path";
24277
24510
  import { fileURLToPath as fileURLToPath3 } from "url";
24278
24511
  import { execSync as execSync12 } from "child_process";
24279
24512
  import chalk17 from "chalk";
24280
24513
  var REPO_URL = "https://github.com/tu11aa/squadrant";
24281
24514
  function readPkgVersion() {
24282
24515
  try {
24283
- const pkgPath = path34.join(path34.dirname(fileURLToPath3(import.meta.url)), "..", "package.json");
24284
- return JSON.parse(fs30.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
24516
+ const pkgPath = path35.join(path35.dirname(fileURLToPath3(import.meta.url)), "..", "package.json");
24517
+ return JSON.parse(fs31.readFileSync(pkgPath, "utf-8")).version ?? "unknown";
24285
24518
  } catch {
24286
24519
  return "unknown";
24287
24520
  }
24288
24521
  }
24289
24522
  function readMetrics(metricsPath) {
24290
24523
  try {
24291
- return JSON.parse(fs30.readFileSync(metricsPath, "utf-8"));
24524
+ return JSON.parse(fs31.readFileSync(metricsPath, "utf-8"));
24292
24525
  } catch {
24293
24526
  return {};
24294
24527
  }
@@ -24326,7 +24559,7 @@ function buildIssueUrl(metrics, squadrantVersion) {
24326
24559
  }
24327
24560
  var feedbackCommand = new Command16("feedback").description("Open a pre-filled GitHub issue for feedback or bug reports").action(() => {
24328
24561
  const config = loadConfig();
24329
- const metricsPath = config.metrics?.path || path34.join(os19.homedir(), ".config", "squadrant", "metrics.json");
24562
+ const metricsPath = config.metrics?.path || path35.join(os19.homedir(), ".config", "squadrant", "metrics.json");
24330
24563
  const metrics = readMetrics(metricsPath);
24331
24564
  const version = readStamp(config) ?? readPkgVersion();
24332
24565
  const issueUrl = buildIssueUrl(metrics, version);
@@ -24626,9 +24859,9 @@ workspaceCommand.command("read").description("Print the contents of a scope-rela
24626
24859
  const config = loadConfig();
24627
24860
  const registry = buildRegistry2();
24628
24861
  try {
24629
- const { projectTarget, path: path45 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24862
+ const { projectTarget, path: path46 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24630
24863
  const driver = resolveDriver(registry, config, projectTarget, !!opts.hub);
24631
- const content = await driver.read(path45);
24864
+ const content = await driver.read(path46);
24632
24865
  process.stdout.write(content);
24633
24866
  } catch (err) {
24634
24867
  console.error(chalk20.red(err.message));
@@ -24640,26 +24873,26 @@ workspaceCommand.command("write").description("Write content to a scope-relative
24640
24873
  const registry = buildRegistry2();
24641
24874
  try {
24642
24875
  let projectTarget;
24643
- let path45;
24876
+ let path46;
24644
24877
  let rawContent;
24645
24878
  if (opts.hub) {
24646
24879
  if (arg3 !== void 0) {
24647
24880
  throw new Error("With --hub, pass only the path and content");
24648
24881
  }
24649
24882
  projectTarget = void 0;
24650
- path45 = arg1;
24883
+ path46 = arg1;
24651
24884
  rawContent = arg2;
24652
24885
  } else {
24653
24886
  if (arg3 === void 0) {
24654
24887
  throw new Error("Missing content \u2014 usage: <project> <path> <content>");
24655
24888
  }
24656
24889
  projectTarget = arg1;
24657
- path45 = arg2;
24890
+ path46 = arg2;
24658
24891
  rawContent = arg3;
24659
24892
  }
24660
24893
  const driver = resolveDriver(registry, config, projectTarget, !!opts.hub);
24661
24894
  const payload = rawContent === "-" ? await readStdin() : rawContent;
24662
- await driver.write(path45, payload);
24895
+ await driver.write(path46, payload);
24663
24896
  } catch (err) {
24664
24897
  console.error(chalk20.red(err.message));
24665
24898
  process.exit(1);
@@ -24669,9 +24902,9 @@ workspaceCommand.command("list").description("List entries in a scope-relative d
24669
24902
  const config = loadConfig();
24670
24903
  const registry = buildRegistry2();
24671
24904
  try {
24672
- const { projectTarget, path: path45 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24905
+ const { projectTarget, path: path46 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24673
24906
  const driver = resolveDriver(registry, config, projectTarget, !!opts.hub);
24674
- const entries = await driver.list(path45);
24907
+ const entries = await driver.list(path46);
24675
24908
  for (const entry of entries) console.log(entry);
24676
24909
  } catch (err) {
24677
24910
  console.error(chalk20.red(err.message));
@@ -24682,9 +24915,9 @@ workspaceCommand.command("exists").description("Exit 0 if path exists, 1 if not"
24682
24915
  const config = loadConfig();
24683
24916
  const registry = buildRegistry2();
24684
24917
  try {
24685
- const { projectTarget, path: path45 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24918
+ const { projectTarget, path: path46 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24686
24919
  const driver = resolveDriver(registry, config, projectTarget, !!opts.hub);
24687
- const ok2 = await driver.exists(path45);
24920
+ const ok2 = await driver.exists(path46);
24688
24921
  process.exit(ok2 ? 0 : 1);
24689
24922
  } catch (err) {
24690
24923
  console.error(chalk20.red(err.message));
@@ -24695,9 +24928,9 @@ workspaceCommand.command("mkdir").description("Recursively create a scope-relati
24695
24928
  const config = loadConfig();
24696
24929
  const registry = buildRegistry2();
24697
24930
  try {
24698
- const { projectTarget, path: path45 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24931
+ const { projectTarget, path: path46 } = resolveTargetAndPath(arg1, arg2, !!opts.hub);
24699
24932
  const driver = resolveDriver(registry, config, projectTarget, !!opts.hub);
24700
- await driver.mkdir(path45);
24933
+ await driver.mkdir(path46);
24701
24934
  } catch (err) {
24702
24935
  console.error(chalk20.red(err.message));
24703
24936
  process.exit(1);
@@ -24736,8 +24969,8 @@ init_dist4();
24736
24969
  init_dist();
24737
24970
  import { Command as Command21 } from "commander";
24738
24971
  import chalk22 from "chalk";
24739
- import fs31 from "fs";
24740
- import path35 from "path";
24972
+ import fs32 from "fs";
24973
+ import path36 from "path";
24741
24974
  import { fileURLToPath as fileURLToPath4 } from "url";
24742
24975
  function parseScope(v2) {
24743
24976
  if (v2 !== "user" && v2 !== "project") {
@@ -24746,10 +24979,10 @@ function parseScope(v2) {
24746
24979
  return v2;
24747
24980
  }
24748
24981
  function findPackageRoot3() {
24749
- let dir = path35.dirname(fileURLToPath4(import.meta.url));
24982
+ let dir = path36.dirname(fileURLToPath4(import.meta.url));
24750
24983
  while (dir !== "/" && dir !== "") {
24751
- if (fs31.existsSync(path35.join(dir, "package.json"))) return dir;
24752
- dir = path35.dirname(dir);
24984
+ if (fs32.existsSync(path36.join(dir, "package.json"))) return dir;
24985
+ dir = path36.dirname(dir);
24753
24986
  }
24754
24987
  return process.cwd();
24755
24988
  }
@@ -24945,12 +25178,12 @@ init_dist();
24945
25178
  init_dist();
24946
25179
  init_dist2();
24947
25180
  import { Command as Command23 } from "commander";
24948
- import fs32 from "fs";
25181
+ import fs33 from "fs";
24949
25182
  import { fileURLToPath as fileURLToPath5 } from "url";
24950
25183
  import { dirname as dirname8, join as join30 } from "path";
24951
25184
  import chalk23 from "chalk";
24952
25185
  function runConfigCheck(opts) {
24953
- const raw = JSON.parse(fs32.readFileSync(opts.configPath, "utf-8"));
25186
+ const raw = JSON.parse(fs33.readFileSync(opts.configPath, "utf-8"));
24954
25187
  const def = getDefaultConfig();
24955
25188
  const items = detectDrift(raw, def);
24956
25189
  let working = raw;
@@ -25038,7 +25271,7 @@ function printItems(items) {
25038
25271
  var configCommand = new Command23("config").description("Inspect and reconcile squadrant config");
25039
25272
  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) => {
25040
25273
  const pkgVersion = readPkgVersion2();
25041
- if (!fs32.existsSync(DEFAULT_CONFIG_PATH)) {
25274
+ if (!fs33.existsSync(DEFAULT_CONFIG_PATH)) {
25042
25275
  console.log(chalk23.yellow("No config found \u2014 run `squadrant init` first."));
25043
25276
  return;
25044
25277
  }
@@ -25084,7 +25317,7 @@ configCommand.command("set").description("Write a config value by dotted key (e.
25084
25317
  });
25085
25318
  function readPkgVersion2() {
25086
25319
  const pkgPath = join30(dirname8(fileURLToPath5(import.meta.url)), "..", "package.json");
25087
- return JSON.parse(fs32.readFileSync(pkgPath, "utf-8")).version;
25320
+ return JSON.parse(fs33.readFileSync(pkgPath, "utf-8")).version;
25088
25321
  }
25089
25322
 
25090
25323
  // packages/cli/src/commands/heal.ts
@@ -25424,7 +25657,7 @@ import chalk28 from "chalk";
25424
25657
  init_dist3();
25425
25658
  init_dist2();
25426
25659
  import { createServer as createServer6, connect as netConnect2 } from "net";
25427
- import fs33 from "fs";
25660
+ import fs34 from "fs";
25428
25661
  import { join as join32 } from "path";
25429
25662
  import { randomUUID as randomUUID7 } from "crypto";
25430
25663
  import chalk27 from "chalk";
@@ -25432,15 +25665,15 @@ var shared;
25432
25665
  var registryEntryPath = () => join32(CLAUDE_SESSIONS_DIR, `${process.pid}.json`);
25433
25666
  function unregisterSenderIdentity() {
25434
25667
  try {
25435
- fs33.unlinkSync(registryEntryPath());
25668
+ fs34.unlinkSync(registryEntryPath());
25436
25669
  } catch {
25437
25670
  }
25438
25671
  }
25439
25672
  function registerSenderIdentity(socketPath2) {
25440
25673
  try {
25441
25674
  unregisterSenderIdentity();
25442
- fs33.mkdirSync(CLAUDE_SESSIONS_DIR, { recursive: true });
25443
- fs33.writeFileSync(
25675
+ fs34.mkdirSync(CLAUDE_SESSIONS_DIR, { recursive: true });
25676
+ fs34.writeFileSync(
25444
25677
  registryEntryPath(),
25445
25678
  JSON.stringify({
25446
25679
  pid: process.pid,
@@ -25466,7 +25699,7 @@ async function sharedReceiptListener() {
25466
25699
  // must never be the reason we refuse to start.
25467
25700
  unlinkStale: (p) => {
25468
25701
  try {
25469
- fs33.unlinkSync(p);
25702
+ fs34.unlinkSync(p);
25470
25703
  } catch {
25471
25704
  }
25472
25705
  },
@@ -25491,7 +25724,7 @@ async function buildCaptainChannel() {
25491
25724
  // in /tmp/x registers cwd "/private/tmp/x" on macOS, so cwd matching silently
25492
25725
  // missed and every captain ping reported accepted-unconfirmed.
25493
25726
  statusFor: (taskId) => readClaudeStatusBySocketPath(captainSocketPath(taskId)),
25494
- wire: (p, e) => writeLine(p, e, { connect: (path45) => netConnect2(path45) }),
25727
+ wire: (p, e) => writeLine(p, e, { connect: (path46) => netConnect2(path46) }),
25495
25728
  receipts,
25496
25729
  newMsgId: () => randomUUID7(),
25497
25730
  sleep: (ms) => new Promise((r) => setTimeout(r, ms)),
@@ -25624,8 +25857,8 @@ var cmuxCommand = new Command28("cmux").description("cmux integration helpers").
25624
25857
  // packages/cli/src/commands/effort.ts
25625
25858
  init_dist();
25626
25859
  init_dist2();
25627
- import fs34 from "fs";
25628
- import path36 from "path";
25860
+ import fs35 from "fs";
25861
+ import path37 from "path";
25629
25862
  import { Command as Command29 } from "commander";
25630
25863
  import chalk30 from "chalk";
25631
25864
  var VALID_EFFORTS = ["max", "balance", "low"];
@@ -25668,9 +25901,9 @@ function effortScopeLabel(projectName) {
25668
25901
  }
25669
25902
  function canonical(p) {
25670
25903
  try {
25671
- return fs34.realpathSync(p);
25904
+ return fs35.realpathSync(p);
25672
25905
  } catch {
25673
- return path36.resolve(p);
25906
+ return path37.resolve(p);
25674
25907
  }
25675
25908
  }
25676
25909
  async function notifyCaptainsOfEffort(effort, config, driver, cwd = process.cwd(), append, scopeProject, projectConfigRoot) {
@@ -25720,7 +25953,7 @@ var effortCommand = new Command29("effort").description("Get or set the crew tok
25720
25953
  const config = loadConfig();
25721
25954
  const registry = new RuntimeRegistry2({ cmux: createCmuxDriver2() });
25722
25955
  const driver = registry.global(config);
25723
- const stateRoot = path36.join(path36.dirname(DEFAULT_CONFIG_PATH), "state");
25956
+ const stateRoot = path37.join(path37.dirname(DEFAULT_CONFIG_PATH), "state");
25724
25957
  const append = (project, text) => appendCaptainMessage({ stateRoot, project, text, source: "daemon" });
25725
25958
  await notifyCaptainsOfEffort(effort, config, driver, process.cwd(), append, options.project);
25726
25959
  } catch {
@@ -25730,19 +25963,19 @@ var effortCommand = new Command29("effort").description("Get or set the crew tok
25730
25963
 
25731
25964
  // packages/cli/src/commands/tokens.ts
25732
25965
  init_dist();
25733
- import fs35 from "fs";
25734
- import path37 from "path";
25966
+ import fs36 from "fs";
25967
+ import path38 from "path";
25735
25968
  import os20 from "os";
25736
25969
  import readline3 from "readline";
25737
25970
  import { Command as Command30 } from "commander";
25738
25971
  import chalk31 from "chalk";
25739
- var CLAUDE_PROJECTS_DIR = path37.join(os20.homedir(), ".claude", "projects");
25972
+ var CLAUDE_PROJECTS_DIR = path38.join(os20.homedir(), ".claude", "projects");
25740
25973
  function parseTranscriptLine(rawLine) {
25741
- const line = rawLine.trim();
25742
- if (!line) return { timestamp: null, usage: null };
25974
+ const line2 = rawLine.trim();
25975
+ if (!line2) return { timestamp: null, usage: null };
25743
25976
  let obj;
25744
25977
  try {
25745
- obj = JSON.parse(line);
25978
+ obj = JSON.parse(line2);
25746
25979
  } catch {
25747
25980
  return { timestamp: null, usage: null };
25748
25981
  }
@@ -25786,9 +26019,9 @@ function foldTranscriptLine(agg, rawLine, state) {
25786
26019
  async function aggregateTranscriptFile(filePath) {
25787
26020
  const agg = emptySessionAggregate();
25788
26021
  const state = { lastCacheRead: null };
25789
- const rl = readline3.createInterface({ input: fs35.createReadStream(filePath), crlfDelay: Infinity });
25790
- for await (const line of rl) {
25791
- foldTranscriptLine(agg, line, state);
26022
+ const rl = readline3.createInterface({ input: fs36.createReadStream(filePath), crlfDelay: Infinity });
26023
+ for await (const line2 of rl) {
26024
+ foldTranscriptLine(agg, line2, state);
25792
26025
  }
25793
26026
  return agg;
25794
26027
  }
@@ -25854,22 +26087,22 @@ function buildRoleReport(role, sessions) {
25854
26087
  }
25855
26088
  async function readdirSafe(dir) {
25856
26089
  try {
25857
- return await fs35.promises.readdir(dir);
26090
+ return await fs36.promises.readdir(dir);
25858
26091
  } catch {
25859
26092
  return [];
25860
26093
  }
25861
26094
  }
25862
26095
  async function listJsonlFiles(dir) {
25863
26096
  const entries = await readdirSafe(dir);
25864
- return entries.filter((e) => e.endsWith(".jsonl")).map((e) => path37.join(dir, e));
26097
+ return entries.filter((e) => e.endsWith(".jsonl")).map((e) => path38.join(dir, e));
25865
26098
  }
25866
26099
  async function findTranscriptDirs(claudeProjectsDir, captainSlug) {
25867
26100
  const entries = await readdirSafe(claudeProjectsDir);
25868
26101
  const captainDirs = [];
25869
26102
  const crewDirs = [];
25870
26103
  for (const entry of entries) {
25871
- if (entry === captainSlug) captainDirs.push(path37.join(claudeProjectsDir, entry));
25872
- else if (isCrewDirName(entry, captainSlug)) crewDirs.push(path37.join(claudeProjectsDir, entry));
26104
+ if (entry === captainSlug) captainDirs.push(path38.join(claudeProjectsDir, entry));
26105
+ else if (isCrewDirName(entry, captainSlug)) crewDirs.push(path38.join(claudeProjectsDir, entry));
25873
26106
  }
25874
26107
  return { captainDirs, crewDirs };
25875
26108
  }
@@ -26327,7 +26560,7 @@ telegramCommand.command("send").argument("<project>", "project whose topic recei
26327
26560
  const { createInterface: createInterface2 } = await import("readline");
26328
26561
  const lines = [];
26329
26562
  const rl = createInterface2({ input: process.stdin });
26330
- for await (const line of rl) lines.push(line);
26563
+ for await (const line2 of rl) lines.push(line2);
26331
26564
  message = lines.join("\n").trimEnd();
26332
26565
  if (!message) {
26333
26566
  console.error(chalk32.red("no message provided (stdin was empty)"));
@@ -26352,11 +26585,12 @@ init_dist2();
26352
26585
  init_dist3();
26353
26586
  init_dist();
26354
26587
  import { Command as Command33 } from "commander";
26588
+ import { join as join36 } from "path";
26355
26589
  import { homedir as homedir20 } from "os";
26356
26590
 
26357
26591
  // packages/cli/src/lib/captain-session-registry.ts
26358
- import fs36 from "fs";
26359
- import path38 from "path";
26592
+ import fs37 from "fs";
26593
+ import path39 from "path";
26360
26594
 
26361
26595
  // packages/cli/src/lib/handoff-facts.ts
26362
26596
  var STALE_FETCH_WARNING_MS = 24 * 60 * 60 * 1e3;
@@ -26407,18 +26641,18 @@ function assembleHandoffFacts(live, claudeMem, gapSessions, checkpoint, now, ext
26407
26641
  // packages/cli/src/lib/captain-session-registry.ts
26408
26642
  var CAPTAIN_SESSION_REGISTRY_FILE = "captain-sessions.jsonl";
26409
26643
  function appendCaptainSession(spokeVault, record) {
26410
- fs36.mkdirSync(spokeVault, { recursive: true });
26411
- const file = path38.join(spokeVault, CAPTAIN_SESSION_REGISTRY_FILE);
26412
- fs36.appendFileSync(file, JSON.stringify(record) + "\n");
26644
+ fs37.mkdirSync(spokeVault, { recursive: true });
26645
+ const file = path39.join(spokeVault, CAPTAIN_SESSION_REGISTRY_FILE);
26646
+ fs37.appendFileSync(file, JSON.stringify(record) + "\n");
26413
26647
  }
26414
26648
  function readCaptainSessionRegistry(spokeVault) {
26415
- const file = path38.join(spokeVault, CAPTAIN_SESSION_REGISTRY_FILE);
26416
- if (!fs36.existsSync(file)) return [];
26649
+ const file = path39.join(spokeVault, CAPTAIN_SESSION_REGISTRY_FILE);
26650
+ if (!fs37.existsSync(file)) return [];
26417
26651
  const records = [];
26418
- for (const line of fs36.readFileSync(file, "utf-8").split("\n")) {
26419
- if (!line.trim()) continue;
26652
+ for (const line2 of fs37.readFileSync(file, "utf-8").split("\n")) {
26653
+ if (!line2.trim()) continue;
26420
26654
  try {
26421
- records.push(JSON.parse(line));
26655
+ records.push(JSON.parse(line2));
26422
26656
  } catch {
26423
26657
  }
26424
26658
  }
@@ -26730,9 +26964,25 @@ function recordCaptainSessionStart(payload) {
26730
26964
  } catch {
26731
26965
  }
26732
26966
  }
26967
+ var RULES_HOOK_EVENTS = { "session-start": "SessionStart", "prompt-submit": "UserPromptSubmit" };
26968
+ async function rulesHookOutput(sub, payload, opts) {
26969
+ if (sub !== "session-start" && sub !== "prompt-submit") return "";
26970
+ if (opts.env.SQUADRANT_RULES_INJECT === "0") return "";
26971
+ const ctx = await withBudget(() => computeRulesInjection({
26972
+ event: sub,
26973
+ payload,
26974
+ env: opts.env,
26975
+ cwd: opts.cwd,
26976
+ project: opts.project,
26977
+ cfg: (opts.loadCfg ?? loadConfig)(),
26978
+ stateRoot: opts.stateRoot ?? join36(CONFIG_DIR, "state")
26979
+ }), opts.budgetMs ?? INJECT_BUDGET_MS);
26980
+ if (!ctx) return "";
26981
+ return JSON.stringify({ hookSpecificOutput: { hookEventName: RULES_HOOK_EVENTS[sub], additionalContext: ctx } });
26982
+ }
26733
26983
  function hooksCommand() {
26734
26984
  const hooks = new Command33("hooks").description("(internal) receive lifecycle hook events from agent processes");
26735
- hooks.command("claude <sub>", { hidden: true }).description("internal: bridge a NativeHookSource claude hook to squadrantd").action(async (sub) => {
26985
+ hooks.command("claude <sub>", { hidden: true }).description("internal: bridge a NativeHookSource claude hook to squadrantd").option("--project <name>", "project for rules injection (default: SQUADRANT_CREW_PROJECT, then cwd)").action(async (sub, opts) => {
26736
26986
  let stdin = "";
26737
26987
  try {
26738
26988
  for await (const chunk of process.stdin) stdin += chunk;
@@ -26745,6 +26995,8 @@ function hooksCommand() {
26745
26995
  } catch {
26746
26996
  }
26747
26997
  }
26998
+ const rulesOut = await rulesHookOutput(sub, payload, { env: process.env, cwd: process.cwd(), project: opts.project });
26999
+ if (rulesOut) await new Promise((resolve4) => process.stdout.write(rulesOut, () => resolve4()));
26748
27000
  if (sub === "session-start" && process.env.SQUADRANT_ROLE === "captain") {
26749
27001
  recordCaptainSessionStart(payload);
26750
27002
  }
@@ -26801,13 +27053,13 @@ function hooksCommand() {
26801
27053
  // packages/cli/src/commands/work.ts
26802
27054
  init_dist();
26803
27055
  init_dist2();
26804
- import path39 from "path";
27056
+ import path40 from "path";
26805
27057
  import { Command as Command34 } from "commander";
26806
27058
  import chalk34 from "chalk";
26807
27059
  function detectCurrentProject(config, cwd = process.cwd()) {
26808
27060
  for (const [name, proj] of Object.entries(config.projects)) {
26809
27061
  const projPath = resolveHome(proj.path);
26810
- if (cwd === projPath || cwd.startsWith(projPath + path39.sep)) return name;
27062
+ if (cwd === projPath || cwd.startsWith(projPath + path40.sep)) return name;
26811
27063
  }
26812
27064
  return void 0;
26813
27065
  }
@@ -26856,8 +27108,8 @@ function stateColor(state) {
26856
27108
  }
26857
27109
  function printItem(item, indent) {
26858
27110
  const color = stateColor(item.state);
26859
- const line = " ".repeat(indent) + `${chalk34.dim(item.id)} ${item.title} ${color(`[${item.state}]`)}` + (indent === 0 ? chalk34.dim(` (${item.project})`) : "");
26860
- console.log(TERMINAL_WORK_STATES.has(item.state) ? chalk34.dim(line) : line);
27111
+ const line2 = " ".repeat(indent) + `${chalk34.dim(item.id)} ${item.title} ${color(`[${item.state}]`)}` + (indent === 0 ? chalk34.dim(` (${item.project})`) : "");
27112
+ console.log(TERMINAL_WORK_STATES.has(item.state) ? chalk34.dim(line2) : line2);
26861
27113
  }
26862
27114
  function printTree(items) {
26863
27115
  const { roots, childrenOf } = groupByParent(items);
@@ -26939,14 +27191,14 @@ var workCommand = new Command34("work").description("Track your own in-flight wo
26939
27191
  // packages/cli/src/commands/handoff.ts
26940
27192
  init_dist();
26941
27193
  import { Command as Command35 } from "commander";
26942
- import path42 from "path";
27194
+ import path43 from "path";
26943
27195
  import os21 from "os";
26944
27196
 
26945
27197
  // packages/cli/src/lib/handoff-live-repo.ts
26946
27198
  init_dist();
26947
27199
  import { execFileSync as execFileSync13 } from "child_process";
26948
- import fs37 from "fs";
26949
- import path40 from "path";
27200
+ import fs38 from "fs";
27201
+ import path41 from "path";
26950
27202
 
26951
27203
  // packages/cli/src/lib/handoff-branch-state.ts
26952
27204
  function tryRun(runner, cmd, args, cwd) {
@@ -27085,7 +27337,7 @@ function localAheadOfBase(runner, projectPath, base) {
27085
27337
  }
27086
27338
  function readFetchAgeMs(projectPath, now) {
27087
27339
  try {
27088
- const stat2 = fs37.statSync(path40.join(projectPath, ".git", "FETCH_HEAD"));
27340
+ const stat2 = fs38.statSync(path41.join(projectPath, ".git", "FETCH_HEAD"));
27089
27341
  return Math.max(0, now - stat2.mtime.getTime());
27090
27342
  } catch {
27091
27343
  return null;
@@ -27156,7 +27408,7 @@ function gatherLiveRepoState(projectPath, fallbackBaseBranch, tasks, runner = de
27156
27408
 
27157
27409
  // packages/cli/src/lib/handoff-claude-mem.ts
27158
27410
  import { createRequire } from "module";
27159
- import fs38 from "fs";
27411
+ import fs39 from "fs";
27160
27412
  var { DatabaseSync } = createRequire(import.meta.url)("node:sqlite");
27161
27413
  var CLAUDE_MEM_RECENCY_LIMIT = 20;
27162
27414
  function decisionText(row) {
@@ -27170,7 +27422,7 @@ function decisionText(row) {
27170
27422
  return row.narrative ?? "";
27171
27423
  }
27172
27424
  function queryClaudeMem(dbPath, project) {
27173
- if (!fs38.existsSync(dbPath)) return null;
27425
+ if (!fs39.existsSync(dbPath)) return null;
27174
27426
  let db;
27175
27427
  try {
27176
27428
  db = new DatabaseSync(dbPath, { readOnly: true });
@@ -27213,7 +27465,7 @@ function queryClaudeMem(dbPath, project) {
27213
27465
  }
27214
27466
 
27215
27467
  // packages/cli/src/lib/handoff-transcript.ts
27216
- import fs39 from "fs";
27468
+ import fs40 from "fs";
27217
27469
  var TRANSCRIPT_BYTE_CAP = 2e5;
27218
27470
  var DIGEST_BYTE_CAP = 8 * 1024;
27219
27471
  var PROMPT_TRUNCATE_CHARS = 300;
@@ -27276,11 +27528,11 @@ function extractMessages(tailText) {
27276
27528
  const collectRefs = (text) => {
27277
27529
  for (const ref of findRefs(text)) refs.add(ref);
27278
27530
  };
27279
- for (const line of tailText.split("\n")) {
27280
- if (!line.trim()) continue;
27531
+ for (const line2 of tailText.split("\n")) {
27532
+ if (!line2.trim()) continue;
27281
27533
  let obj;
27282
27534
  try {
27283
- obj = JSON.parse(line);
27535
+ obj = JSON.parse(line2);
27284
27536
  } catch {
27285
27537
  continue;
27286
27538
  }
@@ -27322,27 +27574,27 @@ function extractMessages(tailText) {
27322
27574
  return { lastUserMessage, lastAssistantText, digest };
27323
27575
  }
27324
27576
  function extractTranscriptTail(transcriptPath, byteCap = TRANSCRIPT_BYTE_CAP) {
27325
- if (!fs39.existsSync(transcriptPath)) return null;
27326
- const content = fs39.readFileSync(transcriptPath, "utf-8");
27577
+ if (!fs40.existsSync(transcriptPath)) return null;
27578
+ const content = fs40.readFileSync(transcriptPath, "utf-8");
27327
27579
  const { lastUserMessage, lastAssistantText, digest } = extractMessages(tailOf(content, byteCap));
27328
- const mtimeIso = fs39.statSync(transcriptPath).mtime.toISOString();
27580
+ const mtimeIso = fs40.statSync(transcriptPath).mtime.toISOString();
27329
27581
  return { path: transcriptPath, mtimeIso, lastUserMessage, lastAssistantText, digest };
27330
27582
  }
27331
27583
 
27332
27584
  // packages/cli/src/lib/handoff-archive.ts
27333
- import fs40 from "fs";
27334
- import path41 from "path";
27585
+ import fs41 from "fs";
27586
+ import path42 from "path";
27335
27587
  function readNewestArchivedHandoff(spokeVault, now) {
27336
- const dir = path41.join(spokeVault, "handoffs");
27337
- if (!fs40.existsSync(dir)) return null;
27338
- const candidates = fs40.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => {
27339
- const full = path41.join(dir, e.name);
27340
- return { name: e.name, full, mtime: fs40.statSync(full).mtime };
27588
+ const dir = path42.join(spokeVault, "handoffs");
27589
+ if (!fs41.existsSync(dir)) return null;
27590
+ const candidates = fs41.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && e.name.endsWith(".json")).map((e) => {
27591
+ const full = path42.join(dir, e.name);
27592
+ return { name: e.name, full, mtime: fs41.statSync(full).mtime };
27341
27593
  }).sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
27342
27594
  for (const candidate of candidates) {
27343
27595
  let content;
27344
27596
  try {
27345
- content = JSON.parse(fs40.readFileSync(candidate.full, "utf-8"));
27597
+ content = JSON.parse(fs41.readFileSync(candidate.full, "utf-8"));
27346
27598
  } catch {
27347
27599
  continue;
27348
27600
  }
@@ -27352,7 +27604,7 @@ function readNewestArchivedHandoff(spokeVault, now) {
27352
27604
  }
27353
27605
 
27354
27606
  // packages/cli/src/commands/handoff.ts
27355
- var CLAUDE_MEM_DB_PATH = path42.join(os21.homedir(), ".claude-mem", "claude-mem.db");
27607
+ var CLAUDE_MEM_DB_PATH = path43.join(os21.homedir(), ".claude-mem", "claude-mem.db");
27356
27608
  async function defaultFetchTasks(project) {
27357
27609
  return await squadrantdCall({ kind: "list", project });
27358
27610
  }
@@ -27420,9 +27672,9 @@ function filterSessions(rows, f) {
27420
27672
  if (f.agent && r.agent !== f.agent) return false;
27421
27673
  if (f.liveOnly && r.status === "stale") return false;
27422
27674
  if (f.project) {
27423
- const path45 = f.projects?.[f.project];
27675
+ const path46 = f.projects?.[f.project];
27424
27676
  const byRecord = r.project === f.project;
27425
- const byCwd = !!path45 && !!r.cwd && (r.cwd === normalized(path45) || r.cwd.startsWith(normalized(path45) + "/"));
27677
+ const byCwd = !!path46 && !!r.cwd && (r.cwd === normalized(path46) || r.cwd.startsWith(normalized(path46) + "/"));
27426
27678
  if (!byRecord && !byCwd) return false;
27427
27679
  }
27428
27680
  return true;
@@ -27442,8 +27694,8 @@ function formatSessionTable(rows) {
27442
27694
  ]);
27443
27695
  const all = [header, ...body];
27444
27696
  const widths = header.map((_, i) => Math.max(...all.map((row) => row[i].length)));
27445
- const line = (row) => row.map((c, i) => c.padEnd(widths[i])).join(" ").trimEnd();
27446
- return [line(header), ...body.map(line)].join("\n");
27697
+ const line2 = (row) => row.map((c, i) => c.padEnd(widths[i])).join(" ").trimEnd();
27698
+ return [line2(header), ...body.map(line2)].join("\n");
27447
27699
  }
27448
27700
  async function collectSessions(drivers) {
27449
27701
  const rows = [];
@@ -27513,7 +27765,7 @@ init_dist();
27513
27765
  init_dist2();
27514
27766
  init_dist3();
27515
27767
  import os22 from "os";
27516
- import path43 from "path";
27768
+ import path44 from "path";
27517
27769
  import { Command as Command37 } from "commander";
27518
27770
  import chalk36 from "chalk";
27519
27771
 
@@ -27631,7 +27883,7 @@ function buildWhoamiDeps(opts = {}) {
27631
27883
  const projects = Object.fromEntries(
27632
27884
  Object.entries(config.projects).map(([n, p]) => [n, resolveHome(p.path)])
27633
27885
  );
27634
- const root = stateRoot ?? path43.join(os22.homedir(), ".config", "squadrant", "state");
27886
+ const root = stateRoot ?? path44.join(os22.homedir(), ".config", "squadrant", "state");
27635
27887
  const store = createStore(root);
27636
27888
  const merged = {
27637
27889
  env: process.env,
@@ -27683,8 +27935,8 @@ var whoamiCommand = new Command37("whoami").description("Show the agent session
27683
27935
  // packages/cli/src/commands/knowledge.ts
27684
27936
  init_dist();
27685
27937
  init_dist2();
27686
- import fs41 from "fs";
27687
- import path44 from "path";
27938
+ import fs42 from "fs";
27939
+ import path45 from "path";
27688
27940
  import { Command as Command38 } from "commander";
27689
27941
  import chalk37 from "chalk";
27690
27942
  var KNOWLEDGE_PRIVACY_NOTICE = "Sources are sent to the extraction crew's model; mark `sensitivity: local-only` to keep a source on local models only.";
@@ -27697,18 +27949,18 @@ function runKnowledgeInit(kb, configPath = DEFAULT_CONFIG_PATH) {
27697
27949
  const hub = resolveHome(cfg.hubVault);
27698
27950
  const dir = kbDir(hub, kb);
27699
27951
  const created = [];
27700
- for (const d of [path44.join(dir, "raw"), kbRulesDir(hub, kb), path44.join(kbRulesDir(hub, kb), PROPOSED_DIR)]) {
27701
- if (!fs41.existsSync(d)) {
27702
- fs41.mkdirSync(d, { recursive: true });
27703
- created.push(path44.relative(dir, d));
27952
+ for (const d of [path45.join(dir, "raw"), kbRulesDir(hub, kb), path45.join(kbRulesDir(hub, kb), PROPOSED_DIR)]) {
27953
+ if (!fs42.existsSync(d)) {
27954
+ fs42.mkdirSync(d, { recursive: true });
27955
+ created.push(path45.relative(dir, d));
27704
27956
  }
27705
27957
  }
27706
- const sourcesFile = path44.join(dir, "sources.yaml");
27707
- if (!fs41.existsSync(sourcesFile)) {
27708
- fs41.writeFileSync(sourcesFile, SOURCES_TEMPLATE);
27958
+ const sourcesFile = path45.join(dir, "sources.yaml");
27959
+ if (!fs42.existsSync(sourcesFile)) {
27960
+ fs42.writeFileSync(sourcesFile, SOURCES_TEMPLATE);
27709
27961
  created.push("sources.yaml");
27710
27962
  }
27711
- if (!fs41.existsSync(path44.join(dir, "index.json"))) {
27963
+ if (!fs42.existsSync(path45.join(dir, "index.json"))) {
27712
27964
  writeIndex(hub, kb, compileIndex(kb, []));
27713
27965
  created.push("index.json");
27714
27966
  }
@@ -27723,7 +27975,7 @@ function runKnowledgeSubscribe(kb, project, configPath = DEFAULT_CONFIG_PATH) {
27723
27975
  const cfg = loadConfig(configPath);
27724
27976
  const pc = cfg.projects[project];
27725
27977
  if (!pc) throw new Error(`Unknown project '${project}'`);
27726
- if (!fs41.existsSync(kbDir(resolveHome(cfg.hubVault), kb))) {
27978
+ if (!fs42.existsSync(kbDir(resolveHome(cfg.hubVault), kb))) {
27727
27979
  throw new Error(`Knowledge base '${kb}' does not exist. Run: squadrant knowledge init ${kb}`);
27728
27980
  }
27729
27981
  const list = pc.knowledge ?? [];
@@ -27761,9 +28013,9 @@ function runKnowledgeReindex(kb, configPath = DEFAULT_CONFIG_PATH) {
27761
28013
  assertKbName(kb);
27762
28014
  const cfg = loadConfig(configPath);
27763
28015
  const hub = resolveHome(cfg.hubVault);
27764
- if (!fs41.existsSync(kbDir(hub, kb))) throw new Error(`Knowledge base '${kb}' does not exist. Run: squadrant knowledge init ${kb}`);
28016
+ if (!fs42.existsSync(kbDir(hub, kb))) throw new Error(`Knowledge base '${kb}' does not exist. Run: squadrant knowledge init ${kb}`);
27765
28017
  const { rules: all, errors } = loadKbRules(cfg, kb, { includeProposed: true });
27766
- const proposedRoot = path44.join(kbRulesDir(hub, kb), PROPOSED_DIR) + path44.sep;
28018
+ const proposedRoot = path45.join(kbRulesDir(hub, kb), PROPOSED_DIR) + path45.sep;
27767
28019
  const live = all.filter((r) => !r.file.startsWith(proposedRoot));
27768
28020
  const file = writeIndex(hub, kb, compileIndex(kb, live));
27769
28021
  return { file, count: live.length, proposed: all.length - live.length, errors: errors.length, invalid: errors };
@@ -27772,7 +28024,7 @@ function runKnowledgeValidate(kb, configPath = DEFAULT_CONFIG_PATH) {
27772
28024
  assertKbName(kb);
27773
28025
  const cfg = loadConfig(configPath);
27774
28026
  const hub = resolveHome(cfg.hubVault);
27775
- if (!fs41.existsSync(kbDir(hub, kb))) throw new Error(`Knowledge base '${kb}' does not exist. Run: squadrant knowledge init ${kb}`);
28027
+ if (!fs42.existsSync(kbDir(hub, kb))) throw new Error(`Knowledge base '${kb}' does not exist. Run: squadrant knowledge init ${kb}`);
27776
28028
  const { sources, errors } = loadSources(hub, kb);
27777
28029
  const res = validateKb({ rulesDir: kbRulesDir(hub, kb), kbRoot: kbDir(hub, kb), sources, domains: cfg.knowledge?.[kb]?.domains });
27778
28030
  const srcChecks = errors.map((e) => ({ level: "fail", message: `sources.yaml: ${e}` }));
@@ -27864,10 +28116,10 @@ function runRulesShow(id, opts, configPath = DEFAULT_CONFIG_PATH) {
27864
28116
  var rulesCommand = new Command39("rules").description("Look up rules from subscribed knowledge bases (#893)");
27865
28117
  rulesCommand.command("search <query...>").description("Search rules by keyword (ranked; best match first)").option("--project <name>", "project (default: from cwd or SQUADRANT_CREW_PROJECT)").option("--all", "include proposed and retired rules").option("--limit <n>", `max results (default ${DEFAULT_SEARCH_LIMIT})`).option("--brief", "one line per rule: [score] MODALITY id: statement").option("--ids-only", "print only rule ids").action((query, opts) => {
27866
28118
  const hits = runRulesSearch(query.join(" "), opts);
27867
- for (const line of renderSearch(hits, opts)) console.log(line);
28119
+ for (const line2 of renderSearch(hits, opts)) console.log(line2);
27868
28120
  });
27869
28121
  rulesCommand.command("list").description("List every resolved rule for the project").option("--project <name>", "project (default: from cwd or SQUADRANT_CREW_PROJECT)").option("--all", "include proposed and retired rules").option("--brief", "one line per rule: MODALITY id: statement").action((opts) => {
27870
- for (const line of renderList2(runRulesList(opts), opts)) console.log(line);
28122
+ for (const line2 of renderList2(runRulesList(opts), opts)) console.log(line2);
27871
28123
  });
27872
28124
  rulesCommand.command("show <ids...>").description("Show one or more rules in full").option("--project <name>", "project (default: from cwd or SQUADRANT_CREW_PROJECT)").option("--all", "include proposed and retired rules").action((ids, opts) => {
27873
28125
  for (const id of ids) {
@@ -27883,14 +28135,14 @@ init_dist();
27883
28135
  init_dist();
27884
28136
  init_dist();
27885
28137
  var __dirname = dirname12(fileURLToPath6(import.meta.url));
27886
- var pkg = JSON.parse(readFileSync21(join36(__dirname, "..", "package.json"), "utf-8"));
28138
+ var pkg = JSON.parse(readFileSync21(join37(__dirname, "..", "package.json"), "utf-8"));
27887
28139
  ensureRuntimeSynced({
27888
- sourceRoot: join36(__dirname, ".."),
27889
- runtimeRoot: join36(homedir21(), ".config", "squadrant")
28140
+ sourceRoot: join37(__dirname, ".."),
28141
+ runtimeRoot: join37(homedir21(), ".config", "squadrant")
27890
28142
  });
27891
28143
  if (!process.env.VITEST) {
27892
28144
  try {
27893
- syncShippedOpencodeSkills({ pkgRoot: join36(__dirname, "..") });
28145
+ syncShippedOpencodeSkills({ pkgRoot: join37(__dirname, "..") });
27894
28146
  } catch (err) {
27895
28147
  process.stderr.write(
27896
28148
  `squadrant: opencode skills sync skipped: ${err.message}
@@ -27900,7 +28152,7 @@ if (!process.env.VITEST) {
27900
28152
  }
27901
28153
  if (process.argv[2] !== "config") {
27902
28154
  try {
27903
- const cfgPath = join36(homedir21(), ".config", "squadrant", "config.json");
28155
+ const cfgPath = join37(homedir21(), ".config", "squadrant", "config.json");
27904
28156
  if (existsSync14(cfgPath)) {
27905
28157
  const cfg = JSON.parse(readConfigFileSync(cfgPath));
27906
28158
  if (needsCheck(cfg, pkg.version)) {