diff --git a/README.md b/README.md index 55a4cbfda..55852df2e 100644 --- a/README.md +++ b/README.md @@ -1,361 +1,192 @@ - -
-
- The agentic compliance platform. Get SOC 2 and ISO 27001 audit-ready in record time, backed by enterprise-grade cybersecurity.
- The open-source compliance platform.
-
+ Website ·
+ Docs ·
+ Discord ·
+ Roadmap ·
Issues
- ·
- Roadmap
{finding.title} {finding.location}
-
+ {label}
+ {description}
+
+ Comp AI
+ Comp AI
-
-
- Learn more »
-
-
- Discord
- ·
- Website
- ·
- Documentation
- ·
+
-
-#### [Vercel](https://vercel.com/)
-
-
-
-
-
-### Built With
-
-- [Next.js](https://nextjs.org/?ref=trycomp.ai)
-- [Trigger.dev](https://trigger.dev/?ref=trycomp.ai)
-- [Prisma](https://prisma.io/?ref=trycomp.ai)
-- [Tailwind CSS](https://tailwindcss.com/?ref=trycomp.ai)
-- [Upstash](https://upstash.com/?ref=trycomp.ai)
-- [Vercel](https://vercel.com/?ref=trycomp.ai)
+
-# Test packages locally
-bun run release:packages --dry-run
-```
+
-## Contributors
+## Contributing
-## Repo Activity
-
-
-
-
+
## License
-Comp AI, Inc. is a commercial open source company, which means some parts of this open source repository require a commercial license. The concept is called "Open Core" where the core technology (99%) is fully open source, licensed under [AGPLv3](https://opensource.org/license/agpl-v3) and the last 1% is covered under a commercial license (["/ee" Enterprise Edition"]).
+Comp AI, Inc. is a commercial open source company. The core technology (99%) is licensed under [AGPLv3](https://opensource.org/license/agpl-v3). Enterprise features under `/ee` require a commercial license. See [LICENSE](https://github.com/trycompai/comp/blob/main/LICENSE) for details.
-> [!TIP]
-> We work closely with the community and always invite feedback about what should be open and what is fine to be commercial. This list is not set and stone and we have moved things from commercial to open in the past. Please open a [discussion](https://github.com/trycompai/comp/discussions) if you feel like something is wrong.
+Open a [discussion](https://github.com/trycompai/comp/discussions) if you have questions about what's open vs commercial.
diff --git a/apps/app/src/app/(app)/[orgId]/security/penetration-tests/components/pentest-preview-animation.tsx b/apps/app/src/app/(app)/[orgId]/security/penetration-tests/components/pentest-preview-animation.tsx
new file mode 100644
index 000000000..893748b3c
--- /dev/null
+++ b/apps/app/src/app/(app)/[orgId]/security/penetration-tests/components/pentest-preview-animation.tsx
@@ -0,0 +1,165 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import { AlertTriangle, CheckCircle2, Loader2, Shield, ShieldAlert } from 'lucide-react';
+
+interface Finding {
+ severity: 'critical' | 'high' | 'medium' | 'low';
+ title: string;
+ location: string;
+}
+
+const findings: Finding[] = [
+ { severity: 'critical', title: 'SQL Injection in /api/users', location: 'POST /api/users?search=' },
+ { severity: 'high', title: 'Stored XSS in comments', location: 'POST /api/comments' },
+ { severity: 'high', title: 'Broken access control', location: 'GET /api/admin/settings' },
+ { severity: 'medium', title: 'Missing rate limiting', location: 'POST /api/auth/login' },
+ { severity: 'medium', title: 'Insecure CORS policy', location: 'Origin: *' },
+ { severity: 'low', title: 'Missing security headers', location: 'X-Frame-Options' },
+];
+
+const agents = [
+ 'Reconnaissance',
+ 'Authentication testing',
+ 'Injection testing',
+ 'Access control audit',
+ 'Configuration review',
+];
+
+const severityColors = {
+ critical: 'bg-red-100 text-red-700 dark:bg-red-950/40 dark:text-red-400',
+ high: 'bg-orange-100 text-orange-700 dark:bg-orange-950/40 dark:text-orange-400',
+ medium: 'bg-yellow-100 text-yellow-700 dark:bg-yellow-950/40 dark:text-yellow-400',
+ low: 'bg-blue-100 text-blue-700 dark:bg-blue-950/40 dark:text-blue-400',
+};
+
+export function PentestPreviewAnimation() {
+ const [progress, setProgress] = useState(0);
+ const [currentAgent, setCurrentAgent] = useState(0);
+ const [visibleFindings, setVisibleFindings] = useState(0);
+ const [phase, setPhase] = useState<'scanning' | 'complete'>('scanning');
+
+ useEffect(() => {
+ const totalDuration = 8000;
+ const interval = 50;
+ let elapsed = 0;
+
+ let pausing = false;
+
+ const timer = setInterval(() => {
+ if (pausing) return;
+
+ elapsed += interval;
+ const t = elapsed / totalDuration;
+
+ if (t >= 1) {
+ setPhase('complete');
+ setProgress(100);
+ setVisibleFindings(findings.length);
+ setCurrentAgent(agents.length - 1);
+
+ // Pause, then reset once
+ pausing = true;
+ setTimeout(() => {
+ elapsed = 0;
+ pausing = false;
+ setPhase('scanning');
+ setProgress(0);
+ setVisibleFindings(0);
+ setCurrentAgent(0);
+ }, 3000);
+ return;
+ }
+
+ // Progress with easing
+ const eased = t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
+ setProgress(Math.round(eased * 100));
+
+ // Cycle through agents
+ setCurrentAgent(Math.min(Math.floor(t * agents.length), agents.length - 1));
+
+ // Reveal findings progressively
+ setVisibleFindings(Math.floor(t * (findings.length + 1)));
+ }, interval);
+
+ return () => clearInterval(timer);
+ }, []);
+
+ const isComplete = phase === 'complete';
+
+ return (
+
-
{title}
+
+ {features.map((item) => (
+
+ )}
+
+