§9 acceptance: grep-zero sweep — every internal x.ai/grok identifier renamed
The PRD's first acceptance gate now holds: grep -RinE '\bx\.ai\b|grok' crates/ --include='*.rs' → 0 matches (exempt: NOTICE and third-party license archives, README provenance, and the required 'Based on Grok Build Open Source' attribution, now sourced from version_attribution.txt). Wire-visible renames (both sides in this repo, changed in lockstep): - Auth method id 'grok.com' → 'kimi-code' (AuthMethodKind::KimiCode). - Every x.ai/* and _x.ai/* ACP ext method and meta key → kigi/* / _kigi/* (~200 names; grokShell → kigiShell). Session-file replay keeps a read-side alias for the legacy '_x.ai/session/update' method so existing updates.jsonl histories load; writes emit only the new name (both directions test-pinned). - Agent types grok-build* → kigi* with a documented legacy-prefix alias at resolution time so persisted sessions keep resolving. - ToolNamespace/BuiltinAgentName GrokBuild* → Kigi* (wire snake_case kigi/kigi_concise/kigi_hashline; schema regenerated); grok_build implementation dirs renamed to kigi*. - x-grok-* headers → x-kigi-*, __GROK_* sentinels → __KIGI_*, themes grokday/groknight → kigiday/kiginight (old persisted values fall back to the default theme), web_fetch allowlist xAI hosts → kimi.com + moonshot platforms, changelog CDN → this repo, grok-build changelog archives deleted. - BYOK default endpoint removed: [endpoints] api_base_url is now truly optional with NO default — consumers fail fast with the flag name when unset (no silent x.ai egress). Mock harnesses inject it explicitly. - System-prompt identity fixed: 'released by xAI' → 'an unofficial community CLI for Kimi' (template + regenerated encrypted form). Also repaired pre-existing grok-era test debt found by the sweep: the stale trace_classify default-model pin, the grok-pager UA label test, pty-harness stale-binary reuse and non-hermetic moonshot routing (a PTY test could previously reach the real api.moonshot.cn), and the outdated oauth fixture scope key. Gates: §9 grep 0; fmt clean; workspace check/clippy 0/0 (-D warnings); FULL cargo test --workspace: 234 suites, 21,961 passed, 0 failed; deny advisories ok.
This commit is contained in:
@@ -80,7 +80,7 @@ impl Default for TitleConfig {
|
||||
TitleItem::Spinner,
|
||||
TitleItem::Activity,
|
||||
TitleItem::SessionName,
|
||||
TitleItem::Grok,
|
||||
TitleItem::Kigi,
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ pub enum TitleItem {
|
||||
Cwd,
|
||||
Model,
|
||||
TurnTimer,
|
||||
Grok,
|
||||
Kigi,
|
||||
ActionRequired,
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@ session_recap_threshold_secs = 30
|
||||
# Set the terminal/tab title to reflect agent state.
|
||||
enabled = true
|
||||
# Items shown in the title. Options: action-required, spinner, activity,
|
||||
# session-name, cwd, model, turn-timer, grok
|
||||
items = [\"action-required\", \"spinner\", \"activity\", \"session-name\", \"grok\"]
|
||||
# session-name, cwd, model, turn-timer, kigi
|
||||
items = [\"action-required\", \"spinner\", \"activity\", \"session-name\", \"kigi\"]
|
||||
|
||||
# [[ui.notifications.hooks]]
|
||||
# command = \"terminal-notifier -title 'Grok' -message '$KIGI_MESSAGE'\"
|
||||
# command = \"terminal-notifier -title 'Kigi' -message '$KIGI_MESSAGE'\"
|
||||
# events = [\"turn_complete\", \"approval_required\"]
|
||||
# only_unfocused = true
|
||||
# timeout_secs = 10
|
||||
@@ -210,7 +210,7 @@ mod tests {
|
||||
session_recap_threshold_secs: 90,
|
||||
title: TitleConfig {
|
||||
enabled: false,
|
||||
items: vec![TitleItem::Grok, TitleItem::Cwd],
|
||||
items: vec![TitleItem::Kigi, TitleItem::Cwd],
|
||||
},
|
||||
hooks: vec![NotificationHook {
|
||||
command: "notify-send".into(),
|
||||
|
||||
@@ -94,7 +94,7 @@ mod tests {
|
||||
fn test_event() -> NotificationEvent {
|
||||
NotificationEvent {
|
||||
kind: NotificationEventKind::TurnComplete,
|
||||
title: "Grok".into(),
|
||||
title: "Kigi".into(),
|
||||
body: "test body payload".into(),
|
||||
session_id: Some("test-session-123".into()),
|
||||
}
|
||||
|
||||
@@ -204,7 +204,7 @@ impl NotificationService {
|
||||
}
|
||||
|
||||
pub fn shutdown(&mut self) {
|
||||
// Reset the tab title back to "grok" so it doesn't linger on the
|
||||
// Reset the tab title back to "kigi" so it doesn't linger on the
|
||||
// last activity label after exit.
|
||||
let title_esc = self.title_manager.reset();
|
||||
kigi_shell::util::with_locked_stderr(|stderr| {
|
||||
@@ -471,7 +471,7 @@ mod tests {
|
||||
});
|
||||
svc.notify(NotificationEvent {
|
||||
kind: NotificationEventKind::TurnComplete,
|
||||
title: "Grok".into(),
|
||||
title: "Kigi".into(),
|
||||
body: "Turn complete".into(),
|
||||
session_id: Some("test-session".into()),
|
||||
});
|
||||
@@ -486,7 +486,7 @@ mod tests {
|
||||
});
|
||||
svc.notify(NotificationEvent {
|
||||
kind: NotificationEventKind::SessionReady,
|
||||
title: "Grok".into(),
|
||||
title: "Kigi".into(),
|
||||
body: "Session ready".into(),
|
||||
session_id: None,
|
||||
});
|
||||
@@ -743,7 +743,7 @@ mod tests {
|
||||
// crash regardless of suppression state.
|
||||
svc.notify(NotificationEvent {
|
||||
kind: NotificationEventKind::TurnComplete,
|
||||
title: "Grok".into(),
|
||||
title: "Kigi".into(),
|
||||
body: "Done".into(),
|
||||
session_id: None,
|
||||
});
|
||||
|
||||
@@ -85,7 +85,7 @@ mod tests {
|
||||
TerminalName::AppleTerminal,
|
||||
TerminalName::VsCode,
|
||||
TerminalName::WarpTerminal,
|
||||
TerminalName::GrokDesktop,
|
||||
TerminalName::KigiDesktop,
|
||||
TerminalName::Vte,
|
||||
TerminalName::Unknown,
|
||||
];
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::terminal::{MultiplexerKind, TerminalContext, TerminalName};
|
||||
pub enum NotificationProtocol {
|
||||
/// iTerm2/WezTerm/Warp: `\x1b]9;{message}\x07`
|
||||
Osc9,
|
||||
/// Kitty: `\x1b]99;i=grok;{message}\x1b\\`
|
||||
/// Kitty: `\x1b]99;i=kigi;{message}\x1b\\`
|
||||
Osc99,
|
||||
/// Ghostty/VTE: `\x1b]777;notify;{title};{body}\x1b\\`
|
||||
Osc777,
|
||||
@@ -45,7 +45,7 @@ pub fn select_protocol(ctx: &TerminalContext) -> NotificationProtocol {
|
||||
| TerminalName::Vte
|
||||
| TerminalName::Terminator
|
||||
| TerminalName::Foot => NotificationProtocol::Osc777,
|
||||
TerminalName::GrokDesktop => NotificationProtocol::None,
|
||||
TerminalName::KigiDesktop => NotificationProtocol::None,
|
||||
TerminalName::AppleTerminal
|
||||
| TerminalName::Alacritty
|
||||
| TerminalName::Rio
|
||||
@@ -78,8 +78,8 @@ pub fn emit_notification(
|
||||
// the app name to avoid showing the session name twice.
|
||||
let sequence: Cow<'_, str> = match protocol {
|
||||
NotificationProtocol::Osc9 => format!("\x1b]9;{body} \u{b7} {title}\x07").into(),
|
||||
NotificationProtocol::Osc99 => format!("\x1b]99;i=grok;{body} \u{b7} {title}\x1b\\").into(),
|
||||
NotificationProtocol::Osc777 => format!("\x1b]777;notify;Grok;{body}\x1b\\").into(),
|
||||
NotificationProtocol::Osc99 => format!("\x1b]99;i=kigi;{body} \u{b7} {title}\x1b\\").into(),
|
||||
NotificationProtocol::Osc777 => format!("\x1b]777;notify;Kigi;{body}\x1b\\").into(),
|
||||
NotificationProtocol::Bel => Cow::Borrowed("\x07"),
|
||||
NotificationProtocol::None => return,
|
||||
};
|
||||
@@ -175,9 +175,9 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn select_grok_desktop_uses_none() {
|
||||
fn select_kigi_desktop_uses_none() {
|
||||
assert_eq!(
|
||||
select_protocol(&ctx_with_brand(TerminalName::GrokDesktop)),
|
||||
select_protocol(&ctx_with_brand(TerminalName::KigiDesktop)),
|
||||
NotificationProtocol::None
|
||||
);
|
||||
}
|
||||
@@ -302,7 +302,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn emit_none_is_noop() {
|
||||
let ctx = ctx_with_brand(TerminalName::GrokDesktop);
|
||||
let ctx = ctx_with_brand(TerminalName::KigiDesktop);
|
||||
// Should return immediately without writing anything.
|
||||
emit_notification(NotificationProtocol::None, "title", "body", &ctx);
|
||||
}
|
||||
@@ -343,7 +343,7 @@ mod tests {
|
||||
(TerminalName::Ghostty, NotificationProtocol::Osc777),
|
||||
(TerminalName::Vte, NotificationProtocol::Osc777),
|
||||
(TerminalName::Foot, NotificationProtocol::Osc777),
|
||||
(TerminalName::GrokDesktop, NotificationProtocol::None),
|
||||
(TerminalName::KigiDesktop, NotificationProtocol::None),
|
||||
(TerminalName::AppleTerminal, NotificationProtocol::Bel),
|
||||
(TerminalName::Alacritty, NotificationProtocol::Bel),
|
||||
(TerminalName::VsCode, NotificationProtocol::Bel),
|
||||
|
||||
@@ -63,7 +63,7 @@ impl SleepInhibitor {
|
||||
#[cfg(target_os = "macos")]
|
||||
fn platform_inhibit(&self) -> bool {
|
||||
let mut assertion_id: u32 = 0;
|
||||
let reason = core_foundation::string::CFString::new("grok: agent turn in progress");
|
||||
let reason = core_foundation::string::CFString::new("kigi: agent turn in progress");
|
||||
let assertion_type =
|
||||
core_foundation::string::CFString::from_static_string("NoIdleSleepAssertion");
|
||||
|
||||
@@ -102,7 +102,7 @@ impl SleepInhibitor {
|
||||
let mut cmd = std::process::Command::new("systemd-inhibit");
|
||||
cmd.args([
|
||||
"--what=idle",
|
||||
"--who=grok",
|
||||
"--who=kigi",
|
||||
"--why=agent turn in progress",
|
||||
"sleep",
|
||||
"infinity",
|
||||
|
||||
@@ -89,7 +89,7 @@ impl TitleManager {
|
||||
|
||||
if !has_parts {
|
||||
self.composed.clear();
|
||||
self.composed.push_str("grok");
|
||||
self.composed.push_str("kigi");
|
||||
}
|
||||
|
||||
let result = if self.composed != self.last_title {
|
||||
@@ -113,9 +113,9 @@ impl TitleManager {
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) -> String {
|
||||
let esc = build_title_escape("grok");
|
||||
let esc = build_title_escape("kigi");
|
||||
self.last_title.clear();
|
||||
self.last_title.push_str("grok");
|
||||
self.last_title.push_str("kigi");
|
||||
self.spinner_frame = 0;
|
||||
self.tick_count = 0;
|
||||
esc
|
||||
@@ -132,9 +132,9 @@ fn write_item(
|
||||
tick_count: u64,
|
||||
) -> bool {
|
||||
match item {
|
||||
TitleItem::Grok => {
|
||||
TitleItem::Kigi => {
|
||||
push_separator(buf, has_parts);
|
||||
buf.push_str("grok");
|
||||
buf.push_str("kigi");
|
||||
}
|
||||
TitleItem::Spinner => {
|
||||
if !state.is_busy && state.activity.is_none() {
|
||||
@@ -267,7 +267,7 @@ fn write_truncated(buf: &mut String, s: &str, max: usize) {
|
||||
/// the frame pipeline.
|
||||
///
|
||||
/// Control characters are stripped here: title parts include remote-sourced
|
||||
/// strings (e.g. grok.com conversation titles), which must not terminate the
|
||||
/// strings (e.g. kimi.com conversation titles), which must not terminate the
|
||||
/// OSC sequence early or inject escapes into the terminal.
|
||||
fn build_title_escape(title: &str) -> String {
|
||||
let sanitized: String = title.chars().filter(|c| !c.is_control()).collect();
|
||||
@@ -307,55 +307,55 @@ mod tests {
|
||||
// --- Title composition tests ---
|
||||
|
||||
#[test]
|
||||
fn grok_only_produces_just_grok() {
|
||||
let cfg = config_with_items(vec![TitleItem::Grok]);
|
||||
fn kigi_only_produces_just_kigi() {
|
||||
let cfg = config_with_items(vec![TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = idle_state();
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_name_and_grok_joined_with_separator() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
|
||||
fn session_name_and_kigi_joined_with_separator() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
session_name: Some("my project"),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "my project - grok");
|
||||
assert_eq!(mgr.last_title, "my project - kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn missing_session_name_skipped() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = idle_state();
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_session_name_skipped() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
session_name: Some(""),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spinner_only_shown_when_active() {
|
||||
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
|
||||
// Idle: spinner absent
|
||||
mgr.update(&idle_state());
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
|
||||
// Active: spinner present
|
||||
let activity = TurnActivity::Thinking;
|
||||
@@ -364,7 +364,7 @@ mod tests {
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert!(mgr.last_title.contains(" - grok"));
|
||||
assert!(mgr.last_title.contains(" - kigi"));
|
||||
let spinner_part: String = mgr.last_title.chars().take(1).collect();
|
||||
assert!(
|
||||
TITLE_SPINNER.contains(&spinner_part.chars().next().unwrap()),
|
||||
@@ -522,22 +522,22 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn activity_hidden_when_idle() {
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
mgr.update(&idle_state());
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spinner_shown_when_busy_without_activity() {
|
||||
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Spinner, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
is_busy: true,
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert!(mgr.last_title.contains(" - grok"));
|
||||
assert!(mgr.last_title.contains(" - kigi"));
|
||||
let spinner_part: String = mgr.last_title.chars().take(1).collect();
|
||||
assert!(
|
||||
TITLE_SPINNER.contains(&spinner_part.chars().next().unwrap()),
|
||||
@@ -548,19 +548,19 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn activity_shows_waiting_when_busy_without_activity() {
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
is_busy: true,
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "Waiting - grok");
|
||||
assert_eq!(mgr.last_title, "Waiting - kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn activity_prefers_specific_activity_over_waiting() {
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Activity, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let activity = TurnActivity::Thinking;
|
||||
let state = TitleState {
|
||||
@@ -569,14 +569,14 @@ mod tests {
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "Thinking - grok");
|
||||
assert_eq!(mgr.last_title, "Thinking - kigi");
|
||||
}
|
||||
|
||||
// --- Action Required blinking ---
|
||||
|
||||
#[test]
|
||||
fn action_required_visible_on_first_tick() {
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
has_pending_permissions: true,
|
||||
@@ -594,7 +594,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn action_required_blinks_across_ticks() {
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
has_pending_permissions: true,
|
||||
@@ -626,28 +626,28 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn action_required_hidden_when_no_permissions() {
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::ActionRequired, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
has_pending_permissions: false,
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
// --- Dedup (no-op when unchanged) ---
|
||||
|
||||
#[test]
|
||||
fn dedup_skips_emission_when_unchanged() {
|
||||
let cfg = config_with_items(vec![TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = idle_state();
|
||||
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
|
||||
// Second update: title is identical, last_title stays the same (no re-emit).
|
||||
let title_before = mgr.last_title.clone();
|
||||
@@ -658,73 +658,73 @@ mod tests {
|
||||
// --- Empty items list ---
|
||||
|
||||
#[test]
|
||||
fn empty_items_produces_grok_fallback() {
|
||||
fn empty_items_produces_kigi_fallback() {
|
||||
let cfg = config_with_items(vec![]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
mgr.update(&idle_state());
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
// --- Model item ---
|
||||
|
||||
#[test]
|
||||
fn model_item_shown_when_present() {
|
||||
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
model: Some("grok-3"),
|
||||
model: Some("kigi-3"),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok-3 - grok");
|
||||
assert_eq!(mgr.last_title, "kigi-3 - kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn model_item_hidden_when_none() {
|
||||
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Model, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
mgr.update(&idle_state());
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
// --- Cwd item ---
|
||||
|
||||
#[test]
|
||||
fn cwd_shows_last_component() {
|
||||
let cfg = config_with_items(vec![TitleItem::Cwd, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::Cwd, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
cwd: Some("/home/user/my-project"),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "my-project - grok");
|
||||
assert_eq!(mgr.last_title, "my-project - kigi");
|
||||
}
|
||||
|
||||
// --- TurnTimer item ---
|
||||
|
||||
#[test]
|
||||
fn turn_timer_shown_when_above_one_second() {
|
||||
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
turn_elapsed: Some(std::time::Duration::from_secs(42)),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "42s - grok");
|
||||
assert_eq!(mgr.last_title, "42s - kigi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn turn_timer_hidden_when_under_one_second() {
|
||||
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Grok]);
|
||||
let cfg = config_with_items(vec![TitleItem::TurnTimer, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let state = TitleState {
|
||||
turn_elapsed: Some(std::time::Duration::from_millis(500)),
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
// --- Truncation ---
|
||||
@@ -759,8 +759,8 @@ mod tests {
|
||||
// --- Reset ---
|
||||
|
||||
#[test]
|
||||
fn reset_clears_state_and_emits_grok() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Grok]);
|
||||
fn reset_clears_state_and_emits_kigi() {
|
||||
let cfg = config_with_items(vec![TitleItem::SessionName, TitleItem::Kigi]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let activity = TurnActivity::Thinking;
|
||||
let state = TitleState {
|
||||
@@ -769,10 +769,10 @@ mod tests {
|
||||
..idle_state()
|
||||
};
|
||||
mgr.update(&state);
|
||||
assert_ne!(mgr.last_title, "grok");
|
||||
assert_ne!(mgr.last_title, "kigi");
|
||||
|
||||
mgr.reset();
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
assert_eq!(mgr.spinner_frame, 0);
|
||||
assert_eq!(mgr.tick_count, 0);
|
||||
}
|
||||
@@ -805,7 +805,7 @@ mod tests {
|
||||
|
||||
// Both should contain the persistent parts.
|
||||
for t in [&t1, &t2] {
|
||||
assert!(t.contains("grok"), "title missing 'grok': {t}");
|
||||
assert!(t.contains("kigi"), "title missing 'kigi': {t}");
|
||||
assert!(t.contains("Responding"), "title missing 'Responding': {t}");
|
||||
assert!(t.contains("my-session"), "title missing session name: {t}");
|
||||
}
|
||||
@@ -820,7 +820,7 @@ mod tests {
|
||||
let cfg = default_config();
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
mgr.update(&idle_state());
|
||||
assert_eq!(mgr.last_title, "grok");
|
||||
assert_eq!(mgr.last_title, "kigi");
|
||||
}
|
||||
|
||||
// --- Multi-item combinations ---
|
||||
@@ -832,13 +832,13 @@ mod tests {
|
||||
TitleItem::SessionName,
|
||||
TitleItem::Model,
|
||||
TitleItem::Cwd,
|
||||
TitleItem::Grok,
|
||||
TitleItem::Kigi,
|
||||
]);
|
||||
let mut mgr = TitleManager::new(&cfg);
|
||||
let activity = TurnActivity::Thinking;
|
||||
let state = TitleState {
|
||||
session_name: Some("proj"),
|
||||
model: Some("grok-3"),
|
||||
model: Some("kigi-3"),
|
||||
activity: Some(&activity),
|
||||
cwd: Some("/home/user/workspace"),
|
||||
..idle_state()
|
||||
@@ -846,7 +846,7 @@ mod tests {
|
||||
mgr.update(&state);
|
||||
assert_eq!(
|
||||
mgr.last_title,
|
||||
"Thinking - proj - grok-3 - workspace - grok"
|
||||
"Thinking - proj - kigi-3 - workspace - kigi"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user