Skip to content

feat(cli): add ocx opencode launcher - #568

Merged
Wibias merged 6 commits into
devfrom
maintainer-takeover/461-feat-ocx-opencode
Jul 27, 2026
Merged

feat(cli): add ocx opencode launcher#568
Wibias merged 6 commits into
devfrom
maintainer-takeover/461-feat-ocx-opencode

Conversation

@Wibias

@Wibias Wibias commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Summary

Maintainer takeover of #461 — lands @mihneaptu's ocx opencode launcher with review fixes from the maintainer pass on #461.

  • Adds ocx opencode [args…]: ensure proxy, build provider.opencodex from the visible catalog, launch opencode with stdio inherited.
  • Credential safety: injects only the generated provider block through OpenCode's inline runtime layer (OPENCODE_CONFIG_CONTENT); never copies or rewrites the user's global/project config, so API keys, MCP credentials, and relative {file:…} paths stay on their original files.
  • Project override note: walks upward for opencode.json / opencode.jsonc to the nearest Git root and prints an informational message when provider.opencodex is also defined locally (runtime layer wins for this launch).
  • Docs: new guides/opencode.md plus sidebar entry.

Supersedes #461 (contributor fork could not be updated; maintainerCanModify=false).

Test plan

  • bun test tests/opencode-cli.test.ts — 30 pass
  • bun run typecheck
  • bun run privacy:scan
  • Cross-platform CI on this head (fresh matrix)

Summary by CodeRabbit

  • New Features
    • Added ocx opencode to launch OpenCode via the local proxy with a generated runtime provider configuration.
    • Routes models through the proxy, handles context/output limits, and supports secure API-key injection without modifying on-disk config.
  • Documentation
    • Added the new “opencode” guide and linked it in the Guides sidebar.
  • Bug Fixes
    • Fixed CLI command handling to properly apply the preceding config branch behavior.
  • Tests
    • Expanded coverage for opencode config generation/merging and routing/limits; adjusted concurrency timing assertions for policy updates.

opencode reads providers from a JSON config rather than env slots, so the
`ocx claude` env-injection pattern does not transfer. This adds a launcher that
generates a provider block from the proxy's visible catalog and points
OPENCODE_CONFIG at it.

The user's own opencode.json is never written to. Their effective config is read
(explicit OPENCODE_CONFIG first, then the XDG global path), merged forward into
a generated copy under the opencodex config dir, and only the `opencodex`
provider key is overwritten. Carrying the base config forward keeps the command
correct whether opencode merges the OPENCODE_CONFIG layer or replaces it, and
leaves plain `opencode` completely unchanged.

Credential handling: the generated file is written to disk and outlives the
child, so it carries opencode's documented `{env:VAR}` reference instead of the
admission key, and the real value is passed only through the child environment.
The key resolves OPENCODEX_API_AUTH_TOKEN before config.apiKeys, matching
fetchClaudeContextWindows — a non-loopback bind requires the env token and may
have no apiKeys at all, where a placeholder would 401 every request.

Model limits: limit.context is emitted only from an authoritative context
window, including native slugs via nativeOpenAiContextWindow. opencode's schema
rejects a limit block carrying context without output and CatalogModel has no
authoritative output field, so a documented budget rides along, clamped to the
context window so a small-context model is never emitted with output > context.

Robustness: opencode.json is parsed as JSONC (strict JSON first, tolerant only
on failure) because opencode documents that syntax and a commented config would
otherwise be rejected as malformed; the generated file is written atomically so
a concurrent launch cannot read a torn file; the detached proxy-start child gets
an error listener so a failed spawn reports through the health poll instead of
throwing; and a project-level opencode.json defining provider.opencodex is
detected and warned about, since opencode loads that layer last and it outranks
the generated block.

Verified against a live proxy: 76 models registered, 47 carrying authoritative
limits with no output > context violations, `opencode models opencodex` lists
all of them, and an end-to-end run through opencodex/kiro/claude-haiku-4.5
returns a completion.
@github-actions github-actions Bot added the enhancement New feature or request label Jul 27, 2026
@Wibias Wibias mentioned this pull request Jul 27, 2026
3 tasks
@coderabbitai

This comment was marked as outdated.

coderabbitai[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

Merge inherited OPENCODE_CONFIG_CONTENT instead of replacing it, probe the
live proxy hostname for baseURL, resolve admission from env/service token/
config keys, add x-opencodex-api-key on non-loopback binds, omit native slugs
in Codex Direct mode, and widen global override detection. Stabilize the
Windows storage-policy concurrency test timing.
coderabbitai[bot]

This comment was marked as resolved.

Wibias added 3 commits July 27, 2026 21:34
When ocx opencode spawns a detached ocx start and OPENCODEX_API_AUTH_TOKEN
is absent, propagate OCX_API_TOKEN_FILE (or the default hardened path) so
handleStart can load the service token before a non-loopback bind.
Use a deterministic loopback default config in provider-block helpers instead
of loadConfig(), send proxy admission via apiKey on loopback and only
x-opencodex-api-key on non-loopback binds, and split the docs/help examples
accordingly.
Fetch the live model list from the running proxy instead of calling fetchAllModels in the CLI process, so env-backed provider keys resolve in the proxy environment and namespaced selectors carry display metadata.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/opencode.ts`:
- Around line 353-361: Bound both the fetch and response body read in the
`/api/models` request flow around `fetchImpl` and `response.text()` so a stalled
management API cannot hang indefinitely. Use the existing request-timeout
mechanism or introduce a shared deadline that covers connection, response, and
body-reading phases, and preserve the current unreachable-error handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4a0f0db8-ad00-4774-a59c-75bf3fcc7eac

📥 Commits

Reviewing files that changed from the base of the PR and between 40f4b3f and 0713778.

📒 Files selected for processing (4)
  • docs-site/src/content/docs/guides/opencode.md
  • src/cli/help.ts
  • src/cli/opencode.ts
  • tests/opencode-cli.test.ts

Comment thread src/cli/opencode.ts Outdated
Abort stalled proxy catalog requests after 8s so ocx opencode fails fast instead of hanging before OpenCode launches.
@Wibias
Wibias merged commit f195e90 into dev Jul 27, 2026
12 checks passed
@lidge-jun
lidge-jun deleted the maintainer-takeover/461-feat-ocx-opencode branch July 29, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants