@staff0rd/assist 0.104.0 → 0.106.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.
Files changed (3) hide show
  1. package/README.md +1 -0
  2. package/dist/index.js +357 -226
  3. package/package.json +1 -1
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.104.0",
9
+ version: "0.106.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -129,9 +129,7 @@ var assistConfigSchema = z.strictObject({
129
129
  devlog: z.strictObject({
130
130
  name: z.string().optional(),
131
131
  ignore: z.array(z.string()).optional(),
132
- skip: z.strictObject({
133
- days: z.array(z.string()).optional()
134
- }).optional()
132
+ skip: z.record(z.string(), z.array(z.string())).optional()
135
133
  }).optional(),
136
134
  notify: z.strictObject({
137
135
  enabled: z.boolean().default(true)
@@ -3717,47 +3715,84 @@ function registerDeploy(program2) {
3717
3715
  import { execSync as execSync16 } from "child_process";
3718
3716
  import { basename as basename3 } from "path";
3719
3717
 
3718
+ // src/commands/devlog/loadBlogSkipDays.ts
3719
+ import { homedir as homedir5 } from "os";
3720
+ import { join as join13 } from "path";
3721
+ var BLOG_REPO_ROOT = join13(homedir5(), "git/blog");
3722
+ function loadBlogSkipDays(repoName) {
3723
+ const config = loadRawYaml(join13(BLOG_REPO_ROOT, "assist.yml"));
3724
+ const devlog = config.devlog;
3725
+ const skip2 = devlog?.skip;
3726
+ return new Set(skip2?.[repoName] ?? []);
3727
+ }
3728
+
3720
3729
  // src/commands/devlog/shared.ts
3721
3730
  import { execSync as execSync15 } from "child_process";
3722
3731
  import chalk38 from "chalk";
3723
3732
 
3724
3733
  // src/commands/devlog/loadDevlogEntries.ts
3725
3734
  import { readdirSync, readFileSync as readFileSync17 } from "fs";
3726
- import { homedir as homedir5 } from "os";
3727
- import { join as join13 } from "path";
3728
- var DEVLOG_DIR = join13(homedir5(), "git/blog/src/content/devlog");
3729
- function loadDevlogEntries(repoName) {
3730
- const entries = /* @__PURE__ */ new Map();
3735
+ import { join as join14 } from "path";
3736
+ var DEVLOG_DIR = join14(BLOG_REPO_ROOT, "src/content/devlog");
3737
+ function extractFrontmatter(content) {
3738
+ const fm = content.match(/^---\n([\s\S]*?)\n---/);
3739
+ return fm?.[1] ?? null;
3740
+ }
3741
+ function matchField(frontmatter, pattern2) {
3742
+ return frontmatter.match(pattern2)?.[1]?.trim() ?? null;
3743
+ }
3744
+ function parseFrontmatter(content, filename) {
3745
+ const frontmatter = extractFrontmatter(content);
3746
+ if (!frontmatter) return null;
3747
+ const date = matchField(frontmatter, /date:\s*"?(\d{4}-\d{2}-\d{2})"?/);
3748
+ const tagsRaw = matchField(frontmatter, /tags:\s*\[([^\]]*)\]/);
3749
+ if (!date || !tagsRaw) return null;
3750
+ const repoTag = tagsRaw.split(",")[0]?.trim();
3751
+ if (!repoTag) return null;
3752
+ return {
3753
+ date,
3754
+ repoTag,
3755
+ version: matchField(frontmatter, /version:\s*(.+)/),
3756
+ title: matchField(frontmatter, /title:\s*(.+)/),
3757
+ filename
3758
+ };
3759
+ }
3760
+ function readDevlogFiles(callback) {
3731
3761
  try {
3732
3762
  const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
3733
3763
  for (const file of files) {
3734
- const content = readFileSync17(join13(DEVLOG_DIR, file), "utf-8");
3735
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
3736
- if (frontmatterMatch) {
3737
- const frontmatter = frontmatterMatch[1];
3738
- const dateMatch = frontmatter.match(/date:\s*"?(\d{4}-\d{2}-\d{2})"?/);
3739
- const versionMatch = frontmatter.match(/version:\s*(.+)/);
3740
- const titleMatch = frontmatter.match(/title:\s*(.+)/);
3741
- const tagsMatch = frontmatter.match(/tags:\s*\[([^\]]*)\]/);
3742
- if (dateMatch && versionMatch && titleMatch && tagsMatch) {
3743
- const tags = tagsMatch[1].split(",").map((t) => t.trim());
3744
- const firstTag = tags[0];
3745
- if (firstTag !== repoName) {
3746
- continue;
3747
- }
3748
- const date = dateMatch[1];
3749
- const version2 = versionMatch[1].trim();
3750
- const title = titleMatch[1].trim();
3751
- const existing = entries.get(date) || [];
3752
- existing.push({ version: version2, title, filename: file });
3753
- entries.set(date, existing);
3754
- }
3755
- }
3764
+ const content = readFileSync17(join14(DEVLOG_DIR, file), "utf-8");
3765
+ const parsed = parseFrontmatter(content, file);
3766
+ if (parsed) callback(parsed);
3756
3767
  }
3757
3768
  } catch {
3758
3769
  }
3770
+ }
3771
+ function loadDevlogEntries(repoName) {
3772
+ const entries = /* @__PURE__ */ new Map();
3773
+ readDevlogFiles((parsed) => {
3774
+ if (parsed.repoTag !== repoName) return;
3775
+ if (!parsed.version || !parsed.title) return;
3776
+ const existing = entries.get(parsed.date) || [];
3777
+ existing.push({
3778
+ version: parsed.version,
3779
+ title: parsed.title,
3780
+ filename: parsed.filename
3781
+ });
3782
+ entries.set(parsed.date, existing);
3783
+ });
3759
3784
  return entries;
3760
3785
  }
3786
+ function loadAllDevlogLatestDates() {
3787
+ const latest = /* @__PURE__ */ new Map();
3788
+ readDevlogFiles((parsed) => {
3789
+ const existing = latest.get(parsed.repoTag);
3790
+ if (!existing || parsed.date > existing) {
3791
+ latest.set(parsed.repoTag, parsed.date);
3792
+ }
3793
+ });
3794
+ return latest;
3795
+ }
3761
3796
 
3762
3797
  // src/commands/devlog/shared.ts
3763
3798
  function getCommitFiles(hash) {
@@ -3828,8 +3863,8 @@ function list3(options2) {
3828
3863
  const config = loadConfig();
3829
3864
  const days = options2.days ?? 30;
3830
3865
  const ignore2 = options2.ignore ?? config.devlog?.ignore ?? [];
3831
- const skipDays = new Set(config.devlog?.skip?.days ?? []);
3832
3866
  const repoName = basename3(process.cwd());
3867
+ const skipDays = loadBlogSkipDays(repoName);
3833
3868
  const devlogEntries = loadDevlogEntries(repoName);
3834
3869
  const reverseFlag = options2.reverse ? "--reverse " : "";
3835
3870
  const limitFlag = options2.reverse ? "" : "-n 500 ";
@@ -3973,8 +4008,8 @@ function printVersionInfo(config, lastInfo, firstHash) {
3973
4008
  function resolveIgnoreList(options2, config) {
3974
4009
  return options2.ignore ?? config.devlog?.ignore ?? [];
3975
4010
  }
3976
- function resolveSkipDays(config) {
3977
- return new Set(config.devlog?.skip?.days ?? []);
4011
+ function resolveSkipDays(repoName) {
4012
+ return loadBlogSkipDays(repoName);
3978
4013
  }
3979
4014
  function getLastDate(lastInfo) {
3980
4015
  return lastInfo?.date ?? null;
@@ -4014,7 +4049,10 @@ function fetchNextCommits(ctx) {
4014
4049
  ctx.ignore,
4015
4050
  getLastDate(ctx.lastInfo)
4016
4051
  );
4017
- const targetDate = findTargetDate(commitsByDate, resolveSkipDays(ctx.config));
4052
+ const targetDate = findTargetDate(
4053
+ commitsByDate,
4054
+ resolveSkipDays(ctx.repoName)
4055
+ );
4018
4056
  return targetDate ? { targetDate, commits: getCommitsForDate(commitsByDate, targetDate) } : null;
4019
4057
  }
4020
4058
  function showResult(ctx, found) {
@@ -4029,41 +4067,129 @@ function next(options2) {
4029
4067
  showResult(ctx, fetchNextCommits(ctx));
4030
4068
  }
4031
4069
 
4032
- // src/commands/devlog/skip.ts
4070
+ // src/commands/devlog/repos/index.ts
4071
+ import { execSync as execSync19 } from "child_process";
4072
+
4073
+ // src/commands/devlog/repos/printReposTable.ts
4033
4074
  import chalk42 from "chalk";
4075
+ function colorStatus(status2) {
4076
+ if (status2 === "missing") return chalk42.red(status2);
4077
+ if (status2 === "outdated") return chalk42.yellow(status2);
4078
+ return chalk42.green(status2);
4079
+ }
4080
+ function formatRow(row, nameWidth) {
4081
+ const devlog = (row.lastDevlog ?? "-").padEnd(11);
4082
+ return `${row.name.padEnd(nameWidth)} ${row.lastPush} ${devlog} ${colorStatus(row.status)}`;
4083
+ }
4084
+ function printReposTable(rows) {
4085
+ const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));
4086
+ const header = [
4087
+ "Repo".padEnd(nameWidth),
4088
+ "Last Push".padEnd(10),
4089
+ "Last Devlog".padEnd(11),
4090
+ "Status"
4091
+ ].join(" ");
4092
+ console.log(chalk42.dim(header));
4093
+ console.log(chalk42.dim("-".repeat(header.length)));
4094
+ for (const row of rows) {
4095
+ console.log(formatRow(row, nameWidth));
4096
+ }
4097
+ }
4098
+
4099
+ // src/commands/devlog/repos/index.ts
4100
+ var statusOrder = { missing: 0, outdated: 1, ok: 2 };
4101
+ function getStatus(lastPush, lastDevlog) {
4102
+ if (!lastDevlog) return "missing";
4103
+ return lastDevlog < lastPush ? "outdated" : "ok";
4104
+ }
4105
+ function fetchRepos(days, all) {
4106
+ const json = execSync19(
4107
+ "gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
4108
+ { encoding: "utf-8" }
4109
+ );
4110
+ const allRepos = JSON.parse(json);
4111
+ const cutoff = /* @__PURE__ */ new Date();
4112
+ cutoff.setDate(cutoff.getDate() - days);
4113
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
4114
+ return allRepos.filter((r) => {
4115
+ if (r.isArchived) return false;
4116
+ if (all) return true;
4117
+ return r.pushedAt.slice(0, 10) >= cutoffStr;
4118
+ });
4119
+ }
4120
+ function toRow(repo, devlogDates) {
4121
+ const lastPush = repo.pushedAt.slice(0, 10);
4122
+ const lastDevlog = devlogDates.get(repo.name) ?? null;
4123
+ return {
4124
+ name: repo.name,
4125
+ lastPush,
4126
+ lastDevlog,
4127
+ status: getStatus(lastPush, lastDevlog)
4128
+ };
4129
+ }
4130
+ function sortRows(rows) {
4131
+ return rows.sort((a, b) => {
4132
+ const s = statusOrder[a.status] - statusOrder[b.status];
4133
+ if (s !== 0) return s;
4134
+ return b.lastPush.localeCompare(a.lastPush);
4135
+ });
4136
+ }
4137
+ function repos(options2) {
4138
+ const ghRepos = fetchRepos(options2.days ?? 30, options2.all ?? false);
4139
+ if (ghRepos.length === 0) {
4140
+ console.log("No repos with recent activity found.");
4141
+ return;
4142
+ }
4143
+ const devlogDates = loadAllDevlogLatestDates();
4144
+ const rows = ghRepos.map((repo) => toRow(repo, devlogDates));
4145
+ printReposTable(sortRows(rows));
4146
+ }
4147
+
4148
+ // src/commands/devlog/skip.ts
4149
+ import { writeFileSync as writeFileSync15 } from "fs";
4150
+ import { join as join15 } from "path";
4151
+ import chalk43 from "chalk";
4152
+ import { stringify as stringifyYaml4 } from "yaml";
4153
+ function getBlogConfigPath() {
4154
+ return join15(BLOG_REPO_ROOT, "assist.yml");
4155
+ }
4034
4156
  function skip(date) {
4035
4157
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
4036
- console.log(chalk42.red("Invalid date format. Use YYYY-MM-DD"));
4158
+ console.log(chalk43.red("Invalid date format. Use YYYY-MM-DD"));
4037
4159
  process.exit(1);
4038
4160
  }
4039
- const config = loadProjectConfig();
4161
+ const repoName = getRepoName();
4162
+ const configPath = getBlogConfigPath();
4163
+ const config = loadRawYaml(configPath);
4040
4164
  const devlog = config.devlog ?? {};
4041
4165
  const skip2 = devlog.skip ?? {};
4042
- const skipDays = skip2.days ?? [];
4166
+ const skipDays = skip2[repoName] ?? [];
4043
4167
  if (skipDays.includes(date)) {
4044
- console.log(chalk42.yellow(`${date} is already in skip list`));
4168
+ console.log(
4169
+ chalk43.yellow(`${date} is already in skip list for ${repoName}`)
4170
+ );
4045
4171
  return;
4046
4172
  }
4047
4173
  skipDays.push(date);
4048
4174
  skipDays.sort();
4049
- skip2.days = skipDays;
4175
+ skip2[repoName] = skipDays;
4050
4176
  devlog.skip = skip2;
4051
4177
  config.devlog = devlog;
4052
- saveConfig(config);
4053
- console.log(chalk42.green(`Added ${date} to skip list`));
4178
+ writeFileSync15(configPath, stringifyYaml4(config, { lineWidth: 0 }));
4179
+ console.log(chalk43.green(`Added ${date} to skip list for ${repoName}`));
4054
4180
  }
4055
4181
 
4056
4182
  // src/commands/devlog/version.ts
4057
- import chalk43 from "chalk";
4183
+ import chalk44 from "chalk";
4058
4184
  function version() {
4059
4185
  const config = loadConfig();
4060
4186
  const name = getRepoName();
4061
4187
  const lastInfo = getLastVersionInfo(name, config);
4062
4188
  const lastVersion = lastInfo?.version ?? null;
4063
4189
  const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
4064
- console.log(`${chalk43.bold("name:")} ${name}`);
4065
- console.log(`${chalk43.bold("last:")} ${lastVersion ?? chalk43.dim("none")}`);
4066
- console.log(`${chalk43.bold("next:")} ${nextVersion ?? chalk43.dim("none")}`);
4190
+ console.log(`${chalk44.bold("name:")} ${name}`);
4191
+ console.log(`${chalk44.bold("last:")} ${lastVersion ?? chalk44.dim("none")}`);
4192
+ console.log(`${chalk44.bold("next:")} ${nextVersion ?? chalk44.dim("none")}`);
4067
4193
  }
4068
4194
 
4069
4195
  // src/commands/registerDevlog.ts
@@ -4077,6 +4203,11 @@ function registerDevlog(program2) {
4077
4203
  devlogCommand.command("version").description("Show current repo name and version info").action(version);
4078
4204
  devlogCommand.command("next").description("Show commits for the day after the last versioned entry").option("-v, --verbose", "Show file names for each commit").action(next);
4079
4205
  devlogCommand.command("skip <date>").description("Add a date (YYYY-MM-DD) to the skip list").action(skip);
4206
+ devlogCommand.command("repos").description("Show repos missing devlog entries").option(
4207
+ "--days <number>",
4208
+ "Only show repos pushed within N days (default: 30)",
4209
+ Number.parseInt
4210
+ ).option("--all", "Show all non-archived repos regardless of push date").action(repos);
4080
4211
  }
4081
4212
 
4082
4213
  // src/commands/netframework/buildTree.ts
@@ -4175,30 +4306,30 @@ function escapeRegex(s) {
4175
4306
  }
4176
4307
 
4177
4308
  // src/commands/netframework/printTree.ts
4178
- import chalk44 from "chalk";
4309
+ import chalk45 from "chalk";
4179
4310
  function printNodes(nodes, prefix2) {
4180
4311
  for (let i = 0; i < nodes.length; i++) {
4181
4312
  const isLast = i === nodes.length - 1;
4182
4313
  const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
4183
4314
  const childPrefix = isLast ? " " : "\u2502 ";
4184
4315
  const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
4185
- const label2 = isMissing ? chalk44.red(nodes[i].relativePath) : nodes[i].relativePath;
4316
+ const label2 = isMissing ? chalk45.red(nodes[i].relativePath) : nodes[i].relativePath;
4186
4317
  console.log(`${prefix2}${connector}${label2}`);
4187
4318
  printNodes(nodes[i].children, prefix2 + childPrefix);
4188
4319
  }
4189
4320
  }
4190
4321
  function printTree(tree, totalCount, solutions) {
4191
- console.log(chalk44.bold("\nProject Dependency Tree"));
4192
- console.log(chalk44.cyan(tree.relativePath));
4322
+ console.log(chalk45.bold("\nProject Dependency Tree"));
4323
+ console.log(chalk45.cyan(tree.relativePath));
4193
4324
  printNodes(tree.children, "");
4194
- console.log(chalk44.dim(`
4325
+ console.log(chalk45.dim(`
4195
4326
  ${totalCount} projects total (including root)`));
4196
- console.log(chalk44.bold("\nSolution Membership"));
4327
+ console.log(chalk45.bold("\nSolution Membership"));
4197
4328
  if (solutions.length === 0) {
4198
- console.log(chalk44.yellow(" Not found in any .sln"));
4329
+ console.log(chalk45.yellow(" Not found in any .sln"));
4199
4330
  } else {
4200
4331
  for (const sln of solutions) {
4201
- console.log(` ${chalk44.green(sln)}`);
4332
+ console.log(` ${chalk45.green(sln)}`);
4202
4333
  }
4203
4334
  }
4204
4335
  console.log();
@@ -4227,7 +4358,7 @@ function printJson(tree, totalCount, solutions) {
4227
4358
  // src/commands/netframework/resolveCsproj.ts
4228
4359
  import { existsSync as existsSync21 } from "fs";
4229
4360
  import path20 from "path";
4230
- import chalk45 from "chalk";
4361
+ import chalk46 from "chalk";
4231
4362
 
4232
4363
  // src/commands/netframework/findRepoRoot.ts
4233
4364
  import { existsSync as existsSync20 } from "fs";
@@ -4247,12 +4378,12 @@ function findRepoRoot(dir) {
4247
4378
  function resolveCsproj(csprojPath) {
4248
4379
  const resolved = path20.resolve(csprojPath);
4249
4380
  if (!existsSync21(resolved)) {
4250
- console.error(chalk45.red(`File not found: ${resolved}`));
4381
+ console.error(chalk46.red(`File not found: ${resolved}`));
4251
4382
  process.exit(1);
4252
4383
  }
4253
4384
  const repoRoot = findRepoRoot(path20.dirname(resolved));
4254
4385
  if (!repoRoot) {
4255
- console.error(chalk45.red("Could not find git repository root"));
4386
+ console.error(chalk46.red("Could not find git repository root"));
4256
4387
  process.exit(1);
4257
4388
  }
4258
4389
  return { resolved, repoRoot };
@@ -4272,12 +4403,12 @@ async function deps(csprojPath, options2) {
4272
4403
  }
4273
4404
 
4274
4405
  // src/commands/netframework/inSln.ts
4275
- import chalk46 from "chalk";
4406
+ import chalk47 from "chalk";
4276
4407
  async function inSln(csprojPath) {
4277
4408
  const { resolved, repoRoot } = resolveCsproj(csprojPath);
4278
4409
  const solutions = findContainingSolutions(resolved, repoRoot);
4279
4410
  if (solutions.length === 0) {
4280
- console.log(chalk46.yellow("Not found in any .sln file"));
4411
+ console.log(chalk47.yellow("Not found in any .sln file"));
4281
4412
  process.exit(1);
4282
4413
  }
4283
4414
  for (const sln of solutions) {
@@ -4294,12 +4425,12 @@ function registerNetframework(program2) {
4294
4425
 
4295
4426
  // src/commands/prs/comment.ts
4296
4427
  import { spawnSync as spawnSync2 } from "child_process";
4297
- import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync15 } from "fs";
4428
+ import { unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "fs";
4298
4429
  import { tmpdir as tmpdir2 } from "os";
4299
- import { join as join14 } from "path";
4430
+ import { join as join16 } from "path";
4300
4431
 
4301
4432
  // src/commands/prs/shared.ts
4302
- import { execSync as execSync19 } from "child_process";
4433
+ import { execSync as execSync20 } from "child_process";
4303
4434
  function isGhNotInstalled(error) {
4304
4435
  if (error instanceof Error) {
4305
4436
  const msg = error.message.toLowerCase();
@@ -4315,14 +4446,14 @@ function isNotFound(error) {
4315
4446
  }
4316
4447
  function getRepoInfo() {
4317
4448
  const repoInfo = JSON.parse(
4318
- execSync19("gh repo view --json owner,name", { encoding: "utf-8" })
4449
+ execSync20("gh repo view --json owner,name", { encoding: "utf-8" })
4319
4450
  );
4320
4451
  return { org: repoInfo.owner.login, repo: repoInfo.name };
4321
4452
  }
4322
4453
  function getCurrentPrNumber() {
4323
4454
  try {
4324
4455
  const prInfo = JSON.parse(
4325
- execSync19("gh pr view --json number", { encoding: "utf-8" })
4456
+ execSync20("gh pr view --json number", { encoding: "utf-8" })
4326
4457
  );
4327
4458
  return prInfo.number;
4328
4459
  } catch (error) {
@@ -4336,7 +4467,7 @@ function getCurrentPrNumber() {
4336
4467
  function getCurrentPrNodeId() {
4337
4468
  try {
4338
4469
  const prInfo = JSON.parse(
4339
- execSync19("gh pr view --json id", { encoding: "utf-8" })
4470
+ execSync20("gh pr view --json id", { encoding: "utf-8" })
4340
4471
  );
4341
4472
  return prInfo.id;
4342
4473
  } catch (error) {
@@ -4368,8 +4499,8 @@ function comment(path35, line, body) {
4368
4499
  validateLine(line);
4369
4500
  try {
4370
4501
  const prId = getCurrentPrNodeId();
4371
- const queryFile = join14(tmpdir2(), `gh-query-${Date.now()}.graphql`);
4372
- writeFileSync15(queryFile, MUTATION);
4502
+ const queryFile = join16(tmpdir2(), `gh-query-${Date.now()}.graphql`);
4503
+ writeFileSync16(queryFile, MUTATION);
4373
4504
  try {
4374
4505
  const result = spawnSync2(
4375
4506
  "gh",
@@ -4407,20 +4538,20 @@ function comment(path35, line, body) {
4407
4538
  }
4408
4539
 
4409
4540
  // src/commands/prs/fixed.ts
4410
- import { execSync as execSync21 } from "child_process";
4541
+ import { execSync as execSync22 } from "child_process";
4411
4542
 
4412
4543
  // src/commands/prs/resolveCommentWithReply.ts
4413
- import { execSync as execSync20 } from "child_process";
4414
- import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync16 } from "fs";
4544
+ import { execSync as execSync21 } from "child_process";
4545
+ import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync17 } from "fs";
4415
4546
  import { tmpdir as tmpdir3 } from "os";
4416
- import { join as join16 } from "path";
4547
+ import { join as join18 } from "path";
4417
4548
 
4418
4549
  // src/commands/prs/loadCommentsCache.ts
4419
4550
  import { existsSync as existsSync22, readFileSync as readFileSync20, unlinkSync as unlinkSync4 } from "fs";
4420
- import { join as join15 } from "path";
4551
+ import { join as join17 } from "path";
4421
4552
  import { parse as parse2 } from "yaml";
4422
4553
  function getCachePath(prNumber) {
4423
- return join15(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
4554
+ return join17(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
4424
4555
  }
4425
4556
  function loadCommentsCache(prNumber) {
4426
4557
  const cachePath = getCachePath(prNumber);
@@ -4440,17 +4571,17 @@ function deleteCommentsCache(prNumber) {
4440
4571
 
4441
4572
  // src/commands/prs/resolveCommentWithReply.ts
4442
4573
  function replyToComment(org, repo, prNumber, commentId, message) {
4443
- execSync20(
4574
+ execSync21(
4444
4575
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
4445
4576
  { stdio: "inherit" }
4446
4577
  );
4447
4578
  }
4448
4579
  function resolveThread(threadId) {
4449
4580
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
4450
- const queryFile = join16(tmpdir3(), `gh-mutation-${Date.now()}.graphql`);
4451
- writeFileSync16(queryFile, mutation);
4581
+ const queryFile = join18(tmpdir3(), `gh-mutation-${Date.now()}.graphql`);
4582
+ writeFileSync17(queryFile, mutation);
4452
4583
  try {
4453
- execSync20(
4584
+ execSync21(
4454
4585
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
4455
4586
  { stdio: "inherit" }
4456
4587
  );
@@ -4502,7 +4633,7 @@ function resolveCommentWithReply(commentId, message) {
4502
4633
  // src/commands/prs/fixed.ts
4503
4634
  function verifySha(sha) {
4504
4635
  try {
4505
- return execSync21(`git rev-parse --verify ${sha}`, {
4636
+ return execSync22(`git rev-parse --verify ${sha}`, {
4506
4637
  encoding: "utf-8"
4507
4638
  }).trim();
4508
4639
  } catch {
@@ -4528,21 +4659,21 @@ function fixed(commentId, sha) {
4528
4659
  }
4529
4660
 
4530
4661
  // src/commands/prs/listComments/index.ts
4531
- import { existsSync as existsSync23, mkdirSync as mkdirSync5, writeFileSync as writeFileSync18 } from "fs";
4532
- import { join as join18 } from "path";
4662
+ import { existsSync as existsSync23, mkdirSync as mkdirSync5, writeFileSync as writeFileSync19 } from "fs";
4663
+ import { join as join20 } from "path";
4533
4664
  import { stringify } from "yaml";
4534
4665
 
4535
4666
  // src/commands/prs/fetchThreadIds.ts
4536
- import { execSync as execSync22 } from "child_process";
4537
- import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
4667
+ import { execSync as execSync23 } from "child_process";
4668
+ import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync18 } from "fs";
4538
4669
  import { tmpdir as tmpdir4 } from "os";
4539
- import { join as join17 } from "path";
4670
+ import { join as join19 } from "path";
4540
4671
  var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
4541
4672
  function fetchThreadIds(org, repo, prNumber) {
4542
- const queryFile = join17(tmpdir4(), `gh-query-${Date.now()}.graphql`);
4543
- writeFileSync17(queryFile, THREAD_QUERY);
4673
+ const queryFile = join19(tmpdir4(), `gh-query-${Date.now()}.graphql`);
4674
+ writeFileSync18(queryFile, THREAD_QUERY);
4544
4675
  try {
4545
- const result = execSync22(
4676
+ const result = execSync23(
4546
4677
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
4547
4678
  { encoding: "utf-8" }
4548
4679
  );
@@ -4564,9 +4695,9 @@ function fetchThreadIds(org, repo, prNumber) {
4564
4695
  }
4565
4696
 
4566
4697
  // src/commands/prs/listComments/fetchReviewComments.ts
4567
- import { execSync as execSync23 } from "child_process";
4698
+ import { execSync as execSync24 } from "child_process";
4568
4699
  function fetchJson(endpoint) {
4569
- const result = execSync23(`gh api --paginate ${endpoint}`, {
4700
+ const result = execSync24(`gh api --paginate ${endpoint}`, {
4570
4701
  encoding: "utf-8"
4571
4702
  });
4572
4703
  if (!result.trim()) return [];
@@ -4608,20 +4739,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
4608
4739
  }
4609
4740
 
4610
4741
  // src/commands/prs/listComments/printComments.ts
4611
- import chalk47 from "chalk";
4742
+ import chalk48 from "chalk";
4612
4743
  function formatForHuman(comment2) {
4613
4744
  if (comment2.type === "review") {
4614
- const stateColor = comment2.state === "APPROVED" ? chalk47.green : comment2.state === "CHANGES_REQUESTED" ? chalk47.red : chalk47.yellow;
4745
+ const stateColor = comment2.state === "APPROVED" ? chalk48.green : comment2.state === "CHANGES_REQUESTED" ? chalk48.red : chalk48.yellow;
4615
4746
  return [
4616
- `${chalk47.cyan("Review")} by ${chalk47.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
4747
+ `${chalk48.cyan("Review")} by ${chalk48.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
4617
4748
  comment2.body,
4618
4749
  ""
4619
4750
  ].join("\n");
4620
4751
  }
4621
4752
  const location = comment2.line ? `:${comment2.line}` : "";
4622
4753
  return [
4623
- `${chalk47.cyan("Line comment")} by ${chalk47.bold(comment2.user)} on ${chalk47.dim(`${comment2.path}${location}`)}`,
4624
- chalk47.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
4754
+ `${chalk48.cyan("Line comment")} by ${chalk48.bold(comment2.user)} on ${chalk48.dim(`${comment2.path}${location}`)}`,
4755
+ chalk48.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
4625
4756
  comment2.body,
4626
4757
  ""
4627
4758
  ].join("\n");
@@ -4653,7 +4784,7 @@ function printComments(result) {
4653
4784
 
4654
4785
  // src/commands/prs/listComments/index.ts
4655
4786
  function writeCommentsCache(prNumber, comments) {
4656
- const assistDir = join18(process.cwd(), ".assist");
4787
+ const assistDir = join20(process.cwd(), ".assist");
4657
4788
  if (!existsSync23(assistDir)) {
4658
4789
  mkdirSync5(assistDir, { recursive: true });
4659
4790
  }
@@ -4662,8 +4793,8 @@ function writeCommentsCache(prNumber, comments) {
4662
4793
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
4663
4794
  comments
4664
4795
  };
4665
- const cachePath = join18(assistDir, `pr-${prNumber}-comments.yaml`);
4666
- writeFileSync18(cachePath, stringify(cacheData));
4796
+ const cachePath = join20(assistDir, `pr-${prNumber}-comments.yaml`);
4797
+ writeFileSync19(cachePath, stringify(cacheData));
4667
4798
  }
4668
4799
  function handleKnownErrors(error) {
4669
4800
  if (isGhNotInstalled(error)) {
@@ -4695,7 +4826,7 @@ async function listComments() {
4695
4826
  ];
4696
4827
  updateCache(prNumber, allComments);
4697
4828
  const hasLineComments = allComments.some((c) => c.type === "line");
4698
- const cachePath = hasLineComments ? join18(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
4829
+ const cachePath = hasLineComments ? join20(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
4699
4830
  return { comments: allComments, cachePath };
4700
4831
  } catch (error) {
4701
4832
  const handled = handleKnownErrors(error);
@@ -4705,37 +4836,37 @@ async function listComments() {
4705
4836
  }
4706
4837
 
4707
4838
  // src/commands/prs/prs/index.ts
4708
- import { execSync as execSync24 } from "child_process";
4839
+ import { execSync as execSync25 } from "child_process";
4709
4840
 
4710
4841
  // src/commands/prs/prs/displayPaginated/index.ts
4711
4842
  import enquirer5 from "enquirer";
4712
4843
 
4713
4844
  // src/commands/prs/prs/displayPaginated/printPr.ts
4714
- import chalk48 from "chalk";
4845
+ import chalk49 from "chalk";
4715
4846
  var STATUS_MAP = {
4716
- MERGED: (pr) => pr.mergedAt ? { label: chalk48.magenta("merged"), date: pr.mergedAt } : null,
4717
- CLOSED: (pr) => pr.closedAt ? { label: chalk48.red("closed"), date: pr.closedAt } : null
4847
+ MERGED: (pr) => pr.mergedAt ? { label: chalk49.magenta("merged"), date: pr.mergedAt } : null,
4848
+ CLOSED: (pr) => pr.closedAt ? { label: chalk49.red("closed"), date: pr.closedAt } : null
4718
4849
  };
4719
4850
  function defaultStatus(pr) {
4720
- return { label: chalk48.green("opened"), date: pr.createdAt };
4851
+ return { label: chalk49.green("opened"), date: pr.createdAt };
4721
4852
  }
4722
- function getStatus(pr) {
4853
+ function getStatus2(pr) {
4723
4854
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
4724
4855
  }
4725
4856
  function formatDate(dateStr) {
4726
4857
  return new Date(dateStr).toISOString().split("T")[0];
4727
4858
  }
4728
4859
  function formatPrHeader(pr, status2) {
4729
- return `${chalk48.cyan(`#${pr.number}`)} ${pr.title} ${chalk48.dim(`(${pr.author.login},`)} ${status2.label} ${chalk48.dim(`${formatDate(status2.date)})`)}`;
4860
+ return `${chalk49.cyan(`#${pr.number}`)} ${pr.title} ${chalk49.dim(`(${pr.author.login},`)} ${status2.label} ${chalk49.dim(`${formatDate(status2.date)})`)}`;
4730
4861
  }
4731
4862
  function logPrDetails(pr) {
4732
4863
  console.log(
4733
- chalk48.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
4864
+ chalk49.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
4734
4865
  );
4735
4866
  console.log();
4736
4867
  }
4737
4868
  function printPr(pr) {
4738
- console.log(formatPrHeader(pr, getStatus(pr)));
4869
+ console.log(formatPrHeader(pr, getStatus2(pr)));
4739
4870
  logPrDetails(pr);
4740
4871
  }
4741
4872
 
@@ -4811,7 +4942,7 @@ async function displayPaginated(pullRequests) {
4811
4942
  async function prs(options2) {
4812
4943
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
4813
4944
  try {
4814
- const result = execSync24(
4945
+ const result = execSync25(
4815
4946
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
4816
4947
  { encoding: "utf-8" }
4817
4948
  );
@@ -4834,7 +4965,7 @@ async function prs(options2) {
4834
4965
  }
4835
4966
 
4836
4967
  // src/commands/prs/wontfix.ts
4837
- import { execSync as execSync25 } from "child_process";
4968
+ import { execSync as execSync26 } from "child_process";
4838
4969
  function validateReason(reason) {
4839
4970
  const lowerReason = reason.toLowerCase();
4840
4971
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -4851,7 +4982,7 @@ function validateShaReferences(reason) {
4851
4982
  const invalidShas = [];
4852
4983
  for (const sha of shas) {
4853
4984
  try {
4854
- execSync25(`git cat-file -t ${sha}`, { stdio: "pipe" });
4985
+ execSync26(`git cat-file -t ${sha}`, { stdio: "pipe" });
4855
4986
  } catch {
4856
4987
  invalidShas.push(sha);
4857
4988
  }
@@ -4900,7 +5031,7 @@ import { spawn as spawn3 } from "child_process";
4900
5031
  import * as path21 from "path";
4901
5032
 
4902
5033
  // src/commands/refactor/logViolations.ts
4903
- import chalk49 from "chalk";
5034
+ import chalk50 from "chalk";
4904
5035
  var DEFAULT_MAX_LINES = 100;
4905
5036
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
4906
5037
  if (violations.length === 0) {
@@ -4909,43 +5040,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
4909
5040
  }
4910
5041
  return;
4911
5042
  }
4912
- console.error(chalk49.red(`
5043
+ console.error(chalk50.red(`
4913
5044
  Refactor check failed:
4914
5045
  `));
4915
- console.error(chalk49.red(` The following files exceed ${maxLines} lines:
5046
+ console.error(chalk50.red(` The following files exceed ${maxLines} lines:
4916
5047
  `));
4917
5048
  for (const violation of violations) {
4918
- console.error(chalk49.red(` ${violation.file} (${violation.lines} lines)`));
5049
+ console.error(chalk50.red(` ${violation.file} (${violation.lines} lines)`));
4919
5050
  }
4920
5051
  console.error(
4921
- chalk49.yellow(
5052
+ chalk50.yellow(
4922
5053
  `
4923
5054
  Each file needs to be sensibly refactored, or if there is no sensible
4924
5055
  way to refactor it, ignore it with:
4925
5056
  `
4926
5057
  )
4927
5058
  );
4928
- console.error(chalk49.gray(` assist refactor ignore <file>
5059
+ console.error(chalk50.gray(` assist refactor ignore <file>
4929
5060
  `));
4930
5061
  if (process.env.CLAUDECODE) {
4931
- console.error(chalk49.cyan(`
5062
+ console.error(chalk50.cyan(`
4932
5063
  ## Extracting Code to New Files
4933
5064
  `));
4934
5065
  console.error(
4935
- chalk49.cyan(
5066
+ chalk50.cyan(
4936
5067
  ` When extracting logic from one file to another, consider where the extracted code belongs:
4937
5068
  `
4938
5069
  )
4939
5070
  );
4940
5071
  console.error(
4941
- chalk49.cyan(
5072
+ chalk50.cyan(
4942
5073
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
4943
5074
  original file's domain, create a new folder containing both the original and extracted files.
4944
5075
  `
4945
5076
  )
4946
5077
  );
4947
5078
  console.error(
4948
- chalk49.cyan(
5079
+ chalk50.cyan(
4949
5080
  ` 2. Share common utilities: If the extracted code can be reused across multiple
4950
5081
  domains, move it to a common/shared folder.
4951
5082
  `
@@ -4955,7 +5086,7 @@ Refactor check failed:
4955
5086
  }
4956
5087
 
4957
5088
  // src/commands/refactor/check/getViolations/index.ts
4958
- import { execSync as execSync26 } from "child_process";
5089
+ import { execSync as execSync27 } from "child_process";
4959
5090
  import fs15 from "fs";
4960
5091
  import { minimatch as minimatch4 } from "minimatch";
4961
5092
 
@@ -5005,7 +5136,7 @@ function getGitFiles(options2) {
5005
5136
  }
5006
5137
  const files = /* @__PURE__ */ new Set();
5007
5138
  if (options2.staged || options2.modified) {
5008
- const staged = execSync26("git diff --cached --name-only", {
5139
+ const staged = execSync27("git diff --cached --name-only", {
5009
5140
  encoding: "utf-8"
5010
5141
  });
5011
5142
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -5013,7 +5144,7 @@ function getGitFiles(options2) {
5013
5144
  }
5014
5145
  }
5015
5146
  if (options2.unstaged || options2.modified) {
5016
- const unstaged = execSync26("git diff --name-only", { encoding: "utf-8" });
5147
+ const unstaged = execSync27("git diff --name-only", { encoding: "utf-8" });
5017
5148
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
5018
5149
  files.add(file);
5019
5150
  }
@@ -5101,11 +5232,11 @@ async function check(pattern2, options2) {
5101
5232
 
5102
5233
  // src/commands/refactor/ignore.ts
5103
5234
  import fs16 from "fs";
5104
- import chalk50 from "chalk";
5235
+ import chalk51 from "chalk";
5105
5236
  var REFACTOR_YML_PATH2 = "refactor.yml";
5106
5237
  function ignore(file) {
5107
5238
  if (!fs16.existsSync(file)) {
5108
- console.error(chalk50.red(`Error: File does not exist: ${file}`));
5239
+ console.error(chalk51.red(`Error: File does not exist: ${file}`));
5109
5240
  process.exit(1);
5110
5241
  }
5111
5242
  const content = fs16.readFileSync(file, "utf-8");
@@ -5121,7 +5252,7 @@ function ignore(file) {
5121
5252
  fs16.writeFileSync(REFACTOR_YML_PATH2, entry);
5122
5253
  }
5123
5254
  console.log(
5124
- chalk50.green(
5255
+ chalk51.green(
5125
5256
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
5126
5257
  )
5127
5258
  );
@@ -5129,7 +5260,7 @@ function ignore(file) {
5129
5260
 
5130
5261
  // src/commands/refactor/restructure/index.ts
5131
5262
  import path30 from "path";
5132
- import chalk53 from "chalk";
5263
+ import chalk54 from "chalk";
5133
5264
 
5134
5265
  // src/commands/refactor/restructure/buildImportGraph/index.ts
5135
5266
  import path22 from "path";
@@ -5372,50 +5503,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
5372
5503
 
5373
5504
  // src/commands/refactor/restructure/displayPlan.ts
5374
5505
  import path26 from "path";
5375
- import chalk51 from "chalk";
5506
+ import chalk52 from "chalk";
5376
5507
  function relPath(filePath) {
5377
5508
  return path26.relative(process.cwd(), filePath);
5378
5509
  }
5379
5510
  function displayMoves(plan) {
5380
5511
  if (plan.moves.length === 0) return;
5381
- console.log(chalk51.bold("\nFile moves:"));
5512
+ console.log(chalk52.bold("\nFile moves:"));
5382
5513
  for (const move of plan.moves) {
5383
5514
  console.log(
5384
- ` ${chalk51.red(relPath(move.from))} \u2192 ${chalk51.green(relPath(move.to))}`
5515
+ ` ${chalk52.red(relPath(move.from))} \u2192 ${chalk52.green(relPath(move.to))}`
5385
5516
  );
5386
- console.log(chalk51.dim(` ${move.reason}`));
5517
+ console.log(chalk52.dim(` ${move.reason}`));
5387
5518
  }
5388
5519
  }
5389
5520
  function displayRewrites(rewrites) {
5390
5521
  if (rewrites.length === 0) return;
5391
5522
  const affectedFiles = new Set(rewrites.map((r) => r.file));
5392
- console.log(chalk51.bold(`
5523
+ console.log(chalk52.bold(`
5393
5524
  Import rewrites (${affectedFiles.size} files):`));
5394
5525
  for (const file of affectedFiles) {
5395
- console.log(` ${chalk51.cyan(relPath(file))}:`);
5526
+ console.log(` ${chalk52.cyan(relPath(file))}:`);
5396
5527
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
5397
5528
  (r) => r.file === file
5398
5529
  )) {
5399
5530
  console.log(
5400
- ` ${chalk51.red(`"${oldSpecifier}"`)} \u2192 ${chalk51.green(`"${newSpecifier}"`)}`
5531
+ ` ${chalk52.red(`"${oldSpecifier}"`)} \u2192 ${chalk52.green(`"${newSpecifier}"`)}`
5401
5532
  );
5402
5533
  }
5403
5534
  }
5404
5535
  }
5405
5536
  function displayPlan(plan) {
5406
5537
  if (plan.warnings.length > 0) {
5407
- console.log(chalk51.yellow("\nWarnings:"));
5408
- for (const w of plan.warnings) console.log(chalk51.yellow(` ${w}`));
5538
+ console.log(chalk52.yellow("\nWarnings:"));
5539
+ for (const w of plan.warnings) console.log(chalk52.yellow(` ${w}`));
5409
5540
  }
5410
5541
  if (plan.newDirectories.length > 0) {
5411
- console.log(chalk51.bold("\nNew directories:"));
5542
+ console.log(chalk52.bold("\nNew directories:"));
5412
5543
  for (const dir of plan.newDirectories)
5413
- console.log(chalk51.green(` ${dir}/`));
5544
+ console.log(chalk52.green(` ${dir}/`));
5414
5545
  }
5415
5546
  displayMoves(plan);
5416
5547
  displayRewrites(plan.rewrites);
5417
5548
  console.log(
5418
- chalk51.dim(
5549
+ chalk52.dim(
5419
5550
  `
5420
5551
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
5421
5552
  )
@@ -5425,18 +5556,18 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
5425
5556
  // src/commands/refactor/restructure/executePlan.ts
5426
5557
  import fs18 from "fs";
5427
5558
  import path27 from "path";
5428
- import chalk52 from "chalk";
5559
+ import chalk53 from "chalk";
5429
5560
  function executePlan(plan) {
5430
5561
  const updatedContents = applyRewrites(plan.rewrites);
5431
5562
  for (const [file, content] of updatedContents) {
5432
5563
  fs18.writeFileSync(file, content, "utf-8");
5433
5564
  console.log(
5434
- chalk52.cyan(` Rewrote imports in ${path27.relative(process.cwd(), file)}`)
5565
+ chalk53.cyan(` Rewrote imports in ${path27.relative(process.cwd(), file)}`)
5435
5566
  );
5436
5567
  }
5437
5568
  for (const dir of plan.newDirectories) {
5438
5569
  fs18.mkdirSync(dir, { recursive: true });
5439
- console.log(chalk52.green(` Created ${path27.relative(process.cwd(), dir)}/`));
5570
+ console.log(chalk53.green(` Created ${path27.relative(process.cwd(), dir)}/`));
5440
5571
  }
5441
5572
  for (const move of plan.moves) {
5442
5573
  const targetDir = path27.dirname(move.to);
@@ -5445,7 +5576,7 @@ function executePlan(plan) {
5445
5576
  }
5446
5577
  fs18.renameSync(move.from, move.to);
5447
5578
  console.log(
5448
- chalk52.white(
5579
+ chalk53.white(
5449
5580
  ` Moved ${path27.relative(process.cwd(), move.from)} \u2192 ${path27.relative(process.cwd(), move.to)}`
5450
5581
  )
5451
5582
  );
@@ -5460,7 +5591,7 @@ function removeEmptyDirectories(dirs) {
5460
5591
  if (entries.length === 0) {
5461
5592
  fs18.rmdirSync(dir);
5462
5593
  console.log(
5463
- chalk52.dim(
5594
+ chalk53.dim(
5464
5595
  ` Removed empty directory ${path27.relative(process.cwd(), dir)}`
5465
5596
  )
5466
5597
  );
@@ -5591,22 +5722,22 @@ async function restructure(pattern2, options2 = {}) {
5591
5722
  const targetPattern = pattern2 ?? "src";
5592
5723
  const files = findSourceFiles2(targetPattern);
5593
5724
  if (files.length === 0) {
5594
- console.log(chalk53.yellow("No files found matching pattern"));
5725
+ console.log(chalk54.yellow("No files found matching pattern"));
5595
5726
  return;
5596
5727
  }
5597
5728
  const tsConfigPath = path30.resolve("tsconfig.json");
5598
5729
  const plan = buildPlan(files, tsConfigPath);
5599
5730
  if (plan.moves.length === 0) {
5600
- console.log(chalk53.green("No restructuring needed"));
5731
+ console.log(chalk54.green("No restructuring needed"));
5601
5732
  return;
5602
5733
  }
5603
5734
  displayPlan(plan);
5604
5735
  if (options2.apply) {
5605
- console.log(chalk53.bold("\nApplying changes..."));
5736
+ console.log(chalk54.bold("\nApplying changes..."));
5606
5737
  executePlan(plan);
5607
- console.log(chalk53.green("\nRestructuring complete"));
5738
+ console.log(chalk54.green("\nRestructuring complete"));
5608
5739
  } else {
5609
- console.log(chalk53.dim("\nDry run. Use --apply to execute."));
5740
+ console.log(chalk54.dim("\nDry run. Use --apply to execute."));
5610
5741
  }
5611
5742
  }
5612
5743
 
@@ -5630,7 +5761,7 @@ function registerRefactor(program2) {
5630
5761
 
5631
5762
  // src/commands/transcript/shared.ts
5632
5763
  import { existsSync as existsSync24, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
5633
- import { basename as basename4, join as join19, relative } from "path";
5764
+ import { basename as basename4, join as join21, relative } from "path";
5634
5765
  import * as readline2 from "readline";
5635
5766
  var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
5636
5767
  function getDatePrefix(daysOffset = 0) {
@@ -5648,7 +5779,7 @@ function collectFiles(dir, extension) {
5648
5779
  if (!existsSync24(dir)) return [];
5649
5780
  const results = [];
5650
5781
  for (const entry of readdirSync3(dir)) {
5651
- const fullPath = join19(dir, entry);
5782
+ const fullPath = join21(dir, entry);
5652
5783
  if (statSync2(fullPath).isDirectory()) {
5653
5784
  results.push(...collectFiles(fullPath, extension));
5654
5785
  } else if (entry.endsWith(extension)) {
@@ -5745,11 +5876,11 @@ async function configure() {
5745
5876
  import { existsSync as existsSync26 } from "fs";
5746
5877
 
5747
5878
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
5748
- import { dirname as dirname15, join as join21 } from "path";
5879
+ import { dirname as dirname15, join as join23 } from "path";
5749
5880
 
5750
5881
  // src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
5751
5882
  import { renameSync } from "fs";
5752
- import { join as join20 } from "path";
5883
+ import { join as join22 } from "path";
5753
5884
  async function resolveDate(rl, choice) {
5754
5885
  if (choice === "1") return getDatePrefix(0);
5755
5886
  if (choice === "2") return getDatePrefix(-1);
@@ -5764,7 +5895,7 @@ async function resolveDate(rl, choice) {
5764
5895
  }
5765
5896
  function renameWithPrefix(vttDir, vttFile, prefix2) {
5766
5897
  const newFilename = `${prefix2}.${vttFile}`;
5767
- renameSync(join20(vttDir, vttFile), join20(vttDir, newFilename));
5898
+ renameSync(join22(vttDir, vttFile), join22(vttDir, newFilename));
5768
5899
  console.log(`Renamed to: ${newFilename}`);
5769
5900
  return newFilename;
5770
5901
  }
@@ -5798,12 +5929,12 @@ async function fixInvalidDatePrefixes(vttFiles) {
5798
5929
  const vttFileDir = dirname15(vttFile.absolutePath);
5799
5930
  const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
5800
5931
  if (newFilename) {
5801
- const newRelativePath = join21(
5932
+ const newRelativePath = join23(
5802
5933
  dirname15(vttFile.relativePath),
5803
5934
  newFilename
5804
5935
  );
5805
5936
  vttFiles[i] = {
5806
- absolutePath: join21(vttFileDir, newFilename),
5937
+ absolutePath: join23(vttFileDir, newFilename),
5807
5938
  relativePath: newRelativePath,
5808
5939
  filename: newFilename
5809
5940
  };
@@ -5816,8 +5947,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
5816
5947
  }
5817
5948
 
5818
5949
  // src/commands/transcript/format/processVttFile/index.ts
5819
- import { existsSync as existsSync25, mkdirSync as mkdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync19 } from "fs";
5820
- import { basename as basename5, dirname as dirname16, join as join22 } from "path";
5950
+ import { existsSync as existsSync25, mkdirSync as mkdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync20 } from "fs";
5951
+ import { basename as basename5, dirname as dirname16, join as join24 } from "path";
5821
5952
 
5822
5953
  // src/commands/transcript/cleanText.ts
5823
5954
  function cleanText(text) {
@@ -6027,17 +6158,17 @@ function toMdFilename(vttFilename) {
6027
6158
  return `${basename5(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
6028
6159
  }
6029
6160
  function resolveOutputDir(relativeDir, transcriptsDir) {
6030
- return relativeDir === "." ? transcriptsDir : join22(transcriptsDir, relativeDir);
6161
+ return relativeDir === "." ? transcriptsDir : join24(transcriptsDir, relativeDir);
6031
6162
  }
6032
6163
  function buildOutputPaths(vttFile, transcriptsDir) {
6033
6164
  const mdFile = toMdFilename(vttFile.filename);
6034
6165
  const relativeDir = dirname16(vttFile.relativePath);
6035
6166
  const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
6036
- const outputPath = join22(outputDir, mdFile);
6167
+ const outputPath = join24(outputDir, mdFile);
6037
6168
  return { outputDir, outputPath, mdFile, relativeDir };
6038
6169
  }
6039
6170
  function logSkipped(relativeDir, mdFile) {
6040
- console.log(`Skipping (already exists): ${join22(relativeDir, mdFile)}`);
6171
+ console.log(`Skipping (already exists): ${join24(relativeDir, mdFile)}`);
6041
6172
  return "skipped";
6042
6173
  }
6043
6174
  function ensureDirectory(dir, label2) {
@@ -6067,7 +6198,7 @@ function readAndParseCues(inputPath) {
6067
6198
  return processCues(readFileSync21(inputPath, "utf-8"));
6068
6199
  }
6069
6200
  function writeFormatted(outputPath, content) {
6070
- writeFileSync19(outputPath, content, "utf-8");
6201
+ writeFileSync20(outputPath, content, "utf-8");
6071
6202
  console.log(`Written: ${outputPath}`);
6072
6203
  }
6073
6204
  function convertVttToMarkdown(inputPath, outputPath) {
@@ -6136,7 +6267,7 @@ async function format() {
6136
6267
 
6137
6268
  // src/commands/transcript/summarise/index.ts
6138
6269
  import { existsSync as existsSync28 } from "fs";
6139
- import { basename as basename6, dirname as dirname18, join as join24, relative as relative2 } from "path";
6270
+ import { basename as basename6, dirname as dirname18, join as join26, relative as relative2 } from "path";
6140
6271
 
6141
6272
  // src/commands/transcript/summarise/processStagedFile/index.ts
6142
6273
  import {
@@ -6146,17 +6277,17 @@ import {
6146
6277
  renameSync as renameSync2,
6147
6278
  rmSync
6148
6279
  } from "fs";
6149
- import { dirname as dirname17, join as join23 } from "path";
6280
+ import { dirname as dirname17, join as join25 } from "path";
6150
6281
 
6151
6282
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
6152
- import chalk54 from "chalk";
6283
+ import chalk55 from "chalk";
6153
6284
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
6154
6285
  function validateStagedContent(filename, content) {
6155
6286
  const firstLine = content.split("\n")[0];
6156
6287
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
6157
6288
  if (!match) {
6158
6289
  console.error(
6159
- chalk54.red(
6290
+ chalk55.red(
6160
6291
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
6161
6292
  )
6162
6293
  );
@@ -6165,7 +6296,7 @@ function validateStagedContent(filename, content) {
6165
6296
  const contentAfterLink = content.slice(firstLine.length).trim();
6166
6297
  if (!contentAfterLink) {
6167
6298
  console.error(
6168
- chalk54.red(
6299
+ chalk55.red(
6169
6300
  `Staged file ${filename} has no summary content after the transcript link.`
6170
6301
  )
6171
6302
  );
@@ -6175,7 +6306,7 @@ function validateStagedContent(filename, content) {
6175
6306
  }
6176
6307
 
6177
6308
  // src/commands/transcript/summarise/processStagedFile/index.ts
6178
- var STAGING_DIR = join23(process.cwd(), ".assist", "transcript");
6309
+ var STAGING_DIR = join25(process.cwd(), ".assist", "transcript");
6179
6310
  function processStagedFile() {
6180
6311
  if (!existsSync27(STAGING_DIR)) {
6181
6312
  return false;
@@ -6199,7 +6330,7 @@ function processStagedFile() {
6199
6330
  );
6200
6331
  process.exit(1);
6201
6332
  }
6202
- const destPath = join23(summaryDir, matchingTranscript.relativePath);
6333
+ const destPath = join25(summaryDir, matchingTranscript.relativePath);
6203
6334
  const destDir = dirname17(destPath);
6204
6335
  if (!existsSync27(destDir)) {
6205
6336
  mkdirSync7(destDir, { recursive: true });
@@ -6215,7 +6346,7 @@ function processStagedFile() {
6215
6346
  // src/commands/transcript/summarise/index.ts
6216
6347
  function buildRelativeKey(relativePath, baseName) {
6217
6348
  const relDir = dirname18(relativePath);
6218
- return relDir === "." ? baseName : join24(relDir, baseName);
6349
+ return relDir === "." ? baseName : join26(relDir, baseName);
6219
6350
  }
6220
6351
  function buildSummaryIndex(summaryDir) {
6221
6352
  const summaryFiles = findMdFilesRecursive(summaryDir);
@@ -6249,8 +6380,8 @@ function summarise2() {
6249
6380
  }
6250
6381
  const next2 = missing[0];
6251
6382
  const outputFilename = `${getTranscriptBaseName(next2.filename)}.md`;
6252
- const outputPath = join24(STAGING_DIR, outputFilename);
6253
- const summaryFileDir = join24(summaryDir, dirname18(next2.relativePath));
6383
+ const outputPath = join26(STAGING_DIR, outputFilename);
6384
+ const summaryFileDir = join26(summaryDir, dirname18(next2.relativePath));
6254
6385
  const relativeTranscriptPath = encodeURI(
6255
6386
  relative2(summaryFileDir, next2.absolutePath).replace(/\\/g, "/")
6256
6387
  );
@@ -6296,38 +6427,38 @@ function registerVerify(program2) {
6296
6427
 
6297
6428
  // src/commands/voice/devices.ts
6298
6429
  import { spawnSync as spawnSync3 } from "child_process";
6299
- import { join as join26 } from "path";
6430
+ import { join as join28 } from "path";
6300
6431
 
6301
6432
  // src/commands/voice/shared.ts
6302
6433
  import { homedir as homedir6 } from "os";
6303
- import { dirname as dirname19, join as join25 } from "path";
6434
+ import { dirname as dirname19, join as join27 } from "path";
6304
6435
  import { fileURLToPath as fileURLToPath6 } from "url";
6305
6436
  var __dirname7 = dirname19(fileURLToPath6(import.meta.url));
6306
- var VOICE_DIR = join25(homedir6(), ".assist", "voice");
6437
+ var VOICE_DIR = join27(homedir6(), ".assist", "voice");
6307
6438
  var voicePaths = {
6308
6439
  dir: VOICE_DIR,
6309
- pid: join25(VOICE_DIR, "voice.pid"),
6310
- log: join25(VOICE_DIR, "voice.log"),
6311
- venv: join25(VOICE_DIR, ".venv"),
6312
- lock: join25(VOICE_DIR, "voice.lock")
6440
+ pid: join27(VOICE_DIR, "voice.pid"),
6441
+ log: join27(VOICE_DIR, "voice.log"),
6442
+ venv: join27(VOICE_DIR, ".venv"),
6443
+ lock: join27(VOICE_DIR, "voice.lock")
6313
6444
  };
6314
6445
  function getPythonDir() {
6315
- return join25(__dirname7, "commands", "voice", "python");
6446
+ return join27(__dirname7, "commands", "voice", "python");
6316
6447
  }
6317
6448
  function getVenvPython() {
6318
- return process.platform === "win32" ? join25(voicePaths.venv, "Scripts", "python.exe") : join25(voicePaths.venv, "bin", "python");
6449
+ return process.platform === "win32" ? join27(voicePaths.venv, "Scripts", "python.exe") : join27(voicePaths.venv, "bin", "python");
6319
6450
  }
6320
6451
  function getLockDir() {
6321
6452
  const config = loadConfig();
6322
6453
  return config.voice?.lockDir ?? VOICE_DIR;
6323
6454
  }
6324
6455
  function getLockFile() {
6325
- return join25(getLockDir(), "voice.lock");
6456
+ return join27(getLockDir(), "voice.lock");
6326
6457
  }
6327
6458
 
6328
6459
  // src/commands/voice/devices.ts
6329
6460
  function devices() {
6330
- const script = join26(getPythonDir(), "list_devices.py");
6461
+ const script = join28(getPythonDir(), "list_devices.py");
6331
6462
  spawnSync3(getVenvPython(), [script], { stdio: "inherit" });
6332
6463
  }
6333
6464
 
@@ -6362,12 +6493,12 @@ function logs(options2) {
6362
6493
  // src/commands/voice/setup.ts
6363
6494
  import { spawnSync as spawnSync4 } from "child_process";
6364
6495
  import { mkdirSync as mkdirSync9 } from "fs";
6365
- import { join as join28 } from "path";
6496
+ import { join as join30 } from "path";
6366
6497
 
6367
6498
  // src/commands/voice/checkLockFile.ts
6368
- import { execSync as execSync27 } from "child_process";
6369
- import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
6370
- import { join as join27 } from "path";
6499
+ import { execSync as execSync28 } from "child_process";
6500
+ import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync24, writeFileSync as writeFileSync21 } from "fs";
6501
+ import { join as join29 } from "path";
6371
6502
  function isProcessAlive(pid) {
6372
6503
  try {
6373
6504
  process.kill(pid, 0);
@@ -6394,7 +6525,7 @@ function bootstrapVenv() {
6394
6525
  if (existsSync30(getVenvPython())) return;
6395
6526
  console.log("Setting up Python environment...");
6396
6527
  const pythonDir = getPythonDir();
6397
- execSync27(
6528
+ execSync28(
6398
6529
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
6399
6530
  {
6400
6531
  stdio: "inherit",
@@ -6404,8 +6535,8 @@ function bootstrapVenv() {
6404
6535
  }
6405
6536
  function writeLockFile(pid) {
6406
6537
  const lockFile = getLockFile();
6407
- mkdirSync8(join27(lockFile, ".."), { recursive: true });
6408
- writeFileSync20(
6538
+ mkdirSync8(join29(lockFile, ".."), { recursive: true });
6539
+ writeFileSync21(
6409
6540
  lockFile,
6410
6541
  JSON.stringify({
6411
6542
  pid,
@@ -6420,7 +6551,7 @@ function setup() {
6420
6551
  mkdirSync9(voicePaths.dir, { recursive: true });
6421
6552
  bootstrapVenv();
6422
6553
  console.log("\nDownloading models...\n");
6423
- const script = join28(getPythonDir(), "setup_models.py");
6554
+ const script = join30(getPythonDir(), "setup_models.py");
6424
6555
  const result = spawnSync4(getVenvPython(), [script], {
6425
6556
  stdio: "inherit",
6426
6557
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
@@ -6433,8 +6564,8 @@ function setup() {
6433
6564
 
6434
6565
  // src/commands/voice/start.ts
6435
6566
  import { spawn as spawn4 } from "child_process";
6436
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync21 } from "fs";
6437
- import { join as join29 } from "path";
6567
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync22 } from "fs";
6568
+ import { join as join31 } from "path";
6438
6569
 
6439
6570
  // src/commands/voice/buildDaemonEnv.ts
6440
6571
  function buildDaemonEnv(options2) {
@@ -6462,7 +6593,7 @@ function spawnBackground(python, script, env) {
6462
6593
  console.error("Failed to start voice daemon");
6463
6594
  process.exit(1);
6464
6595
  }
6465
- writeFileSync21(voicePaths.pid, String(pid));
6596
+ writeFileSync22(voicePaths.pid, String(pid));
6466
6597
  writeLockFile(pid);
6467
6598
  console.log(`Voice daemon started (PID ${pid})`);
6468
6599
  }
@@ -6472,7 +6603,7 @@ function start2(options2) {
6472
6603
  bootstrapVenv();
6473
6604
  const debug = options2.debug || options2.foreground || process.platform === "win32";
6474
6605
  const env = buildDaemonEnv({ debug });
6475
- const script = join29(getPythonDir(), "voice_daemon.py");
6606
+ const script = join31(getPythonDir(), "voice_daemon.py");
6476
6607
  const python = getVenvPython();
6477
6608
  if (options2.foreground) {
6478
6609
  spawnForeground(python, script, env);
@@ -6558,14 +6689,14 @@ function registerVoice(program2) {
6558
6689
 
6559
6690
  // src/commands/roam/auth.ts
6560
6691
  import { randomBytes } from "crypto";
6561
- import chalk55 from "chalk";
6692
+ import chalk56 from "chalk";
6562
6693
 
6563
6694
  // src/lib/openBrowser.ts
6564
- import { execSync as execSync28 } from "child_process";
6695
+ import { execSync as execSync29 } from "child_process";
6565
6696
  function tryExec(commands) {
6566
6697
  for (const cmd of commands) {
6567
6698
  try {
6568
- execSync28(cmd);
6699
+ execSync29(cmd);
6569
6700
  return true;
6570
6701
  } catch {
6571
6702
  }
@@ -6733,13 +6864,13 @@ async function auth() {
6733
6864
  saveGlobalConfig(config);
6734
6865
  const state = randomBytes(16).toString("hex");
6735
6866
  console.log(
6736
- chalk55.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
6867
+ chalk56.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
6737
6868
  );
6738
- console.log(chalk55.white("http://localhost:14523/callback\n"));
6739
- console.log(chalk55.blue("Opening browser for authorization..."));
6740
- console.log(chalk55.dim("Waiting for authorization callback..."));
6869
+ console.log(chalk56.white("http://localhost:14523/callback\n"));
6870
+ console.log(chalk56.blue("Opening browser for authorization..."));
6871
+ console.log(chalk56.dim("Waiting for authorization callback..."));
6741
6872
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
6742
- console.log(chalk55.dim("Exchanging code for tokens..."));
6873
+ console.log(chalk56.dim("Exchanging code for tokens..."));
6743
6874
  const tokens = await exchangeToken({
6744
6875
  code,
6745
6876
  clientId,
@@ -6755,7 +6886,7 @@ async function auth() {
6755
6886
  };
6756
6887
  saveGlobalConfig(config);
6757
6888
  console.log(
6758
- chalk55.green("Roam credentials and tokens saved to ~/.assist.yml")
6889
+ chalk56.green("Roam credentials and tokens saved to ~/.assist.yml")
6759
6890
  );
6760
6891
  }
6761
6892
 
@@ -6802,8 +6933,8 @@ function resolveParams(params, cliArgs) {
6802
6933
  }
6803
6934
 
6804
6935
  // src/commands/run/add.ts
6805
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync22 } from "fs";
6806
- import { join as join30 } from "path";
6936
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync23 } from "fs";
6937
+ import { join as join32 } from "path";
6807
6938
  function findAddIndex() {
6808
6939
  const addIndex = process.argv.indexOf("add");
6809
6940
  if (addIndex === -1 || addIndex + 2 >= process.argv.length) return -1;
@@ -6857,7 +6988,7 @@ function saveNewRunConfig(name, command, args) {
6857
6988
  saveConfig(config);
6858
6989
  }
6859
6990
  function createCommandFile(name) {
6860
- const dir = join30(".claude", "commands");
6991
+ const dir = join32(".claude", "commands");
6861
6992
  mkdirSync11(dir, { recursive: true });
6862
6993
  const content = `---
6863
6994
  description: Run ${name}
@@ -6865,8 +6996,8 @@ description: Run ${name}
6865
6996
 
6866
6997
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
6867
6998
  `;
6868
- const filePath = join30(dir, `${name}.md`);
6869
- writeFileSync22(filePath, content);
6999
+ const filePath = join32(dir, `${name}.md`);
7000
+ writeFileSync23(filePath, content);
6870
7001
  console.log(`Created command file: ${filePath}`);
6871
7002
  }
6872
7003
  function add2() {
@@ -6943,14 +7074,14 @@ function run2(name, args) {
6943
7074
  }
6944
7075
 
6945
7076
  // src/commands/statusLine.ts
6946
- import chalk56 from "chalk";
7077
+ import chalk57 from "chalk";
6947
7078
  function formatNumber(num) {
6948
7079
  return num.toLocaleString("en-US");
6949
7080
  }
6950
7081
  function colorizePercent(pct) {
6951
7082
  const label2 = `${pct}%`;
6952
- if (pct > 80) return chalk56.red(label2);
6953
- if (pct > 40) return chalk56.yellow(label2);
7083
+ if (pct > 80) return chalk57.red(label2);
7084
+ if (pct > 40) return chalk57.yellow(label2);
6954
7085
  return label2;
6955
7086
  }
6956
7087
  async function statusLine() {
@@ -6976,7 +7107,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
6976
7107
  // src/commands/sync/syncClaudeMd.ts
6977
7108
  import * as fs21 from "fs";
6978
7109
  import * as path31 from "path";
6979
- import chalk57 from "chalk";
7110
+ import chalk58 from "chalk";
6980
7111
  async function syncClaudeMd(claudeDir, targetBase) {
6981
7112
  const source = path31.join(claudeDir, "CLAUDE.md");
6982
7113
  const target = path31.join(targetBase, "CLAUDE.md");
@@ -6985,12 +7116,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
6985
7116
  const targetContent = fs21.readFileSync(target, "utf-8");
6986
7117
  if (sourceContent !== targetContent) {
6987
7118
  console.log(
6988
- chalk57.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
7119
+ chalk58.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
6989
7120
  );
6990
7121
  console.log();
6991
7122
  printDiff(targetContent, sourceContent);
6992
7123
  const confirm = await promptConfirm(
6993
- chalk57.red("Overwrite existing CLAUDE.md?"),
7124
+ chalk58.red("Overwrite existing CLAUDE.md?"),
6994
7125
  false
6995
7126
  );
6996
7127
  if (!confirm) {
@@ -7006,7 +7137,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
7006
7137
  // src/commands/sync/syncSettings.ts
7007
7138
  import * as fs22 from "fs";
7008
7139
  import * as path32 from "path";
7009
- import chalk58 from "chalk";
7140
+ import chalk59 from "chalk";
7010
7141
  async function syncSettings(claudeDir, targetBase, options2) {
7011
7142
  const source = path32.join(claudeDir, "settings.json");
7012
7143
  const target = path32.join(targetBase, "settings.json");
@@ -7022,14 +7153,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
7022
7153
  if (mergedContent !== normalizedTarget) {
7023
7154
  if (!options2?.yes) {
7024
7155
  console.log(
7025
- chalk58.yellow(
7156
+ chalk59.yellow(
7026
7157
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
7027
7158
  )
7028
7159
  );
7029
7160
  console.log();
7030
7161
  printDiff(targetContent, mergedContent);
7031
7162
  const confirm = await promptConfirm(
7032
- chalk58.red("Overwrite existing settings.json?"),
7163
+ chalk59.red("Overwrite existing settings.json?"),
7033
7164
  false
7034
7165
  );
7035
7166
  if (!confirm) {
@@ -7066,7 +7197,7 @@ function syncCommands(claudeDir, targetBase) {
7066
7197
  }
7067
7198
 
7068
7199
  // src/commands/update.ts
7069
- import { execSync as execSync29 } from "child_process";
7200
+ import { execSync as execSync30 } from "child_process";
7070
7201
  import * as path34 from "path";
7071
7202
  function isGlobalNpmInstall(dir) {
7072
7203
  try {
@@ -7074,7 +7205,7 @@ function isGlobalNpmInstall(dir) {
7074
7205
  if (resolved.split(path34.sep).includes("node_modules")) {
7075
7206
  return true;
7076
7207
  }
7077
- const globalPrefix = execSync29("npm prefix -g", { stdio: "pipe" }).toString().trim();
7208
+ const globalPrefix = execSync30("npm prefix -g", { stdio: "pipe" }).toString().trim();
7078
7209
  return resolved.toLowerCase().startsWith(path34.resolve(globalPrefix).toLowerCase());
7079
7210
  } catch {
7080
7211
  return false;
@@ -7085,18 +7216,18 @@ async function update() {
7085
7216
  console.log(`Assist is installed at: ${installDir}`);
7086
7217
  if (isGitRepo(installDir)) {
7087
7218
  console.log("Detected git repo installation, pulling latest...");
7088
- execSync29("git pull", { cwd: installDir, stdio: "inherit" });
7219
+ execSync30("git pull", { cwd: installDir, stdio: "inherit" });
7089
7220
  console.log("Installing dependencies...");
7090
- execSync29("npm i", { cwd: installDir, stdio: "inherit" });
7221
+ execSync30("npm i", { cwd: installDir, stdio: "inherit" });
7091
7222
  console.log("Building...");
7092
- execSync29("npm run build", { cwd: installDir, stdio: "inherit" });
7223
+ execSync30("npm run build", { cwd: installDir, stdio: "inherit" });
7093
7224
  console.log("Syncing commands...");
7094
- execSync29("assist sync", { stdio: "inherit" });
7225
+ execSync30("assist sync", { stdio: "inherit" });
7095
7226
  } else if (isGlobalNpmInstall(installDir)) {
7096
7227
  console.log("Detected global npm installation, updating...");
7097
- execSync29("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
7228
+ execSync30("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
7098
7229
  console.log("Syncing commands...");
7099
- execSync29("assist sync", { stdio: "inherit" });
7230
+ execSync30("assist sync", { stdio: "inherit" });
7100
7231
  } else {
7101
7232
  console.error(
7102
7233
  "Could not determine installation method. Expected a git repo or global npm install."