Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
35034da
docs: specify repository workspace organization
mmaxiaolei Jul 11, 2026
81bd818
docs: plan repository workspace implementation
mmaxiaolei Jul 11, 2026
f947959
feat: add repository workspaces flag
mmaxiaolei Jul 11, 2026
cfdebb9
feat: persist repository workspaces
mmaxiaolei Jul 11, 2026
f13c233
test: harden repository workspace persistence
mmaxiaolei Jul 11, 2026
da0635d
feat: add repository workspace model
mmaxiaolei Jul 11, 2026
30ab203
fix: preserve repository workspace recovery state
mmaxiaolei Jul 11, 2026
69c773f
fix: normalize persisted repository paths
mmaxiaolei Jul 11, 2026
c265212
docs: design acknowledged repository persistence
mmaxiaolei Jul 12, 2026
3d36e3a
docs: plan acknowledged repository persistence
mmaxiaolei Jul 12, 2026
9d09906
fix: resolve repository path ambiguity
mmaxiaolei Jul 12, 2026
d2759ce
fix: make repository memory commits infallible
mmaxiaolei Jul 12, 2026
902e12f
feat: acknowledge repository persistence
mmaxiaolei Jul 12, 2026
74ff7cc
test: harden repository persistence acknowledgement
mmaxiaolei Jul 12, 2026
567c857
fix: commit repository state after persistence
mmaxiaolei Jul 12, 2026
ca80325
fix: complete repository persistence verification
mmaxiaolei Jul 12, 2026
9accb1b
feat: add repository git service
mmaxiaolei Jul 12, 2026
4d28011
fix: harden repository git edge cases
mmaxiaolei Jul 12, 2026
2d3fec1
fix: preserve git path and ref edge cases
mmaxiaolei Jul 12, 2026
cb39e07
feat: manage repository worktrees safely
mmaxiaolei Jul 12, 2026
e9bc824
docs: design safe worktree ownership
mmaxiaolei Jul 12, 2026
3e88797
docs: revise safe worktree ownership
mmaxiaolei Jul 13, 2026
c66e7ed
docs: plan safe worktree ownership
mmaxiaolei Jul 13, 2026
8b36c88
feat: add prepared git ref transactions
mmaxiaolei Jul 13, 2026
aefbb86
test: verify ref transaction lock release
mmaxiaolei Jul 13, 2026
80cb9b0
fix: reject conflicting ref transaction updates
mmaxiaolei Jul 13, 2026
56cdfa8
fix: claim worktree targets atomically
mmaxiaolei Jul 13, 2026
66918e9
fix: resolve claimed worktree paths
mmaxiaolei Jul 13, 2026
210f161
test: clean relative worktree fixtures
mmaxiaolei Jul 13, 2026
62f0b92
feat: capture deletion target snapshots
mmaxiaolei Jul 13, 2026
0a05347
fix: validate worktree deletion under ref locks
mmaxiaolei Jul 13, 2026
bc6eef0
fix: preserve worktree deletion partial state
mmaxiaolei Jul 13, 2026
635ea5c
docs: specify repository workspace add button fix
mmaxiaolei Jul 15, 2026
80d78d8
docs: specify workspace branch picker
mmaxiaolei Jul 15, 2026
111a271
feat: add repository workspaces
mmaxiaolei Jul 15, 2026
7ed8264
chore: add repository workspace plans
mmaxiaolei Jul 15, 2026
e9d3051
docs: specify existing worktree adoption
mmaxiaolei Jul 15, 2026
bcca5aa
feat: validate existing worktrees
mmaxiaolei Jul 15, 2026
15576e3
feat: adopt existing worktrees as workspaces
mmaxiaolei Jul 16, 2026
ae708cd
fix: polish repository workspace controls
mmaxiaolei Jul 16, 2026
f42bb93
docs: define workspace selection state
mmaxiaolei Jul 16, 2026
2c7ac49
docs: add workspace selection implementation plan
mmaxiaolei Jul 16, 2026
ea1dc5c
fix: strengthen workspace selection state
mmaxiaolei Jul 16, 2026
a54613a
fix: sort repositories by creation time
mmaxiaolei Jul 16, 2026
4e4ff90
persist active terminal blocks during app shutdown
mmaxiaolei Jul 19, 2026
246649b
docs: design nested repository workspace paths
mmaxiaolei Jul 19, 2026
ed20bc6
fix: create parent directories for repository workspaces
mmaxiaolei Jul 19, 2026
9c1ea77
docs: design local repository workspace
mmaxiaolei Jul 19, 2026
145c2d8
docs: plan local repository workspace
mmaxiaolei Jul 19, 2026
ec8f69a
feat: recognize repository primary worktrees
mmaxiaolei Jul 20, 2026
fb62533
fix: normalize primary worktree paths
mmaxiaolei Jul 20, 2026
64942b1
feat: expose primary worktree in workspace modal
mmaxiaolei Jul 20, 2026
c12f4a0
feat: persist initial local repository workspace
mmaxiaolei Jul 20, 2026
28e5190
feat: auto-create local workspace for repositories
mmaxiaolei Jul 20, 2026
9f6d605
fix: avoid flex panic in create workspace modal
mmaxiaolei Jul 20, 2026
63bfee3
fix: sort repository workspaces by creation time
mmaxiaolei Jul 20, 2026
8155c79
docs: specify workspace terminal activity indicator
mmaxiaolei Jul 20, 2026
0e94a0c
docs: revise workspace activity count semantics
mmaxiaolei Jul 20, 2026
a9b091e
docs: clarify workspace activity badge tab count
mmaxiaolei Jul 20, 2026
f50f35a
docs: specify selected workspace glow state
mmaxiaolei Jul 20, 2026
9ec6bc8
docs: plan workspace activity indicator implementation
mmaxiaolei Jul 20, 2026
47a9697
feat: find repository workspaces matching tabs
mmaxiaolei Jul 20, 2026
e47c415
feat: add workspace activity visual state
mmaxiaolei Jul 20, 2026
e820446
feat: render workspace activity badge
mmaxiaolei Jul 20, 2026
d065e1d
fix: stabilize workspace selection frame layout
mmaxiaolei Jul 20, 2026
882f9a8
feat: sync running workspace activity
mmaxiaolei Jul 20, 2026
7bf6bed
Add workspace status indicators and UI polish
mmaxiaolei Jul 21, 2026
2663071
Fix workspace activity badge layout
mmaxiaolei Jul 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ app/src/server/graphql/schema/generated
crates/command-signatures-v2/js/build
crates/command-signatures-v2/js/node_modules
.worktrees/
/.superpowers/
/target-check
# For testing changes to the channel versions file
channel_versions_test.json
Expand Down Expand Up @@ -79,3 +80,5 @@ official-website/
docs/openwarp-cloud-removal-plan.md
.omx/
.tmp/
.codegraph/
.cursor/
6 changes: 5 additions & 1 deletion app/src/ai/agent/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ impl ServerConversationToken {
}

