diff --git a/.claude/commands/release.md b/.claude/commands/release.md index 6b4d2eda..b4273894 100644 --- a/.claude/commands/release.md +++ b/.claude/commands/release.md @@ -1,6 +1,6 @@ # Release -Prepare a new release for cmuxterm. This command updates the changelog, bumps the version, creates a PR, monitors CI, and then merges and tags. +Prepare a new release for cmux. This command updates the changelog, bumps the version, creates a PR, monitors CI, and then merges and tags. ## Steps @@ -51,8 +51,8 @@ Prepare a new release for cmuxterm. This command updates the changelog, bumps th - Push tag: `git push origin vX.Y.Z` 11. **Monitor the release workflow** - - Watch: `gh run watch --repo manaflow-ai/cmuxterm` - - Verify the release appears at: https://github.com/manaflow-ai/cmuxterm/releases + - Watch: `gh run watch --repo manaflow-ai/cmux` + - Verify the release appears at: https://github.com/manaflow-ai/cmux/releases - Check that the DMG is attached to the release ## Changelog Guidelines diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1784208..a9ffe109 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,11 +85,11 @@ jobs: - name: Inject Sparkle keys into Info.plist run: | - APP_PLIST="build/Build/Products/Release/cmuxterm.app/Contents/Info.plist" + APP_PLIST="build/Build/Products/Release/cmux.app/Contents/Info.plist" echo "Adding SUPublicEDKey to Info.plist..." /usr/libexec/PlistBuddy -c "Add :SUPublicEDKey string ${SPARKLE_PUBLIC_KEY}" "$APP_PLIST" echo "Adding SUFeedURL to Info.plist..." - /usr/libexec/PlistBuddy -c "Add :SUFeedURL string https://github.com/manaflow-ai/cmuxterm/releases/latest/download/appcast.xml" "$APP_PLIST" + /usr/libexec/PlistBuddy -c "Add :SUFeedURL string https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml" "$APP_PLIST" echo "Verifying:" /usr/libexec/PlistBuddy -c "Print :SUPublicEDKey" "$APP_PLIST" /usr/libexec/PlistBuddy -c "Print :SUFeedURL" "$APP_PLIST" @@ -125,8 +125,8 @@ jobs: echo "Missing APPLE_SIGNING_IDENTITY secret" >&2 exit 1 fi - APP_PATH="build/Build/Products/Release/cmuxterm.app" - CLI_PATH="$APP_PATH/Contents/Resources/bin/cmuxterm" + APP_PATH="build/Build/Products/Release/cmux.app" + CLI_PATH="$APP_PATH/Contents/Resources/bin/cmux" if [ -f "$CLI_PATH" ]; then /usr/bin/codesign --force --options runtime --timestamp --sign "$APPLE_SIGNING_IDENTITY" "$CLI_PATH" fi @@ -144,9 +144,9 @@ jobs: echo "Missing notarization secrets (APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID)" >&2 exit 1 fi - APP_PATH="build/Build/Products/Release/cmuxterm.app" - ZIP_SUBMIT="cmuxterm-notary.zip" - DMG_RELEASE="cmuxterm-macos.dmg" + APP_PATH="build/Build/Products/Release/cmux.app" + ZIP_SUBMIT="cmux-notary.zip" + DMG_RELEASE="cmux-macos.dmg" ditto -c -k --sequesterRsrc --keepParent "$APP_PATH" "$ZIP_SUBMIT" APP_SUBMIT_JSON="$(xcrun notarytool submit "$ZIP_SUBMIT" --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --wait --output-format json)" APP_SUBMIT_ID="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"$APP_SUBMIT_JSON")" @@ -165,7 +165,7 @@ jobs: --identity="$APPLE_SIGNING_IDENTITY" \ "$APP_PATH" \ ./ - mv ./cmuxterm*.dmg "$DMG_RELEASE" + mv ./cmux*.dmg "$DMG_RELEASE" DMG_SUBMIT_JSON="$(xcrun notarytool submit "$DMG_RELEASE" --apple-id "$APPLE_ID" --team-id "$APPLE_TEAM_ID" --password "$APPLE_APP_SPECIFIC_PASSWORD" --wait --output-format json)" DMG_SUBMIT_ID="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"$DMG_SUBMIT_JSON")" DMG_STATUS="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])' <<<"$DMG_SUBMIT_JSON")" @@ -185,13 +185,13 @@ jobs: echo "Missing SPARKLE_PRIVATE_KEY secret" >&2 exit 1 fi - ./scripts/sparkle_generate_appcast.sh cmuxterm-macos.dmg "$GITHUB_REF_NAME" appcast.xml + ./scripts/sparkle_generate_appcast.sh cmux-macos.dmg "$GITHUB_REF_NAME" appcast.xml - name: Upload release asset uses: softprops/action-gh-release@v2 with: files: | - cmuxterm-macos.dmg + cmux-macos.dmg appcast.xml generate_release_notes: true diff --git a/.github/workflows/update-homebrew.yml b/.github/workflows/update-homebrew.yml index 0d4e3b7d..f57677d7 100644 --- a/.github/workflows/update-homebrew.yml +++ b/.github/workflows/update-homebrew.yml @@ -31,31 +31,31 @@ jobs: id: sha run: | VERSION="${{ steps.version.outputs.version }}" - curl -sL "https://github.com/manaflow-ai/cmuxterm/releases/download/v${VERSION}/cmuxterm-macos.dmg" -o cmuxterm.dmg - SHA256=$(shasum -a 256 cmuxterm.dmg | cut -d' ' -f1) + curl -sL "https://github.com/manaflow-ai/cmux/releases/download/v${VERSION}/cmux-macos.dmg" -o cmux.dmg + SHA256=$(shasum -a 256 cmux.dmg | cut -d' ' -f1) echo "sha256=$SHA256" >> $GITHUB_OUTPUT - - name: Checkout homebrew-cmuxterm + - name: Checkout homebrew-cmux uses: actions/checkout@v4 with: - repository: manaflow-ai/homebrew-cmuxterm + repository: manaflow-ai/homebrew-cmux token: ${{ secrets.HOMEBREW_TAP_TOKEN }} - path: homebrew-cmuxterm + path: homebrew-cmux - name: Update cask formula env: VERSION: ${{ steps.version.outputs.version }} SHA256: ${{ steps.sha.outputs.sha256 }} run: | - cat > homebrew-cmuxterm/Casks/cmuxterm.rb << CASKEOF - cask "cmuxterm" do + cat > homebrew-cmux/Casks/cmux.rb << CASKEOF + cask "cmux" do version "${VERSION}" sha256 "${SHA256}" - url "https://github.com/manaflow-ai/cmuxterm/releases/download/v#{version}/cmuxterm-macos.dmg" - name "cmuxterm" + url "https://github.com/manaflow-ai/cmux/releases/download/v#{version}/cmux-macos.dmg" + name "cmux" desc "Lightweight native macOS terminal with vertical tabs for AI coding agents" - homepage "https://github.com/manaflow-ai/cmuxterm" + homepage "https://github.com/manaflow-ai/cmux" livecheck do url :url @@ -64,29 +64,29 @@ jobs: depends_on macos: ">= :ventura" - app "cmuxterm.app" + app "cmux.app" zap trash: [ - "~/Library/Application Support/cmuxterm", - "~/Library/Caches/cmuxterm", - "~/Library/Preferences/ai.manaflow.cmuxterm.plist", + "~/Library/Application Support/cmux", + "~/Library/Caches/cmux", + "~/Library/Preferences/ai.manaflow.cmux.plist", ] end CASKEOF # Remove leading whitespace from heredoc - sed -i 's/^ //' homebrew-cmuxterm/Casks/cmuxterm.rb + sed -i 's/^ //' homebrew-cmux/Casks/cmux.rb - name: Commit and push env: VERSION: ${{ steps.version.outputs.version }} run: | - cd homebrew-cmuxterm + cd homebrew-cmux git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add Casks/cmuxterm.rb + git add Casks/cmux.rb if git diff --staged --quiet; then echo "No changes - cask already up to date" else - git commit -m "Update cmuxterm to ${VERSION}" + git commit -m "Update cmux to ${VERSION}" git push fi diff --git a/.gitmodules b/.gitmodules index cfdde7a3..680153c5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,6 +2,6 @@ path = ghostty url = https://github.com/manaflow-ai/ghostty.git branch = main -[submodule "homebrew-cmuxterm"] - path = homebrew-cmuxterm - url = https://github.com/manaflow-ai/homebrew-cmuxterm.git +[submodule "homebrew-cmux"] + path = homebrew-cmux + url = https://github.com/manaflow-ai/homebrew-cmux.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 897e63c0..288fb3cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,15 @@ # Changelog -All notable changes to cmuxterm are documented here. +All notable changes to cmux are documented here. + +## [1.23.0] - 2026-02-09 + +### Changed +- Rename app from cmuxterm to cmux — new app name, bundle ID, socket paths, Homebrew tap, and CLI binary name +- Sidebar now shows tab status as text instead of colored dots, with instant git HEAD change detection + +### Fixed +- CLI `set-status` command not properly quoting values or routing `--tab` flag ## [1.22.0] - 2026-02-09 @@ -114,7 +123,7 @@ All notable changes to cmuxterm are documented here. ### Added - Sentry SDK for crash reporting - Documentation site with Fumadocs -- Homebrew installation support (`brew install --cask cmuxterm`) +- Homebrew installation support (`brew install --cask cmux`) - Auto-update Homebrew cask on release ### Fixed @@ -160,7 +169,7 @@ All notable changes to cmuxterm are documented here. ## [1.4.0] - 2025-01-28 ### Added -- cmuxterm CLI with socket control modes +- cmux CLI with socket control modes - NSPopover-based notifications ### Fixed @@ -184,7 +193,7 @@ All notable changes to cmuxterm are documented here. - Update UI error details and pill visibility ### Changed -- Renamed app to cmuxterm +- Renamed app to cmux - Improved CI UI test stability ## [1.1.0] - 2025-01-28 diff --git a/CLAUDE.md b/CLAUDE.md index 66eaae69..709a0cdf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,4 +1,4 @@ -# cmuxterm agent notes +# cmux agent notes ## Initial setup @@ -83,7 +83,7 @@ ssh cmux-vm 'cd /Users/cmux/GhosttyTabs && xcodebuild -project GhosttyTabs.xcode Run basic automated tests on the UTM macOS VM (never on the host machine): ```bash -ssh cmux-vm 'cd /Users/cmux/GhosttyTabs && xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination "platform=macOS" build && pkill -x "cmuxterm DEV" || true && APP=$(find /Users/cmux/Library/Developer/Xcode/DerivedData -path "*/Build/Products/Debug/cmuxterm DEV.app" -print -quit) && open "$APP" && for i in {1..20}; do [ -S /tmp/cmuxterm.sock ] && break; sleep 0.5; done && python3 tests/test_update_timing.py && python3 tests/test_signals_auto.py && python3 tests/test_ctrl_socket.py && python3 tests/test_notifications.py' +ssh cmux-vm 'cd /Users/cmux/GhosttyTabs && xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination "platform=macOS" build && pkill -x "cmux DEV" || true && APP=$(find /Users/cmux/Library/Developer/Xcode/DerivedData -path "*/Build/Products/Debug/cmux DEV.app" -print -quit) && open "$APP" && for i in {1..20}; do [ -S /tmp/cmux.sock ] && break; sleep 0.5; done && python3 tests/test_update_timing.py && python3 tests/test_signals_auto.py && python3 tests/test_ctrl_socket.py && python3 tests/test_notifications.py' ``` ## Ghostty submodule workflow @@ -143,13 +143,13 @@ Manual release steps (if not using the command): ```bash git tag vX.Y.Z git push origin vX.Y.Z -gh run watch --repo manaflow-ai/cmuxterm +gh run watch --repo manaflow-ai/cmux ``` Notes: - Requires GitHub secrets: `APPLE_CERTIFICATE_BASE64`, `APPLE_CERTIFICATE_PASSWORD`, `APPLE_SIGNING_IDENTITY`, `APPLE_ID`, `APPLE_APP_SPECIFIC_PASSWORD`, `APPLE_TEAM_ID`. -- The release asset is `cmuxterm-macos.dmg` attached to the tag. -- README download button points to `releases/latest/download/cmuxterm-macos.dmg`. +- The release asset is `cmux-macos.dmg` attached to the tag. +- README download button points to `releases/latest/download/cmux-macos.dmg`. - Versioning: bump the minor version for updates unless explicitly asked otherwise. - Changelog: always update both `CHANGELOG.md` and the docs-site version. diff --git a/CLI/cmuxterm.swift b/CLI/cmux.swift similarity index 99% rename from CLI/cmuxterm.swift rename to CLI/cmux.swift index 984c4dab..fc9fc953 100644 --- a/CLI/cmuxterm.swift +++ b/CLI/cmux.swift @@ -129,7 +129,7 @@ struct CMUXCLI { let args: [String] func run() throws { - var socketPath = ProcessInfo.processInfo.environment["CMUX_SOCKET_PATH"] ?? "/tmp/cmuxterm.sock" + var socketPath = ProcessInfo.processInfo.environment["CMUX_SOCKET_PATH"] ?? "/tmp/cmux.sock" var jsonOutput = false var index = 1 @@ -640,10 +640,10 @@ struct CMUXCLI { private func usage() -> String { return """ - cmuxterm - control cmuxterm via Unix socket + cmux - control cmux via Unix socket Usage: - cmuxterm [--socket PATH] [--json] [options] + cmux [--socket PATH] [--json] [options] Commands: ping diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57199aa8..9e988ad6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -# Contributing to cmuxterm +# Contributing to cmux ## Prerequisites @@ -10,8 +10,8 @@ 1. Clone the repository with submodules: ```bash - git clone --recursive https://github.com/manaflow-ai/cmuxterm.git - cd cmuxterm + git clone --recursive https://github.com/manaflow-ai/cmux.git + cd cmux ``` 2. Run the setup script: @@ -20,7 +20,7 @@ ``` This will: - - Initialize git submodules (ghostty, homebrew-cmuxterm) + - Initialize git submodules (ghostty, homebrew-cmux) - Build the GhosttyKit.xcframework from source - Create the necessary symlinks @@ -53,7 +53,7 @@ zig build -Demit-xcframework=true -Doptimize=ReleaseFast ### Basic tests (run on VM) ```bash -ssh cmux-vm 'cd /Users/cmux/GhosttyTabs && xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination "platform=macOS" build && pkill -x "cmuxterm DEV" || true && APP=$(find /Users/cmux/Library/Developer/Xcode/DerivedData -path "*/Build/Products/Debug/cmuxterm DEV.app" -print -quit) && open "$APP" && for i in {1..20}; do [ -S /tmp/cmuxterm.sock ] && break; sleep 0.5; done && python3 tests/test_update_timing.py && python3 tests/test_signals_auto.py && python3 tests/test_ctrl_socket.py && python3 tests/test_notifications.py' +ssh cmux-vm 'cd /Users/cmux/GhosttyTabs && xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Debug -destination "platform=macOS" build && pkill -x "cmux DEV" || true && APP=$(find /Users/cmux/Library/Developer/Xcode/DerivedData -path "*/Build/Products/Debug/cmux DEV.app" -print -quit) && open "$APP" && for i in {1..20}; do [ -S /tmp/cmux.sock ] && break; sleep 0.5; done && python3 tests/test_update_timing.py && python3 tests/test_signals_auto.py && python3 tests/test_ctrl_socket.py && python3 tests/test_notifications.py' ``` ### UI tests (run on VM) diff --git a/GhosttyTabs.xcodeproj/project.pbxproj b/GhosttyTabs.xcodeproj/project.pbxproj index b4cf0cbb..bee3518a 100644 --- a/GhosttyTabs.xcodeproj/project.pbxproj +++ b/GhosttyTabs.xcodeproj/project.pbxproj @@ -42,8 +42,8 @@ A5001240 /* WindowDecorationsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A5001241 /* WindowDecorationsController.swift */; }; A5001100 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A5001101 /* Assets.xcassets */; }; A5001230 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = A5001231 /* Sparkle */; }; - B9000002A1B2C3D4E5F60719 /* cmuxterm.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9000001A1B2C3D4E5F60719 /* cmuxterm.swift */; }; - B900000BA1B2C3D4E5F60719 /* cmuxterm in Copy CLI */ = {isa = PBXBuildFile; fileRef = B9000004A1B2C3D4E5F60719 /* cmuxterm */; }; + B9000002A1B2C3D4E5F60719 /* cmux.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9000001A1B2C3D4E5F60719 /* cmux.swift */; }; + B900000BA1B2C3D4E5F60719 /* cmux in Copy CLI */ = {isa = PBXBuildFile; fileRef = B9000004A1B2C3D4E5F60719 /* cmux */; }; 84E00D47E4584162AE53BC8D /* xterm-ghostty in Resources */ = {isa = PBXBuildFile; fileRef = B2E7294509CC42FE9191870E /* xterm-ghostty */; }; C1D2E3F4A5B6C7D8E9F00001 /* shell-integration in Resources */ = {isa = PBXBuildFile; fileRef = C1D2E3F4A5B6C7D8E9F00002 /* shell-integration */; }; B9000012A1B2C3D4E5F60719 /* AutomationSocketUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B9000011A1B2C3D4E5F60719 /* AutomationSocketUITests.swift */; }; @@ -69,7 +69,7 @@ dstPath = "bin"; dstSubfolderSpec = 7; files = ( - B900000BA1B2C3D4E5F60719 /* cmuxterm in Copy CLI */, + B900000BA1B2C3D4E5F60719 /* cmux in Copy CLI */, ); name = "Copy CLI"; runOnlyForDeploymentPostprocessing = 0; @@ -88,13 +88,13 @@ isa = PBXContainerItemProxy; containerPortal = A5001070 /* Project object */; proxyType = 1; - remoteGlobalIDString = B9000005A1B2C3D4E5F60719 /* cmuxterm-cli */; - remoteInfo = "cmuxterm-cli"; + remoteGlobalIDString = B9000005A1B2C3D4E5F60719 /* cmux-cli */; + remoteInfo = "cmux-cli"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - A5001000 /* cmuxterm.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = cmuxterm.app; sourceTree = BUILT_PRODUCTS_DIR; }; + A5001000 /* cmux.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = cmux.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7E7E6EF344A568AC7FEE3715 /* GhosttyTabsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GhosttyTabsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; A5001011 /* cmuxApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = cmuxApp.swift; sourceTree = ""; }; A5001012 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -135,8 +135,8 @@ A5001101 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B2E7294509CC42FE9191870E /* xterm-ghostty */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ghostty/terminfo/78/xterm-ghostty"; sourceTree = ""; }; C1D2E3F4A5B6C7D8E9F00002 /* shell-integration */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "shell-integration"; sourceTree = ""; }; - B9000001A1B2C3D4E5F60719 /* cmuxterm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = cmuxterm.swift; sourceTree = ""; }; - B9000004A1B2C3D4E5F60719 /* cmuxterm */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cmuxterm; sourceTree = BUILT_PRODUCTS_DIR; }; + B9000001A1B2C3D4E5F60719 /* cmux.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = cmux.swift; sourceTree = ""; }; + B9000004A1B2C3D4E5F60719 /* cmux */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = cmux; sourceTree = BUILT_PRODUCTS_DIR; }; B9000011A1B2C3D4E5F60719 /* AutomationSocketUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutomationSocketUITests.swift; sourceTree = ""; }; B9000013A1B2C3D4E5F60719 /* JumpToUnreadUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumpToUnreadUITests.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -204,7 +204,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -euo pipefail\nDEST=\"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\nGHOSTTY_DEST=\"${DEST}/ghostty\"\nTERMINFO_DEST=\"${DEST}/terminfo\"\nSRC_SHARE=\"${SRCROOT}/ghostty/zig-out/share\"\nGHOSTTY_SRC=\"${SRC_SHARE}/ghostty\"\nTERMINFO_SRC=\"${SRC_SHARE}/terminfo\"\nFALLBACK_GHOSTTY=\"${SRCROOT}/Resources/ghostty\"\nFALLBACK_TERMINFO=\"${SRCROOT}/Resources/ghostty/terminfo\"\nTERMINFO_OVERLAY=\"${SRCROOT}/Resources/terminfo-overlay\"\nif [ -d \"$GHOSTTY_SRC\" ]; then\n mkdir -p \"$GHOSTTY_DEST\"\n rsync -a --delete \"$GHOSTTY_SRC/\" \"$GHOSTTY_DEST/\"\nelif [ -d \"$FALLBACK_GHOSTTY\" ]; then\n mkdir -p \"$GHOSTTY_DEST\"\n rsync -a --delete \"$FALLBACK_GHOSTTY/\" \"$GHOSTTY_DEST/\"\nfi\nif [ -d \"$TERMINFO_SRC\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a --delete \"$TERMINFO_SRC/\" \"$TERMINFO_DEST/\"\nelif [ -d \"$FALLBACK_TERMINFO\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a --delete \"$FALLBACK_TERMINFO/\" \"$TERMINFO_DEST/\"\nfi\n# Overlay any cmuxterm-specific terminfo adjustments.\n# This intentionally does not use --delete so we only patch specific entries.\nif [ -d \"$TERMINFO_OVERLAY\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a \"$TERMINFO_OVERLAY/\" \"$TERMINFO_DEST/\"\nfi\nINFO_PLIST=\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\nCOMMIT=\"$(git -C \"${SRCROOT}\" rev-parse --short=9 HEAD 2>/dev/null || true)\"\nif [ -n \"$COMMIT\" ] && [ -f \"$INFO_PLIST\" ]; then\n /usr/libexec/PlistBuddy -c \"Set :CMUXCommit $COMMIT\" \"$INFO_PLIST\" >/dev/null 2>&1 || /usr/libexec/PlistBuddy -c \"Add :CMUXCommit string $COMMIT\" \"$INFO_PLIST\" >/dev/null 2>&1 || true\nfi\n"; + shellScript = "set -euo pipefail\nDEST=\"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\nGHOSTTY_DEST=\"${DEST}/ghostty\"\nTERMINFO_DEST=\"${DEST}/terminfo\"\nSRC_SHARE=\"${SRCROOT}/ghostty/zig-out/share\"\nGHOSTTY_SRC=\"${SRC_SHARE}/ghostty\"\nTERMINFO_SRC=\"${SRC_SHARE}/terminfo\"\nFALLBACK_GHOSTTY=\"${SRCROOT}/Resources/ghostty\"\nFALLBACK_TERMINFO=\"${SRCROOT}/Resources/ghostty/terminfo\"\nTERMINFO_OVERLAY=\"${SRCROOT}/Resources/terminfo-overlay\"\nif [ -d \"$GHOSTTY_SRC\" ]; then\n mkdir -p \"$GHOSTTY_DEST\"\n rsync -a --delete \"$GHOSTTY_SRC/\" \"$GHOSTTY_DEST/\"\nelif [ -d \"$FALLBACK_GHOSTTY\" ]; then\n mkdir -p \"$GHOSTTY_DEST\"\n rsync -a --delete \"$FALLBACK_GHOSTTY/\" \"$GHOSTTY_DEST/\"\nfi\nif [ -d \"$TERMINFO_SRC\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a --delete \"$TERMINFO_SRC/\" \"$TERMINFO_DEST/\"\nelif [ -d \"$FALLBACK_TERMINFO\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a --delete \"$FALLBACK_TERMINFO/\" \"$TERMINFO_DEST/\"\nfi\n# Overlay any cmux-specific terminfo adjustments.\n# This intentionally does not use --delete so we only patch specific entries.\nif [ -d \"$TERMINFO_OVERLAY\" ]; then\n mkdir -p \"$TERMINFO_DEST\"\n rsync -a \"$TERMINFO_OVERLAY/\" \"$TERMINFO_DEST/\"\nfi\nINFO_PLIST=\"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}\"\nCOMMIT=\"$(git -C \"${SRCROOT}\" rev-parse --short=9 HEAD 2>/dev/null || true)\"\nif [ -n \"$COMMIT\" ] && [ -f \"$INFO_PLIST\" ]; then\n /usr/libexec/PlistBuddy -c \"Set :CMUXCommit $COMMIT\" \"$INFO_PLIST\" >/dev/null 2>&1 || /usr/libexec/PlistBuddy -c \"Add :CMUXCommit string $COMMIT\" \"$INFO_PLIST\" >/dev/null 2>&1 || true\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -265,7 +265,7 @@ B9000003A1B2C3D4E5F60719 /* CLI */ = { isa = PBXGroup; children = ( - B9000001A1B2C3D4E5F60719 /* cmuxterm.swift */, + B9000001A1B2C3D4E5F60719 /* cmux.swift */, ); path = CLI; sourceTree = ""; @@ -282,8 +282,8 @@ A5001042 /* Products */ = { isa = PBXGroup; children = ( - A5001000 /* cmuxterm.app */, - B9000004A1B2C3D4E5F60719 /* cmuxterm */, + A5001000 /* cmux.app */, + B9000004A1B2C3D4E5F60719 /* cmux */, 7E7E6EF344A568AC7FEE3715 /* GhosttyTabsUITests.xctest */, ); name = Products; @@ -325,12 +325,12 @@ ); name = GhosttyTabs; productName = GhosttyTabs; - productReference = A5001000 /* cmuxterm.app */; + productReference = A5001000 /* cmux.app */; productType = "com.apple.product-type.application"; }; - B9000005A1B2C3D4E5F60719 /* cmuxterm-cli */ = { + B9000005A1B2C3D4E5F60719 /* cmux-cli */ = { isa = PBXNativeTarget; - buildConfigurationList = B9000007A1B2C3D4E5F60719 /* Build configuration list for PBXNativeTarget "cmuxterm-cli" */; + buildConfigurationList = B9000007A1B2C3D4E5F60719 /* Build configuration list for PBXNativeTarget "cmux-cli" */; buildPhases = ( B9000006A1B2C3D4E5F60719 /* Sources */, B900000CA1B2C3D4E5F60719 /* Frameworks */, @@ -339,9 +339,9 @@ ); dependencies = ( ); - name = "cmuxterm-cli"; - productName = cmuxterm; - productReference = B9000004A1B2C3D4E5F60719 /* cmuxterm */; + name = "cmux-cli"; + productName = cmux; + productReference = B9000004A1B2C3D4E5F60719 /* cmux */; productType = "com.apple.product-type.tool"; }; CB450DF0F0B3839599082C4D /* GhosttyTabsUITests */ = { @@ -390,7 +390,7 @@ projectRoot = ""; targets = ( A5001050 /* GhosttyTabs */, - B9000005A1B2C3D4E5F60719 /* cmuxterm-cli */, + B9000005A1B2C3D4E5F60719 /* cmux-cli */, CB450DF0F0B3839599082C4D /* GhosttyTabsUITests */, ); }; @@ -450,7 +450,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B9000002A1B2C3D4E5F60719 /* cmuxterm.swift in Sources */, + B9000002A1B2C3D4E5F60719 /* cmux.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -464,7 +464,7 @@ }; B900000EA1B2C3D4E5F60719 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = B9000005A1B2C3D4E5F60719 /* cmuxterm-cli */; + target = B9000005A1B2C3D4E5F60719 /* cmux-cli */; targetProxy = B900000DA1B2C3D4E5F60719 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -538,23 +538,23 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = "cmuxterm DEV"; - INFOPLIST_KEY_CFBundleName = "cmuxterm DEV"; + INFOPLIST_KEY_CFBundleDisplayName = "cmux DEV"; + INFOPLIST_KEY_CFBundleName = "cmux DEV"; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = ""; INFOPLIST_KEY_NSPrincipalClass = NSApplication; - INFOPLIST_KEY_SUFeedURL = "https://github.com/manaflow-ai/cmuxterm/releases/latest/download/appcast.xml"; + INFOPLIST_KEY_SUFeedURL = "https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml"; INFOPLIST_KEY_SUPublicEDKey = "$(SPARKLE_PUBLIC_KEY)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.22.0; + MARKETING_VERSION = 1.23.0; OTHER_LDFLAGS = ( "-lc++", "-framework", @@ -568,8 +568,8 @@ "-framework", Carbon, ); - PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.app.debug; - PRODUCT_NAME = "cmuxterm DEV"; + PRODUCT_BUNDLE_IDENTIFIER = com.cmux.app.debug; + PRODUCT_NAME = "cmux DEV"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "cmux-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -583,23 +583,23 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_CFBundleDisplayName = cmuxterm; - INFOPLIST_KEY_CFBundleName = cmuxterm; + INFOPLIST_KEY_CFBundleDisplayName = cmux; + INFOPLIST_KEY_CFBundleName = cmux; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = ""; INFOPLIST_KEY_NSPrincipalClass = NSApplication; - INFOPLIST_KEY_SUFeedURL = "https://github.com/manaflow-ai/cmuxterm/releases/latest/download/appcast.xml"; + INFOPLIST_KEY_SUFeedURL = "https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml"; INFOPLIST_KEY_SUPublicEDKey = "$(SPARKLE_PUBLIC_KEY)"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.22.0; + MARKETING_VERSION = 1.23.0; OTHER_LDFLAGS = ( "-lc++", "-framework", @@ -614,8 +614,8 @@ Carbon, ); ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.app; - PRODUCT_NAME = cmuxterm; + PRODUCT_BUNDLE_IDENTIFIER = com.cmux.app; + PRODUCT_NAME = cmux; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_OBJC_BRIDGING_HEADER = "cmux-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -627,8 +627,8 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; MACOSX_DEPLOYMENT_TARGET = 13.0; - PRODUCT_NAME = cmuxterm; - PRODUCT_MODULE_NAME = cmuxterm_cli; + PRODUCT_NAME = cmux; + PRODUCT_MODULE_NAME = cmux_cli; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -640,8 +640,8 @@ buildSettings = { CODE_SIGN_STYLE = Automatic; MACOSX_DEPLOYMENT_TARGET = 13.0; - PRODUCT_NAME = cmuxterm; - PRODUCT_MODULE_NAME = cmuxterm_cli; + PRODUCT_NAME = cmux; + PRODUCT_MODULE_NAME = cmux_cli; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; @@ -652,12 +652,12 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.22.0; + MARKETING_VERSION = 1.23.0; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.appuitests; + PRODUCT_BUNDLE_IDENTIFIER = com.cmux.appuitests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; SWIFT_VERSION = 5.0; @@ -669,12 +669,12 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 33; + CURRENT_PROJECT_VERSION = 34; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.22.0; + MARKETING_VERSION = 1.23.0; ONLY_ACTIVE_ARCH = YES; - PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.appuitests; + PRODUCT_BUNDLE_IDENTIFIER = com.cmux.appuitests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_TARGET_NAME = GhosttyTabs; @@ -734,7 +734,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B9000007A1B2C3D4E5F60719 /* Build configuration list for PBXNativeTarget "cmuxterm-cli" */ = { + B9000007A1B2C3D4E5F60719 /* Build configuration list for PBXNativeTarget "cmux-cli" */ = { isa = XCConfigurationList; buildConfigurations = ( B9000008A1B2C3D4E5F60719 /* Debug */, diff --git a/GhosttyTabs.xcodeproj/xcshareddata/xcschemes/cmux.xcscheme b/GhosttyTabs.xcodeproj/xcshareddata/xcschemes/cmux.xcscheme index 409b5318..f326bfd8 100644 --- a/GhosttyTabs.xcodeproj/xcshareddata/xcschemes/cmux.xcscheme +++ b/GhosttyTabs.xcodeproj/xcshareddata/xcschemes/cmux.xcscheme @@ -3,7 +3,7 @@ - + @@ -14,17 +14,17 @@ - + - + - + diff --git a/GhosttyTabsUITests/AutomationSocketUITests.swift b/GhosttyTabsUITests/AutomationSocketUITests.swift index e4a5fc86..764adf3e 100644 --- a/GhosttyTabsUITests/AutomationSocketUITests.swift +++ b/GhosttyTabsUITests/AutomationSocketUITests.swift @@ -3,14 +3,14 @@ import Foundation final class AutomationSocketUITests: XCTestCase { private var socketPath = "" - private let defaultsDomain = "com.cmuxterm.app.debug" + private let defaultsDomain = "com.cmux.app.debug" private let modeKey = "socketControlMode" private let legacyKey = "socketControlEnabled" override func setUp() { super.setUp() continueAfterFailure = false - socketPath = "/tmp/cmuxterm-debug-\(UUID().uuidString).sock" + socketPath = "/tmp/cmux-debug-\(UUID().uuidString).sock" resetSocketDefaults() removeSocketFile() } @@ -75,7 +75,7 @@ final class AutomationSocketUITests: XCTestCase { guard let entries = try? FileManager.default.contentsOfDirectory(atPath: tmpPath) else { return nil } - let matches = entries.filter { $0.hasPrefix("cmuxterm") && $0.hasSuffix(".sock") } + let matches = entries.filter { $0.hasPrefix("cmux") && $0.hasSuffix(".sock") } if let debug = matches.first(where: { $0.contains("debug") }) { return (tmpPath as NSString).appendingPathComponent(debug) } diff --git a/GhosttyTabsUITests/UpdatePillUITests.swift b/GhosttyTabsUITests/UpdatePillUITests.swift index ebcafb9b..4c7c54cc 100644 --- a/GhosttyTabsUITests/UpdatePillUITests.swift +++ b/GhosttyTabsUITests/UpdatePillUITests.swift @@ -113,7 +113,7 @@ final class UpdatePillUITests: XCTestCase { private func launchAppWithMockFeed(mode: String, version: String, timingPath: URL? = nil) -> XCUIApplication { let app = XCUIApplication() app.launchEnvironment["CMUX_UI_TEST_MODE"] = "1" - app.launchEnvironment["CMUX_UI_TEST_FEED_URL"] = "https://cmuxterm.test/appcast.xml" + app.launchEnvironment["CMUX_UI_TEST_FEED_URL"] = "https://cmux.test/appcast.xml" app.launchEnvironment["CMUX_UI_TEST_FEED_MODE"] = mode app.launchEnvironment["CMUX_UI_TEST_UPDATE_VERSION"] = version app.launchEnvironment["CMUX_UI_TEST_AUTO_ALLOW_PERMISSION"] = "1" diff --git a/README.md b/README.md index 0e95d6fd..df53a44a 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ -

