Metadata-Version: 2.4
Name: igrep-tme
Version: 0.1.2
Summary: RAG-powered document search — grep meets semantic search
License-Expression: MIT
License-File: LICENSE
Requires-Python: <3.13,>=3.12
Requires-Dist: bm25s>=0.2.0
Requires-Dist: fastapi>=0.115.0
Requires-Dist: html2text>=2024.2.26
Requires-Dist: httpx>=0.27.0
Requires-Dist: huggingface-hub>=0.20.0
Requires-Dist: libsql-experimental>=0.0.50; python_version < '3.14'
Requires-Dist: mcp>=1.0.0
Requires-Dist: nltk>=3.9.0
Requires-Dist: numpy>=1.26.0
Requires-Dist: openai>=1.0.0
Requires-Dist: openpyxl>=3.1.0
Requires-Dist: orjson>=3.11.8
Requires-Dist: pathspec>=0.12.0
Requires-Dist: pillow>=10.0.0
Requires-Dist: pymupdf>=1.24.0
Requires-Dist: python-docx>=1.0.0
Requires-Dist: python-dotenv>=1.0.0
Requires-Dist: python-pptx>=0.6.23
Requires-Dist: rjieba>=0.1.13
Requires-Dist: sqlalchemy-libsql>=0.1.0; python_version < '3.14'
Requires-Dist: sqlmodel>=0.0.22
Requires-Dist: tree-sitter-language-pack>=0.13
Requires-Dist: uvicorn>=0.41.0
Requires-Dist: watchdog>=4.0.0
Requires-Dist: xxhash>=3.5.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pyright>=1.1.408; extra == 'dev'
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4.0; extra == 'dev'
Provides-Extra: markitdown
Requires-Dist: markitdown>=0.1.0; extra == 'markitdown'
Provides-Extra: mlx
Requires-Dist: huggingface-hub>=0.20.0; extra == 'mlx'
Requires-Dist: mlx-embeddings>=0.0.5; extra == 'mlx'
Requires-Dist: mlx-lm>=0.31.1; extra == 'mlx'
Requires-Dist: mlx-vlm[torch]>=0.4.0; extra == 'mlx'
Requires-Dist: mlx>=0.31.0; extra == 'mlx'
Requires-Dist: safetensors>=0.4.0; extra == 'mlx'
Requires-Dist: vllm-mlx>=0.2.6; extra == 'mlx'
Description-Content-Type: text/markdown

# igrep

Agent-first semantic grep。

grep 的可组合性 + 无索引优先的 RAG 召回能力。

支持 Markdown、纯文本、PDF、图片 OCR 等内容类型。默认 **Local-first**，同时兼容 cloud API。

## 一句话定位

`igrep` = 面向 agent 的 **Search-first 检索内核**。

- 主入口是 `igrep "query"`
- 默认就是 grep-like 的 `--mode normal` 召回；无索引也能直接用
- `ask` 是搜索后的轻量辅助层（Web 中集成为搜索页"总结"tab）
- `serve` / Web 是单机 control plane，不是第二套产品
- `local service` 是统一检索内核的本地运行形态，不是第二套检索协议

## 核心原则

- 一个内核：CLI、`/v1/retrieval`、`/api/*`、Web 共用同一检索语义
- 一个主路径：先保证 noindex normal 召回可用，索引只作为增强层叠加
- 单机优先：`serve` 统一承接项目注册、索引调度、文件监听、状态观测和后端配置观测
- Local-first，Cloud-compatible：默认先让本机可用，再兼容远端能力
- 一个旋钮：`noindex | flash | fast | normal | ultra`，noindex 只做转换不建索引，其余只改变质量与延迟

## 平台默认策略

| 平台 | 默认运行时 | daemon 行为 | 例外 |
|------|------------|-------------|------|
| `macOS Apple Silicon` | `managed_local` | `igrep setup` 安装 oMLX (brew)；oMLX 作为 brew service 独立运行，igrep 是纯 HTTP 客户端 | 若用户显式切到 `external_local / cloud`，调整 `.env` 配置即可 |
| `Linux / 非 Apple Silicon macOS` | `external_local / cloud` | 只启动 control plane，不默认拉起本地 AI 服务 | 直接配置 `external_local / cloud` 端点 |

## 最短路径

### macOS（Apple Silicon）最短路径

