hex-audit 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +137 -77
- package/DEMO.md +40 -117
- package/README.md +200 -402
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/app-build-manifest.json +56 -101
- package/dashboard/.next/app-path-routes-manifest.json +1 -1
- package/dashboard/.next/build-manifest.json +9 -9
- package/dashboard/.next/next-server.js.nft.json +1 -1
- package/dashboard/.next/prerender-manifest.json +1 -1
- package/dashboard/.next/react-loadable-manifest.json +436 -15
- package/dashboard/.next/routes-manifest.json +1 -1
- package/dashboard/.next/server/app/_not-found/page.js +1 -1
- package/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/api/code/route.js +1 -1
- package/dashboard/.next/server/app/api/code/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/comments/route.js +1 -0
- package/dashboard/.next/server/app/api/comments/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/export/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/export/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/resolve/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/resolve/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/route.js +1 -0
- package/dashboard/.next/server/app/api/diagrams/[name]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/figures/[name]/route.js +1 -0
- package/dashboard/.next/server/app/api/figures/[name]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/focus/route.js +1 -0
- package/dashboard/.next/server/app/api/focus/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/github-status/route.js +1 -1
- package/dashboard/.next/server/app/api/invariants/[id]/route.js +1 -0
- package/dashboard/.next/server/app/api/invariants/[id]/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/revert-auto/route.js +1 -0
- package/dashboard/.next/server/app/api/issues/[id]/revert-auto/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/nav/route.js +1 -0
- package/dashboard/.next/server/app/api/nav/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/notes/done/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/done/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/lead/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/lead/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/question/route.js +1 -1
- package/dashboard/.next/server/app/api/notes/question/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/notes/record/route.js +3 -3
- package/dashboard/.next/server/app/api/notes/route.js +2 -2
- package/dashboard/.next/server/app/api/palette/route.js +1 -0
- package/dashboard/.next/server/app/api/palette/route.js.nft.json +1 -0
- package/dashboard/.next/server/app/api/progress/route.js +1 -1
- package/dashboard/.next/server/app/api/progress/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/watch/route.js +2 -2
- package/dashboard/.next/server/app/api/watch/route.js.nft.json +1 -1
- package/dashboard/.next/server/app/api/xref/route.js +1 -0
- package/dashboard/.next/server/app/changes/page.js +1 -20
- package/dashboard/.next/server/app/changes/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/changes/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/excalidraw-assets/[...path]/route.js +1 -0
- package/dashboard/.next/server/app/issues/page.js +5 -28
- package/dashboard/.next/server/app/issues/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/model/page.js +1 -0
- package/dashboard/.next/server/app/{calls → model}/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/model/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/page.js +1 -20
- package/dashboard/.next/server/app/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/report/page.js +1 -1
- package/dashboard/.next/server/app/report/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/review/page.js +1 -0
- package/dashboard/.next/server/app/{access → review}/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/review/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app-paths-manifest.json +19 -16
- package/dashboard/.next/server/chunks/310.js +4 -0
- package/dashboard/.next/server/chunks/370.js +1 -0
- package/dashboard/.next/server/chunks/42.js +1 -1
- package/dashboard/.next/server/chunks/624.js +14 -0
- package/dashboard/.next/server/chunks/645.js +1 -1
- package/dashboard/.next/server/chunks/649.js +1 -1
- package/dashboard/.next/server/chunks/653.js +1 -0
- package/dashboard/.next/server/functions-config-manifest.json +1 -1
- package/dashboard/.next/server/middleware-build-manifest.js +1 -1
- package/dashboard/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/server/pages/_error.js +1 -1
- package/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/static/chunks/0bbe10ee.8e7ffa06d2170dfe.js +84 -0
- package/dashboard/.next/static/chunks/1026.0ef689a305302427.js +1 -0
- package/dashboard/.next/static/chunks/1164.34eb76767ebea46f.js +8 -0
- package/dashboard/.next/static/chunks/119.a9a79633900a235f.js +5 -0
- package/dashboard/.next/static/chunks/1291.6c486c9b1d4b1b3a.js +1 -0
- package/dashboard/.next/static/chunks/139.4691848fc5a46253.js +10 -0
- package/dashboard/.next/static/chunks/145.1bf74fecdb4022e3.js +11 -0
- package/dashboard/.next/static/chunks/1517.8e7075f78e22b3a0.js +8 -0
- package/dashboard/.next/static/chunks/165.6f174060a0ce2db4.js +6 -0
- package/dashboard/.next/static/chunks/1741.5c370b7702d2eb40.js +8 -0
- package/dashboard/.next/static/chunks/1e36816c.5748c83adc8a6bd6.js +108 -0
- package/dashboard/.next/static/chunks/2061.eab75b3c1dfa068a.js +1 -0
- package/dashboard/.next/static/chunks/2148.3ce718f62d1b2f7c.js +10 -0
- package/dashboard/.next/static/chunks/217-1d5b680ffd10e3f9.js +1 -0
- package/dashboard/.next/static/chunks/2208.fb884379aa3ae968.js +1 -0
- package/dashboard/.next/static/chunks/2276.112c7855333fca5f.js +6 -0
- package/dashboard/.next/static/chunks/2374-8c6f137938f8518a.js +1 -0
- package/dashboard/.next/static/chunks/2445.18a86507d2996b95.js +1 -0
- package/dashboard/.next/static/chunks/2712.15dd8577973baf22.js +10 -0
- package/dashboard/.next/static/chunks/2759.533dec5317e0a1d1.js +1 -0
- package/dashboard/.next/static/chunks/2812.62b213bef580b69a.js +1 -0
- package/dashboard/.next/static/chunks/2895.bb57cacb7aaf42a1.js +9 -0
- package/dashboard/.next/static/chunks/2972.e5a9251b538dcf19.js +9 -0
- package/dashboard/.next/static/chunks/3206.8d9a10db2b04b93f.js +1 -0
- package/dashboard/.next/static/chunks/3485.36766504793b7237.js +9 -0
- package/dashboard/.next/static/chunks/3725.de9376dc994735d4.js +9 -0
- package/dashboard/.next/static/chunks/3774.1df377928e8387f7.js +9 -0
- package/dashboard/.next/static/chunks/3963.39d72b3875dfe2e9.js +13 -0
- package/dashboard/.next/static/chunks/4013.73884b23bfaebdde.js +11 -0
- package/dashboard/.next/static/chunks/4117.278aff1fa23fd36e.js +6 -0
- package/dashboard/.next/static/chunks/4210.cc8594110017c579.js +11 -0
- package/dashboard/.next/static/chunks/4282.28485875540886cc.js +7 -0
- package/dashboard/.next/static/chunks/4318.a2f469a88d88f6d0.js +8 -0
- package/dashboard/.next/static/chunks/4363.8999a6e727c48003.js +1 -0
- package/dashboard/.next/static/chunks/4641.e03d118fffebd580.js +5 -0
- package/dashboard/.next/static/chunks/483.a910dab7734a1074.js +8 -0
- package/dashboard/.next/static/chunks/4926.76693f542e9cc062.js +6 -0
- package/dashboard/.next/static/chunks/4938.03f6d04dabf38745.js +10 -0
- package/dashboard/.next/static/chunks/5112.0757c2b0c285e62e.js +1 -0
- package/dashboard/.next/static/chunks/5199.c83ea7efb0eec705.js +11 -0
- package/dashboard/.next/static/chunks/530.849957a8907eb288.js +1 -0
- package/dashboard/.next/static/chunks/5424.4e8ca0711a32bccf.js +7 -0
- package/dashboard/.next/static/chunks/55.a593a78be9714679.js +1 -0
- package/dashboard/.next/static/chunks/5535.6cd0bd8d368d8902.js +4 -0
- package/dashboard/.next/static/chunks/5626.7d4e93d7acbeffc9.js +10 -0
- package/dashboard/.next/static/chunks/5775.a0d7c1b1e89b9a93.js +9 -0
- package/dashboard/.next/static/chunks/6118.266956b3333b1d7a.js +9 -0
- package/dashboard/.next/static/chunks/6121.a2e6d93720b1205e.js +77 -0
- package/dashboard/.next/static/chunks/6853.d3ad43614e8ca0ab.js +1 -0
- package/dashboard/.next/static/chunks/6951.02a3a158d02158c9.js +5 -0
- package/dashboard/.next/static/chunks/6970.013f24568c87d918.js +11 -0
- package/dashboard/.next/static/chunks/7013.39d41e82b37be63b.js +9 -0
- package/dashboard/.next/static/chunks/7107.1c5412197912b8ed.js +8 -0
- package/dashboard/.next/static/chunks/7508.dd60e2d06d149f5f.js +9 -0
- package/dashboard/.next/static/chunks/7524.0fde4c61553d1491.js +3 -0
- package/dashboard/.next/static/chunks/7834-47f318a04a05688f.js +1 -0
- package/dashboard/.next/static/chunks/8317.d0b3eddef4cae0d5.js +1 -0
- package/dashboard/.next/static/chunks/838.2b2aa006519ba44c.js +10 -0
- package/dashboard/.next/static/chunks/8398.924fd8f4c83417c0.js +7 -0
- package/dashboard/.next/static/chunks/8428b36f.8ac4e67061c01307.js +34 -0
- package/dashboard/.next/static/chunks/8514.85ccbbea8ab21d04.js +5 -0
- package/dashboard/.next/static/chunks/8538.5f7ebe76c4b63162.js +1 -0
- package/dashboard/.next/static/chunks/8687.9406baa8b5601fd0.js +1 -0
- package/dashboard/.next/static/chunks/8721.47346e2cb6412376.js +10 -0
- package/dashboard/.next/static/chunks/8770.4f544bd1a6f03a62.js +8 -0
- package/dashboard/.next/static/chunks/8812.3d96fd54dba566f8.js +9 -0
- package/dashboard/.next/static/chunks/8962.d22aa67a97970dd8.js +1 -0
- package/dashboard/.next/static/chunks/8986.b327224b83f4399a.js +5 -0
- package/dashboard/.next/static/chunks/9271.5f66c19a8ee1ff36.js +10 -0
- package/dashboard/.next/static/chunks/9282.f8d01442bab4c0da.js +2 -0
- package/dashboard/.next/static/chunks/9366.0ec24a0791b9b00f.js +1 -0
- package/dashboard/.next/static/chunks/9707.5cd7d2ee933a4af5.js +6 -0
- package/dashboard/.next/static/chunks/9716.15fffc0b0038601d.js +4 -0
- package/dashboard/.next/static/chunks/9791.e3b3f5a367f63c8a.js +1 -0
- package/dashboard/.next/static/chunks/9820.8c1efad5260e8137.js +1 -0
- package/dashboard/.next/static/chunks/985.50150e9eaa4bde33.js +39 -0
- package/dashboard/.next/static/chunks/997.56901b86e1b8a87b.js +8 -0
- package/dashboard/.next/static/chunks/app/changes/page-f8a860034221cad4.js +1 -0
- package/dashboard/.next/static/chunks/app/issues/page-da4da93188c414a6.js +1 -0
- package/dashboard/.next/static/chunks/app/layout-27a9da4610423c1e.js +1 -0
- package/dashboard/.next/static/chunks/app/model/page-9680e22fdd6ddb81.js +1 -0
- package/dashboard/.next/static/chunks/app/page-0e67750d99fb2836.js +1 -0
- package/dashboard/.next/static/chunks/app/report/page-b56b1db9b9dcf2b6.js +1 -0
- package/dashboard/.next/static/chunks/app/review/page-3ef69f0e0badd333.js +1 -0
- package/dashboard/.next/static/chunks/c75e29e3.d91220f782934d80.js +1 -0
- package/dashboard/.next/static/chunks/{main-cc3a889b25e9aa68.js → main-9c95a7ffedc7afb4.js} +1 -1
- package/dashboard/.next/static/chunks/webpack-6da70e4f9fcf1799.js +1 -0
- package/dashboard/.next/static/css/ceafd91ca8dd753d.css +3 -0
- package/dashboard/.next/static/css/e4aad1f9c715b79a.css +1 -0
- package/dashboard/.next/static/media/Assistant-Bold.c8f39f24.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-Medium.1e75d8e6.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-Regular.7acbabb8.woff2 +0 -0
- package/dashboard/.next/static/media/Assistant-SemiBold.167acbf8.woff2 +0 -0
- package/dashboard/app/api/code/route.ts +26 -20
- package/dashboard/app/api/comments/route.ts +158 -0
- package/dashboard/app/api/diagrams/[name]/export/route.ts +26 -0
- package/dashboard/app/api/diagrams/[name]/resolve/route.ts +25 -0
- package/dashboard/app/api/diagrams/[name]/route.ts +37 -0
- package/dashboard/app/api/figures/[name]/route.ts +15 -0
- package/dashboard/app/api/focus/route.ts +35 -0
- package/dashboard/app/api/invariants/[id]/route.ts +35 -0
- package/dashboard/app/api/issues/[id]/revert-auto/route.ts +18 -0
- package/dashboard/app/api/nav/route.ts +120 -0
- package/dashboard/app/api/palette/route.ts +68 -0
- package/dashboard/app/api/progress/route.ts +54 -23
- package/dashboard/app/api/xref/route.ts +30 -0
- package/dashboard/app/changes/ChangesClient.tsx +730 -356
- package/dashboard/app/changes/page.tsx +27 -19
- package/dashboard/app/excalidraw-assets/[...path]/route.ts +56 -0
- package/dashboard/app/globals.css +231 -77
- package/dashboard/app/issues/BoardClient.tsx +817 -0
- package/dashboard/app/issues/page.tsx +27 -272
- package/dashboard/app/layout.tsx +32 -17
- package/dashboard/app/model/ModelClient.tsx +1303 -0
- package/dashboard/app/model/page.tsx +98 -0
- package/dashboard/app/page.tsx +191 -277
- package/dashboard/app/report/ReportClient.tsx +147 -74
- package/dashboard/app/report/page.tsx +25 -14
- package/dashboard/app/review/ReviewClient.tsx +1180 -0
- package/dashboard/app/review/page.tsx +93 -0
- package/dashboard/components/AutoRefresh.tsx +22 -19
- package/dashboard/components/CodeComments.tsx +303 -0
- package/dashboard/components/CodeNav.tsx +523 -0
- package/dashboard/components/CodeReference.tsx +92 -99
- package/dashboard/components/CodeViewer.tsx +526 -0
- package/dashboard/components/CommandPalette.tsx +141 -66
- package/dashboard/components/DiagramCanvas.tsx +275 -0
- package/dashboard/components/DianeNote.tsx +244 -0
- package/dashboard/components/LiveStatus.tsx +30 -68
- package/dashboard/components/MarkdownRenderer.tsx +34 -32
- package/dashboard/components/RecordButton.tsx +132 -0
- package/dashboard/components/ui/Button.tsx +39 -0
- package/dashboard/components/ui/Chip.tsx +37 -0
- package/dashboard/components/ui/EmptyState.tsx +31 -0
- package/dashboard/components/ui/Icons.tsx +126 -0
- package/dashboard/components/ui/Inspector.tsx +122 -0
- package/dashboard/components/ui/Kbd.tsx +15 -0
- package/dashboard/components/ui/ListRow.tsx +92 -0
- package/dashboard/components/ui/LocalTime.tsx +14 -0
- package/dashboard/components/ui/ProgressRing.tsx +54 -0
- package/dashboard/components/ui/ResizeHandle.tsx +93 -0
- package/dashboard/components/ui/RiskMeter.tsx +27 -0
- package/dashboard/components/ui/SearchField.tsx +55 -0
- package/dashboard/components/ui/SegmentedControl.tsx +71 -0
- package/dashboard/components/ui/SeverityDot.tsx +57 -0
- package/dashboard/components/ui/Sidebar.tsx +236 -0
- package/dashboard/components/ui/SplitView.tsx +122 -0
- package/dashboard/components/ui/StateGlyph.tsx +66 -0
- package/dashboard/components/ui/Toast.tsx +91 -0
- package/dashboard/lib/api.ts +17 -0
- package/dashboard/lib/cn.ts +4 -0
- package/dashboard/lib/data.ts +2 -21
- package/dashboard/lib/finding-markdown.ts +1 -1
- package/dashboard/lib/focus.ts +42 -0
- package/dashboard/lib/hotkeys.ts +41 -0
- package/dashboard/lib/inline-markdown.test.ts +11 -0
- package/dashboard/lib/live.ts +32 -0
- package/dashboard/lib/pane-width.ts +36 -0
- package/dashboard/lib/server/board.ts +229 -0
- package/dashboard/lib/server/diagrams.ts +191 -0
- package/dashboard/lib/server/safe-path.ts +28 -0
- package/dashboard/lib/server/workspace.ts +113 -0
- package/dashboard/lib/server/xref.ts +42 -0
- package/dashboard/lib/solidity.test.ts +37 -0
- package/dashboard/lib/solidity.ts +191 -0
- package/dashboard/lib/source.ts +28 -0
- package/dashboard/lib/types.ts +164 -0
- package/dashboard/lib/url.ts +18 -0
- package/dashboard/lib/watcher.ts +31 -22
- package/dashboard/tailwind.config.ts +6 -3
- package/dist/analysis/code-model.d.ts.map +1 -1
- package/dist/analysis/code-model.js +4 -1
- package/dist/analysis/code-model.js.map +1 -1
- package/dist/analysis/diff.d.ts +12 -1
- package/dist/analysis/diff.d.ts.map +1 -1
- package/dist/analysis/diff.js +143 -0
- package/dist/analysis/diff.js.map +1 -1
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +17 -48
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/claude.d.ts.map +1 -1
- package/dist/commands/claude.js +5 -0
- package/dist/commands/claude.js.map +1 -1
- package/dist/commands/dashboard.d.ts.map +1 -1
- package/dist/commands/dashboard.js +10 -2
- package/dist/commands/dashboard.js.map +1 -1
- package/dist/commands/diagram.d.ts +3 -0
- package/dist/commands/diagram.d.ts.map +1 -0
- package/dist/commands/diagram.js +71 -0
- package/dist/commands/diagram.js.map +1 -0
- package/dist/commands/diff.d.ts +4 -5
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +56 -17
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +5 -18
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/facts.d.ts +23 -0
- package/dist/commands/facts.d.ts.map +1 -0
- package/dist/commands/facts.js +121 -0
- package/dist/commands/facts.js.map +1 -0
- package/dist/commands/fix-review.d.ts +9 -0
- package/dist/commands/fix-review.d.ts.map +1 -0
- package/dist/commands/fix-review.js +367 -0
- package/dist/commands/fix-review.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +51 -47
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/issue.d.ts.map +1 -1
- package/dist/commands/issue.js +151 -2
- package/dist/commands/issue.js.map +1 -1
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +11 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/model.d.ts +4 -0
- package/dist/commands/model.d.ts.map +1 -0
- package/dist/commands/model.js +275 -0
- package/dist/commands/model.js.map +1 -0
- package/dist/commands/note.d.ts.map +1 -1
- package/dist/commands/note.js +31 -1
- package/dist/commands/note.js.map +1 -1
- package/dist/commands/review.d.ts +4 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +164 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/core/comments.d.ts +59 -0
- package/dist/core/comments.d.ts.map +1 -0
- package/dist/core/comments.js +263 -0
- package/dist/core/comments.js.map +1 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +0 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/dedup.d.ts +56 -0
- package/dist/core/dedup.d.ts.map +1 -0
- package/dist/core/dedup.js +208 -0
- package/dist/core/dedup.js.map +1 -0
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +0 -15
- package/dist/core/errors.js.map +1 -1
- package/dist/core/external-tools.d.ts +0 -14
- package/dist/core/external-tools.d.ts.map +1 -1
- package/dist/core/external-tools.js +2 -52
- package/dist/core/external-tools.js.map +1 -1
- package/dist/core/fix-review.d.ts +54 -0
- package/dist/core/fix-review.d.ts.map +1 -0
- package/dist/core/fix-review.js +98 -0
- package/dist/core/fix-review.js.map +1 -0
- package/dist/core/fuzz-sync.d.ts +93 -0
- package/dist/core/fuzz-sync.d.ts.map +1 -0
- package/dist/core/fuzz-sync.js +516 -0
- package/dist/core/fuzz-sync.js.map +1 -0
- package/dist/core/git.d.ts +7 -0
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +42 -0
- package/dist/core/git.js.map +1 -1
- package/dist/core/issues.d.ts +32 -1
- package/dist/core/issues.d.ts.map +1 -1
- package/dist/core/issues.js +135 -3
- package/dist/core/issues.js.map +1 -1
- package/dist/core/mcp-config.d.ts +12 -0
- package/dist/core/mcp-config.d.ts.map +1 -0
- package/dist/core/mcp-config.js +29 -0
- package/dist/core/mcp-config.js.map +1 -0
- package/dist/core/model.d.ts +38 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/model.js +160 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/notes.d.ts +2 -0
- package/dist/core/notes.d.ts.map +1 -1
- package/dist/core/notes.js +13 -3
- package/dist/core/notes.js.map +1 -1
- package/dist/core/review.d.ts +47 -0
- package/dist/core/review.d.ts.map +1 -1
- package/dist/core/review.js +177 -1
- package/dist/core/review.js.map +1 -1
- package/dist/core/rules.d.ts +12 -0
- package/dist/core/rules.d.ts.map +1 -0
- package/dist/core/rules.js +66 -0
- package/dist/core/rules.js.map +1 -0
- package/dist/core/schema.d.ts +4817 -2245
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +452 -113
- package/dist/core/schema.js.map +1 -1
- package/dist/core/scope.d.ts +8 -0
- package/dist/core/scope.d.ts.map +1 -0
- package/dist/core/scope.js +18 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/diagrams/build.d.ts +18 -0
- package/dist/diagrams/build.d.ts.map +1 -0
- package/dist/diagrams/build.js +135 -0
- package/dist/diagrams/build.js.map +1 -0
- package/dist/diagrams/excalidraw.d.ts +27 -0
- package/dist/diagrams/excalidraw.d.ts.map +1 -0
- package/dist/diagrams/excalidraw.js +219 -0
- package/dist/diagrams/excalidraw.js.map +1 -0
- package/dist/diagrams/layout.d.ts +48 -0
- package/dist/diagrams/layout.d.ts.map +1 -0
- package/dist/diagrams/layout.js +686 -0
- package/dist/diagrams/layout.js.map +1 -0
- package/dist/facts/build.d.ts +23 -0
- package/dist/facts/build.d.ts.map +1 -0
- package/dist/facts/build.js +112 -0
- package/dist/facts/build.js.map +1 -0
- package/dist/facts/extract.d.ts +53 -0
- package/dist/facts/extract.d.ts.map +1 -0
- package/dist/facts/extract.js +635 -0
- package/dist/facts/extract.js.map +1 -0
- package/dist/facts/fallback.d.ts +7 -0
- package/dist/facts/fallback.d.ts.map +1 -0
- package/dist/facts/fallback.js +156 -0
- package/dist/facts/fallback.js.map +1 -0
- package/dist/facts/implementations.d.ts +29 -0
- package/dist/facts/implementations.d.ts.map +1 -0
- package/dist/facts/implementations.js +43 -0
- package/dist/facts/implementations.js.map +1 -0
- package/dist/facts/query.d.ts +35 -0
- package/dist/facts/query.d.ts.map +1 -0
- package/dist/facts/query.js +157 -0
- package/dist/facts/query.js.map +1 -0
- package/dist/facts/xref.d.ts +53 -0
- package/dist/facts/xref.d.ts.map +1 -0
- package/dist/facts/xref.js +282 -0
- package/dist/facts/xref.js.map +1 -0
- package/dist/index.js +14 -16
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +400 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/skills/ai-audit/SKILL.md +16 -6
- package/dist/skills/ai-audit/UPSTREAM.md +9 -4
- package/dist/skills/ai-audit/references/hex-board.md +34 -46
- package/dist/skills/diane.md +26 -12
- package/dist/skills/fix-review.md +58 -0
- package/dist/skills/fuzz/LICENSE +21 -0
- package/dist/skills/fuzz/SKILL.md +655 -0
- package/dist/skills/fuzz/UPSTREAM.md +119 -0
- package/dist/skills/fuzz/agents/implementers/global-property-implementer.md +81 -0
- package/dist/skills/fuzz/agents/implementers/specific-property-implementer.md +121 -0
- package/dist/skills/fuzz/agents/invariant-discovery/adversarial-profit-maximizer.md +123 -0
- package/dist/skills/fuzz/agents/invariant-discovery/conservation-auditor.md +92 -0
- package/dist/skills/fuzz/agents/invariant-discovery/protocol-type-specialist.md +173 -0
- package/dist/skills/fuzz/agents/invariant-discovery/roundtrip-rounding-analyst.md +164 -0
- package/dist/skills/fuzz/agents/invariant-discovery/state-transition-mapper.md +92 -0
- package/dist/skills/fuzz/agents/invariant-discovery/synthesizer.md +261 -0
- package/dist/skills/fuzz/agents/protocol-analyzer.md +80 -0
- package/dist/skills/fuzz/agents/report-writer.md +135 -0
- package/dist/skills/fuzz/references/handler-patterns.md +222 -0
- package/dist/skills/fuzz/references/hex-invariants.md +102 -0
- package/dist/skills/fuzz/references/property-generation.md +149 -0
- package/dist/skills/fuzz/references/selection-policy.md +49 -0
- package/dist/skills/fuzz/references/setup-playbook.md +92 -0
- package/dist/skills/fuzz/references/template-map.md +121 -0
- package/dist/skills/fuzz/scripts/ensure_foundry.sh +125 -0
- package/dist/skills/fuzz/scripts/estimate_cost.js +157 -0
- package/dist/skills/fuzz/scripts/extract_abis.js +303 -0
- package/dist/skills/fuzz/scripts/fizz_sync.js +692 -0
- package/dist/skills/fuzz/scripts/generate_handlers.js +370 -0
- package/dist/skills/fuzz/scripts/generate_suite.js +254 -0
- package/dist/skills/fuzz/scripts/lib/log-viewer.js +332 -0
- package/dist/skills/fuzz/scripts/run_echidna.js +192 -0
- package/dist/skills/fuzz/scripts/run_medusa.js +329 -0
- package/dist/skills/fuzz/scripts/select_functions.js +637 -0
- package/dist/skills/fuzz/scripts/setup_fuzz_profile.sh +142 -0
- package/dist/skills/fuzz/templates/Actor.sol +63 -0
- package/dist/skills/fuzz/templates/Base.sol +121 -0
- package/dist/skills/fuzz/templates/FoundryTester.sol +29 -0
- package/dist/skills/fuzz/templates/FuzzTester.sol +11 -0
- package/dist/skills/fuzz/templates/Properties.sol +17 -0
- package/dist/skills/fuzz/templates/README.md +56 -0
- package/dist/skills/fuzz/templates/Snapshots.sol +26 -0
- package/dist/skills/fuzz/templates/echidna.yaml +18 -0
- package/dist/skills/fuzz/templates/handlers/Handlers.sol +13 -0
- package/dist/skills/fuzz/templates/medusa.json +93 -0
- package/dist/skills/fuzz/templates/utils/Clamp.sol +223 -0
- package/dist/skills/fuzz/templates/utils/DecimalPrinter.sol +63 -0
- package/dist/skills/fuzz/templates/utils/Deployer.sol +17 -0
- package/dist/skills/fuzz/templates/utils/EnumerableSet.sol +206 -0
- package/dist/skills/fuzz/templates/utils/Hevm.sol +62 -0
- package/dist/skills/fuzz/templates/utils/Logger.sol +619 -0
- package/dist/skills/fuzz/templates/utils/Math.sol +52 -0
- package/dist/skills/fuzz/templates/utils/MockERC20.sol +279 -0
- package/dist/skills/fuzz/templates/utils/PropertiesAsserts.sol +238 -0
- package/dist/skills/fuzz/templates/utils/StringUtils.sol +85 -0
- package/dist/skills/fuzz-convert/SKILL.md +249 -0
- package/dist/skills/fuzz-sync/SKILL.md +342 -0
- package/dist/skills/generate-poc.md +8 -26
- package/dist/skills/generate-report.md +17 -5
- package/dist/skills/ingest-aa-report.md +11 -30
- package/dist/skills/init-audit/SKILL.md +155 -0
- package/dist/skills/init-audit/references/agents/conformance-checker.md +36 -0
- package/dist/skills/init-audit/references/agents/contract-reader.md +59 -0
- package/dist/skills/init-audit/references/agents/diagram-composer.md +48 -0
- package/dist/skills/init-audit/references/agents/docs-extractor.md +26 -0
- package/dist/skills/init-audit/references/agents/prior-audit.md +32 -0
- package/dist/skills/init-audit/references/agents/regression-checker.md +28 -0
- package/dist/skills/init-audit/references/agents/skeptic.md +31 -0
- package/dist/skills/init-audit/references/agents/standards-checker.md +39 -0
- package/dist/skills/init-audit/references/agents/synthesizer.md +50 -0
- package/dist/skills/prevalidate.md +62 -0
- package/dist/skills/sync-issues.md +11 -25
- package/dist/skills/validate-all-findings.md +2 -2
- package/dist/skills/validate-finding.md +25 -24
- package/dist/skills/write-finding.md +6 -5
- package/dist/types/index.d.ts +16 -12
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +5 -4
- package/dashboard/.next/server/app/access/page.js +0 -1
- package/dashboard/.next/server/app/access/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/api/flows/route.js +0 -1
- package/dashboard/.next/server/app/api/mermaid/route.js +0 -1
- package/dashboard/.next/server/app/calls/page.js +0 -1
- package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/conformance/page.js +0 -1
- package/dashboard/.next/server/app/conformance/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/diagram/page.js +0 -1
- package/dashboard/.next/server/app/diagram/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/flows/page.js +0 -1
- package/dashboard/.next/server/app/flows/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/functions/page.js +0 -1
- package/dashboard/.next/server/app/functions/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/notes/page.js +0 -22
- package/dashboard/.next/server/app/notes/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/progress/page.js +0 -1
- package/dashboard/.next/server/app/progress/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/app/stats/page.js +0 -1
- package/dashboard/.next/server/app/stats/page.js.nft.json +0 -1
- package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +0 -1
- package/dashboard/.next/server/chunks/530.js +0 -1
- package/dashboard/.next/server/chunks/622.js +0 -3
- package/dashboard/.next/server/chunks/665.js +0 -13
- package/dashboard/.next/server/chunks/939.js +0 -1
- package/dashboard/.next/static/chunks/3017.4a5312e3c20a173f.js +0 -1
- package/dashboard/.next/static/chunks/7397-37adf76cad543297.js +0 -1
- package/dashboard/.next/static/chunks/7973.e34032723285a616.js +0 -79
- package/dashboard/.next/static/chunks/8452-6d77fa353402422c.js +0 -13
- package/dashboard/.next/static/chunks/8928-fc049decdfbdaa6d.js +0 -1
- package/dashboard/.next/static/chunks/app/access/page-f8403cbdfc1c176b.js +0 -1
- package/dashboard/.next/static/chunks/app/calls/page-41f20d01e12382ef.js +0 -1
- package/dashboard/.next/static/chunks/app/changes/page-82bf8b6f48cdc506.js +0 -1
- package/dashboard/.next/static/chunks/app/conformance/page-6bb8e3b372e38098.js +0 -1
- package/dashboard/.next/static/chunks/app/diagram/page-469cd7a6f183efba.js +0 -1
- package/dashboard/.next/static/chunks/app/flows/page-7872dd9141ba0b07.js +0 -1
- package/dashboard/.next/static/chunks/app/functions/page-5847bcb77a8e7edf.js +0 -1
- package/dashboard/.next/static/chunks/app/issues/page-1ffc64fe40439002.js +0 -1
- package/dashboard/.next/static/chunks/app/layout-6c6d2a0fd7c989d3.js +0 -1
- package/dashboard/.next/static/chunks/app/notes/page-8bcaa52304500098.js +0 -1
- package/dashboard/.next/static/chunks/app/page-d63800ddb072b77b.js +0 -1
- package/dashboard/.next/static/chunks/app/progress/page-e26554f655a62eef.js +0 -1
- package/dashboard/.next/static/chunks/app/report/page-18c04fb2f193b020.js +0 -1
- package/dashboard/.next/static/chunks/app/stats/page-67ff59fd69bed651.js +0 -1
- package/dashboard/.next/static/chunks/webpack-4de0e79bdd6a0418.js +0 -1
- package/dashboard/.next/static/css/1112cea2260b3926.css +0 -3
- package/dashboard/app/access/AccessClient.tsx +0 -402
- package/dashboard/app/access/ReadOnlyFunctions.tsx +0 -114
- package/dashboard/app/access/page.tsx +0 -125
- package/dashboard/app/api/flows/route.ts +0 -32
- package/dashboard/app/api/mermaid/route.ts +0 -25
- package/dashboard/app/calls/CallsClient.tsx +0 -170
- package/dashboard/app/calls/page.tsx +0 -57
- package/dashboard/app/conformance/ConformanceTable.tsx +0 -214
- package/dashboard/app/conformance/page.tsx +0 -186
- package/dashboard/app/diagram/page.tsx +0 -65
- package/dashboard/app/flows/page.tsx +0 -102
- package/dashboard/app/functions/FunctionsClient.tsx +0 -167
- package/dashboard/app/functions/page.tsx +0 -178
- package/dashboard/app/issues/IssuesBoardClient.tsx +0 -813
- package/dashboard/app/notes/NotesClient.tsx +0 -706
- package/dashboard/app/notes/page.tsx +0 -47
- package/dashboard/app/progress/ProgressClient.tsx +0 -354
- package/dashboard/app/progress/page.tsx +0 -127
- package/dashboard/app/stats/StatsClient.tsx +0 -452
- package/dashboard/app/stats/page.tsx +0 -50
- package/dashboard/components/ConfidenceBadge.tsx +0 -53
- package/dashboard/components/DashboardLayout.tsx +0 -510
- package/dashboard/components/FilterableTable.tsx +0 -293
- package/dashboard/components/MermaidViewer.tsx +0 -267
- package/dashboard/components/NotYetGenerated.tsx +0 -32
- package/dashboard/components/SeverityBadge.tsx +0 -28
- package/dashboard/components/SignalBars.tsx +0 -27
- package/dashboard/components/SortableTable.tsx +0 -122
- package/dashboard/lib/conformance-tokens.ts +0 -49
- package/dist/skills/init-audit.md +0 -386
- /package/dashboard/.next/server/app/api/{flows → xref}/route.js.nft.json +0 -0
- /package/dashboard/.next/server/app/{api/mermaid → excalidraw-assets/[...path]}/route.js.nft.json +0 -0
- /package/dashboard/.next/static/{z5XBev05xDAkDrxWxAjNu → bGV1ry1vvIbM5b506eVBR}/_buildManifest.js +0 -0
- /package/dashboard/.next/static/{z5XBev05xDAkDrxWxAjNu → bGV1ry1vvIbM5b506eVBR}/_ssgManifest.js +0 -0
- /package/dashboard/.next/static/chunks/{3205-47d09be47325709f.js → 3205-fd963acf2fdfd080.js} +0 -0
- /package/dashboard/.next/static/chunks/{3924-88d849290406ee6f.js → 3924-f1f85ccc7d59d7ab.js} +0 -0
- /package/dashboard/.next/static/chunks/{618f8807-69fc7bb97c2b87c1.js → 618f8807-fbb1466bc29c17c6.js} +0 -0
- /package/dashboard/.next/static/chunks/{7498-d1814d68ba346d13.js → 7498-7cf464d8af69cd0a.js} +0 -0
- /package/dashboard/.next/static/chunks/app/_not-found/{page-c299b935209993df.js → page-5ff5d54b6fd6f17e.js} +0 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Facts } from '../types/index.js';
|
|
2
|
+
export declare const DEDUP_RULES = "Compare the two findings on four signals:\n- contract (boolean): does the affected contract match?\n- function (boolean): does the affected function match?\n- root_cause: same / overlapping / different \u2014 the technical mechanism.\n- attack_vector: same / overlapping / different \u2014 what the attacker actually does.\n\nThey are duplicates when at least one holds:\n1. root_cause = same AND function = true\n2. root_cause = same AND contract = true AND attack_vector = same\n3. root_cause = overlapping AND function = true AND attack_vector = same\n\nThe canonical card is the earliest-created card that is not itself a duplicate.\nA synced (GitHub) card always wins over a local one.";
|
|
3
|
+
interface FindingLike {
|
|
4
|
+
id: string;
|
|
5
|
+
title?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
created_at?: string;
|
|
8
|
+
root_cause?: {
|
|
9
|
+
locations?: Array<{
|
|
10
|
+
file: string;
|
|
11
|
+
snippet?: string;
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export declare function projectDirOf(outputDir: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Exact function ids a finding is about: snippet lines located in the cited
|
|
18
|
+
* files, plus backticked `name(...)` identifiers resolved within the cited
|
|
19
|
+
* contracts (or anywhere when no file is cited).
|
|
20
|
+
*/
|
|
21
|
+
export declare function functionsForFinding(facts: Facts, finding: FindingLike, projectDir: string): string[];
|
|
22
|
+
export interface DedupCandidate {
|
|
23
|
+
id: string;
|
|
24
|
+
title: string;
|
|
25
|
+
status: string;
|
|
26
|
+
source: string;
|
|
27
|
+
same_function: boolean;
|
|
28
|
+
same_contract: boolean;
|
|
29
|
+
shared_functions: string[];
|
|
30
|
+
title_similarity: number;
|
|
31
|
+
strength: 'strong' | 'weak';
|
|
32
|
+
}
|
|
33
|
+
export interface DedupReport {
|
|
34
|
+
id: string;
|
|
35
|
+
functions: string[];
|
|
36
|
+
candidates: DedupCandidate[];
|
|
37
|
+
rules: string;
|
|
38
|
+
}
|
|
39
|
+
/** Rank existing cards that may duplicate `id`. Judgement stays with the caller. */
|
|
40
|
+
export declare function dedupCandidates(outputDir: string, id: string, limit?: number): DedupReport;
|
|
41
|
+
export interface MatchSignals {
|
|
42
|
+
contract: boolean;
|
|
43
|
+
function: boolean;
|
|
44
|
+
root_cause: 'same' | 'overlapping' | 'different';
|
|
45
|
+
attack_vector: 'same' | 'overlapping' | 'different';
|
|
46
|
+
}
|
|
47
|
+
/** Move `id` to Duplicate pointing at `of`, and record why — in one step. */
|
|
48
|
+
export declare function markDuplicate(outputDir: string, id: string, of: string, input: {
|
|
49
|
+
signals: MatchSignals;
|
|
50
|
+
reasoning: string;
|
|
51
|
+
confidence: 'high' | 'medium' | 'low';
|
|
52
|
+
}): void;
|
|
53
|
+
/** Reject `id` because a triage rule covers it, and record which rule. */
|
|
54
|
+
export declare function excludeByRule(outputDir: string, id: string, ruleId: string, ruleText: string): void;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=dedup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.d.ts","sourceRoot":"","sources":["../../src/core/dedup.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,KAAK,EAAiB,MAAM,mBAAmB,CAAC;AAE9D,eAAO,MAAM,WAAW,urBAY6B,CAAC;AAEtD,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACxE;AAiBD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGtD;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CA6CV;AAsCD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,WAAW,CA0CrF;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC;IACjD,aAAa,EAAE,MAAM,GAAG,aAAa,GAAG,WAAW,CAAC;CACrD;AAmBD,6EAA6E;AAC7E,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAA;CAAE,GACzF,IAAI,CAaN;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,IAAI,CAMN"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One dedup engine for every finding source (manual, AuditAgent, /ai-audit,
|
|
3
|
+
* conformance, GitHub, prior-audit, invariant). The deterministic part —
|
|
4
|
+
* mapping cards to exact functions and ranking candidates — lives here; the
|
|
5
|
+
* semantic judgement (root cause, attack vector) is the agent's, against the
|
|
6
|
+
* rules below, which exist only in this file.
|
|
7
|
+
*
|
|
8
|
+
* Node builtins only (the dashboard and the MCP server import it).
|
|
9
|
+
*/
|
|
10
|
+
import fs from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import { moveIssue } from './issues.js';
|
|
13
|
+
export const DEDUP_RULES = `Compare the two findings on four signals:
|
|
14
|
+
- contract (boolean): does the affected contract match?
|
|
15
|
+
- function (boolean): does the affected function match?
|
|
16
|
+
- root_cause: same / overlapping / different — the technical mechanism.
|
|
17
|
+
- attack_vector: same / overlapping / different — what the attacker actually does.
|
|
18
|
+
|
|
19
|
+
They are duplicates when at least one holds:
|
|
20
|
+
1. root_cause = same AND function = true
|
|
21
|
+
2. root_cause = same AND contract = true AND attack_vector = same
|
|
22
|
+
3. root_cause = overlapping AND function = true AND attack_vector = same
|
|
23
|
+
|
|
24
|
+
The canonical card is the earliest-created card that is not itself a duplicate.
|
|
25
|
+
A synced (GitHub) card always wins over a local one.`;
|
|
26
|
+
function readJson(file) {
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(fs.readFileSync(file, 'utf-8'));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function projectDirOf(outputDir) {
|
|
35
|
+
const cfg = readJson(path.join(outputDir, 'config.json'));
|
|
36
|
+
return cfg?.project?.project_dir ?? path.dirname(outputDir);
|
|
37
|
+
}
|
|
38
|
+
function loadFactsFile(outputDir) {
|
|
39
|
+
return readJson(path.join(outputDir, 'facts.json'));
|
|
40
|
+
}
|
|
41
|
+
function enclosing(facts, file, line) {
|
|
42
|
+
return facts.functions.filter((f) => f.file === file && f.line_start <= line && line <= f.line_end && f.kind !== 'modifier');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Exact function ids a finding is about: snippet lines located in the cited
|
|
46
|
+
* files, plus backticked `name(...)` identifiers resolved within the cited
|
|
47
|
+
* contracts (or anywhere when no file is cited).
|
|
48
|
+
*/
|
|
49
|
+
export function functionsForFinding(facts, finding, projectDir) {
|
|
50
|
+
const out = new Set();
|
|
51
|
+
const files = (finding.root_cause?.locations ?? []).map((l) => l.file);
|
|
52
|
+
const probeLines = (code) => code
|
|
53
|
+
.split(/\r?\n/)
|
|
54
|
+
.map((l) => l.trim())
|
|
55
|
+
.filter((l) => l.length > 8 && !l.startsWith('//') && l !== '// ....');
|
|
56
|
+
const locate = (file, probes) => {
|
|
57
|
+
let content;
|
|
58
|
+
try {
|
|
59
|
+
content = fs.readFileSync(path.join(projectDir, file), 'utf-8');
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const lines = content.split(/\r?\n/);
|
|
65
|
+
for (const probe of probes.slice(0, 6)) {
|
|
66
|
+
const idx = lines.findIndex((l) => l.trim() === probe || l.includes(probe));
|
|
67
|
+
if (idx >= 0)
|
|
68
|
+
for (const f of enclosing(facts, file, idx + 1))
|
|
69
|
+
out.add(f.id);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
for (const loc of finding.root_cause?.locations ?? []) {
|
|
73
|
+
if (loc.snippet)
|
|
74
|
+
locate(loc.file, probeLines(loc.snippet));
|
|
75
|
+
}
|
|
76
|
+
// Hex-standard descriptions carry the offending code in a fenced block.
|
|
77
|
+
const blocks = [...(finding.description ?? '').matchAll(/```[a-z]*\n([\s\S]*?)```/g)].map((m) => m[1]);
|
|
78
|
+
if (blocks.length) {
|
|
79
|
+
const searchFiles = files.length
|
|
80
|
+
? [...new Set(files)]
|
|
81
|
+
: [...new Set(facts.functions.filter((f) => f.in_scope).map((f) => f.file))];
|
|
82
|
+
const probes = blocks.flatMap(probeLines);
|
|
83
|
+
for (const file of searchFiles)
|
|
84
|
+
locate(file, probes);
|
|
85
|
+
}
|
|
86
|
+
const text = `${finding.title ?? ''}\n${finding.description ?? ''}`;
|
|
87
|
+
const names = new Set([...text.matchAll(/`([A-Za-z_][A-Za-z0-9_]*)\(/g)].map((m) => m[1]));
|
|
88
|
+
for (const name of names) {
|
|
89
|
+
for (const f of facts.functions) {
|
|
90
|
+
if (f.name !== name || f.kind === 'modifier')
|
|
91
|
+
continue;
|
|
92
|
+
if (files.length && !files.includes(f.file))
|
|
93
|
+
continue;
|
|
94
|
+
out.add(f.id);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return [...out].sort();
|
|
98
|
+
}
|
|
99
|
+
function tokens(s) {
|
|
100
|
+
return new Set(s
|
|
101
|
+
.toLowerCase()
|
|
102
|
+
.replace(/[`*_()[\],.:;]/g, ' ')
|
|
103
|
+
.split(/\s+/)
|
|
104
|
+
.filter((t) => t.length > 2 && !STOP.has(t)));
|
|
105
|
+
}
|
|
106
|
+
const STOP = new Set([
|
|
107
|
+
'the',
|
|
108
|
+
'and',
|
|
109
|
+
'for',
|
|
110
|
+
'can',
|
|
111
|
+
'not',
|
|
112
|
+
'with',
|
|
113
|
+
'from',
|
|
114
|
+
'that',
|
|
115
|
+
'this',
|
|
116
|
+
'are',
|
|
117
|
+
'when',
|
|
118
|
+
'into',
|
|
119
|
+
'may',
|
|
120
|
+
'allows',
|
|
121
|
+
'missing',
|
|
122
|
+
'lack',
|
|
123
|
+
'lacks',
|
|
124
|
+
]);
|
|
125
|
+
function jaccard(a, b) {
|
|
126
|
+
if (a.size === 0 || b.size === 0)
|
|
127
|
+
return 0;
|
|
128
|
+
let inter = 0;
|
|
129
|
+
for (const x of a)
|
|
130
|
+
if (b.has(x))
|
|
131
|
+
inter++;
|
|
132
|
+
return inter / (a.size + b.size - inter);
|
|
133
|
+
}
|
|
134
|
+
/** Rank existing cards that may duplicate `id`. Judgement stays with the caller. */
|
|
135
|
+
export function dedupCandidates(outputDir, id, limit = 8) {
|
|
136
|
+
const findings = readJson(path.join(outputDir, 'findings.json'))?.findings ?? [];
|
|
137
|
+
const tracking = readJson(path.join(outputDir, 'tracking.json'))?.findings ?? [];
|
|
138
|
+
const facts = loadFactsFile(outputDir);
|
|
139
|
+
const projectDir = projectDirOf(outputDir);
|
|
140
|
+
const byId = new Map(findings.map((f) => [f.id, f]));
|
|
141
|
+
const target = byId.get(id) ?? { id, title: tracking.find((t) => t.id === id)?.title ?? '' };
|
|
142
|
+
const targetFns = facts ? functionsForFinding(facts, target, projectDir) : [];
|
|
143
|
+
const contractsOf = (fns) => new Set(fns.map((f) => f.slice(0, f.indexOf('.'))));
|
|
144
|
+
const targetContracts = contractsOf(targetFns);
|
|
145
|
+
const targetTokens = tokens(target.title ?? '');
|
|
146
|
+
const candidates = [];
|
|
147
|
+
for (const t of tracking) {
|
|
148
|
+
if (t.id === id || t.status === 'duplicate')
|
|
149
|
+
continue;
|
|
150
|
+
const f = byId.get(t.id) ?? { id: t.id, title: t.title };
|
|
151
|
+
const fns = facts ? functionsForFinding(facts, f, projectDir) : [];
|
|
152
|
+
const shared = fns.filter((x) => targetFns.includes(x));
|
|
153
|
+
const sameContract = [...contractsOf(fns)].some((c) => targetContracts.has(c));
|
|
154
|
+
const sim = jaccard(targetTokens, tokens(f.title ?? t.title));
|
|
155
|
+
if (!shared.length && !sameContract && sim < 0.25)
|
|
156
|
+
continue;
|
|
157
|
+
candidates.push({
|
|
158
|
+
id: t.id,
|
|
159
|
+
title: t.title,
|
|
160
|
+
status: t.status,
|
|
161
|
+
source: t.source,
|
|
162
|
+
same_function: shared.length > 0,
|
|
163
|
+
same_contract: sameContract,
|
|
164
|
+
shared_functions: shared,
|
|
165
|
+
title_similarity: Math.round(sim * 100) / 100,
|
|
166
|
+
strength: shared.length > 0 || (sameContract && sim >= 0.3) ? 'strong' : 'weak',
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
candidates.sort((a, b) => Number(b.same_function) - Number(a.same_function) ||
|
|
170
|
+
Number(b.same_contract) - Number(a.same_contract) ||
|
|
171
|
+
b.title_similarity - a.title_similarity);
|
|
172
|
+
return { id, functions: targetFns, candidates: candidates.slice(0, limit), rules: DEDUP_RULES };
|
|
173
|
+
}
|
|
174
|
+
function readComparison(outputDir) {
|
|
175
|
+
const c = readJson(path.join(outputDir, 'comparison.json'));
|
|
176
|
+
return { duplicates: c?.duplicates ?? [], novel: c?.novel ?? [], rejected: c?.rejected ?? [] };
|
|
177
|
+
}
|
|
178
|
+
function writeComparison(outputDir, c) {
|
|
179
|
+
const p = path.join(outputDir, 'comparison.json');
|
|
180
|
+
const tmp = p + '.tmp';
|
|
181
|
+
fs.writeFileSync(tmp, JSON.stringify(c, null, 2) + '\n', 'utf-8');
|
|
182
|
+
fs.renameSync(tmp, p);
|
|
183
|
+
}
|
|
184
|
+
/** Move `id` to Duplicate pointing at `of`, and record why — in one step. */
|
|
185
|
+
export function markDuplicate(outputDir, id, of, input) {
|
|
186
|
+
if (id === of)
|
|
187
|
+
throw new Error('A card cannot duplicate itself.');
|
|
188
|
+
moveIssue(outputDir, id, 'duplicate', of);
|
|
189
|
+
const c = readComparison(outputDir);
|
|
190
|
+
c.duplicates = c.duplicates.filter((d) => d.ai_finding !== id);
|
|
191
|
+
c.duplicates.push({
|
|
192
|
+
ai_finding: id,
|
|
193
|
+
matches: of,
|
|
194
|
+
confidence: input.confidence,
|
|
195
|
+
match_signals: input.signals,
|
|
196
|
+
reasoning: input.reasoning,
|
|
197
|
+
});
|
|
198
|
+
writeComparison(outputDir, c);
|
|
199
|
+
}
|
|
200
|
+
/** Reject `id` because a triage rule covers it, and record which rule. */
|
|
201
|
+
export function excludeByRule(outputDir, id, ruleId, ruleText) {
|
|
202
|
+
moveIssue(outputDir, id, 'rejected');
|
|
203
|
+
const c = readComparison(outputDir);
|
|
204
|
+
c.rejected = c.rejected.filter((r) => r.id !== id);
|
|
205
|
+
c.rejected.push({ id, reason: `${ruleId}: ${ruleText}` });
|
|
206
|
+
writeComparison(outputDir, c);
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=dedup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dedup.js","sourceRoot":"","sources":["../../src/core/dedup.ts"],"names":[],"mappings":"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"}
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface ErrorHint {
|
|
|
3
3
|
fix: string;
|
|
4
4
|
docs?: string;
|
|
5
5
|
}
|
|
6
|
-
export type ErrorCode = 'tool.
|
|
6
|
+
export type ErrorCode = 'tool.forge.missing' | 'tool.forge.failed' | 'tool.claude.missing' | 'tool.node.outdated' | 'project.scope.empty' | 'project.scope.unmatched' | 'project.scope.missing-file' | 'project.missing-config' | 'project.foundry-missing' | 'output.dir.unwritable' | 'output.file.unparseable' | 'ai-tool.missing-scan-id' | 'ai-tool.scan-failed' | 'analysis.no-data' | 'diff.base-required' | 'diff.base-missing' | 'diff.not-git' | 'diff.not-diff-mode';
|
|
7
7
|
export declare const ERROR_HINTS: Record<ErrorCode, ErrorHint>;
|
|
8
8
|
export declare class HexError extends Error {
|
|
9
9
|
code: ErrorCode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,SAAS,GACjB,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,SAAS,GACjB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,oBAAoB,GACpB,qBAAqB,GACrB,yBAAyB,GACzB,4BAA4B,GAC5B,wBAAwB,GACxB,yBAAyB,GACzB,uBAAuB,GACvB,yBAAyB,GACzB,yBAAyB,GACzB,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,GACpB,mBAAmB,GACnB,cAAc,GACd,oBAAoB,CAAC;AAEzB,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,SAAS,EAAE,SAAS,CA2EpD,CAAC;AAEF,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEJ,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM;CAO7C;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ,CAExD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,MAAM,CAYpD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAO9C"}
|
package/dist/core/errors.js
CHANGED
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
export const ERROR_HINTS = {
|
|
3
|
-
'tool.slither.missing': {
|
|
4
|
-
cause: "Slither isn't installed or isn't on PATH.",
|
|
5
|
-
fix: 'Install with: pip install slither-analyzer',
|
|
6
|
-
docs: 'https://github.com/crytic/slither#how-to-install',
|
|
7
|
-
},
|
|
8
|
-
'tool.slither.failed': {
|
|
9
|
-
cause: 'Slither ran but exited with a non-zero code.',
|
|
10
|
-
fix: 'Re-run `slither <project>` manually to see the underlying compilation error.',
|
|
11
|
-
docs: 'https://github.com/crytic/slither/wiki/Usage',
|
|
12
|
-
},
|
|
13
3
|
'tool.forge.missing': {
|
|
14
4
|
cause: 'Foundry (forge/cast) is not installed or not on PATH.',
|
|
15
5
|
fix: 'Install with: curl -L https://foundry.paradigm.xyz | bash && foundryup',
|
|
@@ -19,11 +9,6 @@ export const ERROR_HINTS = {
|
|
|
19
9
|
cause: 'forge build failed before analysis could finish.',
|
|
20
10
|
fix: 'Run `forge build` directly and fix the compilation errors first.',
|
|
21
11
|
},
|
|
22
|
-
'tool.solc.missing': {
|
|
23
|
-
cause: 'solc was not found on PATH.',
|
|
24
|
-
fix: 'Install with `solc-select install <version> && solc-select use <version>`, or rely on Foundry.',
|
|
25
|
-
docs: 'https://github.com/crytic/solc-select#quickstart',
|
|
26
|
-
},
|
|
27
12
|
'tool.claude.missing': {
|
|
28
13
|
cause: 'Claude Code CLI is not installed (hex skills run via Claude Code).',
|
|
29
14
|
fix: 'Install Claude Code, then re-run `hex claude` to copy skills into the project.',
|
package/dist/core/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,24 +16,10 @@ export declare function detectTools(): Promise<ToolInfo[]>;
|
|
|
16
16
|
* Require a tool to be available, throwing if not found.
|
|
17
17
|
*/
|
|
18
18
|
export declare function requireTool(name: string): Promise<void>;
|
|
19
|
-
/**
|
|
20
|
-
* Run Slither with JSON output.
|
|
21
|
-
*/
|
|
22
|
-
export declare function runSlither(dir: string, args: string[]): Promise<ExecResult>;
|
|
23
|
-
/**
|
|
24
|
-
* Get Slither function-summary output with file-based caching.
|
|
25
|
-
* access.ts and state.ts both run the identical `slither . --print function-summary --json -`
|
|
26
|
-
* command. This cache ensures it only runs once per analysis session.
|
|
27
|
-
*/
|
|
28
|
-
export declare function getSlitherFunctionSummary(projectDir: string, outputDir: string): Promise<ExecResult>;
|
|
29
19
|
/**
|
|
30
20
|
* Run Forge (Foundry).
|
|
31
21
|
*/
|
|
32
22
|
export declare function runForge(dir: string, args: string[]): Promise<ExecResult>;
|
|
33
23
|
export declare function flattenFile(projectDir: string, filePath: string): Promise<string | null>;
|
|
34
|
-
/**
|
|
35
|
-
* Run solc.
|
|
36
|
-
*/
|
|
37
|
-
export declare function runSolc(dir: string, args: string[]): Promise<ExecResult>;
|
|
38
24
|
export {};
|
|
39
25
|
//# sourceMappingURL=external-tools.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-tools.d.ts","sourceRoot":"","sources":["../../src/core/external-tools.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"external-tools.d.ts","sourceRoot":"","sources":["../../src/core/external-tools.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAiED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,CAKvD;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ7D;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,UAAU,CAAC,CAGrB;AASD,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiB9F"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
|
-
import fs from 'node:fs';
|
|
3
|
-
import path from 'node:path';
|
|
4
2
|
import { logger } from './logger.js';
|
|
5
3
|
/**
|
|
6
4
|
* Run a command and capture output.
|
|
@@ -15,7 +13,8 @@ function exec(command, args, options = {}) {
|
|
|
15
13
|
const child = spawn(command, args, {
|
|
16
14
|
cwd: options.cwd,
|
|
17
15
|
env,
|
|
18
|
-
shell:
|
|
16
|
+
// No shell: arguments are passed as-is (never concatenated into a command line).
|
|
17
|
+
shell: process.platform === 'win32',
|
|
19
18
|
timeout: options.timeout ?? 120_000,
|
|
20
19
|
});
|
|
21
20
|
const stdout = [];
|
|
@@ -54,8 +53,6 @@ async function checkTool(name, command, args) {
|
|
|
54
53
|
*/
|
|
55
54
|
export async function detectTools() {
|
|
56
55
|
const checks = await Promise.all([
|
|
57
|
-
checkTool('solc', 'solc', ['--version']),
|
|
58
|
-
checkTool('slither', 'slither', ['--version']),
|
|
59
56
|
checkTool('forge', 'forge', ['--version']),
|
|
60
57
|
]);
|
|
61
58
|
return checks;
|
|
@@ -70,46 +67,6 @@ export async function requireTool(name) {
|
|
|
70
67
|
throw new Error(`Required tool '${name}' not found. Please install it and ensure it's in your PATH.`);
|
|
71
68
|
}
|
|
72
69
|
}
|
|
73
|
-
/**
|
|
74
|
-
* Run Slither with JSON output.
|
|
75
|
-
*/
|
|
76
|
-
export async function runSlither(dir, args) {
|
|
77
|
-
logger.dim(`Running: slither ${args.join(' ')}`);
|
|
78
|
-
return exec('slither', args, { cwd: dir, timeout: 300_000 });
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Get Slither function-summary output with file-based caching.
|
|
82
|
-
* access.ts and state.ts both run the identical `slither . --print function-summary --json -`
|
|
83
|
-
* command. This cache ensures it only runs once per analysis session.
|
|
84
|
-
*/
|
|
85
|
-
export async function getSlitherFunctionSummary(projectDir, outputDir) {
|
|
86
|
-
const cacheDir = path.join(outputDir, '.cache');
|
|
87
|
-
const cachePath = path.join(cacheDir, 'slither-function-summary.json');
|
|
88
|
-
// Use cache if it exists and is less than 5 minutes old
|
|
89
|
-
try {
|
|
90
|
-
const stat = fs.statSync(cachePath);
|
|
91
|
-
if (Date.now() - stat.mtimeMs < 5 * 60 * 1000) {
|
|
92
|
-
const cached = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
93
|
-
logger.dim('Using cached Slither function-summary');
|
|
94
|
-
return cached;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// Cache miss — run Slither
|
|
99
|
-
}
|
|
100
|
-
const result = await runSlither(projectDir, ['.', '--print', 'function-summary', '--json', '-']);
|
|
101
|
-
// Cache the result on success
|
|
102
|
-
if (result.exitCode === 0) {
|
|
103
|
-
try {
|
|
104
|
-
fs.mkdirSync(cacheDir, { recursive: true });
|
|
105
|
-
fs.writeFileSync(cachePath, JSON.stringify(result));
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
// Non-fatal — caching is best-effort
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return result;
|
|
112
|
-
}
|
|
113
70
|
/**
|
|
114
71
|
* Run Forge (Foundry).
|
|
115
72
|
*/
|
|
@@ -141,11 +98,4 @@ export async function flattenFile(projectDir, filePath) {
|
|
|
141
98
|
return null;
|
|
142
99
|
}
|
|
143
100
|
}
|
|
144
|
-
/**
|
|
145
|
-
* Run solc.
|
|
146
|
-
*/
|
|
147
|
-
export async function runSolc(dir, args) {
|
|
148
|
-
logger.dim(`Running: solc ${args.join(' ')}`);
|
|
149
|
-
return exec('solc', args, { cwd: dir });
|
|
150
|
-
}
|
|
151
101
|
//# sourceMappingURL=external-tools.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-tools.js","sourceRoot":"","sources":["../../src/core/external-tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"external-tools.js","sourceRoot":"","sources":["../../src/core/external-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fix review: pure helpers (classification, commit mapping, GitHub body
|
|
3
|
+
* rewriting). Orchestration with git/forge lives in src/commands/fix-review.ts.
|
|
4
|
+
*/
|
|
5
|
+
import type { FixReviewCard } from '../types/index.js';
|
|
6
|
+
export type PocResult = 'passing' | 'failing' | 'error' | 'missing';
|
|
7
|
+
/**
|
|
8
|
+
* Status from the evidence, most decisive first:
|
|
9
|
+
* - the PoC fails at the fix commit → fixed (it reproduced at audit time)
|
|
10
|
+
* - the PoC still passes → not_fixed
|
|
11
|
+
* - every function the card is about was removed → fixed (code path gone)
|
|
12
|
+
* - code or commits touch the card but no PoC verdict → unknown (agent judges)
|
|
13
|
+
* - nothing touches it → unaddressed
|
|
14
|
+
*/
|
|
15
|
+
export declare function classifyCard(input: {
|
|
16
|
+
pocBefore?: PocResult;
|
|
17
|
+
pocAfter?: PocResult;
|
|
18
|
+
cardFunctions: string[];
|
|
19
|
+
changedFunctions: string[];
|
|
20
|
+
removedFunctions: string[];
|
|
21
|
+
commits: string[];
|
|
22
|
+
}): {
|
|
23
|
+
status: FixReviewCard['status'];
|
|
24
|
+
evidence: string;
|
|
25
|
+
};
|
|
26
|
+
/** Commits whose message cites the card id (`H-012`) or its GitHub issue (`#12`, `fixes #12`). */
|
|
27
|
+
export declare function commitsForCard(commits: Array<{
|
|
28
|
+
sha: string;
|
|
29
|
+
subject: string;
|
|
30
|
+
body?: string;
|
|
31
|
+
}>, card: {
|
|
32
|
+
id: string;
|
|
33
|
+
github_issue?: number;
|
|
34
|
+
}): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Rewrite only the Status and "Update from the client" fields of a Hex-format
|
|
37
|
+
* issue body; every other byte is preserved. Missing fields are appended in
|
|
38
|
+
* template order.
|
|
39
|
+
*/
|
|
40
|
+
export declare function rewriteIssueBody(body: string, fields: {
|
|
41
|
+
status?: string;
|
|
42
|
+
update?: string;
|
|
43
|
+
}): string;
|
|
44
|
+
/**
|
|
45
|
+
* Index of the unmapped change a reference names: `Contract.entity` with or
|
|
46
|
+
* without the signature (`Vault.sweep`, `Vault.sweep(address,address,uint256)`),
|
|
47
|
+
* or the bare entity name when it is unique. Throws when nothing or more than
|
|
48
|
+
* one change matches.
|
|
49
|
+
*/
|
|
50
|
+
export declare function findUnmappedChange(changes: ReadonlyArray<{
|
|
51
|
+
contract: string;
|
|
52
|
+
entity: string;
|
|
53
|
+
}>, ref: string): number;
|
|
54
|
+
//# sourceMappingURL=fix-review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-review.d.ts","sourceRoot":"","sources":["../../src/core/fix-review.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEpE;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,GAAG;IAAE,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAiCxD;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAC5B,OAAO,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/D,IAAI,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1C,MAAM,EAAE,CASV;AAKD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3C,MAAM,CAgBR;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,aAAa,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,EAC5D,GAAG,EAAE,MAAM,GACV,MAAM,CAiBR"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status from the evidence, most decisive first:
|
|
3
|
+
* - the PoC fails at the fix commit → fixed (it reproduced at audit time)
|
|
4
|
+
* - the PoC still passes → not_fixed
|
|
5
|
+
* - every function the card is about was removed → fixed (code path gone)
|
|
6
|
+
* - code or commits touch the card but no PoC verdict → unknown (agent judges)
|
|
7
|
+
* - nothing touches it → unaddressed
|
|
8
|
+
*/
|
|
9
|
+
export function classifyCard(input) {
|
|
10
|
+
const { pocBefore, pocAfter, cardFunctions, changedFunctions, removedFunctions, commits } = input;
|
|
11
|
+
if (pocAfter === 'failing' && pocBefore !== 'failing') {
|
|
12
|
+
return {
|
|
13
|
+
status: 'fixed',
|
|
14
|
+
evidence: 'The PoC reproduced the issue at the audited commit and fails at the fix commit.',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
if (pocAfter === 'passing') {
|
|
18
|
+
return {
|
|
19
|
+
status: 'not_fixed',
|
|
20
|
+
evidence: changedFunctions.length
|
|
21
|
+
? `The code changed (${changedFunctions.join(', ')}) but the PoC still reproduces the issue.`
|
|
22
|
+
: 'The PoC still reproduces the issue at the fix commit.',
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
if (cardFunctions.length && cardFunctions.every((f) => removedFunctions.includes(f))) {
|
|
26
|
+
return {
|
|
27
|
+
status: 'fixed',
|
|
28
|
+
evidence: `The affected code was removed (${cardFunctions.join(', ')}).`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (changedFunctions.length || commits.length) {
|
|
32
|
+
const why = pocAfter === 'error' ? ' The PoC no longer compiles against the new code.' : '';
|
|
33
|
+
return {
|
|
34
|
+
status: 'unknown',
|
|
35
|
+
evidence: `Touched by ${[changedFunctions.length ? changedFunctions.join(', ') : '', commits.length ? `commit${commits.length > 1 ? 's' : ''} ${commits.map((c) => c.slice(0, 7)).join(', ')}` : ''].filter(Boolean).join(' and ')}; needs a judgement.${why}`,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
status: 'unaddressed',
|
|
40
|
+
evidence: 'No change between the audited and fix commits touches this issue.',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Commits whose message cites the card id (`H-012`) or its GitHub issue (`#12`, `fixes #12`). */
|
|
44
|
+
export function commitsForCard(commits, card) {
|
|
45
|
+
const idRe = new RegExp(`\\b${card.id}\\b`);
|
|
46
|
+
const ghRe = card.github_issue ? new RegExp(`#${card.github_issue}\\b`) : null;
|
|
47
|
+
return commits
|
|
48
|
+
.filter((c) => {
|
|
49
|
+
const text = `${c.subject}\n${c.body ?? ''}`;
|
|
50
|
+
return idRe.test(text) || (ghRe ? ghRe.test(text) : false);
|
|
51
|
+
})
|
|
52
|
+
.map((c) => c.sha);
|
|
53
|
+
}
|
|
54
|
+
const STATUS_RE = /(\*\*Status\*\*:)[^\n]*(\n|$)/;
|
|
55
|
+
const UPDATE_RE = /(\*\*Update from the client\*\*:)[\s\S]*$/;
|
|
56
|
+
/**
|
|
57
|
+
* Rewrite only the Status and "Update from the client" fields of a Hex-format
|
|
58
|
+
* issue body; every other byte is preserved. Missing fields are appended in
|
|
59
|
+
* template order.
|
|
60
|
+
*/
|
|
61
|
+
export function rewriteIssueBody(body, fields) {
|
|
62
|
+
let out = body;
|
|
63
|
+
if (fields.status !== undefined) {
|
|
64
|
+
if (STATUS_RE.test(out))
|
|
65
|
+
out = out.replace(STATUS_RE, (_m, label, nl) => `${label} ${fields.status}${nl}`);
|
|
66
|
+
else
|
|
67
|
+
out = `${out.replace(/\s*$/, '')}\n\n**Status**: ${fields.status}\n`;
|
|
68
|
+
}
|
|
69
|
+
if (fields.update !== undefined) {
|
|
70
|
+
if (UPDATE_RE.test(out))
|
|
71
|
+
out = out.replace(UPDATE_RE, (_m, label) => `${label} ${fields.update}\n`);
|
|
72
|
+
else
|
|
73
|
+
out = `${out.replace(/\s*$/, '')}\n\n**Update from the client**: ${fields.update}\n`;
|
|
74
|
+
}
|
|
75
|
+
return out;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Index of the unmapped change a reference names: `Contract.entity` with or
|
|
79
|
+
* without the signature (`Vault.sweep`, `Vault.sweep(address,address,uint256)`),
|
|
80
|
+
* or the bare entity name when it is unique. Throws when nothing or more than
|
|
81
|
+
* one change matches.
|
|
82
|
+
*/
|
|
83
|
+
export function findUnmappedChange(changes, ref) {
|
|
84
|
+
const name = (e) => e.split('(')[0];
|
|
85
|
+
const hits = changes
|
|
86
|
+
.map((c, i) => ({ c, i }))
|
|
87
|
+
.filter(({ c }) => ref.includes('.')
|
|
88
|
+
? `${c.contract}.${c.entity}` === ref || `${c.contract}.${name(c.entity)}` === ref
|
|
89
|
+
: c.entity === ref || name(c.entity) === ref);
|
|
90
|
+
if (hits.length === 0)
|
|
91
|
+
throw new Error(`No unmapped change matches ${ref}`);
|
|
92
|
+
if (hits.length > 1)
|
|
93
|
+
throw new Error(`${ref} matches ${hits.length} unmapped changes; use Contract.entity(signature): ${hits
|
|
94
|
+
.map(({ c }) => `${c.contract}.${c.entity}`)
|
|
95
|
+
.join(', ')}`);
|
|
96
|
+
return hits[0].i;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=fix-review.js.map
|