Skip to content

Support JSONC Dock configs - #4263

Closed
mattpetters wants to merge 3 commits into
manaflow-ai:mainfrom
mattpetters:feat/dock-should-support-jsonc
Closed

mattpetters wants to merge 3 commits into
manaflow-ai:mainfrom
mattpetters:feat/dock-should-support-jsonc

Conversation

@mattpetters

@mattpetters mattpetters commented May 16, 2026 •

Copy link
Copy Markdown

Summary

  • Parse Dock config files with the shared JSONC parser before decoding controls.
  • Keep Dock parsing in a dedicated DockConfigParser source file and surface stable, user-facing parse errors with recovery guidance.
  • Add focused coverage for comments, trailing commas, comment-like text inside strings, and JSONC parse failures.
  • Update Dock docs and the empty-state setup prompt to describe JSONC support.

Validation

  • git diff --check
  • python3 -m json.tool Resources/Localizable.xcstrings
  • CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag dock-jsonc

Tests were not run locally per repository policy; the new behavior is covered by DockConfigParserTests for CI.

Summary by CodeRabbit

  • New Features

    • Dock configuration now supports JSONC (comments and trailing commas); both dock.json and dock.jsonc are recognized, with dock.json preferred when both exist.
  • Documentation

    • Updated docs and in-app guidance/agent prompts to describe JSONC, filename behavior, control ordering, and validation guidance.
  • Bug Fixes / UX

    • Improved localized parse error messages with specific failure reasons and recovery suggestions for JSONC parse failures.
  • Tests

    • Added tests covering JSONC preprocessing, error reporting, and config file selection.

Review Change Stack

@vercel

vercel Bot commented May 16, 2026

Copy link
Copy Markdown

@mattpetters is attempting to deploy a commit to the Manaflow Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented May 16, 2026 •

Copy link
Copy Markdown

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

Dock configuration now accepts JSONC (comments and trailing commas). A new DockConfigParser preprocesses JSONC then decodes controls. Error localization, the DockEmptyView prompt, unit tests, documentation, and project build entries are updated accordingly.

Changes

JSONC Dock Configuration Support

Layer / File(s) Summary
Localization strings and user guidance
Resources/Localizable.xcstrings, Sources/DockEmptyView.swift
English and Japanese localization values updated to describe JSONC and add parse-failure keys; DockEmptyView agentPrompt reworded to require JSONC validation.
DockConfigParser implementation
Sources/DockConfigParser.swift
Add DockConfigFile, DockConfigFileLocator.existingConfigURL(in:), and DockConfigParser.decodeControls(data:) which preprocesses JSONC via JSONCParser.preprocess, maps preprocess failures to NSError(domain: "cmux.dock", code: 2) with localized description/recovery (including underlying error), and decodes controls.
DockPanel integration and config resolution
Sources/DockPanelView.swift
Make DockControlDefinition nonisolated and Sendable. loadConfig now uses DockConfigParser.decodeControls(data:), validates duplicate ids on the decoded controls, and project/global config discovery now uses DockConfigFileLocator and defaultGlobalConfigURL()/preferredEditableConfigURL adjustments.
Parser and locator tests
cmuxTests/CmuxConfigTests.swift
New tests verify line/block comment handling, preservation of comment-like text in strings, DockConfigFileLocator precedence (dock.json over dock.jsonc), and that malformed JSONC preprocessing throws NSError with localizedDescription, localizedRecoverySuggestion, and an underlying error.
Project wiring and documentation
cmux.xcodeproj/project.pbxproj, docs/dock.md
Add DockConfigParser.swift to Xcode project sources and update docs to state JSONC format (fenced as jsonc), document that controls order defines sidebar order and comments can disable controls, and clarify config precedence rules.

Sequence Diagram(s)

sequenceDiagram
  participant loadConfig
  participant DockConfigParser
  participant JSONCParser
  participant JSONDecoder
  participant Validation
  loadConfig->>DockConfigParser: decodeControls(data)
  DockConfigParser->>JSONCParser: preprocess(rawData)
  JSONCParser-->>DockConfigParser: preprocessedJSON or throw
  DockConfigParser->>JSONDecoder: decode DockConfigFile
  JSONDecoder-->>DockConfigParser: DockConfigFile.controls
  DockConfigParser-->>loadConfig: controls or NSError(cmux.dock)
  loadConfig->>Validation: validate duplicate ids
