@staff0rd/assist 0.287.0 → 0.288.1

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 (2) hide show
  1. package/dist/index.js +254 -154
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.287.0",
9
+ version: "0.288.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -3477,7 +3477,7 @@ function findBacklogUp(startDir) {
3477
3477
  }
3478
3478
 
3479
3479
  // src/commands/backlog/getCurrentOrigin.ts
3480
- import { execSync as execSync18 } from "child_process";
3480
+ import { execFileSync } from "child_process";
3481
3481
  function stripLeadingSlashes(path54) {
3482
3482
  return path54.replace(/^\/+/, "");
3483
3483
  }
@@ -3498,11 +3498,14 @@ function normalizeOrigin(raw) {
3498
3498
  return trimmed.toLowerCase();
3499
3499
  }
3500
3500
  function tryGit(cwd, args) {
3501
+ const windows = /^[A-Za-z]:[\\/]/.test(cwd);
3502
+ const file = windows ? "git.exe" : "git";
3503
+ const argv = windows ? ["-C", cwd, ...args] : args;
3501
3504
  try {
3502
- const out = execSync18(`git ${args}`, {
3503
- cwd,
3505
+ const out = execFileSync(file, argv, {
3504
3506
  encoding: "utf-8",
3505
- stdio: ["pipe", "pipe", "pipe"]
3507
+ stdio: ["pipe", "pipe", "pipe"],
3508
+ ...windows ? {} : { cwd }
3506
3509
  }).trim();
3507
3510
  return out || null;
3508
3511
  } catch {
@@ -3510,18 +3513,18 @@ function tryGit(cwd, args) {
3510
3513
  }
3511
3514
  }
3512
3515
  function firstRemoteUrl(cwd) {
3513
- const remotes = tryGit(cwd, "remote");
3516
+ const remotes = tryGit(cwd, ["remote"]);
3514
3517
  if (!remotes) return null;
3515
3518
  for (const remote of remotes.split("\n").map((r) => r.trim()).filter(Boolean)) {
3516
- const url = tryGit(cwd, `remote get-url ${remote}`);
3519
+ const url = tryGit(cwd, ["remote", "get-url", remote]);
3517
3520
  if (url) return url;
3518
3521
  }
3519
3522
  return null;
3520
3523
  }
3521
3524
  function getCurrentOrigin(cwd) {
3522
- const url = tryGit(cwd, "remote get-url origin") ?? firstRemoteUrl(cwd);
3525
+ const url = tryGit(cwd, ["remote", "get-url", "origin"]) ?? firstRemoteUrl(cwd);
3523
3526
  if (url) return normalizeOrigin(url);
3524
- const root = tryGit(cwd, "rev-parse --show-toplevel");
3527
+ const root = tryGit(cwd, ["rev-parse", "--show-toplevel"]);
3525
3528
  return `local:${root ?? cwd}`;
3526
3529
  }
3527
3530
 
@@ -4369,7 +4372,7 @@ function printComments(item) {
4369
4372
  import { WebSocketServer } from "ws";
4370
4373
 
4371
4374
  // src/shared/getInstallDir.ts
4372
- import { execSync as execSync19 } from "child_process";
4375
+ import { execSync as execSync18 } from "child_process";
4373
4376
  import { dirname as dirname15, resolve as resolve6 } from "path";
4374
4377
  import { fileURLToPath as fileURLToPath3 } from "url";
4375
4378
  var __filename2 = fileURLToPath3(import.meta.url);
@@ -4379,7 +4382,7 @@ function getInstallDir() {
4379
4382
  }
4380
4383
  function isGitRepo(dir) {
4381
4384
  try {
4382
- const result = execSync19("git rev-parse --show-toplevel", {
4385
+ const result = execSync18("git rev-parse --show-toplevel", {
4383
4386
  cwd: dir,
4384
4387
  stdio: "pipe"
4385
4388
  }).toString().trim();
@@ -4396,11 +4399,11 @@ import {
4396
4399
  import chalk43 from "chalk";
4397
4400
 
4398
4401
  // src/lib/openBrowser.ts
4399
- import { execSync as execSync20 } from "child_process";
4402
+ import { execSync as execSync19 } from "child_process";
4400
4403
  function tryExec(commands) {
4401
4404
  for (const cmd of commands) {
4402
4405
  try {
4403
- execSync20(cmd, { stdio: "ignore" });
4406
+ execSync19(cmd, { stdio: "ignore" });
4404
4407
  return true;
4405
4408
  } catch {
4406
4409
  }
@@ -4932,7 +4935,7 @@ function getHtml() {
4932
4935
  }
4933
4936
 
4934
4937
  // src/commands/prs/getPreferredRemoteRepo.ts
4935
- import { execSync as execSync21 } from "child_process";
4938
+ import { execSync as execSync20 } from "child_process";
4936
4939
  var GITHUB_URL_PATTERN = /(?:git@github\.com:|https:\/\/github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?\/?$/;
4937
4940
  function parseGitHubUrl(url) {
4938
4941
  const match = url.match(GITHUB_URL_PATTERN);
@@ -4941,7 +4944,7 @@ function parseGitHubUrl(url) {
4941
4944
  }
4942
4945
  function tryGetRemoteUrl(remote, cwd) {
4943
4946
  try {
4944
- return execSync21(`git remote get-url ${remote}`, {
4947
+ return execSync20(`git remote get-url ${remote}`, {
4945
4948
  encoding: "utf-8",
4946
4949
  stdio: ["pipe", "pipe", "pipe"],
4947
4950
  cwd
@@ -4952,7 +4955,7 @@ function tryGetRemoteUrl(remote, cwd) {
4952
4955
  }
4953
4956
  function getCurrentBranchRemote(cwd) {
4954
4957
  try {
4955
- const ref = execSync21(
4958
+ const ref = execSync20(
4956
4959
  "git rev-parse --abbrev-ref --symbolic-full-name @{u}",
4957
4960
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], cwd }
4958
4961
  ).trim();
@@ -4964,7 +4967,7 @@ function getCurrentBranchRemote(cwd) {
4964
4967
  }
4965
4968
  function listRemotes(cwd) {
4966
4969
  try {
4967
- return execSync21("git remote", {
4970
+ return execSync20("git remote", {
4968
4971
  encoding: "utf-8",
4969
4972
  stdio: ["pipe", "pipe", "pipe"],
4970
4973
  cwd
@@ -7888,7 +7891,7 @@ import { homedir as homedir9 } from "os";
7888
7891
  import { join as join22 } from "path";
7889
7892
 
7890
7893
  // src/shared/checkCliAvailable.ts
7891
- import { execSync as execSync22 } from "child_process";
7894
+ import { execSync as execSync21 } from "child_process";
7892
7895
  function checkCliAvailable(cli) {
7893
7896
  const binary = cli.split(/\s+/)[0];
7894
7897
  const opts = {
@@ -7896,11 +7899,11 @@ function checkCliAvailable(cli) {
7896
7899
  stdio: ["ignore", "pipe", "pipe"]
7897
7900
  };
7898
7901
  try {
7899
- execSync22(`command -v ${binary}`, opts);
7902
+ execSync21(`command -v ${binary}`, opts);
7900
7903
  return true;
7901
7904
  } catch {
7902
7905
  try {
7903
- execSync22(`where ${binary}`, opts);
7906
+ execSync21(`where ${binary}`, opts);
7904
7907
  return true;
7905
7908
  } catch {
7906
7909
  return false;
@@ -9021,7 +9024,7 @@ function registerDeploy(program2) {
9021
9024
  }
9022
9025
 
9023
9026
  // src/commands/devlog/list/index.ts
9024
- import { execFileSync } from "child_process";
9027
+ import { execFileSync as execFileSync2 } from "child_process";
9025
9028
  import { basename as basename4 } from "path";
9026
9029
 
9027
9030
  // src/commands/devlog/loadBlogSkipDays.ts
@@ -9036,7 +9039,7 @@ function loadBlogSkipDays(repoName) {
9036
9039
  }
9037
9040
 
9038
9041
  // src/commands/devlog/shared.ts
9039
- import { execSync as execSync23 } from "child_process";
9042
+ import { execSync as execSync22 } from "child_process";
9040
9043
  import chalk92 from "chalk";
9041
9044
 
9042
9045
  // src/shared/getRepoName.ts
@@ -9128,7 +9131,7 @@ function loadAllDevlogLatestDates() {
9128
9131
  // src/commands/devlog/shared.ts
9129
9132
  function getCommitFiles(hash) {
9130
9133
  try {
9131
- const output = execSync23(`git show --name-only --format="" ${hash}`, {
9134
+ const output = execSync22(`git show --name-only --format="" ${hash}`, {
9132
9135
  encoding: "utf-8"
9133
9136
  });
9134
9137
  return output.trim().split("\n").filter(Boolean);
@@ -9201,7 +9204,7 @@ function list3(options2) {
9201
9204
  if (options2.reverse) args.push("--reverse");
9202
9205
  else args.push("-n", "500");
9203
9206
  args.push("--pretty=format:%ad|%h|%s", "--date=short");
9204
- const output = execFileSync("git", args, { encoding: "utf-8" });
9207
+ const output = execFileSync2("git", args, { encoding: "utf-8" });
9205
9208
  const commitsByDate = parseGitLogCommits(output, ignore2);
9206
9209
  let dateCount = 0;
9207
9210
  let isFirst = true;
@@ -9224,11 +9227,11 @@ function list3(options2) {
9224
9227
  }
9225
9228
 
9226
9229
  // src/commands/devlog/getLastVersionInfo.ts
9227
- import { execFileSync as execFileSync2, execSync as execSync24 } from "child_process";
9230
+ import { execFileSync as execFileSync3, execSync as execSync23 } from "child_process";
9228
9231
  import semver from "semver";
9229
9232
  function getVersionAtCommit(hash) {
9230
9233
  try {
9231
- const content = execSync24(`git show ${hash}:package.json`, {
9234
+ const content = execSync23(`git show ${hash}:package.json`, {
9232
9235
  encoding: "utf-8"
9233
9236
  });
9234
9237
  const pkg = JSON.parse(content);
@@ -9243,7 +9246,7 @@ function stripToMinor(version2) {
9243
9246
  }
9244
9247
  function getLastVersionInfoFromGit() {
9245
9248
  try {
9246
- const output = execFileSync2(
9249
+ const output = execFileSync3(
9247
9250
  "git",
9248
9251
  ["log", "-1", "--pretty=format:%ad|%h", "--date=short"],
9249
9252
  {
@@ -9288,7 +9291,7 @@ function bumpVersion(version2, type) {
9288
9291
  }
9289
9292
 
9290
9293
  // src/commands/devlog/next/displayNextEntry/index.ts
9291
- import { execFileSync as execFileSync3 } from "child_process";
9294
+ import { execFileSync as execFileSync4 } from "child_process";
9292
9295
  import chalk95 from "chalk";
9293
9296
 
9294
9297
  // src/commands/devlog/next/displayNextEntry/displayVersion.ts
@@ -9322,7 +9325,7 @@ function findTargetDate(commitsByDate, skipDays) {
9322
9325
  return Array.from(commitsByDate.keys()).filter((d) => !skipDays.has(d)).sort()[0];
9323
9326
  }
9324
9327
  function fetchCommitsByDate(ignore2, lastDate) {
9325
- const output = execFileSync3(
9328
+ const output = execFileSync4(
9326
9329
  "git",
9327
9330
  ["log", "--pretty=format:%ad|%h|%s", "--date=short", "-n", "500"],
9328
9331
  { encoding: "utf-8" }
@@ -9401,7 +9404,7 @@ function next2(options2) {
9401
9404
  }
9402
9405
 
9403
9406
  // src/commands/devlog/repos/index.ts
9404
- import { execSync as execSync25 } from "child_process";
9407
+ import { execSync as execSync24 } from "child_process";
9405
9408
 
9406
9409
  // src/commands/devlog/repos/printReposTable.ts
9407
9410
  import chalk96 from "chalk";
@@ -9436,7 +9439,7 @@ function getStatus(lastPush, lastDevlog) {
9436
9439
  return lastDevlog < lastPush ? "outdated" : "ok";
9437
9440
  }
9438
9441
  function fetchRepos(days, all) {
9439
- const json = execSync25(
9442
+ const json = execSync24(
9440
9443
  "gh repo list staff0rd --json name,pushedAt,isArchived --limit 200",
9441
9444
  { encoding: "utf-8" }
9442
9445
  );
@@ -9796,7 +9799,7 @@ async function deps(csprojPath, options2) {
9796
9799
  }
9797
9800
 
9798
9801
  // src/commands/dotnet/getChangedCsFiles.ts
9799
- import { execSync as execSync26 } from "child_process";
9802
+ import { execSync as execSync25 } from "child_process";
9800
9803
  var SCOPE_ALL = "all";
9801
9804
  var SCOPE_BASE = "base:";
9802
9805
  var SCOPE_COMMIT = "commit:";
@@ -9820,7 +9823,7 @@ function getChangedCsFiles(scope) {
9820
9823
  } else {
9821
9824
  cmd = "git diff --name-only HEAD";
9822
9825
  }
9823
- const output = execSync26(cmd, { encoding: "utf-8" }).trim();
9826
+ const output = execSync25(cmd, { encoding: "utf-8" }).trim();
9824
9827
  if (output === "") return [];
9825
9828
  return output.split("\n").filter((f) => f.toLowerCase().endsWith(".cs"));
9826
9829
  }
@@ -10018,14 +10021,14 @@ function parseInspectReport(json) {
10018
10021
  }
10019
10022
 
10020
10023
  // src/commands/dotnet/runInspectCode.ts
10021
- import { execSync as execSync27 } from "child_process";
10024
+ import { execSync as execSync26 } from "child_process";
10022
10025
  import { existsSync as existsSync30, readFileSync as readFileSync24, unlinkSync as unlinkSync7 } from "fs";
10023
10026
  import { tmpdir as tmpdir3 } from "os";
10024
10027
  import path25 from "path";
10025
10028
  import chalk106 from "chalk";
10026
10029
  function assertJbInstalled() {
10027
10030
  try {
10028
- execSync27("jb inspectcode --version", { stdio: "pipe" });
10031
+ execSync26("jb inspectcode --version", { stdio: "pipe" });
10029
10032
  } catch {
10030
10033
  console.error(chalk106.red("jb is not installed. Install with:"));
10031
10034
  console.error(
@@ -10039,7 +10042,7 @@ function runInspectCode(slnPath, include, swea) {
10039
10042
  const includeFlag = include ? ` --include="${include}"` : "";
10040
10043
  const sweaFlag = swea ? " --swea" : "";
10041
10044
  try {
10042
- execSync27(
10045
+ execSync26(
10043
10046
  `jb inspectcode "${slnPath}" -o="${reportPath}"${includeFlag}${sweaFlag} --verbosity=OFF`,
10044
10047
  { stdio: "pipe" }
10045
10048
  );
@@ -10060,7 +10063,7 @@ function runInspectCode(slnPath, include, swea) {
10060
10063
  }
10061
10064
 
10062
10065
  // src/commands/dotnet/runRoslynInspect.ts
10063
- import { execSync as execSync28 } from "child_process";
10066
+ import { execSync as execSync27 } from "child_process";
10064
10067
  import chalk107 from "chalk";
10065
10068
  function resolveMsbuildPath() {
10066
10069
  const { run: run4 } = loadConfig();
@@ -10071,7 +10074,7 @@ function resolveMsbuildPath() {
10071
10074
  function assertMsbuildInstalled() {
10072
10075
  const msbuild = resolveMsbuildPath();
10073
10076
  try {
10074
- execSync28(`"${msbuild}" -version`, { stdio: "pipe" });
10077
+ execSync27(`"${msbuild}" -version`, { stdio: "pipe" });
10075
10078
  } catch {
10076
10079
  console.error(chalk107.red(`msbuild not found at: ${msbuild}`));
10077
10080
  console.error(
@@ -10097,7 +10100,7 @@ function runRoslynInspect(slnPath) {
10097
10100
  const msbuild = resolveMsbuildPath();
10098
10101
  let output;
10099
10102
  try {
10100
- output = execSync28(
10103
+ output = execSync27(
10101
10104
  `"${msbuild}" "${slnPath}" -t:Build -v:minimal -maxcpucount -p:EnforceCodeStyleInBuild=true -p:RunAnalyzersDuringBuild=true 2>&1`,
10102
10105
  { encoding: "utf-8", stdio: "pipe", maxBuffer: 50 * 1024 * 1024 }
10103
10106
  );
@@ -10469,7 +10472,7 @@ function resolveLoadOptions(options2) {
10469
10472
  }
10470
10473
 
10471
10474
  // src/commands/handover/summarise.ts
10472
- import { execFileSync as execFileSync4 } from "child_process";
10475
+ import { execFileSync as execFileSync5 } from "child_process";
10473
10476
 
10474
10477
  // src/commands/sessions/summarise/iterateUserEntries.ts
10475
10478
  import * as fs16 from "fs";
@@ -10534,7 +10537,7 @@ function summarise(jsonlPath2) {
10534
10537
  const prompt = `${PROMPT_TEMPLATE}
10535
10538
  ${payload}`;
10536
10539
  try {
10537
- const output = execFileSync4("claude", ["-p", "--model", "haiku", prompt], {
10540
+ const output = execFileSync5("claude", ["-p", "--model", "haiku", prompt], {
10538
10541
  encoding: "utf8",
10539
10542
  timeout: 3e4,
10540
10543
  stdio: ["ignore", "pipe", "ignore"],
@@ -10675,12 +10678,12 @@ function adfToText(doc) {
10675
10678
  }
10676
10679
 
10677
10680
  // src/commands/jira/fetchIssue.ts
10678
- import { execSync as execSync29 } from "child_process";
10681
+ import { execSync as execSync28 } from "child_process";
10679
10682
  import chalk111 from "chalk";
10680
10683
  function fetchIssue(issueKey, fields) {
10681
10684
  let result;
10682
10685
  try {
10683
- result = execSync29(
10686
+ result = execSync28(
10684
10687
  `acli jira workitem view ${issueKey} -f ${fields} --json`,
10685
10688
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
10686
10689
  );
@@ -10726,7 +10729,7 @@ function acceptanceCriteria(issueKey) {
10726
10729
  }
10727
10730
 
10728
10731
  // src/commands/jira/jiraAuth.ts
10729
- import { execSync as execSync30 } from "child_process";
10732
+ import { execSync as execSync29 } from "child_process";
10730
10733
 
10731
10734
  // src/shared/loadJson.ts
10732
10735
  import { existsSync as existsSync33, mkdirSync as mkdirSync11, readFileSync as readFileSync27, writeFileSync as writeFileSync21 } from "fs";
@@ -10790,7 +10793,7 @@ async function jiraAuth() {
10790
10793
  console.error("All fields are required.");
10791
10794
  process.exit(1);
10792
10795
  }
10793
- execSync30(`acli jira auth login --site ${site} --email "${email}" --token`, {
10796
+ execSync29(`acli jira auth login --site ${site} --email "${email}" --token`, {
10794
10797
  encoding: "utf-8",
10795
10798
  input: token,
10796
10799
  stdio: ["pipe", "inherit", "inherit"]
@@ -10841,12 +10844,12 @@ function registerJira(program2) {
10841
10844
  }
10842
10845
 
10843
10846
  // src/commands/reviewComments.ts
10844
- import { execFileSync as execFileSync5 } from "child_process";
10847
+ import { execFileSync as execFileSync6 } from "child_process";
10845
10848
  import chalk114 from "chalk";
10846
10849
  async function reviewComments(number) {
10847
10850
  if (number) {
10848
10851
  try {
10849
- execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
10852
+ execFileSync6("gh", ["pr", "checkout", number], { stdio: "inherit" });
10850
10853
  } catch {
10851
10854
  console.error(chalk114.red(`gh pr checkout ${number} failed; aborting.`));
10852
10855
  process.exit(1);
@@ -11085,7 +11088,7 @@ function registerPrompts(program2) {
11085
11088
  }
11086
11089
 
11087
11090
  // src/commands/prs/shared.ts
11088
- import { execSync as execSync31 } from "child_process";
11091
+ import { execSync as execSync30 } from "child_process";
11089
11092
  function isGhNotInstalled(error) {
11090
11093
  if (error instanceof Error) {
11091
11094
  const msg = error.message.toLowerCase();
@@ -11103,12 +11106,12 @@ function getRepoInfo() {
11103
11106
  const preferred = getPreferredRemoteRepo();
11104
11107
  if (preferred) return preferred;
11105
11108
  const repoInfo = JSON.parse(
11106
- execSync31("gh repo view --json owner,name", { encoding: "utf-8" })
11109
+ execSync30("gh repo view --json owner,name", { encoding: "utf-8" })
11107
11110
  );
11108
11111
  return { org: repoInfo.owner.login, repo: repoInfo.name };
11109
11112
  }
11110
11113
  function getCurrentBranch() {
11111
- return execSync31("git rev-parse --abbrev-ref HEAD", {
11114
+ return execSync30("git rev-parse --abbrev-ref HEAD", {
11112
11115
  encoding: "utf-8"
11113
11116
  }).trim();
11114
11117
  }
@@ -11116,7 +11119,7 @@ function viewCurrentPr(fields) {
11116
11119
  const { org, repo } = getRepoInfo();
11117
11120
  const branch = getCurrentBranch();
11118
11121
  return JSON.parse(
11119
- execSync31(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
11122
+ execSync30(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
11120
11123
  encoding: "utf-8"
11121
11124
  })
11122
11125
  );
@@ -11220,7 +11223,7 @@ function comment2(path54, line, body, startLine) {
11220
11223
  }
11221
11224
 
11222
11225
  // src/commands/prs/edit.ts
11223
- import { execSync as execSync32 } from "child_process";
11226
+ import { execSync as execSync31 } from "child_process";
11224
11227
 
11225
11228
  // src/commands/prs/buildPrBody.ts
11226
11229
  function jiraBrowseUrl(key) {
@@ -11346,17 +11349,17 @@ function edit(options2) {
11346
11349
  if (options2.title) args.push(`--title ${shellQuote(options2.title)}`);
11347
11350
  args.push(`--body ${shellQuote(newBody)}`);
11348
11351
  try {
11349
- execSync32(args.join(" "), { stdio: "inherit" });
11352
+ execSync31(args.join(" "), { stdio: "inherit" });
11350
11353
  } catch (_error) {
11351
11354
  process.exit(1);
11352
11355
  }
11353
11356
  }
11354
11357
 
11355
11358
  // src/commands/prs/fixed.ts
11356
- import { execSync as execSync34 } from "child_process";
11359
+ import { execSync as execSync33 } from "child_process";
11357
11360
 
11358
11361
  // src/commands/prs/resolveCommentWithReply.ts
11359
- import { execSync as execSync33 } from "child_process";
11362
+ import { execSync as execSync32 } from "child_process";
11360
11363
  import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync23 } from "fs";
11361
11364
  import { tmpdir as tmpdir5 } from "os";
11362
11365
  import { join as join34 } from "path";
@@ -11386,7 +11389,7 @@ function deleteCommentsCache(prNumber) {
11386
11389
 
11387
11390
  // src/commands/prs/resolveCommentWithReply.ts
11388
11391
  function replyToComment(org, repo, prNumber, commentId, message) {
11389
- execSync33(
11392
+ execSync32(
11390
11393
  `gh api repos/${org}/${repo}/pulls/${prNumber}/comments -f body="${message.replace(/"/g, '\\"')}" -F in_reply_to=${commentId}`,
11391
11394
  { stdio: ["inherit", "pipe", "inherit"] }
11392
11395
  );
@@ -11396,7 +11399,7 @@ function resolveThread(threadId) {
11396
11399
  const queryFile = join34(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
11397
11400
  writeFileSync23(queryFile, mutation);
11398
11401
  try {
11399
- execSync33(
11402
+ execSync32(
11400
11403
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
11401
11404
  { stdio: ["inherit", "pipe", "inherit"] }
11402
11405
  );
@@ -11448,7 +11451,7 @@ function resolveCommentWithReply(commentId, message) {
11448
11451
  // src/commands/prs/fixed.ts
11449
11452
  function verifySha(sha) {
11450
11453
  try {
11451
- return execSync34(`git rev-parse --verify ${sha}`, {
11454
+ return execSync33(`git rev-parse --verify ${sha}`, {
11452
11455
  encoding: "utf-8"
11453
11456
  }).trim();
11454
11457
  } catch {
@@ -11462,7 +11465,7 @@ function fixed(commentId, sha) {
11462
11465
  const { org, repo } = getRepoInfo();
11463
11466
  const repoUrl = `https://github.com/${org}/${repo}`;
11464
11467
  const message = `Fixed in [${fullSha}](${repoUrl}/commit/${fullSha})`;
11465
- execSync34("git push", { stdio: "inherit" });
11468
+ execSync33("git push", { stdio: "inherit" });
11466
11469
  resolveCommentWithReply(commentId, message);
11467
11470
  } catch (error) {
11468
11471
  if (isGhNotInstalled(error)) {
@@ -11480,7 +11483,7 @@ import { join as join36 } from "path";
11480
11483
  import { stringify } from "yaml";
11481
11484
 
11482
11485
  // src/commands/prs/fetchThreadIds.ts
11483
- import { execSync as execSync35 } from "child_process";
11486
+ import { execSync as execSync34 } from "child_process";
11484
11487
  import { unlinkSync as unlinkSync11, writeFileSync as writeFileSync24 } from "fs";
11485
11488
  import { tmpdir as tmpdir6 } from "os";
11486
11489
  import { join as join35 } from "path";
@@ -11489,7 +11492,7 @@ function fetchThreadIds(org, repo, prNumber) {
11489
11492
  const queryFile = join35(tmpdir6(), `gh-query-${Date.now()}.graphql`);
11490
11493
  writeFileSync24(queryFile, THREAD_QUERY);
11491
11494
  try {
11492
- const result = execSync35(
11495
+ const result = execSync34(
11493
11496
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
11494
11497
  { encoding: "utf-8" }
11495
11498
  );
@@ -11511,9 +11514,9 @@ function fetchThreadIds(org, repo, prNumber) {
11511
11514
  }
11512
11515
 
11513
11516
  // src/commands/prs/listComments/fetchReviewComments.ts
11514
- import { execSync as execSync36 } from "child_process";
11517
+ import { execSync as execSync35 } from "child_process";
11515
11518
  function fetchJson(endpoint) {
11516
- const result = execSync36(`gh api --paginate ${endpoint}`, {
11519
+ const result = execSync35(`gh api --paginate ${endpoint}`, {
11517
11520
  encoding: "utf-8"
11518
11521
  });
11519
11522
  if (!result.trim()) return [];
@@ -11652,7 +11655,7 @@ async function listComments() {
11652
11655
  }
11653
11656
 
11654
11657
  // src/commands/prs/prs/index.ts
11655
- import { execSync as execSync37 } from "child_process";
11658
+ import { execSync as execSync36 } from "child_process";
11656
11659
 
11657
11660
  // src/commands/prs/prs/displayPaginated/index.ts
11658
11661
  import enquirer9 from "enquirer";
@@ -11759,7 +11762,7 @@ async function prs(options2) {
11759
11762
  const state = options2.open ? "open" : options2.closed ? "closed" : "all";
11760
11763
  try {
11761
11764
  const { org, repo } = getRepoInfo();
11762
- const result = execSync37(
11765
+ const result = execSync36(
11763
11766
  `gh pr list --state ${state} --json number,title,url,author,createdAt,mergedAt,closedAt,state,changedFiles --limit 100 -R ${org}/${repo}`,
11764
11767
  { encoding: "utf-8" }
11765
11768
  );
@@ -11782,7 +11785,7 @@ async function prs(options2) {
11782
11785
  }
11783
11786
 
11784
11787
  // src/commands/prs/raise.ts
11785
- import { execSync as execSync38 } from "child_process";
11788
+ import { execSync as execSync37 } from "child_process";
11786
11789
 
11787
11790
  // src/commands/prs/buildCreateArgs.ts
11788
11791
  function buildCreateArgs(title, body, options2) {
@@ -11842,14 +11845,14 @@ function raise(options2) {
11842
11845
  `--body ${shellQuote(body)}`
11843
11846
  ] : buildCreateArgs(options2.title, body, options2);
11844
11847
  try {
11845
- execSync38(args.join(" "), { stdio: "inherit" });
11848
+ execSync37(args.join(" "), { stdio: "inherit" });
11846
11849
  } catch (_error) {
11847
11850
  process.exit(1);
11848
11851
  }
11849
11852
  }
11850
11853
 
11851
11854
  // src/commands/prs/wontfix.ts
11852
- import { execSync as execSync39 } from "child_process";
11855
+ import { execSync as execSync38 } from "child_process";
11853
11856
  function validateReason(reason) {
11854
11857
  const lowerReason = reason.toLowerCase();
11855
11858
  if (lowerReason.includes("claude") || lowerReason.includes("opus")) {
@@ -11866,7 +11869,7 @@ function validateShaReferences(reason) {
11866
11869
  const invalidShas = [];
11867
11870
  for (const sha of shas) {
11868
11871
  try {
11869
- execSync39(`git cat-file -t ${sha}`, { stdio: "pipe" });
11872
+ execSync38(`git cat-file -t ${sha}`, { stdio: "pipe" });
11870
11873
  } catch {
11871
11874
  invalidShas.push(sha);
11872
11875
  }
@@ -12025,10 +12028,10 @@ import chalk124 from "chalk";
12025
12028
  import Enquirer2 from "enquirer";
12026
12029
 
12027
12030
  // src/commands/ravendb/searchItems.ts
12028
- import { execSync as execSync40 } from "child_process";
12031
+ import { execSync as execSync39 } from "child_process";
12029
12032
  import chalk123 from "chalk";
12030
12033
  function opExec(args) {
12031
- return execSync40(`op ${args}`, {
12034
+ return execSync39(`op ${args}`, {
12032
12035
  encoding: "utf-8",
12033
12036
  stdio: ["pipe", "pipe", "pipe"]
12034
12037
  }).trim();
@@ -12180,7 +12183,7 @@ ${errorText}`
12180
12183
  }
12181
12184
 
12182
12185
  // src/commands/ravendb/resolveOpSecret.ts
12183
- import { execSync as execSync41 } from "child_process";
12186
+ import { execSync as execSync40 } from "child_process";
12184
12187
  import chalk128 from "chalk";
12185
12188
  function resolveOpSecret(reference) {
12186
12189
  if (!reference.startsWith("op://")) {
@@ -12188,7 +12191,7 @@ function resolveOpSecret(reference) {
12188
12191
  process.exit(1);
12189
12192
  }
12190
12193
  try {
12191
- return execSync41(`op read "${reference}"`, {
12194
+ return execSync40(`op read "${reference}"`, {
12192
12195
  encoding: "utf-8",
12193
12196
  stdio: ["pipe", "pipe", "pipe"]
12194
12197
  }).trim();
@@ -12437,7 +12440,7 @@ Refactor check failed:
12437
12440
  }
12438
12441
 
12439
12442
  // src/commands/refactor/check/getViolations/index.ts
12440
- import { execSync as execSync42 } from "child_process";
12443
+ import { execSync as execSync41 } from "child_process";
12441
12444
  import fs18 from "fs";
12442
12445
  import { minimatch as minimatch5 } from "minimatch";
12443
12446
 
@@ -12487,7 +12490,7 @@ function getGitFiles(options2) {
12487
12490
  }
12488
12491
  const files = /* @__PURE__ */ new Set();
12489
12492
  if (options2.staged || options2.modified) {
12490
- const staged = execSync42("git diff --cached --name-only", {
12493
+ const staged = execSync41("git diff --cached --name-only", {
12491
12494
  encoding: "utf-8"
12492
12495
  });
12493
12496
  for (const file of staged.trim().split("\n").filter(Boolean)) {
@@ -12495,7 +12498,7 @@ function getGitFiles(options2) {
12495
12498
  }
12496
12499
  }
12497
12500
  if (options2.unstaged || options2.modified) {
12498
- const unstaged = execSync42("git diff --name-only", { encoding: "utf-8" });
12501
+ const unstaged = execSync41("git diff --name-only", { encoding: "utf-8" });
12499
12502
  for (const file of unstaged.trim().split("\n").filter(Boolean)) {
12500
12503
  files.add(file);
12501
12504
  }
@@ -13936,7 +13939,7 @@ function registerRefactor(program2) {
13936
13939
  }
13937
13940
 
13938
13941
  // src/commands/review/review.ts
13939
- import { execFileSync as execFileSync6 } from "child_process";
13942
+ import { execFileSync as execFileSync7 } from "child_process";
13940
13943
 
13941
13944
  // src/commands/review/annotateDiffWithLineNumbers.ts
13942
13945
  var FILE_HEADER2 = /^\+\+\+ (?:b\/)?(.+)$/;
@@ -14071,9 +14074,9 @@ function buildReviewPaths(repoRoot, key) {
14071
14074
  }
14072
14075
 
14073
14076
  // src/commands/review/fetchExistingComments.ts
14074
- import { execSync as execSync43 } from "child_process";
14077
+ import { execSync as execSync42 } from "child_process";
14075
14078
  function fetchRawComments(org, repo, prNumber) {
14076
- const out = execSync43(
14079
+ const out = execSync42(
14077
14080
  `gh api --paginate repos/${org}/${repo}/pulls/${prNumber}/comments`,
14078
14081
  { encoding: "utf-8", maxBuffer: 64 * 1024 * 1024 }
14079
14082
  );
@@ -14104,14 +14107,14 @@ function fetchExistingComments() {
14104
14107
  }
14105
14108
 
14106
14109
  // src/commands/review/gatherContext.ts
14107
- import { execSync as execSync46 } from "child_process";
14110
+ import { execSync as execSync45 } from "child_process";
14108
14111
 
14109
14112
  // src/commands/review/fetchPrDiff.ts
14110
- import { execSync as execSync44 } from "child_process";
14113
+ import { execSync as execSync43 } from "child_process";
14111
14114
  function fetchPrDiff(prNumber, baseSha, headSha) {
14112
14115
  const { org, repo } = getRepoInfo();
14113
14116
  try {
14114
- return execSync44(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
14117
+ return execSync43(`gh pr diff ${prNumber} -R ${org}/${repo}`, {
14115
14118
  encoding: "utf-8",
14116
14119
  maxBuffer: 256 * 1024 * 1024,
14117
14120
  stdio: ["ignore", "pipe", "pipe"]
@@ -14126,19 +14129,19 @@ function isDiffTooLarge(error) {
14126
14129
  }
14127
14130
  function fetchDiffViaGit(baseSha, headSha) {
14128
14131
  try {
14129
- execSync44(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
14132
+ execSync43(`git fetch origin ${baseSha} ${headSha}`, { stdio: "ignore" });
14130
14133
  } catch {
14131
14134
  }
14132
- return execSync44(`git diff ${baseSha}...${headSha}`, {
14135
+ return execSync43(`git diff ${baseSha}...${headSha}`, {
14133
14136
  encoding: "utf-8",
14134
14137
  maxBuffer: 256 * 1024 * 1024
14135
14138
  });
14136
14139
  }
14137
14140
 
14138
14141
  // src/commands/review/fetchPrDiffInfo.ts
14139
- import { execSync as execSync45 } from "child_process";
14142
+ import { execSync as execSync44 } from "child_process";
14140
14143
  function getCurrentBranch2() {
14141
- return execSync45("git rev-parse --abbrev-ref HEAD", {
14144
+ return execSync44("git rev-parse --abbrev-ref HEAD", {
14142
14145
  encoding: "utf-8"
14143
14146
  }).trim();
14144
14147
  }
@@ -14148,7 +14151,7 @@ function fetchPrDiffInfo() {
14148
14151
  const fields = "number,baseRefName,baseRefOid,headRefName,headRefOid";
14149
14152
  let raw;
14150
14153
  try {
14151
- raw = execSync45(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
14154
+ raw = execSync44(`gh pr view ${branch} --json ${fields} -R ${org}/${repo}`, {
14152
14155
  encoding: "utf-8",
14153
14156
  stdio: ["ignore", "pipe", "pipe"]
14154
14157
  });
@@ -14172,7 +14175,7 @@ function fetchPrDiffInfo() {
14172
14175
  }
14173
14176
  function fetchPrChangedFiles(prNumber) {
14174
14177
  const { org, repo } = getRepoInfo();
14175
- const out = execSync45(
14178
+ const out = execSync44(
14176
14179
  `gh api repos/${org}/${repo}/pulls/${prNumber}/files --paginate --jq ".[].filename"`,
14177
14180
  {
14178
14181
  encoding: "utf-8",
@@ -14184,11 +14187,11 @@ function fetchPrChangedFiles(prNumber) {
14184
14187
 
14185
14188
  // src/commands/review/gatherContext.ts
14186
14189
  function gatherContext() {
14187
- const branch = execSync46("git rev-parse --abbrev-ref HEAD", {
14190
+ const branch = execSync45("git rev-parse --abbrev-ref HEAD", {
14188
14191
  encoding: "utf-8"
14189
14192
  }).trim();
14190
- const sha = execSync46("git rev-parse HEAD", { encoding: "utf-8" }).trim();
14191
- const shortSha = execSync46("git rev-parse --short=7 HEAD", {
14193
+ const sha = execSync45("git rev-parse HEAD", { encoding: "utf-8" }).trim();
14194
+ const shortSha = execSync45("git rev-parse --short=7 HEAD", {
14192
14195
  encoding: "utf-8"
14193
14196
  }).trim();
14194
14197
  const prInfo = fetchPrDiffInfo();
@@ -15632,7 +15635,7 @@ function validateOptions(options2) {
15632
15635
  }
15633
15636
  function checkoutPr(number) {
15634
15637
  try {
15635
- execFileSync6("gh", ["pr", "checkout", number], { stdio: "inherit" });
15638
+ execFileSync7("gh", ["pr", "checkout", number], { stdio: "inherit" });
15636
15639
  } catch {
15637
15640
  console.error(`gh pr checkout ${number} failed; aborting.`);
15638
15641
  process.exit(1);
@@ -17024,7 +17027,7 @@ import { mkdirSync as mkdirSync18 } from "fs";
17024
17027
  import { join as join47 } from "path";
17025
17028
 
17026
17029
  // src/commands/voice/checkLockFile.ts
17027
- import { execSync as execSync47 } from "child_process";
17030
+ import { execSync as execSync46 } from "child_process";
17028
17031
  import { existsSync as existsSync45, mkdirSync as mkdirSync17, readFileSync as readFileSync35, writeFileSync as writeFileSync29 } from "fs";
17029
17032
  import { join as join46 } from "path";
17030
17033
  function isProcessAlive2(pid) {
@@ -17053,7 +17056,7 @@ function bootstrapVenv() {
17053
17056
  if (existsSync45(getVenvPython())) return;
17054
17057
  console.log("Setting up Python environment...");
17055
17058
  const pythonDir = getPythonDir();
17056
- execSync47(
17059
+ execSync46(
17057
17060
  `uv sync --project "${pythonDir}" --extra runtime --no-install-project`,
17058
17061
  {
17059
17062
  stdio: "inherit",
@@ -17375,7 +17378,7 @@ async function auth() {
17375
17378
  }
17376
17379
 
17377
17380
  // src/commands/roam/postRoamActivity.ts
17378
- import { execFileSync as execFileSync7 } from "child_process";
17381
+ import { execFileSync as execFileSync8 } from "child_process";
17379
17382
  import { readdirSync as readdirSync7, readFileSync as readFileSync38, statSync as statSync5 } from "fs";
17380
17383
  import { join as join49 } from "path";
17381
17384
  function findPortFile(roamDir) {
@@ -17408,7 +17411,7 @@ function postRoamActivity(app, event) {
17408
17411
  }
17409
17412
  const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${app === "codex" ? 99998 : 99999}`;
17410
17413
  try {
17411
- execFileSync7("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
17414
+ execFileSync8("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
17412
17415
  stdio: "ignore"
17413
17416
  });
17414
17417
  } catch {
@@ -17530,11 +17533,11 @@ function resolveParams(params, cliArgs) {
17530
17533
  }
17531
17534
 
17532
17535
  // src/commands/run/runPreCommands.ts
17533
- import { execSync as execSync48 } from "child_process";
17536
+ import { execSync as execSync47 } from "child_process";
17534
17537
  function runPreCommands(pre, cwd) {
17535
17538
  for (const cmd of pre) {
17536
17539
  try {
17537
- execSync48(cmd, { stdio: "inherit", cwd });
17540
+ execSync47(cmd, { stdio: "inherit", cwd });
17538
17541
  } catch (err) {
17539
17542
  const code = err && typeof err === "object" && "status" in err ? err.status : 1;
17540
17543
  process.exit(code);
@@ -17543,13 +17546,13 @@ function runPreCommands(pre, cwd) {
17543
17546
  }
17544
17547
 
17545
17548
  // src/commands/run/spawnRunCommand.ts
17546
- import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
17549
+ import { execFileSync as execFileSync9, spawn as spawn8 } from "child_process";
17547
17550
  import { existsSync as existsSync48 } from "fs";
17548
17551
  import { dirname as dirname25, join as join50, resolve as resolve11 } from "path";
17549
17552
  function resolveCommand2(command) {
17550
17553
  if (process.platform !== "win32" || command !== "bash") return command;
17551
17554
  try {
17552
- const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
17555
+ const gitPath = execFileSync9("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
17553
17556
  const gitRoot = resolve11(dirname25(gitPath), "..");
17554
17557
  const gitBash = join50(gitRoot, "bin", "bash.exe");
17555
17558
  if (existsSync48(gitBash)) return gitBash;
@@ -17818,7 +17821,7 @@ function registerRun(program2) {
17818
17821
  }
17819
17822
 
17820
17823
  // src/commands/screenshot/index.ts
17821
- import { execSync as execSync49 } from "child_process";
17824
+ import { execSync as execSync48 } from "child_process";
17822
17825
  import { existsSync as existsSync50, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync32 } from "fs";
17823
17826
  import { tmpdir as tmpdir7 } from "os";
17824
17827
  import { join as join53, resolve as resolve13 } from "path";
@@ -17961,7 +17964,7 @@ function runPowerShellScript(processName, outputPath) {
17961
17964
  const scriptPath = join53(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
17962
17965
  writeFileSync32(scriptPath, captureWindowPs1, "utf-8");
17963
17966
  try {
17964
- execSync49(
17967
+ execSync48(
17965
17968
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
17966
17969
  { stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }
17967
17970
  );
@@ -17985,11 +17988,11 @@ function screenshot(processName) {
17985
17988
  }
17986
17989
 
17987
17990
  // src/commands/sessions/daemon/listDaemonPids.ts
17988
- import { execFileSync as execFileSync9 } from "child_process";
17991
+ import { execFileSync as execFileSync10 } from "child_process";
17989
17992
  function listDaemonPids() {
17990
17993
  if (process.platform === "win32") return [];
17991
17994
  try {
17992
- const out = execFileSync9("ps", ["-eo", "pid=,args="], {
17995
+ const out = execFileSync10("ps", ["-eo", "pid=,args="], {
17993
17996
  encoding: "utf-8"
17994
17997
  });
17995
17998
  return out.split("\n").filter((line) => line.includes("assist") && / daemon run\b/.test(line)).map((line) => Number.parseInt(line.trim(), 10)).filter((pid) => Number.isInteger(pid));
@@ -18570,6 +18573,33 @@ function shutdownSessions(sessions) {
18570
18573
  }
18571
18574
  }
18572
18575
 
18576
+ // src/commands/sessions/daemon/autoHealWindowsDaemon.ts
18577
+ async function autoHealWindowsDaemon(conn, state, heal, version2) {
18578
+ daemonLog(`windows proxy: auto-healing windows daemon (mismatch ${version2})`);
18579
+ notifyHealing(state);
18580
+ try {
18581
+ conn.dispose();
18582
+ await heal();
18583
+ daemonLog("windows proxy: heal complete, reconnecting to windows daemon");
18584
+ await conn.ensure();
18585
+ } catch (e) {
18586
+ const message = e instanceof Error ? e.message : String(e);
18587
+ daemonLog(`windows proxy: auto-heal failed: ${message}`);
18588
+ state.broadcast({
18589
+ type: "error",
18590
+ message: `Windows host auto-update failed: ${message}`
18591
+ });
18592
+ }
18593
+ }
18594
+ function notifyHealing(state) {
18595
+ for (const client of state.pendingCreators)
18596
+ sendTo(client, {
18597
+ type: "error",
18598
+ message: "Windows host is out of date; updating it now \u2014 reselect the repo once the update finishes."
18599
+ });
18600
+ state.pendingCreators = [];
18601
+ }
18602
+
18573
18603
  // src/commands/sessions/daemon/connectToWindowsDaemon.ts
18574
18604
  import * as net2 from "net";
18575
18605
 
@@ -18600,18 +18630,6 @@ async function isWindowsDaemonRunning() {
18600
18630
  }
18601
18631
  }
18602
18632
 
18603
- // src/commands/sessions/daemon/discoverWindowsSessions.ts
18604
- async function discoverWindowsSessions(conn) {
18605
- if (conn.connected || !await isWindowsDaemonRunning()) return;
18606
- daemonLog("windows proxy: discovering sessions on running windows daemon");
18607
- try {
18608
- await conn.ensure();
18609
- } catch (e) {
18610
- const message = e instanceof Error ? e.message : String(e);
18611
- daemonLog(`windows proxy: discovery failed: ${message}`);
18612
- }
18613
- }
18614
-
18615
18633
  // src/commands/sessions/daemon/ensureWindowsDaemonRunning.ts
18616
18634
  import { spawn as spawn10 } from "child_process";
18617
18635
  var SPAWN_TIMEOUT_MS2 = 3e4;
@@ -18661,6 +18679,24 @@ function delay2(ms) {
18661
18679
  return new Promise((resolve16) => setTimeout(resolve16, ms));
18662
18680
  }
18663
18681
 
18682
+ // src/commands/sessions/daemon/defaultConnect.ts
18683
+ async function defaultConnect() {
18684
+ await ensureWindowsDaemonRunning();
18685
+ return connectToWindowsDaemon();
18686
+ }
18687
+
18688
+ // src/commands/sessions/daemon/discoverWindowsSessions.ts
18689
+ async function discoverWindowsSessions(conn) {
18690
+ if (conn.connected || !await isWindowsDaemonRunning()) return;
18691
+ daemonLog("windows proxy: discovering sessions on running windows daemon");
18692
+ try {
18693
+ await conn.ensure();
18694
+ } catch (e) {
18695
+ const message = e instanceof Error ? e.message : String(e);
18696
+ daemonLog(`windows proxy: discovery failed: ${message}`);
18697
+ }
18698
+ }
18699
+
18664
18700
  // src/commands/sessions/daemon/forwardWindowsCreate.ts
18665
18701
  async function forwardWindowsCreate(conn, state, client, data) {
18666
18702
  daemonLog(`windows proxy: routing ${data.type} (cwd=${data.cwd})`);
@@ -18693,13 +18729,14 @@ function versionsMatch(a, b) {
18693
18729
 
18694
18730
  // src/commands/sessions/daemon/WindowsProxyState.ts
18695
18731
  var MAX_SCROLLBACK2 = 256 * 1024;
18696
- function createState(broadcast2, onSessionsChanged) {
18732
+ function createState(broadcast2, onSessionsChanged, onVersionMismatch) {
18697
18733
  return {
18698
18734
  windowsSessions: [],
18699
18735
  scrollback: /* @__PURE__ */ new Map(),
18700
18736
  pendingCreators: [],
18701
18737
  broadcast: broadcast2,
18702
- onSessionsChanged
18738
+ onSessionsChanged,
18739
+ onVersionMismatch
18703
18740
  };
18704
18741
  }
18705
18742
  function resetState(state) {
@@ -18730,7 +18767,7 @@ function handleInbound(state, line) {
18730
18767
  inbound[msg.type]?.(state, msg);
18731
18768
  }
18732
18769
  var inbound = {
18733
- hello: (_state, msg) => handleHello(msg),
18770
+ hello: handleHello,
18734
18771
  created: handleCreated,
18735
18772
  sessions: handleSessions,
18736
18773
  output: handleOutput,
@@ -18740,11 +18777,13 @@ var inbound = {
18740
18777
  state.broadcast(msg);
18741
18778
  }
18742
18779
  };
18743
- function handleHello(msg) {
18744
- if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION))
18780
+ function handleHello(state, msg) {
18781
+ if (isHello(msg) && !versionsMatch(msg.version, ASSIST_VERSION)) {
18745
18782
  daemonLog(
18746
18783
  `windows daemon version mismatch: ${msg.version} (wsl ${ASSIST_VERSION})`
18747
18784
  );
18785
+ state.onVersionMismatch(msg.version);
18786
+ }
18748
18787
  }
18749
18788
  function handleCreated(state, msg) {
18750
18789
  daemonLog(`windows daemon: created session ${nsId(msg)}`);
@@ -18775,6 +18814,57 @@ function nsId(msg) {
18775
18814
  return toWindowsSessionId(msg.sessionId);
18776
18815
  }
18777
18816
 
18817
+ // src/commands/sessions/daemon/healWindowsDaemon.ts
18818
+ import { spawn as spawn11 } from "child_process";
18819
+ import { createInterface as createInterface5 } from "readline";
18820
+ var UPDATE_TIMEOUT_MS = 5 * 6e4;
18821
+ var STOP_TIMEOUT_MS2 = 3e4;
18822
+ async function healWindowsDaemon() {
18823
+ daemonLog("windows daemon: auto-heal: running `assist update` on host");
18824
+ await runOnWindowsHost("assist update", UPDATE_TIMEOUT_MS);
18825
+ daemonLog("windows daemon: auto-heal: update done, stopping stale daemon");
18826
+ await runOnWindowsHost("assist daemon stop", STOP_TIMEOUT_MS2);
18827
+ daemonLog("windows daemon: auto-heal: stale daemon stopped");
18828
+ }
18829
+ function runOnWindowsHost(command, timeoutMs) {
18830
+ return new Promise((resolve16, reject) => {
18831
+ const child = spawn11("pwsh.exe", ["-Command", command], {
18832
+ stdio: ["ignore", "pipe", "pipe"]
18833
+ });
18834
+ logStream(child.stdout, command);
18835
+ logStream(child.stderr, command);
18836
+ const timer = setTimeout(() => {
18837
+ child.kill();
18838
+ reject(
18839
+ new Error(
18840
+ `'${command}' on the Windows host timed out after ${timeoutMs}ms`
18841
+ )
18842
+ );
18843
+ }, timeoutMs);
18844
+ child.on("error", (e) => {
18845
+ clearTimeout(timer);
18846
+ reject(e);
18847
+ });
18848
+ child.on("exit", (code) => {
18849
+ clearTimeout(timer);
18850
+ if (code === 0) resolve16();
18851
+ else
18852
+ reject(
18853
+ new Error(
18854
+ `'${command}' on the Windows host exited with code ${code}`
18855
+ )
18856
+ );
18857
+ });
18858
+ });
18859
+ }
18860
+ function logStream(stream, command) {
18861
+ if (!stream) return;
18862
+ const lines = createInterface5({ input: stream });
18863
+ lines.on("line", (line) => daemonLog(`[windows ${command}] ${line}`));
18864
+ lines.on("error", () => {
18865
+ });
18866
+ }
18867
+
18778
18868
  // src/commands/sessions/daemon/isWindowsCwd.ts
18779
18869
  function isWindowsCwd(cwd) {
18780
18870
  return /^[A-Za-z]:[\\/]/.test(cwd);
@@ -18783,8 +18873,16 @@ function shouldProxyToWindows(cwd) {
18783
18873
  return detectPlatform() === "wsl" && isWindowsCwd(cwd);
18784
18874
  }
18785
18875
 
18876
+ // src/commands/sessions/daemon/isWindowsCreate.ts
18877
+ function isWindowsCreate(data) {
18878
+ return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
18879
+ }
18880
+ function isWindowsIo(data) {
18881
+ return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
18882
+ }
18883
+
18786
18884
  // src/commands/sessions/daemon/WindowsConnection.ts
18787
- import { createInterface as createInterface5 } from "readline";
18885
+ import { createInterface as createInterface6 } from "readline";
18788
18886
  var WindowsConnection = class {
18789
18887
  constructor(deps2) {
18790
18888
  this.deps = deps2;
@@ -18821,7 +18919,7 @@ var WindowsConnection = class {
18821
18919
  const socket = await this.deps.connect();
18822
18920
  daemonLog("windows connection: tcp connected, sending hello");
18823
18921
  this.socket = socket;
18824
- const lines = createInterface5({ input: socket });
18922
+ const lines = createInterface6({ input: socket });
18825
18923
  lines.on("error", () => {
18826
18924
  });
18827
18925
  lines.on("line", (line) => this.deps.onLine(line));
@@ -18842,12 +18940,12 @@ var WindowsConnection = class {
18842
18940
 
18843
18941
  // src/commands/sessions/daemon/WindowsProxy.ts
18844
18942
  var WindowsProxy = class {
18845
- state;
18846
- conn;
18847
- constructor(clients, onSessionsChanged, connect3 = defaultConnect) {
18943
+ constructor(clients, onSessionsChanged, connect3 = defaultConnect, heal = healWindowsDaemon) {
18944
+ this.heal = heal;
18848
18945
  this.state = createState(
18849
18946
  (msg) => broadcast(clients, msg),
18850
- onSessionsChanged
18947
+ onSessionsChanged,
18948
+ (version2) => void this.handleVersionMismatch(version2)
18851
18949
  );
18852
18950
  this.conn = new WindowsConnection({
18853
18951
  connect: connect3,
@@ -18855,6 +18953,11 @@ var WindowsProxy = class {
18855
18953
  onClose: () => this.handleClose()
18856
18954
  });
18857
18955
  }
18956
+ state;
18957
+ conn;
18958
+ // why: heal runs once per proxy lifetime; if WSL is the older side, updating Windows can't close the gap, so a repeat mismatch must not loop
18959
+ healAttempted = false;
18960
+ healing = false;
18858
18961
  sessions() {
18859
18962
  return this.state.windowsSessions;
18860
18963
  }
@@ -18868,7 +18971,7 @@ var WindowsProxy = class {
18868
18971
  // windows-origin cwd is forwarded, as is I/O for a namespaced session id.
18869
18972
  route(client, data) {
18870
18973
  if (isWindowsCreate(data)) {
18871
- void this.forwardCreate(client, data);
18974
+ void forwardWindowsCreate(this.conn, this.state, client, data);
18872
18975
  return true;
18873
18976
  }
18874
18977
  if (isWindowsIo(data)) {
@@ -18881,8 +18984,15 @@ var WindowsProxy = class {
18881
18984
  dispose() {
18882
18985
  this.conn.dispose();
18883
18986
  }
18884
- async forwardCreate(client, data) {
18885
- await forwardWindowsCreate(this.conn, this.state, client, data);
18987
+ async handleVersionMismatch(version2) {
18988
+ if (this.healing || this.healAttempted) return;
18989
+ this.healing = true;
18990
+ this.healAttempted = true;
18991
+ try {
18992
+ await autoHealWindowsDaemon(this.conn, this.state, this.heal, version2);
18993
+ } finally {
18994
+ this.healing = false;
18995
+ }
18886
18996
  }
18887
18997
  handleClose() {
18888
18998
  daemonLog("windows proxy: connection to windows daemon closed");
@@ -18895,16 +19005,6 @@ var WindowsProxy = class {
18895
19005
  this.state.onSessionsChanged();
18896
19006
  }
18897
19007
  };
18898
- function isWindowsCreate(data) {
18899
- return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
18900
- }
18901
- function isWindowsIo(data) {
18902
- return typeof data.sessionId === "string" && isWindowsSessionId(data.sessionId);
18903
- }
18904
- async function defaultConnect() {
18905
- await ensureWindowsDaemonRunning();
18906
- return connectToWindowsDaemon();
18907
- }
18908
19008
 
18909
19009
  // src/commands/sessions/daemon/watchClaudeSessionId.ts
18910
19010
  import * as fs27 from "fs";
@@ -19300,7 +19400,7 @@ import { unlinkSync as unlinkSync19 } from "fs";
19300
19400
  import * as net3 from "net";
19301
19401
 
19302
19402
  // src/commands/sessions/daemon/handleConnection.ts
19303
- import { createInterface as createInterface6 } from "readline";
19403
+ import { createInterface as createInterface7 } from "readline";
19304
19404
 
19305
19405
  // src/commands/sessions/shared/parseTranscript.ts
19306
19406
  import * as fs28 from "fs";
@@ -19394,10 +19494,10 @@ function safeParse2(line) {
19394
19494
  }
19395
19495
 
19396
19496
  // src/commands/sessions/daemon/dispatchMessage.ts
19397
- function creator(spawn11) {
19497
+ function creator(spawn12) {
19398
19498
  return (client, m, d) => {
19399
19499
  if (m.windowsProxy.route(client, d)) return;
19400
- sendTo(client, { type: "created", sessionId: spawn11(m, d) });
19500
+ sendTo(client, { type: "created", sessionId: spawn12(m, d) });
19401
19501
  };
19402
19502
  }
19403
19503
  function handleHistory(client) {
@@ -19478,7 +19578,7 @@ function handleConnection(socket, manager) {
19478
19578
  }
19479
19579
  };
19480
19580
  manager.addClient(client);
19481
- const lines = createInterface6({ input: socket });
19581
+ const lines = createInterface7({ input: socket });
19482
19582
  lines.on("error", () => {
19483
19583
  });
19484
19584
  lines.on("line", (line) => {
@@ -19649,7 +19749,7 @@ function summaryPathFor(jsonlPath2) {
19649
19749
  }
19650
19750
 
19651
19751
  // src/commands/sessions/summarise/summariseSession.ts
19652
- import { execFileSync as execFileSync10 } from "child_process";
19752
+ import { execFileSync as execFileSync11 } from "child_process";
19653
19753
 
19654
19754
  // src/commands/sessions/summarise/iterateUserMessages.ts
19655
19755
  import * as fs30 from "fs";
@@ -19726,7 +19826,7 @@ function summariseSession(jsonlPath2) {
19726
19826
  }
19727
19827
  const prompt = buildPrompt2(firstMessage, backlogIds);
19728
19828
  try {
19729
- const output = execFileSync10("claude", ["-p", "--model", "haiku", prompt], {
19829
+ const output = execFileSync11("claude", ["-p", "--model", "haiku", prompt], {
19730
19830
  encoding: "utf8",
19731
19831
  timeout: 3e4,
19732
19832
  stdio: ["ignore", "pipe", "ignore"]
@@ -19996,7 +20096,7 @@ function syncCommands(claudeDir, targetBase) {
19996
20096
  }
19997
20097
 
19998
20098
  // src/commands/update.ts
19999
- import { execSync as execSync50 } from "child_process";
20099
+ import { execSync as execSync49 } from "child_process";
20000
20100
  import * as path53 from "path";
20001
20101
  function isGlobalNpmInstall(dir) {
20002
20102
  try {
@@ -20004,7 +20104,7 @@ function isGlobalNpmInstall(dir) {
20004
20104
  if (resolved.split(path53.sep).includes("node_modules")) {
20005
20105
  return true;
20006
20106
  }
20007
- const globalPrefix = execSync50("npm prefix -g", { stdio: "pipe" }).toString().trim();
20107
+ const globalPrefix = execSync49("npm prefix -g", { stdio: "pipe" }).toString().trim();
20008
20108
  return resolved.toLowerCase().startsWith(path53.resolve(globalPrefix).toLowerCase());
20009
20109
  } catch {
20010
20110
  return false;
@@ -20015,18 +20115,18 @@ async function update2() {
20015
20115
  console.log(`Assist is installed at: ${installDir}`);
20016
20116
  if (isGitRepo(installDir)) {
20017
20117
  console.log("Detected git repo installation, pulling latest...");
20018
- execSync50("git pull", { cwd: installDir, stdio: "inherit" });
20118
+ execSync49("git pull", { cwd: installDir, stdio: "inherit" });
20019
20119
  console.log("Installing dependencies...");
20020
- execSync50("npm i", { cwd: installDir, stdio: "inherit" });
20120
+ execSync49("npm i", { cwd: installDir, stdio: "inherit" });
20021
20121
  console.log("Building...");
20022
- execSync50("npm run build", { cwd: installDir, stdio: "inherit" });
20122
+ execSync49("npm run build", { cwd: installDir, stdio: "inherit" });
20023
20123
  console.log("Syncing commands...");
20024
- execSync50("assist sync", { stdio: "inherit" });
20124
+ execSync49("assist sync", { stdio: "inherit" });
20025
20125
  } else if (isGlobalNpmInstall(installDir)) {
20026
20126
  console.log("Detected global npm installation, updating...");
20027
- execSync50("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
20127
+ execSync49("npm i -g @staff0rd/assist@latest", { stdio: "inherit" });
20028
20128
  console.log("Syncing commands...");
20029
- execSync50("assist sync", { stdio: "inherit" });
20129
+ execSync49("assist sync", { stdio: "inherit" });
20030
20130
  } else {
20031
20131
  console.error(
20032
20132
  "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.287.0",
3
+ "version": "0.288.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {