Skip to content

Latest commit

 

History

History
480 lines (341 loc) · 14.1 KB

File metadata and controls

480 lines (341 loc) · 14.1 KB

Recommended Practices

Practical patterns for integrating codegraph into your development workflow.


Git Hooks

Pre-commit: rebuild the graph

Keep your graph up to date automatically. Add this to your git hooks so the database is always fresh before you commit.

With husky (recommended):

npm install -D husky
npx husky init
echo "codegraph build" > .husky/pre-commit

With a plain git hook:

echo '#!/bin/sh
codegraph build' > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit

Pre-push: impact check

See what your branch will affect before pushing:

# .husky/pre-push
codegraph build
codegraph diff-impact --ref origin/main --no-tests

This prints a summary like:

3 functions changed → 12 callers affected across 7 files

If you want to block pushes that exceed a threshold, add a check:

# .husky/pre-push
codegraph build
IMPACT=$(codegraph diff-impact --ref origin/main --no-tests --json)
AFFECTED=$(echo "$IMPACT" | node -e "
  const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
  console.log(d.summary?.callersAffected || 0)
")
if [ "$AFFECTED" -gt 50 ]; then
  echo "WARNING: $AFFECTED callers affected. Review with 'codegraph diff-impact' before pushing."
  exit 1
fi

Commit message enrichment

Automatically append impact info to commit messages:

# .husky/prepare-commit-msg
IMPACT=$(codegraph diff-impact --staged --no-tests --json 2>/dev/null)
SUMMARY=$(echo "$IMPACT" | node -e "
  const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
  if (d.summary) console.log('Impact: ' + d.summary.functionsChanged + ' functions changed, ' + d.summary.callersAffected + ' callers affected');
" 2>/dev/null)
if [ -n "$SUMMARY" ]; then
  echo "" >> "$1"
  echo "$SUMMARY" >> "$1"
fi

CI / GitHub Actions

Basic: PR impact comments

Copy the included workflow to your repo:

cp node_modules/@optave/codegraph/.github/workflows/codegraph-impact.yml .github/workflows/

Every PR gets a comment:

3 functions changed -> 12 callers affected across 7 files

Advanced: fail on high-impact PRs

Add a threshold check to your CI pipeline:

- name: Check impact threshold
  run: |
    npx codegraph build
    IMPACT=$(npx codegraph diff-impact --ref origin/${{ github.base_ref }} --json)
    AFFECTED=$(echo "$IMPACT" | node -e "
      const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8'));
      console.log(d.summary?.callersAffected || 0)
    ")
    echo "Callers affected: $AFFECTED"
    if [ "$AFFECTED" -gt 100 ]; then
      echo "::error::High impact PR — $AFFECTED callers affected. Requires additional review."
      exit 1
    fi

Caching the graph database

Speed up CI by caching .codegraph/:

- uses: actions/cache@v4
  with:
    path: .codegraph
    key: codegraph-${{ hashFiles('src/**', 'lib/**') }}
    restore-keys: codegraph-
- run: npx codegraph build  # incremental — only re-parses changed files

AI Agent Integration

MCP server

Start the MCP server so AI assistants can query your graph:

codegraph mcp                  # Single-repo mode (default) — only local project
codegraph mcp --multi-repo     # Multi-repo — all registered repos accessible
codegraph mcp --repos a,b      # Multi-repo with allowlist

By default, the MCP server runs in single-repo mode — the AI agent can only query the current project's graph. The repo parameter and list_repos tool are not exposed, preventing agents from silently accessing other codebases.

Enable --multi-repo to let the agent query any registered repository, or use --repos to restrict access to a specific set of repos.

The server exposes tools for query_function, file_deps, impact_analysis, find_cycles, module_map, fn_deps, fn_impact, diff_impact, semantic_search, export_graph, list_functions, structure, and hotspots.

CLAUDE.md for your project

Add this to your project's CLAUDE.md so AI agents know codegraph is available:

## Code Navigation

This project uses codegraph. The database is at `.codegraph/graph.db`.

- **Before modifying a function**: `codegraph fn <name> --no-tests`
- **Before modifying a file**: `codegraph deps <file>`
- **To assess PR impact**: `codegraph diff-impact --no-tests`
- **To find entry points**: `codegraph map`
- **To trace breakage**: `codegraph fn-impact <name> --no-tests`

Rebuild after major structural changes: `codegraph build`

### Semantic search

Use `codegraph search` to find functions by intent rather than exact name.
When a single query might miss results, combine multiple angles with `;`:

  codegraph search "validate auth; check token; verify JWT"
  codegraph search "parse config; load settings" --kind function

Multi-query search uses Reciprocal Rank Fusion — functions that rank
highly across several queries surface first. This is especially useful
when you're not sure what naming convention the codebase uses.

When writing multi-queries, use 2-4 sub-queries (2-4 words each) that
attack the problem from different angles. Pick from these strategies:
- **Naming variants**: cover synonyms the author might have used
  ("send email; notify user; deliver message")
- **Abstraction levels**: pair high-level intent with low-level operation
  ("handle payment; charge credit card")
- **Input/output sides**: cover the read half and write half
  ("parse config; apply settings")
- **Domain + technical**: bridge business language and implementation
  ("onboard tenant; create organization; provision workspace")

Use `--kind function` to cut noise. Use `--file <pattern>` to scope.

Claude Code hooks

You can configure Claude Code hooks to automatically rebuild the graph after file edits:

// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "codegraph build",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

This ensures the graph stays fresh as the AI agent modifies files. Incremental builds are automatic — only changed files are re-parsed.

Parallel session safety hooks

When multiple AI agents work on the same repo concurrently, add hooks to prevent cross-session interference:

  • Edit tracker (PostToolUse on Edit|Write): log every file path touched to .claude/session-edits.log
  • Git guard (PreToolUse on Bash): block git add ., git reset, git restore, git clean, git stash, and validate that git commit only includes files from the session edit log

See this repo's .claude/hooks/track-edits.sh and guard-git.sh for a working implementation. Pair with the /worktree command so each session gets an isolated copy of the repo.


Developer Workflow

Watch mode during development

Keep the graph updating in the background while you code:

codegraph watch

Changes are picked up incrementally — no manual rebuilds needed.

Explore before you edit

Before touching a function, check its blast radius:

codegraph fn myFunction --no-tests      # callers, callees, call chain
codegraph fn-impact myFunction --no-tests  # what breaks if this changes

Before touching a file:

codegraph deps src/utils/auth.ts         # imports and importers
codegraph impact src/utils/auth.ts       # transitive reverse deps

Find circular dependencies early

codegraph cycles                         # file-level cycles
codegraph cycles --functions             # function-level cycles

Semantic search for discovery

When you're not sure where something lives:

codegraph search "handle authentication"
codegraph search "parse config file" --min-score 0.4

Build embeddings first (one-time):

codegraph embed                          # ~23 MB model, fast
codegraph embed --model jina-code        # ~137 MB, best for code search
codegraph embed --model bge-large        # ~335 MB, best general retrieval

Multi-query search

When a single query doesn't capture what you're looking for, combine multiple angles with ;. Results are ranked using Reciprocal Rank Fusion (RRF) — functions that score well across multiple queries rise to the top.

Use 2-4 sub-queries. Each sub-query should attack the problem from a different angle. The framework below covers the four most effective angles — pick 2-3 that fit your situation:

1. Name what it does vs. what it's called

Codebases are inconsistent. The function you want might be called authenticate, checkAuth, verifyUser, or ensureLoggedIn. Cover the likely naming variations:

# You think "validate input" — but the author might have written "sanitize", "check", or "parse"
codegraph search "validate input; sanitize request; check params"

# You think "send email" — but it could be "notify", "mail", or "deliver"
codegraph search "send email; notify user; deliver message"

2. Describe the behavior at different abstraction levels

A high-level description ("handle payment") and a low-level one ("charge credit card") often match different but related functions. Combining them surfaces the full chain:

# High-level intent + low-level implementation
codegraph search "handle payment; charge credit card; create Stripe session"

# Architecture concept + concrete operation
codegraph search "rate limiting; count requests per window; throttle API"

3. Cover the input side and the output side

Many operations have a clear "read" half and a "write" half. Querying both surfaces the full pipeline:

# Reading config + applying config
codegraph search "parse config file; apply settings; load environment"

# Receiving data + transforming data
codegraph search "deserialize JSON payload; map response to model"

4. Include the domain term and the technical term

Business logic often uses domain language that differs from the technical implementation. Bridge both:

# Domain language + implementation pattern
codegraph search "onboard new tenant; create organization; provision workspace"

# User-facing concept + internal mechanism
codegraph search "user permissions; role-based access; check authorization"

Putting it together

A real-world search typically mixes 2-3 of these angles:

# Refactoring a caching layer — synonyms + abstraction levels + domain terms
codegraph search "cache invalidation; expire stale entries; TTL cleanup" --kind function

# Finding all auth-related code before a security review
codegraph search "authenticate request; verify JWT; check session token" --file "src/api/*"

# Understanding how errors propagate — input/output + abstraction
codegraph search "catch exception; format error response; report failure to client"

Additional tips:

  • Keep each sub-query to 2-4 words — embedding models work best on short, focused phrases
  • Use --kind function or --kind method to cut noise from class/type matches
  • Use --file <pattern> to scope to a directory when you roughly know where the code lives
  • Lower --rrf-k (e.g., --rrf-k 30) to make top-ranked results dominate more sharply

Secure Credential Management

Codegraph's LLM features (semantic search with LLM-generated descriptions, future codegraph ask) require an API key. Use apiKeyCommand to fetch it from a secret manager at runtime instead of hardcoding it in config files or leaking it through environment variables.

Why not environment variables?

Environment variables are better than plaintext in config files, but they still leak via ps e, /proc/<pid>/environ, child processes, shell history, and CI logs. apiKeyCommand keeps the secret in your vault and only materializes it in process memory for the duration of the call.

Examples

1Password CLI:

{
  "llm": {
    "provider": "openai",
    "apiKeyCommand": "op read op://Development/openai/api-key"
  }
}

Bitwarden CLI:

{
  "llm": {
    "provider": "anthropic",
    "apiKeyCommand": "bw get password anthropic-api-key"
  }
}

macOS Keychain:

{
  "llm": {
    "provider": "openai",
    "apiKeyCommand": "security find-generic-password -s codegraph-llm -w"
  }
}

HashiCorp Vault:

{
  "llm": {
    "provider": "openai",
    "apiKeyCommand": "vault kv get -field=api_key secret/codegraph/openai"
  }
}

pass (GPG-encrypted):

{
  "llm": {
    "provider": "openai",
    "apiKeyCommand": "pass show codegraph/openai-key"
  }
}

Priority chain

The resolution order is:

  1. apiKeyCommand output (highest priority)
  2. CODEGRAPH_LLM_API_KEY environment variable
  3. llm.apiKey in config file
  4. null (default)

If the command fails (timeout, not found, non-zero exit), codegraph logs a warning and falls back to the next available source. The command has a 10-second timeout.

Security notes

  • The command is split on whitespace and executed with execFileSync (array args, no shell) — no shell injection risk
  • stdout is captured; stderr is discarded
  • The resolved key is held only in process memory, never written to disk
  • Keep .codegraphrc.json out of version control if it contains apiKeyCommand paths specific to your vault layout, or use a shared command that works across the team

.gitignore

Add the codegraph database to .gitignore — it's a build artifact:

# codegraph
.codegraph/

The database is rebuilt from source with codegraph build. Don't commit it.


Suggested setup checklist

# 1. Install codegraph
npm install -g @optave/codegraph

# 2. Build the graph
codegraph build

# 3. Add to .gitignore
echo ".codegraph/" >> .gitignore

# 4. Set up pre-commit hook (with husky)
npm install -D husky
npx husky init
echo "codegraph build" > .husky/pre-commit

# 5. Copy CI workflow
mkdir -p .github/workflows
cp node_modules/@optave/codegraph/.github/workflows/codegraph-impact.yml .github/workflows/

# 6. (Optional) Build embeddings for semantic search
codegraph embed

# 7. (Optional) Add CLAUDE.md for AI agents
# See the AI Agent Integration section above