@mars167/git-ai 2.3.0

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 (122) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +364 -0
  3. package/README.zh-CN.md +361 -0
  4. package/assets/hooks/post-checkout +28 -0
  5. package/assets/hooks/post-merge +28 -0
  6. package/assets/hooks/pre-commit +17 -0
  7. package/assets/hooks/pre-push +29 -0
  8. package/dist/bin/git-ai.js +62 -0
  9. package/dist/src/commands/ai.js +30 -0
  10. package/dist/src/commands/checkIndex.js +19 -0
  11. package/dist/src/commands/dsr.js +156 -0
  12. package/dist/src/commands/graph.js +203 -0
  13. package/dist/src/commands/hooks.js +125 -0
  14. package/dist/src/commands/index.js +92 -0
  15. package/dist/src/commands/pack.js +31 -0
  16. package/dist/src/commands/query.js +139 -0
  17. package/dist/src/commands/semantic.js +134 -0
  18. package/dist/src/commands/serve.js +14 -0
  19. package/dist/src/commands/status.js +78 -0
  20. package/dist/src/commands/trae.js +75 -0
  21. package/dist/src/commands/unpack.js +28 -0
  22. package/dist/src/core/archive.js +91 -0
  23. package/dist/src/core/astGraph.js +127 -0
  24. package/dist/src/core/astGraphQuery.js +142 -0
  25. package/dist/src/core/cozo.js +266 -0
  26. package/dist/src/core/cpg/astLayer.js +56 -0
  27. package/dist/src/core/cpg/callGraph.js +483 -0
  28. package/dist/src/core/cpg/cfgLayer.js +490 -0
  29. package/dist/src/core/cpg/dfgLayer.js +237 -0
  30. package/dist/src/core/cpg/index.js +80 -0
  31. package/dist/src/core/cpg/types.js +108 -0
  32. package/dist/src/core/crypto.js +10 -0
  33. package/dist/src/core/dsr/generate.js +308 -0
  34. package/dist/src/core/dsr/gitContext.js +74 -0
  35. package/dist/src/core/dsr/indexMaterialize.js +106 -0
  36. package/dist/src/core/dsr/paths.js +26 -0
  37. package/dist/src/core/dsr/query.js +73 -0
  38. package/dist/src/core/dsr/snapshotParser.js +73 -0
  39. package/dist/src/core/dsr/state.js +27 -0
  40. package/dist/src/core/dsr/types.js +2 -0
  41. package/dist/src/core/embedding/fusion.js +52 -0
  42. package/dist/src/core/embedding/index.js +43 -0
  43. package/dist/src/core/embedding/parser.js +14 -0
  44. package/dist/src/core/embedding/semantic.js +254 -0
  45. package/dist/src/core/embedding/structural.js +97 -0
  46. package/dist/src/core/embedding/symbolic.js +117 -0
  47. package/dist/src/core/embedding/tokenizer.js +91 -0
  48. package/dist/src/core/embedding/types.js +2 -0
  49. package/dist/src/core/embedding.js +36 -0
  50. package/dist/src/core/git.js +49 -0
  51. package/dist/src/core/gitDiff.js +73 -0
  52. package/dist/src/core/indexCheck.js +131 -0
  53. package/dist/src/core/indexer.js +185 -0
  54. package/dist/src/core/indexerIncremental.js +303 -0
  55. package/dist/src/core/indexing/config.js +51 -0
  56. package/dist/src/core/indexing/hnsw.js +568 -0
  57. package/dist/src/core/indexing/index.js +17 -0
  58. package/dist/src/core/indexing/monitor.js +82 -0
  59. package/dist/src/core/indexing/parallel.js +252 -0
  60. package/dist/src/core/lancedb.js +111 -0
  61. package/dist/src/core/lfs.js +27 -0
  62. package/dist/src/core/log.js +62 -0
  63. package/dist/src/core/manifest.js +88 -0
  64. package/dist/src/core/parser/adapter.js +2 -0
  65. package/dist/src/core/parser/c.js +93 -0
  66. package/dist/src/core/parser/chunkRelations.js +178 -0
  67. package/dist/src/core/parser/chunker.js +274 -0
  68. package/dist/src/core/parser/go.js +98 -0
  69. package/dist/src/core/parser/java.js +80 -0
  70. package/dist/src/core/parser/markdown.js +76 -0
  71. package/dist/src/core/parser/python.js +81 -0
  72. package/dist/src/core/parser/rust.js +103 -0
  73. package/dist/src/core/parser/typescript.js +98 -0
  74. package/dist/src/core/parser/utils.js +62 -0
  75. package/dist/src/core/parser/yaml.js +53 -0
  76. package/dist/src/core/parser.js +75 -0
  77. package/dist/src/core/paths.js +10 -0
  78. package/dist/src/core/repoMap.js +164 -0
  79. package/dist/src/core/retrieval/cache.js +31 -0
  80. package/dist/src/core/retrieval/classifier.js +74 -0
  81. package/dist/src/core/retrieval/expander.js +80 -0
  82. package/dist/src/core/retrieval/fuser.js +40 -0
  83. package/dist/src/core/retrieval/index.js +32 -0
  84. package/dist/src/core/retrieval/reranker.js +304 -0
  85. package/dist/src/core/retrieval/types.js +2 -0
  86. package/dist/src/core/retrieval/weights.js +42 -0
  87. package/dist/src/core/search.js +41 -0
  88. package/dist/src/core/sq8.js +65 -0
  89. package/dist/src/core/symbolSearch.js +143 -0
  90. package/dist/src/core/types.js +2 -0
  91. package/dist/src/core/workspace.js +116 -0
  92. package/dist/src/mcp/server.js +794 -0
  93. package/docs/README.md +44 -0
  94. package/docs/cross-encoder.md +157 -0
  95. package/docs/embedding.md +158 -0
  96. package/docs/logo.png +0 -0
  97. package/docs/windows-setup.md +67 -0
  98. package/docs/zh-CN/DESIGN.md +102 -0
  99. package/docs/zh-CN/README.md +46 -0
  100. package/docs/zh-CN/advanced.md +26 -0
  101. package/docs/zh-CN/architecture_explained.md +116 -0
  102. package/docs/zh-CN/cli.md +109 -0
  103. package/docs/zh-CN/dsr.md +91 -0
  104. package/docs/zh-CN/graph_scenarios.md +173 -0
  105. package/docs/zh-CN/hooks.md +14 -0
  106. package/docs/zh-CN/manifests.md +136 -0
  107. package/docs/zh-CN/mcp.md +205 -0
  108. package/docs/zh-CN/quickstart.md +35 -0
  109. package/docs/zh-CN/rules.md +7 -0
  110. package/docs/zh-CN/technical-details.md +454 -0
  111. package/docs/zh-CN/troubleshooting.md +19 -0
  112. package/docs/zh-CN/windows-setup.md +67 -0
  113. package/install.sh +183 -0
  114. package/package.json +97 -0
  115. package/skills/git-ai-mcp/SKILL.md +86 -0
  116. package/skills/git-ai-mcp/references/constraints.md +143 -0
  117. package/skills/git-ai-mcp/references/tools.md +263 -0
  118. package/templates/agents/common/documents/Fix EISDIR error and enable multi-language indexing.md +14 -0
  119. package/templates/agents/common/documents/Fix git-ai index error in CodaGraph directory.md +13 -0
  120. package/templates/agents/common/skills/git-ai-mcp/SKILL.md +86 -0
  121. package/templates/agents/common/skills/git-ai-mcp/references/constraints.md +143 -0
  122. package/templates/agents/common/skills/git-ai-mcp/references/tools.md +263 -0
