@staff0rd/assist 0.103.0 → 0.105.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 +257 -146
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -90,6 +90,7 @@ After installation, the `assist` command will be available globally. You can als
90
90
  - `assist refactor restructure [pattern]` - Analyze import graph and restructure tightly-coupled files into nested directories
91
91
  - `assist devlog list` - Group git commits by date
92
92
  - `assist devlog next` - Show commits for the day after the last versioned entry
93
+ - `assist devlog repos` - Show which github.com/staff0rd repos are missing devlog entries
93
94
  - `assist devlog skip <date>` - Add a date to the skip list
94
95
  - `assist devlog version` - Show current repo name and version info
95
96
  - `assist cli-hook` - PreToolUse hook for auto-approving read-only CLI commands (reads from `assist.cli-reads`, also auto-approves read-only `gh api` calls). Supports compound commands (`|`, `&&`, `||`, `;`) by checking each sub-command independently
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.103.0",
9
+ version: "0.105.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -2720,6 +2720,7 @@ import { parse } from "shell-quote";
2720
2720
  var SEPARATOR_OPS = /* @__PURE__ */ new Set(["|", "&&", "||", ";"]);
2721
2721
  var UNSAFE_OPS = /* @__PURE__ */ new Set(["(", ")", ">", ">>", "<", "<&", "|&", ">&"]);
2722
2722
  var FD_REDIRECT_RE = /\d+>&\d+/g;
2723
+ var FD_DEVNULL_RE = /\d*>\/dev\/null/g;
2723
2724
  function splitCompound(command) {
2724
2725
  const tokens = tokenizeCommand(command);
2725
2726
  if (!tokens) return void 0;
@@ -2729,7 +2730,7 @@ function splitCompound(command) {
2729
2730
  return result.length > 0 ? result : void 0;
2730
2731
  }
2731
2732
  function tokenizeCommand(command) {
2732
- const trimmed = command.trim().replace(FD_REDIRECT_RE, "");
2733
+ const trimmed = command.trim().replace(FD_DEVNULL_RE, "").replace(FD_REDIRECT_RE, "");
2733
2734
  if (!trimmed) return void 0;
2734
2735
  try {
2735
2736
  const tokens = parse(trimmed);
@@ -3725,38 +3726,65 @@ import { readdirSync, readFileSync as readFileSync17 } from "fs";
3725
3726
  import { homedir as homedir5 } from "os";
3726
3727
  import { join as join13 } from "path";
3727
3728
  var DEVLOG_DIR = join13(homedir5(), "git/blog/src/content/devlog");
3728
- function loadDevlogEntries(repoName) {
3729
- const entries = /* @__PURE__ */ new Map();
3729
+ function extractFrontmatter(content) {
3730
+ const fm = content.match(/^---\n([\s\S]*?)\n---/);
3731
+ return fm?.[1] ?? null;
3732
+ }
3733
+ function matchField(frontmatter, pattern2) {
3734
+ return frontmatter.match(pattern2)?.[1]?.trim() ?? null;
3735
+ }
3736
+ function parseFrontmatter(content, filename) {
3737
+ const frontmatter = extractFrontmatter(content);
3738
+ if (!frontmatter) return null;
3739
+ const date = matchField(frontmatter, /date:\s*"?(\d{4}-\d{2}-\d{2})"?/);
3740
+ const tagsRaw = matchField(frontmatter, /tags:\s*\[([^\]]*)\]/);
3741
+ if (!date || !tagsRaw) return null;
3742
+ const repoTag = tagsRaw.split(",")[0]?.trim();
3743
+ if (!repoTag) return null;
3744
+ return {
3745
+ date,
3746
+ repoTag,
3747
+ version: matchField(frontmatter, /version:\s*(.+)/),
3748
+ title: matchField(frontmatter, /title:\s*(.+)/),
3749
+ filename
3750
+ };
3751
+ }
3752
+ function readDevlogFiles(callback) {
3730
3753
  try {
3731
3754
  const files = readdirSync(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
3732
3755
  for (const file of files) {
3733
3756
  const content = readFileSync17(join13(DEVLOG_DIR, file), "utf-8");
3734
- const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
3735
- if (frontmatterMatch) {
3736
- const frontmatter = frontmatterMatch[1];
3737
- const dateMatch = frontmatter.match(/date:\s*"?(\d{4}-\d{2}-\d{2})"?/);
3738
- const versionMatch = frontmatter.match(/version:\s*(.+)/);
3739
- const titleMatch = frontmatter.match(/title:\s*(.+)/);
3740
- const tagsMatch = frontmatter.match(/tags:\s*\[([^\]]*)\]/);
3741
- if (dateMatch && versionMatch && titleMatch && tagsMatch) {
3742
- const tags = tagsMatch[1].split(",").map((t) => t.trim());
3743
- const firstTag = tags[0];
3744
- if (firstTag !== repoName) {
3745
- continue;
3746
- }
3747
- const date = dateMatch[1];
3748
- const version2 = versionMatch[1].trim();
3749
- const title = titleMatch[1].trim();
3750
- const existing = entries.get(date) || [];
3751
- existing.push({ version: version2, title, filename: file });
3752
- entries.set(date, existing);
3753
- }
3754
- }
3757
+ const parsed = parseFrontmatter(content, file);
3758
+ if (parsed) callback(parsed);
3755
3759
  }
3756
3760
  } catch {
3757
3761
  }
3762
+ }
3763
+ function loadDevlogEntries(repoName) {
3764
+ const entries = /* @__PURE__ */ new Map();
3765
+ readDevlogFiles((parsed) => {
3766
+ if (parsed.repoTag !== repoName) return;
3767
+ if (!parsed.version || !parsed.title) return;
3768
+ const existing = entries.get(parsed.date) || [];
3769
+ existing.push({
3770
+ version: parsed.version,
3771
+ title: parsed.title,
3772
+ filename: parsed.filename
3773
+ });
3774
+ entries.set(parsed.date, existing);
3775
+ });
3758
3776
  return entries;
3759
3777
  }
3778
+ function loadAllDevlogLatestDates() {
3779
+ const latest = /* @__PURE__ */ new Map();
3780
+ readDevlogFiles((parsed) => {
3781
+ const existing = latest.get(parsed.repoTag);
3782
+ if (!existing || parsed.date > existing) {
3783
+ latest.set(parsed.repoTag, parsed.date);
3784
+ }
3785
+ });
3786
+ return latest;
3787
+ }
3760
3788
 
3761
3789
  // src/commands/devlog/shared.ts
3762
3790
  function getCommitFiles(hash) {
@@ -4028,11 +4056,89 @@ function next(options2) {
4028
4056
  showResult(ctx, fetchNextCommits(ctx));
4029
4057
  }
4030
4058
 
4031
- // src/commands/devlog/skip.ts
4059
+ // src/commands/devlog/repos/index.ts
4060
+ import { execSync as execSync19 } from "child_process";
4061
+
4062
+ // src/commands/devlog/repos/printReposTable.ts
4032
4063
  import chalk42 from "chalk";
4064
+ function colorStatus(status2) {
4065
+ if (status2 === "missing") return chalk42.red(status2);
4066
+ if (status2 === "outdated") return chalk42.yellow(status2);
4067
+ return chalk42.green(status2);
4068
+ }
4069
+ function formatRow(row, nameWidth) {
4070
+ const devlog = (row.lastDevlog ?? "-").padEnd(11);
4071
+ return `${row.name.padEnd(nameWidth)} ${row.lastPush} ${devlog} ${colorStatus(row.status)}`;
4072
+ }
4073
+ function printReposTable(rows) {
4074
+ const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));
4075
+ const header = [
4076
+ "Repo".padEnd(nameWidth),
4077
+ "Last Push".padEnd(10),
4078
+ "Last Devlog".padEnd(11),
4079
+ "Status"
4080
+ ].join(" ");
4081
+ console.log(chalk42.dim(header));
4082
+ console.log(chalk42.dim("-".repeat(header.length)));
4083
+ for (const row of rows) {
4084
+ console.log(formatRow(row, nameWidth));
4085
+ }
4086
+ }
4087
+
4088
+ // src/commands/devlog/repos/index.ts
4089
+ var statusOrder = { missing: 0, outdated: 1, ok: 2 };
4090
+ function getStatus(lastPush, lastDevlog) {
4091
+ if (!lastDevlog) return "missing";
4092
+ return lastDevlog < lastPush ? "outdated" : "ok";
4093
+ }
4094
+ function fetchRepos(days, all) {
4095
+ const json = execSync19(
4096
+ "gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
4097
+ { encoding: "utf-8" }
4098
+ );
4099
+ const allRepos = JSON.parse(json);
4100
+ const cutoff = /* @__PURE__ */ new Date();
4101
+ cutoff.setDate(cutoff.getDate() - days);
4102
+ const cutoffStr = cutoff.toISOString().slice(0, 10);
4103
+ return allRepos.filter((r) => {
4104
+ if (r.isArchived) return false;
4105
+ if (all) return true;
4106
+ return r.pushedAt.slice(0, 10) >= cutoffStr;
4107
+ });
4108
+ }
4109
+ function toRow(repo, devlogDates) {
4110
+ const lastPush = repo.pushedAt.slice(0, 10);
4111
+ const lastDevlog = devlogDates.get(repo.name) ?? null;
4112
+ return {
4113
+ name: repo.name,
4114
+ lastPush,
4115
+ lastDevlog,
4116
+ status: getStatus(lastPush, lastDevlog)
4117
+ };
4118
+ }
4119
+ function sortRows(rows) {
4120
+ return rows.sort((a, b) => {
4121
+ const s = statusOrder[a.status] - statusOrder[b.status];
4122
+ if (s !== 0) return s;
4123
+ return b.lastPush.localeCompare(a.lastPush);
4124
+ });
4125
+ }
4126
+ function repos(options2) {
4127
+ const ghRepos = fetchRepos(options2.days ?? 30, options2.all ?? false);
4128
+ if (ghRepos.length === 0) {
4129
+ console.log("No repos with recent activity found.");
4130
+ return;
4131
+ }
4132
+ const devlogDates = loadAllDevlogLatestDates();
4133
+ const rows = ghRepos.map((repo) => toRow(repo, devlogDates));
4134
+ printReposTable(sortRows(rows));
4135
+ }
4136
+
4137
+ // src/commands/devlog/skip.ts
4138
+ import chalk43 from "chalk";
4033
4139
  function skip(date) {
4034
4140
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
4035
- console.log(chalk42.red("Invalid date format. Use YYYY-MM-DD"));
4141
+ console.log(chalk43.red("Invalid date format. Use YYYY-MM-DD"));
4036
4142
  process.exit(1);
4037
4143
  }
4038
4144
  const config = loadProjectConfig();
@@ -4040,7 +4146,7 @@ function skip(date) {
4040
4146
  const skip2 = devlog.skip ?? {};
4041
4147
  const skipDays = skip2.days ?? [];
4042
4148
  if (skipDays.includes(date)) {
4043
- console.log(chalk42.yellow(`${date} is already in skip list`));
4149
+ console.log(chalk43.yellow(`${date} is already in skip list`));
4044
4150
  return;
4045
4151
  }
4046
4152
  skipDays.push(date);
@@ -4049,20 +4155,20 @@ function skip(date) {
4049
4155
  devlog.skip = skip2;
4050
4156
  config.devlog = devlog;
4051
4157
  saveConfig(config);
4052
- console.log(chalk42.green(`Added ${date} to skip list`));
4158
+ console.log(chalk43.green(`Added ${date} to skip list`));
4053
4159
  }
4054
4160
 
4055
4161
  // src/commands/devlog/version.ts
4056
- import chalk43 from "chalk";
4162
+ import chalk44 from "chalk";
4057
4163
  function version() {
4058
4164
  const config = loadConfig();
4059
4165
  const name = getRepoName();
4060
4166
  const lastInfo = getLastVersionInfo(name, config);
4061
4167
  const lastVersion = lastInfo?.version ?? null;
4062
4168
  const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
4063
- console.log(`${chalk43.bold("name:")} ${name}`);
4064
- console.log(`${chalk43.bold("last:")} ${lastVersion ?? chalk43.dim("none")}`);
4065
- console.log(`${chalk43.bold("next:")} ${nextVersion ?? chalk43.dim("none")}`);
4169
+ console.log(`${chalk44.bold("name:")} ${name}`);
4170
+ console.log(`${chalk44.bold("last:")} ${lastVersion ?? chalk44.dim("none")}`);
4171
+ console.log(`${chalk44.bold("next:")} ${nextVersion ?? chalk44.dim("none")}`);
4066
4172
  }
4067
4173
 
4068
4174
  // src/commands/registerDevlog.ts
@@ -4076,6 +4182,11 @@ function registerDevlog(program2) {
4076
4182
  devlogCommand.command("version").description("Show current repo name and version info").action(version);
4077
4183
  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);
4078
4184
  devlogCommand.command("skip <date>").description("Add a date (YYYY-MM-DD) to the skip list").action(skip);
4185
+ devlogCommand.command("repos").description("Show repos missing devlog entries").option(
4186
+ "--days <number>",
4187
+ "Only show repos pushed within N days (default: 30)",
4188
+ Number.parseInt
4189
+ ).option("--all", "Show all non-archived repos regardless of push date").action(repos);
4079
4190
  }
4080
4191
 
4081
4192
  // src/commands/netframework/buildTree.ts
@@ -4174,30 +4285,30 @@ function escapeRegex(s) {
4174
4285
  }
4175
4286
 
4176
4287
  // src/commands/netframework/printTree.ts
4177
- import chalk44 from "chalk";
4288
+ import chalk45 from "chalk";
4178
4289
  function printNodes(nodes, prefix2) {
4179
4290
  for (let i = 0; i < nodes.length; i++) {
4180
4291
  const isLast = i === nodes.length - 1;
4181
4292
  const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
4182
4293
  const childPrefix = isLast ? " " : "\u2502 ";
4183
4294
  const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
4184
- const label2 = isMissing ? chalk44.red(nodes[i].relativePath) : nodes[i].relativePath;
4295
+ const label2 = isMissing ? chalk45.red(nodes[i].relativePath) : nodes[i].relativePath;
4185
4296
  console.log(`${prefix2}${connector}${label2}`);
4186
4297
  printNodes(nodes[i].children, prefix2 + childPrefix);
4187
4298
  }
4188
4299
  }
4189
4300
  function printTree(tree, totalCount, solutions) {
4190
- console.log(chalk44.bold("\nProject Dependency Tree"));
4191
- console.log(chalk44.cyan(tree.relativePath));
4301
+ console.log(chalk45.bold("\nProject Dependency Tree"));
4302
+ console.log(chalk45.cyan(tree.relativePath));
4192
4303
  printNodes(tree.children, "");
4193
- console.log(chalk44.dim(`
4304
+ console.log(chalk45.dim(`
4194
4305
  ${totalCount} projects total (including root)`));
4195
- console.log(chalk44.bold("\nSolution Membership"));
4306
+ console.log(chalk45.bold("\nSolution Membership"));
4196
4307
  if (solutions.length === 0) {
4197
- console.log(chalk44.yellow(" Not found in any .sln"));
4308
+ console.log(chalk45.yellow(" Not found in any .sln"));
4198
4309
  } else {
4199
4310
  for (const sln of solutions) {
4200
- console.log(` ${chalk44.green(sln)}`);
4311
+ console.log(` ${chalk45.green(sln)}`);
4201
4312
  }
4202
4313
  }
4203
4314
  console.log();
@@ -4226,7 +4337,7 @@ function printJson(tree, totalCount, solutions) {
4226
4337
  // src/commands/netframework/resolveCsproj.ts
4227
4338
  import { existsSync as existsSync21 } from "fs";
4228
4339
  import path20 from "path";
4229
- import chalk45 from "chalk";
4340
+ import chalk46 from "chalk";
4230
4341
 
4231
4342
  // src/commands/netframework/findRepoRoot.ts
4232
4343
  import { existsSync as existsSync20 } from "fs";
@@ -4246,12 +4357,12 @@ function findRepoRoot(dir) {
4246
4357
  function resolveCsproj(csprojPath) {
4247
4358
  const resolved = path20.resolve(csprojPath);
4248
4359
  if (!existsSync21(resolved)) {
4249
- console.error(chalk45.red(`File not found: ${resolved}`));
4360
+ console.error(chalk46.red(`File not found: ${resolved}`));
4250
4361
  process.exit(1);
4251
4362
  }
4252
4363
  const repoRoot = findRepoRoot(path20.dirname(resolved));
4253
4364
  if (!repoRoot) {
4254
- console.error(chalk45.red("Could not find git repository root"));
4365
+ console.error(chalk46.red("Could not find git repository root"));
4255
4366
  process.exit(1);
4256
4367
  }
4257
4368
  return { resolved, repoRoot };
@@ -4271,12 +4382,12 @@ async function deps(csprojPath, options2) {
4271
4382
  }
4272
4383
 
4273
4384
  // src/commands/netframework/inSln.ts
4274
- import chalk46 from "chalk";
4385
+ import chalk47 from "chalk";
4275
4386
  async function inSln(csprojPath) {
4276
4387
  const { resolved, repoRoot } = resolveCsproj(csprojPath);
4277
4388
  const solutions = findContainingSolutions(resolved, repoRoot);
4278
4389
  if (solutions.length === 0) {
4279
- console.log(chalk46.yellow("Not found in any .sln file"));
4390
+ console.log(chalk47.yellow("Not found in any .sln file"));
4280
4391
  process.exit(1);
4281
4392
  }
4282
4393
  for (const sln of solutions) {
@@ -4298,7 +4409,7 @@ import { tmpdir as tmpdir2 } from "os";
4298
4409
  import { join as join14 } from "path";
4299
4410
 
4300
4411
  // src/commands/prs/shared.ts
4301
- import { execSync as execSync19 } from "child_process";
4412
+ import { execSync as execSync20 } from "child_process";
4302
4413
  function isGhNotInstalled(error) {
4303
4414
  if (error instanceof Error) {
4304
4415
  const msg = error.message.toLowerCase();
@@ -4314,14 +4425,14 @@ function isNotFound(error) {
4314
4425
  }
4315
4426
  function getRepoInfo() {
4316
4427
  const repoInfo = JSON.parse(
4317
- execSync19("gh repo view --json owner,name", { encoding: "utf-8" })
4428
+ execSync20("gh repo view --json owner,name", { encoding: "utf-8" })
4318
4429
  );
4319
4430
  return { org: repoInfo.owner.login, repo: repoInfo.name };
4320
4431
  }
4321
4432
  function getCurrentPrNumber() {
4322
4433
  try {
4323
4434
  const prInfo = JSON.parse(
4324
- execSync19("gh pr view --json number", { encoding: "utf-8" })
4435
+ execSync20("gh pr view --json number", { encoding: "utf-8" })
4325
4436
  );
4326
4437
  return prInfo.number;
4327
4438
  } catch (error) {
@@ -4335,7 +4446,7 @@ function getCurrentPrNumber() {
4335
4446
  function getCurrentPrNodeId() {
4336
4447
  try {
4337
4448
  const prInfo = JSON.parse(
4338
- execSync19("gh pr view --json id", { encoding: "utf-8" })
4449
+ execSync20("gh pr view --json id", { encoding: "utf-8" })
4339
4450
  );
4340
4451
  return prInfo.id;
4341
4452
  } catch (error) {
@@ -4406,10 +4517,10 @@ function comment(path35, line, body) {
4406
4517
  }
4407
4518
 
4408
4519
  // src/commands/prs/fixed.ts
4409
- import { execSync as execSync21 } from "child_process";
4520
+ import { execSync as execSync22 } from "child_process";
4410
4521
 
4411
4522
  // src/commands/prs/resolveCommentWithReply.ts
4412
- import { execSync as execSync20 } from "child_process";
4523
+ import { execSync as execSync21 } from "child_process";
4413
4524
  import { unlinkSync as unlinkSync5, writeFileSync as writeFileSync16 } from "fs";
4414
4525
  import { tmpdir as tmpdir3 } from "os";
4415
4526
  import { join as join16 } from "path";
@@ -4439,7 +4550,7 @@ function deleteCommentsCache(prNumber) {
4439
4550
 
4440
4551
  // src/commands/prs/resolveCommentWithReply.ts
4441
4552
  function replyToComment(org, repo, prNumber, commentId, message) {
4442
- execSync20(
4553
+ execSync21(
4443
4554
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
4444
4555
  { stdio: "inherit" }
4445
4556
  );
@@ -4449,7 +4560,7 @@ function resolveThread(threadId) {
4449
4560
  const queryFile = join16(tmpdir3(), `gh-mutation-${Date.now()}.graphql`);
4450
4561
  writeFileSync16(queryFile, mutation);
4451
4562
  try {
4452
- execSync20(
4563
+ execSync21(
4453
4564
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
4454
4565
  { stdio: "inherit" }
4455
4566
  );
@@ -4501,7 +4612,7 @@ function resolveCommentWithReply(commentId, message) {
4501
4612
  // src/commands/prs/fixed.ts
4502
4613
  function verifySha(sha) {
4503
4614
  try {
4504
- return execSync21(`git rev-parse --verify ${sha}`, {
4615
+ return execSync22(`git rev-parse --verify ${sha}`, {
4505
4616
  encoding: "utf-8"
4506
4617
  }).trim();
4507
4618
  } catch {
@@ -4532,7 +4643,7 @@ import { join as join18 } from "path";
4532
4643
  import { stringify } from "yaml";
4533
4644
 
4534
4645
  // src/commands/prs/fetchThreadIds.ts
4535
- import { execSync as execSync22 } from "child_process";
4646
+ import { execSync as execSync23 } from "child_process";
4536
4647
  import { unlinkSync as unlinkSync6, writeFileSync as writeFileSync17 } from "fs";
4537
4648
  import { tmpdir as tmpdir4 } from "os";
4538
4649
  import { join as join17 } from "path";
@@ -4541,7 +4652,7 @@ function fetchThreadIds(org, repo, prNumber) {
4541
4652
  const queryFile = join17(tmpdir4(), `gh-query-${Date.now()}.graphql`);
4542
4653
  writeFileSync17(queryFile, THREAD_QUERY);
4543
4654
  try {
4544
- const result = execSync22(
4655
+ const result = execSync23(
4545
4656
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
4546
4657
  { encoding: "utf-8" }
4547
4658
  );
@@ -4563,9 +4674,9 @@ function fetchThreadIds(org, repo, prNumber) {
4563
4674
  }
4564
4675
 
4565
4676
  // src/commands/prs/listComments/fetchReviewComments.ts
4566
- import { execSync as execSync23 } from "child_process";
4677
+ import { execSync as execSync24 } from "child_process";
4567
4678
  function fetchJson(endpoint) {
4568
- const result = execSync23(`gh api --paginate ${endpoint}`, {
4679
+ const result = execSync24(`gh api --paginate ${endpoint}`, {
4569
4680
  encoding: "utf-8"
4570
4681
  });
4571
4682
  if (!result.trim()) return [];
@@ -4607,20 +4718,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
4607
4718
  }
4608
4719
 
4609
4720
  // src/commands/prs/listComments/printComments.ts
4610
- import chalk47 from "chalk";
4721
+ import chalk48 from "chalk";
4611
4722
  function formatForHuman(comment2) {
4612
4723
  if (comment2.type === "review") {
4613
- const stateColor = comment2.state === "APPROVED" ? chalk47.green : comment2.state === "CHANGES_REQUESTED" ? chalk47.red : chalk47.yellow;
4724
+ const stateColor = comment2.state === "APPROVED" ? chalk48.green : comment2.state === "CHANGES_REQUESTED" ? chalk48.red : chalk48.yellow;
4614
4725
  return [
4615
- `${chalk47.cyan("Review")} by ${chalk47.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
4726
+ `${chalk48.cyan("Review")} by ${chalk48.bold(comment2.user)} ${stateColor(`[${comment2.state}]`)}`,
4616
4727
  comment2.body,
4617
4728
  ""
4618
4729
  ].join("\n");
4619
4730
  }
4620
4731
  const location = comment2.line ? `:${comment2.line}` : "";
4621
4732
  return [
4622
- `${chalk47.cyan("Line comment")} by ${chalk47.bold(comment2.user)} on ${chalk47.dim(`${comment2.path}${location}`)}`,
4623
- chalk47.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
4733
+ `${chalk48.cyan("Line comment")} by ${chalk48.bold(comment2.user)} on ${chalk48.dim(`${comment2.path}${location}`)}`,
4734
+ chalk48.dim(comment2.diff_hunk.split("\n").slice(-3).join("\n")),
4624
4735
  comment2.body,
4625
4736
  ""
4626
4737
  ].join("\n");
@@ -4704,37 +4815,37 @@ async function listComments() {
4704
4815
  }
4705
4816
 
4706
4817
  // src/commands/prs/prs/index.ts
4707
- import { execSync as execSync24 } from "child_process";
4818
+ import { execSync as execSync25 } from "child_process";
4708
4819
 
4709
4820
  // src/commands/prs/prs/displayPaginated/index.ts
4710
4821
  import enquirer5 from "enquirer";
4711
4822
 
4712
4823
  // src/commands/prs/prs/displayPaginated/printPr.ts
4713
- import chalk48 from "chalk";
4824
+ import chalk49 from "chalk";
4714
4825
  var STATUS_MAP = {
4715
- MERGED: (pr) => pr.mergedAt ? { label: chalk48.magenta("merged"), date: pr.mergedAt } : null,
4716
- CLOSED: (pr) => pr.closedAt ? { label: chalk48.red("closed"), date: pr.closedAt } : null
4826
+ MERGED: (pr) => pr.mergedAt ? { label: chalk49.magenta("merged"), date: pr.mergedAt } : null,
4827
+ CLOSED: (pr) => pr.closedAt ? { label: chalk49.red("closed"), date: pr.closedAt } : null
4717
4828
  };
4718
4829
  function defaultStatus(pr) {
4719
- return { label: chalk48.green("opened"), date: pr.createdAt };
4830
+ return { label: chalk49.green("opened"), date: pr.createdAt };
4720
4831
  }
4721
- function getStatus(pr) {
4832
+ function getStatus2(pr) {
4722
4833
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
4723
4834
  }
4724
4835
  function formatDate(dateStr) {
4725
4836
  return new Date(dateStr).toISOString().split("T")[0];
4726
4837
  }
4727
4838
  function formatPrHeader(pr, status2) {
4728
- return `${chalk48.cyan(`#${pr.number}`)} ${pr.title} ${chalk48.dim(`(${pr.author.login},`)} ${status2.label} ${chalk48.dim(`${formatDate(status2.date)})`)}`;
4839
+ return `${chalk49.cyan(`#${pr.number}`)} ${pr.title} ${chalk49.dim(`(${pr.author.login},`)} ${status2.label} ${chalk49.dim(`${formatDate(status2.date)})`)}`;
4729
4840
  }
4730
4841
  function logPrDetails(pr) {
4731
4842
  console.log(
4732
- chalk48.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
4843
+ chalk49.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
4733
4844
  );
4734
4845
  console.log();
4735
4846
  }
4736
4847
  function printPr(pr) {
4737
- console.log(formatPrHeader(pr, getStatus(pr)));
4848
+ console.log(formatPrHeader(pr, getStatus2(pr)));
4738
4849
  logPrDetails(pr);
4739
4850
  }
4740
4851
 
@@ -4810,7 +4921,7 @@ async function displayPaginated(pullRequests) {
4810
4921
  async function prs(options2) {
4811
4922
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
4812
4923
  try {
4813
- const result = execSync24(
4924
+ const result = execSync25(
4814
4925
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100`,
4815
4926
  { encoding: "utf-8" }
4816
4927
  );
@@ -4833,7 +4944,7 @@ async function prs(options2) {
4833
4944
  }
4834
4945
 
4835
4946
  // src/commands/prs/wontfix.ts
4836
- import { execSync as execSync25 } from "child_process";
4947
+ import { execSync as execSync26 } from "child_process";
4837
4948
  function validateReason(reason) {
4838
4949
  const lowerReason = reason.toLowerCase();
4839
4950
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -4850,7 +4961,7 @@ function validateShaReferences(reason) {
4850
4961
  const invalidShas = [];
4851
4962
  for (const sha of shas) {
4852
4963
  try {
4853
- execSync25(`git cat-file -t ${sha}`, { stdio: "pipe" });
4964
+ execSync26(`git cat-file -t ${sha}`, { stdio: "pipe" });
4854
4965
  } catch {
4855
4966
  invalidShas.push(sha);
4856
4967
  }
@@ -4899,7 +5010,7 @@ import { spawn as spawn3 } from "child_process";
4899
5010
  import * as path21 from "path";
4900
5011
 
4901
5012
  // src/commands/refactor/logViolations.ts
4902
- import chalk49 from "chalk";
5013
+ import chalk50 from "chalk";
4903
5014
  var DEFAULT_MAX_LINES = 100;
4904
5015
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
4905
5016
  if (violations.length === 0) {
@@ -4908,43 +5019,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
4908
5019
  }
4909
5020
  return;
4910
5021
  }
4911
- console.error(chalk49.red(`
5022
+ console.error(chalk50.red(`
4912
5023
  Refactor check failed:
4913
5024
  `));
4914
- console.error(chalk49.red(` The following files exceed ${maxLines} lines:
5025
+ console.error(chalk50.red(` The following files exceed ${maxLines} lines:
4915
5026
  `));
4916
5027
  for (const violation of violations) {
4917
- console.error(chalk49.red(` ${violation.file} (${violation.lines} lines)`));
5028
+ console.error(chalk50.red(` ${violation.file} (${violation.lines} lines)`));
4918
5029
  }
4919
5030
  console.error(
4920
- chalk49.yellow(
5031
+ chalk50.yellow(
4921
5032
  `
4922
5033
  Each file needs to be sensibly refactored, or if there is no sensible
4923
5034
  way to refactor it, ignore it with:
4924
5035
  `
4925
5036
  )
4926
5037
  );
4927
- console.error(chalk49.gray(` assist refactor ignore <file>
5038
+ console.error(chalk50.gray(` assist refactor ignore <file>
4928
5039
  `));
4929
5040
  if (process.env.CLAUDECODE) {
4930
- console.error(chalk49.cyan(`
5041
+ console.error(chalk50.cyan(`
4931
5042
  ## Extracting Code to New Files
4932
5043
  `));
4933
5044
  console.error(
4934
- chalk49.cyan(
5045
+ chalk50.cyan(
4935
5046
  ` When extracting logic from one file to another, consider where the extracted code belongs:
4936
5047
  `
4937
5048
  )
4938
5049
  );
4939
5050
  console.error(
4940
- chalk49.cyan(
5051
+ chalk50.cyan(
4941
5052
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
4942
5053
  original file's domain, create a new folder containing both the original and extracted files.
4943
5054
  `
4944
5055
  )
4945
5056
  );
4946
5057
  console.error(
4947
- chalk49.cyan(
5058
+ chalk50.cyan(
4948
5059
  ` 2. Share common utilities: If the extracted code can be reused across multiple
4949
5060
  domains, move it to a common/shared folder.
4950
5061
  `
@@ -4954,7 +5065,7 @@ Refactor check failed:
4954
5065
  }
4955
5066
 
4956
5067
  // src/commands/refactor/check/getViolations/index.ts
4957
- import { execSync as execSync26 } from "child_process";
5068
+ import { execSync as execSync27 } from "child_process";
4958
5069
  import fs15 from "fs";
4959
5070
  import { minimatch as minimatch4 } from "minimatch";
4960
5071
 
@@ -5004,7 +5115,7 @@ function getGitFiles(options2) {
5004
5115
  }
5005
5116
  const files = /* @__PURE__ */ new Set();
5006
5117
  if (options2.staged || options2.modified) {
5007
- const staged = execSync26("git diff --cached --name-only", {
5118
+ const staged = execSync27("git diff --cached --name-only", {
5008
5119
  encoding: "utf-8"
5009
5120
  });
5010
5121
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -5012,7 +5123,7 @@ function getGitFiles(options2) {
5012
5123
  }
5013
5124
  }
5014
5125
  if (options2.unstaged || options2.modified) {
5015
- const unstaged = execSync26("git diff --name-only", { encoding: "utf-8" });
5126
+ const unstaged = execSync27("git diff --name-only", { encoding: "utf-8" });
5016
5127
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
5017
5128
  files.add(file);
5018
5129
  }
@@ -5100,11 +5211,11 @@ async function check(pattern2, options2) {
5100
5211
 
5101
5212
  // src/commands/refactor/ignore.ts
5102
5213
  import fs16 from "fs";
5103
- import chalk50 from "chalk";
5214
+ import chalk51 from "chalk";
5104
5215
  var REFACTOR_YML_PATH2 = "refactor.yml";
5105
5216
  function ignore(file) {
5106
5217
  if (!fs16.existsSync(file)) {
5107
- console.error(chalk50.red(`Error: File does not exist: ${file}`));
5218
+ console.error(chalk51.red(`Error: File does not exist: ${file}`));
5108
5219
  process.exit(1);
5109
5220
  }
5110
5221
  const content = fs16.readFileSync(file, "utf-8");
@@ -5120,7 +5231,7 @@ function ignore(file) {
5120
5231
  fs16.writeFileSync(REFACTOR_YML_PATH2, entry);
5121
5232
  }
5122
5233
  console.log(
5123
- chalk50.green(
5234
+ chalk51.green(
5124
5235
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
5125
5236
  )
5126
5237
  );
@@ -5128,7 +5239,7 @@ function ignore(file) {
5128
5239
 
5129
5240
  // src/commands/refactor/restructure/index.ts
5130
5241
  import path30 from "path";
5131
- import chalk53 from "chalk";
5242
+ import chalk54 from "chalk";
5132
5243
 
5133
5244
  // src/commands/refactor/restructure/buildImportGraph/index.ts
5134
5245
  import path22 from "path";
@@ -5371,50 +5482,50 @@ function computeRewrites(moves, edges, allProjectFiles) {
5371
5482
 
5372
5483
  // src/commands/refactor/restructure/displayPlan.ts
5373
5484
  import path26 from "path";
5374
- import chalk51 from "chalk";
5485
+ import chalk52 from "chalk";
5375
5486
  function relPath(filePath) {
5376
5487
  return path26.relative(process.cwd(), filePath);
5377
5488
  }
5378
5489
  function displayMoves(plan) {
5379
5490
  if (plan.moves.length === 0) return;
5380
- console.log(chalk51.bold("\nFile moves:"));
5491
+ console.log(chalk52.bold("\nFile moves:"));
5381
5492
  for (const move of plan.moves) {
5382
5493
  console.log(
5383
- ` ${chalk51.red(relPath(move.from))} \u2192 ${chalk51.green(relPath(move.to))}`
5494
+ ` ${chalk52.red(relPath(move.from))} \u2192 ${chalk52.green(relPath(move.to))}`
5384
5495
  );
5385
- console.log(chalk51.dim(` ${move.reason}`));
5496
+ console.log(chalk52.dim(` ${move.reason}`));
5386
5497
  }
5387
5498
  }
5388
5499
  function displayRewrites(rewrites) {
5389
5500
  if (rewrites.length === 0) return;
5390
5501
  const affectedFiles = new Set(rewrites.map((r) => r.file));
5391
- console.log(chalk51.bold(`
5502
+ console.log(chalk52.bold(`
5392
5503
  Import rewrites (${affectedFiles.size} files):`));
5393
5504
  for (const file of affectedFiles) {
5394
- console.log(` ${chalk51.cyan(relPath(file))}:`);
5505
+ console.log(` ${chalk52.cyan(relPath(file))}:`);
5395
5506
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
5396
5507
  (r) => r.file === file
5397
5508
  )) {
5398
5509
  console.log(
5399
- ` ${chalk51.red(`"${oldSpecifier}"`)} \u2192 ${chalk51.green(`"${newSpecifier}"`)}`
5510
+ ` ${chalk52.red(`"${oldSpecifier}"`)} \u2192 ${chalk52.green(`"${newSpecifier}"`)}`
5400
5511
  );
5401
5512
  }
5402
5513
  }
5403
5514
  }
5404
5515
  function displayPlan(plan) {
5405
5516
  if (plan.warnings.length > 0) {
5406
- console.log(chalk51.yellow("\nWarnings:"));
5407
- for (const w of plan.warnings) console.log(chalk51.yellow(` ${w}`));
5517
+ console.log(chalk52.yellow("\nWarnings:"));
5518
+ for (const w of plan.warnings) console.log(chalk52.yellow(` ${w}`));
5408
5519
  }
5409
5520
  if (plan.newDirectories.length > 0) {
5410
- console.log(chalk51.bold("\nNew directories:"));
5521
+ console.log(chalk52.bold("\nNew directories:"));
5411
5522
  for (const dir of plan.newDirectories)
5412
- console.log(chalk51.green(` ${dir}/`));
5523
+ console.log(chalk52.green(` ${dir}/`));
5413
5524
  }
5414
5525
  displayMoves(plan);
5415
5526
  displayRewrites(plan.rewrites);
5416
5527
  console.log(
5417
- chalk51.dim(
5528
+ chalk52.dim(
5418
5529
  `
5419
5530
  Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rewritten`
5420
5531
  )
@@ -5424,18 +5535,18 @@ Summary: ${plan.moves.length} file(s) moved, ${plan.rewrites.length} imports rew
5424
5535
  // src/commands/refactor/restructure/executePlan.ts
5425
5536
  import fs18 from "fs";
5426
5537
  import path27 from "path";
5427
- import chalk52 from "chalk";
5538
+ import chalk53 from "chalk";
5428
5539
  function executePlan(plan) {
5429
5540
  const updatedContents = applyRewrites(plan.rewrites);
5430
5541
  for (const [file, content] of updatedContents) {
5431
5542
  fs18.writeFileSync(file, content, "utf-8");
5432
5543
  console.log(
5433
- chalk52.cyan(` Rewrote imports in ${path27.relative(process.cwd(), file)}`)
5544
+ chalk53.cyan(` Rewrote imports in ${path27.relative(process.cwd(), file)}`)
5434
5545
  );
5435
5546
  }
5436
5547
  for (const dir of plan.newDirectories) {
5437
5548
  fs18.mkdirSync(dir, { recursive: true });
5438
- console.log(chalk52.green(` Created ${path27.relative(process.cwd(), dir)}/`));
5549
+ console.log(chalk53.green(` Created ${path27.relative(process.cwd(), dir)}/`));
5439
5550
  }
5440
5551
  for (const move of plan.moves) {
5441
5552
  const targetDir = path27.dirname(move.to);
@@ -5444,7 +5555,7 @@ function executePlan(plan) {
5444
5555
  }
5445
5556
  fs18.renameSync(move.from, move.to);
5446
5557
  console.log(
5447
- chalk52.white(
5558
+ chalk53.white(
5448
5559
  ` Moved ${path27.relative(process.cwd(), move.from)} \u2192 ${path27.relative(process.cwd(), move.to)}`
5449
5560
  )
5450
5561
  );
@@ -5459,7 +5570,7 @@ function removeEmptyDirectories(dirs) {
5459
5570
  if (entries.length === 0) {
5460
5571
  fs18.rmdirSync(dir);
5461
5572
  console.log(
5462
- chalk52.dim(
5573
+ chalk53.dim(
5463
5574
  ` Removed empty directory ${path27.relative(process.cwd(), dir)}`
5464
5575
  )
5465
5576
  );
@@ -5590,22 +5701,22 @@ async function restructure(pattern2, options2 = {}) {
5590
5701
  const targetPattern = pattern2 ?? "src";
5591
5702
  const files = findSourceFiles2(targetPattern);
5592
5703
  if (files.length === 0) {
5593
- console.log(chalk53.yellow("No files found matching pattern"));
5704
+ console.log(chalk54.yellow("No files found matching pattern"));
5594
5705
  return;
5595
5706
  }
5596
5707
  const tsConfigPath = path30.resolve("tsconfig.json");
5597
5708
  const plan = buildPlan(files, tsConfigPath);
5598
5709
  if (plan.moves.length === 0) {
5599
- console.log(chalk53.green("No restructuring needed"));
5710
+ console.log(chalk54.green("No restructuring needed"));
5600
5711
  return;
5601
5712
  }
5602
5713
  displayPlan(plan);
5603
5714
  if (options2.apply) {
5604
- console.log(chalk53.bold("\nApplying changes..."));
5715
+ console.log(chalk54.bold("\nApplying changes..."));
5605
5716
  executePlan(plan);
5606
- console.log(chalk53.green("\nRestructuring complete"));
5717
+ console.log(chalk54.green("\nRestructuring complete"));
5607
5718
  } else {
5608
- console.log(chalk53.dim("\nDry run. Use --apply to execute."));
5719
+ console.log(chalk54.dim("\nDry run. Use --apply to execute."));
5609
5720
  }
5610
5721
  }
5611
5722
 
@@ -6148,14 +6259,14 @@ import {
6148
6259
  import { dirname as dirname17, join as join23 } from "path";
6149
6260
 
6150
6261
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
6151
- import chalk54 from "chalk";
6262
+ import chalk55 from "chalk";
6152
6263
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
6153
6264
  function validateStagedContent(filename, content) {
6154
6265
  const firstLine = content.split("\n")[0];
6155
6266
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
6156
6267
  if (!match) {
6157
6268
  console.error(
6158
- chalk54.red(
6269
+ chalk55.red(
6159
6270
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
6160
6271
  )
6161
6272
  );
@@ -6164,7 +6275,7 @@ function validateStagedContent(filename, content) {
6164
6275
  const contentAfterLink = content.slice(firstLine.length).trim();
6165
6276
  if (!contentAfterLink) {
6166
6277
  console.error(
6167
- chalk54.red(
6278
+ chalk55.red(
6168
6279
  `Staged file ${filename} has no summary content after the transcript link.`
6169
6280
  )
6170
6281
  );
@@ -6364,7 +6475,7 @@ import { mkdirSync as mkdirSync9 } from "fs";
6364
6475
  import { join as join28 } from "path";
6365
6476
 
6366
6477
  // src/commands/voice/checkLockFile.ts
6367
- import { execSync as execSync27 } from "child_process";
6478
+ import { execSync as execSync28 } from "child_process";
6368
6479
  import { existsSync as existsSync30, mkdirSync as mkdirSync8, readFileSync as readFileSync24, writeFileSync as writeFileSync20 } from "fs";
6369
6480
  import { join as join27 } from "path";
6370
6481
  function isProcessAlive(pid) {
@@ -6393,7 +6504,7 @@ function bootstrapVenv() {
6393
6504
  if (existsSync30(getVenvPython())) return;
6394
6505
  console.log("Setting up Python environment...");
6395
6506
  const pythonDir = getPythonDir();
6396
- execSync27(
6507
+ execSync28(
6397
6508
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
6398
6509
  {
6399
6510
  stdio: "inherit",
@@ -6557,14 +6668,14 @@ function registerVoice(program2) {
6557
6668
 
6558
6669
  // src/commands/roam/auth.ts
6559
6670
  import { randomBytes } from "crypto";
6560
- import chalk55 from "chalk";
6671
+ import chalk56 from "chalk";
6561
6672
 
6562
6673
  // src/lib/openBrowser.ts
6563
- import { execSync as execSync28 } from "child_process";
6674
+ import { execSync as execSync29 } from "child_process";
6564
6675
  function tryExec(commands) {
6565
6676
  for (const cmd of commands) {
6566
6677
  try {
6567
- execSync28(cmd);
6678
+ execSync29(cmd);
6568
6679
  return true;
6569
6680
  } catch {
6570
6681
  }
@@ -6732,13 +6843,13 @@ async function auth() {
6732
6843
  saveGlobalConfig(config);
6733
6844
  const state = randomBytes(16).toString("hex");
6734
6845
  console.log(
6735
- chalk55.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
6846
+ chalk56.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
6736
6847
  );
6737
- console.log(chalk55.white("http://localhost:14523/callback\n"));
6738
- console.log(chalk55.blue("Opening browser for authorization..."));
6739
- console.log(chalk55.dim("Waiting for authorization callback..."));
6848
+ console.log(chalk56.white("http://localhost:14523/callback\n"));
6849
+ console.log(chalk56.blue("Opening browser for authorization..."));
6850
+ console.log(chalk56.dim("Waiting for authorization callback..."));
6740
6851
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
6741
- console.log(chalk55.dim("Exchanging code for tokens..."));
6852
+ console.log(chalk56.dim("Exchanging code for tokens..."));
6742
6853
  const tokens = await exchangeToken({
6743
6854
  code,
6744
6855
  clientId,
@@ -6754,7 +6865,7 @@ async function auth() {
6754
6865
  };
6755
6866
  saveGlobalConfig(config);
6756
6867
  console.log(
6757
- chalk55.green("Roam credentials and tokens saved to ~/.assist.yml")
6868
+ chalk56.green("Roam credentials and tokens saved to ~/.assist.yml")
6758
6869
  );
6759
6870
  }
6760
6871
 
@@ -6942,14 +7053,14 @@ function run2(name, args) {
6942
7053
  }
6943
7054
 
6944
7055
  // src/commands/statusLine.ts
6945
- import chalk56 from "chalk";
7056
+ import chalk57 from "chalk";
6946
7057
  function formatNumber(num) {
6947
7058
  return num.toLocaleString("en-US");
6948
7059
  }
6949
7060
  function colorizePercent(pct) {
6950
7061
  const label2 = `${pct}%`;
6951
- if (pct > 80) return chalk56.red(label2);
6952
- if (pct > 40) return chalk56.yellow(label2);
7062
+ if (pct > 80) return chalk57.red(label2);
7063
+ if (pct > 40) return chalk57.yellow(label2);
6953
7064
  return label2;
6954
7065
  }
6955
7066
  async function statusLine() {
@@ -6975,7 +7086,7 @@ import { fileURLToPath as fileURLToPath7 } from "url";
6975
7086
  // src/commands/sync/syncClaudeMd.ts
6976
7087
  import * as fs21 from "fs";
6977
7088
  import * as path31 from "path";
6978
- import chalk57 from "chalk";
7089
+ import chalk58 from "chalk";
6979
7090
  async function syncClaudeMd(claudeDir, targetBase) {
6980
7091
  const source = path31.join(claudeDir, "CLAUDE.md");
6981
7092
  const target = path31.join(targetBase, "CLAUDE.md");
@@ -6984,12 +7095,12 @@ async function syncClaudeMd(claudeDir, targetBase) {
6984
7095
  const targetContent = fs21.readFileSync(target, "utf-8");
6985
7096
  if (sourceContent !== targetContent) {
6986
7097
  console.log(
6987
- chalk57.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
7098
+ chalk58.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
6988
7099
  );
6989
7100
  console.log();
6990
7101
  printDiff(targetContent, sourceContent);
6991
7102
  const confirm = await promptConfirm(
6992
- chalk57.red("Overwrite existing CLAUDE.md?"),
7103
+ chalk58.red("Overwrite existing CLAUDE.md?"),
6993
7104
  false
6994
7105
  );
6995
7106
  if (!confirm) {
@@ -7005,7 +7116,7 @@ async function syncClaudeMd(claudeDir, targetBase) {
7005
7116
  // src/commands/sync/syncSettings.ts
7006
7117
  import * as fs22 from "fs";
7007
7118
  import * as path32 from "path";
7008
- import chalk58 from "chalk";
7119
+ import chalk59 from "chalk";
7009
7120
  async function syncSettings(claudeDir, targetBase, options2) {
7010
7121
  const source = path32.join(claudeDir, "settings.json");
7011
7122
  const target = path32.join(targetBase, "settings.json");
@@ -7021,14 +7132,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
7021
7132
  if (mergedContent !== normalizedTarget) {
7022
7133
  if (!options2?.yes) {
7023
7134
  console.log(
7024
- chalk58.yellow(
7135
+ chalk59.yellow(
7025
7136
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
7026
7137
  )
7027
7138
  );
7028
7139
  console.log();
7029
7140
  printDiff(targetContent, mergedContent);
7030
7141
  const confirm = await promptConfirm(
7031
- chalk58.red("Overwrite existing settings.json?"),
7142
+ chalk59.red("Overwrite existing settings.json?"),
7032
7143
  false
7033
7144
  );
7034
7145
  if (!confirm) {
@@ -7065,7 +7176,7 @@ function syncCommands(claudeDir, targetBase) {
7065
7176
  }
7066
7177
 
7067
7178
  // src/commands/update.ts
7068
- import { execSync as execSync29 } from "child_process";
7179
+ import { execSync as execSync30 } from "child_process";
7069
7180
  import * as path34 from "path";
7070
7181
  function isGlobalNpmInstall(dir) {
7071
7182
  try {
@@ -7073,7 +7184,7 @@ function isGlobalNpmInstall(dir) {
7073
7184
  if (resolved.split(path34.sep).includes("node_modules")) {
7074
7185
  return true;
7075
7186
  }
7076
- const globalPrefix = execSync29("npm prefix -g", { stdio: "pipe" }).toString().trim();
7187
+ const globalPrefix = execSync30("npm prefix -g", { stdio: "pipe" }).toString().trim();
7077
7188
  return resolved.toLowerCase().startsWith(path34.resolve(globalPrefix).toLowerCase());
7078
7189
  } catch {
7079
7190
  return false;
@@ -7084,18 +7195,18 @@ async function update() {
7084
7195
  console.log(`Assist is installed at: ${installDir}`);
7085
7196
  if (isGitRepo(installDir)) {
7086
7197
  console.log("Detected git repo installation, pulling latest...");
7087
- execSync29("git pull", { cwd: installDir, stdio: "inherit" });
7198
+ execSync30("git pull", { cwd: installDir, stdio: "inherit" });
7088
7199
  console.log("Installing dependencies...");
7089
- execSync29("npm i", { cwd: installDir, stdio: "inherit" });
7200
+ execSync30("npm i", { cwd: installDir, stdio: "inherit" });
7090
7201
  console.log("Building...");
7091
- execSync29("npm run build", { cwd: installDir, stdio: "inherit" });
7202
+ execSync30("npm run build", { cwd: installDir, stdio: "inherit" });
7092
7203
  console.log("Syncing commands...");
7093
- execSync29("assist sync", { stdio: "inherit" });
7204
+ execSync30("assist sync", { stdio: "inherit" });
7094
7205
  } else if (isGlobalNpmInstall(installDir)) {
7095
7206
  console.log("Detected global npm installation, updating...");
7096
- execSync29("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
7207
+ execSync30("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
7097
7208
  console.log("Syncing commands...");
7098
- execSync29("assist sync", { stdio: "inherit" });
7209
+ execSync30("assist sync", { stdio: "inherit" });
7099
7210
  } else {
7100
7211
  console.error(
7101
7212
  "Could not determine installation method. Expected a git repo or global npm install."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@staff0rd/assist",
3
- "version": "0.103.0",
3
+ "version": "0.105.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {