@chiway/contextweaver 1.4.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +482 -196
  3. package/README.zh-CN.md +669 -0
  4. package/dist/{SearchService-OS7CYHNJ.js → SearchService-WVD6THR3.js} +116 -74
  5. package/dist/chunk-2EVCLNYN.js +223 -0
  6. package/dist/{chunk-ZOMGPIU6.js → chunk-3BNHQV5W.js} +1 -5
  7. package/dist/chunk-BFCIZ52F.js +102 -0
  8. package/dist/chunk-H4MGLXXF.js +115 -0
  9. package/dist/{lock-FL54LIQL.js → chunk-HHYPQA3X.js} +1 -1
  10. package/dist/chunk-IZ6IUHNN.js +77 -0
  11. package/dist/chunk-LB42CZEB.js +18 -0
  12. package/dist/chunk-MN6BQJDB.js +85 -0
  13. package/dist/{chunk-EMSMLPMK.js → chunk-ORYIVY7D.js} +10 -117
  14. package/dist/{chunk-RGJSXUFS.js → chunk-PPLFJGO3.js} +60 -0
  15. package/dist/chunk-TPM6YP43.js +38 -0
  16. package/dist/chunk-XFIM2T6S.js +57 -0
  17. package/dist/{chunk-AB24E3Z7.js → chunk-XMZZZKG7.js} +23 -79
  18. package/dist/chunk-XTWNT7KP.js +156 -0
  19. package/dist/chunk-YMQWNIQI.js +143 -0
  20. package/dist/{chunk-X7PAYQMT.js → chunk-YSQI5IRI.js} +125 -5
  21. package/dist/{codebaseRetrieval-3Z4CRA7X.js → codebaseRetrieval-4BFIM7PU.js} +5 -2
  22. package/dist/{db-PMVM7557.js → db-GBCLP4GG.js} +15 -1
  23. package/dist/findReferences-EBYR3VNL.js +16 -0
  24. package/dist/getSymbolDefinition-ZQK65FPN.js +17 -0
  25. package/dist/index.js +244 -41
  26. package/dist/listFiles-W7C5UYOP.js +14 -0
  27. package/dist/loadConfig-XTVT2OWW.js +9 -0
  28. package/dist/lock-HNKQ6X5B.js +8 -0
  29. package/dist/scanner-OVMAMQSQ.js +13 -0
  30. package/dist/server-ZIJIRVWH.js +347 -0
  31. package/dist/stats-AGKUCJQI.js +12 -0
  32. package/dist/{vectorStore-HPQZOVWF.js → vectorStore-4ODCERRO.js} +1 -1
  33. package/package.json +15 -23
  34. package/dist/scanner-2XGJWYHR.js +0 -11
  35. package/dist/server-XK6EINRV.js +0 -146
