@staff0rd/assist 0.274.0 → 0.275.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@staff0rd/assist",
9
- version: "0.274.0",
9
+ version: "0.275.1",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -29,6 +29,11 @@ var package_default = {
29
29
  "check:types": "tsc --noEmit",
30
30
  test: "vitest run"
31
31
  },
32
+ overrides: {
33
+ lodash: "^4.18.0",
34
+ xml2js: "^0.5.0",
35
+ uuid: "^11.1.1"
36
+ },
32
37
  keywords: [],
33
38
  author: "",
34
39
  license: "ISC",
@@ -119,10 +124,10 @@ import { stringify as stringifyYaml } from "yaml";
119
124
  // src/shared/loadRawYaml.ts
120
125
  import { existsSync, readFileSync } from "fs";
121
126
  import { parse as parseYaml } from "yaml";
122
- function loadRawYaml(path53) {
123
- if (!existsSync(path53)) return {};
127
+ function loadRawYaml(path54) {
128
+ if (!existsSync(path54)) return {};
124
129
  try {
125
- const content = readFileSync(path53, "utf-8");
130
+ const content = readFileSync(path54, "utf-8");
126
131
  return parseYaml(content) || {};
127
132
  } catch {
128
133
  return {};
@@ -1859,8 +1864,8 @@ var MACHINE_DIRECTIVES = [
1859
1864
  "v8 ignore",
1860
1865
  "c8 ignore"
1861
1866
  ];
1862
- function isCommentExempt(text2, markers) {
1863
- const lower = text2.toLowerCase();
1867
+ function isCommentExempt(text3, markers) {
1868
+ const lower = text3.toLowerCase();
1864
1869
  if (MACHINE_DIRECTIVES.some((d) => lower.includes(d))) return true;
1865
1870
  return markers.some((m) => lower.includes(m.toLowerCase()));
1866
1871
  }
@@ -1903,8 +1908,8 @@ function parseDiffAddedLines(diff2) {
1903
1908
 
1904
1909
  // src/commands/verify/commentPolicy/findAddedComments.ts
1905
1910
  var SOURCE_EXTENSIONS = [".ts", ".tsx", ".cts", ".mts", ".js", ".jsx"];
1906
- function toSingleLine(text2) {
1907
- return text2.replace(/\s+/g, " ").trim();
1911
+ function toSingleLine(text3) {
1912
+ return text3.replace(/\s+/g, " ").trim();
1908
1913
  }
1909
1914
  function shouldScan(file, ignoreGlobs) {
1910
1915
  if (!SOURCE_EXTENSIONS.some((ext) => file.endsWith(ext))) return false;
@@ -1925,11 +1930,11 @@ function findAddedComments(options2) {
1925
1930
  for (const [file, lines] of addedLines) {
1926
1931
  if (!shouldScan(file, options2.ignoreGlobs)) continue;
1927
1932
  const sourceFile = project.addSourceFileAtPath(file);
1928
- for (const { pos, text: text2 } of collectComments(sourceFile)) {
1933
+ for (const { pos, text: text3 } of collectComments(sourceFile)) {
1929
1934
  const { line } = sourceFile.getLineAndColumnAtPos(pos);
1930
1935
  if (!lines.has(line)) continue;
1931
- if (isCommentExempt(text2, options2.markers)) continue;
1932
- findings.push({ file, line, text: toSingleLine(text2) });
1936
+ if (isCommentExempt(text3, options2.markers)) continue;
1937
+ findings.push({ file, line, text: toSingleLine(text3) });
1933
1938
  }
1934
1939
  }
1935
1940
  findings.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
@@ -1948,8 +1953,8 @@ function commentPolicy() {
1948
1953
  process.exit(0);
1949
1954
  }
1950
1955
  console.log("Comments added on changed lines:\n");
1951
- for (const { file, line, text: text2 } of findings) {
1952
- console.log(`${file}:${line} \u2192 ${text2}`);
1956
+ for (const { file, line, text: text3 } of findings) {
1957
+ console.log(`${file}:${line} \u2192 ${text3}`);
1953
1958
  }
1954
1959
  console.log(`
1955
1960
  Total: ${findings.length} comment(s)`);
@@ -3056,9 +3061,9 @@ var LOCAL_FILES = ["backlog.jsonl", "backlog.db"];
3056
3061
  function backupLocalBacklogFiles(dir) {
3057
3062
  const moved = [];
3058
3063
  for (const name of LOCAL_FILES) {
3059
- const path53 = join11(dir, ".assist", name);
3060
- if (existsSync15(path53)) {
3061
- renameSync(path53, `${path53}.bak`);
3064
+ const path54 = join11(dir, ".assist", name);
3065
+ if (existsSync15(path54)) {
3066
+ renameSync(path54, `${path54}.bak`);
3062
3067
  moved.push(`${name} \u2192 ${name}.bak`);
3063
3068
  }
3064
3069
  }
@@ -3348,8 +3353,8 @@ var backlogItemSchema = z3.strictObject({
3348
3353
  var backlogFileSchema = z3.array(backlogItemSchema);
3349
3354
 
3350
3355
  // src/commands/backlog/parseBacklogJsonl.ts
3351
- function parseBacklogJsonl(path53) {
3352
- const content = readFileSync10(path53, "utf-8").trim();
3356
+ function parseBacklogJsonl(path54) {
3357
+ const content = readFileSync10(path54, "utf-8").trim();
3353
3358
  if (content.length === 0) return [];
3354
3359
  return content.split("\n").map((line) => line.trim()).filter(Boolean).map((line) => backlogItemSchema.parse(JSON.parse(line)));
3355
3360
  }
@@ -3424,8 +3429,8 @@ function findBacklogUp(startDir) {
3424
3429
 
3425
3430
  // src/commands/backlog/getCurrentOrigin.ts
3426
3431
  import { execSync as execSync18 } from "child_process";
3427
- function stripLeadingSlashes(path53) {
3428
- return path53.replace(/^\/+/, "");
3432
+ function stripLeadingSlashes(path54) {
3433
+ return path54.replace(/^\/+/, "");
3429
3434
  }
3430
3435
  function normalizeOrigin(raw) {
3431
3436
  const trimmed = raw.trim().replace(/\.git$/i, "").replace(/\/+$/, "");
@@ -3689,13 +3694,13 @@ function activityPath(sessionId) {
3689
3694
  function emitActivity(activity2) {
3690
3695
  const sessionId = process.env.ASSIST_ACTIVITY_ID;
3691
3696
  if (!sessionId) return;
3692
- const path53 = activityPath(sessionId);
3693
- mkdirSync6(dirname14(path53), { recursive: true });
3694
- writeFileSync13(path53, JSON.stringify({ ...activity2, startedAt: Date.now() }));
3697
+ const path54 = activityPath(sessionId);
3698
+ mkdirSync6(dirname14(path54), { recursive: true });
3699
+ writeFileSync13(path54, JSON.stringify({ ...activity2, startedAt: Date.now() }));
3695
3700
  }
3696
- function readActivity(path53) {
3701
+ function readActivity(path54) {
3697
3702
  try {
3698
- return JSON.parse(readFileSync11(path53, "utf-8"));
3703
+ return JSON.parse(readFileSync11(path54, "utf-8"));
3699
3704
  } catch {
3700
3705
  return void 0;
3701
3706
  }
@@ -3855,10 +3860,10 @@ function writeSignal(event, data) {
3855
3860
 
3856
3861
  // src/commands/backlog/readSignal.ts
3857
3862
  function readSignal() {
3858
- const path53 = getSignalPath();
3859
- if (!existsSync19(path53)) return void 0;
3863
+ const path54 = getSignalPath();
3864
+ if (!existsSync19(path54)) return void 0;
3860
3865
  try {
3861
- return JSON.parse(readFileSync12(path53, "utf-8"));
3866
+ return JSON.parse(readFileSync12(path54, "utf-8"));
3862
3867
  } catch {
3863
3868
  return void 0;
3864
3869
  }
@@ -4114,11 +4119,11 @@ import chalk37 from "chalk";
4114
4119
 
4115
4120
  // src/commands/backlog/appendComment.ts
4116
4121
  import { sql as sql2 } from "drizzle-orm";
4117
- async function appendComment(orm, itemId, text2, opts = {}) {
4122
+ async function appendComment(orm, itemId, text3, opts = {}) {
4118
4123
  await orm.insert(comments).values({
4119
4124
  itemId,
4120
4125
  idx: sql2`(SELECT COALESCE(MAX(${comments.idx}) + 1, 0) FROM ${comments} WHERE ${comments.itemId} = ${itemId})`,
4121
- text: text2,
4126
+ text: text3,
4122
4127
  phase: opts.phase ?? null,
4123
4128
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
4124
4129
  type: opts.type ?? "comment"
@@ -5121,10 +5126,10 @@ async function web2(options2) {
5121
5126
 
5122
5127
  // src/commands/backlog/comment/index.ts
5123
5128
  import chalk45 from "chalk";
5124
- async function comment(id, text2) {
5129
+ async function comment(id, text3) {
5125
5130
  const found = await findOneItem(id);
5126
5131
  if (!found) process.exit(1);
5127
- await appendComment(found.orm, found.item.id, text2);
5132
+ await appendComment(found.orm, found.item.id, text3);
5128
5133
  console.log(chalk45.green(`Comment added to item #${id}.`));
5129
5134
  }
5130
5135
 
@@ -5294,9 +5299,9 @@ function readLine(dump, start3) {
5294
5299
  return { text: dump.subarray(start3, eol).toString("utf8"), next: eol + 1 };
5295
5300
  }
5296
5301
  function parseHeader(dump) {
5297
- const { text: text2, next: next3 } = readLine(dump, 0);
5302
+ const { text: text3, next: next3 } = readLine(dump, 0);
5298
5303
  try {
5299
- return { header: JSON.parse(text2), bodyStart: next3 };
5304
+ return { header: JSON.parse(text3), bodyStart: next3 };
5300
5305
  } catch {
5301
5306
  return invalid("header is not valid JSON.");
5302
5307
  }
@@ -5305,9 +5310,9 @@ function parseSections(dump, bodyStart) {
5305
5310
  const sections = /* @__PURE__ */ new Map();
5306
5311
  let cursor = bodyStart;
5307
5312
  while (cursor < dump.length) {
5308
- const { text: text2, next: next3 } = readLine(dump, cursor);
5309
- const match = text2.match(/^@table (\S+) (\d+)$/);
5310
- if (!match) invalid(`malformed table marker "${text2}".`);
5313
+ const { text: text3, next: next3 } = readLine(dump, cursor);
5314
+ const match = text3.match(/^@table (\S+) (\d+)$/);
5315
+ if (!match) invalid(`malformed table marker "${text3}".`);
5311
5316
  const [, name, bytes] = match;
5312
5317
  const end = next3 + Number(bytes);
5313
5318
  if (end > dump.length) invalid(`section "${name}" overruns the dump.`);
@@ -5645,8 +5650,8 @@ import chalk54 from "chalk";
5645
5650
  // src/commands/backlog/originDisplayName.ts
5646
5651
  function originDisplayName(origin) {
5647
5652
  if (origin.startsWith("local:")) {
5648
- const path53 = origin.slice("local:".length).replace(/\/+$/, "");
5649
- const segments = path53.split("/").filter(Boolean);
5653
+ const path54 = origin.slice("local:".length).replace(/\/+$/, "");
5654
+ const segments = path54.split("/").filter(Boolean);
5650
5655
  return segments[segments.length - 1] ?? origin;
5651
5656
  }
5652
5657
  const firstSlash = origin.indexOf("/");
@@ -6904,9 +6909,9 @@ var __dirname5 = dirname17(__filename3);
6904
6909
  function packageRoot() {
6905
6910
  return __dirname5;
6906
6911
  }
6907
- function readLines(path53) {
6908
- if (!existsSync22(path53)) return [];
6909
- return readFileSync16(path53, "utf-8").split("\n").filter((line) => line.trim() !== "");
6912
+ function readLines(path54) {
6913
+ if (!existsSync22(path54)) return [];
6914
+ return readFileSync16(path54, "utf-8").split("\n").filter((line) => line.trim() !== "");
6910
6915
  }
6911
6916
  var cachedReads;
6912
6917
  var cachedWrites;
@@ -7389,14 +7394,14 @@ function showProgress(p, label2) {
7389
7394
  const pct = Math.round(p.done / p.total * 100);
7390
7395
  process.stderr.write(`\r\x1B[K[${pct}%] Scanning ${label2}...`);
7391
7396
  }
7392
- async function resolveCommand(cli, path53, description, depth, p) {
7393
- showProgress(p, path53.join(" "));
7394
- const subHelp = await runHelp([cli, ...path53]);
7397
+ async function resolveCommand(cli, path54, description, depth, p) {
7398
+ showProgress(p, path54.join(" "));
7399
+ const subHelp = await runHelp([cli, ...path54]);
7395
7400
  if (!subHelp || !hasSubcommands(subHelp)) {
7396
- return [{ path: path53, description }];
7401
+ return [{ path: path54, description }];
7397
7402
  }
7398
- const children = await discoverAt(cli, path53, depth + 1, p);
7399
- return children.length > 0 ? children : [{ path: path53, description }];
7403
+ const children = await discoverAt(cli, path54, depth + 1, p);
7404
+ return children.length > 0 ? children : [{ path: path54, description }];
7400
7405
  }
7401
7406
  async function discoverAt(cli, parentPath, depth, p) {
7402
7407
  if (depth > SAFETY_DEPTH) return [];
@@ -7506,8 +7511,8 @@ function formatHuman(cli, commands) {
7506
7511
  `];
7507
7512
  for (const cmd of sorted) {
7508
7513
  const full = `${cli} ${cmd.path.join(" ")}`;
7509
- const text2 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
7510
- lines.push(`${prefix(classifyVerb(cmd.path))}${text2}`);
7514
+ const text3 = cmd.description ? `${full} \u2014 ${cmd.description}` : full;
7515
+ lines.push(`${prefix(classifyVerb(cmd.path))}${text3}`);
7511
7516
  }
7512
7517
  return lines.join("\n");
7513
7518
  }
@@ -7544,9 +7549,9 @@ function logPath(cli) {
7544
7549
  return join22(homedir9(), ".assist", `cli-discover-${safeName}.log`);
7545
7550
  }
7546
7551
  function readCache(cli) {
7547
- const path53 = logPath(cli);
7548
- if (!existsSync24(path53)) return void 0;
7549
- return readFileSync18(path53, "utf-8");
7552
+ const path54 = logPath(cli);
7553
+ if (!existsSync24(path54)) return void 0;
7554
+ return readFileSync18(path54, "utf-8");
7550
7555
  }
7551
7556
  function writeCache(cli, output) {
7552
7557
  const dir = join22(homedir9(), ".assist");
@@ -8235,8 +8240,8 @@ function stepIntoNested(container, key, nextKey) {
8235
8240
  }
8236
8241
  return ensureObject(container, resolved);
8237
8242
  }
8238
- function setNestedValue(obj, path53, value) {
8239
- const keys = path53.split(".");
8243
+ function setNestedValue(obj, path54, value) {
8244
+ const keys = path54.split(".");
8240
8245
  const result = { ...obj };
8241
8246
  let current = result;
8242
8247
  for (let i = 0; i < keys.length - 1; i++) {
@@ -8316,9 +8321,9 @@ function isTraversable(value) {
8316
8321
  function stepInto(current, key) {
8317
8322
  return isTraversable(current) ? current[key] : void 0;
8318
8323
  }
8319
- function getNestedValue(obj, path53) {
8324
+ function getNestedValue(obj, path54) {
8320
8325
  let current = obj;
8321
- for (const key of path53.split(".")) current = stepInto(current, key);
8326
+ for (const key of path54.split(".")) current = stepInto(current, key);
8322
8327
  return current;
8323
8328
  }
8324
8329
 
@@ -9852,16 +9857,16 @@ function parseUserLine(line) {
9852
9857
  if (entry.type !== "user") return void 0;
9853
9858
  const msg = entry.message;
9854
9859
  const c = msg?.content;
9855
- let text2;
9860
+ let text3;
9856
9861
  if (typeof c === "string") {
9857
- text2 = c;
9862
+ text3 = c;
9858
9863
  } else if (Array.isArray(c)) {
9859
9864
  const collected = c.filter((b) => b.type === "text").map((b) => b.text ?? "").join("\n");
9860
- text2 = collected || void 0;
9865
+ text3 = collected || void 0;
9861
9866
  }
9862
- if (!text2) return void 0;
9867
+ if (!text3) return void 0;
9863
9868
  return {
9864
- text: text2,
9869
+ text: text3,
9865
9870
  entrypoint: typeof entry.entrypoint === "string" ? entry.entrypoint : void 0
9866
9871
  };
9867
9872
  }
@@ -9912,12 +9917,12 @@ ${payload}`;
9912
9917
  return "";
9913
9918
  }
9914
9919
  }
9915
- function stripPreludes(text2) {
9916
- return text2.replace(/<command-name>[\s\S]*?<\/command-name>/g, "").replace(/<command-message>[\s\S]*?<\/command-message>/g, "").replace(/<command-args>[\s\S]*?<\/command-args>/g, "").replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, "").replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
9920
+ function stripPreludes(text3) {
9921
+ return text3.replace(/<command-name>[\s\S]*?<\/command-name>/g, "").replace(/<command-message>[\s\S]*?<\/command-message>/g, "").replace(/<command-args>[\s\S]*?<\/command-args>/g, "").replace(/<local-command-stdout>[\s\S]*?<\/local-command-stdout>/g, "").replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
9917
9922
  }
9918
- function capPayload(text2, maxBytes) {
9919
- const buf = Buffer.from(text2, "utf8");
9920
- if (buf.length <= maxBytes) return text2;
9923
+ function capPayload(text3, maxBytes) {
9924
+ const buf = Buffer.from(text3, "utf8");
9925
+ if (buf.length <= maxBytes) return text3;
9921
9926
  return buf.subarray(buf.length - maxBytes).toString("utf8");
9922
9927
  }
9923
9928
  function normaliseOutput(raw) {
@@ -9986,9 +9991,9 @@ import chalk109 from "chalk";
9986
9991
 
9987
9992
  // src/commands/jira/adfToText.ts
9988
9993
  function renderInline(node) {
9989
- const text2 = node.text ?? "";
9990
- if (node.marks?.some((m) => m.type === "code")) return `\`${text2}\``;
9991
- return text2;
9994
+ const text3 = node.text ?? "";
9995
+ if (node.marks?.some((m) => m.type === "code")) return `\`${text3}\``;
9996
+ return text3;
9992
9997
  }
9993
9998
  function renderChildren(node, indent2) {
9994
9999
  return renderNodes(node.content ?? [], indent2);
@@ -10030,8 +10035,8 @@ function isListNode(node) {
10030
10035
  function renderListChild(child, indent2, pad, marker, isFirst) {
10031
10036
  if (isListNode(child)) return renderNodes([child], indent2 + 1);
10032
10037
  if (child.type !== "paragraph") return renderNode(child, indent2);
10033
- const text2 = renderChildren(child, indent2);
10034
- return isFirst ? `${pad}${marker} ${text2}` : `${pad} ${text2}`;
10038
+ const text3 = renderChildren(child, indent2);
10039
+ return isFirst ? `${pad}${marker} ${text3}` : `${pad} ${text3}`;
10035
10040
  }
10036
10041
  function renderListItem(node, indent2, marker) {
10037
10042
  const pad = " ".repeat(indent2);
@@ -10106,10 +10111,10 @@ function getStorePath(filename) {
10106
10111
  return join32(getStoreDir(), filename);
10107
10112
  }
10108
10113
  function loadJson(filename) {
10109
- const path53 = getStorePath(filename);
10110
- if (existsSync33(path53)) {
10114
+ const path54 = getStorePath(filename);
10115
+ if (existsSync33(path54)) {
10111
10116
  try {
10112
- return JSON.parse(readFileSync27(path53, "utf-8"));
10117
+ return JSON.parse(readFileSync27(path54, "utf-8"));
10113
10118
  } catch {
10114
10119
  return {};
10115
10120
  }
@@ -10442,9 +10447,9 @@ function excerpt(xml, ...tags) {
10442
10447
  for (const tag of tags) {
10443
10448
  const raw = extractText(xml, tag);
10444
10449
  if (!raw) continue;
10445
- const text2 = stripHtml(raw);
10446
- if (text2.length <= MAX_EXCERPT) return text2;
10447
- return `${text2.slice(0, MAX_EXCERPT)}\u2026`;
10450
+ const text3 = stripHtml(raw);
10451
+ if (text3.length <= MAX_EXCERPT) return text3;
10452
+ return `${text3.slice(0, MAX_EXCERPT)}\u2026`;
10448
10453
  }
10449
10454
  return "";
10450
10455
  }
@@ -10745,15 +10750,15 @@ function postComment(vars) {
10745
10750
  const stdout = startLine === void 0 ? runGhGraphql(MUTATION_SINGLE, base) : runGhGraphql(MUTATION_MULTI, { ...base, startLine });
10746
10751
  assertThreadCreated(stdout);
10747
10752
  }
10748
- function comment2(path53, line, body, startLine) {
10753
+ function comment2(path54, line, body, startLine) {
10749
10754
  validateBody(body);
10750
10755
  validateLine(line);
10751
10756
  if (startLine !== void 0) validateLine(startLine);
10752
10757
  try {
10753
10758
  const prId = getCurrentPrNodeId();
10754
- postComment({ prId, body, path: path53, line, startLine });
10759
+ postComment({ prId, body, path: path54, line, startLine });
10755
10760
  const range = startLine !== void 0 ? `${startLine}-${line}` : `${line}`;
10756
- console.log(`Added review comment on ${path53}:${range}`);
10761
+ console.log(`Added review comment on ${path54}:${range}`);
10757
10762
  } catch (error) {
10758
10763
  if (isGhNotInstalled(error)) {
10759
10764
  console.error("Error: GitHub CLI (gh) is not installed.");
@@ -11333,8 +11338,8 @@ function registerPrs(program2) {
11333
11338
  prsCommand.command("wontfix <comment-id> <reason>").description("Reply with reason and resolve thread").action((commentId, reason) => {
11334
11339
  wontfix(Number.parseInt(commentId, 10), reason);
11335
11340
  });
11336
- prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path53, line, body) => {
11337
- comment2(path53, Number.parseInt(line, 10), body);
11341
+ prsCommand.command("comment <path> <line> <body>").description("Add a line comment to the pending review").action((path54, line, body) => {
11342
+ comment2(path54, Number.parseInt(line, 10), body);
11338
11343
  });
11339
11344
  }
11340
11345
 
@@ -11586,10 +11591,10 @@ function resolveOpSecret(reference) {
11586
11591
  }
11587
11592
 
11588
11593
  // src/commands/ravendb/ravenFetch.ts
11589
- async function ravenFetch(connection, path53) {
11594
+ async function ravenFetch(connection, path54) {
11590
11595
  const apiKey = resolveOpSecret(connection.apiKeyRef);
11591
11596
  let accessToken = await getAccessToken(apiKey);
11592
- const url = `${connection.url}${path53}`;
11597
+ const url = `${connection.url}${path54}`;
11593
11598
  const headers = {
11594
11599
  Authorization: `Bearer ${accessToken}`,
11595
11600
  "Content-Type": "application/json"
@@ -11679,16 +11684,16 @@ import chalk130 from "chalk";
11679
11684
  // src/commands/ravendb/buildQueryPath.ts
11680
11685
  function buildQueryPath(opts) {
11681
11686
  const db = encodeURIComponent(opts.db);
11682
- let path53;
11687
+ let path54;
11683
11688
  if (opts.collection) {
11684
- path53 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
11689
+ path54 = `/databases/${db}/indexes/dynamic/${encodeURIComponent(opts.collection)}?start=${opts.start}&pageSize=${opts.pageSize}&sort=${encodeURIComponent(opts.sort)}`;
11685
11690
  } else {
11686
- path53 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
11691
+ path54 = `/databases/${db}/queries?start=${opts.start}&pageSize=${opts.pageSize}`;
11687
11692
  }
11688
11693
  if (opts.query) {
11689
- path53 += `&query=${encodeURIComponent(opts.query)}`;
11694
+ path54 += `&query=${encodeURIComponent(opts.query)}`;
11690
11695
  }
11691
- return path53;
11696
+ return path54;
11692
11697
  }
11693
11698
 
11694
11699
  // src/commands/ravendb/fetchAllPages.ts
@@ -11697,7 +11702,7 @@ async function fetchAllPages(connection, opts) {
11697
11702
  let start3 = 0;
11698
11703
  while (true) {
11699
11704
  const effectivePageSize = opts.limit !== void 0 ? Math.min(opts.pageSize, opts.limit - allResults.length) : opts.pageSize;
11700
- const path53 = buildQueryPath({
11705
+ const path54 = buildQueryPath({
11701
11706
  db: connection.database,
11702
11707
  collection: opts.collection,
11703
11708
  start: start3,
@@ -11705,7 +11710,7 @@ async function fetchAllPages(connection, opts) {
11705
11710
  sort: opts.sort,
11706
11711
  query: opts.query
11707
11712
  });
11708
- const data = await ravenFetch(connection, path53);
11713
+ const data = await ravenFetch(connection, path54);
11709
11714
  const results = data.Results ?? [];
11710
11715
  const totalResults = data.TotalResults ?? 0;
11711
11716
  if (results.length === 0) break;
@@ -12352,9 +12357,9 @@ function resolveImports(target, dependencies, sourceFile, statements = []) {
12352
12357
  function extractTexts(target, allFunctions, statements) {
12353
12358
  const stmtTexts = statements.map((v) => v.getFullText().trim());
12354
12359
  const fnTexts = allFunctions.map((fn) => {
12355
- const text2 = fn.getFullText().trim();
12356
- if (fn === target && !text2.startsWith("export ")) return `export ${text2}`;
12357
- return text2;
12360
+ const text3 = fn.getFullText().trim();
12361
+ if (fn === target && !text3.startsWith("export ")) return `export ${text3}`;
12362
+ return text3;
12358
12363
  });
12359
12364
  return [...stmtTexts, ...fnTexts];
12360
12365
  }
@@ -12923,8 +12928,8 @@ function findRootParent(file, importedBy, visited) {
12923
12928
  function clusterFiles(graph) {
12924
12929
  const clusters = /* @__PURE__ */ new Map();
12925
12930
  for (const file of graph.files) {
12926
- const basename11 = path38.basename(file, path38.extname(file));
12927
- if (basename11 === "index") continue;
12931
+ const basename12 = path38.basename(file, path38.extname(file));
12932
+ if (basename12 === "index") continue;
12928
12933
  const importers = graph.importedBy.get(file);
12929
12934
  if (!importers || importers.size !== 1) continue;
12930
12935
  const parent = [...importers][0];
@@ -13986,8 +13991,8 @@ async function handlePostSynthesis(synthesisPath, options2) {
13986
13991
  // src/commands/review/prepareReviewDir.ts
13987
13992
  import { existsSync as existsSync36, mkdirSync as mkdirSync14, unlinkSync as unlinkSync12, writeFileSync as writeFileSync26 } from "fs";
13988
13993
  function clearReviewFiles(paths) {
13989
- for (const path53 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
13990
- if (existsSync36(path53)) unlinkSync12(path53);
13994
+ for (const path54 of [paths.claudePath, paths.codexPath, paths.synthesisPath]) {
13995
+ if (existsSync36(path54)) unlinkSync12(path54);
13991
13996
  }
13992
13997
  }
13993
13998
  function prepareReviewDir(paths, requestBody, force) {
@@ -14122,9 +14127,9 @@ var MultiSpinner = class {
14122
14127
  elapsedPrefix: prefix2
14123
14128
  });
14124
14129
  }
14125
- failRemaining(text2) {
14130
+ failRemaining(text3) {
14126
14131
  for (const entry of this.entries) {
14127
- if (entry.state === "running") this.resolve(entry, "failed", text2);
14132
+ if (entry.state === "running") this.resolve(entry, "failed", text3);
14128
14133
  }
14129
14134
  }
14130
14135
  add(entry) {
@@ -14137,14 +14142,14 @@ var MultiSpinner = class {
14137
14142
  set text(value) {
14138
14143
  entry.text = value;
14139
14144
  },
14140
- succeed: (text2) => this.resolve(entry, "succeeded", text2),
14141
- fail: (text2) => this.resolve(entry, "failed", text2)
14145
+ succeed: (text3) => this.resolve(entry, "succeeded", text3),
14146
+ fail: (text3) => this.resolve(entry, "failed", text3)
14142
14147
  };
14143
14148
  }
14144
- resolve(entry, state, text2) {
14149
+ resolve(entry, state, text3) {
14145
14150
  if (entry.state !== "running") return;
14146
14151
  entry.state = state;
14147
- if (text2 !== void 0) entry.text = text2;
14152
+ if (text3 !== void 0) entry.text = text3;
14148
14153
  entry.elapsedStart = void 0;
14149
14154
  this.render();
14150
14155
  this.maybeFinish();
@@ -14219,12 +14224,12 @@ function skippedCodexResult(outputPath) {
14219
14224
  // src/commands/review/formatReviewerFailure.ts
14220
14225
  var FAST_FAIL_MS = 1e3;
14221
14226
  var STDOUT_TAIL_LINES = 20;
14222
- function indent(text2) {
14223
- return text2.split(/\r?\n/).map((line) => ` ${line}`);
14227
+ function indent(text3) {
14228
+ return text3.split(/\r?\n/).map((line) => ` ${line}`);
14224
14229
  }
14225
- function tailLines(text2, maxLines) {
14226
- const lines = text2.split(/\r?\n/);
14227
- return lines.length <= maxLines ? text2 : lines.slice(-maxLines).join("\n");
14230
+ function tailLines(text3, maxLines) {
14231
+ const lines = text3.split(/\r?\n/);
14232
+ return lines.length <= maxLines ? text3 : lines.slice(-maxLines).join("\n");
14228
14233
  }
14229
14234
  function isFastFail(input) {
14230
14235
  return input.exitCode !== 0 && input.elapsedMs !== void 0 && input.elapsedMs < FAST_FAIL_MS;
@@ -15122,8 +15127,8 @@ import chalk149 from "chalk";
15122
15127
 
15123
15128
  // src/commands/seq/fetchSeq.ts
15124
15129
  import chalk146 from "chalk";
15125
- async function fetchSeq(conn, path53, params) {
15126
- const url = `${conn.url}${path53}?${params}`;
15130
+ async function fetchSeq(conn, path54, params) {
15131
+ const url = `${conn.url}${path54}?${params}`;
15127
15132
  const response = await fetch(url, {
15128
15133
  headers: {
15129
15134
  Accept: "application/json",
@@ -15858,8 +15863,8 @@ import { existsSync as existsSync40, mkdirSync as mkdirSync15, readFileSync as r
15858
15863
  import { basename as basename8, dirname as dirname21, join as join41 } from "path";
15859
15864
 
15860
15865
  // src/commands/transcript/cleanText.ts
15861
- function cleanText(text2) {
15862
- const words = text2.split(/\s+/);
15866
+ function cleanText(text3) {
15867
+ const words = text3.split(/\s+/);
15863
15868
  const cleaned = [];
15864
15869
  for (let i = 0; i < words.length; i++) {
15865
15870
  let isRepeat = false;
@@ -15879,8 +15884,8 @@ function cleanText(text2) {
15879
15884
  }
15880
15885
 
15881
15886
  // src/commands/transcript/format/processVttFile/parseVtt/deduplicateCues/removeSubstringDuplicates.ts
15882
- function normalizeText(text2) {
15883
- return text2.toLowerCase().trim();
15887
+ function normalizeText(text3) {
15888
+ return text3.toLowerCase().trim();
15884
15889
  }
15885
15890
  function checkSubstringRelation(textI, textJ) {
15886
15891
  if (textI.includes(textJ) && textI.length > textJ.length)
@@ -16009,13 +16014,13 @@ function parseTimestampLine(line) {
16009
16014
  return { startMs: parseTimestamp(startStr), endMs: parseTimestamp(endStr) };
16010
16015
  }
16011
16016
  function buildCue(startMs, endMs, fullText) {
16012
- const { speaker, text: text2 } = extractSpeaker(fullText);
16013
- return text2 ? { startMs, endMs, speaker, text: text2 } : null;
16017
+ const { speaker, text: text3 } = extractSpeaker(fullText);
16018
+ return text3 ? { startMs, endMs, speaker, text: text3 } : null;
16014
16019
  }
16015
16020
  function parseCueLine(lines, i) {
16016
16021
  const { startMs, endMs } = parseTimestampLine(lines[i]);
16017
- const { text: text2, nextIndex } = collectTextLines(lines, i + 1);
16018
- return { cue: buildCue(startMs, endMs, text2), nextIndex };
16022
+ const { text: text3, nextIndex } = collectTextLines(lines, i + 1);
16023
+ return { cue: buildCue(startMs, endMs, text3), nextIndex };
16019
16024
  }
16020
16025
  function isCueSeparator(line) {
16021
16026
  return line.trim().includes("-->");
@@ -16728,8 +16733,8 @@ async function exchangeToken(params) {
16728
16733
  body: body.toString()
16729
16734
  });
16730
16735
  if (!response.ok) {
16731
- const text2 = await response.text();
16732
- throw new Error(`Token exchange failed (${response.status}): ${text2}`);
16736
+ const text3 = await response.text();
16737
+ throw new Error(`Token exchange failed (${response.status}): ${text3}`);
16733
16738
  }
16734
16739
  return response.json();
16735
16740
  }
@@ -16813,9 +16818,9 @@ function findPortFile(roamDir) {
16813
16818
  return void 0;
16814
16819
  }
16815
16820
  const candidates = entries.filter((name) => /^roam-local-api(-[^.]+)?\.port$/.test(name)).map((name) => {
16816
- const path53 = join49(roamDir, name);
16821
+ const path54 = join49(roamDir, name);
16817
16822
  try {
16818
- return { path: path53, mtimeMs: statSync5(path53).mtimeMs };
16823
+ return { path: path54, mtimeMs: statSync5(path54).mtimeMs };
16819
16824
  } catch {
16820
16825
  return void 0;
16821
16826
  }
@@ -17158,11 +17163,11 @@ function findLinkIndex() {
17158
17163
  function parseLinkArgs() {
17159
17164
  const idx = findLinkIndex();
17160
17165
  if (idx === -1) return null;
17161
- const path53 = process.argv[idx + 1];
17166
+ const path54 = process.argv[idx + 1];
17162
17167
  const rest = process.argv.slice(idx + 2);
17163
17168
  const { value: prefix2 } = extractOption(rest, "--prefix");
17164
17169
  if (!prefix2) return null;
17165
- return { path: path53, prefix: prefix2 };
17170
+ return { path: path54, prefix: prefix2 };
17166
17171
  }
17167
17172
  function hasDuplicateLink(runList, linkPath) {
17168
17173
  return runList.some(
@@ -17582,121 +17587,6 @@ function daemonLog(message) {
17582
17587
  console.log(`${(/* @__PURE__ */ new Date()).toISOString()} [${process.pid}] ${message}`);
17583
17588
  }
17584
17589
 
17585
- // src/commands/sessions/shared/discoverSessions.ts
17586
- import * as fs26 from "fs";
17587
- import * as os from "os";
17588
- import * as path46 from "path";
17589
-
17590
- // src/commands/sessions/shared/parseSessionFile.ts
17591
- import * as fs25 from "fs";
17592
- import * as path45 from "path";
17593
-
17594
- // src/commands/sessions/shared/extractSessionMeta.ts
17595
- function extractSessionMeta(lines) {
17596
- let sessionId = "";
17597
- let cwd = "";
17598
- let timestamp = "";
17599
- let name = "";
17600
- for (const line of lines) {
17601
- const entry = safeParse(line);
17602
- if (!entry) continue;
17603
- sessionId ||= typeof entry.sessionId === "string" ? entry.sessionId : "";
17604
- timestamp ||= typeof entry.timestamp === "string" ? entry.timestamp : "";
17605
- cwd ||= typeof entry.cwd === "string" ? entry.cwd : "";
17606
- if (entry.type === "user" && !entry.isMeta) {
17607
- name = extractName(entry);
17608
- break;
17609
- }
17610
- }
17611
- return { sessionId, cwd, timestamp, name };
17612
- }
17613
- function safeParse(line) {
17614
- try {
17615
- return JSON.parse(line);
17616
- } catch {
17617
- return null;
17618
- }
17619
- }
17620
- function extractName(entry) {
17621
- const msg = entry.message;
17622
- const content = msg?.content;
17623
- const text2 = typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
17624
- return text2.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
17625
- }
17626
-
17627
- // src/commands/sessions/shared/parseSessionFile.ts
17628
- async function parseSessionFile(filePath) {
17629
- let handle;
17630
- try {
17631
- handle = await fs25.promises.open(filePath, "r");
17632
- const buf = Buffer.alloc(16384);
17633
- const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
17634
- const lines = buf.toString("utf8", 0, bytesRead).split("\n").filter(Boolean);
17635
- const meta = extractSessionMeta(lines);
17636
- if (!meta.sessionId) return null;
17637
- const timestamp = meta.timestamp || (await fs25.promises.stat(filePath)).mtime.toISOString();
17638
- const project = meta.cwd ? path45.basename(meta.cwd) : dirNameToProject(filePath);
17639
- return {
17640
- sessionId: meta.sessionId,
17641
- name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
17642
- project,
17643
- cwd: meta.cwd,
17644
- timestamp
17645
- };
17646
- } catch {
17647
- return null;
17648
- } finally {
17649
- await handle?.close();
17650
- }
17651
- }
17652
- function dirNameToProject(filePath) {
17653
- const dirName = path45.basename(path45.dirname(filePath));
17654
- const parts = dirName.split("--");
17655
- return parts[parts.length - 1].replace(/-/g, "/");
17656
- }
17657
-
17658
- // src/commands/sessions/shared/discoverSessions.ts
17659
- async function discoverSessionJsonlPaths() {
17660
- const projectsDir = path46.join(os.homedir(), ".claude", "projects");
17661
- let projectDirs;
17662
- try {
17663
- projectDirs = await fs26.promises.readdir(projectsDir);
17664
- } catch {
17665
- return [];
17666
- }
17667
- const paths = [];
17668
- await Promise.all(
17669
- projectDirs.map(async (dirName) => {
17670
- const dirPath = path46.join(projectsDir, dirName);
17671
- let entries;
17672
- try {
17673
- entries = await fs26.promises.readdir(dirPath);
17674
- } catch {
17675
- return;
17676
- }
17677
- const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
17678
- for (const file of jsonlFiles) {
17679
- paths.push(path46.join(dirPath, file));
17680
- }
17681
- })
17682
- );
17683
- return paths;
17684
- }
17685
- async function discoverSessions() {
17686
- const paths = await discoverSessionJsonlPaths();
17687
- const sessions = [];
17688
- await Promise.all(
17689
- paths.map(async (filePath) => {
17690
- const session = await parseSessionFile(filePath);
17691
- if (session) sessions.push(session);
17692
- })
17693
- );
17694
- sessions.sort(
17695
- (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
17696
- );
17697
- return sessions;
17698
- }
17699
-
17700
17590
  // src/commands/sessions/daemon/broadcast.ts
17701
17591
  function sendTo(client, msg) {
17702
17592
  client.send(JSON.stringify(msg));
@@ -17800,14 +17690,14 @@ import * as pty from "node-pty";
17800
17690
  // src/commands/sessions/daemon/ensureSpawnHelperExecutable.ts
17801
17691
  import { chmodSync, existsSync as existsSync51, statSync as statSync6 } from "fs";
17802
17692
  import { createRequire as createRequire3 } from "module";
17803
- import path47 from "path";
17693
+ import path45 from "path";
17804
17694
  var require4 = createRequire3(import.meta.url);
17805
17695
  var ensured = false;
17806
17696
  function ensureSpawnHelperExecutable() {
17807
17697
  if (ensured || process.platform !== "darwin") return;
17808
17698
  ensured = true;
17809
- const ptyRoot = path47.join(path47.dirname(require4.resolve("node-pty")), "..");
17810
- const helper = path47.join(
17699
+ const ptyRoot = path45.join(path45.dirname(require4.resolve("node-pty")), "..");
17700
+ const helper = path45.join(
17811
17701
  ptyRoot,
17812
17702
  "prebuilds",
17813
17703
  `${process.platform}-${process.arch}`,
@@ -18044,12 +17934,12 @@ function clearIdle(session) {
18044
17934
 
18045
17935
  // src/commands/sessions/daemon/watchActivity.ts
18046
17936
  import { existsSync as existsSync52, mkdirSync as mkdirSync22, watch } from "fs";
18047
- import { dirname as dirname27 } from "path";
17937
+ import { dirname as dirname26 } from "path";
18048
17938
  var DEBOUNCE_MS = 50;
18049
17939
  function watchActivity(session, notify2) {
18050
17940
  if (session.commandType !== "assist" || !session.cwd) return;
18051
- const path53 = activityPath(session.id);
18052
- const dir = dirname27(path53);
17941
+ const path54 = activityPath(session.id);
17942
+ const dir = dirname26(path54);
18053
17943
  try {
18054
17944
  mkdirSync22(dir, { recursive: true });
18055
17945
  } catch {
@@ -18058,7 +17948,7 @@ function watchActivity(session, notify2) {
18058
17948
  let timer = null;
18059
17949
  const read = () => {
18060
17950
  timer = null;
18061
- const activity2 = readActivity(path53);
17951
+ const activity2 = readActivity(path54);
18062
17952
  if (!activity2) return;
18063
17953
  session.activity = activity2;
18064
17954
  if (activity2.claudeSessionId)
@@ -18066,11 +17956,11 @@ function watchActivity(session, notify2) {
18066
17956
  notify2();
18067
17957
  };
18068
17958
  session.activityWatcher = watch(dir, (_event, filename) => {
18069
- if (filename && !path53.endsWith(filename)) return;
17959
+ if (filename && !path54.endsWith(filename)) return;
18070
17960
  if (timer) clearTimeout(timer);
18071
17961
  timer = setTimeout(read, DEBOUNCE_MS);
18072
17962
  });
18073
- if (existsSync52(path53)) read();
17963
+ if (existsSync52(path54)) read();
18074
17964
  }
18075
17965
  function refreshActivity(session) {
18076
17966
  if (session.commandType !== "assist" || !session.cwd) return;
@@ -18159,6 +18049,174 @@ function shutdownSessions(sessions) {
18159
18049
  // src/commands/sessions/daemon/watchClaudeSessionId.ts
18160
18050
  import * as fs27 from "fs";
18161
18051
  import * as path48 from "path";
18052
+
18053
+ // src/commands/sessions/shared/discoverSessions.ts
18054
+ import * as fs26 from "fs";
18055
+ import * as os from "os";
18056
+ import * as path47 from "path";
18057
+
18058
+ // src/commands/sessions/shared/parseSessionFile.ts
18059
+ import * as fs25 from "fs";
18060
+ import * as path46 from "path";
18061
+
18062
+ // src/commands/sessions/shared/deriveHistoryFields.ts
18063
+ var KNOWN = ["draft", "next", "bug", "refine", "run"];
18064
+ function deriveHistoryFields(commandName, commandArgs, name) {
18065
+ const fields = {};
18066
+ const sessionType = deriveSessionType(commandName, name);
18067
+ if (sessionType) fields.sessionType = sessionType;
18068
+ const itemMatch = commandArgs.match(/^(\d+)\b\s*/);
18069
+ if (itemMatch) fields.itemId = Number(itemMatch[1]);
18070
+ const prompt = commandArgs.slice(itemMatch?.[0].length ?? 0).trim();
18071
+ if (prompt) fields.prompt = prompt;
18072
+ return fields;
18073
+ }
18074
+ function deriveSessionType(commandName, name) {
18075
+ if (KNOWN.includes(commandName))
18076
+ return commandName;
18077
+ if (commandName || name) return "prompt";
18078
+ return void 0;
18079
+ }
18080
+
18081
+ // src/commands/sessions/shared/backlogRunMarkers.ts
18082
+ function backlogRunMarkers(text3) {
18083
+ const match = text3.match(/backlog item #(\d+):[ \t]*([^\n]*)/);
18084
+ if (!match) return { commandName: "", commandArgs: "" };
18085
+ const title = match[2].trim();
18086
+ return {
18087
+ commandName: "next",
18088
+ commandArgs: title ? `${match[1]} ${title}` : match[1]
18089
+ };
18090
+ }
18091
+
18092
+ // src/commands/sessions/shared/extractSessionMeta.ts
18093
+ function extractSessionMeta(lines) {
18094
+ let sessionId = "";
18095
+ let cwd = "";
18096
+ let timestamp = "";
18097
+ let name = "";
18098
+ let commandName = "";
18099
+ let commandArgs = "";
18100
+ for (const line of lines) {
18101
+ const entry = safeParse(line);
18102
+ if (!entry) continue;
18103
+ sessionId ||= strField(entry, "sessionId");
18104
+ timestamp ||= strField(entry, "timestamp");
18105
+ cwd ||= strField(entry, "cwd");
18106
+ if (entry.type === "user" && !entry.isMeta) {
18107
+ ({ name, commandName, commandArgs } = parseFirstUserEntry(entry));
18108
+ break;
18109
+ }
18110
+ }
18111
+ return { sessionId, cwd, timestamp, name, commandName, commandArgs };
18112
+ }
18113
+ function parseFirstUserEntry(entry) {
18114
+ const raw = messageText(entry);
18115
+ const commandName = matchMarker(raw, "command-name").replace(/^\//, "");
18116
+ const commandArgs = matchMarker(raw, "command-args");
18117
+ const name = stripMarkers(raw);
18118
+ if (commandName) return { name, commandName, commandArgs };
18119
+ return { name, ...backlogRunMarkers(raw) };
18120
+ }
18121
+ function strField(entry, key) {
18122
+ const value = entry[key];
18123
+ return typeof value === "string" ? value : "";
18124
+ }
18125
+ function safeParse(line) {
18126
+ try {
18127
+ return JSON.parse(line);
18128
+ } catch {
18129
+ return null;
18130
+ }
18131
+ }
18132
+ function messageText(entry) {
18133
+ const msg = entry.message;
18134
+ const content = msg?.content;
18135
+ return typeof content === "string" ? content : Array.isArray(content) ? content.find((c) => c.type === "text")?.text ?? "" : "";
18136
+ }
18137
+ function stripMarkers(text3) {
18138
+ return text3.replace(/<command-[^>]*>[^<]*<\/command-[^>]*>/g, "").trim().slice(0, 80);
18139
+ }
18140
+ function matchMarker(text3, tag) {
18141
+ const match = text3.match(new RegExp(`<${tag}>([\\s\\S]*?)</${tag}>`));
18142
+ return match ? match[1].trim() : "";
18143
+ }
18144
+
18145
+ // src/commands/sessions/shared/parseSessionFile.ts
18146
+ async function parseSessionFile(filePath) {
18147
+ let handle;
18148
+ try {
18149
+ handle = await fs25.promises.open(filePath, "r");
18150
+ const buf = Buffer.alloc(16384);
18151
+ const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
18152
+ const lines = buf.toString("utf8", 0, bytesRead).split("\n").filter(Boolean);
18153
+ const meta = extractSessionMeta(lines);
18154
+ if (!meta.sessionId) return null;
18155
+ const timestamp = meta.timestamp || (await fs25.promises.stat(filePath)).mtime.toISOString();
18156
+ const project = meta.cwd ? path46.basename(meta.cwd) : dirNameToProject(filePath);
18157
+ return {
18158
+ sessionId: meta.sessionId,
18159
+ name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
18160
+ project,
18161
+ cwd: meta.cwd,
18162
+ timestamp,
18163
+ ...deriveHistoryFields(meta.commandName, meta.commandArgs, meta.name)
18164
+ };
18165
+ } catch {
18166
+ return null;
18167
+ } finally {
18168
+ await handle?.close();
18169
+ }
18170
+ }
18171
+ function dirNameToProject(filePath) {
18172
+ const dirName = path46.basename(path46.dirname(filePath));
18173
+ const parts = dirName.split("--");
18174
+ return parts[parts.length - 1].replace(/-/g, "/");
18175
+ }
18176
+
18177
+ // src/commands/sessions/shared/discoverSessions.ts
18178
+ async function discoverSessionJsonlPaths() {
18179
+ const projectsDir = path47.join(os.homedir(), ".claude", "projects");
18180
+ let projectDirs;
18181
+ try {
18182
+ projectDirs = await fs26.promises.readdir(projectsDir);
18183
+ } catch {
18184
+ return [];
18185
+ }
18186
+ const paths = [];
18187
+ await Promise.all(
18188
+ projectDirs.map(async (dirName) => {
18189
+ const dirPath = path47.join(projectsDir, dirName);
18190
+ let entries;
18191
+ try {
18192
+ entries = await fs26.promises.readdir(dirPath);
18193
+ } catch {
18194
+ return;
18195
+ }
18196
+ const jsonlFiles = entries.filter((e) => e.endsWith(".jsonl"));
18197
+ for (const file of jsonlFiles) {
18198
+ paths.push(path47.join(dirPath, file));
18199
+ }
18200
+ })
18201
+ );
18202
+ return paths;
18203
+ }
18204
+ async function discoverSessions() {
18205
+ const paths = await discoverSessionJsonlPaths();
18206
+ const sessions = [];
18207
+ await Promise.all(
18208
+ paths.map(async (filePath) => {
18209
+ const session = await parseSessionFile(filePath);
18210
+ if (session) sessions.push(session);
18211
+ })
18212
+ );
18213
+ sessions.sort(
18214
+ (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
18215
+ );
18216
+ return sessions;
18217
+ }
18218
+
18219
+ // src/commands/sessions/daemon/watchClaudeSessionId.ts
18162
18220
  var POLL_MS = 3e3;
18163
18221
  async function watchClaudeSessionId(options2) {
18164
18222
  let adoptedMs = 0;
@@ -18346,9 +18404,6 @@ var SessionManager = class {
18346
18404
  listSessions() {
18347
18405
  return [...this.sessions.values()].map(toSessionInfo);
18348
18406
  }
18349
- async getHistory() {
18350
- return discoverSessions();
18351
- }
18352
18407
  notify = () => {
18353
18408
  if (this.shuttingDown) return;
18354
18409
  broadcastSessions(this.sessions, this.clients);
@@ -18363,6 +18418,95 @@ import * as net2 from "net";
18363
18418
  // src/commands/sessions/daemon/handleConnection.ts
18364
18419
  import { createInterface as createInterface5 } from "readline";
18365
18420
 
18421
+ // src/commands/sessions/shared/parseTranscript.ts
18422
+ import * as fs28 from "fs";
18423
+
18424
+ // src/commands/sessions/shared/toolTarget.ts
18425
+ function toolTarget(input) {
18426
+ if (!input || typeof input !== "object") return "";
18427
+ const i = input;
18428
+ const str = (v) => typeof v === "string" ? v : "";
18429
+ const target = str(i.file_path) || str(i.path) || str(i.notebook_path) || str(i.command) || str(i.pattern) || str(i.url) || str(i.query) || str(i.description) || str(i.prompt);
18430
+ return target.replace(/\s+/g, " ").trim().slice(0, 120);
18431
+ }
18432
+
18433
+ // src/commands/sessions/shared/entryMessages.ts
18434
+ function entryMessages(entry) {
18435
+ const content = entry.message?.content;
18436
+ if (entry.type === "user") return userMessages(content);
18437
+ if (entry.type === "assistant") return assistantMessages(content);
18438
+ return [];
18439
+ }
18440
+ function userMessages(content) {
18441
+ if (typeof content === "string") return text2("user", cleanUserText(content));
18442
+ if (!Array.isArray(content)) return [];
18443
+ return content.filter((c) => c.type === "text").flatMap((c) => text2("user", cleanUserText(c.text ?? "")));
18444
+ }
18445
+ function assistantMessages(content) {
18446
+ if (typeof content === "string") return text2("assistant", content.trim());
18447
+ if (!Array.isArray(content)) return [];
18448
+ return content.flatMap((c) => assistantItem(c));
18449
+ }
18450
+ function assistantItem(c) {
18451
+ if (c.type === "text") return text2("assistant", (c.text ?? "").trim());
18452
+ if (c.type === "tool_use")
18453
+ return [
18454
+ {
18455
+ role: "tool",
18456
+ tool: typeof c.name === "string" ? c.name : "tool",
18457
+ target: toolTarget(c.input)
18458
+ }
18459
+ ];
18460
+ return [];
18461
+ }
18462
+ function text2(role, value) {
18463
+ return value ? [{ role, text: value }] : [];
18464
+ }
18465
+ function cleanUserText(value) {
18466
+ return value.replace(/<command-[^>]*>[\s\S]*?<\/command-[^>]*>/g, "").replace(/<local-command-[^>]*>[\s\S]*?<\/local-command-[^>]*>/g, "").trim();
18467
+ }
18468
+
18469
+ // src/commands/sessions/shared/findSessionJsonlPath.ts
18470
+ import * as path49 from "path";
18471
+ async function findSessionJsonlPath(sessionId) {
18472
+ const paths = await discoverSessionJsonlPaths();
18473
+ const direct = paths.find((p) => path49.basename(p, ".jsonl") === sessionId);
18474
+ if (direct) return direct;
18475
+ for (const p of paths) {
18476
+ const meta = await parseSessionFile(p);
18477
+ if (meta?.sessionId === sessionId) return p;
18478
+ }
18479
+ return null;
18480
+ }
18481
+
18482
+ // src/commands/sessions/shared/parseTranscript.ts
18483
+ async function parseTranscript(sessionId) {
18484
+ const filePath = await findSessionJsonlPath(sessionId);
18485
+ if (!filePath) return [];
18486
+ try {
18487
+ const raw = await fs28.promises.readFile(filePath, "utf8");
18488
+ return parseTranscriptLines(raw.split("\n"));
18489
+ } catch {
18490
+ return [];
18491
+ }
18492
+ }
18493
+ function parseTranscriptLines(lines) {
18494
+ const messages = [];
18495
+ for (const line of lines) {
18496
+ const entry = line.trim() ? safeParse2(line) : null;
18497
+ if (!entry || entry.isSidechain || entry.isMeta) continue;
18498
+ messages.push(...entryMessages(entry));
18499
+ }
18500
+ return messages;
18501
+ }
18502
+ function safeParse2(line) {
18503
+ try {
18504
+ return JSON.parse(line);
18505
+ } catch {
18506
+ return null;
18507
+ }
18508
+ }
18509
+
18366
18510
  // src/commands/sessions/daemon/dispatchMessage.ts
18367
18511
  function sendCreated(client, id) {
18368
18512
  sendTo(client, { type: "created", sessionId: id });
@@ -18405,10 +18549,16 @@ function handleResume(client, manager, data) {
18405
18549
  )
18406
18550
  );
18407
18551
  }
18408
- function handleHistory(client, manager) {
18409
- manager.getHistory().then((history) => {
18410
- sendTo(client, { type: "history", sessions: history });
18411
- });
18552
+ function handleHistory(client) {
18553
+ discoverSessions().then(
18554
+ (sessions) => sendTo(client, { type: "history", sessions })
18555
+ );
18556
+ }
18557
+ function handleFetchTranscript(client, _manager, data) {
18558
+ const sessionId = data.sessionId;
18559
+ parseTranscript(sessionId).then(
18560
+ (messages) => sendTo(client, { type: "transcript", sessionId, messages })
18561
+ );
18412
18562
  }
18413
18563
  function handleShutdown(client, manager) {
18414
18564
  manager.shutdown();
@@ -18422,6 +18572,7 @@ var handlers = {
18422
18572
  "create-assist": handleCreateAssist,
18423
18573
  resume: handleResume,
18424
18574
  history: handleHistory,
18575
+ "fetch-transcript": handleFetchTranscript,
18425
18576
  shutdown: handleShutdown,
18426
18577
  input: (_client, m, d) => m.writeToSession(d.sessionId, d.data),
18427
18578
  resize: (_client, m, d) => m.resizeSession(d.sessionId, d.cols, d.rows),
@@ -18585,17 +18736,17 @@ function registerDaemon(program2) {
18585
18736
  }
18586
18737
 
18587
18738
  // src/commands/sessions/summarise/index.ts
18588
- import * as fs30 from "fs";
18739
+ import * as fs31 from "fs";
18589
18740
  import chalk159 from "chalk";
18590
18741
 
18591
18742
  // src/commands/sessions/summarise/shared.ts
18592
- import * as fs28 from "fs";
18743
+ import * as fs29 from "fs";
18593
18744
  function writeSummary(jsonlPath2, summary) {
18594
- fs28.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
18745
+ fs29.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
18595
18746
  `, "utf8");
18596
18747
  }
18597
18748
  function hasSummary(jsonlPath2) {
18598
- return fs28.existsSync(summaryPathFor(jsonlPath2));
18749
+ return fs29.existsSync(summaryPathFor(jsonlPath2));
18599
18750
  }
18600
18751
  function summaryPathFor(jsonlPath2) {
18601
18752
  return jsonlPath2.replace(/\.jsonl$/, ".summary");
@@ -18605,17 +18756,17 @@ function summaryPathFor(jsonlPath2) {
18605
18756
  import { execFileSync as execFileSync10 } from "child_process";
18606
18757
 
18607
18758
  // src/commands/sessions/summarise/iterateUserMessages.ts
18608
- import * as fs29 from "fs";
18759
+ import * as fs30 from "fs";
18609
18760
  function* iterateUserMessages(filePath, maxBytes = 65536) {
18610
18761
  let content;
18611
18762
  try {
18612
- const fd = fs29.openSync(filePath, "r");
18763
+ const fd = fs30.openSync(filePath, "r");
18613
18764
  try {
18614
18765
  const buf = Buffer.alloc(maxBytes);
18615
- const bytesRead = fs29.readSync(fd, buf, 0, buf.length, 0);
18766
+ const bytesRead = fs30.readSync(fd, buf, 0, buf.length, 0);
18616
18767
  content = buf.toString("utf8", 0, bytesRead);
18617
18768
  } finally {
18618
- fs29.closeSync(fd);
18769
+ fs30.closeSync(fd);
18619
18770
  }
18620
18771
  } catch {
18621
18772
  return;
@@ -18629,13 +18780,13 @@ function* iterateUserMessages(filePath, maxBytes = 65536) {
18629
18780
 
18630
18781
  // src/commands/sessions/summarise/extractFirstUserMessage.ts
18631
18782
  function extractFirstUserMessage(filePath) {
18632
- for (const text2 of iterateUserMessages(filePath)) {
18633
- return truncate3(text2);
18783
+ for (const text3 of iterateUserMessages(filePath)) {
18784
+ return truncate3(text3);
18634
18785
  }
18635
18786
  return void 0;
18636
18787
  }
18637
- function truncate3(text2, maxChars = 500) {
18638
- const trimmed = text2.trim();
18788
+ function truncate3(text3, maxChars = 500) {
18789
+ const trimmed = text3.trim();
18639
18790
  if (trimmed.length <= maxChars) return trimmed;
18640
18791
  return `${trimmed.slice(0, maxChars)}\u2026`;
18641
18792
  }
@@ -18643,28 +18794,28 @@ function truncate3(text2, maxChars = 500) {
18643
18794
  // src/commands/sessions/summarise/scanSessionBacklogRefs.ts
18644
18795
  function scanSessionBacklogRefs(filePath) {
18645
18796
  const ids = /* @__PURE__ */ new Set();
18646
- for (const text2 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
18647
- for (const id of extractBacklogIds(text2)) {
18797
+ for (const text3 of iterateUserMessages(filePath, Number.MAX_SAFE_INTEGER)) {
18798
+ for (const id of extractBacklogIds(text3)) {
18648
18799
  ids.add(id);
18649
18800
  }
18650
18801
  }
18651
18802
  return [...ids].sort((a, b) => a - b);
18652
18803
  }
18653
- function extractBacklogIds(text2) {
18804
+ function extractBacklogIds(text3) {
18654
18805
  const ids = [];
18655
- for (const m of text2.matchAll(/backlog\s+run\s+(\d+)/gi)) {
18806
+ for (const m of text3.matchAll(/backlog\s+run\s+(\d+)/gi)) {
18656
18807
  ids.push(Number.parseInt(m[1], 10));
18657
18808
  }
18658
- for (const m of text2.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
18809
+ for (const m of text3.matchAll(/backlog\s+(?:item\s+)?#(\d+)/gi)) {
18659
18810
  ids.push(Number.parseInt(m[1], 10));
18660
18811
  }
18661
- for (const m of text2.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
18812
+ for (const m of text3.matchAll(/backlog\s+phase-done\s+(\d+)/gi)) {
18662
18813
  ids.push(Number.parseInt(m[1], 10));
18663
18814
  }
18664
- for (const m of text2.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
18815
+ for (const m of text3.matchAll(/backlog\s+comment\s+(\d+)/gi)) {
18665
18816
  ids.push(Number.parseInt(m[1], 10));
18666
18817
  }
18667
- for (const m of text2.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
18818
+ for (const m of text3.matchAll(/(?:^|[\s(])#(\d{1,4})(?=[\s).,;:!?]|$)/gm)) {
18668
18819
  ids.push(Number.parseInt(m[1], 10));
18669
18820
  }
18670
18821
  return ids;
@@ -18735,7 +18886,7 @@ function selectCandidates(files, options2) {
18735
18886
  const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
18736
18887
  candidates.sort((a, b) => {
18737
18888
  try {
18738
- return fs30.statSync(b).mtimeMs - fs30.statSync(a).mtimeMs;
18889
+ return fs31.statSync(b).mtimeMs - fs31.statSync(a).mtimeMs;
18739
18890
  } catch {
18740
18891
  return 0;
18741
18892
  }
@@ -18849,21 +19000,21 @@ async function statusLine() {
18849
19000
  }
18850
19001
 
18851
19002
  // src/commands/sync.ts
18852
- import * as fs33 from "fs";
19003
+ import * as fs34 from "fs";
18853
19004
  import * as os2 from "os";
18854
- import * as path51 from "path";
19005
+ import * as path52 from "path";
18855
19006
  import { fileURLToPath as fileURLToPath7 } from "url";
18856
19007
 
18857
19008
  // src/commands/sync/syncClaudeMd.ts
18858
- import * as fs31 from "fs";
18859
- import * as path49 from "path";
19009
+ import * as fs32 from "fs";
19010
+ import * as path50 from "path";
18860
19011
  import chalk162 from "chalk";
18861
19012
  async function syncClaudeMd(claudeDir, targetBase, options2) {
18862
- const source = path49.join(claudeDir, "CLAUDE.md");
18863
- const target = path49.join(targetBase, "CLAUDE.md");
18864
- const sourceContent = fs31.readFileSync(source, "utf-8");
18865
- if (fs31.existsSync(target)) {
18866
- const targetContent = fs31.readFileSync(target, "utf-8");
19013
+ const source = path50.join(claudeDir, "CLAUDE.md");
19014
+ const target = path50.join(targetBase, "CLAUDE.md");
19015
+ const sourceContent = fs32.readFileSync(source, "utf-8");
19016
+ if (fs32.existsSync(target)) {
19017
+ const targetContent = fs32.readFileSync(target, "utf-8");
18867
19018
  if (sourceContent !== targetContent) {
18868
19019
  console.log(
18869
19020
  chalk162.yellow("\n\u26A0\uFE0F Warning: CLAUDE.md differs from existing file")
@@ -18880,21 +19031,21 @@ async function syncClaudeMd(claudeDir, targetBase, options2) {
18880
19031
  }
18881
19032
  }
18882
19033
  }
18883
- fs31.copyFileSync(source, target);
19034
+ fs32.copyFileSync(source, target);
18884
19035
  console.log("Copied CLAUDE.md to ~/.claude/CLAUDE.md");
18885
19036
  }
18886
19037
 
18887
19038
  // src/commands/sync/syncSettings.ts
18888
- import * as fs32 from "fs";
18889
- import * as path50 from "path";
19039
+ import * as fs33 from "fs";
19040
+ import * as path51 from "path";
18890
19041
  import chalk163 from "chalk";
18891
19042
  async function syncSettings(claudeDir, targetBase, options2) {
18892
- const source = path50.join(claudeDir, "settings.json");
18893
- const target = path50.join(targetBase, "settings.json");
18894
- const sourceContent = fs32.readFileSync(source, "utf-8");
19043
+ const source = path51.join(claudeDir, "settings.json");
19044
+ const target = path51.join(targetBase, "settings.json");
19045
+ const sourceContent = fs33.readFileSync(source, "utf-8");
18895
19046
  const mergedContent = JSON.stringify(JSON.parse(sourceContent), null, " ");
18896
- if (fs32.existsSync(target)) {
18897
- const targetContent = fs32.readFileSync(target, "utf-8");
19047
+ if (fs33.existsSync(target)) {
19048
+ const targetContent = fs33.readFileSync(target, "utf-8");
18898
19049
  const normalizedTarget = JSON.stringify(
18899
19050
  JSON.parse(targetContent),
18900
19051
  null,
@@ -18920,29 +19071,29 @@ async function syncSettings(claudeDir, targetBase, options2) {
18920
19071
  }
18921
19072
  }
18922
19073
  }
18923
- fs32.writeFileSync(target, mergedContent);
19074
+ fs33.writeFileSync(target, mergedContent);
18924
19075
  console.log("Copied settings.json to ~/.claude/settings.json");
18925
19076
  }
18926
19077
 
18927
19078
  // src/commands/sync.ts
18928
19079
  var __filename4 = fileURLToPath7(import.meta.url);
18929
- var __dirname7 = path51.dirname(__filename4);
19080
+ var __dirname7 = path52.dirname(__filename4);
18930
19081
  async function sync(options2) {
18931
19082
  const config = loadConfig();
18932
19083
  const yes = options2?.yes ?? config.sync.autoConfirm;
18933
- const claudeDir = path51.join(__dirname7, "..", "claude");
18934
- const targetBase = path51.join(os2.homedir(), ".claude");
19084
+ const claudeDir = path52.join(__dirname7, "..", "claude");
19085
+ const targetBase = path52.join(os2.homedir(), ".claude");
18935
19086
  syncCommands(claudeDir, targetBase);
18936
19087
  await syncSettings(claudeDir, targetBase, { yes });
18937
19088
  await syncClaudeMd(claudeDir, targetBase, { yes });
18938
19089
  }
18939
19090
  function syncCommands(claudeDir, targetBase) {
18940
- const sourceDir = path51.join(claudeDir, "commands");
18941
- const targetDir = path51.join(targetBase, "commands");
18942
- fs33.mkdirSync(targetDir, { recursive: true });
18943
- const files = fs33.readdirSync(sourceDir);
19091
+ const sourceDir = path52.join(claudeDir, "commands");
19092
+ const targetDir = path52.join(targetBase, "commands");
19093
+ fs34.mkdirSync(targetDir, { recursive: true });
19094
+ const files = fs34.readdirSync(sourceDir);
18944
19095
  for (const file of files) {
18945
- fs33.copyFileSync(path51.join(sourceDir, file), path51.join(targetDir, file));
19096
+ fs34.copyFileSync(path52.join(sourceDir, file), path52.join(targetDir, file));
18946
19097
  console.log(`Copied ${file} to ${targetDir}`);
18947
19098
  }
18948
19099
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -18950,15 +19101,15 @@ function syncCommands(claudeDir, targetBase) {
18950
19101
 
18951
19102
  // src/commands/update.ts
18952
19103
  import { execSync as execSync50 } from "child_process";
18953
- import * as path52 from "path";
19104
+ import * as path53 from "path";
18954
19105
  function isGlobalNpmInstall(dir) {
18955
19106
  try {
18956
- const resolved = path52.resolve(dir);
18957
- if (resolved.split(path52.sep).includes("node_modules")) {
19107
+ const resolved = path53.resolve(dir);
19108
+ if (resolved.split(path53.sep).includes("node_modules")) {
18958
19109
  return true;
18959
19110
  }
18960
19111
  const globalPrefix = execSync50("npm prefix -g", { stdio: "pipe" }).toString().trim();
18961
- return resolved.toLowerCase().startsWith(path52.resolve(globalPrefix).toLowerCase());
19112
+ return resolved.toLowerCase().startsWith(path53.resolve(globalPrefix).toLowerCase());
18962
19113
  } catch {
18963
19114
  return false;
18964
19115
  }