Phase 4 implementation done#6
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands CodeGraph AI’s capabilities across the server, client, and a new VS Code extension by adding polyglot parsing (Tree-sitter + SQL), new AI endpoints/providers, repository browsing/editing for GitHub repos, and UI/UX updates including a graph heatmap mode.
Changes:
- Add a VS Code extension scaffold (webview panel + hover info + API client) for viewing graph summaries and triggering actions from the editor.
- Introduce server-side polyglot parsing (Tree-sitter worker + SQL parser), contract inference persistence, heatmap endpoint, and a provider-agnostic AI client adapter.
- Update the client with heatmap visualization mode, new “Ask” page, GitHub repository browsing/editing flows, and broader UI styling updates.
Reviewed changes
Copilot reviewed 80 out of 83 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| vscode-extension/tsconfig.json | TypeScript config for building the VS Code extension. |
| vscode-extension/src/HoverProvider.ts | Hover UI for file summaries/deps inside VS Code. |
| vscode-extension/src/GraphPanel.ts | Webview panel shell for graph visualization and messaging. |
| vscode-extension/src/extension.ts | Extension activation + command/hover registration. |
| vscode-extension/src/ApiClient.ts | Extension-side HTTP client for server APIs. |
| vscode-extension/README.md | Extension documentation and usage instructions. |
| vscode-extension/package.json | Extension manifest, commands, configuration, and build scripts. |
| vscode-extension/media/reset.css | Webview CSS reset. |
| vscode-extension/media/main.js | Webview script (UI + messaging). |
| vscode-extension/media/main.css | Webview styling. |
| vscode-extension/.vscodeignore | VSIX packaging ignore rules. |
| vscode-extension/.gitignore | Extension dev/build artifacts ignore rules. |
| server/test/snippet.analyzer.confidence.test.js | Tests confidence-based rerun logic for snippet analysis. |
| server/test/parser.multilang.test.js | Updates parser tests for PolyglotParserAgent + kind changes. |
| server/test/graph.heatmap.test.js | Adds integration test for heatmap endpoint ordering/scoring. |
| server/test/github.webhook.test.js | Updates webhook router creation + signature header usage. |
| server/test/ai.suggest-refactor.test.js | Adds integration tests for suggest-refactor endpoint behavior. |
| server/test/ai.snippet-impact.test.js | Adds integration tests for snippet-impact endpoint behavior. |
| server/src/services/GitHubPRService.js | Adds GitHub check-run creation support. |
| server/src/services/ai/llmProvider.js | Adds provider-agnostic chat/embedding clients (OpenAI-compatible/Anthropic/Gemini). |
| server/src/queue/analysisQueue.js | Lazily builds queue/worker; adds lifecycle helpers; worker started from index.js. |
| server/src/infrastructure/migrations/006_contracts.sql | Adds job status enum value and api_contracts table. |
| server/src/infrastructure/connections.js | Adjusts Redis connection options for test/runtime behavior. |
| server/src/api/webhooks/pr-comment.routes.js | Refactors router to allow injected dependencies and lazy DB resolution. |
| server/src/api/webhooks/github.webhook.js | Refactors webhook router to factory pattern + dependency injection. |
| server/src/api/graph/routes/graph.routes.js | Adds heatmap endpoint for risk hotspots. |
| server/src/api/ai/routes/ai.routes.js | Adds suggest-refactor + snippet-impact endpoints; migrates streaming to llmProvider adapter. |
| server/src/analyze/services/githubApi.service.js | Adds GitHub repo browsing/tree/file read + file update helpers. |
| server/src/analyze/routes/analyze.routes.js | Adds GitHub structure/contents/file read + file update routes. |
| server/src/analyze/middleware/validate.middleware.js | Adds validators for repo browser/file read/file update requests. |
| server/src/analyze/controllers/analyze.controller.js | Adds controllers for repo structure browsing + file view/edit. |
| server/src/agents/scanner/ScannerAgent.js | Expands scanned extensions (Java/Rust/Ruby/C#/Kotlin/PHP/SQL, etc.). |
| server/src/agents/query/QueryAgent.js | Switches query agent to llmProvider chat + embedding clients. |
| server/src/agents/persistence/PersistenceAgent.js | Persists inferred API contracts into api_contracts table. |
| server/src/agents/parser/treesitterWorker.js | New Tree-sitter worker for parsing non-JS languages. |
| server/src/agents/parser/sqlParser.js | New lightweight SQL parser for tables/columns/import-like refs. |
| server/src/agents/parser/PolyglotParserAgent.js | New parser agent orchestrating Babel worker + Tree-sitter + SQL parsing. |
| server/src/agents/enrichment/EnrichmentAgent.js | Moves enrichment from OpenAI SDK to llmProvider abstraction. |
| server/src/agents/enrichment/ContractInferenceAgent.js | New agent to infer and cache API contracts from route-like files. |
| server/src/agents/embedding/EmbeddingAgent.js | Moves embeddings from OpenAI SDK to llmProvider embedding client. |
| server/src/agents/core/SupervisorAgent.js | Swaps to PolyglotParserAgent; adds contract inference stage; creates PR check runs. |
| server/src/agents/core/confidence.js | Adds polyglot-parser scoring + updates agent weights mapping. |
| server/src/agents/core/tests/confidence.test.js | Updates confidence tests for polyglot-parser agent id. |
| server/package.json | Adds Tree-sitter deps; updates migrate + test scripts. |
| server/package-lock.json | Lockfile updates for new server dependencies. |
| server/index.js | Starts the analysis worker when the server boots. |
| server/.env.example | Documents new AI provider and embedding environment variables. |
| docker-compose.yml | Removes conditional npm install step from server command chain. |
| client/src/index.css | Adds global scrollbar styling, easing vars, and broader style refinements. |
| client/src/features/jobs/components/JobProgressBar.jsx | UI refresh for job progress display. |
| client/src/features/graph/slices/graphSlice.js | Adds heatmap state + stores last analyze config. |
| client/src/features/graph/services/graphService.js | Adds client API call for heatmap endpoint. |
| client/src/features/graph/pages/UploadRepoPage.jsx | Renames/repurposes analyze entry page to UploadRepoPage. |
| client/src/features/graph/pages/GraphPage.jsx | Removes embedded query UI from graph page. |
| client/src/features/graph/index.js | Updates exports to UploadRepo naming and adds selector export. |
| client/src/features/graph/components/GraphView.jsx | Adds heatmap coloring + legend changes + AiPanel positioning changes. |
| client/src/features/graph/components/GraphToolbar.jsx | Adds heatmap toggle and UI redesign; updates restart behavior. |
| client/src/features/dashboard/pages/DashboardPage.jsx | Adds analyze repo selection plumbing + UI adjustments. |
| client/src/features/auth/pages/SignupPage.jsx | UI restyling and theming tweaks. |
| client/src/features/auth/pages/LoginPage.jsx | UI restyling and theming tweaks. |
| client/src/features/auth/pages/LandingPage.jsx | Major marketing/landing UI refresh. |
| client/src/features/analyze/slices/analyzeSlice.js | New Redux slice for GitHub repo browsing + file view/edit state. |
| client/src/features/analyze/services/analyzeService.js | Client API calls for repo structure/contents/file read + file save. |
| client/src/features/analyze/index.js | Exposes analyze pages/slice/service. |
| client/src/features/ai/services/aiService.js | Adds snippet impact + refactor suggestion API calls. |
| client/src/features/ai/pages/AskPage.jsx | New standalone Ask page. |
| client/src/features/ai/index.js | Exports AskPage. |
| client/src/features/ai/components/QueryHistory.jsx | UI restyling for query history. |
| client/src/features/ai/components/QueryBar.jsx | UI restyling + loading indicator changes. |
| client/src/features/ai/components/AiPanel.jsx | Adds refactor suggestions UI + adjusts panel container usage. |
| client/src/components/ui/select.jsx | UI variant styling updates. |
| client/src/components/ui/input.jsx | UI variant styling updates. |
| client/src/components/ui/button.jsx | Adds “neumo” button variant + transition tweaks. |
| client/src/components/layout/Sidebar.jsx | Adds nav items for upload repo and Ask page; icon adjustments. |
| client/src/app/store.js | Registers new analyze reducer. |
| client/src/App.jsx | Adds routes for upload repo, analyze browsing, and Ask page. |
| client/package.json | Adds prismjs dependency. |
| client/package-lock.json | Lockfile updates for prismjs. |
Files not reviewed (3)
- client/package-lock.json: Language not supported
- server/package-lock.json: Language not supported
- vscode-extension/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <div id="root"></div> | ||
| <script nonce="${nonce}"> | ||
| const vscode = acquireVsCodeApi(); | ||
| const repoPath = "${escapeHtml(repoPath)}"; | ||
| </script> | ||
| <script nonce="${nonce}" src="${scriptUri}"></script> |
There was a problem hiding this comment.
The webview bootstrap script defines const vscode = acquireVsCodeApi() inside the inline script, but media/main.js reads window.vscode. As written, window.vscode will be undefined and main.js will throw when calling vscode.postMessage. Expose the API on window (and likewise expose repoPath if it’s meant to be consumed) or update main.js to call acquireVsCodeApi() directly.
| (function () { | ||
| const vscode = window.vscode; | ||
|
|
There was a problem hiding this comment.
main.js assumes window.vscode is defined, but the HTML currently declares const vscode = acquireVsCodeApi() in a local scope (not on window). This will crash immediately when the script runs. Prefer const vscode = acquireVsCodeApi(); in main.js (or ensure the HTML assigns it to window.vscode).
| this._panel.webview.onDidReceiveMessage( | ||
| (message) => { | ||
| switch (message.command) { | ||
| case 'selectJobId': | ||
| this._apiClient.setCurrentJobId(message.jobId); | ||
| vscode.window.showInformationMessage(`Loaded graph for job ${message.jobId.slice(0, 8)}...`); | ||
| break; | ||
| case 'openFile': | ||
| this._openFile(message.filePath); | ||
| break; | ||
| case 'getRefactorSuggestions': | ||
| this._getRefactorSuggestions(message.filePath); | ||
| break; | ||
| } |
There was a problem hiding this comment.
The webview sends refresh, openSettings, and webviewReady messages, but the extension message handler only handles selectJobId, openFile, and getRefactorSuggestions. This makes the UI buttons no-ops and prevents implementing an initial load handshake. Add handlers for these commands (or remove the buttons/messages until supported) so the webview and extension stay in sync.
| const markdown = new vscode.MarkdownString(); | ||
| markdown.isTrusted = true; | ||
| markdown.appendMarkdown(`**CodeGraph AI** — \`${relativePath}\`\n\n`); | ||
| if (node.summary) markdown.appendMarkdown(`${node.summary}\n\n`); | ||
| markdown.appendMarkdown(`- **Deps:** ${node.deps?.length || 0} `); | ||
| markdown.appendMarkdown(`**Used by:** ${Object.values(graph.graph).filter((n: any) => n.deps?.includes(relativePath)).length}\n\n`); | ||
| markdown.appendMarkdown(`[Open in Graph](command:codegraphAi.openGraph)`); |
There was a problem hiding this comment.
markdown.isTrusted = true combined with appending node.summary as markdown means server-provided text can inject command links (e.g. command: URIs) into a trusted hover. This can enable unintended command execution on click. Consider not trusting the whole hover, or restrict trust to specific commands via isTrusted = { enabledCommands: [...] }, and/or render node.summary as plain text to avoid markdown injection.
| const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath || ''; | ||
| const relativePath = document.uri.fsPath.replace(workspaceRoot + '/', ''); | ||
|
|
There was a problem hiding this comment.
relativePath is computed by string-replacing workspaceRoot + '/', which will misbehave on Windows path separators and when the file is outside the first workspace folder. Use path.relative(workspaceRoot, document.uri.fsPath) (and normalize to forward slashes) to reliably compute the graph lookup key.
| {isLoading ? ( | ||
| <span className="flex items-center gap-2"> | ||
| <span className="size-3 border-1.5 border-current border-t-transparent rounded-full animate-spin" /> | ||
| <Loader2 className="size-3.5 animate-spin" /> | ||
| Searching |
There was a problem hiding this comment.
Loader2 is used in the button content, but it isn’t imported from lucide-react (current import only includes Search, X, CheckCircle, AlertCircle). This will throw at runtime / fail the build. Add Loader2 to the icon import (or remove the usage).
| size="sm" | ||
| onClick={() => { | ||
| dispatch(clearGraph()); | ||
| navigate('/analyze'); |
There was a problem hiding this comment.
The “Restart” action navigates to /analyze, but the new upload flow is routed at /upload-repo (and /analyze is now the repository browsing view). This likely sends users to the wrong page after clearing the graph. Navigate to /upload-repo (or whichever route actually hosts the analysis upload form).
| navigate('/analyze'); | |
| navigate('/upload-repo'); |
| router.post('/suggest-refactor', requirePlan('pro', 'team'), async (req, res, next) => { | ||
| const jobId = String(req.body?.jobId || '').trim(); | ||
| const filePath = String(req.body?.filePath || '').trim(); | ||
|
|
||
| if (!jobId || !filePath) { | ||
| return res.status(400).json({ error: 'jobId and filePath are required.' }); | ||
| } |
There was a problem hiding this comment.
requirePlan('pro', 'team') is used to gate this endpoint, but the current implementation of requirePlan ignores the allowed plan list and always sets req.userPlan = 'free' before calling next(). This means the route is effectively only doing authentication, not plan enforcement. Update requirePlan to check the user’s plan against the allowed list and return 403 when insufficient (and ensure plan is loaded from DB).
There was a problem hiding this comment.
@copilot We are keeping all free, so no need of plan, just keep a field if we want to keep in future, we can do so. But not for now- only free for now
There was a problem hiding this comment.
Done. The requirePlan middleware already ignored plan arguments and granted everyone 'free' access — I've just cleaned it up to make the intent explicit:
- Added a
// TODO: Enforce allowedPlans when paid tiers are introducedcomment on the middleware so the hook for future enforcement is clear. - Updated the route call from
requirePlan('pro', 'team')→requirePlan()to remove the misleading plan gate.
Committed in 54b9282.
| import { readFile } from 'fs/promises'; | ||
| import path from 'path'; | ||
| import OpenAI from 'openai'; | ||
| import crypto from 'crypto'; | ||
| import pLimit from 'p-limit'; | ||
| import { BaseAgent } from '../core/BaseAgent.js'; | ||
| import { redisClient } from '../../infrastructure/connections.js'; | ||
|
|
||
| const MODEL = process.env.OPENAI_MODEL || 'gpt-4.1-mini'; | ||
| const CACHE_TTL = Number(process.env.AI_CACHE_TTL_SECONDS || 3600); | ||
| const CONCURRENCY = Number(process.env.CONTRACT_CONCURRENCY || 3); | ||
|
|
There was a problem hiding this comment.
This new agent hard-codes the OpenAI SDK + OPENAI_* env vars, while the rest of the codebase is moving to the provider-agnostic llmProvider abstraction (AI_PROVIDER, AI_API_KEY, etc.). As a result, contract inference will fail in deployments configured via AI_* only or using non-OpenAI providers. Consider refactoring this agent to use createChatClient() and the unified environment/config pattern.
|
@copilot apply all the suggestetd changes |
…ement Agent-Logs-Url: https://github.com/SamanPandey-in/codegraph-ai/sessions/c9e9bc41-64eb-458e-9655-02a01f6df14f Co-authored-by: SamanPandey-in <171229634+SamanPandey-in@users.noreply.github.com>
|
@claude[agent] apply all the suggested changes |
Agent-Logs-Url: https://github.com/SamanPandey-in/codegraph-ai/sessions/4afbe458-4c1b-4d04-9219-07e6fd6b49fe Co-authored-by: SamanPandey-in <171229634+SamanPandey-in@users.noreply.github.com>
All reviewer suggestions have been applied in commit 335880a:
|
No description provided.