@staff0rd/assist 0.575.0 → 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.575.0",
9
+ version: "0.576.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -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
 
@@ -14030,7 +14031,7 @@ function requestPreviewDecision(request) {
14030
14031
  }
14031
14032
 
14032
14033
  // src/commands/sessions/shared/awaitPreviewApproval.ts
14033
- async function awaitPreviewApproval(subject, request, saveEditedBody) {
14034
+ async function awaitPreviewApproval(subject, request, options2 = {}) {
14034
14035
  console.log("Awaiting your approval in the assist web UI preview pane\u2026");
14035
14036
  let decision;
14036
14037
  try {
@@ -14041,8 +14042,9 @@ async function awaitPreviewApproval(subject, request, saveEditedBody) {
14041
14042
  );
14042
14043
  process.exit(1);
14043
14044
  }
14044
- if (decision.body !== void 0) saveEditedBody?.(decision.body);
14045
- 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);
14046
14048
  return decision;
14047
14049
  }
14048
14050
 
@@ -20500,14 +20502,8 @@ import { spawnSync as spawnSync4 } from "child_process";
20500
20502
  import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
20501
20503
  import { tmpdir as tmpdir5 } from "os";
20502
20504
  import { join as join49 } from "path";
20503
- function buildArgs2(queryFile, vars) {
20504
- const args = ["api", "graphql", "-F", `query=@${queryFile}`];
20505
- for (const [key, value] of Object.entries(vars)) {
20506
- const flag = typeof value === "number" ? "-F" : "-f";
20507
- args.push(flag, `${key}=${value}`);
20508
- }
20509
- return args;
20510
- }
20505
+
20506
+ // src/shared/throwOnGraphqlErrors.ts
20511
20507
  function throwOnGraphqlErrors(stdout) {
20512
20508
  let parsed;
20513
20509
  try {
@@ -20523,6 +20519,16 @@ function throwOnGraphqlErrors(stdout) {
20523
20519
  ).join("; ");
20524
20520
  throw new Error(messages || "GraphQL request returned errors");
20525
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
+ }
20526
20532
  function runGhGraphql(mutation, vars) {
20527
20533
  const queryFile = join49(tmpdir5(), `gh-query-${Date.now()}.graphql`);
20528
20534
  writeFileSync30(queryFile, mutation);
@@ -20830,6 +20836,83 @@ function fetchIssue2(number, repo) {
20830
20836
  }
20831
20837
  }
20832
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
+
20833
20916
  // src/commands/github/issue/pushIssueBody.ts
20834
20917
  import { execFileSync as execFileSync9 } from "child_process";
20835
20918
  function pushIssueBody(number, repo, bodyPath) {
@@ -20856,7 +20939,7 @@ function pushUnchangedIssue(number, repo, target, fetchedAt, bodyPath) {
20856
20939
 
20857
20940
  // src/commands/github/issue/reviewProposedIssueEdit.ts
20858
20941
  import { randomUUID as randomUUID9 } from "crypto";
20859
- async function reviewProposedIssueEdit(title, body, saveEditedBody) {
20942
+ async function reviewProposedIssueEdit(title, body, working) {
20860
20943
  const sessionId = process.env.ASSIST_SESSION_ID;
20861
20944
  if (process.env.ASSIST_SESSION !== "1" || !sessionId) return body;
20862
20945
  const decision = await awaitPreviewApproval(
@@ -20869,7 +20952,10 @@ async function reviewProposedIssueEdit(title, body, saveEditedBody) {
20869
20952
  prNumber: null,
20870
20953
  kind: "github-issue-edit"
20871
20954
  },
20872
- saveEditedBody
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
+ }
20873
20959
  );
20874
20960
  return decision.body ?? body;
20875
20961
  }
@@ -20886,40 +20972,8 @@ function viewIssue(number, repo) {
20886
20972
  }
20887
20973
  }
20888
20974
 
20889
- // src/commands/github/issue/writeIssueWorkingFile.ts
20890
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync31 } from "fs";
20891
-
20892
- // src/commands/github/issue/issueWorkingFile.ts
20893
- import { join as join50 } from "path";
20894
- function issueWorkingFile(slug, number) {
20895
- const [owner = "unknown", repo = "unknown"] = slug.split("/");
20896
- const dir = join50(getStoreDir(), "github-issues", owner, repo);
20897
- return {
20898
- dir,
20899
- bodyPath: join50(dir, `${number}.md`),
20900
- metaPath: join50(dir, `${number}.json`)
20901
- };
20902
- }
20903
-
20904
- // src/commands/github/issue/writeIssueWorkingFile.ts
20905
- function writeIssueWorkingFile(slug, number, target, updatedAt, body) {
20906
- const { dir, bodyPath, metaPath } = issueWorkingFile(slug, number);
20907
- mkdirSync16(dir, { recursive: true });
20908
- writeFileSync31(bodyPath, body);
20909
- writeFileSync31(
20910
- metaPath,
20911
- `${JSON.stringify({ target, updatedAt }, null, 2)}
20912
- `
20913
- );
20914
- return bodyPath;
20915
- }
20916
-
20917
20975
  // src/commands/github/issue/editIssue.ts
20918
20976
  var USAGE3 = "Usage: assist github issue edit <number> [-R <owner>/<repo>]";
20919
- function slugFromUrl(url) {
20920
- const match = /github\.com\/([^/]+\/[^/]+)\//.exec(url ?? "");
20921
- return match ? match[1] : "unknown/unknown";
20922
- }
20923
20977
  async function editIssue(numberArg, options2) {
20924
20978
  const number = Number.parseInt(numberArg, 10);
20925
20979
  if (!Number.isInteger(number) || number <= 0) {
@@ -20930,27 +20984,419 @@ async function editIssue(numberArg, options2) {
20930
20984
  viewIssue(number, options2.repo);
20931
20985
  return;
20932
20986
  }
20933
- const issue = fetchIssue2(number, options2.repo);
20934
- const slug = options2.repo ?? slugFromUrl(issue.url);
20935
- const target = `${slug}#${number}`;
20936
- validateProposedContent(
20937
- { subject: "Issue", context: "GitHub issues" },
20938
- issue.title,
20939
- issue.body
20940
- );
20941
- const save = (markdown) => writeIssueWorkingFile(slug, number, target, issue.updatedAt, markdown);
20942
- const bodyPath = save(issue.body);
20987
+ const issue = prepareIssueEdit(number, options2.repo, options2.fresh);
20943
20988
  const edited = await reviewProposedIssueEdit(
20944
- `Edit ${target}: ${issue.title}`,
20989
+ `Edit ${issue.target}: ${issue.title}`,
20945
20990
  issue.body,
20946
- save
20991
+ { path: issue.bodyPath, save: issue.save }
20947
20992
  );
20948
- validateProposedContent(
20949
- { subject: "Issue", context: "GitHub issues" },
20950
- issue.title,
20951
- edited
20993
+ validateIssueBody(issue.title, edited);
20994
+ pushUnchangedIssue(
20995
+ number,
20996
+ options2.repo,
20997
+ issue.target,
20998
+ issue.updatedAt,
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
21020
+ );
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}` : "";
21205
+ console.error(
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`
20952
21217
  );
20953
- pushUnchangedIssue(number, options2.repo, target, issue.updatedAt, bodyPath);
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.`
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));
21378
+ process.exit(1);
21379
+ }
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);
20954
21400
  }
20955
21401
 
20956
21402
  // src/commands/prs/readBodyArgument.ts
@@ -20977,9 +21423,12 @@ function registerGithubIssue(githubCommand) {
20977
21423
  issueCommand.command("edit <number>").description("Edit an existing GitHub issue's body in the preview pane").option(
20978
21424
  "-R, --repo <owner/repo>",
20979
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"
20980
21429
  ).addHelpText(
20981
21430
  "after",
20982
- "\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."
20983
21432
  ).action(editIssue);
20984
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(
20985
21434
  "-R, --repo <owner/repo>",
@@ -20995,6 +21444,7 @@ function registerGithubIssue(githubCommand) {
20995
21444
  });
20996
21445
  }
20997
21446
  );
21447
+ registerFixStructure(issueCommand);
20998
21448
  }
20999
21449
 
21000
21450
  // src/commands/registerGithub.ts
@@ -21021,9 +21471,9 @@ async function countPendingHandovers(orm, origin) {
21021
21471
 
21022
21472
  // src/commands/handover/migrateDiskHandovers.ts
21023
21473
  import {
21024
- existsSync as existsSync48,
21474
+ existsSync as existsSync49,
21025
21475
  readdirSync as readdirSync10,
21026
- readFileSync as readFileSync37,
21476
+ readFileSync as readFileSync38,
21027
21477
  rmSync as rmSync3,
21028
21478
  statSync as statSync8
21029
21479
  } from "fs";
@@ -21076,7 +21526,7 @@ function summariseHandoverContent(content) {
21076
21526
 
21077
21527
  // src/commands/handover/migrateDiskHandovers.ts
21078
21528
  function collectMarkdown(dir) {
21079
- if (!existsSync48(dir)) return [];
21529
+ if (!existsSync49(dir)) return [];
21080
21530
  const out = [];
21081
21531
  for (const entry of readdirSync10(dir, { withFileTypes: true })) {
21082
21532
  const full = join53(dir, entry.name);
@@ -21086,7 +21536,7 @@ function collectMarkdown(dir) {
21086
21536
  return out;
21087
21537
  }
21088
21538
  async function migrateFile(orm, origin, file, createdAt) {
21089
- const content = readFileSync37(file, "utf8");
21539
+ const content = readFileSync38(file, "utf8");
21090
21540
  await saveHandover(orm, {
21091
21541
  origin,
21092
21542
  summary: summariseHandoverContent(content),
@@ -21103,7 +21553,7 @@ async function migrateDiskHandovers(orm, origin, cwd = process.cwd()) {
21103
21553
  migrated++;
21104
21554
  }
21105
21555
  const handoverPath = getHandoverPath(cwd);
21106
- if (existsSync48(handoverPath)) {
21556
+ if (existsSync49(handoverPath)) {
21107
21557
  await migrateFile(orm, origin, handoverPath, statSync8(handoverPath).mtime);
21108
21558
  migrated++;
21109
21559
  }
@@ -21234,7 +21684,7 @@ function registerHandover(program2) {
21234
21684
  }
21235
21685
 
21236
21686
  // src/commands/jira/acceptanceCriteria.ts
21237
- import chalk162 from "chalk";
21687
+ import chalk163 from "chalk";
21238
21688
 
21239
21689
  // src/commands/jira/adfToText.ts
21240
21690
  function renderInline(node) {
@@ -21301,7 +21751,7 @@ function acceptanceCriteria(issueKey) {
21301
21751
  const parsed = fetchIssue(issueKey, field);
21302
21752
  const acValue = parsed?.fields?.[field];
21303
21753
  if (!acValue) {
21304
- console.log(chalk162.yellow(`No acceptance criteria found on ${issueKey}.`));
21754
+ console.log(chalk163.yellow(`No acceptance criteria found on ${issueKey}.`));
21305
21755
  return;
21306
21756
  }
21307
21757
  if (typeof acValue === "string") {
@@ -21367,14 +21817,14 @@ async function jiraAuth() {
21367
21817
  }
21368
21818
 
21369
21819
  // src/commands/jira/viewIssue.ts
21370
- import chalk163 from "chalk";
21820
+ import chalk164 from "chalk";
21371
21821
  function viewIssue2(issueKey) {
21372
21822
  const parsed = fetchIssue(issueKey, "summary,description");
21373
21823
  const fields = parsed?.fields;
21374
21824
  const summary = fields?.summary;
21375
21825
  const description = fields?.description;
21376
21826
  if (summary) {
21377
- console.log(chalk163.bold(summary));
21827
+ console.log(chalk164.bold(summary));
21378
21828
  }
21379
21829
  if (description) {
21380
21830
  if (summary) console.log();
@@ -21388,7 +21838,7 @@ function viewIssue2(issueKey) {
21388
21838
  }
21389
21839
  if (!summary && !description) {
21390
21840
  console.log(
21391
- chalk163.yellow(`No summary or description found on ${issueKey}.`)
21841
+ chalk164.yellow(`No summary or description found on ${issueKey}.`)
21392
21842
  );
21393
21843
  }
21394
21844
  }
@@ -21423,7 +21873,7 @@ import { randomUUID as randomUUID10 } from "crypto";
21423
21873
 
21424
21874
  // src/commands/review/checkoutPr.ts
21425
21875
  import { execFileSync as execFileSync12 } from "child_process";
21426
- import chalk164 from "chalk";
21876
+ import chalk165 from "chalk";
21427
21877
 
21428
21878
  // src/commands/sessions/daemon/daemonLog.ts
21429
21879
  var RING_CAPACITY = 1e3;
@@ -21460,7 +21910,7 @@ function canonicalTreePath(path80) {
21460
21910
  }
21461
21911
 
21462
21912
  // src/commands/sessions/daemon/worktree/createWorktree.ts
21463
- import { existsSync as existsSync49 } from "fs";
21913
+ import { existsSync as existsSync50 } from "fs";
21464
21914
  import { basename as basename16, dirname as dirname25 } from "path";
21465
21915
 
21466
21916
  // src/commands/sessions/daemon/worktree/planAllocation.ts
@@ -21507,7 +21957,7 @@ function createWorktree(clone, strategy, boundTreeRoots2, preferredPath) {
21507
21957
  const base = strategy.root ? expandTilde2(strategy.root) : dirname25(clone);
21508
21958
  const registered = new Set(listWorktreePaths(clone));
21509
21959
  const branches = new Set(listLocalBranches(clone));
21510
- 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));
21511
21961
  const path80 = preferredPath && !isTaken(preferredPath) ? preferredPath : nextWorktreePath(clone, base, isTaken);
21512
21962
  const start3 = worktreeStartPoint(clone, strategy.trunk);
21513
21963
  gitSync(clone, [
@@ -21533,7 +21983,7 @@ function keptInTree(cwd, reason4) {
21533
21983
  }
21534
21984
 
21535
21985
  // src/commands/sessions/daemon/worktree/treeDurability.ts
21536
- import { existsSync as existsSync50 } from "fs";
21986
+ import { existsSync as existsSync51 } from "fs";
21537
21987
  var treeIsGone = { durable: true, gone: true };
21538
21988
  function treeDurability(state) {
21539
21989
  if (state.dirty) return { durable: false, reason: "uncommitted changes" };
@@ -21564,14 +22014,14 @@ function* durabilityProbes() {
21564
22014
  });
21565
22015
  }
21566
22016
  async function checkDurability(cwd) {
21567
- if (!existsSync50(cwd)) return treeIsGone;
22017
+ if (!existsSync51(cwd)) return treeIsGone;
21568
22018
  const probes = durabilityProbes();
21569
22019
  let step2 = probes.next();
21570
22020
  while (!step2.done) step2 = probes.next(await gitResult(cwd, step2.value));
21571
22021
  return step2.value;
21572
22022
  }
21573
22023
  function checkDurabilitySync(cwd) {
21574
- if (!existsSync50(cwd)) return treeIsGone;
22024
+ if (!existsSync51(cwd)) return treeIsGone;
21575
22025
  const probes = durabilityProbes();
21576
22026
  let step2 = probes.next();
21577
22027
  while (!step2.done) step2 = probes.next(gitSyncResult(cwd, step2.value));
@@ -21814,20 +22264,20 @@ function persistedTreeRoots() {
21814
22264
  }
21815
22265
 
21816
22266
  // src/commands/sessions/daemon/worktree/seedWorktree.ts
21817
- import { copyFileSync, existsSync as existsSync52, mkdirSync as mkdirSync17 } from "fs";
22267
+ import { copyFileSync, existsSync as existsSync53, mkdirSync as mkdirSync17 } from "fs";
21818
22268
  import { dirname as dirname26, join as join56 } from "path";
21819
22269
 
21820
22270
  // src/commands/sessions/daemon/worktree/runInstall.ts
21821
22271
  import { spawn as spawn5 } from "child_process";
21822
22272
 
21823
22273
  // src/commands/sessions/daemon/worktree/resolveInstallCommand.ts
21824
- import { existsSync as existsSync51 } from "fs";
22274
+ import { existsSync as existsSync52 } from "fs";
21825
22275
  import { join as join55 } from "path";
21826
22276
  function detectInstallCommand(repoRoot2) {
21827
- if (!existsSync51(join55(repoRoot2, "package.json"))) return null;
21828
- if (existsSync51(join55(repoRoot2, "pnpm-lock.yaml"))) return "pnpm install";
21829
- if (existsSync51(join55(repoRoot2, "yarn.lock"))) return "yarn install";
21830
- 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";
21831
22281
  return "npm install";
21832
22282
  }
21833
22283
  function resolveInstallCommand(repoRoot2, install) {
@@ -21940,7 +22390,7 @@ function seedWorktree(worktreePath, clone, onSeeded = () => {
21940
22390
  function copyConfigFiles(worktreePath, clone, copy) {
21941
22391
  for (const rel of copy) {
21942
22392
  const src = join56(clone, rel);
21943
- if (!existsSync52(src)) continue;
22393
+ if (!existsSync53(src)) continue;
21944
22394
  const dest = join56(worktreePath, rel);
21945
22395
  try {
21946
22396
  mkdirSync17(dirname26(dest), { recursive: true });
@@ -22035,7 +22485,7 @@ async function checkoutPr(number) {
22035
22485
  try {
22036
22486
  execFileSync12("gh", ["pr", "checkout", number], { stdio: "inherit" });
22037
22487
  } catch {
22038
- console.error(chalk164.red(`gh pr checkout ${number} failed; aborting.`));
22488
+ console.error(chalk165.red(`gh pr checkout ${number} failed; aborting.`));
22039
22489
  process.exit(1);
22040
22490
  }
22041
22491
  }
@@ -22172,15 +22622,15 @@ function registerList(program2) {
22172
22622
  // src/commands/mermaid/index.ts
22173
22623
  import { mkdirSync as mkdirSync18, readdirSync as readdirSync11 } from "fs";
22174
22624
  import { resolve as resolve16 } from "path";
22175
- import chalk167 from "chalk";
22625
+ import chalk168 from "chalk";
22176
22626
 
22177
22627
  // src/commands/mermaid/exportFile.ts
22178
- import { readFileSync as readFileSync38, writeFileSync as writeFileSync32 } from "fs";
22628
+ import { readFileSync as readFileSync39, writeFileSync as writeFileSync32 } from "fs";
22179
22629
  import { basename as basename17, extname as extname2, resolve as resolve15 } from "path";
22180
- import chalk166 from "chalk";
22630
+ import chalk167 from "chalk";
22181
22631
 
22182
22632
  // src/commands/mermaid/renderBlock.ts
22183
- import chalk165 from "chalk";
22633
+ import chalk166 from "chalk";
22184
22634
  async function renderBlock(krokiUrl, source) {
22185
22635
  const response = await fetch(`${krokiUrl}/mermaid/svg`, {
22186
22636
  method: "POST",
@@ -22189,7 +22639,7 @@ async function renderBlock(krokiUrl, source) {
22189
22639
  });
22190
22640
  if (!response.ok) {
22191
22641
  console.error(
22192
- chalk165.red(
22642
+ chalk166.red(
22193
22643
  `Kroki request failed: ${response.status} ${response.statusText}`
22194
22644
  )
22195
22645
  );
@@ -22201,25 +22651,25 @@ async function renderBlock(krokiUrl, source) {
22201
22651
 
22202
22652
  // src/commands/mermaid/exportFile.ts
22203
22653
  async function exportFile(file, outDir, krokiUrl, onlyIndex) {
22204
- const content = readFileSync38(file, "utf8");
22654
+ const content = readFileSync39(file, "utf8");
22205
22655
  const blocks = extractMermaidBlocks(content);
22206
22656
  const stem = basename17(file, extname2(file));
22207
22657
  if (onlyIndex !== void 0) {
22208
22658
  if (onlyIndex < 1 || onlyIndex > blocks.length) {
22209
22659
  console.error(
22210
- chalk166.red(
22660
+ chalk167.red(
22211
22661
  `${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
22212
22662
  )
22213
22663
  );
22214
22664
  process.exit(1);
22215
22665
  }
22216
22666
  console.log(
22217
- chalk166.gray(
22667
+ chalk167.gray(
22218
22668
  `${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
22219
22669
  )
22220
22670
  );
22221
22671
  } else {
22222
- console.log(chalk166.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
22672
+ console.log(chalk167.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
22223
22673
  }
22224
22674
  for (const [i, source] of blocks.entries()) {
22225
22675
  const idx = i + 1;
@@ -22227,7 +22677,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
22227
22677
  const outPath = resolve15(outDir, `${stem}-${idx}.svg`);
22228
22678
  const svg = await renderBlock(krokiUrl, source);
22229
22679
  writeFileSync32(outPath, svg, "utf8");
22230
- console.log(chalk166.green(` \u2192 ${outPath}`));
22680
+ console.log(chalk167.green(` \u2192 ${outPath}`));
22231
22681
  }
22232
22682
  }
22233
22683
  function extractMermaidBlocks(markdown) {
@@ -22243,18 +22693,18 @@ async function mermaidExport(file, options2 = {}) {
22243
22693
  if (options2.index !== void 0) {
22244
22694
  if (!Number.isInteger(options2.index) || options2.index < 1) {
22245
22695
  console.error(
22246
- chalk167.red(`--index must be a positive integer (got ${options2.index})`)
22696
+ chalk168.red(`--index must be a positive integer (got ${options2.index})`)
22247
22697
  );
22248
22698
  process.exit(1);
22249
22699
  }
22250
22700
  if (!file) {
22251
- console.error(chalk167.red("--index requires a file argument"));
22701
+ console.error(chalk168.red("--index requires a file argument"));
22252
22702
  process.exit(1);
22253
22703
  }
22254
22704
  }
22255
22705
  const files = file ? [file] : readdirSync11(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
22256
22706
  if (files.length === 0) {
22257
- console.log(chalk167.gray("No markdown files found in current directory."));
22707
+ console.log(chalk168.gray("No markdown files found in current directory."));
22258
22708
  return;
22259
22709
  }
22260
22710
  for (const f of files) {
@@ -22281,7 +22731,7 @@ function registerMermaid(program2) {
22281
22731
  import { mkdir as mkdir4 } from "fs/promises";
22282
22732
  import { createServer as createServer2 } from "http";
22283
22733
  import { dirname as dirname28 } from "path";
22284
- import chalk169 from "chalk";
22734
+ import chalk170 from "chalk";
22285
22735
 
22286
22736
  // src/commands/netcap/corsHeaders.ts
22287
22737
  var corsHeaders = {
@@ -22360,7 +22810,7 @@ function createNetcapHandler(options2) {
22360
22810
  import { cp, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
22361
22811
  import { networkInterfaces } from "os";
22362
22812
  import { join as join58 } from "path";
22363
- import chalk168 from "chalk";
22813
+ import chalk169 from "chalk";
22364
22814
 
22365
22815
  // src/commands/netcap/netcapExtensionDir.ts
22366
22816
  import { dirname as dirname27, join as join57 } from "path";
@@ -22404,7 +22854,7 @@ async function prepareExtensionForLoad(port, filter = "") {
22404
22854
  const host = lanIPv4();
22405
22855
  if (!host) {
22406
22856
  console.log(
22407
- chalk168.yellow("could not determine the WSL IP for the extension")
22857
+ chalk169.yellow("could not determine the WSL IP for the extension")
22408
22858
  );
22409
22859
  await configureBackground(source, "127.0.0.1", port, filter);
22410
22860
  return source;
@@ -22415,7 +22865,7 @@ async function prepareExtensionForLoad(port, filter = "") {
22415
22865
  return WSL_WINDOWS_PATH;
22416
22866
  } catch {
22417
22867
  console.log(
22418
- chalk168.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
22868
+ chalk169.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
22419
22869
  );
22420
22870
  return source;
22421
22871
  }
@@ -22448,30 +22898,30 @@ async function netcap(options2) {
22448
22898
  let count8 = 0;
22449
22899
  const handler = createNetcapHandler({
22450
22900
  outPath,
22451
- onPing: () => console.log(chalk169.dim("ping from extension")),
22901
+ onPing: () => console.log(chalk170.dim("ping from extension")),
22452
22902
  onCapture: (entry) => {
22453
22903
  count8 += 1;
22454
22904
  console.log(
22455
- chalk169.green(`captured #${count8}`),
22456
- chalk169.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
22905
+ chalk170.green(`captured #${count8}`),
22906
+ chalk170.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
22457
22907
  );
22458
22908
  }
22459
22909
  });
22460
22910
  const server = createServer2(handler);
22461
22911
  server.listen(port, () => {
22462
22912
  console.log(
22463
- 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}`)
22464
22914
  );
22465
- console.log(chalk169.dim(`appending captures to ${outPath}`));
22915
+ console.log(chalk170.dim(`appending captures to ${outPath}`));
22466
22916
  if (filter)
22467
- console.log(chalk169.dim(`forwarding only URLs matching "${filter}"`));
22468
- console.log(chalk169.dim(`load the unpacked extension from ${extensionPath}`));
22469
- 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"));
22470
22920
  });
22471
22921
  process.on("SIGINT", () => {
22472
22922
  server.close();
22473
22923
  console.log(
22474
- chalk169.bold(
22924
+ chalk170.bold(
22475
22925
  `
22476
22926
  netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} to ${outPath}`
22477
22927
  )
@@ -22483,10 +22933,10 @@ netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} t
22483
22933
  // src/commands/netcap/netcapExtract.ts
22484
22934
  import { writeFileSync as writeFileSync33 } from "fs";
22485
22935
  import { join as join61 } from "path";
22486
- import chalk170 from "chalk";
22936
+ import chalk171 from "chalk";
22487
22937
 
22488
22938
  // src/commands/netcap/extractPostsFromCapture.ts
22489
- import { readFileSync as readFileSync39 } from "fs";
22939
+ import { readFileSync as readFileSync40 } from "fs";
22490
22940
 
22491
22941
  // src/commands/netcap/parseRscRows.ts
22492
22942
  var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
@@ -22882,7 +23332,7 @@ function extractVoyagerPosts(body) {
22882
23332
 
22883
23333
  // src/commands/netcap/extractPostsFromCapture.ts
22884
23334
  function captureEntries(captureFile) {
22885
- const lines2 = readFileSync39(captureFile, "utf8").split("\n").filter(Boolean);
23335
+ const lines2 = readFileSync40(captureFile, "utf8").split("\n").filter(Boolean);
22886
23336
  const entries = [];
22887
23337
  for (const line of lines2) {
22888
23338
  let entry;
@@ -22931,8 +23381,8 @@ function netcapExtract(file) {
22931
23381
  writeFileSync33(outFile, `${JSON.stringify(posts, null, 2)}
22932
23382
  `);
22933
23383
  console.log(
22934
- chalk170.green(`extracted ${posts.length} posts`),
22935
- chalk170.dim(`-> ${outFile}`)
23384
+ chalk171.green(`extracted ${posts.length} posts`),
23385
+ chalk171.dim(`-> ${outFile}`)
22936
23386
  );
22937
23387
  }
22938
23388
 
@@ -22953,7 +23403,7 @@ function registerNetcap(program2) {
22953
23403
  }
22954
23404
 
22955
23405
  // src/commands/news/add/index.ts
22956
- import chalk171 from "chalk";
23406
+ import chalk172 from "chalk";
22957
23407
  import enquirer8 from "enquirer";
22958
23408
  async function add2(url) {
22959
23409
  if (!url) {
@@ -22975,10 +23425,10 @@ async function add2(url) {
22975
23425
  const { orm } = await getReady();
22976
23426
  const added = await addFeed(orm, url);
22977
23427
  if (!added) {
22978
- console.log(chalk171.yellow("Feed already exists"));
23428
+ console.log(chalk172.yellow("Feed already exists"));
22979
23429
  return;
22980
23430
  }
22981
- console.log(chalk171.green(`Added feed: ${url}`));
23431
+ console.log(chalk172.green(`Added feed: ${url}`));
22982
23432
  }
22983
23433
 
22984
23434
  // src/commands/registerNews.ts
@@ -23025,7 +23475,7 @@ function registerPiHook(program2) {
23025
23475
  }
23026
23476
 
23027
23477
  // src/commands/prompts/printPromptsTable.ts
23028
- import chalk172 from "chalk";
23478
+ import chalk173 from "chalk";
23029
23479
  function truncate(str, max) {
23030
23480
  if (str.length <= max) return str;
23031
23481
  return `${str.slice(0, max - 1)}\u2026`;
@@ -23043,14 +23493,14 @@ function printPromptsTable(rows) {
23043
23493
  "Command".padEnd(commandWidth),
23044
23494
  "Repos"
23045
23495
  ].join(" ");
23046
- console.log(chalk172.dim(header));
23047
- console.log(chalk172.dim("-".repeat(header.length)));
23496
+ console.log(chalk173.dim(header));
23497
+ console.log(chalk173.dim("-".repeat(header.length)));
23048
23498
  for (const row of rows) {
23049
23499
  const count8 = String(row.count).padStart(countWidth);
23050
23500
  const tool = row.tool.padEnd(toolWidth);
23051
23501
  const command = truncate(row.command, 60).padEnd(commandWidth);
23052
23502
  console.log(
23053
- `${chalk172.yellow(count8)} ${tool} ${command} ${chalk172.dim(row.repos)}`
23503
+ `${chalk173.yellow(count8)} ${tool} ${command} ${chalk173.dim(row.repos)}`
23054
23504
  );
23055
23505
  }
23056
23506
  }
@@ -23456,7 +23906,7 @@ import { tmpdir as tmpdir6 } from "os";
23456
23906
  import { join as join63 } from "path";
23457
23907
 
23458
23908
  // src/commands/prs/loadCommentsCache.ts
23459
- 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";
23460
23910
  import { parse as parse2 } from "yaml";
23461
23911
 
23462
23912
  // src/commands/prs/commentsCachePath.ts
@@ -23476,24 +23926,24 @@ function commentsCachePath(org, repo, prNumber) {
23476
23926
  // src/commands/prs/loadCommentsCache.ts
23477
23927
  function loadCommentsCache(org, repo, prNumber) {
23478
23928
  const cachePath = commentsCachePath(org, repo, prNumber);
23479
- if (!existsSync53(cachePath)) {
23929
+ if (!existsSync54(cachePath)) {
23480
23930
  return null;
23481
23931
  }
23482
- const content = readFileSync40(cachePath, "utf8");
23932
+ const content = readFileSync41(cachePath, "utf8");
23483
23933
  return parse2(content);
23484
23934
  }
23485
23935
  function deleteCommentsCache(org, repo, prNumber) {
23486
23936
  const cachePath = commentsCachePath(org, repo, prNumber);
23487
- if (existsSync53(cachePath)) {
23937
+ if (existsSync54(cachePath)) {
23488
23938
  unlinkSync13(cachePath);
23489
23939
  console.log("No more unresolved line comments. Cache dropped.");
23490
23940
  }
23491
23941
  }
23492
23942
 
23493
23943
  // src/commands/prs/replyToComment.ts
23494
- import { spawnSync as spawnSync5 } from "child_process";
23944
+ import { spawnSync as spawnSync6 } from "child_process";
23495
23945
  function replyToComment(org, repo, prNumber, commentId, message3) {
23496
- const result = spawnSync5(
23946
+ const result = spawnSync6(
23497
23947
  "gh",
23498
23948
  [
23499
23949
  "api",
@@ -23717,13 +24167,13 @@ function agentFooter(unresolvedCount) {
23717
24167
  }
23718
24168
 
23719
24169
  // src/commands/prs/listComments/commentStyle.ts
23720
- import chalk173 from "chalk";
24170
+ import chalk174 from "chalk";
23721
24171
  var plain = (text18) => text18;
23722
24172
  function colouredState(state) {
23723
24173
  const label2 = `[${state}]`;
23724
- if (state === "APPROVED") return chalk173.green(label2);
23725
- if (state === "CHANGES_REQUESTED") return chalk173.red(label2);
23726
- 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);
23727
24177
  }
23728
24178
  function commentStyle() {
23729
24179
  if (isClaudeCode()) {
@@ -23737,9 +24187,9 @@ function commentStyle() {
23737
24187
  };
23738
24188
  }
23739
24189
  return {
23740
- cyan: chalk173.cyan,
23741
- bold: chalk173.bold,
23742
- dim: chalk173.dim,
24190
+ cyan: chalk174.cyan,
24191
+ bold: chalk174.bold,
24192
+ dim: chalk174.dim,
23743
24193
  state: colouredState,
23744
24194
  diffHunk: true,
23745
24195
  agent: false
@@ -23909,13 +24359,13 @@ import { execSync as execSync48 } from "child_process";
23909
24359
  import enquirer9 from "enquirer";
23910
24360
 
23911
24361
  // src/commands/prs/prs/displayPaginated/printPr.ts
23912
- import chalk174 from "chalk";
24362
+ import chalk175 from "chalk";
23913
24363
  var STATUS_MAP = {
23914
- MERGED: (pr) => pr.mergedAt ? { label: chalk174.magenta("merged"), date: pr.mergedAt } : null,
23915
- 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
23916
24366
  };
23917
24367
  function defaultStatus(pr) {
23918
- return { label: chalk174.green("opened"), date: pr.createdAt };
24368
+ return { label: chalk175.green("opened"), date: pr.createdAt };
23919
24369
  }
23920
24370
  function getStatus2(pr) {
23921
24371
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -23924,11 +24374,11 @@ function formatDate(dateStr) {
23924
24374
  return new Date(dateStr).toISOString().split("T")[0];
23925
24375
  }
23926
24376
  function formatPrHeader(pr, status3) {
23927
- 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)})`)}`;
23928
24378
  }
23929
24379
  function logPrDetails(pr) {
23930
24380
  console.log(
23931
- chalk174.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
24381
+ chalk175.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
23932
24382
  );
23933
24383
  console.log();
23934
24384
  }
@@ -24643,10 +25093,10 @@ function registerPrs(program2) {
24643
25093
  }
24644
25094
 
24645
25095
  // src/commands/ravendb/ravendbAuth.ts
24646
- import chalk180 from "chalk";
25096
+ import chalk181 from "chalk";
24647
25097
 
24648
25098
  // src/shared/createConnectionAuth.ts
24649
- import chalk175 from "chalk";
25099
+ import chalk176 from "chalk";
24650
25100
  function listConnections(connections, format) {
24651
25101
  if (connections.length === 0) {
24652
25102
  console.log("No connections configured.");
@@ -24659,7 +25109,7 @@ function listConnections(connections, format) {
24659
25109
  function removeConnection(connections, name, save) {
24660
25110
  const filtered = connections.filter((c) => c.name !== name);
24661
25111
  if (filtered.length === connections.length) {
24662
- console.error(chalk175.red(`Connection "${name}" not found.`));
25112
+ console.error(chalk176.red(`Connection "${name}" not found.`));
24663
25113
  process.exit(1);
24664
25114
  }
24665
25115
  save(filtered);
@@ -24705,15 +25155,15 @@ function saveConnections(connections) {
24705
25155
  }
24706
25156
 
24707
25157
  // src/commands/ravendb/promptConnection.ts
24708
- import chalk178 from "chalk";
25158
+ import chalk179 from "chalk";
24709
25159
 
24710
25160
  // src/commands/ravendb/selectOpSecret.ts
24711
- import chalk177 from "chalk";
25161
+ import chalk178 from "chalk";
24712
25162
  import Enquirer2 from "enquirer";
24713
25163
 
24714
25164
  // src/commands/ravendb/searchItems.ts
24715
25165
  import { execSync as execSync51 } from "child_process";
24716
- import chalk176 from "chalk";
25166
+ import chalk177 from "chalk";
24717
25167
  function opExec(args) {
24718
25168
  return execSync51(`op ${args}`, {
24719
25169
  encoding: "utf8",
@@ -24726,7 +25176,7 @@ function searchItems(search2) {
24726
25176
  items2 = JSON.parse(opExec("item list --format=json"));
24727
25177
  } catch {
24728
25178
  console.error(
24729
- chalk176.red(
25179
+ chalk177.red(
24730
25180
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
24731
25181
  )
24732
25182
  );
@@ -24740,7 +25190,7 @@ function getItemFields(itemId2) {
24740
25190
  const item = JSON.parse(opExec(`item get "${itemId2}" --format=json`));
24741
25191
  return item.fields.filter((f) => f.reference && f.label);
24742
25192
  } catch {
24743
- console.error(chalk176.red("Failed to get item details from 1Password."));
25193
+ console.error(chalk177.red("Failed to get item details from 1Password."));
24744
25194
  process.exit(1);
24745
25195
  }
24746
25196
  }
@@ -24759,7 +25209,7 @@ async function selectOpSecret(searchTerm) {
24759
25209
  }).run();
24760
25210
  const items2 = searchItems(search2);
24761
25211
  if (items2.length === 0) {
24762
- console.error(chalk177.red(`No items found matching "${search2}".`));
25212
+ console.error(chalk178.red(`No items found matching "${search2}".`));
24763
25213
  process.exit(1);
24764
25214
  }
24765
25215
  const itemId2 = await selectOne(
@@ -24768,7 +25218,7 @@ async function selectOpSecret(searchTerm) {
24768
25218
  );
24769
25219
  const fields = getItemFields(itemId2);
24770
25220
  if (fields.length === 0) {
24771
- 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."));
24772
25222
  process.exit(1);
24773
25223
  }
24774
25224
  const ref = await selectOne(
@@ -24782,7 +25232,7 @@ async function selectOpSecret(searchTerm) {
24782
25232
  async function promptConnection(existingNames) {
24783
25233
  const name = await promptInput("name", "Connection name:");
24784
25234
  if (existingNames.includes(name)) {
24785
- console.error(chalk178.red(`Connection "${name}" already exists.`));
25235
+ console.error(chalk179.red(`Connection "${name}" already exists.`));
24786
25236
  process.exit(1);
24787
25237
  }
24788
25238
  const url = await promptInput(
@@ -24791,22 +25241,22 @@ async function promptConnection(existingNames) {
24791
25241
  );
24792
25242
  const database = await promptInput("database", "Database name:");
24793
25243
  if (!name || !url || !database) {
24794
- console.error(chalk178.red("All fields are required."));
25244
+ console.error(chalk179.red("All fields are required."));
24795
25245
  process.exit(1);
24796
25246
  }
24797
25247
  const apiKeyRef = await selectOpSecret();
24798
- console.log(chalk178.dim(`Using: ${apiKeyRef}`));
25248
+ console.log(chalk179.dim(`Using: ${apiKeyRef}`));
24799
25249
  return { name, url, database, apiKeyRef };
24800
25250
  }
24801
25251
 
24802
25252
  // src/commands/ravendb/ravendbSetConnection.ts
24803
- import chalk179 from "chalk";
25253
+ import chalk180 from "chalk";
24804
25254
  function ravendbSetConnection(name) {
24805
25255
  const raw = loadGlobalConfigRaw();
24806
25256
  const ravendb = raw.ravendb ?? {};
24807
25257
  const connections = ravendb.connections ?? [];
24808
25258
  if (!connections.some((c) => c.name === name)) {
24809
- console.error(chalk179.red(`Connection "${name}" not found.`));
25259
+ console.error(chalk180.red(`Connection "${name}" not found.`));
24810
25260
  console.error(
24811
25261
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
24812
25262
  );
@@ -24822,16 +25272,16 @@ function ravendbSetConnection(name) {
24822
25272
  var ravendbAuth = createConnectionAuth({
24823
25273
  load: loadConnections,
24824
25274
  save: saveConnections,
24825
- 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}`,
24826
25276
  promptNew: promptConnection,
