Install CodeDNA
One command installs the protocol for your AI tool — instructions + real-time enforcement.
Overview
Setup is two steps. For a new project, step 1 is enough — the agent annotates files as it creates them. For an existing codebase, do both.
Tells the agent how to follow the CodeDNA protocol. Choose your tool below.
Bulk-adds CodeDNA headers to files already in your repo. See CLI.
| Tool | Option | Enforcement |
|---|---|---|
| Claude Code | claude-hooks | Active |
| Cursor | cursor-hooks | Active v1.7+ |
| GitHub Copilot | copilot-hooks | Active |
| Cline | cline-hooks | Active v3.36+ |
| OpenCode | opencode | Active |
| Windsurf | windsurf | Instructions only |
| Aider | claude | Instructions only |
| Antigravity / custom agents | agents | Instructions only |
Quick Setup
Run one command for your tool:
bash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) claude-hooks
Replace claude-hooks with your tool's option from the table above.
For an existing codebase, also run:
pip install git+https://github.com/Larens94/codedna.git
codedna init /path/to/project --no-llm # free, structural onlyClaude Code
Active enforcementbash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) claude-hooks
Installs CLAUDE.md + 4 enforcement hooks + .claude/settings.local.json. Claude Code reads CLAUDE.md automatically; hooks validate every write.
What the four hooks do
| Hook | Event | What it does |
|---|---|---|
| SessionStart | Session begins | Reads .codedna, injects project name and module count into context |
| PreToolUse | Before every .py write/edit | Reminds agent to read docstring and plan agent: update |
| PostToolUse | After every .py write/edit | Validates all 4 fields exist and agent: has today's date |
| Stop | Session ends | Reminds to update .codedna with a new agent_sessions entry |
brew install jq (macOS) or apt install jq (Linux).Settings file location
| File | Committed? | Use when |
|---|---|---|
| .claude/settings.local.json | ❌ gitignored | Personal setup — each developer configures locally |
| .claude/settings.json | committed | Team / CI — shared via the repo, always present |
Cursor
Active enforcement v1.7+bash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) cursor-hooks
Installs .cursorrules + hook scripts in .cursor/hooks/. Cursor runs hooks automatically on file edits and when the agent stops.
| Hook | Event | What it does |
|---|---|---|
| after-file-edit.sh | After every file edit | Validates CodeDNA header on source files |
| stop.sh | Agent finishes | Reminds to update .codedna and commit with AI trailers |
mkdir -p .cursor/rules && cp .cursorrules .cursor/rules/codedna.mdcGitHub Copilot
Active enforcementbash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) copilot-hooks
Installs .github/copilot-instructions.md + .github/hooks/hooks.json + .github/hooks/codedna.sh. Copilot runs hooks automatically at session boundaries and after every tool use.
| Hook | Event | What it does |
|---|---|---|
| session_start | Session begins | Reads .codedna, injects project context |
| post_tool_use | After every file write/edit | Validates CodeDNA header on source files |
| session_end | Session finishes | Reminds to update .codedna and commit with AI trailers |
Cline
Active enforcement v3.36+bash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) cline-hooks
Installs .clinerules + hook scripts in .clinerules/hooks/. Cline runs hooks on task start and after every file write/edit.
| Hook | Event | What it does |
|---|---|---|
| TaskStart.sh | Task begins | Reads .codedna, injects project context |
| PostToolUse.sh | After every file write/edit | Validates CodeDNA header on source files |
OpenCode
Active enforcementbash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) opencode
Installs AGENTS.md + .opencode/plugins/codedna.js. Both load automatically at the next opencode startup.
| File | What it does |
|---|---|
| AGENTS.md | CodeDNA v0.9 instructions — loaded automatically as system prompt |
| .opencode/plugins/codedna.js | After every file write → warns on missing headers (11 languages). At session end → reminds to update .codedna and commit with AI trailers. |
Windsurf
Instructions onlybash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) windsurf
Installs .windsurfrules — Windsurf reads it automatically and applies CodeDNA rules to all Cascade sessions.
Aider
Instructions onlybash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) claude
Installs CLAUDE.md, then pass it as system prompt at launch:
aider --system-prompt "$(cat CLAUDE.md)"
Or add permanently to .aider.conf.yml:
system_prompt: CLAUDE.md
Antigravity / Custom Agents
Instructions onlybash <(curl -fsSL https://raw.githubusercontent.com/Larens94/codedna/main/integrations/install.sh) agents
Installs .agents/workflows/codedna.md — Antigravity and compatible agent frameworks read workflow files from .agents/workflows/ automatically.
CLI — Annotate an existing codebase
Bulk-annotate all files in a project from the terminal. Supports local models via Ollama at zero cost.
pip install git+https://github.com/Larens94/codedna.git # Free — structural only, no AI codedna init /path/to/project --no-llm # Free — local model via Ollama codedna init /path/to/project --model ollama/llama3 # Paid — Anthropic Haiku (~$1-3 for a Django project) ANTHROPIC_API_KEY=sk-... codedna init /path/to/project --model claude-haiku-4-5-20251001
Commands
| Command | What it does |
|---|---|
| codedna init PATH | First-time annotation — L1 module headers + L2 function Rules:. Auto-detects languages. |
| codedna update PATH | Incremental — only unannotated files, safe to re-run |
| codedna refresh PATH | Recalculate exports: + used_by: via AST/tree-sitter. Zero LLM cost. Preserves rules:/agent:. |
| codedna check PATH | Coverage report without modifying files. Exit code 1 if incomplete — works in CI. |
| codedna manifest PATH | Generate .codedna project map (Level 0): packages, depends_on, key_files |
| codedna mode MODE | Get/set mode: human (minimal), semi (default), agent (full protocol) |
| codedna wiki bootstrap PATH | (v0.9 experimental) Generate a per-file Obsidian vault under docs/wiki/ with [[wikilinks]] from used_by:/related: graphs |
| codedna wiki sync PATH | (v0.9 experimental) Regenerate docs/codedna-wiki.md — a narrative 7-section project wiki. Hook to post-commit to keep it current. |
Supported models
| Provider | Example | Cost |
|---|---|---|
| None | --no-llm | Free — structural only (exports + used_by) |
| Ollama (local) | ollama/llama3 | Free |
| DeepSeek | deepseek/deepseek-chat | ~$0.40 / 200 files |
| Anthropic | claude-haiku-4-5-20251001 | ~$1–3 / project |
| OpenAI | openai/gpt-4o-mini | Low |
| gemini/gemini-2.0-flash | Low |
Language Annotation Format
Field names are identical across all languages. Only the comment syntax changes. Select your language:
Python
Module docstring — first thing in the file, before any imports
"""filename.py — purpose in 15 words or fewer.
exports: public_fn(arg) -> ReturnType
used_by: caller.py → caller_fn | other.py → other_fn
related: similar_logic.py — shares same pattern (no import link)
rules: hard constraint agents must never violate
agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
message: "open hypothesis for the next agent"
"""
import os
from typing import Optionalmessage: — Agent-to-Agent Chat (v0.9)
The message: sub-field is a conversational layer between agents. Use it for observations not yet certain enough to become rules:.
Lifecycle: a message is either promoted to rules: (reply @prev: promoted to rules:) or dismissed (@prev: not applicable because...). Always append-only.
Works at both levels: Level 1 (module docstring) and Level 2 (function docstring) — so agents using a sliding window still receive it.
Function-level (Level 2)
def my_function(arg: Type) -> ReturnType:
"""Short description.
Rules: constraint — what must or must not happen here
message: model-id | YYYY-MM-DD | observation for next agent
"""
...Semantic naming
# good → type_shape_domain_origin list_dict_users_from_db = get_users() str_html_report_rendered = render(ctx) int_cents_price_from_request = req.json["price"] # avoid data = get_users() result = render(ctx)
TypeScript / JavaScript
JSDoc block — before the first import
/**
* filename.ts — purpose in 15 words or fewer.
*
* exports: publicFn(arg): ReturnType
* used_by: caller.ts → callerFn
* rules: hard constraint agents must never violate
* agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
* message: "open hypothesis for the next agent"
*/
import { something } from './something';Function-level (Level 2)
/**
* Short description.
*
* Rules: constraint
* message: model-id | YYYY-MM-DD | observation
*/
export function myFunction(arg: Type): ReturnType { ... }Go
Block comment — before the package declaration
// filename.go — purpose in 15 words or fewer.
//
// exports: FuncName(arg Type) ReturnType
// used_by: caller.go → CallerFn
// rules: hard constraint agents must never violate
// agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
// message: "open hypothesis for the next agent"
package mypackageFunction-level (Level 2)
// MyFunction does X.
//
// Rules: constraint
// message: model-id | YYYY-MM-DD | observation
func MyFunction(arg Type) ReturnType { ... }Rust
Inner doc comment — at the top of the file
//! filename.rs — purpose in 15 words or fewer.
//!
//! exports: pub_fn(arg: Type) -> ReturnType
//! used_by: caller.rs → caller_fn
//! rules: hard constraint agents must never violate
//! agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
//! message: "open hypothesis for the next agent"
use std::collections::HashMap;Java
Javadoc block — before the class declaration
/**
* ClassName.java — purpose in 15 words or fewer.
*
* exports: publicMethod(arg Type): ReturnType
* used_by: CallerClass.java → callerMethod
* rules: hard constraint agents must never violate
* agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
* message: "open hypothesis for the next agent"
*/
public class ClassName { ... }Ruby
Comment block — at the top of the file
# filename.rb — purpose in 15 words or fewer.
#
# exports: public_method(arg) -> ReturnType
# used_by: caller.rb → caller_method
# rules: hard constraint agents must never violate
# agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
# message: "open hypothesis for the next agent"
require 'json'PHP
// comment block — after <?php, NOT PHPDoc
<?php
// UserController.php — Handles user CRUD endpoints.
//
// exports: UserController | UserController::index() | UserController::store(Request $request)
// used_by: routes/web.php
// related: app/Models/User.php — shared user domain logic
// rules: must extend App\Http\Controllers\Controller
// agent: codedna-cli | codedna-cli | 2026-04-18 | codedna-cli | initial CodeDNA annotation
namespace App\Http\Controllers;Blade templates
{{-- layout.blade.php — Base application layout.
--
-- exports: none
-- used_by: none
-- rules: @yield('content') is required — child views must define this section
-- agent: codedna-cli | codedna-cli | 2026-04-18 | codedna-cli | initial CodeDNA annotation
--}}
<!DOCTYPE html>Blade (Laravel)
{{-- --}} comment block — at the top of the file
{{-- layout.blade.php — Base application layout.
--
-- exports: none
-- used_by: none
-- rules: @yield('content') is required — child views must define this section
-- agent: codedna-cli | codedna-cli | 2026-04-18 | codedna-cli | initial CodeDNA annotation
--}}
<!DOCTYPE html>
<html>JavaScript
JSDoc block — before the first import or export
/**
* filename.js — purpose in 15 words or fewer.
*
* exports: publicFn(arg)
* used_by: caller.js → callerFn
* rules: hard constraint agents must never violate
* agent: claude-sonnet-4-6 | anthropic | 2026-03-24 | s_20260324_001 | what was done
* message: "open hypothesis for the next agent"
*/
const something = require('./something');Hook Events Reference
All CodeDNA hook scripts follow the same pattern: receive JSON via stdin, write feedback to stdout, exit 0.
| Event | Claude Code | Cursor | Copilot | Cline |
|---|---|---|---|---|
| Session / task start | SessionStart | — | sessionStart | TaskStart |
| Before write/edit | PreToolUse | — | — | — |
| After write/edit | PostToolUse | afterFileEdit | postToolUse | PostToolUse |
| Session / agent end | Stop | stop | sessionEnd | — |
Claude Code Plugin Available
claude plugin marketplace add Larens94/codedna && claude plugin install codedna@codedna
/clear). Slash commands are only available after restarting.No API key. No extra cost. Uses your existing Claude subscription. Adds interactive setup via /codedna:init + coverage check via /codedna:check + architectural map via /codedna:manifest + impact analysis via /codedna:impact.