diff --git a/node_version/cli.ts b/node_version/cli.ts index 945ebfa..dd1297e 100644 --- a/node_version/cli.ts +++ b/node_version/cli.ts @@ -8,7 +8,7 @@ import { fileURLToPath } from "node:url"; import { Command } from "commander"; import { fetchRepo, fetchReadme } from "./github.js"; -import { buildPrompt, buildSimplePrompt } from "./prompt.js"; +import { buildPrompt, buildQuickPrompt, buildSimplePrompt } from "./prompt.js"; import { generateExplanation } from "./generate.js"; import { writeOutput } from "./writer.js"; import { readRepoSignalFiles } from "./repo_reader.js"; @@ -243,14 +243,80 @@ Examples: readme = null; } - let readResult: any = null; - if (!options.quick) { + // QUICK MODE + if (options.quick) { + const prompt = buildQuickPrompt( + repoData.full_name, + repoData.description, + readme + ); + + console.log("Generating explanation..."); + + let output: string; + + try { + output = await generateExplanation(prompt); + } catch (e: any) { + console.error("Failed to generate explanation."); + console.error(`error: ${e?.message || e}`); + console.error("\nfix:"); + console.error("- Ensure GEMINI_API_KEY is set"); + console.error("- Or run: explainthisrepo --doctor"); + process.exit(1); + } + + console.log("Quick summary 🎉"); + console.log(output.trim()); + return; + } + + // SIMPLE MODE + if (options.simple) { + let readResult: any = null; + try { readResult = await readRepoSignalFiles(owner, repo); } catch (e: any) { console.warn(`Warning: Could not read repo files: ${e?.message || e}`); readResult = null; } + + const prompt = buildSimplePrompt( + repoData.full_name, + repoData.description, + readme, + readResult?.treeText ?? null + ); + + console.log("Generating explanation..."); + + let output: string; + + try { + output = await generateExplanation(prompt); + } catch (e: any) { + console.error("Failed to generate explanation."); + console.error(`error: ${e?.message || e}`); + console.error("\nfix:"); + console.error("- Ensure GEMINI_API_KEY is set"); + console.error("- Or run: explainthisrepo --doctor"); + process.exit(1); + } + + console.log("Simple summary 🎉"); + console.log(output.trim()); + return; + } + + // NORMAL / DETAILED MODE + let readResult: any = null; + + try { + readResult = await readRepoSignalFiles(owner, repo); + } catch (e: any) { + console.warn(`Warning: Could not read repo files: ${e?.message || e}`); + readResult = null; } const prompt = buildPrompt( @@ -258,7 +324,6 @@ Examples: repoData.description, readme, options.detailed || false, - options.quick || false, readResult?.treeText ?? null, readResult?.filesText ?? null ); @@ -278,34 +343,6 @@ Examples: process.exit(1); } - if (options.quick) { - console.log("Quick summary 🎉"); - console.log(output.trim()); - return; - } - - if (options.simple) { - console.log("Summarizing..."); - const simplePrompt = buildSimplePrompt(output); - - let simpleOutput: string; - - try { - simpleOutput = await generateExplanation(simplePrompt); - } catch (e: any) { - console.error("Failed to generate explanation."); - console.error(`error: ${e?.message || e}`); - console.error("\nfix:"); - console.error("- Ensure GEMINI_API_KEY is set"); - console.error("- Or run: explainthisrepo --doctor"); - process.exit(1); - } - - console.log("Simple summary 🎉"); - console.log(simpleOutput.trim()); - return; - } - console.log("Writing EXPLAIN.md..."); writeOutput(output); diff --git a/node_version/prompt.ts b/node_version/prompt.ts index faf23dc..1a60f7e 100644 --- a/node_version/prompt.ts +++ b/node_version/prompt.ts @@ -3,38 +3,9 @@ export function buildPrompt( description: string | null, readme: string | null, detailed: boolean = false, - quick: boolean = false, treeText: string | null = null, filesText: string | null = null ): string { - // QUICK MODE: one sentence definition only - if (quick) { - const readmeSnippet = (readme || "").slice(0, 2000); - - return ` -You are a senior software engineer. - -Write a ONE-SENTENCE plain-English definition of what this GitHub repository is. - -Repository: -- Name: ${repoName} -- Description: ${description || "No description provided"} - -README snippet: -${readmeSnippet || "No README provided"} - -Rules: -- Output MUST be exactly 1 sentence. -- Plain English. -- No markdown. -- No quotes. -- No bullet points. -- No extra text. -- Do not add features not stated in the description/README. -`.trim(); - } - - // NORMAL / DETAILED MODE let prompt = `You are a senior software engineer. Your task is to explain a GitHub repository clearly and concisely for a human reader. @@ -46,10 +17,10 @@ Repository: README content: ${readme || "No README provided"} -Repository structure: -${treeText || "No tree provided"} +Repo structure: +${treeText || "No file tree provided"} -Key files (snippets): +Key code files: ${filesText || "No code files provided"} Instructions: @@ -72,7 +43,7 @@ Additional instructions: - Mention important files and their roles. `; } - + prompt += ` Output format: @@ -86,14 +57,59 @@ Output format: return prompt.trim(); } -export function buildSimplePrompt(longExplanation: string): string { - return ` -You are a senior software engineer. +export function buildQuickPrompt( + repoName: string, + description: string | null, + readme: string | null +): string { + const readmeSnippet = (readme || "No README provided").slice(0, 2000); + + const prompt = `You are a senior software engineer. + +Write a ONE-SENTENCE plain-English definition of what this GitHub repository is. -Rewrite the long repository explanation below into a SIMPLE version in the exact style specified. +Repository: +- Name: ${repoName} +- Description: ${description || "No description provided"} -Input explanation: -${longExplanation} +README snippet: +${readmeSnippet} + +Rules: +- Output MUST be exactly 1 sentence. +- Plain English. +- No markdown. +- No quotes. +- No bullet points. +- No extra text. +- Do not add features not stated in the description/README. +`; + + return prompt.trim(); +} + +export function buildSimplePrompt( + repoName: string, + description: string | null, + readme: string | null, + treeText: string | null = null +): string { + const readmeContent = (readme || "No README provided").slice(0, 4000); + const treeContent = (treeText || "No file tree provided").slice(0, 1500); + + const prompt = `You are a senior software engineer. + +Summarize this GitHub repository in a concise bullet-point format. + +Repository: +- Name: ${repoName} +- Description: ${description || "No description provided"} + +README content: +${readmeContent} + +Repo structure: +${treeContent} Output style rules: - Plain English. @@ -105,13 +121,14 @@ Key points from the repo: - Each bullet MUST start with: ⬤ - Each bullet title should be 1–3 words only (example: "Purpose", "Stack", "Entrypoints", "How it works", "Usage", "Structure"). - Each bullet body should be 1–2 lines max. -- If the input contains architecture/pipeline steps, capture them naturally. -- If the input does NOT contain architecture/pipeline steps, do NOT invent them. +- Base bullets strictly on the provided README and structure. +- Do NOT invent features, architecture, or details not present in the input. - Optional: end with one extra line starting with: Also interesting: -- Do NOT add features not present in the input. - No quotes. Make it feel like a human developer explaining to another developer in simple terms. -`.trim(); +`; + + return prompt.trim(); } \ No newline at end of file