@staff0rd/assist 0.390.0 → 0.391.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.390.0",
9
+ version: "0.391.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -43,7 +43,9 @@ var package_default = {
43
43
  url: "https://github.com/staff0rd/assist"
44
44
  },
45
45
  dependencies: {
46
+ "@xterm/addon-fit": "^0.11.0",
46
47
  "@xterm/addon-webgl": "^0.19.0",
48
+ "@xterm/xterm": "^6.0.0",
47
49
  "better-sqlite3": "^12.8.0",
48
50
  blessed: "^0.1.81",
49
51
  "blessed-contrib": "^4.11.0",
@@ -95,8 +97,6 @@ var package_default = {
95
97
  "@types/shell-quote": "^1.7.5",
96
98
  "@types/ws": "^8.18.1",
97
99
  "@vitest/coverage-v8": "^4.1.2",
98
- "@xterm/addon-fit": "^0.11.0",
99
- "@xterm/xterm": "^6.0.0",
100
100
  esbuild: "^0.27.3",
101
101
  jscpd: "^4.0.5",
102
102
  jsdom: "^29.1.1",
@@ -140,10 +140,10 @@ import { stringify as stringifyYaml } from "yaml";
140
140
  // src/shared/loadRawYaml.ts
141
141
  import { existsSync, readFileSync } from "fs";
142
142
  import { parse as parseYaml } from "yaml";
143
- function loadRawYaml(path61) {
144
- if (!existsSync(path61)) return {};
143
+ function loadRawYaml(path63) {
144
+ if (!existsSync(path63)) return {};
145
145
  try {
146
- const content = readFileSync(path61, "utf8");
146
+ const content = readFileSync(path63, "utf8");
147
147
  return parseYaml(content) || {};
148
148
  } catch {
149
149
  return {};
@@ -342,6 +342,10 @@ var assistConfigSchema = z2.strictObject({
342
342
  sync: z2.strictObject({
343
343
  autoConfirm: z2.boolean().default(false)
344
344
  }).default({ autoConfirm: false }),
345
+ harness: z2.strictObject({
346
+ engine: z2.enum(["claude", "codex"]).default("claude"),
347
+ exposeCodexActions: z2.boolean().optional()
348
+ }).default({ engine: "claude" }),
345
349
  voice: z2.strictObject({
346
350
  wakeWords: z2.array(z2.string()).default(DEFAULT_WAKE_WORDS),
347
351
  mic: z2.string().optional(),
@@ -1356,8 +1360,8 @@ function findUnmergedPaths() {
1356
1360
  }
1357
1361
  const found = /* @__PURE__ */ new Set();
1358
1362
  for (const line of output.split("\n")) {
1359
- const path61 = line.split(" ")[1];
1360
- if (path61) found.add(path61.trim());
1363
+ const path63 = line.split(" ")[1];
1364
+ if (path63) found.add(path63.trim());
1361
1365
  }
1362
1366
  return [...found];
1363
1367
  }
@@ -1456,8 +1460,8 @@ function getPreferredRemoteRepo(cwd) {
1456
1460
  function gitRefUrl(kind, ref, cwd) {
1457
1461
  const repo = getPreferredRemoteRepo(cwd);
1458
1462
  if (!repo) return void 0;
1459
- const path61 = kind === "branch" ? "tree" : "commit";
1460
- return `https://github.com/${repo.org}/${repo.repo}/${path61}/${ref}`;
1463
+ const path63 = kind === "branch" ? "tree" : "commit";
1464
+ return `https://github.com/${repo.org}/${repo.repo}/${path63}/${ref}`;
1461
1465
  }
1462
1466
 
1463
1467
  // src/commands/commit/collectCommitRefs.ts
@@ -3228,9 +3232,9 @@ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
3228
3232
 
3229
3233
  // src/commands/verify/forbiddenStrings/findForbiddenStrings.ts
3230
3234
  import { minimatch as minimatch2 } from "minimatch";
3231
- function resolveStringsAtPath(data, path61) {
3235
+ function resolveStringsAtPath(data, path63) {
3232
3236
  let current = data;
3233
- for (const segment of path61.split(".")) {
3237
+ for (const segment of path63.split(".")) {
3234
3238
  if (current === null || typeof current !== "object") return [];
3235
3239
  current = current[segment];
3236
3240
  }
@@ -3243,10 +3247,10 @@ function resolveStringsAtPath(data, path61) {
3243
3247
  }
3244
3248
  function findRuleViolations(data, rule) {
3245
3249
  const violations = [];
3246
- for (const path61 of rule.paths) {
3247
- for (const value of resolveStringsAtPath(data, path61)) {
3250
+ for (const path63 of rule.paths) {
3251
+ for (const value of resolveStringsAtPath(data, path63)) {
3248
3252
  if (minimatch2(value, rule.disallowed))
3249
- violations.push({ file: rule.file, path: path61, value });
3253
+ violations.push({ file: rule.file, path: path63, value });
3250
3254
  }
3251
3255
  }
3252
3256
  return violations;
@@ -3285,8 +3289,8 @@ function forbiddenStrings() {
3285
3289
  process.exit(0);
3286
3290
  }
3287
3291
  console.log("Forbidden strings found:\n");
3288
- for (const { file, path: path61, value } of violations) {
3289
- console.log(` ${file} ${path61}: ${value}`);
3292
+ for (const { file, path: path63, value } of violations) {
3293
+ console.log(` ${file} ${path63}: ${value}`);
3290
3294
  }
3291
3295
  console.log(`
3292
3296
  Total: ${violations.length} forbidden string(s).`);
@@ -3578,15 +3582,15 @@ function readBaselineMigrations(repoRelativeDir, ref) {
3578
3582
  } catch {
3579
3583
  return baseline;
3580
3584
  }
3581
- const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path61) => MIGRATION_FILE3.test(basename(path61)));
3582
- for (const path61 of paths) {
3585
+ const paths = listing.split("\n").map((line) => line.trim()).filter(Boolean).filter((path63) => MIGRATION_FILE3.test(basename(path63)));
3586
+ for (const path63 of paths) {
3583
3587
  try {
3584
- const content = execSync12(`git show "${ref}:${path61}"`, {
3588
+ const content = execSync12(`git show "${ref}:${path63}"`, {
3585
3589
  encoding: "utf8",
3586
3590
  maxBuffer: 16 * 1024 * 1024,
3587
3591
  stdio: ["pipe", "pipe", "pipe"]
3588
3592
  });
3589
- baseline.set(basename(path61), content);
3593
+ baseline.set(basename(path63), content);
3590
3594
  } catch {
3591
3595
  }
3592
3596
  }
@@ -4906,9 +4910,6 @@ function findUnblockedTodos(items2) {
4906
4910
  // src/commands/backlog/run.ts
4907
4911
  import chalk44 from "chalk";
4908
4912
 
4909
- // src/shared/spawnClaude.ts
4910
- import { spawn as spawn3 } from "child_process";
4911
-
4912
4913
  // src/commands/sessions/daemon/ensureHooksSettings.ts
4913
4914
  import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync15 } from "fs";
4914
4915
  import { dirname as dirname12 } from "path";
@@ -4954,10 +4955,29 @@ var hooksSettings = {
4954
4955
  }
4955
4956
  };
4956
4957
  function ensureHooksSettings() {
4957
- const path61 = daemonPaths.hooksSettings;
4958
- mkdirSync5(dirname12(path61), { recursive: true });
4959
- writeFileSync15(path61, JSON.stringify(hooksSettings, null, 2));
4960
- return path61;
4958
+ const path63 = daemonPaths.hooksSettings;
4959
+ mkdirSync5(dirname12(path63), { recursive: true });
4960
+ writeFileSync15(path63, JSON.stringify(hooksSettings, null, 2));
4961
+ return path63;
4962
+ }
4963
+
4964
+ // src/shared/spawnInherit.ts
4965
+ import { spawn as spawn3 } from "child_process";
4966
+ function spawnInherit(command, args) {
4967
+ const {
4968
+ ASSIST_ACTIVITY_ID: _activityId,
4969
+ CLAUDE_CODE_CHILD_SESSION: _childSession,
4970
+ ...env
4971
+ } = process.env;
4972
+ const child = spawn3(command, args, {
4973
+ stdio: "inherit",
4974
+ env
4975
+ });
4976
+ const done2 = new Promise((resolve18, reject) => {
4977
+ child.on("close", (code) => resolve18(code ?? 0));
4978
+ child.on("error", reject);
4979
+ });
4980
+ return { child, done: done2 };
4961
4981
  }
4962
4982
 
4963
4983
  // src/shared/spawnClaude.ts
@@ -4976,20 +4996,7 @@ function spawnClaude(prompt, options2 = {}) {
4976
4996
  if (permissionMode) {
4977
4997
  args.push("--permission-mode", permissionMode);
4978
4998
  }
4979
- const {
4980
- ASSIST_ACTIVITY_ID: _activityId,
4981
- CLAUDE_CODE_CHILD_SESSION: _childSession,
4982
- ...env
4983
- } = process.env;
4984
- const child = spawn3("claude", args, {
4985
- stdio: "inherit",
4986
- env
4987
- });
4988
- const done2 = new Promise((resolve18, reject) => {
4989
- child.on("close", (code) => resolve18(code ?? 0));
4990
- child.on("error", reject);
4991
- });
4992
- return { child, done: done2 };
4999
+ return spawnInherit("claude", args);
4993
5000
  }
4994
5001
  function buildArgs(prompt, options2) {
4995
5002
  if (options2.resumeSessionId) {
@@ -5215,9 +5222,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
5215
5222
  function backupLocalBacklogFiles(dir) {
5216
5223
  const moved = [];
5217
5224
  for (const name of LOCAL_FILES) {
5218
- const path61 = join15(dir, ".assist", name);
5219
- if (existsSync18(path61)) {
5220
- renameSync(path61, `${path61}.bak`);
5225
+ const path63 = join15(dir, ".assist", name);
5226
+ if (existsSync18(path63)) {
5227
+ renameSync(path63, `${path63}.bak`);
5221
5228
  moved.push(`${name} \u2192 ${name}.bak`);
5222
5229
  }
5223
5230
  }
@@ -5656,8 +5663,8 @@ var backlogItemSchema = z3.strictObject({
5656
5663
  var backlogFileSchema = z3.array(backlogItemSchema);
5657
5664
 
5658
5665
  // src/commands/backlog/parseBacklogJsonl.ts
5659
- function parseBacklogJsonl(path61) {
5660
- const content = readFileSync14(path61, "utf8").trim();
5666
+ function parseBacklogJsonl(path63) {
5667
+ const content = readFileSync14(path63, "utf8").trim();
5661
5668
  if (content.length === 0) return [];
5662
5669
  return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
5663
5670
  }
@@ -5739,8 +5746,8 @@ function findBacklogUp(startDir) {
5739
5746
 
5740
5747
  // src/commands/backlog/getCurrentOrigin.ts
5741
5748
  import { execFileSync } from "child_process";
5742
- function stripLeadingSlashes(path61) {
5743
- return path61.replace(/^\/+/, "");
5749
+ function stripLeadingSlashes(path63) {
5750
+ return path63.replace(/^\/+/, "");
5744
5751
  }
5745
5752
  function normalizeOrigin(raw) {
5746
5753
  const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
@@ -6280,24 +6287,24 @@ function getOwnerPath(itemId2) {
6280
6287
  function recordSignalOwner(itemId2) {
6281
6288
  const sessionId = process.env.ASSIST_SESSION_ID;
6282
6289
  if (!sessionId) return;
6283
- const path61 = getOwnerPath(itemId2);
6284
- mkdirSync7(dirname14(path61), { recursive: true });
6285
- writeFileSync17(path61, JSON.stringify({ sessionId }));
6290
+ const path63 = getOwnerPath(itemId2);
6291
+ mkdirSync7(dirname14(path63), { recursive: true });
6292
+ writeFileSync17(path63, JSON.stringify({ sessionId }));
6286
6293
  }
6287
6294
  function readSignalOwner(itemId2) {
6288
- const path61 = getOwnerPath(itemId2);
6289
- if (!existsSync21(path61)) return void 0;
6295
+ const path63 = getOwnerPath(itemId2);
6296
+ if (!existsSync21(path63)) return void 0;
6290
6297
  try {
6291
- const parsed = JSON.parse(readFileSync15(path61, "utf8"));
6298
+ const parsed = JSON.parse(readFileSync15(path63, "utf8"));
6292
6299
  return parsed.sessionId;
6293
6300
  } catch {
6294
6301
  return void 0;
6295
6302
  }
6296
6303
  }
6297
6304
  function clearSignalOwner(itemId2) {
6298
- const path61 = getOwnerPath(itemId2);
6305
+ const path63 = getOwnerPath(itemId2);
6299
6306
  try {
6300
- rmSync(path61);
6307
+ rmSync(path63);
6301
6308
  } catch {
6302
6309
  }
6303
6310
  }
@@ -6334,19 +6341,19 @@ function resolveSignalTarget(event, data) {
6334
6341
  function writeSignal(event, data) {
6335
6342
  const target = resolveSignalTarget(event, data);
6336
6343
  if (!target) return;
6337
- const path61 = getSignalPath(target);
6338
- if (!path61) return;
6344
+ const path63 = getSignalPath(target);
6345
+ if (!path63) return;
6339
6346
  const signal = { event, sessionId: target, ...data };
6340
- mkdirSync8(dirname15(path61), { recursive: true });
6341
- writeFileSync18(path61, JSON.stringify(signal));
6347
+ mkdirSync8(dirname15(path63), { recursive: true });
6348
+ writeFileSync18(path63, JSON.stringify(signal));
6342
6349
  }
6343
6350
 
6344
6351
  // src/commands/backlog/readSignal.ts
6345
6352
  function readSignal() {
6346
- const path61 = getSignalPath();
6347
- if (!path61 || !existsSync22(path61)) return void 0;
6353
+ const path63 = getSignalPath();
6354
+ if (!path63 || !existsSync22(path63)) return void 0;
6348
6355
  try {
6349
- return JSON.parse(readFileSync16(path61, "utf8"));
6356
+ return JSON.parse(readFileSync16(path63, "utf8"));
6350
6357
  } catch {
6351
6358
  return void 0;
6352
6359
  }
@@ -6441,13 +6448,13 @@ function activityPath(sessionId) {
6441
6448
  function emitActivity(activity2) {
6442
6449
  const sessionId = process.env.ASSIST_ACTIVITY_ID;
6443
6450
  if (!sessionId) return;
6444
- const path61 = activityPath(sessionId);
6445
- mkdirSync9(dirname16(path61), { recursive: true });
6446
- writeFileSync19(path61, JSON.stringify({ ...activity2, startedAt: Date.now() }));
6451
+ const path63 = activityPath(sessionId);
6452
+ mkdirSync9(dirname16(path63), { recursive: true });
6453
+ writeFileSync19(path63, JSON.stringify({ ...activity2, startedAt: Date.now() }));
6447
6454
  }
6448
- function readActivity(path61) {
6455
+ function readActivity(path63) {
6449
6456
  try {
6450
- return JSON.parse(readFileSync17(path61, "utf8"));
6457
+ return JSON.parse(readFileSync17(path63, "utf8"));
6451
6458
  } catch {
6452
6459
  return void 0;
6453
6460
  }
@@ -6457,9 +6464,9 @@ function reconcileActivity(sessionId, activity2) {
6457
6464
  removeActivity(sessionId);
6458
6465
  return;
6459
6466
  }
6460
- const path61 = activityPath(sessionId);
6461
- mkdirSync9(dirname16(path61), { recursive: true });
6462
- writeFileSync19(path61, JSON.stringify(activity2));
6467
+ const path63 = activityPath(sessionId);
6468
+ mkdirSync9(dirname16(path63), { recursive: true });
6469
+ writeFileSync19(path63, JSON.stringify(activity2));
6463
6470
  }
6464
6471
  function removeActivity(sessionId) {
6465
6472
  try {
@@ -7690,8 +7697,8 @@ async function getBacklogExists(req, res) {
7690
7697
  // src/commands/backlog/originDisplayName.ts
7691
7698
  function originDisplayName(origin) {
7692
7699
  if (origin.startsWith("local:")) {
7693
- const path61 = origin.slice("local:".length).replace(/\/+$/, "");
7694
- const segments = path61.split("/").filter(Boolean);
7700
+ const path63 = origin.slice("local:".length).replace(/\/+$/, "");
7701
+ const segments = path63.split("/").filter(Boolean);
7695
7702
  return segments[segments.length - 1] ?? origin;
7696
7703
  }
7697
7704
  const firstSlash = origin.indexOf("/");
@@ -8082,7 +8089,7 @@ function findSynthesisForBranch(repoReviewsDir, branch2) {
8082
8089
  const parent = dirname20(branchKeyPath);
8083
8090
  const branchPrefix = basename5(branchKeyPath);
8084
8091
  if (!existsSync25(parent)) return null;
8085
- const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join23(parent, name, "synthesis.md")).filter((path61) => existsSync25(path61)).map((path61) => ({ path: path61, mtime: statSync2(path61).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
8092
+ const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join23(parent, name, "synthesis.md")).filter((path63) => existsSync25(path63)).map((path63) => ({ path: path63, mtime: statSync2(path63).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
8086
8093
  return synthesisFiles[0]?.path ?? null;
8087
8094
  }
8088
8095
 
@@ -8131,12 +8138,12 @@ async function getReviewSynthesis(req, res) {
8131
8138
  const cwd = getCwdParam(req, res);
8132
8139
  if (!cwd) return;
8133
8140
  try {
8134
- const path61 = await resolveSynthesisPath(cwd);
8135
- if (!path61) {
8141
+ const path63 = await resolveSynthesisPath(cwd);
8142
+ if (!path63) {
8136
8143
  respondJson(res, 404, { error: "No synthesis found" });
8137
8144
  return;
8138
8145
  }
8139
- respondJson(res, 200, { synthesis: readFileSync19(path61, "utf8") });
8146
+ respondJson(res, 200, { synthesis: readFileSync19(path63, "utf8") });
8140
8147
  } catch {
8141
8148
  respondJson(res, 404, { error: "No synthesis found" });
8142
8149
  }
@@ -8203,21 +8210,78 @@ function runGitStatus(cwd) {
8203
8210
  }).then((r) => r.stdout);
8204
8211
  }
8205
8212
 
8213
+ // src/shared/harnesses.ts
8214
+ import * as os2 from "os";
8215
+ import * as path25 from "path";
8216
+
8217
+ // src/shared/checkCliAvailable.ts
8218
+ import { execSync as execSync29 } from "child_process";
8219
+ function checkCliAvailable(cli) {
8220
+ const binary = cli.split(/\s+/)[0];
8221
+ const opts = {
8222
+ encoding: "utf8",
8223
+ stdio: ["ignore", "pipe", "pipe"]
8224
+ };
8225
+ try {
8226
+ execSync29(`command -v ${binary}`, opts);
8227
+ return true;
8228
+ } catch {
8229
+ try {
8230
+ execSync29(`where ${binary}`, opts);
8231
+ return true;
8232
+ } catch {
8233
+ return false;
8234
+ }
8235
+ }
8236
+ }
8237
+
8238
+ // src/shared/harnesses.ts
8239
+ var harnesses = {
8240
+ claude: {
8241
+ kind: "claude",
8242
+ command: "claude",
8243
+ homeDir: path25.join(os2.homedir(), ".claude"),
8244
+ sync: {
8245
+ agentsFile: "CLAUDE.md",
8246
+ commandDest: (name) => path25.join("commands", `${name}.md`)
8247
+ }
8248
+ },
8249
+ codex: {
8250
+ kind: "codex",
8251
+ command: "codex",
8252
+ homeDir: path25.join(os2.homedir(), ".codex"),
8253
+ sync: {
8254
+ agentsFile: "AGENTS.md",
8255
+ commandDest: (name) => path25.join("skills", name, "SKILL.md")
8256
+ }
8257
+ }
8258
+ };
8259
+ function isHarnessAvailable(kind) {
8260
+ return checkCliAvailable(harnesses[kind].command);
8261
+ }
8262
+
8263
+ // src/commands/sessions/web/harnessCapabilities.ts
8264
+ function harnessCapabilities(_req, res) {
8265
+ const forcedOff = loadConfig().harness.exposeCodexActions === false;
8266
+ const exposeCodexActions = !forcedOff && isHarnessAvailable("codex");
8267
+ respondJson(res, 200, { exposeCodexActions });
8268
+ }
8269
+
8206
8270
  // src/shared/loadJson.ts
8207
8271
  import { existsSync as existsSync26, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync20 } from "fs";
8208
- import { homedir as homedir12 } from "os";
8209
- import { join as join25 } from "path";
8272
+ import { homedir as homedir13 } from "os";
8273
+ import { join as join26 } from "path";
8210
8274
  function getStoreDir() {
8211
- return join25(homedir12(), ".assist");
8275
+ return join26(homedir13(), ".assist");
8212
8276
  }
8213
8277
  function getStorePath(filename) {
8214
- return join25(getStoreDir(), filename);
8278
+ return join26(getStoreDir(), filename);
8215
8279
  }
8216
8280
  function loadJson(filename) {
8217
- const path61 = getStorePath(filename);
8218
- if (existsSync26(path61)) {
8281
+ const path63 = getStorePath(filename);
8282
+ if (existsSync26(path63)) {
8219
8283
  try {
8220
- return JSON.parse(readFileSync20(path61, "utf8"));
8284
+ return JSON.parse(readFileSync20(path63, "utf8"));
8221
8285
  } catch {
8222
8286
  return {};
8223
8287
  }
@@ -8689,6 +8753,7 @@ var routes2 = {
8689
8753
  "GET /api/github-url": githubUrl,
8690
8754
  "GET /api/git-status": gitStatus,
8691
8755
  "GET /api/jira-site": jiraSite,
8756
+ "GET /api/harness": harnessCapabilities,
8692
8757
  "GET /api/pr-status": prStatus,
8693
8758
  "GET /api/pr-list": prList,
8694
8759
  "GET /api/news/items": listNewsItems,
@@ -9139,12 +9204,12 @@ import chalk64 from "chalk";
9139
9204
  import { eq as eq18 } from "drizzle-orm";
9140
9205
 
9141
9206
  // src/commands/jira/fetchIssue.ts
9142
- import { execSync as execSync29 } from "child_process";
9207
+ import { execSync as execSync30 } from "child_process";
9143
9208
  import chalk63 from "chalk";
9144
9209
  function fetchIssue(issueKey, fields) {
9145
9210
  let result;
9146
9211
  try {
9147
- result = execSync29(
9212
+ result = execSync30(
9148
9213
  `acli jira workitem view ${issueKey} -f ${fields} --json`,
9149
9214
  { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }
9150
9215
  );
@@ -9563,7 +9628,7 @@ function ensureRemoteOrigin() {
9563
9628
  import { spawnSync as spawnSync2 } from "child_process";
9564
9629
  import { mkdtempSync, readFileSync as readFileSync22, unlinkSync as unlinkSync6, writeFileSync as writeFileSync21 } from "fs";
9565
9630
  import { tmpdir } from "os";
9566
- import { join as join26 } from "path";
9631
+ import { join as join27 } from "path";
9567
9632
  import enquirer6 from "enquirer";
9568
9633
  async function promptType() {
9569
9634
  const { type } = await enquirer6.prompt({
@@ -9603,8 +9668,8 @@ async function promptDescription() {
9603
9668
  }
9604
9669
  function openEditor() {
9605
9670
  const editor = process.env.EDITOR || process.env.VISUAL || "vi";
9606
- const dir = mkdtempSync(join26(tmpdir(), "assist-"));
9607
- const filePath = join26(dir, "description.md");
9671
+ const dir = mkdtempSync(join27(tmpdir(), "assist-"));
9672
+ const filePath = join27(dir, "description.md");
9608
9673
  writeFileSync21(filePath, "");
9609
9674
  const result = spawnSync2(editor, [filePath], { stdio: "inherit" });
9610
9675
  if (result.status !== 0) {
@@ -10003,6 +10068,24 @@ import enquirer7 from "enquirer";
10003
10068
  // src/commands/backlog/launchMode.ts
10004
10069
  import { randomUUID as randomUUID2 } from "crypto";
10005
10070
 
10071
+ // src/shared/spawnCodex.ts
10072
+ function spawnCodex(prompt, options2 = {}) {
10073
+ const cwd = options2.cwd ?? process.cwd();
10074
+ return spawnInherit(harnesses.codex.command, ["-C", cwd, prompt]);
10075
+ }
10076
+
10077
+ // src/shared/spawnHarness.ts
10078
+ function spawnHarness(harness, prompt, options2 = {}) {
10079
+ if (harness === "codex") {
10080
+ return spawnCodex(prompt, { cwd: options2.cwd });
10081
+ }
10082
+ return spawnClaude(prompt, {
10083
+ allowEdits: true,
10084
+ sessionId: options2.sessionId,
10085
+ resumeSessionId: options2.resumeSessionId
10086
+ });
10087
+ }
10088
+
10006
10089
  // src/commands/backlog/handleLaunchSignal.ts
10007
10090
  import chalk81 from "chalk";
10008
10091
 
@@ -10103,10 +10186,12 @@ async function launchMode(slashCommand, options2) {
10103
10186
  itemName: options2?.itemName,
10104
10187
  claudeSessionId
10105
10188
  });
10106
- const { child, done: done2 } = spawnClaude(
10107
- resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description),
10108
- { allowEdits: true, sessionId: claudeSessionId, resumeSessionId }
10109
- );
10189
+ const prompt = resumeSessionId ? resumeNudge() : buildSlashCommand(slashCommand, options2?.description);
10190
+ const { child, done: done2 } = spawnHarness(options2?.harness ?? "claude", prompt, {
10191
+ sessionId: claudeSessionId,
10192
+ resumeSessionId,
10193
+ cwd: process.cwd()
10194
+ });
10110
10195
  const marker = watchForMarker(child, { actOnDone: options2?.once });
10111
10196
  const exitCode = await awaitClaude(done2, `/${slashCommand}`);
10112
10197
  stopWatching();
@@ -10156,10 +10241,22 @@ async function refine(id, options2) {
10156
10241
  });
10157
10242
  }
10158
10243
 
10244
+ // src/commands/backlog/resolveHarness.ts
10245
+ function resolveHarness(value) {
10246
+ if (value === "claude" || value === "codex") return value;
10247
+ return loadConfig().harness.engine;
10248
+ }
10249
+
10159
10250
  // src/commands/backlog/registerRefineCommand.ts
10160
10251
  function registerRefineCommand(cmd) {
10161
- cmd.command("refine").argument("[id]", "Backlog item ID").description("Alias for refine").option("--once", "Exit when the initial task completes").action(
10162
- (id, opts) => refine(id, { once: opts.once })
10252
+ cmd.command("refine").argument("[id]", "Backlog item ID").description("Alias for refine").option("--once", "Exit when the initial task completes").option(
10253
+ "--harness <kind>",
10254
+ "Coding harness to launch (claude|codex); defaults to the configured harness.engine"
10255
+ ).action(
10256
+ (id, opts) => refine(id, {
10257
+ once: opts.once,
10258
+ harness: resolveHarness(opts.harness)
10259
+ })
10163
10260
  );
10164
10261
  }
10165
10262
 
@@ -11335,12 +11432,12 @@ function findBuiltinDenyRaw(rawCommand) {
11335
11432
 
11336
11433
  // src/commands/cliHook/logDeniedToolCall.ts
11337
11434
  import { mkdirSync as mkdirSync12 } from "fs";
11338
- import { homedir as homedir13 } from "os";
11339
- import { join as join27 } from "path";
11435
+ import { homedir as homedir14 } from "os";
11436
+ import { join as join28 } from "path";
11340
11437
  import Database from "better-sqlite3";
11341
11438
  var _db;
11342
11439
  function getDbDir() {
11343
- return join27(homedir13(), ".assist");
11440
+ return join28(homedir14(), ".assist");
11344
11441
  }
11345
11442
  function initSchema(db) {
11346
11443
  db.exec(`
@@ -11359,7 +11456,7 @@ function openPromptsDb(dir) {
11359
11456
  if (_db) return _db;
11360
11457
  const dbDir = dir ?? getDbDir();
11361
11458
  mkdirSync12(dbDir, { recursive: true });
11362
- const db = new Database(join27(dbDir, "assist.db"));
11459
+ const db = new Database(join28(dbDir, "assist.db"));
11363
11460
  db.pragma("journal_mode = WAL");
11364
11461
  initSchema(db);
11365
11462
  _db = db;
@@ -11469,9 +11566,9 @@ var __dirname4 = dirname21(__filename3);
11469
11566
  function packageRoot() {
11470
11567
  return __dirname4;
11471
11568
  }
11472
- function readLines(path61) {
11473
- if (!existsSync27(path61)) return [];
11474
- return readFileSync23(path61, "utf8").split("\n").filter((line) => line.trim() !== "");
11569
+ function readLines(path63) {
11570
+ if (!existsSync27(path63)) return [];
11571
+ return readFileSync23(path63, "utf8").split("\n").filter((line) => line.trim() !== "");
11475
11572
  }
11476
11573
  var cachedReads;
11477
11574
  var cachedWrites;
@@ -11518,13 +11615,13 @@ function findCliWrite(command) {
11518
11615
 
11519
11616
  // src/shared/readSettingsPerms.ts
11520
11617
  import { existsSync as existsSync28, readFileSync as readFileSync24 } from "fs";
11521
- import { homedir as homedir14 } from "os";
11522
- import { join as join28 } from "path";
11618
+ import { homedir as homedir15 } from "os";
11619
+ import { join as join29 } from "path";
11523
11620
  function readSettingsPerms(key) {
11524
11621
  const paths = [
11525
- join28(homedir14(), ".claude", "settings.json"),
11526
- join28(process.cwd(), ".claude", "settings.json"),
11527
- join28(process.cwd(), ".claude", "settings.local.json")
11622
+ join29(homedir15(), ".claude", "settings.json"),
11623
+ join29(process.cwd(), ".claude", "settings.json"),
11624
+ join29(process.cwd(), ".claude", "settings.local.json")
11528
11625
  ];
11529
11626
  const entries = [];
11530
11627
  for (const p of paths) {
@@ -11798,29 +11895,8 @@ ${reasons.join("\n")}`);
11798
11895
 
11799
11896
  // src/commands/permitCliReads/index.ts
11800
11897
  import { existsSync as existsSync29, mkdirSync as mkdirSync13, readFileSync as readFileSync25, writeFileSync as writeFileSync23 } from "fs";
11801
- import { homedir as homedir15 } from "os";
11802
- import { join as join29 } from "path";
11803
-
11804
- // src/shared/checkCliAvailable.ts
11805
- import { execSync as execSync30 } from "child_process";
11806
- function checkCliAvailable(cli) {
11807
- const binary = cli.split(/\s+/)[0];
11808
- const opts = {
11809
- encoding: "utf8",
11810
- stdio: ["ignore", "pipe", "pipe"]
11811
- };
11812
- try {
11813
- execSync30(`command -v ${binary}`, opts);
11814
- return true;
11815
- } catch {
11816
- try {
11817
- execSync30(`where ${binary}`, opts);
11818
- return true;
11819
- } catch {
11820
- return false;
11821
- }
11822
- }
11823
- }
11898
+ import { homedir as homedir16 } from "os";
11899
+ import { join as join30 } from "path";
11824
11900
 
11825
11901
  // src/commands/permitCliReads/assertCliExists.ts
11826
11902
  function assertCliExists(cli) {
@@ -11936,14 +12012,14 @@ function showProgress(p, label2) {
11936
12012
  const pct = Math.round(p.done / p.total * 100);
11937
12013
  process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
11938
12014
  }
11939
- async function resolveCommand(cli, path61, description, depth, p) {
11940
- showProgress(p, path61.join(" "));
11941
- const subHelp = await runHelp([cli, ...path61]);
12015
+ async function resolveCommand(cli, path63, description, depth, p) {
12016
+ showProgress(p, path63.join(" "));
12017
+ const subHelp = await runHelp([cli, ...path63]);
11942
12018
  if (!subHelp || !hasSubcommands(subHelp)) {
11943
- return [{ path: path61, description }];
12019
+ return [{ path: path63, description }];
11944
12020
  }
11945
- const children = await discoverAt(cli, path61, depth + 1, p);
11946
- return children.length > 0 ? children : [{ path: path61, description }];
12021
+ const children = await discoverAt(cli, path63, depth + 1, p);
12022
+ return children.length > 0 ? children : [{ path: path63, description }];
11947
12023
  }
11948
12024
  async function discoverAt(cli, parentPath, depth, p) {
11949
12025
  if (depth > SAFETY_DEPTH) return [];
@@ -12088,15 +12164,15 @@ function updateSettings(cli, commands) {
12088
12164
  // src/commands/permitCliReads/index.ts
12089
12165
  function logPath(cli) {
12090
12166
  const safeName = cli.replace(/\s+/g, "-");
12091
- return join29(homedir15(), ".assist", `cli-discover-${safeName}.log`);
12167
+ return join30(homedir16(), ".assist", `cli-discover-${safeName}.log`);
12092
12168
  }
12093
12169
  function readCache(cli) {
12094
- const path61 = logPath(cli);
12095
- if (!existsSync29(path61)) return void 0;
12096
- return readFileSync25(path61, "utf8");
12170
+ const path63 = logPath(cli);
12171
+ if (!existsSync29(path63)) return void 0;
12172
+ return readFileSync25(path63, "utf8");
12097
12173
  }
12098
12174
  function writeCache(cli, output) {
12099
- const dir = join29(homedir15(), ".assist");
12175
+ const dir = join30(homedir16(), ".assist");
12100
12176
  mkdirSync13(dir, { recursive: true });
12101
12177
  writeFileSync23(logPath(cli), output);
12102
12178
  }
@@ -12243,18 +12319,18 @@ import { existsSync as existsSync31, readFileSync as readFileSync27, unlinkSync
12243
12319
  import chalk109 from "chalk";
12244
12320
 
12245
12321
  // src/commands/codeComment/getRestrictedDir.ts
12246
- import { homedir as homedir16 } from "os";
12247
- import { join as join30 } from "path";
12322
+ import { homedir as homedir17 } from "os";
12323
+ import { join as join31 } from "path";
12248
12324
  function getRestrictedDir() {
12249
- return join30(homedir16(), ".assist", "restricted");
12325
+ return join31(homedir17(), ".assist", "restricted");
12250
12326
  }
12251
12327
  function getPinStatePath(pin) {
12252
- return join30(getRestrictedDir(), `code-comment-${pin}.json`);
12328
+ return join31(getRestrictedDir(), `code-comment-${pin}.json`);
12253
12329
  }
12254
12330
 
12255
12331
  // src/commands/codeComment/sweepRestrictedDir.ts
12256
12332
  import { readdirSync as readdirSync3, statSync as statSync3, unlinkSync as unlinkSync7 } from "fs";
12257
- import { join as join31 } from "path";
12333
+ import { join as join32 } from "path";
12258
12334
  var STALE_AFTER_MS = 30 * 60 * 1e3;
12259
12335
  function sweepRestrictedDir(dir = getRestrictedDir()) {
12260
12336
  let entries;
@@ -12265,9 +12341,9 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
12265
12341
  }
12266
12342
  const cutoff = Date.now() - STALE_AFTER_MS;
12267
12343
  for (const entry of entries) {
12268
- const path61 = join31(dir, entry);
12344
+ const path63 = join32(dir, entry);
12269
12345
  try {
12270
- if (statSync3(path61).mtimeMs < cutoff) unlinkSync7(path61);
12346
+ if (statSync3(path63).mtimeMs < cutoff) unlinkSync7(path63);
12271
12347
  } catch {
12272
12348
  continue;
12273
12349
  }
@@ -12277,10 +12353,10 @@ function sweepRestrictedDir(dir = getRestrictedDir()) {
12277
12353
  // src/commands/codeComment/readPinState.ts
12278
12354
  import { existsSync as existsSync30, readFileSync as readFileSync26 } from "fs";
12279
12355
  function readPinState(pin) {
12280
- const path61 = getPinStatePath(pin);
12281
- if (!existsSync30(path61)) return void 0;
12356
+ const path63 = getPinStatePath(pin);
12357
+ if (!existsSync30(path63)) return void 0;
12282
12358
  try {
12283
- const state = JSON.parse(readFileSync26(path61, "utf8"));
12359
+ const state = JSON.parse(readFileSync26(path63, "utf8"));
12284
12360
  if (state.pin !== pin) return void 0;
12285
12361
  return state;
12286
12362
  } catch {
@@ -12437,13 +12513,13 @@ import chalk112 from "chalk";
12437
12513
 
12438
12514
  // src/commands/complexity/shared/index.ts
12439
12515
  import fs19 from "fs";
12440
- import path26 from "path";
12516
+ import path27 from "path";
12441
12517
  import chalk111 from "chalk";
12442
12518
  import ts5 from "typescript";
12443
12519
 
12444
12520
  // src/commands/complexity/findSourceFiles.ts
12445
12521
  import fs18 from "fs";
12446
- import path25 from "path";
12522
+ import path26 from "path";
12447
12523
  import { minimatch as minimatch5 } from "minimatch";
12448
12524
  function applyIgnoreGlobs(files, extraIgnore = []) {
12449
12525
  const { complexity } = loadConfig();
@@ -12457,7 +12533,7 @@ function walk(dir, results) {
12457
12533
  const extensions = [".ts", ".tsx"];
12458
12534
  const entries = fs18.readdirSync(dir, { withFileTypes: true });
12459
12535
  for (const entry of entries) {
12460
- const fullPath = path25.join(dir, entry.name);
12536
+ const fullPath = path26.join(dir, entry.name);
12461
12537
  if (entry.isDirectory()) {
12462
12538
  if (entry.name !== "node_modules" && entry.name !== ".git") {
12463
12539
  walk(fullPath, results);
@@ -12679,7 +12755,7 @@ function countSloc(content) {
12679
12755
  function createSourceFromFile(filePath) {
12680
12756
  const content = fs19.readFileSync(filePath, "utf8");
12681
12757
  return ts5.createSourceFile(
12682
- path26.basename(filePath),
12758
+ path27.basename(filePath),
12683
12759
  content,
12684
12760
  ts5.ScriptTarget.Latest,
12685
12761
  true,
@@ -13046,8 +13122,8 @@ function stepIntoNested(container, key, nextKey) {
13046
13122
  }
13047
13123
  return ensureObject(container, resolved);
13048
13124
  }
13049
- function setNestedValue(obj, path61, value) {
13050
- const keys = path61.split(".");
13125
+ function setNestedValue(obj, path63, value) {
13126
+ const keys = path63.split(".");
13051
13127
  const result = { ...obj };
13052
13128
  let current = result;
13053
13129
  for (let i = 0; i < keys.length - 1; i++) {
@@ -13127,9 +13203,9 @@ function isTraversable(value) {
13127
13203
  function stepInto(current, key) {
13128
13204
  return isTraversable(current) ? current[key] : void 0;
13129
13205
  }
13130
- function getNestedValue(obj, path61) {
13206
+ function getNestedValue(obj, path63) {
13131
13207
  let current = obj;
13132
- for (const key of path61.split(".")) current = stepInto(current, key);
13208
+ for (const key of path63.split(".")) current = stepInto(current, key);
13133
13209
  return current;
13134
13210
  }
13135
13211
 
@@ -13271,11 +13347,11 @@ import { execFileSync as execFileSync2 } from "child_process";
13271
13347
  import { basename as basename9 } from "path";
13272
13348
 
13273
13349
  // src/commands/devlog/loadBlogSkipDays.ts
13274
- import { homedir as homedir17 } from "os";
13275
- import { join as join32 } from "path";
13276
- var BLOG_REPO_ROOT = join32(homedir17(), "git/blog");
13350
+ import { homedir as homedir18 } from "os";
13351
+ import { join as join33 } from "path";
13352
+ var BLOG_REPO_ROOT = join33(homedir18(), "git/blog");
13277
13353
  function loadBlogSkipDays(repoName) {
13278
- const config = loadRawYaml(join32(BLOG_REPO_ROOT, "assist.yml"));
13354
+ const config = loadRawYaml(join33(BLOG_REPO_ROOT, "assist.yml"));
13279
13355
  const devlog = config.devlog;
13280
13356
  const skip2 = devlog?.skip;
13281
13357
  return new Set(skip2?.[repoName]);
@@ -13287,13 +13363,13 @@ import chalk124 from "chalk";
13287
13363
 
13288
13364
  // src/shared/getRepoName.ts
13289
13365
  import { existsSync as existsSync33, readFileSync as readFileSync29 } from "fs";
13290
- import { basename as basename8, join as join33 } from "path";
13366
+ import { basename as basename8, join as join34 } from "path";
13291
13367
  function getRepoName() {
13292
13368
  const config = loadConfig();
13293
13369
  if (config.devlog?.name) {
13294
13370
  return config.devlog.name;
13295
13371
  }
13296
- const packageJsonPath = join33(process.cwd(), "package.json");
13372
+ const packageJsonPath = join34(process.cwd(), "package.json");
13297
13373
  if (existsSync33(packageJsonPath)) {
13298
13374
  try {
13299
13375
  const content = readFileSync29(packageJsonPath, "utf8");
@@ -13309,8 +13385,8 @@ function getRepoName() {
13309
13385
 
13310
13386
  // src/commands/devlog/loadDevlogEntries.ts
13311
13387
  import { readdirSync as readdirSync4, readFileSync as readFileSync30 } from "fs";
13312
- import { join as join34 } from "path";
13313
- var DEVLOG_DIR = join34(BLOG_REPO_ROOT, "src/content/devlog");
13388
+ import { join as join35 } from "path";
13389
+ var DEVLOG_DIR = join35(BLOG_REPO_ROOT, "src/content/devlog");
13314
13390
  function extractFrontmatter(content) {
13315
13391
  const fm = content.match(/^---\n([\s\S]*?)\n---/);
13316
13392
  return fm?.[1] ?? null;
@@ -13338,7 +13414,7 @@ function readDevlogFiles(callback) {
13338
13414
  try {
13339
13415
  const files = readdirSync4(DEVLOG_DIR).filter((f) => f.endsWith(".md"));
13340
13416
  for (const file of files) {
13341
- const content = readFileSync30(join34(DEVLOG_DIR, file), "utf8");
13417
+ const content = readFileSync30(join35(DEVLOG_DIR, file), "utf8");
13342
13418
  const parsed = parseFrontmatter(content, file);
13343
13419
  if (parsed) callback(parsed);
13344
13420
  }
@@ -13726,11 +13802,11 @@ function repos(options2) {
13726
13802
 
13727
13803
  // src/commands/devlog/skip.ts
13728
13804
  import { writeFileSync as writeFileSync27 } from "fs";
13729
- import { join as join35 } from "path";
13805
+ import { join as join36 } from "path";
13730
13806
  import chalk129 from "chalk";
13731
13807
  import { stringify as stringifyYaml3 } from "yaml";
13732
13808
  function getBlogConfigPath() {
13733
- return join35(BLOG_REPO_ROOT, "assist.yml");
13809
+ return join36(BLOG_REPO_ROOT, "assist.yml");
13734
13810
  }
13735
13811
  function skip(date) {
13736
13812
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
@@ -13811,19 +13887,19 @@ function registerDevlog(program2) {
13811
13887
 
13812
13888
  // src/commands/dotnet/checkBuildLocks.ts
13813
13889
  import { closeSync as closeSync2, openSync as openSync2, readdirSync as readdirSync5 } from "fs";
13814
- import { join as join36 } from "path";
13890
+ import { join as join37 } from "path";
13815
13891
  import chalk131 from "chalk";
13816
13892
 
13817
13893
  // src/shared/findRepoRoot.ts
13818
13894
  import { existsSync as existsSync34 } from "fs";
13819
- import path27 from "path";
13895
+ import path28 from "path";
13820
13896
  function findRepoRoot(dir) {
13821
13897
  let current = dir;
13822
- while (current !== path27.dirname(current)) {
13823
- if (existsSync34(path27.join(current, ".git"))) {
13898
+ while (current !== path28.dirname(current)) {
13899
+ if (existsSync34(path28.join(current, ".git"))) {
13824
13900
  return current;
13825
13901
  }
13826
- current = path27.dirname(current);
13902
+ current = path28.dirname(current);
13827
13903
  }
13828
13904
  return null;
13829
13905
  }
@@ -13839,7 +13915,7 @@ function isLockedDll(debugDir) {
13839
13915
  }
13840
13916
  for (const file of files) {
13841
13917
  if (!file.toLowerCase().endsWith(".dll")) continue;
13842
- const dllPath = join36(debugDir, file);
13918
+ const dllPath = join37(debugDir, file);
13843
13919
  try {
13844
13920
  const fd = openSync2(dllPath, "r+");
13845
13921
  closeSync2(fd);
@@ -13857,13 +13933,13 @@ function findFirstLockedDll(dir) {
13857
13933
  return null;
13858
13934
  }
13859
13935
  if (entries.includes("bin")) {
13860
- const locked = isLockedDll(join36(dir, "bin", "Debug"));
13936
+ const locked = isLockedDll(join37(dir, "bin", "Debug"));
13861
13937
  if (locked) return locked;
13862
13938
  }
13863
13939
  for (const entry of entries) {
13864
13940
  if (SKIP_DIRS.has(entry) || entry === "bin" || entry.startsWith("."))
13865
13941
  continue;
13866
- const found = findFirstLockedDll(join36(dir, entry));
13942
+ const found = findFirstLockedDll(join37(dir, entry));
13867
13943
  if (found) return found;
13868
13944
  }
13869
13945
  return null;
@@ -13887,7 +13963,7 @@ async function checkBuildLocksCommand() {
13887
13963
 
13888
13964
  // src/commands/dotnet/buildTree.ts
13889
13965
  import { readFileSync as readFileSync31 } from "fs";
13890
- import path28 from "path";
13966
+ import path29 from "path";
13891
13967
  var PROJECT_REF_RE = /<ProjectReference\s+Include="([^"]+)"/g;
13892
13968
  function getProjectRefs(csprojPath) {
13893
13969
  const content = readFileSync31(csprojPath, "utf8");
@@ -13898,14 +13974,14 @@ function getProjectRefs(csprojPath) {
13898
13974
  return refs;
13899
13975
  }
13900
13976
  function buildTree(csprojPath, repoRoot, visited = /* @__PURE__ */ new Set()) {
13901
- const abs = path28.resolve(csprojPath);
13902
- const rel = path28.relative(repoRoot, abs);
13977
+ const abs = path29.resolve(csprojPath);
13978
+ const rel = path29.relative(repoRoot, abs);
13903
13979
  const node = { path: abs, relativePath: rel, children: [] };
13904
13980
  if (visited.has(abs)) return node;
13905
13981
  visited.add(abs);
13906
- const dir = path28.dirname(abs);
13982
+ const dir = path29.dirname(abs);
13907
13983
  for (const ref of getProjectRefs(abs)) {
13908
- const childAbs = path28.resolve(dir, ref);
13984
+ const childAbs = path29.resolve(dir, ref);
13909
13985
  try {
13910
13986
  readFileSync31(childAbs);
13911
13987
  node.children.push(buildTree(childAbs, repoRoot, visited));
@@ -13933,7 +14009,7 @@ function collectAllDeps(node) {
13933
14009
 
13934
14010
  // src/commands/dotnet/findContainingSolutions.ts
13935
14011
  import { readdirSync as readdirSync6, readFileSync as readFileSync32, statSync as statSync4 } from "fs";
13936
- import path29 from "path";
14012
+ import path30 from "path";
13937
14013
  function findSlnFiles(dir, maxDepth, depth = 0) {
13938
14014
  if (depth > maxDepth) return [];
13939
14015
  const results = [];
@@ -13946,7 +14022,7 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
13946
14022
  for (const entry of entries) {
13947
14023
  if (entry.startsWith(".") || entry === "node_modules" || entry === "packages")
13948
14024
  continue;
13949
- const full = path29.join(dir, entry);
14025
+ const full = path30.join(dir, entry);
13950
14026
  try {
13951
14027
  const stat2 = statSync4(full);
13952
14028
  if (stat2.isFile() && entry.endsWith(".sln")) {
@@ -13960,8 +14036,8 @@ function findSlnFiles(dir, maxDepth, depth = 0) {
13960
14036
  return results;
13961
14037
  }
13962
14038
  function findContainingSolutions(csprojPath, repoRoot) {
13963
- const csprojAbs = path29.resolve(csprojPath);
13964
- const csprojBasename = path29.basename(csprojAbs);
14039
+ const csprojAbs = path30.resolve(csprojPath);
14040
+ const csprojBasename = path30.basename(csprojAbs);
13965
14041
  const slnFiles = findSlnFiles(repoRoot, 3);
13966
14042
  const matches = [];
13967
14043
  const pattern2 = new RegExp(`[\\\\"/]${escapeRegex(csprojBasename)}"`);
@@ -13969,7 +14045,7 @@ function findContainingSolutions(csprojPath, repoRoot) {
13969
14045
  try {
13970
14046
  const content = readFileSync32(sln, "utf8");
13971
14047
  if (pattern2.test(content)) {
13972
- matches.push(path29.relative(repoRoot, sln));
14048
+ matches.push(path30.relative(repoRoot, sln));
13973
14049
  }
13974
14050
  } catch {
13975
14051
  }
@@ -14032,15 +14108,15 @@ function printJson(tree, totalCount, solutions) {
14032
14108
 
14033
14109
  // src/commands/dotnet/resolveCsproj.ts
14034
14110
  import { existsSync as existsSync35 } from "fs";
14035
- import path30 from "path";
14111
+ import path31 from "path";
14036
14112
  import chalk133 from "chalk";
14037
14113
  function resolveCsproj(csprojPath) {
14038
- const resolved = path30.resolve(csprojPath);
14114
+ const resolved = path31.resolve(csprojPath);
14039
14115
  if (!existsSync35(resolved)) {
14040
14116
  console.error(chalk133.red(`File not found: ${resolved}`));
14041
14117
  process.exit(1);
14042
14118
  }
14043
- const repoRoot = findRepoRoot(path30.dirname(resolved));
14119
+ const repoRoot = findRepoRoot(path31.dirname(resolved));
14044
14120
  if (!repoRoot) {
14045
14121
  console.error(chalk133.red("Could not find git repository root"));
14046
14122
  process.exit(1);
@@ -14205,16 +14281,16 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
14205
14281
 
14206
14282
  // src/commands/dotnet/resolveSolution.ts
14207
14283
  import { existsSync as existsSync36 } from "fs";
14208
- import path31 from "path";
14284
+ import path32 from "path";
14209
14285
  import chalk137 from "chalk";
14210
14286
 
14211
14287
  // src/commands/dotnet/findSolution.ts
14212
14288
  import { readdirSync as readdirSync7 } from "fs";
14213
- import { dirname as dirname22, join as join37 } from "path";
14289
+ import { dirname as dirname22, join as join38 } from "path";
14214
14290
  import chalk136 from "chalk";
14215
14291
  function findSlnInDir(dir) {
14216
14292
  try {
14217
- return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) => join37(dir, f));
14293
+ return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) => join38(dir, f));
14218
14294
  } catch {
14219
14295
  return [];
14220
14296
  }
@@ -14244,7 +14320,7 @@ function findSolution() {
14244
14320
  // src/commands/dotnet/resolveSolution.ts
14245
14321
  function resolveSolution(sln) {
14246
14322
  if (sln) {
14247
- const resolved = path31.resolve(sln);
14323
+ const resolved = path32.resolve(sln);
14248
14324
  if (!existsSync36(resolved)) {
14249
14325
  console.error(chalk137.red(`Solution file not found: ${resolved}`));
14250
14326
  process.exit(1);
@@ -14287,7 +14363,7 @@ function parseInspectReport(json) {
14287
14363
  import { execSync as execSync35 } from "child_process";
14288
14364
  import { existsSync as existsSync37, readFileSync as readFileSync33, unlinkSync as unlinkSync9 } from "fs";
14289
14365
  import { tmpdir as tmpdir3 } from "os";
14290
- import path32 from "path";
14366
+ import path33 from "path";
14291
14367
  import chalk138 from "chalk";
14292
14368
  function assertJbInstalled() {
14293
14369
  try {
@@ -14301,7 +14377,7 @@ function assertJbInstalled() {
14301
14377
  }
14302
14378
  }
14303
14379
  function runInspectCode(slnPath, include, swea) {
14304
- const reportPath = path32.join(tmpdir3(), `inspect-${Date.now()}.xml`);
14380
+ const reportPath = path33.join(tmpdir3(), `inspect-${Date.now()}.xml`);
14305
14381
  const includeFlag = include ? ` --include="${include}"` : "";
14306
14382
  const sweaFlag = swea ? " --swea" : "";
14307
14383
  try {
@@ -14668,7 +14744,7 @@ function aggregateCommitters(authorLists) {
14668
14744
  import { spawnSync as spawnSync3 } from "child_process";
14669
14745
  import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync28 } from "fs";
14670
14746
  import { tmpdir as tmpdir4 } from "os";
14671
- import { join as join38 } from "path";
14747
+ import { join as join39 } from "path";
14672
14748
  function buildArgs2(queryFile, vars) {
14673
14749
  const args = ["api", "graphql", "-F", `query=@${queryFile}`];
14674
14750
  for (const [key, value] of Object.entries(vars)) {
@@ -14693,7 +14769,7 @@ function throwOnGraphqlErrors(stdout) {
14693
14769
  throw new Error(messages || "GraphQL request returned errors");
14694
14770
  }
14695
14771
  function runGhGraphql(mutation, vars) {
14696
- const queryFile = join38(tmpdir4(), `gh-query-${Date.now()}.graphql`);
14772
+ const queryFile = join39(tmpdir4(), `gh-query-${Date.now()}.graphql`);
14697
14773
  writeFileSync28(queryFile, mutation);
14698
14774
  try {
14699
14775
  const result = spawnSync3("gh", buildArgs2(queryFile, vars), {
@@ -14886,18 +14962,18 @@ import {
14886
14962
  rmSync as rmSync3,
14887
14963
  statSync as statSync5
14888
14964
  } from "fs";
14889
- import { basename as basename10, join as join41 } from "path";
14965
+ import { basename as basename10, join as join42 } from "path";
14890
14966
 
14891
14967
  // src/commands/handover/getHandoverPath.ts
14892
- import { join as join39 } from "path";
14968
+ import { join as join40 } from "path";
14893
14969
  function getHandoverPath(cwd = process.cwd()) {
14894
- return join39(cwd, ".assist", "HANDOVER.md");
14970
+ return join40(cwd, ".assist", "HANDOVER.md");
14895
14971
  }
14896
14972
 
14897
14973
  // src/commands/handover/getHandoversDir.ts
14898
- import { join as join40 } from "path";
14974
+ import { join as join41 } from "path";
14899
14975
  function getHandoversDir(cwd = process.cwd()) {
14900
- return join40(cwd, ".assist", "handovers");
14976
+ return join41(cwd, ".assist", "handovers");
14901
14977
  }
14902
14978
 
14903
14979
  // src/commands/handover/parseArchiveTimestamp.ts
@@ -14938,7 +15014,7 @@ function collectMarkdown(dir) {
14938
15014
  if (!existsSync38(dir)) return [];
14939
15015
  const out = [];
14940
15016
  for (const entry of readdirSync8(dir, { withFileTypes: true })) {
14941
- const full = join41(dir, entry.name);
15017
+ const full = join42(dir, entry.name);
14942
15018
  if (entry.isDirectory()) out.push(...collectMarkdown(full));
14943
15019
  else if (entry.isFile() && entry.name.endsWith(".md")) out.push(full);
14944
15020
  }
@@ -15267,6 +15343,34 @@ function registerJira(program2) {
15267
15343
  ]);
15268
15344
  }
15269
15345
 
15346
+ // src/commands/backlog/registerRefineLaunch.ts
15347
+ var HARNESS_FLAG = "Coding harness to launch (claude|codex); defaults to the configured harness.engine";
15348
+ var HARNESS_CONFIG_HELP = [
15349
+ {
15350
+ key: "harness.engine",
15351
+ setter: "assist config set harness.engine <claude|codex>",
15352
+ note: "default coding harness launched by refine and other flows"
15353
+ },
15354
+ {
15355
+ key: "harness.exposeCodexActions",
15356
+ setter: "assist config set harness.exposeCodexActions <true|false>",
15357
+ note: "force the web UI 'with Codex' actions off even when codex is on PATH"
15358
+ }
15359
+ ];
15360
+ function runRefine(id, opts) {
15361
+ return refine(id, {
15362
+ once: opts.once,
15363
+ resumeSessionId: opts.resumeSession,
15364
+ harness: resolveHarness(opts.harness)
15365
+ });
15366
+ }
15367
+ function registerRefineLaunch(program2, resumeFlag) {
15368
+ const command = program2.command("refine").argument("[id]", "Backlog item ID").description(
15369
+ "Launch a coding harness in /refine mode to refine a backlog item"
15370
+ ).option("--once", "Exit when the initial task completes").option("--resume-session <id>", resumeFlag).option("--harness <kind>", HARNESS_FLAG).action(runRefine);
15371
+ configHelp(command, HARNESS_CONFIG_HELP);
15372
+ }
15373
+
15270
15374
  // src/commands/reviewComments.ts
15271
15375
  import { execFileSync as execFileSync5 } from "child_process";
15272
15376
  import { randomUUID as randomUUID3 } from "crypto";
@@ -15312,11 +15416,6 @@ function registerDescriptionLaunch(program2, name, slashCommand, description, al
15312
15416
  function registerReviewComments(program2) {
15313
15417
  program2.command("review-comments").argument("[number]", "PR number to check out first").description("Launch Claude in /review-comments mode (single session)").action((number) => reviewComments(number));
15314
15418
  }
15315
- function registerRefine(program2) {
15316
- program2.command("refine").argument("[id]", "Backlog item ID").description("Launch Claude in /refine mode to refine a backlog item").option("--once", "Exit when the initial task completes").option("--resume-session <id>", RESUME_SESSION_FLAG).action(
15317
- (id, opts) => refine(id, { once: opts.once, resumeSessionId: opts.resumeSession })
15318
- );
15319
- }
15320
15419
  function registerLaunch(program2) {
15321
15420
  registerNext(program2);
15322
15421
  registerDescriptionLaunch(
@@ -15333,7 +15432,7 @@ function registerLaunch(program2) {
15333
15432
  "Launch Claude in /bug mode, chain into next on /next signal"
15334
15433
  );
15335
15434
  registerReviewComments(program2);
15336
- registerRefine(program2);
15435
+ registerRefineLaunch(program2, RESUME_SESSION_FLAG);
15337
15436
  }
15338
15437
 
15339
15438
  // src/commands/registerList.ts
@@ -15543,15 +15642,15 @@ function createNetcapHandler(options2) {
15543
15642
  // src/commands/netcap/prepareExtensionForLoad.ts
15544
15643
  import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
15545
15644
  import { networkInterfaces } from "os";
15546
- import { join as join43 } from "path";
15645
+ import { join as join44 } from "path";
15547
15646
  import chalk149 from "chalk";
15548
15647
 
15549
15648
  // src/commands/netcap/netcapExtensionDir.ts
15550
- import { dirname as dirname23, join as join42 } from "path";
15649
+ import { dirname as dirname23, join as join43 } from "path";
15551
15650
  import { fileURLToPath as fileURLToPath6 } from "url";
15552
15651
  var moduleDir = dirname23(fileURLToPath6(import.meta.url));
15553
15652
  function netcapExtensionDir() {
15554
- return join42(moduleDir, "commands", "netcap", "netcap-extension");
15653
+ return join43(moduleDir, "commands", "netcap", "netcap-extension");
15555
15654
  }
15556
15655
 
15557
15656
  // src/commands/netcap/prepareExtensionForLoad.ts
@@ -15566,7 +15665,7 @@ function lanIPv4() {
15566
15665
  return void 0;
15567
15666
  }
15568
15667
  async function configureBackground(dir, host, port, filter) {
15569
- const file = join43(dir, "background.js");
15668
+ const file = join44(dir, "background.js");
15570
15669
  const source = await readFile2(file, "utf8");
15571
15670
  await writeFile2(
15572
15671
  file,
@@ -15606,20 +15705,20 @@ async function prepareExtensionForLoad(port, filter = "") {
15606
15705
  }
15607
15706
 
15608
15707
  // src/commands/netcap/resolveNetcapOutPath.ts
15609
- import { isAbsolute, join as join45, resolve as resolve12 } from "path";
15708
+ import { isAbsolute, join as join46, resolve as resolve12 } from "path";
15610
15709
 
15611
15710
  // src/commands/netcap/defaultCapturePath.ts
15612
- import { homedir as homedir18 } from "os";
15613
- import { join as join44 } from "path";
15711
+ import { homedir as homedir19 } from "os";
15712
+ import { join as join45 } from "path";
15614
15713
  function defaultCapturePath() {
15615
- return join44(homedir18(), ".assist", "netcap", "capture.jsonl");
15714
+ return join45(homedir19(), ".assist", "netcap", "capture.jsonl");
15616
15715
  }
15617
15716
 
15618
15717
  // src/commands/netcap/resolveNetcapOutPath.ts
15619
15718
  function resolveNetcapOutPath(out) {
15620
15719
  if (!out) return defaultCapturePath();
15621
15720
  const dir = isAbsolute(out) ? out : resolve12(process.cwd(), out);
15622
- return join45(dir, "capture.jsonl");
15721
+ return join46(dir, "capture.jsonl");
15623
15722
  }
15624
15723
 
15625
15724
  // src/commands/netcap/netcap.ts
@@ -15666,7 +15765,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
15666
15765
 
15667
15766
  // src/commands/netcap/netcapExtract.ts
15668
15767
  import { writeFileSync as writeFileSync30 } from "fs";
15669
- import { join as join46 } from "path";
15768
+ import { join as join47 } from "path";
15670
15769
  import chalk151 from "chalk";
15671
15770
 
15672
15771
  // src/commands/netcap/extractPostsFromCapture.ts
@@ -15692,9 +15791,9 @@ function parseRscRows(flight) {
15692
15791
  }
15693
15792
  function makeRscResolver(rows) {
15694
15793
  return (ref) => {
15695
- const [id, ...path61] = ref.slice(1).replace(/^[L@]/, "").split(":");
15794
+ const [id, ...path63] = ref.slice(1).replace(/^[L@]/, "").split(":");
15696
15795
  let v = rows[id];
15697
- for (const key of path61) {
15796
+ for (const key of path63) {
15698
15797
  if (v == null || typeof v !== "object") return void 0;
15699
15798
  v = v[key];
15700
15799
  }
@@ -16111,7 +16210,7 @@ function extractPostsFromCapture(captureFile) {
16111
16210
  function netcapExtract(file) {
16112
16211
  const captureFile = file ?? defaultCapturePath();
16113
16212
  const posts = extractPostsFromCapture(captureFile);
16114
- const outFile = join46(captureFile, "..", "posts.json");
16213
+ const outFile = join47(captureFile, "..", "posts.json");
16115
16214
  writeFileSync30(outFile, `${JSON.stringify(posts, null, 2)}
16116
16215
  `);
16117
16216
  console.log(
@@ -16341,15 +16440,15 @@ function postComment(vars) {
16341
16440
  const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
16342
16441
  assertThreadCreated(stdout);
16343
16442
  }
16344
- function comment2(path61, line, body, startLine) {
16443
+ function comment2(path63, line, body, startLine) {
16345
16444
  validateBody(body);
16346
16445
  validateLine(line);
16347
16446
  if (startLine !== void 0) validateLine(startLine);
16348
16447
  try {
16349
16448
  const prId = getCurrentPrNodeId();
16350
- postComment({ prId, body, path: path61, line, startLine });
16449
+ postComment({ prId, body, path: path63, line, startLine });
16351
16450
  const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
16352
- console.log(`Added review comment on ${path61}:${range}`);
16451
+ console.log(`Added review comment on ${path63}:${range}`);
16353
16452
  } catch (error) {
16354
16453
  if (isGhNotInstalled(error)) {
16355
16454
  console.error("Error: GitHub CLI (gh) is not installed.");
@@ -16547,14 +16646,14 @@ import { execSync as execSync41 } from "child_process";
16547
16646
  import { execSync as execSync40 } from "child_process";
16548
16647
  import { unlinkSync as unlinkSync12, writeFileSync as writeFileSync31 } from "fs";
16549
16648
  import { tmpdir as tmpdir5 } from "os";
16550
- import { join as join48 } from "path";
16649
+ import { join as join49 } from "path";
16551
16650
 
16552
16651
  // src/commands/prs/loadCommentsCache.ts
16553
16652
  import { existsSync as existsSync39, readFileSync as readFileSync37, unlinkSync as unlinkSync11 } from "fs";
16554
- import { join as join47 } from "path";
16653
+ import { join as join48 } from "path";
16555
16654
  import { parse as parse2 } from "yaml";
16556
16655
  function getCachePath(prNumber) {
16557
- return join47(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
16656
+ return join48(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
16558
16657
  }
16559
16658
  function loadCommentsCache(prNumber) {
16560
16659
  const cachePath = getCachePath(prNumber);
@@ -16584,7 +16683,7 @@ function replyToComment(org, repo, prNumber, commentId, message) {
16584
16683
  // src/commands/prs/resolveCommentWithReply.ts
16585
16684
  function resolveThread(threadId) {
16586
16685
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
16587
- const queryFile = join48(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
16686
+ const queryFile = join49(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
16588
16687
  writeFileSync31(queryFile, mutation);
16589
16688
  try {
16590
16689
  execSync40(
@@ -16667,17 +16766,17 @@ function fixed(commentId, sha) {
16667
16766
 
16668
16767
  // src/commands/prs/listComments/index.ts
16669
16768
  import { existsSync as existsSync40, mkdirSync as mkdirSync16, writeFileSync as writeFileSync33 } from "fs";
16670
- import { join as join50 } from "path";
16769
+ import { join as join51 } from "path";
16671
16770
  import { stringify } from "yaml";
16672
16771
 
16673
16772
  // src/commands/prs/fetchThreadIds.ts
16674
16773
  import { execSync as execSync42 } from "child_process";
16675
16774
  import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync32 } from "fs";
16676
16775
  import { tmpdir as tmpdir6 } from "os";
16677
- import { join as join49 } from "path";
16776
+ import { join as join50 } from "path";
16678
16777
  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 } } } } } } }`;
16679
16778
  function fetchThreadIds(org, repo, prNumber) {
16680
- const queryFile = join49(tmpdir6(), `gh-query-${Date.now()}.graphql`);
16779
+ const queryFile = join50(tmpdir6(), `gh-query-${Date.now()}.graphql`);
16681
16780
  writeFileSync32(queryFile, THREAD_QUERY);
16682
16781
  try {
16683
16782
  const result = execSync42(
@@ -16791,7 +16890,7 @@ function printComments2(result) {
16791
16890
 
16792
16891
  // src/commands/prs/listComments/index.ts
16793
16892
  function writeCommentsCache(prNumber, comments3) {
16794
- const assistDir = join50(process.cwd(), ".assist");
16893
+ const assistDir = join51(process.cwd(), ".assist");
16795
16894
  if (!existsSync40(assistDir)) {
16796
16895
  mkdirSync16(assistDir, { recursive: true });
16797
16896
  }
@@ -16800,7 +16899,7 @@ function writeCommentsCache(prNumber, comments3) {
16800
16899
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
16801
16900
  comments: comments3
16802
16901
  };
16803
- const cachePath = join50(assistDir, `pr-${prNumber}-comments.yaml`);
16902
+ const cachePath = join51(assistDir, `pr-${prNumber}-comments.yaml`);
16804
16903
  writeFileSync33(cachePath, stringify(cacheData));
16805
16904
  }
16806
16905
  function handleKnownErrors(error) {
@@ -16833,7 +16932,7 @@ async function listComments() {
16833
16932
  ];
16834
16933
  updateCache(prNumber, allComments);
16835
16934
  const hasLineComments = allComments.some((c) => c.type === "line");
16836
- const cachePath = hasLineComments ? join50(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
16935
+ const cachePath = hasLineComments ? join51(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
16837
16936
  return { comments: allComments, cachePath };
16838
16937
  } catch (error) {
16839
16938
  const handled = handleKnownErrors(error);
@@ -17210,8 +17309,8 @@ function registerPrs(program2) {
17210
17309
  prsCommand.command("reply <comment-id> <body>").description("Reply to a comment thread without resolving it").action((commentId, body) => {
17211
17310
  reply(Number.parseInt(commentId, 10), body);
17212
17311
  });
17213
- prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path61, line, body) => {
17214
- comment2(path61, Number.parseInt(line, 10), body);
17312
+ prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path63, line, body) => {
17313
+ comment2(path63, Number.parseInt(line, 10), body);
17215
17314
  });
17216
17315
  configHelp(prsCommand, prsConfigHelp);
17217
17316
  }
@@ -17464,10 +17563,10 @@ function resolveOpSecret(reference) {
17464
17563
  }
17465
17564
 
17466
17565
  // src/commands/ravendb/ravenFetch.ts
17467
- async function ravenFetch(connection, path61) {
17566
+ async function ravenFetch(connection, path63) {
17468
17567
  const apiKey = resolveOpSecret(connection.apiKeyRef);
17469
17568
  let accessToken = await getAccessToken(apiKey);
17470
- const url = `${connection.url}${path61}`;
17569
+ const url = `${connection.url}${path63}`;
17471
17570
  const headers = {
17472
17571
  Authorization: `Bearer ${accessToken}`,
17473
17572
  "Content-Type": "application/json"
@@ -17571,16 +17670,16 @@ import chalk166 from "chalk";
17571
17670
  // src/commands/ravendb/buildQueryPath.ts
17572
17671
  function buildQueryPath(opts) {
17573
17672
  const db = encodeURIComponent(opts.db);
17574
- let path61;
17673
+ let path63;
17575
17674
  if (opts.collection) {
17576
- path61 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
17675
+ path63 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
17577
17676
  } else {
17578
- path61 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
17677
+ path63 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
17579
17678
  }
17580
17679
  if (opts.query) {
17581
- path61 += `&query=${encodeURIComponent(opts.query)}`;
17680
+ path63 += `&query=${encodeURIComponent(opts.query)}`;
17582
17681
  }
17583
- return path61;
17682
+ return path63;
17584
17683
  }
17585
17684
 
17586
17685
  // src/commands/ravendb/fetchAllPages.ts
@@ -17589,7 +17688,7 @@ async function fetchAllPages(connection, opts) {
17589
17688
  let start3 = 0;
17590
17689
  while (true) {
17591
17690
  const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
17592
- const path61 = buildQueryPath({
17691
+ const path63 = buildQueryPath({
17593
17692
  db: connection.database,
17594
17693
  collection: opts.collection,
17595
17694
  start: start3,
@@ -17597,7 +17696,7 @@ async function fetchAllPages(connection, opts) {
17597
17696
  sort: opts.sort,
17598
17697
  query: opts.query
17599
17698
  });
17600
- const data = await ravenFetch(connection, path61);
17699
+ const data = await ravenFetch(connection, path63);
17601
17700
  const results = data.Results ?? [];
17602
17701
  const totalResults = data.TotalResults ?? 0;
17603
17702
  if (results.length === 0) break;
@@ -17655,7 +17754,7 @@ function registerRavendb(program2) {
17655
17754
 
17656
17755
  // src/commands/refactor/check/index.ts
17657
17756
  import { spawn as spawn5 } from "child_process";
17658
- import * as path33 from "path";
17757
+ import * as path34 from "path";
17659
17758
 
17660
17759
  // src/commands/refactor/logViolations.ts
17661
17760
  import chalk168 from "chalk";
@@ -17832,7 +17931,7 @@ ${failed2.length} verify script(s) failed:`);
17832
17931
  async function runVerifyQuietly() {
17833
17932
  const result = findPackageJsonWithVerifyScripts(process.cwd());
17834
17933
  if (!result) return true;
17835
- const packageDir = path33.dirname(result.packageJsonPath);
17934
+ const packageDir = path34.dirname(result.packageJsonPath);
17836
17935
  const results = await Promise.all(
17837
17936
  result.verifyScripts.map((script) => runScript(script, packageDir))
17838
17937
  );
@@ -17858,7 +17957,7 @@ async function check(pattern2, options2) {
17858
17957
  }
17859
17958
 
17860
17959
  // src/commands/refactor/extract/index.ts
17861
- import path40 from "path";
17960
+ import path41 from "path";
17862
17961
  import chalk171 from "chalk";
17863
17962
 
17864
17963
  // src/commands/refactor/extract/applyExtraction.ts
@@ -18335,9 +18434,9 @@ function buildDestinationContent(functionTexts, imports, sourceRelativePath, sou
18335
18434
  }
18336
18435
 
18337
18436
  // src/commands/refactor/extract/getRelativeImportPath.ts
18338
- import path34 from "path";
18437
+ import path35 from "path";
18339
18438
  function getRelativeImportPath(from, to) {
18340
- let rel = path34.relative(path34.dirname(from), to).replace(/\.tsx?$/, "").replace(/\\/g, "/");
18439
+ let rel = path35.relative(path35.dirname(from), to).replace(/\.tsx?$/, "").replace(/\\/g, "/");
18341
18440
  if (!rel.startsWith(".")) rel = `./${rel}`;
18342
18441
  return rel;
18343
18442
  }
@@ -18361,9 +18460,9 @@ function findImporters(functionName, sourceFile, destPath, project) {
18361
18460
  }
18362
18461
 
18363
18462
  // src/commands/refactor/extract/resolveBarrel.ts
18364
- import path35 from "path";
18463
+ import path36 from "path";
18365
18464
  function resolveBarrel(functionName, sourcePath, destPath, project) {
18366
- const indexPath = path35.join(path35.dirname(destPath), "index.ts");
18465
+ const indexPath = path36.join(path36.dirname(destPath), "index.ts");
18367
18466
  const barrel = project.getSourceFile(indexPath);
18368
18467
  if (!barrel) return { barrel: void 0, barrelRelPath: "" };
18369
18468
  const sourceRelFromBarrel = getRelativeImportPath(indexPath, sourcePath);
@@ -18381,15 +18480,15 @@ function resolveBarrel(functionName, sourcePath, destPath, project) {
18381
18480
  }
18382
18481
 
18383
18482
  // src/commands/refactor/extract/rewriteImportPaths.ts
18384
- import path36 from "path";
18483
+ import path37 from "path";
18385
18484
  function rewriteImportPaths(imports, sourcePath, destPath) {
18386
- const sourceDir = path36.dirname(sourcePath);
18387
- const destDir = path36.dirname(destPath);
18485
+ const sourceDir = path37.dirname(sourcePath);
18486
+ const destDir = path37.dirname(destPath);
18388
18487
  return imports.map((imp) => {
18389
18488
  if (!imp.moduleSpecifier.startsWith(".")) return imp;
18390
- const absolute = path36.resolve(sourceDir, imp.moduleSpecifier);
18391
- let rel = path36.relative(destDir, absolute).replace(/\\/g, "/");
18392
- if (rel === "") rel = `../${path36.basename(absolute)}`;
18489
+ const absolute = path37.resolve(sourceDir, imp.moduleSpecifier);
18490
+ let rel = path37.relative(destDir, absolute).replace(/\\/g, "/");
18491
+ if (rel === "") rel = `../${path37.basename(absolute)}`;
18393
18492
  else if (!rel.startsWith(".")) rel = `./${rel}`;
18394
18493
  return { ...imp, moduleSpecifier: rel };
18395
18494
  });
@@ -18457,7 +18556,7 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
18457
18556
  }
18458
18557
 
18459
18558
  // src/commands/refactor/extract/displayPlan.ts
18460
- import path37 from "path";
18559
+ import path38 from "path";
18461
18560
  import chalk169 from "chalk";
18462
18561
  function section2(title) {
18463
18562
  return `
@@ -18467,7 +18566,7 @@ function displayImporters(plan2, cwd) {
18467
18566
  if (plan2.importersToUpdate.length === 0) return;
18468
18567
  console.log(section2("Update importers:"));
18469
18568
  for (const imp of plan2.importersToUpdate) {
18470
- const rel = path37.relative(cwd, imp.file.getFilePath());
18569
+ const rel = path38.relative(cwd, imp.file.getFilePath());
18471
18570
  console.log(` ${chalk169.dim(rel)}: \u2192 import from "${imp.relPath}"`);
18472
18571
  }
18473
18572
  }
@@ -18507,16 +18606,16 @@ function displayPlan(functionName, relDest, plan2, cwd) {
18507
18606
  }
18508
18607
 
18509
18608
  // src/commands/refactor/extract/loadProjectFile.ts
18510
- import path39 from "path";
18609
+ import path40 from "path";
18511
18610
  import chalk170 from "chalk";
18512
18611
  import { Project as Project4 } from "ts-morph";
18513
18612
 
18514
18613
  // src/commands/refactor/extract/findTsConfig.ts
18515
18614
  import fs25 from "fs";
18516
- import path38 from "path";
18615
+ import path39 from "path";
18517
18616
  import { Project as Project3 } from "ts-morph";
18518
18617
  function findTsConfig(sourcePath) {
18519
- const rootConfig = path38.resolve("tsconfig.json");
18618
+ const rootConfig = path39.resolve("tsconfig.json");
18520
18619
  if (!fs25.existsSync(rootConfig)) return rootConfig;
18521
18620
  const tried = /* @__PURE__ */ new Set();
18522
18621
  const candidates = [rootConfig, ...readReferences(rootConfig)];
@@ -18525,7 +18624,7 @@ function findTsConfig(sourcePath) {
18525
18624
  tried.add(candidate);
18526
18625
  if (projectIncludes(candidate, sourcePath)) return candidate;
18527
18626
  }
18528
- const siblings = fs25.readdirSync(path38.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path38.resolve(path38.dirname(rootConfig), f));
18627
+ const siblings = fs25.readdirSync(path39.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path39.resolve(path39.dirname(rootConfig), f));
18529
18628
  for (const sibling of siblings) {
18530
18629
  if (tried.has(sibling)) continue;
18531
18630
  tried.add(sibling);
@@ -18544,10 +18643,10 @@ function readReferences(configPath) {
18544
18643
  return [];
18545
18644
  }
18546
18645
  if (!parsed.references?.length) return [];
18547
- const cwd = path38.dirname(configPath);
18646
+ const cwd = path39.dirname(configPath);
18548
18647
  return parsed.references.map((ref) => {
18549
- const refPath = path38.resolve(cwd, ref.path);
18550
- return fs25.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path38.join(refPath, "tsconfig.json") : refPath;
18648
+ const refPath = path39.resolve(cwd, ref.path);
18649
+ return fs25.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path39.join(refPath, "tsconfig.json") : refPath;
18551
18650
  }).filter((p) => fs25.existsSync(p));
18552
18651
  }
18553
18652
  function projectIncludes(configPath, sourcePath) {
@@ -18561,7 +18660,7 @@ function projectIncludes(configPath, sourcePath) {
18561
18660
 
18562
18661
  // src/commands/refactor/extract/loadProjectFile.ts
18563
18662
  function loadProjectFile(file) {
18564
- const sourcePath = path39.resolve(file);
18663
+ const sourcePath = path40.resolve(file);
18565
18664
  const tsConfigPath = findTsConfig(sourcePath);
18566
18665
  const project = new Project4({
18567
18666
  tsConfigFilePath: tsConfigPath
@@ -18576,10 +18675,10 @@ function loadProjectFile(file) {
18576
18675
 
18577
18676
  // src/commands/refactor/extract/index.ts
18578
18677
  async function extract(file, functionName, destination, options2 = {}) {
18579
- const sourcePath = path40.resolve(file);
18580
- const destPath = path40.resolve(destination);
18678
+ const sourcePath = path41.resolve(file);
18679
+ const destPath = path41.resolve(destination);
18581
18680
  const cwd = process.cwd();
18582
- const relDest = path40.relative(cwd, destPath);
18681
+ const relDest = path41.relative(cwd, destPath);
18583
18682
  const { project, sourceFile } = loadProjectFile(file);
18584
18683
  const plan2 = buildPlan2(
18585
18684
  functionName,
@@ -18627,16 +18726,16 @@ function ignore2(file) {
18627
18726
 
18628
18727
  // src/commands/refactor/rename/index.ts
18629
18728
  import fs29 from "fs";
18630
- import path45 from "path";
18729
+ import path46 from "path";
18631
18730
  import chalk175 from "chalk";
18632
18731
 
18633
18732
  // src/commands/refactor/rename/applyRename.ts
18634
18733
  import fs28 from "fs";
18635
- import path42 from "path";
18734
+ import path43 from "path";
18636
18735
  import chalk173 from "chalk";
18637
18736
 
18638
18737
  // src/commands/refactor/restructure/computeRewrites/index.ts
18639
- import path41 from "path";
18738
+ import path42 from "path";
18640
18739
 
18641
18740
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
18642
18741
  import fs27 from "fs";
@@ -18690,7 +18789,7 @@ function normalizeSpecifier(rel) {
18690
18789
  );
18691
18790
  }
18692
18791
  function computeSpecifier(fromFile, toFile) {
18693
- return normalizeSpecifier(path41.relative(path41.dirname(fromFile), toFile));
18792
+ return normalizeSpecifier(path42.relative(path42.dirname(fromFile), toFile));
18694
18793
  }
18695
18794
  function isAffected(edge, moveMap) {
18696
18795
  return moveMap.has(edge.target) || moveMap.has(edge.source);
@@ -18738,20 +18837,20 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
18738
18837
  const updatedContents = applyRewrites(rewrites);
18739
18838
  for (const [file, content] of updatedContents) {
18740
18839
  fs28.writeFileSync(file, content, "utf8");
18741
- console.log(chalk173.cyan(` Updated imports in ${path42.relative(cwd, file)}`));
18840
+ console.log(chalk173.cyan(` Updated imports in ${path43.relative(cwd, file)}`));
18742
18841
  }
18743
- const destDir = path42.dirname(destPath);
18842
+ const destDir = path43.dirname(destPath);
18744
18843
  if (!fs28.existsSync(destDir)) fs28.mkdirSync(destDir, { recursive: true });
18745
18844
  fs28.renameSync(sourcePath, destPath);
18746
18845
  console.log(
18747
18846
  chalk173.white(
18748
- ` Moved ${path42.relative(cwd, sourcePath)} \u2192 ${path42.relative(cwd, destPath)}`
18847
+ ` Moved ${path43.relative(cwd, sourcePath)} \u2192 ${path43.relative(cwd, destPath)}`
18749
18848
  )
18750
18849
  );
18751
18850
  }
18752
18851
 
18753
18852
  // src/commands/refactor/restructure/buildImportGraph/index.ts
18754
- import path43 from "path";
18853
+ import path44 from "path";
18755
18854
  import ts7 from "typescript";
18756
18855
 
18757
18856
  // src/commands/refactor/restructure/buildImportGraph/getImportSpecifiers.ts
@@ -18778,7 +18877,7 @@ function loadParsedConfig(tsConfigPath) {
18778
18877
  return ts7.parseJsonConfigFileContent(
18779
18878
  configFile.config,
18780
18879
  ts7.sys,
18781
- path43.dirname(tsConfigPath)
18880
+ path44.dirname(tsConfigPath)
18782
18881
  );
18783
18882
  }
18784
18883
  function addToSetMap(map, key, value) {
@@ -18794,7 +18893,7 @@ function resolveImport(specifier, filePath, options2) {
18794
18893
  const resolved = ts7.resolveModuleName(specifier, filePath, options2, ts7.sys);
18795
18894
  const resolvedPath = resolved.resolvedModule?.resolvedFileName;
18796
18895
  if (!resolvedPath || resolvedPath.includes("node_modules")) return null;
18797
- return path43.resolve(resolvedPath);
18896
+ return path44.resolve(resolvedPath);
18798
18897
  }
18799
18898
  function buildImportGraph(candidateFiles, tsConfigPath) {
18800
18899
  const parsed = loadParsedConfig(tsConfigPath);
@@ -18803,7 +18902,7 @@ function buildImportGraph(candidateFiles, tsConfigPath) {
18803
18902
  const importedBy = /* @__PURE__ */ new Map();
18804
18903
  const imports = /* @__PURE__ */ new Map();
18805
18904
  for (const sourceFile of program2.getSourceFiles()) {
18806
- const filePath = path43.resolve(sourceFile.fileName);
18905
+ const filePath = path44.resolve(sourceFile.fileName);
18807
18906
  if (filePath.includes("node_modules")) continue;
18808
18907
  for (const specifier of getImportSpecifiers(sourceFile)) {
18809
18908
  const absTarget = resolveImport(specifier, filePath, parsed.options);
@@ -18830,13 +18929,13 @@ function computeRenameRewrites(sourcePath, destPath) {
18830
18929
  }
18831
18930
 
18832
18931
  // src/commands/refactor/rename/printRenamePreview.ts
18833
- import path44 from "path";
18932
+ import path45 from "path";
18834
18933
  import chalk174 from "chalk";
18835
18934
  function printRenamePreview(rewrites, cwd) {
18836
18935
  for (const rewrite of rewrites) {
18837
18936
  console.log(
18838
18937
  chalk174.dim(
18839
- ` ${path44.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
18938
+ ` ${path45.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
18840
18939
  )
18841
18940
  );
18842
18941
  }
@@ -18845,11 +18944,11 @@ function printRenamePreview(rewrites, cwd) {
18845
18944
 
18846
18945
  // src/commands/refactor/rename/index.ts
18847
18946
  async function rename(source, destination, options2 = {}) {
18848
- const sourcePath = path45.resolve(source);
18849
- const destPath = path45.resolve(destination);
18947
+ const sourcePath = path46.resolve(source);
18948
+ const destPath = path46.resolve(destination);
18850
18949
  const cwd = process.cwd();
18851
- const relSource = path45.relative(cwd, sourcePath);
18852
- const relDest = path45.relative(cwd, destPath);
18950
+ const relSource = path46.relative(cwd, sourcePath);
18951
+ const relDest = path46.relative(cwd, destPath);
18853
18952
  if (!fs29.existsSync(sourcePath)) {
18854
18953
  console.log(chalk175.red(`File not found: ${source}`));
18855
18954
  process.exit(1);
@@ -18904,12 +19003,12 @@ function findSymbol(sourceFile, symbolName) {
18904
19003
  }
18905
19004
 
18906
19005
  // src/commands/refactor/renameSymbol/groupReferences.ts
18907
- import path46 from "path";
19006
+ import path47 from "path";
18908
19007
  function groupReferences(symbol, cwd) {
18909
19008
  const refs = symbol.findReferencesAsNodes();
18910
19009
  const grouped = /* @__PURE__ */ new Map();
18911
19010
  for (const ref of refs) {
18912
- const refFile = path46.relative(cwd, ref.getSourceFile().getFilePath());
19011
+ const refFile = path47.relative(cwd, ref.getSourceFile().getFilePath());
18913
19012
  const lines = grouped.get(refFile) ?? [];
18914
19013
  if (!grouped.has(refFile)) grouped.set(refFile, lines);
18915
19014
  lines.push(ref.getStartLineNumber());
@@ -18948,16 +19047,16 @@ Renamed ${oldName} \u2192 ${newName}`));
18948
19047
  }
18949
19048
 
18950
19049
  // src/commands/refactor/restructure/index.ts
18951
- import path53 from "path";
19050
+ import path54 from "path";
18952
19051
  import chalk179 from "chalk";
18953
19052
 
18954
19053
  // src/commands/refactor/restructure/clusterDirectories.ts
18955
- import path47 from "path";
19054
+ import path48 from "path";
18956
19055
  function clusterDirectories(graph) {
18957
19056
  const dirImportedBy = /* @__PURE__ */ new Map();
18958
19057
  for (const edge of graph.edges) {
18959
- const sourceDir = path47.dirname(edge.source);
18960
- const targetDir = path47.dirname(edge.target);
19058
+ const sourceDir = path48.dirname(edge.source);
19059
+ const targetDir = path48.dirname(edge.target);
18961
19060
  if (sourceDir === targetDir) continue;
18962
19061
  if (!graph.files.has(edge.target)) continue;
18963
19062
  const existing = dirImportedBy.get(targetDir) ?? /* @__PURE__ */ new Set();
@@ -18985,20 +19084,20 @@ function clusterDirectories(graph) {
18985
19084
  return clusters;
18986
19085
  }
18987
19086
  function isAncestor(ancestor, descendant) {
18988
- const rel = path47.relative(ancestor, descendant);
19087
+ const rel = path48.relative(ancestor, descendant);
18989
19088
  return !rel.startsWith("..") && rel !== "";
18990
19089
  }
18991
19090
 
18992
19091
  // src/commands/refactor/restructure/clusterFiles.ts
18993
- import path48 from "path";
19092
+ import path49 from "path";
18994
19093
  function findRootParent(file, importedBy, visited) {
18995
19094
  const importers = importedBy.get(file);
18996
19095
  if (!importers || importers.size !== 1) return file;
18997
19096
  const parent = [...importers][0];
18998
- const parentDir = path48.dirname(parent);
18999
- const fileDir = path48.dirname(file);
19097
+ const parentDir = path49.dirname(parent);
19098
+ const fileDir = path49.dirname(file);
19000
19099
  if (parentDir !== fileDir) return file;
19001
- if (path48.basename(parent, path48.extname(parent)) === "index") return file;
19100
+ if (path49.basename(parent, path49.extname(parent)) === "index") return file;
19002
19101
  if (visited.has(parent)) return file;
19003
19102
  visited.add(parent);
19004
19103
  return findRootParent(parent, importedBy, visited);
@@ -19006,16 +19105,16 @@ function findRootParent(file, importedBy, visited) {
19006
19105
  function clusterFiles(graph) {
19007
19106
  const clusters = /* @__PURE__ */ new Map();
19008
19107
  for (const file of graph.files) {
19009
- const basename14 = path48.basename(file, path48.extname(file));
19108
+ const basename14 = path49.basename(file, path49.extname(file));
19010
19109
  if (basename14 === "index") continue;
19011
19110
  const importers = graph.importedBy.get(file);
19012
19111
  if (!importers || importers.size !== 1) continue;
19013
19112
  const parent = [...importers][0];
19014
19113
  if (!graph.files.has(parent)) continue;
19015
- const parentDir = path48.dirname(parent);
19016
- const fileDir = path48.dirname(file);
19114
+ const parentDir = path49.dirname(parent);
19115
+ const fileDir = path49.dirname(file);
19017
19116
  if (parentDir !== fileDir) continue;
19018
- const parentBasename = path48.basename(parent, path48.extname(parent));
19117
+ const parentBasename = path49.basename(parent, path49.extname(parent));
19019
19118
  if (parentBasename === "index") continue;
19020
19119
  const root = findRootParent(parent, graph.importedBy, /* @__PURE__ */ new Set([file]));
19021
19120
  if (!root || root === file) continue;
@@ -19027,10 +19126,10 @@ function clusterFiles(graph) {
19027
19126
  }
19028
19127
 
19029
19128
  // src/commands/refactor/restructure/displayPlan.ts
19030
- import path49 from "path";
19129
+ import path50 from "path";
19031
19130
  import chalk177 from "chalk";
19032
19131
  function relPath(filePath) {
19033
- return path49.relative(process.cwd(), filePath);
19132
+ return path50.relative(process.cwd(), filePath);
19034
19133
  }
19035
19134
  function displayMoves(plan2) {
19036
19135
  if (plan2.moves.length === 0) return;
@@ -19080,33 +19179,33 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
19080
19179
 
19081
19180
  // src/commands/refactor/restructure/executePlan.ts
19082
19181
  import fs30 from "fs";
19083
- import path50 from "path";
19182
+ import path51 from "path";
19084
19183
  import chalk178 from "chalk";
19085
19184
  function executePlan(plan2) {
19086
19185
  const updatedContents = applyRewrites(plan2.rewrites);
19087
19186
  for (const [file, content] of updatedContents) {
19088
19187
  fs30.writeFileSync(file, content, "utf8");
19089
19188
  console.log(
19090
- chalk178.cyan(` Rewrote imports in ${path50.relative(process.cwd(), file)}`)
19189
+ chalk178.cyan(` Rewrote imports in ${path51.relative(process.cwd(), file)}`)
19091
19190
  );
19092
19191
  }
19093
19192
  for (const dir of plan2.newDirectories) {
19094
19193
  fs30.mkdirSync(dir, { recursive: true });
19095
- console.log(chalk178.green(` Created ${path50.relative(process.cwd(), dir)}/`));
19194
+ console.log(chalk178.green(` Created ${path51.relative(process.cwd(), dir)}/`));
19096
19195
  }
19097
19196
  for (const move2 of plan2.moves) {
19098
- const targetDir = path50.dirname(move2.to);
19197
+ const targetDir = path51.dirname(move2.to);
19099
19198
  if (!fs30.existsSync(targetDir)) {
19100
19199
  fs30.mkdirSync(targetDir, { recursive: true });
19101
19200
  }
19102
19201
  fs30.renameSync(move2.from, move2.to);
19103
19202
  console.log(
19104
19203
  chalk178.white(
19105
- ` Moved ${path50.relative(process.cwd(), move2.from)} \u2192 ${path50.relative(process.cwd(), move2.to)}`
19204
+ ` Moved ${path51.relative(process.cwd(), move2.from)} \u2192 ${path51.relative(process.cwd(), move2.to)}`
19106
19205
  )
19107
19206
  );
19108
19207
  }
19109
- removeEmptyDirectories(plan2.moves.map((m) => path50.dirname(m.from)));
19208
+ removeEmptyDirectories(plan2.moves.map((m) => path51.dirname(m.from)));
19110
19209
  }
19111
19210
  function removeEmptyDirectories(dirs) {
19112
19211
  const unique = [...new Set(dirs)];
@@ -19117,7 +19216,7 @@ function removeEmptyDirectories(dirs) {
19117
19216
  fs30.rmdirSync(dir);
19118
19217
  console.log(
19119
19218
  chalk178.dim(
19120
- ` Removed empty directory ${path50.relative(process.cwd(), dir)}`
19219
+ ` Removed empty directory ${path51.relative(process.cwd(), dir)}`
19121
19220
  )
19122
19221
  );
19123
19222
  }
@@ -19125,7 +19224,7 @@ function removeEmptyDirectories(dirs) {
19125
19224
  }
19126
19225
 
19127
19226
  // src/commands/refactor/restructure/planFileMoves/index.ts
19128
- import path52 from "path";
19227
+ import path53 from "path";
19129
19228
 
19130
19229
  // src/commands/refactor/restructure/planFileMoves/shared.ts
19131
19230
  import fs31 from "fs";
@@ -19140,9 +19239,9 @@ function checkDirConflict(result, label2, dir) {
19140
19239
 
19141
19240
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
19142
19241
  import fs32 from "fs";
19143
- import path51 from "path";
19242
+ import path52 from "path";
19144
19243
  function collectEntry(results, dir, entry) {
19145
- const full = path51.join(dir, entry.name);
19244
+ const full = path52.join(dir, entry.name);
19146
19245
  const items2 = entry.isDirectory() ? listFilesRecursive(full) : [full];
19147
19246
  results.push(...items2);
19148
19247
  }
@@ -19156,15 +19255,15 @@ function listFilesRecursive(dir) {
19156
19255
  }
19157
19256
  function addDirectoryFileMoves(moves, childDir, newLocation, reason) {
19158
19257
  for (const file of listFilesRecursive(childDir)) {
19159
- const rel = path51.relative(childDir, file);
19160
- moves.push({ from: file, to: path51.join(newLocation, rel), reason });
19258
+ const rel = path52.relative(childDir, file);
19259
+ moves.push({ from: file, to: path52.join(newLocation, rel), reason });
19161
19260
  }
19162
19261
  }
19163
19262
  function resolveChildDest(parentDir, childDir) {
19164
- return path51.join(parentDir, path51.basename(childDir));
19263
+ return path52.join(parentDir, path52.basename(childDir));
19165
19264
  }
19166
19265
  function childMoveReason(parentDir) {
19167
- return `Directory only imported from ${path51.basename(parentDir)}/`;
19266
+ return `Directory only imported from ${path52.basename(parentDir)}/`;
19168
19267
  }
19169
19268
  function registerDirectoryMove(result, childDir, dest, parentDir) {
19170
19269
  result.directories.push(dest);
@@ -19189,7 +19288,7 @@ function planDirectoryMoves(clusters) {
19189
19288
 
19190
19289
  // src/commands/refactor/restructure/planFileMoves/index.ts
19191
19290
  function childMoveData(child, newDir, parentBase) {
19192
- const to = path52.join(newDir, path52.basename(child));
19291
+ const to = path53.join(newDir, path53.basename(child));
19193
19292
  return { from: child, to, reason: `Only imported by ${parentBase}` };
19194
19293
  }
19195
19294
  function addChildMoves(moves, children, newDir, parentBase) {
@@ -19197,15 +19296,15 @@ function addChildMoves(moves, children, newDir, parentBase) {
19197
19296
  moves.push(childMoveData(child, newDir, parentBase));
19198
19297
  }
19199
19298
  function getBaseName(filePath) {
19200
- return path52.basename(filePath, path52.extname(filePath));
19299
+ return path53.basename(filePath, path53.extname(filePath));
19201
19300
  }
19202
19301
  function resolveClusterDir(parent) {
19203
- return path52.join(path52.dirname(parent), getBaseName(parent));
19302
+ return path53.join(path53.dirname(parent), getBaseName(parent));
19204
19303
  }
19205
19304
  function createParentMove(parent, newDir) {
19206
19305
  return {
19207
19306
  from: parent,
19208
- to: path52.join(newDir, `index${path52.extname(parent)}`),
19307
+ to: path53.join(newDir, `index${path53.extname(parent)}`),
19209
19308
  reason: `Main module of new ${getBaseName(parent)}/ directory`
19210
19309
  };
19211
19310
  }
@@ -19229,7 +19328,7 @@ function planFileMoves(clusters) {
19229
19328
 
19230
19329
  // src/commands/refactor/restructure/index.ts
19231
19330
  function buildPlan3(candidateFiles, tsConfigPath) {
19232
- const candidates = new Set(candidateFiles.map((f) => path53.resolve(f)));
19331
+ const candidates = new Set(candidateFiles.map((f) => path54.resolve(f)));
19233
19332
  const graph = buildImportGraph(candidates, tsConfigPath);
19234
19333
  const allProjectFiles = /* @__PURE__ */ new Set([
19235
19334
  ...graph.importedBy.keys(),
@@ -19252,7 +19351,7 @@ async function restructure(pattern2, options2 = {}) {
19252
19351
  console.log(chalk179.yellow("No files found matching pattern"));
19253
19352
  return;
19254
19353
  }
19255
- const tsConfigPath = path53.resolve("tsconfig.json");
19354
+ const tsConfigPath = path54.resolve("tsconfig.json");
19256
19355
  const plan2 = buildPlan3(files, tsConfigPath);
19257
19356
  if (plan2.moves.length === 0) {
19258
19357
  console.log(chalk179.green("No restructuring needed"));
@@ -19429,11 +19528,11 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
19429
19528
  }
19430
19529
 
19431
19530
  // src/commands/review/buildReviewPaths.ts
19432
- import { homedir as homedir19 } from "os";
19433
- import { basename as basename12, join as join51 } from "path";
19531
+ import { homedir as homedir20 } from "os";
19532
+ import { basename as basename12, join as join52 } from "path";
19434
19533
  function buildReviewPaths(repoRoot, key) {
19435
- const reviewDir = join51(
19436
- homedir19(),
19534
+ const reviewDir = join52(
19535
+ homedir20(),
19437
19536
  ".assist",
19438
19537
  "reviews",
19439
19538
  basename12(repoRoot),
@@ -19441,10 +19540,10 @@ function buildReviewPaths(repoRoot, key) {
19441
19540
  );
19442
19541
  return {
19443
19542
  reviewDir,
19444
- requestPath: join51(reviewDir, "request.md"),
19445
- claudePath: join51(reviewDir, "claude.md"),
19446
- codexPath: join51(reviewDir, "codex.md"),
19447
- synthesisPath: join51(reviewDir, "synthesis.md")
19543
+ requestPath: join52(reviewDir, "request.md"),
19544
+ claudePath: join52(reviewDir, "claude.md"),
19545
+ codexPath: join52(reviewDir, "codex.md"),
19546
+ synthesisPath: join52(reviewDir, "synthesis.md")
19448
19547
  };
19449
19548
  }
19450
19549
 
@@ -19985,8 +20084,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
19985
20084
  // src/commands/review/prepareReviewDir.ts
19986
20085
  import { existsSync as existsSync41, mkdirSync as mkdirSync17, unlinkSync as unlinkSync14, writeFileSync as writeFileSync34 } from "fs";
19987
20086
  function clearReviewFiles(paths) {
19988
- for (const path61 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
19989
- if (existsSync41(path61)) unlinkSync14(path61);
20087
+ for (const path63 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
20088
+ if (existsSync41(path63)) unlinkSync14(path63);
19990
20089
  }
19991
20090
  }
19992
20091
  function prepareReviewDir(paths, requestBody, force) {
@@ -21134,8 +21233,8 @@ import chalk187 from "chalk";
21134
21233
 
21135
21234
  // src/commands/seq/fetchSeq.ts
21136
21235
  import chalk184 from "chalk";
21137
- async function fetchSeq(conn, path61, params) {
21138
- const url = `${conn.url}${path61}?${params}`;
21236
+ async function fetchSeq(conn, path63, params) {
21237
+ const url = `${conn.url}${path63}?${params}`;
21139
21238
  const response = await fetch(url, {
21140
21239
  headers: {
21141
21240
  Accept: "application/json",
@@ -21770,13 +21869,13 @@ async function configure() {
21770
21869
 
21771
21870
  // src/commands/transcript/list.ts
21772
21871
  import { existsSync as existsSync44, readdirSync as readdirSync10, statSync as statSync7 } from "fs";
21773
- import { join as join52 } from "path";
21872
+ import { join as join53 } from "path";
21774
21873
  function list4() {
21775
21874
  const { vttDir } = getTranscriptConfig();
21776
21875
  if (!existsSync44(vttDir)) return;
21777
21876
  for (const entry of readdirSync10(vttDir)) {
21778
21877
  if (!entry.endsWith(".vtt")) continue;
21779
- if (statSync7(join52(vttDir, entry)).isDirectory()) continue;
21878
+ if (statSync7(join53(vttDir, entry)).isDirectory()) continue;
21780
21879
  console.log(entry);
21781
21880
  }
21782
21881
  }
@@ -21789,7 +21888,7 @@ import {
21789
21888
  renameSync as renameSync2,
21790
21889
  writeFileSync as writeFileSync36
21791
21890
  } from "fs";
21792
- import { basename as basename13, join as join53 } from "path";
21891
+ import { basename as basename13, join as join54 } from "path";
21793
21892
 
21794
21893
  // src/commands/transcript/cleanText.ts
21795
21894
  function cleanText(text16) {
@@ -22002,9 +22101,9 @@ function convertVttToMarkdown(inputPath) {
22002
22101
  return formatChatLog(messages);
22003
22102
  }
22004
22103
  function archiveRawVtt(vttDir, sourcePath, filename) {
22005
- const processedDir = join53(vttDir, "processed");
22104
+ const processedDir = join54(vttDir, "processed");
22006
22105
  mkdirSync18(processedDir, { recursive: true });
22007
- renameSync2(sourcePath, join53(processedDir, filename));
22106
+ renameSync2(sourcePath, join54(processedDir, filename));
22008
22107
  }
22009
22108
  function move(file, options2) {
22010
22109
  const { date, client } = options2;
@@ -22014,19 +22113,19 @@ function move(file, options2) {
22014
22113
  }
22015
22114
  const { vttDir, transcriptsDir, summaryDir } = getTranscriptConfig();
22016
22115
  const filename = basename13(file);
22017
- const sourcePath = join53(vttDir, filename);
22116
+ const sourcePath = join54(vttDir, filename);
22018
22117
  if (!existsSync45(sourcePath)) {
22019
22118
  console.error(`Error: VTT file not found: ${sourcePath}`);
22020
22119
  process.exit(1);
22021
22120
  }
22022
22121
  const base = basename13(filename, ".vtt").replace(/ Transcription$/, "");
22023
22122
  const outputName = `${date} ${base}.md`;
22024
- const formattedDir = join53(transcriptsDir, client);
22123
+ const formattedDir = join54(transcriptsDir, client);
22025
22124
  mkdirSync18(formattedDir, { recursive: true });
22026
- const formattedPath = join53(formattedDir, outputName);
22125
+ const formattedPath = join54(formattedDir, outputName);
22027
22126
  writeFileSync36(formattedPath, convertVttToMarkdown(sourcePath), "utf8");
22028
22127
  archiveRawVtt(vttDir, sourcePath, filename);
22029
- const summaryPath = join53(summaryDir, client, outputName);
22128
+ const summaryPath = join54(summaryDir, client, outputName);
22030
22129
  console.log(`Formatted transcript: ${formattedPath}`);
22031
22130
  console.log(`Summary target: ${summaryPath}`);
22032
22131
  }
@@ -22146,38 +22245,38 @@ function registerVerify(program2) {
22146
22245
 
22147
22246
  // src/commands/voice/devices.ts
22148
22247
  import { spawnSync as spawnSync5 } from "child_process";
22149
- import { join as join55 } from "path";
22248
+ import { join as join56 } from "path";
22150
22249
 
22151
22250
  // src/commands/voice/shared.ts
22152
- import { homedir as homedir20 } from "os";
22153
- import { dirname as dirname26, join as join54 } from "path";
22251
+ import { homedir as homedir21 } from "os";
22252
+ import { dirname as dirname26, join as join55 } from "path";
22154
22253
  import { fileURLToPath as fileURLToPath7 } from "url";
22155
22254
  var __dirname5 = dirname26(fileURLToPath7(import.meta.url));
22156
- var VOICE_DIR = join54(homedir20(), ".assist", "voice");
22255
+ var VOICE_DIR = join55(homedir21(), ".assist", "voice");
22157
22256
  var voicePaths = {
22158
22257
  dir: VOICE_DIR,
22159
- pid: join54(VOICE_DIR, "voice.pid"),
22160
- log: join54(VOICE_DIR, "voice.log"),
22161
- venv: join54(VOICE_DIR, ".venv"),
22162
- lock: join54(VOICE_DIR, "voice.lock")
22258
+ pid: join55(VOICE_DIR, "voice.pid"),
22259
+ log: join55(VOICE_DIR, "voice.log"),
22260
+ venv: join55(VOICE_DIR, ".venv"),
22261
+ lock: join55(VOICE_DIR, "voice.lock")
22163
22262
  };
22164
22263
  function getPythonDir() {
22165
- return join54(__dirname5, "commands", "voice", "python");
22264
+ return join55(__dirname5, "commands", "voice", "python");
22166
22265
  }
22167
22266
  function getVenvPython() {
22168
- return process.platform === "win32" ? join54(voicePaths.venv, "Scripts", "python.exe") : join54(voicePaths.venv, "bin", "python");
22267
+ return process.platform === "win32" ? join55(voicePaths.venv, "Scripts", "python.exe") : join55(voicePaths.venv, "bin", "python");
22169
22268
  }
22170
22269
  function getLockDir() {
22171
22270
  const config = loadConfig();
22172
22271
  return config.voice?.lockDir ?? VOICE_DIR;
22173
22272
  }
22174
22273
  function getLockFile() {
22175
- return join54(getLockDir(), "voice.lock");
22274
+ return join55(getLockDir(), "voice.lock");
22176
22275
  }
22177
22276
 
22178
22277
  // src/commands/voice/devices.ts
22179
22278
  function devices() {
22180
- const script = join55(getPythonDir(), "list_devices.py");
22279
+ const script = join56(getPythonDir(), "list_devices.py");
22181
22280
  spawnSync5(getVenvPython(), [script], { stdio: "inherit" });
22182
22281
  }
22183
22282
 
@@ -22212,12 +22311,12 @@ function logs(options2) {
22212
22311
  // src/commands/voice/setup.ts
22213
22312
  import { spawnSync as spawnSync6 } from "child_process";
22214
22313
  import { mkdirSync as mkdirSync20 } from "fs";
22215
- import { join as join57 } from "path";
22314
+ import { join as join58 } from "path";
22216
22315
 
22217
22316
  // src/commands/voice/checkLockFile.ts
22218
22317
  import { execSync as execSync54 } from "child_process";
22219
22318
  import { existsSync as existsSync47, mkdirSync as mkdirSync19, readFileSync as readFileSync42, writeFileSync as writeFileSync37 } from "fs";
22220
- import { join as join56 } from "path";
22319
+ import { join as join57 } from "path";
22221
22320
  function isProcessAlive2(pid) {
22222
22321
  try {
22223
22322
  process.kill(pid, 0);
@@ -22254,7 +22353,7 @@ function bootstrapVenv() {
22254
22353
  }
22255
22354
  function writeLockFile(pid) {
22256
22355
  const lockFile = getLockFile();
22257
- mkdirSync19(join56(lockFile, ".."), { recursive: true });
22356
+ mkdirSync19(join57(lockFile, ".."), { recursive: true });
22258
22357
  writeFileSync37(
22259
22358
  lockFile,
22260
22359
  JSON.stringify({
@@ -22270,7 +22369,7 @@ function setup() {
22270
22369
  mkdirSync20(voicePaths.dir, { recursive: true });
22271
22370
  bootstrapVenv();
22272
22371
  console.log("\nDownloading models...\n");
22273
- const script = join57(getPythonDir(), "setup_models.py");
22372
+ const script = join58(getPythonDir(), "setup_models.py");
22274
22373
  const result = spawnSync6(getVenvPython(), [script], {
22275
22374
  stdio: "inherit",
22276
22375
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
@@ -22284,7 +22383,7 @@ function setup() {
22284
22383
  // src/commands/voice/start.ts
22285
22384
  import { spawn as spawn7 } from "child_process";
22286
22385
  import { mkdirSync as mkdirSync21, writeFileSync as writeFileSync38 } from "fs";
22287
- import { join as join58 } from "path";
22386
+ import { join as join59 } from "path";
22288
22387
 
22289
22388
  // src/commands/voice/buildDaemonEnv.ts
22290
22389
  function buildDaemonEnv(options2) {
@@ -22322,7 +22421,7 @@ function start2(options2) {
22322
22421
  bootstrapVenv();
22323
22422
  const debug = options2.debug || options2.foreground || process.platform === "win32";
22324
22423
  const env = buildDaemonEnv({ debug });
22325
- const script = join58(getPythonDir(), "voice_daemon.py");
22424
+ const script = join59(getPythonDir(), "voice_daemon.py");
22326
22425
  const python = getVenvPython();
22327
22426
  if (options2.foreground) {
22328
22427
  spawnForeground(python, script, env);
@@ -22613,7 +22712,7 @@ async function auth() {
22613
22712
  // src/commands/roam/postRoamActivity.ts
22614
22713
  import { execFileSync as execFileSync9 } from "child_process";
22615
22714
  import { readdirSync as readdirSync11, readFileSync as readFileSync45, statSync as statSync8 } from "fs";
22616
- import { join as join59 } from "path";
22715
+ import { join as join60 } from "path";
22617
22716
  function findPortFile(roamDir) {
22618
22717
  let entries;
22619
22718
  try {
@@ -22622,9 +22721,9 @@ function findPortFile(roamDir) {
22622
22721
  return void 0;
22623
22722
  }
22624
22723
  const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
22625
- const path61 = join59(roamDir, name);
22724
+ const path63 = join60(roamDir, name);
22626
22725
  try {
22627
- return { path: path61, mtimeMs: statSync8(path61).mtimeMs };
22726
+ return { path: path63, mtimeMs: statSync8(path63).mtimeMs };
22628
22727
  } catch {
22629
22728
  return void 0;
22630
22729
  }
@@ -22634,7 +22733,7 @@ function findPortFile(roamDir) {
22634
22733
  function postRoamActivity(app, event) {
22635
22734
  const appData = process.env.APPDATA;
22636
22735
  if (!appData) return;
22637
- const portFile = findPortFile(join59(appData, "Roam"));
22736
+ const portFile = findPortFile(join60(appData, "Roam"));
22638
22737
  if (!portFile) return;
22639
22738
  let port;
22640
22739
  try {
@@ -22855,13 +22954,13 @@ function runPreCommands(pre, cwd) {
22855
22954
  // src/commands/run/spawnRunCommand.ts
22856
22955
  import { execFileSync as execFileSync10, spawn as spawn8 } from "child_process";
22857
22956
  import { existsSync as existsSync50 } from "fs";
22858
- import { dirname as dirname27, join as join60, resolve as resolve13 } from "path";
22957
+ import { dirname as dirname27, join as join61, resolve as resolve13 } from "path";
22859
22958
  function resolveCommand2(command) {
22860
22959
  if (process.platform !== "win32" || command !== "bash") return command;
22861
22960
  try {
22862
22961
  const gitPath = execFileSync10("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
22863
22962
  const gitRoot = resolve13(dirname27(gitPath), "..");
22864
- const gitBash = join60(gitRoot, "bin", "bash.exe");
22963
+ const gitBash = join61(gitRoot, "bin", "bash.exe");
22865
22964
  if (existsSync50(gitBash)) return gitBash;
22866
22965
  } catch {
22867
22966
  }
@@ -22950,7 +23049,7 @@ async function run3(name, args) {
22950
23049
 
22951
23050
  // src/commands/run/add.ts
22952
23051
  import { mkdirSync as mkdirSync22, writeFileSync as writeFileSync39 } from "fs";
22953
- import { join as join61 } from "path";
23052
+ import { join as join62 } from "path";
22954
23053
 
22955
23054
  // src/commands/run/extractOption.ts
22956
23055
  function extractOption(args, flag) {
@@ -23011,7 +23110,7 @@ function saveNewRunConfig(name, command, args, cwd) {
23011
23110
  saveConfig(config);
23012
23111
  }
23013
23112
  function createCommandFile(name) {
23014
- const dir = join61(".claude", "commands");
23113
+ const dir = join62(".claude", "commands");
23015
23114
  mkdirSync22(dir, { recursive: true });
23016
23115
  const content = `---
23017
23116
  description: Run ${name}
@@ -23019,7 +23118,7 @@ description: Run ${name}
23019
23118
 
23020
23119
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
23021
23120
  `;
23022
- const filePath = join61(dir, `${name}.md`);
23121
+ const filePath = join62(dir, `${name}.md`);
23023
23122
  writeFileSync39(filePath, content);
23024
23123
  console.log(`Created command file: ${filePath}`);
23025
23124
  }
@@ -23043,11 +23142,11 @@ function findLinkIndex() {
23043
23142
  function parseLinkArgs() {
23044
23143
  const idx = findLinkIndex();
23045
23144
  if (idx === -1) return null;
23046
- const path61 = process.argv[idx + 1];
23145
+ const path63 = process.argv[idx + 1];
23047
23146
  const rest = process.argv.slice(idx + 2);
23048
23147
  const { value: prefix2 } = extractOption(rest, "--prefix");
23049
23148
  if (!prefix2) return null;
23050
- return { path: path61, prefix: prefix2 };
23149
+ return { path: path63, prefix: prefix2 };
23051
23150
  }
23052
23151
  function hasDuplicateLink(runList, linkPath) {
23053
23152
  return runList.some(
@@ -23076,7 +23175,7 @@ function link2() {
23076
23175
 
23077
23176
  // src/commands/run/remove.ts
23078
23177
  import { existsSync as existsSync51, unlinkSync as unlinkSync18 } from "fs";
23079
- import { join as join62 } from "path";
23178
+ import { join as join63 } from "path";
23080
23179
  function findRemoveIndex() {
23081
23180
  const idx = process.argv.indexOf("remove");
23082
23181
  if (idx === -1 || idx + 1 >= process.argv.length) return -1;
@@ -23091,7 +23190,7 @@ function parseRemoveName() {
23091
23190
  return process.argv[idx + 1];
23092
23191
  }
23093
23192
  function deleteCommandFile(name) {
23094
- const filePath = join62(".claude", "commands", `${name}.md`);
23193
+ const filePath = join63(".claude", "commands", `${name}.md`);
23095
23194
  if (existsSync51(filePath)) {
23096
23195
  unlinkSync18(filePath);
23097
23196
  console.log(`Deleted command file: ${filePath}`);
@@ -23148,7 +23247,7 @@ function registerRun(program2) {
23148
23247
  import { execSync as execSync56 } from "child_process";
23149
23248
  import { existsSync as existsSync52, mkdirSync as mkdirSync23, unlinkSync as unlinkSync19, writeFileSync as writeFileSync40 } from "fs";
23150
23249
  import { tmpdir as tmpdir7 } from "os";
23151
- import { join as join63, resolve as resolve15 } from "path";
23250
+ import { join as join64, resolve as resolve15 } from "path";
23152
23251
  import chalk195 from "chalk";
23153
23252
 
23154
23253
  // src/commands/screenshot/captureWindowPs1.ts
@@ -23285,7 +23384,7 @@ function buildOutputPath(outputDir, processName) {
23285
23384
  return resolve15(outputDir, `${processName}-${timestamp5}.png`);
23286
23385
  }
23287
23386
  function runPowerShellScript(processName, outputPath) {
23288
- const scriptPath = join63(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
23387
+ const scriptPath = join64(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
23289
23388
  writeFileSync40(scriptPath, captureWindowPs1, "utf8");
23290
23389
  try {
23291
23390
  execSync56(
@@ -23755,14 +23854,14 @@ import * as pty from "node-pty";
23755
23854
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
23756
23855
  import { chmodSync, existsSync as existsSync53, statSync as statSync9 } from "fs";
23757
23856
  import { createRequire as createRequire3 } from "module";
23758
- import path54 from "path";
23857
+ import path55 from "path";
23759
23858
  var require4 = createRequire3(import.meta.url);
23760
23859
  var ensured = false;
23761
23860
  function ensureSpawnHelperExecutable() {
23762
23861
  if (ensured || process.platform !== "darwin") return;
23763
23862
  ensured = true;
23764
- const ptyRoot = path54.join(path54.dirname(require4.resolve("node-pty")), "..");
23765
- const helper = path54.join(
23863
+ const ptyRoot = path55.join(path55.dirname(require4.resolve("node-pty")), "..");
23864
+ const helper = path55.join(
23766
23865
  ptyRoot,
23767
23866
  "prebuilds",
23768
23867
  `${process.platform}-${process.arch}`,
@@ -23824,12 +23923,12 @@ import { randomUUID as randomUUID4 } from "crypto";
23824
23923
 
23825
23924
  // src/commands/sessions/daemon/readDesignSystemPrompt.ts
23826
23925
  import * as fs33 from "fs";
23827
- import * as path55 from "path";
23926
+ import * as path56 from "path";
23828
23927
  import { fileURLToPath as fileURLToPath8 } from "url";
23829
23928
  var __filename4 = fileURLToPath8(import.meta.url);
23830
- var __dirname6 = path55.dirname(__filename4);
23929
+ var __dirname6 = path56.dirname(__filename4);
23831
23930
  function readDesignSystemPrompt() {
23832
- const promptPath = path55.join(__dirname6, "..", "claude", "system-prompt.md");
23931
+ const promptPath = path56.join(__dirname6, "..", "claude", "system-prompt.md");
23833
23932
  return fs33.readFileSync(promptPath, "utf8");
23834
23933
  }
23835
23934
 
@@ -24327,8 +24426,8 @@ async function seedRunningMsFromUsage(session, notify2) {
24327
24426
  var DEBOUNCE_MS = 50;
24328
24427
  function watchActivity(session, notify2) {
24329
24428
  if (session.commandType !== "assist" || !session.cwd) return;
24330
- const path61 = activityPath(session.id);
24331
- const dir = dirname29(path61);
24429
+ const path63 = activityPath(session.id);
24430
+ const dir = dirname29(path63);
24332
24431
  try {
24333
24432
  mkdirSync24(dir, { recursive: true });
24334
24433
  } catch {
@@ -24338,7 +24437,7 @@ function watchActivity(session, notify2) {
24338
24437
  let timer = null;
24339
24438
  const read = () => {
24340
24439
  timer = null;
24341
- const activity2 = readActivity(path61);
24440
+ const activity2 = readActivity(path63);
24342
24441
  if (!activity2) return;
24343
24442
  session.activity = activity2;
24344
24443
  if (activity2.claudeSessionId)
@@ -24348,11 +24447,11 @@ function watchActivity(session, notify2) {
24348
24447
  notify2();
24349
24448
  };
24350
24449
  session.activityWatcher = watch(dir, (_event, filename) => {
24351
- if (filename && !path61.endsWith(filename)) return;
24450
+ if (filename && !path63.endsWith(filename)) return;
24352
24451
  if (timer) clearTimeout(timer);
24353
24452
  timer = setTimeout(read, DEBOUNCE_MS);
24354
24453
  });
24355
- if (existsSync54(path61)) read();
24454
+ if (existsSync54(path63)) read();
24356
24455
  }
24357
24456
  function refreshActivity(session) {
24358
24457
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -26313,9 +26412,9 @@ function buildLimitsSegment(rateLimits) {
26313
26412
 
26314
26413
  // src/commands/readGitBranch.ts
26315
26414
  import { readFileSync as readFileSync50, statSync as statSync11 } from "fs";
26316
- import { isAbsolute as isAbsolute2, join as join65, resolve as resolve16 } from "path";
26415
+ import { isAbsolute as isAbsolute2, join as join66, resolve as resolve16 } from "path";
26317
26416
  function resolveGitDir(cwd) {
26318
- const dotGit = join65(cwd, ".git");
26417
+ const dotGit = join66(cwd, ".git");
26319
26418
  let stat2;
26320
26419
  try {
26321
26420
  stat2 = statSync11(dotGit);
@@ -26345,7 +26444,7 @@ function readGitBranch(cwd) {
26345
26444
  }
26346
26445
  let head;
26347
26446
  try {
26348
- head = readFileSync50(join65(gitDir, "HEAD"), "utf8");
26447
+ head = readFileSync50(join66(gitDir, "HEAD"), "utf8");
26349
26448
  } catch {
26350
26449
  return null;
26351
26450
  }
@@ -26408,18 +26507,18 @@ async function statusLine() {
26408
26507
  }
26409
26508
 
26410
26509
  // src/commands/sync.ts
26411
- import * as fs42 from "fs";
26412
- import * as os2 from "os";
26413
- import * as path59 from "path";
26510
+ import * as fs43 from "fs";
26511
+ import * as os3 from "os";
26512
+ import * as path61 from "path";
26414
26513
  import { fileURLToPath as fileURLToPath9 } from "url";
26415
26514
 
26416
26515
  // src/commands/sync/syncClaudeMd.ts
26417
26516
  import * as fs39 from "fs";
26418
- import * as path56 from "path";
26517
+ import * as path57 from "path";
26419
26518
  import chalk199 from "chalk";
26420
26519
  async function syncClaudeMd(claudeDir, targetBase, options2) {
26421
- const source = path56.join(claudeDir, "CLAUDE.md");
26422
- const target = path56.join(targetBase, "CLAUDE.md");
26520
+ const source = path57.join(claudeDir, "CLAUDE.md");
26521
+ const target = path57.join(targetBase, "CLAUDE.md");
26423
26522
  const sourceContent = fs39.readFileSync(source, "utf8");
26424
26523
  if (fs39.existsSync(target)) {
26425
26524
  const targetContent = fs39.readFileSync(target, "utf8");
@@ -26443,38 +26542,79 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
26443
26542
  console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
26444
26543
  }
26445
26544
 
26446
- // src/commands/sync/syncDesign.ts
26545
+ // src/commands/sync/syncCodex.ts
26447
26546
  import * as fs40 from "fs";
26448
- import * as path57 from "path";
26547
+ import * as path58 from "path";
26548
+ function quoteYaml(value) {
26549
+ return `"${value.replace(/\\/g, String.raw`\\`).replace(/"/g, String.raw`\"`)}"`;
26550
+ }
26551
+ function commandToSkill(name, content) {
26552
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
26553
+ const frontmatter = match ? match[1] : "";
26554
+ const body = match ? content.slice(match[0].length) : content;
26555
+ const descriptionMatch = frontmatter.match(/^description:\s*(.*)$/m);
26556
+ const description = descriptionMatch ? descriptionMatch[1].trim().replace(/^["']|["']$/g, "") : name;
26557
+ const header = `---
26558
+ name: ${name}
26559
+ description: ${quoteYaml(description)}
26560
+ ---
26561
+
26562
+ `;
26563
+ return header + body.replace(/^\r?\n+/, "");
26564
+ }
26565
+ function syncCodex(claudeDir) {
26566
+ if (!isHarnessAvailable("codex")) return;
26567
+ const codex = harnesses.codex;
26568
+ const commandsSource = path58.join(claudeDir, "commands");
26569
+ const files = fs40.readdirSync(commandsSource);
26570
+ for (const file of files) {
26571
+ if (!file.endsWith(".md")) continue;
26572
+ const name = file.replace(/\.md$/, "");
26573
+ const content = fs40.readFileSync(path58.join(commandsSource, file), "utf8");
26574
+ const target = path58.join(codex.homeDir, codex.sync.commandDest(name));
26575
+ fs40.mkdirSync(path58.dirname(target), { recursive: true });
26576
+ fs40.writeFileSync(target, commandToSkill(name, content));
26577
+ }
26578
+ const agentsTarget = path58.join(codex.homeDir, codex.sync.agentsFile);
26579
+ fs40.mkdirSync(path58.dirname(agentsTarget), { recursive: true });
26580
+ fs40.copyFileSync(path58.join(claudeDir, "CLAUDE.md"), agentsTarget);
26581
+ console.log(
26582
+ `Synced ${files.length} skill(s) to ~/.codex/skills and CLAUDE.md to ~/.codex/AGENTS.md`
26583
+ );
26584
+ }
26585
+
26586
+ // src/commands/sync/syncDesign.ts
26587
+ import * as fs41 from "fs";
26588
+ import * as path59 from "path";
26449
26589
  function syncDesign(claudeDir, targetBase) {
26450
- const systemPromptSource = path57.join(claudeDir, "system-prompt.md");
26451
- const systemPromptTarget = path57.join(targetBase, "system-prompt.md");
26452
- fs40.copyFileSync(systemPromptSource, systemPromptTarget);
26590
+ const systemPromptSource = path59.join(claudeDir, "system-prompt.md");
26591
+ const systemPromptTarget = path59.join(targetBase, "system-prompt.md");
26592
+ fs41.copyFileSync(systemPromptSource, systemPromptTarget);
26453
26593
  console.log("Copied system-prompt.md to ~/.claude/system-prompt.md");
26454
- const skillsSource = path57.join(claudeDir, "skills");
26455
- const skillsTarget = path57.join(targetBase, "skills");
26456
- fs40.mkdirSync(skillsTarget, { recursive: true });
26457
- const files = fs40.readdirSync(skillsSource);
26594
+ const skillsSource = path59.join(claudeDir, "skills");
26595
+ const skillsTarget = path59.join(targetBase, "skills");
26596
+ fs41.mkdirSync(skillsTarget, { recursive: true });
26597
+ const files = fs41.readdirSync(skillsSource);
26458
26598
  for (const file of files) {
26459
- fs40.copyFileSync(
26460
- path57.join(skillsSource, file),
26461
- path57.join(skillsTarget, file)
26599
+ fs41.copyFileSync(
26600
+ path59.join(skillsSource, file),
26601
+ path59.join(skillsTarget, file)
26462
26602
  );
26463
26603
  }
26464
26604
  console.log(`Synced ${files.length} design skill(s) to ~/.claude/skills`);
26465
26605
  }
26466
26606
 
26467
26607
  // src/commands/sync/syncSettings.ts
26468
- import * as fs41 from "fs";
26469
- import * as path58 from "path";
26608
+ import * as fs42 from "fs";
26609
+ import * as path60 from "path";
26470
26610
  import chalk200 from "chalk";
26471
26611
  async function syncSettings(claudeDir, targetBase, options2) {
26472
- const source = path58.join(claudeDir, "settings.json");
26473
- const target = path58.join(targetBase, "settings.json");
26474
- const sourceContent = fs41.readFileSync(source, "utf8");
26612
+ const source = path60.join(claudeDir, "settings.json");
26613
+ const target = path60.join(targetBase, "settings.json");
26614
+ const sourceContent = fs42.readFileSync(source, "utf8");
26475
26615
  const sourceSettings = JSON.parse(sourceContent);
26476
- const targetExists = fs41.existsSync(target);
26477
- const targetContent = targetExists ? fs41.readFileSync(target, "utf8") : "";
26616
+ const targetExists = fs42.existsSync(target);
26617
+ const targetContent = targetExists ? fs42.readFileSync(target, "utf8") : "";
26478
26618
  const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
26479
26619
  const mergedContent = JSON.stringify(
26480
26620
  { ...preservedUserSettings, ...sourceSettings },
@@ -26503,30 +26643,31 @@ async function syncSettings(claudeDir, targetBase, options2) {
26503
26643
  }
26504
26644
  }
26505
26645
  }
26506
- fs41.writeFileSync(target, mergedContent);
26646
+ fs42.writeFileSync(target, mergedContent);
26507
26647
  console.log("Copied settings.json to ~/.claude/settings.json");
26508
26648
  }
26509
26649
 
26510
26650
  // src/commands/sync.ts
26511
26651
  var __filename5 = fileURLToPath9(import.meta.url);
26512
- var __dirname7 = path59.dirname(__filename5);
26652
+ var __dirname7 = path61.dirname(__filename5);
26513
26653
  async function sync(options2) {
26514
26654
  const config = loadConfig();
26515
26655
  const yes = options2?.yes ?? config.sync.autoConfirm;
26516
- const claudeDir = path59.join(__dirname7, "..", "claude");
26517
- const targetBase = path59.join(os2.homedir(), ".claude");
26656
+ const claudeDir = path61.join(__dirname7, "..", "claude");
26657
+ const targetBase = path61.join(os3.homedir(), ".claude");
26518
26658
  syncCommands(claudeDir, targetBase);
26519
26659
  syncDesign(claudeDir, targetBase);
26520
26660
  await syncSettings(claudeDir, targetBase, { yes });
26521
26661
  await syncClaudeMd(claudeDir, targetBase, { yes });
26662
+ syncCodex(claudeDir);
26522
26663
  }
26523
26664
  function syncCommands(claudeDir, targetBase) {
26524
- const sourceDir = path59.join(claudeDir, "commands");
26525
- const targetDir = path59.join(targetBase, "commands");
26526
- fs42.mkdirSync(targetDir, { recursive: true });
26527
- const files = fs42.readdirSync(sourceDir);
26665
+ const sourceDir = path61.join(claudeDir, "commands");
26666
+ const targetDir = path61.join(targetBase, "commands");
26667
+ fs43.mkdirSync(targetDir, { recursive: true });
26668
+ const files = fs43.readdirSync(sourceDir);
26528
26669
  for (const file of files) {
26529
- fs42.copyFileSync(path59.join(sourceDir, file), path59.join(targetDir, file));
26670
+ fs43.copyFileSync(path61.join(sourceDir, file), path61.join(targetDir, file));
26530
26671
  console.log(`Copied ${file} to ${targetDir}`);
26531
26672
  }
26532
26673
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -26534,7 +26675,7 @@ function syncCommands(claudeDir, targetBase) {
26534
26675
 
26535
26676
  // src/commands/update.ts
26536
26677
  import { execSync as execSync57 } from "child_process";
26537
- import * as path60 from "path";
26678
+ import * as path62 from "path";
26538
26679
 
26539
26680
  // src/commands/restartDaemonAfterUpdate.ts
26540
26681
  async function restartDaemonAfterUpdate() {
@@ -26553,12 +26694,12 @@ async function restartDaemonAfterUpdate() {
26553
26694
  // src/commands/update.ts
26554
26695
  function isGlobalNpmInstall(dir) {
26555
26696
  try {
26556
- const resolved = path60.resolve(dir);
26557
- if (resolved.split(path60.sep).includes("node_modules")) {
26697
+ const resolved = path62.resolve(dir);
26698
+ if (resolved.split(path62.sep).includes("node_modules")) {
26558
26699
  return true;
26559
26700
  }
26560
26701
  const globalPrefix = execSync57("npm prefix -g", { stdio: "pipe" }).toString().trim();
26561
- return resolved.toLowerCase().startsWith(path60.resolve(globalPrefix).toLowerCase());
26702
+ return resolved.toLowerCase().startsWith(path62.resolve(globalPrefix).toLowerCase());
26562
26703
  } catch {
26563
26704
  return false;
26564
26705
  }
@@ -26603,7 +26744,9 @@ function reportCliError(error) {
26603
26744
  // src/index.ts
26604
26745
  var program = new Command();
26605
26746
  program.name("assist").description("CLI application").version(package_default.version).option("--no-open", "Do not open a browser on startup").action((options2) => web({ port: "3100", open: options2.open }));
26606
- var syncCommand = program.command("sync").description("Copy command files to ~/.claude/commands").option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
26747
+ var syncCommand = program.command("sync").description(
26748
+ "Copy command files to ~/.claude/commands; when codex is detected, also install commands as ~/.codex/skills/<name>/SKILL.md and CLAUDE.md as ~/.codex/AGENTS.md"
26749
+ ).option("-y, --yes", "Overwrite settings.json without prompting").action((options2) => sync(options2));
26607
26750
  configHelp(syncCommand, rootConfigHelp.sync);
26608
26751
  program.command("init").description("Initialize VS Code and verify configurations").action(init5);
26609
26752
  var commitCommand = program.command("commit").description("Create a git commit with validation").argument("<args...>", "status | <message> [files...]").action(commit);