Skip to content

docs(v2): C12 文件、代码与 LSP 协作族 (YAO-113)#36

Open
luyao618 wants to merge 3 commits into
mainfrom
yao-113-c12-file-code-lsp
Open

docs(v2): C12 文件、代码与 LSP 协作族 (YAO-113)#36
luyao618 wants to merge 3 commits into
mainfrom
yao-113-c12-file-code-lsp

Conversation

@luyao618
Copy link
Copy Markdown
Owner

@luyao618 luyao618 commented May 24, 2026

C12 文件、代码与 LSP 协作族(YAO-113)

新增 docs/27-文件-代码-与-LSP-协作族.md,覆盖 FileRead / FileWrite / FileEdit / NotebookEdit / Glob / Grep / LSPTool / REPLTool + services/lsp/

source_commit: 290fdc9481a70612bc5823aa4ed225c52c52aad3

判定档:拆分合并(新增章节)。新增段落 K 段为主;不涉及 v1 段落保留 / 改写统计(无 v1 直接前身章节)。

本轮修订(针对 OC-R review 反馈)

  • 修正 errorCode 描述:FileWrite=2/3、FileEdit=6/7、NotebookEdit=9/10,不再笼统说成「9/10 重复实现」。
  • 修正 UNC 路径短路动机:validate 阶段不做 filesystem I/O 以避免 NTLM credential leak,I/O 延后到权限通过后的 call 阶段;不再说「留给下游 OS 自己去拒」。

覆盖目录(spec §6.2 反向矩阵)

  • tools/FileReadTool/tools/FileWriteTool/tools/FileEditTool/tools/NotebookEditTool/
  • tools/GlobTool/tools/GrepTool/
  • tools/LSPTool/services/lsp/(manager / LSPServerInstance / LSPClient / LSPDiagnosticRegistry / passiveFeedback / config)
  • tools/REPLTool/(constants.ts + primitiveTools.ts)

验收事实点(已在正文出现的关键 file:line)

  • FileReadTool.ts:342(maxResultSizeChars: Infinity)、:458-465(UNC 短路)、:830-846(readFileState set)
  • FileWriteTool.ts:198-218(errorCode 2/3);FileEditTool.ts:275-307(errorCode 6/7);NotebookEditTool.ts:218-237(errorCode 9/10)、:326-333(非 memoized jsonParse)、:433-442(offset:undefined)
  • GlobTool.ts:57-80;GrepTool.ts:108-119 / 160-170 / 328-340
  • LSPTool.ts:53 / 131-138 / 263-267 / 432 / 577-588;prompt.ts:1-21
  • services/lsp/manager.ts:1-289;LSPServerInstance.ts:17 / 193-234 / 378-390;LSPClient.ts:1-447;LSPDiagnosticRegistry.ts:42-46;passiveFeedback.ts:1-328;config.ts:1-79
  • REPLTool/constants.ts:13-30 / 37-46;primitiveTools.ts:11-39

CI

bun run check:docs 通过;lint-no-fuzzy-quantifiers 仅 warning(5 处「契约」等正常用法,由 reviewer 复核)。


风格双亲实证

风格双亲:v1-03 状态管理 + v1-20 API调用与错误恢复

v1 原文摘抄(≥ 200 字 × 2 段)

【摘抄 1,来自 docs/03-状态管理.md】

Claude Code 面临一个独特的状态管理难题:它既是一个 React 应用,又不完全是

终端 UI 用 Ink(React for CLI)渲染,组件需要响应式的状态更新。但核心业务逻辑 —— API 调用、工具执行、Agent 编排 —— 运行在 React 树之外。一次工具调用的结果需要同时:

  1. 更新 React 组件(显示在终端 UI 上)
  2. 被非 React 的 query.ts 对话循环读取
  3. 被 Agent 子系统使用(可能运行在隔离的上下文中)

如果用 Redux/Zustand 这类库?太重了。React 内置的 useState/useReducer?无法从 React 树外部访问。模块级全局变量?无法触发 React 重渲染。

Claude Code 的答案是:三层状态架构 + 一个 35 行的自研 Store

【摘抄 2,来自 docs/20-API调用与错误恢复.md】

当你在本地调用一个 REST API 时,最简单的做法是失败就报错。但 Claude Code 面对的是一个远比这复杂的现实:

  1. 网络不可靠 — 用户可能在咖啡馆 WiFi、企业代理、VPN 隧道后面使用
  2. API 容量波动 — 529 过载和 429 限流是 LLM API 的常态,不是异常
  3. 认证令牌过期 — OAuth token、AWS credential、GCP credential 都有 TTL
  4. 流式连接脆弱 — SSE 流可能在中途断开、超时、或被代理截断
  5. 多 Provider 差异 — 同一份代码要兼容 Anthropic 直连、AWS Bedrock、GCP Vertex、Azure Foundry 四种后端

如果每种错误都让用户手动重试,用户体验将是灾难性的 —— 想象你在一个需要 10 分钟的 agentic 编程任务中途遇到一次 529,不得不从头开始。

本章新写正文摘抄(≥ 200 字 × 2 段,覆盖典型叙事段)

【新写 1,来自 docs/27-文件-代码-与-LSP-协作族.md §一】

真正有意思的是它跟写工具之间的契约 —— readFileState。每次成功读完一个文件,FileReadTool 都会在 FileReadTool.ts:830-846 把这条记录写进 ToolUseContext 共享的 readFileState Map:{ content, timestamp: getFileModificationTime(...), offset, limit }。这一手是为后面写工具留的伏笔。如果你跳过 FileRead 直接 FileWrite,validateInput 阶段会拒;如果你读完之后,文件被 linter / 用户在外部改了一次,再写也会拒。这条规矩没写在某一份单独的文档里,它在每一个写工具的 validateInput 里都重复实现了一遍 —— 错误码也各自一套:FileWrite 用 errorCode: 2 / 3,FileEdit 用 errorCode: 6 / 7,NotebookEdit 用 errorCode: 9 / 10,前者表示"还没读过",后者表示"读完之后又被外部改了"。

【新写 2,来自 docs/27-文件-代码-与-LSP-协作族.md §五】

REPL 模式打开后会发生什么?八个名字(FileRead/FileWrite/FileEdit/Glob/Grep/Bash/NotebookEdit/Agent)在工具列表里被抽掉了。模型直接调用 Read 会拿不到这个工具 —— 取而代之,它要通过 REPL 工具发一段 JS/TS 代码,在 REPL 的 VM 上下文里调 Read(...)Bash(...),由 REPL 一次性返回所有结果。为什么要这么绕?因为模型在交互式 CLI 里经常一回合连发七八个 Read/Grep —— 把它们改成一段 JS 让 REPL 一次执行,节省的是 round trip 数和 tool_use 块的 token 开销。但这个收口不能损失工具的实际可用性,所以同样八个工具又通过另一个入口在 REPL VM 里照样存在 —— 注释里那段对 TDZ 的解释值得抄一遍:import 链最终会绕回工具注册表,所以不能在模块顶层 const 求值,必须用 lazy getter 把求值推到第一次调用,否则会触发 "Cannot access before initialization"。

Yao Lu and others added 3 commits May 24, 2026 20:07
新写 docs/27-文件-代码-与-LSP-协作族.md:覆盖 FileRead/FileWrite/FileEdit/
NotebookEdit/Glob/Grep/LSPTool/REPLTool 八工具 + services/lsp/(7 文件)。

- 风格双亲:docs/03-状态管理.md + docs/20-API调用与错误恢复.md
- 源码版本:290fdc9481a70612bc5823aa4ed225c52c52aad3
- 代码块占比 23.6% (≤ 25%),单块均控制在 3–15 行 + 前后散文解释
- 全套 CI 闸(C-1/C-2/C-3/C-4 + check-source-commits +
  lint-no-fuzzy-quantifiers + check-headings + check-orphans)全绿

Co-authored-by: multica-agent <github@multica.ai>
OC-R review (PR #36) 指出两个 blocking 事实错误:

1. errorCode 映射写错了:原文把所有写工具都说成 errorCode 9/10
   实际上每个写工具自己一套:
   - FileWriteTool.ts:198-218 用 errorCode: 2 / 3
   - FileEditTool.ts:275-307 用 errorCode: 6 / 7
   - NotebookEditTool.ts:218-237 才是 9 / 10

2. UNC 路径短路的动机表述反了:原文写成「把 UNC 留给下游 OS 自己去拒」
   实际源码注释(FileReadTool.ts:461-466 / FileWriteTool.ts:179-183)的意图是
   permission 通过前不做任何 filesystem I/O,避免 NTLM credential leak。
   改为「validate 阶段一律放行、延后到权限通过后的 call 阶段做 I/O」。

Co-authored-by: multica-agent <github@multica.ai>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant