Description
The 4 config-loading sites in packages/opencode/src/config/config.ts and packages/opencode/src/config/paths.ts hardcode the literal "opencode" (as opencode.json / opencode.jsonc) when discovering global, project, and managed config files:
globalConfigFile() at config.ts:335 — ["opencode.jsonc", "opencode.json", "config.json"]
loadGlobal() at config.ts:422-424 — config.json + opencode.json + opencode.jsonc cascade
- Project
.opencode directory loop at config.ts:588 — ["opencode.json", "opencode.jsonc"]
- Managed config dir loop at
config.ts:683 — ["opencode.json", "opencode.jsonc"]
- The
ConfigPaths.files(name, directory, worktree) helper at paths.ts:10 already takes a name, so it's nearly there — but the name is currently always "opencode" at call sites.
What this is for
Downstream forks and side-by-side deployments often want to load fork- or tenant-specific config files alongside the canonical opencode.json, without having to maintain a 4-site patch on every upstream sync. Concrete examples:
- A fork named
acompany-develop/securecode carries a 4-site securecode.json/jsonc fallback patch today; would prefer to load that via env var (or a similar opt-in) so the fork's config.ts stays byte-identical to upstream.
- Multi-tenant deployments where ops want to layer a
team.json over opencode.json.
This is also a thin equivalent of the pattern already established by OPENCODE_CONFIG_DIR — letting an env var widen the search surface without changing the default behavior.
Proposed shape
Add a single env var OPENCODE_EXTRA_CONFIG_NAMES (comma-separated):
export OPENCODE_EXTRA_CONFIG_NAMES=securecode,team
# loads opencode.json/jsonc, securecode.json/jsonc, team.json/jsonc (merge cascade)
Default: empty (= no behavior change). Add a corresponding Flag.OPENCODE_EXTRA_CONFIG_NAMES: string[] in packages/core/src/flag/flag.ts next to OPENCODE_CONFIG_DIR, and thread it through:
ConfigPaths.files() — append extra names' .json/.jsonc targets to the up-walk
globalConfigFile() — append extra names' candidates
loadGlobal() — extend the merge cascade
- Project
.opencode dir loop — extend the file list
- Managed config dir loop — extend the file list
All sites are simple Array.prototype.flatMap over the name list. No order-of-precedence change for the default case (opencode.* always wins where it currently does); extra names merge later so they can override per existing mergeConfig semantics.
Why not a plugin hook?
Config loading runs before any plugins can register hooks (plugins are declared in the config file), so the file-name list has to be resolved at bootstrap. An env var is the cleanest bootstrap-level switch.
Willing to PR
If the maintainers are interested, happy to put up the PR (the diff is small, ~50 lines + tests). Filing this issue first per the issue-first policy in CONTRIBUTING.md.
Out of scope
- Reordering precedence between names
- Removing default
opencode.* lookup
- Per-directory name overrides
Description
The 4 config-loading sites in
packages/opencode/src/config/config.tsandpackages/opencode/src/config/paths.tshardcode the literal"opencode"(asopencode.json/opencode.jsonc) when discovering global, project, and managed config files:globalConfigFile()atconfig.ts:335—["opencode.jsonc", "opencode.json", "config.json"]loadGlobal()atconfig.ts:422-424—config.json+opencode.json+opencode.jsonccascade.opencodedirectory loop atconfig.ts:588—["opencode.json", "opencode.jsonc"]config.ts:683—["opencode.json", "opencode.jsonc"]ConfigPaths.files(name, directory, worktree)helper atpaths.ts:10already takes aname, so it's nearly there — but the name is currently always"opencode"at call sites.What this is for
Downstream forks and side-by-side deployments often want to load fork- or tenant-specific config files alongside the canonical
opencode.json, without having to maintain a 4-site patch on every upstream sync. Concrete examples:acompany-develop/securecodecarries a 4-sitesecurecode.json/jsoncfallback patch today; would prefer to load that via env var (or a similar opt-in) so the fork'sconfig.tsstays byte-identical to upstream.team.jsonoveropencode.json.This is also a thin equivalent of the pattern already established by
OPENCODE_CONFIG_DIR— letting an env var widen the search surface without changing the default behavior.Proposed shape
Add a single env var
OPENCODE_EXTRA_CONFIG_NAMES(comma-separated):Default: empty (= no behavior change). Add a corresponding
Flag.OPENCODE_EXTRA_CONFIG_NAMES: string[]inpackages/core/src/flag/flag.tsnext toOPENCODE_CONFIG_DIR, and thread it through:ConfigPaths.files()— append extra names'.json/.jsonctargets to the up-walkglobalConfigFile()— append extra names' candidatesloadGlobal()— extend the merge cascade.opencodedir loop — extend the file listAll sites are simple
Array.prototype.flatMapover the name list. No order-of-precedence change for the default case (opencode.*always wins where it currently does); extra names merge later so they can override per existingmergeConfigsemantics.Why not a plugin hook?
Config loading runs before any plugins can register hooks (plugins are declared in the config file), so the file-name list has to be resolved at bootstrap. An env var is the cleanest bootstrap-level switch.
Willing to PR
If the maintainers are interested, happy to put up the PR (the diff is small, ~50 lines + tests). Filing this issue first per the issue-first policy in CONTRIBUTING.md.
Out of scope
opencode.*lookup