@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,388 +0,0 @@
1
- /**
2
- * `claude-autopilot migrate-v4` — codemod for v4 → v5 rename.
3
- *
4
- * Scans a repo for @delegance/guardrail + guardrail CLI references and proposes
5
- * replacements. Writes with `--write`, restores from manifest with `--undo`.
6
- *
7
- * Mutation rules (per codex review of alpha.3 spec):
8
- * - package.json: updates dependencies, devDependencies, optionalDependencies,
9
- * peerDependencies. Preserves key ordering within each section. Preserves
10
- * semver operator shape (^/~/>=/exact) — only rewrites the package name and
11
- * bumps to ^5.0.0-alpha.
12
- * - Shell scripts, Makefiles, workflow yaml, Dockerfiles: word-boundary match
13
- * on `guardrail <verb>` → `claude-autopilot <verb>`, and
14
- * `@delegance/guardrail` → `@delegance/claude-autopilot`.
15
- * - package-lock.json: NOT touched (regenerated by npm install).
16
- *
17
- * --undo reads `.claude-autopilot/migrate-v4-manifest.json` and restores files
18
- * by sha256 match. Rejects restoration if the current file differs from the
19
- * backup's post-write hash, preventing clobber of user edits.
20
- */
21
-
22
- import * as fs from 'node:fs';
23
- import * as path from 'node:path';
24
- import * as crypto from 'node:crypto';
25
-
26
- export interface MigrateV4Options {
27
- cwd?: string;
28
- write?: boolean;
29
- undo?: boolean;
30
- path?: string;
31
- }
32
-
33
- interface Replacement {
34
- pattern: RegExp;
35
- replace: (match: string, ...groups: string[]) => string;
36
- description: string;
37
- }
38
-
39
- interface FileResult {
40
- path: string;
41
- relPath: string;
42
- replacements: number;
43
- preview: string[];
44
- }
45
-
46
- interface ManifestEntry {
47
- path: string;
48
- beforeSha256: string;
49
- afterSha256: string;
50
- backupPath: string;
51
- timestamp: string;
52
- }
53
-
54
- const MANIFEST_DIR = '.claude-autopilot';
55
- const MANIFEST_NAME = 'migrate-v4-manifest.json';
56
-
57
- // File patterns to scan. Glob-like but hand-rolled — no dep on minimatch for this path.
58
- const INCLUDE_EXTENSIONS = new Set([
59
- '.sh', '.bash', '.zsh', '.fish', '.mk', '.yml', '.yaml', '.json', '.toml', '.md',
60
- ]);
61
- const INCLUDE_FILENAMES = new Set([
62
- 'Makefile', 'Dockerfile', 'dockerfile', 'package.json',
63
- '.pre-commit-config.yaml', '.pre-commit-hooks.yaml', '.husky',
64
- ]);
65
-
66
- // Lockfiles are explicitly skipped — text substitution would corrupt their
67
- // internal structure (resolved URLs, integrity hashes, peer-dep graphs).
68
- // Users regenerate them via `npm install` after the migrate completes.
69
- const SKIP_FILENAMES = new Set([
70
- 'package-lock.json',
71
- 'npm-shrinkwrap.json',
72
- 'pnpm-lock.yaml',
73
- 'yarn.lock',
74
- 'bun.lockb',
75
- 'bun.lock',
76
- ]);
77
-
78
- const SKIP_DIRS = new Set([
79
- 'node_modules', '.git', 'dist', 'build', '.next', '.nuxt', 'out',
80
- 'coverage', '__pycache__', '.venv', 'venv', '.turbo',
81
- MANIFEST_DIR, // don't mutate our own manifest
82
- ]);
83
-
84
- const VERBS = 'run|scan|ci|setup|doctor|init|fix|baseline|explain|ignore|costs|watch|hook|autoregress|triage|pr-desc|council|report|test-gen|mcp|lsp|worker|pr|preflight';
85
-
86
- const TEXT_REPLACEMENTS: Replacement[] = [
87
- // Package name with version suffix (`@delegance/guardrail@^4`, `@delegance/guardrail@4.3.1`)
88
- // MUST run before the bare-name rule. Replaces the entire spec with
89
- // `@delegance/claude-autopilot@alpha` — the old `^4` / `4.3.1` ranges don't
90
- // resolve against the new package (it starts at 5.0.0).
91
- {
92
- pattern: /@delegance\/guardrail@[^\s"'`,)\]}]+/g,
93
- replace: () => '@delegance/claude-autopilot@alpha',
94
- description: '@delegance/guardrail@<version> → @delegance/claude-autopilot@alpha',
95
- },
96
- // Bare package name (no version suffix) — used in imports, package.json keys,
97
- // prose references. Preserves surrounding context.
98
- {
99
- pattern: /@delegance\/guardrail\b/g,
100
- replace: () => '@delegance/claude-autopilot',
101
- description: '@delegance/guardrail → @delegance/claude-autopilot',
102
- },
103
- // `npx guardrail <verb>` / `pnpm dlx guardrail <verb>` / `yarn dlx guardrail <verb>`.
104
- // These must run BEFORE the bare `guardrail <verb>` pattern below so the package-
105
- // name `guardrail` inside `npx` is replaced as a unit with its wrapper tool.
106
- {
107
- pattern: new RegExp(
108
- `((?:^|\\s)(?:npx|pnpm\\s+dlx|yarn\\s+dlx|bunx)\\s+)guardrail(\\s+)(${VERBS})\\b`,
109
- 'g',
110
- ),
111
- replace: (_m, wrapper, ws, verb) => `${wrapper}@delegance/claude-autopilot@alpha${ws}${verb}`,
112
- description: 'npx/pnpm dlx/yarn dlx guardrail <verb> → ... @delegance/claude-autopilot@alpha <verb>',
113
- },
114
- // `guardrail <verb>` on its own line or after whitespace/punctuation
115
- {
116
- pattern: new RegExp(`(^|[\\s\`"'(])guardrail(\\s+)(${VERBS})\\b`, 'g'),
117
- replace: (_m, lead, ws, verb) => `${lead}claude-autopilot${ws}${verb}`,
118
- description: '`guardrail <verb>` → `claude-autopilot <verb>`',
119
- },
120
- // Quoted `"guardrail"` in argv-style arrays — Dockerfile CMD, exec args, etc.
121
- {
122
- pattern: new RegExp(
123
- `(["'])guardrail(["'])(\\s*,\\s*)(["'])(${VERBS})\\b`,
124
- 'g',
125
- ),
126
- replace: (_m, q1, q2, sep, q3, verb) => `${q1}claude-autopilot${q2}${sep}${q3}${verb}`,
127
- description: '`"guardrail", "<verb>"` → `"claude-autopilot", "<verb>"`',
128
- },
129
- ];
130
-
131
- // package.json needs JSON-aware handling for the dependency keys (to preserve
132
- // semver operators and section structure), plus text replacements on the rest
133
- // of the file (for scripts, bin references, etc).
134
- function migratePackageJson(content: string): { updated: string; count: number } {
135
- let pkg: Record<string, unknown>;
136
- try {
137
- pkg = JSON.parse(content) as Record<string, unknown>;
138
- } catch {
139
- return applyTextReplacements(content);
140
- }
141
-
142
- let count = 0;
143
- for (const section of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) {
144
- const deps = pkg[section] as Record<string, string> | undefined;
145
- if (deps && typeof deps === 'object' && '@delegance/guardrail' in deps) {
146
- const oldRange = deps['@delegance/guardrail']!;
147
- const m = oldRange.match(/^(\^|~|>=|<=|>|<|=)?/);
148
- const operator = (m && m[1]) ?? '';
149
- // Rebuild the deps object preserving key order — substitute the old key
150
- // in place with the new one. Straight `delete` + reassign would append
151
- // the renamed dep at the end of its section, producing noisy diffs.
152
- const rebuilt: Record<string, string> = {};
153
- for (const [key, value] of Object.entries(deps)) {
154
- if (key === '@delegance/guardrail') {
155
- rebuilt['@delegance/claude-autopilot'] = `${operator}5.0.0-alpha`;
156
- } else {
157
- rebuilt[key] = value;
158
- }
159
- }
160
- pkg[section] = rebuilt;
161
- count++;
162
- }
163
- }
164
-
165
- const indent = detectJsonIndent(content);
166
- const newline = content.endsWith('\n') ? '\n' : '';
167
- const rewritten = JSON.stringify(pkg, null, indent) + newline;
168
-
169
- // Text replacements on the stringified form — catches `guardrail <verb>` in
170
- // scripts, bin paths, and any other embedded CLI invocation.
171
- const { updated, count: textCount } = applyTextReplacements(rewritten);
172
- return { updated, count: count + textCount };
173
- }
174
-
175
- function detectJsonIndent(source: string): number | string {
176
- const m = source.match(/\n( +)"/);
177
- if (m && m[1]) return m[1].length;
178
- return 2;
179
- }
180
-
181
- function applyTextReplacements(content: string): { updated: string; count: number } {
182
- let updated = content;
183
- let count = 0;
184
- for (const r of TEXT_REPLACEMENTS) {
185
- updated = updated.replace(r.pattern, (...args) => {
186
- count++;
187
- return r.replace(args[0], ...args.slice(1, args.length - 2));
188
- });
189
- }
190
- return { updated, count };
191
- }
192
-
193
- function shouldProcessFile(filePath: string): boolean {
194
- const base = path.basename(filePath);
195
- if (SKIP_FILENAMES.has(base)) return false;
196
- const ext = path.extname(filePath);
197
- if (INCLUDE_FILENAMES.has(base)) return true;
198
- if (INCLUDE_EXTENSIONS.has(ext)) return true;
199
- return false;
200
- }
201
-
202
- function collectFiles(root: string): string[] {
203
- const out: string[] = [];
204
- function walk(dir: string): void {
205
- let entries: fs.Dirent[];
206
- try {
207
- entries = fs.readdirSync(dir, { withFileTypes: true });
208
- } catch { return; }
209
- for (const entry of entries) {
210
- const full = path.join(dir, entry.name);
211
- if (entry.isDirectory()) {
212
- if (SKIP_DIRS.has(entry.name)) continue;
213
- walk(full);
214
- } else if (entry.isFile() && shouldProcessFile(full)) {
215
- out.push(full);
216
- }
217
- }
218
- }
219
- walk(root);
220
- return out;
221
- }
222
-
223
- function sha256(content: string): string {
224
- return crypto.createHash('sha256').update(content).digest('hex');
225
- }
226
-
227
- function processFile(file: string): { replacements: number; original: string; updated: string; preview: string[] } {
228
- const original = fs.readFileSync(file, 'utf8');
229
- const { updated, count } = path.basename(file) === 'package.json'
230
- ? migratePackageJson(original)
231
- : applyTextReplacements(original);
232
- if (count === 0) return { replacements: 0, original, updated: original, preview: [] };
233
- const preview = diffPreview(original, updated);
234
- return { replacements: count, original, updated, preview };
235
- }
236
-
237
- function diffPreview(before: string, after: string): string[] {
238
- const preview: string[] = [];
239
- const beforeLines = before.split('\n');
240
- const afterLines = after.split('\n');
241
- const maxLines = Math.max(beforeLines.length, afterLines.length);
242
- for (let i = 0; i < maxLines && preview.length < 10; i++) {
243
- const b = beforeLines[i] ?? '';
244
- const a = afterLines[i] ?? '';
245
- if (b !== a) {
246
- if (b) preview.push(` - ${b.trim().slice(0, 100)}`);
247
- if (a) preview.push(` + ${a.trim().slice(0, 100)}`);
248
- }
249
- }
250
- return preview;
251
- }
252
-
253
- export async function runMigrateV4(options: MigrateV4Options = {}): Promise<number> {
254
- const cwd = options.cwd ?? options.path ?? process.cwd();
255
-
256
- if (options.undo) return runUndo(cwd);
257
-
258
- const files = collectFiles(cwd);
259
- const results: FileResult[] = [];
260
- let totalReplacements = 0;
261
-
262
- const manifest: ManifestEntry[] = [];
263
-
264
- for (const file of files) {
265
- const { replacements, original, updated, preview } = processFile(file);
266
- if (replacements === 0) continue;
267
- results.push({
268
- path: file,
269
- relPath: path.relative(cwd, file),
270
- replacements,
271
- preview,
272
- });
273
- totalReplacements += replacements;
274
-
275
- if (options.write) {
276
- // Reuse `original` from processFile — avoids a second read + prevents any
277
- // chance of `beforeSha256` diverging from what the transformation actually
278
- // consumed if the file changed mid-scan.
279
- const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
280
- const backupPath = `${file}.v4-backup.${timestamp}`;
281
- fs.writeFileSync(backupPath, original);
282
- fs.writeFileSync(file, updated);
283
- manifest.push({
284
- path: file,
285
- beforeSha256: sha256(original),
286
- afterSha256: sha256(updated),
287
- backupPath,
288
- timestamp,
289
- });
290
- }
291
- }
292
-
293
- // Emit report
294
- console.log(`\n\x1b[1m[migrate-v4] ${options.write ? 'Writing' : 'Dry-run — scanning'} ${cwd}\x1b[0m\n`);
295
- if (results.length === 0) {
296
- console.log(' No v4 references found.');
297
- return 0;
298
- }
299
- for (const r of results) {
300
- console.log(` \x1b[32m${r.replacements}\x1b[0m ${r.relPath}`);
301
- for (const line of r.preview.slice(0, 4)) console.log(` \x1b[2m${line}\x1b[0m`);
302
- }
303
- console.log(`\n ─────────────────────────────`);
304
- console.log(` ${totalReplacements} replacements across ${results.length} files`);
305
-
306
- if (options.write) {
307
- const manifestDir = path.join(cwd, MANIFEST_DIR);
308
- fs.mkdirSync(manifestDir, { recursive: true });
309
- const manifestPath = path.join(manifestDir, MANIFEST_NAME);
310
- fs.writeFileSync(manifestPath, JSON.stringify({
311
- migratedAt: new Date().toISOString(),
312
- from: '@delegance/guardrail',
313
- to: '@delegance/claude-autopilot',
314
- entries: manifest,
315
- }, null, 2));
316
- console.log(`\n \x1b[32m✓\x1b[0m Applied. Manifest: ${path.relative(cwd, manifestPath)}`);
317
- console.log(` Backup files suffix: .v4-backup.<timestamp>`);
318
- console.log(` Restore: claude-autopilot migrate-v4 --undo`);
319
- console.log(`\n Next: run \`npm install\` to sync package-lock.json.`);
320
- } else {
321
- console.log(`\n Run with \x1b[36m--write\x1b[0m to apply (with .v4-backup files + restore manifest).`);
322
- }
323
- return 0;
324
- }
325
-
326
- function runUndo(cwd: string): number {
327
- const manifestPath = path.join(cwd, MANIFEST_DIR, MANIFEST_NAME);
328
- if (!fs.existsSync(manifestPath)) {
329
- console.error(`[migrate-v4] No manifest at ${manifestPath}. Nothing to undo.`);
330
- return 1;
331
- }
332
- const raw = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as {
333
- migratedAt: string;
334
- from: string;
335
- to: string;
336
- entries: ManifestEntry[];
337
- };
338
- const restored: ManifestEntry[] = [];
339
- const pending: ManifestEntry[] = [];
340
-
341
- for (const entry of raw.entries) {
342
- if (!fs.existsSync(entry.path)) {
343
- console.error(` \x1b[33m!\x1b[0m ${path.relative(cwd, entry.path)} missing — skipping`);
344
- pending.push(entry);
345
- continue;
346
- }
347
- if (!fs.existsSync(entry.backupPath)) {
348
- console.error(` \x1b[33m!\x1b[0m backup missing for ${path.relative(cwd, entry.path)} — skipping`);
349
- pending.push(entry);
350
- continue;
351
- }
352
- const currentHash = sha256(fs.readFileSync(entry.path, 'utf8'));
353
- if (currentHash !== entry.afterSha256) {
354
- console.error(` \x1b[33m!\x1b[0m ${path.relative(cwd, entry.path)} modified since migrate — refusing to overwrite`);
355
- console.error(` expected sha256=${entry.afterSha256.slice(0, 8)}, got ${currentHash.slice(0, 8)}`);
356
- pending.push(entry);
357
- continue;
358
- }
359
- const backup = fs.readFileSync(entry.backupPath, 'utf8');
360
- if (sha256(backup) !== entry.beforeSha256) {
361
- console.error(` \x1b[33m!\x1b[0m backup ${path.relative(cwd, entry.backupPath)} tampered — skipping`);
362
- pending.push(entry);
363
- continue;
364
- }
365
- fs.writeFileSync(entry.path, backup);
366
- fs.unlinkSync(entry.backupPath);
367
- console.log(` \x1b[32m✓\x1b[0m ${path.relative(cwd, entry.path)}`);
368
- restored.push(entry);
369
- }
370
-
371
- // Preserve manifest when any entries remain pending so --undo can be re-run
372
- // after the user resolves the blocker (restored their edits, fixed backup, etc).
373
- if (pending.length > 0) {
374
- fs.writeFileSync(manifestPath, JSON.stringify({
375
- ...raw,
376
- entries: pending,
377
- }, null, 2));
378
- console.log(
379
- `\n Restored ${restored.length}, ${pending.length} pending. ` +
380
- `Manifest retained at ${path.relative(cwd, manifestPath)} — re-run --undo after resolving issues.`,
381
- );
382
- return 1;
383
- }
384
-
385
- fs.unlinkSync(manifestPath);
386
- console.log(`\n Restored ${restored.length}, skipped 0.`);
387
- return 0;
388
- }
@@ -1,139 +0,0 @@
1
- import { runSafe } from '../core/shell.ts';
2
- import type { RunResult } from '../core/pipeline/run.ts';
3
- import type { GuardrailConfig } from '../core/config/types.ts';
4
- import type { GitContext } from '../core/detect/git-context.ts';
5
- import { readFileSync } from 'node:fs';
6
- import { join } from 'node:path';
7
- import { findPackageRoot } from './_pkg-root.ts';
8
-
9
- const COMMENT_MARKER = '<!-- guardrail-review -->';
10
-
11
- function readVersion(): string {
12
- try {
13
- const root = findPackageRoot(import.meta.url);
14
- if (!root) return 'unknown';
15
- const pkgPath = join(root, 'package.json');
16
- return (JSON.parse(readFileSync(pkgPath, 'utf8')) as { version: string }).version;
17
- } catch { return 'unknown'; }
18
- }
19
-
20
- /** Detect the current open PR number via gh CLI or CI env vars. */
21
- export function detectPrNumber(cwd: string): number | null {
22
- // CI env vars set by GitHub Actions
23
- const fromEnv = process.env.PR_NUMBER ?? process.env.GH_PR_NUMBER ?? process.env.GITHUB_PR_NUMBER;
24
- if (fromEnv && /^\d+$/.test(fromEnv)) return parseInt(fromEnv, 10);
25
-
26
- // gh CLI — works locally and in CI when gh is authenticated
27
- const raw = runSafe('gh', ['pr', 'view', '--json', 'number', '--jq', '.number'], { cwd });
28
- if (raw) {
29
- const n = parseInt(raw.trim(), 10);
30
- if (!isNaN(n)) return n;
31
- }
32
- return null;
33
- }
34
-
35
- /** Find the ID of a previously-posted autopilot comment, if any. */
36
- function findExistingCommentId(pr: number, cwd: string): number | null {
37
- const raw = runSafe('gh', ['api', `repos/{owner}/{repo}/issues/${pr}/comments`,
38
- '--jq', `[.[] | select(.body | startswith("${COMMENT_MARKER}")) | .id] | first`], { cwd });
39
- if (!raw) return null;
40
- const n = parseInt(raw.trim(), 10);
41
- return isNaN(n) ? null : n;
42
- }
43
-
44
- /** Format a RunResult into a markdown PR comment. */
45
- export function formatComment(
46
- result: RunResult,
47
- config: GuardrailConfig,
48
- gitCtx: GitContext,
49
- touchedFileCount: number,
50
- ): string {
51
- const statusIcon = result.status === 'pass' ? '✅' : result.status === 'warn' ? '⚠️' : '❌';
52
- const statusLabel = result.status === 'pass' ? 'Passed' : result.status === 'warn' ? 'Passed with warnings' : 'Failed';
53
-
54
- const lines: string[] = [
55
- COMMENT_MARKER,
56
- `## ${statusIcon} Autopilot Review — ${statusLabel}`,
57
- '',
58
- ];
59
-
60
- // Context line
61
- const ctx: string[] = [];
62
- if (config.stack) ctx.push(`**Stack:** ${config.stack}`);
63
- if (gitCtx.branch) ctx.push(`**Branch:** \`${gitCtx.branch}\``);
64
- if (gitCtx.commitMessage) ctx.push(`**Commit:** ${gitCtx.commitMessage}`);
65
- ctx.push(`**Files reviewed:** ${touchedFileCount}`);
66
- lines.push(ctx.join(' · '), '');
67
-
68
- // Phase table
69
- lines.push('| Phase | Status | Findings |');
70
- lines.push('|---|:---:|:---:|');
71
- for (const phase of result.phases) {
72
- const icon = phase.status === 'pass' ? '✅' : phase.status === 'skip' ? '—' :
73
- phase.status === 'warn' ? '⚠️' : '❌';
74
- lines.push(`| ${phase.phase} | ${icon} | ${phase.findings.length} |`);
75
- }
76
- lines.push('');
77
-
78
- // Findings by severity
79
- const critical = result.allFindings.filter(f => f.severity === 'critical');
80
- const warnings = result.allFindings.filter(f => f.severity === 'warning');
81
- const notes = result.allFindings.filter(f => f.severity === 'note');
82
-
83
- if (critical.length > 0) {
84
- lines.push('### 🚨 Critical');
85
- for (const f of critical) {
86
- const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
87
- lines.push(`- ${loc}${f.message}`);
88
- if (f.suggestion) lines.push(` > ${f.suggestion}`);
89
- }
90
- lines.push('');
91
- }
92
-
93
- if (warnings.length > 0) {
94
- lines.push('### ⚠️ Warnings');
95
- for (const f of warnings) {
96
- const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
97
- lines.push(`- ${loc}${f.message}`);
98
- if (f.suggestion) lines.push(` > ${f.suggestion}`);
99
- }
100
- lines.push('');
101
- }
102
-
103
- if (notes.length > 0) {
104
- lines.push('<details><summary>Notes</summary>\n');
105
- for (const f of notes) {
106
- const loc = f.file !== '<unspecified>' ? `\`${f.file}${f.line ? `:${f.line}` : ''}\` — ` : '';
107
- lines.push(`- ${loc}${f.message}`);
108
- }
109
- lines.push('\n</details>\n');
110
- }
111
-
112
- if (result.totalCostUSD !== undefined) {
113
- lines.push(`*Cost: $${result.totalCostUSD.toFixed(4)} · ${result.durationMs}ms · [@delegance/guardrail](https://github.com/axledbetter/guardrail) v${readVersion()}*`);
114
- } else {
115
- lines.push(`*${result.durationMs}ms · [@delegance/guardrail](https://github.com/axledbetter/guardrail) v${readVersion()}*`);
116
- }
117
-
118
- return lines.join('\n');
119
- }
120
-
121
- /** Post or update the autopilot comment on the given PR. */
122
- export async function postPrComment(
123
- pr: number,
124
- body: string,
125
- cwd: string,
126
- ): Promise<{ action: 'created' | 'updated'; url: string | null }> {
127
- const existingId = findExistingCommentId(pr, cwd);
128
-
129
- if (existingId) {
130
- runSafe('gh', ['api', `repos/{owner}/{repo}/issues/comments/${existingId}`,
131
- '--method', 'PATCH', '--field', `body=${body}`], { cwd });
132
- return { action: 'updated', url: null };
133
- }
134
-
135
- const raw = runSafe('gh', ['pr', 'comment', String(pr), '--body', body], { cwd });
136
- // gh outputs the comment URL on success
137
- const url = raw?.trim() ?? null;
138
- return { action: 'created', url };
139
- }
@@ -1,168 +0,0 @@
1
- import type { Finding } from '../core/findings/types.ts';
2
- import * as fs from 'node:fs';
3
- import { execSync, spawnSync } from 'node:child_process';
4
-
5
- export interface PrDescOptions {
6
- base?: string;
7
- post?: boolean;
8
- yes?: boolean;
9
- output?: string;
10
- _gitDiff?: string;
11
- _branchName?: string;
12
- _cachedFindings?: Finding[];
13
- _reviewEngine?: {
14
- review(input: { content: string; kind: string }): Promise<{ rawOutput: string }>;
15
- };
16
- }
17
-
18
- export interface PrDescResult {
19
- title: string;
20
- body: string;
21
- prUrl?: string;
22
- }
23
-
24
- export function truncateDiff(diff: string, charLimit = 6000): string {
25
- if (diff.length <= charLimit) return diff;
26
- const remaining = diff.length - charLimit;
27
- return `${diff.slice(0, charLimit)}[...truncated ${remaining} chars]`;
28
- }
29
-
30
- export function summarizeFindings(findings: Finding[], max = 10): string {
31
- if (findings.length === 0) return 'None';
32
- const order: Record<string, number> = { critical: 0, error: 1, warning: 2, info: 3 };
33
- const sorted = [...findings].sort(
34
- (a, b) => (order[a.severity] ?? 9) - (order[b.severity] ?? 9),
35
- );
36
- return sorted
37
- .slice(0, max)
38
- .map(f => `- [${f.severity.toUpperCase()}] ${f.file}:${f.line ?? '?'} — ${f.message}`)
39
- .join('\n');
40
- }
41
-
42
- export function parseDescription(raw: string): { title: string; body: string } {
43
- const titleMatch = raw.match(/^Title:\s*(.+)$/m);
44
- const title = titleMatch ? titleMatch[1]!.trim() : 'chore: update';
45
- const sepIdx = raw.indexOf('\n\n---\n');
46
- const body = sepIdx !== -1 ? raw.slice(sepIdx + 5).trim() : raw.replace(/^Title:.*\n?/m, '').trim();
47
- return { title, body };
48
- }
49
-
50
- export async function runPrDesc(options: PrDescOptions): Promise<PrDescResult> {
51
- const branchName = options._branchName ?? getBranchName();
52
- const diff = options._gitDiff ?? getGitDiff(options.base);
53
-
54
- if (!diff.trim()) {
55
- process.stdout.write('No changes detected\n');
56
- return { title: 'No changes detected', body: '' };
57
- }
58
-
59
- const findings = options._cachedFindings ?? loadCachedFindings();
60
- const prompt = buildPrompt(branchName, truncateDiff(diff), summarizeFindings(findings));
61
-
62
- const engine = options._reviewEngine ?? (await resolveEngine() as unknown as { review(input: { content: string; kind: string }): Promise<{ rawOutput: string }> });
63
- const { rawOutput } = await engine.review({ content: prompt, kind: 'pr-diff' });
64
- const { title, body } = parseDescription(rawOutput);
65
-
66
- const formatted = `Title: ${title}\n\n---\n${body}`;
67
-
68
- if (options.output) {
69
- fs.writeFileSync(options.output, formatted, 'utf8');
70
- } else {
71
- process.stdout.write(formatted + '\n');
72
- }
73
-
74
- if (options.post) {
75
- return createPr(title, body, options.yes ?? false);
76
- }
77
-
78
- return { title, body };
79
- }
80
-
81
- function getBranchName(): string {
82
- try {
83
- return execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf8' }).trim();
84
- } catch {
85
- return 'unknown';
86
- }
87
- }
88
-
89
- function getGitDiff(base?: string): string {
90
- try {
91
- const ref = base ?? getUpstreamBase();
92
- return execSync(`git diff ${ref}...HEAD`, { encoding: 'utf8' });
93
- } catch {
94
- return '';
95
- }
96
- }
97
-
98
- function getUpstreamBase(): string {
99
- try {
100
- return execSync(
101
- 'git rev-parse --abbrev-ref --symbolic-full-name @{u}',
102
- { encoding: 'utf8' },
103
- ).trim();
104
- } catch {
105
- return 'HEAD~1';
106
- }
107
- }
108
-
109
- function loadCachedFindings(): Finding[] {
110
- try {
111
- return JSON.parse(fs.readFileSync('.guardrail-cache/findings.json', 'utf8')) as Finding[];
112
- } catch {
113
- return [];
114
- }
115
- }
116
-
117
- function buildPrompt(branch: string, diff: string, findingsSummary: string): string {
118
- return `Generate a pull request description with three sections:
119
-
120
- ## Summary
121
- <3-5 bullet points describing what changed and why>
122
-
123
- ## Changes
124
- <grouped by file/area, concise>
125
-
126
- ## Test Plan
127
- <checklist of what to verify before merging>
128
-
129
- Branch: ${branch}
130
- Diff:
131
- ${diff}
132
-
133
- Guardrail findings in this diff:
134
- ${findingsSummary}`;
135
- }
136
-
137
- async function resolveEngine() {
138
- const { loadAdapter } = await import('../adapters/loader.ts');
139
- const { loadConfig } = await import('../core/config/loader.ts');
140
- const configPath = process.env.GUARDRAIL_CONFIG ?? 'guardrail.config.yaml';
141
- let engineRef = 'auto';
142
- try {
143
- const cfg = await loadConfig(configPath);
144
- const rev = (cfg as { reviewEngine?: unknown }).reviewEngine;
145
- if (rev) engineRef = typeof rev === 'string' ? rev : (rev as { adapter: string }).adapter;
146
- } catch {
147
- // no config file — fall back to auto
148
- }
149
- return loadAdapter({ point: 'review-engine', ref: engineRef });
150
- }
151
-
152
- async function createPr(title: string, body: string, yes: boolean): Promise<PrDescResult> {
153
- if (!yes) {
154
- process.stdout.write('\nCreate PR with this description? [y/N] ');
155
- const answer = await new Promise<string>(resolve => {
156
- process.stdin.setEncoding('utf8');
157
- process.stdin.once('data', (chunk: string) => resolve(chunk.split('\n')[0] ?? ''));
158
- });
159
- if (!answer.toLowerCase().startsWith('y')) return { title, body };
160
- }
161
- const result = spawnSync('gh', ['pr', 'create', '--title', title, '--body', body], { encoding: 'utf8' });
162
- if (result.status !== 0) {
163
- throw new Error(`gh pr create failed: ${result.stderr?.trim() || result.error?.message || 'unknown error'}`);
164
- }
165
- const prUrl = result.stdout.trim();
166
- process.stdout.write(`\nPR created: ${prUrl}\n`);
167
- return { title, body, prUrl };
168
- }