Define repository and feature-scoped documentation rules for PRDs, User Stories, logic, UI, technical design, and progress evidence. Move feature-owned documents under docs/features, add one entry point per feature, remove the redundant docs index, and update all affected cross-references. Expand the local tool environment design with explicit product, story, logic, UI, technical, and progress documents.
14 KiB
本机工具环境功能逻辑设计
文档信息
| 项目 | 内容 |
|---|---|
| 状态 | 计划 |
| 版本 | 0.1 |
| 日期 | 2026-09-01 |
| 关联 PRD | 本机工具环境 PRD |
| 关联场景 | 本机工具环境 User Stories |
本文是本功能业务规则、状态转换、决策表和跨场景一致性的权威来源。它不定义组件视觉,也 不规定代码模块如何实现。
1. 逻辑目标
- 同一用户操作在不同本机 Runtime 和 stdio MCP 中得到一致的解释器选择。
- 系统不通过隐式回退掩盖配置错误。
- 工具可执行、配套命令可执行和具体能力依赖可用是三个可区分事实。
- 已运行进程使用稳定环境,不被设置变化中途改写。
- 安装、更新、取消、失败和删除都有唯一、可恢复的结果。
- 本机环境和远程 Host 环境没有隐式传播。
2. 核心不变量
INV-1 单一明确来源
Node.js 和 Python 各自恰好保存一个来源:managed 或 custom。不存在 auto、候选优先级
列表或运行时动态选择。
INV-2 禁止静默回退
当前来源不可用时,该工具明确不可用。即使发现另一套系统解释器,也不会自动切换。
INV-3 配套命令同源
node、npm、npx必须属于同一 Node 来源。python、python3、pip必须属于同一 Python 来源。pip等价于当前 Python 的-m pip,不能解析到其他解释器。
INV-4 三层状态独立
- 解释器状态:Node 或 Python 本身能否执行。
- 工具组合状态:npm/npx 或 pip/venv/SSL 是否完整。
- 能力依赖状态:具体 SKILL/MCP 的入口和第三方依赖是否通过验证。
任一上层成功都不能推导下一层成功。
INV-5 进程环境不可变
每个 Runtime/MCP 进程在启动时取得一份环境快照。设置变化只影响之后启动的进程,不改写 已运行进程的 PATH 或解释器。
INV-6 绝对命令优先
stdio MCP 配置的绝对 command 表达用户对该 MCP 的明确覆盖,原样执行,不经过全局工具 命令替换。
INV-7 本机与远程隔离
本机工具选择、shim、Python 包、SKILL 包和 stdio MCP 配置不上传到远程 Host。
INV-8 不推断能力依赖已就绪
能力没有专属实际诊断时,状态只能是“未验证”,不能根据解释器版本或文件存在推断“已就绪”。
3. 状态维度
3.1 来源选择
managed
custom(executablePath)
这是唯一持久状态。
3.2 托管 Python 安装状态
not-installed
downloading
verifying
installing
testing
ready
update-available
error
error 同时携带“是否仍有旧版可用”。若旧版可用,实际工具状态仍基于旧版诊断。
托管 Node 随 GoodBuddy 存在,不使用下载安装状态,但仍可能因打包损坏进入诊断失败。
3.3 工具诊断状态
unknown
testing
ready
partial
unavailable
ready:解释器和本功能承诺的配套命令全部通过。partial:解释器通过,至少一个配套命令失败。unavailable:解释器本身不能使用。
3.4 能力依赖状态
unknown
checking
ready
missing
incompatible
error
unknown在 UI 中显示“依赖未验证”。missing表示明确缺少包或入口。incompatible表示解释器版本、架构或 ABI 不满足已声明要求。error表示诊断本身没有得出有效结论。
4. 来源解析决策表
| 保存来源 | 当前事实 | 解析结果 | 是否回退 |
|---|---|---|---|
| 托管 Node | 完整诊断通过 | 使用 Electron Node 与锁定 npm/npx | 否 |
| 托管 Node | Node 通过,npm/npx 失败 | Node 部分可用,显示失败项 | 否 |
| 托管 Node | Node 失败 | Node 不可用,提示修复/重装 GoodBuddy | 否 |
| 托管 Python | 未安装 | Python 不可用,提供安装 | 否 |
| 托管 Python | 已安装且诊断通过 | 使用托管 Python | 否 |
| 托管 Python | 更新失败但旧版健康 | 继续使用旧版并显示更新失败 | 否 |
| 托管 Python | 安装损坏 | Python 不可用,提供重新安装/删除 | 否 |
| 自定义 | 路径及诊断通过 | 使用该绝对路径 | 否 |
| 自定义 | 路径失效 | 保持选择并显示路径不可用 | 否 |
| 自定义 | 解释器通过、配套命令失败 | 部分可用并显示失败项 | 否 |
| 任意 | 发现其他有效解释器 | 只作为候选展示 | 不自动使用 |
5. 命令解析决策表
| 调用形式 | 结果 |
|---|---|
node ... |
当前 Node |
npm ... |
当前 Node 配套 npm |
npx ... |
当前 Node 配套 npx |
python ... |
当前 Python |
python3 ... |
当前 Python |
pip ... |
当前 Python -m pip |
#!/usr/bin/env node |
从进程工具 PATH 解析当前 Node |
#!/usr/bin/env python3 |
从进程工具 PATH 解析当前 Python |
| stdio MCP 绝对 command | 原样执行 |
未托管裸命令,例如 uvx |
按原筛选 PATH 处理;找不到则明确失败 |
| HTTP/SSE MCP | 不参与本机命令解析 |
绝对 command 的子进程若自行调用裸 node 或 python,仍会看到该 MCP 进程启动时的工具
PATH。这不改变绝对 command 本身。
6. 首次使用和迁移
6.1 全新安装
| 工具 | 默认选择 | 首次状态 |
|---|---|---|
| Node.js | GoodBuddy 托管 | 立即真实诊断 |
| Python | GoodBuddy 托管 | 未安装,展示安装入口 |
系统候选可以展示,但不会改变默认选择。
6.2 旧版本升级
- 设置中没有工具环境字段时执行一次迁移。
- 分别按旧版本实际 PATH 解析 Node 和 Python 3。
- 有效解释器固化为
custom + 绝对真实路径。 - 无有效解释器时选择
managed。 - 持久化后不再因 PATH 变化迁移。
迁移中 Node 和 Python 独立决策,不要求二者使用同一种来源。
7. 托管 Python 生命周期
7.1 首次安装
not-installed
→ downloading
→ verifying
→ installing
→ testing
→ ready
任一步失败:
→ 删除本次暂存
→ error(没有活动版本)
→ 用户可重试
7.2 取消
| 取消阶段 | 结果 |
|---|---|
| 下载 | 终止下载、删除暂存、回到安装前状态 |
| 校验 | 终止校验、删除暂存、回到安装前状态 |
| 解压/安装 | 完成本次有界清理、回到安装前状态 |
| 测试 | 停止诊断、删除未发布候选、回到安装前状态 |
取消不发布候选版本,不把取消显示为安装失败。
7.3 更新
- 下载和验证候选时,旧版继续服务现有进程。
- 应用候选前,页面说明需要停止依赖托管 Python 的本机 Runtime/MCP。
- 用户确认后通过现有生命周期取消/停止相关进程。
- 无法确认停止时不替换当前版本。
- 候选完整诊断通过后才发布。
- 失败继续使用旧版,并显示更新失败。
首期不让两个托管 Python 版本长期并存。候选暂存只服务本次更新。
7.4 删除
| 条件 | 行为 |
|---|---|
| 没有使用中进程 | 确认后删除托管目录 |
| 有使用中进程 | 说明影响,用户确认后停止相关进程再删除 |
| 进程停止失败 | 不删除,保留当前环境 |
| 当前选择为自定义 | 删除托管包不改变自定义来源 |
| 当前选择为托管 | 删除后保持托管选择,状态变为未安装 |
8. 设置保存与进程生效
8.1 保存时
- 验证待保存来源。
- 自定义路径必须在保存前通过解释器诊断;配套命令可以形成
partial。 - 保存成功后标记本机 Runtime 环境配置已变化。
- 不直接修改任何运行中进程。
8.2 后续进程
- 没有活动请求的缓存 Runtime 在下次使用前按现有重建入口重建。
- 有活动请求的 Runtime 完成或被用户停止前保持原环境。
- 已启动 stdio MCP 保持原环境,正常关闭、重连或显式测试后使用新环境。
- 新启动的 Runtime/MCP 立即使用新环境。
每个工具调用的活动记录应归属于实际承载它的进程,不根据最新设置追改历史来源。
9. 能力依赖逻辑
9.1 诊断输入
能力可以声明:
- 需要 Node 或 Python。
- 最低/最高解释器版本。
- 可选依赖文件位置。
- 可选的无副作用诊断入口。
首期声明只用于显示、版本比较和显式诊断,不触发自动安装。
9.2 状态推导
| 工具状态 | 能力诊断 | 能力状态 |
|---|---|---|
| unavailable | 不执行 | missing 或 incompatible,附工具原因 |
| partial | 能力不依赖失败配套项且实际诊断成功 | ready |
| partial | 能力依赖失败配套项 | missing |
| ready | 没有能力诊断 | unknown |
| ready | 实际诊断成功 | ready |
| ready | 明确缺包 | missing |
| ready | 版本/ABI 不满足 | incompatible |
| 任意 | 诊断自身异常 | error |
“依赖未验证”不是错误,也不能显示为“已就绪”。
10. Ask、Execute 与 MCP
| 场景 | 解释器是否可见 | 是否允许执行 |
|---|---|---|
| 本机 Execute Runtime | 是 | 按现有 Execute 权限 |
| 本机 Ask Runtime | 可以存在于进程环境 | 仍由 Runtime Ask 边界决定,不能因此获得命令权限 |
| Main 启动的已启用 stdio MCP | 是 | 按当前 MCP 分配和模式规则 |
| HTTP/SSE MCP | 不适用 | 按当前网络 MCP 规则 |
| 远程 Runtime | 否 | 使用远程 Host 自身环境 |
工具环境不创建新的工具,不扩大 Runtime 当前允许的工具集合。
11. 网络受限与离线
11.1 托管 Node
随 GoodBuddy 提供,安装后可离线使用。
11.2 托管 Python
- 首期支持当前官方 GitHub/镜像来源。
- 下载源不可达时保持未安装或旧版可用状态,并显示准确原因。
- 首期不提供 Python 离线包导入,避免引入未经选型的包格式和导入流程。
- 完全离线用户可以选择已经离线安装的自定义 Python。
未来若加入离线导入,必须在 PRD、User Stories、逻辑状态和技术包校验中同时定义,不能只 增加一个文件按钮。
12. 冲突与一致性检查
| 可能冲突 | 唯一规则 |
|---|---|
| 全局工具选择 vs MCP 绝对 command | 绝对 command 优先 |
| 新设置 vs 运行中进程 | 运行中进程保留启动快照 |
| 新托管版本 vs 健康旧版本 | 候选完整通过后才发布 |
| 系统发现新版本 vs 已保存自定义路径 | 不自动切换 |
| 解释器成功 vs 缺少第三方包 | 工具 ready,能力 missing/unknown |
| Ask 环境包含解释器 vs Ask 只读 | Ask 权限边界优先 |
| 本机设置 vs 远程项目 | 远程隔离优先 |
| 镜像不可达 vs 其他来源可用 | 不在同一次操作中静默切换来源 |
13. 逻辑评估结论
13.1 完整性评估
| 评估维度 | 结论 | 依据 |
|---|---|---|
| 首次使用 | 通过 | 托管 Node 立即诊断,托管 Python 明确未安装 |
| 正常执行 | 通过 | SKILL 与 stdio MCP 共用同一命令解析 |
| 自定义环境 | 通过 | 明确路径、真实诊断、禁止静默回退 |
| 部分失败 | 通过 | 解释器、工具组合、能力依赖三层状态独立 |
| 安装生命周期 | 通过 | 安装、取消、失败、重试有唯一结果 |
| 更新生命周期 | 通过 | 候选通过后发布,失败保留健康旧版 |
| 删除生命周期 | 通过 | 使用中进程先停止,失败不删除 |
| 设置生效 | 通过 | 进程启动快照不可变,新进程使用新设置 |
| 升级兼容 | 通过 | 旧系统解释器一次性固化为自定义路径 |
| Ask/Execute | 通过 | 工具环境不扩大工具集合或权限 |
| 远程边界 | 通过 | 本机配置不进入 Host |
| 受限网络 | 通过 | 来源失败可见,不在同次操作静默切换 |
| 完全离线 | 有明确限制 | Node 可用;Python 首期要求已有自定义环境 |
13.2 一致性评估
- “两种来源”与自定义候选探测不冲突:候选只是自定义来源的选值,不是第三种来源。
- “禁止回退”与升级迁移不冲突:迁移只发生一次,完成后按普通保存选择处理。
- “进程环境不可变”与 Runtime 重建不冲突:只有空闲或后续启动的进程使用新环境。
- “工具环境就绪”与“能力依赖就绪”不冲突:两者属于独立状态维度。
- “绝对 MCP command 优先”与 PATH 注入不冲突:command 不替换,但其子进程继承启动快照。
- “更新保留旧版”不要求长期多版本管理:旧版只在候选发布前保持当前,候选失败即删除。
13.3 当前未决项
没有未决的产品逻辑分支。以下属于实施前必须解决的技术选型,不改变业务规则:
- 六平台 CPython 独立发行包、固定版本、许可证和摘要。
- SKILL/MCP 运行要求声明的最小 schema 和无副作用诊断入口。
- 各 Runtime 当前缓存进程的精确空闲判定与既有重建入口接线。
若技术选型无法满足当前逻辑,例如目标 Python 工件不包含可用 pip/venv,必须回到 PRD 和 逻辑设计调整承诺,不能在实现中静默降级。
14. 需求追踪
| 逻辑范围 | PRD | User Stories |
|---|---|---|
| 明确来源与禁止回退 | FR-3、FR-8 | US-C1、US-C2、US-D3 |
| 托管 Node | FR-1 | US-A1、US-B2 |
| 托管 Python 生命周期 | FR-2、FR-9 | US-A2、US-D2、US-D4、US-D5 |
| 三层状态 | FR-6 | US-A3、US-A4 |
| MCP 命令解析 | FR-5 | US-B1、US-B2、US-B3 |
| 生效时机 | FR-7 | US-C3、US-C4 |
| Ask/Execute | FR-10 | US-D6 |
| 远程隔离 | FR-7、FR-9 | US-D1 |
| 受限网络与离线 | FR-2 | US-E1、US-E2 |