Skip to content

chore: add cmux config that delegates worktree creation to worktrunk - #5053

Open
adaam2 wants to merge 4 commits into
mainfrom
chore/cmux-worktrunk-config
Open

chore: add cmux config that delegates worktree creation to worktrunk#5053
adaam2 wants to merge 4 commits into
mainfrom
chore/cmux-worktrunk-config

Conversation

@adaam2

@adaam2 adaam2 commented Aug 7, 2026

Copy link
Copy Markdown
Member

What

Adds .cmux/cmux.json, a project config for cmux that plugs its workspace creation into our existing worktrunk flow instead of raw git worktree add.

Two workspace commands, wired to the "+" button and command palette:

  • New Branch (worktrunk) — prompts for a branch name (plus optional --no-boot / --base <ref> passthrough), runs wt switch --create, so the .config/wt.toml hooks fire as usual: git:workinit port remap and the background git:workboot stack boot. Echoes the worktree's dashboard URL.
  • Open Branch (worktrunk)wt switch for an existing branch; supports wt shortcuts (^, -, pr:123) and the interactive picker on empty input.

Each workspace opens two panes: a shell left in the worktree, and a Claude agent pane that waits for the worktree path (via a state file keyed on CMUX_WORKSPACE_ID), cds in, and starts.

Notes

  • Requires worktrunk shell integration (https://worktrunk.dev/shell/), which the repo's worktree flow already assumes.
  • --no-boot is translated to GRAM_WT_NO_BOOT=1, matching the git:workboot hook contract.
  • cmux has no teardown hook: closing a workspace does not remove the worktree — wt remove still does that (and the pre-remove nuke hook tears the stack down).
  • No-op for anyone not running cmux; the file is only read by the app.

Summary by cubic

Add cmux project config to create/open worktrees via worktrunk (wt), plus a palette action to import existing git worktrees. The import script resolves the bundled cmux CLI and relies on socket auto-discovery (>=0.64).

  • New Features

    • Adds .cmux/cmux.json to route workspace creation/opening through wt.
    • Two commands: New Branch (wt switch --create, supports --base, --no-boot) and Open Branch (wt switch, supports ^, -, pr:123, or picker); layout opens a terminal plus a claude pane that waits on CMUX_WORKSPACE_ID.
    • Import .cmux/import-worktrees.sh: one workspace per git worktree; resolves the bundled cmux CLI; socket auto-discovered (override with CMUX_SOCKET_PATH).
    • On create, --no-boot sets GRAM_WT_NO_BOOT=1; prints the dashboard URL if a port is found.
  • Migration

    • Requires worktrunk shell integration.
    • For import, allow external CLI: defaults write com.cmuxterm.app socketControlMode automation.
    • Closing a cmux workspace does not remove the worktree; run wt remove.

Written for commit 6a8af9c. Summary will update on new commits.

Review in cubic

@adaam2
adaam2 requested a review from a team as a code owner August 7, 2026 13:44
@changeset-bot

changeset-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 6a8af9c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@cubic-dev-ai cubic-dev-ai Bot left a comment

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.

3 issues found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name=".cmux/import-worktrees.sh">

<violation number="1" location=".cmux/import-worktrees.sh:30">
P2: Worktrees located under paths containing spaces are truncated during import, so `git -C "$wt"` fails and the script skips that worktree. Extract everything after the `worktree ` prefix instead of using the second whitespace-delimited field.</violation>

<violation number="2" location=".cmux/import-worktrees.sh:37">
P2: Under `set -euo pipefail`, any single failing iteration inside the `while read` loop aborts the entire import. `git -C "$wt" rev-parse --abbrev-ref HEAD` or `cmux new-workspace --cwd "$wt"` will fail (nonzero) if a worktree was removed concurrently, points at an invalid path, or the cmux socket/control mode rejects the call — and with `set -e` that tears down the whole loop, silently leaving every remaining worktree un-imported with no indication of which path failed or why. Since this is designed as a re-runnable/idempotent sync, per-worktree failures should be tolerated and reported rather than aborting the batch. Wrap the per-worktree body so a failure is logged and the loop continues.</violation>

<violation number="3" location=".cmux/import-worktrees.sh:38">
P2: The script identifies the workspace it just created by grabbing the *last* entry of `cmux list-workspaces --json` (`[-1]`) instead of the id that `cmux new-workspace` returns. This only works if the CLI appends new workspaces and never reorders or sorts them, and if creation is synchronously visible in the very next call. If cmux returns workspaces in any other order (e.g. name-sorted) or the create is still propagating, `rename-workspace` will rename an existing, unrelated workspace and the new one is left with its default name — silently corrupting workspace labels. Prefer capturing the id directly from the `new-workspace` output payload (most CLIs print the created object) and renaming right from that value.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread .cmux/import-worktrees.sh
print(ws.get("cwd") or "")
')

git -C "$repo" worktree list --porcelain | awk '/^worktree /{print $2}' |

@cubic-dev-ai cubic-dev-ai Bot Aug 7, 2026

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: Worktrees located under paths containing spaces are truncated during import, so git -C "$wt" fails and the script skips that worktree. Extract everything after the worktree prefix instead of using the second whitespace-delimited field.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .cmux/import-worktrees.sh, line 30:

<comment>Worktrees located under paths containing spaces are truncated during import, so `git -C "$wt"` fails and the script skips that worktree. Extract everything after the `worktree ` prefix instead of using the second whitespace-delimited field.</comment>

<file context>
@@ -0,0 +1,44 @@
+    print(ws.get("cwd") or "")
+')
+
+git -C "$repo" worktree list --porcelain | awk '/^worktree /{print $2}' |
+while read -r wt; do
+  if printf "%s\n" "$existing" | grep -Fxq "$wt"; then
</file context>
Fix with cubic

Comment thread .cmux/import-worktrees.sh
continue
fi
branch=$(git -C "$wt" rev-parse --abbrev-ref HEAD)
cmux new-workspace --cwd "$wt"

@cubic-dev-ai cubic-dev-ai Bot Aug 7, 2026

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: Under set -euo pipefail, any single failing iteration inside the while read loop aborts the entire import. git -C "$wt" rev-parse --abbrev-ref HEAD or cmux new-workspace --cwd "$wt" will fail (nonzero) if a worktree was removed concurrently, points at an invalid path, or the cmux socket/control mode rejects the call — and with set -e that tears down the whole loop, silently leaving every remaining worktree un-imported with no indication of which path failed or why. Since this is designed as a re-runnable/idempotent sync, per-worktree failures should be tolerated and reported rather than aborting the batch. Wrap the per-worktree body so a failure is logged and the loop continues.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .cmux/import-worktrees.sh, line 37:

<comment>Under `set -euo pipefail`, any single failing iteration inside the `while read` loop aborts the entire import. `git -C "$wt" rev-parse --abbrev-ref HEAD` or `cmux new-workspace --cwd "$wt"` will fail (nonzero) if a worktree was removed concurrently, points at an invalid path, or the cmux socket/control mode rejects the call — and with `set -e` that tears down the whole loop, silently leaving every remaining worktree un-imported with no indication of which path failed or why. Since this is designed as a re-runnable/idempotent sync, per-worktree failures should be tolerated and reported rather than aborting the batch. Wrap the per-worktree body so a failure is logged and the loop continues.</comment>

<file context>
@@ -0,0 +1,44 @@
+    continue
+  fi
+  branch=$(git -C "$wt" rev-parse --abbrev-ref HEAD)
+  cmux new-workspace --cwd "$wt"
+  id=$(cmux list-workspaces --json | python3 -c '
+import json, sys
</file context>
Fix with cubic

Comment thread .cmux/import-worktrees.sh
fi
branch=$(git -C "$wt" rev-parse --abbrev-ref HEAD)
cmux new-workspace --cwd "$wt"
id=$(cmux list-workspaces --json | python3 -c '

@cubic-dev-ai cubic-dev-ai Bot Aug 7, 2026

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: The script identifies the workspace it just created by grabbing the last entry of cmux list-workspaces --json ([-1]) instead of the id that cmux new-workspace returns. This only works if the CLI appends new workspaces and never reorders or sorts them, and if creation is synchronously visible in the very next call. If cmux returns workspaces in any other order (e.g. name-sorted) or the create is still propagating, rename-workspace will rename an existing, unrelated workspace and the new one is left with its default name — silently corrupting workspace labels. Prefer capturing the id directly from the new-workspace output payload (most CLIs print the created object) and renaming right from that value.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At .cmux/import-worktrees.sh, line 38:

<comment>The script identifies the workspace it just created by grabbing the *last* entry of `cmux list-workspaces --json` (`[-1]`) instead of the id that `cmux new-workspace` returns. This only works if the CLI appends new workspaces and never reorders or sorts them, and if creation is synchronously visible in the very next call. If cmux returns workspaces in any other order (e.g. name-sorted) or the create is still propagating, `rename-workspace` will rename an existing, unrelated workspace and the new one is left with its default name — silently corrupting workspace labels. Prefer capturing the id directly from the `new-workspace` output payload (most CLIs print the created object) and renaming right from that value.</comment>

<file context>
@@ -0,0 +1,44 @@
+  fi
+  branch=$(git -C "$wt" rev-parse --abbrev-ref HEAD)
+  cmux new-workspace --cwd "$wt"
+  id=$(cmux list-workspaces --json | python3 -c '
+import json, sys
+print(json.load(sys.stdin)[-1]["id"])
</file context>
Fix with cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant