@wrongstack/plugins 0.284.1 → 0.285.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 (263) hide show
  1. package/README.md +18 -14
  2. package/dist/accessibility-auditor/index.d.ts +38 -0
  3. package/dist/accessibility-auditor/index.d.ts.map +1 -0
  4. package/dist/accessibility-auditor.d.ts +2 -40
  5. package/dist/accessibility-auditor.js +5 -5
  6. package/dist/agent-handoff/index.d.ts +35 -0
  7. package/dist/agent-handoff/index.d.ts.map +1 -0
  8. package/dist/agent-handoff.d.ts +2 -37
  9. package/dist/agent-handoff.js +3 -2
  10. package/dist/api-compatibility-gate/index.d.ts +36 -0
  11. package/dist/api-compatibility-gate/index.d.ts.map +1 -0
  12. package/dist/api-compatibility-gate.d.ts +2 -38
  13. package/dist/api-compatibility-gate.js +6 -6
  14. package/dist/auto-doc/index.d.ts +20 -0
  15. package/dist/auto-doc/index.d.ts.map +1 -0
  16. package/dist/auto-doc.d.ts +2 -22
  17. package/dist/auto-doc.js +5 -5
  18. package/dist/auto-escalate/index.d.ts +43 -0
  19. package/dist/auto-escalate/index.d.ts.map +1 -0
  20. package/dist/auto-escalate.d.ts +2 -45
  21. package/dist/auto-escalate.js +5 -2
  22. package/dist/auto-i18n-extractor/index.d.ts +34 -0
  23. package/dist/auto-i18n-extractor/index.d.ts.map +1 -0
  24. package/dist/auto-i18n-extractor.d.ts +2 -36
  25. package/dist/auto-i18n-extractor.js +5 -5
  26. package/dist/branch-guard/index.d.ts +32 -0
  27. package/dist/branch-guard/index.d.ts.map +1 -0
  28. package/dist/branch-guard.d.ts +2 -34
  29. package/dist/branch-guard.js +4 -4
  30. package/dist/catalog.d.ts +39 -0
  31. package/dist/catalog.d.ts.map +1 -0
  32. package/dist/changelog-writer/index.d.ts +71 -0
  33. package/dist/changelog-writer/index.d.ts.map +1 -0
  34. package/dist/changelog-writer.d.ts +2 -73
  35. package/dist/changelog-writer.js +9 -5
  36. package/dist/checkpoint/index.d.ts +53 -0
  37. package/dist/checkpoint/index.d.ts.map +1 -0
  38. package/dist/checkpoint.d.ts +2 -55
  39. package/dist/checkpoint.js +6 -6
  40. package/dist/code-metrics/index.d.ts +29 -0
  41. package/dist/code-metrics/index.d.ts.map +1 -0
  42. package/dist/code-metrics.d.ts +2 -31
  43. package/dist/code-metrics.js +5 -5
  44. package/dist/commit-validator/index.d.ts +31 -0
  45. package/dist/commit-validator/index.d.ts.map +1 -0
  46. package/dist/commit-validator.d.ts +2 -33
  47. package/dist/commit-validator.js +5 -3
  48. package/dist/config-validator/index.d.ts +46 -0
  49. package/dist/config-validator/index.d.ts.map +1 -0
  50. package/dist/config-validator.d.ts +2 -48
  51. package/dist/config-validator.js +8 -4
  52. package/dist/context-pins/index.d.ts +43 -0
  53. package/dist/context-pins/index.d.ts.map +1 -0
  54. package/dist/context-pins.d.ts +2 -45
  55. package/dist/context-pins.js +5 -5
  56. package/dist/cost-tracker/index.d.ts +51 -0
  57. package/dist/cost-tracker/index.d.ts.map +1 -0
  58. package/dist/cost-tracker.d.ts +2 -53
  59. package/dist/cost-tracker.js +4 -4
  60. package/dist/cron/index.d.ts +12 -0
  61. package/dist/cron/index.d.ts.map +1 -0
  62. package/dist/cron.d.ts +2 -14
  63. package/dist/cron.js +3 -2
  64. package/dist/dead-code-detector/index.d.ts +32 -0
  65. package/dist/dead-code-detector/index.d.ts.map +1 -0
  66. package/dist/dead-code-detector.d.ts +2 -34
  67. package/dist/dead-code-detector.js +5 -5
  68. package/dist/dep-guard/index.d.ts +63 -0
  69. package/dist/dep-guard/index.d.ts.map +1 -0
  70. package/dist/dep-guard.d.ts +2 -65
  71. package/dist/dep-guard.js +6 -2
  72. package/dist/dependency-vulnerability-gate/index.d.ts +33 -0
  73. package/dist/dependency-vulnerability-gate/index.d.ts.map +1 -0
  74. package/dist/dependency-vulnerability-gate.d.ts +2 -35
  75. package/dist/dependency-vulnerability-gate.js +5 -5
  76. package/dist/diff-summary/index.d.ts +34 -0
  77. package/dist/diff-summary/index.d.ts.map +1 -0
  78. package/dist/diff-summary.d.ts +2 -36
  79. package/dist/diff-summary.js +5 -5
  80. package/dist/doc-sync-guard/index.d.ts +31 -0
  81. package/dist/doc-sync-guard/index.d.ts.map +1 -0
  82. package/dist/doc-sync-guard.d.ts +2 -33
  83. package/dist/doc-sync-guard.js +4 -4
  84. package/dist/duplicate-code-detector/index.d.ts +31 -0
  85. package/dist/duplicate-code-detector/index.d.ts.map +1 -0
  86. package/dist/duplicate-code-detector.d.ts +2 -33
  87. package/dist/duplicate-code-detector.js +5 -5
  88. package/dist/error-lens/index.d.ts +65 -0
  89. package/dist/error-lens/index.d.ts.map +1 -0
  90. package/dist/error-lens.d.ts +2 -67
  91. package/dist/error-lens.js +5 -2
  92. package/dist/feature-flag-tracker/index.d.ts +36 -0
  93. package/dist/feature-flag-tracker/index.d.ts.map +1 -0
  94. package/dist/feature-flag-tracker.d.ts +2 -38
  95. package/dist/feature-flag-tracker.js +5 -5
  96. package/dist/file-watcher/index.d.ts +12 -0
  97. package/dist/file-watcher/index.d.ts.map +1 -0
  98. package/dist/file-watcher.d.ts +2 -14
  99. package/dist/file-watcher.js +7 -7
  100. package/dist/format-on-save/index.d.ts +33 -0
  101. package/dist/format-on-save/index.d.ts.map +1 -0
  102. package/dist/format-on-save.d.ts +2 -35
  103. package/dist/format-on-save.js +6 -6
  104. package/dist/git-autocommit/index.d.ts +15 -0
  105. package/dist/git-autocommit/index.d.ts.map +1 -0
  106. package/dist/git-autocommit.d.ts +2 -17
  107. package/dist/git-autocommit.js +5 -5
  108. package/dist/import-organizer/index.d.ts +50 -0
  109. package/dist/import-organizer/index.d.ts.map +1 -0
  110. package/dist/import-organizer.d.ts +2 -52
  111. package/dist/import-organizer.js +6 -6
  112. package/dist/index.d.ts +186 -64
  113. package/dist/index.d.ts.map +1 -0
  114. package/dist/index.js +946 -394
  115. package/dist/injection-shield/index.d.ts +47 -0
  116. package/dist/injection-shield/index.d.ts.map +1 -0
  117. package/dist/injection-shield.d.ts +2 -49
  118. package/dist/injection-shield.js +4 -2
  119. package/dist/interface-contract-guard/index.d.ts +35 -0
  120. package/dist/interface-contract-guard/index.d.ts.map +1 -0
  121. package/dist/interface-contract-guard.d.ts +2 -37
  122. package/dist/interface-contract-guard.js +5 -5
  123. package/dist/knowledge-graph/index.d.ts +43 -0
  124. package/dist/knowledge-graph/index.d.ts.map +1 -0
  125. package/dist/knowledge-graph.d.ts +2 -45
  126. package/dist/knowledge-graph.js +5 -5
  127. package/dist/license-audit-gate/index.d.ts +32 -0
  128. package/dist/license-audit-gate/index.d.ts.map +1 -0
  129. package/dist/license-audit-gate.d.ts +2 -34
  130. package/dist/license-audit-gate.js +5 -5
  131. package/dist/lint-gate/index.d.ts +31 -0
  132. package/dist/lint-gate/index.d.ts.map +1 -0
  133. package/dist/lint-gate.d.ts +2 -33
  134. package/dist/lint-gate.js +7 -7
  135. package/dist/llm-cache/index.d.ts +54 -0
  136. package/dist/llm-cache/index.d.ts.map +1 -0
  137. package/dist/llm-cache.d.ts +2 -56
  138. package/dist/llm-cache.js +6 -4
  139. package/dist/loop-breaker/index.d.ts +4 -0
  140. package/dist/loop-breaker/index.d.ts.map +1 -0
  141. package/dist/loop-breaker.d.ts +2 -5
  142. package/dist/loop-breaker.js +4 -4
  143. package/dist/migration-planner/index.d.ts +28 -0
  144. package/dist/migration-planner/index.d.ts.map +1 -0
  145. package/dist/migration-planner.d.ts +2 -30
  146. package/dist/migration-planner.js +5 -5
  147. package/dist/model-router/index.d.ts +67 -0
  148. package/dist/model-router/index.d.ts.map +1 -0
  149. package/dist/model-router.d.ts +2 -69
  150. package/dist/model-router.js +5 -2
  151. package/dist/notify-hub/index.d.ts +43 -0
  152. package/dist/notify-hub/index.d.ts.map +1 -0
  153. package/dist/notify-hub.d.ts +2 -45
  154. package/dist/notify-hub.js +3 -2
  155. package/dist/path-guard/index.d.ts +52 -0
  156. package/dist/path-guard/index.d.ts.map +1 -0
  157. package/dist/path-guard.d.ts +2 -54
  158. package/dist/path-guard.js +5 -2
  159. package/dist/performance-regression-gate/index.d.ts +31 -0
  160. package/dist/performance-regression-gate/index.d.ts.map +1 -0
  161. package/dist/performance-regression-gate.d.ts +2 -33
  162. package/dist/performance-regression-gate.js +5 -5
  163. package/dist/plugin-stack-observer/index.d.ts +33 -0
  164. package/dist/plugin-stack-observer/index.d.ts.map +1 -0
  165. package/dist/plugin-stack-observer.d.ts +2 -35
  166. package/dist/plugin-stack-observer.js +3 -2
  167. package/dist/pr-drafter/index.d.ts +33 -0
  168. package/dist/pr-drafter/index.d.ts.map +1 -0
  169. package/dist/pr-drafter.d.ts +2 -35
  170. package/dist/pr-drafter.js +6 -6
  171. package/dist/prompt-firewall/index.d.ts +55 -0
  172. package/dist/prompt-firewall/index.d.ts.map +1 -0
  173. package/dist/prompt-firewall.d.ts +2 -57
  174. package/dist/prompt-firewall.js +5 -2
  175. package/dist/refactor-suggester/index.d.ts +36 -0
  176. package/dist/refactor-suggester/index.d.ts.map +1 -0
  177. package/dist/refactor-suggester.d.ts +2 -38
  178. package/dist/refactor-suggester.js +5 -5
  179. package/dist/release-notes-generator/index.d.ts +25 -0
  180. package/dist/release-notes-generator/index.d.ts.map +1 -0
  181. package/dist/release-notes-generator.d.ts +2 -27
  182. package/dist/release-notes-generator.js +28 -10
  183. package/dist/runtime/index.d.ts +124 -0
  184. package/dist/runtime/index.d.ts.map +1 -0
  185. package/dist/runtime.d.ts +1 -0
  186. package/dist/runtime.js +216 -0
  187. package/dist/schema-evolution-guard/index.d.ts +40 -0
  188. package/dist/schema-evolution-guard/index.d.ts.map +1 -0
  189. package/dist/schema-evolution-guard.d.ts +2 -42
  190. package/dist/schema-evolution-guard.js +5 -5
  191. package/dist/secret-scanner/index.d.ts +32 -0
  192. package/dist/secret-scanner/index.d.ts.map +1 -0
  193. package/dist/secret-scanner.d.ts +2 -34
  194. package/dist/secret-scanner.js +3 -2
  195. package/dist/security-hotspot-scanner/index.d.ts +28 -0
  196. package/dist/security-hotspot-scanner/index.d.ts.map +1 -0
  197. package/dist/security-hotspot-scanner.d.ts +2 -30
  198. package/dist/security-hotspot-scanner.js +5 -5
  199. package/dist/semantic-search-indexer/index.d.ts +36 -0
  200. package/dist/semantic-search-indexer/index.d.ts.map +1 -0
  201. package/dist/semantic-search-indexer.d.ts +2 -38
  202. package/dist/semantic-search-indexer.js +22 -6
  203. package/dist/semver-bump/index.d.ts +24 -0
  204. package/dist/semver-bump/index.d.ts.map +1 -0
  205. package/dist/semver-bump.d.ts +2 -26
  206. package/dist/semver-bump.js +10 -8
  207. package/dist/session-recap/index.d.ts +48 -0
  208. package/dist/session-recap/index.d.ts.map +1 -0
  209. package/dist/session-recap.d.ts +2 -50
  210. package/dist/session-recap.js +6 -4
  211. package/dist/shell-check/index.d.ts +14 -0
  212. package/dist/shell-check/index.d.ts.map +1 -0
  213. package/dist/shell-check.d.ts +2 -16
  214. package/dist/shell-check.js +6 -6
  215. package/dist/smart-rename/index.d.ts +24 -0
  216. package/dist/smart-rename/index.d.ts.map +1 -0
  217. package/dist/smart-rename.d.ts +2 -26
  218. package/dist/smart-rename.js +5 -5
  219. package/dist/spec-linker/index.d.ts +49 -0
  220. package/dist/spec-linker/index.d.ts.map +1 -0
  221. package/dist/spec-linker.d.ts +2 -51
  222. package/dist/spec-linker.js +20100 -244
  223. package/dist/template-engine/index.d.ts +13 -0
  224. package/dist/template-engine/index.d.ts.map +1 -0
  225. package/dist/template-engine.d.ts +2 -15
  226. package/dist/template-engine.js +7 -7
  227. package/dist/test-coverage-gate/index.d.ts +35 -0
  228. package/dist/test-coverage-gate/index.d.ts.map +1 -0
  229. package/dist/test-coverage-gate.d.ts +2 -37
  230. package/dist/test-coverage-gate.js +5 -5
  231. package/dist/test-flake-detector/index.d.ts +25 -0
  232. package/dist/test-flake-detector/index.d.ts.map +1 -0
  233. package/dist/test-flake-detector.d.ts +2 -27
  234. package/dist/test-flake-detector.js +98 -13
  235. package/dist/test-generator/index.d.ts +30 -0
  236. package/dist/test-generator/index.d.ts.map +1 -0
  237. package/dist/test-generator.d.ts +2 -32
  238. package/dist/test-generator.js +5 -5
  239. package/dist/test-runner-gate/index.d.ts +35 -0
  240. package/dist/test-runner-gate/index.d.ts.map +1 -0
  241. package/dist/test-runner-gate.d.ts +2 -37
  242. package/dist/test-runner-gate.js +6 -6
  243. package/dist/todo-listener/index.d.ts +35 -0
  244. package/dist/todo-listener/index.d.ts.map +1 -0
  245. package/dist/todo-listener.d.ts +2 -37
  246. package/dist/todo-listener.js +3 -2
  247. package/dist/todo-tracker/index.d.ts +4 -0
  248. package/dist/todo-tracker/index.d.ts.map +1 -0
  249. package/dist/todo-tracker.d.ts +2 -5
  250. package/dist/todo-tracker.js +5 -5
  251. package/dist/token-budget/index.d.ts +38 -0
  252. package/dist/token-budget/index.d.ts.map +1 -0
  253. package/dist/token-budget.d.ts +2 -40
  254. package/dist/token-budget.js +3 -2
  255. package/dist/token-throttle/index.d.ts +52 -0
  256. package/dist/token-throttle/index.d.ts.map +1 -0
  257. package/dist/token-throttle.d.ts +2 -54
  258. package/dist/token-throttle.js +6 -2
  259. package/dist/type-gate/index.d.ts +35 -0
  260. package/dist/type-gate/index.d.ts.map +1 -0
  261. package/dist/type-gate.d.ts +2 -37
  262. package/dist/type-gate.js +236 -43
  263. package/package.json +10 -7
package/dist/index.js CHANGED
@@ -1,14 +1,3 @@
1
- import { dirname, resolve, extname, isAbsolute, relative, join, basename } from 'path';
2
- import { execSync, execFileSync, execFile, spawn } from 'child_process';
3
- import * as fs from 'fs';
4
- import { readFileSync, writeFileSync, mkdirSync, statSync, watch, existsSync, readdirSync } from 'fs';
5
- import * as fsp from 'fs/promises';
6
- import { readFile, stat, mkdtemp, writeFile, rm } from 'fs/promises';
7
- import { expectDefined } from '@wrongstack/core';
8
- import { tmpdir } from 'os';
9
- import { randomUUID, createHash } from 'crypto';
10
- import { toErrorMessage } from '@wrongstack/core/utils';
11
-
12
1
  // src/agent-handoff/index.ts
13
2
  var API_VERSION = "^0.1.10";
14
3
  var state = {
@@ -305,6 +294,9 @@ var plugin = {
305
294
  }
306
295
  };
307
296
  var agent_handoff_default = plugin;
297
+
298
+ // src/auto-doc/index.ts
299
+ import { isAbsolute, relative, resolve } from "node:path";
308
300
  var AUTO_DOC_API_VERSION = "^0.1.10";
