This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Loci 是一个极简 CLI 启动器,用 Rust 编写。它扫描 PATH 环境变量,列出所有可执行文件,并允许通过模糊搜索启动。设计哲学:"只列出,只跳转" — 不管理版本、不安装包、不记忆别名。
- 包名:
loci-cli(crates.io) / 二进制名loci - 版本:
0.2.1(见Cargo.toml) - 仓库: 同时是 Rust 项目和 AI Agent Skill 包
- Agent 入口:
SKILL.md· 工作流见AGENTS.md
cargo build # Debug 构建
cargo build --release # Release(opt-level="z" + LTO + strip + panic=abort)
cargo test # 运行所有单元测试 + 集成测试
cargo test -- --test-threads=1 # 单线程运行(usage 测试共享磁盘文件,需串行)
cargo test args::tests # 只跑某个模块,如 cargo test scanner::tests
cargo test --test cli # 只跑集成测试
cargo test parse_args_default # 按名称过滤
cargo run -- [args] # 直接运行(无需安装)
cargo install --path . # 安装到本地 PATHRelease profile 在 Cargo.toml 中定义:opt-level = "z", lto = true, strip = true, codegen-units = 1, panic = "abort"。
src/
├── main.rs # 薄入口:解析 → 扫描 → 分发 list/exec;report_error 双通道错误
├── args.rs # 参数解析(ParsedArgs / SelectMode / SortMode / fuzzy_match)
├── list.rs # 列表模式:过滤 → meta → 标签 → 排序 → limit/count → 文本/JSON
├── exec.rs # 选择与启动:interactive / pick-first / exact / index + launch
├── scanner.rs # PATH 扫描、SHA-256 缓存、黑名单、--project 检测
├── metadata.rs # 版本探测、类别推断、用户 tags 合并
├── ui.rs # skim 模糊查找 TUI
├── usage.rs # 使用频率追踪与排序(~/.local/share/loci/usage.json)
└── platform.rs # 可执行检测(Unix 权限位 / Windows PATHEXT)
tests/
└── cli.rs # 端到端集成测试(26 场景,驱动编译后的二进制)
npm/ # npm 分发包 @yaemikoreal/loci(postinstall 下载二进制)
completions/ # Shell 补全(bash/zsh/fish)
docs/usage.md # 完整操作文档
scripts/loci-list # Python 封装,供 Agent 调用
CLI args
→ args::parse_args()
→ Scanner::new()
→ project_mode ? collect_project() : collect()
→ list_mode ? list::output_list() : exec::exec_select()
PATH (+ LOCI_PATH_EXTRA)
→ scanner::collect()
→ SHA-256 指纹检查缓存 (~/.cache/loci/cache.json)
→ 命中 → 直接返回
→ 未命中 → 扫描 → 黑名单过滤 → 首次出现去重 → 字母序 → 写缓存
→ 列表:filter → (meta/tag) → sort → limit/count → 文本/JSON
→ 交互:skim TUI → record_usage → launch
约 130 个测试:~104 单元(各模块 #[cfg(test)])+ 26 集成(tests/cli.rs)。
| 模块 | 约计 | 说明 |
|---|---|---|
args |
47 | 参数解析与 fuzzy_match |
metadata |
20 | 类别推断、版本探测、tags |
scanner |
19 | 扫描、缓存、项目目录 |
usage |
13 | 频率排序与持久化 |
platform |
5 | 可执行检测 |
cli 集成 |
26 | 真二进制 E2E |
| 模式 | 说明 | 位置 |
|---|---|---|
temp_dir(label) |
$TMPDIR/loci-*-<label>-<pid> |
scanner/metadata/platform |
touch_exec(path) |
可执行文件(Unix 0o755 / Windows .exe) |
scanner |
scan_name(name) |
平台感知扫描名(Windows 含 .exe) |
scanner 断言 |
write_version_script(...) |
版本探测用脚本 | metadata |
setup_usage / teardown_usage |
写/清真实 data 目录 usage.json |
usage |
Scanner::test_new(...) |
跳过真实配置加载 | scanner |
重要:usage.rs 测试共享 dirs::data_dir()/loci/usage.json,必须串行:cargo test -- --test-threads=1。
通过 env!("CARGO_BIN_EXE_loci") 驱动二进制;用自定义 PATH 隔离系统工具:
fn create_executable(dir: &Path, name: &str) -> PathBuf
fn loci_with_path(args: &[&str], path: &str) -> Output
fn tool_display_name(name: &str) -> String- 测试工具用
touch_exec/create_executable自动加.exe - 断言用
scan_name/tool_display_name适配平台名 - platform 测试按
#[cfg(windows)]/ Unix 分支编译
parse_args() → ParsedArgs:
| 字段 | 含义 |
|---|---|
list_mode |
-l / --list(必须在 args[1]) |
json_mode |
--json |
meta_mode |
--meta(显式才做版本探测) |
project_mode |
--project |
exists_mode |
--exists / --check(廉价存在性检查,exit 0/1) |
tag_filter |
--tag <name> |
count_mode |
--count(只输出数量) |
limit |
--limit N 或 --top N |
select_mode |
Interactive / PickFirst / Exact / Index(n) |
sort_mode |
Alpha / Freq(--top 强制 Freq) |
filter |
非标志 token 拼接 |
forwarded |
-- 之后透传参数 |
规则要点:
- 标志位(
--json/--meta/--project/--count/--pick-first/--exact)全局扫描,不限于-l后 - 值消费型:
--tag/--index/--sort/--limit/--top;缺值时eprintln!警告 --top N≡ 截断 N 条 +--sort freq- 例:
loci -l --json git→ list + json + filter=git
name filter → meta_cache(可选) → tag filter → sort → limit → count short-circuit → text/JSON
explicit_meta = parsed.meta_mode;meta_mode = explicit_meta || tag_filter.is_some()- 仅
explicit_meta时做版本探测;仅--tag只做类别/标签,不 spawn--version meta_cache在 name filter 后算一次,供 tag 过滤与 JSON 共用
| 模式 | 行为 | 失败 |
|---|---|---|
| Interactive | skim TUI | 用户取消 → exit 0 |
--pick-first |
过滤后取第一个 | exit 1 + no_matching_tool |
--exact |
全等匹配(区分大小写) | exit 1 + exact_not_found |
--index N |
0-based | exit 1 + index_out_of_range |
launch:Unix Command::exec 替换进程;Windows status() 等待子进程。启动前 usage::record_usage。
report_error(json_mode, code, msg):
- 始终:
eprintln!("loci: {}", msg) json_mode时额外:{"loci_error":{"code":"...","message":"..."}}到 stderr(Agent 可解析)
- 路径:
~/.cache/loci/cache.json - 指纹:PATH 目录路径 + mtime 的 SHA-256
- 失效:PATH 或目录 mtime 变化;用户黑名单变化不触发指纹变化(进程重启会重建)
- 写入:
cache.json.tmp→rename(原子) --project不走磁盘缓存
- 内置
DEFAULT_BLACKLIST:shell builtins(cd/echo/export/kill/test/true/false等) - 用户:
~/.config/loci/blacklist(每行一名,#注释) - 顺序:内置 → 用户
- Unix:
mode & 0o111 != 0 - Windows:
PATHEXT(默认.EXE;.BAT;.CMD;.COM;.PS1) - 均先
is_file()
- 列表/程序化选择的
fuzzy_match:大小写不敏感子串(非真正模糊) - 真正模糊匹配仅在 skim TUI(
ui.rs)
追加扫描目录(Unix : / Windows ;),不修改原始 PATH。
loci -l --json --meta 每工具 meta:
| 字段 | 来源 | 示例 |
|---|---|---|
version |
tool --version(3s 超时) |
"git version 2.52.0" |
category |
infer_category() |
"scm" / "python" |
tags |
内置 category + ~/.config/loci/tags.json |
["scm","devops"] |
path |
PATH 解析 | "/usr/bin/git" |
版本探测:先 --version 再 -V;首条非空行 <120 字符;50ms 轮询;超时 kill+wait。
VERSION_PROBE_BLACKLIST:gitk / git-gui / gvim(GUI 勿探测)。
Windows:CREATE_NO_WINDOW + stdin(null)。
内置 10 类:scm / container / python / node / compress / network / editor / rust / go / database。
用户:~/.config/loci/tags.json → {"tool": ["tag1"]}。
--tag 自动 meta 模式,不探测版本,除非同时 --meta。
| 类型 | 标志 | 目录 |
|---|---|---|
| Node | package.json |
node_modules/.bin/ |
| Python venv | pyvenv.cfg |
.venv/venv 的 bin 或 Scripts |
| Rust | Cargo.toml |
target/debug + target/release |
| Conda | $CONDA_PREFIX |
$CONDA_PREFIX/bin |
| 参数 | 行为 |
|---|---|
--limit N |
输出最多 N 条 |
--top N |
最多 N 条 + 强制按频率排序 |
--count |
只输出数量;JSON 为 {"skill_version","total"} |
| 值 | 行为 |
|---|---|
alpha |
字母序(默认) |
freq |
频率降序 → 最近使用 → 字母序 |
数据:~/.local/share/loci/usage.json(tmp+rename)。UTC 自实现,无 chrono。
{
"skill_version": "v0.2.1",
"total": 3,
"executables": ["cargo", "git", "python"],
"filter": "git",
"project": true,
"tag_filter": "scm",
"meta": {
"git": {
"version": "git version 2.52.0",
"category": "scm",
"tags": ["scm"],
"path": "/usr/bin/git"
}
}
}skill_version始终有(env!("CARGO_PKG_VERSION"))meta仅在--meta或--tag时出现;version字段仅显式--meta- 序列化失败时降级紧凑 JSON
cache.json / usage.json:写 .tmp 再 rename。
- 版本探测 3s 超时 + 50ms 轮询;超时 kill+wait
- GUI 探测黑名单;Windows 静默窗
try_wait已收割后用stdout.take(),勿再wait_with_output- Windows
status.code() == None时打印诊断而非静默 exit 1
- 不可读目录
continue - 非 UTF-8 文件名(含
U+FFFD)跳过并警告 - 不存在的 PATH 项静默丢弃
- 无效
LOCI_PATH_EXTRA路径eprintln!警告
有 tag_filter 时 meta_cache 必为 Some(debug debug_assert!;release 子串降级)。
| Crate | 用途 |
|---|---|
skim (frizbee) |
模糊 TUI |
dirs |
配置/缓存/数据目录 |
serde / serde_json |
缓存 + JSON |
sha2 |
PATH 指纹 |
其余用标准库。
推送 v* tag → .github/workflows/release.yml:
- test — ubuntu / macos / windows
cargo test --release - build — 5 目标(linux-x64/arm64, macos-x64/arm64, windows-x64)
- release — artifact + checksums + GitHub Release
npm:@yaemikoreal/loci,install.js 拉二进制,bin/loci.js spawnSync 透传。
| 文件 | 用途 |
|---|---|
docs/usage.md |
用户操作手册 |
SKILL.md |
Agent Skill 协议 |
AGENTS.md |
Agent 工作流 |
README.md |
项目首页 |
cargo build --release
cargo test -- --test-threads=1
cargo test args::tests
cargo test --test cli
cargo test parse_args_default
cargo clippy
cargo install --path .
cargo run -- -l --jsonloci # 交互 TUI
loci git # 预过滤后 TUI
loci --exists git # 存在性检查(Agent 廉价 API)
loci --exists --json git # 存在性 + JSON
loci -l # 文本列表
loci -l --json # JSON(Agent 首选)
loci -l --json git # JSON + 关键词
loci -l --json --meta # JSON + 版本/类别/路径
loci -l --json --tag scm # 标签过滤(无版本探测)
loci -l --json --tag scm --meta # 标签 + 版本
loci -l --project --json # 项目本地工具
loci -l --sort freq # 按频率
loci -l --top 10 # Top10 常用
loci -l --count # 仅数量
loci -l --limit 20 git # 截断
loci --exact python.exe # 精确启动
loci --pick-first git # 首个匹配启动
loci --index 0 python -- --version
loci git -- log --oneline # 预过滤 + 透传