Skip to content

feature: allow extra config file names via OPENCODE_EXTRA_CONFIG_NAMES env var #26831

@yeighta

Description

@yeighta

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-424config.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:

  1. ConfigPaths.files() — append extra names' .json/.jsonc targets to the up-walk
  2. globalConfigFile() — append extra names' candidates
  3. loadGlobal() — extend the merge cascade
  4. Project .opencode dir loop — extend the file list
  5. 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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions