基于 Git 的语义版本控制。
sem 告诉你哪些实体发生了变化:函数、方法、类,而不仅仅是更改的行数。
为什么选择 sem? ·
安装 ·
命令 ·
MCP Server ·
版本发布
sem 是一个构建于 Git 之上的语义版本控制工具。它使用 tree-sitter 解析代码,将每个函数、类和方法提取为实体,并在实体级别而非行级别进行差异对比。这意味着你会看到“函数 `blahh` 已修改”,而不是“x-y 行已更改”。
它适用于任何 Git 仓库,无需设置。
## 安装
```
brew install sem-cli
```
或者将 npm wrapper 安装到 `node_modules` 中:
```
npm install --save-dev @ataraxy-labs/sem
```
使用 Bun 时,请信任该包,以便其 `postinstall` 脚本可以下载二进制文件:
```
bun add -d @ataraxy-labs/sem
bun pm trust @ataraxy-labs/sem
```
或者从源码构建(需要 Rust):
```
git clone https://github.com/Ataraxy-Labs/sem
cd sem/crates
cargo install --path sem-cli
```
或者从 [GitHub Releases](https://github.com/Ataraxy-Labs/sem/releases) 获取二进制文件。
或者通过 Docker 运行:
```
docker build -t sem .
docker run --rm -it -u "$(id -u):$(id -g)" -v "$(pwd):/repo" sem diff
```
## 命令
适用于任何 Git 仓库。无需设置。也可在 Git 之外用于任意文件比较。
### sem diff
实体级 diff,具有重命名检测、结构哈希和单词级内联高亮。
```
# 工作更改的 Semantic diff
sem diff
# 仅 Staged 更改
sem diff --staged
# 特定 commit
sem diff --commit abc1234
# Commit 范围
sem diff --from HEAD~5 --to HEAD
# Verbose 模式(每个实体的 word-level inline diffs)
sem diff -v
# 纯文本输出(git status 样式)
sem diff --format plain
# JSON 输出(适用于 AI agents、CI pipelines)
sem diff --format json
# Markdown 输出(适用于 PRs、reports)
sem diff --format markdown
# 比较任意两个文件(无需 git repo)
sem diff file1.ts file2.ts
# 从 stdin 读取文件更改(无需 git repo)
echo '[{"filePath":"src/main.rs","status":"modified","beforeContent":"...","afterContent":"..."}]' \
| sem diff --stdin --format json
# 仅特定文件类型
sem diff --file-exts .py .rs
```
### sem impact
跨文件依赖图,显示如果实体发生变化会破坏什么。
```
# Full impact analysis
sem impact authenticateUser
# 仅 Direct dependencies
sem impact authenticateUser --deps
# 仅 Direct dependents
sem impact authenticateUser --dependents
# 仅受影响的 tests
sem impact authenticateUser --tests
# JSON 输出
sem impact authenticateUser --json
# 按文件 Disambiguate
sem impact authenticateUser --file src/auth.ts
```
### sem blame
实体级 blame,显示谁最后修改了每个函数、类或方法。
```
sem blame src/auth.ts
# JSON 输出
sem blame src/auth.ts --json
```
### sem log
跟踪单个实体在 git 历史中的演变过程。
```
sem log authenticateUser
# Verbose 模式(显示版本之间的 content diff)
sem log authenticateUser -v
# 限制扫描的 commits
sem log authenticateUser --limit 20
# JSON 输出
sem log authenticateUser --json
```
### sem entities
列出文件中的所有实体及其类型和行范围。
```
sem entities src/auth.ts
# JSON 输出
sem entities src/auth.ts --json
```
### sem context
适用于 LLM 的 token 预算上下文:实体、其依赖项及其依赖项,适配 token 预算。
```
sem context authenticateUser
# 自定义 token budget
sem context authenticateUser --budget 4000
# JSON 输出
sem context authenticateUser --json
```
## 用作默认 Git diff
用实体级 diff 替换 `git diff` 输出。Agent 和人类无需更改任何命令即可自动获取 sem 输出。
```
sem setup
```
现在 `git diff` 显示实体级变更,而不是行级变更。无需提示,无需 agent 配置。任何调用 `git diff` 的地方都会自动获取 sem 输出。还会安装一个 pre-commit hook,显示暂存变更的实体级影响范围。
要禁用并恢复到正常的 git diff:
```
sem unsetup
```
## 支持解析的内容
23 种编程语言,通过 tree-sitter 进行完整的实体提取:
| 语言 | 扩展名 | 实体 |
|----------|-----------|----------|
| TypeScript | `.ts` `.tsx` `.mts` `.cts` | functions, classes, interfaces, types, enums, exports |
| JavaScript | `.js` `.jsx` `.mjs` `.cjs` | functions, classes, variables, exports |
| Python | `.py` | functions, classes, decorated definitions |
| Go | `.go` | functions, methods, types, vars, consts |
| Rust | `.rs` | functions, structs, enums, impls, traits, mods, consts |
| Java | `.java` | classes, methods, interfaces, enums, fields, constructors |
| C | `.c` `.h` | functions, structs, enums, unions, typedefs |
| C++ | `.cpp` `.cc` `.hpp` | functions, classes, structs, enums, namespaces, templates |
| C# | `.cs` | classes, methods, interfaces, enums, structs, properties |
| Ruby | `.rb` | methods, classes, modules |
| PHP | `.php` | functions, classes, methods, interfaces, traits, enums |
| Swift | `.swift` | functions, classes, protocols, structs, enums, properties |
| Elixir | `.ex` `.exs` | modules, functions, macros, guards, protocols |
| Bash | `.sh` | functions |
| HCL/Terraform | `.hcl` `.tf` `.tfvars` | blocks, attributes (qualified names for nested blocks) |
| Kotlin | `.kt` `.kts` | classes, interfaces, objects, functions, properties, companion objects |
| Fortran | `.f90` `.f95` `.f` | functions, subroutines, modules, programs |
| Vue | `.vue` | template/script/style blocks + inner TS/JS entities |
| XML | `.xml` `.plist` `.svg` `.csproj` | elements (nested, tag-name identity) |
| ERB | `.erb` `.html.erb` | blocks, expressions, code tags |
| Svelte | `.svelte` `.svelte.js` `.svelte.ts` | component blocks + rune JS/TS modules |
| Perl | `.pl` `.pm` `.t` | subroutines, packages |
| Dart | `.dart` | classes, mixins, extensions, enums, type aliases, functions |
加上结构化数据格式:
| 格式 | 扩展名 | 实体 |
|--------|-----------|----------|
| JSON | `.json` | properties, objects (RFC 6901 paths) |
| YAML | `.yml` `.yaml` | sections, properties (dot paths) |
| TOML | `.toml` | sections, properties |
| CSV | `.csv` `.tsv` | rows (first column as identity) |
| Markdown | `.md` `.mdx` | heading-based sections |
其他所有内容均回退到基于块的 diff。
## 匹配工作原理
三阶段实体匹配:
1. **精确 ID 匹配** — before/after 中的同一实体 = 已修改或未更改
2. **结构哈希匹配** — 相同的 AST 结构,不同的名称 = 已重命名或已移动(忽略空格/注释)
3. **模糊相似度** — >80% token 重叠 = 可能重命名
这意味着 sem 可以检测重命名和移动,而不仅仅是添加和删除。结构哈希还可以区分表面更改(空格、格式)与实际逻辑更改。
## MCP Server
sem 包含一个 MCP server,为 AI agent 提供 6 个工具:`sem_entities`, `sem_diff`, `sem_blame`, `sem_impact`, `sem_log`, `sem_context`。这些与 CLI 命令完全一致。
```
{
"mcpServers": {
"sem": {
"command": "sem-mcp"
}
}
}
```
安装 MCP 二进制文件:
```
cd sem/crates
cargo install --path sem-mcp
```
## JSON 输出
```
sem diff --format json
```
```
{
"summary": {
"fileCount": 2,
"added": 1,
"modified": 1,
"deleted": 1,
"total": 3
},
"changes": [
{
"entityId": "src/auth.ts::function::validateToken",
"changeType": "added",
"entityType": "function",
"entityName": "validateToken",
"filePath": "src/auth.ts"
}
]
}
```
## 作为库使用
sem-core 可用作 Rust 库依赖:
```
[dependencies]
sem-core = { git = "https://github.com/Ataraxy-Labs/sem", version = "0.3" }
```
被 [weave](https://github.com/Ataraxy-Labs/weave)(语义合并驱动)和 [inspect](https://github.com/Ataraxy-Labs/inspect)(实体级代码审查)使用。
## 架构
- **tree-sitter** 用于代码解析(原生 Rust,而非 WASM)
- **git2** 用于 Git 操作
- **rayon** 用于并行文件处理
- **xxhash** 用于结构哈希
- 插件系统,用于添加新语言和格式
## 贡献
想添加新语言?请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 获取分步指南。
## Star History
[](https://star-history.com/#Ataraxy-Labs/sem&Date)
## License
MIT OR Apache-2.0