@delegance/claude-autopilot 5.0.1 → 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 (410) hide show
  1. package/dist/src/cli/index.js +39 -1
  2. package/dist/src/cli/preflight.js +17 -4
  3. package/package.json +4 -3
  4. package/dist/presets/go/rules/go-sql-injection.d.ts.map +0 -1
  5. package/dist/presets/go/rules/go-sql-injection.js.map +0 -1
  6. package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.d.ts.map +0 -1
  7. package/dist/presets/nextjs-supabase/rules/supabase-rls-bypass.js.map +0 -1
  8. package/dist/presets/python-fastapi/rules/fastapi-missing-auth.d.ts.map +0 -1
  9. package/dist/presets/python-fastapi/rules/fastapi-missing-auth.js.map +0 -1
  10. package/dist/presets/rails-postgres/rules/rails-sql-injection.d.ts.map +0 -1
  11. package/dist/presets/rails-postgres/rules/rails-sql-injection.js.map +0 -1
  12. package/dist/presets/t3/rules/t3-server-only.d.ts.map +0 -1
  13. package/dist/presets/t3/rules/t3-server-only.js.map +0 -1
  14. package/dist/src/adapters/base.d.ts.map +0 -1
  15. package/dist/src/adapters/base.js.map +0 -1
  16. package/dist/src/adapters/council/claude.d.ts.map +0 -1
  17. package/dist/src/adapters/council/claude.js.map +0 -1
  18. package/dist/src/adapters/council/openai.d.ts.map +0 -1
  19. package/dist/src/adapters/council/openai.js.map +0 -1
  20. package/dist/src/adapters/council/types.d.ts.map +0 -1
  21. package/dist/src/adapters/council/types.js.map +0 -1
  22. package/dist/src/adapters/loader.d.ts.map +0 -1
  23. package/dist/src/adapters/loader.js.map +0 -1
  24. package/dist/src/adapters/migration-runner/supabase.d.ts.map +0 -1
  25. package/dist/src/adapters/migration-runner/supabase.js.map +0 -1
  26. package/dist/src/adapters/migration-runner/types.d.ts.map +0 -1
  27. package/dist/src/adapters/migration-runner/types.js.map +0 -1
  28. package/dist/src/adapters/review-bot-parser/cursor.d.ts.map +0 -1
  29. package/dist/src/adapters/review-bot-parser/cursor.js.map +0 -1
  30. package/dist/src/adapters/review-bot-parser/declarative-base.d.ts.map +0 -1
  31. package/dist/src/adapters/review-bot-parser/declarative-base.js.map +0 -1
  32. package/dist/src/adapters/review-bot-parser/types.d.ts.map +0 -1
  33. package/dist/src/adapters/review-bot-parser/types.js.map +0 -1
  34. package/dist/src/adapters/review-engine/auto.d.ts.map +0 -1
  35. package/dist/src/adapters/review-engine/auto.js.map +0 -1
  36. package/dist/src/adapters/review-engine/claude.d.ts.map +0 -1
  37. package/dist/src/adapters/review-engine/claude.js.map +0 -1
  38. package/dist/src/adapters/review-engine/codex.d.ts.map +0 -1
  39. package/dist/src/adapters/review-engine/codex.js.map +0 -1
  40. package/dist/src/adapters/review-engine/gemini.d.ts.map +0 -1
  41. package/dist/src/adapters/review-engine/gemini.js.map +0 -1
  42. package/dist/src/adapters/review-engine/openai-compatible.d.ts.map +0 -1
  43. package/dist/src/adapters/review-engine/openai-compatible.js.map +0 -1
  44. package/dist/src/adapters/review-engine/parse-output.d.ts.map +0 -1
  45. package/dist/src/adapters/review-engine/parse-output.js.map +0 -1
  46. package/dist/src/adapters/review-engine/prompt-builder.d.ts.map +0 -1
  47. package/dist/src/adapters/review-engine/prompt-builder.js.map +0 -1
  48. package/dist/src/adapters/review-engine/types.d.ts.map +0 -1
  49. package/dist/src/adapters/review-engine/types.js.map +0 -1
  50. package/dist/src/adapters/vcs-host/commit-status.d.ts.map +0 -1
  51. package/dist/src/adapters/vcs-host/commit-status.js.map +0 -1
  52. package/dist/src/adapters/vcs-host/github.d.ts.map +0 -1
  53. package/dist/src/adapters/vcs-host/github.js.map +0 -1
  54. package/dist/src/adapters/vcs-host/types.d.ts.map +0 -1
  55. package/dist/src/adapters/vcs-host/types.js.map +0 -1
  56. package/dist/src/cli/_pkg-root.d.ts.map +0 -1
  57. package/dist/src/cli/_pkg-root.js.map +0 -1
  58. package/dist/src/cli/autoregress-bridge.d.ts.map +0 -1
  59. package/dist/src/cli/autoregress-bridge.js.map +0 -1
  60. package/dist/src/cli/baseline.d.ts.map +0 -1
  61. package/dist/src/cli/baseline.js.map +0 -1
  62. package/dist/src/cli/ci.d.ts.map +0 -1
  63. package/dist/src/cli/ci.js.map +0 -1
  64. package/dist/src/cli/costs.d.ts.map +0 -1
  65. package/dist/src/cli/costs.js.map +0 -1
  66. package/dist/src/cli/council.d.ts.map +0 -1
  67. package/dist/src/cli/council.js.map +0 -1
  68. package/dist/src/cli/detector.d.ts.map +0 -1
  69. package/dist/src/cli/detector.js.map +0 -1
  70. package/dist/src/cli/explain.d.ts.map +0 -1
  71. package/dist/src/cli/explain.js.map +0 -1
  72. package/dist/src/cli/fix.d.ts.map +0 -1
  73. package/dist/src/cli/fix.js.map +0 -1
  74. package/dist/src/cli/hook.d.ts.map +0 -1
  75. package/dist/src/cli/hook.js.map +0 -1
  76. package/dist/src/cli/ignore-helper.d.ts.map +0 -1
  77. package/dist/src/cli/ignore-helper.js.map +0 -1
  78. package/dist/src/cli/index.d.ts.map +0 -1
  79. package/dist/src/cli/index.js.map +0 -1
  80. package/dist/src/cli/lsp.d.ts.map +0 -1
  81. package/dist/src/cli/lsp.js.map +0 -1
  82. package/dist/src/cli/mcp.d.ts.map +0 -1
  83. package/dist/src/cli/mcp.js.map +0 -1
  84. package/dist/src/cli/migrate-v4.d.ts.map +0 -1
  85. package/dist/src/cli/migrate-v4.js.map +0 -1
  86. package/dist/src/cli/pr-comment.d.ts.map +0 -1
  87. package/dist/src/cli/pr-comment.js.map +0 -1
  88. package/dist/src/cli/pr-desc.d.ts.map +0 -1
  89. package/dist/src/cli/pr-desc.js.map +0 -1
  90. package/dist/src/cli/pr-review-comments.d.ts.map +0 -1
  91. package/dist/src/cli/pr-review-comments.js.map +0 -1
  92. package/dist/src/cli/pr.d.ts.map +0 -1
  93. package/dist/src/cli/pr.js.map +0 -1
  94. package/dist/src/cli/preflight.d.ts.map +0 -1
  95. package/dist/src/cli/preflight.js.map +0 -1
  96. package/dist/src/cli/report.d.ts.map +0 -1
  97. package/dist/src/cli/report.js.map +0 -1
  98. package/dist/src/cli/run.d.ts.map +0 -1
  99. package/dist/src/cli/run.js.map +0 -1
  100. package/dist/src/cli/scan.d.ts.map +0 -1
  101. package/dist/src/cli/scan.js.map +0 -1
  102. package/dist/src/cli/setup.d.ts.map +0 -1
  103. package/dist/src/cli/setup.js.map +0 -1
  104. package/dist/src/cli/test-gen.d.ts.map +0 -1
  105. package/dist/src/cli/test-gen.js.map +0 -1
  106. package/dist/src/cli/triage.d.ts.map +0 -1
  107. package/dist/src/cli/triage.js.map +0 -1
  108. package/dist/src/cli/watch.d.ts.map +0 -1
  109. package/dist/src/cli/watch.js.map +0 -1
  110. package/dist/src/cli/worker.d.ts.map +0 -1
  111. package/dist/src/cli/worker.js.map +0 -1
  112. package/dist/src/core/cache/cached-engine.d.ts.map +0 -1
  113. package/dist/src/core/cache/cached-engine.js.map +0 -1
  114. package/dist/src/core/cache/review-cache.d.ts.map +0 -1
  115. package/dist/src/core/cache/review-cache.js.map +0 -1
  116. package/dist/src/core/chunking/index.d.ts.map +0 -1
  117. package/dist/src/core/chunking/index.js.map +0 -1
  118. package/dist/src/core/chunking/risk-ranker.d.ts.map +0 -1
  119. package/dist/src/core/chunking/risk-ranker.js.map +0 -1
  120. package/dist/src/core/config/loader.d.ts.map +0 -1
  121. package/dist/src/core/config/loader.js.map +0 -1
  122. package/dist/src/core/config/preset-resolver.d.ts.map +0 -1
  123. package/dist/src/core/config/preset-resolver.js.map +0 -1
  124. package/dist/src/core/config/schema.d.ts.map +0 -1
  125. package/dist/src/core/config/schema.js.map +0 -1
  126. package/dist/src/core/config/types.d.ts.map +0 -1
  127. package/dist/src/core/config/types.js.map +0 -1
  128. package/dist/src/core/council/config.d.ts.map +0 -1
  129. package/dist/src/core/council/config.js.map +0 -1
  130. package/dist/src/core/council/context.d.ts.map +0 -1
  131. package/dist/src/core/council/context.js.map +0 -1
  132. package/dist/src/core/council/runner.d.ts.map +0 -1
  133. package/dist/src/core/council/runner.js.map +0 -1
  134. package/dist/src/core/council/types.d.ts.map +0 -1
  135. package/dist/src/core/council/types.js.map +0 -1
  136. package/dist/src/core/detect/git-context.d.ts.map +0 -1
  137. package/dist/src/core/detect/git-context.js.map +0 -1
  138. package/dist/src/core/detect/llm-key.d.ts.map +0 -1
  139. package/dist/src/core/detect/llm-key.js.map +0 -1
  140. package/dist/src/core/detect/protected-paths.d.ts.map +0 -1
  141. package/dist/src/core/detect/protected-paths.js.map +0 -1
  142. package/dist/src/core/detect/provider-usage.d.ts.map +0 -1
  143. package/dist/src/core/detect/provider-usage.js.map +0 -1
  144. package/dist/src/core/detect/stack.d.ts.map +0 -1
  145. package/dist/src/core/detect/stack.js.map +0 -1
  146. package/dist/src/core/detect/workspaces.d.ts.map +0 -1
  147. package/dist/src/core/detect/workspaces.js.map +0 -1
  148. package/dist/src/core/errors.d.ts.map +0 -1
  149. package/dist/src/core/errors.js.map +0 -1
  150. package/dist/src/core/findings/dedup.d.ts.map +0 -1
  151. package/dist/src/core/findings/dedup.js.map +0 -1
  152. package/dist/src/core/findings/types.d.ts.map +0 -1
  153. package/dist/src/core/findings/types.js.map +0 -1
  154. package/dist/src/core/fix/generator.d.ts.map +0 -1
  155. package/dist/src/core/fix/generator.js.map +0 -1
  156. package/dist/src/core/git/diff-hunks.d.ts.map +0 -1
  157. package/dist/src/core/git/diff-hunks.js.map +0 -1
  158. package/dist/src/core/git/touched-files.d.ts.map +0 -1
  159. package/dist/src/core/git/touched-files.js.map +0 -1
  160. package/dist/src/core/ignore/index.d.ts.map +0 -1
  161. package/dist/src/core/ignore/index.js.map +0 -1
  162. package/dist/src/core/index.d.ts.map +0 -1
  163. package/dist/src/core/index.js.map +0 -1
  164. package/dist/src/core/logging/ndjson-writer.d.ts.map +0 -1
  165. package/dist/src/core/logging/ndjson-writer.js.map +0 -1
  166. package/dist/src/core/logging/redaction.d.ts.map +0 -1
  167. package/dist/src/core/logging/redaction.js.map +0 -1
  168. package/dist/src/core/mcp/concurrency.d.ts.map +0 -1
  169. package/dist/src/core/mcp/concurrency.js.map +0 -1
  170. package/dist/src/core/mcp/handlers/fix-finding.d.ts.map +0 -1
  171. package/dist/src/core/mcp/handlers/fix-finding.js.map +0 -1
  172. package/dist/src/core/mcp/handlers/get-capabilities.d.ts.map +0 -1
  173. package/dist/src/core/mcp/handlers/get-capabilities.js.map +0 -1
  174. package/dist/src/core/mcp/handlers/get-findings.d.ts.map +0 -1
  175. package/dist/src/core/mcp/handlers/get-findings.js.map +0 -1
  176. package/dist/src/core/mcp/handlers/review-diff.d.ts.map +0 -1
  177. package/dist/src/core/mcp/handlers/review-diff.js.map +0 -1
  178. package/dist/src/core/mcp/handlers/scan-files.d.ts.map +0 -1
  179. package/dist/src/core/mcp/handlers/scan-files.js.map +0 -1
  180. package/dist/src/core/mcp/handlers/validate-fix.d.ts.map +0 -1
  181. package/dist/src/core/mcp/handlers/validate-fix.js.map +0 -1
  182. package/dist/src/core/mcp/run-store.d.ts.map +0 -1
  183. package/dist/src/core/mcp/run-store.js.map +0 -1
  184. package/dist/src/core/mcp/workspace.d.ts.map +0 -1
  185. package/dist/src/core/mcp/workspace.js.map +0 -1
  186. package/dist/src/core/persist/baseline.d.ts.map +0 -1
  187. package/dist/src/core/persist/baseline.js.map +0 -1
  188. package/dist/src/core/persist/cost-log.d.ts.map +0 -1
  189. package/dist/src/core/persist/cost-log.js.map +0 -1
  190. package/dist/src/core/persist/findings-cache.d.ts.map +0 -1
  191. package/dist/src/core/persist/findings-cache.js.map +0 -1
  192. package/dist/src/core/persist/triage.d.ts.map +0 -1
  193. package/dist/src/core/persist/triage.js.map +0 -1
  194. package/dist/src/core/phases/static-rules.d.ts.map +0 -1
  195. package/dist/src/core/phases/static-rules.js.map +0 -1
  196. package/dist/src/core/phases/tests.d.ts.map +0 -1
  197. package/dist/src/core/phases/tests.js.map +0 -1
  198. package/dist/src/core/pipeline/review-phase.d.ts.map +0 -1
  199. package/dist/src/core/pipeline/review-phase.js.map +0 -1
  200. package/dist/src/core/pipeline/run.d.ts.map +0 -1
  201. package/dist/src/core/pipeline/run.js.map +0 -1
  202. package/dist/src/core/runtime/idempotency.d.ts.map +0 -1
  203. package/dist/src/core/runtime/idempotency.js.map +0 -1
  204. package/dist/src/core/runtime/lock.d.ts.map +0 -1
  205. package/dist/src/core/runtime/lock.js.map +0 -1
  206. package/dist/src/core/runtime/state.d.ts.map +0 -1
  207. package/dist/src/core/runtime/state.js.map +0 -1
  208. package/dist/src/core/schema-alignment/detector.d.ts.map +0 -1
  209. package/dist/src/core/schema-alignment/detector.js.map +0 -1
  210. package/dist/src/core/schema-alignment/extractor/index.d.ts.map +0 -1
  211. package/dist/src/core/schema-alignment/extractor/index.js.map +0 -1
  212. package/dist/src/core/schema-alignment/extractor/prisma.d.ts.map +0 -1
  213. package/dist/src/core/schema-alignment/extractor/prisma.js.map +0 -1
  214. package/dist/src/core/schema-alignment/extractor/sql.d.ts.map +0 -1
  215. package/dist/src/core/schema-alignment/extractor/sql.js.map +0 -1
  216. package/dist/src/core/schema-alignment/llm-check.d.ts.map +0 -1
  217. package/dist/src/core/schema-alignment/llm-check.js.map +0 -1
  218. package/dist/src/core/schema-alignment/scanner.d.ts.map +0 -1
  219. package/dist/src/core/schema-alignment/scanner.js.map +0 -1
  220. package/dist/src/core/schema-alignment/types.d.ts.map +0 -1
  221. package/dist/src/core/schema-alignment/types.js.map +0 -1
  222. package/dist/src/core/shell.d.ts.map +0 -1
  223. package/dist/src/core/shell.js.map +0 -1
  224. package/dist/src/core/static-rules/registry.d.ts.map +0 -1
  225. package/dist/src/core/static-rules/registry.js.map +0 -1
  226. package/dist/src/core/static-rules/rules/brand-tokens.d.ts.map +0 -1
  227. package/dist/src/core/static-rules/rules/brand-tokens.js.map +0 -1
  228. package/dist/src/core/static-rules/rules/console-log.d.ts.map +0 -1
  229. package/dist/src/core/static-rules/rules/console-log.js.map +0 -1
  230. package/dist/src/core/static-rules/rules/hardcoded-secrets.d.ts.map +0 -1
  231. package/dist/src/core/static-rules/rules/hardcoded-secrets.js.map +0 -1
  232. package/dist/src/core/static-rules/rules/insecure-redirect.d.ts.map +0 -1
  233. package/dist/src/core/static-rules/rules/insecure-redirect.js.map +0 -1
  234. package/dist/src/core/static-rules/rules/large-file.d.ts.map +0 -1
  235. package/dist/src/core/static-rules/rules/large-file.js.map +0 -1
  236. package/dist/src/core/static-rules/rules/missing-auth.d.ts.map +0 -1
  237. package/dist/src/core/static-rules/rules/missing-auth.js.map +0 -1
  238. package/dist/src/core/static-rules/rules/missing-tests.d.ts.map +0 -1
  239. package/dist/src/core/static-rules/rules/missing-tests.js.map +0 -1
  240. package/dist/src/core/static-rules/rules/npm-audit.d.ts.map +0 -1
  241. package/dist/src/core/static-rules/rules/npm-audit.js.map +0 -1
  242. package/dist/src/core/static-rules/rules/package-lock-sync.d.ts.map +0 -1
  243. package/dist/src/core/static-rules/rules/package-lock-sync.js.map +0 -1
  244. package/dist/src/core/static-rules/rules/schema-alignment.d.ts.map +0 -1
  245. package/dist/src/core/static-rules/rules/schema-alignment.js.map +0 -1
  246. package/dist/src/core/static-rules/rules/sql-injection.d.ts.map +0 -1
  247. package/dist/src/core/static-rules/rules/sql-injection.js.map +0 -1
  248. package/dist/src/core/static-rules/rules/ssrf.d.ts.map +0 -1
  249. package/dist/src/core/static-rules/rules/ssrf.js.map +0 -1
  250. package/dist/src/core/static-rules/rules/todo-fixme.d.ts.map +0 -1
  251. package/dist/src/core/static-rules/rules/todo-fixme.js.map +0 -1
  252. package/dist/src/core/static-rules/tailwind-extractor.d.ts.map +0 -1
  253. package/dist/src/core/static-rules/tailwind-extractor.js.map +0 -1
  254. package/dist/src/core/test-gen/coverage-analyzer.d.ts.map +0 -1
  255. package/dist/src/core/test-gen/coverage-analyzer.js.map +0 -1
  256. package/dist/src/core/test-gen/framework-detector.d.ts.map +0 -1
  257. package/dist/src/core/test-gen/framework-detector.js.map +0 -1
  258. package/dist/src/core/test-gen/test-writer.d.ts.map +0 -1
  259. package/dist/src/core/test-gen/test-writer.js.map +0 -1
  260. package/dist/src/core/ui/design-context-loader.d.ts.map +0 -1
  261. package/dist/src/core/ui/design-context-loader.js.map +0 -1
  262. package/dist/src/core/worker/client.d.ts.map +0 -1
  263. package/dist/src/core/worker/client.js.map +0 -1
  264. package/dist/src/core/worker/lockfile.d.ts.map +0 -1
  265. package/dist/src/core/worker/lockfile.js.map +0 -1
  266. package/dist/src/core/worker/server.d.ts.map +0 -1
  267. package/dist/src/core/worker/server.js.map +0 -1
  268. package/dist/src/formatters/github-annotations.d.ts.map +0 -1
  269. package/dist/src/formatters/github-annotations.js.map +0 -1
  270. package/dist/src/formatters/index.d.ts.map +0 -1
  271. package/dist/src/formatters/index.js.map +0 -1
  272. package/dist/src/formatters/junit.d.ts.map +0 -1
  273. package/dist/src/formatters/junit.js.map +0 -1
  274. package/dist/src/formatters/sarif.d.ts.map +0 -1
  275. package/dist/src/formatters/sarif.js.map +0 -1
  276. package/dist/src/index.d.ts.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-bot-parser/types.ts +0 -9
  288. package/src/adapters/review-engine/auto.ts +0 -94
  289. package/src/adapters/review-engine/claude.ts +0 -100
  290. package/src/adapters/review-engine/codex.ts +0 -82
  291. package/src/adapters/review-engine/gemini.ts +0 -105
  292. package/src/adapters/review-engine/openai-compatible.ts +0 -100
  293. package/src/adapters/review-engine/parse-output.ts +0 -74
  294. package/src/adapters/review-engine/prompt-builder.ts +0 -19
  295. package/src/adapters/review-engine/types.ts +0 -19
  296. package/src/adapters/vcs-host/commit-status.ts +0 -39
  297. package/src/adapters/vcs-host/github.ts +0 -77
  298. package/src/adapters/vcs-host/types.ts +0 -44
  299. package/src/cli/_pkg-root.ts +0 -85
  300. package/src/cli/autoregress-bridge.ts +0 -30
  301. package/src/cli/baseline.ts +0 -125
  302. package/src/cli/ci.ts +0 -45
  303. package/src/cli/costs.ts +0 -80
  304. package/src/cli/council.ts +0 -96
  305. package/src/cli/detector.ts +0 -92
  306. package/src/cli/explain.ts +0 -197
  307. package/src/cli/fix.ts +0 -249
  308. package/src/cli/hook.ts +0 -124
  309. package/src/cli/ignore-helper.ts +0 -116
  310. package/src/cli/index.ts +0 -612
  311. package/src/cli/lsp.ts +0 -200
  312. package/src/cli/mcp.ts +0 -206
  313. package/src/cli/migrate-v4.ts +0 -388
  314. package/src/cli/pr-comment.ts +0 -139
  315. package/src/cli/pr-desc.ts +0 -168
  316. package/src/cli/pr-review-comments.ts +0 -92
  317. package/src/cli/pr.ts +0 -76
  318. package/src/cli/preflight.ts +0 -235
  319. package/src/cli/report.ts +0 -186
  320. package/src/cli/run.ts +0 -425
  321. package/src/cli/scan.ts +0 -233
  322. package/src/cli/setup.ts +0 -191
  323. package/src/cli/test-gen.ts +0 -125
  324. package/src/cli/triage.ts +0 -137
  325. package/src/cli/watch.ts +0 -190
  326. package/src/cli/worker.ts +0 -109
  327. package/src/core/.gitkeep +0 -0
  328. package/src/core/cache/cached-engine.ts +0 -32
  329. package/src/core/cache/review-cache.ts +0 -70
  330. package/src/core/chunking/index.ts +0 -113
  331. package/src/core/chunking/risk-ranker.ts +0 -56
  332. package/src/core/config/loader.ts +0 -53
  333. package/src/core/config/preset-resolver.ts +0 -46
  334. package/src/core/config/schema.ts +0 -181
  335. package/src/core/config/types.ts +0 -98
  336. package/src/core/council/config.ts +0 -71
  337. package/src/core/council/context.ts +0 -17
  338. package/src/core/council/runner.ts +0 -83
  339. package/src/core/council/types.ts +0 -45
  340. package/src/core/detect/git-context.ts +0 -27
  341. package/src/core/detect/llm-key.ts +0 -89
  342. package/src/core/detect/protected-paths.ts +0 -63
  343. package/src/core/detect/provider-usage.ts +0 -74
  344. package/src/core/detect/stack.ts +0 -153
  345. package/src/core/detect/workspaces.ts +0 -103
  346. package/src/core/errors.ts +0 -37
  347. package/src/core/findings/dedup.ts +0 -14
  348. package/src/core/findings/types.ts +0 -39
  349. package/src/core/fix/generator.ts +0 -149
  350. package/src/core/git/diff-hunks.ts +0 -86
  351. package/src/core/git/touched-files.ts +0 -73
  352. package/src/core/ignore/index.ts +0 -54
  353. package/src/core/index.ts +0 -1
  354. package/src/core/logging/ndjson-writer.ts +0 -37
  355. package/src/core/logging/redaction.ts +0 -19
  356. package/src/core/mcp/concurrency.ts +0 -16
  357. package/src/core/mcp/handlers/fix-finding.ts +0 -126
  358. package/src/core/mcp/handlers/get-capabilities.ts +0 -62
  359. package/src/core/mcp/handlers/get-findings.ts +0 -36
  360. package/src/core/mcp/handlers/review-diff.ts +0 -65
  361. package/src/core/mcp/handlers/scan-files.ts +0 -65
  362. package/src/core/mcp/handlers/validate-fix.ts +0 -41
  363. package/src/core/mcp/run-store.ts +0 -85
  364. package/src/core/mcp/workspace.ts +0 -35
  365. package/src/core/persist/baseline.ts +0 -112
  366. package/src/core/persist/cost-log.ts +0 -30
  367. package/src/core/persist/findings-cache.ts +0 -43
  368. package/src/core/persist/triage.ts +0 -112
  369. package/src/core/phases/static-rules.ts +0 -93
  370. package/src/core/phases/tests.ts +0 -51
  371. package/src/core/pipeline/review-phase.ts +0 -182
  372. package/src/core/pipeline/run.ts +0 -116
  373. package/src/core/runtime/idempotency.ts +0 -6
  374. package/src/core/runtime/lock.ts +0 -29
  375. package/src/core/runtime/state.ts +0 -97
  376. package/src/core/schema-alignment/detector.ts +0 -59
  377. package/src/core/schema-alignment/extractor/index.ts +0 -24
  378. package/src/core/schema-alignment/extractor/prisma.ts +0 -21
  379. package/src/core/schema-alignment/extractor/sql.ts +0 -99
  380. package/src/core/schema-alignment/llm-check.ts +0 -91
  381. package/src/core/schema-alignment/scanner.ts +0 -107
  382. package/src/core/schema-alignment/types.ts +0 -43
  383. package/src/core/shell.ts +0 -48
  384. package/src/core/static-rules/registry.ts +0 -59
  385. package/src/core/static-rules/rules/brand-tokens.ts +0 -145
  386. package/src/core/static-rules/rules/console-log.ts +0 -42
  387. package/src/core/static-rules/rules/hardcoded-secrets.ts +0 -83
  388. package/src/core/static-rules/rules/insecure-redirect.ts +0 -67
  389. package/src/core/static-rules/rules/large-file.ts +0 -37
  390. package/src/core/static-rules/rules/missing-auth.ts +0 -70
  391. package/src/core/static-rules/rules/missing-tests.ts +0 -57
  392. package/src/core/static-rules/rules/npm-audit.ts +0 -38
  393. package/src/core/static-rules/rules/package-lock-sync.ts +0 -54
  394. package/src/core/static-rules/rules/schema-alignment.ts +0 -132
  395. package/src/core/static-rules/rules/sql-injection.ts +0 -71
  396. package/src/core/static-rules/rules/ssrf.ts +0 -63
  397. package/src/core/static-rules/rules/todo-fixme.ts +0 -40
  398. package/src/core/static-rules/tailwind-extractor.ts +0 -38
  399. package/src/core/test-gen/coverage-analyzer.ts +0 -93
  400. package/src/core/test-gen/framework-detector.ts +0 -21
  401. package/src/core/test-gen/test-writer.ts +0 -33
  402. package/src/core/ui/design-context-loader.ts +0 -87
  403. package/src/core/worker/client.ts +0 -46
  404. package/src/core/worker/lockfile.ts +0 -38
  405. package/src/core/worker/server.ts +0 -81
  406. package/src/formatters/github-annotations.ts +0 -36
  407. package/src/formatters/index.ts +0 -3
  408. package/src/formatters/junit.ts +0 -52
  409. package/src/formatters/sarif.ts +0 -103
  410. package/src/index.ts +0 -3
@@ -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
- }