```bash
uv tool install -U igrep-tme \
  --index-url=https://mirrors.tencent.com/repository/pypi/tencent_pypi/simple \
  --extra-index-url=https://pypi.org/simple
igrep setup

igrep "部署流程" ~/my-repo
igrep project add ~/my-repo   # 注册项目（默认 noindex，自动转换 PDF 等二进制文件）
igrep index ~/my-repo --mode fast  # 需要索引增强时再开启
```

说明：

- `igrep setup` 会安装 oMLX (brew) 等本机依赖，并配置默认端点
- `igrep setup qmd` 可选安装 QMD 查询扩展模型（~2.5GB，提升 normal/ultra 检索质量）
- oMLX 作为 brew service 独立运行，igrep 是纯 HTTP 客户端
- 直接 `igrep "query" path` 就能工作；路径可以是文件或目录，需要进一步收窄时再叠加 `-g/--glob` / `--iglob`
- `igrep project add` 默认 `noindex` 模式：注册项目 + 后台自动转换二进制文件（PDF/Excel 等），搜索走 noindex pipeline
- `igrep index --mode fast/normal/ultra` 开启索引增强后，后台 nightly/watch 自动切到全量构建

### Linux / 远端最短路径

```bash
cat > ~/.igreprc/.env <<'EOF'
IGREP_API_KEY=sk-xxx
IGREP_EMBEDDING_URL=https://api.example.com/v1
IGREP_LLM_URL=https://api.example.com/v1
IGREP_LLM_MODEL=gpt-5-mini
IGREP_RERANK_API_FORMAT=omlx
IGREP_RERANK_URL=https://api.example.com/v1/rerank
EOF

igrep serve start
igrep "部署流程" ~/my-repo
igrep project add ~/my-repo   # 注册项目（默认 noindex，自动转换二进制文件）
igrep index ~/my-repo --mode fast  # 需要索引增强时再开启
```

说明：

- Linux 默认不提供本地 AI 服务；`serve start` 只负责 control plane
- 请直接接 `external_local` 或 `cloud`
- `IGREP_API_KEY` 是共享默认 key
- 若不同能力分属不同 provider，再按 `IGREP_LLM_API_KEY`、`IGREP_EMBEDDING_API_KEY` 等覆写
- 云端增强检索通常使用 `ultra`

## 常用命令

```bash
# 搜索
igrep "query" [path...]
igrep "query" . -g 'src/**/*.py'
igrep "query" . -g '!vendor/**' -g 'src/**'
igrep "query" . --iglob '**/*Test.go'
igrep "query" --type md
igrep "query" --mode flash|fast|normal|ultra
igrep "query" --no-index
igrep "query" --no-index --mode normal
igrep "query" --include '*.log'       # 搜索默认排除的文件类型
igrep "query" --diff                  # 只搜 git 变更文件
igrep "query" --diff HEAD~3           # 只搜最近 3 个 commit 的变更文件
igrep "query" --intent "定位根因"
igrep "query" --all
igrep "query" --project my-repo
igrep "query" --format json --explain
igrep "query" -m 50                   # 最多返回 50 条结果
igrep "query" -C 5                    # 每条结果显示 5 行上下文

# 搜索 + LLM 总结（带 [N] 引用，复用同一检索内核）
igrep ask "部署流程是怎样的" ~/my-repo
igrep ask "query" . --mode normal     # 默认 normal，可切 fast/ultra
igrep ask "query" --max-context-tokens 4000
igrep ask "query" --json              # 结构化输出（answer + citations）

# 项目与索引
igrep project add ~/my-repo              # 默认 noindex，后台自动转换二进制文件
igrep project add ~/my-repo --mode fast  # 注册并开启索引
igrep project list
igrep project remove ~/my-repo
igrep index ~/my-repo                    # 构建索引（更新 registry mode）
igrep index ~/my-repo --mode normal
igrep index ~/my-repo --status
igrep kg build ~/my-repo
igrep convert ~/my-repo             # 预转换二进制文件为 .{name}.igrep.md 隐藏缓存
igrep convert report.pdf             # 单文件转换
igrep convert ~/my-repo --force      # 强制重新转换（忽略缓存）
igrep clean ~/my-repo                # 清除索引（删除 .igrep/ 目录）
igrep clean ~/my-repo --cache        # 仅清除转换缓存（.*.igrep.md 文件）
igrep cache stats                    # 查看持久缓存条目数（embed/llm/rerank）
igrep cache clear                    # 清除所有持久缓存
igrep cache clear --type rerank      # 仅清除指定类型缓存

# 管理服务
igrep serve run                  # 前台运行
igrep serve start                # 后台运行（别名 daemon）
igrep serve stop                 # 停止（感知 launchd/systemd）
igrep serve restart              # 重启
igrep serve status [--strict]    # 状态查看
igrep serve install              # 注册为 OS service（launchd/systemd）
igrep serve uninstall            # 卸载 OS service
```

