@delegance/claude-autopilot 5.0.0 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. package/dist/presets/go/rules/go-sql-injection.d.ts +4 -0
  2. package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.d.ts +4 -0
  3. package/dist/presets/python-fastapi/rules/fastapi-missing-auth.d.ts +4 -0
  4. package/dist/presets/rails-postgres/rules/rails-sql-injection.d.ts +4 -0
  5. package/dist/presets/t3/rules/t3-server-only.d.ts +4 -0
  6. package/dist/src/adapters/base.d.ts +11 -0
  7. package/dist/src/adapters/council/claude.d.ts +3 -0
  8. package/dist/src/adapters/council/openai.d.ts +3 -0
  9. package/dist/src/adapters/council/types.d.ts +5 -0
  10. package/dist/src/adapters/loader.d.ts +11 -0
  11. package/dist/src/adapters/migration-runner/supabase.d.ts +4 -0
  12. package/dist/src/adapters/migration-runner/types.d.ts +31 -0
  13. package/dist/src/adapters/review-bot-parser/cursor.d.ts +3 -0
  14. package/dist/src/adapters/review-bot-parser/declarative-base.d.ts +13 -0
  15. package/{src/adapters/review-bot-parser/types.ts → dist/src/adapters/review-bot-parser/types.d.ts} +4 -4
  16. package/dist/src/adapters/review-engine/auto.d.ts +4 -0
  17. package/dist/src/adapters/review-engine/claude.d.ts +4 -0
  18. package/dist/src/adapters/review-engine/codex.d.ts +4 -0
  19. package/dist/src/adapters/review-engine/gemini.d.ts +4 -0
  20. package/dist/src/adapters/review-engine/openai-compatible.d.ts +4 -0
  21. package/dist/src/adapters/review-engine/parse-output.d.ts +13 -0
  22. package/dist/src/adapters/review-engine/prompt-builder.d.ts +4 -0
  23. package/dist/src/adapters/review-engine/types.d.ts +28 -0
  24. package/dist/src/adapters/vcs-host/commit-status.d.ts +12 -0
  25. package/dist/src/adapters/vcs-host/github.d.ts +4 -0
  26. package/dist/src/adapters/vcs-host/types.d.ts +42 -0
  27. package/{src/cli/_pkg-root.ts → dist/src/cli/_pkg-root.d.ts} +4 -42
  28. package/dist/src/cli/autoregress-bridge.d.ts +3 -0
  29. package/dist/src/cli/baseline.d.ts +7 -0
  30. package/dist/src/cli/ci.d.ts +23 -0
  31. package/dist/src/cli/costs.d.ts +2 -0
  32. package/dist/src/cli/council.d.ts +8 -0
  33. package/dist/src/cli/detector.d.ts +8 -0
  34. package/dist/src/cli/explain.d.ts +8 -0
  35. package/dist/src/cli/fix.d.ts +10 -0
  36. package/dist/src/cli/hook.d.ts +9 -0
  37. package/dist/src/cli/ignore-helper.d.ts +7 -0
  38. package/dist/src/cli/index.d.ts +3 -0
  39. package/dist/src/cli/index.js +39 -1
  40. package/dist/src/cli/lsp.d.ts +29 -0
  41. package/dist/src/cli/mcp.d.ts +5 -0
  42. package/dist/src/cli/migrate-v4.d.ts +28 -0
  43. package/dist/src/cli/pr-comment.d.ts +13 -0
  44. package/dist/src/cli/pr-desc.d.ts +31 -0
  45. package/dist/src/cli/pr-review-comments.d.ts +12 -0
  46. package/dist/src/cli/pr.d.ts +9 -0
  47. package/dist/src/cli/preflight.d.ts +8 -0
  48. package/dist/src/cli/preflight.js +17 -4
  49. package/dist/src/cli/report.d.ts +7 -0
  50. package/dist/src/cli/run.d.ts +23 -0
  51. package/dist/src/cli/scan.d.ts +11 -0
  52. package/dist/src/cli/setup.d.ts +9 -0
  53. package/dist/src/cli/test-gen.d.ts +10 -0
  54. package/dist/src/cli/triage.d.ts +5 -0
  55. package/dist/src/cli/watch.d.ts +18 -0
  56. package/dist/src/cli/worker.d.ts +5 -0
  57. package/dist/src/core/cache/cached-engine.d.ts +8 -0
  58. package/dist/src/core/cache/review-cache.d.ts +21 -0
  59. package/dist/src/core/chunking/index.d.ts +18 -0
  60. package/dist/src/core/chunking/risk-ranker.d.ts +10 -0
  61. package/dist/src/core/config/loader.d.ts +3 -0
  62. package/dist/src/core/config/preset-resolver.d.ts +9 -0
  63. package/dist/src/core/config/schema.d.ts +342 -0
  64. package/dist/src/core/config/types.d.ts +115 -0
  65. package/dist/src/core/council/config.d.ts +3 -0
  66. package/dist/src/core/council/context.d.ts +2 -0
  67. package/dist/src/core/council/runner.d.ts +4 -0
  68. package/dist/src/core/council/types.d.ts +36 -0
  69. package/dist/src/core/detect/git-context.d.ts +12 -0
  70. package/dist/src/core/detect/llm-key.d.ts +38 -0
  71. package/dist/src/core/detect/protected-paths.d.ts +6 -0
  72. package/dist/src/core/detect/provider-usage.d.ts +17 -0
  73. package/dist/src/core/detect/stack.d.ts +6 -0
  74. package/dist/src/core/detect/workspaces.d.ts +11 -0
  75. package/dist/src/core/errors.d.ts +17 -0
  76. package/dist/src/core/findings/dedup.d.ts +4 -0
  77. package/dist/src/core/findings/types.d.ts +33 -0
  78. package/dist/src/core/fix/generator.d.ts +17 -0
  79. package/dist/src/core/git/diff-hunks.d.ts +22 -0
  80. package/dist/src/core/git/touched-files.d.ts +11 -0
  81. package/dist/src/core/ignore/index.d.ts +11 -0
  82. package/dist/src/core/index.d.ts +2 -0
  83. package/dist/src/core/logging/ndjson-writer.d.ts +16 -0
  84. package/dist/src/core/logging/redaction.d.ts +4 -0
  85. package/dist/src/core/mcp/concurrency.d.ts +2 -0
  86. package/dist/src/core/mcp/handlers/fix-finding.d.ts +17 -0
  87. package/dist/src/core/mcp/handlers/get-capabilities.d.ts +14 -0
  88. package/dist/src/core/mcp/handlers/get-findings.d.ts +13 -0
  89. package/dist/src/core/mcp/handlers/review-diff.d.ts +18 -0
  90. package/dist/src/core/mcp/handlers/scan-files.d.ts +15 -0
  91. package/dist/src/core/mcp/handlers/validate-fix.d.ts +12 -0
  92. package/dist/src/core/mcp/run-store.d.ts +12 -0
  93. package/dist/src/core/mcp/workspace.d.ts +3 -0
  94. package/dist/src/core/persist/baseline.d.ts +39 -0
  95. package/dist/src/core/persist/cost-log.d.ts +11 -0
  96. package/dist/src/core/persist/findings-cache.d.ts +9 -0
  97. package/dist/src/core/persist/triage.d.ts +30 -0
  98. package/dist/src/core/phases/static-rules.d.ts +24 -0
  99. package/dist/src/core/phases/tests.d.ts +15 -0
  100. package/dist/src/core/pipeline/review-phase.d.ts +27 -0
  101. package/dist/src/core/pipeline/run.d.ts +27 -0
  102. package/dist/src/core/runtime/idempotency.d.ts +2 -0
  103. package/dist/src/core/runtime/lock.d.ts +5 -0
  104. package/dist/src/core/runtime/state.d.ts +39 -0
  105. package/dist/src/core/schema-alignment/detector.d.ts +3 -0
  106. package/dist/src/core/schema-alignment/extractor/index.d.ts +3 -0
  107. package/dist/src/core/schema-alignment/extractor/prisma.d.ts +3 -0
  108. package/dist/src/core/schema-alignment/extractor/sql.d.ts +3 -0
  109. package/dist/src/core/schema-alignment/llm-check.d.ts +4 -0
  110. package/dist/src/core/schema-alignment/scanner.d.ts +3 -0
  111. package/dist/src/core/schema-alignment/types.d.ts +38 -0
  112. package/dist/src/core/shell.d.ts +15 -0
  113. package/dist/src/core/static-rules/registry.d.ts +5 -0
  114. package/dist/src/core/static-rules/rules/brand-tokens.d.ts +3 -0
  115. package/dist/src/core/static-rules/rules/console-log.d.ts +3 -0
  116. package/dist/src/core/static-rules/rules/hardcoded-secrets.d.ts +3 -0
  117. package/dist/src/core/static-rules/rules/insecure-redirect.d.ts +3 -0
  118. package/dist/src/core/static-rules/rules/large-file.d.ts +3 -0
  119. package/dist/src/core/static-rules/rules/missing-auth.d.ts +3 -0
  120. package/dist/src/core/static-rules/rules/missing-tests.d.ts +3 -0
  121. package/dist/src/core/static-rules/rules/npm-audit.d.ts +3 -0
  122. package/dist/src/core/static-rules/rules/package-lock-sync.d.ts +3 -0
  123. package/dist/src/core/static-rules/rules/schema-alignment.d.ts +3 -0
  124. package/dist/src/core/static-rules/rules/sql-injection.d.ts +3 -0
  125. package/dist/src/core/static-rules/rules/ssrf.d.ts +3 -0
  126. package/dist/src/core/static-rules/rules/todo-fixme.d.ts +3 -0
  127. package/dist/src/core/static-rules/tailwind-extractor.d.ts +7 -0
  128. package/dist/src/core/test-gen/coverage-analyzer.d.ts +7 -0
  129. package/dist/src/core/test-gen/framework-detector.d.ts +3 -0
  130. package/dist/src/core/test-gen/test-writer.d.ts +4 -0
  131. package/dist/src/core/ui/design-context-loader.d.ts +7 -0
  132. package/dist/src/core/worker/client.d.ts +23 -0
  133. package/dist/src/core/worker/lockfile.d.ts +12 -0
  134. package/dist/src/core/worker/server.d.ts +17 -0
  135. package/dist/src/formatters/github-annotations.d.ts +5 -0
  136. package/{src/formatters/index.ts → dist/src/formatters/index.d.ts} +1 -0
  137. package/dist/src/formatters/junit.d.ts +5 -0
  138. package/dist/src/formatters/sarif.d.ts +56 -0
  139. package/{src/index.ts → dist/src/index.d.ts} +1 -0
  140. package/package.json +7 -6
  141. package/dist/presets/go/rules/go-sql-injection.js.map +0 -1
  142. package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.js.map +0 -1
  143. package/dist/presets/python-fastapi/rules/fastapi-missing-auth.js.map +0 -1
  144. package/dist/presets/rails-postgres/rules/rails-sql-injection.js.map +0 -1
  145. package/dist/presets/t3/rules/t3-server-only.js.map +0 -1
  146. package/dist/src/adapters/base.js.map +0 -1
  147. package/dist/src/adapters/council/claude.js.map +0 -1
  148. package/dist/src/adapters/council/openai.js.map +0 -1
  149. package/dist/src/adapters/council/types.js.map +0 -1
  150. package/dist/src/adapters/loader.js.map +0 -1
  151. package/dist/src/adapters/migration-runner/supabase.js.map +0 -1
  152. package/dist/src/adapters/migration-runner/types.js.map +0 -1
  153. package/dist/src/adapters/review-bot-parser/cursor.js.map +0 -1
  154. package/dist/src/adapters/review-bot-parser/declarative-base.js.map +0 -1
  155. package/dist/src/adapters/review-bot-parser/types.js.map +0 -1
  156. package/dist/src/adapters/review-engine/auto.js.map +0 -1
  157. package/dist/src/adapters/review-engine/claude.js.map +0 -1
  158. package/dist/src/adapters/review-engine/codex.js.map +0 -1
  159. package/dist/src/adapters/review-engine/gemini.js.map +0 -1
  160. package/dist/src/adapters/review-engine/openai-compatible.js.map +0 -1
  161. package/dist/src/adapters/review-engine/parse-output.js.map +0 -1
  162. package/dist/src/adapters/review-engine/prompt-builder.js.map +0 -1
  163. package/dist/src/adapters/review-engine/types.js.map +0 -1
  164. package/dist/src/adapters/vcs-host/commit-status.js.map +0 -1
  165. package/dist/src/adapters/vcs-host/github.js.map +0 -1
  166. package/dist/src/adapters/vcs-host/types.js.map +0 -1
  167. package/dist/src/cli/_pkg-root.js.map +0 -1
  168. package/dist/src/cli/autoregress-bridge.js.map +0 -1
  169. package/dist/src/cli/baseline.js.map +0 -1
  170. package/dist/src/cli/ci.js.map +0 -1
  171. package/dist/src/cli/costs.js.map +0 -1
  172. package/dist/src/cli/council.js.map +0 -1
  173. package/dist/src/cli/detector.js.map +0 -1
  174. package/dist/src/cli/explain.js.map +0 -1
  175. package/dist/src/cli/fix.js.map +0 -1
  176. package/dist/src/cli/hook.js.map +0 -1
  177. package/dist/src/cli/ignore-helper.js.map +0 -1
  178. package/dist/src/cli/index.js.map +0 -1
  179. package/dist/src/cli/lsp.js.map +0 -1
  180. package/dist/src/cli/mcp.js.map +0 -1
  181. package/dist/src/cli/migrate-v4.js.map +0 -1
  182. package/dist/src/cli/pr-comment.js.map +0 -1
  183. package/dist/src/cli/pr-desc.js.map +0 -1
  184. package/dist/src/cli/pr-review-comments.js.map +0 -1
  185. package/dist/src/cli/pr.js.map +0 -1
  186. package/dist/src/cli/preflight.js.map +0 -1
  187. package/dist/src/cli/report.js.map +0 -1
  188. package/dist/src/cli/run.js.map +0 -1
  189. package/dist/src/cli/scan.js.map +0 -1
  190. package/dist/src/cli/setup.js.map +0 -1
  191. package/dist/src/cli/test-gen.js.map +0 -1
  192. package/dist/src/cli/triage.js.map +0 -1
  193. package/dist/src/cli/watch.js.map +0 -1
  194. package/dist/src/cli/worker.js.map +0 -1
  195. package/dist/src/core/cache/cached-engine.js.map +0 -1
  196. package/dist/src/core/cache/review-cache.js.map +0 -1
  197. package/dist/src/core/chunking/index.js.map +0 -1
  198. package/dist/src/core/chunking/risk-ranker.js.map +0 -1
  199. package/dist/src/core/config/loader.js.map +0 -1
  200. package/dist/src/core/config/preset-resolver.js.map +0 -1
  201. package/dist/src/core/config/schema.js.map +0 -1
  202. package/dist/src/core/config/types.js.map +0 -1
  203. package/dist/src/core/council/config.js.map +0 -1
  204. package/dist/src/core/council/context.js.map +0 -1
  205. package/dist/src/core/council/runner.js.map +0 -1
  206. package/dist/src/core/council/types.js.map +0 -1
  207. package/dist/src/core/detect/git-context.js.map +0 -1
  208. package/dist/src/core/detect/llm-key.js.map +0 -1
  209. package/dist/src/core/detect/protected-paths.js.map +0 -1
  210. package/dist/src/core/detect/provider-usage.js.map +0 -1
  211. package/dist/src/core/detect/stack.js.map +0 -1
  212. package/dist/src/core/detect/workspaces.js.map +0 -1
  213. package/dist/src/core/errors.js.map +0 -1
  214. package/dist/src/core/findings/dedup.js.map +0 -1
  215. package/dist/src/core/findings/types.js.map +0 -1
  216. package/dist/src/core/fix/generator.js.map +0 -1
  217. package/dist/src/core/git/diff-hunks.js.map +0 -1
  218. package/dist/src/core/git/touched-files.js.map +0 -1
  219. package/dist/src/core/ignore/index.js.map +0 -1
  220. package/dist/src/core/index.js.map +0 -1
  221. package/dist/src/core/logging/ndjson-writer.js.map +0 -1
  222. package/dist/src/core/logging/redaction.js.map +0 -1
  223. package/dist/src/core/mcp/concurrency.js.map +0 -1
  224. package/dist/src/core/mcp/handlers/fix-finding.js.map +0 -1
  225. package/dist/src/core/mcp/handlers/get-capabilities.js.map +0 -1
  226. package/dist/src/core/mcp/handlers/get-findings.js.map +0 -1
  227. package/dist/src/core/mcp/handlers/review-diff.js.map +0 -1
  228. package/dist/src/core/mcp/handlers/scan-files.js.map +0 -1
  229. package/dist/src/core/mcp/handlers/validate-fix.js.map +0 -1
  230. package/dist/src/core/mcp/run-store.js.map +0 -1
  231. package/dist/src/core/mcp/workspace.js.map +0 -1
  232. package/dist/src/core/persist/baseline.js.map +0 -1
  233. package/dist/src/core/persist/cost-log.js.map +0 -1
  234. package/dist/src/core/persist/findings-cache.js.map +0 -1
  235. package/dist/src/core/persist/triage.js.map +0 -1
  236. package/dist/src/core/phases/static-rules.js.map +0 -1
  237. package/dist/src/core/phases/tests.js.map +0 -1
  238. package/dist/src/core/pipeline/review-phase.js.map +0 -1
  239. package/dist/src/core/pipeline/run.js.map +0 -1
  240. package/dist/src/core/runtime/idempotency.js.map +0 -1
  241. package/dist/src/core/runtime/lock.js.map +0 -1
  242. package/dist/src/core/runtime/state.js.map +0 -1
  243. package/dist/src/core/schema-alignment/detector.js.map +0 -1
  244. package/dist/src/core/schema-alignment/extractor/index.js.map +0 -1
  245. package/dist/src/core/schema-alignment/extractor/prisma.js.map +0 -1
  246. package/dist/src/core/schema-alignment/extractor/sql.js.map +0 -1
  247. package/dist/src/core/schema-alignment/llm-check.js.map +0 -1
  248. package/dist/src/core/schema-alignment/scanner.js.map +0 -1
  249. package/dist/src/core/schema-alignment/types.js.map +0 -1
  250. package/dist/src/core/shell.js.map +0 -1
  251. package/dist/src/core/static-rules/registry.js.map +0 -1
  252. package/dist/src/core/static-rules/rules/brand-tokens.js.map +0 -1
  253. package/dist/src/core/static-rules/rules/console-log.js.map +0 -1
  254. package/dist/src/core/static-rules/rules/hardcoded-secrets.js.map +0 -1
  255. package/dist/src/core/static-rules/rules/insecure-redirect.js.map +0 -1
  256. package/dist/src/core/static-rules/rules/large-file.js.map +0 -1
  257. package/dist/src/core/static-rules/rules/missing-auth.js.map +0 -1
  258. package/dist/src/core/static-rules/rules/missing-tests.js.map +0 -1
  259. package/dist/src/core/static-rules/rules/npm-audit.js.map +0 -1
  260. package/dist/src/core/static-rules/rules/package-lock-sync.js.map +0 -1
  261. package/dist/src/core/static-rules/rules/schema-alignment.js.map +0 -1
  262. package/dist/src/core/static-rules/rules/sql-injection.js.map +0 -1
  263. package/dist/src/core/static-rules/rules/ssrf.js.map +0 -1
  264. package/dist/src/core/static-rules/rules/todo-fixme.js.map +0 -1
  265. package/dist/src/core/static-rules/tailwind-extractor.js.map +0 -1
  266. package/dist/src/core/test-gen/coverage-analyzer.js.map +0 -1
  267. package/dist/src/core/test-gen/framework-detector.js.map +0 -1
  268. package/dist/src/core/test-gen/test-writer.js.map +0 -1
  269. package/dist/src/core/ui/design-context-loader.js.map +0 -1
  270. package/dist/src/core/worker/client.js.map +0 -1
  271. package/dist/src/core/worker/lockfile.js.map +0 -1
  272. package/dist/src/core/worker/server.js.map +0 -1
  273. package/dist/src/formatters/github-annotations.js.map +0 -1
  274. package/dist/src/formatters/index.js.map +0 -1
  275. package/dist/src/formatters/junit.js.map +0 -1
  276. package/dist/src/formatters/sarif.js.map +0 -1
  277. package/dist/src/index.js.map +0 -1
  278. package/src/adapters/base.ts +0 -19
  279. package/src/adapters/council/claude.ts +0 -41
  280. package/src/adapters/council/openai.ts +0 -40
  281. package/src/adapters/council/types.ts +0 -7
  282. package/src/adapters/loader.ts +0 -108
  283. package/src/adapters/migration-runner/supabase.ts +0 -56
  284. package/src/adapters/migration-runner/types.ts +0 -36
  285. package/src/adapters/review-bot-parser/cursor.ts +0 -13
  286. package/src/adapters/review-bot-parser/declarative-base.ts +0 -64
  287. package/src/adapters/review-engine/auto.ts +0 -94
  288. package/src/adapters/review-engine/claude.ts +0 -100
  289. package/src/adapters/review-engine/codex.ts +0 -82
  290. package/src/adapters/review-engine/gemini.ts +0 -105
  291. package/src/adapters/review-engine/openai-compatible.ts +0 -100
  292. package/src/adapters/review-engine/parse-output.ts +0 -74
  293. package/src/adapters/review-engine/prompt-builder.ts +0 -19
  294. package/src/adapters/review-engine/types.ts +0 -19
  295. package/src/adapters/vcs-host/commit-status.ts +0 -39
  296. package/src/adapters/vcs-host/github.ts +0 -77
  297. package/src/adapters/vcs-host/types.ts +0 -44
  298. package/src/cli/autoregress-bridge.ts +0 -30
  299. package/src/cli/baseline.ts +0 -125
  300. package/src/cli/ci.ts +0 -45
  301. package/src/cli/costs.ts +0 -80
  302. package/src/cli/council.ts +0 -96
  303. package/src/cli/detector.ts +0 -92
  304. package/src/cli/explain.ts +0 -197
  305. package/src/cli/fix.ts +0 -249
  306. package/src/cli/hook.ts +0 -124
  307. package/src/cli/ignore-helper.ts +0 -116
  308. package/src/cli/index.ts +0 -612
  309. package/src/cli/lsp.ts +0 -200
  310. package/src/cli/mcp.ts +0 -206
  311. package/src/cli/migrate-v4.ts +0 -388
  312. package/src/cli/pr-comment.ts +0 -139
  313. package/src/cli/pr-desc.ts +0 -168
  314. package/src/cli/pr-review-comments.ts +0 -92
  315. package/src/cli/pr.ts +0 -76
  316. package/src/cli/preflight.ts +0 -235
  317. package/src/cli/report.ts +0 -186
  318. package/src/cli/run.ts +0 -425
  319. package/src/cli/scan.ts +0 -233
  320. package/src/cli/setup.ts +0 -191
  321. package/src/cli/test-gen.ts +0 -125
  322. package/src/cli/triage.ts +0 -137
  323. package/src/cli/watch.ts +0 -190
  324. package/src/cli/worker.ts +0 -109
  325. package/src/core/.gitkeep +0 -0
  326. package/src/core/cache/cached-engine.ts +0 -32
  327. package/src/core/cache/review-cache.ts +0 -70
  328. package/src/core/chunking/index.ts +0 -113
  329. package/src/core/chunking/risk-ranker.ts +0 -56
  330. package/src/core/config/loader.ts +0 -53
  331. package/src/core/config/preset-resolver.ts +0 -46
  332. package/src/core/config/schema.ts +0 -181
  333. package/src/core/config/types.ts +0 -98
  334. package/src/core/council/config.ts +0 -71
  335. package/src/core/council/context.ts +0 -17
  336. package/src/core/council/runner.ts +0 -83
  337. package/src/core/council/types.ts +0 -45
  338. package/src/core/detect/git-context.ts +0 -27
  339. package/src/core/detect/llm-key.ts +0 -89
  340. package/src/core/detect/protected-paths.ts +0 -63
  341. package/src/core/detect/provider-usage.ts +0 -74
  342. package/src/core/detect/stack.ts +0 -153
  343. package/src/core/detect/workspaces.ts +0 -103
  344. package/src/core/errors.ts +0 -37
  345. package/src/core/findings/dedup.ts +0 -14
  346. package/src/core/findings/types.ts +0 -39
  347. package/src/core/fix/generator.ts +0 -149
  348. package/src/core/git/diff-hunks.ts +0 -86
  349. package/src/core/git/touched-files.ts +0 -73
  350. package/src/core/ignore/index.ts +0 -54
  351. package/src/core/index.ts +0 -1
  352. package/src/core/logging/ndjson-writer.ts +0 -37
  353. package/src/core/logging/redaction.ts +0 -19
  354. package/src/core/mcp/concurrency.ts +0 -16
  355. package/src/core/mcp/handlers/fix-finding.ts +0 -126
  356. package/src/core/mcp/handlers/get-capabilities.ts +0 -62
  357. package/src/core/mcp/handlers/get-findings.ts +0 -36
  358. package/src/core/mcp/handlers/review-diff.ts +0 -65
  359. package/src/core/mcp/handlers/scan-files.ts +0 -65
  360. package/src/core/mcp/handlers/validate-fix.ts +0 -41
  361. package/src/core/mcp/run-store.ts +0 -85
  362. package/src/core/mcp/workspace.ts +0 -35
  363. package/src/core/persist/baseline.ts +0 -112
  364. package/src/core/persist/cost-log.ts +0 -30
  365. package/src/core/persist/findings-cache.ts +0 -43
  366. package/src/core/persist/triage.ts +0 -112
  367. package/src/core/phases/static-rules.ts +0 -93
  368. package/src/core/phases/tests.ts +0 -51
  369. package/src/core/pipeline/review-phase.ts +0 -182
  370. package/src/core/pipeline/run.ts +0 -116
  371. package/src/core/runtime/idempotency.ts +0 -6
  372. package/src/core/runtime/lock.ts +0 -29
  373. package/src/core/runtime/state.ts +0 -97
  374. package/src/core/schema-alignment/detector.ts +0 -59
  375. package/src/core/schema-alignment/extractor/index.ts +0 -24
  376. package/src/core/schema-alignment/extractor/prisma.ts +0 -21
  377. package/src/core/schema-alignment/extractor/sql.ts +0 -99
  378. package/src/core/schema-alignment/llm-check.ts +0 -91
  379. package/src/core/schema-alignment/scanner.ts +0 -107
  380. package/src/core/schema-alignment/types.ts +0 -43
  381. package/src/core/shell.ts +0 -48
  382. package/src/core/static-rules/registry.ts +0 -59
  383. package/src/core/static-rules/rules/brand-tokens.ts +0 -145
  384. package/src/core/static-rules/rules/console-log.ts +0 -42
  385. package/src/core/static-rules/rules/hardcoded-secrets.ts +0 -83
  386. package/src/core/static-rules/rules/insecure-redirect.ts +0 -67
  387. package/src/core/static-rules/rules/large-file.ts +0 -37
  388. package/src/core/static-rules/rules/missing-auth.ts +0 -70
  389. package/src/core/static-rules/rules/missing-tests.ts +0 -57
  390. package/src/core/static-rules/rules/npm-audit.ts +0 -38
  391. package/src/core/static-rules/rules/package-lock-sync.ts +0 -54
  392. package/src/core/static-rules/rules/schema-alignment.ts +0 -132
  393. package/src/core/static-rules/rules/sql-injection.ts +0 -71
  394. package/src/core/static-rules/rules/ssrf.ts +0 -63
  395. package/src/core/static-rules/rules/todo-fixme.ts +0 -40
  396. package/src/core/static-rules/tailwind-extractor.ts +0 -38
  397. package/src/core/test-gen/coverage-analyzer.ts +0 -93
  398. package/src/core/test-gen/framework-detector.ts +0 -21
  399. package/src/core/test-gen/test-writer.ts +0 -33
  400. package/src/core/ui/design-context-loader.ts +0 -87
  401. package/src/core/worker/client.ts +0 -46
  402. package/src/core/worker/lockfile.ts +0 -38
  403. package/src/core/worker/server.ts +0 -81
  404. package/src/formatters/github-annotations.ts +0 -36
  405. package/src/formatters/junit.ts +0 -52
  406. package/src/formatters/sarif.ts +0 -103
