demirmusa/nanocontext

GitHub: demirmusa/nanocontext

一个基于 Tree-sitter 与向量搜索的代码索引系统,解决 AI 代理在大型项目中重复读取与上下文不一致问题。

Stars: 0 | Forks: 0

# NanoContext **为你的 AI 代理提供整个代码库的路线图。** Tree-sitter AST 解析 · 语义向量搜索 · AI 代理的 MCP 服务器 [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![MCP](https://img.shields.io/badge/MCP-compatible-purple)](https://modelcontextprotocol.io/)
NanoContext 使用 tree-sitter 解析你的代码库,为每个类、方法、导入和导出构建结构化索引,然后通过 MCP 服务器将其全部暴露出来。你的 AI 代理可以进行语义搜索、读取精确的代码范围、跟随调用图,并在无需读取每个文件的情况下记住项目上下文。 **兼容:** VS Code Copilot · Claude Code · Cursor · Windsurf · Gemini CLI · Codex CLI ## 快速开始 ``` # 安装 git clone https://github.com/demirmusa/nanocontext.git cd nanocontext && npm install && npm run build && npm link # 在你的项目中 cd /path/to/your/project nc init # interactive setup wizard nc scan # index the codebase nc s "auth" # search instantly ``` 仅此而已。你的 AI 代理现在可以访问 MCP 工具来导航你的代码。 ## 问题 AI 编码代理功能强大,但在真实项目中会遇到两个障碍: **1. 令牌浪费。** 一个探索 500 个文件的代理逐个读取文件以了解结构。每读取一个文件都会消耗令牌。在会话期间,相同的文件会被多次重复读取,因为代理没有持久的映射来知道内容的位置。在大型项目上这会迅速累积——响应变慢、成本增加,并且更快达到上下文限制。 **2. 不一致性。** 没有结构化的概览,代理做出的更改可能在本地有效但会破坏其他地方的约定。它们会忽略已存在的帮助函数、重复逻辑,或调用具有错误签名的方法——因为它们从未见过定义它的文件。项目越大,问题越严重。 ## NanoContext 如何解决这一点 NanoContext 在预处理阶段将整个代码库转换为紧凑、可搜索的索引,代理可以即时查询——而不是读取原始文件: - **结构优于源码** — 不需要读取 400 行的文件来查找一个方法签名,代理查询索引即可在少数令牌内获得所需内容。每个类、方法、导入、导出和调用引用都通过 tree-sitter AST 解析提取(而非正则表达式)。 - **搜索代替扫描** — 语义向量搜索、精确文本匹配和正则表达式让代理在数毫秒内找到相关代码,无需打开文件并“希望”。 - **持久记忆** — 代理可以存储并回忆项目笔记、设计决策和约定,跨会话无需重复自己。 - **始终新鲜** — 观察模式会在保存时自动索引文件,保持索引与代码同步,无需人工干预。 结构阶段是**免费且确定性的**—不需要 LLM。可选启用 AI Insight 以生成每个方法的关键词摘要,从而提升搜索相关性。 ## 安装 ``` git clone https://github.com/demirmusa/nanocontext.git cd nanocontext npm install npm run build npm link # makes 'nc' available globally ``` **要求:** Node.js >= 18.0.0 ## 用法 ### 初始化项目 ``` cd /path/to/your/project nc init ``` 向导会引导你完成: 1. 选择 AI 代理(VS Code Copilot、Claude、Cursor、Windsurf、Gemini、Codex) 2. 选择 LLM 提供者(Ollama、OpenAI、Anthropic 或无) 3. 选择嵌入提供者(Ollama、OpenAI 或无) 它会创建: | 文件 | 用途 | Git | |------|---------|-----| | `nanocontextconfig.json` | 语言、包含/排除通配符、设置 | 跟踪 | | `.nanocontext/config.json` | API 密钥、提供者配置 | 忽略 | | `.nanocontextignore` | 排除模式(类似 .gitignore) | 跟踪 | | `.vscode/mcp.json`、`.mcp.json` 等 | 每个代理的 MCP 配置(工作区本地、可移植) | 跟踪 | | `.github/copilot-instructions.md` 等 | 代理指令文件 | 跟踪 | ### 扫描与同步 ``` nc scan # full scan (skips unchanged files) nc scan -f src/auth.ts # scan specific file nc scan --resume # resume interrupted scan nc scan --rebuild-vectors # regenerate all vector embeddings ``` ### 搜索 ``` nc s "LoginService" # exact text search (default) nc s "get.*User" -r # regex on names/signatures nc s "authentication logic" -v # semantic vector search nc s "database connection" -v -d # deep vector search (full header data) nc s "error handling" -l 10 # limit results (default: 3) ``` ### 读取代码 ``` nc g src/auth/login.ts[15-40] # get lines 15-40 with line numbers nc inspect src/core/Container.ts # full parsed structure of a file ``` ### 观察变更 ``` nc watch # auto-index on file save nc watch stop # stop from another terminal ``` 观察模式会逐步显示每个流水线步骤的实时进度: ``` 14:30:05 src/auth/login.ts → tree-sitter 14:30:05 src/auth/login.ts ✓ +1 ~2 -0 ``` ### 项目记忆 ``` nc remember "Auth uses JWT with RS256 signing" nc remember "Redis TTL is 5min" --ref "src/cache/redis.ts" nc memories # list all nc memories --search "auth" # search nc forget mem_abc123 # delete nc forget --before 2026-01-01 # bulk delete older memories ``` ### 状态 ``` nc status ``` ``` NanoContext Status Files indexed: 142 Methods: 1,205 Vectors: 1,205 Insight queue: 0 AI Insight: enabled Languages: typescript, javascript ``` ## MCP 集成 ### 设置 `nc init` 会为你选择的每个代理自动生成 MCP 配置: | 代理 | 配置文件 | |------|----------| | VS Code Copilot | `.vscode/mcp.json` | | Claude Code | `.mcp.json` | | Cursor | `.cursor/mcp.json` | | Windsurf | `.windsurf/mcp.json` | | Gemini CLI | `.gemini/settings.json` | | Codex CLI | `.codex/config.toml` | 或手动配置: ``` { "mcpServers": { "nanocontext": { "command": "nc", "args": ["mcp-server"] } } } ``` ### MCP 工具 | 工具 | 参数 | 功能 | |------|--------|------| | `search` | `q`, `n?` | 在名称、签名、文件路径上执行精确文本搜索 | | `svec` | `q`, `n?`, `t?` | 语义向量搜索。`t`: 方法 / 类 / 记忆 / 全部 | | `sdeep` | `q`, `n?` | 包含完整数据(签名、引用、洞察)的向量搜索 | | `sreg` | `p`, `n?` | 在名称、签名、文件路径上执行正则搜索 | | `sregdeep` | `p`, `n?` | 包含完整数据的正则搜索(签名、引用、洞察) | | `code` | `f`, `loc` | 按行范围读取源代码(例如 `loc="45-72"`) | | `deps` | `f`, `m`, `d?` | 获取方法的调用引用(`m` = 方法名或 ID,`d` = 深度,最大 3) | | `scan` | `f?` | 扫描项目或特定文件/通配符 | | `remember` | `text`, `ref?` | 保存项目记忆笔记 | | `memories` | `q?`, `id?` | 列出记忆。`id=true` 以包含 ID(用于遗忘) | | `forget` | `id` | 删除一条记忆 | | `status` | — | 索引统计信息 | **响应键已缩短** 以节省令牌:`t`=类型,`f`=文件,`m`=方法,`c`=类,`l`=位置,`s`=分数,`sg`=签名,`i`=洞察,`r`=引用,`x`=文本。 默认搜索限制为 **3**。可通过传递 `n` 覆盖。 ### MCP 资源 | URI | 描述 | |-----|-------------| | `nc://status` | 当前索引统计 | | `nc://memories` | 所有存储的记忆 | | `nc://headers/{file_path}` | 特定文件的头部数据 |

