Repository navigation
Add Inline VS Code serve-web settings (port, data dir, persistence, extra args) - #6900
austinywang wants to merge 13 commits into
Conversation
…xtra args) Exposes the Inline VS Code `serve-web` launch details that were previously hard-coded in the launcher path, both in `cmux.json` and the Settings UI, per issue #6645. Adds an `inlineVSCode` config block: - persistServeWebState — keep serve-web state across launches (default true; false uses a throwaway data dir so nothing persists) - port — pin the local serve-web port (0 = random) - serverDataDir — choose the serve-web --server-data-dir (~ expands) - extraArgs — advanced upstream serve-web flags, appended verbatim Resolution precedence is cmux.json (also written by the Settings UI) > environment variable (CMUX_INLINE_VSCODE_*) > internal defaults. Defaults preserve the historical behavior (random port, VS Code default data location), so this is purely additive. serve-web stays bound to 127.0.0.1 with a connection token regardless of extraArgs. The macOS launcher reads the live global cmux.json on each (re)start through a single shared path (VSCodeServeWebController), so there is no second way to start VS Code; "Restart Inline VS Code" applies changes immediately. Implementation: - New InlineVSCodeServeWebSupport / resolver / presence-aware reader / pure serve-web argument builder (unit-tested). - New CmuxSettings catalog section + CmuxSettingsUI "Inline VS Code" settings section, search index, and curated search entries. - Schema, configuration docs, and en/ja message catalogs updated; all user-facing strings localized in Localizable.xcstrings (en + ja). Fixes #6645 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughAdds a new ChangesInline VS Code serve-web settings
Sequence Diagram(s)sequenceDiagram
participant TerminalDirectoryOpenSupport
participant InlineVSCodeServeWebConfigurationLoader
participant InlineVSCodeServeWebOptionsResolver
participant Process
TerminalDirectoryOpenSupport->>InlineVSCodeServeWebConfigurationLoader: loadOptions()
InlineVSCodeServeWebConfigurationLoader->>InlineVSCodeServeWebOptionsResolver: resolve inlineVSCode fields
InlineVSCodeServeWebConfigurationLoader-->>TerminalDirectoryOpenSupport: serveWebArguments(...)
TerminalDirectoryOpenSupport->>Process: assign Process.arguments
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Poem
Important Pre-merge checks failedPlease resolve all errors before merging. Addressing warnings is optional. ❌ Failed checks (2 errors, 2 warnings)
✅ Passed checks (21 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 |
…gs-for-inline-vs-code
Greptile SummaryThis PR exposes four previously hard-coded
Confidence Score: 5/5Safe to merge — the change is purely additive, defaults preserve historical behavior, and security invariants (loopback bind, connection-token) are enforced unconditionally in the arg builder. All new logic is pure and comprehensively unit-tested. The loader runs on the background launchQueue, not the main actor. Ephemeral directory cleanup is idempotent. The sanitizedExtraArgs path correctly prevents any user-supplied flag from overriding the cmux-managed host, port, or connection-token arguments. Localization was audited: the app string catalog entries cover all 19 locales, and the schema description keys for non-en/ja locales use the established deep-merge-fallback-to-en pattern already present for canvas, fileEditor, and other sections. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[VSCodeServeWebController.launchServeWebProcess\non launchQueue background] --> B[InlineVSCodeServeWebConfigurationLoader\nreads live cmux.json]
B --> C{inlineVSCode block\nin cmux.json?}
C -- yes --> D[InlineVSCodeConfigFileValues\nwith presence-aware optionals]
C -- no --> E[InlineVSCodeConfigFileValues.empty]
D --> F[InlineVSCodeServeWebOptionsResolver.resolve]
E --> F
F --> G{Field present\nin file?}
G -- yes --> H[Use file value]
G -- no --> I{Env var set?}
I -- yes --> J[Use env var value]
I -- no --> K[Use internal default]
H --> L[InlineVSCodeServeWebOptions]
J --> L
K --> L
L --> M[serveWebArguments builds Process.arguments]
M --> N[sanitizedExtraArgs strips reserved flags]
N --> O[Process launched 127.0.0.1 + connection-token always enforced]
O --> P{persistServeWebState?}
P -- false, no serverDataDir --> Q[makeEphemeralServerDataDir UUID temp dir]
P -- true or explicit dir --> R[persistent / explicit --server-data-dir]
Q --> S[Process terminates]
R --> S
S --> T[removeEphemeralServerDataDir cleans up UUID temp dir]
%%{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"}}}%%
flowchart TD
A[VSCodeServeWebController.launchServeWebProcess\non launchQueue background] --> B[InlineVSCodeServeWebConfigurationLoader\nreads live cmux.json]
B --> C{inlineVSCode block\nin cmux.json?}
C -- yes --> D[InlineVSCodeConfigFileValues\nwith presence-aware optionals]
C -- no --> E[InlineVSCodeConfigFileValues.empty]
D --> F[InlineVSCodeServeWebOptionsResolver.resolve]
E --> F
F --> G{Field present\nin file?}
G -- yes --> H[Use file value]
G -- no --> I{Env var set?}
I -- yes --> J[Use env var value]
I -- no --> K[Use internal default]
H --> L[InlineVSCodeServeWebOptions]
J --> L
K --> L
L --> M[serveWebArguments builds Process.arguments]
M --> N[sanitizedExtraArgs strips reserved flags]
N --> O[Process launched 127.0.0.1 + connection-token always enforced]
O --> P{persistServeWebState?}
P -- false, no serverDataDir --> Q[makeEphemeralServerDataDir UUID temp dir]
P -- true or explicit dir --> R[persistent / explicit --server-data-dir]
Q --> S[Process terminates]
R --> S
S --> T[removeEphemeralServerDataDir cleans up UUID temp dir]
Reviews (11): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile |
…eepy Mode sections Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reserved extraArgs Resolves the autoreview + Greptile findings on the Inline VS Code serve-web options: - Replace the two caseless-enum namespaces with constructor-injected structs (cmux no-ambient-global-state policy): InlineVSCodeServeWebOptionsResolver now takes environment + home directory; a new InlineVSCodeServeWebConfigurationLoader owns the cmux.json read + ephemeral-dir factory; the serve-web argument builder moves onto InlineVSCodeServeWebOptions. - Non-persistent mode never silently reverts to persistent storage: the ephemeral data directory is a unique per-launch temp path that serve-web creates if missing, so a filesystem hiccup can't turn "don't persist" into persisted sign-in/state. - extraArgs can no longer override cmux's loopback/token invariants: cmux-owned flags (--host, --port, --connection-token[-file], --server-data-dir, --without-connection-token, --accept-server-license-terms) are stripped before the user flags are appended, in both the --flag value and --flag=value forms. Docs/schema/strings updated to match (extraArgs no longer "verbatim"); tests cover the sanitizer and the non-persistent guarantee. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…, safe ephemeral dirs - Settings UI: port and server data directory drafts now commit on focus loss (and Return), not only on Return, so edits aren't silently dropped when the user tabs/clicks away or closes the window. Unified the three fields under one @focusstate and commit the field that lost focus. - cmux.json reader is now tolerant per-field: each inlineVSCode key is decoded independently (via JSONSerialization with strict number/boolean typing), so one malformed value (e.g. a quoted "port") no longer discards valid sibling fields — a typo can't drop a valid persistServeWebState:false privacy choice. - Ephemeral serve-web data dirs no longer wipe the shared temp parent. Each non-persistent launch gets a unique UUID dir and never deletes siblings, so one cmux instance can't recursively remove a directory another instance's running serve-web is using. Freshness (non-persistence) comes from the per-launch UUID. Tests updated: per-field tolerance, number/boolean strictness, and ephemeral-dir uniqueness/non-deletion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n teardown The non-persistent ephemeral data directory is now tied to the launched serve-web process lifecycle: the unique per-launch dir is captured and removed in the process termination handler (covering normal exit, stop(), and restart) and on the launch-failure path. Only that specific per-launch UUID directory is removed, so a sibling cmux instance's running serve-web directory is never touched. This bounds disk usage for persistServeWebState: false instead of leaking a directory under the temp root on every restart. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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 `@cmuxTests/InlineVSCodeServeWebOptionsTests.swift`:
- Around line 219-225: Several tests in InlineVSCodeServeWebOptionsTests still
use try! with `#require`, which bypasses Swift Testing’s structured failure
reporting. Update the affected `@Test` functions to be throws tests and replace
each try! `#require` with try `#require` in the assertions around args(),
firstIndex(of:), and the related result checks so failures are reported through
Swift Testing instead of trapping.
In
`@Packages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry`+Default.swift:
- Around line 181-209: The Inline VS Code aliases are hard-coded English in
CuratedSettingEntry+Default, so non-English locales miss the extra search terms.
Move the alias strings for the .inlineVSCode entries (including persist-state,
port, server-data-dir, and extra-args) into localized resources, and wire them
up through the existing localization pattern used by the section entries. In the
same change, update the .inlineVSCode searchKeywords branch in SettingsSectionID
so it returns localized keywords/aliases consistently with the localized title
and symbol text. Keep the new behavior aligned with the other localized settings
cases in CuratedSettingEntry and SettingsSectionID.
🪄 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: 2760752e-0dac-41d8-bf8f-06fe9f71ca81
⛔ Files ignored due to path filters (1)
.github/swift-file-length-budget.tsvis excluded by!**/*.tsv
📒 Files selected for processing (16)
Packages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/InlineVSCodeCatalogSection.swiftPackages/macOS/CmuxSettings/Sources/CmuxSettings/Keys/SettingCatalog.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/CuratedSettingEntry+Default.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Navigation/SettingsSectionID.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Scene/SettingsWindowScene.swiftPackages/macOS/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/InlineVSCodeSection.swiftPackages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swiftResources/Localizable.xcstringsSources/App/InlineVSCodeServeWebOptions.swiftSources/App/TerminalDirectoryOpenSupport.swiftcmux.xcodeproj/project.pbxprojcmuxTests/InlineVSCodeServeWebOptionsTests.swiftweb/app/[locale]/docs/configuration/page.tsxweb/data/cmux.schema.jsonweb/messages/en.jsonweb/messages/ja.json
A fractional inlineVSCode.port (e.g. 1.9) is now treated as absent and falls back to the default random port, matching the schema (type: integer), the Settings UI parser, and CmuxSettings' Int.decodeFromJSON — rather than silently truncating to a different bound port. Integral floats (8123.0) are still accepted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…per-file Per the cmux file/API discipline rule for new Swift code, split the four top-level types out of InlineVSCodeServeWebOptions.swift into their own files: InlineVSCodeServeWebOptions, InlineVSCodeConfigFileValues, InlineVSCodeServeWebOptionsResolver, and InlineVSCodeServeWebConfigurationLoader. Each keeps only its tightly-bound private helpers. Wired the three new files into the cmux target in project.pbxproj. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e helpers - Add Swift-DocC comments to the new public package symbols (InlineVSCodeSection init/body, InlineVSCodeCatalogSection init). - Replace the nested focus enum with three @focusstate bools so the section file holds a single major type (file-organization policy). - Make the section's pure draft-parsing helpers (parsePort/portText/ parseExtraArgs) instance methods on the owning view instead of static, clearing the static-as-namespace policy flag. No behavior change. cmux-policy-check now reports no findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review iteration summaryDrove this through several automated-review rounds (Codex/autoreview + Greptile + cmux-policy). Fixes pushed:
One autoreview finding consciously rejected as a false positive: "add |
This comment has been minimized.
This comment has been minimized.
…gs-for-inline-vs-code # Conflicts: # .github/swift-file-length-budget.tsv # Packages/macOS/CmuxSettingsUI/Tests/CmuxSettingsUITests/SettingsRowAnchorResolutionTests.swift # cmux.xcodeproj/project.pbxproj
| } | ||
| }, |
There was a problem hiding this comment.
Missing locale translations for 18 supported app locales
The catalog supports 20 locales (ar, bs, da, de, en, es, fr, it, ja, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant), but every new entry added by this PR only provides en and ja. The 11 new string keys — settings.section.inlineVSCode, settings.inlineVSCode.persistState, settings.inlineVSCode.port, settings.inlineVSCode.port.subtitle, settings.inlineVSCode.port.placeholder, settings.inlineVSCode.serverDataDir, settings.inlineVSCode.serverDataDir.subtitle, settings.inlineVSCode.serverDataDir.placeholder, settings.inlineVSCode.extraArgs, settings.inlineVSCode.extraArgs.subtitle, and settings.inlineVSCode.note — will fall back to English for all users on ar, bs, da, de, es, fr, it, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, and zh-Hant. Every other manually-translated entry in the catalog ships translated copies for all 20 locales.
Rule Used: Flag production user-facing text that is not fully... (source)
There was a problem hiding this comment.
Fixed in a92756d: expanded the inline VS Code app string catalog entries, including the newly localized search alias keys, to all 19 app locales (ar, bs, da, de, en, es, fr, it, ja, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant). Verified with python3 -m json.tool and a locale-coverage script.
— Claude Code
There was a problem hiding this comment.
Verified on current head 6726c4d: the Inline VS Code settings and search-alias xcstrings entries are present for all supported app locales. Local JSON coverage check reports inline_vs_code_keys=13, locales=19, missing=0. This was fixed in a92756d and preserved through the latest main merge.
— Claude Code
…gs-for-inline-vs-code
Fixes #6645
What
Exposes the Inline VS Code
serve-weblaunch details that were previously hard-coded in the launcher path, both incmux.jsonand the Settings UI. Adds aninlineVSCodeconfig block:persistServeWebStateserve-webstate (sign-in, Settings Sync) across launches. Defaulttrue;falseuses a throwaway data dir so nothing persists.portserve-webport. Default0= random free port.serverDataDirserve-web--server-data-dir. Empty = VS Code default; leading~expands.extraArgsserve-webflags, appended verbatim.{ "inlineVSCode": { "persistServeWebState": true, "port": 8123, "serverDataDir": "~/Library/Application Support/cmux/vscode-serve-web", "extraArgs": [] } }Precedence
cmux.json(also written by the Settings UI) > environment variable (CMUX_INLINE_VSCODE_PORT/_SERVER_DATA_DIR/_PERSIST_STATE/_EXTRA_ARGS) > internal defaults.Defaults preserve the historical behavior (random port, VS Code default data location, persistent state) — this change is purely additive.
Design notes
VSCodeServeWebController) reads the live globalcmux.jsonon each (re)start via a single shared path, so there is no second way to start VS Code. "Restart Inline VS Code" applies changes immediately.serve-webis always bound to127.0.0.1with a connection-token file;extraArgsare appended after the cmux-managed flags and documented as advanced/unsupported.cmux.jsonreader are pure and unit-tested (cmuxTests/InlineVSCodeServeWebOptionsTests.swift).Surfaces touched
Sources/App/InlineVSCodeServeWebOptions.swift(new) +TerminalDirectoryOpenSupport.swift(net-neutral wiring).InlineVSCodeCatalogSection(CmuxSettings) +InlineVSCodeSectionUI (CmuxSettingsUI), section nav, curated search entries.cmux.schema.json, configuration docs page,web/messages/en.json+ja.json.Resources/Localizable.xcstrings(en + ja).Localization audit
All new user-facing Swift strings use
String(localized:)with matchingen+jaentries inLocalizable.xcstrings. Schema descriptions carrydescriptionKeys withen+jain the web message catalogs; the other 18 locales deep-merge-fall-back toen(existingi18n/request.tsbehavior, matchingmarkdown/canvas/workspaceGroups).🤖 Generated with Claude Code
Summary by cubic
Adds configurable Inline VS Code
serve-weboptions (port, server data dir, persistence, extra args) incmux.jsonand the Settings UI. Fixes #6645 while keeping loopback + token invariants and cleaning up per‑launch temp dirs when non‑persistent.New Features
inlineVSCodeconfig:persistServeWebState,port(0 = random),serverDataDir(supports~),extraArgs.cmux.json> env (CMUX_INLINE_VSCODE_*) > defaults; read at each start; use “Restart Inline VS Code” to apply now.127.0.0.1with a connection token; strips cmux-owned flags fromextraArgsto prevent overrides.Bug Fixes
inlineVSCode.portincmux.jsonrejects fractional numbers instead of truncating (e.g.,1.9ignored;8123.0accepted).Written for commit 6726c4d. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes