Skip to content

feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config isolation#263

Merged
marcusrbrown merged 1 commit intofeat/omo-config-updatesfrom
copilot/set-opencode-config-content
Feb 27, 2026
Merged

feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config isolation#263
marcusrbrown merged 1 commit intofeat/omo-config-updatesfrom
copilot/set-opencode-config-content

Conversation

Copy link
Contributor

Copilot AI commented Feb 26, 2026

OPENCODE_CONFIG_CONTENT is OpenCode's highest-precedence config source (position 6 in the precedence chain), making it the correct primitive for enforcing CI-safe defaults — unlike OPENCODE_CONFIG_DIR, which only adds a plugin search path and does not suppress ~/.config/opencode/opencode.json.

Changes

  • src/lib/setup/setup.ts: After oMo installation, exports OPENCODE_CONFIG_CONTENT with autoupdate: false as the CI baseline; user-supplied opencode-config input is spread on top so user values win on conflicting keys:

    const ciConfig: Record<string, unknown> = {
      autoupdate: false,
      ...(inputs.opencodeConfig != null ? (JSON.parse(inputs.opencodeConfig) as Record<string, unknown>) : {}),
    }
    core.exportVariable('OPENCODE_CONFIG_CONTENT', JSON.stringify(ciConfig))
  • src/lib/setup/setup.test.ts: Two new tests — baseline export (autoupdate: false with no user config) and user-config merge (user values override baseline on conflicting keys).

Tools cache strategy is unchanged — omoConfigPath = ~/.config/opencode remains stable.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh gh pr view 263 --repo fro-bot/agent --json baseRefName,headRefName (http block)
    • Triggering command: /usr/bin/gh gh pr edit 263 --repo fro-bot/agent --base feat/omo-config-updates (http block)
  • https://api.github.com/repos/fro-bot/agent/pulls/263
    • Triggering command: /usr/bin/curl curl -s -X PATCH -H Authorization: token ****** -H Accept: application/vnd.github.v3&#43;json REDACTED -d {&#34;base&#34;: &#34;feat/omo-config-updates&#34;} (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>feat(setup): isolate oMo/OpenCode config with OPENCODE_CONFIG_CONTENT</issue_title>
<issue_description>## 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
    </issue_description>

<agent_instructions>Target the PR to the feat/omo-config-updates branch (each of these setup features will be rolled up into this branch).</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@marcusrbrown @fro-bot research `OPENCODE_CONFIG_DI...

Custom agent used: Fro Bot
Specialized for fro-bot/agent: project-scoped coding agent that implements repo-specific features, fixes, and maintenance while following this repo's TDD, TypeScript/ESM, and CI/build conventions.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add OPENCODE_CONFIG_CONTENT as CI-safe environment variable feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config isolation Feb 26, 2026
Copilot AI requested a review from marcusrbrown February 26, 2026 20:55
@marcusrbrown marcusrbrown changed the base branch from main to feat/omo-config-updates February 26, 2026 21:06
Co-authored-by: marcusrbrown <831617+marcusrbrown@users.noreply.github.com>
@marcusrbrown marcusrbrown force-pushed the copilot/set-opencode-config-content branch from a66351a to 5ed00f4 Compare February 27, 2026 14:44
@marcusrbrown marcusrbrown marked this pull request as ready for review February 27, 2026 14:44
@marcusrbrown marcusrbrown merged commit aeb0679 into feat/omo-config-updates Feb 27, 2026
3 checks passed
@marcusrbrown marcusrbrown deleted the copilot/set-opencode-config-content branch February 27, 2026 14:45
marcusrbrown added a commit that referenced this pull request Mar 2, 2026
* chore: update the project banner

* feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config isolation (#263)

feat(setup): export OPENCODE_CONFIG_CONTENT for CI-safe OpenCode config

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* fix(setup): declare and validate opencode-config

* feat(setup): add --skip-auth flag to oMo installer for CI reliability (#260)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* feat(setup): add kimi-for-coding to oMo provider inputs (#268)

feat(setup): expose kimi-for-coding oMo CLI flag as action input

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* feat(setup): add `omo-config` action input for custom oMo configuration (#274)

feat(setup): add omo-config action input for custom oMo configuration

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>

* fix(inputs): add kimi-for-coding to input validation and types

Previously, kimi-for-coding was listed as a valid value in action.yaml and
handled in setup.ts's parseOmoProviders, but was absent from inputs.ts.

This caused users who set 'omo-providers: kimi-for-coding' to fail input
validation with:
  Invalid omo-providers value: "kimi-for-coding". Valid values: ...

Three files updated:
1. src/lib/inputs.ts: added 'kimi-for-coding' to VALID_OMO_PROVIDERS and
   parseOmoProviders function
2. src/lib/types.ts: added readonly kimiForCoding field to OmoProviders
3. src/lib/agent/opencode.test.ts: updated all OmoProviders test objects

Fixes PR #266 blocking issue; all 961 tests pass.

* fix(setup): harden opencode/omo config input parsing

- trim setup inputs and treat whitespace-only config values as not provided
- fail fast with explicit error when opencode-config is invalid JSON
- enforce opencode-config and omo-config as JSON objects (not null/array/primitive)
- harden oMo deep merge against prototype-pollution keys
- add regression tests for null/array/string/invalid JSON and whitespace handling
- document opencode-config input in README
- rebuild dist/main.js

---------

Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

2 participants