@staff0rd/assist 0.440.0 → 0.442.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.440.0",
9
+ version: "0.442.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -98,11 +98,11 @@ var package_default = {
98
98
  "@types/pg-copy-streams": "^1.2.5",
99
99
  "@types/react": "^19.2.14",
100
100
  "@types/react-dom": "^19.2.3",
101
- "@types/react-file-icon": "^1.0.5",
102
101
  "@types/semver": "^7.7.1",
103
102
  "@types/shell-quote": "^1.7.5",
104
103
  "@types/ws": "^8.18.1",
105
104
  "@vitest/coverage-v8": "^4.1.2",
105
+ "devicons-react": "^1.5.0",
106
106
  esbuild: "^0.27.3",
107
107
  jscpd: "^4.0.5",
108
108
  jsdom: "^29.1.1",
@@ -111,7 +111,6 @@ var package_default = {
111
111
  oxlint: "^1.69.0",
112
112
  react: "^19.2.4",
113
113
  "react-dom": "^19.2.4",
114
- "react-file-icon": "^1.6.0",
115
114
  "react-router": "^7.14.0",
116
115
  "semantic-release": "^25.0.2",
117
116
  skott: "^0.35.11",
@@ -438,6 +437,7 @@ var assistConfigSchema = z2.strictObject({
438
437
  enabled: z2.boolean().default(false),
439
438
  root: z2.string().optional(),
440
439
  install: z2.union([z2.boolean(), z2.string()]).default(true),
440
+ commitBeforeManualChecks: z2.boolean().default(false),
441
441
  copy: z2.array(z2.string()).default([
442
442
  ".env",
443
443
  "settings.local.json",
@@ -585,9 +585,6 @@ function loadConfigFrom(cwd) {
585
585
  }
586
586
 
587
587
  // src/shared/loadConfig.ts
588
- function getConfigPath() {
589
- return getConfigPathFrom(process.cwd());
590
- }
591
588
  function getConfigDir() {
592
589
  return getConfigDirFrom(process.cwd());
593
590
  }
@@ -598,8 +595,8 @@ function getProjectRoot() {
598
595
  function loadConfig() {
599
596
  return loadConfigFrom(process.cwd());
600
597
  }
601
- function loadProjectConfig() {
602
- return loadRawYaml(getConfigPath());
598
+ function loadProjectConfig(cwd = process.cwd()) {
599
+ return loadRawYaml(getConfigPathFrom(cwd));
603
600
  }
604
601
  function loadGlobalConfigRaw() {
605
602
  return loadRawYaml(getGlobalConfigPath());
@@ -607,8 +604,8 @@ function loadGlobalConfigRaw() {
607
604
  function saveGlobalConfig(config) {
608
605
  writeFileSync(getGlobalConfigPath(), stringifyYaml(config, { lineWidth: 0 }));
609
606
  }
610
- function saveConfig(config) {
611
- const configPath = getConfigPath();
607
+ function saveConfig(config, cwd = process.cwd()) {
608
+ const configPath = getConfigPathFrom(cwd);
612
609
  writeFileSync(configPath, stringifyYaml(config, { lineWidth: 0 }));
613
610
  }
614
611
  function getTranscriptConfig() {
@@ -3532,7 +3529,7 @@ function configHelp(command, entries, preamble) {
3532
3529
  );
3533
3530
  }
3534
3531
 
3535
- // src/shared/enumerateConfigLeafKeys.ts
3532
+ // src/shared/unwrapSchemaNode.ts
3536
3533
  var WRAPPER_TYPES = /* @__PURE__ */ new Set([
3537
3534
  "optional",
3538
3535
  "default",
@@ -3541,28 +3538,64 @@ var WRAPPER_TYPES = /* @__PURE__ */ new Set([
3541
3538
  "readonly",
3542
3539
  "catch"
3543
3540
  ]);
3544
- function unwrap(node) {
3541
+ function unwrapSchemaNode(node) {
3545
3542
  let current = node;
3543
+ let defaultValue;
3546
3544
  while (current.def && WRAPPER_TYPES.has(current.def.type ?? "") && current.def.innerType) {
3545
+ if (current.def.type === "default" && defaultValue === void 0) {
3546
+ defaultValue = current.def.defaultValue;
3547
+ }
3547
3548
  current = current.def.innerType;
3548
3549
  }
3549
- return current;
3550
+ return { inner: current, defaultValue };
3551
+ }
3552
+
3553
+ // src/shared/describeConfigLeaves.ts
3554
+ var LEAF_TYPES = {
3555
+ string: "string",
3556
+ number: "number",
3557
+ boolean: "boolean",
3558
+ enum: "enum",
3559
+ array: "array",
3560
+ record: "record"
3561
+ };
3562
+ function leafType(node) {
3563
+ return LEAF_TYPES[node.def?.type ?? ""] ?? "other";
3564
+ }
3565
+ function enumValues(node) {
3566
+ const entries = node.def?.entries;
3567
+ if (!entries) return void 0;
3568
+ return Object.values(entries).filter(
3569
+ (value) => typeof value === "string"
3570
+ );
3571
+ }
3572
+ function toLeaf(key, node, defaultValue) {
3573
+ const type = leafType(node);
3574
+ const leaf = { key, type };
3575
+ if (type === "enum") leaf.enumValues = enumValues(node);
3576
+ if (defaultValue !== void 0) leaf.defaultValue = defaultValue;
3577
+ return leaf;
3550
3578
  }
3551
3579
  function collect(node, prefix2, out) {
3552
- const unwrapped = unwrap(node);
3553
- const shape = unwrapped.def?.shape;
3554
- if (unwrapped.def?.type === "object" && shape) {
3580
+ const { inner, defaultValue } = unwrapSchemaNode(node);
3581
+ const shape = inner.def?.shape;
3582
+ if (inner.def?.type === "object" && shape) {
3555
3583
  for (const [key, child] of Object.entries(shape)) {
3556
3584
  collect(child, prefix2 ? `${prefix2}.${key}` : key, out);
3557
3585
  }
3558
3586
  return;
3559
3587
  }
3560
- out.push(prefix2);
3588
+ out.push(toLeaf(prefix2, inner, defaultValue));
3561
3589
  }
3562
- function enumerateConfigLeafKeys(schema2) {
3590
+ function describeConfigLeaves(schema2) {
3563
3591
  const out = [];
3564
3592
  collect(schema2, "", out);
3565
- return out.sort();
3593
+ return out.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
3594
+ }
3595
+
3596
+ // src/shared/enumerateConfigLeafKeys.ts
3597
+ function enumerateConfigLeafKeys(schema2) {
3598
+ return describeConfigLeaves(schema2).map((leaf) => leaf.key);
3566
3599
  }
3567
3600
 
3568
3601
  // src/commands/verify/pendingConfigDocumentation.ts
@@ -3648,9 +3681,9 @@ function forbiddenStrings() {
3648
3681
  console.log("No forbidden-strings rules configured.");
3649
3682
  process.exit(0);
3650
3683
  }
3651
- const cache2 = /* @__PURE__ */ new Map();
3684
+ const cache3 = /* @__PURE__ */ new Map();
3652
3685
  const readJson = (file) => {
3653
- if (cache2.has(file)) return cache2.get(file);
3686
+ if (cache3.has(file)) return cache3.get(file);
3654
3687
  if (!existsSync12(file)) {
3655
3688
  console.log(`Forbidden-strings file not found: ${file}`);
3656
3689
  process.exit(1);
@@ -3662,7 +3695,7 @@ function forbiddenStrings() {
3662
3695
  console.log(`Could not parse ${file}: ${error.message}`);
3663
3696
  process.exit(1);
3664
3697
  }
3665
- cache2.set(file, parsed);
3698
+ cache3.set(file, parsed);
3666
3699
  return parsed;
3667
3700
  };
3668
3701
  const violations = findForbiddenStrings(rules, readJson);
@@ -6609,8 +6642,27 @@ function formatPromptComment(entry) {
6609
6642
  ${entry.text}`;
6610
6643
  }
6611
6644
 
6645
+ // src/commands/backlog/buildManualCheckLines.ts
6646
+ function buildManualCheckLines(manualChecks, commitBeforeManualChecks) {
6647
+ if (manualChecks.length > 0) {
6648
+ return [
6649
+ "",
6650
+ ...commitBeforeManualChecks ? [
6651
+ "Once verify passes, run /commit to commit the work before asking the user to perform the manual checks below."
6652
+ ] : [],
6653
+ "Before marking this phase as done, ask the user to perform these manual checks:",
6654
+ ...manualChecks.map((c) => `- ${c}`),
6655
+ "",
6656
+ "Wait for the user to confirm all manual checks pass before proceeding."
6657
+ ];
6658
+ }
6659
+ return [];
6660
+ }
6661
+
6612
6662
  // src/commands/backlog/buildAuthoredPhasePrompt.ts
6613
- function buildAuthoredPhasePrompt(item, phaseNumber, phase) {
6663
+ function buildAuthoredPhasePrompt(item, phaseNumber, phase, options2 = {
6664
+ commitBeforeManualChecks: false
6665
+ }) {
6614
6666
  const manualChecks = phase.manualChecks ?? [];
6615
6667
  const needsConfirmation = manualChecks.length > 0;
6616
6668
  const confirmSuffix = needsConfirmation ? " and the user confirms" : "";
@@ -6621,7 +6673,7 @@ function buildAuthoredPhasePrompt(item, phaseNumber, phase) {
6621
6673
  "Focus ONLY on this phase. Do not work on other phases.",
6622
6674
  "If you need to modify backlog items, run `assist backlog --help` to discover available commands.",
6623
6675
  "When you have completed all tasks for this phase, run /verify to check your work.",
6624
- ...buildManualCheckLines(manualChecks),
6676
+ ...buildManualCheckLines(manualChecks, options2.commitBeforeManualChecks),
6625
6677
  "",
6626
6678
  `Post concise comments for any notable findings or changes using \`assist backlog comment ${formatItemId(item.id)} "<text>"\`.`,
6627
6679
  "",
@@ -6654,24 +6706,14 @@ function buildJiraStartedLines(item, phaseNumber) {
6654
6706
  `As your first step, before any implementation, run \`/jira started ${item.jiraKey}\` to assign the issue to yourself and transition it to In Progress.`
6655
6707
  ];
6656
6708
  }
6657
- function buildManualCheckLines(manualChecks) {
6658
- if (manualChecks.length > 0) {
6659
- return [
6660
- "",
6661
- "Before marking this phase as done, ask the user to perform these manual checks:",
6662
- ...manualChecks.map((c) => `- ${c}`),
6663
- "",
6664
- "Wait for the user to confirm all manual checks pass before proceeding."
6665
- ];
6666
- }
6667
- return [];
6668
- }
6669
6709
  function formatTasks(phase) {
6670
6710
  return phase.tasks.map((t) => `- ${t.task}`).join("\n");
6671
6711
  }
6672
6712
 
6673
6713
  // src/commands/backlog/buildReviewPrompt.ts
6674
- function buildReviewPrompt(item, phaseNumber) {
6714
+ function buildReviewPrompt(item, phaseNumber, options2 = {
6715
+ commitBeforeManualChecks: false
6716
+ }) {
6675
6717
  const acLines = item.acceptanceCriteria.map((ac, i) => `${i + 1}. ${ac}`).join("\n");
6676
6718
  const itemId2 = formatItemId(item.id);
6677
6719
  return [
@@ -6692,6 +6734,10 @@ function buildReviewPrompt(item, phaseNumber) {
6692
6734
  "",
6693
6735
  `Post concise comments for any notable findings or changes using \`assist backlog comment ${itemId2} "<text>"\`.`,
6694
6736
  "",
6737
+ ...options2.commitBeforeManualChecks ? [
6738
+ "Before asking the user to confirm manual checks, run /commit to commit the work (it is fine if there is nothing new to commit).",
6739
+ ""
6740
+ ] : [],
6695
6741
  "After all criteria pass, ask the user to confirm any manual checks",
6696
6742
  "(e.g. end-to-end behaviour they need to verify themselves).",
6697
6743
  "Wait for the user to confirm before proceeding.",
@@ -6716,10 +6762,13 @@ function buildReviewPrompt(item, phaseNumber) {
6716
6762
  // src/commands/backlog/buildPhasePrompt.ts
6717
6763
  var REVIEW_PHASE_NAME = "Review";
6718
6764
  function buildPhasePrompt(item, phaseNumber, phase) {
6765
+ const commitBeforeManualChecks = loadConfig().worktree?.commitBeforeManualChecks ?? false;
6719
6766
  if (phase.name === REVIEW_PHASE_NAME) {
6720
- return buildReviewPrompt(item, phaseNumber);
6767
+ return buildReviewPrompt(item, phaseNumber, { commitBeforeManualChecks });
6721
6768
  }
6722
- return buildAuthoredPhasePrompt(item, phaseNumber, phase);
6769
+ return buildAuthoredPhasePrompt(item, phaseNumber, phase, {
6770
+ commitBeforeManualChecks
6771
+ });
6723
6772
  }
6724
6773
 
6725
6774
  // src/commands/backlog/watchForMarker.ts
@@ -8098,26 +8147,210 @@ function delay(ms) {
8098
8147
  return new Promise((resolve20) => setTimeout(resolve20, ms));
8099
8148
  }
8100
8149
 
8150
+ // src/commands/sessions/daemon/isWindowsCwd.ts
8151
+ function isWindowsCwd(cwd) {
8152
+ return /^[A-Za-z]:[\\/]/.test(cwd);
8153
+ }
8154
+ function shouldProxyToWindows(cwd) {
8155
+ return detectPlatform() === "wsl" && isWindowsCwd(cwd);
8156
+ }
8157
+
8158
+ // src/commands/sessions/daemon/originForCwd.ts
8159
+ var cache = /* @__PURE__ */ new Map();
8160
+ function originForCwd(cwd) {
8161
+ if (!cwd) return void 0;
8162
+ const cached = cache.get(cwd);
8163
+ if (cached !== void 0) return cached;
8164
+ const origin = getCurrentOrigin(cwd);
8165
+ cache.set(cwd, origin);
8166
+ return origin;
8167
+ }
8168
+
8169
+ // src/commands/sessions/daemon/worktree/git.ts
8170
+ import { execFile as execFile2, execFileSync as execFileSync2 } from "child_process";
8171
+ function isWindowsPath(cwd) {
8172
+ return /^[A-Za-z]:[\\/]/.test(cwd);
8173
+ }
8174
+ function gitInvocation(cwd, args) {
8175
+ const windows = isWindowsPath(cwd);
8176
+ return {
8177
+ file: windows ? "git.exe" : "git",
8178
+ argv: windows ? ["-C", cwd, ...args] : args,
8179
+ options: { encoding: "utf8", ...windows ? {} : { cwd } }
8180
+ };
8181
+ }
8182
+ function git2(cwd, args) {
8183
+ const { file, argv, options: options2 } = gitInvocation(cwd, args);
8184
+ return new Promise((resolve20, reject) => {
8185
+ execFile2(file, argv, options2, (error, stdout) => {
8186
+ if (error) reject(error);
8187
+ else resolve20(stdout.toString());
8188
+ });
8189
+ });
8190
+ }
8191
+ async function gitOrNull(cwd, args) {
8192
+ try {
8193
+ return (await git2(cwd, args)).trim() || null;
8194
+ } catch {
8195
+ return null;
8196
+ }
8197
+ }
8198
+ async function gitResult(cwd, args) {
8199
+ try {
8200
+ return { ok: true, out: (await git2(cwd, args)).trim() };
8201
+ } catch (error) {
8202
+ return {
8203
+ ok: false,
8204
+ error: error instanceof Error ? error.message : String(error)
8205
+ };
8206
+ }
8207
+ }
8208
+ function gitSyncResult(cwd, args) {
8209
+ try {
8210
+ return { ok: true, out: gitSync(cwd, args).trim() };
8211
+ } catch (error) {
8212
+ return {
8213
+ ok: false,
8214
+ error: error instanceof Error ? error.message : String(error)
8215
+ };
8216
+ }
8217
+ }
8218
+ function gitSync(cwd, args) {
8219
+ const { file, argv, options: options2 } = gitInvocation(cwd, args);
8220
+ return execFileSync2(file, argv, {
8221
+ ...options2,
8222
+ stdio: ["pipe", "pipe", "pipe"]
8223
+ }).toString();
8224
+ }
8225
+ function gitSyncOrNull(cwd, args) {
8226
+ try {
8227
+ return gitSync(cwd, args).trim() || null;
8228
+ } catch {
8229
+ return null;
8230
+ }
8231
+ }
8232
+
8233
+ // src/commands/sessions/daemon/worktree/listWorktreePaths.ts
8234
+ function listWorktreePaths(cwd) {
8235
+ const out = gitSyncOrNull(cwd, ["worktree", "list", "--porcelain"]);
8236
+ if (!out) return [];
8237
+ return out.split("\n").filter((line) => line.startsWith("worktree ")).map((line) => line.slice("worktree ".length).trim());
8238
+ }
8239
+ function mainWorktree(cwd) {
8240
+ return listWorktreePaths(cwd)[0] ?? null;
8241
+ }
8242
+ function listLocalBranches(cwd) {
8243
+ const out = gitSyncOrNull(cwd, [
8244
+ "for-each-ref",
8245
+ "--format=%(refname:short)",
8246
+ "refs/heads"
8247
+ ]);
8248
+ return out ? out.split("\n").map((line) => line.trim()) : [];
8249
+ }
8250
+ function gitCommonDir(cwd) {
8251
+ return gitSyncOrNull(cwd, [
8252
+ "rev-parse",
8253
+ "--path-format=absolute",
8254
+ "--git-common-dir"
8255
+ ]);
8256
+ }
8257
+
8258
+ // src/shared/loadJson.ts
8259
+ import { existsSync as existsSync25, mkdirSync as mkdirSync11, readFileSync as readFileSync18, writeFileSync as writeFileSync20 } from "fs";
8260
+ import { homedir as homedir11 } from "os";
8261
+ import { join as join22 } from "path";
8262
+ function getStoreDir() {
8263
+ return join22(homedir11(), ".assist");
8264
+ }
8265
+ function getStorePath(filename) {
8266
+ return join22(getStoreDir(), filename);
8267
+ }
8268
+ function loadJson(filename) {
8269
+ const path71 = getStorePath(filename);
8270
+ if (existsSync25(path71)) {
8271
+ try {
8272
+ return JSON.parse(readFileSync18(path71, "utf8"));
8273
+ } catch {
8274
+ return {};
8275
+ }
8276
+ }
8277
+ return {};
8278
+ }
8279
+ function saveJson(filename, data) {
8280
+ const dir = getStoreDir();
8281
+ if (!existsSync25(dir)) {
8282
+ mkdirSync11(dir, { recursive: true });
8283
+ }
8284
+ writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
8285
+ }
8286
+
8287
+ // src/commands/sessions/daemon/worktree/readWorktreeRegistry.ts
8288
+ var REGISTRY_FILE = "worktrees.json";
8289
+ function readWorktreeRegistry() {
8290
+ const data = loadJson(REGISTRY_FILE);
8291
+ return Object.entries(data).filter(([, record]) => !record.reaped).map(([path71, record]) => ({ path: path71, ...record }));
8292
+ }
8293
+ function worktreeAttributionIncludingReaped(path71) {
8294
+ const record = loadJson(REGISTRY_FILE)[path71];
8295
+ return record ? { clone: record.clone, origin: record.origin } : void 0;
8296
+ }
8297
+ function recordWorktree(path71, clone, origin) {
8298
+ const data = loadJson(REGISTRY_FILE);
8299
+ data[path71] = { clone, origin };
8300
+ saveJson(REGISTRY_FILE, data);
8301
+ }
8302
+ function forgetWorktree(path71) {
8303
+ const data = loadJson(REGISTRY_FILE);
8304
+ const record = data[path71];
8305
+ if (!record || record.reaped) return;
8306
+ data[path71] = { ...record, reaped: true };
8307
+ saveJson(REGISTRY_FILE, data);
8308
+ }
8309
+
8310
+ // src/commands/sessions/daemon/repoGroupForCwd.ts
8311
+ var cache2 = /* @__PURE__ */ new Map();
8312
+ function repoGroupForCwd(cwd) {
8313
+ if (!cwd) return void 0;
8314
+ if (cache2.has(cwd)) return cache2.get(cwd);
8315
+ const group = resolveRepoGroup(cwd);
8316
+ cache2.set(cwd, group);
8317
+ return group;
8318
+ }
8319
+ function resolveRepoGroup(cwd) {
8320
+ const live = groupFromLiveTree(cwd);
8321
+ if (live) return live;
8322
+ const reaped = worktreeAttributionIncludingReaped(cwd);
8323
+ return reaped && hostedGroup(cwd, reaped.origin, reaped.clone);
8324
+ }
8325
+ function groupFromLiveTree(cwd) {
8326
+ const clone = mainWorktree(cwd);
8327
+ const origin = clone ? originForCwd(clone) : void 0;
8328
+ return clone && origin ? hostedGroup(cwd, origin, clone) : void 0;
8329
+ }
8330
+ function hostedGroup(cwd, origin, clone) {
8331
+ return { origin: isWindowsCwd(cwd) ? `windows:${origin}` : origin, clone };
8332
+ }
8333
+
8101
8334
  // src/shared/createBundleHandler.ts
8102
8335
  import { createHash } from "crypto";
8103
- import { readFileSync as readFileSync18, statSync as statSync2 } from "fs";
8104
- import { dirname as dirname19, join as join22 } from "path";
8336
+ import { readFileSync as readFileSync19, statSync as statSync2 } from "fs";
8337
+ import { dirname as dirname19, join as join23 } from "path";
8105
8338
  import { fileURLToPath as fileURLToPath4 } from "url";
8106
8339
  function createBundleHandler(importMetaUrl, bundlePath, contentType = "application/javascript") {
8107
- const file = join22(dirname19(fileURLToPath4(importMetaUrl)), bundlePath);
8108
- let cache2;
8340
+ const file = join23(dirname19(fileURLToPath4(importMetaUrl)), bundlePath);
8341
+ let cache3;
8109
8342
  return (req, res) => {
8110
8343
  const mtimeMs = statSync2(file).mtimeMs;
8111
- if (cache2?.mtimeMs !== mtimeMs) {
8112
- const body = readFileSync18(file, "utf8");
8344
+ if (cache3?.mtimeMs !== mtimeMs) {
8345
+ const body = readFileSync19(file, "utf8");
8113
8346
  const etag = `"${createHash("sha256").update(body).digest("hex").slice(0, 16)}"`;
8114
- cache2 = { body, etag, mtimeMs };
8347
+ cache3 = { body, etag, mtimeMs };
8115
8348
  }
8116
8349
  const headers = {
8117
- ETag: cache2.etag,
8350
+ ETag: cache3.etag,
8118
8351
  "Cache-Control": "no-cache"
8119
8352
  };
8120
- if (req.headers["if-none-match"] === cache2.etag) {
8353
+ if (req.headers["if-none-match"] === cache3.etag) {
8121
8354
  res.writeHead(304, headers);
8122
8355
  res.end();
8123
8356
  return;
@@ -8126,7 +8359,7 @@ function createBundleHandler(importMetaUrl, bundlePath, contentType = "applicati
8126
8359
  "Content-Type": contentType,
8127
8360
  ...headers
8128
8361
  });
8129
- res.end(cache2.body);
8362
+ res.end(cache3.body);
8130
8363
  };
8131
8364
  }
8132
8365
 
@@ -8238,15 +8471,15 @@ async function loadItemSummaries(orm, origin) {
8238
8471
  }
8239
8472
 
8240
8473
  // src/commands/backlog/resolveRepoLocation.ts
8241
- import { existsSync as existsSync25 } from "fs";
8474
+ import { existsSync as existsSync26 } from "fs";
8242
8475
 
8243
8476
  // src/commands/backlog/cloneTargetDir.ts
8244
- import { join as join23, resolve as resolve8 } from "path";
8477
+ import { join as join24, resolve as resolve8 } from "path";
8245
8478
  function cloneTargetDir(origin, baseDir) {
8246
8479
  if (origin.startsWith("local:")) return null;
8247
8480
  const repoName = origin.split("/").filter(Boolean).pop();
8248
8481
  if (!repoName) return null;
8249
- return resolve8(join23(baseDir, repoName));
8482
+ return resolve8(join24(baseDir, repoName));
8250
8483
  }
8251
8484
 
8252
8485
  // src/commands/backlog/resolveRepoLocation.ts
@@ -8254,7 +8487,7 @@ function resolveRepoLocation(origin, knownCwd, baseDir) {
8254
8487
  if (knownCwd) return { cwd: knownCwd };
8255
8488
  const target = cloneTargetDir(origin, baseDir);
8256
8489
  if (!target) return {};
8257
- if (existsSync25(target) && getCurrentOrigin(target) === origin)
8490
+ if (existsSync26(target) && getCurrentOrigin(target) === origin)
8258
8491
  return { cwd: target };
8259
8492
  return { cloneTarget: target };
8260
8493
  }
@@ -8582,9 +8815,9 @@ async function handleItemRoute(req, res, pathname) {
8582
8815
  }
8583
8816
 
8584
8817
  // src/commands/sessions/web/execGit.ts
8585
- import { execFile as execFile2 } from "child_process";
8818
+ import { execFile as execFile3 } from "child_process";
8586
8819
  import { promisify as promisify2 } from "util";
8587
- var execFileAsync2 = promisify2(execFile2);
8820
+ var execFileAsync2 = promisify2(execFile3);
8588
8821
  async function execGit(cwd, args, opts = {}) {
8589
8822
  const { maxBuffer, allowFailure } = opts;
8590
8823
  const { file, argv } = /^[A-Za-z]:[\\/]/.test(cwd) ? { file: "git.exe", argv: ["-C", cwd, ...args] } : { file: "git", argv: args };
@@ -8719,6 +8952,39 @@ async function getBackups(_req, res) {
8719
8952
  respondJson(res, 200, await listBackups(await getDb()));
8720
8953
  }
8721
8954
 
8955
+ // src/commands/config/getNestedValue.ts
8956
+ function isTraversable(value) {
8957
+ return value !== null && value !== void 0 && typeof value === "object";
8958
+ }
8959
+ function stepInto(current, key) {
8960
+ return isTraversable(current) ? current[key] : void 0;
8961
+ }
8962
+ function getNestedValue(obj, path71) {
8963
+ let current = obj;
8964
+ for (const key of path71.split(".")) current = stepInto(current, key);
8965
+ return current;
8966
+ }
8967
+
8968
+ // src/commands/config/readConfigEntries.ts
8969
+ var KEYS_STRIPPED_FROM_MERGED_CONFIG = /* @__PURE__ */ new Set(["repos"]);
8970
+ function readConfigEntries(cwd) {
8971
+ const config = loadConfigFrom(cwd);
8972
+ return describeConfigLeaves(assistConfigSchema).filter((leaf) => !KEYS_STRIPPED_FROM_MERGED_CONFIG.has(leaf.key)).map((leaf) => ({ ...leaf, value: getNestedValue(config, leaf.key) }));
8973
+ }
8974
+
8975
+ // src/commands/sessions/web/getConfig.ts
8976
+ function getConfig(req, res) {
8977
+ const cwd = getCwdParam(req, res);
8978
+ if (!cwd) return;
8979
+ try {
8980
+ respondJson(res, 200, readConfigEntries(cwd));
8981
+ } catch (error) {
8982
+ respondJson(res, 500, {
8983
+ error: error instanceof Error ? error.message : "Failed to read config"
8984
+ });
8985
+ }
8986
+ }
8987
+
8722
8988
  // src/commands/sessions/web/getHtml.ts
8723
8989
  function getHtml() {
8724
8990
  return `<!DOCTYPE html>
@@ -8768,26 +9034,26 @@ function handleServerRuns(req, res) {
8768
9034
  }
8769
9035
 
8770
9036
  // src/commands/sessions/web/getReviewSynthesis.ts
8771
- import { execFile as execFile3 } from "child_process";
8772
- import { readFileSync as readFileSync19 } from "fs";
8773
- import { homedir as homedir11 } from "os";
8774
- import { basename as basename6, join as join25 } from "path";
9037
+ import { execFile as execFile4 } from "child_process";
9038
+ import { readFileSync as readFileSync20 } from "fs";
9039
+ import { homedir as homedir12 } from "os";
9040
+ import { basename as basename6, join as join26 } from "path";
8775
9041
  import { promisify as promisify3 } from "util";
8776
9042
 
8777
9043
  // src/commands/sessions/web/findSynthesisForBranch.ts
8778
- import { existsSync as existsSync26, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
8779
- import { basename as basename5, dirname as dirname20, join as join24 } from "path";
9044
+ import { existsSync as existsSync27, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
9045
+ import { basename as basename5, dirname as dirname20, join as join25 } from "path";
8780
9046
  function findSynthesisForBranch(repoReviewsDir, branch2) {
8781
- const branchKeyPath = join24(repoReviewsDir, `${branch2}-`);
9047
+ const branchKeyPath = join25(repoReviewsDir, `${branch2}-`);
8782
9048
  const parent = dirname20(branchKeyPath);
8783
9049
  const branchPrefix = basename5(branchKeyPath);
8784
- if (!existsSync26(parent)) return null;
8785
- const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join24(parent, name, "synthesis.md")).filter((path71) => existsSync26(path71)).map((path71) => ({ path: path71, mtime: statSync3(path71).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
9050
+ if (!existsSync27(parent)) return null;
9051
+ const synthesisFiles = readdirSync2(parent).filter((name) => name.startsWith(branchPrefix)).map((name) => join25(parent, name, "synthesis.md")).filter((path71) => existsSync27(path71)).map((path71) => ({ path: path71, mtime: statSync3(path71).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
8786
9052
  return synthesisFiles[0]?.path ?? null;
8787
9053
  }
8788
9054
 
8789
9055
  // src/commands/sessions/web/getReviewSynthesis.ts
8790
- var execFileAsync3 = promisify3(execFile3);
9056
+ var execFileAsync3 = promisify3(execFile4);
8791
9057
  function runGit(cwd, args) {
8792
9058
  return execFileAsync3("git", args, {
8793
9059
  encoding: "utf8",
@@ -8799,8 +9065,8 @@ async function resolveSynthesisPath(cwd) {
8799
9065
  runGit(cwd, ["rev-parse", "--show-toplevel"]),
8800
9066
  runGit(cwd, ["rev-parse", "--abbrev-ref", "HEAD"])
8801
9067
  ]);
8802
- const repoReviewsDir = join25(
8803
- homedir11(),
9068
+ const repoReviewsDir = join26(
9069
+ homedir12(),
8804
9070
  ".assist",
8805
9071
  "reviews",
8806
9072
  basename6(repoRoot)
@@ -8816,7 +9082,7 @@ async function getReviewSynthesis(req, res) {
8816
9082
  respondJson(res, 404, { error: "No synthesis found" });
8817
9083
  return;
8818
9084
  }
8819
- respondJson(res, 200, { synthesis: readFileSync19(path71, "utf8") });
9085
+ respondJson(res, 200, { synthesis: readFileSync20(path71, "utf8") });
8820
9086
  } catch {
8821
9087
  respondJson(res, 404, { error: "No synthesis found" });
8822
9088
  }
@@ -8944,35 +9210,6 @@ function harnessCapabilities(_req, res) {
8944
9210
  respondJson(res, 200, { exposeCodexActions, exposePiActions });
8945
9211
  }
8946
9212
 
8947
- // src/shared/loadJson.ts
8948
- import { existsSync as existsSync27, mkdirSync as mkdirSync11, readFileSync as readFileSync20, writeFileSync as writeFileSync20 } from "fs";
8949
- import { homedir as homedir13 } from "os";
8950
- import { join as join27 } from "path";
8951
- function getStoreDir() {
8952
- return join27(homedir13(), ".assist");
8953
- }
8954
- function getStorePath(filename) {
8955
- return join27(getStoreDir(), filename);
8956
- }
8957
- function loadJson(filename) {
8958
- const path71 = getStorePath(filename);
8959
- if (existsSync27(path71)) {
8960
- try {
8961
- return JSON.parse(readFileSync20(path71, "utf8"));
8962
- } catch {
8963
- return {};
8964
- }
8965
- }
8966
- return {};
8967
- }
8968
- function saveJson(filename, data) {
8969
- const dir = getStoreDir();
8970
- if (!existsSync27(dir)) {
8971
- mkdirSync11(dir, { recursive: true });
8972
- }
8973
- writeFileSync20(getStorePath(filename), JSON.stringify(data, null, 2));
8974
- }
8975
-
8976
9213
  // src/commands/sessions/web/jiraSite.ts
8977
9214
  function jiraSite(_req, res) {
8978
9215
  const config = loadJson("jira.json");
@@ -9251,17 +9488,17 @@ async function openInCode(req, res) {
9251
9488
  }
9252
9489
 
9253
9490
  // src/commands/sessions/web/createCachedGhJson.ts
9254
- import { execFile as execFile4 } from "child_process";
9491
+ import { execFile as execFile5 } from "child_process";
9255
9492
  import { promisify as promisify5 } from "util";
9256
- var execFileAsync4 = promisify5(execFile4);
9493
+ var execFileAsync4 = promisify5(execFile5);
9257
9494
  var CACHE_TTL_MS2 = 3e4;
9258
9495
  function createCachedGhJson(args, parse3, fallback, options2 = {}) {
9259
9496
  const { cacheFallback = true } = options2;
9260
- const cache2 = /* @__PURE__ */ new Map();
9497
+ const cache3 = /* @__PURE__ */ new Map();
9261
9498
  return async (cwd, extraArgs = []) => {
9262
9499
  const key = extraArgs.length ? `${cwd}\0${extraArgs.join("\0")}` : cwd;
9263
9500
  const now = Date.now();
9264
- const cached = cache2.get(key);
9501
+ const cached = cache3.get(key);
9265
9502
  if (cached && cached.expires > now) return cached.value;
9266
9503
  let value = fallback;
9267
9504
  try {
@@ -9274,7 +9511,7 @@ function createCachedGhJson(args, parse3, fallback, options2 = {}) {
9274
9511
  value = fallback;
9275
9512
  }
9276
9513
  if (cacheFallback || value !== fallback)
9277
- cache2.set(key, { value, expires: now + CACHE_TTL_MS2 });
9514
+ cache3.set(key, { value, expires: now + CACHE_TTL_MS2 });
9278
9515
  return value;
9279
9516
  };
9280
9517
  }
@@ -9309,9 +9546,9 @@ async function prList(req, res) {
9309
9546
  }
9310
9547
 
9311
9548
  // src/commands/sessions/web/prStatus.ts
9312
- import { execFile as execFile5 } from "child_process";
9549
+ import { execFile as execFile6 } from "child_process";
9313
9550
  import { promisify as promisify6 } from "util";
9314
- var execFileAsync5 = promisify6(execFile5);
9551
+ var execFileAsync5 = promisify6(execFile6);
9315
9552
  function toPrSummary(parsed) {
9316
9553
  if (typeof parsed.number !== "number") return null;
9317
9554
  return {
@@ -9468,13 +9705,198 @@ async function restartWeb(req, res, deps2 = {}) {
9468
9705
  }
9469
9706
  }
9470
9707
 
9708
+ // src/commands/config/setNestedValue.ts
9709
+ function isPlainObject(val) {
9710
+ return val !== null && typeof val === "object" && !Array.isArray(val);
9711
+ }
9712
+ function isNumericKey(key) {
9713
+ return /^\d+$/.test(key);
9714
+ }
9715
+ function resolveKey(key) {
9716
+ return isNumericKey(key) ? Number.parseInt(key, 10) : key;
9717
+ }
9718
+ function getItem(container, key) {
9719
+ if (Array.isArray(container)) return container[key];
9720
+ return container[key];
9721
+ }
9722
+ function setItem(container, key, value) {
9723
+ if (Array.isArray(container)) container[key] = value;
9724
+ else container[key] = value;
9725
+ }
9726
+ function ensureArray(container, key) {
9727
+ const existing = getItem(container, key);
9728
+ const arr = Array.isArray(existing) ? [...existing] : [];
9729
+ setItem(container, key, arr);
9730
+ return arr;
9731
+ }
9732
+ function ensureObject(container, key) {
9733
+ const existing = getItem(container, key);
9734
+ const obj = isPlainObject(existing) ? { ...existing } : {};
9735
+ setItem(container, key, obj);
9736
+ return obj;
9737
+ }
9738
+ function stepIntoNested(container, key, nextKey) {
9739
+ const resolved = resolveKey(key);
9740
+ if (nextKey !== void 0 && isNumericKey(nextKey)) {
9741
+ return ensureArray(container, resolved);
9742
+ }
9743
+ return ensureObject(container, resolved);
9744
+ }
9745
+ function setNestedValue(obj, path71, value) {
9746
+ const keys = path71.split(".");
9747
+ const result = { ...obj };
9748
+ let current = result;
9749
+ for (let i = 0; i < keys.length - 1; i++) {
9750
+ current = stepIntoNested(current, keys[i], keys[i + 1]);
9751
+ }
9752
+ setItem(current, resolveKey(keys[keys.length - 1]), value);
9753
+ return result;
9754
+ }
9755
+
9756
+ // src/commands/config/validateConfig.ts
9757
+ function validateConfig(updated, key) {
9758
+ const result = assistConfigSchema.safeParse(updated);
9759
+ if (result.success) return { ok: true };
9760
+ return {
9761
+ ok: false,
9762
+ errors: result.error.issues.map((issue) => formatIssue(issue, key))
9763
+ };
9764
+ }
9765
+ function formatIssue(issue, key) {
9766
+ const path71 = issue.path.length > 0 ? issue.path.join(".") : key;
9767
+ return `${path71}: ${issue.message}`;
9768
+ }
9769
+
9770
+ // src/commands/config/applyConfigSet.ts
9771
+ var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
9772
+ function applyConfigSet(key, coerced, global, cwd = process.cwd()) {
9773
+ if (!global && isGlobalOnly(key)) {
9774
+ return {
9775
+ ok: false,
9776
+ errors: [
9777
+ `"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
9778
+ ]
9779
+ };
9780
+ }
9781
+ const raw = global ? loadGlobalConfigRaw() : loadProjectConfig(cwd);
9782
+ const updated = setNestedValue(raw, key, coerced);
9783
+ const validation = validateConfig(updated, key);
9784
+ if (!validation.ok) return validation;
9785
+ if (global) {
9786
+ saveGlobalConfig(updated);
9787
+ return { ok: true, target: "global" };
9788
+ }
9789
+ saveConfig(updated, cwd);
9790
+ return { ok: true, target: "project" };
9791
+ }
9792
+ function isGlobalOnly(key) {
9793
+ return GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k));
9794
+ }
9795
+
9796
+ // src/commands/config/coerceConfigValue.ts
9797
+ var EDITABLE_TYPES = /* @__PURE__ */ new Set(["string", "number", "boolean", "enum"]);
9798
+ function coerceConfigValue(key, raw) {
9799
+ const leaf = describeConfigLeaves(assistConfigSchema).find(
9800
+ (candidate) => candidate.key === key
9801
+ );
9802
+ if (!leaf) return { ok: false, error: `Unknown config key "${key}"` };
9803
+ if (!EDITABLE_TYPES.has(leaf.type)) {
9804
+ return {
9805
+ ok: false,
9806
+ error: `"${key}" is a ${leaf.type} value and is read-only here`
9807
+ };
9808
+ }
9809
+ if (leaf.type === "boolean") return coerceBoolean(key, raw);
9810
+ if (leaf.type === "number") return coerceNumber(key, raw);
9811
+ return coerceString(key, raw);
9812
+ }
9813
+ function coerceBoolean(key, raw) {
9814
+ if (typeof raw === "boolean") return { ok: true, value: raw };
9815
+ if (raw === "true") return { ok: true, value: true };
9816
+ if (raw === "false") return { ok: true, value: false };
9817
+ return { ok: false, error: `${key}: expected a boolean` };
9818
+ }
9819
+ function coerceNumber(key, raw) {
9820
+ if (typeof raw === "number" && Number.isFinite(raw)) {
9821
+ return { ok: true, value: raw };
9822
+ }
9823
+ if (typeof raw === "string" && raw.trim() !== "") {
9824
+ const parsed = Number(raw);
9825
+ if (Number.isFinite(parsed)) return { ok: true, value: parsed };
9826
+ }
9827
+ return { ok: false, error: `${key}: expected a number` };
9828
+ }
9829
+ function coerceString(key, raw) {
9830
+ if (typeof raw === "string") return { ok: true, value: raw };
9831
+ return { ok: false, error: `${key}: expected a string` };
9832
+ }
9833
+
9834
+ // src/commands/sessions/web/readJsonBody.ts
9835
+ async function readJsonBody(req) {
9836
+ const chunks = [];
9837
+ for await (const chunk of req) chunks.push(chunk);
9838
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
9839
+ }
9840
+
9841
+ // src/commands/sessions/web/parseSetConfigRequest.ts
9842
+ async function parseSetConfigRequest(req) {
9843
+ let body;
9844
+ try {
9845
+ body = await readJsonBody(req);
9846
+ } catch {
9847
+ return { ok: false, error: "Invalid JSON body" };
9848
+ }
9849
+ const { key, cwd, scope } = body;
9850
+ if (typeof key !== "string" || key === "")
9851
+ return { ok: false, error: "Missing key" };
9852
+ if (typeof cwd !== "string" || cwd === "")
9853
+ return { ok: false, error: "Missing cwd" };
9854
+ if (scope !== "project" && scope !== "global")
9855
+ return { ok: false, error: 'scope must be "project" or "global"' };
9856
+ return { ok: true, key, value: body.value, cwd, global: scope === "global" };
9857
+ }
9858
+
9859
+ // src/commands/sessions/web/setConfig.ts
9860
+ async function setConfig(req, res) {
9861
+ const parsed = await parseSetConfigRequest(req);
9862
+ if (!parsed.ok) {
9863
+ respondJson(res, 400, { error: parsed.error });
9864
+ return;
9865
+ }
9866
+ const coerced = coerceConfigValue(parsed.key, parsed.value);
9867
+ if (!coerced.ok) {
9868
+ respondJson(res, 400, { error: coerced.error, errors: [coerced.error] });
9869
+ return;
9870
+ }
9871
+ try {
9872
+ const result = applyConfigSet(
9873
+ parsed.key,
9874
+ coerced.value,
9875
+ parsed.global,
9876
+ parsed.cwd
9877
+ );
9878
+ if (!result.ok) {
9879
+ respondJson(res, 400, {
9880
+ error: result.errors.join("\n"),
9881
+ errors: result.errors
9882
+ });
9883
+ return;
9884
+ }
9885
+ respondJson(res, 200, { target: result.target });
9886
+ } catch (error) {
9887
+ respondJson(res, 500, {
9888
+ error: error instanceof Error ? error.message : "Failed to save config"
9889
+ });
9890
+ }
9891
+ }
9892
+
9471
9893
  // src/commands/sessions/web/uploadPrImage.ts
9472
9894
  import { rm } from "fs/promises";
9473
9895
 
9474
9896
  // src/commands/sessions/web/runGhImage.ts
9475
- import { execFile as execFile6 } from "child_process";
9897
+ import { execFile as execFile7 } from "child_process";
9476
9898
  import { promisify as promisify7 } from "util";
9477
- var execFileAsync6 = promisify7(execFile6);
9899
+ var execFileAsync6 = promisify7(execFile7);
9478
9900
  var GhImageUnavailableError = class extends Error {
9479
9901
  name = "GhImageUnavailableError";
9480
9902
  };
@@ -9600,22 +10022,22 @@ import { readFileSync as readFileSync21 } from "fs";
9600
10022
  import { createRequire as createRequire2 } from "module";
9601
10023
  var require3 = createRequire2(import.meta.url);
9602
10024
  function createCssHandler(packageEntry) {
9603
- let cache2;
10025
+ let cache3;
9604
10026
  return (req, res) => {
9605
- if (!cache2) {
10027
+ if (!cache3) {
9606
10028
  const resolved = require3.resolve(packageEntry);
9607
10029
  const body = readFileSync21(resolved, "utf8");
9608
10030
  const etag = `"${createHash2("sha256").update(body).digest("hex").slice(0, 16)}"`;
9609
- cache2 = { body, etag };
10031
+ cache3 = { body, etag };
9610
10032
  }
9611
- const headers = { ETag: cache2.etag, "Cache-Control": "no-cache" };
9612
- if (req.headers["if-none-match"] === cache2.etag) {
10033
+ const headers = { ETag: cache3.etag, "Cache-Control": "no-cache" };
10034
+ if (req.headers["if-none-match"] === cache3.etag) {
9613
10035
  res.writeHead(304, headers);
9614
10036
  res.end();
9615
10037
  return;
9616
10038
  }
9617
10039
  res.writeHead(200, { "Content-Type": "text/css", ...headers });
9618
- res.end(cache2.body);
10040
+ res.end(cache3.body);
9619
10041
  };
9620
10042
  }
9621
10043
 
@@ -9651,6 +10073,8 @@ var routes2 = {
9651
10073
  "GET /api/news/items": listNewsItems,
9652
10074
  "GET /api/usage/history": listUsageHistory,
9653
10075
  "GET /api/backups/list": getBackups,
10076
+ "GET /api/config": getConfig,
10077
+ "POST /api/config/set": setConfig,
9654
10078
  "GET /api/review/synthesis": getReviewSynthesis
9655
10079
  };
9656
10080
  var handleRequest = createFallbackHandler(
@@ -9992,6 +10416,9 @@ function scheduleReconnect() {
9992
10416
  }
9993
10417
 
9994
10418
  // src/commands/sessions/web/index.ts
10419
+ function repoEntryCwd(serverCwd) {
10420
+ return repoGroupForCwd(serverCwd)?.clone ?? serverCwd;
10421
+ }
9995
10422
  async function web(options2) {
9996
10423
  const port = Number.parseInt(options2.port, 10);
9997
10424
  const server = startWebServer(
@@ -10004,7 +10431,7 @@ async function web(options2) {
10004
10431
  const serverCwd = process.cwd();
10005
10432
  const ctx = {
10006
10433
  serverCwd,
10007
- repoCwd: isGitRepo(serverCwd) ? serverCwd : void 0
10434
+ repoCwd: isGitRepo(serverCwd) ? repoEntryCwd(serverCwd) : void 0
10008
10435
  };
10009
10436
  const wss = new WebSocketServer({ noServer: true });
10010
10437
  server.on("upgrade", (req, socket, head) => {
@@ -14296,7 +14723,7 @@ function formatResultLine(entry, failing) {
14296
14723
  // src/commands/complexity/maintainability/getMaintainabilityGitState.ts
14297
14724
  import { execSync as execSync32 } from "child_process";
14298
14725
  import path28 from "path";
14299
- function git2(command) {
14726
+ function git3(command) {
14300
14727
  return execSync32(command, { encoding: "utf8" });
14301
14728
  }
14302
14729
  function toAbsolute(root, repoRelative) {
@@ -14304,7 +14731,7 @@ function toAbsolute(root, repoRelative) {
14304
14731
  }
14305
14732
  function collectShrunkFiles(root) {
14306
14733
  const shrunk = /* @__PURE__ */ new Set();
14307
- const numstat = git2("git diff --numstat HEAD").trim();
14734
+ const numstat = git3("git diff --numstat HEAD").trim();
14308
14735
  if (numstat === "") return shrunk;
14309
14736
  for (const line of numstat.split("\n")) {
14310
14737
  const [addedRaw, removedRaw, ...rest] = line.split(" ");
@@ -14317,7 +14744,7 @@ function collectShrunkFiles(root) {
14317
14744
  return shrunk;
14318
14745
  }
14319
14746
  function hasNewSourceFile() {
14320
- const status3 = git2("git status --porcelain --untracked-files=all").trim();
14747
+ const status3 = git3("git status --porcelain --untracked-files=all").trim();
14321
14748
  if (status3 === "") return false;
14322
14749
  for (const line of status3.split("\n")) {
14323
14750
  const code = line.slice(0, 2);
@@ -14329,7 +14756,7 @@ function hasNewSourceFile() {
14329
14756
  }
14330
14757
  function getMaintainabilityGitState() {
14331
14758
  try {
14332
- const root = git2("git rev-parse --show-toplevel").trim();
14759
+ const root = git3("git rev-parse --show-toplevel").trim();
14333
14760
  return {
14334
14761
  shrunkFiles: collectShrunkFiles(root),
14335
14762
  newFileCreated: hasNewSourceFile()
@@ -14525,21 +14952,6 @@ function configList() {
14525
14952
 
14526
14953
  // src/commands/config/configGet.ts
14527
14954
  import chalk127 from "chalk";
14528
-
14529
- // src/commands/config/getNestedValue.ts
14530
- function isTraversable(value) {
14531
- return value !== null && value !== void 0 && typeof value === "object";
14532
- }
14533
- function stepInto(current, key) {
14534
- return isTraversable(current) ? current[key] : void 0;
14535
- }
14536
- function getNestedValue(obj, path71) {
14537
- let current = obj;
14538
- for (const key of path71.split(".")) current = stepInto(current, key);
14539
- return current;
14540
- }
14541
-
14542
- // src/commands/config/configGet.ts
14543
14955
  function configGet(key) {
14544
14956
  console.log(
14545
14957
  formatOutput(
@@ -14561,106 +14973,8 @@ function exitKeyNotSet(key) {
14561
14973
  }
14562
14974
 
14563
14975
  // src/commands/config/configSet.ts
14564
- import chalk130 from "chalk";
14565
-
14566
- // src/commands/config/applyConfigSet.ts
14567
14976
  import chalk129 from "chalk";
14568
14977
 
14569
- // src/commands/config/setNestedValue.ts
14570
- function isPlainObject(val) {
14571
- return val !== null && typeof val === "object" && !Array.isArray(val);
14572
- }
14573
- function isNumericKey(key) {
14574
- return /^\d+$/.test(key);
14575
- }
14576
- function resolveKey(key) {
14577
- return isNumericKey(key) ? Number.parseInt(key, 10) : key;
14578
- }
14579
- function getItem(container, key) {
14580
- if (Array.isArray(container)) return container[key];
14581
- return container[key];
14582
- }
14583
- function setItem(container, key, value) {
14584
- if (Array.isArray(container)) container[key] = value;
14585
- else container[key] = value;
14586
- }
14587
- function ensureArray(container, key) {
14588
- const existing = getItem(container, key);
14589
- const arr = Array.isArray(existing) ? [...existing] : [];
14590
- setItem(container, key, arr);
14591
- return arr;
14592
- }
14593
- function ensureObject(container, key) {
14594
- const existing = getItem(container, key);
14595
- const obj = isPlainObject(existing) ? { ...existing } : {};
14596
- setItem(container, key, obj);
14597
- return obj;
14598
- }
14599
- function stepIntoNested(container, key, nextKey) {
14600
- const resolved = resolveKey(key);
14601
- if (nextKey !== void 0 && isNumericKey(nextKey)) {
14602
- return ensureArray(container, resolved);
14603
- }
14604
- return ensureObject(container, resolved);
14605
- }
14606
- function setNestedValue(obj, path71, value) {
14607
- const keys = path71.split(".");
14608
- const result = { ...obj };
14609
- let current = result;
14610
- for (let i = 0; i < keys.length - 1; i++) {
14611
- current = stepIntoNested(current, keys[i], keys[i + 1]);
14612
- }
14613
- setItem(current, resolveKey(keys[keys.length - 1]), value);
14614
- return result;
14615
- }
14616
-
14617
- // src/commands/config/validateConfig.ts
14618
- import chalk128 from "chalk";
14619
- function validateConfig(updated, key) {
14620
- const result = assistConfigSchema.safeParse(updated);
14621
- if (!result.success) return exitValidationFailed(result.error.issues, key);
14622
- return updated;
14623
- }
14624
- function exitValidationFailed(issues, key) {
14625
- printValidationErrors(issues, key);
14626
- process.exit(1);
14627
- }
14628
- function printValidationErrors(issues, key) {
14629
- for (const issue of issues) {
14630
- console.error(
14631
- chalk128.red(`${formatIssuePath(issue, key)}: ${issue.message}`)
14632
- );
14633
- }
14634
- }
14635
- function formatIssuePath(issue, key) {
14636
- return issue.path.length > 0 ? issue.path.join(".") : key;
14637
- }
14638
-
14639
- // src/commands/config/applyConfigSet.ts
14640
- var GLOBAL_ONLY_KEYS = ["sync.autoConfirm"];
14641
- function applyConfigSet(key, coerced, global) {
14642
- assertNotGlobalOnly(key, global);
14643
- const raw = global ? loadGlobalConfigRaw() : loadProjectConfig();
14644
- const updated = setNestedValue(raw, key, coerced);
14645
- validateConfig(updated, key);
14646
- if (global) {
14647
- saveGlobalConfig(updated);
14648
- return "global";
14649
- }
14650
- saveConfig(updated);
14651
- return "project";
14652
- }
14653
- function assertNotGlobalOnly(key, global) {
14654
- if (!global && GLOBAL_ONLY_KEYS.some((k) => key.startsWith(k))) {
14655
- console.error(
14656
- chalk129.red(
14657
- `"${key}" is a global-only key. Use --global to set it in ~/.assist.yml`
14658
- )
14659
- );
14660
- process.exit(1);
14661
- }
14662
- }
14663
-
14664
14978
  // src/shared/resolveNamedRepoWriteLabel.ts
14665
14979
  var UnknownRepoConfigError = class extends Error {
14666
14980
  name = "UnknownRepoConfigError";
@@ -14683,6 +14997,13 @@ function resolveNamedRepoWriteLabel(globalRaw, name) {
14683
14997
  return matches[0];
14684
14998
  }
14685
14999
 
15000
+ // src/commands/config/exitWithConfigErrors.ts
15001
+ import chalk128 from "chalk";
15002
+ function exitWithConfigErrors(errors) {
15003
+ for (const error of errors) console.error(chalk128.red(error));
15004
+ process.exit(1);
15005
+ }
15006
+
14686
15007
  // src/commands/config/applyRepoConfigSet.ts
14687
15008
  function applyRepoConfigSet(key, coerced, repoName) {
14688
15009
  const globalRaw = loadGlobalConfigRaw();
@@ -14690,7 +15011,8 @@ function applyRepoConfigSet(key, coerced, repoName) {
14690
15011
  const repos2 = isPlainObject2(globalRaw.repos) ? { ...globalRaw.repos } : {};
14691
15012
  const existingBlock = isPlainObject2(repos2[label2]) ? repos2[label2] : {};
14692
15013
  const updatedBlock = setNestedValue(existingBlock, key, coerced);
14693
- validateConfig(updatedBlock, key);
15014
+ const validation = validateConfig(updatedBlock, key);
15015
+ if (!validation.ok) exitWithConfigErrors(validation.errors);
14694
15016
  repos2[label2] = updatedBlock;
14695
15017
  saveGlobalConfig({ ...globalRaw, repos: repos2 });
14696
15018
  return label2;
@@ -14714,21 +15036,26 @@ function resolveRepoTarget(key, value, repo) {
14714
15036
  function configSet(key, value, options2 = {}) {
14715
15037
  if (options2.repo !== void 0 && !options2.global) {
14716
15038
  console.error(
14717
- chalk130.red("--repo writes to the global config; add -g (e.g. -g --repo)")
15039
+ chalk129.red("--repo writes to the global config; add -g (e.g. -g --repo)")
14718
15040
  );
14719
15041
  process.exit(1);
14720
15042
  }
14721
15043
  const resolved = resolveRepoTarget(key, value, options2.repo);
14722
15044
  if (resolved.value === void 0) {
14723
- console.error(chalk130.red(`Missing required argument for '${resolved.key}'`));
15045
+ console.error(chalk129.red(`Missing required argument for '${resolved.key}'`));
14724
15046
  process.exit(1);
14725
15047
  }
14726
15048
  const coerced = coerceValue(resolved.value);
14727
- const target = resolved.useRepo ? `repo: ${applyRepoConfigSet(resolved.key, coerced, resolved.repoName)}` : applyConfigSet(resolved.key, coerced, options2.global ?? false);
15049
+ const target = resolved.useRepo ? `repo: ${applyRepoConfigSet(resolved.key, coerced, resolved.repoName)}` : applyOrExit(resolved.key, coerced, options2.global ?? false);
14728
15050
  console.log(
14729
- chalk130.green(`Set ${resolved.key} = ${JSON.stringify(coerced)} (${target})`)
15051
+ chalk129.green(`Set ${resolved.key} = ${JSON.stringify(coerced)} (${target})`)
14730
15052
  );
14731
15053
  }
15054
+ function applyOrExit(key, coerced, global) {
15055
+ const result = applyConfigSet(key, coerced, global);
15056
+ if (!result.ok) exitWithConfigErrors(result.errors);
15057
+ return result.target;
15058
+ }
14732
15059
  function coerceValue(value) {
14733
15060
  if (value === "true") return true;
14734
15061
  if (value === "false") return false;
@@ -14747,40 +15074,40 @@ function registerConfig(program2) {
14747
15074
  }
14748
15075
 
14749
15076
  // src/commands/db/reportMigrationStatus.ts
14750
- import chalk131 from "chalk";
15077
+ import chalk130 from "chalk";
14751
15078
  function reportApplied(applied) {
14752
15079
  if (applied.length === 0) {
14753
- console.error(chalk131.green("Database is up to date; nothing to apply."));
15080
+ console.error(chalk130.green("Database is up to date; nothing to apply."));
14754
15081
  return;
14755
15082
  }
14756
15083
  for (const migration of applied) {
14757
15084
  console.error(
14758
- chalk131.green(`Applied migration ${migration.id} (${migration.name}).`)
15085
+ chalk130.green(`Applied migration ${migration.id} (${migration.name}).`)
14759
15086
  );
14760
15087
  }
14761
15088
  }
14762
15089
  function reportMigrationStatus(status3) {
14763
15090
  if (status3.state === "in-sync") {
14764
15091
  console.error(
14765
- chalk131.green(`In sync at migration ${status3.version} (latest).`)
15092
+ chalk130.green(`In sync at migration ${status3.version} (latest).`)
14766
15093
  );
14767
15094
  return;
14768
15095
  }
14769
15096
  if (status3.state === "behind") {
14770
15097
  console.error(
14771
- chalk131.yellow(
15098
+ chalk130.yellow(
14772
15099
  `Behind: applied ${status3.applied}, build expects ${status3.expected}.`
14773
15100
  )
14774
15101
  );
14775
15102
  console.error(
14776
- chalk131.yellow(
15103
+ chalk130.yellow(
14777
15104
  `Pending: ${status3.pending.join(", ")}. Run \`assist db migrate\`.`
14778
15105
  )
14779
15106
  );
14780
15107
  return;
14781
15108
  }
14782
15109
  console.error(
14783
- chalk131.red(
15110
+ chalk130.red(
14784
15111
  `Ahead: applied ${status3.applied}, build knows ${status3.expected}. Update assist.`
14785
15112
  )
14786
15113
  );
@@ -14815,7 +15142,7 @@ function registerDb(program2) {
14815
15142
 
14816
15143
  // src/commands/dbMigration/dbMigrationConfirm.ts
14817
15144
  import { unlinkSync as unlinkSync9, writeFileSync as writeFileSync26 } from "fs";
14818
- import chalk132 from "chalk";
15145
+ import chalk131 from "chalk";
14819
15146
 
14820
15147
  // src/commands/dbMigration/getMigrationPinPath.ts
14821
15148
  import { join as join35 } from "path";
@@ -14846,7 +15173,7 @@ function dbMigrationConfirm(pin) {
14846
15173
  sweepRestrictedDir();
14847
15174
  const state = readMigrationPinState(pin);
14848
15175
  if (!state) {
14849
- console.error(chalk132.red(`No pending migration unlock for pin: ${pin}`));
15176
+ console.error(chalk131.red(`No pending migration unlock for pin: ${pin}`));
14850
15177
  process.exitCode = 1;
14851
15178
  return;
14852
15179
  }
@@ -14856,7 +15183,7 @@ function dbMigrationConfirm(pin) {
14856
15183
  );
14857
15184
  unlinkSync9(getMigrationPinPath(pin));
14858
15185
  console.log(
14859
- chalk132.green(
15186
+ chalk131.green(
14860
15187
  `Approved creation of migration ${state.migrationId}. The next write of that migration module will be allowed once.`
14861
15188
  )
14862
15189
  );
@@ -14865,7 +15192,7 @@ function dbMigrationConfirm(pin) {
14865
15192
  // src/commands/dbMigration/dbMigrationUnlock.ts
14866
15193
  import { mkdirSync as mkdirSync15, writeFileSync as writeFileSync27 } from "fs";
14867
15194
  import { randomInt as randomInt2 } from "crypto";
14868
- import chalk133 from "chalk";
15195
+ import chalk132 from "chalk";
14869
15196
 
14870
15197
  // src/commands/dbMigration/nextMigrationId.ts
14871
15198
  function nextMigrationId() {
@@ -14880,7 +15207,7 @@ function dbMigrationUnlock() {
14880
15207
  sweepRestrictedDir();
14881
15208
  writeFileSync27(getMigrationPinPath(pin), JSON.stringify({ pin, migrationId }));
14882
15209
  console.error(
14883
- chalk133.yellow.bold(
15210
+ chalk132.yellow.bold(
14884
15211
  "THIS IS YOUR LAST CHANCE TO RECONSIDER BEFORE INVOLVING A HUMAN.\nRequesting this pin pages a real person to approve a new database migration.\nA schema change is hard to reverse once shipped. You had BETTER have confirmed\nthe change with the user and be certain this migration is genuinely necessary."
14885
15212
  )
14886
15213
  );
@@ -14890,7 +15217,7 @@ function dbMigrationUnlock() {
14890
15217
  });
14891
15218
  if (!delivered) {
14892
15219
  console.error(
14893
- chalk133.red(
15220
+ chalk132.red(
14894
15221
  "Could not deliver the confirmation pin via notification.\nThe migration cannot be approved until the notification channel works."
14895
15222
  )
14896
15223
  );
@@ -14900,7 +15227,7 @@ function dbMigrationUnlock() {
14900
15227
  console.log(
14901
15228
  `A confirmation pin was sent to your desktop notifications.
14902
15229
  To approve creating migration ${migrationId}, run:
14903
- ${chalk133.cyan(" assist db-migration confirm <PIN>")}
15230
+ ${chalk132.cyan(" assist db-migration confirm <PIN>")}
14904
15231
  using the pin from that notification.`
14905
15232
  );
14906
15233
  }
@@ -14920,7 +15247,7 @@ function registerDbMigration(parent) {
14920
15247
 
14921
15248
  // src/commands/deploy/redirect.ts
14922
15249
  import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync28 } from "fs";
14923
- import chalk134 from "chalk";
15250
+ import chalk133 from "chalk";
14924
15251
  var TRAILING_SLASH_SCRIPT = ` <script>
14925
15252
  if (!window.location.pathname.endsWith('/')) {
14926
15253
  window.location.href = \`\${window.location.pathname}/\${window.location.search}\${window.location.hash}\`;
@@ -14929,23 +15256,23 @@ var TRAILING_SLASH_SCRIPT = ` <script>
14929
15256
  function redirect() {
14930
15257
  const indexPath = "index.html";
14931
15258
  if (!existsSync35(indexPath)) {
14932
- console.log(chalk134.yellow("No index.html found"));
15259
+ console.log(chalk133.yellow("No index.html found"));
14933
15260
  return;
14934
15261
  }
14935
15262
  const content = readFileSync30(indexPath, "utf8");
14936
15263
  if (content.includes("window.location.pathname.endsWith('/')")) {
14937
- console.log(chalk134.dim("Trailing slash script already present"));
15264
+ console.log(chalk133.dim("Trailing slash script already present"));
14938
15265
  return;
14939
15266
  }
14940
15267
  const headCloseIndex = content.indexOf("</head>");
14941
15268
  if (headCloseIndex === -1) {
14942
- console.log(chalk134.red("Could not find </head> tag in index.html"));
15269
+ console.log(chalk133.red("Could not find </head> tag in index.html"));
14943
15270
  return;
14944
15271
  }
14945
15272
  const newContent = `${content.slice(0, headCloseIndex) + TRAILING_SLASH_SCRIPT}
14946
15273
  ${content.slice(headCloseIndex)}`;
14947
15274
  writeFileSync28(indexPath, newContent);
14948
- console.log(chalk134.green("Added trailing slash redirect to index.html"));
15275
+ console.log(chalk133.green("Added trailing slash redirect to index.html"));
14949
15276
  }
14950
15277
 
14951
15278
  // src/commands/registerDeploy.ts
@@ -14956,7 +15283,7 @@ function registerDeploy(program2) {
14956
15283
  }
14957
15284
 
14958
15285
  // src/commands/devlog/list/index.ts
14959
- import { execFileSync as execFileSync2 } from "child_process";
15286
+ import { execFileSync as execFileSync3 } from "child_process";
14960
15287
  import { basename as basename9 } from "path";
14961
15288
 
14962
15289
  // src/commands/devlog/loadBlogSkipDays.ts
@@ -14972,7 +15299,7 @@ function loadBlogSkipDays(repoName) {
14972
15299
 
14973
15300
  // src/commands/devlog/shared.ts
14974
15301
  import { execSync as execSync33 } from "child_process";
14975
- import chalk135 from "chalk";
15302
+ import chalk134 from "chalk";
14976
15303
 
14977
15304
  // src/shared/getRepoName.ts
14978
15305
  import { existsSync as existsSync36, readFileSync as readFileSync31 } from "fs";
@@ -15081,13 +15408,13 @@ function shouldIgnoreCommit(files, ignorePaths) {
15081
15408
  }
15082
15409
  function printCommitsWithFiles(commits2, ignore3, verbose) {
15083
15410
  for (const commit2 of commits2) {
15084
- console.log(` ${chalk135.yellow(commit2.hash)} ${commit2.message}`);
15411
+ console.log(` ${chalk134.yellow(commit2.hash)} ${commit2.message}`);
15085
15412
  if (verbose) {
15086
15413
  const visibleFiles = commit2.files.filter(
15087
15414
  (file) => !ignore3.some((p) => file.startsWith(p))
15088
15415
  );
15089
15416
  for (const file of visibleFiles) {
15090
- console.log(` ${chalk135.dim(file)}`);
15417
+ console.log(` ${chalk134.dim(file)}`);
15091
15418
  }
15092
15419
  }
15093
15420
  }
@@ -15112,15 +15439,15 @@ function parseGitLogCommits(output, ignore3, afterDate) {
15112
15439
  }
15113
15440
 
15114
15441
  // src/commands/devlog/list/printDateHeader.ts
15115
- import chalk136 from "chalk";
15442
+ import chalk135 from "chalk";
15116
15443
  function printDateHeader(date, isSkipped, entries) {
15117
15444
  if (isSkipped) {
15118
- console.log(`${chalk136.bold.blue(date)} ${chalk136.dim("skipped")}`);
15445
+ console.log(`${chalk135.bold.blue(date)} ${chalk135.dim("skipped")}`);
15119
15446
  } else if (entries && entries.length > 0) {
15120
- const entryInfo = entries.map((e) => `${chalk136.green(e.version)} ${e.title}`).join(" | ");
15121
- console.log(`${chalk136.bold.blue(date)} ${entryInfo}`);
15447
+ const entryInfo = entries.map((e) => `${chalk135.green(e.version)} ${e.title}`).join(" | ");
15448
+ console.log(`${chalk135.bold.blue(date)} ${entryInfo}`);
15122
15449
  } else {
15123
- console.log(`${chalk136.bold.blue(date)} ${chalk136.red("\u26A0 devlog missing")}`);
15450
+ console.log(`${chalk135.bold.blue(date)} ${chalk135.red("\u26A0 devlog missing")}`);
15124
15451
  }
15125
15452
  }
15126
15453
 
@@ -15136,7 +15463,7 @@ function list3(options2) {
15136
15463
  if (options2.reverse) args.push("--reverse");
15137
15464
  else args.push("-n", "500");
15138
15465
  args.push("--pretty=format:%ad|%h|%s", "--date=short");
15139
- const output = execFileSync2("git", args, { encoding: "utf8" });
15466
+ const output = execFileSync3("git", args, { encoding: "utf8" });
15140
15467
  const commitsByDate = parseGitLogCommits(output, ignore3);
15141
15468
  let dateCount = 0;
15142
15469
  let isFirst = true;
@@ -15159,7 +15486,7 @@ function list3(options2) {
15159
15486
  }
15160
15487
 
15161
15488
  // src/commands/devlog/getLastVersionInfo.ts
15162
- import { execFileSync as execFileSync3, execSync as execSync34 } from "child_process";
15489
+ import { execFileSync as execFileSync4, execSync as execSync34 } from "child_process";
15163
15490
  import semver from "semver";
15164
15491
  function getVersionAtCommit(hash) {
15165
15492
  try {
@@ -15178,7 +15505,7 @@ function stripToMinor(version2) {
15178
15505
  }
15179
15506
  function getLastVersionInfoFromGit() {
15180
15507
  try {
15181
- const output = execFileSync3(
15508
+ const output = execFileSync4(
15182
15509
  "git",
15183
15510
  ["log", "-1", "--pretty=format:%ad|%h", "--date=short"],
15184
15511
  {
@@ -15223,25 +15550,25 @@ function bumpVersion(version2, type) {
15223
15550
  }
15224
15551
 
15225
15552
  // src/commands/devlog/next/displayNextEntry/index.ts
15226
- import { execFileSync as execFileSync4 } from "child_process";
15227
- import chalk138 from "chalk";
15553
+ import { execFileSync as execFileSync5 } from "child_process";
15554
+ import chalk137 from "chalk";
15228
15555
 
15229
15556
  // src/commands/devlog/next/displayNextEntry/displayVersion.ts
15230
- import chalk137 from "chalk";
15557
+ import chalk136 from "chalk";
15231
15558
  function displayVersion(conventional, firstHash, patchVersion, minorVersion) {
15232
15559
  if (conventional && firstHash) {
15233
15560
  const version2 = getVersionAtCommit(firstHash);
15234
15561
  if (version2) {
15235
- console.log(`${chalk137.bold("version:")} ${stripToMinor(version2)}`);
15562
+ console.log(`${chalk136.bold("version:")} ${stripToMinor(version2)}`);
15236
15563
  } else {
15237
- console.log(`${chalk137.bold("version:")} ${chalk137.red("unknown")}`);
15564
+ console.log(`${chalk136.bold("version:")} ${chalk136.red("unknown")}`);
15238
15565
  }
15239
15566
  } else if (patchVersion && minorVersion) {
15240
15567
  console.log(
15241
- `${chalk137.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
15568
+ `${chalk136.bold("version:")} ${patchVersion} (patch) or ${minorVersion} (minor)`
15242
15569
  );
15243
15570
  } else {
15244
- console.log(`${chalk137.bold("version:")} v0.1 (initial)`);
15571
+ console.log(`${chalk136.bold("version:")} v0.1 (initial)`);
15245
15572
  }
15246
15573
  }
15247
15574
 
@@ -15257,7 +15584,7 @@ function findTargetDate(commitsByDate, skipDays) {
15257
15584
  return Array.from(commitsByDate.keys()).filter((d) => !skipDays.has(d)).sort()[0];
15258
15585
  }
15259
15586
  function fetchCommitsByDate(ignore3, lastDate) {
15260
- const output = execFileSync4(
15587
+ const output = execFileSync5(
15261
15588
  "git",
15262
15589
  ["log", "--pretty=format:%ad|%h|%s", "--date=short", "-n", "500"],
15263
15590
  { encoding: "utf8" }
@@ -15289,16 +15616,16 @@ function noCommitsMessage(hasLastInfo) {
15289
15616
  return hasLastInfo ? "No commits after last versioned entry" : "No commits found";
15290
15617
  }
15291
15618
  function logName(repoName) {
15292
- console.log(`${chalk138.bold("name:")} ${repoName}`);
15619
+ console.log(`${chalk137.bold("name:")} ${repoName}`);
15293
15620
  }
15294
15621
  function displayNextEntry(ctx, targetDate, commits2) {
15295
15622
  logName(ctx.repoName);
15296
15623
  printVersionInfo(ctx.config, ctx.lastInfo, commits2[0]?.hash);
15297
- console.log(chalk138.bold.blue(targetDate));
15624
+ console.log(chalk137.bold.blue(targetDate));
15298
15625
  printCommitsWithFiles(commits2, ctx.ignore, ctx.verbose);
15299
15626
  }
15300
15627
  function logNoCommits(lastInfo) {
15301
- console.log(chalk138.dim(noCommitsMessage(!!lastInfo)));
15628
+ console.log(chalk137.dim(noCommitsMessage(!!lastInfo)));
15302
15629
  }
15303
15630
 
15304
15631
  // src/commands/devlog/next/index.ts
@@ -15339,11 +15666,11 @@ function next2(options2) {
15339
15666
  import { execSync as execSync35 } from "child_process";
15340
15667
 
15341
15668
  // src/commands/devlog/repos/printReposTable.ts
15342
- import chalk139 from "chalk";
15669
+ import chalk138 from "chalk";
15343
15670
  function colorStatus(status3) {
15344
- if (status3 === "missing") return chalk139.red(status3);
15345
- if (status3 === "outdated") return chalk139.yellow(status3);
15346
- return chalk139.green(status3);
15671
+ if (status3 === "missing") return chalk138.red(status3);
15672
+ if (status3 === "outdated") return chalk138.yellow(status3);
15673
+ return chalk138.green(status3);
15347
15674
  }
15348
15675
  function formatRow(row, nameWidth) {
15349
15676
  const devlog = (row.lastDevlog ?? "-").padEnd(11);
@@ -15357,8 +15684,8 @@ function printReposTable(rows) {
15357
15684
  "Last Devlog".padEnd(11),
15358
15685
  "Status"
15359
15686
  ].join(" ");
15360
- console.log(chalk139.dim(header));
15361
- console.log(chalk139.dim("-".repeat(header.length)));
15687
+ console.log(chalk138.dim(header));
15688
+ console.log(chalk138.dim("-".repeat(header.length)));
15362
15689
  for (const row of rows) {
15363
15690
  console.log(formatRow(row, nameWidth));
15364
15691
  }
@@ -15416,14 +15743,14 @@ function repos(options2) {
15416
15743
  // src/commands/devlog/skip.ts
15417
15744
  import { writeFileSync as writeFileSync29 } from "fs";
15418
15745
  import { join as join39 } from "path";
15419
- import chalk140 from "chalk";
15746
+ import chalk139 from "chalk";
15420
15747
  import { stringify as stringifyYaml3 } from "yaml";
15421
15748
  function getBlogConfigPath() {
15422
15749
  return join39(BLOG_REPO_ROOT, "assist.yml");
15423
15750
  }
15424
15751
  function skip(date) {
15425
15752
  if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
15426
- console.log(chalk140.red("Invalid date format. Use YYYY-MM-DD"));
15753
+ console.log(chalk139.red("Invalid date format. Use YYYY-MM-DD"));
15427
15754
  process.exit(1);
15428
15755
  }
15429
15756
  const repoName = getRepoName();
@@ -15434,7 +15761,7 @@ function skip(date) {
15434
15761
  const skipDays = skip2[repoName] ?? [];
15435
15762
  if (skipDays.includes(date)) {
15436
15763
  console.log(
15437
- chalk140.yellow(`${date} is already in skip list for ${repoName}`)
15764
+ chalk139.yellow(`${date} is already in skip list for ${repoName}`)
15438
15765
  );
15439
15766
  return;
15440
15767
  }
@@ -15444,20 +15771,20 @@ function skip(date) {
15444
15771
  devlog.skip = skip2;
15445
15772
  config.devlog = devlog;
15446
15773
  writeFileSync29(configPath, stringifyYaml3(config, { lineWidth: 0 }));
15447
- console.log(chalk140.green(`Added ${date} to skip list for ${repoName}`));
15774
+ console.log(chalk139.green(`Added ${date} to skip list for ${repoName}`));
15448
15775
  }
15449
15776
 
15450
15777
  // src/commands/devlog/version.ts
15451
- import chalk141 from "chalk";
15778
+ import chalk140 from "chalk";
15452
15779
  function version() {
15453
15780
  const config = loadConfig();
15454
15781
  const name = getRepoName();
15455
15782
  const lastInfo = getLastVersionInfo(name, config);
15456
15783
  const lastVersion = lastInfo?.version ?? null;
15457
15784
  const nextVersion = lastVersion ? bumpVersion(lastVersion, "patch") : null;
15458
- console.log(`${chalk141.bold("name:")} ${name}`);
15459
- console.log(`${chalk141.bold("last:")} ${lastVersion ?? chalk141.dim("none")}`);
15460
- console.log(`${chalk141.bold("next:")} ${nextVersion ?? chalk141.dim("none")}`);
15785
+ console.log(`${chalk140.bold("name:")} ${name}`);
15786
+ console.log(`${chalk140.bold("last:")} ${lastVersion ?? chalk140.dim("none")}`);
15787
+ console.log(`${chalk140.bold("next:")} ${nextVersion ?? chalk140.dim("none")}`);
15461
15788
  }
15462
15789
 
15463
15790
  // src/commands/devlog/devlogConfigHelp.ts
@@ -15501,7 +15828,7 @@ function registerDevlog(program2) {
15501
15828
  // src/commands/dotnet/checkBuildLocks.ts
15502
15829
  import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync5 } from "fs";
15503
15830
  import { join as join40 } from "path";
15504
- import chalk142 from "chalk";
15831
+ import chalk141 from "chalk";
15505
15832
 
15506
15833
  // src/shared/findRepoRoot.ts
15507
15834
  import { existsSync as existsSync37 } from "fs";
@@ -15564,14 +15891,14 @@ function checkBuildLocks(startDir) {
15564
15891
  const locked = findFirstLockedDll(startDir ?? getSearchRoot());
15565
15892
  if (locked) {
15566
15893
  console.error(
15567
- chalk142.red("Build output locked (is VS debugging?): ") + locked
15894
+ chalk141.red("Build output locked (is VS debugging?): ") + locked
15568
15895
  );
15569
15896
  process.exit(1);
15570
15897
  }
15571
15898
  }
15572
15899
  async function checkBuildLocksCommand() {
15573
15900
  checkBuildLocks();
15574
- console.log(chalk142.green("No build locks detected"));
15901
+ console.log(chalk141.green("No build locks detected"));
15575
15902
  }
15576
15903
 
15577
15904
  // src/commands/dotnet/buildTree.ts
@@ -15670,30 +15997,30 @@ function escapeRegex(s) {
15670
15997
  }
15671
15998
 
15672
15999
  // src/commands/dotnet/printTree.ts
15673
- import chalk143 from "chalk";
16000
+ import chalk142 from "chalk";
15674
16001
  function printNodes(nodes, prefix2) {
15675
16002
  for (let i = 0; i < nodes.length; i++) {
15676
16003
  const isLast = i === nodes.length - 1;
15677
16004
  const connector = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
15678
16005
  const childPrefix = isLast ? " " : "\u2502 ";
15679
16006
  const isMissing = nodes[i].relativePath.startsWith("[MISSING]");
15680
- const label2 = isMissing ? chalk143.red(nodes[i].relativePath) : nodes[i].relativePath;
16007
+ const label2 = isMissing ? chalk142.red(nodes[i].relativePath) : nodes[i].relativePath;
15681
16008
  console.log(`${prefix2}${connector}${label2}`);
15682
16009
  printNodes(nodes[i].children, prefix2 + childPrefix);
15683
16010
  }
15684
16011
  }
15685
16012
  function printTree(tree, totalCount, solutions) {
15686
- console.log(chalk143.bold("\nProject Dependency Tree"));
15687
- console.log(chalk143.cyan(tree.relativePath));
16013
+ console.log(chalk142.bold("\nProject Dependency Tree"));
16014
+ console.log(chalk142.cyan(tree.relativePath));
15688
16015
  printNodes(tree.children, "");
15689
- console.log(chalk143.dim(`
16016
+ console.log(chalk142.dim(`
15690
16017
  ${totalCount} projects total (including root)`));
15691
- console.log(chalk143.bold("\nSolution Membership"));
16018
+ console.log(chalk142.bold("\nSolution Membership"));
15692
16019
  if (solutions.length === 0) {
15693
- console.log(chalk143.yellow(" Not found in any .sln"));
16020
+ console.log(chalk142.yellow(" Not found in any .sln"));
15694
16021
  } else {
15695
16022
  for (const sln of solutions) {
15696
- console.log(` ${chalk143.green(sln)}`);
16023
+ console.log(` ${chalk142.green(sln)}`);
15697
16024
  }
15698
16025
  }
15699
16026
  console.log();
@@ -15722,16 +16049,16 @@ function printJson(tree, totalCount, solutions) {
15722
16049
  // src/commands/dotnet/resolveCsproj.ts
15723
16050
  import { existsSync as existsSync38 } from "fs";
15724
16051
  import path33 from "path";
15725
- import chalk144 from "chalk";
16052
+ import chalk143 from "chalk";
15726
16053
  function resolveCsproj(csprojPath) {
15727
16054
  const resolved = path33.resolve(csprojPath);
15728
16055
  if (!existsSync38(resolved)) {
15729
- console.error(chalk144.red(`File not found: ${resolved}`));
16056
+ console.error(chalk143.red(`File not found: ${resolved}`));
15730
16057
  process.exit(1);
15731
16058
  }
15732
16059
  const repoRoot = findRepoRoot(path33.dirname(resolved));
15733
16060
  if (!repoRoot) {
15734
- console.error(chalk144.red("Could not find git repository root"));
16061
+ console.error(chalk143.red("Could not find git repository root"));
15735
16062
  process.exit(1);
15736
16063
  }
15737
16064
  return { resolved, repoRoot };
@@ -15781,12 +16108,12 @@ function getChangedCsFiles(scope) {
15781
16108
  }
15782
16109
 
15783
16110
  // src/commands/dotnet/inSln.ts
15784
- import chalk145 from "chalk";
16111
+ import chalk144 from "chalk";
15785
16112
  async function inSln(csprojPath) {
15786
16113
  const { resolved, repoRoot } = resolveCsproj(csprojPath);
15787
16114
  const solutions = findContainingSolutions(resolved, repoRoot);
15788
16115
  if (solutions.length === 0) {
15789
- console.log(chalk145.yellow("Not found in any .sln file"));
16116
+ console.log(chalk144.yellow("Not found in any .sln file"));
15790
16117
  process.exit(1);
15791
16118
  }
15792
16119
  for (const sln of solutions) {
@@ -15795,7 +16122,7 @@ async function inSln(csprojPath) {
15795
16122
  }
15796
16123
 
15797
16124
  // src/commands/dotnet/inspect.ts
15798
- import chalk151 from "chalk";
16125
+ import chalk150 from "chalk";
15799
16126
 
15800
16127
  // src/shared/formatElapsed.ts
15801
16128
  function formatElapsed(ms) {
@@ -15807,12 +16134,12 @@ function formatElapsed(ms) {
15807
16134
  }
15808
16135
 
15809
16136
  // src/commands/dotnet/displayIssues.ts
15810
- import chalk146 from "chalk";
16137
+ import chalk145 from "chalk";
15811
16138
  var SEVERITY_COLOR = {
15812
- ERROR: chalk146.red,
15813
- WARNING: chalk146.yellow,
15814
- SUGGESTION: chalk146.cyan,
15815
- HINT: chalk146.dim
16139
+ ERROR: chalk145.red,
16140
+ WARNING: chalk145.yellow,
16141
+ SUGGESTION: chalk145.cyan,
16142
+ HINT: chalk145.dim
15816
16143
  };
15817
16144
  function groupByFile(issues) {
15818
16145
  const byFile = /* @__PURE__ */ new Map();
@@ -15828,15 +16155,15 @@ function groupByFile(issues) {
15828
16155
  }
15829
16156
  function displayIssues(issues) {
15830
16157
  for (const [file, fileIssues] of groupByFile(issues)) {
15831
- console.log(chalk146.bold(file));
16158
+ console.log(chalk145.bold(file));
15832
16159
  for (const issue of fileIssues.sort((a, b) => a.line - b.line)) {
15833
- const color = SEVERITY_COLOR[issue.severity] ?? chalk146.white;
16160
+ const color = SEVERITY_COLOR[issue.severity] ?? chalk145.white;
15834
16161
  console.log(
15835
- ` ${chalk146.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
16162
+ ` ${chalk145.dim(`${issue.line}:`)} ${color(issue.severity)} [${issue.typeId}] ${issue.message}`
15836
16163
  );
15837
16164
  }
15838
16165
  }
15839
- console.log(chalk146.dim(`
16166
+ console.log(chalk145.dim(`
15840
16167
  ${issues.length} issue(s) found`));
15841
16168
  }
15842
16169
 
@@ -15895,12 +16222,12 @@ function filterIssues(issues, all, cliOnly, cliSuppress) {
15895
16222
  // src/commands/dotnet/resolveSolution.ts
15896
16223
  import { existsSync as existsSync39 } from "fs";
15897
16224
  import path34 from "path";
15898
- import chalk148 from "chalk";
16225
+ import chalk147 from "chalk";
15899
16226
 
15900
16227
  // src/commands/dotnet/findSolution.ts
15901
16228
  import { readdirSync as readdirSync7 } from "fs";
15902
16229
  import { dirname as dirname22, join as join41 } from "path";
15903
- import chalk147 from "chalk";
16230
+ import chalk146 from "chalk";
15904
16231
  function findSlnInDir(dir) {
15905
16232
  try {
15906
16233
  return readdirSync7(dir).filter((f) => f.endsWith(".sln")).map((f) => join41(dir, f));
@@ -15916,17 +16243,17 @@ function findSolution() {
15916
16243
  const slnFiles = findSlnInDir(current);
15917
16244
  if (slnFiles.length === 1) return slnFiles[0];
15918
16245
  if (slnFiles.length > 1) {
15919
- console.error(chalk147.red(`Multiple .sln files found in ${current}:`));
16246
+ console.error(chalk146.red(`Multiple .sln files found in ${current}:`));
15920
16247
  for (const f of slnFiles) console.error(` ${f}`);
15921
16248
  console.error(
15922
- chalk147.yellow("Specify which one: assist dotnet inspect <sln>")
16249
+ chalk146.yellow("Specify which one: assist dotnet inspect <sln>")
15923
16250
  );
15924
16251
  process.exit(1);
15925
16252
  }
15926
16253
  if (current === ceiling) break;
15927
16254
  current = dirname22(current);
15928
16255
  }
15929
- console.error(chalk147.red("No .sln file found between cwd and repo root"));
16256
+ console.error(chalk146.red("No .sln file found between cwd and repo root"));
15930
16257
  process.exit(1);
15931
16258
  }
15932
16259
 
@@ -15935,7 +16262,7 @@ function resolveSolution(sln) {
15935
16262
  if (sln) {
15936
16263
  const resolved = path34.resolve(sln);
15937
16264
  if (!existsSync39(resolved)) {
15938
- console.error(chalk148.red(`Solution file not found: ${resolved}`));
16265
+ console.error(chalk147.red(`Solution file not found: ${resolved}`));
15939
16266
  process.exit(1);
15940
16267
  }
15941
16268
  return resolved;
@@ -15977,14 +16304,14 @@ import { execSync as execSync37 } from "child_process";
15977
16304
  import { existsSync as existsSync40, readFileSync as readFileSync35, unlinkSync as unlinkSync10 } from "fs";
15978
16305
  import { tmpdir as tmpdir4 } from "os";
15979
16306
  import path35 from "path";
15980
- import chalk149 from "chalk";
16307
+ import chalk148 from "chalk";
15981
16308
  function assertJbInstalled() {
15982
16309
  try {
15983
16310
  execSync37("jb inspectcode --version", { stdio: "pipe" });
15984
16311
  } catch {
15985
- console.error(chalk149.red("jb is not installed. Install with:"));
16312
+ console.error(chalk148.red("jb is not installed. Install with:"));
15986
16313
  console.error(
15987
- chalk149.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
16314
+ chalk148.yellow(" dotnet tool install -g JetBrains.ReSharper.GlobalTools")
15988
16315
  );
15989
16316
  process.exit(1);
15990
16317
  }
@@ -16002,11 +16329,11 @@ function runInspectCode(slnPath, include, swea) {
16002
16329
  if (error && typeof error === "object" && "stderr" in error) {
16003
16330
  process.stderr.write(error.stderr);
16004
16331
  }
16005
- console.error(chalk149.red("jb inspectcode failed"));
16332
+ console.error(chalk148.red("jb inspectcode failed"));
16006
16333
  process.exit(1);
16007
16334
  }
16008
16335
  if (!existsSync40(reportPath)) {
16009
- console.error(chalk149.red("Report file not generated"));
16336
+ console.error(chalk148.red("Report file not generated"));
16010
16337
  process.exit(1);
16011
16338
  }
16012
16339
  const xml = readFileSync35(reportPath, "utf8");
@@ -16016,7 +16343,7 @@ function runInspectCode(slnPath, include, swea) {
16016
16343
 
16017
16344
  // src/commands/dotnet/runRoslynInspect.ts
16018
16345
  import { execSync as execSync38 } from "child_process";
16019
- import chalk150 from "chalk";
16346
+ import chalk149 from "chalk";
16020
16347
  function resolveMsbuildPath() {
16021
16348
  const { run: run4 } = loadConfig();
16022
16349
  const configs = resolveRunConfigs(run4, getConfigDir());
@@ -16028,9 +16355,9 @@ function assertMsbuildInstalled() {
16028
16355
  try {
16029
16356
  execSync38(`"${msbuild}" -version`, { stdio: "pipe" });
16030
16357
  } catch {
16031
- console.error(chalk150.red(`msbuild not found at: ${msbuild}`));
16358
+ console.error(chalk149.red(`msbuild not found at: ${msbuild}`));
16032
16359
  console.error(
16033
- chalk150.yellow(
16360
+ chalk149.yellow(
16034
16361
  "Configure it via a 'build' run entry in .claude/assist.yml or add msbuild to PATH."
16035
16362
  )
16036
16363
  );
@@ -16077,17 +16404,17 @@ function runEngine(resolved, changedFiles2, options2) {
16077
16404
  // src/commands/dotnet/inspect.ts
16078
16405
  function logScope(changedFiles2) {
16079
16406
  if (changedFiles2 === null) {
16080
- console.log(chalk151.dim("Inspecting full solution..."));
16407
+ console.log(chalk150.dim("Inspecting full solution..."));
16081
16408
  } else {
16082
16409
  console.log(
16083
- chalk151.dim(`Inspecting ${changedFiles2.length} changed file(s)...`)
16410
+ chalk150.dim(`Inspecting ${changedFiles2.length} changed file(s)...`)
16084
16411
  );
16085
16412
  }
16086
16413
  }
16087
16414
  function reportResults(issues, elapsed) {
16088
16415
  if (issues.length > 0) displayIssues(issues);
16089
- else console.log(chalk151.green("No issues found"));
16090
- console.log(chalk151.dim(`Completed in ${formatElapsed(elapsed)}`));
16416
+ else console.log(chalk150.green("No issues found"));
16417
+ console.log(chalk150.dim(`Completed in ${formatElapsed(elapsed)}`));
16091
16418
  if (issues.length > 0) process.exit(1);
16092
16419
  }
16093
16420
  async function inspect(sln, options2) {
@@ -16098,7 +16425,7 @@ async function inspect(sln, options2) {
16098
16425
  const scope = parseScope(options2.scope);
16099
16426
  const changedFiles2 = getChangedCsFiles(scope);
16100
16427
  if (changedFiles2 !== null && changedFiles2.length === 0) {
16101
- console.log(chalk151.green("No changed .cs files found"));
16428
+ console.log(chalk150.green("No changed .cs files found"));
16102
16429
  return;
16103
16430
  }
16104
16431
  logScope(changedFiles2);
@@ -16481,25 +16808,25 @@ function fetchRepoCommitAuthors(org, repo, since) {
16481
16808
  }
16482
16809
 
16483
16810
  // src/commands/github/printCountTable.ts
16484
- import chalk152 from "chalk";
16811
+ import chalk151 from "chalk";
16485
16812
  function printCountTable(labelHeader, rows) {
16486
16813
  const labelWidth = Math.max(
16487
16814
  labelHeader.length,
16488
16815
  ...rows.map((row) => row.label.length)
16489
16816
  );
16490
16817
  const header = `${labelHeader.padEnd(labelWidth)} Commits`;
16491
- console.log(chalk152.dim(header));
16492
- console.log(chalk152.dim("-".repeat(header.length)));
16818
+ console.log(chalk151.dim(header));
16819
+ console.log(chalk151.dim("-".repeat(header.length)));
16493
16820
  for (const row of rows) {
16494
16821
  console.log(`${row.label.padEnd(labelWidth)} ${row.count}`);
16495
16822
  }
16496
16823
  }
16497
16824
 
16498
16825
  // src/commands/github/printRepoAuthorBreakdown.ts
16499
- import chalk153 from "chalk";
16826
+ import chalk152 from "chalk";
16500
16827
  function printRepoAuthorBreakdown(repos2) {
16501
16828
  for (const repo of repos2) {
16502
- console.log(chalk153.bold(repo.name));
16829
+ console.log(chalk152.bold(repo.name));
16503
16830
  const authorWidth = Math.max(
16504
16831
  0,
16505
16832
  ...repo.authors.map((a) => a.author.length)
@@ -16817,7 +17144,7 @@ function registerHandover(program2) {
16817
17144
  }
16818
17145
 
16819
17146
  // src/commands/jira/acceptanceCriteria.ts
16820
- import chalk154 from "chalk";
17147
+ import chalk153 from "chalk";
16821
17148
 
16822
17149
  // src/commands/jira/adfToText.ts
16823
17150
  function renderInline(node) {
@@ -16884,7 +17211,7 @@ function acceptanceCriteria(issueKey) {
16884
17211
  const parsed = fetchIssue(issueKey, field);
16885
17212
  const acValue = parsed?.fields?.[field];
16886
17213
  if (!acValue) {
16887
- console.log(chalk154.yellow(`No acceptance criteria found on ${issueKey}.`));
17214
+ console.log(chalk153.yellow(`No acceptance criteria found on ${issueKey}.`));
16888
17215
  return;
16889
17216
  }
16890
17217
  if (typeof acValue === "string") {
@@ -16950,14 +17277,14 @@ async function jiraAuth() {
16950
17277
  }
16951
17278
 
16952
17279
  // src/commands/jira/viewIssue.ts
16953
- import chalk155 from "chalk";
17280
+ import chalk154 from "chalk";
16954
17281
  function viewIssue(issueKey) {
16955
17282
  const parsed = fetchIssue(issueKey, "summary,description");
16956
17283
  const fields = parsed?.fields;
16957
17284
  const summary = fields?.summary;
16958
17285
  const description = fields?.description;
16959
17286
  if (summary) {
16960
- console.log(chalk155.bold(summary));
17287
+ console.log(chalk154.bold(summary));
16961
17288
  }
16962
17289
  if (description) {
16963
17290
  if (summary) console.log();
@@ -16971,7 +17298,7 @@ function viewIssue(issueKey) {
16971
17298
  }
16972
17299
  if (!summary && !description) {
16973
17300
  console.log(
16974
- chalk155.yellow(`No summary or description found on ${issueKey}.`)
17301
+ chalk154.yellow(`No summary or description found on ${issueKey}.`)
16975
17302
  );
16976
17303
  }
16977
17304
  }
@@ -17025,15 +17352,15 @@ function registerRefineLaunch(program2, resumeFlag) {
17025
17352
  }
17026
17353
 
17027
17354
  // src/commands/reviewPrComments.ts
17028
- import { execFileSync as execFileSync5 } from "child_process";
17355
+ import { execFileSync as execFileSync6 } from "child_process";
17029
17356
  import { randomUUID as randomUUID4 } from "crypto";
17030
- import chalk156 from "chalk";
17357
+ import chalk155 from "chalk";
17031
17358
  async function reviewPrComments(number) {
17032
17359
  if (number) {
17033
17360
  try {
17034
- execFileSync5("gh", ["pr", "checkout", number], { stdio: "inherit" });
17361
+ execFileSync6("gh", ["pr", "checkout", number], { stdio: "inherit" });
17035
17362
  } catch {
17036
- console.error(chalk156.red(`gh pr checkout ${number} failed; aborting.`));
17363
+ console.error(chalk155.red(`gh pr checkout ${number} failed; aborting.`));
17037
17364
  process.exit(1);
17038
17365
  }
17039
17366
  }
@@ -17106,15 +17433,15 @@ function registerList(program2) {
17106
17433
  // src/commands/mermaid/index.ts
17107
17434
  import { mkdirSync as mkdirSync16, readdirSync as readdirSync9 } from "fs";
17108
17435
  import { resolve as resolve13 } from "path";
17109
- import chalk159 from "chalk";
17436
+ import chalk158 from "chalk";
17110
17437
 
17111
17438
  // src/commands/mermaid/exportFile.ts
17112
17439
  import { readFileSync as readFileSync37, writeFileSync as writeFileSync31 } from "fs";
17113
17440
  import { basename as basename11, extname as extname2, resolve as resolve12 } from "path";
17114
- import chalk158 from "chalk";
17441
+ import chalk157 from "chalk";
17115
17442
 
17116
17443
  // src/commands/mermaid/renderBlock.ts
17117
- import chalk157 from "chalk";
17444
+ import chalk156 from "chalk";
17118
17445
  async function renderBlock(krokiUrl, source) {
17119
17446
  const response = await fetch(`${krokiUrl}/mermaid/svg`, {
17120
17447
  method: "POST",
@@ -17123,7 +17450,7 @@ async function renderBlock(krokiUrl, source) {
17123
17450
  });
17124
17451
  if (!response.ok) {
17125
17452
  console.error(
17126
- chalk157.red(
17453
+ chalk156.red(
17127
17454
  `Kroki request failed: ${response.status} ${response.statusText}`
17128
17455
  )
17129
17456
  );
@@ -17141,19 +17468,19 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
17141
17468
  if (onlyIndex !== void 0) {
17142
17469
  if (onlyIndex < 1 || onlyIndex > blocks.length) {
17143
17470
  console.error(
17144
- chalk158.red(
17471
+ chalk157.red(
17145
17472
  `${file}: --index ${onlyIndex} out of range (file has ${blocks.length} diagram(s))`
17146
17473
  )
17147
17474
  );
17148
17475
  process.exit(1);
17149
17476
  }
17150
17477
  console.log(
17151
- chalk158.gray(
17478
+ chalk157.gray(
17152
17479
  `${file} \u2014 rendering diagram ${onlyIndex} of ${blocks.length}`
17153
17480
  )
17154
17481
  );
17155
17482
  } else {
17156
- console.log(chalk158.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
17483
+ console.log(chalk157.gray(`${file} \u2014 ${blocks.length} diagram(s)`));
17157
17484
  }
17158
17485
  for (const [i, source] of blocks.entries()) {
17159
17486
  const idx = i + 1;
@@ -17161,7 +17488,7 @@ async function exportFile(file, outDir, krokiUrl, onlyIndex) {
17161
17488
  const outPath = resolve12(outDir, `${stem}-${idx}.svg`);
17162
17489
  const svg = await renderBlock(krokiUrl, source);
17163
17490
  writeFileSync31(outPath, svg, "utf8");
17164
- console.log(chalk158.green(` \u2192 ${outPath}`));
17491
+ console.log(chalk157.green(` \u2192 ${outPath}`));
17165
17492
  }
17166
17493
  }
17167
17494
  function extractMermaidBlocks(markdown) {
@@ -17177,18 +17504,18 @@ async function mermaidExport(file, options2 = {}) {
17177
17504
  if (options2.index !== void 0) {
17178
17505
  if (!Number.isInteger(options2.index) || options2.index < 1) {
17179
17506
  console.error(
17180
- chalk159.red(`--index must be a positive integer (got ${options2.index})`)
17507
+ chalk158.red(`--index must be a positive integer (got ${options2.index})`)
17181
17508
  );
17182
17509
  process.exit(1);
17183
17510
  }
17184
17511
  if (!file) {
17185
- console.error(chalk159.red("--index requires a file argument"));
17512
+ console.error(chalk158.red("--index requires a file argument"));
17186
17513
  process.exit(1);
17187
17514
  }
17188
17515
  }
17189
17516
  const files = file ? [file] : readdirSync9(process.cwd()).filter((name) => name.toLowerCase().endsWith(".md")).sort();
17190
17517
  if (files.length === 0) {
17191
- console.log(chalk159.gray("No markdown files found in current directory."));
17518
+ console.log(chalk158.gray("No markdown files found in current directory."));
17192
17519
  return;
17193
17520
  }
17194
17521
  for (const f of files) {
@@ -17221,7 +17548,7 @@ function registerMermaid(program2) {
17221
17548
  import { mkdir as mkdir4 } from "fs/promises";
17222
17549
  import { createServer as createServer2 } from "http";
17223
17550
  import { dirname as dirname24 } from "path";
17224
- import chalk161 from "chalk";
17551
+ import chalk160 from "chalk";
17225
17552
 
17226
17553
  // src/commands/netcap/corsHeaders.ts
17227
17554
  var corsHeaders = {
@@ -17300,7 +17627,7 @@ function createNetcapHandler(options2) {
17300
17627
  import { cp, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
17301
17628
  import { networkInterfaces } from "os";
17302
17629
  import { join as join47 } from "path";
17303
- import chalk160 from "chalk";
17630
+ import chalk159 from "chalk";
17304
17631
 
17305
17632
  // src/commands/netcap/netcapExtensionDir.ts
17306
17633
  import { dirname as dirname23, join as join46 } from "path";
@@ -17344,7 +17671,7 @@ async function prepareExtensionForLoad(port, filter = "") {
17344
17671
  const host = lanIPv4();
17345
17672
  if (!host) {
17346
17673
  console.log(
17347
- chalk160.yellow("could not determine the WSL IP for the extension")
17674
+ chalk159.yellow("could not determine the WSL IP for the extension")
17348
17675
  );
17349
17676
  await configureBackground(source, "127.0.0.1", port, filter);
17350
17677
  return source;
@@ -17355,7 +17682,7 @@ async function prepareExtensionForLoad(port, filter = "") {
17355
17682
  return WSL_WINDOWS_PATH;
17356
17683
  } catch {
17357
17684
  console.log(
17358
- chalk160.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
17685
+ chalk159.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
17359
17686
  );
17360
17687
  return source;
17361
17688
  }
@@ -17388,30 +17715,30 @@ async function netcap(options2) {
17388
17715
  let count7 = 0;
17389
17716
  const handler = createNetcapHandler({
17390
17717
  outPath,
17391
- onPing: () => console.log(chalk161.dim("ping from extension")),
17718
+ onPing: () => console.log(chalk160.dim("ping from extension")),
17392
17719
  onCapture: (entry) => {
17393
17720
  count7 += 1;
17394
17721
  console.log(
17395
- chalk161.green(`captured #${count7}`),
17396
- chalk161.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
17722
+ chalk160.green(`captured #${count7}`),
17723
+ chalk160.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
17397
17724
  );
17398
17725
  }
17399
17726
  });
17400
17727
  const server = createServer2(handler);
17401
17728
  server.listen(port, () => {
17402
17729
  console.log(
17403
- chalk161.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
17730
+ chalk160.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
17404
17731
  );
17405
- console.log(chalk161.dim(`appending captures to ${outPath}`));
17732
+ console.log(chalk160.dim(`appending captures to ${outPath}`));
17406
17733
  if (filter)
17407
- console.log(chalk161.dim(`forwarding only URLs matching "${filter}"`));
17408
- console.log(chalk161.dim(`load the unpacked extension from ${extensionPath}`));
17409
- console.log(chalk161.dim("press Ctrl-C to stop"));
17734
+ console.log(chalk160.dim(`forwarding only URLs matching "${filter}"`));
17735
+ console.log(chalk160.dim(`load the unpacked extension from ${extensionPath}`));
17736
+ console.log(chalk160.dim("press Ctrl-C to stop"));
17410
17737
  });
17411
17738
  process.on("SIGINT", () => {
17412
17739
  server.close();
17413
17740
  console.log(
17414
- chalk161.bold(
17741
+ chalk160.bold(
17415
17742
  `
17416
17743
  netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} to ${outPath}`
17417
17744
  )
@@ -17423,7 +17750,7 @@ netcap stopped \u2014 captured ${count7} ${count7 === 1 ? "entry" : "entries"} t
17423
17750
  // src/commands/netcap/netcapExtract.ts
17424
17751
  import { writeFileSync as writeFileSync32 } from "fs";
17425
17752
  import { join as join50 } from "path";
17426
- import chalk162 from "chalk";
17753
+ import chalk161 from "chalk";
17427
17754
 
17428
17755
  // src/commands/netcap/extractPostsFromCapture.ts
17429
17756
  import { readFileSync as readFileSync38 } from "fs";
@@ -17871,8 +18198,8 @@ function netcapExtract(file) {
17871
18198
  writeFileSync32(outFile, `${JSON.stringify(posts, null, 2)}
17872
18199
  `);
17873
18200
  console.log(
17874
- chalk162.green(`extracted ${posts.length} posts`),
17875
- chalk162.dim(`-> ${outFile}`)
18201
+ chalk161.green(`extracted ${posts.length} posts`),
18202
+ chalk161.dim(`-> ${outFile}`)
17876
18203
  );
17877
18204
  }
17878
18205
 
@@ -17893,7 +18220,7 @@ function registerNetcap(program2) {
17893
18220
  }
17894
18221
 
17895
18222
  // src/commands/news/add/index.ts
17896
- import chalk163 from "chalk";
18223
+ import chalk162 from "chalk";
17897
18224
  import enquirer8 from "enquirer";
17898
18225
  async function add2(url) {
17899
18226
  if (!url) {
@@ -17915,10 +18242,10 @@ async function add2(url) {
17915
18242
  const { orm } = await getReady();
17916
18243
  const added = await addFeed(orm, url);
17917
18244
  if (!added) {
17918
- console.log(chalk163.yellow("Feed already exists"));
18245
+ console.log(chalk162.yellow("Feed already exists"));
17919
18246
  return;
17920
18247
  }
17921
- console.log(chalk163.green(`Added feed: ${url}`));
18248
+ console.log(chalk162.green(`Added feed: ${url}`));
17922
18249
  }
17923
18250
 
17924
18251
  // src/commands/registerNews.ts
@@ -17965,7 +18292,7 @@ function registerPiHook(program2) {
17965
18292
  }
17966
18293
 
17967
18294
  // src/commands/prompts/printPromptsTable.ts
17968
- import chalk164 from "chalk";
18295
+ import chalk163 from "chalk";
17969
18296
  function truncate(str, max) {
17970
18297
  if (str.length <= max) return str;
17971
18298
  return `${str.slice(0, max - 1)}\u2026`;
@@ -17983,14 +18310,14 @@ function printPromptsTable(rows) {
17983
18310
  "Command".padEnd(commandWidth),
17984
18311
  "Repos"
17985
18312
  ].join(" ");
17986
- console.log(chalk164.dim(header));
17987
- console.log(chalk164.dim("-".repeat(header.length)));
18313
+ console.log(chalk163.dim(header));
18314
+ console.log(chalk163.dim("-".repeat(header.length)));
17988
18315
  for (const row of rows) {
17989
18316
  const count7 = String(row.count).padStart(countWidth);
17990
18317
  const tool = row.tool.padEnd(toolWidth);
17991
18318
  const command = truncate(row.command, 60).padEnd(commandWidth);
17992
18319
  console.log(
17993
- `${chalk164.yellow(count7)} ${tool} ${command} ${chalk164.dim(row.repos)}`
18320
+ `${chalk163.yellow(count7)} ${tool} ${command} ${chalk163.dim(row.repos)}`
17994
18321
  );
17995
18322
  }
17996
18323
  }
@@ -18154,7 +18481,7 @@ function comment2(path71, line, body, startLine) {
18154
18481
  }
18155
18482
 
18156
18483
  // src/commands/prs/edit.ts
18157
- import { execFileSync as execFileSync6 } from "child_process";
18484
+ import { execFileSync as execFileSync7 } from "child_process";
18158
18485
 
18159
18486
  // src/commands/prs/buildPrBody.ts
18160
18487
  function jiraBrowseUrl(key) {
@@ -18345,7 +18672,7 @@ function edit(options2) {
18345
18672
  if (options2.title) args.push("--title", options2.title);
18346
18673
  args.push("--body", newBody);
18347
18674
  try {
18348
- execFileSync6("gh", args, { stdio: "inherit" });
18675
+ execFileSync7("gh", args, { stdio: "inherit" });
18349
18676
  } catch {
18350
18677
  process.exit(1);
18351
18678
  }
@@ -18407,20 +18734,20 @@ function resolveThread(threadId) {
18407
18734
  }
18408
18735
  }
18409
18736
  function requireCache(prNumber) {
18410
- const cache2 = loadCommentsCache(prNumber);
18411
- if (!cache2) {
18737
+ const cache3 = loadCommentsCache(prNumber);
18738
+ if (!cache3) {
18412
18739
  console.error(
18413
18740
  `Error: No cached comments found for PR #${prNumber}. Run "assist prs list-comments" first.`
18414
18741
  );
18415
18742
  process.exit(1);
18416
18743
  }
18417
- return cache2;
18744
+ return cache3;
18418
18745
  }
18419
18746
  function findLineComment(comments3, commentId) {
18420
18747
  return comments3.find((c) => c.type === "line" && c.id === commentId);
18421
18748
  }
18422
- function requireLineComment(cache2, commentId) {
18423
- const comment3 = findLineComment(cache2.comments, commentId);
18749
+ function requireLineComment(cache3, commentId) {
18750
+ const comment3 = findLineComment(cache3.comments, commentId);
18424
18751
  if (!comment3 || comment3.type !== "line" || !comment3.threadId) {
18425
18752
  console.error(
18426
18753
  `Error: Comment #${commentId} not found or has no thread ID.`
@@ -18429,8 +18756,8 @@ function requireLineComment(cache2, commentId) {
18429
18756
  }
18430
18757
  return comment3;
18431
18758
  }
18432
- function cleanupCacheIfDone(cache2, prNumber, commentId) {
18433
- const hasRemaining = cache2.comments.some(
18759
+ function cleanupCacheIfDone(cache3, prNumber, commentId) {
18760
+ const hasRemaining = cache3.comments.some(
18434
18761
  (c) => c.type === "line" && c.id !== commentId
18435
18762
  );
18436
18763
  if (!hasRemaining) deleteCommentsCache(prNumber);
@@ -18438,13 +18765,13 @@ function cleanupCacheIfDone(cache2, prNumber, commentId) {
18438
18765
  function resolveCommentWithReply(commentId, message2) {
18439
18766
  const prNumber = getCurrentPrNumber();
18440
18767
  const { org, repo } = getRepoInfo();
18441
- const cache2 = requireCache(prNumber);
18442
- const comment3 = requireLineComment(cache2, commentId);
18768
+ const cache3 = requireCache(prNumber);
18769
+ const comment3 = requireLineComment(cache3, commentId);
18443
18770
  replyToComment(org, repo, prNumber, commentId, message2);
18444
18771
  console.log("Reply posted successfully.");
18445
18772
  resolveThread(comment3.threadId);
18446
18773
  console.log("Thread resolved successfully.");
18447
- cleanupCacheIfDone(cache2, prNumber, commentId);
18774
+ cleanupCacheIfDone(cache3, prNumber, commentId);
18448
18775
  }
18449
18776
 
18450
18777
  // src/commands/prs/fixed.ts
@@ -18557,20 +18884,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
18557
18884
  }
18558
18885
 
18559
18886
  // src/commands/prs/listComments/printComments.ts
18560
- import chalk165 from "chalk";
18887
+ import chalk164 from "chalk";
18561
18888
  function formatForHuman(comment3) {
18562
18889
  if (comment3.type === "review") {
18563
- const stateColor = comment3.state === "APPROVED" ? chalk165.green : comment3.state === "CHANGES_REQUESTED" ? chalk165.red : chalk165.yellow;
18890
+ const stateColor = comment3.state === "APPROVED" ? chalk164.green : comment3.state === "CHANGES_REQUESTED" ? chalk164.red : chalk164.yellow;
18564
18891
  return [
18565
- `${chalk165.cyan("Review")} by ${chalk165.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
18892
+ `${chalk164.cyan("Review")} by ${chalk164.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
18566
18893
  comment3.body,
18567
18894
  ""
18568
18895
  ].join("\n");
18569
18896
  }
18570
18897
  const location = comment3.line ? `:${comment3.line}` : "";
18571
18898
  return [
18572
- `${chalk165.cyan("Line comment")} by ${chalk165.bold(comment3.user)} on ${chalk165.dim(`${comment3.path}${location}`)}`,
18573
- chalk165.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
18899
+ `${chalk164.cyan("Line comment")} by ${chalk164.bold(comment3.user)} on ${chalk164.dim(`${comment3.path}${location}`)}`,
18900
+ chalk164.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
18574
18901
  comment3.body,
18575
18902
  ""
18576
18903
  ].join("\n");
@@ -18660,13 +18987,13 @@ import { execSync as execSync46 } from "child_process";
18660
18987
  import enquirer9 from "enquirer";
18661
18988
 
18662
18989
  // src/commands/prs/prs/displayPaginated/printPr.ts
18663
- import chalk166 from "chalk";
18990
+ import chalk165 from "chalk";
18664
18991
  var STATUS_MAP = {
18665
- MERGED: (pr) => pr.mergedAt ? { label: chalk166.magenta("merged"), date: pr.mergedAt } : null,
18666
- CLOSED: (pr) => pr.closedAt ? { label: chalk166.red("closed"), date: pr.closedAt } : null
18992
+ MERGED: (pr) => pr.mergedAt ? { label: chalk165.magenta("merged"), date: pr.mergedAt } : null,
18993
+ CLOSED: (pr) => pr.closedAt ? { label: chalk165.red("closed"), date: pr.closedAt } : null
18667
18994
  };
18668
18995
  function defaultStatus(pr) {
18669
- return { label: chalk166.green("opened"), date: pr.createdAt };
18996
+ return { label: chalk165.green("opened"), date: pr.createdAt };
18670
18997
  }
18671
18998
  function getStatus2(pr) {
18672
18999
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -18675,11 +19002,11 @@ function formatDate(dateStr) {
18675
19002
  return new Date(dateStr).toISOString().split("T")[0];
18676
19003
  }
18677
19004
  function formatPrHeader(pr, status3) {
18678
- return `${chalk166.cyan(`#${pr.number}`)} ${pr.title} ${chalk166.dim(`(${pr.author.login},`)} ${status3.label} ${chalk166.dim(`${formatDate(status3.date)})`)}`;
19005
+ return `${chalk165.cyan(`#${pr.number}`)} ${pr.title} ${chalk165.dim(`(${pr.author.login},`)} ${status3.label} ${chalk165.dim(`${formatDate(status3.date)})`)}`;
18679
19006
  }
18680
19007
  function logPrDetails(pr) {
18681
19008
  console.log(
18682
- chalk166.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
19009
+ chalk165.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
18683
19010
  );
18684
19011
  console.log();
18685
19012
  }
@@ -18800,7 +19127,7 @@ function buildValidatedBody(options2, usage) {
18800
19127
  }
18801
19128
 
18802
19129
  // src/commands/prs/placePr.ts
18803
- import { execFileSync as execFileSync7 } from "child_process";
19130
+ import { execFileSync as execFileSync8 } from "child_process";
18804
19131
 
18805
19132
  // src/commands/prs/buildCreateArgs.ts
18806
19133
  function buildEditArgs(number, title, body) {
@@ -18867,7 +19194,7 @@ async function recordPrActivity() {
18867
19194
  // src/commands/prs/placePr.ts
18868
19195
  function hasUpstream() {
18869
19196
  try {
18870
- execFileSync7(
19197
+ execFileSync8(
18871
19198
  "git",
18872
19199
  ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"],
18873
19200
  { stdio: "pipe" }
@@ -18879,13 +19206,13 @@ function hasUpstream() {
18879
19206
  }
18880
19207
  function ensureBranchPushed() {
18881
19208
  const args = hasUpstream() ? ["push"] : ["push", "--set-upstream", "origin", "HEAD"];
18882
- execFileSync7("git", args, { stdio: "inherit" });
19209
+ execFileSync8("git", args, { stdio: "inherit" });
18883
19210
  }
18884
19211
  async function placePr(prNumber, title, body, options2) {
18885
19212
  const args = prNumber !== null ? buildEditArgs(prNumber, title, body) : buildCreateArgs(title, body, options2);
18886
19213
  try {
18887
19214
  if (prNumber === null && !options2.head) ensureBranchPushed();
18888
- execFileSync7("gh", args, { stdio: "inherit" });
19215
+ execFileSync8("gh", args, { stdio: "inherit" });
18889
19216
  } catch {
18890
19217
  process.exit(1);
18891
19218
  }
@@ -19194,10 +19521,10 @@ function registerPrs(program2) {
19194
19521
  }
19195
19522
 
19196
19523
  // src/commands/ravendb/ravendbAuth.ts
19197
- import chalk172 from "chalk";
19524
+ import chalk171 from "chalk";
19198
19525
 
19199
19526
  // src/shared/createConnectionAuth.ts
19200
- import chalk167 from "chalk";
19527
+ import chalk166 from "chalk";
19201
19528
  function listConnections(connections, format) {
19202
19529
  if (connections.length === 0) {
19203
19530
  console.log("No connections configured.");
@@ -19210,7 +19537,7 @@ function listConnections(connections, format) {
19210
19537
  function removeConnection(connections, name, save) {
19211
19538
  const filtered = connections.filter((c) => c.name !== name);
19212
19539
  if (filtered.length === connections.length) {
19213
- console.error(chalk167.red(`Connection "${name}" not found.`));
19540
+ console.error(chalk166.red(`Connection "${name}" not found.`));
19214
19541
  process.exit(1);
19215
19542
  }
19216
19543
  save(filtered);
@@ -19256,15 +19583,15 @@ function saveConnections(connections) {
19256
19583
  }
19257
19584
 
19258
19585
  // src/commands/ravendb/promptConnection.ts
19259
- import chalk170 from "chalk";
19586
+ import chalk169 from "chalk";
19260
19587
 
19261
19588
  // src/commands/ravendb/selectOpSecret.ts
19262
- import chalk169 from "chalk";
19589
+ import chalk168 from "chalk";
19263
19590
  import Enquirer2 from "enquirer";
19264
19591
 
19265
19592
  // src/commands/ravendb/searchItems.ts
19266
19593
  import { execSync as execSync49 } from "child_process";
19267
- import chalk168 from "chalk";
19594
+ import chalk167 from "chalk";
19268
19595
  function opExec(args) {
19269
19596
  return execSync49(`op ${args}`, {
19270
19597
  encoding: "utf8",
@@ -19277,7 +19604,7 @@ function searchItems(search2) {
19277
19604
  items2 = JSON.parse(opExec("item list --format=json"));
19278
19605
  } catch {
19279
19606
  console.error(
19280
- chalk168.red(
19607
+ chalk167.red(
19281
19608
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
19282
19609
  )
19283
19610
  );
@@ -19291,7 +19618,7 @@ function getItemFields(itemId2) {
19291
19618
  const item = JSON.parse(opExec(`item get "${itemId2}" --format=json`));
19292
19619
  return item.fields.filter((f) => f.reference && f.label);
19293
19620
  } catch {
19294
- console.error(chalk168.red("Failed to get item details from 1Password."));
19621
+ console.error(chalk167.red("Failed to get item details from 1Password."));
19295
19622
  process.exit(1);
19296
19623
  }
19297
19624
  }
@@ -19310,7 +19637,7 @@ async function selectOpSecret(searchTerm) {
19310
19637
  }).run();
19311
19638
  const items2 = searchItems(search2);
19312
19639
  if (items2.length === 0) {
19313
- console.error(chalk169.red(`No items found matching "${search2}".`));
19640
+ console.error(chalk168.red(`No items found matching "${search2}".`));
19314
19641
  process.exit(1);
19315
19642
  }
19316
19643
  const itemId2 = await selectOne(
@@ -19319,7 +19646,7 @@ async function selectOpSecret(searchTerm) {
19319
19646
  );
19320
19647
  const fields = getItemFields(itemId2);
19321
19648
  if (fields.length === 0) {
19322
- console.error(chalk169.red("No fields with references found on this item."));
19649
+ console.error(chalk168.red("No fields with references found on this item."));
19323
19650
  process.exit(1);
19324
19651
  }
19325
19652
  const ref = await selectOne(
@@ -19333,7 +19660,7 @@ async function selectOpSecret(searchTerm) {
19333
19660
  async function promptConnection(existingNames) {
19334
19661
  const name = await promptInput("name", "Connection name:");
19335
19662
  if (existingNames.includes(name)) {
19336
- console.error(chalk170.red(`Connection "${name}" already exists.`));
19663
+ console.error(chalk169.red(`Connection "${name}" already exists.`));
19337
19664
  process.exit(1);
19338
19665
  }
19339
19666
  const url = await promptInput(
@@ -19342,22 +19669,22 @@ async function promptConnection(existingNames) {
19342
19669
  );
19343
19670
  const database = await promptInput("database", "Database name:");
19344
19671
  if (!name || !url || !database) {
19345
- console.error(chalk170.red("All fields are required."));
19672
+ console.error(chalk169.red("All fields are required."));
19346
19673
  process.exit(1);
19347
19674
  }
19348
19675
  const apiKeyRef = await selectOpSecret();
19349
- console.log(chalk170.dim(`Using: ${apiKeyRef}`));
19676
+ console.log(chalk169.dim(`Using: ${apiKeyRef}`));
19350
19677
  return { name, url, database, apiKeyRef };
19351
19678
  }
19352
19679
 
19353
19680
  // src/commands/ravendb/ravendbSetConnection.ts
19354
- import chalk171 from "chalk";
19681
+ import chalk170 from "chalk";
19355
19682
  function ravendbSetConnection(name) {
19356
19683
  const raw = loadGlobalConfigRaw();
19357
19684
  const ravendb = raw.ravendb ?? {};
19358
19685
  const connections = ravendb.connections ?? [];
19359
19686
  if (!connections.some((c) => c.name === name)) {
19360
- console.error(chalk171.red(`Connection "${name}" not found.`));
19687
+ console.error(chalk170.red(`Connection "${name}" not found.`));
19361
19688
  console.error(
19362
19689
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
19363
19690
  );
@@ -19373,16 +19700,16 @@ function ravendbSetConnection(name) {
19373
19700
  var ravendbAuth = createConnectionAuth({
19374
19701
  load: loadConnections,
19375
19702
  save: saveConnections,
19376
- format: (c) => `${chalk172.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
19703
+ format: (c) => `${chalk171.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
19377
19704
  promptNew: promptConnection,
19378
19705
  onFirst: (c) => ravendbSetConnection(c.name)
19379
19706
  });
19380
19707
 
19381
19708
  // src/commands/ravendb/ravendbCollections.ts
19382
- import chalk176 from "chalk";
19709
+ import chalk175 from "chalk";
19383
19710
 
19384
19711
  // src/commands/ravendb/ravenFetch.ts
19385
- import chalk174 from "chalk";
19712
+ import chalk173 from "chalk";
19386
19713
 
19387
19714
  // src/commands/ravendb/getAccessToken.ts
19388
19715
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -19419,10 +19746,10 @@ ${errorText}`
19419
19746
 
19420
19747
  // src/commands/ravendb/resolveOpSecret.ts
19421
19748
  import { execSync as execSync50 } from "child_process";
19422
- import chalk173 from "chalk";
19749
+ import chalk172 from "chalk";
19423
19750
  function resolveOpSecret(reference) {
19424
19751
  if (!reference.startsWith("op://")) {
19425
- console.error(chalk173.red(`Invalid secret reference: must start with op://`));
19752
+ console.error(chalk172.red(`Invalid secret reference: must start with op://`));
19426
19753
  process.exit(1);
19427
19754
  }
19428
19755
  try {
@@ -19432,7 +19759,7 @@ function resolveOpSecret(reference) {
19432
19759
  }).trim();
19433
19760
  } catch {
19434
19761
  console.error(
19435
- chalk173.red(
19762
+ chalk172.red(
19436
19763
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
19437
19764
  )
19438
19765
  );
@@ -19459,7 +19786,7 @@ async function ravenFetch(connection, path71) {
19459
19786
  if (!response.ok) {
19460
19787
  const body = await response.text();
19461
19788
  console.error(
19462
- chalk174.red(`RavenDB error: ${response.status} ${response.statusText}`)
19789
+ chalk173.red(`RavenDB error: ${response.status} ${response.statusText}`)
19463
19790
  );
19464
19791
  console.error(body.substring(0, 500));
19465
19792
  process.exit(1);
@@ -19468,7 +19795,7 @@ async function ravenFetch(connection, path71) {
19468
19795
  }
19469
19796
 
19470
19797
  // src/commands/ravendb/resolveConnection.ts
19471
- import chalk175 from "chalk";
19798
+ import chalk174 from "chalk";
19472
19799
  function loadRavendb() {
19473
19800
  const raw = loadGlobalConfigRaw();
19474
19801
  const ravendb = raw.ravendb;
@@ -19482,7 +19809,7 @@ function resolveConnection(name) {
19482
19809
  const connectionName = name ?? defaultConnection;
19483
19810
  if (!connectionName) {
19484
19811
  console.error(
19485
- chalk175.red(
19812
+ chalk174.red(
19486
19813
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
19487
19814
  )
19488
19815
  );
@@ -19490,7 +19817,7 @@ function resolveConnection(name) {
19490
19817
  }
19491
19818
  const connection = connections.find((c) => c.name === connectionName);
19492
19819
  if (!connection) {
19493
- console.error(chalk175.red(`Connection "${connectionName}" not found.`));
19820
+ console.error(chalk174.red(`Connection "${connectionName}" not found.`));
19494
19821
  console.error(
19495
19822
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
19496
19823
  );
@@ -19521,7 +19848,7 @@ async function ravendbCollections(connectionName) {
19521
19848
  return;
19522
19849
  }
19523
19850
  for (const c of collections) {
19524
- console.log(`${chalk176.bold(c.Name)} ${c.CountOfDocuments} docs`);
19851
+ console.log(`${chalk175.bold(c.Name)} ${c.CountOfDocuments} docs`);
19525
19852
  }
19526
19853
  }
19527
19854
 
@@ -19540,10 +19867,10 @@ var ravendbConfigHelp = [
19540
19867
  ];
19541
19868
 
19542
19869
  // src/commands/ravendb/ravendbQuery.ts
19543
- import chalk178 from "chalk";
19870
+ import chalk177 from "chalk";
19544
19871
 
19545
19872
  // src/commands/ravendb/fetchAllPages.ts
19546
- import chalk177 from "chalk";
19873
+ import chalk176 from "chalk";
19547
19874
 
19548
19875
  // src/commands/ravendb/buildQueryPath.ts
19549
19876
  function buildQueryPath(opts) {
@@ -19581,7 +19908,7 @@ async function fetchAllPages(connection, opts) {
19581
19908
  allResults.push(...results);
19582
19909
  start3 += results.length;
19583
19910
  process.stderr.write(
19584
- `\r${chalk177.dim(`Fetched ${allResults.length}/${totalResults}`)}`
19911
+ `\r${chalk176.dim(`Fetched ${allResults.length}/${totalResults}`)}`
19585
19912
  );
19586
19913
  if (start3 >= totalResults) break;
19587
19914
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -19596,7 +19923,7 @@ async function fetchAllPages(connection, opts) {
19596
19923
  async function ravendbQuery(connectionName, collection, options2) {
19597
19924
  const resolved = resolveArgs(connectionName, collection);
19598
19925
  if (!resolved.collection && !options2.query) {
19599
- console.error(chalk178.red("Provide a collection name or --query filter."));
19926
+ console.error(chalk177.red("Provide a collection name or --query filter."));
19600
19927
  process.exit(1);
19601
19928
  }
19602
19929
  const { collection: col } = resolved;
@@ -19635,7 +19962,7 @@ import { spawn as spawn5 } from "child_process";
19635
19962
  import * as path36 from "path";
19636
19963
 
19637
19964
  // src/commands/refactor/logViolations.ts
19638
- import chalk179 from "chalk";
19965
+ import chalk178 from "chalk";
19639
19966
  var DEFAULT_MAX_LINES = 100;
19640
19967
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
19641
19968
  if (violations.length === 0) {
@@ -19644,43 +19971,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
19644
19971
  }
19645
19972
  return;
19646
19973
  }
19647
- console.error(chalk179.red(`
19974
+ console.error(chalk178.red(`
19648
19975
  Refactor check failed:
19649
19976
  `));
19650
- console.error(chalk179.red(` The following files exceed ${maxLines} lines:
19977
+ console.error(chalk178.red(` The following files exceed ${maxLines} lines:
19651
19978
  `));
19652
19979
  for (const violation of violations) {
19653
- console.error(chalk179.red(` ${violation.file} (${violation.lines} lines)`));
19980
+ console.error(chalk178.red(` ${violation.file} (${violation.lines} lines)`));
19654
19981
  }
19655
19982
  console.error(
19656
- chalk179.yellow(
19983
+ chalk178.yellow(
19657
19984
  `
19658
19985
  Each file needs to be sensibly refactored, or if there is no sensible
19659
19986
  way to refactor it, ignore it with:
19660
19987
  `
19661
19988
  )
19662
19989
  );
19663
- console.error(chalk179.gray(` assist refactor ignore <file>
19990
+ console.error(chalk178.gray(` assist refactor ignore <file>
19664
19991
  `));
19665
19992
  if (process.env.CLAUDECODE) {
19666
- console.error(chalk179.cyan(`
19993
+ console.error(chalk178.cyan(`
19667
19994
  ## Extracting Code to New Files
19668
19995
  `));
19669
19996
  console.error(
19670
- chalk179.cyan(
19997
+ chalk178.cyan(
19671
19998
  ` When extracting logic from one file to another, consider where the extracted code belongs:
19672
19999
  `
19673
20000
  )
19674
20001
  );
19675
20002
  console.error(
19676
- chalk179.cyan(
20003
+ chalk178.cyan(
19677
20004
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
19678
20005
  original file's domain, create a new folder containing both the original and extracted files.
19679
20006
  `
19680
20007
  )
19681
20008
  );
19682
20009
  console.error(
19683
- chalk179.cyan(
20010
+ chalk178.cyan(
19684
20011
  ` 2. Share common utilities: If the extracted code can be reused across multiple
19685
20012
  domains, move it to a common/shared folder.
19686
20013
  `
@@ -19836,7 +20163,7 @@ async function check(pattern2, options2) {
19836
20163
 
19837
20164
  // src/commands/refactor/extract/index.ts
19838
20165
  import path44 from "path";
19839
- import chalk182 from "chalk";
20166
+ import chalk181 from "chalk";
19840
20167
 
19841
20168
  // src/commands/refactor/extract/applyExtraction.ts
19842
20169
  import { SyntaxKind as SyntaxKind4 } from "ts-morph";
@@ -20435,23 +20762,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
20435
20762
 
20436
20763
  // src/commands/refactor/extract/displayPlan.ts
20437
20764
  import path40 from "path";
20438
- import chalk180 from "chalk";
20765
+ import chalk179 from "chalk";
20439
20766
  function section2(title) {
20440
20767
  return `
20441
- ${chalk180.cyan(title)}`;
20768
+ ${chalk179.cyan(title)}`;
20442
20769
  }
20443
20770
  function displayImporters(plan2, cwd) {
20444
20771
  if (plan2.importersToUpdate.length === 0) return;
20445
20772
  console.log(section2("Update importers:"));
20446
20773
  for (const imp of plan2.importersToUpdate) {
20447
20774
  const rel = path40.relative(cwd, imp.file.getFilePath());
20448
- console.log(` ${chalk180.dim(rel)}: \u2192 import from "${imp.relPath}"`);
20775
+ console.log(` ${chalk179.dim(rel)}: \u2192 import from "${imp.relPath}"`);
20449
20776
  }
20450
20777
  }
20451
20778
  function displayPlan(functionName, relDest, plan2, cwd) {
20452
- console.log(chalk180.bold(`Extract: ${functionName} \u2192 ${relDest}
20779
+ console.log(chalk179.bold(`Extract: ${functionName} \u2192 ${relDest}
20453
20780
  `));
20454
- console.log(` ${chalk180.cyan("Functions to move:")}`);
20781
+ console.log(` ${chalk179.cyan("Functions to move:")}`);
20455
20782
  for (const name of plan2.extractedNames) {
20456
20783
  console.log(` ${name}`);
20457
20784
  }
@@ -20485,7 +20812,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
20485
20812
 
20486
20813
  // src/commands/refactor/extract/loadProjectFile.ts
20487
20814
  import path43 from "path";
20488
- import chalk181 from "chalk";
20815
+ import chalk180 from "chalk";
20489
20816
  import { Project as Project4 } from "ts-morph";
20490
20817
 
20491
20818
  // src/commands/refactor/extract/findTsConfig.ts
@@ -20577,7 +20904,7 @@ function loadProjectFile(file) {
20577
20904
  });
20578
20905
  const sourceFile = project.getSourceFile(sourcePath);
20579
20906
  if (!sourceFile) {
20580
- console.log(chalk181.red(`File not found in project: ${file}`));
20907
+ console.log(chalk180.red(`File not found in project: ${file}`));
20581
20908
  process.exit(1);
20582
20909
  }
20583
20910
  return { project, sourceFile };
@@ -20600,19 +20927,19 @@ async function extract(file, functionName, destination, options2 = {}) {
20600
20927
  displayPlan(functionName, relDest, plan2, cwd);
20601
20928
  if (options2.apply) {
20602
20929
  await applyExtraction(functionName, sourceFile, destPath, plan2, project);
20603
- console.log(chalk182.green("\nExtraction complete"));
20930
+ console.log(chalk181.green("\nExtraction complete"));
20604
20931
  } else {
20605
- console.log(chalk182.dim("\nDry run. Use --apply to execute."));
20932
+ console.log(chalk181.dim("\nDry run. Use --apply to execute."));
20606
20933
  }
20607
20934
  }
20608
20935
 
20609
20936
  // src/commands/refactor/ignore.ts
20610
20937
  import fs28 from "fs";
20611
- import chalk183 from "chalk";
20938
+ import chalk182 from "chalk";
20612
20939
  var REFACTOR_YML_PATH2 = "refactor.yml";
20613
20940
  function ignore2(file) {
20614
20941
  if (!fs28.existsSync(file)) {
20615
- console.error(chalk183.red(`Error: File does not exist: ${file}`));
20942
+ console.error(chalk182.red(`Error: File does not exist: ${file}`));
20616
20943
  process.exit(1);
20617
20944
  }
20618
20945
  const content = fs28.readFileSync(file, "utf8");
@@ -20628,7 +20955,7 @@ function ignore2(file) {
20628
20955
  fs28.writeFileSync(REFACTOR_YML_PATH2, entry);
20629
20956
  }
20630
20957
  console.log(
20631
- chalk183.green(
20958
+ chalk182.green(
20632
20959
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
20633
20960
  )
20634
20961
  );
@@ -20637,12 +20964,12 @@ function ignore2(file) {
20637
20964
  // src/commands/refactor/rename/index.ts
20638
20965
  import fs31 from "fs";
20639
20966
  import path49 from "path";
20640
- import chalk186 from "chalk";
20967
+ import chalk185 from "chalk";
20641
20968
 
20642
20969
  // src/commands/refactor/rename/applyRename.ts
20643
20970
  import fs30 from "fs";
20644
20971
  import path46 from "path";
20645
- import chalk184 from "chalk";
20972
+ import chalk183 from "chalk";
20646
20973
 
20647
20974
  // src/commands/refactor/restructure/computeRewrites/index.ts
20648
20975
  import path45 from "path";
@@ -20747,13 +21074,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
20747
21074
  const updatedContents = applyRewrites(rewrites);
20748
21075
  for (const [file, content] of updatedContents) {
20749
21076
  fs30.writeFileSync(file, content, "utf8");
20750
- console.log(chalk184.cyan(` Updated imports in ${path46.relative(cwd, file)}`));
21077
+ console.log(chalk183.cyan(` Updated imports in ${path46.relative(cwd, file)}`));
20751
21078
  }
20752
21079
  const destDir = path46.dirname(destPath);
20753
21080
  if (!fs30.existsSync(destDir)) fs30.mkdirSync(destDir, { recursive: true });
20754
21081
  fs30.renameSync(sourcePath, destPath);
20755
21082
  console.log(
20756
- chalk184.white(
21083
+ chalk183.white(
20757
21084
  ` Moved ${path46.relative(cwd, sourcePath)} \u2192 ${path46.relative(cwd, destPath)}`
20758
21085
  )
20759
21086
  );
@@ -20840,16 +21167,16 @@ function computeRenameRewrites(sourcePath, destPath) {
20840
21167
 
20841
21168
  // src/commands/refactor/rename/printRenamePreview.ts
20842
21169
  import path48 from "path";
20843
- import chalk185 from "chalk";
21170
+ import chalk184 from "chalk";
20844
21171
  function printRenamePreview(rewrites, cwd) {
20845
21172
  for (const rewrite of rewrites) {
20846
21173
  console.log(
20847
- chalk185.dim(
21174
+ chalk184.dim(
20848
21175
  ` ${path48.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
20849
21176
  )
20850
21177
  );
20851
21178
  }
20852
- console.log(chalk185.dim("Dry run. Use --apply to execute."));
21179
+ console.log(chalk184.dim("Dry run. Use --apply to execute."));
20853
21180
  }
20854
21181
 
20855
21182
  // src/commands/refactor/rename/index.ts
@@ -20860,20 +21187,20 @@ async function rename(source, destination, options2 = {}) {
20860
21187
  const relSource = path49.relative(cwd, sourcePath);
20861
21188
  const relDest = path49.relative(cwd, destPath);
20862
21189
  if (!fs31.existsSync(sourcePath)) {
20863
- console.log(chalk186.red(`File not found: ${source}`));
21190
+ console.log(chalk185.red(`File not found: ${source}`));
20864
21191
  process.exit(1);
20865
21192
  }
20866
21193
  if (destPath !== sourcePath && fs31.existsSync(destPath)) {
20867
- console.log(chalk186.red(`Destination already exists: ${destination}`));
21194
+ console.log(chalk185.red(`Destination already exists: ${destination}`));
20868
21195
  process.exit(1);
20869
21196
  }
20870
- console.log(chalk186.bold(`Rename: ${relSource} \u2192 ${relDest}`));
20871
- console.log(chalk186.dim("Loading project..."));
20872
- console.log(chalk186.dim("Scanning imports across the project..."));
21197
+ console.log(chalk185.bold(`Rename: ${relSource} \u2192 ${relDest}`));
21198
+ console.log(chalk185.dim("Loading project..."));
21199
+ console.log(chalk185.dim("Scanning imports across the project..."));
20873
21200
  const rewrites = computeRenameRewrites(sourcePath, destPath);
20874
21201
  const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
20875
21202
  console.log(
20876
- chalk186.dim(
21203
+ chalk185.dim(
20877
21204
  `${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
20878
21205
  )
20879
21206
  );
@@ -20882,11 +21209,11 @@ async function rename(source, destination, options2 = {}) {
20882
21209
  return;
20883
21210
  }
20884
21211
  applyRename(rewrites, sourcePath, destPath, cwd);
20885
- console.log(chalk186.green("Done"));
21212
+ console.log(chalk185.green("Done"));
20886
21213
  }
20887
21214
 
20888
21215
  // src/commands/refactor/renameSymbol/index.ts
20889
- import chalk187 from "chalk";
21216
+ import chalk186 from "chalk";
20890
21217
 
20891
21218
  // src/commands/refactor/renameSymbol/findSymbol.ts
20892
21219
  import { SyntaxKind as SyntaxKind15 } from "ts-morph";
@@ -20932,33 +21259,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
20932
21259
  const { project, sourceFile } = loadProjectFile(file);
20933
21260
  const symbol = findSymbol(sourceFile, oldName);
20934
21261
  if (!symbol) {
20935
- console.log(chalk187.red(`Symbol "${oldName}" not found in ${file}`));
21262
+ console.log(chalk186.red(`Symbol "${oldName}" not found in ${file}`));
20936
21263
  process.exit(1);
20937
21264
  }
20938
21265
  const grouped = groupReferences(symbol, cwd);
20939
21266
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
20940
21267
  console.log(
20941
- chalk187.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
21268
+ chalk186.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
20942
21269
  `)
20943
21270
  );
20944
21271
  for (const [refFile, lines] of grouped) {
20945
21272
  console.log(
20946
- ` ${chalk187.dim(refFile)}: lines ${chalk187.cyan(lines.join(", "))}`
21273
+ ` ${chalk186.dim(refFile)}: lines ${chalk186.cyan(lines.join(", "))}`
20947
21274
  );
20948
21275
  }
20949
21276
  if (options2.apply) {
20950
21277
  symbol.rename(newName);
20951
21278
  await project.save();
20952
- console.log(chalk187.green(`
21279
+ console.log(chalk186.green(`
20953
21280
  Renamed ${oldName} \u2192 ${newName}`));
20954
21281
  } else {
20955
- console.log(chalk187.dim("\nDry run. Use --apply to execute."));
21282
+ console.log(chalk186.dim("\nDry run. Use --apply to execute."));
20956
21283
  }
20957
21284
  }
20958
21285
 
20959
21286
  // src/commands/refactor/restructure/index.ts
20960
21287
  import path57 from "path";
20961
- import chalk190 from "chalk";
21288
+ import chalk189 from "chalk";
20962
21289
 
20963
21290
  // src/commands/refactor/restructure/clusterDirectories.ts
20964
21291
  import path51 from "path";
@@ -21037,50 +21364,50 @@ function clusterFiles(graph) {
21037
21364
 
21038
21365
  // src/commands/refactor/restructure/displayPlan.ts
21039
21366
  import path53 from "path";
21040
- import chalk188 from "chalk";
21367
+ import chalk187 from "chalk";
21041
21368
  function relPath(filePath) {
21042
21369
  return path53.relative(process.cwd(), filePath);
21043
21370
  }
21044
21371
  function displayMoves(plan2) {
21045
21372
  if (plan2.moves.length === 0) return;
21046
- console.log(chalk188.bold("\nFile moves:"));
21373
+ console.log(chalk187.bold("\nFile moves:"));
21047
21374
  for (const move2 of plan2.moves) {
21048
21375
  console.log(
21049
- ` ${chalk188.red(relPath(move2.from))} \u2192 ${chalk188.green(relPath(move2.to))}`
21376
+ ` ${chalk187.red(relPath(move2.from))} \u2192 ${chalk187.green(relPath(move2.to))}`
21050
21377
  );
21051
- console.log(chalk188.dim(` ${move2.reason}`));
21378
+ console.log(chalk187.dim(` ${move2.reason}`));
21052
21379
  }
21053
21380
  }
21054
21381
  function displayRewrites(rewrites) {
21055
21382
  if (rewrites.length === 0) return;
21056
21383
  const affectedFiles = new Set(rewrites.map((r) => r.file));
21057
- console.log(chalk188.bold(`
21384
+ console.log(chalk187.bold(`
21058
21385
  Import rewrites (${affectedFiles.size} files):`));
21059
21386
  for (const file of affectedFiles) {
21060
- console.log(` ${chalk188.cyan(relPath(file))}:`);
21387
+ console.log(` ${chalk187.cyan(relPath(file))}:`);
21061
21388
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
21062
21389
  (r) => r.file === file
21063
21390
  )) {
21064
21391
  console.log(
21065
- ` ${chalk188.red(`"${oldSpecifier}"`)} \u2192 ${chalk188.green(`"${newSpecifier}"`)}`
21392
+ ` ${chalk187.red(`"${oldSpecifier}"`)} \u2192 ${chalk187.green(`"${newSpecifier}"`)}`
21066
21393
  );
21067
21394
  }
21068
21395
  }
21069
21396
  }
21070
21397
  function displayPlan2(plan2) {
21071
21398
  if (plan2.warnings.length > 0) {
21072
- console.log(chalk188.yellow("\nWarnings:"));
21073
- for (const w of plan2.warnings) console.log(chalk188.yellow(` ${w}`));
21399
+ console.log(chalk187.yellow("\nWarnings:"));
21400
+ for (const w of plan2.warnings) console.log(chalk187.yellow(` ${w}`));
21074
21401
  }
21075
21402
  if (plan2.newDirectories.length > 0) {
21076
- console.log(chalk188.bold("\nNew directories:"));
21403
+ console.log(chalk187.bold("\nNew directories:"));
21077
21404
  for (const dir of plan2.newDirectories)
21078
- console.log(chalk188.green(` ${dir}/`));
21405
+ console.log(chalk187.green(` ${dir}/`));
21079
21406
  }
21080
21407
  displayMoves(plan2);
21081
21408
  displayRewrites(plan2.rewrites);
21082
21409
  console.log(
21083
- chalk188.dim(
21410
+ chalk187.dim(
21084
21411
  `
21085
21412
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
21086
21413
  )
@@ -21090,18 +21417,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
21090
21417
  // src/commands/refactor/restructure/executePlan.ts
21091
21418
  import fs32 from "fs";
21092
21419
  import path54 from "path";
21093
- import chalk189 from "chalk";
21420
+ import chalk188 from "chalk";
21094
21421
  function executePlan(plan2) {
21095
21422
  const updatedContents = applyRewrites(plan2.rewrites);
21096
21423
  for (const [file, content] of updatedContents) {
21097
21424
  fs32.writeFileSync(file, content, "utf8");
21098
21425
  console.log(
21099
- chalk189.cyan(` Rewrote imports in ${path54.relative(process.cwd(), file)}`)
21426
+ chalk188.cyan(` Rewrote imports in ${path54.relative(process.cwd(), file)}`)
21100
21427
  );
21101
21428
  }
21102
21429
  for (const dir of plan2.newDirectories) {
21103
21430
  fs32.mkdirSync(dir, { recursive: true });
21104
- console.log(chalk189.green(` Created ${path54.relative(process.cwd(), dir)}/`));
21431
+ console.log(chalk188.green(` Created ${path54.relative(process.cwd(), dir)}/`));
21105
21432
  }
21106
21433
  for (const move2 of plan2.moves) {
21107
21434
  const targetDir = path54.dirname(move2.to);
@@ -21110,7 +21437,7 @@ function executePlan(plan2) {
21110
21437
  }
21111
21438
  fs32.renameSync(move2.from, move2.to);
21112
21439
  console.log(
21113
- chalk189.white(
21440
+ chalk188.white(
21114
21441
  ` Moved ${path54.relative(process.cwd(), move2.from)} \u2192 ${path54.relative(process.cwd(), move2.to)}`
21115
21442
  )
21116
21443
  );
@@ -21125,7 +21452,7 @@ function removeEmptyDirectories(dirs) {
21125
21452
  if (entries.length === 0) {
21126
21453
  fs32.rmdirSync(dir);
21127
21454
  console.log(
21128
- chalk189.dim(
21455
+ chalk188.dim(
21129
21456
  ` Removed empty directory ${path54.relative(process.cwd(), dir)}`
21130
21457
  )
21131
21458
  );
@@ -21258,22 +21585,22 @@ async function restructure(pattern2, options2 = {}) {
21258
21585
  const targetPattern = pattern2 ?? "src";
21259
21586
  const files = findSourceFiles2(targetPattern);
21260
21587
  if (files.length === 0) {
21261
- console.log(chalk190.yellow("No files found matching pattern"));
21588
+ console.log(chalk189.yellow("No files found matching pattern"));
21262
21589
  return;
21263
21590
  }
21264
21591
  const tsConfigPath = findTsConfig(path57.resolve(files[0]));
21265
21592
  const plan2 = buildPlan3(files, tsConfigPath);
21266
21593
  if (plan2.moves.length === 0) {
21267
- console.log(chalk190.green("No restructuring needed"));
21594
+ console.log(chalk189.green("No restructuring needed"));
21268
21595
  return;
21269
21596
  }
21270
21597
  displayPlan2(plan2);
21271
21598
  if (options2.apply) {
21272
- console.log(chalk190.bold("\nApplying changes..."));
21599
+ console.log(chalk189.bold("\nApplying changes..."));
21273
21600
  executePlan(plan2);
21274
- console.log(chalk190.green("\nRestructuring complete"));
21601
+ console.log(chalk189.green("\nRestructuring complete"));
21275
21602
  } else {
21276
- console.log(chalk190.dim("\nDry run. Use --apply to execute."));
21603
+ console.log(chalk189.dim("\nDry run. Use --apply to execute."));
21277
21604
  }
21278
21605
  }
21279
21606
 
@@ -21323,7 +21650,7 @@ function registerRefactor(program2) {
21323
21650
  }
21324
21651
 
21325
21652
  // src/commands/review/review.ts
21326
- import { execFileSync as execFileSync8 } from "child_process";
21653
+ import { execFileSync as execFileSync9 } from "child_process";
21327
21654
 
21328
21655
  // src/commands/review/annotateDiffWithLineNumbers.ts
21329
21656
  var FILE_HEADER2 = /^\+\+\+ (?:b\/)?(.+)$/;
@@ -21856,18 +22183,18 @@ function partitionFindingsByDiff(findings, index3) {
21856
22183
  }
21857
22184
 
21858
22185
  // src/commands/review/warnOutOfDiff.ts
21859
- import chalk191 from "chalk";
22186
+ import chalk190 from "chalk";
21860
22187
  function warnOutOfDiff(outOfDiff) {
21861
22188
  if (outOfDiff.length === 0) return;
21862
22189
  console.warn(
21863
- chalk191.yellow(
22190
+ chalk190.yellow(
21864
22191
  `Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
21865
22192
  )
21866
22193
  );
21867
22194
  for (const finding of outOfDiff) {
21868
22195
  const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
21869
22196
  console.warn(
21870
- ` ${chalk191.yellow("\xB7")} ${finding.title} ${chalk191.dim(
22197
+ ` ${chalk190.yellow("\xB7")} ${finding.title} ${chalk190.dim(
21871
22198
  `(${finding.file}:${range})`
21872
22199
  )}`
21873
22200
  );
@@ -21886,18 +22213,18 @@ function selectInDiffFindings(lineBound, prDiff) {
21886
22213
  }
21887
22214
 
21888
22215
  // src/commands/review/warnUnlocated.ts
21889
- import chalk192 from "chalk";
22216
+ import chalk191 from "chalk";
21890
22217
  function warnUnlocated(unlocated) {
21891
22218
  if (unlocated.length === 0) return;
21892
22219
  console.warn(
21893
- chalk192.yellow(
22220
+ chalk191.yellow(
21894
22221
  `Skipped ${unlocated.length} finding(s) without a parseable file:line:`
21895
22222
  )
21896
22223
  );
21897
22224
  for (const finding of unlocated) {
21898
- const where = finding.location || chalk192.dim("missing");
22225
+ const where = finding.location || chalk191.dim("missing");
21899
22226
  console.warn(
21900
- ` ${chalk192.yellow("\xB7")} ${finding.title} ${chalk192.dim(`(${where})`)}`
22227
+ ` ${chalk191.yellow("\xB7")} ${finding.title} ${chalk191.dim(`(${where})`)}`
21901
22228
  );
21902
22229
  }
21903
22230
  }
@@ -23021,7 +23348,7 @@ function validateOptions(options2) {
23021
23348
  }
23022
23349
  function checkoutPr(number) {
23023
23350
  try {
23024
- execFileSync8("gh", ["pr", "checkout", number], { stdio: "inherit" });
23351
+ execFileSync9("gh", ["pr", "checkout", number], { stdio: "inherit" });
23025
23352
  } catch {
23026
23353
  console.error(`gh pr checkout ${number} failed; aborting.`);
23027
23354
  process.exit(1);
@@ -23069,7 +23396,7 @@ function registerReview(program2) {
23069
23396
  }
23070
23397
 
23071
23398
  // src/commands/seq/seqAuth.ts
23072
- import chalk194 from "chalk";
23399
+ import chalk193 from "chalk";
23073
23400
 
23074
23401
  // src/commands/seq/loadConnections.ts
23075
23402
  function loadConnections2() {
@@ -23098,10 +23425,10 @@ function setDefaultConnection(name) {
23098
23425
  }
23099
23426
 
23100
23427
  // src/shared/assertUniqueName.ts
23101
- import chalk193 from "chalk";
23428
+ import chalk192 from "chalk";
23102
23429
  function assertUniqueName(existingNames, name) {
23103
23430
  if (existingNames.includes(name)) {
23104
- console.error(chalk193.red(`Connection "${name}" already exists.`));
23431
+ console.error(chalk192.red(`Connection "${name}" already exists.`));
23105
23432
  process.exit(1);
23106
23433
  }
23107
23434
  }
@@ -23119,7 +23446,7 @@ async function promptConnection2(existingNames) {
23119
23446
  var seqAuth = createConnectionAuth({
23120
23447
  load: loadConnections2,
23121
23448
  save: saveConnections2,
23122
- format: (c) => `${chalk194.bold(c.name)} ${c.url}`,
23449
+ format: (c) => `${chalk193.bold(c.name)} ${c.url}`,
23123
23450
  promptNew: promptConnection2,
23124
23451
  onFirst: (c) => setDefaultConnection(c.name)
23125
23452
  });
@@ -23139,10 +23466,10 @@ var seqConfigHelp = [
23139
23466
  ];
23140
23467
 
23141
23468
  // src/commands/seq/seqQuery.ts
23142
- import chalk198 from "chalk";
23469
+ import chalk197 from "chalk";
23143
23470
 
23144
23471
  // src/commands/seq/fetchSeq.ts
23145
- import chalk195 from "chalk";
23472
+ import chalk194 from "chalk";
23146
23473
  async function fetchSeq(conn, path71, params) {
23147
23474
  const url = `${conn.url}${path71}?${params}`;
23148
23475
  const response = await fetch(url, {
@@ -23153,7 +23480,7 @@ async function fetchSeq(conn, path71, params) {
23153
23480
  });
23154
23481
  if (!response.ok) {
23155
23482
  const body = await response.text();
23156
- console.error(chalk195.red(`Seq returned ${response.status}: ${body}`));
23483
+ console.error(chalk194.red(`Seq returned ${response.status}: ${body}`));
23157
23484
  process.exit(1);
23158
23485
  }
23159
23486
  return response;
@@ -23212,23 +23539,23 @@ async function fetchSeqEvents(conn, params) {
23212
23539
  }
23213
23540
 
23214
23541
  // src/commands/seq/formatEvent.ts
23215
- import chalk196 from "chalk";
23542
+ import chalk195 from "chalk";
23216
23543
  function levelColor(level) {
23217
23544
  switch (level) {
23218
23545
  case "Fatal":
23219
- return chalk196.bgRed.white;
23546
+ return chalk195.bgRed.white;
23220
23547
  case "Error":
23221
- return chalk196.red;
23548
+ return chalk195.red;
23222
23549
  case "Warning":
23223
- return chalk196.yellow;
23550
+ return chalk195.yellow;
23224
23551
  case "Information":
23225
- return chalk196.cyan;
23552
+ return chalk195.cyan;
23226
23553
  case "Debug":
23227
- return chalk196.gray;
23554
+ return chalk195.gray;
23228
23555
  case "Verbose":
23229
- return chalk196.dim;
23556
+ return chalk195.dim;
23230
23557
  default:
23231
- return chalk196.white;
23558
+ return chalk195.white;
23232
23559
  }
23233
23560
  }
23234
23561
  function levelAbbrev(level) {
@@ -23269,12 +23596,12 @@ function formatTimestamp(iso) {
23269
23596
  function formatEvent(event) {
23270
23597
  const color = levelColor(event.Level);
23271
23598
  const abbrev = levelAbbrev(event.Level);
23272
- const ts8 = chalk196.dim(formatTimestamp(event.Timestamp));
23599
+ const ts8 = chalk195.dim(formatTimestamp(event.Timestamp));
23273
23600
  const msg = renderMessage(event);
23274
23601
  const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
23275
23602
  if (event.Exception) {
23276
23603
  for (const line of event.Exception.split("\n")) {
23277
- lines.push(chalk196.red(` ${line}`));
23604
+ lines.push(chalk195.red(` ${line}`));
23278
23605
  }
23279
23606
  }
23280
23607
  return lines.join("\n");
@@ -23307,11 +23634,11 @@ function rejectTimestampFilter(filter) {
23307
23634
  }
23308
23635
 
23309
23636
  // src/shared/resolveNamedConnection.ts
23310
- import chalk197 from "chalk";
23637
+ import chalk196 from "chalk";
23311
23638
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
23312
23639
  if (connections.length === 0) {
23313
23640
  console.error(
23314
- chalk197.red(
23641
+ chalk196.red(
23315
23642
  `No ${kind} connections configured. Run '${authCommand}' first.`
23316
23643
  )
23317
23644
  );
@@ -23320,7 +23647,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
23320
23647
  const target = requested ?? defaultName ?? connections[0].name;
23321
23648
  const connection = connections.find((c) => c.name === target);
23322
23649
  if (!connection) {
23323
- console.error(chalk197.red(`${kind} connection "${target}" not found.`));
23650
+ console.error(chalk196.red(`${kind} connection "${target}" not found.`));
23324
23651
  process.exit(1);
23325
23652
  }
23326
23653
  return connection;
@@ -23349,7 +23676,7 @@ async function seqQuery(filter, options2) {
23349
23676
  new URLSearchParams({ filter, count: String(count7) })
23350
23677
  );
23351
23678
  if (events.length === 0) {
23352
- console.log(chalk198.yellow("No events found."));
23679
+ console.log(chalk197.yellow("No events found."));
23353
23680
  return;
23354
23681
  }
23355
23682
  if (options2.json) {
@@ -23360,11 +23687,11 @@ async function seqQuery(filter, options2) {
23360
23687
  for (const event of chronological) {
23361
23688
  console.log(formatEvent(event));
23362
23689
  }
23363
- console.log(chalk198.dim(`
23690
+ console.log(chalk197.dim(`
23364
23691
  ${events.length} events`));
23365
23692
  if (events.length >= count7) {
23366
23693
  console.log(
23367
- chalk198.yellow(
23694
+ chalk197.yellow(
23368
23695
  `Results limited to ${count7}. Use --count to retrieve more.`
23369
23696
  )
23370
23697
  );
@@ -23372,10 +23699,10 @@ ${events.length} events`));
23372
23699
  }
23373
23700
 
23374
23701
  // src/shared/setNamedDefaultConnection.ts
23375
- import chalk199 from "chalk";
23702
+ import chalk198 from "chalk";
23376
23703
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
23377
23704
  if (!connections.find((c) => c.name === name)) {
23378
- console.error(chalk199.red(`Connection "${name}" not found.`));
23705
+ console.error(chalk198.red(`Connection "${name}" not found.`));
23379
23706
  process.exit(1);
23380
23707
  }
23381
23708
  setDefault(name);
@@ -23424,7 +23751,7 @@ function registerSignal(program2) {
23424
23751
  }
23425
23752
 
23426
23753
  // src/commands/sql/sqlAuth.ts
23427
- import chalk201 from "chalk";
23754
+ import chalk200 from "chalk";
23428
23755
 
23429
23756
  // src/commands/sql/loadConnections.ts
23430
23757
  function loadConnections3() {
@@ -23453,7 +23780,7 @@ function setDefaultConnection2(name) {
23453
23780
  }
23454
23781
 
23455
23782
  // src/commands/sql/promptConnection.ts
23456
- import chalk200 from "chalk";
23783
+ import chalk199 from "chalk";
23457
23784
  async function promptConnection3(existingNames) {
23458
23785
  const name = await promptInput("name", "Connection name:", "default");
23459
23786
  assertUniqueName(existingNames, name);
@@ -23461,7 +23788,7 @@ async function promptConnection3(existingNames) {
23461
23788
  const portStr = await promptInput("port", "Port:", "1433");
23462
23789
  const port = Number.parseInt(portStr, 10);
23463
23790
  if (!Number.isFinite(port)) {
23464
- console.error(chalk200.red(`Invalid port "${portStr}".`));
23791
+ console.error(chalk199.red(`Invalid port "${portStr}".`));
23465
23792
  process.exit(1);
23466
23793
  }
23467
23794
  const user = await promptInput("user", "User:");
@@ -23474,13 +23801,13 @@ async function promptConnection3(existingNames) {
23474
23801
  var sqlAuth = createConnectionAuth({
23475
23802
  load: loadConnections3,
23476
23803
  save: saveConnections3,
23477
- format: (c) => `${chalk201.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
23804
+ format: (c) => `${chalk200.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
23478
23805
  promptNew: promptConnection3,
23479
23806
  onFirst: (c) => setDefaultConnection2(c.name)
23480
23807
  });
23481
23808
 
23482
23809
  // src/commands/sql/printTable.ts
23483
- import chalk202 from "chalk";
23810
+ import chalk201 from "chalk";
23484
23811
  function formatCell(value) {
23485
23812
  if (value === null || value === void 0) return "";
23486
23813
  if (value instanceof Date) return value.toISOString();
@@ -23489,7 +23816,7 @@ function formatCell(value) {
23489
23816
  }
23490
23817
  function printTable(rows) {
23491
23818
  if (rows.length === 0) {
23492
- console.log(chalk202.yellow("(no rows)"));
23819
+ console.log(chalk201.yellow("(no rows)"));
23493
23820
  return;
23494
23821
  }
23495
23822
  const columns = Object.keys(rows[0]);
@@ -23497,13 +23824,13 @@ function printTable(rows) {
23497
23824
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
23498
23825
  );
23499
23826
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
23500
- console.log(chalk202.dim(header));
23501
- console.log(chalk202.dim("-".repeat(header.length)));
23827
+ console.log(chalk201.dim(header));
23828
+ console.log(chalk201.dim("-".repeat(header.length)));
23502
23829
  for (const row of rows) {
23503
23830
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
23504
23831
  console.log(line);
23505
23832
  }
23506
- console.log(chalk202.dim(`
23833
+ console.log(chalk201.dim(`
23507
23834
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
23508
23835
  }
23509
23836
 
@@ -23577,7 +23904,7 @@ var sqlConfigHelp = [
23577
23904
  ];
23578
23905
 
23579
23906
  // src/commands/sql/sqlMutate.ts
23580
- import chalk203 from "chalk";
23907
+ import chalk202 from "chalk";
23581
23908
 
23582
23909
  // src/commands/sql/isMutation.ts
23583
23910
  var MUTATION_KEYWORDS = [
@@ -23611,7 +23938,7 @@ function isMutation(sql25) {
23611
23938
  async function sqlMutate(query, connectionName) {
23612
23939
  if (!isMutation(query)) {
23613
23940
  console.error(
23614
- chalk203.red(
23941
+ chalk202.red(
23615
23942
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
23616
23943
  )
23617
23944
  );
@@ -23621,18 +23948,18 @@ async function sqlMutate(query, connectionName) {
23621
23948
  const pool = await sqlConnect(conn);
23622
23949
  try {
23623
23950
  const result = await pool.request().query(query);
23624
- console.log(chalk203.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
23951
+ console.log(chalk202.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
23625
23952
  } finally {
23626
23953
  await pool.close();
23627
23954
  }
23628
23955
  }
23629
23956
 
23630
23957
  // src/commands/sql/sqlQuery.ts
23631
- import chalk204 from "chalk";
23958
+ import chalk203 from "chalk";
23632
23959
  async function sqlQuery(query, connectionName) {
23633
23960
  if (isMutation(query)) {
23634
23961
  console.error(
23635
- chalk204.red(
23962
+ chalk203.red(
23636
23963
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
23637
23964
  )
23638
23965
  );
@@ -23647,7 +23974,7 @@ async function sqlQuery(query, connectionName) {
23647
23974
  printTable(rows);
23648
23975
  } else {
23649
23976
  console.log(
23650
- chalk204.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
23977
+ chalk203.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
23651
23978
  );
23652
23979
  }
23653
23980
  } finally {
@@ -24462,7 +24789,7 @@ function registerVoice(program2) {
24462
24789
 
24463
24790
  // src/commands/roam/auth.ts
24464
24791
  import { randomBytes } from "crypto";
24465
- import chalk205 from "chalk";
24792
+ import chalk204 from "chalk";
24466
24793
 
24467
24794
  // src/commands/roam/waitForCallback.ts
24468
24795
  import { createServer as createServer3 } from "http";
@@ -24593,13 +24920,13 @@ async function auth() {
24593
24920
  saveGlobalConfig(config);
24594
24921
  const state = randomBytes(16).toString("hex");
24595
24922
  console.log(
24596
- chalk205.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
24923
+ chalk204.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
24597
24924
  );
24598
- console.log(chalk205.white("http://localhost:14523/callback\n"));
24599
- console.log(chalk205.blue("Opening browser for authorization..."));
24600
- console.log(chalk205.dim("Waiting for authorization callback..."));
24925
+ console.log(chalk204.white("http://localhost:14523/callback\n"));
24926
+ console.log(chalk204.blue("Opening browser for authorization..."));
24927
+ console.log(chalk204.dim("Waiting for authorization callback..."));
24601
24928
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
24602
- console.log(chalk205.dim("Exchanging code for tokens..."));
24929
+ console.log(chalk204.dim("Exchanging code for tokens..."));
24603
24930
  const tokens = await exchangeToken({
24604
24931
  code,
24605
24932
  clientId,
@@ -24615,12 +24942,12 @@ async function auth() {
24615
24942
  };
24616
24943
  saveGlobalConfig(config);
24617
24944
  console.log(
24618
- chalk205.green("Roam credentials and tokens saved to ~/.assist.yml")
24945
+ chalk204.green("Roam credentials and tokens saved to ~/.assist.yml")
24619
24946
  );
24620
24947
  }
24621
24948
 
24622
24949
  // src/commands/roam/postRoamActivity.ts
24623
- import { execFileSync as execFileSync9 } from "child_process";
24950
+ import { execFileSync as execFileSync10 } from "child_process";
24624
24951
  import { readdirSync as readdirSync11, readFileSync as readFileSync47, statSync as statSync9 } from "fs";
24625
24952
  import { join as join63 } from "path";
24626
24953
  function findPortFile(roamDir) {
@@ -24653,7 +24980,7 @@ function postRoamActivity(app, event) {
24653
24980
  }
24654
24981
  const url = `http://127.0.0.1:${port}/api/v1/activity/${app}/${event}?pid=${app === "codex" ? 99998 : 99999}`;
24655
24982
  try {
24656
- execFileSync9("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
24983
+ execFileSync10("curl", ["-sf", "--max-time", "0.2", "-X", "POST", url], {
24657
24984
  stdio: "ignore"
24658
24985
  });
24659
24986
  } catch {
@@ -24862,13 +25189,13 @@ function runPreCommands(pre, cwd) {
24862
25189
  }
24863
25190
 
24864
25191
  // src/commands/run/spawnRunCommand.ts
24865
- import { execFileSync as execFileSync10, spawn as spawn8 } from "child_process";
25192
+ import { execFileSync as execFileSync11, spawn as spawn8 } from "child_process";
24866
25193
  import { existsSync as existsSync54 } from "fs";
24867
25194
  import { dirname as dirname27, join as join64, resolve as resolve15 } from "path";
24868
25195
  function resolveCommand2(command) {
24869
25196
  if (process.platform !== "win32" || command !== "bash") return command;
24870
25197
  try {
24871
- const gitPath = execFileSync10("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
25198
+ const gitPath = execFileSync11("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
24872
25199
  const gitRoot = resolve15(dirname27(gitPath), "..");
24873
25200
  const gitBash = join64(gitRoot, "bin", "bash.exe");
24874
25201
  if (existsSync54(gitBash)) return gitBash;
@@ -25158,7 +25485,7 @@ import { execSync as execSync58 } from "child_process";
25158
25485
  import { existsSync as existsSync56, mkdirSync as mkdirSync24, unlinkSync as unlinkSync21, writeFileSync as writeFileSync42 } from "fs";
25159
25486
  import { tmpdir as tmpdir8 } from "os";
25160
25487
  import { join as join67, resolve as resolve17 } from "path";
25161
- import chalk206 from "chalk";
25488
+ import chalk205 from "chalk";
25162
25489
 
25163
25490
  // src/commands/screenshot/captureWindowPs1.ts
25164
25491
  var captureWindowPs1 = `
@@ -25309,23 +25636,23 @@ function screenshot(processName) {
25309
25636
  const config = loadConfig();
25310
25637
  const outputDir = resolve17(config.screenshot.outputDir);
25311
25638
  const outputPath = buildOutputPath(outputDir, processName);
25312
- console.log(chalk206.gray(`Capturing window for process "${processName}" ...`));
25639
+ console.log(chalk205.gray(`Capturing window for process "${processName}" ...`));
25313
25640
  try {
25314
25641
  runPowerShellScript(processName, outputPath);
25315
- console.log(chalk206.green(`Screenshot saved: ${outputPath}`));
25642
+ console.log(chalk205.green(`Screenshot saved: ${outputPath}`));
25316
25643
  } catch (error) {
25317
25644
  const msg = error instanceof Error ? error.message : String(error);
25318
- console.error(chalk206.red(`Failed to capture screenshot: ${msg}`));
25645
+ console.error(chalk205.red(`Failed to capture screenshot: ${msg}`));
25319
25646
  process.exit(1);
25320
25647
  }
25321
25648
  }
25322
25649
 
25323
25650
  // src/commands/sessions/daemon/listDaemonPids.ts
25324
- import { execFileSync as execFileSync11 } from "child_process";
25651
+ import { execFileSync as execFileSync12 } from "child_process";
25325
25652
  function listDaemonPids() {
25326
25653
  if (process.platform === "win32") return [];
25327
25654
  try {
25328
- const out = execFileSync11("ps", ["-eo", "pid=,args="], {
25655
+ const out = execFileSync12("ps", ["-eo", "pid=,args="], {
25329
25656
  encoding: "utf8"
25330
25657
  });
25331
25658
  return out.split("\n").filter((line) => line.includes("assist") && / daemon run\b/.test(line)).map((line) => Number.parseInt(line.trim(), 10)).filter((pid) => Number.isInteger(pid));
@@ -25684,17 +26011,6 @@ function broadcast(clients, msg) {
25684
26011
  }
25685
26012
  }
25686
26013
 
25687
- // src/commands/sessions/daemon/originForCwd.ts
25688
- var cache = /* @__PURE__ */ new Map();
25689
- function originForCwd(cwd) {
25690
- if (!cwd) return void 0;
25691
- const cached = cache.get(cwd);
25692
- if (cached !== void 0) return cached;
25693
- const origin = getCurrentOrigin(cwd);
25694
- cache.set(cwd, origin);
25695
- return origin;
25696
- }
25697
-
25698
26014
  // src/commands/sessions/daemon/toSessionInfo.ts
25699
26015
  function toSessionInfo({
25700
26016
  id,
@@ -25744,6 +26060,7 @@ function toSessionInfo({
25744
26060
  remoteOrigin: serverOrigin ?? originForCwd(cwd),
25745
26061
  assistArgs,
25746
26062
  cwd,
26063
+ repoGroup: repoGroupForCwd(cwd),
25747
26064
  restored,
25748
26065
  error,
25749
26066
  activity: activity2,
@@ -26060,116 +26377,9 @@ function otherTreeHolders(sessions, session) {
26060
26377
  // src/commands/sessions/daemon/worktree/reapWorktree.ts
26061
26378
  import { existsSync as existsSync59 } from "fs";
26062
26379
 
26063
- // src/commands/sessions/daemon/worktree/git.ts
26064
- import { execFile as execFile7, execFileSync as execFileSync12 } from "child_process";
26065
- function isWindowsPath(cwd) {
26066
- return /^[A-Za-z]:[\\/]/.test(cwd);
26067
- }
26068
- function gitInvocation(cwd, args) {
26069
- const windows = isWindowsPath(cwd);
26070
- return {
26071
- file: windows ? "git.exe" : "git",
26072
- argv: windows ? ["-C", cwd, ...args] : args,
26073
- options: { encoding: "utf8", ...windows ? {} : { cwd } }
26074
- };
26075
- }
26076
- function git3(cwd, args) {
26077
- const { file, argv, options: options2 } = gitInvocation(cwd, args);
26078
- return new Promise((resolve20, reject) => {
26079
- execFile7(file, argv, options2, (error, stdout) => {
26080
- if (error) reject(error);
26081
- else resolve20(stdout.toString());
26082
- });
26083
- });
26084
- }
26085
- async function gitOrNull(cwd, args) {
26086
- try {
26087
- return (await git3(cwd, args)).trim() || null;
26088
- } catch {
26089
- return null;
26090
- }
26091
- }
26092
- async function gitResult(cwd, args) {
26093
- try {
26094
- return { ok: true, out: (await git3(cwd, args)).trim() };
26095
- } catch (error) {
26096
- return {
26097
- ok: false,
26098
- error: error instanceof Error ? error.message : String(error)
26099
- };
26100
- }
26101
- }
26102
- function gitSyncResult(cwd, args) {
26103
- try {
26104
- return { ok: true, out: gitSync(cwd, args).trim() };
26105
- } catch (error) {
26106
- return {
26107
- ok: false,
26108
- error: error instanceof Error ? error.message : String(error)
26109
- };
26110
- }
26111
- }
26112
- function gitSync(cwd, args) {
26113
- const { file, argv, options: options2 } = gitInvocation(cwd, args);
26114
- return execFileSync12(file, argv, {
26115
- ...options2,
26116
- stdio: ["pipe", "pipe", "pipe"]
26117
- }).toString();
26118
- }
26119
- function gitSyncOrNull(cwd, args) {
26120
- try {
26121
- return gitSync(cwd, args).trim() || null;
26122
- } catch {
26123
- return null;
26124
- }
26125
- }
26126
-
26127
- // src/commands/sessions/daemon/worktree/listWorktreePaths.ts
26128
- function listWorktreePaths(cwd) {
26129
- const out = gitSyncOrNull(cwd, ["worktree", "list", "--porcelain"]);
26130
- if (!out) return [];
26131
- return out.split("\n").filter((line) => line.startsWith("worktree ")).map((line) => line.slice("worktree ".length).trim());
26132
- }
26133
- function mainWorktree(cwd) {
26134
- return listWorktreePaths(cwd)[0] ?? null;
26135
- }
26136
- function listLocalBranches(cwd) {
26137
- const out = gitSyncOrNull(cwd, [
26138
- "for-each-ref",
26139
- "--format=%(refname:short)",
26140
- "refs/heads"
26141
- ]);
26142
- return out ? out.split("\n").map((line) => line.trim()) : [];
26143
- }
26144
- function gitCommonDir(cwd) {
26145
- return gitSyncOrNull(cwd, [
26146
- "rev-parse",
26147
- "--path-format=absolute",
26148
- "--git-common-dir"
26149
- ]);
26150
- }
26151
-
26152
- // src/commands/sessions/daemon/worktree/readWorktreeRegistry.ts
26153
- var REGISTRY_FILE = "worktrees.json";
26154
- function readWorktreeRegistry() {
26155
- const data = loadJson(REGISTRY_FILE);
26156
- return Object.entries(data).map(([path71, record]) => ({ path: path71, ...record }));
26157
- }
26158
- function recordWorktree(path71, clone, origin) {
26159
- const data = loadJson(REGISTRY_FILE);
26160
- data[path71] = { clone, origin };
26161
- saveJson(REGISTRY_FILE, data);
26162
- }
26163
- function forgetWorktree(path71) {
26164
- const data = loadJson(REGISTRY_FILE);
26165
- if (!(path71 in data)) return;
26166
- delete data[path71];
26167
- saveJson(REGISTRY_FILE, data);
26168
- }
26169
-
26170
26380
  // src/commands/sessions/daemon/worktree/removeTree.ts
26171
26381
  async function removeTree(clone, worktreePath, force) {
26172
- const remove2 = (forced) => git3(clone, [
26382
+ const remove2 = (forced) => git2(clone, [
26173
26383
  "worktree",
26174
26384
  "remove",
26175
26385
  ...forced ? ["--force"] : [],
@@ -26285,7 +26495,7 @@ async function deleteBranch(clone, branch2) {
26285
26495
  const current = await gitOrNull(clone, ["symbolic-ref", "--short", "HEAD"]);
26286
26496
  if (branch2 === current) return;
26287
26497
  try {
26288
- await git3(clone, ["branch", "-D", branch2]);
26498
+ await git2(clone, ["branch", "-D", branch2]);
26289
26499
  } catch {
26290
26500
  }
26291
26501
  }
@@ -26316,6 +26526,7 @@ function dismissSession(sessions, id) {
26316
26526
  var DISABLED = {
26317
26527
  enabled: false,
26318
26528
  install: true,
26529
+ commitBeforeManualChecks: false,
26319
26530
  copy: [".env", "settings.local.json", ".claude/settings.local.json"]
26320
26531
  };
26321
26532
  function worktreeConfigFor(cwd) {
@@ -27870,7 +28081,7 @@ async function reclaimVanishedWorktrees(clone, paths) {
27870
28081
  }
27871
28082
  async function pruneBookkeeping(clone) {
27872
28083
  try {
27873
- await git3(clone, ["worktree", "prune"]);
28084
+ await git2(clone, ["worktree", "prune"]);
27874
28085
  daemonLog(`worktree bookkeeping pruned for clone ${clone}`);
27875
28086
  } catch (error) {
27876
28087
  daemonLog(
@@ -27881,7 +28092,7 @@ async function pruneBookkeeping(clone) {
27881
28092
  async function reclaimBranch(clone, branch2) {
27882
28093
  if (!listLocalBranches(clone).includes(branch2)) return true;
27883
28094
  try {
27884
- await git3(clone, ["branch", "-d", branch2]);
28095
+ await git2(clone, ["branch", "-d", branch2]);
27885
28096
  daemonLog(`stale worktree branch ${branch2} pruned from clone ${clone}`);
27886
28097
  return true;
27887
28098
  } catch {
@@ -28617,14 +28828,6 @@ function runOnWindowsHost(command, timeoutMs) {
28617
28828
  });
28618
28829
  }
28619
28830
 
28620
- // src/commands/sessions/daemon/isWindowsCwd.ts
28621
- function isWindowsCwd(cwd) {
28622
- return /^[A-Za-z]:[\\/]/.test(cwd);
28623
- }
28624
- function shouldProxyToWindows(cwd) {
28625
- return detectPlatform() === "wsl" && isWindowsCwd(cwd);
28626
- }
28627
-
28628
28831
  // src/commands/sessions/daemon/isWindowsCreate.ts
28629
28832
  function isWindowsCreate(data) {
28630
28833
  return typeof data.cwd === "string" && shouldProxyToWindows(data.cwd);
@@ -29389,10 +29592,18 @@ function safeParse2(line) {
29389
29592
  }
29390
29593
  }
29391
29594
 
29595
+ // src/commands/sessions/daemon/withRepoGroups.ts
29596
+ function withRepoGroups(sessions) {
29597
+ return sessions.map((session) => {
29598
+ const repoGroup = repoGroupForCwd(session.cwd);
29599
+ return repoGroup ? { ...session, repoGroup } : session;
29600
+ });
29601
+ }
29602
+
29392
29603
  // src/commands/sessions/daemon/lifecycleHandlers.ts
29393
29604
  function handleHistory(client) {
29394
29605
  discoverSessions().then(
29395
- (sessions) => sendTo(client, { type: "history", sessions })
29606
+ (sessions) => sendTo(client, { type: "history", sessions: withRepoGroups(sessions) })
29396
29607
  );
29397
29608
  }
29398
29609
  function handleFetchTranscript(client, _manager, data) {
@@ -29741,6 +29952,11 @@ var sessionsConfigHelp = [
29741
29952
  setter: "assist config set worktree.install true -g --repo",
29742
29953
  note: "per-worktree dep install: true auto-detects the package manager, or give an explicit command; false to skip"
29743
29954
  },
29955
+ {
29956
+ key: "worktree.commitBeforeManualChecks",
29957
+ setter: "assist config set worktree.commitBeforeManualChecks true -g --repo",
29958
+ note: "phase prompts run /commit before asking the user to perform manual checks, so work is not left uncommitted in a reapable worktree (default off)"
29959
+ },
29744
29960
  {
29745
29961
  key: "worktree.copy",
29746
29962
  setter: "assist config set worktree.copy .env,.claude/settings.local.json -g --repo",
@@ -29750,7 +29966,7 @@ var sessionsConfigHelp = [
29750
29966
 
29751
29967
  // src/commands/sessions/summarise/index.ts
29752
29968
  import * as fs41 from "fs";
29753
- import chalk207 from "chalk";
29969
+ import chalk206 from "chalk";
29754
29970
 
29755
29971
  // src/commands/sessions/summarise/shared.ts
29756
29972
  import * as fs40 from "fs";
@@ -29824,22 +30040,22 @@ ${firstMessage}`);
29824
30040
  async function summarise2(options2) {
29825
30041
  const files = await discoverSessionFiles();
29826
30042
  if (files.length === 0) {
29827
- console.log(chalk207.yellow("No sessions found."));
30043
+ console.log(chalk206.yellow("No sessions found."));
29828
30044
  return;
29829
30045
  }
29830
30046
  const toProcess = selectCandidates(files, options2);
29831
30047
  if (toProcess.length === 0) {
29832
- console.log(chalk207.green("All sessions already summarised."));
30048
+ console.log(chalk206.green("All sessions already summarised."));
29833
30049
  return;
29834
30050
  }
29835
30051
  console.log(
29836
- chalk207.cyan(
30052
+ chalk206.cyan(
29837
30053
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
29838
30054
  )
29839
30055
  );
29840
30056
  const { succeeded, failed: failed2 } = processSessions(toProcess);
29841
30057
  console.log(
29842
- chalk207.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk207.yellow(`, ${failed2} skipped`) : "")
30058
+ chalk206.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk206.yellow(`, ${failed2} skipped`) : "")
29843
30059
  );
29844
30060
  }
29845
30061
  function selectCandidates(files, options2) {
@@ -29859,16 +30075,16 @@ function processSessions(files) {
29859
30075
  let failed2 = 0;
29860
30076
  for (let i = 0; i < files.length; i++) {
29861
30077
  const file = files[i];
29862
- process.stdout.write(chalk207.dim(` [${i + 1}/${files.length}] `));
30078
+ process.stdout.write(chalk206.dim(` [${i + 1}/${files.length}] `));
29863
30079
  const summary = summariseSession(file);
29864
30080
  if (summary) {
29865
30081
  writeSummary(file, summary);
29866
30082
  succeeded++;
29867
- process.stdout.write(`${chalk207.green("\u2713")} ${summary}
30083
+ process.stdout.write(`${chalk206.green("\u2713")} ${summary}
29868
30084
  `);
29869
30085
  } else {
29870
30086
  failed2++;
29871
- process.stdout.write(` ${chalk207.yellow("skip")}
30087
+ process.stdout.write(` ${chalk206.yellow("skip")}
29872
30088
  `);
29873
30089
  }
29874
30090
  }
@@ -29889,7 +30105,7 @@ function registerSessions(program2) {
29889
30105
  }
29890
30106
 
29891
30107
  // src/commands/statusLine.ts
29892
- import chalk209 from "chalk";
30108
+ import chalk208 from "chalk";
29893
30109
 
29894
30110
  // src/shared/contextLevel.ts
29895
30111
  function contextLevel(pct) {
@@ -29899,7 +30115,7 @@ function contextLevel(pct) {
29899
30115
  }
29900
30116
 
29901
30117
  // src/commands/buildLimitsSegment.ts
29902
- import chalk208 from "chalk";
30118
+ import chalk207 from "chalk";
29903
30119
 
29904
30120
  // src/shared/rateLimitLevel.ts
29905
30121
  var FIVE_HOUR_SECONDS = 5 * 3600;
@@ -29930,9 +30146,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
29930
30146
 
29931
30147
  // src/commands/buildLimitsSegment.ts
29932
30148
  var LEVEL_COLOR = {
29933
- ok: chalk208.green,
29934
- warn: chalk208.yellow,
29935
- over: chalk208.red
30149
+ ok: chalk207.green,
30150
+ warn: chalk207.yellow,
30151
+ over: chalk207.red
29936
30152
  };
29937
30153
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
29938
30154
  const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
@@ -30028,7 +30244,7 @@ async function relayUsage(claudeSessionId, transcriptPath, usedPct) {
30028
30244
  }
30029
30245
 
30030
30246
  // src/commands/statusLine.ts
30031
- chalk209.level = 3;
30247
+ chalk208.level = 3;
30032
30248
  function formatNumber(num) {
30033
30249
  return num.toLocaleString("en-US");
30034
30250
  }
@@ -30036,9 +30252,9 @@ function colorizePercent(pct) {
30036
30252
  const label2 = `${Math.round(pct)}%`;
30037
30253
  switch (contextLevel(pct)) {
30038
30254
  case "red":
30039
- return chalk209.red(label2);
30255
+ return chalk208.red(label2);
30040
30256
  case "yellow":
30041
- return chalk209.yellow(label2);
30257
+ return chalk208.yellow(label2);
30042
30258
  default:
30043
30259
  return label2;
30044
30260
  }
@@ -30051,7 +30267,7 @@ async function statusLine() {
30051
30267
  const usedPct = data.context_window.used_percentage ?? 0;
30052
30268
  const dir = data.workspace?.current_dir ?? data.cwd;
30053
30269
  const branch2 = dir ? readGitBranch(toGitCwd(dir)) : null;
30054
- const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk209.cyan(branch2)} | ` : "";
30270
+ const branchSegment = branch2 ? `\u{1F33F}\uFE0F ${chalk208.cyan(branch2)} | ` : "";
30055
30271
  console.log(
30056
30272
  `${branchSegment}${model} | Tokens - ${formatNumber(totalIn)} \u2191 : ${formatNumber(totalOut)} \u2193 | Context - ${colorizePercent(usedPct)}${buildLimitsSegment(data.rate_limits)}`
30057
30273
  );
@@ -30072,14 +30288,14 @@ import { fileURLToPath as fileURLToPath9 } from "url";
30072
30288
  // src/commands/sync/syncClaudeMd.ts
30073
30289
  import * as fs42 from "fs";
30074
30290
  import * as path61 from "path";
30075
- import chalk211 from "chalk";
30291
+ import chalk210 from "chalk";
30076
30292
 
30077
30293
  // src/commands/sync/printAutoConfirmHint.ts
30078
- import chalk210 from "chalk";
30294
+ import chalk209 from "chalk";
30079
30295
  var autoConfirmHintCommand = "assist config set sync.autoConfirm true --global";
30080
30296
  function printAutoConfirmHint() {
30081
30297
  console.log(
30082
- chalk210.dim(
30298
+ chalk209.dim(
30083
30299
  `Tip: run \`${autoConfirmHintCommand}\` to overwrite automatically next time`
30084
30300
  )
30085
30301
  );
@@ -30095,14 +30311,14 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
30095
30311
  const targetContent = fs42.readFileSync(target, "utf8");
30096
30312
  if (sourceContent !== targetContent) {
30097
30313
  console.log(
30098
- chalk211.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
30314
+ chalk210.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
30099
30315
  );
30100
30316
  console.log();
30101
30317
  printDiff(targetContent, sourceContent);
30102
30318
  if (!options2?.yes) {
30103
30319
  printAutoConfirmHint();
30104
30320
  const confirm = await promptConfirm(
30105
- chalk211.red("Overwrite existing CLAUDE.md?"),
30321
+ chalk210.red("Overwrite existing CLAUDE.md?"),
30106
30322
  false
30107
30323
  );
30108
30324
  if (!confirm) {
@@ -30297,7 +30513,7 @@ function syncPi(claudeDir) {
30297
30513
  // src/commands/sync/syncSettings.ts
30298
30514
  import * as fs47 from "fs";
30299
30515
  import * as path68 from "path";
30300
- import chalk212 from "chalk";
30516
+ import chalk211 from "chalk";
30301
30517
  async function syncSettings(claudeDir, targetBase, options2) {
30302
30518
  const source = path68.join(claudeDir, "settings.json");
30303
30519
  const target = path68.join(targetBase, "settings.json");
@@ -30316,7 +30532,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
30316
30532
  if (mergedContent !== normalizedTarget) {
30317
30533
  if (!options2?.yes) {
30318
30534
  console.log(
30319
- chalk212.yellow(
30535
+ chalk211.yellow(
30320
30536
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
30321
30537
  )
30322
30538
  );
@@ -30324,7 +30540,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
30324
30540
  printDiff(targetContent, mergedContent);
30325
30541
  printAutoConfirmHint();
30326
30542
  const confirm = await promptConfirm(
30327
- chalk212.red("Overwrite existing settings.json?"),
30543
+ chalk211.red("Overwrite existing settings.json?"),
30328
30544
  false
30329
30545
  );
30330
30546
  if (!confirm) {
@@ -30423,10 +30639,10 @@ async function update2() {
30423
30639
  }
30424
30640
 
30425
30641
  // src/reportCliError.ts
30426
- import chalk213 from "chalk";
30642
+ import chalk212 from "chalk";
30427
30643
  function reportCliError(error) {
30428
30644
  if (error instanceof InvalidItemIdError || error instanceof AmbiguousRepoConfigError || error instanceof UnknownRepoConfigError) {
30429
- console.error(chalk213.red(error.message));
30645
+ console.error(chalk212.red(error.message));
30430
30646
  } else {
30431
30647
  console.error(error);
30432
30648
  }