§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:
@@ -3,7 +3,7 @@ license = "Apache-2.0"
|
||||
name = "kigi-shell-base"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
description = "Foundation modules for the grok shell crate family: environment presets, CPU profiling, and process/filesystem utilities."
|
||||
description = "Foundation modules for the kigi shell crate family: environment presets, CPU profiling, and process/filesystem utilities."
|
||||
|
||||
[features]
|
||||
# CI default set: builds a single shared rlib per crate, so downstream test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//! Foundation modules shared by the grok shell crate family. Extracted from
|
||||
//! Foundation modules shared by the kigi shell crate family. Extracted from
|
||||
//! `kigi-shell` (which re-exports them at their original paths) so they
|
||||
//! build in parallel and stop rebuilding on shell edits.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//! Changelog fetching from CDN with local disk cache.
|
||||
//!
|
||||
//! Both markdown (`*.external.md`) and JSON (`*.external.json`) changelogs
|
||||
//! are published per-version to the CDN at `x.ai/cli/changelogs/`.
|
||||
//! are published per-version alongside the Kigi GitHub distribution.
|
||||
//!
|
||||
//! `ChangelogManager::fetch()` retrieves both formats in parallel and
|
||||
//! returns a `Changelog` with optional markdown + structured entries.
|
||||
@@ -11,8 +11,11 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// CDN base for all changelogs (proxies to GCS, cache-friendly).
|
||||
const CHANGELOG_BASE: &str = "https://x.ai/cli/changelogs";
|
||||
/// Base URL for published changelogs. Kigi distributes via GitHub, so
|
||||
/// per-version changelogs live in the release repository. Unreachable or
|
||||
/// missing files degrade gracefully to the on-disk cache (see `fetch_with`).
|
||||
const CHANGELOG_BASE: &str =
|
||||
"https://raw.githubusercontent.com/ZacharyZhang-NY/Kigi-CLI/main/changelogs";
|
||||
const FETCH_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(3);
|
||||
|
||||
/// A single structured changelog entry from the published JSON changelog.
|
||||
@@ -258,7 +261,7 @@ mod tests {
|
||||
#[test]
|
||||
fn offline_mode_reads_seeded_disk_cache_only() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let home = tmp.path().join("grok-home");
|
||||
let home = tmp.path().join("kigi-home");
|
||||
std::fs::create_dir_all(&home).unwrap();
|
||||
std::fs::write(home.join("CHANGELOG.md"), "# seeded offline md\n").unwrap();
|
||||
std::fs::write(
|
||||
@@ -282,7 +285,7 @@ mod tests {
|
||||
#[test]
|
||||
fn cdn_miss_falls_back_to_env_home_disk_cache() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let home = tmp.path().join("grok-home-fallback");
|
||||
let home = tmp.path().join("kigi-home-fallback");
|
||||
std::fs::create_dir_all(&home).unwrap();
|
||||
std::fs::write(home.join("CHANGELOG.md"), "# fallback md\n").unwrap();
|
||||
|
||||
|
||||
@@ -166,14 +166,14 @@ pub fn kill_process_by_pid(pid: u32) -> std::io::Result<()> {
|
||||
terminate.map_err(|e| std::io::Error::other(format!("TerminateProcess({pid}): {e}")))
|
||||
}
|
||||
}
|
||||
/// True if `pid` is a grok process; pairs with [`kill_process_by_pid`] to avoid killing a recycled PID.
|
||||
/// True if `pid` is a kigi process; pairs with [`kill_process_by_pid`] to avoid killing a recycled PID.
|
||||
/// Best-effort on macOS/BSD (liveness-only via `kill -0`), exact on Linux (/proc cmdline) and Windows (image path).
|
||||
pub fn is_grok_process(pid: u32) -> bool {
|
||||
pub fn is_kigi_process(pid: u32) -> bool {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let cmdline_path = format!("/proc/{pid}/cmdline");
|
||||
match std::fs::read(&cmdline_path) {
|
||||
Ok(data) => String::from_utf8_lossy(&data).contains("grok"),
|
||||
Ok(data) => String::from_utf8_lossy(&data).contains("kigi"),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
@@ -205,7 +205,7 @@ pub fn is_grok_process(pid: u32) -> bool {
|
||||
}
|
||||
String::from_utf16_lossy(&buf[..size as usize])
|
||||
.to_ascii_lowercase()
|
||||
.contains("grok")
|
||||
.contains("kigi")
|
||||
}
|
||||
#[cfg(all(not(target_os = "linux"), not(windows)))]
|
||||
{
|
||||
@@ -229,7 +229,7 @@ mod tests {
|
||||
}
|
||||
#[test]
|
||||
fn test_is_production_coding_api_url_rejects_public_api() {
|
||||
assert!(!is_production_coding_api_url("https://api.x.ai/v1"));
|
||||
assert!(!is_production_coding_api_url("https://byok.example/v1"));
|
||||
}
|
||||
#[test]
|
||||
fn test_is_production_coding_api_url_rejects_spoofed_hostname() {
|
||||
@@ -248,7 +248,7 @@ mod tests {
|
||||
}
|
||||
#[test]
|
||||
fn test_is_effective_coding_endpoint_url_rejects_remote_third_party() {
|
||||
assert!(!is_effective_coding_endpoint_url("https://api.x.ai/v1"));
|
||||
assert!(!is_effective_coding_endpoint_url("https://byok.example/v1"));
|
||||
assert!(!is_effective_coding_endpoint_url(
|
||||
"https://localhost.evil.example/v1"
|
||||
));
|
||||
@@ -264,7 +264,7 @@ mod tests {
|
||||
assert!(is_first_party_url(
|
||||
"https://api.kimi.com/coding/v1/chat/completions"
|
||||
));
|
||||
assert!(!is_first_party_url("https://api.x.ai/v1"));
|
||||
assert!(!is_first_party_url("https://byok.example/v1"));
|
||||
assert!(!is_first_party_url("https://api.openai.com/v1"));
|
||||
assert!(!is_first_party_url("https://api.anthropic.com/v1"));
|
||||
assert!(!is_first_party_url("https://api.kimi.com.evil.example/v1"));
|
||||
@@ -310,8 +310,8 @@ mod tests {
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn is_grok_process_self_true_impossible_pid_false() {
|
||||
assert!(is_grok_process(std::process::id()));
|
||||
assert!(!is_grok_process(u32::MAX));
|
||||
fn is_kigi_process_self_true_impossible_pid_false() {
|
||||
assert!(is_kigi_process(std::process::id()));
|
||||
assert!(!is_kigi_process(u32::MAX));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user