cmuxterm

+

cmux

A Ghostty-based macOS terminal with vertical tabs and notifications for AI coding agents

- - Download cmuxterm for macOS + + Download cmux for macOS

- cmuxterm screenshot + cmux screenshot

## Features @@ -25,14 +25,14 @@ **Homebrew:** ```bash -brew tap manaflow-ai/cmuxterm -brew install --cask cmuxterm +brew tap manaflow-ai/cmux +brew install --cask cmux ``` -Or [download the DMG](https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg) directly. +Or [download the DMG](https://github.com/manaflow-ai/cmux/releases/latest/download/cmux-macos.dmg) directly. -## Why cmuxterm? +## Why cmux? -Running multiple AI coding agents? cmuxterm helps you manage them. Instead of losing track of which terminal needs input, the notification panel shows you exactly where to look. +Running multiple AI coding agents? cmux helps you manage them. Instead of losing track of which terminal needs input, the notification panel shows you exactly where to look. A native macOS app means it launches instantly, uses minimal RAM, and feels right at home on your Mac. diff --git a/Resources/shell-integration/.zlogin b/Resources/shell-integration/.zlogin index ccd06471..5bdbd6cc 100644 --- a/Resources/shell-integration/.zlogin +++ b/Resources/shell-integration/.zlogin @@ -1,6 +1,6 @@ # vim:ft=zsh # -# Compatibility shim: with the current integration model, cmuxterm restores +# Compatibility shim: with the current integration model, cmux restores # ZDOTDIR in .zshenv so this file should never be reached. If it is, restore # ZDOTDIR and behave like vanilla zsh by sourcing the user's .zlogin. diff --git a/Resources/shell-integration/.zprofile b/Resources/shell-integration/.zprofile index 135c5f38..930de65a 100644 --- a/Resources/shell-integration/.zprofile +++ b/Resources/shell-integration/.zprofile @@ -1,6 +1,6 @@ # vim:ft=zsh # -# Compatibility shim: with the current integration model, cmuxterm restores +# Compatibility shim: with the current integration model, cmux restores # ZDOTDIR in .zshenv so this file should never be reached. If it is, restore # ZDOTDIR and behave like vanilla zsh by sourcing the user's .zprofile. diff --git a/Resources/shell-integration/.zshenv b/Resources/shell-integration/.zshenv index b7306e37..21570241 100644 --- a/Resources/shell-integration/.zshenv +++ b/Resources/shell-integration/.zshenv @@ -1,16 +1,16 @@ # vim:ft=zsh # -# cmuxterm ZDOTDIR bootstrap for zsh. +# cmux ZDOTDIR bootstrap for zsh. # # GhosttyKit already uses a ZDOTDIR injection mechanism for zsh (setting ZDOTDIR -# to Ghostty's integration dir). cmuxterm also needs to run its integration, but +# to Ghostty's integration dir). cmux also needs to run its integration, but # we must restore the user's real ZDOTDIR immediately so that: # - /etc/zshrc sets HISTFILE relative to the real ZDOTDIR/HOME (shared history) # - zsh loads the user's real .zprofile/.zshrc normally (no wrapper recursion) # # We restore ZDOTDIR from (in priority order): # - GHOSTTY_ZSH_ZDOTDIR (set by GhosttyKit when it overwrote ZDOTDIR) -# - CMUX_ZSH_ZDOTDIR (set by cmuxterm when it overwrote a user-provided ZDOTDIR) +# - CMUX_ZSH_ZDOTDIR (set by cmux when it overwrote a user-provided ZDOTDIR) # - unset (zsh treats unset ZDOTDIR as $HOME) if [[ -n "${GHOSTTY_ZSH_ZDOTDIR+X}" ]]; then @@ -36,7 +36,7 @@ fi [[ -r "$_cmux_ghostty" ]] && builtin source -- "$_cmux_ghostty" fi - # Load cmuxterm integration (unless disabled) + # Load cmux integration (unless disabled) if [[ "${CMUX_SHELL_INTEGRATION:-1}" != "0" && -n "${CMUX_SHELL_INTEGRATION_DIR:-}" ]]; then builtin typeset _cmux_integ="$CMUX_SHELL_INTEGRATION_DIR/cmux-zsh-integration.zsh" [[ -r "$_cmux_integ" ]] && builtin source -- "$_cmux_integ" diff --git a/Resources/shell-integration/.zshrc b/Resources/shell-integration/.zshrc index 9f3a379d..6179833e 100644 --- a/Resources/shell-integration/.zshrc +++ b/Resources/shell-integration/.zshrc @@ -1,6 +1,6 @@ # vim:ft=zsh # -# Compatibility shim: with the current integration model, cmuxterm restores +# Compatibility shim: with the current integration model, cmux restores # ZDOTDIR in .zshenv so this file should never be reached. If it is, restore # ZDOTDIR and behave like vanilla zsh by sourcing the user's .zshrc. diff --git a/Resources/shell-integration/cmux-bash-integration.bash b/Resources/shell-integration/cmux-bash-integration.bash index f179f7cd..79787d5a 100644 --- a/Resources/shell-integration/cmux-bash-integration.bash +++ b/Resources/shell-integration/cmux-bash-integration.bash @@ -1,4 +1,4 @@ -# cmuxterm shell integration for bash +# cmux shell integration for bash _cmux_send() { local payload="$1" @@ -10,7 +10,7 @@ _cmux_send() { # Some nc builds don't support unix sockets, but keep as a last-ditch fallback. # # Important: macOS/BSD nc will often wait for the peer to close the socket - # after it has finished writing. cmuxterm keeps the connection open, so + # after it has finished writing. cmux keeps the connection open, so # a plain `nc -U` can hang indefinitely and leak background processes. # # Prefer flags that guarantee we exit after sending, and fall back to a diff --git a/Resources/shell-integration/cmux-zsh-integration.zsh b/Resources/shell-integration/cmux-zsh-integration.zsh index 1f50aa21..7e77eef1 100644 --- a/Resources/shell-integration/cmux-zsh-integration.zsh +++ b/Resources/shell-integration/cmux-zsh-integration.zsh @@ -1,4 +1,4 @@ -# cmuxterm shell integration for zsh +# cmux shell integration for zsh # Injected automatically — do not source manually _cmux_send() { @@ -11,7 +11,7 @@ _cmux_send() { # Some nc builds don't support unix sockets, but keep as a last-ditch fallback. # # Important: macOS/BSD nc will often wait for the peer to close the socket - # after it has finished writing. cmuxterm keeps the connection open, so + # after it has finished writing. cmux keeps the connection open, so # a plain `nc -U` can hang indefinitely and leak background processes. # # Prefer flags that guarantee we exit after sending, and fall back to a diff --git a/Resources/terminfo-overlay/README.md b/Resources/terminfo-overlay/README.md index 8efd8e26..eda9ee2a 100644 --- a/Resources/terminfo-overlay/README.md +++ b/Resources/terminfo-overlay/README.md @@ -1,14 +1,14 @@ -# cmuxterm terminfo overlay +# cmux terminfo overlay -cmuxterm ships Ghostty's `xterm-ghostty` terminfo entry, but the embedded -renderer in cmuxterm has differed from Ghostty's app renderer in how it treats +cmux ships Ghostty's `xterm-ghostty` terminfo entry, but the embedded +renderer in cmux has differed from Ghostty's app renderer in how it treats the "bright" SGR 90-97/100-107 sequences. This overlay patches the terminfo capabilities so that `tput setaf 8` (and similar "bright" colors) uses 256-color indexed sequences (`38;5;m` / `48;5;m`) rather than SGR 90-97/100-107. This avoids relying on bright SGR handling and fixes zsh-autosuggestions (default `fg=8`) visibility issues in -cmuxterm. +cmux. The build phase `Copy Ghostty Resources` overlays this directory onto the app bundle's `Contents/Resources/terminfo` after copying Ghostty's resources. diff --git a/Sources/SocketControlSettings.swift b/Sources/SocketControlSettings.swift index 653c1b6f..050d47ff 100644 --- a/Sources/SocketControlSettings.swift +++ b/Sources/SocketControlSettings.swift @@ -47,9 +47,9 @@ struct SocketControlSettings { return override } #if DEBUG - return "/tmp/cmuxterm-debug.sock" + return "/tmp/cmux-debug.sock" #else - return "/tmp/cmuxterm.sock" + return "/tmp/cmux.sock" #endif } diff --git a/Sources/TabManager.swift b/Sources/TabManager.swift index 04d60c9c..94772d9d 100644 --- a/Sources/TabManager.swift +++ b/Sources/TabManager.swift @@ -759,13 +759,13 @@ class TabManager: ObservableObject { } private func windowTitle(for tab: Tab?) -> String { - guard let tab else { return "cmuxterm" } + guard let tab else { return "cmux" } let trimmedTitle = tab.title.trimmingCharacters(in: .whitespacesAndNewlines) if !trimmedTitle.isEmpty { return trimmedTitle } let trimmedDirectory = tab.currentDirectory.trimmingCharacters(in: .whitespacesAndNewlines) - return trimmedDirectory.isEmpty ? "cmuxterm" : trimmedDirectory + return trimmedDirectory.isEmpty ? "cmux" : trimmedDirectory } func focusTab(_ tabId: UUID, surfaceId: UUID? = nil, suppressFlash: Bool = false) { diff --git a/Sources/TerminalController.swift b/Sources/TerminalController.swift index 1bd0e44f..2f46af08 100644 --- a/Sources/TerminalController.swift +++ b/Sources/TerminalController.swift @@ -7,7 +7,7 @@ import Foundation class TerminalController { static let shared = TerminalController() - private var socketPath = "/tmp/cmuxterm.sock" + private var socketPath = "/tmp/cmux.sock" private var serverSocket: Int32 = -1 private var isRunning = false private var clientHandlers: [Int32: Thread] = [:] diff --git a/Sources/TerminalNotificationStore.swift b/Sources/TerminalNotificationStore.swift index fb5dfb62..5ac8fa32 100644 --- a/Sources/TerminalNotificationStore.swift +++ b/Sources/TerminalNotificationStore.swift @@ -34,8 +34,8 @@ struct TerminalNotification: Identifiable, Hashable { final class TerminalNotificationStore: ObservableObject { static let shared = TerminalNotificationStore() - static let categoryIdentifier = "com.cmuxterm.app.userNotification" - static let actionShowIdentifier = "com.cmuxterm.app.userNotification.show" + static let categoryIdentifier = "com.cmux.app.userNotification" + static let actionShowIdentifier = "com.cmux.app.userNotification.show" @Published private(set) var notifications: [TerminalNotification] = [] @@ -176,7 +176,7 @@ final class TerminalNotificationStore: ObservableObject { let content = UNMutableNotificationContent() let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String - ?? "cmuxterm" + ?? "cmux" content.title = notification.title.isEmpty ? appName : notification.title content.subtitle = notification.subtitle content.body = notification.body @@ -242,8 +242,8 @@ final class TerminalNotificationStore: ObservableObject { self.hasPromptedForSettings = true let alert = NSAlert() - alert.messageText = "Enable Notifications for cmuxterm" - alert.informativeText = "Notifications are disabled for cmuxterm. Enable them in System Settings to see alerts." + alert.messageText = "Enable Notifications for cmux" + alert.informativeText = "Notifications are disabled for cmux. Enable them in System Settings to see alerts." alert.addButton(withTitle: "Open Settings") alert.addButton(withTitle: "Not Now") let response = alert.runModal() diff --git a/Sources/Update/UpdateController.swift b/Sources/Update/UpdateController.swift index ff91225f..dfd1cfff 100644 --- a/Sources/Update/UpdateController.swift +++ b/Sources/Update/UpdateController.swift @@ -3,7 +3,7 @@ import Cocoa import Combine import SwiftUI -/// Controller for managing Sparkle updates in cmuxterm. +/// Controller for managing Sparkle updates in cmux. class UpdateController { private(set) var updater: SPUUpdater private let userDriver: UpdateDriver diff --git a/Sources/Update/UpdateDelegate.swift b/Sources/Update/UpdateDelegate.swift index 7e1f5ba0..269f3052 100644 --- a/Sources/Update/UpdateDelegate.swift +++ b/Sources/Update/UpdateDelegate.swift @@ -12,7 +12,7 @@ extension UpdateDriver: SPUUpdaterDelegate { } #endif let infoURL = Bundle.main.object(forInfoDictionaryKey: "SUFeedURL") as? String - let fallback = "https://github.com/manaflow-ai/cmuxterm/releases/latest/download/appcast.xml" + let fallback = "https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml" let feedURLString = (infoURL?.isEmpty == false) ? infoURL! : fallback recordFeedURLString(feedURLString, usedFallback: feedURLString == fallback) return feedURLString diff --git a/Sources/Update/UpdateDriver.swift b/Sources/Update/UpdateDriver.swift index 5a00802b..6f73d23d 100644 --- a/Sources/Update/UpdateDriver.swift +++ b/Sources/Update/UpdateDriver.swift @@ -56,7 +56,7 @@ class UpdateDriver: NSObject, SPUUserDriver { } func showUpdateReleaseNotes(with downloadData: SPUDownloadData) { - // cmuxterm uses Sparkle's UI for release notes links instead. + // cmux uses Sparkle's UI for release notes links instead. } func showUpdateReleaseNotesFailedToDownloadWithError(_ error: any Error) { diff --git a/Sources/Update/UpdateLogStore.swift b/Sources/Update/UpdateLogStore.swift index e130420a..a42f0e10 100644 --- a/Sources/Update/UpdateLogStore.swift +++ b/Sources/Update/UpdateLogStore.swift @@ -4,7 +4,7 @@ import AppKit final class UpdateLogStore { static let shared = UpdateLogStore() - private let queue = DispatchQueue(label: "cmuxterm.update.log") + private let queue = DispatchQueue(label: "cmux.update.log") private var entries: [String] = [] private let maxEntries = 200 private let maxFileSize: UInt64 = 256 * 1024 // 256 KB @@ -16,7 +16,7 @@ final class UpdateLogStore { formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] let logsDir = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first ?? FileManager.default.temporaryDirectory - logURL = logsDir.appendingPathComponent("Logs/cmuxterm-update.log") + logURL = logsDir.appendingPathComponent("Logs/cmux-update.log") ensureLogFile() } @@ -84,7 +84,7 @@ final class UpdateLogStore { final class FocusLogStore { static let shared = FocusLogStore() - private let queue = DispatchQueue(label: "cmuxterm.focus.log") + private let queue = DispatchQueue(label: "cmux.focus.log") private var entries: [String] = [] private let maxEntries = 400 private let maxFileSize: UInt64 = 256 * 1024 // 256 KB @@ -96,7 +96,7 @@ final class FocusLogStore { formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] let logsDir = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first ?? FileManager.default.temporaryDirectory - logURL = logsDir.appendingPathComponent("Logs/cmuxterm-focus.log") + logURL = logsDir.appendingPathComponent("Logs/cmux-focus.log") ensureLogFile() } diff --git a/Sources/Update/UpdatePopoverView.swift b/Sources/Update/UpdatePopoverView.swift index d4d3ce4d..5cce9543 100644 --- a/Sources/Update/UpdatePopoverView.swift +++ b/Sources/Update/UpdatePopoverView.swift @@ -52,7 +52,7 @@ fileprivate struct PermissionRequestView: View { Text("Enable automatic updates?") .font(.system(size: 13, weight: .semibold)) - Text("cmuxterm can automatically check for updates in the background.") + Text("cmux can automatically check for updates in the background.") .font(.system(size: 11)) .foregroundColor(.secondary) .fixedSize(horizontal: false, vertical: true) diff --git a/Sources/Update/UpdateTestSupport.swift b/Sources/Update/UpdateTestSupport.swift index 86748f86..ea822889 100644 --- a/Sources/Update/UpdateTestSupport.swift +++ b/Sources/Update/UpdateTestSupport.swift @@ -61,13 +61,13 @@ enum UpdateTestSupport { private static func makeAppcastItem(displayVersion: String) -> SUAppcastItem? { let enclosure: [String: Any] = [ - "url": "https://example.com/cmuxterm.zip", + "url": "https://example.com/cmux.zip", "length": "1024", "sparkle:version": displayVersion, "sparkle:shortVersionString": displayVersion, ] let dict: [String: Any] = [ - "title": "cmuxterm \(displayVersion)", + "title": "cmux \(displayVersion)", "enclosure": enclosure, ] return SUAppcastItem(dictionary: dict) diff --git a/Sources/Update/UpdateTestURLProtocol.swift b/Sources/Update/UpdateTestURLProtocol.swift index 6c6fe575..05508618 100644 --- a/Sources/Update/UpdateTestURLProtocol.swift +++ b/Sources/Update/UpdateTestURLProtocol.swift @@ -2,9 +2,9 @@ import Foundation final class UpdateTestURLProtocol: URLProtocol { - static let host = "cmuxterm.test" + static let host = "cmux.test" static let appcastPath = "/appcast.xml" - static let updatePath = "/cmuxterm-test.zip" + static let updatePath = "/cmux-test.zip" private static var isRegistered = false private static let registrationLock = NSLock() @@ -84,7 +84,7 @@ final class UpdateTestURLProtocol: URLProtocol { } else { item = """ - cmuxterm \(version) + cmux \(version) \(version) \(version) @@ -98,7 +98,7 @@ final class UpdateTestURLProtocol: URLProtocol { xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/"> - cmuxterm Test Updates + cmux Test Updates https://\(host) Test updates feed en @@ -111,7 +111,7 @@ final class UpdateTestURLProtocol: URLProtocol { } private static func updateArchiveData() -> Data { - Data("cmuxterm test update".utf8) + Data("cmux test update".utf8) } } #endif diff --git a/Sources/Update/UpdateViewModel.swift b/Sources/Update/UpdateViewModel.swift index 7fc0bc4f..42a0ac02 100644 --- a/Sources/Update/UpdateViewModel.swift +++ b/Sources/Update/UpdateViewModel.swift @@ -216,13 +216,13 @@ class UpdateViewModel: ObservableObject { if let networkError = networkError(from: nsError) { switch networkError.code { case NSURLErrorNotConnectedToInternet: - return "cmuxterm can’t reach the update server. Check your internet connection and try again." + return "cmux can't reach the update server. Check your internet connection and try again." case NSURLErrorTimedOut: return "The update server took too long to respond. Try again in a moment." case NSURLErrorCannotFindHost: return "The update server can’t be found. Check your connection or try again later." case NSURLErrorCannotConnectToHost: - return "cmuxterm couldn’t connect to the update server. Check your connection or try again later." + return "cmux couldn't connect to the update server. Check your connection or try again later." case NSURLErrorNetworkConnectionLost: return "The network connection was lost while checking for updates. Try again." case NSURLErrorSecureConnectionFailed, @@ -238,7 +238,7 @@ class UpdateViewModel: ObservableObject { if nsError.domain == SUSparkleErrorDomain { switch nsError.code { case 2001: - return "cmuxterm couldn't download the update feed. Check your connection and try again." + return "cmux couldn't download the update feed. Check your connection and try again." case 1000, 1002: return "The update feed could not be read. Please try again later." case 4: @@ -248,7 +248,7 @@ class UpdateViewModel: ObservableObject { case 1, 2, 3001, 3002: return "The update's signature could not be verified. Please try again later." case 1003, 1005, 4005: - return "Move cmuxterm into Applications and relaunch to enable updates." + return "Move cmux into Applications and relaunch to enable updates." default: break } @@ -437,7 +437,7 @@ enum UpdateState: Equatable { if let semver = Self.extractSemanticVersion(from: version) { let tag = semver.hasPrefix("v") ? semver : "v\(semver)" - if let url = URL(string: "https://github.com/manaflow-ai/cmuxterm/releases/tag/\(tag)") { + if let url = URL(string: "https://github.com/manaflow-ai/cmux/releases/tag/\(tag)") { self = .tagged(url) return } @@ -447,7 +447,7 @@ enum UpdateState: Equatable { return nil } - if let url = URL(string: "https://github.com/manaflow-ai/cmuxterm/commit/\(newHash)") { + if let url = URL(string: "https://github.com/manaflow-ai/cmux/commit/\(newHash)") { self = .commit(url) } else { return nil diff --git a/Sources/cmuxApp.swift b/Sources/cmuxApp.swift index 8252f2d7..e2936dc0 100644 --- a/Sources/cmuxApp.swift +++ b/Sources/cmuxApp.swift @@ -128,7 +128,7 @@ struct cmuxApp: App { .windowResizability(.contentMinSize) .commands { CommandGroup(replacing: .appInfo) { - Button("About cmuxterm") { + Button("About cmux") { showAboutPanel() } Button("Ghostty Settings…") { @@ -462,7 +462,7 @@ private final class SidebarDebugWindowController: NSWindowController, NSWindowDe private struct AboutPanelView: View { @Environment(\.openURL) private var openURL - private let githubURL = URL(string: "https://github.com/manaflow-ai/cmuxterm") + private let githubURL = URL(string: "https://github.com/manaflow-ai/cmux") private let docsURL = URL(string: "https://term.cmux.dev") private var version: String? { Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String } @@ -486,7 +486,7 @@ private struct AboutPanelView: View { VStack(alignment: .center, spacing: 32) { VStack(alignment: .center, spacing: 8) { - Text("cmuxterm") + Text("cmux") .bold() .font(.title) Text("A Ghostty-based terminal with vertical tabs\nand a notification panel for macOS.") @@ -507,7 +507,7 @@ private struct AboutPanelView: View { } let commitText = commit ?? "—" let commitURL = commit.flatMap { hash in - URL(string: "https://github.com/manaflow-ai/cmuxterm/commit/\(hash)") + URL(string: "https://github.com/manaflow-ai/cmux/commit/\(hash)") } AboutPropertyRow(label: "Commit", text: commitText, url: commitURL) } diff --git a/TODO.md b/TODO.md index 1f576806..61afca62 100644 --- a/TODO.md +++ b/TODO.md @@ -8,7 +8,7 @@ - Opens a new terminal - Shows user the diff to their config file (claude.json, opencode config, codex config, etc.) - Prompts user to type 'y' to confirm - - Implement as part of `cmuxterm` CLI, menubar just triggers the CLI command + - Implement as part of `cmux` CLI, menubar just triggers the CLI command ## Additional Integrations - [ ] Codex integration diff --git a/docs-site/README.md b/docs-site/README.md index 1e95125b..c24ce69d 100644 --- a/docs-site/README.md +++ b/docs-site/README.md @@ -1,6 +1,6 @@ -# cmuxterm Documentation +# cmux Documentation -Documentation website for [cmuxterm](https://github.com/manaflow-ai/cmuxterm), built with [Fumadocs](https://fumadocs.vercel.app) and Next.js. +Documentation website for [cmux](https://github.com/manaflow-ai/cmux), built with [Fumadocs](https://fumadocs.vercel.app) and Next.js. ## Development diff --git a/docs-site/app/(docs)/layout.tsx b/docs-site/app/(docs)/layout.tsx index e1241497..1dbf7cd5 100644 --- a/docs-site/app/(docs)/layout.tsx +++ b/docs-site/app/(docs)/layout.tsx @@ -7,7 +7,7 @@ export default function Layout({ children }: { children: ReactNode }) { /dev/null && echo "cmuxterm available" +command -v cmux &>/dev/null && echo "cmux available" ``` **3. Check the TERM_PROGRAM environment variable:** ```bash -[ "$TERM_PROGRAM" = "ghostty" ] && [ -S /tmp/cmuxterm.sock ] && echo "In cmuxterm" +[ "$TERM_PROGRAM" = "ghostty" ] && [ -S /tmp/cmux.sock ] && echo "In cmux" ``` - cmuxterm sets `TERM_PROGRAM=ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty. + cmux sets `TERM_PROGRAM=ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty. ## Setting Up Hooks @@ -46,12 +46,12 @@ Claude Code supports hooks that run on specific events. Add these to your `~/.cl { "matcher": "Task", "hooks": [ - "/path/to/cmuxterm-notify.sh" + "/path/to/cmux-notify.sh" ] } ], "Stop": [ - "/path/to/cmuxterm-notify.sh" + "/path/to/cmux-notify.sh" ] } } @@ -59,14 +59,14 @@ Claude Code supports hooks that run on specific events. Add these to your `~/.cl ## Notification Hook Script -Create a script that checks for cmuxterm and sends notifications: +Create a script that checks for cmux and sends notifications: ```bash #!/bin/bash -# ~/.claude/hooks/cmuxterm-notify.sh +# ~/.claude/hooks/cmux-notify.sh -# Only proceed if we're in cmuxterm -if [ ! -S /tmp/cmuxterm.sock ]; then +# Only proceed if we're in cmux +if [ ! -S /tmp/cmux.sock ]; then exit 0 fi @@ -80,14 +80,14 @@ SESSION=$(echo "$EVENT" | jq -r '.session_id // ""' | cut -c1-8) case "$EVENT_TYPE" in "Stop") - cmuxterm notify \ + cmux notify \ --title "Claude Code" \ --subtitle "Task Complete" \ --body "Session $SESSION finished" ;; "PostToolUse") if [ "$TOOL_NAME" = "Task" ]; then - cmuxterm notify \ + cmux notify \ --title "Claude Code" \ --subtitle "Agent Finished" \ --body "Task agent completed in session $SESSION" @@ -99,7 +99,7 @@ esac Make it executable: ```bash -chmod +x ~/.claude/hooks/cmuxterm-notify.sh +chmod +x ~/.claude/hooks/cmux-notify.sh ``` ## Example Configurations @@ -112,7 +112,7 @@ Get notified whenever Claude Code finishes a task: { "hooks": { "Stop": [ - "~/.claude/hooks/cmuxterm-notify.sh" + "~/.claude/hooks/cmux-notify.sh" ] } } @@ -128,7 +128,7 @@ Only notify for Task tool completions (agent subprocesses): "PostToolUse": [ { "matcher": "Task", - "hooks": ["~/.claude/hooks/cmuxterm-notify.sh"] + "hooks": ["~/.claude/hooks/cmux-notify.sh"] } ] } @@ -141,9 +141,9 @@ Add error notifications: ```bash #!/bin/bash -# cmuxterm-notify.sh with error handling +# cmux-notify.sh with error handling -if [ ! -S /tmp/cmuxterm.sock ]; then +if [ ! -S /tmp/cmux.sock ]; then exit 0 fi @@ -152,11 +152,11 @@ EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"') ERROR=$(echo "$EVENT" | jq -r '.error // ""') if [ -n "$ERROR" ] && [ "$ERROR" != "null" ]; then - cmuxterm notify \ + cmux notify \ --title "Claude Code Error" \ --body "$ERROR" elif [ "$EVENT_TYPE" = "Stop" ]; then - cmuxterm notify \ + cmux notify \ --title "Claude Code" \ --body "Task complete" fi @@ -168,20 +168,20 @@ Only notify if the terminal is not focused: ```bash #!/bin/bash -# cmuxterm-notify.sh with focus detection +# cmux-notify.sh with focus detection -if [ ! -S /tmp/cmuxterm.sock ]; then +if [ ! -S /tmp/cmux.sock ]; then exit 0 fi -# cmuxterm automatically suppresses notifications for focused tabs, +# cmux automatically suppresses notifications for focused tabs, # so we can always send - it will handle suppression for us EVENT=$(cat) EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"') if [ "$EVENT_TYPE" = "Stop" ]; then - cmuxterm notify \ + cmux notify \ --title "Claude Code" \ --subtitle "Ready" \ --body "Waiting for your input" @@ -196,7 +196,7 @@ If you prefer not to use the CLI, you can emit OSC sequences directly: #!/bin/bash # Direct OSC notification (no CLI needed) -if [ ! -S /tmp/cmuxterm.sock ]; then +if [ ! -S /tmp/cmux.sock ]; then exit 0 fi @@ -220,12 +220,12 @@ mkdir -p ~/.claude/hooks 2. Create the notification script: ```bash -cat > ~/.claude/hooks/cmuxterm-notify.sh << 'EOF' +cat > ~/.claude/hooks/cmux-notify.sh << 'EOF' #!/bin/bash -# cmuxterm notification hook for Claude Code +# cmux notification hook for Claude Code -# Skip if not in cmuxterm -[ -S /tmp/cmuxterm.sock ] || exit 0 +# Skip if not in cmux +[ -S /tmp/cmux.sock ] || exit 0 EVENT=$(cat) EVENT_TYPE=$(echo "$EVENT" | jq -r '.event // "unknown"') @@ -233,14 +233,14 @@ TOOL=$(echo "$EVENT" | jq -r '.tool_name // ""') case "$EVENT_TYPE" in "Stop") - cmuxterm notify --title "Claude Code" --body "Session complete" + cmux notify --title "Claude Code" --body "Session complete" ;; "PostToolUse") - [ "$TOOL" = "Task" ] && cmuxterm notify --title "Claude Code" --body "Agent finished" + [ "$TOOL" = "Task" ] && cmux notify --title "Claude Code" --body "Agent finished" ;; esac EOF -chmod +x ~/.claude/hooks/cmuxterm-notify.sh +chmod +x ~/.claude/hooks/cmux-notify.sh ``` 3. Configure Claude Code: @@ -249,11 +249,11 @@ chmod +x ~/.claude/hooks/cmuxterm-notify.sh cat > ~/.claude/settings.json << 'EOF' { "hooks": { - "Stop": ["~/.claude/hooks/cmuxterm-notify.sh"], + "Stop": ["~/.claude/hooks/cmux-notify.sh"], "PostToolUse": [ { "matcher": "Task", - "hooks": ["~/.claude/hooks/cmuxterm-notify.sh"] + "hooks": ["~/.claude/hooks/cmux-notify.sh"] } ] } @@ -263,4 +263,4 @@ EOF 4. Restart Claude Code to apply the hooks. -Now you'll receive desktop notifications in cmuxterm whenever Claude Code finishes a task or needs attention. +Now you'll receive desktop notifications in cmux whenever Claude Code finishes a task or needs attention. diff --git a/docs-site/content/docs/cli.mdx b/docs-site/content/docs/cli.mdx index a537243d..8fded89c 100644 --- a/docs-site/content/docs/cli.mdx +++ b/docs-site/content/docs/cli.mdx @@ -1,19 +1,19 @@ --- title: CLI Reference -description: Command-line interface for cmuxterm +description: Command-line interface for cmux --- # CLI Reference -cmuxterm includes a command-line tool for controlling the terminal from scripts and other tools. +cmux includes a command-line tool for controlling the terminal from scripts and other tools. ## Installation -The CLI is bundled with cmuxterm. Inside cmuxterm terminals, it's available automatically. For external use: +The CLI is bundled with cmux. Inside cmux terminals, it's available automatically. For external use: ```bash # Create symlink to CLI -sudo ln -sf "/Applications/cmuxterm.app/Contents/MacOS/cmuxterm" /usr/local/bin/cmuxterm +sudo ln -sf "/Applications/cmux.app/Contents/MacOS/cmux" /usr/local/bin/cmux ``` ## Global Options @@ -42,8 +42,8 @@ sudo ln -sf "/Applications/cmuxterm.app/Contents/MacOS/cmuxterm" /usr/local/bin/ List all open tabs. ```bash -cmuxterm list-tabs -cmuxterm list-tabs --json +cmux list-tabs +cmux list-tabs --json ``` #### new-tab @@ -51,7 +51,7 @@ cmuxterm list-tabs --json Create a new tab. ```bash -cmuxterm new-tab +cmux new-tab ``` #### select-tab @@ -59,7 +59,7 @@ cmuxterm new-tab Switch to a specific tab. ```bash -cmuxterm select-tab --tab +cmux select-tab --tab ``` #### current-tab @@ -67,8 +67,8 @@ cmuxterm select-tab --tab Get the current tab info. ```bash -cmuxterm current-tab -cmuxterm current-tab --json +cmux current-tab +cmux current-tab --json ``` #### close-tab @@ -76,7 +76,7 @@ cmuxterm current-tab --json Close a tab. ```bash -cmuxterm close-tab --tab +cmux close-tab --tab ``` ### Split Management @@ -86,10 +86,10 @@ cmuxterm close-tab --tab Create a new split pane. ```bash -cmuxterm new-split right -cmuxterm new-split down -cmuxterm new-split left -cmuxterm new-split up +cmux new-split right +cmux new-split down +cmux new-split left +cmux new-split up ``` #### list-panels @@ -97,8 +97,8 @@ cmuxterm new-split up List panels in the current tab. ```bash -cmuxterm list-panels -cmuxterm list-panels --json +cmux list-panels +cmux list-panels --json ``` #### focus-panel @@ -106,7 +106,7 @@ cmuxterm list-panels --json Focus a specific panel. ```bash -cmuxterm focus-panel --panel +cmux focus-panel --panel ``` ### Input Commands @@ -116,8 +116,8 @@ cmuxterm focus-panel --panel Send text to the terminal. ```bash -cmuxterm send "echo hello" -cmuxterm send "ls -la\n" # Include newline to execute +cmux send "echo hello" +cmux send "ls -la\n" # Include newline to execute ``` #### send-key @@ -125,9 +125,9 @@ cmuxterm send "ls -la\n" # Include newline to execute Send a key press. ```bash -cmuxterm send-key enter -cmuxterm send-key tab -cmuxterm send-key escape +cmux send-key enter +cmux send-key tab +cmux send-key escape ``` #### send-panel @@ -135,7 +135,7 @@ cmuxterm send-key escape Send text to a specific panel. ```bash -cmuxterm send-panel --panel "command" +cmux send-panel --panel "command" ``` #### send-key-panel @@ -143,7 +143,7 @@ cmuxterm send-panel --panel "command" Send a key press to a specific panel. ```bash -cmuxterm send-key-panel --panel enter +cmux send-key-panel --panel enter ``` ### Notifications @@ -153,8 +153,8 @@ cmuxterm send-key-panel --panel enter Send a notification. ```bash -cmuxterm notify --title "Title" --body "Message body" -cmuxterm notify --title "Title" --subtitle "Subtitle" --body "Body" +cmux notify --title "Title" --body "Message body" +cmux notify --title "Title" --subtitle "Subtitle" --body "Body" ``` #### list-notifications @@ -162,8 +162,8 @@ cmuxterm notify --title "Title" --subtitle "Subtitle" --body "Body" List all notifications. ```bash -cmuxterm list-notifications -cmuxterm list-notifications --json +cmux list-notifications +cmux list-notifications --json ``` #### clear-notifications @@ -171,17 +171,17 @@ cmuxterm list-notifications --json Clear all notifications. ```bash -cmuxterm clear-notifications +cmux clear-notifications ``` ### Utility #### ping -Check if cmuxterm is running and responsive. +Check if cmux is running and responsive. ```bash -cmuxterm ping +cmux ping ``` ## Examples @@ -192,9 +192,9 @@ cmuxterm ping #!/bin/bash npm run build if [ $? -eq 0 ]; then - cmuxterm notify --title "✓ Build Success" --body "Ready to deploy" + cmux notify --title "✓ Build Success" --body "Ready to deploy" else - cmuxterm notify --title "✗ Build Failed" --body "Check the logs" + cmux notify --title "✗ Build Failed" --body "Check the logs" fi ``` @@ -203,14 +203,14 @@ fi ```bash #!/bin/bash # Create a new tab -result=$(cmuxterm new-tab --json) +result=$(cmux new-tab --json) tab_id=$(echo "$result" | jq -r '.id') # Select the new tab -cmuxterm select-tab --tab "$tab_id" +cmux select-tab --tab "$tab_id" # Send a command -cmuxterm send "npm run dev\n" +cmux send "npm run dev\n" ``` ### Monitor Multiple Tabs @@ -218,5 +218,5 @@ cmuxterm send "npm run dev\n" ```bash #!/bin/bash # List all tabs and their directories -cmuxterm list-tabs --json | jq -r '.tabs[] | "\(.title): \(.directory)"' +cmux list-tabs --json | jq -r '.tabs[] | "\(.title): \(.directory)"' ``` diff --git a/docs-site/content/docs/configuration.mdx b/docs-site/content/docs/configuration.mdx index 17afb591..a22bb101 100644 --- a/docs-site/content/docs/configuration.mdx +++ b/docs-site/content/docs/configuration.mdx @@ -1,15 +1,15 @@ --- title: Configuration -description: Configure cmuxterm appearance and behavior +description: Configure cmux appearance and behavior --- # Configuration -cmuxterm reads configuration from Ghostty config files, giving you familiar options if you're coming from Ghostty. +cmux reads configuration from Ghostty config files, giving you familiar options if you're coming from Ghostty. ## Config File Locations -cmuxterm looks for configuration in these locations (in order): +cmux looks for configuration in these locations (in order): 1. `~/.config/ghostty/config` 2. `~/Library/Application Support/com.mitchellh.ghostty/config` @@ -76,7 +76,7 @@ working-directory = ~/Projects ## App Settings -In-app settings are available via **cmuxterm → Settings** (⌘,): +In-app settings are available via **cmux → Settings** (⌘,): ### Theme Mode diff --git a/docs-site/content/docs/environment-variables.mdx b/docs-site/content/docs/environment-variables.mdx index 4df74049..0eb7bbcb 100644 --- a/docs-site/content/docs/environment-variables.mdx +++ b/docs-site/content/docs/environment-variables.mdx @@ -1,11 +1,11 @@ --- title: Environment Variables -description: Environment variables for configuring cmuxterm +description: Environment variables for configuring cmux --- # Environment Variables -cmuxterm uses environment variables for configuration and integration. +cmux uses environment variables for configuration and integration. ## Socket Control @@ -14,10 +14,10 @@ cmuxterm uses environment variables for configuration and integration. Override the default socket path. ```bash -export CMUX_SOCKET_PATH=/custom/path/cmuxterm.sock +export CMUX_SOCKET_PATH=/custom/path/cmux.sock ``` -Default: `/tmp/cmuxterm.sock` (release) or `/tmp/cmuxterm-debug.sock` (debug) +Default: `/tmp/cmux.sock` (release) or `/tmp/cmux-debug.sock` (debug) ### CMUX_SOCKET_ENABLE @@ -48,10 +48,10 @@ Default tab ID for CLI commands. ```bash export CMUX_TAB_ID=abc123 -cmuxterm send "hello" # Sends to tab abc123 +cmux send "hello" # Sends to tab abc123 ``` -cmuxterm automatically sets this in each terminal session. +cmux automatically sets this in each terminal session. ### CMUX_PANEL_ID @@ -59,14 +59,14 @@ Default panel ID for CLI commands. ```bash export CMUX_PANEL_ID=xyz789 -cmuxterm send-panel "hello" # Sends to panel xyz789 +cmux send-panel "hello" # Sends to panel xyz789 ``` -cmuxterm automatically sets this for each split pane. +cmux automatically sets this for each split pane. ## Terminal Environment -cmuxterm sets these variables in terminal sessions: +cmux sets these variables in terminal sessions: ### TERM @@ -85,7 +85,7 @@ TERM_PROGRAM=ghostty ``` - cmuxterm sets this to `ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty. + cmux sets this to `ghostty` since it's built on Ghostty. Use the socket check to distinguish from regular Ghostty. ### GHOSTTY_RESOURCES_DIR @@ -124,25 +124,25 @@ export CMUX_COMMIT=abc1234 ## Detection Script -Check if running inside cmuxterm: +Check if running inside cmux: ```bash #!/bin/bash -is_cmuxterm() { - # Check for cmuxterm socket - if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmuxterm.sock}" ]; then +is_cmux() { + # Check for cmux socket + if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmux.sock}" ]; then return 0 fi return 1 } -if is_cmuxterm; then - echo "Running in cmuxterm" +if is_cmux; then + echo "Running in cmux" echo "Tab ID: ${CMUX_TAB_ID:-unknown}" echo "Panel ID: ${CMUX_PANEL_ID:-unknown}" else - echo "Not in cmuxterm" + echo "Not in cmux" fi ``` @@ -151,15 +151,15 @@ fi Add to your `~/.bashrc` or `~/.zshrc`: ```bash -# cmuxterm integration -if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmuxterm.sock}" ]; then - # We're in cmuxterm +# cmux integration +if [ -S "${CMUX_SOCKET_PATH:-/tmp/cmux.sock}" ]; then + # We're in cmux # Function to notify on long commands notify_done() { "$@" local exit_code=$? - cmuxterm notify --title "Command Complete" --body "$1" + cmux notify --title "Command Complete" --body "$1" return $exit_code } diff --git a/docs-site/content/docs/index.mdx b/docs-site/content/docs/index.mdx index 6e6a7e20..7312ed7e 100644 --- a/docs-site/content/docs/index.mdx +++ b/docs-site/content/docs/index.mdx @@ -1,13 +1,13 @@ --- title: Introduction -description: cmuxterm - A lightweight native macOS terminal with vertical tabs and notifications for AI coding agents +description: cmux - A lightweight native macOS terminal with vertical tabs and notifications for AI coding agents --- -# cmuxterm +# cmux -cmuxterm is a lightweight, native macOS terminal built on Ghostty for managing multiple AI coding agents. It features vertical tabs, a notification panel, and a socket-based control API. +cmux is a lightweight, native macOS terminal built on Ghostty for managing multiple AI coding agents. It features vertical tabs, a notification panel, and a socket-based control API. -## Why cmuxterm? +## Why cmux? - **Native macOS app** - Built with Swift and AppKit, not Electron. Fast startup, low memory usage, and native look and feel. - **Lightweight** - Small binary, minimal resource footprint. No bundled browser engine. @@ -19,7 +19,7 @@ When running AI coding agents like Claude Code, Codex, or similar tools, you nee - **Know when agents need attention** - Agents waiting for input should notify you - **Automate terminal control** - Programmatically create tabs, send input, and more -cmuxterm solves these with: +cmux solves these with: - **Vertical sidebar tabs** - All terminals visible at a glance - **OSC 99/777 notifications** - Desktop alerts when agents need you @@ -28,11 +28,11 @@ cmuxterm solves these with: ## Quick Start ```bash -brew tap manaflow-ai/cmuxterm -brew install --cask cmuxterm +brew tap manaflow-ai/cmux +brew install --cask cmux ``` -Or [download the DMG](https://github.com/manaflow-ai/cmuxterm/releases/latest/download/cmuxterm-macos.dmg) directly. +Or [download the DMG](https://github.com/manaflow-ai/cmux/releases/latest/download/cmux-macos.dmg) directly. ## Key Features diff --git a/docs-site/content/docs/installation.mdx b/docs-site/content/docs/installation.mdx index a1d76b92..a9ce18bd 100644 --- a/docs-site/content/docs/installation.mdx +++ b/docs-site/content/docs/installation.mdx @@ -1,6 +1,6 @@ --- title: Installation -description: How to install cmuxterm on macOS +description: How to install cmux on macOS --- # Installation @@ -10,29 +10,29 @@ description: How to install cmuxterm on macOS Install via Homebrew: ```bash -brew tap manaflow-ai/cmuxterm -brew install --cask cmuxterm +brew tap manaflow-ai/cmux +brew install --cask cmux ``` To update later: ```bash -brew upgrade --cask cmuxterm +brew upgrade --cask cmux ``` ## Manual Download Download the latest release from GitHub: - - Download cmuxterm for macOS + + Download cmux for macOS Then: 1. Open the downloaded `.dmg` file -2. Drag **cmuxterm** to your **Applications** folder -3. Open cmuxterm from Applications +2. Drag **cmux** to your **Applications** folder +3. Open cmux from Applications On first launch, macOS may ask you to confirm opening an app from an identified developer. Click **Open** to proceed. @@ -40,7 +40,7 @@ Then: ## Verify Installation -Open cmuxterm and you should see: +Open cmux and you should see: - A terminal window with a vertical tab sidebar on the left - One initial tab already open @@ -48,23 +48,23 @@ Open cmuxterm and you should see: ## CLI Tool -cmuxterm includes a command-line tool for automation. It's bundled inside the app and works automatically when you run commands inside cmuxterm. +cmux includes a command-line tool for automation. It's bundled inside the app and works automatically when you run commands inside cmux. -To use the CLI from outside cmuxterm, you can create a symlink: +To use the CLI from outside cmux, you can create a symlink: ```bash -sudo ln -sf "/Applications/cmuxterm.app/Contents/MacOS/cmuxterm" /usr/local/bin/cmuxterm +sudo ln -sf "/Applications/cmux.app/Contents/MacOS/cmux" /usr/local/bin/cmux ``` Then you can run commands like: ```bash -cmuxterm list-tabs -cmuxterm notify --title "Build Complete" --body "Your build finished successfully" +cmux list-tabs +cmux notify --title "Build Complete" --body "Your build finished successfully" ``` ## Updates -cmuxterm checks for updates automatically using Sparkle. When an update is available, you'll see an update pill in the titlebar. Click it to install the latest version. +cmux checks for updates automatically using Sparkle. When an update is available, you'll see an update pill in the titlebar. Click it to install the latest version. -You can also check for updates manually via **cmuxterm → Check for Updates** in the menu bar. +You can also check for updates manually via **cmux → Check for Updates** in the menu bar. diff --git a/docs-site/content/docs/keyboard-shortcuts.mdx b/docs-site/content/docs/keyboard-shortcuts.mdx index 431cfd60..f5ba718d 100644 --- a/docs-site/content/docs/keyboard-shortcuts.mdx +++ b/docs-site/content/docs/keyboard-shortcuts.mdx @@ -1,6 +1,6 @@ --- title: Keyboard Shortcuts -description: Complete list of cmuxterm keyboard shortcuts +description: Complete list of cmux keyboard shortcuts --- # Keyboard Shortcuts diff --git a/docs-site/content/docs/notifications.mdx b/docs-site/content/docs/notifications.mdx index edb3c30f..4028f14a 100644 --- a/docs-site/content/docs/notifications.mdx +++ b/docs-site/content/docs/notifications.mdx @@ -1,16 +1,16 @@ --- title: Notifications -description: Desktop notifications in cmuxterm for AI agents +description: Desktop notifications in cmux for AI agents --- # Notifications -cmuxterm supports desktop notifications, allowing AI agents and scripts to alert you when they need attention. +cmux supports desktop notifications, allowing AI agents and scripts to alert you when they need attention. ## How It Works 1. A process in the terminal sends an OSC escape sequence -2. cmuxterm parses the notification title and body +2. cmux parses the notification title and body 3. If the terminal isn't focused, a desktop notification appears 4. The tab shows an unread badge @@ -21,13 +21,13 @@ cmuxterm supports desktop notifications, allowing AI agents and scripts to alert The simplest way to send a notification: ```bash -cmuxterm notify --title "Task Complete" --body "Your build finished" +cmux notify --title "Task Complete" --body "Your build finished" ``` With a subtitle: ```bash -cmuxterm notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input" +cmux notify --title "Claude Code" --subtitle "Waiting" --body "Agent needs input" ``` ### Using OSC Sequences @@ -59,7 +59,7 @@ See [OSC Sequences](/docs/osc-sequences) for full format documentation. Notifications are suppressed (no desktop alert) when: -- The cmuxterm window is focused +- The cmux window is focused - The specific tab sending the notification is active - The notification panel is open @@ -94,9 +94,9 @@ notify-after() { "$@" local exit_code=$? if [ $exit_code -eq 0 ]; then - cmuxterm notify --title "✓ Command Complete" --body "$1" + cmux notify --title "✓ Command Complete" --body "$1" else - cmuxterm notify --title "✗ Command Failed" --body "$1 (exit $exit_code)" + cmux notify --title "✗ Command Failed" --body "$1 (exit $exit_code)" fi return $exit_code } @@ -108,7 +108,7 @@ notify-after npm run build ### Notify When Build Finishes ```bash -npm run build && cmuxterm notify --title "Build Success" --body "Ready to deploy" +npm run build && cmux notify --title "Build Success" --body "Ready to deploy" ``` ### Watch Script Completion @@ -123,5 +123,5 @@ do_work() { } do_work -cmuxterm notify --title "Task Complete" --body "long-running-task.sh finished" +cmux notify --title "Task Complete" --body "long-running-task.sh finished" ``` diff --git a/docs-site/content/docs/osc-sequences.mdx b/docs-site/content/docs/osc-sequences.mdx index 8981d42f..86e9a83e 100644 --- a/docs-site/content/docs/osc-sequences.mdx +++ b/docs-site/content/docs/osc-sequences.mdx @@ -1,11 +1,11 @@ --- title: OSC Sequences -description: OSC escape sequence reference for cmuxterm notifications +description: OSC escape sequence reference for cmux notifications --- # OSC Sequences -cmuxterm supports two OSC (Operating System Command) escape sequence standards for sending notifications from terminal programs. +cmux supports two OSC (Operating System Command) escape sequence standards for sending notifications from terminal programs. ## OSC 99 (Kitty Protocol) @@ -137,13 +137,13 @@ notify_osc777 "Download Complete" "File saved to ~/Downloads" | Subtitle | ✓ | ✗ | | Notification ID | ✓ | ✗ | | Complexity | Higher | Lower | -| Compatibility | Kitty, cmuxterm | RXVT, cmuxterm | +| Compatibility | Kitty, cmux | RXVT, cmux | ## Recommendations - **Use OSC 777** for simple title + body notifications - **Use OSC 99** when you need subtitles or notification IDs -- **Use the CLI** (`cmuxterm notify`) for the easiest integration +- **Use the CLI** (`cmux notify`) for the easiest integration ## Testing @@ -163,7 +163,7 @@ printf '\e]99;i=test;e=1;d=1;p=body:This is the body text\e\\' ### tmux -If using tmux inside cmuxterm, enable passthrough: +If using tmux inside cmux, enable passthrough: ```bash # In .tmux.conf diff --git a/docs-site/content/docs/socket-api.mdx b/docs-site/content/docs/socket-api.mdx index 19c3de84..d2be6b69 100644 --- a/docs-site/content/docs/socket-api.mdx +++ b/docs-site/content/docs/socket-api.mdx @@ -1,24 +1,24 @@ --- title: Socket API -description: Unix socket API for programmatic control of cmuxterm +description: Unix socket API for programmatic control of cmux --- # Socket API -cmuxterm exposes a Unix socket for programmatic control, enabling automation and integration with tools like Claude Code. +cmux exposes a Unix socket for programmatic control, enabling automation and integration with tools like Claude Code. ## Socket Location | Build | Socket Path | |-------|-------------| -| Release | `/tmp/cmuxterm.sock` | -| Debug | `/tmp/cmuxterm-debug.sock` | +| Release | `/tmp/cmux.sock` | +| Debug | `/tmp/cmux-debug.sock` | You can override the path with the `CMUX_SOCKET_PATH` environment variable. ## Access Modes -cmuxterm has three access modes, configurable in Settings: +cmux has three access modes, configurable in Settings: | Mode | Description | |------|-------------| @@ -227,7 +227,7 @@ import json def send_command(cmd): sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - sock.connect('/tmp/cmuxterm.sock') + sock.connect('/tmp/cmux.sock') sock.send(json.dumps(cmd).encode() + b'\n') response = sock.recv(4096).decode() sock.close() @@ -252,7 +252,7 @@ send_command({ # Function to send commands cmux_cmd() { - echo "$1" | nc -U /tmp/cmuxterm.sock + echo "$1" | nc -U /tmp/cmux.sock } # List tabs diff --git a/docs-site/content/docs/splits.mdx b/docs-site/content/docs/splits.mdx index 9c5a4a61..d7385ab9 100644 --- a/docs-site/content/docs/splits.mdx +++ b/docs-site/content/docs/splits.mdx @@ -1,11 +1,11 @@ --- title: Split Panes -description: Working with split panes in cmuxterm +description: Working with split panes in cmux --- # Split Panes -cmuxterm supports splitting terminal panes within a tab, allowing you to view multiple terminals side by side. +cmux supports splitting terminal panes within a tab, allowing you to view multiple terminals side by side. ## Creating Splits @@ -20,10 +20,10 @@ cmuxterm supports splitting terminal panes within a tab, allowing you to view mu ```bash # Split in a specific direction -cmuxterm new-split right -cmuxterm new-split down -cmuxterm new-split left -cmuxterm new-split up +cmux new-split right +cmux new-split down +cmux new-split left +cmux new-split up ``` ## Navigating Splits @@ -43,10 +43,10 @@ Use **⌘⌥** + arrow keys to move between splits: ```bash # List all panes in current tab -cmuxterm list-panels +cmux list-panels # Focus a specific pane -cmuxterm focus-panel --panel +cmux focus-panel --panel ``` ## Closing Splits @@ -75,7 +75,7 @@ split-divider-color = #45475a ## Split Layout -cmuxterm uses a binary split tree structure: +cmux uses a binary split tree structure: - Each split creates two child panes - Nested splits create a tree of panes @@ -104,8 +104,8 @@ With the CLI, you can send input to specific panes: ```bash # Send text to a specific pane -cmuxterm send-panel --panel "echo hello" +cmux send-panel --panel "echo hello" # Send a keypress to a specific pane -cmuxterm send-key-panel --panel enter +cmux send-key-panel --panel enter ``` diff --git a/docs-site/content/docs/tabs.mdx b/docs-site/content/docs/tabs.mdx index 4b6e5456..6d07e54b 100644 --- a/docs-site/content/docs/tabs.mdx +++ b/docs-site/content/docs/tabs.mdx @@ -1,11 +1,11 @@ --- title: Vertical Tabs -description: Managing terminal tabs in cmuxterm +description: Managing terminal tabs in cmux --- # Vertical Tabs -cmuxterm displays all your terminal tabs in a vertical sidebar on the left side of the window, making it easy to see and switch between multiple terminals at a glance. +cmux displays all your terminal tabs in a vertical sidebar on the left side of the window, making it easy to see and switch between multiple terminals at a glance. ## Sidebar Features diff --git a/docs-site/package-lock.json b/docs-site/package-lock.json index 70d08f48..a45206fc 100644 --- a/docs-site/package-lock.json +++ b/docs-site/package-lock.json @@ -1,11 +1,11 @@ { - "name": "cmuxterm-docs", + "name": "cmux-docs", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "cmuxterm-docs", + "name": "cmux-docs", "version": "0.1.0", "dependencies": { "fumadocs-core": "^14.0.0", diff --git a/docs-site/package.json b/docs-site/package.json index 7ef39cc1..894d6e07 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -1,5 +1,5 @@ { - "name": "cmuxterm-docs", + "name": "cmux-docs", "version": "0.1.0", "private": true, "scripts": { diff --git a/docs/notifications.md b/docs/notifications.md index 151eb4df..42bb5903 100644 --- a/docs/notifications.md +++ b/docs/notifications.md @@ -1,29 +1,29 @@ # Notifications -cmuxterm provides a notification panel for AI agents like Claude Code, Codex, and OpenCode. Notifications appear in a dedicated panel and trigger macOS system notifications. +cmux provides a notification panel for AI agents like Claude Code, Codex, and OpenCode. Notifications appear in a dedicated panel and trigger macOS system notifications. ## Quick Start ```bash -# Send a notification (if cmuxterm is available) -command -v cmuxterm &>/dev/null && cmuxterm notify --title "Done" --body "Task complete" +# Send a notification (if cmux is available) +command -v cmux &>/dev/null && cmux notify --title "Done" --body "Task complete" # With fallback to macOS notifications -command -v cmuxterm &>/dev/null && cmuxterm notify --title "Done" --body "Task complete" || osascript -e 'display notification "Task complete" with title "Done"' +command -v cmux &>/dev/null && cmux notify --title "Done" --body "Task complete" || osascript -e 'display notification "Task complete" with title "Done"' ``` ## Detection -Check if `cmuxterm` CLI is available before using it: +Check if `cmux` CLI is available before using it: ```bash # Shell -if command -v cmuxterm &>/dev/null; then - cmuxterm notify --title "Hello" +if command -v cmux &>/dev/null; then + cmux notify --title "Hello" fi # One-liner with fallback -command -v cmuxterm &>/dev/null && cmuxterm notify --title "Hello" || osascript -e 'display notification "" with title "Hello"' +command -v cmux &>/dev/null && cmux notify --title "Hello" || osascript -e 'display notification "" with title "Hello"' ``` ```python @@ -32,8 +32,8 @@ import shutil import subprocess def notify(title: str, body: str = ""): - if shutil.which("cmuxterm"): - subprocess.run(["cmuxterm", "notify", "--title", title, "--body", body]) + if shutil.which("cmux"): + subprocess.run(["cmux", "notify", "--title", title, "--body", body]) else: # Fallback to macOS subprocess.run(["osascript", "-e", f'display notification "{body}" with title "{title}"']) @@ -43,13 +43,13 @@ def notify(title: str, body: str = ""): ```bash # Simple notification -cmuxterm notify --title "Build Complete" +cmux notify --title "Build Complete" # With subtitle and body -cmuxterm notify --title "Claude Code" --subtitle "Permission" --body "Approval needed" +cmux notify --title "Claude Code" --subtitle "Permission" --body "Approval needed" # Notify specific tab/panel -cmuxterm notify --title "Done" --tab 0 --panel 1 +cmux notify --title "Done" --tab 0 --panel 1 ``` ## Integration Examples @@ -67,7 +67,7 @@ Add to `~/.claude/settings.json`: "hooks": [ { "type": "command", - "command": "command -v cmuxterm &>/dev/null && cmuxterm notify --title 'Claude Code' --body 'Waiting for input' || osascript -e 'display notification \"Waiting for input\" with title \"Claude Code\"'" + "command": "command -v cmux &>/dev/null && cmux notify --title 'Claude Code' --body 'Waiting for input' || osascript -e 'display notification \"Waiting for input\" with title \"Claude Code\"'" } ] }, @@ -76,7 +76,7 @@ Add to `~/.claude/settings.json`: "hooks": [ { "type": "command", - "command": "command -v cmuxterm &>/dev/null && cmuxterm notify --title 'Claude Code' --subtitle 'Permission' --body 'Approval needed' || osascript -e 'display notification \"Approval needed\" with title \"Claude Code\"'" + "command": "command -v cmux &>/dev/null && cmux notify --title 'Claude Code' --subtitle 'Permission' --body 'Approval needed' || osascript -e 'display notification \"Approval needed\" with title \"Claude Code\"'" } ] } @@ -90,7 +90,7 @@ Add to `~/.claude/settings.json`: Add to `~/.codex/config.toml`: ```toml -notify = ["bash", "-c", "command -v cmuxterm &>/dev/null && cmuxterm notify --title Codex --body \"$(echo $1 | jq -r '.\"last-assistant-message\" // \"Turn complete\"' 2>/dev/null | head -c 100)\" || osascript -e 'display notification \"Turn complete\" with title \"Codex\"'", "--"] +notify = ["bash", "-c", "command -v cmux &>/dev/null && cmux notify --title Codex --body \"$(echo $1 | jq -r '.\"last-assistant-message\" // \"Turn complete\"' 2>/dev/null | head -c 100)\" || osascript -e 'display notification \"Turn complete\" with title \"Codex\"'", "--"] ``` Or create a simple script `~/.local/bin/codex-notify.sh`: @@ -98,7 +98,7 @@ Or create a simple script `~/.local/bin/codex-notify.sh`: ```bash #!/bin/bash MSG=$(echo "$1" | jq -r '."last-assistant-message" // "Turn complete"' 2>/dev/null | head -c 100) -command -v cmuxterm &>/dev/null && cmuxterm notify --title "Codex" --body "$MSG" || osascript -e "display notification \"$MSG\" with title \"Codex\"" +command -v cmux &>/dev/null && cmux notify --title "Codex" --body "$MSG" || osascript -e "display notification \"$MSG\" with title \"Codex\"" ``` Then use: @@ -108,13 +108,13 @@ notify = ["bash", "~/.local/bin/codex-notify.sh"] ### OpenCode Plugin -Create `.opencode/plugins/cmuxterm-notify.js`: +Create `.opencode/plugins/cmux-notify.js`: ```javascript export const CmuxNotificationPlugin = async ({ $, }) => { const notify = async (title, body) => { try { - await $`command -v cmuxterm && cmuxterm notify --title ${title} --body ${body}`; + await $`command -v cmux && cmux notify --title ${title} --body ${body}`; } catch { await $`osascript -e ${"display notification \"" + body + "\" with title \"" + title + "\""}`; } @@ -132,7 +132,7 @@ export const CmuxNotificationPlugin = async ({ $, }) => { ## Environment Variables -cmuxterm sets these in child shells: +cmux sets these in child shells: | Variable | Description | |----------|-------------| @@ -143,14 +143,14 @@ cmuxterm sets these in child shells: ## CLI Commands ``` -cmuxterm notify --title [--subtitle ] [--body ] [--tab ] [--panel ] -cmuxterm list-notifications -cmuxterm clear-notifications -cmuxterm ping +cmux notify --title [--subtitle ] [--body ] [--tab ] [--panel ] +cmux list-notifications +cmux clear-notifications +cmux ping ``` ## Best Practices -1. **Always check availability first** - Use `command -v cmuxterm` before calling +1. **Always check availability first** - Use `command -v cmux` before calling 2. **Provide fallbacks** - Use `|| osascript` for macOS fallback 3. **Keep notifications concise** - Title should be brief, use body for details diff --git a/homebrew-cmux b/homebrew-cmux new file mode 160000 index 00000000..19af91f6 --- /dev/null +++ b/homebrew-cmux @@ -0,0 +1 @@ +Subproject commit 19af91f6d47016a74a08546e8693dc03eefb7ef5 diff --git a/homebrew-cmuxterm b/homebrew-cmuxterm deleted file mode 160000 index c12d7538..00000000 --- a/homebrew-cmuxterm +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c12d753824b3ab1f4289a7e45d7ea28aa114b496 diff --git a/scripts/reload.sh b/scripts/reload.sh index a7fb147a..2fed33d0 100755 --- a/scripts/reload.sh +++ b/scripts/reload.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -APP_NAME="cmuxterm DEV" -BUNDLE_ID="com.cmuxterm.app.debug" -BASE_APP_NAME="cmuxterm DEV" +APP_NAME="cmux DEV" +BUNDLE_ID="com.cmux.app.debug" +BASE_APP_NAME="cmux DEV" DERIVED_DATA="" NAME_SET=0 BUNDLE_SET=0 @@ -97,13 +97,13 @@ if [[ -n "$TAG" ]]; then TAG_ID="$(sanitize_bundle "$TAG")" TAG_SLUG="$(sanitize_path "$TAG")" if [[ "$NAME_SET" -eq 0 ]]; then - APP_NAME="cmuxterm DEV ${TAG}" + APP_NAME="cmux DEV ${TAG}" fi if [[ "$BUNDLE_SET" -eq 0 ]]; then - BUNDLE_ID="com.cmuxterm.app.debug.${TAG_ID}" + BUNDLE_ID="com.cmux.app.debug.${TAG_ID}" fi if [[ "$DERIVED_SET" -eq 0 ]]; then - DERIVED_DATA="/tmp/cmuxterm-${TAG_SLUG}" + DERIVED_DATA="/tmp/cmux-${TAG_SLUG}" fi fi @@ -180,10 +180,10 @@ if [[ -n "$TAG" && "$APP_NAME" != "$SEARCH_APP_NAME" ]]; then /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $BUNDLE_ID" "$INFO_PLIST" 2>/dev/null \ || /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string $BUNDLE_ID" "$INFO_PLIST" if [[ -n "${TAG_SLUG:-}" ]]; then - APP_SUPPORT_DIR="$HOME/Library/Application Support/cmuxterm" + APP_SUPPORT_DIR="$HOME/Library/Application Support/cmux" CMUXD_SOCKET="${APP_SUPPORT_DIR}/cmuxd-dev-${TAG_SLUG}.sock" - CMUX_SOCKET="/tmp/cmuxterm-debug-${TAG_SLUG}.sock" - echo "$CMUX_SOCKET" > /tmp/cmuxterm-last-socket-path || true + CMUX_SOCKET="/tmp/cmux-debug-${TAG_SLUG}.sock" + echo "$CMUX_SOCKET" > /tmp/cmux-last-socket-path || true /usr/libexec/PlistBuddy -c "Add :LSEnvironment dict" "$INFO_PLIST" 2>/dev/null || true /usr/libexec/PlistBuddy -c "Set :LSEnvironment:CMUXD_UNIX_PATH \"${CMUXD_SOCKET}\"" "$INFO_PLIST" 2>/dev/null \ || /usr/libexec/PlistBuddy -c "Add :LSEnvironment:CMUXD_UNIX_PATH string \"${CMUXD_SOCKET}\"" "$INFO_PLIST" @@ -225,8 +225,8 @@ if [[ -x "$CMUXD_SRC" ]]; then cp "$CMUXD_SRC" "$BIN_DIR/cmuxd" chmod +x "$BIN_DIR/cmuxd" fi -# Avoid inheriting cmuxterm/ghostty environment variables from the terminal that -# runs this script (often inside another cmuxterm instance), which can cause +# Avoid inheriting cmux/ghostty environment variables from the terminal that +# runs this script (often inside another cmux instance), which can cause # socket and resource-path conflicts. OPEN_CLEAN_ENV=( env @@ -235,15 +235,13 @@ OPEN_CLEAN_ENV=( -u CMUX_PANEL_ID -u CMUXD_UNIX_PATH -u CMUX_TAG - -u CMUXTERM_TAG -u CMUX_BUNDLE_ID - -u CMUXTERM_BUNDLE_ID -u CMUX_SHELL_INTEGRATION -u GHOSTTY_BIN_DIR -u GHOSTTY_RESOURCES_DIR -u GHOSTTY_SHELL_FEATURES # Dev shells (including CI/Codex) often force-disable paging by exporting these. - # Don't leak that into cmuxterm, otherwise `git diff` won't page even with PAGER=less. + # Don't leak that into cmux, otherwise `git diff` won't page even with PAGER=less. -u GIT_PAGER -u GH_PAGER -u TERMINFO diff --git a/scripts/reloadp.sh b/scripts/reloadp.sh index dfae1eef..fbb75fe8 100755 --- a/scripts/reloadp.sh +++ b/scripts/reloadp.sh @@ -2,20 +2,20 @@ set -euo pipefail xcodebuild -project GhosttyTabs.xcodeproj -scheme cmux -configuration Release -destination 'platform=macOS' build -pkill -x cmuxterm || true +pkill -x cmux || true sleep 0.2 APP_PATH="$( - find "$HOME/Library/Developer/Xcode/DerivedData" -path "*/Build/Products/Release/cmuxterm.app" -print0 \ + find "$HOME/Library/Developer/Xcode/DerivedData" -path "*/Build/Products/Release/cmux.app" -print0 \ | xargs -0 /usr/bin/stat -f "%m %N" 2>/dev/null \ | sort -nr \ | head -n 1 \ | cut -d' ' -f2- )" if [[ -z "${APP_PATH}" ]]; then - echo "cmuxterm.app not found in DerivedData" >&2 + echo "cmux.app not found in DerivedData" >&2 exit 1 fi # Dev shells (including CI/Codex) often force-disable paging by exporting these. -# Don't leak that into cmuxterm, otherwise `git diff` won't page even with PAGER=less. +# Don't leak that into cmux, otherwise `git diff` won't page even with PAGER=less. env -u GIT_PAGER -u GH_PAGER open "$APP_PATH" -osascript -e 'tell application "cmuxterm" to activate' || true +osascript -e 'tell application "cmux" to activate' || true diff --git a/scripts/sparkle_generate_appcast.sh b/scripts/sparkle_generate_appcast.sh index 2266c6f3..bfcfb64a 100755 --- a/scripts/sparkle_generate_appcast.sh +++ b/scripts/sparkle_generate_appcast.sh @@ -16,8 +16,8 @@ if [[ -z "${SPARKLE_PRIVATE_KEY:-}" ]]; then fi SPARKLE_VERSION="${SPARKLE_VERSION:-2.8.1}" -DOWNLOAD_URL_PREFIX="${DOWNLOAD_URL_PREFIX:-https://github.com/manaflow-ai/cmuxterm/releases/download/$TAG/}" -RELEASE_NOTES_URL="${RELEASE_NOTES_URL:-https://github.com/manaflow-ai/cmuxterm/releases/tag/$TAG}" +DOWNLOAD_URL_PREFIX="${DOWNLOAD_URL_PREFIX:-https://github.com/manaflow-ai/cmux/releases/download/$TAG/}" +RELEASE_NOTES_URL="${RELEASE_NOTES_URL:-https://github.com/manaflow-ai/cmux/releases/tag/$TAG}" work_dir="$(mktemp -d)" cleanup() { diff --git a/scripts/sparkle_generate_keys.sh b/scripts/sparkle_generate_keys.sh index 256ed0f8..5829b1d5 100755 --- a/scripts/sparkle_generate_keys.sh +++ b/scripts/sparkle_generate_keys.sh @@ -2,7 +2,7 @@ set -euo pipefail SPARKLE_VERSION="${SPARKLE_VERSION:-2.8.1}" -SPARKLE_KEYCHAIN_ACCOUNT="${SPARKLE_KEYCHAIN_ACCOUNT:-cmuxterm}" +SPARKLE_KEYCHAIN_ACCOUNT="${SPARKLE_KEYCHAIN_ACCOUNT:-cmux}" SPARKLE_ENV_FILE="${SPARKLE_ENV_FILE:-.env}" work_dir="$(mktemp -d)" diff --git a/tests/cmux.py b/tests/cmux.py index 09e23cfb..71b1f535 100755 --- a/tests/cmux.py +++ b/tests/cmux.py @@ -43,8 +43,8 @@ class cmuxError(Exception): pass -_LAST_SOCKET_PATH_FILE = "/tmp/cmuxterm-last-socket-path" -_DEFAULT_DEBUG_BUNDLE_ID = "com.cmuxterm.app.debug" +_LAST_SOCKET_PATH_FILE = "/tmp/cmux-last-socket-path" +_DEFAULT_DEBUG_BUNDLE_ID = "com.cmux.app.debug" def _sanitize_tag_slug(raw: str) -> str: @@ -68,11 +68,11 @@ def _quote_option_value(value: str) -> str: def _default_bundle_id() -> str: - override = os.environ.get("CMUX_BUNDLE_ID") or os.environ.get("CMUXTERM_BUNDLE_ID") + override = os.environ.get("CMUX_BUNDLE_ID") if override: return override - tag = os.environ.get("CMUX_TAG") or os.environ.get("CMUXTERM_TAG") + tag = os.environ.get("CMUX_TAG") if tag: suffix = _sanitize_bundle_suffix(tag) return f"{_DEFAULT_DEBUG_BUNDLE_ID}.{suffix}" @@ -110,12 +110,12 @@ def _can_connect(path: str, timeout: float = 0.15, retries: int = 4) -> bool: def _default_socket_path() -> str: - tag = os.environ.get("CMUX_TAG") or os.environ.get("CMUXTERM_TAG") + tag = os.environ.get("CMUX_TAG") if tag: slug = _sanitize_tag_slug(tag) tagged_candidates = [ - f"/tmp/cmuxterm-debug-{slug}.sock", - f"/tmp/cmuxterm-{slug}.sock", + f"/tmp/cmux-debug-{slug}.sock", + f"/tmp/cmux-{slug}.sock", ] for path in tagged_candidates: if os.path.exists(path) and _can_connect(path): @@ -142,13 +142,13 @@ def _default_socket_path() -> str: return last_socket # Prefer the non-tagged sockets when present. - candidates = ["/tmp/cmuxterm-debug.sock", "/tmp/cmuxterm.sock"] + candidates = ["/tmp/cmux-debug.sock", "/tmp/cmux.sock"] for path in candidates: if os.path.exists(path) and _can_connect(path): return path # Otherwise, fall back to the newest tagged debug socket if there is one. - tagged = glob.glob("/tmp/cmuxterm-debug-*.sock") + tagged = glob.glob("/tmp/cmux-debug-*.sock") tagged = [p for p in tagged if os.path.exists(p)] if tagged: tagged.sort(key=lambda p: os.path.getmtime(p), reverse=True) diff --git a/tests/test_app_keystrokes.sh b/tests/test_app_keystrokes.sh index 1f50b31d..2bc06b8e 100755 --- a/tests/test_app_keystrokes.sh +++ b/tests/test_app_keystrokes.sh @@ -1,24 +1,24 @@ #!/bin/bash -# Test script that sends keystrokes to cmuxterm via AppleScript +# Test script that sends keystrokes to cmux via AppleScript # This tests the actual keyboard input path through the app set -e -echo "=== cmuxterm Keystroke Test ===" +echo "=== cmux Keystroke Test ===" echo "" -# Check if cmuxterm is running -if ! pgrep -x "cmuxterm" > /dev/null; then - echo "Error: cmuxterm is not running" - echo "Please start cmuxterm first" +# Check if cmux is running +if ! pgrep -x "cmux" > /dev/null; then + echo "Error: cmux is not running" + echo "Please start cmux first" exit 1 fi -echo "cmuxterm is running" +echo "cmux is running" echo "" -# Activate cmuxterm -osascript -e 'tell application "cmuxterm" to activate' +# Activate cmux +osascript -e 'tell application "cmux" to activate' sleep 0.5 echo "Test 1: Testing Ctrl+C (SIGINT)" @@ -56,7 +56,7 @@ echo " If cat exited, Ctrl+D is working!" echo "" echo "=== Manual Verification Required ===" -echo "Please check the cmuxterm window to verify:" +echo "Please check the cmux window to verify:" echo " 1. The 'sleep 30' command was interrupted by Ctrl+C" echo " 2. The 'cat' command exited after Ctrl+D" echo "" diff --git a/tests/test_cpu_notifications.py b/tests/test_cpu_notifications.py index 245bf812..ddcb882a 100644 --- a/tests/test_cpu_notifications.py +++ b/tests/test_cpu_notifications.py @@ -10,7 +10,7 @@ Tests that CPU usage stays reasonable when: Usage: python3 tests/test_cpu_notifications.py -Requires cmuxterm to be running with socket control enabled. +Requires cmux to be running with socket control enabled. """ from __future__ import annotations @@ -39,8 +39,8 @@ SETTLE_TIME = 2.0 MONITOR_DURATION = 3.0 -def get_cmuxterm_pid() -> Optional[int]: - """Get the PID of the running cmuxterm process.""" +def get_cmux_pid() -> Optional[int]: + """Get the PID of the running cmux process.""" socket_path = os.environ.get("CMUX_SOCKET_PATH") if not socket_path: # Ask cmux.py to resolve default socket path (supports CMUX_TAG and last-socket file). @@ -68,14 +68,14 @@ def get_cmuxterm_pid() -> Optional[int]: return pid result = subprocess.run( - ["pgrep", "-f", r"cmuxterm\.app/Contents/MacOS/cmuxterm$"], + ["pgrep", "-f", r"cmux\.app/Contents/MacOS/cmux$"], capture_output=True, text=True, ) if result.returncode != 0: # Try DEV build result = subprocess.run( - ["pgrep", "-f", r"cmuxterm DEV\.app/Contents/MacOS/cmuxterm"], + ["pgrep", "-f", r"cmux DEV\.app/Contents/MacOS/cmux"], capture_output=True, text=True, ) @@ -167,7 +167,7 @@ def test_cpu_after_popover_close(client: cmux, pid: int) -> tuple[bool, str]: time.sleep(0.1) time.sleep(0.5) - # Ensure the correct cmuxterm instance is frontmost (tag-safe). + # Ensure the correct cmux instance is frontmost (tag-safe). bundle_id = cmux.default_bundle_id() subprocess.run( ["osascript", "-e", f'tell application id "{bundle_id}" to activate'], @@ -243,17 +243,17 @@ def test_cpu_idle_with_notifications(client: cmux, pid: int) -> tuple[bool, str] def main(): print("=" * 60) - print("cmuxterm Notification CPU Tests") + print("cmux Notification CPU Tests") print("=" * 60) socket_path = cmux().socket_path - pid = get_cmuxterm_pid() + pid = get_cmux_pid() if pid is None: - print("\n❌ SKIP: cmuxterm is not running") + print("\n❌ SKIP: cmux is not running") return 0 - print(f"\nFound cmuxterm process: PID {pid}") + print(f"\nFound cmux process: PID {pid}") # Try to connect to the socket client = cmux(socket_path) @@ -261,7 +261,7 @@ def main(): client.connect() print(f"Connected to {socket_path}") except cmuxError: - print("\n❌ SKIP: Could not connect to cmuxterm socket") + print("\n❌ SKIP: Could not connect to cmux socket") print("Tip: set CMUX_TAG= or CMUX_SOCKET_PATH= to target a tagged instance.") return 0 diff --git a/tests/test_cpu_usage.py b/tests/test_cpu_usage.py index 30bd3366..9a7e3320 100644 --- a/tests/test_cpu_usage.py +++ b/tests/test_cpu_usage.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 """ -CPU usage test for cmuxterm. +CPU usage test for cmux. -This test monitors cmuxterm's CPU usage during idle periods to catch +This test monitors cmux's CPU usage during idle periods to catch performance regressions like runaway animations or continuous view updates. -Run this test after launching cmuxterm: +Run this test after launching cmux: python3 tests/test_cpu_usage.py The test will fail if: @@ -49,8 +49,8 @@ SUSPICIOUS_PATTERNS = [ ] -def get_cmuxterm_pid() -> Optional[int]: - """Get the PID of the running cmuxterm process.""" +def get_cmux_pid() -> Optional[int]: + """Get the PID of the running cmux process.""" socket_path = os.environ.get("CMUX_SOCKET_PATH") if not socket_path: try: @@ -77,14 +77,14 @@ def get_cmuxterm_pid() -> Optional[int]: return pid result = subprocess.run( - ["pgrep", "-f", r"cmuxterm\.app/Contents/MacOS/cmuxterm$"], + ["pgrep", "-f", r"cmux\.app/Contents/MacOS/cmux$"], capture_output=True, text=True, ) if result.returncode != 0: # Try DEV build result = subprocess.run( - ["pgrep", "-f", r"cmuxterm DEV\.app/Contents/MacOS/cmuxterm"], + ["pgrep", "-f", r"cmux DEV\.app/Contents/MacOS/cmux"], capture_output=True, text=True, ) @@ -141,17 +141,17 @@ def monitor_cpu_usage(pid: int, duration: float, interval: float) -> List[float] def main(): print("=" * 60) - print("cmuxterm CPU Usage Test") + print("cmux CPU Usage Test") print("=" * 60) - # Find cmuxterm process - pid = get_cmuxterm_pid() + # Find cmux process + pid = get_cmux_pid() if pid is None: - print("\n❌ SKIP: cmuxterm is not running") - print("Start cmuxterm and run this test again.") + print("\n❌ SKIP: cmux is not running") + print("Start cmux and run this test again.") return 0 # Not a failure, just skip - print(f"\nFound cmuxterm process: PID {pid}") + print(f"\nFound cmux process: PID {pid}") # Wait for app to settle print(f"Waiting {SETTLE_TIME}s for app to settle...") @@ -187,7 +187,7 @@ def main(): print(f" - {issue}") # Save sample for debugging - sample_file = Path(f"/tmp/cmuxterm_cpu_test_sample_{pid}.txt") + sample_file = Path(f"/tmp/cmux_cpu_test_sample_{pid}.txt") sample_file.write_text(sample_output) print(f"\nFull sample saved to: {sample_file}") @@ -196,7 +196,7 @@ def main(): lines = sample_output.split("\n") relevant_lines = [ l for l in lines - if "cmuxterm" in l and ("body" in l or "Animation" in l or "Timer" in l) + if "cmux" in l and ("body" in l or "Animation" in l or "Timer" in l) ][:10] for line in relevant_lines: print(f" {line.strip()[:100]}") diff --git a/tests/test_ctrl_enter_keybind.py b/tests/test_ctrl_enter_keybind.py index a394e6a1..29c305f2 100644 --- a/tests/test_ctrl_enter_keybind.py +++ b/tests/test_ctrl_enter_keybind.py @@ -3,7 +3,7 @@ Automated test for ctrl+enter keybind using real keystrokes. Requires: - - cmuxterm running + - cmux running - Accessibility permissions for System Events (osascript) - keybind = ctrl+enter=text:\\r (or \\n/\\x0d) configured in Ghostty config """ @@ -115,14 +115,14 @@ def test_ctrl_enter_keybind(client: cmux) -> tuple[bool, str]: def run_tests() -> int: print("=" * 60) - print("cmuxterm Ctrl+Enter Keybind Test") + print("cmux Ctrl+Enter Keybind Test") print("=" * 60) print() socket_path = cmux.default_socket_path() if not os.path.exists(socket_path): print(f"SKIP: Socket not found at {socket_path}") - print("Tip: start cmuxterm first (or set CMUX_TAG / CMUX_SOCKET_PATH).") + print("Tip: start cmux first (or set CMUX_TAG / CMUX_SOCKET_PATH).") return 0 config_path = find_config_with_keybind() diff --git a/tests/test_shell_histfile_ghostty_zdotdir_regression.py b/tests/test_shell_histfile_ghostty_zdotdir_regression.py index b7ad546c..b35e1c4c 100644 --- a/tests/test_shell_histfile_ghostty_zdotdir_regression.py +++ b/tests/test_shell_histfile_ghostty_zdotdir_regression.py @@ -4,8 +4,8 @@ Regression: GhosttyKit already injects zsh shell integration by setting ZDOTDIR to Ghostty's own integration directory (and optionally preserving a user-set ZDOTDIR in GHOSTTY_ZSH_ZDOTDIR). -cmuxterm also injects its own zsh integration by setting ZDOTDIR to -Resources/shell-integration. If cmuxterm incorrectly treats Ghostty's injected +cmux also injects its own zsh integration by setting ZDOTDIR to +Resources/shell-integration. If cmux incorrectly treats Ghostty's injected ZDOTDIR as the "user" ZDOTDIR, zsh history will be isolated to the integration directory rather than the user's HOME/ZDOTDIR, breaking cross-terminal history and therefore zsh-autosuggestions. @@ -63,7 +63,7 @@ def main() -> int: env.pop("GHOSTTY_SHELL_FEATURES", None) env.pop("GHOSTTY_BIN_DIR", None) - # Simulate the buggy situation: cmuxterm stores Ghostty's injected ZDOTDIR + # Simulate the buggy situation: cmux stores Ghostty's injected ZDOTDIR # as the "original" ZDOTDIR, then sets ZDOTDIR to its own wrapper. env["CMUX_ORIGINAL_ZDOTDIR"] = str(ghostty_zsh_dir) env["ZDOTDIR"] = str(cmux_wrapper_dir) diff --git a/tests/test_shell_zdotdir_user_override.py b/tests/test_shell_zdotdir_user_override.py index ed7438f2..a067173b 100644 --- a/tests/test_shell_zdotdir_user_override.py +++ b/tests/test_shell_zdotdir_user_override.py @@ -3,8 +3,8 @@ Regression: if the user's .zshenv changes ZDOTDIR, then .zshrc should be sourced from the updated ZDOTDIR (matching vanilla zsh semantics). -Why this matters for cmuxterm: -- cmuxterm sets ZDOTDIR to the app wrapper directory so zsh loads wrapper +Why this matters for cmux: +- cmux sets ZDOTDIR to the app wrapper directory so zsh loads wrapper startup files. - The wrapper .zshenv temporarily restores ZDOTDIR to the original directory while sourcing the user's real .zshenv. diff --git a/tests/test_shell_zdotdir_wrapper.py b/tests/test_shell_zdotdir_wrapper.py index 1675163d..8d9ce5e0 100644 --- a/tests/test_shell_zdotdir_wrapper.py +++ b/tests/test_shell_zdotdir_wrapper.py @@ -3,7 +3,7 @@ Regression: zsh wrapper startup files must source user files with the *original* ZDOTDIR, not the wrapper directory. -The cmuxterm zsh integration sets ZDOTDIR to the app's wrapper directory so zsh +The cmux zsh integration sets ZDOTDIR to the app's wrapper directory so zsh loads wrapper .zshenv/.zprofile/.zshrc. Those wrappers must temporarily restore ZDOTDIR while sourcing the user's real startup files so $ZDOTDIR semantics match normal zsh behavior. diff --git a/tests/test_sidebar_cwd_git.py b/tests/test_sidebar_cwd_git.py index 401a80a0..6b0d3fcf 100644 --- a/tests/test_sidebar_cwd_git.py +++ b/tests/test_sidebar_cwd_git.py @@ -89,8 +89,8 @@ def _git(cwd: Path, *args: str) -> None: def _init_git_repo(repo: Path) -> None: repo.mkdir(parents=True, exist_ok=True) _git(repo, "init") - _git(repo, "config", "user.email", "cmuxterm-test@example.com") - _git(repo, "config", "user.name", "cmuxterm-test") + _git(repo, "config", "user.email", "cmux-test@example.com") + _git(repo, "config", "user.name", "cmux-test") (repo / "README.md").write_text("hello\n", encoding="utf-8") _git(repo, "add", "README.md") _git(repo, "commit", "-m", "init") @@ -103,7 +103,7 @@ def _init_git_repo(repo: Path) -> None: def main() -> int: - tag = os.environ.get("CMUX_TAG") or os.environ.get("CMUXTERM_TAG") or "" + tag = os.environ.get("CMUX_TAG") or "" if not tag: print("Tip: set CMUX_TAG= when running this test to avoid socket conflicts.") diff --git a/tests/test_sidebar_ports.py b/tests/test_sidebar_ports.py index 51b242dd..0fd98966 100644 --- a/tests/test_sidebar_ports.py +++ b/tests/test_sidebar_ports.py @@ -83,7 +83,7 @@ def _find_free_allowed_port() -> int: def _start_external_server(base: Path, port: int) -> subprocess.Popen: """ - Start an http.server outside cmuxterm and ensure it is actually listening. + Start an http.server outside cmux and ensure it is actually listening. Retries are handled by the caller by picking a different port. """ proc = subprocess.Popen( @@ -201,7 +201,7 @@ def _wait_for_lsof_listen_gone(port: int, timeout: float = 8.0) -> None: def main() -> int: - tag = os.environ.get("CMUX_TAG") or os.environ.get("CMUXTERM_TAG") or "" + tag = os.environ.get("CMUX_TAG") or "" if not tag: print("Tip: set CMUX_TAG= when running this test to avoid socket conflicts.") @@ -215,7 +215,7 @@ def main() -> int: shutil.rmtree(base) base.mkdir(parents=True, exist_ok=True) - # Start a listening server outside cmuxterm. A fresh tab should NOT show this port, + # Start a listening server outside cmux. A fresh tab should NOT show this port, # since ports should be attributed to the shell session in the tab. port = None last_start_err: Exception | None = None diff --git a/tests/test_terminfo_bright_colors.py b/tests/test_terminfo_bright_colors.py index 91c5de53..5969ca80 100644 --- a/tests/test_terminfo_bright_colors.py +++ b/tests/test_terminfo_bright_colors.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 """ -Regression: cmuxterm relies on Ghostty's xterm-ghostty terminfo entry. +Regression: cmux relies on Ghostty's xterm-ghostty terminfo entry. -In cmuxterm (embedded GhosttyKit), "bright" SGR 90-97 can render incorrectly +In cmux (embedded GhosttyKit), "bright" SGR 90-97 can render incorrectly for some palettes. zsh-autosuggestions defaults to `fg=8`, which historically resolved to SGR 90 via terminfo `setaf`. -cmuxterm ships a terminfo overlay that forces bright colors to use indexed +cmux ships a terminfo overlay that forces bright colors to use indexed 256-color sequences (`38;5;` / `48;5;`) instead of SGR 90-97/100-107. This test ensures the overlay remains in place. """