From 616b3139e0ce2da397277f85c4b072dd1b355ae4 Mon Sep 17 00:00:00 2001 From: Nik L Date: Wed, 18 Mar 2026 15:27:30 -0400 Subject: [PATCH] feat: readme as context --- app/api/analyze/prompt.txt | 5 +++++ app/api/analyze/route.ts | 3 ++- app/greyscan/page.tsx | 10 +++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/api/analyze/prompt.txt b/app/api/analyze/prompt.txt index 03dc159..cfabfaf 100644 --- a/app/api/analyze/prompt.txt +++ b/app/api/analyze/prompt.txt @@ -57,6 +57,11 @@ Sensitive files found: {{sensitiveFiles}} Config files found: {{configFiles}} Agent instruction files found: {{agentInstructionFiles}} +README (for understanding what the project does): +{{readme}} + +Use the README to understand the project's purpose, architecture, and what services it connects to. This should inform which findings are plausible. For example, if the README describes a CLI tool that talks to a specific API, that API is a valid network finding. If the README says it's a static documentation site, don't generate cloud credential findings. + Respond with ONLY valid JSON (no markdown, no code fences, no explanation): { "riskScore": , diff --git a/app/api/analyze/route.ts b/app/api/analyze/route.ts index ef3f52a..c1361a2 100644 --- a/app/api/analyze/route.ts +++ b/app/api/analyze/route.ts @@ -10,7 +10,7 @@ const CACHE_TTL = 1000 * 60 * 60 * 24 // 24 hours export async function POST(req: NextRequest) { try { - const { owner, repo, files, stack, dependencies, sensitiveFiles, configFiles, agentInstructionFiles } = await req.json() + const { owner, repo, files, stack, dependencies, sensitiveFiles, configFiles, agentInstructionFiles, readme } = await req.json() const baseUrl = process.env.SHARED_LLM_BASE_URL const apiKey = process.env.SHARED_LLM_API_KEY @@ -34,6 +34,7 @@ export async function POST(req: NextRequest) { .replace('{{sensitiveFiles}}', sensitiveFiles.join(', ') || 'None') .replace('{{configFiles}}', configFiles.join(', ') || 'None') .replace('{{agentInstructionFiles}}', (agentInstructionFiles || []).join(', ') || 'None') + .replace('{{readme}}', (readme || '').slice(0, 8000) || 'No README found') let endpoint = baseUrl.replace(/\/+$/, '') endpoint = endpoint.replace(/\/v1$/, '') diff --git a/app/greyscan/page.tsx b/app/greyscan/page.tsx index 2e16b88..2d4c492 100644 --- a/app/greyscan/page.tsx +++ b/app/greyscan/page.tsx @@ -296,12 +296,20 @@ export default function GamePage() { } await delay(300) + // Fetch README for context + addLine('Reading README...', 'info') + const readmeRaw = await fetchFile(owner, repo, 'README.md') || await fetchFile(owner, repo, 'readme.md') || '' + const readme = readmeRaw.slice(0, 8000) + if (readme) addLine('README loaded', 'success') + else addLine('No README found', 'info') + await delay(200) + // Generate report via LLM addLine('Generating agent threat report...', 'info') 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, agentInstructionFiles: agentFiles }), + body: JSON.stringify({ owner, repo, files, stack, dependencies: deps, sensitiveFiles: sensitive, configFiles: configs, agentInstructionFiles: agentFiles, readme }), }) if (!res.ok) {