Skip to content

Extract CmuxFoundation package (modular refactor, wave 1) - #5055

Merged
azooz2003-bit merged 4 commits into
mainfrom
feat-modularize-foundation
May 31, 2026
Merged

azooz2003-bit merged 4 commits into
mainfrom
feat-modularize-foundation

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented May 31, 2026 •

Copy link
Copy Markdown
Collaborator

First leaf of the modular refactor. Introduces `CmuxFoundation`, a dependency-free SwiftPM package for shared low-level utilities, and moves `cmuxJavaScriptStringLiteral` into it. The app target depends on it via a local package reference and imports it. Behavior is unchanged.

This proves the extraction pattern end to end on the lowest-risk surface: a new package with a Swift 6 strict manifest, Swift Testing unit tests, Xcode local-package wiring, and the app target forwarding to the package. Later waves follow the same shape.

Changes:

  • New `Packages/CmuxFoundation` (Swift 6 language mode, ExistentialAny + InternalImportsByDefault, no dependencies).
  • `cmuxJavaScriptStringLiteral` moved out of `AppDelegate.swift`; the call site is unchanged via `import CmuxFoundation`.
  • 6 Swift Testing unit tests covering the escaper.
  • `project.pbxproj` wired like the existing local packages; `check-pbxproj.sh` passes.

No user-facing change.

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Summary by cubic

Extracted CmuxFoundation, a dependency-free SwiftPM package for shared low-level utilities, and moved the JS string literal helper into it as String.javaScriptStringLiteral. The app now imports the package; behavior is unchanged.

  • Refactors
    • Added Packages/CmuxFoundation (Swift 6; no deps; ExistentialAny, InternalImportsByDefault).
    • Replaced cmuxJavaScriptStringLiteral(_:) with String.javaScriptStringLiteral; fixed the AppDelegate call site.
    • Added Swift Testing unit tests for the escaper.
    • Wired Xcode project and workspace to the new local package.

Written for commit c22f751. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Refactor
    • Moved JavaScript string-encoding logic into a new shared foundation package (CmuxFoundation); app now uses the shared helper.
  • New Features
    • Exposed a String API to produce JavaScript-escaped string literals.
  • Tests
    • Added unit tests validating quoting, escaping, newlines, and Unicode behavior.
  • Chores
    • Workspace/project updated to include the new local package and README documentation.

First leaf of the modular refactor. New CmuxFoundation SwiftPM package
(Swift 6 strict, no dependencies) for shared low-level utilities, seeded
with cmuxJavaScriptStringLiteral moved out of AppDelegate. The app target
depends on it via a local package reference and imports it. Behavior is
unchanged; the package has unit tests via Swift Testing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented May 31, 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 May 31, 2026 7:06pm
cmux-staging Building Building Preview, Comment May 31, 2026 7:06pm

@coderabbitai

coderabbitai Bot commented May 31, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1c8c81e4-e135-43ab-b8a1-5e8d5b6b3401

📥 Commits

Reviewing files that changed from the base of the PR and between 81f807f and c22f751.

📒 Files selected for processing (1)
  • Sources/AppDelegate.swift

📝 Walkthrough

Walkthrough

This PR extracts a JavaScript string literal encoding utility into a new local Swift package CmuxFoundation, implementing it as a String extension property, adding comprehensive tests and documentation, and integrating the package into the main app and Xcode workspace through project wiring and AppDelegate import changes.

Changes

CmuxFoundation Package Extraction

Layer / File(s) Summary
CmuxFoundation package, implementation, and tests
Packages/CmuxFoundation/Package.swift, Packages/CmuxFoundation/Sources/CmuxFoundation/String+JavaScriptStringLiteral.swift, Packages/CmuxFoundation/Tests/CmuxFoundationTests/String+JavaScriptStringLiteralTests.swift
Defines a new Swift package targeting macOS 14 and Swift 6 with language feature settings; implements String.javaScriptStringLiteral: String? using JSONSerialization for correct escaping; adds five test cases validating plain strings, empty strings, escaped characters, newlines, and Unicode preservation.
CmuxFoundation documentation
Packages/CmuxFoundation/README.md
Documents CmuxFoundation as a dependency-free set of shared primitives, describes the String.javaScriptStringLiteral property in a Contents section, and provides a Swift usage example with test assertion for expected quoting behavior.
AppDelegate import and Xcode project/workspace wiring
Sources/AppDelegate.swift, cmux.xcodeproj/project.pbxproj, cmux.xcworkspace/contents.xcworkspacedata
AppDelegate imports CmuxFoundation and the local cmuxJavaScriptStringLiteral(_:) helper is removed; the Xcode project registers CmuxFoundation as a local package reference, adds it to build phases, and links it as a product dependency; the workspace includes the CmuxFoundation package group in the Packages container.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • manaflow-ai/cmux#4834: Modifies cmux.xcworkspace/contents.xcworkspacedata to register local Swift packages in the workspace navigator.

