From 6e7a1d2ce1980dc5565a07c56fa4a5acb96109e4 Mon Sep 17 00:00:00 2001 From: yangming Date: Thu, 22 Oct 2026 19:15:35 +0800 Subject: [PATCH] docs: add CONTRIBUTING.md, rebase on latest main - Add CONTRIBUTING.md covering setup, architecture, testing, PR workflow - README.md: add Contributing section with link to CONTRIBUTING.md - AGENTS.md: add house-rule pointer to CONTRIBUTING.md and /add-lang skill - Reference /add-lang skill (on main) instead of docs/ADDING-A-LANGUAGE.md (from closed PR #97, never landed on main) - Update installer target list to 11 (added Copilot variants) - Note server-instructions.ts as single source of truth (issue #529) - Add CHANGELOG format guidance (### New Features / ### Fixes) Addresses feedback from @Yisus423 on PR #665. --- AGENTS.md | 1 + CONTRIBUTING.md | 280 ++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 6 ++ 3 files changed, 287 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/AGENTS.md b/AGENTS.md index 77e5ed7c1c..9b2e31059a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -288,3 +288,4 @@ publish actions on shared state. Write the files, hand the user the commands. - The **current branch's tip** — your own unmerged work obviously can't be what the comment is reacting to. Always disambiguate "released," "merged-but-unreleased," and "in-progress" before agreeing that a user-reported problem is unfixed (or that a fix is incomplete). A user saying "your fix only covers X" about a recent PR is usually pointing at the *released* shortcomings — your in-flight branch may already address them but they have no way to know that. - **Version-tag every image referenced in `README.md`.** GitHub caches README images (`raw.githubusercontent.com` with a 5-minute TTL; third-party hosts sit behind the long-lived camo proxy), so updating an asset in place can keep showing the stale version. Give each README image URL a `?v=N` query tag and **bump `N` in the same commit whenever the asset bytes change** — e.g. `assets/waitlist.svg?v=2`. The changed URL sidesteps every cache so the new image shows immediately instead of waiting on a TTL to expire. +- For contributor-facing guidance (PR workflow, commit conventions), see `CONTRIBUTING.md`. To add a new language, use the `/add-lang` skill (`.claude/skills/add-lang/SKILL.md`). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..504521febb --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,280 @@ +# Contributing to CodeGraph + +Thanks for your interest in contributing! This guide covers everything you need to +get started. + +## Table of Contents + +- [Code of Conduct](#code-of-conduct) +- [Getting Started](#getting-started) +- [Development Setup](#development-setup) +- [Project Architecture](#project-architecture) +- [Making Changes](#making-changes) +- [Adding a New Language](#adding-a-new-language) +- [Testing](#testing) +- [Commit Messages](#commit-messages) +- [Pull Requests](#pull-requests) +- [Reporting Issues](#reporting-issues) + +--- + +## Code of Conduct + +Be respectful and constructive. We're all here to build something useful. + +## Getting Started + +### Prerequisites + +- **Node.js** >= 20.0.0, < 25.0.0 (Node 25.x has a V8 WASM JIT bug — see + [#81](https://github.com/colbymchenry/codegraph/issues/81)) +- **npm** (ships with Node) +- **Git** + +### Fork and Clone + +```bash +# Fork via GitHub UI, then: +git clone https://github.com//codegraph.git +cd codegraph +git remote add upstream https://github.com/colbymchenry/codegraph.git +``` + +### Install and Verify + +```bash +npm install +npm run build +npm test +``` + +If all tests pass, you're ready to go. + +## Development Setup + +### Useful Commands + +| Command | What it does | +|---|---| +| `npm run build` | Compile TypeScript + copy assets into `dist/` | +| `npm run dev` | Watch mode — rebuilds on file change | +| `npm run clean` | Remove `dist/` | +| `npm test` | Run the full test suite (vitest) | +| `npm run test:watch` | Run tests in watch mode | +| `npm run cli` | Build then run the local CLI binary | + +### Running a Single Test + +```bash +npx vitest run __tests__/extraction.test.ts -t "Groovy" +``` + +### Project Structure + +``` +src/ +├── index.ts # Public API (CodeGraph class) +├── types.ts # Core type definitions (NodeKind, EdgeKind, Language) +├── db/ # SQLite database layer (schema, queries) +├── extraction/ # Tree-sitter parsing and per-language extractors +│ ├── index.ts # ExtractionOrchestrator — drives the pipeline +│ ├── tree-sitter.ts # Core tree-sitter extraction engine +│ ├── grammars.ts # Grammar loading + extension-to-language map +│ ├── languages/ # One file per language (python.ts, go.ts, ...) +│ ├── parse-worker.ts # Heavy parsing off the main thread +│ ├── *-extractor.ts # Standalone extractors for non-tree-sitter formats +│ │ # (svelte, vue, astro, liquid, dfm, razor, ...) +│ └── wasm/ # Vendored grammar .wasm files +├── resolution/ # Cross-file reference resolution +│ └── frameworks/ # Framework-specific resolvers (Express, Django, ...) +├── graph/ # Graph traversal (BFS/DFS, impact radius) +├── context/ # Context building for AI consumption +├── mcp/ # MCP server (tools, transport, daemon, session) +├── installer/ # Multi-agent installer (11 targets — see below) +├── search/ # FTS5 query parsing +├── sync/ # File watcher and git hooks +└── bin/ # CLI entry point +__tests__/ # Tests mirror the module they cover +docs/ # Design docs, benchmarks, cookbooks +``` + +## Making Changes + +### Branching + +Always branch off `upstream/main`: + +```bash +git checkout -b feat/my-feature upstream/main +``` + +Use descriptive branch names: `feat/`, `fix/`, `docs/`, `refactor/`. + +### What to Edit + +- **Types** (`src/types.ts`): `NodeKind`, `EdgeKind`, and `Language` are + runtime-iterable `const` arrays. Changing them affects the entire pipeline. +- **Extractors** (`src/extraction/languages/`): Each language has its own file + exporting a `LanguageExtractor` config. See + [Adding a New Language](#adding-a-new-language). +- **MCP tools** (`src/mcp/`): `server-instructions.ts` is the **single source + of truth** for agent-facing tool guidance — edit it and nowhere else. (The + installer used to duplicate this guidance into each agent's instructions file, + but that was removed in issue #529.) +- **Installer** (`src/installer/`): Adding a new agent target is one new file in + `targets/` + one entry in `registry.ts`. All changes need test coverage in + `__tests__/installer-targets.test.ts`. + +### Installer Targets + +The installer supports 11 agent targets: + +| Target | MCP config file | +|---|---| +| Claude Code | `.mcp.json` | +| Cursor | `.cursor/mcp.json` | +| Codex CLI | `~/.codex/config.toml` | +| opencode | `opencode.jsonc` / `opencode.json` | +| Hermes | `~/.hermes/config.yaml` | +| Gemini CLI | `~/.gemini/settings.json` | +| Antigravity | `~/.gemini/config/mcp_config.json` | +| Kiro | `~/.kiro/settings/mcp.json` | +| Copilot (VS Code) | `.vscode/mcp.json` | +| Copilot CLI | `~/.copilot/mcp-config.json` | +| Copilot (JetBrains) | plugin `mcp.json` | + +### Build Verification + +Before committing, always run: + +```bash +npm run build && npm test +``` + +TypeScript strict mode is fully enabled — the compiler catches a lot. The build +also copies `.wasm` files and `schema.sql` into `dist/`; if you add new assets, +make sure `copy-assets` picks them up. + +## Adding a New Language + +Use the interactive `/add-lang` skill (`.claude/skills/add-lang/SKILL.md`) — it +walks through the full workflow: + +1. Sourcing a tree-sitter `.wasm` grammar +2. Probing the AST before writing code +3. Registering the language (one new file + two registry lines) +4. Writing the extractor (two patterns: `LanguageExtractor` config vs custom class) +5. Testing and PR checklist + +## Testing + +### Philosophy + +Tests use **real files** and **real SQLite** — there is no DB mocking. Each test +creates a temp directory with `fs.mkdtempSync` and cleans up in `afterAll`/`afterEach`. + +### Running Tests + +```bash +npm test # full suite +npx vitest run __tests__/extraction.test.ts # single file +npx vitest run -t "TypeScript" # filter by test name +``` + +### Writing Tests + +- Place tests in `__tests__/` mirroring the module they cover +- Use `extractFromSource(filename, code)` for extraction unit tests +- Use `it.runIf(process.platform === 'win32')(...)` for platform-gated tests +- Clean up temp dirs in `afterEach`/`afterAll` +- Don't skip or mock the database — integration tests must hit real SQLite + +### Evaluation Tests + +The `__tests__/evaluation/` directory has retrieval quality benchmarks. Run +with: + +```bash +npm run eval # builds first, then runs the evaluation runner +``` + +These are not part of the standard test suite and are run separately. + +## Commit Messages + +We follow [Conventional Commits](https://www.conventionalcommits.org/): + +``` +type(scope): description +``` + +**Types:** `feat`, `fix`, `docs`, `chore`, `refactor`, `test`, `perf` + +**Common scopes:** `extraction`, `resolution`, `mcp`, `cli`, `installer`, +`watcher`, `npm`, `release` + +**Examples:** + +``` +feat(extraction): add Groovy language support +fix(resolution): stream node-kind scans in synthesis to fix OOM +docs(readme): link to the website & docs site +chore: update vitest to v2.1.9 +``` + +- Use the imperative mood ("add" not "added") +- Keep the subject line under 72 characters +- Reference issues with `Closes #123` or `Relates to #123` in the body + +## Pull Requests + +### Before Opening + +1. Rebase on the latest `upstream/main` +2. Run `npm run build && npm test` — everything must pass +3. Run `npx tsc --noEmit` — no type errors +4. Keep changes focused — one concern per PR + +### Changelog + +If your change is user-facing, add a bullet under `## [Unreleased]` in +`CHANGELOG.md`. Use `### New Features`, `### Fixes`, or `### Security` sections +(not `### Added` / `### Changed` / `### Fixed`). Write one plain-language +sentence per bullet — what changed and why it matters to a user. Strip internal +file paths, symbol names, and benchmark numbers. Reference issues by number, +e.g. `(#123)`. + +### PR Description + +Include: + +- **What** changed and **why** +- Test plan (what you ran, what passed) +- Any known limitations or follow-up work +- For language additions: grammar source, version, license, and sha256 if + vendored + +### Review Process + +- Maintainers may request changes — please respond to feedback +- Keep PRs up to date with `upstream/main` via rebase (not merge commits) +- Squash commits if the history is messy + +## Reporting Issues + +When filing a bug report, please include: + +- CodeGraph version (`codegraph --version` or `npx @colbymchenry/codegraph --version`) +- Node.js version (`node --version`) +- Operating system and version +- Steps to reproduce +- Expected vs actual behavior +- Relevant log output or error messages + +For feature requests, describe the use case and why existing functionality +doesn't cover it. + +## License + +By contributing, you agree that your contributions will be licensed under the +[MIT License](LICENSE). diff --git a/README.md b/README.md index baac93178c..a5ddeb2c0c 100644 --- a/README.md +++ b/README.md @@ -900,6 +900,12 @@ Framework routing is validated the same way, on a canonical app per framework: E **Very large repositories (hundreds of thousands of files), or a large `.codegraph/codegraph.db-wal` file** — The `-wal` file is SQLite's write-ahead log: writes waiting to be folded into `codegraph.db`. While a big index is being built, CodeGraph lets it grow in proportion to the index (soft threshold = the larger of 256 MB and a quarter of the index size, up to 2 GB) before folding it back, because folding too often is what made large indexes slow on ordinary disks. At rest it is trimmed to 64 MB, and a leftover from a killed session is folded and trimmed the next time the project opens — the index itself has no size limit. Two environment variables tune this: `CODEGRAPH_WAL_VALVE_MB` (the soft threshold during indexing) and `CODEGRAPH_WAL_HEAL_MB` (the resting size and the trim threshold). `CODEGRAPH_WAL_VALVE_DEBUG=1` prints every decision to stderr. +## Contributing + +Contributions are welcome! See [`CONTRIBUTING.md`](CONTRIBUTING.md) for development setup, testing conventions, and PR guidelines. + +Want to add a new language? Use the `/add-lang` skill (`.claude/skills/add-lang/SKILL.md`) — it walks through sourcing a tree-sitter grammar, probing the AST, choosing an extractor pattern, and the worked examples in the existing extractors. + ## License MIT