pub fn debug_link(&self) -> String {
format!("{}://debug/maa/{}", ChannelState::url_scheme(), self.as_str())
format!(
"{}://debug/maa/{}",
ChannelState::url_scheme(),
self.as_str()
)
}

pub fn conversation_link(&self) -> String {
Expand Down
2 changes: 1 addition & 1 deletion app/src/ai/agent/api_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ use crate::cloud_object::model::persistence::ObjectStoreModel;
use crate::cloud_object::model::view::ObjectStoreViewModel;
use crate::cloud_object::update_manager::UpdateManager;
use crate::cloud_object::{StoredObjectMetadata, StoredObjectPermissions};
use crate::server_time::ServerTimestamp;
use crate::notebooks::manager::NotebookManager;
use crate::server::ids::SyncId;
use crate::server_time::ServerTimestamp;
use crate::settings::AISettings;
use crate::system::SystemStats;
use crate::workspaces::user_profiles::UserProfiles;
Expand Down
12 changes: 6 additions & 6 deletions app/src/ai/agent/conversation_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ fn run_shell_command_tool() -> api::message::tool_call::Tool {
})
}

fn tool_call_message_with_tool(id: &str, call_id: &str, tool: api::message::tool_call::Tool) -> api::Message {
fn tool_call_message_with_tool(
id: &str,
call_id: &str,
tool: api::message::tool_call::Tool,
) -> api::Message {
api::Message {
id: id.to_string(),
task_id: "root-task".to_string(),
Expand Down Expand Up @@ -475,11 +479,7 @@ fn test_cli_subagent_serialized_block_preserves_block_id_and_metadata() {
api::Task {
id: "root-task".to_string(),
messages: vec![
tool_call_message_with_tool(
"tool-call-1",
"call-1",
run_shell_command_tool(),
),
tool_call_message_with_tool("tool-call-1", "call-1", run_shell_command_tool()),
tool_call_result_message_with_result(
"tool-result-1",
"call-1",
Expand Down
14 changes: 10 additions & 4 deletions app/src/ai/agent_providers/active_ai/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ pub mod prompt_suggestions {
}
}
};
let system = render("prompt_suggestions_system.j2", context! { language => language });
let system = render(
"prompt_suggestions_system.j2",
context! { language => language },
);
let user = render(
"prompt_suggestions_user.j2",
context! {
Expand Down Expand Up @@ -433,9 +436,12 @@ pub mod next_command {
.into_iter()
.map(|(name, content)| UserRuleCtx { name, content })
.collect();
let system = render("next_command_system.j2", context! {
user_rules => user_rule_ctxs,
});
let system = render(
"next_command_system.j2",
context! {
user_rules => user_rule_ctxs,
},
);
let user = render(
"next_command_user.j2",
context! {
Expand Down
4 changes: 1 addition & 3 deletions app/src/ai/agent_sdk/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1518,9 +1518,7 @@ impl AgentDriver {
fn handle_terminal_driver_event(&mut self, event: &TerminalDriverEvent) {
match event {
TerminalDriverEvent::SlowBootstrap => {
eprintln!(
"Warning: Terminal session is slow to bootstrap."
);
eprintln!("Warning: Terminal session is slow to bootstrap.");
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions app/src/ai/agent_sdk/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@ fn run_agent(
Ok(())
}
AgentCommand::Profile(sub) => profiles::run(ctx, global_options, sub),
AgentCommand::List(_) => Err(anyhow::anyhow!(
"Agent skill listing is disabled in Zap"
)),
AgentCommand::List(_) => Err(anyhow::anyhow!("Agent skill listing is disabled in Zap")),
}
}

Expand Down
6 changes: 1 addition & 5 deletions app/src/ai/agent_tips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ static DEFAULT_TIPS: LazyLock<Vec<AgentTip>> = LazyLock::new(|| {
action: None,
kind: AgentTipKind::Context,
},

AgentTip {
description: crate::t!("agent-tip-agent-profiles"),
link: Some("".to_string()),
Expand Down Expand Up @@ -411,10 +410,7 @@ pub fn get_agent_tips(ctx: &AppContext) -> Vec<AgentTip> {
{
tips.push(AgentTip {
description: crate::t!("agent-tip-voice-input"),
link: Some(
""
.to_string(),
),
link: Some("".to_string()),
binding_name: Some("FN"),
action: None,
kind: AgentTipKind::General,
Expand Down
34 changes: 16 additions & 18 deletions app/src/ai/blocklist/action_model/execute/read_skill.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use super::{ActionExecution, AnyActionExecution, ExecuteActionInput, PreprocessActionInput};
#[cfg(feature = "local_fs")]
use crate::ai::agent::AIAgentActionResultType;
use crate::ai::skills::{SkillManager, SkillTelemetryEvent};
#[cfg(feature = "local_fs")]
use crate::ai::skills::extract_skill_parent_directory;
use crate::ai::skills::{SkillManager, SkillTelemetryEvent};
use crate::send_telemetry_from_ctx;
use ai::agent::action_result::AnyFileContent;
use ai::skills::SkillReference;
#[cfg(feature = "local_fs")]
use ai::skills::parse_skill;
use ai::skills::SkillReference;
use std::path::Path;
use warpui::{ModelContext, SingletonEntity};

Expand Down Expand Up @@ -112,21 +112,17 @@ impl ReadSkillExecutor {
return ActionExecution::new_async(
async move { parse_skill(&path) },
move |parsed, _app| match parsed {
Ok(skill) => AIAgentActionResultType::ReadSkill(
ReadSkillResult::Success {
content: FileContext::new(
skill.path.to_string_lossy().into_owned(),
AnyFileContent::StringContent(skill.content.clone()),
skill.line_range.clone(),
None,
),
},
),
Err(err) => AIAgentActionResultType::ReadSkill(
ReadSkillResult::Error(format!(
"Skill not found: {skill_ref_for_async:?} ({err})"
)),
),
Ok(skill) => AIAgentActionResultType::ReadSkill(ReadSkillResult::Success {
content: FileContext::new(
skill.path.to_string_lossy().into_owned(),
AnyFileContent::StringContent(skill.content.clone()),
skill.line_range.clone(),
None,
),
}),
Err(err) => AIAgentActionResultType::ReadSkill(ReadSkillResult::Error(
format!("Skill not found: {skill_ref_for_async:?} ({err})"),
)),
},
);
}
Expand Down Expand Up @@ -160,7 +156,9 @@ impl ReadSkillExecutor {
///
/// 抽出 helper 是为了让 `ActionExecution<T>` 的泛型 `T` 在 `success_execution`
/// 和 `new_async` 两条路径里推导到相同类型(否则 Rust 会要求函数显式声明返回类型)。
fn success_execution(skill: &ai::skills::ParsedSkill) -> ActionExecution<anyhow::Result<ai::skills::ParsedSkill>> {
fn success_execution(
skill: &ai::skills::ParsedSkill,
) -> ActionExecution<anyhow::Result<ai::skills::ParsedSkill>> {
let content = FileContext::new(
skill.path.to_string_lossy().into_owned(),
AnyFileContent::StringContent(skill.content.clone()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ fn test_read_skill_executor_fallback_returns_error_when_file_missing() {
on_complete,
} = execution
else {
panic!("Legal-shaped skill path should still produce Async execution before disk check");
panic!(
"Legal-shaped skill path should still produce Async execution before disk check"
);
};

let async_result = execute_future.await;
Expand Down
4 changes: 3 additions & 1 deletion app/src/ai/blocklist/agent_view/zero_state_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,9 @@ fn render_title_and_description(props: HeaderProps, app: &AppContext) -> Vec<Box
sub_text_color,
Default::default(),
)
.with_heading_to_font_size_multipliers(appearance.heading_font_size_multipliers().clone())
.with_heading_to_font_size_multipliers(
appearance.heading_font_size_multipliers().clone(),
)
.with_inline_code_properties(Some(main_text_color), None)
.finish()
});
Expand Down
4 changes: 3 additions & 1 deletion app/src/ai/blocklist/block/view_impl/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,9 @@ pub(super) fn render(props: Props, app: &AppContext) -> Box<dyn Element> {
body_color,
Default::default(),
)
.with_heading_to_font_size_multipliers(appearance.heading_font_size_multipliers().clone())
.with_heading_to_font_size_multipliers(
appearance.heading_font_size_multipliers().clone(),
)
.set_selectable(true);

let mut action =
Expand Down
4 changes: 3 additions & 1 deletion app/src/ai/blocklist/inline_action/inline_action_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,9 @@ impl HeaderConfig {
text_color,
Default::default(),
)
.with_heading_to_font_size_multipliers(appearance.heading_font_size_multipliers().clone())
.with_heading_to_font_size_multipliers(
appearance.heading_font_size_multipliers().clone(),
)
.set_selectable(self.is_text_selectable);
if !self.soft_wrap_title {
element = element.with_no_text_wrapping();
Expand Down
1 change: 0 additions & 1 deletion app/src/ai_assistant/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ const PANEL_HORIZONTAL_PADDING: f32 = 6.;
const EDITOR_MARGIN: f32 = 16.;
const LOGO_SIZE: f32 = 20.;


const ZERO_STATE_HELP_TEXT: &str = "Shift + ctrl + space a block or text selection to ask Zap AI.";
const SCRIPT_ZERO_STATE_PROMPT: &str = "Write a script to connect to an AWS EC2 instance.";
const GIT_ZERO_STATE_PROMPT: &str = "How do I undo the most recent commits in git?";
Expand Down
9 changes: 5 additions & 4 deletions app/src/ai_assistant/transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use warpui::units::Pixels;
use warpui::{
elements::{
Align, Border, ChildAnchor, ClippedScrollStateHandle, ClippedScrollable, ConstrainedBox,
Container, CornerRadius, CrossAxisAlignment, EventHandler, Fill, Flex,
Container, CornerRadius, CrossAxisAlignment, EventHandler, Expanded, Fill, Flex,
FormattedTextElement, HyperlinkUrl, Icon, MainAxisAlignment, MainAxisSize,
MouseStateHandle, ParentAnchor, ParentElement, Radius, SavePosition, ScrollbarWidth,
Expanded, Shrinkable, Text, Wrap,
Shrinkable, Text, Wrap,
},
keymap::Keystroke,
platform::Cursor,
Expand Down Expand Up @@ -49,7 +49,6 @@ const TERMINAL_INPUT_SVG_PATH: &str = "bundled/svg/terminal-input.svg";
const USER_ICON_SVG_PATH: &str = "bundled/svg/user.svg";
const SAVE_WORKFLOW_ICON_PATH: &str = "bundled/svg/workflow.svg";


const PANEL_LEFT_MARGIN: f32 = 15.;
const DETAILS_BOTTOM_MARGIN: f32 = 12.;

Expand Down Expand Up @@ -634,7 +633,9 @@ impl Transcript {
theme.main_text_color(theme.surface_2()).into_solid(),
highlighted_hyperlink.clone(),
)
.with_heading_to_font_size_multipliers(appearance.heading_font_size_multipliers().clone())
.with_heading_to_font_size_multipliers(
appearance.heading_font_size_multipliers().clone(),
)
.with_inline_code_properties(
Some(theme.nonactive_ui_text_color().into()),
Some(inline_code_bg_color),
Expand Down
1 change: 0 additions & 1 deletion app/src/ai_assistant/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use crate::{appearance::Appearance, ui_components::blended_colors};

use super::{panel::AIAssistantAction, requests::Requests, transcript::CodeBlockMouseStateHandles};


const SQUARE_ALERT_SVG_PATH: &str = "bundled/svg/alert-square.svg";
const TRIANGLE_ALERT_SVG_PATH: &str = "bundled/svg/alert-triangle.svg";

Expand Down
12 changes: 12 additions & 0 deletions app/src/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::ai::blocklist::InputConfig;
use crate::ai::blocklist::SerializedBlockListItem;
use crate::code::editor_management::CodeSource;
use crate::drive::ZapDriveObjectSettings;
use crate::project_organization::domain::RepositoryWorkspaceId;
use crate::root_view::quake_mode_window_id;
use crate::server::ids::SyncId;
use crate::settings_view::SettingsSection;
Expand Down Expand Up @@ -45,6 +46,8 @@ pub struct PersistedAgentManagementFilters {
pub struct WindowSnapshot {
pub tabs: Vec<TabSnapshot>,
pub active_tab_index: usize,
pub active_repository_workspace_id: Option<RepositoryWorkspaceId>,
pub repository_workspace_states: Vec<RepositoryWorkspaceWindowStateSnapshot>,
pub bounds: Option<RectF>,
pub fullscreen_state: FullscreenState,
pub quake_mode: bool,
Expand All @@ -64,6 +67,7 @@ pub struct WindowSnapshot {

#[derive(Clone, Debug, PartialEq)]
pub struct TabSnapshot {
pub repository_workspace_id: Option<RepositoryWorkspaceId>,
pub custom_title: Option<String>,
pub root: PaneNodeSnapshot,
pub default_directory_color: Option<AnsiColorIdentifier>,
Expand All @@ -72,6 +76,12 @@ pub struct TabSnapshot {
pub right_panel: Option<RightPanelSnapshot>,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RepositoryWorkspaceWindowStateSnapshot {
pub repository_workspace_id: RepositoryWorkspaceId,
pub active_tab_index: usize,
}

impl TabSnapshot {
pub(crate) fn color(&self) -> Option<AnsiColorIdentifier> {
self.selected_color.resolve(self.default_directory_color)
Expand Down Expand Up @@ -317,6 +327,7 @@ pub enum CodeReviewPaneSnapshot {

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub enum LeftPanelDisplayedTab {
ProjectTree,
FileTree,
GlobalSearch,
ZapDrive,
Expand All @@ -329,6 +340,7 @@ pub enum LeftPanelDisplayedTab {
impl From<ToolPanelView> for LeftPanelDisplayedTab {
fn from(view: ToolPanelView) -> Self {
match view {
ToolPanelView::ProjectTree => LeftPanelDisplayedTab::ProjectTree,
ToolPanelView::ProjectExplorer => LeftPanelDisplayedTab::FileTree,
ToolPanelView::GlobalSearch { .. } => LeftPanelDisplayedTab::GlobalSearch,
ToolPanelView::ZapDrive => LeftPanelDisplayedTab::ZapDrive,
Expand Down
9 changes: 5 additions & 4 deletions app/src/appearance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use macos_app_icon::*;
use crate::{
settings::{
active_theme_kind, font::heading_font_size_multipliers_from_settings, FontSettings,
FontSettingsChangedEvent, MonospaceFontSize, Settings, ThemeSettings, UI_FONT_SIZE_MIN,
UI_FONT_SIZE_MAX,
FontSettingsChangedEvent, MonospaceFontSize, Settings, ThemeSettings, UI_FONT_SIZE_MAX,
UI_FONT_SIZE_MIN,
},
themes::theme::{ThemeKind, WarpTheme},
ASSETS,
Expand Down Expand Up @@ -485,8 +485,9 @@ fn build_appearance(ctx: &mut AppContext) -> Appearance {
let ui_font_family = if ui_font_name.is_empty() {
load_default_ui_font_family(ctx).expect("unable to load default ui font family")
} else {
get_or_load_font_family(&ui_font_name, ctx)
.unwrap_or_else(|| load_default_ui_font_family(ctx).expect("unable to load default ui font family"))
get_or_load_font_family(&ui_font_name, ctx).unwrap_or_else(|| {
load_default_ui_font_family(ctx).expect("unable to load default ui font family")
})
};

let am_font_family_from_settings = get_or_load_font_family(&am_font_name, ctx);
Expand Down
14 changes: 3 additions & 11 deletions app/src/autoupdate/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,12 @@ mod appimage {
if downloaded - last_reported >= REPORT_BYTES_THRESHOLD
|| last_reported_at.elapsed() >= REPORT_TIME_THRESHOLD
{
on_progress(DownloadProgress {
downloaded,
total,
});
on_progress(DownloadProgress { downloaded, total });
last_reported = downloaded;
last_reported_at = Instant::now();
}
}
on_progress(DownloadProgress {
downloaded,
total,
});
on_progress(DownloadProgress { downloaded, total });

// openWarp:在覆盖原 AppImage 之前先对临时文件做 SHA-256 校验,
// 防御 CDN 中间人 / 网络损坏。其他 channel 跳过(有自家流程)。
Expand Down Expand Up @@ -395,9 +389,7 @@ impl PackageManager {
.output();
let output = match output {
Ok(o) => o,
Err(err) => {
return Err(err).context("Failed to run package manager detection script")
}
Err(err) => return Err(err).context("Failed to run package manager detection script"),
};

// exit 1 = 这个候选名没被任何 PM 识别;不是错,继续下一个候选。
Expand Down
Loading