{"name":"Transform GitHub repositories into architecture blueprints with AI","nodes":[{"id":"c239fbe4-e34f-445f-9292-141699a76a9a","name":"Receive GitHub URL","type":"n8n-nodes-base.webhook","onError":"continueRegularOutput","position":[-2704,208],"parameters":{"path":"repo-blueprint","options":{"ignoreBots":false},"httpMethod":"POST","responseMode":"responseNode"},"typeVersion":2.1},{"id":"f6117e39-bbea-4b8b-af81-9d11dea411d6","name":"Blueprint Form","type":"n8n-nodes-base.formTrigger","position":[-2704,512],"parameters":{"path":"repo-blueprint-form","options":{"buttonLabel":"Generate Blueprint"},"formTitle":"Repo Blueprint Architect","formFields":{"values":[{"fieldLabel":"GitHub Repository URL","placeholder":"https://github.com/owner/repo","requiredField":true}]},"responseMode":"responseNode","formDescription":"Enter a public GitHub repository URL to generate an evidence-based system architecture blueprint with Mermaid.js diagrams."},"typeVersion":2.1},{"id":"0da401d5-5bd5-4d5c-8bd4-56c0231278e6","name":"Parse Owner and Repo","type":"n8n-nodes-base.code","position":[-2432,208],"parameters":{"jsCode":"const input = $input.first().json;\nconst url = input.body?.github_url || input.body?.repository_url || input['GitHub Repository URL'];\n\nif (!url) {\n  throw new Error('Missing GitHub URL. Send body.github_url or body.repository_url (webhook) or fill the form field.');\n}\n\nconst match = url.match(/github\\.com\\/([^\\/]+)\\/([^\\/\\.]+)/);\n\nif (!match) {\n  throw new Error(`Invalid GitHub URL: ${url}`);\n}\n\nreturn [{\n  json: {\n    github_url: url,\n    owner: match[1],\n    repo: match[2]\n  }\n}];"},"typeVersion":2},{"id":"a1b2c3d4-e5f6-7890-abcd-ef1234567890","name":"Fetch Repo Metadata","type":"n8n-nodes-base.httpRequest","position":[-2160,208],"parameters":{"url":"=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}","options":{"response":{"response":{"neverError":true}}},"sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Accept","value":"application/vnd.github.v3+json"},{"name":"User-Agent","value":"n8n-repo-blueprint"}]},"nodeCredentialType":"githubApi"},"credentials":{"githubApi":{"id":"CONFIGURE_ME","name":"GitHub API"}},"typeVersion":4.4},{"id":"fcdd844d-d327-45b1-b319-6b2fb78da8b6","name":"Fetch Repo Tree","type":"n8n-nodes-base.httpRequest","position":[-1888,208],"parameters":{"url":"=https://api.github.com/repos/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/git/trees/{{ $json.default_branch || 'main' }}?recursive=1","options":{},"sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Accept","value":"application/vnd.github.v3+json"},{"name":"User-Agent","value":"n8n-repo-blueprint"}]},"nodeCredentialType":"githubApi"},"credentials":{"githubApi":{"id":"CONFIGURE_ME","name":"GitHub API"}},"typeVersion":4.4},{"id":"84d7cac3-bcb0-4c99-9778-8382f43a4699","name":"Identify Key Files","type":"n8n-nodes-base.code","position":[-1616,208],"parameters":{"jsCode":"const treeData = $input.first().json;\nconst tree = treeData.tree || [];\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\n\nconst filteredTree = tree.filter(item => {\n  const p = item.path.toLowerCase();\n  return !p.includes('node_modules') &&\n         !p.includes('.git/') &&\n         !p.includes('package-lock.json') &&\n         !p.includes('yarn.lock') &&\n         !p.includes('dist/') &&\n         !p.includes('build/') &&\n         !p.includes('__pycache__') &&\n         !p.includes('.egg-info');\n});\n\nlet fileTreeStr = filteredTree\n  .filter(item => item.type === 'blob')\n  .map(item => item.path)\n  .join('\\n');\nif (fileTreeStr.length > 40000) {\n  fileTreeStr = fileTreeStr.substring(0, 40000) + '\\n... [TREE TRUNCATED]';\n}\n\nconst keyPatterns = [\n  /^main\\.py$/i,\n  /^app\\.py$/i,\n  /^index\\.(js|ts|tsx)$/i,\n  /^server\\.(js|ts)$/i,\n  /^package\\.json$/i,\n  /^requirements\\.txt$/i,\n  /^pyproject\\.toml$/i,\n  /^Cargo\\.toml$/i,\n  /^go\\.mod$/i,\n  /^setup\\.py$/i,\n  /^setup\\.cfg$/i,\n  /^docker-compose\\.ya?ml$/i,\n  /^Dockerfile$/i,\n  /^Makefile$/i,\n  /^config\\/.*\\.(ya?ml|json|toml)$/i,\n  /^src\\/index\\.(js|ts|tsx)$/i,\n  /^src\\/main\\.(py|js|ts|rs)$/i,\n  /^src\\/app\\.(py|js|ts)$/i,\n  /^\\.github\\/workflows\\/.*\\.ya?ml$/i,\n  /^streamlit_app\\.py$/i,\n  /^train.*\\.py$/i,\n  /^model.*\\.py$/i,\n  /^predict.*\\.py$/i,\n  /^Pipfile$/i,\n  /^environment\\.ya?ml$/i\n];\n\nconst keyFiles = filteredTree\n  .filter(item => item.type === 'blob')\n  .filter(item => keyPatterns.some(pattern => pattern.test(item.path)))\n  .map(item => item.path)\n  .slice(0, 12);\n\nconst totalFiles = filteredTree.filter(i => i.type === 'blob').length;\nconst totalDirs = filteredTree.filter(i => i.type === 'tree').length;\n\nif (keyFiles.length === 0) {\n  return [{\n    json: { owner, repo, filePath: null, fileTreeStr, totalFiles, totalDirs }\n  }];\n}\n\nreturn keyFiles.map(filePath => ({\n  json: { owner, repo, filePath, fileTreeStr, totalFiles, totalDirs }\n}));"},"typeVersion":2},{"id":"9ed95dfa-5a0d-4f76-ab11-e8a25f3fb18b","name":"Fetch Key File Contents","type":"n8n-nodes-base.httpRequest","position":[-1344,208],"parameters":{"url":"=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/{{ $json.filePath }}","options":{"response":{"response":{"neverError":true}}},"sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Accept","value":"application/vnd.github.v3+json"},{"name":"User-Agent","value":"n8n-repo-blueprint"}]},"nodeCredentialType":"githubApi"},"credentials":{"githubApi":{"id":"CONFIGURE_ME","name":"GitHub API"}},"typeVersion":4.4},{"id":"076af1fe-6bfe-49ab-8500-cd1b2f3db975","name":"Prepare LLM Input","type":"n8n-nodes-base.code","position":[-1088,208],"parameters":{"jsCode":"const items = $input.all();\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\nconst metadata = $('Fetch Repo Metadata').first().json;\nconst description = metadata.description || '';\nconst topics = (metadata.topics || []).join(', ');\nconst language = metadata.language || '';\nconst fileTreeStr = $('Identify Key Files').first().json.fileTreeStr;\nconst totalFiles = $('Identify Key Files').first().json.totalFiles;\nconst totalDirs = $('Identify Key Files').first().json.totalDirs;\n\nconst fileContents = items\n  .filter(item => item.json.content && item.json.path)\n  .map(item => {\n    try {\n      const decoded = Buffer.from(item.json.content, 'base64').toString('utf-8');\n      const truncated = decoded.length > 3000\n        ? decoded.substring(0, 3000) + '\\n... [TRUNCATED]'\n        : decoded;\n      return `--- FILE: ${item.json.path} ---\\n${truncated}\\n`;\n    } catch(e) {\n      return `--- FILE: ${item.json.path} --- [BINARY/UNREADABLE]\\n`;\n    }\n  })\n  .join('\\n');\n\nconst prompt = `Repository: ${owner}/${repo}\\nDescription: ${description || 'No description provided'}\\nTopics: ${topics || 'None'}\\nPrimary Language: ${language || 'Unknown'}\\nTotal files: ${totalFiles} | Total directories: ${totalDirs}\\n\\n=== FULL FILE TREE ===\\n${fileTreeStr}\\n\\n=== KEY FILE CONTENTS ===\\n${fileContents}`;\n\nreturn [{\n  json: {\n    owner,\n    repo,\n    llmInput: prompt,\n    fileTreeStr,\n    totalFiles,\n    totalDirs\n  }\n}];"},"typeVersion":2},{"id":"b2f94c0e-b70b-4a2a-8cea-2a9863d78ce0","name":"Analyze Architecture","type":"@n8n/n8n-nodes-langchain.chainLlm","position":[-816,208],"parameters":{"text":"={{ $json.llmInput }}","batching":{},"messages":{"messageValues":[{"message":"You are a Senior Software Architect performing a forensic, evidence-only code analysis. You describe ONLY what exists in the repository evidence below. You NEVER speculate or assume.\n\nABSOLUTE RULES — VIOLATION MEANS FAILURE:\n1. ONLY reference technologies found in the file tree or file contents provided.\n2. Check dependency files (requirements.txt, package.json, Cargo.toml, go.mod, pyproject.toml) — list ONLY libraries found there.\n3. No Dockerfile in tree → DO NOT mention Docker.\n4. No .tf files in tree → DO NOT mention Terraform.\n5. No .github/workflows/ in tree → DO NOT mention CI/CD.\n6. Read entry-point files (main.py, app.py, index.js) to understand the project's ACTUAL purpose and domain.\n7. Every claim must trace to a specific file in the evidence.\n\nTOKEN EFFICIENCY: Concise. Bullets over paragraphs. No filler. Every sentence must add information.\n\nMERMAID SYNTAX RULES (violations break rendering):\n1. Node IDs: ONLY alphanumeric (A, B, SVC1). No special chars, spaces, or hyphens.\n2. Labels: ALWAYS in double quotes: A[\"Service\"].\n3. Reserved words (end, graph, subgraph, style, click, class, default): NEVER as node IDs.\n4. Edge labels in double quotes: A -->|\"data\"| B\n5. Every subgraph closes with end on its own line.\n6. Use flowchart TD (NOT graph TD).\n7. No emoji or unicode in Mermaid code.\n\nDark-theme hex styles:\n- Frontend: style ID fill:#1f6feb,stroke:#58a6ff,color:#fff\n- Backend: style ID fill:#238636,stroke:#3fb950,color:#fff\n- Database: style ID fill:#da3633,stroke:#f85149,color:#fff\n- External: style ID fill:#8b949e,stroke:#c9d1d9,color:#fff\n\nUse subgraph blocks to group by layer. Shapes: [\"Service\"] for services, [(\"Database\")] for databases.\n\nOUTPUT FORMAT (strict — nothing outside these sections):\n\n## Project Purpose\n[1-2 sentences: what this project does, with its specific domain, based on code evidence.]\n\n## Technical Stack\n- **Language**: [from file extensions]\n- **Framework**: [from dependency files ONLY]\n- **Key Dependencies**: [from requirements.txt/package.json/etc.]\n- **Infrastructure**: [ONLY if config files exist in tree — omit entire line if none]\n\n## Architecture Blueprint\n```mermaid\nflowchart TD\n[diagram reflecting ACTUAL file structure — subgraphs by layer]\n```\n\n## Request Flow\n```mermaid\nsequenceDiagram\n[based on ACTUAL code paths — min 3 participants]\n```\n\n## Evidence-Based Risks\n1. [Risk traceable to specific file/pattern]\n2. [Risk traceable to specific file/pattern]\n3. [Risk traceable to specific file/pattern]"}]},"promptType":"define"},"typeVersion":1.9},{"id":"ce51847f-7c5f-494f-975b-e8ea545cd50c","name":"Claude 3.5 Sonnet","type":"@n8n/n8n-nodes-langchain.lmChatAnthropic","position":[-816,432],"parameters":{"model":{"__rl":true,"mode":"id","value":"claude-sonnet-4-5-20250929"},"options":{"temperature":0.1,"maxTokensToSample":3000}},"credentials":{"anthropicApi":{"id":"CONFIGURE_ME","name":"Anthropic API"}},"typeVersion":1.3},{"id":"b2c3d4e5-f6a7-8901-bcde-f12345678901","name":"Fix Markdown","type":"n8n-nodes-base.code","position":[-544,208],"parameters":{"jsCode":"const input = $input.first().json;\nlet md = input.text || '';\n\n// Fix: Ensure space after # headers\nmd = md.replace(/^(#{1,6})([^\\s#])/gm, '$1 $2');\n\n// Fix: Ensure blank line before headers\nmd = md.replace(/([^\\n])\\n(#{1,6}\\s)/g, '$1\\n\\n$2');\n\n// Fix: Ensure blank line before code blocks\nmd = md.replace(/([^\\n])\\n```/g, '$1\\n\\n```');\n\n// Fix: Ensure blank line after code blocks\nmd = md.replace(/```\\n([^\\n`])/g, '```\\n\\n$1');\n\n// Fix: Remove trailing whitespace on lines\nmd = md.replace(/[ \\t]+$/gm, '');\n\nreturn [{\n  json: {\n    ...input,\n    text: md\n  }\n}];"},"typeVersion":2},{"id":"18443356-0962-445c-9f53-daf3e95505ed","name":"Generate Dashboard HTML","type":"n8n-nodes-base.code","position":[-272,208],"parameters":{"jsCode":"const analysisOutput = $input.first().json.text || '';\nconst owner = $('Parse Owner and Repo').first().json.owner;\nconst repo = $('Parse Owner and Repo').first().json.repo;\nconst description = $('Fetch Repo Metadata').first().json.description || '';\nconst totalFiles = $('Prepare LLM Input').first().json.totalFiles;\nconst totalDirs = $('Prepare LLM Input').first().json.totalDirs;\nconst defaultBranch = $('Fetch Repo Metadata').first().json.default_branch || 'main';\nconst now = new Date().toISOString().split('T')[0];\n\nconst mermaidBlocks = [];\nconst mermaidRegex = /```mermaid\\n([\\s\\S]*?)```/g;\nlet m;\nwhile ((m = mermaidRegex.exec(analysisOutput)) !== null) {\n  mermaidBlocks.push(m[1].trim());\n}\n\nconst markdown = `# System Blueprint: ${owner}/${repo}\\n\\n> ${description || 'Architecture analysis'}\\n>\\n> Auto-generated on ${now} by Repo-to-Blueprint Architect\\n\\n${analysisOutput.trim()}\\n\\n---\\n\\n## Repository Stats\\n| Metric | Value |\\n|--------|-------|\\n| Total Files | ${totalFiles} |\\n| Total Directories | ${totalDirs} |\\n| Generated | ${now} |\\n| Source | [${owner}/${repo}](https://github.com/${owner}/${repo}) |\\n\\n---\\n\\n*Generated by Repo-to-Blueprint Architect via n8n*\\n`;\n\nconst mermaidPreview = mermaidBlocks.length > 0 ? mermaidBlocks[0].substring(0, 1500) : '[No diagram]';\n\nreturn [{\n  json: {\n    owner,\n    repo,\n    markdownContent: markdown,\n    mermaidCode: mermaidPreview,\n    diagramCount: mermaidBlocks.length,\n    commitMessage: `docs: update system blueprint (${now})`,\n    defaultBranch\n  }\n}];"},"typeVersion":2},{"id":"5301aa8f-fce4-42e8-8334-3339e873dfc3","name":"Fetch Existing README","type":"n8n-nodes-base.httpRequest","position":[0,208],"parameters":{"url":"=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/README_ARCH.md?ref={{ $json.defaultBranch }}","options":{"response":{"response":{"neverError":true}}},"sendHeaders":true,"authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Accept","value":"application/vnd.github.v3+json"},{"name":"User-Agent","value":"n8n-repo-blueprint"}]},"nodeCredentialType":"githubApi"},"credentials":{"githubApi":{"id":"CONFIGURE_ME","name":"GitHub API"}},"typeVersion":4.4},{"id":"f006ed96-6ef9-4bc8-96bb-0fac76993db0","name":"Prepare Push Data","type":"n8n-nodes-base.code","position":[272,208],"parameters":{"jsCode":"const dashData = $('Generate Dashboard HTML').first().json;\nconst existing = $input.first().json;\n\nconst content = Buffer.from(dashData.markdownContent).toString('base64');\n\nconst body = {\n  message: dashData.commitMessage,\n  content: content,\n  branch: dashData.defaultBranch\n};\n\nif (existing.sha) {\n  body.sha = existing.sha;\n}\n\nreturn [{\n  json: {\n    owner: dashData.owner,\n    repo: dashData.repo,\n    pushBodyStr: JSON.stringify(body),\n    isUpdate: !!existing.sha,\n    diagramCount: dashData.diagramCount,\n    mermaidCode: dashData.mermaidCode\n  }\n}];"},"typeVersion":2},{"id":"e5558bb5-6670-4824-864c-696360085f67","name":"Push README_ARCH.md","type":"n8n-nodes-base.httpRequest","position":[544,208],"parameters":{"url":"=https://api.github.com/repos/{{ $json.owner }}/{{ $json.repo }}/contents/README_ARCH.md","method":"PUT","options":{},"jsonBody":"={{ $json.pushBodyStr }}","sendBody":true,"sendHeaders":true,"specifyBody":"json","authentication":"predefinedCredentialType","headerParameters":{"parameters":[{"name":"Accept","value":"application/vnd.github.v3+json"},{"name":"User-Agent","value":"n8n-repo-blueprint"}]},"nodeCredentialType":"githubApi"},"credentials":{"githubApi":{"id":"CONFIGURE_ME","name":"GitHub API"}},"typeVersion":4.4},{"id":"f9b37d10-b08d-4689-9332-c3cdc1e0d2a0","name":"Notify on Update","type":"n8n-nodes-base.slack","position":[816,48],"parameters":{"text":"=:{{ $('Prepare Push Data').first().json.isUpdate ? 'arrows_counterclockwise' : 'blueprint' }}: *System Blueprint {{ $('Prepare Push Data').first().json.isUpdate ? 'Updated' : 'Created' }}*\n\n*Repository:* <https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}|{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}>\n*Blueprint:* <https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/blob/{{ $('Generate Dashboard HTML').first().json.defaultBranch }}/README_ARCH.md|View README_ARCH.md>\n*Diagrams:* {{ $('Prepare Push Data').first().json.diagramCount }} generated\n*Stats:* {{ $('Prepare LLM Input').first().json.totalFiles }} files | {{ $('Prepare LLM Input').first().json.totalDirs }} dirs\n\n```{{ $('Prepare Push Data').first().json.mermaidCode }}```","select":"channel","resource":"message","channelId":{"__rl":true,"mode":"list","value":""},"operation":"post","otherOptions":{}},"credentials":{"slackApi":{"id":"CONFIGURE_ME","name":"Slack Bot Token"}},"typeVersion":2.4,"continueOnFail":true},{"id":"8e995431-419c-4d45-b349-368f72ec21c7","name":"Send Success Page","type":"n8n-nodes-base.respondToWebhook","position":[1088,48],"parameters":{"options":{"responseCode":200,"responseHeaders":{"entries":[{"name":"Content-Type","value":"text/html; charset=utf-8"}]}},"respondWith":"text","responseBody":"=<!DOCTYPE html><html lang='en'><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Blueprint Generated</title><style>*{margin:0;padding:0;box-sizing:border-box}body{font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#0d1117;color:#c9d1d9;display:flex;align-items:center;justify-content:center;min-height:100vh}.card{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:3rem;max-width:520px;text-align:center;box-shadow:0 8px 32px rgba(0,0,0,.4)}h1{color:#58a6ff;font-size:1.8rem;margin-bottom:1rem}.icon{font-size:3.5rem;margin-bottom:1rem}p{margin:.7rem 0;color:#8b949e;line-height:1.6}.repo{color:#c9d1d9;font-weight:600}.btn{display:inline-block;background:#238636;color:#fff;padding:.75rem 2rem;border-radius:8px;margin-top:1.5rem;font-size:1rem;text-decoration:none;transition:background .2s}.btn:hover{background:#2ea043}.footer{margin-top:2rem;font-size:.75rem;color:#484f58}</style></head><body><div class='card'><div class='icon'>&#9989;</div><h1>Blueprint Generated!</h1><p>Architecture analysis complete for<br><span class='repo'>{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}</span></p><p>{{ $('Prepare Push Data').first().json.diagramCount }} diagram(s) generated and pushed.</p><a class='btn' href='https://github.com/{{ $('Parse Owner and Repo').first().json.owner }}/{{ $('Parse Owner and Repo').first().json.repo }}/blob/{{ $('Generate Dashboard HTML').first().json.defaultBranch }}/README_ARCH.md' target='_blank'>View README_ARCH.md &#8594;</a><div class='footer'>Powered by Repo-to-Blueprint Architect</div></div></body></html>"},"typeVersion":1.5},{"id":"s0000000-0000-0000-0000-000000000000","name":"Sticky Note - Setup","type":"n8n-nodes-base.stickyNote","position":[-2784,-384],"parameters":{"width":3960,"height":416,"content":"## How it works\n\nThis workflow analyzes any public GitHub repository and generates an evidence-based architecture blueprint with Mermaid.js diagrams.\n\n1. A GitHub URL is submitted via the web form or webhook API\n2. The workflow fetches repository metadata, the full file tree, and contents of key files (package.json, main.py, Dockerfiles, etc.)\n3. Claude AI (Sonnet 4.5, temperature 0.1) analyzes ONLY the evidence — strict anti-hallucination rules prevent it from inventing technologies not found in the code\n4. A Markdown blueprint with architecture diagrams and risk analysis is assembled, validated, and pushed as `README_ARCH.md` to the repository\n5. A Slack notification is sent and the form user receives a styled success page\n\n## Setup steps\n\n1. **GitHub API** — Create a Personal Access Token with `repo` scope. Add as \"GitHub API\" credential\n2. **Anthropic API** — Get an API key from console.anthropic.com. Add as \"Anthropic API\" credential\n3. **Slack** *(optional)* — Create a Slack Bot Token with `chat:write` scope. Add as \"Slack API\" credential and update the channel ID in the Notify node\n4. **Activate** — Toggle the workflow active. Use the Form URL in your browser or POST `{\"github_url\": \"https://github.com/owner/repo\"}` to the webhook"},"typeVersion":1},{"id":"s1000001-0000-0000-0000-000000000001","name":"Sticky Note - Input","type":"n8n-nodes-base.stickyNote","position":[-2816,80],"parameters":{"color":6,"width":580,"height":560,"content":"## Input\nTwo entry points: web form for browser users, webhook POST for API calls. Both feed into the URL parser."},"typeVersion":1},{"id":"s1000002-0000-0000-0000-000000000002","name":"Sticky Note - Evidence","type":"n8n-nodes-base.stickyNote","position":[-2208,80],"parameters":{"color":6,"width":1292,"height":320,"content":"## Evidence gathering\nFetches repo metadata, file tree, and key file contents. This evidence is the only input to the AI."},"typeVersion":1},{"id":"s1000003-0000-0000-0000-000000000003","name":"Sticky Note - AI","type":"n8n-nodes-base.stickyNote","position":[-896,80],"parameters":{"color":6,"width":588,"height":500,"content":"## AI analysis\nClaude Sonnet 4.5 analyzes only what exists in the code. Anti-hallucination rules enforced. Markdown auto-fixed."},"typeVersion":1},{"id":"s1000004-0000-0000-0000-000000000004","name":"Sticky Note - Delivery","type":"n8n-nodes-base.stickyNote","position":[-288,48],"parameters":{"color":6,"width":1560,"height":352,"content":"## Delivery\nAssembles blueprint, pushes to repo, notifies Slack, and returns a success page."},"typeVersion":1}],"settings":{"executionOrder":"v1","saveExecutionProgress":true,"saveDataErrorExecution":"all","saveDataSuccessExecution":"all"},"connections":{"Fix Markdown":{"main":[[{"node":"Generate Dashboard HTML","type":"main","index":0}]]},"Blueprint Form":{"main":[[{"node":"Parse Owner and Repo","type":"main","index":0}]]},"Fetch Repo Tree":{"main":[[{"node":"Identify Key Files","type":"main","index":0}]]},"Notify on Update":{"main":[[{"node":"Send Success Page","type":"main","index":0}]]},"Claude 3.5 Sonnet":{"ai_languageModel":[[{"node":"Analyze Architecture","type":"ai_languageModel","index":0}]]},"Prepare LLM Input":{"main":[[{"node":"Analyze Architecture","type":"main","index":0}]]},"Prepare Push Data":{"main":[[{"node":"Push README_ARCH.md","type":"main","index":0}]]},"Identify Key Files":{"main":[[{"node":"Fetch Key File Contents","type":"main","index":0}]]},"Receive GitHub URL":{"main":[[{"node":"Parse Owner and Repo","type":"main","index":0}]]},"Fetch Repo Metadata":{"main":[[{"node":"Fetch Repo Tree","type":"main","index":0}]]},"Push README_ARCH.md":{"main":[[{"node":"Notify on Update","type":"main","index":0}]]},"Analyze Architecture":{"main":[[{"node":"Fix Markdown","type":"main","index":0}]]},"Parse Owner and Repo":{"main":[[{"node":"Fetch Repo Metadata","type":"main","index":0}]]},"Fetch Existing README":{"main":[[{"node":"Prepare Push Data","type":"main","index":0}]]},"Fetch Key File Contents":{"main":[[{"node":"Prepare LLM Input","type":"main","index":0}]]},"Generate Dashboard HTML":{"main":[[{"node":"Fetch Existing README","type":"main","index":0}]]}}}