opencode icon indicating copy to clipboard operation
opencode copied to clipboard

feat: Add OPENCODE_DISABLE_PROJECT_CONFIG for external tooling integration

Open kdcokenny opened this issue 5 days ago • 2 comments

Problem

I'm building OCX, a CLI extension for OpenCode that adds profile management. Profiles let users run OpenCode with different configurations depending on context—work vs personal, client A vs client B—without modifying the project's files.

To make this work today, OCX creates symlink farms: temporary directories that mirror the entire project via symlinks, excluding OpenCode's config files, then injecting the profile's config instead. OpenCode runs from this temp directory, thinking it's the real project.

This approach works, but it's fragile:

  • Complex cleanup — Orphaned temp directories from crashes need detection and removal
  • Windows issues — Symlinks require special permissions on Windows
  • Overhead — Creating hundreds of symlinks just to hide a few config files

The root cause: OpenCode always discovers configuration from the working directory. There's no way to tell it "I'm injecting config externally—ignore project files."

Proposed Solution

Add OPENCODE_DISABLE_PROJECT_CONFIG environment variable. When set to "true", OpenCode skips discovery of project-level configuration:

Disabled (project-level) Unaffected
opencode.jsonc, opencode.json in project ~/.config/opencode/ (global user config)
AGENTS.md, CLAUDE.md, CONTEXT.md in project ~/.local/share/opencode/ (session state)
.opencode/ directory (agents, skills, plugins, commands) OPENCODE_CONFIG_CONTENT (env var injection)
OPENCODE_CONFIG_DIR (env var injection)
OPENCODE_CONFIG (env var injection)

Global configuration and session state remain fully functional. Only project-level discovery is skipped, allowing external tools to inject configuration via the existing environment variable mechanisms.

Example Usage

OPENCODE_DISABLE_PROJECT_CONFIG=true \
OPENCODE_CONFIG_CONTENT='{"model":{"default":"anthropic/claude-sonnet-4-20250514"}}' \
OPENCODE_CONFIG_DIR=~/.config/opencode/profiles/work \
opencode

This runs OpenCode using the "work" profile's config and agents, completely ignoring any opencode.jsonc, AGENTS.md, or .opencode/ in the current project.

Implementation

Following the OPENCODE_DISABLE_CLAUDE_CODE pattern from PR #7205:

1. Define the flag (packages/opencode/src/flag/flag.ts):

export const OPENCODE_DISABLE_PROJECT_CONFIG = flag({
  key: "OPENCODE_DISABLE_PROJECT_CONFIG",
  description: "Disable discovery of project-level config, rules, and components",
})

2. Skip project config discovery (packages/opencode/src/config/config.ts):

In the read() function, check the flag before walking up directories for project config.

3. Skip project rule discovery (packages/opencode/src/file/system.ts):

Check the flag before discovering AGENTS.md, CLAUDE.md, CONTEXT.md in the project.

4. Skip project component loading (packages/opencode/src/app/app.ts):

Check the flag before loading agents, skills, plugins from <project>/.opencode/.

Benefits

  • Enables external tooling — Tools like OCX can inject config cleanly without filesystem hacks
  • Follows existing patterns — Same approach as OPENCODE_DISABLE_CLAUDE_CODE
  • Backwards compatible — Opt-in only, no change to default behavior
  • Minimal surface area — Single flag, conditional checks around existing discovery logic

Related

  • #7068 — Separating config directory from working directory (SDK context)
  • #6358 — Managed settings / enterprise config
  • #7205 — OPENCODE_DISABLE_CLAUDE_CODE pattern this follows

Happy to submit a PR if this approach works for you. Also open to discussing whether this should be a single flag or split into granular flags (e.g., separate flags for config vs rules vs components) if that's preferred.

kdcokenny avatar Jan 10 '26 02:01 kdcokenny