@staff0rd/assist 0.305.4 → 0.307.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.305.4",
9
+ version: "0.307.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -2178,7 +2178,7 @@ function flushIfFailed(exitCode, chunks) {
2178
2178
 
2179
2179
  // src/commands/verify/run/runAllEntries.ts
2180
2180
  function runEntry(entry, onComplete) {
2181
- return new Promise((resolve16) => {
2181
+ return new Promise((resolve17) => {
2182
2182
  const child = spawnCommand(
2183
2183
  entry.fullCommand,
2184
2184
  entry.cwd,
@@ -2190,7 +2190,7 @@ function runEntry(entry, onComplete) {
2190
2190
  const exitCode = code ?? 1;
2191
2191
  flushIfFailed(exitCode, chunks);
2192
2192
  onComplete?.(exitCode);
2193
- resolve16({ script: entry.name, code: exitCode });
2193
+ resolve17({ script: entry.name, code: exitCode });
2194
2194
  });
2195
2195
  });
2196
2196
  }
@@ -2943,8 +2943,8 @@ function spawnClaude(prompt, options2 = {}) {
2943
2943
  stdio: "inherit",
2944
2944
  env
2945
2945
  });
2946
- const done2 = new Promise((resolve16, reject) => {
2947
- child.on("close", (code) => resolve16(code ?? 0));
2946
+ const done2 = new Promise((resolve17, reject) => {
2947
+ child.on("close", (code) => resolve17(code ?? 0));
2948
2948
  child.on("error", reject);
2949
2949
  });
2950
2950
  return { child, done: done2 };
@@ -4752,9 +4752,9 @@ import {
4752
4752
  // src/commands/sessions/daemon/connectToDaemon.ts
4753
4753
  import * as net from "net";
4754
4754
  function connectToDaemon() {
4755
- return new Promise((resolve16, reject) => {
4755
+ return new Promise((resolve17, reject) => {
4756
4756
  const socket = net.connect(daemonPaths.socket);
4757
- socket.once("connect", () => resolve16(socket));
4757
+ socket.once("connect", () => resolve17(socket));
4758
4758
  socket.once("error", reject);
4759
4759
  });
4760
4760
  }
@@ -4834,7 +4834,7 @@ function spawnDaemon(reason) {
4834
4834
  child.unref();
4835
4835
  }
4836
4836
  function delay(ms) {
4837
- return new Promise((resolve16) => setTimeout(resolve16, ms));
4837
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
4838
4838
  }
4839
4839
 
4840
4840
  // src/commands/sessions/web/handleRequest.ts
@@ -4972,20 +4972,17 @@ async function loadVisibleItems(req) {
4972
4972
  return loaded.filter((item) => !completedStatuses.has(item.status));
4973
4973
  }
4974
4974
 
4975
- // src/commands/backlog/web/parseItemBody.ts
4975
+ // src/commands/backlog/web/parseStatusBody.ts
4976
4976
  function readBody(req) {
4977
- return new Promise((resolve16, reject) => {
4977
+ return new Promise((resolve17, reject) => {
4978
4978
  let body = "";
4979
4979
  req.on("data", (chunk) => {
4980
4980
  body += chunk.toString();
4981
4981
  });
4982
- req.on("end", () => resolve16(body));
4982
+ req.on("end", () => resolve17(body));
4983
4983
  req.on("error", reject);
4984
4984
  });
4985
4985
  }
4986
- async function parseItemBody(req) {
4987
- return JSON.parse(await readBody(req));
4988
- }
4989
4986
  async function parseStatusBody(req) {
4990
4987
  return JSON.parse(await readBody(req));
4991
4988
  }
@@ -5099,22 +5096,6 @@ function validateRewind(item, plan2, phase) {
5099
5096
  return void 0;
5100
5097
  }
5101
5098
 
5102
- // src/commands/backlog/web/updateItem.ts
5103
- import { eq as eq15 } from "drizzle-orm";
5104
- async function updateItem(req, res, id2) {
5105
- const body = await parseItemBody(req);
5106
- const result = await findItemOr404(res, id2);
5107
- if (!result) return;
5108
- const { orm } = result;
5109
- await orm.update(items).set({
5110
- type: body.type ?? result.item.type,
5111
- name: body.name,
5112
- description: body.description ?? null,
5113
- acceptanceCriteria: JSON.stringify(body.acceptanceCriteria ?? [])
5114
- }).where(eq15(items.id, id2));
5115
- respondJson(res, 200, await loadItem(orm, id2));
5116
- }
5117
-
5118
5099
  // src/commands/backlog/web/handleItemRoute.ts
5119
5100
  var id = (match, group = 1) => Number.parseInt(match[group], 10);
5120
5101
  var routes = [
@@ -5138,11 +5119,6 @@ var routes = [
5138
5119
  method: "GET",
5139
5120
  run: (_req, res, m) => getItemById(res, id(m))
5140
5121
  },
5141
- {
5142
- pattern: /^\/api\/items\/(\d+)$/,
5143
- method: "PUT",
5144
- run: (req, res, m) => updateItem(req, res, id(m))
5145
- },
5146
5122
  {
5147
5123
  pattern: /^\/api\/items\/(\d+)$/,
5148
5124
  method: "PATCH",
@@ -5527,17 +5503,17 @@ async function stopDaemon() {
5527
5503
  }
5528
5504
  }
5529
5505
  function closedBeforeTimeout(socket) {
5530
- return new Promise((resolve16) => {
5506
+ return new Promise((resolve17) => {
5531
5507
  const timer = setTimeout(() => {
5532
5508
  socket.destroy();
5533
- resolve16(false);
5509
+ resolve17(false);
5534
5510
  }, STOP_TIMEOUT_MS);
5535
5511
  socket.resume();
5536
5512
  socket.on("error", () => {
5537
5513
  });
5538
5514
  socket.once("close", () => {
5539
5515
  clearTimeout(timer);
5540
- resolve16(true);
5516
+ resolve17(true);
5541
5517
  });
5542
5518
  });
5543
5519
  }
@@ -5588,8 +5564,8 @@ async function restartWeb(req, res, deps2 = {}) {
5588
5564
  respondJson(res, 400, { error: "Invalid target" });
5589
5565
  return;
5590
5566
  }
5591
- await new Promise((resolve16) => {
5592
- res.once("finish", resolve16);
5567
+ await new Promise((resolve17) => {
5568
+ res.once("finish", resolve17);
5593
5569
  respondJson(res, 200, { ok: true });
5594
5570
  });
5595
5571
  if (target === "daemon" || target === "both") {
@@ -6486,22 +6462,22 @@ async function add(options2) {
6486
6462
  import chalk58 from "chalk";
6487
6463
 
6488
6464
  // src/commands/backlog/insertPhaseAt.ts
6489
- import { count, eq as eq17 } from "drizzle-orm";
6465
+ import { count, eq as eq16 } from "drizzle-orm";
6490
6466
 
6491
6467
  // src/commands/backlog/shiftPhasesUp.ts
6492
- import { and as and3, desc as desc2, eq as eq16, gte } from "drizzle-orm";
6468
+ import { and as and3, desc as desc2, eq as eq15, gte } from "drizzle-orm";
6493
6469
  async function shiftPhasesUp(db, itemId, fromIdx) {
6494
- const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(eq16(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(desc2(planPhases.idx));
6470
+ const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and3(eq15(planPhases.itemId, itemId), gte(planPhases.idx, fromIdx))).orderBy(desc2(planPhases.idx));
6495
6471
  for (const p of toShift) {
6496
- await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and3(eq16(planTasks.itemId, itemId), eq16(planTasks.phaseIdx, p.idx)));
6497
- await db.update(planPhases).set({ idx: p.idx + 1 }).where(and3(eq16(planPhases.itemId, itemId), eq16(planPhases.idx, p.idx)));
6472
+ await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and3(eq15(planTasks.itemId, itemId), eq15(planTasks.phaseIdx, p.idx)));
6473
+ await db.update(planPhases).set({ idx: p.idx + 1 }).where(and3(eq15(planPhases.itemId, itemId), eq15(planPhases.idx, p.idx)));
6498
6474
  }
6499
6475
  }
6500
6476
 
6501
6477
  // src/commands/backlog/insertPhaseAt.ts
6502
6478
  async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, currentPhase) {
6503
6479
  await orm.transaction(async (tx) => {
6504
- const [row] = await tx.select({ cnt: count() }).from(planPhases).where(eq17(planPhases.itemId, itemId));
6480
+ const [row] = await tx.select({ cnt: count() }).from(planPhases).where(eq16(planPhases.itemId, itemId));
6505
6481
  const phaseCount = row?.cnt ?? 0;
6506
6482
  await shiftPhasesUp(tx, itemId, phaseIdx);
6507
6483
  await tx.insert(planPhases).values({ itemId, idx: phaseIdx, name, manualChecks });
@@ -6510,16 +6486,16 @@ async function insertPhaseAt(orm, itemId, phaseIdx, name, tasks, manualChecks, c
6510
6486
  }
6511
6487
  if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
6512
6488
  const atReviewSlot = currentPhase - 1 >= phaseCount;
6513
- await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(eq17(items.id, itemId));
6489
+ await tx.update(items).set({ currentPhase: atReviewSlot ? phaseIdx + 1 : currentPhase + 1 }).where(eq16(items.id, itemId));
6514
6490
  }
6515
6491
  });
6516
6492
  }
6517
6493
 
6518
6494
  // src/commands/backlog/resolveInsertPosition.ts
6519
6495
  import chalk57 from "chalk";
6520
- import { count as count2, eq as eq18 } from "drizzle-orm";
6496
+ import { count as count2, eq as eq17 } from "drizzle-orm";
6521
6497
  async function resolveInsertPosition(orm, itemId, position) {
6522
- const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq18(planPhases.itemId, itemId));
6498
+ const [row] = await orm.select({ cnt: count2() }).from(planPhases).where(eq17(planPhases.itemId, itemId));
6523
6499
  const phaseCount = row?.cnt ?? 0;
6524
6500
  if (position === void 0) return phaseCount;
6525
6501
  const pos = Number.parseInt(position, 10);
@@ -6680,9 +6656,9 @@ function hasCycle(adjacency, fromId, toId) {
6680
6656
  }
6681
6657
 
6682
6658
  // src/commands/backlog/loadDependencyGraph.ts
6683
- import { eq as eq19 } from "drizzle-orm";
6659
+ import { eq as eq18 } from "drizzle-orm";
6684
6660
  async function loadDependencyGraph(orm) {
6685
- const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq19(links.type, "depends-on"));
6661
+ const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq18(links.type, "depends-on"));
6686
6662
  const graph = /* @__PURE__ */ new Map();
6687
6663
  for (const { itemId, targetId } of rows) {
6688
6664
  const bucket = graph.get(itemId);
@@ -6745,7 +6721,7 @@ async function link(fromId, toId, opts) {
6745
6721
 
6746
6722
  // src/commands/backlog/unlink.ts
6747
6723
  import chalk62 from "chalk";
6748
- import { and as and4, eq as eq20 } from "drizzle-orm";
6724
+ import { and as and4, eq as eq19 } from "drizzle-orm";
6749
6725
  async function unlink(fromId, toId) {
6750
6726
  const fromNum = Number.parseInt(fromId, 10);
6751
6727
  const toNum = Number.parseInt(toId, 10);
@@ -6763,7 +6739,7 @@ async function unlink(fromId, toId) {
6763
6739
  console.log(chalk62.yellow(`No link from #${fromId} to #${toId} found.`));
6764
6740
  return;
6765
6741
  }
6766
- await orm.delete(links).where(and4(eq20(links.itemId, fromNum), eq20(links.targetId, toNum)));
6742
+ await orm.delete(links).where(and4(eq19(links.itemId, fromNum), eq19(links.targetId, toNum)));
6767
6743
  console.log(chalk62.green(`Removed link from #${fromId} to #${toId}.`));
6768
6744
  }
6769
6745
 
@@ -6779,7 +6755,7 @@ function registerLinkCommands(cmd) {
6779
6755
 
6780
6756
  // src/commands/backlog/move-repo/index.ts
6781
6757
  import chalk64 from "chalk";
6782
- import { eq as eq22 } from "drizzle-orm";
6758
+ import { eq as eq21 } from "drizzle-orm";
6783
6759
 
6784
6760
  // src/commands/backlog/move-repo/confirmMove.ts
6785
6761
  import chalk63 from "chalk";
@@ -6794,9 +6770,9 @@ async function confirmMove(cnt, oldOrigin, newOrigin) {
6794
6770
  }
6795
6771
 
6796
6772
  // src/commands/backlog/move-repo/countByOrigin.ts
6797
- import { count as count3, eq as eq21 } from "drizzle-orm";
6773
+ import { count as count3, eq as eq20 } from "drizzle-orm";
6798
6774
  async function countByOrigin(orm, origin) {
6799
- const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(eq21(items.origin, origin));
6775
+ const [{ cnt }] = await orm.select({ cnt: count3() }).from(items).where(eq20(items.origin, origin));
6800
6776
  return cnt;
6801
6777
  }
6802
6778
 
@@ -6839,7 +6815,7 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
6839
6815
  console.log(chalk64.yellow("Move cancelled; no changes made."));
6840
6816
  return;
6841
6817
  }
6842
- await orm.update(items).set({ origin: newOrigin }).where(eq22(items.origin, oldOrigin));
6818
+ await orm.update(items).set({ origin: newOrigin }).where(eq21(items.origin, oldOrigin));
6843
6819
  console.log(
6844
6820
  chalk64.green(
6845
6821
  `Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
@@ -7173,10 +7149,10 @@ async function start(id2) {
7173
7149
 
7174
7150
  // src/commands/backlog/stop/index.ts
7175
7151
  import chalk75 from "chalk";
7176
- import { and as and5, eq as eq23 } from "drizzle-orm";
7152
+ import { and as and5, eq as eq22 } from "drizzle-orm";
7177
7153
  async function stop() {
7178
7154
  const { orm } = await getReady();
7179
- const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and5(eq23(items.status, "in-progress"), eq23(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
7155
+ const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and5(eq22(items.status, "in-progress"), eq22(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
7180
7156
  if (stopped.length === 0) {
7181
7157
  console.log(chalk75.yellow("No in-progress items to stop."));
7182
7158
  return;
@@ -7222,18 +7198,18 @@ function registerStatusCommands(cmd) {
7222
7198
 
7223
7199
  // src/commands/backlog/removePhase.ts
7224
7200
  import chalk79 from "chalk";
7225
- import { and as and8, eq as eq26 } from "drizzle-orm";
7201
+ import { and as and8, eq as eq25 } from "drizzle-orm";
7226
7202
 
7227
7203
  // src/commands/backlog/findPhase.ts
7228
7204
  import chalk78 from "chalk";
7229
- import { and as and6, count as count4, eq as eq24 } from "drizzle-orm";
7205
+ import { and as and6, count as count4, eq as eq23 } from "drizzle-orm";
7230
7206
  async function findPhase(id2, phase) {
7231
7207
  const found = await findOneItem(id2);
7232
7208
  if (!found) return void 0;
7233
7209
  const { orm, item } = found;
7234
7210
  const itemId = item.id;
7235
7211
  const phaseIdx = Number.parseInt(phase, 10) - 1;
7236
- const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and6(eq24(planPhases.itemId, itemId), eq24(planPhases.idx, phaseIdx)));
7212
+ const [row] = await orm.select({ cnt: count4() }).from(planPhases).where(and6(eq23(planPhases.itemId, itemId), eq23(planPhases.idx, phaseIdx)));
7237
7213
  if (!row || row.cnt === 0) {
7238
7214
  console.log(
7239
7215
  chalk78.red(`Phase ${phaseIdx + 1} not found on item #${itemId}.`)
@@ -7245,14 +7221,14 @@ async function findPhase(id2, phase) {
7245
7221
  }
7246
7222
 
7247
7223
  // src/commands/backlog/reindexPhases.ts
7248
- import { and as and7, asc as asc6, count as count5, eq as eq25 } from "drizzle-orm";
7224
+ import { and as and7, asc as asc6, count as count5, eq as eq24 } from "drizzle-orm";
7249
7225
  async function reindexPhases(db, itemId) {
7250
- const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq25(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
7226
+ const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq24(planPhases.itemId, itemId)).orderBy(asc6(planPhases.idx));
7251
7227
  for (let i = 0; i < remaining.length; i++) {
7252
7228
  const oldIdx = remaining[i].idx;
7253
7229
  if (oldIdx === i) continue;
7254
- await db.update(planTasks).set({ phaseIdx: i }).where(and7(eq25(planTasks.itemId, itemId), eq25(planTasks.phaseIdx, oldIdx)));
7255
- await db.update(planPhases).set({ idx: i }).where(and7(eq25(planPhases.itemId, itemId), eq25(planPhases.idx, oldIdx)));
7230
+ await db.update(planTasks).set({ phaseIdx: i }).where(and7(eq24(planTasks.itemId, itemId), eq24(planTasks.phaseIdx, oldIdx)));
7231
+ await db.update(planPhases).set({ idx: i }).where(and7(eq24(planPhases.itemId, itemId), eq24(planPhases.idx, oldIdx)));
7256
7232
  }
7257
7233
  }
7258
7234
  async function adjustCurrentPhase(db, item, removedIdx) {
@@ -7260,13 +7236,13 @@ async function adjustCurrentPhase(db, item, removedIdx) {
7260
7236
  if (currentPhase === void 0) return;
7261
7237
  const currentIdx = currentPhase - 1;
7262
7238
  if (removedIdx < currentIdx) {
7263
- await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq25(items.id, item.id));
7239
+ await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq24(items.id, item.id));
7264
7240
  return;
7265
7241
  }
7266
7242
  if (removedIdx !== currentIdx) return;
7267
- const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq25(planPhases.itemId, item.id));
7243
+ const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq24(planPhases.itemId, item.id));
7268
7244
  const cnt = row?.cnt ?? 0;
7269
- await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq25(items.id, item.id));
7245
+ await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq24(items.id, item.id));
7270
7246
  }
7271
7247
 
7272
7248
  // src/commands/backlog/removePhase.ts
@@ -7276,9 +7252,9 @@ async function removePhase(id2, phase) {
7276
7252
  const { item, orm, itemId, phaseIdx } = found;
7277
7253
  await orm.transaction(async (tx) => {
7278
7254
  await tx.delete(planTasks).where(
7279
- and8(eq26(planTasks.itemId, itemId), eq26(planTasks.phaseIdx, phaseIdx))
7255
+ and8(eq25(planTasks.itemId, itemId), eq25(planTasks.phaseIdx, phaseIdx))
7280
7256
  );
7281
- await tx.delete(planPhases).where(and8(eq26(planPhases.itemId, itemId), eq26(planPhases.idx, phaseIdx)));
7257
+ await tx.delete(planPhases).where(and8(eq25(planPhases.itemId, itemId), eq25(planPhases.idx, phaseIdx)));
7282
7258
  await reindexPhases(tx, itemId);
7283
7259
  await adjustCurrentPhase(tx, item, phaseIdx);
7284
7260
  });
@@ -7289,7 +7265,7 @@ async function removePhase(id2, phase) {
7289
7265
 
7290
7266
  // src/commands/backlog/update/index.ts
7291
7267
  import chalk81 from "chalk";
7292
- import { eq as eq27 } from "drizzle-orm";
7268
+ import { eq as eq26 } from "drizzle-orm";
7293
7269
 
7294
7270
  // src/commands/backlog/update/parseListIndex.ts
7295
7271
  function parseListIndex(raw, length, label2) {
@@ -7423,7 +7399,7 @@ async function update(id2, options2) {
7423
7399
  if (!built) return;
7424
7400
  const { orm } = found;
7425
7401
  const itemId = found.item.id;
7426
- await orm.update(items).set(built.set).where(eq27(items.id, itemId));
7402
+ await orm.update(items).set(built.set).where(eq26(items.id, itemId));
7427
7403
  console.log(chalk81.green(`Updated ${built.fields} on item #${itemId}.`));
7428
7404
  }
7429
7405
 
@@ -7431,22 +7407,22 @@ async function update(id2, options2) {
7431
7407
  import chalk82 from "chalk";
7432
7408
 
7433
7409
  // src/commands/backlog/applyPhaseUpdate.ts
7434
- import { and as and9, eq as eq28 } from "drizzle-orm";
7410
+ import { and as and9, eq as eq27 } from "drizzle-orm";
7435
7411
  async function applyPhaseUpdate(orm, itemId, phaseIdx, fields) {
7436
7412
  await orm.transaction(async (tx) => {
7437
7413
  if (fields.name) {
7438
7414
  await tx.update(planPhases).set({ name: fields.name }).where(
7439
- and9(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx))
7415
+ and9(eq27(planPhases.itemId, itemId), eq27(planPhases.idx, phaseIdx))
7440
7416
  );
7441
7417
  }
7442
7418
  if (fields.manualCheck) {
7443
7419
  await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
7444
- and9(eq28(planPhases.itemId, itemId), eq28(planPhases.idx, phaseIdx))
7420
+ and9(eq27(planPhases.itemId, itemId), eq27(planPhases.idx, phaseIdx))
7445
7421
  );
7446
7422
  }
7447
7423
  if (fields.task) {
7448
7424
  await tx.delete(planTasks).where(
7449
- and9(eq28(planTasks.itemId, itemId), eq28(planTasks.phaseIdx, phaseIdx))
7425
+ and9(eq27(planTasks.itemId, itemId), eq27(planTasks.phaseIdx, phaseIdx))
7450
7426
  );
7451
7427
  if (fields.task.length) {
7452
7428
  await tx.insert(planTasks).values(
@@ -8363,12 +8339,12 @@ function hasSubcommands(helpText) {
8363
8339
  // src/commands/permitCliReads/runHelp.ts
8364
8340
  import { exec as exec2 } from "child_process";
8365
8341
  function runHelp(args) {
8366
- return new Promise((resolve16) => {
8342
+ return new Promise((resolve17) => {
8367
8343
  exec2(
8368
8344
  `${args.join(" ")} --help`,
8369
8345
  { encoding: "utf8", timeout: 3e4 },
8370
8346
  (_err, stdout, stderr) => {
8371
- resolve16(stdout || stderr || "");
8347
+ resolve17(stdout || stderr || "");
8372
8348
  }
8373
8349
  );
8374
8350
  });
@@ -10755,9 +10731,9 @@ function registerGithub(program2) {
10755
10731
  }
10756
10732
 
10757
10733
  // src/commands/handover/countPendingHandovers.ts
10758
- import { and as and10, eq as eq29, isNull, sql as sql3 } from "drizzle-orm";
10734
+ import { and as and10, eq as eq28, isNull, sql as sql3 } from "drizzle-orm";
10759
10735
  async function countPendingHandovers(orm, origin) {
10760
- const [row] = await orm.select({ count: sql3`count(*)::int` }).from(handovers).where(and10(eq29(handovers.origin, origin), isNull(handovers.recalledAt)));
10736
+ const [row] = await orm.select({ count: sql3`count(*)::int` }).from(handovers).where(and10(eq28(handovers.origin, origin), isNull(handovers.recalledAt)));
10761
10737
  return row?.count ?? 0;
10762
10738
  }
10763
10739
 
@@ -10897,13 +10873,13 @@ async function load(options2 = {}) {
10897
10873
  }
10898
10874
 
10899
10875
  // src/commands/handover/listPendingHandovers.ts
10900
- import { and as and11, desc as desc3, eq as eq30, isNull as isNull2 } from "drizzle-orm";
10876
+ import { and as and11, desc as desc3, eq as eq29, isNull as isNull2 } from "drizzle-orm";
10901
10877
  async function listPendingHandovers(orm, origin) {
10902
10878
  return orm.select({
10903
10879
  id: handovers.id,
10904
10880
  summary: handovers.summary,
10905
10881
  createdAt: handovers.createdAt
10906
- }).from(handovers).where(and11(eq30(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc3(handovers.createdAt), desc3(handovers.id));
10882
+ }).from(handovers).where(and11(eq29(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc3(handovers.createdAt), desc3(handovers.id));
10907
10883
  }
10908
10884
 
10909
10885
  // src/commands/handover/printPendingHandovers.ts
@@ -10916,17 +10892,17 @@ async function printPendingHandovers() {
10916
10892
  }
10917
10893
 
10918
10894
  // src/commands/handover/recallHandover.ts
10919
- import { and as and12, desc as desc4, eq as eq31, isNull as isNull3 } from "drizzle-orm";
10895
+ import { and as and12, desc as desc4, eq as eq30, isNull as isNull3 } from "drizzle-orm";
10920
10896
  async function recallHandover(orm, origin, id2) {
10921
10897
  const [row] = await orm.select().from(handovers).where(
10922
10898
  and12(
10923
- eq31(handovers.origin, origin),
10899
+ eq30(handovers.origin, origin),
10924
10900
  isNull3(handovers.recalledAt),
10925
- ...id2 === void 0 ? [] : [eq31(handovers.id, id2)]
10901
+ ...id2 === void 0 ? [] : [eq30(handovers.id, id2)]
10926
10902
  )
10927
10903
  ).orderBy(desc4(handovers.createdAt), desc4(handovers.id)).limit(1);
10928
10904
  if (!row) return void 0;
10929
- await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq31(handovers.id, row.id));
10905
+ await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq30(handovers.id, row.id));
10930
10906
  return row.content;
10931
10907
  }
10932
10908
 
@@ -11356,8 +11332,666 @@ function registerMermaid(program2) {
11356
11332
  );
11357
11333
  }
11358
11334
 
11359
- // src/commands/news/add/index.ts
11335
+ // src/commands/netcap/netcap.ts
11336
+ import { mkdir } from "fs/promises";
11337
+ import { createServer as createServer2 } from "http";
11338
+ import { dirname as dirname20 } from "path";
11339
+ import chalk124 from "chalk";
11340
+
11341
+ // src/commands/netcap/corsHeaders.ts
11342
+ var corsHeaders = {
11343
+ "Access-Control-Allow-Origin": "*",
11344
+ "Access-Control-Allow-Methods": "POST, GET, OPTIONS",
11345
+ "Access-Control-Allow-Headers": "Content-Type",
11346
+ "Access-Control-Max-Age": "86400"
11347
+ };
11348
+
11349
+ // src/commands/netcap/handleNetcapPost.ts
11350
+ import { appendFile } from "fs/promises";
11351
+
11352
+ // src/commands/netcap/parseNetcapEntry.ts
11353
+ function parseNetcapEntry(body) {
11354
+ try {
11355
+ const parsed = JSON.parse(body);
11356
+ if (typeof parsed !== "object" || parsed === null) return null;
11357
+ return parsed;
11358
+ } catch {
11359
+ return null;
11360
+ }
11361
+ }
11362
+
11363
+ // src/commands/netcap/handleNetcapPost.ts
11364
+ function handleNetcapPost(req, res, options2) {
11365
+ let body = "";
11366
+ req.on("data", (chunk) => {
11367
+ body += chunk;
11368
+ });
11369
+ req.on("end", () => {
11370
+ const entry = parseNetcapEntry(body);
11371
+ if (!entry) {
11372
+ res.writeHead(400, corsHeaders);
11373
+ res.end();
11374
+ return;
11375
+ }
11376
+ void appendFile(options2.outPath, `${JSON.stringify(entry)}
11377
+ `).then(() => {
11378
+ options2.onCapture?.(entry);
11379
+ res.writeHead(200, {
11380
+ ...corsHeaders,
11381
+ "Content-Type": "application/json"
11382
+ });
11383
+ res.end(JSON.stringify({ ok: true }));
11384
+ }).catch((error) => {
11385
+ res.writeHead(500, corsHeaders);
11386
+ res.end(String(error));
11387
+ });
11388
+ });
11389
+ }
11390
+
11391
+ // src/commands/netcap/createNetcapHandler.ts
11392
+ function createNetcapHandler(options2) {
11393
+ return (req, res) => {
11394
+ if (req.method === "OPTIONS") {
11395
+ res.writeHead(204, corsHeaders);
11396
+ res.end();
11397
+ return;
11398
+ }
11399
+ if (req.method === "GET") {
11400
+ options2.onPing?.(req);
11401
+ res.writeHead(200, { ...corsHeaders, "Content-Type": "text/plain" });
11402
+ res.end("netcap receiver");
11403
+ return;
11404
+ }
11405
+ if (req.method !== "POST") {
11406
+ res.writeHead(405, corsHeaders);
11407
+ res.end();
11408
+ return;
11409
+ }
11410
+ handleNetcapPost(req, res, options2);
11411
+ };
11412
+ }
11413
+
11414
+ // src/commands/netcap/prepareExtensionForLoad.ts
11415
+ import { cp, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
11416
+ import { networkInterfaces } from "os";
11417
+ import { join as join35 } from "path";
11360
11418
  import chalk123 from "chalk";
11419
+
11420
+ // src/commands/netcap/netcapExtensionDir.ts
11421
+ import { dirname as dirname19, join as join34 } from "path";
11422
+ import { fileURLToPath as fileURLToPath5 } from "url";
11423
+ var moduleDir = dirname19(fileURLToPath5(import.meta.url));
11424
+ function netcapExtensionDir() {
11425
+ return join34(moduleDir, "commands", "netcap", "netcap-extension");
11426
+ }
11427
+
11428
+ // src/commands/netcap/prepareExtensionForLoad.ts
11429
+ var WSL_WINDOWS_DIR = "/mnt/c/tools/netcap-extension";
11430
+ var WSL_WINDOWS_PATH = String.raw`C:\tools\netcap-extension`;
11431
+ function lanIPv4() {
11432
+ for (const addrs of Object.values(networkInterfaces())) {
11433
+ for (const addr of addrs ?? []) {
11434
+ if (addr.family === "IPv4" && !addr.internal) return addr.address;
11435
+ }
11436
+ }
11437
+ return void 0;
11438
+ }
11439
+ async function configureBackground(dir, host, port, filter) {
11440
+ const file = join35(dir, "background.js");
11441
+ const source = await readFile2(file, "utf8");
11442
+ await writeFile2(
11443
+ file,
11444
+ source.replace(
11445
+ /const RECEIVER = "[^"]*";/,
11446
+ `const RECEIVER = "http://${host}:${port}/";`
11447
+ ).replace(
11448
+ /const FILTER = "[^"]*";/,
11449
+ `const FILTER = ${JSON.stringify(filter)};`
11450
+ )
11451
+ );
11452
+ }
11453
+ async function prepareExtensionForLoad(port, filter = "") {
11454
+ const source = netcapExtensionDir();
11455
+ if (detectPlatform() !== "wsl") {
11456
+ await configureBackground(source, "127.0.0.1", port, filter);
11457
+ return source;
11458
+ }
11459
+ const host = lanIPv4();
11460
+ if (!host) {
11461
+ console.log(
11462
+ chalk123.yellow("could not determine the WSL IP for the extension")
11463
+ );
11464
+ await configureBackground(source, "127.0.0.1", port, filter);
11465
+ return source;
11466
+ }
11467
+ try {
11468
+ await cp(source, WSL_WINDOWS_DIR, { recursive: true });
11469
+ await configureBackground(WSL_WINDOWS_DIR, host, port, filter);
11470
+ return WSL_WINDOWS_PATH;
11471
+ } catch {
11472
+ console.log(
11473
+ chalk123.yellow(`could not copy extension to ${WSL_WINDOWS_PATH}`)
11474
+ );
11475
+ return source;
11476
+ }
11477
+ }
11478
+
11479
+ // src/commands/netcap/resolveNetcapOutPath.ts
11480
+ import { isAbsolute, join as join37, resolve as resolve11 } from "path";
11481
+
11482
+ // src/commands/netcap/defaultCapturePath.ts
11483
+ import { homedir as homedir12 } from "os";
11484
+ import { join as join36 } from "path";
11485
+ function defaultCapturePath() {
11486
+ return join36(homedir12(), ".assist", "netcap", "capture.jsonl");
11487
+ }
11488
+
11489
+ // src/commands/netcap/resolveNetcapOutPath.ts
11490
+ function resolveNetcapOutPath(out) {
11491
+ if (!out) return defaultCapturePath();
11492
+ const dir = isAbsolute(out) ? out : resolve11(process.cwd(), out);
11493
+ return join37(dir, "capture.jsonl");
11494
+ }
11495
+
11496
+ // src/commands/netcap/netcap.ts
11497
+ async function netcap(options2) {
11498
+ const port = Number(options2.port);
11499
+ const outPath = resolveNetcapOutPath(options2.out);
11500
+ const filter = options2.filter ?? "";
11501
+ await mkdir(dirname20(outPath), { recursive: true });
11502
+ const extensionPath = await prepareExtensionForLoad(port, filter);
11503
+ let count6 = 0;
11504
+ const handler = createNetcapHandler({
11505
+ outPath,
11506
+ onPing: () => console.log(chalk124.dim("ping from extension")),
11507
+ onCapture: (entry) => {
11508
+ count6 += 1;
11509
+ console.log(
11510
+ chalk124.green(`captured #${count6}`),
11511
+ chalk124.dim(`${entry.method ?? "?"} ${entry.url ?? "?"}`)
11512
+ );
11513
+ }
11514
+ });
11515
+ const server = createServer2(handler);
11516
+ server.listen(port, () => {
11517
+ console.log(
11518
+ chalk124.bold(`netcap receiver listening on http://127.0.0.1:${port}`)
11519
+ );
11520
+ console.log(chalk124.dim(`appending captures to ${outPath}`));
11521
+ if (filter)
11522
+ console.log(chalk124.dim(`forwarding only URLs matching "${filter}"`));
11523
+ console.log(chalk124.dim(`load the unpacked extension from ${extensionPath}`));
11524
+ console.log(chalk124.dim("press Ctrl-C to stop"));
11525
+ });
11526
+ process.on("SIGINT", () => {
11527
+ server.close();
11528
+ console.log(
11529
+ chalk124.bold(
11530
+ `
11531
+ netcap stopped \u2014 captured ${count6} ${count6 === 1 ? "entry" : "entries"} to ${outPath}`
11532
+ )
11533
+ );
11534
+ process.exit(0);
11535
+ });
11536
+ }
11537
+
11538
+ // src/commands/netcap/netcapExtract.ts
11539
+ import { writeFileSync as writeFileSync26 } from "fs";
11540
+ import { join as join38 } from "path";
11541
+ import chalk125 from "chalk";
11542
+
11543
+ // src/commands/netcap/extractPostsFromCapture.ts
11544
+ import { readFileSync as readFileSync30 } from "fs";
11545
+
11546
+ // src/commands/netcap/parseRscRows.ts
11547
+ var isRscRef = (v) => typeof v === "string" && /^\$[0-9a-fL@]/.test(v);
11548
+ function parseRscRows(flight) {
11549
+ const rows = {};
11550
+ for (const line of flight.split("\n")) {
11551
+ const m = line.match(/^([0-9a-f]+):(.*)$/s);
11552
+ if (!m) continue;
11553
+ let payload = m[2];
11554
+ if (payload && !/^[[{"\d\-tfn]/.test(payload[0]))
11555
+ payload = payload.slice(1);
11556
+ try {
11557
+ rows[m[1]] = JSON.parse(payload);
11558
+ } catch {
11559
+ rows[m[1]] = m[2];
11560
+ }
11561
+ }
11562
+ return rows;
11563
+ }
11564
+ function makeRscResolver(rows) {
11565
+ return (ref) => {
11566
+ const [id2, ...path58] = ref.slice(1).replace(/^[L@]/, "").split(":");
11567
+ let v = rows[id2];
11568
+ for (const key of path58) {
11569
+ if (v == null || typeof v !== "object") return void 0;
11570
+ v = v[key];
11571
+ }
11572
+ return v;
11573
+ };
11574
+ }
11575
+
11576
+ // src/commands/netcap/collectRscText.ts
11577
+ function isVisibleText(t) {
11578
+ if (/^(proto\.|com\.linkedin|react\.)/.test(t)) return false;
11579
+ if (!/\s/.test(t.trim())) return false;
11580
+ return /[a-zA-Z]{3,}/.test(t);
11581
+ }
11582
+ var isHashtag = (t) => /^#[A-Za-z0-9_]+$/.test(t);
11583
+ function collectRscText(v, resolve17, sink, seen) {
11584
+ if (v == null) return;
11585
+ if (typeof v === "string") {
11586
+ if (isRscRef(v)) {
11587
+ if (!seen.has(v)) {
11588
+ seen.add(v);
11589
+ collectRscText(resolve17(v), resolve17, sink, seen);
11590
+ }
11591
+ } else if (isHashtag(v)) sink.hashtags.push(v);
11592
+ else if (isVisibleText(v)) sink.text.push(v);
11593
+ return;
11594
+ }
11595
+ if (Array.isArray(v)) {
11596
+ for (const x of v) collectRscText(x, resolve17, sink, seen);
11597
+ return;
11598
+ }
11599
+ if (typeof v === "object") {
11600
+ for (const val of Object.values(v)) {
11601
+ collectRscText(val, resolve17, sink, seen);
11602
+ }
11603
+ }
11604
+ }
11605
+
11606
+ // src/commands/netcap/buildMentionMap.ts
11607
+ function asObject(v) {
11608
+ return v != null && typeof v === "object" && !Array.isArray(v) ? v : void 0;
11609
+ }
11610
+ function profileActionUrl(o) {
11611
+ const actions = asObject(o.action)?.actions;
11612
+ if (!Array.isArray(actions)) return void 0;
11613
+ for (const a of actions) {
11614
+ const url = asObject(asObject(asObject(a)?.value)?.content)?.url;
11615
+ const target = asObject(url)?.url;
11616
+ if (typeof target === "string" && /\/in\//.test(target)) return target;
11617
+ }
11618
+ return void 0;
11619
+ }
11620
+ var slugFromProfileUrl = (url) => url.match(/\/in\/([^/?]+)/)?.[1];
11621
+ function visitObjects(root, fn) {
11622
+ const stack = [root];
11623
+ while (stack.length) {
11624
+ const v = stack.pop();
11625
+ if (v == null || typeof v !== "object") continue;
11626
+ const o = asObject(v);
11627
+ if (o) fn(o);
11628
+ for (const child of Array.isArray(v) ? v : Object.values(v)) {
11629
+ if (child && typeof child === "object") stack.push(child);
11630
+ }
11631
+ }
11632
+ }
11633
+ function buildMentionMap(rows, resolve17) {
11634
+ const map = /* @__PURE__ */ new Map();
11635
+ visitObjects(rows, (o) => {
11636
+ const url = profileActionUrl(o);
11637
+ if (!url || o.children == null) return;
11638
+ const slug = slugFromProfileUrl(url);
11639
+ if (!slug || map.has(slug)) return;
11640
+ const sink = { text: [], hashtags: [] };
11641
+ collectRscText(o.children, resolve17, sink, /* @__PURE__ */ new Set());
11642
+ const name = sink.text.join(" ").replace(/\s+/g, " ").trim();
11643
+ map.set(slug, name ? { slug, name, url } : { slug, url });
11644
+ });
11645
+ return map;
11646
+ }
11647
+
11648
+ // src/commands/netcap/activityUrnDate.ts
11649
+ function activityUrnDate(urn) {
11650
+ if (!urn) return void 0;
11651
+ const id2 = urn.split(":").pop();
11652
+ if (!id2 || !/^\d+$/.test(id2)) return void 0;
11653
+ return new Date(Number(BigInt(id2) >> 22n)).toISOString();
11654
+ }
11655
+
11656
+ // src/commands/netcap/dedupeLinks.ts
11657
+ function decodeSafetyLink(url) {
11658
+ try {
11659
+ const wrapped = new URL(url).searchParams.get("url");
11660
+ return wrapped ? decodeURIComponent(wrapped) : url;
11661
+ } catch {
11662
+ return url;
11663
+ }
11664
+ }
11665
+ function dedupeLinks(links2) {
11666
+ return [
11667
+ ...new Set(
11668
+ links2.map((l) => /\/safety\/go\//.test(l) ? decodeSafetyLink(l) : l)
11669
+ )
11670
+ ];
11671
+ }
11672
+
11673
+ // src/commands/netcap/linkifyMentions.ts
11674
+ function linkifyMentions(text5, mentions) {
11675
+ let out = text5;
11676
+ for (const m of mentions) {
11677
+ if (m.name && out.includes(m.name)) {
11678
+ out = out.replace(m.name, `[${m.name}](${m.url})`);
11679
+ }
11680
+ }
11681
+ return out;
11682
+ }
11683
+
11684
+ // src/commands/netcap/buildPost.ts
11685
+ var profileUrl = (slug) => `https://www.linkedin.com/in/${slug}/`;
11686
+ var joinText = (parts) => parts.join(" ").replace(/\s+/g, " ").replace(/\s+([.,!?])/g, "$1").trim();
11687
+ function resolveMentions(raw, mentionMap, author) {
11688
+ const slugs = /* @__PURE__ */ new Set();
11689
+ for (const url of raw.profileUrls) {
11690
+ const slug = slugFromProfileUrl(url);
11691
+ if (slug && slug !== author) slugs.add(slug);
11692
+ }
11693
+ return [...slugs].map(
11694
+ (slug) => mentionMap.get(slug) ?? { slug, url: profileUrl(slug) }
11695
+ );
11696
+ }
11697
+ function resolveAuthor(mentionMap, author) {
11698
+ if (!author) return void 0;
11699
+ return mentionMap.get(author) ?? { slug: author, url: profileUrl(author) };
11700
+ }
11701
+ function buildPost(raw, mentionMap, author) {
11702
+ const text5 = joinText(raw.text);
11703
+ if (!text5) return void 0;
11704
+ const mentions = resolveMentions(raw, mentionMap, author);
11705
+ const relatedPosts = [...new Set(raw.related)];
11706
+ return {
11707
+ text: text5,
11708
+ markdown: linkifyMentions(text5, mentions),
11709
+ mentions,
11710
+ hashtags: [...new Set(raw.hashtags)],
11711
+ links: dedupeLinks(raw.links),
11712
+ relatedPosts,
11713
+ activityUrn: relatedPosts[0],
11714
+ postedAt: activityUrnDate(relatedPosts[0]),
11715
+ author: resolveAuthor(mentionMap, author)
11716
+ };
11717
+ }
11718
+
11719
+ // src/commands/netcap/walkPostRow.ts
11720
+ var isCommentary = (o) => asObject(o.viewTrackingSpecs)?.viewName === "feed-commentary";
11721
+ function walkPostRow(v, resolve17, raw) {
11722
+ if (v == null || typeof v !== "object") return;
11723
+ if (Array.isArray(v)) {
11724
+ for (const x of v) walkPostRow(x, resolve17, raw);
11725
+ return;
11726
+ }
11727
+ const o = v;
11728
+ if (o.$type === "proto.sdui.actions.core.NavigateToUrl" && typeof o.url === "string") {
11729
+ if (/\/in\//.test(o.url)) raw.profileUrls.push(o.url);
11730
+ else raw.links.push(o.url);
11731
+ }
11732
+ if (o.$type === "proto.sdui.actions.requests.RequestedArguments") {
11733
+ const a = JSON.stringify(o).match(/urn:li:activity:\d+/);
11734
+ if (a) raw.related.push(a[0]);
11735
+ }
11736
+ if (isCommentary(o)) {
11737
+ const sink = { text: raw.text, hashtags: raw.hashtags };
11738
+ collectRscText(o.children, resolve17, sink, /* @__PURE__ */ new Set());
11739
+ }
11740
+ for (const val of Object.values(o)) walkPostRow(val, resolve17, raw);
11741
+ }
11742
+
11743
+ // src/commands/netcap/extractLinkedInPosts.ts
11744
+ function findAuthorSlug(flight) {
11745
+ return flight.match(/profile-activity-load-([A-Za-z0-9-]+)/)?.[1];
11746
+ }
11747
+ function findCommentaryRows(rows) {
11748
+ return Object.keys(rows).filter(
11749
+ (id2) => /"componentkey":"feed-commentary_/.test(JSON.stringify(rows[id2]))
11750
+ );
11751
+ }
11752
+ function extractLinkedInPosts(flight, author = findAuthorSlug(flight)) {
11753
+ const rows = parseRscRows(flight);
11754
+ const resolve17 = makeRscResolver(rows);
11755
+ const mentionMap = buildMentionMap(rows, resolve17);
11756
+ const posts = [];
11757
+ for (const id2 of findCommentaryRows(rows)) {
11758
+ const raw = {
11759
+ text: [],
11760
+ hashtags: [],
11761
+ profileUrls: [],
11762
+ links: [],
11763
+ related: []
11764
+ };
11765
+ walkPostRow(rows[id2], resolve17, raw);
11766
+ const post = buildPost(raw, mentionMap, author);
11767
+ if (post) posts.push(post);
11768
+ }
11769
+ return posts;
11770
+ }
11771
+
11772
+ // src/commands/netcap/collectVoyagerAttributes.ts
11773
+ function attributeDetails(update3) {
11774
+ const attrs = asObject(asObject(update3.commentary)?.text)?.attributesV2;
11775
+ if (!Array.isArray(attrs)) return [];
11776
+ return attrs.map((a) => asObject(asObject(a)?.detailData)).filter((d) => d !== void 0);
11777
+ }
11778
+ function mentionsFrom(details, profiles, authorSlug) {
11779
+ const bySlug = /* @__PURE__ */ new Map();
11780
+ for (const detail of details) {
11781
+ const urn = detail["*profileMention"];
11782
+ if (typeof urn !== "string") continue;
11783
+ const mention = profiles.get(urn);
11784
+ if (mention && mention.slug !== authorSlug)
11785
+ bySlug.set(mention.slug, mention);
11786
+ }
11787
+ return [...bySlug.values()];
11788
+ }
11789
+ function hashtagsFrom(details) {
11790
+ const tags = [];
11791
+ for (const detail of details) {
11792
+ const urn = detail["*hashtag"];
11793
+ const tag = typeof urn === "string" ? urn.match(/\(([^,]+),/)?.[1] : void 0;
11794
+ if (tag) tags.push(`#${tag}`);
11795
+ }
11796
+ return [...new Set(tags)];
11797
+ }
11798
+ function linksFrom(details) {
11799
+ const links2 = details.map((detail) => asObject(detail.textLink)?.url).filter((url) => typeof url === "string");
11800
+ return dedupeLinks(links2);
11801
+ }
11802
+ function collectVoyagerAttributes(update3, profiles, authorSlug) {
11803
+ const details = attributeDetails(update3);
11804
+ return {
11805
+ mentions: mentionsFrom(details, profiles, authorSlug),
11806
+ hashtags: hashtagsFrom(details),
11807
+ links: linksFrom(details)
11808
+ };
11809
+ }
11810
+
11811
+ // src/commands/netcap/resolveVoyagerAuthor.ts
11812
+ var profileUrl2 = (slug) => `https://www.linkedin.com/in/${slug}/`;
11813
+ function profileSlug(actor) {
11814
+ const target = asObject(actor?.navigationContext)?.actionTarget;
11815
+ if (typeof target !== "string") return void 0;
11816
+ return target.match(/\/in\/([^/?]+)/)?.[1];
11817
+ }
11818
+ function resolveVoyagerAuthor(update3) {
11819
+ const actor = asObject(update3.actor);
11820
+ const slug = profileSlug(actor);
11821
+ if (!slug) return void 0;
11822
+ const name = asObject(actor?.name)?.text;
11823
+ const mention = { slug, url: profileUrl2(slug) };
11824
+ if (typeof name === "string" && name.trim()) mention.name = name.trim();
11825
+ return mention;
11826
+ }
11827
+
11828
+ // src/commands/netcap/buildVoyagerPost.ts
11829
+ function commentaryText(update3) {
11830
+ const body = asObject(asObject(update3.commentary)?.text)?.text;
11831
+ return typeof body === "string" && body.trim() ? body.trim() : void 0;
11832
+ }
11833
+ function activityUrnOf(update3) {
11834
+ const urn = asObject(update3.metadata)?.backendUrn;
11835
+ return typeof urn === "string" ? urn : void 0;
11836
+ }
11837
+ function buildVoyagerPost(update3, profiles) {
11838
+ const text5 = commentaryText(update3);
11839
+ if (!text5) return void 0;
11840
+ const author = resolveVoyagerAuthor(update3);
11841
+ const { mentions, hashtags, links: links2 } = collectVoyagerAttributes(
11842
+ update3,
11843
+ profiles,
11844
+ author?.slug
11845
+ );
11846
+ const activityUrn = activityUrnOf(update3);
11847
+ return {
11848
+ text: text5,
11849
+ markdown: linkifyMentions(text5, mentions),
11850
+ mentions,
11851
+ hashtags,
11852
+ links: links2,
11853
+ relatedPosts: activityUrn ? [activityUrn] : [],
11854
+ activityUrn,
11855
+ postedAt: activityUrnDate(activityUrn),
11856
+ author
11857
+ };
11858
+ }
11859
+
11860
+ // src/commands/netcap/voyagerProfileMentions.ts
11861
+ var PROFILE_TYPE = "com.linkedin.voyager.dash.identity.profile.Profile";
11862
+ var profileUrl3 = (slug) => `https://www.linkedin.com/in/${slug}/`;
11863
+ function profileName(o) {
11864
+ return [o.firstName, o.lastName].filter((s) => typeof s === "string" && s.length > 0).join(" ");
11865
+ }
11866
+ function voyagerProfileMentions(included) {
11867
+ const map = /* @__PURE__ */ new Map();
11868
+ for (const o of included) {
11869
+ const urn = o.entityUrn;
11870
+ const slug = o.publicIdentifier;
11871
+ if (o.$type !== PROFILE_TYPE) continue;
11872
+ if (typeof urn !== "string" || typeof slug !== "string") continue;
11873
+ const name = profileName(o);
11874
+ const url = profileUrl3(slug);
11875
+ map.set(urn, name ? { slug, name, url } : { slug, url });
11876
+ }
11877
+ return map;
11878
+ }
11879
+
11880
+ // src/commands/netcap/extractVoyagerPosts.ts
11881
+ function includedObjects(root) {
11882
+ const included = root.included;
11883
+ if (!Array.isArray(included)) return [];
11884
+ return included.map((item) => asObject(item)).filter((o) => o !== void 0);
11885
+ }
11886
+ function elementUrns(root) {
11887
+ const data = asObject(asObject(root.data)?.data);
11888
+ if (!data) return [];
11889
+ for (const value of Object.values(data)) {
11890
+ const elements = asObject(value)?.["*elements"];
11891
+ if (Array.isArray(elements))
11892
+ return elements.filter((e) => typeof e === "string");
11893
+ }
11894
+ return [];
11895
+ }
11896
+ function extractVoyagerPosts(body) {
11897
+ let root;
11898
+ try {
11899
+ root = JSON.parse(body);
11900
+ } catch {
11901
+ return [];
11902
+ }
11903
+ const rootObj = asObject(root);
11904
+ if (!rootObj) return [];
11905
+ const included = includedObjects(rootObj);
11906
+ const byUrn = /* @__PURE__ */ new Map();
11907
+ for (const o of included) {
11908
+ if (typeof o.entityUrn === "string") byUrn.set(o.entityUrn, o);
11909
+ }
11910
+ const profiles = voyagerProfileMentions(included);
11911
+ const posts = [];
11912
+ for (const ref of elementUrns(rootObj)) {
11913
+ const update3 = byUrn.get(ref);
11914
+ if (!update3) continue;
11915
+ const post = buildVoyagerPost(update3, profiles);
11916
+ if (post) posts.push(post);
11917
+ }
11918
+ return posts;
11919
+ }
11920
+
11921
+ // src/commands/netcap/extractPostsFromCapture.ts
11922
+ function captureEntries(captureFile) {
11923
+ const lines = readFileSync30(captureFile, "utf8").split("\n").filter(Boolean);
11924
+ const entries = [];
11925
+ for (const line of lines) {
11926
+ let entry;
11927
+ try {
11928
+ entry = JSON.parse(line);
11929
+ } catch {
11930
+ continue;
11931
+ }
11932
+ if (typeof entry.url !== "string" || typeof entry.responseBody !== "string")
11933
+ continue;
11934
+ entries.push({ url: entry.url, responseBody: entry.responseBody });
11935
+ }
11936
+ return entries;
11937
+ }
11938
+ function dedupeByActivity(posts) {
11939
+ const byUrn = /* @__PURE__ */ new Map();
11940
+ const noUrn = [];
11941
+ for (const post of posts) {
11942
+ if (!post.activityUrn) {
11943
+ noUrn.push(post);
11944
+ continue;
11945
+ }
11946
+ const existing = byUrn.get(post.activityUrn);
11947
+ if (!existing || post.text.length > existing.text.length)
11948
+ byUrn.set(post.activityUrn, post);
11949
+ }
11950
+ return [...byUrn.values(), ...noUrn];
11951
+ }
11952
+ function extractPostsFromCapture(captureFile) {
11953
+ const entries = captureEntries(captureFile);
11954
+ const rscBodies = entries.filter((e) => /rsc-action/.test(e.url)).map((e) => e.responseBody);
11955
+ const voyagerBodies = entries.filter((e) => /voyagerFeedDashProfileUpdates/.test(e.url)).map((e) => e.responseBody);
11956
+ const author = rscBodies.map(findAuthorSlug).find(Boolean);
11957
+ const all = [
11958
+ ...rscBodies.flatMap((body) => extractLinkedInPosts(body, author)),
11959
+ ...voyagerBodies.flatMap(extractVoyagerPosts)
11960
+ ];
11961
+ return dedupeByActivity(all);
11962
+ }
11963
+
11964
+ // src/commands/netcap/netcapExtract.ts
11965
+ function netcapExtract(file) {
11966
+ const captureFile = file ?? defaultCapturePath();
11967
+ const posts = extractPostsFromCapture(captureFile);
11968
+ const outFile = join38(captureFile, "..", "posts.json");
11969
+ writeFileSync26(outFile, `${JSON.stringify(posts, null, 2)}
11970
+ `);
11971
+ console.log(
11972
+ chalk125.green(`extracted ${posts.length} posts`),
11973
+ chalk125.dim(`-> ${outFile}`)
11974
+ );
11975
+ }
11976
+
11977
+ // src/commands/registerNetcap.ts
11978
+ function registerNetcap(program2) {
11979
+ const command = program2.command("netcap").description(
11980
+ "Start a local receiver that captures browser network traffic (fetch/XHR) to a JSONL file via the netcap browser extension"
11981
+ ).option("-p, --port <port>", "Port to listen on", "8723").option(
11982
+ "-o, --out <dir>",
11983
+ "Directory to write the capture file into (default ~/.assist/netcap)"
11984
+ ).option(
11985
+ "-f, --filter <pattern>",
11986
+ "Only forward requests whose URL contains this substring"
11987
+ ).action((options2) => netcap(options2));
11988
+ command.command("extract [file]").description(
11989
+ "Extract LinkedIn posts (text, author, mentions, links) from a netcap capture file to posts.json"
11990
+ ).action((file) => netcapExtract(file));
11991
+ }
11992
+
11993
+ // src/commands/news/add/index.ts
11994
+ import chalk126 from "chalk";
11361
11995
  import enquirer8 from "enquirer";
11362
11996
  async function add2(url) {
11363
11997
  if (!url) {
@@ -11379,10 +12013,10 @@ async function add2(url) {
11379
12013
  const { orm } = await getReady();
11380
12014
  const added = await addFeed(orm, url);
11381
12015
  if (!added) {
11382
- console.log(chalk123.yellow("Feed already exists"));
12016
+ console.log(chalk126.yellow("Feed already exists"));
11383
12017
  return;
11384
12018
  }
11385
- console.log(chalk123.green(`Added feed: ${url}`));
12019
+ console.log(chalk126.green(`Added feed: ${url}`));
11386
12020
  }
11387
12021
 
11388
12022
  // src/commands/registerNews.ts
@@ -11392,7 +12026,7 @@ function registerNews(program2) {
11392
12026
  }
11393
12027
 
11394
12028
  // src/commands/prompts/printPromptsTable.ts
11395
- import chalk124 from "chalk";
12029
+ import chalk127 from "chalk";
11396
12030
  function truncate(str, max) {
11397
12031
  if (str.length <= max) return str;
11398
12032
  return `${str.slice(0, max - 1)}\u2026`;
@@ -11410,14 +12044,14 @@ function printPromptsTable(rows) {
11410
12044
  "Command".padEnd(commandWidth),
11411
12045
  "Repos"
11412
12046
  ].join(" ");
11413
- console.log(chalk124.dim(header));
11414
- console.log(chalk124.dim("-".repeat(header.length)));
12047
+ console.log(chalk127.dim(header));
12048
+ console.log(chalk127.dim("-".repeat(header.length)));
11415
12049
  for (const row of rows) {
11416
12050
  const count6 = String(row.count).padStart(countWidth);
11417
12051
  const tool = row.tool.padEnd(toolWidth);
11418
12052
  const command = truncate(row.command, 60).padEnd(commandWidth);
11419
12053
  console.log(
11420
- `${chalk124.yellow(count6)} ${tool} ${command} ${chalk124.dim(row.repos)}`
12054
+ `${chalk127.yellow(count6)} ${tool} ${command} ${chalk127.dim(row.repos)}`
11421
12055
  );
11422
12056
  }
11423
12057
  }
@@ -11765,23 +12399,23 @@ import { execSync as execSync33 } from "child_process";
11765
12399
 
11766
12400
  // src/commands/prs/resolveCommentWithReply.ts
11767
12401
  import { execSync as execSync32 } from "child_process";
11768
- import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync26 } from "fs";
12402
+ import { unlinkSync as unlinkSync10, writeFileSync as writeFileSync27 } from "fs";
11769
12403
  import { tmpdir as tmpdir5 } from "os";
11770
- import { join as join35 } from "path";
12404
+ import { join as join40 } from "path";
11771
12405
 
11772
12406
  // src/commands/prs/loadCommentsCache.ts
11773
- import { existsSync as existsSync33, readFileSync as readFileSync30, unlinkSync as unlinkSync9 } from "fs";
11774
- import { join as join34 } from "path";
12407
+ import { existsSync as existsSync33, readFileSync as readFileSync31, unlinkSync as unlinkSync9 } from "fs";
12408
+ import { join as join39 } from "path";
11775
12409
  import { parse as parse2 } from "yaml";
11776
12410
  function getCachePath(prNumber) {
11777
- return join34(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
12411
+ return join39(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`);
11778
12412
  }
11779
12413
  function loadCommentsCache(prNumber) {
11780
12414
  const cachePath = getCachePath(prNumber);
11781
12415
  if (!existsSync33(cachePath)) {
11782
12416
  return null;
11783
12417
  }
11784
- const content = readFileSync30(cachePath, "utf8");
12418
+ const content = readFileSync31(cachePath, "utf8");
11785
12419
  return parse2(content);
11786
12420
  }
11787
12421
  function deleteCommentsCache(prNumber) {
@@ -11801,8 +12435,8 @@ function replyToComment(org, repo, prNumber, commentId, message) {
11801
12435
  }
11802
12436
  function resolveThread(threadId) {
11803
12437
  const mutation = `mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } }`;
11804
- const queryFile = join35(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
11805
- writeFileSync26(queryFile, mutation);
12438
+ const queryFile = join40(tmpdir5(), `gh-mutation-${Date.now()}.graphql`);
12439
+ writeFileSync27(queryFile, mutation);
11806
12440
  try {
11807
12441
  execSync32(
11808
12442
  `gh api graphql -F query=@${queryFile} -f threadId="${threadId}"`,
@@ -11883,19 +12517,19 @@ function fixed(commentId, sha) {
11883
12517
  }
11884
12518
 
11885
12519
  // src/commands/prs/listComments/index.ts
11886
- import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync28 } from "fs";
11887
- import { join as join37 } from "path";
12520
+ import { existsSync as existsSync34, mkdirSync as mkdirSync13, writeFileSync as writeFileSync29 } from "fs";
12521
+ import { join as join42 } from "path";
11888
12522
  import { stringify } from "yaml";
11889
12523
 
11890
12524
  // src/commands/prs/fetchThreadIds.ts
11891
12525
  import { execSync as execSync34 } from "child_process";
11892
- import { unlinkSync as unlinkSync11, writeFileSync as writeFileSync27 } from "fs";
12526
+ import { unlinkSync as unlinkSync11, writeFileSync as writeFileSync28 } from "fs";
11893
12527
  import { tmpdir as tmpdir6 } from "os";
11894
- import { join as join36 } from "path";
12528
+ import { join as join41 } from "path";
11895
12529
  var THREAD_QUERY = `query($owner: String!, $repo: String!, $prNumber: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $prNumber) { reviewThreads(first: 100) { nodes { id isResolved comments(first: 100) { nodes { databaseId } } } } } } }`;
11896
12530
  function fetchThreadIds(org, repo, prNumber) {
11897
- const queryFile = join36(tmpdir6(), `gh-query-${Date.now()}.graphql`);
11898
- writeFileSync27(queryFile, THREAD_QUERY);
12531
+ const queryFile = join41(tmpdir6(), `gh-query-${Date.now()}.graphql`);
12532
+ writeFileSync28(queryFile, THREAD_QUERY);
11899
12533
  try {
11900
12534
  const result = execSync34(
11901
12535
  `gh api graphql -F query=@${queryFile} -F owner="${org}" -F repo="${repo}" -F prNumber=${prNumber}`,
@@ -11963,20 +12597,20 @@ function fetchLineComments(org, repo, prNumber, threadInfo) {
11963
12597
  }
11964
12598
 
11965
12599
  // src/commands/prs/listComments/printComments.ts
11966
- import chalk125 from "chalk";
12600
+ import chalk128 from "chalk";
11967
12601
  function formatForHuman(comment3) {
11968
12602
  if (comment3.type === "review") {
11969
- const stateColor = comment3.state === "APPROVED" ? chalk125.green : comment3.state === "CHANGES_REQUESTED" ? chalk125.red : chalk125.yellow;
12603
+ const stateColor = comment3.state === "APPROVED" ? chalk128.green : comment3.state === "CHANGES_REQUESTED" ? chalk128.red : chalk128.yellow;
11970
12604
  return [
11971
- `${chalk125.cyan("Review")} by ${chalk125.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
12605
+ `${chalk128.cyan("Review")} by ${chalk128.bold(comment3.user)} ${stateColor(`[${comment3.state}]`)}`,
11972
12606
  comment3.body,
11973
12607
  ""
11974
12608
  ].join("\n");
11975
12609
  }
11976
12610
  const location = comment3.line ? `:${comment3.line}` : "";
11977
12611
  return [
11978
- `${chalk125.cyan("Line comment")} by ${chalk125.bold(comment3.user)} on ${chalk125.dim(`${comment3.path}${location}`)}`,
11979
- chalk125.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
12612
+ `${chalk128.cyan("Line comment")} by ${chalk128.bold(comment3.user)} on ${chalk128.dim(`${comment3.path}${location}`)}`,
12613
+ chalk128.dim(comment3.diff_hunk.split("\n").slice(-3).join("\n")),
11980
12614
  comment3.body,
11981
12615
  ""
11982
12616
  ].join("\n");
@@ -12008,7 +12642,7 @@ function printComments2(result) {
12008
12642
 
12009
12643
  // src/commands/prs/listComments/index.ts
12010
12644
  function writeCommentsCache(prNumber, comments3) {
12011
- const assistDir = join37(process.cwd(), ".assist");
12645
+ const assistDir = join42(process.cwd(), ".assist");
12012
12646
  if (!existsSync34(assistDir)) {
12013
12647
  mkdirSync13(assistDir, { recursive: true });
12014
12648
  }
@@ -12017,8 +12651,8 @@ function writeCommentsCache(prNumber, comments3) {
12017
12651
  fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
12018
12652
  comments: comments3
12019
12653
  };
12020
- const cachePath = join37(assistDir, `pr-${prNumber}-comments.yaml`);
12021
- writeFileSync28(cachePath, stringify(cacheData));
12654
+ const cachePath = join42(assistDir, `pr-${prNumber}-comments.yaml`);
12655
+ writeFileSync29(cachePath, stringify(cacheData));
12022
12656
  }
12023
12657
  function handleKnownErrors(error) {
12024
12658
  if (isGhNotInstalled(error)) {
@@ -12050,7 +12684,7 @@ async function listComments() {
12050
12684
  ];
12051
12685
  updateCache(prNumber, allComments);
12052
12686
  const hasLineComments = allComments.some((c) => c.type === "line");
12053
- const cachePath = hasLineComments ? join37(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
12687
+ const cachePath = hasLineComments ? join42(process.cwd(), ".assist", `pr-${prNumber}-comments.yaml`) : null;
12054
12688
  return { comments: allComments, cachePath };
12055
12689
  } catch (error) {
12056
12690
  const handled = handleKnownErrors(error);
@@ -12066,13 +12700,13 @@ import { execSync as execSync36 } from "child_process";
12066
12700
  import enquirer9 from "enquirer";
12067
12701
 
12068
12702
  // src/commands/prs/prs/displayPaginated/printPr.ts
12069
- import chalk126 from "chalk";
12703
+ import chalk129 from "chalk";
12070
12704
  var STATUS_MAP = {
12071
- MERGED: (pr) => pr.mergedAt ? { label: chalk126.magenta("merged"), date: pr.mergedAt } : null,
12072
- CLOSED: (pr) => pr.closedAt ? { label: chalk126.red("closed"), date: pr.closedAt } : null
12705
+ MERGED: (pr) => pr.mergedAt ? { label: chalk129.magenta("merged"), date: pr.mergedAt } : null,
12706
+ CLOSED: (pr) => pr.closedAt ? { label: chalk129.red("closed"), date: pr.closedAt } : null
12073
12707
  };
12074
12708
  function defaultStatus(pr) {
12075
- return { label: chalk126.green("opened"), date: pr.createdAt };
12709
+ return { label: chalk129.green("opened"), date: pr.createdAt };
12076
12710
  }
12077
12711
  function getStatus2(pr) {
12078
12712
  return STATUS_MAP[pr.state]?.(pr) ?? defaultStatus(pr);
@@ -12081,11 +12715,11 @@ function formatDate(dateStr) {
12081
12715
  return new Date(dateStr).toISOString().split("T")[0];
12082
12716
  }
12083
12717
  function formatPrHeader(pr, status2) {
12084
- return `${chalk126.cyan(`#${pr.number}`)} ${pr.title} ${chalk126.dim(`(${pr.author.login},`)} ${status2.label} ${chalk126.dim(`${formatDate(status2.date)})`)}`;
12718
+ return `${chalk129.cyan(`#${pr.number}`)} ${pr.title} ${chalk129.dim(`(${pr.author.login},`)} ${status2.label} ${chalk129.dim(`${formatDate(status2.date)})`)}`;
12085
12719
  }
12086
12720
  function logPrDetails(pr) {
12087
12721
  console.log(
12088
- chalk126.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
12722
+ chalk129.dim(` ${pr.changedFiles.toLocaleString()} files | ${pr.url}`)
12089
12723
  );
12090
12724
  console.log();
12091
12725
  }
@@ -12364,10 +12998,10 @@ function registerPrs(program2) {
12364
12998
  }
12365
12999
 
12366
13000
  // src/commands/ravendb/ravendbAuth.ts
12367
- import chalk132 from "chalk";
13001
+ import chalk135 from "chalk";
12368
13002
 
12369
13003
  // src/shared/createConnectionAuth.ts
12370
- import chalk127 from "chalk";
13004
+ import chalk130 from "chalk";
12371
13005
  function listConnections(connections, format2) {
12372
13006
  if (connections.length === 0) {
12373
13007
  console.log("No connections configured.");
@@ -12380,7 +13014,7 @@ function listConnections(connections, format2) {
12380
13014
  function removeConnection(connections, name, save) {
12381
13015
  const filtered = connections.filter((c) => c.name !== name);
12382
13016
  if (filtered.length === connections.length) {
12383
- console.error(chalk127.red(`Connection "${name}" not found.`));
13017
+ console.error(chalk130.red(`Connection "${name}" not found.`));
12384
13018
  process.exit(1);
12385
13019
  }
12386
13020
  save(filtered);
@@ -12426,15 +13060,15 @@ function saveConnections(connections) {
12426
13060
  }
12427
13061
 
12428
13062
  // src/commands/ravendb/promptConnection.ts
12429
- import chalk130 from "chalk";
13063
+ import chalk133 from "chalk";
12430
13064
 
12431
13065
  // src/commands/ravendb/selectOpSecret.ts
12432
- import chalk129 from "chalk";
13066
+ import chalk132 from "chalk";
12433
13067
  import Enquirer2 from "enquirer";
12434
13068
 
12435
13069
  // src/commands/ravendb/searchItems.ts
12436
13070
  import { execSync as execSync39 } from "child_process";
12437
- import chalk128 from "chalk";
13071
+ import chalk131 from "chalk";
12438
13072
  function opExec(args) {
12439
13073
  return execSync39(`op ${args}`, {
12440
13074
  encoding: "utf8",
@@ -12447,7 +13081,7 @@ function searchItems(search2) {
12447
13081
  items2 = JSON.parse(opExec("item list --format=json"));
12448
13082
  } catch {
12449
13083
  console.error(
12450
- chalk128.red(
13084
+ chalk131.red(
12451
13085
  "Failed to search 1Password. Ensure the CLI is installed and you are signed in."
12452
13086
  )
12453
13087
  );
@@ -12461,7 +13095,7 @@ function getItemFields(itemId) {
12461
13095
  const item = JSON.parse(opExec(`item get "${itemId}" --format=json`));
12462
13096
  return item.fields.filter((f) => f.reference && f.label);
12463
13097
  } catch {
12464
- console.error(chalk128.red("Failed to get item details from 1Password."));
13098
+ console.error(chalk131.red("Failed to get item details from 1Password."));
12465
13099
  process.exit(1);
12466
13100
  }
12467
13101
  }
@@ -12480,7 +13114,7 @@ async function selectOpSecret(searchTerm) {
12480
13114
  }).run();
12481
13115
  const items2 = searchItems(search2);
12482
13116
  if (items2.length === 0) {
12483
- console.error(chalk129.red(`No items found matching "${search2}".`));
13117
+ console.error(chalk132.red(`No items found matching "${search2}".`));
12484
13118
  process.exit(1);
12485
13119
  }
12486
13120
  const itemId = await selectOne(
@@ -12489,7 +13123,7 @@ async function selectOpSecret(searchTerm) {
12489
13123
  );
12490
13124
  const fields = getItemFields(itemId);
12491
13125
  if (fields.length === 0) {
12492
- console.error(chalk129.red("No fields with references found on this item."));
13126
+ console.error(chalk132.red("No fields with references found on this item."));
12493
13127
  process.exit(1);
12494
13128
  }
12495
13129
  const ref = await selectOne(
@@ -12503,7 +13137,7 @@ async function selectOpSecret(searchTerm) {
12503
13137
  async function promptConnection(existingNames) {
12504
13138
  const name = await promptInput("name", "Connection name:");
12505
13139
  if (existingNames.includes(name)) {
12506
- console.error(chalk130.red(`Connection "${name}" already exists.`));
13140
+ console.error(chalk133.red(`Connection "${name}" already exists.`));
12507
13141
  process.exit(1);
12508
13142
  }
12509
13143
  const url = await promptInput(
@@ -12512,22 +13146,22 @@ async function promptConnection(existingNames) {
12512
13146
  );
12513
13147
  const database = await promptInput("database", "Database name:");
12514
13148
  if (!name || !url || !database) {
12515
- console.error(chalk130.red("All fields are required."));
13149
+ console.error(chalk133.red("All fields are required."));
12516
13150
  process.exit(1);
12517
13151
  }
12518
13152
  const apiKeyRef = await selectOpSecret();
12519
- console.log(chalk130.dim(`Using: ${apiKeyRef}`));
13153
+ console.log(chalk133.dim(`Using: ${apiKeyRef}`));
12520
13154
  return { name, url, database, apiKeyRef };
12521
13155
  }
12522
13156
 
12523
13157
  // src/commands/ravendb/ravendbSetConnection.ts
12524
- import chalk131 from "chalk";
13158
+ import chalk134 from "chalk";
12525
13159
  function ravendbSetConnection(name) {
12526
13160
  const raw = loadGlobalConfigRaw();
12527
13161
  const ravendb = raw.ravendb ?? {};
12528
13162
  const connections = ravendb.connections ?? [];
12529
13163
  if (!connections.some((c) => c.name === name)) {
12530
- console.error(chalk131.red(`Connection "${name}" not found.`));
13164
+ console.error(chalk134.red(`Connection "${name}" not found.`));
12531
13165
  console.error(
12532
13166
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
12533
13167
  );
@@ -12543,16 +13177,16 @@ function ravendbSetConnection(name) {
12543
13177
  var ravendbAuth = createConnectionAuth({
12544
13178
  load: loadConnections,
12545
13179
  save: saveConnections,
12546
- format: (c) => `${chalk132.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
13180
+ format: (c) => `${chalk135.bold(c.name)} ${c.url} db=${c.database} key=${c.apiKeyRef}`,
12547
13181
  promptNew: promptConnection,
12548
13182
  onFirst: (c) => ravendbSetConnection(c.name)
12549
13183
  });
12550
13184
 
12551
13185
  // src/commands/ravendb/ravendbCollections.ts
12552
- import chalk136 from "chalk";
13186
+ import chalk139 from "chalk";
12553
13187
 
12554
13188
  // src/commands/ravendb/ravenFetch.ts
12555
- import chalk134 from "chalk";
13189
+ import chalk137 from "chalk";
12556
13190
 
12557
13191
  // src/commands/ravendb/getAccessToken.ts
12558
13192
  var OAUTH_URL = "https://amazon-useast-1-oauth.ravenhq.com/ApiKeys/OAuth/AccessToken";
@@ -12589,10 +13223,10 @@ ${errorText}`
12589
13223
 
12590
13224
  // src/commands/ravendb/resolveOpSecret.ts
12591
13225
  import { execSync as execSync40 } from "child_process";
12592
- import chalk133 from "chalk";
13226
+ import chalk136 from "chalk";
12593
13227
  function resolveOpSecret(reference) {
12594
13228
  if (!reference.startsWith("op://")) {
12595
- console.error(chalk133.red(`Invalid secret reference: must start with op://`));
13229
+ console.error(chalk136.red(`Invalid secret reference: must start with op://`));
12596
13230
  process.exit(1);
12597
13231
  }
12598
13232
  try {
@@ -12602,7 +13236,7 @@ function resolveOpSecret(reference) {
12602
13236
  }).trim();
12603
13237
  } catch {
12604
13238
  console.error(
12605
- chalk133.red(
13239
+ chalk136.red(
12606
13240
  "Failed to resolve secret reference. Ensure 1Password CLI is installed and you are signed in."
12607
13241
  )
12608
13242
  );
@@ -12629,7 +13263,7 @@ async function ravenFetch(connection, path58) {
12629
13263
  if (!response.ok) {
12630
13264
  const body = await response.text();
12631
13265
  console.error(
12632
- chalk134.red(`RavenDB error: ${response.status} ${response.statusText}`)
13266
+ chalk137.red(`RavenDB error: ${response.status} ${response.statusText}`)
12633
13267
  );
12634
13268
  console.error(body.substring(0, 500));
12635
13269
  process.exit(1);
@@ -12638,7 +13272,7 @@ async function ravenFetch(connection, path58) {
12638
13272
  }
12639
13273
 
12640
13274
  // src/commands/ravendb/resolveConnection.ts
12641
- import chalk135 from "chalk";
13275
+ import chalk138 from "chalk";
12642
13276
  function loadRavendb() {
12643
13277
  const raw = loadGlobalConfigRaw();
12644
13278
  const ravendb = raw.ravendb;
@@ -12652,7 +13286,7 @@ function resolveConnection(name) {
12652
13286
  const connectionName = name ?? defaultConnection;
12653
13287
  if (!connectionName) {
12654
13288
  console.error(
12655
- chalk135.red(
13289
+ chalk138.red(
12656
13290
  "No connection specified and no default set. Use assist ravendb set-connection <name> or pass a connection name."
12657
13291
  )
12658
13292
  );
@@ -12660,7 +13294,7 @@ function resolveConnection(name) {
12660
13294
  }
12661
13295
  const connection = connections.find((c) => c.name === connectionName);
12662
13296
  if (!connection) {
12663
- console.error(chalk135.red(`Connection "${connectionName}" not found.`));
13297
+ console.error(chalk138.red(`Connection "${connectionName}" not found.`));
12664
13298
  console.error(
12665
13299
  `Available: ${connections.map((c) => c.name).join(", ") || "(none)"}`
12666
13300
  );
@@ -12691,15 +13325,15 @@ async function ravendbCollections(connectionName) {
12691
13325
  return;
12692
13326
  }
12693
13327
  for (const c of collections) {
12694
- console.log(`${chalk136.bold(c.Name)} ${c.CountOfDocuments} docs`);
13328
+ console.log(`${chalk139.bold(c.Name)} ${c.CountOfDocuments} docs`);
12695
13329
  }
12696
13330
  }
12697
13331
 
12698
13332
  // src/commands/ravendb/ravendbQuery.ts
12699
- import chalk138 from "chalk";
13333
+ import chalk141 from "chalk";
12700
13334
 
12701
13335
  // src/commands/ravendb/fetchAllPages.ts
12702
- import chalk137 from "chalk";
13336
+ import chalk140 from "chalk";
12703
13337
 
12704
13338
  // src/commands/ravendb/buildQueryPath.ts
12705
13339
  function buildQueryPath(opts) {
@@ -12737,7 +13371,7 @@ async function fetchAllPages(connection, opts) {
12737
13371
  allResults.push(...results);
12738
13372
  start3 += results.length;
12739
13373
  process.stderr.write(
12740
- `\r${chalk137.dim(`Fetched ${allResults.length}/${totalResults}`)}`
13374
+ `\r${chalk140.dim(`Fetched ${allResults.length}/${totalResults}`)}`
12741
13375
  );
12742
13376
  if (start3 >= totalResults) break;
12743
13377
  if (opts.limit !== void 0 && allResults.length >= opts.limit) break;
@@ -12752,7 +13386,7 @@ async function fetchAllPages(connection, opts) {
12752
13386
  async function ravendbQuery(connectionName, collection, options2) {
12753
13387
  const resolved = resolveArgs(connectionName, collection);
12754
13388
  if (!resolved.collection && !options2.query) {
12755
- console.error(chalk138.red("Provide a collection name or --query filter."));
13389
+ console.error(chalk141.red("Provide a collection name or --query filter."));
12756
13390
  process.exit(1);
12757
13391
  }
12758
13392
  const { collection: col } = resolved;
@@ -12790,7 +13424,7 @@ import { spawn as spawn5 } from "child_process";
12790
13424
  import * as path28 from "path";
12791
13425
 
12792
13426
  // src/commands/refactor/logViolations.ts
12793
- import chalk139 from "chalk";
13427
+ import chalk142 from "chalk";
12794
13428
  var DEFAULT_MAX_LINES = 100;
12795
13429
  function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
12796
13430
  if (violations.length === 0) {
@@ -12799,43 +13433,43 @@ function logViolations(violations, maxLines = DEFAULT_MAX_LINES) {
12799
13433
  }
12800
13434
  return;
12801
13435
  }
12802
- console.error(chalk139.red(`
13436
+ console.error(chalk142.red(`
12803
13437
  Refactor check failed:
12804
13438
  `));
12805
- console.error(chalk139.red(` The following files exceed ${maxLines} lines:
13439
+ console.error(chalk142.red(` The following files exceed ${maxLines} lines:
12806
13440
  `));
12807
13441
  for (const violation of violations) {
12808
- console.error(chalk139.red(` ${violation.file} (${violation.lines} lines)`));
13442
+ console.error(chalk142.red(` ${violation.file} (${violation.lines} lines)`));
12809
13443
  }
12810
13444
  console.error(
12811
- chalk139.yellow(
13445
+ chalk142.yellow(
12812
13446
  `
12813
13447
  Each file needs to be sensibly refactored, or if there is no sensible
12814
13448
  way to refactor it, ignore it with:
12815
13449
  `
12816
13450
  )
12817
13451
  );
12818
- console.error(chalk139.gray(` assist refactor ignore <file>
13452
+ console.error(chalk142.gray(` assist refactor ignore <file>
12819
13453
  `));
12820
13454
  if (process.env.CLAUDECODE) {
12821
- console.error(chalk139.cyan(`
13455
+ console.error(chalk142.cyan(`
12822
13456
  ## Extracting Code to New Files
12823
13457
  `));
12824
13458
  console.error(
12825
- chalk139.cyan(
13459
+ chalk142.cyan(
12826
13460
  ` When extracting logic from one file to another, consider where the extracted code belongs:
12827
13461
  `
12828
13462
  )
12829
13463
  );
12830
13464
  console.error(
12831
- chalk139.cyan(
13465
+ chalk142.cyan(
12832
13466
  ` 1. Keep related logic together: If the extracted code is tightly coupled to the
12833
13467
  original file's domain, create a new folder containing both the original and extracted files.
12834
13468
  `
12835
13469
  )
12836
13470
  );
12837
13471
  console.error(
12838
- chalk139.cyan(
13472
+ chalk142.cyan(
12839
13473
  ` 2. Share common utilities: If the extracted code can be reused across multiple
12840
13474
  domains, move it to a common/shared folder.
12841
13475
  `
@@ -12933,7 +13567,7 @@ function getViolations(pattern2, options2 = {}, maxLines = DEFAULT_MAX_LINES) {
12933
13567
 
12934
13568
  // src/commands/refactor/check/index.ts
12935
13569
  function runScript(script, cwd) {
12936
- return new Promise((resolve16) => {
13570
+ return new Promise((resolve17) => {
12937
13571
  const child = spawn5("npm", ["run", script], {
12938
13572
  stdio: "pipe",
12939
13573
  shell: true,
@@ -12947,7 +13581,7 @@ function runScript(script, cwd) {
12947
13581
  output += data.toString();
12948
13582
  });
12949
13583
  child.on("close", (code) => {
12950
- resolve16({ script, code: code ?? 1, output });
13584
+ resolve17({ script, code: code ?? 1, output });
12951
13585
  });
12952
13586
  });
12953
13587
  }
@@ -12991,7 +13625,7 @@ async function check(pattern2, options2) {
12991
13625
 
12992
13626
  // src/commands/refactor/extract/index.ts
12993
13627
  import path35 from "path";
12994
- import chalk142 from "chalk";
13628
+ import chalk145 from "chalk";
12995
13629
 
12996
13630
  // src/commands/refactor/extract/applyExtraction.ts
12997
13631
  import { SyntaxKind as SyntaxKind4 } from "ts-morph";
@@ -13566,23 +14200,23 @@ function buildPlan2(functionName, sourceFile, sourcePath, destPath, project) {
13566
14200
 
13567
14201
  // src/commands/refactor/extract/displayPlan.ts
13568
14202
  import path32 from "path";
13569
- import chalk140 from "chalk";
14203
+ import chalk143 from "chalk";
13570
14204
  function section(title) {
13571
14205
  return `
13572
- ${chalk140.cyan(title)}`;
14206
+ ${chalk143.cyan(title)}`;
13573
14207
  }
13574
14208
  function displayImporters(plan2, cwd) {
13575
14209
  if (plan2.importersToUpdate.length === 0) return;
13576
14210
  console.log(section("Update importers:"));
13577
14211
  for (const imp of plan2.importersToUpdate) {
13578
14212
  const rel = path32.relative(cwd, imp.file.getFilePath());
13579
- console.log(` ${chalk140.dim(rel)}: \u2192 import from "${imp.relPath}"`);
14213
+ console.log(` ${chalk143.dim(rel)}: \u2192 import from "${imp.relPath}"`);
13580
14214
  }
13581
14215
  }
13582
14216
  function displayPlan(functionName, relDest, plan2, cwd) {
13583
- console.log(chalk140.bold(`Extract: ${functionName} \u2192 ${relDest}
14217
+ console.log(chalk143.bold(`Extract: ${functionName} \u2192 ${relDest}
13584
14218
  `));
13585
- console.log(` ${chalk140.cyan("Functions to move:")}`);
14219
+ console.log(` ${chalk143.cyan("Functions to move:")}`);
13586
14220
  for (const name of plan2.extractedNames) {
13587
14221
  console.log(` ${name}`);
13588
14222
  }
@@ -13616,7 +14250,7 @@ function displayPlan(functionName, relDest, plan2, cwd) {
13616
14250
 
13617
14251
  // src/commands/refactor/extract/loadProjectFile.ts
13618
14252
  import path34 from "path";
13619
- import chalk141 from "chalk";
14253
+ import chalk144 from "chalk";
13620
14254
  import { Project as Project4 } from "ts-morph";
13621
14255
 
13622
14256
  // src/commands/refactor/extract/findTsConfig.ts
@@ -13676,7 +14310,7 @@ function loadProjectFile(file) {
13676
14310
  });
13677
14311
  const sourceFile = project.getSourceFile(sourcePath);
13678
14312
  if (!sourceFile) {
13679
- console.log(chalk141.red(`File not found in project: ${file}`));
14313
+ console.log(chalk144.red(`File not found in project: ${file}`));
13680
14314
  process.exit(1);
13681
14315
  }
13682
14316
  return { project, sourceFile };
@@ -13699,19 +14333,19 @@ async function extract(file, functionName, destination, options2 = {}) {
13699
14333
  displayPlan(functionName, relDest, plan2, cwd);
13700
14334
  if (options2.apply) {
13701
14335
  await applyExtraction(functionName, sourceFile, destPath, plan2, project);
13702
- console.log(chalk142.green("\nExtraction complete"));
14336
+ console.log(chalk145.green("\nExtraction complete"));
13703
14337
  } else {
13704
- console.log(chalk142.dim("\nDry run. Use --apply to execute."));
14338
+ console.log(chalk145.dim("\nDry run. Use --apply to execute."));
13705
14339
  }
13706
14340
  }
13707
14341
 
13708
14342
  // src/commands/refactor/ignore.ts
13709
14343
  import fs22 from "fs";
13710
- import chalk143 from "chalk";
14344
+ import chalk146 from "chalk";
13711
14345
  var REFACTOR_YML_PATH2 = "refactor.yml";
13712
14346
  function ignore(file) {
13713
14347
  if (!fs22.existsSync(file)) {
13714
- console.error(chalk143.red(`Error: File does not exist: ${file}`));
14348
+ console.error(chalk146.red(`Error: File does not exist: ${file}`));
13715
14349
  process.exit(1);
13716
14350
  }
13717
14351
  const content = fs22.readFileSync(file, "utf8");
@@ -13727,7 +14361,7 @@ function ignore(file) {
13727
14361
  fs22.writeFileSync(REFACTOR_YML_PATH2, entry);
13728
14362
  }
13729
14363
  console.log(
13730
- chalk143.green(
14364
+ chalk146.green(
13731
14365
  `Added ${file} to refactor ignore list (max ${maxLines} lines)`
13732
14366
  )
13733
14367
  );
@@ -13736,12 +14370,12 @@ function ignore(file) {
13736
14370
  // src/commands/refactor/rename/index.ts
13737
14371
  import fs25 from "fs";
13738
14372
  import path40 from "path";
13739
- import chalk146 from "chalk";
14373
+ import chalk149 from "chalk";
13740
14374
 
13741
14375
  // src/commands/refactor/rename/applyRename.ts
13742
14376
  import fs24 from "fs";
13743
14377
  import path37 from "path";
13744
- import chalk144 from "chalk";
14378
+ import chalk147 from "chalk";
13745
14379
 
13746
14380
  // src/commands/refactor/restructure/computeRewrites/index.ts
13747
14381
  import path36 from "path";
@@ -13846,13 +14480,13 @@ function applyRename(rewrites, sourcePath, destPath, cwd) {
13846
14480
  const updatedContents = applyRewrites(rewrites);
13847
14481
  for (const [file, content] of updatedContents) {
13848
14482
  fs24.writeFileSync(file, content, "utf8");
13849
- console.log(chalk144.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
14483
+ console.log(chalk147.cyan(` Updated imports in ${path37.relative(cwd, file)}`));
13850
14484
  }
13851
14485
  const destDir = path37.dirname(destPath);
13852
14486
  if (!fs24.existsSync(destDir)) fs24.mkdirSync(destDir, { recursive: true });
13853
14487
  fs24.renameSync(sourcePath, destPath);
13854
14488
  console.log(
13855
- chalk144.white(
14489
+ chalk147.white(
13856
14490
  ` Moved ${path37.relative(cwd, sourcePath)} \u2192 ${path37.relative(cwd, destPath)}`
13857
14491
  )
13858
14492
  );
@@ -13939,16 +14573,16 @@ function computeRenameRewrites(sourcePath, destPath) {
13939
14573
 
13940
14574
  // src/commands/refactor/rename/printRenamePreview.ts
13941
14575
  import path39 from "path";
13942
- import chalk145 from "chalk";
14576
+ import chalk148 from "chalk";
13943
14577
  function printRenamePreview(rewrites, cwd) {
13944
14578
  for (const rewrite of rewrites) {
13945
14579
  console.log(
13946
- chalk145.dim(
14580
+ chalk148.dim(
13947
14581
  ` ${path39.relative(cwd, rewrite.file)}: ${rewrite.oldSpecifier} \u2192 ${rewrite.newSpecifier}`
13948
14582
  )
13949
14583
  );
13950
14584
  }
13951
- console.log(chalk145.dim("Dry run. Use --apply to execute."));
14585
+ console.log(chalk148.dim("Dry run. Use --apply to execute."));
13952
14586
  }
13953
14587
 
13954
14588
  // src/commands/refactor/rename/index.ts
@@ -13959,20 +14593,20 @@ async function rename(source, destination, options2 = {}) {
13959
14593
  const relSource = path40.relative(cwd, sourcePath);
13960
14594
  const relDest = path40.relative(cwd, destPath);
13961
14595
  if (!fs25.existsSync(sourcePath)) {
13962
- console.log(chalk146.red(`File not found: ${source}`));
14596
+ console.log(chalk149.red(`File not found: ${source}`));
13963
14597
  process.exit(1);
13964
14598
  }
13965
14599
  if (destPath !== sourcePath && fs25.existsSync(destPath)) {
13966
- console.log(chalk146.red(`Destination already exists: ${destination}`));
14600
+ console.log(chalk149.red(`Destination already exists: ${destination}`));
13967
14601
  process.exit(1);
13968
14602
  }
13969
- console.log(chalk146.bold(`Rename: ${relSource} \u2192 ${relDest}`));
13970
- console.log(chalk146.dim("Loading project..."));
13971
- console.log(chalk146.dim("Scanning imports across the project..."));
14603
+ console.log(chalk149.bold(`Rename: ${relSource} \u2192 ${relDest}`));
14604
+ console.log(chalk149.dim("Loading project..."));
14605
+ console.log(chalk149.dim("Scanning imports across the project..."));
13972
14606
  const rewrites = computeRenameRewrites(sourcePath, destPath);
13973
14607
  const affectedFiles = new Set(rewrites.map((r) => r.file)).size;
13974
14608
  console.log(
13975
- chalk146.dim(
14609
+ chalk149.dim(
13976
14610
  `${rewrites.length} import path(s) to update across ${affectedFiles} file(s)`
13977
14611
  )
13978
14612
  );
@@ -13981,11 +14615,11 @@ async function rename(source, destination, options2 = {}) {
13981
14615
  return;
13982
14616
  }
13983
14617
  applyRename(rewrites, sourcePath, destPath, cwd);
13984
- console.log(chalk146.green("Done"));
14618
+ console.log(chalk149.green("Done"));
13985
14619
  }
13986
14620
 
13987
14621
  // src/commands/refactor/renameSymbol/index.ts
13988
- import chalk147 from "chalk";
14622
+ import chalk150 from "chalk";
13989
14623
 
13990
14624
  // src/commands/refactor/renameSymbol/findSymbol.ts
13991
14625
  import { SyntaxKind as SyntaxKind14 } from "ts-morph";
@@ -14031,33 +14665,33 @@ async function renameSymbol(file, oldName, newName, options2 = {}) {
14031
14665
  const { project, sourceFile } = loadProjectFile(file);
14032
14666
  const symbol = findSymbol(sourceFile, oldName);
14033
14667
  if (!symbol) {
14034
- console.log(chalk147.red(`Symbol "${oldName}" not found in ${file}`));
14668
+ console.log(chalk150.red(`Symbol "${oldName}" not found in ${file}`));
14035
14669
  process.exit(1);
14036
14670
  }
14037
14671
  const grouped = groupReferences(symbol, cwd);
14038
14672
  const totalRefs = [...grouped.values()].reduce((s, l) => s + l.length, 0);
14039
14673
  console.log(
14040
- chalk147.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
14674
+ chalk150.bold(`Rename: ${oldName} \u2192 ${newName} (${totalRefs} references)
14041
14675
  `)
14042
14676
  );
14043
14677
  for (const [refFile, lines] of grouped) {
14044
14678
  console.log(
14045
- ` ${chalk147.dim(refFile)}: lines ${chalk147.cyan(lines.join(", "))}`
14679
+ ` ${chalk150.dim(refFile)}: lines ${chalk150.cyan(lines.join(", "))}`
14046
14680
  );
14047
14681
  }
14048
14682
  if (options2.apply) {
14049
14683
  symbol.rename(newName);
14050
14684
  await project.save();
14051
- console.log(chalk147.green(`
14685
+ console.log(chalk150.green(`
14052
14686
  Renamed ${oldName} \u2192 ${newName}`));
14053
14687
  } else {
14054
- console.log(chalk147.dim("\nDry run. Use --apply to execute."));
14688
+ console.log(chalk150.dim("\nDry run. Use --apply to execute."));
14055
14689
  }
14056
14690
  }
14057
14691
 
14058
14692
  // src/commands/refactor/restructure/index.ts
14059
14693
  import path48 from "path";
14060
- import chalk150 from "chalk";
14694
+ import chalk153 from "chalk";
14061
14695
 
14062
14696
  // src/commands/refactor/restructure/clusterDirectories.ts
14063
14697
  import path42 from "path";
@@ -14136,50 +14770,50 @@ function clusterFiles(graph) {
14136
14770
 
14137
14771
  // src/commands/refactor/restructure/displayPlan.ts
14138
14772
  import path44 from "path";
14139
- import chalk148 from "chalk";
14773
+ import chalk151 from "chalk";
14140
14774
  function relPath(filePath) {
14141
14775
  return path44.relative(process.cwd(), filePath);
14142
14776
  }
14143
14777
  function displayMoves(plan2) {
14144
14778
  if (plan2.moves.length === 0) return;
14145
- console.log(chalk148.bold("\nFile moves:"));
14779
+ console.log(chalk151.bold("\nFile moves:"));
14146
14780
  for (const move of plan2.moves) {
14147
14781
  console.log(
14148
- ` ${chalk148.red(relPath(move.from))} \u2192 ${chalk148.green(relPath(move.to))}`
14782
+ ` ${chalk151.red(relPath(move.from))} \u2192 ${chalk151.green(relPath(move.to))}`
14149
14783
  );
14150
- console.log(chalk148.dim(` ${move.reason}`));
14784
+ console.log(chalk151.dim(` ${move.reason}`));
14151
14785
  }
14152
14786
  }
14153
14787
  function displayRewrites(rewrites) {
14154
14788
  if (rewrites.length === 0) return;
14155
14789
  const affectedFiles = new Set(rewrites.map((r) => r.file));
14156
- console.log(chalk148.bold(`
14790
+ console.log(chalk151.bold(`
14157
14791
  Import rewrites (${affectedFiles.size} files):`));
14158
14792
  for (const file of affectedFiles) {
14159
- console.log(` ${chalk148.cyan(relPath(file))}:`);
14793
+ console.log(` ${chalk151.cyan(relPath(file))}:`);
14160
14794
  for (const { oldSpecifier, newSpecifier } of rewrites.filter(
14161
14795
  (r) => r.file === file
14162
14796
  )) {
14163
14797
  console.log(
14164
- ` ${chalk148.red(`"${oldSpecifier}"`)} \u2192 ${chalk148.green(`"${newSpecifier}"`)}`
14798
+ ` ${chalk151.red(`"${oldSpecifier}"`)} \u2192 ${chalk151.green(`"${newSpecifier}"`)}`
14165
14799
  );
14166
14800
  }
14167
14801
  }
14168
14802
  }
14169
14803
  function displayPlan2(plan2) {
14170
14804
  if (plan2.warnings.length > 0) {
14171
- console.log(chalk148.yellow("\nWarnings:"));
14172
- for (const w of plan2.warnings) console.log(chalk148.yellow(` ${w}`));
14805
+ console.log(chalk151.yellow("\nWarnings:"));
14806
+ for (const w of plan2.warnings) console.log(chalk151.yellow(` ${w}`));
14173
14807
  }
14174
14808
  if (plan2.newDirectories.length > 0) {
14175
- console.log(chalk148.bold("\nNew directories:"));
14809
+ console.log(chalk151.bold("\nNew directories:"));
14176
14810
  for (const dir of plan2.newDirectories)
14177
- console.log(chalk148.green(` ${dir}/`));
14811
+ console.log(chalk151.green(` ${dir}/`));
14178
14812
  }
14179
14813
  displayMoves(plan2);
14180
14814
  displayRewrites(plan2.rewrites);
14181
14815
  console.log(
14182
- chalk148.dim(
14816
+ chalk151.dim(
14183
14817
  `
14184
14818
  Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports rewritten`
14185
14819
  )
@@ -14189,18 +14823,18 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
14189
14823
  // src/commands/refactor/restructure/executePlan.ts
14190
14824
  import fs26 from "fs";
14191
14825
  import path45 from "path";
14192
- import chalk149 from "chalk";
14826
+ import chalk152 from "chalk";
14193
14827
  function executePlan(plan2) {
14194
14828
  const updatedContents = applyRewrites(plan2.rewrites);
14195
14829
  for (const [file, content] of updatedContents) {
14196
14830
  fs26.writeFileSync(file, content, "utf8");
14197
14831
  console.log(
14198
- chalk149.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
14832
+ chalk152.cyan(` Rewrote imports in ${path45.relative(process.cwd(), file)}`)
14199
14833
  );
14200
14834
  }
14201
14835
  for (const dir of plan2.newDirectories) {
14202
14836
  fs26.mkdirSync(dir, { recursive: true });
14203
- console.log(chalk149.green(` Created ${path45.relative(process.cwd(), dir)}/`));
14837
+ console.log(chalk152.green(` Created ${path45.relative(process.cwd(), dir)}/`));
14204
14838
  }
14205
14839
  for (const move of plan2.moves) {
14206
14840
  const targetDir = path45.dirname(move.to);
@@ -14209,7 +14843,7 @@ function executePlan(plan2) {
14209
14843
  }
14210
14844
  fs26.renameSync(move.from, move.to);
14211
14845
  console.log(
14212
- chalk149.white(
14846
+ chalk152.white(
14213
14847
  ` Moved ${path45.relative(process.cwd(), move.from)} \u2192 ${path45.relative(process.cwd(), move.to)}`
14214
14848
  )
14215
14849
  );
@@ -14224,7 +14858,7 @@ function removeEmptyDirectories(dirs) {
14224
14858
  if (entries.length === 0) {
14225
14859
  fs26.rmdirSync(dir);
14226
14860
  console.log(
14227
- chalk149.dim(
14861
+ chalk152.dim(
14228
14862
  ` Removed empty directory ${path45.relative(process.cwd(), dir)}`
14229
14863
  )
14230
14864
  );
@@ -14357,22 +14991,22 @@ async function restructure(pattern2, options2 = {}) {
14357
14991
  const targetPattern = pattern2 ?? "src";
14358
14992
  const files = findSourceFiles2(targetPattern);
14359
14993
  if (files.length === 0) {
14360
- console.log(chalk150.yellow("No files found matching pattern"));
14994
+ console.log(chalk153.yellow("No files found matching pattern"));
14361
14995
  return;
14362
14996
  }
14363
14997
  const tsConfigPath = path48.resolve("tsconfig.json");
14364
14998
  const plan2 = buildPlan3(files, tsConfigPath);
14365
14999
  if (plan2.moves.length === 0) {
14366
- console.log(chalk150.green("No restructuring needed"));
15000
+ console.log(chalk153.green("No restructuring needed"));
14367
15001
  return;
14368
15002
  }
14369
15003
  displayPlan2(plan2);
14370
15004
  if (options2.apply) {
14371
- console.log(chalk150.bold("\nApplying changes..."));
15005
+ console.log(chalk153.bold("\nApplying changes..."));
14372
15006
  executePlan(plan2);
14373
- console.log(chalk150.green("\nRestructuring complete"));
15007
+ console.log(chalk153.green("\nRestructuring complete"));
14374
15008
  } else {
14375
- console.log(chalk150.dim("\nDry run. Use --apply to execute."));
15009
+ console.log(chalk153.dim("\nDry run. Use --apply to execute."));
14376
15010
  }
14377
15011
  }
14378
15012
 
@@ -14527,11 +15161,11 @@ ${annotateDiffWithLineNumbers(context.diff.trimEnd())}
14527
15161
  }
14528
15162
 
14529
15163
  // src/commands/review/buildReviewPaths.ts
14530
- import { homedir as homedir12 } from "os";
14531
- import { basename as basename7, join as join38 } from "path";
15164
+ import { homedir as homedir13 } from "os";
15165
+ import { basename as basename7, join as join43 } from "path";
14532
15166
  function buildReviewPaths(repoRoot, key) {
14533
- const reviewDir = join38(
14534
- homedir12(),
15167
+ const reviewDir = join43(
15168
+ homedir13(),
14535
15169
  ".assist",
14536
15170
  "reviews",
14537
15171
  basename7(repoRoot),
@@ -14539,10 +15173,10 @@ function buildReviewPaths(repoRoot, key) {
14539
15173
  );
14540
15174
  return {
14541
15175
  reviewDir,
14542
- requestPath: join38(reviewDir, "request.md"),
14543
- claudePath: join38(reviewDir, "claude.md"),
14544
- codexPath: join38(reviewDir, "codex.md"),
14545
- synthesisPath: join38(reviewDir, "synthesis.md")
15176
+ requestPath: join43(reviewDir, "request.md"),
15177
+ claudePath: join43(reviewDir, "claude.md"),
15178
+ codexPath: join43(reviewDir, "codex.md"),
15179
+ synthesisPath: join43(reviewDir, "synthesis.md")
14546
15180
  };
14547
15181
  }
14548
15182
 
@@ -14685,7 +15319,7 @@ function gatherContext() {
14685
15319
  }
14686
15320
 
14687
15321
  // src/commands/review/postReviewToPr.ts
14688
- import { readFileSync as readFileSync31 } from "fs";
15322
+ import { readFileSync as readFileSync32 } from "fs";
14689
15323
 
14690
15324
  // src/commands/review/parseFindings.ts
14691
15325
  var SEVERITIES = ["blocker", "major", "minor", "nit"];
@@ -14941,18 +15575,18 @@ function partitionFindingsByDiff(findings, index3) {
14941
15575
  }
14942
15576
 
14943
15577
  // src/commands/review/warnOutOfDiff.ts
14944
- import chalk151 from "chalk";
15578
+ import chalk154 from "chalk";
14945
15579
  function warnOutOfDiff(outOfDiff) {
14946
15580
  if (outOfDiff.length === 0) return;
14947
15581
  console.warn(
14948
- chalk151.yellow(
15582
+ chalk154.yellow(
14949
15583
  `Skipped ${outOfDiff.length} finding(s) whose lines fall outside the PR diff (GitHub would silently drop these):`
14950
15584
  )
14951
15585
  );
14952
15586
  for (const finding of outOfDiff) {
14953
15587
  const range = finding.startLine !== void 0 ? `${finding.startLine}-${finding.line}` : `${finding.line}`;
14954
15588
  console.warn(
14955
- ` ${chalk151.yellow("\xB7")} ${finding.title} ${chalk151.dim(
15589
+ ` ${chalk154.yellow("\xB7")} ${finding.title} ${chalk154.dim(
14956
15590
  `(${finding.file}:${range})`
14957
15591
  )}`
14958
15592
  );
@@ -14971,18 +15605,18 @@ function selectInDiffFindings(lineBound, prDiff) {
14971
15605
  }
14972
15606
 
14973
15607
  // src/commands/review/warnUnlocated.ts
14974
- import chalk152 from "chalk";
15608
+ import chalk155 from "chalk";
14975
15609
  function warnUnlocated(unlocated) {
14976
15610
  if (unlocated.length === 0) return;
14977
15611
  console.warn(
14978
- chalk152.yellow(
15612
+ chalk155.yellow(
14979
15613
  `Skipped ${unlocated.length} finding(s) without a parseable file:line:`
14980
15614
  )
14981
15615
  );
14982
15616
  for (const finding of unlocated) {
14983
- const where = finding.location || chalk152.dim("missing");
15617
+ const where = finding.location || chalk155.dim("missing");
14984
15618
  console.warn(
14985
- ` ${chalk152.yellow("\xB7")} ${finding.title} ${chalk152.dim(`(${where})`)}`
15619
+ ` ${chalk155.yellow("\xB7")} ${finding.title} ${chalk155.dim(`(${where})`)}`
14986
15620
  );
14987
15621
  }
14988
15622
  }
@@ -14995,7 +15629,7 @@ async function confirmPost(prNumber, count6, options2) {
14995
15629
  async function postReviewToPr(synthesisPath, options2) {
14996
15630
  const prInfo = fetchPrDiffInfo();
14997
15631
  const prNumber = prInfo.prNumber;
14998
- const markdown = readFileSync31(synthesisPath, "utf8");
15632
+ const markdown = readFileSync32(synthesisPath, "utf8");
14999
15633
  const findings = parseFindings(markdown);
15000
15634
  if (findings.length === 0) {
15001
15635
  console.log("Synthesis contains no findings; nothing to post.");
@@ -15077,7 +15711,7 @@ async function handlePostSynthesis(synthesisPath, options2) {
15077
15711
  }
15078
15712
 
15079
15713
  // src/commands/review/prepareReviewDir.ts
15080
- import { existsSync as existsSync35, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync29 } from "fs";
15714
+ import { existsSync as existsSync35, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync30 } from "fs";
15081
15715
  function clearReviewFiles(paths) {
15082
15716
  for (const path58 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
15083
15717
  if (existsSync35(path58)) unlinkSync12(path58);
@@ -15086,7 +15720,7 @@ function clearReviewFiles(paths) {
15086
15720
  function prepareReviewDir(paths, requestBody, force) {
15087
15721
  mkdirSync14(paths.reviewDir, { recursive: true });
15088
15722
  if (force) clearReviewFiles(paths);
15089
- writeFileSync29(paths.requestPath, requestBody);
15723
+ writeFileSync30(paths.requestPath, requestBody);
15090
15724
  }
15091
15725
 
15092
15726
  // src/commands/review/runApplySession.ts
@@ -15431,7 +16065,7 @@ The review request is at: ${requestPath}
15431
16065
  }
15432
16066
 
15433
16067
  // src/commands/review/runClaudeReviewer.ts
15434
- import { writeFileSync as writeFileSync30 } from "fs";
16068
+ import { writeFileSync as writeFileSync31 } from "fs";
15435
16069
 
15436
16070
  // src/commands/review/finaliseReviewerSpinner.ts
15437
16071
  var SUMMARY_MAX_LEN = 80;
@@ -15689,12 +16323,12 @@ function onCloseResult(ctx, code) {
15689
16323
  return { ...closed, stderr: ctx.stderr.value, stdout: ctx.stdout.value };
15690
16324
  }
15691
16325
  function waitForChildExit(ctx) {
15692
- return new Promise((resolve16) => {
16326
+ return new Promise((resolve17) => {
15693
16327
  let settled = false;
15694
16328
  const settle = (result) => {
15695
16329
  if (settled) return;
15696
16330
  settled = true;
15697
- resolve16(result);
16331
+ resolve17(result);
15698
16332
  };
15699
16333
  ctx.child.on("error", (err) => settle(onErrorResult(ctx, err)));
15700
16334
  ctx.child.on("close", (code) => settle(onCloseResult(ctx, code)));
@@ -15767,7 +16401,7 @@ async function runClaudeReviewer(spec) {
15767
16401
  }
15768
16402
  });
15769
16403
  if (result.exitCode === 0 && finalText)
15770
- writeFileSync30(spec.outputPath, finalText);
16404
+ writeFileSync31(spec.outputPath, finalText);
15771
16405
  return finaliseReviewerRun({ ...spec, command }, spinner, result);
15772
16406
  }
15773
16407
 
@@ -15879,7 +16513,7 @@ async function runReviewers(reviewDir, claudePath, codexPath, stdinPrompt, optio
15879
16513
  }
15880
16514
 
15881
16515
  // src/commands/review/synthesise.ts
15882
- import { readFileSync as readFileSync32 } from "fs";
16516
+ import { readFileSync as readFileSync33 } from "fs";
15883
16517
 
15884
16518
  // src/commands/review/buildSynthesisStdin.ts
15885
16519
  var SYNTHESIS_PROMPT = `You are consolidating two independent code reviews of the same change. The original review request is in request.md. The two reviews are in claude.md and codex.md in the current working directory.
@@ -15935,7 +16569,7 @@ Files:
15935
16569
 
15936
16570
  // src/commands/review/synthesise.ts
15937
16571
  function printSummary2(synthesisPath) {
15938
- const markdown = readFileSync32(synthesisPath, "utf8");
16572
+ const markdown = readFileSync33(synthesisPath, "utf8");
15939
16573
  console.log("");
15940
16574
  console.log(buildReviewSummary(markdown));
15941
16575
  console.log("");
@@ -16153,7 +16787,7 @@ function registerReview(program2) {
16153
16787
  }
16154
16788
 
16155
16789
  // src/commands/seq/seqAuth.ts
16156
- import chalk154 from "chalk";
16790
+ import chalk157 from "chalk";
16157
16791
 
16158
16792
  // src/commands/seq/loadConnections.ts
16159
16793
  function loadConnections2() {
@@ -16182,10 +16816,10 @@ function setDefaultConnection(name) {
16182
16816
  }
16183
16817
 
16184
16818
  // src/shared/assertUniqueName.ts
16185
- import chalk153 from "chalk";
16819
+ import chalk156 from "chalk";
16186
16820
  function assertUniqueName(existingNames, name) {
16187
16821
  if (existingNames.includes(name)) {
16188
- console.error(chalk153.red(`Connection "${name}" already exists.`));
16822
+ console.error(chalk156.red(`Connection "${name}" already exists.`));
16189
16823
  process.exit(1);
16190
16824
  }
16191
16825
  }
@@ -16203,16 +16837,16 @@ async function promptConnection2(existingNames) {
16203
16837
  var seqAuth = createConnectionAuth({
16204
16838
  load: loadConnections2,
16205
16839
  save: saveConnections2,
16206
- format: (c) => `${chalk154.bold(c.name)} ${c.url}`,
16840
+ format: (c) => `${chalk157.bold(c.name)} ${c.url}`,
16207
16841
  promptNew: promptConnection2,
16208
16842
  onFirst: (c) => setDefaultConnection(c.name)
16209
16843
  });
16210
16844
 
16211
16845
  // src/commands/seq/seqQuery.ts
16212
- import chalk158 from "chalk";
16846
+ import chalk161 from "chalk";
16213
16847
 
16214
16848
  // src/commands/seq/fetchSeq.ts
16215
- import chalk155 from "chalk";
16849
+ import chalk158 from "chalk";
16216
16850
  async function fetchSeq(conn, path58, params) {
16217
16851
  const url = `${conn.url}${path58}?${params}`;
16218
16852
  const response = await fetch(url, {
@@ -16223,7 +16857,7 @@ async function fetchSeq(conn, path58, params) {
16223
16857
  });
16224
16858
  if (!response.ok) {
16225
16859
  const body = await response.text();
16226
- console.error(chalk155.red(`Seq returned ${response.status}: ${body}`));
16860
+ console.error(chalk158.red(`Seq returned ${response.status}: ${body}`));
16227
16861
  process.exit(1);
16228
16862
  }
16229
16863
  return response;
@@ -16282,23 +16916,23 @@ async function fetchSeqEvents(conn, params) {
16282
16916
  }
16283
16917
 
16284
16918
  // src/commands/seq/formatEvent.ts
16285
- import chalk156 from "chalk";
16919
+ import chalk159 from "chalk";
16286
16920
  function levelColor(level) {
16287
16921
  switch (level) {
16288
16922
  case "Fatal":
16289
- return chalk156.bgRed.white;
16923
+ return chalk159.bgRed.white;
16290
16924
  case "Error":
16291
- return chalk156.red;
16925
+ return chalk159.red;
16292
16926
  case "Warning":
16293
- return chalk156.yellow;
16927
+ return chalk159.yellow;
16294
16928
  case "Information":
16295
- return chalk156.cyan;
16929
+ return chalk159.cyan;
16296
16930
  case "Debug":
16297
- return chalk156.gray;
16931
+ return chalk159.gray;
16298
16932
  case "Verbose":
16299
- return chalk156.dim;
16933
+ return chalk159.dim;
16300
16934
  default:
16301
- return chalk156.white;
16935
+ return chalk159.white;
16302
16936
  }
16303
16937
  }
16304
16938
  function levelAbbrev(level) {
@@ -16339,12 +16973,12 @@ function formatTimestamp(iso) {
16339
16973
  function formatEvent(event) {
16340
16974
  const color = levelColor(event.Level);
16341
16975
  const abbrev = levelAbbrev(event.Level);
16342
- const ts8 = chalk156.dim(formatTimestamp(event.Timestamp));
16976
+ const ts8 = chalk159.dim(formatTimestamp(event.Timestamp));
16343
16977
  const msg = renderMessage(event);
16344
16978
  const lines = [`${ts8} ${color(`[${abbrev}]`)} ${msg}`];
16345
16979
  if (event.Exception) {
16346
16980
  for (const line of event.Exception.split("\n")) {
16347
- lines.push(chalk156.red(` ${line}`));
16981
+ lines.push(chalk159.red(` ${line}`));
16348
16982
  }
16349
16983
  }
16350
16984
  return lines.join("\n");
@@ -16377,11 +17011,11 @@ function rejectTimestampFilter(filter) {
16377
17011
  }
16378
17012
 
16379
17013
  // src/shared/resolveNamedConnection.ts
16380
- import chalk157 from "chalk";
17014
+ import chalk160 from "chalk";
16381
17015
  function resolveNamedConnection(connections, requested, defaultName, kind, authCommand) {
16382
17016
  if (connections.length === 0) {
16383
17017
  console.error(
16384
- chalk157.red(
17018
+ chalk160.red(
16385
17019
  `No ${kind} connections configured. Run '${authCommand}' first.`
16386
17020
  )
16387
17021
  );
@@ -16390,7 +17024,7 @@ function resolveNamedConnection(connections, requested, defaultName, kind, authC
16390
17024
  const target = requested ?? defaultName ?? connections[0].name;
16391
17025
  const connection = connections.find((c) => c.name === target);
16392
17026
  if (!connection) {
16393
- console.error(chalk157.red(`${kind} connection "${target}" not found.`));
17027
+ console.error(chalk160.red(`${kind} connection "${target}" not found.`));
16394
17028
  process.exit(1);
16395
17029
  }
16396
17030
  return connection;
@@ -16419,7 +17053,7 @@ async function seqQuery(filter, options2) {
16419
17053
  new URLSearchParams({ filter, count: String(count6) })
16420
17054
  );
16421
17055
  if (events.length === 0) {
16422
- console.log(chalk158.yellow("No events found."));
17056
+ console.log(chalk161.yellow("No events found."));
16423
17057
  return;
16424
17058
  }
16425
17059
  if (options2.json) {
@@ -16430,11 +17064,11 @@ async function seqQuery(filter, options2) {
16430
17064
  for (const event of chronological) {
16431
17065
  console.log(formatEvent(event));
16432
17066
  }
16433
- console.log(chalk158.dim(`
17067
+ console.log(chalk161.dim(`
16434
17068
  ${events.length} events`));
16435
17069
  if (events.length >= count6) {
16436
17070
  console.log(
16437
- chalk158.yellow(
17071
+ chalk161.yellow(
16438
17072
  `Results limited to ${count6}. Use --count to retrieve more.`
16439
17073
  )
16440
17074
  );
@@ -16442,10 +17076,10 @@ ${events.length} events`));
16442
17076
  }
16443
17077
 
16444
17078
  // src/shared/setNamedDefaultConnection.ts
16445
- import chalk159 from "chalk";
17079
+ import chalk162 from "chalk";
16446
17080
  function setNamedDefaultConnection(connections, name, setDefault, kind) {
16447
17081
  if (!connections.find((c) => c.name === name)) {
16448
- console.error(chalk159.red(`Connection "${name}" not found.`));
17082
+ console.error(chalk162.red(`Connection "${name}" not found.`));
16449
17083
  process.exit(1);
16450
17084
  }
16451
17085
  setDefault(name);
@@ -16493,7 +17127,7 @@ function registerSignal(program2) {
16493
17127
  }
16494
17128
 
16495
17129
  // src/commands/sql/sqlAuth.ts
16496
- import chalk161 from "chalk";
17130
+ import chalk164 from "chalk";
16497
17131
 
16498
17132
  // src/commands/sql/loadConnections.ts
16499
17133
  function loadConnections3() {
@@ -16522,7 +17156,7 @@ function setDefaultConnection2(name) {
16522
17156
  }
16523
17157
 
16524
17158
  // src/commands/sql/promptConnection.ts
16525
- import chalk160 from "chalk";
17159
+ import chalk163 from "chalk";
16526
17160
  async function promptConnection3(existingNames) {
16527
17161
  const name = await promptInput("name", "Connection name:", "default");
16528
17162
  assertUniqueName(existingNames, name);
@@ -16530,7 +17164,7 @@ async function promptConnection3(existingNames) {
16530
17164
  const portStr = await promptInput("port", "Port:", "1433");
16531
17165
  const port = Number.parseInt(portStr, 10);
16532
17166
  if (!Number.isFinite(port)) {
16533
- console.error(chalk160.red(`Invalid port "${portStr}".`));
17167
+ console.error(chalk163.red(`Invalid port "${portStr}".`));
16534
17168
  process.exit(1);
16535
17169
  }
16536
17170
  const user = await promptInput("user", "User:");
@@ -16543,13 +17177,13 @@ async function promptConnection3(existingNames) {
16543
17177
  var sqlAuth = createConnectionAuth({
16544
17178
  load: loadConnections3,
16545
17179
  save: saveConnections3,
16546
- format: (c) => `${chalk161.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
17180
+ format: (c) => `${chalk164.bold(c.name)} ${c.server}:${c.port}/${c.database} (${c.user})`,
16547
17181
  promptNew: promptConnection3,
16548
17182
  onFirst: (c) => setDefaultConnection2(c.name)
16549
17183
  });
16550
17184
 
16551
17185
  // src/commands/sql/printTable.ts
16552
- import chalk162 from "chalk";
17186
+ import chalk165 from "chalk";
16553
17187
  function formatCell(value) {
16554
17188
  if (value === null || value === void 0) return "";
16555
17189
  if (value instanceof Date) return value.toISOString();
@@ -16558,7 +17192,7 @@ function formatCell(value) {
16558
17192
  }
16559
17193
  function printTable(rows) {
16560
17194
  if (rows.length === 0) {
16561
- console.log(chalk162.yellow("(no rows)"));
17195
+ console.log(chalk165.yellow("(no rows)"));
16562
17196
  return;
16563
17197
  }
16564
17198
  const columns = Object.keys(rows[0]);
@@ -16566,13 +17200,13 @@ function printTable(rows) {
16566
17200
  (col) => Math.max(col.length, ...rows.map((r) => formatCell(r[col]).length))
16567
17201
  );
16568
17202
  const header = columns.map((c, i) => c.padEnd(widths[i])).join(" ");
16569
- console.log(chalk162.dim(header));
16570
- console.log(chalk162.dim("-".repeat(header.length)));
17203
+ console.log(chalk165.dim(header));
17204
+ console.log(chalk165.dim("-".repeat(header.length)));
16571
17205
  for (const row of rows) {
16572
17206
  const line = columns.map((c, i) => formatCell(row[c]).padEnd(widths[i])).join(" ");
16573
17207
  console.log(line);
16574
17208
  }
16575
- console.log(chalk162.dim(`
17209
+ console.log(chalk165.dim(`
16576
17210
  ${rows.length} row${rows.length === 1 ? "" : "s"}`));
16577
17211
  }
16578
17212
 
@@ -16632,7 +17266,7 @@ async function sqlColumns(table, connectionName) {
16632
17266
  }
16633
17267
 
16634
17268
  // src/commands/sql/sqlMutate.ts
16635
- import chalk163 from "chalk";
17269
+ import chalk166 from "chalk";
16636
17270
 
16637
17271
  // src/commands/sql/isMutation.ts
16638
17272
  var MUTATION_KEYWORDS = [
@@ -16666,7 +17300,7 @@ function isMutation(sql6) {
16666
17300
  async function sqlMutate(query, connectionName) {
16667
17301
  if (!isMutation(query)) {
16668
17302
  console.error(
16669
- chalk163.red(
17303
+ chalk166.red(
16670
17304
  "assist sql mutate refuses non-mutating statements. Use `assist sql query` instead."
16671
17305
  )
16672
17306
  );
@@ -16676,18 +17310,18 @@ async function sqlMutate(query, connectionName) {
16676
17310
  const pool = await sqlConnect(conn);
16677
17311
  try {
16678
17312
  const result = await pool.request().query(query);
16679
- console.log(chalk163.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
17313
+ console.log(chalk166.dim(`${result.rowsAffected.join(", ")} row(s) affected`));
16680
17314
  } finally {
16681
17315
  await pool.close();
16682
17316
  }
16683
17317
  }
16684
17318
 
16685
17319
  // src/commands/sql/sqlQuery.ts
16686
- import chalk164 from "chalk";
17320
+ import chalk167 from "chalk";
16687
17321
  async function sqlQuery(query, connectionName) {
16688
17322
  if (isMutation(query)) {
16689
17323
  console.error(
16690
- chalk164.red(
17324
+ chalk167.red(
16691
17325
  "assist sql query refuses mutating statements. Use `assist sql mutate` instead."
16692
17326
  )
16693
17327
  );
@@ -16702,7 +17336,7 @@ async function sqlQuery(query, connectionName) {
16702
17336
  printTable(rows);
16703
17337
  } else {
16704
17338
  console.log(
16705
- chalk164.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
17339
+ chalk167.dim(`${result.rowsAffected.join(", ")} row(s) affected`)
16706
17340
  );
16707
17341
  }
16708
17342
  } finally {
@@ -16763,7 +17397,7 @@ function registerSql(program2) {
16763
17397
 
16764
17398
  // src/commands/transcript/shared.ts
16765
17399
  import { existsSync as existsSync38, readdirSync as readdirSync7, statSync as statSync5 } from "fs";
16766
- import { basename as basename8, join as join39, relative as relative2 } from "path";
17400
+ import { basename as basename8, join as join44, relative as relative2 } from "path";
16767
17401
  import * as readline2 from "readline";
16768
17402
  var DATE_PREFIX_REGEX = /^\d{4}-\d{2}-\d{2}/;
16769
17403
  function getDatePrefix(daysOffset = 0) {
@@ -16781,7 +17415,7 @@ function collectFiles(dir, extension) {
16781
17415
  if (!existsSync38(dir)) return [];
16782
17416
  const results = [];
16783
17417
  for (const entry of readdirSync7(dir)) {
16784
- const fullPath = join39(dir, entry);
17418
+ const fullPath = join44(dir, entry);
16785
17419
  if (statSync5(fullPath).isDirectory()) {
16786
17420
  results.push(...collectFiles(fullPath, extension));
16787
17421
  } else if (entry.endsWith(extension)) {
@@ -16813,9 +17447,9 @@ function createReadlineInterface() {
16813
17447
  });
16814
17448
  }
16815
17449
  function askQuestion(rl, question) {
16816
- return new Promise((resolve16) => {
17450
+ return new Promise((resolve17) => {
16817
17451
  rl.question(question, (answer) => {
16818
- resolve16(answer.trim());
17452
+ resolve17(answer.trim());
16819
17453
  });
16820
17454
  });
16821
17455
  }
@@ -16878,11 +17512,11 @@ async function configure() {
16878
17512
  import { existsSync as existsSync40 } from "fs";
16879
17513
 
16880
17514
  // src/commands/transcript/format/fixInvalidDatePrefixes/index.ts
16881
- import { dirname as dirname20, join as join41 } from "path";
17515
+ import { dirname as dirname22, join as join46 } from "path";
16882
17516
 
16883
17517
  // src/commands/transcript/format/fixInvalidDatePrefixes/promptForDateFix.ts
16884
17518
  import { renameSync as renameSync2 } from "fs";
16885
- import { join as join40 } from "path";
17519
+ import { join as join45 } from "path";
16886
17520
  async function resolveDate(rl, choice) {
16887
17521
  if (choice === "1") return getDatePrefix(0);
16888
17522
  if (choice === "2") return getDatePrefix(-1);
@@ -16897,7 +17531,7 @@ async function resolveDate(rl, choice) {
16897
17531
  }
16898
17532
  function renameWithPrefix(vttDir, vttFile, prefix2) {
16899
17533
  const newFilename = `${prefix2}.${vttFile}`;
16900
- renameSync2(join40(vttDir, vttFile), join40(vttDir, newFilename));
17534
+ renameSync2(join45(vttDir, vttFile), join45(vttDir, newFilename));
16901
17535
  console.log(`Renamed to: ${newFilename}`);
16902
17536
  return newFilename;
16903
17537
  }
@@ -16928,15 +17562,15 @@ async function fixInvalidDatePrefixes(vttFiles) {
16928
17562
  for (let i = 0; i < vttFiles.length; i++) {
16929
17563
  const vttFile = vttFiles[i];
16930
17564
  if (!isValidDatePrefix(vttFile.filename)) {
16931
- const vttFileDir = dirname20(vttFile.absolutePath);
17565
+ const vttFileDir = dirname22(vttFile.absolutePath);
16932
17566
  const newFilename = await promptForDateFix(vttFile.filename, vttFileDir);
16933
17567
  if (newFilename) {
16934
- const newRelativePath = join41(
16935
- dirname20(vttFile.relativePath),
17568
+ const newRelativePath = join46(
17569
+ dirname22(vttFile.relativePath),
16936
17570
  newFilename
16937
17571
  );
16938
17572
  vttFiles[i] = {
16939
- absolutePath: join41(vttFileDir, newFilename),
17573
+ absolutePath: join46(vttFileDir, newFilename),
16940
17574
  relativePath: newRelativePath,
16941
17575
  filename: newFilename
16942
17576
  };
@@ -16949,8 +17583,8 @@ async function fixInvalidDatePrefixes(vttFiles) {
16949
17583
  }
16950
17584
 
16951
17585
  // src/commands/transcript/format/processVttFile/index.ts
16952
- import { existsSync as existsSync39, mkdirSync as mkdirSync15, readFileSync as readFileSync33, writeFileSync as writeFileSync31 } from "fs";
16953
- import { basename as basename9, dirname as dirname21, join as join42 } from "path";
17586
+ import { existsSync as existsSync39, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync32 } from "fs";
17587
+ import { basename as basename9, dirname as dirname23, join as join47 } from "path";
16954
17588
 
16955
17589
  // src/commands/transcript/cleanText.ts
16956
17590
  function cleanText(text5) {
@@ -17160,17 +17794,17 @@ function toMdFilename(vttFilename) {
17160
17794
  return `${basename9(vttFilename, ".vtt").replace(/\s*Transcription\s*/g, " ").trim()}.md`;
17161
17795
  }
17162
17796
  function resolveOutputDir(relativeDir, transcriptsDir) {
17163
- return relativeDir === "." ? transcriptsDir : join42(transcriptsDir, relativeDir);
17797
+ return relativeDir === "." ? transcriptsDir : join47(transcriptsDir, relativeDir);
17164
17798
  }
17165
17799
  function buildOutputPaths(vttFile, transcriptsDir) {
17166
17800
  const mdFile = toMdFilename(vttFile.filename);
17167
- const relativeDir = dirname21(vttFile.relativePath);
17801
+ const relativeDir = dirname23(vttFile.relativePath);
17168
17802
  const outputDir = resolveOutputDir(relativeDir, transcriptsDir);
17169
- const outputPath = join42(outputDir, mdFile);
17803
+ const outputPath = join47(outputDir, mdFile);
17170
17804
  return { outputDir, outputPath, mdFile, relativeDir };
17171
17805
  }
17172
17806
  function logSkipped(relativeDir, mdFile) {
17173
- console.log(`Skipping (already exists): ${join42(relativeDir, mdFile)}`);
17807
+ console.log(`Skipping (already exists): ${join47(relativeDir, mdFile)}`);
17174
17808
  return "skipped";
17175
17809
  }
17176
17810
  function ensureDirectory(dir, label2) {
@@ -17197,10 +17831,10 @@ function logReduction(cueCount, messageCount) {
17197
17831
  }
17198
17832
  function readAndParseCues(inputPath) {
17199
17833
  console.log(`Reading: ${inputPath}`);
17200
- return processCues(readFileSync33(inputPath, "utf8"));
17834
+ return processCues(readFileSync34(inputPath, "utf8"));
17201
17835
  }
17202
17836
  function writeFormatted(outputPath, content) {
17203
- writeFileSync31(outputPath, content, "utf8");
17837
+ writeFileSync32(outputPath, content, "utf8");
17204
17838
  console.log(`Written: ${outputPath}`);
17205
17839
  }
17206
17840
  function convertVttToMarkdown(inputPath, outputPath) {
@@ -17269,27 +17903,27 @@ async function format() {
17269
17903
 
17270
17904
  // src/commands/transcript/summarise/index.ts
17271
17905
  import { existsSync as existsSync42 } from "fs";
17272
- import { basename as basename10, dirname as dirname23, join as join44, relative as relative3 } from "path";
17906
+ import { basename as basename10, dirname as dirname25, join as join49, relative as relative3 } from "path";
17273
17907
 
17274
17908
  // src/commands/transcript/summarise/processStagedFile/index.ts
17275
17909
  import {
17276
17910
  existsSync as existsSync41,
17277
17911
  mkdirSync as mkdirSync16,
17278
- readFileSync as readFileSync34,
17912
+ readFileSync as readFileSync35,
17279
17913
  renameSync as renameSync3,
17280
17914
  rmSync as rmSync4
17281
17915
  } from "fs";
17282
- import { dirname as dirname22, join as join43 } from "path";
17916
+ import { dirname as dirname24, join as join48 } from "path";
17283
17917
 
17284
17918
  // src/commands/transcript/summarise/processStagedFile/validateStagedContent.ts
17285
- import chalk165 from "chalk";
17919
+ import chalk168 from "chalk";
17286
17920
  var FULL_TRANSCRIPT_REGEX = /^\[Full Transcript\]\(([^)]+)\)/;
17287
17921
  function validateStagedContent(filename, content) {
17288
17922
  const firstLine = content.split("\n")[0];
17289
17923
  const match = firstLine.match(FULL_TRANSCRIPT_REGEX);
17290
17924
  if (!match) {
17291
17925
  console.error(
17292
- chalk165.red(
17926
+ chalk168.red(
17293
17927
  `Staged file ${filename} missing [Full Transcript](<path>) link on first line.`
17294
17928
  )
17295
17929
  );
@@ -17298,7 +17932,7 @@ function validateStagedContent(filename, content) {
17298
17932
  const contentAfterLink = content.slice(firstLine.length).trim();
17299
17933
  if (!contentAfterLink) {
17300
17934
  console.error(
17301
- chalk165.red(
17935
+ chalk168.red(
17302
17936
  `Staged file ${filename} has no summary content after the transcript link.`
17303
17937
  )
17304
17938
  );
@@ -17308,7 +17942,7 @@ function validateStagedContent(filename, content) {
17308
17942
  }
17309
17943
 
17310
17944
  // src/commands/transcript/summarise/processStagedFile/index.ts
17311
- var STAGING_DIR = join43(process.cwd(), ".assist", "transcript");
17945
+ var STAGING_DIR = join48(process.cwd(), ".assist", "transcript");
17312
17946
  function processStagedFile() {
17313
17947
  if (!existsSync41(STAGING_DIR)) {
17314
17948
  return false;
@@ -17319,7 +17953,7 @@ function processStagedFile() {
17319
17953
  }
17320
17954
  const { transcriptsDir, summaryDir } = getTranscriptConfig();
17321
17955
  const stagedFile = stagedFiles[0];
17322
- const content = readFileSync34(stagedFile.absolutePath, "utf8");
17956
+ const content = readFileSync35(stagedFile.absolutePath, "utf8");
17323
17957
  validateStagedContent(stagedFile.filename, content);
17324
17958
  const stagedBaseName = getTranscriptBaseName(stagedFile.filename);
17325
17959
  const transcriptFiles = findMdFilesRecursive(transcriptsDir);
@@ -17332,8 +17966,8 @@ function processStagedFile() {
17332
17966
  );
17333
17967
  process.exit(1);
17334
17968
  }
17335
- const destPath = join43(summaryDir, matchingTranscript.relativePath);
17336
- const destDir = dirname22(destPath);
17969
+ const destPath = join48(summaryDir, matchingTranscript.relativePath);
17970
+ const destDir = dirname24(destPath);
17337
17971
  if (!existsSync41(destDir)) {
17338
17972
  mkdirSync16(destDir, { recursive: true });
17339
17973
  }
@@ -17347,8 +17981,8 @@ function processStagedFile() {
17347
17981
 
17348
17982
  // src/commands/transcript/summarise/index.ts
17349
17983
  function buildRelativeKey(relativePath, baseName) {
17350
- const relDir = dirname23(relativePath);
17351
- return relDir === "." ? baseName : join44(relDir, baseName);
17984
+ const relDir = dirname25(relativePath);
17985
+ return relDir === "." ? baseName : join49(relDir, baseName);
17352
17986
  }
17353
17987
  function buildSummaryIndex(summaryDir) {
17354
17988
  const summaryFiles = findMdFilesRecursive(summaryDir);
@@ -17382,8 +18016,8 @@ function summarise2() {
17382
18016
  }
17383
18017
  const next3 = missing[0];
17384
18018
  const outputFilename = `${getTranscriptBaseName(next3.filename)}.md`;
17385
- const outputPath = join44(STAGING_DIR, outputFilename);
17386
- const summaryFileDir = join44(summaryDir, dirname23(next3.relativePath));
18019
+ const outputPath = join49(STAGING_DIR, outputFilename);
18020
+ const summaryFileDir = join49(summaryDir, dirname25(next3.relativePath));
17387
18021
  const relativeTranscriptPath = encodeURI(
17388
18022
  relative3(summaryFileDir, next3.absolutePath).replace(/\\/g, "/")
17389
18023
  );
@@ -17433,50 +18067,50 @@ function registerVerify(program2) {
17433
18067
 
17434
18068
  // src/commands/voice/devices.ts
17435
18069
  import { spawnSync as spawnSync5 } from "child_process";
17436
- import { join as join46 } from "path";
18070
+ import { join as join51 } from "path";
17437
18071
 
17438
18072
  // src/commands/voice/shared.ts
17439
- import { homedir as homedir13 } from "os";
17440
- import { dirname as dirname24, join as join45 } from "path";
17441
- import { fileURLToPath as fileURLToPath5 } from "url";
17442
- var __dirname5 = dirname24(fileURLToPath5(import.meta.url));
17443
- var VOICE_DIR = join45(homedir13(), ".assist", "voice");
18073
+ import { homedir as homedir14 } from "os";
18074
+ import { dirname as dirname26, join as join50 } from "path";
18075
+ import { fileURLToPath as fileURLToPath6 } from "url";
18076
+ var __dirname5 = dirname26(fileURLToPath6(import.meta.url));
18077
+ var VOICE_DIR = join50(homedir14(), ".assist", "voice");
17444
18078
  var voicePaths = {
17445
18079
  dir: VOICE_DIR,
17446
- pid: join45(VOICE_DIR, "voice.pid"),
17447
- log: join45(VOICE_DIR, "voice.log"),
17448
- venv: join45(VOICE_DIR, ".venv"),
17449
- lock: join45(VOICE_DIR, "voice.lock")
18080
+ pid: join50(VOICE_DIR, "voice.pid"),
18081
+ log: join50(VOICE_DIR, "voice.log"),
18082
+ venv: join50(VOICE_DIR, ".venv"),
18083
+ lock: join50(VOICE_DIR, "voice.lock")
17450
18084
  };
17451
18085
  function getPythonDir() {
17452
- return join45(__dirname5, "commands", "voice", "python");
18086
+ return join50(__dirname5, "commands", "voice", "python");
17453
18087
  }
17454
18088
  function getVenvPython() {
17455
- return process.platform === "win32" ? join45(voicePaths.venv, "Scripts", "python.exe") : join45(voicePaths.venv, "bin", "python");
18089
+ return process.platform === "win32" ? join50(voicePaths.venv, "Scripts", "python.exe") : join50(voicePaths.venv, "bin", "python");
17456
18090
  }
17457
18091
  function getLockDir() {
17458
18092
  const config = loadConfig();
17459
18093
  return config.voice?.lockDir ?? VOICE_DIR;
17460
18094
  }
17461
18095
  function getLockFile() {
17462
- return join45(getLockDir(), "voice.lock");
18096
+ return join50(getLockDir(), "voice.lock");
17463
18097
  }
17464
18098
 
17465
18099
  // src/commands/voice/devices.ts
17466
18100
  function devices() {
17467
- const script = join46(getPythonDir(), "list_devices.py");
18101
+ const script = join51(getPythonDir(), "list_devices.py");
17468
18102
  spawnSync5(getVenvPython(), [script], { stdio: "inherit" });
17469
18103
  }
17470
18104
 
17471
18105
  // src/commands/voice/logs.ts
17472
- import { existsSync as existsSync43, readFileSync as readFileSync35 } from "fs";
18106
+ import { existsSync as existsSync43, readFileSync as readFileSync36 } from "fs";
17473
18107
  function logs(options2) {
17474
18108
  if (!existsSync43(voicePaths.log)) {
17475
18109
  console.log("No voice log file found");
17476
18110
  return;
17477
18111
  }
17478
18112
  const count6 = Number.parseInt(options2.lines ?? "150", 10);
17479
- const content = readFileSync35(voicePaths.log, "utf8").trim();
18113
+ const content = readFileSync36(voicePaths.log, "utf8").trim();
17480
18114
  if (!content) {
17481
18115
  console.log("Voice log is empty");
17482
18116
  return;
@@ -17499,12 +18133,12 @@ function logs(options2) {
17499
18133
  // src/commands/voice/setup.ts
17500
18134
  import { spawnSync as spawnSync6 } from "child_process";
17501
18135
  import { mkdirSync as mkdirSync18 } from "fs";
17502
- import { join as join48 } from "path";
18136
+ import { join as join53 } from "path";
17503
18137
 
17504
18138
  // src/commands/voice/checkLockFile.ts
17505
18139
  import { execSync as execSync46 } from "child_process";
17506
- import { existsSync as existsSync44, mkdirSync as mkdirSync17, readFileSync as readFileSync36, writeFileSync as writeFileSync32 } from "fs";
17507
- import { join as join47 } from "path";
18140
+ import { existsSync as existsSync44, mkdirSync as mkdirSync17, readFileSync as readFileSync37, writeFileSync as writeFileSync33 } from "fs";
18141
+ import { join as join52 } from "path";
17508
18142
  function isProcessAlive2(pid) {
17509
18143
  try {
17510
18144
  process.kill(pid, 0);
@@ -17517,7 +18151,7 @@ function checkLockFile() {
17517
18151
  const lockFile = getLockFile();
17518
18152
  if (!existsSync44(lockFile)) return;
17519
18153
  try {
17520
- const lock = JSON.parse(readFileSync36(lockFile, "utf8"));
18154
+ const lock = JSON.parse(readFileSync37(lockFile, "utf8"));
17521
18155
  if (lock.pid && isProcessAlive2(lock.pid)) {
17522
18156
  console.error(
17523
18157
  `Voice daemon already running (PID ${lock.pid}, env: ${lock.env}). Stop it first with: assist voice stop`
@@ -17541,8 +18175,8 @@ function bootstrapVenv() {
17541
18175
  }
17542
18176
  function writeLockFile(pid) {
17543
18177
  const lockFile = getLockFile();
17544
- mkdirSync17(join47(lockFile, ".."), { recursive: true });
17545
- writeFileSync32(
18178
+ mkdirSync17(join52(lockFile, ".."), { recursive: true });
18179
+ writeFileSync33(
17546
18180
  lockFile,
17547
18181
  JSON.stringify({
17548
18182
  pid,
@@ -17557,7 +18191,7 @@ function setup() {
17557
18191
  mkdirSync18(voicePaths.dir, { recursive: true });
17558
18192
  bootstrapVenv();
17559
18193
  console.log("\nDownloading models...\n");
17560
- const script = join48(getPythonDir(), "setup_models.py");
18194
+ const script = join53(getPythonDir(), "setup_models.py");
17561
18195
  const result = spawnSync6(getVenvPython(), [script], {
17562
18196
  stdio: "inherit",
17563
18197
  env: { ...process.env, VOICE_LOG_FILE: voicePaths.log }
@@ -17570,8 +18204,8 @@ function setup() {
17570
18204
 
17571
18205
  // src/commands/voice/start.ts
17572
18206
  import { spawn as spawn7 } from "child_process";
17573
- import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync33 } from "fs";
17574
- import { join as join49 } from "path";
18207
+ import { mkdirSync as mkdirSync19, writeFileSync as writeFileSync34 } from "fs";
18208
+ import { join as join54 } from "path";
17575
18209
 
17576
18210
  // src/commands/voice/buildDaemonEnv.ts
17577
18211
  function buildDaemonEnv(options2) {
@@ -17599,7 +18233,7 @@ function spawnBackground(python, script, env) {
17599
18233
  console.error("Failed to start voice daemon");
17600
18234
  process.exit(1);
17601
18235
  }
17602
- writeFileSync33(voicePaths.pid, String(pid));
18236
+ writeFileSync34(voicePaths.pid, String(pid));
17603
18237
  writeLockFile(pid);
17604
18238
  console.log(`Voice daemon started (PID ${pid})`);
17605
18239
  }
@@ -17609,7 +18243,7 @@ function start2(options2) {
17609
18243
  bootstrapVenv();
17610
18244
  const debug = options2.debug || options2.foreground || process.platform === "win32";
17611
18245
  const env = buildDaemonEnv({ debug });
17612
- const script = join49(getPythonDir(), "voice_daemon.py");
18246
+ const script = join54(getPythonDir(), "voice_daemon.py");
17613
18247
  const python = getVenvPython();
17614
18248
  if (options2.foreground) {
17615
18249
  spawnForeground(python, script, env);
@@ -17619,7 +18253,7 @@ function start2(options2) {
17619
18253
  }
17620
18254
 
17621
18255
  // src/commands/voice/status.ts
17622
- import { existsSync as existsSync45, readFileSync as readFileSync37 } from "fs";
18256
+ import { existsSync as existsSync45, readFileSync as readFileSync38 } from "fs";
17623
18257
  function isProcessAlive3(pid) {
17624
18258
  try {
17625
18259
  process.kill(pid, 0);
@@ -17630,7 +18264,7 @@ function isProcessAlive3(pid) {
17630
18264
  }
17631
18265
  function readRecentLogs(count6) {
17632
18266
  if (!existsSync45(voicePaths.log)) return [];
17633
- const lines = readFileSync37(voicePaths.log, "utf8").trim().split("\n");
18267
+ const lines = readFileSync38(voicePaths.log, "utf8").trim().split("\n");
17634
18268
  return lines.slice(-count6);
17635
18269
  }
17636
18270
  function status() {
@@ -17638,7 +18272,7 @@ function status() {
17638
18272
  console.log("Voice daemon: not running (no PID file)");
17639
18273
  return;
17640
18274
  }
17641
- const pid = Number.parseInt(readFileSync37(voicePaths.pid, "utf8").trim(), 10);
18275
+ const pid = Number.parseInt(readFileSync38(voicePaths.pid, "utf8").trim(), 10);
17642
18276
  const alive = isProcessAlive3(pid);
17643
18277
  console.log(`Voice daemon: ${alive ? "running" : "dead"} (PID ${pid})`);
17644
18278
  const recent = readRecentLogs(5);
@@ -17657,13 +18291,13 @@ function status() {
17657
18291
  }
17658
18292
 
17659
18293
  // src/commands/voice/stop.ts
17660
- import { existsSync as existsSync46, readFileSync as readFileSync38, unlinkSync as unlinkSync15 } from "fs";
18294
+ import { existsSync as existsSync46, readFileSync as readFileSync39, unlinkSync as unlinkSync15 } from "fs";
17661
18295
  function stop2() {
17662
18296
  if (!existsSync46(voicePaths.pid)) {
17663
18297
  console.log("Voice daemon is not running (no PID file)");
17664
18298
  return;
17665
18299
  }
17666
- const pid = Number.parseInt(readFileSync38(voicePaths.pid, "utf8").trim(), 10);
18300
+ const pid = Number.parseInt(readFileSync39(voicePaths.pid, "utf8").trim(), 10);
17667
18301
  try {
17668
18302
  process.kill(pid, "SIGTERM");
17669
18303
  console.log(`Sent SIGTERM to voice daemon (PID ${pid})`);
@@ -17695,10 +18329,10 @@ function registerVoice(program2) {
17695
18329
 
17696
18330
  // src/commands/roam/auth.ts
17697
18331
  import { randomBytes } from "crypto";
17698
- import chalk166 from "chalk";
18332
+ import chalk169 from "chalk";
17699
18333
 
17700
18334
  // src/commands/roam/waitForCallback.ts
17701
- import { createServer as createServer2 } from "http";
18335
+ import { createServer as createServer3 } from "http";
17702
18336
  function respondHtml(res, status2, title) {
17703
18337
  res.writeHead(status2, { "Content-Type": "text/html" });
17704
18338
  res.end(
@@ -17716,12 +18350,12 @@ function extractCode(url, expectedState) {
17716
18350
  return code;
17717
18351
  }
17718
18352
  function waitForCallback(port, expectedState) {
17719
- return new Promise((resolve16, reject) => {
18353
+ return new Promise((resolve17, reject) => {
17720
18354
  const timeout = setTimeout(() => {
17721
18355
  server.close();
17722
18356
  reject(new Error("Authorization timed out after 120 seconds"));
17723
18357
  }, 12e4);
17724
- const server = createServer2((req, res) => {
18358
+ const server = createServer3((req, res) => {
17725
18359
  const url = new URL(req.url ?? "/", `http://localhost:${port}`);
17726
18360
  if (url.pathname !== "/callback") {
17727
18361
  res.writeHead(404);
@@ -17733,7 +18367,7 @@ function waitForCallback(port, expectedState) {
17733
18367
  const code = extractCode(url, expectedState);
17734
18368
  respondHtml(res, 200, "Authorization successful!");
17735
18369
  server.close();
17736
- resolve16(code);
18370
+ resolve17(code);
17737
18371
  } catch (error) {
17738
18372
  respondHtml(res, 400, error.message);
17739
18373
  server.close();
@@ -17826,13 +18460,13 @@ async function auth() {
17826
18460
  saveGlobalConfig(config);
17827
18461
  const state = randomBytes(16).toString("hex");
17828
18462
  console.log(
17829
- chalk166.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
18463
+ chalk169.yellow("\nEnsure this Redirect URI is set in your Roam OAuth app:")
17830
18464
  );
17831
- console.log(chalk166.white("http://localhost:14523/callback\n"));
17832
- console.log(chalk166.blue("Opening browser for authorization..."));
17833
- console.log(chalk166.dim("Waiting for authorization callback..."));
18465
+ console.log(chalk169.white("http://localhost:14523/callback\n"));
18466
+ console.log(chalk169.blue("Opening browser for authorization..."));
18467
+ console.log(chalk169.dim("Waiting for authorization callback..."));
17834
18468
  const { code, redirectUri } = await authorizeInBrowser(clientId, state);
17835
- console.log(chalk166.dim("Exchanging code for tokens..."));
18469
+ console.log(chalk169.dim("Exchanging code for tokens..."));
17836
18470
  const tokens = await exchangeToken({
17837
18471
  code,
17838
18472
  clientId,
@@ -17848,14 +18482,14 @@ async function auth() {
17848
18482
  };
17849
18483
  saveGlobalConfig(config);
17850
18484
  console.log(
17851
- chalk166.green("Roam credentials and tokens saved to ~/.assist.yml")
18485
+ chalk169.green("Roam credentials and tokens saved to ~/.assist.yml")
17852
18486
  );
17853
18487
  }
17854
18488
 
17855
18489
  // src/commands/roam/postRoamActivity.ts
17856
18490
  import { execFileSync as execFileSync7 } from "child_process";
17857
- import { readdirSync as readdirSync8, readFileSync as readFileSync39, statSync as statSync6 } from "fs";
17858
- import { join as join50 } from "path";
18491
+ import { readdirSync as readdirSync8, readFileSync as readFileSync40, statSync as statSync6 } from "fs";
18492
+ import { join as join55 } from "path";
17859
18493
  function findPortFile(roamDir) {
17860
18494
  let entries;
17861
18495
  try {
@@ -17864,7 +18498,7 @@ function findPortFile(roamDir) {
17864
18498
  return void 0;
17865
18499
  }
17866
18500
  const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
17867
- const path58 = join50(roamDir, name);
18501
+ const path58 = join55(roamDir, name);
17868
18502
  try {
17869
18503
  return { path: path58, mtimeMs: statSync6(path58).mtimeMs };
17870
18504
  } catch {
@@ -17876,11 +18510,11 @@ function findPortFile(roamDir) {
17876
18510
  function postRoamActivity(app, event) {
17877
18511
  const appData = process.env.APPDATA;
17878
18512
  if (!appData) return;
17879
- const portFile = findPortFile(join50(appData, "Roam"));
18513
+ const portFile = findPortFile(join55(appData, "Roam"));
17880
18514
  if (!portFile) return;
17881
18515
  let port;
17882
18516
  try {
17883
- port = readFileSync39(portFile, "utf8").trim();
18517
+ port = readFileSync40(portFile, "utf8").trim();
17884
18518
  } catch {
17885
18519
  return;
17886
18520
  }
@@ -17924,7 +18558,7 @@ function registerRoam(program2) {
17924
18558
  }
17925
18559
 
17926
18560
  // src/commands/run/index.ts
17927
- import { resolve as resolve12 } from "path";
18561
+ import { resolve as resolve13 } from "path";
17928
18562
 
17929
18563
  // src/commands/run/findRunConfig.ts
17930
18564
  function exitNoRunConfigs() {
@@ -18023,13 +18657,13 @@ function runPreCommands(pre, cwd) {
18023
18657
  // src/commands/run/spawnRunCommand.ts
18024
18658
  import { execFileSync as execFileSync8, spawn as spawn8 } from "child_process";
18025
18659
  import { existsSync as existsSync47 } from "fs";
18026
- import { dirname as dirname25, join as join51, resolve as resolve11 } from "path";
18660
+ import { dirname as dirname27, join as join56, resolve as resolve12 } from "path";
18027
18661
  function resolveCommand2(command) {
18028
18662
  if (process.platform !== "win32" || command !== "bash") return command;
18029
18663
  try {
18030
18664
  const gitPath = execFileSync8("where", ["git"], { encoding: "utf8" }).trim().split("\r\n")[0];
18031
- const gitRoot = resolve11(dirname25(gitPath), "..");
18032
- const gitBash = join51(gitRoot, "bin", "bash.exe");
18665
+ const gitRoot = resolve12(dirname27(gitPath), "..");
18666
+ const gitBash = join56(gitRoot, "bin", "bash.exe");
18033
18667
  if (existsSync47(gitBash)) return gitBash;
18034
18668
  } catch {
18035
18669
  }
@@ -18076,7 +18710,7 @@ function listRunConfigs(verbose) {
18076
18710
  }
18077
18711
  }
18078
18712
  function execRunConfig(config, args) {
18079
- const cwd = config.cwd ? resolve12(getConfigDir(), config.cwd) : void 0;
18713
+ const cwd = config.cwd ? resolve13(getConfigDir(), config.cwd) : void 0;
18080
18714
  if (config.pre) runPreCommands(config.pre, cwd);
18081
18715
  const resolved = resolveParams(config.params, args);
18082
18716
  spawnRunCommand(
@@ -18115,8 +18749,8 @@ async function run3(name, args) {
18115
18749
  }
18116
18750
 
18117
18751
  // src/commands/run/add.ts
18118
- import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync34 } from "fs";
18119
- import { join as join52 } from "path";
18752
+ import { mkdirSync as mkdirSync20, writeFileSync as writeFileSync35 } from "fs";
18753
+ import { join as join57 } from "path";
18120
18754
 
18121
18755
  // src/commands/run/extractOption.ts
18122
18756
  function extractOption(args, flag) {
@@ -18177,7 +18811,7 @@ function saveNewRunConfig(name, command, args, cwd) {
18177
18811
  saveConfig(config);
18178
18812
  }
18179
18813
  function createCommandFile(name) {
18180
- const dir = join52(".claude", "commands");
18814
+ const dir = join57(".claude", "commands");
18181
18815
  mkdirSync20(dir, { recursive: true });
18182
18816
  const content = `---
18183
18817
  description: Run ${name}
@@ -18185,8 +18819,8 @@ description: Run ${name}
18185
18819
 
18186
18820
  Run \`assist run ${name} $ARGUMENTS 2>&1\`.
18187
18821
  `;
18188
- const filePath = join52(dir, `${name}.md`);
18189
- writeFileSync34(filePath, content);
18822
+ const filePath = join57(dir, `${name}.md`);
18823
+ writeFileSync35(filePath, content);
18190
18824
  console.log(`Created command file: ${filePath}`);
18191
18825
  }
18192
18826
  function add3() {
@@ -18242,7 +18876,7 @@ function link2() {
18242
18876
 
18243
18877
  // src/commands/run/remove.ts
18244
18878
  import { existsSync as existsSync48, unlinkSync as unlinkSync16 } from "fs";
18245
- import { join as join53 } from "path";
18879
+ import { join as join58 } from "path";
18246
18880
  function findRemoveIndex() {
18247
18881
  const idx = process.argv.indexOf("remove");
18248
18882
  if (idx === -1 || idx + 1 >= process.argv.length) return -1;
@@ -18257,7 +18891,7 @@ function parseRemoveName() {
18257
18891
  return process.argv[idx + 1];
18258
18892
  }
18259
18893
  function deleteCommandFile(name) {
18260
- const filePath = join53(".claude", "commands", `${name}.md`);
18894
+ const filePath = join58(".claude", "commands", `${name}.md`);
18261
18895
  if (existsSync48(filePath)) {
18262
18896
  unlinkSync16(filePath);
18263
18897
  console.log(`Deleted command file: ${filePath}`);
@@ -18297,10 +18931,10 @@ function registerRun(program2) {
18297
18931
 
18298
18932
  // src/commands/screenshot/index.ts
18299
18933
  import { execSync as execSync48 } from "child_process";
18300
- import { existsSync as existsSync49, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync35 } from "fs";
18934
+ import { existsSync as existsSync49, mkdirSync as mkdirSync21, unlinkSync as unlinkSync17, writeFileSync as writeFileSync36 } from "fs";
18301
18935
  import { tmpdir as tmpdir7 } from "os";
18302
- import { join as join54, resolve as resolve13 } from "path";
18303
- import chalk167 from "chalk";
18936
+ import { join as join59, resolve as resolve14 } from "path";
18937
+ import chalk170 from "chalk";
18304
18938
 
18305
18939
  // src/commands/screenshot/captureWindowPs1.ts
18306
18940
  var captureWindowPs1 = `
@@ -18433,11 +19067,11 @@ function buildOutputPath(outputDir, processName) {
18433
19067
  mkdirSync21(outputDir, { recursive: true });
18434
19068
  }
18435
19069
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
18436
- return resolve13(outputDir, `${processName}-${timestamp2}.png`);
19070
+ return resolve14(outputDir, `${processName}-${timestamp2}.png`);
18437
19071
  }
18438
19072
  function runPowerShellScript(processName, outputPath) {
18439
- const scriptPath = join54(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
18440
- writeFileSync35(scriptPath, captureWindowPs1, "utf8");
19073
+ const scriptPath = join59(tmpdir7(), `assist-screenshot-${Date.now()}.ps1`);
19074
+ writeFileSync36(scriptPath, captureWindowPs1, "utf8");
18441
19075
  try {
18442
19076
  execSync48(
18443
19077
  `powershell -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}" -ProcessName "${processName}" -OutputPath "${outputPath}"`,
@@ -18449,15 +19083,15 @@ function runPowerShellScript(processName, outputPath) {
18449
19083
  }
18450
19084
  function screenshot(processName) {
18451
19085
  const config = loadConfig();
18452
- const outputDir = resolve13(config.screenshot.outputDir);
19086
+ const outputDir = resolve14(config.screenshot.outputDir);
18453
19087
  const outputPath = buildOutputPath(outputDir, processName);
18454
- console.log(chalk167.gray(`Capturing window for process "${processName}" ...`));
19088
+ console.log(chalk170.gray(`Capturing window for process "${processName}" ...`));
18455
19089
  try {
18456
19090
  runPowerShellScript(processName, outputPath);
18457
- console.log(chalk167.green(`Screenshot saved: ${outputPath}`));
19091
+ console.log(chalk170.green(`Screenshot saved: ${outputPath}`));
18458
19092
  } catch (error) {
18459
19093
  const msg = error instanceof Error ? error.message : String(error);
18460
- console.error(chalk167.red(`Failed to capture screenshot: ${msg}`));
19094
+ console.error(chalk170.red(`Failed to capture screenshot: ${msg}`));
18461
19095
  process.exit(1);
18462
19096
  }
18463
19097
  }
@@ -18482,10 +19116,10 @@ var STATUS_TIMEOUT_MS = 5e3;
18482
19116
  function queryDaemon(socket) {
18483
19117
  socket.write(`${JSON.stringify({ type: "ping" })}
18484
19118
  `);
18485
- return new Promise((resolve16) => {
19119
+ return new Promise((resolve17) => {
18486
19120
  const result = { sessions: [] };
18487
19121
  const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
18488
- const timer = setTimeout(() => resolve16(result), STATUS_TIMEOUT_MS);
19122
+ const timer = setTimeout(() => resolve17(result), STATUS_TIMEOUT_MS);
18489
19123
  const lines = createInterface4({ input: socket });
18490
19124
  lines.on("error", () => {
18491
19125
  });
@@ -18493,7 +19127,7 @@ function queryDaemon(socket) {
18493
19127
  applyLine(result, pending, line);
18494
19128
  if (pending.size === 0) {
18495
19129
  clearTimeout(timer);
18496
- resolve16(result);
19130
+ resolve17(result);
18497
19131
  }
18498
19132
  });
18499
19133
  });
@@ -18513,7 +19147,7 @@ function applyLine(result, pending, line) {
18513
19147
  }
18514
19148
 
18515
19149
  // src/commands/sessions/daemon/reportStolenSocket.ts
18516
- import { readFileSync as readFileSync40 } from "fs";
19150
+ import { readFileSync as readFileSync41 } from "fs";
18517
19151
  function reportStolenSocket(socketPid) {
18518
19152
  if (!socketPid) return;
18519
19153
  const filePid = readPidFile();
@@ -18525,7 +19159,7 @@ function reportStolenSocket(socketPid) {
18525
19159
  function readPidFile() {
18526
19160
  try {
18527
19161
  const pid = Number.parseInt(
18528
- readFileSync40(daemonPaths.pid, "utf8").trim(),
19162
+ readFileSync41(daemonPaths.pid, "utf8").trim(),
18529
19163
  10
18530
19164
  );
18531
19165
  return Number.isInteger(pid) ? pid : void 0;
@@ -18644,6 +19278,7 @@ var persistedSessionSchema = z6.object({
18644
19278
  commandType: z6.enum(["claude", "run", "assist"]),
18645
19279
  cwd: z6.string(),
18646
19280
  startedAt: z6.number(),
19281
+ runningMs: z6.number().optional(),
18647
19282
  claudeSessionId: z6.string().optional(),
18648
19283
  runName: z6.string().optional(),
18649
19284
  runArgs: z6.array(z6.string()).optional(),
@@ -18672,6 +19307,7 @@ function toPersistedSession(session) {
18672
19307
  commandType: session.commandType,
18673
19308
  cwd: session.cwd ?? process.cwd(),
18674
19309
  startedAt: session.startedAt,
19310
+ runningMs: accumulatedRunningMs(session),
18675
19311
  claudeSessionId: session.claudeSessionId,
18676
19312
  runName: session.runName,
18677
19313
  runArgs: session.runArgs,
@@ -18679,6 +19315,9 @@ function toPersistedSession(session) {
18679
19315
  activity: session.activity
18680
19316
  };
18681
19317
  }
19318
+ function accumulatedRunningMs(session) {
19319
+ return session.runningSince != null ? session.runningMs + Date.now() - session.runningSince : session.runningMs;
19320
+ }
18682
19321
 
18683
19322
  // src/commands/sessions/daemon/toSessionInfo.ts
18684
19323
  function toSessionInfo({
@@ -18687,6 +19326,8 @@ function toSessionInfo({
18687
19326
  commandType,
18688
19327
  status: status2,
18689
19328
  startedAt,
19329
+ runningMs,
19330
+ runningSince,
18690
19331
  runName,
18691
19332
  runArgs,
18692
19333
  assistArgs,
@@ -18703,6 +19344,8 @@ function toSessionInfo({
18703
19344
  commandType,
18704
19345
  status: status2,
18705
19346
  startedAt,
19347
+ runningMs,
19348
+ runningSince,
18706
19349
  runName,
18707
19350
  runArgs,
18708
19351
  assistArgs,
@@ -18828,12 +19471,15 @@ function shellEscape(s) {
18828
19471
 
18829
19472
  // src/commands/sessions/daemon/createAssistSession.ts
18830
19473
  function createAssistSession(id2, assistArgs, cwd) {
19474
+ const startedAt = Date.now();
18831
19475
  return {
18832
19476
  id: id2,
18833
19477
  name: `assist ${assistArgs.join(" ")}`,
18834
19478
  commandType: "assist",
18835
19479
  status: "running",
18836
- startedAt: Date.now(),
19480
+ startedAt,
19481
+ runningMs: 0,
19482
+ runningSince: startedAt,
18837
19483
  pty: spawnPty(["assist", ...assistArgs], cwd, id2),
18838
19484
  scrollback: "",
18839
19485
  assistArgs,
@@ -18861,24 +19507,30 @@ function spawnRun(opts) {
18861
19507
 
18862
19508
  // src/commands/sessions/daemon/createSession.ts
18863
19509
  function createSession(id2, prompt, cwd) {
19510
+ const startedAt = Date.now();
18864
19511
  return {
18865
19512
  id: id2,
18866
19513
  name: prompt?.slice(0, 40) || `Session ${id2}`,
18867
19514
  commandType: "claude",
18868
19515
  status: "running",
18869
- startedAt: Date.now(),
19516
+ startedAt,
19517
+ runningMs: 0,
19518
+ runningSince: startedAt,
18870
19519
  pty: spawnClaude2({ prompt, cwd, sessionId: id2 }),
18871
19520
  scrollback: "",
18872
19521
  cwd
18873
19522
  };
18874
19523
  }
18875
19524
  function createRunSession(id2, runName, runArgs, cwd) {
19525
+ const startedAt = Date.now();
18876
19526
  return {
18877
19527
  id: id2,
18878
19528
  name: `run: ${runName}`,
18879
19529
  commandType: "run",
18880
19530
  status: "running",
18881
- startedAt: Date.now(),
19531
+ startedAt,
19532
+ runningMs: 0,
19533
+ runningSince: startedAt,
18882
19534
  pty: spawnRun({ name: runName, args: runArgs, cwd }),
18883
19535
  scrollback: "",
18884
19536
  runName,
@@ -18902,6 +19554,16 @@ function greetClient(client, sessions, windowsProxy) {
18902
19554
  void windowsProxy.discover();
18903
19555
  }
18904
19556
 
19557
+ // src/commands/sessions/daemon/setStatus.ts
19558
+ function setStatus2(session, newStatus) {
19559
+ const now = Date.now();
19560
+ if (session.status === "running" && session.runningSince != null) {
19561
+ session.runningMs += now - session.runningSince;
19562
+ }
19563
+ session.runningSince = newStatus === "running" ? now : null;
19564
+ session.status = newStatus;
19565
+ }
19566
+
18905
19567
  // src/commands/sessions/daemon/watchEscInterrupt.ts
18906
19568
  var ESC2 = "\x1B";
18907
19569
  var SETTLE_MS = 1e3;
@@ -18957,7 +19619,7 @@ function applyStatusChange(session, status2, exitCode, dismiss, notify2, reuseFo
18957
19619
  disarmEscInterrupt(session);
18958
19620
  if (session.status === status2) return;
18959
19621
  daemonLog(`session ${session.id} status: ${session.status} -> ${status2}`);
18960
- session.status = status2;
19622
+ setStatus2(session, status2);
18961
19623
  if (shouldAutoRun(session, exitCode) && session.activity?.itemId != null) {
18962
19624
  reuseForRun(session, session.activity.itemId);
18963
19625
  notify2();
@@ -18990,6 +19652,8 @@ function errorSession(id2, persisted, error) {
18990
19652
  ...restoreBase(id2, persisted),
18991
19653
  status: "error",
18992
19654
  startedAt: persisted.startedAt,
19655
+ runningMs: persisted.runningMs ?? 0,
19656
+ runningSince: null,
18993
19657
  pty: null,
18994
19658
  runName: persisted.runName,
18995
19659
  runArgs: persisted.runArgs,
@@ -19006,10 +19670,13 @@ function backlogRunArgs(persisted) {
19006
19670
 
19007
19671
  // src/commands/sessions/daemon/runningSession.ts
19008
19672
  function runningSession(base, persisted, pty2) {
19673
+ const startedAt = Date.now();
19009
19674
  return {
19010
19675
  ...base,
19011
19676
  status: "running",
19012
- startedAt: Date.now(),
19677
+ startedAt,
19678
+ runningMs: persisted.runningMs ?? 0,
19679
+ runningSince: startedAt,
19013
19680
  pty: pty2,
19014
19681
  claudeSessionId: persisted.claudeSessionId,
19015
19682
  restored: true,
@@ -19044,6 +19711,8 @@ function restoreSession(id2, persisted) {
19044
19711
  ...base,
19045
19712
  status: "done",
19046
19713
  startedAt: persisted.startedAt,
19714
+ runningMs: persisted.runningMs ?? 0,
19715
+ runningSince: null,
19047
19716
  pty: null,
19048
19717
  runName: persisted.runName,
19049
19718
  runArgs: persisted.runArgs,
@@ -19086,12 +19755,15 @@ function restoreAll(spawn12, sessions) {
19086
19755
 
19087
19756
  // src/commands/sessions/daemon/resumeSession.ts
19088
19757
  function resumeSession(id2, sessionId, cwd, name) {
19758
+ const startedAt = Date.now();
19089
19759
  return {
19090
19760
  id: id2,
19091
19761
  name: name ? `${name.slice(0, 36)} (R)` : `Resume ${sessionId.slice(0, 8)}`,
19092
19762
  commandType: "claude",
19093
19763
  status: "running",
19094
- startedAt: Date.now(),
19764
+ startedAt,
19765
+ runningMs: 0,
19766
+ runningSince: startedAt,
19095
19767
  pty: spawnClaude2({ resumeSessionId: sessionId, cwd, sessionId: id2 }),
19096
19768
  scrollback: "",
19097
19769
  cwd
@@ -19100,12 +19772,12 @@ function resumeSession(id2, sessionId, cwd, name) {
19100
19772
 
19101
19773
  // src/commands/sessions/daemon/watchActivity.ts
19102
19774
  import { existsSync as existsSync51, mkdirSync as mkdirSync22, watch } from "fs";
19103
- import { dirname as dirname26 } from "path";
19775
+ import { dirname as dirname28 } from "path";
19104
19776
  var DEBOUNCE_MS = 50;
19105
19777
  function watchActivity(session, notify2) {
19106
19778
  if (session.commandType !== "assist" || !session.cwd) return;
19107
19779
  const path58 = activityPath(session.id);
19108
- const dir = dirname26(path58);
19780
+ const dir = dirname28(path58);
19109
19781
  try {
19110
19782
  mkdirSync22(dir, { recursive: true });
19111
19783
  } catch {
@@ -19172,8 +19844,10 @@ function retrySession(session, clients, onStatusChange) {
19172
19844
  if (!respawn) return false;
19173
19845
  if (session.status !== "done") session.pty?.kill();
19174
19846
  session.scrollback = "";
19175
- session.status = "running";
19176
19847
  session.startedAt = Date.now();
19848
+ session.runningMs = 0;
19849
+ session.runningSince = null;
19850
+ setStatus2(session, "running");
19177
19851
  session.restored = void 0;
19178
19852
  session.pty = respawn();
19179
19853
  broadcast(clients, { type: "clear", sessionId: session.id });
@@ -19196,8 +19870,10 @@ function reuseSessionForRun(session, itemId, clients, onStatusChange) {
19196
19870
  session.assistArgs = assistArgs;
19197
19871
  session.name = `assist ${assistArgs.join(" ")}`;
19198
19872
  session.commandType = "assist";
19199
- session.status = "running";
19200
19873
  session.startedAt = Date.now();
19874
+ session.runningMs = 0;
19875
+ session.runningSince = null;
19876
+ setStatus2(session, "running");
19201
19877
  session.restored = void 0;
19202
19878
  session.pty = spawnPty(["assist", ...assistArgs], session.cwd, session.id);
19203
19879
  wirePtyEvents(session, clients, onStatusChange);
@@ -19225,10 +19901,10 @@ function windowsDaemonHost() {
19225
19901
 
19226
19902
  // src/commands/sessions/daemon/connectToWindowsDaemon.ts
19227
19903
  function connectToWindowsDaemon() {
19228
- return new Promise((resolve16, reject) => {
19904
+ return new Promise((resolve17, reject) => {
19229
19905
  const socket = net2.connect(windowsDaemonPort(), windowsDaemonHost());
19230
19906
  socket.setKeepAlive(true, 1e4);
19231
- socket.once("connect", () => resolve16(socket));
19907
+ socket.once("connect", () => resolve17(socket));
19232
19908
  socket.once("error", reject);
19233
19909
  });
19234
19910
  }
@@ -19305,7 +19981,7 @@ async function waitForWindowsDaemon() {
19305
19981
  );
19306
19982
  }
19307
19983
  function delay2(ms) {
19308
- return new Promise((resolve16) => setTimeout(resolve16, ms));
19984
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
19309
19985
  }
19310
19986
 
19311
19987
  // src/commands/sessions/daemon/defaultConnect.ts
@@ -19472,7 +20148,7 @@ async function healWindowsDaemon() {
19472
20148
  daemonLog("windows daemon: auto-heal: stale daemon stopped");
19473
20149
  }
19474
20150
  function runOnWindowsHost(command, timeoutMs) {
19475
- return new Promise((resolve16, reject) => {
20151
+ return new Promise((resolve17, reject) => {
19476
20152
  const child = spawn11("pwsh.exe", ["-Command", command], {
19477
20153
  stdio: ["ignore", "pipe", "pipe"]
19478
20154
  });
@@ -19492,7 +20168,7 @@ function runOnWindowsHost(command, timeoutMs) {
19492
20168
  });
19493
20169
  child.on("exit", (code) => {
19494
20170
  clearTimeout(timer);
19495
- if (code === 0) resolve16();
20171
+ if (code === 0) resolve17();
19496
20172
  else
19497
20173
  reject(
19498
20174
  new Error(
@@ -19967,7 +20643,7 @@ async function createdSince(filePath, sinceMs) {
19967
20643
  }
19968
20644
  }
19969
20645
  function sleep(ms) {
19970
- return new Promise((resolve16) => setTimeout(resolve16, ms));
20646
+ return new Promise((resolve17) => setTimeout(resolve17, ms));
19971
20647
  }
19972
20648
 
19973
20649
  // src/commands/sessions/daemon/watchForClaudeSessionId.ts
@@ -20346,10 +21022,10 @@ function handleConnection(socket, manager) {
20346
21022
  }
20347
21023
 
20348
21024
  // src/commands/sessions/daemon/onListening.ts
20349
- import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync36 } from "fs";
21025
+ import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync37 } from "fs";
20350
21026
 
20351
21027
  // src/commands/sessions/daemon/startPidFileWatchdog.ts
20352
- import { readFileSync as readFileSync41 } from "fs";
21028
+ import { readFileSync as readFileSync42 } from "fs";
20353
21029
  var WATCHDOG_INTERVAL_MS = 5e3;
20354
21030
  function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
20355
21031
  const timer = setInterval(() => {
@@ -20360,7 +21036,7 @@ function startPidFileWatchdog(onLost, intervalMs = WATCHDOG_INTERVAL_MS) {
20360
21036
  }
20361
21037
  function ownsPidFile() {
20362
21038
  try {
20363
- return readFileSync41(daemonPaths.pid, "utf8").trim() === String(process.pid);
21039
+ return readFileSync42(daemonPaths.pid, "utf8").trim() === String(process.pid);
20364
21040
  } catch {
20365
21041
  return false;
20366
21042
  }
@@ -20368,7 +21044,7 @@ function ownsPidFile() {
20368
21044
 
20369
21045
  // src/commands/sessions/daemon/onListening.ts
20370
21046
  function onListening(manager, checkAutoExit) {
20371
- writeFileSync36(daemonPaths.pid, String(process.pid));
21047
+ writeFileSync37(daemonPaths.pid, String(process.pid));
20372
21048
  startPidFileWatchdog(() => {
20373
21049
  daemonLog("lost daemon.pid ownership; shutting down sessions and exiting");
20374
21050
  manager.shutdown();
@@ -20502,7 +21178,7 @@ async function setSessionStatus(status2) {
20502
21178
 
20503
21179
  // src/commands/sessions/summarise/index.ts
20504
21180
  import * as fs35 from "fs";
20505
- import chalk168 from "chalk";
21181
+ import chalk171 from "chalk";
20506
21182
 
20507
21183
  // src/commands/sessions/summarise/shared.ts
20508
21184
  import * as fs33 from "fs";
@@ -20656,22 +21332,22 @@ ${firstMessage}`);
20656
21332
  async function summarise3(options2) {
20657
21333
  const files = await discoverSessionFiles();
20658
21334
  if (files.length === 0) {
20659
- console.log(chalk168.yellow("No sessions found."));
21335
+ console.log(chalk171.yellow("No sessions found."));
20660
21336
  return;
20661
21337
  }
20662
21338
  const toProcess = selectCandidates(files, options2);
20663
21339
  if (toProcess.length === 0) {
20664
- console.log(chalk168.green("All sessions already summarised."));
21340
+ console.log(chalk171.green("All sessions already summarised."));
20665
21341
  return;
20666
21342
  }
20667
21343
  console.log(
20668
- chalk168.cyan(
21344
+ chalk171.cyan(
20669
21345
  `Summarising ${toProcess.length} session(s) (${files.length} total)\u2026`
20670
21346
  )
20671
21347
  );
20672
21348
  const { succeeded, failed: failed2 } = processSessions(toProcess);
20673
21349
  console.log(
20674
- chalk168.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk168.yellow(`, ${failed2} skipped`) : "")
21350
+ chalk171.green(`Done: ${succeeded} summarised`) + (failed2 > 0 ? chalk171.yellow(`, ${failed2} skipped`) : "")
20675
21351
  );
20676
21352
  }
20677
21353
  function selectCandidates(files, options2) {
@@ -20691,16 +21367,16 @@ function processSessions(files) {
20691
21367
  let failed2 = 0;
20692
21368
  for (let i = 0; i < files.length; i++) {
20693
21369
  const file = files[i];
20694
- process.stdout.write(chalk168.dim(` [${i + 1}/${files.length}] `));
21370
+ process.stdout.write(chalk171.dim(` [${i + 1}/${files.length}] `));
20695
21371
  const summary = summariseSession(file);
20696
21372
  if (summary) {
20697
21373
  writeSummary(file, summary);
20698
21374
  succeeded++;
20699
- process.stdout.write(`${chalk168.green("\u2713")} ${summary}
21375
+ process.stdout.write(`${chalk171.green("\u2713")} ${summary}
20700
21376
  `);
20701
21377
  } else {
20702
21378
  failed2++;
20703
- process.stdout.write(` ${chalk168.yellow("skip")}
21379
+ process.stdout.write(` ${chalk171.yellow("skip")}
20704
21380
  `);
20705
21381
  }
20706
21382
  }
@@ -20718,10 +21394,10 @@ function registerSessions(program2) {
20718
21394
  }
20719
21395
 
20720
21396
  // src/commands/statusLine.ts
20721
- import chalk170 from "chalk";
21397
+ import chalk173 from "chalk";
20722
21398
 
20723
21399
  // src/commands/buildLimitsSegment.ts
20724
- import chalk169 from "chalk";
21400
+ import chalk172 from "chalk";
20725
21401
 
20726
21402
  // src/shared/rateLimitLevel.ts
20727
21403
  var FIVE_HOUR_SECONDS = 5 * 3600;
@@ -20752,9 +21428,9 @@ function rateLimitLevel(pct, resetsAt, windowSeconds, now) {
20752
21428
 
20753
21429
  // src/commands/buildLimitsSegment.ts
20754
21430
  var LEVEL_COLOR = {
20755
- ok: chalk169.green,
20756
- warn: chalk169.yellow,
20757
- over: chalk169.red
21431
+ ok: chalk172.green,
21432
+ warn: chalk172.yellow,
21433
+ over: chalk172.red
20758
21434
  };
20759
21435
  function formatLimit(pct, resetsAt, windowSeconds, fallbackLabel, now) {
20760
21436
  const level = rateLimitLevel(pct, resetsAt, windowSeconds, now);
@@ -20794,14 +21470,14 @@ async function relayRateLimits(rateLimits) {
20794
21470
  }
20795
21471
 
20796
21472
  // src/commands/statusLine.ts
20797
- chalk170.level = 3;
21473
+ chalk173.level = 3;
20798
21474
  function formatNumber(num) {
20799
21475
  return num.toLocaleString("en-US");
20800
21476
  }
20801
21477
  function colorizePercent(pct) {
20802
21478
  const label2 = `${Math.round(pct)}%`;
20803
- if (pct > 80) return chalk170.red(label2);
20804
- if (pct > 40) return chalk170.yellow(label2);
21479
+ if (pct > 80) return chalk173.red(label2);
21480
+ if (pct > 40) return chalk173.yellow(label2);
20805
21481
  return label2;
20806
21482
  }
20807
21483
  async function statusLine() {
@@ -20820,12 +21496,12 @@ async function statusLine() {
20820
21496
  import * as fs38 from "fs";
20821
21497
  import * as os2 from "os";
20822
21498
  import * as path56 from "path";
20823
- import { fileURLToPath as fileURLToPath6 } from "url";
21499
+ import { fileURLToPath as fileURLToPath7 } from "url";
20824
21500
 
20825
21501
  // src/commands/sync/syncClaudeMd.ts
20826
21502
  import * as fs36 from "fs";
20827
21503
  import * as path54 from "path";
20828
- import chalk171 from "chalk";
21504
+ import chalk174 from "chalk";
20829
21505
  async function syncClaudeMd(claudeDir, targetBase, options2) {
20830
21506
  const source = path54.join(claudeDir, "CLAUDE.md");
20831
21507
  const target = path54.join(targetBase, "CLAUDE.md");
@@ -20834,12 +21510,12 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
20834
21510
  const targetContent = fs36.readFileSync(target, "utf8");
20835
21511
  if (sourceContent !== targetContent) {
20836
21512
  console.log(
20837
- chalk171.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
21513
+ chalk174.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
20838
21514
  );
20839
21515
  console.log();
20840
21516
  printDiff(targetContent, sourceContent);
20841
21517
  const confirm = options2?.yes || await promptConfirm(
20842
- chalk171.red("Overwrite existing CLAUDE.md?"),
21518
+ chalk174.red("Overwrite existing CLAUDE.md?"),
20843
21519
  false
20844
21520
  );
20845
21521
  if (!confirm) {
@@ -20855,7 +21531,7 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
20855
21531
  // src/commands/sync/syncSettings.ts
20856
21532
  import * as fs37 from "fs";
20857
21533
  import * as path55 from "path";
20858
- import chalk172 from "chalk";
21534
+ import chalk175 from "chalk";
20859
21535
  async function syncSettings(claudeDir, targetBase, options2) {
20860
21536
  const source = path55.join(claudeDir, "settings.json");
20861
21537
  const target = path55.join(targetBase, "settings.json");
@@ -20871,14 +21547,14 @@ async function syncSettings(claudeDir, targetBase, options2) {
20871
21547
  if (mergedContent !== normalizedTarget) {
20872
21548
  if (!options2?.yes) {
20873
21549
  console.log(
20874
- chalk172.yellow(
21550
+ chalk175.yellow(
20875
21551
  "\n\u26A0\uFE0F Warning: settings.json differs from existing file"
20876
21552
  )
20877
21553
  );
20878
21554
  console.log();
20879
21555
  printDiff(targetContent, mergedContent);
20880
21556
  const confirm = await promptConfirm(
20881
- chalk172.red("Overwrite existing settings.json?"),
21557
+ chalk175.red("Overwrite existing settings.json?"),
20882
21558
  false
20883
21559
  );
20884
21560
  if (!confirm) {
@@ -20893,7 +21569,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
20893
21569
  }
20894
21570
 
20895
21571
  // src/commands/sync.ts
20896
- var __filename4 = fileURLToPath6(import.meta.url);
21572
+ var __filename4 = fileURLToPath7(import.meta.url);
20897
21573
  var __dirname6 = path56.dirname(__filename4);
20898
21574
  async function sync(options2) {
20899
21575
  const config = loadConfig();
@@ -21011,6 +21687,7 @@ registerDeploy(program);
21011
21687
  registerComplexity(program);
21012
21688
  registerDotnet(program);
21013
21689
  registerNews(program);
21690
+ registerNetcap(program);
21014
21691
  registerRavendb(program);
21015
21692
  registerSeq(program);
21016
21693
  registerSql(program);