泄露代码里看到的 Claude Code:harness工程长什么样

"

Claude Code意外泄漏51.2万行TS核心代码

来源:github.com/instructkr/...

备份:github.com/GuiminChen/...

Harness 工程:设计、实现与可借鉴点

本文描述仓库中 rust/ 兼容 harness 的目标、结构与实现方式,并归纳对 大型代码库迁移、双语言共存、渐进替换 类项目的借鉴意义。主程序真源仍在 ../src/(TypeScript) ;Rust 侧当前里程碑是 「可证明的抽取 + 与上游接缝对齐的骨架」,而非完整 CLI 运行时。


1. Harness-first 在讲什么?

rust/README.md 引用的 PRD 思路可概括为四步:

  1. 先抽「可观测事实」 :从现有上游源码中稳定读出 命令表、工具表、启动阶段 等,而不是先写一大套自以为对齐的运行时。
  2. 边界与上游同名同构 :crate 划分贴在 commands / tools / runtime(bootstrap)主仓库已有的接缝 上,方便两边对照与后续填充。
  3. 证明先于扩张 :用 测试 + 小 CLI 子命令 把抽取结果 钉在 CI 里 ;新功能先在 harness 层 reak proof,再谈行为兼容。
  4. 公开承认缺口 :里程碑描述明确 不做 drop-in 全量 parity,避免对外过度承诺。

这是一种 「兼容性优先的脚手架」 策略:价值在于 降低迁移不确定性与回归成本,而不是第一天换掉主程序。


2. 工作空间与依赖图

bash 复制代码
rust/
├── Cargo.toml          # workspace,members = crates/*,unsafe forbid 等统一 lint
├── README.md
└── crates/
    ├── rusty-claude-cli/   # 二进制入口(薄)
    ├── compat-harness/     # 读 TS 源、做抽取的唯一实现 crate
    ├── runtime/            # BootstrapPhase / BootstrapPlan(无 I/O)
    ├── commands/           # CommandRegistry 等纯数据类型
    └── tools/              # ToolRegistry 等纯数据类型

依赖关系(有向无环):

  • commandstools 互不依赖 :清单 形态 独立,避免类型互相拖拽。
  • compat-harness 聚合 解析逻辑 + IO(读文件) ;其它 crate 保持可单测、可复用的小库

3. 上游路径契约:UpstreamPaths

compat-harness 假定仓库布局固定(与当前 monorepo 一致):

方法 指向
commands_path() repo_root/src/commands.ts
tools_path() repo_root/src/tools.ts
cli_path() repo_root/src/entrypoints/cli.tsx

from_workspace_dir 通过 canonicalize + parent()rust/crates/compat-harness/../../ 推出 repo_root
借鉴 :把 「真源文件位置」 收束成一个类型,后续改路径只改一处;测试用 CARGO_MANIFEST_DIR 定位 fixture。


4. 抽取如何实现?(启发式逐行,非 TypeScript AST)

4.1 设计取舍

未引入 swc/typescript parser :对 registry 型文件 (大量 importexport const ... = [feature() ? require)采用 逐行扫描 + 简单字符串规则

优点 缺点
零第三方解析依赖、实现短、编译快 上游 大改格式 时可能误报/漏报
与「manifest 级」目标匹配,不做语义分析 不能替代类型检查或真实 import

适合 harness 的第一阶段 ;若后期需要精确到 导出图 / 循环依赖 ,可再 增量 接 AST 或 ts-morph,而不必推翻 crate 划分。

4.2 命令清单(extract_commands

  • 内置import ... from './commands/...' → 符号记入 CommandSource::Builtin
  • 内部列表 :在 INTERNAL_ONLY_COMMANDS = [ 与 closing ] 之间,按行提取标识符 → InternalOnly
  • 特性门控 :行内同时含 feature('./commands/ ,取赋值左侧名 → FeatureGated
  • 去重(name, source) 二元组去重 → CommandRegistry

4.3 工具清单(extract_tools

  • ./tools/ 的 import 且符号以 Tool / Tools 结尾ToolSource::Base
  • feature('...') 且与 Tool 相关的赋值 → Conditional

4.4 启动阶段(extract_bootstrap_plan

cli.tsx 全文做子串探测 (如 --versionstartupProfiler--daemon-worker),按固定顺序 追加 BootstrapPhase 枚举项,最后 MainRuntime

这与真实运行时 「有则启用某快路径」 的语义大致同构,但是 粗粒度 的静态近似。


5. 二进制入口:rusty-claude-cli

当前只做三件事(见 main.rs):

子命令 行为
(无参数) 提示此为 foundation,引导 --help
dump-manifests 当前工作区 调用 extract_manifest,打印 命令/工具/phases 数量
bootstrap-plan 打印 BootstrapPlan::claude_code_default()runtime完整阶段骨架
--help 使用说明

注意bootstrap-plan 当前打印的是 runtime 中写死的「全阶段列表」 ,而 dump-manifests 里报告 bootstrap phases 数量 时用的是 extract_bootstrap_plan(cli.tsx)启发式子集 。二者 源码未完全统一 ,符合「脚手架阶段」常见情况:一个命令展示「目标模型」,另一个展示「从上游扫出来的近似」 。后续可改为 bootstrap-plan 也走 extract_manifest 或并列输出,便于对齐。


6. 测试作为「活文档」与回归护栏

compat-harness 内集成测试(见 lib.rs``#[cfg(test)]):

  • 本仓库 fixture_paths() 读真实 commands.ts / tools.ts
  • 断言 非空 manifest。
  • 断言 已知符号 (如 addDirreviewAgentToolBashTool)存在,且 不会像字面量那样误提 INTERNAL_ONLY_COMMANDS

借鉴不 snapshot 整个列表 (避免上游小改导致海量 diff),而用 最小护栏 (非空 + 锚点符号)平衡 稳定性与维护成本


7. 工作空间工程质量

  • resolver = "2" 、统一 edition / license / publish
  • workspace lint:unsafe_code = forbidrust/Cargo.toml):与安全文化一致,harness 也不偷偷 unsafe

8. 可借鉴点(针对类似「从 TS/JS 大单体迁 Rust/Go」的项目)

  1. 接缝优先的 crate 切分
    先对齐 产品已存在的模块名 (commands / tools / bootstrap),而不是按 Rust 书上的分层 重命名,减少团队沟通成本。
  2. 「抽取器」与「领域类型」分离
    commandstools 只放 registry 数据结构文件 IO + 启发式解析 放在 compat-harness 。将来换解析实现, 下游类型稳定
  3. 证明工件跑在 CI
    小测试 + 一个 dump-manifests 式命令,让 「还能读懂上游 registry」 成为 合并门禁,早于重写运行时。
  4. 显式来源标签
    Builtin / InternalOnly / FeatureGatedBase / Conditional同一符号在不同构建下的可见性 有地方表达,便于以后生成文档或与新运行时对齐。
  5. 接受「廉价启发式」的第一版
    AST 投入 之前,用行级规则快速 覆盖 80% manifest ;文档里写清 脆弱点 (格式重写、feature() 行文变化)。
  6. DAG 依赖、零环
    commandstools 避免 类型泥球 ;大项目上这种依赖纪律 后期收益大
  7. 里程碑话术
    README 明确 harness-first ≠ feature parity ,管理 干系人预期,避免 harness 被误当成「已可替换」。

9. 局限与后续方向(客观描述)

  • Anthropic API、无 QueryEngine 、无 Ink/UI:Rust 层 不参与 主产品运行路径。
  • 抽取 不验证 :TS 能否编译、import 是否解析成功、feature() 是否 DCE。
  • bootstrap-planextract_bootstrap_plan 输出 未统一(见 §5),属于可改进的工程细节。
  • 上游若 重命名 registry 文件改成动态注册表 ,需同步更新 UpstreamPaths 与解析规则。

10. 与仓库内其它文档的关系

  • rust/README.md:里程碑与命令行用法(权威简短版)。
  • ARCHITECTURE.md:全仓库 TS + Rust 关系总览。
  • 若扩展 harness,宜在 rust/README.md 更新里程碑,而非仅改本文。

基于 rust/README.mdrust/crates/*/src/lib.rsrusty-claude-cli/src/main.rsrust/Cargo.toml 整理。

相关推荐
医学AI望远镜19 小时前
公开数据集整理:心脏CMR分割、心肌瘢痕、肋骨骨折、骨关节炎等
人工智能·数据集·医学图像分割
懂AI的老郑19 小时前
智能体演变路径预测:AI未来行为的核心解码
人工智能
wayz1119 小时前
Day 7:第一周复习与模型综合比较
人工智能·算法·机器学习·量化交易
小超同学你好19 小时前
Transformer 27. Vision Transformer(ViT):把图像当作「词序列」的编码器
人工智能·深度学习·transformer
登山人在路上19 小时前
RAGAS 中的已知偏差详解
人工智能·全文检索·ai编程
空白诗19 小时前
ModelEngine Nexent:一句话创建智能体的全新范式
人工智能·nexent
元直数字电路验证19 小时前
AI入门体系化知识框架
人工智能
zhangshuang-peta19 小时前
MCP 与治理:当 Agent 成为组织决策的一部分
大数据·人工智能·ai agent·mcp·peta
SCBAiotAigc19 小时前
2026.4.21:在做yolo26分类任务时出现save_dir一直是个固定的一个值的避坑技巧
人工智能·具身智能·yolo26
原我归来是少年19 小时前
一 InsightMemory - 从 RAG 到 Memory:AI 应用缺的不是搜索,而是持续认知
人工智能