@wrongstack/plugins 0.308.6 → 0.309.0

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 (51) hide show
  1. package/dist/accessibility-auditor.js +26 -82
  2. package/dist/agent-handoff.js +16 -26
  3. package/dist/auto-i18n-extractor.js +19 -23
  4. package/dist/branch-guard.js +19 -111
  5. package/dist/changelog-writer.js +20 -133
  6. package/dist/code-metrics.js +26 -71
  7. package/dist/commit-validator.js +16 -14
  8. package/dist/config-validator.js +18 -22
  9. package/dist/cost-tracker.js +15 -96
  10. package/dist/dead-code-detector.js +27 -31
  11. package/dist/dependency-vulnerability-gate.js +18 -15
  12. package/dist/diff-summary.js +19 -128
  13. package/dist/doc-sync-guard.js +24 -39
  14. package/dist/duplicate-code-detector.js +30 -169
  15. package/dist/feature-flag-tracker.js +26 -71
  16. package/dist/file-watcher.js +19 -23
  17. package/dist/format-on-save.js +25 -214
  18. package/dist/import-organizer.js +31 -106
  19. package/dist/index.js +452 -1236
  20. package/dist/interface-contract-guard.js +26 -71
  21. package/dist/lint-gate.js +19 -111
  22. package/dist/migration-planner.js +28 -120
  23. package/dist/notify-hub.js +18 -28
  24. package/dist/path-guard.js +27 -102
  25. package/dist/pr-drafter.js +18 -16
  26. package/dist/prompt-firewall.js +8 -205
  27. package/dist/refactor-suggester.js +27 -166
  28. package/dist/release-notes-generator.js +6 -35
  29. package/dist/runtime/bounded-map.d.ts +2 -85
  30. package/dist/runtime/credential-patterns.d.ts +2 -41
  31. package/dist/runtime/h1-state.d.ts +2 -61
  32. package/dist/runtime/handles.d.ts +2 -45
  33. package/dist/runtime/index.d.ts +8 -180
  34. package/dist/runtime/llm.d.ts +2 -43
  35. package/dist/runtime/local-bin.d.ts +2 -119
  36. package/dist/runtime/redos-guard.d.ts +2 -68
  37. package/dist/runtime/safe-json.d.ts +2 -24
  38. package/dist/runtime/sandbox.d.ts +2 -58
  39. package/dist/runtime.js +1 -868
  40. package/dist/schema-evolution-guard.js +20 -24
  41. package/dist/secret-scanner.js +22 -146
  42. package/dist/security-hotspot-scanner.js +24 -154
  43. package/dist/session-recap.js +16 -14
  44. package/dist/spec-linker.js +19 -17
  45. package/dist/template-engine.js +22 -37
  46. package/dist/test-coverage-gate.js +19 -34
  47. package/dist/test-generator.js +6 -35
  48. package/dist/test-runner-gate.js +34 -143
  49. package/dist/todo-listener.js +17 -38
  50. package/dist/type-gate.js +23 -311
  51. package/package.json +4 -3
