Skip to content

feat(setup): isolate oMo/OpenCode config with OPENCODE_CONFIG_CONTENT #239

@fro-bot

Description

@fro-bot

Summary

Set OPENCODE_CONFIG_CONTENT as a CI-safe environment variable during setup to enforce consistent, predictable OpenCode behavior across all runs — specifically preventing auto-updates and supporting user-supplied config overrides.

Motivation

OpenCode's config precedence order (from opencode.ai/docs/config/#precedence-order):

  1. Remote config (.well-known/opencode)
  2. Global config (~/.config/opencode/opencode.json)
  3. Custom config (OPENCODE_CONFIG env var)
  4. Project config (opencode.json in project)
  5. .opencode directories
  6. OPENCODE_CONFIG_CONTENT env var — highest priority

The original proposal used OPENCODE_CONFIG_DIR (per-run temp directory) for isolation. However, OPENCODE_CONFIG_DIR is not a config replacement — it adds an extra .opencode-style search path for agents/commands/plugins and does not prevent OpenCode from reading ~/.config/opencode/opencode.json. Additionally, per-run temp directories would break the tools cache (which keys on stable paths → guaranteed cache misses).

OPENCODE_CONFIG_CONTENT is the correct primitive. It has the highest precedence and reliably enforces CI-safe settings regardless of project or global config. This matches the pattern used by OCX, the established OpenCode CLI wrapper.

Implementation

File: src/lib/setup/setup.ts

In runSetup(), after oMo installation, export OPENCODE_CONFIG_CONTENT with CI-appropriate defaults:

// Build CI-safe OpenCode config (highest precedence — wins on all conflicting keys)
const ciConfig = {
  autoupdate: false,
  // Merge user-supplied opencode-config input on top
  ...(inputs.opencodeConfig != null ? JSON.parse(inputs.opencodeConfig) : {}),
}
core.exportVariable('OPENCODE_CONFIG_CONTENT', JSON.stringify(ciConfig))

The existing opencodeConfig field in SetupInputs (already parsed from the opencode-config input) provides user-supplied overrides — no new inputs required for the baseline case.

What NOT to Do

Do not use mkdtempSync() for OPENCODE_CONFIG_DIR:

  • Does not isolate ~/.config/opencode/opencode.json (still read at lower precedence)
  • oMo installer writes to ~/.config/opencode/ regardless of OPENCODE_CONFIG_DIR
  • Per-run paths break the tools cache (guaranteed cache misses)

If OPENCODE_CONFIG_DIR is ever used, it must point to a stable path (not a temp dir).

Considerations

  • Configs are merged, not replaced: OPENCODE_CONFIG_CONTENT only wins on conflicting keys. Non-conflicting project-level settings are preserved (e.g., a project's model choice is respected unless explicitly overridden).
  • OPENCODE_DISABLE_PROJECT_CONFIG: Future input for untrusted contexts (e.g., fork PRs). Off by default to preserve expected repo behavior.
  • Cache unchanged: omoConfigPath = ~/.config/opencode remains stable and continues to be cached as before. No tools cache changes needed.
  • OCX precedent: Matches the pattern used by OCX — the established OpenCode CLI wrapper.

Acceptance Criteria

  • OPENCODE_CONFIG_CONTENT exported in runSetup() with autoupdate: false as baseline
  • User-supplied opencode-config input merged on top of baseline
  • OPENCODE_CONFIG_DIR not set to a per-run temp directory
  • Tools cache strategy unchanged (stable omoConfigPath = ~/.config/opencode)
  • Tests updated to verify OPENCODE_CONFIG_CONTENT is exported with correct content
  • Build succeeds (pnpm build)
  • All tests pass (pnpm test)

Context

Identified in PR #236 as an improvement for CI reliability. Research conducted in issue comment — OPENCODE_CONFIG_DIR vs OPENCODE_CONFIG_CONTENT analyzed against official docs, OCX source, and reviewed by Oracle.

Scope

  • Effort: Small (1 env var export + test update, ~1–4h)
  • Risk: Low (OPENCODE_CONFIG_CONTENT only wins on conflicting keys; project configs otherwise preserved)
  • Dependencies: None

Metadata

Metadata

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions