@staff0rd/assist 0.346.0 → 0.348.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.346.0",
9
+ version: "0.348.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -201,6 +201,10 @@ var assistConfigSchema = z2.strictObject({
201
201
  push: z2.boolean().default(false),
202
202
  expectedBranch: z2.string().optional()
203
203
  }).default({ conventional: false, pull: false, push: false }),
204
+ branch: z2.strictObject({
205
+ prefix: z2.string().optional(),
206
+ defaultBranch: z2.string().optional()
207
+ }).optional(),
204
208
  devlog: z2.strictObject({
205
209
  name: z2.string().optional(),
206
210
  ignore: z2.array(z2.string()).optional(),
@@ -6146,8 +6150,8 @@ import { promisify } from "util";
6146
6150
  // src/commands/sessions/web/findSynthesisForBranch.ts
6147
6151
  import { existsSync as existsSync24, readdirSync, statSync as statSync2 } from "fs";
6148
6152
  import { basename as basename2, dirname as dirname18, join as join21 } from "path";
6149
- function findSynthesisForBranch(repoReviewsDir, branch) {
6150
- const branchKeyPath = join21(repoReviewsDir, `${branch}-`);
6153
+ function findSynthesisForBranch(repoReviewsDir, branch2) {
6154
+ const branchKeyPath = join21(repoReviewsDir, `${branch2}-`);
6151
6155
  const parent = dirname18(branchKeyPath);
6152
6156
  const branchPrefix = basename2(branchKeyPath);
6153
6157
  if (!existsSync24(parent)) return null;
@@ -6184,7 +6188,7 @@ function runGit(cwd, args) {
6184
6188
  }).then((r) => r.stdout.trim());
6185
6189
  }
6186
6190
  async function resolveSynthesisPath(cwd) {
6187
- const [repoRoot, branch] = await Promise.all([
6191
+ const [repoRoot, branch2] = await Promise.all([
6188
6192
  runGit(cwd, ["rev-parse", "--show-toplevel"]),
6189
6193
  runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
6190
6194
  ]);
@@ -6194,7 +6198,7 @@ async function resolveSynthesisPath(cwd) {
6194
6198
  "reviews",
6195
6199
  basename3(repoRoot)
6196
6200
  );
6197
- return findSynthesisForBranch(repoReviewsDir, branch);
6201
+ return findSynthesisForBranch(repoReviewsDir, branch2);
6198
6202
  }
6199
6203
  async function getReviewSynthesis(req, res) {
6200
6204
  const cwd = getCwdParam(req, res);
@@ -8698,6 +8702,101 @@ function registerBacklog(program2) {
8698
8702
  }
8699
8703
  }
8700
8704
 
8705
+ // src/commands/branch/branch.ts
8706
+ import { execSync as execSync24 } from "child_process";
8707
+
8708
+ // src/commands/branch/buildBranchName.ts
8709
+ function buildBranchName({
8710
+ prefix: prefix2,
8711
+ jira,
8712
+ slug
8713
+ }) {
8714
+ const segments = [];
8715
+ if (prefix2) segments.push(`${prefix2}/`);
8716
+ if (jira) segments.push(`${jira}-`);
8717
+ segments.push(slug);
8718
+ return segments.join("");
8719
+ }
8720
+
8721
+ // src/commands/branch/resolveDefaultBranch.ts
8722
+ import { execSync as execSync23 } from "child_process";
8723
+ var REMOTE_HEAD_REGEX = /^ref:\s+refs\/heads\/(\S+)\s+HEAD$/m;
8724
+ function resolveDefaultBranch(override, cwd) {
8725
+ if (override) return override;
8726
+ try {
8727
+ const output = execSync23("git ls-remote --symref origin HEAD", {
8728
+ encoding: "utf8",
8729
+ stdio: ["pipe", "pipe", "pipe"],
8730
+ cwd
8731
+ });
8732
+ const match = output.match(REMOTE_HEAD_REGEX);
8733
+ if (match) return match[1];
8734
+ } catch {
8735
+ }
8736
+ return "main";
8737
+ }
8738
+
8739
+ // src/commands/branch/validateSlug.ts
8740
+ var KEBAB_CASE_REGEX = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
8741
+ var HASH_REF_REGEX = /#\d+/;
8742
+ var BACKLOG_NUMBER_SEGMENT_REGEX = /(?:^|-)\d{1,4}(?:-|$)/;
8743
+ function validateSlug(slug) {
8744
+ if (!slug) {
8745
+ return "Slug is required";
8746
+ }
8747
+ if (HASH_REF_REGEX.test(slug)) {
8748
+ return `Slug "${slug}" contains a backlog reference (#<number>); remove it`;
8749
+ }
8750
+ if (!KEBAB_CASE_REGEX.test(slug)) {
8751
+ return `Slug "${slug}" must be kebab-case (lowercase letters, digits, and hyphens)`;
8752
+ }
8753
+ if (BACKLOG_NUMBER_SEGMENT_REGEX.test(slug)) {
8754
+ return `Slug "${slug}" contains a numeric token that looks like a backlog ID; remove or reword it`;
8755
+ }
8756
+ return null;
8757
+ }
8758
+
8759
+ // src/commands/branch/branch.ts
8760
+ function branch(slug, options2) {
8761
+ const slugError = validateSlug(slug);
8762
+ if (slugError) {
8763
+ console.error(`Error: ${slugError}`);
8764
+ process.exit(1);
8765
+ }
8766
+ const config = loadConfig();
8767
+ const branchName = buildBranchName({
8768
+ prefix: config.branch?.prefix,
8769
+ jira: options2.jira,
8770
+ slug
8771
+ });
8772
+ try {
8773
+ const defaultBranch = resolveDefaultBranch(config.branch?.defaultBranch);
8774
+ execSync24("git fetch", { stdio: "inherit" });
8775
+ execSync24(
8776
+ `git switch -c ${shellQuote(branchName)} ${shellQuote(`origin/${defaultBranch}`)}`,
8777
+ { stdio: "inherit" }
8778
+ );
8779
+ console.log(
8780
+ `Created and switched to ${branchName} (from origin/${defaultBranch})`
8781
+ );
8782
+ process.exit(0);
8783
+ } catch (error) {
8784
+ console.error(
8785
+ `Error: ${error instanceof Error ? error.message : String(error)}`
8786
+ );
8787
+ process.exit(1);
8788
+ }
8789
+ }
8790
+
8791
+ // src/commands/registerBranch.ts
8792
+ function registerBranch(program2) {
8793
+ program2.command("branch <slug>").description(
8794
+ "Create and switch to a branch off the fresh remote default branch"
8795
+ ).option("--jira <key>", "Jira issue key to include in the branch name").action(
8796
+ (slug, options2) => branch(slug, options2)
8797
+ );
8798
+ }
8799
+
8701
8800
  // src/commands/cliHook/index.ts
8702
8801
  import { basename as basename4 } from "path";
8703
8802
 
@@ -8838,14 +8937,26 @@ var BUILTIN_DENIES = [
8838
8937
  message: `Do not run 'git commit' directly. Use 'assist commit "<message>"' instead.`
8839
8938
  }
8840
8939
  ];
8940
+ var BRANCH_CREATION_MESSAGE = "Do not create branches with raw git. Use the /branch command, or 'assist branch <slug> [--jira <KEY>]' \u2014 it branches off the fresh remote default and enforces the team naming convention.";
8941
+ var BRANCH_CREATION_REGEXES = [
8942
+ /(?<=^|\s)git\s+(?:checkout|co)\s+-[bB](?=\s|$)/,
8943
+ /(?<=^|\s)git\s+switch\s+(?:-[cC]|--create)(?=\s|$)/,
8944
+ /(?<=^|\s)git\s+branch\s+(?!-)\S/
8945
+ ];
8841
8946
  function rawDenyRegex(pattern2) {
8842
8947
  const tokens = pattern2.trim().split(/\s+/).map((token) => token.replace(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)).join(String.raw`\s+`);
8843
8948
  return new RegExp(`(?<=^|\\s)${tokens}(?=\\s|$)`);
8844
8949
  }
8845
- var RAW_BUILTIN_DENIES = BUILTIN_DENIES.map((rule) => ({
8846
- ...rule,
8847
- regex: rawDenyRegex(rule.pattern)
8848
- }));
8950
+ var RAW_BUILTIN_DENIES = [
8951
+ ...BUILTIN_DENIES.map((rule) => ({
8952
+ message: rule.message,
8953
+ regex: rawDenyRegex(rule.pattern)
8954
+ })),
8955
+ ...BRANCH_CREATION_REGEXES.map((regex) => ({
8956
+ message: BRANCH_CREATION_MESSAGE,
8957
+ regex
8958
+ }))
8959
+ ];
8849
8960
  function matchBuiltinDeny(text7) {
8850
8961
  return RAW_BUILTIN_DENIES.find((rule) => rule.regex.test(text7));
8851
8962
  }
@@ -9336,7 +9447,7 @@ import { homedir as homedir12 } from "os";
9336
9447
  import { join as join26 } from "path";
9337
9448
 
9338
9449
  // src/shared/checkCliAvailable.ts
9339
- import { execSync as execSync23 } from "child_process";
9450
+ import { execSync as execSync25 } from "child_process";
9340
9451
  function checkCliAvailable(cli) {
9341
9452
  const binary = cli.split(/\s+/)[0];
9342
9453
  const opts = {
@@ -9344,11 +9455,11 @@ function checkCliAvailable(cli) {
9344
9455
  stdio: ["ignore", "pipe", "pipe"]
9345
9456
  };
9346
9457
  try {
9347
- execSync23(`command -v ${binary}`, opts);
9458
+ execSync25(`command -v ${binary}`, opts);
9348
9459
  return true;
9349
9460
  } catch {
9350
9461
  try {
9351
- execSync23(`where ${binary}`, opts);
9462
+ execSync25(`where ${binary}`, opts);
9352
9463
  return true;
9353
9464
  } catch {
9354
9465
  return false;
@@ -10724,7 +10835,7 @@ function loadBlogSkipDays(repoName) {
10724
10835
  }
10725
10836
 
10726
10837
  // src/commands/devlog/shared.ts
10727
- import { execSync as execSync24 } from "child_process";
10838
+ import { execSync as execSync26 } from "child_process";
10728
10839
  import chalk109 from "chalk";
10729
10840
 
10730
10841
  // src/shared/getRepoName.ts
@@ -10816,7 +10927,7 @@ function loadAllDevlogLatestDates() {
10816
10927
  // src/commands/devlog/shared.ts
10817
10928
  function getCommitFiles(hash) {
10818
10929
  try {
10819
- const output = execSync24(`git show --name-only --format="" ${hash}`, {
10930
+ const output = execSync26(`git show --name-only --format="" ${hash}`, {
10820
10931
  encoding: "utf8"
10821
10932
  });
10822
10933
  return output.trim().split("\n").filter(Boolean);
@@ -10912,11 +11023,11 @@ function list3(options2) {
10912
11023
  }
10913
11024
 
10914
11025
  // src/commands/devlog/getLastVersionInfo.ts
10915
- import { execFileSync as execFileSync3, execSync as execSync25 } from "child_process";
11026
+ import { execFileSync as execFileSync3, execSync as execSync27 } from "child_process";
10916
11027
  import semver from "semver";
10917
11028
  function getVersionAtCommit(hash) {
10918
11029
  try {
10919
- const content = execSync25(`git show ${hash}:package.json`, {
11030
+ const content = execSync27(`git show ${hash}:package.json`, {
10920
11031
  encoding: "utf8"
10921
11032
  });
10922
11033
  const pkg = JSON.parse(content);
@@ -11089,7 +11200,7 @@ function next2(options2) {
11089
11200
  }
11090
11201
 
11091
11202
  // src/commands/devlog/repos/index.ts
11092
- import { execSync as execSync26 } from "child_process";
11203
+ import { execSync as execSync28 } from "child_process";
11093
11204
 
11094
11205
  // src/commands/devlog/repos/printReposTable.ts
11095
11206
  import chalk113 from "chalk";
@@ -11124,7 +11235,7 @@ function getStatus(lastPush, lastDevlog) {
11124
11235
  return lastDevlog < lastPush ? "outdated" : "ok";
11125
11236
  }
11126
11237
  function fetchRepos(days, all) {
11127
- const json = execSync26(
11238
+ const json = execSync28(
11128
11239
  "gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
11129
11240
  { encoding: "utf8" }
11130
11241
  );
@@ -11484,7 +11595,7 @@ async function deps(csprojPath, options2) {
11484
11595
  }
11485
11596
 
11486
11597
  // src/commands/dotnet/getChangedCsFiles.ts
11487
- import { execSync as execSync27 } from "child_process";
11598
+ import { execSync as execSync29 } from "child_process";
11488
11599
  var SCOPE_ALL = "all";
11489
11600
  var SCOPE_BASE = "base:";
11490
11601
  var SCOPE_COMMIT = "commit:";
@@ -11508,7 +11619,7 @@ function getChangedCsFiles(scope) {
11508
11619
  } else {
11509
11620
  cmd = "git diff --name-only HEAD";
11510
11621
  }
11511
- const output = execSync27(cmd, { encoding: "utf8" }).trim();
11622
+ const output = execSync29(cmd, { encoding: "utf8" }).trim();
11512
11623
  if (output === "") return [];
11513
11624
  return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
11514
11625
  }
@@ -11706,14 +11817,14 @@ function parseInspectReport(json) {
11706
11817
  }
11707
11818
 
11708
11819
  // src/commands/dotnet/runInspectCode.ts
11709
- import { execSync as execSync28 } from "child_process";
11820
+ import { execSync as execSync30 } from "child_process";
11710
11821
  import { existsSync as existsSync35, readFileSync as readFileSync30, unlinkSync as unlinkSync9 } from "fs";
11711
11822
  import { tmpdir as tmpdir3 } from "os";
11712
11823
  import path27 from "path";
11713
11824
  import chalk123 from "chalk";
11714
11825
  function assertJbInstalled() {
11715
11826
  try {
11716
- execSync28("jb inspectcode --version", { stdio: "pipe" });
11827
+ execSync30("jb inspectcode --version", { stdio: "pipe" });
11717
11828
  } catch {
11718
11829
  console.error(chalk123.red("jb is not installed. Install with:"));
11719
11830
  console.error(
@@ -11727,7 +11838,7 @@ function runInspectCode(slnPath, include, swea) {
11727
11838
  const includeFlag = include ? ` --include="${include}"` : "";
11728
11839
  const sweaFlag = swea ? " --swea" : "";
11729
11840
  try {
11730
- execSync28(
11841
+ execSync30(
11731
11842
  `jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
11732
11843
  { stdio: "pipe" }
11733
11844
  );
@@ -11748,7 +11859,7 @@ function runInspectCode(slnPath, include, swea) {
11748
11859
  }
11749
11860
 
11750
11861
  // src/commands/dotnet/runRoslynInspect.ts
11751
- import { execSync as execSync29 } from "child_process";
11862
+ import { execSync as execSync31 } from "child_process";
11752
11863
  import chalk124 from "chalk";
11753
11864
  function resolveMsbuildPath() {
11754
11865
  const { run: run4 } = loadConfig();
@@ -11759,7 +11870,7 @@ function resolveMsbuildPath() {
11759
11870
  function assertMsbuildInstalled() {
11760
11871
  const msbuild = resolveMsbuildPath();
11761
11872
  try {
11762
- execSync29(`"${msbuild}" -version`, { stdio: "pipe" });
11873
+ execSync31(`"${msbuild}" -version`, { stdio: "pipe" });
11763
11874
  } catch {
11764
11875
  console.error(chalk124.red(`msbuild not found at: ${msbuild}`));
11765
11876
  console.error(
@@ -11785,7 +11896,7 @@ function runRoslynInspect(slnPath) {
11785
11896
  const msbuild = resolveMsbuildPath();
11786
11897
  let output;
11787
11898
  try {
11788
- output = execSync29(
11899
+ output = execSync31(
11789
11900
  `"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
11790
11901
  { encoding: "utf8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
11791
11902
  );
@@ -12574,7 +12685,7 @@ function acceptanceCriteria(issueKey) {
12574
12685
  }
12575
12686
 
12576
12687
  // src/commands/jira/jiraAuth.ts
12577
- import { execSync as execSync30 } from "child_process";
12688
+ import { execSync as execSync32 } from "child_process";
12578
12689
 
12579
12690
  // src/shared/loadJson.ts
12580
12691
  import { existsSync as existsSync37, mkdirSync as mkdirSync13, readFileSync as readFileSync32, writeFileSync as writeFileSync27 } from "fs";
@@ -12638,7 +12749,7 @@ async function jiraAuth() {
12638
12749
  console.error("All fields are required.");
12639
12750
  process.exit(1);
12640
12751
  }
12641
- execSync30(`acli jira auth login --site ${site} --email "${email}" --token`, {
12752
+ execSync32(`acli jira auth login --site ${site} --email "${email}" --token`, {
12642
12753
  encoding: "utf8",
12643
12754
  input: token,
12644
12755
  stdio: ["pipe", "inherit", "inherit"]
@@ -13640,7 +13751,7 @@ function registerPrompts(program2) {
13640
13751
  }
13641
13752
 
13642
13753
  // src/commands/prs/shared.ts
13643
- import { execSync as execSync31 } from "child_process";
13754
+ import { execSync as execSync33 } from "child_process";
13644
13755
  function isGhNotInstalled(error) {
13645
13756
  if (error instanceof Error) {
13646
13757
  const msg = error.message.toLowerCase();
@@ -13658,20 +13769,20 @@ function getRepoInfo() {
13658
13769
  const preferred = getPreferredRemoteRepo();
13659
13770
  if (preferred) return preferred;
13660
13771
  const repoInfo = JSON.parse(
13661
- execSync31("gh repo view --json owner,name", { encoding: "utf8" })
13772
+ execSync33("gh repo view --json owner,name", { encoding: "utf8" })
13662
13773
  );
13663
13774
  return { org: repoInfo.owner.login, repo: repoInfo.name };
13664
13775
  }
13665
13776
  function getCurrentBranch() {
13666
- return execSync31("git rev-parse --abbrev-ref HEAD", {
13777
+ return execSync33("git rev-parse --abbrev-ref HEAD", {
13667
13778
  encoding: "utf8"
13668
13779
  }).trim();
13669
13780
  }
13670
13781
  function viewCurrentPr(fields) {
13671
13782
  const { org, repo } = getRepoInfo();
13672
- const branch = getCurrentBranch();
13783
+ const branch2 = getCurrentBranch();
13673
13784
  return JSON.parse(
13674
- execSync31(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
13785
+ execSync33(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
13675
13786
  encoding: "utf8"
13676
13787
  })
13677
13788
  );
@@ -13775,7 +13886,7 @@ function comment2(path57, line, body, startLine) {
13775
13886
  }
13776
13887
 
13777
13888
  // src/commands/prs/edit.ts
13778
- import { execSync as execSync32 } from "child_process";
13889
+ import { execSync as execSync34 } from "child_process";
13779
13890
 
13780
13891
  // src/commands/prs/buildPrBody.ts
13781
13892
  function jiraBrowseUrl(key) {
@@ -13948,17 +14059,17 @@ function edit(options2) {
13948
14059
  if (options2.title) args.push(`--title ${shellQuote(options2.title)}`);
13949
14060
  args.push(`--body ${shellQuote(newBody)}`);
13950
14061
  try {
13951
- execSync32(args.join(" "), { stdio: "inherit" });
14062
+ execSync34(args.join(" "), { stdio: "inherit" });
13952
14063
  } catch {
13953
14064
  process.exit(1);
13954
14065
  }
13955
14066
  }
13956
14067
 
13957
14068
  // src/commands/prs/fixed.ts
13958
- import { execSync as execSync35 } from "child_process";
14069
+ import { execSync as execSync37 } from "child_process";
13959
14070
 
13960
14071
  // src/commands/prs/resolveCommentWithReply.ts
13961
- import { execSync as execSync34 } from "child_process";
14072
+ import { execSync as execSync36 } from "child_process";
13962
14073
  import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
13963
14074
  import { tmpdir as tmpdir5 } from "os";
13964
14075
  import { join as join46 } from "path";
@@ -13987,9 +14098,9 @@ function deleteCommentsCache(prNumber) {
13987
14098
  }
13988
14099
 
13989
14100
  // src/commands/prs/replyToComment.ts
13990
- import { execSync as execSync33 } from "child_process";
14101
+ import { execSync as execSync35 } from "child_process";
13991
14102
  function replyToComment(org, repo, prNumber, commentId, message) {
13992
- execSync33(
14103
+ execSync35(
13993
14104
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, String.raw`\"`)}" -F in_reply_to=${commentId}`,
13994
14105
  { stdio: ["inherit", "pipe", "inherit"] }
13995
14106
  );
@@ -14001,7 +14112,7 @@ function resolveThread(threadId) {
14001
14112
  const queryFile = join46(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
14002
14113
  writeFileSync30(queryFile, mutation);
14003
14114
  try {
14004
- execSync34(
14115
+ execSync36(
14005
14116
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
14006
14117
  { stdio: ["inherit", "pipe", "inherit"] }
14007
14118
  );
@@ -14053,7 +14164,7 @@ function resolveCommentWithReply(commentId, message) {
14053
14164
  // src/commands/prs/fixed.ts
14054
14165
  function verifySha(sha) {
14055
14166
  try {
14056
- return execSync35(`git rev-parse --verify ${sha}`, {
14167
+ return execSync37(`git rev-parse --verify ${sha}`, {
14057
14168
  encoding: "utf8"
14058
14169
  }).trim();
14059
14170
  } catch {
@@ -14067,7 +14178,7 @@ function fixed(commentId, sha) {
14067
14178
  const { org, repo } = getRepoInfo();
14068
14179
  const repoUrl = `https://github.com/${org}/${repo}`;
14069
14180
  const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
14070
- execSync35("git push", { stdio: "inherit" });
14181
+ execSync37("git push", { stdio: "inherit" });
14071
14182
  resolveCommentWithReply(commentId, message);
14072
14183
  } catch (error) {
14073
14184
  if (isGhNotInstalled(error)) {
@@ -14085,7 +14196,7 @@ import { join as join48 } from "path";
14085
14196
  import { stringify } from "yaml";
14086
14197
 
14087
14198
  // src/commands/prs/fetchThreadIds.ts
14088
- import { execSync as execSync36 } from "child_process";
14199
+ import { execSync as execSync38 } from "child_process";
14089
14200
  import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync31 } from "fs";
14090
14201
  import { tmpdir as tmpdir6 } from "os";
14091
14202
  import { join as join47 } from "path";
@@ -14094,7 +14205,7 @@ function fetchThreadIds(org, repo, prNumber) {
14094
14205
  const queryFile = join47(tmpdir6(), `gh-query-${Date.now()}.graphql`);
14095
14206
  writeFileSync31(queryFile, THREAD_QUERY);
14096
14207
  try {
14097
- const result = execSync36(
14208
+ const result = execSync38(
14098
14209
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
14099
14210
  { encoding: "utf8" }
14100
14211
  );
@@ -14116,9 +14227,9 @@ function fetchThreadIds(org, repo, prNumber) {
14116
14227
  }
14117
14228
 
14118
14229
  // src/commands/prs/listComments/fetchReviewComments.ts
14119
- import { execSync as execSync37 } from "child_process";
14230
+ import { execSync as execSync39 } from "child_process";
14120
14231
  function fetchJson(endpoint) {
14121
- const result = execSync37(`gh api --paginate ${endpoint}`, {
14232
+ const result = execSync39(`gh api --paginate ${endpoint}`, {
14122
14233
  encoding: "utf8"
14123
14234
  });
14124
14235
  if (!result.trim()) return [];
@@ -14257,7 +14368,7 @@ async function listComments() {
14257
14368
  }
14258
14369
 
14259
14370
  // src/commands/prs/prs/index.ts
14260
- import { execSync as execSync38 } from "child_process";
14371
+ import { execSync as execSync40 } from "child_process";
14261
14372
 
14262
14373
  // src/commands/prs/prs/displayPaginated/index.ts
14263
14374
  import enquirer9 from "enquirer";
@@ -14364,7 +14475,7 @@ async function prs(options2) {
14364
14475
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
14365
14476
  try {
14366
14477
  const { org, repo } = getRepoInfo();
14367
- const result = execSync38(
14478
+ const result = execSync40(
14368
14479
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
14369
14480
  { encoding: "utf8" }
14370
14481
  );
@@ -14387,7 +14498,7 @@ async function prs(options2) {
14387
14498
  }
14388
14499
 
14389
14500
  // src/commands/prs/raise.ts
14390
- import { execSync as execSync39 } from "child_process";
14501
+ import { execSync as execSync41 } from "child_process";
14391
14502
 
14392
14503
  // src/commands/prs/buildCreateArgs.ts
14393
14504
  function buildCreateArgs(title, body, options2) {
@@ -14447,7 +14558,7 @@ function raise(options2) {
14447
14558
  `--body ${shellQuote(body)}`
14448
14559
  ] : buildCreateArgs(options2.title, body, options2);
14449
14560
  try {
14450
- execSync39(args.join(" "), { stdio: "inherit" });
14561
+ execSync41(args.join(" "), { stdio: "inherit" });
14451
14562
  } catch {
14452
14563
  process.exit(1);
14453
14564
  }
@@ -14479,7 +14590,7 @@ function reply(commentId, body) {
14479
14590
  }
14480
14591
 
14481
14592
  // src/commands/prs/wontfix.ts
14482
- import { execSync as execSync40 } from "child_process";
14593
+ import { execSync as execSync42 } from "child_process";
14483
14594
  function validateReason(reason) {
14484
14595
  const lowerReason = reason.toLowerCase();
14485
14596
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -14496,7 +14607,7 @@ function validateShaReferences(reason) {
14496
14607
  const invalidShas = [];
14497
14608
  for (const sha of shas) {
14498
14609
  try {
14499
- execSync40(`git cat-file -t ${sha}`, { stdio: "pipe" });
14610
+ execSync42(`git cat-file -t ${sha}`, { stdio: "pipe" });
14500
14611
  } catch {
14501
14612
  invalidShas.push(sha);
14502
14613
  }
@@ -14658,10 +14769,10 @@ import chalk143 from "chalk";
14658
14769
  import Enquirer2 from "enquirer";
14659
14770
 
14660
14771
  // src/commands/ravendb/searchItems.ts
14661
- import { execSync as execSync41 } from "child_process";
14772
+ import { execSync as execSync43 } from "child_process";
14662
14773
  import chalk142 from "chalk";
14663
14774
  function opExec(args) {
14664
- return execSync41(`op ${args}`, {
14775
+ return execSync43(`op ${args}`, {
14665
14776
  encoding: "utf8",
14666
14777
  stdio: ["pipe", "pipe", "pipe"]
14667
14778
  }).trim();
@@ -14813,7 +14924,7 @@ ${errorText}`
14813
14924
  }
14814
14925
 
14815
14926
  // src/commands/ravendb/resolveOpSecret.ts
14816
- import { execSync as execSync42 } from "child_process";
14927
+ import { execSync as execSync44 } from "child_process";
14817
14928
  import chalk147 from "chalk";
14818
14929
  function resolveOpSecret(reference) {
14819
14930
  if (!reference.startsWith("op://")) {
@@ -14821,7 +14932,7 @@ function resolveOpSecret(reference) {
14821
14932
  process.exit(1);
14822
14933
  }
14823
14934
  try {
14824
- return execSync42(`op read "${reference}"`, {
14935
+ return execSync44(`op read "${reference}"`, {
14825
14936
  encoding: "utf8",
14826
14937
  stdio: ["pipe", "pipe", "pipe"]
14827
14938
  }).trim();
@@ -15070,7 +15181,7 @@ Refactor check failed:
15070
15181
  }
15071
15182
 
15072
15183
  // src/commands/refactor/check/getViolations/index.ts
15073
- import { execSync as execSync43 } from "child_process";
15184
+ import { execSync as execSync45 } from "child_process";
15074
15185
  import fs22 from "fs";
15075
15186
  import { minimatch as minimatch6 } from "minimatch";
15076
15187
 
@@ -15120,7 +15231,7 @@ function getGitFiles(options2) {
15120
15231
  }
15121
15232
  const files = /* @__PURE__ */ new Set();
15122
15233
  if (options2.staged || options2.modified) {
15123
- const staged = execSync43("git diff --cached --name-only", {
15234
+ const staged = execSync45("git diff --cached --name-only", {
15124
15235
  encoding: "utf8"
15125
15236
  });
15126
15237
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -15128,7 +15239,7 @@ function getGitFiles(options2) {
15128
15239
  }
15129
15240
  }
15130
15241
  if (options2.unstaged || options2.modified) {
15131
- const unstaged = execSync43("git diff --name-only", { encoding: "utf8" });
15242
+ const unstaged = execSync45("git diff --name-only", { encoding: "utf8" });
15132
15243
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
15133
15244
  files.add(file);
15134
15245
  }
@@ -16772,9 +16883,9 @@ function buildReviewPaths(repoRoot, key) {
16772
16883
  }
16773
16884
 
16774
16885
  // src/commands/review/fetchExistingComments.ts
16775
- import { execSync as execSync44 } from "child_process";
16886
+ import { execSync as execSync46 } from "child_process";
16776
16887
  function fetchRawComments(org, repo, prNumber) {
16777
- const out = execSync44(
16888
+ const out = execSync46(
16778
16889
  `gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
16779
16890
  { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 }
16780
16891
  );
@@ -16805,14 +16916,14 @@ function fetchExistingComments() {
16805
16916
  }
16806
16917
 
16807
16918
  // src/commands/review/gatherContext.ts
16808
- import { execSync as execSync47 } from "child_process";
16919
+ import { execSync as execSync49 } from "child_process";
16809
16920
 
16810
16921
  // src/commands/review/fetchPrDiff.ts
16811
- import { execSync as execSync45 } from "child_process";
16922
+ import { execSync as execSync47 } from "child_process";
16812
16923
  function fetchPrDiff(prNumber, baseSha, headSha) {
16813
16924
  const { org, repo } = getRepoInfo();
16814
16925
  try {
16815
- return execSync45(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
16926
+ return execSync47(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
16816
16927
  encoding: "utf8",
16817
16928
  maxBuffer: 256 * 1024 * 1024,
16818
16929
  stdio: ["ignore", "pipe", "pipe"]
@@ -16827,36 +16938,36 @@ function isDiffTooLarge(error) {
16827
16938
  }
16828
16939
  function fetchDiffViaGit(baseSha, headSha) {
16829
16940
  try {
16830
- execSync45(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
16941
+ execSync47(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
16831
16942
  } catch {
16832
16943
  }
16833
- return execSync45(`git diff ${baseSha}...${headSha}`, {
16944
+ return execSync47(`git diff ${baseSha}...${headSha}`, {
16834
16945
  encoding: "utf8",
16835
16946
  maxBuffer: 256 * 1024 * 1024
16836
16947
  });
16837
16948
  }
16838
16949
 
16839
16950
  // src/commands/review/fetchPrDiffInfo.ts
16840
- import { execSync as execSync46 } from "child_process";
16951
+ import { execSync as execSync48 } from "child_process";
16841
16952
  function getCurrentBranch2() {
16842
- return execSync46("git rev-parse --abbrev-ref HEAD", {
16953
+ return execSync48("git rev-parse --abbrev-ref HEAD", {
16843
16954
  encoding: "utf8"
16844
16955
  }).trim();
16845
16956
  }
16846
16957
  function fetchPrDiffInfo() {
16847
16958
  const { org, repo } = getRepoInfo();
16848
- const branch = getCurrentBranch2();
16959
+ const branch2 = getCurrentBranch2();
16849
16960
  const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
16850
16961
  let raw;
16851
16962
  try {
16852
- raw = execSync46(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
16963
+ raw = execSync48(`gh pr view ${branch2} --json ${fields} -R ${org}/${repo}`, {
16853
16964
  encoding: "utf8",
16854
16965
  stdio: ["ignore", "pipe", "pipe"]
16855
16966
  });
16856
16967
  } catch (error) {
16857
16968
  if (error instanceof Error && error.message.includes("no pull requests")) {
16858
16969
  console.error(
16859
- `Error: No open pull request found for branch \`${branch}\`. Open a PR for this branch before running \`assist review\`.`
16970
+ `Error: No open pull request found for branch \`${branch2}\`. Open a PR for this branch before running \`assist review\`.`
16860
16971
  );
16861
16972
  process.exit(1);
16862
16973
  }
@@ -16873,7 +16984,7 @@ function fetchPrDiffInfo() {
16873
16984
  }
16874
16985
  function fetchPrChangedFiles(prNumber) {
16875
16986
  const { org, repo } = getRepoInfo();
16876
- const out = execSync46(
16987
+ const out = execSync48(
16877
16988
  `gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
16878
16989
  {
16879
16990
  encoding: "utf8",
@@ -16885,18 +16996,18 @@ function fetchPrChangedFiles(prNumber) {
16885
16996
 
16886
16997
  // src/commands/review/gatherContext.ts
16887
16998
  function gatherContext() {
16888
- const branch = execSync47("git rev-parse --abbrev-ref HEAD", {
16999
+ const branch2 = execSync49("git rev-parse --abbrev-ref HEAD", {
16889
17000
  encoding: "utf8"
16890
17001
  }).trim();
16891
- const sha = execSync47("git rev-parse HEAD", { encoding: "utf8" }).trim();
16892
- const shortSha = execSync47("git rev-parse --short=7 HEAD", {
17002
+ const sha = execSync49("git rev-parse HEAD", { encoding: "utf8" }).trim();
17003
+ const shortSha = execSync49("git rev-parse --short=7 HEAD", {
16893
17004
  encoding: "utf8"
16894
17005
  }).trim();
16895
17006
  const prInfo = fetchPrDiffInfo();
16896
17007
  const changedFiles = fetchPrChangedFiles(prInfo.prNumber);
16897
17008
  const diff2 = fetchPrDiff(prInfo.prNumber, prInfo.baseSha, prInfo.headSha);
16898
17009
  return {
16899
- branch,
17010
+ branch: branch2,
16900
17011
  sha,
16901
17012
  shortSha,
16902
17013
  prNumber: prInfo.prNumber,
@@ -19437,7 +19548,7 @@ import { mkdirSync as mkdirSync19 } from "fs";
19437
19548
  import { join as join55 } from "path";
19438
19549
 
19439
19550
  // src/commands/voice/checkLockFile.ts
19440
- import { execSync as execSync48 } from "child_process";
19551
+ import { execSync as execSync50 } from "child_process";
19441
19552
  import { existsSync as existsSync46, mkdirSync as mkdirSync18, readFileSync as readFileSync40, writeFileSync as writeFileSync36 } from "fs";
19442
19553
  import { join as join54 } from "path";
19443
19554
  function isProcessAlive2(pid) {
@@ -19466,7 +19577,7 @@ function bootstrapVenv() {
19466
19577
  if (existsSync46(getVenvPython())) return;
19467
19578
  console.log("Setting up Python environment...");
19468
19579
  const pythonDir = getPythonDir();
19469
- execSync48(
19580
+ execSync50(
19470
19581
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
19471
19582
  {
19472
19583
  stdio: "inherit",
@@ -19943,11 +20054,11 @@ function resolveParams(params, cliArgs) {
19943
20054
  }
19944
20055
 
19945
20056
  // src/commands/run/runPreCommands.ts
19946
- import { execSync as execSync49 } from "child_process";
20057
+ import { execSync as execSync51 } from "child_process";
19947
20058
  function runPreCommands(pre, cwd) {
19948
20059
  for (const cmd of pre) {
19949
20060
  try {
19950
- execSync49(cmd, { stdio: "inherit", cwd });
20061
+ execSync51(cmd, { stdio: "inherit", cwd });
19951
20062
  } catch (error) {
19952
20063
  const code = error && typeof error === "object" && "status" in error ? error.status : 1;
19953
20064
  process.exit(code);
@@ -20231,7 +20342,7 @@ function registerRun(program2) {
20231
20342
  }
20232
20343
 
20233
20344
  // src/commands/screenshot/index.ts
20234
- import { execSync as execSync50 } from "child_process";
20345
+ import { execSync as execSync52 } from "child_process";
20235
20346
  import { existsSync as existsSync51, mkdirSync as mkdirSync22, unlinkSync as unlinkSync19, writeFileSync as writeFileSync39 } from "fs";
20236
20347
  import { tmpdir as tmpdir7 } from "os";
20237
20348
  import { join as join61, resolve as resolve15 } from "path";
@@ -20374,7 +20485,7 @@ function runPowerShellScript(processName, outputPath) {
20374
20485
  const scriptPath = join61(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
20375
20486
  writeFileSync39(scriptPath, captureWindowPs1, "utf8");
20376
20487
  try {
20377
- execSync50(
20488
+ execSync52(
20378
20489
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
20379
20490
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf8" }
20380
20491
  );
@@ -23314,7 +23425,7 @@ function syncCommands(claudeDir, targetBase) {
23314
23425
  }
23315
23426
 
23316
23427
  // src/commands/update.ts
23317
- import { execSync as execSync51 } from "child_process";
23428
+ import { execSync as execSync53 } from "child_process";
23318
23429
  import * as path56 from "path";
23319
23430
 
23320
23431
  // src/commands/restartDaemonAfterUpdate.ts
@@ -23338,7 +23449,7 @@ function isGlobalNpmInstall(dir) {
23338
23449
  if (resolved.split(path56.sep).includes("node_modules")) {
23339
23450
  return true;
23340
23451
  }
23341
- const globalPrefix = execSync51("npm prefix -g", { stdio: "pipe" }).toString().trim();
23452
+ const globalPrefix = execSync53("npm prefix -g", { stdio: "pipe" }).toString().trim();
23342
23453
  return resolved.toLowerCase().startsWith(path56.resolve(globalPrefix).toLowerCase());
23343
23454
  } catch {
23344
23455
  return false;
@@ -23349,18 +23460,18 @@ async function update2() {
23349
23460
  console.log(`Assist is installed at: ${installDir}`);
23350
23461
  if (isGitRepo(installDir)) {
23351
23462
  console.log("Detected git repo installation, pulling latest...");
23352
- execSync51("git pull", { cwd: installDir, stdio: "inherit" });
23463
+ execSync53("git pull", { cwd: installDir, stdio: "inherit" });
23353
23464
  console.log("Installing dependencies...");
23354
- execSync51("npm i", { cwd: installDir, stdio: "inherit" });
23465
+ execSync53("npm i", { cwd: installDir, stdio: "inherit" });
23355
23466
  console.log("Building...");
23356
- execSync51("npm run build", { cwd: installDir, stdio: "inherit" });
23467
+ execSync53("npm run build", { cwd: installDir, stdio: "inherit" });
23357
23468
  console.log("Syncing commands...");
23358
- execSync51("assist sync", { stdio: "inherit" });
23469
+ execSync53("assist sync", { stdio: "inherit" });
23359
23470
  } else if (isGlobalNpmInstall(installDir)) {
23360
23471
  console.log("Detected global npm installation, updating...");
23361
- execSync51("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
23472
+ execSync53("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
23362
23473
  console.log("Syncing commands...");
23363
- execSync51("assist sync", { stdio: "inherit" });
23474
+ execSync53("assist sync", { stdio: "inherit" });
23364
23475
  } else {
23365
23476
  console.error(
23366
23477
  "Could not determine installation method. Expected a git repo or global npm install."
@@ -23402,6 +23513,7 @@ registerMermaid(program);
23402
23513
  registerPrs(program);
23403
23514
  registerRoam(program);
23404
23515
  registerBacklog(program);
23516
+ registerBranch(program);
23405
23517
  registerList(program);
23406
23518
  registerVerify(program);
23407
23519
  registerRefactor(program);