@wrongstack/plugins 0.295.0 → 0.296.2

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 (110) hide show
  1. package/dist/accessibility-auditor/index.d.ts.map +1 -1
  2. package/dist/accessibility-auditor.js +31 -3
  3. package/dist/agent-handoff/index.d.ts.map +1 -1
  4. package/dist/agent-handoff.js +30 -1
  5. package/dist/auto-doc/index.d.ts.map +1 -1
  6. package/dist/auto-doc.js +3 -1
  7. package/dist/auto-i18n-extractor.js +5 -0
  8. package/dist/branch-guard/index.d.ts.map +1 -1
  9. package/dist/branch-guard.js +116 -3
  10. package/dist/changelog-writer/index.d.ts.map +1 -1
  11. package/dist/changelog-writer.js +137 -3
  12. package/dist/checkpoint/index.d.ts +2 -0
  13. package/dist/checkpoint/index.d.ts.map +1 -1
  14. package/dist/checkpoint.js +34 -8
  15. package/dist/code-metrics.js +5 -0
  16. package/dist/commit-validator/index.d.ts.map +1 -1
  17. package/dist/commit-validator.js +35 -8
  18. package/dist/context-pins/index.d.ts.map +1 -1
  19. package/dist/context-pins.js +6 -5
  20. package/dist/cost-tracker/index.d.ts.map +1 -1
  21. package/dist/cost-tracker.js +101 -1
  22. package/dist/cron/index.d.ts.map +1 -1
  23. package/dist/cron.js +1 -0
  24. package/dist/dead-code-detector/index.d.ts.map +1 -1
  25. package/dist/dead-code-detector.js +9 -1
  26. package/dist/dependency-vulnerability-gate/index.d.ts.map +1 -1
  27. package/dist/dependency-vulnerability-gate.js +43 -8
  28. package/dist/diff-summary/index.d.ts.map +1 -1
  29. package/dist/diff-summary.js +112 -2
  30. package/dist/doc-sync-guard.js +17 -1
  31. package/dist/duplicate-code-detector/index.d.ts.map +1 -1
  32. package/dist/duplicate-code-detector.js +102 -2
  33. package/dist/feature-flag-tracker/index.d.ts.map +1 -1
  34. package/dist/feature-flag-tracker.js +30 -4
  35. package/dist/file-watcher/index.d.ts.map +1 -1
  36. package/dist/file-watcher.js +6 -7
  37. package/dist/format-on-save/index.d.ts +2 -0
  38. package/dist/format-on-save/index.d.ts.map +1 -1
  39. package/dist/format-on-save.js +288 -59
  40. package/dist/git-autocommit/index.d.ts +12 -0
  41. package/dist/git-autocommit/index.d.ts.map +1 -1
  42. package/dist/git-autocommit.js +58 -4
  43. package/dist/import-organizer/index.d.ts.map +1 -1
  44. package/dist/import-organizer.js +152 -21
  45. package/dist/index.js +1413 -590
  46. package/dist/injection-shield/index.d.ts +16 -0
  47. package/dist/injection-shield/index.d.ts.map +1 -1
  48. package/dist/injection-shield.js +12 -4
  49. package/dist/interface-contract-guard/index.d.ts.map +1 -1
  50. package/dist/interface-contract-guard.js +60 -26
  51. package/dist/knowledge-graph/index.d.ts.map +1 -1
  52. package/dist/knowledge-graph.js +7 -6
  53. package/dist/lint-gate/index.d.ts.map +1 -1
  54. package/dist/lint-gate.js +115 -2
  55. package/dist/loop-breaker/index.d.ts.map +1 -1
  56. package/dist/loop-breaker.js +15 -5
  57. package/dist/migration-planner.js +15 -1
  58. package/dist/notify-hub/index.d.ts.map +1 -1
  59. package/dist/notify-hub.js +41 -4
  60. package/dist/pr-drafter/index.d.ts.map +1 -1
  61. package/dist/pr-drafter.js +20 -1
  62. package/dist/prompt-firewall/index.d.ts.map +1 -1
  63. package/dist/prompt-firewall.js +140 -11
  64. package/dist/refactor-suggester/index.d.ts.map +1 -1
  65. package/dist/refactor-suggester.js +119 -4
  66. package/dist/runtime/bounded-map.d.ts +86 -0
  67. package/dist/runtime/bounded-map.d.ts.map +1 -0
  68. package/dist/runtime/credential-patterns.d.ts +42 -0
  69. package/dist/runtime/credential-patterns.d.ts.map +1 -0
  70. package/dist/runtime/handles.d.ts +46 -0
  71. package/dist/runtime/handles.d.ts.map +1 -0
  72. package/dist/runtime/index.d.ts +4 -0
  73. package/dist/runtime/index.d.ts.map +1 -1
  74. package/dist/runtime/local-bin.d.ts +120 -0
  75. package/dist/runtime/local-bin.d.ts.map +1 -0
  76. package/dist/runtime/safe-json.d.ts +25 -0
  77. package/dist/runtime/safe-json.d.ts.map +1 -0
  78. package/dist/runtime.js +309 -22
  79. package/dist/schema-evolution-guard.js +5 -0
  80. package/dist/secret-scanner/index.d.ts.map +1 -1
  81. package/dist/secret-scanner.js +194 -50
  82. package/dist/security-hotspot-scanner/index.d.ts.map +1 -1
  83. package/dist/security-hotspot-scanner.js +132 -1
  84. package/dist/semantic-search-indexer/index.d.ts.map +1 -1
  85. package/dist/semantic-search-indexer.js +7 -1
  86. package/dist/semver-bump/index.d.ts.map +1 -1
  87. package/dist/semver-bump.js +21 -2
  88. package/dist/session-recap/index.d.ts.map +1 -1
  89. package/dist/session-recap.js +18 -1
  90. package/dist/smart-rename/index.d.ts +2 -0
  91. package/dist/smart-rename/index.d.ts.map +1 -1
  92. package/dist/smart-rename.js +16 -2
  93. package/dist/spec-linker/index.d.ts.map +1 -1
  94. package/dist/spec-linker.js +19 -2
  95. package/dist/template-engine/index.d.ts.map +1 -1
  96. package/dist/template-engine.js +45 -3
  97. package/dist/test-coverage-gate.js +17 -1
  98. package/dist/test-runner-gate/index.d.ts.map +1 -1
  99. package/dist/test-runner-gate.js +142 -9
  100. package/dist/todo-listener/index.d.ts.map +1 -1
  101. package/dist/todo-listener.js +42 -2
  102. package/dist/todo-tracker/index.d.ts.map +1 -1
  103. package/dist/todo-tracker.js +3 -4
  104. package/dist/token-budget/index.d.ts.map +1 -1
  105. package/dist/token-budget.js +31 -19
  106. package/dist/token-throttle/index.d.ts.map +1 -1
  107. package/dist/token-throttle.js +17 -2
  108. package/dist/type-gate/index.d.ts.map +1 -1
  109. package/dist/type-gate.js +108 -17
  110. package/package.json +3 -3
