@wrongstack/plugins 0.293.0 → 0.295.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.
Files changed (211) hide show
  1. package/README.md +7 -71
  2. package/dist/accessibility-auditor/index.d.ts +1 -1
  3. package/dist/accessibility-auditor/index.d.ts.map +1 -1
  4. package/dist/accessibility-auditor.js +50 -33
  5. package/dist/agent-handoff/index.d.ts +1 -1
  6. package/dist/agent-handoff/index.d.ts.map +1 -1
  7. package/dist/agent-handoff.js +30 -1
  8. package/dist/api-compatibility-gate/index.d.ts +1 -1
  9. package/dist/api-compatibility-gate/index.d.ts.map +1 -1
  10. package/dist/api-compatibility-gate.js +21 -16
  11. package/dist/audit/index.d.ts +386 -0
  12. package/dist/audit/index.d.ts.map +1 -0
  13. package/dist/audit.d.ts +1 -0
  14. package/dist/audit.js +454 -0
  15. package/dist/auto-doc/index.d.ts +1 -1
  16. package/dist/auto-doc/index.d.ts.map +1 -1
  17. package/dist/auto-doc.js +3 -1
  18. package/dist/auto-escalate/index.d.ts +1 -1
  19. package/dist/auto-escalate/index.d.ts.map +1 -1
  20. package/dist/auto-i18n-extractor/index.d.ts +1 -1
  21. package/dist/auto-i18n-extractor/index.d.ts.map +1 -1
  22. package/dist/auto-i18n-extractor.js +7 -1
  23. package/dist/branch-guard/index.d.ts +1 -1
  24. package/dist/branch-guard/index.d.ts.map +1 -1
  25. package/dist/branch-guard.js +111 -1
  26. package/dist/catalog.d.ts +5 -30
  27. package/dist/catalog.d.ts.map +1 -1
  28. package/dist/changelog-writer/index.d.ts +1 -1
  29. package/dist/changelog-writer/index.d.ts.map +1 -1
  30. package/dist/changelog-writer.js +137 -3
  31. package/dist/checkpoint/index.d.ts +3 -1
  32. package/dist/checkpoint/index.d.ts.map +1 -1
  33. package/dist/checkpoint.js +41 -16
  34. package/dist/code-metrics/index.d.ts +1 -1
  35. package/dist/code-metrics/index.d.ts.map +1 -1
  36. package/dist/code-metrics.js +34 -29
  37. package/dist/commit-validator/index.d.ts +1 -1
  38. package/dist/commit-validator/index.d.ts.map +1 -1
  39. package/dist/commit-validator.js +17 -7
  40. package/dist/config-validator/index.d.ts +1 -1
  41. package/dist/config-validator/index.d.ts.map +1 -1
  42. package/dist/context-pins/index.d.ts +1 -1
  43. package/dist/context-pins/index.d.ts.map +1 -1
  44. package/dist/context-pins.js +6 -5
  45. package/dist/cost-tracker/index.d.ts +1 -1
  46. package/dist/cost-tracker/index.d.ts.map +1 -1
  47. package/dist/cost-tracker.js +109 -2
  48. package/dist/cron/index.d.ts +1 -1
  49. package/dist/cron/index.d.ts.map +1 -1
  50. package/dist/cron.js +1 -0
  51. package/dist/dead-code-detector/index.d.ts +1 -1
  52. package/dist/dead-code-detector/index.d.ts.map +1 -1
  53. package/dist/dead-code-detector.js +31 -18
  54. package/dist/dep-guard/index.d.ts +1 -1
  55. package/dist/dep-guard/index.d.ts.map +1 -1
  56. package/dist/dependency-vulnerability-gate/index.d.ts +1 -1
  57. package/dist/dependency-vulnerability-gate/index.d.ts.map +1 -1
  58. package/dist/dependency-vulnerability-gate.js +67 -20
  59. package/dist/diff-summary/index.d.ts +1 -1
  60. package/dist/diff-summary/index.d.ts.map +1 -1
  61. package/dist/diff-summary.js +128 -30
  62. package/dist/doc-sync-guard/index.d.ts +1 -1
  63. package/dist/doc-sync-guard/index.d.ts.map +1 -1
  64. package/dist/doc-sync-guard.js +7 -1
  65. package/dist/duplicate-code-detector/index.d.ts +26 -1
  66. package/dist/duplicate-code-detector/index.d.ts.map +1 -1
  67. package/dist/duplicate-code-detector.js +280 -69
  68. package/dist/error-lens/index.d.ts +1 -1
  69. package/dist/error-lens/index.d.ts.map +1 -1
  70. package/dist/factories/index.d.ts +4 -0
  71. package/dist/factories/index.d.ts.map +1 -0
  72. package/dist/factories.d.ts +1 -0
  73. package/dist/factories.js +74 -0
  74. package/dist/feature-flag-tracker/index.d.ts +1 -1
  75. package/dist/feature-flag-tracker/index.d.ts.map +1 -1
  76. package/dist/feature-flag-tracker.js +59 -33
  77. package/dist/file-watcher/index.d.ts +1 -1
  78. package/dist/file-watcher/index.d.ts.map +1 -1
  79. package/dist/file-watcher.js +6 -7
  80. package/dist/format-on-save/index.d.ts +3 -1
  81. package/dist/format-on-save/index.d.ts.map +1 -1
  82. package/dist/format-on-save.js +289 -59
  83. package/dist/generated-plugin-exports.d.ts +65 -0
  84. package/dist/generated-plugin-exports.d.ts.map +1 -0
  85. package/dist/git-autocommit/index.d.ts +1 -1
  86. package/dist/git-autocommit/index.d.ts.map +1 -1
  87. package/dist/import-organizer/index.d.ts +1 -1
  88. package/dist/import-organizer/index.d.ts.map +1 -1
  89. package/dist/import-organizer.js +141 -20
  90. package/dist/index.d.ts +4 -183
  91. package/dist/index.d.ts.map +1 -1
  92. package/dist/index.js +18298 -17279
  93. package/dist/injection-shield/index.d.ts +1 -1
  94. package/dist/injection-shield/index.d.ts.map +1 -1
  95. package/dist/interface-contract-guard/index.d.ts +1 -1
  96. package/dist/interface-contract-guard/index.d.ts.map +1 -1
  97. package/dist/interface-contract-guard.js +87 -53
  98. package/dist/knowledge-graph/index.d.ts +1 -1
  99. package/dist/knowledge-graph/index.d.ts.map +1 -1
  100. package/dist/knowledge-graph.js +7 -6
  101. package/dist/license-audit-gate/index.d.ts +1 -1
  102. package/dist/license-audit-gate/index.d.ts.map +1 -1
  103. package/dist/lint-gate/index.d.ts +1 -1
  104. package/dist/lint-gate/index.d.ts.map +1 -1
  105. package/dist/lint-gate.js +112 -1
  106. package/dist/llm-cache/index.d.ts +5 -1
  107. package/dist/llm-cache/index.d.ts.map +1 -1
  108. package/dist/llm-cache.js +16 -8
  109. package/dist/loop-breaker/index.d.ts +1 -1
  110. package/dist/loop-breaker/index.d.ts.map +1 -1
  111. package/dist/loop-breaker.js +25 -9
  112. package/dist/manifest/index.d.ts +16 -0
  113. package/dist/manifest/index.d.ts.map +1 -0
  114. package/dist/manifest.d.ts +1 -0
  115. package/dist/manifest.js +152 -0
  116. package/dist/migration-planner/index.d.ts +1 -1
  117. package/dist/migration-planner/index.d.ts.map +1 -1
  118. package/dist/migration-planner.js +5 -1
  119. package/dist/model-router/index.d.ts +1 -1
  120. package/dist/model-router/index.d.ts.map +1 -1
  121. package/dist/notify-hub/index.d.ts +1 -1
  122. package/dist/notify-hub/index.d.ts.map +1 -1
  123. package/dist/notify-hub/webhook-channel.d.ts +1 -1
  124. package/dist/notify-hub/webhook-channel.d.ts.map +1 -1
  125. package/dist/notify-hub.js +41 -4
  126. package/dist/path-guard/index.d.ts +1 -1
  127. package/dist/path-guard/index.d.ts.map +1 -1
  128. package/dist/performance-regression-gate/index.d.ts +1 -1
  129. package/dist/performance-regression-gate/index.d.ts.map +1 -1
  130. package/dist/plugin-stack-observer/index.d.ts +1 -1
  131. package/dist/plugin-stack-observer/index.d.ts.map +1 -1
  132. package/dist/pr-drafter/index.d.ts +1 -1
  133. package/dist/pr-drafter/index.d.ts.map +1 -1
  134. package/dist/pr-drafter.js +28 -29
  135. package/dist/process-guard/index.d.ts +1 -1
  136. package/dist/process-guard/index.d.ts.map +1 -1
  137. package/dist/prompt-firewall/index.d.ts +1 -1
  138. package/dist/prompt-firewall/index.d.ts.map +1 -1
  139. package/dist/prompt-firewall.js +140 -11
  140. package/dist/refactor-suggester/index.d.ts +1 -1
  141. package/dist/refactor-suggester/index.d.ts.map +1 -1
  142. package/dist/refactor-suggester.js +148 -33
  143. package/dist/release-notes-generator/index.d.ts +1 -1
  144. package/dist/release-notes-generator/index.d.ts.map +1 -1
  145. package/dist/release-notes-generator.js +29 -22
  146. package/dist/runtime/bounded-map.d.ts +86 -0
  147. package/dist/runtime/bounded-map.d.ts.map +1 -0
  148. package/dist/runtime/credential-patterns.d.ts +42 -0
  149. package/dist/runtime/credential-patterns.d.ts.map +1 -0
  150. package/dist/runtime/index.d.ts +18 -0
  151. package/dist/runtime/index.d.ts.map +1 -1
  152. package/dist/runtime/llm.d.ts +1 -1
  153. package/dist/runtime/llm.d.ts.map +1 -1
  154. package/dist/runtime/local-bin.d.ts +120 -0
  155. package/dist/runtime/local-bin.d.ts.map +1 -0
  156. package/dist/runtime/safe-json.d.ts +25 -0
  157. package/dist/runtime/safe-json.d.ts.map +1 -0
  158. package/dist/runtime.js +332 -22
  159. package/dist/schema-evolution-guard/index.d.ts +1 -1
  160. package/dist/schema-evolution-guard/index.d.ts.map +1 -1
  161. package/dist/schema-evolution-guard.js +7 -1
  162. package/dist/secret-scanner/index.d.ts +1 -1
  163. package/dist/secret-scanner/index.d.ts.map +1 -1
  164. package/dist/secret-scanner.js +181 -48
  165. package/dist/security-hotspot-scanner/index.d.ts +1 -1
  166. package/dist/security-hotspot-scanner/index.d.ts.map +1 -1
  167. package/dist/security-hotspot-scanner.js +158 -20
  168. package/dist/semantic-search-indexer/index.d.ts +1 -1
  169. package/dist/semantic-search-indexer/index.d.ts.map +1 -1
  170. package/dist/semantic-search-indexer.js +7 -1
  171. package/dist/semver-bump/index.d.ts +1 -1
  172. package/dist/semver-bump/index.d.ts.map +1 -1
  173. package/dist/semver-bump.js +97 -43
  174. package/dist/session-recap/index.d.ts +1 -1
  175. package/dist/session-recap/index.d.ts.map +1 -1
  176. package/dist/shell-check/index.d.ts +1 -1
  177. package/dist/shell-check/index.d.ts.map +1 -1
  178. package/dist/smart-rename/index.d.ts +1 -1
  179. package/dist/smart-rename/index.d.ts.map +1 -1
  180. package/dist/spec-linker/index.d.ts +1 -1
  181. package/dist/spec-linker/index.d.ts.map +1 -1
  182. package/dist/spec-linker.js +222 -20772
  183. package/dist/template-engine/index.d.ts +1 -1
  184. package/dist/template-engine/index.d.ts.map +1 -1
  185. package/dist/template-engine.js +34 -8
  186. package/dist/test-coverage-gate/index.d.ts +1 -1
  187. package/dist/test-coverage-gate/index.d.ts.map +1 -1
  188. package/dist/test-coverage-gate.js +34 -14
  189. package/dist/test-flake-detector/index.d.ts +1 -1
  190. package/dist/test-flake-detector/index.d.ts.map +1 -1
  191. package/dist/test-flake-detector.js +31 -20
  192. package/dist/test-generator/index.d.ts +1 -1
  193. package/dist/test-generator/index.d.ts.map +1 -1
  194. package/dist/test-runner-gate/index.d.ts +1 -1
  195. package/dist/test-runner-gate/index.d.ts.map +1 -1
  196. package/dist/test-runner-gate.js +132 -9
  197. package/dist/todo-listener/index.d.ts +1 -32
  198. package/dist/todo-listener/index.d.ts.map +1 -1
  199. package/dist/todo-listener.js +30 -1
  200. package/dist/todo-tracker/index.d.ts +1 -1
  201. package/dist/todo-tracker/index.d.ts.map +1 -1
  202. package/dist/todo-tracker.js +3 -4
  203. package/dist/token-budget/index.d.ts +1 -1
  204. package/dist/token-budget/index.d.ts.map +1 -1
  205. package/dist/token-throttle/index.d.ts +1 -1
  206. package/dist/token-throttle/index.d.ts.map +1 -1
  207. package/dist/token-throttle.js +17 -2
  208. package/dist/type-gate/index.d.ts +1 -1
  209. package/dist/type-gate/index.d.ts.map +1 -1
  210. package/dist/type-gate.js +106 -19
  211. package/package.json +80 -68
