@staff0rd/assist 0.766.3 → 0.767.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.
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.766.3",
9
+ version: "0.767.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -10547,6 +10547,35 @@ function isGitRepo(dir) {
10547
10547
  }
10548
10548
  }
10549
10549
 
10550
+ // src/shared/sweepStagedAttachments.ts
10551
+ import { readdirSync as readdirSync4, rmSync as rmSync3, statSync as statSync3 } from "fs";
10552
+ import { join as join35 } from "path";
10553
+
10554
+ // src/shared/stagedAttachmentsDir.ts
10555
+ import { homedir as homedir13 } from "os";
10556
+ import { join as join34 } from "path";
10557
+ var stagedAttachmentsDir = join34(homedir13(), ".assist", "attachments");
10558
+
10559
+ // src/shared/sweepStagedAttachments.ts
10560
+ var PANE_PERSIST_TTL_MS = 24 * 60 * 60 * 1e3;
10561
+ function sweepStagedAttachments(dir = stagedAttachmentsDir, now = Date.now()) {
10562
+ let entries;
10563
+ try {
10564
+ entries = readdirSync4(dir);
10565
+ } catch {
10566
+ return;
10567
+ }
10568
+ for (const name of entries) {
10569
+ if (!name.startsWith("upload-")) continue;
10570
+ const path106 = join35(dir, name);
10571
+ try {
10572
+ if (now - statSync3(path106).mtimeMs > PANE_PERSIST_TTL_MS)
10573
+ rmSync3(path106, { recursive: true, force: true });
10574
+ } catch {
10575
+ }
10576
+ }
10577
+ }
10578
+
10550
10579
  // src/shared/web.ts
10551
10580
  import {
10552
10581
  createServer
@@ -10694,7 +10723,7 @@ import {
10694
10723
  closeSync as closeSync2,
10695
10724
  mkdirSync as mkdirSync10,
10696
10725
  openSync as openSync3,
10697
- statSync as statSync3,
10726
+ statSync as statSync4,
10698
10727
  unlinkSync as unlinkSync6,
10699
10728
  writeSync
10700
10729
  } from "fs";
@@ -10743,7 +10772,7 @@ function tryCreateLock() {
10743
10772
  }
10744
10773
  function isLockStale() {
10745
10774
  try {
10746
- return Date.now() - statSync3(daemonPaths.spawnLock).mtimeMs > STALE_LOCK_MS;
10775
+ return Date.now() - statSync4(daemonPaths.spawnLock).mtimeMs > STALE_LOCK_MS;
10747
10776
  } catch {
10748
10777
  return true;
10749
10778
  }
@@ -10883,13 +10912,13 @@ function gitCommonDir(cwd) {
10883
10912
 
10884
10913
  // src/shared/loadJson.ts
10885
10914
  import { existsSync as existsSync32, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync21 } from "fs";
10886
- import { homedir as homedir13 } from "os";
10887
- import { join as join34 } from "path";
10915
+ import { homedir as homedir14 } from "os";
10916
+ import { join as join36 } from "path";
10888
10917
  function getStoreDir() {
10889
- return process.env.ASSIST_STORE_DIR || join34(homedir13(), ".assist");
10918
+ return process.env.ASSIST_STORE_DIR || join36(homedir14(), ".assist");
10890
10919
  }
10891
10920
  function getStorePath(filename) {
10892
- return join34(getStoreDir(), filename);
10921
+ return join36(getStoreDir(), filename);
10893
10922
  }
10894
10923
  function loadJson(filename) {
10895
10924
  const path106 = getStorePath(filename);
@@ -11258,14 +11287,14 @@ function attachSessionSocket(server, ctx) {
11258
11287
 
11259
11288
  // src/shared/createBundleHandler.ts
11260
11289
  import { createHash } from "crypto";
11261
- import { readFileSync as readFileSync21, statSync as statSync4 } from "fs";
11262
- import { dirname as dirname21, join as join35 } from "path";
11290
+ import { readFileSync as readFileSync21, statSync as statSync5 } from "fs";
11291
+ import { dirname as dirname21, join as join37 } from "path";
11263
11292
  import { fileURLToPath as fileURLToPath4 } from "url";
11264
11293
  function createBundleHandler(importMetaUrl, bundlePath, contentType = "application/javascript") {
11265
- const file = join35(dirname21(fileURLToPath4(importMetaUrl)), bundlePath);
11294
+ const file = join37(dirname21(fileURLToPath4(importMetaUrl)), bundlePath);
11266
11295
  let cache6;
11267
11296
  return (req, res) => {
11268
- const mtimeMs = statSync4(file).mtimeMs;
11297
+ const mtimeMs = statSync5(file).mtimeMs;
11269
11298
  if (cache6?.mtimeMs !== mtimeMs) {
11270
11299
  const body = readFileSync21(file, "utf8");
11271
11300
  const etag = `"${createHash("sha256").update(body).digest("hex").slice(0, 16)}"`;
@@ -13323,19 +13352,19 @@ function handleServerRuns(req, res) {
13323
13352
  // src/commands/sessions/web/getReviewSynthesis.ts
13324
13353
  import { execFile as execFile6 } from "child_process";
13325
13354
  import { readFileSync as readFileSync22 } from "fs";
13326
- import { homedir as homedir14 } from "os";
13327
- import { basename as basename11, join as join37 } from "path";
13355
+ import { homedir as homedir15 } from "os";
13356
+ import { basename as basename11, join as join39 } from "path";
13328
13357
  import { promisify as promisify5 } from "util";
13329
13358
 
13330
13359
  // src/commands/sessions/web/findSynthesisForBranch.ts
13331
- import { existsSync as existsSync35, readdirSync as readdirSync4, statSync as statSync5 } from "fs";
13332
- import { basename as basename10, dirname as dirname22, join as join36 } from "path";
13360
+ import { existsSync as existsSync35, readdirSync as readdirSync5, statSync as statSync6 } from "fs";
13361
+ import { basename as basename10, dirname as dirname22, join as join38 } from "path";
13333
13362
  function findSynthesisForBranch(repoReviewsDir, branch2) {
13334
- const branchKeyPath = join36(repoReviewsDir, `${branch2}-`);
13363
+ const branchKeyPath = join38(repoReviewsDir, `${branch2}-`);
13335
13364
  const parent = dirname22(branchKeyPath);
13336
13365
  const branchPrefix = basename10(branchKeyPath);
13337
13366
  if (!existsSync35(parent)) return null;
13338
- const synthesisFiles = readdirSync4(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join36(parent, name, "synthesis.md")).filter((path106) => existsSync35(path106)).map((path106) => ({ path: path106, mtime: statSync5(path106).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
13367
+ const synthesisFiles = readdirSync5(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join38(parent, name, "synthesis.md")).filter((path106) => existsSync35(path106)).map((path106) => ({ path: path106, mtime: statSync6(path106).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
13339
13368
  return synthesisFiles[0]?.path ?? null;
13340
13369
  }
13341
13370
 
@@ -13353,8 +13382,8 @@ async function resolveSynthesisPath(cwd) {
13353
13382
  runGit2(cwd, ["rev-parse", "--show-toplevel"]),
13354
13383
  runGit2(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
13355
13384
  ]);
13356
- const repoReviewsDir = join37(
13357
- homedir14(),
13385
+ const repoReviewsDir = join39(
13386
+ homedir15(),
13358
13387
  ".assist",
13359
13388
  "reviews",
13360
13389
  basename11(repoRoot2)
@@ -13667,8 +13696,8 @@ function subsequenceScore(text17, query) {
13667
13696
  function scoreFilePath(path106, query) {
13668
13697
  const needle = query.trim().toLowerCase();
13669
13698
  if (!needle) return 0;
13670
- const basename32 = path106.slice(path106.lastIndexOf("/") + 1);
13671
- const inBasename = subsequenceScore(basename32, needle);
13699
+ const basename33 = path106.slice(path106.lastIndexOf("/") + 1);
13700
+ const inBasename = subsequenceScore(basename33, needle);
13672
13701
  if (inBasename !== null) return BASENAME_WEIGHT + inBasename;
13673
13702
  return subsequenceScore(path106, needle);
13674
13703
  }
@@ -14637,11 +14666,11 @@ function parseRulesSection(content) {
14637
14666
  }
14638
14667
 
14639
14668
  // src/commands/rules/scopeDirectory.ts
14640
- import { existsSync as existsSync36, statSync as statSync6 } from "fs";
14669
+ import { existsSync as existsSync36, statSync as statSync7 } from "fs";
14641
14670
  import path25 from "path";
14642
14671
  function scopeDirectory(target) {
14643
14672
  const resolved = path25.resolve(target);
14644
- return existsSync36(resolved) && statSync6(resolved).isDirectory() ? resolved : path25.dirname(resolved);
14673
+ return existsSync36(resolved) && statSync7(resolved).isDirectory() ? resolved : path25.dirname(resolved);
14645
14674
  }
14646
14675
 
14647
14676
  // src/commands/rules/readScopedRules.ts
@@ -15167,13 +15196,6 @@ import { stat as stat3 } from "fs/promises";
15167
15196
 
15168
15197
  // src/shared/isStagedAttachmentPath.ts
15169
15198
  import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve12, sep } from "path";
15170
-
15171
- // src/shared/stagedAttachmentsDir.ts
15172
- import { homedir as homedir15 } from "os";
15173
- import { join as join38 } from "path";
15174
- var stagedAttachmentsDir = join38(homedir15(), ".assist", "attachments");
15175
-
15176
- // src/shared/isStagedAttachmentPath.ts
15177
15199
  function isStagedAttachmentPath(path106) {
15178
15200
  const rel = relative3(stagedAttachmentsDir, resolve12(path106));
15179
15201
  return rel !== "" && rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute3(rel);
@@ -15189,12 +15211,9 @@ var attachmentMimeTypes = {
15189
15211
  "image/gif": "gif",
15190
15212
  "image/webp": "webp",
15191
15213
  "image/svg+xml": "svg",
15192
- "image/bmp": "bmp",
15193
- "image/avif": "avif",
15194
15214
  "video/mp4": "mp4",
15195
15215
  "video/webm": "webm",
15196
- "video/quicktime": "mov",
15197
- "video/ogg": "ogv"
15216
+ "video/quicktime": "mov"
15198
15217
  };
15199
15218
 
15200
15219
  // src/commands/sessions/web/attachmentContentType.ts
@@ -15832,13 +15851,13 @@ import { existsSync as existsSync39 } from "fs";
15832
15851
  // src/commands/run/resolveCommand.ts
15833
15852
  import { execFileSync as execFileSync4 } from "child_process";
15834
15853
  import { existsSync as existsSync38 } from "fs";
15835
- import { dirname as dirname23, join as join39, resolve as resolve13 } from "path";
15854
+ import { dirname as dirname23, join as join40, resolve as resolve13 } from "path";
15836
15855
  function resolveCommand(command) {
15837
15856
  if (process.platform !== "win32" || command !== "bash") return command;
15838
15857
  try {
15839
15858
  const gitPath = execFileSync4("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
15840
15859
  const gitRoot = resolve13(dirname23(gitPath), "..");
15841
- const gitBash = join39(gitRoot, "bin", "bash.exe");
15860
+ const gitBash = join40(gitRoot, "bin", "bash.exe");
15842
15861
  if (existsSync38(gitBash)) return gitBash;
15843
15862
  } catch {
15844
15863
  return command;
@@ -16942,7 +16961,7 @@ async function readRequestBuffer(req, limit) {
16942
16961
 
16943
16962
  // src/commands/sessions/web/stageAttachment.ts
16944
16963
  import { mkdir as mkdir4, mkdtemp, writeFile as writeFile2 } from "fs/promises";
16945
- import { extname as extname2, join as join40 } from "path";
16964
+ import { extname as extname2, join as join41 } from "path";
16946
16965
  function extensionFromMime(contentType) {
16947
16966
  const mime = contentType.split(";")[0].trim().toLowerCase();
16948
16967
  const known = attachmentMimeTypes[mime];
@@ -16950,20 +16969,29 @@ function extensionFromMime(contentType) {
16950
16969
  const subtype = mime.split("/")[1]?.replace(/^x-/, "").replace(/\+.*$/, "");
16951
16970
  return subtype && /^[a-z0-9]+$/.test(subtype) ? subtype : void 0;
16952
16971
  }
16972
+ var ghAttachableExtensions = /* @__PURE__ */ new Set([
16973
+ ...Object.values(attachmentMimeTypes),
16974
+ "jpeg"
16975
+ ]);
16953
16976
  function pickExtension(name, contentType) {
16954
16977
  const fromName = extname2(name).replace(/^\./, "").toLowerCase();
16955
- if (/^[a-z0-9]+$/.test(fromName)) return fromName;
16956
- return extensionFromMime(contentType) ?? "png";
16978
+ const ext = /^[a-z0-9]+$/.test(fromName) ? fromName : extensionFromMime(contentType) ?? "png";
16979
+ if (!ghAttachableExtensions.has(ext))
16980
+ throw new Error(
16981
+ `gh cannot attach .${ext} files (supported: ${[...ghAttachableExtensions].join(", ")}).`
16982
+ );
16983
+ return ext;
16957
16984
  }
16958
16985
  function safeBaseName(name) {
16959
16986
  const base = name.replace(/\.[^.]+$/, "").replace(/[^a-zA-Z0-9_-]+/g, "-");
16960
16987
  return base.replace(/^-+|-+$/g, "").slice(0, 60) || "screenshot";
16961
16988
  }
16962
16989
  async function stageAttachment(name, contentType, body) {
16990
+ const ext = pickExtension(name, contentType);
16963
16991
  await mkdir4(stagedAttachmentsDir, { recursive: true });
16964
- const dir = await mkdtemp(join40(stagedAttachmentsDir, "upload-"));
16992
+ const dir = await mkdtemp(join41(stagedAttachmentsDir, "upload-"));
16965
16993
  const alt = safeBaseName(name);
16966
- const filePath = join40(dir, `${alt}.${pickExtension(name, contentType)}`);
16994
+ const filePath = join41(dir, `${alt}.${ext}`);
16967
16995
  await writeFile2(filePath, body);
16968
16996
  return { dir, filePath, alt };
16969
16997
  }
@@ -17013,14 +17041,14 @@ import { readFile as readFile3, stat as stat4, writeFile as writeFile3 } from "f
17013
17041
  // src/commands/sessions/web/formatWithOxfmt.ts
17014
17042
  import { execFile as execFile10 } from "child_process";
17015
17043
  import { existsSync as existsSync40 } from "fs";
17016
- import { dirname as dirname24, join as join41 } from "path";
17044
+ import { dirname as dirname24, join as join42 } from "path";
17017
17045
  import { promisify as promisify10 } from "util";
17018
17046
  var execFileAsync9 = promisify10(execFile10);
17019
17047
  var TIMEOUT_MS = 15e3;
17020
17048
  function findOxfmtScript(root2) {
17021
17049
  let dir = root2;
17022
17050
  for (; ; ) {
17023
- const candidate = join41(dir, "node_modules", "oxfmt", "bin", "oxfmt");
17051
+ const candidate = join42(dir, "node_modules", "oxfmt", "bin", "oxfmt");
17024
17052
  if (existsSync40(candidate)) return candidate;
17025
17053
  const parent = dirname24(dir);
17026
17054
  if (parent === dir) return void 0;
@@ -17472,6 +17500,7 @@ async function web(options2) {
17472
17500
  };
17473
17501
  attachSessionSocket(server, ctx);
17474
17502
  installRestartMenu();
17503
+ sweepStagedAttachments();
17475
17504
  streamDaemonLogs();
17476
17505
  void ensureDaemonRunning("web server start").catch((error) => {
17477
17506
  console.error(
@@ -18548,12 +18577,12 @@ function findCliWrite(command) {
18548
18577
  // src/shared/readSettingsPerms.ts
18549
18578
  import { existsSync as existsSync42, readFileSync as readFileSync27 } from "fs";
18550
18579
  import { homedir as homedir16 } from "os";
18551
- import { join as join42 } from "path";
18580
+ import { join as join43 } from "path";
18552
18581
  function readSettingsPerms(key) {
18553
18582
  const paths = [
18554
- join42(homedir16(), ".claude", "settings.json"),
18555
- join42(process.cwd(), ".claude", "settings.json"),
18556
- join42(process.cwd(), ".claude", "settings.local.json")
18583
+ join43(homedir16(), ".claude", "settings.json"),
18584
+ join43(process.cwd(), ".claude", "settings.json"),
18585
+ join43(process.cwd(), ".claude", "settings.local.json")
18557
18586
  ];
18558
18587
  const entries = [];
18559
18588
  for (const p of paths) {
@@ -18777,11 +18806,11 @@ function decideCommand(toolName, rawCommand) {
18777
18806
  // src/commands/cliHook/logDeniedToolCall.ts
18778
18807
  import { mkdirSync as mkdirSync12 } from "fs";
18779
18808
  import { homedir as homedir17 } from "os";
18780
- import { join as join43 } from "path";
18809
+ import { join as join44 } from "path";
18781
18810
  import Database from "better-sqlite3";
18782
18811
  var _db;
18783
18812
  function getDbDir() {
18784
- return join43(homedir17(), ".assist");
18813
+ return join44(homedir17(), ".assist");
18785
18814
  }
18786
18815
  function initSchema(db) {
18787
18816
  db.exec(`
@@ -18800,7 +18829,7 @@ function openPromptsDb(dir) {
18800
18829
  if (_db) return _db;
18801
18830
  const dbDir = dir ?? getDbDir();
18802
18831
  mkdirSync12(dbDir, { recursive: true });
18803
- const db = new Database(join43(dbDir, "assist.db"));
18832
+ const db = new Database(join44(dbDir, "assist.db"));
18804
18833
  db.pragma("journal_mode = WAL");
18805
18834
  initSchema(db);
18806
18835
  _db = db;
@@ -18921,7 +18950,7 @@ ${reasons.join("\n")}`);
18921
18950
  // src/commands/permitCliReads.ts
18922
18951
  import { existsSync as existsSync43, mkdirSync as mkdirSync13, readFileSync as readFileSync28, writeFileSync as writeFileSync23 } from "fs";
18923
18952
  import { homedir as homedir18 } from "os";
18924
- import { join as join44 } from "path";
18953
+ import { join as join45 } from "path";
18925
18954
 
18926
18955
  // src/commands/permitCliReads/assertCliExists.ts
18927
18956
  function assertCliExists(cli) {
@@ -19184,7 +19213,7 @@ function updateSettings(cli, commands) {
19184
19213
  // src/commands/permitCliReads.ts
19185
19214
  function logPath(cli) {
19186
19215
  const safeName = cli.replace(/\s+/g, "-");
19187
- return join44(homedir18(), ".assist", `cli-discover-${safeName}.log`);
19216
+ return join45(homedir18(), ".assist", `cli-discover-${safeName}.log`);
19188
19217
  }
19189
19218
  function readCache(cli) {
19190
19219
  const path106 = logPath(cli);
@@ -19192,7 +19221,7 @@ function readCache(cli) {
19192
19221
  return readFileSync28(path106, "utf8");
19193
19222
  }
19194
19223
  function writeCache(cli, output) {
19195
- const dir = join44(homedir18(), ".assist");
19224
+ const dir = join45(homedir18(), ".assist");
19196
19225
  mkdirSync13(dir, { recursive: true });
19197
19226
  writeFileSync23(logPath(cli), output);
19198
19227
  }
@@ -19357,30 +19386,30 @@ function isHashCommentFile(filePath) {
19357
19386
 
19358
19387
  // src/commands/codeComment/getRestrictedDir.ts
19359
19388
  import { homedir as homedir19 } from "os";
19360
- import { join as join45 } from "path";
19389
+ import { join as join46 } from "path";
19361
19390
  function getRestrictedDir() {
19362
- return join45(homedir19(), ".assist", "restricted");
19391
+ return join46(homedir19(), ".assist", "restricted");
19363
19392
  }
19364
19393
  function getPinStatePath(pin2) {
19365
- return join45(getRestrictedDir(), `code-comment-${pin2}.json`);
19394
+ return join46(getRestrictedDir(), `code-comment-${pin2}.json`);
19366
19395
  }
19367
19396
 
19368
19397
  // src/commands/codeComment/sweepRestrictedDir.ts
19369
- import { readdirSync as readdirSync5, statSync as statSync7, unlinkSync as unlinkSync7 } from "fs";
19370
- import { join as join46 } from "path";
19398
+ import { readdirSync as readdirSync6, statSync as statSync8, unlinkSync as unlinkSync7 } from "fs";
19399
+ import { join as join47 } from "path";
19371
19400
  var STALE_AFTER_MS = 30 * 60 * 1e3;
19372
19401
  function sweepRestrictedDir(dir = getRestrictedDir()) {
19373
19402
  let entries;
19374
19403
  try {
19375
- entries = readdirSync5(dir);
19404
+ entries = readdirSync6(dir);
19376
19405
  } catch {
19377
19406
  return;
19378
19407
  }
19379
19408
  const cutoff = Date.now() - STALE_AFTER_MS;
19380
19409
  for (const entry of entries) {
19381
- const path106 = join46(dir, entry);
19410
+ const path106 = join47(dir, entry);
19382
19411
  try {
19383
- if (statSync7(path106).mtimeMs < cutoff) unlinkSync7(path106);
19412
+ if (statSync8(path106).mtimeMs < cutoff) unlinkSync7(path106);
19384
19413
  } catch {
19385
19414
  continue;
19386
19415
  }
@@ -21032,18 +21061,18 @@ import chalk137 from "chalk";
21032
21061
 
21033
21062
  // src/commands/criteriaExtension/criteriaExtensionDir.ts
21034
21063
  import { existsSync as existsSync46 } from "fs";
21035
- import { dirname as dirname26, join as join47 } from "path";
21064
+ import { dirname as dirname26, join as join48 } from "path";
21036
21065
  import { fileURLToPath as fileURLToPath6 } from "url";
21037
21066
  var moduleDir = dirname26(fileURLToPath6(import.meta.url));
21038
21067
  function criteriaExtensionDir() {
21039
- const bundled = join47(
21068
+ const bundled = join48(
21040
21069
  moduleDir,
21041
21070
  "commands",
21042
21071
  "criteriaExtension",
21043
21072
  "criteria-extension"
21044
21073
  );
21045
21074
  if (existsSync46(bundled)) return bundled;
21046
- return join47(moduleDir, "..", "..", "..", "criteria-extension");
21075
+ return join48(moduleDir, "..", "..", "..", "criteria-extension");
21047
21076
  }
21048
21077
 
21049
21078
  // src/commands/criteriaExtension/criteriaExtension.ts
@@ -21072,15 +21101,15 @@ async function criteriaExtension() {
21072
21101
  // src/commands/criteriaExtension/signCriteriaExtension.ts
21073
21102
  import { rm as rm2 } from "fs/promises";
21074
21103
  import { homedir as homedir20, tmpdir as tmpdir3 } from "os";
21075
- import { join as join53 } from "path";
21104
+ import { join as join54 } from "path";
21076
21105
  import chalk139 from "chalk";
21077
21106
 
21078
21107
  // src/commands/criteriaExtension/copySignedXpi.ts
21079
21108
  import { copyFile } from "fs/promises";
21080
- import { join as join48 } from "path";
21109
+ import { join as join49 } from "path";
21081
21110
  var SIGNED_XPI_NAME = "criteria-extension.xpi";
21082
21111
  async function copySignedXpi(xpi, dir) {
21083
- const fixed2 = join48(dir, SIGNED_XPI_NAME);
21112
+ const fixed2 = join49(dir, SIGNED_XPI_NAME);
21084
21113
  if (fixed2 === xpi) return fixed2;
21085
21114
  await copyFile(xpi, fixed2);
21086
21115
  return fixed2;
@@ -21089,11 +21118,11 @@ async function copySignedXpi(xpi, dir) {
21089
21118
  // src/commands/criteriaExtension/findSignedXpi.ts
21090
21119
  import { existsSync as existsSync47 } from "fs";
21091
21120
  import { readdir } from "fs/promises";
21092
- import { join as join49 } from "path";
21121
+ import { join as join50 } from "path";
21093
21122
  async function findSignedXpi(dir) {
21094
21123
  if (!existsSync47(dir)) return null;
21095
21124
  const name = (await readdir(dir)).find((entry) => entry.endsWith(".xpi"));
21096
- return name ? join49(dir, name) : null;
21125
+ return name ? join50(dir, name) : null;
21097
21126
  }
21098
21127
 
21099
21128
  // src/commands/criteriaExtension/signedAddonInstallPath.ts
@@ -21116,10 +21145,10 @@ async function signedAddonInstallPath(xpi) {
21116
21145
 
21117
21146
  // src/commands/criteriaExtension/signPreflightProblem.ts
21118
21147
  import { existsSync as existsSync48 } from "fs";
21119
- import { join as join50 } from "path";
21148
+ import { join as join51 } from "path";
21120
21149
  var KEY_URL = "https://addons.mozilla.org/en-US/developers/addon/api/key/";
21121
21150
  function signPreflightProblem(source) {
21122
- if (!existsSync48(join50(source, "content.js")))
21151
+ if (!existsSync48(join51(source, "content.js")))
21123
21152
  return {
21124
21153
  message: `no content.js in ${source}`,
21125
21154
  hint: "run npm run build to bundle the content script"
@@ -21134,7 +21163,7 @@ function signPreflightProblem(source) {
21134
21163
 
21135
21164
  // src/commands/criteriaExtension/stageCriteriaExtension.ts
21136
21165
  import { cp as cp3, mkdir as mkdir5, readFile as readFile4, rm, writeFile as writeFile4 } from "fs/promises";
21137
- import { basename as basename13, join as join51 } from "path";
21166
+ import { basename as basename13, join as join52 } from "path";
21138
21167
 
21139
21168
  // src/commands/criteriaExtension/stampManifestVersion.ts
21140
21169
  function stampManifestVersion(manifest, version2) {
@@ -21151,7 +21180,7 @@ async function stageCriteriaExtension(source, staging, version2) {
21151
21180
  recursive: true,
21152
21181
  filter: (path106) => basename13(path106) !== "updates.json"
21153
21182
  });
21154
- const manifest = join51(staging, "manifest.json");
21183
+ const manifest = join52(staging, "manifest.json");
21155
21184
  const stamped = stampManifestVersion(
21156
21185
  await readFile4(manifest, "utf8"),
21157
21186
  version2
@@ -21161,7 +21190,7 @@ async function stageCriteriaExtension(source, staging, version2) {
21161
21190
 
21162
21191
  // src/commands/criteriaExtension/writeUpdateManifest.ts
21163
21192
  import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
21164
- import { join as join52 } from "path";
21193
+ import { join as join53 } from "path";
21165
21194
 
21166
21195
  // src/commands/criteriaExtension/buildUpdateManifest.ts
21167
21196
  var RELEASE_DOWNLOAD_URL = "https://github.com/staff0rd/assist/releases/download";
@@ -21186,17 +21215,17 @@ function buildUpdateManifest(manifest, version2) {
21186
21215
  // src/commands/criteriaExtension/writeUpdateManifest.ts
21187
21216
  async function writeUpdateManifest(source, dir, version2) {
21188
21217
  await writeFile5(
21189
- join52(dir, "updates.json"),
21218
+ join53(dir, "updates.json"),
21190
21219
  buildUpdateManifest(
21191
- await readFile5(join52(source, "manifest.json"), "utf8"),
21220
+ await readFile5(join53(source, "manifest.json"), "utf8"),
21192
21221
  version2
21193
21222
  )
21194
21223
  );
21195
21224
  }
21196
21225
 
21197
21226
  // src/commands/criteriaExtension/signCriteriaExtension.ts
21198
- var ARTIFACTS_DIR = join53(homedir20(), ".assist", "criteria-extension");
21199
- var STAGING_DIR = join53(tmpdir3(), "assist-criteria-extension");
21227
+ var ARTIFACTS_DIR = join54(homedir20(), ".assist", "criteria-extension");
21228
+ var STAGING_DIR = join54(tmpdir3(), "assist-criteria-extension");
21200
21229
  async function signCriteriaExtension() {
21201
21230
  const source = criteriaExtensionDir();
21202
21231
  const problem = signPreflightProblem(source);
@@ -21380,12 +21409,12 @@ import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync26 } from "fs"
21380
21409
  import chalk142 from "chalk";
21381
21410
 
21382
21411
  // src/commands/dbMigration/getMigrationPinPath.ts
21383
- import { join as join54 } from "path";
21412
+ import { join as join55 } from "path";
21384
21413
  function getMigrationPinPath(pin2) {
21385
- return join54(getRestrictedDir(), `db-migration-pin-${pin2}.json`);
21414
+ return join55(getRestrictedDir(), `db-migration-pin-${pin2}.json`);
21386
21415
  }
21387
21416
  function getMigrationApprovalPath(migrationId) {
21388
- return join54(getRestrictedDir(), `db-migration-approval-${migrationId}.json`);
21417
+ return join55(getRestrictedDir(), `db-migration-approval-${migrationId}.json`);
21389
21418
  }
21390
21419
 
21391
21420
  // src/commands/dbMigration/readMigrationPinState.ts
@@ -21523,10 +21552,10 @@ import { basename as basename15 } from "path";
21523
21552
 
21524
21553
  // src/commands/devlog/loadBlogSkipDays.ts
21525
21554
  import { homedir as homedir21 } from "os";
21526
- import { join as join55 } from "path";
21527
- var BLOG_REPO_ROOT = join55(homedir21(), "git/blog");
21555
+ import { join as join56 } from "path";
21556
+ var BLOG_REPO_ROOT = join56(homedir21(), "git/blog");
21528
21557
  function loadBlogSkipDays(repoName) {
21529
- const config = loadRawYaml(join55(BLOG_REPO_ROOT, "assist.yml"));
21558
+ const config = loadRawYaml(join56(BLOG_REPO_ROOT, "assist.yml"));
21530
21559
  const devlog = config.devlog;
21531
21560
  const skip2 = devlog?.skip;
21532
21561
  return new Set(skip2?.[repoName]);
@@ -21538,13 +21567,13 @@ import chalk145 from "chalk";
21538
21567
 
21539
21568
  // src/shared/getRepoName.ts
21540
21569
  import { existsSync as existsSync51, readFileSync as readFileSync33 } from "fs";
21541
- import { basename as basename14, join as join56 } from "path";
21570
+ import { basename as basename14, join as join57 } from "path";
21542
21571
  function getRepoName() {
21543
21572
  const config = loadConfig();
21544
21573
  if (config.devlog?.name) {
21545
21574
  return config.devlog.name;
21546
21575
  }
21547
- const packageJsonPath = join56(process.cwd(), "package.json");
21576
+ const packageJsonPath = join57(process.cwd(), "package.json");
21548
21577
  if (existsSync51(packageJsonPath)) {
21549
21578
  try {
21550
21579
  const content = readFileSync33(packageJsonPath, "utf8");
@@ -21559,9 +21588,9 @@ function getRepoName() {
21559
21588
  }
21560
21589
 
21561
21590
  // src/commands/devlog/loadDevlogEntries.ts
21562
- import { readdirSync as readdirSync6, readFileSync as readFileSync34 } from "fs";
21563
- import { join as join57 } from "path";
21564
- var DEVLOG_DIR = join57(BLOG_REPO_ROOT, "src/content/devlog");
21591
+ import { readdirSync as readdirSync7, readFileSync as readFileSync34 } from "fs";
21592
+ import { join as join58 } from "path";
21593
+ var DEVLOG_DIR = join58(BLOG_REPO_ROOT, "src/content/devlog");
21565
21594
  function extractFrontmatter(content) {
21566
21595
  const fm = content.match(/^---\n([\s\S]*?)\n---/);
21567
21596
  return fm?.[1] ?? null;
@@ -21587,9 +21616,9 @@ function parseFrontmatter(content, filename) {
21587
21616
  }
21588
21617
  function readDevlogFiles(callback) {
21589
21618
  try {
21590
- const files = readdirSync6(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
21619
+ const files = readdirSync7(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
21591
21620
  for (const file of files) {
21592
- const content = readFileSync34(join57(DEVLOG_DIR, file), "utf8");
21621
+ const content = readFileSync34(join58(DEVLOG_DIR, file), "utf8");
21593
21622
  const parsed = parseFrontmatter(content, file);
21594
21623
  if (parsed) callback(parsed);
21595
21624
  }
@@ -21977,11 +22006,11 @@ function repos(options2) {
21977
22006
 
21978
22007
  // src/commands/devlog/skip.ts
21979
22008
  import { writeFileSync as writeFileSync29 } from "fs";
21980
- import { join as join58 } from "path";
22009
+ import { join as join59 } from "path";
21981
22010
  import chalk150 from "chalk";
21982
22011
  import { stringify as stringifyYaml3 } from "yaml";
21983
22012
  function getBlogConfigPath() {
21984
- return join58(BLOG_REPO_ROOT, "assist.yml");
22013
+ return join59(BLOG_REPO_ROOT, "assist.yml");
21985
22014
  }
21986
22015
  function skip(date) {
21987
22016
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
@@ -22042,20 +22071,20 @@ function registerDevlog(program2) {
22042
22071
  }
22043
22072
 
22044
22073
  // src/commands/dotnet/checkBuildLocks.ts
22045
- import { closeSync as closeSync4, openSync as openSync5, readdirSync as readdirSync7 } from "fs";
22046
- import { join as join59 } from "path";
22074
+ import { closeSync as closeSync4, openSync as openSync5, readdirSync as readdirSync8 } from "fs";
22075
+ import { join as join60 } from "path";
22047
22076
  import chalk152 from "chalk";
22048
22077
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
22049
22078
  function isLockedDll(debugDir) {
22050
22079
  let files;
22051
22080
  try {
22052
- files = readdirSync7(debugDir, { recursive: true });
22081
+ files = readdirSync8(debugDir, { recursive: true });
22053
22082
  } catch {
22054
22083
  return null;
22055
22084
  }
22056
22085
  for (const file of files) {
22057
22086
  if (!file.toLowerCase().endsWith(".dll")) continue;
22058
- const dllPath = join59(debugDir, file);
22087
+ const dllPath = join60(debugDir, file);
22059
22088
  try {
22060
22089
  const fd = openSync5(dllPath, "r+");
22061
22090
  closeSync4(fd);
@@ -22068,18 +22097,18 @@ function isLockedDll(debugDir) {
22068
22097
  function findFirstLockedDll(dir) {
22069
22098
  let entries;
22070
22099
  try {
22071
- entries = readdirSync7(dir);
22100
+ entries = readdirSync8(dir);
22072
22101
  } catch {
22073
22102
  return null;
22074
22103
  }
22075
22104
  if (entries.includes("bin")) {
22076
- const locked = isLockedDll(join59(dir, "bin", "Debug"));
22105
+ const locked = isLockedDll(join60(dir, "bin", "Debug"));
22077
22106
  if (locked) return locked;
22078
22107
  }
22079
22108
  for (const entry of entries) {
22080
22109
  if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
22081
22110
  continue;
22082
- const found = findFirstLockedDll(join59(dir, entry));
22111
+ const found = findFirstLockedDll(join60(dir, entry));
22083
22112
  if (found) return found;
22084
22113
  }
22085
22114
  return null;
@@ -22148,14 +22177,14 @@ function collectAllDeps(node) {
22148
22177
  }
22149
22178
 
22150
22179
  // src/commands/dotnet/findContainingSolutions.ts
22151
- import { readdirSync as readdirSync8, readFileSync as readFileSync36, statSync as statSync8 } from "fs";
22180
+ import { readdirSync as readdirSync9, readFileSync as readFileSync36, statSync as statSync9 } from "fs";
22152
22181
  import path35 from "path";
22153
22182
  function findSlnFiles(dir, maxDepth, depth = 0) {
22154
22183
  if (depth > maxDepth) return [];
22155
22184
  const results = [];
22156
22185
  let entries;
22157
22186
  try {
22158
- entries = readdirSync8(dir);
22187
+ entries = readdirSync9(dir);
22159
22188
  } catch {
22160
22189
  return results;
22161
22190
  }
@@ -22164,7 +22193,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
22164
22193
  continue;
22165
22194
  const full = path35.join(dir, entry);
22166
22195
  try {
22167
- const stat5 = statSync8(full);
22196
+ const stat5 = statSync9(full);
22168
22197
  if (stat5.isFile() && entry.endsWith(".sln")) {
22169
22198
  results.push(full);
22170
22199
  } else if (stat5.isDirectory()) {
@@ -22425,12 +22454,12 @@ import path37 from "path";
22425
22454
  import chalk158 from "chalk";
22426
22455
 
22427
22456
  // src/commands/dotnet/findSolution.ts
22428
- import { readdirSync as readdirSync9 } from "fs";
22429
- import { dirname as dirname27, join as join60 } from "path";
22457
+ import { readdirSync as readdirSync10 } from "fs";
22458
+ import { dirname as dirname27, join as join61 } from "path";
22430
22459
  import chalk157 from "chalk";
22431
22460
  function findSlnInDir(dir) {
22432
22461
  try {
22433
- return readdirSync9(dir).filter((f) => f.endsWith(".sln")).map((f) => join60(dir, f));
22462
+ return readdirSync10(dir).filter((f) => f.endsWith(".sln")).map((f) => join61(dir, f));
22434
22463
  } catch {
22435
22464
  return [];
22436
22465
  }
@@ -23425,7 +23454,7 @@ function aggregateCommitters(authorLists) {
23425
23454
  import { spawnSync as spawnSync6 } from "child_process";
23426
23455
  import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
23427
23456
  import { tmpdir as tmpdir5 } from "os";
23428
- import { join as join61 } from "path";
23457
+ import { join as join62 } from "path";
23429
23458
  function buildArgs2(queryFile, vars) {
23430
23459
  const args = ["api", "graphql", "-F", `query=@${queryFile}`];
23431
23460
  for (const [key, value] of Object.entries(vars)) {
@@ -23435,7 +23464,7 @@ function buildArgs2(queryFile, vars) {
23435
23464
  return args;
23436
23465
  }
23437
23466
  function runGhGraphql(mutation, vars) {
23438
- const queryFile = join61(tmpdir5(), `gh-query-${Date.now()}.graphql`);
23467
+ const queryFile = join62(tmpdir5(), `gh-query-${Date.now()}.graphql`);
23439
23468
  writeFileSync30(queryFile, mutation);
23440
23469
  try {
23441
23470
  const result = spawnSync6("gh", buildArgs2(queryFile, vars), {
@@ -24608,10 +24637,7 @@ async function reviewProposedIssue(title, body, metadata2 = []) {
24608
24637
 
24609
24638
  // src/commands/prs/attachArgs.ts
24610
24639
  function attachArgs(attachments) {
24611
- return attachments.flatMap(({ path: path106, alt }) => [
24612
- "--attach",
24613
- alt ? `${path106}#${alt}` : path106
24614
- ]);
24640
+ return attachments.flatMap(({ path: path106 }) => ["--attach", path106]);
24615
24641
  }
24616
24642
 
24617
24643
  // src/commands/prs/runGhWithAttachments.ts
@@ -24619,13 +24645,13 @@ import { execFileSync as execFileSync9 } from "child_process";
24619
24645
  import { basename as basename16 } from "path";
24620
24646
 
24621
24647
  // src/shared/removeStagedAttachments.ts
24622
- import { rmSync as rmSync3 } from "fs";
24648
+ import { rmSync as rmSync4 } from "fs";
24623
24649
  import { dirname as dirname28 } from "path";
24624
24650
  function removeStagedAttachments(attachments) {
24625
24651
  for (const { path: path106 } of attachments) {
24626
24652
  const dir = dirname28(path106);
24627
24653
  if (!isStagedAttachmentPath(dir)) continue;
24628
- rmSync3(dir, { recursive: true, force: true });
24654
+ rmSync4(dir, { recursive: true, force: true });
24629
24655
  }
24630
24656
  }
24631
24657
 
@@ -24783,14 +24809,14 @@ function fetchIssue2(number, repo) {
24783
24809
  import { existsSync as existsSync56, readFileSync as readFileSync38 } from "fs";
24784
24810
 
24785
24811
  // src/commands/github/issue/issueWorkingFile.ts
24786
- import { join as join62 } from "path";
24812
+ import { join as join63 } from "path";
24787
24813
  function issueWorkingFile(slug2, number) {
24788
24814
  const [owner = "unknown", repo = "unknown"] = slug2.split("/");
24789
- const dir = join62(getStoreDir(), "github-issues", owner, repo);
24815
+ const dir = join63(getStoreDir(), "github-issues", owner, repo);
24790
24816
  return {
24791
24817
  dir,
24792
- bodyPath: join62(dir, `${number}.md`),
24793
- metaPath: join62(dir, `${number}.json`)
24818
+ bodyPath: join63(dir, `${number}.md`),
24819
+ metaPath: join63(dir, `${number}.json`)
24794
24820
  };
24795
24821
  }
24796
24822
 
@@ -25433,14 +25459,14 @@ import { existsSync as existsSync57 } from "fs";
25433
25459
  import { basename as basename18, dirname as dirname29 } from "path";
25434
25460
 
25435
25461
  // src/commands/sessions/daemon/worktree/planAllocation.ts
25436
- import { basename as basename17, join as join63 } from "path";
25462
+ import { basename as basename17, join as join64 } from "path";
25437
25463
  function planAllocation(clone, boundTreeRoots2) {
25438
25464
  return boundTreeRoots2.has(clone) ? "spill" : "primary";
25439
25465
  }
25440
25466
  function nextWorktreePath(clone, base, isTaken) {
25441
25467
  const name = basename17(clone);
25442
25468
  for (let n = 2; n < 1e3; n++) {
25443
- const candidate = join63(base, `${name}-${n}`);
25469
+ const candidate = join64(base, `${name}-${n}`);
25444
25470
  if (!isTaken(candidate)) return candidate;
25445
25471
  }
25446
25472
  throw new Error(`no free worktree suffix for ${clone}`);
@@ -25794,19 +25820,19 @@ function persistedTreeRoots() {
25794
25820
 
25795
25821
  // src/commands/sessions/daemon/worktree/seedWorktree.ts
25796
25822
  import { copyFileSync, existsSync as existsSync60, mkdirSync as mkdirSync17 } from "fs";
25797
- import { dirname as dirname30, join as join65 } from "path";
25823
+ import { dirname as dirname30, join as join66 } from "path";
25798
25824
 
25799
25825
  // src/commands/sessions/daemon/worktree/runInstall.ts
25800
25826
  import { resolve as resolve17 } from "path";
25801
25827
 
25802
25828
  // src/commands/sessions/daemon/worktree/detectInstallCommand.ts
25803
25829
  import { existsSync as existsSync59 } from "fs";
25804
- import { join as join64 } from "path";
25830
+ import { join as join65 } from "path";
25805
25831
  function detectInstallCommand(dir) {
25806
- if (!existsSync59(join64(dir, "package.json"))) return null;
25807
- if (existsSync59(join64(dir, "pnpm-lock.yaml"))) return "pnpm install";
25808
- if (existsSync59(join64(dir, "yarn.lock"))) return "yarn install";
25809
- if (existsSync59(join64(dir, "bun.lockb"))) return "bun install";
25832
+ if (!existsSync59(join65(dir, "package.json"))) return null;
25833
+ if (existsSync59(join65(dir, "pnpm-lock.yaml"))) return "pnpm install";
25834
+ if (existsSync59(join65(dir, "yarn.lock"))) return "yarn install";
25835
+ if (existsSync59(join65(dir, "bun.lockb"))) return "bun install";
25810
25836
  return "npm install";
25811
25837
  }
25812
25838
 
@@ -25968,9 +25994,9 @@ function seedWorktree(worktreePath, clone, onSeeded = () => {
25968
25994
  }
25969
25995
  function copyConfigFiles(worktreePath, clone, copy) {
25970
25996
  for (const rel of copy) {
25971
- const src = join65(clone, rel);
25997
+ const src = join66(clone, rel);
25972
25998
  if (!existsSync60(src)) continue;
25973
- const dest = join65(worktreePath, rel);
25999
+ const dest = join66(worktreePath, rel);
25974
26000
  try {
25975
26001
  mkdirSync17(dirname30(dest), { recursive: true });
25976
26002
  copyFileSync(src, dest);
@@ -26274,7 +26300,7 @@ function registerLitellm(program2) {
26274
26300
  }
26275
26301
 
26276
26302
  // src/commands/mermaidExport.ts
26277
- import { mkdirSync as mkdirSync18, readdirSync as readdirSync10 } from "fs";
26303
+ import { mkdirSync as mkdirSync18, readdirSync as readdirSync11 } from "fs";
26278
26304
  import { resolve as resolve19 } from "path";
26279
26305
  import chalk174 from "chalk";
26280
26306
 
@@ -26356,7 +26382,7 @@ async function mermaidExport(file, options2 = {}) {
26356
26382
  process.exit(1);
26357
26383
  }
26358
26384
  }
26359
- const files = file ? [file] : readdirSync10(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
26385
+ const files = file ? [file] : readdirSync11(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
26360
26386
  if (files.length === 0) {
26361
26387
  console.log(chalk174.gray("No markdown files found in current directory."));
26362
26388
  return;
@@ -27004,15 +27030,15 @@ function createNetcapHandler(options2) {
27004
27030
  // src/commands/netcap/prepareExtensionForLoad.ts
27005
27031
  import { cp as cp4, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
27006
27032
  import { networkInterfaces } from "os";
27007
- import { join as join67 } from "path";
27033
+ import { join as join68 } from "path";
27008
27034
  import chalk177 from "chalk";
27009
27035
 
27010
27036
  // src/commands/netcap/netcapExtensionDir.ts
27011
- import { dirname as dirname32, join as join66 } from "path";
27037
+ import { dirname as dirname32, join as join67 } from "path";
27012
27038
  import { fileURLToPath as fileURLToPath7 } from "url";
27013
27039
  var moduleDir2 = dirname32(fileURLToPath7(import.meta.url));
27014
27040
  function netcapExtensionDir() {
27015
- return join66(moduleDir2, "commands", "netcap", "netcap-extension");
27041
+ return join67(moduleDir2, "commands", "netcap", "netcap-extension");
27016
27042
  }
27017
27043
 
27018
27044
  // src/commands/netcap/prepareExtensionForLoad.ts
@@ -27027,7 +27053,7 @@ function lanIPv4() {
27027
27053
  return void 0;
27028
27054
  }
27029
27055
  async function configureBackground(dir, host, port, filter) {
27030
- const file = join67(dir, "background.js");
27056
+ const file = join68(dir, "background.js");
27031
27057
  const source = await readFile6(file, "utf8");
27032
27058
  await writeFile6(
27033
27059
  file,
@@ -27067,20 +27093,20 @@ async function prepareExtensionForLoad(port, filter = "") {
27067
27093
  }
27068
27094
 
27069
27095
  // src/commands/netcap/resolveNetcapOutPath.ts
27070
- import { isAbsolute as isAbsolute5, join as join69, resolve as resolve21 } from "path";
27096
+ import { isAbsolute as isAbsolute5, join as join70, resolve as resolve21 } from "path";
27071
27097
 
27072
27098
  // src/commands/netcap/defaultCapturePath.ts
27073
27099
  import { homedir as homedir22 } from "os";
27074
- import { join as join68 } from "path";
27100
+ import { join as join69 } from "path";
27075
27101
  function defaultCapturePath() {
27076
- return join68(homedir22(), ".assist", "netcap", "capture.jsonl");
27102
+ return join69(homedir22(), ".assist", "netcap", "capture.jsonl");
27077
27103
  }
27078
27104
 
27079
27105
  // src/commands/netcap/resolveNetcapOutPath.ts
27080
27106
  function resolveNetcapOutPath(out) {
27081
27107
  if (!out) return defaultCapturePath();
27082
27108
  const dir = isAbsolute5(out) ? out : resolve21(process.cwd(), out);
27083
- return join69(dir, "capture.jsonl");
27109
+ return join70(dir, "capture.jsonl");
27084
27110
  }
27085
27111
 
27086
27112
  // src/commands/netcap/netcap.ts
@@ -27127,7 +27153,7 @@ netcap stopped \u2014 captured ${count8} ${count8 === 1 ? "entry" : "entries"} t
27127
27153
 
27128
27154
  // src/commands/netcap/netcapExtract.ts
27129
27155
  import { writeFileSync as writeFileSync34 } from "fs";
27130
- import { join as join70 } from "path";
27156
+ import { join as join71 } from "path";
27131
27157
  import chalk179 from "chalk";
27132
27158
 
27133
27159
  // src/commands/netcap/extractPostsFromCapture.ts
@@ -27572,7 +27598,7 @@ function extractPostsFromCapture(captureFile) {
27572
27598
  function netcapExtract(file) {
27573
27599
  const captureFile = file ?? defaultCapturePath();
27574
27600
  const posts = extractPostsFromCapture(captureFile);
27575
- const outFile = join70(captureFile, "..", "posts.json");
27601
+ const outFile = join71(captureFile, "..", "posts.json");
27576
27602
  writeFileSync34(outFile, `${JSON.stringify(posts, null, 2)}
27577
27603
  `);
27578
27604
  console.log(
@@ -27935,7 +27961,7 @@ import { execSync as execSync41 } from "child_process";
27935
27961
  import { execSync as execSync40 } from "child_process";
27936
27962
  import { unlinkSync as unlinkSync14, writeFileSync as writeFileSync35 } from "fs";
27937
27963
  import { tmpdir as tmpdir6 } from "os";
27938
- import { join as join72 } from "path";
27964
+ import { join as join73 } from "path";
27939
27965
 
27940
27966
  // src/commands/prs/loadCommentsCache.ts
27941
27967
  import { existsSync as existsSync62, readFileSync as readFileSync43, unlinkSync as unlinkSync13 } from "fs";
@@ -27943,9 +27969,9 @@ import { parse as parse3 } from "yaml";
27943
27969
 
27944
27970
  // src/commands/prs/commentsCachePath.ts
27945
27971
  import { homedir as homedir23 } from "os";
27946
- import { join as join71 } from "path";
27972
+ import { join as join72 } from "path";
27947
27973
  function commentsCachePath(org, repo, prNumber) {
27948
- return join71(
27974
+ return join72(
27949
27975
  homedir23(),
27950
27976
  ".assist",
27951
27977
  "pr-comments",
@@ -27994,7 +28020,7 @@ function replyToComment(org, repo, prNumber, commentId, message3) {
27994
28020
  // src/commands/prs/resolveCommentWithReply.ts
27995
28021
  function resolveThread(threadId) {
27996
28022
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
27997
- const queryFile = join72(tmpdir6(), `gh-mutation-${Date.now()}.graphql`);
28023
+ const queryFile = join73(tmpdir6(), `gh-mutation-${Date.now()}.graphql`);
27998
28024
  writeFileSync35(queryFile, mutation);
27999
28025
  try {
28000
28026
  execSync40(
@@ -28079,10 +28105,10 @@ function fixed(commentId, sha) {
28079
28105
  import { execSync as execSync42 } from "child_process";
28080
28106
  import { unlinkSync as unlinkSync15, writeFileSync as writeFileSync36 } from "fs";
28081
28107
  import { tmpdir as tmpdir7 } from "os";
28082
- import { join as join73 } from "path";
28108
+ import { join as join74 } from "path";
28083
28109
  var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
28084
28110
  function fetchThreadIds(org, repo, prNumber) {
28085
- const queryFile = join73(tmpdir7(), `gh-query-${Date.now()}.graphql`);
28111
+ const queryFile = join74(tmpdir7(), `gh-query-${Date.now()}.graphql`);
28086
28112
  writeFileSync36(queryFile, THREAD_QUERY);
28087
28113
  try {
28088
28114
  const result = execSync42(
@@ -28156,19 +28182,19 @@ import { dirname as dirname34 } from "path";
28156
28182
  import { stringify as stringify3 } from "yaml";
28157
28183
 
28158
28184
  // src/commands/prs/removeStaleCommentsCaches.ts
28159
- import { readdirSync as readdirSync11, unlinkSync as unlinkSync16 } from "fs";
28160
- import { join as join74 } from "path";
28185
+ import { readdirSync as readdirSync12, unlinkSync as unlinkSync16 } from "fs";
28186
+ import { join as join75 } from "path";
28161
28187
  var STALE_PATTERN = /^pr-\d+-comments\.yaml$/;
28162
28188
  function removeStaleCommentsCaches(cwd = process.cwd()) {
28163
- const dir = join74(cwd, ".assist");
28189
+ const dir = join75(cwd, ".assist");
28164
28190
  let entries;
28165
28191
  try {
28166
- entries = readdirSync11(dir);
28192
+ entries = readdirSync12(dir);
28167
28193
  } catch {
28168
28194
  return;
28169
28195
  }
28170
28196
  for (const entry of entries.filter((e) => STALE_PATTERN.test(e))) {
28171
- unlinkSync16(join74(dir, entry));
28197
+ unlinkSync16(join75(dir, entry));
28172
28198
  }
28173
28199
  }
28174
28200
 
@@ -30807,7 +30833,7 @@ async function notify() {
30807
30833
  import { execSync as execSync52 } from "child_process";
30808
30834
  import { existsSync as existsSync63, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync38 } from "fs";
30809
30835
  import { tmpdir as tmpdir8 } from "os";
30810
- import { join as join75, resolve as resolve22 } from "path";
30836
+ import { join as join76, resolve as resolve22 } from "path";
30811
30837
  import chalk204 from "chalk";
30812
30838
 
30813
30839
  // src/commands/screenshot/captureWindowPs1.ts
@@ -30944,7 +30970,7 @@ function buildOutputPath(outputDir, processName) {
30944
30970
  return resolve22(outputDir, `${processName}-${timestamp5}.png`);
30945
30971
  }
30946
30972
  function runPowerShellScript(processName, outputPath) {
30947
- const scriptPath = join75(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
30973
+ const scriptPath = join76(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
30948
30974
  writeFileSync38(scriptPath, captureWindowPs1, "utf8");
30949
30975
  try {
30950
30976
  execSync52(
@@ -31058,13 +31084,13 @@ function buildLimitsSegment(rateLimits) {
31058
31084
  }
31059
31085
 
31060
31086
  // src/commands/readGitBranch.ts
31061
- import { readFileSync as readFileSync46, statSync as statSync9 } from "fs";
31062
- import { isAbsolute as isAbsolute6, join as join76, resolve as resolve23 } from "path";
31087
+ import { readFileSync as readFileSync46, statSync as statSync10 } from "fs";
31088
+ import { isAbsolute as isAbsolute6, join as join77, resolve as resolve23 } from "path";
31063
31089
  function resolveGitDir(cwd) {
31064
- const dotGit = join76(cwd, ".git");
31090
+ const dotGit = join77(cwd, ".git");
31065
31091
  let stat5;
31066
31092
  try {
31067
- stat5 = statSync9(dotGit);
31093
+ stat5 = statSync10(dotGit);
31068
31094
  } catch {
31069
31095
  return null;
31070
31096
  }
@@ -31091,7 +31117,7 @@ function readGitBranch(cwd) {
31091
31117
  }
31092
31118
  let head;
31093
31119
  try {
31094
- head = readFileSync46(join76(gitDir, "HEAD"), "utf8");
31120
+ head = readFileSync46(join77(gitDir, "HEAD"), "utf8");
31095
31121
  } catch {
31096
31122
  return null;
31097
31123
  }
@@ -34050,12 +34076,12 @@ function fetchHighLevelPr(prNumber, repo) {
34050
34076
  import { existsSync as existsSync64, readFileSync as readFileSync47 } from "fs";
34051
34077
 
34052
34078
  // src/commands/review/highLevel/highLevelReviewPath.ts
34053
- import { join as join77 } from "path";
34079
+ import { join as join78 } from "path";
34054
34080
  function slug(value) {
34055
34081
  return value.replace(/[^\w.-]+/g, "-");
34056
34082
  }
34057
34083
  function highLevelReviewPath(repo, headRef, headSha) {
34058
- return join77(
34084
+ return join78(
34059
34085
  getStoreDir(),
34060
34086
  "high-level-reviews",
34061
34087
  slug(repo),
@@ -35079,11 +35105,11 @@ async function handlePostSynthesis(synthesisPath, prInfo, options2) {
35079
35105
  }
35080
35106
 
35081
35107
  // src/commands/review/cachedReviewerResult.ts
35082
- import { statSync as statSync10 } from "fs";
35108
+ import { statSync as statSync11 } from "fs";
35083
35109
  function cachedReviewerResult(name, outputPath) {
35084
35110
  let size;
35085
35111
  try {
35086
- size = statSync10(outputPath).size;
35112
+ size = statSync11(outputPath).size;
35087
35113
  } catch {
35088
35114
  return null;
35089
35115
  }
@@ -35131,7 +35157,7 @@ import { format } from "util";
35131
35157
 
35132
35158
  // src/commands/review/createReviewLogSink.ts
35133
35159
  import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync23 } from "fs";
35134
- import { join as join78 } from "path";
35160
+ import { join as join79 } from "path";
35135
35161
 
35136
35162
  // src/shared/stripAnsi.ts
35137
35163
  var ANSI = new RegExp(
@@ -35159,7 +35185,7 @@ function createReviewLogSink() {
35159
35185
  },
35160
35186
  attach(reviewDir) {
35161
35187
  mkdirSync23(reviewDir, { recursive: true });
35162
- logPath2 = join78(reviewDir, LOG_FILE);
35188
+ logPath2 = join79(reviewDir, LOG_FILE);
35163
35189
  const lines2 = [
35164
35190
  "",
35165
35191
  `=== ${(/* @__PURE__ */ new Date()).toISOString()} ===`,
@@ -36241,9 +36267,9 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
36241
36267
 
36242
36268
  // src/commands/review/buildReviewPaths.ts
36243
36269
  import { homedir as homedir24 } from "os";
36244
- import { basename as basename21, join as join79 } from "path";
36270
+ import { basename as basename21, join as join80 } from "path";
36245
36271
  function buildReviewPaths(repoRoot2, key) {
36246
- const reviewDir = join79(
36272
+ const reviewDir = join80(
36247
36273
  homedir24(),
36248
36274
  ".assist",
36249
36275
  "reviews",
@@ -36252,10 +36278,10 @@ function buildReviewPaths(repoRoot2, key) {
36252
36278
  );
36253
36279
  return {
36254
36280
  reviewDir,
36255
- requestPath: join79(reviewDir, "request.md"),
36256
- claudePath: join79(reviewDir, "claude.md"),
36257
- codexPath: join79(reviewDir, "codex.md"),
36258
- synthesisPath: join79(reviewDir, "synthesis.md")
36281
+ requestPath: join80(reviewDir, "request.md"),
36282
+ claudePath: join80(reviewDir, "claude.md"),
36283
+ codexPath: join80(reviewDir, "codex.md"),
36284
+ synthesisPath: join80(reviewDir, "synthesis.md")
36259
36285
  };
36260
36286
  }
36261
36287
 
@@ -36553,12 +36579,12 @@ function insertRuleBullet(content, rule) {
36553
36579
  import { readFileSync as readFileSync50 } from "fs";
36554
36580
 
36555
36581
  // src/commands/rules/findClaudeFiles.ts
36556
- import { readdirSync as readdirSync12 } from "fs";
36582
+ import { readdirSync as readdirSync13 } from "fs";
36557
36583
  import path81 from "path";
36558
36584
  var SKIP_DIRECTORIES = /* @__PURE__ */ new Set(["node_modules", "dist", "build", "coverage"]);
36559
36585
  function findClaudeFiles(dir) {
36560
36586
  const results = [];
36561
- for (const entry of readdirSync12(dir, { withFileTypes: true })) {
36587
+ for (const entry of readdirSync13(dir, { withFileTypes: true })) {
36562
36588
  if (entry.isDirectory()) {
36563
36589
  if (entry.name.startsWith(".") || SKIP_DIRECTORIES.has(entry.name))
36564
36590
  continue;
@@ -37236,12 +37262,12 @@ async function reviewProposedSlackMessage(target, body, workingPath) {
37236
37262
  }
37237
37263
 
37238
37264
  // src/commands/slack/slackWorkingFile.ts
37239
- import { join as join80 } from "path";
37265
+ import { join as join81 } from "path";
37240
37266
  function slackWorkingFile(channel, partIndex) {
37241
37267
  const slug2 = channel.replace(/^[#@]/, "").toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "channel";
37242
- const dir = join80(getStoreDir(), "slack");
37268
+ const dir = join81(getStoreDir(), "slack");
37243
37269
  const name = partIndex === void 0 ? slug2 : `${slug2}-${partIndex}`;
37244
- return { dir, bodyPath: join80(dir, `${name}.md`) };
37270
+ return { dir, bodyPath: join81(dir, `${name}.md`) };
37245
37271
  }
37246
37272
 
37247
37273
  // src/commands/slack/previewSlackThreadParts.ts
@@ -38420,21 +38446,21 @@ async function configure() {
38420
38446
  }
38421
38447
 
38422
38448
  // src/commands/transcript/list.ts
38423
- import { existsSync as existsSync76, readdirSync as readdirSync19, statSync as statSync11 } from "fs";
38424
- import { join as join92 } from "path";
38449
+ import { existsSync as existsSync76, readdirSync as readdirSync20, statSync as statSync12 } from "fs";
38450
+ import { join as join93 } from "path";
38425
38451
  function list3() {
38426
38452
  const { vttDir } = getTranscriptConfig();
38427
38453
  if (!existsSync76(vttDir)) return;
38428
- for (const entry of readdirSync19(vttDir)) {
38454
+ for (const entry of readdirSync20(vttDir)) {
38429
38455
  if (!entry.endsWith(".vtt")) continue;
38430
- if (statSync11(join92(vttDir, entry)).isDirectory()) continue;
38456
+ if (statSync12(join93(vttDir, entry)).isDirectory()) continue;
38431
38457
  console.log(entry);
38432
38458
  }
38433
38459
  }
38434
38460
 
38435
38461
  // src/commands/transcript/move.ts
38436
38462
  import { existsSync as existsSync77, mkdirSync as mkdirSync32, renameSync as renameSync2, writeFileSync as writeFileSync50 } from "fs";
38437
- import { basename as basename25, join as join93 } from "path";
38463
+ import { basename as basename25, join as join94 } from "path";
38438
38464
 
38439
38465
  // src/commands/transcript/convertVttToMarkdown.ts
38440
38466
  function convertVttToMarkdown(inputPath) {
@@ -38444,9 +38470,9 @@ function convertVttToMarkdown(inputPath) {
38444
38470
  // src/commands/transcript/move.ts
38445
38471
  var DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
38446
38472
  function archiveRawVtt(vttDir, sourcePath, filename) {
38447
- const processedDir = join93(vttDir, "processed");
38473
+ const processedDir = join94(vttDir, "processed");
38448
38474
  mkdirSync32(processedDir, { recursive: true });
38449
- renameSync2(sourcePath, join93(processedDir, filename));
38475
+ renameSync2(sourcePath, join94(processedDir, filename));
38450
38476
  }
38451
38477
  function move(file, options2) {
38452
38478
  const { date, client } = options2;
@@ -38456,19 +38482,19 @@ function move(file, options2) {
38456
38482
  }
38457
38483
  const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
38458
38484
  const filename = basename25(file);
38459
- const sourcePath = join93(vttDir, filename);
38485
+ const sourcePath = join94(vttDir, filename);
38460
38486
  if (!existsSync77(sourcePath)) {
38461
38487
  console.error(`Error: VTT file not found: ${sourcePath}`);
38462
38488
  process.exit(1);
38463
38489
  }
38464
38490
  const base = basename25(filename, ".vtt").replace(/ Transcription$/, "");
38465
38491
  const outputName = `${date} ${base}.md`;
38466
- const formattedDir = join93(transcriptsDir, client);
38492
+ const formattedDir = join94(transcriptsDir, client);
38467
38493
  mkdirSync32(formattedDir, { recursive: true });
38468
- const formattedPath = join93(formattedDir, outputName);
38494
+ const formattedPath = join94(formattedDir, outputName);
38469
38495
  writeFileSync50(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
38470
38496
  archiveRawVtt(vttDir, sourcePath, filename);
38471
- const summaryPath = join93(summaryDir, client, outputName);
38497
+ const summaryPath = join94(summaryDir, client, outputName);
38472
38498
  console.log(`Formatted transcript: ${formattedPath}`);
38473
38499
  console.log(`Summary target: ${summaryPath}`);
38474
38500
  }
@@ -39274,10 +39300,10 @@ function checkSequential(migrations3, files) {
39274
39300
  }
39275
39301
 
39276
39302
  // src/commands/verify/migrations/listMigrationFiles.ts
39277
- import { readdirSync as readdirSync20 } from "fs";
39303
+ import { readdirSync as readdirSync21 } from "fs";
39278
39304
  var MIGRATION_FILE2 = /^migration\d+[A-Za-z0-9]*\.ts$/;
39279
39305
  function listMigrationFiles(dir) {
39280
- return readdirSync20(dir).filter((file) => MIGRATION_FILE2.test(file));
39306
+ return readdirSync21(dir).filter((file) => MIGRATION_FILE2.test(file));
39281
39307
  }
39282
39308
 
39283
39309
  // src/commands/verify/migrations/readBaselineMigrations.ts
@@ -39629,11 +39655,11 @@ function changedPaths(from, cwd) {
39629
39655
  }
39630
39656
 
39631
39657
  // src/commands/watch/readBuiltVersion.ts
39632
- import { join as join94 } from "path";
39658
+ import { join as join95 } from "path";
39633
39659
  function readBuiltVersion(cwd) {
39634
39660
  try {
39635
39661
  const root2 = runGit3(["rev-parse", "--show-toplevel"], cwd);
39636
- return readPackageJson(join94(root2, "package.json")).version ?? "unknown";
39662
+ return readPackageJson(join95(root2, "package.json")).version ?? "unknown";
39637
39663
  } catch {
39638
39664
  return "unknown";
39639
39665
  }
@@ -40101,12 +40127,12 @@ ${buildWatchReport(from)}`);
40101
40127
  }
40102
40128
 
40103
40129
  // src/commands/watch/consumeSimulatedDivergence.ts
40104
- import { existsSync as existsSync81, rmSync as rmSync7 } from "fs";
40130
+ import { existsSync as existsSync81, rmSync as rmSync8 } from "fs";
40105
40131
  function consumeSimulatedDivergence(cwd) {
40106
40132
  try {
40107
40133
  const path106 = simulatedDivergencePath(cwd);
40108
40134
  if (!existsSync81(path106)) return false;
40109
- rmSync7(path106);
40135
+ rmSync8(path106);
40110
40136
  return true;
40111
40137
  } catch {
40112
40138
  return false;
@@ -40415,19 +40441,19 @@ async function auth() {
40415
40441
 
40416
40442
  // src/commands/roam/postRoamActivity.ts
40417
40443
  import { execFileSync as execFileSync22 } from "child_process";
40418
- import { readdirSync as readdirSync21, readFileSync as readFileSync62, statSync as statSync12 } from "fs";
40419
- import { join as join95 } from "path";
40444
+ import { readdirSync as readdirSync22, readFileSync as readFileSync62, statSync as statSync13 } from "fs";
40445
+ import { join as join96 } from "path";
40420
40446
  function findPortFile(roamDir) {
40421
40447
  let entries;
40422
40448
  try {
40423
- entries = readdirSync21(roamDir);
40449
+ entries = readdirSync22(roamDir);
40424
40450
  } catch {
40425
40451
  return void 0;
40426
40452
  }
40427
40453
  const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
40428
- const path106 = join95(roamDir, name);
40454
+ const path106 = join96(roamDir, name);
40429
40455
  try {
40430
- return { path: path106, mtimeMs: statSync12(path106).mtimeMs };
40456
+ return { path: path106, mtimeMs: statSync13(path106).mtimeMs };
40431
40457
  } catch {
40432
40458
  return void 0;
40433
40459
  }
@@ -40442,7 +40468,7 @@ var PID_BY_APP = {
40442
40468
  function postRoamActivity(app, event) {
40443
40469
  const appData = process.env.APPDATA;
40444
40470
  if (!appData) return;
40445
- const portFile = findPortFile(join95(appData, "Roam"));
40471
+ const portFile = findPortFile(join96(appData, "Roam"));
40446
40472
  if (!portFile) return;
40447
40473
  let port;
40448
40474
  try {
@@ -40578,7 +40604,7 @@ async function run3(name, args) {
40578
40604
 
40579
40605
  // src/commands/run/add.ts
40580
40606
  import { mkdirSync as mkdirSync33, writeFileSync as writeFileSync53 } from "fs";
40581
- import { join as join96 } from "path";
40607
+ import { join as join97 } from "path";
40582
40608
 
40583
40609
  // src/commands/run/extractOption.ts
40584
40610
  function extractOption(args, flag) {
@@ -40639,7 +40665,7 @@ function saveNewRunConfig(name, command, args, cwd) {
40639
40665
  saveConfig(config);
40640
40666
  }
40641
40667
  function createCommandFile(name) {
40642
- const dir = join96(".claude", "commands");
40668
+ const dir = join97(".claude", "commands");
40643
40669
  mkdirSync33(dir, { recursive: true });
40644
40670
  const content = `---
40645
40671
  description: Run ${name}
@@ -40647,7 +40673,7 @@ description: Run ${name}
40647
40673
 
40648
40674
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
40649
40675
  `;
40650
- const filePath = join96(dir, `${name}.md`);
40676
+ const filePath = join97(dir, `${name}.md`);
40651
40677
  writeFileSync53(filePath, content);
40652
40678
  console.log(`Created command file: ${filePath}`);
40653
40679
  }
@@ -40704,7 +40730,7 @@ function link2() {
40704
40730
 
40705
40731
  // src/commands/run/remove.ts
40706
40732
  import { existsSync as existsSync82, unlinkSync as unlinkSync21 } from "fs";
40707
- import { join as join97 } from "path";
40733
+ import { join as join98 } from "path";
40708
40734
  function findRemoveIndex() {
40709
40735
  const idx = process.argv.indexOf("remove");
40710
40736
  if (idx === -1 || idx + 1 >= process.argv.length) return -1;
@@ -40719,7 +40745,7 @@ function parseRemoveName() {
40719
40745
  return process.argv[idx + 1];
40720
40746
  }
40721
40747
  function deleteCommandFile(name) {
40722
- const filePath = join97(".claude", "commands", `${name}.md`);
40748
+ const filePath = join98(".claude", "commands", `${name}.md`);
40723
40749
  if (existsSync82(filePath)) {
40724
40750
  unlinkSync21(filePath);
40725
40751
  console.log(`Deleted command file: ${filePath}`);
@@ -40991,7 +41017,7 @@ function requestDrain(socket, lines2) {
40991
41017
  }
40992
41018
 
40993
41019
  // src/commands/sessions/daemon/runDaemon.ts
40994
- import { mkdirSync as mkdirSync37 } from "fs";
41020
+ import { mkdirSync as mkdirSync38 } from "fs";
40995
41021
 
40996
41022
  // src/commands/sessions/daemon/createAutoExit.ts
40997
41023
  var DEFAULT_GRACE_MS = 6e4;
@@ -41226,6 +41252,10 @@ function resizeSession(sessions, id, cols, rows, viewer = {}) {
41226
41252
  if (isInactiveViewer(s, viewer)) return;
41227
41253
  claimViewer(s, viewer, "resize");
41228
41254
  const unchanged = s.cols === cols && s.rows === rows;
41255
+ if (!unchanged || viewer.claim)
41256
+ daemonLog(
41257
+ `session ${id} resize ${s.cols}x${s.rows} -> ${cols}x${rows} by ${viewer.viewerId ?? "unknown viewer"} on ${viewer.viewerNode ?? "unknown node"}${viewer.claim ? " (takeover)" : ""}`
41258
+ );
41229
41259
  s.cols = cols;
41230
41260
  s.rows = rows;
41231
41261
  const resize = (c, r) => resizePty(s, c, r);
@@ -41485,7 +41515,7 @@ import { existsSync as existsSync85 } from "fs";
41485
41515
  import * as pty from "node-pty";
41486
41516
 
41487
41517
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
41488
- import { chmodSync, existsSync as existsSync84, statSync as statSync13 } from "fs";
41518
+ import { chmodSync, existsSync as existsSync84, statSync as statSync14 } from "fs";
41489
41519
  import { createRequire as createRequire3 } from "module";
41490
41520
  import path102 from "path";
41491
41521
  var require4 = createRequire3(import.meta.url);
@@ -41501,7 +41531,7 @@ function ensureSpawnHelperExecutable() {
41501
41531
  "spawn-helper"
41502
41532
  );
41503
41533
  if (!existsSync84(helper)) return;
41504
- const mode = statSync13(helper).mode;
41534
+ const mode = statSync14(helper).mode;
41505
41535
  if ((mode & 73) === 0) chmodSync(helper, mode | 493);
41506
41536
  }
41507
41537
 
@@ -41734,12 +41764,12 @@ import { basename as basename28 } from "path";
41734
41764
 
41735
41765
  // src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
41736
41766
  import { existsSync as existsSync86 } from "fs";
41737
- import { join as join100 } from "path";
41767
+ import { join as join101 } from "path";
41738
41768
 
41739
41769
  // src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
41740
- import { statSync as statSync14 } from "fs";
41770
+ import { statSync as statSync15 } from "fs";
41741
41771
  import { rm as rm3 } from "fs/promises";
41742
- import { join as join99 } from "path";
41772
+ import { join as join100 } from "path";
41743
41773
  async function deleteTreeDirectly(clone, worktreePath, why) {
41744
41774
  if (holdsAGitDirectoryRatherThanALink(worktreePath)) {
41745
41775
  const refusal = "it is a clone of its own, not a linked worktree";
@@ -41767,7 +41797,7 @@ async function deleteTreeDirectly(clone, worktreePath, why) {
41767
41797
  return { removed: true };
41768
41798
  }
41769
41799
  function holdsAGitDirectoryRatherThanALink(worktreePath) {
41770
- return statSync14(join99(worktreePath, ".git"), {
41800
+ return statSync15(join100(worktreePath, ".git"), {
41771
41801
  throwIfNoEntry: false
41772
41802
  })?.isDirectory() === true;
41773
41803
  }
@@ -41803,7 +41833,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
41803
41833
  );
41804
41834
  }
41805
41835
  function strandedReason(worktreePath, cause) {
41806
- if (!existsSync86(join100(worktreePath, ".git")))
41836
+ if (!existsSync86(join101(worktreePath, ".git")))
41807
41837
  return "its .git link is already gone";
41808
41838
  if (/not a working tree|not a git repository/i.test(reason2(cause)))
41809
41839
  return "git no longer recognises it as a working tree";
@@ -42046,12 +42076,12 @@ function closeGateApplies(sessions, session) {
42046
42076
  }
42047
42077
 
42048
42078
  // src/commands/sessions/daemon/worktree/liveProcessesInTree.ts
42049
- import { readdirSync as readdirSync22, readlinkSync } from "fs";
42079
+ import { readdirSync as readdirSync23, readlinkSync } from "fs";
42050
42080
  import { sep as sep4 } from "path";
42051
42081
  function liveProcessesInTree(treePath, procRoot = "/proc") {
42052
42082
  let entries;
42053
42083
  try {
42054
- entries = readdirSync22(procRoot);
42084
+ entries = readdirSync23(procRoot);
42055
42085
  } catch {
42056
42086
  return [];
42057
42087
  }
@@ -42696,10 +42726,37 @@ function startSessionTitleGeneration(session, notify2) {
42696
42726
  runSessionTitleGeneration(session, prompt, notify2, singleLineTitle(prompt));
42697
42727
  }
42698
42728
 
42729
+ // src/commands/sessions/daemon/worktree/appendWatcherLog.ts
42730
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync34 } from "fs";
42731
+ import { dirname as dirname42 } from "path";
42732
+
42733
+ // src/commands/sessions/daemon/worktree/watcherLogPath.ts
42734
+ import { createHash as createHash4 } from "crypto";
42735
+ import { homedir as homedir26 } from "os";
42736
+ import { basename as basename29, join as join102 } from "path";
42737
+ function watcherLogPath(cwd) {
42738
+ const clone = canonicalTreePath(cwd);
42739
+ const key = createHash4("sha1").update(clone).digest("hex").slice(0, 8);
42740
+ const dir = process.env.ASSIST_WATCHER_LOG_DIR ?? join102(homedir26(), ".assist", "watchers");
42741
+ return join102(dir, `${basename29(clone) || "root"}-${key}.log`);
42742
+ }
42743
+
42744
+ // src/commands/sessions/daemon/worktree/appendWatcherLog.ts
42745
+ function appendWatcherLog(session, data) {
42746
+ if (session.watcher !== true || !session.cwd) return;
42747
+ try {
42748
+ const path106 = watcherLogPath(session.cwd);
42749
+ mkdirSync34(dirname42(path106), { recursive: true });
42750
+ appendFileSync3(path106, data);
42751
+ } catch {
42752
+ }
42753
+ }
42754
+
42699
42755
  // src/commands/sessions/daemon/emitSessionOutput.ts
42700
42756
  var MAX_SCROLLBACK = 256 * 1024;
42701
42757
  function emitSessionOutput(session, clients, data) {
42702
42758
  session.scrollback += data;
42759
+ appendWatcherLog(session, data);
42703
42760
  if (session.scrollback.length > MAX_SCROLLBACK) {
42704
42761
  session.scrollback = session.scrollback.slice(-MAX_SCROLLBACK);
42705
42762
  }
@@ -42772,8 +42829,8 @@ function handleRefusedRun(session, exitCode, onStatusChange) {
42772
42829
  }
42773
42830
 
42774
42831
  // src/commands/sessions/daemon/watchActivity.ts
42775
- import { existsSync as existsSync90, mkdirSync as mkdirSync34, watch as watch2 } from "fs";
42776
- import { dirname as dirname42 } from "path";
42832
+ import { existsSync as existsSync90, mkdirSync as mkdirSync35, watch as watch2 } from "fs";
42833
+ import { dirname as dirname43 } from "path";
42777
42834
 
42778
42835
  // src/commands/sessions/daemon/applyActivityToSession.ts
42779
42836
  function applyActivityToSession(session, activity2) {
@@ -42835,9 +42892,9 @@ var DEBOUNCE_MS2 = 50;
42835
42892
  function watchActivity(session, notify2, onClaudeSessionId) {
42836
42893
  if (session.commandType !== "assist" || !session.cwd) return;
42837
42894
  const path106 = activityPath(session.id);
42838
- const dir = dirname42(path106);
42895
+ const dir = dirname43(path106);
42839
42896
  try {
42840
- mkdirSync34(dir, { recursive: true });
42897
+ mkdirSync35(dir, { recursive: true });
42841
42898
  } catch {
42842
42899
  return;
42843
42900
  }
@@ -43041,10 +43098,10 @@ function headContainsSessionId(filePath, claudeSessionId) {
43041
43098
  }
43042
43099
 
43043
43100
  // src/commands/sessions/daemon/ensureProjectDirExists.ts
43044
- import { mkdirSync as mkdirSync35 } from "fs";
43101
+ import { mkdirSync as mkdirSync36 } from "fs";
43045
43102
  function ensureProjectDirExists(dir, sessionId) {
43046
43103
  try {
43047
- mkdirSync35(dir, { recursive: true });
43104
+ mkdirSync36(dir, { recursive: true });
43048
43105
  return true;
43049
43106
  } catch (error) {
43050
43107
  daemonLog(
@@ -44023,12 +44080,42 @@ function createAssistSession(id, assistArgs, cwd, meta, holdPty) {
44023
44080
  };
44024
44081
  }
44025
44082
 
44083
+ // src/commands/sessions/daemon/worktree/seedWatcherScrollback.ts
44084
+ import { readFileSync as readFileSync65, writeFileSync as writeFileSync54 } from "fs";
44085
+ var SCROLLBACK_TAIL = 256 * 1024;
44086
+ var MAX_LOG_SIZE = 4 * 1024 * 1024;
44087
+ function readLogTail2(path106) {
44088
+ let log2;
44089
+ try {
44090
+ log2 = readFileSync65(path106, "utf8");
44091
+ } catch {
44092
+ return "";
44093
+ }
44094
+ if (log2.length > MAX_LOG_SIZE) {
44095
+ log2 = log2.slice(-SCROLLBACK_TAIL);
44096
+ writeFileSync54(path106, log2);
44097
+ daemonLog(`watcher log ${path106} trimmed to its last ${log2.length} chars`);
44098
+ }
44099
+ return log2.slice(-SCROLLBACK_TAIL);
44100
+ }
44101
+ function seedWatcherScrollback(cwd, event) {
44102
+ const path106 = watcherLogPath(cwd);
44103
+ const history = readLogTail2(path106);
44104
+ const note = watcherNote(`${event} at ${(/* @__PURE__ */ new Date()).toLocaleString()}`);
44105
+ appendWatcherLog({ watcher: true, cwd }, note);
44106
+ daemonLog(
44107
+ `watcher in ${cwd} seeded with ${history.length} chars of history from ${path106} (${event})`
44108
+ );
44109
+ return history + note;
44110
+ }
44111
+
44026
44112
  // src/commands/sessions/daemon/createWatcherSession.ts
44027
44113
  var WATCHER_ARGS = ["watch", "loop"];
44028
44114
  function createWatcherSession(id, cwd) {
44029
44115
  return {
44030
44116
  ...createAssistSession(id, WATCHER_ARGS, cwd),
44031
- watcher: true
44117
+ watcher: true,
44118
+ scrollback: seedWatcherScrollback(cwd, "watcher started")
44032
44119
  };
44033
44120
  }
44034
44121
 
@@ -45007,7 +45094,17 @@ function relaunchConsoleWatcher(id, persisted, base) {
45007
45094
  daemonLog(
45008
45095
  `relaunching watcher session ${id} running ${command.join(" ")} in ${persisted.cwd ?? "(no cwd)"}`
45009
45096
  );
45010
- return runningSession(base, persisted, spawnPty(command, persisted.cwd, id));
45097
+ const session = runningSession(
45098
+ base,
45099
+ persisted,
45100
+ spawnPty(command, persisted.cwd, id)
45101
+ );
45102
+ if (persisted.cwd)
45103
+ session.scrollback = seedWatcherScrollback(
45104
+ persisted.cwd,
45105
+ "daemon restarted; watcher relaunched"
45106
+ );
45107
+ return session;
45011
45108
  }
45012
45109
 
45013
45110
  // src/commands/sessions/daemon/restoreSession.ts
@@ -45114,7 +45211,7 @@ function rearmStoppedSessions(sessions, notify2) {
45114
45211
 
45115
45212
  // src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
45116
45213
  import { existsSync as existsSync93 } from "fs";
45117
- import { basename as basename30 } from "path";
45214
+ import { basename as basename31 } from "path";
45118
45215
 
45119
45216
  // src/commands/sessions/daemon/worktree/accountedTrees.ts
45120
45217
  function accountedTrees(sessions) {
@@ -45222,7 +45319,7 @@ function capped2(lines2) {
45222
45319
  }
45223
45320
 
45224
45321
  // src/commands/sessions/daemon/worktree/resurfaceOrphanedWorktree.ts
45225
- import { basename as basename29 } from "path";
45322
+ import { basename as basename30 } from "path";
45226
45323
  function resurfaceOrphanedWorktree(sessions, spawnWith, recovered, notify2) {
45227
45324
  const { orphan, reason: reason4, held } = recovered;
45228
45325
  let id;
@@ -45245,7 +45342,7 @@ function orphanedSession(id, recovered) {
45245
45342
  const { orphan, reason: reason4, held } = recovered;
45246
45343
  return {
45247
45344
  ...sessionBase(id, "stopped"),
45248
- name: `recovered ${basename29(orphan.path)}`,
45345
+ name: `recovered ${basename30(orphan.path)}`,
45249
45346
  subtitle: `${held.summary} in ${orphan.path}`,
45250
45347
  commandType: "claude",
45251
45348
  pty: null,
@@ -45306,7 +45403,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
45306
45403
  logVanishedTree(sessions, path106);
45307
45404
  vanished.set(clone, [
45308
45405
  ...vanished.get(clone) ?? [],
45309
- { path: path106, branch: basename30(path106) }
45406
+ { path: path106, branch: basename31(path106) }
45310
45407
  ]);
45311
45408
  continue;
45312
45409
  }
@@ -46426,8 +46523,8 @@ function resumeSession(id, sessionId, cwd, name, holdPty, harness) {
46426
46523
  import { existsSync as existsSync95 } from "fs";
46427
46524
 
46428
46525
  // src/commands/sessions/daemon/worktree/carryTranscriptToTree.ts
46429
- import { copyFileSync as copyFileSync5, existsSync as existsSync94, mkdirSync as mkdirSync36 } from "fs";
46430
- import { join as join102 } from "path";
46526
+ import { copyFileSync as copyFileSync5, existsSync as existsSync94, mkdirSync as mkdirSync37 } from "fs";
46527
+ import { join as join104 } from "path";
46431
46528
  function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
46432
46529
  const dir = projectDirForCwd(toCwd);
46433
46530
  if (dir === projectDirForCwd(fromCwd)) {
@@ -46436,7 +46533,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
46436
46533
  );
46437
46534
  return;
46438
46535
  }
46439
- const dest = join102(dir, `${claudeSessionId}.jsonl`);
46536
+ const dest = join104(dir, `${claudeSessionId}.jsonl`);
46440
46537
  if (existsSync94(dest)) {
46441
46538
  daemonLog(`transcript ${claudeSessionId} already present in ${dir}`);
46442
46539
  return;
@@ -46449,7 +46546,7 @@ function carryTranscriptToTree(claudeSessionId, fromCwd, toCwd) {
46449
46546
  return;
46450
46547
  }
46451
46548
  try {
46452
- mkdirSync36(dir, { recursive: true });
46549
+ mkdirSync37(dir, { recursive: true });
46453
46550
  copyFileSync5(source, dest);
46454
46551
  daemonLog(
46455
46552
  `transcript ${source} copied to ${dest} so ${toCwd} can resume it`
@@ -47324,10 +47421,10 @@ function handleConnection(socket, manager) {
47324
47421
  }
47325
47422
 
47326
47423
  // src/commands/sessions/daemon/onListening.ts
47327
- import { unlinkSync as unlinkSync22, writeFileSync as writeFileSync54 } from "fs";
47424
+ import { unlinkSync as unlinkSync22, writeFileSync as writeFileSync55 } from "fs";
47328
47425
 
47329
47426
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
47330
- import { readFileSync as readFileSync65 } from "fs";
47427
+ import { readFileSync as readFileSync66 } from "fs";
47331
47428
  var WATCHDOG_INTERVAL_MS = 5e3;
47332
47429
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
47333
47430
  const timer = setInterval(() => {
@@ -47338,7 +47435,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
47338
47435
  }
47339
47436
  function ownsPidFile() {
47340
47437
  try {
47341
- return readFileSync65(daemonPaths.pid, "utf8").trim() === String(process.pid);
47438
+ return readFileSync66(daemonPaths.pid, "utf8").trim() === String(process.pid);
47342
47439
  } catch {
47343
47440
  return false;
47344
47441
  }
@@ -47346,7 +47443,7 @@ function ownsPidFile() {
47346
47443
 
47347
47444
  // src/commands/sessions/daemon/onListening.ts
47348
47445
  function onListening(manager, checkAutoExit) {
47349
- writeFileSync54(daemonPaths.pid, String(process.pid));
47446
+ writeFileSync55(daemonPaths.pid, String(process.pid));
47350
47447
  startPidFileWatchdog(() => {
47351
47448
  daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
47352
47449
  void manager.flushActiveMs().finally(() => {
@@ -47434,7 +47531,7 @@ async function recoverFromAddrInUse(server, manager, checkAutoExit) {
47434
47531
 
47435
47532
  // src/commands/sessions/daemon/runDaemon.ts
47436
47533
  async function runDaemon() {
47437
- mkdirSync37(daemonPaths.dir, { recursive: true });
47534
+ mkdirSync38(daemonPaths.dir, { recursive: true });
47438
47535
  daemonLog(
47439
47536
  `starting (reason: ${process.env.ASSIST_DAEMON_SPAWN_REASON ?? "manual"})`
47440
47537
  );