Poem

🐰 A rabbit extracts with care,
String literals now fully share,
From AppDelegate's hidden fold,
To CmuxFoundation, a package bold,
Tests pass, escapes are right,
The workspace shines so bright! ✨

🚥 Pre-merge checks | ✅ 16 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% 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 description covers the main changes and rationale, but lacks some sections from the template: Testing and Review Trigger sections are missing, and the checklist is incomplete. Add Testing section describing how the change was tested, include the Review Trigger block, and complete the checklist with verification items.
✅ Passed checks (16 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: extracting CmuxFoundation as a new modular package.
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 PR adds a pure value-transform computed property on String for JavaScript escaping. No new types with isolation issues introduced; existing code isolation debt is unchanged.
Cmux Swift Blocking Runtime ✅ Passed PR introduces no blocking/timing-based synchronization primitives; it merely refactors an existing string encoding utility into a reusable package using JSONSerialization.
Cmux No Hacky Sleeps ✅ Passed PR contains Swift-only changes (package manifest, extension, tests, docs); no TypeScript/JavaScript/shell modifications; sleeps/timers are out of scope per rule.
Cmux Algorithmic Complexity ✅ Passed String.javaScriptStringLiteral encodes individual strings with JSONSerialization. No collection iteration, nested loops, or hot path impact. Test-only usage in DEBUG helper.
Cmux Swift Concurrency ✅ Passed PR adds pure synchronous CmuxFoundation utility package and removes legacy helper; no Dispatch queues, Combine, completion handlers, or fire-and-forget Tasks introduced.
Cmux Swift @Concurrent ✅ Passed PR contains only synchronous code: String.javaScriptStringLiteral property and call site updates. No async/await, @concurrent annotations, or actor isolation issues found. Compliant with rules.
Cmux Swift File And Package Boundaries ✅ Passed PR extracts independently testable feature logic into new CmuxFoundation SwiftPM package; all new files small and focused with comprehensive tests.
Cmux Swift Logging ✅ Passed No logging violations found. New CmuxFoundation package code has zero print, debugPrint, dump, or NSLog statements; tests and package configuration only.
Cmux User-Facing Error Privacy ✅ Passed PR adds CmuxFoundation package with tests, docs, and debug-only code. No user-facing errors, vendor names, credentials, or sensitive details are exposed.
Cmux Full Internationalization ✅ Passed PR is a pure refactor creating CmuxFoundation package; contains no user-facing text additions, no string catalog changes, and no web/metadata localization updates requiring translation.
Cmux Swiftui State Layout ✅ Passed PR extracts utility function into CmuxFoundation package; no SwiftUI state patterns (Observable, @Published, @State, GeometryReader) introduced.
Cmux Architecture Rethink ✅ Passed Pure value transformation extracted to dependency-free package with clear owner, immutable property, documented invariant. No timing, dispatch, locks, observers, or UI lifecycle split patterns.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds only a CmuxFoundation utility package with a String.javaScriptStringLiteral extension and tests—no user-visible windows, panels, or window controllers are added or changed.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 feat-modularize-foundation

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.

Lists the package under the workspace Packages group so it shows in the
Xcode navigator alongside the other local packages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented May 31, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR extracts cmuxJavaScriptStringLiteral into a new dependency-free SwiftPM package (CmuxFoundation) and rewires the app target to import it — a clean structural move that proves the extraction pattern end-to-end.

  • New package: Packages/CmuxFoundation is a Swift 6 library with no internal dependencies; String.javaScriptStringLiteral replaces the old free function and is covered by five Swift Testing unit tests.
  • Call-site migration: AppDelegate drops the local helper and imports CmuxFoundation, but the replacement expression awaitingInputId?.javaScriptStringLiteral ?? "null" produces String?? because javaScriptStringLiteral returns String?; ?? only unwraps the outer optional, so expectedInputIdLiteral is String? and \(expectedInputIdLiteral) in the JS template renders as Optional(...) — breaking every evaluation where awaitingInputId is non-nil.
  • Documentation: Both the String+JavaScriptStringLiteral.swift doc-comment and the README show the same double-optional call pattern, which callers will copy and encounter the same silent breakage.

Confidence Score: 3/5

The call-site migration introduces a double-optional that renders Optional(...) inside the JavaScript template on every non-nil input, causing a ReferenceError in the web view at runtime.

The extraction itself is structurally sound, but the migrated call site in AppDelegate and the canonical examples in the doc-comment and README all use the same double-optional pattern. Because javaScriptStringLiteral returns String?, optional chaining on String? produces String??, and ?? 'null' leaves the result as String? — so string interpolation in the JS script body produces Optional('...') rather than the bare literal, breaking evaluateJavaScript calls whenever awaitingInputId is non-nil.

Sources/AppDelegate.swift (the live call site), Packages/CmuxFoundation/Sources/CmuxFoundation/String+JavaScriptStringLiteral.swift and README.md (doc-comment and usage examples that propagate the pattern).

Important Files Changed

Filename Overview
Sources/AppDelegate.swift Call site migrated to the new extension but uses optional chaining on String? returning String?, producing String?? that ?? "null" only partially unwraps — string interpolation renders Optional(...) in the JS template, breaking every call where awaitingInputId is non-nil.
Packages/CmuxFoundation/Sources/CmuxFoundation/String+JavaScriptStringLiteral.swift Implementation is correct; the doc-comment example propagates the double-optional anti-pattern (id?.javaScriptStringLiteral ?? "null") that callers will copy, compounding the AppDelegate bug.
Packages/CmuxFoundation/Package.swift Swift 6 manifest is well-structured; ExistentialAny and InternalImportsByDefault are only applied to the library target, not the test target (previously flagged).
Packages/CmuxFoundation/Tests/CmuxFoundationTests/String+JavaScriptStringLiteralTests.swift Five Swift Testing cases covering quoting, empty strings, backslash/quote escaping, newlines, and Unicode — solid coverage for the happy path.
Packages/CmuxFoundation/README.md Usage example uses the same double-optional pattern as the doc-comment, meaning copy-pasted code will silently produce Optional(...) in JS templates.
cmux.xcodeproj/project.pbxproj New XCLocalSwiftPackageReference and XCSwiftPackageProductDependency entries follow the established pattern for other local packages; wiring looks correct.
cmux.xcworkspace/contents.xcworkspacedata CmuxFoundation FileRef added using the same group: convention as existing local packages.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    App["cmux App Target\n(AppDelegate.swift)"]
    CF["CmuxFoundation\n(Packages/CmuxFoundation)"]
    Str["String+JavaScriptStringLiteral\n.javaScriptStringLiteral returns String?"]
    JS["WKWebView\nevaluateJavaScript(script)"]

    App -->|"import CmuxFoundation"| CF
    CF --> Str
    App -->|"awaitingInputId.flatMap -> String?"| Str
    App -->|"interpolates into JS template"| JS

    style App fill:#f5f5f5,stroke:#333
    style CF fill:#dbeafe,stroke:#2563eb
    style Str fill:#dbeafe,stroke:#2563eb
    style JS fill:#fef9c3,stroke:#ca8a04
Loading

Reviews (3): Last reviewed commit: "Update AppDelegate call site to String.j..." | Re-trigger Greptile

Comment on lines +19 to +24
guard let data = try? JSONSerialization.data(withJSONObject: [value]),
let arrayLiteral = String(data: data, encoding: .utf8),
arrayLiteral.count >= 2 else {
return nil
}
return String(arrayLiteral.dropFirst().dropLast())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 U+2028/U+2029 not escaped — JS string literal claim may not hold

JSONSerialization does not escape U+2028 (LINE SEPARATOR) or U+2029 (PARAGRAPH SEPARATOR) by default. Both characters are legal in JSON strings, but in ECMAScript ≤ 2018 they are line terminators that immediately end a string literal, producing a syntax error. A WKWebView backed by JavaScriptCore or V8 on older hosts evaluating setValue("\u2028") would throw. The doc-comment says the result is "ready to splice into JS source", but that claim is not always true. Either add a post-processing step that replaces \u2028/\u2029 with their \u escape sequences, or narrow the doc-comment to document the limitation and add a test that pins the current (unescaped) behavior.

Comment on lines +25 to +28
.testTarget(
name: "CmuxFoundationTests",
dependencies: ["CmuxFoundation"]
),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 The test target does not carry the same swiftSettings as the library target. With swift-tools-version: 6.0, Swift 6 language mode is the default for all targets, so StrictConcurrency is already active — but ExistentialAny and InternalImportsByDefault are opt-in upcoming features and will not apply in the test target. Future tests that use bare existentials (Protocol instead of any Protocol) or rely on import-visibility semantics will silently diverge from production behavior. Adding the same settings block keeps the compilation environment uniform.

Suggested change
.testTarget(
name: "CmuxFoundationTests",
dependencies: ["CmuxFoundation"]
),
.testTarget(
name: "CmuxFoundationTests",
dependencies: ["CmuxFoundation"],
swiftSettings: [
.swiftLanguageMode(.v6),
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("InternalImportsByDefault"),
]
),

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

azooz2003-bit and others added 2 commits May 31, 2026 14:02
Foundation helpers should be ergonomic extensions on existing types, not
bare top-level functions. Replace the public func cmuxJavaScriptStringLiteral
with String.javaScriptStringLiteral and update the call site. Behavior is
unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Completes the extension reshape: the call site now uses
awaitingInputId?.javaScriptStringLiteral instead of the removed free
function. (The previous commit moved the helper but a failed edit left
this call site referencing the deleted symbol.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment thread Sources/AppDelegate.swift
completion: @escaping ([String: String]) -> Void
) {
let expectedInputIdLiteral = cmuxJavaScriptStringLiteral(awaitingInputId) ?? "null"
let expectedInputIdLiteral = awaitingInputId?.javaScriptStringLiteral ?? "null"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P0 Dangling call to removed free function — compilation error

The PR deletes cmuxJavaScriptStringLiteral(_:) from AppDelegate.swift and replaces it with the String.javaScriptStringLiteral property on CmuxFoundation, but this call site was never migrated. Because awaitingInputId is String?, the correct replacement is awaitingInputId?.javaScriptStringLiteral ?? "null". As written, the build will fail with "use of unresolved identifier 'cmuxJavaScriptStringLiteral'".

@azooz2003-bit
azooz2003-bit merged commit 6c6282b into main May 31, 2026
19 of 21 checks passed
@azooz2003-bit
azooz2003-bit deleted the feat-modularize-foundation branch May 31, 2026 19:12
Comment thread Sources/AppDelegate.swift
completion: @escaping ([String: String]) -> Void
) {
let expectedInputIdLiteral = cmuxJavaScriptStringLiteral(awaitingInputId) ?? "null"
let expectedInputIdLiteral = awaitingInputId?.javaScriptStringLiteral ?? "null"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Double-optional collapses to String?, not String, so \(expectedInputIdLiteral) in the template prints Optional("\"someId\"") rather than the bare literal. The JS engine receives const expectedInputId = Optional("\"someId\""); and throws a ReferenceError on every call where awaitingInputId is non-nil. Use flatMap to flatten the chain and get a plain String.

Suggested change
let expectedInputIdLiteral = awaitingInputId?.javaScriptStringLiteral ?? "null"
let expectedInputIdLiteral = awaitingInputId.flatMap(\.javaScriptStringLiteral) ?? "null"

Comment on lines +10 to +13
/// ```swift
/// "a\"b".javaScriptStringLiteral // -> "\"a\\\"b\""
/// webView.evaluateJavaScript("setValue(\(id?.javaScriptStringLiteral ?? "null"))")
/// ```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 The doc-comment example uses id?.javaScriptStringLiteral ?? "null" where id: String?. Because javaScriptStringLiteral itself returns String?, optional chaining produces String??, and ?? unwraps only the outer level — the result is String?, not String. When that String? is interpolated into a JS template it renders as Optional(...), not the bare literal. The canonical call pattern should use flatMap to flatten the nested optional.

Suggested change
/// ```swift
/// "a\"b".javaScriptStringLiteral // -> "\"a\\\"b\""
/// webView.evaluateJavaScript("setValue(\(id?.javaScriptStringLiteral ?? "null"))")
/// ```
/// ```swift
/// "a\"b".javaScriptStringLiteral // -> "\"a\\\"b\""
/// webView.evaluateJavaScript("setValue(\(id.flatMap(\.javaScriptStringLiteral) ?? "null"))")
/// ```

hhsw2015 pushed a commit to hhsw2015/cmux that referenced this pull request Jun 1, 2026
- Add Send Ctrl-F to Terminal passthrough (manaflow-ai#5011, force-stop CC agents)
- Fix sidebar worktree spawn worktree-setup-as-input bug (manaflow-ai#5032)
- Add boundary-aware ranking layer for command-palette fuzzy search
- Open extension browser as pane tab + polish (manaflow-ai#5053)
- Move sidebar kind selection to titlebar menu, fix clipped tooltip
  and floor sidebar width (manaflow-ai#5045)
- Extract CmuxFoundation package — modular refactor wave 1 (manaflow-ai#5055)
- Center empty sidebar-extension state, fade host bottom edge (manaflow-ai#5057)
- Align titlebar accessory hints (manaflow-ai#5059)
- Restore sidebar minimum width (manaflow-ai#5062)

Conflicts resolved:
- cmux.xcodeproj/project.pbxproj: merge fork's CMUXSettingsCore +
  CMUXSessionDaemon package refs with upstream's new CmuxFoundation
  package reference and product dependency.

This branch was successfully deployed

1 active deployment
Preview – cmux — c22f7513 Deployed May 31, 2026 by vercel[bot]
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