diff --git a/.github/scripts/bundle-appimage.sh b/.github/scripts/bundle-appimage.sh index db0e59c4..7d51f1a7 100755 --- a/.github/scripts/bundle-appimage.sh +++ b/.github/scripts/bundle-appimage.sh @@ -52,8 +52,8 @@ APPDIR="dist/AppDir" rm -rf "$APPDIR" mkdir -p "$APPDIR/usr/bin" -cp "target/${TARGET}/release/tty7" "$APPDIR/usr/bin/tty7" -chmod +x "$APPDIR/usr/bin/tty7" +cp "target/${TARGET}/release/tty7-app" "$APPDIR/usr/bin/tty7-app" +chmod +x "$APPDIR/usr/bin/tty7-app" # A desktop entry + icon are mandatory AppImage metadata; linuxdeploy places # them and generates AppRun. Icon basename must match the desktop's Icon= key. @@ -62,7 +62,7 @@ cat > "$TOOLS/tty7.desktop" <<'DESKTOP' Type=Application Name=tty7 Comment=A fast, native terminal -Exec=tty7 +Exec=tty7-app Icon=tty7 Categories=System;TerminalEmulator; Terminal=false @@ -76,7 +76,7 @@ convert assets/app-icon.png -resize 256x256 "$TOOLS/tty7.png" # install the desktop/icon into their standard locations. "$LINUXDEPLOY" \ --appdir "$APPDIR" \ - --executable "$APPDIR/usr/bin/tty7" \ + --executable "$APPDIR/usr/bin/tty7-app" \ --desktop-file "$TOOLS/tty7.desktop" \ --icon-file "$TOOLS/tty7.png" diff --git a/.github/scripts/bundle-linux.sh b/.github/scripts/bundle-linux.sh index c053849a..b9edec67 100755 --- a/.github/scripts/bundle-linux.sh +++ b/.github/scripts/bundle-linux.sh @@ -27,11 +27,11 @@ STAGE="dist/${NAME}" rm -rf dist mkdir -p "$STAGE" -cp "target/${TARGET}/release/tty7" "$STAGE/tty7" -chmod +x "$STAGE/tty7" +cp "target/${TARGET}/release/tty7-app" "$STAGE/tty7-app" +chmod +x "$STAGE/tty7-app" # Release builds keep symbols (thin LTO, no profile strip); drop them here so # the archive isn't ~100 MB of debug info. -strip "$STAGE/tty7" || echo "⚠️ strip unavailable — shipping unstripped binary" +strip "$STAGE/tty7-app" || echo "⚠️ strip unavailable — shipping unstripped binary" mkdir -p "$STAGE/completions" cp assets/completions/*.json "$STAGE/completions/" cp LICENSE "$STAGE/LICENSE" diff --git a/.github/scripts/bundle-macos.sh b/.github/scripts/bundle-macos.sh index c82a5b96..5252e979 100755 --- a/.github/scripts/bundle-macos.sh +++ b/.github/scripts/bundle-macos.sh @@ -25,8 +25,8 @@ APP="dist/tty7.app" rm -rf dist mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" -cp "target/${TARGET}/release/tty7" "$APP/Contents/MacOS/tty7" -chmod +x "$APP/Contents/MacOS/tty7" +cp "target/${TARGET}/release/tty7-app" "$APP/Contents/MacOS/tty7-app" +chmod +x "$APP/Contents/MacOS/tty7-app" cp assets/tty7.icns "$APP/Contents/Resources/tty7.icns" # Completion signatures are loaded at runtime (not embedded), resolved relative # to the executable as ../Resources/completions — see terminal::signature. @@ -44,7 +44,7 @@ cat > "$APP/Contents/Info.plist" <CFBundleIdentifiercom.github.tty7 CFBundleVersion${VERSION} CFBundleShortVersionString${VERSION} - CFBundleExecutabletty7 + CFBundleExecutabletty7-app CFBundleIconFiletty7 CFBundlePackageTypeAPPL NSHighResolutionCapable @@ -96,7 +96,7 @@ ENT # Sign inner-out: the executable first, then the bundle. codesign --force --options runtime --timestamp --entitlements "$ENTITLEMENTS" \ - --sign "$SIGN_ID" "$APP/Contents/MacOS/tty7" + --sign "$SIGN_ID" "$APP/Contents/MacOS/tty7-app" codesign --force --options runtime --timestamp --entitlements "$ENTITLEMENTS" \ --sign "$SIGN_ID" "$APP" codesign --verify --strict --verbose=2 "$APP" diff --git a/.github/scripts/bundle-windows.ps1 b/.github/scripts/bundle-windows.ps1 index 40fd3cae..24182b03 100644 --- a/.github/scripts/bundle-windows.ps1 +++ b/.github/scripts/bundle-windows.ps1 @@ -5,7 +5,7 @@ # (Program Files or per-user, Start Menu shortcut, "Apps" uninstall entry) # # Fonts are embedded via include_bytes! and the app icon is compiled into the -# executable as a resource (see build.rs). So the payload is tty7.exe plus a +# executable as a resource (see build.rs). So the payload is tty7-app.exe plus a # sibling completions\ dir (loaded at runtime — see terminal::signature) and the # license/readme. Both artifacts are unsigned builds — SmartScreen will # warn on first launch. @@ -20,7 +20,7 @@ $Stage = "dist/$Name" Remove-Item -Recurse -Force dist -ErrorAction SilentlyContinue New-Item -ItemType Directory -Force -Path $Stage | Out-Null -Copy-Item "target/$Target/release/tty7.exe" "$Stage/tty7.exe" +Copy-Item "target/$Target/release/tty7-app.exe" "$Stage/tty7-app.exe" New-Item -ItemType Directory -Force -Path "$Stage/completions" | Out-Null Copy-Item "assets/completions/*.json" "$Stage/completions/" Copy-Item LICENSE "$Stage/LICENSE.txt" @@ -29,7 +29,7 @@ Copy-Item README.md "$Stage/README.md" # The Linux musl `tty7-server`, staged at server/ so a WSL distro can be handed # the binary this client shipped with (WSL downloads nothing). The # lookup path is a contract with `daemon::install::wsl` — it searches -# /server/ first — so this directory name is not free to +# /server/ first — so this directory name is not free to # change on its own. Missing is a warning, not an error, matching `server-musl`'s # own skip-don't-fail probe; WSL then fails at connect time with a message # naming the directories it searched. diff --git a/.github/scripts/windows-installer.iss b/.github/scripts/windows-installer.iss index fa3d89d8..64dd3cd5 100644 --- a/.github/scripts/windows-installer.iss +++ b/.github/scripts/windows-installer.iss @@ -3,7 +3,7 @@ ; payload and passes every path in via /D defines: ; ; /DAppVersion= version parsed from Cargo.toml -; /DStageDir= staged payload (tty7.exe, completions\, LICENSE.txt, README.md) +; /DStageDir= staged payload (tty7-app.exe, completions\, LICENSE.txt, README.md) ; /DOutputDir= where the setup exe is written ; /DOutputName= setup exe filename, without ".exe" ; @@ -35,14 +35,14 @@ ArchitecturesInstallIn64BitMode=x64compatible MinVersion=10.0 LicenseFile={#StageDir}\LICENSE.txt SetupIconFile=..\..\assets\favicon.ico -UninstallDisplayIcon={app}\tty7.exe +UninstallDisplayIcon={app}\tty7-app.exe OutputDir={#OutputDir} OutputBaseFilename={#OutputName} Compression=lzma2 SolidCompression=yes WizardStyle=modern -; The persistent daemon (tty7.exe --daemon) is a detached background process -; that outlives the GUI and holds the running image of tty7.exe, so Windows +; The persistent daemon (tty7-app.exe --daemon) is a detached background process +; that outlives the GUI and holds the running image of tty7-app.exe, so Windows ; locks the file and an upgrade can't replace it. We stop it explicitly in ; PrepareToInstall below; keep the Restart Manager as a backstop but don't let ; it relaunch anything (the GUI respawns the daemon itself on next start). @@ -53,7 +53,7 @@ RestartApplications=no Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked [Files] -Source: "{#StageDir}\tty7.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#StageDir}\tty7-app.exe"; DestDir: "{app}"; Flags: ignoreversion Source: "{#StageDir}\completions\*"; DestDir: "{app}\completions"; Flags: ignoreversion recursesubdirs Source: "{#StageDir}\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion Source: "{#StageDir}\README.md"; DestDir: "{app}"; Flags: ignoreversion @@ -63,26 +63,26 @@ Source: "{#StageDir}\README.md"; DestDir: "{app}"; Flags: ignoreversion Source: "{#StageDir}\server\*"; DestDir: "{app}\server"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist [Icons] -Name: "{autoprograms}\tty7"; Filename: "{app}\tty7.exe" -Name: "{autodesktop}\tty7"; Filename: "{app}\tty7.exe"; Tasks: desktopicon +Name: "{autoprograms}\tty7"; Filename: "{app}\tty7-app.exe" +Name: "{autodesktop}\tty7"; Filename: "{app}\tty7-app.exe"; Tasks: desktopicon [Run] -Filename: "{app}\tty7.exe"; Description: "{cm:LaunchProgram,tty7}"; Flags: nowait postinstall skipifsilent +Filename: "{app}\tty7-app.exe"; Description: "{cm:LaunchProgram,tty7}"; Flags: nowait postinstall skipifsilent [UninstallRun] -; Stop the daemon before the uninstaller deletes tty7.exe — the running daemon +; Stop the daemon before the uninstaller deletes tty7-app.exe — the running daemon ; is the locked image of that file, so removing it fails otherwise. This runs at ; the start of uninstallation, before any files are removed. The installed binary ; is this version, which understands the flag; runhidden suppresses any flash and ; the call returns without opening a window. RunOnceId keys the entry so a repeated ; uninstall doesn't run it twice. -Filename: "{app}\tty7.exe"; Parameters: "--stop-daemon"; Flags: runhidden waituntilterminated; RunOnceId: "StopDaemon" +Filename: "{app}\tty7-app.exe"; Parameters: "--stop-daemon"; Flags: runhidden waituntilterminated; RunOnceId: "StopDaemon" [Code] -(* Gracefully stop the persistent daemon before we overwrite tty7.exe. We can't +(* Gracefully stop the persistent daemon before we overwrite tty7-app.exe. We can't run the *installed* binary here — on an upgrade from an older build it may not understand --stop-daemon and would launch the GUI instead — so we extract the - *new* tty7.exe to {tmp} and run that. It connects to the running daemon, hangs + *new* tty7-app.exe to {tmp} and run that. It connects to the running daemon, hangs up every shell, waits for it to exit (releasing the file lock), then returns without opening a window. Best effort: any failure falls through to the Restart Manager backstop, and a fresh install simply has no daemon to stop. *) @@ -90,8 +90,8 @@ function PrepareToInstall(var NeedsRestart: Boolean): String; var ResultCode: Integer; begin - ExtractTemporaryFile('tty7.exe'); - Exec(ExpandConstant('{tmp}\tty7.exe'), '--stop-daemon', '', + ExtractTemporaryFile('tty7-app.exe'); + Exec(ExpandConstant('{tmp}\tty7-app.exe'), '--stop-daemon', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); Result := ''; end; diff --git a/Cargo.toml b/Cargo.toml index c81f0504..8dc6c0b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,10 +7,10 @@ repository = "https://github.com/l0ng-ai/tty7" license = "Apache-2.0" readme = "README.md" publish = false -default-run = "tty7" +default-run = "tty7-app" [[bin]] -name = "tty7" +name = "tty7-app" path = "src/main.rs" [dependencies] diff --git a/crates/tty7-core/src/core/agent_hooks.rs b/crates/tty7-core/src/core/agent_hooks.rs index f63c2fa8..084380d0 100644 --- a/crates/tty7-core/src/core/agent_hooks.rs +++ b/crates/tty7-core/src/core/agent_hooks.rs @@ -136,7 +136,7 @@ fn write_to_controlling_tty(bytes: &[u8]) -> bool { .iter() .find(|p| p.pid == pid) .and_then(|p| name_of(p.parent)) - .is_some_and(|n| n == "tty7.exe") + .is_some_and(|n| n == "tty7-app.exe") }); if let Some(pid) = shell { diff --git a/crates/tty7-core/src/daemon/install/wsl.rs b/crates/tty7-core/src/daemon/install/wsl.rs index d7d8762d..cc71e51c 100644 --- a/crates/tty7-core/src/daemon/install/wsl.rs +++ b/crates/tty7-core/src/daemon/install/wsl.rs @@ -1103,7 +1103,7 @@ mod tests { #[test] fn the_search_order_is_specific_first_and_deduplicated() { - let exe = PathBuf::from("/opt/tty7/bin/tty7.exe"); + let exe = PathBuf::from("/opt/tty7/bin/tty7-app.exe"); let dirs = bundled_search_dirs(Some(&exe), None); assert_eq!(dirs[0], PathBuf::from("/opt/tty7/bin/server")); assert_eq!(dirs[1], PathBuf::from("/opt/tty7/bin")); diff --git a/scripts/bench/mem.sh b/scripts/bench/mem.sh index b0a22423..d8f5bbd5 100755 --- a/scripts/bench/mem.sh +++ b/scripts/bench/mem.sh @@ -8,7 +8,7 @@ SELF=${0:A} HERE=${SELF:h} REPO=${HERE:h:h} WORK=${TTY7_BENCH_DIR:-$REPO/.bench} -TTY7_BIN=${TTY7_BIN:-$REPO/target/release/tty7} +TTY7_BIN=${TTY7_BIN:-$REPO/target/release/tty7-app} RUNS=${1:-3} R=$WORK/results mkdir -p $R diff --git a/scripts/bench/run_one.sh b/scripts/bench/run_one.sh index 5f054a5b..5a7733d5 100755 --- a/scripts/bench/run_one.sh +++ b/scripts/bench/run_one.sh @@ -17,7 +17,7 @@ SELF=${0:A} HERE=${SELF:h} REPO=${HERE:h:h} WORK=${TTY7_BENCH_DIR:-$REPO/.bench} -TTY7_BIN=${TTY7_BIN:-$REPO/target/release/tty7} +TTY7_BIN=${TTY7_BIN:-$REPO/target/release/tty7-app} TERM_NAME=$1 TEST=$2 COLS=${3:-}