feat(desktop): pre-trust bundled ApeMind recipes + let bundled apemind extension be editable#20
Merged
Merged
Conversation
…ning When the user opens a bundled ApeMind workflow, goose currently shows the "⚠️ New Workflow Warning" dialog because the recipe hash is not in the user's `userData/recipe_hashes/` directory. For workflows we ship with the app this is wrong — the user has already trusted them by installing the distribution. Extend `seedDefaultRecipes()` (added in earlier PR #19) to also: - Parse each bundled YAML - Compute SHA-256 over `JSON.stringify(parsed)` — same algorithm goose's Electron-side `recipeHash.ts` uses for the `has-accepted-recipe-before` IPC check - Write a `<hash>.hash` file in `userData/recipe_hashes/` if absent Effect: the bundled-recipe warning is suppressed on first open. Failure mode (best-effort): if YAML parse fails or hash shape mismatches goose's runtime serialization, the worst case is the warning shows once and the user clicks "Trust and Execute" — same as the prior behavior. Failure logs a warning, does not block startup. 5-cat compliance: still category 3 (默认配置) + 5 (打包分发). All in the Electron main process; zero changes to goose-rs core or the warning dialog logic. Signed-off-by: earayu <earayu@163.com>
The `apemind` entry in bundled-extensions.json ships with placeholder URL and Authorization Bearer token (per earayu2's #鹅岛 directive). With `bundled: true` the existing ExtensionItem.tsx gating hides the edit (gear) button entirely, so the user has no way to swap the placeholder values from the UI. Surgical carve-out: keep all other bundled / builtin extensions read-only (preserve upstream security model), but special-case `extension.name === 'apemind'` so its edit button appears. Users can then open the configure modal and replace URL + Bearer token before enabling. 5-cat compliance: still category 4 (UI 可见性微调) + 3 (默认配置 / bundled extension config). The change is a one-condition extension to existing logic and rebases cleanly with upstream. Signed-off-by: earayu <earayu@163.com>
earayu
added a commit
that referenced
this pull request
May 28, 2026
…llback (#22) * fix(desktop): trust bundled recipes by title when runtime hash mismatches PR #20 pre-computed SHA-256 over `JSON.stringify(yaml.parse(file))` and wrote `userData/recipe_hashes/<hash>.hash` for each bundled YAML. Field inspection on 3F (冯诺伊曼) confirms three `.hash` files exist for the three bundled recipes, but earayu2 still sees "⚠️ 新配方警告" when opening any of them. Root cause: the `recipe` object passed to the `has-accepted-recipe-before` IPC at runtime comes from goose-server (Rust). Its `JSON.stringify` shape (field order, `null` for absent optional fields, extra metadata) differs from a naive `JSON.stringify(yaml.parse(file))`, so the SHA-256 hashes do not match and the existing pre-trusted file is never found. Fix: add a second match path that does not depend on byte-exact JSON serialization: 1. `seedDefaultRecipes` also writes `userData/bundled-recipe-titles.json` — an array of the `title` fields parsed from each bundled YAML. 2. `recipeHash.ts` `has-accepted-recipe-before` handler: when the hash lookup misses with ENOENT, fall back to checking whether `recipe.title` is in the bundled-titles list. If yes, return true. Effect: bundled recipes are trusted on first open even if the runtime recipe shape differs from yaml.parse output. Existing hash-based trust still works for user-recorded acceptances (e.g. user clicks "Trust and Execute" on a non-bundled recipe). 5-cat compliance: still category 3 (默认配置) + category 4 (UI behavior). The IPC handler change is localized to one file; no change to goose-rs / RecipeWarningModal / recipe loading logic. Signed-off-by: earayu <earayu@163.com> * refine: match bundled recipe by title AND description to lower collision risk @梅西 raised that pure title match could false-positive on user-imported recipes with the same title. Tighten by requiring both `title` and `description` to match the bundled entry. Both fields are stable identifiers of bundled ApeMind workflows (authored by 梅西, unlikely to collide with random user imports). User edits that change description still see the warning, which is the intended security behavior for modified recipes. Signed-off-by: earayu <earayu@163.com> --------- Signed-off-by: earayu <earayu@163.com>
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.
现状
PR #19 把 ApeMind MCP 占位 + Recipe seeding 接到分发层后,3F 本机验证(@冯诺伊曼 msg c04c0ede)确认:
~/.config/goose/recipes/但 @earayu2 又给了两个 UX 反馈:
userData/recipe_hashes/里没有这个 recipe 的 hash 记录 —— goose 默认认为这是用户没见过的"新工作流"。ExtensionItem.tsx的 gating 规则把所有bundled: true扩展视为不可编辑(只有开关、没有齿轮按钮)。但 apemind 的 URL + token 是占位值,用户必须能编辑才能启用。现象
apemind-knowledge-qa/apemind-deep-research/apemind-table-summary工作流 → 弹"新工作流警告" → 体验差(明明是我们 ship 的工作流为啥还要警告)影响
期望结果
两个最小改动:
seedDefaultRecipes()增加预信任 hash(ui/desktop/src/main.ts):JSON.stringify(parsed)+ SHA-256app.getPath('userData')/recipe_hashes/<hash>.hash写时间戳ipcMain.handle('has-accepted-recipe-before', ...)用的检查方式 —— 写文件后 goose 视为"用户已接受",不弹警告ExtensionItem.tsx给 apemind 开后门:extension.type === 'builtin' || ('bundled' in extension && extension.bundled)→ 不可编辑extension.name === 'apemind'→ 即使 bundled 也允许编辑不解决什么
recipeHash.tsIPC handler 本身(保持上游 hash 检查 + record 逻辑不变)allow_configure字段到 BundledExtension JSON schema(PoC 阶段就 apemind 一个,特例够用;通用化等多扩展时再做)验证
~/.config/goose/recipes/+userData/recipe_hashes/等用户状态pnpm -C ui/desktop run package+ 打开新 appapemind-knowledge-qa等任一 ApeMind 工作流 → 应不弹"新工作流警告"关联