package/dist/type-gate.js CHANGED
@@ -3,7 +3,80 @@ import { existsSync } from "node:fs";
3
3
 
4
4
  // src/runtime/index.ts
5
5
  import { execFile } from "node:child_process";
6
- import { basename, extname, isAbsolute, relative, resolve } from "node:path";
6
+ import { basename, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
7
+
8
+ // src/runtime/local-bin.ts
9
+ import { createRequire } from "node:module";
10
+ import { delimiter, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
11
+ import { accessSync, constants, readFileSync } from "node:fs";
12
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
13
+ function resolveExecInvocation(command, args = []) {
14
+ const resolved = resolveWin32Command(command);
15
+ const normalizedResolved = resolved.toLowerCase();
16
+ const needsShell = process.platform === "win32" && (normalizedResolved.endsWith(".cmd") || normalizedResolved.endsWith(".bat"));
17
+ if (needsShell) {
18
+ const shim = buildWin32CmdShimInvocation(resolved, args);
19
+ return { cmd: shim.command, args: shim.args, windowsVerbatimArguments: true };
20
+ }
21
+ return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
22
+ }
23
+ function isInside(parent, candidate) {
24
+ const rel = relative(parent, candidate);
25
+ return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
26
+ }
27
+ var binCache = /* @__PURE__ */ new Map();
28
+ var BIN_CACHE_MAX = 64;
29
+ var NEGATIVE_BIN_CACHE_TTL_MS = 5e3;
30
+ function cachePut(key, value) {
31
+ while (binCache.size >= BIN_CACHE_MAX) {
32
+ const oldest = binCache.keys().next().value;
33
+ if (oldest === void 0) break;
34
+ binCache.delete(oldest);
35
+ }
36
+ binCache.set(key, { value, cachedAt: Date.now() });
37
+ return value;
38
+ }
39
+ function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
40
+ const key = `${packageName}|${binName}|${cwd}`;
41
+ const cached = binCache.get(key);
42
+ if (cached !== void 0) {
43
+ if (cached.value !== null || Date.now() - cached.cachedAt < NEGATIVE_BIN_CACHE_TTL_MS) {
44
+ return cached.value === null ? null : { ...cached.value, args: [cached.value.entry, ...extraArgs] };
45
+ }
46
+ binCache.delete(key);
47
+ }
48
+ let resolved = null;
49
+ try {
50
+ const requireFromProject = createRequire(resolve(cwd, "package.json"));
51
+ const packagePath = requireFromProject.resolve(`${packageName}/package.json`);
52
+ const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
53
+ const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[binName] ?? Object.values(packageJson.bin ?? {})[0];
54
+ if (relativeBin && !isAbsolute(relativeBin)) {
55
+ const packageDir = dirname(packagePath);
56
+ const entry = resolve(packageDir, relativeBin);
57
+ if (isInside(packageDir, entry)) {
58
+ resolved = { cmd: process.execPath, args: [entry], entry };
59
+ }
60
+ }
61
+ } catch {
62
+ resolved = null;
63
+ }
64
+ cachePut(key, resolved);
65
+ return resolved === null ? null : { ...resolved, args: [resolved.entry, ...extraArgs] };
66
+ }
67
+
68
+ // src/runtime/handles.ts
69
+ function releaseHandle(off) {
70
+ if (off) {
71
+ try {
72
+ off();
73
+ } catch {
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
79
+ // src/runtime/index.ts
7
80
  var META_CHARS = /["'`;&|<>\r\n]/;
8
81
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
9
82
  function hasLeadingDash(arg) {
@@ -17,9 +90,9 @@ function safeSplit(command) {
17
90
  function withinProjectPath(projectRoot, candidate) {
18
91
  if (candidate.length === 0 || candidate.length > 4096) return false;
19
92
  if (hasLeadingDash(candidate)) return false;
20
- const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
21
- const rel = relative(projectRoot, resolved);
22
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
93
+ const resolved = isAbsolute2(candidate) ? resolve2(candidate) : resolve2(projectRoot, candidate);
94
+ const rel = relative2(projectRoot, resolved);
95
+ return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
23
96
  }
24
97
  function everyFlagAllowed(allowed, args) {
25
98
  for (const arg of args) {
@@ -31,14 +104,14 @@ function everyFlagAllowed(allowed, args) {
31
104
  }
32
105
  function sanitizeRunnerPath(value, options = {}) {
33
106
  if (!value || hasLeadingDash(value)) return null;
34
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
107
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
35
108
  if (!withinProjectPath(projectRoot, value)) return null;
36
- return isAbsolute(value) ? resolve(value) : resolve(projectRoot, value);
109
+ return isAbsolute2(value) ? resolve2(value) : resolve2(projectRoot, value);
37
110
  }
38
111
  function resolveRunnerCommand(runtime, command, options = {}) {
39
112
  const tokens = safeSplit(command);
40
113
  if (!tokens || tokens.length === 0) return null;
41
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
114
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
42
115
  const launcher = runtime.packageManager;
43
116
  const [head, second, ...rest] = tokens;
44
117
  if (!head) return null;
@@ -69,7 +142,7 @@ function resolveRunnerCommand(runtime, command, options = {}) {
69
142
  return { cmd: head, args: [second, exe, ...tail], display };
70
143
  }
71
144
  }
72
- if (isAbsolute(head)) {
145
+ if (isAbsolute2(head)) {
73
146
  if (!withinProjectPath(projectRoot, head)) return null;
74
147
  const base = basename(head);
75
148
  if (base !== runtime.executable && base !== launcher) return null;
@@ -90,7 +163,7 @@ function runRunnerCommand(argv, options) {
90
163
  });
91
164
  }
92
165
  return new Promise((resolvePromise) => {
93
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
166
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
94
167
  const trimmedCwd = options.cwd.trim();
95
168
  if (!withinProjectPath(projectRoot, trimmedCwd)) {
96
169
  resolvePromise({
@@ -108,21 +181,37 @@ function runRunnerCommand(argv, options) {
108
181
  const stderrChunks = [];
109
182
  let stdoutBytes = 0;
110
183
  let stderrBytes = 0;
111
- options.signal?.addEventListener("abort", () => {
184
+ const onAbort = () => {
112
185
  timedOut = true;
113
- }, { once: true });
186
+ };
187
+ let invocation;
188
+ try {
189
+ invocation = resolveExecInvocation(argv[0], argv.slice(1));
190
+ } catch (err) {
191
+ resolvePromise({
192
+ code: null,
193
+ stdout: "",
194
+ stderr: `runtime helper: ${err instanceof Error ? err.message : String(err)}`,
195
+ timedOut: false,
196
+ spawnError: true
197
+ });
198
+ return;
199
+ }
200
+ options.signal?.addEventListener("abort", onAbort, { once: true });
114
201
  const child = execFile(
115
- argv[0],
116
- argv.slice(1),
202
+ invocation.cmd,
203
+ invocation.args,
117
204
  {
118
205
  cwd: trimmedCwd,
119
206
  timeout: options.timeoutMs,
120
207
  signal: options.signal,
121
208
  maxBuffer: MAX_BUFFER_BYTES,
122
209
  windowsHide: true,
123
- shell: false
210
+ shell: false,
211
+ ...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
124
212
  },
125
213
  (err) => {
214
+ options.signal?.removeEventListener("abort", onAbort);
126
215
  if (timedOut) {
127
216
  resolvePromise({
128
217
  code: null,
@@ -186,7 +275,7 @@ function runRunnerCommand(argv, options) {
186
275
  }
187
276
  function withinProject(p) {
188
277
  const cwd = process.cwd();
189
- return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
278
+ return withinProjectPath(cwd, p) || relative2(cwd, p) === ".";
190
279
  }
191
280
 
192
281
  // src/type-gate/index.ts
@@ -263,7 +352,9 @@ async function runTypeCheck(cfg) {
263
352
  if (!resolved) return null;
264
353
  argv = [resolved.cmd, ...resolved.args];
265
354
  } else {
266
- argv = ["npx", "tsc", "--noEmit", "--incremental"];
355
+ const tscFlags = ["--noEmit", "--incremental"];
356
+ const localTsc = resolveNodeBin("typescript", "tsc", process.cwd(), tscFlags);
357
+ argv = localTsc ? [localTsc.cmd, ...localTsc.args] : ["npx", "tsc", ...tscFlags];
267
358
  if (tsConfig && tsConfig !== "tsconfig.json") {
268
359
  argv = [...argv, "-p", tsConfig];
269
360
  }
@@ -359,7 +450,7 @@ var plugin = {
359
450
  state.errorCount = 0;
360
451
  state.skippedCount = 0;
361
452
  state.lastResult = null;
362
- state.hookUnregister = null;
453
+ state.hookUnregister = releaseHandle(state.hookUnregister);
363
454
  const cfg = readConfig(api.config.extensions?.["type-gate"]);
364
455
  const hook = async (input) => {
365
456
  if (!cfg.enabled) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/plugins",
3
- "version": "0.295.0",
3
+ "version": "0.296.2",
4
4
  "description": "Official WrongStack collection of focused plugins for code quality, security, observability, planning, and agent coordination",
5
5
  "license": "MIT",
6
6
  "author": "ECOSTACK TECHNOLOGY OÜ",
@@ -294,8 +294,8 @@
294
294
  "vitest": "^4.1.10"
295
295
  },
296
296
  "dependencies": {
297
- "@wrongstack/core": "0.295.0",
298
- "@wrongstack/tools": "0.295.0"
297
+ "@wrongstack/core": "0.296.2",
298
+ "@wrongstack/tools": "0.296.2"
299
299
  },
300
300
  "scripts": {
301
301
  "build": "node ../../scripts/build-package.mjs",