24827
25277
  onFirst: (c) => ravendbSetConnection(c.name)
24828
25278
  });
24829
25279
 
24830
25280
  // src/commands/ravendb/ravendbCollections.ts
24831
- import chalk184 from "chalk";
25281
+ import chalk185 from "chalk";
24832
25282
 
24833
25283
  // src/commands/ravendb/ravenFetch.ts
24834
- import chalk182 from "chalk";
25284
+ import chalk183 from "chalk";
24835
25285
 
24836
25286
  // src/commands/ravendb/getAccessToken.ts
24837
25287
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -24868,10 +25318,10 @@ ${errorText}`
24868
25318
 
24869
25319
  // src/commands/ravendb/resolveOpSecret.ts
24870
25320
  import { execSync as execSync52 } from "child_process";
24871
- import chalk181 from "chalk";
25321
+ import chalk182 from "chalk";
24872
25322
  function resolveOpSecret(reference) {
24873
25323
  if (!reference.startsWith("op://")) {
24874
- console.error(chalk181.red(`Invalid secret reference: must start with op://`));
25324
+ console.error(chalk182.red(`Invalid secret reference: must start with op://`));
24875
25325
  process.exit(1);
24876
25326
  }
24877
25327
  try {
@@ -24881,7 +25331,7 @@ function resolveOpSecret(reference) {
24881
25331
  }).trim();
