fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT#7335
fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT#7335jamadeo merged 3 commits intoblock:mainfrom
Conversation
Signed-off-by: Vadim Polulyakh <[email protected]> (cherry picked from commit ce19b4c)
Signed-off-by: Vadim Polulyakh <[email protected]> (cherry picked from commit 7f789c8)
35d0a4a to
09edb58
Compare
There was a problem hiding this comment.
Pull request overview
This PR unifies path resolution in the Desktop app around the GOOSE_PATH_ROOT environment variable. Previously, MCP shim scripts (jbang, uvx, npx/node) and the recipe storage picker used hardcoded ~/.config/goose paths, causing divergence in branded/isolated desktop runs where the path root differs from the default. The PR fixes root causes of issues like mcp-hermit not being found and the "touch: cannot touch" cleanup error (issue #5944).
Changes:
main.ts: AddsresolveGoosePathRoot()to expand/exposeGOOSE_PATH_ROOTinappConfigand passes it through to thegoosedsubprocess environment.- Shell shims (
jbang,uvx,node-setup-common.sh): Replace hardcoded~/.config/goosepaths withMCP_HERMIT_DIRderived fromGOOSE_PATH_ROOT(with a deprecatedGOOSE_CONFIG_DIRfallback and a standard platform default). recipe_management.ts: UpdatesgetStorageDirectoryto preferGOOSE_PATH_ROOT/config/recipesfor global recipe browsing.
Reviewed changes
Copilot reviewed 2 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
ui/desktop/src/main.ts |
Adds resolveGoosePathRoot() helper, exposes GOOSE_PATH_ROOT in appConfig, and passes it to the goosed subprocess env |
ui/desktop/src/recipe/recipe_management.ts |
Updates getStorageDirectory to use GOOSE_PATH_ROOT/config/recipes for global recipe directory |
ui/desktop/src/bin/uvx |
Replaces hardcoded ~/.config/goose with MCP_HERMIT_DIR derived from GOOSE_PATH_ROOT |
ui/desktop/src/bin/node-setup-common.sh |
Same path unification plus fixes the cleanup marker path for the mcp-hermit one-time cleanup |
ui/desktop/src/bin/jbang |
Same path unification as uvx |
| const configDir = window.appConfig.get('GOOSE_CONFIG_DIR') as string | undefined; | ||
| if (configDir) { | ||
| return `${configDir}/recipes`; | ||
| } |
There was a problem hiding this comment.
GOOSE_CONFIG_DIR is never added to appConfig in main.ts, so window.appConfig.get('GOOSE_CONFIG_DIR') will always return undefined and the fallback block on lines 49-52 is unreachable dead code. Either add GOOSE_CONFIG_DIR to appConfig in main.ts, or remove this dead fallback branch since the PR's stated intent is to unify around GOOSE_PATH_ROOT.
| const configDir = window.appConfig.get('GOOSE_CONFIG_DIR') as string | undefined; | |
| if (configDir) { | |
| return `${configDir}/recipes`; | |
| } |
* origin/main: (21 commits) fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT (#7335) fix: pass OAuth scopes to DCR and extract granted_scopes from token response (#7571) fix: write to real file if config.yaml is symlink (#7669) fix: preserve pairings when stopping gateway (#7733) fix: reduce server log verbosity — skip session in instrument, defaul… (#7729) fix: provider test infrastructure (#7738) fix: sanitize streamable HTTP extension names derived from URLs (#7740) refactor: derive GooseMode string conversions with strum (#7706) docs: Add Spraay Batch Payments MCP Extension Tutorial (#7525) fix: flake.nix (#7224) delete goose web (#7696) Add @angiejones as CODEOWNER for documentation (#7711) Add MLflow integration guide (#7563) docs: LM Studio availability (#7698) feat: add Avian as an LLM provider (#7561) Adds `linux-mcp-server` to the goose registry (#6979) fix: add #[serde(default)] to description field on 4 ExtensionConfig variants (#7708) feat: combine TUI UX from alexhancock/tui-goodness with publishing config from jackamadeo/package-tui (#7683) chore: cleanup old sandbox (#7700) Correct windows artifact (#7699) ...
* origin/main: (21 commits) fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT (#7335) fix: pass OAuth scopes to DCR and extract granted_scopes from token response (#7571) fix: write to real file if config.yaml is symlink (#7669) fix: preserve pairings when stopping gateway (#7733) fix: reduce server log verbosity — skip session in instrument, defaul… (#7729) fix: provider test infrastructure (#7738) fix: sanitize streamable HTTP extension names derived from URLs (#7740) refactor: derive GooseMode string conversions with strum (#7706) docs: Add Spraay Batch Payments MCP Extension Tutorial (#7525) fix: flake.nix (#7224) delete goose web (#7696) Add @angiejones as CODEOWNER for documentation (#7711) Add MLflow integration guide (#7563) docs: LM Studio availability (#7698) feat: add Avian as an LLM provider (#7561) Adds `linux-mcp-server` to the goose registry (#6979) fix: add #[serde(default)] to description field on 4 ExtensionConfig variants (#7708) feat: combine TUI UX from alexhancock/tui-goodness with publishing config from jackamadeo/package-tui (#7683) chore: cleanup old sandbox (#7700) Correct windows artifact (#7699) ...
…e-issue * origin/main: fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT (#7335) fix: pass OAuth scopes to DCR and extract granted_scopes from token response (#7571) fix: write to real file if config.yaml is symlink (#7669) fix: preserve pairings when stopping gateway (#7733) fix: reduce server log verbosity — skip session in instrument, defaul… (#7729) fix: provider test infrastructure (#7738) fix: sanitize streamable HTTP extension names derived from URLs (#7740) refactor: derive GooseMode string conversions with strum (#7706) docs: Add Spraay Batch Payments MCP Extension Tutorial (#7525) fix: flake.nix (#7224) delete goose web (#7696) Add @angiejones as CODEOWNER for documentation (#7711) Add MLflow integration guide (#7563) docs: LM Studio availability (#7698) feat: add Avian as an LLM provider (#7561) Adds `linux-mcp-server` to the goose registry (#6979) fix: add #[serde(default)] to description field on 4 ExtensionConfig variants (#7708)
* main: (45 commits)
fix: resolve {{ recipe_dir }} in nested sub-recipe paths during secret discovery (#7797)
Add @DOsinga as CODEOWNER for documentation (#7799)
feat: Add summarize tool for deterministic reads (#7054)
fix(api): use camelCase in CallToolResponse and add type discriminators to ContentBlock (#7487)
feat: ACP providers for claude code and codex (#6605)
chore(deps): bump express-rate-limit from 8.2.1 to 8.3.0 in /evals/open-model-gym/mcp-harness (#7703)
feat(openai): capture reasoning summaries from responses API (#7375)
Fix some dependencies (#7794)
fix: improve keyring availability error detection (#7766)
feat: add MiniMax provider with Anthropic-compatible API (#7640)
feat: add Tensorix as a declarative provider (#7712)
fix(security): remove insecure default secret from GOOSE_EXTERNAL_BACKEND (#7783)
refactor: Convert Tanzu provider to declarative JSON config (#7124)
replaces https://github.com/block/goose/pull/7340/changes (#7786)
feat(summon): make skill supporting files individually loadable via load() (#7583)
Keep toast open on failed extension (#7771)
fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT (#7335)
fix: pass OAuth scopes to DCR and extract granted_scopes from token response (#7571)
fix: write to real file if config.yaml is symlink (#7669)
fix: preserve pairings when stopping gateway (#7733)
...
* main: (69 commits)
fix: resolve {{ recipe_dir }} in nested sub-recipe paths during secret discovery (#7797)
Add @DOsinga as CODEOWNER for documentation (#7799)
feat: Add summarize tool for deterministic reads (#7054)
fix(api): use camelCase in CallToolResponse and add type discriminators to ContentBlock (#7487)
feat: ACP providers for claude code and codex (#6605)
chore(deps): bump express-rate-limit from 8.2.1 to 8.3.0 in /evals/open-model-gym/mcp-harness (#7703)
feat(openai): capture reasoning summaries from responses API (#7375)
Fix some dependencies (#7794)
fix: improve keyring availability error detection (#7766)
feat: add MiniMax provider with Anthropic-compatible API (#7640)
feat: add Tensorix as a declarative provider (#7712)
fix(security): remove insecure default secret from GOOSE_EXTERNAL_BACKEND (#7783)
refactor: Convert Tanzu provider to declarative JSON config (#7124)
replaces https://github.com/block/goose/pull/7340/changes (#7786)
feat(summon): make skill supporting files individually loadable via load() (#7583)
Keep toast open on failed extension (#7771)
fix(ui-desktop): unify path resolution around GOOSE_PATH_ROOT (#7335)
fix: pass OAuth scopes to DCR and extract granted_scopes from token response (#7571)
fix: write to real file if config.yaml is symlink (#7669)
fix: preserve pairings when stopping gateway (#7733)
...
Summary
This PR keeps path resolution consistent in Desktop by using
GOOSE_PATH_ROOTas the path-root contract, with a minimal surface area.What changed
main.ts: expose/passGOOSE_PATH_ROOTfor Desktop runtime and renderer config.jbang,uvx,node-setup-common.sh): resolvemcp-hermitunderGOOSE_PATH_ROOT/config(or platform default when unset).GOOSE_PATH_ROOT/config/recipesfor global recipe browsing in isolated runs.Why
In branded/isolated Desktop runs, backend paths and UI/shim paths can diverge (
GOOSE_PATH_ROOT/...vs~/.config/goose/...).That mismatch can cause extension bootstrap and recipe UX inconsistencies.
Related issues
Validation
cd ui/desktop && npm run lint:checkcd ui/desktop && npm run test:runBoth passed.
AI usage
AI assistance was used to draft and apply code edits; validation was performed by running the checks above.