@wrongstack/plugins 0.295.1 → 0.296.3

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.
Files changed (44) hide show
  1. package/dist/accessibility-auditor.js +12 -1
  2. package/dist/branch-guard.js +13 -2
  3. package/dist/commit-validator/index.d.ts.map +1 -1
  4. package/dist/commit-validator.js +18 -1
  5. package/dist/dead-code-detector/index.d.ts.map +1 -1
  6. package/dist/dead-code-detector.js +4 -1
  7. package/dist/diff-summary.js +12 -1
  8. package/dist/doc-sync-guard.js +12 -1
  9. package/dist/git-autocommit/index.d.ts +12 -0
  10. package/dist/git-autocommit/index.d.ts.map +1 -1
  11. package/dist/git-autocommit.js +58 -4
  12. package/dist/import-organizer.js +12 -1
  13. package/dist/index.js +149 -47
  14. package/dist/injection-shield/index.d.ts +16 -0
  15. package/dist/injection-shield/index.d.ts.map +1 -1
  16. package/dist/injection-shield.js +12 -4
  17. package/dist/lint-gate.js +12 -1
  18. package/dist/migration-planner.js +12 -1
  19. package/dist/pr-drafter/index.d.ts.map +1 -1
  20. package/dist/pr-drafter.js +20 -1
  21. package/dist/runtime/handles.d.ts +46 -0
  22. package/dist/runtime/handles.d.ts.map +1 -0
  23. package/dist/runtime/index.d.ts +1 -0
  24. package/dist/runtime/index.d.ts.map +1 -1
  25. package/dist/runtime.js +18 -0
  26. package/dist/secret-scanner/index.d.ts.map +1 -1
  27. package/dist/secret-scanner.js +19 -2
  28. package/dist/session-recap/index.d.ts.map +1 -1
  29. package/dist/session-recap.js +18 -1
  30. package/dist/smart-rename/index.d.ts +2 -0
  31. package/dist/smart-rename/index.d.ts.map +1 -1
  32. package/dist/smart-rename.js +16 -2
  33. package/dist/spec-linker/index.d.ts.map +1 -1
  34. package/dist/spec-linker.js +19 -2
  35. package/dist/template-engine/index.d.ts.map +1 -1
  36. package/dist/template-engine.js +15 -1
  37. package/dist/test-coverage-gate.js +12 -1
  38. package/dist/test-runner-gate.js +12 -1
  39. package/dist/todo-listener.js +12 -1
  40. package/dist/token-budget/index.d.ts.map +1 -1
  41. package/dist/token-budget.js +31 -19
  42. package/dist/type-gate/index.d.ts.map +1 -1
  43. package/dist/type-gate.js +12 -1
  44. package/package.json +3 -3
@@ -8,6 +8,17 @@ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
8
8
  // src/runtime/local-bin.ts
9
9
  import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
10
10
 
11
+ // src/runtime/handles.ts
12
+ function releaseHandle(off) {
13
+ if (off) {
14
+ try {
15
+ off();
16
+ } catch {
17
+ }
18
+ }
19
+ return null;
20
+ }
21
+
11
22
  // src/runtime/index.ts
