Skip to content

Add editable reusable parameters to workspace layouts - #8085

Closed
austinywang wants to merge 20 commits into
mainfrom
issue-8059-parameterized-workspace-layouts
Closed

austinywang wants to merge 20 commits into
mainfrom
issue-8059-parameterized-workspace-layouts

Conversation

@austinywang

@austinywang austinywang commented Jul 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #8059

Related: #6557, #6898

Summary

  • add {{name}} and {{name=default}} substitution across workspace and surface names, paths, environment values, setup commands, terminal commands, and browser URLs
  • let a workspace definition opt in with params, whose saved values are reused automatically every time the layout opens
  • add an explicit editor at New Workspace → Manage Layouts → Edit Layout Parameters → … for global inline workspace actions
  • launch parameterized layouts immediately with saved values; normal UI launches never interrupt the user with a parameter prompt
  • preserve CLI/socket overrides with repeatable --param and v2 template_params, including atomic missing-value validation before workspace mutation

UX and ownership

params is the reusable source of truth. Selecting a configured layout from the plus menu, Command Palette, surface action, or saved-layout menu resolves and launches it immediately. Editing happens only when the user chooses the explicit Manage Layouts editor, where fields are prefilled and Save Changes atomically updates actions.<id>.workspace.params in the global cmux.json while preserving JSONC comments and surrounding formatting.

Project-local actions, workspaceCommand definitions, and ~/.config/cmux/layouts.json entries remain source-owned and are edited in their configuration files. Missing required values abort the whole launch and explain where to edit them.

Definitions without params retain literal {{...}} text for backward compatibility.

Resolution model

Precedence, highest first:

  1. explicit --param / template_params
  2. saved workspace params
  3. literal same-named workspace env values
  4. the cmux app process environment
  5. inline placeholder defaults

Values are non-recursive. Workspace definitions substitute literal values because a parameter may represent a path, URL, title, environment value, or command fragment.

Validation

  • red regression commit e8fe3b3ea2: 15 tests ran, with the new no-prompt test failing because the old code displayed a sheet and created no workspace
  • green merged-HEAD cloud run issue-8059-explicit-editor-green-pushed-16bff0fa177b: 60/60 tests passed across action execution, parameter persistence, menu rendering, editor sizing, and saved layouts
  • final pushed HEAD 341a9e752d: 15/15 CmuxConfigWorkspaceActionTests passed in run issue-8059-explicit-editor-green-pushed-34c414ff84ca
  • CmuxFoundation and CmuxControlSocket focused suites passed
  • pbxproj normalization, all 511 test-file wiring checks, workspace package grouping, diff checks, schema/catalog parsing, localization parity, and rich-tag/placeholder audits passed
  • the Package.resolved policy script currently reports ios/cmux.xcworkspace/xcshareddata/swiftpm/Package.resolved, an upstream file added by current main; this PR does not modify that file

Localization was audited across the app string catalog and all 20 web catalogs. Every changed key is present in every supported locale, and rich-text tags/placeholders match English.

@vercel

vercel Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jul 15, 2026 4:13pm
cmux-staging Building Building Preview, Comment Jul 15, 2026 4:13pm

@coderabbitai

coderabbitai Bot commented Jul 14, 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 reusable workspace template variables with precedence-based resolution across workspace definitions, saved layouts, CLI commands, socket APIs, and launch flows. Repeatable --param values, structured missing-parameter errors, schema updates, tests, localization, and documentation are included.

Changes

Workspace template parameterization

Layer / File(s) Summary
Template engine and definition contract
Packages/macOS/CmuxFoundation/..., Sources/CmuxWorkspaceDefinition*, Packages/macOS/CmuxFoundation/Tests/...
Adds template parsing, escaping, validation, precedence resolution, missing-variable errors, workspace defaults, and unit coverage.
Workspace resolution and launch integration
Sources/CmuxWorkspaceDefinition+Parameterization.swift, Sources/TabManager+SavedLayouts.swift, Sources/TerminalController+WorkspaceCreate.swift, Sources/CmuxConfigExecutor*, Sources/*SavedLayout*
Resolves workspace and nested layout fields before creation, saved-layout opening, configured command execution, and interactive parameter prompting.
CLI parameter parsing and forwarding
CLI/*, cmuxTests/CLIWorkspaceTemplateParameterTests.swift
Adds repeatable --param parsing, environment imports, command forwarding, layout forwarding, help text, and integration tests.
Socket contract and structured errors
Packages/macOS/CmuxControlSocket/..., Sources/TerminalController+ControlLayoutContext.swift
Validates string-valued template_params, forwards them through layout control, and returns structured missing_parameters errors.
Schema, documentation, localization, and wiring
web/data/cmux.schema.json, docs/cli-contract.md, web/app/..., web/messages/*, Resources/Localizable.xcstrings, cmux.xcodeproj/project.pbxproj
Documents parameterized layouts, updates schemas and localized strings, and wires new Swift sources into the project.

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

Possibly related PRs

  • manaflow-ai/cmux#7414: Extends the saved-layout and layout.open control flow that accepts and resolves template_params.
  • manaflow-ai/cmux#8150: Adds related saved-layout workspace setup handling through CmuxWorkspaceDefinition.setupCommand.

Suggested reviewers: lawrencecchen


Important

Pre-merge checks failed

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

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error New Swift catalog keys only have en/ja in Resources/Localizable.xcstrings despite 20 app locales, and the new V2 template error message is raw English. Add translations for all 20 locales in the touched string catalog and localize the new V2 template error messages through a locale-aware source before returning them.
Docstring Coverage ⚠️ Warning Docstring coverage is 23.21% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (23 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes implement #8059’s layout parameterization, defaults, CLI and socket params, missing-parameter errors, and preflighted resolution.
Out of Scope Changes check ✅ Passed The added docs, localization, tests, and UI wiring all support the parameterization feature and do not appear unrelated.
Cmux Swift Actor Isolation ✅ Passed New template types are plain Sendable structs; UI helpers are intentionally @MainActor, and the layout/workspace paths already run on MainActor.
Cmux Swift Blocking Runtime ✅ Passed Touched Swift diffs add parsing/UI flow only; no new semaphores, sleeps, asyncAfter, locks, or main-sync wrappers were introduced.
Cmux Browser Automation Off-Main ✅ Passed PASS: The PR only changes workspace/layout parameterization; no browser.* socket commands, worker routing, WebKit waits, or policy tests were touched.
Cmux Expensive Synchronous Load ✅ Passed Touched interactive/socket paths only parse templates and saved-layout JSON; no RestorableAgentSessionIndex.load, transcript/JSONL scans, or SharedLiveAgentIndex calls were added.
Cmux Cache Substitution Correctness ✅ Passed The commit only adds workspace parameterization and shell-input plumbing; I found no cache/history/undo/snapshot read substitution or stale/cold-cache issue in the touched Swift files.
Cmux No Hacky Sleeps ✅ Passed HEAD^..HEAD only changes three Swift files; no TS/JS/shell/build-runtime diffs and no introduced waits/polling in non-Swift runtime code.
Cmux Algorithmic Complexity ✅ Passed The only new algorithmic code is the template scanner, and it remains linear in my stress test; the other edits are simple parameter plumbing/tests.
Cmux Swift Concurrency ✅ Passed No new DispatchQueue/Combine/fire-and-forget Task patterns appear; the only new completion-handler API is an AppKit alert boundary.
Cmux Swift @Concurrent ✅ Passed No new @concurrent/nonisolated async issues: touched Swift helpers are synchronous or @MainActor, and the saved-layout UI path stays main-actor-bound.
Cmux Swift Package Boundaries ✅ Passed Core template parsing/resolution lives in CmuxFoundation; the app-target changes are thin TabManager/TerminalController/UI glue and endpoint composition.
Cmux Swiftpm Lockfiles ✅ Passed PR range only changes pbxproj file wiring and source files; no Package.resolved, Package.swift, .gitignore, workflow, or SwiftPM package-reference edits are present.
Cmux Swift Logging ✅ Passed No production Swift logging violations found: changed runtime files add no print/debugPrint/dump/NSLog or new Logger declarations.
Cmux User-Facing Error Privacy ✅ Passed New user-facing errors are generic and only mention public template params/help text; no vendor names, secrets, raw upstream errors, or private payloads leak.
Cmux Swiftui State Layout ✅ Passed Touched SwiftUI-facing files add only AppKit bridge/helpers; no new ObservableObject/@Published/GeometryReader/lazy-row store refs, or render-time state writes.
Cmux Architecture Rethink ✅ Passed PASS: The new launch/template flow is centralized in shared helpers; I found no new sleeps, polling, observers, duplicate entrypoints, or split UI owners in the touched Swift.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The new UI is NSAlert-based sheet/modal prompting, not a standalone NSWindow/NSPanel; no changed file adds a new cmux.* window ID or auxiliary-window registration.
Cmux Source Artifacts ✅ Passed All changed paths are intentional source/docs/tests/localization/config; no temp, build, cache, or artifact dirs appeared in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The only production diff adds normal workspace-create plumbing; it introduces no #if DEBUG blocks, test-only members, or wrapper seams.
Cmux No Ambient Global State ✅ Passed Changed production Swift files add only instance methods/value types and one static help string; no new top-level API, mutable globals, or shared/default singletons were introduced.
Title check ✅ Passed The title clearly summarizes the main change: editable reusable workspace parameters.
Description check ✅ Passed The description covers summary, UX, precedence, and validation details, with only some optional template sections omitted.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-8059-parameterized-workspace-layouts

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 14, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds launch-time {{name}}/{{name=default}} parameterization across workspace and surface string fields (names, cwd, env values, setup, commands, browser URLs), backed by a shared CmuxTemplateResolver in CmuxFoundation with a documented five-tier precedence chain. The feature is opt-in via a new params block on the workspace definition, fully backward-compatible with existing layouts, and exercised end-to-end via CLI --param, socket template_params, and a new "Edit Layout Parameters" app UI.

  • New CmuxFoundation types (CmuxTemplate, CmuxTemplateResolver, CmuxTemplateVariable, CmuxTemplateParameterInput) provide a standalone, Sendable, testable grammar layer reusable by future surfaces.
  • Socket protocol additions for workspace.create and layout.open validate that template_params is a string-to-string object and return a structured missing_parameters error \u2014 preflight runs before any workspace state is mutated so a missing value cannot leave a partially-created workspace.
  • App UI adds a \u201cManage Layouts \u2192 Edit Layout Parameters\u201d submenu for global inline actions, backed by WorkspaceActionParameterEditor and persisted via CmuxConfigActionSaver.updateWorkspaceActionParameters; web docs, schema, and all 20 locale message files are updated in the same PR.

Confidence Score: 5/5

Safe to merge — preflight resolution is atomic, backward compatibility is correctly gated, and the new socket contract is validated before reaching app state.

The core template grammar, resolver, and workspace parameterization logic are well-structured and tested. Two minor code quality issues exist in CmuxConfigActionSaver: a dead guard-let branch that can never fire, and a compound guard that would surface a misleading error message if JSON parsing fails after config validation has already passed. WorkspaceTemplateErrorPresenter reuses the missing-parameters title key for its generic error branch. None of these affect current runtime correctness.

Sources/CmuxConfigActionSaver.swift (dead guard and misleading error attribution) and Sources/WorkspaceTemplateErrorPresenter.swift (shared title key across both error branches).

Important Files Changed

Filename Overview
Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplate.swift New pure-value type implementing the {{name}}/{{name=default}} template grammar with escape support; parser is linear, reserves capacity, and uses Array for O(1) indexed access.
Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateResolver.swift New Sendable struct implementing the five-tier precedence chain (explicit → params → workspace env → process env → inline default); resolves atomically and collects all missing names before throwing.
Sources/CmuxWorkspaceDefinition+Parameterization.swift Adds opt-in template resolution to CmuxWorkspaceDefinition; correctly gates on params != nil
Sources/TabManager+SavedLayouts.swift Converts openWorkspace(fromSavedLayout:) from returning Workspace? to throwing; adds openSavedLayout convenience wrapper for all menu/command call sites with proper error presentation.
Sources/TerminalController+WorkspaceCreate.swift Adds template_params parsing and resolution for workspace.create socket command; correctly validates that template_params is a string-to-string object and skips resolution when no params are provided.
Sources/CmuxConfigActionSaver.swift Adds updateWorkspaceActionParameters to persist params edits; has a dead guard let (always succeeds), and a compound guard that misattributes parse errors as actionNotFound.
Sources/WorkspaceTemplateErrorPresenter.swift New alert presenter for template errors; reuses the missingParameters.title key for the generic failure branch, so title and body would disagree if a non-missingVariables error reaches present(_:).
Sources/NewWorkspaceMenuModel.swift Adds editableActions computation using empty process environment for the menu filter — correct for display purposes; the editor itself uses the real environment.
Sources/WorkspaceActionParameterEditor.swift New @mainactor NSAlert-based editor for inline workspace layout params; correctly uses real process environment and calls beginSheetModal for async presentation.
Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlCommandCoordinator+Layout.swift Adds template_params validation and forwarding for layout.open socket command; correctly handles missingParameters resolution in the response switch.
CLI/CMUXCLI+WorkspaceTemplateParameters.swift New CLI file adding --param parsing for workspace create and layout open commands; correctly handles KEY=VALUE and bare KEY (shell import) forms.
web/data/cmux.schema.json Adds workspaceDefinition, workspaceTemplateParams, workspaceLayoutNode, and workspaceSurfaceDefinition $defs with full property schemas; refs are consistent across actions and commands.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Launch trigger"] --> B{"params present or explicit params?"}
    B -- No --> C["Pass definition through unchanged"]
    B -- Yes --> D["CmuxTemplateResolver.resolvedValues()"]
    D --> E{"All variables resolved?"}
    E -- No --> F["throw missingVariables"]
    E -- Yes --> G["substitutingTemplateValues() atomically"]
    G --> H["Create workspace"]
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"}}}%%
flowchart TD
    A["Launch trigger"] --> B{"params present or explicit params?"}
    B -- No --> C["Pass definition through unchanged"]
    B -- Yes --> D["CmuxTemplateResolver.resolvedValues()"]
    D --> E{"All variables resolved?"}
    E -- No --> F["throw missingVariables"]
    E -- Yes --> G["substitutingTemplateValues() atomically"]
    G --> H["Create workspace"]
Loading

Reviews (9): Last reviewed commit: "Remove stale workspace prompt binding" | Re-trigger Greptile

Comment thread Resources/Localizable.xcstrings

@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

Caution

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

⚠️ Outside diff range comments (1)
Sources/AppDelegate+SavedLayoutMenu.swift (1)

54-77: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Bind and reuse the resolved window instead of discarding it.

The guard confirms resolvedWindow(for: context) is non-nil but never captures it, so the catch block passes presentingWindow: nil to WorkspaceTemplateErrorPresenter. Per the presenter's own logic, a nil window forces a blocking NSAlert.runModal() instead of a sheet attached to the actual context-menu window — even though a valid window was just confirmed to exist.

🪟 Proposed fix: bind and pass the resolved window
-        guard let box = sender.representedObject as? SavedLayoutContextMenuActionBox,
-              let context = mainWindowContexts.values.first(where: { $0.windowId == box.windowId }),
-              resolvedWindow(for: context) != nil else {
+        guard let box = sender.representedObject as? SavedLayoutContextMenuActionBox,
+              let context = mainWindowContexts.values.first(where: { $0.windowId == box.windowId }),
+              let window = resolvedWindow(for: context) else {
             NSSound.beep()
             return
         }

         do {
             guard let layout = try SavedLayoutStore().layout(named: box.layoutName) else {
                 NSSound.beep()
                 return
             }
             _ = try context.tabManager.openWorkspace(
                 fromSavedLayout: layout,
                 cwdOverride: nil,
                 focus: true
             )
         } catch let error as CmuxTemplateResolutionError {
-            WorkspaceTemplateErrorPresenter(presentingWindow: nil).present(error)
+            WorkspaceTemplateErrorPresenter(presentingWindow: window).present(error)
         } catch {
             NSSound.beep()
         }
🤖 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/AppDelegate`+SavedLayoutMenu.swift around lines 54 - 77, Update
performSavedLayoutContextMenuItem to bind the non-nil result of
resolvedWindow(for: context) in its guard, then pass that resolved window to
WorkspaceTemplateErrorPresenter in the CmuxTemplateResolutionError catch instead
of nil. Preserve the existing validation and error-handling behavior.
🤖 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 `@Resources/Localizable.xcstrings`:
- Line 43802: Update the layout help localization value for the cmux layout
usage text: remove the unsupported “export” subcommand from the description, and
document that layout open accepts bare --param KEY arguments alongside the
existing KEY=VALUE syntax. Keep the listed implemented subcommands and examples
aligned with the actual CLI contract.

In `@web/messages/ja.json`:
- Line 1815: Update the Japanese translation for parameterizedLayoutsCLI to
state that the value-less --param KEY form reads an exported environment
variable, replacing the current wording that refers to a shell variable while
preserving the rest of the message.

---

Outside diff comments:
In `@Sources/AppDelegate`+SavedLayoutMenu.swift:
- Around line 54-77: Update performSavedLayoutContextMenuItem to bind the
non-nil result of resolvedWindow(for: context) in its guard, then pass that
resolved window to WorkspaceTemplateErrorPresenter in the
CmuxTemplateResolutionError catch instead of nil. Preserve the existing
validation and error-handling behavior.
🪄 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: b357281d-19f8-4fbe-965d-818b32ac1cbd

📥 Commits

Reviewing files that changed from the base of the PR and between 1c22c55 and 55431fc.

📒 Files selected for processing (50)
  • CLI/CMUXCLI+WorkspaceTemplateParameters.swift
  • CLI/cmux.swift
  • CLI/cmux_layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlCommandCoordinator+Layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlLayoutContext.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorLayoutTests.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlLayoutContextTestStubs.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplate.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateResolutionError.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateResolver.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateVariable.swift
  • Packages/macOS/CmuxFoundation/Tests/CmuxFoundationTests/CmuxTemplateTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate+SavedLayoutMenu.swift
  • Sources/CmuxConfigExecutor+WorkspaceParameterization.swift
  • Sources/CmuxConfigExecutor.swift
  • Sources/CmuxWorkspaceDefinition+Parameterization.swift
  • Sources/CmuxWorkspaceDefinition.swift
  • Sources/ContentView+SavedLayoutCommands.swift
  • Sources/TabManager+SavedLayouts.swift
  • Sources/TerminalController+ControlLayoutContext.swift
  • Sources/TerminalController+WorkspaceCreate.swift
  • Sources/TerminalController+WorkspaceTemplateParameters.swift
  • Sources/WorkspaceTemplateErrorPresenter.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CLIWorkspaceTemplateParameterTests.swift
  • cmuxTests/SavedLayoutDefinitionTests.swift
  • docs/cli-contract.md
  • web/app/[locale]/(landing)/docs/custom-commands/page.tsx
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json

Comment thread Resources/Localizable.xcstrings Outdated
Comment thread web/messages/ja.json Outdated
…-8059-parameterized-workspace-layouts

# Conflicts:
#	cmux.xcodeproj/project.pbxproj

@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/cmux.swift (1)

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

Translate the updated CLI strings in every supported locale

cli.workspace.create.error.unknownFlag, cli.layout.help, and cli.layout.open.error.unknownFlag are only translated in a subset of Resources/Localizable.xcstrings locales. Add the missing entries for the remaining supported locales (ar, bs, da, de, es, fr, it, km, nb, pl, pt-BR, ru, th, tr, zh-Hans, zh-Hant) so these new messages don’t fall back to English.

🤖 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/cmux.swift` at line 7473, Translate the updated CLI strings for
cli.workspace.create.error.unknownFlag in CLI/cmux.swift:7473-7473,
cli.layout.help in CLI/cmux_layout.swift:5-14, and
cli.layout.open.error.unknownFlag in CLI/cmux_layout.swift:139-153 by adding
entries for every missing supported locale: ar, bs, da, de, es, fr, it, km, nb,
pl, pt-BR, ru, th, tr, zh-Hans, and zh-Hant. Update
Resources/Localizable.xcstrings consistently so these keys have localized values
instead of falling back to English.

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.

Outside diff comments:
In `@CLI/cmux.swift`:
- Line 7473: Translate the updated CLI strings for
cli.workspace.create.error.unknownFlag in CLI/cmux.swift:7473-7473,
cli.layout.help in CLI/cmux_layout.swift:5-14, and
cli.layout.open.error.unknownFlag in CLI/cmux_layout.swift:139-153 by adding
entries for every missing supported locale: ar, bs, da, de, es, fr, it, km, nb,
pl, pt-BR, ru, th, tr, zh-Hans, and zh-Hant. Update
Resources/Localizable.xcstrings consistently so these keys have localized values
instead of falling back to English.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 94ade4d8-afd7-4596-b58c-31d2790e9d3d

📥 Commits

Reviewing files that changed from the base of the PR and between d851c7a and 32a225a.

📒 Files selected for processing (2)
  • CLI/cmux.swift
  • CLI/cmux_layout.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: 3

Caution

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

⚠️ Outside diff range comments (1)
Sources/CmuxWorkspaceDefinition+Parameterization.swift (1)

79-81: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer sorting dictionary elements directly.

Iterating over the dictionary's keys to perform a redundant optional lookup env?[key] is unidiomatic. You can directly sort the dictionary's elements and map the values, which is cleaner and avoids the lookup.

♻️ Proposed refactor
-        templates.append(contentsOf: (env ?? [:]).keys.sorted().compactMap { key in
-            env?[key].map(CmuxTemplate.init)
-        })
+        templates.append(contentsOf: (env ?? [:]).sorted(by: { $0.key < $1.key }).map { 
+            CmuxTemplate($0.value) 
+        })
🤖 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/CmuxWorkspaceDefinition`+Parameterization.swift around lines 79 - 81,
Update the template appending logic to sort the dictionary elements from env
directly, then map each element’s value into CmuxTemplate without iterating keys
or performing optional lookups. Preserve the existing empty/nil environment
behavior.
🤖 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 7482-7485: Update the parameter construction around cwdOpt so
params["caller_cwd"] is always set to FileManager.default.currentDirectoryPath,
while params["cwd"] remains conditional on an explicitly provided cwdOpt.

In `@Sources/TerminalController`+WorkspaceCreate.swift:
- Around line 139-156: The template resolution flow around
resolver.resolvedValues must run regardless of whether templateParameters is
empty. Remove the templateParameters.isEmpty() bypass, always resolve and
substitute templateDefinition, initialCommandTemplate, initialEnvTemplate, and
descriptionTemplate, while preserving workspaceTemplateResolutionFailure(error)
handling for resolution failures.

In `@web/messages/fr.json`:
- Around line 420-425: Update the French localization values for summary and
destinationsTitle to use consistent fork terminology such as “Dupliquez” or
“Forkez” instead of “Branchez”, while preserving the surrounding meaning and all
other translations unchanged.

---

Outside diff comments:
In `@Sources/CmuxWorkspaceDefinition`+Parameterization.swift:
- Around line 79-81: Update the template appending logic to sort the dictionary
elements from env directly, then map each element’s value into CmuxTemplate
without iterating keys or performing optional lookups. Preserve the existing
empty/nil environment behavior.
🪄 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: 872bc6a1-2dca-4b2e-bb28-7de4265380c9

📥 Commits

Reviewing files that changed from the base of the PR and between 32a225a and 882b012.

📒 Files selected for processing (46)
  • CLI/CMUXCLI+WorkspaceTemplateParameters.swift
  • CLI/cmux.swift
  • CLI/cmux_layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlCommandCoordinator+Layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlLayoutContext.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorLayoutTests.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlLayoutContextTestStubs.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateParameterInput.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateResolver.swift
  • Packages/macOS/CmuxFoundation/Tests/CmuxFoundationTests/CmuxTemplateTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate+SavedLayoutMenu.swift
  • Sources/CmuxConfigExecutor+WorkspaceParameterization.swift
  • Sources/CmuxConfigExecutor.swift
  • Sources/CmuxWorkspaceDefinition+Parameterization.swift
  • Sources/ContentView+SavedLayoutCommands.swift
  • Sources/TabManager+SavedLayouts.swift
  • Sources/TerminalController+ControlLayoutContext.swift
  • Sources/TerminalController+WorkspaceCreate.swift
  • Sources/WorkspaceTemplateParameterPrompt.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CLIWorkspaceTemplateParameterTests.swift
  • cmuxTests/SavedLayoutDefinitionTests.swift
  • cmuxTests/WorkspaceTemplateParameterPromptTests.swift
  • docs/cli-contract.md
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json
💤 Files with no reviewable changes (1)
  • CLI/CMUXCLI+WorkspaceTemplateParameters.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.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

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/CmuxWorkspaceDefinition+Parameterization.swift (1)

79-81: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer sorting dictionary elements directly.

Iterating over the dictionary's keys to perform a redundant optional lookup env?[key] is unidiomatic. You can directly sort the dictionary's elements and map the values, which is cleaner and avoids the lookup.

♻️ Proposed refactor
-        templates.append(contentsOf: (env ?? [:]).keys.sorted().compactMap { key in
-            env?[key].map(CmuxTemplate.init)
-        })
+        templates.append(contentsOf: (env ?? [:]).sorted(by: { $0.key < $1.key }).map { 
+            CmuxTemplate($0.value) 
+        })
🤖 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/CmuxWorkspaceDefinition`+Parameterization.swift around lines 79 - 81,
Update the template appending logic to sort the dictionary elements from env
directly, then map each element’s value into CmuxTemplate without iterating keys
or performing optional lookups. Preserve the existing empty/nil environment
behavior.
🤖 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 7482-7485: Update the parameter construction around cwdOpt so
params["caller_cwd"] is always set to FileManager.default.currentDirectoryPath,
while params["cwd"] remains conditional on an explicitly provided cwdOpt.

In `@Sources/TerminalController`+WorkspaceCreate.swift:
- Around line 139-156: The template resolution flow around
resolver.resolvedValues must run regardless of whether templateParameters is
empty. Remove the templateParameters.isEmpty() bypass, always resolve and
substitute templateDefinition, initialCommandTemplate, initialEnvTemplate, and
descriptionTemplate, while preserving workspaceTemplateResolutionFailure(error)
handling for resolution failures.

In `@web/messages/fr.json`:
- Around line 420-425: Update the French localization values for summary and
destinationsTitle to use consistent fork terminology such as “Dupliquez” or
“Forkez” instead of “Branchez”, while preserving the surrounding meaning and all
other translations unchanged.

---

Outside diff comments:
In `@Sources/CmuxWorkspaceDefinition`+Parameterization.swift:
- Around line 79-81: Update the template appending logic to sort the dictionary
elements from env directly, then map each element’s value into CmuxTemplate
without iterating keys or performing optional lookups. Preserve the existing
empty/nil environment behavior.
🪄 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: 872bc6a1-2dca-4b2e-bb28-7de4265380c9

📥 Commits

Reviewing files that changed from the base of the PR and between 32a225a and 882b012.

📒 Files selected for processing (46)
  • CLI/CMUXCLI+WorkspaceTemplateParameters.swift
  • CLI/cmux.swift
  • CLI/cmux_layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlCommandCoordinator+Layout.swift
  • Packages/macOS/CmuxControlSocket/Sources/CmuxControlSocket/Coordinator/Layout/ControlLayoutContext.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlCommandCoordinatorLayoutTests.swift
  • Packages/macOS/CmuxControlSocket/Tests/CmuxControlSocketTests/ControlLayoutContextTestStubs.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateParameterInput.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplateResolver.swift
  • Packages/macOS/CmuxFoundation/Tests/CmuxFoundationTests/CmuxTemplateTests.swift
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate+SavedLayoutMenu.swift
  • Sources/CmuxConfigExecutor+WorkspaceParameterization.swift
  • Sources/CmuxConfigExecutor.swift
  • Sources/CmuxWorkspaceDefinition+Parameterization.swift
  • Sources/ContentView+SavedLayoutCommands.swift
  • Sources/TabManager+SavedLayouts.swift
  • Sources/TerminalController+ControlLayoutContext.swift
  • Sources/TerminalController+WorkspaceCreate.swift
  • Sources/WorkspaceTemplateParameterPrompt.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CLIWorkspaceTemplateParameterTests.swift
  • cmuxTests/SavedLayoutDefinitionTests.swift
  • cmuxTests/WorkspaceTemplateParameterPromptTests.swift
  • docs/cli-contract.md
  • web/data/cmux.schema.json
  • web/messages/ar.json
  • web/messages/bs.json
  • web/messages/da.json
  • web/messages/de.json
  • web/messages/en.json
  • web/messages/es.json
  • web/messages/fr.json
  • web/messages/it.json
  • web/messages/ja.json
  • web/messages/km.json
  • web/messages/ko.json
  • web/messages/no.json
  • web/messages/pl.json
  • web/messages/pt-BR.json
  • web/messages/ru.json
  • web/messages/th.json
  • web/messages/tr.json
  • web/messages/uk.json
  • web/messages/zh-CN.json
  • web/messages/zh-TW.json
💤 Files with no reviewable changes (1)
  • CLI/CMUXCLI+WorkspaceTemplateParameters.swift
🛑 Comments failed to post (3)
CLI/cmux.swift (1)

7482-7485: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Send caller_cwd unconditionally for accurate template path resolution.

When --cwd is omitted but a layout or default template parameter specifies a relative path for the working directory, the server relies on caller_cwd to resolve it against the CLI's invocation directory. By scoping caller_cwd inside the if let cwdOpt block, omitted --cwd flags will cause relative paths to silently resolve against the server's fallback directory (usually ~) instead of the current working directory.

💡 Proposed fix
+        params["caller_cwd"] = FileManager.default.currentDirectoryPath
         if let cwdOpt {
             params["cwd"] = cwdOpt
-            params["caller_cwd"] = FileManager.default.currentDirectoryPath
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        params["caller_cwd"] = FileManager.default.currentDirectoryPath
        if let cwdOpt {
            params["cwd"] = cwdOpt
        }
🤖 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/cmux.swift` around lines 7482 - 7485, Update the parameter construction
around cwdOpt so params["caller_cwd"] is always set to
FileManager.default.currentDirectoryPath, while params["cwd"] remains
conditional on an explicitly provided cwdOpt.
Sources/TerminalController+WorkspaceCreate.swift (1)

139-156: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Do not skip resolution when explicit parameters are empty.

This branch leaves process-environment and inline-default placeholders literal, and lets missing required values reach workspace creation. Always preflight and substitute the templates; explicit parameters are only the highest-precedence source, not the feature gate.

Proposed fix
-        if templateParameters.isEmpty {
-            resolvedDefinition = templateDefinition
-            initialCommand = initialCommandTemplate
-            initialEnv = initialEnvTemplate
-            description = descriptionTemplate
-        } else {
-            do {
-                let values = try resolver.resolvedValues(
-                    for: templateDefinition.templateStrings + additionalTemplates
-                )
-                resolvedDefinition = templateDefinition.substitutingTemplateValues(values)
-                initialCommand = initialCommandTemplate.map { CmuxTemplate($0).substituting(values) }
-                initialEnv = initialEnvTemplate.mapValues { CmuxTemplate($0).substituting(values) }
-                description = descriptionTemplate.map { CmuxTemplate($0).substituting(values) }
-            } catch {
-                return workspaceTemplateResolutionFailure(error)
-            }
+        do {
+            let values = try resolver.resolvedValues(
+                for: templateDefinition.templateStrings + additionalTemplates
+            )
+            resolvedDefinition = templateDefinition.substitutingTemplateValues(values)
+            initialCommand = initialCommandTemplate.map { CmuxTemplate($0).substituting(values) }
+            initialEnv = initialEnvTemplate.mapValues { CmuxTemplate($0).substituting(values) }
+            description = descriptionTemplate.map { CmuxTemplate($0).substituting(values) }
+        } catch {
+            return workspaceTemplateResolutionFailure(error)
         }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

        do {
            let values = try resolver.resolvedValues(
                for: templateDefinition.templateStrings + additionalTemplates
            )
            resolvedDefinition = templateDefinition.substitutingTemplateValues(values)
            initialCommand = initialCommandTemplate.map { CmuxTemplate($0).substituting(values) }
            initialEnv = initialEnvTemplate.mapValues { CmuxTemplate($0).substituting(values) }
            description = descriptionTemplate.map { CmuxTemplate($0).substituting(values) }
        } catch {
            return workspaceTemplateResolutionFailure(error)
        }
🤖 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/TerminalController`+WorkspaceCreate.swift around lines 139 - 156, The
template resolution flow around resolver.resolvedValues must run regardless of
whether templateParameters is empty. Remove the templateParameters.isEmpty()
bypass, always resolve and substitute templateDefinition,
initialCommandTemplate, initialEnvTemplate, and descriptionTemplate, while
preserving workspaceTemplateResolutionFailure(error) handling for resolution
failures.
web/messages/fr.json (1)

420-425: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use French fork terminology instead of “Branchez”.

“Branchez une conversation” means connecting or plugging it in, not creating a conversation fork. Use a consistent term such as “Dupliquez” or “Forkez” in the summary and destination heading.

🤖 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 `@web/messages/fr.json` around lines 420 - 425, Update the French localization
values for summary and destinationsTitle to use consistent fork terminology such
as “Dupliquez” or “Forkez” instead of “Branchez”, while preserving the
surrounding meaning and all other translations unchanged.

@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)
Sources/TerminalController+WorkspaceCreate.swift (1)

137-161: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Always resolve templates to support environment variables, inline defaults, and catch missing variables consistently.

The check if templateParameters.isEmpty bypasses template resolution entirely when no explicit parameters are passed in the request. This prevents process environment variables (e.g., {{HOME}}) and inline defaults (e.g., {{port=8080}}) from resolving, and causes inconsistent validation behavior where missing placeholders are silently ignored if no parameters are passed.

To fix this, check if the templates actually contain variables instead of relying on the templateParameters payload size.

🐛 Proposed fix
         let resolvedDefinition: CmuxWorkspaceDefinition
         let initialCommand: String?
         let initialInput: String?
         let initialEnv: [String: String]
         let description: String?
-        if templateParameters.isEmpty {
+        let allTemplates = templateDefinition.templateStrings + additionalTemplates
+        
+        if !allTemplates.contains(where: \.containsVariables) {
             resolvedDefinition = templateDefinition
             initialCommand = initialCommandTemplate
             initialInput = initialInputTemplate
             initialEnv = initialEnvTemplate
             description = descriptionTemplate
         } else {
             do {
-                let values = try resolver.resolvedValues(
-                    for: templateDefinition.templateStrings + additionalTemplates
-                )
+                let values = try resolver.resolvedValues(for: allTemplates)
                 resolvedDefinition = templateDefinition.substitutingTemplateValues(values)
                 initialCommand = initialCommandTemplate.map { CmuxTemplate($0).substituting(values) }
                 initialInput = initialInputTemplate.map { CmuxTemplate($0).substituting(values) }
                 initialEnv = initialEnvTemplate.mapValues { CmuxTemplate($0).substituting(values) }
                 description = descriptionTemplate.map { CmuxTemplate($0).substituting(values) }
             } catch {
                 return workspaceTemplateResolutionFailure(error)
             }
         }
🤖 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/TerminalController`+WorkspaceCreate.swift around lines 137 - 161,
Update the branching around template resolution to determine whether the
combined templates contain variables, rather than checking
templateParameters.isEmpty. Always invoke resolver.resolvedValues when
templateDefinition, command, input, environment, or description templates
contain placeholders, including environment variables and inline defaults;
retain the direct-value path only when no templates require resolution, and
preserve workspaceTemplateResolutionFailure(error) handling.
🤖 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 `@Sources/TerminalController`+WorkspaceCreate.swift:
- Around line 137-161: Update the branching around template resolution to
determine whether the combined templates contain variables, rather than checking
templateParameters.isEmpty. Always invoke resolver.resolvedValues when
templateDefinition, command, input, environment, or description templates
contain placeholders, including environment variables and inline defaults;
retain the direct-value path only when no templates require resolution, and
preserve workspaceTemplateResolutionFailure(error) handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0027434c-6fc9-4940-83b6-2635d4cdbbb0

📥 Commits

Reviewing files that changed from the base of the PR and between 882b012 and 3e7322b.

📒 Files selected for processing (5)
  • CLI/cmux.swift
  • Packages/macOS/CmuxFoundation/Sources/CmuxFoundation/ConfigValues/Template/CmuxTemplate.swift
  • Packages/macOS/CmuxFoundation/Tests/CmuxFoundationTests/CmuxTemplateTests.swift
  • Sources/TerminalController+WorkspaceCreate.swift
  • cmuxTests/CLIWorkspaceTemplateParameterTests.swift

@austinywang
austinywang force-pushed the issue-8059-parameterized-workspace-layouts branch 3 times, most recently from b976f19 to 01d22d1 Compare July 15, 2026 23:50
@austinywang
austinywang force-pushed the issue-8059-parameterized-workspace-layouts branch from 01d22d1 to e8fe3b3 Compare July 16, 2026 00:12
@cursor

cursor Bot commented Jul 16, 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.

@austinywang austinywang changed the title Parameterize workspace layouts at launch time Add editable reusable parameters to workspace layouts Jul 16, 2026
@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: parameterize workspace layouts (template variables / params / env expansion)

3 participants