feat: better greyscan positioning

This commit is contained in:
Nik L
2026-03-18 15:21:56 -04:00
parent 697c09457c
commit 62af4ed8b9
3 changed files with 79 additions and 42 deletions

View File

@@ -3,7 +3,7 @@
import { useState, useEffect, useRef } from 'react'
import {
Shield, AlertTriangle, Globe, FolderOpen, Terminal,
ArrowLeft, Copy, Check, ArrowRight, Lock, Eye,
ArrowLeft, Copy, Check, ArrowRight, Lock, Eye, MessageSquareWarning,
} from 'lucide-react'
// --- Types ---
@@ -50,6 +50,16 @@ const CONFIG_PATTERNS = [
'netlify.toml', 'terraform/', 'k8s/', '.aws/', 'Makefile',
]
const AGENT_INSTRUCTION_PATTERNS = [
'CLAUDE.md', '.claude/', '.claude/commands/', '.claude/agents/',
'.cursorrules', '.cursorignore', '.cursor/',
'.github/copilot-instructions.md',
'AGENTS.md', '.mcp.json', 'mcp.json',
'.aider.conf.yml', '.aiderignore',
'CONVENTIONS.md', 'CONTRIBUTING.md',
'.windsurfrules', '.boltrules', '.clinerules',
]
const STACK_DETECT: [string, (f: string[]) => boolean][] = [
['Node.js', f => f.some(x => x === 'package.json')],
['TypeScript', f => f.some(x => x === 'tsconfig.json' || x.endsWith('.ts') || x.endsWith('.tsx'))],
@@ -123,6 +133,7 @@ function typeIcon(t: string) {
if (t === 'network_call') return <Globe className="h-4 w-4" />
if (t === 'directory_access') return <FolderOpen className="h-4 w-4" />
if (t === 'command_execution') return <Terminal className="h-4 w-4" />
if (t === 'prompt_injection') return <MessageSquareWarning className="h-4 w-4" />
return <Eye className="h-4 w-4" />
}
@@ -238,6 +249,20 @@ export default function GamePage() {
// Config files
const configs = files.filter(f => CONFIG_PATTERNS.some(p => f.includes(p))).slice(0, 15)
// Agent instruction files (prompt injection surface)
addLine('Scanning for agent instruction files...', 'info')
await delay(200)
const agentFiles = files.filter(f => {
const name = f.split('/').pop() || f
return AGENT_INSTRUCTION_PATTERNS.some(p => name === p || f.includes(p))
})
for (const f of agentFiles.slice(0, 8)) {
addLine(f, 'warning')
await delay(100)
}
if (agentFiles.length === 0) addLine('No agent instruction files found', 'success')
await delay(200)
// Fetch dependencies
addLine('Analyzing dependencies...', 'info')
await delay(200)
@@ -276,7 +301,7 @@ export default function GamePage() {
const res = await fetch('/api/analyze', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ owner, repo, files, stack, dependencies: deps, sensitiveFiles: sensitive, configFiles: configs }),
body: JSON.stringify({ owner, repo, files, stack, dependencies: deps, sensitiveFiles: sensitive, configFiles: configs, agentInstructionFiles: agentFiles }),
})
if (!res.ok) {
@@ -362,7 +387,7 @@ export default function GamePage() {
</h1>
<p className="text-muted-foreground font-serif text-base sm:text-lg leading-relaxed mb-10 max-w-xl mx-auto">
AI agents run as you, with access to everything you have. Paste a repo URL and we&apos;ll show what an unrestricted agent would attempt on your machine when working on that codebase.
AI agents run as you, with access to everything you have. Paste a repo and see what an unrestricted agent could attempt. This is not a security audit, it&apos;s a wake-up call.
</p>
<form
@@ -569,8 +594,11 @@ export default function GamePage() {
{/* CTA */}
<div className="px-6 sm:px-8 py-6 sm:py-8 border-t border-border/20 bg-card/20 text-center">
<p className="text-xs text-muted-foreground/50 font-sans mb-4">
This is not a security certification. It&apos;s a demonstration of what&apos;s possible without a sandbox.
</p>
<p className="font-serif text-lg sm:text-xl font-semibold tracking-tight mb-2">
This is what Greywall would have blocked.
Greywall blocks this by default.
</p>
<p className="text-xs text-muted-foreground font-serif mb-5">
Container-free sandboxing with real-time observability for AI agents.