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