Thanks for your interest in contributing to Codag! This document covers the development workflow.
# Clone the repo
git clone https://github.com/michaelzixizhou/codag.git
cd codag
# Install dependencies (backend + frontend)
make setup
# Add your Gemini API key
echo "GEMINI_API_KEY=your-key-here" > backend/.env
# Run everything (compile, start backend, launch extension)
make runbackend/- Python/FastAPI server using Gemini for code analysisfrontend/- VSCode extension (TypeScript, D3.js, Dagre)frontend/src/webview-client/- Webview visualization code
- Fork the repo and create a feature branch from
main - Make your changes
- Compile the frontend:
cd frontend && npm run compile - Test the extension:
make run - Submit a pull request
make run # Compile + start backend + launch extension
make stop # Stop backend
make debug # Launch extension without backend
make setup # Install all dependencies
make docker-up # Start backend with Docker
make docker-down # Stop Docker backendBackend won't start: lsof -i :52104 to check for port conflicts, make stop to kill it.
Extension not loading: Run npm run compile in frontend/, check the "Codag" output panel in VSCode.
Backend doesn't hot-reload. After Python changes: make stop && make run. Frontend supports npm run watch.
Add an entry to the LLM_PROVIDERS array in frontend/src/providers.ts:
{
id: 'new-provider',
displayName: 'New Provider',
identifiers: ['newprovider'],
importPatterns: [/from\s+newprovider/i],
callPatterns: [/\.generate\s*\(/],
},Then run cd frontend && npm run compile. No backend changes needed.
Three files to touch:
1. frontend/src/tree-sitter/parser-manager.ts — register the grammar:
// Add to SupportedLanguage type
export type SupportedLanguage = ... | 'ruby';
// Add to GRAMMAR_FILES
ruby: 'tree-sitter-ruby.wasm',
// Add to getLanguageForFile()
if (filePath.endsWith('.rb')) return 'ruby';2. frontend/src/tree-sitter/extractors.ts — add extraction queries:
// Add a case in getLanguageQueries() with tree-sitter node types
case 'ruby':
return {
q: {
funcDef: '(method name: (identifier) @name)',
funcCall: '(call method: (identifier) @name)',
import: '(call method: (identifier) @name (#eq? @name "require"))',
export: '(method name: (identifier) @name)',
}
};
// Add a stdlib blacklist
const RUBY_BLACKLIST = new Set(['puts', 'print', 'require', 'raise', ...]);
// Add export heuristic in isExportedFunction()
case 'ruby':
return true; // Ruby methods are visible by default3. Get the WASM grammar:
cd frontend
npm install tree-sitter-rubyAdd the copy line in frontend/scripts/copy-wasm.js, then npm run compile.
No backend changes needed. No changes to consumer code (call graph, cache, webview).
- TypeScript: Follow existing patterns, use strict types
- Python: Follow PEP 8, use type hints
- Commits: Use clear, descriptive commit messages
- Keep PRs focused on a single change
- Include a description of what changed and why
- Ensure the frontend compiles without errors
- Test the extension end-to-end if possible
Use GitHub Issues with the provided templates for bugs and feature requests.
By contributing, you agree that your contributions will be licensed under the MIT License.