package/dist/index.js CHANGED
@@ -1,699 +1,25 @@
1
- // src/accessibility-auditor/index.ts
2
- import { readFile } from "node:fs/promises";
3
- import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
4
-
5
- // src/runtime/index.ts
6
- import { execFile } from "node:child_process";
7
- import { basename, extname as extname2, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
8
-
9
- // src/runtime/llm.ts
10
- function stripOuterMarkdownFence(text) {
11
- const trimmed = text.trim();
12
- const match = trimmed.match(/^```(?:[a-z0-9_-]+)?\s*\r?\n([\s\S]*?)\r?\n```$/i);
13
- return (match?.[1] ?? trimmed).trim();
14
- }
15
- function parseLlmJsonObject(text) {
16
- const candidate = stripOuterMarkdownFence(text);
17
- try {
18
- const parsed = JSON.parse(candidate);
19
- return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
20
- } catch {
21
- return null;
22
- }
23
- }
24
- async function runOptionalPluginLlm(request) {
25
- if (!request.requested) {
26
- return { used: false, value: null, fallbackReason: "not-requested" };
27
- }
28
- if (!request.api.llm) {
29
- return { used: false, value: null, fallbackReason: "unavailable" };
30
- }
31
- if (request.options?.signal?.aborted) {
32
- return { used: false, value: null, fallbackReason: "cancelled" };
33
- }
34
- try {
35
- const response = await request.api.llm.complete(request.prompt, request.options);
36
- const parsed = request.parse(response.text);
37
- if (parsed === null) {
38
- request.api.log.warn(`${request.label}: ignored invalid LLM response`);
39
- return { used: false, value: null, fallbackReason: "invalid-response" };
40
- }
41
- return { used: true, value: parsed, fallbackReason: null };
42
- } catch (error) {
43
- const cancelled = request.options?.signal?.aborted === true;
44
- request.api.log.warn(`${request.label}: LLM enrichment failed; using deterministic fallback`, {
45
- error: error instanceof Error ? error.message : String(error)
46
- });
47
- return {
48
- used: false,
49
- value: null,
50
- fallbackReason: cancelled ? "cancelled" : "provider-error"
51
- };
52
- }
53
- }
54
- async function runOptionalPluginCouncil(request) {
55
- if (!request.requested) {
56
- return { used: false, value: null, fallbackReason: "not-requested" };
57
- }
58
- if (request.options?.signal?.aborted) {
59
- return { used: false, value: null, fallbackReason: "cancelled" };
60
- }
61
- const council = request.api.llm?.council;
62
- if (council) {
63
- try {
64
- const result = await council(request.prompt, {
65
- ...request.context ? { context: request.context } : {},
66
- ...request.profile ? { profile: request.profile } : {},
67
- ...request.councilOptions ? { options: request.councilOptions } : {},
68
- ...request.options?.signal ? { signal: request.options.signal } : {}
69
- });
70
- if (result.status === "cancelled") {
71
- return { used: false, value: null, fallbackReason: "cancelled" };
72
- }
73
- const parsed = result.status === "decided" ? request.parse(result.answer ?? "") : null;
74
- if (parsed !== null) return { used: true, value: parsed, fallbackReason: null };
75
- request.api.log.warn(
76
- `${request.label}: Council did not return a valid answer; trying One Shot`,
77
- {
78
- status: result.status,
79
- resolution: result.resolution
80
- }
81
- );
82
- } catch (error) {
83
- if (request.options?.signal?.aborted) {
84
- return { used: false, value: null, fallbackReason: "cancelled" };
85
- }
86
- request.api.log.warn(`${request.label}: Council failed; trying One Shot`, {
87
- error: error instanceof Error ? error.message : String(error)
88
- });
89
- }
90
- }
91
- return runOptionalPluginLlm(request);
92
- }
93
-
94
- // src/runtime/local-bin.ts
95
- import { createRequire } from "node:module";
96
- import { delimiter, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
97
- import { accessSync, constants, readFileSync } from "node:fs";
98
- import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
99
- function resolveExecInvocation(command, args = []) {
100
- const resolved = resolveWin32Command(command);
101
- const normalizedResolved = resolved.toLowerCase();
102
- const needsShell = process.platform === "win32" && (normalizedResolved.endsWith(".cmd") || normalizedResolved.endsWith(".bat"));
103
- if (needsShell) {
104
- const shim = buildWin32CmdShimInvocation(resolved, args);
105
- return { cmd: shim.command, args: shim.args, windowsVerbatimArguments: true };
106
- }
107
- return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
108
- }
109
- function findOnPath(cmd) {
110
- if (!cmd) return null;
111
- const exists = (p) => {
112
- try {
113
- accessSync(p, constants.X_OK);
114
- return true;
115
- } catch {
116
- return false;
117
- }
118
- };
119
- if (cmd.includes("/") || cmd.includes("\\")) {
120
- return exists(cmd) ? resolve(cmd) : null;
121
- }
122
- const suffixes = process.platform === "win32" && extname(cmd) === "" ? (process.env["PATHEXT"] ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean) : [""];
123
- for (const dir of (process.env["PATH"] ?? "").split(delimiter)) {
124
- if (!dir) continue;
125
- const base = join(dir, cmd);
126
- for (const suffix of suffixes) {
127
- const candidate = `${base}${suffix}`;
128
- if (exists(candidate)) return candidate;
129
- }
130
- }
131
- return null;
132
- }
133
- function isInside(parent, candidate) {
134
- const rel = relative(parent, candidate);
135
- return rel === "" || !rel.startsWith(`..${sep}`) && rel !== ".." && !isAbsolute(rel);
136
- }
137
- var binCache = /* @__PURE__ */ new Map();
138
- var BIN_CACHE_MAX = 64;
139
- var NEGATIVE_BIN_CACHE_TTL_MS = 5e3;
140
- function cachePut(key, value) {
141
- while (binCache.size >= BIN_CACHE_MAX) {
142
- const oldest = binCache.keys().next().value;
143
- if (oldest === void 0) break;
144
- binCache.delete(oldest);
145
- }
146
- binCache.set(key, { value, cachedAt: Date.now() });
147
- return value;
148
- }
149
- function clearLocalBinCache() {
150
- binCache.clear();
151
- }
152
- function resolveNodeBin(packageName, binName, cwd, extraArgs = []) {
153
- const key = `${packageName}|${binName}|${cwd}`;
154
- const cached = binCache.get(key);
155
- if (cached !== void 0) {
156
- if (cached.value !== null || Date.now() - cached.cachedAt < NEGATIVE_BIN_CACHE_TTL_MS) {
157
- return cached.value === null ? null : { ...cached.value, args: [cached.value.entry, ...extraArgs] };
158
- }
159
- binCache.delete(key);
160
- }
161
- let resolved = null;
162
- try {
163
- const requireFromProject = createRequire(resolve(cwd, "package.json"));
164
- const packagePath = requireFromProject.resolve(`${packageName}/package.json`);
165
- const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
166
- const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[binName] ?? Object.values(packageJson.bin ?? {})[0];
167
- if (relativeBin && !isAbsolute(relativeBin)) {
168
- const packageDir = dirname(packagePath);
169
- const entry = resolve(packageDir, relativeBin);
170
- if (isInside(packageDir, entry)) {
171
- resolved = { cmd: process.execPath, args: [entry], entry };
172
- }
173
- }
174
- } catch {
175
- resolved = null;
176
- }
177
- cachePut(key, resolved);
178
- return resolved === null ? null : { ...resolved, args: [resolved.entry, ...extraArgs] };
179
- }
180
- function resolveFirstNodeBin(candidates, cwd) {
181
- for (const c of candidates) {
182
- const hit = resolveNodeBin(c.packageName, c.binName, cwd, c.args ?? []);
183
- if (hit) return { ...hit, packageName: c.packageName, binName: c.binName };
184
- }
185
- return null;
186
- }
187
-
188
- // src/runtime/bounded-map.ts
189
- var BoundedMap = class {
190
- map = /* @__PURE__ */ new Map();
191
- max;
192
- ttlMs;
193
- now;
194
- /** Entries dropped to stay under `max`. Surfaced by plugin health(). */
195
- evictions = 0;
196
- constructor(options) {
197
- const normalizedMax = Math.floor(options.max);
198
- this.max = Number.isSafeInteger(normalizedMax) ? Math.max(1, normalizedMax) : 1;
199
- this.ttlMs = options.ttlMs;
200
- this.now = options.now ?? Date.now;
201
- }
202
- expired(entry) {
203
- return this.ttlMs !== void 0 && this.now() - entry.storedAt > this.ttlMs;
204
- }
205
- get(key) {
206
- const entry = this.map.get(key);
207
- if (entry === void 0) return void 0;
208
- if (this.expired(entry)) {
209
- this.map.delete(key);
210
- return void 0;
211
- }
212
- this.map.delete(key);
213
- this.map.set(key, entry);
214
- return entry.value;
215
- }
216
- /**
217
- * Read without promoting the key to most-recently-used. Use for
218
- * diagnostics that must not perturb the eviction order.
219
- */
220
- peek(key) {
221
- const entry = this.map.get(key);
222
- if (entry === void 0 || this.expired(entry)) return void 0;
223
- return entry.value;
224
- }
225
- has(key) {
226
- const entry = this.map.get(key);
227
- if (entry === void 0) return false;
228
- if (this.expired(entry)) {
229
- this.map.delete(key);
230
- return false;
231
- }
232
- return true;
233
- }
234
- set(key, value) {
235
- this.map.delete(key);
236
- this.map.set(key, { value, storedAt: this.now() });
237
- while (this.map.size > this.max) {
238
- const coldest = this.map.keys().next().value;
239
- if (coldest === void 0) break;
240
- this.map.delete(coldest);
241
- this.evictions += 1;
242
- }
243
- return this;
244
- }
245
- delete(key) {
246
- return this.map.delete(key);
247
- }
248
- clear() {
249
- this.map.clear();
250
- this.evictions = 0;
251
- }
252
- get size() {
253
- return this.map.size;
254
- }
255
- /** How many entries have been dropped to respect `max`, since the last clear. */
256
- get evictionCount() {
257
- return this.evictions;
258
- }
259
- /** Drop every expired entry. Cheap enough to call from a status tool. */
260
- prune() {
261
- if (this.ttlMs === void 0) return 0;
262
- let removed = 0;
263
- for (const [key, entry] of this.map) {
264
- if (this.expired(entry)) {
265
- this.map.delete(key);
266
- removed += 1;
267
- }
268
- }
269
- return removed;
270
- }
271
- /** Live (non-expired) entries, coldest first. */
272
- *entries() {
273
- for (const [key, entry] of this.map) {
274
- if (!this.expired(entry)) yield [key, entry.value];
275
- }
276
- }
277
- [Symbol.iterator]() {
278
- return this.entries();
279
- }
280
- };
281
- var BoundedSet = class {
282
- inner;
283
- constructor(options) {
284
- this.inner = new BoundedMap(options);
285
- }
286
- has(value) {
287
- return this.inner.has(value);
288
- }
289
- add(value) {
290
- this.inner.set(value, true);
291
- return this;
292
- }
293
- delete(value) {
294
- return this.inner.delete(value);
295
- }
296
- clear() {
297
- this.inner.clear();
298
- }
299
- get size() {
300
- return this.inner.size;
301
- }
302
- /** How many entries have been dropped to respect `max`, since the last clear. */
303
- get evictionCount() {
304
- return this.inner.evictionCount;
305
- }
306
- *values() {
307
- for (const [key] of this.inner) yield key;
308
- }
309
- [Symbol.iterator]() {
310
- return this.values();
311
- }
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
312
12
  };
13
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
313
14
 
314
- // src/runtime/safe-json.ts
315
- var UNSERIALIZABLE = "[unserializable]";
316
- function safeJsonStringify(value, indent) {
317
- try {
318
- const stack = [];
319
- const out = JSON.stringify(
320
- value,
321
- function replacer(_key, val) {
322
- if (typeof val === "bigint") return `${val.toString()}n`;
323
- if (val === null || typeof val !== "object") return val;
324
- while (stack.length > 0 && stack[stack.length - 1] !== this) stack.pop();
325
- if (stack.includes(val)) return "[circular]";
326
- stack.push(val);
327
- return val;
328
- },
329
- indent
330
- );
331
- return out ?? String(value);
332
- } catch {
333
- return UNSERIALIZABLE;
334
- }
335
- }
336
-
337
- // src/runtime/handles.ts
338
- function releaseHandle(off) {
339
- if (off) {
340
- try {
341
- off();
342
- } catch {
343
- }
344
- }
345
- return null;
346
- }
347
-
348
- // src/runtime/redos-guard.ts
349
- import { Worker } from "node:worker_threads";
350
- function withReDoSGuard(re, input, budgetMs = 50, options = {}) {
351
- const opts = { budgetMs, ...options };
352
- const start = Date.now();
353
- const workerSource = buildWorkerSource(re.source, input, re.flags);
354
- const worker = new Worker(workerSource, {
355
- eval: true,
356
- name: `redos-guard:${re.source.slice(0, 32)}`
357
- });
358
- return new Promise((resolve29) => {
359
- let settled = false;
360
- const onMessage = (msg) => {
361
- if (settled) return;
362
- settled = true;
363
- clearTimeout(timer);
364
- worker.terminate().catch(() => {
365
- });
366
- if (!msg.ok) {
367
- resolve29({ timedOut: true, match: null });
368
- return;
369
- }
370
- resolve29({ timedOut: false, match: msg.match });
371
- };
372
- const onError = () => {
373
- if (settled) return;
374
- settled = true;
375
- clearTimeout(timer);
376
- worker.terminate().catch(() => {
377
- });
378
- resolve29({ timedOut: true, match: null });
379
- };
380
- const timer = setTimeout(() => {
381
- if (settled) return;
382
- settled = true;
383
- const elapsedMs = Date.now() - start;
384
- worker.terminate().catch(() => {
385
- });
386
- try {
387
- opts.onTimeout?.({
388
- regex: re,
389
- input,
390
- budgetMs: opts.budgetMs,
391
- elapsedMs
392
- });
393
- } catch {
394
- }
395
- resolve29({ timedOut: true, match: null });
396
- }, opts.budgetMs);
397
- timer.unref?.();
398
- worker.on("message", onMessage);
399
- worker.on("error", onError);
400
- });
401
- }
402
- function buildWorkerSource(source, input, flags) {
403
- const S = JSON.stringify(source);
404
- const I = JSON.stringify(input);
405
- const F = JSON.stringify(flags);
406
- return `
407
- const { parentPort } = require('node:worker_threads');
408
- const source = ${S};
409
- const input = ${I};
410
- const flags = ${F};
411
- try {
412
- const re = new RegExp(source, flags);
413
- const match = re.exec(input);
414
- // parentPort.postMessage, NOT bare postMessage: with eval:true
415
- // workers this Node version does not expose the bare postMessage
416
- // global \u2014 the worker throws ReferenceError at startup and the
417
- // host misreads it as a timeout (positive-path regression).
418
- parentPort.postMessage({ ok: true, match });
419
- } catch (err) {
420
- parentPort.postMessage({ ok: false, error: err && err.message ? err.message : String(err) });
421
- }
422
- `;
423
- }
15
+ // src/accessibility-auditor/index.ts
16
+ import { readFile } from "node:fs/promises";
17
+ import { isAbsolute, relative, resolve } from "node:path";
424
18
 
425
19
  // src/runtime/index.ts
426
- var META_CHARS = /["'`;&|<>\r\n]/;
427
- var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
428
- function hasLeadingDash(arg) {
429
- return arg.length > 0 && arg.startsWith("-");
430
- }
431
- function safeSplit(command) {
432
- const trimmed = command.trim();
433
- if (!trimmed || META_CHARS.test(trimmed)) return null;
434
- return trimmed.split(/\s+/).filter(Boolean);
435
- }
436
- function withinProjectPath(projectRoot, candidate) {
437
- if (candidate.length === 0 || candidate.length > 4096) return false;
438
- if (hasLeadingDash(candidate)) return false;
439
- const resolved = isAbsolute2(candidate) ? resolve2(candidate) : resolve2(projectRoot, candidate);
440
- const rel = relative2(projectRoot, resolved);
441
- return rel === "" || !rel.startsWith("..") && !isAbsolute2(rel);
442
- }
443
- function everyFlagAllowed(allowed, args) {
444
- for (const arg of args) {
445
- if (!hasLeadingDash(arg)) continue;
446
- if (allowed === null) return false;
447
- if (!allowed.has(arg)) return false;
448
- }
449
- return true;
450
- }
451
- function sanitizeRunnerPath(value, options = {}) {
452
- if (!value || hasLeadingDash(value)) return null;
453
- const projectRoot = resolve2(options.projectRoot ?? process.cwd());
454
- if (!withinProjectPath(projectRoot, value)) return null;
455
- return isAbsolute2(value) ? resolve2(value) : resolve2(projectRoot, value);
456
- }
457
- function resolveRunnerCommand(runtime, command, options = {}) {
458
- const tokens = safeSplit(command);
459
- if (!tokens || tokens.length === 0) return null;
460
- const projectRoot = resolve2(options.projectRoot ?? process.cwd());
461
- const launcher = runtime.packageManager;
462
- const [head, second, ...rest] = tokens;
463
- if (!head) return null;
464
- const display = tokens.join(" ");
465
- if (launcher !== "none" && tokens.length === 1 && head === launcher) {
466
- return null;
467
- }
468
- if (head === runtime.executable) {
469
- if (!everyFlagAllowed(runtime.allowedFlags, [second, ...rest].filter((v) => Boolean(v)))) {
470
- return null;
471
- }
472
- return {
473
- cmd: head,
474
- args: [second, ...rest].filter((v) => Boolean(v)),
475
- display
476
- };
477
- }
478
- if (launcher !== "none" && head === launcher && runtime.subcommands.length === 0 && second === runtime.executable) {
479
- if (!everyFlagAllowed(runtime.allowedFlags, rest)) return null;
480
- return { cmd: head, args: [second, ...rest], display };
481
- }
482
- if (launcher !== "none" && head === launcher && runtime.subcommands.length > 0) {
483
- const subcommand = runtime.subcommands[0];
484
- const exe = rest[0];
485
- if (second === subcommand && exe === runtime.executable) {
486
- const tail = rest.slice(1);
487
- if (!everyFlagAllowed(runtime.allowedFlags, tail)) return null;
488
- return { cmd: head, args: [second, exe, ...tail], display };
489
- }
490
- }
491
- if (isAbsolute2(head)) {
492
- if (!withinProjectPath(projectRoot, head)) return null;
493
- const base = basename(head);
494
- if (base !== runtime.executable && base !== launcher) return null;
495
- if (second !== runtime.executable) return null;
496
- if (!everyFlagAllowed(runtime.allowedFlags, rest)) return null;
497
- return { cmd: head, args: [second, ...rest], display };
498
- }
499
- return null;
500
- }
501
- function runRunnerCommand(argv, options) {
502
- if (argv.length === 0) {
503
- return Promise.resolve({
504
- code: null,
505
- stdout: "",
506
- stderr: "runtime helper: empty argv",
507
- timedOut: false,
508
- spawnError: true
509
- });
510
- }
511
- return new Promise((resolvePromise) => {
512
- const projectRoot = resolve2(options.projectRoot ?? process.cwd());
513
- const trimmedCwd = options.cwd.trim();
514
- if (!withinProjectPath(projectRoot, trimmedCwd)) {
515
- resolvePromise({
516
- code: null,
517
- stdout: "",
518
- stderr: "runtime helper: cwd outside project",
519
- timedOut: false,
520
- spawnError: true
521
- });
522
- return;
523
- }
524
- let timedOut = false;
525
- let spawnErrored = false;
526
- const start = Date.now();
527
- const stdoutChunks = [];
528
- const stderrChunks = [];
529
- let stdoutBytes = 0;
530
- let stderrBytes = 0;
531
- const onAbort = () => {
532
- timedOut = true;
533
- };
534
- let invocation;
535
- try {
536
- invocation = resolveExecInvocation(argv[0], argv.slice(1));
537
- } catch (err) {
538
- resolvePromise({
539
- code: null,
540
- stdout: "",
541
- stderr: `runtime helper: ${err instanceof Error ? err.message : String(err)}`,
542
- timedOut: false,
543
- spawnError: true
544
- });
545
- return;
546
- }
547
- options.signal?.addEventListener("abort", onAbort, { once: true });
548
- const child = execFile(
549
- invocation.cmd,
550
- invocation.args,
551
- {
552
- cwd: trimmedCwd,
553
- timeout: options.timeoutMs,
554
- signal: options.signal,
555
- maxBuffer: MAX_BUFFER_BYTES,
556
- // execFile defaults `encoding` to 'utf8', which makes the
557
- // stdout/stderr `data` events emit *strings*. The chunk arrays
558
- // below are typed Buffer[] and every consumer runs them through
559
- // Buffer.concat(...).toString('utf8'), which throws
560
- // ERR_INVALID_ARG_TYPE on any non-empty string output. Pin the
561
- // streams to buffers so the declared contract holds (regression:
562
- // runRunnerCommand crashed on any child that actually wrote
563
- // output; only the maxBuffer fixture exercised this path).
564
- encoding: "buffer",
565
- windowsHide: true,
566
- shell: false,
567
- ...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
568
- },
569
- (err) => {
570
- options.signal?.removeEventListener("abort", onAbort);
571
- if (timedOut) {
572
- resolvePromise({
573
- code: null,
574
- stdout: Buffer.concat(stdoutChunks).toString("utf8"),
575
- stderr: Buffer.concat(stderrChunks).toString("utf8"),
576
- timedOut: true,
577
- spawnError: false
578
- });
579
- return;
580
- }
581
- if (spawnErrored) {
582
- resolvePromise({
583
- code: 127,
584
- stdout: Buffer.concat(stdoutChunks).toString("utf8"),
585
- stderr: Buffer.concat(stderrChunks).toString("utf8"),
586
- timedOut: false,
587
- spawnError: true
588
- });
589
- return;
590
- }
591
- if (err) {
592
- const anyErr = err;
593
- if ((anyErr.killed === true || anyErr.signal === "SIGTERM") && // maxBuffer overflow must NOT be misreported as a timeout
594
- // — it's a real failure (the child wrote too much) and
595
- // downstream callers (type-gate/index.ts:227) return
596
- // null on timedOut=true, which would silently swallow
597
- // maxBuffer overflow into a confusing empty-output
598
- // result. Skip the timeout resolve when the err shape
599
- // names maxBuffer explicitly.
600
- !/maxBuffer length exceeded/i.test(anyErr.message ?? "") && // And only count it as a timeout if the wall clock has
601
- // actually elapsed past the budget. External SIGTERMs and
602
- // races against the exit handler don't satisfy this.
603
- Date.now() - start >= options.timeoutMs) {
604
- resolvePromise({
605
- code: null,
606
- stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
607
- stderr: Buffer.concat(stderrChunks).toString("utf-8"),
608
- timedOut: true,
609
- spawnError: false
610
- });
611
- return;
612
- }
613
- const code = typeof anyErr.code === "number" ? anyErr.code : 1;
614
- resolvePromise({
615
- code,
616
- stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
617
- stderr: Buffer.concat(stderrChunks).toString("utf-8"),
618
- timedOut: false,
619
- spawnError: false
620
- });
621
- return;
622
- }
623
- resolvePromise({
624
- code: 0,
625
- stdout: Buffer.concat(stdoutChunks).toString("utf8"),
626
- stderr: Buffer.concat(stderrChunks).toString("utf8"),
627
- timedOut: false,
628
- spawnError: false
629
- });
630
- }
631
- );
632
- child.on("exit", (_code, signal) => {
633
- if (signal !== null && Date.now() - start >= options.timeoutMs) {
634
- timedOut = true;
635
- }
636
- });
637
- child.stdout?.on("data", (chunk) => {
638
- stdoutBytes += chunk.length;
639
- if (stdoutBytes <= MAX_BUFFER_BYTES) stdoutChunks.push(chunk);
640
- });
641
- child.stderr?.on("data", (chunk) => {
642
- stderrBytes += chunk.length;
643
- if (stderrBytes <= MAX_BUFFER_BYTES) stderrChunks.push(chunk);
644
- });
645
- child.on("error", (err) => {
646
- if (err.code === "ENOENT" || err.code === "EPERM" || err.code === "EACCES") {
647
- spawnErrored = true;
648
- }
649
- });
650
- });
651
- }
652
- function withinProject(p) {
653
- const cwd = process.cwd();
654
- return withinProjectPath(cwd, p) || relative2(cwd, p) === ".";
655
- }
656
- var DEFAULT_EXCLUDE_DIRS = ["node_modules", "dist", ".git", "coverage"];
657
- async function collectSourceFilesAsync(root, opts) {
658
- const { readdir: readdir6, stat: stat8 } = await import("node:fs/promises");
659
- const files = [];
660
- try {
661
- const s = await stat8(root);
662
- if (s.isFile()) {
663
- if (matchesExtension(root, opts.extensions)) files.push(root);
664
- return files;
665
- }
666
- if (!s.isDirectory()) return files;
667
- } catch {
668
- return files;
669
- }
670
- const exclude = opts.excludeDirs ?? DEFAULT_EXCLUDE_DIRS;
671
- const excludeSet = new Set(exclude);
672
- async function walk(dir, depth) {
673
- if (opts.maxDepth !== void 0 && depth > opts.maxDepth) return;
674
- let entries;
675
- try {
676
- entries = await readdir6(dir, { withFileTypes: true });
677
- } catch {
678
- return;
679
- }
680
- entries.sort((a, b) => a.name.localeCompare(b.name));
681
- for (const entry of entries) {
682
- if (excludeSet.has(entry.name)) continue;
683
- const full = resolve2(dir, entry.name);
684
- if (entry.isDirectory()) {
685
- await walk(full, depth + 1);
686
- } else if (entry.isFile() && matchesExtension(full, opts.extensions)) {
687
- files.push(full);
688
- }
689
- }
690
- }
691
- await walk(root, 0);
692
- return files;
693
- }
694
- function matchesExtension(p, exts) {
695
- return exts.includes(extname2(p).toLowerCase());
696
- }
20
+ var runtime_exports = {};
21
+ __reExport(runtime_exports, runtime_star);
22
+ import * as runtime_star from "@wrongstack/plugin-sdk/runtime";
697
23
 
698
24
  // src/accessibility-auditor/index.ts
699
25
  var API_VERSION = "^0.1.10";
@@ -780,7 +106,7 @@ async function auditFile(filePath, projectRoot) {
780
106
  const idsByValue = /* @__PURE__ */ new Map();
781
107
  function add(line, rule, severity, message, note) {
782
108
  findings.push({
783
- file: relative3(projectRoot, filePath),
109
+ file: relative(projectRoot, filePath),
784
110
  line,
785
111
  rule,
786
112
  severity,
@@ -879,9 +205,9 @@ async function auditFile(filePath, projectRoot) {
879
205
  }
880
206
  async function auditPath(rawPath, cfg) {
881
207
  const root = process.cwd();
882
- const resolved = isAbsolute3(rawPath) ? resolve3(rawPath) : resolve3(root, rawPath);
208
+ const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
883
209
  const exts = normalizeExtensions(cfg.includeExtensions);
884
- const files = await collectSourceFilesAsync(resolved, { extensions: exts });
210
+ const files = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
885
211
  const findings = [];
886
212
  let scannedFiles = 0;
887
213
  let truncated = false;
@@ -895,7 +221,7 @@ async function auditPath(rawPath, cfg) {
895
221
  }
896
222
  }
897
223
  return {
898
- path: relative3(root, resolved),
224
+ path: relative(root, resolved),
899
225
  findings: findings.slice(0, cfg.maxFindings),
900
226
  fileCount: files.length,
901
227
  scannedFiles,
@@ -968,7 +294,7 @@ var plugin = {
968
294
  state.findingCount = 0;
969
295
  state.hookInvocationCount = 0;
970
296
  state.lastResult = null;
971
- state.hookUnregister = releaseHandle(state.hookUnregister);
297
+ state.hookUnregister = (0, runtime_exports.releaseHandle)(state.hookUnregister);
972
298
  const cfg = readConfig(api.config.extensions?.["accessibility-auditor"]);
973
299
  const hook = async (input) => {
974
300
  if (!cfg.enabled || !cfg.onWriteEdit) return;
@@ -976,9 +302,9 @@ var plugin = {
976
302
  const inp = input.toolInput ?? {};
977
303
  const sourcePath = inp["path"];
978
304
  if (!sourcePath || typeof sourcePath !== "string") return;
979
- if (!withinProject(sourcePath)) return;
305
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
980
306
  const exts = normalizeExtensions(cfg.includeExtensions);
981
- if (!matchesExtension(sourcePath, exts)) return;
307
+ if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
982
308
  state.hookInvocationCount += 1;
983
309
  const result = await auditPath(sourcePath, cfg);
984
310
  state.auditCount += 1;
@@ -1020,7 +346,7 @@ var plugin = {
1020
346
  if (!rawPath || typeof rawPath !== "string") {
1021
347
  return { ok: false, error: "path is required" };
1022
348
  }
1023
- if (!withinProject(rawPath)) {
349
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
1024
350
  return { ok: false, error: "path must be inside the project" };
1025
351
  }
1026
352
  state.auditCount += 1;
@@ -1173,7 +499,7 @@ function buildBody(payload, cfg) {
1173
499
  if (cfg.includeResult && payload.result !== void 0) {
1174
500
  lines.push("## Result");
1175
501
  lines.push("```json");
1176
- lines.push(safeJsonStringify(payload.result, 2));
502
+ lines.push((0, runtime_exports.safeJsonStringify)(payload.result, 2));
1177
503
  lines.push("```");
1178
504
  lines.push("");
1179
505
  }
@@ -1414,10 +740,10 @@ var plugin2 = {
1414
740
  var agent_handoff_default = plugin2;
1415
741
 
1416
742
  // src/api-compatibility-gate/index.ts
1417
- import { execFile as execFile2 } from "node:child_process";
1418
- import { existsSync, readFileSync as readFileSync2 } from "node:fs";
743
+ import { execFile } from "node:child_process";
744
+ import { existsSync, readFileSync } from "node:fs";
1419
745
  import { readFile as readFile2 } from "node:fs/promises";
1420
- import { basename as basename2, dirname as dirname2, extname as extname3, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
746
+ import { basename, dirname, extname, isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
1421
747
  var API_VERSION3 = "^0.1.10";
1422
748
  var state3 = {
1423
749
  invocationCount: 0,
@@ -1481,25 +807,25 @@ function matchesAnyPattern(filePath, patterns) {
1481
807
  return patterns.some((p) => patternToRegex(p).test(normalized));
1482
808
  }
1483
809
  function resolveToProjectRoot(filePath) {
1484
- if (isAbsolute4(filePath)) return resolve4(filePath);
1485
- return resolve4(process.cwd(), filePath);
810
+ if (isAbsolute2(filePath)) return resolve2(filePath);
811
+ return resolve2(process.cwd(), filePath);
1486
812
  }
1487
813
  function withinProject2(filePath) {
1488
814
  if (typeof filePath !== "string" || filePath.length === 0 || filePath.length > 4096) return false;
1489
815
  const resolved = resolveToProjectRoot(filePath);
1490
- const rel = relative4(process.cwd(), resolved);
816
+ const rel = relative2(process.cwd(), resolved);
1491
817
  if (rel === "" || rel === ".") return true;
1492
818
  if (rel.startsWith("..")) return false;
1493
- if (isAbsolute4(rel)) return false;
819
+ if (isAbsolute2(rel)) return false;
1494
820
  return true;
1495
821
  }
1496
822
  function isPackageEntryPoint(filePath) {
1497
823
  const resolved = resolveToProjectRoot(filePath);
1498
- const dir = dirname2(resolved);
1499
- const pkgPath = resolve4(dir, "package.json");
824
+ const dir = dirname(resolved);
825
+ const pkgPath = resolve2(dir, "package.json");
1500
826
  if (!existsSync(pkgPath)) return false;
1501
827
  try {
1502
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
828
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
1503
829
  const entries = [];
1504
830
  if (pkg.main) entries.push(pkg.main);
1505
831
  if (pkg.module) entries.push(pkg.module);
@@ -1517,9 +843,9 @@ function isPackageEntryPoint(filePath) {
1517
843
  }
1518
844
  }
1519
845
  for (const entry of entries) {
1520
- const entryResolved = resolve4(dir, entry);
846
+ const entryResolved = resolve2(dir, entry);
1521
847
  if (entryResolved === resolved) return true;
1522
- if (basename2(dirname2(entryResolved)) === basename2(dirname2(resolved)) && basename2(entryResolved, extname3(entryResolved)) === basename2(resolved, extname3(resolved))) {
848
+ if (basename(dirname(entryResolved)) === basename(dirname(resolved)) && basename(entryResolved, extname(entryResolved)) === basename(resolved, extname(resolved))) {
1523
849
  return true;
1524
850
  }
1525
851
  }
@@ -1570,9 +896,9 @@ function extractExports(source) {
1570
896
  }
1571
897
  function readGitVersion(filePath) {
1572
898
  const resolved = resolveToProjectRoot(filePath);
1573
- const relPath = normalizePath(relative4(process.cwd(), resolved));
899
+ const relPath = normalizePath(relative2(process.cwd(), resolved));
1574
900
  return new Promise((resolveVersion) => {
1575
- execFile2(
901
+ execFile(
1576
902
  "git",
1577
903
  ["show", `HEAD:${relPath}`],
1578
904
  {
@@ -1774,14 +1100,14 @@ var plugin3 = {
1774
1100
  var api_compatibility_gate_default = plugin3;
1775
1101
 
1776
1102
  // src/auto-doc/index.ts
1777
- import { isAbsolute as isAbsolute5, relative as relative5, resolve as resolve5 } from "node:path";
1103
+ import { isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
1778
1104
  var AUTO_DOC_API_VERSION = "^0.1.10";
1779
1105
  function resolveProjectPath(rawPath, cwd = process.cwd()) {
1780
1106
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
1781
- const root = resolve5(cwd);
1782
- const resolved = isAbsolute5(rawPath) ? resolve5(rawPath) : resolve5(root, rawPath);
1783
- const rel = relative5(root, resolved);
1784
- if (rel === "" || !rel.startsWith("..") && !isAbsolute5(rel)) return resolved;
1107
+ const root = resolve3(cwd);
1108
+ const resolved = isAbsolute3(rawPath) ? resolve3(rawPath) : resolve3(root, rawPath);
1109
+ const rel = relative3(root, resolved);
1110
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute3(rel)) return resolved;
1785
1111
  return null;
1786
1112
  }
1787
1113
  var state4 = {
@@ -1962,10 +1288,10 @@ async function runAutoDoc(input, api) {
1962
1288
  continue;
1963
1289
  }
1964
1290
  try {
1965
- const { readFileSync: readFileSync17, writeFileSync: writeFileSync3 } = await import("node:fs");
1291
+ const { readFileSync: readFileSync16, writeFileSync: writeFileSync3 } = await import("node:fs");
1966
1292
  let content;
1967
1293
  try {
1968
- content = readFileSync17(safeFile, "utf-8");
1294
+ content = readFileSync16(safeFile, "utf-8");
1969
1295
  } catch {
1970
1296
  api.log.warn(`auto-doc: could not read file ${safeFile}`);
1971
1297
  continue;
@@ -2315,7 +1641,7 @@ var plugin5 = {
2315
1641
  var auto_escalate_default = plugin5;
2316
1642
 
2317
1643
  // src/auto-i18n-extractor/index.ts
2318
- import { readFileSync as readFileSync3 } from "node:fs";
1644
+ import { readFileSync as readFileSync2 } from "node:fs";
2319
1645
  var API_VERSION4 = "^0.1.10";
2320
1646
  var state6 = {
2321
1647
  filesScanned: 0,
@@ -2400,7 +1726,7 @@ function extractStrings(content, cfg) {
2400
1726
  }
2401
1727
  function readSourceFile(filePath) {
2402
1728
  try {
2403
- return readFileSync3(filePath, "utf-8");
1729
+ return readFileSync2(filePath, "utf-8");
2404
1730
  } catch {
2405
1731
  return null;
2406
1732
  }
@@ -2476,7 +1802,7 @@ var plugin6 = {
2476
1802
  const inp = input.toolInput ?? {};
2477
1803
  const sourcePath = inp["path"];
2478
1804
  if (!sourcePath || typeof sourcePath !== "string") return;
2479
- if (!withinProject(sourcePath)) return;
1805
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
2480
1806
  const ext = fileExtension(sourcePath);
2481
1807
  if (!cfg.fileExtensions.includes(ext)) {
2482
1808
  state6.skipped += 1;
@@ -2529,7 +1855,7 @@ ${lines.join("\n")}${more}`;
2529
1855
  if (typeof filePath !== "string" || !filePath) {
2530
1856
  return { ok: false, error: "path is required" };
2531
1857
  }
2532
- if (!withinProject(filePath)) {
1858
+ if (!(0, runtime_exports.withinProject)(filePath)) {
2533
1859
  return { ok: false, error: "path must be inside the project" };
2534
1860
  }
2535
1861
  const ext = fileExtension(filePath);
@@ -2636,7 +1962,7 @@ ${lines.join("\n")}${more}`;
2636
1962
  var auto_i18n_extractor_default = plugin6;
2637
1963
 
2638
1964
  // src/branch-guard/index.ts
2639
- import { execFile as execFile3 } from "node:child_process";
1965
+ import { execFile as execFile2 } from "node:child_process";
2640
1966
  var API_VERSION5 = "^0.1.10";
2641
1967
  var state7 = {
2642
1968
  invocationCount: 0,
@@ -2688,16 +2014,16 @@ function hasDisabledPluginEntry(raw) {
2688
2014
  return name === "branch-guard" || name === "@wrongstack/plugins/branch-guard";
2689
2015
  });
2690
2016
  }
2691
- var branchCache = new BoundedMap({ max: 64, ttlMs: 3e4 });
2017
+ var branchCache = new runtime_exports.BoundedMap({ max: 64, ttlMs: 3e4 });
2692
2018
  function runGit(args, cwd, signal) {
2693
- return new Promise((resolve29, reject) => {
2694
- execFile3(
2019
+ return new Promise((resolve27, reject) => {
2020
+ execFile2(
2695
2021
  "git",
2696
2022
  args,
2697
2023
  { encoding: "utf-8", timeout: 3e3, cwd, windowsHide: true, signal },
2698
2024
  (error, stdout) => {
2699
2025
  if (error) reject(error);
2700
- else resolve29(stdout);
2026
+ else resolve27(stdout);
2701
2027
  }
2702
2028
  );
2703
2029
  });
@@ -2798,8 +2124,8 @@ var plugin7 = {
2798
2124
  state7.invocationCount = 0;
2799
2125
  state7.blockCount = 0;
2800
2126
  state7.warnCount = 0;
2801
- state7.hookUnregister = releaseHandle(state7.hookUnregister);
2802
- state7.configUnregister = releaseHandle(state7.configUnregister);
2127
+ state7.hookUnregister = (0, runtime_exports.releaseHandle)(state7.hookUnregister);
2128
+ state7.configUnregister = (0, runtime_exports.releaseHandle)(state7.configUnregister);
2803
2129
  state7.lastBlock = null;
2804
2130
  branchCache.clear();
2805
2131
  let cfg = readHostConfig(api.config);
@@ -2945,11 +2271,11 @@ var plugin7 = {
2945
2271
  var branch_guard_default = plugin7;
2946
2272
 
2947
2273
  // src/changelog-writer/index.ts
2948
- import { readFileSync as readFileSync4, writeFileSync } from "node:fs";
2949
- import { isAbsolute as isAbsolute6, relative as relative6, resolve as resolve6 } from "node:path";
2274
+ import { readFileSync as readFileSync3, writeFileSync } from "node:fs";
2275
+ import { isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
2950
2276
  var state8 = {
2951
2277
  entries: [],
2952
- filesTouched: new BoundedSet({ max: 2e3 }),
2278
+ filesTouched: new runtime_exports.BoundedSet({ max: 2e3 }),
2953
2279
  commitsSeen: 0,
2954
2280
  writes: 0,
2955
2281
  polishes: 0,
@@ -2963,10 +2289,10 @@ var DEFAULTS6 = {
2963
2289
  maxEntries: 200
2964
2290
  };
2965
2291
  function resolveProjectPath2(rawPath, cwd = process.cwd()) {
2966
- const root = resolve6(cwd);
2967
- const resolved = isAbsolute6(rawPath) ? resolve6(rawPath) : resolve6(root, rawPath);
2968
- const rel = relative6(root, resolved);
2969
- if (rel === "" || !rel.startsWith("..") && !isAbsolute6(rel)) return resolved;
2292
+ const root = resolve4(cwd);
2293
+ const resolved = isAbsolute4(rawPath) ? resolve4(rawPath) : resolve4(root, rawPath);
2294
+ const rel = relative4(root, resolved);
2295
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute4(rel)) return resolved;
2970
2296
  return null;
2971
2297
  }
2972
2298
  function readConfig7(raw) {
@@ -3110,7 +2436,7 @@ var plugin8 = {
3110
2436
  },
3111
2437
  setup(api) {
3112
2438
  state8.entries = [];
3113
- state8.filesTouched = new BoundedSet({ max: 2e3 });
2439
+ state8.filesTouched = new runtime_exports.BoundedSet({ max: 2e3 });
3114
2440
  state8.commitsSeen = 0;
3115
2441
  state8.writes = 0;
3116
2442
  for (const off of state8.eventUnsubscribers) {
@@ -3260,7 +2586,7 @@ var plugin8 = {
3260
2586
  );
3261
2587
  let existing = null;
3262
2588
  try {
3263
- existing = readFileSync4(cfg.filePath, "utf-8");
2589
+ existing = readFileSync3(cfg.filePath, "utf-8");
3264
2590
  } catch {
3265
2591
  existing = null;
3266
2592
  }
@@ -3306,7 +2632,7 @@ var plugin8 = {
3306
2632
  filesTouched: state8.filesTouched.size
3307
2633
  };
3308
2634
  state8.entries = [];
3309
- state8.filesTouched = new BoundedSet({ max: 2e3 });
2635
+ state8.filesTouched = new runtime_exports.BoundedSet({ max: 2e3 });
3310
2636
  state8.commitsSeen = 0;
3311
2637
  state8.writes = 0;
3312
2638
  api.log.info("changelog-writer: teardown complete", { final });
@@ -3328,7 +2654,7 @@ var changelog_writer_default = plugin8;
3328
2654
 
3329
2655
  // src/checkpoint/index.ts
3330
2656
  import { mkdir, readFile as readFile3, stat, writeFile } from "node:fs/promises";
3331
- import { dirname as dirname3, isAbsolute as isAbsolute7, relative as relative7, resolve as resolve7 } from "node:path";
2657
+ import { dirname as dirname2, isAbsolute as isAbsolute5, relative as relative5, resolve as resolve5 } from "node:path";
3332
2658
  var state9 = {
3333
2659
  snapshots: [],
3334
2660
  nextId: 1,
@@ -3357,10 +2683,10 @@ function readConfig8(raw) {
3357
2683
  };
3358
2684
  }
3359
2685
  function resolveProjectPath3(rawPath, cwd = process.cwd()) {
3360
- const root = resolve7(cwd);
3361
- const resolved = isAbsolute7(rawPath) ? resolve7(rawPath) : resolve7(root, rawPath);
3362
- const rel = relative7(root, resolved);
3363
- if (rel === "" || !rel.startsWith("..") && !isAbsolute7(rel)) return resolved;
2686
+ const root = resolve5(cwd);
2687
+ const resolved = isAbsolute5(rawPath) ? resolve5(rawPath) : resolve5(root, rawPath);
2688
+ const rel = relative5(root, resolved);
2689
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute5(rel)) return resolved;
3364
2690
  return null;
3365
2691
  }
3366
2692
  function hashContent(s) {
@@ -3462,9 +2788,9 @@ var plugin9 = {
3462
2788
  const ti = input.toolInput ?? {};
3463
2789
  const raw = ti["path"] ?? ti["file_path"] ?? ti["filePath"];
3464
2790
  if (typeof raw !== "string" || raw.length === 0) return;
3465
- const safePath2 = resolveProjectPath3(raw);
3466
- if (!safePath2) return;
3467
- const captured = await captureFileForHook(safePath2, cfg.maxFileBytes, runtime.signal);
2791
+ const safePath = resolveProjectPath3(raw);
2792
+ if (!safePath) return;
2793
+ const captured = await captureFileForHook(safePath, cfg.maxFileBytes, runtime.signal);
3468
2794
  if (captured === "too-large") {
3469
2795
  state9.skippedLarge += 1;
3470
2796
  return;
@@ -3482,7 +2808,7 @@ var plugin9 = {
3482
2808
  state9.captures += 1;
3483
2809
  api.metrics.counter("captures");
3484
2810
  api.emitCustom?.("checkpoint:captured", {
3485
- path: safePath2,
2811
+ path: safePath,
3486
2812
  bytes: captured.bytes,
3487
2813
  hadContent: captured.content !== null,
3488
2814
  // 32-bit unsigned hash of the captured bytes. Collisions
@@ -3526,12 +2852,12 @@ var plugin9 = {
3526
2852
  const rejectedOutsideProject = [];
3527
2853
  let skipped = 0;
3528
2854
  for (const p of paths) {
3529
- const safePath2 = resolveProjectPath3(p);
3530
- if (!safePath2) {
2855
+ const safePath = resolveProjectPath3(p);
2856
+ if (!safePath) {
3531
2857
  rejectedOutsideProject.push(p);
3532
2858
  continue;
3533
2859
  }
3534
- const captured = await captureFile(safePath2, cfg.maxFileBytes);
2860
+ const captured = await captureFile(safePath, cfg.maxFileBytes);
3535
2861
  if (captured === "too-large") {
3536
2862
  skipped += 1;
3537
2863
  state9.skippedLarge += 1;
@@ -3643,7 +2969,7 @@ var plugin9 = {
3643
2969
  continue;
3644
2970
  }
3645
2971
  try {
3646
- await mkdir(dirname3(f.path), { recursive: true });
2972
+ await mkdir(dirname2(f.path), { recursive: true });
3647
2973
  await writeFile(f.path, f.content);
3648
2974
  restored.push(f.path);
3649
2975
  } catch (err) {
@@ -3715,7 +3041,7 @@ var checkpoint_default = plugin9;
3715
3041
 
3716
3042
  // src/code-metrics/index.ts
3717
3043
  import { readFile as readFile4 } from "node:fs/promises";
3718
- import { isAbsolute as isAbsolute8, relative as relative8, resolve as resolve8 } from "node:path";
3044
+ import { isAbsolute as isAbsolute6, relative as relative6, resolve as resolve6 } from "node:path";
3719
3045
  var API_VERSION6 = "^0.1.10";
3720
3046
  var state10 = {
3721
3047
  measureCount: 0,
@@ -3745,7 +3071,7 @@ function toPosix(p) {
3745
3071
  return p.replace(/\\/g, "/");
3746
3072
  }
3747
3073
  function relativePath(p) {
3748
- return toPosix(relative8(process.cwd(), p));
3074
+ return toPosix(relative6(process.cwd(), p));
3749
3075
  }
3750
3076
  function countFunctions(content) {
3751
3077
  let count = 0;
@@ -3851,9 +3177,9 @@ function analyzeFile(filePath, content) {
3851
3177
  }
3852
3178
  async function measurePath(rawPath, cfg) {
3853
3179
  const root = process.cwd();
3854
- const resolved = isAbsolute8(rawPath) ? resolve8(rawPath) : resolve8(root, rawPath);
3180
+ const resolved = isAbsolute6(rawPath) ? resolve6(rawPath) : resolve6(root, rawPath);
3855
3181
  const exts = normalizeExtensions2(cfg.extensions);
3856
- const allFiles = await collectSourceFilesAsync(resolved, { extensions: exts });
3182
+ const allFiles = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
3857
3183
  const files = allFiles.slice(0, cfg.maxFiles);
3858
3184
  const metrics = [];
3859
3185
  for (const p of files) {
@@ -3910,11 +3236,11 @@ var plugin10 = {
3910
3236
  const inp = input.toolInput ?? {};
3911
3237
  const sourcePath = inp["path"];
3912
3238
  if (!sourcePath || typeof sourcePath !== "string") return;
3913
- if (!withinProject(sourcePath)) return;
3239
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
3914
3240
  const exts = normalizeExtensions2(cfg.extensions);
3915
- if (!matchesExtension(sourcePath, exts)) return;
3241
+ if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
3916
3242
  state10.hookInvocationCount += 1;
3917
- const resolved = resolve8(process.cwd(), sourcePath);
3243
+ const resolved = resolve6(process.cwd(), sourcePath);
3918
3244
  let content;
3919
3245
  try {
3920
3246
  content = await readFile4(resolved, "utf-8");
@@ -3944,7 +3270,7 @@ var plugin10 = {
3944
3270
  async execute(input) {
3945
3271
  if (!cfg.enabled) return { ok: false, error: "code-metrics is disabled" };
3946
3272
  const rawPath = typeof input.path === "string" ? input.path : ".";
3947
- if (!withinProject(rawPath)) {
3273
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
3948
3274
  return { ok: false, error: "path is outside the project root" };
3949
3275
  }
3950
3276
  state10.measureCount += 1;
@@ -3958,7 +3284,7 @@ var plugin10 = {
3958
3284
  state10.fileCount += result.files.length;
3959
3285
  return {
3960
3286
  ok: true,
3961
- path: relativePath(resolve8(process.cwd(), rawPath)),
3287
+ path: relativePath(resolve6(process.cwd(), rawPath)),
3962
3288
  files: result.files,
3963
3289
  totalFiles: result.totalFiles,
3964
3290
  capped: result.totalFiles > cfg.maxFiles
@@ -4223,7 +3549,7 @@ var plugin11 = {
4223
3549
  state11.invalidCount = 0;
4224
3550
  state11.suggestFixCount = 0;
4225
3551
  state11.suggestFixErrors = 0;
4226
- state11.hookUnregister = releaseHandle(state11.hookUnregister);
3552
+ state11.hookUnregister = (0, runtime_exports.releaseHandle)(state11.hookUnregister);
4227
3553
  state11.lastValidation = null;
4228
3554
  const cfg = readConfig10(api.config.extensions?.["commit-validator"]);
4229
3555
  const hook = async (input) => {
@@ -4416,7 +3742,7 @@ Suggested rewrite (${suggest.model}):
4416
3742
  var commit_validator_default = plugin11;
4417
3743
 
4418
3744
  // src/config-validator/index.ts
4419
- import { readFileSync as readFileSync5, statSync } from "node:fs";
3745
+ import { readFileSync as readFileSync4, statSync } from "node:fs";
4420
3746
  var state12 = {
4421
3747
  invocations: 0,
4422
3748
  filesChecked: 0,
@@ -4677,13 +4003,13 @@ var plugin12 = {
4677
4003
  const ti = input.toolInput ?? {};
4678
4004
  const raw = ti["path"] ?? ti["file_path"] ?? ti["filePath"];
4679
4005
  if (typeof raw !== "string" || raw.length === 0) return;
4680
- if (!withinProject(raw)) return;
4006
+ if (!(0, runtime_exports.withinProject)(raw)) return;
4681
4007
  const lower = raw.toLowerCase();
4682
4008
  if (!cfg.extensions.some((ext) => lower.endsWith(ext))) return;
4683
4009
  let text;
4684
4010
  try {
4685
4011
  if (statSync(raw).size > cfg.maxFileBytes) return;
4686
- text = readFileSync5(raw, "utf-8");
4012
+ text = readFileSync4(raw, "utf-8");
4687
4013
  } catch {
4688
4014
  return;
4689
4015
  }
@@ -4767,7 +4093,7 @@ var config_validator_default = plugin12;
4767
4093
 
4768
4094
  // src/context-pins/index.ts
4769
4095
  import * as fs from "node:fs";
4770
- import { dirname as dirname4, isAbsolute as isAbsolute9, relative as relative9, resolve as resolve9 } from "node:path";
4096
+ import { dirname as dirname3, isAbsolute as isAbsolute7, relative as relative7, resolve as resolve7 } from "node:path";
4771
4097
  import { atomicWrite, ensureDir } from "@wrongstack/core/utils";
4772
4098
  var state13 = {
4773
4099
  pins: [],
@@ -4785,10 +4111,10 @@ var DEFAULTS11 = {
4785
4111
  };
4786
4112
  function resolveProjectPath4(rawPath, cwd = process.cwd()) {
4787
4113
  if (typeof rawPath !== "string" || rawPath.length === 0) return "";
4788
- const root = resolve9(cwd);
4789
- const resolved = isAbsolute9(rawPath) ? resolve9(rawPath) : resolve9(root, rawPath);
4790
- const rel = relative9(root, resolved);
4791
- if (rel === "" || !rel.startsWith("..") && !isAbsolute9(rel)) return resolved;
4114
+ const root = resolve7(cwd);
4115
+ const resolved = isAbsolute7(rawPath) ? resolve7(rawPath) : resolve7(root, rawPath);
4116
+ const rel = relative7(root, resolved);
4117
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute7(rel)) return resolved;
4792
4118
  return null;
4793
4119
  }
4794
4120
  function readConfig12(raw) {
@@ -4818,7 +4144,7 @@ function loadPins(filePath) {
4818
4144
  async function persistPins(filePath) {
4819
4145
  if (!filePath) return true;
4820
4146
  try {
4821
- await ensureDir(dirname4(filePath));
4147
+ await ensureDir(dirname3(filePath));
4822
4148
  await atomicWrite(filePath, JSON.stringify({ pins: state13.pins, nextId: state13.nextId }, null, 2));
4823
4149
  return true;
4824
4150
  } catch {
@@ -5043,7 +4369,7 @@ function readCostTrackerConfig(raw) {
5043
4369
  mailboxDigestTo: typeof digestTo === "string" && digestTo.length > 0 ? digestTo : "cost-tracker"
5044
4370
  };
5045
4371
  }
5046
- var modelKeyCache = new BoundedMap({ max: 256 });
4372
+ var modelKeyCache = new runtime_exports.BoundedMap({ max: 256 });
5047
4373
  function estimateCost(model, promptTokens, completionTokens) {
5048
4374
  let key = modelKeyCache.get(model);
5049
4375
  if (!key) {
@@ -5653,7 +4979,7 @@ var cron_default = plugin15;
5653
4979
 
5654
4980
  // src/dead-code-detector/index.ts
5655
4981
  import { readdir, readFile as readFile5, stat as stat2 } from "node:fs/promises";
5656
- import { extname as extname4, join as join2, relative as relative10, resolve as resolve10 } from "node:path";
4982
+ import { extname as extname2, join, relative as relative8, resolve as resolve8 } from "node:path";
5657
4983
  var API_VERSION10 = "^0.1.10";
5658
4984
  var state15 = {
5659
4985
  scanCount: 0,
@@ -5696,17 +5022,17 @@ async function gatherFiles(root, depth, cfg) {
5696
5022
  for (const entry of entries) {
5697
5023
  if (entry.isDirectory()) {
5698
5024
  if (remaining > 0 && !excludeSet.has(entry.name)) {
5699
- await walk(join2(dir, entry.name), remaining - 1);
5025
+ await walk(join(dir, entry.name), remaining - 1);
5700
5026
  }
5701
5027
  } else if (entry.isFile()) {
5702
- const ext = extname4(entry.name).toLowerCase();
5028
+ const ext = extname2(entry.name).toLowerCase();
5703
5029
  if (cfg.extensions.includes(ext)) {
5704
- files.push(join2(dir, entry.name));
5030
+ files.push(join(dir, entry.name));
5705
5031
  }
5706
5032
  }
5707
5033
  }
5708
5034
  }
5709
- await walk(resolve10(root), depth);
5035
+ await walk(resolve8(root), depth);
5710
5036
  return files;
5711
5037
  }
5712
5038
  function stripNoise(content) {
@@ -5799,11 +5125,11 @@ async function scan(root, depth, cfg) {
5799
5125
  return { findings: await findUnusedSymbols(files), scannedFiles: files.length };
5800
5126
  }
5801
5127
  async function resolveScanRoot(rawPath) {
5802
- const resolved = resolve10(process.cwd(), rawPath);
5128
+ const resolved = resolve8(process.cwd(), rawPath);
5803
5129
  try {
5804
5130
  const stats = await stat2(resolved);
5805
5131
  if (!stats.isDirectory()) {
5806
- return resolve10(resolved, "..");
5132
+ return resolve8(resolved, "..");
5807
5133
  }
5808
5134
  } catch {
5809
5135
  }
@@ -5813,7 +5139,7 @@ function toPosix2(p) {
5813
5139
  return p.replace(/\\/g, "/");
5814
5140
  }
5815
5141
  function relativePath2(p) {
5816
- return toPosix2(relative10(process.cwd(), p));
5142
+ return toPosix2(relative8(process.cwd(), p));
5817
5143
  }
5818
5144
  var plugin16 = {
5819
5145
  name: "dead-code-detector",
@@ -5872,7 +5198,7 @@ var plugin16 = {
5872
5198
  const inp = input.toolInput ?? {};
5873
5199
  const sourcePath = inp["path"];
5874
5200
  if (!sourcePath || typeof sourcePath !== "string") return;
5875
- if (!withinProject(sourcePath)) return;
5201
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
5876
5202
  const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
5877
5203
  if (!cfg.extensions.includes(ext)) return;
5878
5204
  state15.hookInvocationCount += 1;
@@ -5884,8 +5210,8 @@ var plugin16 = {
5884
5210
  state15.errorCount += 1;
5885
5211
  return;
5886
5212
  }
5887
- const changedFile = resolve10(process.cwd(), sourcePath);
5888
- const relevant = result.findings.filter((f) => resolve10(f.file) === changedFile);
5213
+ const changedFile = resolve8(process.cwd(), sourcePath);
5214
+ const relevant = result.findings.filter((f) => resolve8(f.file) === changedFile);
5889
5215
  if (relevant.length === 0) {
5890
5216
  state15.missCount += 1;
5891
5217
  return;
@@ -5930,7 +5256,7 @@ Consider removing the export if it is not part of the public API.`;
5930
5256
  const rawPath = typeof input.path === "string" ? input.path : ".";
5931
5257
  const rawDepth = typeof input.depth === "number" ? input.depth : cfg.defaultDepth;
5932
5258
  const depth = Math.max(0, Math.min(Math.floor(rawDepth), cfg.maxDepth));
5933
- if (!withinProject(rawPath)) {
5259
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
5934
5260
  return { ok: false, error: "scan path is outside the project root" };
5935
5261
  }
5936
5262
  state15.scanCount += 1;
@@ -6378,7 +5704,7 @@ ${notes.map((n) => ` - ${n}`).join("\n")}`
6378
5704
  var dep_guard_default = plugin17;
6379
5705
 
6380
5706
  // src/dependency-vulnerability-gate/index.ts
6381
- import { execFile as execFile4 } from "node:child_process";
5707
+ import { execFile as execFile3 } from "node:child_process";
6382
5708
  import { access } from "node:fs/promises";
6383
5709
  var API_VERSION11 = "^0.1.10";
6384
5710
  var state17 = {
@@ -6512,12 +5838,12 @@ async function runAudit(cfg) {
6512
5838
  const start = Date.now();
6513
5839
  let invocation;
6514
5840
  try {
6515
- invocation = resolveExecInvocation(manager, ["audit", "--json"]);
5841
+ invocation = (0, runtime_exports.resolveExecInvocation)(manager, ["audit", "--json"]);
6516
5842
  } catch {
6517
5843
  return null;
6518
5844
  }
6519
- const stdout = await new Promise((resolve29) => {
6520
- execFile4(
5845
+ const stdout = await new Promise((resolve27) => {
5846
+ execFile3(
6521
5847
  invocation.cmd,
6522
5848
  invocation.args,
6523
5849
  {
@@ -6531,10 +5857,10 @@ async function runAudit(cfg) {
6531
5857
  },
6532
5858
  (error, output) => {
6533
5859
  if (error && error.killed) {
6534
- resolve29(null);
5860
+ resolve27(null);
6535
5861
  return;
6536
5862
  }
6537
- resolve29(output);
5863
+ resolve27(output);
6538
5864
  }
6539
5865
  );
6540
5866
  });
@@ -6712,7 +6038,7 @@ Review the audit output or adjust the dependency choice.`;
6712
6038
  var dependency_vulnerability_gate_default = plugin18;
6713
6039
 
6714
6040
  // src/diff-summary/index.ts
6715
- import { execFile as execFile5 } from "node:child_process";
6041
+ import { execFile as execFile4 } from "node:child_process";
6716
6042
  var API_VERSION12 = "^0.1.10";
6717
6043
  var state18 = {
6718
6044
  invocationCount: 0,
@@ -6757,10 +6083,10 @@ function contentHash(s) {
6757
6083
  }
6758
6084
  return h >>> 0;
6759
6085
  }
6760
- var pathMemo = new BoundedMap({ max: 512 });
6086
+ var pathMemo = new runtime_exports.BoundedMap({ max: 512 });
6761
6087
  function runGit2(args, cwd) {
6762
6088
  return new Promise((resolveCommand) => {
6763
- execFile5(
6089
+ execFile4(
6764
6090
  "git",
6765
6091
  args,
6766
6092
  {
@@ -6872,7 +6198,7 @@ var plugin19 = {
6872
6198
  state18.fallbackCount = 0;
6873
6199
  state18.throttledCount = 0;
6874
6200
  state18.duplicateContentCount = 0;
6875
- state18.hookUnregister = releaseHandle(state18.hookUnregister);
6201
+ state18.hookUnregister = (0, runtime_exports.releaseHandle)(state18.hookUnregister);
6876
6202
  state18.lastSummary = null;
6877
6203
  pathMemo.clear();
6878
6204
  const cfg = readConfig16(api.config.extensions?.["diff-summary"]);
@@ -6885,7 +6211,7 @@ var plugin19 = {
6885
6211
  const filePath = inp["path"];
6886
6212
  if (!filePath || typeof filePath !== "string") return;
6887
6213
  state18.invocationCount += 1;
6888
- if (!withinProject(filePath)) {
6214
+ if (!(0, runtime_exports.withinProject)(filePath)) {
6889
6215
  state18.fallbackCount += 1;
6890
6216
  return;
6891
6217
  }
@@ -7019,7 +6345,7 @@ var plugin19 = {
7019
6345
  var diff_summary_default = plugin19;
7020
6346
 
7021
6347
  // src/doc-sync-guard/index.ts
7022
- import { basename as basename3, extname as extname5 } from "node:path";
6348
+ import { basename as basename2, extname as extname3 } from "node:path";
7023
6349
  var API_VERSION13 = "^0.1.10";
7024
6350
  var state19 = {
7025
6351
  changedFiles: [],
@@ -7048,21 +6374,21 @@ function normalizeSlashes(p) {
7048
6374
  return p.replace(/\\/g, "/");
7049
6375
  }
7050
6376
  function isSourceFile(p, extensions) {
7051
- const ext = extname5(p).toLowerCase();
6377
+ const ext = extname3(p).toLowerCase();
7052
6378
  return extensions.includes(ext);
7053
6379
  }
7054
6380
  function isPublicSource(p, extensions) {
7055
6381
  if (!isSourceFile(p, extensions)) return false;
7056
6382
  const norm = normalizeSlashes(p);
7057
6383
  if (norm.includes("/node_modules/") || norm.startsWith("node_modules/")) return false;
7058
- const base = basename3(norm).toLowerCase();
6384
+ const base = basename2(norm).toLowerCase();
7059
6385
  if (/\.(test|spec)\./.test(base)) return false;
7060
6386
  if (base.startsWith("_")) return false;
7061
6387
  return true;
7062
6388
  }
7063
6389
  function isDocFile(p, docNames) {
7064
6390
  const norm = normalizeSlashes(p);
7065
- const base = basename3(norm);
6391
+ const base = basename2(norm);
7066
6392
  const lowerBase = base.toLowerCase();
7067
6393
  if (docNames.some((name) => lowerBase === name.toLowerCase())) return true;
7068
6394
  if (norm.includes("/docs/") || norm.startsWith("docs/")) return true;
@@ -7080,7 +6406,7 @@ function extractDocContent(toolInput) {
7080
6406
  return void 0;
7081
6407
  }
7082
6408
  function referenceTokens(p) {
7083
- const base = basename3(p);
6409
+ const base = basename2(p);
7084
6410
  const withoutExt = base.replace(/\.[^.]+$/, "");
7085
6411
  const tokens = [base];
7086
6412
  if (withoutExt && withoutExt !== base) tokens.push(withoutExt);
@@ -7138,13 +6464,13 @@ var plugin20 = {
7138
6464
  state19.sourceWrites = 0;
7139
6465
  state19.docWrites = 0;
7140
6466
  state19.warningsIssued = 0;
7141
- state19.hookUnregister = releaseHandle(state19.hookUnregister);
6467
+ state19.hookUnregister = (0, runtime_exports.releaseHandle)(state19.hookUnregister);
7142
6468
  const cfg = readConfig17(api.config.extensions?.["doc-sync-guard"]);
7143
6469
  const hook = (input) => {
7144
6470
  if (!cfg.enabled) return;
7145
6471
  if (input.toolResult?.isError) return;
7146
6472
  const path = extractPath(input.toolInput);
7147
- if (!path || !withinProject(path)) return;
6473
+ if (!path || !(0, runtime_exports.withinProject)(path)) return;
7148
6474
  if (isPublicSource(path, cfg.sourceExtensions)) {
7149
6475
  trackChangedFile(path, cfg.maxTrackedFiles);
7150
6476
  state19.sourceWrites += 1;
@@ -7231,7 +6557,7 @@ var doc_sync_guard_default = plugin20;
7231
6557
 
7232
6558
  // src/duplicate-code-detector/index.ts
7233
6559
  import { readFile as readFile6, realpath, stat as stat3 } from "node:fs/promises";
7234
- import { isAbsolute as isAbsolute10, relative as relative11, resolve as resolve11, sep as sep2 } from "node:path";
6560
+ import { isAbsolute as isAbsolute8, relative as relative9, resolve as resolve9, sep } from "node:path";
7235
6561
  var API_VERSION14 = "^0.1.10";
7236
6562
  var HOOK_WARNING_COOLDOWN_MS = 6e4;
7237
6563
  var state20 = {
@@ -7241,7 +6567,7 @@ var state20 = {
7241
6567
  warningCount: 0,
7242
6568
  errorCount: 0,
7243
6569
  hookUnregister: null,
7244
- lastHookWarning: new BoundedMap({ max: 512, ttlMs: HOOK_WARNING_COOLDOWN_MS }),
6570
+ lastHookWarning: new runtime_exports.BoundedMap({ max: 512, ttlMs: HOOK_WARNING_COOLDOWN_MS }),
7245
6571
  fileIndex: /* @__PURE__ */ new Map(),
7246
6572
  inFlightFingerprintReads: /* @__PURE__ */ new Map(),
7247
6573
  indexFingerprintCount: 0,
@@ -7288,14 +6614,14 @@ function readConfig18(raw) {
7288
6614
  };
7289
6615
  }
7290
6616
  function isWithinRoot(projectRoot, candidate) {
7291
- const rel = relative11(projectRoot, candidate);
7292
- return rel === "" || rel !== ".." && !rel.startsWith(`..${sep2}`) && !isAbsolute10(rel);
6617
+ const rel = relative9(projectRoot, candidate);
6618
+ return rel === "" || rel !== ".." && !rel.startsWith(`..${sep}`) && !isAbsolute8(rel);
7293
6619
  }
7294
6620
  function toPosix3(p) {
7295
6621
  return p.replace(/\\/g, "/");
7296
6622
  }
7297
6623
  function relativePath3(p) {
7298
- return toPosix3(relative11(process.cwd(), p));
6624
+ return toPosix3(relative9(process.cwd(), p));
7299
6625
  }
7300
6626
  function removeInlineComments(line) {
7301
6627
  return line.replace(/\/\/.*$/, "").replace(/\/\*[\s\S]*?\*\//, "");
@@ -7387,8 +6713,8 @@ function findDuplicates(files, minLines, maxFindings) {
7387
6713
  }
7388
6714
  async function scanPath(rawPath, cfg) {
7389
6715
  const root = process.cwd();
7390
- const resolved = isAbsolute10(rawPath) ? resolve11(rawPath) : resolve11(root, rawPath);
7391
- const filePaths = await collectSourceFilesAsync(resolved, {
6716
+ const resolved = isAbsolute8(rawPath) ? resolve9(rawPath) : resolve9(root, rawPath);
6717
+ const filePaths = await (0, runtime_exports.collectSourceFilesAsync)(resolved, {
7392
6718
  extensions: cfg.extensions,
7393
6719
  excludeDirs: cfg.excludeDirs
7394
6720
  });
@@ -7515,8 +6841,8 @@ var plugin21 = {
7515
6841
  const inp = input.toolInput ?? {};
7516
6842
  const sourcePath = inp["path"];
7517
6843
  if (!sourcePath || typeof sourcePath !== "string") return;
7518
- const projectRoot = resolve11(process.cwd());
7519
- const resolvedFile = isAbsolute10(sourcePath) ? resolve11(sourcePath) : resolve11(projectRoot, sourcePath);
6844
+ const projectRoot = resolve9(process.cwd());
6845
+ const resolvedFile = isAbsolute8(sourcePath) ? resolve9(sourcePath) : resolve9(projectRoot, sourcePath);
7520
6846
  if (!isWithinRoot(projectRoot, resolvedFile)) return;
7521
6847
  let changedFile;
7522
6848
  try {
@@ -7540,7 +6866,7 @@ var plugin21 = {
7540
6866
  if (changedFps.size === 0) return;
7541
6867
  let otherFilePaths;
7542
6868
  try {
7543
- otherFilePaths = await collectSourceFilesAsync(projectRoot, {
6869
+ otherFilePaths = await (0, runtime_exports.collectSourceFilesAsync)(projectRoot, {
7544
6870
  extensions: cfg.extensions,
7545
6871
  excludeDirs: cfg.excludeDirs
7546
6872
  });
@@ -7550,7 +6876,7 @@ var plugin21 = {
7550
6876
  }
7551
6877
  const matched = /* @__PURE__ */ new Set();
7552
6878
  for (const p of otherFilePaths) {
7553
- if (resolve11(p) === resolve11(changedFile)) continue;
6879
+ if (resolve9(p) === resolve9(changedFile)) continue;
7554
6880
  const otherFps = await readCachedFingerprints(p, cfg.minLines);
7555
6881
  if (otherFps === null || otherFps.size === 0) continue;
7556
6882
  for (const fp of changedFps) {
@@ -7582,7 +6908,7 @@ var plugin21 = {
7582
6908
  async execute(input) {
7583
6909
  if (!cfg.enabled) return { ok: false, error: "duplicate-code-detector is disabled" };
7584
6910
  const rawPath = typeof input.path === "string" ? input.path : ".";
7585
- if (!withinProject(rawPath)) {
6911
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
7586
6912
  return { ok: false, error: "scan path is outside the project root" };
7587
6913
  }
7588
6914
  state20.scanCount += 1;
@@ -7596,7 +6922,7 @@ var plugin21 = {
7596
6922
  state20.findingCount += result.findings.length;
7597
6923
  return {
7598
6924
  ok: true,
7599
- path: relativePath3(resolve11(process.cwd(), rawPath)),
6925
+ path: relativePath3(resolve9(process.cwd(), rawPath)),
7600
6926
  scannedFiles: result.scannedFiles,
7601
6927
  minLines: cfg.minLines,
7602
6928
  findings: result.findings
@@ -7975,7 +7301,7 @@ var error_lens_default = plugin22;
7975
7301
 
7976
7302
  // src/feature-flag-tracker/index.ts
7977
7303
  import { readFile as readFile7 } from "node:fs/promises";
7978
- import { isAbsolute as isAbsolute11, relative as relative12, resolve as resolve12 } from "node:path";
7304
+ import { isAbsolute as isAbsolute9, relative as relative10, resolve as resolve10 } from "node:path";
7979
7305
  var API_VERSION15 = "^0.1.10";
7980
7306
  var state22 = {
7981
7307
  scanCount: 0,
@@ -8014,7 +7340,7 @@ function toPosix4(p) {
8014
7340
  return p.replace(/\\/g, "/");
8015
7341
  }
8016
7342
  function relativePath4(p) {
8017
- return toPosix4(relative12(process.cwd(), p));
7343
+ return toPosix4(relative10(process.cwd(), p));
8018
7344
  }
8019
7345
  function compilePatterns(patterns) {
8020
7346
  const out = [];
@@ -8050,9 +7376,9 @@ function scanFile(filePath, content, patterns, maxFindings) {
8050
7376
  }
8051
7377
  async function scanPath2(rawPath, cfg) {
8052
7378
  const root = process.cwd();
8053
- const resolved = isAbsolute11(rawPath) ? resolve12(rawPath) : resolve12(root, rawPath);
7379
+ const resolved = isAbsolute9(rawPath) ? resolve10(rawPath) : resolve10(root, rawPath);
8054
7380
  const exts = normalizeExtensions3(cfg.extensions);
8055
- const files = await collectSourceFilesAsync(resolved, { extensions: exts });
7381
+ const files = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
8056
7382
  const patterns = compilePatterns(cfg.patterns);
8057
7383
  const usages = [];
8058
7384
  let scannedFiles = 0;
@@ -8128,11 +7454,11 @@ var plugin23 = {
8128
7454
  const inp = input.toolInput ?? {};
8129
7455
  const sourcePath = inp["path"];
8130
7456
  if (!sourcePath || typeof sourcePath !== "string") return;
8131
- if (!withinProject(sourcePath)) return;
7457
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
8132
7458
  const exts = normalizeExtensions3(cfg.extensions);
8133
- if (!matchesExtension(sourcePath, exts)) return;
7459
+ if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
8134
7460
  state22.hookInvocationCount += 1;
8135
- const resolved = resolve12(process.cwd(), sourcePath);
7461
+ const resolved = resolve10(process.cwd(), sourcePath);
8136
7462
  let content;
8137
7463
  try {
8138
7464
  content = await readFile7(resolved, "utf-8");
@@ -8167,7 +7493,7 @@ Make sure flag behavior is intentional and consider updating flag inventory/docs
8167
7493
  async execute(input) {
8168
7494
  if (!cfg.enabled) return { ok: false, error: "feature-flag-tracker is disabled" };
8169
7495
  const rawPath = typeof input.path === "string" ? input.path : ".";
8170
- if (!withinProject(rawPath)) {
7496
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
8171
7497
  return { ok: false, error: "path is outside the project root" };
8172
7498
  }
8173
7499
  state22.scanCount += 1;
@@ -8181,7 +7507,7 @@ Make sure flag behavior is intentional and consider updating flag inventory/docs
8181
7507
  state22.flagCount += result.usages.length;
8182
7508
  return {
8183
7509
  ok: true,
8184
- path: relativePath4(resolve12(process.cwd(), rawPath)),
7510
+ path: relativePath4(resolve10(process.cwd(), rawPath)),
8185
7511
  scannedFiles: result.scannedFiles,
8186
7512
  discoveredFiles: result.discoveredFiles,
8187
7513
  // Say so when the cap stopped the walk early: a partial scan
@@ -8261,7 +7587,7 @@ var feature_flag_tracker_default = plugin23;
8261
7587
 
8262
7588
  // src/file-watcher/index.ts
8263
7589
  import { watch as fsWatch } from "node:fs";
8264
- import { join as join3 } from "node:path";
7590
+ import { join as join2 } from "node:path";
8265
7591
  var API_VERSION16 = "^0.1.10";
8266
7592
  var watch_idCounter = 0;
8267
7593
  function nextId() {
@@ -8343,7 +7669,7 @@ var plugin24 = {
8343
7669
  }
8344
7670
  const autoIndex = api.config.extensions?.["file-watcher"]?.["autoIndex"] ?? false;
8345
7671
  const indexProjectRoot = api.config.extensions?.["file-watcher"]?.["indexProjectRoot"] ?? "";
8346
- const safeIndexRoot = indexProjectRoot !== "" && withinProject(indexProjectRoot) ? indexProjectRoot : "";
7672
+ const safeIndexRoot = indexProjectRoot !== "" && (0, runtime_exports.withinProject)(indexProjectRoot) ? indexProjectRoot : "";
8347
7673
  if (indexProjectRoot !== "" && safeIndexRoot === "") {
8348
7674
  api.log.warn(
8349
7675
  "file-watcher: indexProjectRoot is outside the project root \u2014 using watched dirPath instead",
@@ -8365,7 +7691,7 @@ var plugin24 = {
8365
7691
  if (handle.events.length > 0 && !(eventType === "change" ? handle.events.includes("change") : handle.events.includes("add") || handle.events.includes("delete"))) {
8366
7692
  return;
8367
7693
  }
8368
- const rawPath = filename.startsWith(dirPath) ? filename : join3(dirPath, filename);
7694
+ const rawPath = filename.startsWith(dirPath) ? filename : join2(dirPath, filename);
8369
7695
  const fullPath = rawPath.replace(/\\/g, "/");
8370
7696
  const key = `${handle.id}:${fullPath}:${eventType}`;
8371
7697
  debounceEvent(
@@ -8488,7 +7814,7 @@ var plugin24 = {
8488
7814
  }
8489
7815
  const events = input["events"] ?? ["change", "add", "delete"];
8490
7816
  const recursive = input["recursive"] ?? true;
8491
- const bad = paths.find((p) => !withinProject(p));
7817
+ const bad = paths.find((p) => !(0, runtime_exports.withinProject)(p));
8492
7818
  if (bad !== void 0) {
8493
7819
  return {
8494
7820
  ok: false,
@@ -8614,7 +7940,7 @@ var plugin24 = {
8614
7940
  var file_watcher_default = plugin24;
8615
7941
 
8616
7942
  // src/format-on-save/index.ts
8617
- import { execFile as execFile6 } from "node:child_process";
7943
+ import { execFile as execFile5 } from "node:child_process";
8618
7944
  import { createHash } from "node:crypto";
8619
7945
  import { access as access2, readFile as readFile8, stat as stat4 } from "node:fs/promises";
8620
7946
  var API_VERSION17 = "^0.1.10";
@@ -8652,7 +7978,7 @@ function readConfig21(raw) {
8652
7978
  skipTtlMs: typeof r["skipTtlMs"] === "number" && r["skipTtlMs"] >= 0 ? r["skipTtlMs"] : DEFAULTS20.skipTtlMs
8653
7979
  };
8654
7980
  }
8655
- var recentlyCovered = new BoundedMap({ max: 256 });
7981
+ var recentlyCovered = new runtime_exports.BoundedMap({ max: 256 });
8656
7982
  function clearRegistrations() {
8657
7983
  if (state23.hookUnregister) {
8658
7984
  try {
@@ -8688,7 +8014,7 @@ var FORMATTERS = [
8688
8014
  var activeFormatter;
8689
8015
  function resetFormatter() {
8690
8016
  activeFormatter = void 0;
8691
- clearLocalBinCache();
8017
+ (0, runtime_exports.clearLocalBinCache)();
8692
8018
  }
8693
8019
  function resolveFormatter() {
8694
8020
  if (activeFormatter !== void 0) return activeFormatter;
@@ -8701,7 +8027,7 @@ function resolveFormatter() {
8701
8027
  }
8702
8028
  }
8703
8029
  for (const f of FORMATTERS) {
8704
- const onPath = findOnPath(f.binName);
8030
+ const onPath = (0, runtime_exports.findOnPath)(f.binName);
8705
8031
  if (!onPath) continue;
8706
8032
  activeFormatter = { cmd: onPath, args: [...f.writeArgs], label: f.label };
8707
8033
  return activeFormatter;
@@ -8710,7 +8036,7 @@ function resolveFormatter() {
8710
8036
  return null;
8711
8037
  }
8712
8038
  function resolveNodeBinFor(f, cwd) {
8713
- const hit = resolveFirstNodeBin([{ packageName: f.packageName, binName: f.binName }], cwd);
8039
+ const hit = (0, runtime_exports.resolveFirstNodeBin)([{ packageName: f.packageName, binName: f.binName }], cwd);
8714
8040
  if (!hit) return null;
8715
8041
  return { cmd: hit.cmd, args: [...hit.args, ...f.writeArgs], label: f.label };
8716
8042
  }
@@ -8725,7 +8051,7 @@ async function sha256File(filePath) {
8725
8051
  }
8726
8052
  }
8727
8053
  async function formatFile(filePath, timeoutMs) {
8728
- if (!withinProject(filePath)) return null;
8054
+ if (!(0, runtime_exports.withinProject)(filePath)) return null;
8729
8055
  try {
8730
8056
  await access2(filePath);
8731
8057
  } catch {
@@ -8743,13 +8069,13 @@ async function formatFile(filePath, timeoutMs) {
8743
8069
  const hashBefore = await sha256File(filePath);
8744
8070
  let invocation;
8745
8071
  try {
8746
- invocation = resolveExecInvocation(formatter.cmd, [...formatter.args, filePath]);
8072
+ invocation = (0, runtime_exports.resolveExecInvocation)(formatter.cmd, [...formatter.args, filePath]);
8747
8073
  } catch {
8748
8074
  return null;
8749
8075
  }
8750
8076
  try {
8751
- await new Promise((resolve29, reject) => {
8752
- execFile6(
8077
+ await new Promise((resolve27, reject) => {
8078
+ execFile5(
8753
8079
  invocation.cmd,
8754
8080
  invocation.args,
8755
8081
  {
@@ -8765,7 +8091,7 @@ async function formatFile(filePath, timeoutMs) {
8765
8091
  const e = err;
8766
8092
  if (e.killed) return reject(err);
8767
8093
  }
8768
- resolve29();
8094
+ resolve27();
8769
8095
  }
8770
8096
  );
8771
8097
  });
@@ -8983,7 +8309,7 @@ var plugin25 = {
8983
8309
  var format_on_save_default = plugin25;
8984
8310
 
8985
8311
  // src/git-autocommit/index.ts
8986
- import { execFile as execFile7 } from "node:child_process";
8312
+ import { execFile as execFile6 } from "node:child_process";
8987
8313
  import { existsSync as existsSync2 } from "node:fs";
8988
8314
  var API_VERSION18 = "^0.1.10";
8989
8315
  var commitCount = { value: 0 };
@@ -8993,7 +8319,7 @@ var DEFAULT_GIT_TIMEOUT_MS = 3e4;
8993
8319
  var GIT_COMMIT_TIMEOUT_MS = 5 * 6e4;
8994
8320
  async function runGit3(args, cwd, timeoutMs = DEFAULT_GIT_TIMEOUT_MS) {
8995
8321
  return await new Promise((resolvePromise, rejectPromise) => {
8996
- execFile7(
8322
+ execFile6(
8997
8323
  "git",
8998
8324
  args,
8999
8325
  {
@@ -9506,7 +8832,7 @@ var git_autocommit_default = plugin26;
9506
8832
 
9507
8833
  // src/gitignore-guard/index.ts
9508
8834
  import { access as access3, readFile as readFile9, writeFile as writeFile2 } from "node:fs/promises";
9509
- import { basename as basename4, isAbsolute as isAbsolute12, join as join4, relative as relative13, resolve as resolve13, sep as sep3 } from "node:path";
8835
+ import { basename as basename3, isAbsolute as isAbsolute10, join as join3, relative as relative11, resolve as resolve11, sep as sep2 } from "node:path";
9510
8836
  var API_VERSION19 = "^0.1.10";
9511
8837
  var DEFAULT_ARTIFACT_PATTERNS = Object.freeze([
9512
8838
  "dist/",
@@ -9533,7 +8859,7 @@ var DEFAULT_ARTIFACT_PATTERNS = Object.freeze([
9533
8859
  "*.env.*"
9534
8860
  ]);
9535
8861
  function toForwardSlashes(p) {
9536
- return p.split(sep3).join("/").replaceAll("\\", "/");
8862
+ return p.split(sep2).join("/").replaceAll("\\", "/");
9537
8863
  }
9538
8864
  function globToSource(glob) {
9539
8865
  return glob.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]");
@@ -9593,11 +8919,11 @@ function isCoveredByLines(lines, relPath) {
9593
8919
  }
9594
8920
  function gitignoreCandidates(relDir, root) {
9595
8921
  const parts = relDir === "" ? [] : toForwardSlashes(relDir).split("/");
9596
- const out = [join4(root, ".gitignore")];
8922
+ const out = [join3(root, ".gitignore")];
9597
8923
  let cur = root;
9598
8924
  for (const part of parts) {
9599
- cur = join4(cur, part);
9600
- out.push(join4(cur, ".gitignore"));
8925
+ cur = join3(cur, part);
8926
+ out.push(join3(cur, ".gitignore"));
9601
8927
  }
9602
8928
  return out;
9603
8929
  }
@@ -9628,9 +8954,9 @@ async function appendPatterns(target, patterns, limit) {
9628
8954
  }
9629
8955
  function projectRelativePath(rawPath, cwd) {
9630
8956
  const root = cwd ?? process.cwd();
9631
- const abs = isAbsolute12(rawPath) ? rawPath : resolve13(root, rawPath);
9632
- const rel = toForwardSlashes(relative13(root, abs));
9633
- if (rel.startsWith("..") || isAbsolute12(rel) || rel === "") return null;
8957
+ const abs = isAbsolute10(rawPath) ? rawPath : resolve11(root, rawPath);
8958
+ const rel = toForwardSlashes(relative11(root, abs));
8959
+ if (rel.startsWith("..") || isAbsolute10(rel) || rel === "") return null;
9634
8960
  return { abs, rel, root };
9635
8961
  }
9636
8962
  var DEFAULTS21 = {
@@ -9762,7 +9088,7 @@ var plugin27 = {
9762
9088
  const inp = input.toolInput ?? {};
9763
9089
  const rawPath = inp["path"];
9764
9090
  if (typeof rawPath !== "string" || rawPath.trim().length === 0) return;
9765
- if (basename4(rawPath) === ".gitignore") return;
9091
+ if (basename3(rawPath) === ".gitignore") return;
9766
9092
  const resolved = projectRelativePath(rawPath, input.cwd);
9767
9093
  if (!resolved) return;
9768
9094
  state24.invocationCount += 1;
@@ -9787,7 +9113,7 @@ var plugin27 = {
9787
9113
  };
9788
9114
  if (cfg.mode === "append") {
9789
9115
  const nearest = await firstExistingGitignore(candidates);
9790
- const target = nearest ?? join4(resolved.root, ".gitignore");
9116
+ const target = nearest ?? join3(resolved.root, ".gitignore");
9791
9117
  const { appended } = await appendPatterns(target, [matched], cfg.maxAppendPerCall);
9792
9118
  if (appended.length === 0) {
9793
9119
  state24.coveredSkipCount += 1;
@@ -9884,7 +9210,7 @@ var plugin27 = {
9884
9210
  }
9885
9211
  const candidates = gitignoreCandidates(relDirOf(resolved.rel), resolved.root);
9886
9212
  const nearest = await firstExistingGitignore(candidates);
9887
- const target = nearest ?? join4(resolved.root, ".gitignore");
9213
+ const target = nearest ?? join3(resolved.root, ".gitignore");
9888
9214
  const { appended } = await appendPatterns(target, [pattern], cfg.maxAppendPerCall);
9889
9215
  if (appended.length === 0) {
9890
9216
  state24.coveredSkipCount += 1;
@@ -9942,7 +9268,7 @@ var gitignore_guard_default = plugin27;
9942
9268
  // src/import-organizer/index.ts
9943
9269
  import { spawn } from "node:child_process";
9944
9270
  import { existsSync as existsSync3, statSync as statSync2 } from "node:fs";
9945
- import { basename as basename5, isAbsolute as isAbsolute13 } from "node:path";
9271
+ import { basename as basename4, isAbsolute as isAbsolute11 } from "node:path";
9946
9272
  var ALLOWED_FIRST_TOKENS = /* @__PURE__ */ new Set([
9947
9273
  "npx",
9948
9274
  "pnpm",
@@ -9977,7 +9303,7 @@ function resolveLocalToolCommand(tokens) {
9977
9303
  const rest = tokens.slice(i + 1);
9978
9304
  const pkg = LOCAL_BIN_PACKAGES[toolToken];
9979
9305
  if (!pkg) return null;
9980
- const local = resolveNodeBin(pkg.packageName, pkg.binName, process.cwd(), rest);
9306
+ const local = (0, runtime_exports.resolveNodeBin)(pkg.packageName, pkg.binName, process.cwd(), rest);
9981
9307
  if (!local) return null;
9982
9308
  return { cmd: local.cmd, args: local.args };
9983
9309
  }
@@ -9996,7 +9322,7 @@ function resolveAllowedCommand(command) {
9996
9322
  if (head === "node") {
9997
9323
  const target = tokens[1];
9998
9324
  if (!target) return null;
9999
- const base = basename5(target);
9325
+ const base = basename4(target);
10000
9326
  if (!(base in LOCAL_BIN_PACKAGES) && !ALLOWED_FIRST_TOKENS.has(base)) return null;
10001
9327
  }
10002
9328
  const local = ALLOWED_FIRST_TOKENS.has(head) ? resolveLocalToolCommand(tokens) : null;
@@ -10004,13 +9330,13 @@ function resolveAllowedCommand(command) {
10004
9330
  if (ALLOWED_FIRST_TOKENS.has(head)) {
10005
9331
  return { cmd: head, args: tokens.slice(1) };
10006
9332
  }
10007
- if (isAbsolute13(head)) {
10008
- if (!withinProject(head)) return null;
10009
- const base = basename5(head);
9333
+ if (isAbsolute11(head)) {
9334
+ if (!(0, runtime_exports.withinProject)(head)) return null;
9335
+ const base = basename4(head);
10010
9336
  if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
10011
9337
  }
10012
- if (!isAbsolute13(head) && withinProject(head)) {
10013
- const base = basename5(head);
9338
+ if (!isAbsolute11(head) && (0, runtime_exports.withinProject)(head)) {
9339
+ const base = basename4(head);
10014
9340
  if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
10015
9341
  }
10016
9342
  return null;
@@ -10046,13 +9372,13 @@ function readConfig23(raw) {
10046
9372
  }
10047
9373
  var MAX_CAPTURE_BYTES = 4 * 1024 * 1024;
10048
9374
  function runCommand(command, args, timeoutMs, cwd) {
10049
- return new Promise((resolve29) => {
9375
+ return new Promise((resolve27) => {
10050
9376
  let timedOut = false;
10051
9377
  let settled = false;
10052
9378
  const settle = (r) => {
10053
9379
  if (settled) return;
10054
9380
  settled = true;
10055
- resolve29(r);
9381
+ resolve27(r);
10056
9382
  };
10057
9383
  const stdoutChunks = [];
10058
9384
  const stderrChunks = [];
@@ -10067,7 +9393,7 @@ function runCommand(command, args, timeoutMs, cwd) {
10067
9393
  let child;
10068
9394
  let invocation;
10069
9395
  try {
10070
- invocation = resolveExecInvocation(command, args);
9396
+ invocation = (0, runtime_exports.resolveExecInvocation)(command, args);
10071
9397
  } catch {
10072
9398
  signal.removeEventListener("abort", onAbort);
10073
9399
  settle({ code: 127, stdout: "", stderr: "", timedOut: false });
@@ -10111,7 +9437,7 @@ function runCommand(command, args, timeoutMs, cwd) {
10111
9437
  });
10112
9438
  }
10113
9439
  async function organizeImports(filePath, cfg, cwd) {
10114
- if (!withinProject(filePath)) return null;
9440
+ if (!(0, runtime_exports.withinProject)(filePath)) return null;
10115
9441
  if (!existsSync3(filePath)) return null;
10116
9442
  let bytesBefore;
10117
9443
  try {
@@ -10191,7 +9517,7 @@ var plugin28 = {
10191
9517
  state25.organizedCount = 0;
10192
9518
  state25.cleanCount = 0;
10193
9519
  state25.errorCount = 0;
10194
- state25.hookUnregister = releaseHandle(state25.hookUnregister);
9520
+ state25.hookUnregister = (0, runtime_exports.releaseHandle)(state25.hookUnregister);
10195
9521
  state25.lastResult = null;
10196
9522
  state25.probeComplete = false;
10197
9523
  state25.linterAvailable = false;
@@ -10298,7 +9624,7 @@ ${result.stderr.trim()}`
10298
9624
  });
10299
9625
  },
10300
9626
  teardown(api) {
10301
- clearLocalBinCache();
9627
+ (0, runtime_exports.clearLocalBinCache)();
10302
9628
  if (state25.hookUnregister) {
10303
9629
  try {
10304
9630
  state25.hookUnregister();
@@ -10553,7 +9879,7 @@ var injection_shield_default = plugin29;
10553
9879
 
10554
9880
  // src/interface-contract-guard/index.ts
10555
9881
  import { readFile as readFile10 } from "node:fs/promises";
10556
- import { isAbsolute as isAbsolute14, relative as relative14, resolve as resolve14 } from "node:path";
9882
+ import { isAbsolute as isAbsolute12, relative as relative12, resolve as resolve12 } from "node:path";
10557
9883
  var API_VERSION21 = "^0.1.10";
10558
9884
  var state27 = {
10559
9885
  scanCount: 0,
@@ -10586,7 +9912,7 @@ function toPosix5(p) {
10586
9912
  return p.replace(/\\/g, "/");
10587
9913
  }
10588
9914
  function relativePath5(p) {
10589
- return toPosix5(relative14(process.cwd(), p));
9915
+ return toPosix5(relative12(process.cwd(), p));
10590
9916
  }
10591
9917
  var INTERFACE_RE = /(?:export\s+)?interface\s+([A-Za-z_$][A-Za-z0-9_$]*)/g;
10592
9918
  function extractInterfaceNames(content) {
@@ -10614,9 +9940,9 @@ function collectImplementedNames(content, into) {
10614
9940
  }
10615
9941
  async function scanPath3(rawPath, cfg) {
10616
9942
  const root = process.cwd();
10617
- const resolved = isAbsolute14(rawPath) ? resolve14(rawPath) : resolve14(root, rawPath);
9943
+ const resolved = isAbsolute12(rawPath) ? resolve12(rawPath) : resolve12(root, rawPath);
10618
9944
  const exts = normalizeExtensions4(cfg.extensions);
10619
- const allFiles = await collectSourceFilesAsync(resolved, { extensions: exts });
9945
+ const allFiles = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
10620
9946
  const files = allFiles.slice(0, cfg.maxFiles);
10621
9947
  const implemented = /* @__PURE__ */ new Set();
10622
9948
  const declarations = [];
@@ -10700,11 +10026,11 @@ var plugin30 = {
10700
10026
  const inp = input.toolInput ?? {};
10701
10027
  const sourcePath = inp["path"];
10702
10028
  if (!sourcePath || typeof sourcePath !== "string") return;
10703
- if (!withinProject(sourcePath)) return;
10029
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
10704
10030
  const exts = normalizeExtensions4(cfg.extensions);
10705
- if (!matchesExtension(sourcePath, exts)) return;
10031
+ if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
10706
10032
  state27.hookInvocationCount += 1;
10707
- const resolved = resolve14(process.cwd(), sourcePath);
10033
+ const resolved = resolve12(process.cwd(), sourcePath);
10708
10034
  let content;
10709
10035
  try {
10710
10036
  content = await readFile10(resolved, "utf-8");
@@ -10738,7 +10064,7 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
10738
10064
  async execute(input) {
10739
10065
  if (!cfg.enabled) return { ok: false, error: "interface-contract-guard is disabled" };
10740
10066
  const rawPath = typeof input.path === "string" ? input.path : ".";
10741
- if (!withinProject(rawPath)) {
10067
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
10742
10068
  return { ok: false, error: "path is outside the project root" };
10743
10069
  }
10744
10070
  state27.scanCount += 1;
@@ -10752,7 +10078,7 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
10752
10078
  state27.findingCount += result.findings.length;
10753
10079
  return {
10754
10080
  ok: true,
10755
- path: relativePath5(resolve14(process.cwd(), rawPath)),
10081
+ path: relativePath5(resolve12(process.cwd(), rawPath)),
10756
10082
  scannedFiles: result.scannedFiles,
10757
10083
  findings: result.findings,
10758
10084
  // Say so when the corpus was cut short. A partial scan that
@@ -10832,8 +10158,8 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
10832
10158
  var interface_contract_guard_default = plugin30;
10833
10159
 
10834
10160
  // src/knowledge-graph/index.ts
10835
- import { readFileSync as readFileSync7 } from "node:fs";
10836
- import { dirname as dirname5, isAbsolute as isAbsolute15, relative as relative15, resolve as resolve15 } from "node:path";
10161
+ import { readFileSync as readFileSync6 } from "node:fs";
10162
+ import { dirname as dirname4, isAbsolute as isAbsolute13, relative as relative13, resolve as resolve13 } from "node:path";
10837
10163
  import { atomicWrite as atomicWrite2, ensureDir as ensureDir2 } from "@wrongstack/core/utils";
10838
10164
  var API_VERSION22 = "^0.1.10";
10839
10165
  var state28 = {
@@ -10855,10 +10181,10 @@ var DEFAULTS25 = {
10855
10181
  };
10856
10182
  function resolveProjectPath5(rawPath, cwd = process.cwd()) {
10857
10183
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
10858
- const root = resolve15(cwd);
10859
- const resolved = isAbsolute15(rawPath) ? resolve15(rawPath) : resolve15(root, rawPath);
10860
- const rel = relative15(root, resolved);
10861
- if (rel === "" || !rel.startsWith("..") && !isAbsolute15(rel)) return resolved;
10184
+ const root = resolve13(cwd);
10185
+ const resolved = isAbsolute13(rawPath) ? resolve13(rawPath) : resolve13(root, rawPath);
10186
+ const rel = relative13(root, resolved);
10187
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute13(rel)) return resolved;
10862
10188
  return null;
10863
10189
  }
10864
10190
  function readConfig26(raw) {
@@ -10876,7 +10202,7 @@ function readConfig26(raw) {
10876
10202
  function loadFacts(filePath) {
10877
10203
  if (!filePath) return { facts: [], nextId: 1 };
10878
10204
  try {
10879
- const raw = JSON.parse(readFileSync7(filePath, "utf-8"));
10205
+ const raw = JSON.parse(readFileSync6(filePath, "utf-8"));
10880
10206
  const facts = Array.isArray(raw.facts) ? raw.facts.filter(
10881
10207
  (f) => !!f && typeof f === "object" && typeof f.id === "string" && typeof f.subject === "string" && typeof f.relation === "string" && typeof f.object === "string"
10882
10208
  ) : [];
@@ -10889,7 +10215,7 @@ function loadFacts(filePath) {
10889
10215
  async function persistFacts(filePath) {
10890
10216
  if (!filePath) return true;
10891
10217
  try {
10892
- await ensureDir2(dirname5(filePath));
10218
+ await ensureDir2(dirname4(filePath));
10893
10219
  await atomicWrite2(
10894
10220
  filePath,
10895
10221
  JSON.stringify({ facts: state28.facts, nextId: state28.nextId }, null, 2)
@@ -11156,8 +10482,8 @@ var plugin31 = {
11156
10482
  var knowledge_graph_default = plugin31;
11157
10483
 
11158
10484
  // src/license-audit-gate/index.ts
11159
- import { readFileSync as readFileSync8 } from "node:fs";
11160
- import { resolve as resolve16 } from "node:path";
10485
+ import { readFileSync as readFileSync7 } from "node:fs";
10486
+ import { resolve as resolve14 } from "node:path";
11161
10487
  var API_VERSION23 = "^0.1.10";
11162
10488
  var state29 = {
11163
10489
  invocations: 0,
@@ -11219,8 +10545,8 @@ function auditPackages(names, allowedLicenses) {
11219
10545
  for (const name of names) {
11220
10546
  let licenses = [];
11221
10547
  try {
11222
- const pkgPath = resolve16("node_modules", name, "package.json");
11223
- const raw = JSON.parse(readFileSync8(pkgPath, "utf-8"));
10548
+ const pkgPath = resolve14("node_modules", name, "package.json");
10549
+ const raw = JSON.parse(readFileSync7(pkgPath, "utf-8"));
11224
10550
  licenses = extractLicenseStrings(raw);
11225
10551
  } catch {
11226
10552
  errors.push(name);
@@ -11399,12 +10725,12 @@ Allowed licenses: ${cfg.allowedLicenses.join(", ")}
11399
10725
  var license_audit_gate_default = plugin32;
11400
10726
 
11401
10727
  // src/lint-gate/index.ts
11402
- import { execFile as execFile8 } from "node:child_process";
11403
- import { readFileSync as readFileSync9 } from "node:fs";
10728
+ import { execFile as execFile7 } from "node:child_process";
10729
+ import { readFileSync as readFileSync8 } from "node:fs";
11404
10730
  import { mkdtemp, readFile as readFile11, rm, writeFile as writeFile3 } from "node:fs/promises";
11405
- import { createRequire as createRequire2 } from "node:module";
10731
+ import { createRequire } from "node:module";
11406
10732
  import { tmpdir } from "node:os";
11407
- import { dirname as dirname6, isAbsolute as isAbsolute16, join as join5, relative as relative16, resolve as resolve17, sep as sep4 } from "node:path";
10733
+ import { dirname as dirname5, isAbsolute as isAbsolute14, join as join4, relative as relative14, resolve as resolve15, sep as sep3 } from "node:path";
11408
10734
  var API_VERSION24 = "^0.1.10";
11409
10735
  var state30 = {
11410
10736
  /** Total PreToolUse invocations. */
@@ -11442,22 +10768,22 @@ var LINTER_PACKAGES = {
11442
10768
  biome: "@biomejs/biome",
11443
10769
  eslint: "eslint"
11444
10770
  };
11445
- var linterCache = new BoundedMap({ max: 32, ttlMs: 3e5 });
11446
- function isInside2(parent, candidate) {
11447
- const rel = relative16(parent, candidate);
11448
- return rel === "" || !rel.startsWith(`..${sep4}`) && rel !== ".." && !isAbsolute16(rel);
10771
+ var linterCache = new runtime_exports.BoundedMap({ max: 32, ttlMs: 3e5 });
10772
+ function isInside(parent, candidate) {
10773
+ const rel = relative14(parent, candidate);
10774
+ return rel === "" || !rel.startsWith(`..${sep3}`) && rel !== ".." && !isAbsolute14(rel);
11449
10775
  }
11450
10776
  function resolveLocalLinter(name, cwd) {
11451
10777
  try {
11452
10778
  const packageName = LINTER_PACKAGES[name];
11453
- const requireFromProject = createRequire2(resolve17(cwd, "package.json"));
10779
+ const requireFromProject = createRequire(resolve15(cwd, "package.json"));
11454
10780
  const packagePath = requireFromProject.resolve(`${packageName}/package.json`);
11455
- const packageJson = JSON.parse(readFileSync9(packagePath, "utf-8"));
10781
+ const packageJson = JSON.parse(readFileSync8(packagePath, "utf-8"));
11456
10782
  const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[name] ?? Object.values(packageJson.bin ?? {})[0];
11457
- if (!relativeBin || isAbsolute16(relativeBin)) return null;
11458
- const packageDir = dirname6(packagePath);
11459
- const entry = resolve17(packageDir, relativeBin);
11460
- if (!isInside2(packageDir, entry)) return null;
10783
+ if (!relativeBin || isAbsolute14(relativeBin)) return null;
10784
+ const packageDir = dirname5(packagePath);
10785
+ const entry = resolve15(packageDir, relativeBin);
10786
+ if (!isInside(packageDir, entry)) return null;
11461
10787
  return {
11462
10788
  cmd: process.execPath,
11463
10789
  args: name === "biome" ? [entry, "check", "--reporter=json"] : [entry, "--format=json"],
@@ -11470,7 +10796,7 @@ function resolveLocalLinter(name, cwd) {
11470
10796
  function runCommand2(command, args, timeoutMs, cwd, signal) {
11471
10797
  return new Promise((resolveResult) => {
11472
10798
  try {
11473
- execFile8(
10799
+ execFile7(
11474
10800
  command,
11475
10801
  args,
11476
10802
  {
@@ -11510,8 +10836,8 @@ async function lintContent(content, filePath, linter, timeoutMs, cwd, signal) {
11510
10836
  const ext = filePath.includes(".") ? filePath.slice(filePath.lastIndexOf(".")) : ".ts";
11511
10837
  let tmpDir;
11512
10838
  try {
11513
- tmpDir = await mkdtemp(join5(tmpdir(), "lint-gate-"));
11514
- const tmpFile = join5(tmpDir, `input${ext}`);
10839
+ tmpDir = await mkdtemp(join4(tmpdir(), "lint-gate-"));
10840
+ const tmpFile = join4(tmpDir, `input${ext}`);
11515
10841
  await writeFile3(tmpFile, content, "utf-8");
11516
10842
  const fullArgs = [...linter.args, tmpFile];
11517
10843
  const result = await runCommand2(linter.cmd, fullArgs, timeoutMs, cwd, signal);
@@ -11529,8 +10855,8 @@ async function lintAndFix(content, filePath, linter, timeoutMs, cwd, signal) {
11529
10855
  const ext = filePath.includes(".") ? filePath.slice(filePath.lastIndexOf(".")) : ".ts";
11530
10856
  let tmpDir;
11531
10857
  try {
11532
- tmpDir = await mkdtemp(join5(tmpdir(), "lint-gate-fix-"));
11533
- const tmpFile = join5(tmpDir, `input${ext}`);
10858
+ tmpDir = await mkdtemp(join4(tmpdir(), "lint-gate-fix-"));
10859
+ const tmpFile = join4(tmpDir, `input${ext}`);
11534
10860
  await writeFile3(tmpFile, content, "utf-8");
11535
10861
  const fixArgs = linter.name === "biome" ? [linter.args[0], "check", "--write", tmpFile] : [linter.args[0], "--fix", tmpFile];
11536
10862
  await runCommand2(linter.cmd, fixArgs, timeoutMs, cwd, signal);
@@ -11631,11 +10957,11 @@ var plugin33 = {
11631
10957
  state30.hitCount = 0;
11632
10958
  state30.fixCount = 0;
11633
10959
  state30.linterErrorCount = 0;
11634
- state30.hookUnregister = releaseHandle(state30.hookUnregister);
10960
+ state30.hookUnregister = (0, runtime_exports.releaseHandle)(state30.hookUnregister);
11635
10961
  state30.lastResult = null;
11636
10962
  linterCache.clear();
11637
10963
  const cfg = readConfig28(api.config.extensions?.["lint-gate"]);
11638
- const cwd = resolve17(api.config.cwd ?? process.cwd());
10964
+ const cwd = resolve15(api.config.cwd ?? process.cwd());
11639
10965
  const linterReady = detectLinter(cfg.linter, cwd).then((linter) => {
11640
10966
  if (!linter) {
11641
10967
  api.log.warn("lint-gate: no linter found (biome or eslint) \u2014 hook will be a no-op", {
@@ -12137,8 +11463,8 @@ var plugin34 = {
12137
11463
  var llm_cache_default = plugin34;
12138
11464
 
12139
11465
  // src/loop-breaker/index.ts
12140
- import { execFile as execFile9 } from "node:child_process";
12141
- import { isAbsolute as isAbsolute17, relative as relative17 } from "node:path";
11466
+ import { execFile as execFile8 } from "node:child_process";
11467
+ import { isAbsolute as isAbsolute15, relative as relative15 } from "node:path";
12142
11468
  var state32 = {
12143
11469
  lastFingerprint: null,
12144
11470
  streak: 0,
@@ -12249,13 +11575,13 @@ function hashString2(value) {
12249
11575
  return String(h >>> 0);
12250
11576
  }
12251
11577
  async function gitDiffFingerprint(cwd, targetPath, signal) {
12252
- const pathspec = isAbsolute17(targetPath) ? relative17(cwd, targetPath) : targetPath;
11578
+ const pathspec = isAbsolute15(targetPath) ? relative15(cwd, targetPath) : targetPath;
12253
11579
  if (!pathspec || pathspec === ".." || pathspec.startsWith("../") || pathspec.startsWith("..\\")) {
12254
11580
  return null;
12255
11581
  }
12256
11582
  try {
12257
- const diff = await new Promise((resolve29, reject) => {
12258
- execFile9(
11583
+ const diff = await new Promise((resolve27, reject) => {
11584
+ execFile8(
12259
11585
  "git",
12260
11586
  ["diff", "--no-ext-diff", "--", pathspec],
12261
11587
  {
@@ -12271,7 +11597,7 @@ async function gitDiffFingerprint(cwd, targetPath, signal) {
12271
11597
  },
12272
11598
  (error, stdout) => {
12273
11599
  if (error) reject(error);
12274
- else resolve29(stdout);
11600
+ else resolve27(stdout);
12275
11601
  }
12276
11602
  );
12277
11603
  });
@@ -12628,7 +11954,17 @@ var plugin35 = {
12628
11954
  var loop_breaker_default = plugin35;
12629
11955
 
12630
11956
  // src/migration-planner/index.ts
12631
- import { existsSync as existsSync4, readFileSync as readFileSync10 } from "node:fs";
11957
+ import { existsSync as existsSync4, readFileSync as readFileSync9 } from "node:fs";
11958
+
11959
+ // src/runtime/llm.ts
11960
+ import {
11961
+ parseLlmJsonObject,
11962
+ runOptionalPluginCouncil,
11963
+ runOptionalPluginLlm,
11964
+ stripOuterMarkdownFence
11965
+ } from "@wrongstack/plugin-sdk/runtime";
11966
+
11967
+ // src/migration-planner/index.ts
12632
11968
  var API_VERSION25 = "^0.1.10";
12633
11969
  var state33 = {
12634
11970
  plansGenerated: 0,
@@ -12665,10 +12001,10 @@ function readChangelog(packageName, cfg) {
12665
12001
  candidates.push(`node_modules/${packageName}/CHANGELOG.md`);
12666
12002
  candidates.push(`node_modules/${packageName}/changelog.md`);
12667
12003
  for (const candidate of candidates) {
12668
- if (!withinProject(candidate)) continue;
12004
+ if (!(0, runtime_exports.withinProject)(candidate)) continue;
12669
12005
  if (existsSync4(candidate)) {
12670
12006
  try {
12671
- const content = readFileSync10(candidate, "utf-8");
12007
+ const content = readFileSync9(candidate, "utf-8");
12672
12008
  return { source: candidate, content: content.slice(0, cfg.maxChars) };
12673
12009
  } catch {
12674
12010
  }
@@ -12876,7 +12212,7 @@ var plugin36 = {
12876
12212
  state33.llmAnalysisCount = 0;
12877
12213
  state33.llmFallbackCount = 0;
12878
12214
  state33.lastPlan = null;
12879
- state33.hookUnregister = releaseHandle(state33.hookUnregister);
12215
+ state33.hookUnregister = (0, runtime_exports.releaseHandle)(state33.hookUnregister);
12880
12216
  const cfg = readConfig31(api.config.extensions?.["migration-planner"]);
12881
12217
  const hook = (input) => {
12882
12218
  if (!cfg.enabled) return;
@@ -12884,14 +12220,14 @@ var plugin36 = {
12884
12220
  const inp = input.toolInput ?? {};
12885
12221
  const path = inp["path"];
12886
12222
  if (!path) return;
12887
- const basename8 = path.split(/[/\\]/).pop() ?? "";
12223
+ const basename7 = path.split(/[/\\]/).pop() ?? "";
12888
12224
  if (!/^(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/i.test(
12889
- basename8
12225
+ basename7
12890
12226
  )) {
12891
12227
  return;
12892
12228
  }
12893
12229
  return {
12894
- additionalContext: `Manifest file ${basename8} changed. Consider running migration_plan if a dependency version was updated.`
12230
+ additionalContext: `Manifest file ${basename7} changed. Consider running migration_plan if a dependency version was updated.`
12895
12231
  };
12896
12232
  };
12897
12233
  state33.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook, {
@@ -13499,7 +12835,7 @@ async function deliver(event, payload) {
13499
12835
  }
13500
12836
  const result = await deliverViaChannel(ch, event, {
13501
12837
  title: typeof payload.title === "string" ? payload.title : event,
13502
- body: typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : safeJsonStringify(payload),
12838
+ body: typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : (0, runtime_exports.safeJsonStringify)(payload),
13503
12839
  level: event === "tool.error" || event === "budget.threshold" ? "warning" : "info",
13504
12840
  source: event,
13505
12841
  metadata: payload
@@ -13783,6 +13119,12 @@ var plugin38 = {
13783
13119
  };
13784
13120
  var notify_hub_default = plugin38;
13785
13121
 
13122
+ // src/runtime/redos-guard.ts
13123
+ import {
13124
+ withReDoSGuard,
13125
+ guardedMatcher
13126
+ } from "@wrongstack/plugin-sdk/runtime";
13127
+
13786
13128
  // src/path-guard/glob.ts
13787
13129
  var GLOB_REDOS_BUDGET_MS = 250;
13788
13130
  function mergeGuardedRegex(patterns) {
@@ -13897,8 +13239,8 @@ function isRootPathScope(path) {
13897
13239
  function isDirectoryAmbiguousPath(path) {
13898
13240
  const normalized = normalizePath2(path).replace(/\/$/, "");
13899
13241
  if (isRootPathScope(normalized)) return true;
13900
- const basename8 = normalized.slice(normalized.lastIndexOf("/") + 1);
13901
- return path.endsWith("/") || basename8.length > 0 && !basename8.includes(".");
13242
+ const basename7 = normalized.slice(normalized.lastIndexOf("/") + 1);
13243
+ return path.endsWith("/") || basename7.length > 0 && !basename7.includes(".");
13902
13244
  }
13903
13245
  function hasConfiguredProtectedDescendant(path, patterns) {
13904
13246
  const normalized = normalizePath2(path).replace(/\/$/, "").toLowerCase();
@@ -14386,7 +13728,7 @@ function heredocDelimiterOnLine(line) {
14386
13728
  const stripTabs = line[cursor] === "-";
14387
13729
  if (stripTabs) cursor += 1;
14388
13730
  while (line[cursor] === " " || line[cursor] === " ") cursor += 1;
14389
- let delimiter2 = "";
13731
+ let delimiter = "";
14390
13732
  let delimiterQuote = null;
14391
13733
  let quoted = false;
14392
13734
  for (; cursor < line.length; cursor += 1) {
@@ -14398,9 +13740,9 @@ function heredocDelimiterOnLine(line) {
14398
13740
  } else if (delimiterChar === "\\" && delimiterQuote === '"' && cursor + 1 < line.length) {
14399
13741
  quoted = true;
14400
13742
  cursor += 1;
14401
- delimiter2 += line[cursor] ?? "";
13743
+ delimiter += line[cursor] ?? "";
14402
13744
  } else {
14403
- delimiter2 += delimiterChar;
13745
+ delimiter += delimiterChar;
14404
13746
  }
14405
13747
  continue;
14406
13748
  }
@@ -14412,13 +13754,13 @@ function heredocDelimiterOnLine(line) {
14412
13754
  if (delimiterChar === "\\" && cursor + 1 < line.length) {
14413
13755
  quoted = true;
14414
13756
  cursor += 1;
14415
- delimiter2 += line[cursor] ?? "";
13757
+ delimiter += line[cursor] ?? "";
14416
13758
  continue;
14417
13759
  }
14418
13760
  if (/\s|[;&|<>]/.test(delimiterChar)) break;
14419
- delimiter2 += delimiterChar;
13761
+ delimiter += delimiterChar;
14420
13762
  }
14421
- return delimiter2.length > 0 ? { delimiter: delimiter2, start: index, end: cursor, quoted, stripTabs } : null;
13763
+ return delimiter.length > 0 ? { delimiter, start: index, end: cursor, quoted, stripTabs } : null;
14422
13764
  }
14423
13765
  return null;
14424
13766
  }
@@ -15073,13 +14415,13 @@ function operationLabel(toolName) {
15073
14415
 
15074
14416
  // src/path-guard/index.ts
15075
14417
  import { realpathSync } from "node:fs";
15076
- import { resolve as resolve18 } from "node:path";
14418
+ import { resolve as resolve16 } from "node:path";
15077
14419
  function isSymlinkEscape(path, cwd) {
15078
- if (!withinProject(path)) return false;
14420
+ if (!(0, runtime_exports.withinProject)(path)) return false;
15079
14421
  try {
15080
- const abs = resolve18(cwd ?? process.cwd(), path);
14422
+ const abs = resolve16(cwd ?? process.cwd(), path);
15081
14423
  const real = realpathSync(abs);
15082
- return !withinProject(real);
14424
+ return !(0, runtime_exports.withinProject)(real);
15083
14425
  } catch {
15084
14426
  return false;
15085
14427
  }
@@ -15348,8 +14690,8 @@ var plugin39 = {
15348
14690
  var path_guard_default = plugin39;
15349
14691
 
15350
14692
  // src/performance-regression-gate/index.ts
15351
- import { existsSync as existsSync5, readFileSync as readFileSync11 } from "node:fs";
15352
- import { isAbsolute as isAbsolute18, relative as relative18, resolve as resolve19 } from "node:path";
14693
+ import { existsSync as existsSync5, readFileSync as readFileSync10 } from "node:fs";
14694
+ import { isAbsolute as isAbsolute16, relative as relative16, resolve as resolve17 } from "node:path";
15353
14695
  var API_VERSION26 = "^0.1.10";
15354
14696
  var state36 = {
15355
14697
  invocationCount: 0,
@@ -15372,21 +14714,21 @@ function readConfig35(raw) {
15372
14714
  thresholdPercent: threshold
15373
14715
  };
15374
14716
  }
15375
- function withinProject3(p, cwd = process.cwd()) {
14717
+ function withinProject17(p, cwd = process.cwd()) {
15376
14718
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
15377
- const root = resolve19(cwd);
15378
- const resolved = isAbsolute18(p) ? resolve19(p) : resolve19(root, p);
15379
- const rel = relative18(root, resolved);
14719
+ const root = resolve17(cwd);
14720
+ const resolved = isAbsolute16(p) ? resolve17(p) : resolve17(root, p);
14721
+ const rel = relative16(root, resolved);
15380
14722
  if (rel === "" || rel === ".") return true;
15381
14723
  if (rel.startsWith("..")) return false;
15382
- if (isAbsolute18(rel)) return false;
14724
+ if (isAbsolute16(rel)) return false;
15383
14725
  return true;
15384
14726
  }
15385
14727
  function resolveProjectPath6(rawPath, cwd = process.cwd()) {
15386
14728
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
15387
- const root = resolve19(cwd);
15388
- const resolved = isAbsolute18(rawPath) ? resolve19(rawPath) : resolve19(root, rawPath);
15389
- if (!withinProject3(resolved, cwd)) return null;
14729
+ const root = resolve17(cwd);
14730
+ const resolved = isAbsolute16(rawPath) ? resolve17(rawPath) : resolve17(root, rawPath);
14731
+ if (!withinProject17(resolved, cwd)) return null;
15390
14732
  return resolved;
15391
14733
  }
15392
14734
  function isValidNumber(n) {
@@ -15416,7 +14758,7 @@ function flattenResults(results) {
15416
14758
  function loadResults(path) {
15417
14759
  if (!path || !existsSync5(path)) return null;
15418
14760
  try {
15419
- const raw = JSON.parse(readFileSync11(path, "utf-8"));
14761
+ const raw = JSON.parse(readFileSync10(path, "utf-8"));
15420
14762
  return raw;
15421
14763
  } catch {
15422
14764
  return null;
@@ -15798,9 +15140,9 @@ function readConfig36(raw) {
15798
15140
  var plugin_stack_observer_default = PLUGIN;
15799
15141
 
15800
15142
  // src/pr-drafter/index.ts
15801
- import { execFile as execFile10 } from "node:child_process";
15143
+ import { execFile as execFile9 } from "node:child_process";
15802
15144
  import { mkdir as mkdir2, writeFile as writeFile4 } from "node:fs/promises";
15803
- import { dirname as dirname7, isAbsolute as isAbsolute19, relative as relative19, resolve as resolve20 } from "node:path";
15145
+ import { dirname as dirname6, isAbsolute as isAbsolute17, relative as relative17, resolve as resolve18 } from "node:path";
15804
15146
  var API_VERSION27 = "^0.1.10";
15805
15147
  var state38 = {
15806
15148
  commits: [],
@@ -15839,15 +15181,15 @@ function readConfig37(raw) {
15839
15181
  }
15840
15182
  function resolveProjectPath7(rawPath, cwd = process.cwd()) {
15841
15183
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
15842
- const root = resolve20(cwd);
15843
- const resolved = isAbsolute19(rawPath) ? resolve20(rawPath) : resolve20(root, rawPath);
15844
- const rel = relative19(root, resolved);
15845
- if (rel === "" || !rel.startsWith("..") && !isAbsolute19(rel)) return resolved;
15184
+ const root = resolve18(cwd);
15185
+ const resolved = isAbsolute17(rawPath) ? resolve18(rawPath) : resolve18(root, rawPath);
15186
+ const rel = relative17(root, resolved);
15187
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute17(rel)) return resolved;
15846
15188
  return null;
15847
15189
  }
15848
15190
  function runGit4(args, timeout) {
15849
15191
  return new Promise((resolveOutput) => {
15850
- execFile10(
15192
+ execFile9(
15851
15193
  "git",
15852
15194
  args,
15853
15195
  {
@@ -15932,7 +15274,7 @@ async function writeDraft(cfg, llm) {
15932
15274
  }
15933
15275
  const draft = await buildDraft(cfg, llm);
15934
15276
  try {
15935
- await mkdir2(dirname7(resolved), { recursive: true });
15277
+ await mkdir2(dirname6(resolved), { recursive: true });
15936
15278
  await writeFile4(resolved, draft.body);
15937
15279
  state38.draftsWritten += 1;
15938
15280
  } catch {
@@ -15996,7 +15338,7 @@ var plugin41 = {
15996
15338
  state38.draftsWritten = 0;
15997
15339
  state38.draftErrors = 0;
15998
15340
  state38.stopInvocations = 0;
15999
- state38.stopHookUnregister = releaseHandle(state38.stopHookUnregister);
15341
+ state38.stopHookUnregister = (0, runtime_exports.releaseHandle)(state38.stopHookUnregister);
16000
15342
  for (const off of state38.eventUnsubscribers) {
16001
15343
  try {
16002
15344
  off();
@@ -16065,7 +15407,7 @@ var plugin41 = {
16065
15407
  const resolved = resolveProjectPath7(cfg.outputPath);
16066
15408
  if (!resolved) return { ok: false, error: "outputPath resolves outside project" };
16067
15409
  try {
16068
- await mkdir2(dirname7(resolved), { recursive: true });
15410
+ await mkdir2(dirname6(resolved), { recursive: true });
16069
15411
  await writeFile4(resolved, draft.body);
16070
15412
  state38.draftsWritten += 1;
16071
15413
  return {
@@ -16290,136 +15632,10 @@ var process_guard_default = plugin42;
16290
15632
  import { performance as performance2 } from "node:perf_hooks";
16291
15633
 
16292
15634
  // src/runtime/credential-patterns.ts
16293
- var CREDENTIAL_PATTERNS = [
16294
- // LLM provider keys
16295
- {
16296
- type: "anthropic_key",
16297
- regex: /(?<![A-Za-z0-9])sk-ant-api\d+-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g
16298
- },
16299
- { type: "openai_key", regex: /(?<![A-Za-z0-9])sk-(?!ant)(?:proj-)?[A-Za-z0-9_-]{20,}(?![A-Za-z0-9])/g },
16300
- // GitHub. `ghp_` is only the personal-access-token prefix — the OAuth
16301
- // (`gho_`), user-to-server (`ghu_`), server-to-server (`ghs_`) and
16302
- // refresh (`ghr_`) tokens grant the same or broader access and were
16303
- // previously not detected at all.
16304
- { type: "github_pat", regex: /(?<![A-Za-z0-9])ghp_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g },
16305
- {
16306
- type: "github_oauth_token",
16307
- regex: /(?<![A-Za-z0-9])gh[ousr]_[A-Za-z0-9]{36,}(?![A-Za-z0-9])/g
16308
- },
16309
- { type: "github_pat_v2", regex: /(?<![A-Za-z0-9])github_pat_[A-Za-z0-9_]{50,}(?![A-Za-z0-9])/g },
16310
- // GitLab
16311
- { type: "gitlab_pat", regex: /(?<![A-Za-z0-9])glpat-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
16312
- {
16313
- type: "gitlab_runner_token",
16314
- regex: /(?<![A-Za-z0-9])glrt-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
16315
- },
16316
- // npm — a leaked publish token is a supply-chain compromise.
16317
- { type: "npm_token", regex: /(?<![A-Za-z0-9])npm_[A-Za-z0-9]{36}(?![A-Za-z0-9])/g },
16318
- // AWS
16319
- { type: "aws_access_key", regex: /(?<![A-Za-z0-9])AKIA[0-9A-Z]{16}(?![A-Za-z0-9])/g },
16320
- // GCP
16321
- { type: "gcp_key", regex: /(?<![A-Za-z0-9])AIza[0-9A-Za-z_-]{35}(?![A-Za-z0-9])/g },
16322
- // Slack. `xoxe` (token-rotation) and `xapp` (app-level) were missing;
16323
- // both are as sensitive as the bot/user tokens already covered.
16324
- {
16325
- type: "slack_token",
16326
- regex: /(?<![A-Za-z0-9-])xox[abposer]-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g
16327
- },
16328
- { type: "slack_app_token", regex: /(?<![A-Za-z0-9-])xapp-\d-[A-Za-z0-9-]{10,}(?![A-Za-z0-9-])/g },
16329
- {
16330
- type: "slack_webhook",
16331
- regex: /https:\/\/hooks\.slack\.com\/services\/T[A-Za-z0-9_-]+\/B[A-Za-z0-9_-]+\/[A-Za-z0-9]{16,}/g
16332
- },
16333
- // Stripe
16334
- {
16335
- type: "stripe_key",
16336
- regex: /(?<![A-Za-z0-9])sk_(?:live|test)_[A-Za-z0-9]{24,}(?![A-Za-z0-9])/g
16337
- },
16338
- // Twilio
16339
- { type: "twilio_sid", regex: /(?<![A-Za-z0-9])AC[a-f0-9]{32}(?![A-Za-z0-9])/g },
16340
- // Telegram
16341
- {
16342
- type: "telegram_bot_token",
16343
- regex: /(?:(?<![A-Za-z0-9_])|(?<=(?:^|[^A-Za-z0-9_])bot))\d+:[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
16344
- },
16345
- // JWT
16346
- {
16347
- type: "jwt",
16348
- regex: /(?<![A-Za-z0-9/+=])eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}(?![A-Za-z0-9/+=])/g
16349
- },
16350
- // Private keys
16351
- {
16352
- type: "private_key",
16353
- regex: /(?:^|\n)(?:-----BEGIN (?:RSA|EC|OPENSSH|DSA)? ?PRIVATE KEY-----[\s\S]*?-----END (?:RSA|EC|OPENSSH|DSA)? ?PRIVATE KEY-----|-----BEGIN PGP PRIVATE KEY BLOCK-----[\s\S]*?-----END PGP PRIVATE KEY BLOCK-----)(?!\S)/g
16354
- },
16355
- // AI/ML provider tokens
16356
- { type: "huggingface_token", regex: /(?<![A-Za-z0-9])hf_[A-Za-z0-9]{34}(?![A-Za-z0-9])/g },
16357
- { type: "replicate_token", regex: /(?<![A-Za-z0-9])r8_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
16358
- { type: "perplexity_key", regex: /(?<![A-Za-z0-9])pplx-[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
16359
- { type: "groq_key", regex: /(?<![A-Za-z0-9])gsk_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
16360
- // SaaS / infrastructure tokens — each grants API access on the user's
16361
- // account, and each was previously invisible to this gate.
16362
- { type: "sendgrid_key", regex: /(?<![A-Za-z0-9])SG\.[A-Za-z0-9_-]{20,}\.[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
16363
- { type: "digitalocean_token", regex: /(?<![A-Za-z0-9])dop_v1_[a-f0-9]{64}(?![A-Za-z0-9])/g },
16364
- { type: "doppler_token", regex: /(?<![A-Za-z0-9])dp\.(?:pt|st|sa|scim|audit)\.[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
16365
- { type: "shopify_token", regex: /(?<![A-Za-z0-9])shp(?:at|ca|pa|ss)_[a-fA-F0-9]{32}(?![A-Za-z0-9])/g },
16366
- { type: "docker_pat", regex: /(?<![A-Za-z0-9])dckr_pat_[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
16367
- { type: "linear_key", regex: /(?<![A-Za-z0-9])lin_api_[A-Za-z0-9]{40,}(?![A-Za-z0-9])/g },
16368
- { type: "atlassian_token", regex: /(?<![A-Za-z0-9])ATATT3[A-Za-z0-9_\-=]{40,}(?![A-Za-z0-9_\-=])/g },
16369
- { type: "square_token", regex: /(?<![A-Za-z0-9])(?:sq0(?:atp|csp)-|EAAA)[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g },
16370
- {
16371
- type: "azure_storage_key",
16372
- regex: /AccountKey=[A-Za-z0-9+/]{80,}={0,2}/g
16373
- },
16374
- {
16375
- type: "google_oauth_client_secret",
16376
- regex: /(?<![A-Za-z0-9_-])GOCSPX-[A-Za-z0-9_-]{20,}(?![A-Za-z0-9_-])/g
16377
- },
16378
- // Bearer tokens
16379
- {
16380
- type: "bearer_token",
16381
- regex: /(?<![A-Za-z0-9_.~+/-])Bearer\s+[A-Za-z0-9._~+/-]{12,512}=*(?![A-Za-z0-9._~+/-])/g
16382
- },
16383
- // Database URIs. Require password-bearing user-info; credential-free values stay scannable.
16384
- { type: "mongodb_uri", regex: /mongodb(?:\+srv)?:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
16385
- {
16386
- type: "postgres_uri",
16387
- // Query parsers decode percent-encoded parameter names. Recognize each
16388
- // encoded character in `password` so mixed forms such as `pass%77ord`
16389
- // cannot bypass detection while keeping the scan strictly bounded.
16390
- regex: /postgres(?:ql)?:\/\/(?:[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+|[^&\s?"'`#]{1,2048}\?(?:(?!(?:p|%70)(?:a|%61)(?:s|%73)(?:s|%73)(?:w|%77)(?:o|%6[fF])(?:r|%72)(?:d|%64)=)[^&\s#"'`]{1,256}&){0,32}(?:p|%70)(?:a|%61)(?:s|%73)(?:s|%73)(?:w|%77)(?:o|%6[fF])(?:r|%72)(?:d|%64)=[^&\s#"'`]{1,4096})/g
16391
- },
16392
- { type: "mysql_uri", regex: /mysql:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
16393
- { type: "redis_uri", regex: /redis:\/\/[^\s:/@"'`]*:[^\s/@"'`]+@[^\s"'`]+/g },
16394
- {
16395
- // Credentials serialised as JSON, keyed rather than prefixed. Every other
16396
- // entry in this table recognises a credential by its SHAPE (`ghp_`, `sk-`,
16397
- // `eyJ`), which means a key with no distinctive prefix — Azure, a
16398
- // self-hosted gateway, an Anthropic/Codex OAuth token — was invisible to
16399
- // both surfaces. `prompt-firewall` guards the outgoing provider request, so
16400
- // this is what stops a JSON-shaped tool result carrying such a value to a
16401
- // third party.
16402
- //
16403
- // The key is matched in a LOOKBEHIND, so the reported match is the secret
16404
- // itself and the pattern keeps zero capturing groups — `secret-scanner`
16405
- // maps a combined-regex group index back to the pattern that fired, and an
16406
- // inner group would shift that mapping (see the style note above, enforced
16407
- // by credential-pattern-parity.test.ts).
16408
- //
16409
- // Mirrors `json_credential_key` in
16410
- // `@wrongstack/core` → `src/security/secret-scrubber.ts`. Keep the two key
16411
- // lists in step; the core side additionally preserves the key name when it
16412
- // rewrites, which is why it is written with capture groups instead.
16413
- type: "json_credential_key",
16414
- regex: /(?<="[A-Za-z0-9_]{0,64}(?:apiKey|api_key|token|secret|password|authorization|bearer|private_key|access_token|refresh_token|client_secret)"\s{0,8}:\s{0,8}")[^"\\]{8,512}(?=")/gi
16415
- }
16416
- ];
16417
- function cloneCredentialPatterns() {
16418
- return CREDENTIAL_PATTERNS.map((p) => ({
16419
- type: p.type,
16420
- regex: new RegExp(p.regex.source, p.regex.flags)
16421
- }));
16422
- }
15635
+ import {
15636
+ cloneCredentialPatterns,
15637
+ CREDENTIAL_PATTERNS
15638
+ } from "@wrongstack/plugin-sdk/runtime";
16423
15639
 
16424
15640
  // src/prompt-firewall/index.ts
16425
15641
  var KIND_ALIASES = {
@@ -16920,7 +16136,7 @@ var prompt_firewall_default = plugin43;
16920
16136
 
16921
16137
  // src/refactor-suggester/index.ts
16922
16138
  import { readFile as readFile12 } from "node:fs/promises";
16923
- import { isAbsolute as isAbsolute20, relative as relative20, resolve as resolve21 } from "node:path";
16139
+ import { isAbsolute as isAbsolute18, relative as relative18, resolve as resolve19 } from "node:path";
16924
16140
  var API_VERSION28 = "^0.1.10";
16925
16141
  var HOOK_WARNING_COOLDOWN_MS2 = 6e4;
16926
16142
  var state41 = {
@@ -16930,7 +16146,7 @@ var state41 = {
16930
16146
  warningCount: 0,
16931
16147
  errorCount: 0,
16932
16148
  hookUnregister: null,
16933
- lastHookWarning: new BoundedMap({ max: 512, ttlMs: HOOK_WARNING_COOLDOWN_MS2 })
16149
+ lastHookWarning: new runtime_exports.BoundedMap({ max: 512, ttlMs: HOOK_WARNING_COOLDOWN_MS2 })
16934
16150
  };
16935
16151
  var DEFAULTS37 = {
16936
16152
  enabled: false,
@@ -16964,7 +16180,7 @@ function toPosix6(p) {
16964
16180
  return p.replace(/\\/g, "/");
16965
16181
  }
16966
16182
  function relativePath6(p) {
16967
- return toPosix6(relative20(process.cwd(), p));
16183
+ return toPosix6(relative18(process.cwd(), p));
16968
16184
  }
16969
16185
  function leadingIndentLevel(line) {
16970
16186
  const leading = line.match(/^(\s*)/)?.[1] ?? "";
@@ -17051,9 +16267,9 @@ function detectSmells(filePath, content, rules) {
17051
16267
  }
17052
16268
  async function scanPath4(rawPath, cfg) {
17053
16269
  const root = process.cwd();
17054
- const resolved = isAbsolute20(rawPath) ? resolve21(rawPath) : resolve21(root, rawPath);
16270
+ const resolved = isAbsolute18(rawPath) ? resolve19(rawPath) : resolve19(root, rawPath);
17055
16271
  const exts = normalizeExtensions5(cfg.extensions);
17056
- const files = await collectSourceFilesAsync(resolved, { extensions: exts });
16272
+ const files = await (0, runtime_exports.collectSourceFilesAsync)(resolved, { extensions: exts });
17057
16273
  const suggestions = [];
17058
16274
  let scannedFiles = 0;
17059
16275
  let truncated = false;
@@ -17131,14 +16347,14 @@ var plugin44 = {
17131
16347
  const inp = input.toolInput ?? {};
17132
16348
  const sourcePath = inp["path"];
17133
16349
  if (!sourcePath || typeof sourcePath !== "string") return;
17134
- if (!withinProject(sourcePath)) return;
16350
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
17135
16351
  const exts = normalizeExtensions5(cfg.extensions);
17136
- if (!matchesExtension(sourcePath, exts)) return;
16352
+ if (!(0, runtime_exports.matchesExtension)(sourcePath, exts)) return;
17137
16353
  state41.hookInvocationCount += 1;
17138
16354
  const now = Date.now();
17139
16355
  const lastWarning = state41.lastHookWarning.get(sourcePath);
17140
16356
  if (lastWarning !== void 0 && now - lastWarning < HOOK_WARNING_COOLDOWN_MS2) return;
17141
- const resolved = resolve21(process.cwd(), sourcePath);
16357
+ const resolved = resolve19(process.cwd(), sourcePath);
17142
16358
  let content;
17143
16359
  try {
17144
16360
  content = await readFile12(resolved, "utf-8");
@@ -17171,7 +16387,7 @@ var plugin44 = {
17171
16387
  async execute(input) {
17172
16388
  if (!cfg.enabled) return { ok: false, error: "refactor-suggester is disabled" };
17173
16389
  const rawPath = typeof input.path === "string" ? input.path : ".";
17174
- if (!withinProject(rawPath)) {
16390
+ if (!(0, runtime_exports.withinProject)(rawPath)) {
17175
16391
  return { ok: false, error: "path is outside the project root" };
17176
16392
  }
17177
16393
  state41.scanCount += 1;
@@ -17185,7 +16401,7 @@ var plugin44 = {
17185
16401
  state41.suggestionCount += result.suggestions.length;
17186
16402
  return {
17187
16403
  ok: true,
17188
- path: relativePath6(resolve21(process.cwd(), rawPath)),
16404
+ path: relativePath6(resolve19(process.cwd(), rawPath)),
17189
16405
  scannedFiles: result.scannedFiles,
17190
16406
  discoveredFiles: result.discoveredFiles,
17191
16407
  // Say so when the cap stopped the walk early: a partial scan
@@ -17266,7 +16482,7 @@ var plugin44 = {
17266
16482
  var refactor_suggester_default = plugin44;
17267
16483
 
17268
16484
  // src/release-notes-generator/index.ts
17269
- import { execFile as execFile11 } from "node:child_process";
16485
+ import { execFile as execFile10 } from "node:child_process";
17270
16486
  var API_VERSION29 = "^0.1.10";
17271
16487
  var state42 = {
17272
16488
  generateCount: 0,
@@ -17318,7 +16534,7 @@ function formatCommit(c, includeScope) {
17318
16534
  }
17319
16535
  function runGit5(args, signal) {
17320
16536
  return new Promise((resolveOutput, reject) => {
17321
- execFile11(
16537
+ execFile10(
17322
16538
  "git",
17323
16539
  args,
17324
16540
  {
@@ -17600,8 +16816,8 @@ var plugin45 = {
17600
16816
  var release_notes_generator_default = plugin45;
17601
16817
 
17602
16818
  // src/schema-evolution-guard/index.ts
17603
- import { readFileSync as readFileSync12 } from "node:fs";
17604
- import { basename as basename6 } from "node:path";
16819
+ import { readFileSync as readFileSync11 } from "node:fs";
16820
+ import { basename as basename5 } from "node:path";
17605
16821
  var API_VERSION30 = "^0.1.10";
17606
16822
  var state43 = {
17607
16823
  invocationCount: 0,
@@ -17788,7 +17004,7 @@ var plugin46 = {
17788
17004
  const filePath = typeof toolInput["path"] === "string" ? toolInput["path"] : void 0;
17789
17005
  if (!filePath) return;
17790
17006
  state43.invocationCount += 1;
17791
- const fileName = basename6(filePath);
17007
+ const fileName = basename5(filePath);
17792
17008
  if (!matchesAnyPattern2(fileName, cfg.filePatterns)) {
17793
17009
  state43.skippedCount += 1;
17794
17010
  return;
@@ -17801,9 +17017,9 @@ var plugin46 = {
17801
17017
  let content;
17802
17018
  if (typeof toolInput["content"] === "string") {
17803
17019
  content = toolInput["content"];
17804
- } else if (withinProject(filePath)) {
17020
+ } else if ((0, runtime_exports.withinProject)(filePath)) {
17805
17021
  try {
17806
- content = readFileSync12(filePath, "utf-8");
17022
+ content = readFileSync11(filePath, "utf-8");
17807
17023
  } catch {
17808
17024
  content = void 0;
17809
17025
  }
@@ -18249,8 +17465,8 @@ var plugin47 = {
18249
17465
  setup(api) {
18250
17466
  const previous = runtimes.get(api);
18251
17467
  if (previous) {
18252
- previous.state.hookUnregister = releaseHandle(previous.state.hookUnregister);
18253
- previous.state.postHookUnregister = releaseHandle(previous.state.postHookUnregister);
17468
+ previous.state.hookUnregister = (0, runtime_exports.releaseHandle)(previous.state.hookUnregister);
17469
+ previous.state.postHookUnregister = (0, runtime_exports.releaseHandle)(previous.state.postHookUnregister);
18254
17470
  }
18255
17471
  const cfg = readConfig43(api.config.extensions?.["secret-scanner"]);
18256
17472
  PATTERNS3 = [...BASE_PATTERNS];
@@ -18397,7 +17613,7 @@ var secret_scanner_default = plugin47;
18397
17613
 
18398
17614
  // src/security-hotspot-scanner/index.ts
18399
17615
  import { readdir as readdir2, readFile as readFile13, stat as stat5 } from "node:fs/promises";
18400
- import { isAbsolute as isAbsolute21, relative as relative21, resolve as resolve22 } from "node:path";
17616
+ import { isAbsolute as isAbsolute19, relative as relative19, resolve as resolve20 } from "node:path";
18401
17617
  var API_VERSION31 = "^0.1.10";
18402
17618
  var state44 = {
18403
17619
  scanCount: 0,
@@ -18407,7 +17623,7 @@ var state44 = {
18407
17623
  skippedCount: 0,
18408
17624
  blockedCount: 0,
18409
17625
  lastResult: null,
18410
- knownHotspots: new BoundedSet({ max: 5e3 }),
17626
+ knownHotspots: new runtime_exports.BoundedSet({ max: 5e3 }),
18411
17627
  hookUnregister: null
18412
17628
  };
18413
17629
  var DEFAULTS41 = {
@@ -18488,8 +17704,8 @@ function isSourceFile2(filePath, extensions) {
18488
17704
  async function scanPath5(inputPath, cfg) {
18489
17705
  const start = Date.now();
18490
17706
  const root = process.cwd();
18491
- const resolved = isAbsolute21(inputPath) ? resolve22(inputPath) : resolve22(root, inputPath);
18492
- if (!withinProject(inputPath)) {
17707
+ const resolved = isAbsolute19(inputPath) ? resolve20(inputPath) : resolve20(root, inputPath);
17708
+ if (!(0, runtime_exports.withinProject)(inputPath)) {
18493
17709
  return {
18494
17710
  path: inputPath,
18495
17711
  scanned: false,
@@ -18509,7 +17725,7 @@ async function scanPath5(inputPath, cfg) {
18509
17725
  filesScanned += 1;
18510
17726
  const findings = scanSource(content, maxPerFile);
18511
17727
  for (const f of findings) {
18512
- allFindings.push({ ...f, snippet: `${relative21(root, filePath)}:${f.line}: ${f.snippet}` });
17728
+ allFindings.push({ ...f, snippet: `${relative19(root, filePath)}:${f.line}: ${f.snippet}` });
18513
17729
  if (allFindings.length >= cfg.maxFindings) return;
18514
17730
  }
18515
17731
  } catch {
@@ -18524,7 +17740,7 @@ async function scanPath5(inputPath, cfg) {
18524
17740
  }
18525
17741
  for (const entry of entries) {
18526
17742
  if (allFindings.length >= cfg.maxFindings) return;
18527
- const full = resolve22(dir, entry);
17743
+ const full = resolve20(dir, entry);
18528
17744
  try {
18529
17745
  const st = await stat5(full);
18530
17746
  if (st.isDirectory()) {
@@ -18628,7 +17844,7 @@ var plugin48 = {
18628
17844
  const inp = input.toolInput ?? {};
18629
17845
  const sourcePath = inp["path"];
18630
17846
  if (!sourcePath || typeof sourcePath !== "string") return;
18631
- if (!withinProject(sourcePath)) return;
17847
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
18632
17848
  const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
18633
17849
  if (!scanOnChangeSet.has(ext)) {
18634
17850
  state44.skippedCount += 1;
@@ -18793,7 +18009,7 @@ var security_hotspot_scanner_default = plugin48;
18793
18009
 
18794
18010
  // src/semantic-search-indexer/index.ts
18795
18011
  import * as fs2 from "node:fs/promises";
18796
- import { isAbsolute as isAbsolute22, relative as relative22, resolve as resolve23 } from "node:path";
18012
+ import { isAbsolute as isAbsolute20, relative as relative20, resolve as resolve21 } from "node:path";
18797
18013
  import { DEFAULT_WALK_IGNORE_DIRS } from "@wrongstack/core/utils";
18798
18014
  var API_VERSION32 = "^0.1.10";
18799
18015
  var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -18871,21 +18087,21 @@ function readConfig45(raw) {
18871
18087
  function normalizeSlashes2(p) {
18872
18088
  return p.replace(/\\/g, "/");
18873
18089
  }
18874
- function withinProject4(p) {
18090
+ function withinProject21(p) {
18875
18091
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
18876
18092
  const root = normalizeSlashes2(process.cwd());
18877
- const resolved = normalizeSlashes2(isAbsolute22(p) ? resolve23(p) : resolve23(root, p));
18878
- const rel = normalizeSlashes2(relative22(root, resolved));
18093
+ const resolved = normalizeSlashes2(isAbsolute20(p) ? resolve21(p) : resolve21(root, p));
18094
+ const rel = normalizeSlashes2(relative20(root, resolved));
18879
18095
  if (rel === "" || rel === ".") return true;
18880
18096
  if (rel.startsWith("..")) return false;
18881
- if (isAbsolute22(rel)) return false;
18097
+ if (isAbsolute20(rel)) return false;
18882
18098
  return true;
18883
18099
  }
18884
18100
  function resolveProjectPath8(p) {
18885
18101
  const raw = typeof p === "string" && p.length > 0 ? p : ".";
18886
- if (!withinProject4(raw)) return null;
18102
+ if (!withinProject21(raw)) return null;
18887
18103
  const root = normalizeSlashes2(process.cwd());
18888
- return normalizeSlashes2(isAbsolute22(raw) ? resolve23(raw) : resolve23(root, raw));
18104
+ return normalizeSlashes2(isAbsolute20(raw) ? resolve21(raw) : resolve21(root, raw));
18889
18105
  }
18890
18106
  function tokenize(text, minLength) {
18891
18107
  const tokens = [];
@@ -18915,7 +18131,7 @@ function shouldIndexFile(filePath, cfg) {
18915
18131
  var INDEX_BATCH_SIZE = 32;
18916
18132
  var YIELD_EVERY_FILES = 64;
18917
18133
  function yieldEventLoop() {
18918
- return new Promise((resolve29) => setImmediate(resolve29));
18134
+ return new Promise((resolve27) => setImmediate(resolve27));
18919
18135
  }
18920
18136
  function addFileToIndex(relPath, content, size, cfg) {
18921
18137
  if (!state45.index || content.includes("\0")) return;
@@ -18969,8 +18185,8 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
18969
18185
  state45.truncated = true;
18970
18186
  return;
18971
18187
  }
18972
- const absChild = normalizeSlashes2(resolve23(absPath, ent.name));
18973
- const relChild = normalizeSlashes2(relative22(root, absChild));
18188
+ const absChild = normalizeSlashes2(resolve21(absPath, ent.name));
18189
+ const relChild = normalizeSlashes2(relative20(root, absChild));
18974
18190
  if (relChild === "" || relChild === ".") continue;
18975
18191
  if (excludes.some((re) => re.test(relChild))) continue;
18976
18192
  if (ent.isDirectory()) {
@@ -19012,7 +18228,7 @@ async function buildIndex(rootPath, cfg) {
19012
18228
  return;
19013
18229
  }
19014
18230
  if (rootStats.isFile()) {
19015
- const relPath = normalizeSlashes2(relative22(normalizeSlashes2(process.cwd()), rootPath));
18231
+ const relPath = normalizeSlashes2(relative20(normalizeSlashes2(process.cwd()), rootPath));
19016
18232
  await indexFileFromStats(rootPath, relPath === "" ? "." : relPath, rootStats, cfg);
19017
18233
  state45.fileCount = state45.index.files.size;
19018
18234
  } else if (rootStats.isDirectory()) {
@@ -19307,16 +18523,16 @@ var semantic_search_indexer_default = plugin49;
19307
18523
  // src/semver-bump/index.ts
19308
18524
  import { expectDefined as expectDefined2 } from "@wrongstack/core/utils";
19309
18525
  import { toErrorMessage } from "@wrongstack/core/utils";
19310
- import { execFile as execFile12 } from "node:child_process";
18526
+ import { execFile as execFile11 } from "node:child_process";
19311
18527
  import { access as access4, readFile as readFile15, readdir as readdir4, writeFile as writeFile5 } from "node:fs/promises";
19312
- import { isAbsolute as isAbsolute23, join as join6, relative as relative23, resolve as resolve24 } from "node:path";
18528
+ import { isAbsolute as isAbsolute21, join as join5, relative as relative21, resolve as resolve22 } from "node:path";
19313
18529
  var API_VERSION33 = "^0.1.10";
19314
18530
  function resolveProjectRoot(rawCwd, root = process.cwd()) {
19315
18531
  if (typeof rawCwd !== "string" || rawCwd.length === 0) return root;
19316
- const base = resolve24(root);
19317
- const resolved = isAbsolute23(rawCwd) ? resolve24(rawCwd) : resolve24(base, rawCwd);
19318
- const rel = relative23(base, resolved);
19319
- if (rel === "" || !rel.startsWith("..") && !isAbsolute23(rel)) return resolved;
18532
+ const base = resolve22(root);
18533
+ const resolved = isAbsolute21(rawCwd) ? resolve22(rawCwd) : resolve22(base, rawCwd);
18534
+ const rel = relative21(base, resolved);
18535
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute21(rel)) return resolved;
19320
18536
  return null;
19321
18537
  }
19322
18538
  var state46 = {
@@ -19328,15 +18544,15 @@ var state46 = {
19328
18544
  lastBump: null
19329
18545
  };
19330
18546
  function runCommand3(command, args, cwd) {
19331
- return new Promise((resolve29, reject) => {
19332
- execFile12(command, args, {
18547
+ return new Promise((resolve27, reject) => {
18548
+ execFile11(command, args, {
19333
18549
  encoding: "utf-8",
19334
18550
  cwd,
19335
18551
  timeout: 3e4,
19336
18552
  windowsHide: true
19337
18553
  }, (err, stdout, stderr) => {
19338
18554
  if (!err) {
19339
- resolve29(stdout.trim());
18555
+ resolve27(stdout.trim());
19340
18556
  return;
19341
18557
  }
19342
18558
  const failure = err;
@@ -19364,14 +18580,14 @@ async function getPackageJson(cwd) {
19364
18580
  }
19365
18581
  async function collectManifests(root) {
19366
18582
  const paths = [];
19367
- const rootPkg = join6(root, "package.json");
18583
+ const rootPkg = join5(root, "package.json");
19368
18584
  try {
19369
18585
  await access4(rootPkg);
19370
18586
  paths.push(rootPkg);
19371
18587
  } catch {
19372
18588
  }
19373
18589
  for (const group of ["packages", "apps"]) {
19374
- const groupDir = join6(root, group);
18590
+ const groupDir = join5(root, group);
19375
18591
  let entries;
19376
18592
  try {
19377
18593
  entries = await readdir4(groupDir, { withFileTypes: true });
@@ -19380,7 +18596,7 @@ async function collectManifests(root) {
19380
18596
  }
19381
18597
  for (const entry of entries) {
19382
18598
  if (!entry.isDirectory()) continue;
19383
- const candidate = join6(groupDir, entry.name, "package.json");
18599
+ const candidate = join5(groupDir, entry.name, "package.json");
19384
18600
  try {
19385
18601
  await access4(candidate);
19386
18602
  paths.push(candidate);
@@ -19575,7 +18791,7 @@ var plugin50 = {
19575
18791
  };
19576
18792
  }
19577
18793
  const root = cwd ?? process.cwd();
19578
- const bumpScript = join6(root, "scripts", "bump-version.mjs");
18794
+ const bumpScript = join5(root, "scripts", "bump-version.mjs");
19579
18795
  const changed = await collectManifests(root);
19580
18796
  let hasBumpScript = true;
19581
18797
  try {
@@ -19591,7 +18807,7 @@ var plugin50 = {
19591
18807
  return { ok: false, error: `bump script failed: ${msg}` };
19592
18808
  }
19593
18809
  for (const rel of ["package.json", "package-lock.json", "src/lib/utils.ts", "index.html"]) {
19594
- const p = join6(root, "website", rel);
18810
+ const p = join5(root, "website", rel);
19595
18811
  try {
19596
18812
  await access4(p);
19597
18813
  changed.push(p);
@@ -20068,7 +19284,7 @@ var plugin51 = {
20068
19284
  state47.commitCount = 0;
20069
19285
  state47.startedAt = null;
20070
19286
  state47.lastActivityAt = null;
20071
- state47.stopHookUnregister = releaseHandle(state47.stopHookUnregister);
19287
+ state47.stopHookUnregister = (0, runtime_exports.releaseHandle)(state47.stopHookUnregister);
20072
19288
  for (const off of state47.eventUnsubscribers) {
20073
19289
  try {
20074
19290
  off();
@@ -20337,18 +19553,18 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
20337
19553
  var session_recap_default = plugin51;
20338
19554
 
20339
19555
  // src/shell-check/index.ts
20340
- import { execFile as execFile13 } from "node:child_process";
19556
+ import { execFile as execFile12 } from "node:child_process";
20341
19557
  import { readdir as readdir5 } from "node:fs/promises";
20342
- import { isAbsolute as isAbsolute24, join as join7, relative as relative24, resolve as resolve25 } from "node:path";
19558
+ import { isAbsolute as isAbsolute22, join as join6, relative as relative22, resolve as resolve23 } from "node:path";
20343
19559
  var API_VERSION34 = "^0.1.10";
20344
- function withinProject5(p) {
19560
+ function withinProject22(p) {
20345
19561
  if (p.startsWith("-")) return false;
20346
19562
  const root = process.cwd();
20347
- const resolved = isAbsolute24(p) ? resolve25(p) : resolve25(root, p);
20348
- const rel = relative24(root, resolved);
19563
+ const resolved = isAbsolute22(p) ? resolve23(p) : resolve23(root, p);
19564
+ const rel = relative22(root, resolved);
20349
19565
  if (rel === "" || rel === ".") return true;
20350
19566
  if (rel.startsWith("..")) return false;
20351
- if (isAbsolute24(rel)) return false;
19567
+ if (isAbsolute22(rel)) return false;
20352
19568
  return true;
20353
19569
  }
20354
19570
  var MAX_PATH_LEN = 4096;
@@ -20363,7 +19579,7 @@ var state48 = {
20363
19579
  async function runShellCheck(files, severity, cwd) {
20364
19580
  try {
20365
19581
  await new Promise((resolvePromise, rejectPromise) => {
20366
- execFile13(
19582
+ execFile12(
20367
19583
  "shellcheck",
20368
19584
  ["--version"],
20369
19585
  { encoding: "utf-8", windowsHide: true },
@@ -20389,7 +19605,7 @@ async function runShellCheck(files, severity, cwd) {
20389
19605
  let raw;
20390
19606
  try {
20391
19607
  raw = await new Promise((resolvePromise, rejectPromise) => {
20392
- execFile13(
19608
+ execFile12(
20393
19609
  "shellcheck",
20394
19610
  args,
20395
19611
  {
@@ -20441,7 +19657,7 @@ async function findShellFiles(dir, pattern) {
20441
19657
  return results;
20442
19658
  }
20443
19659
  for (const entry of entries) {
20444
- const full = join7(dir, entry.name);
19660
+ const full = join6(dir, entry.name);
20445
19661
  if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
20446
19662
  results.push(...await findShellFiles(full, pattern));
20447
19663
  } else if (entry.isFile() && (entry.name.endsWith(".sh") || entry.name === "Dockerfile")) {
@@ -20525,7 +19741,7 @@ var plugin52 = {
20525
19741
  const pattern = inp.pattern ?? "";
20526
19742
  const severity = inp.severity ?? "warning";
20527
19743
  state48.invocationCount += 1;
20528
- const pathIsSafe = (p) => typeof p === "string" && p.length > 0 && p.length <= MAX_PATH_LEN && withinProject5(p);
19744
+ const pathIsSafe = (p) => typeof p === "string" && p.length > 0 && p.length <= MAX_PATH_LEN && withinProject22(p);
20529
19745
  if (!pathIsSafe(directory)) {
20530
19746
  return {
20531
19747
  ok: false,
@@ -20640,8 +19856,8 @@ var plugin52 = {
20640
19856
  var shell_check_default = plugin52;
20641
19857
 
20642
19858
  // src/smart-rename/index.ts
20643
- import { readFileSync as readFileSync13, writeFileSync as writeFileSync2 } from "node:fs";
20644
- import { extname as extname6, isAbsolute as isAbsolute25, relative as relative25, resolve as resolve26 } from "node:path";
19859
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync2 } from "node:fs";
19860
+ import { extname as extname4, isAbsolute as isAbsolute23, relative as relative23, resolve as resolve24 } from "node:path";
20645
19861
  var API_VERSION35 = "^0.1.10";
20646
19862
  var state49 = {
20647
19863
  renameCount: 0,
@@ -20660,21 +19876,21 @@ function readConfig47(raw) {
20660
19876
  extensions: Array.isArray(r["extensions"]) ? r["extensions"].filter((x) => typeof x === "string") : DEFAULTS44.extensions
20661
19877
  };
20662
19878
  }
20663
- function withinProject6(p) {
19879
+ function withinProject23(p) {
20664
19880
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
20665
19881
  const root = process.cwd();
20666
- const resolved = isAbsolute25(p) ? resolve26(p) : resolve26(root, p);
20667
- const rel = relative25(root, resolved);
19882
+ const resolved = isAbsolute23(p) ? resolve24(p) : resolve24(root, p);
19883
+ const rel = relative23(root, resolved);
20668
19884
  if (rel === "" || rel === ".") return true;
20669
19885
  if (rel.startsWith("..")) return false;
20670
- if (isAbsolute25(rel)) return false;
19886
+ if (isAbsolute23(rel)) return false;
20671
19887
  return true;
20672
19888
  }
20673
19889
  function toPosix7(p) {
20674
19890
  return p.replace(/\\/g, "/");
20675
19891
  }
20676
19892
  function relativePath7(p) {
20677
- return toPosix7(relative25(process.cwd(), p));
19893
+ return toPosix7(relative23(process.cwd(), p));
20678
19894
  }
20679
19895
  function escapeRegex2(s) {
20680
19896
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -20759,17 +19975,17 @@ var plugin53 = {
20759
19975
  if (!isIdentifier(newName)) {
20760
19976
  return { ok: false, error: `newName "${newName}" is not a valid identifier` };
20761
19977
  }
20762
- if (!withinProject6(rawPath)) {
19978
+ if (!withinProject23(rawPath)) {
20763
19979
  return { ok: false, error: "path is outside the project root" };
20764
19980
  }
20765
- const ext = extname6(rawPath).toLowerCase();
19981
+ const ext = extname4(rawPath).toLowerCase();
20766
19982
  if (!cfg.extensions.includes(ext)) {
20767
19983
  return { ok: false, error: `extension ${ext} is not allowed for rename` };
20768
19984
  }
20769
- const resolved = resolve26(process.cwd(), rawPath);
19985
+ const resolved = resolve24(process.cwd(), rawPath);
20770
19986
  let content;
20771
19987
  try {
20772
- content = readFileSync13(resolved, "utf-8");
19988
+ content = readFileSync12(resolved, "utf-8");
20773
19989
  } catch (err) {
20774
19990
  state49.errorCount += 1;
20775
19991
  return { ok: false, error: String(err) };
@@ -21157,8 +20373,8 @@ var plugin54 = {
21157
20373
  state50.skippedNonMd = 0;
21158
20374
  state50.readErrorCount = 0;
21159
20375
  state50.autoFixApplied = 0;
21160
- state50.postHookUnregister = releaseHandle(state50.postHookUnregister);
21161
- state50.preHookUnregister = releaseHandle(state50.preHookUnregister);
20376
+ state50.postHookUnregister = (0, runtime_exports.releaseHandle)(state50.postHookUnregister);
20377
+ state50.preHookUnregister = (0, runtime_exports.releaseHandle)(state50.preHookUnregister);
21162
20378
  const cfg = readConfig48(api.config.extensions?.["spec-linker"]);
21163
20379
  const postHook = async (input) => {
21164
20380
  if (!cfg.enabled) return;
@@ -21312,7 +20528,7 @@ var spec_linker_default = plugin54;
21312
20528
 
21313
20529
  // src/template-engine/index.ts
21314
20530
  import { readFile as readFile17, writeFile as writeFile6 } from "node:fs/promises";
21315
- import { isAbsolute as isAbsolute26 } from "node:path";
20531
+ import { isAbsolute as isAbsolute24 } from "node:path";
21316
20532
  var API_VERSION36 = "^0.1.10";
21317
20533
  var templates = /* @__PURE__ */ new Map();
21318
20534
  var MAX_TEMPLATES = 256;
@@ -21368,10 +20584,10 @@ function renderTemplateRaw(template, variables) {
21368
20584
  return result;
21369
20585
  }
21370
20586
  function validateRelativeTemplatePath(field, value) {
21371
- if (isAbsolute26(value) || value.split(/[\\/]+/).includes("..")) {
20587
+ if (isAbsolute24(value) || value.split(/[\\/]+/).includes("..")) {
21372
20588
  return `${field} must be a relative path without ".." components`;
21373
20589
  }
21374
- if (!withinProject(value)) {
20590
+ if (!(0, runtime_exports.withinProject)(value)) {
21375
20591
  return `${field} must resolve inside the project directory`;
21376
20592
  }
21377
20593
  return null;
@@ -21674,7 +20890,7 @@ var plugin55 = {
21674
20890
  };
21675
20891
  }
21676
20892
  });
21677
- contributorUnregister = releaseHandle(contributorUnregister);
20893
+ contributorUnregister = (0, runtime_exports.releaseHandle)(contributorUnregister);
21678
20894
  contributorUnregister = api.registerSystemPromptContributor(async () => [
21679
20895
  {
21680
20896
  type: "text",
@@ -21690,7 +20906,7 @@ var plugin55 = {
21690
20906
  teardown(api) {
21691
20907
  const count = templates.size;
21692
20908
  templates.clear();
21693
- contributorUnregister = releaseHandle(contributorUnregister);
20909
+ contributorUnregister = (0, runtime_exports.releaseHandle)(contributorUnregister);
21694
20910
  api.log.info("template-engine: teardown complete", { cleared: count });
21695
20911
  },
21696
20912
  async health() {
@@ -21709,7 +20925,7 @@ var plugin55 = {
21709
20925
  var template_engine_default = plugin55;
21710
20926
 
21711
20927
  // src/test-coverage-gate/index.ts
21712
- import { readFileSync as readFileSync14 } from "node:fs";
20928
+ import { readFileSync as readFileSync13 } from "node:fs";
21713
20929
  var API_VERSION37 = "^0.1.10";
21714
20930
  var state51 = {
21715
20931
  invocationCount: 0,
@@ -21750,7 +20966,7 @@ function readConfig49(raw) {
21750
20966
  }
21751
20967
  function readCoverageSummary(coveragePath) {
21752
20968
  try {
21753
- const raw = readFileSync14(coveragePath, "utf-8");
20969
+ const raw = readFileSync13(coveragePath, "utf-8");
21754
20970
  return JSON.parse(raw);
21755
20971
  } catch {
21756
20972
  return null;
@@ -21820,7 +21036,7 @@ var plugin56 = {
21820
21036
  state51.skippedCount = 0;
21821
21037
  state51.lastOverallPct = null;
21822
21038
  state51.lastResult = null;
21823
- state51.hookUnregister = releaseHandle(state51.hookUnregister);
21039
+ state51.hookUnregister = (0, runtime_exports.releaseHandle)(state51.hookUnregister);
21824
21040
  const cfg = readConfig49(api.config.extensions?.["test-coverage-gate"]);
21825
21041
  const hook = (input) => {
21826
21042
  if (!cfg.enabled) return;
@@ -21828,7 +21044,7 @@ var plugin56 = {
21828
21044
  const inp = input.toolInput ?? {};
21829
21045
  const sourcePath = inp["path"];
21830
21046
  if (!sourcePath || typeof sourcePath !== "string") return;
21831
- if (!withinProject(sourcePath)) return;
21047
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
21832
21048
  const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
21833
21049
  if (!runOnChangeSet.has(ext)) {
21834
21050
  state51.skippedCount += 1;
@@ -21965,10 +21181,10 @@ var plugin56 = {
21965
21181
  var test_coverage_gate_default = plugin56;
21966
21182
 
21967
21183
  // src/test-flake-detector/index.ts
21968
- import { execFile as execFile14 } from "node:child_process";
21969
- import { readFileSync as readFileSync15 } from "node:fs";
21970
- import { createRequire as createRequire3 } from "node:module";
21971
- import { dirname as dirname8, isAbsolute as isAbsolute27, relative as relative26, resolve as resolve27 } from "node:path";
21184
+ import { execFile as execFile13 } from "node:child_process";
21185
+ import { readFileSync as readFileSync14 } from "node:fs";
21186
+ import { createRequire as createRequire2 } from "node:module";
21187
+ import { dirname as dirname7, isAbsolute as isAbsolute25, relative as relative24, resolve as resolve25 } from "node:path";
21972
21188
  var API_VERSION38 = "^0.1.10";
21973
21189
  var state52 = {
21974
21190
  invocationCount: 0,
@@ -22037,17 +21253,17 @@ var ALLOWED_RUNNER_FLAGS = /* @__PURE__ */ new Set([
22037
21253
  "--reporter=verbose",
22038
21254
  "--reporter=default"
22039
21255
  ]);
22040
- function withinProject7(p) {
21256
+ function withinProject26(p) {
22041
21257
  if (p.length === 0 || p.length > 4096 || p.startsWith("-")) return false;
22042
- const root = resolve27(process.cwd());
22043
- const resolved = isAbsolute27(p) ? resolve27(p) : resolve27(root, p);
22044
- const rel = relative26(root, resolved);
22045
- return rel === "" || !rel.startsWith("..") && !isAbsolute27(rel);
21258
+ const root = resolve25(process.cwd());
21259
+ const resolved = isAbsolute25(p) ? resolve25(p) : resolve25(root, p);
21260
+ const rel = relative24(root, resolved);
21261
+ return rel === "" || !rel.startsWith("..") && !isAbsolute25(rel);
22046
21262
  }
22047
- function isInside3(parent, child) {
21263
+ function isInside2(parent, child) {
22048
21264
  if (parent === child) return true;
22049
- const rel = relative26(parent, child);
22050
- return rel !== "" && !rel.startsWith("..") && !isAbsolute27(rel);
21265
+ const rel = relative24(parent, child);
21266
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute25(rel);
22051
21267
  }
22052
21268
  function tokenizeCommand(command) {
22053
21269
  const trimmed = command.trim();
@@ -22084,14 +21300,14 @@ function resolveTestCommand(baseCommand, testPattern) {
22084
21300
  if (runnerArgs.some((arg) => !ALLOWED_RUNNER_FLAGS.has(arg))) return null;
22085
21301
  let resolvedEntry;
22086
21302
  try {
22087
- const requireFromProject = createRequire3(resolve27(process.cwd(), "package.json"));
21303
+ const requireFromProject = createRequire2(resolve25(process.cwd(), "package.json"));
22088
21304
  const packagePath = requireFromProject.resolve(`${runner}/package.json`);
22089
- const packageJson = JSON.parse(readFileSync15(packagePath, "utf8"));
21305
+ const packageJson = JSON.parse(readFileSync14(packagePath, "utf8"));
22090
21306
  const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[runner] ?? Object.values(packageJson.bin ?? {})[0];
22091
21307
  if (!relativeBin) return null;
22092
- const packageDir = dirname8(packagePath);
22093
- const candidate = resolve27(packageDir, relativeBin);
22094
- if (isAbsolute27(relativeBin) || !isInside3(packageDir, candidate)) {
21308
+ const packageDir = dirname7(packagePath);
21309
+ const candidate = resolve25(packageDir, relativeBin);
21310
+ if (isAbsolute25(relativeBin) || !isInside2(packageDir, candidate)) {
22095
21311
  return null;
22096
21312
  }
22097
21313
  resolvedEntry = candidate;
@@ -22100,7 +21316,7 @@ function resolveTestCommand(baseCommand, testPattern) {
22100
21316
  }
22101
21317
  const args = [resolvedEntry, ...runnerArgs];
22102
21318
  if (testPattern) {
22103
- if (!withinProject7(testPattern)) return null;
21319
+ if (!withinProject26(testPattern)) return null;
22104
21320
  args.push(testPattern);
22105
21321
  }
22106
21322
  return {
@@ -22111,7 +21327,7 @@ function resolveTestCommand(baseCommand, testPattern) {
22111
21327
  }
22112
21328
  function runOnce(command, timeoutMs) {
22113
21329
  return new Promise((resolveRun) => {
22114
- execFile14(
21330
+ execFile13(
22115
21331
  command.cmd,
22116
21332
  command.args,
22117
21333
  {
@@ -22333,8 +21549,8 @@ var plugin57 = {
22333
21549
  var test_flake_detector_default = plugin57;
22334
21550
 
22335
21551
  // src/test-generator/index.ts
22336
- import { readFileSync as readFileSync16 } from "node:fs";
22337
- import { isAbsolute as isAbsolute28, relative as relative27, resolve as resolve28 } from "node:path";
21552
+ import { readFileSync as readFileSync15 } from "node:fs";
21553
+ import { isAbsolute as isAbsolute26, relative as relative25, resolve as resolve26 } from "node:path";
22338
21554
  var API_VERSION39 = "^0.1.10";
22339
21555
  var state53 = {
22340
21556
  generateCount: 0,
@@ -22390,21 +21606,21 @@ var SOURCE_EXTENSIONS = [
22390
21606
  ".cpp",
22391
21607
  ".hpp"
22392
21608
  ];
22393
- function withinProject8(p) {
21609
+ function withinProject27(p) {
22394
21610
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
22395
21611
  const root = process.cwd();
22396
- const resolved = isAbsolute28(p) ? resolve28(p) : resolve28(root, p);
22397
- const rel = relative27(root, resolved);
21612
+ const resolved = isAbsolute26(p) ? resolve26(p) : resolve26(root, p);
21613
+ const rel = relative25(root, resolved);
22398
21614
  if (rel === "" || rel === ".") return true;
22399
21615
  if (rel.startsWith("..")) return false;
22400
- if (isAbsolute28(rel)) return false;
21616
+ if (isAbsolute26(rel)) return false;
22401
21617
  return true;
22402
21618
  }
22403
21619
  function toPosix8(p) {
22404
21620
  return p.replace(/\\/g, "/");
22405
21621
  }
22406
21622
  function relativePath8(p) {
22407
- return toPosix8(relative27(process.cwd(), p));
21623
+ return toPosix8(relative25(process.cwd(), p));
22408
21624
  }
22409
21625
  function detectExports(content) {
22410
21626
  const exports = [];
@@ -22498,7 +21714,7 @@ function generateTestContent(sourcePath, sourceModule, detected, cfg) {
22498
21714
  return lines.join("\n");
22499
21715
  }
22500
21716
  function generateForFile(filePath, cfg) {
22501
- const sourceContent = readFileSync16(filePath, "utf-8");
21717
+ const sourceContent = readFileSync15(filePath, "utf-8");
22502
21718
  const detected = detectExports(sourceContent);
22503
21719
  const sourceFile = relativePath8(filePath);
22504
21720
  const sourceParts = sourceFile.split("/");
@@ -22614,7 +21830,7 @@ var plugin58 = {
22614
21830
  if (!rawPath || typeof rawPath !== "string") {
22615
21831
  return { ok: false, error: "path is required" };
22616
21832
  }
22617
- if (!withinProject8(rawPath)) {
21833
+ if (!withinProject27(rawPath)) {
22618
21834
  return { ok: false, error: "path is outside the project root" };
22619
21835
  }
22620
21836
  if (!SOURCE_EXTENSIONS.some((ext) => rawPath.toLowerCase().endsWith(ext))) {
@@ -22623,7 +21839,7 @@ var plugin58 = {
22623
21839
  error: `test generation only reads source files (${SOURCE_EXTENSIONS.join(", ")}); refusing "${rawPath}"`
22624
21840
  };
22625
21841
  }
22626
- const resolved = resolve28(process.cwd(), rawPath);
21842
+ const resolved = resolve26(process.cwd(), rawPath);
22627
21843
  state53.generateCount += 1;
22628
21844
  let result;
22629
21845
  try {
@@ -22708,15 +21924,15 @@ var plugin58 = {
22708
21924
  var test_generator_default = plugin58;
22709
21925
 
22710
21926
  // src/test-runner-gate/index.ts
22711
- import { execFile as execFile15 } from "node:child_process";
21927
+ import { execFile as execFile14 } from "node:child_process";
22712
21928
  import { access as access5 } from "node:fs/promises";
22713
- import { basename as basename7, dirname as dirname9, isAbsolute as isAbsolute29, join as join8 } from "node:path";
22714
- import { buildWin32CmdShimInvocation as buildWin32CmdShimInvocation2, resolveWin32Command as resolveWin32Command2 } from "@wrongstack/tools/win32";
21929
+ import { basename as basename6, dirname as dirname8, isAbsolute as isAbsolute27, join as join7 } from "node:path";
21930
+ import { buildWin32CmdShimInvocation, resolveWin32Command } from "@wrongstack/tools/win32";
22715
21931
  function resolveExec(command, args) {
22716
- const resolved = resolveWin32Command2(command);
21932
+ const resolved = resolveWin32Command(command);
22717
21933
  const needsShell = process.platform === "win32" && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
22718
21934
  if (needsShell) {
22719
- const shim = buildWin32CmdShimInvocation2(resolved, args);
21935
+ const shim = buildWin32CmdShimInvocation(resolved, args);
22720
21936
  return { cmd: shim.command, args: shim.args, windowsVerbatimArguments: true };
22721
21937
  }
22722
21938
  return { cmd: resolved, args: [...args], windowsVerbatimArguments: false };
@@ -22785,7 +22001,7 @@ function pathContentHash(content) {
22785
22001
  }
22786
22002
  return h >>> 0;
22787
22003
  }
22788
- var lastPassedHash = new BoundedMap({ max: 1024 });
22004
+ var lastPassedHash = new runtime_exports.BoundedMap({ max: 1024 });
22789
22005
  var ALLOWED_COMMAND_TOKENS = /* @__PURE__ */ new Set([
22790
22006
  "npx",
22791
22007
  "pnpm",
@@ -22801,9 +22017,9 @@ var ALLOWED_COMMAND_TOKENS = /* @__PURE__ */ new Set([
22801
22017
  // by basename in resolveAllowedCommand().
22802
22018
  ]);
22803
22019
  function resolveTestFiles(sourcePath, patterns) {
22804
- const name = basename7(sourcePath).replace(/\.[^.]+$/, "");
22020
+ const name = basename6(sourcePath).replace(/\.[^.]+$/, "");
22805
22021
  const pathNoExt = sourcePath.replace(/\.[^.]+$/, "");
22806
- const dir = dirname9(sourcePath);
22022
+ const dir = dirname8(sourcePath);
22807
22023
  const candidates = [];
22808
22024
  for (const pattern of patterns) {
22809
22025
  const candidate = pattern.replace(/\{name\}/g, name).replace(/\{path\}/g, pathNoExt).replace(/\{dir\}/g, dir);
@@ -22812,7 +22028,7 @@ function resolveTestFiles(sourcePath, patterns) {
22812
22028
  candidates.push(candidate);
22813
22029
  } else {
22814
22030
  candidates.push(candidate);
22815
- candidates.push(join8(dir, candidate));
22031
+ candidates.push(join7(dir, candidate));
22816
22032
  }
22817
22033
  }
22818
22034
  }
@@ -22839,15 +22055,15 @@ async function detectRunner(requested) {
22839
22055
  const match = candidates.find((c) => c.name === requested);
22840
22056
  if (!match) return null;
22841
22057
  try {
22842
- await new Promise((resolve29, reject) => {
22058
+ await new Promise((resolve27, reject) => {
22843
22059
  const ex = resolveExec("npx", [`${match.name}`, "--version"]);
22844
- execFile15(ex.cmd, ex.args, {
22060
+ execFile14(ex.cmd, ex.args, {
22845
22061
  encoding: "utf-8",
22846
22062
  timeout: 5e3,
22847
22063
  cwd: process.cwd(),
22848
22064
  windowsHide: true,
22849
22065
  ...ex.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
22850
- }, (err) => err ? reject(err) : resolve29());
22066
+ }, (err) => err ? reject(err) : resolve27());
22851
22067
  });
22852
22068
  return match;
22853
22069
  } catch {
@@ -22856,15 +22072,15 @@ async function detectRunner(requested) {
22856
22072
  }
22857
22073
  for (const candidate of candidates) {
22858
22074
  try {
22859
- await new Promise((resolve29, reject) => {
22075
+ await new Promise((resolve27, reject) => {
22860
22076
  const ex = resolveExec("npx", [`${candidate.name}`, "--version"]);
22861
- execFile15(ex.cmd, ex.args, {
22077
+ execFile14(ex.cmd, ex.args, {
22862
22078
  encoding: "utf-8",
22863
22079
  timeout: 5e3,
22864
22080
  cwd: process.cwd(),
22865
22081
  windowsHide: true,
22866
22082
  ...ex.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
22867
- }, (err) => err ? reject(err) : resolve29());
22083
+ }, (err) => err ? reject(err) : resolve27());
22868
22084
  });
22869
22085
  return candidate;
22870
22086
  } catch {
@@ -22879,9 +22095,9 @@ function resolveAllowedCommand2(customCommand) {
22879
22095
  if (ALLOWED_COMMAND_TOKENS.has(head)) {
22880
22096
  return { cmd: head, args: tokens.slice(1) };
22881
22097
  }
22882
- if (isAbsolute29(head)) {
22883
- if (!withinProject(head)) return null;
22884
- const base = basename7(head);
22098
+ if (isAbsolute27(head)) {
22099
+ if (!(0, runtime_exports.withinProject)(head)) return null;
22100
+ const base = basename6(head);
22885
22101
  if (ALLOWED_COMMAND_TOKENS.has(base)) {
22886
22102
  return { cmd: head, args: tokens.slice(1) };
22887
22103
  }
@@ -22889,7 +22105,7 @@ function resolveAllowedCommand2(customCommand) {
22889
22105
  return null;
22890
22106
  }
22891
22107
  async function runTests(testFile, runner, customCommand, timeoutMs) {
22892
- if (!withinProject(testFile)) return null;
22108
+ if (!(0, runtime_exports.withinProject)(testFile)) return null;
22893
22109
  let cmd;
22894
22110
  let cmdArgs;
22895
22111
  let trailingFlag;
@@ -22910,9 +22126,9 @@ async function runTests(testFile, runner, customCommand, timeoutMs) {
22910
22126
  let stdout = "";
22911
22127
  try {
22912
22128
  const { stdout: out } = await new Promise(
22913
- (resolve29, reject) => {
22129
+ (resolve27, reject) => {
22914
22130
  const ex = resolveExec(cmd, fullArgs);
22915
- execFile15(
22131
+ execFile14(
22916
22132
  ex.cmd,
22917
22133
  ex.args,
22918
22134
  {
@@ -22924,7 +22140,7 @@ async function runTests(testFile, runner, customCommand, timeoutMs) {
22924
22140
  },
22925
22141
  (err, out2, stderr) => {
22926
22142
  if (err) reject(Object.assign(err, { stdout: out2, stderr }));
22927
- else resolve29({ stdout: out2, stderr });
22143
+ else resolve27({ stdout: out2, stderr });
22928
22144
  }
22929
22145
  );
22930
22146
  }
@@ -23041,7 +22257,7 @@ var plugin59 = {
23041
22257
  state54.errorCount = 0;
23042
22258
  state54.extensionSkippedCount = 0;
23043
22259
  state54.cachedSkipCount = 0;
23044
- state54.hookUnregister = releaseHandle(state54.hookUnregister);
22260
+ state54.hookUnregister = (0, runtime_exports.releaseHandle)(state54.hookUnregister);
23045
22261
  state54.lastResult = null;
23046
22262
  lastPassedHash.clear();
23047
22263
  const cfg = readConfig52(api.config.extensions?.["test-runner-gate"]);
@@ -23062,7 +22278,7 @@ var plugin59 = {
23062
22278
  const inp = input.toolInput ?? {};
23063
22279
  const sourcePath = inp["path"];
23064
22280
  if (!sourcePath || typeof sourcePath !== "string") return;
23065
- if (!withinProject(sourcePath)) return;
22281
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
23066
22282
  if (sourcePath.includes(".test.") || sourcePath.includes(".spec.")) return;
23067
22283
  if (cfg.enableExtensionFilter) {
23068
22284
  const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
@@ -23292,7 +22508,7 @@ var plugin60 = {
23292
22508
  state55.lastMessageId = null;
23293
22509
  state55.lastPayloadHash = "";
23294
22510
  state55.lastBroadcastAt = 0;
23295
- state55.hookUnregister = releaseHandle(state55.hookUnregister);
22511
+ state55.hookUnregister = (0, runtime_exports.releaseHandle)(state55.hookUnregister);
23296
22512
  const cfg = readConfig53(api.config.extensions?.["todo-listener"]);
23297
22513
  const mailbox = api.mailbox;
23298
22514
  const hook = async (input) => {
@@ -23333,7 +22549,7 @@ var plugin60 = {
23333
22549
  0,
23334
22550
  200
23335
22551
  );
23336
- const body = safeJsonStringify(payload, 2);
22552
+ const body = (0, runtime_exports.safeJsonStringify)(payload, 2);
23337
22553
  const sendInput = {
23338
22554
  from: `plugin:todo-listener`,
23339
22555
  to: "*",
@@ -24201,15 +23417,15 @@ function estimateRequestTokens(request, charsPerToken) {
24201
23417
  }
24202
23418
  function sleep(ms, signal) {
24203
23419
  if (signal?.aborted) return Promise.resolve();
24204
- return new Promise((resolve29) => {
23420
+ return new Promise((resolve27) => {
24205
23421
  const timer = setTimeout(() => {
24206
23422
  signal?.removeEventListener("abort", onAbort);
24207
- resolve29();
23423
+ resolve27();
24208
23424
  }, ms);
24209
23425
  timer.unref?.();
24210
23426
  function onAbort() {
24211
23427
  clearTimeout(timer);
24212
- resolve29();
23428
+ resolve27();
24213
23429
  }
24214
23430
  signal?.addEventListener("abort", onAbort, { once: true });
24215
23431
  });
@@ -24417,7 +23633,7 @@ var TSC_RUNTIME = {
24417
23633
  defaultCommand: "pnpm exec tsc --noEmit"
24418
23634
  };
24419
23635
  function validateTsConfigPath(p) {
24420
- const sanitized = sanitizeRunnerPath(p);
23636
+ const sanitized = (0, runtime_exports.sanitizeRunnerPath)(p);
24421
23637
  return sanitized;
24422
23638
  }
24423
23639
  async function runTypeCheck(cfg) {
@@ -24430,12 +23646,12 @@ async function runTypeCheck(cfg) {
24430
23646
  const tsConfig = validTsConfig ?? (rawTsConfig || "tsconfig.json");
24431
23647
  let argv;
24432
23648
  if (cfg.command) {
24433
- const resolved = resolveRunnerCommand(TSC_RUNTIME, cfg.command);
23649
+ const resolved = (0, runtime_exports.resolveRunnerCommand)(TSC_RUNTIME, cfg.command);
24434
23650
  if (!resolved) return null;
24435
23651
  argv = [resolved.cmd, ...resolved.args];
24436
23652
  } else {
24437
23653
  const tscFlags = ["--noEmit", "--incremental"];
24438
- const localTsc = resolveNodeBin("typescript", "tsc", process.cwd(), tscFlags);
23654
+ const localTsc = (0, runtime_exports.resolveNodeBin)("typescript", "tsc", process.cwd(), tscFlags);
24439
23655
  argv = localTsc ? [localTsc.cmd, ...localTsc.args] : ["npx", "tsc", ...tscFlags];
24440
23656
  if (tsConfig && tsConfig !== "tsconfig.json") {
24441
23657
  argv = [...argv, "-p", tsConfig];
@@ -24444,7 +23660,7 @@ async function runTypeCheck(cfg) {
24444
23660
  if (!cfg.command && tsConfig && !existsSync6(tsConfig)) {
24445
23661
  return null;
24446
23662
  }
24447
- const result = await runRunnerCommand([argv[0], ...argv.slice(1)], {
23663
+ const result = await (0, runtime_exports.runRunnerCommand)([argv[0], ...argv.slice(1)], {
24448
23664
  cwd: process.cwd(),
24449
23665
  timeoutMs: cfg.timeoutMs
24450
23666
  });
@@ -24532,7 +23748,7 @@ var plugin64 = {
24532
23748
  state59.errorCount = 0;
24533
23749
  state59.skippedCount = 0;
24534
23750
  state59.lastResult = null;
24535
- state59.hookUnregister = releaseHandle(state59.hookUnregister);
23751
+ state59.hookUnregister = (0, runtime_exports.releaseHandle)(state59.hookUnregister);
24536
23752
  const cfg = readConfig56(api.config.extensions?.["type-gate"]);
24537
23753
  const hook = async (input) => {
24538
23754
  if (!cfg.enabled) return;
@@ -24540,7 +23756,7 @@ var plugin64 = {
24540
23756
  const inp = input.toolInput ?? {};
24541
23757
  const sourcePath = inp["path"];
24542
23758
  if (!sourcePath || typeof sourcePath !== "string") return;
24543
- if (!withinProject(sourcePath)) return;
23759
+ if (!(0, runtime_exports.withinProject)(sourcePath)) return;
24544
23760
  const ext = sourcePath.includes(".") ? sourcePath.slice(sourcePath.lastIndexOf(".")).toLowerCase() : "";
24545
23761
  if (!runOnChangeSet2.has(ext)) {
24546
23762
  state59.skippedCount += 1;