@wrongstack/tools 0.6.0 → 0.6.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/outdated.js CHANGED
@@ -1,13 +1,9 @@
1
1
  import { spawn } from 'child_process';
2
+ import { stat } from 'fs/promises';
2
3
  import { buildChildEnv } from '@wrongstack/core';
3
4
  import * as path from 'path';
4
5
 
5
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
6
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
7
- }) : x)(function(x) {
8
- if (typeof require !== "undefined") return require.apply(this, arguments);
9
- throw Error('Dynamic require of "' + x + '" is not supported');
10
- });
6
+ // src/outdated.ts
11
7
  function resolvePath(input, ctx) {
12
8
  return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.cwd, input);
13
9
  }
@@ -62,7 +58,6 @@ var outdatedTool = {
62
58
  }
63
59
  };
64
60
  async function detectManager(cwd) {
65
- const { stat } = __require("fs/promises");
66
61
  try {
67
62
  await stat(`${cwd}/pnpm-lock.yaml`);
68
63
  return "pnpm";
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/_util.ts","../src/outdated.ts"],"names":["resolve"],"mappings":"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","file":"outdated.js","sourcesContent":["import * as path from 'node:path';\nimport type { Context } from '@wrongstack/core';\n\nexport function resolvePath(input: string, ctx: Context): string {\n return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.cwd, input);\n}\n\nexport function ensureInsideRoot(absPath: string, ctx: Context): string {\n const root = path.resolve(ctx.projectRoot);\n const target = path.resolve(absPath);\n const rel = path.relative(root, target);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`Path \"${absPath}\" is outside project root \"${root}\"`);\n }\n return target;\n}\n\nexport function safeResolve(input: string, ctx: Context): string {\n return ensureInsideRoot(resolvePath(input, ctx), ctx);\n}\n\nexport function truncateMiddle(s: string, max: number): string {\n if (Buffer.byteLength(s, 'utf8') <= max) return s;\n const half = Math.floor(max / 2);\n return (\n s.slice(0, half) +\n `\\n…[truncated ${Buffer.byteLength(s, 'utf8') - max} bytes from middle]…\\n` +\n s.slice(-half)\n );\n}\n\nexport function isBinaryBuffer(buf: Buffer): boolean {\n const len = Math.min(buf.length, 8192);\n for (let i = 0; i < len; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n}\n","import { spawn } from 'node:child_process';\nimport { buildChildEnv } from '@wrongstack/core';\nimport type { Tool } from '@wrongstack/core';\nimport { safeResolve } from './_util.js';\n\ninterface OutdatedInput {\n cwd?: string;\n format?: 'list' | 'table';\n include_deprecated?: boolean;\n check?: string | string[];\n}\n\ninterface OutdatedPackage {\n name: string;\n current: string;\n latest: string;\n wanted: string;\n type: string;\n location: string;\n}\n\ninterface OutdatedOutput {\n exit_code: number;\n packages: OutdatedPackage[];\n total: number;\n output: string;\n truncated: boolean;\n}\n\nexport const outdatedTool: Tool<OutdatedInput, OutdatedOutput> = {\n name: 'outdated',\n category: 'Package Management',\n description: 'Check for outdated npm packages. Shows current, wanted, and latest versions.',\n usageHint:\n 'Set `check` to filter specific packages. `format` as list or table. `include_deprecated` shows deprecated packages.',\n permission: 'auto',\n mutating: false,\n timeoutMs: 60_000,\n inputSchema: {\n type: 'object',\n properties: {\n cwd: { type: 'string', description: 'Working directory (default: cwd)' },\n format: {\n type: 'string',\n enum: ['list', 'table'],\n description: 'Output format (default: list)',\n },\n include_deprecated: {\n type: 'boolean',\n description: 'Include deprecated packages (default: false)',\n },\n check: {\n type: 'string',\n description: 'Specific package(s) to check (comma-separated)',\n },\n },\n },\n async execute(input, ctx, opts) {\n const cwd = input.cwd ? safeResolve(input.cwd, ctx) : ctx.cwd;\n const manager = await detectManager(cwd);\n\n const args: string[] = ['outdated', '--json'];\n if (input.format === 'table') args.push('--table');\n if (input.include_deprecated) args.push('--include', 'deprecated');\n\n return runOutdated(manager, args, cwd, opts.signal);\n },\n};\n\nasync function detectManager(cwd: string): Promise<string> {\n const { stat } = require('node:fs/promises');\n try {\n await stat(`${cwd}/pnpm-lock.yaml`);\n return 'pnpm';\n } catch {\n /* */\n }\n try {\n await stat(`${cwd}/yarn.lock`);\n return 'yarn';\n } catch {\n /* */\n }\n return 'npm';\n}\n\nfunction runOutdated(\n manager: string,\n args: string[],\n cwd: string,\n signal: AbortSignal,\n): Promise<OutdatedOutput> {\n return new Promise((resolve) => {\n let stdout = '';\n let stderr = '';\n const MAX = 100_000;\n\n const child = spawn(manager, args, { cwd, signal, env: buildChildEnv(), stdio: ['ignore', 'pipe', 'pipe'] });\n child.stdout?.on('data', (c) => {\n if (stdout.length < MAX) stdout += c.toString();\n });\n child.stderr?.on('data', (c) => {\n if (stderr.length < MAX) stderr += c.toString();\n });\n child.on('close', (code) => {\n const result = parseOutdatedOutput(stdout, code ?? 0);\n resolve(result);\n });\n child.on('error', (e) =>\n resolve({\n exit_code: 1,\n packages: [],\n total: 0,\n output: e.message,\n truncated: false,\n }),\n );\n });\n}\n\nfunction parseOutdatedOutput(json: string, exitCode: number): OutdatedOutput {\n const packages: OutdatedPackage[] = [];\n\n if (!json) {\n return {\n exit_code: exitCode,\n packages: [],\n total: 0,\n output: exitCode === 0 ? 'All packages up to date' : 'Could not check outdated packages',\n truncated: false,\n };\n }\n\n try {\n const data = JSON.parse(json);\n for (const name of Object.keys(data)) {\n const info = data[name];\n packages.push({\n name,\n current: info.current ?? 'unknown',\n latest: info.latest ?? 'unknown',\n wanted: info.wanted ?? 'unknown',\n type: info.type ?? 'unknown',\n location: info.location ?? name,\n });\n }\n } catch {\n // JSON parse failed, return raw output\n }\n\n return {\n exit_code: exitCode,\n packages,\n total: packages.length,\n output: json,\n truncated: json.length >= 100_000,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/_util.ts","../src/outdated.ts"],"names":["resolve"],"mappings":"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","file":"outdated.js","sourcesContent":["import * as path from 'node:path';\nimport type { Context } from '@wrongstack/core';\n\nexport function resolvePath(input: string, ctx: Context): string {\n return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.cwd, input);\n}\n\nexport function ensureInsideRoot(absPath: string, ctx: Context): string {\n const root = path.resolve(ctx.projectRoot);\n const target = path.resolve(absPath);\n const rel = path.relative(root, target);\n if (rel.startsWith('..') || path.isAbsolute(rel)) {\n throw new Error(`Path \"${absPath}\" is outside project root \"${root}\"`);\n }\n return target;\n}\n\nexport function safeResolve(input: string, ctx: Context): string {\n return ensureInsideRoot(resolvePath(input, ctx), ctx);\n}\n\nexport function truncateMiddle(s: string, max: number): string {\n if (Buffer.byteLength(s, 'utf8') <= max) return s;\n const half = Math.floor(max / 2);\n return (\n s.slice(0, half) +\n `\\n…[truncated ${Buffer.byteLength(s, 'utf8') - max} bytes from middle]…\\n` +\n s.slice(-half)\n );\n}\n\nexport function isBinaryBuffer(buf: Buffer): boolean {\n const len = Math.min(buf.length, 8192);\n for (let i = 0; i < len; i++) {\n if (buf[i] === 0) return true;\n }\n return false;\n}\n","import { spawn } from 'node:child_process';\nimport { stat } from 'node:fs/promises';\nimport { buildChildEnv } from '@wrongstack/core';\nimport type { Tool } from '@wrongstack/core';\nimport { safeResolve } from './_util.js';\n\ninterface OutdatedInput {\n cwd?: string;\n format?: 'list' | 'table';\n include_deprecated?: boolean;\n check?: string | string[];\n}\n\ninterface OutdatedPackage {\n name: string;\n current: string;\n latest: string;\n wanted: string;\n type: string;\n location: string;\n}\n\ninterface OutdatedOutput {\n exit_code: number;\n packages: OutdatedPackage[];\n total: number;\n output: string;\n truncated: boolean;\n}\n\nexport const outdatedTool: Tool<OutdatedInput, OutdatedOutput> = {\n name: 'outdated',\n category: 'Package Management',\n description: 'Check for outdated npm packages. Shows current, wanted, and latest versions.',\n usageHint:\n 'Set `check` to filter specific packages. `format` as list or table. `include_deprecated` shows deprecated packages.',\n permission: 'auto',\n mutating: false,\n timeoutMs: 60_000,\n inputSchema: {\n type: 'object',\n properties: {\n cwd: { type: 'string', description: 'Working directory (default: cwd)' },\n format: {\n type: 'string',\n enum: ['list', 'table'],\n description: 'Output format (default: list)',\n },\n include_deprecated: {\n type: 'boolean',\n description: 'Include deprecated packages (default: false)',\n },\n check: {\n type: 'string',\n description: 'Specific package(s) to check (comma-separated)',\n },\n },\n },\n async execute(input, ctx, opts) {\n const cwd = input.cwd ? safeResolve(input.cwd, ctx) : ctx.cwd;\n const manager = await detectManager(cwd);\n\n const args: string[] = ['outdated', '--json'];\n if (input.format === 'table') args.push('--table');\n if (input.include_deprecated) args.push('--include', 'deprecated');\n\n return runOutdated(manager, args, cwd, opts.signal);\n },\n};\n\nasync function detectManager(cwd: string): Promise<string> {\n try {\n await stat(`${cwd}/pnpm-lock.yaml`);\n return 'pnpm';\n } catch {\n /* */\n }\n try {\n await stat(`${cwd}/yarn.lock`);\n return 'yarn';\n } catch {\n /* */\n }\n return 'npm';\n}\n\nfunction runOutdated(\n manager: string,\n args: string[],\n cwd: string,\n signal: AbortSignal,\n): Promise<OutdatedOutput> {\n return new Promise((resolve) => {\n let stdout = '';\n let stderr = '';\n const MAX = 100_000;\n\n const child = spawn(manager, args, { cwd, signal, env: buildChildEnv(), stdio: ['ignore', 'pipe', 'pipe'] });\n child.stdout?.on('data', (c) => {\n if (stdout.length < MAX) stdout += c.toString();\n });\n child.stderr?.on('data', (c) => {\n if (stderr.length < MAX) stderr += c.toString();\n });\n child.on('close', (code) => {\n const result = parseOutdatedOutput(stdout, code ?? 0);\n resolve(result);\n });\n child.on('error', (e) =>\n resolve({\n exit_code: 1,\n packages: [],\n total: 0,\n output: e.message,\n truncated: false,\n }),\n );\n });\n}\n\nfunction parseOutdatedOutput(json: string, exitCode: number): OutdatedOutput {\n const packages: OutdatedPackage[] = [];\n\n if (!json) {\n return {\n exit_code: exitCode,\n packages: [],\n total: 0,\n output: exitCode === 0 ? 'All packages up to date' : 'Could not check outdated packages',\n truncated: false,\n };\n }\n\n try {\n const data = JSON.parse(json);\n for (const name of Object.keys(data)) {\n const info = data[name];\n packages.push({\n name,\n current: info.current ?? 'unknown',\n latest: info.latest ?? 'unknown',\n wanted: info.wanted ?? 'unknown',\n type: info.type ?? 'unknown',\n location: info.location ?? name,\n });\n }\n } catch {\n // JSON parse failed, return raw output\n }\n\n return {\n exit_code: exitCode,\n packages,\n total: packages.length,\n output: json,\n truncated: json.length >= 100_000,\n };\n}\n"]}
package/dist/pack.js CHANGED
@@ -5,15 +5,11 @@ import { dirname } from 'path';
5
5
  import * as os from 'os';
6
6
  import { statSync } from 'fs';
7
7
  import * as fs9 from 'fs/promises';
8
+ import { stat } from 'fs/promises';
8
9
  import * as dns from 'dns/promises';
9
10
  import * as net from 'net';
10
11
 
11
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
12
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
13
- }) : x)(function(x) {
14
- if (typeof require !== "undefined") return require.apply(this, arguments);
15
- throw Error('Dynamic require of "' + x + '" is not supported');
16
- });
12
+ // src/_spawn-stream.ts
17
13
  async function* spawnStream(opts) {
18
14
  const max = opts.maxBytes ?? 2e5;
19
15
  const flushAt = opts.flushBytes ?? 4 * 1024;
@@ -173,14 +169,14 @@ var auditTool = {
173
169
  }
174
170
  };
175
171
  async function detectManager(cwd) {
176
- const { stat: stat9 } = await import('fs/promises');
172
+ const { stat: stat10 } = await import('fs/promises');
177
173
  try {
178
- await stat9(`${cwd}/pnpm-lock.yaml`);
174
+ await stat10(`${cwd}/pnpm-lock.yaml`);
179
175
  return "pnpm";
180
176
  } catch {
181
177
  }
182
178
  try {
183
- await stat9(`${cwd}/yarn.lock`);
179
+ await stat10(`${cwd}/yarn.lock`);
184
180
  return "yarn";
185
181
  } catch {
186
182
  }
@@ -966,8 +962,8 @@ function findGitDir(cwd) {
966
962
  let dir = cwd;
967
963
  for (let i = 0; i < 20; i++) {
968
964
  try {
969
- const stat9 = statSync(path.join(dir, ".git"));
970
- if (stat9.isDirectory()) return dir;
965
+ const stat10 = statSync(path.join(dir, ".git"));
966
+ if (stat10.isDirectory()) return dir;
971
967
  } catch {
972
968
  }
973
969
  const parent = path.dirname(dir);
@@ -1006,8 +1002,8 @@ async function fileDiff(input, ctx, signal) {
1006
1002
  const results = [];
1007
1003
  for (const file of files) {
1008
1004
  const absPath = safeResolve(file, ctx);
1009
- const stat9 = await fs9.stat(absPath).catch(() => null);
1010
- if (!stat9?.isFile()) continue;
1005
+ const stat10 = await fs9.stat(absPath).catch(() => null);
1006
+ if (!stat10?.isFile()) continue;
1011
1007
  const content = await fs9.readFile(absPath, "utf8");
1012
1008
  const lines = content.split(/\r?\n/);
1013
1009
  results.push(`--- ${file}
@@ -1105,8 +1101,8 @@ async function resolveFiles(filesInput, cwd) {
1105
1101
  for (const f of files) {
1106
1102
  const absPath = f.trim().startsWith("/") ? f.trim() : `${cwd}/${f.trim()}`;
1107
1103
  try {
1108
- const stat9 = await fs9.stat(absPath);
1109
- if (stat9.isFile()) resolved.push(absPath);
1104
+ const stat10 = await fs9.stat(absPath);
1105
+ if (stat10.isFile()) resolved.push(absPath);
1110
1106
  } catch {
1111
1107
  }
1112
1108
  }
@@ -1197,13 +1193,13 @@ var editTool = {
1197
1193
  if (input.new_string === void 0) throw new Error("edit: new_string is required");
1198
1194
  if (input.old_string === "") throw new Error("edit: old_string cannot be empty");
1199
1195
  const absPath = safeResolve(input.path, ctx);
1200
- const stat9 = await fs9.stat(absPath).catch((err) => {
1196
+ const stat10 = await fs9.stat(absPath).catch((err) => {
1201
1197
  if (err.code === "ENOENT") {
1202
1198
  throw new Error(`edit: file "${input.path}" does not exist. Use \`write\` instead.`);
1203
1199
  }
1204
1200
  throw err;
1205
1201
  });
1206
- if (!stat9.isFile()) throw new Error(`edit: "${input.path}" is not a regular file`);
1202
+ if (!stat10.isFile()) throw new Error(`edit: "${input.path}" is not a regular file`);
1207
1203
  if (!ctx.hasRead(absPath)) {
1208
1204
  throw new Error(`edit: file "${input.path}" was not read in this session. Read it first.`);
1209
1205
  }
@@ -1895,13 +1891,13 @@ var formatTool = {
1895
1891
  }
1896
1892
  };
1897
1893
  async function detectFixer(cwd) {
1898
- const { stat: stat9 } = await import('fs/promises');
1894
+ const { stat: stat10 } = await import('fs/promises');
1899
1895
  try {
1900
- await stat9(`${cwd}/biome.json`);
1896
+ await stat10(`${cwd}/biome.json`);
1901
1897
  return "biome";
1902
1898
  } catch {
1903
1899
  try {
1904
- await stat9(`${cwd}/.prettierrc`);
1900
+ await stat10(`${cwd}/.prettierrc`);
1905
1901
  return "prettier";
1906
1902
  } catch {
1907
1903
  return "biome";
@@ -1978,8 +1974,8 @@ function findGitDir2(cwd, projectRoot) {
1978
1974
  let dir = cwd;
1979
1975
  for (let i = 0; i < 20; i++) {
1980
1976
  try {
1981
- const stat9 = statSync(`${dir}/.git`);
1982
- if (stat9.isDirectory()) return dir;
1977
+ const stat10 = statSync(`${dir}/.git`);
1978
+ if (stat10.isDirectory()) return dir;
1983
1979
  } catch {
1984
1980
  }
1985
1981
  if (dir === root) break;
@@ -2418,8 +2414,8 @@ async function runNative(input, base, mode, limit, signal) {
2418
2414
  if (globRe && !globRe.test(e.name) && !globRe.test(full)) continue;
2419
2415
  if (globRe) globRe.lastIndex = 0;
2420
2416
  try {
2421
- const stat9 = await fs9.stat(full);
2422
- if (stat9.size > 1e6) continue;
2417
+ const stat10 = await fs9.stat(full);
2418
+ if (stat10.size > 1e6) continue;
2423
2419
  const head = await fs9.readFile(full);
2424
2420
  if (isBinaryBuffer(head)) continue;
2425
2421
  const text = head.toString("utf8");
@@ -2558,13 +2554,13 @@ var installTool = {
2558
2554
  }
2559
2555
  };
2560
2556
  async function detectPackageManager(cwd) {
2561
- const { stat: stat9 } = await import('fs/promises');
2557
+ const { stat: stat10 } = await import('fs/promises');
2562
2558
  try {
2563
- await stat9(`${cwd}/pnpm-lock.yaml`);
2559
+ await stat10(`${cwd}/pnpm-lock.yaml`);
2564
2560
  return "pnpm";
2565
2561
  } catch {
2566
2562
  try {
2567
- await stat9(`${cwd}/yarn.lock`);
2563
+ await stat10(`${cwd}/yarn.lock`);
2568
2564
  return "yarn";
2569
2565
  } catch {
2570
2566
  return "npm";
@@ -2771,11 +2767,11 @@ var lintTool = {
2771
2767
  }
2772
2768
  };
2773
2769
  async function detectLinter(cwd) {
2774
- const { stat: stat9 } = await import('fs/promises');
2770
+ const { stat: stat10 } = await import('fs/promises');
2775
2771
  const checks = ["biome.json", ".eslintrc.json", "tslint.json", ".eslintrc.js", "tsconfig.json"];
2776
2772
  for (const f of checks) {
2777
2773
  try {
2778
- await stat9(`${cwd}/${f}`);
2774
+ await stat10(`${cwd}/${f}`);
2779
2775
  if (f.includes("biome")) return "biome";
2780
2776
  if (f.includes("eslint")) return "eslint";
2781
2777
  if (f.includes("tslint")) return "tslint";
@@ -3008,14 +3004,13 @@ var outdatedTool = {
3008
3004
  }
3009
3005
  };
3010
3006
  async function detectManager2(cwd) {
3011
- const { stat: stat9 } = __require("fs/promises");
3012
3007
  try {
3013
- await stat9(`${cwd}/pnpm-lock.yaml`);
3008
+ await stat(`${cwd}/pnpm-lock.yaml`);
3014
3009
  return "pnpm";
3015
3010
  } catch {
3016
3011
  }
3017
3012
  try {
3018
- await stat9(`${cwd}/yarn.lock`);
3013
+ await stat(`${cwd}/yarn.lock`);
3019
3014
  return "yarn";
3020
3015
  } catch {
3021
3016
  }
@@ -3351,17 +3346,17 @@ var readTool = {
3351
3346
  async execute(input, ctx) {
3352
3347
  if (!input?.path) throw new Error("read: path is required");
3353
3348
  const absPath = safeResolve(input.path, ctx);
3354
- let stat9;
3349
+ let stat10;
3355
3350
  try {
3356
- stat9 = await fs9.stat(absPath);
3351
+ stat10 = await fs9.stat(absPath);
3357
3352
  } catch (err) {
3358
3353
  const code = err.code;
3359
3354
  if (code === "ENOENT") throw new Error(`read: file not found "${input.path}"`);
3360
3355
  throw new Error(`read: failed to stat "${input.path}": ${err instanceof Error ? err.message : String(err)}`);
3361
3356
  }
3362
- if (!stat9.isFile()) throw new Error(`read: "${input.path}" is not a regular file`);
3363
- if (stat9.size > MAX_BYTES2) {
3364
- throw new Error(`read: file too large (${stat9.size} bytes, limit ${MAX_BYTES2})`);
3357
+ if (!stat10.isFile()) throw new Error(`read: "${input.path}" is not a regular file`);
3358
+ if (stat10.size > MAX_BYTES2) {
3359
+ throw new Error(`read: file too large (${stat10.size} bytes, limit ${MAX_BYTES2})`);
3365
3360
  }
3366
3361
  const buf = await fs9.readFile(absPath);
3367
3362
  if (isBinaryBuffer(buf)) {
@@ -3373,14 +3368,14 @@ var readTool = {
3373
3368
  const offset = Math.max(1, input.offset ?? 1);
3374
3369
  const limit = Math.max(0, Math.min(input.limit ?? 2e3, 5e3));
3375
3370
  if (limit === 0) {
3376
- ctx.recordRead(absPath, stat9.mtimeMs);
3371
+ ctx.recordRead(absPath, stat10.mtimeMs);
3377
3372
  return { text: "", total_lines: total, encoding: "utf8", truncated: total > 0 };
3378
3373
  }
3379
3374
  const slice = allLines.slice(offset - 1, offset - 1 + limit);
3380
3375
  const truncated = offset - 1 + slice.length < total;
3381
3376
  const width = String(offset + slice.length - 1).length;
3382
3377
  const numbered = slice.map((line, i) => `${String(offset + i).padStart(width, " ")}\u2192${line}`).join("\n");
3383
- ctx.recordRead(absPath, stat9.mtimeMs);
3378
+ ctx.recordRead(absPath, stat10.mtimeMs);
3384
3379
  return {
3385
3380
  text: numbered,
3386
3381
  total_lines: total,
@@ -3447,8 +3442,8 @@ var replaceTool = {
3447
3442
  }
3448
3443
  const rel = path.relative(ctx.projectRoot, realPath);
3449
3444
  if (rel.startsWith("..") || path.isAbsolute(rel)) continue;
3450
- const stat9 = await fs9.stat(realPath).catch(() => null);
3451
- if (!stat9 || !stat9.isFile()) continue;
3445
+ const stat10 = await fs9.stat(realPath).catch(() => null);
3446
+ if (!stat10 || !stat10.isFile()) continue;
3452
3447
  let content;
3453
3448
  try {
3454
3449
  const buf = await fs9.readFile(realPath);
@@ -3473,7 +3468,7 @@ var replaceTool = {
3473
3468
  totalReplacements += count;
3474
3469
  if (!dryRun) {
3475
3470
  const newContent = toStyle(newContentLf, style);
3476
- await atomicWrite(realPath, newContent, { mode: stat9.mode & 511 });
3471
+ await atomicWrite(realPath, newContent, { mode: stat10.mode & 511 });
3477
3472
  }
3478
3473
  const diff = dryRun || matches.length > 0 ? unifiedDiff(content, toStyle(newContentLf, style), {
3479
3474
  fromFile: absPath,
@@ -3503,8 +3498,8 @@ async function resolveFiles2(filesInput, ctx, extraGlob) {
3503
3498
  const resolved = [];
3504
3499
  for (const p of parts) {
3505
3500
  const absPath = safeResolve(p, ctx);
3506
- const stat9 = await fs9.stat(absPath).catch(() => null);
3507
- if (stat9?.isFile()) {
3501
+ const stat10 = await fs9.stat(absPath).catch(() => null);
3502
+ if (stat10?.isFile()) {
3508
3503
  resolved.push(absPath);
3509
3504
  }
3510
3505
  }
@@ -3563,8 +3558,8 @@ async function globNative(pattern, base, extraGlob) {
3563
3558
  if (DEFAULT_IGNORE3.includes(e.name)) continue;
3564
3559
  const full = path.join(dir, e.name);
3565
3560
  try {
3566
- const stat9 = await fs9.lstat(full);
3567
- if (stat9.isSymbolicLink()) continue;
3561
+ const stat10 = await fs9.lstat(full);
3562
+ if (stat10.isSymbolicLink()) continue;
3568
3563
  } catch {
3569
3564
  continue;
3570
3565
  }
@@ -4050,11 +4045,11 @@ var testTool = {
4050
4045
  }
4051
4046
  };
4052
4047
  async function detectRunner(cwd) {
4053
- const { stat: stat9 } = await import('fs/promises');
4048
+ const { stat: stat10 } = await import('fs/promises');
4054
4049
  const candidates = ["vitest.config.ts", "jest.config.js", ".mocharc.json"];
4055
4050
  for (const f of candidates) {
4056
4051
  try {
4057
- await stat9(path.join(cwd, f));
4052
+ await stat10(path.join(cwd, f));
4058
4053
  if (f.includes("vitest")) return "vitest";
4059
4054
  if (f.includes("jest")) return "jest";
4060
4055
  if (f.includes("mocha")) return "mocha";
@@ -4673,11 +4668,11 @@ var typecheckTool = {
4673
4668
  }
4674
4669
  };
4675
4670
  async function findTsConfig(cwd) {
4676
- const { stat: stat9 } = await import('fs/promises');
4671
+ const { stat: stat10 } = await import('fs/promises');
4677
4672
  const candidates = ["tsconfig.json", "tsconfig.base.json"];
4678
4673
  for (const f of candidates) {
4679
4674
  try {
4680
- const s = await stat9(path.join(cwd, f));
4675
+ const s = await stat10(path.join(cwd, f));
4681
4676
  if (s.isFile()) return path.join(cwd, f);
4682
4677
  } catch {
4683
4678
  }
@@ -4707,12 +4702,12 @@ var writeTool = {
4707
4702
  let existed = false;
4708
4703
  let prev = "";
4709
4704
  try {
4710
- const stat10 = await fs9.stat(absPath);
4711
- existed = stat10.isFile();
4705
+ const stat11 = await fs9.stat(absPath);
4706
+ existed = stat11.isFile();
4712
4707
  if (existed) {
4713
4708
  if (!ctx.hasRead(absPath)) {
4714
4709
  prev = await fs9.readFile(absPath, "utf8");
4715
- ctx.recordRead(absPath, stat10.mtimeMs);
4710
+ ctx.recordRead(absPath, stat11.mtimeMs);
4716
4711
  } else {
4717
4712
  prev = await fs9.readFile(absPath, "utf8");
4718
4713
  }
@@ -4725,8 +4720,8 @@ var writeTool = {
4725
4720
  await atomicWrite(absPath, input.content);
4726
4721
  const diff = existed ? unifiedDiff(prev, input.content, { fromFile: input.path, toFile: input.path }) : `+++ ${input.path}
4727
4722
  + (new file, ${input.content.split("\n").length} lines)`;
4728
- const stat9 = await fs9.stat(absPath);
4729
- ctx.recordRead(absPath, stat9.mtimeMs);
4723
+ const stat10 = await fs9.stat(absPath);
4724
+ ctx.recordRead(absPath, stat10.mtimeMs);
4730
4725
  ctx.session.recordFileChange({
4731
4726
  path: absPath,
4732
4727
  action: existed ? "modified" : "created",