Rebrand cmux → Programa (core rename + runtime contracts, phased)#48
Merged
Conversation
Rename cmux → Programa in prose, manaflow-ai/cmux → darkroomengineering/programa, cmux-macos.dmg → programa-macos.dmg. Remove prior-owner promo content from README (manaflow star history, Founder's Edition Stripe link, personal contacts).
Mechanical s/Cmux/Programa/g across Sources/**, CLI/**, cmuxTests/**, excluding AppleScriptSupport.swift (@objc .sdef contract) and AppIconDockTilePlugin.swift (principal-class target) — both self-contained. Filenames, pbxproj, and scheme unchanged; builds green with the cmux scheme.
git mv the 6 Cmux/cmux-named sources (cmuxApp, CmuxConfig, CmuxConfigExecutor, CmuxDirectoryTrust, Panels/CmuxWebView, CLI/cmux) → Programa*/programa and update every project.pbxproj ref (build file, file reference path, group, sources phase). Builds green with the cmux scheme.
…rogramaUITests (Phase 3) git mv both test dirs + CmuxConfigTests.swift → ProgramaConfigTests.swift; update project.pbxproj (targets, products, group paths, config-list names) and the three schemes' test-target labels. App product label (cmux.app) and scheme filenames remain for Phase 4. build-for-testing (cmux-ci) green; tests not run locally per policy.
- Schemes cmux{,-unit,-ci}.xcscheme → programa*; app label cmux.app → programa.app
- CLI target cmux-cli → programa-cli, PRODUCT_MODULE_NAME cmux_cli → programa_cli,
stale product refs cmux/cmux.app → programa/programa.app (PRODUCT_NAME already
Programa/programa — unchanged)
- Bridging header cmux-Bridging-Header.h → programa-Bridging-Header.h
- scripts: -scheme cmux → programa, DerivedData/cmux- tag prefix → programa-
- CI: -scheme + -only-testing/-skip-testing test-target refs → programa*
Deferred (Phase 6): the Copy-Resources build phase (CMUXCommit plist key +
shell-integration copy — byte-verified untouched), the cmux CLI command name,
release-artifact/entitlements naming. Builds green with the new programa scheme.
…e 5) Global config, settings.json, and project-root config now prefer the new programa paths (~/.config/programa/, programa.json) and transparently fall back to the legacy cmux paths when only those exist, so existing users keep working: - ProgramaConfigStore.globalConfigPath: effective(new, legacy) - ProgramaSettingsFileStore.defaultPrimaryPath: effective(new, legacy) - findProgramaConfig: accepts programa.json then cmux.json; new configs default to programa.json - display/help strings + command.cmuxConfig.subtitle → programa.json UserDefaults key cmux.settingsFile.backups.v1 intentionally left (renaming would orphan stored backups — deferred to Phase 6 key migration). Builds green.
…ePlugin (Phase 6a) Class + target + product (CmuxDockTilePlugin.plugin → ProgramaDockTilePlugin.plugin) + app Info.plist NSDockTilePlugIn value, in lockstep. Notification value was already com.darkroom.programa.*. Compiles; dock-icon switching to be manually verified.
…sdef text (Phase 6b) @objc(CmuxScript{Window,Tab,Terminal,InputTextCommand}) → Programa* in lockstep with the .sdef cocoa class refs; sdef dictionary/suite/description text cmux → Programa. AppleEvent codes (code="Cmux…") preserved (internal dispatch, invisible to users). Compiles; AppleScript dispatch to be manually verified.
…a*/programa* (Phase 6c) Lockstep rename across all 7 files that inject or handle the tokens: __cmux* page globals → __programa*, and the JS↔Swift message handlers cmuxIMEState, cmuxAddressBarFocusState, cmuxReactGrab → programa*. Internal app-owned bridge (both sides ship together). Compiles; browser IME/address-bar/ReactGrab to be runtime-verified.
…hase 6e) Build-phase writer (Copy Resources PlistBuddy) + all reader sites (ProgramaApp, ContentView, CLI) in lockstep. Regenerated every build (no cross-version persistence), so no migration shim needed. Builds green.
…hase 6, UserDefaults) Add a version-gated startup migration that copies every cmux-prefixed default to its programa-prefixed key (never deletes the legacy key), so no user preference is lost by the rebrand. Rename the standalone persisted keys (welcomeShown, surfacePoolEnabled, devMutate…, debugBG, focusDebug, keyLatencyProbe, shortcutMonitorTrace, typingTimingLogs, settingsFile.backups). Port keys (cmuxPortBase/Range) and socket-mode value (cmuxonly) deferred to their own contracts (shell-integration / socket-mode). Builds green.
…ow-up) test_ci_scheme_testaction_debug.sh referenced the old cmux.xcscheme path and test_bundled_ghostty_theme_picker_helper.sh used -scheme cmux; both broke after the Phase 4 scheme rename. Points them at programa.xcscheme / -scheme programa.
Rename cmux.entitlements → programa.entitlements (git mv + the 3 signing refs in build-sign-upload.sh, release.yml, nightly.yml — pbxproj CODE_SIGN_ENTITLEMENTS is empty, so the Xcode build is unaffected). Rename nightly DMG/artifact names cmux-nightly-* → programa-nightly-* and the release dry-run artifact. Homebrew cask refs left as-is (external repo, deprecated per board cleanup).
The macos-26 runner is ~2x slower than macos-15 (same suite: 23m on macos-15 vs >45m on macos-26). The rebrand changed project.pbxproj, which is part of the DerivedData cache key, so every run on this branch rebuilds from a cold cache and macos-26 consistently hit the 45m cap. Not a code issue — macos-15 passes the same tests. Give macos-26 headroom.
Localizable.xcstrings (50 EN strings; JA had none) + matching Swift defaultValue/Text
fallbacks. Brand nouns → "Programa" (Quit/About/CLI/settings/dialogs/updates);
command/binary references → lowercase "programa" (Install 'programa' in PATH,
Usage: programa claude-teams/omo, and the sendText("programa welcome") terminal
command). Localization KEYS with lowercase cmux (cmuxOnly, cmuxConfig) preserved via
value-only edits + a (?![A-Z]) guard. Builds green.
…functional) The CLI product is PRODUCT_NAME=programa and is bundled at Contents/Resources/bin/programa, but the app still looked for bin/cmux and installed /usr/local/bin/cmux — a pre-existing mismatch (main is mid-rebrand) that left the 'Install CLI' + CLI resolution broken. Point them at bin/programa and /usr/local/bin/programa. Also fix the remaining 'programa welcome' terminal command send, the menu-bar title/tooltip, and brand fallbacks (window title, app name for notifications) cmux → Programa. Socket contract already agrees (shared last-socket-path hint). Builds green.
…hase 6d)
Rename the two integration scripts (cmux-{bash,zsh}-integration → programa-*) and every
cmux_ shell-protocol token in lockstep across the scripts, the embedded-shell Swift string
literals (Workspace, AppDelegate, BrowserPopupWindowController), and CLI/programa.swift
(SSH bootstrap + loaders). The cross-boundary env vars were already PROGRAMA_*. PostHog
analytics events (cmux_daily_active/hourly_active) intentionally preserved for continuity.
Compiles; shell integration behavior verified by E2E CI (port detection, PR sidebar).
…Phase 6f functional)
- ${..._BIN:-cmux} tmux-shim fallbacks → :-programa (were invoking the old binary name)
- manaflow-ai/cmux nightly/release workflow URLs → darkroomengineering/programa
- /tmp/cmux* socket + hint paths → /tmp/programa* (fixes latent mismatch with the app's
SocketControlSettings + reload.sh, which already use /tmp/programa*)
- sentry tag + dispatch-queue labels cmux → programa
Left cmux-relay-auth (JSON handshake protocol shared with the Go remote daemon — needs a
coordinated both-sides change). Builds green.
…e 6, cosmetic) ~90 cmuxXxx Swift identifiers + ~60 dotted cmux.* Notification/queue/error-domain literals across 30 Sources/CLI files → programa*. Verified with build-for-testing (app + programaTests + programaUITests compile). Deliberately preserved identifiers/strings hard-coded by the test targets and tests_v2 (e.g. SocketControlMode.cmuxOnly rawValue "cmuxonly", cmux*ForTesting helpers, "cmux.main"/"cmux.settings"/"cmux.about" test-asserted keys, cmux-ssh-startup-* asserted in test_ssh_remote_cli_metadata) — those need a coordinated app+test rename (follow-up). Also fixed the 'Bundled Programa CLI' error string. Analytics events + cmux-relay-auth untouched.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Renames the product from cmux to Programa throughout the codebase, done as a series of build-verified phases instead of one big sweep (a prior blanket attempt was reverted for producing an inconsistent diff). Every commit here builds green on its own.
Crucially, the two places where a rename could lose user data — the config files and stored preferences — ship with migrations, so existing users keep working after they update:
~/.config/cmux/and project-rootcmux.jsonare still read if the new~/.config/programa//programa.jsondon't exist yet.cmux-prefixed UserDefaults value is copied forward to itsprogramakey once, on first launch.Summary
Twelve commits, each build-gated (
-scheme programa … build, orbuild-for-testingfor the test phase):manaflow-ai/cmux→darkroomengineering/programa, README promo cleanup.Cmux*→Programa*; 6 source files + both test targets renamed with pbxproj/scheme updates.programa*,cmux-cli→programa-cli, bridging header,reload*.sh/CI-scheme+ test-target refs. (PRODUCT_NAMEwas alreadyprograma.)CmuxDockTilePlugin→ProgramaDockTilePlugin(class + target + product + appInfo.plistNSDockTilePlugIn, in lockstep).@objc(CmuxScript*)→ProgramaScript*↔.sdefcocoa-class refs + user-facing dictionary text; AppleEventcode=values preserved.__cmux*globals +cmuxIMEState/cmuxAddressBarFocusState/cmuxReactGrabhandlers renamed in lockstep across 7 files.CMUXCommitInfo.plist key →ProgramaCommit(build writer + all readers).Deliberately not in this PR (tracked in
plans/rebrand-progress.md), because they can only be verified by CI/manual runtime tests, not the local compile gate:$cmux_*protocol tokens ↔ Swift, ~100+ shell functions).~/.cmux→~/.programabootstrap (386 refs, needs per-occurrence categorization).Localizable.xcstringsbrand strings (EN+JA).cmux.entitlements, DMG names, homebrew).Analytics
cmuxtermis intentionally kept for historical continuity.Test Plan
xcodebuild -scheme programa … buildgreen after every phasebuild-for-testing -scheme programa-ciprograma-unit)