§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:
@@ -1496,7 +1496,7 @@ mod searchable_text_tests {
|
||||
b.subagent_type = "explore".into();
|
||||
b.persona = Some("scout".into());
|
||||
b.role = Some("researcher".into());
|
||||
b.model = Some("grok-test".into());
|
||||
b.model = Some("kigi-test".into());
|
||||
b.activity_label = Some("Running: cargo build".into());
|
||||
}
|
||||
let text = block.searchable_text().expect("subagent text");
|
||||
@@ -1504,7 +1504,7 @@ mod searchable_text_tests {
|
||||
assert!(text.contains("explore"), "got: {text:?}");
|
||||
assert!(text.contains("scout"), "got: {text:?}");
|
||||
assert!(text.contains("researcher"), "got: {text:?}");
|
||||
assert!(text.contains("grok-test"), "got: {text:?}");
|
||||
assert!(text.contains("kigi-test"), "got: {text:?}");
|
||||
assert!(text.contains("Running: cargo build"), "got: {text:?}");
|
||||
assert!(text.contains("panicked at assert"), "got: {text:?}");
|
||||
}
|
||||
@@ -1539,9 +1539,9 @@ mod searchable_text_tests {
|
||||
auto_compact_threshold_percent: 85,
|
||||
usage_categories: vec![],
|
||||
};
|
||||
let block = RenderBlock::context_info(snapshot, "grok-4.5");
|
||||
let block = RenderBlock::context_info(snapshot, "kigi-4.5");
|
||||
// Only the model name is source text; the rest is a numeric breakdown.
|
||||
assert_eq!(block.searchable_text().as_deref(), Some("grok-4.5"));
|
||||
assert_eq!(block.searchable_text().as_deref(), Some("kigi-4.5"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -466,7 +466,7 @@ mod tests {
|
||||
#[test]
|
||||
fn preamble_uses_primary_text_color_for_description() {
|
||||
// Pin theme to avoid races with parallel tests that call `cache::set`.
|
||||
crate::theme::cache::set(crate::theme::ThemeKind::GrokNight);
|
||||
crate::theme::cache::set(crate::theme::ThemeKind::KigiNight);
|
||||
let block =
|
||||
BgTaskBlock::started("ls", "t1").with_description(Some("List the files".into()));
|
||||
let text = block.preamble(&test_ctx()).expect("preamble");
|
||||
|
||||
@@ -24,7 +24,7 @@ use kigi_shell::session::{ContextInfo, count_detail};
|
||||
/// Context
|
||||
///
|
||||
/// 36.7k / 1.0m tokens (3.67%)
|
||||
/// grok-4
|
||||
/// kigi-4
|
||||
///
|
||||
/// ◆ ◆ ◆ ◆ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇
|
||||
/// ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇ ◇
|
||||
@@ -467,7 +467,7 @@ impl ContextInfoBlock {
|
||||
// (routed from kigi-shell's model config resolution). This makes
|
||||
// the “Auto-compact at X%” line and the tip band match exactly what
|
||||
// remote settings / user TOML / env have configured for the
|
||||
// current model (e.g. 65 for grok-build).
|
||||
// current model (e.g. 65 for kigi).
|
||||
//
|
||||
// `threshold_tokens` uses `div_ceil` rather than truncating integer
|
||||
// division so it matches the rounded `usage_pct` from `ContextInfo`
|
||||
@@ -705,7 +705,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn build_lines_contains_header_tokens_and_model() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
// Layout: Context / <blank> / tokens / model.
|
||||
@@ -715,12 +715,12 @@ mod tests {
|
||||
assert!(l2.contains("tokens"));
|
||||
// Percent now shows 2 decimal places (36.7k / 1m = 3.67%).
|
||||
assert!(l2.contains("(3.67%)"), "got: {l2:?}");
|
||||
assert_eq!(line_text(&lines, 3), "grok-4");
|
||||
assert_eq!(line_text(&lines, 3), "kigi-4");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_lines_contains_tokens_summary() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let l2 = line_text(&lines, 2);
|
||||
@@ -747,7 +747,7 @@ mod tests {
|
||||
// line is also showing.
|
||||
let mut snap = snapshot();
|
||||
snap.usage_pct = 80;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let last = line_text(&lines, lines.len() - 1);
|
||||
@@ -756,7 +756,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn build_lines_omits_tip_below_threshold() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
assert!(!all_text(&lines).contains("/compact"));
|
||||
@@ -770,7 +770,7 @@ mod tests {
|
||||
// other (manual /compact vs. auto-compact about to fire).
|
||||
let mut snap = snapshot();
|
||||
snap.usage_pct = 85; // the historical default (and value in snapshot() helper)
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
assert!(!all_text(&lines).contains("/compact"));
|
||||
@@ -778,7 +778,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn build_lines_shows_auto_compact_estimate_below_threshold() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let all = all_text(&lines);
|
||||
@@ -796,7 +796,7 @@ mod tests {
|
||||
snap.total = 4_000_000;
|
||||
snap.used = 0;
|
||||
snap.usage_pct = 0;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let all = all_text(&lines);
|
||||
@@ -809,7 +809,7 @@ mod tests {
|
||||
#[test]
|
||||
fn build_lines_auto_compact_eta_arithmetic_at_known_snapshot() {
|
||||
// 1M window, 36_700 used: ceil(850_000) - 36_700 = 813_300 → "813k".
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let all = all_text(&lines);
|
||||
@@ -849,7 +849,7 @@ mod tests {
|
||||
let mut snap = snapshot();
|
||||
snap.total = 2_000_000;
|
||||
snap.used = 36_700;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let l2 = line_text(&lines, 2);
|
||||
@@ -863,7 +863,7 @@ mod tests {
|
||||
fn build_lines_shows_imminent_auto_compact_at_threshold() {
|
||||
let mut snap = snapshot();
|
||||
snap.usage_pct = 85;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let all = all_text(&lines);
|
||||
@@ -926,7 +926,7 @@ mod tests {
|
||||
snap.tool_definitions_tokens = 0;
|
||||
snap.free_tokens = 90_000;
|
||||
snap.usage_pct = 10;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let (diamonds, tools, free, total) = count_bar_glyphs(&lines, BarLayout::WIDE);
|
||||
@@ -941,7 +941,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn bar_total_cells_always_sum_to_one_hundred() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let (_, _, _, total) = count_bar_glyphs(&lines, BarLayout::WIDE);
|
||||
@@ -957,7 +957,7 @@ mod tests {
|
||||
snap.tool_definitions_tokens = 0;
|
||||
snap.message_tokens = 0;
|
||||
snap.free_tokens = 0;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let (diamonds, tools, free, total) = count_bar_glyphs(&lines, BarLayout::WIDE);
|
||||
@@ -979,7 +979,7 @@ mod tests {
|
||||
snap.message_tokens = 1_000;
|
||||
snap.free_tokens = 0;
|
||||
snap.usage_pct = 100;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let (diamonds, tools, free, total) = count_bar_glyphs(&lines, BarLayout::WIDE);
|
||||
@@ -999,7 +999,7 @@ mod tests {
|
||||
snap.tool_definitions_tokens = 800;
|
||||
snap.free_tokens = 0;
|
||||
snap.usage_pct = 100;
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let (diamonds, tools, free, total) = count_bar_glyphs(&lines, BarLayout::WIDE);
|
||||
@@ -1027,7 +1027,7 @@ mod tests {
|
||||
auto_compact_threshold_percent: 65,
|
||||
usage_categories: vec![],
|
||||
};
|
||||
let block = ContextInfoBlock::new(snap, "grok-build");
|
||||
let block = ContextInfoBlock::new(snap, "kigi");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
|
||||
@@ -1055,7 +1055,7 @@ mod tests {
|
||||
TokenUsageCategory::skills_listing(&"x".repeat(9_600), 21),
|
||||
TokenUsageCategory::mcp_servers(&"y".repeat(1_200), 4),
|
||||
];
|
||||
let block = ContextInfoBlock::new(snap, "grok-4");
|
||||
let block = ContextInfoBlock::new(snap, "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let all = all_text(&lines);
|
||||
@@ -1161,7 +1161,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn narrow_bar_renders_10_rows() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
// The bar starts at index 5 (header / blank / tokens / model /
|
||||
@@ -1179,7 +1179,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn narrow_bar_total_cells_still_100() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
let (_, _, _, total) = count_bar_glyphs(&lines, BarLayout::NARROW);
|
||||
@@ -1190,7 +1190,7 @@ mod tests {
|
||||
fn narrow_bar_each_row_has_at_most_10_cells() {
|
||||
// Sanity: no single bar row should exceed the narrow row_len.
|
||||
// We count cell glyphs (not separator spaces) per row.
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
for (offset, line) in lines[5..15].iter().enumerate() {
|
||||
@@ -1215,7 +1215,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn wide_bar_each_row_has_at_most_20_cells() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
for (offset, line) in lines[5..10].iter().enumerate() {
|
||||
@@ -1258,7 +1258,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn legend_label_uses_secondary_color_wide() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let row = find_legend_line(&lines, "System prompt").expect("legend row");
|
||||
@@ -1279,7 +1279,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn legend_label_uses_secondary_color_narrow() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
let row = find_legend_line(&lines, "System prompt").expect("legend row 1");
|
||||
@@ -1299,7 +1299,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn narrow_legend_wraps_to_two_lines_per_category() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
let categories = [
|
||||
@@ -1335,7 +1335,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn narrow_legend_data_row_starts_with_one_space_indent() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::NARROW);
|
||||
// The data row for the first legend entry sits at index 17
|
||||
@@ -1355,7 +1355,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn wide_legend_remains_single_line_per_category() {
|
||||
let block = ContextInfoBlock::new(snapshot(), "grok-4");
|
||||
let block = ContextInfoBlock::new(snapshot(), "kigi-4");
|
||||
let theme = test_theme();
|
||||
let lines = block.build_lines(&theme, BarLayout::WIDE);
|
||||
let row_text =
|
||||
|
||||
@@ -143,14 +143,14 @@ pub fn mermaid_block_ranges(view: &MarkdownRenderView) -> Vec<Range<usize>> {
|
||||
|
||||
/// Whether a theme renders diagrams on a dark surface.
|
||||
///
|
||||
/// `GrokDay` is the only light theme; every other concrete theme (and the
|
||||
/// `GrokNight` default that `Auto` resolves to before it reaches the cache) is
|
||||
/// `KigiDay` is the only light theme; every other concrete theme (and the
|
||||
/// `KigiNight` default that `Auto` resolves to before it reaches the cache) is
|
||||
/// dark. The render worker maps this to `kigi_mermaid::MermaidTheme`; it
|
||||
/// lives here (rather than referencing the engine crate) so the
|
||||
/// always-compiled detection module stays independent of the optional
|
||||
/// `mermaid` feature.
|
||||
pub fn theme_is_dark(theme: ThemeKind) -> bool {
|
||||
!matches!(theme, ThemeKind::GrokDay)
|
||||
!matches!(theme, ThemeKind::KigiDay)
|
||||
}
|
||||
|
||||
/// Cache key for a rendered diagram: content hash + theme + quality tier +
|
||||
@@ -580,7 +580,7 @@ mod tests {
|
||||
fn cache_key_sensitivity() {
|
||||
let dark = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
@@ -589,7 +589,7 @@ mod tests {
|
||||
dark,
|
||||
MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
)
|
||||
@@ -599,7 +599,7 @@ mod tests {
|
||||
dark,
|
||||
MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->C",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
)
|
||||
@@ -609,7 +609,7 @@ mod tests {
|
||||
dark,
|
||||
MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokDay,
|
||||
ThemeKind::KigiDay,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
)
|
||||
@@ -619,7 +619,7 @@ mod tests {
|
||||
dark,
|
||||
MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
160,
|
||||
MermaidRenderQuality::Terminal,
|
||||
)
|
||||
@@ -627,7 +627,7 @@ mod tests {
|
||||
// Quality tier change ⇒ different key (and filename).
|
||||
let open = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Open,
|
||||
);
|
||||
@@ -638,7 +638,7 @@ mod tests {
|
||||
open,
|
||||
MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
999,
|
||||
MermaidRenderQuality::Open,
|
||||
)
|
||||
@@ -650,20 +650,20 @@ mod tests {
|
||||
// Widths within the same bucket collapse to one key.
|
||||
let a = MermaidCacheKey::derive(
|
||||
"x",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
let b = MermaidCacheKey::derive(
|
||||
"x",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80 + MERMAID_WIDTH_BUCKET - 1,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
assert_eq!(a, b);
|
||||
let c = MermaidCacheKey::derive(
|
||||
"x",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80 + MERMAID_WIDTH_BUCKET,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
@@ -677,7 +677,7 @@ mod tests {
|
||||
let mut set = HashSet::new();
|
||||
let key = MermaidCacheKey::derive(
|
||||
"A-->B\n",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
@@ -685,7 +685,7 @@ mod tests {
|
||||
assert!(set.contains(&key));
|
||||
assert!(!set.contains(&MermaidCacheKey::derive(
|
||||
"A-->B\n",
|
||||
ThemeKind::GrokDay,
|
||||
ThemeKind::KigiDay,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
)));
|
||||
@@ -825,13 +825,13 @@ mod tests {
|
||||
// -- theme mapping + cache filename --------------------------------------
|
||||
|
||||
#[test]
|
||||
fn theme_is_dark_maps_grokday_to_light_only() {
|
||||
fn theme_is_dark_maps_kigiday_to_light_only() {
|
||||
assert!(
|
||||
!theme_is_dark(ThemeKind::GrokDay),
|
||||
"GrokDay is the light theme"
|
||||
!theme_is_dark(ThemeKind::KigiDay),
|
||||
"KigiDay is the light theme"
|
||||
);
|
||||
for dark in [
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
ThemeKind::TokyoNight,
|
||||
ThemeKind::RosePineMoon,
|
||||
ThemeKind::OscuraMidnight,
|
||||
@@ -844,7 +844,7 @@ mod tests {
|
||||
fn cache_filename_is_stable_and_keyed() {
|
||||
let a = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
@@ -860,21 +860,21 @@ mod tests {
|
||||
// Different theme / source / width → different filename.
|
||||
let b = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokDay,
|
||||
ThemeKind::KigiDay,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
assert_ne!(a.cache_filename(), b.cache_filename());
|
||||
let c = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->C",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Terminal,
|
||||
);
|
||||
assert_ne!(a.cache_filename(), c.cache_filename());
|
||||
let open = MermaidCacheKey::derive(
|
||||
"flowchart TD\nA-->B",
|
||||
ThemeKind::GrokNight,
|
||||
ThemeKind::KigiNight,
|
||||
80,
|
||||
MermaidRenderQuality::Open,
|
||||
);
|
||||
|
||||
@@ -794,13 +794,13 @@ mod tests {
|
||||
#[test]
|
||||
fn model_unavailable_with_switch() {
|
||||
let event = SessionEvent::ModelUnavailable {
|
||||
previous_model_id: "grok-4.5".into(),
|
||||
new_model_id: "grok-build".into(),
|
||||
reason: "Model \"grok-4.5\" is no longer available.".into(),
|
||||
previous_model_id: "kigi-4.5".into(),
|
||||
new_model_id: "kigi".into(),
|
||||
reason: "Model \"kigi-4.5\" is no longer available.".into(),
|
||||
};
|
||||
assert_eq!(
|
||||
event.message(),
|
||||
"Model \"grok-4.5\" is no longer available. Switched to \"grok-build\"."
|
||||
"Model \"kigi-4.5\" is no longer available. Switched to \"kigi\"."
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2418,13 +2418,13 @@ mod tests {
|
||||
type Rgb = (u8, u8, u8);
|
||||
type SyntectSpans = Vec<(Rgb, String)>;
|
||||
|
||||
/// Pins GrokNight via the shared test-lock guard; hold it for the whole
|
||||
/// Pins KigiNight via the shared test-lock guard; hold it for the whole
|
||||
/// test so a concurrent theme flip can't skew the compared highlighter walks.
|
||||
fn pin_groknight_syntect() -> std::sync::MutexGuard<'static, ()> {
|
||||
fn pin_kiginight_syntect() -> std::sync::MutexGuard<'static, ()> {
|
||||
let guard = crate::theme::cache::pin_theme();
|
||||
assert!(
|
||||
!Theme::groknight().diff_uses_line_fg(),
|
||||
"GrokNight must be banded for Equal-line syntect path in render"
|
||||
!Theme::kiginight().diff_uses_line_fg(),
|
||||
"KigiNight must be banded for Equal-line syntect path in render"
|
||||
);
|
||||
guard
|
||||
}
|
||||
@@ -2454,7 +2454,7 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Hunk-only: fresh highlighter, only the given lines in order (prod path).
|
||||
/// Caller pins the theme via `pin_groknight_syntect` (lock is not reentrant).
|
||||
/// Caller pins the theme via `pin_kiginight_syntect` (lock is not reentrant).
|
||||
fn hunk_only_raw_styles(path: &Path, lines: &[&str]) -> Vec<SyntectSpans> {
|
||||
let syntect = get_syntect();
|
||||
let mut hl = syntect
|
||||
@@ -2467,7 +2467,7 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Full-file then slice: silent HL from line 1, return styles for all lines.
|
||||
/// Caller pins the theme via `pin_groknight_syntect` (lock is not reentrant).
|
||||
/// Caller pins the theme via `pin_kiginight_syntect` (lock is not reentrant).
|
||||
fn full_file_raw_styles(path: &Path, file_text: &str) -> Vec<SyntectSpans> {
|
||||
let syntect = get_syntect();
|
||||
let mut hl = syntect
|
||||
@@ -2505,7 +2505,7 @@ class ProcessQueueItem(BaseModel):
|
||||
/// Control: self-contained Rust line → keyword RGB ≠ string RGB (raw syntect).
|
||||
#[test]
|
||||
fn syntax_highlight_splits_keyword_and_string_fg() {
|
||||
let _guard = pin_groknight_syntect();
|
||||
let _guard = pin_kiginight_syntect();
|
||||
let path = Path::new("probe.rs");
|
||||
let lines = hunk_only_raw_styles(path, &["let x = \"hello\";"]);
|
||||
assert_eq!(lines.len(), 1);
|
||||
@@ -2552,7 +2552,7 @@ class ProcessQueueItem(BaseModel):
|
||||
/// (and differ from cold hunk-only spill) after a mid-file closing `"""`.
|
||||
#[test]
|
||||
fn file_scoped_matches_full_file_on_field_line() {
|
||||
let _guard = pin_groknight_syntect();
|
||||
let _guard = pin_kiginight_syntect();
|
||||
let path = Path::new("queue_item.py");
|
||||
let (file, hunk, field_ln) = fixture_python_close_hunk();
|
||||
let close_ln = hunk[0].ln;
|
||||
@@ -2629,7 +2629,7 @@ class ProcessQueueItem(BaseModel):
|
||||
/// baked under another theme it must not paint — hunk-only output.
|
||||
#[test]
|
||||
fn file_scoped_stale_theme_falls_back_to_hunk_only() {
|
||||
let _guard = pin_groknight_syntect();
|
||||
let _guard = pin_kiginight_syntect();
|
||||
let path = Path::new("queue_item.py");
|
||||
let (file, hunk, field_ln) = fixture_python_close_hunk();
|
||||
// Real computed map: paintable by construction (line keys and texts
|
||||
@@ -2672,7 +2672,7 @@ class ProcessQueueItem(BaseModel):
|
||||
);
|
||||
|
||||
// Stale: the SAME paintable map baked under another theme is skipped.
|
||||
let stale = ThemeKind::GrokDay;
|
||||
let stale = ThemeKind::KigiDay;
|
||||
assert_ne!(stale, crate::theme::cache::current_kind());
|
||||
block.highlight = EditHighlightPhase::FileScoped {
|
||||
by_new_line,
|
||||
@@ -2739,7 +2739,7 @@ class ProcessQueueItem(BaseModel):
|
||||
/// after a mid-file closing `"""`.
|
||||
#[test]
|
||||
fn triple_quote_hunk_only_differs_from_full_file_today() {
|
||||
let _guard = pin_groknight_syntect();
|
||||
let _guard = pin_kiginight_syntect();
|
||||
let path = Path::new("queue_item.py");
|
||||
let (file, hunk, field_ln) = fixture_python_close_hunk();
|
||||
let close_ln = hunk[0].ln;
|
||||
|
||||
@@ -447,7 +447,7 @@ session content
|
||||
|
||||
#[test]
|
||||
fn shorten_memory_path() {
|
||||
// Paths under the configured grok memory root keep one trailing segment group.
|
||||
// Paths under the configured kigi memory root keep one trailing segment group.
|
||||
let memory_root = kigi_config::kigi_home().join("memory");
|
||||
let session = memory_root.join("xai-50aa78f0/sessions/2026-05-01.md");
|
||||
let top = memory_root.join("MEMORY.md");
|
||||
|
||||
@@ -656,7 +656,7 @@ mod tests {
|
||||
ToolCallBlock::ListDir(ListDirToolCallBlock::new("src")),
|
||||
ToolCallBlock::Search(SearchToolCallBlock::new("todo")),
|
||||
ToolCallBlock::WebFetch(WebFetchToolCallBlock::new("https://example.com")),
|
||||
ToolCallBlock::WebSearch(WebSearchToolCallBlock::new("grok")),
|
||||
ToolCallBlock::WebSearch(WebSearchToolCallBlock::new("kigi")),
|
||||
ToolCallBlock::IntegrationSearch(IntegrationSearchToolCallBlock::new("linear")),
|
||||
ToolCallBlock::UseTool(UseToolCallBlock::new("linear__save_issue")),
|
||||
ToolCallBlock::MemorySearch(MemorySearchToolCallBlock::new("auth")),
|
||||
|
||||
@@ -1114,7 +1114,7 @@ mod tests {
|
||||
fn prompt_band_color_native_vs_rgb() {
|
||||
use ratatui::style::Color;
|
||||
|
||||
let theme = Theme::groknight();
|
||||
let theme = Theme::kiginight();
|
||||
assert_eq!(
|
||||
UserPromptBlock::prompt_band_color_for(&theme, false, true),
|
||||
Some(Color::DarkGray)
|
||||
|
||||
@@ -950,9 +950,9 @@ impl ScrollbackState {
|
||||
if let Some(entry) = self.entries.get_mut(&id)
|
||||
&& let RenderBlock::ToolCall(ToolCallBlock::Execute(ref mut exec)) = entry.block
|
||||
{
|
||||
// Replace output entirely — grok-shell sends full accumulated buffer each tick.
|
||||
// Replace output entirely — kigi-shell sends full accumulated buffer each tick.
|
||||
// The shell now sends clean output (no ANSI codes) when the client sets
|
||||
// x.ai/bashOutputNoColor: true, so no stripping is needed.
|
||||
// kigi/bashOutputNoColor: true, so no stripping is needed.
|
||||
exec.output = Some(output.to_string());
|
||||
entry.invalidate_cache();
|
||||
self.dirty_heights.insert(id);
|
||||
|
||||
@@ -542,7 +542,7 @@ mod tests {
|
||||
};
|
||||
// Three distinct URLs across two searches, one duplicated.
|
||||
let entries = vec![
|
||||
searched("grok", &["https://a.com", "https://b.com"]),
|
||||
searched("kigi", &["https://a.com", "https://b.com"]),
|
||||
searched("pager", &["https://b.com", "https://c.com"]),
|
||||
];
|
||||
let l = label(&entries);
|
||||
|
||||
@@ -2539,7 +2539,7 @@ mod tests {
|
||||
#[test]
|
||||
fn persistent_and_active_overlay_agree_on_same_endpoints() {
|
||||
// Pin theme to avoid races with parallel tests that call `cache::set`.
|
||||
crate::theme::cache::set(crate::theme::ThemeKind::GrokNight);
|
||||
crate::theme::cache::set(crate::theme::ThemeKind::KigiNight);
|
||||
let mut model = ResolvedSelectionModel::default();
|
||||
for i in 0..4u16 {
|
||||
model.push_line(ResolvedSelectableLine {
|
||||
|
||||
@@ -407,7 +407,7 @@ impl<'a> EntryRenderer<'a> {
|
||||
///
|
||||
/// Mirrors `desired_height` but derives the content line count from the block's
|
||||
/// raw source text (`searchable_text`) instead of laying it out. Lets the layout
|
||||
/// cache size off-screen entries on a bulk load (`grok -r`) without word-wrapping
|
||||
/// cache size off-screen entries on a bulk load (`kigi -r`) without word-wrapping
|
||||
/// and markdown-rendering every entry (O(history)). On-screen entries get their
|
||||
/// EXACT `desired_height`, so visible content is never estimated.
|
||||
pub fn estimate_height(&self, width: u16) -> u16 {
|
||||
@@ -1486,7 +1486,7 @@ mod tests {
|
||||
// Background blocks own the gutter via the existing full-area fill, so
|
||||
// the no-bg clear must not run for them. Concrete theme so bg_light !=
|
||||
// bg_base (Theme::current() quantizes both to Reset in the test env).
|
||||
let theme = Theme::groknight();
|
||||
let theme = Theme::kiginight();
|
||||
assert_ne!(
|
||||
theme.bg_light, theme.bg_base,
|
||||
"test premise: block bg must differ from base bg"
|
||||
@@ -1517,14 +1517,14 @@ mod tests {
|
||||
// code rectangle gets a notch. Concrete theme so the two bgs differ.
|
||||
//
|
||||
// Requires color support: under `NO_COLOR` the global markdown style
|
||||
// carries no code background while this test's local `groknight()`
|
||||
// carries no code background while this test's local `kiginight()`
|
||||
// theme still has RGB — a mismatch impossible in production.
|
||||
// (Historically this passed under NO_COLOR only because the md_style
|
||||
// Reset→silver fallback bug painted a concrete bg despite the opt-out.)
|
||||
if !crate::theme::color_support::detect().has_color() {
|
||||
return;
|
||||
}
|
||||
let theme = Theme::groknight();
|
||||
let theme = Theme::kiginight();
|
||||
let mut entry = ScrollbackEntry::new(RenderBlock::agent_message("```\nZZZZ\n```\n"));
|
||||
// The code block's only content row is the first content row, which is
|
||||
// also where the timestamp overlay lands. Drop `created_at` so the
|
||||
@@ -1802,7 +1802,7 @@ mod tests {
|
||||
|
||||
// The off-screen estimate accounts for the affordance row (one per
|
||||
// diagram) and so never under-reserves vs the realized height — the
|
||||
// invariant a bulk load (`grok -r`) relies on to avoid clipping.
|
||||
// invariant a bulk load (`kigi -r`) relies on to avoid clipping.
|
||||
let est_on = r.estimate_height(80);
|
||||
assert_eq!(
|
||||
est_on,
|
||||
@@ -1872,7 +1872,7 @@ mod tests {
|
||||
// their previews as panel is pinned by block-side tests.)
|
||||
use crate::scrollback::block::StubBlock;
|
||||
|
||||
let theme = Theme::groknight();
|
||||
let theme = Theme::kiginight();
|
||||
let entry = ScrollbackEntry::new(RenderBlock::Stub(
|
||||
StubBlock::new("alpha\nbravo", Color::Blue).with_line_bg(LINE_BG, true),
|
||||
));
|
||||
@@ -1900,7 +1900,7 @@ mod tests {
|
||||
// tool-preview panels.
|
||||
use crate::scrollback::block::StubBlock;
|
||||
|
||||
let theme = Theme::groknight();
|
||||
let theme = Theme::kiginight();
|
||||
let entry = ScrollbackEntry::new(RenderBlock::Stub(
|
||||
StubBlock::new("alpha\nbravo", Color::Blue).with_line_bg(LINE_BG, false),
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user