24882
25332
  } catch {
24883
25333
  console.error(
24884
- chalk181.red(
25334
+ chalk182.red(
24885
25335
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
24886
25336
  )
24887
25337
  );
@@ -24908,7 +25358,7 @@ async function ravenFetch(connection, path80) {
24908
25358
  if (!response.ok) {
24909
25359
  const body = await response.text();
24910
25360
  console.error(
24911
- chalk182.red(`RavenDB error: ${response.status} ${response.statusText}`)
25361
+ chalk183.red(`RavenDB error: ${response.status} ${response.statusText}`)
24912
25362
  );
24913
25363
  console.error(body.substring(0, 500));
24914
25364
  process.exit(1);
@@ -24917,7 +25367,7 @@ async function ravenFetch(connection, path80) {
24917
25367
  }
24918
25368
 
24919
25369
  // src/commands/ravendb/resolveConnection.ts
24920
- import chalk183 from "chalk";
25370
+ import chalk184 from "chalk";
24921
25371
  function loadRavendb() {
24922
25372
  const raw = loadGlobalConfigRaw();
24923
25373
  const ravendb = raw.ravendb;
@@ -24931,7 +25381,7 @@ function resolveConnection(name) {
24931
25381
  const connectionName = name ?? defaultConnection;
24932
25382
  if (!connectionName) {
24933
25383
  console.error(
24934
- chalk183.red(
25384
+ chalk184.red(
24935
25385
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
24936
25386
  )
24937
25387
  );
@@ -24939,7 +25389,7 @@ function resolveConnection(name) {
24939
25389
  }
24940
25390
  const connection = connections.find((c) => c.name === connectionName);
24941
25391
  if (!connection) {
24942
- console.error(chalk183.red(`Connection "${connectionName}" not found.`));
25392
+ console.error(chalk184.red(`Connection "${connectionName}" not found.`));
24943
25393
  console.error(
24944
25394
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
24945
25395
  );
@@ -24970,15 +25420,15 @@ async function ravendbCollections(connectionName) {
24970
25420
  return;
24971
25421
  }
24972
25422
  for (const c of collections) {
24973
- console.log(`${chalk184.bold(c.Name)} ${c.CountOfDocuments} docs`);
25423
+ console.log(`${chalk185.bold(c.Name)} ${c.CountOfDocuments} docs`);
24974
25424
  }
24975
25425
  }
24976
25426
 
24977
25427
  // src/commands/ravendb/ravendbQuery.ts
24978
- import chalk186 from "chalk";
25428
+ import chalk187 from "chalk";
24979
25429
 
24980
25430
  // src/commands/ravendb/fetchAllPages.ts
24981
- import chalk185 from "chalk";
25431
+ import chalk186 from "chalk";
24982
25432
 
24983
25433
  // src/commands/ravendb/buildQueryPath.ts
24984
25434
  function buildQueryPath(opts) {
@@ -25016,7 +25466,7 @@ async function fetchAllPages(connection, opts) {
25016
25466
  allResults.push(...results);
25017
25467
  start3 += results.length;
25018
25468
  process.stderr.write(
25019
- `\r${chalk185.dim(`Fetched ${allResults.length}/${totalResults}`)}`
25469
+ `\r${chalk186.dim(`Fetched ${allResults.length}/${totalResults}`)}`
25020
25470
  );
25021
25471
  if (start3 >= totalResults) break;
25022
25472
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -25031,7 +25481,7 @@ async function fetchAllPages(connection, opts) {
25031
25481
  async function ravendbQuery(connectionName, collection, options2) {
25032
25482
  const resolved = resolveArgs(connectionName, collection);
25033
25483
  if (!resolved.collection && !options2.query) {
25034
- console.error(chalk186.red("Provide a collection name or --query filter."));
25484
+ console.error(chalk187.red("Provide a collection name or --query filter."));
25035
25485
  process.exit(1);
25036
25486
  }
25037
25487
  const { collection: col } = resolved;
@@ -25070,7 +25520,7 @@ import { spawn as spawn6 } from "child_process";
25070
25520
  import * as path42 from "path";
25071
25521
 
25072
25522
  // src/commands/refactor/logViolations.ts
25073
- import chalk187 from "chalk";
25523
+ import chalk188 from "chalk";
25074
25524
  var DEFAULT_MAX_LINES2 = 100;
25075
25525
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
25076
25526
  if (violations.length === 0) {
@@ -25079,43 +25529,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES2) {
25079
25529
  }
25080
25530
  return;
25081
25531
  }
25082
- console.error(chalk187.red(`
25532
+ console.error(chalk188.red(`
25083
25533
  Refactor check failed:
25084
25534
  `));
25085
- console.error(chalk187.red(` The following files exceed ${maxLines} lines:
25535
+ console.error(chalk188.red(` The following files exceed ${maxLines} lines:
25086
25536
  `));
25087
25537
  for (const violation of violations) {
25088
- console.error(chalk187.red(` ${violation.file} (${violation.lines} lines)`));
25538
+ console.error(chalk188.red(` ${violation.file} (${violation.lines} lines)`));
25089
25539
  }
25090
25540
  console.error(
25091
- chalk187.yellow(
25541
+ chalk188.yellow(
25092
25542
  `
25093
25543
  Each file needs to be sensibly refactored, or if there is no sensible
25094
25544
  way to refactor it, ignore it with:
25095
25545
  `
25096
25546
  )
25097
25547
  );
25098
- console.error(chalk187.gray(` assist refactor ignore <file>
25548
+ console.error(chalk188.gray(` assist refactor ignore <file>
25099
25549
  `));
25100
25550
  if (process.env.CLAUDECODE) {
25101
- console.error(chalk187.cyan(`
25551
+ console.error(chalk188.cyan(`
25102
25552
  ## Extracting Code to New Files
25103
25553
  `));
25104
25554
  console.error(
25105
- chalk187.cyan(
25555
+ chalk188.cyan(
25106
25556
  ` When extracting logic from one file to another, consider where the extracted code belongs:
25107
25557
  `
25108
25558
  )
25109
25559
  );
25110
25560
  console.error(
25111
- chalk187.cyan(
25561
+ chalk188.cyan(
25112
25562
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
25113
25563
  original file's domain, create a new folder containing both the original and extracted files.
25114
25564
  `
25115
25565
  )
25116
25566
  );
25117
25567
  console.error(
25118
- chalk187.cyan(
25568
+ chalk188.cyan(
25119
25569
  ` 2. Share common utilities: If the extracted code can be reused across multiple
25120
25570
  domains, move it to a common/shared folder.
25121
25571
  `
@@ -25271,7 +25721,7 @@ async function check(pattern2, options2) {
25271
25721
 
25272
25722
  // src/commands/refactor/extract/index.ts
25273
25723
  import path50 from "path";
25274
- import chalk190 from "chalk";
25724
+ import chalk191 from "chalk";
25275
25725
 
25276
25726
  // src/commands/refactor/extract/applyExtraction.ts
25277
25727
  import { SyntaxKind as SyntaxKind4 } from "ts-morph";
@@ -25870,23 +26320,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
25870
26320
 
25871
26321
  // src/commands/refactor/extract/displayPlan.ts
25872
26322
  import path46 from "path";
25873
- import chalk188 from "chalk";
26323
+ import chalk189 from "chalk";
25874
26324
  function section2(title) {
25875
26325
  return `
25876
- ${chalk188.cyan(title)}`;
26326
+ ${chalk189.cyan(title)}`;
25877
26327
  }
25878
26328
  function displayImporters(plan2, cwd) {
25879
26329
  if (plan2.importersToUpdate.length === 0) return;
25880
26330
  console.log(section2("Update importers:"));
25881
26331
  for (const imp of plan2.importersToUpdate) {
25882
26332
  const rel = path46.relative(cwd, imp.file.getFilePath());
25883
- console.log(` ${chalk188.dim(rel)}: \u2192 import from "${imp.relPath}"`);
26333
+ console.log(` ${chalk189.dim(rel)}: \u2192 import from "${imp.relPath}"`);
25884
26334
  }
25885
26335
  }
25886
26336
  function displayPlan(functionName, relDest, plan2, cwd) {
25887
- console.log(chalk188.bold(`Extract: ${functionName} \u2192 ${relDest}
26337
+ console.log(chalk189.bold(`Extract: ${functionName} \u2192 ${relDest}
25888
26338
  `));
25889
- console.log(` ${chalk188.cyan("Functions to move:")}`);
26339
+ console.log(` ${chalk189.cyan("Functions to move:")}`);
25890
26340
  for (const name of plan2.extractedNames) {
25891
26341
  console.log(` ${name}`);
25892
26342
  }
@@ -25920,7 +26370,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
25920
26370
 
25921
26371
  // src/commands/refactor/extract/loadProjectFile.ts
25922
26372
  import path49 from "path";
25923
- import chalk189 from "chalk";
26373
+ import chalk190 from "chalk";
25924
26374
  import { Project as Project4 } from "ts-morph";
25925
26375
 
25926
26376
  // src/commands/refactor/extract/findTsConfig.ts
@@ -26012,7 +26462,7 @@ function loadProjectFile(file) {
26012
26462
  });
26013
26463
  const sourceFile = project.getSourceFile(sourcePath);
26014
26464
  if (!sourceFile) {
26015
- console.log(chalk189.red(`File not found in project: ${file}`));
26465
+ console.log(chalk190.red(`File not found in project: ${file}`));
26016
26466
  process.exit(1);
26017
26467
  }
26018
26468
  return { project, sourceFile };
@@ -26035,19 +26485,19 @@ async function extract(file, functionName, destination, options2 = {}) {
26035
26485
  displayPlan(functionName, relDest, plan2, cwd);
26036
26486
  if (options2.apply) {
26037
26487
  await applyExtraction(functionName, sourceFile, destPath, plan2, project);
26038
- console.log(chalk190.green("\nExtraction complete"));
26488
+ console.log(chalk191.green("\nExtraction complete"));
26039
26489
  } else {
26040
- console.log(chalk190.dim("\nDry run. Use --apply to execute."));
26490
+ console.log(chalk191.dim("\nDry run. Use --apply to execute."));
26041
26491
  }
26042
26492
  }
26043
26493
 
26044
26494
  // src/commands/refactor/ignore.ts
26045
26495
  import fs33 from "fs";
26046
- import chalk191 from "chalk";
26496
+ import chalk192 from "chalk";
26047
26497
  var REFACTOR_YML_PATH2 = "refactor.yml";
26048
26498
  function ignore2(file) {
26049
26499
  if (!fs33.existsSync(file)) {
26050
- console.error(chalk191.red(`Error: File does not exist: ${file}`));
26500
+ console.error(chalk192.red(`Error: File does not exist: ${file}`));
26051
26501
  process.exit(1);
26052
26502
  }
26053
26503
  const content = fs33.readFileSync(file, "utf8");
@@ -26063,7 +26513,7 @@ function ignore2(file) {
26063
26513
  fs33.writeFileSync(REFACTOR_YML_PATH2, entry);
26064
26514
  }
26065
26515
  console.log(
26066
- chalk191.green(
26516
+ chalk192.green(
26067
26517
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
26068
26518
  )
26069
26519
  );
@@ -26072,12 +26522,12 @@ function ignore2(file) {
26072
26522
  // src/commands/refactor/rename/index.ts
26073
26523
  import fs36 from "fs";
26074
26524
  import path55 from "path";
26075
- import chalk194 from "chalk";
26525
+ import chalk195 from "chalk";
26076
26526
 
26077
26527
  // src/commands/refactor/rename/applyRename.ts
26078
26528
  import fs35 from "fs";
26079
26529
  import path52 from "path";
26080
- import chalk192 from "chalk";
26530
+ import chalk193 from "chalk";
26081
26531
 
26082
26532
  // src/commands/refactor/restructure/computeRewrites/index.ts
26083
26533
  import path51 from "path";
@@ -26182,13 +26632,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
26182
26632
  const updatedContents = applyRewrites(rewrites);
26183
26633
  for (const [file, content] of updatedContents) {
26184
26634
  fs35.writeFileSync(file, content, "utf8");
26185
- console.log(chalk192.cyan(` Updated imports in ${path52.relative(cwd, file)}`));
26635
+ console.log(chalk193.cyan(` Updated imports in ${path52.relative(cwd, file)}`));
26186
26636
  }
26187
26637
  const destDir = path52.dirname(destPath);
26188
26638
  if (!fs35.existsSync(destDir)) fs35.mkdirSync(destDir, { recursive: true });
26189
26639
  fs35.renameSync(sourcePath, destPath);
26190
26640
  console.log(
26191
- chalk192.white(
26641
+ chalk193.white(
26192
26642
  ` Moved ${path52.relative(cwd, sourcePath)} \u2192 ${path52.relative(cwd, destPath)}`
26193
26643
  )
26194
26644
  );
@@ -26275,16 +26725,16 @@ function computeRenameRewrites(sourcePath, destPath) {
26275
26725
 
26276
26726
  // src/commands/refactor/rename/printRenamePreview.ts
26277
26727
  import path54 from "path";
26278
- import chalk193 from "chalk";
26728
+ import chalk194 from "chalk";
26279
26729
  function printRenamePreview(rewrites, cwd) {
26280
26730
  for (const rewrite of rewrites) {
26281
26731
  console.log(
26282
- chalk193.dim(
26732
+ chalk194.dim(
26283
26733
  ` ${path54.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
26284
26734
  )
26285
26735
  );
26286
26736
  }
26287
- console.log(chalk193.dim("Dry run. Use --apply to execute."));
26737
+ console.log(chalk194.dim("Dry run. Use --apply to execute."));
26288
26738
  }
26289
26739
 
26290
26740
  // src/commands/refactor/rename/index.ts
@@ -26295,20 +26745,20 @@ async function rename(source, destination, options2 = {}) {
26295
26745
  const relSource = path55.relative(cwd, sourcePath);
26296
26746
  const relDest = path55.relative(cwd, destPath);
26297
26747
  if (!fs36.existsSync(sourcePath)) {
26298
- console.log(chalk194.red(`File not found: ${source}`));
26748
+ console.log(chalk195.red(`File not found: ${source}`));
26299
26749
  process.exit(1);
26300
26750
  }
26301
26751
  if (destPath !== sourcePath && fs36.existsSync(destPath)) {
26302
- console.log(chalk194.red(`Destination already exists: ${destination}`));
26752
+ console.log(chalk195.red(`Destination already exists: ${destination}`));
26303
26753
  process.exit(1);
26304
26754
  }
26305
- console.log(chalk194.bold(`Rename: ${relSource} \u2192 ${relDest}`));
26306
- console.log(chalk194.dim("Loading project..."));
26307
- 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..."));
26308
26758
  const rewrites = computeRenameRewrites(sourcePath, destPath);
26309
26759
  const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
26310
26760
  console.log(
26311
- chalk194.dim(
26761
+ chalk195.dim(
26312
26762
  `${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
26313
26763
  )
26314
26764
  );
@@ -26317,11 +26767,11 @@ async function rename(source, destination, options2 = {}) {
26317
26767
  return;
26318
26768
  }
26319
26769
  applyRename(rewrites, sourcePath, destPath, cwd);
26320
- console.log(chalk194.green("Done"));
26770
+ console.log(chalk195.green("Done"));
26321
26771
  }
26322
26772
 
26323
26773
  // src/commands/refactor/renameSymbol/index.ts
26324
- import chalk195 from "chalk";
26774
+ import chalk196 from "chalk";
26325
26775
 
26326
26776
  // src/commands/refactor/renameSymbol/findSymbol.ts
26327
26777
  import { SyntaxKind as SyntaxKind15 } from "ts-morph";
@@ -26367,33 +26817,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
26367
26817
  const { project, sourceFile } = loadProjectFile(file);
26368
26818
  const symbol = findSymbol(sourceFile, oldName);
26369
26819
  if (!symbol) {
26370
- console.log(chalk195.red(`Symbol "${oldName}" not found in ${file}`));
26820
+ console.log(chalk196.red(`Symbol "${oldName}" not found in ${file}`));
26371
26821
  process.exit(1);
26372
26822
  }
26373
26823
  const grouped = groupReferences(symbol, cwd);
26374
26824
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
26375
26825
  console.log(
26376
- chalk195.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
26826
+ chalk196.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
26377
26827
  `)
26378
26828
  );
26379
26829
  for (const [refFile, lines2] of grouped) {
26380
26830
  console.log(
26381
- ` ${chalk195.dim(refFile)}: lines ${chalk195.cyan(lines2.join(", "))}`
26831
+ ` ${chalk196.dim(refFile)}: lines ${chalk196.cyan(lines2.join(", "))}`
26382
26832
  );
26383
26833
  }
26384
26834
  if (options2.apply) {
26385
26835
  symbol.rename(newName);
26386
26836
  await project.save();
26387
- console.log(chalk195.green(`
26837
+ console.log(chalk196.green(`
26388
26838
  Renamed ${oldName} \u2192 ${newName}`));
26389
26839
  } else {
26390
- console.log(chalk195.dim("\nDry run. Use --apply to execute."));
26840
+ console.log(chalk196.dim("\nDry run. Use --apply to execute."));
26391
26841
  }
26392
26842
  }
26393
26843
 
26394
26844
  // src/commands/refactor/restructure/index.ts
26395
26845
  import path63 from "path";
26396
- import chalk198 from "chalk";
26846
+ import chalk199 from "chalk";
26397
26847
 
26398
26848
  // src/commands/refactor/restructure/clusterDirectories.ts
26399
26849
  import path57 from "path";
@@ -26472,50 +26922,50 @@ function clusterFiles(graph) {
26472
26922
 
26473
26923
  // src/commands/refactor/restructure/displayPlan.ts
26474
26924
  import path59 from "path";
26475
- import chalk196 from "chalk";
26925
+ import chalk197 from "chalk";
26476
26926
  function relPath(filePath) {
26477
26927
  return path59.relative(process.cwd(), filePath);
26478
26928
  }
26479
26929
  function displayMoves(plan2) {
26480
26930
  if (plan2.moves.length === 0) return;
26481
- console.log(chalk196.bold("\nFile moves:"));
26931
+ console.log(chalk197.bold("\nFile moves:"));
26482
26932
  for (const move2 of plan2.moves) {
26483
26933
  console.log(
26484
- ` ${chalk196.red(relPath(move2.from))} \u2192 ${chalk196.green(relPath(move2.to))}`
26934
+ ` ${chalk197.red(relPath(move2.from))} \u2192 ${chalk197.green(relPath(move2.to))}`
26485
26935
  );
26486
- console.log(chalk196.dim(` ${move2.reason}`));
26936
+ console.log(chalk197.dim(` ${move2.reason}`));
26487
26937
  }
26488
26938
  }
26489
26939
  function displayRewrites(rewrites) {
26490
26940
  if (rewrites.length === 0) return;
26491
26941
  const affectedFiles = new Set(rewrites.map((r) => r.file));
26492
- console.log(chalk196.bold(`
26942
+ console.log(chalk197.bold(`
26493
26943
  Import rewrites (${affectedFiles.size} files):`));
26494
26944
  for (const file of affectedFiles) {
26495
- console.log(` ${chalk196.cyan(relPath(file))}:`);
26945
+ console.log(` ${chalk197.cyan(relPath(file))}:`);
26496
26946
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
26497
26947
  (r) => r.file === file
26498
26948
  )) {
26499
26949
  console.log(
26500
- ` ${chalk196.red(`"${oldSpecifier}"`)} \u2192 ${chalk196.green(`"${newSpecifier}"`)}`
26950
+ ` ${chalk197.red(`"${oldSpecifier}"`)} \u2192 ${chalk197.green(`"${newSpecifier}"`)}`
26501
26951
  );
26502
26952
  }
26503
26953
  }
26504
26954
  }
26505
26955
  function displayPlan2(plan2) {
26506
26956
  if (plan2.warnings.length > 0) {
26507
- console.log(chalk196.yellow("\nWarnings:"));
26508
- 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}`));
26509
26959
  }
26510
26960
  if (plan2.newDirectories.length > 0) {
26511
- console.log(chalk196.bold("\nNew directories:"));
26961
+ console.log(chalk197.bold("\nNew directories:"));
26512
26962
  for (const dir of plan2.newDirectories)
26513
- console.log(chalk196.green(` ${dir}/`));
26963
+ console.log(chalk197.green(` ${dir}/`));
26514
26964
  }
26515
26965
  displayMoves(plan2);
26516
26966
  displayRewrites(plan2.rewrites);
26517
26967
  console.log(
26518
- chalk196.dim(
26968
+ chalk197.dim(
26519
26969
  `
26520
26970
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
26521
26971
  )
@@ -26525,18 +26975,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
26525
26975
  // src/commands/refactor/restructure/executePlan.ts
26526
26976
  import fs37 from "fs";
26527
26977
  import path60 from "path";
26528
- import chalk197 from "chalk";
26978
+ import chalk198 from "chalk";
26529
26979
  function executePlan(plan2) {
26530
26980
  const updatedContents = applyRewrites(plan2.rewrites);
26531
26981
  for (const [file, content] of updatedContents) {
26532
26982
  fs37.writeFileSync(file, content, "utf8");
26533
26983
  console.log(
26534
- chalk197.cyan(` Rewrote imports in ${path60.relative(process.cwd(), file)}`)
26984
+ chalk198.cyan(` Rewrote imports in ${path60.relative(process.cwd(), file)}`)
26535
26985
  );
26536
26986
  }
26537
26987
  for (const dir of plan2.newDirectories) {
26538
26988
  fs37.mkdirSync(dir, { recursive: true });
26539
- console.log(chalk197.green(` Created ${path60.relative(process.cwd(), dir)}/`));
26989
+ console.log(chalk198.green(` Created ${path60.relative(process.cwd(), dir)}/`));
26540
26990
  }
26541
26991
  for (const move2 of plan2.moves) {
26542
26992
  const targetDir = path60.dirname(move2.to);
@@ -26545,7 +26995,7 @@ function executePlan(plan2) {
26545
26995
  }
26546
26996
  fs37.renameSync(move2.from, move2.to);
26547
26997
  console.log(
26548
- chalk197.white(
26998
+ chalk198.white(
26549
26999
  ` Moved ${path60.relative(process.cwd(), move2.from)} \u2192 ${path60.relative(process.cwd(), move2.to)}`
26550
27000
  )
26551
27001
  );
@@ -26560,7 +27010,7 @@ function removeEmptyDirectories(dirs) {
26560
27010
  if (entries.length === 0) {
26561
27011
  fs37.rmdirSync(dir);
26562
27012
  console.log(
26563
- chalk197.dim(
27013
+ chalk198.dim(
26564
27014
  ` Removed empty directory ${path60.relative(process.cwd(), dir)}`
26565
27015
  )
26566
27016
  );
@@ -26693,22 +27143,22 @@ async function restructure(pattern2, options2 = {}) {
26693
27143
  const targetPattern = pattern2 ?? "src";
26694
27144
  const files = findSourceFiles2(targetPattern);
26695
27145
  if (files.length === 0) {
26696
- console.log(chalk198.yellow("No files found matching pattern"));
27146
+ console.log(chalk199.yellow("No files found matching pattern"));
26697
27147
  return;
26698
27148
  }
26699
27149
  const tsConfigPath = findTsConfig(path63.resolve(files[0]));
26700
27150
  const plan2 = buildPlan3(files, tsConfigPath);
26701
27151
  if (plan2.moves.length === 0) {
26702
- console.log(chalk198.green("No restructuring needed"));
27152
+ console.log(chalk199.green("No restructuring needed"));
26703
27153
  return;
26704
27154
  }
26705
27155
  displayPlan2(plan2);
26706
27156
  if (options2.apply) {
26707
- console.log(chalk198.bold("\nApplying changes..."));
27157
+ console.log(chalk199.bold("\nApplying changes..."));
26708
27158
  executePlan(plan2);
26709
- console.log(chalk198.green("\nRestructuring complete"));
27159
+ console.log(chalk199.green("\nRestructuring complete"));
26710
27160
  } else {
26711
- console.log(chalk198.dim("\nDry run. Use --apply to execute."));
27161
+ console.log(chalk199.dim("\nDry run. Use --apply to execute."));
26712
27162
  }
26713
27163
  }
26714
27164
 
@@ -27031,7 +27481,7 @@ function gatherContext() {
27031
27481
  }
27032
27482
 
27033
27483
  // src/commands/review/postReviewToPr.ts
27034
- import { readFileSync as readFileSync41 } from "fs";
27484
+ import { readFileSync as readFileSync42 } from "fs";
27035
27485
 
27036
27486
  // src/commands/review/carriedUnanchoredFindings.ts
27037
27487
  function carriedUnanchoredFindings(unanchored) {
@@ -27366,18 +27816,18 @@ function partitionFindingsByDiff(findings, index3) {
27366
27816
  }
27367
27817
 
27368
27818
  // src/commands/review/warnOutOfDiff.ts
27369
- import chalk199 from "chalk";
27819
+ import chalk200 from "chalk";
27370
27820
  function warnOutOfDiff(outOfDiff) {
27371
27821
  if (outOfDiff.length === 0) return;
27372
27822
  console.warn(
27373
- chalk199.yellow(
27823
+ chalk200.yellow(
27374
27824
  `Moved ${outOfDiff.length} finding(s) whose lines fall outside the PR diff into the review body (GitHub cannot anchor a comment on these):`
27375
27825
  )
27376
27826
  );
27377
27827
  for (const finding of outOfDiff) {
27378
27828
  const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
27379
27829
  console.warn(
27380
- ` ${chalk199.yellow("\xB7")} ${finding.title} ${chalk199.dim(
27830
+ ` ${chalk200.yellow("\xB7")} ${finding.title} ${chalk200.dim(
27381
27831
  `(${finding.file}:${range})`
27382
27832
  )}`
27383
27833
  );
@@ -27401,18 +27851,18 @@ function selectInDiffFindings(lineBound, prDiff) {
27401
27851
  }
27402
27852
 
27403
27853
  // src/commands/review/warnUnlocated.ts
27404
- import chalk200 from "chalk";
27854
+ import chalk201 from "chalk";
27405
27855
  function warnUnlocated(unlocated) {
27406
27856
  if (unlocated.length === 0) return;
27407
27857
  console.warn(
27408
- chalk200.yellow(
27858
+ chalk201.yellow(
27409
27859
  `Moved ${unlocated.length} finding(s) without a parseable file:line into the review body:`
27410
27860
  )
27411
27861
  );
27412
27862
  for (const finding of unlocated) {
27413
- const where = finding.location || chalk200.dim("missing");
27863
+ const where = finding.location || chalk201.dim("missing");
27414
27864
  console.warn(
27415
- ` ${chalk200.yellow("\xB7")} ${finding.title} ${chalk200.dim(`(${where})`)}`
27865
+ ` ${chalk201.yellow("\xB7")} ${finding.title} ${chalk201.dim(`(${where})`)}`
27416
27866
  );
27417
27867
  }
27418
27868
  }
@@ -27479,7 +27929,7 @@ async function confirmPost(prNumber, work, options2) {
27479
27929
  return promptConfirm(`Post ${work} to PR #${prNumber}?`, false);
27480
27930
  }
27481
27931
  async function postFindingsToPr(prInfo, synthesisPath, options2) {
27482
- const markdown = readFileSync41(synthesisPath, "utf8");
27932
+ const markdown = readFileSync42(synthesisPath, "utf8");
27483
27933
  const { inDiff, unanchored } = selectPostableFindings(markdown, prInfo);
27484
27934
  const carried = carriedUnanchoredFindings(unanchored);
27485
27935
  if (inDiff.length === 0 && carried.length === 0) return NOTHING_POSTED;
@@ -27615,10 +28065,10 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
27615
28065
  }
27616
28066
 
27617
28067
  // src/commands/review/prepareReviewDir.ts
27618
- 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";
27619
28069
  function clearReviewFiles(paths) {
27620
28070
  for (const path80 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
27621
- if (existsSync54(path80)) unlinkSync17(path80);
28071
+ if (existsSync55(path80)) unlinkSync17(path80);
27622
28072
  }
27623
28073
  }
27624
28074
  function prepareReviewDir(paths, requestBody, force) {
@@ -27744,9 +28194,9 @@ var MultiSpinner = class {
27744
28194
  };
27745
28195
 
27746
28196
  // src/commands/review/ensureCodexAvailable.ts
27747
- import { spawnSync as spawnSync6 } from "child_process";
28197
+ import { spawnSync as spawnSync7 } from "child_process";
27748
28198
  function runNpmInstall() {
27749
- const result = spawnSync6("npm", ["install", "-g", "@openai/codex"], {
28199
+ const result = spawnSync7("npm", ["install", "-g", "@openai/codex"], {
27750
28200
  stdio: "inherit",
27751
28201
  shell: true
27752
28202
  });
@@ -27845,7 +28295,7 @@ function printReviewerFailures(results) {
27845
28295
  }
27846
28296
 
27847
28297
  // src/commands/review/runAndSynthesise.ts
27848
- import { existsSync as existsSync56, unlinkSync as unlinkSync19 } from "fs";
28298
+ import { existsSync as existsSync57, unlinkSync as unlinkSync19 } from "fs";
27849
28299
 
27850
28300
  // src/commands/review/buildReviewerStdin.ts
27851
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.
@@ -28274,7 +28724,7 @@ function resolveClaude(args) {
28274
28724
  }
28275
28725
 
28276
28726
  // src/commands/review/runCodexReviewer.ts
28277
- import { existsSync as existsSync55, unlinkSync as unlinkSync18 } from "fs";
28727
+ import { existsSync as existsSync56, unlinkSync as unlinkSync18 } from "fs";
28278
28728
 
28279
28729
  // src/commands/review/parseCodexEvent.ts
28280
28730
  function isItemStarted(value) {
@@ -28326,7 +28776,7 @@ async function runCodexReviewer(spec) {
28326
28776
  reportReviewerToolUse(spec.name, event, spinner);
28327
28777
  }
28328
28778
  });
28329
- if (result.exitCode !== 0 && existsSync55(spec.outputPath)) {
28779
+ if (result.exitCode !== 0 && existsSync56(spec.outputPath)) {
28330
28780
  unlinkSync18(spec.outputPath);
28331
28781
  }
28332
28782
  return finaliseReviewerRun({ ...spec, command }, spinner, result);
@@ -28368,7 +28818,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
28368
28818
  }
28369
28819
 
28370
28820
  // src/commands/review/synthesise.ts
28371
- import { readFileSync as readFileSync42 } from "fs";
28821
+ import { readFileSync as readFileSync43 } from "fs";
28372
28822
 
28373
28823
  // src/commands/review/buildSynthesisStdin.ts
28374
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.
@@ -28433,7 +28883,7 @@ Files:
28433
28883
 
28434
28884
  // src/commands/review/synthesise.ts
28435
28885
  function printSummary2(synthesisPath) {
28436
- const markdown = readFileSync42(synthesisPath, "utf8");
28886
+ const markdown = readFileSync43(synthesisPath, "utf8");
28437
28887
  console.log("");
28438
28888
  console.log(buildReviewSummary(markdown));
28439
28889
  console.log("");
@@ -28481,7 +28931,7 @@ async function runAndSynthesise(args) {
28481
28931
  console.error("Both reviewers failed; skipping synthesis.");
28482
28932
  return { ok: false, failures };
28483
28933
  }
28484
- if (anyFresh && existsSync56(paths.synthesisPath)) {
28934
+ if (anyFresh && existsSync57(paths.synthesisPath)) {
28485
28935
  unlinkSync19(paths.synthesisPath);
28486
28936
  }
28487
28937
  const synthesisResult = await synthesise(paths, { multi });
@@ -28667,7 +29117,7 @@ function registerReview(program2) {
28667
29117
  }
28668
29118
 
28669
29119
  // src/commands/seq/seqAuth.ts
28670
- import chalk202 from "chalk";
29120
+ import chalk203 from "chalk";
28671
29121
 
28672
29122
  // src/commands/seq/loadConnections.ts
28673
29123
  function loadConnections2() {
@@ -28696,10 +29146,10 @@ function setDefaultConnection(name) {
28696
29146
  }
28697
29147
 
28698
29148
  // src/shared/assertUniqueName.ts
28699
- import chalk201 from "chalk";
29149
+ import chalk202 from "chalk";
28700
29150
  function assertUniqueName(existingNames, name) {
28701
29151
  if (existingNames.includes(name)) {
28702
- console.error(chalk201.red(`Connection "${name}" already exists.`));
29152
+ console.error(chalk202.red(`Connection "${name}" already exists.`));
28703
29153
  process.exit(1);
28704
29154
  }
28705
29155
  }
@@ -28717,16 +29167,16 @@ async function promptConnection2(existingNames) {
28717
29167
  var seqAuth = createConnectionAuth({
28718
29168
  load: loadConnections2,
28719
29169
  save: saveConnections2,
28720
- format: (c) => `${chalk202.bold(c.name)} ${c.url}`,
29170
+ format: (c) => `${chalk203.bold(c.name)} ${c.url}`,
28721
29171
  promptNew: promptConnection2,
28722
29172
  onFirst: (c) => setDefaultConnection(c.name)
28723
29173
  });
28724
29174
 
28725
29175
  // src/commands/seq/seqQuery.ts
28726
- import chalk206 from "chalk";
29176
+ import chalk207 from "chalk";
28727
29177
 
28728
29178
  // src/commands/seq/fetchSeq.ts
28729
- import chalk203 from "chalk";
29179
+ import chalk204 from "chalk";
28730
29180
  async function fetchSeq(conn, path80, params) {
28731
29181
  const url = `${conn.url}${path80}?${params}`;
28732
29182
  const response = await fetch(url, {
@@ -28737,7 +29187,7 @@ async function fetchSeq(conn, path80, params) {
28737
29187
  });
28738
29188
  if (!response.ok) {
28739
29189
  const body = await response.text();
28740
- console.error(chalk203.red(`Seq returned ${response.status}: ${body}`));
29190
+ console.error(chalk204.red(`Seq returned ${response.status}: ${body}`));
28741
29191
  process.exit(1);
28742
29192
  }
28743
29193
  return response;
@@ -28796,23 +29246,23 @@ async function fetchSeqEvents(conn, params) {
28796
29246
  }
28797
29247
 
28798
29248
  // src/commands/seq/formatEvent.ts
28799
- import chalk204 from "chalk";
29249
+ import chalk205 from "chalk";
28800
29250
  function levelColor(level) {
28801
29251
  switch (level) {
28802
29252
  case "Fatal":
28803
- return chalk204.bgRed.white;
29253
+ return chalk205.bgRed.white;
28804
29254
  case "Error":
28805
- return chalk204.red;
29255
+ return chalk205.red;
28806
29256
  case "Warning":
28807
- return chalk204.yellow;
29257
+ return chalk205.yellow;
28808
29258
  case "Information":
28809
- return chalk204.cyan;
29259
+ return chalk205.cyan;
28810
29260
  case "Debug":
28811
- return chalk204.gray;
29261
+ return chalk205.gray;
28812
29262
  case "Verbose":
28813
- return chalk204.dim;
29263
+ return chalk205.dim;
28814
29264
  default:
28815
- return chalk204.white;
29265
+ return chalk205.white;
28816
29266
  }
28817
29267
  }
28818
29268
  function levelAbbrev(level) {
@@ -28853,12 +29303,12 @@ function formatTimestamp(iso) {
28853
29303
  function formatEvent(event) {
28854
29304
  const color = levelColor(event.Level);
28855
29305
  const abbrev = levelAbbrev(event.Level);
28856
- const ts8 = chalk204.dim(formatTimestamp(event.Timestamp));
29306
+ const ts8 = chalk205.dim(formatTimestamp(event.Timestamp));
28857
29307
  const msg = renderMessage(event);
28858
29308
  const lines2 = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
28859
29309
  if (event.Exception) {
28860
29310
  for (const line of event.Exception.split("\n")) {
28861
- lines2.push(chalk204.red(` ${line}`));
29311
+ lines2.push(chalk205.red(` ${line}`));
28862
29312
  }
28863
29313
  }
28864
29314
  return lines2.join("\n");
@@ -28891,11 +29341,11 @@ function rejectTimestampFilter(filter) {
28891
29341
  }
28892
29342
 
28893
29343
  // src/shared/resolveNamedConnection.ts
28894
- import chalk205 from "chalk";
29344
+ import chalk206 from "chalk";
28895
29345
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
28896
29346
  if (connections.length === 0) {
28897
29347
  console.error(
28898
- chalk205.red(
29348
+ chalk206.red(
28899
29349
  `No ${kind} connections configured. Run '${authCommand}' first.`
28900
29350
  )
28901
29351
  );
@@ -28904,7 +29354,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
28904
29354
  const target = requested ?? defaultName ?? connections[0].name;
28905
29355
  const connection = connections.find((c) => c.name === target);
28906
29356
  if (!connection) {
28907
- console.error(chalk205.red(`${kind} connection "${target}" not found.`));
29357
+ console.error(chalk206.red(`${kind} connection "${target}" not found.`));
28908
29358
  process.exit(1);
28909
29359
  }
28910
29360
  return connection;
@@ -28933,7 +29383,7 @@ async function seqQuery(filter, options2) {
28933
29383
  new URLSearchParams({ filter, count: String(count8) })
28934
29384
  );
28935
29385
  if (events.length === 0) {
28936
- console.log(chalk206.yellow("No events found."));
29386
+ console.log(chalk207.yellow("No events found."));
28937
29387
  return;
28938
29388
  }
28939
29389
  if (options2.json) {
@@ -28944,11 +29394,11 @@ async function seqQuery(filter, options2) {
28944
29394
  for (const event of chronological) {
28945
29395
  console.log(formatEvent(event));
28946
29396
  }
28947
- console.log(chalk206.dim(`
29397
+ console.log(chalk207.dim(`
28948
29398
  ${events.length} events`));
28949
29399
  if (events.length >= count8) {
28950
29400
  console.log(
28951
- chalk206.yellow(
29401
+ chalk207.yellow(
28952
29402
  `Results limited to ${count8}. Use --count to retrieve more.`
28953
29403
  )
28954
29404
  );
@@ -28956,10 +29406,10 @@ ${events.length} events`));
28956
29406
  }
28957
29407
 
28958
29408
  // src/shared/setNamedDefaultConnection.ts
28959
- import chalk207 from "chalk";
29409
+ import chalk208 from "chalk";
28960
29410
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
28961
29411
  if (!connections.find((c) => c.name === name)) {
28962
- console.error(chalk207.red(`Connection "${name}" not found.`));
29412
+ console.error(chalk208.red(`Connection "${name}" not found.`));
28963
29413
  process.exit(1);
28964
29414
  }
28965
29415
  setDefault(name);
@@ -29008,7 +29458,7 @@ function registerSignal(program2) {
29008
29458
  }
29009
29459
 
29010
29460
  // src/commands/sql/sqlAuth.ts
29011
- import chalk209 from "chalk";
29461
+ import chalk210 from "chalk";
29012
29462
 
29013
29463
  // src/commands/sql/loadConnections.ts
29014
29464
  function loadConnections3() {
@@ -29037,7 +29487,7 @@ function setDefaultConnection2(name) {
29037
29487
  }
29038
29488
 
29039
29489
  // src/commands/sql/promptConnection.ts
29040
- import chalk208 from "chalk";
29490
+ import chalk209 from "chalk";
29041
29491
  async function promptConnection3(existingNames) {
29042
29492
  const name = await promptInput("name", "Connection name:", "default");
29043
29493
  assertUniqueName(existingNames, name);
@@ -29045,7 +29495,7 @@ async function promptConnection3(existingNames) {
29045
29495
  const portStr = await promptInput("port", "Port:", "1433");
29046
29496
  const port = Number.parseInt(portStr, 10);
29047
29497
  if (!Number.isFinite(port)) {
29048
- console.error(chalk208.red(`Invalid port "${portStr}".`));
29498
+ console.error(chalk209.red(`Invalid port "${portStr}".`));
29049
29499
  process.exit(1);
29050
29500
  }
29051
29501
  const user = await promptInput("user", "User:");
@@ -29058,13 +29508,13 @@ async function promptConnection3(existingNames) {
29058
29508
  var sqlAuth = createConnectionAuth({
29059
29509
  load: loadConnections3,
29060
29510
  save: saveConnections3,
29061
- 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})`,
29062
29512
  promptNew: promptConnection3,
29063
29513
  onFirst: (c) => setDefaultConnection2(c.name)
29064
29514
  });
29065
29515
 
29066
29516
  // src/commands/sql/printTable.ts
29067
- import chalk210 from "chalk";
29517
+ import chalk211 from "chalk";
29068
29518
  function formatCell(value) {
29069
29519
  if (value === null || value === void 0) return "";
29070
29520
  if (value instanceof Date) return value.toISOString();
@@ -29073,7 +29523,7 @@ function formatCell(value) {
29073
29523
  }
29074
29524
  function printTable(rows) {
29075
29525
  if (rows.length === 0) {
29076
- console.log(chalk210.yellow("(no rows)"));
29526
+ console.log(chalk211.yellow("(no rows)"));
29077
29527
  return;
29078
29528
  }
29079
29529
  const columns = Object.keys(rows[0]);
@@ -29081,13 +29531,13 @@ function printTable(rows) {
29081
29531
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
29082
29532
  );
29083
29533
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
29084
- console.log(chalk210.dim(header));
29085
- console.log(chalk210.dim("-".repeat(header.length)));
29534
+ console.log(chalk211.dim(header));
29535
+ console.log(chalk211.dim("-".repeat(header.length)));
29086
29536
  for (const row of rows) {
29087
29537
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
29088
29538
  console.log(line);
29089
29539
  }
29090
- console.log(chalk210.dim(`
29540
+ console.log(chalk211.dim(`
29091
29541
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
29092
29542
  }
29093
29543
 
@@ -29147,7 +29597,7 @@ async function sqlColumns(table, connectionName) {
29147
29597
  }
29148
29598
 
29149
29599
  // src/commands/sql/sqlMutate.ts
29150
- import chalk211 from "chalk";
29600
+ import chalk212 from "chalk";
29151
29601
 
29152
29602
  // src/commands/sql/isMutation.ts
29153
29603
  var MUTATION_KEYWORDS = [
@@ -29181,7 +29631,7 @@ function isMutation(sql25) {
29181
29631
  async function sqlMutate(query, connectionName) {
29182
29632
  if (!isMutation(query)) {
29183
29633
  console.error(
29184
- chalk211.red(
29634
+ chalk212.red(
29185
29635
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
29186
29636
  )
29187
29637
  );
@@ -29191,18 +29641,18 @@ async function sqlMutate(query, connectionName) {
29191
29641
  const pool = await sqlConnect(conn);
29192
29642
  try {
29193
29643
  const result = await pool.request().query(query);
29194
- console.log(chalk211.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
29644
+ console.log(chalk212.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
29195
29645
  } finally {
29196
29646
  await pool.close();
29197
29647
  }
29198
29648
  }
29199
29649
 
29200
29650
  // src/commands/sql/sqlQuery.ts
29201
- import chalk212 from "chalk";
29651
+ import chalk213 from "chalk";
29202
29652
  async function sqlQuery(query, connectionName) {
29203
29653
  if (isMutation(query)) {
29204
29654
  console.error(
29205
- chalk212.red(
29655
+ chalk213.red(
29206
29656
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
29207
29657
  )
29208
29658
  );
@@ -29217,7 +29667,7 @@ async function sqlQuery(query, connectionName) {
29217
29667
  printTable(rows);
29218
29668
  } else {
29219
29669
  console.log(
29220
- chalk212.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
29670
+ chalk213.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
29221
29671
  );
29222
29672
  }
29223
29673
  } finally {
@@ -29362,7 +29812,7 @@ function reportPrune(label2, result, force) {
29362
29812
  // src/commands/sync/syncClaudeMd.ts
29363
29813
  import * as fs41 from "fs";
29364
29814
  import * as path66 from "path";
29365
- import chalk213 from "chalk";
29815
+ import chalk214 from "chalk";
29366
29816
  async function syncClaudeMd(claudeDir, targetBase, options2) {
29367
29817
  const source = path66.join(claudeDir, "CLAUDE.md");
29368
29818
  const target = path66.join(targetBase, "CLAUDE.md");
@@ -29371,14 +29821,14 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
29371
29821
  const targetContent = fs41.readFileSync(target, "utf8");
29372
29822
  if (sourceContent !== targetContent) {
29373
29823
  console.log(
29374
- 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")
29375
29825
  );
29376
29826
  console.log();
29377
29827
  printDiff(targetContent, sourceContent);
29378
29828
  if (!options2?.yes) {
29379
29829
  printAutoConfirmHint();
29380
29830
  const confirm = await promptConfirm(
29381
- chalk213.red("Overwrite existing CLAUDE.md?"),
29831
+ chalk214.red("Overwrite existing CLAUDE.md?"),
29382
29832
  false
29383
29833
  );
29384
29834
  if (!confirm) {
@@ -29611,7 +30061,7 @@ function syncPi(claudeDir, options2) {
29611
30061
  // src/commands/sync/syncSettings.ts
29612
30062
  import * as fs47 from "fs";
29613
30063
  import * as path73 from "path";
29614
- import chalk214 from "chalk";
30064
+ import chalk215 from "chalk";
29615
30065
  async function syncSettings(claudeDir, targetBase, options2) {
29616
30066
  const source = path73.join(claudeDir, "settings.json");
29617
30067
  const target = path73.join(targetBase, "settings.json");
@@ -29630,7 +30080,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
29630
30080
  if (mergedContent !== normalizedTarget) {
29631
30081
  if (!options2?.yes) {
29632
30082
  console.log(
29633
- chalk214.yellow(
30083
+ chalk215.yellow(
29634
30084
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
29635
30085
  )
29636
30086
  );
@@ -29638,7 +30088,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
29638
30088
  printDiff(targetContent, mergedContent);
29639
30089
  printAutoConfirmHint();
29640
30090
  const confirm = await promptConfirm(
29641
- chalk214.red("Overwrite existing settings.json?"),
30091
+ chalk215.red("Overwrite existing settings.json?"),
29642
30092
  false
29643
30093
  );
29644
30094
  if (!confirm) {
@@ -29780,11 +30230,11 @@ async function configure() {
29780
30230
  }
29781
30231
 
29782
30232
  // src/commands/transcript/list.ts
29783
- 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";
29784
30234
  import { join as join77 } from "path";
29785
30235
  function list4() {
29786
30236
  const { vttDir } = getTranscriptConfig();
29787
- if (!existsSync61(vttDir)) return;
30237
+ if (!existsSync62(vttDir)) return;
29788
30238
  for (const entry of readdirSync19(vttDir)) {
29789
30239
  if (!entry.endsWith(".vtt")) continue;
29790
30240
  if (statSync10(join77(vttDir, entry)).isDirectory()) continue;
@@ -29794,9 +30244,9 @@ function list4() {
29794
30244
 
29795
30245
  // src/commands/transcript/move.ts
29796
30246
  import {
29797
- existsSync as existsSync62,
30247
+ existsSync as existsSync63,
29798
30248
  mkdirSync as mkdirSync26,
29799
- readFileSync as readFileSync47,
30249
+ readFileSync as readFileSync48,
29800
30250
  renameSync as renameSync2,
29801
30251
  writeFileSync as writeFileSync42
29802
30252
  } from "fs";
@@ -30008,7 +30458,7 @@ function formatChatLog(messages) {
30008
30458
  // src/commands/transcript/move.ts
30009
30459
  var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
30010
30460
  function convertVttToMarkdown(inputPath) {
30011
- const cues = parseVtt(readFileSync47(inputPath, "utf8"));
30461
+ const cues = parseVtt(readFileSync48(inputPath, "utf8"));
30012
30462
  const messages = cuesToChatMessages(deduplicateCues(cues));
30013
30463
  return formatChatLog(messages);
30014
30464
  }
@@ -30026,7 +30476,7 @@ function move(file, options2) {
30026
30476
  const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
30027
30477
  const filename = basename21(file);
30028
30478
  const sourcePath = join78(vttDir, filename);
30029
- if (!existsSync62(sourcePath)) {
30479
+ if (!existsSync63(sourcePath)) {
30030
30480
  console.error(`Error: VTT file not found: ${sourcePath}`);
30031
30481
  process.exit(1);
30032
30482
  }
@@ -30118,7 +30568,7 @@ function registerVerify(program2) {
30118
30568
  }
30119
30569
 
30120
30570
  // src/commands/voice/devices.ts
30121
- import { spawnSync as spawnSync7 } from "child_process";
30571
+ import { spawnSync as spawnSync8 } from "child_process";
30122
30572
  import { join as join80 } from "path";
30123
30573
 
30124
30574
  // src/commands/voice/shared.ts
@@ -30151,18 +30601,18 @@ function getLockFile() {
30151
30601
  // src/commands/voice/devices.ts
30152
30602
  function devices() {
30153
30603
  const script = join80(getPythonDir(), "list_devices.py");
30154
- spawnSync7(getVenvPython(), [script], { stdio: "inherit" });
30604
+ spawnSync8(getVenvPython(), [script], { stdio: "inherit" });
30155
30605
  }
30156
30606
 
30157
30607
  // src/commands/voice/logs.ts
30158
- import { existsSync as existsSync63, readFileSync as readFileSync48 } from "fs";
30608
+ import { existsSync as existsSync64, readFileSync as readFileSync49 } from "fs";
30159
30609
  function logs(options2) {
30160
- if (!existsSync63(voicePaths.log)) {
30610
+ if (!existsSync64(voicePaths.log)) {
30161
30611
  console.log("No voice log file found");
30162
30612
  return;
30163
30613
  }
30164
30614
  const count8 = Number.parseInt(options2.lines ?? "150", 10);
30165
- const content = readFileSync48(voicePaths.log, "utf8").trim();
30615
+ const content = readFileSync49(voicePaths.log, "utf8").trim();
30166
30616
  if (!content) {
30167
30617
  console.log("Voice log is empty");
30168
30618
  return;
@@ -30183,13 +30633,13 @@ function logs(options2) {
30183
30633
  }
30184
30634
 
30185
30635
  // src/commands/voice/setup.ts
30186
- import { spawnSync as spawnSync8 } from "child_process";
30636
+ import { spawnSync as spawnSync9 } from "child_process";
30187
30637
  import { mkdirSync as mkdirSync28 } from "fs";
30188
30638
  import { join as join82 } from "path";
30189
30639
 
30190
30640
  // src/commands/voice/checkLockFile.ts
30191
30641
  import { execSync as execSync58 } from "child_process";
30192
- 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";
30193
30643
  import { join as join81 } from "path";
30194
30644
  function isProcessAlive2(pid) {
30195
30645
  try {
@@ -30201,9 +30651,9 @@ function isProcessAlive2(pid) {
30201
30651
  }
30202
30652
  function checkLockFile() {
30203
30653
  const lockFile = getLockFile();
30204
- if (!existsSync64(lockFile)) return;
30654
+ if (!existsSync65(lockFile)) return;
30205
30655
  try {
30206
- const lock2 = JSON.parse(readFileSync49(lockFile, "utf8"));
30656
+ const lock2 = JSON.parse(readFileSync50(lockFile, "utf8"));
30207
30657
  if (lock2.pid && isProcessAlive2(lock2.pid)) {
30208
30658
  console.error(
30209
30659
  `Voice daemon already running (PID ${lock2.pid}, env: ${lock2.env}). Stop it first with: assist voice stop`
@@ -30214,7 +30664,7 @@ function checkLockFile() {
30214
30664
  }
30215
30665
  }
30216
30666
  function bootstrapVenv() {
30217
- if (existsSync64(getVenvPython())) return;
30667
+ if (existsSync65(getVenvPython())) return;
30218
30668
  console.log("Setting up Python environment...");
30219
30669
  const pythonDir = getPythonDir();
30220
30670
  execSync58(
@@ -30244,7 +30694,7 @@ function setup() {
30244
30694
  bootstrapVenv();
30245
30695
  console.log("\nDownloading models...\n");
30246
30696
  const script = join82(getPythonDir(), "setup_models.py");
30247
- const result = spawnSync8(getVenvPython(), [script], {
30697
+ const result = spawnSync9(getVenvPython(), [script], {
30248
30698
  stdio: "inherit",
30249
30699
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
30250
30700
  });
@@ -30305,7 +30755,7 @@ function start2(options2) {
30305
30755
  }
30306
30756
 
30307
30757
  // src/commands/voice/status.ts
30308
- import { existsSync as existsSync65, readFileSync as readFileSync50 } from "fs";
30758
+ import { existsSync as existsSync66, readFileSync as readFileSync51 } from "fs";
30309
30759
  function isProcessAlive3(pid) {
30310
30760
  try {
30311
30761
  process.kill(pid, 0);
@@ -30315,16 +30765,16 @@ function isProcessAlive3(pid) {
30315
30765
  }
30316
30766
  }
30317
30767
  function readRecentLogs(count8) {
30318
- if (!existsSync65(voicePaths.log)) return [];
30319
- 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");
30320
30770
  return lines2.slice(-count8);
30321
30771
  }
30322
30772
  function status2() {
30323
- if (!existsSync65(voicePaths.pid)) {
30773
+ if (!existsSync66(voicePaths.pid)) {
30324
30774
  console.log("Voice daemon: not running (no PID file)");
30325
30775
  return;
30326
30776
  }
30327
- const pid = Number.parseInt(readFileSync50(voicePaths.pid, "utf8").trim(), 10);
30777
+ const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
30328
30778
  const alive = isProcessAlive3(pid);
30329
30779
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
30330
30780
  const recent = readRecentLogs(5);
@@ -30343,13 +30793,13 @@ function status2() {
30343
30793
  }
30344
30794
 
30345
30795
  // src/commands/voice/stop.ts
30346
- 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";
30347
30797
  function stop2() {
30348
- if (!existsSync66(voicePaths.pid)) {
30798
+ if (!existsSync67(voicePaths.pid)) {
30349
30799
  console.log("Voice daemon is not running (no PID file)");
30350
30800
  return;
30351
30801
  }
30352
- const pid = Number.parseInt(readFileSync51(voicePaths.pid, "utf8").trim(), 10);
30802
+ const pid = Number.parseInt(readFileSync52(voicePaths.pid, "utf8").trim(), 10);
30353
30803
  try {
30354
30804
  process.kill(pid, "SIGTERM");
30355
30805
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -30362,7 +30812,7 @@ function stop2() {
30362
30812
  }
30363
30813
  try {
30364
30814
  const lockFile = getLockFile();
30365
- if (existsSync66(lockFile)) unlinkSync20(lockFile);
30815
+ if (existsSync67(lockFile)) unlinkSync20(lockFile);
30366
30816
  } catch {
30367
30817
  }
30368
30818
  console.log("Voice daemon stopped");
@@ -30380,9 +30830,6 @@ function registerVoice(program2) {
30380
30830
  configHelp(voiceCommand, voiceConfigHelp);
30381
30831
  }
30382
30832
 
30383
- // src/commands/watch/readBuiltVersion.ts
30384
- import { join as join84 } from "path";
30385
-
30386
30833
  // src/commands/watch/resolveUpstream.ts
30387
30834
  import { execFileSync as execFileSync15 } from "child_process";
30388
30835
  function runGit3(args, cwd) {
@@ -30423,7 +30870,13 @@ function resolveUpstream(cwd) {
30423
30870
  }
30424
30871
  }
30425
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
+
30426
30878
  // src/commands/watch/readBuiltVersion.ts
30879
+ import { join as join84 } from "path";
30427
30880
  function readBuiltVersion(cwd) {
30428
30881
  try {
30429
30882
  const root = runGit3(["rev-parse", "--show-toplevel"], cwd);
@@ -30534,12 +30987,11 @@ function syncAdvice(paths) {
30534
30987
  // src/commands/watch/buildWatchReport.ts
30535
30988
  var lines = (output) => output.split("\n").filter((line) => line.length > 0);
30536
30989
  function buildWatchReport(from, cwd) {
30537
- const range = from ? `${from}..HEAD` : void 0;
30538
- const changed = range ? lines(runGit3(["diff", "--name-only", range], cwd)) : [];
30990
+ const changed = from ? changedPaths(from, cwd) : [];
30539
30991
  return renderWatchReport({
30540
30992
  version: readBuiltVersion(cwd),
30541
30993
  commits: readRecentCommits(10, cwd),
30542
- newShas: range ? lines(runGit3(["rev-list", range], cwd)) : [],
30994
+ newShas: from ? lines(runGit3(["rev-list", `${from}..HEAD`], cwd)) : [],
30543
30995
  restarts: restartAdvice(changed),
30544
30996
  syncs: syncAdvice(changed)
30545
30997
  });
@@ -30765,7 +31217,7 @@ function resolveParams(params, cliArgs) {
30765
31217
  }
30766
31218
 
30767
31219
  // src/commands/run/resolveRunCwd.ts
30768
- import { existsSync as existsSync67 } from "fs";
31220
+ import { existsSync as existsSync68 } from "fs";
30769
31221
  import { resolve as resolve18 } from "path";
30770
31222
  var MissingRunCwdError = class extends Error {
30771
31223
  constructor(runName, cwd) {
@@ -30778,17 +31230,17 @@ var MissingRunCwdError = class extends Error {
30778
31230
  function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
30779
31231
  if (!config.cwd) return void 0;
30780
31232
  const cwd = resolve18(baseDir, config.cwd);
30781
- if (!existsSync67(cwd)) throw new MissingRunCwdError(config.name, cwd);
31233
+ if (!existsSync68(cwd)) throw new MissingRunCwdError(config.name, cwd);
30782
31234
  return cwd;
30783
31235
  }
30784
31236
 
30785
31237
  // src/commands/run/runCommandToCompletion.ts
30786
31238
  import { spawn as spawn9 } from "child_process";
30787
- import { existsSync as existsSync69 } from "fs";
31239
+ import { existsSync as existsSync70 } from "fs";
30788
31240
 
30789
31241
  // src/commands/run/resolveCommand.ts
30790
31242
  import { execFileSync as execFileSync16 } from "child_process";
30791
- import { existsSync as existsSync68 } from "fs";
31243
+ import { existsSync as existsSync69 } from "fs";
30792
31244
  import { dirname as dirname35, join as join85, resolve as resolve19 } from "path";
30793
31245
  function resolveCommand2(command) {
30794
31246
  if (process.platform !== "win32" || command !== "bash") return command;
@@ -30796,7 +31248,7 @@ function resolveCommand2(command) {
30796
31248
  const gitPath = execFileSync16("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
30797
31249
  const gitRoot = resolve19(dirname35(gitPath), "..");
30798
31250
  const gitBash = join85(gitRoot, "bin", "bash.exe");
30799
- if (existsSync68(gitBash)) return gitBash;
31251
+ if (existsSync69(gitBash)) return gitBash;
30800
31252
  } catch {
30801
31253
  return command;
30802
31254
  }
@@ -30806,7 +31258,7 @@ function resolveCommand2(command) {
30806
31258
  // src/commands/run/runCommandToCompletion.ts
30807
31259
  function runCommandToCompletion(command, args, env, cwd, quiet) {
30808
31260
  return new Promise((resolveResult) => {
30809
- if (cwd && !existsSync69(cwd)) {
31261
+ if (cwd && !existsSync70(cwd)) {
30810
31262
  resolveResult({
30811
31263
  kind: "failed",
30812
31264
  message: `Failed to execute command: cwd ${cwd} does not exist`
@@ -30852,6 +31304,15 @@ function runPreCommands(pre, cwd) {
30852
31304
  }
30853
31305
  }
30854
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
+
30855
31316
  // src/commands/watch/runWatchBuild.ts
30856
31317
  async function runWatchBuild(entry) {
30857
31318
  const config = findRunConfig(entry);
@@ -30863,18 +31324,15 @@ async function runWatchBuild(entry) {
30863
31324
  return { kind: "failed", exitCode: 1, output: error.message };
30864
31325
  }
30865
31326
  if (config.pre) runPreCommands(config.pre, cwd);
30866
- const result = await runCommandToCompletion(
30867
- config.command,
30868
- [...config.args ?? [], ...resolveParams(config.params, [])],
30869
- config.env,
30870
- cwd,
30871
- 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
+ )
30872
31335
  );
30873
- if (result.kind === "failed")
30874
- return { kind: "failed", exitCode: 1, output: result.message };
30875
- if (result.exitCode !== 0)
30876
- return { kind: "failed", exitCode: result.exitCode, output: result.output };
30877
- return { kind: "built" };
30878
31336
  }
30879
31337
 
30880
31338
  // src/commands/watch/reportBuildOrExit.ts
@@ -30889,6 +31347,25 @@ async function reportBuildOrExit(entry) {
30889
31347
  process.exit(4);
30890
31348
  }
30891
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
+
30892
31369
  // src/commands/watch/fetchQuietly.ts
30893
31370
  import { execFileSync as execFileSync17 } from "child_process";
30894
31371
  var MIN_FETCH_TIMEOUT_MS = 6e4;
@@ -31000,6 +31477,8 @@ ${buildWatchReport(outcome.from)}`);
31000
31477
  await reportBuildOrExit(
31001
31478
  typeof options2.build === "string" ? options2.build : DEFAULT_BUILD_ENTRY
31002
31479
  );
31480
+ if (syncAdvice(changedPaths(outcome.from)).length > 0)
31481
+ await reportSyncOrExit();
31003
31482
  }
31004
31483
  process.exit(0);
31005
31484
  }
@@ -31008,7 +31487,7 @@ ${buildWatchReport(outcome.from)}`);
31008
31487
  function registerWatch(program2) {
31009
31488
  const watchCommand = program2.command("watch").description("Wait on upstream movement for the current branch");
31010
31489
  watchCommand.command("wait").description(
31011
- "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)"
31012
31491
  ).option(
31013
31492
  "--interval <duration>",
31014
31493
  "How often to fetch after the fetch at startup (e.g. 30s, 2m)",
@@ -31022,7 +31501,7 @@ function registerWatch(program2) {
31022
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"
31023
31502
  ).option(
31024
31503
  "--build [entry]",
31025
- "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"
31026
31505
  ).action(
31027
31506
  (options2) => watchWait(options2)
31028
31507
  );
@@ -31036,7 +31515,7 @@ function registerWatch(program2) {
31036
31515
 
31037
31516
  // src/commands/roam/auth.ts
31038
31517
  import { randomBytes } from "crypto";
31039
- import chalk215 from "chalk";
31518
+ import chalk216 from "chalk";
31040
31519
 
31041
31520
  // src/commands/roam/waitForCallback.ts
31042
31521
  import { createServer as createServer3 } from "http";
@@ -31167,13 +31646,13 @@ async function auth() {
31167
31646
  saveGlobalConfig(config);
31168
31647
  const state = randomBytes(16).toString("hex");
31169
31648
  console.log(
31170
- 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:")
31171
31650
  );
31172
- console.log(chalk215.white("http://localhost:14523/callback\n"));
31173
- console.log(chalk215.blue("Opening browser for authorization..."));
31174
- 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..."));
31175
31654
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
31176
- console.log(chalk215.dim("Exchanging code for tokens..."));
31655
+ console.log(chalk216.dim("Exchanging code for tokens..."));
31177
31656
  const tokens = await exchangeToken({
31178
31657
  code,
31179
31658
  clientId,
@@ -31189,13 +31668,13 @@ async function auth() {
31189
31668
  };
31190
31669
  saveGlobalConfig(config);
31191
31670
  console.log(
31192
- chalk215.green("Roam credentials and tokens saved to ~/.assist.yml")
31671
+ chalk216.green("Roam credentials and tokens saved to ~/.assist.yml")
31193
31672
  );
31194
31673
  }
31195
31674
 
31196
31675
  // src/commands/roam/postRoamActivity.ts
31197
31676
  import { execFileSync as execFileSync18 } from "child_process";
31198
- 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";
31199
31678
  import { join as join86 } from "path";
31200
31679
  function findPortFile(roamDir) {
31201
31680
  let entries;
@@ -31221,7 +31700,7 @@ function postRoamActivity(app, event) {
31221
31700
  if (!portFile) return;
31222
31701
  let port;
31223
31702
  try {
31224
- port = readFileSync52(portFile, "utf8").trim();
31703
+ port = readFileSync53(portFile, "utf8").trim();
31225
31704
  } catch {
31226
31705
  return;
31227
31706
  }
@@ -31475,7 +31954,7 @@ function link2() {
31475
31954
  }
31476
31955
 
31477
31956
  // src/commands/run/remove.ts
31478
- import { existsSync as existsSync70, unlinkSync as unlinkSync21 } from "fs";
31957
+ import { existsSync as existsSync71, unlinkSync as unlinkSync21 } from "fs";
31479
31958
  import { join as join88 } from "path";
31480
31959
  function findRemoveIndex() {
31481
31960
  const idx = process.argv.indexOf("remove");
@@ -31492,7 +31971,7 @@ function parseRemoveName() {
31492
31971
  }
31493
31972
  function deleteCommandFile(name) {
31494
31973
  const filePath = join88(".claude", "commands", `${name}.md`);
31495
- if (existsSync70(filePath)) {
31974
+ if (existsSync71(filePath)) {
31496
31975
  unlinkSync21(filePath);
31497
31976
  console.log(`Deleted command file: ${filePath}`);
31498
31977
  }
@@ -31537,10 +32016,10 @@ function registerRun(program2) {
31537
32016
 
31538
32017
  // src/commands/screenshot/index.ts
31539
32018
  import { execSync as execSync60 } from "child_process";
31540
- 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";
31541
32020
  import { tmpdir as tmpdir8 } from "os";
31542
32021
  import { join as join89, resolve as resolve20 } from "path";
31543
- import chalk216 from "chalk";
32022
+ import chalk217 from "chalk";
31544
32023
 
31545
32024
  // src/commands/screenshot/captureWindowPs1.ts
31546
32025
  var captureWindowPs1 = `
@@ -31669,7 +32148,7 @@ Write-Output $OutputPath
31669
32148
 
31670
32149
  // src/commands/screenshot/index.ts
31671
32150
  function buildOutputPath(outputDir, processName) {
31672
- if (!existsSync71(outputDir)) {
32151
+ if (!existsSync72(outputDir)) {
31673
32152
  mkdirSync31(outputDir, { recursive: true });
31674
32153
  }
31675
32154
  const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
@@ -31691,13 +32170,13 @@ function screenshot(processName) {
31691
32170
  const config = loadConfig();
31692
32171
  const outputDir = resolve20(config.screenshot.outputDir);
31693
32172
  const outputPath = buildOutputPath(outputDir, processName);
31694
- console.log(chalk216.gray(`Capturing window for process "${processName}" ...`));
32173
+ console.log(chalk217.gray(`Capturing window for process "${processName}" ...`));
31695
32174
  try {
31696
32175
  runPowerShellScript(processName, outputPath);
31697
- console.log(chalk216.green(`Screenshot saved: ${outputPath}`));
32176
+ console.log(chalk217.green(`Screenshot saved: ${outputPath}`));
31698
32177
  } catch (error) {
31699
32178
  const msg = error instanceof Error ? error.message : String(error);
31700
- console.error(chalk216.red(`Failed to capture screenshot: ${msg}`));
32179
+ console.error(chalk217.red(`Failed to capture screenshot: ${msg}`));
31701
32180
  process.exit(1);
31702
32181
  }
31703
32182
  }
@@ -31753,11 +32232,11 @@ function applyLine(result, pending, line) {
31753
32232
  }
31754
32233
 
31755
32234
  // src/commands/sessions/daemon/readDaemonPidFile.ts
31756
- import { readFileSync as readFileSync53 } from "fs";
32235
+ import { readFileSync as readFileSync54 } from "fs";
31757
32236
  function readDaemonPidFile() {
31758
32237
  try {
31759
32238
  const pid = Number.parseInt(
31760
- readFileSync53(daemonPaths.pid, "utf8").trim(),
32239
+ readFileSync54(daemonPaths.pid, "utf8").trim(),
31761
32240
  10
31762
32241
  );
31763
32242
  return Number.isInteger(pid) ? pid : void 0;
@@ -32014,12 +32493,12 @@ function toSessionRunInfo({
32014
32493
  }
32015
32494
 
32016
32495
  // src/commands/sessions/daemon/worktree/joinRefusal.ts
32017
- import { existsSync as existsSync72 } from "fs";
32496
+ import { existsSync as existsSync73 } from "fs";
32018
32497
  function joinRefusal(session) {
32019
32498
  if (session.commandType === "run") return "a server run has no agent stream";
32020
32499
  if (session.closing === true) return "the session is closing";
32021
32500
  if (!session.cwd) return "the session has no working directory";
32022
- if (!existsSync72(session.cwd))
32501
+ if (!existsSync73(session.cwd))
32023
32502
  return "the session's workspace no longer exists";
32024
32503
  return void 0;
32025
32504
  }
@@ -32183,11 +32662,11 @@ function sessionBase(id, status3) {
32183
32662
  }
32184
32663
 
32185
32664
  // src/commands/sessions/daemon/spawnPty.ts
32186
- import { existsSync as existsSync74 } from "fs";
32665
+ import { existsSync as existsSync75 } from "fs";
32187
32666
  import * as pty from "node-pty";
32188
32667
 
32189
32668
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
32190
- import { chmodSync, existsSync as existsSync73, statSync as statSync12 } from "fs";
32669
+ import { chmodSync, existsSync as existsSync74, statSync as statSync12 } from "fs";
32191
32670
  import { createRequire as createRequire3 } from "module";
32192
32671
  import path75 from "path";
32193
32672
  var require4 = createRequire3(import.meta.url);
@@ -32202,7 +32681,7 @@ function ensureSpawnHelperExecutable() {
32202
32681
  `${process.platform}-${process.arch}`,
32203
32682
  "spawn-helper"
32204
32683
  );
32205
- if (!existsSync73(helper)) return;
32684
+ if (!existsSync74(helper)) return;
32206
32685
  const mode = statSync12(helper).mode;
32207
32686
  if ((mode & 73) === 0) chmodSync(helper, mode | 493);
32208
32687
  }
@@ -32238,7 +32717,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
32238
32717
  });
32239
32718
  }
32240
32719
  function refuseMissingCwd(cwd, sessionId) {
32241
- if (!cwd || existsSync74(cwd)) return;
32720
+ if (!cwd || existsSync75(cwd)) return;
32242
32721
  daemonLog(
32243
32722
  `${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
32244
32723
  );
@@ -32420,11 +32899,11 @@ function setStatus2(session, newStatus) {
32420
32899
  }
32421
32900
 
32422
32901
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
32423
- import { existsSync as existsSync76 } from "fs";
32902
+ import { existsSync as existsSync77 } from "fs";
32424
32903
  import { basename as basename22 } from "path";
32425
32904
 
32426
32905
  // src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
32427
- import { existsSync as existsSync75 } from "fs";
32906
+ import { existsSync as existsSync76 } from "fs";
32428
32907
  import { join as join92 } from "path";
32429
32908
 
32430
32909
  // src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
@@ -32494,7 +32973,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
32494
32973
  );
32495
32974
  }
32496
32975
  function strandedReason(worktreePath, cause) {
32497
- if (!existsSync75(join92(worktreePath, ".git")))
32976
+ if (!existsSync76(join92(worktreePath, ".git")))
32498
32977
  return "its .git link is already gone";
32499
32978
  if (/not a working tree|not a git repository/i.test(reason2(cause)))
32500
32979
  return "git no longer recognises it as a working tree";
@@ -32546,7 +33025,7 @@ function reason3(error) {
32546
33025
 
32547
33026
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
32548
33027
  async function reapWorktree(worktreePath, force = false) {
32549
- if (!existsSync76(worktreePath)) {
33028
+ if (!existsSync77(worktreePath)) {
32550
33029
  forgetWorktree(worktreePath);
32551
33030
  daemonLog(
32552
33031
  `worktree ${worktreePath} already gone; its record was forgotten`
@@ -32571,7 +33050,7 @@ async function reapWorktree(worktreePath, force = false) {
32571
33050
  }
32572
33051
  function owningClone(worktreePath) {
32573
33052
  const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
32574
- if (recorded && existsSync76(recorded)) return recorded;
33053
+ if (recorded && existsSync77(recorded)) return recorded;
32575
33054
  const detected = mainWorktree(worktreePath);
32576
33055
  if (detected) return detected;
32577
33056
  daemonLog(
@@ -32702,12 +33181,12 @@ function closeGateApplies(sessions, session) {
32702
33181
  }
32703
33182
 
32704
33183
  // src/commands/sessions/daemon/worktree/watchGitState.ts
32705
- import { existsSync as existsSync77, watch } from "fs";
33184
+ import { existsSync as existsSync78, watch } from "fs";
32706
33185
  var DEBOUNCE_MS = 500;
32707
33186
  var POLL_MS = 3e4;
32708
33187
  function watchGitState(cwd, onChange) {
32709
33188
  const common = gitCommonDir(cwd);
32710
- if (!common || !existsSync77(common)) return void 0;
33189
+ if (!common || !existsSync78(common)) return void 0;
32711
33190
  const watchers = [
32712
33191
  watchGitDir(common, onChange),
32713
33192
  pollGitState(cwd, onChange)
@@ -32882,9 +33361,9 @@ function flushPhaseActiveMs(session) {
32882
33361
  if (await persistPhaseActiveMs(phase.itemId, phase.phaseIdx, delta))
32883
33362
  session.activeMsFlushedForStretch = { since, ms: flushed + delta };
32884
33363
  };
32885
- const chain = (session.activeMsFlushChain ?? Promise.resolve()).then(run4);
32886
- session.activeMsFlushChain = chain;
32887
- return chain;
33364
+ const chain2 = (session.activeMsFlushChain ?? Promise.resolve()).then(run4);
33365
+ session.activeMsFlushChain = chain2;
33366
+ return chain2;
32888
33367
  }
32889
33368
 
32890
33369
  // src/commands/sessions/daemon/stripReplayQueries.ts
@@ -33182,10 +33661,10 @@ function emitSessionOutput(session, clients, data) {
33182
33661
  }
33183
33662
 
33184
33663
  // src/commands/sessions/daemon/exitReason.ts
33185
- import { existsSync as existsSync78 } from "fs";
33664
+ import { existsSync as existsSync79 } from "fs";
33186
33665
  import { resolve as resolve21 } from "path";
33187
33666
  function exitDetail(session) {
33188
- if (session.cwd && !existsSync78(session.cwd))
33667
+ if (session.cwd && !existsSync79(session.cwd))
33189
33668
  return `working directory ${session.cwd} no longer exists`;
33190
33669
  return missingRunConfigCwd(session);
33191
33670
  }
@@ -33199,7 +33678,7 @@ function missingRunConfigCwd(session) {
33199
33678
  const config = resolveRunConfig(session.runName, dir);
33200
33679
  if (!config?.cwd) return void 0;
33201
33680
  const configured = resolve21(runConfigBaseDirFrom(dir), config.cwd);
33202
- if (existsSync78(configured)) return void 0;
33681
+ if (existsSync79(configured)) return void 0;
33203
33682
  return `run config "${config.name}": cwd ${configured} does not exist`;
33204
33683
  }
33205
33684
 
@@ -33240,7 +33719,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
33240
33719
  }
33241
33720
 
33242
33721
  // src/commands/sessions/daemon/watchActivity.ts
33243
- 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";
33244
33723
  import { dirname as dirname37 } from "path";
33245
33724
 
33246
33725
  // src/commands/sessions/daemon/applyActivityToSession.ts
@@ -33326,7 +33805,7 @@ function watchActivity(session, notify2, onClaudeSessionId) {
33326
33805
  if (timer) clearTimeout(timer);
33327
33806
  timer = setTimeout(read2, DEBOUNCE_MS2);
33328
33807
  });
33329
- if (existsSync79(path80)) read2();
33808
+ if (existsSync80(path80)) read2();
33330
33809
  }
33331
33810
  function refreshActivity(session) {
33332
33811
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -34948,7 +35427,7 @@ function rearmStoppedSessions(sessions, notify2) {
34948
35427
  }
34949
35428
 
34950
35429
  // src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
34951
- import { existsSync as existsSync82 } from "fs";
35430
+ import { existsSync as existsSync83 } from "fs";
34952
35431
  import { basename as basename24 } from "path";
34953
35432
 
34954
35433
  // src/commands/sessions/daemon/worktree/accountedTrees.ts
@@ -35003,9 +35482,9 @@ function bindResumedWorktree(session, cwd, notify2) {
35003
35482
  }
35004
35483
 
35005
35484
  // src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
35006
- import { existsSync as existsSync81 } from "fs";
35485
+ import { existsSync as existsSync82 } from "fs";
35007
35486
  async function reclaimVanishedWorktrees(clone, paths) {
35008
- if (!existsSync81(clone)) {
35487
+ if (!existsSync82(clone)) {
35009
35488
  for (const { path: path80 } of paths) forgetWorktree(path80);
35010
35489
  daemonLog(
35011
35490
  `clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
@@ -35171,7 +35650,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
35171
35650
  );
35172
35651
  continue;
35173
35652
  }
35174
- if (!existsSync82(path80)) {
35653
+ if (!existsSync83(path80)) {
35175
35654
  logVanishedTree(sessions, path80);
35176
35655
  vanished.set(clone, [
35177
35656
  ...vanished.get(clone) ?? [],
@@ -35788,14 +36267,14 @@ async function defaultConnect() {
35788
36267
  }
35789
36268
 
35790
36269
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
35791
- import { existsSync as existsSync83, readFileSync as readFileSync55 } from "fs";
36270
+ import { existsSync as existsSync84, readFileSync as readFileSync56 } from "fs";
35792
36271
  import { posix as posix3 } from "path";
35793
36272
  function hasPersistedWindowsSessions() {
35794
36273
  const sessionsFile = windowsSessionsFileFromWsl();
35795
36274
  if (!sessionsFile) return false;
35796
36275
  try {
35797
- if (!existsSync83(sessionsFile)) return false;
35798
- const data = JSON.parse(readFileSync55(sessionsFile, "utf8"));
36276
+ if (!existsSync84(sessionsFile)) return false;
36277
+ const data = JSON.parse(readFileSync56(sessionsFile, "utf8"));
35799
36278
  return Array.isArray(data) && data.length > 0;
35800
36279
  } catch (error) {
35801
36280
  const message3 = error instanceof Error ? error.message : String(error);
@@ -36529,7 +37008,7 @@ function setAutoAdvance(sessions, id, enabled) {
36529
37008
  }
36530
37009
 
36531
37010
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
36532
- import { existsSync as existsSync86 } from "fs";
37011
+ import { existsSync as existsSync87 } from "fs";
36533
37012
 
36534
37013
  // src/commands/sessions/daemon/resumeSession.ts
36535
37014
  function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
@@ -36560,10 +37039,10 @@ function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
36560
37039
  }
36561
37040
 
36562
37041
  // src/commands/sessions/daemon/worktree/resumeInReplacementTree.ts
36563
- import { existsSync as existsSync85 } from "fs";
37042
+ import { existsSync as existsSync86 } from "fs";
36564
37043
 
36565
37044
  // src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
36566
- 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";
36567
37046
  import { join as join94 } from "path";
36568
37047
  function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
36569
37048
  const dir = projectDirForCwd(toCwd);
@@ -36574,7 +37053,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
36574
37053
  return;
36575
37054
  }
36576
37055
  const dest = join94(dir, `${claudeSessionId}.jsonl`);
36577
- if (existsSync84(dest)) {
37056
+ if (existsSync85(dest)) {
36578
37057
  daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
36579
37058
  return;
36580
37059
  }
@@ -36625,7 +37104,7 @@ function resumeInReplacementTree(ctx, claudeSessionId, missingCwd, name, harness
36625
37104
  }
36626
37105
  function cloneForReapedTree(missingCwd) {
36627
37106
  const clone = worktreeAttributionIncludingReaped(missingCwd)?.clone;
36628
- if (!clone || !existsSync85(clone))
37107
+ if (!clone || !existsSync86(clone))
36629
37108
  throw new Error(
36630
37109
  `working directory no longer exists and no clone is recorded to re-allocate from: ${missingCwd}`
36631
37110
  );
@@ -36634,7 +37113,7 @@ function cloneForReapedTree(missingCwd) {
36634
37113
 
36635
37114
  // src/commands/sessions/daemon/worktree/resumeInTree.ts
36636
37115
  function resumeInTree(ctx, sessionId, cwd, name, harness) {
36637
- if (!existsSync86(cwd))
37116
+ if (!existsSync87(cwd))
36638
37117
  return resumeInReplacementTree(ctx, sessionId, cwd, name, harness);
36639
37118
  const id = ctx.spawnWith(
36640
37119
  (sid) => resumeSession(sid, sessionId, cwd, name, void 0, harness)
@@ -37213,7 +37692,7 @@ function handleConnection(socket, manager) {
37213
37692
  import { unlinkSync as unlinkSync23, writeFileSync as writeFileSync47 } from "fs";
37214
37693
 
37215
37694
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
37216
- import { readFileSync as readFileSync56 } from "fs";
37695
+ import { readFileSync as readFileSync57 } from "fs";
37217
37696
  var WATCHDOG_INTERVAL_MS = 5e3;
37218
37697
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
37219
37698
  const timer = setInterval(() => {
@@ -37224,7 +37703,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
37224
37703
  }
37225
37704
  function ownsPidFile() {
37226
37705
  try {
37227
- return readFileSync56(daemonPaths.pid, "utf8").trim() === String(process.pid);
37706
+ return readFileSync57(daemonPaths.pid, "utf8").trim() === String(process.pid);
37228
37707
  } catch {
37229
37708
  return false;
37230
37709
  }
@@ -37474,7 +37953,7 @@ function registerSetStatusCommand(cmd) {
37474
37953
 
37475
37954
  // src/commands/sessions/summarise/index.ts
37476
37955
  import * as fs56 from "fs";
37477
- import chalk217 from "chalk";
37956
+ import chalk218 from "chalk";
37478
37957
 
37479
37958
  // src/commands/sessions/summarise/shared.ts
37480
37959
  import * as fs55 from "fs";
@@ -37533,22 +38012,22 @@ ${firstMessage}`);
37533
38012
  async function summarise2(options2) {
37534
38013
  const files = await discoverSessionFiles();
37535
38014
  if (files.length === 0) {
37536
- console.log(chalk217.yellow("No sessions found."));
38015
+ console.log(chalk218.yellow("No sessions found."));
37537
38016
  return;
37538
38017
  }
37539
38018
  const toProcess = selectCandidates(files, options2);
37540
38019
  if (toProcess.length === 0) {
37541
- console.log(chalk217.green("All sessions already summarised."));
38020
+ console.log(chalk218.green("All sessions already summarised."));
37542
38021
  return;
37543
38022
  }
37544
38023
  console.log(
37545
- chalk217.cyan(
38024
+ chalk218.cyan(
37546
38025
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
37547
38026
  )
37548
38027
  );
37549
38028
  const { succeeded, failed: failed2 } = processSessions(toProcess);
37550
38029
  console.log(
37551
- chalk217.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk217.yellow(`, ${failed2} skipped`) : "")
38030
+ chalk218.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk218.yellow(`, ${failed2} skipped`) : "")
37552
38031
  );
37553
38032
  }
37554
38033
  function selectCandidates(files, options2) {
@@ -37568,16 +38047,16 @@ function processSessions(files) {
37568
38047
  let failed2 = 0;
37569
38048
  for (let i = 0; i < files.length; i++) {
37570
38049
  const file = files[i];
37571
- process.stdout.write(chalk217.dim(` [${i + 1}/${files.length}] `));
38050
+ process.stdout.write(chalk218.dim(` [${i + 1}/${files.length}] `));
37572
38051
  const summary = summariseSession(file);
37573
38052
  if (summary) {
37574
38053
  writeSummary(file, summary);
37575
38054
  succeeded++;
37576
- process.stdout.write(`${chalk217.green("\u2713")} ${summary}
38055
+ process.stdout.write(`${chalk218.green("\u2713")} ${summary}
37577
38056
  `);
37578
38057
  } else {
37579
38058
  failed2++;
37580
- process.stdout.write(` ${chalk217.yellow("skip")}
38059
+ process.stdout.write(` ${chalk218.yellow("skip")}
37581
38060
  `);
37582
38061
  }
37583
38062
  }
@@ -37598,7 +38077,7 @@ function registerSessions(program2) {
37598
38077
  }
37599
38078
 
37600
38079
  // src/commands/statusLine.ts
37601
- import chalk219 from "chalk";
38080
+ import chalk220 from "chalk";
37602
38081
 
37603
38082
  // src/shared/contextLevel.ts
37604
38083
  function contextLevel(pct) {
@@ -37608,7 +38087,7 @@ function contextLevel(pct) {
37608
38087
  }
37609
38088
 
37610
38089
  // src/commands/buildLimitsSegment.ts
37611
- import chalk218 from "chalk";
38090
+ import chalk219 from "chalk";
37612
38091
 
37613
38092
  // src/shared/rateLimitLevel.ts
37614
38093
  var FIVE_HOUR_SECONDS = 5 * 3600;
@@ -37646,9 +38125,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
37646
38125
 
37647
38126
  // src/commands/buildLimitsSegment.ts
37648
38127
  var LEVEL_COLOR = {
37649
- ok: chalk218.green,
37650
- warn: chalk218.yellow,
37651
- over: chalk218.red
38128
+ ok: chalk219.green,
38129
+ warn: chalk219.yellow,
38130
+ over: chalk219.red
37652
38131
  };
37653
38132
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
37654
38133
  const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
@@ -37679,7 +38158,7 @@ function buildLimitsSegment(rateLimits) {
37679
38158
  }
37680
38159
 
37681
38160
  // src/commands/readGitBranch.ts
37682
- import { readFileSync as readFileSync58, statSync as statSync15 } from "fs";
38161
+ import { readFileSync as readFileSync59, statSync as statSync15 } from "fs";
37683
38162
  import { isAbsolute as isAbsolute4, join as join95, resolve as resolve22 } from "path";
37684
38163
  function resolveGitDir(cwd) {
37685
38164
  const dotGit = join95(cwd, ".git");
@@ -37694,7 +38173,7 @@ function resolveGitDir(cwd) {
37694
38173
  }
37695
38174
  let contents;
37696
38175
  try {
37697
- contents = readFileSync58(dotGit, "utf8");
38176
+ contents = readFileSync59(dotGit, "utf8");
37698
38177
  } catch {
37699
38178
  return null;
37700
38179
  }
@@ -37712,7 +38191,7 @@ function readGitBranch(cwd) {
37712
38191
  }
37713
38192
  let head;
37714
38193
  try {
37715
- head = readFileSync58(join95(gitDir, "HEAD"), "utf8");
38194
+ head = readFileSync59(join95(gitDir, "HEAD"), "utf8");
37716
38195
  } catch {
37717
38196
  return null;
37718
38197
  }
@@ -37744,7 +38223,7 @@ async function relayUsage(claudeSessionId, transcriptPath2, usedPct) {
37744
38223
  }
37745
38224
 
37746
38225
  // src/commands/statusLine.ts
37747
- chalk219.level = 3;
38226
+ chalk220.level = 3;
37748
38227
  function formatNumber(num) {
37749
38228
  return num.toLocaleString("en-US");
37750
38229
  }
@@ -37752,9 +38231,9 @@ function colorizePercent(pct) {
37752
38231
  const label2 = `${Math.round(pct)}%`;
37753
38232
  switch (contextLevel(pct)) {
37754
38233
  case "red":
37755
- return chalk219.red(label2);
38234
+ return chalk220.red(label2);
37756
38235
  case "yellow":
37757
- return chalk219.yellow(label2);
38236
+ return chalk220.yellow(label2);
37758
38237
  default:
37759
38238
  return label2;
37760
38239
  }
@@ -37767,7 +38246,7 @@ async function statusLine() {
37767
38246
  const usedPct = data.context_window.used_percentage ?? 0;
37768
38247
  const dir = data.workspace?.current_dir ?? data.cwd;
37769
38248
  const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
37770
- const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk219.cyan(branch2)} | ` : "";
38249
+ const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk220.cyan(branch2)} | ` : "";
37771
38250
  console.log(
37772
38251
  `${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
37773
38252
  );
@@ -37837,10 +38316,10 @@ async function update2() {
37837
38316
  }
37838
38317
 
37839
38318
  // src/reportCliError.ts
37840
- import chalk220 from "chalk";
38319
+ import chalk221 from "chalk";
37841
38320
  function reportCliError(error) {
37842
38321
  if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError || error instanceof MissingRunCwdError) {
37843
- console.error(chalk220.red(error.message));
38322
+ console.error(chalk221.red(error.message));
37844
38323
  } else {
37845
38324
  console.error(error);
37846
38325
  }