@@ -0,0 +1,116 @@
1
+ # 技术架构与选型深度解析
2
+
3
+ 本文档旨在从架构设计角度,深入剖析 `git-ai` 的核心实现原理、关键技术选型及其背后的决策逻辑。适用于技术评审、架构选型参考及二次开发指导。
4
+
5
+ ## 1. 核心架构设计理念
6
+
7
+ `git-ai` 的设计目标是构建一个**轻量级、去中心化、零依赖**的代码库语义索引引擎。不同于传统的集中式代码搜索服务(如 Sourcegraph),`git-ai` 采用“Client-Side Indexing”模式,将索引能力下沉至开发者本地环境。
8
+
9
+ ### 1.1 设计哲学:Hybrid RAG 与 高召回策略
10
+
11
+ 我们采用了 **Hybrid RAG (混合检索增强生成)** 的设计思想,通过不同组件的协同来平衡检索的精度与召回率。核心原则是 **"Recall over Precision"(召回优于精度)** —— 宁可多搜几个交给 AI (LLM) 去过滤,也绝不漏掉潜在的关键信息。
12
+
13
+ * **Tree-sitter (骨架提取)**:负责“精准”的结构化数据。提取代码的类、方法、接口定义,构建代码的“骨架”。
14
+ * **CozoDB (关联推导)**:负责“逻辑”连接。处理继承、实现、包含等图关系,支持多跳查询(如“查找所有子类”)。
15
+ * **LanceDB (语义仲裁)**:负责“模糊”召回。通过 Hash Embedding 捕捉代码的语义特征,即使不知道确切名字,也能通过上下文找到相关代码。
16
+ * **AI (最终过滤)**:作为 RAG 的最后一环,LLM 利用其强大的理解能力,对召回的混合结果进行 Re-ranking 和精确过滤。
17
+
18
+ **核心约束:**
19
+ * **零环境依赖**:不依赖 Docker、JVM、Python 环境,开箱即用。
20
+ * **纯本地运行**:数据隐私优先,无需上传代码至云端。
21
+ * **高性能**:毫秒级检索,索引体积可控(通常 < 代码体积的 20%)。
22
+
23
+ ---
24
+
25
+ ## 2. 索引流水线 (Indexing Pipeline)
26
+
27
+ 索引构建过程是一个典型的 ETL (Extract, Transform, Load) 流程,分为三个阶段:
28
+
29
+ ### 2.1 结构化解析 (Parsing & Chunking)
30
+
31
+ 为了解决传统基于行的分片(Line-based Chunking)导致的语义截断问题,我们采用了基于 AST(抽象语法树)的结构化分片策略。
32
+
33
+ * **技术选型:Tree-sitter**
34
+ * **背景**:GitHub Atom 团队开发的增量解析系统,现已成为代码解析领域的工业标准。
35
+ * **实现机制**:通过 `tree-sitter-{lang}` 生成具体语言的 CST (Concrete Syntax Tree),再通过遍历算法提取 Symbol(类、函数、接口)及其上下文(Range)。
36
+ * **优势**:
37
+ * **多语言支持**:通过统一的 WASM/Node.js 绑定支持几十种主流语言。
38
+ * **容错性**:即使代码存在语法错误,仍能构建部分 AST,保证索引鲁棒性。
39
+ * **性能**:基于 C 编写,解析速度极快(单文件 < 10ms)。
40
+
41
+ ### 2.2 向量化 (Embedding)
42
+
43
+ 这是将非结构化代码转换为结构化向量的关键步骤。
44
+
45
+ * **技术选型:Random Indexing (Deterministic Hash Embedding)**
46
+ * **背景**:一种降维技术,基于 Johnson-Lindenstrauss 引理(高维空间中的随机向量近似正交)。
47
+ * **实现机制**:
48
+ 1. **Tokenization**:对代码标识符进行分词与归一化。
49
+ 2. **Hashing**:计算 Token 的 SHA-256 哈希。
50
+ 3. **Projection**:将哈希映射到固定维度(如 256 维)的稀疏向量中(+1/-1)。
51
+ 4. **Aggregation**:叠加所有 Token 向量并归一化。
52
+ * **决策依据(VS 深度学习模型)**:
53
+ * **Transformer 模型 (如 BERT/OpenAI)**:虽然语义理解强,但模型文件巨大(数百 MB)、推理延迟高、且通常需要 GPU 或云端 API,违背了“轻量级 CLI”的设计初衷。
54
+ * **Hash Embedding**:虽然无法捕捉同义词语义(如 Login ≈ SignIn),但在代码搜索场景中,**精确的标识符匹配**(Identifier Match)往往比模糊语义更重要。该方案实现了**零模型文件依赖、纳秒级推理速度**。
55
+
56
+ ### 2.3 关系图谱构建 (Knowledge Graph)
57
+
58
+ 为了弥补向量检索在结构化查询(如继承关系、嵌套结构)上的不足,我们同步构建了 AST 关系图。
59
+
60
+ * **模型设计**:
61
+ * **节点**:File, Symbol (Class, Method, Interface)
62
+ * **边**:Contains (包含), Extends (继承), Implements (实现)
63
+ * *注:当前版本主要关注“定义(Definition)”关系,暂未包含“引用(Reference/Call Graph)”关系,以保持索引构建的轻量化。*
64
+ * **存储**:将 AST 关系降维为 Datalog 事实表(Facts),存入图数据库。
65
+
66
+ ---
67
+
68
+ ## 3. 存储引擎选型 (Storage Engine)
69
+
70
+ 我们采用了“双引擎”策略,分别处理向量检索和图查询。
71
+
72
+ ### 3.1 向量存储:LanceDB
73
+
74
+ * **技术背景**:基于 Apache Arrow 和 Lance 数据格式的新一代向量数据库。
75
+ * **选型理由**:
76
+ * **Serverless 架构**:不同于 Milvus/Qdrant 需要独立服务进程,LanceDB 是嵌入式的(类似 SQLite),数据即文件。
77
+ * **列式存储**:原生支持 Arrow 格式,Zero-copy 读取,极大降低内存开销。
78
+ * **多模态支持**:单表支持向量索引(IVF-PQ)与标量字段(全文检索),便于混合查询。
79
+ * **Rust 内核**:保证了极高的 I/O 吞吐和稳定性。
80
+
81
+ ### 3.2 图存储:CozoDB
82
+
83
+ * **技术背景**:基于 Datalog 的事务型、关系型/图混合数据库。
84
+ * **选型理由**:
85
+ * **递归查询能力**:原生支持 Datalog 推理规则,能够优雅处理代码中的递归结构(如多层继承链、模块依赖树),这是标准 SQL (SQLite) 难以高效实现的。
86
+ * **轻量级嵌入**:底层存储引擎可插拔(支持 RocksDB, SQLite, Sled),我们默认使用 SQLite 后端,保持了单文件部署的简洁性。
87
+ * **WASM 支持**:具备回退到纯内存 WASM 模式的能力,保证在极端环境下的可用性。
88
+
89
+ ---
90
+
91
+ ## 4. 技术栈横向对比 (Benchmark & Comparison)
92
+
93
+ | 维度 | git-ai (本方案) | Sourcegraph (Zoekt) | CTags / GTags | 基于 OpenAI 的方案 |
94
+ | :--- | :--- | :--- | :--- | :--- |
95
+ | **核心算法** | Hash Embedding + AST Graph | Trigram Index (N-gram) | 正则/词法分析 | LLM Embedding |
96
+ | **检索模式** | 混合检索 (语义+结构) | 精确/正则匹配 | 符号跳转 | 纯语义相似度 |
97
+ | **依赖环境** | Node.js Runtime (零外部依赖) | Go Server, Docker | C 编译环境 | Python/GPU/API Key |
98
+ | **索引体积** | 小 (~15-20%) | 中等 (~30%) | 极小 (<5%) | 极大 (向量维度高) |
99
+ | **语义理解** | 中 (基于词袋模型) | 无 | 无 | 高 |
100
+ | **部署成本** | **极低 (CLI 工具)** | 高 (需运维集群) | 低 | 中/高 |
101
+
102
+ ## 5. 总结与展望
103
+
104
+ `git-ai` 的架构本质上是在**检索效果**与**工程成本**之间寻找的一个极致平衡点。
105
+
106
+ 通过 **Tree-sitter + Hash Embedding + LanceDB + CozoDB** 的组合,我们在不引入任何重型依赖的前提下,实现了对代码库的**语义级(Vector)**和**结构级(Graph)**的双重索引。这种架构特别适合作为 AI Agent 的“代码知识外脑”,为其提供精准、快速的上下文检索能力。
107
+
108
+ ## 6. 按提交语义工件(DSR)
109
+
110
+ 除了面向当前 checkout 的 `.git-ai/` 索引缓存外,`git-ai` 还提供 DSR(Deterministic Semantic Record)作为 **按提交(per-commit)** 的语义工件:
111
+
112
+ - 每个 commit 对应一份 DSR 文件:`.git-ai/dsr/<commit_hash>.json`
113
+ - DSR 必须不可变且确定性;数据库索引仅作可删缓存(可由 DSR + Git 重建)
114
+ - 历史遍历必须从 Git DAG 出发,DSR 只 enrich 节点,不定义边
115
+
116
+ 详见:[DSR 文档](./dsr.md)
@@ -0,0 +1,109 @@
1
+ # 命令行使用
2
+
3
+ ## git 代理模式
4
+
5
+ ```bash
6
+ git-ai init
7
+ git-ai status
8
+ git-ai add -A
9
+ git-ai commit -m "msg"
10
+ git-ai push -u origin main
11
+ ```
12
+
13
+ ## AI 子命令
14
+
15
+ ```bash
16
+ git-ai ai status
17
+ git-ai ai index --overwrite
18
+ git-ai ai index --incremental --staged
19
+ git-ai ai query "search text" --limit 20
20
+ git-ai ai query "get*repo" --mode wildcard --case-insensitive --limit 20
21
+ git-ai ai semantic "semantic query" --topk 10
22
+ git-ai ai graph find "Foo"
23
+ git-ai ai graph children src/mcp/server.ts --as-file
24
+ git-ai ai graph query "?[name, kind] := *ast_symbol{ref_id, file, name, kind, signature, start_line, end_line}" --params "{}"
25
+ git-ai ai dsr context --json
26
+ git-ai ai dsr generate HEAD
27
+ git-ai ai dsr rebuild-index
28
+ git-ai ai dsr query symbol-evolution "GitAIV2MCPServer" --limit 200 --json
29
+ git-ai ai pack
30
+ git-ai ai unpack
31
+ git-ai ai agent install
32
+ git-ai ai hooks install
33
+ git-ai ai serve
34
+ ```
35
+
36
+ 说明:
37
+ - 除 `ai status` 默认输出为人类可读文本外,其余命令输出均为 JSON(便于 Agent/脚本解析)。
38
+ - `ai status --json` 可输出机器可读 JSON。
39
+ - `ai index` 的进度条输出到 stderr,stdout 保持为 JSON(避免破坏管道解析)。
40
+
41
+ ## DSR(按提交、不可变、确定性)
42
+
43
+ DSR 命令入口为 `git-ai ai dsr ...`,产物位于 `.git-ai/dsr/`。
44
+
45
+ - `dsr context`:发现 repo root / HEAD / branch,并检测 DSR 目录状态
46
+ - `dsr generate <commit>`:为单个提交生成 DSR(存在且不同会报错,不会覆盖)
47
+ - `dsr rebuild-index`:从 DSR 重建可删的查询加速索引
48
+ - `dsr query symbol-evolution <symbol>`:只读查询;先遍历 Git DAG,再读取 DSR 附着语义;缺失 DSR 会停止并报错
49
+
50
+ ## Agent 一键安装(skills/rules)
51
+
52
+ 将本仓库内置的 Agent 模板(skills/rules)复制到目标仓库的 `.agents/` 目录,便于主流 code agent 识别与加载。
53
+
54
+ ```bash
55
+ cd /path/to/your-repo
56
+ git-ai ai agent install
57
+ git-ai ai agent install --overwrite
58
+ git-ai ai agent install --to /custom/location/.agents
59
+
60
+ # 可选:安装到 Trae 的 .trae 目录
61
+ git-ai ai agent install --agent trae
62
+ ```
63
+
64
+ ## RepoMap(全局鸟瞰,可选)
65
+
66
+ 为了支持类似 aider 的 repomap 能力(重要文件/符号排名、上下文映射、引导 Wiki 关联阅读),repo map 被集成到 **已有检索命令** 中,默认不输出,避免增加输出体积与 token 消耗。
67
+
68
+ 在需要时,显式开启:
69
+
70
+ ```bash
71
+ git-ai ai query "HelloController" --with-repo-map --repo-map-files 20 --repo-map-symbols 5
72
+ git-ai ai semantic "where is auth handled" --with-repo-map
73
+ ```
74
+
75
+ 参数说明:
76
+ - `--with-repo-map`:在 JSON 输出中附加 `repo_map` 字段
77
+ - `--repo-map-files <n>`:repo map 展示的文件数量上限(默认 20)
78
+ - `--repo-map-symbols <n>`:每个文件展示的符号上限(默认 5)
79
+ - `--wiki <dir>`:指定 Wiki 目录(默认自动探测 `docs/wiki` 或 `wiki`)
80
+
81
+ ## 符号搜索模式(ai query)
82
+
83
+ `git-ai ai query` 默认是子串搜索;当你的输入包含 `*` / `?` 时,或显式指定 `--mode`,可以启用更适合 code agent 的搜索模式:
84
+
85
+ - `--mode substring`:子串匹配(默认)
86
+ - `--mode prefix`:前缀匹配
87
+ - `--mode wildcard`:通配符(`*` 任意串,`?` 单字符)
88
+ - `--mode regex`:正则
89
+ - `--mode fuzzy`:模糊匹配(子序列)
90
+
91
+ 常用参数:
92
+ - `--case-insensitive`:大小写不敏感
93
+ - `--max-candidates <n>`:先拉取候选再过滤的上限(模式为 wildcard/regex/fuzzy 时有用)
94
+
95
+ ## AST 图搜索(CozoDB)
96
+
97
+ > **实战指南**:觉得命令太抽象?请查看 [AST 图谱实战指南](./graph_scenarios.md) 了解如何查找定义、父类、子类等常见场景。
98
+
99
+ `git-ai ai index` 会在 `.git-ai/` 下额外维护一份 AST 关系图数据库(默认文件名:`.git-ai/ast-graph.sqlite`)。
100
+
101
+ 图搜索相关命令:
102
+ - `git-ai ai graph find <prefix>`:按符号名前缀(不区分大小写)查找
103
+ - `git-ai ai graph children <id>`:列出包含关系的直接子节点(`id` 可以是 `ref_id` 或 `file_id`)
104
+ - `git-ai ai graph children <file> --as-file`:把 `<file>` 视作 repo 相对路径,自动换算为 `file_id`
105
+ - `git-ai ai graph query "<CozoScript>" --params '<JSON>'`:直接执行 CozoScript 查询
106
+
107
+ 依赖说明:
108
+ - 默认优先使用 `cozo-node`(SQLite 持久化)
109
+ - 若 `cozo-node` 不可用,会回退到 `cozo-lib-wasm`(内存引擎,通过导出文件实现跨进程复用)
@@ -0,0 +1,91 @@
1
+ # DSR(Deterministic Semantic Record)
2
+
3
+ DSR 是一个 **按提交(per-commit)** 的、**不可变(immutable)**、**确定性(deterministic)** 的语义工件:每个 Git commit 对应一份 DSR 文件。DSR 只负责“丰富提交节点的语义”,**永远不定义 Git DAG 的边**。
4
+
5
+ ## 设计约束(不可违反)
6
+
7
+ - Git commit DAG 是历史与分支的唯一权威来源
8
+ - DSR 按提交生成:一个 commit → 一个 DSR 文件
9
+ - DSR 一旦生成不可修改;若发现冲突,视为系统错误并停止
10
+ - DSR 是规范工件(canonical artifact);数据库/索引仅是可重建缓存(rebuildable cache)
11
+ - 绝不从语义数据推断 Git 拓扑(父子/分支/合并结构)
12
+
13
+ 冲突优先级:
14
+
15
+ Git > DSR > Database > Heuristics
16
+
17
+ 缺失数据处理:
18
+
19
+ - 缓存缺失:从 DSR + Git 重建
20
+ - DSR 缺失:报告并停止(不要推断)
21
+
22
+ ## 存储布局
23
+
24
+ DSR 相关产物位于仓库根目录:
25
+
26
+ - `.git-ai/dsr/<commit_hash>.json`:单提交 DSR(规范工件)
27
+ - `.git-ai/dsr/dsr-index.sqlite`:DSR 查询加速索引(可删缓存)
28
+ - `.git-ai/dsr/dsr-index.export.json`:非 SQLite 后端时的导出快照(用于跨进程复用)
29
+
30
+ ## DSR Schema(v1)
31
+
32
+ 必填字段:
33
+
34
+ - `commit_hash`
35
+ - `affected_symbols`
36
+ - `ast_operations`
37
+ - `semantic_change_type`
38
+
39
+ 可选字段:
40
+
41
+ - `summary`(默认使用 commit subject)
42
+ - `risk_level`
43
+
44
+ 禁止字段(避免编码拓扑/分支信息):
45
+
46
+ - parent commits / branch names / merge topology
47
+
48
+ ## CLI 命令
49
+
50
+ ### Phase 0:上下文发现
51
+
52
+ ```bash
53
+ git-ai ai dsr context --json
54
+ ```
55
+
56
+ 产物(JSON)包含:
57
+
58
+ - `repo_root`
59
+ - `commit_hash`(HEAD commit)
60
+ - `branch` / `detached`
61
+ - `dsr_directory_state`(.git-ai 与 dsr 目录存在性/文件数)
62
+
63
+ ### Phase 2:为单个提交生成 DSR
64
+
65
+ ```bash
66
+ git-ai ai dsr generate <commit>
67
+ ```
68
+
69
+ - `<commit>` 支持任何可解析为 commit 的 rev(例如 `HEAD`、sha、tag)
70
+ - 生成路径固定为 `.git-ai/dsr/<commit_hash>.json`
71
+ - 若文件已存在且内容不同会报错并停止(保证不可变性)
72
+
73
+ ### Phase 3:从 DSR 重建缓存索引
74
+
75
+ ```bash
76
+ git-ai ai dsr rebuild-index
77
+ ```
78
+
79
+ 该索引用于加速查询,语义事实不应只存在于数据库中。
80
+
81
+ ### Phase 6:只读查询(Git DAG 先行)
82
+
83
+ ```bash
84
+ git-ai ai dsr query symbol-evolution <symbol> --limit 200 --json
85
+ ```
86
+
87
+ 行为要点:
88
+
89
+ - 先按 `git rev-list --topo-order` 遍历 DAG
90
+ - 每个 commit 再读取对应 DSR 进行语义附着
91
+ - 遇到缺失 DSR 的 commit 会立刻停止并返回错误(不推断)
@@ -0,0 +1,173 @@
1
+ # AST 图谱实战指南
2
+
3
+ `git-ai ai graph` 命令提供了强大的代码结构查询能力。本文档通过实际场景,介绍如何查找定义、结构、继承关系等。
4
+
5
+ ## 1. 查找定义 (Find Definitions)
6
+
7
+ ### 场景:我知道一个类或方法的名字(或前缀),想找到它在哪里定义。
8
+
9
+ **命令:**
10
+ ```bash
11
+ # 查找名字以 "GitAI" 开头的符号
12
+ git-ai ai graph find "GitAI"
13
+ ```
14
+
15
+ **输出示例:**
16
+ ```json
17
+ {
18
+ "repoRoot": "/path/to/repo",
19
+ "result": {
20
+ "headers": ["ref_id", "file", "lang", "name", "kind", "signature", "start_line", "end_line"],
21
+ "rows": [
22
+ ["...", "src/mcp/server.ts", "ts", "GitAIV2MCPServer", "class", "class GitAIV2MCPServer", 16, 120]
23
+ ]
24
+ }
25
+ }
26
+ ```
27
+
28
+ > **提示**:如果你只记得模糊的名字(如 `*Server`),建议使用 `ai query` 命令配合 wildcard 模式:
29
+ > ```bash
30
+ > git-ai ai query "*Server" --mode wildcard
31
+ > ```
32
+
33
+ ---
34
+
35
+ ## 2. 查看文件结构 (File Structure)
36
+
37
+ ### 场景:我想知道某个文件里定义了哪些类、函数或接口。
38
+
39
+ **命令:**
40
+ 使用 `children` 子命令,并加上 `--as-file` 参数,直接传文件路径:
41
+
42
+ ```bash
43
+ # 查看 src/mcp/server.ts 里的顶层符号
44
+ git-ai ai graph children src/mcp/server.ts --as-file
45
+ ```
46
+
47
+ **输出示例:**
48
+ ```json
49
+ {
50
+ "result": {
51
+ "headers": ["child_id", "file", "lang", "name", "kind", "signature", "start_line", "end_line"],
52
+ "rows": [
53
+ ["...", "src/mcp/server.ts", "ts", "GitAIV2MCPServer", "class", "class GitAIV2MCPServer", 16, 120]
54
+ ]
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### 场景:我想进一步看某个类里有哪些方法。
60
+
61
+ **步骤:**
62
+ 1. 从上一步结果中复制类的 `child_id`(即 `ref_id`)。
63
+ 2. 再次运行 `children` 命令(这次不需要 `--as-file`)。
64
+
65
+ ```bash
66
+ git-ai ai graph children <ref_id_from_previous_step>
67
+ ```
68
+
69
+ ---
70
+
71
+ ## 3. 查找继承与实现 (Inheritance & Implementation)
72
+
73
+ 这部分需要使用 `git-ai ai graph query` 执行 CozoScript。CozoScript 是一种类似 Datalog 的逻辑查询语言。
74
+
75
+ ### 场景:查找某个类的所有子类 (Find Subclasses)
76
+
77
+ 假设你想找所有继承自 `BaseCommand` 的类。
78
+
79
+ **CozoScript:**
80
+ ```cozo
81
+ ?[name, file, start_line] :=
82
+ *ast_extends_name{sub_id, super_name: 'BaseCommand'},
83
+ *ast_symbol{ref_id: sub_id, name, file, lang, kind, signature, start_line, end_line}
84
+ ```
85
+
86
+ **CLI 命令:**
87
+ ```bash
88
+ git-ai ai graph query "?[name, file, lang] := *ast_extends_name{sub_id, super_name: 'BaseCommand'}, *ast_symbol{ref_id: sub_id, name, file, lang, kind, signature, start_line, end_line}"
89
+ ```
90
+
91
+ ### 场景:查找某个接口的所有实现 (Find Implementations)
92
+
93
+ 假设你想找所有实现了 `Runnable` 接口的类。
94
+
95
+ **CozoScript:**
96
+ ```cozo
97
+ ?[name, file] :=
98
+ *ast_implements_name{sub_id, iface_name: 'Runnable'},
99
+ *ast_symbol{ref_id: sub_id, name, file, lang, kind, start_line, end_line}
100
+ ```
101
+
102
+ **CLI 命令:**
103
+ ```bash
104
+ git-ai ai graph query "?[name, file, lang] := *ast_implements_name{sub_id, iface_name: 'Runnable'}, *ast_symbol{ref_id: sub_id, name, file, lang, kind, signature, start_line, end_line}"
105
+ ```
106
+
107
+ ### 场景:查找某个类的父类 (Find Parent Class)
108
+
109
+ 假设你想知道 `MyClass` 继承了谁。
110
+
111
+ **CozoScript:**
112
+ ```cozo
113
+ ?[super_name] :=
114
+ *ast_symbol{ref_id, name: 'MyClass'},
115
+ *ast_extends_name{sub_id: ref_id, super_name}
116
+ ```
117
+
118
+ ---
119
+
120
+ ## 4. 查找引用 (Find References/Usages)
121
+
122
+ AST 图谱现在支持一部分“引用/调用”能力(基于语法树的启发式抽取,按**名字**关联),可用于快速回答:
123
+ - “这个方法/函数被谁调用?”
124
+ - “从这个方法往下会调用到哪些方法(近似调用链)?”
125
+ - “某个符号名在仓库里有哪些引用位置(call/new/type)?”
126
+
127
+ ### 4.1 查引用位置(按名字)
128
+
129
+ ```bash
130
+ git-ai ai graph refs "MySymbol"
131
+ ```
132
+
133
+ ### 4.2 查调用者 / 被调用者(按名字)
134
+
135
+ ```bash
136
+ git-ai ai graph callers "greet"
137
+ git-ai ai graph callees "hello"
138
+ ```
139
+
140
+ ### 4.3 近似调用链(按名字 + 深度)
141
+
142
+ ```bash
143
+ # 从 greet 向上找:谁调用了它、再往上是谁调用了调用者...
144
+ git-ai ai graph chain "greet" --direction upstream --depth 3 --lang java
145
+
146
+ # 从 hello 向下找:hello 里调用了什么、被调用者又调用了什么...
147
+ git-ai ai graph chain "hello" --direction downstream --depth 3 --lang ts
148
+ ```
149
+
150
+ ### 性能与准确性提示(很重要)
151
+
152
+ - `chain` 是“按名字”的启发式调用链:每一跳都会把 `callee_name` 与全仓库同名符号做匹配,跨语言/跨目录也会互相影响
153
+ - 当链路中出现高频通用名字(如 `remove` / `update` / `get` / `list`),同名符号会指数级放大,中间结果暴涨,导致查询变慢
154
+ - 更稳的用法:
155
+ - 优先用 `callers` 精确定位“谁调用了 X”(一跳)
156
+ - 调小 `--depth`(建议从 1/2 开始)
157
+ - 配合 `--limit` 控制返回规模
158
+ - 明确指定语言,避免跨语言噪声:`--lang java` 或 `--lang ts`
159
+ - 如果输出里出现大量单字母(常见于压缩/混淆后的前端代码),用 `chain --min-name-len 2` 过滤掉短名字
160
+
161
+ ---
162
+
163
+ ## 附录:数据表结构参考
164
+
165
+ 如果你想编写更复杂的查询,可以参考以下表结构:
166
+
167
+ - **`ast_symbol`**: `{ ref_id, file, lang, name, kind, signature, start_line, end_line }`
168
+ - **`ast_file`**: `{ file_id, file, lang }`
169
+ - **`ast_contains`**: `{ parent_id, child_id }` (parent_id 可能是 file_id 或 ref_id)
170
+ - **`ast_extends_name`**: `{ sub_id, super_name }`
171
+ - **`ast_implements_name`**: `{ sub_id, iface_name }`
172
+ - **`ast_ref_name`**: `{ from_id, from_lang, name, ref_kind, file, line, col }` (ref_kind: call/new/type)
173
+ - **`ast_call_name`**: `{ caller_id, caller_lang, callee_name, file, line, col }`
@@ -0,0 +1,14 @@
1
+ # Hooks 工作流
2
+
3
+ ## 安装
4
+
5
+ ```bash
6
+ cd /path/to/repo
7
+ git-ai ai hooks install
8
+ git-ai ai hooks status
9
+ ```
10
+
11
+ ## 行为
12
+ - `pre-commit`:自动 `index --incremental --staged` + `pack`,并把 `.git-ai/meta.json`、`.git-ai/lancedb.tar.gz` 加入暂存区(索引内容以 staged 为准)
13
+ - `pre-push`:再次 `pack`,若归档发生变化则阻止 push,提示先提交归档文件
14
+ - `post-checkout` / `post-merge`:若存在 `.git-ai/lancedb.tar.gz` 则自动 `unpack`
@@ -0,0 +1,136 @@
1
+ # Manifest Workspace(`.repo/manifests`)支持(Ref 指针 + 按需索引/查询)
2
+
3
+ 这篇文档说明 `git-ai` 如何在 **Android repo tool** 的 workspace 场景中工作:在 `.../.repo/manifests` 这种 *manifest 仓库* 中,`git-ai` 不会把所有子仓库的索引都塞进 manifest 仓库;而是把 manifest 里的 `<project/>` 视为“ref 指针”,在查询时按需定位/检出对应子仓库,并在子仓库内查询(必要时再构建索引)。
4
+
5
+ 适用目录结构示例:
6
+
7
+ ```text
8
+ workspace/
9
+ .repo/
10
+ manifests/ # 运行 git-ai 的位置
11
+ .git/
12
+ default.xml
13
+ project-a/
14
+ .git/
15
+ ...
16
+ project-b/
17
+ .git/
18
+ ...
19
+ ```
20
+
21
+ ## 背景与目标
22
+
23
+ 在 repo tool workspace 中:
24
+ - **真正的代码**分散在 `workspace/` 下的多个 project 子仓库(`project-a/`、`project-b/`…)
25
+ - **manifest 仓库**位于 `workspace/.repo/manifests`,负责描述 project 列表与 revision
26
+
27
+ 如果把 workspace 下所有源码都索引进 manifest 仓库,会带来:
28
+ - 存储成本高:manifest 仓库的 `.git-ai/` 会膨胀(尤其在多项目 workspace)
29
+ - 性能风险:一次索引要扫描大量目录,且每次增量都集中写到同一个 DB
30
+
31
+ 因此本方案改为:
32
+ - manifest 仓库只索引自身(如需要),不存储所有子仓库索引
33
+ - 子仓库索引由子仓库自己维护(`.git-ai/lancedb/` 或 `.git-ai/lancedb.tar.gz`)
34
+ - 查询时按需切到/拉取对应子仓库,再查询其索引
35
+
36
+ ## 行为概览
37
+
38
+ 当你在 manifest 仓库运行:
39
+
40
+ ```bash
41
+ git-ai ai query SomeClass --limit 20
42
+ ```
43
+
44
+ `git-ai` 会:
45
+ - 解析 manifest(默认 `default.xml`)得到 project 列表(相当于“ref 指针”集合)
46
+ - 对每个 project:
47
+ - 优先使用 workspace 本地已有目录(`workspace/<project path>`)
48
+ - 若本地不存在,则克隆到 `workspace-cache`(在 manifest 仓库的 `.git-ai/` 下,不提交)
49
+ - 切到 manifest 指定的 revision(如果有)
50
+ - 若子仓库已有索引则直接查询;否则按需构建索引后查询
51
+
52
+ ### 流程图(按需查询)
53
+
54
+ ```mermaid
55
+ graph TD
56
+ A["用户在 .repo/manifests 运行 git-ai ai query"] --> B["resolveGitRoot 定位 repoRoot"];
57
+ B --> C["inferWorkspaceRoot: repoRoot 上溯到 workspace 根"];
58
+ C --> D["解析 default.xml 得到 projects"];
59
+ D --> E{"project 在 workspace 是否已存在?"};
60
+ E -->|是| F["直接使用 workspace/{path}"];
61
+ E -->|否| G["clone 到 repoRoot/.git-ai/workspace-cache/{path}"];
62
+ F --> H["checkout revision(如有)"];
63
+ G --> H;
64
+ H --> I{"子仓库是否已有索引?"};
65
+ I -->|有| J["直接查询子仓库 refs/chunks"];
66
+ I -->|无| K["在子仓库内构建索引后再查询"];
67
+ J --> L["聚合结果输出(带 project 信息)"];
68
+ K --> L;
69
+ ```
70
+
71
+ ## 关键实现点
72
+
73
+ ### 1) 推导 workspaceRoot(workspace 根目录)
74
+
75
+ 判断逻辑:
76
+ - 当 `repoRoot` 的路径中包含 `.repo/manifests` 或 `.repo/manifests.git` 时,认为这是 manifest 仓库
77
+ - 将 `workspaceRoot` 设为 `.repo` 的上一级目录(即 workspace 根)
78
+
79
+ 实现入口:[inferWorkspaceRoot](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/core/git.ts)
80
+
81
+ ### 2) Manifest 解析(project 列表作为 ref 指针)
82
+
83
+ 当前实现会读取 manifest 仓库中的 `default.xml`(如果没有则尝试其他 `*.xml`),解析:
84
+ - `<project name path remote revision/>`
85
+ - `<remote name fetch/>` 与 `<default remote revision/>`
86
+
87
+ 相关实现:
88
+ - [manifest.ts](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/core/manifest.ts)
89
+
90
+ ### 3) 子仓库按需检出(workspace 优先,缺失则 cache clone)
91
+
92
+ - 若 `workspace/<project path>` 已存在且是 git 仓库:直接使用
93
+ - 否则 clone 到 `repoRoot/.git-ai/workspace-cache/<project path>`(该目录不应提交)
94
+ - 若 manifest 提供 revision:切到对应 revision(或 `origin/<revision>`)
95
+
96
+ 相关实现:[workspace.ts](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/core/workspace.ts)
97
+
98
+ ### 4) 子仓库索引按需使用(优先现有索引,缺失则构建)
99
+
100
+ 查询时针对每个子仓库:
101
+ - 若存在 `.git-ai/lancedb/`:直接打开查询
102
+ - 否则若存在 `.git-ai/lancedb.tar.gz`:先解包再查询
103
+ - 都不存在时:在该子仓库内按需构建索引,再查询
104
+
105
+ 相关实现:
106
+ - [ensureRepoIndexReady](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/core/workspace.ts)
107
+ - CLI 查询入口:[ai query](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/commands/query.ts)
108
+ - MCP 符号检索在 manifests 场景下也会走按需查询:[server.ts](file:///Users/mars/dev/git-ai/git-ai-cli-v2/src/mcp/server.ts)
109
+
110
+ ### 5) 存储成本与性能策略
111
+
112
+ - manifest 仓库只保存“ref 指针”(manifest XML)与少量运行时缓存(workspace-cache),避免把所有子仓库索引集中存储
113
+ - 查询只触达必要的子仓库,并在拿到足够结果后提前停止
114
+ - workspace-cache 放在 `.git-ai/` 下并通过 `.gitignore` 排除,避免污染 manifest 仓库历史
115
+
116
+ ## 使用方式
117
+
118
+ ### 直接在 manifests 仓库查询
119
+
120
+ ```bash
121
+ cd /ABS/PATH/workspace/.repo/manifests
122
+ git-ai ai query SomeClass --limit 20
123
+ ```
124
+
125
+ 输出里会包含 `rows[].project` 字段,标明结果来自哪个子仓库(以及是从 workspace 还是 cache 来的)。
126
+
127
+ ### 验证模版
128
+
129
+ 仓库内提供了一个最小模版可以一键生成 workspace 并验证:
130
+ - 文档:[repo-manifest-workspace-template/README.md](file:///Users/mars/dev/git-ai/git-ai-cli-v2/examples/repo-manifest-workspace-template/README.md)
131
+ - 初始化脚本:[init-workspace.mjs](file:///Users/mars/dev/git-ai/git-ai-cli-v2/examples/repo-manifest-workspace-template/init-workspace.mjs)
132
+
133
+ ## 已知限制与后续方向
134
+
135
+ - 当前 XML 解析为轻量实现,覆盖常见的 `<remote/>`、`<default/>`、`<project/>` 场景;更复杂的 include/override 还未覆盖。
136
+ - 若 manifest 未提供 remote fetch 且 workspace 本地也不存在对应 project 目录,则无法自动 clone。