Loading

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

  • manaflow-ai/cmux#3366: Both PRs modify Dock config handling in Sources/DockPanelView.swift and resolve filename precedence between dock.json and dock.jsonc.
  • manaflow-ai/cmux#3454: Related JSONC preprocessing/parsing changes; both touch JSONCParser usage and error paths.
  • manaflow-ai/cmux#3217: Related changes to Dock panel/control loading that this PR integrates with the new parser.

Poem

🐰 I nibble through configs, neat and spry,
Comments and commas now can live and fly,
JSONC hops in, parsed with care,
Errors point the burrow to repair,
Tests keep the meadow tidy and dry.


Caution

Pre-merge checks failed

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

  • Ignore

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

Check name Status Explanation Resolution
Cmux Swiftui State Layout ❌ Error PR introduces new ObservableObject/@published classes where @Observable is modern. Also uses GeometryReader for layout measurement affecting child height calculations without fallback justification. Replace DockControlRuntime and DockControlsStore with @Observable macro. Replace GeometryReader with onGeometryChange or non-layout-affecting approach.
Docstring Coverage ⚠️ Warning Docstring coverage is 5.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description covers the key changes (JSONC parsing, dedicated parser file, error handling, test coverage, documentation updates) but is missing several template sections: Testing details, Demo Video, Review Trigger commands, and Checklist items. Add the missing template sections: describe how testing was performed, include any demo video if applicable, add the Review Trigger commands, and complete the Checklist with checkmarks or explanations.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Support JSONC Dock configs' accurately and concisely summarizes the primary change: adding JSONC (JSON with Comments) support to Dock configuration files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed All Swift changes comply with actor isolation rules. New value types marked nonisolated. No mutable Sendable, implicit MainActor protocols, or background violations.
Cmux Swift Blocking Runtime ✅ Passed No blocking/timing synchronization primitives (semaphores, sleeps, locks, asyncAfter) introduced in production code. Proper concurrency patterns and file I/O for config loading used.
Cmux No Hacky Sleeps ✅ Passed Check only applies to TypeScript, JavaScript, shell, and non-Swift runtime scripts. This PR modifies only Swift, localization, documentation, and project config files.
Cmux Swift Concurrency ✅ Passed No legacy async patterns. Uses synchronous JSONDecoder, existing @MainActor classes unchanged, no DispatchQueue or new Tasks.
Cmux Swift @Concurrent ✅ Passed No violations of swift-concurrent-annotation.md. All new nonisolated declarations are on synchronous structs. No async or @concurrent annotations. File I/O is synchronous.
Cmux Swift File And Package Boundaries ✅ Passed New DockConfigParser.swift (73 lines) has single responsibility, well under thresholds. DockPanelView adds 6 net lines to 929-line file, far below 250-line limit. No boundary violations.
Cmux Swift Logging ✅ Passed No Swift logging violations. PR adds no print/debugPrint/dump/NSLog in app/runtime code. Error handling uses localized NSError messages without exposing sensitive data.
Cmux User-Facing Error Privacy ✅ Passed User-facing error messages comply with rules. Upstream JSONCParser errors are filtered to generic, localized strings without exposing vendor names or internal details.
Cmux Architecture Rethink ✅ Passed No violations detected. New JSONC parser module. No timing, locks, duplicate wiring, or split lifecycle. Single MainActor owner with unified reload() flow.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed No new or materially changed standalone windows. Refactors Dock config parsing. Pre-existing NSWindow callback parameters were not modified.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@mattpetters

mattpetters commented May 16, 2026 •

Copy link
Copy Markdown
Author

BTW — love cmux. it’s my daily env now. you guys are tapped tf in! @lawrencecchen

@greptile-apps

