@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/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as fs4 from 'fs/promises';
2
+ import { stat } from 'fs/promises';
2
3
  import * as path from 'path';
3
4
  import { dirname } from 'path';
4
5
  import { atomicWrite, unifiedDiff, detectNewlineStyle, normalizeToLf, toStyle, compileGlob, buildChildEnv, stripAnsi, loadPlan, emptyPlan, clearPlan, savePlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, formatPlan } from '@wrongstack/core';
@@ -8,12 +9,7 @@ import * as dns from 'dns/promises';
8
9
  import * as net from 'net';
9
10
  import { statSync } from 'fs';
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/read.ts
17
13
  function resolvePath(input, ctx) {
18
14
  return path.isAbsolute(input) ? path.normalize(input) : path.resolve(ctx.cwd, input);
19
15
  }
@@ -67,17 +63,17 @@ var readTool = {
67
63
  async execute(input, ctx) {
68
64
  if (!input?.path) throw new Error("read: path is required");
69
65
  const absPath = safeResolve(input.path, ctx);
70
- let stat9;
66
+ let stat10;
71
67
  try {
72
- stat9 = await fs4.stat(absPath);
68
+ stat10 = await fs4.stat(absPath);
73
69
  } catch (err) {
74
70
  const code = err.code;
75
71
  if (code === "ENOENT") throw new Error(`read: file not found "${input.path}"`);
76
72
  throw new Error(`read: failed to stat "${input.path}": ${err instanceof Error ? err.message : String(err)}`);
77
73
  }
78
- if (!stat9.isFile()) throw new Error(`read: "${input.path}" is not a regular file`);
79
- if (stat9.size > MAX_BYTES) {
80
- throw new Error(`read: file too large (${stat9.size} bytes, limit ${MAX_BYTES})`);
74
+ if (!stat10.isFile()) throw new Error(`read: "${input.path}" is not a regular file`);
75
+ if (stat10.size > MAX_BYTES) {
76
+ throw new Error(`read: file too large (${stat10.size} bytes, limit ${MAX_BYTES})`);
81
77
  }
82
78
  const buf = await fs4.readFile(absPath);
83
79
  if (isBinaryBuffer(buf)) {
@@ -89,14 +85,14 @@ var readTool = {
89
85
  const offset = Math.max(1, input.offset ?? 1);
90
86
  const limit = Math.max(0, Math.min(input.limit ?? 2e3, 5e3));
91
87
  if (limit === 0) {
92
- ctx.recordRead(absPath, stat9.mtimeMs);
88
+ ctx.recordRead(absPath, stat10.mtimeMs);
93
89
  return { text: "", total_lines: total, encoding: "utf8", truncated: total > 0 };
94
90
  }
95
91
  const slice = allLines.slice(offset - 1, offset - 1 + limit);
96
92
  const truncated = offset - 1 + slice.length < total;
97
93
  const width = String(offset + slice.length - 1).length;
98
94
  const numbered = slice.map((line, i) => `${String(offset + i).padStart(width, " ")}\u2192${line}`).join("\n");
99
- ctx.recordRead(absPath, stat9.mtimeMs);
95
+ ctx.recordRead(absPath, stat10.mtimeMs);
100
96
  return {
101
97
  text: numbered,
102
98
  total_lines: total,
@@ -128,12 +124,12 @@ var writeTool = {
128
124
  let existed = false;
129
125
  let prev = "";
130
126
  try {
131
- const stat10 = await fs4.stat(absPath);
132
- existed = stat10.isFile();
127
+ const stat11 = await fs4.stat(absPath);
128
+ existed = stat11.isFile();
133
129
  if (existed) {
134
130
  if (!ctx.hasRead(absPath)) {
135
131
  prev = await fs4.readFile(absPath, "utf8");
136
- ctx.recordRead(absPath, stat10.mtimeMs);
132
+ ctx.recordRead(absPath, stat11.mtimeMs);
137
133
  } else {
138
134
  prev = await fs4.readFile(absPath, "utf8");
139
135
  }
@@ -146,8 +142,8 @@ var writeTool = {
146
142
  await atomicWrite(absPath, input.content);
147
143
  const diff = existed ? unifiedDiff(prev, input.content, { fromFile: input.path, toFile: input.path }) : `+++ ${input.path}
148
144
  + (new file, ${input.content.split("\n").length} lines)`;
149
- const stat9 = await fs4.stat(absPath);
150
- ctx.recordRead(absPath, stat9.mtimeMs);
145
+ const stat10 = await fs4.stat(absPath);
146
+ ctx.recordRead(absPath, stat10.mtimeMs);
151
147
  ctx.session.recordFileChange({
152
148
  path: absPath,
153
149
  action: existed ? "modified" : "created",
@@ -186,13 +182,13 @@ var editTool = {
186
182
  if (input.new_string === void 0) throw new Error("edit: new_string is required");
187
183
  if (input.old_string === "") throw new Error("edit: old_string cannot be empty");
188
184
  const absPath = safeResolve(input.path, ctx);
189
- const stat9 = await fs4.stat(absPath).catch((err) => {
185
+ const stat10 = await fs4.stat(absPath).catch((err) => {
190
186
  if (err.code === "ENOENT") {
191
187
  throw new Error(`edit: file "${input.path}" does not exist. Use \`write\` instead.`);
192
188
  }
193
189
  throw err;
194
190
  });
195
- if (!stat9.isFile()) throw new Error(`edit: "${input.path}" is not a regular file`);
191
+ if (!stat10.isFile()) throw new Error(`edit: "${input.path}" is not a regular file`);
196
192
  if (!ctx.hasRead(absPath)) {
197
193
  throw new Error(`edit: file "${input.path}" was not read in this session. Read it first.`);
198
194
  }
@@ -384,8 +380,8 @@ var replaceTool = {
384
380
  }
385
381
  const rel = path.relative(ctx.projectRoot, realPath);
386
382
  if (rel.startsWith("..") || path.isAbsolute(rel)) continue;
387
- const stat9 = await fs4.stat(realPath).catch(() => null);
388
- if (!stat9 || !stat9.isFile()) continue;
383
+ const stat10 = await fs4.stat(realPath).catch(() => null);
384
+ if (!stat10 || !stat10.isFile()) continue;
389
385
  let content;
390
386
  try {
391
387
  const buf = await fs4.readFile(realPath);
@@ -410,7 +406,7 @@ var replaceTool = {
410
406
  totalReplacements += count;
411
407
  if (!dryRun) {
412
408
  const newContent = toStyle(newContentLf, style);
413
- await atomicWrite(realPath, newContent, { mode: stat9.mode & 511 });
409
+ await atomicWrite(realPath, newContent, { mode: stat10.mode & 511 });
414
410
  }
415
411
  const diff = dryRun || matches.length > 0 ? unifiedDiff(content, toStyle(newContentLf, style), {
416
412
  fromFile: absPath,
@@ -440,8 +436,8 @@ async function resolveFiles(filesInput, ctx, extraGlob) {
440
436
  const resolved = [];
441
437
  for (const p of parts) {
442
438
  const absPath = safeResolve(p, ctx);
443
- const stat9 = await fs4.stat(absPath).catch(() => null);
444
- if (stat9?.isFile()) {
439
+ const stat10 = await fs4.stat(absPath).catch(() => null);
440
+ if (stat10?.isFile()) {
445
441
  resolved.push(absPath);
446
442
  }
447
443
  }
@@ -500,8 +496,8 @@ async function globNative(pattern, base, extraGlob) {
500
496
  if (DEFAULT_IGNORE.includes(e.name)) continue;
501
497
  const full = path.join(dir, e.name);
502
498
  try {
503
- const stat9 = await fs4.lstat(full);
504
- if (stat9.isSymbolicLink()) continue;
499
+ const stat10 = await fs4.lstat(full);
500
+ if (stat10.isSymbolicLink()) continue;
505
501
  } catch {
506
502
  continue;
507
503
  }
@@ -817,8 +813,8 @@ async function runNative(input, base, mode, limit, signal) {
817
813
  if (globRe && !globRe.test(e.name) && !globRe.test(full)) continue;
818
814
  if (globRe) globRe.lastIndex = 0;
819
815
  try {
820
- const stat9 = await fs4.stat(full);
821
- if (stat9.size > 1e6) continue;
816
+ const stat10 = await fs4.stat(full);
817
+ if (stat10.size > 1e6) continue;
822
818
  const head = await fs4.readFile(full);
823
819
  if (isBinaryBuffer(head)) continue;
824
820
  const text = head.toString("utf8");
@@ -2424,8 +2420,8 @@ function findGitDir(cwd, projectRoot) {
2424
2420
  let dir = cwd;
2425
2421
  for (let i = 0; i < 20; i++) {
2426
2422
  try {
2427
- const stat9 = statSync(`${dir}/.git`);
2428
- if (stat9.isDirectory()) return dir;
2423
+ const stat10 = statSync(`${dir}/.git`);
2424
+ if (stat10.isDirectory()) return dir;
2429
2425
  } catch {
2430
2426
  }
2431
2427
  if (dir === root) break;
@@ -2810,8 +2806,8 @@ function findGitDir2(cwd) {
2810
2806
  let dir = cwd;
2811
2807
  for (let i = 0; i < 20; i++) {
2812
2808
  try {
2813
- const stat9 = statSync(path.join(dir, ".git"));
2814
- if (stat9.isDirectory()) return dir;
2809
+ const stat10 = statSync(path.join(dir, ".git"));
2810
+ if (stat10.isDirectory()) return dir;
2815
2811
  } catch {
2816
2812
  }
2817
2813
  const parent = path.dirname(dir);
@@ -2850,8 +2846,8 @@ async function fileDiff(input, ctx, signal) {
2850
2846
  const results = [];
2851
2847
  for (const file of files) {
2852
2848
  const absPath = safeResolve(file, ctx);
2853
- const stat9 = await fs4.stat(absPath).catch(() => null);
2854
- if (!stat9?.isFile()) continue;
2849
+ const stat10 = await fs4.stat(absPath).catch(() => null);
2850
+ if (!stat10?.isFile()) continue;
2855
2851
  const content = await fs4.readFile(absPath, "utf8");
2856
2852
  const lines = content.split(/\r?\n/);
2857
2853
  results.push(`--- ${file}
@@ -3193,11 +3189,11 @@ var lintTool = {
3193
3189
  }
3194
3190
  };
3195
3191
  async function detectLinter(cwd) {
3196
- const { stat: stat9 } = await import('fs/promises');
3192
+ const { stat: stat10 } = await import('fs/promises');
3197
3193
  const checks = ["biome.json", ".eslintrc.json", "tslint.json", ".eslintrc.js", "tsconfig.json"];
3198
3194
  for (const f of checks) {
3199
3195
  try {
3200
- await stat9(`${cwd}/${f}`);
3196
+ await stat10(`${cwd}/${f}`);
3201
3197
  if (f.includes("biome")) return "biome";
3202
3198
  if (f.includes("eslint")) return "eslint";
3203
3199
  if (f.includes("tslint")) return "tslint";
@@ -3292,13 +3288,13 @@ var formatTool = {
3292
3288
  }
3293
3289
  };
3294
3290
  async function detectFixer(cwd) {
3295
- const { stat: stat9 } = await import('fs/promises');
3291
+ const { stat: stat10 } = await import('fs/promises');
3296
3292
  try {
3297
- await stat9(`${cwd}/biome.json`);
3293
+ await stat10(`${cwd}/biome.json`);
3298
3294
  return "biome";
3299
3295
  } catch {
3300
3296
  try {
3301
- await stat9(`${cwd}/.prettierrc`);
3297
+ await stat10(`${cwd}/.prettierrc`);
3302
3298
  return "prettier";
3303
3299
  } catch {
3304
3300
  return "biome";
@@ -3374,11 +3370,11 @@ var typecheckTool = {
3374
3370
  }
3375
3371
  };
3376
3372
  async function findTsConfig(cwd) {
3377
- const { stat: stat9 } = await import('fs/promises');
3373
+ const { stat: stat10 } = await import('fs/promises');
3378
3374
  const candidates = ["tsconfig.json", "tsconfig.base.json"];
3379
3375
  for (const f of candidates) {
3380
3376
  try {
3381
- const s = await stat9(path.join(cwd, f));
3377
+ const s = await stat10(path.join(cwd, f));
3382
3378
  if (s.isFile()) return path.join(cwd, f);
3383
3379
  } catch {
3384
3380
  }
@@ -3455,11 +3451,11 @@ var testTool = {
3455
3451
  }
3456
3452
  };
3457
3453
  async function detectRunner(cwd) {
3458
- const { stat: stat9 } = await import('fs/promises');
3454
+ const { stat: stat10 } = await import('fs/promises');
3459
3455
  const candidates = ["vitest.config.ts", "jest.config.js", ".mocharc.json"];
3460
3456
  for (const f of candidates) {
3461
3457
  try {
3462
- await stat9(path.join(cwd, f));
3458
+ await stat10(path.join(cwd, f));
3463
3459
  if (f.includes("vitest")) return "vitest";
3464
3460
  if (f.includes("jest")) return "jest";
3465
3461
  if (f.includes("mocha")) return "mocha";
@@ -3630,13 +3626,13 @@ var installTool = {
3630
3626
  }
3631
3627
  };
3632
3628
  async function detectPackageManager(cwd) {
3633
- const { stat: stat9 } = await import('fs/promises');
3629
+ const { stat: stat10 } = await import('fs/promises');
3634
3630
  try {
3635
- await stat9(`${cwd}/pnpm-lock.yaml`);
3631
+ await stat10(`${cwd}/pnpm-lock.yaml`);
3636
3632
  return "pnpm";
3637
3633
  } catch {
3638
3634
  try {
3639
- await stat9(`${cwd}/yarn.lock`);
3635
+ await stat10(`${cwd}/yarn.lock`);
3640
3636
  return "yarn";
3641
3637
  } catch {
3642
3638
  return "npm";
@@ -3695,14 +3691,14 @@ var auditTool = {
3695
3691
  }
3696
3692
  };
3697
3693
  async function detectManager(cwd) {
3698
- const { stat: stat9 } = await import('fs/promises');
3694
+ const { stat: stat10 } = await import('fs/promises');
3699
3695
  try {
3700
- await stat9(`${cwd}/pnpm-lock.yaml`);
3696
+ await stat10(`${cwd}/pnpm-lock.yaml`);
3701
3697
  return "pnpm";
3702
3698
  } catch {
3703
3699
  }
3704
3700
  try {
3705
- await stat9(`${cwd}/yarn.lock`);
3701
+ await stat10(`${cwd}/yarn.lock`);
3706
3702
  return "yarn";
3707
3703
  } catch {
3708
3704
  }
@@ -3790,14 +3786,13 @@ var outdatedTool = {
3790
3786
  }
3791
3787
  };
3792
3788
  async function detectManager2(cwd) {
3793
- const { stat: stat9 } = __require("fs/promises");
3794
3789
  try {
3795
- await stat9(`${cwd}/pnpm-lock.yaml`);
3790
+ await stat(`${cwd}/pnpm-lock.yaml`);
3796
3791
  return "pnpm";
3797
3792
  } catch {
3798
3793
  }
3799
3794
  try {
3800
- await stat9(`${cwd}/yarn.lock`);
3795
+ await stat(`${cwd}/yarn.lock`);
3801
3796
  return "yarn";
3802
3797
  } catch {
3803
3798
  }
@@ -4133,8 +4128,8 @@ async function resolveFiles2(filesInput, cwd) {
4133
4128
  for (const f of files) {
4134
4129
  const absPath = f.trim().startsWith("/") ? f.trim() : `${cwd}/${f.trim()}`;
4135
4130
  try {
4136
- const stat9 = await fs4.stat(absPath);
4137
- if (stat9.isFile()) resolved.push(absPath);
4131
+ const stat10 = await fs4.stat(absPath);
4132
+ if (stat10.isFile()) resolved.push(absPath);
4138
4133
  } catch {
4139
4134
  }
4140
4135
  }