Skip to content

Add Herdr CLI compatibility shim (Step toward native Herdr ) - #8736

Closed
RaviTharuma wants to merge 28 commits into
manaflow-ai:mainfrom
RaviTharuma:feat/herdr-native-mvp
Closed

RaviTharuma wants to merge 28 commits into
manaflow-ai:mainfrom
RaviTharuma:feat/herdr-native-mvp

Conversation

@RaviTharuma

@RaviTharuma RaviTharuma commented Jul 23, 2026 •

Copy link
Copy Markdown

Summary

Add a small, hidden cmux __herdr-compat dispatcher that translates a stable set of discovery aliases to the installed Herdr CLI:

  • status → herdr status
  • snapshot → herdr api snapshot
  • list-workspaces → herdr workspace list
  • list-tabs → herdr tab list
  • list-panes → herdr pane list

The dispatcher uses execv, so Herdr owns stdout, stderr, signals, and exit status. It does not require a running cmux socket and does not claim native topology/UI parity.

Why

Herdr is an agent-focused terminal multiplexer with a structured workspace/tab/pane/agent API. This narrow compatibility seam gives launchers and future integrations one cmux-owned entry point while keeping the first change independently reviewable. A separate user-space bridge remains available as a stopgap: https://github.com/RaviTharuma/cmux-herdr

The broader native nested-topology design is documented in that repository under docs/upstream/ and is intentionally not bundled into this PR.

Tests

  • Debug app build succeeds with CODE_SIGNING_ALLOWED=NO.
  • Built CLI smoke-tested against the live Herdr installation:
    • __herdr-compat --help
    • __herdr-compat snapshot (valid JSON)
    • __herdr-compat list-panes
  • Added process-level regression coverage for translation, --json, child exit propagation, unknown commands, missing Herdr, and help.
  • cmux-unit currently cannot complete in this checkout because pre-existing AgentResumeLivenessTests.swift fails to compile (missing argument for parameter 'processLiveness'). The Herdr test file itself compiles after fixing its initial direct-internal-type assumption.

Scope

This is additive and hidden. It does not:

  • inject a fake tmux binary,
  • mirror Herdr panes as Bonsplit panes,
  • persist nested topology,
  • connect cmux directly to the Herdr socket,
  • add UI or remote transport.

View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Summary by cubic

Adds a hidden cmux __herdr-compat command that forwards discovery aliases to an installed herdr CLI, giving launchers a cmux-owned entry point while cmux works toward native Herdr parity. The command replaces cmux with herdr via exec, so Herdr owns output, signals, and exit status without needing a cmux socket.

  • Supports status, snapshot, list-workspaces, list-tabs, and list-panes.
  • Maps top-level --json to status --json; JSON-only aliases ignore it and reject alias-local --json.
  • Searches only the supplied PATH, treats empty components as the current directory, skips directories and cmux-bundled binaries, and rejects malformed components.
  • Strips CMUX_* and CMUXD_* variables from the child environment.
  • Adds localized usage and launch errors (English and Japanese) and registers the command for suggestions.
  • Adds process-level tests covering translation, PATH handling, environment isolation, exit propagation, diagnostics, and help.

Written for commit 951f519. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a hidden compatibility command that translates supported aliases into equivalent herdr CLI commands.
    • Supported aliases include status, snapshots, and workspace, tab, and pane listings.
    • Added help output, JSON support for status, command validation, and clear exit statuses.
  • Bug Fixes

    • Improved executable discovery across configured and supplied PATH entries, including empty path components.
  • Localization

    • Added localized messages for usage instructions and compatibility errors.

Note

Medium Risk
Introduces a new exec-based CLI bridge and tightens PATH resolution semantics; impact is limited because the command is hidden and scoped, but incorrect PATH handling could still cause surprising launch failures.

Overview
Adds a hidden top-level command cmux __herdr-compat that maps a small set of discovery aliases to the installed Herdr CLI and replaces the process with execv, so stdout, stderr, signals, and exit codes come from Herdr—not from a cmux socket.