12
23
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
13
24
  function hasLeadingDash(arg) {
@@ -285,7 +296,7 @@ var plugin = {
285
296
  state.findingCount = 0;
286
297
  state.hookInvocationCount = 0;
287
298
  state.lastResult = null;
288
- state.hookUnregister = null;
299
+ state.hookUnregister = releaseHandle(state.hookUnregister);
289
300
  const cfg = readConfig(api.config.extensions?.["accessibility-auditor"]);
290
301
  const hook = async (input) => {
291
302
  if (!cfg.enabled || !cfg.onWriteEdit) return;
@@ -98,6 +98,17 @@ var BoundedMap = class {
98
98
  }
99
99
  };
100
100
 
101
+ // src/runtime/handles.ts
102
+ function releaseHandle(off) {
103
+ if (off) {
104
+ try {
105
+ off();
106
+ } catch {
107
+ }
108
+ }
109
+ return null;
110
+ }
111
+
101
112
  // src/runtime/index.ts
102
113
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
103
114
 
@@ -263,8 +274,8 @@ var plugin = {
263
274
  state.invocationCount = 0;
264
275
  state.blockCount = 0;
265
276
  state.warnCount = 0;
266
- state.hookUnregister = null;
267
- state.configUnregister = null;
277
+ state.hookUnregister = releaseHandle(state.hookUnregister);
278
+ state.configUnregister = releaseHandle(state.configUnregister);
268
279
  state.lastBlock = null;
269
280
  branchCache.clear();
270
281
  let cfg = readHostConfig(api.config);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commit-validator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAiRrD,QAAA,MAAM,MAAM,EAAE,MAgSb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commit-validator/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAkRrD,QAAA,MAAM,MAAM,EAAE,MAgSb,CAAC;eAEa,MAAM"}
@@ -1,3 +1,20 @@
1
+ // src/runtime/local-bin.ts
2
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
3
+
4
+ // src/runtime/handles.ts
5
+ function releaseHandle(off) {
6
+ if (off) {
7
+ try {
8
+ off();
9
+ } catch {
10
+ }
11
+ }
12
+ return null;
13
+ }
14
+
15
+ // src/runtime/index.ts
16
+ var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
17
+
1
18
  // src/commit-validator/index.ts
2
19
  var API_VERSION = "^0.1.10";
3
20
  var state = {
@@ -192,7 +209,7 @@ var plugin = {
192
209
  state.invalidCount = 0;
193
210
  state.suggestFixCount = 0;
194
211
  state.suggestFixErrors = 0;
195
- state.hookUnregister = null;
212
+ state.hookUnregister = releaseHandle(state.hookUnregister);
196
213
  state.lastValidation = null;
197
214
  const cfg = readConfig(api.config.extensions?.["commit-validator"]);
198
215
  const hook = async (input) => {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dead-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAiSrD,QAAA,MAAM,MAAM,EAAE,MAkOb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dead-code-detector/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAySrD,QAAA,MAAM,MAAM,EAAE,MAkOb,CAAC;eAEa,MAAM"}
@@ -133,7 +133,10 @@ function findUnusedSymbols(files) {
133
133
  for (const file of files) {
134
134
  const fileExports = extractExports(file.content, file.path);
135
135
  for (const exp of fileExports) {
136
- const pattern = new RegExp(`\\b${escapeRegex(exp.identifier)}\\b`, "g");
136
+ const pattern = new RegExp(
137
+ `(?<![A-Za-z0-9_$])${escapeRegex(exp.identifier)}(?![A-Za-z0-9_$])`,
138
+ "g"
139
+ );
137
140
  let usedElsewhere = false;
138
141
  for (const other of files) {
139
142
  if (other.path === file.path) continue;
@@ -101,6 +101,17 @@ var BoundedMap = class {
101
101
  }
102
102
  };
103
103
 
104
+ // src/runtime/handles.ts
105
+ function releaseHandle(off) {
106
+ if (off) {
107
+ try {
108
+ off();
109
+ } catch {
110
+ }
111
+ }
112
+ return null;
113
+ }
114
+
104
115
  // src/runtime/index.ts
105
116
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
106
117
  function hasLeadingDash(arg) {
@@ -278,7 +289,7 @@ var plugin = {
278
289
  state.fallbackCount = 0;
279
290
  state.throttledCount = 0;
280
291
  state.duplicateContentCount = 0;
281
- state.hookUnregister = null;
292
+ state.hookUnregister = releaseHandle(state.hookUnregister);
282
293
  state.lastSummary = null;
283
294
  pathMemo.clear();
284
295
  const cfg = readConfig(api.config.extensions?.["diff-summary"]);
@@ -7,6 +7,17 @@ import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
7
  // src/runtime/local-bin.ts
8
8
  import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
9
9
 
10
+ // src/runtime/handles.ts
11
+ function releaseHandle(off) {
12
+ if (off) {
13
+ try {
14
+ off();
15
+ } catch {
16
+ }
17
+ }
18
+ return null;
19
+ }
20
+
10
21
  // src/runtime/index.ts
11
22
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
12
23
  function hasLeadingDash(arg) {
@@ -143,7 +154,7 @@ var plugin = {
143
154
  state.sourceWrites = 0;
144
155
  state.docWrites = 0;
145
156
  state.warningsIssued = 0;
146
- state.hookUnregister = null;
157
+ state.hookUnregister = releaseHandle(state.hookUnregister);
147
158
  const cfg = readConfig(api.config.extensions?.["doc-sync-guard"]);
148
159
  const hook = (input) => {
149
160
  if (!cfg.enabled) return;
@@ -10,6 +10,18 @@
10
10
  * - For status: use the built-in `git` tool with `command: "status"` or `command: "diff"`.
11
11
  */
12
12
  import type { Plugin } from '@wrongstack/core/types';
13
+ /**
14
+ * Parse one `git status --porcelain` line into the path to stage.
15
+ *
16
+ * Two shapes the naive `line.slice(3)` got wrong:
17
+ * - **Renames/copies** print `R old -> new`. Slicing produced the literal
18
+ * string `"old -> new"`, which matches no file on disk, so the rename was
19
+ * dropped from the commit entirely. The path that must be staged is the
20
+ * NEW one.
21
+ * - **Quoted paths** (spaces, unicode, control chars) keep their quotes,
22
+ * likewise matching nothing.
23
+ */
24
+ export declare function parsePorcelainLine(line: string): string | null;
13
25
  declare const plugin: Plugin;
14
26
  export default plugin;
15
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/git-autocommit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAoTrD,QAAA,MAAM,MAAM,EAAE,MAsXb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/git-autocommit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA+IrD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW9D;AA2OD,QAAA,MAAM,MAAM,EAAE,MAsXb,CAAC;eAEa,MAAM"}
@@ -34,10 +34,63 @@ async function runGit(args, cwd, timeoutMs = DEFAULT_GIT_TIMEOUT_MS) {
34
34
  );
35
35
  });
36
36
  }
37
+ function unquotePorcelainPath(raw) {
38
+ if (!raw.startsWith('"') || !raw.endsWith('"') || raw.length < 2) return raw;
39
+ const inner = raw.slice(1, -1);
40
+ const bytes = [];
41
+ for (let i = 0; i < inner.length; i++) {
42
+ const ch = inner[i];
43
+ if (ch !== "\\") {
44
+ for (const b of Buffer.from(ch, "utf8")) bytes.push(b);
45
+ continue;
46
+ }
47
+ const next = inner[i + 1];
48
+ if (next === void 0) {
49
+ bytes.push(92);
50
+ break;
51
+ }
52
+ const simple = {
53
+ n: 10,
54
+ t: 9,
55
+ r: 13,
56
+ a: 7,
57
+ b: 8,
58
+ f: 12,
59
+ v: 11,
60
+ '"': 34,
61
+ "\\": 92
62
+ };
63
+ const mapped = simple[next];
64
+ if (mapped !== void 0) {
65
+ bytes.push(mapped);
66
+ i += 1;
67
+ continue;
68
+ }
69
+ const octal = /^[0-7]{1,3}/.exec(inner.slice(i + 1));
70
+ if (octal) {
71
+ bytes.push(Number.parseInt(octal[0], 8) & 255);
72
+ i += octal[0].length;
73
+ continue;
74
+ }
75
+ for (const b of Buffer.from(next, "utf8")) bytes.push(b);
76
+ i += 1;
77
+ }
78
+ return Buffer.from(bytes).toString("utf8");
79
+ }
80
+ function parsePorcelainLine(line) {
81
+ const body = line.slice(3);
82
+ if (!body) return null;
83
+ const status = line.slice(0, 2);
84
+ if (status.includes("R") || status.includes("C")) {
85
+ const arrow = body.lastIndexOf(" -> ");
86
+ if (arrow !== -1) return unquotePorcelainPath(body.slice(arrow + 4).trim());
87
+ }
88
+ return unquotePorcelainPath(body.trim());
89
+ }
37
90
  async function getChangedFiles(cwd) {
38
91
  const output = await runGit(["status", "--porcelain"], cwd);
39
92
  if (!output) return [];
40
- return output.split("\n").filter((l) => l.trim()).map((l) => l.slice(3).trim());
93
+ return output.split("\n").filter((l) => l.trim()).map((l) => parsePorcelainLine(l)).filter((p) => p !== null && p.length > 0);
41
94
  }
42
95
  async function getStagedFiles(cwd) {
43
96
  const output = await runGit(["diff", "--cached", "--name-only"], cwd);
@@ -53,7 +106,7 @@ async function stageFiles(files, cwd) {
53
106
  }
54
107
  });
55
108
  if (existing.length === 0) throw new Error("No files exist to stage");
56
- await runGit(["add", ...existing], cwd);
109
+ await runGit(["add", "--", ...existing], cwd);
57
110
  }
58
111
  async function commitWithMessage(message, cwd) {
59
112
  return await runGit(["commit", "-m", message], cwd, GIT_COMMIT_TIMEOUT_MS);
@@ -106,7 +159,7 @@ async function externalChangesSinceStage(cwd) {
106
159
  const unstaged = out.split("\n").filter((l) => l.trim()).filter((l) => {
107
160
  const idx = l[0] ?? " ";
108
161
  return idx === " " || idx === "?";
109
- }).map((l) => l.slice(3).trim());
162
+ }).map((l) => parsePorcelainLine(l)).filter((p) => p !== null && p.length > 0);
110
163
  return unstaged.length > 0 ? unstaged : null;
111
164
  } catch {
112
165
  return null;
@@ -470,5 +523,6 @@ ${preCommitDiff}
470
523
  };
471
524
  var git_autocommit_default = plugin;
472
525
  export {
473
- git_autocommit_default as default
526
+ git_autocommit_default as default,
527
+ parsePorcelainLine
474
528
  };
@@ -66,6 +66,17 @@ function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
66
66
  return resolved === null ? null : { ...resolved, args: [resolved.entry, ...extraArgs] };
67
67
  }
68
68
 
69
+ // src/runtime/handles.ts
70
+ function releaseHandle(off) {
71
+ if (off) {
72
+ try {
73
+ off();
74
+ } catch {
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+
69
80
  // src/runtime/index.ts
70
81
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
71
82
  function hasLeadingDash(arg) {
@@ -318,7 +329,7 @@ var plugin = {
318
329
  state.organizedCount = 0;
319
330
  state.cleanCount = 0;
320
331
  state.errorCount = 0;
321
- state.hookUnregister = null;
332
+ state.hookUnregister = releaseHandle(state.hookUnregister);
322
333
  state.lastResult = null;
323
334
  state.probeComplete = false;
324
335
  state.linterAvailable = false;