内容
# hald
**你的代码库,被掌控。**
<sub>*源自古诺斯语 **hald** — 持有,保持。*</sub>
GraphRAG驱动的代码库智能工具。利用Git历史记录(提交记录、作者、文件、关系)构建知识图谱,并允许你使用自然语言查询它。就像拥有了一名高级工程师,他阅读了每一个提交记录,可以立即回答你关于代码库的任何问题。
<p align="center">
<a href="https://www.npmjs.com/package/haldy"><img src="https://img.shields.io/npm/v/haldy?style=flat-square" alt="npm 版本"></a>
<a href="https://github.com/gabrielcarvvlho/hald/actions"><img src="https://img.shields.io/github/actions/workflow/status/gabrielcarvvlho/hald/ci.yml?style=flat-square" alt="CI"></a>
<a href="https://github.com/gabrielcarvvlho/hald/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="MIT License"></a>
</p>
<p align="center">
<a href="docs/assets/hero.gif">
<img src="docs/assets/hero.gif" alt="Hald 可视化:社区,摘要,点击解释" width="820">
</a>
</p>
> 运行 `hald scan` 一次。然后 `hald graph` 打开一个交互式的代码库知识图谱视图 — 社区以LLM生成的摘要标记,顶级专家突出显示,点击任意集群进行解释。
## 快速开始
```bash
# 安装(需要 Node.js 20+)
npm install -g haldy
# 立即试用 — 零密钥,零成本:打开一个内置的演示图
hald graph --mock
# 扫描您的仓库(如果设置了LLM API密钥,则使用;否则回落到无密钥的代理中介路径)
cd your-repo
hald scan
# 提问
hald ask "谁最了解计费模块?"
hald ask "为什么我们迁移到 gRPC?"
hald ask "最近 3 个月内有什么变化?"
hald stats
```
没有API密钥?`hald scan` 回落到 **代理中介提取** — 您的AI代理自己执行实体提取,零额外成本(参见 [LLM 提供商](#llm-提供商))。
## 工作原理
```
git log
|
v
Chunker (提交记录 -> 重叠文本单元)
|
v
LLM 提取 (实体:人员,模块,决策,模式)
|
v
实体解析器 (重复数据删除 + 规范名称)
|
v
知识图谱 (节点 + 加权边在 SQLite 中)
|
v
社区检测 (Louvain 聚类 + LLM 摘要)
|
v
MCP 工具 (hald_find_expert, hald_trace_decision, ...)
|
v
您的 AI 代理 (使用其自己的令牌合成答案)
```
扫描消耗令牌。查询始终免费 — 工具返回结构化图数据,您的代理进行推理。
## 可视化浏览器
```bash
hald graph # 打开真正的索引(默认)
hald graph --mock # 打开一个内置的固定图用于设计迭代
```
在您的浏览器中打开一个交互式可视化。内置:
- **大气画布** — 微妙的径向渐变赋予集群深度。为不支持 `radial-gradient` 的浏览器提供可靠的备用方案。
- **社区以LLM摘要标记** — 每个集群的标题浮动在集群最顶部的节点上方(不在质心上,因此它永远不会位于节点上)。悬停查看完整摘要,点击打开一个带有前 5 个实体的详细信息卡。
- **默认显示顶级专家** — 最具连接性的节点在首次绘制时被标记,以便您立即拥有锚点。
- **权重映射边** — 厚度和阿尔法比例与关系权重(对数映射)。沉重的连接感觉沉重;跨集群的桥梁保持安静。边作为二次贝塞尔曲线渲染在 2D 叠加层上,位于 WebGL 画布下方。
- **悬停聚焦光环** — 活动节点获得柔和的琥珀色到社区颜色的光环。静止状态保持干净(无甜甜圈重叠)。
- **呼吸运动** — 节点在其布局位置周围轻轻漂移,通过不相关的正弦振荡器。尊重 `prefers-reduced-motion: reduce`。
- **悬停涟漪** — 悬停节点的邻居会短暂脉动,以便于局部邻域一目了然。
- **Cmd-click 路径** — ⌘-click(mac)或 Ctrl-click(linux/win)第二个节点,同时选择一个节点以跟踪最短路径。路径以琥珀色突出显示,并带有浮动横幅,显示完整的跳跃列表和每个节点之间的关系类型(`Alice ─authored→ src/extractor ─uses→ src/store`)。点击任意跳跃以导航,而不会丢失路径。Esc / ✕ / 点击空白空间以清除。
- **缩放驱动的标签密度** — 缩放超过 ~0.4× 以查看所有标签,缩放超过 2× 以仅显示社区标签。
- **搜索和过滤** — `/` 聚焦搜索,输入芯片切换实体类型开启/关闭,`Esc` 关闭面板。“0 匹配”在画布顶部内联显示。
- **浅色 + 深色模式** — 遵循系统偏好,在标题栏中可切换。悬停标签药丸根据主题重新着色,以保持可读性。
- **可分享的URL** — 所选节点和活动过滤器在URL哈希中持久存在。复制/粘贴以发送特定视图。
- **PNG导出** — 一键保存当前视图为图像。捕获弯曲边缘叠加层和实时社区标签。
- **键盘导航** — 箭头键平移,`/` 搜索,`Esc` 关闭 / 清除路径 / 关闭侧边栏。
- **模拟模式** — `hald graph --mock` 启动一个精心策划的固定图(~50 个实体,6 个社区),用于无需重新索引或任何LLM成本的可视化迭代。
完全离线工作 — 无CDN依赖。
## 你可以问
| 问题类型 | 示例 | 使用的工具 |
|---|---|---|
| 所有权 | "谁最了解支付模块?" | `hald_find_expert` |
| 决策 | "为什么我们从REST切换到gRPC?" | `hald_trace_decision` |
| 耦合 | "我修改身份验证层时什么会中断?" | `hald_show_coupling` |
| 孤岛 | "代码库中有没有没人碰过的部分?" | `hald_find_silos` |
| 关系 | "队列系统和计费如何连接?" | `hald_get_path` |
| 自由格式 | "总结数据管道的架构" | `hald_query` |
## LLM 提供商
hald 自动检测您可用的API密钥。在运行 `hald scan` 之前设置以下任意一个以获得最快、最高质量的索引。未设置密钥?hald 回落到 **代理中介提取** — 您的AI代理自己执行提取,零额外成本。
| 提供商 | 环境变量 | 默认模型 | 每 1k 次提交的成本 |
|---|---|---|---|
| Anthropic | `ANTHROPIC_API_KEY` | claude-sonnet-4-6 | ~$0.50-$1.00 |
| OpenAI | `OPENAI_API_KEY` | gpt-5.4-mini | ~$0.50-$1.00 |
| Google | `GOOGLE_API_KEY` | gemini-3.1-flash-lite-preview | ~$0.15-$0.40 |
| Zhipu AI | `ZHIPU_API_KEY` | glm-4-flash | ~$0.05-$0.15 |
| Ollama(本地) | `OPENAI_API_KEY` + `HALD_BASE_URL` | 可配置 | $0.00 |
查询始终免费 — 查询时无LLM调用。
## 平台设置
### Claude Code
将 hald 添加到您的项目的 `.mcp.json` 中:
```json
{
"mcpServers": {
"hald": {
"command": "npx",
"args": ["haldy", "serve"]
}
}
}
```
### Cursor
添加到您项目的 `.cursor/mcp.json` 中:
```json
{
"mcpServers": {
"hald": {
"command": "npx",
"args": ["haldy", "serve"],
"env": {
"ANTHROPIC_API_KEY": "${env:ANTHROPIC_API_KEY}"
}
}
}
}
```
### Codex
参见 [`.codex/INSTALL.md`](.codex/INSTALL.md) 以获取设置说明。
### OpenCode
将 `.opencode/plugins/hald.js` 复制到您的 OpenCode 插件目录中。
### Gemini CLI
直接从仓库安装:
```bash
gemini extensions install https://github.com/gabrielcarvvlho/hald
```
或从本地checkout安装(Gemini扩展是目录,不是单个文件):
```bash
mkdir -p ~/.gemini/extensions/hald && cp gemini-extension.json ~/.gemini/extensions/hald/
```
## CLI 参考
```
hald scan [options] 构建或更新知识图谱
--full 强制完整重新扫描(忽略现有索引)
--max-commits <n> 限制要处理的提交记录数量
--since <date> 仅扫描此日期(YYYY-MM-DD)之后的提交记录
--provider <name> LLM 提供商:anthropic | openai | google | zhipu | auto
-y, --yes 跳过成本确认提示
hald ask <question> 提问一个自然语言问题
--type <type> 搜索策略:local | global | auto
hald stats 显示索引统计信息
hald graph 在浏览器中打开交互式图谱可视化
--mock 使用内置的固定图(不需要索引)
--port <number> HTTP 服务器端口(默认 3742)
--no-open 不要自动打开浏览器
hald reset 删除本地索引并重新开始
hald serve 在stdio上启动MCP服务器
```
## 配置
配置优先级(优先生效):
1. CLI 标志 / MCP 工具参数
2. 仓库根目录中的 `.hald/config.json`
3. 环境变量(`HALD_*`)
4. 默认值
| 环境变量 | 描述 | 默认值 |
|---|---|---|
| `HALD_PROVIDER` | 扫描的LLM提供商 | `auto` |
| `HALD_MODEL` | 重写默认模型 | 提供商默认值 |
| `HALD_BASE_URL` | 自定义端点(Ollama,OpenRouter,Azure) | -- |
| `HALD_MAX_COMMITS` | 要扫描的最大提交记录 | 无限制 |
## 存储
索引存储在 `.hald/` 下,位于仓库根目录。添加到 `.gitignore` 中:
```
.hald/
```
可以安全删除 — 再次运行 `hald scan` 以重建。
## 开发
```bash
git clone https://github.com/gabrielcarvvlho/hald.git
cd hald
npm install
npm run build
npm test
```
参见 [CONTRIBUTING.md](CONTRIBUTING.md) 以获取指南。
## 许可证
MIT