@@ -1,112 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import type { Finding } from '../findings/types.ts';
4
-
5
- const BASELINE_FILE = '.guardrail-baseline.json';
6
-
7
- export interface BaselineEntry {
8
- id: string;
9
- file: string;
10
- line?: number;
11
- severity: string;
12
- message: string;
13
- pinnedAt: string;
14
- note?: string;
15
- }
16
-
17
- export interface Baseline {
18
- version: 1;
19
- createdAt: string;
20
- updatedAt: string;
21
- note?: string;
22
- entries: BaselineEntry[];
23
- }
24
-
25
- /** Stable key for matching a finding against a baseline entry. */
26
- function baselineKey(f: { id: string; file: string; line?: number }): string {
27
- return `${f.id}::${f.file}::${f.line ?? ''}`;
28
- }
29
-
30
- export function baselineFilePath(cwd: string, overridePath?: string): string {
31
- return overridePath
32
- ? path.isAbsolute(overridePath) ? overridePath : path.join(cwd, overridePath)
33
- : path.join(cwd, BASELINE_FILE);
34
- }
35
-
36
- export function loadBaseline(cwd: string, overridePath?: string): Baseline | null {
37
- const p = baselineFilePath(cwd, overridePath);
38
- if (!fs.existsSync(p)) return null;
39
- try {
40
- return JSON.parse(fs.readFileSync(p, 'utf8')) as Baseline;
41
- } catch {
42
- return null;
43
- }
44
- }
45
-
46
- export function saveBaseline(cwd: string, findings: Finding[], options: { note?: string; overridePath?: string } = {}): Baseline {
47
- const existing = loadBaseline(cwd, options.overridePath);
48
- const now = new Date().toISOString();
49
- const baseline: Baseline = {
50
- version: 1,
51
- createdAt: existing?.createdAt ?? now,
52
- updatedAt: now,
53
- note: options.note ?? existing?.note,
54
- entries: findings.map(f => ({
55
- id: f.id,
56
- file: f.file,
57
- line: f.line,
58
- severity: f.severity,
59
- message: f.message,
60
- pinnedAt: now,
61
- })),
62
- };
63
- const p = baselineFilePath(cwd, options.overridePath);
64
- const tmp = p + '.tmp';
65
- fs.writeFileSync(tmp, JSON.stringify(baseline, null, 2), 'utf8');
66
- fs.renameSync(tmp, p);
67
- return baseline;
68
- }
69
-
70
- export function clearBaseline(cwd: string, overridePath?: string): void {
71
- const p = baselineFilePath(cwd, overridePath);
72
- if (fs.existsSync(p)) fs.unlinkSync(p);
73
- }
74
-
75
- export interface BaselineFilterResult {
76
- newFindings: Finding[];
77
- baselinedFindings: Finding[];
78
- baselinedCount: number;
79
- }
80
-
81
- /** Returns findings NOT present in the baseline (new findings only). */
82
- export function filterBaselined(findings: Finding[], baseline: Baseline): BaselineFilterResult {
83
- const pinned = new Set(baseline.entries.map(baselineKey));
84
- const newFindings: Finding[] = [];
85
- const baselinedFindings: Finding[] = [];
86
- for (const f of findings) {
87
- if (pinned.has(baselineKey(f))) {
88
- baselinedFindings.push(f);
89
- } else {
90
- newFindings.push(f);
91
- }
92
- }
93
- return { newFindings, baselinedFindings, baselinedCount: baselinedFindings.length };
94
- }
95
-
96
- export interface BaselineDiff {
97
- added: Finding[]; // in current but not in baseline
98
- resolved: BaselineEntry[]; // in baseline but not in current
99
- unchanged: Finding[]; // in both
100
- }
101
-
102
- /** Diff current findings against a baseline snapshot. */
103
- export function diffAgainstBaseline(current: Finding[], baseline: Baseline): BaselineDiff {
104
- const currentKeys = new Set(current.map(baselineKey));
105
- const baselineKeys = new Set(baseline.entries.map(baselineKey));
106
-
107
- return {
108
- added: current.filter(f => !baselineKeys.has(baselineKey(f))),
109
- resolved: baseline.entries.filter(e => !currentKeys.has(baselineKey(e))),
110
- unchanged: current.filter(f => baselineKeys.has(baselineKey(f))),
111
- };
112
- }
@@ -1,30 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
-
4
- const CACHE_DIR = '.guardrail-cache';
5
- const LOG_FILE = 'costs.jsonl';
6
-
7
- export interface CostLogEntry {
8
- timestamp: string;
9
- files: number;
10
- inputTokens: number;
11
- outputTokens: number;
12
- costUSD: number;
13
- durationMs: number;
14
- }
15
-
16
- export function appendCostLog(cwd: string, entry: CostLogEntry): void {
17
- const dir = path.join(cwd, CACHE_DIR);
18
- fs.mkdirSync(dir, { recursive: true });
19
- fs.appendFileSync(path.join(dir, LOG_FILE), JSON.stringify(entry) + '\n', 'utf8');
20
- }
21
-
22
- export function readCostLog(cwd: string): CostLogEntry[] {
23
- const p = path.join(cwd, CACHE_DIR, LOG_FILE);
24
- if (!fs.existsSync(p)) return [];
25
- return fs.readFileSync(p, 'utf8')
26
- .split('\n')
27
- .filter(Boolean)
28
- .map(line => { try { return JSON.parse(line) as CostLogEntry; } catch { return null; } })
29
- .filter((e): e is CostLogEntry => e !== null);
30
- }
@@ -1,43 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import type { Finding } from '../findings/types.ts';
4
-
5
- const CACHE_DIR = '.guardrail-cache';
6
- const CACHE_FILE = 'findings.json';
7
-
8
- function cacheFilePath(cwd: string): string {
9
- return path.join(cwd, CACHE_DIR, CACHE_FILE);
10
- }
11
-
12
- function findingKey(f: Finding): string {
13
- return `${f.id}::${f.file}::${f.line ?? ''}`;
14
- }
15
-
16
- export function loadCachedFindings(cwd: string): Finding[] {
17
- const p = cacheFilePath(cwd);
18
- if (!fs.existsSync(p)) return [];
19
- try {
20
- return JSON.parse(fs.readFileSync(p, 'utf8')) as Finding[];
21
- } catch {
22
- return [];
23
- }
24
- }
25
-
26
- export function saveCachedFindings(cwd: string, findings: Finding[]): void {
27
- const dir = path.join(cwd, CACHE_DIR);
28
- fs.mkdirSync(dir, { recursive: true });
29
- // atomic write
30
- const tmp = cacheFilePath(cwd) + '.tmp';
31
- fs.writeFileSync(tmp, JSON.stringify(findings, null, 2), 'utf8');
32
- fs.renameSync(tmp, cacheFilePath(cwd));
33
- }
34
-
35
- /**
36
- * Returns only findings not present in the cached baseline.
37
- * Two findings are considered the same when id + file + line all match.
38
- */
39
- export function filterNewFindings(current: Finding[], cached: Finding[]): Finding[] {
40
- if (cached.length === 0) return current;
41
- const seen = new Set(cached.map(findingKey));
42
- return current.filter(f => !seen.has(findingKey(f)));
43
- }
@@ -1,112 +0,0 @@
1
- import * as fs from 'node:fs';
2
- import * as path from 'node:path';
3
- import type { Finding } from '../findings/types.ts';
4
-
5
- const TRIAGE_FILE = '.guardrail-triage.json';
6
-
7
- export type TriageState = 'accepted-risk' | 'false-positive';
8
-
9
- export interface TriageEntry {
10
- id: string;
11
- file: string;
12
- line?: number;
13
- state: TriageState;
14
- reason?: string;
15
- triagedAt: string;
16
- expiresAt?: string;
17
- }
18
-
19
- export interface TriageStore {
20
- version: 1;
21
- entries: TriageEntry[];
22
- }
23
-
24
- function triageFilePath(cwd: string): string {
25
- return path.join(cwd, TRIAGE_FILE);
26
- }
27
-
28
- function entryKey(e: { id: string; file: string; line?: number }): string {
29
- return `${e.id}::${e.file}::${e.line ?? ''}`;
30
- }
31
-
32
- export function loadTriage(cwd: string): TriageStore {
33
- const p = triageFilePath(cwd);
34
- if (!fs.existsSync(p)) return { version: 1, entries: [] };
35
- try {
36
- return JSON.parse(fs.readFileSync(p, 'utf8')) as TriageStore;
37
- } catch {
38
- return { version: 1, entries: [] };
39
- }
40
- }
41
-
42
- export function saveTriage(cwd: string, store: TriageStore): void {
43
- const p = triageFilePath(cwd);
44
- const tmp = p + '.tmp';
45
- fs.writeFileSync(tmp, JSON.stringify(store, null, 2), 'utf8');
46
- fs.renameSync(tmp, p);
47
- }
48
-
49
- export function addTriageEntry(
50
- cwd: string,
51
- finding: Finding,
52
- state: TriageState,
53
- options: { reason?: string; expiresInDays?: number } = {},
54
- ): void {
55
- const store = loadTriage(cwd);
56
- const key = entryKey(finding);
57
- store.entries = store.entries.filter(e => entryKey(e) !== key);
58
- const entry: TriageEntry = {
59
- id: finding.id,
60
- file: finding.file,
61
- line: finding.line,
62
- state,
63
- reason: options.reason,
64
- triagedAt: new Date().toISOString(),
65
- };
66
- if (options.expiresInDays !== undefined) {
67
- const exp = new Date();
68
- exp.setDate(exp.getDate() + options.expiresInDays);
69
- entry.expiresAt = exp.toISOString();
70
- }
71
- store.entries.push(entry);
72
- saveTriage(cwd, store);
73
- }
74
-
75
- export function removeTriageEntry(cwd: string, ids: string[]): number {
76
- const store = loadTriage(cwd);
77
- const before = store.entries.length;
78
- store.entries = store.entries.filter(e => !ids.some(id => e.id === id || e.id.startsWith(id)));
79
- saveTriage(cwd, store);
80
- return before - store.entries.length;
81
- }
82
-
83
- export function clearExpiredEntries(cwd: string): number {
84
- const store = loadTriage(cwd);
85
- const now = new Date().toISOString();
86
- const before = store.entries.length;
87
- store.entries = store.entries.filter(e => !e.expiresAt || e.expiresAt > now);
88
- saveTriage(cwd, store);
89
- return before - store.entries.length;
90
- }
91
-
92
- export interface TriageFilterResult {
93
- active: Finding[];
94
- triaged: Finding[];
95
- triageCount: number;
96
- }
97
-
98
- export function filterTriaged(findings: Finding[], store: TriageStore): TriageFilterResult {
99
- const now = new Date().toISOString();
100
- const activeKeys = new Set(
101
- store.entries
102
- .filter(e => !e.expiresAt || e.expiresAt > now)
103
- .map(entryKey),
104
- );
105
- const active: Finding[] = [];
106
- const triaged: Finding[] = [];
107
- for (const f of findings) {
108
- if (activeKeys.has(entryKey(f))) triaged.push(f);
109
- else active.push(f);
110
- }
111
- return { active, triaged, triageCount: triaged.length };
112
- }
@@ -1,93 +0,0 @@
1
- import type { Finding, FixAttempt, FixStatus } from '../findings/types.ts';
2
- import type { GuardrailConfig } from '../config/types.ts';
3
- import type { ReviewEngine } from '../../adapters/review-engine/types.ts';
4
- import { dedupFindings, findingContentKey } from '../findings/dedup.ts';
5
-
6
- export interface StaticRule {
7
- name: string;
8
- severity: 'critical' | 'warning' | 'note';
9
- check(touchedFiles: string[], config?: Record<string, unknown>): Promise<Finding[]>;
10
- autofix?(finding: Finding): Promise<FixStatus>;
11
- }
12
-
13
- export interface StaticRulesPhaseInput {
14
- touchedFiles: string[];
15
- rules: StaticRule[];
16
- config?: GuardrailConfig;
17
- engine?: ReviewEngine;
18
- }
19
-
20
- export interface StaticRulesPhaseResult {
21
- phase: 'static-rules';
22
- status: 'pass' | 'warn' | 'fail';
23
- findings: Finding[];
24
- fixAttempts: FixAttempt[];
25
- durationMs: number;
26
- }
27
-
28
- export async function runStaticRulesPhase(input: StaticRulesPhaseInput): Promise<StaticRulesPhaseResult> {
29
- const start = Date.now();
30
-
31
- const preFixFindings = dedupFindings(await runAllChecks(input.rules, input.touchedFiles, input.config, input.engine));
32
-
33
- const fixAttempts: FixAttempt[] = [];
34
- let anyFixApplied = false;
35
-
36
- for (const finding of preFixFindings) {
37
- const rule = findRuleForFinding(input.rules, finding);
38
- if (!rule?.autofix) continue;
39
-
40
- if (finding.protectedPath) {
41
- fixAttempts.push({
42
- findingId: finding.id,
43
- attemptedAt: new Date().toISOString(),
44
- status: 'skipped',
45
- notes: 'protected path',
46
- });
47
- continue;
48
- }
49
-
50
- const status = await rule.autofix(finding);
51
- if (status === 'fixed') anyFixApplied = true;
52
- fixAttempts.push({ findingId: finding.id, attemptedAt: new Date().toISOString(), status });
53
- }
54
-
55
- // Re-check is the source of truth for what persists after autofix.
56
- // findings always returns preFixFindings so callers have a complete record;
57
- // fixAttempts + re-check set-difference tells them what was resolved.
58
- const postFixFindings = anyFixApplied
59
- ? dedupFindings(await runAllChecks(input.rules, input.touchedFiles, input.config, input.engine))
60
- : preFixFindings;
61
-
62
- const postFixKeys = new Set(postFixFindings.map(findingContentKey));
63
- const isFixed = (f: Finding): boolean => !postFixKeys.has(findingContentKey(f));
64
-
65
- const unfixedCritical = preFixFindings.some(f => f.severity === 'critical' && !isFixed(f));
66
- const unfixedWarning = preFixFindings.some(f => f.severity === 'warning' && !isFixed(f));
67
-
68
- let status: StaticRulesPhaseResult['status'];
69
- if (unfixedCritical) status = 'fail';
70
- else if (unfixedWarning) status = 'warn';
71
- else status = 'pass';
72
-
73
- return { phase: 'static-rules', status, findings: preFixFindings, fixAttempts, durationMs: Date.now() - start };
74
- }
75
-
76
- async function runAllChecks(
77
- rules: StaticRule[],
78
- files: string[],
79
- config?: GuardrailConfig,
80
- engine?: ReviewEngine,
81
- ): Promise<Finding[]> {
82
- const ruleConfig: Record<string, unknown> = {
83
- ...(config ? (config as unknown as Record<string, unknown>) : {}),
84
- _engine: engine,
85
- };
86
- const all: Finding[] = [];
87
- for (const rule of rules) all.push(...(await rule.check(files, ruleConfig)));
88
- return all;
89
- }
90
-
91
- function findRuleForFinding(rules: StaticRule[], finding: Finding): StaticRule | undefined {
92
- return rules.find(r => r.name === finding.category) ?? rules.find(r => finding.category.includes(r.name));
93
- }
@@ -1,51 +0,0 @@
1
- import { execSync } from 'node:child_process';
2
- import type { Finding } from '../findings/types.ts';
3
-
4
- export interface TestsPhaseInput {
5
- touchedFiles: string[];
6
- testCommand?: string | null;
7
- cwd?: string;
8
- }
9
-
10
- export interface TestsPhaseResult {
11
- phase: 'tests';
12
- status: 'pass' | 'fail' | 'skip';
13
- findings: Finding[];
14
- output?: string;
15
- durationMs: number;
16
- }
17
-
18
- export async function runTestsPhase(input: TestsPhaseInput): Promise<TestsPhaseResult> {
19
- const start = Date.now();
20
-
21
- if (!input.testCommand) {
22
- return { phase: 'tests', status: 'skip', findings: [], durationMs: Date.now() - start };
23
- }
24
-
25
- let output: string | undefined;
26
- try {
27
- // shell:true is intentional — testCommand is developer-supplied config, supports quoted args + pipes.
28
- output = execSync(input.testCommand, {
29
- encoding: 'utf8',
30
- cwd: input.cwd,
31
- timeout: 120000,
32
- shell: process.env.SHELL ?? "/bin/sh",
33
- stdio: ['ignore', 'pipe', 'pipe'],
34
- });
35
- } catch {
36
- const finding: Finding = {
37
- id: 'tests-phase-fail',
38
- source: 'static-rules',
39
- severity: 'critical',
40
- category: 'test-failure',
41
- file: '<tests>',
42
- message: `Test command failed: ${input.testCommand}`,
43
- suggestion: 'Fix failing tests before merging',
44
- protectedPath: false,
45
- createdAt: new Date().toISOString(),
46
- };
47
- return { phase: 'tests', status: 'fail', findings: [finding], output: undefined, durationMs: Date.now() - start };
48
- }
49
-
50
- return { phase: 'tests', status: 'pass', findings: [], output, durationMs: Date.now() - start };
51
- }
@@ -1,182 +0,0 @@
1
- import type { ReviewEngine } from '../../adapters/review-engine/types.ts';
2
- import type { Finding } from '../findings/types.ts';
3
- import type { GuardrailConfig } from '../config/types.ts';
4
- import { buildReviewChunks, type ReviewChunk } from '../chunking/index.ts';
5
- import { GuardrailError } from '../errors.ts';
6
- import { hasFrontendFiles, loadDesignContext } from '../ui/design-context-loader.ts';
7
-
8
- export interface ReviewPhaseResult {
9
- phase: 'review';
10
- status: 'pass' | 'warn' | 'fail' | 'skip';
11
- findings: Finding[];
12
- rawOutputs?: string[];
13
- costUSD?: number;
14
- usage?: { input: number; output: number };
15
- durationMs: number;
16
- }
17
-
18
- export interface ReviewPhaseInput {
19
- touchedFiles: string[];
20
- engine: ReviewEngine;
21
- config: GuardrailConfig;
22
- cwd?: string;
23
- gitSummary?: string;
24
- designSchema?: string;
25
- budgetRemainingUSD?: number;
26
- base?: string;
27
- }
28
-
29
- interface ChunkResult {
30
- findings: Finding[];
31
- rawOutput: string;
32
- inputTokens: number;
33
- outputTokens: number;
34
- costUSD: number;
35
- }
36
-
37
- function backoffMs(attempt: number, strategy: 'exp' | 'linear' | 'none'): number {
38
- if (strategy === 'none') return 0;
39
- if (strategy === 'linear') return attempt * 2000;
40
- return Math.min(Math.pow(2, attempt) * 1000, 32000); // exp: 1s, 2s, 4s, 8s … 32s cap
41
- }
42
-
43
- async function reviewChunkWithRetry(chunk: ReviewChunk, input: ReviewPhaseInput): Promise<ChunkResult> {
44
- const strategy = input.config.chunking?.rateLimitBackoff ?? 'exp';
45
- const maxAttempts = strategy === 'none' ? 1 : 4;
46
-
47
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
48
- try {
49
- const output = await input.engine.review({
50
- content: chunk.content,
51
- kind: chunk.kind,
52
- context: { stack: input.config.stack, cwd: input.cwd, gitSummary: input.gitSummary, designSchema: input.designSchema },
53
- });
54
- return {
55
- findings: output.findings,
56
- rawOutput: output.rawOutput,
57
- inputTokens: output.usage?.input ?? 0,
58
- outputTokens: output.usage?.output ?? 0,
59
- costUSD: output.usage?.costUSD ?? 0,
60
- };
61
- } catch (err) {
62
- const isRateLimit = err instanceof GuardrailError && err.code === 'rate_limit';
63
- const isLast = attempt === maxAttempts - 1;
64
- if (!isRateLimit || isLast) throw err;
65
- const delay = backoffMs(attempt + 1, strategy);
66
- await new Promise(r => setTimeout(r, delay));
67
- }
68
- }
69
- throw new Error('unreachable');
70
- }
71
-
72
- /** Run up to `limit` promises concurrently, preserving result order. */
73
- async function pMap<T, R>(
74
- items: T[],
75
- fn: (item: T, index: number) => Promise<R>,
76
- limit: number,
77
- ): Promise<R[]> {
78
- const results: R[] = new Array(items.length);
79
- let next = 0;
80
-
81
- async function worker(): Promise<void> {
82
- while (next < items.length) {
83
- const i = next++;
84
- results[i] = await fn(items[i]!, i);
85
- }
86
- }
87
-
88
- const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());
89
- await Promise.all(workers);
90
- return results;
91
- }
92
-
93
- export async function runReviewPhase(input: ReviewPhaseInput): Promise<ReviewPhaseResult> {
94
- const start = Date.now();
95
-
96
- if (input.touchedFiles.length === 0) {
97
- return { phase: 'review', status: 'skip', findings: [], durationMs: Date.now() - start };
98
- }
99
-
100
- let designSchema: string | undefined;
101
- if (hasFrontendFiles(input.touchedFiles) && input.config.brand?.componentLibrary) {
102
- const loaded = loadDesignContext(
103
- input.config.brand.componentLibrary,
104
- input.cwd ?? process.cwd(),
105
- );
106
- if (loaded) designSchema = loaded;
107
- }
108
- const enrichedInput: ReviewPhaseInput = designSchema ? { ...input, designSchema } : input;
109
-
110
- const chunks = await buildReviewChunks({
111
- touchedFiles: enrichedInput.touchedFiles,
112
- strategy: enrichedInput.config.reviewStrategy ?? 'auto',
113
- chunking: enrichedInput.config.chunking,
114
- engine: enrichedInput.engine,
115
- cwd: enrichedInput.cwd,
116
- protectedPaths: enrichedInput.config.protectedPaths,
117
- base: enrichedInput.base,
118
- });
119
-
120
- const parallelism = enrichedInput.config.chunking?.parallelism ?? 3;
121
- const budgetUSD = enrichedInput.budgetRemainingUSD;
122
-
123
- // For budget tracking we still need to enforce it — run serially if budget set,
124
- // parallel otherwise (budget check between serial chunks is the safe path).
125
- let chunkResults: ChunkResult[];
126
- if (budgetUSD !== undefined) {
127
- chunkResults = [];
128
- let spent = 0;
129
- let budgetExceeded = false;
130
- for (const chunk of chunks) {
131
- if (spent >= budgetUSD) { budgetExceeded = true; break; }
132
- const r = await reviewChunkWithRetry(chunk, enrichedInput);
133
- spent += r.costUSD;
134
- chunkResults.push(r);
135
- }
136
- if (budgetExceeded) {
137
- chunkResults.push({
138
- findings: [{
139
- id: 'budget-exceeded',
140
- source: 'pipeline',
141
- severity: 'warning',
142
- category: 'budget',
143
- file: '<pipeline>',
144
- message: `Review budget of $${budgetUSD} USD exceeded — remaining chunks skipped`,
145
- protectedPath: false,
146
- createdAt: new Date().toISOString(),
147
- }],
148
- rawOutput: '', inputTokens: 0, outputTokens: 0, costUSD: 0,
149
- });
150
- }
151
- } else {
152
- chunkResults = await pMap(chunks, chunk => reviewChunkWithRetry(chunk, enrichedInput), parallelism);
153
- }
154
-
155
- let totalInputTokens = 0;
156
- let totalOutputTokens = 0;
157
- let totalCostUSD = 0;
158
- const allFindings: Finding[] = [];
159
- const allRawOutputs: string[] = [];
160
-
161
- for (const r of chunkResults) {
162
- allFindings.push(...r.findings);
163
- if (r.rawOutput) allRawOutputs.push(r.rawOutput);
164
- totalInputTokens += r.inputTokens;
165
- totalOutputTokens += r.outputTokens;
166
- totalCostUSD += r.costUSD;
167
- }
168
-
169
- const hasCritical = allFindings.some(f => f.severity === 'critical');
170
- const hasWarning = allFindings.some(f => f.severity === 'warning');
171
- const status = hasCritical ? 'fail' : hasWarning ? 'warn' : 'pass';
172
-
173
- return {
174
- phase: 'review',
175
- status,
176
- findings: allFindings,
177
- rawOutputs: allRawOutputs.length > 0 ? allRawOutputs : undefined,
178
- costUSD: totalCostUSD > 0 ? totalCostUSD : undefined,
179
- usage: totalInputTokens > 0 ? { input: totalInputTokens, output: totalOutputTokens } : undefined,
180
- durationMs: Date.now() - start,
181
- };
182
- }