codeprobe-scanner 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/bin/codeprobe.cjs +1 -1
  2. package/package.json +1 -1
  3. package/src/integrations/videodb.ts +9 -8
  4. package/.claude/settings.local.json +0 -19
  5. package/.dockerignore +0 -17
  6. package/.env.development +0 -8
  7. package/.env.setup +0 -214
  8. package/.github/workflows/codeprobe-scan.yml +0 -137
  9. package/.github/workflows/codeprobe.yml +0 -84
  10. package/.github/workflows/scan-schedule.yml +0 -28
  11. package/ANALYSIS_SUMMARY.md +0 -365
  12. package/API_INTEGRATIONS.md +0 -469
  13. package/BUILD_PLAYBOOK.md +0 -349
  14. package/CLAUDE.md +0 -106
  15. package/DEPLOY.md +0 -452
  16. package/DEPLOYMENT_STATUS.md +0 -240
  17. package/DEPLOY_CHECKLIST.md +0 -316
  18. package/Dockerfile +0 -24
  19. package/EXECUTION_PLAN.html +0 -1086
  20. package/IMPLEMENTATION_COMPLETE.md +0 -288
  21. package/IMPLEMENTATION_SUMMARY.md +0 -443
  22. package/INTERACTIVE_FIX_FLOW.md +0 -308
  23. package/MIGRATION_COMPLETE.md +0 -327
  24. package/ORCHESTRATOR_SYNTHESIS.json +0 -80
  25. package/PENDING_WORK.md +0 -308
  26. package/PREFLIGHT_PLAN.md +0 -182
  27. package/QUICKSTART.md +0 -305
  28. package/STAGE_1_SETUP_ENGINE.md +0 -245
  29. package/STAGE_2_ARCHITECTURE.md +0 -714
  30. package/STAGE_2_CLI_VERIFICATION.md +0 -269
  31. package/STAGE_2_COMPLETE.md +0 -332
  32. package/STAGE_2_IMPLEMENTATION_PLAN.md +0 -679
  33. package/STAGE_3_COMPLETE.md +0 -246
  34. package/STAGE_3_DASHBOARD_POLISH.md +0 -371
  35. package/STAGE_3_SETUP.md +0 -155
  36. package/VIDEODB_INTEGRATION.md +0 -237
  37. package/archived/DASHBOARD_UI_WALKTHROUGH.md +0 -392
  38. package/archived/FRONTEND_SETUP.md +0 -236
  39. package/archived/auth.ts +0 -40
  40. package/archived/dashboard/components/BusinessImpactCard.tsx +0 -48
  41. package/archived/dashboard/components/CVETable.tsx +0 -104
  42. package/archived/dashboard/components/ErrorBoundary.tsx +0 -48
  43. package/archived/dashboard/components/PatchDiffViewer.tsx +0 -43
  44. package/archived/dashboard/components/RiskGauge.tsx +0 -64
  45. package/archived/dashboard/frontend.tsx +0 -104
  46. package/archived/dashboard/hooks/useAuth.ts +0 -32
  47. package/archived/dashboard/hooks/useScan.ts +0 -65
  48. package/archived/dashboard/index.html +0 -15
  49. package/archived/dashboard/pages/LoginPage.tsx +0 -28
  50. package/archived/dashboard/pages/ScanDetailPage.tsx +0 -143
  51. package/archived/dashboard/pages/ScansListPage.tsx +0 -160
  52. package/bun.lock +0 -603
  53. package/codeprobe-prd.md +0 -674
  54. package/cve-cache.json +0 -25
  55. package/demo-vulnerable-app/.github/workflows/codeprobe.yml +0 -32
  56. package/demo-vulnerable-app/README.md +0 -70
  57. package/demo-vulnerable-app/package-lock.json +0 -27
  58. package/demo-vulnerable-app/package.json +0 -15
  59. package/demo-vulnerable-app/server.js +0 -34
  60. package/demo.sh +0 -45
  61. package/index.ts +0 -19
  62. package/patches.json +0 -12
  63. package/serve-dashboard.ts +0 -23
  64. package/src/cli/index.ts +0 -137
  65. package/src/engine/index.ts +0 -90
  66. package/src/test/cli.test.ts +0 -211
  67. package/src/test/dashboard.test.ts +0 -38
  68. package/src/test/demo-scan.json +0 -32
  69. package/src/test/engine.test.ts +0 -157
  70. package/tailwind.config.js +0 -11
  71. package/tsconfig.json +0 -30
  72. package/verify-dashboard.ts +0 -87
  73. package/verify-env.sh +0 -98
@@ -1,143 +0,0 @@
1
- import React from "react";
2
- import { useScan } from "../hooks/useScan.ts";
3
- import { RiskGauge } from "../components/RiskGauge.tsx";
4
- import { CVETable } from "../components/CVETable.tsx";
5
- import { PatchDiffViewer } from "../components/PatchDiffViewer.tsx";
6
- import { BusinessImpactCard } from "../components/BusinessImpactCard.tsx";
7
-
8
- interface ScanDetailPageProps {
9
- scanId: string;
10
- token: string | null;
11
- onBack: () => void;
12
- }
13
-
14
- export function ScanDetailPage({ scanId, token, onBack }: ScanDetailPageProps) {
15
- const { scan, loading, error } = useScan(scanId, token);
16
-
17
- if (error) {
18
- return (
19
- <div className="space-y-4">
20
- <button onClick={onBack} className="text-blue-400 hover:text-blue-300">
21
- ← Back
22
- </button>
23
- <div className="bg-red-900 border border-red-600 rounded p-4 text-white">
24
- Failed to load scan. Try refreshing.
25
- </div>
26
- </div>
27
- );
28
- }
29
-
30
- if (loading) {
31
- return (
32
- <div className="space-y-4">
33
- <button onClick={onBack} className="text-blue-400 hover:text-blue-300">
34
- ← Back
35
- </button>
36
- <p className="text-gray-400">Loading scan details...</p>
37
- </div>
38
- );
39
- }
40
-
41
- if (!scan) {
42
- return (
43
- <div className="space-y-4">
44
- <button onClick={onBack} className="text-blue-400 hover:text-blue-300">
45
- ← Back
46
- </button>
47
- <div className="text-center py-8 text-gray-400">
48
- Scan not found. It may have been deleted.
49
- </div>
50
- </div>
51
- );
52
- }
53
-
54
- const copyUrl = () => {
55
- const url = `${window.location.origin}?scan=${scanId}`;
56
- navigator.clipboard.writeText(url);
57
- alert("Scan URL copied!");
58
- };
59
-
60
- const exportJson = () => {
61
- const element = document.createElement("a");
62
- element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(JSON.stringify(scan, null, 2)));
63
- element.setAttribute("download", `${scanId}.json`);
64
- element.style.display = "none";
65
- document.body.appendChild(element);
66
- element.click();
67
- document.body.removeChild(element);
68
- };
69
-
70
- return (
71
- <div className="space-y-8">
72
- <button onClick={onBack} className="text-blue-400 hover:text-blue-300 text-sm font-semibold">
73
- ← Back to Scans
74
- </button>
75
-
76
- <div className="space-y-4">
77
- <h2 className="text-2xl font-bold">{scan.repo}</h2>
78
- <p className="text-gray-400 text-sm">
79
- Scan ID: <code className="bg-gray-800 px-2 py-1 rounded">{scan.id}</code>
80
- </p>
81
- <p className="text-gray-400 text-sm">
82
- Timestamp: {new Date(scan.timestamp * 1000).toLocaleString()}
83
- </p>
84
- </div>
85
-
86
- <div className="bg-gray-800 rounded-lg p-6">
87
- <RiskGauge score={scan.riskScore || 0} />
88
- </div>
89
-
90
- {scan.cves && scan.cves.length > 0 && (
91
- <BusinessImpactCard riskScore={scan.riskScore} cveCount={scan.cves.length} />
92
- )}
93
-
94
- <div className="grid grid-cols-3 gap-4">
95
- <div className="bg-gray-800 rounded p-4">
96
- <p className="text-gray-400 text-xs font-semibold mb-1">Confirmed Exploitable</p>
97
- <p className="text-2xl font-bold text-red-400">
98
- {scan.cves?.filter((c: any) => c.status.includes("Confirmed")).length || 0}
99
- </p>
100
- </div>
101
- <div className="bg-gray-800 rounded p-4">
102
- <p className="text-gray-400 text-xs font-semibold mb-1">Theoretical Risk</p>
103
- <p className="text-2xl font-bold text-yellow-400">
104
- {scan.cves?.filter((c: any) => c.status.includes("Theoretical")).length || 0}
105
- </p>
106
- </div>
107
- <div className="bg-gray-800 rounded p-4">
108
- <p className="text-gray-400 text-xs font-semibold mb-1">Supply Chain Warnings</p>
109
- <p className="text-2xl font-bold text-orange-400">{scan.supplyChainWarnings || 0}</p>
110
- </div>
111
- </div>
112
-
113
- {scan.cves && scan.cves.length > 0 && (
114
- <div className="bg-gray-800 rounded-lg p-6">
115
- <h3 className="text-xl font-bold mb-4">Vulnerabilities</h3>
116
- <CVETable cves={scan.cves} />
117
- </div>
118
- )}
119
-
120
- {scan.cves?.[0]?.patch && (
121
- <div className="bg-gray-800 rounded-lg p-6">
122
- <h3 className="text-xl font-bold mb-4">Patch Diff</h3>
123
- <PatchDiffViewer diff={scan.cves[0].patch} />
124
- </div>
125
- )}
126
-
127
- <div className="flex gap-2 flex-wrap">
128
- <button
129
- onClick={copyUrl}
130
- className="px-4 py-2 bg-blue-600 hover:bg-blue-700 rounded font-semibold text-sm transition"
131
- >
132
- Copy Scan URL
133
- </button>
134
- <button
135
- onClick={exportJson}
136
- className="px-4 py-2 bg-gray-700 hover:bg-gray-600 rounded font-semibold text-sm transition"
137
- >
138
- Export as JSON
139
- </button>
140
- </div>
141
- </div>
142
- );
143
- }
@@ -1,160 +0,0 @@
1
- import React, { useState } from "react";
2
- import { useScans } from "../hooks/useScan.ts";
3
-
4
- interface ScansListPageProps {
5
- token: string | null;
6
- onSelectScan: (scanId: string) => void;
7
- }
8
-
9
- export function ScansListPage({ token, onSelectScan }: ScansListPageProps) {
10
- const { scans, loading, error } = useScans(token);
11
- const [page, setPage] = useState(1);
12
- const [filter, setFilter] = useState<string | null>(null);
13
-
14
- const itemsPerPage = 10;
15
- const filtered = filter
16
- ? scans.filter((s) => {
17
- const risk = s.riskScore || 0;
18
- if (filter === "CRITICAL") return risk >= 8;
19
- if (filter === "HIGH") return risk >= 6 && risk < 8;
20
- if (filter === "MEDIUM") return risk >= 4 && risk < 6;
21
- return risk < 4;
22
- })
23
- : scans;
24
-
25
- const paginated = filtered.slice((page - 1) * itemsPerPage, page * itemsPerPage);
26
- const maxPages = Math.ceil(filtered.length / itemsPerPage);
27
-
28
- if (error) {
29
- return (
30
- <div className="bg-red-900 border border-red-600 rounded p-4 text-white">
31
- Failed to load scans. Try refreshing.
32
- </div>
33
- );
34
- }
35
-
36
- if (filtered.length === 0 && !loading) {
37
- return (
38
- <div className="text-center py-12">
39
- <p className="text-gray-400 mb-4">No scans yet.</p>
40
- <p className="text-gray-500 text-sm">
41
- Run <code className="bg-gray-800 px-2 py-1 rounded">codeprobe scan</code> from CLI
42
- </p>
43
- </div>
44
- );
45
- }
46
-
47
- return (
48
- <div className="space-y-6">
49
- <div className="flex gap-2 flex-wrap">
50
- <button
51
- onClick={() => {
52
- setFilter(null);
53
- setPage(1);
54
- }}
55
- className={`px-4 py-2 rounded text-sm font-semibold transition ${
56
- filter === null
57
- ? "bg-blue-600 text-white"
58
- : "bg-gray-700 text-gray-300 hover:bg-gray-600"
59
- }`}
60
- >
61
- All
62
- </button>
63
- {["CRITICAL", "HIGH", "MEDIUM", "LOW"].map((level) => (
64
- <button
65
- key={level}
66
- onClick={() => {
67
- setFilter(level);
68
- setPage(1);
69
- }}
70
- className={`px-4 py-2 rounded text-sm font-semibold transition ${
71
- filter === level
72
- ? "bg-blue-600 text-white"
73
- : "bg-gray-700 text-gray-300 hover:bg-gray-600"
74
- }`}
75
- >
76
- {level}
77
- </button>
78
- ))}
79
- </div>
80
-
81
- {loading && <p className="text-gray-400">Loading scans...</p>}
82
-
83
- {!loading && (
84
- <>
85
- <div className="overflow-x-auto">
86
- <table className="w-full text-sm">
87
- <thead>
88
- <tr className="border-b border-gray-700">
89
- <th className="text-left py-3 px-4 font-semibold text-gray-300">Scan ID</th>
90
- <th className="text-left py-3 px-4 font-semibold text-gray-300">Repo</th>
91
- <th className="text-left py-3 px-4 font-semibold text-gray-300">Risk</th>
92
- <th className="text-left py-3 px-4 font-semibold text-gray-300">CVEs</th>
93
- <th className="text-left py-3 px-4 font-semibold text-gray-300">Timestamp</th>
94
- <th className="text-left py-3 px-4 font-semibold text-gray-300">Action</th>
95
- </tr>
96
- </thead>
97
- <tbody>
98
- {paginated.map((scan: any) => (
99
- <tr key={scan.id} className="border-b border-gray-800 hover:bg-gray-800 transition">
100
- <td className="py-4 px-4 font-mono text-blue-400 text-xs">{scan.id}</td>
101
- <td className="py-4 px-4 text-gray-300 max-w-xs truncate">{scan.repo}</td>
102
- <td className="py-4 px-4">
103
- <span
104
- className={`px-2 py-1 rounded text-xs font-semibold ${
105
- scan.riskScore >= 8
106
- ? "bg-red-900 text-red-300"
107
- : scan.riskScore >= 6
108
- ? "bg-orange-900 text-orange-300"
109
- : scan.riskScore >= 4
110
- ? "bg-yellow-900 text-yellow-300"
111
- : "bg-green-900 text-green-300"
112
- }`}
113
- >
114
- {scan.riskScore?.toFixed(1) || "N/A"}
115
- </span>
116
- </td>
117
- <td className="py-4 px-4 text-gray-300">{scan.cves?.length || 0}</td>
118
- <td className="py-4 px-4 text-gray-400 text-xs">
119
- {new Date(scan.timestamp * 1000).toLocaleString()}
120
- </td>
121
- <td className="py-4 px-4">
122
- <button
123
- onClick={() => onSelectScan(scan.id)}
124
- className="text-blue-400 hover:text-blue-300 text-sm font-semibold"
125
- >
126
- View →
127
- </button>
128
- </td>
129
- </tr>
130
- ))}
131
- </tbody>
132
- </table>
133
- </div>
134
-
135
- {maxPages > 1 && (
136
- <div className="flex justify-between items-center">
137
- <button
138
- onClick={() => setPage(Math.max(1, page - 1))}
139
- disabled={page === 1}
140
- className="px-4 py-2 bg-gray-700 hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed rounded transition"
141
- >
142
- Previous
143
- </button>
144
- <span className="text-gray-400 text-sm">
145
- Page {page} of {maxPages}
146
- </span>
147
- <button
148
- onClick={() => setPage(Math.min(maxPages, page + 1))}
149
- disabled={page === maxPages}
150
- className="px-4 py-2 bg-gray-700 hover:bg-gray-600 disabled:opacity-50 disabled:cursor-not-allowed rounded transition"
151
- >
152
- Next
153
- </button>
154
- </div>
155
- )}
156
- </>
157
- )}
158
- </div>
159
- );
160
- }