@staff0rd/assist 0.599.0 → 0.601.0

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
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.599.0",
9
+ version: "0.601.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -187,8 +187,8 @@ function getRemoteOriginUrl(cwd) {
187
187
  }
188
188
 
189
189
  // src/commands/backlog/getCurrentOrigin.ts
190
- function stripLeadingSlashes(path84) {
191
- return path84.replace(/^\/+/, "");
190
+ function stripLeadingSlashes(path90) {
191
+ return path90.replace(/^\/+/, "");
192
192
  }
193
193
  function normalizeOrigin(raw) {
194
194
  const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
@@ -238,9 +238,9 @@ function findGitLink(dir) {
238
238
  }
239
239
  return null;
240
240
  }
241
- function isFile(path84) {
241
+ function isFile(path90) {
242
242
  try {
243
- return statSync(path84).isFile();
243
+ return statSync(path90).isFile();
244
244
  } catch {
245
245
  return false;
246
246
  }
@@ -259,9 +259,9 @@ function linkedGitDirParent(gitDir) {
259
259
  const match = /^(.*)[/\\]worktrees[/\\][^/\\]+[/\\]?$/.exec(gitDir);
260
260
  return match ? match[1] : null;
261
261
  }
262
- function readTrimmed(path84) {
262
+ function readTrimmed(path90) {
263
263
  try {
264
- const content = readFileSync(path84, "utf8").trim();
264
+ const content = readFileSync(path90, "utf8").trim();
265
265
  return content === "" ? null : content;
266
266
  } catch {
267
267
  return null;
@@ -274,10 +274,10 @@ function absolute(target, from) {
274
274
  // src/shared/loadRawYaml.ts
275
275
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
276
276
  import { parse as parseYaml } from "yaml";
277
- function loadRawYaml(path84) {
278
- if (!existsSync2(path84)) return {};
277
+ function loadRawYaml(path90) {
278
+ if (!existsSync2(path90)) return {};
279
279
  try {
280
- const content = readFileSync2(path84, "utf8");
280
+ const content = readFileSync2(path90, "utf8");
281
281
  return parseYaml(content) || {};
282
282
  } catch {
283
283
  return {};
@@ -349,8 +349,8 @@ function mergeRawConfigs(globalRaw, projectRaw) {
349
349
  // src/commands/backlog/originDisplayName.ts
350
350
  function originDisplayName(origin) {
351
351
  if (origin.startsWith("local:")) {
352
- const path84 = origin.slice("local:".length).replace(/\/+$/, "");
353
- const segments = path84.split("/").filter(Boolean);
352
+ const path90 = origin.slice("local:".length).replace(/\/+$/, "");
353
+ const segments = path90.split("/").filter(Boolean);
354
354
  return segments[segments.length - 1] ?? origin;
355
355
  }
356
356
  const firstSlash = origin.indexOf("/");
@@ -1785,8 +1785,8 @@ function findUnmergedPaths() {
1785
1785
  }
1786
1786
  const found = /* @__PURE__ */ new Set();
1787
1787
  for (const line of output.split("\n")) {
1788
- const path84 = line.split(" ")[1];
1789
- if (path84) found.add(path84.trim());
1788
+ const path90 = line.split(" ")[1];
1789
+ if (path90) found.add(path90.trim());
1790
1790
  }
1791
1791
  return [...found];
1792
1792
  }
@@ -1896,8 +1896,8 @@ function getPreferredRemoteRepo(cwd) {
1896
1896
  function gitRefUrl(kind, ref, cwd) {
1897
1897
  const repo = getPreferredRemoteRepo(cwd);
1898
1898
  if (!repo) return void 0;
1899
- const path84 = kind === "branch" ? "tree" : "commit";
1900
- return `https://github.com/${repo.org}/${repo.repo}/${path84}/${ref}`;
1899
+ const path90 = kind === "branch" ? "tree" : "commit";
1900
+ return `https://github.com/${repo.org}/${repo.repo}/${path90}/${ref}`;
1901
1901
  }
1902
1902
 
1903
1903
  // src/commands/commit/collectCommitRefs.ts
@@ -3995,25 +3995,25 @@ function toFindings(file, lines2, raw, exempt) {
3995
3995
 
3996
3996
  // src/commands/verify/blockCodeComments/collectFileComments.ts
3997
3997
  function collectFileComments(file, lines2, project) {
3998
- const read2 = () => fs14.readFileSync(file, "utf8");
3998
+ const read3 = () => fs14.readFileSync(file, "utf8");
3999
3999
  if (isYamlFile(file))
4000
- return toFindings(file, lines2, collectYamlComments(read2()), false);
4000
+ return toFindings(file, lines2, collectYamlComments(read3()), false);
4001
4001
  if (isDockerfile(file) || isEnvFile(file) || isShellFile(file))
4002
4002
  return toFindings(
4003
4003
  file,
4004
4004
  lines2,
4005
- collectHashComments(read2(), { skipHeader: isShellFile(file) }),
4005
+ collectHashComments(read3(), { skipHeader: isShellFile(file) }),
4006
4006
  true
4007
4007
  );
4008
4008
  if (isBicepFile(file))
4009
- return toFindings(file, lines2, collectBicepComments(read2()), true);
4009
+ return toFindings(file, lines2, collectBicepComments(read3()), true);
4010
4010
  if (isCsharpFile(file)) {
4011
- const content = read2();
4011
+ const content = read3();
4012
4012
  if (isGeneratedCsharpFile(file, content)) return [];
4013
4013
  return toFindings(file, lines2, collectCsharpComments(content), true);
4014
4014
  }
4015
4015
  if (isRazorFile(file))
4016
- return toFindings(file, lines2, extractRazorComments(read2()), true);
4016
+ return toFindings(file, lines2, extractRazorComments(read3()), true);
4017
4017
  return collectSourceFindings(file, lines2, project);
4018
4018
  }
4019
4019
 
@@ -4273,11 +4273,11 @@ function enumValues(node) {
4273
4273
  function opaqueConfigNode(inner, base) {
4274
4274
  return { ...base, kind: "other", type: leafTypeOf(inner) };
4275
4275
  }
4276
- function build(node, path84) {
4276
+ function build(node, path90) {
4277
4277
  const { inner, defaultValue, optional } = unwrapSchemaNode(node);
4278
4278
  const secret = isSecretSchemaNode(node) || isSecretSchemaNode(inner);
4279
4279
  const base = {
4280
- path: path84,
4280
+ path: path90,
4281
4281
  ...optional ? { optional: true } : {},
4282
4282
  ...defaultValue === void 0 ? {} : { defaultValue },
4283
4283
  ...secret ? { secret: true } : {}
@@ -4296,9 +4296,9 @@ function segmentText(segment) {
4296
4296
  if (segment.kind === "index") return `[${segment.index}]`;
4297
4297
  return "[]";
4298
4298
  }
4299
- function formatConfigPath(path84) {
4299
+ function formatConfigPath(path90) {
4300
4300
  let text18 = "";
4301
- for (const segment of path84) {
4301
+ for (const segment of path90) {
4302
4302
  const dotted = segment.kind === "key" || segment.kind === "entry";
4303
4303
  const rendered = segmentText(segment);
4304
4304
  text18 += dotted && text18 ? `.${rendered}` : rendered;
@@ -4946,9 +4946,9 @@ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
4946
4946
 
4947
4947
  // src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
4948
4948
  import { minimatch as minimatch2 } from "minimatch";
4949
- function resolveStringsAtPath(data, path84) {
4949
+ function resolveStringsAtPath(data, path90) {
4950
4950
  let current = data;
4951
- for (const segment of path84.split(".")) {
4951
+ for (const segment of path90.split(".")) {
4952
4952
  if (current === null || typeof current !== "object") return [];
4953
4953
  current = current[segment];
4954
4954
  }
@@ -4961,10 +4961,10 @@ function resolveStringsAtPath(data, path84) {
4961
4961
  }
4962
4962
  function findRuleViolations(data, rule) {
4963
4963
  const violations = [];
4964
- for (const path84 of rule.paths) {
4965
- for (const value of resolveStringsAtPath(data, path84)) {
4964
+ for (const path90 of rule.paths) {
4965
+ for (const value of resolveStringsAtPath(data, path90)) {
4966
4966
  if (minimatch2(value, rule.disallowed))
4967
- violations.push({ file: rule.file, path: path84, value });
4967
+ violations.push({ file: rule.file, path: path90, value });
4968
4968
  }
4969
4969
  }
4970
4970
  return violations;
@@ -5003,8 +5003,8 @@ function forbiddenStrings() {
5003
5003
  process.exit(0);
5004
5004
  }
5005
5005
  console.log("Forbidden strings found:\n");
5006
- for (const { file, path: path84, value } of violations) {
5007
- console.log(` ${file} ${path84}: ${value}`);
5006
+ for (const { file, path: path90, value } of violations) {
5007
+ console.log(` ${file} ${path90}: ${value}`);
5008
5008
  }
5009
5009
  console.log(`
5010
5010
  Total: ${violations.length} forbidden string(s).`);
@@ -5319,15 +5319,15 @@ function readBaselineMigrations(repoRelativeDir, ref) {
5319
5319
  } catch {
5320
5320
  return baseline;
5321
5321
  }
5322
- const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path84) => MIGRATION_FILE3.test(basename2(path84)));
5323
- for (const path84 of paths) {
5322
+ const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path90) => MIGRATION_FILE3.test(basename2(path90)));
5323
+ for (const path90 of paths) {
5324
5324
  try {
5325
- const content = execSync14(`git show "${ref}:${path84}"`, {
5325
+ const content = execSync14(`git show "${ref}:${path90}"`, {
5326
5326
  encoding: "utf8",
5327
5327
  maxBuffer: 16 * 1024 * 1024,
5328
5328
  stdio: ["pipe", "pipe", "pipe"]
5329
5329
  });
5330
- baseline.set(basename2(path84), content);
5330
+ baseline.set(basename2(path90), content);
5331
5331
  } catch {
5332
5332
  }
5333
5333
  }
@@ -6761,10 +6761,10 @@ var hooksSettings = {
6761
6761
  }
6762
6762
  };
6763
6763
  function ensureHooksSettings() {
6764
- const path84 = daemonPaths.hooksSettings;
6765
- mkdirSync5(dirname13(path84), { recursive: true });
6766
- writeFileSync15(path84, JSON.stringify(hooksSettings, null, 2));
6767
- return path84;
6764
+ const path90 = daemonPaths.hooksSettings;
6765
+ mkdirSync5(dirname13(path90), { recursive: true });
6766
+ writeFileSync15(path90, JSON.stringify(hooksSettings, null, 2));
6767
+ return path90;
6768
6768
  }
6769
6769
 
6770
6770
  // src/shared/spawnInherit.ts
@@ -7062,9 +7062,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
7062
7062
  function backupLocalBacklogFiles(dir) {
7063
7063
  const moved = [];
7064
7064
  for (const name of LOCAL_FILES) {
7065
- const path84 = join15(dir, ".assist", name);
7066
- if (existsSync19(path84)) {
7067
- renameSync(path84, `${path84}.bak`);
7065
+ const path90 = join15(dir, ".assist", name);
7066
+ if (existsSync19(path90)) {
7067
+ renameSync(path90, `${path90}.bak`);
7068
7068
  moved.push(`${name} \u2192 ${name}.bak`);
7069
7069
  }
7070
7070
  }
@@ -7544,8 +7544,8 @@ var backlogItemSchema = z4.strictObject({
7544
7544
  var backlogFileSchema = z4.array(backlogItemSchema);
7545
7545
 
7546
7546
  // src/commands/backlog/parseBacklogJsonl.ts
7547
- function parseBacklogJsonl(path84) {
7548
- const content = readFileSync15(path84, "utf8").trim();
7547
+ function parseBacklogJsonl(path90) {
7548
+ const content = readFileSync15(path90, "utf8").trim();
7549
7549
  if (content.length === 0) return [];
7550
7550
  return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
7551
7551
  }
@@ -8356,24 +8356,24 @@ function getOwnerPath(itemId2) {
8356
8356
  function recordSignalOwner(itemId2) {
8357
8357
  const sessionId = process.env.ASSIST_SESSION_ID;
8358
8358
  if (!sessionId) return;
8359
- const path84 = getOwnerPath(itemId2);
8360
- mkdirSync7(dirname15(path84), { recursive: true });
8361
- writeFileSync17(path84, JSON.stringify({ sessionId }));
8359
+ const path90 = getOwnerPath(itemId2);
8360
+ mkdirSync7(dirname15(path90), { recursive: true });
8361
+ writeFileSync17(path90, JSON.stringify({ sessionId }));
8362
8362
  }
8363
8363
  function readSignalOwner(itemId2) {
8364
- const path84 = getOwnerPath(itemId2);
8365
- if (!existsSync23(path84)) return void 0;
8364
+ const path90 = getOwnerPath(itemId2);
8365
+ if (!existsSync23(path90)) return void 0;
8366
8366
  try {
8367
- const parsed = JSON.parse(readFileSync16(path84, "utf8"));
8367
+ const parsed = JSON.parse(readFileSync16(path90, "utf8"));
8368
8368
  return parsed.sessionId;
8369
8369
  } catch {
8370
8370
  return void 0;
8371
8371
  }
8372
8372
  }
8373
8373
  function clearSignalOwner(itemId2) {
8374
- const path84 = getOwnerPath(itemId2);
8374
+ const path90 = getOwnerPath(itemId2);
8375
8375
  try {
8376
- rmSync(path84);
8376
+ rmSync(path90);
8377
8377
  } catch {
8378
8378
  }
8379
8379
  }
@@ -8410,19 +8410,19 @@ function resolveSignalTarget(event, data) {
8410
8410
  function writeSignal(event, data) {
8411
8411
  const target = resolveSignalTarget(event, data);
8412
8412
  if (!target) return;
8413
- const path84 = getSignalPath(target);
8414
- if (!path84) return;
8413
+ const path90 = getSignalPath(target);
8414
+ if (!path90) return;
8415
8415
  const signal = { event, sessionId: target, ...data };
8416
- mkdirSync8(dirname16(path84), { recursive: true });
8417
- writeFileSync18(path84, JSON.stringify(signal));
8416
+ mkdirSync8(dirname16(path90), { recursive: true });
8417
+ writeFileSync18(path90, JSON.stringify(signal));
8418
8418
  }
8419
8419
 
8420
8420
  // src/commands/backlog/readSignal.ts
8421
8421
  function readSignal() {
8422
- const path84 = getSignalPath();
8423
- if (!path84 || !existsSync24(path84)) return void 0;
8422
+ const path90 = getSignalPath();
8423
+ if (!path90 || !existsSync24(path90)) return void 0;
8424
8424
  try {
8425
- return JSON.parse(readFileSync17(path84, "utf8"));
8425
+ return JSON.parse(readFileSync17(path90, "utf8"));
8426
8426
  } catch {
8427
8427
  return void 0;
8428
8428
  }
@@ -8619,13 +8619,13 @@ function activityPath(sessionId) {
8619
8619
  function emitActivity(activity2) {
8620
8620
  const sessionId = process.env.ASSIST_ACTIVITY_ID;
8621
8621
  if (!sessionId) return;
8622
- const path84 = activityPath(sessionId);
8623
- mkdirSync9(dirname17(path84), { recursive: true });
8624
- writeFileSync19(path84, JSON.stringify({ ...activity2, startedAt: Date.now() }));
8622
+ const path90 = activityPath(sessionId);
8623
+ mkdirSync9(dirname17(path90), { recursive: true });
8624
+ writeFileSync19(path90, JSON.stringify({ ...activity2, startedAt: Date.now() }));
8625
8625
  }
8626
- function readActivity(path84) {
8626
+ function readActivity(path90) {
8627
8627
  try {
8628
- return JSON.parse(readFileSync18(path84, "utf8"));
8628
+ return JSON.parse(readFileSync18(path90, "utf8"));
8629
8629
  } catch {
8630
8630
  return void 0;
8631
8631
  }
@@ -8635,9 +8635,9 @@ function reconcileActivity(sessionId, activity2) {
8635
8635
  removeActivity(sessionId);
8636
8636
  return;
8637
8637
  }
8638
- const path84 = activityPath(sessionId);
8639
- mkdirSync9(dirname17(path84), { recursive: true });
8640
- writeFileSync19(path84, JSON.stringify(activity2));
8638
+ const path90 = activityPath(sessionId);
8639
+ mkdirSync9(dirname17(path90), { recursive: true });
8640
+ writeFileSync19(path90, JSON.stringify(activity2));
8641
8641
  }
8642
8642
  function removeActivity(sessionId) {
8643
8643
  try {
@@ -10090,10 +10090,10 @@ function getStorePath(filename) {
10090
10090
  return join26(getStoreDir(), filename);
10091
10091
  }
10092
10092
  function loadJson(filename) {
10093
- const path84 = getStorePath(filename);
10094
- if (existsSync29(path84)) {
10093
+ const path90 = getStorePath(filename);
10094
+ if (existsSync29(path90)) {
10095
10095
  try {
10096
- return JSON.parse(readFileSync19(path84, "utf8"));
10096
+ return JSON.parse(readFileSync19(path90, "utf8"));
10097
10097
  } catch {
10098
10098
  return {};
10099
10099
  }
@@ -10112,22 +10112,22 @@ function saveJson(filename, data) {
10112
10112
  var REGISTRY_FILE = "worktrees.json";
10113
10113
  function readWorktreeRegistry() {
10114
10114
  const data = loadJson(REGISTRY_FILE);
10115
- return Object.entries(data).filter(([, record]) => !record.reaped).map(([path84, record]) => ({ path: path84, ...record }));
10115
+ return Object.entries(data).filter(([, record]) => !record.reaped).map(([path90, record]) => ({ path: path90, ...record }));
10116
10116
  }
10117
- function worktreeAttributionIncludingReaped(path84) {
10118
- const record = loadJson(REGISTRY_FILE)[path84];
10117
+ function worktreeAttributionIncludingReaped(path90) {
10118
+ const record = loadJson(REGISTRY_FILE)[path90];
10119
10119
  return record ? { clone: record.clone, origin: record.origin } : void 0;
10120
10120
  }
10121
- function recordWorktree(path84, clone, origin) {
10121
+ function recordWorktree(path90, clone, origin) {
10122
10122
  const data = loadJson(REGISTRY_FILE);
10123
- data[path84] = { clone, origin };
10123
+ data[path90] = { clone, origin };
10124
10124
  saveJson(REGISTRY_FILE, data);
10125
10125
  }
10126
- function forgetWorktree(path84) {
10126
+ function forgetWorktree(path90) {
10127
10127
  const data = loadJson(REGISTRY_FILE);
10128
- const record = data[path84];
10128
+ const record = data[path90];
10129
10129
  if (!record || record.reaped) return;
10130
- data[path84] = { ...record, reaped: true };
10130
+ data[path90] = { ...record, reaped: true };
10131
10131
  saveJson(REGISTRY_FILE, data);
10132
10132
  }
10133
10133
 
@@ -10878,8 +10878,8 @@ async function loadCommittedPaths(cwd, sessionId) {
10878
10878
  for (const commit2 of commits2) {
10879
10879
  const resolved = await resolveCommit(cwd, commit2.sha);
10880
10880
  if (!resolved) continue;
10881
- for (const path84 of resolved.paths) {
10882
- if (!bases.has(path84)) bases.set(path84, resolved.base);
10881
+ for (const path90 of resolved.paths) {
10882
+ if (!bases.has(path90)) bases.set(path90, resolved.base);
10883
10883
  }
10884
10884
  }
10885
10885
  return { commits: commits2, bases };
@@ -10897,16 +10897,16 @@ async function itemChangeSet(cwd, sessionId) {
10897
10897
  }
10898
10898
  function groupByBase(bases) {
10899
10899
  const groups = /* @__PURE__ */ new Map();
10900
- for (const [path84, base] of bases) {
10900
+ for (const [path90, base] of bases) {
10901
10901
  const paths = groups.get(base);
10902
- if (paths) paths.push(path84);
10903
- else groups.set(base, [path84]);
10902
+ if (paths) paths.push(path90);
10903
+ else groups.set(base, [path90]);
10904
10904
  }
10905
10905
  return [...groups].map(([base, paths]) => ({ base, paths: paths.sort() }));
10906
10906
  }
10907
10907
  async function dirtyPaths(cwd, bases) {
10908
10908
  const output = await execGit(cwd, ["diff", "--name-only", "HEAD"]);
10909
- return output.split("\n").filter((path84) => path84 && !bases.has(path84)).sort();
10909
+ return output.split("\n").filter((path90) => path90 && !bases.has(path90)).sort();
10910
10910
  }
10911
10911
 
10912
10912
  // src/commands/sessions/web/scopedDiff.ts
@@ -10915,8 +10915,8 @@ async function scopedDiff(cwd, session, scope) {
10915
10915
  if (scope.kind === "commit") return commitDiff(cwd, scope.sha);
10916
10916
  return await trackedScopeDiff(cwd, session, scope) + await untrackedDiff(cwd);
10917
10917
  }
10918
- async function untrackedFileDiff(cwd, path84) {
10919
- return execGit(cwd, ["diff", "--no-index", "--", "/dev/null", path84], {
10918
+ async function untrackedFileDiff(cwd, path90) {
10919
+ return execGit(cwd, ["diff", "--no-index", "--", "/dev/null", path90], {
10920
10920
  maxBuffer: MAX_DIFF_BYTES,
10921
10921
  allowFailure: true
10922
10922
  });
@@ -10929,7 +10929,7 @@ async function untrackedDiff(cwd) {
10929
10929
  ]);
10930
10930
  const paths = list5.split("\n").filter(Boolean);
10931
10931
  const diffs = await Promise.all(
10932
- paths.map((path84) => untrackedFileDiff(cwd, path84))
10932
+ paths.map((path90) => untrackedFileDiff(cwd, path90))
10933
10933
  );
10934
10934
  return diffs.join("");
10935
10935
  }
@@ -11022,9 +11022,9 @@ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve10
11022
11022
  function repoRoot(cwd) {
11023
11023
  return resolve10(toGitCwd(cwd));
11024
11024
  }
11025
- function resolveWithinCwd(cwd, path84) {
11025
+ function resolveWithinCwd(cwd, path90) {
11026
11026
  const root = repoRoot(cwd);
11027
- const target = resolve10(root, path84);
11027
+ const target = resolve10(root, path90);
11028
11028
  const rel = relative2(root, target);
11029
11029
  if (rel === "" || rel.startsWith("..") || isAbsolute2(rel)) return null;
11030
11030
  return target;
@@ -11034,14 +11034,14 @@ function resolveWithinCwd(cwd, path84) {
11034
11034
  function getFileTarget(req, res) {
11035
11035
  const cwd = getCwdParam(req, res);
11036
11036
  if (!cwd) return null;
11037
- const path84 = new URL(req.url ?? "/", "http://localhost").searchParams.get(
11037
+ const path90 = new URL(req.url ?? "/", "http://localhost").searchParams.get(
11038
11038
  "path"
11039
11039
  );
11040
- if (!path84) {
11040
+ if (!path90) {
11041
11041
  respondJson(res, 400, { error: "Missing path" });
11042
11042
  return null;
11043
11043
  }
11044
- const target = resolveWithinCwd(cwd, path84);
11044
+ const target = resolveWithinCwd(cwd, path90);
11045
11045
  if (!target) {
11046
11046
  respondJson(res, 400, { error: "Path outside cwd" });
11047
11047
  return null;
@@ -11116,11 +11116,11 @@ function globalConfigTargetFor(cwd) {
11116
11116
 
11117
11117
  // src/commands/config/globalConfigFileLabel.ts
11118
11118
  var WINDOWS_MOUNT_PREFIX = "/mnt/";
11119
- function globalConfigFileLabel(path84) {
11120
- if (path84 === getGlobalConfigPath()) return "~/.assist.yml";
11121
- if (path84.startsWith(WINDOWS_MOUNT_PREFIX))
11122
- return `${path84} on the Windows host`;
11123
- return path84;
11119
+ function globalConfigFileLabel(path90) {
11120
+ if (path90 === getGlobalConfigPath()) return "~/.assist.yml";
11121
+ if (path90.startsWith(WINDOWS_MOUNT_PREFIX))
11122
+ return `${path90} on the Windows host`;
11123
+ return path90;
11124
11124
  }
11125
11125
 
11126
11126
  // src/commands/config/readRawConfigLayers.ts
@@ -11177,35 +11177,35 @@ function isPlainRecord(value) {
11177
11177
  }
11178
11178
 
11179
11179
  // src/shared/mapConfigSecrets.ts
11180
- function mapChildren(value, path84, childNode, map) {
11180
+ function mapChildren(value, path90, childNode, map) {
11181
11181
  if (!isPlainRecord(value)) return value;
11182
11182
  return Object.fromEntries(
11183
11183
  Object.entries(value).map(([name, child]) => [
11184
11184
  name,
11185
- walk(child, [...path84, name], childNode(name), map)
11185
+ walk(child, [...path90, name], childNode(name), map)
11186
11186
  ])
11187
11187
  );
11188
11188
  }
11189
- function mapItems(value, path84, item, map) {
11189
+ function mapItems(value, path90, item, map) {
11190
11190
  if (!Array.isArray(value)) return value;
11191
- return value.map((entry, index3) => walk(entry, [...path84, index3], item, map));
11191
+ return value.map((entry, index3) => walk(entry, [...path90, index3], item, map));
11192
11192
  }
11193
- function walk(value, path84, node, map) {
11193
+ function walk(value, path90, node, map) {
11194
11194
  if (!node || value === void 0 || value === null) return value;
11195
- if (node.secret) return map(value, path84);
11195
+ if (node.secret) return map(value, path90);
11196
11196
  switch (node.kind) {
11197
11197
  case "object":
11198
11198
  case "unionOfObjects":
11199
11199
  return mapChildren(
11200
11200
  value,
11201
- path84,
11201
+ path90,
11202
11202
  (name) => configNodeField(node, name),
11203
11203
  map
11204
11204
  );
11205
11205
  case "objectList":
11206
- return mapItems(value, path84, node.item, map);
11206
+ return mapItems(value, path90, node.item, map);
11207
11207
  case "record":
11208
- return mapChildren(value, path84, () => node.value, map);
11208
+ return mapChildren(value, path90, () => node.value, map);
11209
11209
  default:
11210
11210
  return value;
11211
11211
  }
@@ -11230,9 +11230,9 @@ function isTraversable(value) {
11230
11230
  function stepInto(current, key) {
11231
11231
  return isTraversable(current) ? current[key] : void 0;
11232
11232
  }
11233
- function getNestedValue(obj, path84) {
11233
+ function getNestedValue(obj, path90) {
11234
11234
  let current = obj;
11235
- for (const key of path84.split(".")) current = stepInto(current, key);
11235
+ for (const key of path90.split(".")) current = stepInto(current, key);
11236
11236
  return current;
11237
11237
  }
11238
11238
 
@@ -11282,9 +11282,9 @@ function step(node, segment) {
11282
11282
  return void 0;
11283
11283
  }
11284
11284
  }
11285
- function findConfigNode(root, path84) {
11285
+ function findConfigNode(root, path90) {
11286
11286
  let current = root;
11287
- for (const segment of path84) {
11287
+ for (const segment of path90) {
11288
11288
  if (!current) return void 0;
11289
11289
  current = step(current, segment);
11290
11290
  }
@@ -11301,34 +11301,34 @@ function nameSegment(name) {
11301
11301
  return name === RECORD_ENTRY_TOKEN ? { kind: "entry" } : { kind: "key", name };
11302
11302
  }
11303
11303
  function parseConfigPath(text18) {
11304
- const path84 = [];
11304
+ const path90 = [];
11305
11305
  let at2 = 0;
11306
11306
  while (at2 < text18.length) {
11307
11307
  if (text18[at2] === "[") {
11308
11308
  const close = text18.indexOf("]", at2);
11309
11309
  const segment = close === -1 ? void 0 : bracketSegment(text18.slice(at2 + 1, close));
11310
11310
  if (!segment) return void 0;
11311
- path84.push(segment);
11311
+ path90.push(segment);
11312
11312
  at2 = close + 1;
11313
11313
  continue;
11314
11314
  }
11315
11315
  if (text18[at2] === ".") {
11316
- if (path84.length === 0) return void 0;
11316
+ if (path90.length === 0) return void 0;
11317
11317
  at2 += 1;
11318
11318
  }
11319
11319
  const start3 = at2;
11320
11320
  while (at2 < text18.length && text18[at2] !== "." && text18[at2] !== "[") at2 += 1;
11321
11321
  const name = text18.slice(start3, at2);
11322
11322
  if (!name) return void 0;
11323
- path84.push(nameSegment(name));
11323
+ path90.push(nameSegment(name));
11324
11324
  }
11325
- return path84;
11325
+ return path90;
11326
11326
  }
11327
11327
 
11328
11328
  // src/commands/config/configEntryNode.ts
11329
11329
  function configEntryNode(root, key) {
11330
- const path84 = parseConfigPath(key);
11331
- return path84 ? findConfigNode(root, path84) : void 0;
11330
+ const path90 = parseConfigPath(key);
11331
+ return path90 ? findConfigNode(root, path90) : void 0;
11332
11332
  }
11333
11333
 
11334
11334
  // src/commands/config/configHelpForKey.ts
@@ -11463,7 +11463,7 @@ function findSynthesisForBranch(repoReviewsDir, branch2) {
11463
11463
  const parent = dirname21(branchKeyPath);
11464
11464
  const branchPrefix = basename8(branchKeyPath);
11465
11465
  if (!existsSync32(parent)) return null;
11466
- const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join29(parent, name, "synthesis.md")).filter((path84) => existsSync32(path84)).map((path84) => ({ path: path84, mtime: statSync4(path84).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
11466
+ const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join29(parent, name, "synthesis.md")).filter((path90) => existsSync32(path90)).map((path90) => ({ path: path90, mtime: statSync4(path90).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
11467
11467
  return synthesisFiles[0]?.path ?? null;
11468
11468
  }
11469
11469
 
@@ -11493,12 +11493,12 @@ async function getReviewSynthesis(req, res) {
11493
11493
  const cwd = getCwdParam(req, res);
11494
11494
  if (!cwd) return;
11495
11495
  try {
11496
- const path84 = await resolveSynthesisPath(cwd);
11497
- if (!path84) {
11496
+ const path90 = await resolveSynthesisPath(cwd);
11497
+ if (!path90) {
11498
11498
  respondJson(res, 404, { error: "No synthesis found" });
11499
11499
  return;
11500
11500
  }
11501
- respondJson(res, 200, { synthesis: readFileSync21(path84, "utf8") });
11501
+ respondJson(res, 200, { synthesis: readFileSync21(path90, "utf8") });
11502
11502
  } catch {
11503
11503
  respondJson(res, 404, { error: "No synthesis found" });
11504
11504
  }
@@ -11581,8 +11581,8 @@ function parseDiffNameStatus(output) {
11581
11581
  if (!status3 || fields.length < 2) continue;
11582
11582
  const category = categorize(status3[0]);
11583
11583
  if (!category) continue;
11584
- const path84 = fields[fields.length - 1];
11585
- if (path84) result[category].push(path84);
11584
+ const path90 = fields[fields.length - 1];
11585
+ if (path90) result[category].push(path90);
11586
11586
  }
11587
11587
  return result;
11588
11588
  }
@@ -11718,21 +11718,21 @@ function subsequenceScore(text18, query) {
11718
11718
  }
11719
11719
  return score - Math.min(text18.length, MAX_LENGTH_PENALTY);
11720
11720
  }
11721
- function scoreFilePath(path84, query) {
11721
+ function scoreFilePath(path90, query) {
11722
11722
  const needle = query.trim().toLowerCase();
11723
11723
  if (!needle) return 0;
11724
- const basename26 = path84.slice(path84.lastIndexOf("/") + 1);
11724
+ const basename26 = path90.slice(path90.lastIndexOf("/") + 1);
11725
11725
  const inBasename = subsequenceScore(basename26, needle);
11726
11726
  if (inBasename !== null) return BASENAME_WEIGHT + inBasename;
11727
- return subsequenceScore(path84, needle);
11727
+ return subsequenceScore(path90, needle);
11728
11728
  }
11729
11729
 
11730
11730
  // src/commands/sessions/web/rankFilePaths.ts
11731
11731
  function rankFilePaths(paths, query, limit) {
11732
11732
  const scored = [];
11733
- for (const path84 of paths) {
11734
- const score = scoreFilePath(path84, query);
11735
- if (score !== null) scored.push({ path: path84, score });
11733
+ for (const path90 of paths) {
11734
+ const score = scoreFilePath(path90, query);
11735
+ if (score !== null) scored.push({ path: path90, score });
11736
11736
  }
11737
11737
  scored.sort((a, b) => b.score - a.score || a.path.localeCompare(b.path));
11738
11738
  return scored.slice(0, limit).map((entry) => entry.path);
@@ -11897,17 +11897,33 @@ import path32 from "path";
11897
11897
  import { existsSync as existsSync34, readFileSync as readFileSync22 } from "fs";
11898
11898
  import path31 from "path";
11899
11899
 
11900
- // src/commands/rules/parseRulesSection.ts
11900
+ // src/commands/rules/rulesSectionRange.ts
11901
11901
  var RULES_HEADING = /^##\s+rules\s*$/i;
11902
11902
  var SECTION_END = /^#{1,2}\s/;
11903
11903
  var RULE_BULLET = /^\s*[-*]\s+\*\*\s*([^*]+?)\s*\*\*\s*(?:[—–:-]\s*)?(.*)$/;
11904
+ function rulesSectionRange(lines2) {
11905
+ const start3 = lines2.findIndex((line) => RULES_HEADING.test(line));
11906
+ if (start3 === -1) return void 0;
11907
+ const offset = lines2.slice(start3 + 1).findIndex((line) => SECTION_END.test(line));
11908
+ return { start: start3, end: offset === -1 ? lines2.length : start3 + 1 + offset };
11909
+ }
11910
+ function contentLines(content) {
11911
+ const trimmed = content.replace(/\s+$/, "");
11912
+ return trimmed === "" ? [] : trimmed.split(/\r?\n/);
11913
+ }
11914
+ function appendRulesSection(lines2, entry) {
11915
+ const preamble = lines2.length === 0 ? [] : [...lines2, ""];
11916
+ return `${[...preamble, "## Rules", "", entry].join("\n")}
11917
+ `;
11918
+ }
11919
+
11920
+ // src/commands/rules/parseRulesSection.ts
11904
11921
  function parseRulesSection(content) {
11905
11922
  const lines2 = content.split(/\r?\n/);
11906
- const start3 = lines2.findIndex((line) => RULES_HEADING.test(line));
11907
- if (start3 === -1) return [];
11923
+ const range = rulesSectionRange(lines2);
11924
+ if (!range) return [];
11908
11925
  const rules3 = [];
11909
- for (const line of lines2.slice(start3 + 1)) {
11910
- if (SECTION_END.test(line)) break;
11926
+ for (const line of lines2.slice(range.start + 1, range.end)) {
11911
11927
  const match = RULE_BULLET.exec(line);
11912
11928
  if (!match) continue;
11913
11929
  const code = match[1].trim();
@@ -12282,38 +12298,38 @@ async function restartWeb(req, res, deps2 = {}) {
12282
12298
  import { relative as relative3 } from "path";
12283
12299
 
12284
12300
  // src/commands/sessions/web/revertPathChanges.ts
12285
- async function isTracked(cwd, path84) {
12301
+ async function isTracked(cwd, path90) {
12286
12302
  try {
12287
- await execGit(cwd, ["ls-files", "--error-unmatch", "--", path84]);
12303
+ await execGit(cwd, ["ls-files", "--error-unmatch", "--", path90]);
12288
12304
  return true;
12289
12305
  } catch {
12290
12306
  return false;
12291
12307
  }
12292
12308
  }
12293
- async function isInHead(cwd, path84) {
12294
- const listing = await execGit(cwd, ["ls-tree", "HEAD", "--", path84]);
12309
+ async function isInHead(cwd, path90) {
12310
+ const listing = await execGit(cwd, ["ls-tree", "HEAD", "--", path90]);
12295
12311
  return listing.trim().length > 0;
12296
12312
  }
12297
- async function revertPathChanges(cwd, path84) {
12298
- if (!await isTracked(cwd, path84)) {
12299
- await execGit(cwd, ["clean", "-f", "--", path84]);
12313
+ async function revertPathChanges(cwd, path90) {
12314
+ if (!await isTracked(cwd, path90)) {
12315
+ await execGit(cwd, ["clean", "-f", "--", path90]);
12300
12316
  return;
12301
12317
  }
12302
- if (await isInHead(cwd, path84)) {
12303
- await execGit(cwd, ["checkout", "HEAD", "--", path84]);
12318
+ if (await isInHead(cwd, path90)) {
12319
+ await execGit(cwd, ["checkout", "HEAD", "--", path90]);
12304
12320
  return;
12305
12321
  }
12306
- await execGit(cwd, ["rm", "-f", "--", path84]);
12322
+ await execGit(cwd, ["rm", "-f", "--", path90]);
12307
12323
  }
12308
12324
 
12309
12325
  // src/commands/sessions/web/revertDiffFile.ts
12310
12326
  async function revertDiffFile(req, res) {
12311
12327
  const resolved = getFileTarget(req, res);
12312
12328
  if (!resolved) return;
12313
- const path84 = relative3(repoRoot(resolved.cwd), resolved.target);
12329
+ const path90 = relative3(repoRoot(resolved.cwd), resolved.target);
12314
12330
  try {
12315
- await revertPathChanges(resolved.cwd, path84);
12316
- respondJson(res, 200, { reverted: path84 });
12331
+ await revertPathChanges(resolved.cwd, path90);
12332
+ respondJson(res, 200, { reverted: path90 });
12317
12333
  } catch (error) {
12318
12334
  respondJson(res, 500, {
12319
12335
  error: error instanceof Error ? error.message : "Failed to revert file"
@@ -12335,7 +12351,7 @@ async function readJsonBody(req) {
12335
12351
  function requestedPaths(body) {
12336
12352
  const paths = body.paths;
12337
12353
  if (!Array.isArray(paths)) return null;
12338
- if (paths.some((path84) => typeof path84 !== "string")) return null;
12354
+ if (paths.some((path90) => typeof path90 !== "string")) return null;
12339
12355
  return paths;
12340
12356
  }
12341
12357
  async function revertDiffPaths(req, res) {
@@ -12355,10 +12371,10 @@ async function revertDiffPaths(req, res) {
12355
12371
  const root = repoRoot(cwd);
12356
12372
  const reverted = [];
12357
12373
  const failed2 = [];
12358
- for (const path84 of paths) {
12359
- const target = resolveWithinCwd(cwd, path84);
12374
+ for (const path90 of paths) {
12375
+ const target = resolveWithinCwd(cwd, path90);
12360
12376
  if (!target) {
12361
- failed2.push({ path: path84, error: "Path outside cwd" });
12377
+ failed2.push({ path: path90, error: "Path outside cwd" });
12362
12378
  continue;
12363
12379
  }
12364
12380
  const relativePath = relative4(root, target);
@@ -12448,11 +12464,11 @@ function coerceStructuredConfigValue(key, raw) {
12448
12464
  };
12449
12465
  }
12450
12466
  function formatIssue(key, issue) {
12451
- const path84 = formatConfigPath([
12467
+ const path90 = formatConfigPath([
12452
12468
  { kind: "key", name: key },
12453
12469
  ...issue.path.map(toSegment)
12454
12470
  ]);
12455
- return `${path84}: ${issue.message}`;
12471
+ return `${path90}: ${issue.message}`;
12456
12472
  }
12457
12473
  function toSegment(part) {
12458
12474
  return typeof part === "number" ? { kind: "index", index: part } : { kind: "key", name: String(part) };
@@ -12547,9 +12563,9 @@ function coerceUnion(key, raw, types) {
12547
12563
  }
12548
12564
 
12549
12565
  // src/shared/valueAtConfigPath.ts
12550
- function valueAtConfigPath(value, path84) {
12566
+ function valueAtConfigPath(value, path90) {
12551
12567
  let current = value;
12552
- for (const key of path84) {
12568
+ for (const key of path90) {
12553
12569
  if (typeof key === "number") {
12554
12570
  if (!Array.isArray(current)) return void 0;
12555
12571
  current = current[key];
@@ -12566,7 +12582,7 @@ function restoreConfigSecrets(value, stored, node) {
12566
12582
  return mapConfigSecrets(
12567
12583
  value,
12568
12584
  node,
12569
- (secret, path84) => isRedactedSecret(secret) ? valueAtConfigPath(stored, path84) : secret
12585
+ (secret, path90) => isRedactedSecret(secret) ? valueAtConfigPath(stored, path90) : secret
12570
12586
  );
12571
12587
  }
12572
12588
 
@@ -12615,8 +12631,8 @@ function stepIntoNested(container, key, nextKey) {
12615
12631
  }
12616
12632
  return ensureObject(container, resolved);
12617
12633
  }
12618
- function setNestedValue(obj, path84, value) {
12619
- const keys = path84.split(".");
12634
+ function setNestedValue(obj, path90, value) {
12635
+ const keys = path90.split(".");
12620
12636
  const result = { ...obj };
12621
12637
  let current = result;
12622
12638
  for (let i = 0; i < keys.length - 1; i++) {
@@ -12643,8 +12659,8 @@ function formatIssue2(issue, key) {
12643
12659
  return issue.keys.map(
12644
12660
  (unrecognized) => `${[...issue.path, unrecognized].join(".")}: Unrecognized key`
12645
12661
  );
12646
- const path84 = issue.path.length > 0 ? issue.path.join(".") : key;
12647
- return [`${path84}: ${issue.message}`];
12662
+ const path90 = issue.path.length > 0 ? issue.path.join(".") : key;
12663
+ return [`${path90}: ${issue.message}`];
12648
12664
  }
12649
12665
 
12650
12666
  // src/commands/config/applyConfigSet.ts
@@ -12901,8 +12917,8 @@ function removeAt(container, keys) {
12901
12917
  }
12902
12918
  return removeFromChild(container, key, rest);
12903
12919
  }
12904
- function unsetNestedValue(obj, path84) {
12905
- const { container, removed } = removeAt(obj, path84.split("."));
12920
+ function unsetNestedValue(obj, path90) {
12921
+ const { container, removed } = removeAt(obj, path90.split("."));
12906
12922
  return { config: container, removed };
12907
12923
  }
12908
12924
 
@@ -14016,9 +14032,9 @@ function originToSshUrl(origin) {
14016
14032
  const firstSlash = origin.indexOf("/");
14017
14033
  if (firstSlash <= 0) return null;
14018
14034
  const host = origin.slice(0, firstSlash);
14019
- const path84 = origin.slice(firstSlash + 1);
14020
- if (!path84) return null;
14021
- return `git@${host}:${path84}.git`;
14035
+ const path90 = origin.slice(firstSlash + 1);
14036
+ if (!path90) return null;
14037
+ return `git@${host}:${path90}.git`;
14022
14038
  }
14023
14039
 
14024
14040
  // src/commands/backlog/cloneRepo.ts
@@ -17046,9 +17062,9 @@ var __dirname4 = dirname23(__filename3);
17046
17062
  function packageRoot() {
17047
17063
  return __dirname4;
17048
17064
  }
17049
- function readLines(path84) {
17050
- if (!existsSync38(path84)) return [];
17051
- return readFileSync26(path84, "utf8").split("\n").filter((line) => line.trim() !== "");
17065
+ function readLines(path90) {
17066
+ if (!existsSync38(path90)) return [];
17067
+ return readFileSync26(path90, "utf8").split("\n").filter((line) => line.trim() !== "");
17052
17068
  }
17053
17069
  var cachedReads;
17054
17070
  var cachedWrites;
@@ -17250,11 +17266,11 @@ function isTruncator(part) {
17250
17266
  return TRUNCATOR_BINARIES.includes(binary) || PIPED_TRUNCATOR_RE.test(part);
17251
17267
  }
17252
17268
  function findTruncatedReadDeny(parts) {
17253
- const read2 = parts.map(matchUntruncatableRead).find(Boolean);
17254
- if (!read2 || !parts.some(isTruncator)) return void 0;
17269
+ const read3 = parts.map(matchUntruncatableRead).find(Boolean);
17270
+ if (!read3 || !parts.some(isTruncator)) return void 0;
17255
17271
  return {
17256
17272
  permissionDecision: "deny",
17257
- permissionDecisionReason: `Do not pipe '${read2}' through head or tail. Plan, Activity and Comments print at the end of the output, so a truncated read drops them and leaves you assuming the item has none. Run '${read2} <id>' bare and read all of it, or use a focused view: 'assist backlog comments <id>' for comments only.`
17273
+ permissionDecisionReason: `Do not pipe '${read3}' through head or tail. Plan, Activity and Comments print at the end of the output, so a truncated read drops them and leaves you assuming the item has none. Run '${read3} <id>' bare and read all of it, or use a focused view: 'assist backlog comments <id>' for comments only.`
17258
17274
  };
17259
17275
  }
17260
17276
 
@@ -17569,14 +17585,14 @@ function showProgress(p, label2) {
17569
17585
  const pct = Math.round(p.done / p.total * 100);
17570
17586
  process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
17571
17587
  }
17572
- async function resolveCommand(cli, path84, description, depth, p) {
17573
- showProgress(p, path84.join(" "));
17574
- const subHelp = await runHelp([cli, ...path84]);
17588
+ async function resolveCommand(cli, path90, description, depth, p) {
17589
+ showProgress(p, path90.join(" "));
17590
+ const subHelp = await runHelp([cli, ...path90]);
17575
17591
  if (!subHelp || !hasSubcommands(subHelp)) {
17576
- return [{ path: path84, description }];
17592
+ return [{ path: path90, description }];
17577
17593
  }
17578
- const children = await discoverAt(cli, path84, depth + 1, p);
17579
- return children.length > 0 ? children : [{ path: path84, description }];
17594
+ const children = await discoverAt(cli, path90, depth + 1, p);
17595
+ return children.length > 0 ? children : [{ path: path90, description }];
17580
17596
  }
17581
17597
  async function discoverAt(cli, parentPath, depth, p) {
17582
17598
  if (depth > SAFETY_DEPTH) return [];
@@ -17724,9 +17740,9 @@ function logPath(cli) {
17724
17740
  return join39(homedir17(), ".assist", `cli-discover-${safeName}.log`);
17725
17741
  }
17726
17742
  function readCache(cli) {
17727
- const path84 = logPath(cli);
17728
- if (!existsSync40(path84)) return void 0;
17729
- return readFileSync28(path84, "utf8");
17743
+ const path90 = logPath(cli);
17744
+ if (!existsSync40(path90)) return void 0;
17745
+ return readFileSync28(path90, "utf8");
17730
17746
  }
17731
17747
  function writeCache(cli, output) {
17732
17748
  const dir = join39(homedir17(), ".assist");
@@ -17886,9 +17902,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
17886
17902
  }
17887
17903
  const cutoff = Date.now() - STALE_AFTER_MS;
17888
17904
  for (const entry of entries) {
17889
- const path84 = join41(dir, entry);
17905
+ const path90 = join41(dir, entry);
17890
17906
  try {
17891
- if (statSync7(path84).mtimeMs < cutoff) unlinkSync7(path84);
17907
+ if (statSync7(path90).mtimeMs < cutoff) unlinkSync7(path90);
17892
17908
  } catch {
17893
17909
  continue;
17894
17910
  }
@@ -17898,10 +17914,10 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
17898
17914
  // src/commands/codeComment/readPinState.ts
17899
17915
  import { existsSync as existsSync41, readFileSync as readFileSync29 } from "fs";
17900
17916
  function readPinState(pin) {
17901
- const path84 = getPinStatePath(pin);
17902
- if (!existsSync41(path84)) return void 0;
17917
+ const path90 = getPinStatePath(pin);
17918
+ if (!existsSync41(path90)) return void 0;
17903
17919
  try {
17904
- const state = JSON.parse(readFileSync29(path84, "utf8"));
17920
+ const state = JSON.parse(readFileSync29(path90, "utf8"));
17905
17921
  if (state.pin !== pin) return void 0;
17906
17922
  return state;
17907
17923
  } catch {
@@ -19040,11 +19056,11 @@ async function loadPath(source) {
19040
19056
  }
19041
19057
  }
19042
19058
  async function criteriaExtension() {
19043
- const path84 = await loadPath(criteriaExtensionDir());
19059
+ const path90 = await loadPath(criteriaExtensionDir());
19044
19060
  console.log(
19045
19061
  chalk139.bold("acceptance criteria outliner \u2014 GitHub browser extension")
19046
19062
  );
19047
- console.log(chalk139.dim(`load the unpacked extension from ${path84}`));
19063
+ console.log(chalk139.dim(`load the unpacked extension from ${path90}`));
19048
19064
  }
19049
19065
 
19050
19066
  // src/commands/criteriaExtension/signCriteriaExtension.ts
@@ -19169,10 +19185,10 @@ async function signCriteriaExtension() {
19169
19185
  process.exitCode = 1;
19170
19186
  return;
19171
19187
  }
19172
- const path84 = await signedAddonInstallPath(
19188
+ const path90 = await signedAddonInstallPath(
19173
19189
  await copySignedXpi(xpi, ARTIFACTS_DIR)
19174
19190
  );
19175
- console.log(chalk141.dim(`install the signed add-on from ${path84}`));
19191
+ console.log(chalk141.dim(`install the signed add-on from ${path90}`));
19176
19192
  }
19177
19193
 
19178
19194
  // src/commands/registerCriteriaExtension.ts
@@ -19270,10 +19286,10 @@ function getMigrationApprovalPath(migrationId) {
19270
19286
  // src/commands/dbMigration/readMigrationPinState.ts
19271
19287
  import { existsSync as existsSync46, readFileSync as readFileSync31 } from "fs";
19272
19288
  function readMigrationPinState(pin) {
19273
- const path84 = getMigrationPinPath(pin);
19274
- if (!existsSync46(path84)) return void 0;
19289
+ const path90 = getMigrationPinPath(pin);
19290
+ if (!existsSync46(path90)) return void 0;
19275
19291
  try {
19276
- const state = JSON.parse(readFileSync31(path84, "utf8"));
19292
+ const state = JSON.parse(readFileSync31(path90, "utf8"));
19277
19293
  if (state.pin !== pin) return void 0;
19278
19294
  if (!Number.isInteger(state.migrationId)) return void 0;
19279
19295
  return state;
@@ -20703,10 +20719,10 @@ function decideCommentGuard(input, existingContent) {
20703
20719
  import { existsSync as existsSync52, unlinkSync as unlinkSync11 } from "fs";
20704
20720
  function consumeMigrationApproval(migrationId) {
20705
20721
  sweepRestrictedDir();
20706
- const path84 = getMigrationApprovalPath(migrationId);
20707
- if (!existsSync52(path84)) return false;
20722
+ const path90 = getMigrationApprovalPath(migrationId);
20723
+ if (!existsSync52(path90)) return false;
20708
20724
  try {
20709
- unlinkSync11(path84);
20725
+ unlinkSync11(path90);
20710
20726
  return true;
20711
20727
  } catch {
20712
20728
  return false;
@@ -22400,11 +22416,11 @@ function recentDaemonLogLines() {
22400
22416
  // src/commands/sessions/daemon/worktree/canonicalTreePath.ts
22401
22417
  import { realpathSync as realpathSync2 } from "fs";
22402
22418
  import { resolve as resolve14 } from "path";
22403
- function canonicalTreePath(path84) {
22419
+ function canonicalTreePath(path90) {
22404
22420
  try {
22405
- return realpathSync2(path84);
22421
+ return realpathSync2(path90);
22406
22422
  } catch {
22407
- return resolve14(path84);
22423
+ return resolve14(path90);
22408
22424
  }
22409
22425
  }
22410
22426
 
@@ -22457,22 +22473,22 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
22457
22473
  const registered = new Set(listWorktreePaths(clone));
22458
22474
  const branches = new Set(listLocalBranches(clone));
22459
22475
  const isTaken = (candidate) => registered.has(candidate) || existsSync55(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename16(candidate));
22460
- const path84 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
22476
+ const path90 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
22461
22477
  const start3 = worktreeStartPoint(clone, strategy.trunk);
22462
22478
  gitSync(clone, [
22463
22479
  "worktree",
22464
22480
  "add",
22465
22481
  start3.track ? "--track" : "--no-track",
22466
22482
  "-b",
22467
- basename16(path84),
22468
- path84,
22483
+ basename16(path90),
22484
+ path90,
22469
22485
  start3.ref
22470
22486
  ]);
22471
- recordWorktree(path84, clone, getCurrentOrigin(clone));
22487
+ recordWorktree(path90, clone, getCurrentOrigin(clone));
22472
22488
  daemonLog(
22473
- start3.track ? `worktree allocated ${path84} (branch ${basename16(path84)} tracking ${start3.ref}) for clone ${clone}` : `worktree allocated ${path84} (branch ${basename16(path84)} off ${start3.ref}, no mainline tracking) for clone ${clone}`
22489
+ start3.track ? `worktree allocated ${path90} (branch ${basename16(path90)} tracking ${start3.ref}) for clone ${clone}` : `worktree allocated ${path90} (branch ${basename16(path90)} off ${start3.ref}, no mainline tracking) for clone ${clone}`
22474
22490
  );
22475
- return path84;
22491
+ return path90;
22476
22492
  }
22477
22493
 
22478
22494
  // src/commands/sessions/daemon/worktree/keptInTree.ts
@@ -22613,13 +22629,13 @@ function allocateTree(requestedCwd, boundTreeRoots2, options2 = {}) {
22613
22629
  if (forcedSpill) daemonLog(forcedSpill);
22614
22630
  else if (reusesClone(clone, boundTreeRoots2, reuse))
22615
22631
  return { cwd: clone, kind: "primary", created: false, clone };
22616
- const path84 = createWorktree(
22632
+ const path90 = createWorktree(
22617
22633
  clone,
22618
22634
  { root: cfg.root, trunk: cfg.trunk },
22619
22635
  boundTreeRoots2,
22620
22636
  options2.replacesTree
22621
22637
  );
22622
- return { cwd: path84, kind: "worktree", created: true, clone };
22638
+ return { cwd: path90, kind: "worktree", created: true, clone };
22623
22639
  }
22624
22640
 
22625
22641
  // src/commands/sessions/daemon/describePersistedSession.ts
@@ -22950,13 +22966,13 @@ function worktreeHoldingBranch(cwd, branch2) {
22950
22966
  const listing = gitSyncOrNull(cwd, ["worktree", "list", "--porcelain"]);
22951
22967
  if (!listing) return null;
22952
22968
  const here = gitSyncOrNull(cwd, ["rev-parse", "--show-toplevel"]);
22953
- let path84 = null;
22969
+ let path90 = null;
22954
22970
  for (const line of listing.split("\n")) {
22955
22971
  const trimmed = line.trim();
22956
22972
  if (trimmed.startsWith("worktree "))
22957
- path84 = trimmed.slice("worktree ".length).trim();
22973
+ path90 = trimmed.slice("worktree ".length).trim();
22958
22974
  else if (trimmed === `branch refs/heads/${branch2}`)
22959
- return path84 && path84 !== here ? path84 : null;
22975
+ return path90 && path90 !== here ? path90 : null;
22960
22976
  }
22961
22977
  return null;
22962
22978
  }
@@ -23998,9 +24014,9 @@ function parseRscRows(flight) {
23998
24014
  }
23999
24015
  function makeRscResolver(rows) {
24000
24016
  return (ref) => {
24001
- const [id, ...path84] = ref.slice(1).replace(/^[L@]/, "").split(":");
24017
+ const [id, ...path90] = ref.slice(1).replace(/^[L@]/, "").split(":");
24002
24018
  let v = rows[id];
24003
- for (const key of path84) {
24019
+ for (const key of path90) {
24004
24020
  if (v == null || typeof v !== "object") return void 0;
24005
24021
  v = v[key];
24006
24022
  }
@@ -24703,16 +24719,16 @@ function validateLine(line) {
24703
24719
  process.exit(1);
24704
24720
  }
24705
24721
  }
24706
- async function comment2(path84, line, body, startLine) {
24722
+ async function comment2(path90, line, body, startLine) {
24707
24723
  validateBody(body);
24708
24724
  validateLine(line);
24709
24725
  if (startLine !== void 0) validateLine(startLine);
24710
24726
  const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
24711
- await reviewProposedPrComment(`Comment on ${path84}:${range}`, body, null);
24727
+ await reviewProposedPrComment(`Comment on ${path90}:${range}`, body, null);
24712
24728
  try {
24713
24729
  const prId = getCurrentPrNodeId();
24714
- postReviewComment({ prId, body, path: path84, line, startLine });
24715
- console.log(`Added review comment on ${path84}:${range}`);
24730
+ postReviewComment({ prId, body, path: path90, line, startLine });
24731
+ console.log(`Added review comment on ${path90}:${range}`);
24716
24732
  } catch (error) {
24717
24733
  if (isGhNotInstalled(error)) {
24718
24734
  console.error("Error: GitHub CLI (gh) is not installed.");
@@ -25914,9 +25930,9 @@ function registerPrsComments(prsCommand) {
25914
25930
  });
25915
25931
  prsCommand.command("comment <path> <line> <body>").description(
25916
25932
  "Add a line comment to the pending review (body of - reads it from stdin)"
25917
- ).action(async (path84, line, body) => {
25933
+ ).action(async (path90, line, body) => {
25918
25934
  await comment2(
25919
- path84,
25935
+ path90,
25920
25936
  Number.parseInt(line, 10),
25921
25937
  await readBodyArgument(body)
25922
25938
  );
@@ -26380,10 +26396,10 @@ function resolveOpSecret(reference) {
26380
26396
  }
26381
26397
 
26382
26398
  // src/commands/ravendb/ravenFetch.ts
26383
- async function ravenFetch(connection, path84) {
26399
+ async function ravenFetch(connection, path90) {
26384
26400
  const apiKey = resolveOpSecret(connection.apiKeyRef);
26385
26401
  let accessToken = await getAccessToken(apiKey);
26386
- const url = `${connection.url}${path84}`;
26402
+ const url = `${connection.url}${path90}`;
26387
26403
  const headers = {
26388
26404
  Authorization: `Bearer ${accessToken}`,
26389
26405
  "Content-Type": "application/json"
@@ -26473,16 +26489,16 @@ import chalk193 from "chalk";
26473
26489
  // src/commands/ravendb/buildQueryPath.ts
26474
26490
  function buildQueryPath(opts) {
26475
26491
  const db = encodeURIComponent(opts.db);
26476
- let path84;
26492
+ let path90;
26477
26493
  if (opts.collection) {
26478
- path84 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
26494
+ path90 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
26479
26495
  } else {
26480
- path84 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
26496
+ path90 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
26481
26497
  }
26482
26498
  if (opts.query) {
26483
- path84 += `&query=${encodeURIComponent(opts.query)}`;
26499
+ path90 += `&query=${encodeURIComponent(opts.query)}`;
26484
26500
  }
26485
- return path84;
26501
+ return path90;
26486
26502
  }
26487
26503
 
26488
26504
  // src/commands/ravendb/fetchAllPages.ts
@@ -26491,7 +26507,7 @@ async function fetchAllPages(connection, opts) {
26491
26507
  let start3 = 0;
26492
26508
  while (true) {
26493
26509
  const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
26494
- const path84 = buildQueryPath({
26510
+ const path90 = buildQueryPath({
26495
26511
  db: connection.database,
26496
26512
  collection: opts.collection,
26497
26513
  start: start3,
@@ -26499,7 +26515,7 @@ async function fetchAllPages(connection, opts) {
26499
26515
  sort: opts.sort,
26500
26516
  query: opts.query
26501
26517
  });
26502
- const data = await ravenFetch(connection, path84);
26518
+ const data = await ravenFetch(connection, path90);
26503
26519
  const results = data.Results ?? [];
26504
26520
  const totalResults = data.TotalResults ?? 0;
26505
26521
  if (results.length === 0) break;
@@ -29107,8 +29123,8 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
29107
29123
  // src/commands/review/prepareReviewDir.ts
29108
29124
  import { existsSync as existsSync61, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync38 } from "fs";
29109
29125
  function clearReviewFiles(paths) {
29110
- for (const path84 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
29111
- if (existsSync61(path84)) unlinkSync17(path84);
29126
+ for (const path90 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
29127
+ if (existsSync61(path90)) unlinkSync17(path90);
29112
29128
  }
29113
29129
  }
29114
29130
  function prepareReviewDir(paths, requestBody, force) {
@@ -30156,15 +30172,185 @@ function registerReview(program2) {
30156
30172
  );
30157
30173
  }
30158
30174
 
30159
- // src/commands/rules/listRules.ts
30160
- import path67 from "path";
30175
+ // src/commands/rules/addRule.ts
30176
+ import { existsSync as existsSync66, readFileSync as readFileSync50, writeFileSync as writeFileSync41 } from "fs";
30177
+ import path71 from "path";
30161
30178
  import chalk209 from "chalk";
30179
+
30180
+ // src/commands/rules/insertRuleBullet.ts
30181
+ function insertRuleBullet(content, code, text18) {
30182
+ const bullet = `- **${code}** \u2014 ${text18}`;
30183
+ const lines2 = contentLines(content);
30184
+ const range = rulesSectionRange(lines2);
30185
+ if (!range) return appendRulesSection(lines2, bullet);
30186
+ const body = lines2.slice(range.start + 1, range.end);
30187
+ const lastBullet = body.reduce(
30188
+ (last, line, index3) => RULE_BULLET.test(line) ? index3 : last,
30189
+ -1
30190
+ );
30191
+ const at2 = lastBullet === -1 ? range.start + 1 : range.start + lastBullet + 2;
30192
+ const inserted = lastBullet === -1 ? ["", bullet] : [bullet];
30193
+ return `${[...lines2.slice(0, at2), ...inserted, ...lines2.slice(at2)].join("\n")}
30194
+ `;
30195
+ }
30196
+
30197
+ // src/commands/rules/nextRuleCode.ts
30198
+ import { readFileSync as readFileSync47 } from "fs";
30199
+
30200
+ // src/commands/rules/findClaudeFiles.ts
30201
+ import { readdirSync as readdirSync13 } from "fs";
30202
+ import path67 from "path";
30203
+ var SKIP_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage"]);
30204
+ function findClaudeFiles(dir) {
30205
+ const results = [];
30206
+ for (const entry of readdirSync13(dir, { withFileTypes: true })) {
30207
+ if (entry.isDirectory()) {
30208
+ if (entry.name.startsWith(".") || SKIP_DIRECTORIES.has(entry.name))
30209
+ continue;
30210
+ results.push(...findClaudeFiles(path67.join(dir, entry.name)));
30211
+ } else if (entry.name === "CLAUDE.md") {
30212
+ results.push(path67.join(dir, entry.name));
30213
+ }
30214
+ }
30215
+ return results;
30216
+ }
30217
+
30218
+ // src/commands/rules/nextRuleCode.ts
30219
+ var CODE_PREFIX = "R";
30220
+ function nextRuleCode(root) {
30221
+ const numbers = findClaudeFiles(root).flatMap(
30222
+ (file) => parseRulesSection(readFileSync47(file, "utf8")).map(
30223
+ (rule) => Number(/(\d+)\s*$/.exec(rule.code)?.[1] ?? 0)
30224
+ )
30225
+ );
30226
+ return `${CODE_PREFIX}${Math.max(0, ...numbers) + 1}`;
30227
+ }
30228
+
30229
+ // src/commands/rules/resolveRuleScope.ts
30230
+ import { existsSync as existsSync64 } from "fs";
30231
+ import path68 from "path";
30232
+ function resolveRuleScope(target) {
30233
+ const resolved = path68.resolve(target);
30234
+ if (path68.basename(resolved) === "CLAUDE.md") return resolved;
30235
+ const startDir = scopeDirectory(resolved);
30236
+ const root = findRepoRoot(startDir) ?? startDir;
30237
+ let current = startDir;
30238
+ while (true) {
30239
+ const candidate = path68.join(current, "CLAUDE.md");
30240
+ if (existsSync64(candidate)) return candidate;
30241
+ if (current === root || current === path68.dirname(current)) break;
30242
+ current = path68.dirname(current);
30243
+ }
30244
+ return path68.join(root, "CLAUDE.md");
30245
+ }
30246
+
30247
+ // src/commands/rules/updateScopedRulesIndex.ts
30248
+ import { existsSync as existsSync65, readFileSync as readFileSync49, writeFileSync as writeFileSync40 } from "fs";
30249
+ import path70 from "path";
30250
+
30251
+ // src/commands/rules/scopedRuleDirectories.ts
30252
+ import { readFileSync as readFileSync48 } from "fs";
30253
+ import path69 from "path";
30254
+ function scopedRuleDirectories(root) {
30255
+ return findClaudeFiles(root).filter(
30256
+ (file) => path69.dirname(file) !== root && parseRulesSection(readFileSync48(file, "utf8")).length > 0
30257
+ ).map(
30258
+ (file) => `${path69.relative(root, path69.dirname(file)).split(path69.sep).join("/")}/`
30259
+ ).sort();
30260
+ }
30261
+
30262
+ // src/commands/rules/upsertScopedRulesPointer.ts
30263
+ var POINTER_PREFIX = "Directories with their own `## Rules`:";
30264
+ function pointerLine(directories) {
30265
+ return `${POINTER_PREFIX} ${directories.map((dir) => `\`${dir}\``).join(", ")}`;
30266
+ }
30267
+ function upsertScopedRulesPointer(content, directories) {
30268
+ const lines2 = contentLines(content);
30269
+ const range = rulesSectionRange(lines2);
30270
+ const existing = lines2.findIndex(
30271
+ (line, index3) => range !== void 0 && index3 > range.start && index3 < range.end && line.startsWith(POINTER_PREFIX)
30272
+ );
30273
+ if (directories.length === 0) {
30274
+ if (existing === -1) return content;
30275
+ const without = [...lines2.slice(0, existing), ...lines2.slice(existing + 1)];
30276
+ return `${without.join("\n").replace(/\n{3,}/g, "\n\n").trimEnd()}
30277
+ `;
30278
+ }
30279
+ const pointer = pointerLine(directories);
30280
+ if (existing !== -1) {
30281
+ if (lines2[existing] === pointer) return content;
30282
+ const replaced = [...lines2];
30283
+ replaced[existing] = pointer;
30284
+ return `${replaced.join("\n")}
30285
+ `;
30286
+ }
30287
+ if (!range) return appendRulesSection(lines2, pointer);
30288
+ let at2 = range.end;
30289
+ while (at2 > range.start + 1 && (lines2[at2 - 1] ?? "").trim() === "") at2--;
30290
+ return `${[...lines2.slice(0, at2), "", pointer, ...lines2.slice(at2)].join("\n")}
30291
+ `;
30292
+ }
30293
+
30294
+ // src/commands/rules/updateScopedRulesIndex.ts
30295
+ function updateScopedRulesIndex(root) {
30296
+ const directories = scopedRuleDirectories(root);
30297
+ const rootFile = path70.join(root, "CLAUDE.md");
30298
+ const before = existsSync65(rootFile) ? readFileSync49(rootFile, "utf8") : "";
30299
+ const after = upsertScopedRulesPointer(before, directories);
30300
+ if (after !== before) writeFileSync40(rootFile, after);
30301
+ return directories;
30302
+ }
30303
+
30304
+ // src/commands/rules/addRule.ts
30305
+ function read2(file) {
30306
+ return existsSync66(file) ? readFileSync50(file, "utf8") : "";
30307
+ }
30308
+ function addRule(text18, options2) {
30309
+ const rule = text18.trim();
30310
+ if (rule === "") {
30311
+ console.error(chalk209.red("Rule text is required"));
30312
+ process.exitCode = 1;
30313
+ return;
30314
+ }
30315
+ const target = resolveRuleScope(options2.scope ?? process.cwd());
30316
+ const targetDir = path71.dirname(target);
30317
+ const root = findRepoRoot(targetDir) ?? targetDir;
30318
+ const code = nextRuleCode(root);
30319
+ writeFileSync41(target, insertRuleBullet(read2(target), code, rule));
30320
+ updateScopedRulesIndex(root);
30321
+ console.log(
30322
+ `Added ${chalk209.cyan(code)} to ${path71.relative(process.cwd(), target) || target}`
30323
+ );
30324
+ }
30325
+
30326
+ // src/commands/rules/indexRules.ts
30327
+ import path72 from "path";
30328
+ import chalk210 from "chalk";
30329
+ function indexRules(target) {
30330
+ const startDir = scopeDirectory(path72.resolve(target ?? process.cwd()));
30331
+ const root = findRepoRoot(startDir) ?? startDir;
30332
+ const directories = updateScopedRulesIndex(root);
30333
+ const rootFile = path72.relative(process.cwd(), path72.join(root, "CLAUDE.md"));
30334
+ if (directories.length === 0) {
30335
+ console.log(
30336
+ chalk210.gray(`No directories carry their own \`## Rules\` under ${root}`)
30337
+ );
30338
+ return;
30339
+ }
30340
+ console.log(`Recorded in ${rootFile || "CLAUDE.md"}`);
30341
+ for (const directory of directories)
30342
+ console.log(` ${chalk210.cyan(directory)}`);
30343
+ }
30344
+
30345
+ // src/commands/rules/listRules.ts
30346
+ import path73 from "path";
30347
+ import chalk211 from "chalk";
30162
30348
  function listRules(target) {
30163
- const resolved = path67.resolve(target ?? process.cwd());
30349
+ const resolved = path73.resolve(target ?? process.cwd());
30164
30350
  const rules3 = readScopedRules(resolved);
30165
30351
  if (rules3.length === 0) {
30166
- const label2 = path67.relative(process.cwd(), resolved) || ".";
30167
- console.log(chalk209.gray(`No rules in scope for ${label2}`));
30352
+ const label2 = path73.relative(process.cwd(), resolved) || ".";
30353
+ console.log(chalk211.gray(`No rules in scope for ${label2}`));
30168
30354
  return;
30169
30355
  }
30170
30356
  const base = findRepoRoot(scopeDirectory(resolved));
@@ -30174,23 +30360,34 @@ function listRules(target) {
30174
30360
  if (rule.source !== shown) {
30175
30361
  shown = rule.source;
30176
30362
  console.log(
30177
- chalk209.dim(base ? path67.relative(base, rule.source) : rule.source)
30363
+ chalk211.dim(base ? path73.relative(base, rule.source) : rule.source)
30178
30364
  );
30179
30365
  }
30180
- console.log(` ${chalk209.cyan(rule.code.padEnd(width))} ${rule.text}`);
30366
+ console.log(` ${chalk211.cyan(rule.code.padEnd(width))} ${rule.text}`);
30181
30367
  }
30182
30368
  }
30183
30369
 
30184
30370
  // src/commands/registerRules.ts
30185
30371
  function registerRules(program2) {
30186
- const rulesCommand = program2.command("rules").description("Read the CLAUDE.md rules in scope for a path");
30372
+ const rulesCommand = program2.command("rules").description("Read and write the CLAUDE.md rules in scope for a path");
30187
30373
  rulesCommand.command("list [path]").description(
30188
30374
  "List the rules from the `## Rules` section of every CLAUDE.md from a path's directory up to the repo root (default: cwd)"
30189
30375
  ).action((target) => listRules(target));
30376
+ rulesCommand.command("add <text>").description(
30377
+ "Add a rule to the `## Rules` section of the scope's CLAUDE.md, allocating the next repo-wide code and creating the section when absent"
30378
+ ).option(
30379
+ "--scope <path>",
30380
+ "File or directory whose nearest CLAUDE.md receives the rule, or a CLAUDE.md path to write to directly (default: cwd)"
30381
+ ).action(
30382
+ (text18, options2) => addRule(text18, options2)
30383
+ );
30384
+ rulesCommand.command("index [path]").description(
30385
+ "Record the directories that carry their own `## Rules` in the repo root's CLAUDE.md, so scoped rules are discoverable from the root"
30386
+ ).action((target) => indexRules(target));
30190
30387
  }
30191
30388
 
30192
30389
  // src/commands/seq/seqAuth.ts
30193
- import chalk211 from "chalk";
30390
+ import chalk213 from "chalk";
30194
30391
 
30195
30392
  // src/commands/seq/loadConnections.ts
30196
30393
  function loadConnections2() {
@@ -30219,10 +30416,10 @@ function setDefaultConnection(name) {
30219
30416
  }
30220
30417
 
30221
30418
  // src/shared/assertUniqueName.ts
30222
- import chalk210 from "chalk";
30419
+ import chalk212 from "chalk";
30223
30420
  function assertUniqueName(existingNames, name) {
30224
30421
  if (existingNames.includes(name)) {
30225
- console.error(chalk210.red(`Connection "${name}" already exists.`));
30422
+ console.error(chalk212.red(`Connection "${name}" already exists.`));
30226
30423
  process.exit(1);
30227
30424
  }
30228
30425
  }
@@ -30240,18 +30437,18 @@ async function promptConnection2(existingNames) {
30240
30437
  var seqAuth = createConnectionAuth({
30241
30438
  load: loadConnections2,
30242
30439
  save: saveConnections2,
30243
- format: (c) => `${chalk211.bold(c.name)} ${c.url}`,
30440
+ format: (c) => `${chalk213.bold(c.name)} ${c.url}`,
30244
30441
  promptNew: promptConnection2,
30245
30442
  onFirst: (c) => setDefaultConnection(c.name)
30246
30443
  });
30247
30444
 
30248
30445
  // src/commands/seq/seqQuery.ts
30249
- import chalk215 from "chalk";
30446
+ import chalk217 from "chalk";
30250
30447
 
30251
30448
  // src/commands/seq/fetchSeq.ts
30252
- import chalk212 from "chalk";
30253
- async function fetchSeq(conn, path84, params) {
30254
- const url = `${conn.url}${path84}?${params}`;
30449
+ import chalk214 from "chalk";
30450
+ async function fetchSeq(conn, path90, params) {
30451
+ const url = `${conn.url}${path90}?${params}`;
30255
30452
  const response = await fetch(url, {
30256
30453
  headers: {
30257
30454
  Accept: "application/json",
@@ -30260,7 +30457,7 @@ async function fetchSeq(conn, path84, params) {
30260
30457
  });
30261
30458
  if (!response.ok) {
30262
30459
  const body = await response.text();
30263
- console.error(chalk212.red(`Seq returned ${response.status}: ${body}`));
30460
+ console.error(chalk214.red(`Seq returned ${response.status}: ${body}`));
30264
30461
  process.exit(1);
30265
30462
  }
30266
30463
  return response;
@@ -30319,23 +30516,23 @@ async function fetchSeqEvents(conn, params) {
30319
30516
  }
30320
30517
 
30321
30518
  // src/commands/seq/formatEvent.ts
30322
- import chalk213 from "chalk";
30519
+ import chalk215 from "chalk";
30323
30520
  function levelColor(level) {
30324
30521
  switch (level) {
30325
30522
  case "Fatal":
30326
- return chalk213.bgRed.white;
30523
+ return chalk215.bgRed.white;
30327
30524
  case "Error":
30328
- return chalk213.red;
30525
+ return chalk215.red;
30329
30526
  case "Warning":
30330
- return chalk213.yellow;
30527
+ return chalk215.yellow;
30331
30528
  case "Information":
30332
- return chalk213.cyan;
30529
+ return chalk215.cyan;
30333
30530
  case "Debug":
30334
- return chalk213.gray;
30531
+ return chalk215.gray;
30335
30532
  case "Verbose":
30336
- return chalk213.dim;
30533
+ return chalk215.dim;
30337
30534
  default:
30338
- return chalk213.white;
30535
+ return chalk215.white;
30339
30536
  }
30340
30537
  }
30341
30538
  function levelAbbrev(level) {
@@ -30376,12 +30573,12 @@ function formatTimestamp(iso) {
30376
30573
  function formatEvent(event) {
30377
30574
  const color = levelColor(event.Level);
30378
30575
  const abbrev = levelAbbrev(event.Level);
30379
- const ts8 = chalk213.dim(formatTimestamp(event.Timestamp));
30576
+ const ts8 = chalk215.dim(formatTimestamp(event.Timestamp));
30380
30577
  const msg = renderMessage(event);
30381
30578
  const lines2 = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
30382
30579
  if (event.Exception) {
30383
30580
  for (const line of event.Exception.split("\n")) {
30384
- lines2.push(chalk213.red(` ${line}`));
30581
+ lines2.push(chalk215.red(` ${line}`));
30385
30582
  }
30386
30583
  }
30387
30584
  return lines2.join("\n");
@@ -30414,11 +30611,11 @@ function rejectTimestampFilter(filter) {
30414
30611
  }
30415
30612
 
30416
30613
  // src/shared/resolveNamedConnection.ts
30417
- import chalk214 from "chalk";
30614
+ import chalk216 from "chalk";
30418
30615
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
30419
30616
  if (connections.length === 0) {
30420
30617
  console.error(
30421
- chalk214.red(
30618
+ chalk216.red(
30422
30619
  `No ${kind} connections configured. Run '${authCommand}' first.`
30423
30620
  )
30424
30621
  );
@@ -30427,7 +30624,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
30427
30624
  const target = requested ?? defaultName ?? connections[0].name;
30428
30625
  const connection = connections.find((c) => c.name === target);
30429
30626
  if (!connection) {
30430
- console.error(chalk214.red(`${kind} connection "${target}" not found.`));
30627
+ console.error(chalk216.red(`${kind} connection "${target}" not found.`));
30431
30628
  process.exit(1);
30432
30629
  }
30433
30630
  return connection;
@@ -30456,7 +30653,7 @@ async function seqQuery(filter, options2) {
30456
30653
  new URLSearchParams({ filter, count: String(count8) })
30457
30654
  );
30458
30655
  if (events.length === 0) {
30459
- console.log(chalk215.yellow("No events found."));
30656
+ console.log(chalk217.yellow("No events found."));
30460
30657
  return;
30461
30658
  }
30462
30659
  if (options2.json) {
@@ -30467,11 +30664,11 @@ async function seqQuery(filter, options2) {
30467
30664
  for (const event of chronological) {
30468
30665
  console.log(formatEvent(event));
30469
30666
  }
30470
- console.log(chalk215.dim(`
30667
+ console.log(chalk217.dim(`
30471
30668
  ${events.length} events`));
30472
30669
  if (events.length >= count8) {
30473
30670
  console.log(
30474
- chalk215.yellow(
30671
+ chalk217.yellow(
30475
30672
  `Results limited to ${count8}. Use --count to retrieve more.`
30476
30673
  )
30477
30674
  );
@@ -30479,10 +30676,10 @@ ${events.length} events`));
30479
30676
  }
30480
30677
 
30481
30678
  // src/shared/setNamedDefaultConnection.ts
30482
- import chalk216 from "chalk";
30679
+ import chalk218 from "chalk";
30483
30680
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
30484
30681
  if (!connections.find((c) => c.name === name)) {
30485
- console.error(chalk216.red(`Connection "${name}" not found.`));
30682
+ console.error(chalk218.red(`Connection "${name}" not found.`));
30486
30683
  process.exit(1);
30487
30684
  }
30488
30685
  setDefault(name);
@@ -30531,7 +30728,7 @@ function registerSignal(program2) {
30531
30728
  }
30532
30729
 
30533
30730
  // src/commands/sql/sqlAuth.ts
30534
- import chalk218 from "chalk";
30731
+ import chalk220 from "chalk";
30535
30732
 
30536
30733
  // src/commands/sql/loadConnections.ts
30537
30734
  function loadConnections3() {
@@ -30560,7 +30757,7 @@ function setDefaultConnection2(name) {
30560
30757
  }
30561
30758
 
30562
30759
  // src/commands/sql/promptConnection.ts
30563
- import chalk217 from "chalk";
30760
+ import chalk219 from "chalk";
30564
30761
  async function promptConnection3(existingNames) {
30565
30762
  const name = await promptInput("name", "Connection name:", "default");
30566
30763
  assertUniqueName(existingNames, name);
@@ -30568,7 +30765,7 @@ async function promptConnection3(existingNames) {
30568
30765
  const portStr = await promptInput("port", "Port:", "1433");
30569
30766
  const port = Number.parseInt(portStr, 10);
30570
30767
  if (!Number.isFinite(port)) {
30571
- console.error(chalk217.red(`Invalid port "${portStr}".`));
30768
+ console.error(chalk219.red(`Invalid port "${portStr}".`));
30572
30769
  process.exit(1);
30573
30770
  }
30574
30771
  const user = await promptInput("user", "User:");
@@ -30581,13 +30778,13 @@ async function promptConnection3(existingNames) {
30581
30778
  var sqlAuth = createConnectionAuth({
30582
30779
  load: loadConnections3,
30583
30780
  save: saveConnections3,
30584
- format: (c) => `${chalk218.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
30781
+ format: (c) => `${chalk220.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
30585
30782
  promptNew: promptConnection3,
30586
30783
  onFirst: (c) => setDefaultConnection2(c.name)
30587
30784
  });
30588
30785
 
30589
30786
  // src/commands/sql/printTable.ts
30590
- import chalk219 from "chalk";
30787
+ import chalk221 from "chalk";
30591
30788
  function formatCell(value) {
30592
30789
  if (value === null || value === void 0) return "";
30593
30790
  if (value instanceof Date) return value.toISOString();
@@ -30596,7 +30793,7 @@ function formatCell(value) {
30596
30793
  }
30597
30794
  function printTable(rows) {
30598
30795
  if (rows.length === 0) {
30599
- console.log(chalk219.yellow("(no rows)"));
30796
+ console.log(chalk221.yellow("(no rows)"));
30600
30797
  return;
30601
30798
  }
30602
30799
  const columns = Object.keys(rows[0]);
@@ -30604,13 +30801,13 @@ function printTable(rows) {
30604
30801
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
30605
30802
  );
30606
30803
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
30607
- console.log(chalk219.dim(header));
30608
- console.log(chalk219.dim("-".repeat(header.length)));
30804
+ console.log(chalk221.dim(header));
30805
+ console.log(chalk221.dim("-".repeat(header.length)));
30609
30806
  for (const row of rows) {
30610
30807
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
30611
30808
  console.log(line);
30612
30809
  }
30613
- console.log(chalk219.dim(`
30810
+ console.log(chalk221.dim(`
30614
30811
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
30615
30812
  }
30616
30813
 
@@ -30670,7 +30867,7 @@ async function sqlColumns(table, connectionName) {
30670
30867
  }
30671
30868
 
30672
30869
  // src/commands/sql/sqlMutate.ts
30673
- import chalk220 from "chalk";
30870
+ import chalk222 from "chalk";
30674
30871
 
30675
30872
  // src/commands/sql/isMutation.ts
30676
30873
  var MUTATION_KEYWORDS = [
@@ -30704,7 +30901,7 @@ function isMutation(sql25) {
30704
30901
  async function sqlMutate(query, connectionName) {
30705
30902
  if (!isMutation(query)) {
30706
30903
  console.error(
30707
- chalk220.red(
30904
+ chalk222.red(
30708
30905
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
30709
30906
  )
30710
30907
  );
@@ -30714,18 +30911,18 @@ async function sqlMutate(query, connectionName) {
30714
30911
  const pool = await sqlConnect(conn);
30715
30912
  try {
30716
30913
  const result = await pool.request().query(query);
30717
- console.log(chalk220.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
30914
+ console.log(chalk222.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
30718
30915
  } finally {
30719
30916
  await pool.close();
30720
30917
  }
30721
30918
  }
30722
30919
 
30723
30920
  // src/commands/sql/sqlQuery.ts
30724
- import chalk221 from "chalk";
30921
+ import chalk223 from "chalk";
30725
30922
  async function sqlQuery(query, connectionName) {
30726
30923
  if (isMutation(query)) {
30727
30924
  console.error(
30728
- chalk221.red(
30925
+ chalk223.red(
30729
30926
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
30730
30927
  )
30731
30928
  );
@@ -30740,7 +30937,7 @@ async function sqlQuery(query, connectionName) {
30740
30937
  printTable(rows);
30741
30938
  } else {
30742
30939
  console.log(
30743
- chalk221.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
30940
+ chalk223.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
30744
30941
  );
30745
30942
  }
30746
30943
  } finally {
@@ -30803,15 +31000,15 @@ function registerSql(program2) {
30803
31000
  // src/commands/sync.ts
30804
31001
  import * as fs48 from "fs";
30805
31002
  import * as os5 from "os";
30806
- import * as path78 from "path";
31003
+ import * as path84 from "path";
30807
31004
  import { fileURLToPath as fileURLToPath8 } from "url";
30808
31005
 
30809
31006
  // src/commands/sync/pruneCommands.ts
30810
- import * as path69 from "path";
31007
+ import * as path75 from "path";
30811
31008
 
30812
31009
  // src/commands/sync/pruneTarget.ts
30813
31010
  import * as fs40 from "fs";
30814
- import * as path68 from "path";
31011
+ import * as path74 from "path";
30815
31012
  function pruneTarget(targetDir, keepNames, shape, options2) {
30816
31013
  const result = {
30817
31014
  orphans: [],
@@ -30829,7 +31026,7 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
30829
31026
  }
30830
31027
  if (keep.has(name)) continue;
30831
31028
  result.orphans.push(entry.name);
30832
- const entryPath = path68.join(targetDir, entry.name);
31029
+ const entryPath = path74.join(targetDir, entry.name);
30833
31030
  const reason4 = shape.blockedBy?.(entryPath);
30834
31031
  if (reason4) {
30835
31032
  result.skipped.push({ name: entry.name, reason: reason4 });
@@ -30849,7 +31046,7 @@ function pruneCommands(targetDir, commandNames, options2) {
30849
31046
  targetDir,
30850
31047
  commandNames,
30851
31048
  {
30852
- nameOf: (entry) => entry.isFile() && entry.name.endsWith(".md") ? path69.basename(entry.name, ".md") : void 0
31049
+ nameOf: (entry) => entry.isFile() && entry.name.endsWith(".md") ? path75.basename(entry.name, ".md") : void 0
30853
31050
  },
30854
31051
  options2
30855
31052
  );
@@ -30884,24 +31081,24 @@ function reportPrune(label2, result, force) {
30884
31081
 
30885
31082
  // src/commands/sync/syncClaudeMd.ts
30886
31083
  import * as fs41 from "fs";
30887
- import * as path70 from "path";
30888
- import chalk222 from "chalk";
31084
+ import * as path76 from "path";
31085
+ import chalk224 from "chalk";
30889
31086
  async function syncClaudeMd(claudeDir, targetBase, options2) {
30890
- const source = path70.join(claudeDir, "CLAUDE.md");
30891
- const target = path70.join(targetBase, "CLAUDE.md");
31087
+ const source = path76.join(claudeDir, "CLAUDE.md");
31088
+ const target = path76.join(targetBase, "CLAUDE.md");
30892
31089
  const sourceContent = fs41.readFileSync(source, "utf8");
30893
31090
  if (fs41.existsSync(target)) {
30894
31091
  const targetContent = fs41.readFileSync(target, "utf8");
30895
31092
  if (sourceContent !== targetContent) {
30896
31093
  console.log(
30897
- chalk222.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
31094
+ chalk224.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
30898
31095
  );
30899
31096
  console.log();
30900
31097
  printDiff(targetContent, sourceContent);
30901
31098
  if (!options2?.yes) {
30902
31099
  printAutoConfirmHint();
30903
31100
  const confirm = await promptConfirm(
30904
- chalk222.red("Overwrite existing CLAUDE.md?"),
31101
+ chalk224.red("Overwrite existing CLAUDE.md?"),
30905
31102
  false
30906
31103
  );
30907
31104
  if (!confirm) {
@@ -30916,13 +31113,13 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
30916
31113
  }
30917
31114
 
30918
31115
  // src/commands/sync/syncCodex.ts
30919
- import * as path73 from "path";
31116
+ import * as path79 from "path";
30920
31117
 
30921
31118
  // src/commands/sync/installHarnessCommands.ts
30922
31119
  import * as fs42 from "fs";
30923
- import * as path71 from "path";
31120
+ import * as path77 from "path";
30924
31121
  function installHarnessCommands(claudeDir, harness, transform) {
30925
- const commandsSource = path71.join(claudeDir, "commands");
31122
+ const commandsSource = path77.join(claudeDir, "commands");
30926
31123
  const files = fs42.readdirSync(commandsSource);
30927
31124
  const names = [];
30928
31125
  let synced = 0;
@@ -30930,15 +31127,15 @@ function installHarnessCommands(claudeDir, harness, transform) {
30930
31127
  if (!file.endsWith(".md")) continue;
30931
31128
  const name = file.replace(/\.md$/, "");
30932
31129
  names.push(name);
30933
- const content = fs42.readFileSync(path71.join(commandsSource, file), "utf8");
30934
- const target = path71.join(harness.homeDir, harness.sync.commandDest(name));
30935
- fs42.mkdirSync(path71.dirname(target), { recursive: true });
31130
+ const content = fs42.readFileSync(path77.join(commandsSource, file), "utf8");
31131
+ const target = path77.join(harness.homeDir, harness.sync.commandDest(name));
31132
+ fs42.mkdirSync(path77.dirname(target), { recursive: true });
30936
31133
  fs42.writeFileSync(target, transform(name, content));
30937
31134
  synced++;
30938
31135
  }
30939
- const agentsTarget = path71.join(harness.homeDir, harness.sync.agentsFile);
30940
- fs42.mkdirSync(path71.dirname(agentsTarget), { recursive: true });
30941
- fs42.copyFileSync(path71.join(claudeDir, "CLAUDE.md"), agentsTarget);
31136
+ const agentsTarget = path77.join(harness.homeDir, harness.sync.agentsFile);
31137
+ fs42.mkdirSync(path77.dirname(agentsTarget), { recursive: true });
31138
+ fs42.copyFileSync(path77.join(claudeDir, "CLAUDE.md"), agentsTarget);
30942
31139
  return { total: files.length, synced, names };
30943
31140
  }
30944
31141
 
@@ -30964,7 +31161,7 @@ function unexpectedContent(skillDir) {
30964
31161
 
30965
31162
  // src/commands/sync/syncCodexHooks.ts
30966
31163
  import * as fs44 from "fs";
30967
- import * as path72 from "path";
31164
+ import * as path78 from "path";
30968
31165
  var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
30969
31166
  var END = "# <<< assist codex hooks (managed) <<<";
30970
31167
  function upsertManagedBlock(existing, body) {
@@ -30995,9 +31192,9 @@ ${rest}
30995
31192
  }
30996
31193
  function syncCodexHooks(sourcePath) {
30997
31194
  const body = fs44.readFileSync(sourcePath, "utf8");
30998
- const configPath = path72.join(harnesses.codex.homeDir, "config.toml");
31195
+ const configPath = path78.join(harnesses.codex.homeDir, "config.toml");
30999
31196
  const existing = fs44.existsSync(configPath) ? fs44.readFileSync(configPath, "utf8") : "";
31000
- fs44.mkdirSync(path72.dirname(configPath), { recursive: true });
31197
+ fs44.mkdirSync(path78.dirname(configPath), { recursive: true });
31001
31198
  fs44.writeFileSync(configPath, upsertManagedBlock(existing, body));
31002
31199
  console.log(
31003
31200
  "Registered assist codex-hook in ~/.codex/config.toml (UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, Stop)"
@@ -31029,7 +31226,7 @@ function syncCodex(claudeDir, options2) {
31029
31226
  harnesses.codex,
31030
31227
  commandToSkill
31031
31228
  );
31032
- syncCodexHooks(path73.join(claudeDir, "..", "codex", "config.toml"));
31229
+ syncCodexHooks(path79.join(claudeDir, "..", "codex", "config.toml"));
31033
31230
  console.log(
31034
31231
  `Synced ${total} skill(s) to ~/.codex/skills and CLAUDE.md to ~/.codex/AGENTS.md`
31035
31232
  );
@@ -31037,42 +31234,42 @@ function syncCodex(claudeDir, options2) {
31037
31234
  const force = options2.force ?? false;
31038
31235
  reportPrune(
31039
31236
  "~/.codex/skills",
31040
- pruneSkills(path73.join(harnesses.codex.homeDir, "skills"), names, { force }),
31237
+ pruneSkills(path79.join(harnesses.codex.homeDir, "skills"), names, { force }),
31041
31238
  force
31042
31239
  );
31043
31240
  }
31044
31241
 
31045
31242
  // src/commands/sync/syncDesign.ts
31046
31243
  import * as fs45 from "fs";
31047
- import * as path74 from "path";
31244
+ import * as path80 from "path";
31048
31245
  function syncDesign(claudeDir, targetBase) {
31049
- const systemPromptSource = path74.join(claudeDir, "design-system-prompt.md");
31050
- const systemPromptTarget = path74.join(targetBase, "design-system-prompt.md");
31246
+ const systemPromptSource = path80.join(claudeDir, "design-system-prompt.md");
31247
+ const systemPromptTarget = path80.join(targetBase, "design-system-prompt.md");
31051
31248
  fs45.copyFileSync(systemPromptSource, systemPromptTarget);
31052
31249
  console.log(
31053
31250
  "Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
31054
31251
  );
31055
- const skillsSource = path74.join(claudeDir, "skills");
31056
- const skillsTarget = path74.join(targetBase, "skills");
31252
+ const skillsSource = path80.join(claudeDir, "skills");
31253
+ const skillsTarget = path80.join(targetBase, "skills");
31057
31254
  fs45.mkdirSync(skillsTarget, { recursive: true });
31058
31255
  const files = fs45.readdirSync(skillsSource);
31059
31256
  for (const file of files) {
31060
31257
  fs45.copyFileSync(
31061
- path74.join(skillsSource, file),
31062
- path74.join(skillsTarget, file)
31258
+ path80.join(skillsSource, file),
31259
+ path80.join(skillsTarget, file)
31063
31260
  );
31064
31261
  }
31065
31262
  console.log(`Synced ${files.length} design skill(s) to ~/.claude/skills`);
31066
31263
  }
31067
31264
 
31068
31265
  // src/commands/sync/syncPi.ts
31069
- import * as path76 from "path";
31266
+ import * as path82 from "path";
31070
31267
 
31071
31268
  // src/commands/sync/syncPiHooks.ts
31072
31269
  import * as fs46 from "fs";
31073
- import * as path75 from "path";
31270
+ import * as path81 from "path";
31074
31271
  function piExtensionsDir() {
31075
- return path75.join(harnesses.pi.homeDir, "extensions");
31272
+ return path81.join(harnesses.pi.homeDir, "extensions");
31076
31273
  }
31077
31274
  function syncPiHooks(sourceDir) {
31078
31275
  const target = piExtensionsDir();
@@ -31080,8 +31277,8 @@ function syncPiHooks(sourceDir) {
31080
31277
  const files = fs46.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
31081
31278
  for (const file of files) {
31082
31279
  fs46.copyFileSync(
31083
- path75.join(sourceDir, file),
31084
- path75.join(target, `assist-${file}`)
31280
+ path81.join(sourceDir, file),
31281
+ path81.join(target, `assist-${file}`)
31085
31282
  );
31086
31283
  }
31087
31284
  console.log(
@@ -31118,7 +31315,7 @@ function syncPi(claudeDir, options2) {
31118
31315
  harnesses.pi,
31119
31316
  commandToPrompt
31120
31317
  );
31121
- syncPiHooks(path76.join(claudeDir, "..", "pi"));
31318
+ syncPiHooks(path82.join(claudeDir, "..", "pi"));
31122
31319
  console.log(
31123
31320
  `Synced ${synced} prompt(s) to ~/.pi/agent/prompts and CLAUDE.md to ~/.pi/agent/AGENTS.md`
31124
31321
  );
@@ -31126,18 +31323,18 @@ function syncPi(claudeDir, options2) {
31126
31323
  const force = options2.force ?? false;
31127
31324
  reportPrune(
31128
31325
  "~/.pi/agent/prompts",
31129
- pruneCommands(path76.join(harnesses.pi.homeDir, "prompts"), names, { force }),
31326
+ pruneCommands(path82.join(harnesses.pi.homeDir, "prompts"), names, { force }),
31130
31327
  force
31131
31328
  );
31132
31329
  }
31133
31330
 
31134
31331
  // src/commands/sync/syncSettings.ts
31135
31332
  import * as fs47 from "fs";
31136
- import * as path77 from "path";
31137
- import chalk223 from "chalk";
31333
+ import * as path83 from "path";
31334
+ import chalk225 from "chalk";
31138
31335
  async function syncSettings(claudeDir, targetBase, options2) {
31139
- const source = path77.join(claudeDir, "settings.json");
31140
- const target = path77.join(targetBase, "settings.json");
31336
+ const source = path83.join(claudeDir, "settings.json");
31337
+ const target = path83.join(targetBase, "settings.json");
31141
31338
  const sourceContent = fs47.readFileSync(source, "utf8");
31142
31339
  const sourceSettings = JSON.parse(sourceContent);
31143
31340
  const targetExists = fs47.existsSync(target);
@@ -31153,7 +31350,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
31153
31350
  if (mergedContent !== normalizedTarget) {
31154
31351
  if (!options2?.yes) {
31155
31352
  console.log(
31156
- chalk223.yellow(
31353
+ chalk225.yellow(
31157
31354
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
31158
31355
  )
31159
31356
  );
@@ -31161,7 +31358,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
31161
31358
  printDiff(targetContent, mergedContent);
31162
31359
  printAutoConfirmHint();
31163
31360
  const confirm = await promptConfirm(
31164
- chalk223.red("Overwrite existing settings.json?"),
31361
+ chalk225.red("Overwrite existing settings.json?"),
31165
31362
  false
31166
31363
  );
31167
31364
  if (!confirm) {
@@ -31177,13 +31374,13 @@ async function syncSettings(claudeDir, targetBase, options2) {
31177
31374
 
31178
31375
  // src/commands/sync.ts
31179
31376
  var __filename4 = fileURLToPath8(import.meta.url);
31180
- var __dirname5 = path78.dirname(__filename4);
31377
+ var __dirname5 = path84.dirname(__filename4);
31181
31378
  async function sync(options2) {
31182
31379
  const config = loadConfig();
31183
31380
  const yes = options2?.yes ?? config.sync.autoConfirm;
31184
31381
  const prune = { prune: options2?.prune, force: options2?.force };
31185
- const claudeDir = path78.join(__dirname5, "..", "claude");
31186
- const targetBase = path78.join(os5.homedir(), ".claude");
31382
+ const claudeDir = path84.join(__dirname5, "..", "claude");
31383
+ const targetBase = path84.join(os5.homedir(), ".claude");
31187
31384
  const commandFiles = syncCommands(claudeDir, targetBase);
31188
31385
  syncDesign(claudeDir, targetBase);
31189
31386
  await syncSettings(claudeDir, targetBase, { yes });
@@ -31191,21 +31388,21 @@ async function sync(options2) {
31191
31388
  syncCodex(claudeDir, prune);
31192
31389
  syncPi(claudeDir, prune);
31193
31390
  if (!options2?.prune) return;
31194
- const commandNames = commandFiles.filter((file) => file.endsWith(".md")).map((file) => path78.basename(file, ".md"));
31391
+ const commandNames = commandFiles.filter((file) => file.endsWith(".md")).map((file) => path84.basename(file, ".md"));
31195
31392
  const force = options2.force ?? false;
31196
31393
  reportPrune(
31197
31394
  "~/.claude/commands",
31198
- pruneCommands(path78.join(targetBase, "commands"), commandNames, { force }),
31395
+ pruneCommands(path84.join(targetBase, "commands"), commandNames, { force }),
31199
31396
  force
31200
31397
  );
31201
31398
  }
31202
31399
  function syncCommands(claudeDir, targetBase) {
31203
- const sourceDir = path78.join(claudeDir, "commands");
31204
- const targetDir = path78.join(targetBase, "commands");
31400
+ const sourceDir = path84.join(claudeDir, "commands");
31401
+ const targetDir = path84.join(targetBase, "commands");
31205
31402
  fs48.mkdirSync(targetDir, { recursive: true });
31206
31403
  const files = fs48.readdirSync(sourceDir);
31207
31404
  for (const file of files) {
31208
- fs48.copyFileSync(path78.join(sourceDir, file), path78.join(targetDir, file));
31405
+ fs48.copyFileSync(path84.join(sourceDir, file), path84.join(targetDir, file));
31209
31406
  console.log(`Copied ${file} to ${targetDir}`);
31210
31407
  }
31211
31408
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -31233,7 +31430,7 @@ function registerSync(program2) {
31233
31430
  }
31234
31431
 
31235
31432
  // src/commands/transcript/clean.ts
31236
- import { existsSync as existsSync68 } from "fs";
31433
+ import { existsSync as existsSync71 } from "fs";
31237
31434
 
31238
31435
  // src/commands/transcript/cleanText.ts
31239
31436
  function cleanText(text18) {
@@ -31457,9 +31654,9 @@ function formatVtt(cues) {
31457
31654
  }
31458
31655
 
31459
31656
  // src/commands/transcript/convert/readCleanedCues.ts
31460
- import { readFileSync as readFileSync51 } from "fs";
31657
+ import { readFileSync as readFileSync55 } from "fs";
31461
31658
  function readCleanedCues(inputPath) {
31462
- return deduplicateCues(parseVtt(readFileSync51(inputPath, "utf8")));
31659
+ return deduplicateCues(parseVtt(readFileSync55(inputPath, "utf8")));
31463
31660
  }
31464
31661
 
31465
31662
  // src/commands/transcript/clean.ts
@@ -31478,7 +31675,7 @@ function clean(file, options2 = {}) {
31478
31675
  );
31479
31676
  process.exit(1);
31480
31677
  }
31481
- if (!existsSync68(file)) {
31678
+ if (!existsSync71(file)) {
31482
31679
  console.error(`Error: VTT file not found: ${file}`);
31483
31680
  process.exit(1);
31484
31681
  }
@@ -31561,12 +31758,12 @@ async function configure() {
31561
31758
  }
31562
31759
 
31563
31760
  // src/commands/transcript/list.ts
31564
- import { existsSync as existsSync69, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
31761
+ import { existsSync as existsSync72, readdirSync as readdirSync20, statSync as statSync11 } from "fs";
31565
31762
  import { join as join83 } from "path";
31566
31763
  function list4() {
31567
31764
  const { vttDir } = getTranscriptConfig();
31568
- if (!existsSync69(vttDir)) return;
31569
- for (const entry of readdirSync19(vttDir)) {
31765
+ if (!existsSync72(vttDir)) return;
31766
+ for (const entry of readdirSync20(vttDir)) {
31570
31767
  if (!entry.endsWith(".vtt")) continue;
31571
31768
  if (statSync11(join83(vttDir, entry)).isDirectory()) continue;
31572
31769
  console.log(entry);
@@ -31574,7 +31771,7 @@ function list4() {
31574
31771
  }
31575
31772
 
31576
31773
  // src/commands/transcript/move.ts
31577
- import { existsSync as existsSync70, mkdirSync as mkdirSync27, renameSync as renameSync2, writeFileSync as writeFileSync43 } from "fs";
31774
+ import { existsSync as existsSync73, mkdirSync as mkdirSync27, renameSync as renameSync2, writeFileSync as writeFileSync45 } from "fs";
31578
31775
  import { basename as basename21, join as join84 } from "path";
31579
31776
 
31580
31777
  // src/commands/transcript/convertVttToMarkdown.ts
@@ -31598,7 +31795,7 @@ function move(file, options2) {
31598
31795
  const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
31599
31796
  const filename = basename21(file);
31600
31797
  const sourcePath = join84(vttDir, filename);
31601
- if (!existsSync70(sourcePath)) {
31798
+ if (!existsSync73(sourcePath)) {
31602
31799
  console.error(`Error: VTT file not found: ${sourcePath}`);
31603
31800
  process.exit(1);
31604
31801
  }
@@ -31607,7 +31804,7 @@ function move(file, options2) {
31607
31804
  const formattedDir = join84(transcriptsDir, client);
31608
31805
  mkdirSync27(formattedDir, { recursive: true });
31609
31806
  const formattedPath = join84(formattedDir, outputName);
31610
- writeFileSync43(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
31807
+ writeFileSync45(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
31611
31808
  archiveRawVtt(vttDir, sourcePath, filename);
31612
31809
  const summaryPath = join84(summaryDir, client, outputName);
31613
31810
  console.log(`Formatted transcript: ${formattedPath}`);
@@ -31728,14 +31925,14 @@ function devices() {
31728
31925
  }
31729
31926
 
31730
31927
  // src/commands/voice/logs.ts
31731
- import { existsSync as existsSync71, readFileSync as readFileSync52 } from "fs";
31928
+ import { existsSync as existsSync74, readFileSync as readFileSync56 } from "fs";
31732
31929
  function logs(options2) {
31733
- if (!existsSync71(voicePaths.log)) {
31930
+ if (!existsSync74(voicePaths.log)) {
31734
31931
  console.log("No voice log file found");
31735
31932
  return;
31736
31933
  }
31737
31934
  const count8 = Number.parseInt(options2.lines ?? "150", 10);
31738
- const content = readFileSync52(voicePaths.log, "utf8").trim();
31935
+ const content = readFileSync56(voicePaths.log, "utf8").trim();
31739
31936
  if (!content) {
31740
31937
  console.log("Voice log is empty");
31741
31938
  return;
@@ -31762,7 +31959,7 @@ import { join as join88 } from "path";
31762
31959
 
31763
31960
  // src/commands/voice/checkLockFile.ts
31764
31961
  import { execSync as execSync58 } from "child_process";
31765
- import { existsSync as existsSync72, mkdirSync as mkdirSync28, readFileSync as readFileSync53, writeFileSync as writeFileSync44 } from "fs";
31962
+ import { existsSync as existsSync75, mkdirSync as mkdirSync28, readFileSync as readFileSync57, writeFileSync as writeFileSync46 } from "fs";
31766
31963
  import { join as join87 } from "path";
31767
31964
  function isProcessAlive2(pid) {
31768
31965
  try {
@@ -31774,9 +31971,9 @@ function isProcessAlive2(pid) {
31774
31971
  }
31775
31972
  function checkLockFile() {
31776
31973
  const lockFile = getLockFile();
31777
- if (!existsSync72(lockFile)) return;
31974
+ if (!existsSync75(lockFile)) return;
31778
31975
  try {
31779
- const lock2 = JSON.parse(readFileSync53(lockFile, "utf8"));
31976
+ const lock2 = JSON.parse(readFileSync57(lockFile, "utf8"));
31780
31977
  if (lock2.pid && isProcessAlive2(lock2.pid)) {
31781
31978
  console.error(
31782
31979
  `Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
@@ -31787,7 +31984,7 @@ function checkLockFile() {
31787
31984
  }
31788
31985
  }
31789
31986
  function bootstrapVenv() {
31790
- if (existsSync72(getVenvPython())) return;
31987
+ if (existsSync75(getVenvPython())) return;
31791
31988
  console.log("Setting up Python environment...");
31792
31989
  const pythonDir = getPythonDir();
31793
31990
  execSync58(
@@ -31801,7 +31998,7 @@ function bootstrapVenv() {
31801
31998
  function writeLockFile(pid) {
31802
31999
  const lockFile = getLockFile();
31803
32000
  mkdirSync28(join87(lockFile, ".."), { recursive: true });
31804
- writeFileSync44(
32001
+ writeFileSync46(
31805
32002
  lockFile,
31806
32003
  JSON.stringify({
31807
32004
  pid,
@@ -31829,7 +32026,7 @@ function setup() {
31829
32026
 
31830
32027
  // src/commands/voice/start.ts
31831
32028
  import { spawn as spawn8 } from "child_process";
31832
- import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync45 } from "fs";
32029
+ import { mkdirSync as mkdirSync30, writeFileSync as writeFileSync47 } from "fs";
31833
32030
  import { join as join89 } from "path";
31834
32031
 
31835
32032
  // src/commands/voice/buildDaemonEnv.ts
@@ -31858,7 +32055,7 @@ function spawnBackground(python, script, env) {
31858
32055
  console.error("Failed to start voice daemon");
31859
32056
  process.exit(1);
31860
32057
  }
31861
- writeFileSync45(voicePaths.pid, String(pid));
32058
+ writeFileSync47(voicePaths.pid, String(pid));
31862
32059
  writeLockFile(pid);
31863
32060
  console.log(`Voice daemon started (PID ${pid})`);
31864
32061
  }
@@ -31878,7 +32075,7 @@ function start2(options2) {
31878
32075
  }
31879
32076
 
31880
32077
  // src/commands/voice/status.ts
31881
- import { existsSync as existsSync73, readFileSync as readFileSync54 } from "fs";
32078
+ import { existsSync as existsSync76, readFileSync as readFileSync58 } from "fs";
31882
32079
  function isProcessAlive3(pid) {
31883
32080
  try {
31884
32081
  process.kill(pid, 0);
@@ -31888,16 +32085,16 @@ function isProcessAlive3(pid) {
31888
32085
  }
31889
32086
  }
31890
32087
  function readRecentLogs(count8) {
31891
- if (!existsSync73(voicePaths.log)) return [];
31892
- const lines2 = readFileSync54(voicePaths.log, "utf8").trim().split("\n");
32088
+ if (!existsSync76(voicePaths.log)) return [];
32089
+ const lines2 = readFileSync58(voicePaths.log, "utf8").trim().split("\n");
31893
32090
  return lines2.slice(-count8);
31894
32091
  }
31895
32092
  function status2() {
31896
- if (!existsSync73(voicePaths.pid)) {
32093
+ if (!existsSync76(voicePaths.pid)) {
31897
32094
  console.log("Voice daemon: not running (no PID file)");
31898
32095
  return;
31899
32096
  }
31900
- const pid = Number.parseInt(readFileSync54(voicePaths.pid, "utf8").trim(), 10);
32097
+ const pid = Number.parseInt(readFileSync58(voicePaths.pid, "utf8").trim(), 10);
31901
32098
  const alive = isProcessAlive3(pid);
31902
32099
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
31903
32100
  const recent = readRecentLogs(5);
@@ -31916,13 +32113,13 @@ function status2() {
31916
32113
  }
31917
32114
 
31918
32115
  // src/commands/voice/stop.ts
31919
- import { existsSync as existsSync74, readFileSync as readFileSync55, unlinkSync as unlinkSync20 } from "fs";
32116
+ import { existsSync as existsSync77, readFileSync as readFileSync59, unlinkSync as unlinkSync20 } from "fs";
31920
32117
  function stop2() {
31921
- if (!existsSync74(voicePaths.pid)) {
32118
+ if (!existsSync77(voicePaths.pid)) {
31922
32119
  console.log("Voice daemon is not running (no PID file)");
31923
32120
  return;
31924
32121
  }
31925
- const pid = Number.parseInt(readFileSync55(voicePaths.pid, "utf8").trim(), 10);
32122
+ const pid = Number.parseInt(readFileSync59(voicePaths.pid, "utf8").trim(), 10);
31926
32123
  try {
31927
32124
  process.kill(pid, "SIGTERM");
31928
32125
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -31935,7 +32132,7 @@ function stop2() {
31935
32132
  }
31936
32133
  try {
31937
32134
  const lockFile = getLockFile();
31938
- if (existsSync74(lockFile)) unlinkSync20(lockFile);
32135
+ if (existsSync77(lockFile)) unlinkSync20(lockFile);
31939
32136
  } catch {
31940
32137
  }
31941
32138
  console.log("Voice daemon stopped");
@@ -32060,11 +32257,11 @@ var webUiPrefix = "src/commands/sessions/web/ui/";
32060
32257
  var sessionsPrefix = "src/commands/sessions/";
32061
32258
  var rules = [
32062
32259
  {
32063
- matches: (path84) => path84.startsWith(webUiPrefix),
32260
+ matches: (path90) => path90.startsWith(webUiPrefix),
32064
32261
  advice: "restart the web server, then hard-reload the browser tab"
32065
32262
  },
32066
32263
  {
32067
- matches: (path84) => path84.startsWith(sessionsPrefix) && !path84.startsWith(webUiPrefix),
32264
+ matches: (path90) => path90.startsWith(sessionsPrefix) && !path90.startsWith(webUiPrefix),
32068
32265
  advice: "restart the daemon"
32069
32266
  }
32070
32267
  ];
@@ -32075,31 +32272,31 @@ function restartAdvice(paths) {
32075
32272
  // src/commands/watch/syncAdvice.ts
32076
32273
  var rules2 = [
32077
32274
  {
32078
- matches: (path84) => path84.startsWith("claude/commands/"),
32275
+ matches: (path90) => path90.startsWith("claude/commands/"),
32079
32276
  reason: "claude/commands changed"
32080
32277
  },
32081
32278
  {
32082
- matches: (path84) => path84.startsWith("claude/skills/"),
32279
+ matches: (path90) => path90.startsWith("claude/skills/"),
32083
32280
  reason: "claude/skills changed"
32084
32281
  },
32085
32282
  {
32086
- matches: (path84) => path84 === "claude/settings.json",
32283
+ matches: (path90) => path90 === "claude/settings.json",
32087
32284
  reason: "claude/settings.json changed"
32088
32285
  },
32089
32286
  {
32090
- matches: (path84) => path84 === "claude/CLAUDE.md",
32287
+ matches: (path90) => path90 === "claude/CLAUDE.md",
32091
32288
  reason: "claude/CLAUDE.md changed"
32092
32289
  },
32093
32290
  {
32094
- matches: (path84) => path84 === "claude/design-system-prompt.md",
32291
+ matches: (path90) => path90 === "claude/design-system-prompt.md",
32095
32292
  reason: "claude/design-system-prompt.md changed"
32096
32293
  },
32097
32294
  {
32098
- matches: (path84) => path84.startsWith("codex/"),
32295
+ matches: (path90) => path90.startsWith("codex/"),
32099
32296
  reason: "codex sources changed"
32100
32297
  },
32101
32298
  {
32102
- matches: (path84) => path84.startsWith("pi/"),
32299
+ matches: (path90) => path90.startsWith("pi/"),
32103
32300
  reason: "pi sources changed"
32104
32301
  }
32105
32302
  ];
@@ -32340,7 +32537,7 @@ function resolveParams(params, cliArgs) {
32340
32537
  }
32341
32538
 
32342
32539
  // src/commands/run/resolveRunCwd.ts
32343
- import { existsSync as existsSync75 } from "fs";
32540
+ import { existsSync as existsSync78 } from "fs";
32344
32541
  import { resolve as resolve19 } from "path";
32345
32542
  var MissingRunCwdError = class extends Error {
32346
32543
  constructor(runName, cwd) {
@@ -32353,17 +32550,17 @@ var MissingRunCwdError = class extends Error {
32353
32550
  function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
32354
32551
  if (!config.cwd) return void 0;
32355
32552
  const cwd = resolve19(baseDir, config.cwd);
32356
- if (!existsSync75(cwd)) throw new MissingRunCwdError(config.name, cwd);
32553
+ if (!existsSync78(cwd)) throw new MissingRunCwdError(config.name, cwd);
32357
32554
  return cwd;
32358
32555
  }
32359
32556
 
32360
32557
  // src/commands/run/runCommandToCompletion.ts
32361
32558
  import { spawn as spawn9 } from "child_process";
32362
- import { existsSync as existsSync77 } from "fs";
32559
+ import { existsSync as existsSync80 } from "fs";
32363
32560
 
32364
32561
  // src/commands/run/resolveCommand.ts
32365
32562
  import { execFileSync as execFileSync16 } from "child_process";
32366
- import { existsSync as existsSync76 } from "fs";
32563
+ import { existsSync as existsSync79 } from "fs";
32367
32564
  import { dirname as dirname37, join as join91, resolve as resolve20 } from "path";
32368
32565
  function resolveCommand2(command) {
32369
32566
  if (process.platform !== "win32" || command !== "bash") return command;
@@ -32371,7 +32568,7 @@ function resolveCommand2(command) {
32371
32568
  const gitPath = execFileSync16("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
32372
32569
  const gitRoot = resolve20(dirname37(gitPath), "..");
32373
32570
  const gitBash = join91(gitRoot, "bin", "bash.exe");
32374
- if (existsSync76(gitBash)) return gitBash;
32571
+ if (existsSync79(gitBash)) return gitBash;
32375
32572
  } catch {
32376
32573
  return command;
32377
32574
  }
@@ -32381,7 +32578,7 @@ function resolveCommand2(command) {
32381
32578
  // src/commands/run/runCommandToCompletion.ts
32382
32579
  function runCommandToCompletion(command, args, env, cwd, quiet) {
32383
32580
  return new Promise((resolveResult) => {
32384
- if (cwd && !existsSync77(cwd)) {
32581
+ if (cwd && !existsSync80(cwd)) {
32385
32582
  resolveResult({
32386
32583
  kind: "failed",
32387
32584
  message: `Failed to execute command: cwd ${cwd} does not exist`
@@ -32638,7 +32835,7 @@ function registerWatch(program2) {
32638
32835
 
32639
32836
  // src/commands/roam/auth.ts
32640
32837
  import { randomBytes } from "crypto";
32641
- import chalk224 from "chalk";
32838
+ import chalk226 from "chalk";
32642
32839
 
32643
32840
  // src/commands/roam/waitForCallback.ts
32644
32841
  import { createServer as createServer3 } from "http";
@@ -32769,13 +32966,13 @@ async function auth() {
32769
32966
  saveGlobalConfig(config);
32770
32967
  const state = randomBytes(16).toString("hex");
32771
32968
  console.log(
32772
- chalk224.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
32969
+ chalk226.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
32773
32970
  );
32774
- console.log(chalk224.white("http://localhost:14523/callback\n"));
32775
- console.log(chalk224.blue("Opening browser for authorization..."));
32776
- console.log(chalk224.dim("Waiting for authorization callback..."));
32971
+ console.log(chalk226.white("http://localhost:14523/callback\n"));
32972
+ console.log(chalk226.blue("Opening browser for authorization..."));
32973
+ console.log(chalk226.dim("Waiting for authorization callback..."));
32777
32974
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
32778
- console.log(chalk224.dim("Exchanging code for tokens..."));
32975
+ console.log(chalk226.dim("Exchanging code for tokens..."));
32779
32976
  const tokens = await exchangeToken({
32780
32977
  code,
32781
32978
  clientId,
@@ -32791,25 +32988,25 @@ async function auth() {
32791
32988
  };
32792
32989
  saveGlobalConfig(config);
32793
32990
  console.log(
32794
- chalk224.green("Roam credentials and tokens saved to ~/.assist.yml")
32991
+ chalk226.green("Roam credentials and tokens saved to ~/.assist.yml")
32795
32992
  );
32796
32993
  }
32797
32994
 
32798
32995
  // src/commands/roam/postRoamActivity.ts
32799
32996
  import { execFileSync as execFileSync18 } from "child_process";
32800
- import { readdirSync as readdirSync20, readFileSync as readFileSync56, statSync as statSync12 } from "fs";
32997
+ import { readdirSync as readdirSync21, readFileSync as readFileSync60, statSync as statSync12 } from "fs";
32801
32998
  import { join as join92 } from "path";
32802
32999
  function findPortFile(roamDir) {
32803
33000
  let entries;
32804
33001
  try {
32805
- entries = readdirSync20(roamDir);
33002
+ entries = readdirSync21(roamDir);
32806
33003
  } catch {
32807
33004
  return void 0;
32808
33005
  }
32809
33006
  const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
32810
- const path84 = join92(roamDir, name);
33007
+ const path90 = join92(roamDir, name);
32811
33008
  try {
32812
- return { path: path84, mtimeMs: statSync12(path84).mtimeMs };
33009
+ return { path: path90, mtimeMs: statSync12(path90).mtimeMs };
32813
33010
  } catch {
32814
33011
  return void 0;
32815
33012
  }
@@ -32823,7 +33020,7 @@ function postRoamActivity(app, event) {
32823
33020
  if (!portFile) return;
32824
33021
  let port;
32825
33022
  try {
32826
- port = readFileSync56(portFile, "utf8").trim();
33023
+ port = readFileSync60(portFile, "utf8").trim();
32827
33024
  } catch {
32828
33025
  return;
32829
33026
  }
@@ -32951,7 +33148,7 @@ async function run3(name, args) {
32951
33148
  }
32952
33149
 
32953
33150
  // src/commands/run/add.ts
32954
- import { mkdirSync as mkdirSync31, writeFileSync as writeFileSync46 } from "fs";
33151
+ import { mkdirSync as mkdirSync31, writeFileSync as writeFileSync48 } from "fs";
32955
33152
  import { join as join93 } from "path";
32956
33153
 
32957
33154
  // src/commands/run/extractOption.ts
@@ -33022,7 +33219,7 @@ description: Run ${name}
33022
33219
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
33023
33220
  `;
33024
33221
  const filePath = join93(dir, `${name}.md`);
33025
- writeFileSync46(filePath, content);
33222
+ writeFileSync48(filePath, content);
33026
33223
  console.log(`Created command file: ${filePath}`);
33027
33224
  }
33028
33225
  function add3() {
@@ -33045,11 +33242,11 @@ function findLinkIndex() {
33045
33242
  function parseLinkArgs() {
33046
33243
  const idx = findLinkIndex();
33047
33244
  if (idx === -1) return null;
33048
- const path84 = process.argv[idx + 1];
33245
+ const path90 = process.argv[idx + 1];
33049
33246
  const rest = process.argv.slice(idx + 2);
33050
33247
  const { value: prefix2 } = extractOption(rest, "--prefix");
33051
33248
  if (!prefix2) return null;
33052
- return { path: path84, prefix: prefix2 };
33249
+ return { path: path90, prefix: prefix2 };
33053
33250
  }
33054
33251
  function hasDuplicateLink(runList, linkPath) {
33055
33252
  return runList.some(
@@ -33077,7 +33274,7 @@ function link2() {
33077
33274
  }
33078
33275
 
33079
33276
  // src/commands/run/remove.ts
33080
- import { existsSync as existsSync78, unlinkSync as unlinkSync21 } from "fs";
33277
+ import { existsSync as existsSync81, unlinkSync as unlinkSync21 } from "fs";
33081
33278
  import { join as join94 } from "path";
33082
33279
  function findRemoveIndex() {
33083
33280
  const idx = process.argv.indexOf("remove");
@@ -33094,7 +33291,7 @@ function parseRemoveName() {
33094
33291
  }
33095
33292
  function deleteCommandFile(name) {
33096
33293
  const filePath = join94(".claude", "commands", `${name}.md`);
33097
- if (existsSync78(filePath)) {
33294
+ if (existsSync81(filePath)) {
33098
33295
  unlinkSync21(filePath);
33099
33296
  console.log(`Deleted command file: ${filePath}`);
33100
33297
  }
@@ -33139,10 +33336,10 @@ function registerRun(program2) {
33139
33336
 
33140
33337
  // src/commands/screenshot/index.ts
33141
33338
  import { execSync as execSync60 } from "child_process";
33142
- import { existsSync as existsSync79, mkdirSync as mkdirSync32, unlinkSync as unlinkSync22, writeFileSync as writeFileSync47 } from "fs";
33339
+ import { existsSync as existsSync82, mkdirSync as mkdirSync32, unlinkSync as unlinkSync22, writeFileSync as writeFileSync49 } from "fs";
33143
33340
  import { tmpdir as tmpdir9 } from "os";
33144
33341
  import { join as join95, resolve as resolve21 } from "path";
33145
- import chalk225 from "chalk";
33342
+ import chalk227 from "chalk";
33146
33343
 
33147
33344
  // src/commands/screenshot/captureWindowPs1.ts
33148
33345
  var captureWindowPs1 = `
@@ -33271,7 +33468,7 @@ Write-Output $OutputPath
33271
33468
 
33272
33469
  // src/commands/screenshot/index.ts
33273
33470
  function buildOutputPath(outputDir, processName) {
33274
- if (!existsSync79(outputDir)) {
33471
+ if (!existsSync82(outputDir)) {
33275
33472
  mkdirSync32(outputDir, { recursive: true });
33276
33473
  }
33277
33474
  const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -33279,7 +33476,7 @@ function buildOutputPath(outputDir, processName) {
33279
33476
  }
33280
33477
  function runPowerShellScript(processName, outputPath) {
33281
33478
  const scriptPath = join95(tmpdir9(), `assist-screenshot-${Date.now()}.ps1`);
33282
- writeFileSync47(scriptPath, captureWindowPs1, "utf8");
33479
+ writeFileSync49(scriptPath, captureWindowPs1, "utf8");
33283
33480
  try {
33284
33481
  execSync60(
33285
33482
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
@@ -33293,13 +33490,13 @@ function screenshot(processName) {
33293
33490
  const config = loadConfig();
33294
33491
  const outputDir = resolve21(config.screenshot.outputDir);
33295
33492
  const outputPath = buildOutputPath(outputDir, processName);
33296
- console.log(chalk225.gray(`Capturing window for process "${processName}" ...`));
33493
+ console.log(chalk227.gray(`Capturing window for process "${processName}" ...`));
33297
33494
  try {
33298
33495
  runPowerShellScript(processName, outputPath);
33299
- console.log(chalk225.green(`Screenshot saved: ${outputPath}`));
33496
+ console.log(chalk227.green(`Screenshot saved: ${outputPath}`));
33300
33497
  } catch (error) {
33301
33498
  const msg = error instanceof Error ? error.message : String(error);
33302
- console.error(chalk225.red(`Failed to capture screenshot: ${msg}`));
33499
+ console.error(chalk227.red(`Failed to capture screenshot: ${msg}`));
33303
33500
  process.exit(1);
33304
33501
  }
33305
33502
  }
@@ -33355,11 +33552,11 @@ function applyLine(result, pending, line) {
33355
33552
  }
33356
33553
 
33357
33554
  // src/commands/sessions/daemon/readDaemonPidFile.ts
33358
- import { readFileSync as readFileSync57 } from "fs";
33555
+ import { readFileSync as readFileSync61 } from "fs";
33359
33556
  function readDaemonPidFile() {
33360
33557
  try {
33361
33558
  const pid = Number.parseInt(
33362
- readFileSync57(daemonPaths.pid, "utf8").trim(),
33559
+ readFileSync61(daemonPaths.pid, "utf8").trim(),
33363
33560
  10
33364
33561
  );
33365
33562
  return Number.isInteger(pid) ? pid : void 0;
@@ -33616,12 +33813,12 @@ function toSessionRunInfo({
33616
33813
  }
33617
33814
 
33618
33815
  // src/commands/sessions/daemon/worktree/joinRefusal.ts
33619
- import { existsSync as existsSync80 } from "fs";
33816
+ import { existsSync as existsSync83 } from "fs";
33620
33817
  function joinRefusal(session) {
33621
33818
  if (session.commandType === "run") return "a server run has no agent stream";
33622
33819
  if (session.closing === true) return "the session is closing";
33623
33820
  if (!session.cwd) return "the session has no working directory";
33624
- if (!existsSync80(session.cwd))
33821
+ if (!existsSync83(session.cwd))
33625
33822
  return "the session's workspace no longer exists";
33626
33823
  return void 0;
33627
33824
  }
@@ -33785,26 +33982,26 @@ function sessionBase(id, status3) {
33785
33982
  }
33786
33983
 
33787
33984
  // src/commands/sessions/daemon/spawnPty.ts
33788
- import { existsSync as existsSync82 } from "fs";
33985
+ import { existsSync as existsSync85 } from "fs";
33789
33986
  import * as pty from "node-pty";
33790
33987
 
33791
33988
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
33792
- import { chmodSync, existsSync as existsSync81, statSync as statSync13 } from "fs";
33989
+ import { chmodSync, existsSync as existsSync84, statSync as statSync13 } from "fs";
33793
33990
  import { createRequire as createRequire3 } from "module";
33794
- import path79 from "path";
33991
+ import path85 from "path";
33795
33992
  var require4 = createRequire3(import.meta.url);
33796
33993
  var ensured = false;
33797
33994
  function ensureSpawnHelperExecutable() {
33798
33995
  if (ensured || process.platform !== "darwin") return;
33799
33996
  ensured = true;
33800
- const ptyRoot = path79.join(path79.dirname(require4.resolve("node-pty")), "..");
33801
- const helper = path79.join(
33997
+ const ptyRoot = path85.join(path85.dirname(require4.resolve("node-pty")), "..");
33998
+ const helper = path85.join(
33802
33999
  ptyRoot,
33803
34000
  "prebuilds",
33804
34001
  `${process.platform}-${process.arch}`,
33805
34002
  "spawn-helper"
33806
34003
  );
33807
- if (!existsSync81(helper)) return;
34004
+ if (!existsSync84(helper)) return;
33808
34005
  const mode = statSync13(helper).mode;
33809
34006
  if ((mode & 73) === 0) chmodSync(helper, mode | 493);
33810
34007
  }
@@ -33840,7 +34037,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
33840
34037
  });
33841
34038
  }
33842
34039
  function refuseMissingCwd(cwd, sessionId) {
33843
- if (!cwd || existsSync82(cwd)) return;
34040
+ if (!cwd || existsSync85(cwd)) return;
33844
34041
  daemonLog(
33845
34042
  `${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
33846
34043
  );
@@ -33919,12 +34116,12 @@ function serverRunMeta(runName, cwd) {
33919
34116
 
33920
34117
  // src/commands/sessions/daemon/readDesignSystemPrompt.ts
33921
34118
  import * as fs49 from "fs";
33922
- import * as path80 from "path";
34119
+ import * as path86 from "path";
33923
34120
  import { fileURLToPath as fileURLToPath10 } from "url";
33924
34121
  var __filename5 = fileURLToPath10(import.meta.url);
33925
- var __dirname7 = path80.dirname(__filename5);
34122
+ var __dirname7 = path86.dirname(__filename5);
33926
34123
  function readDesignSystemPrompt() {
33927
- const promptPath = path80.join(
34124
+ const promptPath = path86.join(
33928
34125
  __dirname7,
33929
34126
  "..",
33930
34127
  "claude",
@@ -34022,11 +34219,11 @@ function setStatus2(session, newStatus) {
34022
34219
  }
34023
34220
 
34024
34221
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
34025
- import { existsSync as existsSync84 } from "fs";
34222
+ import { existsSync as existsSync87 } from "fs";
34026
34223
  import { basename as basename22 } from "path";
34027
34224
 
34028
34225
  // src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
34029
- import { existsSync as existsSync83 } from "fs";
34226
+ import { existsSync as existsSync86 } from "fs";
34030
34227
  import { join as join98 } from "path";
34031
34228
 
34032
34229
  // src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
@@ -34096,7 +34293,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
34096
34293
  );
34097
34294
  }
34098
34295
  function strandedReason(worktreePath, cause) {
34099
- if (!existsSync83(join98(worktreePath, ".git")))
34296
+ if (!existsSync86(join98(worktreePath, ".git")))
34100
34297
  return "its .git link is already gone";
34101
34298
  if (/not a working tree|not a git repository/i.test(reason2(cause)))
34102
34299
  return "git no longer recognises it as a working tree";
@@ -34148,7 +34345,7 @@ function reason3(error) {
34148
34345
 
34149
34346
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
34150
34347
  async function reapWorktree(worktreePath, force = false) {
34151
- if (!existsSync84(worktreePath)) {
34348
+ if (!existsSync87(worktreePath)) {
34152
34349
  forgetWorktree(worktreePath);
34153
34350
  daemonLog(
34154
34351
  `worktree ${worktreePath} already gone; its record was forgotten`
@@ -34173,7 +34370,7 @@ async function reapWorktree(worktreePath, force = false) {
34173
34370
  }
34174
34371
  function owningClone(worktreePath) {
34175
34372
  const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
34176
- if (recorded && existsSync84(recorded)) return recorded;
34373
+ if (recorded && existsSync87(recorded)) return recorded;
34177
34374
  const detected = mainWorktree(worktreePath);
34178
34375
  if (detected) return detected;
34179
34376
  daemonLog(
@@ -34304,12 +34501,12 @@ function closeGateApplies(sessions, session) {
34304
34501
  }
34305
34502
 
34306
34503
  // src/commands/sessions/daemon/worktree/watchGitState.ts
34307
- import { existsSync as existsSync85, watch } from "fs";
34504
+ import { existsSync as existsSync88, watch } from "fs";
34308
34505
  var DEBOUNCE_MS = 500;
34309
34506
  var POLL_MS = 3e4;
34310
34507
  function watchGitState(cwd, onChange) {
34311
34508
  const common = gitCommonDir(cwd);
34312
- if (!common || !existsSync85(common)) return void 0;
34509
+ if (!common || !existsSync88(common)) return void 0;
34313
34510
  const watchers = [
34314
34511
  watchGitDir(common, onChange),
34315
34512
  pollGitState(cwd, onChange)
@@ -34786,10 +34983,10 @@ function emitSessionOutput(session, clients, data) {
34786
34983
  }
34787
34984
 
34788
34985
  // src/commands/sessions/daemon/exitReason.ts
34789
- import { existsSync as existsSync86 } from "fs";
34986
+ import { existsSync as existsSync89 } from "fs";
34790
34987
  import { resolve as resolve22 } from "path";
34791
34988
  function exitDetail(session) {
34792
- if (session.cwd && !existsSync86(session.cwd))
34989
+ if (session.cwd && !existsSync89(session.cwd))
34793
34990
  return `working directory ${session.cwd} no longer exists`;
34794
34991
  return missingRunConfigCwd(session);
34795
34992
  }
@@ -34803,7 +35000,7 @@ function missingRunConfigCwd(session) {
34803
35000
  const config = resolveRunConfig(session.runName, dir);
34804
35001
  if (!config?.cwd) return void 0;
34805
35002
  const configured = resolve22(runConfigBaseDirFrom(dir), config.cwd);
34806
- if (existsSync86(configured)) return void 0;
35003
+ if (existsSync89(configured)) return void 0;
34807
35004
  return `run config "${config.name}": cwd ${configured} does not exist`;
34808
35005
  }
34809
35006
 
@@ -34844,7 +35041,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
34844
35041
  }
34845
35042
 
34846
35043
  // src/commands/sessions/daemon/watchActivity.ts
34847
- import { existsSync as existsSync87, mkdirSync as mkdirSync33, watch as watch2 } from "fs";
35044
+ import { existsSync as existsSync90, mkdirSync as mkdirSync33, watch as watch2 } from "fs";
34848
35045
  import { dirname as dirname39 } from "path";
34849
35046
 
34850
35047
  // src/commands/sessions/daemon/applyActivityToSession.ts
@@ -34906,8 +35103,8 @@ async function seedRunningMsFromUsage(session, notify2) {
34906
35103
  var DEBOUNCE_MS2 = 50;
34907
35104
  function watchActivity(session, notify2, onClaudeSessionId) {
34908
35105
  if (session.commandType !== "assist" || !session.cwd) return;
34909
- const path84 = activityPath(session.id);
34910
- const dir = dirname39(path84);
35106
+ const path90 = activityPath(session.id);
35107
+ const dir = dirname39(path90);
34911
35108
  try {
34912
35109
  mkdirSync33(dir, { recursive: true });
34913
35110
  } catch {
@@ -34915,9 +35112,9 @@ function watchActivity(session, notify2, onClaudeSessionId) {
34915
35112
  }
34916
35113
  reconcileActivity(session.id, session.activity);
34917
35114
  let timer = null;
34918
- const read2 = () => {
35115
+ const read3 = () => {
34919
35116
  timer = null;
34920
- const activity2 = readActivity(path84);
35117
+ const activity2 = readActivity(path90);
34921
35118
  if (!activity2) return;
34922
35119
  applyActivityToSession(session, activity2);
34923
35120
  if (activity2.claudeSessionId) onClaudeSessionId?.(session);
@@ -34926,11 +35123,11 @@ function watchActivity(session, notify2, onClaudeSessionId) {
34926
35123
  notify2();
34927
35124
  };
34928
35125
  session.activityWatcher = watch2(dir, (_event, filename) => {
34929
- if (filename && !path84.endsWith(filename)) return;
35126
+ if (filename && !path90.endsWith(filename)) return;
34930
35127
  if (timer) clearTimeout(timer);
34931
- timer = setTimeout(read2, DEBOUNCE_MS2);
35128
+ timer = setTimeout(read3, DEBOUNCE_MS2);
34932
35129
  });
34933
- if (existsSync87(path84)) read2();
35130
+ if (existsSync90(path90)) read3();
34934
35131
  }
34935
35132
  function refreshActivity(session) {
34936
35133
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -35073,12 +35270,12 @@ import { watch as watch3 } from "fs";
35073
35270
 
35074
35271
  // src/commands/sessions/shared/findTranscriptPathSync.ts
35075
35272
  import * as fs51 from "fs";
35076
- import * as path81 from "path";
35273
+ import * as path87 from "path";
35077
35274
  function projectDirForCwd(cwd) {
35078
- return path81.join(claudeProjectsRoot(), projectSlug(cwd));
35275
+ return path87.join(claudeProjectsRoot(), projectSlug(cwd));
35079
35276
  }
35080
35277
  function transcriptPathFor(cwd, claudeSessionId) {
35081
- return path81.join(projectDirForCwd(cwd), `${claudeSessionId}.jsonl`);
35278
+ return path87.join(projectDirForCwd(cwd), `${claudeSessionId}.jsonl`);
35082
35279
  }
35083
35280
  function findTranscriptPathSync(cwd, claudeSessionId) {
35084
35281
  const direct = transcriptPathFor(cwd, claudeSessionId);
@@ -35092,8 +35289,8 @@ function findTranscriptPathSync(cwd, claudeSessionId) {
35092
35289
  }
35093
35290
  for (const file of files) {
35094
35291
  if (!file.endsWith(".jsonl")) continue;
35095
- if (headContainsSessionId(path81.join(dir, file), claudeSessionId))
35096
- return path81.join(dir, file);
35292
+ if (headContainsSessionId(path87.join(dir, file), claudeSessionId))
35293
+ return path87.join(dir, file);
35097
35294
  }
35098
35295
  return null;
35099
35296
  }
@@ -36267,9 +36464,9 @@ function tempRoots() {
36267
36464
  }
36268
36465
  return [...roots];
36269
36466
  }
36270
- function underTempRoot(path84) {
36467
+ function underTempRoot(path90) {
36271
36468
  return tempRoots().some(
36272
- (root) => path84.startsWith(root.endsWith(sep2) ? root : root + sep2)
36469
+ (root) => path90.startsWith(root.endsWith(sep2) ? root : root + sep2)
36273
36470
  );
36274
36471
  }
36275
36472
 
@@ -36581,7 +36778,7 @@ function rearmStoppedSessions(sessions, notify2) {
36581
36778
  }
36582
36779
 
36583
36780
  // src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
36584
- import { existsSync as existsSync90 } from "fs";
36781
+ import { existsSync as existsSync93 } from "fs";
36585
36782
  import { basename as basename24 } from "path";
36586
36783
 
36587
36784
  // src/commands/sessions/daemon/worktree/accountedTrees.ts
@@ -36636,18 +36833,18 @@ function bindResumedWorktree(session, cwd, notify2) {
36636
36833
  }
36637
36834
 
36638
36835
  // src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
36639
- import { existsSync as existsSync89 } from "fs";
36836
+ import { existsSync as existsSync92 } from "fs";
36640
36837
  async function reclaimVanishedWorktrees(clone, paths) {
36641
- if (!existsSync89(clone)) {
36642
- for (const { path: path84 } of paths) forgetWorktree(path84);
36838
+ if (!existsSync92(clone)) {
36839
+ for (const { path: path90 } of paths) forgetWorktree(path90);
36643
36840
  daemonLog(
36644
36841
  `clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
36645
36842
  );
36646
36843
  return;
36647
36844
  }
36648
36845
  await pruneBookkeeping2(clone);
36649
- for (const { path: path84, branch: branch2 } of paths)
36650
- if (await reclaimBranch(clone, branch2)) forgetWorktree(path84);
36846
+ for (const { path: path90, branch: branch2 } of paths)
36847
+ if (await reclaimBranch(clone, branch2)) forgetWorktree(path90);
36651
36848
  }
36652
36849
  async function pruneBookkeeping2(clone) {
36653
36850
  try {
@@ -36674,37 +36871,37 @@ async function reclaimBranch(clone, branch2) {
36674
36871
  }
36675
36872
 
36676
36873
  // src/commands/sessions/daemon/worktree/logVanishedTree.ts
36677
- function logVanishedTree(sessions, path84) {
36874
+ function logVanishedTree(sessions, path90) {
36678
36875
  const claimants = [...sessions.values()].filter(
36679
- (s) => s.cwd === path84 || s.worktree?.path === path84
36876
+ (s) => s.cwd === path90 || s.worktree?.path === path90
36680
36877
  );
36681
36878
  if (claimants.length === 0) {
36682
- daemonLog(`worktree ${path84} gone from disk and unclaimed; reclaiming it`);
36879
+ daemonLog(`worktree ${path90} gone from disk and unclaimed; reclaiming it`);
36683
36880
  return;
36684
36881
  }
36685
36882
  for (const s of claimants)
36686
36883
  daemonLog(
36687
- `session ${s.id} ("${s.name}") claims worktree ${path84}, which is gone from disk; reclaiming it`
36884
+ `session ${s.id} ("${s.name}") claims worktree ${path90}, which is gone from disk; reclaiming it`
36688
36885
  );
36689
36886
  }
36690
36887
 
36691
36888
  // src/commands/sessions/daemon/worktree/describeHeldWork.ts
36692
36889
  var MAX_ITEMS = 20;
36693
- async function describeHeldWork(path84, reason4) {
36694
- if (reason4.startsWith("uncommitted")) return await changedFiles(path84);
36695
- if (reason4.startsWith("unpushed")) return await unpushedCommits(path84, reason4);
36890
+ async function describeHeldWork(path90, reason4) {
36891
+ if (reason4.startsWith("uncommitted")) return await changedFiles(path90);
36892
+ if (reason4.startsWith("unpushed")) return await unpushedCommits(path90, reason4);
36696
36893
  return { summary: reason4, items: [] };
36697
36894
  }
36698
- async function changedFiles(path84) {
36699
- const status3 = await gitResult(path84, ["status", "--porcelain"]);
36895
+ async function changedFiles(path90) {
36896
+ const status3 = await gitResult(path90, ["status", "--porcelain"]);
36700
36897
  const lines2 = status3.ok ? nonEmptyLines(status3.out) : [];
36701
36898
  return {
36702
36899
  summary: `${lines2.length} uncommitted ${lines2.length === 1 ? "file" : "files"}`,
36703
36900
  items: capped(lines2)
36704
36901
  };
36705
36902
  }
36706
- async function unpushedCommits(path84, reason4) {
36707
- const log2 = await gitResult(path84, ["log", "--oneline", "@{upstream}..HEAD"]);
36903
+ async function unpushedCommits(path90, reason4) {
36904
+ const log2 = await gitResult(path90, ["log", "--oneline", "@{upstream}..HEAD"]);
36708
36905
  if (!log2.ok) return { summary: reason4, items: [] };
36709
36906
  const lines2 = nonEmptyLines(log2.out);
36710
36907
  return {
@@ -36796,24 +36993,24 @@ function reconcileWorktreesOnRestore(sessions, spawnWith, notify2) {
36796
36993
  async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
36797
36994
  const accounted = accountedTrees(sessions);
36798
36995
  const vanished = /* @__PURE__ */ new Map();
36799
- for (const { path: path84, clone } of readWorktreeRegistry()) {
36800
- if (underTempRoot(path84)) {
36801
- forgetWorktree(path84);
36996
+ for (const { path: path90, clone } of readWorktreeRegistry()) {
36997
+ if (underTempRoot(path90)) {
36998
+ forgetWorktree(path90);
36802
36999
  daemonLog(
36803
- `worktree ${path84} lies outside any project root; pruned from the registry rather than recovered`
37000
+ `worktree ${path90} lies outside any project root; pruned from the registry rather than recovered`
36804
37001
  );
36805
37002
  continue;
36806
37003
  }
36807
- if (!existsSync90(path84)) {
36808
- logVanishedTree(sessions, path84);
37004
+ if (!existsSync93(path90)) {
37005
+ logVanishedTree(sessions, path90);
36809
37006
  vanished.set(clone, [
36810
37007
  ...vanished.get(clone) ?? [],
36811
- { path: path84, branch: basename24(path84) }
37008
+ { path: path90, branch: basename24(path90) }
36812
37009
  ]);
36813
37010
  continue;
36814
37011
  }
36815
- if (accounted.has(path84)) continue;
36816
- await recoverOrphan(sessions, spawnWith, { path: path84, clone }, notify2);
37012
+ if (accounted.has(path90)) continue;
37013
+ await recoverOrphan(sessions, spawnWith, { path: path90, clone }, notify2);
36817
37014
  }
36818
37015
  for (const [clone, paths] of vanished)
36819
37016
  await reclaimVanishedWorktrees(clone, paths);
@@ -37421,14 +37618,14 @@ async function defaultConnect() {
37421
37618
  }
37422
37619
 
37423
37620
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
37424
- import { existsSync as existsSync91, readFileSync as readFileSync59 } from "fs";
37621
+ import { existsSync as existsSync94, readFileSync as readFileSync63 } from "fs";
37425
37622
  import { posix as posix3 } from "path";
37426
37623
  function hasPersistedWindowsSessions() {
37427
37624
  const sessionsFile = windowsSessionsFileFromWsl();
37428
37625
  if (!sessionsFile) return false;
37429
37626
  try {
37430
- if (!existsSync91(sessionsFile)) return false;
37431
- const data = JSON.parse(readFileSync59(sessionsFile, "utf8"));
37627
+ if (!existsSync94(sessionsFile)) return false;
37628
+ const data = JSON.parse(readFileSync63(sessionsFile, "utf8"));
37432
37629
  return Array.isArray(data) && data.length > 0;
37433
37630
  } catch (error) {
37434
37631
  const message3 = error instanceof Error ? error.message : String(error);
@@ -38162,7 +38359,7 @@ function setAutoAdvance(sessions, id, enabled) {
38162
38359
  }
38163
38360
 
38164
38361
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
38165
- import { existsSync as existsSync94 } from "fs";
38362
+ import { existsSync as existsSync97 } from "fs";
38166
38363
 
38167
38364
  // src/commands/sessions/daemon/resumeSession.ts
38168
38365
  function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
@@ -38193,10 +38390,10 @@ function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
38193
38390
  }
38194
38391
 
38195
38392
  // src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
38196
- import { existsSync as existsSync93 } from "fs";
38393
+ import { existsSync as existsSync96 } from "fs";
38197
38394
 
38198
38395
  // src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
38199
- import { copyFileSync as copyFileSync7, existsSync as existsSync92, mkdirSync as mkdirSync35 } from "fs";
38396
+ import { copyFileSync as copyFileSync7, existsSync as existsSync95, mkdirSync as mkdirSync35 } from "fs";
38200
38397
  import { join as join100 } from "path";
38201
38398
  function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
38202
38399
  const dir = projectDirForCwd(toCwd);
@@ -38207,7 +38404,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
38207
38404
  return;
38208
38405
  }
38209
38406
  const dest = join100(dir, `${claudeSessionId}.jsonl`);
38210
- if (existsSync92(dest)) {
38407
+ if (existsSync95(dest)) {
38211
38408
  daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
38212
38409
  return;
38213
38410
  }
@@ -38258,7 +38455,7 @@ function resumeInReplacementTree(ctx, claudeSessionId, missingCwd, name, harness
38258
38455
  }
38259
38456
  function cloneForReapedTree(missingCwd) {
38260
38457
  const clone = worktreeAttributionIncludingReaped(missingCwd)?.clone;
38261
- if (!clone || !existsSync93(clone))
38458
+ if (!clone || !existsSync96(clone))
38262
38459
  throw new Error(
38263
38460
  `working directory no longer exists and no clone is recorded to re-allocate from: ${missingCwd}`
38264
38461
  );
@@ -38267,7 +38464,7 @@ function cloneForReapedTree(missingCwd) {
38267
38464
 
38268
38465
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
38269
38466
  function resumeInTree(ctx, sessionId, cwd, name, harness) {
38270
- if (!existsSync94(cwd))
38467
+ if (!existsSync97(cwd))
38271
38468
  return resumeInReplacementTree(ctx, sessionId, cwd, name, harness);
38272
38469
  const id = ctx.spawnWith(
38273
38470
  (sid) => resumeSession(sid, sessionId, cwd, name, void 0, harness)
@@ -38534,12 +38731,12 @@ function handleSetStatus(client, m, d) {
38534
38731
  import * as fs54 from "fs";
38535
38732
 
38536
38733
  // src/commands/sessions/shared/codex/findCodexRolloutPath.ts
38537
- import * as path82 from "path";
38734
+ import * as path88 from "path";
38538
38735
  async function findCodexRolloutPath(sessionId) {
38539
38736
  if (!sessionId) return null;
38540
38737
  const paths = await discoverCodexRolloutPaths();
38541
38738
  const suffix = `-${sessionId}.jsonl`;
38542
- return paths.find((file) => path82.basename(file).endsWith(suffix)) ?? null;
38739
+ return paths.find((file) => path88.basename(file).endsWith(suffix)) ?? null;
38543
38740
  }
38544
38741
 
38545
38742
  // src/commands/sessions/shared/codex/codexToolTarget.ts
@@ -38844,10 +39041,10 @@ function handleConnection(socket, manager) {
38844
39041
  }
38845
39042
 
38846
39043
  // src/commands/sessions/daemon/onListening.ts
38847
- import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync48 } from "fs";
39044
+ import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync50 } from "fs";
38848
39045
 
38849
39046
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
38850
- import { readFileSync as readFileSync60 } from "fs";
39047
+ import { readFileSync as readFileSync64 } from "fs";
38851
39048
  var WATCHDOG_INTERVAL_MS = 5e3;
38852
39049
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
38853
39050
  const timer = setInterval(() => {
@@ -38858,7 +39055,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
38858
39055
  }
38859
39056
  function ownsPidFile() {
38860
39057
  try {
38861
- return readFileSync60(daemonPaths.pid, "utf8").trim() === String(process.pid);
39058
+ return readFileSync64(daemonPaths.pid, "utf8").trim() === String(process.pid);
38862
39059
  } catch {
38863
39060
  return false;
38864
39061
  }
@@ -38866,7 +39063,7 @@ function ownsPidFile() {
38866
39063
 
38867
39064
  // src/commands/sessions/daemon/onListening.ts
38868
39065
  function onListening(manager, checkAutoExit) {
38869
- writeFileSync48(daemonPaths.pid, String(process.pid));
39066
+ writeFileSync50(daemonPaths.pid, String(process.pid));
38870
39067
  startPidFileWatchdog(() => {
38871
39068
  daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
38872
39069
  void manager.flushActiveMs().finally(() => {
@@ -39108,7 +39305,7 @@ function registerSetStatusCommand(cmd) {
39108
39305
 
39109
39306
  // src/commands/sessions/summarise/index.ts
39110
39307
  import * as fs56 from "fs";
39111
- import chalk226 from "chalk";
39308
+ import chalk228 from "chalk";
39112
39309
 
39113
39310
  // src/commands/sessions/summarise/shared.ts
39114
39311
  import * as fs55 from "fs";
@@ -39167,22 +39364,22 @@ ${firstMessage}`);
39167
39364
  async function summarise2(options2) {
39168
39365
  const files = await discoverSessionFiles();
39169
39366
  if (files.length === 0) {
39170
- console.log(chalk226.yellow("No sessions found."));
39367
+ console.log(chalk228.yellow("No sessions found."));
39171
39368
  return;
39172
39369
  }
39173
39370
  const toProcess = selectCandidates(files, options2);
39174
39371
  if (toProcess.length === 0) {
39175
- console.log(chalk226.green("All sessions already summarised."));
39372
+ console.log(chalk228.green("All sessions already summarised."));
39176
39373
  return;
39177
39374
  }
39178
39375
  console.log(
39179
- chalk226.cyan(
39376
+ chalk228.cyan(
39180
39377
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
39181
39378
  )
39182
39379
  );
39183
39380
  const { succeeded, failed: failed2 } = processSessions(toProcess);
39184
39381
  console.log(
39185
- chalk226.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk226.yellow(`, ${failed2} skipped`) : "")
39382
+ chalk228.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk228.yellow(`, ${failed2} skipped`) : "")
39186
39383
  );
39187
39384
  }
39188
39385
  function selectCandidates(files, options2) {
@@ -39202,16 +39399,16 @@ function processSessions(files) {
39202
39399
  let failed2 = 0;
39203
39400
  for (let i = 0; i < files.length; i++) {
39204
39401
  const file = files[i];
39205
- process.stdout.write(chalk226.dim(` [${i + 1}/${files.length}] `));
39402
+ process.stdout.write(chalk228.dim(` [${i + 1}/${files.length}] `));
39206
39403
  const summary = summariseSession(file);
39207
39404
  if (summary) {
39208
39405
  writeSummary(file, summary);
39209
39406
  succeeded++;
39210
- process.stdout.write(`${chalk226.green("\u2713")} ${summary}
39407
+ process.stdout.write(`${chalk228.green("\u2713")} ${summary}
39211
39408
  `);
39212
39409
  } else {
39213
39410
  failed2++;
39214
- process.stdout.write(` ${chalk226.yellow("skip")}
39411
+ process.stdout.write(` ${chalk228.yellow("skip")}
39215
39412
  `);
39216
39413
  }
39217
39414
  }
@@ -39232,7 +39429,7 @@ function registerSessions(program2) {
39232
39429
  }
39233
39430
 
39234
39431
  // src/commands/statusLine.ts
39235
- import chalk228 from "chalk";
39432
+ import chalk230 from "chalk";
39236
39433
 
39237
39434
  // src/shared/contextLevel.ts
39238
39435
  function contextLevel(pct) {
@@ -39242,7 +39439,7 @@ function contextLevel(pct) {
39242
39439
  }
39243
39440
 
39244
39441
  // src/commands/buildLimitsSegment.ts
39245
- import chalk227 from "chalk";
39442
+ import chalk229 from "chalk";
39246
39443
 
39247
39444
  // src/shared/rateLimitLevel.ts
39248
39445
  var FIVE_HOUR_SECONDS = 5 * 3600;
@@ -39280,9 +39477,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
39280
39477
 
39281
39478
  // src/commands/buildLimitsSegment.ts
39282
39479
  var LEVEL_COLOR = {
39283
- ok: chalk227.green,
39284
- warn: chalk227.yellow,
39285
- over: chalk227.red
39480
+ ok: chalk229.green,
39481
+ warn: chalk229.yellow,
39482
+ over: chalk229.red
39286
39483
  };
39287
39484
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
39288
39485
  const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
@@ -39313,7 +39510,7 @@ function buildLimitsSegment(rateLimits) {
39313
39510
  }
39314
39511
 
39315
39512
  // src/commands/readGitBranch.ts
39316
- import { readFileSync as readFileSync62, statSync as statSync16 } from "fs";
39513
+ import { readFileSync as readFileSync66, statSync as statSync16 } from "fs";
39317
39514
  import { isAbsolute as isAbsolute5, join as join101, resolve as resolve23 } from "path";
39318
39515
  function resolveGitDir(cwd) {
39319
39516
  const dotGit = join101(cwd, ".git");
@@ -39328,7 +39525,7 @@ function resolveGitDir(cwd) {
39328
39525
  }
39329
39526
  let contents;
39330
39527
  try {
39331
- contents = readFileSync62(dotGit, "utf8");
39528
+ contents = readFileSync66(dotGit, "utf8");
39332
39529
  } catch {
39333
39530
  return null;
39334
39531
  }
@@ -39346,7 +39543,7 @@ function readGitBranch(cwd) {
39346
39543
  }
39347
39544
  let head;
39348
39545
  try {
39349
- head = readFileSync62(join101(gitDir, "HEAD"), "utf8");
39546
+ head = readFileSync66(join101(gitDir, "HEAD"), "utf8");
39350
39547
  } catch {
39351
39548
  return null;
39352
39549
  }
@@ -39378,7 +39575,7 @@ async function relayUsage(claudeSessionId, transcriptPath2, usedPct) {
39378
39575
  }
39379
39576
 
39380
39577
  // src/commands/statusLine.ts
39381
- chalk228.level = 3;
39578
+ chalk230.level = 3;
39382
39579
  function formatNumber(num) {
39383
39580
  return num.toLocaleString("en-US");
39384
39581
  }
@@ -39386,9 +39583,9 @@ function colorizePercent(pct) {
39386
39583
  const label2 = `${Math.round(pct)}%`;
39387
39584
  switch (contextLevel(pct)) {
39388
39585
  case "red":
39389
- return chalk228.red(label2);
39586
+ return chalk230.red(label2);
39390
39587
  case "yellow":
39391
- return chalk228.yellow(label2);
39588
+ return chalk230.yellow(label2);
39392
39589
  default:
39393
39590
  return label2;
39394
39591
  }
@@ -39401,7 +39598,7 @@ async function statusLine() {
39401
39598
  const usedPct = data.context_window.used_percentage ?? 0;
39402
39599
  const dir = data.workspace?.current_dir ?? data.cwd;
39403
39600
  const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
39404
- const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk228.cyan(branch2)} | ` : "";
39601
+ const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk230.cyan(branch2)} | ` : "";
39405
39602
  console.log(
39406
39603
  `${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
39407
39604
  );
@@ -39415,7 +39612,7 @@ async function statusLine() {
39415
39612
 
39416
39613
  // src/commands/update.ts
39417
39614
  import { execSync as execSync61 } from "child_process";
39418
- import * as path83 from "path";
39615
+ import * as path89 from "path";
39419
39616
 
39420
39617
  // src/commands/restartDaemonAfterUpdate.ts
39421
39618
  async function restartDaemonAfterUpdate() {
@@ -39434,12 +39631,12 @@ async function restartDaemonAfterUpdate() {
39434
39631
  // src/commands/update.ts
39435
39632
  function isGlobalNpmInstall(dir) {
39436
39633
  try {
39437
- const resolved = path83.resolve(dir);
39438
- if (resolved.split(path83.sep).includes("node_modules")) {
39634
+ const resolved = path89.resolve(dir);
39635
+ if (resolved.split(path89.sep).includes("node_modules")) {
39439
39636
  return true;
39440
39637
  }
39441
39638
  const globalPrefix = execSync61("npm prefix -g", { stdio: "pipe" }).toString().trim();
39442
- return resolved.toLowerCase().startsWith(path83.resolve(globalPrefix).toLowerCase());
39639
+ return resolved.toLowerCase().startsWith(path89.resolve(globalPrefix).toLowerCase());
39443
39640
  } catch {
39444
39641
  return false;
39445
39642
  }
@@ -39471,10 +39668,10 @@ async function update2() {
39471
39668
  }
39472
39669
 
39473
39670
  // src/reportCliError.ts
39474
- import chalk229 from "chalk";
39671
+ import chalk231 from "chalk";
39475
39672
  function reportCliError(error) {
39476
39673
  if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError || error instanceof MissingRunCwdError || error instanceof MiroExtractError) {
39477
- console.error(chalk229.red(error.message));
39674
+ console.error(chalk231.red(error.message));
39478
39675
  } else {
39479
39676
  console.error(error);
39480
39677
  }