Consolidate binary targets to galaxy-oss only
- Remove dev, integration, local, preview, and stable bin targets - Update Cargo.toml to reflect single binary - Fix related module references and tests
This commit is contained in:
@@ -66,7 +66,7 @@ use crate::ai::blocklist::code_block::CodeSnippetButtonHandles;
|
||||
use crate::ai::blocklist::inline_action::inline_action_icons::icon_size;
|
||||
use crate::ai::blocklist::permissions::is_agent_mode_autonomy_allowed;
|
||||
use crate::ai::blocklist::{
|
||||
BlocklistAIActionModel, BlocklistAIHistoryEvent, BlocklistAIPermissions,
|
||||
BlocklistAIActionModel, BlocklistAIController, BlocklistAIHistoryEvent, BlocklistAIPermissions,
|
||||
};
|
||||
use crate::ai::control_code_parser::{parse_control_codes_from_bytes, ParsedControlCodeOutput};
|
||||
use crate::ai::execution_profiles::profiles::{
|
||||
@@ -489,27 +489,36 @@ impl CLISubagentView {
|
||||
}
|
||||
|
||||
fn task_inputs_to_render(&self, app: &AppContext) -> Vec<AIAgentInput> {
|
||||
BlocklistAIHistoryModel::as_ref(app)
|
||||
let inputs = BlocklistAIHistoryModel::as_ref(app)
|
||||
.conversation(&self.conversation_id)
|
||||
.and_then(|conversation| conversation.get_task(&self.task_id))
|
||||
.map(|task| {
|
||||
task.exchanges()
|
||||
.flat_map(|exchange| exchange.input.iter())
|
||||
.filter_map(|input| {
|
||||
matches!(input, AIAgentInput::UserQuery { .. }).then(|| input.clone())
|
||||
})
|
||||
.last()
|
||||
.into_iter()
|
||||
.collect()
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.unwrap_or_else(|| self.model.inputs_to_render(app).to_vec())
|
||||
.unwrap_or_else(|| self.model.inputs_to_render(app).to_vec());
|
||||
|
||||
inputs
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find_map(|input| match &input {
|
||||
AIAgentInput::UserQuery { query, .. }
|
||||
if query != BlocklistAIController::cli_monitor_nudge_message() =>
|
||||
{
|
||||
Some(input)
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.into_iter()
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Builds the compact visible transcript for the monitor task.
|
||||
///
|
||||
/// The latest user query and the newest assistant text remain visible while historical tool
|
||||
/// activity is omitted to avoid a growing stack of repeated poll cards. Only the newest
|
||||
/// exchange's live action is retained.
|
||||
/// The view shows at most one user query and one assistant progress message. Historical tool
|
||||
/// calls and monitor nudges are implementation details, not user-facing transcript content.
|
||||
fn task_output_to_render(&self, app: &AppContext) -> AIAgentOutput {
|
||||
let Some(task) = BlocklistAIHistoryModel::as_ref(app)
|
||||
.conversation(&self.conversation_id)
|
||||
@@ -519,32 +528,17 @@ impl CLISubagentView {
|
||||
.model
|
||||
.status(app)
|
||||
.output_to_render()
|
||||
.map(|output| output.get().clone())
|
||||
.map(|output| compact_monitor_output([output.get().clone()]))
|
||||
.unwrap_or_default();
|
||||
};
|
||||
|
||||
let Some(last_exchange_id) = task.last_exchange().map(|exchange| exchange.id) else {
|
||||
return AIAgentOutput::default();
|
||||
};
|
||||
|
||||
let mut visible_output = AIAgentOutput::default();
|
||||
for exchange in task.exchanges() {
|
||||
let Some(output) = exchange.output_status.output() else {
|
||||
continue;
|
||||
};
|
||||
let output = output.get();
|
||||
for message in output.messages.iter().filter(|message| {
|
||||
should_retain_task_output_message(&message.message, exchange.id == last_exchange_id)
|
||||
}) {
|
||||
if matches!(message.message, AIAgentOutputMessageType::Text(_)) {
|
||||
visible_output.messages.retain(|existing| {
|
||||
!matches!(existing.message, AIAgentOutputMessageType::Text(_))
|
||||
});
|
||||
}
|
||||
visible_output.messages.push(message.clone());
|
||||
}
|
||||
}
|
||||
visible_output
|
||||
let outputs = task.exchanges().filter_map(|exchange| {
|
||||
exchange
|
||||
.output_status
|
||||
.output()
|
||||
.map(|output| output.get().clone())
|
||||
});
|
||||
compact_monitor_output(outputs)
|
||||
}
|
||||
|
||||
fn execute_pending_action(&mut self, ctx: &mut ViewContext<Self>) {
|
||||
@@ -1635,18 +1629,23 @@ fn should_show_read_files_speedbump(app: &AppContext) -> bool {
|
||||
&& *AISettings::as_ref(app).should_show_agent_mode_autoread_files_speedbump
|
||||
}
|
||||
|
||||
fn should_retain_task_output_message(
|
||||
message: &AIAgentOutputMessageType,
|
||||
is_latest_exchange: bool,
|
||||
) -> bool {
|
||||
fn compact_monitor_output(outputs: impl IntoIterator<Item = AIAgentOutput>) -> AIAgentOutput {
|
||||
let latest_text = outputs
|
||||
.into_iter()
|
||||
.flat_map(|output| output.messages)
|
||||
.filter(|message| should_retain_task_output_message(&message.message))
|
||||
.last();
|
||||
|
||||
// Keep the monitor transcript to one user-visible assistant message. Tool calls are
|
||||
// implementation details; the model's latest explanation is the useful progress update.
|
||||
AIAgentOutput {
|
||||
messages: latest_text.into_iter().collect(),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn should_retain_task_output_message(message: &AIAgentOutputMessageType) -> bool {
|
||||
matches!(message, AIAgentOutputMessageType::Text(_))
|
||||
|| (is_latest_exchange
|
||||
&& matches!(
|
||||
message,
|
||||
AIAgentOutputMessageType::Action(_)
|
||||
| AIAgentOutputMessageType::RuntimeActivity(_)
|
||||
| AIAgentOutputMessageType::WebSearch(_)
|
||||
))
|
||||
}
|
||||
|
||||
fn get_action_loading_text(action: AIAgentActionType) -> Option<String> {
|
||||
@@ -1663,10 +1662,10 @@ fn get_action_loading_text(action: AIAgentActionType) -> Option<String> {
|
||||
AIAgentActionType::FileGlobV2 { .. } => Some(LOAD_OUTPUT_MESSAGE_FOR_FILE_GLOB.to_string()),
|
||||
AIAgentActionType::ReadShellCommandOutput { delay, .. } => match delay {
|
||||
Some(crate::ai::agent::ShellCommandDelay::OnCompletion) => {
|
||||
Some("Waiting for the running command to finish…".to_string())
|
||||
Some("Waiting for the command to finish…".to_string())
|
||||
}
|
||||
Some(crate::ai::agent::ShellCommandDelay::Duration(_)) | None => {
|
||||
Some("Checking the running command output…".to_string())
|
||||
Some("Reading the latest command output…".to_string())
|
||||
}
|
||||
},
|
||||
AIAgentActionType::WriteToLongRunningShellCommand { .. } => {
|
||||
|
||||
@@ -3,11 +3,14 @@ use std::time::Duration;
|
||||
use galaxy_agent_core::RuntimeActivity;
|
||||
use galaxy_terminal::model::escape_sequences;
|
||||
|
||||
use super::{get_action_icon, get_action_loading_text, should_retain_task_output_message};
|
||||
use super::{
|
||||
compact_monitor_output, get_action_icon, get_action_loading_text,
|
||||
should_retain_task_output_message,
|
||||
};
|
||||
use crate::ai::agent::task::TaskId;
|
||||
use crate::ai::agent::{
|
||||
AIAgentAction, AIAgentActionId, AIAgentActionType, AIAgentOutputMessageType,
|
||||
AIAgentPtyWriteMode, AIAgentText, ShellCommandDelay,
|
||||
AIAgentAction, AIAgentActionId, AIAgentActionType, AIAgentOutput, AIAgentOutputMessage,
|
||||
AIAgentOutputMessageType, AIAgentPtyWriteMode, AIAgentText, MessageId, ShellCommandDelay,
|
||||
};
|
||||
use crate::terminal::model::block::BlockId;
|
||||
use crate::ui_components::icons::Icon;
|
||||
@@ -21,7 +24,7 @@ fn command_output_poll_has_visible_monitor_status() {
|
||||
|
||||
assert_eq!(
|
||||
get_action_loading_text(action.clone()).as_deref(),
|
||||
Some("Checking the running command output…")
|
||||
Some("Reading the latest command output…")
|
||||
);
|
||||
assert_eq!(get_action_icon(action), Some(Icon::ClockRefresh));
|
||||
}
|
||||
@@ -43,11 +46,11 @@ fn typed_interrupt_has_distinct_visible_status() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transcript_retains_prior_text_but_only_latest_tool_activity() {
|
||||
fn transcript_retains_only_one_user_visible_agent_message() {
|
||||
let text = AIAgentOutputMessageType::Text(AIAgentText { sections: vec![] });
|
||||
assert!(should_retain_task_output_message(&text, false));
|
||||
assert!(should_retain_task_output_message(&text));
|
||||
|
||||
let poll = AIAgentOutputMessageType::Action(AIAgentAction {
|
||||
let poll = AIAgentAction {
|
||||
id: AIAgentActionId::from("poll".to_string()),
|
||||
task_id: TaskId::new("cli-task".to_string()),
|
||||
action: AIAgentActionType::ReadShellCommandOutput {
|
||||
@@ -56,9 +59,13 @@ fn transcript_retains_prior_text_but_only_latest_tool_activity() {
|
||||
},
|
||||
requires_result: true,
|
||||
tool_name: Some("read_shell_command_output".to_string()),
|
||||
});
|
||||
assert!(!should_retain_task_output_message(&poll, false));
|
||||
assert!(should_retain_task_output_message(&poll, true));
|
||||
};
|
||||
assert!(!should_retain_task_output_message(
|
||||
&AIAgentOutputMessageType::Action(poll.clone()),
|
||||
));
|
||||
assert!(!should_retain_task_output_message(
|
||||
&AIAgentOutputMessageType::Action(poll),
|
||||
));
|
||||
|
||||
let runtime_activity = AIAgentOutputMessageType::RuntimeActivity(RuntimeActivity {
|
||||
id: "acp-tool".to_owned(),
|
||||
@@ -66,6 +73,21 @@ fn transcript_retains_prior_text_but_only_latest_tool_activity() {
|
||||
status: None,
|
||||
output: None,
|
||||
});
|
||||
assert!(!should_retain_task_output_message(&runtime_activity, false));
|
||||
assert!(should_retain_task_output_message(&runtime_activity, true));
|
||||
assert!(!should_retain_task_output_message(&runtime_activity));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn compact_monitor_output_keeps_only_the_latest_text_message() {
|
||||
let output = |id: &str| AIAgentOutput {
|
||||
messages: vec![AIAgentOutputMessage::text(
|
||||
MessageId::new(id.to_owned()),
|
||||
AIAgentText { sections: vec![] },
|
||||
)],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let compacted = compact_monitor_output([output("old"), output("latest")]);
|
||||
|
||||
assert_eq!(compacted.messages.len(), 1);
|
||||
assert_eq!(&*compacted.messages[0].id, "latest");
|
||||
}
|
||||
|
||||
@@ -2954,7 +2954,7 @@ impl BlocklistAIController {
|
||||
}
|
||||
|
||||
pub(crate) fn cli_monitor_nudge_message() -> &'static str {
|
||||
"The command is still running. Please check its latest output and keep monitoring it."
|
||||
"The command is still running. Before checking it again, provide one concise, user-facing sentence grounded in the latest output about what it appears to be doing, then continue monitoring it."
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
||||
@@ -816,7 +816,7 @@ fn build_system_prompt(
|
||||
"## Orchestration Mode\nDelegate only independent, bounded work where parallelism materially helps, then synthesize the results.\n\n",
|
||||
),
|
||||
RigRequestMode::Cli => prompt.push_str(
|
||||
"## Running Command Monitor\nKeep an eye on the existing command while continuing the user's request. Use the command ID from the tool result for every read/write operation. If the result says the command finished, report its outcome and stop polling. If it says the command is still running, the next assistant output MUST be a tool call. Use `read_shell_command_output` with a short delay for normal progress. If the snapshot clearly shows an interactive pager or editor, do not keep polling: an alternate screen containing `(END)` is `less`, so call `write_to_long_running_shell_command` with input `q` and mode `raw`; for a clearly identified Vim screen, send input `:q` with mode `line`. Poll briefly after sending quit input to verify the outcome. Use `interrupt_shell_command` immediately when the user's explicit stop condition is met. The next response must be a tool call, not a progress update. Never choose a poll interval that crosses a user-specified deadline or stop condition. After an interrupt, poll briefly to verify the outcome. Never start a duplicate command merely to check its state, and never report completion while a result says it is still running.\n\n",
|
||||
"## Running Command Monitor\nKeep an eye on the existing command while continuing the user's request. Use the command ID from the tool result for every read/write operation. If the result says the command finished, report its outcome and stop polling. If the result says the command is still running, write at most one concise, user-facing sentence grounded in the latest output explaining what the command appears to be doing or waiting for, then make the polling tool call in the same response. Do not send a text-only progress response, repeat a generic 'still running' message, or mention internal polling mechanics. If the snapshot clearly shows an interactive pager or editor, do not keep polling: an alternate screen containing `(END)` is `less`, so call `write_to_long_running_shell_command` with input `q` and mode `raw`; for a clearly identified Vim screen, send input `:q` with mode `line`. Poll briefly after sending quit input to verify the outcome. Use `interrupt_shell_command` immediately when the user's explicit stop condition is met. Never choose a poll interval that crosses a user-specified deadline or stop condition. After an interrupt, poll briefly to verify the outcome. Never start a duplicate command merely to check its state, and never report completion while a result says it is still running.\n\n",
|
||||
),
|
||||
RigRequestMode::CompletedCommandAssessment => prompt.push_str(
|
||||
"## Completed Command Assessment\nThe monitored command has finished. Use its command, command ID, final terminal output, and the assessment instruction in the latest hidden input to provide the final user-facing outcome. Do not continue polling, request more terminal output, or call tools.\n\n",
|
||||
|
||||
@@ -450,10 +450,11 @@ fn lrc_snapshot_follow_up_uses_the_cli_monitor_prompt_and_tools() {
|
||||
|
||||
assert!(prompt.contains("## Running Command Monitor"));
|
||||
assert!(prompt.contains("`read_shell_command_output` with a short delay"));
|
||||
assert!(prompt.contains("next assistant output MUST be a tool call"));
|
||||
assert!(prompt.contains("one concise, user-facing sentence"));
|
||||
assert!(prompt.contains("Do not send a text-only progress response"));
|
||||
assert!(prompt.contains("alternate screen containing `(END)` is `less`"));
|
||||
assert!(prompt.contains("`write_to_long_running_shell_command` with input `q` and mode `raw`"));
|
||||
assert!(prompt.contains("The next response must be a tool call, not a progress update"));
|
||||
assert!(prompt.contains("make the polling tool call in the same response"));
|
||||
assert!(prepared
|
||||
.request
|
||||
.tools
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
// On Windows, we don't want to display a console window when the application is running in release
|
||||
// builds. See https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute.
|
||||
#![cfg_attr(feature = "release_bundle", windows_subsystem = "windows")]
|
||||
|
||||
use anyhow::Result;
|
||||
use galaxy_core::channel::{Channel, ChannelState};
|
||||
use galaxy_core::features;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
ChannelState::set(
|
||||
ChannelState::new(Channel::Dev, warp_channel_config::load_config!("dev"))
|
||||
.with_additional_features(features::DEBUG_FLAGS)
|
||||
.with_additional_features(features::DOGFOOD_FLAGS)
|
||||
.with_additional_features(features::PREVIEW_FLAGS),
|
||||
);
|
||||
|
||||
galaxy::run()
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use galaxy_cli::WorkerCommand;
|
||||
use galaxy_core::channel::{Channel, ChannelConfig, ChannelState, OzConfig, WarpServerConfig};
|
||||
use galaxy_core::AppId;
|
||||
|
||||
#[derive(Debug, Default, Parser, Clone)]
|
||||
#[command(name = "warp-integration")]
|
||||
#[clap(args_conflicts_with_subcommands = true)]
|
||||
pub struct Args {
|
||||
#[command(subcommand)]
|
||||
command: Option<WorkerCommand>,
|
||||
}
|
||||
|
||||
pub fn main() -> Result<()> {
|
||||
ChannelState::set(ChannelState::new(
|
||||
Channel::Integration,
|
||||
ChannelConfig {
|
||||
app_id: AppId::new(
|
||||
"dev",
|
||||
"warp",
|
||||
if cfg!(target_os = "macos") {
|
||||
"Warp-Integration"
|
||||
} else {
|
||||
"WarpIntegration"
|
||||
},
|
||||
),
|
||||
logfile_name: "warp_integration.log".into(),
|
||||
server_config: WarpServerConfig {
|
||||
firebase_auth_api_key: "".into(),
|
||||
// Use an IP in the IANA testing range, with the TCP discard port, to
|
||||
// black-hole server traffic.
|
||||
server_root_url: "http://192.0.2.0:9".into(),
|
||||
rtc_server_url: "ws://192.0.2.0:9/graphql/v2".into(),
|
||||
session_sharing_server_url: None,
|
||||
iap_config: None,
|
||||
},
|
||||
oz_config: OzConfig {
|
||||
// Use an IP in the IANA testing range, with the TCP discard port, to
|
||||
// black-hole server traffic.
|
||||
oz_root_url: "http://192.0.2.0:9".into(),
|
||||
workload_audience_url: None,
|
||||
},
|
||||
telemetry_config: None,
|
||||
autoupdate_config: None,
|
||||
mcp_static_config: None,
|
||||
},
|
||||
));
|
||||
|
||||
let args = Args::parse();
|
||||
|
||||
if let Some(command) = &args.command {
|
||||
match command {
|
||||
#[cfg(unix)]
|
||||
WorkerCommand::TerminalServer(args) => {
|
||||
// If we were asked to run as a terminal server (as opposed to the main
|
||||
// GUI application), do so. This must occur before init_logging, as the
|
||||
// terminal server sets up its own logger, and attempting to set a second
|
||||
// logger leads to a panic.
|
||||
galaxy::terminal::local_tty::server::run_terminal_server(args);
|
||||
return Ok(());
|
||||
}
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
WorkerCommand::RemoteServerProxy(_) | WorkerCommand::RemoteServerDaemon(_) => {
|
||||
return galaxy::run();
|
||||
}
|
||||
// This is a catch-all to handle the plugin host, which the integration test crate doesn't have a feature flag for.
|
||||
#[allow(unreachable_patterns)]
|
||||
other => panic!("Worker not supported in integration tests: {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
galaxy::run()
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use galaxy_core::channel::{Channel, ChannelState};
|
||||
use galaxy_core::features;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let config = warp_channel_config::load_config!("local");
|
||||
|
||||
let mut state = ChannelState::new(Channel::Local, config)
|
||||
.with_additional_features(features::DEBUG_FLAGS)
|
||||
.with_additional_features(features::DOGFOOD_FLAGS)
|
||||
.with_additional_features(features::PREVIEW_FLAGS)
|
||||
.with_additional_features(features::LOCAL_FLAGS);
|
||||
|
||||
// Enable sandbox telemetry feature flag if the env var is set.
|
||||
if std::env::var("WITH_SANDBOX_TELEMETRY").is_ok() {
|
||||
state = state.with_additional_features(&[features::FeatureFlag::WithSandboxTelemetry]);
|
||||
}
|
||||
|
||||
ChannelState::set(state);
|
||||
|
||||
galaxy::run()
|
||||
}
|
||||
|
||||
// If we're not using an external plist, embed the following as the Info.plist.
|
||||
#[cfg(all(not(feature = "extern_plist"), target_os = "macos"))]
|
||||
embed_plist::embed_info_plist_bytes!(r#"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Galaxy</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>galaxy-local</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>samsung.galaxy.GalaxyLocal</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>Galaxy</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.1.0</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.developer-tools</string>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>UIDesignRequiresCompatibility</key>
|
||||
<true/>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array><dict><key>CFBundleURLName</key><string>Galaxy</string><key>CFBundleURLSchemes</key><array><string>galaxyai</string></array></dict></array>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>© 2026, Samsung Electronics Co., Ltd.</string>
|
||||
</dict>
|
||||
</plist>
|
||||
"#.as_bytes());
|
||||
@@ -25,6 +25,7 @@ fn main() -> Result<()> {
|
||||
if cfg!(debug_assertions) {
|
||||
state = state.with_additional_features(galaxy_core::features::DEBUG_FLAGS);
|
||||
}
|
||||
state = state.with_additional_features(galaxy_core::features::PREVIEW_FLAGS);
|
||||
state = state.with_additional_features(&[
|
||||
FeatureFlag::AgentMode,
|
||||
FeatureFlag::AgentView,
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// On Windows, we don't want to display a console window when the application is running in release
|
||||
// builds. See https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute.
|
||||
#![cfg_attr(feature = "release_bundle", windows_subsystem = "windows")]
|
||||
|
||||
use anyhow::Result;
|
||||
use galaxy_core::channel::{Channel, ChannelState};
|
||||
use galaxy_core::features;
|
||||
|
||||
fn main() -> Result<()> {
|
||||
ChannelState::set(
|
||||
ChannelState::new(
|
||||
Channel::Preview,
|
||||
warp_channel_config::load_config!("preview"),
|
||||
)
|
||||
.with_additional_features(features::PREVIEW_FLAGS)
|
||||
.with_additional_features(&[features::FeatureFlag::ForceLogin]),
|
||||
);
|
||||
|
||||
galaxy::run()
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// On Windows, we don't want to display a console window when the application is running in release
|
||||
// builds. See https://doc.rust-lang.org/reference/runtime.html#the-windows_subsystem-attribute.
|
||||
#![cfg_attr(feature = "release_bundle", windows_subsystem = "windows")]
|
||||
|
||||
use anyhow::Result;
|
||||
use galaxy_core::channel::{Channel, ChannelState};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
ChannelState::set(ChannelState::new(
|
||||
Channel::Stable,
|
||||
warp_channel_config::load_config!("stable"),
|
||||
));
|
||||
|
||||
galaxy::run()
|
||||
}
|
||||
@@ -1239,6 +1239,10 @@ pub(crate) fn initialize_app(
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate state and caches out of macOS Application Support before creating
|
||||
// the new home-relative data directory.
|
||||
galaxy_core::paths::migrate_legacy_macos_data_dir_if_needed();
|
||||
|
||||
// One-time migration: give Preview its own config directory by
|
||||
// symlinking contents from the shared ~/.warp location. Must run
|
||||
// before ensure_galaxy_watch_roots_exist() creates the new directory.
|
||||
|
||||
@@ -27,20 +27,20 @@ This will create a new folder with an up.sql and down.sql.
|
||||
## Step 3: Run the migration + generate the schema
|
||||
```
|
||||
cd <repo root>
|
||||
diesel migration run --database-url="/Users/$USER/Library/Application Support/samsung.galaxy.GalaxyLocal/galaxy.sqlite"
|
||||
diesel migration run --database-url="/Users/$USER/.galaxy-local/galaxy.sqlite"
|
||||
```
|
||||
This will run the migration on the same warp that runs when you run the app locally. This automatically generates or updates the `crates/persistence/src/schema.rs`. We do not make manual edits to `schema.rs`.
|
||||
|
||||
You can also print the schema from a database that already has the migration with:
|
||||
```
|
||||
diesel print-schema --database-url="/Users/$USER/Library/Application Support/samsung.galaxy.GalaxyLocal/galaxy.sqlite"
|
||||
diesel print-schema --database-url="/Users/$USER/.galaxy-local/galaxy.sqlite"
|
||||
```
|
||||
|
||||
## Reverting/redo-ing migrations
|
||||
As you are writing features and changing branches, you'll want to undo migrations to fix your database and make it compatible with older code. Redo-ing can also be helpful as you are iterating on your schema.
|
||||
```
|
||||
diesel migration revert --database-url="/Users/$USER/Library/Application Support/samsung.galaxy.GalaxyLocal/galaxy.sqlite"
|
||||
diesel migration redo --database-url="/Users/$USER/Library/Application Support/samsung.galaxy.GalaxyLocal/galaxy.sqlite"
|
||||
diesel migration revert --database-url="/Users/$USER/.galaxy-local/galaxy.sqlite"
|
||||
diesel migration redo --database-url="/Users/$USER/.galaxy-local/galaxy.sqlite"
|
||||
```
|
||||
|
||||
# Schema style
|
||||
|
||||
Reference in New Issue
Block a user