@@ -0,0 +1,669 @@
1
+ # ContextWeaver
2
+
3
+ <p align="center">
4
+ <strong>🧵 为 AI Agent 精心编织的代码库上下文引擎</strong>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <em>Semantic Code Retrieval for AI Agents — Hybrid Search • Graph Expansion • Token-Aware Packing</em>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <strong>简体中文</strong> ·
13
+ <a href="README.md">English</a>
14
+ </p>
15
+
16
+ ---
17
+
18
+ **ContextWeaver** 是一个专为 AI 代码助手设计的语义检索引擎,采用混合搜索(向量 + 词法)、智能上下文扩展和 Token 感知打包策略,为 LLM 提供精准、相关且上下文完整的代码片段。
19
+
20
+ <p align="center">
21
+ <img src="docs/architecture.png" alt="ContextWeaver 架构概览" width="800" />
22
+ </p>
23
+
24
+ ## ✨ 核心特性
25
+
26
+ ### 🔍 混合检索引擎
27
+ - **向量召回 (Vector Retrieval)**:基于语义相似度的深度理解
28
+ - **词法召回 (Lexical/FTS)**:精确匹配函数名、类名等技术术语
29
+ - **RRF 融合 (Reciprocal Rank Fusion)**:智能融合多路召回结果
30
+
31
+ ### 🧠 AST 语义分片
32
+ - **Tree-sitter 解析**:支持 TypeScript、JavaScript、Python、Go、Java、Rust、C、C++、C# 等语言
33
+ - **Dual-Text 策略**:`displayCode` 用于展示,`vectorText` 用于 Embedding
34
+ - **Gap-Aware 合并**:智能处理代码间隙,保持语义完整性
35
+ - **Breadcrumb 注入**:向量文本包含层级路径,提升检索召回率
36
+ - **UTF-16 字符域归一**:在写入 metadata 前用 `SourceAdapter.toCharOffset` 统一偏移,避免多字节字符切片错位(v1.4.0+)
37
+
38
+ ### 📊 三阶段上下文扩展
39
+ - **E1 邻居扩展**:同文件前后相邻 chunks,保证代码块完整性
40
+ - **E2 面包屑补全**:同一类/函数下的其他方法,理解整体结构
41
+ - **E3 Import 解析**:跨文件依赖追踪(可配置开关)
42
+
43
+ ### 🎯 智能截断策略 (Smart TopK)
44
+ - **Anchor & Floor**:动态阈值 + 绝对下限双保险
45
+ - **Delta Guard**:防止 Top1 outlier 场景的误判
46
+ - **Safe Harbor**:前 N 个结果只检查下限,保证基本召回
47
+
48
+ ### 🔌 MCP 原生支持
49
+ - **MCP Server 模式**:一键启动 Model Context Protocol 服务端
50
+ - **多工具粒度**(v1.5.0+):除核心语义检索外,新增结构浏览、符号引用、符号定义、统计四类专项工具
51
+ - **意图与术语分离**:LLM 友好的 API 设计
52
+ - **自动索引**:首次查询自动触发索引,增量更新透明无感
53
+
54
+ ### ⚡ 查询缓存与文件监听 (v1.5.0+)
55
+ - **查询缓存 (QueryCache)**:进程内 per-project LRU 缓存(默认 50 条),命中后跳过向量召回/Rerank/扩展全流程
56
+ - **缓存自动失效**:缓存键由 `归一化查询 + projectId + 索引版本 + 搜索配置指纹` 组成,索引更新或配置变更后自动失效,不会返回陈旧结果
57
+ - **Watch 模式**:`contextweaver watch` 监听文件系统变化并自动触发增量索引,带防抖(默认 500ms)与扫描去重(避免并发扫描)
58
+
59
+ ### 📈 统计与可观测 (v1.5.0+)
60
+ - **三类指标**:索引过程、搜索质量/行为、健康/一致性
61
+ - **双出口**:`contextweaver stats` CLI(支持 `--json`)+ MCP `stats` 工具
62
+ - **一致性诊断**:自动检测迁移状态异常、`pending_marks` 积压、向量行缺失等问题并给出修复建议
63
+
64
+ ### 🛡️ Crash-Safe 数据架构 (v1.4.0+)
65
+ - **正文唯一源**:LanceDB 仅存向量与定位元数据,正文回查 `files.content`,索引体积降低 30-50%
66
+ - **跨库事务补偿**:LanceDB → FTS+outbox → SQLite mark 三阶段写入,任一失败自动回滚或重放
67
+ - **迁移状态机**:`pending/done/aborted` 三态持久化,崩溃恢复自动重建
68
+ - **跨进程互斥**:advisory lock 防止 MCP server 与 CLI 并发触发 LanceDB 迁移
69
+ - **chunk_id 去重**:写入前预删除,防止 retry 场景产生重复行
70
+
71
+ ## 📦 快速开始
72
+
73
+ ### 环境要求
74
+
75
+ - Node.js >= 20
76
+ - pnpm (推荐) 或 npm
77
+
78
+ ### 安装
79
+
80
+ ```bash
81
+ # 全局安装
82
+ npm install -g @chiway/contextweaver
83
+
84
+ # 或使用 pnpm
85
+ pnpm add -g @chiway/contextweaver
86
+ ```
87
+
88
+ ### 初始化配置
89
+
90
+ ```bash
91
+ # 初始化配置文件(创建 ~/.contextweaver/.env)
92
+ contextweaver init
93
+ # 或简写
94
+ cw init
95
+ ```
96
+
97
+ 编辑 `~/.contextweaver/.env`,填入你的 API Key:
98
+
99
+ ```bash
100
+ # Embedding API 配置(必需)
101
+ EMBEDDINGS_API_KEY=your-api-key-here
102
+ EMBEDDINGS_BASE_URL=https://api.siliconflow.cn/v1/embeddings
103
+ EMBEDDINGS_MODEL=BAAI/bge-m3
104
+ EMBEDDINGS_MAX_CONCURRENCY=10
105
+ EMBEDDINGS_DIMENSIONS=1024
106
+
107
+ # Reranker 配置(必需)
108
+ RERANK_API_KEY=your-api-key-here
109
+ RERANK_BASE_URL=https://api.siliconflow.cn/v1/rerank
110
+ RERANK_MODEL=BAAI/bge-reranker-v2-m3
111
+ RERANK_TOP_N=20
112
+
113
+ # 搜索参数(可选,覆盖内置默认值)
114
+ CW_SEARCH_WVEC=0.6
115
+ CW_SEARCH_WLEX=0.4
116
+ CW_SEARCH_RERANK_TOP_N=10
117
+ CW_SEARCH_MAX_TOTAL_CHARS=48000
118
+ CW_SEARCH_VECTOR_TOP_K=80
119
+ CW_SEARCH_SMART_MAX_K=8
120
+ CW_SEARCH_IMPORT_FILES_PER_SEED=3
121
+
122
+ # 忽略模式(可选,逗号分隔)
123
+ # IGNORE_PATTERNS=.venv,node_modules
124
+ ```
125
+
126
+ ### 索引代码库
127
+
128
+ ```bash
129
+ # 在代码库根目录执行
130
+ contextweaver index
131
+
132
+ # 指定路径
133
+ contextweaver index /path/to/your/project
134
+
135
+ # 强制重新索引
136
+ contextweaver index --force
137
+ ```
138
+
139
+ ### 监听模式(v1.5.0+)
140
+
141
+ ```bash
142
+ # 监听文件变化并自动增量索引(按 Ctrl+C 停止)
143
+ contextweaver watch
144
+
145
+ # 指定路径与防抖时间(毫秒)
146
+ contextweaver watch /path/to/project --debounce 800
147
+ ```
148
+
149
+ `watch` 会在启动时先执行一次全量增量扫描,随后监听文件系统事件;变更触发防抖窗口内的去重扫描,已被忽略规则过滤的路径不会触发扫描。
150
+
151
+ ### 本地搜索
152
+
153
+ ```bash
154
+ # 语义搜索
155
+ cw search --information-request "用户认证流程是如何实现的?"
156
+
157
+ # 带精确术语
158
+ cw search --information-request "数据库连接逻辑" --technical-terms "DatabasePool,Connection"
159
+ ```
160
+
161
+ ### 结构浏览与符号查找(v1.5.0+)
162
+
163
+ 以下命令是 MCP 工具的 CLI 镜像,零 Embedding API 成本:
164
+
165
+ ```bash
166
+ # 列出已索引文件(支持 glob / 语言 / 数量过滤)
167
+ contextweaver list-files --glob "src/**/*.ts" --language typescript --max-results 100
168
+
169
+ # 查看符号定义
170
+ contextweaver definition SearchService --hint-path src/search
171
+
172
+ # 查看符号引用
173
+ contextweaver references handleStats --exclude-definition
174
+ ```
175
+
176
+ ### 统计(v1.5.0+)
177
+
178
+ ```bash
179
+ # 人类可读的统计报告
180
+ contextweaver stats
181
+
182
+ # JSON 输出(便于脚本消费)
183
+ contextweaver stats --json
184
+
185
+ # 指定项目路径
186
+ contextweaver stats --path /path/to/project
187
+ ```
188
+
189
+ ### 启动 MCP 服务器
190
+
191
+ ```bash
192
+ # 启动 MCP 服务端(供 Claude 等 AI 助手使用)
193
+ contextweaver mcp
194
+ ```
195
+
196
+ ### 索引管理 (v1.4.0+)
197
+
198
+ ```bash
199
+ # 查看 LanceDB 迁移状态
200
+ contextweaver migrate
201
+
202
+ # 解除 aborted 状态:清空 LanceDB 并触发全量重建
203
+ # 触发时机:抽样校验失败后 Indexer 拒绝写入;运行此命令后再次 index 即可
204
+ contextweaver migrate --reset
205
+
206
+ # 指定项目路径
207
+ contextweaver migrate --path /path/to/project
208
+ ```
209
+
210
+ ## 🔧 MCP 集成配置
211
+
212
+ ### Claude Desktop 配置
213
+
214
+ 在 Claude Desktop 的配置文件中添加:
215
+
216
+ ```json
217
+ {
218
+ "mcpServers": {
219
+ "contextweaver": {
220
+ "command": "contextweaver",
221
+ "args": ["mcp"]
222
+ }
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### MCP 工具一览(v1.5.0+)
228
+
229
+ ContextWeaver 提供 5 个 MCP 工具,遵循「语义检索为主、结构浏览为辅」的分层设计:
230
+
231
+ | 工具 | 用途 | Embedding 成本 |
232
+ |------|------|---------------|
233
+ | `codebase-retrieval` | **主力工具**:混合语义 + 精确匹配检索 | 有 |
234
+ | `list-files` | 列出已索引文件结构(路径/语言/大小) | 无 |
235
+ | `find-references` | 查找符号的启发式文本引用 | 无 |
236
+ | `get-symbol-definition` | 查找符号的疑似定义块 | 无 |
237
+ | `stats` | 索引/搜索/健康统计 | 无 |
238
+
239
+ #### `codebase-retrieval` 参数说明
240
+
241
+ | 参数 | 类型 | 必需 | 描述 |
242
+ |------|------|------|------|
243
+ | `repo_path` | string | ✅ | 代码库根目录的绝对路径 |
244
+ | `information_request` | string | ✅ | 自然语言形式的语义意图描述 |
245
+ | `technical_terms` | string[] | ❌ | 精确技术术语(类名、函数名等) |
246
+
247
+ #### `list-files` 参数说明
248
+
249
+ | 参数 | 类型 | 必需 | 描述 |
250
+ |------|------|------|------|
251
+ | `repo_path` | string | ✅ | 代码库根目录的绝对路径 |
252
+ | `glob` | string | ❌ | 路径 glob 过滤 |
253
+ | `language` | string | ❌ | 语言过滤(匹配 `files.language`) |
254
+ | `max_results` | number | ❌ | 最大返回数量(默认 200) |
255
+
256
+ #### `find-references` 参数说明
257
+
258
+ | 参数 | 类型 | 必需 | 描述 |
259
+ |------|------|------|------|
260
+ | `repo_path` | string | ✅ | 代码库根目录的绝对路径 |
261
+ | `symbol` | string | ✅ | 精确符号名 |
262
+ | `exclude_definition` | boolean | ❌ | 排除面包屑尾部匹配符号名的 chunk |
263
+ | `max_results` | number | ❌ | 最大返回数量(默认 50) |
264
+
265
+ #### `get-symbol-definition` 参数说明
266
+
267
+ | 参数 | 类型 | 必需 | 描述 |
268
+ |------|------|------|------|
269
+ | `repo_path` | string | ✅ | 代码库根目录的绝对路径 |
270
+ | `symbol` | string | ✅ | 要解析的精确符号名 |
271
+ | `hint_path` | string | ❌ | 用于同名定义消歧的偏好路径 |
272
+ | `max_results` | number | ❌ | 最大返回数量(默认 3) |
273
+
274
+ > **说明**:`find-references` 与 `get-symbol-definition` 是基于已索引 chunk 的启发式文本检索,并非编译器级精确导航。穷尽式原始文本匹配请在 MCP 之外使用 `grep`。
275
+
276
+ #### 设计理念
277
+
278
+ - **意图与术语分离**:`information_request` 描述「做什么」,`technical_terms` 过滤「叫什么」
279
+ - **同文件上下文优先**:默认提供同文件上下文,跨文件探索由 Agent 自主发起
280
+ - **回归代理本能**:工具只负责定位,跨文件探索由 Agent 按需触发
281
+
282
+ ## 🏗️ 架构设计
283
+
284
+ ```mermaid
285
+ flowchart TB
286
+ subgraph Interface["CLI / MCP Interface"]
287
+ CLI[contextweaver CLI]
288
+ MCP[MCP Server]
289
+ end
290
+
291
+ subgraph Search["SearchService"]
292
+ QC[QueryCache<br/>LRU]
293
+ VR[Vector Retrieval]
294
+ LR[Lexical Retrieval]
295
+ RRF[RRF Fusion + Rerank]
296
+ QC -.cache hit.-> CP
297
+ VR --> RRF
298
+ LR --> RRF
299
+ end
300
+
301
+ subgraph Expand["Context Expansion"]
302
+ GE[GraphExpander]
303
+ CP[ContextPacker]
304
+ GE --> CP
305
+ end
306
+
307
+ subgraph Storage["Storage Layer"]
308
+ VS[(VectorStore<br/>LanceDB)]
309
+ DB[(SQLite<br/>FTS5)]
310
+ end
311
+
312
+ subgraph Index["Indexing Pipeline"]
313
+ CR[Crawler<br/>fdir] --> SS[SemanticSplitter<br/>Tree-sitter] --> IX[Indexer<br/>Batch Embedding]
314
+ end
315
+
316
+ Interface --> Search
317
+ RRF --> GE
318
+ Search <--> Storage
319
+ Expand <--> Storage
320
+ Index --> Storage
321
+ ```
322
+
323
+ ### 核心模块说明
324
+
325
+ | 模块 | 职责 |
326
+ |------|------|
327
+ | **SearchService** | 混合搜索核心,协调向量/词法召回、RRF 融合、Rerank 精排,集成 QueryCache |
328
+ | **QueryCache** | per-project 进程内 LRU 缓存(v1.5.0+),命中后跳过整条检索流水线 |
329
+ | **GraphExpander** | 上下文扩展器,执行 E1/E2/E3 三阶段扩展策略 |
330
+ | **ContextPacker** | 上下文打包器,负责段落合并和 Token 预算控制 |
331
+ | **ChunkContentLoader** | 按 `(path, start_index, end_index)` 从 `files.content` 批量切片(v1.4.0+) |
332
+ | **VectorStore** | LanceDB 适配层,仅暴露纯 vector 操作 |
333
+ | **Database (SQLite)** | 元数据存储 + FTS5 全文索引 + 统计计数器,schema_version=3 |
334
+ | **Bootstrap** | 跨库初始化协调器:pending_marks 重放 + LanceDB schema 迁移(v1.4.0+) |
335
+ | **SemanticSplitter** | AST 语义分片器,基于 Tree-sitter 解析,写入时统一到 UTF-16 字符域 |
336
+ | **Watcher** | 文件监听协调器(v1.5.0+),防抖 + 扫描去重 + 忽略过滤 |
337
+ | **Stats** | 统计聚合层(v1.5.0+),组合索引/搜索/健康三类指标 |
338
+
339
+ ### 数据架构 (v1.4.0+)
340
+
341
+ ```
342
+ ~/.contextweaver/<projectId>/
343
+ ├── index.db # SQLite
344
+ │ ├── files # 文件元数据 + 完整正文(content 列,文本切片唯一来源)
345
+ │ ├── files_fts # 外部内容表,倒排索引指向 files
346
+ │ ├── chunks_fts # chunk 级倒排索引,per-file 整体替换
347
+ │ ├── metadata # schema_version / lancedb_migration_state / lock
348
+ │ ├── stats # 索引/搜索累计计数器(v1.5.0+)
349
+ │ └── pending_marks # outbox:vector_index_hash 标记失败时启动重放
350
+ └── vectors.lance/ # LanceDB chunks 表(仅向量 + 定位元数据,不存正文)
351
+ ```
352
+
353
+ **关键不变量**:
354
+ - 正文唯一源是 `files.content`;`ChunkContentLoader` 用 `start_index/end_index` 切片(与 `displayCode` 同源)
355
+ - 所有 LanceDB 偏移字段都在 UTF-16 字符域,多字节文件不会切错
356
+ - 跨库写入顺序:LanceDB → (FTS + outbox 单事务) → SQLite mark + 清 outbox
357
+ - LanceDB 迁移状态 `pending/done/aborted` 持久化,跨进程用 advisory lock 互斥
358
+ - 查询缓存键绑定索引版本与搜索配置指纹,索引或配置变更即失效
359
+
360
+ ## 📁 项目结构
361
+
362
+ ```
363
+ contextweaver/
364
+ ├── src/
365
+ │ ├── index.ts # CLI 入口(init / index / watch / search / mcp / migrate / stats)
366
+ │ ├── config.ts # 配置管理(环境变量)
367
+ │ ├── defaultEnv.ts # 默认 .env 模板
368
+ │ ├── cli/
369
+ │ │ └── mirrorCommands.ts # MCP 工具的 CLI 镜像(list-files / definition / references)
370
+ │ ├── api/ # 外部 API 封装
371
+ │ │ ├── embedding.ts # Embedding API
372
+ │ │ └── reranker.ts # Reranker API
373
+ │ ├── chunking/ # 语义分片
374
+ │ │ ├── SemanticSplitter.ts # AST 语义分片器
375
+ │ │ ├── SourceAdapter.ts # 源码适配器(UTF-16/UTF-8 域归一)
376
+ │ │ ├── LanguageSpec.ts # 语言规范定义
377
+ │ │ ├── ParserPool.ts # Tree-sitter 解析器池
378
+ │ │ └── types.ts # 分片类型定义
379
+ │ ├── scanner/ # 文件扫描
380
+ │ │ ├── index.ts # 扫描编排
381
+ │ │ ├── crawler.ts # 文件系统遍历
382
+ │ │ ├── processor.ts # 文件处理
383
+ │ │ ├── watcher.ts # 文件监听协调器(v1.5.0+)
384
+ │ │ ├── filter.ts # 过滤规则
385
+ │ │ ├── hash.ts # 文件 hash
386
+ │ │ └── language.ts # 语言识别
387
+ │ ├── indexer/ # 索引器
388
+ │ │ └── index.ts # 三阶段事务(LanceDB → FTS+outbox → SQLite mark)
389
+ │ ├── vectorStore/ # 向量存储
390
+ │ │ └── index.ts # LanceDB 适配层(纯 vector 操作)
391
+ │ ├── db/ # 数据库
392
+ │ │ ├── index.ts # SQLite + FTS5 + pending_marks + 迁移状态机 + 统计计数器
393
+ │ │ └── bootstrap.ts # 跨库初始化协调(v1.4.0+)
394
+ │ ├── search/ # 搜索服务
395
+ │ │ ├── SearchService.ts # 核心搜索服务(集成缓存)
396
+ │ │ ├── QueryCache.ts # per-project LRU 查询缓存(v1.5.0+)
397
+ │ │ ├── GraphExpander.ts # 上下文扩展器
398
+ │ │ ├── ContextPacker.ts # 上下文打包器
399
+ │ │ ├── ChunkContentLoader.ts # 按 (path, start_index, end_index) 切片(v1.4.0+)
400
+ │ │ ├── fts.ts # 全文搜索(per-file 整体替换)
401
+ │ │ ├── config.ts # 搜索默认配置 + 取值边界
402
+ │ │ ├── loadConfig.ts # 环境变量覆盖 + 配置指纹(v1.5.0+)
403
+ │ │ ├── types.ts # 类型定义
404
+ │ │ ├── utils.ts # token overlap 评分
405
+ │ │ └── resolvers/ # 多语言 Import 解析器
406
+ │ │ ├── JsTsResolver.ts
407
+ │ │ ├── PythonResolver.ts
408
+ │ │ ├── GoResolver.ts
409
+ │ │ ├── JavaResolver.ts
410
+ │ │ ├── RustResolver.ts
411
+ │ │ ├── CppResolver.ts
412
+ │ │ └── CSharpResolver.ts
413
+ │ ├── stats/ # 统计聚合层(v1.5.0+)
414
+ │ │ └── index.ts # 索引/搜索/健康三类指标聚合与渲染
415
+ │ ├── mcp/ # MCP 服务端
416
+ │ │ ├── server.ts # MCP 服务器实现(注册 5 个工具)
417
+ │ │ ├── main.ts # MCP 入口
418
+ │ │ └── tools/
419
+ │ │ ├── index.ts # 工具注册中心
420
+ │ │ ├── shared.ts # 工具共享逻辑
421
+ │ │ ├── codebaseRetrieval.ts # 代码检索工具
422
+ │ │ ├── listFiles.ts # 文件结构浏览(v1.5.0+)
423
+ │ │ ├── findReferences.ts # 符号引用查找(v1.5.0+)
424
+ │ │ ├── getSymbolDefinition.ts # 符号定义查找(v1.5.0+)
425
+ │ │ └── stats.ts # 统计工具(v1.5.0+)
426
+ │ └── utils/ # 工具函数
427
+ │ ├── logger.ts # 日志系统
428
+ │ ├── encoding.ts # 编码检测
429
+ │ └── lock.ts # 文件锁
430
+ ├── tests/ # 单测 + 集成测试(28 个测试文件,156 个测试用例)
431
+ │ ├── chunking/ # SourceAdapter / 分片
432
+ │ ├── cli/ # mirrorCommands
433
+ │ ├── db/ # 迁移、outbox、advisory lock、index-version
434
+ │ ├── indexer/ # 事务补偿、GC、aborted 守卫
435
+ │ ├── integration/ # 真实 LanceDB 端到端
436
+ │ ├── mcp/ # list-files / find-references / get-symbol-definition / shared / 工具注册
437
+ │ ├── scanner/ # watcher / index-version
438
+ │ ├── search/ # FTS、ChunkContentLoader、Packer、缓存、loadConfig
439
+ │ ├── stats/ # 统计聚合
440
+ │ └── vectorStore/ # chunk_id 去重、抽样校验
441
+ ├── package.json
442
+ └── tsconfig.json
443
+ ```
444
+
445
+ ## ⚙️ 配置详解
446
+
447
+ ### 环境变量
448
+
449
+ | 变量名 | 必需 | 默认值 | 描述 |
450
+ |--------|------|--------|------|
451
+ | `EMBEDDINGS_API_KEY` | ✅ | - | Embedding API 密钥 |
452
+ | `EMBEDDINGS_BASE_URL` | ✅ | - | Embedding API 地址 |
453
+ | `EMBEDDINGS_MODEL` | ✅ | - | Embedding 模型名称 |
454
+ | `EMBEDDINGS_MAX_CONCURRENCY` | ❌ | 10 | Embedding 并发数 |
455
+ | `EMBEDDINGS_DIMENSIONS` | ❌ | 1024 | 向量维度 |
456
+ | `RERANK_API_KEY` | ✅ | - | Reranker API 密钥 |
457
+ | `RERANK_BASE_URL` | ✅ | - | Reranker API 地址 |
458
+ | `RERANK_MODEL` | ✅ | - | Reranker 模型名称 |
459
+ | `RERANK_TOP_N` | ❌ | 20 | Rerank 返回数量 |
460
+ | `IGNORE_PATTERNS` | ❌ | - | 额外忽略模式 |
461
+
462
+ ### 搜索参数环境变量覆盖(v1.5.0+)
463
+
464
+ 以下环境变量可覆盖内置默认值;超出取值边界时会被自动钳制到合法区间。`wVec`/`wLex` 只设其一时,另一个自动取 `1 - x`。
465
+
466
+ | 变量名 | 默认值 | 取值边界 | 描述 |
467
+ |--------|--------|----------|------|
468
+ | `CW_SEARCH_WVEC` | 0.6 | 0–1 | 向量权重(融合阶段) |
469
+ | `CW_SEARCH_WLEX` | 0.4 | 0–1 | 词法权重(与 `wVec` 互补) |
470
+ | `CW_SEARCH_RERANK_TOP_N` | 10 | 5–20 | Rerank 后保留数量 |
471
+ | `CW_SEARCH_MAX_TOTAL_CHARS` | 48000 | 20000–80000 | Token 预算(以字符计,约 12k tokens) |
472
+ | `CW_SEARCH_VECTOR_TOP_K` | 80 | 40–200 | 向量召回候选数 |
473
+ | `CW_SEARCH_SMART_MAX_K` | 8 | 5–15 | Smart TopK 硬上限 |
474
+ | `CW_SEARCH_IMPORT_FILES_PER_SEED` | 3 | 0–5 | E3 每 seed 解析的导入文件数(0 关闭跨文件扩展) |
475
+
476
+ ### 搜索配置参数(内置默认值)
477
+
478
+ ```typescript
479
+ interface SearchConfig {
480
+ // === 召回阶段 ===
481
+ vectorTopK: number; // 向量召回候选数(默认 80)
482
+ vectorTopM: number; // 去重后保留的向量数(默认 60)
483
+ ftsTopKFiles: number; // FTS 召回文件数(默认 20)
484
+ lexChunksPerFile: number; // 每文件词法 chunks 数(默认 2)
485
+ lexTotalChunks: number; // 词法总 chunks 数(默认 40)
486
+
487
+ // === 融合阶段 ===
488
+ rrfK0: number; // RRF 平滑常数(默认 20)
489
+ wVec: number; // 向量权重(默认 0.6)
490
+ wLex: number; // 词法权重(默认 0.4)
491
+ fusedTopM: number; // 融合后送 rerank 数量(默认 60)
492
+
493
+ // === Rerank ===
494
+ rerankTopN: number; // Rerank 后保留数量(默认 10)
495
+ maxRerankChars: number; // Rerank 文本最大字符数(默认 1000)
496
+ maxBreadcrumbChars: number;// 面包屑上下文最大字符数(默认 250)
497
+ headRatio: number; // 截断时 head/tail 比例(默认 0.67)
498
+
499
+ // === 扩展策略 ===
500
+ neighborHops: number; // E1 邻居跳数(默认 2)
501
+ breadcrumbExpandLimit: number; // E2 面包屑补全数(默认 3)
502
+ importFilesPerSeed: number; // E3 每 seed 导入文件数(默认 3)
503
+ chunksPerImportFile: number; // E3 每导入文件 chunks(默认 3)
504
+
505
+ // === ContextPacker ===
506
+ maxSegmentsPerFile: number; // 每文件最大非连续段数(默认 3)
507
+ maxTotalChars: number; // Token 预算(字符,默认 48000)
508
+
509
+ // === Smart TopK ===
510
+ enableSmartTopK: boolean; // 启用智能截断(默认 true)
511
+ smartTopScoreRatio: number; // 动态阈值比例(默认 0.5)
512
+ smartTopScoreDeltaAbs: number; // 相对 Top1 最大绝对降幅(默认 0.25)
513
+ smartMinScore: number; // 绝对下限(默认 0.25)
514
+ smartMinK: number; // Safe Harbor 数量(默认 2)
515
+ smartMaxK: number; // 硬上限(默认 8)
516
+ }
517
+ ```
518
+
519
+ ## 🌍 多语言支持
520
+
521
+ ContextWeaver 通过 Tree-sitter 原生支持以下编程语言的 AST 解析:
522
+
523
+ | 语言 | AST 解析 | Import 解析 | 文件扩展名 |
524
+ |------|----------|-------------|-----------|
525
+ | TypeScript | ✅ | ✅ | `.ts`, `.tsx` |
526
+ | JavaScript | ✅ | ✅ | `.js`, `.jsx`, `.mjs`, `.cjs` |
527
+ | Python | ✅ | ✅ | `.py` |
528
+ | Go | ✅ | ✅ | `.go` |
529
+ | Java | ✅ | ✅ | `.java` |
530
+ | Rust | ✅ | ✅ | `.rs` |
531
+ | C | ✅ | ✅ | `.c`, `.h` |
532
+ | C++ | ✅ | ✅ | `.cpp`, `.cc`, `.cxx`, `.hpp` |
533
+ | C# | ✅ | ✅ | `.cs` |
534
+
535
+ 其他语言会采用基于行的 Fallback 分片策略,仍可正常索引和搜索。
536
+
537
+ ## 🔄 工作流程
538
+
539
+ ### 索引流程
540
+
541
+ ```
542
+ 0. Bootstrap → pending_marks 重放 + LanceDB schema 迁移(首次启动)
543
+ 1. Crawler → 遍历文件系统,过滤忽略项
544
+ 2. Processor → 读取文件内容,计算 hash
545
+ 3. Splitter → AST 解析,语义分片(偏移归一到 UTF-16 字符域)
546
+ 4. Indexer → 批量 Embedding
547
+ 5. 阶段 4-6 伪事务:
548
+ ├─ LanceDB 写入(预删 (path, hash) 防重复 → add → 清旧版本)
549
+ ├─ FTS + outbox 单 SQLite 事务(失败回滚 LanceDB)
550
+ └─ SQLite mark + 清 outbox 单事务(失败时 outbox 保留,下次启动 replay)
551
+ 6. 末尾 GC → 清理 LanceDB 孤儿 chunks(time budget 5s)
552
+ ```
553
+
554
+ ### 搜索流程
555
+
556
+ ```
557
+ 1. Query Parse → 解析查询,分离语义和术语
558
+ 2. Cache Lookup → 命中则直接返回(v1.5.0+,缓存键含索引版本 + 配置指纹)
559
+ 3. Hybrid Recall → 向量 + 词法双路召回
560
+ 4. RRF Fusion → Reciprocal Rank Fusion 融合
561
+ 5. Rerank → 交叉编码器精排
562
+ 6. Smart Cutoff → 智能分数截断
563
+ 7. Graph Expand → 邻居/面包屑/导入扩展
564
+ 8. Context Pack → 段落合并,Token 预算
565
+ 9. Cache Store → 写入缓存(v1.5.0+)
566
+ 10. Format Output → 格式化返回给 LLM
567
+ ```
568
+
569
+ ## 📊 性能特性
570
+
571
+ - **查询缓存**:重复查询命中 LRU 缓存,跳过召回/Rerank/扩展全流程(v1.5.0+)
572
+ - **增量索引**:只处理变更文件,二次索引速度提升 10x+
573
+ - **批量 Embedding**:自适应批次大小,支持并发控制
574
+ - **速率限制恢复**:429 错误时自动退避,渐进恢复
575
+ - **连接池复用**:Tree-sitter 解析器池化复用
576
+ - **文件索引缓存**:GraphExpander 文件路径索引 lazy load
577
+ - **零成本元数据工具**:`list-files`/`find-references`/`get-symbol-definition` 不调用 Embedding API(v1.5.0+)
578
+
579
+ ## 📈 统计与可观测 (v1.5.0+)
580
+
581
+ `contextweaver stats` 输出三个分区:
582
+
583
+ - **索引过程**:累计索引运行次数、上次索引时间、上次结果快照(新增/修改/删除/未变/跳过/错误 + 向量索引明细)
584
+ - **搜索质量/行为**:累计查询次数、缓存命中率、实际计算次数,以及各阶段平均耗时(retrieve / rerank / expand / pack)与平均召回 seed 数
585
+ - **健康/一致性**:文件数与正文总量、LanceDB 向量行数、embedding 维度、索引版本、迁移状态、`pending_marks`、语言占比
586
+
587
+ 当检测到迁移状态异常、`pending_marks` 积压或向量行缺失时,报告底部会输出**诊断告警**及对应修复命令。`--json` 输出结构对应 `StatsReport`,便于脚本与监控系统消费。
588
+
589
+ ## 🐛 日志与调试
590
+
591
+ 日志文件位置:`~/.contextweaver/logs/app.YYYY-MM-DD.log`
592
+
593
+ 设置日志级别:
594
+
595
+ ```bash
596
+ # 开启 debug 日志
597
+ LOG_LEVEL=debug contextweaver search --information-request "..."
598
+ ```
599
+
600
+ ## 🚨 故障排查 (v1.4.0+)
601
+
602
+ ### LanceDB 迁移卡死 (`aborted` 状态)
603
+
604
+ **现象**:`contextweaver index` 报错 "LanceDB 处于 aborted 状态,拒绝写入以防止 schema 污染"。
605
+
606
+ **原因**:v1.4.0 升级时 LanceDB 旧索引中的 `display_code` 与当前 `files.content` 抽样差异 > 1%(通常发生在 chunk 偏移用 UTF-8 字节域旧索引上)。
607
+
608
+ **解决**:
609
+ ```bash
610
+ contextweaver migrate --reset # 清空 LanceDB chunks 表 + 重置状态为 done
611
+ contextweaver index # 全量重建(新 schema)
612
+ ```
613
+
614
+ 也可先运行 `contextweaver stats` 查看诊断告警,确认当前迁移状态与 `pending_marks` 积压情况。
615
+
616
+ ### 跨进程迁移竞争
617
+
618
+ 如果 MCP server 长驻 + 另一终端跑 `contextweaver index`,两进程会争抢迁移。v1.4.0 引入 10 分钟僵尸阈值的 advisory lock,自动让一个进程跳过迁移、另一个完成。
619
+
620
+ 如锁卡住(process kill -9 后),可手动清理:
621
+ ```bash
622
+ sqlite3 ~/.contextweaver/<projectId>/index.db \
623
+ "DELETE FROM metadata WHERE key = 'lancedb_migration_lock';"
624
+ ```
625
+
626
+ ### 重复 embedding 浪费
627
+
628
+ v1.4.0 已通过 `pending_marks` outbox 机制解决:FTS 写入成功但 vector_index_hash 标记失败时,下次启动自动 replay,不会触发重复 embedding。
629
+
630
+ ### 搜索结果未反映最新改动
631
+
632
+ 确认增量索引已执行(或开启 `contextweaver watch` 自动增量)。查询缓存键绑定索引版本,索引更新后旧缓存自动失效,无需手动清理。
633
+
634
+ ## 📜 版本历史
635
+
636
+ - **v1.5.0** (2026-06): 查询缓存、文件监听、统计与多粒度 MCP 工具
637
+ - 新增 `QueryCache`(per-project LRU),缓存键含索引版本 + 搜索配置指纹,自动失效
638
+ - 新增 `contextweaver watch` 文件监听 + 防抖增量索引
639
+ - 新增 `contextweaver stats` CLI(`--json`)与 MCP `stats` 工具,三类指标 + 一致性诊断
640
+ - 新增 3 个 MCP 工具:`list-files` / `find-references` / `get-symbol-definition`,及对应 CLI 镜像命令
641
+ - 新增 `CW_SEARCH_*` 环境变量覆盖搜索参数(带边界钳制)
642
+ - 28 个测试文件 / 156 个测试用例
643
+ - **v1.4.0** (2026-05): 数据架构与跨库一致性大修
644
+ - LanceDB chunks 表移除 `display_code/vector_text`,正文回查 `files.content`
645
+ - SemanticSplitter 偏移统一到 UTF-16 字符域
646
+ - schema_version 2 → 3,新增 `pending_marks` outbox + 三态迁移状态机
647
+ - 新增 `contextweaver migrate` CLI
648
+ - 跨进程 advisory lock 防止迁移竞争
649
+ - **v1.3.x**: 跨库写入事务性、scan 末尾自动 GC、files_fts 外部内容表
650
+ - **v1.2.x**: 搜索管道优化、索引内存优化
651
+ - **v1.1.x**: 智能 TopK 截断、Smart Cutoff
652
+ - **v1.0.x**: 初始 release
653
+
654
+ ## 📄 开源协议
655
+
656
+ 本项目采用 MIT 许可证。
657
+
658
+ ## 🙏 致谢
659
+
660
+ - [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) - 高性能语法解析
661
+ - [LanceDB](https://lancedb.com/) - 嵌入式向量数据库
662
+ - [MCP](https://modelcontextprotocol.io/) - Model Context Protocol
663
+ - [SiliconFlow](https://siliconflow.cn/) - 推荐的 Embedding/Reranker API 服务
664
+
665
+ ---
666
+
667
+ <p align="center">
668
+ <sub>Made with ❤️ for AI-assisted coding</sub>
669
+ </p>