约定：

- 默认不传路径时，CLI 搜当前目录；只有 `--all` 才展开到全部已注册项目
- `path...` 是搜索根（文件或目录），不是 glob 字符串；glob 过滤统一走 `-g/--glob` / `--iglob`
- `-g/--glob` / `--iglob` 对齐 ripgrep：可重复、支持 `!pattern` 排除、后面的规则覆盖前面的规则
- `--include PATTERN` 覆盖 `BUILTIN_EXCLUDES` 中的指定模式（如 `--include '*.log'`），可重复；搜索和索引均支持
- 默认搜索模式是 `normal`；`project add` 默认 `noindex`（只转换，不建索引）
- 直接搜是主路径：无索引时走 noindex normal 召回；有索引时复用索引增强信号
- indexed 与 noindex 共用同一套 glob 过滤语义
- `--no-index` 强制走 noindex 召回
- `--diff [REF]` 只搜 git 变更文件（默认 HEAD = 未提交变更）
- `-m/--max-count` 控制最大返回条数（默认 20）
- `-C/--context` 控制上下文行数（默认 20，最大 100）
- `--explain` 输出 pipeline 诊断信息到 stderr（不污染 stdout）
- 输出格式：`filepath:startline:` 头 + `lineno: content` 行号前缀（编辑器可解析头行）
- `serve start/stop/restart/status` 统一感知 OS service（launchd/systemd）
- oMLX 作为 brew service 独立运行，通过 `brew services start/stop omlx` 管理

## 单机 Control Plane

`igrep serve` 的角色是单机 supervisor，不是微服务编排器。

它负责：

- 项目注册表：`web_db.project` 是项目成员关系的单一事实源
- 索引调度：`BuildCoordinator` 统一管理 active/queued build
- 文件监听：`WatchManager` 只负责记脏和恢复，不直接拥有调度权
- 管理接口：`/v1/retrieval`、`/health`、`/api/*`
- Web 管理面：项目页、索引页、系统页都消费同一套 control-plane runtime

当前运行态观测口径：

- `/api/projects` / `/api/projects/status`：项目级 `build + watch`
- `/api/index/status`：索引状态 + `build + watch`
- `/api/control-plane/status`：进程级 `coordinator + watch` 摘要

这条控制面是刻意保持单机的：

- 读路径尽量并发
- 写路径仍由 coordinator 串行编排
- watcher 只服务已注册项目；`indexed_root` 是派生缓存，不是项目注册 SSoT

## 模式

产品心智上，默认入口是“直接搜就能有 `normal` 召回”；索引是可选增强，不是使用前提。

| 模式 | 索引侧 | 查询侧 | 典型场景 |
|------|--------|--------|---------|
| `flash` | FTS5 | lexical-only | 最快开始搜索 |
| `fast` | dense | dense + lexical + rerank | 本地高频交互 |
| `normal` | `fast` + summary | `fast` + query-time LLM 扩展 | 默认 grep-like 召回 |
| `ultra` | `normal` + contextual / hierarchy / KG 数据位 | `normal` + 更重增强 | 高价值增强检索 |

补充：

- `normal` 才启用 query-time LLM 扩展
- `--intent` / API `intent` 只用于 query-time LLM phrase/query expansion 的 prompt grounding，并回传为 `intent_used` 元数据；不直接改变召回或 rerank
- `-g/--glob` / `--iglob` 只改变候选文件范围，不改变检索协议或 mode 语义
- `ultra` 的 hierarchy / KG 都是可选增强，不是协议前提
- `--no-index` 强制无索引模式（跳过索引，直接走 noindex pipeline）
- noindex 候选 chunk 采用“双视图”：内部仍用原始文本做 scoring / rerank，对 CLI / Web / ask 展示时再渲染成带 `L{no}:` 行号的 snippet；代码优先展示 symbol 原型 + 命中局部上下文，Markdown 优先展示 heading ancestry + 命中局部上下文

完整矩阵见 `docs/MODE_DESIGN.md`。

## 配置

优先级固定为：

`IGREP_* env > <project>/.igrep/.env > ~/.igreprc/.env > code defaults`

三种后端来源共用同一协议：

- `managed_local`
- `external_local`
- `cloud`

最常用的能力键：

```bash
IGREP_EMBEDDING_URL=...
IGREP_LLM_URL=...
IGREP_LLM_MODEL=...
IGREP_RERANK_API_FORMAT=omlx|tei
IGREP_RERANK_URL=...
```

凭证 fallback：

- `IGREP_API_KEY`
- `IGREP_LLM_API_KEY -> IGREP_API_KEY`
- `IGREP_EMBEDDING_API_KEY -> IGREP_API_KEY`
- `IGREP_OCR_API_KEY -> IGREP_LLM_API_KEY -> IGREP_API_KEY`

协议与本地托管口径见 `docs/LOCAL_SERVICE_PROTOCOL.md`。默认本地模型与轮换口径见 `docs/LOCAL_SERVICE_MODEL_POLICY.md`。

## 文件过滤

igrep 在扫描和搜索时会自动排除不相关文件，过滤源按优先级叠加：

| 过滤源 | 机制 | 说明 |
|--------|------|------|
| `.gitignore` | ripgrep 原生 | 自动发现，递归目录树 |
| `.rgignore` | ripgrep 原生 | 项目级/目录级自定义排除，pattern 相对文件所在目录解析 |
| `~/.igreprc/.rgignore` | 全局 fallback | 用户级排除，对所有项目生效 |
| `BUILTIN_EXCLUDES` | 硬编码 | `.git/`、`node_modules/`、二进制文件等；可用 `--include` 按模式覆盖 |
| `--include PATTERN` | CLI 参数 | 覆盖 `BUILTIN_EXCLUDES` 中的指定模式（如 `*.log`）；搜索和索引均支持 |
| `-g/--glob` / `--iglob` | CLI 参数 | 搜索时临时收窄候选文件 |

`.rgignore` 使用标准 gitignore 语法，由 ripgrep 自动发现和应用。

## Prior Bundle

`<project>/.igrep/context.txt` 是项目先验的唯一手写入口。

igrep 在查询时会把两类信息合并成 scope-aware prior：

- `domain prior`：用户手写的 `.igrep/context.txt`
- `structure prior`：索引生成的 `tree_node / overview`

边界：

- `.igrep/context.txt` 只由用户维护，不会被机器回写
- `tree_node / overview` 只做结构认知缓存，不回写成用户 context
- prior 只帮助路由和组织证据，不替代 chunk / file / dir 结果

## 编辑器 / Agent 集成

```bash
# VS Code 搜索扩展
igrep setup vscode           # 安装到 ~/.vscode/extensions/

# Obsidian 搜索插件
igrep setup obsidian          # 安装到 Obsidian vault

# MCP Server (Claude Code / Codebuddy / Codex)
igrep mcp install

# OpenClaw memory plugin
igrep openclaw plugin setup
igrep openclaw plugin doctor --strict

# Workspace 技能
igrep skill install
```

详细说明见各 README：

- VS Code: `integrations/vscode/igrep-search/README.md`
- Obsidian: `integrations/obsidian/igrep-search/README.md`
- OpenClaw: `integrations/openclaw/igrep-memory/README.md`

## 评测与验证

质量门禁与 benchmark 入口：

```bash
./scripts/verify --fast
./scripts/verify
./scripts/verify --e2e

./scripts/eval-smoke
igrep eval benchmarks/codesearchnet/data/evals/codesearchnet.standard.jsonl --mode fast,normal
```

详细协议见：

- `docs/EVALUATION.md`
- `benchmarks/README.md`

## 文档入口

- 文档导航：`docs/README.md`
- 技术架构：`docs/ARCHITECTURE.md`
- 管理语义 SSoT：`spec/management.md`
- local service 协议 SSoT：`docs/LOCAL_SERVICE_PROTOCOL.md`
- HTTP 契约 SSoT：`spec/openapi.yaml`
- 模式矩阵：`docs/MODE_DESIGN.md`
- Agent 工作流：`docs/AGENT_WORKFLOWS.md`

## 开发

```bash
uv pip install -e ".[dev]"

./scripts/verify --fast
./scripts/verify
./scripts/verify --e2e

cd web && bun run lint
cd web && bun run build
```

说明：

- 前端默认包管理器是 `bun`
- 锁文件 SSoT 是 `web/bun.lock`
- `./scripts/verify` 是默认完整回归入口

## License

MIT
