Complete agent monitoring and Galaxy Control integration

- expose command-monitor conversations and preserve visible agent transcripts
- add bounded polling and a dedicated shell interrupt tool
- improve direct-provider images, skills, tool history, and usage handling
- package and brand Galaxy Control across releases, installers, persistence, and docs
This commit is contained in:
2026-07-29 15:04:58 -05:00
parent 100f1eff1c
commit dbfa8bcd48
172 changed files with 6357 additions and 3825 deletions
+49 -50
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Builds a Warp binary and bundles it up for distribution.
# Builds a Galaxy binary and bundles it up for distribution.
set -e
@@ -19,7 +19,7 @@ trap cleanup EXIT
# By default we build dev bundles.
RELEASE_CHANNEL="dev"
FEATURES="release_bundle,crash_reporting"
FEATURES="release_bundle"
EXTRA_FEATURES=""
PACKAGES=( appimage )
BUILD="true"
@@ -85,8 +85,8 @@ while (( "$#" )); do
;;
--artifact)
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "warpctrl" ]]; then
echo "Error: --artifact must be 'app', 'cli', or 'warpctrl', got '$2'" >&2
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "galaxyctrl" ]]; then
echo "Error: --artifact must be 'app', 'cli', or 'galaxyctrl', got '$2'" >&2
exit 1
fi
ARTIFACT="$2"
@@ -120,8 +120,8 @@ done
# set positional arguments in their proper place
eval set -- "$PARAMS"
# Statically compile the CLI and warpctrl artifacts so they can run on older Linux distros.
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
# Statically compile the CLI and galaxyctrl artifacts so they can run on older Linux distros.
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
TARGET_TRIPLE="${BUILD_ARCH}-unknown-linux-musl"
# Only configure the musl toolchain when we are actually compiling. Packaging-only
# runs (--skip-build) just need TARGET_TRIPLE to locate the prebuilt binary, and
@@ -144,13 +144,13 @@ elif [[ $RELEASE_CHANNEL = "local" || $RELEASE_CHANNEL = "dev" ]]; then
# For dev bundles, we want to enable debug assertions to
# catch violations that would otherwise silently pass in
# a normal release build (e.g. in stable).
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
CARGO_PROFILE="release-cli-debug_assertions"
else
CARGO_PROFILE="release-lto-debug_assertions"
fi
else
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
CARGO_PROFILE="release-cli"
else
CARGO_PROFILE="release-lto"
@@ -173,71 +173,70 @@ mkdir -p "$OUT_DIR"
# APP_NAME here must match the value used in Rust as the
# application name; see app/src/channel.rs.
#
# WARP_BIN is the name of the binary produced by cargo;
# GALAXY_BIN is the name of the binary produced by cargo;
# BINARY_NAME is the desired name of the binary in the final package.
if [[ $RELEASE_CHANNEL = "local" ]]; then
WARP_BIN="warp"
BINARY_NAME="warp-local"
GALAXY_BIN="galaxy-local"
BINARY_NAME="galaxy-local"
APP_NAME="GalaxyLocal"
FEATURES="$FEATURES,agent_mode_debug"
export HANDLE_MARKDOWN=1
elif [[ $RELEASE_CHANNEL = "dev" ]]; then
WARP_BIN="dev"
BINARY_NAME="warp-dev"
GALAXY_BIN="galaxy-dev"
BINARY_NAME="galaxy-dev"
APP_NAME="GalaxyDev"
FEATURES="$FEATURES,agent_mode_debug"
# Enable heap usage tracking & profiling using jemalloc through pprof.
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
export HANDLE_MARKDOWN=1
elif [[ $RELEASE_CHANNEL = "preview" ]]; then
WARP_BIN="preview"
BINARY_NAME="warp-preview"
GALAXY_BIN="galaxy-preview"
BINARY_NAME="galaxy-preview"
APP_NAME="GalaxyPreview"
FEATURES="$FEATURES,preview_channel"
# Enable heap usage tracking & profiling using jemalloc through pprof.
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
elif [[ $RELEASE_CHANNEL = "stable" ]]; then
WARP_BIN="stable"
BINARY_NAME="warp"
GALAXY_BIN="stable"
BINARY_NAME="galaxy"
APP_NAME="Galaxy"
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
WARP_BIN="warp-oss"
BINARY_NAME="warp-oss"
GALAXY_BIN="galaxy-oss"
BINARY_NAME="galaxy-oss"
APP_NAME="GalaxyOss"
# The OSS channel does not ship Sentry, so drop the crash_reporting feature
# (which would otherwise pull in the Sentry SDK as a dependency).
FEATURES="release_bundle"
fi
# Artifact-specific binary naming
if [[ "$ARTIFACT" == "cli" ]]; then
# For CLI artifacts, use oz instead of warp as the binary name. The OSS
# channel is an exception: its CLI command name is `warp-oss`, matching
# `Channel::cli_command_name` in the Rust source.
if [[ $RELEASE_CHANNEL != "oss" ]]; then
BINARY_NAME="${BINARY_NAME/warp/oz}"
fi
elif [[ "$ARTIFACT" == "warpctrl" ]]; then
BINARY_NAME="warpctrl"
# Keep packaged CLI names aligned with `Channel::cli_command_name`.
case "$RELEASE_CHANNEL" in
stable) BINARY_NAME="galaxy-ai" ;;
preview) BINARY_NAME="galaxy-ai-preview" ;;
dev) BINARY_NAME="galaxy-ai-dev" ;;
local) BINARY_NAME="galaxy-ai-local" ;;
oss) BINARY_NAME="galaxy-ai-oss" ;;
esac
elif [[ "$ARTIFACT" == "galaxyctrl" ]]; then
BINARY_NAME="galaxyctrl"
PACKAGES=()
fi
# Artifact-specific configuration
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
FEATURES="$FEATURES,standalone"
if [[ "$ARTIFACT" == "warpctrl" ]]; then
FEATURES="$FEATURES,warp_control_cli"
if [[ "$ARTIFACT" == "galaxyctrl" ]]; then
FEATURES="$FEATURES,galaxy_control_cli"
fi
elif [[ "$ARTIFACT" == "app" ]]; then
# All channels ship the v3 classifier and v2 heuristic.
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2"
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2,galaxy_control_cli"
fi
if [[ -n "$EXTRA_FEATURES" ]]; then
FEATURES="$FEATURES,$EXTRA_FEATURES"
fi
BUNDLE_ID="dev.warp.$APP_NAME"
EXECUTABLE_PATH="$CARGO_TARGET_OUTPUT_DIR/$WARP_BIN"
BUNDLE_ID="dev.galaxy.$APP_NAME"
EXECUTABLE_PATH="$CARGO_TARGET_OUTPUT_DIR/$GALAXY_BIN"
DEBUG_EXECUTABLE_PATH="$EXECUTABLE_PATH.debug"
# Note that this variable must be set (and exported!) before we compile the
@@ -249,14 +248,14 @@ export APPIMAGE_NAME="$APP_NAME-$BUILD_ARCH.AppImage"
# then exit. We use this script to invoke `cargo check` to ensure that we are
# using the same feature flags and profile that we would be using in production.
if [[ "$CHECK_ONLY" == "true" ]]; then
cargo check -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
cargo check -p galaxy --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
exit 0
fi
# Build the binary.
if [[ "$BUILD" == "true" ]]; then
echo "Building and bundling Warp for channel $RELEASE_CHANNEL and bundle id $BUNDLE_ID"
cargo build -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
echo "Building and bundling Galaxy for channel $RELEASE_CHANNEL and bundle id $BUNDLE_ID"
cargo build -p galaxy --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES" ${TARGET_TRIPLE:+--target $TARGET_TRIPLE}
echo "Making debug copy of '$EXECUTABLE_PATH' at '$DEBUG_EXECUTABLE_PATH'"
cp "$EXECUTABLE_PATH" "$DEBUG_EXECUTABLE_PATH"
@@ -275,25 +274,25 @@ else
echo 'Skipping `cargo build` step due to --skip-build argument'
fi
if [[ "$ARTIFACT" == "warpctrl" ]]; then
echo "Copying control-mode binary into $OUT_DIR/$WARP_BIN"
cp "$EXECUTABLE_PATH" "$OUT_DIR/$WARP_BIN"
WARPCTRL_SCRIPT_PATH="$OUT_DIR/warpctrl"
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH"
cat > "$WARPCTRL_SCRIPT_PATH" << EOF
if [[ "$ARTIFACT" == "galaxyctrl" ]]; then
echo "Copying control-mode binary into $OUT_DIR/$GALAXY_BIN"
cp "$EXECUTABLE_PATH" "$OUT_DIR/$GALAXY_BIN"
GALAXYCTRL_SCRIPT_PATH="$OUT_DIR/galaxyctrl"
echo "Creating galaxyctrl wrapper script at $GALAXYCTRL_SCRIPT_PATH"
cat > "$GALAXYCTRL_SCRIPT_PATH" << EOF
#!/usr/bin/env bash
script_dir="\$(cd "\$(dirname "\${BASH_SOURCE[0]}")" && pwd)"
exec "\$script_dir/$WARP_BIN" --warpctrl "\$@"
exec -a "\$0" "\$script_dir/$GALAXY_BIN" --galaxyctrl "\$@"
EOF
chmod +x "$WARPCTRL_SCRIPT_PATH"
chmod +x "$GALAXYCTRL_SCRIPT_PATH"
fi
BINARY_PATH="$EXECUTABLE_PATH"
if [[ "$ARTIFACT" == "warpctrl" ]]; then
BINARY_PATH="$WARPCTRL_SCRIPT_PATH"
if [[ "$ARTIFACT" == "galaxyctrl" ]]; then
BINARY_PATH="$GALAXYCTRL_SCRIPT_PATH"
fi
# Prepare bundled resources for CLI builds.
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
echo "Preparing CLI resources directory"
BUNDLED_RESOURCES_DIR="$OUT_DIR/resources"
"$WORKSPACE_ROOT_DIR/script/prepare_bundled_resources" "$BUNDLED_RESOURCES_DIR" "$RELEASE_CHANNEL" "$CARGO_PROFILE"
+9 -12
View File
@@ -8,7 +8,7 @@
# - OUT_DIR: The directory into which we should place the final package.
# - CARGO_TARGET_OUTPUT_DIR: The cargo target directory containing build output.
# - RELEASE_CHANNEL: The release channel we're bundling (e.g.: "dev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.warp.WarpDev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.galaxy.GalaxyDev").
# - EXECUTABLE_PATH: The path to the compiled executable we want to install.
# - BINARY_NAME: The name that the compiled executable should have on the target machine.
# - APPIMAGE_NAME: The name of the AppImage file to produce.
@@ -16,14 +16,11 @@
STAGE_DIR="$DIST_DIR/appimagepkg"
APP_DIR="$DIST_DIR/AppDir"
# Extract channel suffix from BINARY_NAME
if [ "$ARTIFACT" = "cli" ]; then
CHANNEL_SUFFIX="${BINARY_NAME#oz}"
else
CHANNEL_SUFFIX="${BINARY_NAME#warp}"
if [[ "$ARTIFACT" != "app" ]]; then
echo "::error ::AppImage packaging only supports the app artifact" >&2
exit 1
fi
PACKAGE_NAME="warp-terminal$CHANNEL_SUFFIX"
source "$WORKSPACE_ROOT_DIR/script/linux/package_metadata"
# Adding NO_STRIP to stop linuxdeploy from attempting to strip symbols
# from binaries built on a different arch than the current symbol.
@@ -55,9 +52,9 @@ mkdir -p "$STAGE_DIR"
OPT_DIR="/opt/warpdotdev/$PACKAGE_NAME"
source "$WORKSPACE_ROOT_DIR/script/linux/bundle_install" "$STAGE_DIR"
# Modify the "Exec=" line in the .desktop file to use the name of the installed
# binary and not our /usr/bin symlink (which doesn't exist in an AppImage).
sed -i -E 's/Exec=warp-terminal/Exec=warp/' "$STAGE_DIR/usr/share/applications/$BUNDLE_ID.desktop"
# The AppImage exposes the staged Cargo binary rather than the package
# launcher's /usr/bin symlink, so point the desktop entry at that binary.
sed -i -E "s#^Exec=[^ ]+#Exec=$BINARY_NAME#" "$STAGE_DIR/usr/share/applications/$BUNDLE_ID.desktop"
# Find all icon files from inside the package staging directory.
ICON_FILES=( $(find "$STAGE_DIR/usr/share/icons" -name "*.png") )
@@ -68,7 +65,7 @@ rm -rf "$APP_DIR"
# Run linuxdeploy to create an appropriately-structured AppDir and turn it into
# an AppImage, located in OUT_DIR.
#
# We use a custom input plugin (bundled-resources) to copy Warp's bundled
# We use a custom input plugin (bundled-resources) to copy Galaxy's bundled
# resources into the AppDir alongside the executable, since linuxdeploy only
# deploys the binary, desktop file, and icons by default.
cd "$OUT_DIR"
+4 -24
View File
@@ -8,34 +8,14 @@
# - OUT_DIR: The directory into which we should place the final package.
# - CARGO_TARGET_OUTPUT_DIR: The cargo target directory containing build output.
# - RELEASE_CHANNEL: The release channel we're bundling (e.g.: "dev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.warp.WarpDev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.galaxy.GalaxyDev").
# - EXECUTABLE_PATH: The path to the compiled executable we want to install.
# - BINARY_NAME: The name that the compiled executable should have on the target machine.
# - ARTIFACT: Which artifact to build: app or cli.
set -e
# Extract channel suffix from BINARY_NAME
if [ "$ARTIFACT" = "cli" ]; then
CHANNEL_SUFFIX="${BINARY_NAME#oz}"
else
CHANNEL_SUFFIX="${BINARY_NAME#warp}"
fi
# On Linux, we keep the `-stable` suffix for stable to avoid package conflicts.
# The binary name is still `oz`, and the repo name is still `warpdotdev`.
if [ "$ARTIFACT" = "cli" -a "$RELEASE_CHANNEL" = "stable" ]; then
CHANNEL_SUFFIX="-stable"
fi
if [ "$ARTIFACT" = "app" ]; then
PACKAGE_NAME="warp-terminal$CHANNEL_SUFFIX"
elif [ "$ARTIFACT" = "cli" ]; then
PACKAGE_NAME="oz$CHANNEL_SUFFIX"
else
echo "::error ::Unknown ARTIFACT: $ARTIFACT (expected 'app' or 'cli')"
exit 1
fi
source "$WORKSPACE_ROOT_DIR/script/linux/package_metadata"
BUILD_ARCH="${BUILD_ARCH:-$(uname -m)}"
if [ "$BUILD_ARCH" = "aarch64" ]; then
@@ -71,14 +51,14 @@ tar cvf "$PKGDIR/data.tar" -C "$PKGDIR/stage" .
VERSION="$GIT_RELEASE_TAG"
RELEASE=1
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@VERSION@@#$VERSION#g; s#@@RELEASE@@#$RELEASE#g; s#@@ARCH@@#$ARCH#g; s#@@OUTDIR@@#$OUT_DIR#g; s#@@BINARY_NAME@@#$BINARY_NAME#g" \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@VERSION@@#$VERSION#g; s#@@RELEASE@@#$RELEASE#g; s#@@ARCH@@#$ARCH#g; s#@@OUTDIR@@#$OUT_DIR#g; s#@@BINARY_NAME@@#$BINARY_NAME#g" \
< "$WORKSPACE_ROOT_DIR/resources/linux/arch/$ARTIFACT/PKGBUILD.template" \
> "$PKGDIR/PKGBUILD"
# Only create wrapper script for app artifact
if [ "$ARTIFACT" = "app" ]; then
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@BINARY_NAME@@#$BINARY_NAME#g" \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@BINARY_NAME@@#$BINARY_NAME#g" \
< "$WORKSPACE_ROOT_DIR/resources/linux/arch/$ARTIFACT/warp.sh.template" \
> "$PKGDIR/$PACKAGE_NAME.sh"
fi
+5 -30
View File
@@ -8,39 +8,14 @@
# - OUT_DIR: The directory into which we should place the final package.
# - CARGO_TARGET_OUTPUT_DIR: The cargo target directory containing build output.
# - RELEASE_CHANNEL: The release channel we're bundling (e.g.: "dev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.warp.WarpDev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.galaxy.GalaxyDev").
# - EXECUTABLE_PATH: The path to the compiled executable we want to install.
# - BINARY_NAME: The name that the compiled executable should have on the target machine.
# - ARTIFACT: Which artifact to build: app or cli.
set -e
# Extract channel suffix from BINARY_NAME
if [ "$ARTIFACT" = "cli" ]; then
CHANNEL_SUFFIX="${BINARY_NAME#oz}"
else
CHANNEL_SUFFIX="${BINARY_NAME#warp}"
fi
REPO_NAME="warpdotdev$CHANNEL_SUFFIX"
# On Linux, we keep the `-stable` suffix for stable to avoid package conflicts.
# The binary name is still `oz`, and the repo name is still `warpdotdev`.
if [ "$ARTIFACT" = "cli" -a "$RELEASE_CHANNEL" = "stable" ]; then
CHANNEL_SUFFIX="-stable"
fi
case "$ARTIFACT" in
app)
PACKAGE_NAME="warp-terminal$CHANNEL_SUFFIX"
;;
cli)
PACKAGE_NAME="oz$CHANNEL_SUFFIX"
;;
*)
echo "::error ::Unknown ARTIFACT: $ARTIFACT (expected 'app' or 'cli')"
exit 1
;;
esac
source "$WORKSPACE_ROOT_DIR/script/linux/package_metadata"
TEMPLATE_DIR="$WORKSPACE_ROOT_DIR/resources/linux/debian/$ARTIFACT"
# Add a simple test to make sure we're generating the appropriate repository
@@ -87,11 +62,11 @@ DEBIAN_DIR="$PKGDIR/DEBIAN"
VERSION="$(echo "$GIT_RELEASE_TAG" | sed -E "s/^v//; s/([a-z]+)_/\1./")"
mkdir "$DEBIAN_DIR"
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@VERSION@@#$VERSION#g; s#@@ARCH@@#$ARCH#g" \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@VERSION@@#$VERSION#g; s#@@ARCH@@#$ARCH#g" \
< "$TEMPLATE_DIR/control.template" \
> "$DEBIAN_DIR/control"
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@BINARY_NAME@@#$BINARY_NAME#g; s#@@OPTDIR@@#$OPT_DIR#g; s#@@REPO_NAME@@#$REPO_NAME#g; s#@@CHANNEL@@#$RELEASE_CHANNEL#g; s#@@ARCH@@#$ARCH#g" \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@BINARY_NAME@@#$BINARY_NAME#g; s#@@OPTDIR@@#$OPT_DIR#g; s#@@REPO_NAME@@#$REPO_NAME#g; s#@@CHANNEL@@#$RELEASE_CHANNEL#g; s#@@ARCH@@#$ARCH#g" \
< "$TEMPLATE_DIR/postinst.template" \
> "$DEBIAN_DIR/postinst"
sed \
@@ -99,7 +74,7 @@ sed \
< "$WORKSPACE_ROOT_DIR/resources/linux/debian/common/postinst.repo.template" \
>> "$DEBIAN_DIR/postinst"
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@OPTDIR@@#$OPT_DIR#g; s#@@REPO_NAME@@#$REPO_NAME#g" \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; s#@@BINARY_NAME@@#$BINARY_NAME#g; s#@@OPTDIR@@#$OPT_DIR#g; s#@@REPO_NAME@@#$REPO_NAME#g" \
< "$TEMPLATE_DIR/postrm.template" \
> "$DEBIAN_DIR/postrm"
sed \
+19 -1
View File
@@ -9,7 +9,7 @@
# - CARGO_TARGET_OUTPUT_DIR: The cargo target directory containing build output.
# - OPT_DIR: The absolute path to our install directory (under /opt) on the target machine.
# - RELEASE_CHANNEL: The release channel we're bundling (e.g.: "dev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.warp.WarpDev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.galaxy.GalaxyDev").
# - EXECUTABLE_PATH: The path to the compiled executable we want to install.
# - BINARY_NAME: The name that the compiled executable should have on the target machine.
# - ARTIFACT: Which artifact to build: app or cli.
@@ -34,6 +34,24 @@ fi
install -D "$EXECUTABLE_PATH" "${TARGET_DIR}${OPT_DIR}/$BINARY_NAME"
# Only install desktop file and icons if the artifact is "app"
if [[ "$ARTIFACT" == "app" ]]; then
# Normal app packages expose both command-line entrypoints through the same
# channel-specific Galaxy executable. The Galaxy AI wrapper preserves its
# invocation name, while Galaxy Control also selects the isolated control
# parser before normal app startup.
source "$WORKSPACE_ROOT_DIR/script/linux/package_metadata"
mkdir -p "${TARGET_DIR}/usr/bin"
cat > "${TARGET_DIR}/usr/bin/$GALAXY_AI_COMMAND_NAME" << EOF
#!/usr/bin/env bash
exec -a "\$0" "$OPT_DIR/$BINARY_NAME" "\$@"
EOF
cat > "${TARGET_DIR}/usr/bin/$GALAXY_CONTROL_COMMAND_NAME" << EOF
#!/usr/bin/env bash
exec -a "\$0" "$OPT_DIR/$BINARY_NAME" --galaxyctrl "\$@"
EOF
chmod 755 \
"${TARGET_DIR}/usr/bin/$GALAXY_AI_COMMAND_NAME" \
"${TARGET_DIR}/usr/bin/$GALAXY_CONTROL_COMMAND_NAME"
install -Dm644 "$WORKSPACE_ROOT_DIR/app/channels/$RELEASE_CHANNEL/$BUNDLE_ID.desktop" "${TARGET_DIR}/usr/share/applications/$BUNDLE_ID.desktop"
for size in 16x16 32x32 64x64 128x128 256x256 512x512; do
src_path="$WORKSPACE_ROOT_DIR/app/channels/$RELEASE_CHANNEL/icon/no-padding/$size.png"
+6 -24
View File
@@ -8,36 +8,15 @@
# - OUT_DIR: The directory into which we should place the final package.
# - CARGO_TARGET_OUTPUT_DIR: The cargo target directory containing build output.
# - RELEASE_CHANNEL: The release channel we're bundling (e.g.: "dev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.warp.WarpDev").
# - BUNDLE_ID: The app ID for the bundle (e.g.: "dev.galaxy.GalaxyDev").
# - EXECUTABLE_PATH: The path to the compiled executable we want to install.
# - BINARY_NAME: The name that the compiled executable should have on the target machine.
# - ARTIFACT: Which artifact to build: app or cli.
set -e
# Extract channel suffix from BINARY_NAME
if [ "$ARTIFACT" = "cli" ]; then
CHANNEL_SUFFIX="${BINARY_NAME#oz}"
else
CHANNEL_SUFFIX="${BINARY_NAME#warp}"
fi
REPO_NAME="warpdotdev$CHANNEL_SUFFIX"
# On Linux, we keep the `-stable` suffix for stable to avoid package conflicts.
# The binary name is still `oz`, and the repo name is still `warpdotdev`.
if [ "$ARTIFACT" = "cli" -a "$RELEASE_CHANNEL" = "stable" ]; then
CHANNEL_SUFFIX="-stable"
fi
ARTIFACT="${ARTIFACT:-app}"
if [ "$ARTIFACT" = "app" ]; then
PACKAGE_NAME="warp-terminal$CHANNEL_SUFFIX"
elif [ "$ARTIFACT" = "cli" ]; then
PACKAGE_NAME="oz$CHANNEL_SUFFIX"
else
echo "::error ::Unknown ARTIFACT: $ARTIFACT (expected 'app' or 'cli')"
exit 1
fi
source "$WORKSPACE_ROOT_DIR/script/linux/package_metadata"
BUILD_ARCH="${BUILD_ARCH:-$(uname -m)}"
if [ "$BUILD_ARCH" = "aarch64" ]; then
@@ -69,8 +48,11 @@ mkdir -p "$RPMBUILD_DIR"/{SPEC,RPMS}
VERSION="$GIT_RELEASE_TAG"
RELEASE="1"
sed \
"s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; \
"s#@@PACKAGE_NAME@@#$PACKAGE_NAME#g; \
s#@@CHANNEL_SUFFIX@@#$CHANNEL_SUFFIX#g; \
s#@@BINARY_NAME@@#$BINARY_NAME#g; \
s#@@GALAXY_AI_COMMAND_NAME@@#$GALAXY_AI_COMMAND_NAME#g; \
s#@@GALAXY_CONTROL_COMMAND_NAME@@#$GALAXY_CONTROL_COMMAND_NAME#g; \
s#@@VERSION@@#$VERSION#g; \
s#@@RELEASE@@#$RELEASE#g; \
s#@@ARCH@@#$ARCH#g; \
+4 -4
View File
@@ -1,6 +1,6 @@
#!/bin/bash
#
# linuxdeploy input plugin for restructuring the AppDir to match Warp's
# linuxdeploy input plugin for restructuring the AppDir to match Galaxy's
# standard Linux install layout.
#
# By default, linuxdeploy places the executable at usr/bin/ inside the AppDir.
@@ -12,8 +12,8 @@
# as installing a .deb or .rpm package.
#
# Required environment variables:
# WARP_BINARY_NAME: Name of the binary (e.g. "warp-dev").
# WARP_PACKAGE_NAME: Package directory name (e.g. "warp-terminal-dev").
# WARP_BINARY_NAME: Name of the binary (e.g. "galaxy-dev").
# WARP_PACKAGE_NAME: Package directory name (e.g. "galaxy-terminal-dev").
# WARP_BUNDLED_RESOURCES_DIR: Path to the staged resources directory to copy.
set -e
@@ -76,4 +76,4 @@ echo "Copying bundled resources to $DEST_RESOURCES"
mkdir -p "$DEST_RESOURCES"
cp -R "$WARP_BUNDLED_RESOURCES_DIR/." "$DEST_RESOURCES/"
echo "Successfully restructured AppDir for Warp"
echo "Successfully restructured AppDir for Galaxy"
+44
View File
@@ -0,0 +1,44 @@
#!/usr/bin/env bash
#
# Derives Linux package metadata from Galaxy's release channel and artifact.
# This file is sourced by the individual package builders.
case "$RELEASE_CHANNEL" in
stable)
CHANNEL_SUFFIX=""
;;
local|dev|preview|oss)
CHANNEL_SUFFIX="-$RELEASE_CHANNEL"
;;
*)
echo "::error ::Unknown RELEASE_CHANNEL: $RELEASE_CHANNEL" >&2
return 1
;;
esac
GALAXY_AI_COMMAND_NAME="galaxy-ai$CHANNEL_SUFFIX"
GALAXY_CONTROL_COMMAND_NAME="galaxyctrl$CHANNEL_SUFFIX"
case "$ARTIFACT" in
app)
# The OSS desktop entry invokes the Cargo binary directly. Other channels
# expose the traditional `*-terminal` launcher independently of the Cargo
# binary name.
if [[ "$RELEASE_CHANNEL" == "oss" ]]; then
PACKAGE_NAME="galaxy-oss"
else
PACKAGE_NAME="galaxy-terminal$CHANNEL_SUFFIX"
fi
;;
cli)
PACKAGE_NAME="galaxy-ai$CHANNEL_SUFFIX"
;;
*)
echo "::error ::Unknown ARTIFACT: $ARTIFACT (expected 'app' or 'cli')" >&2
return 1
;;
esac
# Repository provisioning still uses the existing release infrastructure and
# templates. This name is intentionally independent of Galaxy package names.
REPO_NAME="warpdotdev$CHANNEL_SUFFIX"
@@ -43,20 +43,22 @@ PATH="$temp_dir/bin:$PATH" \
CARGO_TARGET_DIR="$temp_dir/target" \
"$workspace_root/script/linux/bundle" \
--check-only \
--artifact warpctrl \
--artifact galaxyctrl \
--arch "$arch" \
--features smoke_feature
grep -qx -- '--features' "$temp_dir/cargo-args"
grep -qx -- 'release_bundle,crash_reporting,agent_mode_debug,jemalloc_pprof,heap_usage_tracking,standalone,warp_control_cli,smoke_feature' "$temp_dir/cargo-args"
grep -qx -- 'galaxy' "$temp_dir/cargo-args"
grep -qx -- 'galaxy-dev' "$temp_dir/cargo-args"
grep -qx -- 'release_bundle,agent_mode_debug,jemalloc_pprof,heap_usage_tracking,standalone,galaxy_control_cli,smoke_feature' "$temp_dir/cargo-args"
profile_dir="$temp_dir/target/$target/release-cli-debug_assertions"
mkdir -p "$profile_dir"
cat > "$profile_dir/dev" <<'EOF'
cat > "$profile_dir/galaxy-dev" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$@" > "$FORWARDED_ARGS_FILE"
EOF
chmod +x "$profile_dir/dev"
chmod +x "$profile_dir/galaxy-dev"
PATH="$temp_dir/bin:$PATH" \
CARGO_TARGET_DIR="$temp_dir/target" \
@@ -64,14 +66,16 @@ PATH="$temp_dir/bin:$PATH" \
SKIP_SETTINGS_SCHEMA=1 \
"$workspace_root/script/linux/bundle" \
--skip-build \
--artifact warpctrl \
--artifact galaxyctrl \
--arch "$arch"
grep -Fq 'exec -a "$0"' "$profile_dir/bundle/linux/galaxyctrl"
FORWARDED_ARGS_FILE="$temp_dir/forwarded-args" \
"$profile_dir/bundle/linux/warpctrl" tab create --instance "inst 123"
"$profile_dir/bundle/linux/galaxyctrl" tab create --instance "inst 123"
cat > "$temp_dir/expected-forwarded-args" <<'EOF'
--warpctrl
--galaxyctrl
tab
create
--instance
+118
View File
@@ -0,0 +1,118 @@
#!/usr/bin/env bash
set -e
workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
assert_metadata() {
local artifact="$1"
local channel="$2"
local expected_suffix="$3"
local expected_package="$4"
ARTIFACT="$artifact"
RELEASE_CHANNEL="$channel"
source "$workspace_root/script/linux/package_metadata"
[[ "$CHANNEL_SUFFIX" == "$expected_suffix" ]]
[[ "$PACKAGE_NAME" == "$expected_package" ]]
[[ "$GALAXY_AI_COMMAND_NAME" == "galaxy-ai$expected_suffix" ]]
[[ "$GALAXY_CONTROL_COMMAND_NAME" == "galaxyctrl$expected_suffix" ]]
}
assert_metadata app stable "" galaxy-terminal
assert_metadata app local -local galaxy-terminal-local
assert_metadata app dev -dev galaxy-terminal-dev
assert_metadata app preview -preview galaxy-terminal-preview
assert_metadata app oss -oss galaxy-oss
assert_metadata cli stable "" galaxy-ai
assert_metadata cli local -local galaxy-ai-local
assert_metadata cli dev -dev galaxy-ai-dev
assert_metadata cli preview -preview galaxy-ai-preview
assert_metadata cli oss -oss galaxy-ai-oss
assert_desktop_launcher() {
local channel="$1"
local app_name="$2"
local expected_launcher="$3"
local desktop_file="$workspace_root/app/channels/$channel/dev.galaxy.$app_name.desktop"
[[ -f "$desktop_file" ]]
grep -qx -- "Exec=$expected_launcher %U" "$desktop_file"
}
assert_desktop_launcher stable Galaxy galaxy-terminal
assert_desktop_launcher local GalaxyLocal galaxy-terminal-local
assert_desktop_launcher dev GalaxyDev galaxy-terminal-dev
assert_desktop_launcher preview GalaxyPreview galaxy-terminal-preview
assert_desktop_launcher oss GalaxyOss galaxy-oss
grep -qx -- 'Package: @@PACKAGE_NAME@@' \
"$workspace_root/resources/linux/debian/app/control.template" \
"$workspace_root/resources/linux/debian/cli/control.template"
grep -qx -- 'Name: @@PACKAGE_NAME@@' \
"$workspace_root/resources/linux/rpm/app/warp.spec.template" \
"$workspace_root/resources/linux/rpm/cli/warp.spec.template"
grep -qx -- '%{_bindir}/@@GALAXY_AI_COMMAND_NAME@@' \
"$workspace_root/resources/linux/rpm/app/warp.spec.template"
grep -qx -- '%{_bindir}/@@GALAXY_CONTROL_COMMAND_NAME@@' \
"$workspace_root/resources/linux/rpm/app/warp.spec.template"
grep -qx -- 'pkgname=@@PACKAGE_NAME@@' \
"$workspace_root/resources/linux/arch/app/PKGBUILD.template" \
"$workspace_root/resources/linux/arch/cli/PKGBUILD.template"
temp_dir="$(mktemp -d)"
trap 'rm -rf "$temp_dir"' EXIT
fake_workspace="$temp_dir/workspace"
stage_dir="$temp_dir/stage"
mkdir -p \
"$fake_workspace/bin" \
"$fake_workspace/script/linux" \
"$fake_workspace/app/channels/dev" \
"$stage_dir"
ln -s \
"$workspace_root/script/linux/package_metadata" \
"$fake_workspace/script/linux/package_metadata"
cat > "$fake_workspace/script/prepare_bundled_resources" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x "$fake_workspace/script/prepare_bundled_resources"
cat > "$fake_workspace/bin/install" <<'EOF'
#!/usr/bin/env bash
paths=()
for arg in "$@"; do
if [[ "$arg" != -* ]]; then
paths+=("$arg")
fi
done
mkdir -p "$(dirname "${paths[1]}")"
cp "${paths[0]}" "${paths[1]}"
EOF
chmod +x "$fake_workspace/bin/install"
cat > "$fake_workspace/app/channels/dev/dev.galaxy.GalaxyDev.desktop" <<'EOF'
[Desktop Entry]
Name=Galaxy Dev
Exec=galaxy-terminal-dev %U
EOF
cat > "$temp_dir/galaxy-dev" <<'EOF'
#!/usr/bin/env bash
exit 0
EOF
chmod +x "$temp_dir/galaxy-dev"
PATH="$fake_workspace/bin:$PATH" \
WORKSPACE_ROOT_DIR="$fake_workspace" \
RELEASE_CHANNEL=dev \
ARTIFACT=app \
BUNDLE_ID=dev.galaxy.GalaxyDev \
EXECUTABLE_PATH="$temp_dir/galaxy-dev" \
BINARY_NAME=galaxy-dev \
OPT_DIR=/opt/warpdotdev/galaxy-terminal-dev \
CARGO_PROFILE=dev \
"$workspace_root/script/linux/bundle_install" "$stage_dir"
grep -Fq 'exec -a "$0" "/opt/warpdotdev/galaxy-terminal-dev/galaxy-dev" "$@"' \
"$stage_dir/usr/bin/galaxy-ai-dev"
grep -Fq 'exec -a "$0" "/opt/warpdotdev/galaxy-terminal-dev/galaxy-dev" --galaxyctrl "$@"' \
"$stage_dir/usr/bin/galaxyctrl-dev"
+51 -49
View File
@@ -70,7 +70,7 @@ cleanup_dmg_files() {
find "$target_dir" -name "rw.*.dmg" -type f -delete
fi
# Also check if any volumes are mounted and unmount them
hdiutil info | grep "/Volumes/Warp.*" | awk '{print $1}' | while read -r disk; do
hdiutil info | grep "/Volumes/Galaxy.*" | awk '{print $1}' | while read -r disk; do
echo "Unmounting disk image: $disk"
hdiutil detach "$disk" -force || true
done
@@ -136,7 +136,7 @@ while (( "$#" )); do
SELFSIGN=false
shift
;;
# Sign with a local Apple Development cert instead of the official Warp cert.
# Sign with a local Apple Development cert instead of the official Galaxy cert.
# Useful for local debug builds when you don't have access to the company signing key.
# Falls back to ad-hoc signing if no Apple Development cert is found.
--selfsign)
@@ -223,8 +223,8 @@ while (( "$#" )); do
;;
--artifact)
if [ -n "$2" ] && [ "${2:0:1}" != "-" ]; then
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "warpctrl" ]]; then
echo "Error: --artifact must be 'app', 'cli', or 'warpctrl', got '$2'" >&2
if [[ "$2" != "app" && "$2" != "cli" && "$2" != "galaxyctrl" ]]; then
echo "Error: --artifact must be 'app', 'cli', or 'galaxyctrl', got '$2'" >&2
exit 1
fi
ARTIFACT="$2"
@@ -250,13 +250,13 @@ elif [[ $RELEASE_CHANNEL = "local" || $RELEASE_CHANNEL = "dev" ]]; then
# For dev bundles, we want to enable debug assertions to
# catch violations that would otherwise silently pass in
# a normal release build (e.g. in stable).
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
CARGO_PROFILE="release-cli-debug_assertions"
else
CARGO_PROFILE="release-lto-debug_assertions"
fi
else
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
if [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
CARGO_PROFILE="release-cli"
else
CARGO_PROFILE="release-lto"
@@ -269,9 +269,9 @@ if [[ "$CARGO_PROFILE" == "dev" ]]; then
fi
if [[ $RELEASE_CHANNEL = "local" ]]; then
WARP_BIN="galaxy-ai"
WARP_BIN="galaxy-local"
BUNDLE_ID="com.samsung.Galaxy-Local"
WARP_APP_NAME="Galaxy"
WARP_APP_NAME="Galaxy Local"
WARP_SCHEME_NAME="galaxy"
FEATURES="$FEATURES,agent_mode_debug"
# For local builds, use different versions of our bundled frameworks (e.g.:
@@ -279,24 +279,22 @@ if [[ $RELEASE_CHANNEL = "local" ]]; then
# app/build.rs later, while running `cargo bundle`.
export FRAMEWORK_OVERRIDE="dev"
elif [[ $RELEASE_CHANNEL = "dev" ]]; then
WARP_BIN="dev"
WARP_BIN="galaxy-dev"
BUNDLE_ID="com.samsung.Galaxy-Dev"
WARP_APP_NAME="GalaxyDev"
WARP_APP_NAME="Galaxy Dev"
WARP_SCHEME_NAME="galaxydev"
FEATURES="$FEATURES,agent_mode_debug"
# Enable heap usage tracking & profiling using jemalloc through pprof.
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
# Enable the Warp Control CLI wrapper for local scripting/automation.
FEATURES="$FEATURES,warp_control_cli"
# For dev builds, use different versions of our bundled frameworks (e.g.:
# Sentry). This needs to be exported so it can be referenced by
# app/build.rs later, while running `cargo bundle`.
export FRAMEWORK_OVERRIDE="dev"
export HANDLE_MARKDOWN=1
elif [[ $RELEASE_CHANNEL = "preview" ]]; then
WARP_BIN="preview"
WARP_BIN="galaxy-preview"
BUNDLE_ID="com.samsung.Galaxy-Preview"
WARP_APP_NAME="GalaxyPreview"
WARP_APP_NAME="Galaxy Preview"
WARP_SCHEME_NAME="galaxypreview"
FEATURES="$FEATURES,preview_channel"
# Enable heap usage tracking & profiling using jemalloc through pprof.
@@ -309,7 +307,7 @@ elif [[ $RELEASE_CHANNEL = "stable" ]]; then
# Enable heap usage tracking & profiling using jemalloc through pprof.
FEATURES="$FEATURES,jemalloc_pprof,heap_usage_tracking"
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
WARP_BIN="galaxy-ai-oss"
WARP_BIN="galaxy-oss"
BUNDLE_ID="com.samsung.Galaxy"
WARP_APP_NAME="Galaxy"
WARP_SCHEME_NAME="galaxy"
@@ -349,13 +347,17 @@ else
fi
# Set artifact-specific configuration.
if [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
if [[ "$ARTIFACT" == cli ]]; then
UNIVERSAL_BINARY=false
OPEN_AFTER_BUNDLE=false
FEATURES="$FEATURES,standalone"
elif [[ "$ARTIFACT" == galaxyctrl ]]; then
UNIVERSAL_BINARY=false
OPEN_AFTER_BUNDLE=false
FEATURES="$FEATURES,standalone,galaxy_control_cli"
elif [[ "$ARTIFACT" == app ]]; then
# All channels ship the v3 classifier and v2 heuristic.
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2"
FEATURES="$FEATURES,gui,nld_classifier_v3,nld_heuristic_v2,galaxy_control_cli"
fi
# If we're building a universal bundle for the app artifact, make sure the additional target is available.
@@ -368,7 +370,7 @@ fi
# using the same feature flags and profile that we would be using in production.
if [[ "$CHECK_ONLY" == "true" ]]; then
cargo check --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --target "$DEFAULT_TARGET" --features "$FEATURES"
if [[ $UNIVERSAL_BINARY = true && "$ARTIFACT" != "cli" && "$ARTIFACT" != "warpctrl" ]]; then
if [[ $UNIVERSAL_BINARY = true && "$ARTIFACT" != "cli" && "$ARTIFACT" != "galaxyctrl" ]]; then
cargo check --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --target "$ADDITIONAL_TARGET" --features "$FEATURES"
fi
exit 0
@@ -453,7 +455,7 @@ if [[ "$ARTIFACT" == "app" ]]; then
</array>" "$BUNDLE_DIR"/$WARP_APP_NAME.app/Contents/Info.plist
fi
# Temporary key that ChatGPT Desktop can use to determine if the latest version of Warp supports the ChatGPT integration.
# Temporary key that ChatGPT Desktop can use to determine if the latest version of Galaxy supports the ChatGPT integration.
# Once support has been rolled out for a sufficient amount of time we (and ChatGPT) can remove this.
plutil -insert SUPPORTS_CHAT_GPT_WORK_WITH_APPS -bool true "$BUNDLE_DIR"/$WARP_APP_NAME.app/Contents/Info.plist
@@ -534,11 +536,11 @@ if [[ "$ARTIFACT" == "app" ]]; then
# Determine CLI wrapper script path based on release channel. Each channel's
# value here must match `Channel::cli_command_name` in the Rust source.
if [[ $RELEASE_CHANNEL = "stable" ]]; then
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/oz"
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai"
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/warp-oss"
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai-oss"
else
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/oz-$RELEASE_CHANNEL"
CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai-$RELEASE_CHANNEL"
fi
echo "Creating Resources/bin directory and CLI wrapper script..."
@@ -556,26 +558,26 @@ EOF
# Make the script executable
chmod +x "$CLI_SCRIPT_PATH"
if [[ ",$FEATURES," =~ ",warp_control_cli," ]]; then
# Each value must match `Channel::warpctrl_command_name` in the Rust source.
if [[ ",$FEATURES," =~ ",galaxy_control_cli," ]]; then
# Each value must match `Channel::galaxyctrl_command_name` in the Rust source.
if [[ $RELEASE_CHANNEL = "stable" ]]; then
WARPCTRL_COMMAND_NAME="warpctrl"
GALAXYCTRL_COMMAND_NAME="galaxyctrl"
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
WARPCTRL_COMMAND_NAME="warpctrl-oss"
GALAXYCTRL_COMMAND_NAME="galaxyctrl-oss"
else
WARPCTRL_COMMAND_NAME="warpctrl-$RELEASE_CHANNEL"
GALAXYCTRL_COMMAND_NAME="galaxyctrl-$RELEASE_CHANNEL"
fi
WARPCTRL_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/$WARPCTRL_COMMAND_NAME"
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH..."
"$WORKSPACE_ROOT_DIR/script/macos/create_warpctrl_wrapper" \
"$WARPCTRL_SCRIPT_PATH" \
GALAXYCTRL_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/$GALAXYCTRL_COMMAND_NAME"
echo "Creating galaxyctrl wrapper script at $GALAXYCTRL_SCRIPT_PATH..."
"$WORKSPACE_ROOT_DIR/script/macos/create_galaxyctrl_wrapper" \
"$GALAXYCTRL_SCRIPT_PATH" \
"../../MacOS/$WARP_BIN"
fi
# Store the built artifact locations for GitHub Actions outputs.
BINARY_PATH="target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN"
DMG_PATH="$OUT_DIR/$FINAL_DMG_NAME"
elif [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
elif [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "galaxyctrl" ]]; then
if [[ $BUILD_BINARY == true ]]; then
# Create Info.plist before building the app, since it's embedded at build time.
# Apple's codesigning tools will detect Info.plist files in the same directory as an executable.
@@ -602,15 +604,15 @@ elif [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
echo "Copying binary into $OUT_DIR/$WARP_BIN"
cp "target/$DEFAULT_TARGET/$TARGET_PROFILE_DIR/$WARP_BIN" "$OUT_DIR/$WARP_BIN"
if [[ "$ARTIFACT" == "warpctrl" ]]; then
if [[ ! ",$FEATURES," =~ ",warp_control_cli," ]]; then
echo "warpctrl artifact requires the warp_control_cli feature" >&2
if [[ "$ARTIFACT" == "galaxyctrl" ]]; then
if [[ ! ",$FEATURES," =~ ",galaxy_control_cli," ]]; then
echo "galaxyctrl artifact requires the galaxy_control_cli feature" >&2
exit 1
fi
WARPCTRL_SCRIPT_PATH="$OUT_DIR/warpctrl"
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH"
"$WORKSPACE_ROOT_DIR/script/macos/create_warpctrl_wrapper" \
"$WARPCTRL_SCRIPT_PATH" \
GALAXYCTRL_SCRIPT_PATH="$OUT_DIR/galaxyctrl"
echo "Creating galaxyctrl wrapper script at $GALAXYCTRL_SCRIPT_PATH"
"$WORKSPACE_ROOT_DIR/script/macos/create_galaxyctrl_wrapper" \
"$GALAXYCTRL_SCRIPT_PATH" \
"$WARP_BIN"
fi
@@ -625,8 +627,8 @@ elif [[ "$ARTIFACT" == "cli" || "$ARTIFACT" == "warpctrl" ]]; then
# Set the primary binary path to output.
if [[ "$ARTIFACT" == "warpctrl" ]]; then
BINARY_PATH="$OUT_DIR/warpctrl"
if [[ "$ARTIFACT" == "galaxyctrl" ]]; then
BINARY_PATH="$OUT_DIR/galaxyctrl"
else
BINARY_PATH="$OUT_DIR/$WARP_BIN"
fi
@@ -696,7 +698,7 @@ if [[ $SELFSIGN = true ]]; then
if [[ "$ARTIFACT" == app ]]; then
echo "Self-signing $BUNDLE_DIR/$WARP_APP_NAME.app with ${SIGNING_CERT}..."
codesign --force --deep --options runtime --sign "$SIGNING_CERT" "$BUNDLE_DIR/$WARP_APP_NAME.app" --entitlements script/Debug-Entitlements.plist
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == galaxyctrl ]]; then
echo "Self-signing $OUT_DIR/$WARP_BIN with ${SIGNING_CERT}..."
codesign --force --options runtime --sign "$SIGNING_CERT" "$OUT_DIR/$WARP_BIN" --entitlements script/Debug-Entitlements.plist
fi
@@ -705,7 +707,7 @@ elif [[ $CODESIGN = true ]]; then
echo "Codesigning $BUNDLE_DIR/$WARP_APP_NAME.app..."
# Use --deep so we sign bundled frameworks as well
codesign --deep -f -o runtime --timestamp -s "$APPLE_TEAM_ID" "$BUNDLE_DIR/$WARP_APP_NAME.app" --entitlements script/Entitlements.plist
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == warpctrl ]]; then
elif [[ "$ARTIFACT" == cli || "$ARTIFACT" == galaxyctrl ]]; then
echo "Codesigning $OUT_DIR/$WARP_BIN..."
codesign -f -o runtime --timestamp -s "$APPLE_TEAM_ID" "$OUT_DIR/$WARP_BIN" --entitlements script/Entitlements.plist
@@ -731,16 +733,16 @@ fi
########################
if [[ "$ARTIFACT" = app ]]; then
function create_warp_dmg() {
function create_galaxy_dmg() {
echo "Creating $DMG_DIR/$DMG_NAME..."
rm "$DMG_DIR/$DMG_NAME" || true
local source_folder="$1"
local args=(
--volname Warp
--volname Galaxy
# For --no-internet-enable, see https://github.com/create-dmg/create-dmg/issues/179
--no-internet-enable
--background app/assets/resources/mac/warp_install_image.png
--background app/assets/resources/mac/galaxy_install_image.png
--icon-size 128
--window-size 700 500
--format UDZO
@@ -776,7 +778,7 @@ if [[ "$ARTIFACT" = app ]]; then
mkdir -p "$DMG_DIR"
cp -R "$BUNDLE_DIR/$WARP_APP_NAME.app" "$DMG_DIR"
create_warp_dmg "$DMG_DIR"
create_galaxy_dmg "$DMG_DIR"
echo "Codesigning $DMG_DIR/$DMG_NAME..."
codesign -s "$APPLE_TEAM_ID" --timestamp "$DMG_DIR/$DMG_NAME"
@@ -790,7 +792,7 @@ if [[ "$ARTIFACT" = app ]]; then
echo "Cleaning up any existing DMG files before creating new ones..."
cleanup_dmg_files "$DMG_DIR"
create_warp_dmg "$BUNDLE_DIR"
create_galaxy_dmg "$BUNDLE_DIR"
fi
fi
@@ -816,7 +818,7 @@ if [[ $CODESIGN = true ]]; then
echo "Verifying notarization ticket..."
if [[ "$ARTIFACT" = app ]]; then
xcrun stapler validate "$DMG_DIR/$DMG_NAME"
elif [[ "$ARTIFACT" = cli || "$ARTIFACT" = warpctrl ]]; then
elif [[ "$ARTIFACT" = cli || "$ARTIFACT" = galaxyctrl ]]; then
spctl -a -t open --context context:primary-signature -vv "$OUT_DIR/$WARP_BIN"
fi
fi
@@ -14,7 +14,7 @@ mkdir -p "$(dirname "$WRAPPER_PATH")"
cat > "$WRAPPER_PATH" << EOF
#!/bin/bash
# This wrapper may be installed through a symlink in /usr/local/bin. Resolve
# symlinks before locating the Warp executable relative to the bundled wrapper.
# symlinks before locating the Galaxy executable relative to the bundled wrapper.
wrapper_path="\${BASH_SOURCE[0]}"
while [[ -L "\$wrapper_path" ]]; do
wrapper_dir="\$(cd -P "\$(dirname "\$wrapper_path")" && pwd)"
@@ -25,9 +25,9 @@ while [[ -L "\$wrapper_path" ]]; do
done
script_dir="\$(cd -P "\$(dirname "\$wrapper_path")" && pwd)"
# Warp Control has a separate argument parser from the normal Warp/Oz parser.
# Galaxy Control has a separate argument parser from the normal Galaxy parser.
# The hidden flag selects it before normal CLI parsing or GUI startup.
# Replace the wrapper process while preserving its invocation name as argv[0].
exec -a "\$0" "\$script_dir/$BINARY_RELATIVE_PATH" --warpctrl "\$@"
exec -a "\$0" "\$script_dir/$BINARY_RELATIVE_PATH" --galaxyctrl "\$@"
EOF
chmod +x "$WRAPPER_PATH"
+12 -12
View File
@@ -1,16 +1,16 @@
#!/bin/bash
#
# macOS-specific implementation of `./script/run`. Runs a local version of
# Warp as a real 'app' instead of a bare executable, so macOS can treat it
# Galaxy as a real 'app' instead of a bare executable, so macOS can treat it
# like a real signed app (custom URL schemes, user notifications, etc.).
#
# This script is invoked by `./script/run`, which handles cross-platform
# setup (install_channel_config, binary name detection, feature-to-env-var
# mapping). The following env vars are expected to be set by the caller:
# WARP_BIN_NAME — "warp" (internal local build) or "warp-oss"
# WARP_BIN_NAME — "galaxy-local" or "galaxy-oss"
# WARP_CHANNEL — "local" or "oss"
# FEATURES — comma-separated cargo features (already normalized)
# Must be called from the root directory of the warp repo.
# Must be called from the root directory of the Galaxy repository.
set -e
@@ -37,14 +37,14 @@ else
WARP_SCHEME_NAME="galaxyoss"
fi
DONT_OPEN=false
# Launches the binary with "open", meaning the Warp process is
# Launches the binary with "open", meaning the Galaxy process is
# launched by the MacOS application launcher instead of a shell session.
# Note that since Warp isn't launched as a child process, using ctrl+c
# Note that since Galaxy isn't launched as a child process, using ctrl+c
# won't kill the app (but will kill the tail process displaying output).
# tl;dr better simulates running Warp Dev/Stable
# tl;dr better simulates running Galaxy Local/OSS
OPEN_WITH_LAUNCHD=false
# Arguments to pass directly Warp (specified after --)
# Arguments to pass directly to Galaxy (specified after --)
# This is not supported when opening with launchd, as passing CLI arguments to
# an application doesn't make sense.
WARP_ARGS=()
@@ -135,11 +135,11 @@ if [[ ",$FEATURES," =~ ",heap_usage_tracking," ]]; then
"${REPO_ROOT}/script/prepare_bundled_pprof" "$HELPERS_DIR"
fi
if [[ ",$FEATURES," =~ ",warp_control_cli," ]]; then
WARPCTRL_SCRIPT_PATH="$WARP_APP_PATH/Contents/Resources/bin/warpctrl-$WARP_CHANNEL"
echo "Creating warpctrl wrapper script at $WARPCTRL_SCRIPT_PATH..."
"${REPO_ROOT}/script/macos/create_warpctrl_wrapper" \
"$WARPCTRL_SCRIPT_PATH" \
if [[ ",$FEATURES," =~ ",galaxy_control_cli," ]]; then
GALAXYCTRL_SCRIPT_PATH="$WARP_APP_PATH/Contents/Resources/bin/galaxyctrl-$WARP_CHANNEL"
echo "Creating galaxyctrl wrapper script at $GALAXYCTRL_SCRIPT_PATH..."
"${REPO_ROOT}/script/macos/create_galaxyctrl_wrapper" \
"$GALAXYCTRL_SCRIPT_PATH" \
"../../MacOS/$WARP_BIN_NAME"
fi
@@ -6,10 +6,10 @@ workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
temp_dir="$(mktemp -d)"
trap 'rm -rf "$temp_dir"' EXIT
bundle_dir="$temp_dir/WarpDev.app/Contents"
wrapper_path="$bundle_dir/Resources/bin/warpctrl-dev"
binary_path="$bundle_dir/MacOS/dev"
installed_path="$temp_dir/usr/local/bin/warpctrl-dev"
bundle_dir="$temp_dir/GalaxyDev.app/Contents"
wrapper_path="$bundle_dir/Resources/bin/galaxyctrl-dev"
binary_path="$bundle_dir/MacOS/galaxy-dev"
installed_path="$temp_dir/usr/local/bin/galaxyctrl-dev"
forwarded_args_file="$temp_dir/forwarded-args"
expected_args_file="$temp_dir/expected-args"
@@ -20,12 +20,12 @@ printf '%s\n' "$@" > "$FORWARDED_ARGS_FILE"
EOF
chmod +x "$binary_path"
"$workspace_root/script/macos/create_warpctrl_wrapper" \
"$workspace_root/script/macos/create_galaxyctrl_wrapper" \
"$wrapper_path" \
"../../MacOS/dev"
"../../MacOS/galaxy-dev"
cat > "$expected_args_file" << 'EOF'
--warpctrl
--galaxyctrl
tab
create
--instance
+3 -3
View File
@@ -1,8 +1,8 @@
#!/bin/bash
#
# Cross-platform entrypoint for running a local Warp build.
# Cross-platform entrypoint for running a local Galaxy build.
#
# On macOS this delegates to `./script/macos/run`, which builds and runs Warp
# On macOS this delegates to `./script/macos/run`, which builds and runs Galaxy
# as a real `.app` bundle (with code signing, plist updates, etc.). On Linux
# and Windows it invokes `cargo run` directly for the appropriate binary.
#
@@ -18,7 +18,7 @@ cd "${REPO_ROOT}"
OS_TYPE="$(uname -s)"
FEATURES="gui"
FEATURES="gui,galaxy_control_cli"
INSTALL_COMMON_SKILLS=1
FORCE_COMMON_SKILLS=0
COMMON_SKILLS_TARGET="${WARP_COMMON_SKILLS_INSTALL_TARGET:-}"
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env bash
set -e
workspace_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
temp_dir="$(mktemp -d)"
trap 'rm -rf "$temp_dir"' EXIT
mkdir -p "$temp_dir/bin"
cat > "$temp_dir/bin/cargo" <<'EOF'
#!/usr/bin/env bash
printf '%s\n' "$@" > "$CARGO_ARGS_FILE"
EOF
chmod +x "$temp_dir/bin/cargo"
assert_cargo_target() {
local args_file="$1"
local expected_bin="$2"
grep -qx -- 'galaxy' "$args_file"
grep -qx -- '--bin' "$args_file"
grep -qx -- "$expected_bin" "$args_file"
if grep -Eqx -- 'warp|warp-oss|dev|preview' "$args_file"; then
echo "Found a removed Cargo package or binary target in $args_file" >&2
exit 1
fi
}
for channel_and_bin in \
"local galaxy-local" \
"dev galaxy-dev" \
"preview galaxy-preview" \
"stable stable" \
"oss galaxy-oss"
do
channel="${channel_and_bin%% *}"
expected_bin="${channel_and_bin#* }"
linux_args="$temp_dir/linux-$channel.args"
PATH="$temp_dir/bin:$PATH" \
CARGO_ARGS_FILE="$linux_args" \
CARGO_TARGET_DIR="$temp_dir/target" \
"$workspace_root/script/linux/bundle" \
--check-only \
--channel "$channel" \
--packages none
assert_cargo_target "$linux_args" "$expected_bin"
wasm_args="$temp_dir/wasm-$channel.args"
PATH="$temp_dir/bin:$PATH" \
CARGO_ARGS_FILE="$wasm_args" \
"$workspace_root/script/wasm/bundle" \
--check-only \
--channel "$channel"
assert_cargo_target "$wasm_args" "$expected_bin"
done
macos_bundle="$workspace_root/script/macos/bundle"
grep -Fq -- 'CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai"' "$macos_bundle"
grep -Fq -- 'CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai-oss"' "$macos_bundle"
grep -Fq -- 'CLI_SCRIPT_PATH="$BUNDLED_RESOURCES_DIR/bin/galaxy-ai-$RELEASE_CHANNEL"' "$macos_bundle"
if grep -Eq -- 'CLI_SCRIPT_PATH=.*(warp|oz)' "$macos_bundle"; then
echo "Found a removed Warp/Oz CLI launcher in $macos_bundle" >&2
exit 1
fi
windows_bundle="$workspace_root/script/windows/bundle.ps1"
for expected_bin in galaxy-local galaxy-dev galaxy-preview stable galaxy-oss; do
grep -Fq -- "\$GALAXY_BIN = '$expected_bin'" "$windows_bundle"
done
grep -Fq -- 'cargo check -p galaxy' "$windows_bundle"
grep -Fq -- 'cargo build -p galaxy' "$windows_bundle"
if grep -Eq -- "cargo (check|build) -p warp|\\\$GALAXY_BIN = '(warp|warp-oss|dev|preview)'" "$windows_bundle"; then
echo "Found a removed Cargo package or binary target in $windows_bundle" >&2
exit 1
fi
windows_installer="$workspace_root/script/windows/windows-installer.iss"
grep -Fq -- "AppId=galaxy-terminal-{#ReleaseChannel}" "$windows_installer"
grep -Fq -- "CmdScriptName := 'galaxy-ai.cmd'" "$windows_installer"
grep -Fq -- "CmdScriptName := 'galaxy-ai-{#ReleaseChannel}.cmd'" "$windows_installer"
grep -Fq -- 'set "GALAXY_CLI_MODE=1"' "$windows_installer"
grep -Fq -- 'WizardSmallImageFile="installer-images\galaxy-logo.bmp"' "$windows_installer"
grep -Fq -- 'WizardImageFile="installer-images\galaxy-banner.bmp"' "$windows_installer"
if grep -Eq -- "CmdScriptName := '(warp|oz)|AppId=warp-terminal|SOFTWARE\\\\Warp|dev\\.warp|installer-images\\\\warp" "$windows_installer"; then
echo "Found removed Warp/Oz installer branding in $windows_installer" >&2
exit 1
fi
@@ -6,6 +6,7 @@ discovery_dir="$(mktemp -d)"
trap 'rm -rf "$discovery_dir"' EXIT
python3 - "$workspace_root" "$discovery_dir" <<'PY'
import json
import os
import pathlib
import subprocess
@@ -14,19 +15,19 @@ import sys
workspace_root = pathlib.Path(sys.argv[1])
discovery_dir = sys.argv[2]
environment = os.environ.copy()
environment["WARP_LOCAL_CONTROL_DISCOVERY_DIR"] = discovery_dir
environment["GALAXY_LOCAL_CONTROL_DISCOVERY_DIR"] = discovery_dir
result = subprocess.run(
[
"cargo",
"run",
"-p",
"warp",
"galaxy",
"--bin",
"warp",
"galaxy-oss",
"--features",
"warp_control_cli",
"galaxy_control_cli",
"--",
"--warpctrl",
"--galaxyctrl",
"--output-format",
"json",
"instance",
@@ -36,14 +37,20 @@ result = subprocess.run(
env=environment,
capture_output=True,
text=True,
timeout=180,
timeout=600,
)
if result.returncode != 0:
sys.stderr.write(result.stderr)
sys.stderr.write(result.stdout)
raise SystemExit(result.returncode)
if result.stdout.strip() != "[]":
try:
output = json.loads(result.stdout)
except json.JSONDecodeError as error:
sys.stderr.write(result.stderr)
sys.stderr.write(f"unexpected warpctrl output: {result.stdout!r}\n")
sys.stderr.write(f"invalid galaxyctrl JSON output: {error}: {result.stdout!r}\n")
raise SystemExit(1)
if output != {"instances": []}:
sys.stderr.write(result.stderr)
sys.stderr.write(f"unexpected galaxyctrl output: {output!r}\n")
raise SystemExit(1)
PY
+15 -17
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Builds a Warp binary and bundles it up for distribution.
# Builds a Galaxy binary and bundles it up for distribution.
set -e
@@ -20,8 +20,6 @@ CARGO_TARGET_DIR="$WORKSPACE_ROOT_DIR/target/wasm32-unknown-unknown"
# By default we build dev bundles.
RELEASE_CHANNEL="dev"
# TODO: We should enable crash_reporting and before enabling for trusted testers.
# https://linear.app/warpdotdev/issue/PLAT-428/crash-reporting-on-web
FEATURES="release_bundle,gui"
DEBUG=false
@@ -114,20 +112,20 @@ mkdir -p "$EXTRAS_DIR"
# Update parameters based on the target release channel.
#
# WARP_BIN is the name of the binary produced by cargo.
# N.B. The bundled outputs will always be warp.js and warp_bg.wasm.
# GALAXY_BIN is the name of the binary produced by cargo.
# N.B. The bundled outputs will always be galaxy.js and galaxy_bg.wasm.
if [[ $RELEASE_CHANNEL = "local" ]]; then
WARP_BIN="warp"
GALAXY_BIN="galaxy-local"
FEATURES="$FEATURES,remote_tty"
elif [[ $RELEASE_CHANNEL = "dev" ]]; then
WARP_BIN="dev"
GALAXY_BIN="galaxy-dev"
elif [[ $RELEASE_CHANNEL = "preview" ]]; then
WARP_BIN="preview"
GALAXY_BIN="galaxy-preview"
FEATURES="$FEATURES,preview_channel"
elif [[ $RELEASE_CHANNEL = "stable" ]]; then
WARP_BIN="stable"
GALAXY_BIN="stable"
elif [[ $RELEASE_CHANNEL = "oss" ]]; then
WARP_BIN="warp-oss"
GALAXY_BIN="galaxy-oss"
fi
if [ -n "${FEATURES_OVERRIDE+x}" ]; then
@@ -138,20 +136,20 @@ fi
# then exit. We use this script to invoke `cargo check` to ensure that we are
# using the same feature flags and profile that we would be using in production.
if [[ "$CHECK_ONLY" == "true" ]]; then
ASSET_TARGET_DIR="$ASSET_TARGET_DIR" cargo check --target wasm32-unknown-unknown --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES"
ASSET_TARGET_DIR="$ASSET_TARGET_DIR" cargo check --package galaxy --target wasm32-unknown-unknown --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES"
exit 0
fi
# Build the wasm binary.
echo "Building and bundling Warp for channel $RELEASE_CHANNEL"
ASSET_TARGET_DIR="$ASSET_TARGET_DIR" cargo build --target wasm32-unknown-unknown --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES"
echo "Building and bundling Galaxy for channel $RELEASE_CHANNEL"
ASSET_TARGET_DIR="$ASSET_TARGET_DIR" cargo build --package galaxy --target wasm32-unknown-unknown --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES"
# Generate linked JS and wasm files that can be run in the browser.
echo "Running wasm-bindgen on $CARGO_TARGET_OUTPUT_DIR/$WARP_BIN.wasm"
wasm-bindgen --target web --out-dir "$OUT_DIR" --out-name "warp" --keep-debug --no-typescript "$CARGO_TARGET_OUTPUT_DIR/$WARP_BIN.wasm"
echo "Running wasm-bindgen on $CARGO_TARGET_OUTPUT_DIR/$GALAXY_BIN.wasm"
wasm-bindgen --target web --out-dir "$OUT_DIR" --out-name "galaxy" --keep-debug --no-typescript "$CARGO_TARGET_OUTPUT_DIR/$GALAXY_BIN.wasm"
WASM_BINARY_OUT="${OUT_DIR}/warp_bg.wasm"
WASM_BINARY_DEBUG="${EXTRAS_DIR}/warp_bg.debug.wasm"
WASM_BINARY_OUT="${OUT_DIR}/galaxy_bg.wasm"
WASM_BINARY_DEBUG="${EXTRAS_DIR}/galaxy_bg.debug.wasm"
if [[ "$NO_SPLIT" != "true" ]]; then
# Run Sentry's wasm-split binary to separate out debug information from the
+2 -2
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>warp</title>
<title>Galaxy</title>
<style type="text/css">
body {
margin: 0px;
@@ -22,7 +22,7 @@
<body>
<script type="module">
import init from "/assets/client/wasm/warp.js";
import init from "/assets/client/wasm/galaxy.js";
window.addEventListener("load", () => {
init();
});
+2 -2
View File
@@ -7,12 +7,12 @@ cd "${REPO_ROOT}"
WASM_BINDGEN_VERSION="$(cargo metadata --format-version 1 | jq -rc '.packages[] | select(.name == "wasm-bindgen") | .version')"
cargo install wasm-bindgen-cli --version "$WASM_BINDGEN_VERSION"
# We source the bundle script so we can access it's calculated $OUT_DIR.
# We source the bundle script so we can access its calculated $OUT_DIR.
source ./script/wasm/bundle --debug --no-split --channel local "$@"
BUNDLE_DIR="$(dirname "$OUT_DIR")"
cp "$WORKSPACE_ROOT_DIR/script/wasm/dev-index.html" "$BUNDLE_DIR/index.html"
echo "Built Warp to $BUNDLE_DIR"
echo "Built Galaxy to $BUNDLE_DIR"
cargo run --release --package serve-wasm -- "$BUNDLE_DIR"
+4 -4
View File
@@ -12,7 +12,7 @@ The installer is a single executable that takes care of:
`windows-installer.iss` is an **Inno Setup script**:
a configuration file for building a Warp installer.
a configuration file for building a Galaxy installer.
The Inno Setup Compiler takes a script file and generates an installer executable.
This is roughly equivalent to the bundling process on MacOS.
@@ -28,7 +28,7 @@ However, it requires the Inno Setup compiler to be turned into a `.exe` file.
First, ensure you've set up your environment.
* Download and install the [Inno Setup Compiler](https://jrsoftware.org/isdl.php).
* Run `cargo build` to ensure the installer uses the latest version of Warp.
* Run `cargo build` to ensure the installer uses the latest version of Galaxy.
### Option 1: Use the CLI
1. Add the Inno Setup Command-line Compiler executable to your shell path.
@@ -39,7 +39,7 @@ iscc .\script\windows\windows-installer.iss
```
3. Run the generated executable:
```shell
.\script\windows\Output\Warp-Windows-Setup.exe
.\script\windows\Output\GalaxySetup.exe
```
The script begins with a series of preprocessor definitions.
@@ -49,7 +49,7 @@ Usage: `iscc <script path> /D<name>[=<value>]`
The following constants can be overwritten:
* `MyAppVersion` (default: `0.1.0`)
* `MyAppExeName` (default: `warp.exe`)
* `MyAppExeName` (default: `galaxy-dev.exe`)
* `ReleaseChannel` (default: `dev`)
* `TargetProfileDir` (default: `debug`)
+27 -31
View File
@@ -14,11 +14,11 @@ Param (
[Alias('release-tag')]
[String]$RELEASE_TAG = '',
[String]$FEATURES = 'release_bundle,crash_reporting,gui',
[String]$FEATURES = 'release_bundle,gui',
# Builds only the Warp binary, skips the installer.
# Builds only the Galaxy binary, skips the installer.
[Switch]$SKIP_BUILD_INSTALLER = $False,
# Builds only the installer, skips the Warp binary. Use this if the Warp
# Builds only the installer, skips the Galaxy binary. Use this if the Galaxy
# binary has already been built.
[Switch]$SKIP_BUILD_BINARY = $False,
@@ -52,7 +52,7 @@ if ($ARCH -eq 'arm64') {
$FILE_ENDING = 'Setup-arm64'
$PLATFORM_TARGET = 'aarch64-pc-windows-msvc'
} else {
# If x64, then we just use the filename "WarpSetup.exe" for example
# If x64, then we just use the filename "GalaxySetup.exe" for example
$FILE_ENDING = 'Setup'
$PLATFORM_TARGET = 'x86_64-pc-windows-msvc'
}
@@ -79,39 +79,35 @@ if ($CARGO_PROFILE -eq 'dev') {
} else {
$CARGO_TARGET_OUTPUT_DIR = "$CARGO_TARGET_DIR" + '\' + $PLATFORM_TARGET + '\' + "$CARGO_PROFILE"
}
$BUNDLE_ID = "dev.warp.$app_name"
# Update parameters based on the target release channel.
#
# APP_NAME here must match the value used in Rust as the
# application name; see app/src/channel.rs.
#
# WARP_BIN is the name of the binary produced by cargo;
# GALAXY_BIN is the name of the binary produced by cargo;
# BINARY_NAME is the desired name of the binary in the final package.
if ("$CHANNEL" -eq 'local') {
$WARP_BIN = 'warp'
$BINARY_NAME = 'warp.exe'
$GALAXY_BIN = 'galaxy-local'
$BINARY_NAME = 'galaxy-local.exe'
$APP_NAME = 'GalaxyLocal'
} elseif ("$CHANNEL" -eq 'dev') {
$WARP_BIN = 'dev'
$BINARY_NAME = 'dev.exe'
$GALAXY_BIN = 'galaxy-dev'
$BINARY_NAME = 'galaxy-dev.exe'
$APP_NAME = 'GalaxyDev'
$FEATURES = "$FEATURES,agent_mode_debug"
} elseif ("$CHANNEL" -eq 'preview') {
$WARP_BIN = 'preview'
$BINARY_NAME = 'preview.exe'
$GALAXY_BIN = 'galaxy-preview'
$BINARY_NAME = 'galaxy-preview.exe'
$APP_NAME = 'GalaxyPreview'
$FEATURES = "$FEATURES,preview_channel"
} elseif ("$CHANNEL" -eq 'stable') {
$WARP_BIN = 'stable'
$BINARY_NAME = 'warp.exe'
$GALAXY_BIN = 'stable'
$BINARY_NAME = 'galaxy.exe'
$APP_NAME = 'Galaxy'
} elseif ("$CHANNEL" -eq 'oss') {
$WARP_BIN = 'warp-oss'
$BINARY_NAME = 'warp-oss.exe'
$GALAXY_BIN = 'galaxy-oss'
$BINARY_NAME = 'galaxy-oss.exe'
$APP_NAME = 'GalaxyOss'
# The OSS channel does not ship Sentry, so drop the crash_reporting feature
# (which would otherwise pull in the Sentry SDK as a dependency).
$FEATURES = 'release_bundle,gui'
}
@@ -119,11 +115,11 @@ if ("$CHANNEL" -eq 'local') {
$FEATURES = "$FEATURES,nld_classifier_v3,nld_heuristic_v2"
$BINARY_PATH = "$CARGO_TARGET_OUTPUT_DIR\$BINARY_NAME"
$BUNDLE_ID = "dev.warp.$APP_NAME"
$BUNDLE_ID = "samsung.galaxy.$APP_NAME"
$INSTALLER_OUTPUT_DIR = "$WINDOWS_INSTALLER_DIR\Output"
$INSTALLER_NAME = "$($APP_NAME)$($FILE_ENDING)"
$INSTALLER_PATH = "$($INSTALLER_OUTPUT_DIR)\$($INSTALLER_NAME).exe"
$PDB_PATH = "$CARGO_TARGET_OUTPUT_DIR\$WARP_BIN.pdb"
$PDB_PATH = "$CARGO_TARGET_OUTPUT_DIR\$GALAXY_BIN.pdb"
# The CARGO_FULL_PROFILE environment variable is read by the `cargo` build
# script (`app/build.rs`) to determine where to place `conpty.dll`.
@@ -137,28 +133,28 @@ if ($DEBUG_BUILD) {
# then exit. We use this script to invoke `cargo check` to ensure that we are
# using the same feature flags and profile that we would be using in production.
if ($CHECK_ONLY) {
cargo check -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
cargo check -p galaxy --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
if (-Not $?) {
Write-Error "Failed to verify Warp $WARP_BIN compilation with profile $CARGO_PROFILE"
Write-Error "Failed to verify Galaxy $GALAXY_BIN compilation with profile $CARGO_PROFILE"
exit 1
}
exit 0
}
if (-Not $SKIP_BUILD_BINARY) {
Write-Output "Building Warp for channel $CHANNEL and bundle id $BUNDLE_ID"
Write-Output "Building Galaxy for channel $CHANNEL and bundle id $BUNDLE_ID"
$env:CARGO_BIN_NAME = $CHANNEL
$env:WARP_APP_NAME = $APP_NAME
cargo build -p warp --profile "$CARGO_PROFILE" --bin "$WARP_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
$env:GALAXY_APP_NAME = $APP_NAME
cargo build -p galaxy --profile "$CARGO_PROFILE" --bin "$GALAXY_BIN" --features "$FEATURES" --target $PLATFORM_TARGET
if (-Not $?) {
Write-Error "Failed to build Warp $WARP_BIN binary with profile $CARGO_PROFILE"
Write-Error "Failed to build Galaxy $GALAXY_BIN binary with profile $CARGO_PROFILE"
exit 1
}
# If we desire an executable name different from the cargo bin, rename it.
if ("$WARP_BIN.exe" -ne $BINARY_NAME) {
$binarySource = "$CARGO_TARGET_OUTPUT_DIR\$WARP_BIN.exe"
Write-Output "Renaming executable $WARP_BIN.exe to $BINARY_NAME"
if ("$GALAXY_BIN.exe" -ne $BINARY_NAME) {
$binarySource = "$CARGO_TARGET_OUTPUT_DIR\$GALAXY_BIN.exe"
Write-Output "Renaming executable $GALAXY_BIN.exe to $BINARY_NAME"
Move-Item -Path "$binarySource" -Destination "$BINARY_PATH" -Force
}
}
@@ -186,7 +182,7 @@ if (-Not $?) {
exit 1
}
Write-Output 'Building Warp installer'
Write-Output 'Building Galaxy installer'
$ISCC_ARGS = @(
"$WINDOWS_INSTALLER_DIR\windows-installer.iss",
"/DReleaseChannel=$CHANNEL",
Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

+38 -45
View File
@@ -2,8 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#include "environment.iss"
#define MyAppPublisher "Denver Technologies, Inc."
#define MyAppURL "https://www.warp.dev/"
#define MyAppPublisher "Galaxy"
#ifndef MyAppName
#define MyAppName "GalaxyDev"
#endif
@@ -11,7 +10,7 @@
#define MyAppVersion "0.1.0"
#endif
#ifndef MyAppExeName
#define MyAppExeName "dev.exe"
#define MyAppExeName "galaxy-dev.exe"
#endif
#ifndef ReleaseChannel
#define ReleaseChannel "dev"
@@ -30,21 +29,18 @@
((ReleaseChannel == "integration") ? "Integration" : \
((ReleaseChannel == "oss") ? "Oss" : \
"Unknown")))))
#define AppMutexName "Local\Warp" + ChannelPascalCase + "_SingleInstance"
#define AppMutexName "Local\Galaxy" + ChannelPascalCase + "_SingleInstance"
[Setup]
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId=warp-terminal-{#ReleaseChannel}
AppId=galaxy-terminal-{#ReleaseChannel}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppVerName={#MyAppName} {#MyAppVersion}
UninstallDisplayName={#MyAppName}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={autopf}\{#MyAppName}
ArchitecturesAllowed={#Arch}
ArchitecturesInstallIn64BitMode={#Arch}
@@ -57,18 +53,18 @@ OutputBaseFilename={#OutputName}
Compression=lzma
SolidCompression=yes
WizardStyle=modern
WizardSmallImageFile="installer-images\warp-logo.bmp"
WizardImageFile="installer-images\warp-banner.bmp"
WizardSmallImageFile="installer-images\galaxy-logo.bmp"
WizardImageFile="installer-images\galaxy-banner.bmp"
SetupIconFile="..\..\app\channels\{#ReleaseChannel}\icon\no-padding\icon.ico"
UninstallDisplayIcon="{app}\icon.ico"
; Force close previous Warp if it hasn't shut down yet.
; Force close previous Galaxy if it hasn't shut down yet.
; In the update flow we already warn the user if they have something running and make them confirm
; before running this installer. Therefore, we are good to force close Warp without fear of losing
; before running this installer. Therefore, we are good to force close Galaxy without fear of losing
; unsaved work.
; VSCode does something similar:
; https://github.com/microsoft/vscode/blob/aac9914f93551f894b8df1e4680bd847e7636be3/build/win32/code.iss#L41
CloseApplications=force
; For manual installs: if Warp is running, show a dialog prompting the user to close it
; For manual installs: if Galaxy is running, show a dialog prompting the user to close it
; before Setup proceeds. Returned empty for background updates so the check is skipped.
AppMutex={code:GetAppMutex}
SetupMutex={#AppMutexName}Setup
@@ -108,25 +104,25 @@ Source: "{#AssetsDir}\{#Arch}\dxil.dll"; DestDir: "{app}"
Source: "{#TargetProfileDir}\resources\*"; DestDir: "{app}\resources"; Flags: ignoreversion recursesubdirs
[Registry]
Root: HKCU; Subkey: "SOFTWARE\Warp.dev\{#MyAppName}"; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Warp.dev\{#MyAppName}"; ValueType: string; ValueName: "InstallationPath"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletevalue
Root: HKCU; Subkey: "SOFTWARE\Galaxy\{#MyAppName}"; Flags: uninsdeletekey
Root: HKCU; Subkey: "SOFTWARE\Galaxy\{#MyAppName}"; ValueType: string; ValueName: "InstallationPath"; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletevalue
Root: HKA; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\{#MyAppExeName}"; ValueType: string; ValueName: ""; ValueData: "{app}\{#MyAppExeName}"; Flags: uninsdeletekey
; cleanup "Open Warp Here" registry entries
; Clean up obsolete context-menu entries for this Galaxy channel.
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}"; Flags: deletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}"; Flags: deletekey
; Add "Open Warp in new tab" to directory context menu
; Add "Open Galaxy in new tab" to directory context menu
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new tab"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Tab\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_tab?path=%1"""
; Add "Open Warp in new tab" to directory background context menu
; Add "Open Galaxy in new tab" to directory background context menu
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new tab"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Tab\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_tab?path=%V"""
; Add "Open Warp in new window" to directory context menu
; Add "Open Galaxy in new window" to directory context menu
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new window"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\shell\{#MyAppName}Window\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_window?path=%1"""
; Add "Open Warp in new window" to directory background context menu
; Add "Open Galaxy in new window" to directory background context menu
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window"; ValueType: string; ValueName: ""; ValueData: "Open {#MyAppName} in new window"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window"; ValueType: string; ValueName: "Icon"; ValueData: "{app}\icon.ico"
Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Window\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#MyAppExeName}"" ""{#MyAppName}://action/new_window?path=%V"""
@@ -135,13 +131,13 @@ Root: HKA; Subkey: "Software\Classes\Directory\Background\shell\{#MyAppName}Wind
Name: addToPath; Description: "Add Galaxy to PATH"
[UninstallDelete]
Type: filesandordirs; Name: "{userappdata}\warp\{#MyAppName}"
Type: filesandordirs; Name: "{localappdata}\warp\{#MyAppName}"
Type: filesandordirs; Name: "{userappdata}\galaxy\{#MyAppName}"
Type: filesandordirs; Name: "{localappdata}\galaxy\{#MyAppName}"
Type: filesandordirs; Name: "{app}\bin"
[Icons]
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "dev.warp.{#MyAppName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "dev.warp.{#MyAppName}"; Tasks: desktopicon
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "samsung.galaxy.{#MyAppName}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; IconFilename: "{app}\icon.ico"; AppUserModelID: "samsung.galaxy.{#MyAppName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: postinstall runhidden nowait
@@ -156,10 +152,10 @@ begin
#endif
end;
{ Returns true when the installer was launched by Warp's auto-update code.
{ Returns true when the installer was launched by Galaxy's auto-update code.
The auto-update path passes /update=1 on the command line and /NOCLOSEAPPLICATIONS
so that the installer does not forcibly kill the running Warp process. Instead we
wait for Warp to exit naturally by polling the app mutex below. }
so that the installer does not forcibly kill the running Galaxy process. Instead we
wait for Galaxy to exit naturally by polling the app mutex below. }
function IsBackgroundUpdate(): Boolean;
begin
Result := ExpandConstant('{param:update|false}') <> 'false';
@@ -167,7 +163,7 @@ end;
{ For background updates, return an empty mutex name so that Inno Setup skips its
built-in "application is running" dialog - we handle the wait ourselves. For manual
installs, return the real mutex name so the user is prompted to close Warp first. }
installs, return the real mutex name so the user is prompted to close Galaxy first. }
function GetAppMutex(Value: string): string;
begin
if IsBackgroundUpdate() then
@@ -185,15 +181,15 @@ var
WaitCounter: Integer;
ResultCode: Integer;
begin
{ Background update: the installer was launched while Warp was still running.
{ Background update: the installer was launched while Galaxy was still running.
We passed /NOCLOSEAPPLICATIONS so Inno won't kill it. Wait here - before any
files are touched - for Warp to release its single-instance mutex, which
files are touched - for Galaxy to release its single-instance mutex, which
happens as part of normal process exit. }
if CurStep = ssInstall then
begin
if IsBackgroundUpdate() then
begin
Log('Background update: waiting for Warp to exit (mutex: {#AppMutexName})...');
Log('Background update: waiting for Galaxy to exit (mutex: {#AppMutexName})...');
WaitCounter := 0;
while CheckForMutexes('{#AppMutexName}') and (WaitCounter < 30) do
begin
@@ -202,12 +198,12 @@ begin
end;
if CheckForMutexes('{#AppMutexName}') then
begin
Log('Warp mutex still held after timeout; force-killing remaining processes.');
{ Kill by image name. {#MyAppExeName} (e.g. warp.exe, dev.exe) is unique
Log('Galaxy mutex still held after timeout; force-killing remaining processes.');
{ Kill by image name. {#MyAppExeName} (e.g. galaxy.exe, galaxy-dev.exe) is unique
enough that collateral damage is not a concern. OpenConsole.exe is NOT
killed by name because it is shared with Windows Terminal; instead we
rely on Warp's Job Object (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) to
cascade-kill any child OpenConsole.exe processes when warp.exe dies. }
rely on Galaxy's Job Object (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE) to
cascade-kill any child OpenConsole.exe processes when Galaxy exits. }
Exec('taskkill.exe', '/f /im {#MyAppExeName}', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
if ResultCode <> 0 then
Log('force-kill failed for {#MyAppExeName} (exit code: ' + IntToStr(ResultCode) + ')');
@@ -215,9 +211,9 @@ begin
end
else
begin
Log('Warp has exited; proceeding with file installation.');
Log('Galaxy has exited; proceeding with file installation.');
{ The minidump crash-reporter is a child process (same exe name) that
may outlive the main Warp process. It holds the executable file open,
may outlive the main Galaxy process. It holds the executable file open,
which causes the file-copy step to fail with "Access is denied".
We identify it by the "minidump-server" argument in its command line. }
Exec('powershell.exe',
@@ -230,10 +226,9 @@ begin
end;
end;
{ After a successful install, write a helper script for running the Warp CLI. }
{ We use this to add a "warp-" prefix (e.g. "warp-preview.cmd" vs. "preview.exe") }
{ After a successful install, write a channel-specific Galaxy AI helper script. }
if CurStep = ssPostInstall then begin
{ Add Warp to PATH if requested }
{ Add Galaxy to PATH if requested }
if IsTaskSelected('addToPath') then
EnvAddPath(ExpandConstant('{app}\bin'));
@@ -244,17 +239,15 @@ begin
{ Determine the channel-specific script name. These values must match
`Channel::cli_command_name` in the Rust source. }
#if ReleaseChannel == "stable"
CmdScriptName := 'oz.cmd'
#elif ReleaseChannel == "oss"
CmdScriptName := 'warp-oss.cmd';
CmdScriptName := 'galaxy-ai.cmd';
#else
CmdScriptName := 'oz-{#ReleaseChannel}.cmd';
CmdScriptName := 'galaxy-ai-{#ReleaseChannel}.cmd';
#endif
{ Create the helper CMD script }
CmdScriptPath := BinDir + '\' + CmdScriptName;
CmdScriptContent := '@echo off' + #13#10 +
'set "WARP_CLI_MODE=1"' + #13#10 +
'set "GALAXY_CLI_MODE=1"' + #13#10 +
'"' + ExpandConstant('{app}\{#MyAppExeName}') + '" %*' + #13#10;
SaveStringToFile(CmdScriptPath, CmdScriptContent, False);