309
301
  function resolveProjectPath(rawPath, cwd = process.cwd()) {
310
302
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
@@ -491,10 +483,10 @@ async function runAutoDoc(input, api) {
491
483
  continue;
492
484
  }
493
485
  try {
494
- const { readFileSync: readFileSync24, writeFileSync: writeFileSync8 } = await import('fs');
486
+ const { readFileSync: readFileSync25, writeFileSync: writeFileSync8 } = await import("node:fs");
495
487
  let content;
496
488
  try {
497
- content = readFileSync24(safeFile, "utf-8");
489
+ content = readFileSync25(safeFile, "utf-8");
498
490
  } catch {
499
491
  api.log.warn(`auto-doc: could not read file ${safeFile}`);
500
492
  continue;
@@ -840,6 +832,9 @@ var plugin3 = {
840
832
  }
841
833
  };
842
834
  var auto_escalate_default = plugin3;
835
+
836
+ // src/branch-guard/index.ts
837
+ import { execFile } from "node:child_process";
843
838
  var API_VERSION2 = "^0.1.10";
844
839
  var state4 = {
845
840
  invocationCount: 0,
@@ -892,14 +887,14 @@ function hasDisabledPluginEntry(raw) {
892
887
  });
893
888
  }
894
889
  function runGit(args, cwd, signal) {
895
- return new Promise((resolve34, reject) => {
890
+ return new Promise((resolve36, reject) => {
896
891
  execFile(
897
892
  "git",
898
893
  args,
899
894
  { encoding: "utf-8", timeout: 3e3, cwd, windowsHide: true, signal },
900
895
  (error, stdout) => {
901
896
  if (error) reject(error);
902
- else resolve34(stdout);
897
+ else resolve36(stdout);
903
898
  }
904
899
  );
905
900
  });
@@ -1138,6 +1133,10 @@ var plugin4 = {
1138
1133
  }
1139
1134
  };
1140
1135
  var branch_guard_default = plugin4;
1136
+
1137
+ // src/changelog-writer/index.ts
1138
+ import { readFileSync, writeFileSync } from "node:fs";
1139
+ import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2 } from "node:path";
1141
1140
  var state5 = {
1142
1141
  entries: [],
1143
1142
  filesTouched: /* @__PURE__ */ new Set(),
@@ -1154,10 +1153,10 @@ var DEFAULTS3 = {
1154
1153
  maxEntries: 200
1155
1154
  };
1156
1155
  function resolveProjectPath2(rawPath, cwd = process.cwd()) {
1157
- const root = resolve(cwd);
1158
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
1159
- const rel = relative(root, resolved);
1160
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
1156
+ const root = resolve2(cwd);
1157
+ const resolved = isAbsolute2(rawPath) ? resolve2(rawPath) : resolve2(root, rawPath);
1158
+ const rel = relative2(root, resolved);
1159
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute2(rel)) return resolved;
1161
1160
  return null;
1162
1161
  }
1163
1162
  function readConfig4(raw) {
@@ -1512,6 +1511,11 @@ var plugin5 = {
1512
1511
  }
1513
1512
  };
1514
1513
  var changelog_writer_default = plugin5;
1514
+
1515
+ // src/checkpoint/index.ts
1516
+ import { mkdirSync, readFileSync as readFileSync2, statSync, writeFileSync as writeFileSync2 } from "node:fs";
1517
+ import { readFile, stat } from "node:fs/promises";
1518
+ import { dirname, isAbsolute as isAbsolute3, relative as relative3, resolve as resolve3 } from "node:path";
1515
1519
  var state6 = {
1516
1520
  snapshots: [],
1517
1521
  nextId: 1,
@@ -1537,10 +1541,10 @@ function readConfig5(raw) {
1537
1541
  };
1538
1542
  }
1539
1543
  function resolveProjectPath3(rawPath, cwd = process.cwd()) {
1540
- const root = resolve(cwd);
1541
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
1542
- const rel = relative(root, resolved);
1543
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
1544
+ const root = resolve3(cwd);
1545
+ const resolved = isAbsolute3(rawPath) ? resolve3(rawPath) : resolve3(root, rawPath);
1546
+ const rel = relative3(root, resolved);
1547
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute3(rel)) return resolved;
1544
1548
  return null;
1545
1549
  }
1546
1550
  function hashContent(s) {
@@ -1555,7 +1559,7 @@ function captureFile(path, maxBytes) {
1555
1559
  try {
1556
1560
  const st = statSync(path);
1557
1561
  if (st.size > maxBytes) return "too-large";
1558
- const content = readFileSync(path, "utf-8");
1562
+ const content = readFileSync2(path, "utf-8");
1559
1563
  return { path, content, bytes: st.size };
1560
1564
  } catch {
1561
1565
  return { path, content: null, bytes: 0 };
@@ -1809,7 +1813,7 @@ var plugin6 = {
1809
1813
  }
1810
1814
  try {
1811
1815
  mkdirSync(dirname(f.path), { recursive: true });
1812
- writeFileSync(f.path, f.content);
1816
+ writeFileSync2(f.path, f.content);
1813
1817
  restored.push(f.path);
1814
1818
  } catch (err) {
1815
1819
  errors.push({ path: f.path, error: err instanceof Error ? err.message : String(err) });
@@ -1950,7 +1954,8 @@ function parseCommitMessage(message, cfg) {
1950
1954
  errors.push(
1951
1955
  `Type "${type}" is not in allowedTypes: ${cfg.allowedTypes.join(", ")}. Standard types: ${STANDARD_TYPES.join(", ")}.`
1952
1956
  );
1953
- } else if (cfg.allowedTypes.length === 0 && !STANDARD_TYPES.includes(type)) ;
1957
+ } else if (cfg.allowedTypes.length === 0 && !STANDARD_TYPES.includes(type)) {
1958
+ }
1954
1959
  if (cfg.requireScope && !scope) {
1955
1960
  errors.push("A scope is required (e.g. feat(auth): ...).");
1956
1961
  }
@@ -2244,6 +2249,9 @@ Suggested rewrite (${suggest.model}):
2244
2249
  }
2245
2250
  };
2246
2251
  var commit_validator_default = plugin7;
2252
+
2253
+ // src/config-validator/index.ts
2254
+ import { readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
2247
2255
  var state8 = {
2248
2256
  invocations: 0,
2249
2257
  filesChecked: 0,
@@ -2504,8 +2512,8 @@ var plugin8 = {
2504
2512
  if (!cfg.extensions.some((ext) => lower.endsWith(ext))) return;
2505
2513
  let text;
2506
2514
  try {
2507
- if (statSync(raw).size > cfg.maxFileBytes) return;
2508
- text = readFileSync(raw, "utf-8");
2515
+ if (statSync2(raw).size > cfg.maxFileBytes) return;
2516
+ text = readFileSync3(raw, "utf-8");
2509
2517
  } catch {
2510
2518
  return;
2511
2519
  }
@@ -2586,6 +2594,10 @@ var plugin8 = {
2586
2594
  }
2587
2595
  };
2588
2596
  var config_validator_default = plugin8;
2597
+
2598
+ // src/context-pins/index.ts
2599
+ import * as fs from "node:fs";
2600
+ import { dirname as dirname2, isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4 } from "node:path";
2589
2601
  var state9 = {
2590
2602
  pins: [],
2591
2603
  nextId: 1,
@@ -2602,10 +2614,10 @@ var DEFAULTS7 = {
2602
2614
  };
2603
2615
  function resolveProjectPath4(rawPath, cwd = process.cwd()) {
2604
2616
  if (typeof rawPath !== "string" || rawPath.length === 0) return "";
2605
- const root = resolve(cwd);
2606
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
2607
- const rel = relative(root, resolved);
2608
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
2617
+ const root = resolve4(cwd);
2618
+ const resolved = isAbsolute4(rawPath) ? resolve4(rawPath) : resolve4(root, rawPath);
2619
+ const rel = relative4(root, resolved);
2620
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute4(rel)) return resolved;
2609
2621
  return null;
2610
2622
  }
2611
2623
  function readConfig8(raw) {
@@ -2635,7 +2647,7 @@ function loadPins(filePath) {
2635
2647
  function persistPins(filePath) {
2636
2648
  if (!filePath) return true;
2637
2649
  try {
2638
- fs.mkdirSync(dirname(filePath), { recursive: true });
2650
+ fs.mkdirSync(dirname2(filePath), { recursive: true });
2639
2651
  fs.writeFileSync(filePath, JSON.stringify({ pins: state9.pins, nextId: state9.nextId }, null, 2));
2640
2652
  return true;
2641
2653
  } catch {
@@ -2829,6 +2841,9 @@ var plugin9 = {
2829
2841
  }
2830
2842
  };
2831
2843
  var context_pins_default = plugin9;
2844
+
2845
+ // src/cost-tracker/index.ts
2846
+ import { expectDefined } from "@wrongstack/core";
2832
2847
  var API_VERSION4 = "^0.1.10";
2833
2848
  var PRICING = {
2834
2849
  "gpt-4o": { input: 5, output: 15 },
@@ -3786,15 +3801,19 @@ ${notes.map((n) => ` - ${n}`).join("\n")}`
3786
3801
  }
3787
3802
  };
3788
3803
  var dep_guard_default = plugin12;
3804
+
3805
+ // src/diff-summary/index.ts
3806
+ import { execFileSync } from "node:child_process";
3807
+ import { isAbsolute as isAbsolute5, relative as relative5, resolve as resolve5 } from "node:path";
3789
3808
  var API_VERSION6 = "^0.1.10";
3790
3809
  function withinProject(p) {
3791
3810
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
3792
3811
  const root = process.cwd();
3793
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
3794
- const rel = relative(root, resolved);
3812
+ const resolved = isAbsolute5(p) ? resolve5(p) : resolve5(root, p);
3813
+ const rel = relative5(root, resolved);
3795
3814
  if (rel === "" || rel === ".") return true;
3796
3815
  if (rel.startsWith("..")) return false;
3797
- if (isAbsolute(rel)) return false;
3816
+ if (isAbsolute5(rel)) return false;
3798
3817
  return true;
3799
3818
  }
3800
3819
  var state12 = {
@@ -4381,15 +4400,19 @@ ${errorLine ?? "(no error line)"}
4381
4400
  }
4382
4401
  };
4383
4402
  var error_lens_default = plugin14;
4403
+
4404
+ // src/file-watcher/index.ts
4405
+ import { watch as fsWatch } from "node:fs";
4406
+ import { isAbsolute as isAbsolute6, relative as relative6, resolve as resolve6 } from "node:path";
4384
4407
  var API_VERSION7 = "^0.1.10";
4385
4408
  function withinProject2(p) {
4386
4409
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
4387
4410
  const root = process.cwd();
4388
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
4389
- const rel = relative(root, resolved);
4411
+ const resolved = isAbsolute6(p) ? resolve6(p) : resolve6(root, p);
4412
+ const rel = relative6(root, resolved);
4390
4413
  if (rel === "" || rel === ".") return true;
4391
4414
  if (rel.startsWith("..")) return false;
4392
- if (isAbsolute(rel)) return false;
4415
+ if (isAbsolute6(rel)) return false;
4393
4416
  return true;
4394
4417
  }
4395
4418
  var watch_idCounter = 0;
@@ -4487,7 +4510,7 @@ var plugin15 = {
4487
4510
  }
4488
4511
  function safeWatchDir(dirPath, recursive, handle) {
4489
4512
  try {
4490
- const watcher = watch(dirPath, { recursive }, (eventType, filename) => {
4513
+ const watcher = fsWatch(dirPath, { recursive }, (eventType, filename) => {
4491
4514
  if (!filename) return;
4492
4515
  const fullPath = `${dirPath}/${filename}`;
4493
4516
  const key = `${handle.id}:${fullPath}:${eventType}`;
@@ -4508,7 +4531,7 @@ var plugin15 = {
4508
4531
  `index:${fullPath}`,
4509
4532
  async () => {
4510
4533
  try {
4511
- const { enqueueReindex } = await import('@wrongstack/tools/codebase-index');
4534
+ const { enqueueReindex } = await import("@wrongstack/tools/codebase-index");
4512
4535
  const root = safeIndexRoot || dirPath;
4513
4536
  enqueueReindex({
4514
4537
  projectRoot: root,
@@ -4692,15 +4715,20 @@ var plugin15 = {
4692
4715
  }
4693
4716
  };
4694
4717
  var file_watcher_default = plugin15;
4718
+
4719
+ // src/format-on-save/index.ts
4720
+ import { execFileSync as execFileSync2, execSync } from "node:child_process";
4721
+ import { existsSync, statSync as statSync3 } from "node:fs";
4722
+ import { isAbsolute as isAbsolute7, relative as relative7, resolve as resolve7 } from "node:path";
4695
4723
  var API_VERSION8 = "^0.1.10";
4696
4724
  function withinProject3(p) {
4697
4725
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
4698
4726
  const root = process.cwd();
4699
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
4700
- const rel = relative(root, resolved);
4727
+ const resolved = isAbsolute7(p) ? resolve7(p) : resolve7(root, p);
4728
+ const rel = relative7(root, resolved);
4701
4729
  if (rel === "" || rel === ".") return true;
4702
4730
  if (rel.startsWith("..")) return false;
4703
- if (isAbsolute(rel)) return false;
4731
+ if (isAbsolute7(rel)) return false;
4704
4732
  return true;
4705
4733
  }
4706
4734
  var state14 = {
@@ -4765,12 +4793,12 @@ function formatFile(filePath, timeoutMs) {
4765
4793
  if (!existsSync(filePath)) return null;
4766
4794
  let bytesBefore;
4767
4795
  try {
4768
- bytesBefore = statSync(filePath).size;
4796
+ bytesBefore = statSync3(filePath).size;
4769
4797
  } catch {
4770
4798
  return null;
4771
4799
  }
4772
4800
  try {
4773
- execFileSync("npx", ["biome", "format", "--write", filePath], {
4801
+ execFileSync2("npx", ["biome", "format", "--write", filePath], {
4774
4802
  encoding: "utf-8",
4775
4803
  timeout: timeoutMs,
4776
4804
  cwd: process.cwd(),
@@ -4782,7 +4810,7 @@ function formatFile(filePath, timeoutMs) {
4782
4810
  }
4783
4811
  let bytesAfter;
4784
4812
  try {
4785
- bytesAfter = statSync(filePath).size;
4813
+ bytesAfter = statSync3(filePath).size;
4786
4814
  } catch {
4787
4815
  return null;
4788
4816
  }
@@ -4790,7 +4818,7 @@ function formatFile(filePath, timeoutMs) {
4790
4818
  return { changed: true, bytesBefore, bytesAfter };
4791
4819
  }
4792
4820
  try {
4793
- execFileSync("npx", ["biome", "format", filePath], {
4821
+ execFileSync2("npx", ["biome", "format", filePath], {
4794
4822
  encoding: "utf-8",
4795
4823
  timeout: timeoutMs,
4796
4824
  cwd: process.cwd(),
@@ -4985,6 +5013,10 @@ var plugin16 = {
4985
5013
  }
4986
5014
  };
4987
5015
  var format_on_save_default = plugin16;
5016
+
5017
+ // src/git-autocommit/index.ts
5018
+ import { execFileSync as execFileSync3 } from "node:child_process";
5019
+ import { existsSync as existsSync2 } from "node:fs";
4988
5020
  var API_VERSION9 = "^0.1.10";
4989
5021
  var commitCount = { value: 0 };
4990
5022
  var lastCommit = { hash: null, at: null };
@@ -4993,7 +5025,7 @@ var DEFAULT_GIT_TIMEOUT_MS = 3e4;
4993
5025
  var GIT_COMMIT_TIMEOUT_MS = 5 * 6e4;
4994
5026
  function runGit2(args, cwd, timeoutMs = DEFAULT_GIT_TIMEOUT_MS) {
4995
5027
  try {
4996
- return execFileSync("git", args, {
5028
+ return execFileSync3("git", args, {
4997
5029
  encoding: "utf-8",
4998
5030
  cwd,
4999
5031
  stdio: ["pipe", "pipe", "pipe"],
@@ -5019,7 +5051,7 @@ function stageFiles(files, cwd) {
5019
5051
  if (!files || !Array.isArray(files)) return;
5020
5052
  const existing = files.filter((f) => {
5021
5053
  try {
5022
- return existsSync(f);
5054
+ return existsSync2(f);
5023
5055
  } catch {
5024
5056
  return false;
5025
5057
  }
@@ -5441,14 +5473,19 @@ ${preCommitDiff}
5441
5473
  }
5442
5474
  };
5443
5475
  var git_autocommit_default = plugin17;
5476
+
5477
+ // src/import-organizer/index.ts
5478
+ import { spawn } from "node:child_process";
5479
+ import { existsSync as existsSync3, statSync as statSync4 } from "node:fs";
5480
+ import { basename, isAbsolute as isAbsolute8, relative as relative8, resolve as resolve8 } from "node:path";
5444
5481
  function withinProject4(p) {
5445
5482
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
5446
5483
  const root = process.cwd();
5447
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
5448
- const rel = relative(root, resolved);
5484
+ const resolved = isAbsolute8(p) ? resolve8(p) : resolve8(root, p);
5485
+ const rel = relative8(root, resolved);
5449
5486
  if (rel === "" || rel === ".") return true;
5450
5487
  if (rel.startsWith("..")) return false;
5451
- if (isAbsolute(rel)) return false;
5488
+ if (isAbsolute8(rel)) return false;
5452
5489
  return true;
5453
5490
  }
5454
5491
  var ALLOWED_FIRST_TOKENS = /* @__PURE__ */ new Set([
@@ -5470,12 +5507,12 @@ function resolveAllowedCommand(command) {
5470
5507
  if (ALLOWED_FIRST_TOKENS.has(head)) {
5471
5508
  return { cmd: head, args: tokens.slice(1) };
5472
5509
  }
5473
- if (isAbsolute(head)) {
5510
+ if (isAbsolute8(head)) {
5474
5511
  if (!withinProject4(head)) return null;
5475
5512
  const base = basename(head);
5476
5513
  if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
5477
5514
  }
5478
- if (!isAbsolute(head) && withinProject4(head)) {
5515
+ if (!isAbsolute8(head) && withinProject4(head)) {
5479
5516
  const base = basename(head);
5480
5517
  if (ALLOWED_FIRST_TOKENS.has(base)) return { cmd: head, args: tokens.slice(1) };
5481
5518
  }
@@ -5511,7 +5548,7 @@ function readConfig13(raw) {
5511
5548
  };
5512
5549
  }
5513
5550
  function runCommand(command, args, timeoutMs, cwd) {
5514
- return new Promise((resolve34) => {
5551
+ return new Promise((resolve36) => {
5515
5552
  let timedOut = false;
5516
5553
  const stdoutChunks = [];
5517
5554
  const stderrChunks = [];
@@ -5523,17 +5560,17 @@ function runCommand(command, args, timeoutMs, cwd) {
5523
5560
  signal: AbortSignal.timeout(timeoutMs)
5524
5561
  });
5525
5562
  } catch {
5526
- resolve34({ code: 127, stdout: "", stderr: "", timedOut: false });
5563
+ resolve36({ code: 127, stdout: "", stderr: "", timedOut: false });
5527
5564
  return;
5528
5565
  }
5529
5566
  child.stdout?.on("data", (c) => stdoutChunks.push(c));
5530
5567
  child.stderr?.on("data", (c) => stderrChunks.push(c));
5531
5568
  child.on("error", () => {
5532
- resolve34({ code: 127, stdout: "", stderr: "", timedOut: false });
5569
+ resolve36({ code: 127, stdout: "", stderr: "", timedOut: false });
5533
5570
  });
5534
5571
  child.on("close", (code) => {
5535
5572
  if (timedOut) return;
5536
- resolve34({
5573
+ resolve36({
5537
5574
  code,
5538
5575
  stdout: Buffer.concat(stdoutChunks).toString("utf-8"),
5539
5576
  stderr: Buffer.concat(stderrChunks).toString("utf-8"),
@@ -5542,16 +5579,16 @@ function runCommand(command, args, timeoutMs, cwd) {
5542
5579
  });
5543
5580
  child.on("abort", () => {
5544
5581
  timedOut = true;
5545
- resolve34({ code: null, stdout: "", stderr: "", timedOut: true });
5582
+ resolve36({ code: null, stdout: "", stderr: "", timedOut: true });
5546
5583
  });
5547
5584
  });
5548
5585
  }
5549
5586
  async function organizeImports(filePath, cfg, cwd) {
5550
5587
  if (!withinProject4(filePath)) return null;
5551
- if (!existsSync(filePath)) return null;
5588
+ if (!existsSync3(filePath)) return null;
5552
5589
  let bytesBefore;
5553
5590
  try {
5554
- bytesBefore = statSync(filePath).size;
5591
+ bytesBefore = statSync4(filePath).size;
5555
5592
  } catch {
5556
5593
  return null;
5557
5594
  }
@@ -5572,7 +5609,7 @@ async function organizeImports(filePath, cfg, cwd) {
5572
5609
  if (result.code === 127) return null;
5573
5610
  let bytesAfter;
5574
5611
  try {
5575
- bytesAfter = statSync(filePath).size;
5612
+ bytesAfter = statSync4(filePath).size;
5576
5613
  } catch {
5577
5614
  return null;
5578
5615
  }
@@ -5972,6 +6009,10 @@ var plugin19 = {
5972
6009
  }
5973
6010
  };
5974
6011
  var injection_shield_default = plugin19;
6012
+
6013
+ // src/knowledge-graph/index.ts
6014
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "node:fs";
6015
+ import { dirname as dirname3, isAbsolute as isAbsolute9, relative as relative9, resolve as resolve9 } from "node:path";
5975
6016
  var API_VERSION11 = "^0.1.10";
5976
6017
  var state17 = {
5977
6018
  facts: [],
@@ -5992,10 +6033,10 @@ var DEFAULTS14 = {
5992
6033
  };
5993
6034
  function resolveProjectPath5(rawPath, cwd = process.cwd()) {
5994
6035
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
5995
- const root = resolve(cwd);
5996
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
5997
- const rel = relative(root, resolved);
5998
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
6036
+ const root = resolve9(cwd);
6037
+ const resolved = isAbsolute9(rawPath) ? resolve9(rawPath) : resolve9(root, rawPath);
6038
+ const rel = relative9(root, resolved);
6039
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute9(rel)) return resolved;
5999
6040
  return null;
6000
6041
  }
6001
6042
  function readConfig15(raw) {
@@ -6013,7 +6054,7 @@ function readConfig15(raw) {
6013
6054
  function loadFacts(filePath) {
6014
6055
  if (!filePath) return { facts: [], nextId: 1 };
6015
6056
  try {
6016
- const raw = JSON.parse(readFileSync(filePath, "utf-8"));
6057
+ const raw = JSON.parse(readFileSync5(filePath, "utf-8"));
6017
6058
  const facts = Array.isArray(raw.facts) ? raw.facts.filter(
6018
6059
  (f) => !!f && typeof f === "object" && typeof f.id === "string" && typeof f.subject === "string" && typeof f.relation === "string" && typeof f.object === "string"
6019
6060
  ) : [];
@@ -6026,8 +6067,8 @@ function loadFacts(filePath) {
6026
6067
  function persistFacts(filePath) {
6027
6068
  if (!filePath) return true;
6028
6069
  try {
6029
- mkdirSync(dirname(filePath), { recursive: true });
6030
- writeFileSync(
6070
+ mkdirSync3(dirname3(filePath), { recursive: true });
6071
+ writeFileSync4(
6031
6072
  filePath,
6032
6073
  JSON.stringify({ facts: state17.facts, nextId: state17.nextId }, null, 2)
6033
6074
  );
@@ -6291,6 +6332,12 @@ var plugin20 = {
6291
6332
  }
6292
6333
  };
6293
6334
  var knowledge_graph_default = plugin20;
6335
+
6336
+ // src/lint-gate/index.ts
6337
+ import { execFile as execFile2 } from "node:child_process";
6338
+ import { mkdtemp, readFile as readFile2, rm, writeFile } from "node:fs/promises";
6339
+ import { tmpdir } from "node:os";
6340
+ import { join } from "node:path";
6294
6341
  var API_VERSION12 = "^0.1.10";
6295
6342
  var state18 = {
6296
6343
  /** Total PreToolUse invocations. */
@@ -6328,9 +6375,9 @@ function executable(command) {
6328
6375
  return process.platform === "win32" && command === "npx" ? "npx.cmd" : command;
6329
6376
  }
6330
6377
  function runCommand2(command, args, timeoutMs, signal) {
6331
- return new Promise((resolve34) => {
6378
+ return new Promise((resolve36) => {
6332
6379
  try {
6333
- execFile(
6380
+ execFile2(
6334
6381
  executable(command),
6335
6382
  args,
6336
6383
  {
@@ -6341,10 +6388,10 @@ function runCommand2(command, args, timeoutMs, signal) {
6341
6388
  maxBuffer: 2 * 1024 * 1024,
6342
6389
  ...signal ? { signal } : {}
6343
6390
  },
6344
- (error, stdout) => resolve34({ stdout, error })
6391
+ (error, stdout) => resolve36({ stdout, error })
6345
6392
  );
6346
6393
  } catch (err) {
6347
- resolve34({ stdout: "", error: err instanceof Error ? err : new Error(String(err)) });
6394
+ resolve36({ stdout: "", error: err instanceof Error ? err : new Error(String(err)) });
6348
6395
  }
6349
6396
  });
6350
6397
  }
@@ -6392,7 +6439,7 @@ async function lintAndFix(content, filePath, linter, timeoutMs, signal) {
6392
6439
  const fixArgs = linter.name === "biome" ? ["biome", "check", "--write", tmpFile] : ["eslint", "--fix", tmpFile];
6393
6440
  await runCommand2(linter.cmd, fixArgs, timeoutMs, signal);
6394
6441
  if (signal.aborted) throw signal.reason;
6395
- return await readFile(tmpFile, "utf-8");
6442
+ return await readFile2(tmpFile, "utf-8");
6396
6443
  } catch {
6397
6444
  if (signal.aborted) throw signal.reason;
6398
6445
  return content;
@@ -6519,7 +6566,7 @@ var plugin21 = {
6519
6566
  const newStr = inp["new_string"];
6520
6567
  if (typeof oldStr !== "string" || typeof newStr !== "string") return;
6521
6568
  try {
6522
- const current = await readFile(filePath, "utf-8");
6569
+ const current = await readFile2(filePath, "utf-8");
6523
6570
  content = applyEdit(current, oldStr, newStr);
6524
6571
  } catch {
6525
6572
  return;
@@ -6713,6 +6760,9 @@ ${summary}${truncated}`
6713
6760
  }
6714
6761
  };
6715
6762
  var lint_gate_default = plugin21;
6763
+
6764
+ // src/llm-cache/index.ts
6765
+ import { createHash } from "node:crypto";
6716
6766
  var state19 = {
6717
6767
  cache: /* @__PURE__ */ new Map(),
6718
6768
  hits: 0,
@@ -6964,6 +7014,9 @@ var plugin22 = {
6964
7014
  }
6965
7015
  };
6966
7016
  var llm_cache_default = plugin22;
7017
+
7018
+ // src/loop-breaker/index.ts
7019
+ import { execFile as execFile3 } from "node:child_process";
6967
7020
  var state20 = {
6968
7021
  lastFingerprint: null,
6969
7022
  streak: 0,
@@ -7059,8 +7112,8 @@ function hashString2(value) {
7059
7112
  }
7060
7113
  async function gitDiffFingerprint(cwd, signal) {
7061
7114
  try {
7062
- const diff = await new Promise((resolve34, reject) => {
7063
- execFile(
7115
+ const diff = await new Promise((resolve36, reject) => {
7116
+ execFile3(
7064
7117
  "git",
7065
7118
  ["diff", "--no-ext-diff", "--"],
7066
7119
  {
@@ -7076,7 +7129,7 @@ async function gitDiffFingerprint(cwd, signal) {
7076
7129
  },
7077
7130
  (error, stdout) => {
7078
7131
  if (error) reject(error);
7079
- else resolve34(stdout);
7132
+ else resolve36(stdout);
7080
7133
  }
7081
7134
  );
7082
7135
  });
@@ -8330,6 +8383,11 @@ function readConfig22(raw) {
8330
8383
  };
8331
8384
  }
8332
8385
  var plugin_stack_observer_default = PLUGIN;
8386
+
8387
+ // src/pr-drafter/index.ts
8388
+ import { execFileSync as execFileSync4 } from "node:child_process";
8389
+ import { mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "node:fs";
8390
+ import { dirname as dirname4, isAbsolute as isAbsolute10, relative as relative10, resolve as resolve10 } from "node:path";
8333
8391
  var API_VERSION13 = "^0.1.10";
8334
8392
  var state25 = {
8335
8393
  commits: [],
@@ -8368,15 +8426,15 @@ function readConfig23(raw) {
8368
8426
  }
8369
8427
  function resolveProjectPath6(rawPath, cwd = process.cwd()) {
8370
8428
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
8371
- const root = resolve(cwd);
8372
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
8373
- const rel = relative(root, resolved);
8374
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
8429
+ const root = resolve10(cwd);
8430
+ const resolved = isAbsolute10(rawPath) ? resolve10(rawPath) : resolve10(root, rawPath);
8431
+ const rel = relative10(root, resolved);
8432
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute10(rel)) return resolved;
8375
8433
  return null;
8376
8434
  }
8377
8435
  function gitBranch() {
8378
8436
  try {
8379
- const out = execFileSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
8437
+ const out = execFileSync4("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
8380
8438
  encoding: "utf-8",
8381
8439
  cwd: process.cwd(),
8382
8440
  stdio: ["pipe", "pipe", "ignore"],
@@ -8389,7 +8447,7 @@ function gitBranch() {
8389
8447
  }
8390
8448
  function gitDiff() {
8391
8449
  try {
8392
- return execFileSync("git", ["diff", "--stat"], {
8450
+ return execFileSync4("git", ["diff", "--stat"], {
8393
8451
  encoding: "utf-8",
8394
8452
  cwd: process.cwd(),
8395
8453
  stdio: ["pipe", "pipe", "ignore"],
@@ -8458,8 +8516,8 @@ async function writeDraft(cfg, llm) {
8458
8516
  }
8459
8517
  const draft = await buildDraft(cfg, llm);
8460
8518
  try {
8461
- mkdirSync(dirname(resolved), { recursive: true });
8462
- writeFileSync(resolved, draft.body);
8519
+ mkdirSync4(dirname4(resolved), { recursive: true });
8520
+ writeFileSync5(resolved, draft.body);
8463
8521
  state25.draftsWritten += 1;
8464
8522
  } catch {
8465
8523
  state25.draftErrors += 1;
@@ -8585,8 +8643,8 @@ var plugin27 = {
8585
8643
  const resolved = resolveProjectPath6(cfg.outputPath);
8586
8644
  if (!resolved) return { ok: false, error: "outputPath resolves outside project" };
8587
8645
  try {
8588
- mkdirSync(dirname(resolved), { recursive: true });
8589
- writeFileSync(resolved, draft.body);
8646
+ mkdirSync4(dirname4(resolved), { recursive: true });
8647
+ writeFileSync5(resolved, draft.body);
8590
8648
  state25.draftsWritten += 1;
8591
8649
  return {
8592
8650
  ok: true,
@@ -9374,13 +9432,20 @@ var plugin29 = {
9374
9432
  }
9375
9433
  };
9376
9434
  var secret_scanner_default = plugin29;
9435
+
9436
+ // src/semver-bump/index.ts
9437
+ import { expectDefined as expectDefined2 } from "@wrongstack/core";
9438
+ import { toErrorMessage } from "@wrongstack/core/utils";
9439
+ import { execFileSync as execFileSync5 } from "node:child_process";
9440
+ import { existsSync as existsSync4, readFileSync as readFileSync6, readdirSync, writeFileSync as writeFileSync6 } from "node:fs";
9441
+ import { isAbsolute as isAbsolute11, join as join2, relative as relative11, resolve as resolve11 } from "node:path";
9377
9442
  var API_VERSION14 = "^0.1.10";
9378
9443
  function resolveProjectRoot(rawCwd, root = process.cwd()) {
9379
9444
  if (typeof rawCwd !== "string" || rawCwd.length === 0) return root;
9380
- const base = resolve(root);
9381
- const resolved = isAbsolute(rawCwd) ? resolve(rawCwd) : resolve(base, rawCwd);
9382
- const rel = relative(base, resolved);
9383
- if (rel === "" || !rel.startsWith("..") && !isAbsolute(rel)) return resolved;
9445
+ const base = resolve11(root);
9446
+ const resolved = isAbsolute11(rawCwd) ? resolve11(rawCwd) : resolve11(base, rawCwd);
9447
+ const rel = relative11(base, resolved);
9448
+ if (rel === "" || !rel.startsWith("..") && !isAbsolute11(rel)) return resolved;
9384
9449
  return null;
9385
9450
  }
9386
9451
  var state28 = {
@@ -9393,7 +9458,7 @@ var state28 = {
9393
9458
  };
9394
9459
  function runGit3(args, cwd) {
9395
9460
  try {
9396
- return execFileSync("git", args, {
9461
+ return execFileSync5("git", args, {
9397
9462
  encoding: "utf-8",
9398
9463
  cwd,
9399
9464
  stdio: ["pipe", "pipe", "pipe"],
@@ -9408,24 +9473,24 @@ function runGit3(args, cwd) {
9408
9473
  }
9409
9474
  function getPackageJson(cwd) {
9410
9475
  const path = cwd ? `${cwd}/package.json` : "package.json";
9411
- if (!existsSync(path)) return null;
9476
+ if (!existsSync4(path)) return null;
9412
9477
  try {
9413
- return JSON.parse(readFileSync(path, "utf-8"));
9478
+ return JSON.parse(readFileSync6(path, "utf-8"));
9414
9479
  } catch {
9415
9480
  return null;
9416
9481
  }
9417
9482
  }
9418
9483
  function collectManifests(root) {
9419
9484
  const paths = [];
9420
- const rootPkg = join(root, "package.json");
9421
- if (existsSync(rootPkg)) paths.push(rootPkg);
9485
+ const rootPkg = join2(root, "package.json");
9486
+ if (existsSync4(rootPkg)) paths.push(rootPkg);
9422
9487
  for (const group of ["packages", "apps"]) {
9423
- const groupDir = join(root, group);
9424
- if (!existsSync(groupDir)) continue;
9488
+ const groupDir = join2(root, group);
9489
+ if (!existsSync4(groupDir)) continue;
9425
9490
  for (const entry of readdirSync(groupDir, { withFileTypes: true })) {
9426
9491
  if (!entry.isDirectory()) continue;
9427
- const candidate = join(groupDir, entry.name, "package.json");
9428
- if (existsSync(candidate)) paths.push(candidate);
9492
+ const candidate = join2(groupDir, entry.name, "package.json");
9493
+ if (existsSync4(candidate)) paths.push(candidate);
9429
9494
  }
9430
9495
  }
9431
9496
  return paths;
@@ -9434,9 +9499,9 @@ function parseVersion(v) {
9434
9499
  const m = v.match(/^v?(\d+)\.(\d+)\.(\d+)/);
9435
9500
  if (!m) return [0, 0, 0];
9436
9501
  return [
9437
- Number.parseInt(expectDefined(m[1]), 10),
9438
- Number.parseInt(expectDefined(m[2]), 10),
9439
- Number.parseInt(expectDefined(m[3]), 10)
9502
+ Number.parseInt(expectDefined2(m[1]), 10),
9503
+ Number.parseInt(expectDefined2(m[2]), 10),
9504
+ Number.parseInt(expectDefined2(m[3]), 10)
9440
9505
  ];
9441
9506
  }
9442
9507
  function bumpVersion(version, part) {
@@ -9615,11 +9680,11 @@ var plugin30 = {
9615
9680
  };
9616
9681
  }
9617
9682
  const root = cwd ?? process.cwd();
9618
- const bumpScript = join(root, "scripts", "bump-version.mjs");
9683
+ const bumpScript = join2(root, "scripts", "bump-version.mjs");
9619
9684
  const changed = collectManifests(root);
9620
- if (existsSync(bumpScript)) {
9685
+ if (existsSync4(bumpScript)) {
9621
9686
  try {
9622
- execFileSync(process.execPath, [bumpScript, "set", newVersion], {
9687
+ execFileSync5(process.execPath, [bumpScript, "set", newVersion], {
9623
9688
  cwd: root,
9624
9689
  stdio: ["pipe", "pipe", "pipe"],
9625
9690
  timeout: 3e4,
@@ -9630,14 +9695,14 @@ var plugin30 = {
9630
9695
  return { ok: false, error: `bump script failed: ${msg}` };
9631
9696
  }
9632
9697
  for (const rel of ["package.json", "package-lock.json", "src/lib/utils.ts", "index.html"]) {
9633
- const p = join(root, "website", rel);
9634
- if (existsSync(p)) changed.push(p);
9698
+ const p = join2(root, "website", rel);
9699
+ if (existsSync4(p)) changed.push(p);
9635
9700
  }
9636
9701
  } else {
9637
9702
  for (const manifest of changed) {
9638
- const pkgData = JSON.parse(readFileSync(manifest, "utf-8"));
9703
+ const pkgData = JSON.parse(readFileSync6(manifest, "utf-8"));
9639
9704
  pkgData.version = newVersion;
9640
- writeFileSync(manifest, JSON.stringify(pkgData, null, 2) + "\n", "utf-8");
9705
+ writeFileSync6(manifest, JSON.stringify(pkgData, null, 2) + "\n", "utf-8");
9641
9706
  }
9642
9707
  }
9643
9708
  try {
@@ -9969,7 +10034,7 @@ async function readTranscriptTail(transcriptPath, n) {
9969
10034
  if (!transcriptPath || n <= 0) return [];
9970
10035
  let raw;
9971
10036
  try {
9972
- const { readFile: readFile6 } = await import('fs/promises');
10037
+ const { readFile: readFile6 } = await import("node:fs/promises");
9973
10038
  raw = await readFile6(transcriptPath, "utf-8");
9974
10039
  } catch {
9975
10040
  return [];
@@ -10071,7 +10136,8 @@ var plugin31 = {
10071
10136
  const p = payload;
10072
10137
  const toolName = p?.tool ?? p?.name ?? eventName;
10073
10138
  if (typeof toolName === "string") bumpToolCount(toolName);
10074
- if (toolName === "git_autocommit" || toolName.startsWith("git ")) ;
10139
+ if (toolName === "git_autocommit" || toolName.startsWith("git ")) {
10140
+ }
10075
10141
  });
10076
10142
  state29.eventUnsubscribers.push(offTool);
10077
10143
  const offResult = api.onPattern("tool.result", (_event, payload) => {
@@ -10306,14 +10372,19 @@ Tokens: ${recap.tokens.total.input} in / ${recap.tokens.total.output} out
10306
10372
  }
10307
10373
  };
10308
10374
  var session_recap_default = plugin31;
10375
+
10376
+ // src/shell-check/index.ts
10377
+ import { execFileSync as execFileSync6, execSync as execSync2 } from "node:child_process";
10378
+ import { existsSync as existsSync5, readdirSync as readdirSync2 } from "node:fs";
10379
+ import { isAbsolute as isAbsolute12, join as join3, relative as relative12, resolve as resolve12 } from "node:path";
10309
10380
  var API_VERSION15 = "^0.1.10";
10310
10381
  function withinProject5(p) {
10311
10382
  const root = process.cwd();
10312
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
10313
- const rel = relative(root, resolved);
10383
+ const resolved = isAbsolute12(p) ? resolve12(p) : resolve12(root, p);
10384
+ const rel = relative12(root, resolved);
10314
10385
  if (rel === "" || rel === ".") return true;
10315
10386
  if (rel.startsWith("..")) return false;
10316
- if (isAbsolute(rel)) return false;
10387
+ if (isAbsolute12(rel)) return false;
10317
10388
  return true;
10318
10389
  }
10319
10390
  var MAX_PATH_LEN = 4096;
@@ -10326,9 +10397,9 @@ var state30 = {
10326
10397
  lastRun: null
10327
10398
  };
10328
10399
  function runShellCheck(files, severity, cwd) {
10329
- if (!existsSync("shellcheck")) {
10400
+ if (!existsSync5("shellcheck")) {
10330
10401
  try {
10331
- execSync("shellcheck --version", { encoding: "utf-8", stdio: "ignore", windowsHide: true });
10402
+ execSync2("shellcheck --version", { encoding: "utf-8", stdio: "ignore", windowsHide: true });
10332
10403
  } catch {
10333
10404
  throw new Error(
10334
10405
  "shellcheck is not installed. Install via: apt install shellcheck / brew install shellcheck"
@@ -10345,7 +10416,7 @@ function runShellCheck(files, severity, cwd) {
10345
10416
  const args = ["-f", "json", "-S", severityFlag, ...files];
10346
10417
  let raw;
10347
10418
  try {
10348
- raw = execFileSync("shellcheck", args, {
10419
+ raw = execFileSync6("shellcheck", args, {
10349
10420
  encoding: "utf-8",
10350
10421
  cwd,
10351
10422
  stdio: ["pipe", "pipe", "pipe"],
@@ -10378,9 +10449,9 @@ function runShellCheck(files, severity, cwd) {
10378
10449
  function findShellFiles(dir, pattern) {
10379
10450
  const results = [];
10380
10451
  try {
10381
- const entries = readdirSync(dir, { withFileTypes: true });
10452
+ const entries = readdirSync2(dir, { withFileTypes: true });
10382
10453
  for (const entry of entries) {
10383
- const full = join(dir, entry.name);
10454
+ const full = join3(dir, entry.name);
10384
10455
  if (entry.isDirectory() && entry.name !== "node_modules" && entry.name !== ".git") {
10385
10456
  results.push(...findShellFiles(full, pattern));
10386
10457
  } else if (entry.isFile() && (entry.name.endsWith(".sh") || entry.name === "Dockerfile")) {
@@ -10579,6 +10650,12 @@ var plugin32 = {
10579
10650
  }
10580
10651
  };
10581
10652
  var shell_check_default = plugin32;
10653
+
10654
+ // src/spec-linker/index.ts
10655
+ import * as fs3 from "node:fs/promises";
10656
+
10657
+ // src/template-engine/index.ts
10658
+ import { isAbsolute as isAbsolute13 } from "node:path";
10582
10659
  var API_VERSION16 = "^0.1.10";
10583
10660
  var templates = /* @__PURE__ */ new Map();
10584
10661
  function expandTemplate(template, variables) {
@@ -10625,7 +10702,7 @@ function renderTemplateRaw(template, variables) {
10625
10702
  return result;
10626
10703
  }
10627
10704
  function validateRelativeTemplatePath(field, value) {
10628
- if (isAbsolute(value) || value.split(/[\\/]+/).includes("..")) {
10705
+ if (isAbsolute13(value) || value.split(/[\\/]+/).includes("..")) {
10629
10706
  return `${field} must be a relative path without ".." components`;
10630
10707
  }
10631
10708
  return null;
@@ -10698,7 +10775,7 @@ var plugin33 = {
10698
10775
  if (output_path) {
10699
10776
  const pathError = validateRelativeTemplatePath("output_path", output_path);
10700
10777
  if (pathError) return { ok: false, error: pathError };
10701
- const { writeFileSync: writeFileSync8 } = await import('fs');
10778
+ const { writeFileSync: writeFileSync8 } = await import("node:fs");
10702
10779
  writeFileSync8(output_path, result, "utf-8");
10703
10780
  return {
10704
10781
  ok: true,
@@ -10752,8 +10829,8 @@ var plugin33 = {
10752
10829
  }
10753
10830
  let content;
10754
10831
  try {
10755
- const { readFileSync: readFileSync24 } = await import('fs');
10756
- content = readFileSync24(template_path, "utf-8");
10832
+ const { readFileSync: readFileSync25 } = await import("node:fs");
10833
+ content = readFileSync25(template_path, "utf-8");
10757
10834
  } catch (err) {
10758
10835
  return { ok: false, error: `Could not read template file: ${err}` };
10759
10836
  }
@@ -10766,7 +10843,7 @@ var plugin33 = {
10766
10843
  if (output_path) {
10767
10844
  const pathError = validateRelativeTemplatePath("output_path", output_path);
10768
10845
  if (pathError) return { ok: false, error: pathError };
10769
- const { writeFileSync: writeFileSync8 } = await import('fs');
10846
+ const { writeFileSync: writeFileSync8 } = await import("node:fs");
10770
10847
  writeFileSync8(output_path, result, "utf-8");
10771
10848
  return {
10772
10849
  ok: true,
@@ -10884,6 +10961,10 @@ var plugin33 = {
10884
10961
  }
10885
10962
  };
10886
10963
  var template_engine_default = plugin33;
10964
+
10965
+ // src/test-coverage-gate/index.ts
10966
+ import { readFileSync as readFileSync7 } from "node:fs";
10967
+ import { isAbsolute as isAbsolute14, relative as relative13, resolve as resolve13 } from "node:path";
10887
10968
  var API_VERSION17 = "^0.1.10";
10888
10969
  var state31 = {
10889
10970
  invocationCount: 0,
@@ -10919,16 +11000,16 @@ function readConfig27(raw) {
10919
11000
  function withinProject6(p) {
10920
11001
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
10921
11002
  const root = process.cwd();
10922
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
10923
- const rel = relative(root, resolved);
11003
+ const resolved = isAbsolute14(p) ? resolve13(p) : resolve13(root, p);
11004
+ const rel = relative13(root, resolved);
10924
11005
  if (rel === "" || rel === ".") return true;
10925
11006
  if (rel.startsWith("..")) return false;
10926
- if (isAbsolute(rel)) return false;
11007
+ if (isAbsolute14(rel)) return false;
10927
11008
  return true;
10928
11009
  }
10929
11010
  function readCoverageSummary(coveragePath) {
10930
11011
  try {
10931
- const raw = readFileSync(coveragePath, "utf-8");
11012
+ const raw = readFileSync7(coveragePath, "utf-8");
10932
11013
  return JSON.parse(raw);
10933
11014
  } catch {
10934
11015
  return null;
@@ -11141,6 +11222,11 @@ var plugin34 = {
11141
11222
  }
11142
11223
  };
11143
11224
  var test_coverage_gate_default = plugin34;
11225
+
11226
+ // src/test-runner-gate/index.ts
11227
+ import { execFileSync as execFileSync7, execSync as execSync3 } from "node:child_process";
11228
+ import { existsSync as existsSync6 } from "node:fs";
11229
+ import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute15, join as join4, relative as relative14, resolve as resolve14 } from "node:path";
11144
11230
  var API_VERSION18 = "^0.1.10";
11145
11231
  var state32 = {
11146
11232
  invocationCount: 0,
@@ -11209,11 +11295,11 @@ var lastPassedHash = /* @__PURE__ */ new Map();
11209
11295
  function withinProject7(p) {
11210
11296
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
11211
11297
  const root = process.cwd();
11212
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
11213
- const rel = relative(root, resolved);
11298
+ const resolved = isAbsolute15(p) ? resolve14(p) : resolve14(root, p);
11299
+ const rel = relative14(root, resolved);
11214
11300
  if (rel === "" || rel === ".") return true;
11215
11301
  if (rel.startsWith("..")) return false;
11216
- if (isAbsolute(rel)) return false;
11302
+ if (isAbsolute15(rel)) return false;
11217
11303
  return true;
11218
11304
  }
11219
11305
  var ALLOWED_COMMAND_TOKENS = /* @__PURE__ */ new Set([
@@ -11231,9 +11317,9 @@ var ALLOWED_COMMAND_TOKENS = /* @__PURE__ */ new Set([
11231
11317
  // by basename in resolveAllowedCommand().
11232
11318
  ]);
11233
11319
  function resolveTestFiles(sourcePath, patterns) {
11234
- const name = basename(sourcePath).replace(/\.[^.]+$/, "");
11320
+ const name = basename2(sourcePath).replace(/\.[^.]+$/, "");
11235
11321
  const pathNoExt = sourcePath.replace(/\.[^.]+$/, "");
11236
- const dir = dirname(sourcePath);
11322
+ const dir = dirname5(sourcePath);
11237
11323
  const candidates = [];
11238
11324
  for (const pattern of patterns) {
11239
11325
  const candidate = pattern.replace(/\{name\}/g, name).replace(/\{path\}/g, pathNoExt).replace(/\{dir\}/g, dir);
@@ -11242,7 +11328,7 @@ function resolveTestFiles(sourcePath, patterns) {
11242
11328
  candidates.push(candidate);
11243
11329
  } else {
11244
11330
  candidates.push(candidate);
11245
- candidates.push(join(dir, candidate));
11331
+ candidates.push(join4(dir, candidate));
11246
11332
  }
11247
11333
  }
11248
11334
  }
@@ -11251,7 +11337,7 @@ function resolveTestFiles(sourcePath, patterns) {
11251
11337
  function findTestFile(sourcePath, patterns) {
11252
11338
  const candidates = resolveTestFiles(sourcePath, patterns);
11253
11339
  for (const candidate of candidates) {
11254
- if (existsSync(candidate)) return candidate;
11340
+ if (existsSync6(candidate)) return candidate;
11255
11341
  }
11256
11342
  return null;
11257
11343
  }
@@ -11265,7 +11351,7 @@ function detectRunner(requested) {
11265
11351
  const match = candidates.find((c) => c.name === requested);
11266
11352
  if (!match) return null;
11267
11353
  try {
11268
- execSync(`npx ${match.name} --version`, {
11354
+ execSync3(`npx ${match.name} --version`, {
11269
11355
  encoding: "utf-8",
11270
11356
  timeout: 5e3,
11271
11357
  cwd: process.cwd(),
@@ -11278,7 +11364,7 @@ function detectRunner(requested) {
11278
11364
  }
11279
11365
  for (const candidate of candidates) {
11280
11366
  try {
11281
- execSync(`npx ${candidate.name} --version`, {
11367
+ execSync3(`npx ${candidate.name} --version`, {
11282
11368
  encoding: "utf-8",
11283
11369
  timeout: 5e3,
11284
11370
  cwd: process.cwd(),
@@ -11297,9 +11383,9 @@ function resolveAllowedCommand2(customCommand) {
11297
11383
  if (ALLOWED_COMMAND_TOKENS.has(head)) {
11298
11384
  return { cmd: head, args: tokens.slice(1) };
11299
11385
  }
11300
- if (isAbsolute(head)) {
11386
+ if (isAbsolute15(head)) {
11301
11387
  if (!withinProject7(head)) return null;
11302
- const base = basename(head);
11388
+ const base = basename2(head);
11303
11389
  if (ALLOWED_COMMAND_TOKENS.has(base)) {
11304
11390
  return { cmd: head, args: tokens.slice(1) };
11305
11391
  }
@@ -11327,7 +11413,7 @@ function runTests(testFile, runner, customCommand, timeoutMs) {
11327
11413
  const fullArgs = [...cmdArgs, ...trailing];
11328
11414
  let stdout = "";
11329
11415
  try {
11330
- stdout = execFileSync(cmd, fullArgs, {
11416
+ stdout = execFileSync7(cmd, fullArgs, {
11331
11417
  encoding: "utf-8",
11332
11418
  timeout: timeoutMs,
11333
11419
  cwd: process.cwd(),
@@ -11622,6 +11708,201 @@ Fix the failing tests or revert the change if it broke something.`
11622
11708
  }
11623
11709
  };
11624
11710
  var test_runner_gate_default = plugin35;
11711
+
11712
+ // src/type-gate/index.ts
11713
+ import { execFileSync as execFileSync8 } from "node:child_process";
11714
+ import { existsSync as existsSync7 } from "node:fs";
11715
+ import { isAbsolute as isAbsolute17, relative as relative16, resolve as resolve16 } from "node:path";
11716
+
11717
+ // src/runtime/index.ts
11718
+ import { execFile as execFile4 } from "node:child_process";
11719
+ import { basename as basename3, isAbsolute as isAbsolute16, relative as relative15, resolve as resolve15 } from "node:path";
11720
+ var META_CHARS = /["'`;&|<>\r\n]/;
11721
+ var MAX_BUFFER_BYTES = 16 * 1024 * 1024;
11722
+ function hasLeadingDash(arg) {
11723
+ return arg.length > 0 && arg.startsWith("-");
11724
+ }
11725
+ function safeSplit(command) {
11726
+ const trimmed = command.trim();
11727
+ if (!trimmed || META_CHARS.test(trimmed)) return null;
11728
+ return trimmed.split(/\s+/).filter(Boolean);
11729
+ }
11730
+ function withinProjectPath(projectRoot, candidate) {
11731
+ if (candidate.length === 0 || candidate.length > 4096) return false;
11732
+ if (hasLeadingDash(candidate)) return false;
11733
+ const resolved = isAbsolute16(candidate) ? resolve15(candidate) : resolve15(projectRoot, candidate);
11734
+ const rel = relative15(projectRoot, resolved);
11735
+ return rel === "" || !rel.startsWith("..") && !isAbsolute16(rel);
11736
+ }
11737
+ function everyFlagAllowed(allowed, args) {
11738
+ for (const arg of args) {
11739
+ if (!hasLeadingDash(arg)) continue;
11740
+ if (allowed === null) return false;
11741
+ if (!allowed.has(arg)) return false;
11742
+ }
11743
+ return true;
11744
+ }
11745
+ function sanitizeRunnerPath(value, options = {}) {
11746
+ if (!value || hasLeadingDash(value)) return null;
11747
+ const projectRoot = resolve15(options.projectRoot ?? process.cwd());
11748
+ if (!withinProjectPath(projectRoot, value)) return null;
11749
+ return isAbsolute16(value) ? resolve15(value) : resolve15(projectRoot, value);
11750
+ }
11751
+ function resolveRunnerCommand(runtime, command, options = {}) {
11752
+ const tokens = safeSplit(command);
11753
+ if (!tokens || tokens.length === 0) return null;
11754
+ const projectRoot = resolve15(options.projectRoot ?? process.cwd());
11755
+ const launcher = runtime.packageManager;
11756
+ const [head, second, ...rest] = tokens;
11757
+ if (!head) return null;
11758
+ const display = tokens.join(" ");
11759
+ if (launcher !== "none" && tokens.length === 1 && head === launcher) {
11760
+ return null;
11761
+ }
11762
+ if (head === runtime.executable) {
11763
+ if (!everyFlagAllowed(runtime.allowedFlags, [second, ...rest].filter((v) => Boolean(v)))) {
11764
+ return null;
11765
+ }
11766
+ return {
11767
+ cmd: head,
11768
+ args: [second, ...rest].filter((v) => Boolean(v)),
11769
+ display
11770
+ };
11771
+ }
11772
+ if (launcher !== "none" && head === launcher && runtime.subcommands.length === 0 && second === runtime.executable) {
11773
+ if (!everyFlagAllowed(runtime.allowedFlags, rest)) return null;
11774
+ return { cmd: head, args: [second, ...rest], display };
11775
+ }
11776
+ if (launcher !== "none" && head === launcher && runtime.subcommands.length > 0) {
11777
+ const subcommand = runtime.subcommands[0];
11778
+ const exe = rest[0];
11779
+ if (second === subcommand && exe === runtime.executable) {
11780
+ const tail = rest.slice(1);
11781
+ if (!everyFlagAllowed(runtime.allowedFlags, tail)) return null;
11782
+ return { cmd: head, args: [second, exe, ...tail], display };
11783
+ }
11784
+ }
11785
+ if (isAbsolute16(head)) {
11786
+ if (!withinProjectPath(projectRoot, head)) return null;
11787
+ const base = basename3(head);
11788
+ if (base !== runtime.executable && base !== launcher) return null;
11789
+ if (second !== runtime.executable) return null;
11790
+ if (!everyFlagAllowed(runtime.allowedFlags, rest)) return null;
11791
+ return { cmd: head, args: [second, ...rest], display };
11792
+ }
11793
+ return null;
11794
+ }
11795
+ function runRunnerCommand(argv, options) {
11796
+ if (argv.length === 0) {
11797
+ return Promise.resolve({
11798
+ code: null,
11799
+ stdout: "",
11800
+ stderr: "runtime helper: empty argv",
11801
+ timedOut: false,
11802
+ spawnError: true
11803
+ });
11804
+ }
11805
+ return new Promise((resolvePromise) => {
11806
+ const projectRoot = resolve15(options.projectRoot ?? process.cwd());
11807
+ const trimmedCwd = options.cwd.trim();
11808
+ if (!withinProjectPath(projectRoot, trimmedCwd)) {
11809
+ resolvePromise({
11810
+ code: null,
11811
+ stdout: "",
11812
+ stderr: "runtime helper: cwd outside project",
11813
+ timedOut: false,
11814
+ spawnError: true
11815
+ });
11816
+ return;
11817
+ }
11818
+ let timedOut = false;
11819
+ let spawnErrored = false;
11820
+ const stdoutChunks = [];
11821
+ const stderrChunks = [];
11822
+ let stdoutBytes = 0;
11823
+ let stderrBytes = 0;
11824
+ const child = execFile4(
11825
+ argv[0],
11826
+ argv.slice(1),
11827
+ {
11828
+ cwd: trimmedCwd,
11829
+ timeout: options.timeoutMs,
11830
+ signal: options.signal,
11831
+ maxBuffer: MAX_BUFFER_BYTES,
11832
+ windowsHide: true,
11833
+ shell: false
11834
+ },
11835
+ (err, stdout, stderr) => {
11836
+ if (timedOut) {
11837
+ resolvePromise({
11838
+ code: null,
11839
+ stdout: Buffer.concat([...stdoutChunks, ...Buffer.isBuffer(stdout) ? [stdout] : [Buffer.from(stdout)]]).toString("utf8"),
11840
+ stderr: Buffer.concat([...stderrChunks, ...Buffer.isBuffer(stderr) ? [stderr] : [Buffer.from(stderr)]]).toString("utf8"),
11841
+ timedOut: true,
11842
+ spawnError: false
11843
+ });
11844
+ return;
11845
+ }
11846
+ if (spawnErrored) {
11847
+ resolvePromise({
11848
+ code: 127,
11849
+ stdout: Buffer.concat([...stdoutChunks, ...Buffer.isBuffer(stdout) ? [stdout] : [Buffer.from(stdout)]]).toString("utf8"),
11850
+ stderr: Buffer.concat([...stderrChunks, ...Buffer.isBuffer(stderr) ? [stderr] : [Buffer.from(stderr)]]).toString("utf8"),
11851
+ timedOut: false,
11852
+ spawnError: true
11853
+ });
11854
+ return;
11855
+ }
11856
+ if (err) {
11857
+ const anyErr = err;
11858
+ const code = typeof anyErr.code === "number" ? anyErr.code : 1;
11859
+ resolvePromise({
11860
+ code,
11861
+ stdout: Buffer.concat([
11862
+ ...stdoutChunks,
11863
+ ...anyErr.stdout ? [Buffer.isBuffer(anyErr.stdout) ? anyErr.stdout : Buffer.from(anyErr.stdout)] : []
11864
+ ]).toString("utf8"),
11865
+ stderr: Buffer.concat([
11866
+ ...stderrChunks,
11867
+ ...anyErr.stderr ? [Buffer.isBuffer(anyErr.stderr) ? anyErr.stderr : Buffer.from(anyErr.stderr)] : []
11868
+ ]).toString("utf8"),
11869
+ timedOut: false,
11870
+ spawnError: false
11871
+ });
11872
+ return;
11873
+ }
11874
+ resolvePromise({
11875
+ code: 0,
11876
+ stdout: Buffer.concat([
11877
+ ...stdoutChunks,
11878
+ ...Buffer.isBuffer(stdout) ? [stdout] : [Buffer.from(stdout)]
11879
+ ]).toString("utf8"),
11880
+ stderr: Buffer.concat([
11881
+ ...stderrChunks,
11882
+ ...Buffer.isBuffer(stderr) ? [stderr] : [Buffer.from(stderr)]
11883
+ ]).toString("utf8"),
11884
+ timedOut: false,
11885
+ spawnError: false
11886
+ });
11887
+ }
11888
+ );
11889
+ child.stdout?.on("data", (chunk) => {
11890
+ stdoutBytes += chunk.length;
11891
+ if (stdoutBytes <= MAX_BUFFER_BYTES) stdoutChunks.push(chunk);
11892
+ });
11893
+ child.stderr?.on("data", (chunk) => {
11894
+ stderrBytes += chunk.length;
11895
+ if (stderrBytes <= MAX_BUFFER_BYTES) stderrChunks.push(chunk);
11896
+ });
11897
+ child.on("error", (err) => {
11898
+ if (err.code === "ENOENT" || err.code === "EPERM" || err.code === "EACCES") {
11899
+ spawnErrored = true;
11900
+ }
11901
+ });
11902
+ });
11903
+ }
11904
+
11905
+ // src/type-gate/index.ts
11625
11906
  var API_VERSION19 = "^0.1.10";
11626
11907
  var state33 = {
11627
11908
  invocationCount: 0,
@@ -11658,63 +11939,59 @@ function readConfig29(raw) {
11658
11939
  function withinProject8(p) {
11659
11940
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
11660
11941
  const root = process.cwd();
11661
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
11662
- const rel = relative(root, resolved);
11942
+ const resolved = isAbsolute17(p) ? resolve16(p) : resolve16(root, p);
11943
+ const rel = relative16(root, resolved);
11663
11944
  if (rel === "" || rel === ".") return true;
11664
11945
  if (rel.startsWith("..")) return false;
11665
- if (isAbsolute(rel)) return false;
11946
+ if (isAbsolute17(rel)) return false;
11666
11947
  return true;
11667
11948
  }
11668
- var ALLOWED_COMMAND_TOKENS2 = /* @__PURE__ */ new Set([
11669
- "npx",
11670
- "pnpm",
11671
- "npm",
11672
- "yarn",
11673
- "bun",
11674
- "tsc",
11675
- "node",
11676
- "tsx"
11677
- ]);
11678
- function resolveAllowedCommand3(customCommand) {
11679
- const tokens = customCommand.split(/\s+/).filter(Boolean);
11680
- if (tokens.length === 0) return null;
11681
- const head = tokens[0];
11682
- if (ALLOWED_COMMAND_TOKENS2.has(head)) {
11683
- return { cmd: head, args: tokens.slice(1) };
11684
- }
11685
- if (isAbsolute(head)) {
11686
- if (!withinProject8(head)) return null;
11687
- const base = head.split(/[/\\]/).pop() ?? "";
11688
- if (ALLOWED_COMMAND_TOKENS2.has(base)) {
11689
- return { cmd: head, args: tokens.slice(1) };
11690
- }
11691
- }
11692
- return null;
11949
+ var TSC_RUNTIME = {
11950
+ id: "typescript",
11951
+ packageManager: "pnpm",
11952
+ executable: "tsc",
11953
+ allowedFlags: /* @__PURE__ */ new Set([
11954
+ "--noEmit",
11955
+ "--pretty",
11956
+ "--pretty=false",
11957
+ "--incremental",
11958
+ "--watch",
11959
+ "--build",
11960
+ "--filter"
11961
+ ]),
11962
+ subcommands: ["exec"],
11963
+ defaultCommand: "pnpm exec tsc --noEmit"
11964
+ };
11965
+ function validateTsConfigPath(p) {
11966
+ const sanitized = sanitizeRunnerPath(p);
11967
+ return sanitized;
11693
11968
  }
11694
11969
  function runTypeCheck(cfg) {
11695
11970
  const start = Date.now();
11696
- const tsConfig = cfg.tsConfigPath;
11697
- let cmd;
11698
- let args;
11971
+ const rawTsConfig = cfg.tsConfigPath;
11972
+ const validTsConfig = rawTsConfig && rawTsConfig !== "tsconfig.json" ? validateTsConfigPath(rawTsConfig) : null;
11973
+ if (rawTsConfig && rawTsConfig !== "tsconfig.json" && !validTsConfig) {
11974
+ return null;
11975
+ }
11976
+ const tsConfig = validTsConfig ?? (rawTsConfig || "tsconfig.json");
11977
+ let argv;
11699
11978
  if (cfg.command) {
11700
- const resolved = resolveAllowedCommand3(cfg.command);
11979
+ const resolved = resolveRunnerCommand(TSC_RUNTIME, cfg.command);
11701
11980
  if (!resolved) return null;
11702
- cmd = resolved.cmd;
11703
- args = resolved.args;
11981
+ argv = [resolved.cmd, ...resolved.args];
11704
11982
  } else {
11705
- cmd = "npx";
11706
- args = ["tsc", "--noEmit"];
11983
+ argv = ["npx", "tsc", "--noEmit"];
11707
11984
  if (tsConfig && tsConfig !== "tsconfig.json") {
11708
- args.push("-p", tsConfig);
11985
+ argv = [...argv, "-p", tsConfig];
11709
11986
  }
11710
11987
  }
11711
- if (!cfg.command && tsConfig && !existsSync(tsConfig)) {
11988
+ if (!cfg.command && tsConfig && !existsSync7(tsConfig)) {
11712
11989
  return null;
11713
11990
  }
11714
11991
  let stdout = "";
11715
11992
  let stderr = "";
11716
11993
  try {
11717
- const out = execFileSync(cmd, args, {
11994
+ const out = execFileSync8(argv[0], argv.slice(1), {
11718
11995
  encoding: "utf-8",
11719
11996
  timeout: cfg.timeoutMs,
11720
11997
  cwd: process.cwd(),
@@ -11728,6 +12005,7 @@ function runTypeCheck(cfg) {
11728
12005
  stdout = e.stdout ?? "";
11729
12006
  stderr = e.stderr ?? "";
11730
12007
  }
12008
+ void runRunnerCommand;
11731
12009
  const combined = `${stdout}
11732
12010
  ${stderr}`.trim();
11733
12011
  const durationMs = Date.now() - start;
@@ -11745,6 +12023,12 @@ ${stderr}`.trim();
11745
12023
  var plugin36 = {
11746
12024
  name: "type-gate",
11747
12025
  version: "0.1.0",
12026
+ runtime: {
12027
+ language: "typescript",
12028
+ packageManager: "pnpm",
12029
+ executable: "tsc",
12030
+ defaultCommand: "pnpm exec tsc --noEmit"
12031
+ },
11748
12032
  description: "PostToolUse hook that runs TypeScript type-checking after every write or edit to a source file",
11749
12033
  apiVersion: API_VERSION19,
11750
12034
  capabilities: { tools: true, hooks: true },
@@ -12141,6 +12425,10 @@ var plugin37 = {
12141
12425
  }
12142
12426
  };
12143
12427
  var todo_listener_default = plugin37;
12428
+
12429
+ // src/todo-tracker/index.ts
12430
+ import * as fsp from "node:fs/promises";
12431
+ import { randomUUID } from "node:crypto";
12144
12432
  function deriveFilePath(api) {
12145
12433
  const raw = api.config.extensions?.["todo-tracker"];
12146
12434
  const explicit = typeof raw?.["filePath"] === "string" ? raw["filePath"] : null;
@@ -12892,7 +13180,7 @@ function estimateRequestTokens(request, charsPerToken) {
12892
13180
  walk(request["messages"]);
12893
13181
  return Math.ceil(chars / charsPerToken);
12894
13182
  }
12895
- var sleep = (ms) => new Promise((resolve34) => setTimeout(resolve34, ms));
13183
+ var sleep = (ms) => new Promise((resolve36) => setTimeout(resolve36, ms));
12896
13184
  var plugin40 = {
12897
13185
  name: "token-throttle",
12898
13186
  version: "0.1.0",
@@ -13036,6 +13324,10 @@ var plugin40 = {
13036
13324
  }
13037
13325
  };
13038
13326
  var token_throttle_default = plugin40;
13327
+
13328
+ // src/accessibility-auditor/index.ts
13329
+ import { existsSync as existsSync8, readFileSync as readFileSync8, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
13330
+ import { isAbsolute as isAbsolute18, relative as relative17, resolve as resolve17 } from "node:path";
13039
13331
  var API_VERSION21 = "^0.1.10";
13040
13332
  var state38 = {
13041
13333
  auditCount: 0,
@@ -13066,11 +13358,11 @@ function readConfig33(raw) {
13066
13358
  function withinProject9(p) {
13067
13359
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
13068
13360
  const root = process.cwd();
13069
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
13070
- const rel = relative(root, resolved);
13361
+ const resolved = isAbsolute18(p) ? resolve17(p) : resolve17(root, p);
13362
+ const rel = relative17(root, resolved);
13071
13363
  if (rel === "" || rel === ".") return true;
13072
13364
  if (rel.startsWith("..")) return false;
13073
- if (isAbsolute(rel)) return false;
13365
+ if (isAbsolute18(rel)) return false;
13074
13366
  return true;
13075
13367
  }
13076
13368
  function normalizeExtensions(exts) {
@@ -13083,8 +13375,8 @@ function matchesExtension(p, exts) {
13083
13375
  }
13084
13376
  function collectUiFiles(root, exts) {
13085
13377
  const files = [];
13086
- if (!existsSync(root)) return files;
13087
- const s = statSync(root);
13378
+ if (!existsSync8(root)) return files;
13379
+ const s = statSync5(root);
13088
13380
  if (s.isFile()) {
13089
13381
  if (matchesExtension(root, exts)) files.push(root);
13090
13382
  return files;
@@ -13093,15 +13385,15 @@ function collectUiFiles(root, exts) {
13093
13385
  function walk(dir) {
13094
13386
  let entries;
13095
13387
  try {
13096
- entries = readdirSync(dir);
13388
+ entries = readdirSync3(dir);
13097
13389
  } catch {
13098
13390
  return;
13099
13391
  }
13100
13392
  for (const entry of entries) {
13101
- const full = resolve(dir, entry);
13393
+ const full = resolve17(dir, entry);
13102
13394
  let st;
13103
13395
  try {
13104
- st = statSync(full);
13396
+ st = statSync5(full);
13105
13397
  } catch {
13106
13398
  continue;
13107
13399
  }
@@ -13135,7 +13427,7 @@ function hasMeaningfulAlt(tag) {
13135
13427
  function auditFile(filePath, projectRoot) {
13136
13428
  let content;
13137
13429
  try {
13138
- content = readFileSync(filePath, "utf-8");
13430
+ content = readFileSync8(filePath, "utf-8");
13139
13431
  } catch {
13140
13432
  return [];
13141
13433
  }
@@ -13144,7 +13436,7 @@ function auditFile(filePath, projectRoot) {
13144
13436
  const idsByValue = /* @__PURE__ */ new Map();
13145
13437
  function add(line, rule, severity, message) {
13146
13438
  findings.push({
13147
- file: relative(projectRoot, filePath),
13439
+ file: relative17(projectRoot, filePath),
13148
13440
  line,
13149
13441
  rule,
13150
13442
  severity,
@@ -13228,7 +13520,7 @@ function auditFile(filePath, projectRoot) {
13228
13520
  }
13229
13521
  function auditPath(rawPath, cfg) {
13230
13522
  const root = process.cwd();
13231
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
13523
+ const resolved = isAbsolute18(rawPath) ? resolve17(rawPath) : resolve17(root, rawPath);
13232
13524
  const exts = normalizeExtensions(cfg.includeExtensions);
13233
13525
  const files = collectUiFiles(resolved, exts);
13234
13526
  const findings = [];
@@ -13238,7 +13530,7 @@ function auditPath(rawPath, cfg) {
13238
13530
  if (findings.length >= cfg.maxFindings) break;
13239
13531
  }
13240
13532
  return {
13241
- path: relative(root, resolved),
13533
+ path: relative17(root, resolved),
13242
13534
  findings: findings.slice(0, cfg.maxFindings),
13243
13535
  fileCount: files.length
13244
13536
  };
@@ -13441,6 +13733,11 @@ var plugin41 = {
13441
13733
  }
13442
13734
  };
13443
13735
  var accessibility_auditor_default = plugin41;
13736
+
13737
+ // src/api-compatibility-gate/index.ts
13738
+ import { execFileSync as execFileSync9 } from "node:child_process";
13739
+ import { existsSync as existsSync9, readFileSync as readFileSync9 } from "node:fs";
13740
+ import { basename as basename4, dirname as dirname6, extname, isAbsolute as isAbsolute19, relative as relative18, resolve as resolve18 } from "node:path";
13444
13741
  var API_VERSION22 = "^0.1.10";
13445
13742
  var state39 = {
13446
13743
  invocationCount: 0,
@@ -13504,25 +13801,25 @@ function matchesAnyPattern(filePath, patterns) {
13504
13801
  return patterns.some((p) => patternToRegex(p).test(normalized));
13505
13802
  }
13506
13803
  function resolveToProjectRoot(filePath) {
13507
- if (isAbsolute(filePath)) return resolve(filePath);
13508
- return resolve(process.cwd(), filePath);
13804
+ if (isAbsolute19(filePath)) return resolve18(filePath);
13805
+ return resolve18(process.cwd(), filePath);
13509
13806
  }
13510
13807
  function withinProject10(filePath) {
13511
13808
  if (typeof filePath !== "string" || filePath.length === 0 || filePath.length > 4096) return false;
13512
13809
  const resolved = resolveToProjectRoot(filePath);
13513
- const rel = relative(process.cwd(), resolved);
13810
+ const rel = relative18(process.cwd(), resolved);
13514
13811
  if (rel === "" || rel === ".") return true;
13515
13812
  if (rel.startsWith("..")) return false;
13516
- if (isAbsolute(rel)) return false;
13813
+ if (isAbsolute19(rel)) return false;
13517
13814
  return true;
13518
13815
  }
13519
13816
  function isPackageEntryPoint(filePath) {
13520
13817
  const resolved = resolveToProjectRoot(filePath);
13521
- const dir = dirname(resolved);
13522
- const pkgPath = resolve(dir, "package.json");
13523
- if (!existsSync(pkgPath)) return false;
13818
+ const dir = dirname6(resolved);
13819
+ const pkgPath = resolve18(dir, "package.json");
13820
+ if (!existsSync9(pkgPath)) return false;
13524
13821
  try {
13525
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
13822
+ const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
13526
13823
  const entries = [];
13527
13824
  if (pkg.main) entries.push(pkg.main);
13528
13825
  if (pkg.module) entries.push(pkg.module);
@@ -13540,9 +13837,9 @@ function isPackageEntryPoint(filePath) {
13540
13837
  }
13541
13838
  }
13542
13839
  for (const entry of entries) {
13543
- const entryResolved = resolve(dir, entry);
13840
+ const entryResolved = resolve18(dir, entry);
13544
13841
  if (entryResolved === resolved) return true;
13545
- if (basename(dirname(entryResolved)) === basename(dirname(resolved)) && basename(entryResolved, extname(entryResolved)) === basename(resolved, extname(resolved))) {
13842
+ if (basename4(dirname6(entryResolved)) === basename4(dirname6(resolved)) && basename4(entryResolved, extname(entryResolved)) === basename4(resolved, extname(resolved))) {
13546
13843
  return true;
13547
13844
  }
13548
13845
  }
@@ -13593,9 +13890,9 @@ function extractExports(source) {
13593
13890
  }
13594
13891
  function readGitVersion(filePath) {
13595
13892
  const resolved = resolveToProjectRoot(filePath);
13596
- const relPath = normalizePath2(relative(process.cwd(), resolved));
13893
+ const relPath = normalizePath2(relative18(process.cwd(), resolved));
13597
13894
  try {
13598
- const out = execFileSync("git", ["show", `HEAD:${relPath}`], {
13895
+ const out = execFileSync9("git", ["show", `HEAD:${relPath}`], {
13599
13896
  encoding: "utf-8",
13600
13897
  cwd: process.cwd(),
13601
13898
  stdio: ["pipe", "pipe", "pipe"]
@@ -13608,7 +13905,7 @@ function readGitVersion(filePath) {
13608
13905
  function readCurrentFile(filePath) {
13609
13906
  try {
13610
13907
  const resolved = resolveToProjectRoot(filePath);
13611
- return readFileSync(resolved, "utf-8");
13908
+ return readFileSync9(resolved, "utf-8");
13612
13909
  } catch {
13613
13910
  return null;
13614
13911
  }
@@ -13791,6 +14088,10 @@ var plugin42 = {
13791
14088
  }
13792
14089
  };
13793
14090
  var api_compatibility_gate_default = plugin42;
14091
+
14092
+ // src/auto-i18n-extractor/index.ts
14093
+ import { readFileSync as readFileSync10 } from "node:fs";
14094
+ import { isAbsolute as isAbsolute20, relative as relative19, resolve as resolve19 } from "node:path";
13794
14095
  var API_VERSION23 = "^0.1.10";
13795
14096
  var state40 = {
13796
14097
  filesScanned: 0,
@@ -13834,11 +14135,11 @@ function readConfig35(raw) {
13834
14135
  function withinProject11(p) {
13835
14136
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
13836
14137
  const root = process.cwd();
13837
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
13838
- const rel = relative(root, resolved);
14138
+ const resolved = isAbsolute20(p) ? resolve19(p) : resolve19(root, p);
14139
+ const rel = relative19(root, resolved);
13839
14140
  if (rel === "" || rel === ".") return true;
13840
14141
  if (rel.startsWith("..")) return false;
13841
- if (isAbsolute(rel)) return false;
14142
+ if (isAbsolute20(rel)) return false;
13842
14143
  return true;
13843
14144
  }
13844
14145
  function fileExtension(p) {
@@ -13886,7 +14187,7 @@ function extractStrings(content, cfg) {
13886
14187
  }
13887
14188
  function readSourceFile(filePath) {
13888
14189
  try {
13889
- return readFileSync(filePath, "utf-8");
14190
+ return readFileSync10(filePath, "utf-8");
13890
14191
  } catch {
13891
14192
  return null;
13892
14193
  }
@@ -14120,6 +14421,10 @@ ${lines.join("\n")}${more}`;
14120
14421
  }
14121
14422
  };
14122
14423
  var auto_i18n_extractor_default = plugin43;
14424
+
14425
+ // src/code-metrics/index.ts
14426
+ import { existsSync as existsSync10, readFileSync as readFileSync11, readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
14427
+ import { extname as extname2, isAbsolute as isAbsolute21, relative as relative20, resolve as resolve20 } from "node:path";
14123
14428
  var API_VERSION24 = "^0.1.10";
14124
14429
  var state41 = {
14125
14430
  measureCount: 0,
@@ -14145,23 +14450,23 @@ function readConfig36(raw) {
14145
14450
  function withinProject12(p) {
14146
14451
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
14147
14452
  const root = process.cwd();
14148
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
14149
- const rel = relative(root, resolved);
14453
+ const resolved = isAbsolute21(p) ? resolve20(p) : resolve20(root, p);
14454
+ const rel = relative20(root, resolved);
14150
14455
  if (rel === "" || rel === ".") return true;
14151
14456
  if (rel.startsWith("..")) return false;
14152
- if (isAbsolute(rel)) return false;
14457
+ if (isAbsolute21(rel)) return false;
14153
14458
  return true;
14154
14459
  }
14155
14460
  function normalizeExtensions2(exts) {
14156
14461
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
14157
14462
  }
14158
14463
  function matchesExtension2(p, exts) {
14159
- return exts.includes(extname(p).toLowerCase());
14464
+ return exts.includes(extname2(p).toLowerCase());
14160
14465
  }
14161
14466
  function collectSourceFiles(root, exts) {
14162
14467
  const files = [];
14163
- if (!existsSync(root)) return files;
14164
- const s = statSync(root);
14468
+ if (!existsSync10(root)) return files;
14469
+ const s = statSync6(root);
14165
14470
  if (s.isFile()) {
14166
14471
  if (matchesExtension2(root, exts)) files.push(root);
14167
14472
  return files;
@@ -14170,16 +14475,16 @@ function collectSourceFiles(root, exts) {
14170
14475
  function walk(dir) {
14171
14476
  let entries;
14172
14477
  try {
14173
- entries = readdirSync(dir);
14478
+ entries = readdirSync4(dir);
14174
14479
  } catch {
14175
14480
  return;
14176
14481
  }
14177
14482
  for (const entry of entries) {
14178
14483
  if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
14179
- const full = resolve(dir, entry);
14484
+ const full = resolve20(dir, entry);
14180
14485
  let st;
14181
14486
  try {
14182
- st = statSync(full);
14487
+ st = statSync6(full);
14183
14488
  } catch {
14184
14489
  continue;
14185
14490
  }
@@ -14197,7 +14502,7 @@ function toPosix(p) {
14197
14502
  return p.replace(/\\/g, "/");
14198
14503
  }
14199
14504
  function relativePath(p) {
14200
- return toPosix(relative(process.cwd(), p));
14505
+ return toPosix(relative20(process.cwd(), p));
14201
14506
  }
14202
14507
  function countFunctions(content) {
14203
14508
  let count = 0;
@@ -14276,14 +14581,14 @@ function analyzeFile(filePath, content) {
14276
14581
  }
14277
14582
  function measurePath(rawPath, cfg) {
14278
14583
  const root = process.cwd();
14279
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
14584
+ const resolved = isAbsolute21(rawPath) ? resolve20(rawPath) : resolve20(root, rawPath);
14280
14585
  const exts = normalizeExtensions2(cfg.extensions);
14281
14586
  const allFiles = collectSourceFiles(resolved, exts);
14282
14587
  const files = allFiles.slice(0, cfg.maxFiles);
14283
14588
  const metrics = [];
14284
14589
  for (const p of files) {
14285
14590
  try {
14286
- const content = readFileSync(p, "utf-8");
14591
+ const content = readFileSync11(p, "utf-8");
14287
14592
  metrics.push(analyzeFile(p, content));
14288
14593
  } catch {
14289
14594
  }
@@ -14339,10 +14644,10 @@ var plugin44 = {
14339
14644
  const exts = normalizeExtensions2(cfg.extensions);
14340
14645
  if (!matchesExtension2(sourcePath, exts)) return;
14341
14646
  state41.hookInvocationCount += 1;
14342
- const resolved = resolve(process.cwd(), sourcePath);
14647
+ const resolved = resolve20(process.cwd(), sourcePath);
14343
14648
  let content;
14344
14649
  try {
14345
- content = readFileSync(resolved, "utf-8");
14650
+ content = readFileSync11(resolved, "utf-8");
14346
14651
  } catch {
14347
14652
  state41.errorCount += 1;
14348
14653
  return;
@@ -14383,7 +14688,7 @@ var plugin44 = {
14383
14688
  state41.fileCount += result.files.length;
14384
14689
  return {
14385
14690
  ok: true,
14386
- path: relativePath(resolve(process.cwd(), rawPath)),
14691
+ path: relativePath(resolve20(process.cwd(), rawPath)),
14387
14692
  files: result.files,
14388
14693
  totalFiles: result.totalFiles,
14389
14694
  capped: result.totalFiles > cfg.maxFiles
@@ -14452,6 +14757,10 @@ var plugin44 = {
14452
14757
  }
14453
14758
  };
14454
14759
  var code_metrics_default = plugin44;
14760
+
14761
+ // src/dead-code-detector/index.ts
14762
+ import { readdirSync as readdirSync5, readFileSync as readFileSync12, statSync as statSync7 } from "node:fs";
14763
+ import { extname as extname3, isAbsolute as isAbsolute22, join as join5, relative as relative21, resolve as resolve21 } from "node:path";
14455
14764
  var API_VERSION25 = "^0.1.10";
14456
14765
  var state42 = {
14457
14766
  scanCount: 0,
@@ -14485,24 +14794,24 @@ function gatherFiles(root, depth, cfg) {
14485
14794
  function walk(dir, remaining) {
14486
14795
  let entries;
14487
14796
  try {
14488
- entries = readdirSync(dir, { withFileTypes: true });
14797
+ entries = readdirSync5(dir, { withFileTypes: true });
14489
14798
  } catch {
14490
14799
  return;
14491
14800
  }
14492
14801
  for (const entry of entries) {
14493
14802
  if (entry.isDirectory()) {
14494
14803
  if (remaining > 0 && !cfg.excludeDirs.includes(entry.name)) {
14495
- walk(join(dir, entry.name), remaining - 1);
14804
+ walk(join5(dir, entry.name), remaining - 1);
14496
14805
  }
14497
14806
  } else if (entry.isFile()) {
14498
- const ext = extname(entry.name).toLowerCase();
14807
+ const ext = extname3(entry.name).toLowerCase();
14499
14808
  if (cfg.extensions.includes(ext)) {
14500
- files.push(join(dir, entry.name));
14809
+ files.push(join5(dir, entry.name));
14501
14810
  }
14502
14811
  }
14503
14812
  }
14504
14813
  }
14505
- walk(resolve(root), depth);
14814
+ walk(resolve21(root), depth);
14506
14815
  return files;
14507
14816
  }
14508
14817
  function stripNoise(content) {
@@ -14579,7 +14888,7 @@ function scan(root, depth, cfg) {
14579
14888
  const files = [];
14580
14889
  for (const p of filePaths) {
14581
14890
  try {
14582
- const content = readFileSync(p, "utf-8");
14891
+ const content = readFileSync12(p, "utf-8");
14583
14892
  files.push({ path: p, content, stripped: stripNoise(content) });
14584
14893
  } catch {
14585
14894
  }
@@ -14589,19 +14898,19 @@ function scan(root, depth, cfg) {
14589
14898
  function withinProject13(p) {
14590
14899
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
14591
14900
  const root = process.cwd();
14592
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
14593
- const rel = relative(root, resolved);
14901
+ const resolved = isAbsolute22(p) ? resolve21(p) : resolve21(root, p);
14902
+ const rel = relative21(root, resolved);
14594
14903
  if (rel === "" || rel === ".") return true;
14595
14904
  if (rel.startsWith("..")) return false;
14596
- if (isAbsolute(rel)) return false;
14905
+ if (isAbsolute22(rel)) return false;
14597
14906
  return true;
14598
14907
  }
14599
14908
  function resolveScanRoot(rawPath) {
14600
- const resolved = resolve(process.cwd(), rawPath);
14909
+ const resolved = resolve21(process.cwd(), rawPath);
14601
14910
  try {
14602
- const stats = statSync(resolved);
14911
+ const stats = statSync7(resolved);
14603
14912
  if (!stats.isDirectory()) {
14604
- return resolve(resolved, "..");
14913
+ return resolve21(resolved, "..");
14605
14914
  }
14606
14915
  } catch {
14607
14916
  }
@@ -14611,7 +14920,7 @@ function toPosix2(p) {
14611
14920
  return p.replace(/\\/g, "/");
14612
14921
  }
14613
14922
  function relativePath2(p) {
14614
- return toPosix2(relative(process.cwd(), p));
14923
+ return toPosix2(relative21(process.cwd(), p));
14615
14924
  }
14616
14925
  var plugin45 = {
14617
14926
  name: "dead-code-detector",
@@ -14682,8 +14991,8 @@ var plugin45 = {
14682
14991
  state42.errorCount += 1;
14683
14992
  return;
14684
14993
  }
14685
- const changedFile = resolve(process.cwd(), sourcePath);
14686
- const relevant = result.findings.filter((f) => resolve(f.file) === changedFile);
14994
+ const changedFile = resolve21(process.cwd(), sourcePath);
14995
+ const relevant = result.findings.filter((f) => resolve21(f.file) === changedFile);
14687
14996
  if (relevant.length === 0) {
14688
14997
  state42.missCount += 1;
14689
14998
  return;
@@ -14800,6 +15109,10 @@ Consider removing the export if it is not part of the public API.`;
14800
15109
  }
14801
15110
  };
14802
15111
  var dead_code_detector_default = plugin45;
15112
+
15113
+ // src/dependency-vulnerability-gate/index.ts
15114
+ import { execFileSync as execFileSync10 } from "node:child_process";
15115
+ import { existsSync as existsSync11 } from "node:fs";
14803
15116
  var API_VERSION26 = "^0.1.10";
14804
15117
  var state43 = {
14805
15118
  invocations: 0,
@@ -14912,14 +15225,14 @@ function isInstallCommand(input) {
14912
15225
  return INSTALL_RE2.test(command);
14913
15226
  }
14914
15227
  function detectManager() {
14915
- return existsSync("pnpm-lock.yaml") ? "pnpm" : "npm";
15228
+ return existsSync11("pnpm-lock.yaml") ? "pnpm" : "npm";
14916
15229
  }
14917
15230
  function runAudit(cfg) {
14918
15231
  const manager = detectManager();
14919
15232
  const start = Date.now();
14920
15233
  let stdout = "";
14921
15234
  try {
14922
- stdout = execFileSync(manager, ["audit", "--json"], {
15235
+ stdout = execFileSync10(manager, ["audit", "--json"], {
14923
15236
  encoding: "utf-8",
14924
15237
  timeout: cfg.timeoutMs,
14925
15238
  cwd: process.cwd(),
@@ -15102,6 +15415,9 @@ Review the audit output or adjust the dependency choice.`;
15102
15415
  }
15103
15416
  };
15104
15417
  var dependency_vulnerability_gate_default = plugin46;
15418
+
15419
+ // src/doc-sync-guard/index.ts
15420
+ import { isAbsolute as isAbsolute23, relative as relative22, resolve as resolve22, basename as basename5, extname as extname4 } from "node:path";
15105
15421
  var API_VERSION27 = "^0.1.10";
15106
15422
  var state44 = {
15107
15423
  changedFiles: [],
@@ -15129,32 +15445,32 @@ function readConfig39(raw) {
15129
15445
  function withinProject14(p) {
15130
15446
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
15131
15447
  const root = process.cwd();
15132
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
15133
- const rel = relative(root, resolved);
15448
+ const resolved = isAbsolute23(p) ? resolve22(p) : resolve22(root, p);
15449
+ const rel = relative22(root, resolved);
15134
15450
  if (rel === "" || rel === ".") return true;
15135
15451
  if (rel.startsWith("..")) return false;
15136
- if (isAbsolute(rel)) return false;
15452
+ if (isAbsolute23(rel)) return false;
15137
15453
  return true;
15138
15454
  }
15139
15455
  function normalizeSlashes(p) {
15140
15456
  return p.replace(/\\/g, "/");
15141
15457
  }
15142
15458
  function isSourceFile(p, extensions) {
15143
- const ext = extname(p).toLowerCase();
15459
+ const ext = extname4(p).toLowerCase();
15144
15460
  return extensions.includes(ext);
15145
15461
  }
15146
15462
  function isPublicSource(p, extensions) {
15147
15463
  if (!isSourceFile(p, extensions)) return false;
15148
15464
  const norm = normalizeSlashes(p);
15149
15465
  if (norm.includes("/node_modules/") || norm.startsWith("node_modules/")) return false;
15150
- const base = basename(norm).toLowerCase();
15466
+ const base = basename5(norm).toLowerCase();
15151
15467
  if (/\.(test|spec)\./.test(base)) return false;
15152
15468
  if (base.startsWith("_")) return false;
15153
15469
  return true;
15154
15470
  }
15155
15471
  function isDocFile(p, docNames) {
15156
15472
  const norm = normalizeSlashes(p);
15157
- const base = basename(norm);
15473
+ const base = basename5(norm);
15158
15474
  const lowerBase = base.toLowerCase();
15159
15475
  if (docNames.some((name) => lowerBase === name.toLowerCase())) return true;
15160
15476
  if (norm.includes("/docs/") || norm.startsWith("docs/")) return true;
@@ -15172,7 +15488,7 @@ function extractDocContent(toolInput) {
15172
15488
  return void 0;
15173
15489
  }
15174
15490
  function referenceTokens(p) {
15175
- const base = basename(p);
15491
+ const base = basename5(p);
15176
15492
  const withoutExt = base.replace(/\.[^.]+$/, "");
15177
15493
  const tokens = [base];
15178
15494
  if (withoutExt && withoutExt !== base) tokens.push(withoutExt);
@@ -15320,6 +15636,10 @@ Consider mentioning these changes in the documentation.`;
15320
15636
  }
15321
15637
  };
15322
15638
  var doc_sync_guard_default = plugin47;
15639
+
15640
+ // src/duplicate-code-detector/index.ts
15641
+ import { existsSync as existsSync12, readFileSync as readFileSync13, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
15642
+ import { extname as extname5, isAbsolute as isAbsolute24, relative as relative23, resolve as resolve23 } from "node:path";
15323
15643
  var API_VERSION28 = "^0.1.10";
15324
15644
  var state45 = {
15325
15645
  scanCount: 0,
@@ -15353,21 +15673,21 @@ function readConfig40(raw) {
15353
15673
  function withinProject15(p) {
15354
15674
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
15355
15675
  const root = process.cwd();
15356
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
15357
- const rel = relative(root, resolved);
15676
+ const resolved = isAbsolute24(p) ? resolve23(p) : resolve23(root, p);
15677
+ const rel = relative23(root, resolved);
15358
15678
  if (rel === "" || rel === ".") return true;
15359
15679
  if (rel.startsWith("..")) return false;
15360
- if (isAbsolute(rel)) return false;
15680
+ if (isAbsolute24(rel)) return false;
15361
15681
  return true;
15362
15682
  }
15363
15683
  function matchesExtension3(p, exts) {
15364
- const ext = extname(p).toLowerCase();
15684
+ const ext = extname5(p).toLowerCase();
15365
15685
  return exts.includes(ext);
15366
15686
  }
15367
15687
  function collectSourceFiles2(root, cfg) {
15368
15688
  const files = [];
15369
- if (!existsSync(root)) return files;
15370
- const s = statSync(root);
15689
+ if (!existsSync12(root)) return files;
15690
+ const s = statSync8(root);
15371
15691
  if (s.isFile()) {
15372
15692
  if (matchesExtension3(root, cfg.extensions)) files.push(root);
15373
15693
  return files;
@@ -15376,15 +15696,15 @@ function collectSourceFiles2(root, cfg) {
15376
15696
  function walk(dir) {
15377
15697
  let entries;
15378
15698
  try {
15379
- entries = readdirSync(dir);
15699
+ entries = readdirSync6(dir);
15380
15700
  } catch {
15381
15701
  return;
15382
15702
  }
15383
15703
  for (const entry of entries) {
15384
- const full = resolve(dir, entry);
15704
+ const full = resolve23(dir, entry);
15385
15705
  let st;
15386
15706
  try {
15387
- st = statSync(full);
15707
+ st = statSync8(full);
15388
15708
  } catch {
15389
15709
  continue;
15390
15710
  }
@@ -15402,7 +15722,7 @@ function toPosix3(p) {
15402
15722
  return p.replace(/\\/g, "/");
15403
15723
  }
15404
15724
  function relativePath3(p) {
15405
- return toPosix3(relative(process.cwd(), p));
15725
+ return toPosix3(relative23(process.cwd(), p));
15406
15726
  }
15407
15727
  function removeInlineComments(line) {
15408
15728
  return line.replace(/\/\/.*$/, "").replace(/\/\*[\s\S]*?\*\//, "");
@@ -15460,12 +15780,12 @@ function findDuplicates(files, minLines, maxFindings) {
15460
15780
  }
15461
15781
  function scanPath(rawPath, cfg) {
15462
15782
  const root = process.cwd();
15463
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
15783
+ const resolved = isAbsolute24(rawPath) ? resolve23(rawPath) : resolve23(root, rawPath);
15464
15784
  const filePaths = collectSourceFiles2(resolved, cfg);
15465
15785
  const files = /* @__PURE__ */ new Map();
15466
15786
  for (const p of filePaths) {
15467
15787
  try {
15468
- files.set(p, readFileSync(p, "utf-8"));
15788
+ files.set(p, readFileSync13(p, "utf-8"));
15469
15789
  } catch {
15470
15790
  }
15471
15791
  }
@@ -15545,24 +15865,24 @@ var plugin48 = {
15545
15865
  const now = Date.now();
15546
15866
  const lastWarning = state45.lastHookWarning.get(sourcePath);
15547
15867
  if (lastWarning !== void 0 && now - lastWarning < 6e4) return;
15548
- const changedFile = resolve(process.cwd(), sourcePath);
15868
+ const changedFile = resolve23(process.cwd(), sourcePath);
15549
15869
  let content;
15550
15870
  try {
15551
- content = readFileSync(changedFile, "utf-8");
15871
+ content = readFileSync13(changedFile, "utf-8");
15552
15872
  } catch {
15553
15873
  state45.errorCount += 1;
15554
15874
  return;
15555
15875
  }
15556
15876
  const changedWindows = extractWindows(changedFile, content, cfg.minLines);
15557
15877
  if (changedWindows.length === 0) return;
15558
- const projectRoot = resolve(process.cwd());
15878
+ const projectRoot = resolve23(process.cwd());
15559
15879
  let otherFiles;
15560
15880
  try {
15561
15881
  const filePaths = collectSourceFiles2(projectRoot, cfg).filter((p) => p !== changedFile);
15562
15882
  otherFiles = /* @__PURE__ */ new Map();
15563
15883
  for (const p of filePaths) {
15564
15884
  try {
15565
- otherFiles.set(p, readFileSync(p, "utf-8"));
15885
+ otherFiles.set(p, readFileSync13(p, "utf-8"));
15566
15886
  } catch {
15567
15887
  }
15568
15888
  }
@@ -15621,7 +15941,7 @@ var plugin48 = {
15621
15941
  state45.findingCount += result.findings.length;
15622
15942
  return {
15623
15943
  ok: true,
15624
- path: relativePath3(resolve(process.cwd(), rawPath)),
15944
+ path: relativePath3(resolve23(process.cwd(), rawPath)),
15625
15945
  scannedFiles: result.scannedFiles,
15626
15946
  minLines: cfg.minLines,
15627
15947
  findings: result.findings
@@ -15698,6 +16018,10 @@ var plugin48 = {
15698
16018
  }
15699
16019
  };
15700
16020
  var duplicate_code_detector_default = plugin48;
16021
+
16022
+ // src/feature-flag-tracker/index.ts
16023
+ import { existsSync as existsSync13, readFileSync as readFileSync14, readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
16024
+ import { extname as extname6, isAbsolute as isAbsolute25, relative as relative24, resolve as resolve24 } from "node:path";
15701
16025
  var API_VERSION29 = "^0.1.10";
15702
16026
  var state46 = {
15703
16027
  scanCount: 0,
@@ -15732,23 +16056,23 @@ function readConfig41(raw) {
15732
16056
  function withinProject16(p) {
15733
16057
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
15734
16058
  const root = process.cwd();
15735
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
15736
- const rel = relative(root, resolved);
16059
+ const resolved = isAbsolute25(p) ? resolve24(p) : resolve24(root, p);
16060
+ const rel = relative24(root, resolved);
15737
16061
  if (rel === "" || rel === ".") return true;
15738
16062
  if (rel.startsWith("..")) return false;
15739
- if (isAbsolute(rel)) return false;
16063
+ if (isAbsolute25(rel)) return false;
15740
16064
  return true;
15741
16065
  }
15742
16066
  function normalizeExtensions3(exts) {
15743
16067
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
15744
16068
  }
15745
16069
  function matchesExtension4(p, exts) {
15746
- return exts.includes(extname(p).toLowerCase());
16070
+ return exts.includes(extname6(p).toLowerCase());
15747
16071
  }
15748
16072
  function collectSourceFiles3(root, exts) {
15749
16073
  const files = [];
15750
- if (!existsSync(root)) return files;
15751
- const s = statSync(root);
16074
+ if (!existsSync13(root)) return files;
16075
+ const s = statSync9(root);
15752
16076
  if (s.isFile()) {
15753
16077
  if (matchesExtension4(root, exts)) files.push(root);
15754
16078
  return files;
@@ -15757,16 +16081,16 @@ function collectSourceFiles3(root, exts) {
15757
16081
  function walk(dir) {
15758
16082
  let entries;
15759
16083
  try {
15760
- entries = readdirSync(dir);
16084
+ entries = readdirSync7(dir);
15761
16085
  } catch {
15762
16086
  return;
15763
16087
  }
15764
16088
  for (const entry of entries) {
15765
16089
  if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
15766
- const full = resolve(dir, entry);
16090
+ const full = resolve24(dir, entry);
15767
16091
  let st;
15768
16092
  try {
15769
- st = statSync(full);
16093
+ st = statSync9(full);
15770
16094
  } catch {
15771
16095
  continue;
15772
16096
  }
@@ -15784,7 +16108,7 @@ function toPosix4(p) {
15784
16108
  return p.replace(/\\/g, "/");
15785
16109
  }
15786
16110
  function relativePath4(p) {
15787
- return toPosix4(relative(process.cwd(), p));
16111
+ return toPosix4(relative24(process.cwd(), p));
15788
16112
  }
15789
16113
  function compilePatterns(patterns) {
15790
16114
  const sources = [...DEFAULT_PATTERNS2, ...patterns];
@@ -15815,14 +16139,14 @@ function scanFile(filePath, content, patterns, maxFindings) {
15815
16139
  }
15816
16140
  function scanPath2(rawPath, cfg) {
15817
16141
  const root = process.cwd();
15818
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
16142
+ const resolved = isAbsolute25(rawPath) ? resolve24(rawPath) : resolve24(root, rawPath);
15819
16143
  const exts = normalizeExtensions3(cfg.extensions);
15820
16144
  const files = collectSourceFiles3(resolved, exts);
15821
16145
  const patterns = compilePatterns(cfg.patterns);
15822
16146
  const usages = [];
15823
16147
  for (const p of files) {
15824
16148
  try {
15825
- const content = readFileSync(p, "utf-8");
16149
+ const content = readFileSync14(p, "utf-8");
15826
16150
  usages.push(...scanFile(p, content, patterns, cfg.maxFindings));
15827
16151
  if (usages.length >= cfg.maxFindings) break;
15828
16152
  } catch {
@@ -15886,10 +16210,10 @@ var plugin49 = {
15886
16210
  const exts = normalizeExtensions3(cfg.extensions);
15887
16211
  if (!matchesExtension4(sourcePath, exts)) return;
15888
16212
  state46.hookInvocationCount += 1;
15889
- const resolved = resolve(process.cwd(), sourcePath);
16213
+ const resolved = resolve24(process.cwd(), sourcePath);
15890
16214
  let content;
15891
16215
  try {
15892
- content = readFileSync(resolved, "utf-8");
16216
+ content = readFileSync14(resolved, "utf-8");
15893
16217
  } catch {
15894
16218
  state46.errorCount += 1;
15895
16219
  return;
@@ -15935,7 +16259,7 @@ Make sure flag behavior is intentional and consider updating flag inventory/docs
15935
16259
  state46.flagCount += result.usages.length;
15936
16260
  return {
15937
16261
  ok: true,
15938
- path: relativePath4(resolve(process.cwd(), rawPath)),
16262
+ path: relativePath4(resolve24(process.cwd(), rawPath)),
15939
16263
  scannedFiles: result.scannedFiles,
15940
16264
  usages: result.usages
15941
16265
  };
@@ -16008,6 +16332,10 @@ Make sure flag behavior is intentional and consider updating flag inventory/docs
16008
16332
  }
16009
16333
  };
16010
16334
  var feature_flag_tracker_default = plugin49;
16335
+
16336
+ // src/interface-contract-guard/index.ts
16337
+ import { existsSync as existsSync14, readFileSync as readFileSync15, readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
16338
+ import { extname as extname7, isAbsolute as isAbsolute26, relative as relative25, resolve as resolve25 } from "node:path";
16011
16339
  var API_VERSION30 = "^0.1.10";
16012
16340
  var state47 = {
16013
16341
  scanCount: 0,
@@ -16034,23 +16362,23 @@ function readConfig42(raw) {
16034
16362
  function withinProject17(p) {
16035
16363
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
16036
16364
  const root = process.cwd();
16037
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
16038
- const rel = relative(root, resolved);
16365
+ const resolved = isAbsolute26(p) ? resolve25(p) : resolve25(root, p);
16366
+ const rel = relative25(root, resolved);
16039
16367
  if (rel === "" || rel === ".") return true;
16040
16368
  if (rel.startsWith("..")) return false;
16041
- if (isAbsolute(rel)) return false;
16369
+ if (isAbsolute26(rel)) return false;
16042
16370
  return true;
16043
16371
  }
16044
16372
  function normalizeExtensions4(exts) {
16045
16373
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
16046
16374
  }
16047
16375
  function matchesExtension5(p, exts) {
16048
- return exts.includes(extname(p).toLowerCase());
16376
+ return exts.includes(extname7(p).toLowerCase());
16049
16377
  }
16050
16378
  function collectSourceFiles4(root, exts) {
16051
16379
  const files = [];
16052
- if (!existsSync(root)) return files;
16053
- const s = statSync(root);
16380
+ if (!existsSync14(root)) return files;
16381
+ const s = statSync10(root);
16054
16382
  if (s.isFile()) {
16055
16383
  if (matchesExtension5(root, exts)) files.push(root);
16056
16384
  return files;
@@ -16059,16 +16387,16 @@ function collectSourceFiles4(root, exts) {
16059
16387
  function walk(dir) {
16060
16388
  let entries;
16061
16389
  try {
16062
- entries = readdirSync(dir);
16390
+ entries = readdirSync8(dir);
16063
16391
  } catch {
16064
16392
  return;
16065
16393
  }
16066
16394
  for (const entry of entries) {
16067
16395
  if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
16068
- const full = resolve(dir, entry);
16396
+ const full = resolve25(dir, entry);
16069
16397
  let st;
16070
16398
  try {
16071
- st = statSync(full);
16399
+ st = statSync10(full);
16072
16400
  } catch {
16073
16401
  continue;
16074
16402
  }
@@ -16086,7 +16414,7 @@ function toPosix5(p) {
16086
16414
  return p.replace(/\\/g, "/");
16087
16415
  }
16088
16416
  function relativePath5(p) {
16089
- return toPosix5(relative(process.cwd(), p));
16417
+ return toPosix5(relative25(process.cwd(), p));
16090
16418
  }
16091
16419
  var INTERFACE_RE = /(?:export\s+)?interface\s+([A-Za-z_$][A-Za-z0-9_$]*)/g;
16092
16420
  function extractInterfaceNames(content) {
@@ -16107,13 +16435,13 @@ function hasImplementer(name, contents) {
16107
16435
  }
16108
16436
  function scanPath3(rawPath, cfg) {
16109
16437
  const root = process.cwd();
16110
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
16438
+ const resolved = isAbsolute26(rawPath) ? resolve25(rawPath) : resolve25(root, rawPath);
16111
16439
  const exts = normalizeExtensions4(cfg.extensions);
16112
16440
  const files = collectSourceFiles4(resolved, exts);
16113
16441
  const contents = [];
16114
16442
  for (const p of files) {
16115
16443
  try {
16116
- contents.push({ path: p, content: readFileSync(p, "utf-8") });
16444
+ contents.push({ path: p, content: readFileSync15(p, "utf-8") });
16117
16445
  } catch {
16118
16446
  }
16119
16447
  }
@@ -16185,10 +16513,10 @@ var plugin50 = {
16185
16513
  const exts = normalizeExtensions4(cfg.extensions);
16186
16514
  if (!matchesExtension5(sourcePath, exts)) return;
16187
16515
  state47.hookInvocationCount += 1;
16188
- const resolved = resolve(process.cwd(), sourcePath);
16516
+ const resolved = resolve25(process.cwd(), sourcePath);
16189
16517
  let content;
16190
16518
  try {
16191
- content = readFileSync(resolved, "utf-8");
16519
+ content = readFileSync15(resolved, "utf-8");
16192
16520
  } catch {
16193
16521
  state47.errorCount += 1;
16194
16522
  return;
@@ -16233,7 +16561,7 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
16233
16561
  state47.findingCount += result.findings.length;
16234
16562
  return {
16235
16563
  ok: true,
16236
- path: relativePath5(resolve(process.cwd(), rawPath)),
16564
+ path: relativePath5(resolve25(process.cwd(), rawPath)),
16237
16565
  scannedFiles: result.scannedFiles,
16238
16566
  findings: result.findings
16239
16567
  };
@@ -16304,6 +16632,10 @@ If you changed member shapes, search the project for implementers/\`satisfies\`/
16304
16632
  }
16305
16633
  };
16306
16634
  var interface_contract_guard_default = plugin50;
16635
+
16636
+ // src/license-audit-gate/index.ts
16637
+ import { readFileSync as readFileSync16 } from "node:fs";
16638
+ import { resolve as resolve26 } from "node:path";
16307
16639
  var API_VERSION31 = "^0.1.10";
16308
16640
  var state48 = {
16309
16641
  invocations: 0,
@@ -16380,8 +16712,8 @@ function auditPackages(names, allowedLicenses) {
16380
16712
  for (const name of names) {
16381
16713
  let licenses = [];
16382
16714
  try {
16383
- const pkgPath = resolve("node_modules", name, "package.json");
16384
- const raw = JSON.parse(readFileSync(pkgPath, "utf-8"));
16715
+ const pkgPath = resolve26("node_modules", name, "package.json");
16716
+ const raw = JSON.parse(readFileSync16(pkgPath, "utf-8"));
16385
16717
  licenses = extractLicenseStrings(raw);
16386
16718
  } catch {
16387
16719
  errors.push(name);
@@ -16558,6 +16890,10 @@ Allowed licenses: ${cfg.allowedLicenses.join(", ")}
16558
16890
  }
16559
16891
  };
16560
16892
  var license_audit_gate_default = plugin51;
16893
+
16894
+ // src/migration-planner/index.ts
16895
+ import { existsSync as existsSync15, readFileSync as readFileSync17 } from "node:fs";
16896
+ import { isAbsolute as isAbsolute27, relative as relative26, resolve as resolve27 } from "node:path";
16561
16897
  var API_VERSION32 = "^0.1.10";
16562
16898
  var state49 = {
16563
16899
  plansGenerated: 0,
@@ -16583,11 +16919,11 @@ function readConfig44(raw) {
16583
16919
  function withinProject18(p) {
16584
16920
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
16585
16921
  const root = process.cwd();
16586
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
16587
- const rel = relative(root, resolved);
16922
+ const resolved = isAbsolute27(p) ? resolve27(p) : resolve27(root, p);
16923
+ const rel = relative26(root, resolved);
16588
16924
  if (rel === "" || rel === ".") return true;
16589
16925
  if (rel.startsWith("..")) return false;
16590
- if (isAbsolute(rel)) return false;
16926
+ if (isAbsolute27(rel)) return false;
16591
16927
  return true;
16592
16928
  }
16593
16929
  function normalizeVersion(v) {
@@ -16599,9 +16935,9 @@ function readChangelog(packageName, cfg) {
16599
16935
  candidates.push(`node_modules/${packageName}/changelog.md`);
16600
16936
  for (const candidate of candidates) {
16601
16937
  if (!withinProject18(candidate)) continue;
16602
- if (existsSync(candidate)) {
16938
+ if (existsSync15(candidate)) {
16603
16939
  try {
16604
- const content = readFileSync(candidate, "utf-8");
16940
+ const content = readFileSync17(candidate, "utf-8");
16605
16941
  return { source: candidate, content: content.slice(0, cfg.maxChars) };
16606
16942
  } catch {
16607
16943
  }
@@ -16753,14 +17089,14 @@ var plugin52 = {
16753
17089
  const inp = input.toolInput ?? {};
16754
17090
  const path = inp["path"];
16755
17091
  if (!path) return;
16756
- const basename6 = path.split(/[/\\]/).pop() ?? "";
17092
+ const basename7 = path.split(/[/\\]/).pop() ?? "";
16757
17093
  if (!/^(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|bun\.lockb?)$/i.test(
16758
- basename6
17094
+ basename7
16759
17095
  )) {
16760
17096
  return;
16761
17097
  }
16762
17098
  return {
16763
- additionalContext: `Manifest file ${basename6} changed. Consider running migration_plan if a dependency version was updated.`
17099
+ additionalContext: `Manifest file ${basename7} changed. Consider running migration_plan if a dependency version was updated.`
16764
17100
  };
16765
17101
  };
16766
17102
  state49.hookUnregister = api.registerHook("PostToolUse", "write|edit", hook);
@@ -16901,6 +17237,10 @@ var plugin52 = {
16901
17237
  }
16902
17238
  };
16903
17239
  var migration_planner_default = plugin52;
17240
+
17241
+ // src/performance-regression-gate/index.ts
17242
+ import { existsSync as existsSync16, readFileSync as readFileSync18 } from "node:fs";
17243
+ import { isAbsolute as isAbsolute28, relative as relative27, resolve as resolve28 } from "node:path";
16904
17244
  var API_VERSION33 = "^0.1.10";
16905
17245
  var state50 = {
16906
17246
  invocationCount: 0,
@@ -16925,18 +17265,18 @@ function readConfig45(raw) {
16925
17265
  }
16926
17266
  function withinProject19(p, cwd = process.cwd()) {
16927
17267
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
16928
- const root = resolve(cwd);
16929
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
16930
- const rel = relative(root, resolved);
17268
+ const root = resolve28(cwd);
17269
+ const resolved = isAbsolute28(p) ? resolve28(p) : resolve28(root, p);
17270
+ const rel = relative27(root, resolved);
16931
17271
  if (rel === "" || rel === ".") return true;
16932
17272
  if (rel.startsWith("..")) return false;
16933
- if (isAbsolute(rel)) return false;
17273
+ if (isAbsolute28(rel)) return false;
16934
17274
  return true;
16935
17275
  }
16936
17276
  function resolveProjectPath7(rawPath, cwd = process.cwd()) {
16937
17277
  if (typeof rawPath !== "string" || rawPath.length === 0) return null;
16938
- const root = resolve(cwd);
16939
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
17278
+ const root = resolve28(cwd);
17279
+ const resolved = isAbsolute28(rawPath) ? resolve28(rawPath) : resolve28(root, rawPath);
16940
17280
  if (!withinProject19(resolved, cwd)) return null;
16941
17281
  return resolved;
16942
17282
  }
@@ -16965,9 +17305,9 @@ function flattenResults(results) {
16965
17305
  return flat;
16966
17306
  }
16967
17307
  function loadResults(path) {
16968
- if (!path || !existsSync(path)) return null;
17308
+ if (!path || !existsSync16(path)) return null;
16969
17309
  try {
16970
- const raw = JSON.parse(readFileSync(path, "utf-8"));
17310
+ const raw = JSON.parse(readFileSync18(path, "utf-8"));
16971
17311
  return raw;
16972
17312
  } catch {
16973
17313
  return null;
@@ -17210,6 +17550,10 @@ var plugin53 = {
17210
17550
  }
17211
17551
  };
17212
17552
  var performance_regression_gate_default = plugin53;
17553
+
17554
+ // src/refactor-suggester/index.ts
17555
+ import { existsSync as existsSync17, readFileSync as readFileSync19, readdirSync as readdirSync9, statSync as statSync11 } from "node:fs";
17556
+ import { extname as extname8, isAbsolute as isAbsolute29, relative as relative28, resolve as resolve29 } from "node:path";
17213
17557
  var API_VERSION34 = "^0.1.10";
17214
17558
  var state51 = {
17215
17559
  scanCount: 0,
@@ -17248,23 +17592,23 @@ function readConfig46(raw) {
17248
17592
  function withinProject20(p) {
17249
17593
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
17250
17594
  const root = process.cwd();
17251
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
17252
- const rel = relative(root, resolved);
17595
+ const resolved = isAbsolute29(p) ? resolve29(p) : resolve29(root, p);
17596
+ const rel = relative28(root, resolved);
17253
17597
  if (rel === "" || rel === ".") return true;
17254
17598
  if (rel.startsWith("..")) return false;
17255
- if (isAbsolute(rel)) return false;
17599
+ if (isAbsolute29(rel)) return false;
17256
17600
  return true;
17257
17601
  }
17258
17602
  function normalizeExtensions5(exts) {
17259
17603
  return exts.map((e) => e.startsWith(".") ? e.toLowerCase() : `.${e.toLowerCase()}`);
17260
17604
  }
17261
17605
  function matchesExtension6(p, exts) {
17262
- return exts.includes(extname(p).toLowerCase());
17606
+ return exts.includes(extname8(p).toLowerCase());
17263
17607
  }
17264
17608
  function collectSourceFiles5(root, exts) {
17265
17609
  const files = [];
17266
- if (!existsSync(root)) return files;
17267
- const s = statSync(root);
17610
+ if (!existsSync17(root)) return files;
17611
+ const s = statSync11(root);
17268
17612
  if (s.isFile()) {
17269
17613
  if (matchesExtension6(root, exts)) files.push(root);
17270
17614
  return files;
@@ -17273,16 +17617,16 @@ function collectSourceFiles5(root, exts) {
17273
17617
  function walk(dir) {
17274
17618
  let entries;
17275
17619
  try {
17276
- entries = readdirSync(dir);
17620
+ entries = readdirSync9(dir);
17277
17621
  } catch {
17278
17622
  return;
17279
17623
  }
17280
17624
  for (const entry of entries) {
17281
17625
  if (entry === "node_modules" || entry === "dist" || entry === ".git" || entry === "coverage") continue;
17282
- const full = resolve(dir, entry);
17626
+ const full = resolve29(dir, entry);
17283
17627
  let st;
17284
17628
  try {
17285
- st = statSync(full);
17629
+ st = statSync11(full);
17286
17630
  } catch {
17287
17631
  continue;
17288
17632
  }
@@ -17300,7 +17644,7 @@ function toPosix6(p) {
17300
17644
  return p.replace(/\\/g, "/");
17301
17645
  }
17302
17646
  function relativePath6(p) {
17303
- return toPosix6(relative(process.cwd(), p));
17647
+ return toPosix6(relative28(process.cwd(), p));
17304
17648
  }
17305
17649
  function leadingIndentLevel(line) {
17306
17650
  const leading = line.match(/^(\s*)/)?.[1] ?? "";
@@ -17388,13 +17732,13 @@ function detectSmells(filePath, content, rules) {
17388
17732
  }
17389
17733
  function scanPath4(rawPath, cfg) {
17390
17734
  const root = process.cwd();
17391
- const resolved = isAbsolute(rawPath) ? resolve(rawPath) : resolve(root, rawPath);
17735
+ const resolved = isAbsolute29(rawPath) ? resolve29(rawPath) : resolve29(root, rawPath);
17392
17736
  const exts = normalizeExtensions5(cfg.extensions);
17393
17737
  const files = collectSourceFiles5(resolved, exts);
17394
17738
  const suggestions = [];
17395
17739
  for (const p of files) {
17396
17740
  try {
17397
- const content = readFileSync(p, "utf-8");
17741
+ const content = readFileSync19(p, "utf-8");
17398
17742
  suggestions.push(...detectSmells(p, content, cfg.rules));
17399
17743
  if (suggestions.length >= cfg.maxSuggestions) break;
17400
17744
  } catch {
@@ -17464,10 +17808,10 @@ var plugin54 = {
17464
17808
  const now = Date.now();
17465
17809
  const lastWarning = state51.lastHookWarning.get(sourcePath);
17466
17810
  if (lastWarning !== void 0 && now - lastWarning < 6e4) return;
17467
- const resolved = resolve(process.cwd(), sourcePath);
17811
+ const resolved = resolve29(process.cwd(), sourcePath);
17468
17812
  let content;
17469
17813
  try {
17470
- content = readFileSync(resolved, "utf-8");
17814
+ content = readFileSync19(resolved, "utf-8");
17471
17815
  } catch {
17472
17816
  state51.errorCount += 1;
17473
17817
  return;
@@ -17511,7 +17855,7 @@ var plugin54 = {
17511
17855
  state51.suggestionCount += result.suggestions.length;
17512
17856
  return {
17513
17857
  ok: true,
17514
- path: relativePath6(resolve(process.cwd(), rawPath)),
17858
+ path: relativePath6(resolve29(process.cwd(), rawPath)),
17515
17859
  scannedFiles: result.scannedFiles,
17516
17860
  suggestions: result.suggestions,
17517
17861
  rules: cfg.rules
@@ -17586,6 +17930,9 @@ var plugin54 = {
17586
17930
  }
17587
17931
  };
17588
17932
  var refactor_suggester_default = plugin54;
17933
+
17934
+ // src/release-notes-generator/index.ts
17935
+ import { execFileSync as execFileSync11 } from "node:child_process";
17589
17936
  var API_VERSION35 = "^0.1.10";
17590
17937
  var state52 = {
17591
17938
  generateCount: 0,
@@ -17626,23 +17973,41 @@ function formatCommit(c, includeScope) {
17626
17973
  line += ` ${c.description}`;
17627
17974
  return line;
17628
17975
  }
17976
+ var GIT_OPTIONS = {
17977
+ encoding: "utf-8",
17978
+ stdio: ["pipe", "pipe", "ignore"],
17979
+ shell: false
17980
+ };
17629
17981
  function resolveFromRef(defaultFrom, inputFrom) {
17630
17982
  if (inputFrom) return inputFrom;
17631
17983
  if (defaultFrom === "latest-tag") {
17632
17984
  try {
17633
- return execSync("git describe --tags --abbrev=0", { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"] }).trim();
17985
+ return execFileSync11("git", ["describe", "--tags", "--abbrev=0"], GIT_OPTIONS).trim();
17634
17986
  } catch {
17635
17987
  return "";
17636
17988
  }
17637
17989
  }
17638
17990
  return defaultFrom;
17639
17991
  }
17992
+ function resolveCommit(ref) {
17993
+ const resolved = execFileSync11(
17994
+ "git",
17995
+ ["rev-parse", "--verify", "--end-of-options", `${ref}^{commit}`],
17996
+ GIT_OPTIONS
17997
+ ).trim();
17998
+ if (!/^[0-9a-f]{40,64}$/i.test(resolved)) {
17999
+ throw new Error(`git returned an invalid commit id for ref ${JSON.stringify(ref)}`);
18000
+ }
18001
+ return resolved;
18002
+ }
17640
18003
  function getCommits(from, to) {
17641
- const range = from ? `${from}..${to}` : to;
17642
- const output = execSync(`git log --pretty=format:'%H%x09%s' ${range}`, {
17643
- encoding: "utf-8",
17644
- stdio: ["pipe", "pipe", "ignore"]
17645
- });
18004
+ const toCommit = resolveCommit(to);
18005
+ const range = from ? `${resolveCommit(from)}..${toCommit}` : toCommit;
18006
+ const output = execFileSync11(
18007
+ "git",
18008
+ ["log", "--pretty=format:%H%x09%s", "--end-of-options", range],
18009
+ GIT_OPTIONS
18010
+ );
17646
18011
  if (!output.trim()) return [];
17647
18012
  const commits = [];
17648
18013
  for (const line of output.split(/\r?\n/)) {
@@ -17790,6 +18155,10 @@ var plugin55 = {
17790
18155
  }
17791
18156
  };
17792
18157
  var release_notes_generator_default = plugin55;
18158
+
18159
+ // src/schema-evolution-guard/index.ts
18160
+ import { readFileSync as readFileSync20 } from "node:fs";
18161
+ import { basename as basename6, isAbsolute as isAbsolute30, relative as relative29, resolve as resolve30 } from "node:path";
17793
18162
  var API_VERSION36 = "^0.1.10";
17794
18163
  var state53 = {
17795
18164
  invocationCount: 0,
@@ -17842,11 +18211,11 @@ function fileKind(fileName) {
17842
18211
  function withinProject21(p) {
17843
18212
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
17844
18213
  const root = process.cwd();
17845
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
17846
- const rel = relative(root, resolved);
18214
+ const resolved = isAbsolute30(p) ? resolve30(p) : resolve30(root, p);
18215
+ const rel = relative29(root, resolved);
17847
18216
  if (rel === "" || rel === ".") return true;
17848
18217
  if (rel.startsWith("..")) return false;
17849
- if (isAbsolute(rel)) return false;
18218
+ if (isAbsolute30(rel)) return false;
17850
18219
  return true;
17851
18220
  }
17852
18221
  function findIssues(content, kind, maxFindings) {
@@ -17986,7 +18355,7 @@ var plugin56 = {
17986
18355
  const filePath = typeof toolInput["path"] === "string" ? toolInput["path"] : void 0;
17987
18356
  if (!filePath) return;
17988
18357
  state53.invocationCount += 1;
17989
- const fileName = basename(filePath);
18358
+ const fileName = basename6(filePath);
17990
18359
  if (!matchesAnyPattern2(fileName, cfg.filePatterns)) {
17991
18360
  state53.skippedCount += 1;
17992
18361
  return;
@@ -18001,7 +18370,7 @@ var plugin56 = {
18001
18370
  content = toolInput["content"];
18002
18371
  } else if (withinProject21(filePath)) {
18003
18372
  try {
18004
- content = readFileSync(filePath, "utf-8");
18373
+ content = readFileSync20(filePath, "utf-8");
18005
18374
  } catch {
18006
18375
  content = void 0;
18007
18376
  }
@@ -18103,6 +18472,10 @@ ${body}${suffix}`;
18103
18472
  }
18104
18473
  };
18105
18474
  var schema_evolution_guard_default = plugin56;
18475
+
18476
+ // src/security-hotspot-scanner/index.ts
18477
+ import { readdirSync as readdirSync10, readFileSync as readFileSync21, statSync as statSync12 } from "node:fs";
18478
+ import { isAbsolute as isAbsolute31, relative as relative30, resolve as resolve31 } from "node:path";
18106
18479
  var API_VERSION37 = "^0.1.10";
18107
18480
  var state54 = {
18108
18481
  scanCount: 0,
@@ -18187,17 +18560,17 @@ function isSourceFile2(filePath, extensions) {
18187
18560
  function withinProject22(p) {
18188
18561
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
18189
18562
  const root = process.cwd();
18190
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
18191
- const rel = relative(root, resolved);
18563
+ const resolved = isAbsolute31(p) ? resolve31(p) : resolve31(root, p);
18564
+ const rel = relative30(root, resolved);
18192
18565
  if (rel === "" || rel === ".") return true;
18193
18566
  if (rel.startsWith("..")) return false;
18194
- if (isAbsolute(rel)) return false;
18567
+ if (isAbsolute31(rel)) return false;
18195
18568
  return true;
18196
18569
  }
18197
18570
  function scanPath5(inputPath, cfg) {
18198
18571
  const start = Date.now();
18199
18572
  const root = process.cwd();
18200
- const resolved = isAbsolute(inputPath) ? resolve(inputPath) : resolve(root, inputPath);
18573
+ const resolved = isAbsolute31(inputPath) ? resolve31(inputPath) : resolve31(root, inputPath);
18201
18574
  if (!withinProject22(inputPath)) {
18202
18575
  return {
18203
18576
  path: inputPath,
@@ -18214,11 +18587,11 @@ function scanPath5(inputPath, cfg) {
18214
18587
  const scanFile2 = (filePath) => {
18215
18588
  if (!isSourceFile2(filePath, cfg.scanOnChange)) return;
18216
18589
  try {
18217
- const content = readFileSync(filePath, "utf-8");
18590
+ const content = readFileSync21(filePath, "utf-8");
18218
18591
  filesScanned += 1;
18219
18592
  const findings = scanSource(content, maxPerFile);
18220
18593
  for (const f of findings) {
18221
- allFindings.push({ ...f, snippet: `${relative(root, filePath)}:${f.line}: ${f.snippet}` });
18594
+ allFindings.push({ ...f, snippet: `${relative30(root, filePath)}:${f.line}: ${f.snippet}` });
18222
18595
  if (allFindings.length >= cfg.maxFindings) return;
18223
18596
  }
18224
18597
  } catch {
@@ -18227,15 +18600,15 @@ function scanPath5(inputPath, cfg) {
18227
18600
  const walk = (dir) => {
18228
18601
  let entries;
18229
18602
  try {
18230
- entries = readdirSync(dir);
18603
+ entries = readdirSync10(dir);
18231
18604
  } catch {
18232
18605
  return;
18233
18606
  }
18234
18607
  for (const entry of entries) {
18235
18608
  if (allFindings.length >= cfg.maxFindings) return;
18236
- const full = resolve(dir, entry);
18609
+ const full = resolve31(dir, entry);
18237
18610
  try {
18238
- const st = statSync(full);
18611
+ const st = statSync12(full);
18239
18612
  if (st.isDirectory()) {
18240
18613
  if (entry.startsWith(".") || entry === "node_modules" || entry === "dist" || entry === "coverage") {
18241
18614
  continue;
@@ -18249,7 +18622,7 @@ function scanPath5(inputPath, cfg) {
18249
18622
  }
18250
18623
  };
18251
18624
  try {
18252
- const st = statSync(resolved);
18625
+ const st = statSync12(resolved);
18253
18626
  if (st.isDirectory()) {
18254
18627
  walk(resolved);
18255
18628
  } else if (st.isFile()) {
@@ -18499,6 +18872,10 @@ Review or remove the risky pattern(s).`;
18499
18872
  }
18500
18873
  };
18501
18874
  var security_hotspot_scanner_default = plugin57;
18875
+
18876
+ // src/semantic-search-indexer/index.ts
18877
+ import * as fs2 from "node:fs/promises";
18878
+ import { isAbsolute as isAbsolute32, relative as relative31, resolve as resolve32 } from "node:path";
18502
18879
  var API_VERSION38 = "^0.1.10";
18503
18880
  var state55 = {
18504
18881
  index: null,
@@ -18509,7 +18886,9 @@ var state55 = {
18509
18886
  truncated: false,
18510
18887
  queryCount: 0,
18511
18888
  reindexCount: 0,
18512
- buildPromise: null};
18889
+ buildPromise: null,
18890
+ hookUnregister: null
18891
+ };
18513
18892
  var DEFAULTS47 = {
18514
18893
  enabled: true,
18515
18894
  includeExtensions: [
@@ -18571,18 +18950,18 @@ function normalizeSlashes2(p) {
18571
18950
  function withinProject23(p) {
18572
18951
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
18573
18952
  const root = normalizeSlashes2(process.cwd());
18574
- const resolved = normalizeSlashes2(isAbsolute(p) ? resolve(p) : resolve(root, p));
18575
- const rel = normalizeSlashes2(relative(root, resolved));
18953
+ const resolved = normalizeSlashes2(isAbsolute32(p) ? resolve32(p) : resolve32(root, p));
18954
+ const rel = normalizeSlashes2(relative31(root, resolved));
18576
18955
  if (rel === "" || rel === ".") return true;
18577
18956
  if (rel.startsWith("..")) return false;
18578
- if (isAbsolute(rel)) return false;
18957
+ if (isAbsolute32(rel)) return false;
18579
18958
  return true;
18580
18959
  }
18581
18960
  function resolveProjectPath8(p) {
18582
18961
  const raw = typeof p === "string" && p.length > 0 ? p : ".";
18583
18962
  if (!withinProject23(raw)) return null;
18584
18963
  const root = normalizeSlashes2(process.cwd());
18585
- return normalizeSlashes2(isAbsolute(raw) ? resolve(raw) : resolve(root, raw));
18964
+ return normalizeSlashes2(isAbsolute32(raw) ? resolve32(raw) : resolve32(root, raw));
18586
18965
  }
18587
18966
  function tokenize(text, minLength) {
18588
18967
  const tokens = [];
@@ -18612,7 +18991,7 @@ function shouldIndexFile(filePath, cfg) {
18612
18991
  var INDEX_BATCH_SIZE = 32;
18613
18992
  var YIELD_EVERY_FILES = 64;
18614
18993
  function yieldEventLoop() {
18615
- return new Promise((resolve34) => setImmediate(resolve34));
18994
+ return new Promise((resolve36) => setImmediate(resolve36));
18616
18995
  }
18617
18996
  function addFileToIndex(relPath, content, size, cfg) {
18618
18997
  if (!state55.index || content.includes("\0")) return;
@@ -18640,7 +19019,7 @@ async function indexFileFromStats(absPath, relPath, stats, cfg) {
18640
19019
  if (!shouldIndexFile(relPath, cfg) || !stats.isFile() || stats.size > cfg.maxFileBytes) return;
18641
19020
  let content;
18642
19021
  try {
18643
- content = await fsp.readFile(absPath, "utf-8");
19022
+ content = await fs2.readFile(absPath, "utf-8");
18644
19023
  } catch {
18645
19024
  return;
18646
19025
  }
@@ -18656,7 +19035,7 @@ async function flushFileBatch(batch, cfg) {
18656
19035
  async function walkDirectory(absPath, cfg, excludes, fileBatch) {
18657
19036
  let entries;
18658
19037
  try {
18659
- entries = await fsp.readdir(absPath, { withFileTypes: true });
19038
+ entries = await fs2.readdir(absPath, { withFileTypes: true });
18660
19039
  } catch {
18661
19040
  return;
18662
19041
  }
@@ -18666,8 +19045,8 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
18666
19045
  state55.truncated = true;
18667
19046
  return;
18668
19047
  }
18669
- const absChild = normalizeSlashes2(resolve(absPath, ent.name));
18670
- const relChild = normalizeSlashes2(relative(root, absChild));
19048
+ const absChild = normalizeSlashes2(resolve32(absPath, ent.name));
19049
+ const relChild = normalizeSlashes2(relative31(root, absChild));
18671
19050
  if (relChild === "" || relChild === ".") continue;
18672
19051
  if (excludes.some((re) => re.test(relChild))) continue;
18673
19052
  if (ent.isDirectory()) {
@@ -18678,7 +19057,7 @@ async function walkDirectory(absPath, cfg, excludes, fileBatch) {
18678
19057
  if (!shouldIndexFile(relChild, cfg)) continue;
18679
19058
  let stats;
18680
19059
  try {
18681
- stats = await fsp.stat(absChild);
19060
+ stats = await fs2.stat(absChild);
18682
19061
  } catch {
18683
19062
  continue;
18684
19063
  }
@@ -18703,13 +19082,13 @@ async function buildIndex(rootPath, cfg) {
18703
19082
  const excludes = compileExcludes(cfg.excludePatterns);
18704
19083
  let rootStats;
18705
19084
  try {
18706
- rootStats = await fsp.stat(rootPath);
19085
+ rootStats = await fs2.stat(rootPath);
18707
19086
  } catch {
18708
19087
  state55.termCount = 0;
18709
19088
  return;
18710
19089
  }
18711
19090
  if (rootStats.isFile()) {
18712
- const relPath = normalizeSlashes2(relative(normalizeSlashes2(process.cwd()), rootPath));
19091
+ const relPath = normalizeSlashes2(relative31(normalizeSlashes2(process.cwd()), rootPath));
18713
19092
  await indexFileFromStats(rootPath, relPath === "" ? "." : relPath, rootStats, cfg);
18714
19093
  state55.fileCount = state55.index.files.size;
18715
19094
  } else if (rootStats.isDirectory()) {
@@ -18869,6 +19248,13 @@ var plugin58 = {
18869
19248
  state55.queryCount = 0;
18870
19249
  state55.reindexCount = 0;
18871
19250
  state55.buildPromise = null;
19251
+ if (state55.hookUnregister) {
19252
+ try {
19253
+ state55.hookUnregister();
19254
+ } catch {
19255
+ }
19256
+ state55.hookUnregister = null;
19257
+ }
18872
19258
  const cfg = readConfig50(api.config.extensions?.["semantic-search-indexer"]);
18873
19259
  api.tools.register({
18874
19260
  name: "semantic_search",
@@ -18954,6 +19340,13 @@ var plugin58 = {
18954
19340
  });
18955
19341
  },
18956
19342
  teardown(api) {
19343
+ if (state55.hookUnregister) {
19344
+ try {
19345
+ state55.hookUnregister();
19346
+ } catch {
19347
+ }
19348
+ state55.hookUnregister = null;
19349
+ }
18957
19350
  const final = {
18958
19351
  fileCount: state55.fileCount,
18959
19352
  termCount: state55.termCount,
@@ -18986,6 +19379,10 @@ var plugin58 = {
18986
19379
  }
18987
19380
  };
18988
19381
  var semantic_search_indexer_default = plugin58;
19382
+
19383
+ // src/smart-rename/index.ts
19384
+ import { readFileSync as readFileSync22, writeFileSync as writeFileSync7 } from "node:fs";
19385
+ import { extname as extname9, isAbsolute as isAbsolute33, relative as relative32, resolve as resolve33 } from "node:path";
18989
19386
  var API_VERSION39 = "^0.1.10";
18990
19387
  var state56 = {
18991
19388
  renameCount: 0,
@@ -19007,18 +19404,18 @@ function readConfig51(raw) {
19007
19404
  function withinProject24(p) {
19008
19405
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
19009
19406
  const root = process.cwd();
19010
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
19011
- const rel = relative(root, resolved);
19407
+ const resolved = isAbsolute33(p) ? resolve33(p) : resolve33(root, p);
19408
+ const rel = relative32(root, resolved);
19012
19409
  if (rel === "" || rel === ".") return true;
19013
19410
  if (rel.startsWith("..")) return false;
19014
- if (isAbsolute(rel)) return false;
19411
+ if (isAbsolute33(rel)) return false;
19015
19412
  return true;
19016
19413
  }
19017
19414
  function toPosix7(p) {
19018
19415
  return p.replace(/\\/g, "/");
19019
19416
  }
19020
19417
  function relativePath7(p) {
19021
- return toPosix7(relative(process.cwd(), p));
19418
+ return toPosix7(relative32(process.cwd(), p));
19022
19419
  }
19023
19420
  function escapeRegex2(s) {
19024
19421
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -19089,14 +19486,14 @@ var plugin59 = {
19089
19486
  if (!withinProject24(rawPath)) {
19090
19487
  return { ok: false, error: "path is outside the project root" };
19091
19488
  }
19092
- const ext = extname(rawPath).toLowerCase();
19489
+ const ext = extname9(rawPath).toLowerCase();
19093
19490
  if (!cfg.extensions.includes(ext)) {
19094
19491
  return { ok: false, error: `extension ${ext} is not allowed for rename` };
19095
19492
  }
19096
- const resolved = resolve(process.cwd(), rawPath);
19493
+ const resolved = resolve33(process.cwd(), rawPath);
19097
19494
  let content;
19098
19495
  try {
19099
- content = readFileSync(resolved, "utf-8");
19496
+ content = readFileSync22(resolved, "utf-8");
19100
19497
  } catch (err) {
19101
19498
  state56.errorCount += 1;
19102
19499
  return { ok: false, error: String(err) };
@@ -19106,7 +19503,7 @@ var plugin59 = {
19106
19503
  state56.replacementCount += replacements;
19107
19504
  if (input.apply) {
19108
19505
  try {
19109
- writeFileSync(resolved, preview, "utf-8");
19506
+ writeFileSync7(resolved, preview, "utf-8");
19110
19507
  } catch (err) {
19111
19508
  state56.errorCount += 1;
19112
19509
  return { ok: false, error: String(err) };
@@ -19150,6 +19547,12 @@ var plugin59 = {
19150
19547
  }
19151
19548
  };
19152
19549
  var smart_rename_default = plugin59;
19550
+
19551
+ // src/test-flake-detector/index.ts
19552
+ import { execFileSync as execFileSync12 } from "node:child_process";
19553
+ import { readFileSync as readFileSync23 } from "node:fs";
19554
+ import { createRequire } from "node:module";
19555
+ import { dirname as dirname7, isAbsolute as isAbsolute34, relative as relative33, resolve as resolve34 } from "node:path";
19153
19556
  var API_VERSION40 = "^0.1.10";
19154
19557
  var state57 = {
19155
19558
  invocationCount: 0,
@@ -19209,19 +19612,95 @@ function parseTestOutput(output) {
19209
19612
  }
19210
19613
  return { passed, failed };
19211
19614
  }
19212
- function buildCommand(baseCommand, testPattern) {
19213
- const trimmedBase = baseCommand.trim();
19214
- if (!testPattern) return trimmedBase;
19215
- if (trimmedBase.includes(testPattern)) return trimmedBase;
19216
- return `${trimmedBase} ${testPattern}`;
19615
+ var TEST_RUNNERS = /* @__PURE__ */ new Set(["vitest", "jest", "mocha"]);
19616
+ var ALLOWED_RUNNER_FLAGS = /* @__PURE__ */ new Set([
19617
+ "run",
19618
+ "--run",
19619
+ "--runInBand",
19620
+ "--passWithNoTests",
19621
+ "--reporter=verbose",
19622
+ "--reporter=default"
19623
+ ]);
19624
+ function withinProject25(p) {
19625
+ if (p.length === 0 || p.length > 4096 || p.startsWith("-")) return false;
19626
+ const root = resolve34(process.cwd());
19627
+ const resolved = isAbsolute34(p) ? resolve34(p) : resolve34(root, p);
19628
+ const rel = relative33(root, resolved);
19629
+ return rel === "" || !rel.startsWith("..") && !isAbsolute34(rel);
19630
+ }
19631
+ function isInside(parent, child) {
19632
+ if (parent === child) return true;
19633
+ const rel = relative33(parent, child);
19634
+ return rel !== "" && !rel.startsWith("..") && !isAbsolute34(rel);
19635
+ }
19636
+ function tokenizeCommand(command) {
19637
+ const trimmed = command.trim();
19638
+ if (!trimmed || /["'`;&|<>\r\n]/.test(trimmed)) return null;
19639
+ return trimmed.split(/\s+/).filter(Boolean);
19640
+ }
19641
+ function resolveTestCommand(baseCommand, testPattern) {
19642
+ const tokens = tokenizeCommand(baseCommand);
19643
+ if (!tokens) return null;
19644
+ let runner;
19645
+ let runnerArgs;
19646
+ const [head, second, third, ...rest] = tokens;
19647
+ if (TEST_RUNNERS.has(head ?? "")) {
19648
+ runner = head;
19649
+ runnerArgs = tokens.slice(1);
19650
+ } else if (head === "npx" && TEST_RUNNERS.has(second ?? "")) {
19651
+ runner = second;
19652
+ runnerArgs = tokens.slice(2);
19653
+ } else if (head === "pnpm" && (second === "exec" || second === "dlx") && TEST_RUNNERS.has(third ?? "")) {
19654
+ runner = third;
19655
+ runnerArgs = rest;
19656
+ } else if (head === "pnpm" && TEST_RUNNERS.has(second ?? "")) {
19657
+ runner = second;
19658
+ runnerArgs = tokens.slice(2);
19659
+ } else if (head === "npm" && second === "exec" && TEST_RUNNERS.has(third ?? "")) {
19660
+ runner = third;
19661
+ runnerArgs = rest;
19662
+ } else if (head === "yarn" && TEST_RUNNERS.has(second ?? "")) {
19663
+ runner = second;
19664
+ runnerArgs = tokens.slice(2);
19665
+ } else {
19666
+ return null;
19667
+ }
19668
+ if (runnerArgs.some((arg) => !ALLOWED_RUNNER_FLAGS.has(arg))) return null;
19669
+ let resolvedEntry;
19670
+ try {
19671
+ const requireFromProject = createRequire(resolve34(process.cwd(), "package.json"));
19672
+ const packagePath = requireFromProject.resolve(`${runner}/package.json`);
19673
+ const packageJson = JSON.parse(readFileSync23(packagePath, "utf8"));
19674
+ const relativeBin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.[runner] ?? Object.values(packageJson.bin ?? {})[0];
19675
+ if (!relativeBin) return null;
19676
+ const packageDir = dirname7(packagePath);
19677
+ const candidate = resolve34(packageDir, relativeBin);
19678
+ if (isAbsolute34(relativeBin) || !isInside(packageDir, candidate)) {
19679
+ return null;
19680
+ }
19681
+ resolvedEntry = candidate;
19682
+ } catch {
19683
+ return null;
19684
+ }
19685
+ const args = [resolvedEntry, ...runnerArgs];
19686
+ if (testPattern) {
19687
+ if (!withinProject25(testPattern)) return null;
19688
+ args.push(testPattern);
19689
+ }
19690
+ return {
19691
+ cmd: process.execPath,
19692
+ args,
19693
+ display: [...tokens, ...testPattern ? [testPattern] : []].join(" ")
19694
+ };
19217
19695
  }
19218
19696
  function runOnce(command, timeoutMs) {
19219
19697
  try {
19220
- const output = execSync(command, {
19698
+ const output = execFileSync12(command.cmd, command.args, {
19221
19699
  encoding: "utf-8",
19222
19700
  timeout: timeoutMs,
19223
19701
  cwd: process.cwd(),
19224
- stdio: ["pipe", "pipe", "pipe"]
19702
+ stdio: ["pipe", "pipe", "pipe"],
19703
+ shell: false
19225
19704
  });
19226
19705
  return { output };
19227
19706
  } catch (err) {
@@ -19306,10 +19785,16 @@ var plugin60 = {
19306
19785
  return { ok: false, error: "test-flake-detector is disabled" };
19307
19786
  }
19308
19787
  const requestedRuns = typeof input.runs === "number" && input.runs >= 1 ? Math.min(Math.floor(input.runs), cfg.maxRuns) : 5;
19309
- const command = buildCommand(
19788
+ const command = resolveTestCommand(
19310
19789
  typeof input.command === "string" && input.command.trim().length > 0 ? input.command : cfg.defaultCommand,
19311
19790
  input.testPattern
19312
19791
  );
19792
+ if (!command) {
19793
+ return {
19794
+ ok: false,
19795
+ error: "Unsupported test command or unsafe testPattern. Use vitest, jest, or mocha through a supported package runner, and keep patterns inside the project."
19796
+ };
19797
+ }
19313
19798
  state57.invocationCount += 1;
19314
19799
  const start = Date.now();
19315
19800
  const records = /* @__PURE__ */ new Map();
@@ -19351,7 +19836,7 @@ var plugin60 = {
19351
19836
  };
19352
19837
  return {
19353
19838
  ok: true,
19354
- command,
19839
+ command: command.display,
19355
19840
  runsRequested: requestedRuns,
19356
19841
  runsCompleted,
19357
19842
  durationMs,
@@ -19419,6 +19904,10 @@ var plugin60 = {
19419
19904
  }
19420
19905
  };
19421
19906
  var test_flake_detector_default = plugin60;
19907
+
19908
+ // src/test-generator/index.ts
19909
+ import { readFileSync as readFileSync24 } from "node:fs";
19910
+ import { isAbsolute as isAbsolute35, relative as relative34, resolve as resolve35 } from "node:path";
19422
19911
  var API_VERSION41 = "^0.1.10";
19423
19912
  var state58 = {
19424
19913
  generateCount: 0,
@@ -19441,21 +19930,21 @@ function readConfig53(raw) {
19441
19930
  includeImports: r["includeImports"] !== false
19442
19931
  };
19443
19932
  }
19444
- function withinProject25(p) {
19933
+ function withinProject26(p) {
19445
19934
  if (typeof p !== "string" || p.length === 0 || p.length > 4096) return false;
19446
19935
  const root = process.cwd();
19447
- const resolved = isAbsolute(p) ? resolve(p) : resolve(root, p);
19448
- const rel = relative(root, resolved);
19936
+ const resolved = isAbsolute35(p) ? resolve35(p) : resolve35(root, p);
19937
+ const rel = relative34(root, resolved);
19449
19938
  if (rel === "" || rel === ".") return true;
19450
19939
  if (rel.startsWith("..")) return false;
19451
- if (isAbsolute(rel)) return false;
19940
+ if (isAbsolute35(rel)) return false;
19452
19941
  return true;
19453
19942
  }
19454
19943
  function toPosix8(p) {
19455
19944
  return p.replace(/\\/g, "/");
19456
19945
  }
19457
19946
  function relativePath8(p) {
19458
- return toPosix8(relative(process.cwd(), p));
19947
+ return toPosix8(relative34(process.cwd(), p));
19459
19948
  }
19460
19949
  function detectExports(content) {
19461
19950
  const exports = [];
@@ -19536,7 +20025,7 @@ function generateTestContent(filePath, detected, cfg) {
19536
20025
  return lines.join("\n");
19537
20026
  }
19538
20027
  function generateForFile(filePath, cfg) {
19539
- const content = readFileSync(filePath, "utf-8");
20028
+ const content = readFileSync24(filePath, "utf-8");
19540
20029
  const detected = detectExports(content);
19541
20030
  const sourceName = relativePath8(filePath).split("/").pop();
19542
20031
  const baseName = sourceName.replace(/\.[^.]+$/, "");
@@ -19603,10 +20092,10 @@ var plugin61 = {
19603
20092
  if (!rawPath || typeof rawPath !== "string") {
19604
20093
  return { ok: false, error: "path is required" };
19605
20094
  }
19606
- if (!withinProject25(rawPath)) {
20095
+ if (!withinProject26(rawPath)) {
19607
20096
  return { ok: false, error: "path is outside the project root" };
19608
20097
  }
19609
- const resolved = resolve(process.cwd(), rawPath);
20098
+ const resolved = resolve35(process.cwd(), rawPath);
19610
20099
  state58.generateCount += 1;
19611
20100
  let result;
19612
20101
  try {
@@ -19936,9 +20425,9 @@ var plugin62 = {
19936
20425
  state59.postInvocations += 1;
19937
20426
  let content;
19938
20427
  try {
19939
- const stat4 = await fsp.stat(filePath);
20428
+ const stat4 = await fs3.stat(filePath);
19940
20429
  if (!stat4.isFile()) return;
19941
- content = await fsp.readFile(filePath, "utf-8");
20430
+ content = await fs3.readFile(filePath, "utf-8");
19942
20431
  } catch {
19943
20432
  state59.readErrorCount += 1;
19944
20433
  return;
@@ -20070,5 +20559,68 @@ ${lines}${overflowNote}`
20070
20559
  }
20071
20560
  };
20072
20561
  var spec_linker_default = plugin62;
20073
-
20074
- export { accessibility_auditor_default as accessibilityAuditorPlugin, agent_handoff_default as agentHandoffPlugin, api_compatibility_gate_default as apiCompatibilityGatePlugin, auto_doc_default as autoDocPlugin, auto_escalate_default as autoEscalatePlugin, auto_i18n_extractor_default as autoI18nExtractorPlugin, branch_guard_default as branchGuardPlugin, changelog_writer_default as changelogWriterPlugin, checkpoint_default as checkpointPlugin, code_metrics_default as codeMetricsPlugin, commit_validator_default as commitValidatorPlugin, config_validator_default as configValidatorPlugin, context_pins_default as contextPinsPlugin, cost_tracker_default as costTrackerPlugin, cron_default as cronPlugin, dead_code_detector_default as deadCodeDetectorPlugin, dep_guard_default as depGuardPlugin, dependency_vulnerability_gate_default as dependencyVulnerabilityGatePlugin, diff_summary_default as diffSummaryPlugin, doc_sync_guard_default as docSyncGuardPlugin, duplicate_code_detector_default as duplicateCodeDetectorPlugin, error_lens_default as errorLensPlugin, feature_flag_tracker_default as featureFlagTrackerPlugin, file_watcher_default as fileWatcherPlugin, format_on_save_default as formatOnSavePlugin, git_autocommit_default as gitAutocommitPlugin, import_organizer_default as importOrganizerPlugin, injection_shield_default as injectionShieldPlugin, interface_contract_guard_default as interfaceContractGuardPlugin, knowledge_graph_default as knowledgeGraphPlugin, license_audit_gate_default as licenseAuditGatePlugin, lint_gate_default as lintGatePlugin, llm_cache_default as llmCachePlugin, loop_breaker_default as loopBreakerPlugin, migration_planner_default as migrationPlannerPlugin, model_router_default as modelRouterPlugin, notify_hub_default as notifyHubPlugin, path_guard_default as pathGuardPlugin, performance_regression_gate_default as performanceRegressionGatePlugin, plugin_stack_observer_default as pluginStackObserverPlugin, pr_drafter_default as prDrafterPlugin, prompt_firewall_default as promptFirewallPlugin, refactor_suggester_default as refactorSuggesterPlugin, release_notes_generator_default as releaseNotesGeneratorPlugin, schema_evolution_guard_default as schemaEvolutionGuardPlugin, secret_scanner_default as secretScannerPlugin, security_hotspot_scanner_default as securityHotspotScannerPlugin, semantic_search_indexer_default as semanticSearchIndexerPlugin, semver_bump_default as semverBumpPlugin, session_recap_default as sessionRecapPlugin, shell_check_default as shellCheckPlugin, smart_rename_default as smartRenamePlugin, spec_linker_default as specLinkerPlugin, template_engine_default as templateEnginePlugin, test_coverage_gate_default as testCoverageGatePlugin, test_flake_detector_default as testFlakeDetectorPlugin, test_generator_default as testGeneratorPlugin, test_runner_gate_default as testRunnerGatePlugin, todo_listener_default as todoListenerPlugin, todo_tracker_default as todoTrackerPlugin, token_budget_default as tokenBudgetPlugin, token_throttle_default as tokenThrottlePlugin, type_gate_default as typeGatePlugin };
20562
+ export {
20563
+ accessibility_auditor_default as accessibilityAuditorPlugin,
20564
+ agent_handoff_default as agentHandoffPlugin,
20565
+ api_compatibility_gate_default as apiCompatibilityGatePlugin,
20566
+ auto_doc_default as autoDocPlugin,
20567
+ auto_escalate_default as autoEscalatePlugin,
20568
+ auto_i18n_extractor_default as autoI18nExtractorPlugin,
20569
+ branch_guard_default as branchGuardPlugin,
20570
+ changelog_writer_default as changelogWriterPlugin,
20571
+ checkpoint_default as checkpointPlugin,
20572
+ code_metrics_default as codeMetricsPlugin,
20573
+ commit_validator_default as commitValidatorPlugin,
20574
+ config_validator_default as configValidatorPlugin,
20575
+ context_pins_default as contextPinsPlugin,
20576
+ cost_tracker_default as costTrackerPlugin,
20577
+ cron_default as cronPlugin,
20578
+ dead_code_detector_default as deadCodeDetectorPlugin,
20579
+ dep_guard_default as depGuardPlugin,
20580
+ dependency_vulnerability_gate_default as dependencyVulnerabilityGatePlugin,
20581
+ diff_summary_default as diffSummaryPlugin,
20582
+ doc_sync_guard_default as docSyncGuardPlugin,
20583
+ duplicate_code_detector_default as duplicateCodeDetectorPlugin,
20584
+ error_lens_default as errorLensPlugin,
20585
+ feature_flag_tracker_default as featureFlagTrackerPlugin,
20586
+ file_watcher_default as fileWatcherPlugin,
20587
+ format_on_save_default as formatOnSavePlugin,
20588
+ git_autocommit_default as gitAutocommitPlugin,
20589
+ import_organizer_default as importOrganizerPlugin,
20590
+ injection_shield_default as injectionShieldPlugin,
20591
+ interface_contract_guard_default as interfaceContractGuardPlugin,
20592
+ knowledge_graph_default as knowledgeGraphPlugin,
20593
+ license_audit_gate_default as licenseAuditGatePlugin,
20594
+ lint_gate_default as lintGatePlugin,
20595
+ llm_cache_default as llmCachePlugin,
20596
+ loop_breaker_default as loopBreakerPlugin,
20597
+ migration_planner_default as migrationPlannerPlugin,
20598
+ model_router_default as modelRouterPlugin,
20599
+ notify_hub_default as notifyHubPlugin,
20600
+ path_guard_default as pathGuardPlugin,
20601
+ performance_regression_gate_default as performanceRegressionGatePlugin,
20602
+ plugin_stack_observer_default as pluginStackObserverPlugin,
20603
+ pr_drafter_default as prDrafterPlugin,
20604
+ prompt_firewall_default as promptFirewallPlugin,
20605
+ refactor_suggester_default as refactorSuggesterPlugin,
20606
+ release_notes_generator_default as releaseNotesGeneratorPlugin,
20607
+ schema_evolution_guard_default as schemaEvolutionGuardPlugin,
20608
+ secret_scanner_default as secretScannerPlugin,
20609
+ security_hotspot_scanner_default as securityHotspotScannerPlugin,
20610
+ semantic_search_indexer_default as semanticSearchIndexerPlugin,
20611
+ semver_bump_default as semverBumpPlugin,
20612
+ session_recap_default as sessionRecapPlugin,
20613
+ shell_check_default as shellCheckPlugin,
20614
+ smart_rename_default as smartRenamePlugin,
20615
+ spec_linker_default as specLinkerPlugin,
20616
+ template_engine_default as templateEnginePlugin,
20617
+ test_coverage_gate_default as testCoverageGatePlugin,
20618
+ test_flake_detector_default as testFlakeDetectorPlugin,
20619
+ test_generator_default as testGeneratorPlugin,
20620
+ test_runner_gate_default as testRunnerGatePlugin,
20621
+ todo_listener_default as todoListenerPlugin,
20622
+ todo_tracker_default as todoTrackerPlugin,
20623
+ token_budget_default as tokenBudgetPlugin,
20624
+ token_throttle_default as tokenThrottlePlugin,
20625
+ type_gate_default as typeGatePlugin
20626
+ };