Aliases: status, snapshot, list-workspaces, list-tabs, and list-panes forward to the corresponding herdr subcommands. Top-level cmux --json maps to status --json only; for the list/snapshot aliases it is accepted but not passed through because those commands always emit JSON.

Executable lookup for this path uses resolveExecutableInSuppliedSearchPath: only the process PATH, with shell-like empty components and an empty PATH treated as the current directory—no HOME/provider fallbacks. Shared resolution logic now rejects directory names that shadow binaries and centralizes directory normalization.

Localized help and provider-neutral errors, command-suggestion registration for __herdr-compat, and process-level regression tests cover translation, PATH edge cases, and missing-binary behavior.

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

@cursor

cursor Bot commented Jul 23, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@RaviTharuma

Copy link
Copy Markdown
Author

Broader design / parity tracking issue: #8737. The external fallback bridge and full design package live at https://github.com/RaviTharuma/cmux-herdr.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

We couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting @coderabbitai full review.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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 a hidden cmux __herdr-compat bridge. It translates supported aliases, resolves herdr through PATH, forwards arguments and exit codes, provides localized errors and help, and adds end-to-end coverage.

Changes

Herdr compatibility bridge

Layer / File(s) Summary
Executable resolution
CLI/CMUXCLI+ExecutableResolution.swift, cmuxTests/CMUXCLIHerdrCompatTests.swift
Executable lookup now supports supplied PATH values, trims provider entries, and maps empty components to the current directory.
Compatibility command execution
CLI/CMUXCLI+HerdrCompat.swift, Resources/Localizable.xcstrings
The bridge validates aliases, translates provider arguments, handles --json, executes herdr, and reports localized usage and errors.
CLI entry-point and build wiring
CLI/cmux.swift, CLI/CMUXCLI+CommandSuggestions.swift, cmux.xcodeproj/project.pbxproj
The hidden command runs before normal CLI processing. The implementation and tests are included in their Xcode targets.
Compatibility regression coverage
cmuxTests/CMUXCLIHerdrCompatTests.swift
End-to-end tests cover translations, exit codes, aliases, help, PATH behavior, diagnostics, localization, and environment isolation.

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

Sequence Diagram(s)

sequenceDiagram
  participant cmux
  participant CMUXCLI
  participant ExecutableResolver
  participant PATH
  participant herdr
  cmux->>CMUXCLI: Run __herdr-compat command
  CMUXCLI->>ExecutableResolver: Resolve herdr from supplied PATH
  ExecutableResolver->>PATH: Search configured directories
  PATH-->>ExecutableResolver: Return executable path
  CMUXCLI->>herdr: execv translated arguments
  herdr-->>cmux: Return output and exit status
Loading

Suggested reviewers: austinywang, lawrencecchen, azooz2003-bit

Merge Risk: 🟡 Moderate · up to 94537

The hidden compatibility command currently has two behavior risks: some aliases may handle explicit JSON flags incorrectly, and localized errors or help may fall back to untranslated text when launched from the packaged application; it also adds translations outside the supported locale set. These bounded issues should be addressed before merging.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Cmux User-Facing Error Privacy ❌ Error The new help prints cmux __herdr-compat, and execv forwards Herdr stdout/stderr unchanged; this exposes an upstream vendor name and raw output to users without product-UI configuration. Remove vendor-specific identifiers from user-visible help and errors, and sanitize or suppress upstream stdout/stderr before returning command output.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift Package Boundaries ❓ Inconclusive Investigation in progress; no final assessment submitted. Await further repository and diff evidence.
✅ Passed checks (22 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.
Cmux Swift Actor Isolation ✅ Passed The production diff adds synchronous CMUXCLI helpers and PATH dispatch only; it introduces no MainActor models, service protocols, Sendable reference types, async background access, or UI stores.
Cmux Swift Blocking Runtime ✅ Passed The PR changes five Swift files, and the full added production diff contains no semaphores, waits, sleeps, delayed dispatch, timers, polling, main sync, or manual locks.
Cmux Browser Automation Off-Main ✅ Passed Browser-related scoped diff only extends existing main-actor browser.zoom.set with synchronous pageZoom/layout handling; no prohibited wait routing changed, and worker browser policy tests remain p...
Cmux Expensive Synchronous Load ✅ Passed The diff adds only hidden CLI dispatch, bounded PATH executable checks, argv setup, and execv; it adds no agent-history, transcript, JSONL, or synchronous main-actor loader.
Cmux Cache Substitution Correctness ✅ Passed The diff adds a Herdr CLI dispatcher and PATH resolver; it does not replace an authoritative persistence, history, undo, or snapshot read with a cache.
Cmux No Hacky Sleeps ✅ Passed The PR diff contains Swift, localization, and Xcode project changes only. No covered non-Swift runtime sleep or timer was introduced; test-only process timeouts are allowed.
Cmux Algorithmic Complexity ✅ Passed The new production code scans only a fixed five-alias list and linear PATH/argv arrays; PATH normalization uses Set deduplication, and existing node-version sorting is unchanged.
Cmux Swift Concurrency ✅ Passed Feature-side diff adds no Dispatch queues/groups, Combine state, completion-handler APIs, or fire-and-forget Tasks; the bridge uses synchronous execv and tests reuse existing process helpers.
Cmux Swift @Concurrent ✅ Passed The feature-side Swift diff adds only synchronous Herdr dispatch, argument translation, and path-resolution functions; it introduces no async/nonisolated work, @concurrent annotations, or UI-isolat...
Cmux Swiftpm Lockfiles ✅ Passed The PR diff has no Package.swift, Package.resolved, or .gitignore changes; its Xcode diff only adds Swift source references, not SwiftPM package references, and the policy checker passes.
Cmux Swift Logging ✅ Passed The PR diff adds only print(usage) for intended CLI help output; structural checks found no debugPrint, dump, NSLog, Logger, or diagnostic file logging.
Cmux Full Internationalization ✅ Passed The new CLI usage and errors use String(localized:defaultValue:); the three matching catalog keys provide translated, non-empty values for all 20 existing locales, with matching placeholders.
Cmux Swiftui State Layout ✅ Passed The PR diff adds only CLI resolver/dispatcher code and process tests; changed Swift files have no SwiftUI imports, View boundaries, state wrappers, GeometryReader, lazy rows, or render-time mutation.
Cmux Architecture Rethink ✅ Passed The diff adds one CLI dispatch path to runHerdrCompat and a required PATH bridge; scans found no sleeps, polling, locks, observers, side channels, or UI lifecycle ownership.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The PR-specific Swift diff adds only CLI resolution/exec logic and tests. It introduces or changes no NSWindow, NSPanel, NSWindowController, Window, or WindowGroup code.
Cmux Source Artifacts ✅ Passed The PR changes only seven tracked Swift, Xcode project, and localization files; no artifact directories, generated outputs, binary files, or scratch paths enter the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The PR diff contains no Swift files under /Sources/ outside /Tests/; changed Swift files are in CLI/ and cmuxTests/, so this rule is inapplicable.
Cmux No Ambient Global State ✅ Passed The PR adds behavior as methods on the existing constructable CMUXCLI type; its only stored static addition is a private constant, with no new free functions, global mutable state, namespace type,...
Title check ✅ Passed The title clearly identifies the main change: adding a Herdr CLI compatibility shim.
Description check ✅ Passed The description explains the change, rationale, scope, and testing in detail, but omits the template checklist and demo video section.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@greptile-apps

greptile-apps Bot commented Jul 23, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a hidden cmux __herdr-compat dispatcher that translates five discovery aliases (status, snapshot, list-workspaces, list-tabs, list-panes) to their Herdr CLI equivalents and execs into the provider binary, so exit status, signals, and I/O belong entirely to Herdr. The change is additive and deliberately narrow—no socket coupling, no UI surface, and no fake tmux binary.

  • A new resolveExecutableInSuppliedSearchPath variant enforces strict PATH-only lookup with POSIX-compliant empty-component handling and pre-normalization directory validation, preventing missing-directory/.. path traversal into the cwd.
  • A shared resolveExecutable helper now also rejects directories that shadow executables by name, fixing a class of shadowing bugs for all providers.
  • Localization for EN and JA is complete across usage, error, and unknown-command strings, matching the pattern of existing catalog entries.

Confidence Score: 5/5

  • Safe to merge. The change is strictly additive behind a hidden command, and the new PATH resolution logic is well-tested and more correct than what it replaces.
  • All five aliases translate correctly with no flag injection errors. The exec boundary strips cmux-private env vars. PATH resolution is now more conservative than before (rejects directory shadows, validates before normalization). EN and JA localization is complete. Tests cover every documented edge case at the process level.
  • No files require special attention.

Important Files Changed

Filename Overview
CLI/CMUXCLI+HerdrCompat.swift New dispatcher: correctly strips leading --json, validates alias-local --json before exec, filters CMUX_/CMUXD_ env vars, uses defer for C-string cleanup, and keeps all error copy provider-neutral and localized.
CLI/CMUXCLI+ExecutableResolution.swift Refactored to share a private resolveExecutable core; adds resolveExecutableInSuppliedSearchPath with POSIX-correct empty-component handling and pre-normalization path validation; directory-shadowing guard now applied to all providers.
Resources/Localizable.xcstrings Three new keys (usage, unknownCommand, launchFailed) with EN and JA translations matching the existing catalog structure; defaultValues in Swift code are consistent with EN catalog values.
cmuxTests/CMUXCLIHerdrCompatTests.swift Process-level regression tests covering alias translation, JSON flag rules, exit propagation, provider-neutral diagnostics (JA), empty/empty-component PATH, and directory-shadowing—all in the test target via @testable import.
CLI/CMUXCLI+CommandSuggestions.swift Registers __herdr-compat in topLevelCommandNames for command suggestion coverage; one-line additive change.
CLI/cmux.swift Adds the __herdr-compat dispatch branch before socket resolution, consistent with how other hidden commands (e.g., --version) are handled before socket checks.
cmux.xcodeproj/project.pbxproj Registers CMUXCLI+HerdrCompat.swift in the app target and CMUXCLIHerdrCompatTests.swift in the test target; UUIDs follow the existing project convention.

Sequence Diagram

sequenceDiagram
    participant User
    participant cmux as cmux CLI
    participant Resolver as resolveExecutableInSuppliedSearchPath
    participant PATH as Process PATH
    participant herdr as herdr binary

    User->>cmux: "cmux [--json] __herdr-compat <alias> [args]"
    cmux->>cmux: Strip leading --json flags → effectiveJSONOutput
    cmux->>cmux: Check --help / missing command → print usage or exit 2
    cmux->>cmux: Reject alias-local --json on JSON-only aliases (exit 2)
    cmux->>cmux: herdrCompatArguments(alias) → herdr subcommand args
    note right of cmux: status→[status], snapshot→[api,snapshot],<br/>list-workspaces→[workspace,list], etc.<br/>Inject --json only for status
    cmux->>Resolver: resolveExecutableInSuppliedSearchPath("herdr", PATH)
    Resolver->>PATH: Split on ":", empty component → cwd
    Resolver->>Resolver: normalizedDirectories (validate pre-normalization)
    Resolver->>Resolver: Skip directories shadowing executables
    Resolver->>Resolver: Exclude cmux bundled bin
    Resolver-->>cmux: /path/to/herdr (or nil → exit 127)
    cmux->>cmux: "Filter CMUX_*/CMUXD_* from child environment"
    cmux->>cmux: Build C argv/envp with strdup (defer frees on failure)
    cmux->>herdr: execve(herdr, [herdr, subcmd…], filtered_env)
    note over herdr: Process replaced — stdout/stderr/<br/>signals/exit owned by herdr
Loading

Reviews (13): Last reviewed commit: "fix: isolate Herdr execution environment..." | Re-trigger Greptile

Comment thread CLI/CMUXCLI+HerdrCompat.swift Outdated
Comment thread CLI/CMUXCLI+HerdrCompat.swift Outdated

@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

🤖 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`+HerdrCompat.swift:
- Around line 24-27: Centralize the supported Herdr compatibility commands in
one shared symbol, then update herdrCompatArguments, the unknown-command
CLIError message, and herdrCompatUsage to derive their command lists from it.
Preserve the existing command ordering and behavior while ensuring future
aliases automatically appear consistently in dispatch, errors, and help text.
- Around line 71-84: Update resolveHerdrExecutable to reject directory-valued
herdr candidates before accepting them as executables: verify the candidate is
not a directory, then apply isExecutableFile(atPath:). Preserve the existing
PATH traversal and continue searching when a matching directory is encountered.

In `@cmuxTests/CMUXCLIErrorOutputRegressionTests.swift`:
- Around line 57-93: Extend testHerdrCompatAliasesAndUnknownCommand with
hermetic process cases using an empty PATH directory: verify a Herdr-dependent
compatibility command reports executable-resolution failure with the required
nonzero status and output, and invoke __herdr-compat --help to assert its
documented exit status and output contract. Keep the existing alias and
unknown-command coverage unchanged.
🪄 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: d4ef324e-f407-4bef-8488-16352148274f

📥 Commits

Reviewing files that changed from the base of the PR and between 7652d3b and 90d6edb.

📒 Files selected for processing (5)
  • CLI/CMUXCLI+CommandSuggestions.swift
  • CLI/CMUXCLI+HerdrCompat.swift
  • CLI/cmux.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

Comment thread CLI/CMUXCLI+HerdrCompat.swift
Comment thread CLI/CMUXCLI+HerdrCompat.swift Outdated
Comment thread cmuxTests/CMUXCLIErrorOutputRegressionTests.swift Outdated
@RaviTharuma

Copy link
Copy Markdown
Author

Addressed the Greptile review in 250da51:

  • Confirmed the Herdr JSON contract: api snapshot, workspace list, tab list, and pane list always emit JSON and reject explicit --json; only status accepts it. All five aliases were smoke-tested and parsed as JSON.
  • Removed the hidden dispatcher name from user-facing errors.
  • Reused cmux's localized missing-provider message.
  • Made launch failure provider-neutral.
  • Added English and Japanese string-catalog entries.

Verification:

CMUX_SKIP_ZIG_BUILD=1 xcodebuild ... build CODE_SIGNING_ALLOWED=NO
** BUILD SUCCEEDED **

Built CLI smoke tests pass for all aliases plus unknown-command and missing-provider exit paths.

@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 `@CLI/CMUXCLI`+HerdrCompat.swift:
- Around line 46-52: Update the launch-failure handling in the Herdr
compatibility flow to use a provider-neutral recovery message without
interpolating executable or strerror details. Revise the
cli.herdrCompat.error.launchFailed localization entry and all catalog values to
remove format placeholders, and adjust the message construction to match the new
non-parameterized string while preserving the existing exit code.
🪄 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: e9dd767b-9717-4269-9033-59260aefdd30

📥 Commits

Reviewing files that changed from the base of the PR and between 90d6edb and 250da51.

📒 Files selected for processing (2)
  • CLI/CMUXCLI+HerdrCompat.swift
  • Resources/Localizable.xcstrings

Comment thread CLI/CMUXCLI+HerdrCompat.swift Outdated
@RaviTharuma

Copy link
Copy Markdown
Author

Pushed a comprehensive review follow-up in 3c82667:

  • localized compatibility usage/help in English and Japanese (the supported locales documented by AGENTS.md)
  • changed launch failure to a provider-neutral recovery message with no path or raw strerror
  • centralized alias names and translations so dispatch, errors, and help cannot drift
  • reused cmux's enriched provider executable search path
  • hardened the shared resolver so executable directories cannot shadow a later binary
  • extracted argv cleanup into a named helper
  • added process coverage for help output and synchronized command lists

I did not forward cmux --socket: Herdr 0.7.5 does not support a --socket option globally or on these subcommands (herdr --socket … exits 2). Forwarding it would break valid calls. The bridge continues to forward alias-specific options after the alias.

Verification:

  • git diff --check: clean
  • primary LSP diagnostics: 0
  • CMUX_SKIP_ZIG_BUILD=1 xcodebuild ... build CODE_SIGNING_ALLOWED=NO: BUILD SUCCEEDED
  • built-CLI smoke tests: all five aliases, help, unknown command, directory shadowing, and forced exec failure passed
  • focused cmux-unit tests are currently blocked by a pre-existing unrelated compile error in cmuxTests/AgentResumeLivenessTests.swift:25 (missing argument for parameter 'processLiveness')

@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

🤖 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`+HerdrCompat.swift:
- Around line 49-52: Update the Herdr compatibility argument construction used
by freeHerdrCompatArguments so any strdup allocation failure is detected
immediately before execv runs. Abort the launch with the existing
failure-handling path and ensure partially built argv data is released, rather
than appending nil or continuing with incomplete arguments.

In `@cmuxTests/CMUXCLIErrorOutputRegressionTests.swift`:
- Around line 93-94: Pin the locale to English for the subprocesses exercised by
the output assertions in CMUXCLIErrorOutputRegressionTests, including the cases
covering the assertions around delete-everything and status output. Configure
the subprocess environment or invocation so these English string checks are
stable regardless of the host locale.
- Around line 96-105: Update the __herdr-compat --help test around runProcess so
it cannot resolve the fake herdr executable: remove that fixture or invoke the
help process with an empty PATH. Preserve the existing help output and
successful-status assertions while ensuring the test passes independently of
Herdr provider resolution.
🪄 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: ba1be4f5-abe1-4135-8117-81fa885c3ba1

📥 Commits

Reviewing files that changed from the base of the PR and between 250da51 and 3c82667.

📒 Files selected for processing (4)
  • CLI/CMUXCLI+ExecutableResolution.swift
  • CLI/CMUXCLI+HerdrCompat.swift
  • Resources/Localizable.xcstrings
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

Comment thread CLI/CMUXCLI+HerdrCompat.swift Outdated
Comment thread cmuxTests/CMUXCLIErrorOutputRegressionTests.swift Outdated
Comment thread cmuxTests/CMUXCLIErrorOutputRegressionTests.swift Outdated
@RaviTharuma

Copy link
Copy Markdown
Author

Addressed all three latest CodeRabbit findings in 5635446: guarded and cleaned up partial strdup allocations, pinned subprocess locale for English assertions, and removed the fake provider before the help check. Primary LSP diagnostics report zero issues; the app build completed with BUILD SUCCEEDED; built-CLI smoke tests confirm localized unknown-command output and provider-independent help.

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

Caution

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

⚠️ Outside diff range comments (1)
CLI/CMUXCLI+HerdrCompat.swift (1)

71-73: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Forward explicit --json for every translated command.

The CLI parser supplies jsonOutput out-of-band, but this branch drops it for snapshot and the list aliases. Thus cmux --json __herdr-compat snapshot launches herdr api snapshot instead of forwarding --json, silently turning Herdr’s required rejection into success. Forward it uniformly and add a regression case for a non-status alias.

Proposed fix
-        if command == "status", jsonOutput, !arguments.contains("--json") {
+        if jsonOutput, !arguments.contains("--json") {
             prefix.append("--json")
         }
🤖 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`+HerdrCompat.swift around lines 71 - 73, Update the
translated-command argument handling around the command == "status" check so
jsonOutput appends "--json" for every Herdr-compatible command, not only status
or when the flag is already present. Preserve the duplicate-prevention behavior
for explicit arguments, and add a regression case covering a non-status alias
such as snapshot.
🤖 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.

Outside diff comments:
In `@CLI/CMUXCLI`+HerdrCompat.swift:
- Around line 71-73: Update the translated-command argument handling around the
command == "status" check so jsonOutput appends "--json" for every
Herdr-compatible command, not only status or when the flag is already present.
Preserve the duplicate-prevention behavior for explicit arguments, and add a
regression case covering a non-status alias such as snapshot.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a97b0fa5-edda-40e6-bd59-ff0a7b430ad7

📥 Commits

Reviewing files that changed from the base of the PR and between 3c82667 and 5635446.

📒 Files selected for processing (2)
  • CLI/CMUXCLI+HerdrCompat.swift
  • cmuxTests/CMUXCLIErrorOutputRegressionTests.swift

@RaviTharuma

Copy link
Copy Markdown
Author

Follow-up context from the stopgap + design package

Native remains the primary path; this PR stays intentionally a hidden compat shim, not nested topology.

Living docs (plugin repo):

Tracking issue for the real tree model: #8737

Happy to address the open review notes on this shim (--json handling for list/snapshot aliases, user-facing vendor/internal-name wording) in a focused follow-up commit without expanding scope into nested render/restore.

@cursor

cursor Bot commented Aug 1, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 7 files

Tip: cubic used a learning from your PR history. Let your coding agent read cubic learnings directly with the cubic MCP.

Re-trigger cubic

Comment thread cmuxTests/CMUXCLIHerdrCompatTests.swift Outdated
Comment thread cmuxTests/CMUXCLIHerdrCompatTests.swift Outdated

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

RaviTharuma and others added 18 commits September 10, 2026 08:52
Document that only `status` maps cmux `--json` to a provider flag; list and
snapshot aliases always emit JSON and ignore `--json` so we do not inject an
unsupported flag. Soften usage copy away from a hard-coded vendor label.
Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>
Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>
Remove committed conflict markers from Localizable.xcstrings, rebuild the
three herdr-compat keys on top of current main (all 20 locales), and align
en/ja launchFailed/unknownCommand copy with the provider-neutral runtime
strings. Drop superseded duplicate herdr process tests from
CMUXCLIErrorOutputRegressionTests so coverage lives only in
CMUXCLIHerdrCompatTests.

Co-authored-by: Ravi Tharuma <RaviTharuma@users.noreply.github.com>

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com>
Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com>
Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com>
Co-authored-by: cmux reload-cloud <cmux-reload-cloud@users.noreply.github.com>
The French localization assertions cubic flagged (P0) were removed with the
test that used them; the helper kept mapping locale == "fr" to fr_FR, which
no caller reaches and which no longer has catalog coverage. Both live callers
pass "en" or "ja", so the POSIX locale stays en_US either way.
A rebase of this branch reverted the en and ja values of the three
cli.herdrCompat.* keys to their pre-review text while the other 18 locales
kept the corrected wording, so en/ja disagreed with both the code and the
tests:

- error.launchFailed: en/ja had resurfaced the provider name and the
  resolved filesystem path via a 2-argument format, but the call site
  passes no format arguments, so users would have seen literal %1$@/%2$@.
- error.unknownCommand: en/ja used a 1-argument '%@' with the alias list
  frozen into the translation, while the call site passes command plus
  Self.herdrCompatCommandList as %1$@/%2$@; the list would drift silently.
- usage: en/ja dropped the note that an alias-local --json is rejected,
  which the dispatcher now enforces before translation.

en now matches each defaultValue exactly and ja matches the assertions in
testHerdrCompatDiagnosticsUseSuppliedPATHAndRemainProviderNeutral.

Copy link
Copy Markdown
Author

@austinywang friendly ping — Herdr CLI compatibility shim is still open and ready for a maintainer look. Happy to rebase onto current main or address any follow-up notes.

@RaviTharuma RaviTharuma closed this by deleting the head repository Sep 24, 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.

4 participants