CodeBoarding is an early-stage project, and we love contributors! ❤️
- Check existing issues or open a new one to discuss your idea.
- Small, focused changes are preferred.
- Be kind and constructive in discussions (Discord welcome).
- Bug fixes
- Features and enhancements
- Language support and static analysis improvements
- Docs and examples
- Performance and stability (LLM prompting mostly)
- Naming: variables use
snake_case; classes usePascalCase. - Formatting: We use Black formatter (line length: 120).
- Add type hints if possible.
For active contributors who want to modify the code:
# Install with dev dependencies (includes Black formatter and pre-commit)
uv sync --dev
# Activate virtual environment
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Run setup (this will automatically install pre-commit hooks if available)
python setup.pyThe pre-commit hooks will automatically format your code with Black before each commit.
For regular users who just want to run the analysis, use uv sync --frozen instead (see README).
Adding language support requires changes across several files. Use PR #276 (Rust support) as a reference.
| File | What to add |
|---|---|
static_analyzer/engine/adapters/<lang>_adapter.py |
New file. Adapter class extending LanguageAdapter. Handles language-specific qualified name construction, reference keys, and any special rules (e.g. mod.rs collapsing for Rust). |
static_analyzer/engine/adapters/__init__.py |
Import the adapter and add it to ADAPTER_REGISTRY. |
static_analyzer/constants.py |
Add a value to the Language enum. Qualified names use the universal . delimiter defined in ClusteringConfig.QUALIFIED_NAME_DELIMITER. |
static_analyzer/__init__.py |
Add a mapping in _lang_to_adapter_name() from the ProgrammingLanguage name to the adapter registry key. |
vscode_constants.py |
Add an LSP server config entry to VSCODE_CONFIG["lsp_servers"] with the server name, command, languages, file extensions, and install command. |
tool_registry/registry.py |
Add a ToolDependency entry to TOOL_REGISTRY (see below). |
The LSP server must be registered in tool_registry/registry.py so it gets installed automatically. The ToolDependency entry depends on how the server is distributed:
npm package (e.g. pyright, typescript-language-server) — no pipeline update needed:
ToolDependency(
key="python",
binary_name="pyright-langserver",
kind=ToolKind.NODE,
config_section=ConfigSection.LSP_SERVERS,
npm_packages=["pyright@1.1.400"],
js_entry_file="langserver.index.js",
js_entry_parent="pyright",
)Upstream download (e.g. jdtls from Eclipse) — downloaded directly, no pipeline:
ToolDependency(
key="java",
binary_name="java",
kind=ToolKind.ARCHIVE,
config_section=ConfigSection.LSP_SERVERS,
source=UpstreamToolSource(
tag=JDTLS_VERSION,
url_template=JDTLS_URL_TEMPLATE,
build=JDTLS_BUILD,
),
archive_subdir="jdtls",
)Built from source (e.g. gopls, tokei) — no upstream binaries, needs pipeline:
ToolDependency(
key="go",
binary_name="gopls",
kind=ToolKind.NATIVE,
config_section=ConfigSection.LSP_SERVERS,
source=GitHubToolSource(
tag=TOOLS_TAG,
repo=TOOLS_REPO,
asset_template="gopls-{platform_suffix}",
sha256={...},
),
)If the LSP server doesn't publish pre-built binaries (like gopls or tokei), you need to update .github/workflows/build-tools.yml to build it from source. The workflow is manually triggered and publishes binaries to the CodeBoarding/tools repo:
- Add a new
build-<tool>job tobuild-tools.ymlwith the appropriate toolchain (Go, Rust, etc.) - Add the tool version as a top-level
env:variable - Add the new artifacts to the
publish-releasejob - Run the workflow, then copy the SHA256 hashes from the output into your
ToolDependency
- Write unit tests for the adapter (aim for 100% coverage on new code)
- Run
uv run pytest --ignore=tests/integrationto verify nothing is broken - Run
uv run mypy .anduv run black . --check - Add integration test fixtures:
- Edge cases (
tests/integration/fixtures/edge_cases/<lang>_edge_cases.json): A hand-crafted small project that exercises language-specific features (interfaces, generics, inheritance, etc.). Listsexpected_referencesthat the static analysis must find. Seego_edge_cases.jsonorpython_edge_cases.jsonfor the format. - Real project (
tests/integration/fixtures/real_projects/<project>_<lang>.json): A well-known open-source repo pinned to a specific commit, with expected metric counts (references, packages, call graph nodes/edges, source files). Seeprometheus_go.jsonormockito_java.jsonfor the format.
- Edge cases (
- Fork the repo.
- Create a branch:
feat/...,fix/..., ordocs/.... - In the PR, explain WHAT/WHY/HOW: what changed, why it's useful, and how you tested it.
- Optional: add a picture of a diagram from your favorite project.