Repository navigation
Document cmux agent skills - #4203
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughAdds two new cmux skills: cmux-settings (Python CLI for safely viewing/editing ~/.config/cmux/cmux.json with JSONC support, dotted-path operations, and validation) and cmux-workspace (workspace-scoped automation rules and command reference). Integrates both into the web docs and updated English/Japanese translations. Changescmux-settings and cmux-workspace skills
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI as cmux-settings CLI
participant JSONC as JSONC Parser
participant Settings as cmux.json
participant Editor
User->>CLI: subcommand (get/set/validate/open)
CLI->>Settings: load file
Settings-->>JSONC: raw JSONC content
JSONC->>JSONC: strip comments, trailing commas
JSONC-->>CLI: parsed JSON dict
alt get/set/unset
CLI->>CLI: navigate dotted path
CLI->>CLI: return value or update dict
else validate
CLI->>CLI: compare keys vs schema sources
CLI-->>User: validation result
else open
CLI->>Editor: launch $EDITOR/$VISUAL
Editor->>Settings: user edits
end
CLI->>Settings: atomic write (temp + replace)
Settings-->>User: success/unchanged feedback
graph TD
A["Automation Request"] --> B{Scope specified?}
B -->|No| C["Use CMUX_WORKSPACE_ID<br/>or cmux identify --json"]
B -->|Yes| D["Use specified workspace"]
C --> E["Check Caller Panes"]
D --> E
E --> F{Helper pane<br/>exists?}
F -->|Yes| G["Reuse helper pane<br/>route output there"]
F -->|No| H["Create right-side<br/>helper pane"]
G --> I["Execute action"]
H --> I
I --> J{Focus change<br/>requested?}
J -->|No| K["Use --focus false"]
J -->|Yes| L["Explicit user ask<br/>required"]
K --> M["Complete without<br/>disruption"]
L --> M
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
Caution Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional.
❌ Failed checks (1 error, 1 warning)
✅ Passed checks (14 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryAdds two installable repo skills —
Confidence Score: 5/5Safe to merge. The new Python CLI writes atomically, validates keys against a known schema, and guards intermediate path rewrites; three issues found in earlier review rounds are all resolved in this revision. Changes are additive — two new skills, reference docs, web page tables, and i18n strings. The Python helper correctly strips JSONC, uses os.replace for atomic writes, filters source-derived supported paths to known settings sections only, and raises a clean error instead of silently clobbering scalars. No existing behaviour is altered. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A([cmux-settings subcommand]) --> B{subcommand}
B --> P[path: print config path]
B --> D[dump: print raw or parsed JSON]
B --> G[get key: read value at dotted path]
B --> S[set key value: write value]
B --> U[unset key: remove key, prune empty parents]
B --> L[list-supported: print all recognized paths]
B --> V[validate: check all set keys are known]
B --> O[open: open in $EDITOR or fallback chain]
S --> LS[load_settings: strip_jsonc then json.loads]
U --> LS
G --> LS
LS --> |file missing| NF[return default skeleton]
LS --> |parse error| ERR[SystemExit: not valid JSONC]
LS --> DATA[(parsed dict)]
DATA --> SA[set_at: create intermediates or error if non-dict]
DATA --> UA[unset_at: delete key, prune empty ancestors]
SA --> |changed| AW[atomic_write: json.dumps to tempfile then os.replace]
UA --> |changed| AW
SA --> |no-op| NOOP[print unchanged]
UA --> |not present| NOOP
V --> SP[supported_paths: try Swift source, fallback to all-keys.md]
SP --> |found| VALIDATE[flatten set keys, check supported set plus prefix]
SP --> |not found| WARN[warn: schema unavailable]
O --> ED{$EDITOR set?}
ED --> |yes| RUN[subprocess.call editor]
ED --> |no| FB[try code then cursor then open -e then xdg-open]
Reviews (3): Last reviewed commit: "Tighten cmux settings editor handling" | Re-trigger Greptile |
|
|
||
| def supported_paths_from_source(source: Path) -> list[str]: | ||
| text = source.read_text() | ||
| return sorted(set(re.findall(r'"([a-zA-Z]+\.[a-zA-Z0-9_.]+)"', text))) |
There was a problem hiding this comment.
The regex scans for any double-quoted dotted string in the Swift source file, so it will match non-settings strings like
"com.apple.Foundation", "github.manaflow.cmux", or other literals that happen to contain a dot. False positives end up in supported_paths(), which causes validate to accept those spurious paths as recognized keys and silently swallow validation errors for typos that share the same prefix.
| return sorted(set(re.findall(r'"([a-zA-Z]+\.[a-zA-Z0-9_.]+)"', text))) | |
| # Match only strings that start with a known top-level settings section so | |
| # we don't pick up bundle IDs, module names, or other dotted literals. | |
| _KNOWN_SECTIONS = ( | |
| "app.", "terminal.", "notifications.", "sidebar.", "sidebarAppearance.", | |
| "workspaceColors.", "automation.", "browser.", "shortcuts.", | |
| ) | |
| candidates = re.findall(r'"([a-zA-Z]+\.[a-zA-Z0-9_.]+)"', text) | |
| return sorted({p for p in candidates if any(p.startswith(s) for s in _KNOWN_SECTIONS)}) |
There was a problem hiding this comment.
Fixed by filtering source-derived supported paths to known cmux settings sections only.
— Claude Code
| for p in parts[:-1]: | ||
| if p not in cur or not isinstance(cur[p], dict): | ||
| cur[p] = {} | ||
| cur = cur[p] |
There was a problem hiding this comment.
When an intermediate path component already exists in the config but is not a dict (e.g. a scalar left by a previous bulk edit),
set_at silently replaces it with an empty dict {} without any warning, discarding the previous value. A user running cmux-settings set automation.portBase 9200 on a file where automation somehow held a string would lose that value with no diagnostic.
| for p in parts[:-1]: | |
| if p not in cur or not isinstance(cur[p], dict): | |
| cur[p] = {} | |
| cur = cur[p] | |
| for p in parts[:-1]: | |
| if p not in cur: | |
| cur[p] = {} | |
| elif not isinstance(cur[p], dict): | |
| raise SystemExit( | |
| f"error: intermediate key '{p}' is not an object (got {type(cur[p]).__name__}); " | |
| f"cannot set nested path" | |
| ) | |
| cur = cur[p] |
There was a problem hiding this comment.
Fixed by rejecting nested writes when an intermediate key exists but is not an object, preserving the existing value.
— Claude Code
| print( | ||
| "error: could not locate Sources/CmuxSettingsJSONPathSupport.swift or references/all-keys.md", | ||
| file=sys.stderr, | ||
| ) |
There was a problem hiding this comment.
The
list-supported error message mentions the internal Swift source file path Sources/CmuxSettingsJSONPathSupport.swift in command output read directly by agents. Per the project's error-copy policy, command output should not expose internal implementation paths; a user-oriented message about the missing reference file is sufficient.
| print( | |
| "error: could not locate Sources/CmuxSettingsJSONPathSupport.swift or references/all-keys.md", | |
| file=sys.stderr, | |
| ) | |
| print( | |
| "error: could not load the supported-paths list; " | |
| "run from a cmux checkout or reinstall the cmux-settings skill", | |
| file=sys.stderr, | |
| ) |
There was a problem hiding this comment.
Fixed by replacing the implementation-path error with a user-facing reinstall-or-run-from-checkout message.
— Claude Code
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 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 `@skills/cmux-settings/scripts/cmux-settings`:
- Around line 106-109: The split_path function currently allows empty segments
like "a..b", ".a", and "a."; update split_path to validate the result of
dotted.split(".") and reject any empty segment (e.g., any s == "" in the list)
by raising SystemExit with a clear error message (e.g., "error: empty key path
segment" or similar); keep the initial empty-string check for the whole input
and ensure callers of split_path continue to receive a list[str] only when all
segments are non-empty.
- Around line 121-130: The change detection in set_at is unsafe because it uses
the string sentinel "__cmux_missing__" which can equal a legitimate value;
update set_at (function name set_at) to detect changes without a colliding
sentinel — e.g., compute changed by checking presence or inequality (changed =
(leaf not in cur) or cur[leaf] != value) or use a unique object() sentinel —
then assign cur[leaf] = value and return changed.
- Around line 81-82: The global regex r",(\s*[}\]])" used in the return
statement can remove commas that appear inside string literals; replace that
single re.sub call with a small scanner that walks the joined output string,
tracks whether you're inside a quoted string (respecting backslash escapes) and
only removes a trailing comma when it is encountered outside of a string (i.e.
when not in-string and the next non-space char is ']' or '}'); update the code
that currently contains the return re.sub(...) expression to call this scanner
or inline the logic so only commas outside string literals are stripped.
- Around line 331-335: The fallback that calls subprocess.call(["open",
str(path)]) can raise FileNotFoundError on systems without an "open" binary;
update the logic around the apps loop (the list ["code","cursor","open"], the
shutil.which checks, and the subprocess.call invocation) to first try a
platform-appropriate editor lookup (check shutil.which for "open" before calling
it), then fall back to checking the $EDITOR environment variable, and wrap the
final subprocess call in a try/except that catches FileNotFoundError and returns
or exits with a clean non-zero error message via the same logging/return path
used elsewhere.
🪄 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: bb94ddeb-09c6-43f9-af8d-cc8d2cc7160d
📒 Files selected for processing (13)
skills/cmux-settings/SKILL.mdskills/cmux-settings/agents/openai.yamlskills/cmux-settings/references/all-keys.mdskills/cmux-settings/references/shortcut-actions.mdskills/cmux-settings/scripts/cmux-settingsskills/cmux-workspace/SKILL.mdskills/cmux-workspace/agents/openai.yamlskills/cmux-workspace/references/commands.mdskills/cmux/SKILL.mdweb/app/[locale]/docs/skills/page.tsxweb/app/sitemap.tsweb/messages/en.jsonweb/messages/ja.json
There was a problem hiding this comment.
4 issues found across 13 files
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="skills/cmux-settings/scripts/cmux-settings">
<violation number="1" location="skills/cmux-settings/scripts/cmux-settings:128">
P2: `set` can incorrectly report "unchanged" and skip writing when the new value equals the string sentinel `"__cmux_missing__"`. Use a unique object sentinel instead of a user-representable string.</violation>
</file>
<file name="skills/cmux-workspace/references/commands.md">
<violation number="1" location="skills/cmux-workspace/references/commands.md:25">
P2: `new-workspace` example uses unsupported `--cwd`; use `--working-directory` so the command actually runs.</violation>
<violation number="2" location="skills/cmux-workspace/references/commands.md:44">
P2: `new-split` does not accept `--workspace`; this example is invalid and will error at runtime.</violation>
<violation number="3" location="skills/cmux-workspace/references/commands.md:53">
P2: `close-surface` example includes unsupported `--workspace`, so the documented command will not execute.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
|
||
| cmux focus-pane --workspace "$CMUX_WORKSPACE_ID" --pane pane:2 | ||
| cmux focus-panel --workspace "$CMUX_WORKSPACE_ID" --panel surface:3 | ||
| cmux close-surface --workspace "$CMUX_WORKSPACE_ID" --surface surface:3 |
There was a problem hiding this comment.
P2: close-surface example includes unsupported --workspace, so the documented command will not execute.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At skills/cmux-workspace/references/commands.md, line 53:
<comment>`close-surface` example includes unsupported `--workspace`, so the documented command will not execute.</comment>
<file context>
@@ -0,0 +1,110 @@
+
+cmux focus-pane --workspace "$CMUX_WORKSPACE_ID" --pane pane:2
+cmux focus-panel --workspace "$CMUX_WORKSPACE_ID" --panel surface:3
+cmux close-surface --workspace "$CMUX_WORKSPACE_ID" --surface surface:3
+cmux move-surface --surface surface:7 --pane pane:2 --focus true
+cmux reorder-surface --surface surface:7 --before surface:3
</file context>
| cmux close-surface --workspace "$CMUX_WORKSPACE_ID" --surface surface:3 | |
| cmux close-surface --surface surface:3 |
There was a problem hiding this comment.
Verified against CLI help and implementation: close-surface accepts --workspace, so this example is valid as written.
— Claude Code
There was a problem hiding this comment.
Thanks for the feedback! I've saved this as a new learning to improve future reviews.
| cmux list-panels --workspace "$CMUX_WORKSPACE_ID" | ||
| cmux tree --workspace "$CMUX_WORKSPACE_ID" | ||
|
|
||
| cmux new-split right --workspace "$CMUX_WORKSPACE_ID" |
There was a problem hiding this comment.
P2: new-split does not accept --workspace; this example is invalid and will error at runtime.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At skills/cmux-workspace/references/commands.md, line 44:
<comment>`new-split` does not accept `--workspace`; this example is invalid and will error at runtime.</comment>
<file context>
@@ -0,0 +1,110 @@
+cmux list-panels --workspace "$CMUX_WORKSPACE_ID"
+cmux tree --workspace "$CMUX_WORKSPACE_ID"
+
+cmux new-split right --workspace "$CMUX_WORKSPACE_ID"
+cmux new-split down --workspace "$CMUX_WORKSPACE_ID" --surface "$CMUX_SURFACE_ID"
+cmux new-pane --workspace "$CMUX_WORKSPACE_ID" --type terminal --direction right
</file context>
| cmux new-split right --workspace "$CMUX_WORKSPACE_ID" | |
| cmux new-split right --surface "$CMUX_SURFACE_ID" |
|
|
||
| cmux list-workspaces | ||
| cmux list-workspaces --json | ||
| cmux new-workspace --name "task" --cwd "$PWD" |
There was a problem hiding this comment.
P2: new-workspace example uses unsupported --cwd; use --working-directory so the command actually runs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At skills/cmux-workspace/references/commands.md, line 25:
<comment>`new-workspace` example uses unsupported `--cwd`; use `--working-directory` so the command actually runs.</comment>
<file context>
@@ -0,0 +1,110 @@
+
+cmux list-workspaces
+cmux list-workspaces --json
+cmux new-workspace --name "task" --cwd "$PWD"
+cmux new-workspace --command "npm run dev"
+cmux new-workspace --layout '{"root":{"type":"terminal"}}'
</file context>
| cmux new-workspace --name "task" --cwd "$PWD" | |
| cmux new-workspace --name "task" --working-directory "$PWD" |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit fe15f6b. Configure here.
There was a problem hiding this comment.
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 `@skills/cmux-settings/scripts/cmux-settings`:
- Around line 385-391: The code uses editor.split() when launching the editor
(the editor variable passed to subprocess.call), which fails for editor paths
containing spaces; replace editor.split() with shlex.split(editor) to parse
quoted/complex EDITOR values robustly and pass the resulting list plus str(path)
to subprocess.call; also update the FileNotFoundError error message (inside the
except block that currently prints "error: editor not found:
{editor.split()[0]}") to extract the executable name from shlex.split(editor)[0]
(or otherwise use the parsed tokens) so the error reports the correct program
name.
- Around line 348-358: The hard-coded structural set named "structural" lists
schema keys that must be kept in sync with schema changes; add a concise
maintenance comment directly above the structural declaration referencing that
this list must be updated whenever the schema evolves (and ideally point
maintainers to the canonical schema source or file and to run any relevant
validation/update steps), so future changes to keys like "$schema",
"schemaVersion", "actions", "ui", "commands", "vault", "newWorkspaceCommand",
"surfaceTabBarButtons", and "rightSidebar" are not missed.
🪄 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: 0e5fe7b4-5532-482c-ac81-b54c09b5c940
📒 Files selected for processing (1)
skills/cmux-settings/scripts/cmux-settings
There was a problem hiding this comment.
1 issue found across 1 file (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="skills/cmux-settings/scripts/cmux-settings">
<violation number="1" location="skills/cmux-settings/scripts/cmux-settings:388">
P2: Parse `$EDITOR` with shell-style splitting instead of `str.split()`, otherwise quoted editor commands (especially paths with spaces) fail to execute.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Addressed in follow-up commits; latest CodeRabbit check is passing.

Summary
Testing
Note
Medium Risk
Adds a new Python helper that can modify
~/.config/cmux/cmux.jsonand validate keys; while scoped to the skills tooling, mistakes could impact user configuration. The rest is documentation/i18n updates with low runtime risk.Overview
Adds two new installable skills:
cmux-settings(with a bundledcmux-settingsPython helper to read/write JSONC settings, list supported schema paths, validate unknown keys, and open the config) andcmux-workspace(guidance + command reference for scoping automation to the caller workspace/surface and avoiding focus-disrupting commands).Updates the existing
cmuxskill to cross-link these new skills, expands/docs/skillsto list them and adds new coverage and suggested future skills sections, updates EN/JA translations accordingly, and bumps the sitemaplastModifiedfor/docs/skills.Reviewed by Cursor Bugbot for commit 0774b13. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by cubic
Adds two installable repo skills,
cmux-settingsandcmux-workspace, and expands the skills docs with coverage and suggestions. Documents current‑workspace automation and ships a safe helper to edit and validate~/.config/cmux/cmux.json.New Features
cmux-settingsskills/cmux-settings/scripts/cmux-settings(JSONC‑aware; subcommands:path,dump [--no-comments],get,set,unset,list-supported,validate,open; supports--file).skills/cmux-settings/agents/openai.yaml.cmux-workspaceskills/cmux-workspace/references/commands.md.skills/cmux-workspace/agents/openai.yaml./docs/skillslists the new skills, adds a coverage table and a “suggested future skills” section.web/messages/{en.json,ja.json}; sitemaplastModifiedbumped; cross‑links added inskills/cmux/SKILL.md.Bug Fixes
cmux-settingshelper robustnessunsetprunes empty parents.$EDITOR/$VISUALwith safe parsing; pre‑creates the file with schema header if missing; fallbacks tocode --wait,cursor --wait,open -e,xdg-open; clearer errors and exit codes.Written for commit 0774b13. Summary will update on new commits.
Summary by CodeRabbit
New Features
Documentation