Skip to content

Add cmux launcher for oh-my-opencode-slim - #7712

Closed
guanbear wants to merge 5 commits into
manaflow-ai:mainfrom
guanbear:codex/omo-slim-cmux
Closed

guanbear wants to merge 5 commits into
manaflow-ai:mainfrom
guanbear:codex/omo-slim-cmux

Conversation

@guanbear

@guanbear guanbear commented Jul 9, 2026 •

Copy link
Copy Markdown

Summary

  • add cmux omo-slim and cmux omos as OpenCode launchers for oh-my-opencode-slim
  • reuse cmux's tmux compatibility shim so slim background-agent panes can appear as native cmux splits
  • configure a separate shadow OpenCode config with oh-my-opencode-slim, background subagents, and multiplexer.type = "tmux"
  • include restore/fork/trust aliases, command suggestions, task-manager detection, and localized CLI help for both names
  • keep the slim path isolated from full OMO plugins and user package pins, while preserving user slim JSON/JSONC config where possible
  • route slim terminal-notifier calls through cmux notify, matching the existing OMO integration

Verification

  • go test ./cmd/cmuxd-remote from daemon/remote
  • git diff --check
  • python3 -m json.tool Resources/Localizable.xcstrings
  • swiftc -parse on all modified Swift files

Not run

  • swift test for Packages/macOS/CMUXAgentLaunch because this machine's CommandLineTools SwiftPM manifest link fails with an undefined PackageDescription.Package symbol
  • ./scripts/reload.sh --tag omo-slim because this machine is missing zig (brew install zig)

Note

Medium Risk
Touches agent launch, shadow config/plugin install, and session restore/fork across local CLI, app UI, and remote daemon; misconfiguration could break OpenCode sessions or mix OMO vs slim plugins.

Overview
Adds cmux omo-slim and the omos alias to launch OpenCode with oh-my-opencode-slim in a cmux-aware setup: tmux shims route specialist panes to native splits, terminal-notifier goes through cmux notify, and OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS is enabled with a default port of 4097.

A dedicated shadow OpenCode config installs oh-my-opencode-slim, strips full OMO plugin entries, applies multiplexer.type = tmux (with layout defaults), and can read user JSONC slim config. Shared OMO install helpers are generalized (plugin name, manifest, JSON comment stripping).

Resume, fork, and trust paths treat omo, omo-slim, and omos as OpenCode session wrappers via AgentLaunchCaptureTrust.launcherIsOpenCodeSessionWrapper, so fork support skips direct OpenCode version probes. The same launchers are wired through agent detection, task manager, CLI suggestions, localization, and the remote cmuxd-remote relay (refactored runOpenCodeRelay for OMO vs slim).

Reviewed by Cursor Bugbot for commit a809253. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds omo-slim command and launcher support across the macOS CLI, agent launch handling, app detection, and the remote daemon relay, plus slim-specific shim, plugin, localization, and test updates.

Changes

omo-slim Launcher Support

Layer / File(s) Summary
CLI command registration, dispatch, and usage text
CLI/CMUXCLI+CommandSuggestions.swift, CLI/CMUXCLI+SessionsListForkDiagnostics.swift, CLI/cmux.swift, Resources/Localizable.xcstrings
Registers omo-slim, updates dispatch and fork diagnostics, and adds localized usage text.
omo-slim shim, plugin bootstrap, and launch flow
CLI/cmux.swift
Adds slim shim creation, shadow config and manifest helpers, slim plugin bootstrap, environment setup, and runOMOSlim.
Agent launch argv resolution and trust matching for omo-slim
Packages/macOS/CMUXAgentLaunch/Sources/..., Packages/macOS/CMUXAgentLaunch/Tests/*
Extends fork/resume argv handling, sanitization, trust aliases, and tests for omo-slim.
App-level detection, fork support, and task registration for omo-slim
Sources/AgentForkSupport.swift, Sources/ContentView.swift, Sources/RestorableAgentSession.swift, Sources/TaskManagerTypes.swift, Sources/TextBoxAgentDetection.swift
Updates fork support, probe selection, built-in agent metadata, and identity aliases to include omo-slim.
Remote daemon relay and plugin setup for omo-slim
daemon/remote/cmd/cmuxd-remote/agent_launch.go, cli.go, agent_launch_test.go
Adds relay routing, slim shim infrastructure, generalized plugin setup, slim plugin configuration, CLI wiring, and tests.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • manaflow-ai/cmux#7139: Both PRs modify the daemon/remote/cmd/cmuxd-remote/cli.go relay dispatch path used by runCLI.
  • manaflow-ai/cmux#7329: Both PRs touch CMUXCLI+CommandSuggestions.swift by extending the top-level command suggestion set.

Suggested reviewers: lawrencecchen

🚥 Pre-merge checks | ✅ 4 | ❌ 21

❌ Failed checks (1 warning, 20 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift Actor Isolation ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift Blocking Runtime ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Browser Automation Off-Main ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Expensive Synchronous Load ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Cache Substitution Correctness ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux No Hacky Sleeps ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Algorithmic Complexity ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift Concurrency ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift @Concurrent ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift File And Package Boundaries ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swiftpm Lockfiles ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift Logging ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux User-Facing Error Privacy ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Full Internationalization ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swiftui State Layout ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Architecture Rethink ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Swift Auxiliary Window Close Shortcuts ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux Source Artifacts ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux No Test Or Debug Seam In Production Source ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
Cmux No Ambient Global State ❓ Inconclusive Repository clone failed, so this custom check could not run with code access. Retry the review run. If this persists, inspect pre-merge custom-check logs for infrastructure or agent runtime failures.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: adding a new cmux launcher for oh-my-opencode-slim.
Description check ✅ Passed The description is mostly complete with summary, verification, and risk details, but it omits the demo video, review trigger block, and checklist.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 9, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces cmux omo-slim (alias omos) as a new OpenCode launcher that activates the oh-my-opencode-slim plugin with a dedicated shadow config, tmux compatibility shim, terminal-notifier routing through cmux notify, and background subagent support on port 4097. It also refactors all "omo" launcher checks across Swift and Go into the shared AgentLaunchCaptureTrust.launcherIsOpenCodeSessionWrapper() predicate, covering fork, resume, trust, task-manager detection, and session diagnostics.

  • Adds runOMOSlim in Swift and runOMOSlimRelay/runOpenCodeRelay in Go; refactors runOMORelay into the generic helper and adds a dedicated remote session bridge plugin (opencode_session_plugin.go) for slim-mode lifecycle events.
  • Generalises shadow config helpers (omoEnsureShadowPackageManifest, install messages) to accept plugin name/manifest parameters, and adds a custom JSONC comment stripper for reading user slim config.
  • Two new localized keys (cli.omoSlim.installFailed, cli.omoSlim.noPackageManager) are referenced in production Swift but absent from Localizable.xcstrings, leaving non-English users with English fallback on plugin installation errors.

Confidence Score: 4/5

Safe to merge after adding the two missing xcstrings catalog entries; the core launch, shadow config, shim, and session relay logic is well-structured and covered by tests.

The only defect found is that cli.omoSlim.installFailed and cli.omoSlim.noPackageManager are referenced in production Swift but have no entries in Localizable.xcstrings, so every non-English user gets raw English text during plugin installation failures. Everything else — shadow config isolation, JSONC stripping, tmux shim creation, port arbitration, fork/resume/trust wiring, and the remote relay refactor — looks correct and is exercised by the new Go and Swift test suite additions.

Resources/Localizable.xcstrings and CLI/cmux.swift (the two missing localized key registrations)

Important Files Changed

Filename Overview
CLI/cmux.swift Adds runOMOSlim + helper functions (shim dir, shadow config, env wiring); two new localized keys referenced here are absent from Localizable.xcstrings
Resources/Localizable.xcstrings Adds cli.omoSlim.usage with en/ja/ko/uk translations; cli.omoSlim.installFailed and cli.omoSlim.noPackageManager are missing entirely
Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift Adds launcherIsOpenCodeSessionWrapper() and expands wrapperLaunchersByKind/validLaunchersByKind sets; clean, well-tested addition
daemon/remote/cmd/cmuxd-remote/agent_launch.go Refactors runOMORelay into generic runOpenCodeRelay, adds runOMOSlimRelay, helper shim/plugin setup, and port-resolution helpers; well-covered by tests
daemon/remote/cmd/cmuxd-remote/opencode_session_plugin.go New file that writes the remote OpenCode session bridge plugin; atomic write pattern and idempotent content check are correct
daemon/remote/cmd/cmuxd-remote/agent_launch_test.go Good coverage: path-safety test, multiplexer defaults, JSONC config reading, port resolution variants all tested

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User
    participant cmux CLI
    participant runOMOSlim
    participant omoSlimEnsurePlugin
    participant shimDir as createOMOSlimShimDirectory
    participant opencode

    User->>cmux CLI: cmux omo-slim [args]
    cmux CLI->>runOMOSlim: dispatch
    runOMOSlim->>runOMOSlim: resolve opencode executable
    runOMOSlim->>omoSlimEnsurePlugin: set up shadow config + install plugin
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: write shadow opencode.json (strip OMO, add slim)
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: symlink user slim JSONC config
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: "configure multiplexer.type=tmux in slim config"
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: "setenv OPENCODE_CONFIG_DIR=shadow"
    runOMOSlim->>shimDir: create tmux + terminal-notifier shims
    runOMOSlim->>runOMOSlim: configureOMOSlimEnvironment (CMUX_OMO_SLIM_CMUX_BIN, OPENCODE_PORT, OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS)
    runOMOSlim->>opencode: execv with --port arg prepended
    opencode-->>User: launches with oh-my-opencode-slim plugin active
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User
    participant cmux CLI
    participant runOMOSlim
    participant omoSlimEnsurePlugin
    participant shimDir as createOMOSlimShimDirectory
    participant opencode

    User->>cmux CLI: cmux omo-slim [args]
    cmux CLI->>runOMOSlim: dispatch
    runOMOSlim->>runOMOSlim: resolve opencode executable
    runOMOSlim->>omoSlimEnsurePlugin: set up shadow config + install plugin
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: write shadow opencode.json (strip OMO, add slim)
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: symlink user slim JSONC config
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: "configure multiplexer.type=tmux in slim config"
    omoSlimEnsurePlugin->>omoSlimEnsurePlugin: "setenv OPENCODE_CONFIG_DIR=shadow"
    runOMOSlim->>shimDir: create tmux + terminal-notifier shims
    runOMOSlim->>runOMOSlim: configureOMOSlimEnvironment (CMUX_OMO_SLIM_CMUX_BIN, OPENCODE_PORT, OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS)
    runOMOSlim->>opencode: execv with --port arg prepended
    opencode-->>User: launches with oh-my-opencode-slim plugin active
Loading

Reviews (7): Last reviewed commit: "Merge latest main into omo-slim launcher..." | Re-trigger Greptile

Comment on lines +40225 to +40241
"cli.omoSlim.usage": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Usage: cmux omo-slim [opencode-args...]\n\nLaunch OpenCode with oh-my-opencode-slim in a cmux-aware environment.\n\noh-my-opencode-slim coordinates background specialist agents. This\ncommand sets up a tmux shim so those agent panes become native cmux\nsplits with sidebar metadata and notifications.\n\nThis command:\n - sets a tmux-like environment so oh-my-opencode-slim uses cmux splits\n - prepends a private tmux shim to PATH\n - forwards all remaining arguments to opencode\n\nExamples:\n cmux omo-slim\n cmux omo-slim --continue\n cmux omo-slim --model zhipu/glm-5.2"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "使い方: cmux omo-slim [opencode-args...]\n\ncmux 対応の環境で OpenCode と oh-my-opencode-slim を起動します。\n\noh-my-opencode-slim はバックグラウンドの専門エージェントを調整します。\nこのコマンドは tmux shim を設定し、それらのエージェントペインを\nサイドバーのメタデータと通知を備えたネイティブの cmux split に変換します。\n\nこのコマンドは次を行います:\n - oh-my-opencode-slim が cmux の split を使うよう tmux 風の環境を設定\n - 専用の tmux shim を PATH の先頭に追加\n - 残りの引数をそのまま opencode に渡す\n\n例:\n cmux omo-slim\n cmux omo-slim --continue\n cmux omo-slim --model zhipu/glm-5.2"
}
}
}
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Missing locale translations in cli.omoSlim.usage

cli.omoSlim.usage is translated into only en and ja, but the immediately adjacent peer key cli.omo.usage also supplies ko and uk entries. The catalog already supports those locales for this type of CLI usage string, so the new key should include all four. Korean and Ukrainian users running cmux omo-slim --help will see the untranslated English fallback instead of their expected locale.

Rule Used: Flag production user-facing text that is not fully... (source)

Comment thread CLI/cmux.swift
Comment on lines +22425 to +22443
private func omoSlimEnsurePlugin(processEnvironment: [String: String]) throws {
let userDir = omoUserConfigDir()
let shadowDir = omoSlimShadowConfigDir()
let fm = FileManager.default

try fm.createDirectory(at: shadowDir, withIntermediateDirectories: true, attributes: nil)

let userJsonURL = userDir.appendingPathComponent("opencode.json")
let shadowJsonURL = shadowDir.appendingPathComponent("opencode.json")

var config: [String: Any]
if let data = try? Data(contentsOf: userJsonURL) {
guard let existing = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
throw CLIError(message: "Failed to parse \(userJsonURL.path). Fix the JSON syntax and retry.")
}
config = existing
} else {
config = [:]
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Error message exposes internal config file path

userJsonURL.path expands to the full home-directory path (e.g. /Users/alice/.config/opencode/opencode.json), leaking it in a user-facing error. The Go counterpart's test TestOmoEnsurePluginInvalidJSONErrorDoesNotExposeUserPath was written specifically to prevent this — the Swift omo-slim path should follow the same principle.

Suggested change
private func omoSlimEnsurePlugin(processEnvironment: [String: String]) throws {
let userDir = omoUserConfigDir()
let shadowDir = omoSlimShadowConfigDir()
let fm = FileManager.default
try fm.createDirectory(at: shadowDir, withIntermediateDirectories: true, attributes: nil)
let userJsonURL = userDir.appendingPathComponent("opencode.json")
let shadowJsonURL = shadowDir.appendingPathComponent("opencode.json")
var config: [String: Any]
if let data = try? Data(contentsOf: userJsonURL) {
guard let existing = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
throw CLIError(message: "Failed to parse \(userJsonURL.path). Fix the JSON syntax and retry.")
}
config = existing
} else {
config = [:]
}
private func omoSlimEnsurePlugin(processEnvironment: [String: String]) throws {
let userDir = omoUserConfigDir()
let shadowDir = omoSlimShadowConfigDir()
let fm = FileManager.default
try fm.createDirectory(at: shadowDir, withIntermediateDirectories: true, attributes: nil)
let userJsonURL = userDir.appendingPathComponent("opencode.json")
let shadowJsonURL = shadowDir.appendingPathComponent("opencode.json")
var config: [String: Any]
if let data = try? Data(contentsOf: userJsonURL) {
guard let existing = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
throw CLIError(message: "Failed to parse opencode.json in the opencode config directory. Fix the JSON syntax and retry.")
}
config = existing
} else {
config = [:]
}

Comment on lines +283 to +291
case "omo", "omo-slim":
let parts = commandParts(executablePath: executablePath, arguments: arguments, fallbackExecutable: "cmux")
var tail = parts.tail
let command = launcher ?? "omo"
if tail.first == command { tail.removeFirst() }
guard let preserved = AgentLaunchSanitizer.preservedArguments(kind: "opencode", args: tail) else {
return .resolved(nil)
}
return .resolved([parts.executable, command, "--session", sessionId] + preserved)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Mixed indentation: tabs inside a spaces-indented file

The new "omo", "omo-slim" case arm (lines 283–291) uses hard tabs, while the rest of AgentResumeArgv.swift and the adjacent "omx", "omc" arm use spaces. This will render oddly in editors and diffs, and may cause a swiftformat / linter failure in CI.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go
Comment thread CLI/cmux.swift

@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: 2

🤖 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 `@daemon/remote/cmd/cmuxd-remote/agent_launch.go`:
- Around line 135-197: runOMOSlimRelay duplicates nearly all of runOMORelay, so
move the shared relay flow into a common helper and parameterize the few
differences to prevent drift. Keep the existing unique pieces configurable via
args like tmuxPathPrefix, cmuxBinEnvVar, termEnvVar, extraEnv, the plugin setup
function, and the error-message prefix, and reuse the same port-handling logic
from the relay helper instead of copying it. Update runOMOSlimRelay to delegate
to the shared helper while preserving its current opencode/plugin behavior.

In `@Sources/ContentView.swift`:
- Around line 5592-5594: Parenthesize the boolean group in the ternary within
the snapshot launcher support check so the condition is clearly treated as one
expression before the `?` branch. Update the logic around the
`snapshot.launchCommand?.launcher` comparisons and `isRemoteTerminal` in
`ContentView` to match the intended grouping used by
`AgentForkSupport.supportsFork`, improving readability and reducing the chance
of future edits changing the ternary binding.
🪄 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

Run ID: 6677be95-16e0-49b5-8c0c-ac365b79e03f

📥 Commits

Reviewing files that changed from the base of the PR and between a1c5295 and 7c82bab.

📒 Files selected for processing (19)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+SessionsListForkDiagnostics.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentForkArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentForkArgvTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentForkSupport.swift
  • Sources/ContentView.swift
  • Sources/RestorableAgentSession.swift
  • Sources/TaskManagerTypes.swift
  • Sources/TextBoxAgentDetection.swift
  • daemon/remote/cmd/cmuxd-remote/agent_launch.go
  • daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
  • daemon/remote/cmd/cmuxd-remote/cli.go

Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go
Comment thread Sources/ContentView.swift Outdated
@guanbear
guanbear force-pushed the codex/omo-slim-cmux branch from 7c82bab to acbc7b2 Compare July 9, 2026 08:08

@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: 2

🤖 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 `@daemon/remote/cmd/cmuxd-remote/agent_launch.go`:
- Around line 172-174: The default OPENCODE_PORT initialization in
agent_launch.go currently hardcodes the same port for both relays, so update the
startup path in the relevant launch logic to avoid sharing 4096 between omo and
omo-slim. Adjust the code around the OPENCODE_PORT environment setup in the
agent launch flow so omo-slim uses a distinct default port or an ephemeral
fallback, while preserving the existing behavior for omo. Use the surrounding
symbols in this file that perform relay startup and env setup to locate the
right place.

In `@Sources/AgentForkSupport.swift`:
- Around line 303-305: The omo-family launcher check is duplicated with
hardcoded string literals, which creates multiple sources of truth for the same
launcher set. Update the `snapshot.launchCommand?.launcher` check in
`AgentForkSupport` to use the canonical launcher-kind helper from
`AgentLaunchCaptureTrust` (for example, `launcherDescribesKind(..., kind:
"opencode")`) or another shared accessor instead of repeating `"omo"`,
`"omo-slim"`, and `"omos"`. Make the same shared-source change at the other call
sites so all fork-support logic relies on `wrapperLaunchersByKind` /
`nativeProcessAliasesByKind` rather than local lists.
🪄 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

Run ID: 02faba01-699e-45a6-9a4d-3f30f138549c

📥 Commits

Reviewing files that changed from the base of the PR and between 7c82bab and acbc7b2.

📒 Files selected for processing (19)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+SessionsListForkDiagnostics.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentForkArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentForkArgvTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentForkSupport.swift
  • Sources/ContentView.swift
  • Sources/RestorableAgentSession.swift
  • Sources/TaskManagerTypes.swift
  • Sources/TextBoxAgentDetection.swift
  • daemon/remote/cmd/cmuxd-remote/agent_launch.go
  • daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
  • daemon/remote/cmd/cmuxd-remote/cli.go

Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go Outdated
Comment thread Sources/AgentForkSupport.swift Outdated
@guanbear
guanbear force-pushed the codex/omo-slim-cmux branch 2 times, most recently from 00521f8 to 30a17b3 Compare July 9, 2026 08:21
Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift
Comment on lines +22729 to +22740
guard let openCodeExecutablePath = resolveOpenCodeExecutable(searchPath: launcherEnvironment["PATH"]) else {
throw CLIError(message: missingProviderExecutableMessage(
displayName: "OpenCode",
executableName: "opencode"
))
}
launcherEnvironment["PATH"] = providerExecutableSearchPath(
searchPath: launcherEnvironment["PATH"],
includingExecutableAt: openCodeExecutablePath
)

try omoSlimEnsurePlugin(processEnvironment: launcherEnvironment)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 This is inconsistent with the fix applied to runOMO in this same PR. runOMO was changed to the generic "Required agent executable not found. Install the agent CLI and retry." precisely to avoid exposing the upstream vendor name ("OpenCode") and executable name ("opencode") in a user-visible error. runOMOSlim uses the old missingProviderExecutableMessage path, so this error still leaks implementation details to the user.

Suggested change
guard let openCodeExecutablePath = resolveOpenCodeExecutable(searchPath: launcherEnvironment["PATH"]) else {
throw CLIError(message: missingProviderExecutableMessage(
displayName: "OpenCode",
executableName: "opencode"
))
}
launcherEnvironment["PATH"] = providerExecutableSearchPath(
searchPath: launcherEnvironment["PATH"],
includingExecutableAt: openCodeExecutablePath
)
try omoSlimEnsurePlugin(processEnvironment: launcherEnvironment)
guard let openCodeExecutablePath = resolveOpenCodeExecutable(searchPath: launcherEnvironment["PATH"]) else {
throw CLIError(message: "Required agent executable not found. Install the agent CLI and retry.")
}
launcherEnvironment["PATH"] = providerExecutableSearchPath(
searchPath: launcherEnvironment["PATH"],
includingExecutableAt: openCodeExecutablePath
)
try omoSlimEnsurePlugin(processEnvironment: launcherEnvironment)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/RestorableAgentSession.swift (1)

432-444: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fourth hardcoded copy of the omo-family launcher list.

openCodeVersionProbe now independently lists "omo", "omo-slim", "omos" to skip the version probe, mirroring the same set already owned by AgentLaunchCaptureTrust.wrapperLaunchersByKind["opencode"]. As per path instructions ("flag... more than one disagreeing source of truth for the same fact"), consider checking AgentLaunchCaptureTrust.launcherDescribesKind(launchCommand?.launcher, kind: "opencode") here as well so all four call sites (this one, AgentForkSupport.swift, ContentView.swift, and the CLI diagnostics file) stay in sync automatically.

🤖 Prompt for 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.

In `@Sources/RestorableAgentSession.swift` around lines 432 - 444,
openCodeVersionProbe currently hardcodes the omo-family launcher names, creating
a duplicate source of truth for the opencode launcher set. Update this switch to
rely on AgentLaunchCaptureTrust.launcherDescribesKind(launchCommand?.launcher,
kind: "opencode") instead of matching "omo", "omo-slim", and "omos" directly, so
the version-probe skip logic stays aligned with the existing
wrapperLaunchersByKind definition and the other call sites remain in sync.

Source: Path instructions

🤖 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 `@CLI/CMUXCLI`+SessionsListForkDiagnostics.swift:
- Line 367: The omo-family launcher check is duplicated across multiple places
and should use one shared source of truth. Extract the launcher aliases into a
shared Set<String> constant such as OMOFamilyLaunchers, then update the
launchCommand checks in CMUXCLI+SessionsListForkDiagnostics and the related
identity checks in AgentForkSupport and RestorableAgentSession to use that
constant instead of repeated string comparisons. Keep the behavior identical
while centralizing the launcher detection logic.

---

Outside diff comments:
In `@Sources/RestorableAgentSession.swift`:
- Around line 432-444: openCodeVersionProbe currently hardcodes the omo-family
launcher names, creating a duplicate source of truth for the opencode launcher
set. Update this switch to rely on
AgentLaunchCaptureTrust.launcherDescribesKind(launchCommand?.launcher, kind:
"opencode") instead of matching "omo", "omo-slim", and "omos" directly, so the
version-probe skip logic stays aligned with the existing wrapperLaunchersByKind
definition and the other call sites remain in sync.
🪄 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

Run ID: ac462bec-dd32-4a89-9698-2e2241ec063a

📥 Commits

Reviewing files that changed from the base of the PR and between acbc7b2 and 00521f8.

📒 Files selected for processing (19)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+SessionsListForkDiagnostics.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentForkArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentForkArgvTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentForkSupport.swift
  • Sources/ContentView.swift
  • Sources/RestorableAgentSession.swift
  • Sources/TaskManagerTypes.swift
  • Sources/TextBoxAgentDetection.swift
  • daemon/remote/cmd/cmuxd-remote/agent_launch.go
  • daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
  • daemon/remote/cmd/cmuxd-remote/cli.go

return (true, "available")
}
if launchCommand?.launcher == "omo" {
if launchCommand?.launcher == "omo" || launchCommand?.launcher == "omo-slim" || launchCommand?.launcher == "omos" {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider extracting the omo-family launcher set into a shared constant.

The launcher == "omo" || launcher == "omo-slim" || launcher == "omos" pattern is now duplicated across at least AgentForkSupport.swift, RestorableAgentSession.swift, and this file. A single shared Set<String> constant (e.g., OMOFamilyLaunchers) would serve as the authoritative source and prevent future drift when a new alias is added to one location but not all.

As per coding guidelines, the same behavior should not be wired separately through multiple surfaces instead of one shared path. As per path instructions, correctness-critical identity detection should use a reliable, structured source of truth rather than scattered heuristics.

♻️ Suggested shared constant
// In a shared location, e.g. CMUXAgentLaunch or a common constants file:
static let omoFamilyLaunchers: Set<String> = ["omo", "omo-slim", "omos"]

// Then at each call site:
- if launchCommand?.launcher == "omo" || launchCommand?.launcher == "omo-slim" || launchCommand?.launcher == "omos" {
+ if let launcher = launchCommand?.launcher, Self.omoFamilyLaunchers.contains(launcher) {
    return (true, "available")
  }
🤖 Prompt for 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.

In `@CLI/CMUXCLI`+SessionsListForkDiagnostics.swift at line 367, The omo-family
launcher check is duplicated across multiple places and should use one shared
source of truth. Extract the launcher aliases into a shared Set<String> constant
such as OMOFamilyLaunchers, then update the launchCommand checks in
CMUXCLI+SessionsListForkDiagnostics and the related identity checks in
AgentForkSupport and RestorableAgentSession to use that constant instead of
repeated string comparisons. Keep the behavior identical while centralizing the
launcher detection logic.

Sources: Coding guidelines, Path instructions

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Sources/RestorableAgentSession.swift (1)

432-444: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider routing through the canonical launcher-kind helper here too.

This switch adds "omo-slim" to a fourth independent enumeration of the omo/omo-slim/omos triplet (alongside AgentForkSupport.swift, ContentView.swift, and CLI/CMUXCLI+SessionsListForkDiagnostics.swift). The behavior is correct, but centralizing via AgentLaunchCaptureTrust's launcher-kind helper would prevent a future omo variant from being missed in one of these spots.

Based on path instructions ("Apply .github/review-bot-rules/reliability-single-source-of-truth.md... flag... more than one disagreeing source of truth for the same fact").

🤖 Prompt for 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.

In `@Sources/RestorableAgentSession.swift` around lines 432 - 444, The launcher
check in openCodeVersionProbe is duplicating the omo/omo-slim/omos
classification and can drift from the other call sites. Update this switch to
route through AgentLaunchCaptureTrust’s canonical launcher-kind helper instead
of matching launcher strings directly, and keep the existing nil behavior for
the omo family and omx/omc while letting the helper be the single source of
truth.

Source: Path instructions

♻️ Duplicate comments (1)
CLI/CMUXCLI+SessionsListForkDiagnostics.swift (1)

367-367: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Duplicate concern: omo-family launcher set should be shared.

This was already flagged in a prior review comment (c9acb673). The launcher == "omo" || launcher == "omo-slim" || launcher == "omos" pattern remains duplicated across AgentForkSupport.swift, RestorableAgentSession.swift, and this file. Extracting a shared Set<String> constant would prevent future drift when a new alias is added to one location but not all.

As per coding guidelines, the same behavior should not be wired separately through multiple surfaces instead of one shared path. As per path instructions, correctness-critical identity detection should use a reliable, structured source of truth rather than scattered heuristics.

🤖 Prompt for 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.

In `@CLI/CMUXCLI`+SessionsListForkDiagnostics.swift at line 367, The omo-family
launcher check is duplicated across multiple places and should be centralized
into one shared source of truth. Replace the repeated `launcher == "omo" ||
launcher == "omo-slim" || launcher == "omos"` logic with a shared `Set<String>`
constant or helper used by `AgentForkSupport`, `RestorableAgentSession`, and
`CMUXCLI+SessionsListForkDiagnostics` so all identity checks stay consistent and
future aliases only need to be updated once.

Sources: Coding guidelines, Path instructions, Learnings

🤖 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 `@daemon/remote/cmd/cmuxd-remote/agent_launch_test.go`:
- Around line 65-84: The test
TestOmoSlimEnsurePluginConfiguresShadowTmuxMultiplexer mutates the process
environment by calling omoSlimEnsurePlugin and then asserting
OPENCODE_CONFIG_DIR, so it can leak state into later tests. Update the test to
register and restore OPENCODE_CONFIG_DIR with t.Setenv before invoking
omoSlimEnsurePlugin, using the same shadow directory from omoSlimShadowConfigDir
to keep the environment isolated for the rest of the package tests.

In `@daemon/remote/cmd/cmuxd-remote/agent_launch.go`:
- Around line 891-897: configureOMOSlimPlugin currently ignores failures when
replacing the symlink, marshaling slimConfig, or writing the slim JSON, so make
those operations return errors instead of being silently skipped. In the
needsWrite block, handle the Readlink/Remove path carefully, capture and
propagate any json.MarshalIndent and os.WriteFile errors, and ensure the
function returns a failure when updating oh-my-opencode-slim.json does not
complete successfully. Use the existing configureOMOSlimPlugin flow and
configPath/muxConfig handling to locate the fix.
- Around line 145-153: The OPENCODE_PORT setup in agent_launch.go is using the
default port even when openCodeRelayLaunchArgs preserves an explicit --port
value. Update the launch flow around openCodeRelayLaunchArgs and
resolveNodeScriptExec to derive the effective port from the passed args first
(including both --port and --port= forms), then fall back to the existing
OPENCODE_PORT env var, and only then to openCodeRelayDefaultPort so the
environment matches the launched process.

---

Outside diff comments:
In `@Sources/RestorableAgentSession.swift`:
- Around line 432-444: The launcher check in openCodeVersionProbe is duplicating
the omo/omo-slim/omos classification and can drift from the other call sites.
Update this switch to route through AgentLaunchCaptureTrust’s canonical
launcher-kind helper instead of matching launcher strings directly, and keep the
existing nil behavior for the omo family and omx/omc while letting the helper be
the single source of truth.

---

Duplicate comments:
In `@CLI/CMUXCLI`+SessionsListForkDiagnostics.swift:
- Line 367: The omo-family launcher check is duplicated across multiple places
and should be centralized into one shared source of truth. Replace the repeated
`launcher == "omo" || launcher == "omo-slim" || launcher == "omos"` logic with a
shared `Set<String>` constant or helper used by `AgentForkSupport`,
`RestorableAgentSession`, and `CMUXCLI+SessionsListForkDiagnostics` so all
identity checks stay consistent and future aliases only need to be updated once.
🪄 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

Run ID: 02062a05-d25c-49d8-ac11-2e45caf0fcb3

📥 Commits

Reviewing files that changed from the base of the PR and between 00521f8 and 30a17b3.

📒 Files selected for processing (19)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+SessionsListForkDiagnostics.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentForkArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentForkArgvTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentForkSupport.swift
  • Sources/ContentView.swift
  • Sources/RestorableAgentSession.swift
  • Sources/TaskManagerTypes.swift
  • Sources/TextBoxAgentDetection.swift
  • daemon/remote/cmd/cmuxd-remote/agent_launch.go
  • daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
  • daemon/remote/cmd/cmuxd-remote/cli.go

Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go Outdated
Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go Outdated
@guanbear
guanbear force-pushed the codex/omo-slim-cmux branch from 30a17b3 to c60b081 Compare July 9, 2026 08:40
Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go
@guanbear
guanbear force-pushed the codex/omo-slim-cmux branch from c60b081 to c300f6d Compare July 9, 2026 08:44
Comment thread CLI/cmux.swift
Comment thread daemon/remote/cmd/cmuxd-remote/agent_launch.go

@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: 3

♻️ Duplicate comments (3)
daemon/remote/cmd/cmuxd-remote/agent_launch.go (2)

145-153: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

OPENCODE_PORT still diverges from an explicit --port.

When the user passes --port 5010 with OPENCODE_PORT unset, Line 147 exports the variant default (e.g. 4097) while openCodeRelayLaunchArgs preserves 5010, so plugin/background code reads a different port than the launched OpenCode process. Derive the effective port from args first, then the env var, then the default.

🤖 Prompt for 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.

In `@daemon/remote/cmd/cmuxd-remote/agent_launch.go` around lines 145 - 153, The
port selection in agent_launch.go is inconsistent because OPENCODE_PORT is being
set from cfg.defaultPort before the explicit --port value is considered, while
openCodeRelayLaunchArgs uses the user-provided port. Update the launch flow in
the agent launch path so the effective port is resolved from args first, then
the existing OPENCODE_PORT, then the default, and use that same resolved value
both for setting OPENCODE_PORT and for building launchArgs via
openCodeRelayLaunchArgs so the relay and launched process stay in sync.

891-897: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Propagate slim config write failures.

configureOMOSlimPlugin still ignores errors from os.Remove, json.MarshalIndent, and os.WriteFile, so it can report success while leaving oh-my-opencode-slim.json without the required multiplexer.type = "tmux" config.

🛡️ Proposed fix
 	if needsWrite {
 		slimConfig["multiplexer"] = muxConfig
 		if target, err := os.Readlink(configPath); err == nil && target != "" {
-			os.Remove(configPath)
+			if err := os.Remove(configPath); err != nil {
+				return fmt.Errorf("replace symlinked omo-slim config: %w", err)
+			}
 		}
-		data, _ := json.MarshalIndent(slimConfig, "", "  ")
-		os.WriteFile(configPath, data, 0644)
+		data, err := json.MarshalIndent(slimConfig, "", "  ")
+		if err != nil {
+			return fmt.Errorf("marshal omo-slim config: %w", err)
+		}
+		if err := os.WriteFile(configPath, data, 0644); err != nil {
+			return fmt.Errorf("write omo-slim config: %w", err)
+		}
 	}
🤖 Prompt for 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.

In `@daemon/remote/cmd/cmuxd-remote/agent_launch.go` around lines 891 - 897, The
configureOMOSlimPlugin flow is swallowing failures from os.Remove,
json.MarshalIndent, and os.WriteFile, so update the needsWrite branch to handle
and return these errors instead of ignoring them. Use the existing configPath,
slimConfig, and muxConfig logic in configureOMOSlimPlugin, and make sure any
failure while removing the old file, marshaling the updated config, or writing
oh-my-opencode-slim.json is propagated back to the caller so the tmux
multiplexer setting is not reported as applied unless it was actually persisted.
daemon/remote/cmd/cmuxd-remote/agent_launch_test.go (1)

65-119: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Restore OPENCODE_CONFIG_DIR after this test.

omoSlimEnsurePlugin mutates the process env via os.Setenv("OPENCODE_CONFIG_DIR", ...), so this test can leak that value into later package tests. Register it with t.Setenv("OPENCODE_CONFIG_DIR", "") before invoking the helper so it is restored on cleanup.

🤖 Prompt for 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.

In `@daemon/remote/cmd/cmuxd-remote/agent_launch_test.go` around lines 65 - 119,
This test leaks the OPENCODE_CONFIG_DIR process environment because
omoSlimEnsurePlugin sets it internally and it is never restored. In
TestOmoSlimEnsurePluginConfiguresShadowTmuxMultiplexer, register
OPENCODE_CONFIG_DIR with t.Setenv before calling omoSlimEnsurePlugin so cleanup
resets it automatically, keeping later tests isolated; use the existing
omoSlimEnsurePlugin and omoSlimShadowConfigDir symbols to locate the setup.
🤖 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 `@CLI/cmux.swift`:
- Around line 22449-22456: The parse-failure message in the config-loading
branch is inconsistent with the genericized `omoEnsurePlugin` message because it
still interpolates `userJsonURL.path`. Update the `JSONSerialization` failure
path in this config parsing logic to match the same generic `"Failed to parse
launcher config. Fix the JSON syntax and retry."` wording used by
`omoEnsurePlugin`, keeping the message consistent across both code paths.
- Around line 15502-15523: The top-level help output in usage() is missing the
new omo-slim/omos launcher even though the subcommand help exists in the
cmux.swift switch. Update the main usage list to include a matching entry for
omo-slim and its alias omos alongside the existing omo, omx, and omc entries so
cmux --help surfaces the new command; use the existing usage() function and the
new case label strings as the identifiers to locate the right spot.

In `@Sources/TaskManagerTypes.swift`:
- Around line 578-581: The TaskManagerTypes launcher detection entry is missing
the literal "omo-slim" token in argumentNeedles, so add it alongside the
existing opencode/omo aliases in the same initializer to keep indirect
invocation detection consistent with directBasenames and the claude/omc pattern.

---

Duplicate comments:
In `@daemon/remote/cmd/cmuxd-remote/agent_launch_test.go`:
- Around line 65-119: This test leaks the OPENCODE_CONFIG_DIR process
environment because omoSlimEnsurePlugin sets it internally and it is never
restored. In TestOmoSlimEnsurePluginConfiguresShadowTmuxMultiplexer, register
OPENCODE_CONFIG_DIR with t.Setenv before calling omoSlimEnsurePlugin so cleanup
resets it automatically, keeping later tests isolated; use the existing
omoSlimEnsurePlugin and omoSlimShadowConfigDir symbols to locate the setup.

In `@daemon/remote/cmd/cmuxd-remote/agent_launch.go`:
- Around line 145-153: The port selection in agent_launch.go is inconsistent
because OPENCODE_PORT is being set from cfg.defaultPort before the explicit
--port value is considered, while openCodeRelayLaunchArgs uses the user-provided
port. Update the launch flow in the agent launch path so the effective port is
resolved from args first, then the existing OPENCODE_PORT, then the default, and
use that same resolved value both for setting OPENCODE_PORT and for building
launchArgs via openCodeRelayLaunchArgs so the relay and launched process stay in
sync.
- Around line 891-897: The configureOMOSlimPlugin flow is swallowing failures
from os.Remove, json.MarshalIndent, and os.WriteFile, so update the needsWrite
branch to handle and return these errors instead of ignoring them. Use the
existing configPath, slimConfig, and muxConfig logic in configureOMOSlimPlugin,
and make sure any failure while removing the old file, marshaling the updated
config, or writing oh-my-opencode-slim.json is propagated back to the caller so
the tmux multiplexer setting is not reported as applied unless it was actually
persisted.
🪄 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

Run ID: 60b3fa14-f02e-4e0f-816f-f05ac83b5f62

📥 Commits

Reviewing files that changed from the base of the PR and between 30a17b3 and c60b081.

📒 Files selected for processing (19)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+SessionsListForkDiagnostics.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentForkArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentForkArgvTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentForkSupport.swift
  • Sources/ContentView.swift
  • Sources/RestorableAgentSession.swift
  • Sources/TaskManagerTypes.swift
  • Sources/TextBoxAgentDetection.swift
  • daemon/remote/cmd/cmuxd-remote/agent_launch.go
  • daemon/remote/cmd/cmuxd-remote/agent_launch_test.go
  • daemon/remote/cmd/cmuxd-remote/cli.go

Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift
Comment thread Sources/TaskManagerTypes.swift Outdated
@guanbear
guanbear force-pushed the codex/omo-slim-cmux branch from c300f6d to b74e2c9 Compare July 9, 2026 08:53
…nd help

- TaskManagerTypes: add the literal 'omo-slim' token to argumentNeedles so
  the slim launcher is detected when invoked indirectly (matching the
  claude entry which lists its 'omc' alias).
- cmux.swift usage(): list 'omo-slim (alias: omos)' in the top-level
  command list so 'cmux --help' surfaces the new launcher.

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a809253. Configure here.

installedLabel: "oh-my-opencode-slim plugin installed",
installFailLabel: "failed to install oh-my-opencode-slim",
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remote slim omits session plugin

Medium Severity

macOS omoSlimEnsurePlugin writes plugins/cmux-session.js into the slim shadow config, but remote omoSlimEnsurePlugin only uses ensureOpencodePlugin and never creates that file. Remote cmux omo-slim / cmux omos therefore miss the cmux OpenCode session bridge that the local launcher installs.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a809253. Configure here.

@guanbear

Copy link
Copy Markdown
Author

Superseded by #8165. OMO Slim 2.2.x now provides native cmux pane integration, so the replacement PR removes the tmux shim and shadow-config approach while retaining first-class launcher, remote, resume, fork, and agent-detection support.

@guanbear guanbear closed this Jul 15, 2026
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.

1 participant