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
+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);