Get started Overview Quick Setup Active enforcement Claude Code Cursor GitHub Copilot Cline OpenCode Instructions only Windsurf Aider Antigravity Annotate your code CLI Languages Reference Hook Events Plugin (coming soon)

Documentation

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.

1
Install the integration for your AI tool

Tells the agent how to follow the CodeDNA protocol. Choose your tool below.

2
Annotate your existing codebase (existing projects only)

Bulk-adds CodeDNA headers to files already in your repo. See CLI.

ToolOptionEnforcement
Claude Codeclaude-hooksActive
Cursorcursor-hooksActive v1.7+
GitHub Copilotcopilot-hooksActive
Clinecline-hooksActive v3.36+
OpenCodeopencodeActive
WindsurfwindsurfInstructions only
AiderclaudeInstructions only
Antigravity / custom agentsagentsInstructions only
Active enforcement = hooks validate annotations automatically on every file write/edit, regardless of session length or task complexity. The agent cannot skip annotations even in long or complex sessions.

Quick Setup

Run one command for your tool:

terminal
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 only

Claude Code

Active enforcement
terminal
bash <(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

HookEventWhat it does
SessionStartSession beginsReads .codedna, injects project name and module count into context
PreToolUseBefore every .py write/editReminds agent to read docstring and plan agent: update
PostToolUseAfter every .py write/editValidates all 4 fields exist and agent: has today's date
StopSession endsReminds to update .codedna with a new agent_sessions entry
Requires jq: brew install jq (macOS) or apt install jq (Linux).

Settings file location

FileCommitted?Use when
.claude/settings.local.json❌ gitignoredPersonal setup — each developer configures locally
.claude/settings.jsoncommittedTeam / CI — shared via the repo, always present

Cursor

Active enforcement v1.7+
terminal
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.

HookEventWhat it does
after-file-edit.shAfter every file editValidates CodeDNA header on source files
stop.shAgent finishesReminds to update .codedna and commit with AI trailers
For Cursor v0.43+, you can also place rules under .cursor/rules/: mkdir -p .cursor/rules && cp .cursorrules .cursor/rules/codedna.mdc

GitHub Copilot

Active enforcement
terminal
bash <(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.

HookEventWhat it does
session_startSession beginsReads .codedna, injects project context
post_tool_useAfter every file write/editValidates CodeDNA header on source files
session_endSession finishesReminds to update .codedna and commit with AI trailers

Cline

Active enforcement v3.36+
terminal
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.

HookEventWhat it does
TaskStart.shTask beginsReads .codedna, injects project context
PostToolUse.shAfter every file write/editValidates CodeDNA header on source files

OpenCode

Active enforcement
terminal
bash <(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.

FileWhat it does
AGENTS.mdCodeDNA v0.8 instructions — loaded automatically as system prompt
.opencode/plugins/codedna.jsAfter every file write → warns on missing headers (11 languages). At session end → reminds to update .codedna and commit with AI trailers.
Fallback: if no AGENTS.md is found, OpenCode falls back to CLAUDE.md automatically — projects using the Claude Code integration work out of the box.

Windsurf

Instructions only
terminal
bash <(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.

Windsurf supports post-response hooks (observability only) — no blocking enforcement is available. The agent receives instructions but nothing validates compliance automatically.

Aider

Instructions only
terminal
bash <(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 only
terminal
bash <(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

CommandWhat it does
codedna init PATHFirst-time annotation — L1 module headers + L2 function Rules:
codedna update PATHIncremental — only unannotated files, safe to re-run
codedna check PATHCoverage report without modifying files
codedna manifest PATHFull architectural map — package tree, import graph
codedna init PATH --extensions ts goAnnotate TypeScript + Go files too (L1 only)

Supported models

ProviderExampleCost
Ollama (local)ollama/llama3Free
Anthropicclaude-haiku-4-5-20251001~$1–3 / project
OpenAIopenai/gpt-4o-miniLow
Googlegemini/gemini-2.0-flashLow
None--no-llmFree

Language Annotation Format

Field names are identical across all languages. Only the comment syntax changes. Select your language:

Python
"""docstring"""
TypeScript
/** JSDoc */
JavaScript
/** JSDoc */
Go
// before package
Rust
//! inner doc
Java
/** Javadoc */
Ruby
# comment block

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
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 Optional

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 mypackage

Function-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'

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.

EventClaude CodeCursorCopilotCline
Session / task startSessionStartsessionStartTaskStart
Before write/editPreToolUse
After write/editPostToolUseafterFileEditpostToolUsePostToolUse
Session / agent endStopstopsessionEnd
All hook scripts use tools/validate_manifests.py for validation — downloaded automatically by install.sh.

Claude Code Plugin Coming soon

The CodeDNA plugin for Claude Code has been accepted by Anthropic and is currently under review — not yet available in the public directory.

Use Claude Code hooks or the CLI in the meantime — they provide equivalent functionality.

Once available:

claude plugin install codedna

No API key. No extra cost. Uses your existing Claude subscription. Adds /codedna:init, /codedna:check, /codedna:manifest, /codedna:impact + four enforcement hooks.