Synced from monorepo
Changes: - Classify clipboard delivery confidence - Add durable session update append - Scope the xAI session bearer to first-party memory embedding endpoints - Persist subagent outputs to disk and bound long-lived agent state - Add MiniSweAgent:bash for mini-swe-agent parity - Revert taking local sessions off the persistent shell - Contextual tip recommending grok wrap on SSH sessions - Voice STT bearer from model BYOK env_key/api_key - Define exact website policies for sandbox - Gate unsafe shell environments - Shared pin hoist; single require_sha gate for marketplace plugins - Server-signed is-managed claim (closes sidecar-removal downgrade) - Optional require_sha pin for remote plugin installs - Show session title and last exchange in the exit resume hint - Gate shell output redirects - Warn when fail_closed is present but not a boolean - Add canonical text editing core (ratatui-textarea) - Keep execution state out of goal scratch - Add acknowledged persistence primitives - Inherit child network restrictions in sandbox - Fail closed when hook matchers fail to recompile - Add MCP setup preferences for plugin MCPs - Gate sourced shell scripts - Gate file-typed project hooks - grok wrap: restore terminal modes on child death - Harden owner-only permissions on auth and MCP credentials - Create crash dump files with owner-only permissions - Write the agent_id cache owner-only (0600) - SessionMetrics mode skips Mixpanel profile sync - Dashboard: slim live-tail peek - Yank full queued prompt text, not (+N lines) - Defeat clock-rollback on the signed managed-config cache - Stop early session/cancel from overtaking the prompt and wedging the turn slot - Self-heal a diverged agent entrypoint on startup - Add matched inference expectations in test-support - Add AuthSingleFlight cancel/successor gap tests - Remove consumer from external OTEL allowlist and pin scrub coverage - Enable /copy in minimal mode - Surface capacity and API-key detail on 429 errors - Single-flight interactive auth - Fix PageUp/PageDown skipping lines behind sticky prompt header
This commit is contained in:
parent
8adf9013a0
commit
98c3b2438a
225 changed files with 18836 additions and 7156 deletions
|
|
@ -26,3 +26,80 @@ pub enum WarningSeverity {
|
|||
/// Rendered in dim/gray. Informational, not actionable.
|
||||
Info,
|
||||
}
|
||||
|
||||
/// Pick the warning the single-slot welcome banner shows: the first
|
||||
/// `Warning`-severity entry, else the last entry.
|
||||
///
|
||||
/// `startup_warnings` is appended to at runtime while the user sits on the
|
||||
/// welcome screen (session-start failures, Claude import results), so a plain
|
||||
/// `first()` lets an early entry mask that later feedback — e.g. an import
|
||||
/// Info result at index 0 hides a session-start Warning pushed behind it.
|
||||
/// Severity decides first (a real Warning always beats an Info; among
|
||||
/// Warnings, assemble order stays authoritative); a Warning-less list falls
|
||||
/// back to the **last** entry because later Info pushes are direct
|
||||
/// user-action feedback that must not be masked by an older Info. Every
|
||||
/// banner surface (height calc + render) must pick through here so they
|
||||
/// cannot disagree.
|
||||
pub fn banner_warning(warnings: &[StartupWarning]) -> Option<&StartupWarning> {
|
||||
warnings
|
||||
.iter()
|
||||
.find(|w| w.severity == WarningSeverity::Warning)
|
||||
.or_else(|| warnings.last())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn entry(severity: WarningSeverity, message: &str) -> StartupWarning {
|
||||
StartupWarning {
|
||||
severity,
|
||||
message: message.to_string(),
|
||||
action: None,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_warning_empty_is_none() {
|
||||
assert!(banner_warning(&[]).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_warning_lone_info_shows() {
|
||||
let list = [entry(WarningSeverity::Info, "info note")];
|
||||
assert_eq!(banner_warning(&list).unwrap().message, "info note");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_warning_runtime_pushed_warning_displaces_info() {
|
||||
// An Info entry holds index 0 (e.g. a Claude import result). A
|
||||
// Warning pushed later (e.g. "Not inside a git repository") must
|
||||
// still win the single banner slot.
|
||||
let list = [
|
||||
entry(WarningSeverity::Info, "info note"),
|
||||
entry(WarningSeverity::Warning, "real problem"),
|
||||
];
|
||||
assert_eq!(banner_warning(&list).unwrap().message, "real problem");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_warning_runtime_pushed_info_displaces_earlier_info() {
|
||||
// Warning-less list: a later Info push is direct user-action
|
||||
// feedback (e.g. a Claude import result) and wins over an older Info.
|
||||
let list = [
|
||||
entry(WarningSeverity::Info, "info note"),
|
||||
entry(WarningSeverity::Info, "import result"),
|
||||
];
|
||||
assert_eq!(banner_warning(&list).unwrap().message, "import result");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn banner_warning_first_warning_wins_among_warnings() {
|
||||
let list = [
|
||||
entry(WarningSeverity::Warning, "first"),
|
||||
entry(WarningSeverity::Warning, "second"),
|
||||
entry(WarningSeverity::Info, "info note"),
|
||||
];
|
||||
assert_eq!(banner_warning(&list).unwrap().message, "first");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue