@staff0rd/assist 0.516.0 → 0.516.2

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.516.0",
9
+ version: "0.516.2",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -668,9 +668,6 @@ function getConfigPathFrom(cwd) {
668
668
  function getGlobalConfigPath() {
669
669
  return join2(homedir(), ".assist.yml");
670
670
  }
671
- function getConfigDirFrom(cwd) {
672
- return dirname2(getConfigPathFrom(cwd));
673
- }
674
671
  function projectConfigPathFrom(cwd) {
675
672
  if (findConfigUp(cwd)) return getConfigPathFrom(cwd);
676
673
  const clone = linkedWorktree(cwd)?.clone;
@@ -688,9 +685,6 @@ function loadConfigFrom(cwd) {
688
685
  }
689
686
 
690
687
  // src/shared/loadConfig.ts
691
- function getConfigDir() {
692
- return getConfigDirFrom(process.cwd());
693
- }
694
688
  function getProjectRoot() {
695
689
  const found = findConfigUp(process.cwd());
696
690
  return found?.rootDir ?? process.cwd();
@@ -4584,7 +4578,7 @@ Total: ${lines2.length} hardcoded color(s)`);
4584
4578
  }
4585
4579
 
4586
4580
  // src/commands/verify/run/resolveEntries.ts
4587
- import * as path19 from "path";
4581
+ import * as path20 from "path";
4588
4582
 
4589
4583
  // src/shared/resolveRunConfigs.ts
4590
4584
  import { dirname as dirname10, relative, resolve as resolve4 } from "path";
@@ -4684,17 +4678,40 @@ function resolveLocalCwd(config, configDir, ctx) {
4684
4678
  };
4685
4679
  }
4686
4680
 
4681
+ // src/shared/findRepoRoot.ts
4682
+ import { existsSync as existsSync15 } from "fs";
4683
+ import path19 from "path";
4684
+ function findRepoRoot(dir) {
4685
+ let current = dir;
4686
+ while (current !== path19.dirname(current)) {
4687
+ if (existsSync15(path19.join(current, ".git"))) {
4688
+ return current;
4689
+ }
4690
+ current = path19.dirname(current);
4691
+ }
4692
+ return null;
4693
+ }
4694
+
4695
+ // src/shared/runConfigBaseDir.ts
4696
+ function runConfigBaseDirFrom(cwd) {
4697
+ return findConfigUp(cwd)?.rootDir ?? findRepoRoot(cwd) ?? cwd;
4698
+ }
4699
+ function runConfigBaseDir() {
4700
+ return runConfigBaseDirFrom(process.cwd());
4701
+ }
4702
+
4687
4703
  // src/commands/verify/run/resolveEntries.ts
4688
4704
  function buildFullCommand(command, args) {
4689
4705
  return [shellQuote(command), ...(args ?? []).map(shellQuote)].join(" ");
4690
4706
  }
4691
4707
  function getRunEntries() {
4692
4708
  const { run: run4 } = loadConfig();
4693
- const configs = resolveRunConfigs(run4, getConfigDir());
4709
+ const baseDir = runConfigBaseDir();
4710
+ const configs = resolveRunConfigs(run4, baseDir);
4694
4711
  return configs.filter((r) => r.name.startsWith("verify:")).map((r) => ({
4695
4712
  name: r.name,
4696
4713
  fullCommand: buildFullCommand(r.command, r.args),
4697
- cwd: r.cwd ? path19.resolve(getConfigDir(), r.cwd) : void 0,
4714
+ cwd: r.cwd ? path20.resolve(baseDir, r.cwd) : void 0,
4698
4715
  env: r.env,
4699
4716
  filter: r.filter,
4700
4717
  quiet: r.quiet
@@ -4703,7 +4720,7 @@ function getRunEntries() {
4703
4720
  function getPackageJsonEntries() {
4704
4721
  const result = findPackageJsonWithVerifyScripts(process.cwd());
4705
4722
  if (!result) return [];
4706
- const cwd = path19.dirname(result.packageJsonPath);
4723
+ const cwd = path20.dirname(result.packageJsonPath);
4707
4724
  return result.verifyScripts.map((script) => ({
4708
4725
  name: script,
4709
4726
  fullCommand: `npm run ${script}`,
@@ -4728,7 +4745,7 @@ function list() {
4728
4745
 
4729
4746
  // src/commands/verify/migrations/index.ts
4730
4747
  import { readFileSync as readFileSync11 } from "fs";
4731
- import path20 from "path";
4748
+ import path21 from "path";
4732
4749
  import { fileURLToPath } from "url";
4733
4750
 
4734
4751
  // src/commands/verify/migrations/checkAppendOnly.ts
@@ -4870,8 +4887,8 @@ function resolveBaselineRef() {
4870
4887
  // src/commands/verify/migrations/index.ts
4871
4888
  var REPO_RELATIVE_DIR = "src/shared/db/migrations";
4872
4889
  function migrationsDir() {
4873
- return path20.resolve(
4874
- path20.dirname(fileURLToPath(import.meta.url)),
4890
+ return path21.resolve(
4891
+ path21.dirname(fileURLToPath(import.meta.url)),
4875
4892
  "../../../shared/db/migrations"
4876
4893
  );
4877
4894
  }
@@ -4889,7 +4906,7 @@ function migrations2() {
4889
4906
  if (ref) {
4890
4907
  const baseline = readBaselineMigrations(REPO_RELATIVE_DIR, ref);
4891
4908
  const current = new Map(
4892
- files.map((file) => [file, readFileSync11(path20.join(dir, file), "utf8")])
4909
+ files.map((file) => [file, readFileSync11(path21.join(dir, file), "utf8")])
4893
4910
  );
4894
4911
  for (const finding of checkAppendOnly(baseline, current)) {
4895
4912
  problems.push(
@@ -5215,7 +5232,7 @@ async function newCli() {
5215
5232
 
5216
5233
  // src/commands/new/registerNew/newProject.ts
5217
5234
  import { execSync as execSync22 } from "child_process";
5218
- import { existsSync as existsSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
5235
+ import { existsSync as existsSync17, readFileSync as readFileSync13, writeFileSync as writeFileSync13 } from "fs";
5219
5236
 
5220
5237
  // src/commands/deploy/init/index.ts
5221
5238
  import { execSync as execSync21 } from "child_process";
@@ -5223,14 +5240,14 @@ import chalk29 from "chalk";
5223
5240
  import enquirer3 from "enquirer";
5224
5241
 
5225
5242
  // src/commands/deploy/init/updateWorkflow.ts
5226
- import { existsSync as existsSync15, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
5243
+ import { existsSync as existsSync16, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
5227
5244
  import { dirname as dirname12, join as join10 } from "path";
5228
5245
  import { fileURLToPath as fileURLToPath2 } from "url";
5229
5246
  import chalk28 from "chalk";
5230
5247
  var WORKFLOW_PATH = ".github/workflows/build.yml";
5231
5248
  var __dirname2 = dirname12(fileURLToPath2(import.meta.url));
5232
5249
  function getExistingSiteId() {
5233
- if (!existsSync15(WORKFLOW_PATH)) {
5250
+ if (!existsSync16(WORKFLOW_PATH)) {
5234
5251
  return null;
5235
5252
  }
5236
5253
  const content = readFileSync12(WORKFLOW_PATH, "utf8");
@@ -5245,10 +5262,10 @@ function getTemplateContent(siteId) {
5245
5262
  async function updateWorkflow(siteId) {
5246
5263
  const newContent = getTemplateContent(siteId);
5247
5264
  const workflowDir = ".github/workflows";
5248
- if (!existsSync15(workflowDir)) {
5265
+ if (!existsSync16(workflowDir)) {
5249
5266
  mkdirSync3(workflowDir, { recursive: true });
5250
5267
  }
5251
- if (existsSync15(WORKFLOW_PATH)) {
5268
+ if (existsSync16(WORKFLOW_PATH)) {
5252
5269
  const oldContent = readFileSync12(WORKFLOW_PATH, "utf8");
5253
5270
  if (oldContent === newContent) {
5254
5271
  console.log(chalk28.green("build.yml is already up to date"));
@@ -5343,7 +5360,7 @@ async function newProject() {
5343
5360
  }
5344
5361
  function addViteBaseConfig() {
5345
5362
  const viteConfigPath = "vite.config.ts";
5346
- if (!existsSync16(viteConfigPath)) {
5363
+ if (!existsSync17(viteConfigPath)) {
5347
5364
  console.log("No vite.config.ts found, skipping base config");
5348
5365
  return;
5349
5366
  }
@@ -5407,11 +5424,11 @@ function detectPlatform() {
5407
5424
  import { spawn as spawn2 } from "child_process";
5408
5425
  import fs16 from "fs";
5409
5426
  import { createRequire } from "module";
5410
- import path21 from "path";
5427
+ import path22 from "path";
5411
5428
  var require2 = createRequire(import.meta.url);
5412
5429
  function getSnoreToastPath() {
5413
- const notifierPath = path21.dirname(require2.resolve("node-notifier"));
5414
- return path21.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
5430
+ const notifierPath = path22.dirname(require2.resolve("node-notifier"));
5431
+ return path22.join(notifierPath, "vendor", "snoreToast", "snoretoast-x64.exe");
5415
5432
  }
5416
5433
  function showWindowsNotificationFromWsl(options2) {
5417
5434
  const { title, message: message3, sound } = options2;
@@ -6031,7 +6048,7 @@ function parseItemId(input) {
6031
6048
 
6032
6049
  // src/commands/backlog/acquireLock.ts
6033
6050
  import {
6034
- existsSync as existsSync17,
6051
+ existsSync as existsSync18,
6035
6052
  mkdirSync as mkdirSync4,
6036
6053
  readFileSync as readFileSync14,
6037
6054
  unlinkSync as unlinkSync2,
@@ -6055,7 +6072,7 @@ function isProcessAlive(pid) {
6055
6072
  }
6056
6073
  function foreignLockHolder(itemId2) {
6057
6074
  const lockPath = getLockPath(itemId2);
6058
- if (!existsSync17(lockPath)) return null;
6075
+ if (!existsSync18(lockPath)) return null;
6059
6076
  try {
6060
6077
  const lock2 = JSON.parse(readFileSync14(lockPath, "utf8"));
6061
6078
  if (typeof lock2.pid !== "number" || lock2.pid === process.pid) return null;
@@ -6504,19 +6521,19 @@ function message(error) {
6504
6521
  import chalk38 from "chalk";
6505
6522
 
6506
6523
  // src/commands/backlog/migrateLocalBacklog.ts
6507
- import { existsSync as existsSync19 } from "fs";
6524
+ import { existsSync as existsSync20 } from "fs";
6508
6525
  import { join as join16 } from "path";
6509
6526
  import chalk37 from "chalk";
6510
6527
 
6511
6528
  // src/commands/backlog/backupLocalBacklogFiles.ts
6512
- import { existsSync as existsSync18, renameSync } from "fs";
6529
+ import { existsSync as existsSync19, renameSync } from "fs";
6513
6530
  import { join as join15 } from "path";
6514
6531
  var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
6515
6532
  function backupLocalBacklogFiles(dir) {
6516
6533
  const moved = [];
6517
6534
  for (const name of LOCAL_FILES) {
6518
6535
  const path71 = join15(dir, ".assist", name);
6519
- if (existsSync18(path71)) {
6536
+ if (existsSync19(path71)) {
6520
6537
  renameSync(path71, `${path71}.bak`);
6521
6538
  moved.push(`${name} \u2192 ${name}.bak`);
6522
6539
  }
@@ -7020,7 +7037,7 @@ async function verifyImport(orm, origin, items2, imported) {
7020
7037
  }
7021
7038
  }
7022
7039
  async function migrateLocalBacklog(orm, dir, origin) {
7023
- if (!existsSync19(jsonlPath(dir))) return;
7040
+ if (!existsSync20(jsonlPath(dir))) return;
7024
7041
  const existing = (await loadAllItems(orm, origin)).length;
7025
7042
  if (existing > 0) {
7026
7043
  const moved2 = backupLocalBacklogFiles(dir);
@@ -7059,7 +7076,7 @@ async function deleteItem(orm, id) {
7059
7076
  }
7060
7077
 
7061
7078
  // src/commands/backlog/findBacklogUp.ts
7062
- import { existsSync as existsSync20 } from "fs";
7079
+ import { existsSync as existsSync21 } from "fs";
7063
7080
  import { dirname as dirname14, join as join17 } from "path";
7064
7081
  var BACKLOG_MARKERS = [
7065
7082
  join17(".assist", "backlog.db"),
@@ -7069,7 +7086,7 @@ var BACKLOG_MARKERS = [
7069
7086
  function findBacklogUp(startDir) {
7070
7087
  let current = startDir;
7071
7088
  while (current !== dirname14(current)) {
7072
- if (BACKLOG_MARKERS.some((marker) => existsSync20(join17(current, marker)))) {
7089
+ if (BACKLOG_MARKERS.some((marker) => existsSync21(join17(current, marker)))) {
7073
7090
  return current;
7074
7091
  }
7075
7092
  current = dirname14(current);
@@ -7323,7 +7340,7 @@ function reportDuplicateRun(itemId2, holder) {
7323
7340
  }
7324
7341
 
7325
7342
  // src/commands/backlog/consumePause.ts
7326
- import { existsSync as existsSync21, mkdirSync as mkdirSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "fs";
7343
+ import { existsSync as existsSync22, mkdirSync as mkdirSync6, unlinkSync as unlinkSync3, writeFileSync as writeFileSync16 } from "fs";
7327
7344
  import { homedir as homedir6 } from "os";
7328
7345
  import { join as join18 } from "path";
7329
7346
  function getControlsDir() {
@@ -7340,7 +7357,7 @@ function requestPause(itemId2) {
7340
7357
  );
7341
7358
  }
7342
7359
  function isPausePending(itemId2) {
7343
- return existsSync21(getPausePath(itemId2));
7360
+ return existsSync22(getPausePath(itemId2));
7344
7361
  }
7345
7362
  function clearPause(itemId2) {
7346
7363
  try {
@@ -7350,7 +7367,7 @@ function clearPause(itemId2) {
7350
7367
  }
7351
7368
  function consumePause(itemId2) {
7352
7369
  const pausePath = getPausePath(itemId2);
7353
- if (!existsSync21(pausePath)) return false;
7370
+ if (!existsSync22(pausePath)) return false;
7354
7371
  try {
7355
7372
  unlinkSync3(pausePath);
7356
7373
  } catch {
@@ -7680,7 +7697,7 @@ function buildPhasePrompt(item, phaseNumber, phase) {
7680
7697
 
7681
7698
  // src/shared/harnesses.ts
7682
7699
  import * as os from "os";
7683
- import * as path22 from "path";
7700
+ import * as path23 from "path";
7684
7701
 
7685
7702
  // src/shared/checkCliAvailable.ts
7686
7703
  import { execSync as execSync30 } from "child_process";
@@ -7709,28 +7726,28 @@ var harnesses = {
7709
7726
  claude: {
7710
7727
  kind: "claude",
7711
7728
  command: "claude",
7712
- homeDir: path22.join(os.homedir(), ".claude"),
7729
+ homeDir: path23.join(os.homedir(), ".claude"),
7713
7730
  sync: {
7714
7731
  agentsFile: "CLAUDE.md",
7715
- commandDest: (name) => path22.join("commands", `${name}.md`)
7732
+ commandDest: (name) => path23.join("commands", `${name}.md`)
7716
7733
  }
7717
7734
  },
7718
7735
  codex: {
7719
7736
  kind: "codex",
7720
7737
  command: "codex",
7721
- homeDir: path22.join(os.homedir(), ".codex"),
7738
+ homeDir: path23.join(os.homedir(), ".codex"),
7722
7739
  sync: {
7723
7740
  agentsFile: "AGENTS.md",
7724
- commandDest: (name) => path22.join("skills", name, "SKILL.md")
7741
+ commandDest: (name) => path23.join("skills", name, "SKILL.md")
7725
7742
  }
7726
7743
  },
7727
7744
  pi: {
7728
7745
  kind: "pi",
7729
7746
  command: "pi",
7730
- homeDir: path22.join(os.homedir(), ".pi", "agent"),
7747
+ homeDir: path23.join(os.homedir(), ".pi", "agent"),
7731
7748
  sync: {
7732
7749
  agentsFile: "AGENTS.md",
7733
- commandDest: (name) => path22.join("prompts", `${name}.md`)
7750
+ commandDest: (name) => path23.join("prompts", `${name}.md`)
7734
7751
  }
7735
7752
  }
7736
7753
  };
@@ -7775,10 +7792,10 @@ function spawnHarness(harness, prompt, options2 = {}) {
7775
7792
  }
7776
7793
 
7777
7794
  // src/commands/backlog/watchForMarker.ts
7778
- import { existsSync as existsSync24, unwatchFile, watchFile } from "fs";
7795
+ import { existsSync as existsSync25, unwatchFile, watchFile } from "fs";
7779
7796
 
7780
7797
  // src/commands/backlog/readSignal.ts
7781
- import { existsSync as existsSync23, readFileSync as readFileSync17 } from "fs";
7798
+ import { existsSync as existsSync24, readFileSync as readFileSync17 } from "fs";
7782
7799
 
7783
7800
  // src/commands/backlog/writeSignal.ts
7784
7801
  import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync18 } from "fs";
@@ -7788,7 +7805,7 @@ import chalk42 from "chalk";
7788
7805
 
7789
7806
  // src/commands/backlog/recordSignalOwner.ts
7790
7807
  import {
7791
- existsSync as existsSync22,
7808
+ existsSync as existsSync23,
7792
7809
  mkdirSync as mkdirSync7,
7793
7810
  readFileSync as readFileSync16,
7794
7811
  rmSync,
@@ -7808,7 +7825,7 @@ function recordSignalOwner(itemId2) {
7808
7825
  }
7809
7826
  function readSignalOwner(itemId2) {
7810
7827
  const path71 = getOwnerPath(itemId2);
7811
- if (!existsSync22(path71)) return void 0;
7828
+ if (!existsSync23(path71)) return void 0;
7812
7829
  try {
7813
7830
  const parsed = JSON.parse(readFileSync16(path71, "utf8"));
7814
7831
  return parsed.sessionId;
@@ -7866,7 +7883,7 @@ function writeSignal(event, data) {
7866
7883
  // src/commands/backlog/readSignal.ts
7867
7884
  function readSignal() {
7868
7885
  const path71 = getSignalPath();
7869
- if (!path71 || !existsSync23(path71)) return void 0;
7886
+ if (!path71 || !existsSync24(path71)) return void 0;
7870
7887
  try {
7871
7888
  return JSON.parse(readFileSync17(path71, "utf8"));
7872
7889
  } catch {
@@ -7880,7 +7897,7 @@ function watchForMarker(child, options2) {
7880
7897
  const statusPath = getSignalPath();
7881
7898
  if (!statusPath) return { killedOnMarker: () => killed };
7882
7899
  watchFile(statusPath, { interval: 1e3 }, () => {
7883
- if (!existsSync24(statusPath)) return;
7900
+ if (!existsSync25(statusPath)) return;
7884
7901
  const signal = readSignal();
7885
7902
  if (!signal) return;
7886
7903
  if (signal.event === "done" && !options2?.actOnDone) return;
@@ -7931,7 +7948,7 @@ function launchPhaseSession(item, phaseNumber, phase, phaseLabel2, claudeSession
7931
7948
  }
7932
7949
 
7933
7950
  // src/commands/backlog/resolvePhaseResult.ts
7934
- import { existsSync as existsSync25, unlinkSync as unlinkSync4 } from "fs";
7951
+ import { existsSync as existsSync26, unlinkSync as unlinkSync4 } from "fs";
7935
7952
  import chalk43 from "chalk";
7936
7953
 
7937
7954
  // src/commands/backlog/handleIncompletePhase.ts
@@ -7953,7 +7970,7 @@ async function handleIncompletePhase() {
7953
7970
  // src/commands/backlog/resolvePhaseResult.ts
7954
7971
  function cleanupSignal() {
7955
7972
  const statusPath = getSignalPath();
7956
- if (statusPath && existsSync25(statusPath)) {
7973
+ if (statusPath && existsSync26(statusPath)) {
7957
7974
  unlinkSync4(statusPath);
7958
7975
  }
7959
7976
  }
@@ -7964,7 +7981,7 @@ async function isTerminalStatus(itemId2) {
7964
7981
  }
7965
7982
  async function resolvePhaseResult(phaseIndex, itemId2) {
7966
7983
  const signalPath = getSignalPath();
7967
- if (!signalPath || !existsSync25(signalPath)) {
7984
+ if (!signalPath || !existsSync26(signalPath)) {
7968
7985
  if (await isTerminalStatus(itemId2)) return { kind: "abort" };
7969
7986
  const action = await handleIncompletePhase();
7970
7987
  if (action === "abort") return { kind: "abort" };
@@ -8110,16 +8127,16 @@ function reportPhaseActivity(item, phaseNumber, totalPhases, phase, claudeSessio
8110
8127
  import chalk44 from "chalk";
8111
8128
 
8112
8129
  // src/commands/sessions/shared/findSessionJsonlPath.ts
8113
- import * as path25 from "path";
8130
+ import * as path26 from "path";
8114
8131
 
8115
8132
  // src/commands/sessions/shared/discoverSessions.ts
8116
8133
  import * as fs18 from "fs";
8117
8134
  import * as os3 from "os";
8118
- import * as path24 from "path";
8135
+ import * as path25 from "path";
8119
8136
 
8120
8137
  // src/commands/sessions/shared/parseSessionFile.ts
8121
8138
  import * as fs17 from "fs";
8122
- import * as path23 from "path";
8139
+ import * as path24 from "path";
8123
8140
 
8124
8141
  // src/commands/sessions/shared/deriveHistoryFields.ts
8125
8142
  var KNOWN = [
@@ -8243,10 +8260,10 @@ async function readHeadLines(handle) {
8243
8260
  }
8244
8261
  function deriveProject(cwd, filePath, origin) {
8245
8262
  if (!cwd) return dirNameToProject(filePath);
8246
- return origin === "windows" ? path23.win32.basename(cwd) : path23.basename(cwd);
8263
+ return origin === "windows" ? path24.win32.basename(cwd) : path24.basename(cwd);
8247
8264
  }
8248
8265
  function dirNameToProject(filePath) {
8249
- const dirName = path23.basename(path23.dirname(filePath));
8266
+ const dirName = path24.basename(path24.dirname(filePath));
8250
8267
  const parts = dirName.split("--");
8251
8268
  return parts[parts.length - 1].replace(/-/g, "/");
8252
8269
  }
@@ -8254,7 +8271,7 @@ function dirNameToProject(filePath) {
8254
8271
  // src/commands/sessions/shared/discoverSessions.ts
8255
8272
  function sessionRoots() {
8256
8273
  const roots = [
8257
- { dir: path24.join(os3.homedir(), ".claude", "projects"), origin: "wsl" }
8274
+ { dir: path25.join(os3.homedir(), ".claude", "projects"), origin: "wsl" }
8258
8275
  ];
8259
8276
  const windowsRoot = loadConfig().sessions?.windowsProjectsRoot;
8260
8277
  if (windowsRoot) roots.push({ dir: windowsRoot, origin: "windows" });
@@ -8272,7 +8289,7 @@ async function discoverSessionJsonlPaths() {
8272
8289
  }
8273
8290
  await Promise.all(
8274
8291
  projectDirs.map(async (dirName) => {
8275
- const dirPath = path24.join(dir, dirName);
8292
+ const dirPath = path25.join(dir, dirName);
8276
8293
  let entries;
8277
8294
  try {
8278
8295
  entries = await fs18.promises.readdir(dirPath);
@@ -8281,7 +8298,7 @@ async function discoverSessionJsonlPaths() {
8281
8298
  }
8282
8299
  for (const file of entries) {
8283
8300
  if (file.endsWith(".jsonl"))
8284
- results.push({ path: path24.join(dirPath, file), origin });
8301
+ results.push({ path: path25.join(dirPath, file), origin });
8285
8302
  }
8286
8303
  })
8287
8304
  );
@@ -8311,7 +8328,7 @@ async function discoverSessions() {
8311
8328
  async function findSessionJsonlPath(sessionId) {
8312
8329
  const paths = await discoverSessionJsonlPaths();
8313
8330
  const direct = paths.find(
8314
- (p) => path25.basename(p.path, ".jsonl") === sessionId
8331
+ (p) => path26.basename(p.path, ".jsonl") === sessionId
8315
8332
  );
8316
8333
  if (direct) return direct.path;
8317
8334
  for (const p of paths) {
@@ -9316,7 +9333,7 @@ function gitCommonDir(cwd) {
9316
9333
  }
9317
9334
 
9318
9335
  // src/shared/loadJson.ts
9319
- import { existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync19, writeFileSync as writeFileSync20 } from "fs";
9336
+ import { existsSync as existsSync27, mkdirSync as mkdirSync11, readFileSync as readFileSync19, writeFileSync as writeFileSync20 } from "fs";
9320
9337
  import { homedir as homedir12 } from "os";
9321
9338
  import { join as join24 } from "path";
9322
9339
  function getStoreDir() {
@@ -9327,7 +9344,7 @@ function getStorePath(filename) {
9327
9344
  }
9328
9345
  function loadJson(filename) {
9329
9346
  const path71 = getStorePath(filename);
9330
- if (existsSync26(path71)) {
9347
+ if (existsSync27(path71)) {
9331
9348
  try {
9332
9349
  return JSON.parse(readFileSync19(path71, "utf8"));
9333
9350
  } catch {
@@ -9338,7 +9355,7 @@ function loadJson(filename) {
9338
9355
  }
9339
9356
  function saveJson(filename, data) {
9340
9357
  const dir = getStoreDir();
9341
- if (!existsSync26(dir)) {
9358
+ if (!existsSync27(dir)) {
9342
9359
  mkdirSync11(dir, { recursive: true });
9343
9360
  }
9344
9361
  writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
@@ -9531,7 +9548,7 @@ async function loadItemSummaries(orm, origin) {
9531
9548
  }
9532
9549
 
9533
9550
  // src/commands/backlog/resolveRepoLocation.ts
9534
- import { existsSync as existsSync27 } from "fs";
9551
+ import { existsSync as existsSync28 } from "fs";
9535
9552
 
9536
9553
  // src/commands/backlog/cloneTargetDir.ts
9537
9554
  import { join as join26, resolve as resolve9 } from "path";
@@ -9547,7 +9564,7 @@ function resolveRepoLocation(origin, knownCwd, baseDir) {
9547
9564
  if (knownCwd) return { cwd: knownCwd };
9548
9565
  const target = cloneTargetDir(origin, baseDir);
9549
9566
  if (!target) return {};
9550
- if (existsSync27(target) && getCurrentOrigin(target) === origin)
9567
+ if (existsSync28(target) && getCurrentOrigin(target) === origin)
9551
9568
  return { cwd: target };
9552
9569
  return { cloneTarget: target };
9553
9570
  }
@@ -10590,7 +10607,7 @@ function getServerRuns(rawCwd) {
10590
10607
  try {
10591
10608
  const cwd = toGitCwd(rawCwd);
10592
10609
  const { run: run4 } = loadConfigFrom(cwd);
10593
- return resolveRunConfigs(run4, getConfigDirFrom(cwd)).filter((r) => r.server).map((r) => ({ name: r.name, port: r.port }));
10610
+ return resolveRunConfigs(run4, runConfigBaseDirFrom(cwd)).filter((r) => r.server).map((r) => ({ name: r.name, port: r.port }));
10594
10611
  } catch {
10595
10612
  return [];
10596
10613
  }
@@ -10609,14 +10626,14 @@ import { basename as basename8, join as join28 } from "path";
10609
10626
  import { promisify as promisify3 } from "util";
10610
10627
 
10611
10628
  // src/commands/sessions/web/findSynthesisForBranch.ts
10612
- import { existsSync as existsSync28, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
10629
+ import { existsSync as existsSync29, readdirSync as readdirSync2, statSync as statSync4 } from "fs";
10613
10630
  import { basename as basename7, dirname as dirname21, join as join27 } from "path";
10614
10631
  function findSynthesisForBranch(repoReviewsDir, branch2) {
10615
10632
  const branchKeyPath = join27(repoReviewsDir, `${branch2}-`);
10616
10633
  const parent = dirname21(branchKeyPath);
10617
10634
  const branchPrefix = basename7(branchKeyPath);
10618
- if (!existsSync28(parent)) return null;
10619
- const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join27(parent, name, "synthesis.md")).filter((path71) => existsSync28(path71)).map((path71) => ({ path: path71, mtime: statSync4(path71).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
10635
+ if (!existsSync29(parent)) return null;
10636
+ const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join27(parent, name, "synthesis.md")).filter((path71) => existsSync29(path71)).map((path71) => ({ path: path71, mtime: statSync4(path71).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
10620
10637
  return synthesisFiles[0]?.path ?? null;
10621
10638
  }
10622
10639
 
@@ -12738,7 +12755,7 @@ function registerAssociateJiraCommand(cmd) {
12738
12755
 
12739
12756
  // src/commands/backlog/cloneRepo.ts
12740
12757
  import { spawnSync as spawnSync2 } from "child_process";
12741
- import { existsSync as existsSync29 } from "fs";
12758
+ import { existsSync as existsSync30 } from "fs";
12742
12759
  import { mkdir as mkdir3 } from "fs/promises";
12743
12760
  import chalk69 from "chalk";
12744
12761
 
@@ -12774,7 +12791,7 @@ async function cloneRepo(originRaw) {
12774
12791
  if (!target) {
12775
12792
  return fail2(`Could not derive a repository name from "${origin}".`);
12776
12793
  }
12777
- if (existsSync29(target)) {
12794
+ if (existsSync30(target)) {
12778
12795
  return fail2(`Clone target already exists: ${target}`);
12779
12796
  }
12780
12797
  await mkdir3(baseDir, { recursive: true });
@@ -15714,7 +15731,7 @@ function extractGraphqlQuery(args) {
15714
15731
  }
15715
15732
 
15716
15733
  // src/shared/loadCliReads.ts
15717
- import { existsSync as existsSync30, readFileSync as readFileSync25, writeFileSync as writeFileSync22 } from "fs";
15734
+ import { existsSync as existsSync31, readFileSync as readFileSync25, writeFileSync as writeFileSync22 } from "fs";
15718
15735
  import { dirname as dirname22, resolve as resolve12 } from "path";
15719
15736
  import { fileURLToPath as fileURLToPath5 } from "url";
15720
15737
  var __filename3 = fileURLToPath5(import.meta.url);
@@ -15723,7 +15740,7 @@ function packageRoot() {
15723
15740
  return __dirname4;
15724
15741
  }
15725
15742
  function readLines(path71) {
15726
- if (!existsSync30(path71)) return [];
15743
+ if (!existsSync31(path71)) return [];
15727
15744
  return readFileSync25(path71, "utf8").split("\n").filter((line) => line.trim() !== "");
15728
15745
  }
15729
15746
  var cachedReads;
@@ -15770,7 +15787,7 @@ function findCliWrite(command) {
15770
15787
  }
15771
15788
 
15772
15789
  // src/shared/readSettingsPerms.ts
15773
- import { existsSync as existsSync31, readFileSync as readFileSync26 } from "fs";
15790
+ import { existsSync as existsSync32, readFileSync as readFileSync26 } from "fs";
15774
15791
  import { homedir as homedir14 } from "os";
15775
15792
  import { join as join31 } from "path";
15776
15793
  function readSettingsPerms(key) {
@@ -15786,7 +15803,7 @@ function readSettingsPerms(key) {
15786
15803
  return entries;
15787
15804
  }
15788
15805
  function readPermissionArray(filePath, key) {
15789
- if (!existsSync31(filePath)) return [];
15806
+ if (!existsSync32(filePath)) return [];
15790
15807
  try {
15791
15808
  const data = JSON.parse(readFileSync26(filePath, "utf8"));
15792
15809
  const arr = data?.permissions?.[key];
@@ -16105,7 +16122,7 @@ ${reasons.join("\n")}`);
16105
16122
  }
16106
16123
 
16107
16124
  // src/commands/permitCliReads/index.ts
16108
- import { existsSync as existsSync32, mkdirSync as mkdirSync13, readFileSync as readFileSync27, writeFileSync as writeFileSync23 } from "fs";
16125
+ import { existsSync as existsSync33, mkdirSync as mkdirSync13, readFileSync as readFileSync27, writeFileSync as writeFileSync23 } from "fs";
16109
16126
  import { homedir as homedir16 } from "os";
16110
16127
  import { join as join33 } from "path";
16111
16128
 
@@ -16374,7 +16391,7 @@ function logPath(cli) {
16374
16391
  }
16375
16392
  function readCache(cli) {
16376
16393
  const path71 = logPath(cli);
16377
- if (!existsSync32(path71)) return void 0;
16394
+ if (!existsSync33(path71)) return void 0;
16378
16395
  return readFileSync27(path71, "utf8");
16379
16396
  }
16380
16397
  function writeCache(cli, output) {
@@ -16509,7 +16526,7 @@ function registerCliHook(program2) {
16509
16526
  }
16510
16527
 
16511
16528
  // src/commands/codeComment/codeCommentConfirm.ts
16512
- import { existsSync as existsSync34, readFileSync as readFileSync29, unlinkSync as unlinkSync8, writeFileSync as writeFileSync24 } from "fs";
16529
+ import { existsSync as existsSync35, readFileSync as readFileSync29, unlinkSync as unlinkSync8, writeFileSync as writeFileSync24 } from "fs";
16513
16530
  import chalk121 from "chalk";
16514
16531
 
16515
16532
  // src/commands/codeComment/getRestrictedDir.ts
@@ -16545,10 +16562,10 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
16545
16562
  }
16546
16563
 
16547
16564
  // src/commands/codeComment/readPinState.ts
16548
- import { existsSync as existsSync33, readFileSync as readFileSync28 } from "fs";
16565
+ import { existsSync as existsSync34, readFileSync as readFileSync28 } from "fs";
16549
16566
  function readPinState(pin) {
16550
16567
  const path71 = getPinStatePath(pin);
16551
- if (!existsSync33(path71)) return void 0;
16568
+ if (!existsSync34(path71)) return void 0;
16552
16569
  try {
16553
16570
  const state = JSON.parse(readFileSync28(path71, "utf8"));
16554
16571
  if (state.pin !== pin) return void 0;
@@ -16567,7 +16584,7 @@ function codeCommentConfirm(pin) {
16567
16584
  process.exitCode = 1;
16568
16585
  return;
16569
16586
  }
16570
- if (!existsSync34(state.file)) {
16587
+ if (!existsSync35(state.file)) {
16571
16588
  console.error(chalk121.red(`Target file no longer exists: ${state.file}`));
16572
16589
  process.exitCode = 1;
16573
16590
  return;
@@ -16764,13 +16781,13 @@ import chalk124 from "chalk";
16764
16781
 
16765
16782
  // src/commands/complexity/shared/index.ts
16766
16783
  import fs20 from "fs";
16767
- import path27 from "path";
16784
+ import path28 from "path";
16768
16785
  import chalk123 from "chalk";
16769
16786
  import ts5 from "typescript";
16770
16787
 
16771
16788
  // src/commands/complexity/findSourceFiles.ts
16772
16789
  import fs19 from "fs";
16773
- import path26 from "path";
16790
+ import path27 from "path";
16774
16791
  import { minimatch as minimatch5 } from "minimatch";
16775
16792
  function applyIgnoreGlobs(files, extraIgnore = []) {
16776
16793
  const { complexity } = loadConfig();
@@ -16784,7 +16801,7 @@ function walk2(dir, results) {
16784
16801
  const extensions = [".ts", ".tsx"];
16785
16802
  const entries = fs19.readdirSync(dir, { withFileTypes: true });
16786
16803
  for (const entry of entries) {
16787
- const fullPath = path26.join(dir, entry.name);
16804
+ const fullPath = path27.join(dir, entry.name);
16788
16805
  if (entry.isDirectory()) {
16789
16806
  if (entry.name !== "node_modules" && entry.name !== ".git") {
16790
16807
  walk2(fullPath, results);
@@ -17006,7 +17023,7 @@ function countSloc(content) {
17006
17023
  function createSourceFromFile(filePath) {
17007
17024
  const content = fs20.readFileSync(filePath, "utf8");
17008
17025
  return ts5.createSourceFile(
17009
- path27.basename(filePath),
17026
+ path28.basename(filePath),
17010
17027
  content,
17011
17028
  ts5.ScriptTarget.Latest,
17012
17029
  true,
@@ -17168,12 +17185,12 @@ function formatResultLine(entry, failing) {
17168
17185
 
17169
17186
  // src/commands/complexity/maintainability/getMaintainabilityGitState.ts
17170
17187
  import { execSync as execSync35 } from "child_process";
17171
- import path28 from "path";
17188
+ import path29 from "path";
17172
17189
  function git3(command) {
17173
17190
  return execSync35(command, { encoding: "utf8" });
17174
17191
  }
17175
17192
  function toAbsolute(root, repoRelative) {
17176
- return path28.resolve(root, repoRelative);
17193
+ return path29.resolve(root, repoRelative);
17177
17194
  }
17178
17195
  function collectShrunkFiles(root) {
17179
17196
  const shrunk = /* @__PURE__ */ new Set();
@@ -17213,7 +17230,7 @@ function getMaintainabilityGitState() {
17213
17230
  }
17214
17231
 
17215
17232
  // src/commands/complexity/maintainability/printMaintainabilityFailure.ts
17216
- import path29 from "path";
17233
+ import path30 from "path";
17217
17234
  import chalk127 from "chalk";
17218
17235
  var extractTemplate = "assist refactor extract <file> <functionName> <destination> --apply";
17219
17236
  function remediationLine(entry) {
@@ -17222,7 +17239,7 @@ function remediationLine(entry) {
17222
17239
  ${chalk127.cyan(extractTemplate)}`;
17223
17240
  }
17224
17241
  function cheatLine(entry, gitState) {
17225
- const shrank = gitState.shrunkFiles.has(path29.resolve(entry.file));
17242
+ const shrank = gitState.shrunkFiles.has(path30.resolve(entry.file));
17226
17243
  if (!shrank || gitState.newFileCreated) return "";
17227
17244
  return `
17228
17245
  ${chalk127.red("\u2717 You shrank existing lines in this file without creating a new file. That cannot clear the gate \u2014 extract a responsibility to a new file.")}`;
@@ -17633,10 +17650,10 @@ function getMigrationApprovalPath(migrationId) {
17633
17650
  }
17634
17651
 
17635
17652
  // src/commands/dbMigration/readMigrationPinState.ts
17636
- import { existsSync as existsSync35, readFileSync as readFileSync30 } from "fs";
17653
+ import { existsSync as existsSync36, readFileSync as readFileSync30 } from "fs";
17637
17654
  function readMigrationPinState(pin) {
17638
17655
  const path71 = getMigrationPinPath(pin);
17639
- if (!existsSync35(path71)) return void 0;
17656
+ if (!existsSync36(path71)) return void 0;
17640
17657
  try {
17641
17658
  const state = JSON.parse(readFileSync30(path71, "utf8"));
17642
17659
  if (state.pin !== pin) return void 0;
@@ -17725,7 +17742,7 @@ function registerDbMigration(parent) {
17725
17742
  }
17726
17743
 
17727
17744
  // src/commands/deploy/redirect.ts
17728
- import { existsSync as existsSync36, readFileSync as readFileSync31, writeFileSync as writeFileSync28 } from "fs";
17745
+ import { existsSync as existsSync37, readFileSync as readFileSync31, writeFileSync as writeFileSync28 } from "fs";
17729
17746
  import chalk139 from "chalk";
17730
17747
  var TRAILING_SLASH_SCRIPT = ` <script>
17731
17748
  if (!window.location.pathname.endsWith('/')) {
@@ -17734,7 +17751,7 @@ var TRAILING_SLASH_SCRIPT = ` <script>
17734
17751
  </script>`;
17735
17752
  function redirect() {
17736
17753
  const indexPath = "index.html";
17737
- if (!existsSync36(indexPath)) {
17754
+ if (!existsSync37(indexPath)) {
17738
17755
  console.log(chalk139.yellow("No index.html found"));
17739
17756
  return;
17740
17757
  }
@@ -17781,7 +17798,7 @@ import { execSync as execSync36 } from "child_process";
17781
17798
  import chalk140 from "chalk";
17782
17799
 
17783
17800
  // src/shared/getRepoName.ts
17784
- import { existsSync as existsSync37, readFileSync as readFileSync32 } from "fs";
17801
+ import { existsSync as existsSync38, readFileSync as readFileSync32 } from "fs";
17785
17802
  import { basename as basename10, join as join38 } from "path";
17786
17803
  function getRepoName() {
17787
17804
  const config = loadConfig();
@@ -17789,7 +17806,7 @@ function getRepoName() {
17789
17806
  return config.devlog.name;
17790
17807
  }
17791
17808
  const packageJsonPath = join38(process.cwd(), "package.json");
17792
- if (existsSync37(packageJsonPath)) {
17809
+ if (existsSync38(packageJsonPath)) {
17793
17810
  try {
17794
17811
  const content = readFileSync32(packageJsonPath, "utf8");
17795
17812
  const pkg = JSON.parse(content);
@@ -18289,22 +18306,6 @@ function registerDevlog(program2) {
18289
18306
  import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync5 } from "fs";
18290
18307
  import { join as join41 } from "path";
18291
18308
  import chalk147 from "chalk";
18292
-
18293
- // src/shared/findRepoRoot.ts
18294
- import { existsSync as existsSync38 } from "fs";
18295
- import path30 from "path";
18296
- function findRepoRoot(dir) {
18297
- let current = dir;
18298
- while (current !== path30.dirname(current)) {
18299
- if (existsSync38(path30.join(current, ".git"))) {
18300
- return current;
18301
- }
18302
- current = path30.dirname(current);
18303
- }
18304
- return null;
18305
- }
18306
-
18307
- // src/commands/dotnet/checkBuildLocks.ts
18308
18309
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
18309
18310
  function isLockedDll(debugDir) {
18310
18311
  let files;
@@ -18806,7 +18807,7 @@ import { execSync as execSync41 } from "child_process";
18806
18807
  import chalk155 from "chalk";
18807
18808
  function resolveMsbuildPath() {
18808
18809
  const { run: run4 } = loadConfig();
18809
- const configs = resolveRunConfigs(run4, getConfigDir());
18810
+ const configs = resolveRunConfigs(run4, runConfigBaseDir());
18810
18811
  const buildConfig = configs.find((r) => r.name === "build");
18811
18812
  return buildConfig?.command ?? "msbuild";
18812
18813
  }
@@ -28126,9 +28127,6 @@ function pullFastForward(cwd) {
28126
28127
  return mergeBehindBranch(cwd);
28127
28128
  }
28128
28129
 
28129
- // src/commands/watch/runWatchBuild.ts
28130
- import { resolve as resolve18 } from "path";
28131
-
28132
28130
  // src/commands/run/findRunConfig.ts
28133
28131
  function exitNoRunConfigs() {
28134
28132
  console.error("No run configurations found in assist.yml");
@@ -28152,7 +28150,7 @@ function exitWithAmbiguousConfig(name, matches) {
28152
28150
  }
28153
28151
  function requireRunConfigs() {
28154
28152
  const { run: run4 } = loadConfig();
28155
- const configs = resolveRunConfigs(run4, getConfigDir());
28153
+ const configs = resolveRunConfigs(run4, runConfigBaseDir());
28156
28154
  if (configs.length === 0) return exitNoRunConfigs();
28157
28155
  return configs;
28158
28156
  }
@@ -28199,24 +28197,55 @@ function resolveParams(params, cliArgs) {
28199
28197
  return resolved;
28200
28198
  }
28201
28199
 
28202
- // src/commands/run/runCommandToCompletion.ts
28203
- import { execFileSync as execFileSync11, spawn as spawn9 } from "child_process";
28200
+ // src/commands/run/resolveRunCwd.ts
28204
28201
  import { existsSync as existsSync58 } from "fs";
28205
- import { dirname as dirname31, join as join68, resolve as resolve17 } from "path";
28202
+ import { resolve as resolve17 } from "path";
28203
+ var MissingRunCwdError = class extends Error {
28204
+ constructor(runName, cwd) {
28205
+ super(`run config "${runName}": cwd ${cwd} does not exist`);
28206
+ this.runName = runName;
28207
+ this.cwd = cwd;
28208
+ this.name = "MissingRunCwdError";
28209
+ }
28210
+ };
28211
+ function resolveRunCwd(config, baseDir = runConfigBaseDir()) {
28212
+ if (!config.cwd) return void 0;
28213
+ const cwd = resolve17(baseDir, config.cwd);
28214
+ if (!existsSync58(cwd)) throw new MissingRunCwdError(config.name, cwd);
28215
+ return cwd;
28216
+ }
28217
+
28218
+ // src/commands/run/runCommandToCompletion.ts
28219
+ import { spawn as spawn9 } from "child_process";
28220
+ import { existsSync as existsSync60 } from "fs";
28221
+
28222
+ // src/commands/run/resolveCommand.ts
28223
+ import { execFileSync as execFileSync11 } from "child_process";
28224
+ import { existsSync as existsSync59 } from "fs";
28225
+ import { dirname as dirname31, join as join68, resolve as resolve18 } from "path";
28206
28226
  function resolveCommand2(command) {
28207
28227
  if (process.platform !== "win32" || command !== "bash") return command;
28208
28228
  try {
28209
28229
  const gitPath = execFileSync11("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
28210
- const gitRoot = resolve17(dirname31(gitPath), "..");
28230
+ const gitRoot = resolve18(dirname31(gitPath), "..");
28211
28231
  const gitBash = join68(gitRoot, "bin", "bash.exe");
28212
- if (existsSync58(gitBash)) return gitBash;
28232
+ if (existsSync59(gitBash)) return gitBash;
28213
28233
  } catch {
28214
28234
  return command;
28215
28235
  }
28216
28236
  return command;
28217
28237
  }
28238
+
28239
+ // src/commands/run/runCommandToCompletion.ts
28218
28240
  function runCommandToCompletion(command, args, env, cwd, quiet) {
28219
28241
  return new Promise((resolveResult) => {
28242
+ if (cwd && !existsSync60(cwd)) {
28243
+ resolveResult({
28244
+ kind: "failed",
28245
+ message: `Failed to execute command: cwd ${cwd} does not exist`
28246
+ });
28247
+ return;
28248
+ }
28220
28249
  const child = spawn9(resolveCommand2(command), args, {
28221
28250
  stdio: quiet ? "pipe" : "inherit",
28222
28251
  env: env ? { ...process.env, ...expandEnv(env) } : void 0,
@@ -28259,7 +28288,13 @@ function runPreCommands(pre, cwd) {
28259
28288
  // src/commands/watch/runWatchBuild.ts
28260
28289
  async function runWatchBuild(entry) {
28261
28290
  const config = findRunConfig(entry);
28262
- const cwd = config.cwd ? resolve18(getConfigDir(), config.cwd) : void 0;
28291
+ let cwd;
28292
+ try {
28293
+ cwd = resolveRunCwd(config);
28294
+ } catch (error) {
28295
+ if (!(error instanceof MissingRunCwdError)) throw error;
28296
+ return { kind: "failed", exitCode: 1, output: error.message };
28297
+ }
28263
28298
  if (config.pre) runPreCommands(config.pre, cwd);
28264
28299
  const result = await runCommandToCompletion(
28265
28300
  config.command,
@@ -28663,13 +28698,10 @@ function registerRoam(program2) {
28663
28698
  configHelp(roamCommand, roamConfigHelp);
28664
28699
  }
28665
28700
 
28666
- // src/commands/run/index.ts
28667
- import { resolve as resolve19 } from "path";
28668
-
28669
28701
  // src/commands/run/formatConfiguredCommands.ts
28670
28702
  function formatConfiguredCommands() {
28671
28703
  const { run: entries } = loadConfig();
28672
- const configs = resolveRunConfigs(entries, getConfigDir());
28704
+ const configs = resolveRunConfigs(entries, runConfigBaseDir());
28673
28705
  if (configs.length === 0) return "\nNo configured commands";
28674
28706
  const names = configs.map((r) => ` ${r.name}`).join("\n");
28675
28707
  return `
@@ -28709,7 +28741,7 @@ function listRunConfigs(verbose) {
28709
28741
  }
28710
28742
  }
28711
28743
  function execRunConfig(config, args) {
28712
- const cwd = config.cwd ? resolve19(getConfigDir(), config.cwd) : void 0;
28744
+ const cwd = resolveRunCwd(config);
28713
28745
  if (config.pre) runPreCommands(config.pre, cwd);
28714
28746
  const resolved = resolveParams(config.params, args);
28715
28747
  spawnRunCommand(
@@ -28876,7 +28908,7 @@ function link2() {
28876
28908
  }
28877
28909
 
28878
28910
  // src/commands/run/remove.ts
28879
- import { existsSync as existsSync59, unlinkSync as unlinkSync21 } from "fs";
28911
+ import { existsSync as existsSync61, unlinkSync as unlinkSync21 } from "fs";
28880
28912
  import { join as join71 } from "path";
28881
28913
  function findRemoveIndex() {
28882
28914
  const idx = process.argv.indexOf("remove");
@@ -28893,7 +28925,7 @@ function parseRemoveName() {
28893
28925
  }
28894
28926
  function deleteCommandFile(name) {
28895
28927
  const filePath = join71(".claude", "commands", `${name}.md`);
28896
- if (existsSync59(filePath)) {
28928
+ if (existsSync61(filePath)) {
28897
28929
  unlinkSync21(filePath);
28898
28930
  console.log(`Deleted command file: ${filePath}`);
28899
28931
  }
@@ -28938,9 +28970,9 @@ function registerRun(program2) {
28938
28970
 
28939
28971
  // src/commands/screenshot/index.ts
28940
28972
  import { execSync as execSync61 } from "child_process";
28941
- import { existsSync as existsSync60, mkdirSync as mkdirSync25, unlinkSync as unlinkSync22, writeFileSync as writeFileSync42 } from "fs";
28973
+ import { existsSync as existsSync62, mkdirSync as mkdirSync25, unlinkSync as unlinkSync22, writeFileSync as writeFileSync42 } from "fs";
28942
28974
  import { tmpdir as tmpdir8 } from "os";
28943
- import { join as join72, resolve as resolve20 } from "path";
28975
+ import { join as join72, resolve as resolve19 } from "path";
28944
28976
  import chalk211 from "chalk";
28945
28977
 
28946
28978
  // src/commands/screenshot/captureWindowPs1.ts
@@ -29070,11 +29102,11 @@ Write-Output $OutputPath
29070
29102
 
29071
29103
  // src/commands/screenshot/index.ts
29072
29104
  function buildOutputPath(outputDir, processName) {
29073
- if (!existsSync60(outputDir)) {
29105
+ if (!existsSync62(outputDir)) {
29074
29106
  mkdirSync25(outputDir, { recursive: true });
29075
29107
  }
29076
29108
  const timestamp6 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
29077
- return resolve20(outputDir, `${processName}-${timestamp6}.png`);
29109
+ return resolve19(outputDir, `${processName}-${timestamp6}.png`);
29078
29110
  }
29079
29111
  function runPowerShellScript(processName, outputPath) {
29080
29112
  const scriptPath = join72(tmpdir8(), `assist-screenshot-${Date.now()}.ps1`);
@@ -29090,7 +29122,7 @@ function runPowerShellScript(processName, outputPath) {
29090
29122
  }
29091
29123
  function screenshot(processName) {
29092
29124
  const config = loadConfig();
29093
- const outputDir = resolve20(config.screenshot.outputDir);
29125
+ const outputDir = resolve19(config.screenshot.outputDir);
29094
29126
  const outputPath = buildOutputPath(outputDir, processName);
29095
29127
  console.log(chalk211.gray(`Capturing window for process "${processName}" ...`));
29096
29128
  try {
@@ -29529,7 +29561,7 @@ import { randomUUID as randomUUID8 } from "crypto";
29529
29561
  function resolveRunConfig(name, cwd) {
29530
29562
  try {
29531
29563
  const { run: run4 } = loadConfigFrom(cwd);
29532
- const configs = resolveRunConfigs(run4, getConfigDirFrom(cwd));
29564
+ const configs = resolveRunConfigs(run4, runConfigBaseDirFrom(cwd));
29533
29565
  const exact = configs.find((r) => r.name === name);
29534
29566
  if (exact) return exact;
29535
29567
  const suffixMatches = configs.filter((r) => r.name.endsWith(`:${name}`));
@@ -29559,11 +29591,11 @@ function readDesignSystemPrompt() {
29559
29591
  }
29560
29592
 
29561
29593
  // src/commands/sessions/daemon/spawnPty.ts
29562
- import { existsSync as existsSync62 } from "fs";
29594
+ import { existsSync as existsSync64 } from "fs";
29563
29595
  import * as pty from "node-pty";
29564
29596
 
29565
29597
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
29566
- import { chmodSync, existsSync as existsSync61, statSync as statSync11 } from "fs";
29598
+ import { chmodSync, existsSync as existsSync63, statSync as statSync11 } from "fs";
29567
29599
  import { createRequire as createRequire3 } from "module";
29568
29600
  import path59 from "path";
29569
29601
  var require4 = createRequire3(import.meta.url);
@@ -29578,7 +29610,7 @@ function ensureSpawnHelperExecutable() {
29578
29610
  `${process.platform}-${process.arch}`,
29579
29611
  "spawn-helper"
29580
29612
  );
29581
- if (!existsSync61(helper)) return;
29613
+ if (!existsSync63(helper)) return;
29582
29614
  const mode = statSync11(helper).mode;
29583
29615
  if ((mode & 73) === 0) chmodSync(helper, mode | 493);
29584
29616
  }
@@ -29614,7 +29646,7 @@ function spawnPty(args, cwd, sessionId, extraEnv) {
29614
29646
  });
29615
29647
  }
29616
29648
  function refuseMissingCwd(cwd, sessionId) {
29617
- if (!cwd || existsSync62(cwd)) return;
29649
+ if (!cwd || existsSync64(cwd)) return;
29618
29650
  daemonLog(
29619
29651
  `${sessionId ? `session ${sessionId}` : "pty"} not spawned: working directory ${cwd} no longer exists`
29620
29652
  );
@@ -29737,11 +29769,11 @@ function setStatus2(session, newStatus) {
29737
29769
  }
29738
29770
 
29739
29771
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
29740
- import { existsSync as existsSync64 } from "fs";
29772
+ import { existsSync as existsSync66 } from "fs";
29741
29773
  import { basename as basename18 } from "path";
29742
29774
 
29743
29775
  // src/commands/sessions/daemon/worktree/deleteStrandedTree.ts
29744
- import { existsSync as existsSync63 } from "fs";
29776
+ import { existsSync as existsSync65 } from "fs";
29745
29777
  import { join as join75 } from "path";
29746
29778
 
29747
29779
  // src/commands/sessions/daemon/worktree/deleteTreeDirectly.ts
@@ -29811,7 +29843,7 @@ async function deleteStrandedTree(clone, worktreePath, cause) {
29811
29843
  );
29812
29844
  }
29813
29845
  function strandedReason(worktreePath, cause) {
29814
- if (!existsSync63(join75(worktreePath, ".git")))
29846
+ if (!existsSync65(join75(worktreePath, ".git")))
29815
29847
  return "its .git link is already gone";
29816
29848
  if (/not a working tree|not a git repository/i.test(reason2(cause)))
29817
29849
  return "git no longer recognises it as a working tree";
@@ -29863,7 +29895,7 @@ function reason3(error) {
29863
29895
 
29864
29896
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
29865
29897
  async function reapWorktree(worktreePath, force = false) {
29866
- if (!existsSync64(worktreePath)) {
29898
+ if (!existsSync66(worktreePath)) {
29867
29899
  forgetWorktree(worktreePath);
29868
29900
  daemonLog(
29869
29901
  `worktree ${worktreePath} already gone; its record was forgotten`
@@ -29888,7 +29920,7 @@ async function reapWorktree(worktreePath, force = false) {
29888
29920
  }
29889
29921
  function owningClone(worktreePath) {
29890
29922
  const recorded = worktreeAttributionIncludingReaped(worktreePath)?.clone;
29891
- if (recorded && existsSync64(recorded)) return recorded;
29923
+ if (recorded && existsSync66(recorded)) return recorded;
29892
29924
  const detected = mainWorktree(worktreePath);
29893
29925
  if (detected) return detected;
29894
29926
  daemonLog(
@@ -30016,12 +30048,12 @@ function closeGateApplies(sessions, session) {
30016
30048
  }
30017
30049
 
30018
30050
  // src/commands/sessions/daemon/worktree/watchGitState.ts
30019
- import { existsSync as existsSync65, watch } from "fs";
30051
+ import { existsSync as existsSync67, watch } from "fs";
30020
30052
  var DEBOUNCE_MS = 500;
30021
30053
  var POLL_MS = 3e4;
30022
30054
  function watchGitState(cwd, onChange) {
30023
30055
  const common = gitCommonDir(cwd);
30024
- if (!common || !existsSync65(common)) return void 0;
30056
+ if (!common || !existsSync67(common)) return void 0;
30025
30057
  const watchers = [
30026
30058
  watchGitDir(common, onChange),
30027
30059
  pollGitState(cwd, onChange)
@@ -30465,12 +30497,25 @@ function emitSessionOutput(session, clients, data) {
30465
30497
  }
30466
30498
 
30467
30499
  // src/commands/sessions/daemon/exitReason.ts
30468
- import { existsSync as existsSync66 } from "fs";
30469
- function exitReason(session, exitCode) {
30500
+ import { existsSync as existsSync68 } from "fs";
30501
+ import { resolve as resolve20 } from "path";
30502
+ function exitDetail(session) {
30503
+ if (session.cwd && !existsSync68(session.cwd))
30504
+ return `working directory ${session.cwd} no longer exists`;
30505
+ return missingRunConfigCwd(session);
30506
+ }
30507
+ function exitReason(exitCode, detail) {
30470
30508
  const base = `process exited with code ${exitCode}`;
30471
- if (session.cwd && !existsSync66(session.cwd))
30472
- return `${base}: working directory ${session.cwd} no longer exists`;
30473
- return base;
30509
+ return detail ? `${base}: ${detail}` : base;
30510
+ }
30511
+ function missingRunConfigCwd(session) {
30512
+ if (session.commandType !== "run" || !session.runName) return void 0;
30513
+ const dir = session.cwd ?? process.cwd();
30514
+ const config = resolveRunConfig(session.runName, dir);
30515
+ if (!config?.cwd) return void 0;
30516
+ const configured = resolve20(runConfigBaseDirFrom(dir), config.cwd);
30517
+ if (existsSync68(configured)) return void 0;
30518
+ return `run config "${config.name}": cwd ${configured} does not exist`;
30474
30519
  }
30475
30520
 
30476
30521
  // src/commands/sessions/daemon/handleFailedResume.ts
@@ -30486,7 +30531,7 @@ function handleFailedResume(session, exitCode, onStatusChange) {
30486
30531
  }
30487
30532
 
30488
30533
  // src/commands/sessions/daemon/watchActivity.ts
30489
- import { existsSync as existsSync67, mkdirSync as mkdirSync26, watch as watch2 } from "fs";
30534
+ import { existsSync as existsSync69, mkdirSync as mkdirSync26, watch as watch2 } from "fs";
30490
30535
  import { dirname as dirname33 } from "path";
30491
30536
 
30492
30537
  // src/commands/sessions/daemon/applyReviewPause.ts
@@ -30567,7 +30612,7 @@ function watchActivity(session, notify2, onClaudeSessionId) {
30567
30612
  if (timer) clearTimeout(timer);
30568
30613
  timer = setTimeout(read, DEBOUNCE_MS2);
30569
30614
  });
30570
- if (existsSync67(path71)) read();
30615
+ if (existsSync69(path71)) read();
30571
30616
  }
30572
30617
  function refreshActivity(session) {
30573
30618
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -30616,9 +30661,10 @@ function handlePtyExit(session, exitCode, onStatusChange) {
30616
30661
  if (handleFailedResume(session, exitCode, onStatusChange)) return;
30617
30662
  const priorStatus = session.status;
30618
30663
  if (exitCode !== 0) {
30619
- session.error = exitReason(session, exitCode);
30664
+ const detail = exitDetail(session);
30665
+ session.error = exitReason(exitCode, detail);
30620
30666
  daemonLog(
30621
- `session ${session.id} ("${session.name}") pty exited with code ${exitCode} from status "${priorStatus}" \u2014 unexpected exit, marking error`
30667
+ `session ${session.id} ("${session.name}") pty exited with code ${exitCode} from status "${priorStatus}" \u2014 unexpected exit, marking error${detail ? `: ${detail}` : ""}`
30622
30668
  );
30623
30669
  onStatusChange(session, "error", exitCode);
30624
30670
  return;
@@ -31892,7 +31938,7 @@ function rearmStoppedSessions(sessions, notify2) {
31892
31938
  }
31893
31939
 
31894
31940
  // src/commands/sessions/daemon/worktree/reconcileWorktreesOnRestore.ts
31895
- import { existsSync as existsSync70 } from "fs";
31941
+ import { existsSync as existsSync72 } from "fs";
31896
31942
  import { basename as basename20 } from "path";
31897
31943
 
31898
31944
  // src/commands/sessions/daemon/worktree/accountedTrees.ts
@@ -31982,9 +32028,9 @@ function capped(lines2) {
31982
32028
  }
31983
32029
 
31984
32030
  // src/commands/sessions/daemon/worktree/reclaimVanishedWorktrees.ts
31985
- import { existsSync as existsSync69 } from "fs";
32031
+ import { existsSync as existsSync71 } from "fs";
31986
32032
  async function reclaimVanishedWorktrees(clone, paths) {
31987
- if (!existsSync69(clone)) {
32033
+ if (!existsSync71(clone)) {
31988
32034
  for (const { path: path71 } of paths) forgetWorktree(path71);
31989
32035
  daemonLog(
31990
32036
  `clone ${clone} is gone; forgot ${paths.length} worktree record(s) it owned`
@@ -32091,7 +32137,7 @@ async function recoverOrphanedWorktrees(sessions, spawnWith, notify2) {
32091
32137
  const accounted = accountedTrees(sessions);
32092
32138
  const vanished = /* @__PURE__ */ new Map();
32093
32139
  for (const { path: path71, clone } of readWorktreeRegistry()) {
32094
- if (!existsSync70(path71)) {
32140
+ if (!existsSync72(path71)) {
32095
32141
  logVanishedTree(sessions, path71);
32096
32142
  vanished.set(clone, [
32097
32143
  ...vanished.get(clone) ?? [],
@@ -32556,13 +32602,13 @@ async function defaultConnect() {
32556
32602
  }
32557
32603
 
32558
32604
  // src/commands/sessions/daemon/hasPersistedWindowsSessions.ts
32559
- import { existsSync as existsSync71, readFileSync as readFileSync51 } from "fs";
32605
+ import { existsSync as existsSync73, readFileSync as readFileSync51 } from "fs";
32560
32606
  import { posix } from "path";
32561
32607
  function hasPersistedWindowsSessions() {
32562
32608
  const sessionsFile = windowsSessionsFileFromWsl();
32563
32609
  if (!sessionsFile) return false;
32564
32610
  try {
32565
- if (!existsSync71(sessionsFile)) return false;
32611
+ if (!existsSync73(sessionsFile)) return false;
32566
32612
  const data = JSON.parse(readFileSync51(sessionsFile, "utf8"));
32567
32613
  return Array.isArray(data) && data.length > 0;
32568
32614
  } catch (error) {
@@ -33537,9 +33583,9 @@ function safeParse2(line) {
33537
33583
  }
33538
33584
 
33539
33585
  // src/commands/sessions/daemon/repoDirExists.ts
33540
- import { existsSync as existsSync72 } from "fs";
33586
+ import { existsSync as existsSync74 } from "fs";
33541
33587
  function repoDirExists(cwd) {
33542
- return existsSync72(toGitCwd(cwd));
33588
+ return existsSync74(toGitCwd(cwd));
33543
33589
  }
33544
33590
 
33545
33591
  // src/commands/sessions/daemon/withRepoGroups.ts
@@ -34546,7 +34592,7 @@ async function update2() {
34546
34592
  // src/reportCliError.ts
34547
34593
  import chalk217 from "chalk";
34548
34594
  function reportCliError(error) {
34549
- if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError) {
34595
+ if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError || error instanceof MissingRunCwdError) {
34550
34596
  console.error(chalk217.red(error.message));
34551
34597
  } else {
34552
34598
  console.error(error);