Closes#417.
The user config (`~/.config/opencode/oh-my-openagent.json[c]`) is no
longer the only level above the project. `loadPluginConfig` now walks
from the working directory up to `$HOME` (inclusive), collecting every
`.opencode/oh-my-openagent.json[c]` it finds along the way. Configs
closer to the working directory override configs farther up, allowing
per-tree setups like:
~/work/.opencode/oh-my-openagent.json # work credentials
~/dev/.opencode/oh-my-openagent.json # personal credentials
~/.config/opencode/oh-my-openagent.json # global fallback
This subsumes the previous single project-config load: the project's
own config is just the closest hit of the walk. `agent_definitions`
relative paths resolve against each ancestor's own `.opencode/` base,
`git_master` overrides accumulate across the walk (closer wins), and
legacy basenames are migrated wherever they appear.
`mcp_env_allowlist` is intentionally NOT extensible from walked
ancestors. It remains user-only as a security boundary so a malicious
or untrusted parent directory cannot extend the env var allowlist used
during ${VAR} expansion in `.mcp.json` files. The existing test that
pins this behaviour is extended to cover the multi-ancestor case.
`os.homedir()` caches in Bun, so the stop directory is resolved by
reading `process.env.HOME` directly. Production behaviour is unchanged
because the OS sets HOME at startup; tests can now redirect the walk
boundary by setting HOME to a temp directory before each call.
Updates test expectations across agent, cli, shared, plugin, and tools tests
to match gpt-5.5 as the new default for oracle, hephaestus, and deep agents.
Includes snapshot updates for model-fallback tests.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Prevent project config defaults from re-enabling git_master fields that users explicitly disabled. Rebuild git_master from explicit user and project keys so include_co_authored_by and commit_footer merge predictably.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Root cause: loadPluginConfig() unconditionally switched userConfigPath to the
canonical name after calling migrateLegacyConfigFile(), even when migration
failed (e.g. file lock on Windows, permission denied). This left the config
path pointing to a non-existent file, so the plugin config silently loaded
as empty defaults.
Additionally, several fallback/default paths were hardcoded to the legacy
'oh-my-opencode' basename instead of using CONFIG_BASENAME ('oh-my-openagent'),
causing CLI config commands (writeOmoConfig, detectCurrentConfig) to write to
the wrong filename.
Changes:
- plugin-config.ts: check migrateLegacyConfigFile() return value; only switch
to canonical path if migration succeeded OR the canonical file already exists
- opencode-config-dir.ts: use CONFIG_BASENAME for omoConfig path in
getOpenCodeConfigPaths()
- config-context.ts: getOmoConfigPath() now uses detectPluginConfigFile() to
find whichever name variant actually exists on disk
- plugin-config.ts: default fallback paths use CONFIG_BASENAME instead of
hardcoded legacy name
- Added test: loadPluginConfig still loads config when migration fails
(read-only directory simulation)
disabled_tools was defined in the Zod schema but omitted from
mergeConfigs(), causing project-level config to shadow user-level
disabled_tools instead of merging both sets. Add Set union and
regression test.
Closes#2555
Align runtime defaults, tests, docs, and generated artifacts with the newer GPT-5.4 baseline. Keep think-mode and prompt-routing expectations consistent after the model version bump.
Previously, a single validation error (e.g. wrong type for
prometheus.permission.edit) caused safeParse to fail and the
entire oh-my-opencode.json was silently replaced with {}.
Now loadConfigFromPath falls back to parseConfigPartially() which
validates each top-level key in isolation, keeps the sections that
pass, and logs which sections were skipped.
Closes#1767
When merging user and project configs, categories were simply
spread instead of deep merged. This caused user-level category
model settings to be completely overwritten by project-level
configs, even when the project config only specified partial
overrides like temperature.
Add deepMerge for categories field and comprehensive tests.