hex-audit 0.6.3 → 0.7.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/DEMO.md +13 -0
- package/README.md +60 -6
- package/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/app-build-manifest.json +100 -89
- package/dashboard/.next/app-path-routes-manifest.json +1 -1
- package/dashboard/.next/build-manifest.json +14 -14
- package/dashboard/.next/next-minimal-server.js.nft.json +1 -1
- package/dashboard/.next/next-server.js.nft.json +1 -1
- package/dashboard/.next/prerender-manifest.js +1 -1
- package/dashboard/.next/prerender-manifest.json +1 -1
- package/dashboard/.next/react-loadable-manifest.json +118 -118
- 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_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/access/page.js +1 -1
- package/dashboard/.next/server/app/access/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/access/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/calls/page.js +1 -1
- package/dashboard/.next/server/app/calls/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/calls/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/changes/page.js +20 -0
- package/dashboard/.next/server/app/changes/page.js.nft.json +1 -0
- package/dashboard/.next/server/app/changes/page_client-reference-manifest.js +1 -0
- package/dashboard/.next/server/app/conformance/page.js +1 -1
- package/dashboard/.next/server/app/conformance/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/diagram/page.js +1 -1
- package/dashboard/.next/server/app/diagram/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/flows/page.js +1 -1
- package/dashboard/.next/server/app/flows/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/functions/page.js +1 -1
- package/dashboard/.next/server/app/functions/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/functions/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/issues/page.js +6 -6
- package/dashboard/.next/server/app/issues/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/notes/page.js +3 -3
- package/dashboard/.next/server/app/notes/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/page.js +2 -2
- package/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/progress/page.js +1 -1
- package/dashboard/.next/server/app/progress/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/report/page.js +1 -1
- package/dashboard/.next/server/app/report/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app/stats/page.js +1 -1
- package/dashboard/.next/server/app/stats/page.js.nft.json +1 -1
- package/dashboard/.next/server/app/stats/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/server/app-paths-manifest.json +8 -7
- package/dashboard/.next/server/chunks/42.js +1 -1
- package/dashboard/.next/server/chunks/530.js +1 -1
- package/dashboard/.next/server/chunks/649.js +1 -1
- package/dashboard/.next/server/chunks/939.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/next-font-manifest.js +1 -1
- package/dashboard/.next/server/next-font-manifest.json +1 -1
- package/dashboard/.next/server/pages/500.html +1 -1
- package/dashboard/.next/server/pages-manifest.json +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/{1.8868c4d131111be7.js → 1.a666047ea18866fb.js} +2 -2
- package/dashboard/.next/static/chunks/1015.39008440ab15e196.js +226 -0
- package/dashboard/.next/static/chunks/1151.497fa63c5b9eba52.js +1 -0
- package/dashboard/.next/static/chunks/1199.f30cbfa151e56076.js +148 -0
- package/dashboard/.next/static/chunks/1375.64c20f1064a38a10.js +43 -0
- package/dashboard/.next/static/chunks/1799.8dc56017eede704e.js +9 -0
- package/dashboard/.next/static/chunks/20154aaa.e87f69fe10483f8b.js +1 -0
- package/dashboard/.next/static/chunks/2077.5603adeb156c7d10.js +1 -0
- package/dashboard/.next/static/chunks/2166.9f6592b9399eadd8.js +215 -0
- package/dashboard/.next/static/chunks/{2291.85a70cb0c228157b.js → 2291.584b42ccad079b99.js} +1 -1
- package/dashboard/.next/static/chunks/2325.7decd077edfb81d9.js +24 -0
- package/dashboard/.next/static/chunks/{2383.62c035a052272594.js → 2383.ca81f980ce6528a4.js} +1 -1
- package/dashboard/.next/static/chunks/2694.7dfa5fef28851903.js +1 -0
- package/dashboard/.next/static/chunks/275.38af87389c1d33d7.js +34 -0
- package/dashboard/.next/static/chunks/2781.fba46046dbf2693b.js +93 -0
- package/dashboard/.next/static/chunks/2805.35b4cd8a94978aaf.js +1 -0
- package/dashboard/.next/static/chunks/{2879.51436986f93981d9.js → 2879.74d65e33e60505ee.js} +1 -1
- package/dashboard/.next/static/chunks/3017.4a5312e3c20a173f.js +1 -0
- package/dashboard/.next/static/chunks/3205-47d09be47325709f.js +2 -0
- package/dashboard/.next/static/chunks/3236.eac9855778a54518.js +1 -0
- package/dashboard/.next/static/chunks/3480.853a445a3784642a.js +1 -0
- package/dashboard/.next/static/chunks/3626.c5dacee11c8fbc4d.js +64 -0
- package/dashboard/.next/static/chunks/3865.5e6d2d501380e03b.js +90 -0
- package/dashboard/.next/static/chunks/3887.073cece834a4eae2.js +1 -0
- package/dashboard/.next/static/chunks/3924-88d849290406ee6f.js +1 -0
- package/dashboard/.next/static/chunks/3948.74201b9f0672234d.js +287 -0
- package/dashboard/.next/static/chunks/4728.e69372b5e5b61b8d.js +24 -0
- package/dashboard/.next/static/chunks/4787.821a6ad2816cdc60.js +23 -0
- package/dashboard/.next/static/chunks/5060.47402abc10273699.js +1 -0
- package/dashboard/.next/static/chunks/5284.334c7c0587d5d47a.js +1 -0
- package/dashboard/.next/static/chunks/5715.e16b1230cc4b4652.js +115 -0
- package/dashboard/.next/static/chunks/6014.641a2c53ba506241.js +104 -0
- package/dashboard/.next/static/chunks/6024.f099c15f75aa6722.js +79 -0
- package/dashboard/.next/static/chunks/{6052.033a6f1013c666eb.js → 6052.3001318955e5b36c.js} +2 -2
- package/dashboard/.next/static/chunks/6177.a01cf0a03734cf09.js +1 -0
- package/dashboard/.next/static/chunks/618f8807-69fc7bb97c2b87c1.js +1 -0
- package/dashboard/.next/static/chunks/6434.f560693253fea8de.js +1 -0
- package/dashboard/.next/static/chunks/6468.976d89ba133185f1.js +77 -0
- package/dashboard/.next/static/chunks/6540.6f3c4f2c6877ed89.js +1 -0
- package/dashboard/.next/static/chunks/6549.e3c4c1766cff1449.js +1 -0
- package/dashboard/.next/static/chunks/690f35d0.ab57e02a04c7e9e0.js +119 -0
- package/dashboard/.next/static/chunks/{7020.831e16e26d91abc1.js → 7020.b718b1b9cea36e60.js} +2 -2
- package/dashboard/.next/static/chunks/7397-37adf76cad543297.js +1 -0
- package/dashboard/.next/static/chunks/7498-d1814d68ba346d13.js +1 -0
- package/dashboard/.next/static/chunks/7802.f0134c792fccd382.js +80 -0
- package/dashboard/.next/static/chunks/7973.e34032723285a616.js +79 -0
- package/dashboard/.next/static/chunks/{7a04ac15.1c6cea694301806c.js → 7a04ac15.e49de94ece135900.js} +1 -1
- package/dashboard/.next/static/chunks/8216.1138ec313908a708.js +5 -0
- package/dashboard/.next/static/chunks/{8233babc.780b8e272eda298f.js → 8233babc.09872dcb3ff44064.js} +1 -1
- package/dashboard/.next/static/chunks/{8452-e616b5f43bceb95f.js → 8452-6d77fa353402422c.js} +2 -2
- package/dashboard/.next/static/chunks/8645.98a43217d406500e.js +1 -0
- package/dashboard/.next/static/chunks/8928-fc049decdfbdaa6d.js +1 -0
- package/dashboard/.next/static/chunks/9173.a7160f7d0b685fa7.js +1 -0
- package/dashboard/.next/static/chunks/9178.998a8c49996de8e4.js +1 -0
- package/dashboard/.next/static/chunks/9466.a914ce0de7d3bb84.js +1 -0
- package/dashboard/.next/static/chunks/9660.b1c8deae2c449d14.js +1 -0
- package/dashboard/.next/static/chunks/{9717.6cf5c8c89403b651.js → 9717.bba51b78ebd8fd29.js} +1 -1
- package/dashboard/.next/static/chunks/9720.d63a0696776bcc60.js +1 -0
- package/dashboard/.next/static/chunks/9811.2993c4cbd28e8d1b.js +1 -0
- package/dashboard/.next/static/chunks/app/_not-found/page-c299b935209993df.js +1 -0
- package/dashboard/.next/static/chunks/app/access/page-f8403cbdfc1c176b.js +1 -0
- package/dashboard/.next/static/chunks/app/calls/page-41f20d01e12382ef.js +1 -0
- package/dashboard/.next/static/chunks/app/changes/page-82bf8b6f48cdc506.js +1 -0
- package/dashboard/.next/static/chunks/app/conformance/page-6bb8e3b372e38098.js +1 -0
- package/dashboard/.next/static/chunks/app/diagram/page-469cd7a6f183efba.js +1 -0
- package/dashboard/.next/static/chunks/app/flows/page-7872dd9141ba0b07.js +1 -0
- package/dashboard/.next/static/chunks/app/functions/page-5847bcb77a8e7edf.js +1 -0
- package/dashboard/.next/static/chunks/app/issues/page-1ffc64fe40439002.js +1 -0
- package/dashboard/.next/static/chunks/app/layout-6c6d2a0fd7c989d3.js +1 -0
- package/dashboard/.next/static/chunks/app/notes/page-8bcaa52304500098.js +1 -0
- package/dashboard/.next/static/chunks/app/page-d63800ddb072b77b.js +1 -0
- package/dashboard/.next/static/chunks/app/progress/page-e26554f655a62eef.js +1 -0
- package/dashboard/.next/static/chunks/app/report/page-18c04fb2f193b020.js +1 -0
- package/dashboard/.next/static/chunks/app/stats/page-67ff59fd69bed651.js +1 -0
- package/dashboard/.next/static/chunks/{b7167ec1.7afbab6f609e3326.js → b7167ec1.708a3d61698ca2e6.js} +1 -1
- package/dashboard/.next/static/chunks/c7ea4e13.3073a2f551aa5ac8.js +1 -0
- package/dashboard/.next/static/chunks/framework-a117d81bf1b91f9a.js +33 -0
- package/dashboard/.next/static/chunks/main-app-5662c64b50ba40d1.js +1 -0
- package/dashboard/.next/static/chunks/main-cc3a889b25e9aa68.js +1 -0
- package/dashboard/.next/static/chunks/pages/_app-308fef0bf9b328f2.js +1 -0
- package/dashboard/.next/static/chunks/pages/_error-c91b5eabd7ac9382.js +1 -0
- package/dashboard/.next/static/chunks/webpack-4de0e79bdd6a0418.js +1 -0
- package/dashboard/.next/static/css/1112cea2260b3926.css +3 -0
- package/dashboard/.next/static/media/39f449c8730c2295-s.woff2 +0 -0
- package/dashboard/.next/static/media/86f65e8637cc94e3-s.woff2 +0 -0
- package/dashboard/.next/static/media/8760c4774489e4ba-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/9fabb9c65b63d798-s.woff2 +0 -0
- package/dashboard/.next/static/media/a1f87af3f44fadbb-s.woff2 +0 -0
- package/dashboard/.next/static/media/f9e1dbe9676d9bb6-s.woff2 +0 -0
- package/dashboard/.next/static/z5XBev05xDAkDrxWxAjNu/_buildManifest.js +1 -0
- package/dashboard/app/changes/ChangesClient.tsx +464 -0
- package/dashboard/app/changes/page.tsx +36 -0
- package/dashboard/app/issues/IssuesBoardClient.tsx +11 -1
- package/dashboard/app/layout.tsx +13 -1
- package/dashboard/app/notes/NotesClient.tsx +5 -0
- package/dashboard/app/page.tsx +42 -0
- package/dashboard/components/DashboardLayout.tsx +43 -18
- package/dist/analysis/code-model.d.ts +113 -0
- package/dist/analysis/code-model.d.ts.map +1 -0
- package/dist/analysis/code-model.js +529 -0
- package/dist/analysis/code-model.js.map +1 -0
- package/dist/analysis/diff.d.ts +64 -0
- package/dist/analysis/diff.d.ts.map +1 -0
- package/dist/analysis/diff.js +644 -0
- package/dist/analysis/diff.js.map +1 -0
- package/dist/commands/analyze.d.ts.map +1 -1
- package/dist/commands/analyze.js +18 -2
- package/dist/commands/analyze.js.map +1 -1
- package/dist/commands/diff.d.ts +26 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +218 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +66 -6
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/issue.d.ts.map +1 -1
- package/dist/commands/issue.js +4 -4
- package/dist/commands/issue.js.map +1 -1
- package/dist/commands/note.d.ts.map +1 -1
- package/dist/commands/note.js +30 -2
- package/dist/commands/note.js.map +1 -1
- package/dist/core/config.d.ts +9 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +18 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/errors.d.ts +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +16 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/git.d.ts +24 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +115 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/issues.d.ts +4 -2
- package/dist/core/issues.d.ts.map +1 -1
- package/dist/core/issues.js +67 -28
- package/dist/core/issues.js.map +1 -1
- package/dist/core/notes.d.ts +25 -1
- package/dist/core/notes.d.ts.map +1 -1
- package/dist/core/notes.js +34 -2
- package/dist/core/notes.js.map +1 -1
- package/dist/core/schema.d.ts +750 -53
- package/dist/core/schema.d.ts.map +1 -1
- package/dist/core/schema.js +153 -1
- package/dist/core/schema.js.map +1 -1
- package/dist/core/skills.d.ts +10 -4
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +100 -37
- package/dist/core/skills.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/skills/ai-audit/LICENSE +21 -0
- package/dist/skills/ai-audit/SKILL.md +476 -0
- package/dist/skills/ai-audit/UPSTREAM.md +46 -0
- package/dist/skills/ai-audit/references/agent-prompts.md +133 -0
- package/dist/skills/ai-audit/references/assemble.sh +357 -0
- package/dist/skills/ai-audit/references/dedup-and-assembly.md +420 -0
- package/dist/skills/ai-audit/references/hacking-agents/access-control-agent.md +27 -0
- package/dist/skills/ai-audit/references/hacking-agents/asymmetry-agent.md +77 -0
- package/dist/skills/ai-audit/references/hacking-agents/boundary-agent.md +79 -0
- package/dist/skills/ai-audit/references/hacking-agents/economic-security-agent.md +35 -0
- package/dist/skills/ai-audit/references/hacking-agents/execution-trace-agent.md +33 -0
- package/dist/skills/ai-audit/references/hacking-agents/first-principles-agent.md +36 -0
- package/dist/skills/ai-audit/references/hacking-agents/flow-gap-agent.md +49 -0
- package/dist/skills/ai-audit/references/hacking-agents/invariant-agent.md +44 -0
- package/dist/skills/ai-audit/references/hacking-agents/math-precision-agent.md +48 -0
- package/dist/skills/ai-audit/references/hacking-agents/numerical-gap-agent.md +46 -0
- package/dist/skills/ai-audit/references/hacking-agents/periphery-agent.md +27 -0
- package/dist/skills/ai-audit/references/hacking-agents/shared-rules.md +61 -0
- package/dist/skills/ai-audit/references/hacking-agents/trust-gap-agent.md +40 -0
- package/dist/skills/ai-audit/references/hex-board.md +223 -0
- package/dist/skills/ai-audit/references/hex-export.sh +71 -0
- package/dist/skills/ai-audit/references/judging.md +75 -0
- package/dist/skills/ai-audit/references/report-formatting.md +385 -0
- package/dist/skills/ai-audit/references/report-language.md +151 -0
- package/dist/skills/ai-audit/references/senior-auditor-sop.md +63 -0
- package/dist/skills/generate-report.md +7 -3
- package/dist/skills/init-audit.md +104 -2
- package/dist/skills/validate-all-findings.md +1 -1
- package/dist/skills/validate-finding.md +8 -4
- package/dist/types/index.d.ts +7 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +2 -1
- package/dashboard/.next/server/app/_not-found.html +0 -1
- package/dashboard/.next/server/app/_not-found.meta +0 -6
- package/dashboard/.next/server/app/_not-found.rsc +0 -12
- package/dashboard/.next/server/app/diagram.html +0 -1
- package/dashboard/.next/server/app/diagram.meta +0 -5
- package/dashboard/.next/server/app/diagram.rsc +0 -10
- package/dashboard/.next/server/app/flows.html +0 -1
- package/dashboard/.next/server/app/flows.meta +0 -5
- package/dashboard/.next/server/app/flows.rsc +0 -10
- package/dashboard/.next/server/chunks/44.js +0 -1
- package/dashboard/.next/server/pages/404.html +0 -1
- package/dashboard/.next/static/AyrRAwu4mazjp8iX4Yjbb/_buildManifest.js +0 -1
- package/dashboard/.next/static/chunks/1015.3ab89142e5f44120.js +0 -226
- package/dashboard/.next/static/chunks/1151.b6ef5c786e587ed7.js +0 -1
- package/dashboard/.next/static/chunks/1199.a072929dbec89965.js +0 -148
- package/dashboard/.next/static/chunks/1375.d4d2f7fc9c9c2ff1.js +0 -43
- package/dashboard/.next/static/chunks/1799.83206776abbbf1fc.js +0 -9
- package/dashboard/.next/static/chunks/20154aaa.ccc347c04ab5ad4a.js +0 -1
- package/dashboard/.next/static/chunks/2077.7011a570c87aa7b1.js +0 -1
- package/dashboard/.next/static/chunks/2166.cc0fabeb2e89b840.js +0 -215
- package/dashboard/.next/static/chunks/2325.2c55cb9a6282ae3f.js +0 -24
- package/dashboard/.next/static/chunks/2694.92bbe252063e4786.js +0 -1
- package/dashboard/.next/static/chunks/275.0d761aa0e5b030b8.js +0 -34
- package/dashboard/.next/static/chunks/2781.8536b644a480aede.js +0 -93
- package/dashboard/.next/static/chunks/2805.a8d71d2f92bb6ba9.js +0 -1
- package/dashboard/.next/static/chunks/3017.e55781da9dd32d37.js +0 -1
- package/dashboard/.next/static/chunks/3205-728c260fbb4f89c6.js +0 -2
- package/dashboard/.next/static/chunks/3236.dff44fa7961d9d5e.js +0 -1
- package/dashboard/.next/static/chunks/3480.9451396ad7ee7613.js +0 -1
- package/dashboard/.next/static/chunks/3626.ba1cf848a9f2e93d.js +0 -64
- package/dashboard/.next/static/chunks/3865.a432a7910a2f5281.js +0 -90
- package/dashboard/.next/static/chunks/3887.c22cbfa3f095826c.js +0 -1
- package/dashboard/.next/static/chunks/3924-4a05057b5450abe1.js +0 -1
- package/dashboard/.next/static/chunks/3948.fe3c7d758568d98b.js +0 -287
- package/dashboard/.next/static/chunks/4728.07d87640a3e7dd0d.js +0 -24
- package/dashboard/.next/static/chunks/4787.4e5f6a0e0e40a583.js +0 -23
- package/dashboard/.next/static/chunks/5060.baca226af35ed016.js +0 -1
- package/dashboard/.next/static/chunks/5284.f949ac90c95ff143.js +0 -1
- package/dashboard/.next/static/chunks/5715.1524bcc9591e180b.js +0 -115
- package/dashboard/.next/static/chunks/6014.700ae4969b64d728.js +0 -104
- package/dashboard/.next/static/chunks/6024.4d23707c65514679.js +0 -79
- package/dashboard/.next/static/chunks/6177.e5c84cfc4c0dea51.js +0 -1
- package/dashboard/.next/static/chunks/618f8807-547c5614e1318888.js +0 -1
- package/dashboard/.next/static/chunks/6434.9481771c33195d29.js +0 -1
- package/dashboard/.next/static/chunks/6468.f4a3e8fa6accc6da.js +0 -77
- package/dashboard/.next/static/chunks/6540.86f367d7390738d4.js +0 -1
- package/dashboard/.next/static/chunks/6549.4d0d472df96429a5.js +0 -1
- package/dashboard/.next/static/chunks/690f35d0.3e40ca0930e4bbdb.js +0 -119
- package/dashboard/.next/static/chunks/7397-f6f4dddc7a20bfc1.js +0 -1
- package/dashboard/.next/static/chunks/7498-ea83cb9e30ec5491.js +0 -1
- package/dashboard/.next/static/chunks/7802.89aec9ee11680850.js +0 -80
- package/dashboard/.next/static/chunks/7973.8b526f589aca5d84.js +0 -79
- package/dashboard/.next/static/chunks/8216.1bead812eb126c35.js +0 -5
- package/dashboard/.next/static/chunks/8645.a5ca76f11edc9633.js +0 -1
- package/dashboard/.next/static/chunks/8928-60c623ee89d2e6ad.js +0 -1
- package/dashboard/.next/static/chunks/9173.2486ffca31131ec5.js +0 -1
- package/dashboard/.next/static/chunks/9178.469341860bf8caec.js +0 -1
- package/dashboard/.next/static/chunks/9466.e904660d38c03eea.js +0 -1
- package/dashboard/.next/static/chunks/9660.84a85811380c5f33.js +0 -1
- package/dashboard/.next/static/chunks/9720.67d4d0d15a96d691.js +0 -1
- package/dashboard/.next/static/chunks/9811.65e1d080c2d256af.js +0 -1
- package/dashboard/.next/static/chunks/app/_not-found/page-548ab392d0e890d1.js +0 -1
- package/dashboard/.next/static/chunks/app/access/page-3668562e7464eb5d.js +0 -1
- package/dashboard/.next/static/chunks/app/calls/page-d07f5b8664cc8303.js +0 -1
- package/dashboard/.next/static/chunks/app/conformance/page-2fede1d7b5f9265d.js +0 -1
- package/dashboard/.next/static/chunks/app/diagram/page-b228444265546495.js +0 -1
- package/dashboard/.next/static/chunks/app/flows/page-fa67783d8cd79cab.js +0 -1
- package/dashboard/.next/static/chunks/app/functions/page-686f0296639133a3.js +0 -1
- package/dashboard/.next/static/chunks/app/issues/page-98a298e1c1045c91.js +0 -1
- package/dashboard/.next/static/chunks/app/layout-49f2496c7637d931.js +0 -1
- package/dashboard/.next/static/chunks/app/notes/page-17af94c67ba79c00.js +0 -1
- package/dashboard/.next/static/chunks/app/page-24bac51dfe007c66.js +0 -1
- package/dashboard/.next/static/chunks/app/progress/page-427fb18da3afb061.js +0 -1
- package/dashboard/.next/static/chunks/app/report/page-796f2f4a8a5ac8f7.js +0 -1
- package/dashboard/.next/static/chunks/app/stats/page-db81f600a086f252.js +0 -1
- package/dashboard/.next/static/chunks/c7ea4e13.5effeeba6618bdb7.js +0 -1
- package/dashboard/.next/static/chunks/framework-cf6f5bdca6ba0184.js +0 -33
- package/dashboard/.next/static/chunks/main-63ff429eab01f5bf.js +0 -1
- package/dashboard/.next/static/chunks/main-app-9d2f6b8a47133e9b.js +0 -1
- package/dashboard/.next/static/chunks/pages/_app-6ad2b50514c24ab4.js +0 -1
- package/dashboard/.next/static/chunks/pages/_error-d5eb11c5c4626811.js +0 -1
- package/dashboard/.next/static/chunks/webpack-08869f2b18792e51.js +0 -1
- package/dashboard/.next/static/css/4a38d8f6f6b7a68f.css +0 -3
- package/dashboard/.next/static/media/438aa629764e75f3-s.woff2 +0 -0
- package/dashboard/.next/static/media/4c9affa5bc8f420e-s.p.woff2 +0 -0
- package/dashboard/.next/static/media/51251f8b9793cdb3-s.woff2 +0 -0
- package/dashboard/.next/static/media/875ae681bfde4580-s.woff2 +0 -0
- package/dashboard/.next/static/media/cc978ac5ee68c2b6-s.woff2 +0 -0
- package/dashboard/.next/static/media/e857b654a2caa584-s.woff2 +0 -0
- /package/dashboard/.next/static/{AyrRAwu4mazjp8iX4Yjbb → z5XBev05xDAkDrxWxAjNu}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { FilterableTable, type FilterableColumn } from '@/components/FilterableTable';
|
|
5
|
+
import { ConfidenceBadge } from '@/components/ConfidenceBadge';
|
|
6
|
+
import { CodeReference } from '@/components/CodeReference';
|
|
7
|
+
import { MarkdownRenderer, InlineMarkdown } from '@/components/MarkdownRenderer';
|
|
8
|
+
import { SeverityBadge } from '@/components/SeverityBadge';
|
|
9
|
+
|
|
10
|
+
// ─── Types (shape of .hex/diff.json, see src/core/schema.ts DiffSchema) ──
|
|
11
|
+
|
|
12
|
+
interface DiffChange {
|
|
13
|
+
contract: string;
|
|
14
|
+
entity: string;
|
|
15
|
+
kind: string;
|
|
16
|
+
file: string;
|
|
17
|
+
change: 'added' | 'removed' | 'modified' | 'comments_only';
|
|
18
|
+
line_start?: number;
|
|
19
|
+
line_end?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
interface ImpactReason {
|
|
23
|
+
kind: 'changed' | 'calls' | 'modifier' | 'reads_state' | 'override' | 'inherits';
|
|
24
|
+
via: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface Impacted {
|
|
28
|
+
contract: string;
|
|
29
|
+
function: string;
|
|
30
|
+
file: string;
|
|
31
|
+
visibility: string;
|
|
32
|
+
is_entry_point: boolean;
|
|
33
|
+
depth: number;
|
|
34
|
+
reasons: ImpactReason[];
|
|
35
|
+
confidence: string;
|
|
36
|
+
derived_from: string;
|
|
37
|
+
line_start?: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface DiffData {
|
|
41
|
+
generated_at: string;
|
|
42
|
+
base_commit: string;
|
|
43
|
+
head_commit: string;
|
|
44
|
+
warnings?: string[];
|
|
45
|
+
files: Array<{
|
|
46
|
+
path: string;
|
|
47
|
+
status: string;
|
|
48
|
+
old_path?: string;
|
|
49
|
+
additions: number;
|
|
50
|
+
deletions: number;
|
|
51
|
+
}>;
|
|
52
|
+
changes: DiffChange[];
|
|
53
|
+
storage_layout_changes: Array<{ contract: string; file: string; kind: string; detail: string }>;
|
|
54
|
+
impacted: Impacted[];
|
|
55
|
+
summary: {
|
|
56
|
+
files_changed: number;
|
|
57
|
+
additions: number;
|
|
58
|
+
deletions: number;
|
|
59
|
+
functions_added: number;
|
|
60
|
+
functions_modified: number;
|
|
61
|
+
functions_removed: number;
|
|
62
|
+
impacted_functions: number;
|
|
63
|
+
impacted_entry_points: number;
|
|
64
|
+
storage_layout_changes: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
type Severity = 'Critical' | 'High' | 'Medium' | 'Low' | 'Info';
|
|
69
|
+
|
|
70
|
+
export interface PriorReview {
|
|
71
|
+
reviewed_at: string;
|
|
72
|
+
items: Array<{
|
|
73
|
+
id: string;
|
|
74
|
+
title: string;
|
|
75
|
+
severity: Severity;
|
|
76
|
+
status: string;
|
|
77
|
+
reasoning: string;
|
|
78
|
+
issue_id?: string;
|
|
79
|
+
}>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// ─── Small pieces ───────────────────────────────────────────────────
|
|
83
|
+
|
|
84
|
+
const CHANGE_STYLES: Record<string, string> = {
|
|
85
|
+
added: 'bg-accent-subtle text-accent',
|
|
86
|
+
modified: 'bg-[var(--high)]/18 text-[var(--high)]',
|
|
87
|
+
removed: 'bg-[var(--critical)]/18 text-[var(--critical)]',
|
|
88
|
+
comments_only: 'bg-surface-3 text-text-tertiary',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const CHANGE_LABELS: Record<string, string> = {
|
|
92
|
+
added: 'Added',
|
|
93
|
+
modified: 'Modified',
|
|
94
|
+
removed: 'Removed',
|
|
95
|
+
comments_only: 'Comments only',
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
function Chip({ className, children }: { className: string; children: React.ReactNode }) {
|
|
99
|
+
return (
|
|
100
|
+
<span
|
|
101
|
+
className={`inline-flex items-center rounded-md px-2 py-0.5 text-caption font-medium ${className}`}
|
|
102
|
+
>
|
|
103
|
+
{children}
|
|
104
|
+
</span>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function ChangeBadge({ change }: { change: string }) {
|
|
109
|
+
return (
|
|
110
|
+
<Chip className={CHANGE_STYLES[change] ?? CHANGE_STYLES.comments_only}>
|
|
111
|
+
{CHANGE_LABELS[change] ?? change}
|
|
112
|
+
</Chip>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const REASON_LABELS: Record<ImpactReason['kind'], string> = {
|
|
117
|
+
changed: 'Changed',
|
|
118
|
+
calls: 'Calls',
|
|
119
|
+
modifier: 'Uses modifier',
|
|
120
|
+
reads_state: 'Reads state',
|
|
121
|
+
override: 'Dispatches to',
|
|
122
|
+
inherits: 'Inherits',
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const PRIOR_STATUS: Record<string, { label: string; className: string }> = {
|
|
126
|
+
regressed: { label: 'Regressed', className: 'bg-[var(--critical)]/18 text-[var(--critical)]' },
|
|
127
|
+
acknowledged_still_present: {
|
|
128
|
+
label: 'Still present',
|
|
129
|
+
className: 'bg-[var(--medium)]/18 text-[var(--medium)]',
|
|
130
|
+
},
|
|
131
|
+
fix_touched_ok: { label: 'Fix touched, holds', className: 'bg-accent-subtle text-accent' },
|
|
132
|
+
fixed_unchanged: { label: 'Fixed, untouched', className: 'bg-surface-3 text-text-secondary' },
|
|
133
|
+
code_removed: { label: 'Code removed', className: 'bg-surface-3 text-text-tertiary' },
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
function Stat({ label, value, tone }: { label: string; value: number | string; tone?: 'warn' }) {
|
|
137
|
+
return (
|
|
138
|
+
<div
|
|
139
|
+
className={`rounded-lg border p-4 ${
|
|
140
|
+
tone === 'warn'
|
|
141
|
+
? 'border-[var(--high)]/30 bg-[var(--high)]/5'
|
|
142
|
+
: 'border-border-subtle bg-surface-1'
|
|
143
|
+
}`}
|
|
144
|
+
>
|
|
145
|
+
<div
|
|
146
|
+
className={`text-display scale-in ${tone === 'warn' ? 'text-[var(--high)]' : 'text-text-primary'}`}
|
|
147
|
+
>
|
|
148
|
+
{value}
|
|
149
|
+
</div>
|
|
150
|
+
<div className="mt-1 text-caption text-text-secondary">{label}</div>
|
|
151
|
+
</div>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function Section({ title, children }: { title: string; children: React.ReactNode }) {
|
|
156
|
+
return (
|
|
157
|
+
<section className="mb-sp-6">
|
|
158
|
+
<h3 className="mb-sp-3 text-heading font-medium text-text-primary">{title}</h3>
|
|
159
|
+
{children}
|
|
160
|
+
</section>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// ─── Columns ────────────────────────────────────────────────────────
|
|
165
|
+
|
|
166
|
+
const changeColumns: FilterableColumn<DiffChange>[] = [
|
|
167
|
+
{
|
|
168
|
+
id: 'contract',
|
|
169
|
+
header: 'Contract',
|
|
170
|
+
accessorKey: 'contract',
|
|
171
|
+
enableColumnFilter: true,
|
|
172
|
+
cell: (row) => <span className="font-medium text-text-primary">{row.contract}</span>,
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: 'entity',
|
|
176
|
+
header: 'Entity',
|
|
177
|
+
accessorKey: 'entity',
|
|
178
|
+
cell: (row) => <code className="font-mono text-body text-text-secondary">{row.entity}</code>,
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
id: 'kind',
|
|
182
|
+
header: 'Kind',
|
|
183
|
+
accessorKey: 'kind',
|
|
184
|
+
enableColumnFilter: true,
|
|
185
|
+
cell: (row) => (
|
|
186
|
+
<span className="text-body text-text-secondary">{row.kind.replace('_', ' ')}</span>
|
|
187
|
+
),
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: 'change',
|
|
191
|
+
header: 'Change',
|
|
192
|
+
accessorKey: 'change',
|
|
193
|
+
enableColumnFilter: true,
|
|
194
|
+
filterOrder: ['added', 'modified', 'removed', 'comments_only'],
|
|
195
|
+
cell: (row) => <ChangeBadge change={row.change} />,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
id: 'location',
|
|
199
|
+
header: 'Location',
|
|
200
|
+
accessorKey: 'file',
|
|
201
|
+
cell: (row) =>
|
|
202
|
+
row.change === 'removed' || !row.line_start ? (
|
|
203
|
+
<code className="font-mono text-caption text-text-tertiary">{row.file}</code>
|
|
204
|
+
) : (
|
|
205
|
+
<CodeReference file={row.file} lineStart={row.line_start} lineEnd={row.line_end} />
|
|
206
|
+
),
|
|
207
|
+
},
|
|
208
|
+
];
|
|
209
|
+
|
|
210
|
+
interface ImpactRow extends Impacted {
|
|
211
|
+
entry: string;
|
|
212
|
+
reason: string;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const impactColumns: FilterableColumn<ImpactRow>[] = [
|
|
216
|
+
{
|
|
217
|
+
id: 'contract',
|
|
218
|
+
header: 'Contract',
|
|
219
|
+
accessorKey: 'contract',
|
|
220
|
+
enableColumnFilter: true,
|
|
221
|
+
cell: (row) => <span className="font-medium text-text-primary">{row.contract}</span>,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: 'function',
|
|
225
|
+
header: 'Function',
|
|
226
|
+
accessorKey: 'function',
|
|
227
|
+
cell: (row) => <code className="font-mono text-body text-text-secondary">{row.function}</code>,
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
id: 'entry',
|
|
231
|
+
header: 'Entry point',
|
|
232
|
+
accessorKey: 'entry',
|
|
233
|
+
enableColumnFilter: true,
|
|
234
|
+
cell: (row) =>
|
|
235
|
+
row.is_entry_point ? (
|
|
236
|
+
<Chip className="bg-accent-subtle text-accent">Entry point</Chip>
|
|
237
|
+
) : (
|
|
238
|
+
<span className="text-caption text-text-tertiary">{row.visibility}</span>
|
|
239
|
+
),
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
id: 'depth',
|
|
243
|
+
header: 'Depth',
|
|
244
|
+
accessorKey: 'depth',
|
|
245
|
+
cell: (row) => (
|
|
246
|
+
<span className="text-body text-text-secondary">
|
|
247
|
+
{row.depth === 0 ? 'changed' : row.depth}
|
|
248
|
+
</span>
|
|
249
|
+
),
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
id: 'reason',
|
|
253
|
+
header: 'Why',
|
|
254
|
+
accessorKey: 'reason',
|
|
255
|
+
enableColumnFilter: true,
|
|
256
|
+
cell: (row) => (
|
|
257
|
+
<div className="space-y-0.5">
|
|
258
|
+
{row.reasons.slice(0, 2).map((r, i) => (
|
|
259
|
+
<div key={i} className="text-caption text-text-secondary">
|
|
260
|
+
{REASON_LABELS[r.kind] ?? r.kind}{' '}
|
|
261
|
+
{r.kind !== 'changed' && <code className="font-mono text-text-primary">{r.via}</code>}
|
|
262
|
+
{r.kind === 'changed' && <span className="text-text-tertiary">({r.via})</span>}
|
|
263
|
+
</div>
|
|
264
|
+
))}
|
|
265
|
+
{row.reasons.length > 2 && (
|
|
266
|
+
<div className="text-caption text-text-tertiary">+{row.reasons.length - 2} more</div>
|
|
267
|
+
)}
|
|
268
|
+
</div>
|
|
269
|
+
),
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
id: 'confidence',
|
|
273
|
+
header: 'Confidence',
|
|
274
|
+
accessorKey: 'confidence',
|
|
275
|
+
enableColumnFilter: true,
|
|
276
|
+
filterOrder: ['high', 'medium', 'low'],
|
|
277
|
+
cell: (row) => <ConfidenceBadge level={row.confidence} derivedFrom={row.derived_from} />,
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
id: 'location',
|
|
281
|
+
header: 'Location',
|
|
282
|
+
accessorKey: 'file',
|
|
283
|
+
cell: (row) =>
|
|
284
|
+
row.line_start ? (
|
|
285
|
+
<CodeReference file={row.file} lineStart={row.line_start} />
|
|
286
|
+
) : (
|
|
287
|
+
<code className="font-mono text-caption text-text-tertiary">{row.file}</code>
|
|
288
|
+
),
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
|
|
292
|
+
// ─── Component ──────────────────────────────────────────────────────
|
|
293
|
+
|
|
294
|
+
export function ChangesClient({
|
|
295
|
+
diff,
|
|
296
|
+
overview,
|
|
297
|
+
review,
|
|
298
|
+
}: {
|
|
299
|
+
diff: DiffData;
|
|
300
|
+
overview: string | null;
|
|
301
|
+
review: PriorReview | null;
|
|
302
|
+
}) {
|
|
303
|
+
const s = diff.summary;
|
|
304
|
+
const base = diff.base_commit.slice(0, 8);
|
|
305
|
+
const head = diff.head_commit.slice(0, 8);
|
|
306
|
+
|
|
307
|
+
const impactRows: ImpactRow[] = diff.impacted.map((i) => ({
|
|
308
|
+
...i,
|
|
309
|
+
entry: i.is_entry_point ? 'Entry point' : 'Internal',
|
|
310
|
+
reason: REASON_LABELS[i.reasons[0]?.kind] ?? '',
|
|
311
|
+
}));
|
|
312
|
+
const regressed = review?.items.filter((i) => i.status === 'regressed').length ?? 0;
|
|
313
|
+
|
|
314
|
+
return (
|
|
315
|
+
<div>
|
|
316
|
+
<h2 className="mb-sp-2 text-title font-semibold text-text-primary">Changes</h2>
|
|
317
|
+
<div className="mb-sp-5 flex flex-wrap items-center gap-2 text-caption text-text-tertiary">
|
|
318
|
+
<span>Differential audit</span>
|
|
319
|
+
<code className="rounded-md bg-surface-2 px-2 py-0.5 font-mono text-text-secondary">
|
|
320
|
+
{base}
|
|
321
|
+
</code>
|
|
322
|
+
<span aria-hidden="true">→</span>
|
|
323
|
+
<code className="rounded-md bg-surface-2 px-2 py-0.5 font-mono text-text-secondary">
|
|
324
|
+
{head}
|
|
325
|
+
</code>
|
|
326
|
+
<span>
|
|
327
|
+
· +{s.additions} / −{s.deletions} lines
|
|
328
|
+
</span>
|
|
329
|
+
</div>
|
|
330
|
+
|
|
331
|
+
{(diff.warnings ?? []).map((w, i) => (
|
|
332
|
+
<div
|
|
333
|
+
key={i}
|
|
334
|
+
className="mb-sp-3 rounded-lg border border-[var(--high)]/30 bg-[var(--high)]/5 px-4 py-3 text-body text-text-secondary"
|
|
335
|
+
>
|
|
336
|
+
{w}
|
|
337
|
+
</div>
|
|
338
|
+
))}
|
|
339
|
+
|
|
340
|
+
<div className="mb-sp-6 grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6 stagger">
|
|
341
|
+
<Stat label="Files changed" value={s.files_changed} />
|
|
342
|
+
<Stat label="Functions added" value={s.functions_added} />
|
|
343
|
+
<Stat label="Functions modified" value={s.functions_modified} />
|
|
344
|
+
<Stat label="Functions removed" value={s.functions_removed} />
|
|
345
|
+
<Stat label="Impacted entry points" value={s.impacted_entry_points} />
|
|
346
|
+
<Stat
|
|
347
|
+
label="Storage layout changes"
|
|
348
|
+
value={s.storage_layout_changes}
|
|
349
|
+
tone={s.storage_layout_changes > 0 ? 'warn' : undefined}
|
|
350
|
+
/>
|
|
351
|
+
{review && (
|
|
352
|
+
<Stat
|
|
353
|
+
label="Prior findings regressed"
|
|
354
|
+
value={regressed}
|
|
355
|
+
tone={regressed > 0 ? 'warn' : undefined}
|
|
356
|
+
/>
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
{overview && (
|
|
361
|
+
<Section title="What changed">
|
|
362
|
+
<div className="rounded-lg border border-border-subtle bg-surface-1 p-6">
|
|
363
|
+
<MarkdownRenderer content={overview} />
|
|
364
|
+
</div>
|
|
365
|
+
</Section>
|
|
366
|
+
)}
|
|
367
|
+
|
|
368
|
+
{diff.storage_layout_changes.length > 0 && (
|
|
369
|
+
<Section title="Storage layout">
|
|
370
|
+
<ul className="divide-y divide-border-subtle rounded-lg border border-border-subtle bg-surface-1">
|
|
371
|
+
{diff.storage_layout_changes.map((l, i) => (
|
|
372
|
+
<li key={i} className="flex flex-wrap items-baseline gap-x-3 gap-y-1 px-4 py-3">
|
|
373
|
+
<span className="font-medium text-text-primary">{l.contract}</span>
|
|
374
|
+
<Chip className="bg-[var(--high)]/18 text-[var(--high)]">
|
|
375
|
+
{l.kind.replace(/_/g, ' ')}
|
|
376
|
+
</Chip>
|
|
377
|
+
<span className="text-body text-text-secondary">
|
|
378
|
+
<InlineMarkdown>{l.detail}</InlineMarkdown>
|
|
379
|
+
</span>
|
|
380
|
+
</li>
|
|
381
|
+
))}
|
|
382
|
+
</ul>
|
|
383
|
+
</Section>
|
|
384
|
+
)}
|
|
385
|
+
|
|
386
|
+
<Section title="Changed code">
|
|
387
|
+
<p className="mb-sp-3 text-body text-text-secondary">
|
|
388
|
+
{diff.files.length} file{diff.files.length !== 1 ? 's' : ''}:{' '}
|
|
389
|
+
{diff.files.map((f, i) => (
|
|
390
|
+
<span key={f.path}>
|
|
391
|
+
{i > 0 && ', '}
|
|
392
|
+
<code className="font-mono text-caption text-text-primary">{f.path}</code>{' '}
|
|
393
|
+
<span className="text-caption text-text-tertiary">
|
|
394
|
+
({f.status}
|
|
395
|
+
{f.old_path ? ` from ${f.old_path}` : ''}, +{f.additions}/−{f.deletions})
|
|
396
|
+
</span>
|
|
397
|
+
</span>
|
|
398
|
+
))}
|
|
399
|
+
</p>
|
|
400
|
+
<FilterableTable columns={changeColumns} data={diff.changes} />
|
|
401
|
+
</Section>
|
|
402
|
+
|
|
403
|
+
<Section title="Impacted flows">
|
|
404
|
+
<p className="mb-sp-3 text-body text-text-secondary">
|
|
405
|
+
Every function the change reaches: changed code (depth 0), then callers, modifier users,
|
|
406
|
+
readers of state the change writes, and inherited entry points. {s.impacted_functions}{' '}
|
|
407
|
+
impacted beyond the changed code.
|
|
408
|
+
</p>
|
|
409
|
+
<FilterableTable columns={impactColumns} data={impactRows} />
|
|
410
|
+
</Section>
|
|
411
|
+
|
|
412
|
+
{review && review.items.length > 0 && (
|
|
413
|
+
<Section title="Prior findings">
|
|
414
|
+
<div className="overflow-x-auto rounded-lg border border-border-subtle bg-surface-1">
|
|
415
|
+
<table className="w-full text-left">
|
|
416
|
+
<thead>
|
|
417
|
+
<tr className="border-b border-border-subtle text-caption text-text-tertiary">
|
|
418
|
+
<th className="px-4 py-2 font-normal">ID</th>
|
|
419
|
+
<th className="px-4 py-2 font-normal">Title</th>
|
|
420
|
+
<th className="px-4 py-2 font-normal">Severity</th>
|
|
421
|
+
<th className="px-4 py-2 font-normal">Status</th>
|
|
422
|
+
<th className="px-4 py-2 font-normal">Card</th>
|
|
423
|
+
</tr>
|
|
424
|
+
</thead>
|
|
425
|
+
<tbody>
|
|
426
|
+
{review.items.map((item) => {
|
|
427
|
+
const st = PRIOR_STATUS[item.status] ?? {
|
|
428
|
+
label: item.status,
|
|
429
|
+
className: 'bg-surface-3 text-text-secondary',
|
|
430
|
+
};
|
|
431
|
+
return (
|
|
432
|
+
<tr
|
|
433
|
+
key={item.id}
|
|
434
|
+
className="border-b border-border-subtle last:border-0 hover:bg-surface-3"
|
|
435
|
+
title={item.reasoning}
|
|
436
|
+
>
|
|
437
|
+
<td className="px-4 py-2 text-body text-text-secondary">{item.id}</td>
|
|
438
|
+
<td className="px-4 py-2 text-body text-text-primary">{item.title}</td>
|
|
439
|
+
<td className="px-4 py-2">
|
|
440
|
+
<SeverityBadge severity={item.severity} />
|
|
441
|
+
</td>
|
|
442
|
+
<td className="px-4 py-2">
|
|
443
|
+
<Chip className={st.className}>{st.label}</Chip>
|
|
444
|
+
</td>
|
|
445
|
+
<td className="px-4 py-2 text-body">
|
|
446
|
+
{item.issue_id ? (
|
|
447
|
+
<Link href="/issues" className="text-accent hover:underline">
|
|
448
|
+
{item.issue_id}
|
|
449
|
+
</Link>
|
|
450
|
+
) : (
|
|
451
|
+
<span className="text-text-tertiary">—</span>
|
|
452
|
+
)}
|
|
453
|
+
</td>
|
|
454
|
+
</tr>
|
|
455
|
+
);
|
|
456
|
+
})}
|
|
457
|
+
</tbody>
|
|
458
|
+
</table>
|
|
459
|
+
</div>
|
|
460
|
+
</Section>
|
|
461
|
+
)}
|
|
462
|
+
</div>
|
|
463
|
+
);
|
|
464
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readJsonFile, readMarkdownFile } from '@/lib/data';
|
|
2
|
+
import { NotYetGenerated } from '@/components/NotYetGenerated';
|
|
3
|
+
import { ChangesClient, type DiffData, type PriorReview } from './ChangesClient';
|
|
4
|
+
|
|
5
|
+
// Read .hex/ at request time (see app/calls/page.tsx for why).
|
|
6
|
+
export const dynamic = 'force-dynamic';
|
|
7
|
+
|
|
8
|
+
interface ConfigFile {
|
|
9
|
+
project?: { mode?: string; diff?: { base_commit?: string } };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function ChangesPage() {
|
|
13
|
+
const diff = readJsonFile<DiffData>('diff.json');
|
|
14
|
+
const config = readJsonFile<ConfigFile>('config.json');
|
|
15
|
+
|
|
16
|
+
if (!diff) {
|
|
17
|
+
const base = config?.project?.diff?.base_commit;
|
|
18
|
+
return (
|
|
19
|
+
<div>
|
|
20
|
+
<h2 className="mb-sp-5 text-title font-semibold text-text-primary">Changes</h2>
|
|
21
|
+
<p className="mb-sp-4 text-body text-text-secondary">
|
|
22
|
+
This page is for differential audits: what changed since the previously audited commit,
|
|
23
|
+
and which flows the change reaches.
|
|
24
|
+
</p>
|
|
25
|
+
<NotYetGenerated
|
|
26
|
+
command={base ? 'hex diff' : 'hex init --mode diff --base <commit> --scope "<globs>"'}
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const overview = readMarkdownFile('diff-overview.md');
|
|
33
|
+
const review = readJsonFile<PriorReview>('previous-audit/review.json');
|
|
34
|
+
|
|
35
|
+
return <ChangesClient diff={diff} overview={overview} review={review} />;
|
|
36
|
+
}
|
|
@@ -23,7 +23,13 @@ export type IssueStatus =
|
|
|
23
23
|
| 'synced'
|
|
24
24
|
| 'rejected'
|
|
25
25
|
| 'duplicate';
|
|
26
|
-
export type IssueSource =
|
|
26
|
+
export type IssueSource =
|
|
27
|
+
| 'manual'
|
|
28
|
+
| 'auditagent'
|
|
29
|
+
| 'ai-audit'
|
|
30
|
+
| 'conformance'
|
|
31
|
+
| 'github'
|
|
32
|
+
| 'prior-audit';
|
|
27
33
|
export type PocStatus = 'passing' | 'failing' | 'not_started';
|
|
28
34
|
|
|
29
35
|
export interface BoardIssue {
|
|
@@ -263,9 +269,11 @@ function SourceFilter({
|
|
|
263
269
|
const options: Array<{ id: IssueSource | 'all'; label: string }> = [
|
|
264
270
|
{ id: 'all', label: 'All sources' },
|
|
265
271
|
{ id: 'manual', label: 'Manual' },
|
|
272
|
+
{ id: 'ai-audit', label: 'AI audit' },
|
|
266
273
|
{ id: 'auditagent', label: 'AuditAgent' },
|
|
267
274
|
{ id: 'conformance', label: 'Conformance' },
|
|
268
275
|
{ id: 'github', label: 'GitHub' },
|
|
276
|
+
{ id: 'prior-audit', label: 'Prior audit' },
|
|
269
277
|
];
|
|
270
278
|
return (
|
|
271
279
|
<div className="flex flex-wrap gap-1.5">
|
|
@@ -437,8 +445,10 @@ function SourceChip({ source }: { source: IssueSource }) {
|
|
|
437
445
|
const labels: Record<IssueSource, string> = {
|
|
438
446
|
manual: 'Manual',
|
|
439
447
|
auditagent: 'AuditAgent',
|
|
448
|
+
'ai-audit': 'AI audit',
|
|
440
449
|
conformance: 'Conformance',
|
|
441
450
|
github: 'GitHub',
|
|
451
|
+
'prior-audit': 'Prior audit',
|
|
442
452
|
};
|
|
443
453
|
return (
|
|
444
454
|
<span className="rounded-md bg-surface-2 px-1.5 py-0.5 text-text-tertiary">
|
package/dashboard/app/layout.tsx
CHANGED
|
@@ -4,6 +4,7 @@ import { ThemeProvider } from 'next-themes';
|
|
|
4
4
|
import { DashboardLayout } from '@/components/DashboardLayout';
|
|
5
5
|
import { CommandPalette } from '@/components/CommandPalette';
|
|
6
6
|
import pkg from '../../package.json';
|
|
7
|
+
import { readJsonFile } from '@/lib/data';
|
|
7
8
|
import './globals.css';
|
|
8
9
|
|
|
9
10
|
const manrope = Manrope({
|
|
@@ -23,6 +24,15 @@ export const metadata: Metadata = {
|
|
|
23
24
|
description: 'Local dashboard for Solidity smart contract audits',
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
// The sidebar depends on .hex/config.json (diff mode shows Changes), so every
|
|
28
|
+
// route renders at request time — including /diagram and /flows, which would
|
|
29
|
+
// otherwise be prerendered with whatever config existed at build time.
|
|
30
|
+
export const dynamic = 'force-dynamic';
|
|
31
|
+
|
|
32
|
+
function isDiffAudit(): boolean {
|
|
33
|
+
return readJsonFile<{ project?: { mode?: string } }>('config.json')?.project?.mode === 'diff';
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
export default function RootLayout({
|
|
27
37
|
children,
|
|
28
38
|
}: {
|
|
@@ -33,7 +43,9 @@ export default function RootLayout({
|
|
|
33
43
|
<body className={`${manrope.variable} ${jetbrainsMono.variable} min-h-screen bg-surface-0 text-text-primary font-sans`}>
|
|
34
44
|
<ThemeProvider attribute="data-theme" defaultTheme="dark" enableSystem={false}>
|
|
35
45
|
<CommandPalette />
|
|
36
|
-
<DashboardLayout version={pkg.version}
|
|
46
|
+
<DashboardLayout version={pkg.version} diffMode={isDiffAudit()}>
|
|
47
|
+
{children}
|
|
48
|
+
</DashboardLayout>
|
|
37
49
|
</ThemeProvider>
|
|
38
50
|
</body>
|
|
39
51
|
</html>
|
|
@@ -381,6 +381,11 @@ function LeadsSection({
|
|
|
381
381
|
className="flex items-start justify-between gap-3 rounded-md border border-border-subtle bg-surface-2 px-3 py-2"
|
|
382
382
|
>
|
|
383
383
|
<span className="min-w-0 flex-1 text-body text-text-primary">
|
|
384
|
+
{lead.source === 'ai-audit' && (
|
|
385
|
+
<span className="mr-2 rounded-md bg-surface-3 px-1.5 py-0.5 text-caption text-text-tertiary">
|
|
386
|
+
AI audit
|
|
387
|
+
</span>
|
|
388
|
+
)}
|
|
384
389
|
<InlineMarkdown>{lead.text}</InlineMarkdown>
|
|
385
390
|
</span>
|
|
386
391
|
<button
|
package/dashboard/app/page.tsx
CHANGED
|
@@ -17,9 +17,17 @@ interface ProjectConfig {
|
|
|
17
17
|
chain: string;
|
|
18
18
|
solidity_version: string;
|
|
19
19
|
scope: string[];
|
|
20
|
+
mode?: 'full' | 'diff';
|
|
21
|
+
diff?: { base_commit: string };
|
|
20
22
|
};
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
interface DiffSummary {
|
|
26
|
+
base_commit: string;
|
|
27
|
+
head_commit: string;
|
|
28
|
+
summary: { files_changed: number; impacted_entry_points: number; storage_layout_changes: number };
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
interface Stats {
|
|
24
32
|
totals: {
|
|
25
33
|
files: number;
|
|
@@ -158,6 +166,7 @@ export default function HomePage() {
|
|
|
158
166
|
const config = readJsonFile<ProjectConfig>('config.json');
|
|
159
167
|
const overview = readMarkdownFile('overview.md');
|
|
160
168
|
const stats = readJsonFile<Stats>('stats.json');
|
|
169
|
+
const diff = config?.project.mode === 'diff' ? readJsonFile<DiffSummary>('diff.json') : null;
|
|
161
170
|
const findingsData = readJsonFile<FindingsData>('findings.json');
|
|
162
171
|
const externalCallsData = readJsonFile<ExternalCallsData>('external-calls.json');
|
|
163
172
|
|
|
@@ -191,6 +200,39 @@ export default function HomePage() {
|
|
|
191
200
|
</span>
|
|
192
201
|
</div>
|
|
193
202
|
)}
|
|
203
|
+
{config?.project.mode === 'diff' && (
|
|
204
|
+
<Link
|
|
205
|
+
href="/changes"
|
|
206
|
+
className="mt-3 flex flex-wrap items-center gap-2 rounded-lg border border-border-subtle bg-surface-1 px-4 py-3 text-body text-text-secondary hover:border-border-default hover:bg-surface-2"
|
|
207
|
+
>
|
|
208
|
+
<span className="rounded-md bg-accent-subtle px-2.5 py-1 text-caption font-medium text-accent">
|
|
209
|
+
Differential
|
|
210
|
+
</span>
|
|
211
|
+
<code className="font-mono text-caption text-text-primary">
|
|
212
|
+
{(diff?.base_commit ?? config.project.diff?.base_commit ?? '').slice(0, 8)}
|
|
213
|
+
</code>
|
|
214
|
+
<span aria-hidden="true">→</span>
|
|
215
|
+
<code className="font-mono text-caption text-text-primary">
|
|
216
|
+
{(diff?.head_commit ?? config.project.commit).slice(0, 8)}
|
|
217
|
+
</code>
|
|
218
|
+
{diff ? (
|
|
219
|
+
<span>
|
|
220
|
+
· {diff.summary.files_changed} file{diff.summary.files_changed !== 1 ? 's' : ''} changed ·{' '}
|
|
221
|
+
{diff.summary.impacted_entry_points} impacted entry point
|
|
222
|
+
{diff.summary.impacted_entry_points !== 1 ? 's' : ''}
|
|
223
|
+
{diff.summary.storage_layout_changes > 0 && (
|
|
224
|
+
<span className="text-[var(--high)]">
|
|
225
|
+
{' '}
|
|
226
|
+
· {diff.summary.storage_layout_changes} storage layout change
|
|
227
|
+
{diff.summary.storage_layout_changes !== 1 ? 's' : ''}
|
|
228
|
+
</span>
|
|
229
|
+
)}
|
|
230
|
+
</span>
|
|
231
|
+
) : (
|
|
232
|
+
<span>· run hex diff to compute the change set</span>
|
|
233
|
+
)}
|
|
234
|
+
</Link>
|
|
235
|
+
)}
|
|
194
236
|
</div>
|
|
195
237
|
|
|
196
238
|
{/* KPI cards */}
|