展示 HN: Rust 中的 ContextCodeCache
工具可以扫描一个项目并生成一个 ContextCodeCache —— 一个 .ccc 目录,里面包含每个源文件的紧凑且机器可读的映射:它的常量、函数(带有返回类型和文档摘要)、文件内调用图以及标记备注(TODO/FIXME/...)。它的设计目的是为代理提供一个便宜的、始终更新的项目索引。请 ⭐ 如果您发现这个有用 💚 安装 / 构建 需要 Rust ≥ 1.77(tree-sitter 0.25 堆栈;一些传递依赖项使用 2024 版本)还需要一个较新的 cargo。 cargo build --release # 二进制文件 @ target/release/ccc ./target/release/ccc install # 将其复制到您的 PATH(Linux) ccc install 将正在运行的二进制文件复制到 ~/.local/bin(Linux 上的用户本地 bin 目录——不需要 sudo)并将其标记为可执行。传递 --dir <DIR> 以选择不同的目录,或者 --force 以覆盖现有的 ccc。如果目标目录不在您的 $PATH 中,它会打印出添加到您的 shell 配置文件的行。用法 ccc scan [PATH] # 重新生成 PATH/.ccc(PATH 默认为“.”) ccc scan [PATH] --tokens # 也将缓存预编码为令牌流 ccc check [PATH] # 如果 .ccc 过时则退出非零 - 用于 CI ccc check [PATH] --format json # 同样,但将更改的缓存文件以 JSON 格式打印出来 ccc tokenize [PATH] # 将现有的 .ccc 预编码为 tokens.bin + tokens.json ccc install [--dir DIR] # 将 ccc 二进制文件安装到您的 PATH(Linux) ccc check --format json 打印一行——{ root, up_to_date, files[], changes[] }——其中 files 是过时的缓存条目的相对路径。它是为其他工具使用而设计;捆绑的 GitHub Action 通过 fromJSON(...)将该数组馈送到下游作业:scan 将每个文件条目以及 CCC.md 索引重写,因此提交的差异总是来源于重新运行生成器。check 在内存中重新生成并与提交的 .ccc 进行比较,忽略生成时间戳,因此新鲜度门永远不会仅仅因为时间过去而失败。规范 .ccc/ ├── CCC.md # 索引:总计 + 每个文件一行 ├── src-main.rs.md # <module>-<file>.<ext>.md,每个源文件一个 └── src-math.rs.md 每个文件条目遵循以下格式: # math.rs.md (yyyymmdd-hh-mm-ss) UTC # 来源:src/math.rs [ rust ] # 常量 - L4@PI:f64 # 函数 - L7:8@square:f64 // 平方一个数字。 - L12:8@circle_area:f64 // 给定半径的圆的面积。 # 引用 - circle_area@L14 调用 L7:8@square:f64 # 注释 - @L13 注意:使用上面的截断 PI,因此结果是近似的。 常量 - 文件级常量/静态:L<line>@<name>:<type>。由于并不是每种语言都标记常量,因此使用每种语言的约定:Rust const / static 和 Go const / var 规格;Python 仅限 SHOUTING_SNEK_CASE 模块绑定;JS/TS 仅限 const 声明(不包括 let / var)。Python 和 JS/TS 中的类/impl 属性被视为成员,而不是文件常量。函数 - 定义:L<line>:<col>@<name>:<return_type> // 文档摘要 引用 - 文件内调用图,由作用域解析(不仅仅是通过名称):<caller>@L<line> 调用 L<line>:<col>@<func>:<return_type>。一个裸露的 foo() 绑定到同一个文件中的自由函数 foo;接收器调用(self.foo()、this.foo(),或 Go recv.Foo())绑定到封闭类型上的方法 foo。对任何其他接收器的调用(other.foo())需要类型信息来解析,因此不发出边缘,而不是根据名称进行猜测。注释 - 标记注释(TODO、FIXME、XXX、HACK、BUG、NOTE、SAFETY) 一个工作示例位于 example/ 及其生成的 example/.ccc/。令牌流(预编码缓存) 令牌流不兼容于 Anthropic 模型。这些是近似的 tiktoken ID(一个 OpenAI 词汇表)。可以与 DeepSeek V4-Pro 等一起使用。将其用于共享 OpenAI 词汇的下游模型,或用于粗略的大小估计。如果使用 Claude,请使用 .ccc markdown 作为上下文。要获取准确的 Claude 令牌计数,请使用 Anthropic 的 count_tokens 端点。 tokens.json 在行内携带此警告(approximate: true + 注释)。 ccc tokenize(或 ccc scan --tokens)使用预训练的 tiktoken 词汇编码整个 .ccc 语料库(默认使用 o200k_base,--encoding cl100k_base 也支持)并写入: .ccc/ ├── tokens.bin # 所有缓存文件的低字节序 u32 令牌 ID,连接在一起 └── tokens.json # 索引:编码、布局,以及 per-file {offset, len} 在 tokens 中 消费者以无重令牌化的方式加载原始令牌 - 将 tokens.bin 作为 u32 切片读取,并通过 tokens.json 索引。 TokenCache 加载器正是这样做的,每次令牌化运行都验证持久化流可以解码为字节上相同的语料库:let cache = codecache::TokenCache::load(project_root)?; let ids: &[u32] = cache.file("src-main.rs.md").unwrap(); // 原始令牌,准备使用 let text = cache.decode(ids)?; // 可选:回到 markdown 令牌工件是派生的,因此简单的 ccc scan 会清除它们;再次运行 --tokens(或 ccc tokenize)以刷新。支持的语言 Rust、Python、JavaScript、TypeScript(+ TSX)和 Go,通过 tree-sitter。跳过不受支持的文件;隐藏
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