fix(extension): 完成MCP命令目标并收紧Schema边界

This commit is contained in:
2026-09-02 14:52:03 +08:00
parent c3ef9dfa44
commit 9e680a0239
24 changed files with 427 additions and 45 deletions
@@ -544,7 +544,9 @@ error
当前宿主只注册已启用且已满足权限授权的 Plugin Command。执行前按 JSON Schema 校验参数、按 `when` 校验上下文,再根据 Command 声明裁剪 Context;单次执行默认超时 30 秒,effect 的 JSON 编码结果不得超过 64 KiB。宿主保留最多 500 条轻量审计事件,仅记录 Command、Plugin、状态、耗时和错误码,不记录 arguments、Context、effect 或 Secret。
需要 Secret 的 Command 必须在 `commands.yaml` 的内部 `secrets` 数组中声明对应 Setting Key,并在 Plugin Manifest 声明 `secrets.use` 权限。安装时宿主校验该字段确实属于当前 Plugin Settings Schema 的 `secret` 类型;只有权限已授予并启用后,运行时才向受控 handler 提供按需 Resolver,未声明字段返回 `PLUGIN_SECRET_ACCESS_DENIED``secrets` 不属于前端 `PluginCommand` DTOSecret 明文也不会并入普通 Settings 字典。
需要 Secret 的 Command 必须在 `commands.yaml` 的内部 `secrets` 数组中声明对应 Setting Key,并在 Plugin Manifest 声明 `secrets.use` 权限。安装时宿主校验该字段确实属于当前 Plugin Settings Schema 的 `secret` 类型;只有权限已授予并启用后,运行时才向受控 handler 或 MCP Command Target 提供声明过的 Secret。未声明字段返回 `PLUGIN_SECRET_ACCESS_DENIED`,必填 Secret 未配置返回 `PLUGIN_SECRET_REQUIRED``secrets` 不属于前端 `PluginCommand` DTOSecret 明文也不会并入普通 Settings 字典。
`commands.yaml` 中的执行目标必须在宿主白名单 `handler` 与当前 Plugin 命名空间的 `mcp_tool` 之间二选一。MCP Command Target 不注册为 Agent Tool;宿主用 `_notesagent` 保留包装传入 Command ID、参数、裁剪后的 Context 和声明过的 Secret,并将 MCP structured result 再校验为白名单 effect。Command 与 Tool Schema 仅允许 `#...` 文档内引用,任何通过 `$ref``$dynamicRef` 指向文件、HTTP 或其他外部资源的 Schema 都会在注册前被拒绝。
### 7.5 Settings Schema
@@ -627,7 +629,7 @@ DELETE /api/plugins/{plugin_id}/settings/{key}/secret
Secret 明文不进入普通 Settings、日志、Trace、Benchmark Dataset 或前端持久化。
非敏感值按 `plugin_id` 写入 `APP_DATA_DIR/plugins/settings.json`。该文件只保存普通值、Schema 版本和确定性的 Secret ReferenceSecret 本身由宿主凭据存储加密保存。卸载 Plugin 时同时清理它的 Settings 命名空间和 Secret Reference。当前开发阶段使用 Fernet 文件凭据存储,第三阶段接入桌面 Host 后应迁移到 Stronghold 或系统 Keychain。
非敏感值按 `plugin_id` 写入 `APP_DATA_DIR/plugins/settings.json`。该文件只保存普通值、Schema 版本和确定性的定长 Secret Reference,格式为 `plugin.<sha256(plugin_id\\0setting_key)>`;Secret 本身由宿主凭据存储加密保存。卸载 Plugin 时同时清理它的 Settings 命名空间和 Secret Reference。当前开发阶段使用 Fernet 文件凭据存储,第三阶段接入桌面 Host 后应迁移到 Stronghold 或系统 Keychain。
`plugin.*` 为宿主保留凭据命名空间。`/api/credentials/{credential_id}`、Provider 持久配置、Provider 临时测试凭据和 Provider Resolver 均拒绝该前缀,防止通过 Provider 链路覆盖、删除或向外部 Base URL 发送 Plugin Secret。
@@ -657,6 +659,7 @@ PLUGIN_SETTINGS_VERSION_CONFLICT
PLUGIN_SETTINGS_FIELD_INVALID
PLUGIN_SECRET_FIELD_NOT_FOUND
PLUGIN_SECRET_ACCESS_DENIED
PLUGIN_SECRET_REQUIRED
PLUGIN_SECRET_VALUE_INVALID
PLUGIN_SECRET_STORE_ERROR
PLUGIN_STORAGE_ERROR