配置

### 项目配置 — `nanocontextconfig.json` 由 `nc init` 创建。提交到 Git。 ``` { "version": 1, "languages": ["typescript", "javascript"], "include": ["src/**/*.ts", "src/**/*.js"], "exclude": ["node_modules", "dist", "*.test.*"], "aiInsight": true, "watch": { "debounceMs": 500 }, "search": { "defaultLimit": 3, "maxLimit": 50 }, "dependencyDepth": 2 } ``` | 字段 | 描述 | |------|---------| | `languages` | 要解析的语言:`typescript`、`javascript`、`csharp` | | `include` | 要索引的文件通配符 | | `exclude` | 要跳过的通配符 | | `aiInsight` | 启用 LLM 关键词生成(第二阶段) | | `watch.debounceMs` | 文件观察器防抖延迟(毫秒) | | `search.defaultLimit` | 默认搜索结果数量 | | `dependencyDepth` | 跟踪调用引用的深度 | ### 用户配置 — `.nanocontext/config.json` Git 忽略。存储 API 密钥和提供者配置。 ``` { "llm": { "provider": "ollama", "endpoint": "http://localhost:11434", "model": "llama3.2" }, "embedding": { "provider": "ollama", "endpoint": "http://localhost:11434", "model": "nomic-embed-text" } } ``` ### 忽略文件 — `.nanocontextignore` 类似 `.gitignore`。每行一个模式: ``` node_modules dist .git *.min.js __tests__ *.spec.ts ```

LLM 提供者

### Ollama(本地,免费) 无需 API 密钥。完全在本地运行。 ``` # 安装: https://ollama.com ollama pull llama3.2 # LLM ollama pull nomic-embed-text # Embeddings ``` ### OpenAI 需要 API 密钥(在 `nc init` 时设置)。 - LLM:`gpt-5-mini-2025-08-07`(推荐) - 嵌入:`text-embedding-3-small` ### Anthropic 需要 API 密钥。仅使用 LLM——嵌入可使用 Ollama 或 OpenAI。 - LLM:`claude-haiku-4-5-20251001`(推荐) ### 无提供者 结构阶段完全无需任何 LLM 或嵌入提供者。你可以获得 AST 解析、精确文本搜索和正则表达式搜索——只是没有语义向量搜索或 AI 生成的洞察。

工作原理

### 两阶段流水线 **阶段 1 — 结构(免费、确定性、无 LLM)** 1. Tree-sitter WASM 解析器提取类、方法、导入、导出 2. 捕获方法签名、行范围、调用引用和装饰器 3. 为每个源文件写入 `.header.json` 文件到 `.nanocontext/headers/` 4. 更新 SQLite 搜索索引以支持精确/正则搜索 5. 生成并存储向量嵌入到 LanceDB(如果配置了嵌入提供者) **阶段 2 — 洞察(可选,LLM 驱动)** 1. 方法排队等待 LLM 处理 2. 将签名和代码发送到配置的 LLM 3. 返回关键词摘要以提升搜索相关性 4. 更新头部文件和向量存储中的洞察 ### 头文件格式 对于每个源文件,`.header.json` 捕获其完整结构: ``` { "file": "src/auth/login.ts", "lang": "typescript", "checksum": "a1b2c3d4", "classes": [ { "name": "AuthService", "loc": "10-85", "extends": "BaseService", "implements": ["IAuthProvider"], "insight": "authentication jwt token validation" } ], "methods": [ { "name": "login", "class": "AuthService", "loc": "15-40", "sig": "public async login(credentials: LoginDto): Promise", "refs": ["validateCredentials", "generateToken", "this.tokenStore.save"], "decorators": ["@Post('/login')"], "insight": "user login credentials validation token generation" } ], "imports": ["jsonwebtoken", "./token-store", "../models/user"], "exports": ["AuthService"] } ``` ### 存储 | 存储 | 后端 | 用途 | |------|---------|------| | `SqliteStateStore` | better-sqlite3 | 校验和、搜索索引、洞察队列、扫描统计 | | `HeaderStore` | JSON 文件 | 每个源文件的 `.header.json` | | `LanceVectorStore` | LanceDB | 向量嵌入用于语义搜索 |

支持的语言

| 语言 | 扩展名 | 解析器 | |------|-----------|--------| | TypeScript | `.ts`、`.tsx` | tree-sitter-typescript | | JavaScript | `.js`、`.jsx`、`.mjs`、`.cjs` | tree-sitter-javascript | | C# | `.cs` | tree-sitter-c-sharp | ### 添加新语言 1. 创建扩展 `BaseLanguageParser` 的解析器: ``` // src/core/parser/languages/MyLangParser.ts import { BaseLanguageParser } from '../BaseLanguageParser'; export class MyLangParser extends BaseLanguageParser { readonly language = 'mylang'; readonly extensions = ['.ml']; protected getWasmFileName(): string { return 'tree-sitter-mylang.wasm'; } protected extractClasses(rootNode: any, content: string): ClassInfo[] { /* ... */ } protected extractMethods(rootNode: any, content: string): MethodInfo[] { /* ... */ } protected extractImports(rootNode: any, content: string): string[] { /* ... */ } protected extractExports(rootNode: any, content: string): string[] { /* ... */ } } ``` 2. 在 `ParserRegistry.ts` 中注册: ``` this.register(new MyLangParser()); ``` 3. 确保 WASM 语法在 `tree-sitter-wasms` 中可用。

项目结构

``` src/ cli/ # CLI entry point (Commander.js) commands/ # Command handlers (scan, search, watch, get, init, ...) init/ # Agent-based init system initializers/ # Per-agent initializers (VSCode, Claude, Cursor, ...) utils/ # CLI utilities (colors) core/ config/ # Two-tier config (project + user) embedding/ # Embedding providers (Ollama, OpenAI) interfaces/ # All TypeScript interfaces and types llm/ # LLM providers (Ollama, OpenAI, Anthropic) memory/ # MemoryStore (SQLite + vectors) parser/ # Tree-sitter parser registry languages/ # Language-specific parsers (TS, JS, C#) pipeline/ # Structure + Insight pipelines, SyncService search/ # SearchEngine + SearchFormatter storage/ # SqliteStateStore, LanceVectorStore, HeaderStore watcher/ # FileWatcher (chokidar, lock file, extension filter) Container.ts # DI composition root mcp/ # MCP server (stdio transport) utils/ # Shared utilities (checksum, logger) ```
## 许可证 MIT
标签:AI代理集成, AI编码助手, AST解析, CMS安全, GNU通用公共许可证, JavaScript, MCP服务器, MITM代理, Node.js, SOC Prime, Token优化, Tree-sitter, TypeScript, 上下文记忆, 二进制发布, 代码导航, 代码索引, 代码结构化, 向量嵌入, 安全插件, 开发工具, 开源工具, 快速搜索, 数据可视化, 结构化索引, 自动化攻击, 语义搜索