@staff0rd/assist 0.657.1 → 0.658.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.657.1",
9
+ version: "0.658.0",
10
10
  type: "module",
11
11
  main: "dist/index.js",
12
12
  bin: {
@@ -5019,28 +5019,45 @@ async function notify() {
5019
5019
  console.log(`Notification sent: ${notification_type} for ${projectName}`);
5020
5020
  }
5021
5021
 
5022
- // src/commands/activity/activityChart.ts
5022
+ // src/lib/renderLineChart.ts
5023
+ import * as fs16 from "fs";
5024
+ import * as tty from "tty";
5023
5025
  import blessed from "blessed";
5024
5026
  import contrib from "blessed-contrib";
5025
- function activityChart(data, range) {
5027
+ var keyboardInput = () => {
5028
+ if (process.stdin.isTTY) return void 0;
5029
+ try {
5030
+ return new tty.ReadStream(fs16.openSync("/dev/tty", "r"));
5031
+ } catch {
5032
+ return void 0;
5033
+ }
5034
+ };
5035
+ function renderLineChart({
5036
+ title,
5037
+ label: label2,
5038
+ seriesTitle,
5039
+ labels,
5040
+ values,
5041
+ wholeNumbersOnly = false
5042
+ }) {
5043
+ const input = keyboardInput();
5026
5044
  const screen = blessed.screen({
5027
5045
  smartCSR: true,
5028
- title: "Commit Activity"
5046
+ title,
5047
+ input
5029
5048
  });
5030
5049
  const grid = new contrib.grid({ rows: 1, cols: 1, screen });
5031
- const labels = data.map((d) => d.date.slice(5));
5032
- const values = data.map((d) => d.count);
5033
5050
  const line = grid.set(0, 0, 1, 1, contrib.line, {
5034
- label: ` Commits per week \xB7 ${range.since} \u2192 ${range.until} (press q to close) `,
5051
+ label: ` ${label2} (press q to close) `,
5035
5052
  showLegend: true,
5036
- legend: { width: 12 },
5053
+ legend: { width: Math.max(12, seriesTitle.length + 2) },
5037
5054
  xLabelPadding: 3,
5038
5055
  xPadding: 5,
5039
- wholeNumbersOnly: true
5056
+ wholeNumbersOnly
5040
5057
  });
5041
5058
  line.setData([
5042
5059
  {
5043
- title: "Commits",
5060
+ title: seriesTitle,
5044
5061
  x: labels,
5045
5062
  y: values,
5046
5063
  style: { line: "green" }
@@ -5048,6 +5065,7 @@ function activityChart(data, range) {
5048
5065
  ]);
5049
5066
  screen.key(["q", "C-c", "escape"], () => {
5050
5067
  screen.destroy();
5068
+ input?.destroy();
5051
5069
  });
5052
5070
  screen.render();
5053
5071
  }
@@ -5107,7 +5125,14 @@ async function activity(options2) {
5107
5125
  }
5108
5126
  const weeklyData = [...weekly.entries()].map(([date, count8]) => ({ date, count: count8 })).sort((a, b) => a.date.localeCompare(b.date));
5109
5127
  const until = data[data.length - 1].date;
5110
- activityChart(weeklyData, { since, until });
5128
+ renderLineChart({
5129
+ title: "Commit Activity",
5130
+ label: `Commits per week \xB7 ${since} \u2192 ${until}`,
5131
+ seriesTitle: "Commits",
5132
+ labels: weeklyData.map((d) => d.date.slice(5)),
5133
+ values: weeklyData.map((d) => d.count),
5134
+ wholeNumbersOnly: true
5135
+ });
5111
5136
  }
5112
5137
 
5113
5138
  // src/commands/registerActivity.ts
@@ -6337,6 +6362,72 @@ function registerBackup(program2) {
6337
6362
  configHelp(backupCommand, backupConfigHelp);
6338
6363
  }
6339
6364
 
6365
+ // src/commands/chart/parseChartSeries.ts
6366
+ function parseChartSeries(lines2) {
6367
+ const points = [];
6368
+ for (const line of lines2) {
6369
+ const trimmed = line.trim();
6370
+ if (trimmed === "") continue;
6371
+ const parts = trimmed.split(/[,\t ]+/).filter((part) => part !== "");
6372
+ if (parts.length < 2) {
6373
+ throw new Error(`Expected a label and a value, got: ${trimmed}`);
6374
+ }
6375
+ const label2 = parts.slice(0, -1).join(" ");
6376
+ const raw = parts[parts.length - 1];
6377
+ const value = Number(raw);
6378
+ if (!Number.isFinite(value)) {
6379
+ throw new Error(`Value "${raw}" is not numeric, on line: ${trimmed}`);
6380
+ }
6381
+ points.push({ label: label2, value });
6382
+ }
6383
+ return points;
6384
+ }
6385
+
6386
+ // src/commands/chart/readStdinLines.ts
6387
+ import * as readline2 from "readline";
6388
+ async function readStdinLines() {
6389
+ const rl = readline2.createInterface({
6390
+ input: process.stdin,
6391
+ terminal: false
6392
+ });
6393
+ const lines2 = [];
6394
+ for await (const line of rl) {
6395
+ lines2.push(line);
6396
+ }
6397
+ return lines2;
6398
+ }
6399
+
6400
+ // src/commands/chart.ts
6401
+ async function chart(options2) {
6402
+ const lines2 = await readStdinLines();
6403
+ let points;
6404
+ try {
6405
+ points = parseChartSeries(lines2);
6406
+ } catch (error) {
6407
+ console.error(error instanceof Error ? error.message : String(error));
6408
+ process.exit(1);
6409
+ }
6410
+ if (points.length < 2) {
6411
+ console.log("Not enough data points to chart.");
6412
+ return;
6413
+ }
6414
+ const title = options2.title ?? "Chart";
6415
+ renderLineChart({
6416
+ title,
6417
+ label: title,
6418
+ seriesTitle: title,
6419
+ labels: points.map((p) => p.label),
6420
+ values: points.map((p) => p.value)
6421
+ });
6422
+ }
6423
+
6424
+ // src/commands/registerChart.ts
6425
+ function registerChart(program2) {
6426
+ program2.command("chart").description(
6427
+ "Chart a label/value series read from stdin, one pair per line (comma, tab or whitespace separated)"
6428
+ ).option("--title <title>", "Chart title").action(chart);
6429
+ }
6430
+
6340
6431
  // src/commands/backlog/next.ts
6341
6432
  import chalk47 from "chalk";
6342
6433
  import enquirer5 from "enquirer";
@@ -8631,12 +8722,12 @@ import chalk44 from "chalk";
8631
8722
  import * as path29 from "path";
8632
8723
 
8633
8724
  // src/commands/sessions/shared/discoverSessions.ts
8634
- import * as fs20 from "fs";
8725
+ import * as fs21 from "fs";
8635
8726
  import * as os3 from "os";
8636
8727
  import * as path28 from "path";
8637
8728
 
8638
8729
  // src/commands/sessions/shared/codex/discoverCodexRolloutPaths.ts
8639
- import * as fs16 from "fs";
8730
+ import * as fs17 from "fs";
8640
8731
  import * as path25 from "path";
8641
8732
 
8642
8733
  // src/commands/sessions/shared/codex/codexSessionsDir.ts
@@ -8661,7 +8752,7 @@ async function discoverCodexRolloutPaths() {
8661
8752
  async function collect(dir, depth) {
8662
8753
  let entries;
8663
8754
  try {
8664
- entries = await fs16.promises.readdir(dir, { withFileTypes: true });
8755
+ entries = await fs17.promises.readdir(dir, { withFileTypes: true });
8665
8756
  } catch {
8666
8757
  return [];
8667
8758
  }
@@ -8677,7 +8768,7 @@ async function collectEntry(dir, entry, depth) {
8677
8768
  }
8678
8769
 
8679
8770
  // src/commands/sessions/shared/codex/parseCodexSessionFile.ts
8680
- import * as fs18 from "fs";
8771
+ import * as fs19 from "fs";
8681
8772
  import * as path26 from "path";
8682
8773
 
8683
8774
  // src/commands/sessions/shared/backlogRunMarkers.ts
@@ -8769,12 +8860,12 @@ function firstUserMessage(entry) {
8769
8860
  }
8770
8861
 
8771
8862
  // src/commands/sessions/shared/codex/readCodexHeadLines.ts
8772
- import * as fs17 from "fs";
8773
- import * as readline2 from "readline";
8863
+ import * as fs18 from "fs";
8864
+ import * as readline3 from "readline";
8774
8865
  var DEFAULT_MAX_LINES = 80;
8775
8866
  async function readCodexHeadLines(filePath, maxLines = DEFAULT_MAX_LINES) {
8776
- const stream = fs17.createReadStream(filePath, { encoding: "utf8" });
8777
- const reader = readline2.createInterface({ input: stream });
8867
+ const stream = fs18.createReadStream(filePath, { encoding: "utf8" });
8868
+ const reader = readline3.createInterface({ input: stream });
8778
8869
  const lines2 = [];
8779
8870
  try {
8780
8871
  for await (const line of reader) {
@@ -8812,7 +8903,7 @@ async function parseCodexSessionFile(filePath) {
8812
8903
  }
8813
8904
  }
8814
8905
  async function mtime(filePath) {
8815
- return (await fs18.promises.stat(filePath)).mtime.toISOString();
8906
+ return (await fs19.promises.stat(filePath)).mtime.toISOString();
8816
8907
  }
8817
8908
 
8818
8909
  // src/commands/sessions/shared/codex/discoverCodexSessions.ts
@@ -8823,7 +8914,7 @@ async function discoverCodexSessions() {
8823
8914
  }
8824
8915
 
8825
8916
  // src/commands/sessions/shared/parseSessionFile.ts
8826
- import * as fs19 from "fs";
8917
+ import * as fs20 from "fs";
8827
8918
 
8828
8919
  // src/commands/sessions/shared/extractSessionMeta.ts
8829
8920
  function extractSessionMeta(lines2) {
@@ -8894,10 +8985,10 @@ function dirNameToProject(filePath) {
8894
8985
  async function parseSessionFile(filePath, origin = "wsl") {
8895
8986
  let handle;
8896
8987
  try {
8897
- handle = await fs19.promises.open(filePath, "r");
8988
+ handle = await fs20.promises.open(filePath, "r");
8898
8989
  const meta = extractSessionMeta(await readHeadLines(handle));
8899
8990
  if (!meta.sessionId) return null;
8900
- const timestamp6 = meta.timestamp || (await fs19.promises.stat(filePath)).mtime.toISOString();
8991
+ const timestamp6 = meta.timestamp || (await fs20.promises.stat(filePath)).mtime.toISOString();
8901
8992
  return {
8902
8993
  sessionId: meta.sessionId,
8903
8994
  name: meta.name || `Session ${meta.sessionId.slice(0, 8)}`,
@@ -8934,7 +9025,7 @@ async function discoverSessionJsonlPaths() {
8934
9025
  sessionRoots().map(async ({ dir, origin }) => {
8935
9026
  let projectDirs;
8936
9027
  try {
8937
- projectDirs = await fs20.promises.readdir(dir);
9028
+ projectDirs = await fs21.promises.readdir(dir);
8938
9029
  } catch {
8939
9030
  return;
8940
9031
  }
@@ -8943,7 +9034,7 @@ async function discoverSessionJsonlPaths() {
8943
9034
  const dirPath = path28.join(dir, dirName);
8944
9035
  let entries;
8945
9036
  try {
8946
- entries = await fs20.promises.readdir(dirPath);
9037
+ entries = await fs21.promises.readdir(dirPath);
8947
9038
  } catch {
8948
9039
  return;
8949
9040
  }
@@ -9824,7 +9915,7 @@ import { spawn as spawn4 } from "child_process";
9824
9915
  import {
9825
9916
  closeSync,
9826
9917
  mkdirSync as mkdirSync10,
9827
- openSync,
9918
+ openSync as openSync2,
9828
9919
  statSync as statSync2,
9829
9920
  unlinkSync as unlinkSync5,
9830
9921
  writeSync
@@ -9864,7 +9955,7 @@ function acquireSpawnLock() {
9864
9955
  }
9865
9956
  function tryCreateLock() {
9866
9957
  try {
9867
- const fd = openSync(daemonPaths.spawnLock, "wx");
9958
+ const fd = openSync2(daemonPaths.spawnLock, "wx");
9868
9959
  writeSync(fd, String(process.pid));
9869
9960
  closeSync(fd);
9870
9961
  return true;
@@ -9886,7 +9977,7 @@ function releaseSpawnLock() {
9886
9977
  }
9887
9978
  }
9888
9979
  function spawnDaemon(reason4) {
9889
- const log2 = openSync(daemonPaths.log, "a");
9980
+ const log2 = openSync2(daemonPaths.log, "a");
9890
9981
  const child = spawn4(process.execPath, [process.argv[1], "daemon", "run"], {
9891
9982
  detached: true,
9892
9983
  windowsHide: true,
@@ -13544,7 +13635,7 @@ var handleRequest = createFallbackHandler(
13544
13635
  );
13545
13636
 
13546
13637
  // src/commands/sessions/web/handleSocket.ts
13547
- import { createInterface as createInterface3 } from "readline";
13638
+ import { createInterface as createInterface4 } from "readline";
13548
13639
  var CWD_DEFAULTED_TYPES = /* @__PURE__ */ new Set(["create", "create-run", "create-assist"]);
13549
13640
  function handleSocket(ws, ctx) {
13550
13641
  const connection = openDaemonConnection(ws, ctx);
@@ -13572,7 +13663,7 @@ async function openDaemonConnection(ws, ctx) {
13572
13663
  }
13573
13664
  }
13574
13665
  function relayDaemonLines(conn, ws, repoCwd) {
13575
- const lines2 = createInterface3({ input: conn });
13666
+ const lines2 = createInterface4({ input: conn });
13576
13667
  lines2.on("error", () => {
13577
13668
  });
13578
13669
  lines2.on("line", (line) => {
@@ -13836,7 +13927,7 @@ function installRestartMenu(options2 = {}) {
13836
13927
  }
13837
13928
 
13838
13929
  // src/commands/sessions/web/streamDaemonLogs.ts
13839
- import { createInterface as createInterface4 } from "readline";
13930
+ import { createInterface as createInterface5 } from "readline";
13840
13931
  var RECONNECT_MS = 3e3;
13841
13932
  function streamDaemonLogs() {
13842
13933
  void connect2();
@@ -13855,7 +13946,7 @@ async function connect2() {
13855
13946
  }
13856
13947
  }
13857
13948
  function wire(socket) {
13858
- const lines2 = createInterface4({ input: socket });
13949
+ const lines2 = createInterface5({ input: socket });
13859
13950
  lines2.on("error", () => {
13860
13951
  });
13861
13952
  lines2.on("line", emit);
@@ -13927,20 +14018,20 @@ async function web2(options2) {
13927
14018
  import chalk64 from "chalk";
13928
14019
 
13929
14020
  // src/commands/sessions/shared/resolveSessionTranscript.ts
13930
- import * as fs22 from "fs";
14021
+ import * as fs23 from "fs";
13931
14022
  import * as path35 from "path";
13932
14023
 
13933
14024
  // src/commands/sessions/summarise/readTranscriptHead.ts
13934
- import * as fs21 from "fs";
14025
+ import * as fs22 from "fs";
13935
14026
  function readTranscriptHead(filePath, maxBytes = 65536) {
13936
14027
  try {
13937
- const fd = fs21.openSync(filePath, "r");
14028
+ const fd = fs22.openSync(filePath, "r");
13938
14029
  try {
13939
14030
  const buf = Buffer.alloc(maxBytes);
13940
- const bytesRead = fs21.readSync(fd, buf, 0, buf.length, 0);
14031
+ const bytesRead = fs22.readSync(fd, buf, 0, buf.length, 0);
13941
14032
  return buf.toString("utf8", 0, bytesRead);
13942
14033
  } finally {
13943
- fs21.closeSync(fd);
14034
+ fs22.closeSync(fd);
13944
14035
  }
13945
14036
  } catch {
13946
14037
  return void 0;
@@ -13969,13 +14060,13 @@ function resolveSessionTranscript(sessionId, projectsRoot = claudeProjectsRoot()
13969
14060
  function findTranscriptFile(sessionId, projectsRoot) {
13970
14061
  let projectDirs;
13971
14062
  try {
13972
- projectDirs = fs22.readdirSync(projectsRoot);
14063
+ projectDirs = fs23.readdirSync(projectsRoot);
13973
14064
  } catch {
13974
14065
  return void 0;
13975
14066
  }
13976
14067
  for (const dir of projectDirs) {
13977
14068
  const candidate = path35.join(projectsRoot, dir, `${sessionId}.jsonl`);
13978
- if (fs22.existsSync(candidate)) return candidate;
14069
+ if (fs23.existsSync(candidate)) return candidate;
13979
14070
  }
13980
14071
  return void 0;
13981
14072
  }
@@ -14025,7 +14116,7 @@ async function addActivity(id, kind, ref, options2) {
14025
14116
  import chalk65 from "chalk";
14026
14117
 
14027
14118
  // src/commands/sessions/shared/resolveCurrentSessionId.ts
14028
- import * as fs23 from "fs";
14119
+ import * as fs24 from "fs";
14029
14120
  import * as path36 from "path";
14030
14121
  var SESSION_ID_ENV = "CLAUDE_CODE_SESSION_ID";
14031
14122
  function resolveCurrentSessionId(options2 = {}) {
@@ -14040,7 +14131,7 @@ function resolveCurrentSessionId(options2 = {}) {
14040
14131
  function newestTranscriptId(dir) {
14041
14132
  let entries;
14042
14133
  try {
14043
- entries = fs23.readdirSync(dir);
14134
+ entries = fs24.readdirSync(dir);
14044
14135
  } catch {
14045
14136
  return void 0;
14046
14137
  }
@@ -14056,7 +14147,7 @@ function newestTranscriptId(dir) {
14056
14147
  }
14057
14148
  function modifiedAtOf(filePath) {
14058
14149
  try {
14059
- return fs23.statSync(filePath).mtimeMs;
14150
+ return fs24.statSync(filePath).mtimeMs;
14060
14151
  } catch {
14061
14152
  return void 0;
14062
14153
  }
@@ -19022,13 +19113,13 @@ import chalk133 from "chalk";
19022
19113
  import chalk126 from "chalk";
19023
19114
 
19024
19115
  // src/commands/complexity/shared/index.ts
19025
- import fs25 from "fs";
19116
+ import fs26 from "fs";
19026
19117
  import path38 from "path";
19027
19118
  import chalk125 from "chalk";
19028
19119
  import ts5 from "typescript";
19029
19120
 
19030
19121
  // src/commands/complexity/findSourceFiles.ts
19031
- import fs24 from "fs";
19122
+ import fs25 from "fs";
19032
19123
  import path37 from "path";
19033
19124
  import { minimatch as minimatch5 } from "minimatch";
19034
19125
  function applyIgnoreGlobs(files, extraIgnore = []) {
@@ -19037,11 +19128,11 @@ function applyIgnoreGlobs(files, extraIgnore = []) {
19037
19128
  return files.filter((f) => !ignore3.some((glob) => minimatch5(f, glob)));
19038
19129
  }
19039
19130
  function walk2(dir, results) {
19040
- if (!fs24.existsSync(dir)) {
19131
+ if (!fs25.existsSync(dir)) {
19041
19132
  return;
19042
19133
  }
19043
19134
  const extensions = [".ts", ".tsx"];
19044
- const entries = fs24.readdirSync(dir, { withFileTypes: true });
19135
+ const entries = fs25.readdirSync(dir, { withFileTypes: true });
19045
19136
  for (const entry of entries) {
19046
19137
  const fullPath = path37.join(dir, entry.name);
19047
19138
  if (entry.isDirectory()) {
@@ -19062,10 +19153,10 @@ function findSourceFiles2(pattern2, baseDir = ".", extraIgnore = []) {
19062
19153
  extraIgnore
19063
19154
  );
19064
19155
  }
19065
- if (fs24.existsSync(pattern2) && fs24.statSync(pattern2).isFile()) {
19156
+ if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isFile()) {
19066
19157
  return [pattern2];
19067
19158
  }
19068
- if (fs24.existsSync(pattern2) && fs24.statSync(pattern2).isDirectory()) {
19159
+ if (fs25.existsSync(pattern2) && fs25.statSync(pattern2).isDirectory()) {
19069
19160
  walk2(pattern2, results);
19070
19161
  return applyIgnoreGlobs(results, extraIgnore);
19071
19162
  }
@@ -19263,7 +19354,7 @@ function countSloc(content) {
19263
19354
 
19264
19355
  // src/commands/complexity/shared/index.ts
19265
19356
  function createSourceFromFile(filePath) {
19266
- const content = fs25.readFileSync(filePath, "utf8");
19357
+ const content = fs26.readFileSync(filePath, "utf8");
19267
19358
  return ts5.createSourceFile(
19268
19359
  path38.basename(filePath),
19269
19360
  content,
@@ -19375,7 +19466,7 @@ function aggregateResults(fileMetrics) {
19375
19466
  }
19376
19467
 
19377
19468
  // src/commands/complexity/maintainability/collectFileMetrics.ts
19378
- import fs26 from "fs";
19469
+ import fs27 from "fs";
19379
19470
 
19380
19471
  // src/commands/complexity/maintainability/calculateMaintainabilityIndex.ts
19381
19472
  function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, sloc2) {
@@ -19390,7 +19481,7 @@ function calculateMaintainabilityIndex(halsteadVolume, cyclomaticComplexity, slo
19390
19481
  function collectFileMetrics(files) {
19391
19482
  const fileMetrics = /* @__PURE__ */ new Map();
19392
19483
  for (const file of files) {
19393
- const content = fs26.readFileSync(file, "utf8");
19484
+ const content = fs27.readFileSync(file, "utf8");
19394
19485
  fileMetrics.set(file, {
19395
19486
  sloc: countSloc(content),
19396
19487
  functions: [],
@@ -19551,14 +19642,14 @@ async function maintainability(pattern2 = "**/*.ts", options2 = {}) {
19551
19642
  }
19552
19643
 
19553
19644
  // src/commands/complexity/sloc.ts
19554
- import fs27 from "fs";
19645
+ import fs28 from "fs";
19555
19646
  import chalk132 from "chalk";
19556
19647
  async function sloc(pattern2 = "**/*.ts", options2 = {}) {
19557
19648
  withSourceFiles(pattern2, (files) => {
19558
19649
  const results = [];
19559
19650
  let hasViolation = false;
19560
19651
  for (const file of files) {
19561
- const content = fs27.readFileSync(file, "utf8");
19652
+ const content = fs28.readFileSync(file, "utf8");
19562
19653
  const lines2 = countSloc(content);
19563
19654
  results.push({ file, lines: lines2 });
19564
19655
  if (options2.threshold !== void 0 && lines2 > options2.threshold) {
@@ -20807,7 +20898,7 @@ function registerDevlog(program2) {
20807
20898
  }
20808
20899
 
20809
20900
  // src/commands/dotnet/checkBuildLocks.ts
20810
- import { closeSync as closeSync3, openSync as openSync3, readdirSync as readdirSync8 } from "fs";
20901
+ import { closeSync as closeSync3, openSync as openSync4, readdirSync as readdirSync8 } from "fs";
20811
20902
  import { join as join56 } from "path";
20812
20903
  import chalk154 from "chalk";
20813
20904
  var SKIP_DIRS = /* @__PURE__ */ new Set(["node_modules", ".git", "packages"]);
@@ -20822,7 +20913,7 @@ function isLockedDll(debugDir) {
20822
20913
  if (!file.toLowerCase().endsWith(".dll")) continue;
20823
20914
  const dllPath = join56(debugDir, file);
20824
20915
  try {
20825
- const fd = openSync3(dllPath, "r+");
20916
+ const fd = openSync4(dllPath, "r+");
20826
20917
  closeSync3(fd);
20827
20918
  } catch {
20828
20919
  return dllPath;
@@ -21417,7 +21508,7 @@ function registerDotnet(program2) {
21417
21508
  }
21418
21509
 
21419
21510
  // src/commands/editHook/index.ts
21420
- import fs28 from "fs";
21511
+ import fs29 from "fs";
21421
21512
 
21422
21513
  // src/commands/editHook/introducedComments.ts
21423
21514
  function introducedComments(added, removed) {
@@ -21664,7 +21755,7 @@ function tryParseInput2(raw) {
21664
21755
  function readExisting(filePath) {
21665
21756
  if (!filePath) return void 0;
21666
21757
  try {
21667
- return fs28.readFileSync(filePath, "utf8");
21758
+ return fs29.readFileSync(filePath, "utf8");
21668
21759
  } catch {
21669
21760
  return void 0;
21670
21761
  }
@@ -28267,17 +28358,17 @@ Refactor check failed:
28267
28358
 
28268
28359
  // src/commands/refactor/check/getViolations/index.ts
28269
28360
  import { execSync as execSync55 } from "child_process";
28270
- import fs30 from "fs";
28361
+ import fs31 from "fs";
28271
28362
  import { minimatch as minimatch6 } from "minimatch";
28272
28363
 
28273
28364
  // src/commands/refactor/check/getViolations/getIgnoredFiles.ts
28274
- import fs29 from "fs";
28365
+ import fs30 from "fs";
28275
28366
  var REFACTOR_YML_PATH = "refactor.yml";
28276
28367
  function parseRefactorYml() {
28277
- if (!fs29.existsSync(REFACTOR_YML_PATH)) {
28368
+ if (!fs30.existsSync(REFACTOR_YML_PATH)) {
28278
28369
  return [];
28279
28370
  }
28280
- const content = fs29.readFileSync(REFACTOR_YML_PATH, "utf8");
28371
+ const content = fs30.readFileSync(REFACTOR_YML_PATH, "utf8");
28281
28372
  const entries = [];
28282
28373
  const lines2 = content.split("\n");
28283
28374
  let currentEntry = {};
@@ -28307,7 +28398,7 @@ function getIgnoredFiles() {
28307
28398
 
28308
28399
  // src/commands/refactor/check/getViolations/index.ts
28309
28400
  function countLines(filePath) {
28310
- const content = fs30.readFileSync(filePath, "utf8");
28401
+ const content = fs31.readFileSync(filePath, "utf8");
28311
28402
  return content.split("\n").length;
28312
28403
  }
28313
28404
  function getGitFiles(options2) {
@@ -29065,11 +29156,11 @@ import chalk200 from "chalk";
29065
29156
  import { Project as Project4 } from "ts-morph";
29066
29157
 
29067
29158
  // src/commands/refactor/extract/findTsConfig.ts
29068
- import fs32 from "fs";
29159
+ import fs33 from "fs";
29069
29160
  import path52 from "path";
29070
29161
 
29071
29162
  // src/commands/refactor/extract/findEnclosingTsConfig.ts
29072
- import fs31 from "fs";
29163
+ import fs32 from "fs";
29073
29164
  import path51 from "path";
29074
29165
 
29075
29166
  // src/commands/refactor/extract/projectIncludesFile.ts
@@ -29090,7 +29181,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
29090
29181
  const nested = path51.join(dir, "tsconfig.json");
29091
29182
  if (!tried.has(nested)) {
29092
29183
  tried.add(nested);
29093
- if (fs31.existsSync(nested) && projectIncludesFile(nested, sourcePath)) {
29184
+ if (fs32.existsSync(nested) && projectIncludesFile(nested, sourcePath)) {
29094
29185
  return nested;
29095
29186
  }
29096
29187
  }
@@ -29104,7 +29195,7 @@ function findEnclosingTsConfig(sourcePath, rootDir, tried) {
29104
29195
  // src/commands/refactor/extract/findTsConfig.ts
29105
29196
  function findTsConfig(sourcePath) {
29106
29197
  const rootConfig = path52.resolve("tsconfig.json");
29107
- if (!fs32.existsSync(rootConfig)) return rootConfig;
29198
+ if (!fs33.existsSync(rootConfig)) return rootConfig;
29108
29199
  const tried = /* @__PURE__ */ new Set();
29109
29200
  const candidates = [rootConfig, ...readReferences(rootConfig)];
29110
29201
  for (const candidate of candidates) {
@@ -29112,7 +29203,7 @@ function findTsConfig(sourcePath) {
29112
29203
  tried.add(candidate);
29113
29204
  if (projectIncludesFile(candidate, sourcePath)) return candidate;
29114
29205
  }
29115
- const siblings = fs32.readdirSync(path52.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path52.resolve(path52.dirname(rootConfig), f));
29206
+ const siblings = fs33.readdirSync(path52.dirname(rootConfig)).filter((f) => /^tsconfig.*\.json$/.test(f)).map((f) => path52.resolve(path52.dirname(rootConfig), f));
29116
29207
  for (const sibling of siblings) {
29117
29208
  if (tried.has(sibling)) continue;
29118
29209
  tried.add(sibling);
@@ -29127,8 +29218,8 @@ function findTsConfig(sourcePath) {
29127
29218
  return rootConfig;
29128
29219
  }
29129
29220
  function readReferences(configPath) {
29130
- if (!fs32.existsSync(configPath)) return [];
29131
- const raw = fs32.readFileSync(configPath, "utf8");
29221
+ if (!fs33.existsSync(configPath)) return [];
29222
+ const raw = fs33.readFileSync(configPath, "utf8");
29132
29223
  const stripped = raw.replace(/\/\/.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "");
29133
29224
  let parsed;
29134
29225
  try {
@@ -29140,8 +29231,8 @@ function readReferences(configPath) {
29140
29231
  const cwd = path52.dirname(configPath);
29141
29232
  return parsed.references.map((ref) => {
29142
29233
  const refPath = path52.resolve(cwd, ref.path);
29143
- return fs32.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path52.join(refPath, "tsconfig.json") : refPath;
29144
- }).filter((p) => fs32.existsSync(p));
29234
+ return fs33.statSync(refPath, { throwIfNoEntry: false })?.isDirectory() ? path52.join(refPath, "tsconfig.json") : refPath;
29235
+ }).filter((p) => fs33.existsSync(p));
29145
29236
  }
29146
29237
 
29147
29238
  // src/commands/refactor/extract/loadProjectFile.ts
@@ -29183,25 +29274,25 @@ async function extract(file, functionName, destination, options2 = {}) {
29183
29274
  }
29184
29275
 
29185
29276
  // src/commands/refactor/ignore.ts
29186
- import fs33 from "fs";
29277
+ import fs34 from "fs";
29187
29278
  import chalk202 from "chalk";
29188
29279
  var REFACTOR_YML_PATH2 = "refactor.yml";
29189
29280
  function ignore2(file) {
29190
- if (!fs33.existsSync(file)) {
29281
+ if (!fs34.existsSync(file)) {
29191
29282
  console.error(chalk202.red(`Error: File does not exist: ${file}`));
29192
29283
  process.exit(1);
29193
29284
  }
29194
- const content = fs33.readFileSync(file, "utf8");
29285
+ const content = fs34.readFileSync(file, "utf8");
29195
29286
  const lineCount = content.split("\n").length;
29196
29287
  const maxLines = lineCount + 10;
29197
29288
  const entry = `- file: ${file}
29198
29289
  maxLines: ${maxLines}
29199
29290
  `;
29200
- if (fs33.existsSync(REFACTOR_YML_PATH2)) {
29201
- const existing = fs33.readFileSync(REFACTOR_YML_PATH2, "utf8");
29202
- fs33.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
29291
+ if (fs34.existsSync(REFACTOR_YML_PATH2)) {
29292
+ const existing = fs34.readFileSync(REFACTOR_YML_PATH2, "utf8");
29293
+ fs34.writeFileSync(REFACTOR_YML_PATH2, existing + entry);
29203
29294
  } else {
29204
- fs33.writeFileSync(REFACTOR_YML_PATH2, entry);
29295
+ fs34.writeFileSync(REFACTOR_YML_PATH2, entry);
29205
29296
  }
29206
29297
  console.log(
29207
29298
  chalk202.green(
@@ -29211,12 +29302,12 @@ function ignore2(file) {
29211
29302
  }
29212
29303
 
29213
29304
  // src/commands/refactor/rename/index.ts
29214
- import fs36 from "fs";
29305
+ import fs37 from "fs";
29215
29306
  import path59 from "path";
29216
29307
  import chalk205 from "chalk";
29217
29308
 
29218
29309
  // src/commands/refactor/rename/applyRename.ts
29219
- import fs35 from "fs";
29310
+ import fs36 from "fs";
29220
29311
  import path56 from "path";
29221
29312
  import chalk203 from "chalk";
29222
29313
 
@@ -29224,7 +29315,7 @@ import chalk203 from "chalk";
29224
29315
  import path55 from "path";
29225
29316
 
29226
29317
  // src/commands/refactor/restructure/computeRewrites/applyRewrites.ts
29227
- import fs34 from "fs";
29318
+ import fs35 from "fs";
29228
29319
  function getOrCreateList(map, key) {
29229
29320
  const list5 = map.get(key) ?? [];
29230
29321
  if (!map.has(key)) map.set(key, list5);
@@ -29243,7 +29334,7 @@ function rewriteSpecifier(content, oldSpecifier, newSpecifier) {
29243
29334
  return content.replace(pattern2, `$1${newSpecifier}$2`);
29244
29335
  }
29245
29336
  function applyFileRewrites(file, fileRewrites) {
29246
- let content = fs34.readFileSync(file, "utf8");
29337
+ let content = fs35.readFileSync(file, "utf8");
29247
29338
  for (const { oldSpecifier, newSpecifier } of fileRewrites) {
29248
29339
  content = rewriteSpecifier(content, oldSpecifier, newSpecifier);
29249
29340
  }
@@ -29322,12 +29413,12 @@ function computeRewrites(moves, edges, allProjectFiles) {
29322
29413
  function applyRename(rewrites, sourcePath, destPath, cwd) {
29323
29414
  const updatedContents = applyRewrites(rewrites);
29324
29415
  for (const [file, content] of updatedContents) {
29325
- fs35.writeFileSync(file, content, "utf8");
29416
+ fs36.writeFileSync(file, content, "utf8");
29326
29417
  console.log(chalk203.cyan(` Updated imports in ${path56.relative(cwd, file)}`));
29327
29418
  }
29328
29419
  const destDir = path56.dirname(destPath);
29329
- if (!fs35.existsSync(destDir)) fs35.mkdirSync(destDir, { recursive: true });
29330
- fs35.renameSync(sourcePath, destPath);
29420
+ if (!fs36.existsSync(destDir)) fs36.mkdirSync(destDir, { recursive: true });
29421
+ fs36.renameSync(sourcePath, destPath);
29331
29422
  console.log(
29332
29423
  chalk203.white(
29333
29424
  ` Moved ${path56.relative(cwd, sourcePath)} \u2192 ${path56.relative(cwd, destPath)}`
@@ -29435,11 +29526,11 @@ async function rename(source, destination, options2 = {}) {
29435
29526
  const cwd = process.cwd();
29436
29527
  const relSource = path59.relative(cwd, sourcePath);
29437
29528
  const relDest = path59.relative(cwd, destPath);
29438
- if (!fs36.existsSync(sourcePath)) {
29529
+ if (!fs37.existsSync(sourcePath)) {
29439
29530
  console.log(chalk205.red(`File not found: ${source}`));
29440
29531
  process.exit(1);
29441
29532
  }
29442
- if (destPath !== sourcePath && fs36.existsSync(destPath)) {
29533
+ if (destPath !== sourcePath && fs37.existsSync(destPath)) {
29443
29534
  console.log(chalk205.red(`Destination already exists: ${destination}`));
29444
29535
  process.exit(1);
29445
29536
  }
@@ -29664,27 +29755,27 @@ Summary: ${plan2.moves.length} file(s) moved, ${plan2.rewrites.length} imports r
29664
29755
  }
29665
29756
 
29666
29757
  // src/commands/refactor/restructure/executePlan.ts
29667
- import fs37 from "fs";
29758
+ import fs38 from "fs";
29668
29759
  import path64 from "path";
29669
29760
  import chalk208 from "chalk";
29670
29761
  function executePlan(plan2) {
29671
29762
  const updatedContents = applyRewrites(plan2.rewrites);
29672
29763
  for (const [file, content] of updatedContents) {
29673
- fs37.writeFileSync(file, content, "utf8");
29764
+ fs38.writeFileSync(file, content, "utf8");
29674
29765
  console.log(
29675
29766
  chalk208.cyan(` Rewrote imports in ${path64.relative(process.cwd(), file)}`)
29676
29767
  );
29677
29768
  }
29678
29769
  for (const dir of plan2.newDirectories) {
29679
- fs37.mkdirSync(dir, { recursive: true });
29770
+ fs38.mkdirSync(dir, { recursive: true });
29680
29771
  console.log(chalk208.green(` Created ${path64.relative(process.cwd(), dir)}/`));
29681
29772
  }
29682
29773
  for (const move2 of plan2.moves) {
29683
29774
  const targetDir = path64.dirname(move2.to);
29684
- if (!fs37.existsSync(targetDir)) {
29685
- fs37.mkdirSync(targetDir, { recursive: true });
29775
+ if (!fs38.existsSync(targetDir)) {
29776
+ fs38.mkdirSync(targetDir, { recursive: true });
29686
29777
  }
29687
- fs37.renameSync(move2.from, move2.to);
29778
+ fs38.renameSync(move2.from, move2.to);
29688
29779
  console.log(
29689
29780
  chalk208.white(
29690
29781
  ` Moved ${path64.relative(process.cwd(), move2.from)} \u2192 ${path64.relative(process.cwd(), move2.to)}`
@@ -29696,10 +29787,10 @@ function executePlan(plan2) {
29696
29787
  function removeEmptyDirectories(dirs) {
29697
29788
  const unique = [...new Set(dirs)];
29698
29789
  for (const dir of unique) {
29699
- if (!fs37.existsSync(dir)) continue;
29700
- const entries = fs37.readdirSync(dir);
29790
+ if (!fs38.existsSync(dir)) continue;
29791
+ const entries = fs38.readdirSync(dir);
29701
29792
  if (entries.length === 0) {
29702
- fs37.rmdirSync(dir);
29793
+ fs38.rmdirSync(dir);
29703
29794
  console.log(
29704
29795
  chalk208.dim(
29705
29796
  ` Removed empty directory ${path64.relative(process.cwd(), dir)}`
@@ -29713,18 +29804,18 @@ function removeEmptyDirectories(dirs) {
29713
29804
  import path66 from "path";
29714
29805
 
29715
29806
  // src/commands/refactor/restructure/planFileMoves/shared.ts
29716
- import fs38 from "fs";
29807
+ import fs39 from "fs";
29717
29808
  function emptyResult() {
29718
29809
  return { moves: [], directories: [], warnings: [] };
29719
29810
  }
29720
29811
  function checkDirConflict(result, label2, dir) {
29721
- if (!fs38.existsSync(dir)) return false;
29812
+ if (!fs39.existsSync(dir)) return false;
29722
29813
  result.warnings.push(`Skipping ${label2}: directory ${dir} already exists`);
29723
29814
  return true;
29724
29815
  }
29725
29816
 
29726
29817
  // src/commands/refactor/restructure/planFileMoves/planDirectoryMoves.ts
29727
- import fs39 from "fs";
29818
+ import fs40 from "fs";
29728
29819
  import path65 from "path";
29729
29820
  function collectEntry2(results, dir, entry) {
29730
29821
  const full = path65.join(dir, entry.name);
@@ -29732,9 +29823,9 @@ function collectEntry2(results, dir, entry) {
29732
29823
  results.push(...items2);
29733
29824
  }
29734
29825
  function listFilesRecursive(dir) {
29735
- if (!fs39.existsSync(dir)) return [];
29826
+ if (!fs40.existsSync(dir)) return [];
29736
29827
  const results = [];
29737
- for (const entry of fs39.readdirSync(dir, { withFileTypes: true })) {
29828
+ for (const entry of fs40.readdirSync(dir, { withFileTypes: true })) {
29738
29829
  collectEntry2(results, dir, entry);
29739
29830
  }
29740
29831
  return results;
@@ -32893,7 +32984,7 @@ function registerSql(program2) {
32893
32984
  }
32894
32985
 
32895
32986
  // src/commands/sync.ts
32896
- import * as fs48 from "fs";
32987
+ import * as fs49 from "fs";
32897
32988
  import * as os5 from "os";
32898
32989
  import * as path85 from "path";
32899
32990
  import { fileURLToPath as fileURLToPath9 } from "url";
@@ -32902,7 +32993,7 @@ import { fileURLToPath as fileURLToPath9 } from "url";
32902
32993
  import * as path76 from "path";
32903
32994
 
32904
32995
  // src/commands/sync/pruneTarget.ts
32905
- import * as fs40 from "fs";
32996
+ import * as fs41 from "fs";
32906
32997
  import * as path75 from "path";
32907
32998
  function pruneTarget(targetDir, keepNames, shape, options2) {
32908
32999
  const result = {
@@ -32911,9 +33002,9 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
32911
33002
  skipped: [],
32912
33003
  unmanaged: []
32913
33004
  };
32914
- if (!fs40.existsSync(targetDir)) return result;
33005
+ if (!fs41.existsSync(targetDir)) return result;
32915
33006
  const keep = new Set(keepNames);
32916
- for (const entry of fs40.readdirSync(targetDir, { withFileTypes: true })) {
33007
+ for (const entry of fs41.readdirSync(targetDir, { withFileTypes: true })) {
32917
33008
  const name = shape.nameOf(entry);
32918
33009
  if (name === void 0) {
32919
33010
  result.unmanaged.push(entry.name);
@@ -32928,7 +33019,7 @@ function pruneTarget(targetDir, keepNames, shape, options2) {
32928
33019
  continue;
32929
33020
  }
32930
33021
  if (options2.force) {
32931
- fs40.rmSync(entryPath, { recursive: true });
33022
+ fs41.rmSync(entryPath, { recursive: true });
32932
33023
  result.removed.push(entry.name);
32933
33024
  }
32934
33025
  }
@@ -32975,7 +33066,7 @@ function reportPrune(label2, result, force) {
32975
33066
  }
32976
33067
 
32977
33068
  // src/commands/sync/reportRetiredAgentsFiles.ts
32978
- import * as fs41 from "fs";
33069
+ import * as fs42 from "fs";
32979
33070
  import * as path77 from "path";
32980
33071
  var retired = [
32981
33072
  path77.join(harnesses.claude.homeDir, "CLAUDE.md"),
@@ -32983,7 +33074,7 @@ var retired = [
32983
33074
  path77.join(harnesses.pi.homeDir, "AGENTS.md")
32984
33075
  ];
32985
33076
  function reportRetiredAgentsFiles() {
32986
- const leftovers = retired.filter((file) => fs41.existsSync(file));
33077
+ const leftovers = retired.filter((file) => fs42.existsSync(file));
32987
33078
  if (leftovers.length === 0) return;
32988
33079
  console.log(
32989
33080
  "No longer written by sync \u2014 each harness now composes its own advice at session start:"
@@ -32998,28 +33089,28 @@ function reportRetiredAgentsFiles() {
32998
33089
  import * as path80 from "path";
32999
33090
 
33000
33091
  // src/commands/sync/installHarnessCommands.ts
33001
- import * as fs42 from "fs";
33092
+ import * as fs43 from "fs";
33002
33093
  import * as path78 from "path";
33003
33094
  function installHarnessCommands(claudeDir, harness, transform) {
33004
33095
  const commandsSource = path78.join(claudeDir, "commands");
33005
- const files = fs42.readdirSync(commandsSource);
33096
+ const files = fs43.readdirSync(commandsSource);
33006
33097
  const names = [];
33007
33098
  let synced = 0;
33008
33099
  for (const file of files) {
33009
33100
  if (!file.endsWith(".md")) continue;
33010
33101
  const name = file.replace(/\.md$/, "");
33011
33102
  names.push(name);
33012
- const content = fs42.readFileSync(path78.join(commandsSource, file), "utf8");
33103
+ const content = fs43.readFileSync(path78.join(commandsSource, file), "utf8");
33013
33104
  const target = path78.join(harness.homeDir, harness.sync.commandDest(name));
33014
- fs42.mkdirSync(path78.dirname(target), { recursive: true });
33015
- fs42.writeFileSync(target, transform(name, content));
33105
+ fs43.mkdirSync(path78.dirname(target), { recursive: true });
33106
+ fs43.writeFileSync(target, transform(name, content));
33016
33107
  synced++;
33017
33108
  }
33018
33109
  return { total: files.length, synced, names };
33019
33110
  }
33020
33111
 
33021
33112
  // src/commands/sync/pruneSkills.ts
33022
- import * as fs43 from "fs";
33113
+ import * as fs44 from "fs";
33023
33114
  function pruneSkills(targetDir, skillNames, options2) {
33024
33115
  return pruneTarget(
33025
33116
  targetDir,
@@ -33032,14 +33123,14 @@ function pruneSkills(targetDir, skillNames, options2) {
33032
33123
  );
33033
33124
  }
33034
33125
  function unexpectedContent(skillDir) {
33035
- const entries = fs43.readdirSync(skillDir);
33126
+ const entries = fs44.readdirSync(skillDir);
33036
33127
  const others = entries.filter((entry) => entry !== "SKILL.md");
33037
33128
  if (others.length > 0) return `contains ${others.sort().join(", ")}`;
33038
33129
  return entries.length === 0 ? "no SKILL.md" : void 0;
33039
33130
  }
33040
33131
 
33041
33132
  // src/commands/sync/syncCodexHooks.ts
33042
- import * as fs44 from "fs";
33133
+ import * as fs45 from "fs";
33043
33134
  import * as path79 from "path";
33044
33135
  var BEGIN = "# >>> assist codex hooks (managed) \u2014 do not edit >>>";
33045
33136
  var END = "# <<< assist codex hooks (managed) <<<";
@@ -33070,11 +33161,11 @@ ${rest}
33070
33161
  `;
33071
33162
  }
33072
33163
  function syncCodexHooks(sourcePath) {
33073
- const body = fs44.readFileSync(sourcePath, "utf8");
33164
+ const body = fs45.readFileSync(sourcePath, "utf8");
33074
33165
  const configPath = path79.join(harnesses.codex.homeDir, "config.toml");
33075
- const existing = fs44.existsSync(configPath) ? fs44.readFileSync(configPath, "utf8") : "";
33076
- fs44.mkdirSync(path79.dirname(configPath), { recursive: true });
33077
- fs44.writeFileSync(configPath, upsertManagedBlock(existing, body));
33166
+ const existing = fs45.existsSync(configPath) ? fs45.readFileSync(configPath, "utf8") : "";
33167
+ fs45.mkdirSync(path79.dirname(configPath), { recursive: true });
33168
+ fs45.writeFileSync(configPath, upsertManagedBlock(existing, body));
33078
33169
  console.log(
33079
33170
  "Registered assist codex-hook in ~/.codex/config.toml (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PermissionRequest, Stop)"
33080
33171
  );
@@ -33117,21 +33208,21 @@ function syncCodex(claudeDir, options2) {
33117
33208
  }
33118
33209
 
33119
33210
  // src/commands/sync/syncDesign.ts
33120
- import * as fs45 from "fs";
33211
+ import * as fs46 from "fs";
33121
33212
  import * as path81 from "path";
33122
33213
  function syncDesign(claudeDir, targetBase) {
33123
33214
  const systemPromptSource = path81.join(claudeDir, "design-system-prompt.md");
33124
33215
  const systemPromptTarget = path81.join(targetBase, "design-system-prompt.md");
33125
- fs45.copyFileSync(systemPromptSource, systemPromptTarget);
33216
+ fs46.copyFileSync(systemPromptSource, systemPromptTarget);
33126
33217
  console.log(
33127
33218
  "Copied design-system-prompt.md to ~/.claude/design-system-prompt.md"
33128
33219
  );
33129
33220
  const skillsSource = path81.join(claudeDir, "skills");
33130
33221
  const skillsTarget = path81.join(targetBase, "skills");
33131
- fs45.mkdirSync(skillsTarget, { recursive: true });
33132
- const files = fs45.readdirSync(skillsSource);
33222
+ fs46.mkdirSync(skillsTarget, { recursive: true });
33223
+ const files = fs46.readdirSync(skillsSource);
33133
33224
  for (const file of files) {
33134
- fs45.copyFileSync(
33225
+ fs46.copyFileSync(
33135
33226
  path81.join(skillsSource, file),
33136
33227
  path81.join(skillsTarget, file)
33137
33228
  );
@@ -33143,17 +33234,17 @@ function syncDesign(claudeDir, targetBase) {
33143
33234
  import * as path83 from "path";
33144
33235
 
33145
33236
  // src/commands/sync/syncPiHooks.ts
33146
- import * as fs46 from "fs";
33237
+ import * as fs47 from "fs";
33147
33238
  import * as path82 from "path";
33148
33239
  function piExtensionsDir() {
33149
33240
  return path82.join(harnesses.pi.homeDir, "extensions");
33150
33241
  }
33151
33242
  function syncPiHooks(sourceDir) {
33152
33243
  const target = piExtensionsDir();
33153
- fs46.mkdirSync(target, { recursive: true });
33154
- const files = fs46.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
33244
+ fs47.mkdirSync(target, { recursive: true });
33245
+ const files = fs47.readdirSync(sourceDir).filter((f) => f.endsWith(".ts"));
33155
33246
  for (const file of files) {
33156
- fs46.copyFileSync(
33247
+ fs47.copyFileSync(
33157
33248
  path82.join(sourceDir, file),
33158
33249
  path82.join(target, `assist-${file}`)
33159
33250
  );
@@ -33204,16 +33295,16 @@ function syncPi(claudeDir, options2) {
33204
33295
  }
33205
33296
 
33206
33297
  // src/commands/sync/syncSettings.ts
33207
- import * as fs47 from "fs";
33298
+ import * as fs48 from "fs";
33208
33299
  import * as path84 from "path";
33209
33300
  import chalk227 from "chalk";
33210
33301
  async function syncSettings(claudeDir, targetBase, options2) {
33211
33302
  const source = path84.join(claudeDir, "settings.json");
33212
33303
  const target = path84.join(targetBase, "settings.json");
33213
- const sourceContent = fs47.readFileSync(source, "utf8");
33304
+ const sourceContent = fs48.readFileSync(source, "utf8");
33214
33305
  const sourceSettings = JSON.parse(sourceContent);
33215
- const targetExists = fs47.existsSync(target);
33216
- const targetContent = targetExists ? fs47.readFileSync(target, "utf8") : "";
33306
+ const targetExists = fs48.existsSync(target);
33307
+ const targetContent = targetExists ? fs48.readFileSync(target, "utf8") : "";
33217
33308
  const preservedUserSettings = targetExists ? JSON.parse(targetContent) : {};
33218
33309
  const mergedContent = JSON.stringify(
33219
33310
  { ...preservedUserSettings, ...sourceSettings },
@@ -33243,7 +33334,7 @@ async function syncSettings(claudeDir, targetBase, options2) {
33243
33334
  }
33244
33335
  }
33245
33336
  }
33246
- fs47.writeFileSync(target, mergedContent);
33337
+ fs48.writeFileSync(target, mergedContent);
33247
33338
  console.log("Copied settings.json to ~/.claude/settings.json");
33248
33339
  }
33249
33340
 
@@ -33274,10 +33365,10 @@ async function sync(options2) {
33274
33365
  function syncCommands(claudeDir, targetBase) {
33275
33366
  const sourceDir = path85.join(claudeDir, "commands");
33276
33367
  const targetDir = path85.join(targetBase, "commands");
33277
- fs48.mkdirSync(targetDir, { recursive: true });
33278
- const files = fs48.readdirSync(sourceDir);
33368
+ fs49.mkdirSync(targetDir, { recursive: true });
33369
+ const files = fs49.readdirSync(sourceDir);
33279
33370
  for (const file of files) {
33280
- fs48.copyFileSync(path85.join(sourceDir, file), path85.join(targetDir, file));
33371
+ fs49.copyFileSync(path85.join(sourceDir, file), path85.join(targetDir, file));
33281
33372
  console.log(`Copied ${file} to ${targetDir}`);
33282
33373
  }
33283
33374
  console.log(`Synced ${files.length} command(s) to ~/.claude/commands`);
@@ -33596,9 +33687,9 @@ function clean(file, options2 = {}) {
33596
33687
  }
33597
33688
 
33598
33689
  // src/commands/transcript/shared.ts
33599
- import * as readline3 from "readline";
33690
+ import * as readline4 from "readline";
33600
33691
  function createReadlineInterface() {
33601
- return readline3.createInterface({
33692
+ return readline4.createInterface({
33602
33693
  input: process.stdin,
33603
33694
  output: process.stdout
33604
33695
  });
@@ -35659,7 +35750,7 @@ function listDaemonPids() {
35659
35750
  }
35660
35751
 
35661
35752
  // src/commands/sessions/daemon/queryDaemon.ts
35662
- import { createInterface as createInterface6 } from "readline";
35753
+ import { createInterface as createInterface7 } from "readline";
35663
35754
  var STATUS_TIMEOUT_MS = 5e3;
35664
35755
  function queryDaemon(socket) {
35665
35756
  socket.write(`${JSON.stringify({ type: "ping" })}
@@ -35668,7 +35759,7 @@ function queryDaemon(socket) {
35668
35759
  const result = { sessions: [] };
35669
35760
  const pending = /* @__PURE__ */ new Set(["sessions", "pong"]);
35670
35761
  const timer = setTimeout(() => resolve25(result), STATUS_TIMEOUT_MS);
35671
- const lines2 = createInterface6({ input: socket });
35762
+ const lines2 = createInterface7({ input: socket });
35672
35763
  lines2.on("error", () => {
35673
35764
  });
35674
35765
  lines2.on("line", (line) => {
@@ -35758,7 +35849,7 @@ function reportStrays(pids) {
35758
35849
  }
35759
35850
 
35760
35851
  // src/commands/sessions/daemon/drainDaemon.ts
35761
- import { createInterface as createInterface7 } from "readline";
35852
+ import { createInterface as createInterface8 } from "readline";
35762
35853
 
35763
35854
  // src/commands/sessions/daemon/clearPersistedSessionsOnDrain.ts
35764
35855
  function clearPersistedSessionsOnDrain() {
@@ -35800,7 +35891,7 @@ async function drainDaemon(options2 = {}) {
35800
35891
  clearPersistedSessionsOnDrain();
35801
35892
  return;
35802
35893
  }
35803
- const lines2 = createInterface7({ input: socket });
35894
+ const lines2 = createInterface8({ input: socket });
35804
35895
  lines2.on("error", () => {
35805
35896
  });
35806
35897
  const live = await liveSessions(lines2);
@@ -36264,7 +36355,7 @@ function serverRunMeta(runName, cwd) {
36264
36355
  }
36265
36356
 
36266
36357
  // src/commands/sessions/daemon/readDesignSystemPrompt.ts
36267
- import * as fs49 from "fs";
36358
+ import * as fs50 from "fs";
36268
36359
  import * as path87 from "path";
36269
36360
  import { fileURLToPath as fileURLToPath11 } from "url";
36270
36361
  var __filename5 = fileURLToPath11(import.meta.url);
@@ -36276,7 +36367,7 @@ function readDesignSystemPrompt() {
36276
36367
  "claude",
36277
36368
  "design-system-prompt.md"
36278
36369
  );
36279
- return fs49.readFileSync(promptPath, "utf8");
36370
+ return fs50.readFileSync(promptPath, "utf8");
36280
36371
  }
36281
36372
 
36282
36373
  // src/commands/sessions/daemon/spawnClaude.ts
@@ -37365,7 +37456,7 @@ function reportSilentFailure(session, clients) {
37365
37456
  }
37366
37457
 
37367
37458
  // src/commands/sessions/shared/codex/resolveCodexSessionId.ts
37368
- import * as fs50 from "fs";
37459
+ import * as fs51 from "fs";
37369
37460
  var META_LINES = 5;
37370
37461
  async function resolveCodexSessionId(cwd, sinceMs) {
37371
37462
  if (!cwd) return null;
@@ -37394,7 +37485,7 @@ async function startedIn(file, cwd, sinceMs) {
37394
37485
  }
37395
37486
  async function touchedSince(file, sinceMs) {
37396
37487
  try {
37397
- return (await fs50.promises.stat(file)).mtimeMs >= sinceMs;
37488
+ return (await fs51.promises.stat(file)).mtimeMs >= sinceMs;
37398
37489
  } catch {
37399
37490
  return false;
37400
37491
  }
@@ -37428,7 +37519,7 @@ function bindCodexSession(session, notify2) {
37428
37519
  import { watch as watch3 } from "fs";
37429
37520
 
37430
37521
  // src/commands/sessions/shared/findTranscriptPathSync.ts
37431
- import * as fs51 from "fs";
37522
+ import * as fs52 from "fs";
37432
37523
  import * as path88 from "path";
37433
37524
  function projectDirForCwd(cwd) {
37434
37525
  return path88.join(claudeProjectsRoot(), projectSlug(cwd));
@@ -37438,11 +37529,11 @@ function transcriptPathFor(cwd, claudeSessionId) {
37438
37529
  }
37439
37530
  function findTranscriptPathSync(cwd, claudeSessionId) {
37440
37531
  const direct = transcriptPathFor(cwd, claudeSessionId);
37441
- if (fs51.existsSync(direct)) return direct;
37532
+ if (fs52.existsSync(direct)) return direct;
37442
37533
  const dir = projectDirForCwd(cwd);
37443
37534
  let files;
37444
37535
  try {
37445
- files = fs51.readdirSync(dir);
37536
+ files = fs52.readdirSync(dir);
37446
37537
  } catch {
37447
37538
  return null;
37448
37539
  }
@@ -37456,14 +37547,14 @@ function findTranscriptPathSync(cwd, claudeSessionId) {
37456
37547
  function headContainsSessionId(filePath, claudeSessionId) {
37457
37548
  let fd;
37458
37549
  try {
37459
- fd = fs51.openSync(filePath, "r");
37550
+ fd = fs52.openSync(filePath, "r");
37460
37551
  const buf = Buffer.alloc(16384);
37461
- const bytesRead = fs51.readSync(fd, buf, 0, buf.length, 0);
37552
+ const bytesRead = fs52.readSync(fd, buf, 0, buf.length, 0);
37462
37553
  return buf.toString("utf8", 0, bytesRead).includes(claudeSessionId);
37463
37554
  } catch {
37464
37555
  return false;
37465
37556
  } finally {
37466
- if (fd !== void 0) fs51.closeSync(fd);
37557
+ if (fd !== void 0) fs52.closeSync(fd);
37467
37558
  }
37468
37559
  }
37469
37560
 
@@ -37633,7 +37724,7 @@ function asRecord3(value) {
37633
37724
  }
37634
37725
 
37635
37726
  // src/commands/sessions/shared/readTranscriptTail.ts
37636
- import * as fs52 from "fs";
37727
+ import * as fs53 from "fs";
37637
37728
  var DEFAULT_MAX_BYTES = 256 * 1024;
37638
37729
  function parseTailEntries(raw) {
37639
37730
  const entries = [];
@@ -37657,7 +37748,7 @@ function dropPartialFirstLine(raw, sliced) {
37657
37748
  async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37658
37749
  let handle;
37659
37750
  try {
37660
- handle = await fs52.promises.open(filePath, "r");
37751
+ handle = await fs53.promises.open(filePath, "r");
37661
37752
  const { size } = await handle.stat();
37662
37753
  const start3 = Math.max(0, size - maxBytes);
37663
37754
  const length = size - start3;
@@ -37676,20 +37767,20 @@ async function readTranscriptTail(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37676
37767
  function readTranscriptTailSync(filePath, maxBytes = DEFAULT_MAX_BYTES) {
37677
37768
  let fd;
37678
37769
  try {
37679
- fd = fs52.openSync(filePath, "r");
37680
- const { size } = fs52.fstatSync(fd);
37770
+ fd = fs53.openSync(filePath, "r");
37771
+ const { size } = fs53.fstatSync(fd);
37681
37772
  const start3 = Math.max(0, size - maxBytes);
37682
37773
  const length = size - start3;
37683
37774
  if (length === 0) return [];
37684
37775
  const buf = Buffer.alloc(length);
37685
- fs52.readSync(fd, buf, 0, length, start3);
37776
+ fs53.readSync(fd, buf, 0, length, start3);
37686
37777
  return parseTailEntries(
37687
37778
  dropPartialFirstLine(buf.toString("utf8"), start3 > 0)
37688
37779
  );
37689
37780
  } catch {
37690
37781
  return [];
37691
37782
  } finally {
37692
- if (fd !== void 0) fs52.closeSync(fd);
37783
+ if (fd !== void 0) fs53.closeSync(fd);
37693
37784
  }
37694
37785
  }
37695
37786
 
@@ -38068,7 +38159,7 @@ async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
38068
38159
  }
38069
38160
 
38070
38161
  // src/commands/sessions/shared/transcriptUsage.ts
38071
- import * as fs53 from "fs";
38162
+ import * as fs54 from "fs";
38072
38163
  function transcriptUsage(lines2) {
38073
38164
  const byId = /* @__PURE__ */ new Map();
38074
38165
  for (const line of lines2) {
@@ -38092,7 +38183,7 @@ function transcriptUsage(lines2) {
38092
38183
  return [...byId.values()];
38093
38184
  }
38094
38185
  async function readTranscriptUsage(transcriptPath2) {
38095
- const content = await fs53.promises.readFile(transcriptPath2, "utf8");
38186
+ const content = await fs54.promises.readFile(transcriptPath2, "utf8");
38096
38187
  return transcriptUsage(content.split("\n"));
38097
38188
  }
38098
38189
 
@@ -39785,10 +39876,10 @@ async function isWindowsDaemonRunning() {
39785
39876
  import { spawn as spawn11 } from "child_process";
39786
39877
 
39787
39878
  // src/commands/sessions/daemon/logChildStream.ts
39788
- import { createInterface as createInterface8 } from "readline";
39879
+ import { createInterface as createInterface9 } from "readline";
39789
39880
  function logChildStream(stream, label2, onLine) {
39790
39881
  if (!stream) return;
39791
- const lines2 = createInterface8({ input: stream });
39882
+ const lines2 = createInterface9({ input: stream });
39792
39883
  lines2.on("line", (line) => {
39793
39884
  daemonLog(`[${label2}] ${line}`);
39794
39885
  onLine?.(line);
@@ -40218,7 +40309,7 @@ function isWindowsIo(data) {
40218
40309
  }
40219
40310
 
40220
40311
  // src/commands/sessions/daemon/WindowsConnection.ts
40221
- import { createInterface as createInterface9 } from "readline";
40312
+ import { createInterface as createInterface10 } from "readline";
40222
40313
 
40223
40314
  // src/commands/sessions/daemon/LaunchCircuitBreaker.ts
40224
40315
  var MAX_FAILURES = 3;
@@ -40305,7 +40396,7 @@ var WindowsConnection = class {
40305
40396
  return socket;
40306
40397
  }
40307
40398
  wire(socket) {
40308
- const lines2 = createInterface9({ input: socket });
40399
+ const lines2 = createInterface10({ input: socket });
40309
40400
  lines2.on("error", () => {
40310
40401
  });
40311
40402
  lines2.on("line", (line) => this.deps.onLine(line));
@@ -40914,7 +41005,7 @@ function exitAfterFlush(code) {
40914
41005
  }
40915
41006
 
40916
41007
  // src/commands/sessions/daemon/handleConnection.ts
40917
- import { createInterface as createInterface10 } from "readline";
41008
+ import { createInterface as createInterface11 } from "readline";
40918
41009
 
40919
41010
  // src/commands/sessions/daemon/creator.ts
40920
41011
  function creator(isNew, spawn13) {
@@ -40989,7 +41080,7 @@ function handleSetStatus(client, m, d) {
40989
41080
  }
40990
41081
 
40991
41082
  // src/commands/sessions/shared/parseTranscript.ts
40992
- import * as fs54 from "fs";
41083
+ import * as fs55 from "fs";
40993
41084
 
40994
41085
  // src/commands/sessions/shared/codex/findCodexRolloutPath.ts
40995
41086
  import * as path89 from "path";
@@ -41072,7 +41163,7 @@ async function parseTranscript(sessionId) {
41072
41163
  }
41073
41164
  async function readMessages(filePath, parse4) {
41074
41165
  try {
41075
- const raw = await fs54.promises.readFile(filePath, "utf8");
41166
+ const raw = await fs55.promises.readFile(filePath, "utf8");
41076
41167
  return parse4(raw.split("\n"));
41077
41168
  } catch {
41078
41169
  return [];
@@ -41278,7 +41369,7 @@ function handleConnection(socket, manager) {
41278
41369
  };
41279
41370
  manager.addClient(client);
41280
41371
  manager.clients.greet(client);
41281
- const lines2 = createInterface10({ input: socket });
41372
+ const lines2 = createInterface11({ input: socket });
41282
41373
  lines2.on("error", () => {
41283
41374
  });
41284
41375
  lines2.on("line", (line) => {
@@ -41600,17 +41691,17 @@ async function renameSession(title) {
41600
41691
  }
41601
41692
 
41602
41693
  // src/commands/sessions/summarise/index.ts
41603
- import * as fs56 from "fs";
41694
+ import * as fs57 from "fs";
41604
41695
  import chalk230 from "chalk";
41605
41696
 
41606
41697
  // src/commands/sessions/summarise/shared.ts
41607
- import * as fs55 from "fs";
41698
+ import * as fs56 from "fs";
41608
41699
  function writeSummary(jsonlPath2, summary) {
41609
- fs55.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
41700
+ fs56.writeFileSync(summaryPathFor(jsonlPath2), `${summary.trim()}
41610
41701
  `, "utf8");
41611
41702
  }
41612
41703
  function hasSummary(jsonlPath2) {
41613
- return fs55.existsSync(summaryPathFor(jsonlPath2));
41704
+ return fs56.existsSync(summaryPathFor(jsonlPath2));
41614
41705
  }
41615
41706
  function summaryPathFor(jsonlPath2) {
41616
41707
  return jsonlPath2.replace(/\.jsonl$/, ".summary");
@@ -41682,7 +41773,7 @@ function selectCandidates(files, options2) {
41682
41773
  const candidates = options2.force ? files : files.filter((f) => !hasSummary(f));
41683
41774
  candidates.sort((a, b) => {
41684
41775
  try {
41685
- return fs56.statSync(b).mtimeMs - fs56.statSync(a).mtimeMs;
41776
+ return fs57.statSync(b).mtimeMs - fs57.statSync(a).mtimeMs;
41686
41777
  } catch {
41687
41778
  return 0;
41688
41779
  }
@@ -42005,6 +42096,7 @@ configHelp(screenshotCommand, rootConfigHelp.screenshot);
42005
42096
  registerActivity(program);
42006
42097
  registerAdvise(program);
42007
42098
  registerBackup(program);
42099
+ registerChart(program);
42008
42100
  registerDb(program);
42009
42101
  registerDbMigration(program);
42010
42102
  registerCliHook(program);