package/dist/runtime.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/runtime/index.ts
2
2
  import { execFile } from "node:child_process";
3
3
  import { existsSync, readdirSync, statSync } from "node:fs";
4
- import { basename, extname, isAbsolute, relative, resolve } from "node:path";
4
+ import { basename, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
5
5
 
6
6
  // src/runtime/llm.ts
7
7
  function stripOuterMarkdownFence(text) {
@@ -49,6 +49,249 @@ async function runOptionalPluginLlm(request) {
49
49
  }
50
50
  }
51
51
 
52
+ // src/runtime/local-bin.ts
53
+ import { createRequire } from "node:module";
54
+ import { delimiter, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
55
+ import { accessSync, constants, readFileSync } from "node:fs";
56
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
57
+ function resolveExecInvocation(command, args = []) {
58
+ const resolved = resolveWin32Command(command);
59
+ const normalizedResolved = resolved.toLowerCase();
60
+ const needsShell = process.platform === "win32" && (normalizedResolved.endsWith(".cmd") || normalizedResolved.endsWith(".bat"));
61
+ if (needsShell) {
62
+ const shim = buildWin32CmdShimInvocation(resolved, args);
63
+ return { cmd: shim.command, args: shim.args, windowsVerbatimArguments: true };
64
+ }
65
+ return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
66
+ }
67
+ function findOnPath(cmd) {
68
+ if (!cmd) return null;
69
+ const exists = (p) => {
70
+ try {
71
+ accessSync(p, constants.X_OK);
72
+ return true;
73
+ } catch {
74
+ return false;
75
+ }
76
+ };
77
+ if (cmd.includes("/") || cmd.includes("\\")) {
78
+ return exists(cmd) ? resolve(cmd) : null;
79
+ }
80
+ const suffixes = process.platform === "win32" && extname(cmd) === "" ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
81
+ for (const dir of (process.env["PATH"] ?? "").split(delimiter)) {
82
+ if (!dir) continue;
83
+ const base = join(dir, cmd);
84
+ for (const suffix of suffixes) {
85
+ const candidate = `${base}${suffix}`;
86
+ if (exists(candidate)) return candidate;
87
+ }
88
+ }
89
+ return null;
90
+ }
91
+ function isInside(parent, candidate) {
92
+ const rel = relative(parent, candidate);
93
+ return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
94
+ }
95
+ var binCache = /* @__PURE__ */ new Map();
96
+ var BIN_CACHE_MAX = 64;
97
+ var NEGATIVE_BIN_CACHE_TTL_MS = 5e3;
98
+ function cachePut(key, value) {
99
+ while (binCache.size >= BIN_CACHE_MAX) {
100
+ const oldest = binCache.keys().next().value;
101
+ if (oldest === void 0) break;
102
+ binCache.delete(oldest);
103
+ }
104
+ binCache.set(key, { value, cachedAt: Date.now() });
105
+ return value;
106
+ }
107
+ function clearLocalBinCache() {
108
+ binCache.clear();
109
+ }
110
+ function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
111
+ const key = `${packageName}|${binName}|${cwd}`;
112
+ const cached = binCache.get(key);
113
+ if (cached !== void 0) {
114
+ if (cached.value !== null || Date.now() - cached.cachedAt < NEGATIVE_BIN_CACHE_TTL_MS) {
115
+ return cached.value === null ? null : { ...cached.value, args: [cached.value.entry, ...extraArgs] };
116
+ }
117
+ binCache.delete(key);
118
+ }
119
+ let resolved = null;
120
+ try {
121
+ const requireFromProject = createRequire(resolve(cwd, "package.json"));
122
+ const packagePath = requireFromProject.resolve(`${packageName}/package.json`);
123
+ const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
124
+ const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[binName] ?? Object.values(packageJson.bin ?? {})[0];
125
+ if (relativeBin && !isAbsolute(relativeBin)) {
126
+ const packageDir = dirname(packagePath);
127
+ const entry = resolve(packageDir, relativeBin);
128
+ if (isInside(packageDir, entry)) {
129
+ resolved = { cmd: process.execPath, args: [entry], entry };
130
+ }
131
+ }
132
+ } catch {
133
+ resolved = null;
134
+ }
135
+ cachePut(key, resolved);
136
+ return resolved === null ? null : { ...resolved, args: [resolved.entry, ...extraArgs] };
137
+ }
138
+ function resolveFirstNodeBin(candidates, cwd) {
139
+ for (const c of candidates) {
140
+ const hit = resolveNodeBin(c.packageName, c.binName, cwd, c.args ?? []);
141
+ if (hit) return { ...hit, packageName: c.packageName, binName: c.binName };
142
+ }
143
+ return null;
144
+ }
145
+
146
+ // src/runtime/bounded-map.ts
147
+ var BoundedMap = class {
148
+ map = /* @__PURE__ */ new Map();
149
+ max;
150
+ ttlMs;
151
+ now;
152
+ /** Entries dropped to stay under `max`. Surfaced by plugin health(). */
153
+ evictions = 0;
154
+ constructor(options) {
155
+ const normalizedMax = Math.floor(options.max);
156
+ this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
157
+ this.ttlMs = options.ttlMs;
158
+ this.now = options.now ?? Date.now;
159
+ }
160
+ expired(entry) {
161
+ return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
162
+ }
163
+ get(key) {
164
+ const entry = this.map.get(key);
165
+ if (entry === void 0) return void 0;
166
+ if (this.expired(entry)) {
167
+ this.map.delete(key);
168
+ return void 0;
169
+ }
170
+ this.map.delete(key);
171
+ this.map.set(key, entry);
172
+ return entry.value;
173
+ }
174
+ /**
175
+ * Read without promoting the key to most-recently-used. Use for
176
+ * diagnostics that must not perturb the eviction order.
177
+ */
178
+ peek(key) {
179
+ const entry = this.map.get(key);
180
+ if (entry === void 0 || this.expired(entry)) return void 0;
181
+ return entry.value;
182
+ }
183
+ has(key) {
184
+ const entry = this.map.get(key);
185
+ if (entry === void 0) return false;
186
+ if (this.expired(entry)) {
187
+ this.map.delete(key);
188
+ return false;
189
+ }
190
+ return true;
191
+ }
192
+ set(key, value) {
193
+ this.map.delete(key);
194
+ this.map.set(key, { value, storedAt: this.now() });
195
+ while (this.map.size > this.max) {
196
+ const coldest = this.map.keys().next().value;
197
+ if (coldest === void 0) break;
198
+ this.map.delete(coldest);
199
+ this.evictions += 1;
200
+ }
201
+ return this;
202
+ }
203
+ delete(key) {
204
+ return this.map.delete(key);
205
+ }
206
+ clear() {
207
+ this.map.clear();
208
+ this.evictions = 0;
209
+ }
210
+ get size() {
211
+ return this.map.size;
212
+ }
213
+ /** How many entries have been dropped to respect `max`, since the last clear. */
214
+ get evictionCount() {
215
+ return this.evictions;
216
+ }
217
+ /** Drop every expired entry. Cheap enough to call from a status tool. */
218
+ prune() {
219
+ if (this.ttlMs === void 0) return 0;
220
+ let removed = 0;
221
+ for (const [key, entry] of this.map) {
222
+ if (this.expired(entry)) {
223
+ this.map.delete(key);
224
+ removed += 1;
225
+ }
226
+ }
227
+ return removed;
228
+ }
229
+ /** Live (non-expired) entries, coldest first. */
230
+ *entries() {
231
+ for (const [key, entry] of this.map) {
232
+ if (!this.expired(entry)) yield [key, entry.value];
233
+ }
234
+ }
235
+ [Symbol.iterator]() {
236
+ return this.entries();
237
+ }
238
+ };
239
+ var BoundedSet = class {
240
+ inner;
241
+ constructor(options) {
242
+ this.inner = new BoundedMap(options);
243
+ }
244
+ has(value) {
245
+ return this.inner.has(value);
246
+ }
247
+ add(value) {
248
+ this.inner.set(value, true);
249
+ return this;
250
+ }
251
+ delete(value) {
252
+ return this.inner.delete(value);
253
+ }
254
+ clear() {
255
+ this.inner.clear();
256
+ }
257
+ get size() {
258
+ return this.inner.size;
259
+ }
260
+ /** How many entries have been dropped to respect `max`, since the last clear. */
261
+ get evictionCount() {
262
+ return this.inner.evictionCount;
263
+ }
264
+ *values() {
265
+ for (const [key] of this.inner) yield key;
266
+ }
267
+ [Symbol.iterator]() {
268
+ return this.values();
269
+ }
270
+ };
271
+
272
+ // src/runtime/safe-json.ts
273
+ var UNSERIALIZABLE = "[unserializable]";
274
+ function safeJsonStringify(value, indent) {
275
+ try {
276
+ const stack = [];
277
+ const out = JSON.stringify(
278
+ value,
279
+ function replacer(_key, val) {
280
+ if (typeof val === "bigint") return `${val.toString()}n`;
281
+ if (val === null || typeof val !== "object") return val;
282
+ while (stack.length > 0 && stack[stack.length - 1] !== this) stack.pop();
283
+ if (stack.includes(val)) return "[circular]";
284
+ stack.push(val);
285
+ return val;
286
+ },
287
+ indent
288
+ );
289
+ return out ?? String(value);
290
+ } catch {
291
+ return UNSERIALIZABLE;
292
+ }
293
+ }
294
+
52
295
  // src/runtime/index.ts
53
296
  var META_CHARS = /["'`;&|<>\r\n]/;
54
297
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
@@ -63,9 +306,9 @@ function safeSplit(command) {
63
306
  function withinProjectPath(projectRoot, candidate) {
64
307
  if (candidate.length === 0 || candidate.length > 4096) return false;
65
308
  if (hasLeadingDash(candidate)) return false;
66
- const resolved = isAbsolute(candidate) ? resolve(candidate) : resolve(projectRoot, candidate);
67
- const rel = relative(projectRoot, resolved);
68
- return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
309
+ const resolved = isAbsolute2(candidate) ? resolve2(candidate) : resolve2(projectRoot, candidate);
310
+ const rel = relative2(projectRoot, resolved);
311
+ return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
69
312
  }
70
313
  function everyFlagAllowed(allowed, args) {
71
314
  for (const arg of args) {
@@ -77,14 +320,14 @@ function everyFlagAllowed(allowed, args) {
77
320
  }
78
321
  function sanitizeRunnerPath(value, options = {}) {
79
322
  if (!value || hasLeadingDash(value)) return null;
80
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
323
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
81
324
  if (!withinProjectPath(projectRoot, value)) return null;
82
- return isAbsolute(value) ? resolve(value) : resolve(projectRoot, value);
325
+ return isAbsolute2(value) ? resolve2(value) : resolve2(projectRoot, value);
83
326
  }
84
327
  function resolveRunnerCommand(runtime, command, options = {}) {
85
328
  const tokens = safeSplit(command);
86
329
  if (!tokens || tokens.length === 0) return null;
87
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
330
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
88
331
  const launcher = runtime.packageManager;
89
332
  const [head, second, ...rest] = tokens;
90
333
  if (!head) return null;
@@ -115,7 +358,7 @@ function resolveRunnerCommand(runtime, command, options = {}) {
115
358
  return { cmd: head, args: [second, exe, ...tail], display };
116
359
  }
117
360
  }
118
- if (isAbsolute(head)) {
361
+ if (isAbsolute2(head)) {
119
362
  if (!withinProjectPath(projectRoot, head)) return null;
120
363
  const base = basename(head);
121
364
  if (base !== runtime.executable && base !== launcher) return null;
@@ -136,7 +379,7 @@ function runRunnerCommand(argv, options) {
136
379
  });
137
380
  }
138
381
  return new Promise((resolvePromise) => {
139
- const projectRoot = resolve(options.projectRoot ?? process.cwd());
382
+ const projectRoot = resolve2(options.projectRoot ?? process.cwd());
140
383
  const trimmedCwd = options.cwd.trim();
141
384
  if (!withinProjectPath(projectRoot, trimmedCwd)) {
142
385
  resolvePromise({
@@ -154,21 +397,37 @@ function runRunnerCommand(argv, options) {
154
397
  const stderrChunks = [];
155
398
  let stdoutBytes = 0;
156
399
  let stderrBytes = 0;
157
- options.signal?.addEventListener("abort", () => {
400
+ const onAbort = () => {
158
401
  timedOut = true;
159
- }, { once: true });
402
+ };
403
+ let invocation;
404
+ try {
405
+ invocation = resolveExecInvocation(argv[0], argv.slice(1));
406
+ } catch (err) {
407
+ resolvePromise({
408
+ code: null,
409
+ stdout: "",
410
+ stderr: `runtime helper: ${err instanceof Error ? err.message : String(err)}`,
411
+ timedOut: false,
412
+ spawnError: true
413
+ });
414
+ return;
415
+ }
416
+ options.signal?.addEventListener("abort", onAbort, { once: true });
160
417
  const child = execFile(
161
- argv[0],
162
- argv.slice(1),
418
+ invocation.cmd,
419
+ invocation.args,
163
420
  {
164
421
  cwd: trimmedCwd,
165
422
  timeout: options.timeoutMs,
166
423
  signal: options.signal,
167
424
  maxBuffer: MAX_BUFFER_BYTES,
168
425
  windowsHide: true,
169
- shell: false
426
+ shell: false,
427
+ ...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
170
428
  },
171
429
  (err) => {
430
+ options.signal?.removeEventListener("abort", onAbort);
172
431
  if (timedOut) {
173
432
  resolvePromise({
174
433
  code: null,
@@ -240,14 +499,15 @@ async function probeRunner(runtime, probeArg = "--version", options) {
240
499
  return result.code === 0;
241
500
  }
242
501
  function withinProject(p) {
243
- return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
502
+ const cwd = process.cwd();
503
+ return withinProjectPath(cwd, p) || relative2(cwd, p) === ".";
244
504
  }
245
505
  function locateRunnerEntry(runtime, projectRoot) {
246
- const root = resolve(projectRoot);
506
+ const root = resolve2(projectRoot);
247
507
  const candidates = [
248
- resolve(root, "node_modules", ".bin", runtime.executable),
249
- resolve(root, "node_modules", ".bin", `${runtime.executable}.cmd`),
250
- resolve(root, "node_modules", ".bin", `${runtime.executable}.ps1`)
508
+ resolve2(root, "node_modules", ".bin", runtime.executable),
509
+ resolve2(root, "node_modules", ".bin", `${runtime.executable}.cmd`),
510
+ resolve2(root, "node_modules", ".bin", `${runtime.executable}.ps1`)
251
511
  ];
252
512
  for (const c of candidates) {
253
513
  if (existsSync(c)) return c;
@@ -265,6 +525,7 @@ function collectSourceFiles(root, opts) {
265
525
  }
266
526
  if (!s.isDirectory()) return files;
267
527
  const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
528
+ const excludeSet = new Set(exclude);
268
529
  function walk(dir, depth) {
269
530
  if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
270
531
  let entries;
@@ -273,9 +534,10 @@ function collectSourceFiles(root, opts) {
273
534
  } catch {
274
535
  return;
275
536
  }
537
+ entries.sort();
276
538
  for (const entry of entries) {
277
- if (exclude.includes(entry)) continue;
278
- const full = resolve(dir, entry);
539
+ if (excludeSet.has(entry)) continue;
540
+ const full = resolve2(dir, entry);
279
541
  let st;
280
542
  try {
281
543
  st = statSync(full);
@@ -292,18 +554,66 @@ function collectSourceFiles(root, opts) {
292
554
  walk(root, 0);
293
555
  return files;
294
556
  }
557
+ async function collectSourceFilesAsync(root, opts) {
558
+ const { readdir, stat } = await import("node:fs/promises");
559
+ const files = [];
560
+ try {
561
+ const s = await stat(root);
562
+ if (s.isFile()) {
563
+ if (matchesExtension(root, opts.extensions)) files.push(root);
564
+ return files;
565
+ }
566
+ if (!s.isDirectory()) return files;
567
+ } catch {
568
+ return files;
569
+ }
570
+ const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
571
+ const excludeSet = new Set(exclude);
572
+ async function walk(dir, depth) {
573
+ if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
574
+ let entries;
575
+ try {
576
+ entries = await readdir(dir, { withFileTypes: true });
577
+ } catch {
578
+ return;
579
+ }
580
+ entries.sort((a, b) => a.name.localeCompare(b.name));
581
+ for (const entry of entries) {
582
+ if (excludeSet.has(entry.name)) continue;
583
+ const full = resolve2(dir, entry.name);
584
+ if (entry.isDirectory()) {
585
+ await walk(full, depth + 1);
586
+ } else if (entry.isFile() && matchesExtension(full, opts.extensions)) {
587
+ files.push(full);
588
+ }
589
+ }
590
+ }
591
+ await walk(root, 0);
592
+ return files;
593
+ }
295
594
  function matchesExtension(p, exts) {
296
- return exts.includes(extname(p).toLowerCase());
595
+ return exts.includes(extname2(p).toLowerCase());
297
596
  }
298
597
  export {
598
+ BoundedMap,
599
+ BoundedSet,
600
+ UNSERIALIZABLE,
601
+ clearLocalBinCache,
299
602
  collectSourceFiles,
603
+ collectSourceFilesAsync,
604
+ findOnPath,
300
605
  locateRunnerEntry,
301
606
  matchesExtension,
302
607
  parseLlmJsonObject,
303
608
  probeRunner,
609
+ resolveExecInvocation,
610
+ resolveFirstNodeBin,
611
+ resolveNodeBin,
304
612
  resolveRunnerCommand,
613
+ resolveWin32Command,
305
614
  runOptionalPluginLlm,
306
615
  runRunnerCommand,
616
+ safeJsonStringify,
307
617
  sanitizeRunnerPath,
308
618
  stripOuterMarkdownFence,
309
619
  withinProject
@@ -34,7 +34,7 @@
34
34
  *
35
35
  * @public
36
36
  */
37
- import type { Plugin } from '@wrongstack/core';
37
+ import type { Plugin } from '@wrongstack/core/types';
38
38
  declare const plugin: Plugin;
39
39
  export default plugin;
40
40
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema-evolution-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AA0M/C,QAAA,MAAM,MAAM,EAAE,MAgNb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema-evolution-guard/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AA0MrD,QAAA,MAAM,MAAM,EAAE,MAgNb,CAAC;eAEa,MAAM"}
@@ -4,6 +4,11 @@ import { basename as basename2 } from "node:path";
4
4
 
5
5
  // src/runtime/index.ts
6
6
  import { basename, extname, isAbsolute, relative, resolve } from "node:path";
7
+
8
+ // src/runtime/local-bin.ts
9
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
10
+
11
+ // src/runtime/index.ts
7
12
  var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
8
13
  function hasLeadingDash(arg) {
9
14
  return arg.length > 0 && arg.startsWith("-");
@@ -16,7 +21,8 @@ function withinProjectPath(projectRoot, candidate) {
16
21
  return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
17
22
  }
18
23
  function withinProject(p) {
19
- return withinProjectPath(process.cwd(), p) || relative(process.cwd(), p) === ".";
24
+ const cwd = process.cwd();
25
+ return withinProjectPath(cwd, p) || relative(cwd, p) === ".";
20
26
  }
21
27
 
22
28
  // src/schema-evolution-guard/index.ts
@@ -26,7 +26,7 @@
26
26
  * They share the same threat model but act at different points in the
27
27
  * pipeline.
28
28
  */
29
- import type { Plugin } from '@wrongstack/core';
29
+ import type { Plugin } from '@wrongstack/core/types';
30
30
  declare const plugin: Plugin;
31
31
  export default plugin;
32
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secret-scanner/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAqd/C,QAAA,MAAM,MAAM,EAAE,MAgOb,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/secret-scanner/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAwmBrD,QAAA,MAAM,MAAM,EAAE,MAgOb,CAAC;eAEa,MAAM"}