25 KiB
与其他工具集成
同一个"接入外部工具"的动作,在使用者眼里是"我能在 VS Code / Zed / Cursor / GitHub Actions / Codex CLI 里用 Claude 吗、要装什么、凭证怎么走",在开发者眼里是"为什么 IDE 走 MCP 的
sse-ide/ws-ide子类型、为什么 ACP agent 用 stdio NDJSON、为什么 ChatGPT 订阅凭证要 fallback 读~/.codex/auth.json、为什么install-github-app是 React 多步表单而不是一行 shell"。集成天然是双视角主题——用户想知道"能不能接、怎么接",开发者想知道"边界在哪、契约长什么样、为什么这样切"。
产品视角(写给使用者)
这一节回答一个最高频的问题:我能在 X 里用 Claude 吗? 答案按"接入形态"分成五类,每类给一个清单式的"做什么 → 怎么做"。
第一类:把 Claude 接进 IDE(VS Code / Cursor / Windsurf / JetBrains / Zed)
你能在主流 IDE 里得到一个能看见当前工作区、能开 diff、能跑工具的 Claude。两条路径,按 IDE 选:
- VS Code 家族(VS Code / Cursor / Windsurf)+ JetBrains 家族:装官方扩展或插件,然后在
claudeREPL 里跑/ide(命令在src/commands/ide/index.ts注册,实现在src/commands/ide/ide.tsx)。它会扫描当前在跑的 IDE、列出带扩展的实例、让你选一个连过去。/ide open(ide.tsx:277-329)还会把当前 worktree 或 cwd 在选中的 IDE 里打开。注意 VS Code 系列有一条限制:同一时刻只能有一个 Claude 实例连过去(ide.tsx:127-131的告警)。 - Zed / Cursor 等 ACP 客户端:ACP(Agent Client Protocol)是 stdio NDJSON 协议。Claude 自身就是一个 ACP agent,跑
claude --acp(src/entrypoints/cli.tsx:123-124的 fast-path,受feature('ACP')门控)就会进入 stdio 模式,由 IDE 直接 spawn。Zed 侧的配置方式见docs/features/agents/acp.md:在 Zed 的settings.json里加agent_servers,command指向claude,args写["--acp"]。
这两条路径的区别:/ide 是 Claude 主动连过去(Claude 作为 MCP client 反向连 IDE 的 MCP server),适合在终端 REPL 里把 IDE 当作"上下文源";--acp 是 IDE 把 Claude 当 agent 调起来(Claude 作为 ACP server),适合 IDE 内置的 Agent Panel。两种方向都支持,挑你顺手的。
自动连接:/ide 第一次手动选完之后,会在 IdeAutoConnectDialog(src/components/IdeAutoConnectDialog.js)里问你要不要"以后自动连"。开了之后下次启动 REPL 会自动连上同一台 IDE,不用每次 /ide。要关掉就再跑 /ide 选 None,会弹 IdeDisableAutoConnectDialog。
第二类:把 Claude 暴露成可以被远程调用的服务(ACP / Bridge / RCS)
"我有一台跑 Claude 的机器、想让另一台机器(或浏览器、或团队同事)调用它"——三类方案:
- ACP agent 远程化:
claude --acp默认是本地 stdio。要让 WebSocket 客户端也能调,跑acp-link(packages/acp-link/,README 在packages/acp-link/README.md)。它把 WebSocket 连接桥接到 ACP agent 的 stdin/stdout。默认端口 9315,默认会自动生成一个 token;要固定 token 用ACP_AUTH_TOKEN环境变量,要禁用认证(不推荐)用--no-auth。详细 CLI 选项见 README。 - Bridge / Remote Control 快速路径:
claude remote-control/claude rc/claude remote/claude sync/claude bridge(cli.tsx:178-188,五个别名都进同一条 fast-path,受feature('BRIDGE_MODE')门控)。这条路径把当前进程接到一个 Remote Control 后端,让你的 REPL 能被远端控制。 - 自托管 RCS(Remote Control Server):如果你要给一个团队或长期跑的后端,用
packages/remote-control-server/(Docker 部署 + Web UI 控制面板,启动用bun run rcs)。它的 README(packages/remote-control-server/README.md)列了五项能力:会话管理、实时消息流(WebSocket / SSE 双向)、权限审批(在 Web UI 里点同意/拒绝)、多环境管理(注册多台运行环境、心跳和断线重连)、API Key + JWT 双层认证。acp-link 也能注册到 RCS:设ACP_RCS_URL/ACP_RCS_TOKEN/ACP_RCS_GROUP(或--group <id>flag),就能在 RCS Web UI 里看到这个 ACP agent。
这三类的取舍:acp-link 适合"我有一台机器、想让外部 WebSocket 调一下";claude remote-control 适合"我正在 REPL 里干活、临时让远端接入";自托管 RCS 适合"团队级长期跑"。同一个底(query loop + 工具系统)三种接入形态,见设计视角的"集成边界"一节。
第三类:把 Claude 嵌进 GitHub 工作流(issue / PR review / 自动修复)
两条入口:
- 手动一键装:
claude install-github-app(实现在src/commands/install-github-app/install-github-app.tsx,命令注册在src/commands/install-github-app/index.ts)。它是一个多步 React 表单(不是 shell 命令),会带你走完:检测gh是否装了、选 repo、检测现有 workflow、装 GitHub App、写 API key 到 GitHub Secret、装 workflow 文件。装完之后,在你的 GitHub repo 里@claude提一句,就会触发claude-code-action跑一轮。具体能触发什么事件、workflow 模板长什么样,看src/constants/github-app.ts——WORKFLOW_CONTENT是写进你 repo 的 workflow 文件内容,GITHUB_ACTION_SETUP_DOCS_URL指向anthropics/claude-code-action仓库的 setup 文档。 - 直接 commit + push + 开 PR:
/commit-push-pr(src/commands/commit-push-pr.ts)。这不是 GitHub App,是你本地claude直接用ghCLI 帮你开 PR。它内部有一个ALLOWED_TOOLS白名单(commit-push-pr.ts:11-23),只允许Bash(git ...)/Bash(gh pr ...)/SearchExtraTools和两个 Slack 工具。如果你的 CLAUDE.md 提到要往 Slack 发 PR 链接,它还会用SearchExtraTools找 Slack 工具问你要不要发(commit-push-pr.ts的slackStep)。 - PR 自动修复:
/autofix-pr(src/commands/autofix-pr/,入口launchAutofixPr.ts)。这是给 CI 上跑的——PR 触发后 Claude 看一遍、发现明显问题就自动提交一个修复 commit。
第四类:和 Codex CLI 共享 ChatGPT 订阅凭证
如果你同时在用 Codex CLI 和 Claude,并且想用 ChatGPT 订阅当后端(OPENAI_AUTH_MODE=chatgpt),你不需要在两边各登录一次。Claude 会先读自己的 ~/.claude/openai-chatgpt-auth.json;如果不存在,会 fallback 读 Codex CLI 的 ~/.codex/auth.json(src/services/api/openai/chatgptAuth.ts:339-344)。所以你在 Codex CLI 里登录过、Claude 这边就能直接复用。
反过来不成立:Codex CLI 不会读 Claude 的凭证文件。如果你只想在 Claude 里用,就只在 Claude 这边 /login 走 ChatGPT 设备码流程;如果你想在两边都用,去 Codex CLI 登录一次更省事。
凭证刷新有 5 分钟的偏差窗口(REFRESH_SKEW_MS = 5 * 60 * 1000,chatgptAuth.ts:7)——令牌过期前 5 分钟内任意一次请求都会触发刷新,避免边界 race。详见 cross/03-security.md 的凭证章节。
第五类:跨工具凭证共享(其他 Provider)
只有 ChatGPT 订阅路径会跨工具读 Codex 的凭证文件。其他 Provider(Anthropic / 普通 OpenAI API key / Gemini / Grok / Bedrock / Vertex / Foundry)的 key 都存在 Claude 自己的 ~/.claude/ 下或 settings.json 里,不与任何外部工具共享。
如果你同时在别的工具(比如 Aider、Continue)里用 Anthropic API,那些工具各自读自己的配置——你需要在每个工具里都配一遍 ANTHROPIC_API_KEY 或对应的环境变量。这不是 bug,是有意的隔离:一个工具的凭证泄露不应该顺带把另一个工具的也带出去。
设计视角(写给开发者)
设计大纲原本完全没有"跨工具集成视角"。这一节补上"集成边界"——每一类集成背后都有一组明确的契约和决策:协议形态、凭证流向、feature 门控、命令路径。读完之后你应该能回答:"如果我要加一个新的 IDE 集成、或一个新的 CI 平台,边界在哪、哪些约束是必须遵守的"。
为什么 IDE 集成走 MCP 的 sse-ide / ws-ide 子类型,而不是普通 MCP
打开 src/commands/ide/ide.tsx:463-472,看连接 IDE 时写入 dynamicMcpConfig 的逻辑:
const url = selectedIDE.url
newConfig.ide = {
type: url.startsWith('ws:') ? 'ws-ide' : 'sse-ide',
url: url,
ideName: selectedIDE.name,
authToken: selectedIDE.authToken,
ideRunningInWindows: selectedIDE.ideRunningInWindows,
scope: 'dynamic' as const,
} as ScopedMcpServerConfig
IDE 在 MCP config 里是一个特殊的 ide key,type 是 sse-ide 或 ws-ide——不是普通的 sse / websocket。这两个子类型在 src/services/mcp/ 里有专门的处理路径。为什么不给 IDE 用普通 MCP? 因为 IDE 提供的不只是工具(mcp__ide__* 工具前缀,见 ide.tsx:455-456 的 filter 清理逻辑),还有 diff 显示、当前选中文件、diagnostics 推送这些"非工具形态"的能力。给 IDE 单独留一个 type,让 MCP client 知道"这个连接除了普通工具调用,还有 IDE 专有的副作用通道"。
另一个有意思的设计:dynamicMcpConfig 的 scope 是 'dynamic'。这意味着 IDE 配置不写进 settings.json,而是活在 React state 里——下次启动 REPL 不会自动恢复。自动恢复靠 IdeAutoConnectDialog 单独存的标志位("以后自动连"),连接动作本身每次都要重新走一遍。这个设计的代价是:用户换一台机器、或者把 settings 同步到另一台,IDE 自动连不会跨机器带过去。收益是:IDE 的端口和 token 是会话期会变的(IDE 重启端口就变),写进持久化 settings 反而会读到过期值。
disconnect 的细节(ide.tsx:446-460):断开连接时除了清 config,还主动 ideClient.client.onclose = () => {} 把 onclose 置空。为什么? MCP client 有自动重连机制,正常关闭会触发重连。置空 onclose 是"我说了要断、别再自己连回来"的信号——这是 RPC 类连接很容易踩的坑,/ide 选 None 的时候必须做这一步,否则用户会看到"我明明断了它又自己连上"。
为什么 ACP agent 是 stdio NDJSON,而 acp-link 要做 WebSocket → stdio 桥接
ACP 的协议形态选择写在 docs/features/agents/acp.md:stdin/stdout 的 NDJSON 流。为什么是 stdio? 因为 stdio 是 IDE 调子进程最简单的形态——IDE spawn claude --acp,往 stdin 写 NDJSON,从 stdout 读 NDJSON。不需要开端口、不需要握手、不需要网络配置。代价是"只能本地调用"——IDE 和 agent 必须在同一台机器上同一个进程树里。
acp-link(packages/acp-link/)就是为突破这个限制存在的。看 README 的 "How It Works":它监听 WebSocket、收到 connect 消息就 spawn 配置好的 ACP agent 子进程、把 WebSocket 帧和 agent 的 stdin/stdout 双向桥接。为什么不直接给 ACP agent 加一个 WebSocket 模式? 因为 stdio 和 WebSocket 是两种完全不同的 I/O 模型——stdio 是阻塞 read、WebSocket 是事件回调。把它们塞进同一个 agent 进程会让 agent 的代码复杂度爆炸。acp-link 作为独立进程承担"协议翻译",agent 自己保持纯 stdio,单一职责。
这个设计的代价:多了一层进程。acp-link 进程崩了,agent 和 WebSocket 客户端都会失联。RCS 的多环境管理(README 提到"心跳和断线重连")部分就是为了缓解这个——acp-link 进程挂了 RCS 能检测到、能重启。packages/acp-link/src/manager/(README 的 "Manager UI" 段)进一步提供了"一台机器跑多个 acp-link 子进程、统一管理"的形态,这是为团队场景设计的。
凭证透传:ACP agent 启动时会读 settings.json 里的环境变量(见 docs/features/agents/acp.md 第 58 行,ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN 等)。Zed 这种 IDE 还能在 agent_servers 配置里显式传 env。为什么不让 ACP 协议自己带凭证? 因为 ACP 是协议、凭证是部署期决策——协议只规定"怎么对话",凭证由调用方(IDE 的 agent_servers.env / RCS 的环境变量 / acp-link 启动时的环境)决定。这种分离让同一个 ACP agent 能在不同 IDE、不同部署形态下复用,不需要改 agent 代码。
为什么 ChatGPT 订阅凭证要 fallback 读 ~/.codex/auth.json
打开 src/services/api/openai/chatgptAuth.ts:42-57:
function authFilePath(): string {
return join(getClaudeConfigHomeDirLocal(), AUTH_FILE)
}
function codexAuthFilePath(): string {
return join(
process.env.CODEX_HOME ?? join(process.env.HOME ?? '', '.codex'),
'auth.json',
)
}
两个路径函数。getValidChatGPTAuth(chatgptAuth.ts:339-344)的读取顺序是:先读 Claude 自己的 ~/.claude/openai-chatgpt-auth.json,读不到再 fallback 读 Codex CLI 的 ~/.codex/auth.json,并打一条 debug 日志 [OpenAI] Using ChatGPT auth from Codex auth.json。
为什么这么设计? ChatGPT 订阅的 OAuth 设备码流程是 OpenAI 自己发的(ISSUER = 'https://auth.openai.com',CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann',chatgptAuth.ts:5-6)。Codex CLI 用的是同一个 issuer 同一个 client_id(验证:verificationUrl 用 ${ISSUER}/codex/device,chatgptAuth.ts:217)。两边走的是同一套令牌体系,令牌可以互换——所以让 Claude 复用 Codex 的凭证是合法的、不是"借用"。
为什么不强制让用户在 Claude 这边也登录一次? 因为 ChatGPT 订阅用户已经为这个 token 付过费、已经走完设备码握手了。让他在每个工具里都重做一次设备码登录(打开浏览器、输 userCode、等待授权)是明显的体验灾难。fallback 读 Codex 凭证把"一次登录、多个工具复用"变成可能。
反向不成立:Codex CLI 不会读 Claude 的凭证文件。这是有意的非对称——Claude 这边承认"我是后来的、我读你的",但 Codex CLI 作为 OpenAI 自家工具不知道 Claude 的存在。这种非对称在跨工具凭证共享里很常见:后入场的一方做兼容,先入场的一方保持简单。
风险:这个 fallback 假设 Codex CLI 的凭证文件格式稳定。如果某天 Codex CLI 改了 auth.json 的 schema(加字段、改字段名、嵌套层级变化),Claude 这边的 readStoredAuth(chatgptAuth.ts:123)就要跟着改。这是跨工具集成的固有脆弱性——两边的格式没有契约约束,只靠"碰巧一致"维持。如果 Codex CLI 那边改了,Claude 这边不会自动收到通知,要靠用户报"我用 ChatGPT 模式登录不了了"才会被发现。
install-github-app 为什么是 React 多步表单,而不是一行 shell
打开 src/commands/install-github-app/install-github-app.tsx,它 import 了 11 个 Step 组件:ApiKeyStep / CheckExistingSecretStep / CheckGitHubStep / ChooseRepoStep / CreatingStep / ErrorStep / ExistingWorkflowStep / InstallAppStep / OAuthFlowStep / SuccessStep / WarningsStep。一个简单的"装 GitHub App"为什么要拆这么多步?
因为"装一个 GitHub App"在生产环境里至少有 11 个分支:
gh装了吗?没装怎么办?(CheckGitHubStep)- 用户想装到当前 repo 还是别的 repo?当前 repo 探测到了吗?(
ChooseRepoStep) - API key 用现有的还是新建?用 OAuth 还是 API key?(
ApiKeyStep,selectedApiKeyOption: 'new' | 'existing' | 'oauth',见install-github-app.tsx:36) - repo 里已经有同名 secret 了吗?要覆盖还是保留?(
CheckExistingSecretStep) - repo 里已经有 workflow 文件了吗?要装哪几个?(
ExistingWorkflowStep,默认['claude', 'claude-review'],见install-github-app.tsx:35) - 创建过程中出错了?错误长什么样、能不能重试?(
ErrorStep、CreatingStep) - 装完了有哪些警告?比如权限不够、repo 是 fork、org policy 限制?(
WarningsStep)
每一个分支都需要用户决策、都要展示状态。用一行 shell 解决不了——shell 是"我已知所有参数、一次性执行",而 GitHub App 安装是"边探测边问边装"。React 多步表单是这种"探测-决策-执行-反馈"循环的自然形态。
契约:install-github-app 写进用户 repo 的 workflow 文件内容是写死在 src/constants/github-app.ts 的 WORKFLOW_CONTENT 常量里——这是一个 GitHub Actions YAML 字符串,定义了 issue_comment / pull_request_review_comment / issues / pull_request_review 四类事件的触发条件(都是 @claude mention),跑在 ubuntu-latest 上,permissions 是 contents: read / pull-requests: read / issues: read / id-token: write。PR 标题也是常量 PR_TITLE = 'Add Claude Code GitHub Workflow'。这些常量就是 Claude ↔ GitHub 的契约——改 WORKFLOW_CONTENT 等于改所有未来用户装上去的 workflow 模板,要非常小心向后兼容。
/commit-push-pr 的 ALLOWED_TOOLS 白名单为什么这么窄
看 src/commands/commit-push-pr.ts:11-23:只允许 Bash(git ...) 几条、Bash(gh pr ...) 几条、SearchExtraTools、两个 Slack 工具。为什么不给它 FileEdit / FileWrite? 因为 /commit-push-pr 的语义是"把已经做好的改动提交、推送、开 PR"——它不应该再修改代码。如果允许 FileEdit,这个命令就会从"提交工具"退化成"提交 + 顺手再改点代码"的工具,权限边界就乱了。
为什么 Slack 工具要单列? 看 commit-push-pr.ts 后面的 slackStep 逻辑:如果你的 CLAUDE.md 里写了"开完 PR 往 Slack 发链接",这个命令会尝试用 SearchExtraTools 找 Slack 工具,问你要不要发。这是一条条件性集成——不是所有用户都装了 Slack MCP,所以不能硬编码 mcp__slack__send_message,要走延迟工具搜索。如果没找到,silent skip,不打扰用户。
getPromptContent 里的 process.env.USER_TYPE === 'ant' && isUndercover()(commit-push-pr.ts:33-40 附近)是一个有意思的边界:Anthropic 内部用户跑这个命令时,会切到 "undercover" 模式——不暴露自己在用 Claude。这是 dogfooding 的产物:内部用户用自家工具时,对外(比如在公开的开源 repo 里开 PR)不能露出"这是 AI 写的"的痕迹。这个分支只在 USER_TYPE === 'ant' 时生效,普通用户看不到。
三种长驻模式(ACP / Bridge / Daemon)共享底层 query loop 但各有独立 entry
这是设计大纲第十二章的核心论点在集成视角下的具体化。三者的关系:
- ACP(
src/services/acp/):cli.tsx:123-124的--acpfast-path,受feature('ACP')门控。进入src/services/acp/entry.ts,spawn 一个AcpAgent(agent.ts)。agent 把 ACP 客户端的请求桥接到内部的 query loop(src/services/acp/bridge.ts),权限决策走createAcpCanUseTool(src/services/acp/permissions.ts)。 - Bridge(
src/bridge/):cli.tsx:178-188的remote-control/rc/remote/sync/bridge五个别名 fast-path,受feature('BRIDGE_MODE')门控。进入src/bridge/bridgeMain.ts,JWT 认证(jwtUtils.ts)、消息传输(bridgeMessaging.ts)、权限回调(bridgePermissionCallbacks.ts)。 - Daemon(
src/daemon/):cli.tsx的daemon子命令,受feature('DAEMON')门控。src/daemon/main.ts是 entry,workerRegistry.ts管 worker,--daemon-worker=<kind>派生精简 worker。
共享的部分:三者都最终调用 src/query.ts 的 query() async generator(见设计大纲第五章)。工具系统、Provider 路由、流式响应——这些都是共用的。各自增加的编排层:ACP 加了"会话管理 + 权限桥接 + prompt 排队",Bridge 加了"JWT 认证 + 远端消息传输 + 权限远程审批",Daemon 加了"worker 注册表 + 心跳 + 精简 worker 派生"。
为什么三个要分开:因为它们的调用方不同。ACP 的调用方是 IDE(同机 stdio),Bridge 的调用方是 RCS 后端(远端 JWT),Daemon 的调用方是 CI 或 supervisor(进程级 spawn)。三种调用方对认证、传输、生命周期的要求完全不同——IDE 不需要认证(已经在用户机器上)、RCS 必须认证(暴露在网络上)、Daemon 必须支持后台 + 心跳(长跑)。把这些塞进同一个 entry 会让代码变成"if (acp) {...} else if (bridge) {...} else if (daemon) {...}"的分支地狱。分开三个 entry、各自 feature-gated,是用 entry 数量换 entry 简单度的权衡。
BYOC runner 是三条线的交汇点:claude environment-runner / claude self-hosted-runner(见设计大纲第十二章)是这三条线和 CI(产品大纲第十一章)的交汇——它能让外部 CI 系统以 Bring-Your-Own-Compute 的方式调用 Claude,背后可能用 ACP(同机)、Bridge(远端)、或 Daemon(长跑)任意一种。这是"集成边界"最抽象的一层:用户不直接选 ACP/Bridge/Daemon,他选的是 environment-runner,由 runner 决定底下用哪种长驻模式。
VS Code 桥接(vscode-ide-bridge/)的现状
CLAUDE.md 提到 vscode-ide-bridge/ 是"VS Code 桥接"辅助目录。但这个目录在当前仓库里实际不存在(ls 返回空)。VS Code 集成实际走的是 /ide 命令 + VS Code 扩展(扩展是独立分发的,不在本仓库里),不是通过这个目录里的代码。vscode-ide-bridge/ 在仓库的某个历史版本里存在过、后来被移除或合并到 src/commands/ide/——CLAUDE.md 的描述滞后了。这是反编译重建工作的典型痕迹:文档描述的是"原本应该有什么",代码里实际是"重建后剩下了什么"。
两视角如何呼应
用户视角的每一个"我能接什么"的清单,几乎都能在设计视角找到对应的契约和决策:
- "我能在 VS Code / Zed / Cursor 里用 Claude 吗"(产品视角)对应 "为什么 IDE 走 MCP 的
sse-ide/ws-ide子类型、为什么 ACP agent 用 stdio NDJSON"(设计视角)——用户看到的是"装个扩展、/ide一连就行",开发者看到的是"dynamicMcpConfig的idekey 用了专门的 type、ACP 协议形态选择 stdio 是为了 IDE spawn 子进程最简单"。 - "我能不能让远端调用我机器上的 Claude"(产品视角)对应 "acp-link 为什么是 WebSocket → stdio 桥接、自托管 RCS 为什么是 Docker + Web UI"(设计视角)——用户看到的是"
claude remote-control一跑、Web UI 一开就能用",开发者看到的是"三种长驻模式(ACP / Bridge / Daemon)共享 query loop 但各有独立 entry、用 entry 数量换 entry 简单度"。 - "我在 Codex CLI 登录过、Claude 这边能复用吗"(产品视角)对应 "为什么 ChatGPT 订阅凭证要 fallback 读
~/.codex/auth.json"(设计视角)——用户看到的是"不用再登录一次",开发者看到的是"两边用同一 issuer 同一 client_id、令牌可互换、但 schema 没有契约约束只靠碰巧一致"。 - "我能在 GitHub Actions 里用 Claude 吗"(产品视角)对应 "
install-github-app为什么是 React 多步表单、/commit-push-pr的ALLOWED_TOOLS白名单为什么这么窄"(设计视角)——用户看到的是"claude install-github-app一键装、@claude一 at 就触发",开发者看到的是"11 个 Step 组件对应 11 个分支、WORKFLOW_CONTENT常量是 Claude ↔ GitHub 的契约、白名单用'允许什么'定义命令的语义边界"。 - "我的 key 会不会被别的工具读到"(产品视角)对应 "跨工具凭证共享为什么只有 ChatGPT 订阅路径、为什么反向不成立"(设计视角)——用户看到的是"除了 ChatGPT 订阅路径、其他 key 都不共享",开发者看到的是"后入场的一方做兼容、先入场的一方保持简单的非对称设计"。
- "
vscode-ide-bridge/是什么"(产品视角用户翻 CLAUDE.md 看到的)对应 "反编译重建工作的典型痕迹——文档描述原本应该有什么、代码里实际剩下了什么"(设计视角)——用户看到的是"文档里提到了一个目录",开发者看到的是"那个目录在当前仓库里实际不存在、VS Code 集成走的是/ide+ 独立扩展"。
这种呼应关系是"与其他工具集成"必须双视角覆盖的核心原因:用户视角告诉你怎么接,设计视角告诉你接的边界在哪、契约长什么样、哪些描述滞后于代码。两个视角合在一起,才能让使用者正确判断"我现在的接法是不是最优、要不要换一种",也让开发者在加新集成时知道"哪些约束(凭证隔离、协议形态、feature 门控、entry 分离)是必须遵守的"——而不是把每个集成都重新发明一遍。