docs(v2): C12 文件、代码与 LSP 协作族 (YAO-113)#36
Open
luyao618 wants to merge 3 commits into
Open
Conversation
新写 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>
Co-authored-by: multica-agent <github@multica.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 反馈)
覆盖目录(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)
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 树之外。一次工具调用的结果需要同时:
query.ts对话循环读取如果用 Redux/Zustand 这类库?太重了。React 内置的
useState/useReducer?无法从 React 树外部访问。模块级全局变量?无法触发 React 重渲染。Claude Code 的答案是:三层状态架构 + 一个 35 行的自研 Store。
【摘抄 2,来自 docs/20-API调用与错误恢复.md】
当你在本地调用一个 REST API 时,最简单的做法是失败就报错。但 Claude Code 面对的是一个远比这复杂的现实:
如果每种错误都让用户手动重试,用户体验将是灾难性的 —— 想象你在一个需要 10 分钟的 agentic 编程任务中途遇到一次 529,不得不从头开始。
本章新写正文摘抄(≥ 200 字 × 2 段,覆盖典型叙事段)
【新写 1,来自 docs/27-文件-代码-与-LSP-协作族.md §一】
真正有意思的是它跟写工具之间的契约 ——
readFileState。每次成功读完一个文件,FileReadTool 都会在FileReadTool.ts:830-846把这条记录写进ToolUseContext共享的readFileStateMap:{ 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"。