mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-14 18:03:41 +08:00
e48d83067a
* feat: show a zoom indicator in the desktop tab bar Reserve the right edge of the tab row for a ZOOM pill while the focused pane is zoomed, matching the accent style of the mode bars. The per-tab Z suffix stays; the pill makes the zoomed state visible at a glance like tmux's status-right flag. * feat: optionally show the hostname in the desktop tab bar Add ui.tab_bar_hostname to display the machine's hostname at the right edge of the tab row, like tmux's #h in status-right. The value resolves where the server renders, so remote sessions show the remote host. Off by default. * fix: strip control characters from the tab bar hostname * fix: hide the hostname when it would squeeze out the tab strip * feat: add configurable tab bar status * fix: harden tab bar status updates * fix: terminate tab bar status process trees * fix: disable status commands on unsupported platforms * fix: skip unchanged status command renders * fix: keep tab bar status opt-in by default --------- Co-authored-by: David Heinemeier Hansson <david@hey.com>
169 lines
5.7 KiB
Rust
169 lines
5.7 KiB
Rust
//! Internal app events delivered via channel.
|
|
//!
|
|
//! Background tasks (PTY child watchers, future hook listeners, etc.) send
|
|
//! events to the main loop through this channel. No polling needed.
|
|
|
|
use std::time::Instant;
|
|
|
|
use crate::detect::{Agent, AgentState};
|
|
use crate::layout::PaneId;
|
|
use crate::workspace::{GitStatusCacheEntry, WorkspaceGitStatus};
|
|
|
|
#[derive(Debug)]
|
|
pub struct ApiWorktreeAddRequest {
|
|
pub id: String,
|
|
pub operation_id: u64,
|
|
pub checkout_key: std::path::PathBuf,
|
|
pub source_workspace_id: Option<String>,
|
|
pub source_existing_membership: Option<crate::workspace::WorktreeSpaceMembership>,
|
|
pub source_checkout_path: std::path::PathBuf,
|
|
pub source_repo_root: std::path::PathBuf,
|
|
pub repo_key: String,
|
|
pub repo_name: String,
|
|
pub label: Option<String>,
|
|
pub focus: bool,
|
|
pub respond_to: std::sync::mpsc::Sender<String>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct WorktreeAddResult {
|
|
pub path: std::path::PathBuf,
|
|
pub api_request: Option<ApiWorktreeAddRequest>,
|
|
pub result: Result<(), String>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct ApiWorktreeRemoveRequest {
|
|
pub id: String,
|
|
pub operation_id: u64,
|
|
pub checkout_key: std::path::PathBuf,
|
|
pub respond_to: std::sync::mpsc::Sender<String>,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct WorktreeRemoveResult {
|
|
pub workspace_id: String,
|
|
pub path: std::path::PathBuf,
|
|
pub workspace: Option<Box<crate::api::schema::WorkspaceInfo>>,
|
|
pub worktree: Option<Box<crate::api::schema::WorktreeInfo>>,
|
|
pub forced: bool,
|
|
pub api_request: Option<ApiWorktreeRemoveRequest>,
|
|
pub result: Result<(), String>,
|
|
}
|
|
|
|
/// An event from a background task to the main loop.
|
|
#[derive(Debug)]
|
|
pub enum AppEvent {
|
|
/// A pane's child process exited.
|
|
PaneDied { pane_id: PaneId },
|
|
/// Fallback detector state changed in a pane.
|
|
StateChanged {
|
|
pane_id: PaneId,
|
|
agent: Option<Agent>,
|
|
state: AgentState,
|
|
visible_blocker: bool,
|
|
visible_working: bool,
|
|
process_exited: bool,
|
|
observed_at: Instant,
|
|
},
|
|
/// Hook-authoritative agent state was reported for a pane.
|
|
HookStateReported {
|
|
pane_id: PaneId,
|
|
source: String,
|
|
agent_label: String,
|
|
state: AgentState,
|
|
message: Option<String>,
|
|
seq: Option<u64>,
|
|
session_ref: Option<crate::agent_resume::AgentSessionRef>,
|
|
},
|
|
/// Agent session identity was reported without state authority.
|
|
AgentSessionReported {
|
|
pane_id: PaneId,
|
|
source: String,
|
|
agent_label: String,
|
|
seq: Option<u64>,
|
|
session_ref: Option<crate::agent_resume::AgentSessionRef>,
|
|
session_start_source: Option<String>,
|
|
},
|
|
/// Display-only agent metadata was reported for a pane.
|
|
HookMetadataReported {
|
|
pane_id: PaneId,
|
|
source: String,
|
|
agent_label: Option<String>,
|
|
applies_to_source: Option<String>,
|
|
title: Option<String>,
|
|
display_agent: Option<String>,
|
|
state_labels: std::collections::HashMap<String, String>,
|
|
clear_title: bool,
|
|
clear_display_agent: bool,
|
|
clear_state_labels: bool,
|
|
seq: Option<u64>,
|
|
ttl: Option<std::time::Duration>,
|
|
},
|
|
/// Hook authority was explicitly cleared for a pane.
|
|
HookAuthorityCleared {
|
|
pane_id: PaneId,
|
|
source: Option<String>,
|
|
seq: Option<u64>,
|
|
},
|
|
/// The current detected agent gracefully released this pane back to the shell.
|
|
HookAgentReleased {
|
|
pane_id: PaneId,
|
|
source: String,
|
|
agent_label: String,
|
|
known_agent: Option<Agent>,
|
|
seq: Option<u64>,
|
|
},
|
|
/// A new version is available through the active installation manager.
|
|
UpdateReady {
|
|
version: String,
|
|
install_command: String,
|
|
},
|
|
/// Remote agent detection manifest update check finished.
|
|
AgentDetectionManifestsUpdated {
|
|
updated: Vec<crate::detect::manifest_update::ManifestUpdateCommit>,
|
|
status: crate::detect::manifest_update::ManifestUpdateStatus,
|
|
},
|
|
/// A pane child emitted one or more executable BEL characters.
|
|
/// The host-facing process forwards them to its outer terminal.
|
|
TerminalBell { pane_id: PaneId, count: u16 },
|
|
/// A pane child emitted a valid OSC 52 clipboard write. The main loop
|
|
/// re-emits it through herdr's own clipboard writer.
|
|
ClipboardWrite { content: Vec<u8> },
|
|
/// Prefix-mode ASCII input-source request, emitted on entering/leaving the ASCII input
|
|
/// realm. The foreground process applies the host-local TIS switch (`active = true`) /
|
|
/// restore (`active = false`): the client in server mode (via server forwarding), the
|
|
/// app itself in monolithic mode.
|
|
PrefixInputSource { active: bool },
|
|
/// A pane child reported its shell current directory through terminal
|
|
/// metadata such as OSC 7.
|
|
TerminalCwdReported {
|
|
pane_id: PaneId,
|
|
cwd: std::path::PathBuf,
|
|
},
|
|
/// Background git status refresh completed for workspaces.
|
|
GitStatusRefreshed {
|
|
results: Vec<WorkspaceGitStatus>,
|
|
cache_updates: Vec<(std::path::PathBuf, GitStatusCacheEntry)>,
|
|
},
|
|
/// A configured tab bar status command finished.
|
|
TabBarCommandFinished {
|
|
generation: u64,
|
|
segment_index: usize,
|
|
result: Result<Option<String>, String>,
|
|
},
|
|
/// A plugin action or event command finished.
|
|
PluginCommandFinished {
|
|
log_id: String,
|
|
finished_unix_ms: u64,
|
|
exit_code: Option<i32>,
|
|
stdout: String,
|
|
stderr: String,
|
|
error: Option<String>,
|
|
},
|
|
/// Background `git worktree add` completed.
|
|
WorktreeAddFinished(Box<WorktreeAddResult>),
|
|
/// Background `git worktree remove` completed.
|
|
WorktreeRemoveFinished(Box<WorktreeRemoveResult>),
|
|
}
|