greptile-apps Bot commented May 16, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces JSONC support for Dock configuration files, allowing users to write comments and trailing commas in their dock.json (or new dock.jsonc) files. It extracts parsing into a dedicated DockConfigParser source file, surfaces structured user-facing error messages for JSONC preprocessing failures, and updates documentation and in-app prompts accordingly.

  • DockConfigParser.swift is added as a dedicated parsing layer that preprocesses JSONC (via JSONCParser) and wraps preprocessing errors into localised NSError values with user-friendly descriptions and recovery suggestions; DockConfigFile and DockControlDefinition gain nonisolated and Sendable conformances.
  • DockConfigFileLocator encodes the dock.json-first, dock.jsonc-fallback resolution in a single reusable helper, used in three call sites; DockControlsStore now surfaces errorRecoverySuggestion alongside errorMessage in DockErrorView.
  • DockConfigParserTests covers comment stripping, string-literal preservation, file precedence, and error reporting; docs and the empty-state prompt are updated to describe JSONC support and the two-filename behaviour.

Confidence Score: 5/5

Safe to merge — changes are additive, well-tested, and correctly isolated.

The parsing layer is cleanly separated into DockConfigParser, JSONC preprocessing errors are wrapped with user-friendly cmux-domain messages and recovery suggestions, and the file-locator logic is consistent across all three call sites. Previous review comments about error copy and doc precedence order have been addressed. Tests cover the new parsing paths, file-selection precedence, and the error message/recovery surface.

No files require special attention.

Important Files Changed

Filename Overview
Sources/DockConfigParser.swift New file: clean separation of concerns — JSONC preprocessing, error wrapping, and file-locator logic all in one dedicated source. Localized error messages correctly use cmux-domain language; format-specifier mapping between the Swift LocalizationValue interpolation and %@ in xcstrings is consistent with the test assertions.
Sources/DockPanelView.swift Adds errorRecoverySuggestion to DockControlsStore and threads it to DockErrorView; refactors globalConfigURL into two functions (nullable lookup vs. unconditional creation default); delegates parsing to DockConfigParser. All changes are additive and do not alter existing actor isolation or concurrency patterns.
Sources/JSONCParser.swift Single-line change: promotes JSONCError from private to nonisolated (internal) so DockConfigParser can pattern-match against its cases. No logic changes.
Resources/Localizable.xcstrings Adds six new localisation keys for JSONC parse errors (description, recovery, and four reason variants) in English and Japanese; updates the dock-setup agent prompt to describe JSONC and dual-filename support. Previous jsoncPreprocessingFailed key addressed.
cmuxTests/CmuxConfigTests.swift Adds DockConfigParserTests with seven cases covering line comments, block comments, string-literal preservation, file-locator precedence, and error message/recovery formatting. Coverage matches the stated validation goals.
docs/dock.md Rewritten Config Precedence section now accurately describes per-directory walk-up with dock.json-first resolution, fixing the previous misleading global-rank list.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[DockControlsStore.reload] --> B[Self.resolve]
    B --> C{Project config?}
    C -->|walk up tree| D[DockConfigFileLocator.existingConfigURL]
    D -->|dock.json exists?| E[dock.json URL]
    D -->|dock.jsonc exists?| F[dock.jsonc URL]
    D -->|neither| G[check parent dir]
    G --> D
    C -->|no project config| H[globalConfigURL]
    H --> D2[DockConfigFileLocator.existingConfigURL in ~/.config/cmux]
    E --> I[loadConfig]
    F --> I
    H --> I
    I --> J[Data contentsOf url]
    J --> K[DockConfigParser.decodeControls]
    K --> L[JSONCParser.preprocess]
    L -->|success| M[JSONDecoder decode DockConfigFile]
    L -->|JSONC error| N[wrap to NSError with localised description and recovery]
    M -->|success| O[DockControlRuntime array]
    M -->|DecodingError| P[raw DecodingError propagates]
    N --> P
    P --> Q[errorMessage and errorRecoverySuggestion in DockErrorView]
    O --> R[controls shown in UI]
Loading

Reviews (8): Last reviewed commit: "Merge branch 'manaflow-ai:main' into fea..." | Re-trigger Greptile

Comment thread Sources/DockPanelView.swift Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/dock.md`:
- Line 51: Update the Agent Setup sentence that currently says “validate the
JSON” so it instead reads “validate the JSONC” to match the earlier statement
that Dock config is JSONC; locate the Agent Setup wording in docs/dock.md (the
paragraph mentioning validation) and replace the phrase "validate the JSON" with
"validate the JSONC" so the terminology is consistent across the document.

In `@Sources/DockPanelView.swift`:
- Around line 86-105: The DockConfigParser enum (including static func
decodeControls) which references JSONCParser, DockControlDefinition, and
DockConfigFile should be extracted from Sources/DockPanelView.swift into its own
Swift source file (e.g., DockConfigParser.swift) and moved into the appropriate
module boundary so parsing logic is separated from UI/persistence code; create
the new file, paste the enum and its decodeControls implementation, add any
necessary imports or access-level adjustments (public/internal) so JSONCParser,
DockControlDefinition, and DockConfigFile remain visible, remove the original
enum from DockPanelView.swift, and run a quick build to fix any symbol
visibility or import issues.
- Around line 92-100: The NSError construction for domain "cmux.dock" with code
2 currently injects raw error.localizedDescription into the user-facing
NSLocalizedDescriptionKey; change this to a stable, user-friendly message (e.g.,
"Failed to preprocess JSONC. Please check your configuration and try again.")
and include only minimal/sanitized diagnostic info (for example append a short
diagnostic tag or error code, not the full upstream message) via a separate
developer-only field in userInfo (or log the full error). Update the NSError
creation where NSLocalizedDescriptionKey is set (the initializer creating the
userInfo dictionary) to use the new wording and move detailed diagnostics out of
the displayed string.
🪄 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: 1bf2a7cd-4cf9-4302-b648-dfa05c13ea45

📥 Commits

Reviewing files that changed from the base of the PR and between 789d188 and d1b57e6.

📒 Files selected for processing (5)
  • Resources/Localizable.xcstrings
  • Sources/DockEmptyView.swift
  • Sources/DockPanelView.swift
  • cmuxTests/CmuxConfigTests.swift
  • docs/dock.md

Comment thread docs/dock.md
Comment thread Sources/DockPanelView.swift Outdated
Comment thread Sources/DockPanelView.swift Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

Re-trigger cubic

@mattpetters
mattpetters force-pushed the feat/dock-should-support-jsonc branch from d1b57e6 to fd6a3f5 Compare May 16, 2026 22:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Resources/Localizable.xcstrings`:
- Around line 108121-108134: Update the localized message for the
"dock.error.jsoncParseFailed" stringUnit so it follows the preprocessing format
contract by including the underlying error placeholder ("%@") in the value;
modify both localizations (the "en" and "ja" stringUnit values) to include the
"%@" placeholder where the underlying error text should be interpolated so
downstream preprocessing can surface the detailed error.
🪄 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: 815b1038-b9a2-4236-a814-a8831b18d86d

📥 Commits

Reviewing files that changed from the base of the PR and between d1b57e6 and fd6a3f5.

📒 Files selected for processing (7)
  • Resources/Localizable.xcstrings
  • Sources/DockConfigParser.swift
  • Sources/DockEmptyView.swift
  • Sources/DockPanelView.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CmuxConfigTests.swift
  • docs/dock.md

Comment thread Resources/Localizable.xcstrings
@mattpetters
mattpetters force-pushed the feat/dock-should-support-jsonc branch from fd6a3f5 to 7eef9e0 Compare May 16, 2026 22:24
Comment thread Sources/DockConfigParser.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

