diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 325c2f67..1d61bc20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,64 +10,42 @@ Thanks for your interest in contributing! Here's how to get involved. ## Adding a New Language -Want to add support for a language like Clojure, Zig, Haskell, etc.? Here's what's needed: +Want to add support for a language like Clojure, Zig, Haskell, etc.? `--deps` runs [ast-grep](https://ast-grep.github.io/) with YAML rules that are embedded in the binary (`//go:embed sg-rules/*.yml` in `scanner/astgrep.go`), so there is no grammar to build or ship. The language must be one ast-grep can parse. Here's what's needed: -### 1. Add grammar to `release.yml` +### 1. Add a rule file -In `.github/workflows/release.yml`, add a line to the `GRAMMARS` env var: +Create `scanner/sg-rules/.yml` with an imports rule and a functions rule. Rule IDs start with a prefix followed by `-`, for example `lua-imports` and `lua-functions`: ```yaml -env: - GRAMMARS: | - go:tree-sitter/tree-sitter-go:master:src - # ... existing grammars ... - clojure:sogaiu/tree-sitter-clojure:main:src # <- add yours +id: lua-imports +language: lua +rule: + any: + - kind: function_call + pattern: require($$$) +--- +id: lua-functions +language: lua +rule: + kind: function_declaration ``` -Format: `name:github_org/repo:branch:src_dir` +Use the existing files in `scanner/sg-rules/` as examples, and the [ast-grep playground](https://ast-grep.github.io/playground.html) to find node kinds. -Most grammars use `src` as the source directory, but check the repo structure. +### 2. Map the rule prefix and the extensions -### 2. Create a query file +- `scanner/astgrep.go`: add the rule-ID prefix to `ruleIDToLang`. +- `scanner/types.go`: add each file extension to `extToLang`, the language to `resolverLanguageFamilies` (imports only resolve between languages in the same family), and its display name to `LangDisplay`. -Create `scanner/queries/.scm` to define what to capture: +### 3. Add a conformance case -```scm -; Functions - capture function/method definitions -(function_definition - name: (identifier) @function) +`scanner/conformance_test.go` fails for any language in `extToLang` without an entry in `conformanceCases`: a two-file fixture, the edge that must (or must not) exist, and the expected coverage status. Run `go test ./scanner/` with ast-grep installed. -; Imports - capture import/require statements -(import_clause - (identifier) @import) -``` - -**Finding the right node types:** -- Use [tree-sitter playground](https://tree-sitter.github.io/tree-sitter/7-playground.html) -- Check the grammar repo's `grammar.js` for node names -- Look at existing queries in `scanner/queries/` for examples - -### 3. Add extension mapping - -In `scanner/grammar.go`, add to the `extToLang` map: - -```go -var extToLang = map[string]string{ - // ... existing mappings ... - ".clj": "clojure", - ".cljs": "clojure", - ".cljc": "clojure", -} -``` +If suffix and directory matching cannot resolve the language's imports, add a resolver in `scanner/filegraph.go` (see `resolveLuaModule`) with tests. ### 4. Open a PR -That's it from your side! Open a PR with these 3 changes. - -**What happens next:** -- Maintainer reviews the PR -- Maintainer updates the Homebrew formula (`codemap.rb`) with the new grammar -- On next release, all platforms get the new language automatically +Release packaging copies `scanner/sg-rules/*`, so nothing else changes for a release. ## Development Setup @@ -78,12 +56,13 @@ cd codemap # Build the binary go build -o codemap . -# Build grammars for --deps mode (requires clang/gcc) -make deps +# --deps mode needs ast-grep on PATH (as ast-grep or sg) +brew install ast-grep # or: pip install ast-grep-cli # Test it ./codemap . ./codemap --deps . +go test ./... ``` ## Code Style diff --git a/README.md b/README.md index 64dbb295..fcb1263f 100644 --- a/README.md +++ b/README.md @@ -25,42 +25,63 @@ After `codemap setup`, the agent gets three answers it cannot get from the sourc **Where things are.** `codemap .` ``` -╭────────────────────────────── codemap ──────────────────────────────╮ -│ Files: 289 | Size: 2.3MB │ -│ Top Extensions: .go (227), .yml (35), .md (23), .sh (2), .ps1 (1) │ -╰─────────────────────────────────────────────────────────────────────╯ +╭─────────────────────────────── codemap ────────────────────────────────╮ +│ Files: 372 (all types, after ignore rules and filters) | Size: 2.9MB │ +│ Top Extensions: .go (293), .md (45), .yml (29), .sh (3), .ps1 (1) │ +╰────────────────────────────────────────────────────────────────────────╯ codemap -├── analysis/ (2 files, 3.6KB, all .go) -├── cmd/ (47 files, 463.2KB, all .go) -├── config/ (2 files, 23.2KB, all .go) +├── analysis/ (2 files, 4.1KB, all .go) +│ └── ⭐️ contracts.go ←45 (+1 test) +├── ⭐️ cmd/ ←6 (59 files, 533.1KB, all .go) +│ ... +├── config/ (2 files, 25.1KB, all .go) +│ └── ⭐️ config.go 328L ←42 (+1 test) ... +⭐️ ←N = imported by N files, 3+ of them non-test (Go: package count, on its dir); NL = lines, shown at 100+ (text files up to 2MB) +Hubs (top 10 of 15, by importers): + ←79 scanner/ + ←48 internal/projectpath/ + ←45 analysis/contracts.go + ... +Next: codemap --deps · codemap --importers scanner/astgrep.go ``` **Who depends on this.** `codemap --importers config/config.go` ``` ⚠️ HUB FILE: config/config.go - Imported by 40 files - changes have wide impact! + Imported by 42 files (package codemap/config: Go imports name packages, not files) - changes have wide impact! Dependents: • blast_radius.go + • blast_radius_fixes_test.go • cmd/config.go - ... and 38 more + • cmd/config_more_test.go + • cmd/config_test.go + ... and 37 more + Imports 2 hub(s): internal/projectpath/ (2 files), limits/ (2 files) Coverage: complete ``` **Where is X defined.** `codemap find "hub importers"` ranks files by path and function/type names, then by body text; hits that matched only in a body are tagged `(body)`. For an exact bug symptom, grep too. ``` +importers_go_package_test.go + matched: importers_go_package_test.go, TestImportersCLIReportsGoPackageGranularity, TestImportersCLIGoPackageHubIsNotAFileHub, TestImportersCommandListsMultiFilePackageImporter + importers: 0 (of package codemap) +cmd/hooks_test.go + matched: TestHubInfoIsHub, TestCheckFileImportersOutput, formatFileImportersOutput, TestHubInfoWithMultipleHubs, TestGetHubInfoNoDeps + importers: 0 (of package codemap/cmd) main.go - matched: resolveImportersInvocation, buildImportersReport, runImportersMode - importers: 0 + matched: resolveImportersInvocation, buildImportersReport, runImportersMode, isGitHubURL + importers: 0 (of package codemap) +... Coverage: complete ``` Ranked by path and symbol match, each hit tagged with its importer count. Lexical only, and it says so. -**And the one line every answer carries.** Every dependency answer reports a coverage status: `complete`, `partial`, or `unavailable`, with the source that could not be trusted. A partial graph never reads as a complete one, so "nothing imports this" and "I couldn't tell" are different answers. +**And the one line every answer carries.** Every dependency answer reports a coverage status: `complete`, `partial`, or `unavailable`, with the source that could not be trusted. A partial graph never reads as a complete one, so "nothing imports this" and "I couldn't tell" are different answers. The full contract is in [docs/RESOLUTION.md](docs/RESOLUTION.md#the-coverage-contract). ## What it's for @@ -85,451 +106,38 @@ scoop bucket add codemap https://github.com/JordanCoin/scoop-codemap scoop install codemap ``` -> Other options: [Releases](https://github.com/JordanCoin/codemap/releases) | `go install` | build from source - -### CI / tarball install - -Release tarballs ship `codemap` and the bundled rules but not the `ast-grep` executable, which `--deps` needs. Either install it separately: - -```bash -apk add --no-cache curl jq bash python3 py3-pip - -ARCH=$(uname -m) -if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; elif [ "$ARCH" = "aarch64" ]; then ARCH="arm64"; fi - -CODEMAP_VERSION=$(curl -fsSL https://api.github.com/repos/JordanCoin/codemap/releases/latest | jq -r '.tag_name' | tr -d 'v') -curl -fsSL "https://github.com/JordanCoin/codemap/releases/download/v${CODEMAP_VERSION}/codemap_${CODEMAP_VERSION}_linux_${ARCH}.tar.gz" \ - | tar xz -C /usr/local/bin/ codemap - -python3 -m pip install --no-cache-dir ast-grep-cli -``` - -…or use the self-contained `codemap-full` artifact, which bundles `codemap`, `ast-grep`, and `sg`: - -```bash -curl -fsSL "https://github.com/JordanCoin/codemap/releases/download/v${CODEMAP_VERSION}/codemap-full_${CODEMAP_VERSION}_linux_${ARCH}.tar.gz" \ - | tar xz -C /usr/local/bin/ codemap ast-grep sg -``` - -## Setup - -Run setup anywhere inside your git repo. Repo-scoped commands such as -`setup`, `doctor`, `config`, `watch`, `skill`, `context`, `serve`, and -managed hooks resolve the nearest git root automatically, including linked -worktrees with a `.git` file. - -```bash -cd /path/to/your/project -codemap setup -``` - -`codemap setup` configures the agents it detects: Claude Code when `~/.claude`, `~/.claude.json`, or `claude` on `PATH` exists, Codex when `~/.codex` or `codex` on `PATH` exists, and both when it finds neither. It: - -- creates `.codemap/config.json` with auto-detected language filters -- merges Claude hooks into `.claude/settings.local.json` and configures MCP in `.mcp.json` (project scope) -- merges Codex hooks into `~/.codex/hooks.json` and configures MCP in `~/.codex/config.toml` (user scope, since Codex skips a project's `.codex/` until the project is trusted; `--project` writes `.codex/` instead) -- writes the builtin skills to `.claude/skills/` for Claude, keeping any skill file you edited -- hooks start and read daemon state at session start - -Rerunning setup is safe: it changes only what is missing or stale. `--no-config`, `--no-hooks`, `--no-mcp`, and `--no-skills` skip a piece. - -Managed entries record the verified absolute path of the running `codemap`, so agents don't depend on your shell `PATH`. Rerun setup if that path changes. - -```bash -codemap setup --agent claude # one agent only -codemap setup --agent codex -codemap setup --global # Claude at user scope too (~/.claude), applies to every project -codemap setup --project # Codex at project scope (.codex/) instead of ~/.codex -``` - -After a `brew upgrade`, the session-start hook prints one line naming any integration still stamped with the old version and the command that refreshes it. - -### Verify - -```bash -codemap doctor # validate this project's integrations -codemap doctor --global # validate user-scope configuration -``` - -Doctor checks project scope and falls back to user scope, reporting which one satisfied each check. For Codex, trust the hooks from `/hooks` in CLI or Settings → Hooks in Desktop, then start a new session. - -## Dependency resolution - -`--deps` and `--importers` resolve imports using each ecosystem's own rules rather than guessing from paths: - -| Ecosystem | Resolved via | -|-----------|--------------| -| **Go** | module path from `go.mod`; stdlib and third-party imports are not fuzzy-matched into local files | -| **Rust** | `cargo metadata` — workspace membership, target kinds (lib/bin/test/bench/example/build), and `dev-dependencies` reachable from `#[cfg(test)]` blocks | -| **JS/TS** | `package.json` `exports`/`imports` maps, npm/pnpm/Bun workspaces, Deno import maps, and `tsconfig` `rootDir`/`outDir` remapping (including `extends`) | -| **Dart/Flutter** | `pubspec.yaml` package names and declared dependencies; `package:` URIs resolve within the owning package's `lib/`, while undeclared or duplicate package names fail closed | -| **Everything else** | ast-grep import extraction with suffix and directory matching | - -### The coverage contract - -Every dependency answer reports how much of it codemap actually stands behind: - -```bash -codemap --json --deps . | jq .coverage -``` - -```json -{ - "status": "partial", - "sources": [ - { "name": "ast-grep", "status": "authoritative", - "languages": ["bash", "c", "cpp", "csharp", "dart", "elixir", "go", "java", "javascript", "kotlin", "lua", "php", "python", "ruby", "rust", "scala", "solidity", "swift", "typescript"] }, - { "name": "cargo-metadata", "status": "mixed", - "detail": "2 of 5 Cargo manifests used fallback topology", - "languages": ["rust"] } - ], - "issues": [ - { "code": "unresolved-import", "path": "src/app.ts", - "message": "import ./gone resolved to no file in the project" } - ] -} -``` - -`issues` lists each project-relative import that resolved to no file, one entry per reference. The key is omitted when there are none. - -- `status` is `complete`, `partial`, or `unavailable`. -- Each source reports `authoritative`, `mixed`, `fallback`, `timeout`, `unavailable`, or `failed`. -- `languages` names the languages a source can affect. Per-file answers (`--importers`, `get_importers`, `get_file_context`, the importer sections of `blast-radius`) keep only the sources tagged with the file's language, plus untagged sources, which apply everywhere. A Go file in a Go+Rust repo reads `complete` with no Rust caveat; `--deps` keeps the scan-level rollup. -- A timed-out or failed scan returns an **empty result with provenance**, not a silent empty graph and not a hard error — so an agent can tell "nothing imports this" apart from "I couldn't tell". - -The JSON payload is versioned (`schema_version: codemap.analysis/v1`) so consumers can depend on its shape. - -### Supported languages - -21 ast-grep language rules for dependency analysis: Go, Python, JavaScript, JSX, TypeScript, TSX, Rust, Ruby, C, C++, Java, Swift, Dart, Kotlin, C#, PHP, Bash, Lua, Scala, Elixir, Solidity. Dart projects, including Flutter apps and packages, also get `pubspec.yaml` dependency discovery. CUE files also contribute module-scoped package edges through lexical import extraction; CUE is not an ast-grep rule. - -> Powered by [ast-grep](https://ast-grep.github.io/). Installed automatically with the Homebrew formula. +Tarballs, CI, and what `codemap setup` writes: [docs/INSTALL.md](docs/INSTALL.md). ## Commands ```bash -codemap . # structure view (respects .codemap/config.json) -codemap --diff # what changed vs main -codemap --deps . # dependency flow -codemap --importers f # who imports a file -codemap blast-radius # review bundle: diff + deps + importers -codemap collide # rank open PRs by shared-file merge-order hazard -codemap find "" # where is X defined: rank by path, symbol names, then body text ("(body)" tag), with importer counts -codemap handoff . # save layered handoff for cross-agent continuation -codemap context # machine-readable project context JSON -codemap doctor # validate agent integrations -codemap skill list # available agent skills -codemap watch start # background daemon for live graph state -codemap serve # HTTP API for non-MCP integrations -codemap mcp # MCP server on stdio -codemap --version -``` - -### Options - -Standard linked Git worktrees automatically reuse the primary worktree's -`.codemap/config.json` and project skills. Create the worktree with Git, an IDE, -or any manager that uses standard linked-worktree metadata, then give the agent -its absolute path: - -```bash -git worktree add -b -codemap -C /tmp/feature-worktree context -``` - -Normal CLI and plugin MCP calls need no `--setup-root`: central config and skills -come from the primary worktree, while handoffs, watcher files, and hook/session -state remain in the linked worktree. Independent clones have no trusted Git -metadata linking them, so sharing setup between them still requires an explicit -override: - -```bash -codemap -C /tmp/independent-clone --setup-root /path/to/original context -``` - -`-C`/`--project-root` operates on exactly the named directory, like `git -C`; -it may be a subdirectory of a repository, and storage and config discovery still -walk up to the git root. `--setup-root` explicitly reuses `/.codemap` -policy and runtime state from another checkout. Both accept a repository or -subdirectory; relative setup paths resolve from the project root. - -| Flag | Description | - -| Flag | Description | -|------|-------------| -| `-C, --project-root ` | Operate on exactly `` (may be a subdirectory of a repository; storage and config discovery still walk up to the git root) | -| `--setup-root ` | Explicitly reuse policy and runtime state from `/.codemap` | -| `--depth, -d ` | Limit tree depth (0 = unlimited) | -| `--only ` | Only include files with these extensions | -| `--exclude ` | Exclude files matching patterns | -| `--max-files ` | Scan bound: files kept by the tree, and the largest repo a dependency scan runs on (default 100000, or config `max_files`; `-1` = unbounded). Above it the output says `bounded: scanned N of M files` instead of presenting a prefix as the repo | -| `--diff` | Show files changed vs main branch | -| `--ref ` | Branch to compare against (with `--diff`) | -| `--deps` | Dependency flow mode | -| `--importers ` | Check who imports a file | -| `--skyline` | City skyline visualization | -| `--animate` | Animate the skyline (with `--skyline`) | -| `--json` | Output JSON | -| `--color ` | `auto` (default): ANSI colour only when stdout is a terminal and `NO_COLOR` is unset; `always` keeps colour when piping into `less -R`; `never` turns it off | - -> Flags come before the path/URL: `codemap --json github.com/user/repo` - -**Pattern matching** needs no quotes: `.png` matches any `.png` file, `Fonts` matches any `/Fonts/` directory, `*Test*` is a glob. - -## Modes - -### Diff - -```bash -codemap --diff -codemap --diff --ref develop -``` - -``` -╭─────────────────────────── myproject ──────────────────────────╮ -│ Changed: 4 files | +156 -23 lines vs main │ -╰────────────────────────────────────────────────────────────────╯ -├── api/ -│ └── (new) auth.go ✎ handlers.go (+45 -12) -└── ✎ main.go (+29 -3) - -⚠ handlers.go is used by 3 other files -``` - -### Dependency flow - -```bash -codemap --deps . -``` - +codemap . # structure view +codemap --diff # what changed vs main +codemap --deps . # dependency flow +codemap --importers # who imports a file +codemap blast-radius # review bundle: diff + deps + importers +codemap find "" # where is X defined +codemap handoff . # save a handoff for the next agent +codemap doctor # validate agent integrations ``` -╭──────────────────────────────────────────────────────────────╮ -│ MyApp - Dependency Flow │ -├──────────────────────────────────────────────────────────────┤ -│ Go: chi, zap, testify │ -╰──────────────────────────────────────────────────────────────╯ - -Backend ════════════════════════════════════════════════════ - server ───▶ validate ───▶ rules, config - api ───▶ handlers, middleware - -HUBS: config (12←), api (8←), utils (5←) -``` - -### Blast radius - -Who breaks if you change a file: - -```bash -codemap --importers config/config.go -``` - -``` -⚠️ HUB FILE: config/config.go - Imported by 21 files - changes have wide impact! - - Dependents: - • cmd/hooks.go - • mcp/find_guidance.go - ... -``` - -For a review bundle in one command — Markdown, text, or a single JSON object: - -```bash -codemap blast-radius --ref main . -codemap blast-radius --json --ref main . -codemap blast-radius --text --ref main . -``` - -### Skyline - -```bash -codemap --skyline --animate -``` - -![codemap skyline](assets/skyline-animated.gif) - -### Remote repos - -Analyze any public GitHub or GitLab repo without cloning it yourself: - -```bash -codemap github.com/anthropics/anthropic-cookbook -codemap gitlab.com/user/repo -``` - -Shallow-clones to a temp directory and cleans up. If you already have the repo locally, codemap uses your copy. ## Agent integration -### Hooks - -Automatic context at session start, before and after edits, and at compaction. -→ See [docs/HOOKS.md](docs/HOOKS.md) - -The prompt-submit hook classifies intent, surfaces hub-file risk, shows your working set, matches relevant skills, and emits structured markers (``) for tool consumption. - -### MCP - -`codemap setup` registers the MCP server for each agent; `codemap mcp` serves 19 tools over stdio. When it is registered, hook nudges name the matching tool next to the CLI command, for example `codemap --importers X (MCP: get_importers)`. - -| Category | Tools | -|----------|-------| -| Structure | `get_structure`, `find`, `find_file`, `get_hubs`, `get_file_context` | -| Dependencies | `get_dependencies`, `get_importers`, `get_diff` | -| Topology | `get_topology`, `get_module_context` | -| Session | `get_working_set`, `get_activity`, `get_handoff` | -| Daemon | `start_watch`, `stop_watch`, `status` | -| Skills | `list_skills`, `get_skill` | -| Discovery | `list_projects` | - -`get_structure`, `get_diff`, `get_importers`, `get_dependencies`, and `get_handoff` declare an `OutputSchema` and return typed structured content alongside the text response, so callers get parseable results instead of prose. - -### Codex - -`codemap setup` configures Codex when it detects it. Codex asks you to trust the hooks once from `/hooks`, even at user scope. The plugin is an optional extra that adds the skills to Codex: - -```bash -codemap setup --agent codex # user-scope hooks + MCP in ~/.codex -codemap plugin install # optional global plugin (MCP + skills), activated by default -codemap doctor --agent codex # validate; reports CLI and Desktop runtimes separately -``` - -**After upgrading the codemap binary**, agent integrations do not update themselves: - -```bash -codemap plugin install # Codex only, once per Codex environment -cd /path/to/project && codemap setup && codemap doctor # both agents, per project -``` - -`codemap plugin install` refreshes the plugin for CLI and Desktop sharing a Codex environment, and migrates the current project when run inside one — but it does not discover every configured project. Start a new task or session afterward, and re-check hook trust if Codex asks. - -> `codemap doctor` probes executables recorded in project-local config (`.codex/config.toml`, `.mcp.json`), so running it inside an untrusted repo executes a repo-chosen path. Doctor bounds this by requiring absolute paths and a recognized argument shape, but treat it like any command that honors project-local config. - -## Project config - -Per-project defaults in `.codemap/config.json`, so you don't pass `--only`/`--exclude`/`--depth` every time. Hooks respect it too. - -```bash -codemap config init # auto-detect top extensions, write config -codemap config show # display current config -``` - -```json -{ - "only": ["rs", "sh", "sql", "toml", "yml"], - "exclude": ["docs/reference", "docs/research"], - "depth": 4, - "max_files": 100000, - "mode": "auto", - "guidance": { - "missing_extension_hints": true, - "ignored_extensions": [] - }, - "budgets": { - "session_start_bytes": 30000, - "diff_bytes": 15000, - "max_hubs": 8 - }, - "routing": { - "retrieval": { "strategy": "keyword", "top_k": 3 }, - "subsystems": [ - { - "id": "watching", - "paths": ["watch/**"], - "keywords": ["hook", "daemon", "events"], - "docs": ["docs/HOOKS.md"], - "agents": ["codemap-hook-triage"] - } - ] - }, - "drift": { - "enabled": true, - "recent_commits": 10, - "require_docs_for": ["watching"] - } -} -``` - -All fields are optional. `--only` and `--depth` override the config's values for one run; `--exclude` adds to the config's `exclude` list, so a config exclude keeps applying when you pass more patterns on the command line. Exclude patterns follow `.gitignore` anchors: a bare name (`tool`) matches at any depth, `/tool` only the root entry, `tool/` only directories, and `/tool/` only the root directory, so a built binary at the root can be excluded without losing `cmd/tool/`. When an MCP file search finds real matches hidden by `only`, codemap reports the paths and suggests which extensions to add — set `guidance.missing_extension_hints: false` to disable. - -## Skills - -Markdown files that give agents context-aware guidance, matched against intent, mentioned files, and project languages. - -```bash -codemap skill list -codemap skill show hub-safety -codemap skill init # custom skill template -``` - -| Builtin | Activates when | -|---------|---------------| -| `hub-safety` | Editing hub files (3+ importers) | -| `refactor` | Restructuring, renaming, moving code | -| `test-first` | Writing tests, TDD workflows | -| `explore` | Understanding how code works | -| `handoff` | Switching between AI agents | -| `config-setup` | `.codemap/config.json` is missing, boilerplate, or mismatched to the stack | - -Drop a `.md` file with YAML frontmatter in `.codemap/skills/` to add your own — project-local skills override builtins, no Go code required: - -```yaml ---- -name: my-skill -description: When this skill should activate -keywords: ["relevant", "keywords"] -languages: ["go"] ---- - -# Instructions for the AI agent -``` - -## Context protocol - -One command that gives any AI tool codemap's full intelligence: - -```bash -codemap context # full JSON envelope -codemap context --for "refactor auth" # with pre-classified intent + matched skills -codemap context --compact # minimal, for token-constrained agents -``` - -Returns a `ContextEnvelope` with project metadata, dependency-graph evidence, intent classification, working set, matched skills, and a handoff reference. If fresh graph evidence is unavailable, hub counts are `null` and risk is `unknown` instead of being inferred from stale state. Anything that can shell out gets code-aware context. - -## HTTP API - -```bash -codemap serve --port 9471 -``` - -| Endpoint | Returns | -|----------|---------| -| `GET /api/context?intent=refactor+auth` | Full context envelope | -| `GET /api/context?compact=true` | Minimal envelope | -| `GET /api/skills` | All skills with metadata | -| `GET /api/skills?language=go&category=refactor` | Filtered skill matches | -| `GET /api/skills/` | Full skill body | -| `GET /api/working-set` | Current session's active files | -| `GET /api/health` | Health check | - -Binds to `127.0.0.1`; use `--host 0.0.0.0` to expose. - -## Cross-agent handoff - -When you switch agents (Claude → Codex → Cursor), codemap tracks who worked and what they touched: - -```json -{ - "agent_history": [ - {"agent_id": "claude-code", "files_edited": ["cmd/hooks.go", "main.go"], "ended_at": "..."}, - {"agent_id": "codex", "files_edited": ["scanner/types.go"], "ended_at": "..."} - ] -} -``` - -Agent detection is automatic via environment variables. History carries across sessions, capped at 20 entries, in `.codemap/handoff.latest.json`. +- **Hooks**: automatic context at session start, before and after edits, and at compaction. [docs/HOOKS.md](docs/HOOKS.md) +- **MCP**: `codemap mcp` serves 19 tools over stdio. [docs/MCP.md](docs/MCP.md) +- **Codex**: `codemap setup` configures it; trust the hooks once from `/hooks`. [docs/MCP.md](docs/MCP.md#codex) + +## Go deeper + +| I want to | Read | +|-----------|------| +| install in CI or from a tarball | [docs/INSTALL.md](docs/INSTALL.md) | +| wire up my agent | [docs/HOOKS.md](docs/HOOKS.md) | +| trust the dependency numbers | [docs/RESOLUTION.md](docs/RESOLUTION.md) | +| see every flag and mode | [docs/COMMANDS.md](docs/COMMANDS.md) | +| tune what the agent sees | [docs/CONFIG.md](docs/CONFIG.md) | +| use the MCP tools or Codex | [docs/MCP.md](docs/MCP.md) | +| add a language | [CONTRIBUTING.md](CONTRIBUTING.md#adding-a-new-language) | ## Roadmap diff --git a/assets/codemap.png b/assets/codemap.png index 1cfd7a79..187a36e2 100644 Binary files a/assets/codemap.png and b/assets/codemap.png differ diff --git a/docs/COMMANDS.md b/docs/COMMANDS.md new file mode 100644 index 00000000..8bfc82e4 --- /dev/null +++ b/docs/COMMANDS.md @@ -0,0 +1,166 @@ +# Commands + +This doc answers: what does every codemap command, flag and mode do? + +```bash +codemap . # structure view (respects .codemap/config.json) +codemap --diff # what changed vs main +codemap --deps . # dependency flow +codemap --importers f # who imports a file +codemap blast-radius # review bundle: diff + deps + importers +codemap collide # rank open PRs by shared-file merge-order hazard +codemap find "" # where is X defined: rank by path, symbol names, then body text ("(body)" tag), with importer counts +codemap handoff . # save layered handoff for cross-agent continuation +codemap context # machine-readable project context JSON +codemap doctor # validate agent integrations +codemap skill list # available agent skills +codemap watch start # background daemon for live graph state +codemap serve # HTTP API for non-MCP integrations +codemap mcp # MCP server on stdio +codemap --version +``` + +## Options + +Standard linked Git worktrees automatically reuse the primary worktree's +`.codemap/config.json` and project skills. Create the worktree with Git, an IDE, +or any manager that uses standard linked-worktree metadata, then give the agent +its absolute path: + +```bash +git worktree add -b +codemap -C /tmp/feature-worktree context +``` + +Normal CLI and plugin MCP calls need no `--setup-root`: central config and skills +come from the primary worktree, while handoffs, watcher files, and hook/session +state remain in the linked worktree. Independent clones have no trusted Git +metadata linking them, so sharing setup between them still requires an explicit +override: + +```bash +codemap -C /tmp/independent-clone --setup-root /path/to/original context +``` + +`-C`/`--project-root` operates on exactly the named directory, like `git -C`; +it may be a subdirectory of a repository, and storage and config discovery still +walk up to the git root. `--setup-root` explicitly reuses `/.codemap` +policy and runtime state from another checkout. Both accept a repository or +subdirectory; relative setup paths resolve from the project root. + +| Flag | Description | +|------|-------------| +| `-C, --project-root ` | Operate on exactly `` (may be a subdirectory of a repository; storage and config discovery still walk up to the git root) | +| `--setup-root ` | Explicitly reuse policy and runtime state from `/.codemap` | +| `--depth, -d ` | Limit tree depth (0 = unlimited) | +| `--only ` | Only include files with these extensions | +| `--exclude ` | Exclude files matching patterns | +| `--max-files ` | Scan bound: files kept by the tree, and the largest repo a dependency scan runs on (default 100000, or config `max_files`; `-1` = unbounded). Above it the output says `bounded: scanned N of M files` instead of presenting a prefix as the repo | +| `--diff` | Show files changed vs main branch | +| `--ref ` | Branch to compare against (with `--diff`) | +| `--include-untracked` | With `--diff --ref`: also list untracked files | +| `--deps` | Dependency flow mode | +| `--stdin` | Read JSON file manifest from stdin (use with `--deps`) | +| `--importers ` | Check who imports a file | +| `--hubs` | List hub files (3+ importers) | +| `--file ` | Imports, importers, and hub status for one file | +| `--topology` | Project/module dependency topology | +| `--module ` | Context for one module ID or unique name | +| `--module-file ` | Context for the module owning a file | +| `--ecosystem ` | Filter topology by provider | +| `--skyline` | City skyline visualization | +| `--animate` | Animate the skyline (with `--skyline`) | +| `--json` | Output JSON | +| `--debug` | Show scanner and path diagnostics | +| `--color ` | `auto` (default): ANSI colour only when stdout is a terminal and `NO_COLOR` is unset; `always` keeps colour when piping into `less -R`; `never` turns it off | + +> Flags come before the path/URL: `codemap --json github.com/user/repo` + +**Pattern matching** needs no quotes: `.png` matches any `.png` file, `Fonts` matches any `/Fonts/` directory, `*Test*` is a glob. + +## Modes + +### Diff + +```bash +codemap --diff +codemap --diff --ref develop +``` + +``` +╭─────────────────────────── myproject ──────────────────────────╮ +│ Changed: 4 files | +156 -23 lines vs main │ +╰────────────────────────────────────────────────────────────────╯ +├── api/ +│ └── (new) auth.go ✎ handlers.go (+45 -12) +└── ✎ main.go (+29 -3) + +⚠ handlers.go is used by 3 other files +``` + +### Dependency flow + +```bash +codemap --deps . +``` + +``` +╭──────────────────────────────────────────────────────────────╮ +│ MyApp - Dependency Flow │ +├──────────────────────────────────────────────────────────────┤ +│ Go: chi, zap, testify │ +╰──────────────────────────────────────────────────────────────╯ + +Backend ════════════════════════════════════════════════════ + server ───▶ validate ───▶ rules, config + api ───▶ handlers, middleware + +HUBS: config (12←), api (8←), utils (5←) +``` + +### Blast radius + +Who breaks if you change a file: + +```bash +codemap --importers config/config.go +``` + +``` +⚠️ HUB FILE: config/config.go + Imported by 42 files (package codemap/config: Go imports name packages, not files) - changes have wide impact! + + Dependents: + • blast_radius.go + • blast_radius_fixes_test.go + ... +``` + +For a review bundle in one command, as Markdown, text, or a single JSON object: + +```bash +codemap blast-radius --ref main . +codemap blast-radius --json --ref main . +codemap blast-radius --text --ref main . +``` + +### Skyline + +```bash +codemap --skyline --animate +``` + +![codemap skyline](../assets/skyline-animated.gif) + +### Remote repos + +Analyze any public GitHub or GitLab repo without cloning it yourself: + +```bash +codemap github.com/anthropics/anthropic-cookbook +codemap gitlab.com/user/repo +``` + +Shallow-clones to a temp directory and cleans up. If you already have the repo locally, codemap uses your copy. + +Next: [tune what the agent sees](CONFIG.md) diff --git a/docs/CONFIG.md b/docs/CONFIG.md new file mode 100644 index 00000000..10f57c67 --- /dev/null +++ b/docs/CONFIG.md @@ -0,0 +1,129 @@ +# Config, skills and integrations + +This doc answers: how do I tune what codemap shows an agent, add skills, and feed its context to tools that are not MCP clients? + +## Project config + +Per-project defaults in `.codemap/config.json`, so you don't pass `--only`/`--exclude`/`--depth` every time. Hooks respect it too. + +```bash +codemap config init # auto-detect top extensions, write config +codemap config show # display current config +``` + +```json +{ + "only": ["rs", "sh", "sql", "toml", "yml"], + "exclude": ["docs/reference", "docs/research"], + "depth": 4, + "max_files": 100000, + "mode": "auto", + "guidance": { + "missing_extension_hints": true, + "ignored_extensions": [] + }, + "budgets": { + "session_start_bytes": 30000, + "diff_bytes": 15000, + "max_hubs": 8 + }, + "routing": { + "retrieval": { "strategy": "keyword", "top_k": 3 }, + "subsystems": [ + { + "id": "watching", + "paths": ["watch/**"], + "keywords": ["hook", "daemon", "events"], + "docs": ["docs/HOOKS.md"], + "agents": ["codemap-hook-triage"] + } + ] + }, + "drift": { + "enabled": true, + "recent_commits": 10, + "require_docs_for": ["watching"] + } +} +``` + +All fields are optional. `--only` and `--depth` override the config's values for one run; `--exclude` adds to the config's `exclude` list, so a config exclude keeps applying when you pass more patterns on the command line. Exclude patterns follow `.gitignore` anchors: a bare name (`tool`) matches at any depth, `/tool` only the root entry, `tool/` only directories, and `/tool/` only the root directory, so a built binary at the root can be excluded without losing `cmd/tool/`. When an MCP file search finds real matches hidden by `only`, codemap reports the paths and suggests which extensions to add; set `guidance.missing_extension_hints: false` to disable. + +## Skills + +Markdown files that give agents context-aware guidance, matched against intent, mentioned files, and project languages. + +```bash +codemap skill list +codemap skill show hub-safety +codemap skill init # custom skill template +``` + +| Builtin | Activates when | +|---------|---------------| +| `hub-safety` | Editing hub files (3+ importers) | +| `refactor` | Restructuring, renaming, moving code | +| `test-first` | Writing tests, TDD workflows | +| `explore` | Understanding how code works | +| `handoff` | Switching between AI agents | +| `config-setup` | `.codemap/config.json` is missing, boilerplate, or mismatched to the stack | + +Drop a `.md` file with YAML frontmatter in `.codemap/skills/` to add your own. Project-local skills override builtins, no Go code required: + +```yaml +--- +name: my-skill +description: When this skill should activate +keywords: ["relevant", "keywords"] +languages: ["go"] +--- + +# Instructions for the AI agent +``` + +## Context protocol + +One command that gives any AI tool codemap's full intelligence: + +```bash +codemap context # full JSON envelope +codemap context --for "refactor auth" # with pre-classified intent + matched skills +codemap context --compact # minimal, for token-constrained agents +``` + +Returns a `ContextEnvelope` with project metadata, dependency-graph evidence, intent classification, working set, matched skills, and a handoff reference. If fresh graph evidence is unavailable, hub counts are `null` and risk is `unknown` instead of being inferred from stale state. Anything that can shell out gets code-aware context. + +## HTTP API + +```bash +codemap serve --port 9471 +``` + +| Endpoint | Returns | +|----------|---------| +| `GET /api/context?intent=refactor+auth` | Full context envelope | +| `GET /api/context?compact=true` | Minimal envelope | +| `GET /api/skills` | All skills with metadata | +| `GET /api/skills?language=go&category=refactor` | Filtered skill matches | +| `GET /api/skills/` | Full skill body | +| `GET /api/working-set` | Current session's active files | +| `GET /api/health` | Health check | + +Binds to `127.0.0.1`; use `--host 0.0.0.0` to expose. + +## Cross-agent handoff + +When you switch agents (Claude → Codex → Cursor), codemap tracks who worked and what they touched: + +```json +{ + "agent_history": [ + {"agent_id": "claude-code", "files_edited": ["cmd/hooks.go", "main.go"], "ended_at": "..."}, + {"agent_id": "codex", "files_edited": ["scanner/types.go"], "ended_at": "..."} + ] +} +``` + +Agent detection is automatic via environment variables. History carries across sessions, capped at 20 entries, in `.codemap/handoff.latest.json`. + +Next: [MCP tools and Codex](MCP.md) diff --git a/docs/HOOKS.md b/docs/HOOKS.md index 4faf6ea9..bf3f112d 100644 --- a/docs/HOOKS.md +++ b/docs/HOOKS.md @@ -1,5 +1,7 @@ # Codemap Hooks +This doc answers: what does codemap show my agent automatically, when, and how do I configure it? + Hooks give Claude Code and Codex automatic codebase context throughout a session or task. ## The Full Experience @@ -469,3 +471,5 @@ The 8-second hook timeout prevents any single hook from blocking Claude. 4. You should see project structure at the top 5. Ask the agent to edit a core file - watch for hub warnings 6. End your session and see the summary + +Next: [how codemap resolves dependencies](RESOLUTION.md) diff --git a/docs/INSTALL.md b/docs/INSTALL.md new file mode 100644 index 00000000..fc4522b3 --- /dev/null +++ b/docs/INSTALL.md @@ -0,0 +1,73 @@ +# Install and setup + +This doc answers: how do I install codemap outside Homebrew or Scoop, what does `codemap setup` change, and how do I check it worked? + +Homebrew and Scoop one-liners are in the [README](../README.md#install). Other options: [Releases](https://github.com/JordanCoin/codemap/releases) | `go install` | build from source. + +## CI / tarball install + +Release tarballs ship `codemap` and the bundled rules but not the `ast-grep` executable, which `--deps` needs. Either install it separately: + +```bash +apk add --no-cache curl jq bash python3 py3-pip + +ARCH=$(uname -m) +if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; elif [ "$ARCH" = "aarch64" ]; then ARCH="arm64"; fi + +CODEMAP_VERSION=$(curl -fsSL https://api.github.com/repos/JordanCoin/codemap/releases/latest | jq -r '.tag_name' | tr -d 'v') +curl -fsSL "https://github.com/JordanCoin/codemap/releases/download/v${CODEMAP_VERSION}/codemap_${CODEMAP_VERSION}_linux_${ARCH}.tar.gz" \ + | tar xz -C /usr/local/bin/ codemap + +python3 -m pip install --no-cache-dir ast-grep-cli +``` + +…or use the self-contained `codemap-full` artifact, which bundles `codemap`, `ast-grep`, and `sg`: + +```bash +curl -fsSL "https://github.com/JordanCoin/codemap/releases/download/v${CODEMAP_VERSION}/codemap-full_${CODEMAP_VERSION}_linux_${ARCH}.tar.gz" \ + | tar xz -C /usr/local/bin/ codemap ast-grep sg +``` + +## Setup + +Run setup anywhere inside your git repo. Repo-scoped commands such as +`setup`, `doctor`, `config`, `watch`, `skill`, `context`, `serve`, and +managed hooks resolve the nearest git root automatically, including linked +worktrees with a `.git` file. + +```bash +cd /path/to/your/project +codemap setup +``` + +`codemap setup` configures the agents it detects: Claude Code when `~/.claude`, `~/.claude.json`, or `claude` on `PATH` exists, Codex when `~/.codex` or `codex` on `PATH` exists, and both when it finds neither. It: + +- creates `.codemap/config.json` with auto-detected language filters +- merges Claude hooks into `.claude/settings.local.json` and configures MCP in `.mcp.json` (project scope) +- merges Codex hooks into `~/.codex/hooks.json` and configures MCP in `~/.codex/config.toml` (user scope, since Codex skips a project's `.codex/` until the project is trusted; `--project` writes `.codex/` instead) +- writes the builtin skills to `.claude/skills/` for Claude, keeping any skill file you edited +- hooks start and read daemon state at session start + +Rerunning setup is safe: it changes only what is missing or stale. `--no-config`, `--no-hooks`, `--no-mcp`, and `--no-skills` skip a piece. + +Managed entries record the verified absolute path of the running `codemap`, so agents don't depend on your shell `PATH`. Rerun setup if that path changes. + +```bash +codemap setup --agent claude # one agent only +codemap setup --agent codex +codemap setup --global # Claude at user scope too (~/.claude), applies to every project +codemap setup --project # Codex at project scope (.codex/) instead of ~/.codex +``` + +After a `brew upgrade`, the session-start hook prints one line naming any integration still stamped with the old version and the command that refreshes it. + +## Verify + +```bash +codemap doctor # validate this project's integrations +codemap doctor --global # validate user-scope configuration +``` + +Doctor checks project scope and falls back to user scope, reporting which one satisfied each check. For Codex, trust the hooks from `/hooks` in CLI or Settings → Hooks in Desktop, then start a new session. + +Next: [what the hooks show your agent](HOOKS.md) diff --git a/docs/MCP.md b/docs/MCP.md index d56b5b79..6cfd7815 100644 --- a/docs/MCP.md +++ b/docs/MCP.md @@ -1,5 +1,7 @@ # Codemap MCP Server +This doc answers: how do I run codemap as an MCP server, what tools does it expose, and how do I wire up and upgrade Codex? + Run codemap as an MCP server for Claude Code, Codex, or another MCP client. ## Setup @@ -12,18 +14,36 @@ codemap setup --agent claude # Configure only Claude Code codemap setup --agent codex # Configure only Codex ``` -Setup writes a managed, versioned absolute executable path. After upgrading or -moving Codemap, Codex plugin users should run `codemap plugin install` first, -then rerun setup in each configured project. Claude users skip plugin -installation but still rerun setup. Use `codemap doctor` for strict validation; -it reports Codex CLI and Desktop runtimes independently. Agent integrations do -not automatically refresh the generated local plugin or per-project setup. -For a manual, PATH-dependent Claude definition: +Setup writes a managed, versioned absolute executable path, so after upgrading +or moving Codemap you rerun it in each configured project; the steps, including +the Codex plugin refresh, are under [Codex](#codex). Use `codemap doctor` for +strict validation. For a manual, PATH-dependent Claude definition: ```bash claude mcp add --transport stdio codemap -- codemap mcp ``` +### Codex + +`codemap setup` configures Codex when it detects it. Codex asks you to trust the hooks once from `/hooks`, even at user scope. The plugin is an optional extra that adds the skills to Codex: + +```bash +codemap setup --agent codex # user-scope hooks + MCP in ~/.codex +codemap plugin install # optional global plugin (MCP + skills), activated by default +codemap doctor --agent codex # validate; reports CLI and Desktop runtimes separately +``` + +**After upgrading the codemap binary**, agent integrations do not update themselves: + +```bash +codemap plugin install # Codex only, once per Codex environment +cd /path/to/project && codemap setup && codemap doctor # both agents, per project +``` + +`codemap plugin install` refreshes the plugin for CLI and Desktop sharing a Codex environment, and migrates the current project when run inside one, but it does not discover every configured project. Start a new task or session afterward, and re-check hook trust if Codex asks. + +> `codemap doctor` probes executables recorded in project-local config (`.codex/config.toml`, `.mcp.json`), so running it inside an untrusted repo executes a repo-chosen path. Doctor bounds this by requiring absolute paths and a recognized argument shape, but treat it like any command that honors project-local config. + ### Build ```bash @@ -105,7 +125,11 @@ Both values may be repository roots or subdirectories. An explicit `--setup-root` preserves the existing shared policy-and-runtime-state behavior, and managed MCP definitions created while it is active retain it automatically. -## Available Tools (17) +## Available Tools (19) + +`codemap mcp` serves 19 tools over stdio. When it is registered, hook nudges name the matching tool next to the CLI command, for example `codemap --importers X (MCP: get_importers)`. + +`get_structure`, `get_diff`, `get_importers`, `get_dependencies`, and `get_handoff` declare an `OutputSchema` and return typed structured content alongside the text response, so callers get parseable results instead of prose. ### Project Analysis @@ -114,11 +138,19 @@ and managed MCP definitions created while it is active retain it automatically. | `get_structure` | Project tree view with file sizes and language detection, tests folded into their source, plus the hub list | | `get_dependencies` | Dependency flow with imports, functions, and hub files | | `get_diff` | Changed files with line counts and impact analysis | +| `find` | Rank files by path and function/type names, then body text (`(body)` tag), with importer count and hub status per hit | | `find_file` | Find files by name pattern | | `get_importers` | Find all files that import a specific file | | `get_hubs` | List all hub files (3+ importers) with dependent counts | | `get_file_context` | Complete dependency context for one file (imports, importers, hub status, connected files) | +### Topology + +| Tool | Description | +|------|-------------| +| `get_topology` | Project/module topology from build manifests: module dependencies, dependents, hubs, membership, evidence, and coverage | +| `get_module_context` | Dependency context for one exact module ID, unique module name, or repository-relative file owner; ambiguous names return candidate IDs | + ### Watch Daemon | Tool | Description | @@ -184,3 +216,5 @@ Output and budget notes: Cancellation notes: - project scans, dependency graphs, ast-grep, Git diff/impact work, project discovery, and generated handoff/detail work stop with the MCP request context - with `save=true`, cancellation observed after generation but before persistence prevents `WriteLatest`; once persistence begins, the existing multi-file write completes or reports its existing error without rollback + +Next: [back to the README](../README.md) diff --git a/docs/RESOLUTION.md b/docs/RESOLUTION.md new file mode 100644 index 00000000..a5063fc0 --- /dev/null +++ b/docs/RESOLUTION.md @@ -0,0 +1,57 @@ +# Dependency resolution + +This doc answers: how does codemap decide what imports what, how much of each answer does it stand behind, and which languages does it cover? + +`--deps` and `--importers` resolve imports using each ecosystem's own rules rather than guessing from paths: + +| Ecosystem | Resolved via | +|-----------|--------------| +| **Go** | module path from `go.mod`; stdlib and third-party imports are not fuzzy-matched into local files | +| **Rust** | `cargo metadata`: workspace membership, target kinds (lib/bin/test/bench/example/build), and `dev-dependencies` reachable from `#[cfg(test)]` blocks | +| **JS/TS** | `package.json` `exports`/`imports` maps, npm/pnpm/Bun workspaces, Deno import maps, and `tsconfig` `rootDir`/`outDir` remapping (including `extends`) | +| **Dart/Flutter** | `pubspec.yaml` package names and declared dependencies; `package:` URIs resolve within the owning package's `lib/`, while undeclared or duplicate package names fail closed | +| **Everything else** | ast-grep import extraction with suffix and directory matching | + +## The coverage contract + +Every dependency answer reports how much of it codemap actually stands behind: + +```bash +codemap --json --deps . | jq .coverage +``` + +```json +{ + "status": "partial", + "sources": [ + { "name": "ast-grep", "status": "authoritative", + "languages": ["bash", "c", "cpp", "csharp", "dart", "elixir", "go", "java", "javascript", "kotlin", "lua", "php", "python", "ruby", "rust", "scala", "solidity", "swift", "typescript"] }, + { "name": "cargo-metadata", "status": "mixed", + "detail": "2 of 5 Cargo manifests used fallback topology", + "languages": ["rust"] } + ], + "issues": [ + { "code": "unresolved-import", "path": "src/app.ts", + "message": "import ./gone resolved to no file in the project" } + ] +} +``` + +`issues` lists each project-relative import that resolved to no file, one entry per reference. The key is omitted when there are none. + +- `status` is `complete`, `partial`, or `unavailable`. +- Each source reports `authoritative`, `mixed`, `fallback`, `timeout`, `unavailable`, or `failed`. +- `languages` names the languages a source can affect. Per-file answers (`--importers`, `get_importers`, `get_file_context`, the importer sections of `blast-radius`) keep only the sources tagged with the file's language, plus untagged sources, which apply everywhere. A Go file in a Go+Rust repo reads `complete` with no Rust caveat; `--deps` keeps the scan-level rollup. +- A timed-out or failed scan returns an **empty result with provenance**, not a silent empty graph and not a hard error, so an agent can tell "nothing imports this" apart from "I couldn't tell". + +The JSON payload is versioned (`schema_version: codemap.analysis/v1`) so consumers can depend on its shape. + +## Supported languages + +21 ast-grep language rules for dependency analysis: Go, Python, JavaScript, JSX, TypeScript, TSX, Rust, Ruby, C, C++, Java, Swift, Dart, Kotlin, C#, PHP, Bash, Lua, Scala, Elixir, Solidity. Dart projects, including Flutter apps and packages, also get `pubspec.yaml` dependency discovery. CUE files also contribute module-scoped package edges through lexical import extraction; CUE is not an ast-grep rule. + +> Powered by [ast-grep](https://ast-grep.github.io/). Installed automatically with the Homebrew formula. + +To add a language, see [CONTRIBUTING.md](../CONTRIBUTING.md#adding-a-new-language). + +Next: [every command, flag and mode](COMMANDS.md) diff --git a/docs/SESSION-LEDGER-CODEX-REVIEW.md b/docs/design/SESSION-LEDGER-CODEX-REVIEW.md similarity index 100% rename from docs/SESSION-LEDGER-CODEX-REVIEW.md rename to docs/design/SESSION-LEDGER-CODEX-REVIEW.md diff --git a/docs/SESSION-LEDGER-SPEC.md b/docs/design/SESSION-LEDGER-SPEC.md similarity index 99% rename from docs/SESSION-LEDGER-SPEC.md rename to docs/design/SESSION-LEDGER-SPEC.md index fab037bc..6a0d4c4f 100644 --- a/docs/SESSION-LEDGER-SPEC.md +++ b/docs/design/SESSION-LEDGER-SPEC.md @@ -1,7 +1,7 @@ # codemap session ledger, spec v1 Status: proposal, revised after Codex's interrogation of v0 -(docs/SESSION-LEDGER-CODEX-REVIEW.md, 31 items). Items 1 to 27 are applied +(docs/design/SESSION-LEDGER-CODEX-REVIEW.md, 31 items). Items 1 to 27 are applied below and referenced as [C-n]; cuts 28 to 30 are applied. Nothing is built. Every claim about current behaviour names where it was checked on 2026-10-11 at main 253c8d6.