@staff0rd/assist 0.574.1 → 0.576.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.574.1",
9
+ version: "0.576.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -4946,14 +4946,14 @@ function findRuleViolations(data, rule) {
4946
4946
  }
4947
4947
  return violations;
4948
4948
  }
4949
- function findForbiddenStrings(rules2, readJson) {
4950
- return rules2.flatMap((rule) => findRuleViolations(readJson(rule.file), rule));
4949
+ function findForbiddenStrings(rules3, readJson) {
4950
+ return rules3.flatMap((rule) => findRuleViolations(readJson(rule.file), rule));
4951
4951
  }
4952
4952
 
4953
4953
  // src/commands/verify/forbiddenStrings/index.ts
4954
4954
  function forbiddenStrings() {
4955
- const rules2 = loadConfig().forbiddenStrings ?? [];
4956
- if (rules2.length === 0) {
4955
+ const rules3 = loadConfig().forbiddenStrings ?? [];
4956
+ if (rules3.length === 0) {
4957
4957
  console.log("No forbidden-strings rules configured.");
4958
4958
  process.exit(0);
4959
4959
  }
@@ -4974,7 +4974,7 @@ function forbiddenStrings() {
4974
4974
  cache5.set(file, parsed);
4975
4975
  return parsed;
4976
4976
  };
4977
- const violations = findForbiddenStrings(rules2, readJson);
4977
+ const violations = findForbiddenStrings(rules3, readJson);
4978
4978
  if (violations.length === 0) {
4979
4979
  console.log("No forbidden strings found.");
4980
4980
  process.exit(0);
@@ -13949,7 +13949,7 @@ import chalk71 from "chalk";
13949
13949
  import { randomUUID as randomUUID2 } from "crypto";
13950
13950
 
13951
13951
  // src/commands/sessions/shared/reportPreviewRejection.ts
13952
- function reportPreviewRejection(subject, decision) {
13952
+ function reportPreviewRejection(subject, decision, advice) {
13953
13953
  console.error(
13954
13954
  `${subject} rejected${decision.reason ? `: ${decision.reason}` : "."}`
13955
13955
  );
@@ -13968,6 +13968,7 @@ ${quoted}
13968
13968
  `);
13969
13969
  }
13970
13970
  }
13971
+ if (advice) console.error(advice);
13971
13972
  process.exit(1);
13972
13973
  }
13973
13974
 
@@ -13979,6 +13980,7 @@ function toPreviewDecision(msg) {
13979
13980
  reason: msg.reason,
13980
13981
  comments: Array.isArray(msg.comments) ? msg.comments : void 0,
13981
13982
  screenshots: Array.isArray(msg.screenshots) ? msg.screenshots : void 0,
13983
+ body: typeof msg.body === "string" ? msg.body : void 0,
13982
13984
  reviewAfter: msg.reviewAfter === true,
13983
13985
  announceAfter: msg.announceAfter === true,
13984
13986
  draft: typeof msg.draft === "boolean" ? msg.draft : void 0
@@ -14029,7 +14031,7 @@ function requestPreviewDecision(request) {
14029
14031
  }
14030
14032
 
14031
14033
  // src/commands/sessions/shared/awaitPreviewApproval.ts
14032
- async function awaitPreviewApproval(subject, request) {
14034
+ async function awaitPreviewApproval(subject, request, options2 = {}) {
14033
14035
  console.log("Awaiting your approval in the assist web UI preview pane\u2026");
14034
14036
  let decision;
14035
14037
  try {
@@ -14040,7 +14042,9 @@ async function awaitPreviewApproval(subject, request) {
14040
14042
  );
14041
14043
  process.exit(1);
14042
14044
  }
14043
- if (decision.decision === "reject") reportPreviewRejection(subject, decision);
14045
+ if (decision.body !== void 0) options2.saveEditedBody?.(decision.body);
14046
+ if (decision.decision === "reject")
14047
+ reportPreviewRejection(subject, decision, options2.rejectionAdvice);
14044
14048
  return decision;
14045
14049
  }
14046
14050
 
@@ -20498,14 +20502,8 @@ import { spawnSync as spawnSync4 } from "child_process";
20498
20502
  import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
20499
20503
  import { tmpdir as tmpdir5 } from "os";
20500
20504
  import { join as join49 } from "path";
20501
- function buildArgs2(queryFile, vars) {
20502
- const args = ["api", "graphql", "-F", `query=@${queryFile}`];
20503
- for (const [key, value] of Object.entries(vars)) {
20504
- const flag = typeof value === "number" ? "-F" : "-f";
20505
- args.push(flag, `${key}=${value}`);
20506
- }
20507
- return args;
20508
- }
20505
+
20506
+ // src/shared/throwOnGraphqlErrors.ts
20509
20507
  function throwOnGraphqlErrors(stdout) {
20510
20508
  let parsed;
20511
20509
  try {
@@ -20521,6 +20519,16 @@ function throwOnGraphqlErrors(stdout) {
20521
20519
  ).join("; ");
20522
20520
  throw new Error(messages || "GraphQL request returned errors");
20523
20521
  }
20522
+
20523
+ // src/shared/runGhGraphql.ts
20524
+ function buildArgs2(queryFile, vars) {
20525
+ const args = ["api", "graphql", "-F", `query=@${queryFile}`];
20526
+ for (const [key, value] of Object.entries(vars)) {
20527
+ const flag = typeof value === "number" ? "-F" : "-f";
20528
+ args.push(flag, `${key}=${value}`);
20529
+ }
20530
+ return args;
20531
+ }
20524
20532
  function runGhGraphql(mutation, vars) {
20525
20533
  const queryFile = join49(tmpdir5(), `gh-query-${Date.now()}.graphql`);
20526
20534
  writeFileSync30(queryFile, mutation);
@@ -20828,6 +20836,83 @@ function fetchIssue2(number, repo) {
20828
20836
  }
20829
20837
  }
20830
20838
 
20839
+ // src/commands/github/issue/resumeIssueBody.ts
20840
+ import { existsSync as existsSync48, readFileSync as readFileSync37 } from "fs";
20841
+
20842
+ // src/commands/github/issue/issueWorkingFile.ts
20843
+ import { join as join50 } from "path";
20844
+ function issueWorkingFile(slug, number) {
20845
+ const [owner = "unknown", repo = "unknown"] = slug.split("/");
20846
+ const dir = join50(getStoreDir(), "github-issues", owner, repo);
20847
+ return {
20848
+ dir,
20849
+ bodyPath: join50(dir, `${number}.md`),
20850
+ metaPath: join50(dir, `${number}.json`)
20851
+ };
20852
+ }
20853
+
20854
+ // src/commands/github/issue/resumeIssueBody.ts
20855
+ function resumeIssueBody(slug, number, updatedAt) {
20856
+ const { bodyPath, metaPath } = issueWorkingFile(slug, number);
20857
+ if (!existsSync48(bodyPath) || !existsSync48(metaPath)) return void 0;
20858
+ try {
20859
+ const meta = JSON.parse(readFileSync37(metaPath, "utf8"));
20860
+ if (meta.updatedAt !== updatedAt) return void 0;
20861
+ return readFileSync37(bodyPath, "utf8");
20862
+ } catch {
20863
+ return void 0;
20864
+ }
20865
+ }
20866
+
20867
+ // src/commands/github/issue/validateIssueBody.ts
20868
+ function validateIssueBody(title, body) {
20869
+ validateProposedContent(
20870
+ { subject: "Issue", context: "GitHub issues" },
20871
+ title,
20872
+ body
20873
+ );
20874
+ }
20875
+
20876
+ // src/commands/github/issue/writeIssueWorkingFile.ts
20877
+ import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync31 } from "fs";
20878
+ function writeIssueWorkingFile(slug, number, target, updatedAt, body) {
20879
+ const { dir, bodyPath, metaPath } = issueWorkingFile(slug, number);
20880
+ mkdirSync16(dir, { recursive: true });
20881
+ writeFileSync31(bodyPath, body);
20882
+ writeFileSync31(
20883
+ metaPath,
20884
+ `${JSON.stringify({ target, updatedAt }, null, 2)}
20885
+ `
20886
+ );
20887
+ return bodyPath;
20888
+ }
20889
+
20890
+ // src/commands/github/issue/prepareIssueEdit.ts
20891
+ function slugFromUrl(url) {
20892
+ const match = /github\.com\/([^/]+\/[^/]+)\//.exec(url ?? "");
20893
+ return match ? match[1] : "unknown/unknown";
20894
+ }
20895
+ function prepareIssueEdit(number, repo, fresh) {
20896
+ const issue = fetchIssue2(number, repo);
20897
+ const slug = repo ?? slugFromUrl(issue.url);
20898
+ const target = `${slug}#${number}`;
20899
+ const resumed = fresh ? void 0 : resumeIssueBody(slug, number, issue.updatedAt);
20900
+ const body = resumed ?? issue.body;
20901
+ validateIssueBody(issue.title, body);
20902
+ const save = (markdown) => writeIssueWorkingFile(slug, number, target, issue.updatedAt, markdown);
20903
+ const bodyPath = save(body);
20904
+ if (resumed !== void 0)
20905
+ console.log(`Previewing the in-progress markdown from ${bodyPath}`);
20906
+ return {
20907
+ title: issue.title,
20908
+ target,
20909
+ updatedAt: issue.updatedAt,
20910
+ body,
20911
+ bodyPath,
20912
+ save
20913
+ };
20914
+ }
20915
+
20831
20916
  // src/commands/github/issue/pushIssueBody.ts
20832
20917
  import { execFileSync as execFileSync9 } from "child_process";
20833
20918
  function pushIssueBody(number, repo, bodyPath) {
@@ -20840,19 +20925,39 @@ function pushIssueBody(number, repo, bodyPath) {
20840
20925
  }
20841
20926
  }
20842
20927
 
20928
+ // src/commands/github/issue/pushUnchangedIssue.ts
20929
+ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
20930
+ if (fetchIssue2(number, repo).updatedAt !== fetchedAt) {
20931
+ console.error(
20932
+ `${target} was updated on GitHub after it was fetched. Nothing was pushed; the markdown is at ${bodyPath}`
20933
+ );
20934
+ process.exit(1);
20935
+ }
20936
+ pushIssueBody(number, repo, bodyPath);
20937
+ console.log(`Issue body updated on ${target}`);
20938
+ }
20939
+
20843
20940
  // src/commands/github/issue/reviewProposedIssueEdit.ts
20844
20941
  import { randomUUID as randomUUID9 } from "crypto";
20845
- async function reviewProposedIssueEdit(title, body) {
20942
+ async function reviewProposedIssueEdit(title, body, working) {
20846
20943
  const sessionId = process.env.ASSIST_SESSION_ID;
20847
- if (process.env.ASSIST_SESSION !== "1" || !sessionId) return;
20848
- await awaitPreviewApproval("GitHub issue edit preview", {
20849
- sessionId,
20850
- requestId: randomUUID9(),
20851
- title,
20852
- body,
20853
- prNumber: null,
20854
- kind: "github-issue-edit"
20855
- });
20944
+ if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
20945
+ const decision = await awaitPreviewApproval(
20946
+ "GitHub issue edit preview",
20947
+ {
20948
+ sessionId,
20949
+ requestId: randomUUID9(),
20950
+ title,
20951
+ body,
20952
+ prNumber: null,
20953
+ kind: "github-issue-edit"
20954
+ },
20955
+ {
20956
+ saveEditedBody: working.save,
20957
+ rejectionAdvice: `Nothing was pushed. The pane's markdown, including any collapses already applied, is at ${working.path}. Revise that file in place \u2014 do not recompose the body from scratch \u2014 then re-run this command to preview the revision.`
20958
+ }
20959
+ );
20960
+ return decision.body ?? body;
20856
20961
  }
20857
20962
 
20858
20963
  // src/commands/github/issue/viewIssue.ts
@@ -20867,40 +20972,8 @@ function viewIssue(number, repo) {
20867
20972
  }
20868
20973
  }
20869
20974
 
20870
- // src/commands/github/issue/writeIssueWorkingFile.ts
20871
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync31 } from "fs";
20872
-
20873
- // src/commands/github/issue/issueWorkingFile.ts
20874
- import { join as join50 } from "path";
20875
- function issueWorkingFile(slug, number) {
20876
- const [owner = "unknown", repo = "unknown"] = slug.split("/");
20877
- const dir = join50(getStoreDir(), "github-issues", owner, repo);
20878
- return {
20879
- dir,
20880
- bodyPath: join50(dir, `${number}.md`),
20881
- metaPath: join50(dir, `${number}.json`)
20882
- };
20883
- }
20884
-
20885
- // src/commands/github/issue/writeIssueWorkingFile.ts
20886
- function writeIssueWorkingFile(slug, number, target, updatedAt, body) {
20887
- const { dir, bodyPath, metaPath } = issueWorkingFile(slug, number);
20888
- mkdirSync16(dir, { recursive: true });
20889
- writeFileSync31(bodyPath, body);
20890
- writeFileSync31(
20891
- metaPath,
20892
- `${JSON.stringify({ target, updatedAt }, null, 2)}
20893
- `
20894
- );
20895
- return bodyPath;
20896
- }
20897
-
20898
20975
  // src/commands/github/issue/editIssue.ts
20899
20976
  var USAGE3 = "Usage: assist github issue edit <number> [-R <owner>/<repo>]";
20900
- function slugFromUrl(url) {
20901
- const match = /github\.com\/([^/]+\/[^/]+)\//.exec(url ?? "");
20902
- return match ? match[1] : "unknown/unknown";
20903
- }
20904
20977
  async function editIssue(numberArg, options2) {
20905
20978
  const number = Number.parseInt(numberArg, 10);
20906
20979
  if (!Number.isInteger(number) || number <= 0) {
@@ -20911,30 +20984,419 @@ async function editIssue(numberArg, options2) {
20911
20984
  viewIssue(number, options2.repo);
20912
20985
  return;
20913
20986
  }
20914
- const issue = fetchIssue2(number, options2.repo);
20915
- const slug = options2.repo ?? slugFromUrl(issue.url);
20916
- const target = `${slug}#${number}`;
20917
- validateProposedContent(
20918
- { subject: "Issue", context: "GitHub issues" },
20919
- issue.title,
20920
- issue.body
20987
+ const issue = prepareIssueEdit(number, options2.repo, options2.fresh);
20988
+ const edited = await reviewProposedIssueEdit(
20989
+ `Edit ${issue.target}: ${issue.title}`,
20990
+ issue.body,
20991
+ { path: issue.bodyPath, save: issue.save }
20921
20992
  );
20922
- const bodyPath = writeIssueWorkingFile(
20923
- slug,
20993
+ validateIssueBody(issue.title, edited);
20994
+ pushUnchangedIssue(
20924
20995
  number,
20925
- target,
20996
+ options2.repo,
20997
+ issue.target,
20926
20998
  issue.updatedAt,
20927
- issue.body
20999
+ issue.bodyPath
21000
+ );
21001
+ }
21002
+
21003
+ // src/commands/github/issue/fixStructure/matchedLabels.ts
21004
+ function matchedLabels(labels, stripLabels) {
21005
+ if (stripLabels.length === 0) return [];
21006
+ const wanted = new Set(stripLabels.map((name) => name.trim().toLowerCase()));
21007
+ return labels.filter((label2) => wanted.has(label2.name.trim().toLowerCase()));
21008
+ }
21009
+
21010
+ // src/commands/github/issue/fixStructure/normaliseTypeName.ts
21011
+ function normaliseTypeName(name) {
21012
+ return name.toLowerCase().replace(/[^a-z0-9]/g, "");
21013
+ }
21014
+
21015
+ // src/commands/github/issue/fixStructure/resolveIssueType.ts
21016
+ function resolveIssueType(issueTypes, levelName) {
21017
+ const wanted = normaliseTypeName(levelName);
21018
+ const match = issueTypes.find(
21019
+ (type) => normaliseTypeName(type.name) === wanted
20928
21020
  );
20929
- await reviewProposedIssueEdit(`Edit ${target}: ${issue.title}`, issue.body);
20930
- if (fetchIssue2(number, options2.repo).updatedAt !== issue.updatedAt) {
21021
+ if (!match) {
21022
+ throw new Error(
21023
+ `The organisation has no ${levelName} issue type. It has ${issueTypes.map((type) => type.name).join(", ")}`
21024
+ );
21025
+ }
21026
+ return match;
21027
+ }
21028
+
21029
+ // src/commands/github/issue/fixStructure/resolveLevelIndex.ts
21030
+ function resolveLevelIndex(chain2, name) {
21031
+ if (!name) return -1;
21032
+ const wanted = normaliseTypeName(name);
21033
+ return chain2.findIndex((level) => normaliseTypeName(level) === wanted);
21034
+ }
21035
+
21036
+ // src/commands/github/issue/fixStructure/buildPlanEntry.ts
21037
+ function buildPlanEntry(issue, context) {
21038
+ const labelRemovals = matchedLabels(issue.labels, context.stripLabels);
21039
+ const level = context.chain[context.rootLevelIndex + issue.depth];
21040
+ if (level === void 0) {
21041
+ return { issue, level: null, typeChange: null, labelRemovals };
21042
+ }
21043
+ const settled = resolveLevelIndex([level], issue.typeName) === 0 || issue.depth === 0 && !context.rootAsserted;
21044
+ if (settled) return { issue, level, typeChange: null, labelRemovals };
21045
+ const target = resolveIssueType(context.issueTypes, level);
21046
+ return {
21047
+ issue,
21048
+ level,
21049
+ typeChange: { from: issue.typeName, to: target.name, typeId: target.id },
21050
+ labelRemovals
21051
+ };
21052
+ }
21053
+
21054
+ // src/commands/github/issue/fixStructure/orderDepthFirst.ts
21055
+ function orderDepthFirst(issues) {
21056
+ const byParent = /* @__PURE__ */ new Map();
21057
+ for (const issue of issues) {
21058
+ const siblings = byParent.get(issue.parentId) ?? [];
21059
+ siblings.push(issue);
21060
+ byParent.set(issue.parentId, siblings);
21061
+ }
21062
+ const ordered = [];
21063
+ const visit = (issue) => {
21064
+ ordered.push(issue);
21065
+ for (const child of byParent.get(issue.id) ?? []) visit(child);
21066
+ };
21067
+ for (const root of byParent.get(null) ?? []) visit(root);
21068
+ return ordered;
21069
+ }
21070
+
21071
+ // src/commands/github/issue/fixStructure/buildFixStructurePlan.ts
21072
+ function buildFixStructurePlan(issues, options2) {
21073
+ const context = { ...options2, stripLabels: options2.stripLabels ?? [] };
21074
+ const byId = new Map(issues.map((issue) => [issue.id, issue]));
21075
+ const entries = [];
21076
+ const tooDeep = [];
21077
+ for (const issue of orderDepthFirst(issues)) {
21078
+ const entry = buildPlanEntry(issue, context);
21079
+ entries.push(entry);
21080
+ if (entry.level === null) {
21081
+ tooDeep.push({
21082
+ issue,
21083
+ parent: issue.parentId ? byId.get(issue.parentId) ?? null : null
21084
+ });
21085
+ }
21086
+ }
21087
+ return {
21088
+ entries,
21089
+ tooDeep,
21090
+ typeChangeCount: entries.filter((entry) => entry.typeChange).length,
21091
+ labelRemovalCount: entries.reduce(
21092
+ (total, entry) => total + entry.labelRemovals.length,
21093
+ 0
21094
+ )
21095
+ };
21096
+ }
21097
+
21098
+ // src/shared/runGhGraphqlJson.ts
21099
+ import { spawnSync as spawnSync5 } from "child_process";
21100
+ function runGhGraphqlJson(query, vars = {}) {
21101
+ const result = spawnSync5("gh", ["api", "graphql", "--input", "-"], {
21102
+ encoding: "utf8",
21103
+ windowsHide: true,
21104
+ input: JSON.stringify({ query, variables: vars }),
21105
+ maxBuffer: 64 * 1024 * 1024
21106
+ });
21107
+ if (result.status !== 0) throw new Error(result.stderr || result.stdout);
21108
+ throwOnGraphqlErrors(result.stdout);
21109
+ return result.stdout;
21110
+ }
21111
+
21112
+ // src/commands/github/issue/fixStructure/issueFieldsFragment.ts
21113
+ var issueFieldsFragment = `fragment issueFields on Issue {
21114
+ id
21115
+ number
21116
+ title
21117
+ issueType { name }
21118
+ repository { nameWithOwner }
21119
+ labels(first: 100) { nodes { id name } pageInfo { hasNextPage } }
21120
+ subIssues(first: 100) { nodes { id } pageInfo { hasNextPage } }
21121
+ }`;
21122
+
21123
+ // src/commands/github/issue/fixStructure/parseIssueNode.ts
21124
+ function parseIssueNode(node) {
21125
+ const raw = node;
21126
+ const repo = raw.repository?.nameWithOwner ?? "";
21127
+ const where = `${repo}#${raw.number}`;
21128
+ if (raw.labels?.pageInfo?.hasNextPage) {
21129
+ throw new Error(
21130
+ `${where} carries more than 100 labels, which is not supported`
21131
+ );
21132
+ }
21133
+ if (raw.subIssues?.pageInfo?.hasNextPage) {
21134
+ throw new Error(
21135
+ `${where} has more than 100 sub-issues, which is not supported`
21136
+ );
21137
+ }
21138
+ return {
21139
+ id: raw.id,
21140
+ number: raw.number,
21141
+ title: raw.title,
21142
+ repo,
21143
+ typeName: raw.issueType?.name ?? null,
21144
+ labels: (raw.labels?.nodes ?? []).filter((label2) => label2 !== null),
21145
+ childIds: (raw.subIssues?.nodes ?? []).filter((child) => child !== null).map((child) => child.id)
21146
+ };
21147
+ }
21148
+
21149
+ // src/commands/github/issue/fixStructure/fetchRootIssue.ts
21150
+ var QUERY = `query($owner: String!, $repo: String!, $number: Int!) {
21151
+ repository(owner: $owner, name: $repo) {
21152
+ issue(number: $number) { ...issueFields }
21153
+ }
21154
+ }
21155
+ ${issueFieldsFragment}`;
21156
+ function fetchRootIssue(target) {
21157
+ const raw = runGhGraphqlJson(QUERY, {
21158
+ owner: target.owner,
21159
+ repo: target.repo,
21160
+ number: target.number
21161
+ });
21162
+ const issue = JSON.parse(raw).data?.repository?.issue;
21163
+ if (!issue) {
21164
+ throw new Error(
21165
+ `No issue ${target.owner}/${target.repo}#${target.number} could be read`
21166
+ );
21167
+ }
21168
+ return parseIssueNode(issue);
21169
+ }
21170
+
21171
+ // src/commands/github/issue/fixStructure/printFixStructurePlan.ts
21172
+ import chalk162 from "chalk";
21173
+ function annotate(entry) {
21174
+ const notes = [];
21175
+ if (entry.level === null) {
21176
+ notes.push(chalk162.red("deeper than the leaf level"));
21177
+ } else if (entry.typeChange) {
21178
+ notes.push(
21179
+ chalk162.yellow(
21180
+ `${entry.typeChange.from ?? "no type"} -> ${entry.typeChange.to}`
21181
+ )
21182
+ );
21183
+ } else {
21184
+ notes.push(chalk162.dim(entry.issue.typeName ?? "no type"));
21185
+ }
21186
+ for (const label2 of entry.labelRemovals) {
21187
+ notes.push(chalk162.yellow(`-${label2.name}`));
21188
+ }
21189
+ return notes;
21190
+ }
21191
+ function formatCount(count8, noun) {
21192
+ return `${count8} ${noun}${count8 === 1 ? "" : "s"}`;
21193
+ }
21194
+ function printFixStructurePlan(plan2, chain2) {
21195
+ console.log(chalk162.dim(`chain: ${chain2.join(" > ")}`));
21196
+ for (const entry of plan2.entries) {
21197
+ const indent3 = " ".repeat(entry.issue.depth);
21198
+ const name = chalk162.cyan(`${entry.issue.repo}#${entry.issue.number}`);
21199
+ console.log(
21200
+ `${indent3}${name} ${entry.issue.title} [${annotate(entry).join(", ")}]`
21201
+ );
21202
+ }
21203
+ for (const { issue, parent } of plan2.tooDeep) {
21204
+ const where = parent ? ` under ${parent.repo}#${parent.number}` : "";
20931
21205
  console.error(
20932
- `${target} was updated on GitHub after it was fetched. Nothing was pushed; the markdown is at ${bodyPath}`
21206
+ chalk162.red(
21207
+ `${issue.repo}#${issue.number}${where} sits below ${chain2[chain2.length - 1]}, the leaf level`
21208
+ )
21209
+ );
21210
+ }
21211
+ if (plan2.typeChangeCount === 0 && plan2.labelRemovalCount === 0) {
21212
+ console.log(chalk162.green("Nothing to change"));
21213
+ return;
21214
+ }
21215
+ console.log(
21216
+ `${formatCount(plan2.typeChangeCount, "type change")}, ${formatCount(plan2.labelRemovalCount, "label removal")} planned`
21217
+ );
21218
+ console.log(chalk162.dim("Dry run \u2014 nothing written"));
21219
+ }
21220
+
21221
+ // src/commands/github/issue/fixStructure/resolveFixStructureTarget.ts
21222
+ var BARE_NUMBER = /^#?(\d+)$/;
21223
+ var REPO_SLUG = /^([^/\s]+)\/([^/\s]+)$/;
21224
+ function resolveFixStructureTarget(target, repo) {
21225
+ const shorthand = normalizeGithubIssue(target);
21226
+ if (shorthand) {
21227
+ const [slug2, number] = shorthand.split("#");
21228
+ const [owner, name] = (slug2 ?? "").split("/");
21229
+ return { owner: owner ?? "", repo: name ?? "", number: Number(number) };
21230
+ }
21231
+ const bare = BARE_NUMBER.exec(target.trim());
21232
+ if (!bare) {
21233
+ throw new Error(
21234
+ `Could not read "${target}" as a GitHub issue. Pass owner/repo#number, a github.com issue URL, or a bare number with --repo owner/repo`
21235
+ );
21236
+ }
21237
+ if (!repo) {
21238
+ throw new Error(
21239
+ `A bare issue number needs a repository. Re-run with --repo owner/repo, or pass the issue as owner/repo#${bare[1]}`
21240
+ );
21241
+ }
21242
+ const slug = REPO_SLUG.exec(repo.trim());
21243
+ if (!slug) {
21244
+ throw new Error(`--repo must be owner/repo, not "${repo}"`);
21245
+ }
21246
+ return {
21247
+ owner: slug[1] ?? "",
21248
+ repo: slug[2] ?? "",
21249
+ number: Number(bare[1])
21250
+ };
21251
+ }
21252
+
21253
+ // src/commands/github/issue/fixStructure/resolveOrgIssueTypes.ts
21254
+ var QUERY2 = `query($owner: String!) {
21255
+ organization(login: $owner) {
21256
+ issueTypes(first: 50) { nodes { id name } }
21257
+ }
21258
+ }`;
21259
+ function missingOrg(owner) {
21260
+ return new Error(
21261
+ `Issue types live on the organisation, and ${owner} is not one this token can read`
21262
+ );
21263
+ }
21264
+ function resolveOrgIssueTypes(owner) {
21265
+ let raw;
21266
+ try {
21267
+ raw = runGhGraphqlJson(QUERY2, { owner });
21268
+ } catch (error) {
21269
+ const message3 = error instanceof Error ? error.message : String(error);
21270
+ if (message3.includes("Could not resolve to an Organization")) {
21271
+ throw missingOrg(owner);
21272
+ }
21273
+ throw error;
21274
+ }
21275
+ const organization = JSON.parse(raw).data?.organization;
21276
+ if (!organization) throw missingOrg(owner);
21277
+ const types = (organization.issueTypes?.nodes ?? []).filter(
21278
+ (type) => type !== null
21279
+ );
21280
+ if (types.length === 0) {
21281
+ throw new Error(`The ${owner} organisation has no issue types defined`);
21282
+ }
21283
+ return types;
21284
+ }
21285
+
21286
+ // src/commands/github/issue/fixStructure/resolveRootLevelIndex.ts
21287
+ function resolveRootLevelIndex(chain2, targetTypeName, level) {
21288
+ if (level) {
21289
+ const index4 = resolveLevelIndex(chain2, level);
21290
+ if (index4 === -1) {
21291
+ throw new Error(
21292
+ `--level must name one of ${chain2.join(", ")}, not "${level}"`
21293
+ );
21294
+ }
21295
+ return { index: index4, asserted: true };
21296
+ }
21297
+ const index3 = resolveLevelIndex(chain2, targetTypeName);
21298
+ if (index3 === -1) {
21299
+ const has = targetTypeName ? `has the type ${targetTypeName}, which is not in the ${chain2.join(" > ")} chain` : "has no issue type";
21300
+ throw new Error(
21301
+ `The target ${has}, so its level cannot be inferred. Re-run with --level ${chain2.map((name) => name.toLowerCase()).join("|")} to assert where it sits.`
20933
21302
  );
21303
+ }
21304
+ return { index: index3, asserted: false };
21305
+ }
21306
+
21307
+ // src/commands/github/issue/fixStructure/types.ts
21308
+ var defaultTypeChain = ["Epic", "Story", "Subtask"];
21309
+
21310
+ // src/commands/github/issue/fixStructure/fetchSubtreeIssues.ts
21311
+ var QUERY3 = `query($ids: [ID!]!) {
21312
+ nodes(ids: $ids) { ... on Issue { ...issueFields } }
21313
+ }
21314
+ ${issueFieldsFragment}`;
21315
+ var BATCH = 50;
21316
+ function fetchSubtreeIssues(ids) {
21317
+ const issues = [];
21318
+ for (let start3 = 0; start3 < ids.length; start3 += BATCH) {
21319
+ const raw = runGhGraphqlJson(QUERY3, {
21320
+ ids: ids.slice(start3, start3 + BATCH)
21321
+ });
21322
+ const nodes = JSON.parse(raw).data?.nodes ?? [];
21323
+ for (const node of nodes) {
21324
+ if (node) issues.push(parseIssueNode(node));
21325
+ }
21326
+ }
21327
+ return issues;
21328
+ }
21329
+
21330
+ // src/commands/github/issue/fixStructure/walkSubtree.ts
21331
+ function walkSubtree(root, maxDepth, fetchIssues = fetchSubtreeIssues) {
21332
+ const placed = [{ ...root, depth: 0, parentId: null }];
21333
+ const seen = /* @__PURE__ */ new Set([root.id]);
21334
+ let frontier = placed;
21335
+ for (let depth = 1; depth <= maxDepth && frontier.length > 0; depth += 1) {
21336
+ const parentOf2 = /* @__PURE__ */ new Map();
21337
+ for (const parent of frontier) {
21338
+ for (const childId of parent.childIds) {
21339
+ if (seen.has(childId)) continue;
21340
+ seen.add(childId);
21341
+ parentOf2.set(childId, parent.id);
21342
+ }
21343
+ }
21344
+ if (parentOf2.size === 0) break;
21345
+ const children = fetchIssues([...parentOf2.keys()]).map((issue) => ({
21346
+ ...issue,
21347
+ depth,
21348
+ parentId: parentOf2.get(issue.id) ?? null
21349
+ }));
21350
+ placed.push(...children);
21351
+ frontier = children;
21352
+ }
21353
+ return placed;
21354
+ }
21355
+
21356
+ // src/commands/github/issue/fixStructure/fixStructure.ts
21357
+ function fixStructure(target, options2) {
21358
+ const chain2 = defaultTypeChain;
21359
+ try {
21360
+ const resolved = resolveFixStructureTarget(target, options2.repo);
21361
+ const root = fetchRootIssue(resolved);
21362
+ const { index: index3, asserted } = resolveRootLevelIndex(
21363
+ chain2,
21364
+ root.typeName,
21365
+ options2.level
21366
+ );
21367
+ const issueTypes = resolveOrgIssueTypes(resolved.owner);
21368
+ const issues = walkSubtree(root, chain2.length - index3);
21369
+ const plan2 = buildFixStructurePlan(issues, {
21370
+ chain: chain2,
21371
+ rootLevelIndex: index3,
21372
+ rootAsserted: asserted,
21373
+ issueTypes
21374
+ });
21375
+ printFixStructurePlan(plan2, chain2);
21376
+ } catch (error) {
21377
+ console.error(error instanceof Error ? error.message : String(error));
20934
21378
  process.exit(1);
20935
21379
  }
20936
- pushIssueBody(number, options2.repo, bodyPath);
20937
- console.log(`Issue body updated on ${target}`);
21380
+ }
21381
+
21382
+ // src/commands/github/issue/fixStructure/registerFixStructure.ts
21383
+ var chain = defaultTypeChain.join(" > ");
21384
+ var levels = defaultTypeChain.map((name) => name.toLowerCase()).join("|");
21385
+ function registerFixStructure(issueCommand) {
21386
+ issueCommand.command("fix-structure <target>").description("Report the issue type drift across one issue subtree").option(
21387
+ "-R, --repo <owner/repo>",
21388
+ "Repository a bare issue number belongs to"
21389
+ ).option(
21390
+ "--level <level>",
21391
+ `The target's own position in the ${chain} chain, when it cannot be inferred from its type`
21392
+ ).addHelpText(
21393
+ "after",
21394
+ `
21395
+ Walks the subtree reachable from <target> via sub-issues and reports the type each issue should carry: every level below the target is typed to the next level down the ${chain} chain. Nothing outside the subtree is ever read or written.
21396
+ The target's own level is inferred from its issue type, so aiming at a story types its children as subtasks. When the target's type is not in the chain the level cannot be inferred, and --level ${levels} asserts it instead \u2014 which also plans the target's own type.
21397
+ The target is owner/repo#number, a github.com issue URL, or a bare number with --repo.
21398
+ This reports only; nothing is written.`
21399
+ ).action(fixStructure);
20938
21400
  }
20939
21401
 
20940
21402
  // src/commands/prs/readBodyArgument.ts
@@ -20961,9 +21423,12 @@ function registerGithubIssue(githubCommand) {
20961
21423
  issueCommand.command("edit <number>").description("Edit an existing GitHub issue's body in the preview pane").option(
20962
21424
  "-R, --repo <owner/repo>",
20963
21425
  "Target repository (defaults to the current repo)"
21426
+ ).option(
21427
+ "--fresh",
21428
+ "Discard any working file for the issue and re-fetch its body from GitHub"
20964
21429
  ).addHelpText(
20965
21430
  "after",
20966
- "\nFetches the issue's current body and opens it in the assist web preview pane, where it can be reworked before it is pushed back. Approving pushes the pane's markdown to the issue; nothing is pushed if the issue moved on GitHub after it was fetched, or outside a web session.\nOnly the body is touched \u2014 the title, labels, assignees and state are left alone."
21431
+ "\nFetches the issue's current body and opens it in the assist web preview pane, where it can be reworked before it is pushed back. Approving pushes the pane's markdown to the issue; nothing is pushed if the issue moved on GitHub after it was fetched, or outside a web session.\nRejecting writes the pane's markdown to a working file and names it: revise that file in place and re-run to preview the revision, which keeps any collapses already applied. A re-run resumes from the working file while the issue has not moved on GitHub; --fresh discards it and re-fetches.\nOnly the body is touched \u2014 the title, labels, assignees and state are left alone."
20967
21432
  ).action(editIssue);
20968
21433
  issueCommand.command("comment <number>").description("Comment on a GitHub issue (body of - reads it from stdin)").option("--body <body>", "Comment body (- reads it from stdin)").option(
20969
21434
  "-R, --repo <owner/repo>",
@@ -20979,6 +21444,7 @@ function registerGithubIssue(githubCommand) {
20979
21444
  });
20980
21445
  }
20981
21446
  );
21447
+ registerFixStructure(issueCommand);
20982
21448
  }
20983
21449
 
20984
21450
  // src/commands/registerGithub.ts
@@ -21005,9 +21471,9 @@ async function countPendingHandovers(orm, origin) {
21005
21471
 
21006
21472
  // src/commands/handover/migrateDiskHandovers.ts
21007
21473
  import {
21008
- existsSync as existsSync48,
21474
+ existsSync as existsSync49,
21009
21475
  readdirSync as readdirSync10,
21010
- readFileSync as readFileSync37,
21476
+ readFileSync as readFileSync38,
21011
21477
  rmSync as rmSync3,
21012
21478
  statSync as statSync8
21013
21479
  } from "fs";
@@ -21060,7 +21526,7 @@ function summariseHandoverContent(content) {
21060
21526
 
21061
21527
  // src/commands/handover/migrateDiskHandovers.ts
21062
21528
  function collectMarkdown(dir) {
21063
- if (!existsSync48(dir)) return [];
21529
+ if (!existsSync49(dir)) return [];
21064
21530
  const out = [];
21065
21531
  for (const entry of readdirSync10(dir, { withFileTypes: true })) {
21066
21532
  const full = join53(dir, entry.name);
@@ -21070,7 +21536,7 @@ function collectMarkdown(dir) {
21070
21536
  return out;
21071
21537
  }
21072
21538
  async function migrateFile(orm, origin, file, createdAt) {
21073
- const content = readFileSync37(file, "utf8");
21539
+ const content = readFileSync38(file, "utf8");
21074
21540
  await saveHandover(orm, {
21075
21541
  origin,
21076
21542
  summary: summariseHandoverContent(content),
@@ -21087,7 +21553,7 @@ async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
21087
21553
  migrated++;
21088
21554
  }
21089
21555
  const handoverPath = getHandoverPath(cwd);
21090
- if (existsSync48(handoverPath)) {
21556
+ if (existsSync49(handoverPath)) {
21091
21557
  await migrateFile(orm, origin, handoverPath, statSync8(handoverPath).mtime);
21092
21558
  migrated++;
21093
21559
  }
@@ -21218,7 +21684,7 @@ function registerHandover(program2) {
21218
21684
  }
21219
21685
 
21220
21686
  // src/commands/jira/acceptanceCriteria.ts
21221
- import chalk162 from "chalk";
21687
+ import chalk163 from "chalk";
21222
21688
 
21223
21689
  // src/commands/jira/adfToText.ts
21224
21690
  function renderInline(node) {
@@ -21285,7 +21751,7 @@ function acceptanceCriteria(issueKey) {
21285
21751
  const parsed = fetchIssue(issueKey, field);
21286
21752
  const acValue = parsed?.fields?.[field];
21287
21753
  if (!acValue) {
21288
- console.log(chalk162.yellow(`No acceptance criteria found on ${issueKey}.`));
21754
+ console.log(chalk163.yellow(`No acceptance criteria found on ${issueKey}.`));
21289
21755
  return;
21290
21756
  }
21291
21757
  if (typeof acValue === "string") {
@@ -21351,14 +21817,14 @@ async function jiraAuth() {
21351
21817
  }
21352
21818
 
21353
21819
  // src/commands/jira/viewIssue.ts
21354
- import chalk163 from "chalk";
21820
+ import chalk164 from "chalk";
21355
21821
  function viewIssue2(issueKey) {
21356
21822
  const parsed = fetchIssue(issueKey, "summary,description");
21357
21823
  const fields = parsed?.fields;
21358
21824
  const summary = fields?.summary;
21359
21825
  const description = fields?.description;
21360
21826
  if (summary) {
21361
- console.log(chalk163.bold(summary));
21827
+ console.log(chalk164.bold(summary));
21362
21828
  }
21363
21829
  if (description) {
21364
21830
  if (summary) console.log();
@@ -21372,7 +21838,7 @@ function viewIssue2(issueKey) {
21372
21838
  }
21373
21839
  if (!summary && !description) {
21374
21840
  console.log(
21375
- chalk163.yellow(`No summary or description found on ${issueKey}.`)
21841
+ chalk164.yellow(`No summary or description found on ${issueKey}.`)
21376
21842
  );
21377
21843
  }
21378
21844
  }
@@ -21407,7 +21873,7 @@ import { randomUUID as randomUUID10 } from "crypto";
21407
21873
 
21408
21874
  // src/commands/review/checkoutPr.ts
21409
21875
  import { execFileSync as execFileSync12 } from "child_process";
21410
- import chalk164 from "chalk";
21876
+ import chalk165 from "chalk";
21411
21877
 
21412
21878
  // src/commands/sessions/daemon/daemonLog.ts
21413
21879
  var RING_CAPACITY = 1e3;
@@ -21444,7 +21910,7 @@ function canonicalTreePath(path80) {
21444
21910
  }
21445
21911
 
21446
21912
  // src/commands/sessions/daemon/worktree/createWorktree.ts
21447
- import { existsSync as existsSync49 } from "fs";
21913
+ import { existsSync as existsSync50 } from "fs";
21448
21914
  import { basename as basename16, dirname as dirname25 } from "path";
21449
21915
 
21450
21916
  // src/commands/sessions/daemon/worktree/planAllocation.ts
@@ -21491,7 +21957,7 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
21491
21957
  const base = strategy.root ? expandTilde2(strategy.root) : dirname25(clone);
21492
21958
  const registered = new Set(listWorktreePaths(clone));
21493
21959
  const branches = new Set(listLocalBranches(clone));
21494
- const isTaken = (candidate) => registered.has(candidate) || existsSync49(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename16(candidate));
21960
+ const isTaken = (candidate) => registered.has(candidate) || existsSync50(candidate) || boundTreeRoots2.has(candidate) || branches.has(basename16(candidate));
21495
21961
  const path80 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
21496
21962
  const start3 = worktreeStartPoint(clone, strategy.trunk);
21497
21963
  gitSync(clone, [
@@ -21517,7 +21983,7 @@ function keptInTree(cwd, reason4) {
21517
21983
  }
21518
21984
 
21519
21985
  // src/commands/sessions/daemon/worktree/treeDurability.ts
21520
- import { existsSync as existsSync50 } from "fs";
21986
+ import { existsSync as existsSync51 } from "fs";
21521
21987
  var treeIsGone = { durable: true, gone: true };
21522
21988
  function treeDurability(state) {
21523
21989
  if (state.dirty) return { durable: false, reason: "uncommitted changes" };
@@ -21548,14 +22014,14 @@ function* durabilityProbes() {
21548
22014
  });
21549
22015
  }
21550
22016
  async function checkDurability(cwd) {
21551
- if (!existsSync50(cwd)) return treeIsGone;
22017
+ if (!existsSync51(cwd)) return treeIsGone;
21552
22018
  const probes = durabilityProbes();
21553
22019
  let step2 = probes.next();
21554
22020
  while (!step2.done) step2 = probes.next(await gitResult(cwd, step2.value));
21555
22021
  return step2.value;
21556
22022
  }
21557
22023
  function checkDurabilitySync(cwd) {
21558
- if (!existsSync50(cwd)) return treeIsGone;
22024
+ if (!existsSync51(cwd)) return treeIsGone;
21559
22025
  const probes = durabilityProbes();
21560
22026
  let step2 = probes.next();
21561
22027
  while (!step2.done) step2 = probes.next(gitSyncResult(cwd, step2.value));
@@ -21798,20 +22264,20 @@ function persistedTreeRoots() {
21798
22264
  }
21799
22265
 
21800
22266
  // src/commands/sessions/daemon/worktree/seedWorktree.ts
21801
- import { copyFileSync, existsSync as existsSync52, mkdirSync as mkdirSync17 } from "fs";
22267
+ import { copyFileSync, existsSync as existsSync53, mkdirSync as mkdirSync17 } from "fs";
21802
22268
  import { dirname as dirname26, join as join56 } from "path";
21803
22269
 
21804
22270
  // src/commands/sessions/daemon/worktree/runInstall.ts
21805
22271
  import { spawn as spawn5 } from "child_process";
21806
22272
 
21807
22273
  // src/commands/sessions/daemon/worktree/resolveInstallCommand.ts
21808
- import { existsSync as existsSync51 } from "fs";
22274
+ import { existsSync as existsSync52 } from "fs";
21809
22275
  import { join as join55 } from "path";
21810
22276
  function detectInstallCommand(repoRoot2) {
21811
- if (!existsSync51(join55(repoRoot2, "package.json"))) return null;
21812
- if (existsSync51(join55(repoRoot2, "pnpm-lock.yaml"))) return "pnpm install";
21813
- if (existsSync51(join55(repoRoot2, "yarn.lock"))) return "yarn install";
21814
- if (existsSync51(join55(repoRoot2, "bun.lockb"))) return "bun install";
22277
+ if (!existsSync52(join55(repoRoot2, "package.json"))) return null;
22278
+ if (existsSync52(join55(repoRoot2, "pnpm-lock.yaml"))) return "pnpm install";
22279
+ if (existsSync52(join55(repoRoot2, "yarn.lock"))) return "yarn install";
22280
+ if (existsSync52(join55(repoRoot2, "bun.lockb"))) return "bun install";
21815
22281
  return "npm install";
21816
22282
  }
21817
22283
  function resolveInstallCommand(repoRoot2, install) {
@@ -21924,7 +22390,7 @@ function seedWorktree(worktreePath, clone, onSeeded = () => {
21924
22390
  function copyConfigFiles(worktreePath, clone, copy) {
21925
22391
  for (const rel of copy) {
21926
22392
  const src = join56(clone, rel);
21927
- if (!existsSync52(src)) continue;
22393
+ if (!existsSync53(src)) continue;
21928
22394
  const dest = join56(worktreePath, rel);
21929
22395
  try {
21930
22396
  mkdirSync17(dirname26(dest), { recursive: true });
@@ -22019,7 +22485,7 @@ async function checkoutPr(number) {
22019
22485
  try {
22020
22486
  execFileSync12("gh", ["pr", "checkout", number], { stdio: "inherit" });
22021
22487
  } catch {
22022
- console.error(chalk164.red(`gh pr checkout ${number} failed; aborting.`));
22488
+ console.error(chalk165.red(`gh pr checkout ${number} failed; aborting.`));
22023
22489
  process.exit(1);
22024
22490
  }
22025
22491
  }
@@ -22156,15 +22622,15 @@ function registerList(program2) {
22156
22622
  // src/commands/mermaid/index.ts
22157
22623
  import { mkdirSync as mkdirSync18, readdirSync as readdirSync11 } from "fs";
22158
22624
  import { resolve as resolve16 } from "path";
22159
- import chalk167 from "chalk";
22625
+ import chalk168 from "chalk";
22160
22626
 
22161
22627
  // src/commands/mermaid/exportFile.ts
22162
- import { readFileSync as readFileSync38, writeFileSync as writeFileSync32 } from "fs";
22628
+ import { readFileSync as readFileSync39, writeFileSync as writeFileSync32 } from "fs";
22163
22629
  import { basename as basename17, extname as extname2, resolve as resolve15 } from "path";
22164
- import chalk166 from "chalk";
22630
+ import chalk167 from "chalk";
22165
22631
 
22166
22632
  // src/commands/mermaid/renderBlock.ts
22167
- import chalk165 from "chalk";
22633
+ import chalk166 from "chalk";
22168
22634
  async function renderBlock(krokiUrl, source) {
22169
22635
  const response = await fetch(`${krokiUrl}/mermaid/svg`, {
22170
22636
  method: "POST",
@@ -22173,7 +22639,7 @@ async function renderBlock(krokiUrl, source) {
22173
22639
  });
22174
22640
  if (!response.ok) {
22175
22641
  console.error(
22176
- chalk165.red(
22642
+ chalk166.red(
22177
22643
  `Kroki request failed: ${response.status} ${response.statusText}`
22178
22644
  )
22179
22645
  );
@@ -22185,25 +22651,25 @@ async function renderBlock(krokiUrl, source) {
22185
22651
 
22186
22652
  // src/commands/mermaid/exportFile.ts
22187
22653
  async function exportFile(file, outDir, krokiUrl, onlyIndex) {
22188
- const content = readFileSync38(file, "utf8");
22654
+ const content = readFileSync39(file, "utf8");
22189
22655
  const blocks = extractMermaidBlocks(content);
22190
22656
  const stem = basename17(file, extname2(file));
22191
22657
  if (onlyIndex !== void 0) {
22192
22658
  if (onlyIndex < 1 || onlyIndex > blocks.length) {
22193
22659
  console.error(
22194
- chalk166.red(
22660
+ chalk167.red(
22195
22661
  `${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
22196
22662
  )
22197
22663
  );
22198
22664
  process.exit(1);
22199
22665
  }
22200
22666
  console.log(
22201
- chalk166.gray(
22667
+ chalk167.gray(
22202
22668
  `${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
22203
22669
  )
22204
22670
  );
22205
22671
  } else {
22206
- console.log(chalk166.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
22672
+ console.log(chalk167.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
22207
22673
  }
22208
22674
  for (const [i, source] of blocks.entries()) {
22209
22675
  const idx = i + 1;
@@ -22211,7 +22677,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
22211
22677
  const outPath = resolve15(outDir, `${stem}-${idx}.svg`);
22212
22678
  const svg = await renderBlock(krokiUrl, source);
22213
22679
  writeFileSync32(outPath, svg, "utf8");
22214
- console.log(chalk166.green(` \u2192 ${outPath}`));
22680
+ console.log(chalk167.green(` \u2192 ${outPath}`));
22215
22681
  }
22216
22682
  }
22217
22683
  function extractMermaidBlocks(markdown) {
@@ -22227,18 +22693,18 @@ async function mermaidExport(file, options2 = {}) {
22227
22693
  if (options2.index !== void 0) {
22228
22694
  if (!Number.isInteger(options2.index) || options2.index < 1) {
22229
22695
  console.error(
22230
- chalk167.red(`--index must be a positive integer (got ${options2.index})`)
22696
+ chalk168.red(`--index must be a positive integer (got ${options2.index})`)
22231
22697
  );
22232
22698
  process.exit(1);
22233
22699
  }
22234
22700
  if (!file) {
22235
- console.error(chalk167.red("--index requires a file argument"));
22701
+ console.error(chalk168.red("--index requires a file argument"));
22236
22702
  process.exit(1);
22237
22703
  }
22238
22704
  }
22239
22705
  const files = file ? [file] : readdirSync11(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
22240
22706
  if (files.length === 0) {
22241
- console.log(chalk167.gray("No markdown files found in current directory."));
22707
+ console.log(chalk168.gray("No markdown files found in current directory."));
22242
22708
  return;
22243
22709
  }
22244
22710
  for (const f of files) {
@@ -22265,7 +22731,7 @@ function registerMermaid(program2) {
22265
22731
  import { mkdir as mkdir4 } from "fs/promises";
22266
22732
  import { createServer as createServer2 } from "http";
22267
22733
  import { dirname as dirname28 } from "path";
22268
- import chalk169 from "chalk";
22734
+ import chalk170 from "chalk";
22269
22735
 
22270
22736
  // src/commands/netcap/corsHeaders.ts
22271
22737
  var corsHeaders = {
@@ -22344,7 +22810,7 @@ function createNetcapHandler(options2) {
22344
22810
  import { cp, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
22345
22811
  import { networkInterfaces } from "os";
22346
22812
  import { join as join58 } from "path";
22347
- import chalk168 from "chalk";
22813
+ import chalk169 from "chalk";
22348
22814
 
22349
22815
  // src/commands/netcap/netcapExtensionDir.ts
22350
22816
  import { dirname as dirname27, join as join57 } from "path";
@@ -22388,7 +22854,7 @@ async function prepareExtensionForLoad(port, filter = "") {
22388
22854
  const host = lanIPv4();
22389
22855
  if (!host) {
22390
22856
  console.log(
22391
- chalk168.yellow("could not determine the WSL IP for the extension")
22857
+ chalk169.yellow("could not determine the WSL IP for the extension")
22392
22858
  );
22393
22859
  await configureBackground(source, "127.0.0.1", port, filter);
22394
22860
  return source;
@@ -22399,7 +22865,7 @@ async function prepareExtensionForLoad(port, filter = "") {
22399
22865
  return WSL_WINDOWS_PATH;
22400
22866
  } catch {
22401
22867
  console.log(
22402
- chalk168.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
22868
+ chalk169.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
22403
22869
  );
22404
22870
  return source;
22405
22871
  }
@@ -22432,30 +22898,30 @@ async function netcap(options2) {
22432
22898
  let count8 = 0;
22433
22899
  const handler = createNetcapHandler({
22434
22900
  outPath,
22435
- onPing: () => console.log(chalk169.dim("ping from extension")),
22901
+ onPing: () => console.log(chalk170.dim("ping from extension")),
22436
22902
  onCapture: (entry) => {
22437
22903
  count8 += 1;
22438
22904
  console.log(
22439
- chalk169.green(`captured #${count8}`),
22440
- chalk169.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
22905
+ chalk170.green(`captured #${count8}`),
22906
+ chalk170.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
22441
22907
  );
22442
22908
  }
22443
22909
  });
22444
22910
  const server = createServer2(handler);
22445
22911
  server.listen(port, () => {
22446
22912
  console.log(
22447
- chalk169.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
22913
+ chalk170.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
22448
22914
  );
22449
- console.log(chalk169.dim(`appending captures to ${outPath}`));
22915
+ console.log(chalk170.dim(`appending captures to ${outPath}`));
22450
22916
  if (filter)
22451
- console.log(chalk169.dim(`forwarding only URLs matching "${filter}"`));
22452
- console.log(chalk169.dim(`load the unpacked extension from ${extensionPath}`));
22453
- console.log(chalk169.dim("press Ctrl-C to stop"));
22917
+ console.log(chalk170.dim(`forwarding only URLs matching "${filter}"`));
22918
+ console.log(chalk170.dim(`load the unpacked extension from ${extensionPath}`));
22919
+ console.log(chalk170.dim("press Ctrl-C to stop"));
22454
22920
  });
22455
22921
  process.on("SIGINT", () => {
22456
22922
  server.close();
22457
22923
  console.log(
22458
- chalk169.bold(
22924
+ chalk170.bold(
22459
22925
  `
22460
22926
  netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} to ${outPath}`
22461
22927
  )
@@ -22467,10 +22933,10 @@ netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} t
22467
22933
  // src/commands/netcap/netcapExtract.ts
22468
22934
  import { writeFileSync as writeFileSync33 } from "fs";
22469
22935
  import { join as join61 } from "path";
22470
- import chalk170 from "chalk";
22936
+ import chalk171 from "chalk";
22471
22937
 
22472
22938
  // src/commands/netcap/extractPostsFromCapture.ts
22473
- import { readFileSync as readFileSync39 } from "fs";
22939
+ import { readFileSync as readFileSync40 } from "fs";
22474
22940
 
22475
22941
  // src/commands/netcap/parseRscRows.ts
22476
22942
  var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
@@ -22866,7 +23332,7 @@ function extractVoyagerPosts(body) {
22866
23332
 
22867
23333
  // src/commands/netcap/extractPostsFromCapture.ts
22868
23334
  function captureEntries(captureFile) {
22869
- const lines2 = readFileSync39(captureFile, "utf8").split("\n").filter(Boolean);
23335
+ const lines2 = readFileSync40(captureFile, "utf8").split("\n").filter(Boolean);
22870
23336
  const entries = [];
22871
23337
  for (const line of lines2) {
22872
23338
  let entry;
@@ -22915,8 +23381,8 @@ function netcapExtract(file) {
22915
23381
  writeFileSync33(outFile, `${JSON.stringify(posts, null, 2)}
22916
23382
  `);
22917
23383
  console.log(
22918
- chalk170.green(`extracted ${posts.length} posts`),
22919
- chalk170.dim(`-> ${outFile}`)
23384
+ chalk171.green(`extracted ${posts.length} posts`),
23385
+ chalk171.dim(`-> ${outFile}`)
22920
23386
  );
22921
23387
  }
22922
23388
 
@@ -22937,7 +23403,7 @@ function registerNetcap(program2) {
22937
23403
  }
22938
23404
 
22939
23405
  // src/commands/news/add/index.ts
22940
- import chalk171 from "chalk";
23406
+ import chalk172 from "chalk";
22941
23407
  import enquirer8 from "enquirer";
22942
23408
  async function add2(url) {
22943
23409
  if (!url) {
@@ -22959,10 +23425,10 @@ async function add2(url) {
22959
23425
  const { orm } = await getReady();
22960
23426
  const added = await addFeed(orm, url);
22961
23427
  if (!added) {
22962
- console.log(chalk171.yellow("Feed already exists"));
23428
+ console.log(chalk172.yellow("Feed already exists"));
22963
23429
  return;
22964
23430
  }
22965
- console.log(chalk171.green(`Added feed: ${url}`));
23431
+ console.log(chalk172.green(`Added feed: ${url}`));
22966
23432
  }
22967
23433
 
22968
23434
  // src/commands/registerNews.ts
@@ -23009,7 +23475,7 @@ function registerPiHook(program2) {
23009
23475
  }
23010
23476
 
23011
23477
  // src/commands/prompts/printPromptsTable.ts
23012
- import chalk172 from "chalk";
23478
+ import chalk173 from "chalk";
23013
23479
  function truncate(str, max) {
23014
23480
  if (str.length <= max) return str;
23015
23481
  return `${str.slice(0, max - 1)}\u2026`;
@@ -23027,14 +23493,14 @@ function printPromptsTable(rows) {
23027
23493
  "Command".padEnd(commandWidth),
23028
23494
  "Repos"
23029
23495
  ].join(" ");
23030
- console.log(chalk172.dim(header));
23031
- console.log(chalk172.dim("-".repeat(header.length)));
23496
+ console.log(chalk173.dim(header));
23497
+ console.log(chalk173.dim("-".repeat(header.length)));
23032
23498
  for (const row of rows) {
23033
23499
  const count8 = String(row.count).padStart(countWidth);
23034
23500
  const tool = row.tool.padEnd(toolWidth);
23035
23501
  const command = truncate(row.command, 60).padEnd(commandWidth);
23036
23502
  console.log(
23037
- `${chalk172.yellow(count8)} ${tool} ${command} ${chalk172.dim(row.repos)}`
23503
+ `${chalk173.yellow(count8)} ${tool} ${command} ${chalk173.dim(row.repos)}`
23038
23504
  );
23039
23505
  }
23040
23506
  }
@@ -23440,7 +23906,7 @@ import { tmpdir as tmpdir6 } from "os";
23440
23906
  import { join as join63 } from "path";
23441
23907
 
23442
23908
  // src/commands/prs/loadCommentsCache.ts
23443
- import { existsSync as existsSync53, readFileSync as readFileSync40, unlinkSync as unlinkSync13 } from "fs";
23909
+ import { existsSync as existsSync54, readFileSync as readFileSync41, unlinkSync as unlinkSync13 } from "fs";
23444
23910
  import { parse as parse2 } from "yaml";
23445
23911
 
23446
23912
  // src/commands/prs/commentsCachePath.ts
@@ -23460,24 +23926,24 @@ function commentsCachePath(org, repo, prNumber) {
23460
23926
  // src/commands/prs/loadCommentsCache.ts
23461
23927
  function loadCommentsCache(org, repo, prNumber) {
23462
23928
  const cachePath = commentsCachePath(org, repo, prNumber);
23463
- if (!existsSync53(cachePath)) {
23929
+ if (!existsSync54(cachePath)) {
23464
23930
  return null;
23465
23931
  }
23466
- const content = readFileSync40(cachePath, "utf8");
23932
+ const content = readFileSync41(cachePath, "utf8");
23467
23933
  return parse2(content);
23468
23934
  }
23469
23935
  function deleteCommentsCache(org, repo, prNumber) {
23470
23936
  const cachePath = commentsCachePath(org, repo, prNumber);
23471
- if (existsSync53(cachePath)) {
23937
+ if (existsSync54(cachePath)) {
23472
23938
  unlinkSync13(cachePath);
23473
23939
  console.log("No more unresolved line comments. Cache dropped.");
23474
23940
  }
23475
23941
  }
23476
23942
 
23477
23943
  // src/commands/prs/replyToComment.ts
23478
- import { spawnSync as spawnSync5 } from "child_process";
23944
+ import { spawnSync as spawnSync6 } from "child_process";
23479
23945
  function replyToComment(org, repo, prNumber, commentId, message3) {
23480
- const result = spawnSync5(
23946
+ const result = spawnSync6(
23481
23947
  "gh",
23482
23948
  [
23483
23949
  "api",
@@ -23701,13 +24167,13 @@ function agentFooter(unresolvedCount) {
23701
24167
  }
23702
24168
 
23703
24169
  // src/commands/prs/listComments/commentStyle.ts
23704
- import chalk173 from "chalk";
24170
+ import chalk174 from "chalk";
23705
24171
  var plain = (text18) => text18;
23706
24172
  function colouredState(state) {
23707
24173
  const label2 = `[${state}]`;
23708
- if (state === "APPROVED") return chalk173.green(label2);
23709
- if (state === "CHANGES_REQUESTED") return chalk173.red(label2);
23710
- return chalk173.yellow(label2);
24174
+ if (state === "APPROVED") return chalk174.green(label2);
24175
+ if (state === "CHANGES_REQUESTED") return chalk174.red(label2);
24176
+ return chalk174.yellow(label2);
23711
24177
  }
23712
24178
  function commentStyle() {
23713
24179
  if (isClaudeCode()) {
@@ -23721,9 +24187,9 @@ function commentStyle() {
23721
24187
  };
23722
24188
  }
23723
24189
  return {
23724
- cyan: chalk173.cyan,
23725
- bold: chalk173.bold,
23726
- dim: chalk173.dim,
24190
+ cyan: chalk174.cyan,
24191
+ bold: chalk174.bold,
24192
+ dim: chalk174.dim,
23727
24193
  state: colouredState,
23728
24194
  diffHunk: true,
23729
24195
  agent: false
@@ -23893,13 +24359,13 @@ import { execSync as execSync48 } from "child_process";
23893
24359
  import enquirer9 from "enquirer";
23894
24360
 
23895
24361
  // src/commands/prs/prs/displayPaginated/printPr.ts
23896
- import chalk174 from "chalk";
24362
+ import chalk175 from "chalk";
23897
24363
  var STATUS_MAP = {
23898
- MERGED: (pr) => pr.mergedAt ? { label: chalk174.magenta("merged"), date: pr.mergedAt } : null,
23899
- CLOSED: (pr) => pr.closedAt ? { label: chalk174.red("closed"), date: pr.closedAt } : null
24364
+ MERGED: (pr) => pr.mergedAt ? { label: chalk175.magenta("merged"), date: pr.mergedAt } : null,
24365
+ CLOSED: (pr) => pr.closedAt ? { label: chalk175.red("closed"), date: pr.closedAt } : null
23900
24366
  };
23901
24367
  function defaultStatus(pr) {
23902
- return { label: chalk174.green("opened"), date: pr.createdAt };
24368
+ return { label: chalk175.green("opened"), date: pr.createdAt };
23903
24369
  }
23904
24370
  function getStatus2(pr) {
23905
24371
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -23908,11 +24374,11 @@ function formatDate(dateStr) {
23908
24374
  return new Date(dateStr).toISOString().split("T")[0];
23909
24375
  }
23910
24376
  function formatPrHeader(pr, status3) {
23911
- return `${chalk174.cyan(`#${pr.number}`)} ${pr.title} ${chalk174.dim(`(${pr.author.login},`)} ${status3.label} ${chalk174.dim(`${formatDate(status3.date)})`)}`;
24377
+ return `${chalk175.cyan(`#${pr.number}`)} ${pr.title} ${chalk175.dim(`(${pr.author.login},`)} ${status3.label} ${chalk175.dim(`${formatDate(status3.date)})`)}`;
23912
24378
  }
23913
24379
  function logPrDetails(pr) {
23914
24380
  console.log(
23915
- chalk174.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
24381
+ chalk175.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
23916
24382
  );
23917
24383
  console.log();
23918
24384
  }
@@ -24627,10 +25093,10 @@ function registerPrs(program2) {
24627
25093
  }
24628
25094
 
24629
25095
  // src/commands/ravendb/ravendbAuth.ts
24630
- import chalk180 from "chalk";
25096
+ import chalk181 from "chalk";
24631
25097
 
24632
25098
  // src/shared/createConnectionAuth.ts
24633
- import chalk175 from "chalk";
25099
+ import chalk176 from "chalk";
24634
25100
  function listConnections(connections, format) {
24635
25101
  if (connections.length === 0) {
24636
25102
  console.log("No connections configured.");
@@ -24643,7 +25109,7 @@ function listConnections(connections, format) {
24643
25109
  function removeConnection(connections, name, save) {
24644
25110
  const filtered = connections.filter((c) => c.name !== name);
24645
25111
  if (filtered.length === connections.length) {
24646
- console.error(chalk175.red(`Connection "${name}" not found.`));
25112
+ console.error(chalk176.red(`Connection "${name}" not found.`));
24647
25113
  process.exit(1);
24648
25114
  }
24649
25115
  save(filtered);
@@ -24689,15 +25155,15 @@ function saveConnections(connections) {
24689
25155
  }
24690
25156
 
24691
25157
  // src/commands/ravendb/promptConnection.ts
24692
- import chalk178 from "chalk";
25158
+ import chalk179 from "chalk";
24693
25159
 
24694
25160
  // src/commands/ravendb/selectOpSecret.ts
24695
- import chalk177 from "chalk";
25161
+ import chalk178 from "chalk";
24696
25162
  import Enquirer2 from "enquirer";
24697
25163
 
24698
25164
  // src/commands/ravendb/searchItems.ts
24699
25165
  import { execSync as execSync51 } from "child_process";
24700
- import chalk176 from "chalk";
25166
+ import chalk177 from "chalk";
24701
25167
  function opExec(args) {
24702
25168
  return execSync51(`op ${args}`, {
24703
25169
  encoding: "utf8",
@@ -24710,7 +25176,7 @@ function searchItems(search2) {
24710
25176
  items2 = JSON.parse(opExec("item list --format=json"));
24711
25177
  } catch {
24712
25178
  console.error(
24713
- chalk176.red(
25179
+ chalk177.red(
24714
25180
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
24715
25181
  )
24716
25182
  );
@@ -24724,7 +25190,7 @@ function getItemFields(itemId2) {
24724
25190
  const item = JSON.parse(opExec(`item get "${itemId2}" --format=json`));
24725
25191
  return item.fields.filter((f) => f.reference && f.label);
24726
25192
  } catch {
24727
- console.error(chalk176.red("Failed to get item details from 1Password."));
25193
+ console.error(chalk177.red("Failed to get item details from 1Password."));
24728
25194
  process.exit(1);
24729
25195
  }
24730
25196
  }
@@ -24743,7 +25209,7 @@ async function selectOpSecret(searchTerm) {
24743
25209
  }).run();
24744
25210
  const items2 = searchItems(search2);
24745
25211
  if (items2.length === 0) {
24746
- console.error(chalk177.red(`No items found matching "${search2}".`));
25212
+ console.error(chalk178.red(`No items found matching "${search2}".`));
24747
25213
  process.exit(1);
24748
25214
  }
24749
25215
  const itemId2 = await selectOne(
@@ -24752,7 +25218,7 @@ async function selectOpSecret(searchTerm) {
24752
25218
  );
24753
25219
  const fields = getItemFields(itemId2);
24754
25220
  if (fields.length === 0) {
24755
- console.error(chalk177.red("No fields with references found on this item."));
25221
+ console.error(chalk178.red("No fields with references found on this item."));
24756
25222
  process.exit(1);
24757
25223
  }
24758
25224
  const ref = await selectOne(
@@ -24766,7 +25232,7 @@ async function selectOpSecret(searchTerm) {
24766
25232
  async function promptConnection(existingNames) {
24767
25233
  const name = await promptInput("name", "Connection name:");
24768
25234
  if (existingNames.includes(name)) {
24769
- console.error(chalk178.red(`Connection "${name}" already exists.`));
25235
+ console.error(chalk179.red(`Connection "${name}" already exists.`));
24770
25236
  process.exit(1);
24771
25237
  }
24772
25238
  const url = await promptInput(
@@ -24775,22 +25241,22 @@ async function promptConnection(existingNames) {
24775
25241
  );
24776
25242
  const database = await promptInput("database", "Database name:");
24777
25243
  if (!name || !url || !database) {
24778
- console.error(chalk178.red("All fields are required."));
25244
+ console.error(chalk179.red("All fields are required."));
24779
25245
  process.exit(1);
24780
25246
  }
24781
25247
  const apiKeyRef = await selectOpSecret();
24782
- console.log(chalk178.dim(`Using: ${apiKeyRef}`));
25248
+ console.log(chalk179.dim(`Using: ${apiKeyRef}`));
24783
25249
  return { name, url, database, apiKeyRef };
24784
25250
  }
24785
25251
 
24786
25252
  // src/commands/ravendb/ravendbSetConnection.ts
24787
- import chalk179 from "chalk";
25253
+ import chalk180 from "chalk";
24788
25254
  function ravendbSetConnection(name) {
24789
25255
  const raw = loadGlobalConfigRaw();
24790
25256
  const ravendb = raw.ravendb ?? {};
24791
25257
  const connections = ravendb.connections ?? [];
24792
25258
  if (!connections.some((c) => c.name === name)) {
24793
- console.error(chalk179.red(`Connection "${name}" not found.`));
25259
+ console.error(chalk180.red(`Connection "${name}" not found.`));
24794
25260
  console.error(
24795
25261
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
24796
25262
  );
@@ -24806,16 +25272,16 @@ function ravendbSetConnection(name) {
24806
25272
  var ravendbAuth = createConnectionAuth({
24807
25273
  load: loadConnections,
24808
25274
  save: saveConnections,
24809
- format: (c) => `${chalk180.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
25275
+ format: (c) => `${chalk181.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
24810
25276
  promptNew: promptConnection,
24811
25277
  onFirst: (c) => ravendbSetConnection(c.name)
24812
25278
  });
24813
25279
 
24814
25280
  // src/commands/ravendb/ravendbCollections.ts
24815
- import chalk184 from "chalk";
25281
+ import chalk185 from "chalk";
24816
25282
 
24817
25283
  // src/commands/ravendb/ravenFetch.ts
24818
- import chalk182 from "chalk";
25284
+ import chalk183 from "chalk";
24819
25285
 
24820
25286
  // src/commands/ravendb/getAccessToken.ts
24821
25287
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -24852,10 +25318,10 @@ ${errorText}`
24852
25318
 
24853
25319
  // src/commands/ravendb/resolveOpSecret.ts
24854
25320
  import { execSync as execSync52 } from "child_process";
24855
- import chalk181 from "chalk";
25321
+ import chalk182 from "chalk";
24856
25322
  function resolveOpSecret(reference) {
24857
25323
  if (!reference.startsWith("op://")) {
24858
- console.error(chalk181.red(`Invalid secret reference: must start with op://`));
25324
+ console.error(chalk182.red(`Invalid secret reference: must start with op://`));
24859
25325
  process.exit(1);
24860
25326
  }
24861
25327
  try {
@@ -24865,7 +25331,7 @@ function resolveOpSecret(reference) {
24865
25331
  }).trim();
24866
25332
  } catch {
24867
25333
  console.error(
24868
- chalk181.red(
25334
+ chalk182.red(
24869
25335
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
24870
25336
  )
24871
25337
  );
@@ -24892,7 +25358,7 @@ async function ravenFetch(connection, path80) {
24892
25358
  if (!response.ok) {
24893
25359
  const body = await response.text();
24894
25360
  console.error(
24895
- chalk182.red(`RavenDB error: ${response.status} ${response.statusText}`)
25361
+ chalk183.red(`RavenDB error: ${response.status} ${response.statusText}`)
24896
25362
  );
24897
25363
  console.error(body.substring(0, 500));
24898
25364
  process.exit(1);
@@ -24901,7 +25367,7 @@ async function ravenFetch(connection, path80) {
24901
25367
  }
24902
25368
 
24903
25369
  // src/commands/ravendb/resolveConnection.ts
24904
- import chalk183 from "chalk";
25370
+ import chalk184 from "chalk";
24905
25371
  function loadRavendb() {
24906
25372
  const raw = loadGlobalConfigRaw();
24907
25373
  const ravendb = raw.ravendb;
@@ -24915,7 +25381,7 @@ function resolveConnection(name) {
24915
25381
  const connectionName = name ?? defaultConnection;
24916
25382
  if (!connectionName) {
24917
25383
  console.error(
24918
- chalk183.red(
25384
+ chalk184.red(
24919
25385
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
24920
25386
  )
24921
25387
  );
@@ -24923,7 +25389,7 @@ function resolveConnection(name) {
24923
25389
  }
24924
25390
  const connection = connections.find((c) => c.name === connectionName);
24925
25391
  if (!connection) {
24926
- console.error(chalk183.red(`Connection "${connectionName}" not found.`));
25392
+ console.error(chalk184.red(`Connection "${connectionName}" not found.`));
24927
25393
  console.error(
24928
25394
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
24929
25395
  );
@@ -24954,15 +25420,15 @@ async function ravendbCollections(connectionName) {
24954
25420
  return;
24955
25421
  }
24956
25422
  for (const c of collections) {
24957
- console.log(`${chalk184.bold(c.Name)} ${c.CountOfDocuments} docs`);
25423
+ console.log(`${chalk185.bold(c.Name)} ${c.CountOfDocuments} docs`);
24958
25424
  }
24959
25425
  }
24960
25426
 
24961
25427
  // src/commands/ravendb/ravendbQuery.ts
24962
- import chalk186 from "chalk";
25428
+ import chalk187 from "chalk";
24963
25429
 
24964
25430
  // src/commands/ravendb/fetchAllPages.ts
24965
- import chalk185 from "chalk";
25431
+ import chalk186 from "chalk";
24966
25432
 
24967
25433
  // src/commands/ravendb/buildQueryPath.ts
24968
25434
  function buildQueryPath(opts) {
@@ -25000,7 +25466,7 @@ async function fetchAllPages(connection, opts) {
25000
25466
  allResults.push(...results);
25001
25467
  start3 += results.length;
25002
25468
  process.stderr.write(
25003
- `\r${chalk185.dim(`Fetched ${allResults.length}/${totalResults}`)}`
25469
+ `\r${chalk186.dim(`Fetched ${allResults.length}/${totalResults}`)}`
25004
25470
  );
25005
25471
  if (start3 >= totalResults) break;
25006
25472
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -25015,7 +25481,7 @@ async function fetchAllPages(connection, opts) {
25015
25481
  async function ravendbQuery(connectionName, collection, options2) {
25016
25482
  const resolved = resolveArgs(connectionName, collection);
25017
25483
  if (!resolved.collection && !options2.query) {
25018
- console.error(chalk186.red("Provide a collection name or --query filter."));
25484
+ console.error(chalk187.red("Provide a collection name or --query filter."));
25019
25485
  process.exit(1);
25020
25486
  }
25021
25487
  const { collection: col } = resolved;
@@ -25054,7 +25520,7 @@ import { spawn as spawn6 } from "child_process";
25054
25520
  import * as path42 from "path";
25055
25521
 
25056
25522
  // src/commands/refactor/logViolations.ts
25057
- import chalk187 from "chalk";
25523
+ import chalk188 from "chalk";
25058
25524
  var DEFAULT_MAX_LINES2 = 100;
25059
25525
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
25060
25526
  if (violations.length === 0) {
@@ -25063,43 +25529,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
25063
25529
  }
25064
25530
  return;
25065
25531
  }
25066
- console.error(chalk187.red(`
25532
+ console.error(chalk188.red(`
25067
25533
  Refactor check failed:
25068
25534
  `));
25069
- console.error(chalk187.red(` The following files exceed ${maxLines} lines:
25535
+ console.error(chalk188.red(` The following files exceed ${maxLines} lines:
25070
25536
  `));
25071
25537
  for (const violation of violations) {
25072
- console.error(chalk187.red(` ${violation.file} (${violation.lines} lines)`));
25538
+ console.error(chalk188.red(` ${violation.file} (${violation.lines} lines)`));
25073
25539
  }
25074
25540
  console.error(
25075
- chalk187.yellow(
25541
+ chalk188.yellow(
25076
25542
  `
25077
25543
  Each file needs to be sensibly refactored, or if there is no sensible
25078
25544
  way to refactor it, ignore it with:
25079
25545
  `
25080
25546
  )
25081
25547
  );
25082
- console.error(chalk187.gray(` assist refactor ignore <file>
25548
+ console.error(chalk188.gray(` assist refactor ignore <file>
25083
25549
  `));
25084
25550
  if (process.env.CLAUDECODE) {
25085
- console.error(chalk187.cyan(`
25551
+ console.error(chalk188.cyan(`
25086
25552
  ## Extracting Code to New Files
25087
25553
  `));
25088
25554
  console.error(
25089
- chalk187.cyan(
25555
+ chalk188.cyan(
25090
25556
  ` When extracting logic from one file to another, consider where the extracted code belongs:
25091
25557
  `
25092
25558
  )
25093
25559
  );
25094
25560
  console.error(
25095
- chalk187.cyan(
25561
+ chalk188.cyan(
25096
25562
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
25097
25563
  original file's domain, create a new folder containing both the original and extracted files.
25098
25564
  `
25099
25565
  )
25100
25566
  );
25101
25567
  console.error(
25102
- chalk187.cyan(
25568
+ chalk188.cyan(
25103
25569
  ` 2. Share common utilities: If the extracted code can be reused across multiple
25104
25570
  domains, move it to a common/shared folder.
25105
25571
  `
@@ -25255,7 +25721,7 @@ async function check(pattern2, options2) {
25255
25721
 
25256
25722
  // src/commands/refactor/extract/index.ts
25257
25723
  import path50 from "path";
25258
- import chalk190 from "chalk";
25724
+ import chalk191 from "chalk";
25259
25725
 
25260
25726
  // src/commands/refactor/extract/applyExtraction.ts
25261
25727
  import { SyntaxKind as SyntaxKind4 } from "ts-morph";
@@ -25854,23 +26320,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
25854
26320
 
25855
26321
  // src/commands/refactor/extract/displayPlan.ts
25856
26322
  import path46 from "path";
25857
- import chalk188 from "chalk";
26323
+ import chalk189 from "chalk";
25858
26324
  function section2(title) {
25859
26325
  return `
25860
- ${chalk188.cyan(title)}`;
26326
+ ${chalk189.cyan(title)}`;
25861
26327
  }
25862
26328
  function displayImporters(plan2, cwd) {
25863
26329
  if (plan2.importersToUpdate.length === 0) return;
25864
26330
  console.log(section2("Update importers:"));
25865
26331
  for (const imp of plan2.importersToUpdate) {
25866
26332
  const rel = path46.relative(cwd, imp.file.getFilePath());
25867
- console.log(` ${chalk188.dim(rel)}: \u2192 import from "${imp.relPath}"`);
26333
+ console.log(` ${chalk189.dim(rel)}: \u2192 import from "${imp.relPath}"`);
25868
26334
  }
25869
26335
  }
25870
26336
  function displayPlan(functionName, relDest, plan2, cwd) {
25871
- console.log(chalk188.bold(`Extract: ${functionName} \u2192 ${relDest}
26337
+ console.log(chalk189.bold(`Extract: ${functionName} \u2192 ${relDest}
25872
26338
  `));
25873
- console.log(` ${chalk188.cyan("Functions to move:")}`);
26339
+ console.log(` ${chalk189.cyan("Functions to move:")}`);
25874
26340
  for (const name of plan2.extractedNames) {
25875
26341
  console.log(` ${name}`);
25876
26342
  }
@@ -25904,7 +26370,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
25904
26370
 
25905
26371
  // src/commands/refactor/extract/loadProjectFile.ts
25906
26372
  import path49 from "path";
25907
- import chalk189 from "chalk";
26373
+ import chalk190 from "chalk";
25908
26374
  import { Project as Project4 } from "ts-morph";
25909
26375
 
25910
26376
  // src/commands/refactor/extract/findTsConfig.ts
@@ -25996,7 +26462,7 @@ function loadProjectFile(file) {
25996
26462
  });
25997
26463
  const sourceFile = project.getSourceFile(sourcePath);
25998
26464
  if (!sourceFile) {
25999
- console.log(chalk189.red(`File not found in project: ${file}`));
26465
+ console.log(chalk190.red(`File not found in project: ${file}`));
26000
26466
  process.exit(1);
26001
26467
  }
26002
26468
  return { project, sourceFile };
@@ -26019,19 +26485,19 @@ async function extract(file, functionName, destination, options2 = {}) {
26019
26485
  displayPlan(functionName, relDest, plan2, cwd);
26020
26486
  if (options2.apply) {
26021
26487
  await applyExtraction(functionName, sourceFile, destPath, plan2, project);
26022
- console.log(chalk190.green("\nExtraction complete"));
26488
+ console.log(chalk191.green("\nExtraction complete"));
26023
26489
  } else {
26024
- console.log(chalk190.dim("\nDry run. Use --apply to execute."));
26490
+ console.log(chalk191.dim("\nDry run. Use --apply to execute."));
26025
26491
  }
26026
26492
  }
26027
26493
 
26028
26494
  // src/commands/refactor/ignore.ts
26029
26495
  import fs33 from "fs";
26030
- import chalk191 from "chalk";
26496
+ import chalk192 from "chalk";
26031
26497
  var REFACTOR_YML_PATH2 = "refactor.yml";
26032
26498
  function ignore2(file) {
26033
26499
  if (!fs33.existsSync(file)) {
26034
- console.error(chalk191.red(`Error: File does not exist: ${file}`));
26500
+ console.error(chalk192.red(`Error: File does not exist: ${file}`));
26035
26501
  process.exit(1);
26036
26502
  }
26037
26503
  const content = fs33.readFileSync(file, "utf8");
@@ -26047,7 +26513,7 @@ function ignore2(file) {
26047
26513
  fs33.writeFileSync(REFACTOR_YML_PATH2, entry);
26048
26514
  }
26049
26515
  console.log(
26050
- chalk191.green(
26516
+ chalk192.green(
26051
26517
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
26052
26518
  )
26053
26519
  );
@@ -26056,12 +26522,12 @@ function ignore2(file) {
26056
26522
  // src/commands/refactor/rename/index.ts
26057
26523
  import fs36 from "fs";
26058
26524
  import path55 from "path";
26059
- import chalk194 from "chalk";
26525
+ import chalk195 from "chalk";
26060
26526
 
26061
26527
  // src/commands/refactor/rename/applyRename.ts
26062
26528
  import fs35 from "fs";
26063
26529
  import path52 from "path";
26064
- import chalk192 from "chalk";
26530
+ import chalk193 from "chalk";
26065
26531
 
26066
26532
  // src/commands/refactor/restructure/computeRewrites/index.ts
26067
26533
  import path51 from "path";
@@ -26166,13 +26632,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
26166
26632
  const updatedContents = applyRewrites(rewrites);
26167
26633
  for (const [file, content] of updatedContents) {
26168
26634
  fs35.writeFileSync(file, content, "utf8");
26169
- console.log(chalk192.cyan(` Updated imports in ${path52.relative(cwd, file)}`));
26635
+ console.log(chalk193.cyan(` Updated imports in ${path52.relative(cwd, file)}`));
26170
26636
  }
26171
26637
  const destDir = path52.dirname(destPath);
26172
26638
  if (!fs35.existsSync(destDir)) fs35.mkdirSync(destDir, { recursive: true });
26173
26639
  fs35.renameSync(sourcePath, destPath);
26174
26640
  console.log(
26175
- chalk192.white(
26641
+ chalk193.white(
26176
26642
  ` Moved ${path52.relative(cwd, sourcePath)} \u2192 ${path52.relative(cwd, destPath)}`
26177
26643
  )
26178
26644
  );
@@ -26259,16 +26725,16 @@ function computeRenameRewrites(sourcePath, destPath) {
26259
26725
 
26260
26726
  // src/commands/refactor/rename/printRenamePreview.ts
26261
26727
  import path54 from "path";
26262
- import chalk193 from "chalk";
26728
+ import chalk194 from "chalk";
26263
26729
  function printRenamePreview(rewrites, cwd) {
26264
26730
  for (const rewrite of rewrites) {
26265
26731
  console.log(
26266
- chalk193.dim(
26732
+ chalk194.dim(
26267
26733
  ` ${path54.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
26268
26734
  )
26269
26735
  );
26270
26736
  }
26271
- console.log(chalk193.dim("Dry run. Use --apply to execute."));
26737
+ console.log(chalk194.dim("Dry run. Use --apply to execute."));
26272
26738
  }
26273
26739
 
26274
26740
  // src/commands/refactor/rename/index.ts
@@ -26279,20 +26745,20 @@ async function rename(source, destination, options2 = {}) {
26279
26745
  const relSource = path55.relative(cwd, sourcePath);
26280
26746
  const relDest = path55.relative(cwd, destPath);
26281
26747
  if (!fs36.existsSync(sourcePath)) {
26282
- console.log(chalk194.red(`File not found: ${source}`));
26748
+ console.log(chalk195.red(`File not found: ${source}`));
26283
26749
  process.exit(1);
26284
26750
  }
26285
26751
  if (destPath !== sourcePath && fs36.existsSync(destPath)) {
26286
- console.log(chalk194.red(`Destination already exists: ${destination}`));
26752
+ console.log(chalk195.red(`Destination already exists: ${destination}`));
26287
26753
  process.exit(1);
26288
26754
  }
26289
- console.log(chalk194.bold(`Rename: ${relSource} \u2192 ${relDest}`));
26290
- console.log(chalk194.dim("Loading project..."));
26291
- console.log(chalk194.dim("Scanning imports across the project..."));
26755
+ console.log(chalk195.bold(`Rename: ${relSource} \u2192 ${relDest}`));
26756
+ console.log(chalk195.dim("Loading project..."));
26757
+ console.log(chalk195.dim("Scanning imports across the project..."));
26292
26758
  const rewrites = computeRenameRewrites(sourcePath, destPath);
26293
26759
  const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
26294
26760
  console.log(
26295
- chalk194.dim(
26761
+ chalk195.dim(
26296
26762
  `${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
26297
26763
  )
26298
26764
  );
@@ -26301,11 +26767,11 @@ async function rename(source, destination, options2 = {}) {
26301
26767
  return;
26302
26768
  }
26303
26769
  applyRename(rewrites, sourcePath, destPath, cwd);
26304
- console.log(chalk194.green("Done"));
26770
+ console.log(chalk195.green("Done"));
26305
26771
  }
26306
26772
 
26307
26773
  // src/commands/refactor/renameSymbol/index.ts
26308
- import chalk195 from "chalk";
26774
+ import chalk196 from "chalk";
26309
26775
 
26310
26776
  // src/commands/refactor/renameSymbol/findSymbol.ts
26311
26777
  import { SyntaxKind as SyntaxKind15 } from "ts-morph";
@@ -26351,33 +26817,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
26351
26817
  const { project, sourceFile } = loadProjectFile(file);
26352
26818
  const symbol = findSymbol(sourceFile, oldName);
26353
26819
  if (!symbol) {
26354
- console.log(chalk195.red(`Symbol "${oldName}" not found in ${file}`));
26820
+ console.log(chalk196.red(`Symbol "${oldName}" not found in ${file}`));
26355
26821
  process.exit(1);
26356
26822
  }
26357
26823
  const grouped = groupReferences(symbol, cwd);
26358
26824
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
26359
26825
  console.log(
26360
- chalk195.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
26826
+ chalk196.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
26361
26827
  `)
26362
26828
  );
26363
26829
  for (const [refFile, lines2] of grouped) {
26364
26830
  console.log(
26365
- ` ${chalk195.dim(refFile)}: lines ${chalk195.cyan(lines2.join(", "))}`
26831
+ ` ${chalk196.dim(refFile)}: lines ${chalk196.cyan(lines2.join(", "))}`
26366
26832
  );
26367
26833
  }
26368
26834
  if (options2.apply) {
26369
26835
  symbol.rename(newName);
26370
26836
  await project.save();
26371
- console.log(chalk195.green(`
26837
+ console.log(chalk196.green(`
26372
26838
  Renamed ${oldName} \u2192 ${newName}`));
26373
26839
  } else {
26374
- console.log(chalk195.dim("\nDry run. Use --apply to execute."));
26840
+ console.log(chalk196.dim("\nDry run. Use --apply to execute."));
26375
26841
  }
26376
26842
  }
26377
26843
 
26378
26844
  // src/commands/refactor/restructure/index.ts
26379
26845
  import path63 from "path";
26380
- import chalk198 from "chalk";
26846
+ import chalk199 from "chalk";
26381
26847
 
26382
26848
  // src/commands/refactor/restructure/clusterDirectories.ts
26383
26849
  import path57 from "path";
@@ -26456,50 +26922,50 @@ function clusterFiles(graph) {
26456
26922
 
26457
26923
  // src/commands/refactor/restructure/displayPlan.ts
26458
26924
  import path59 from "path";
26459
- import chalk196 from "chalk";
26925
+ import chalk197 from "chalk";
26460
26926
  function relPath(filePath) {
26461
26927
  return path59.relative(process.cwd(), filePath);
26462
26928
  }
26463
26929
  function displayMoves(plan2) {
26464
26930
  if (plan2.moves.length === 0) return;
26465
- console.log(chalk196.bold("\nFile moves:"));
26931
+ console.log(chalk197.bold("\nFile moves:"));
26466
26932
  for (const move2 of plan2.moves) {
26467
26933
  console.log(
26468
- ` ${chalk196.red(relPath(move2.from))} \u2192 ${chalk196.green(relPath(move2.to))}`
26934
+ ` ${chalk197.red(relPath(move2.from))} \u2192 ${chalk197.green(relPath(move2.to))}`
26469
26935
  );
26470
- console.log(chalk196.dim(` ${move2.reason}`));
26936
+ console.log(chalk197.dim(` ${move2.reason}`));
26471
26937
  }
26472
26938
  }
26473
26939
  function displayRewrites(rewrites) {
26474
26940
  if (rewrites.length === 0) return;
26475
26941
  const affectedFiles = new Set(rewrites.map((r) => r.file));
26476
- console.log(chalk196.bold(`
26942
+ console.log(chalk197.bold(`
26477
26943
  Import rewrites (${affectedFiles.size} files):`));
26478
26944
  for (const file of affectedFiles) {
26479
- console.log(` ${chalk196.cyan(relPath(file))}:`);
26945
+ console.log(` ${chalk197.cyan(relPath(file))}:`);
26480
26946
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
26481
26947
  (r) => r.file === file
26482
26948
  )) {
26483
26949
  console.log(
26484
- ` ${chalk196.red(`"${oldSpecifier}"`)} \u2192 ${chalk196.green(`"${newSpecifier}"`)}`
26950
+ ` ${chalk197.red(`"${oldSpecifier}"`)} \u2192 ${chalk197.green(`"${newSpecifier}"`)}`
26485
26951
  );
26486
26952
  }
26487
26953
  }
26488
26954
  }
26489
26955
  function displayPlan2(plan2) {
26490
26956
  if (plan2.warnings.length > 0) {
26491
- console.log(chalk196.yellow("\nWarnings:"));
26492
- for (const w of plan2.warnings) console.log(chalk196.yellow(` ${w}`));
26957
+ console.log(chalk197.yellow("\nWarnings:"));
26958
+ for (const w of plan2.warnings) console.log(chalk197.yellow(` ${w}`));
26493
26959
  }
26494
26960
  if (plan2.newDirectories.length > 0) {
26495
- console.log(chalk196.bold("\nNew directories:"));
26961
+ console.log(chalk197.bold("\nNew directories:"));
26496
26962
  for (const dir of plan2.newDirectories)
26497
- console.log(chalk196.green(` ${dir}/`));
26963
+ console.log(chalk197.green(` ${dir}/`));
26498
26964
  }
26499
26965
  displayMoves(plan2);
26500
26966
  displayRewrites(plan2.rewrites);
26501
26967
  console.log(
26502
- chalk196.dim(
26968
+ chalk197.dim(
26503
26969
  `
26504
26970
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
26505
26971
  )
@@ -26509,18 +26975,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
26509
26975
  // src/commands/refactor/restructure/executePlan.ts
26510
26976
  import fs37 from "fs";
26511
26977
  import path60 from "path";
26512
- import chalk197 from "chalk";
26978
+ import chalk198 from "chalk";
26513
26979
  function executePlan(plan2) {
26514
26980
  const updatedContents = applyRewrites(plan2.rewrites);
26515
26981
  for (const [file, content] of updatedContents) {
26516
26982
  fs37.writeFileSync(file, content, "utf8");
26517
26983
  console.log(
26518
- chalk197.cyan(` Rewrote imports in ${path60.relative(process.cwd(), file)}`)
26984
+ chalk198.cyan(` Rewrote imports in ${path60.relative(process.cwd(), file)}`)
26519
26985
  );
26520
26986
  }
26521
26987
  for (const dir of plan2.newDirectories) {
26522
26988
  fs37.mkdirSync(dir, { recursive: true });
26523
- console.log(chalk197.green(` Created ${path60.relative(process.cwd(), dir)}/`));
26989
+ console.log(chalk198.green(` Created ${path60.relative(process.cwd(), dir)}/`));
26524
26990
  }
26525
26991
  for (const move2 of plan2.moves) {
26526
26992
  const targetDir = path60.dirname(move2.to);
@@ -26529,7 +26995,7 @@ function executePlan(plan2) {
26529
26995
  }
26530
26996
  fs37.renameSync(move2.from, move2.to);
26531
26997
  console.log(
26532
- chalk197.white(
26998
+ chalk198.white(
26533
26999
  ` Moved ${path60.relative(process.cwd(), move2.from)} \u2192 ${path60.relative(process.cwd(), move2.to)}`
26534
27000
  )
26535
27001
  );
@@ -26544,7 +27010,7 @@ function removeEmptyDirectories(dirs) {
26544
27010
  if (entries.length === 0) {
26545
27011
  fs37.rmdirSync(dir);
26546
27012
  console.log(
26547
- chalk197.dim(
27013
+ chalk198.dim(
26548
27014
  ` Removed empty directory ${path60.relative(process.cwd(), dir)}`
26549
27015
  )
26550
27016
  );
@@ -26677,22 +27143,22 @@ async function restructure(pattern2, options2 = {}) {
26677
27143
  const targetPattern = pattern2 ?? "src";
26678
27144
  const files = findSourceFiles2(targetPattern);
26679
27145
  if (files.length === 0) {
26680
- console.log(chalk198.yellow("No files found matching pattern"));
27146
+ console.log(chalk199.yellow("No files found matching pattern"));
26681
27147
  return;
26682
27148
  }
26683
27149
  const tsConfigPath = findTsConfig(path63.resolve(files[0]));
26684
27150
  const plan2 = buildPlan3(files, tsConfigPath);
26685
27151
  if (plan2.moves.length === 0) {
26686
- console.log(chalk198.green("No restructuring needed"));
27152
+ console.log(chalk199.green("No restructuring needed"));
26687
27153
  return;
26688
27154
  }
26689
27155
  displayPlan2(plan2);
26690
27156
  if (options2.apply) {
26691
- console.log(chalk198.bold("\nApplying changes..."));
27157
+ console.log(chalk199.bold("\nApplying changes..."));
26692
27158
  executePlan(plan2);
26693
- console.log(chalk198.green("\nRestructuring complete"));
27159
+ console.log(chalk199.green("\nRestructuring complete"));
26694
27160
  } else {
26695
- console.log(chalk198.dim("\nDry run. Use --apply to execute."));
27161
+ console.log(chalk199.dim("\nDry run. Use --apply to execute."));
26696
27162
  }
26697
27163
  }
26698
27164
 
@@ -27015,7 +27481,7 @@ function gatherContext() {
27015
27481
  }
27016
27482
 
27017
27483
  // src/commands/review/postReviewToPr.ts
27018
- import { readFileSync as readFileSync41 } from "fs";
27484
+ import { readFileSync as readFileSync42 } from "fs";
27019
27485
 
27020
27486
  // src/commands/review/carriedUnanchoredFindings.ts
27021
27487
  function carriedUnanchoredFindings(unanchored) {
@@ -27350,18 +27816,18 @@ function partitionFindingsByDiff(findings, index3) {
27350
27816
  }
27351
27817
 
27352
27818
  // src/commands/review/warnOutOfDiff.ts
27353
- import chalk199 from "chalk";
27819
+ import chalk200 from "chalk";
27354
27820
  function warnOutOfDiff(outOfDiff) {
27355
27821
  if (outOfDiff.length === 0) return;
27356
27822
  console.warn(
27357
- chalk199.yellow(
27823
+ chalk200.yellow(
27358
27824
  `Moved ${outOfDiff.length} finding(s) whose lines fall outside the PR diff into the review body (GitHub cannot anchor a comment on these):`
27359
27825
  )
27360
27826
  );
27361
27827
  for (const finding of outOfDiff) {
27362
27828
  const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
27363
27829
  console.warn(
27364
- ` ${chalk199.yellow("\xB7")} ${finding.title} ${chalk199.dim(
27830
+ ` ${chalk200.yellow("\xB7")} ${finding.title} ${chalk200.dim(
27365
27831
  `(${finding.file}:${range})`
27366
27832
  )}`
27367
27833
  );
@@ -27385,18 +27851,18 @@ function selectInDiffFindings(lineBound, prDiff) {
27385
27851
  }
27386
27852
 
27387
27853
  // src/commands/review/warnUnlocated.ts
27388
- import chalk200 from "chalk";
27854
+ import chalk201 from "chalk";
27389
27855
  function warnUnlocated(unlocated) {
27390
27856
  if (unlocated.length === 0) return;
27391
27857
  console.warn(
27392
- chalk200.yellow(
27858
+ chalk201.yellow(
27393
27859
  `Moved ${unlocated.length} finding(s) without a parseable file:line into the review body:`
27394
27860
  )
27395
27861
  );
27396
27862
  for (const finding of unlocated) {
27397
- const where = finding.location || chalk200.dim("missing");
27863
+ const where = finding.location || chalk201.dim("missing");
27398
27864
  console.warn(
27399
- ` ${chalk200.yellow("\xB7")} ${finding.title} ${chalk200.dim(`(${where})`)}`
27865
+ ` ${chalk201.yellow("\xB7")} ${finding.title} ${chalk201.dim(`(${where})`)}`
27400
27866
  );
27401
27867
  }
27402
27868
  }
@@ -27463,7 +27929,7 @@ async function confirmPost(prNumber, work, options2) {
27463
27929
  return promptConfirm(`Post ${work} to PR #${prNumber}?`, false);
27464
27930
  }
27465
27931
  async function postFindingsToPr(prInfo, synthesisPath, options2) {
27466
- const markdown = readFileSync41(synthesisPath, "utf8");
27932
+ const markdown = readFileSync42(synthesisPath, "utf8");
27467
27933
  const { inDiff, unanchored } = selectPostableFindings(markdown, prInfo);
27468
27934
  const carried = carriedUnanchoredFindings(unanchored);
27469
27935
  if (inDiff.length === 0 && carried.length === 0) return NOTHING_POSTED;
@@ -27599,10 +28065,10 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
27599
28065
  }
27600
28066
 
27601
28067
  // src/commands/review/prepareReviewDir.ts
27602
- import { existsSync as existsSync54, mkdirSync as mkdirSync20, unlinkSync as unlinkSync17, writeFileSync as writeFileSync37 } from "fs";
28068
+ import { existsSync as existsSync55, mkdirSync as mkdirSync20, unlinkSync as unlinkSync17, writeFileSync as writeFileSync37 } from "fs";
27603
28069
  function clearReviewFiles(paths) {
27604
28070
  for (const path80 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
27605
- if (existsSync54(path80)) unlinkSync17(path80);
28071
+ if (existsSync55(path80)) unlinkSync17(path80);
27606
28072
  }
27607
28073
  }
27608
28074
  function prepareReviewDir(paths, requestBody, force) {
@@ -27728,9 +28194,9 @@ var MultiSpinner = class {
27728
28194
  };
27729
28195
 
27730
28196
  // src/commands/review/ensureCodexAvailable.ts
27731
- import { spawnSync as spawnSync6 } from "child_process";
28197
+ import { spawnSync as spawnSync7 } from "child_process";
27732
28198
  function runNpmInstall() {
27733
- const result = spawnSync6("npm", ["install", "-g", "@openai/codex"], {
28199
+ const result = spawnSync7("npm", ["install", "-g", "@openai/codex"], {
27734
28200
  stdio: "inherit",
27735
28201
  shell: true
27736
28202
  });
@@ -27829,7 +28295,7 @@ function printReviewerFailures(results) {
27829
28295
  }
27830
28296
 
27831
28297
  // src/commands/review/runAndSynthesise.ts
27832
- import { existsSync as existsSync56, unlinkSync as unlinkSync19 } from "fs";
28298
+ import { existsSync as existsSync57, unlinkSync as unlinkSync19 } from "fs";
27833
28299
 
27834
28300
  // src/commands/review/buildReviewerStdin.ts
27835
28301
  var REVIEW_PROMPT = `You are acting as a reviewer for a proposed code change made by another engineer. The full review request \u2014 branch, base, changed files, and unified diff \u2014 is in the request file whose absolute path is given below.
@@ -28258,7 +28724,7 @@ function resolveClaude(args) {
28258
28724
  }
28259
28725
 
28260
28726
  // src/commands/review/runCodexReviewer.ts
28261
- import { existsSync as existsSync55, unlinkSync as unlinkSync18 } from "fs";
28727
+ import { existsSync as existsSync56, unlinkSync as unlinkSync18 } from "fs";
28262
28728
 
28263
28729
  // src/commands/review/parseCodexEvent.ts
28264
28730
  function isItemStarted(value) {
@@ -28310,7 +28776,7 @@ async function runCodexReviewer(spec) {
28310
28776
  reportReviewerToolUse(spec.name, event, spinner);
28311
28777
  }
28312
28778
  });
28313
- if (result.exitCode !== 0 && existsSync55(spec.outputPath)) {
28779
+ if (result.exitCode !== 0 && existsSync56(spec.outputPath)) {
28314
28780
  unlinkSync18(spec.outputPath);
28315
28781
  }
28316
28782
  return finaliseReviewerRun({ ...spec, command }, spinner, result);
@@ -28352,7 +28818,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
28352
28818
  }
28353
28819
 
28354
28820
  // src/commands/review/synthesise.ts
28355
- import { readFileSync as readFileSync42 } from "fs";
28821
+ import { readFileSync as readFileSync43 } from "fs";
28356
28822
 
28357
28823
  // src/commands/review/buildSynthesisStdin.ts
28358
28824
  var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
@@ -28417,7 +28883,7 @@ Files:
28417
28883
 
28418
28884
  // src/commands/review/synthesise.ts
28419
28885
  function printSummary2(synthesisPath) {
28420
- const markdown = readFileSync42(synthesisPath, "utf8");
28886
+ const markdown = readFileSync43(synthesisPath, "utf8");
28421
28887
  console.log("");
28422
28888
  console.log(buildReviewSummary(markdown));
28423
28889
  console.log("");
@@ -28465,7 +28931,7 @@ async function runAndSynthesise(args) {
28465
28931
  console.error("Both reviewers failed; skipping synthesis.");
28466
28932
  return { ok: false, failures };
28467
28933
  }
28468
- if (anyFresh && existsSync56(paths.synthesisPath)) {
28934
+ if (anyFresh && existsSync57(paths.synthesisPath)) {
28469
28935
  unlinkSync19(paths.synthesisPath);
28470
28936
  }
28471
28937
  const synthesisResult = await synthesise(paths, { multi });
@@ -28651,7 +29117,7 @@ function registerReview(program2) {
28651
29117
  }
28652
29118
 
28653
29119
  // src/commands/seq/seqAuth.ts
28654
- import chalk202 from "chalk";
29120
+ import chalk203 from "chalk";
28655
29121
 
28656
29122
  // src/commands/seq/loadConnections.ts
28657
29123
  function loadConnections2() {
@@ -28680,10 +29146,10 @@ function setDefaultConnection(name) {
28680
29146
  }
28681
29147
 
28682
29148
  // src/shared/assertUniqueName.ts
28683
- import chalk201 from "chalk";
29149
+ import chalk202 from "chalk";
28684
29150
  function assertUniqueName(existingNames, name) {
28685
29151
  if (existingNames.includes(name)) {
28686
- console.error(chalk201.red(`Connection "${name}" already exists.`));
29152
+ console.error(chalk202.red(`Connection "${name}" already exists.`));
28687
29153
  process.exit(1);
28688
29154
  }
28689
29155
  }
@@ -28701,16 +29167,16 @@ async function promptConnection2(existingNames) {
28701
29167
  var seqAuth = createConnectionAuth({
28702
29168
  load: loadConnections2,
28703
29169
  save: saveConnections2,
28704
- format: (c) => `${chalk202.bold(c.name)} ${c.url}`,
29170
+ format: (c) => `${chalk203.bold(c.name)} ${c.url}`,
28705
29171
  promptNew: promptConnection2,
28706
29172
  onFirst: (c) => setDefaultConnection(c.name)
28707
29173
  });
28708
29174
 
28709
29175
  // src/commands/seq/seqQuery.ts
28710
- import chalk206 from "chalk";
29176
+ import chalk207 from "chalk";
28711
29177
 
28712
29178
  // src/commands/seq/fetchSeq.ts
28713
- import chalk203 from "chalk";
29179
+ import chalk204 from "chalk";
28714
29180
  async function fetchSeq(conn, path80, params) {
28715
29181
  const url = `${conn.url}${path80}?${params}`;
28716
29182
  const response = await fetch(url, {
@@ -28721,7 +29187,7 @@ async function fetchSeq(conn, path80, params) {
28721
29187
  });
28722
29188
  if (!response.ok) {
28723
29189
  const body = await response.text();
28724
- console.error(chalk203.red(`Seq returned ${response.status}: ${body}`));
29190
+ console.error(chalk204.red(`Seq returned ${response.status}: ${body}`));
28725
29191
  process.exit(1);
28726
29192
  }
28727
29193
  return response;
@@ -28780,23 +29246,23 @@ async function fetchSeqEvents(conn, params) {
28780
29246
  }
28781
29247
 
28782
29248
  // src/commands/seq/formatEvent.ts
28783
- import chalk204 from "chalk";
29249
+ import chalk205 from "chalk";
28784
29250
  function levelColor(level) {
28785
29251
  switch (level) {
28786
29252
  case "Fatal":
28787
- return chalk204.bgRed.white;
29253
+ return chalk205.bgRed.white;
28788
29254
  case "Error":
28789
- return chalk204.red;
29255
+ return chalk205.red;
28790
29256
  case "Warning":
28791
- return chalk204.yellow;
29257
+ return chalk205.yellow;
28792
29258
  case "Information":
28793
- return chalk204.cyan;
29259
+ return chalk205.cyan;
28794
29260
  case "Debug":
28795
- return chalk204.gray;
29261
+ return chalk205.gray;
28796
29262
  case "Verbose":
28797
- return chalk204.dim;
29263
+ return chalk205.dim;
28798
29264
  default:
28799
- return chalk204.white;
29265
+ return chalk205.white;
28800
29266
  }
28801
29267
  }
28802
29268
  function levelAbbrev(level) {
@@ -28837,12 +29303,12 @@ function formatTimestamp(iso) {
28837
29303
  function formatEvent(event) {
28838
29304
  const color = levelColor(event.Level);
28839
29305
  const abbrev = levelAbbrev(event.Level);
28840
- const ts8 = chalk204.dim(formatTimestamp(event.Timestamp));
29306
+ const ts8 = chalk205.dim(formatTimestamp(event.Timestamp));
28841
29307
  const msg = renderMessage(event);
28842
29308
  const lines2 = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
28843
29309
  if (event.Exception) {
28844
29310
  for (const line of event.Exception.split("\n")) {
28845
- lines2.push(chalk204.red(` ${line}`));
29311
+ lines2.push(chalk205.red(` ${line}`));
28846
29312
  }
28847
29313
  }
28848
29314
  return lines2.join("\n");
@@ -28875,11 +29341,11 @@ function rejectTimestampFilter(filter) {
28875
29341
  }
28876
29342
 
28877
29343
  // src/shared/resolveNamedConnection.ts
28878
- import chalk205 from "chalk";
29344
+ import chalk206 from "chalk";
28879
29345
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
28880
29346
  if (connections.length === 0) {
28881
29347
  console.error(
28882
- chalk205.red(
29348
+ chalk206.red(
28883
29349
  `No ${kind} connections configured. Run '${authCommand}' first.`
28884
29350
  )
28885
29351
  );
@@ -28888,7 +29354,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
28888
29354
  const target = requested ?? defaultName ?? connections[0].name;
28889
29355
  const connection = connections.find((c) => c.name === target);
28890
29356
  if (!connection) {
28891
- console.error(chalk205.red(`${kind} connection "${target}" not found.`));
29357
+ console.error(chalk206.red(`${kind} connection "${target}" not found.`));
28892
29358
  process.exit(1);
28893
29359
  }
28894
29360
  return connection;
@@ -28917,7 +29383,7 @@ async function seqQuery(filter, options2) {
28917
29383
  new URLSearchParams({ filter, count: String(count8) })
28918
29384
  );
28919
29385
  if (events.length === 0) {
28920
- console.log(chalk206.yellow("No events found."));
29386
+ console.log(chalk207.yellow("No events found."));
28921
29387
  return;
28922
29388
  }
28923
29389
  if (options2.json) {
@@ -28928,11 +29394,11 @@ async function seqQuery(filter, options2) {
28928
29394
  for (const event of chronological) {
28929
29395
  console.log(formatEvent(event));
28930
29396
  }
28931
- console.log(chalk206.dim(`
29397
+ console.log(chalk207.dim(`
28932
29398
  ${events.length} events`));
28933
29399
  if (events.length >= count8) {
28934
29400
  console.log(
28935
- chalk206.yellow(
29401
+ chalk207.yellow(
28936
29402
  `Results limited to ${count8}. Use --count to retrieve more.`
28937
29403
  )
28938
29404
  );
@@ -28940,10 +29406,10 @@ ${events.length} events`));
28940
29406
  }
28941
29407
 
28942
29408
  // src/shared/setNamedDefaultConnection.ts
28943
- import chalk207 from "chalk";
29409
+ import chalk208 from "chalk";
28944
29410
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
28945
29411
  if (!connections.find((c) => c.name === name)) {
28946
- console.error(chalk207.red(`Connection "${name}" not found.`));
29412
+ console.error(chalk208.red(`Connection "${name}" not found.`));
28947
29413
  process.exit(1);
28948
29414
  }
28949
29415
  setDefault(name);
@@ -28992,7 +29458,7 @@ function registerSignal(program2) {
28992
29458
  }
28993
29459
 
28994
29460
  // src/commands/sql/sqlAuth.ts
28995
- import chalk209 from "chalk";
29461
+ import chalk210 from "chalk";
28996
29462
 
28997
29463
  // src/commands/sql/loadConnections.ts
28998
29464
  function loadConnections3() {
@@ -29021,7 +29487,7 @@ function setDefaultConnection2(name) {
29021
29487
  }
29022
29488
 
29023
29489
  // src/commands/sql/promptConnection.ts
29024
- import chalk208 from "chalk";
29490
+ import chalk209 from "chalk";
29025
29491
  async function promptConnection3(existingNames) {
29026
29492
  const name = await promptInput("name", "Connection name:", "default");
29027
29493
  assertUniqueName(existingNames, name);
@@ -29029,7 +29495,7 @@ async function promptConnection3(existingNames) {
29029
29495
  const portStr = await promptInput("port", "Port:", "1433");
29030
29496
  const port = Number.parseInt(portStr, 10);
29031
29497
  if (!Number.isFinite(port)) {
29032
- console.error(chalk208.red(`Invalid port "${portStr}".`));
29498
+ console.error(chalk209.red(`Invalid port "${portStr}".`));
29033
29499
  process.exit(1);
29034
29500
  }
29035
29501
  const user = await promptInput("user", "User:");
@@ -29042,13 +29508,13 @@ async function promptConnection3(existingNames) {
29042
29508
  var sqlAuth = createConnectionAuth({
29043
29509
  load: loadConnections3,
29044
29510
  save: saveConnections3,
29045
- format: (c) => `${chalk209.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
29511
+ format: (c) => `${chalk210.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
29046
29512
  promptNew: promptConnection3,
29047
29513
  onFirst: (c) => setDefaultConnection2(c.name)
29048
29514
  });
29049
29515
 
29050
29516
  // src/commands/sql/printTable.ts
29051
- import chalk210 from "chalk";
29517
+ import chalk211 from "chalk";
29052
29518
  function formatCell(value) {
29053
29519
  if (value === null || value === void 0) return "";
29054
29520
  if (value instanceof Date) return value.toISOString();
@@ -29057,7 +29523,7 @@ function formatCell(value) {
29057
29523
  }
29058
29524
  function printTable(rows) {
29059
29525
  if (rows.length === 0) {
29060
- console.log(chalk210.yellow("(no rows)"));
29526
+ console.log(chalk211.yellow("(no rows)"));
29061
29527
  return;
29062
29528
  }
29063
29529
  const columns = Object.keys(rows[0]);
@@ -29065,13 +29531,13 @@ function printTable(rows) {
29065
29531
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
29066
29532
  );
29067
29533
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
29068
- console.log(chalk210.dim(header));
29069
- console.log(chalk210.dim("-".repeat(header.length)));
29534
+ console.log(chalk211.dim(header));
29535
+ console.log(chalk211.dim("-".repeat(header.length)));
29070
29536
  for (const row of rows) {
29071
29537
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
29072
29538
  console.log(line);
29073
29539
  }
29074
- console.log(chalk210.dim(`
29540
+ console.log(chalk211.dim(`
29075
29541
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
29076
29542
  }
29077
29543
 
@@ -29131,7 +29597,7 @@ async function sqlColumns(table, connectionName) {
29131
29597
  }
29132
29598
 
29133
29599
  // src/commands/sql/sqlMutate.ts
29134
- import chalk211 from "chalk";
29600
+ import chalk212 from "chalk";
29135
29601
 
29136
29602
  // src/commands/sql/isMutation.ts
29137
29603
  var MUTATION_KEYWORDS = [
@@ -29165,7 +29631,7 @@ function isMutation(sql25) {
29165
29631
  async function sqlMutate(query, connectionName) {
29166
29632
  if (!isMutation(query)) {
29167
29633
  console.error(
29168
- chalk211.red(
29634
+ chalk212.red(
29169
29635
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
29170
29636
  )
29171
29637
  );
@@ -29175,18 +29641,18 @@ async function sqlMutate(query, connectionName) {
29175
29641
  const pool = await sqlConnect(conn);
29176
29642
  try {
29177
29643
  const result = await pool.request().query(query);
29178
- console.log(chalk211.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
29644
+ console.log(chalk212.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
29179
29645
  } finally {
29180
29646
  await pool.close();
29181
29647
  }
29182
29648
  }
29183
29649
 
29184
29650
  // src/commands/sql/sqlQuery.ts
29185
- import chalk212 from "chalk";
29651
+ import chalk213 from "chalk";
29186
29652
  async function sqlQuery(query, connectionName) {
29187
29653
  if (isMutation(query)) {
29188
29654
  console.error(
29189
- chalk212.red(
29655
+ chalk213.red(
29190
29656
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
29191
29657
  )
29192
29658
  );
@@ -29201,7 +29667,7 @@ async function sqlQuery(query, connectionName) {
29201
29667
  printTable(rows);
29202
29668
  } else {
29203
29669
  console.log(
29204
- chalk212.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
29670
+ chalk213.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
29205
29671
  );
29206
29672
  }
29207
29673
  } finally {
@@ -29346,7 +29812,7 @@ function reportPrune(label2, result, force) {
29346
29812
  // src/commands/sync/syncClaudeMd.ts
29347
29813
  import * as fs41 from "fs";
29348
29814
  import * as path66 from "path";
29349
- import chalk213 from "chalk";
29815
+ import chalk214 from "chalk";
29350
29816
  async function syncClaudeMd(claudeDir, targetBase, options2) {
29351
29817
  const source = path66.join(claudeDir, "CLAUDE.md");
29352
29818
  const target = path66.join(targetBase, "CLAUDE.md");
@@ -29355,14 +29821,14 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
29355
29821
  const targetContent = fs41.readFileSync(target, "utf8");
29356
29822
  if (sourceContent !== targetContent) {
29357
29823
  console.log(
29358
- chalk213.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
29824
+ chalk214.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
29359
29825
  );
29360
29826
  console.log();
29361
29827
  printDiff(targetContent, sourceContent);
29362
29828
  if (!options2?.yes) {
29363
29829
  printAutoConfirmHint();
29364
29830
  const confirm = await promptConfirm(
29365
- chalk213.red("Overwrite existing CLAUDE.md?"),
29831
+ chalk214.red("Overwrite existing CLAUDE.md?"),
29366
29832
  false
29367
29833
  );
29368
29834
  if (!confirm) {
@@ -29595,7 +30061,7 @@ function syncPi(claudeDir, options2) {
29595
30061
  // src/commands/sync/syncSettings.ts
29596
30062
  import * as fs47 from "fs";
29597
30063
  import * as path73 from "path";
29598
- import chalk214 from "chalk";
30064
+ import chalk215 from "chalk";
29599
30065
  async function syncSettings(claudeDir, targetBase, options2) {
29600
30066
  const source = path73.join(claudeDir, "settings.json");
29601
30067
  const target = path73.join(targetBase, "settings.json");
@@ -29614,7 +30080,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
29614
30080
  if (mergedContent !== normalizedTarget) {
29615
30081
  if (!options2?.yes) {
29616
30082
  console.log(
29617
- chalk214.yellow(
30083
+ chalk215.yellow(
29618
30084
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
29619
30085
  )
29620
30086
  );
@@ -29622,7 +30088,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
29622
30088
  printDiff(targetContent, mergedContent);
29623
30089
  printAutoConfirmHint();
29624
30090
  const confirm = await promptConfirm(
29625
- chalk214.red("Overwrite existing settings.json?"),
30091
+ chalk215.red("Overwrite existing settings.json?"),
29626
30092
  false
29627
30093
  );
29628
30094
  if (!confirm) {
@@ -29764,11 +30230,11 @@ async function configure() {
29764
30230
  }
29765
30231
 
29766
30232
  // src/commands/transcript/list.ts
29767
- import { existsSync as existsSync61, readdirSync as readdirSync19, statSync as statSync10 } from "fs";
30233
+ import { existsSync as existsSync62, readdirSync as readdirSync19, statSync as statSync10 } from "fs";
29768
30234
  import { join as join77 } from "path";
29769
30235
  function list4() {
29770
30236
  const { vttDir } = getTranscriptConfig();
29771
- if (!existsSync61(vttDir)) return;
30237
+ if (!existsSync62(vttDir)) return;
29772
30238
  for (const entry of readdirSync19(vttDir)) {
29773
30239
  if (!entry.endsWith(".vtt")) continue;
29774
30240
  if (statSync10(join77(vttDir, entry)).isDirectory()) continue;
@@ -29778,9 +30244,9 @@ function list4() {
29778
30244
 
29779
30245
  // src/commands/transcript/move.ts
29780
30246
  import {
29781
- existsSync as existsSync62,
30247
+ existsSync as existsSync63,
29782
30248
  mkdirSync as mkdirSync26,
29783
- readFileSync as readFileSync47,
30249
+ readFileSync as readFileSync48,
29784
30250
  renameSync as renameSync2,
29785
30251
  writeFileSync as writeFileSync42
29786
30252
  } from "fs";
@@ -29992,7 +30458,7 @@ function formatChatLog(messages) {
29992
30458
  // src/commands/transcript/move.ts
29993
30459
  var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
29994
30460
  function convertVttToMarkdown(inputPath) {
29995
- const cues = parseVtt(readFileSync47(inputPath, "utf8"));
30461
+ const cues = parseVtt(readFileSync48(inputPath, "utf8"));
29996
30462
  const messages = cuesToChatMessages(deduplicateCues(cues));
29997
30463
  return formatChatLog(messages);
29998
30464
  }
@@ -30010,7 +30476,7 @@ function move(file, options2) {
30010
30476
  const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
30011
30477
  const filename = basename21(file);
30012
30478
  const sourcePath = join78(vttDir, filename);
30013
- if (!existsSync62(sourcePath)) {
30479
+ if (!existsSync63(sourcePath)) {
30014
30480
  console.error(`Error: VTT file not found: ${sourcePath}`);
30015
30481
  process.exit(1);
30016
30482
  }
@@ -30102,7 +30568,7 @@ function registerVerify(program2) {
30102
30568
  }
30103
30569
 
30104
30570
  // src/commands/voice/devices.ts
30105
- import { spawnSync as spawnSync7 } from "child_process";
30571
+ import { spawnSync as spawnSync8 } from "child_process";
30106
30572
  import { join as join80 } from "path";
30107
30573
 
30108
30574
  // src/commands/voice/shared.ts
@@ -30135,18 +30601,18 @@ function getLockFile() {
30135
30601
  // src/commands/voice/devices.ts
30136
30602
  function devices() {
30137
30603
  const script = join80(getPythonDir(), "list_devices.py");
30138
- spawnSync7(getVenvPython(), [script], { stdio: "inherit" });
30604
+ spawnSync8(getVenvPython(), [script], { stdio: "inherit" });
30139
30605
  }
30140
30606
 
30141
30607
  // src/commands/voice/logs.ts
30142
- import { existsSync as existsSync63, readFileSync as readFileSync48 } from "fs";
30608
+ import { existsSync as existsSync64, readFileSync as readFileSync49 } from "fs";
30143
30609
  function logs(options2) {
30144
- if (!existsSync63(voicePaths.log)) {
30610
+ if (!existsSync64(voicePaths.log)) {
30145
30611
  console.log("No voice log file found");
30146
30612
  return;
30147
30613
  }
30148
30614
  const count8 = Number.parseInt(options2.lines ?? "150", 10);
30149
- const content = readFileSync48(voicePaths.log, "utf8").trim();
30615
+ const content = readFileSync49(voicePaths.log, "utf8").trim();
30150
30616
  if (!content) {
30151
30617
  console.log("Voice log is empty");
30152
30618
  return;
@@ -30167,13 +30633,13 @@ function logs(options2) {
30167
30633
  }
30168
30634
 
30169
30635
  // src/commands/voice/setup.ts
30170
- import { spawnSync as spawnSync8 } from "child_process";
30636
+ import { spawnSync as spawnSync9 } from "child_process";
30171
30637
  import { mkdirSync as mkdirSync28 } from "fs";
30172
30638
  import { join as join82 } from "path";
30173
30639
 
30174
30640
  // src/commands/voice/checkLockFile.ts
30175
30641
  import { execSync as execSync58 } from "child_process";
30176
- import { existsSync as existsSync64, mkdirSync as mkdirSync27, readFileSync as readFileSync49, writeFileSync as writeFileSync43 } from "fs";
30642
+ import { existsSync as existsSync65, mkdirSync as mkdirSync27, readFileSync as readFileSync50, writeFileSync as writeFileSync43 } from "fs";
30177
30643
  import { join as join81 } from "path";
30178
30644
  function isProcessAlive2(pid) {
30179
30645
  try {
@@ -30185,9 +30651,9 @@ function isProcessAlive2(pid) {
30185
30651
  }
30186
30652
  function checkLockFile() {
30187
30653
  const lockFile = getLockFile();
30188
- if (!existsSync64(lockFile)) return;
30654
+ if (!existsSync65(lockFile)) return;
30189
30655
  try {
30190
- const lock2 = JSON.parse(readFileSync49(lockFile, "utf8"));
30656
+ const lock2 = JSON.parse(readFileSync50(lockFile, "utf8"));
30191
30657
  if (lock2.pid && isProcessAlive2(lock2.pid)) {
30192
30658
  console.error(
30193
30659
  `Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
@@ -30198,7 +30664,7 @@ function checkLockFile() {
30198
30664
  }
30199
30665
  }
30200
30666
  function bootstrapVenv() {
30201
- if (existsSync64(getVenvPython())) return;
30667
+ if (existsSync65(getVenvPython())) return;
30202
30668
  console.log("Setting up Python environment...");
30203
30669
  const pythonDir = getPythonDir();
30204
30670
  execSync58(
@@ -30228,7 +30694,7 @@ function setup() {
30228
30694
  bootstrapVenv();
30229
30695
  console.log("\nDownloading models...\n");
30230
30696
  const script = join82(getPythonDir(), "setup_models.py");
30231
- const result = spawnSync8(getVenvPython(), [script], {
30697
+ const result = spawnSync9(getVenvPython(), [script], {
30232
30698
  stdio: "inherit",
30233
30699
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
30234
30700
  });
@@ -30289,7 +30755,7 @@ function start2(options2) {
30289
30755
  }
30290
30756
 
30291
30757
  // src/commands/voice/status.ts
30292
- import { existsSync as existsSync65, readFileSync as readFileSync50 } from "fs";
30758
+ import { existsSync as existsSync66, readFileSync as readFileSync51 } from "fs";
30293
30759
  function isProcessAlive3(pid) {
30294
30760
  try {
30295
30761
  process.kill(pid, 0);
@@ -30299,16 +30765,16 @@ function isProcessAlive3(pid) {
30299
30765
  }
30300
30766
  }
30301
30767
  function readRecentLogs(count8) {
30302
- if (!existsSync65(voicePaths.log)) return [];
30303
- const lines2 = readFileSync50(voicePaths.log, "utf8").trim().split("\n");
30768
+ if (!existsSync66(voicePaths.log)) return [];
30769
+ const lines2 = readFileSync51(voicePaths.log, "utf8").trim().split("\n");
30304
30770
  return lines2.slice(-count8);
30305
30771
  }
30306
30772
  function status2() {
30307
- if (!existsSync65(voicePaths.pid)) {
30773
+ if (!existsSync66(voicePaths.pid)) {
30308
30774
  console.log("Voice daemon: not running (no PID file)");
30309
30775
  return;
30310
30776
  }
30311
- const pid = Number.parseInt(readFileSync50(voicePaths.pid, "utf8").trim(), 10);
30777
+ const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
30312
30778
  const alive = isProcessAlive3(pid);
30313
30779
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
30314
30780
  const recent = readRecentLogs(5);
@@ -30327,13 +30793,13 @@ function status2() {
30327
30793
  }
30328
30794
 
30329
30795
  // src/commands/voice/stop.ts
30330
- import { existsSync as existsSync66, readFileSync as readFileSync51, unlinkSync as unlinkSync20 } from "fs";
30796
+ import { existsSync as existsSync67, readFileSync as readFileSync52, unlinkSync as unlinkSync20 } from "fs";
30331
30797
  function stop2() {
30332
- if (!existsSync66(voicePaths.pid)) {
30798
+ if (!existsSync67(voicePaths.pid)) {
30333
30799
  console.log("Voice daemon is not running (no PID file)");
30334
30800
  return;
30335
30801
  }
30336
- const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
30802
+ const pid = Number.parseInt(readFileSync52(voicePaths.pid, "utf8").trim(), 10);
30337
30803
  try {
30338
30804
  process.kill(pid, "SIGTERM");
30339
30805
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -30346,7 +30812,7 @@ function stop2() {
30346
30812
  }
30347
30813
  try {
30348
30814
  const lockFile = getLockFile();
30349
- if (existsSync66(lockFile)) unlinkSync20(lockFile);
30815
+ if (existsSync67(lockFile)) unlinkSync20(lockFile);
30350
30816
  } catch {
30351
30817
  }
30352
30818
  console.log("Voice daemon stopped");
@@ -30364,9 +30830,6 @@ function registerVoice(program2) {
30364
30830
  configHelp(voiceCommand, voiceConfigHelp);
30365
30831
  }
30366
30832
 
30367
- // src/commands/watch/readBuiltVersion.ts
30368
- import { join as join84 } from "path";
30369
-
30370
30833
  // src/commands/watch/resolveUpstream.ts
30371
30834
  import { execFileSync as execFileSync15 } from "child_process";
30372
30835
  function runGit3(args, cwd) {
@@ -30407,7 +30870,13 @@ function resolveUpstream(cwd) {
30407
30870
  }
30408
30871
  }
30409
30872
 
30873
+ // src/commands/watch/changedPaths.ts
30874
+ function changedPaths(from, cwd) {
30875
+ return runGit3(["diff", "--name-only", `${from}..HEAD`], cwd).split("\n").filter((line) => line.length > 0);
30876
+ }
30877
+
30410
30878
  // src/commands/watch/readBuiltVersion.ts
30879
+ import { join as join84 } from "path";
30411
30880
  function readBuiltVersion(cwd) {
30412
30881
  try {
30413
30882
  const root = runGit3(["rev-parse", "--show-toplevel"], cwd);
@@ -30436,7 +30905,8 @@ function renderWatchReport({
30436
30905
  version: version2,
30437
30906
  commits: commits2,
30438
30907
  newShas,
30439
- restarts
30908
+ restarts,
30909
+ syncs
30440
30910
  }) {
30441
30911
  const isNew = new Set(newShas);
30442
30912
  const lines2 = [`**Version** ${version2}`, ""];
@@ -30455,6 +30925,10 @@ function renderWatchReport({
30455
30925
  lines2.push(
30456
30926
  ...restarts.length === 0 ? ["- none needed"] : restarts.map((restart) => `- ${restart}`)
30457
30927
  );
30928
+ lines2.push("", "**Sync**", "");
30929
+ lines2.push(
30930
+ ...syncs.length === 0 ? ["- not needed"] : syncs.map((sync2) => `- ${sync2}`)
30931
+ );
30458
30932
  return lines2.join("\n");
30459
30933
  }
30460
30934
 
@@ -30475,17 +30949,51 @@ function restartAdvice(paths) {
30475
30949
  return rules.filter((rule) => paths.some(rule.matches)).map((rule) => rule.advice);
30476
30950
  }
30477
30951
 
30952
+ // src/commands/watch/syncAdvice.ts
30953
+ var rules2 = [
30954
+ {
30955
+ matches: (path80) => path80.startsWith("claude/commands/"),
30956
+ reason: "claude/commands changed"
30957
+ },
30958
+ {
30959
+ matches: (path80) => path80.startsWith("claude/skills/"),
30960
+ reason: "claude/skills changed"
30961
+ },
30962
+ {
30963
+ matches: (path80) => path80 === "claude/settings.json",
30964
+ reason: "claude/settings.json changed"
30965
+ },
30966
+ {
30967
+ matches: (path80) => path80 === "claude/CLAUDE.md",
30968
+ reason: "claude/CLAUDE.md changed"
30969
+ },
30970
+ {
30971
+ matches: (path80) => path80 === "claude/design-system-prompt.md",
30972
+ reason: "claude/design-system-prompt.md changed"
30973
+ },
30974
+ {
30975
+ matches: (path80) => path80.startsWith("codex/"),
30976
+ reason: "codex sources changed"
30977
+ },
30978
+ {
30979
+ matches: (path80) => path80.startsWith("pi/"),
30980
+ reason: "pi sources changed"
30981
+ }
30982
+ ];
30983
+ function syncAdvice(paths) {
30984
+ return rules2.filter((rule) => paths.some(rule.matches)).map((rule) => rule.reason);
30985
+ }
30986
+
30478
30987
  // src/commands/watch/buildWatchReport.ts
30479
30988
  var lines = (output) => output.split("\n").filter((line) => line.length > 0);
30480
30989
  function buildWatchReport(from, cwd) {
30481
- const range = from ? `${from}..HEAD` : void 0;
30990
+ const changed = from ? changedPaths(from, cwd) : [];
30482
30991
  return renderWatchReport({
30483
30992
  version: readBuiltVersion(cwd),
30484
30993
  commits: readRecentCommits(10, cwd),
30485
- newShas: range ? lines(runGit3(["rev-list", range], cwd)) : [],
30486
- restarts: restartAdvice(
30487
- range ? lines(runGit3(["diff", "--name-only", range], cwd)) : []
30488
- )
30994
+ newShas: from ? lines(runGit3(["rev-list", `${from}..HEAD`], cwd)) : [],
30995
+ restarts: restartAdvice(changed),
30996
+ syncs: syncAdvice(changed)
30489
30997
  });
30490
30998
  }
30491
30999
 
@@ -30709,7 +31217,7 @@ function resolveParams(params, cliArgs) {
30709
31217
  }
30710
31218
 
30711
31219
  // src/commands/run/resolveRunCwd.ts
30712
- import { existsSync as existsSync67 } from "fs";
31220
+ import { existsSync as existsSync68 } from "fs";
30713
31221
  import { resolve as resolve18 } from "path";
30714
31222
  var MissingRunCwdError = class extends Error {
30715
31223
  constructor(runName, cwd) {
@@ -30722,17 +31230,17 @@ var MissingRunCwdError = class extends Error {
30722
31230
  function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
30723
31231
  if (!config.cwd) return void 0;
30724
31232
  const cwd = resolve18(baseDir, config.cwd);
30725
- if (!existsSync67(cwd)) throw new MissingRunCwdError(config.name, cwd);
31233
+ if (!existsSync68(cwd)) throw new MissingRunCwdError(config.name, cwd);
30726
31234
  return cwd;
30727
31235
  }
30728
31236
 
30729
31237
  // src/commands/run/runCommandToCompletion.ts
30730
31238
  import { spawn as spawn9 } from "child_process";
30731
- import { existsSync as existsSync69 } from "fs";
31239
+ import { existsSync as existsSync70 } from "fs";
30732
31240
 
30733
31241
  // src/commands/run/resolveCommand.ts
30734
31242
  import { execFileSync as execFileSync16 } from "child_process";
30735
- import { existsSync as existsSync68 } from "fs";
31243
+ import { existsSync as existsSync69 } from "fs";
30736
31244
  import { dirname as dirname35, join as join85, resolve as resolve19 } from "path";
30737
31245
  function resolveCommand2(command) {
30738
31246
  if (process.platform !== "win32" || command !== "bash") return command;
@@ -30740,7 +31248,7 @@ function resolveCommand2(command) {
30740
31248
  const gitPath = execFileSync16("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
30741
31249
  const gitRoot = resolve19(dirname35(gitPath), "..");
30742
31250
  const gitBash = join85(gitRoot, "bin", "bash.exe");
30743
- if (existsSync68(gitBash)) return gitBash;
31251
+ if (existsSync69(gitBash)) return gitBash;
30744
31252
  } catch {
30745
31253
  return command;
30746
31254
  }
@@ -30750,7 +31258,7 @@ function resolveCommand2(command) {
30750
31258
  // src/commands/run/runCommandToCompletion.ts
30751
31259
  function runCommandToCompletion(command, args, env, cwd, quiet) {
30752
31260
  return new Promise((resolveResult) => {
30753
- if (cwd && !existsSync69(cwd)) {
31261
+ if (cwd && !existsSync70(cwd)) {
30754
31262
  resolveResult({
30755
31263
  kind: "failed",
30756
31264
  message: `Failed to execute command: cwd ${cwd} does not exist`
@@ -30796,6 +31304,15 @@ function runPreCommands(pre, cwd) {
30796
31304
  }
30797
31305
  }
30798
31306
 
31307
+ // src/commands/watch/toBuildOutcome.ts
31308
+ function toBuildOutcome(result) {
31309
+ if (result.kind === "failed")
31310
+ return { kind: "failed", exitCode: 1, output: result.message };
31311
+ if (result.exitCode !== 0)
31312
+ return { kind: "failed", exitCode: result.exitCode, output: result.output };
31313
+ return { kind: "built" };
31314
+ }
31315
+
30799
31316
  // src/commands/watch/runWatchBuild.ts
30800
31317
  async function runWatchBuild(entry) {
30801
31318
  const config = findRunConfig(entry);
@@ -30807,18 +31324,15 @@ async function runWatchBuild(entry) {
30807
31324
  return { kind: "failed", exitCode: 1, output: error.message };
30808
31325
  }
30809
31326
  if (config.pre) runPreCommands(config.pre, cwd);
30810
- const result = await runCommandToCompletion(
30811
- config.command,
30812
- [...config.args ?? [], ...resolveParams(config.params, [])],
30813
- config.env,
30814
- cwd,
30815
- config.quiet
31327
+ return toBuildOutcome(
31328
+ await runCommandToCompletion(
31329
+ config.command,
31330
+ [...config.args ?? [], ...resolveParams(config.params, [])],
31331
+ config.env,
31332
+ cwd,
31333
+ config.quiet
31334
+ )
30816
31335
  );
30817
- if (result.kind === "failed")
30818
- return { kind: "failed", exitCode: 1, output: result.message };
30819
- if (result.exitCode !== 0)
30820
- return { kind: "failed", exitCode: result.exitCode, output: result.output };
30821
- return { kind: "built" };
30822
31336
  }
30823
31337
 
30824
31338
  // src/commands/watch/reportBuildOrExit.ts
@@ -30833,6 +31347,25 @@ async function reportBuildOrExit(entry) {
30833
31347
  process.exit(4);
30834
31348
  }
30835
31349
 
31350
+ // src/commands/watch/runPostBuildSync.ts
31351
+ async function runPostBuildSync() {
31352
+ return toBuildOutcome(
31353
+ await runCommandToCompletion("assist", ["sync", "--yes"])
31354
+ );
31355
+ }
31356
+
31357
+ // src/commands/watch/reportSyncOrExit.ts
31358
+ async function reportSyncOrExit() {
31359
+ const outcome = await runPostBuildSync();
31360
+ if (outcome.kind === "built") {
31361
+ console.log("synced ~/.claude");
31362
+ return;
31363
+ }
31364
+ if (outcome.output.length > 0) process.stdout.write(outcome.output);
31365
+ console.error(`sync failed with exit code ${outcome.exitCode}`);
31366
+ process.exit(4);
31367
+ }
31368
+
30836
31369
  // src/commands/watch/fetchQuietly.ts
30837
31370
  import { execFileSync as execFileSync17 } from "child_process";
30838
31371
  var MIN_FETCH_TIMEOUT_MS = 6e4;
@@ -30944,6 +31477,8 @@ ${buildWatchReport(outcome.from)}`);
30944
31477
  await reportBuildOrExit(
30945
31478
  typeof options2.build === "string" ? options2.build : DEFAULT_BUILD_ENTRY
30946
31479
  );
31480
+ if (syncAdvice(changedPaths(outcome.from)).length > 0)
31481
+ await reportSyncOrExit();
30947
31482
  }
30948
31483
  process.exit(0);
30949
31484
  }
@@ -30952,7 +31487,7 @@ ${buildWatchReport(outcome.from)}`);
30952
31487
  function registerWatch(program2) {
30953
31488
  const watchCommand = program2.command("watch").description("Wait on upstream movement for the current branch");
30954
31489
  watchCommand.command("wait").description(
30955
- "Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull hits genuine divergence, 4 when --build fails, 1 when waiting is impossible, 130 on interrupt)"
31490
+ "Block until the current branch's upstream gains commits, then exit 0 (2 on timeout, 3 when --pull hits genuine divergence, 4 when --build or the post-build sync fails, 1 when waiting is impossible, 130 on interrupt)"
30956
31491
  ).option(
30957
31492
  "--interval <duration>",
30958
31493
  "How often to fetch after the fetch at startup (e.g. 30s, 2m)",
@@ -30966,21 +31501,21 @@ function registerWatch(program2) {
30966
31501
  "On movement, fast-forward with git pull --ff-only, recovering a dirty tree or a merely-behind branch; exit 3 with git's reason on genuine divergence"
30967
31502
  ).option(
30968
31503
  "--build [entry]",
30969
- "After a successful pull, run this run entry (default auto-build); exit 4 with its output when it fails"
31504
+ "After a successful pull, run this run entry (default auto-build), then run assist sync --yes when the pulled commits touched the files sync installs; exit 4 with the output of whichever fails"
30970
31505
  ).action(
30971
31506
  (options2) => watchWait(options2)
30972
31507
  );
30973
31508
  watchCommand.command("report").description(
30974
- "Print the built version, the last 10 commits as a markdown table, and the restarts the new commits make necessary"
31509
+ "Print the built version, the last 10 commits as a markdown table, the restarts the new commits make necessary, and whether ~/.claude needs a sync"
30975
31510
  ).option(
30976
31511
  "--from <sha>",
30977
- "Mark commits reachable from HEAD but not <sha> as new, and derive restart advice from the files they changed"
31512
+ "Mark commits reachable from HEAD but not <sha> as new, and derive the restart and sync advice from the files they changed"
30978
31513
  ).action((options2) => watchReport(options2));
30979
31514
  }
30980
31515
 
30981
31516
  // src/commands/roam/auth.ts
30982
31517
  import { randomBytes } from "crypto";
30983
- import chalk215 from "chalk";
31518
+ import chalk216 from "chalk";
30984
31519
 
30985
31520
  // src/commands/roam/waitForCallback.ts
30986
31521
  import { createServer as createServer3 } from "http";
@@ -31111,13 +31646,13 @@ async function auth() {
31111
31646
  saveGlobalConfig(config);
31112
31647
  const state = randomBytes(16).toString("hex");
31113
31648
  console.log(
31114
- chalk215.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
31649
+ chalk216.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
31115
31650
  );
31116
- console.log(chalk215.white("http://localhost:14523/callback\n"));
31117
- console.log(chalk215.blue("Opening browser for authorization..."));
31118
- console.log(chalk215.dim("Waiting for authorization callback..."));
31651
+ console.log(chalk216.white("http://localhost:14523/callback\n"));
31652
+ console.log(chalk216.blue("Opening browser for authorization..."));
31653
+ console.log(chalk216.dim("Waiting for authorization callback..."));
31119
31654
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
31120
- console.log(chalk215.dim("Exchanging code for tokens..."));
31655
+ console.log(chalk216.dim("Exchanging code for tokens..."));
31121
31656
  const tokens = await exchangeToken({
31122
31657
  code,
31123
31658
  clientId,
@@ -31133,13 +31668,13 @@ async function auth() {
31133
31668
  };
31134
31669
  saveGlobalConfig(config);
31135
31670
  console.log(
31136
- chalk215.green("Roam credentials and tokens saved to ~/.assist.yml")
31671
+ chalk216.green("Roam credentials and tokens saved to ~/.assist.yml")
31137
31672
  );
31138
31673
  }
31139
31674
 
31140
31675
  // src/commands/roam/postRoamActivity.ts
31141
31676
  import { execFileSync as execFileSync18 } from "child_process";
31142
- import { readdirSync as readdirSync20, readFileSync as readFileSync52, statSync as statSync11 } from "fs";
31677
+ import { readdirSync as readdirSync20, readFileSync as readFileSync53, statSync as statSync11 } from "fs";
31143
31678
  import { join as join86 } from "path";
31144
31679
  function findPortFile(roamDir) {
31145
31680
  let entries;
@@ -31165,7 +31700,7 @@ function postRoamActivity(app, event) {
31165
31700
  if (!portFile) return;
31166
31701
  let port;
31167
31702
  try {
31168
- port = readFileSync52(portFile, "utf8").trim();
31703
+ port = readFileSync53(portFile, "utf8").trim();
31169
31704
  } catch {
31170
31705
  return;
31171
31706
  }
@@ -31419,7 +31954,7 @@ function link2() {
31419
31954
  }
31420
31955
 
31421
31956
  // src/commands/run/remove.ts
31422
- import { existsSync as existsSync70, unlinkSync as unlinkSync21 } from "fs";
31957
+ import { existsSync as existsSync71, unlinkSync as unlinkSync21 } from "fs";
31423
31958
  import { join as join88 } from "path";
31424
31959
  function findRemoveIndex() {
31425
31960
  const idx = process.argv.indexOf("remove");
@@ -31436,7 +31971,7 @@ function parseRemoveName() {
31436
31971
  }
31437
31972
  function deleteCommandFile(name) {
31438
31973
  const filePath = join88(".claude", "commands", `${name}.md`);
31439
- if (existsSync70(filePath)) {
31974
+ if (existsSync71(filePath)) {
31440
31975
  unlinkSync21(filePath);
31441
31976
  console.log(`Deleted command file: ${filePath}`);
31442
31977
  }
@@ -31481,10 +32016,10 @@ function registerRun(program2) {
31481
32016
 
31482
32017
  // src/commands/screenshot/index.ts
31483
32018
  import { execSync as execSync60 } from "child_process";
31484
- import { existsSync as existsSync71, mkdirSync as mkdirSync31, unlinkSync as unlinkSync22, writeFileSync as writeFileSync46 } from "fs";
32019
+ import { existsSync as existsSync72, mkdirSync as mkdirSync31, unlinkSync as unlinkSync22, writeFileSync as writeFileSync46 } from "fs";
31485
32020
  import { tmpdir as tmpdir8 } from "os";
31486
32021
  import { join as join89, resolve as resolve20 } from "path";
31487
- import chalk216 from "chalk";
32022
+ import chalk217 from "chalk";
31488
32023
 
31489
32024
  // src/commands/screenshot/captureWindowPs1.ts
31490
32025
  var captureWindowPs1 = `
@@ -31613,7 +32148,7 @@ Write-Output $OutputPath
31613
32148
 
31614
32149
  // src/commands/screenshot/index.ts
31615
32150
  function buildOutputPath(outputDir, processName) {
31616
- if (!existsSync71(outputDir)) {
32151
+ if (!existsSync72(outputDir)) {
31617
32152
  mkdirSync31(outputDir, { recursive: true });
31618
32153
  }
31619
32154
  const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -31635,13 +32170,13 @@ function screenshot(processName) {
31635
32170
  const config = loadConfig();
31636
32171
  const outputDir = resolve20(config.screenshot.outputDir);
31637
32172
  const outputPath = buildOutputPath(outputDir, processName);
31638
- console.log(chalk216.gray(`Capturing window for process "${processName}" ...`));
32173
+ console.log(chalk217.gray(`Capturing window for process "${processName}" ...`));
31639
32174
  try {
31640
32175
  runPowerShellScript(processName, outputPath);
31641
- console.log(chalk216.green(`Screenshot saved: ${outputPath}`));
32176
+ console.log(chalk217.green(`Screenshot saved: ${outputPath}`));
31642
32177
  } catch (error) {
31643
32178
  const msg = error instanceof Error ? error.message : String(error);
31644
- console.error(chalk216.red(`Failed to capture screenshot: ${msg}`));
32179
+ console.error(chalk217.red(`Failed to capture screenshot: ${msg}`));
31645
32180
  process.exit(1);
31646
32181
  }
31647
32182
  }
@@ -31697,11 +32232,11 @@ function applyLine(result, pending, line) {
31697
32232
  }
31698
32233
 
31699
32234
  // src/commands/sessions/daemon/readDaemonPidFile.ts
31700
- import { readFileSync as readFileSync53 } from "fs";
32235
+ import { readFileSync as readFileSync54 } from "fs";
31701
32236
  function readDaemonPidFile() {
31702
32237
  try {
31703
32238
  const pid = Number.parseInt(
31704
- readFileSync53(daemonPaths.pid, "utf8").trim(),
32239
+ readFileSync54(daemonPaths.pid, "utf8").trim(),
31705
32240
  10
31706
32241
  );
31707
32242
  return Number.isInteger(pid) ? pid : void 0;
@@ -31958,12 +32493,12 @@ function toSessionRunInfo({
31958
32493
  }
31959
32494
 
31960
32495
  // src/commands/sessions/daemon/worktree/joinRefusal.ts
31961
- import { existsSync as existsSync72 } from "fs";
32496
+ import { existsSync as existsSync73 } from "fs";
31962
32497
  function joinRefusal(session) {
31963
32498
  if (session.commandType === "run") return "a server run has no agent stream";
31964
32499
  if (session.closing === true) return "the session is closing";
31965
32500
  if (!session.cwd) return "the session has no working directory";
31966
- if (!existsSync72(session.cwd))
32501
+ if (!existsSync73(session.cwd))
31967
32502
  return "the session's workspace no longer exists";
31968
32503
  return void 0;
31969
32504
  }
@@ -32127,11 +32662,11 @@ function sessionBase(id, status3) {
32127
32662
  }
32128
32663
 
32129
32664
  // src/commands/sessions/daemon/spawnPty.ts
32130
- import { existsSync as existsSync74 } from "fs";
32665
+ import { existsSync as existsSync75 } from "fs";
32131
32666
  import * as pty from "node-pty";
32132
32667
 
32133
32668
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
32134
- import { chmodSync, existsSync as existsSync73, statSync as statSync12 } from "fs";
32669
+ import { chmodSync, existsSync as existsSync74, statSync as statSync12 } from "fs";
32135
32670
  import { createRequire as createRequire3 } from "module";
32136
32671
  import path75 from "path";
32137
32672
  var require4 = createRequire3(import.meta.url);
@@ -32146,7 +32681,7 @@ function ensureSpawnHelperExecutable() {
32146
32681
  `${process.platform}-${process.arch}`,
32147
32682
  "spawn-helper"
32148
32683
  );
32149
- if (!existsSync73(helper)) return;
32684
+ if (!existsSync74(helper)) return;
32150
32685
  const mode = statSync12(helper).mode;
32151
32686
  if ((mode & 73) === 0) chmodSync(helper, mode | 493);
32152
32687
  }
@@ -32182,7 +32717,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
32182
32717
  });
32183
32718
  }
32184
32719
  function refuseMissingCwd(cwd, sessionId) {
32185
- if (!cwd || existsSync74(cwd)) return;
32720
+ if (!cwd || existsSync75(cwd)) return;
32186
32721
  daemonLog(
32187
32722
  `${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
32188
32723
  );
@@ -32364,11 +32899,11 @@ function setStatus2(session, newStatus) {
32364
32899
  }
32365
32900
 
32366
32901
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
32367
- import { existsSync as existsSync76 } from "fs";
32902
+ import { existsSync as existsSync77 } from "fs";
32368
32903
  import { basename as basename22 } from "path";
32369
32904
 
32370
32905
  // src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
32371
- import { existsSync as existsSync75 } from "fs";
32906
+ import { existsSync as existsSync76 } from "fs";
32372
32907
  import { join as join92 } from "path";
32373
32908
 
32374
32909
  // src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
@@ -32438,7 +32973,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
32438
32973
  );
32439
32974
  }
32440
32975
  function strandedReason(worktreePath, cause) {
32441
- if (!existsSync75(join92(worktreePath, ".git")))
32976
+ if (!existsSync76(join92(worktreePath, ".git")))
32442
32977
  return "its .git link is already gone";
32443
32978
  if (/not a working tree|not a git repository/i.test(reason2(cause)))
32444
32979
  return "git no longer recognises it as a working tree";
@@ -32490,7 +33025,7 @@ function reason3(error) {
32490
33025
 
32491
33026
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
32492
33027
  async function reapWorktree(worktreePath, force = false) {
32493
- if (!existsSync76(worktreePath)) {
33028
+ if (!existsSync77(worktreePath)) {
32494
33029
  forgetWorktree(worktreePath);
32495
33030
  daemonLog(
32496
33031
  `worktree ${worktreePath} already gone; its record was forgotten`
@@ -32515,7 +33050,7 @@ async function reapWorktree(worktreePath, force = false) {
32515
33050
  }
32516
33051
  function owningClone(worktreePath) {
32517
33052
  const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
32518
- if (recorded && existsSync76(recorded)) return recorded;
33053
+ if (recorded && existsSync77(recorded)) return recorded;
32519
33054
  const detected = mainWorktree(worktreePath);
32520
33055
  if (detected) return detected;
32521
33056
  daemonLog(
@@ -32646,12 +33181,12 @@ function closeGateApplies(sessions, session) {
32646
33181
  }
32647
33182
 
32648
33183
  // src/commands/sessions/daemon/worktree/watchGitState.ts
32649
- import { existsSync as existsSync77, watch } from "fs";
33184
+ import { existsSync as existsSync78, watch } from "fs";
32650
33185
  var DEBOUNCE_MS = 500;
32651
33186
  var POLL_MS = 3e4;
32652
33187
  function watchGitState(cwd, onChange) {
32653
33188
  const common = gitCommonDir(cwd);
32654
- if (!common || !existsSync77(common)) return void 0;
33189
+ if (!common || !existsSync78(common)) return void 0;
32655
33190
  const watchers = [
32656
33191
  watchGitDir(common, onChange),
32657
33192
  pollGitState(cwd, onChange)
@@ -32826,9 +33361,9 @@ function flushPhaseActiveMs(session) {
32826
33361
  if (await persistPhaseActiveMs(phase.itemId, phase.phaseIdx, delta))
32827
33362
  session.activeMsFlushedForStretch = { since, ms: flushed + delta };
32828
33363
  };
32829
- const chain = (session.activeMsFlushChain ?? Promise.resolve()).then(run4);
32830
- session.activeMsFlushChain = chain;
32831
- return chain;
33364
+ const chain2 = (session.activeMsFlushChain ?? Promise.resolve()).then(run4);
33365
+ session.activeMsFlushChain = chain2;
33366
+ return chain2;
32832
33367
  }
32833
33368
 
32834
33369
  // src/commands/sessions/daemon/stripReplayQueries.ts
@@ -32885,6 +33420,7 @@ function decidePrPreview(sessions, waiters, notify2, d) {
32885
33420
  reason: d.reason,
32886
33421
  comments: d.comments,
32887
33422
  screenshots: d.screenshots,
33423
+ body: d.body,
32888
33424
  reviewAfter: d.reviewAfter,
32889
33425
  announceAfter: d.announceAfter,
32890
33426
  draft: d.draft
@@ -33125,10 +33661,10 @@ function emitSessionOutput(session, clients, data) {
33125
33661
  }
33126
33662
 
33127
33663
  // src/commands/sessions/daemon/exitReason.ts
33128
- import { existsSync as existsSync78 } from "fs";
33664
+ import { existsSync as existsSync79 } from "fs";
33129
33665
  import { resolve as resolve21 } from "path";
33130
33666
  function exitDetail(session) {
33131
- if (session.cwd && !existsSync78(session.cwd))
33667
+ if (session.cwd && !existsSync79(session.cwd))
33132
33668
  return `working directory ${session.cwd} no longer exists`;
33133
33669
  return missingRunConfigCwd(session);
33134
33670
  }
@@ -33142,7 +33678,7 @@ function missingRunConfigCwd(session) {
33142
33678
  const config = resolveRunConfig(session.runName, dir);
33143
33679
  if (!config?.cwd) return void 0;
33144
33680
  const configured = resolve21(runConfigBaseDirFrom(dir), config.cwd);
33145
- if (existsSync78(configured)) return void 0;
33681
+ if (existsSync79(configured)) return void 0;
33146
33682
  return `run config "${config.name}": cwd ${configured} does not exist`;
33147
33683
  }
33148
33684
 
@@ -33183,7 +33719,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
33183
33719
  }
33184
33720
 
33185
33721
  // src/commands/sessions/daemon/watchActivity.ts
33186
- import { existsSync as existsSync79, mkdirSync as mkdirSync32, watch as watch2 } from "fs";
33722
+ import { existsSync as existsSync80, mkdirSync as mkdirSync32, watch as watch2 } from "fs";
33187
33723
  import { dirname as dirname37 } from "path";
33188
33724
 
33189
33725
  // src/commands/sessions/daemon/applyActivityToSession.ts
@@ -33269,7 +33805,7 @@ function watchActivity(session, notify2, onClaudeSessionId) {
33269
33805
  if (timer) clearTimeout(timer);
33270
33806
  timer = setTimeout(read2, DEBOUNCE_MS2);
33271
33807
  });
33272
- if (existsSync79(path80)) read2();
33808
+ if (existsSync80(path80)) read2();
33273
33809
  }
33274
33810
  function refreshActivity(session) {
33275
33811
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -34891,7 +35427,7 @@ function rearmStoppedSessions(sessions, notify2) {
34891
35427
  }
34892
35428
 
34893
35429
  // src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
34894
- import { existsSync as existsSync82 } from "fs";
35430
+ import { existsSync as existsSync83 } from "fs";
34895
35431
  import { basename as basename24 } from "path";
34896
35432
 
34897
35433
  // src/commands/sessions/daemon/worktree/accountedTrees.ts
@@ -34946,9 +35482,9 @@ function bindResumedWorktree(session, cwd, notify2) {
34946
35482
  }
34947
35483
 
34948
35484
  // src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
34949
- import { existsSync as existsSync81 } from "fs";
35485
+ import { existsSync as existsSync82 } from "fs";
34950
35486
  async function reclaimVanishedWorktrees(clone, paths) {
34951
- if (!existsSync81(clone)) {
35487
+ if (!existsSync82(clone)) {
34952
35488
  for (const { path: path80 } of paths) forgetWorktree(path80);
34953
35489
  daemonLog(
34954
35490
  `clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
@@ -35114,7 +35650,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
35114
35650
  );
35115
35651
  continue;
35116
35652
  }
35117
- if (!existsSync82(path80)) {
35653
+ if (!existsSync83(path80)) {
35118
35654
  logVanishedTree(sessions, path80);
35119
35655
  vanished.set(clone, [
35120
35656
  ...vanished.get(clone) ?? [],
@@ -35731,14 +36267,14 @@ async function defaultConnect() {
35731
36267
  }
35732
36268
 
35733
36269
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
35734
- import { existsSync as existsSync83, readFileSync as readFileSync55 } from "fs";
36270
+ import { existsSync as existsSync84, readFileSync as readFileSync56 } from "fs";
35735
36271
  import { posix as posix3 } from "path";
35736
36272
  function hasPersistedWindowsSessions() {
35737
36273
  const sessionsFile = windowsSessionsFileFromWsl();
35738
36274
  if (!sessionsFile) return false;
35739
36275
  try {
35740
- if (!existsSync83(sessionsFile)) return false;
35741
- const data = JSON.parse(readFileSync55(sessionsFile, "utf8"));
36276
+ if (!existsSync84(sessionsFile)) return false;
36277
+ const data = JSON.parse(readFileSync56(sessionsFile, "utf8"));
35742
36278
  return Array.isArray(data) && data.length > 0;
35743
36279
  } catch (error) {
35744
36280
  const message3 = error instanceof Error ? error.message : String(error);
@@ -36472,7 +37008,7 @@ function setAutoAdvance(sessions, id, enabled) {
36472
37008
  }
36473
37009
 
36474
37010
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
36475
- import { existsSync as existsSync86 } from "fs";
37011
+ import { existsSync as existsSync87 } from "fs";
36476
37012
 
36477
37013
  // src/commands/sessions/daemon/resumeSession.ts
36478
37014
  function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
@@ -36503,10 +37039,10 @@ function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
36503
37039
  }
36504
37040
 
36505
37041
  // src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
36506
- import { existsSync as existsSync85 } from "fs";
37042
+ import { existsSync as existsSync86 } from "fs";
36507
37043
 
36508
37044
  // src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
36509
- import { copyFileSync as copyFileSync7, existsSync as existsSync84, mkdirSync as mkdirSync34 } from "fs";
37045
+ import { copyFileSync as copyFileSync7, existsSync as existsSync85, mkdirSync as mkdirSync34 } from "fs";
36510
37046
  import { join as join94 } from "path";
36511
37047
  function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
36512
37048
  const dir = projectDirForCwd(toCwd);
@@ -36517,7 +37053,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
36517
37053
  return;
36518
37054
  }
36519
37055
  const dest = join94(dir, `${claudeSessionId}.jsonl`);
36520
- if (existsSync84(dest)) {
37056
+ if (existsSync85(dest)) {
36521
37057
  daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
36522
37058
  return;
36523
37059
  }
@@ -36568,7 +37104,7 @@ function resumeInReplacementTree(ctx, claudeSessionId, missingCwd, name, harness
36568
37104
  }
36569
37105
  function cloneForReapedTree(missingCwd) {
36570
37106
  const clone = worktreeAttributionIncludingReaped(missingCwd)?.clone;
36571
- if (!clone || !existsSync85(clone))
37107
+ if (!clone || !existsSync86(clone))
36572
37108
  throw new Error(
36573
37109
  `working directory no longer exists and no clone is recorded to re-allocate from: ${missingCwd}`
36574
37110
  );
@@ -36577,7 +37113,7 @@ function cloneForReapedTree(missingCwd) {
36577
37113
 
36578
37114
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
36579
37115
  function resumeInTree(ctx, sessionId, cwd, name, harness) {
36580
- if (!existsSync86(cwd))
37116
+ if (!existsSync87(cwd))
36581
37117
  return resumeInReplacementTree(ctx, sessionId, cwd, name, harness);
36582
37118
  const id = ctx.spawnWith(
36583
37119
  (sid) => resumeSession(sid, sessionId, cwd, name, void 0, harness)
@@ -37156,7 +37692,7 @@ function handleConnection(socket, manager) {
37156
37692
  import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync47 } from "fs";
37157
37693
 
37158
37694
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
37159
- import { readFileSync as readFileSync56 } from "fs";
37695
+ import { readFileSync as readFileSync57 } from "fs";
37160
37696
  var WATCHDOG_INTERVAL_MS = 5e3;
37161
37697
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
37162
37698
  const timer = setInterval(() => {
@@ -37167,7 +37703,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
37167
37703
  }
37168
37704
  function ownsPidFile() {
37169
37705
  try {
37170
- return readFileSync56(daemonPaths.pid, "utf8").trim() === String(process.pid);
37706
+ return readFileSync57(daemonPaths.pid, "utf8").trim() === String(process.pid);
37171
37707
  } catch {
37172
37708
  return false;
37173
37709
  }
@@ -37417,7 +37953,7 @@ function registerSetStatusCommand(cmd) {
37417
37953
 
37418
37954
  // src/commands/sessions/summarise/index.ts
37419
37955
  import * as fs56 from "fs";
37420
- import chalk217 from "chalk";
37956
+ import chalk218 from "chalk";
37421
37957
 
37422
37958
  // src/commands/sessions/summarise/shared.ts
37423
37959
  import * as fs55 from "fs";
@@ -37476,22 +38012,22 @@ ${firstMessage}`);
37476
38012
  async function summarise2(options2) {
37477
38013
  const files = await discoverSessionFiles();
37478
38014
  if (files.length === 0) {
37479
- console.log(chalk217.yellow("No sessions found."));
38015
+ console.log(chalk218.yellow("No sessions found."));
37480
38016
  return;
37481
38017
  }
37482
38018
  const toProcess = selectCandidates(files, options2);
37483
38019
  if (toProcess.length === 0) {
37484
- console.log(chalk217.green("All sessions already summarised."));
38020
+ console.log(chalk218.green("All sessions already summarised."));
37485
38021
  return;
37486
38022
  }
37487
38023
  console.log(
37488
- chalk217.cyan(
38024
+ chalk218.cyan(
37489
38025
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
37490
38026
  )
37491
38027
  );
37492
38028
  const { succeeded, failed: failed2 } = processSessions(toProcess);
37493
38029
  console.log(
37494
- chalk217.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk217.yellow(`, ${failed2} skipped`) : "")
38030
+ chalk218.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk218.yellow(`, ${failed2} skipped`) : "")
37495
38031
  );
37496
38032
  }
37497
38033
  function selectCandidates(files, options2) {
@@ -37511,16 +38047,16 @@ function processSessions(files) {
37511
38047
  let failed2 = 0;
37512
38048
  for (let i = 0; i < files.length; i++) {
37513
38049
  const file = files[i];
37514
- process.stdout.write(chalk217.dim(` [${i + 1}/${files.length}] `));
38050
+ process.stdout.write(chalk218.dim(` [${i + 1}/${files.length}] `));
37515
38051
  const summary = summariseSession(file);
37516
38052
  if (summary) {
37517
38053
  writeSummary(file, summary);
37518
38054
  succeeded++;
37519
- process.stdout.write(`${chalk217.green("\u2713")} ${summary}
38055
+ process.stdout.write(`${chalk218.green("\u2713")} ${summary}
37520
38056
  `);
37521
38057
  } else {
37522
38058
  failed2++;
37523
- process.stdout.write(` ${chalk217.yellow("skip")}
38059
+ process.stdout.write(` ${chalk218.yellow("skip")}
37524
38060
  `);
37525
38061
  }
37526
38062
  }
@@ -37541,7 +38077,7 @@ function registerSessions(program2) {
37541
38077
  }
37542
38078
 
37543
38079
  // src/commands/statusLine.ts
37544
- import chalk219 from "chalk";
38080
+ import chalk220 from "chalk";
37545
38081
 
37546
38082
  // src/shared/contextLevel.ts
37547
38083
  function contextLevel(pct) {
@@ -37551,7 +38087,7 @@ function contextLevel(pct) {
37551
38087
  }
37552
38088
 
37553
38089
  // src/commands/buildLimitsSegment.ts
37554
- import chalk218 from "chalk";
38090
+ import chalk219 from "chalk";
37555
38091
 
37556
38092
  // src/shared/rateLimitLevel.ts
37557
38093
  var FIVE_HOUR_SECONDS = 5 * 3600;
@@ -37589,9 +38125,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
37589
38125
 
37590
38126
  // src/commands/buildLimitsSegment.ts
37591
38127
  var LEVEL_COLOR = {
37592
- ok: chalk218.green,
37593
- warn: chalk218.yellow,
37594
- over: chalk218.red
38128
+ ok: chalk219.green,
38129
+ warn: chalk219.yellow,
38130
+ over: chalk219.red
37595
38131
  };
37596
38132
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
37597
38133
  const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
@@ -37622,7 +38158,7 @@ function buildLimitsSegment(rateLimits) {
37622
38158
  }
37623
38159
 
37624
38160
  // src/commands/readGitBranch.ts
37625
- import { readFileSync as readFileSync58, statSync as statSync15 } from "fs";
38161
+ import { readFileSync as readFileSync59, statSync as statSync15 } from "fs";
37626
38162
  import { isAbsolute as isAbsolute4, join as join95, resolve as resolve22 } from "path";
37627
38163
  function resolveGitDir(cwd) {
37628
38164
  const dotGit = join95(cwd, ".git");
@@ -37637,7 +38173,7 @@ function resolveGitDir(cwd) {
37637
38173
  }
37638
38174
  let contents;
37639
38175
  try {
37640
- contents = readFileSync58(dotGit, "utf8");
38176
+ contents = readFileSync59(dotGit, "utf8");
37641
38177
  } catch {
37642
38178
  return null;
37643
38179
  }
@@ -37655,7 +38191,7 @@ function readGitBranch(cwd) {
37655
38191
  }
37656
38192
  let head;
37657
38193
  try {
37658
- head = readFileSync58(join95(gitDir, "HEAD"), "utf8");
38194
+ head = readFileSync59(join95(gitDir, "HEAD"), "utf8");
37659
38195
  } catch {
37660
38196
  return null;
37661
38197
  }
@@ -37687,7 +38223,7 @@ async function relayUsage(claudeSessionId, transcriptPath2, usedPct) {
37687
38223
  }
37688
38224
 
37689
38225
  // src/commands/statusLine.ts
37690
- chalk219.level = 3;
38226
+ chalk220.level = 3;
37691
38227
  function formatNumber(num) {
37692
38228
  return num.toLocaleString("en-US");
37693
38229
  }
@@ -37695,9 +38231,9 @@ function colorizePercent(pct) {
37695
38231
  const label2 = `${Math.round(pct)}%`;
37696
38232
  switch (contextLevel(pct)) {
37697
38233
  case "red":
37698
- return chalk219.red(label2);
38234
+ return chalk220.red(label2);
37699
38235
  case "yellow":
37700
- return chalk219.yellow(label2);
38236
+ return chalk220.yellow(label2);
37701
38237
  default:
37702
38238
  return label2;
37703
38239
  }
@@ -37710,7 +38246,7 @@ async function statusLine() {
37710
38246
  const usedPct = data.context_window.used_percentage ?? 0;
37711
38247
  const dir = data.workspace?.current_dir ?? data.cwd;
37712
38248
  const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
37713
- const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk219.cyan(branch2)} | ` : "";
38249
+ const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk220.cyan(branch2)} | ` : "";
37714
38250
  console.log(
37715
38251
  `${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
37716
38252
  );
@@ -37780,10 +38316,10 @@ async function update2() {
37780
38316
  }
37781
38317
 
37782
38318
  // src/reportCliError.ts
37783
- import chalk220 from "chalk";
38319
+ import chalk221 from "chalk";
37784
38320
  function reportCliError(error) {
37785
38321
  if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError || error instanceof MissingRunCwdError) {
37786
- console.error(chalk220.red(error.message));
38322
+ console.error(chalk221.red(error.message));
37787
38323
  } else {
37788
38324
  console.error(error);
37789
38325
  }