🤖 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/CmuxConfigTests.swift`:
- Around line 38-60: Add a new unit test (e.g.,
testPreservesCommentMarkersInStringValues) that uses decodeControls to parse a
JSON controls array where a control's "command" string contains explicit comment
markers like "//" and "/* ... */"; assert controls.count == 1 and that
controls.first?.command exactly equals the original string so comment markers
inside string values are preserved; reference the existing
testParsesBlockCommentedControlAndPreservesCommentSyntaxInStrings for structure
and reuse decodeControls, controls, and XCTAssertEqual assertions.

In `@Resources/Localizable.xcstrings`:
- Around line 108155-108171: Update the English localization entries for the
JSONC parse failure reasons to standardize article usage: change the value for
"dock.error.jsoncParseFailed.reason.encoding" from "unsupported text encoding"
to "an unsupported text encoding", and change the value for
"dock.error.jsoncParseFailed.reason.syntax" to a more natural phrase such as
"invalid syntax" (or "an invalid JSONC syntax" if you prefer to keep an
article), so composed messages like "Couldn't parse Dock config as JSONC: %@."
read consistently and naturally.

In `@Sources/DockConfigParser.swift`:
- Around line 37-40: Update the recovery suggestion string in DockConfigParser
where NSLocalizedRecoverySuggestionErrorKey is set for the
"dock.error.jsoncParseFailed.recovery" message: change the defaultValue (and
matching localized copy if present) to reference both "dock.json" and
"dock.jsonc" (e.g. "Check comments and trailing commas in dock.json or
dock.jsonc, then reload Dock.") so users editing either format see the correct
guidance.
🪄 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: 09089e2c-29bc-4add-8e33-2ae21fffc2ac

📥 Commits

Reviewing files that changed from the base of the PR and between fd6a3f5 and 7eef9e0.

📒 Files selected for processing (7)
  • Resources/Localizable.xcstrings
  • Sources/DockConfigParser.swift
  • Sources/DockEmptyView.swift
  • Sources/DockPanelView.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CmuxConfigTests.swift
  • docs/dock.md

Comment thread cmuxTests/CmuxConfigTests.swift
Comment thread Resources/Localizable.xcstrings
Comment thread Sources/DockConfigParser.swift
@mattpetters
mattpetters force-pushed the feat/dock-should-support-jsonc branch from 7eef9e0 to b8cd040 Compare May 16, 2026 22:31

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Resources/Localizable.xcstrings`:
- Around line 107906-107913: The deliverable text currently mandates
creating/updating only "dock.json" which conflicts with JSONC support; update
the "Deliverable" section so it accepts either "dock.json" or "dock.jsonc"
(e.g., change "Create or update the appropriate dock.json." to "Create or update
the appropriate dock.json or dock.jsonc."), preserve the existing guidance
around precedence ("if both exist, dock.json wins") and JSONC parsing
validation, and ensure references to the top-level "controls" schema remain
consistent with both filenames.
🪄 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: 8a58662a-b89d-49cd-9bea-5739348862e3

📥 Commits

Reviewing files that changed from the base of the PR and between 7eef9e0 and b8cd040.

📒 Files selected for processing (7)
  • Resources/Localizable.xcstrings
  • Sources/DockConfigParser.swift
  • Sources/DockEmptyView.swift
  • Sources/DockPanelView.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CmuxConfigTests.swift
  • docs/dock.md

Comment thread Resources/Localizable.xcstrings Outdated
@mattpetters
mattpetters force-pushed the feat/dock-should-support-jsonc branch from b8cd040 to d8c0026 Compare May 16, 2026 22:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (2)
Sources/DockPanelView.swift (2)

300-304: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the parser’s recovery guidance in the Dock error UI.

DockConfigParser.decodeControls now returns user-facing recovery steps, but this layer still collapses failures to error.localizedDescription and DockErrorView only renders a single string. The new JSONC “what to do next” guidance never reaches users. Please carry localizedRecoverySuggestion through the store and render it alongside the message.

As per coding guidelines: “ensure messages: (1) describe the issue in cmux/product terms, (2) provide 1–2 concrete next actions”.

Also applies to: 418-419, 627-628, 850-867

🤖 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/DockPanelView.swift` around lines 300 - 304, The catch block in
DockPanelView currently sets only errorMessage = error.localizedDescription,
dropping DockConfigParser.decodeControls’ localizedRecoverySuggestion; update
the error flow to carry a separate recoverySuggestion (or a combined structured
error object) from where decodeControls returns it through the store/update
methods, set both sourceLabel and recoverySuggestion in the catch (instead of
collapsing to a single string), and update DockErrorView to render the
recoverySuggestion as a second, actionable line (1–2 concrete next actions)
alongside the existing error message; ensure the same propagation/fix is applied
to the other catch sites referenced (around lines 418–419 and 627–628 and
850–867).

320-331: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Open the existing JSONC file when reload fails.

If the parser throws, activeConfigURL never gets populated, so the Line 326 fallback still targets dock.json. For an existing but malformed dock.jsonc, the “Open Dock Config” action will open or create a new dock.json, and because DockConfigFileLocator prefers .json, that new file can shadow the real config on the next reload instead of letting the user fix it. Please prefer any existing config file before falling back to the default path.

Suggested fix
 private static func preferredEditableConfigURL(rootDirectory: String?) throws -> URL {
     if let rootDirectory = rootDirectory.flatMap(existingDirectory) {
-        return URL(fileURLWithPath: rootDirectory, isDirectory: true)
-            .appendingPathComponent(".cmux", isDirectory: true)
-            .appendingPathComponent("dock.json", isDirectory: false)
+        let configDirectory = URL(fileURLWithPath: rootDirectory, isDirectory: true)
+            .appendingPathComponent(".cmux", isDirectory: true)
+        return DockConfigFileLocator.existingConfigURL(in: configDirectory)
+            ?? configDirectory.appendingPathComponent("dock.json", isDirectory: false)
     }
-    return defaultGlobalConfigURL()
+    return globalConfigURL() ?? defaultGlobalConfigURL()
 }

Also applies to: 456-458, 473-503

🤖 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/DockPanelView.swift` around lines 320 - 331, openConfiguration
currently falls back to Self.preferredEditableConfigURL(rootDirectory:
lastRootDirectory) even when a malformed but existing config (e.g. dock.jsonc)
exists because activeConfigURL is nil after a parse error; change the logic in
openConfiguration (and the similar blocks at the other locations mentioned) to
first check for any existing config file in the root directory before using
preferredEditableConfigURL: attempt to locate an existing config URL (using the
same lookup logic as DockConfigFileLocator or an existing helper that returns an
existing config URL for lastRootDirectory), set target to that existing URL if
present, otherwise use preferredEditableConfigURL, and then proceed to create
the template only if the target truly does not exist (preserving activeConfigURL
behavior and avoiding creating a new dock.json that would shadow dock.jsonc).
🤖 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 `@docs/dock.md`:
- Around line 62-67: Update the trust section to explicitly state that the
global Dock config trust behavior applies to both ~/.config/cmux/dock.json and
~/.config/cmux/dock.jsonc (i.e., both filenames are treated the same for trust
decisions); mention that either file in the global config location will be
subject to the same trust rules used for repo-level .cmux/dock.json and
.cmux/dock.jsonc so readers know there is no trust difference between the .json
and .jsonc variants.

---

Outside diff comments:
In `@Sources/DockPanelView.swift`:
- Around line 300-304: The catch block in DockPanelView currently sets only
errorMessage = error.localizedDescription, dropping
DockConfigParser.decodeControls’ localizedRecoverySuggestion; update the error
flow to carry a separate recoverySuggestion (or a combined structured error
object) from where decodeControls returns it through the store/update methods,
set both sourceLabel and recoverySuggestion in the catch (instead of collapsing
to a single string), and update DockErrorView to render the recoverySuggestion
as a second, actionable line (1–2 concrete next actions) alongside the existing
error message; ensure the same propagation/fix is applied to the other catch
sites referenced (around lines 418–419 and 627–628 and 850–867).
- Around line 320-331: openConfiguration currently falls back to
Self.preferredEditableConfigURL(rootDirectory: lastRootDirectory) even when a
malformed but existing config (e.g. dock.jsonc) exists because activeConfigURL
is nil after a parse error; change the logic in openConfiguration (and the
similar blocks at the other locations mentioned) to first check for any existing
config file in the root directory before using preferredEditableConfigURL:
attempt to locate an existing config URL (using the same lookup logic as
DockConfigFileLocator or an existing helper that returns an existing config URL
for lastRootDirectory), set target to that existing URL if present, otherwise
use preferredEditableConfigURL, and then proceed to create the template only if
the target truly does not exist (preserving activeConfigURL behavior and
avoiding creating a new dock.json that would shadow dock.jsonc).
🪄 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: fa8b6ee9-ae0d-479d-be1c-86699caf50cb

📥 Commits

Reviewing files that changed from the base of the PR and between b8cd040 and d8c0026.

📒 Files selected for processing (7)
  • Resources/Localizable.xcstrings
  • Sources/DockConfigParser.swift
  • Sources/DockEmptyView.swift
  • Sources/DockPanelView.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/CmuxConfigTests.swift
  • docs/dock.md

Comment thread docs/dock.md
@mattpetters
mattpetters force-pushed the feat/dock-should-support-jsonc branch from d8c0026 to 9fe3fb3 Compare May 16, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant