@easbot/codebase
v0.3.23
Published
Code Knowledge Graph SDK for EASBot - Property Graph model for code indexing and querying with Tree-sitter parsing, FTS hybrid search, and incremental updates
Maintainers
Readme
English | 中文
@easbot/codebase
代码知识图谱 SDK - 基于 Property Graph 模型的代码索引与查询系统
特性
- Property Graph 模型: 使用节点和边存储代码实体及其关系
- 多语言支持: TypeScript、JavaScript、Python、Rust、Go、C/C++、C#、Java、Scala、Ruby、PHP、Zig
- 混合搜索: FTS 全文搜索 + 结构化查询
- 增量更新: 基于文件内容哈希的智能增量索引
- Tree-sitter 解析: 高性能 AST 解析
- 统一 DB 抽象: 通过
@easbot/database的SyncSqliteConnection接入,默认better-sqlite3backend,可切到node:sqlite/@tursodatabase/database
数据库 Backend
packages/codebase 通过 @easbot/database 接入 SQLite,不再直接依赖 better-sqlite3 的裸 binding。DatabaseManager 内部持有 SyncSqliteConnection(同步 facade,对标 codegraph SqliteDatabase),60+ 同步 DB 调用点零改动。
默认 backend:better-sqlite3
DatabaseManager 构造时显式传 backend: 'better-sqlite3',不走 'auto' fallback。理由:
- codebase 性能基线(index / search / sync 各项指标)基于
better-sqlite3同步 binding 测量 - 自动探测在容器 / Linux / Windows 等环境下可能 fallback 到未预期的 backend,runtime 行为难以预测
better-sqlite3@^12.9.0保留为packages/codebase的物理依赖(未移到optionalDependencies),保证安装时一定拉取对应 native binding
Backend 切换路径
应用层可通过 createSyncSqliteConnection({ backend: 'node-sqlite' | '@tursodatabase/database', ... }) 切换。当前 codebase DatabaseManager 硬编码 'better-sqlite3',如需切换请修改 packages/codebase/src/database/database-manager.ts constructor(约 L98)。
完整 backend 抽象与性能对照见:
:memory: 字面量支持
SyncSqliteConnection.initialize 接受 :memory: 字面量(SQLite 生态默认)作为内存库信号;codebase DatabaseManager 跳过 Filesystem.normalize 让字面量透传。
CLI / MCP / Installer
packages/codebase 当前未暴露独立 CLI;调用方通过 createCodebase() API 集成,或通过 easbot 主 CLI(H-M1 阶段落地后)以二级命令 easbot codebase ... 形式调用。
--json 协议(决策 0051 / 规范 v1.3)
所有 CLI 命令支持 --json 输出机器可读 JSON。统一走 @easbot/terminal 的 emitJsonOk(data, meta?) / emitJsonError(code, message):
# 成功响应 schema
easbot codebase status --json
# {
# "ok": true,
# "data": { "rootDir": "...", "configExists": true, "dbExists": true, ... },
# "meta": { "scope": "all" }
# }
# init 路径(决策 0051 新增)
easbot codebase init --json
# {
# "ok": true,
# "data": {
# "configPath": "<worktree>/.easbot/codebase.json",
# "dbPath": "<worktree>/.easbot/db/codebase.db",
# "backend": "better-sqlite3",
# "schemaVersion": 1,
# "created": true,
# "skipped": false,
# "metaInitialized": true
# },
# "meta": { "action": "created" }
# }
#
# 决策 0076:init 现在落地三件套契约(与 memory/note 对齐):
# 1. <worktree>/.easbot/codebase.json — JSON config
# 2. <worktree>/.easbot/db/codebase.db — SQLite db(含 schema + meta 表 5 个 KV)
# 3. db meta 表:version / createdAt / index_state=uninitialized / indexed_with_version=unknown / schema_version
# 二次 init 不带 --force 时 idempotent 跳过;带 --force 时删旧 db 重建三件套。
# 不主动跑 sync;用户显式跑 `easbot codebase sync` 触发首次同步。
# 错误响应 schema
easbot codebase path <missing> --json
# {
# "ok": false,
# "error": { "code": "E_NOT_FOUND", "message": "..." }
# }豁免清单:watch(服务型启动)/ mcp(JSON-RPC 协议)。详见 决策 0051 + CLI 输出规范 v1.3。
Status / Doctor 统一输出格式(决策 0073 / CLI 规范 v1.4)
codebase status / codebase doctor 与 note / memory 三包统一走 @easbot/terminal 的 formatKnowledgeStatus / formatKnowledgeDoctor 渲染,视觉与字段结构完全一致。
status 输出示例
$ easbot codebase status
─ codebase status ─────────────────────────────────────────────────
Root directory E:/work/my-project
Config ✓ E:/work/my-project/.easbot/codebase.json
DB ✓ E:/work/my-project/.easbot/db/codebase.db (12582912 bytes)
Index state ready
Schema version 1
Extraction version 1
Backend better-sqlite3
Last sync 2026-08-31T14:23:11.000Z
Vector enabled ✓
Embedding dims 1536
LLM:
Initialized ✓
Provider openai
Capabilities:
Embedding ✓ text-embedding-3-small
Graph LLM ✓ gpt-4o-mini
Rerank LLM ✗
Counts:
nodes 1247
edges 3891
Healthy ✓doctor 输出示例
$ easbot codebase doctor
─ codebase doctor ─────────────────────────────────────────────────
Healthy ✓
Duration 127 ms
Backend availability:
- better-sqlite3 ✓
- node:sqlite ✗
- @tursodatabase/database ✗
DB stats:
page_count 768
page_size 4096
freelist_count 0
Checks 12 total (0 error, 0 warn, 1 info, 11 ok)
[ok] ✓ database: database file exists and accessible (12 ms)
[ok] ✓ fts: FTS5 available (8 ms)
[ok] ✓ vector: vector index usable (23 ms)
[ok] ✓ schema: schema version matches (2 ms)
[ok] ✓ lock: no lock contention (1 ms)
[ok] ✓ disk_space: sufficient (156 MB free) (3 ms)
[ok] ✓ orphan: no orphan records (18 ms)
[info] ℹ llm: LLM reachable (ping 42 ms) (42 ms)
[ok] ✓ fk_integrity: foreign keys consistent (15 ms)
[ok] ✓ parse_errors: no parse errors in index (21 ms)
[ok] ✓ extraction_version: extraction version matches config (2 ms)
[ok] ✓ embedding_dims_consistency: meta=1536 probe=1536 config=1536 (35 ms)关键字段说明
| 字段 | 说明 |
|------|------|
| LLM.initialized | LLM 是否已初始化(配置有效且可达) |
| LLM.capabilities | 三大能力:embedding / graphLlm / rerankLlm,各显示模型名或 ✗ |
| Vector enabled | 向量索引是否启用 |
| Embedding dims | 实测 embedding 维度(非仅读 config),status 末尾探测并回填 meta 表 |
| embedding_dims_consistency | doctor 第 9 项检查:对比 meta / probe / config 三方维度是否一致 |
JSON 输出(--json)
$ easbot codebase status --json
{
"ok": true,
"data": {
"rootDir": "E:/work/my-project",
"configExists": true,
"dbExists": true,
"indexState": "ready",
"schemaVersion": 1,
"llm": {
"initialized": true,
"capabilities": { "embedding": true, "graphLlm": true, "rerankLlm": false },
"embeddingModel": "text-embedding-3-small",
"graphModel": "gpt-4o-mini",
"providerId": "openai"
},
"counts": { "nodes": 1247, "edges": 3891 },
"healthy": true
},
"meta": { "scope": "all" }
}兼容 CLI 输出规范 v1.4 / 决策 0040。
安装
pnpm add @easbot/codebase快速开始
import { createCodebase } from '@easbot/codebase';
// 创建图谱实例
const graph = await createCodebase({
workspaceDir: '/path/to/your/project',
});
// 索引项目
const result = await graph.indexDirectory();
console.log(`索引完成: ${result.filesProcessed} 文件, ${result.nodesCreated} 节点`);
// 搜索代码
const results = await graph.search('UserService');
for (const r of results) {
console.log(`${r.name} (${r.astType}) - ${r.filePath}:${r.startLine}`);
}
// 查询节点
const classes = await graph.queryNodes({ astType: 'class_declaration' });
// 查询调用图
const callGraph = await graph.queryCallGraph('ts:src/service.ts:function_declaration:UserService');
// 关闭图谱
await graph.close();API 文档
CodeKnowledgeGraph
主类,提供完整的代码知识图谱功能。
构造选项
interface CodeKnowledgeGraphConfig {
workspaceDir: string; // 工作区目录
database?: {
path: string; // 数据库路径
walMode?: boolean; // WAL 模式
};
parser?: {
languages?: Language[]; // 支持的语言
lazyLoad?: boolean; // 延迟加载
};
indexer?: {
batchSize: number; // 批处理大小
ignorePatterns: string[]; // 忽略模式
incremental: boolean; // 增量更新
};
}主要方法
| 方法 | 说明 |
|------|------|
| initialize() | 初始化图谱 |
| indexFile(path) | 索引单个文件 |
| indexDirectory(dir?) | 索引目录 |
| sync() | 增量同步 |
| search(query, options?) | 混合搜索 |
| queryNodes(filter) | 查询节点 |
| queryEdges(filter) | 查询边 |
| queryNeighbors(nodeId, options?) | 查询邻居 |
| queryCallGraph(nodeId, depth?) | 查询调用图 |
| queryInheritance(nodeId) | 查询继承关系 |
| getStatus() | 获取状态 |
| healthCheck() | 健康检查 |
| close() | 关闭图谱 |
搜索选项
interface SearchOptions {
maxResults?: number; // 最大结果数
minScore?: number; // 最小分数
language?: Language; // 语言过滤
filePath?: string; // 文件路径过滤
astType?: string; // AST 类型过滤
enableFts?: boolean; // 启用 FTS
ftsWeight?: number; // FTS 权重
}Name Lookup 行为(决策 0087)
5 个图操作(node / callers / callees / impact / context)通过共享 resolveName() 函数定位节点。本节说明其匹配语义与 LLM 推荐用法。
3 层 SQL fallback(按优先级)
| 层级 | 匹配模式 | SQL 条件 | 适用场景 |
|------|---------|---------|---------|
| 1. exact | name 字段全等 | WHERE name = ? | 短类名 / namespace / 完全限定名(含 @<line>) |
| 2. qualified | name 含目标字符串(兜底) | WHERE name LIKE %?% | 短方法名 / 类名前缀不匹配 |
| 3. substring | 前两层全空 + file/kind 过滤 | WHERE name LIKE %?% AND file_path/kind | 极端罕见场景(如类名拼写模糊) |
LLM 推荐用法(workflow)
search → (pick name + file) → callers | callees | impact | context | node
↑ ↓
└─────────────── explore (PRIMARY, source code + 1-level) ←──────┘Step 1:先用 search(query="AuthService") 拿到 name + file_path。
Step 2:以 search 返回的 name + file 作为后续操作的输入:
// ✅ 推荐:短类名 + file 过滤(最强消歧信号)
await service.callers(ctx, { name: 'AuthService', file: 'auth-service.ts' });
// ✅ 推荐:完全限定名(name 含 namespace + @<line>)
await service.callers(ctx, { name: 'AuthService.login@20' });
// ✅ 推荐:nodeId 直接定位(零歧义)
await service.callers(ctx, { nodeId: 'ts:src/auth-service.ts:method_definition:AuthService.login@20' });
// ❌ 反模式:短类名 + 无 file
await service.callers(ctx, { name: 'AuthService' });
// → AmbiguousError: 3 candidates (AuthService 类 + AuthService.login@20 + AuthService.validate@30)错误处理
| 错误 | 触发条件 | 修复 |
|------|---------|------|
| NotFoundError | 0 候选 | 检查 name 拼写 / 拼写错误 / 不存在的符号 |
| AmbiguousError | ≥2 候选且无 file 消歧 | 从错误返回的 candidates[] 列表中选一个 name + file 重试 |
数据模型
节点 (Node)
| 字段 | 类型 | 说明 | |------|------|------| | id | string | 唯一标识 | | name | string | 名称 | | ast_type | string | AST 类型 | | language | string | 语言 | | file_path | string | 文件路径 | | start_line | number | 起始行 | | start_col | number | 起始列 | | end_line | number | 结束行 | | end_col | number | 结束列 | | text | string | 代码文本 |
边 (Edge)
| 字段 | 类型 | 说明 | |------|------|------| | id | string | 唯一标识 | | source | string | 源节点 ID | | target | string | 目标节点 ID | | relation | string | 关系类型 |
关系类型
| 关系 | 说明 | |------|------| | CONTAINS | 包含关系(类包含方法) | | CALLS | 调用关系(函数调用) | | INHERITS_FROM | 继承关系 | | IMPLEMENTS | 实现接口 | | IMPORTS | 导入模块 | | REFERENCES | 引用关系 |
架构
src/
├── types.ts # 类型定义
├── errors.ts # 错误类
├── index.ts # 入口文件
├── code-knowledge-graph.ts # 主类
├── database/
│ └── database-manager.ts # 数据库管理
├── parser/
│ └── parser-manager.ts # 解析器管理
├── extractor/
│ ├── node-extractor.ts # 节点提取
│ └── edge-extractor.ts # 边提取
├── indexer/
│ └── indexer.ts # 索引器
└── query/
└── query-interface.ts # 查询接口开发
# 安装依赖
pnpm install
# 构建
pnpm build
# 测试
pnpm test
# 类型检查
pnpm type-check
# 代码检查
pnpm lint许可证
MIT
